
/*
 *  Frame buffer control
 *
 *  (C) Copyright 2001-2003 Geert Uytterhoeven
 *
 *  This file is subject to the terms and conditions of the GNU General Public
 *  License. See the file COPYING in the main directory of this archive for
 *  more details.
 */

#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

#include "types.h"
#include "export.h"
#include "fb.h"
#include "util.h"
#include "colormap.h"


static int fb_fd = -1;

struct fb_fix_screeninfo fb_fix;
struct fb_var_screeninfo fb_var;
struct fb_cmap fb_cmap;

static unsigned long fb_start;
static u32 fb_len, fb_offset;
static void *fb_addr;
u8 *fb;


    /*
     *   Saved frame buffer device state
     */

static struct fb_var_screeninfo saved_var;
static struct fb_fix_screeninfo saved_fix;
static struct fb_cmap saved_cmap;
static u16 *saved_red, *saved_green, *saved_blue, *saved_transp;
static u8 *saved_fb;


static void fix_validate(void);
static void var_validate(void);
static void var_validate_change(const struct fb_var_screeninfo *old,
				int error);
static void cmap_validate(void);
static void cmap_validate_change(const struct fb_cmap *old, int error);
static void fb_dump_cmap(void);


    /*
     *  Open the frame buffer device
     */

void fb_open(void)
{
    Debug("fb_open()\n");
    if ((fb_fd = open(Opt_Fbdev, O_RDWR)) == -1) {
	Fatal("open %s: %s\n", Opt_Fbdev, strerror(errno));
    }
}


    /*
     *  Close the frame buffer device
     */

void fb_close(void)
{
    Debug("fb_close()\n");
    if (fb_fd != -1) {
	close(fb_fd);
	fb_fd = -1;
    }
}


    /*
     *  Get the fixed information about a frame buffer
     */

int fb_get_fix(void)
{
    Debug("fb_get_fix()\n");
    if (ioctl(fb_fd, FBIOGET_FSCREENINFO, &fb_fix) == -1) {
	Fatal("ioctl FBIOGET_FSCREENINFO: %s\n", strerror(errno));
    }
    fix_validate();
    return 1;
}


    /*
     *  Get the variable information about a frame buffer
     */

int fb_get_var(void)
{
    Debug("fb_get_var()\n");
    if (ioctl(fb_fd, FBIOGET_VSCREENINFO, &fb_var) == -1) {
	Fatal("ioctl FBIOGET_VSCREENINFO: %s\n", strerror(errno));
    }
    var_validate();
    return 1;
}


    /*
     *  Set the variable information about a frame buffer
     */

int fb_set_var(void)
{
    struct fb_var_screeninfo var = fb_var;
    int error;

    Debug("fb_set_var()\n");
    error = ioctl(fb_fd, FBIOPUT_VSCREENINFO, &fb_var);
    var_validate_change(&var, error);
    if (error == -1) {
	Fatal("ioctl FBIOPUT_VSCREENINFO: %s\n", strerror(errno));
    }
    return 1;
}


    /*
     *  Get the colormap
     */

int fb_get_cmap(void)
{
    Debug("fb_get_cmap()\n");
    if (ioctl(fb_fd, FBIOGETCMAP, &fb_cmap) == -1) {
	Fatal("ioctl FBIOGETCMAP: %s\n", strerror(errno));
    }
    cmap_validate();
    if (Opt_Debug)
	fb_dump_cmap();
    return 1;
}


    /*
     *  Set the colormap
     */

int fb_set_cmap(void)
{
    struct fb_cmap cmap = fb_cmap;
    int error;

    Debug("fb_set_cmap()\n");
    if (Opt_Debug)
	fb_dump_cmap();
    error = ioctl(fb_fd, FBIOPUTCMAP, &fb_cmap);
    cmap_validate_change(&cmap, error);
    if (error == -1) {
	Fatal("ioctl FBIOPUTCMAP: %s\n", strerror(errno));
    }
    return 1;
}


    /*
     *  Pan the display
     */

