
/*
 *  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 "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)
{
    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)
{
    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]);
}