int fb_pan(u32 xoffset, u32 yoffset)
{
    struct fb_var_screeninfo var;
    int error;

    Debug("fb_pan(%u, %u)\n", xoffset, yoffset);
    fb_var.xoffset = xoffset;
    fb_var.yoffset = yoffset;
    var = fb_var;
    error = ioctl(fb_fd, FBIOPAN_DISPLAY, &fb_var);
    var_validate_change(&var, error);
    if (error == -1) {
	Fatal("ioctl FBIOPAN_DISPLAY: %s\n", strerror(errno));
    }
    return 1;
}


    /*
     *  Map the frame buffer
     */

void fb_map(void)
{
    long page_size;
    unsigned long page_mask;

    Debug("fb_map()\n");

    page_size = sysconf(_SC_PAGESIZE);
    if (page_size == -1)
	Fatal("Cannot obtain page size: %s\n", strerror(errno));

    page_mask = ~(page_size-1);
    fb_start = (unsigned long)fb_fix.smem_start & page_mask;
    fb_offset = (unsigned long)fb_fix.smem_start & ~page_mask;
    fb_len = (fb_offset+fb_fix.smem_len+~page_mask) & page_mask;
    Debug("fb_start = %lx, fb_offset = %x, fb_len = %x\n", fb_start, fb_offset,
	  fb_len);
    fb_addr = mmap(NULL, fb_len, PROT_READ | PROT_WRITE, MAP_SHARED, fb_fd, 0);
    if (fb_addr == MAP_FAILED)
	Fatal("mmap smem: %s\n", strerror(errno));
    fb = fb_addr+fb_offset;
}


    /*
     *  Unmap the frame buffer
     */

void fb_unmap(void)
{
    Debug("fb_unmap()\n");
    if (munmap(fb_addr, fb_len) == -1)
	Fatal("munmap smem: %s\n", strerror(errno));
}


    /*
     *  Save the frame buffer contents
     */

void fb_save(void)
{
    Debug("fb_save()\n");
    if (!(saved_fb = malloc(fb_fix.smem_len)))
	Fatal("malloc %d: %s\n", fb_fix.smem_len, strerror(errno));
    memcpy(saved_fb, fb, fb_fix.smem_len);
}


    /*
     *  Restore the frame buffer contents
     */

void fb_restore(void)
{
    Debug("fb_restore()\n");
    memcpy(fb, saved_fb, fb_fix.smem_len);
    free(saved_fb);
}


    /*
     *  Clear the frame buffer
     *
     *  We can't use memset(), because on PPC it uses dcbz, which is not
     *  allowed on non-cacheable memory :-(
     */

void fb_clear(void)
{
    u32 size = fb_fix.smem_len/sizeof(unsigned long);
    unsigned long *p = (unsigned long *)fb;

    Debug("fb_clear()\n");
    while (size--)
	*p++ = 0;
}


    /*
     *  Validate the fixed information about a frame buffer
     */

static void fix_validate(void)
{
    /* FIXME: check for impossible values */
}


    /*
     *  Validate the variable information about a frame buffer
     */

static void var_validate(void)
{
    /* FIXME: check for impossible values */
}


    /*
     *  Validate a change of the variable information about a frame buffer
     */

#define CHECK_CHANGE(x)							\
    do {								\
	if (fb_var.x != old->x) {					\
	    if (error == -1)						\
		Error(#x " changed from %u to %u\n", old->x, fb_var.x);	\
	    else							\
		Warning(#x " changed from %u to %u\n", old->x, fb_var.x);\
	}								\
    } while (0)

#define CHECK_ROUNDING(x)			\
    do {					\
	if (fb_var.x < old->x)			\
	    Error(#x " was rounded down\n");	\
    } while (0)

#define CHECK_CHANGE_AND_ROUNDING(x)	\
    do {				\
	CHECK_CHANGE(x);		\
	if (error != -1)		\
	    CHECK_ROUNDING(x);		\
    } while (0)

static void var_validate_change(const struct fb_var_screeninfo *old, int error)
{
    unsigned int i;

    CHECK_CHANGE_AND_ROUNDING(xres);
    CHECK_CHANGE_AND_ROUNDING(yres);
    CHECK_CHANGE_AND_ROUNDING(xres_virtual);
    CHECK_CHANGE_AND_ROUNDING(yres_virtual);
    CHECK_CHANGE_AND_ROUNDING(xoffset);
    CHECK_CHANGE_AND_ROUNDING(yoffset);
    CHECK_CHANGE_AND_ROUNDING(bits_per_pixel);
    CHECK_CHANGE(grayscale);
    CHECK_CHANGE_AND_ROUNDING(red.offset);
    CHECK_CHANGE_AND_ROUNDING(red.length);
    CHECK_CHANGE(red.msb_right);
    CHECK_CHANGE_AND_ROUNDING(green.offset);
    CHECK_CHANGE_AND_ROUNDING(green.length);
    CHECK_CHANGE_AND_ROUNDING(green.length);
    CHECK_CHANGE(green.msb_right);
    CHECK_CHANGE_AND_ROUNDING(blue.offset);
    CHECK_CHANGE_AND_ROUNDING(blue.length);
    CHECK_CHANGE_AND_ROUNDING(blue.length);
    CHECK_CHANGE(blue.msb_right);
    CHECK_CHANGE_AND_ROUNDING(transp.offset);
    CHECK_CHANGE_AND_ROUNDING(transp.length);
    CHECK_CHANGE_AND_ROUNDING(transp.length);
    CHECK_CHANGE(transp.msb_right);
    CHECK_CHANGE(nonstd);
    CHECK_CHANGE(activate);
    CHECK_CHANGE_AND_ROUNDING(height);
    CHECK_CHANGE_AND_ROUNDING(width);
    CHECK_CHANGE(accel_flags);
    CHECK_CHANGE_AND_ROUNDING(pixclock);
    CHECK_CHANGE_AND_ROUNDING(left_margin);
    CHECK_CHANGE_AND_ROUNDING(right_margin);
    CHECK_CHANGE_AND_ROUNDING(upper_margin);
    CHECK_CHANGE_AND_ROUNDING(lower_margin);
    CHECK_CHANGE_AND_ROUNDING(hsync_len);
    CHECK_CHANGE_AND_ROUNDING(vsync_len);
    CHECK_CHANGE(sync);
    CHECK_CHANGE(vmode);
    CHECK_CHANGE(rotate);
    for (i = 0; i < sizeof(fb_var.reserved)/sizeof(fb_var.reserved[0]); i++)
	if (fb_var.reserved[i] != old->reserved[i]) {
	    if (error == -1)
		Error("reserved[%u] changed from %u to %u\n", i,
		      old->reserved[i], fb_var.reserved[i]);
	    else
		Warning("reserved[%u] changed from %u to %u\n", i,
			old->reserved[i], fb_var.reserved[i]);
	}

    var_validate();
}

#undef CHECK_CHANGE
#undef CHECK_ROUNDING
#undef CHECK_CHANGE_AND_ROUNDING


    /*
     *  Validate the colormap
     */

static void cmap_validate(void)
{
    /* FIXME */
}


    /*
     *  Validate a change of the colormap
     */

static void cmap_validate_change(const struct fb_cmap *old, int error)
{
    /* FIXME */

    cmap_validate();
}


    /*
     *  Validate the variable and fixed information about a frame buffer
     */

static void var_fix_validate(void)
{
    /* FIXME: check for impossible combinations */
}


    /*
     *  Initialization
     */

#define ALLOC_AND_SAVE_COMPONENT(name)					\
    do {								\
	if (!(saved_ ## name = malloc(fb_cmap.len*sizeof(u16))))	\
	    Fatal("malloc %zu: %s\n", fb_cmap.len*sizeof(u16),		\
		  strerror(errno));					\
	memcpy(saved_ ## name, fb_cmap.name, fb_cmap.len*sizeof(u16));	\
    } while (0)

void fb_init(void)
{
    if (Opt_Export) {
	export_init();
	return;
    }

    Debug("fb_init()\n");
    fb_open();
    fb_get_var();
    saved_var = fb_var;
    if (fb_var.xoffset || fb_var.yoffset || fb_var.accel_flags ||
	fb_var.vmode & FB_VMODE_YWRAP) {
	fb_var.xoffset = 0;
	fb_var.yoffset = 0;
	fb_var.accel_flags = 0;
	fb_var.vmode &= ~FB_VMODE_YWRAP;
	fb_set_var();
    }
    fb_get_fix();
    var_fix_validate();
    saved_fix = fb_fix;
    switch (fb_fix.visual) {
	case FB_VISUAL_MONO01:
	case FB_VISUAL_MONO10:
	case FB_VISUAL_TRUECOLOR:
	    /* no colormap */
	    break;

	case FB_VISUAL_PSEUDOCOLOR:
	case FB_VISUAL_STATIC_PSEUDOCOLOR:
	    cmap_init(1<<fb_var.bits_per_pixel);
	    break;

	case FB_VISUAL_DIRECTCOLOR:
	    cmap_init(1<<(max(max(fb_var.red.length, fb_var.green.length),
			      max(fb_var.blue.length, fb_var.transp.length))));
	    break;
    }
    if (fb_cmap.len) {
	fb_get_cmap();
	saved_cmap = fb_cmap;
	ALLOC_AND_SAVE_COMPONENT(red);
	ALLOC_AND_SAVE_COMPONENT(green);
	ALLOC_AND_SAVE_COMPONENT(blue);
	if (fb_cmap.transp)
	    ALLOC_AND_SAVE_COMPONENT(transp);
    }
    fb_map();
    fb_save();
    fb_clear();
}

#undef ALLOC_AND_SAVE_COMPONENT


    /*
     *   Clean up
     */

#define RESTORE_AND_FREE_COMPONENT(name)				\
    do {								\
	memcpy(fb_cmap.name, saved_ ## name, fb_cmap.len*sizeof(u16));	\
	free(saved_ ## name);						\
    } while (0)

void fb_cleanup(void)
{
    if (Opt_Export)
	return;

    Debug("fb_cleanup()\n");
    if (saved_fb)
	fb_restore();
    if (fb)
	fb_unmap();
    if (fb_fd != -1) {
	if (saved_cmap.len) {
	    fb_cmap = saved_cmap;
	    RESTORE_AND_FREE_COMPONENT(red);
	    RESTORE_AND_FREE_COMPONENT(green);
	    RESTORE_AND_FREE_COMPONENT(blue);
	    if (fb_cmap.transp)
		RESTORE_AND_FREE_COMPONENT(transp);
	    fb_set_cmap();
	}
	fb_var = saved_var;
	fb_set_var();
	fb_get_var();
	/* FIXME: compare fb_var with saved_var */
	fb_get_fix();
	/* FIXME: compare fb_fix with saved_fix */
	fb_close();
    }
}

#undef RESTORE_AND_FREE_COMPONENT


    /*
     *  Dump the colormap
     */

static void fb_dump_cmap(void)
{
    int i;

    Debug("Colormap start = %d len = %d\n", fb_cmap.start, fb_cmap.len);
    for (i = 0; i < fb_cmap.len; i++)
	Debug("%4d: R %04x G %04x B %04x A %04x\n", i, fb_cmap.red[i],
	      fb_cmap.green[i], fb_cmap.blue[i], fb_cmap.transp[i]);
}

