From dd7595a3475407a7fa96a97393bae8c5220e8762 Mon Sep 17 00:00:00 2001 From: David Walter Seikel Date: Wed, 4 Jan 2012 18:41:13 +1000 Subject: Add the base Enlightenment Foundation Libraries - eina, eet, evas, ecore, embryo, and edje. Note that embryo wont be used, but I'm not sure yet if you can build edje without it. --- .../evas/src/modules/engines/fb/evas_fb_main.c | 600 +++++++++++++++++++++ 1 file changed, 600 insertions(+) create mode 100644 libraries/evas/src/modules/engines/fb/evas_fb_main.c (limited to 'libraries/evas/src/modules/engines/fb/evas_fb_main.c') diff --git a/libraries/evas/src/modules/engines/fb/evas_fb_main.c b/libraries/evas/src/modules/engines/fb/evas_fb_main.c new file mode 100644 index 0000000..1d61f1a --- /dev/null +++ b/libraries/evas/src/modules/engines/fb/evas_fb_main.c @@ -0,0 +1,600 @@ +/* -------------------------------------------------------------------- */ +/* LINUX FBCON FRAMEBUFFER UTILITY CODE */ +/* makes setting up the framebuffer easy. Also makes it eays to port to */ +/* some other system if needed. */ +/* Copyright (c) 1999 - Carsten Haitzler (The Rasterman) */ +/* -------------------------------------------------------------------- */ +#include "evas_common.h" +#include "evas_fb.h" + +#include +#include +#include +#include +#include + +#define FB_ACTIVE 0 +#define FB_REL_REQ 1 +#define FB_INACTIVE 2 +#define FB_ACQ_REQ 3 + +/* -------------------------------------------------------------------- */ +/* internal variables */ + +static struct fb_fix_screeninfo fb_fix; +static int fb, tty; +static int bpp, depth; +//static int orig_vt_no = 0; +static int kd_mode; +static struct vt_mode vt_omode; +static struct fb_var_screeninfo fb_ovar; +static unsigned short ored[256], ogreen[256], oblue[256]; +static unsigned short red[256], green[256], blue[256]; +static struct fb_cmap ocmap = { 0, 256, ored, ogreen, oblue, NULL }; +static struct fb_cmap cmap = { 0, 256, red, green, blue, NULL }; + +/* -------------------------------------------------------------------- */ +/* internal function prototypes */ + +static void fb_cleanup(void); +//static void fb_cleanup_fork(void); +//static void fb_setvt(int vtno); +static void fb_init_palette_332(FB_Mode *mode); +static void fb_init_palette_linear(FB_Mode *mode); + +/* -------------------------------------------------------------------- */ +/* palette setting */ + +static void +fb_init_palette_332(FB_Mode *mode) +{ + int r, g, b, i; + + if (mode->fb_var.bits_per_pixel != 8) + return; + i = 0; + + if (ioctl(fb, FBIOGETCMAP, &cmap) == -1) + perror("ioctl FBIOGETCMAP"); + + /* generate the palette */ + for (r = 0; r < 8; r++) + { + for (g = 0; g < 8; g++) + { + for (b = 0; b < 4; b++) + { + int val; + + val = (r << 5) | (r << 2) | (r >> 1); + red[i] = (val << 8) | val; + val = (g << 5) | (g << 2) | (g >> 1); + green[i] = (val << 8) | val; + val = (b << 6) | (b << 4) | (b << 2) | (b); + blue[i] = (val << 8) | val; + i++; + } + } + } + + /* set colormap */ + if (ioctl(fb, FBIOPUTCMAP, &cmap) == -1) + perror("ioctl FBIOPUTCMAP"); +} + +static void +fb_init_palette_linear(FB_Mode *mode) +{ + int i; + + if (mode->fb_var.bits_per_pixel != 8) + return; + + if (ioctl(fb, FBIOGETCMAP, &cmap) == -1) + perror("ioctl FBIOGETCMAP"); + + /* generate the palette */ + for (i = 0; i < 256; i++) + red[i] = (i << 8) | i; + for (i = 0; i < 256; i++) + green[i] = (i << 8) | i; + for (i = 0; i < 256; i++) + blue[i] = (i << 8) | i; + + /* set colormap */ + if (ioctl(fb, FBIOPUTCMAP, &cmap) == -1) + perror("ioctl FBIOPUTCMAP"); +} + +/* -------------------------------------------------------------------- */ +/* initialisation & cleanup */ + +FB_Mode * +fb_list_modes(unsigned int *num_return) +{ + FILE *f; + char line[256], label[256], value[256]; + FB_Mode *modes = NULL; + int num; + + num = 0; + f = fopen("/etc/fb.modes","r"); + if (!f) + { + *num_return = 0; + return NULL; + } + while (fgets(line, sizeof(line) - 1, f)) + { + if (sscanf(line, "mode \"%250[^\"]\"", label) == 1) + { + char f1[32], f2[32], f3[32], f4[32]; + + f1[0] = 0; f2[0] = 0; f3[0] = 0; f4[0] = 0; + sscanf(label, "%30[^x]x%30[^-]-%30[^-]-%30s", f1, f2, f3, f4); + if ((f1[0]) && (f2[0])) + { + int geometry = 0; + int timings = 0; + + num++; + modes = realloc(modes, num * sizeof(FB_Mode)); + modes[num - 1].width = atoi(f1); + modes[num - 1].height = atoi(f2); + if (f3[0]) + modes[num - 1].refresh = atoi(f3); + else + modes[num - 1].refresh = 0; + modes[num - 1].fb_var.sync = 0; + while ((fgets(line, sizeof(line) - 1, f)) && + (!strstr(line, "endmode"))) + { + + if (sscanf(line," geometry %i %i %i %i %i", + &modes[num - 1].fb_var.xres, + &modes[num - 1].fb_var.yres, + &modes[num - 1].fb_var.xres_virtual, + &modes[num - 1].fb_var.yres_virtual, + &modes[num - 1].fb_var.bits_per_pixel) == 5) + geometry = 1; + if (sscanf(line," timings %i %i %i %i %i %i %i", + &modes[num - 1].fb_var.pixclock, + &modes[num - 1].fb_var.left_margin, + &modes[num - 1].fb_var.right_margin, + &modes[num - 1].fb_var.upper_margin, + &modes[num - 1].fb_var.lower_margin, + &modes[num - 1].fb_var.hsync_len, + &modes[num - 1].fb_var.vsync_len) == 7) + timings = 1; + if ((sscanf(line, " hsync %15s", value) == 1) && + (!strcmp(value,"high"))) + modes[num - 1].fb_var.sync |= FB_SYNC_HOR_HIGH_ACT; + if ((sscanf(line, " vsync %15s", value) == 1) && + (!strcmp(value,"high"))) + modes[num - 1].fb_var.sync |= FB_SYNC_VERT_HIGH_ACT; + if ((sscanf(line, " csync %15s", value) == 1) && + (!strcmp(value,"high"))) + modes[num - 1].fb_var.sync |= FB_SYNC_COMP_HIGH_ACT; + if ((sscanf(line, " extsync %15s", value) == 1) && + (!strcmp(value,"true"))) + modes[num - 1].fb_var.sync |= FB_SYNC_EXT; + if ((sscanf(line, " laced %15s", value) == 1) && + (!strcmp(value,"true"))) + modes[num - 1].fb_var.vmode |= FB_VMODE_INTERLACED; + if ((sscanf(line, " double %15s",value) == 1) && + (!strcmp(value,"true"))) + modes[num - 1].fb_var.vmode |= FB_VMODE_DOUBLE; + } + if ((!geometry) || (!timings)) + { + num--; + if (num == 0) + { + free(modes); + modes = NULL; + } + } + else + { + modes[num - 1].fb_var.xoffset = 0; + modes[num - 1].fb_var.yoffset = 0; + } + } + } + } + fclose(f); + *num_return = num; + return modes; +} + +FB_Mode * +fb_setmode(unsigned int width, unsigned int height, unsigned int pdepth, unsigned int refresh) +{ + FB_Mode *modes, *mode = NULL; + unsigned int i, num_modes; + + modes = fb_list_modes(&num_modes); + if (modes) + { + for (i = 0; i < num_modes; i++) + { + if ((modes[i].width == width) && + (modes[i].height == height) && + (!pdepth || modes[i].fb_var.bits_per_pixel == pdepth) && + (modes[i].refresh == refresh)) + { + if (pdepth) modes[i].fb_var.bits_per_pixel = pdepth; + + if (ioctl(fb, FBIOPUT_VSCREENINFO, &modes[i].fb_var) == -1) + perror("ioctl FBIOPUT_VSCREENINFO"); + + free(modes); + return fb_getmode(); + } + } + free(modes); + } + return mode; +} + +FB_Mode * +fb_changedepth(FB_Mode *cur_mode, unsigned int pdepth) +{ + cur_mode->fb_var.bits_per_pixel = pdepth; + + if (ioctl(fb, FBIOPUT_VSCREENINFO, &cur_mode->fb_var) == -1) + perror("ioctl FBIOPUT_VSCREENINFO"); + + free(cur_mode); + return fb_getmode(); +} + +FB_Mode * +fb_changeres(FB_Mode *cur_mode, unsigned int width, unsigned int height, unsigned int refresh) +{ + FB_Mode *modes; + unsigned int i, num_modes; + + modes = fb_list_modes(&num_modes); + if (modes) + { + for (i = 0; i < num_modes; i++) + { + if ((modes[i].width == width) && + (modes[i].height == height) && + (modes[i].refresh == refresh)) + { + modes[i].fb_var.bits_per_pixel = cur_mode->depth; + + if (ioctl(fb, FBIOPUT_VSCREENINFO, &modes[i].fb_var) == -1) + perror("ioctl FBIOPUT_VSCREENINFO"); + + free(modes); + free(cur_mode); + return fb_getmode(); + } + } + free(modes); + } + return cur_mode; +} + +FB_Mode * +fb_changemode(FB_Mode *cur_mode, unsigned int width, unsigned int height, unsigned int pdepth, unsigned int refresh) +{ + FB_Mode *modes; + unsigned int i, num_modes; + + modes = fb_list_modes(&num_modes); + if (modes) + { + for (i = 0; i < num_modes; i++) + { + if ((modes[i].width == width) && + (modes[i].height == height) && + (!pdepth || modes[i].fb_var.bits_per_pixel == pdepth) && + (modes[i].refresh == refresh)) + { + if (pdepth) modes[i].fb_var.bits_per_pixel = pdepth; + + if (ioctl(fb, FBIOPUT_VSCREENINFO, &modes[i].fb_var) == -1) + perror("ioctl FBIOPUT_VSCREENINFO"); + + free(modes); + free(cur_mode); + return fb_getmode(); + } + } + free(modes); + } + return cur_mode; +} + +FB_Mode * +fb_getmode(void) +{ + FB_Mode *mode = NULL; + int hpix, lines, clockrate; + + mode = malloc(sizeof(FB_Mode)); + /* look what we have now ... */ + + if (ioctl(fb, FBIOGET_VSCREENINFO, &mode->fb_var) == -1) + { + perror("ioctl FBIOGET_VSCREENINFO"); + return NULL; + } + + mode->width = mode->fb_var.xres_virtual; + mode->height = mode->fb_var.yres_virtual; + hpix = + mode->fb_var.left_margin + + mode->fb_var.xres + + mode->fb_var.right_margin + + mode->fb_var.hsync_len; + lines = + mode->fb_var.upper_margin + + mode->fb_var.yres + + mode->fb_var.lower_margin + + mode->fb_var.vsync_len; + if (mode->fb_var.pixclock > 0) + clockrate = 1000000 / mode->fb_var.pixclock; + else + clockrate = 0; + if ((lines > 0) && (hpix > 0)) + mode->refresh = clockrate * 1000000 / (lines * hpix); + switch (mode->fb_var.bits_per_pixel) + { + case 1: + bpp = 1; + depth = 1; + break; + case 4: + bpp = 1; + depth = 4; + break; + case 8: + bpp = 1; + depth = 8; + break; + case 15: + case 16: + if (mode->fb_var.green.length == 6) + depth = 16; + else + depth = 15; + bpp = 2; + break; + case 24: + depth = 24; + bpp = mode->fb_var.bits_per_pixel / 8; + break; + case 32: + depth = 32; + bpp = mode->fb_var.bits_per_pixel / 8; + break; + default: + ERR("Cannot handle framebuffer of depth %i", + mode->fb_var.bits_per_pixel); + fb_cleanup(); + free(mode); + return NULL; + } + mode->depth = depth; + mode->bpp = bpp; + if (mode->depth == 8) fb_init_palette_332(mode); + else fb_init_palette_linear(mode); + return mode; +} + +/* XXX: unused +static void +fb_setvt(int vtno) +{ + struct vt_stat vts; + char vtname[32]; + int vtfd; + + if (vtno < 0) + { + if ((ioctl(tty,VT_OPENQRY, &vtno) == -1)) + { + perror("ioctl VT_OPENQRY"); + return; + } + if (vtno <= 0 ) + { + perror("ioctl VT_OPENQRY vtno <= 0"); + return; + } + } + vtno &= 0xff; + sprintf(vtname, "/dev/tty%i", vtno); + if (chown(vtname, getuid(), getgid()) != 0) + { + vtfd = 0; // do nothing - don't worry about chown + } + if (access(vtname,R_OK | W_OK) == -1) + { + CRIT("Access %s: %s",vtname,strerror(errno)); + return; + } + vtfd = open(vtname,O_RDWR); + + if (ioctl(tty, VT_GETSTATE, &vts) == -1) + { + perror("ioctl VT_GETSTATE"); + close(vtfd); + return; + } + + orig_vt_no = vts.v_active; + close(vtfd); +#if 0 + if (ioctl(tty, VT_ACTIVATE, vtno) == -1) + { + perror("ioctl VT_ACTIVATE"); + exit(1); + } + if (ioctl(tty, VT_WAITACTIVE, vtno) == -1) + { + perror("ioctl VT_WAITACTIVE"); + exit(1); + } +#endif +} +*/ + +void +fb_init(int vt __UNUSED__, int device) +{ + char dev[32]; + + tty = 0; +#if 0 + if (vt != 0) fb_setvt(vt); +#endif + + if ( getenv("EVAS_FB_DEV") ) + { + fb = open(getenv("EVAS_FB_DEV"), O_RDWR); + } + else + { + sprintf(dev, "/dev/fb/%i", device); + fb = open(dev, O_RDWR); + if ( fb == -1 ) + { + sprintf(dev, "/dev/fb%i", device); + fb = open(dev, O_RDWR); + } + } + if (fb == -1) + { + CRIT("open %s: %s", dev, strerror(errno)); + fb_cleanup(); + return; + } + + if (ioctl(fb, FBIOGET_VSCREENINFO, &fb_ovar) == -1) + { + perror("ioctl FBIOGET_VSCREENINFO"); + return; + } + if (ioctl(fb, FBIOGET_FSCREENINFO, &fb_fix) == -1) + { + perror("ioctl FBIOGET_FSCREENINFO"); + return; + } + + if ((fb_ovar.bits_per_pixel == 8) || + (fb_fix.visual == FB_VISUAL_DIRECTCOLOR)) + { + if (ioctl(fb,FBIOGETCMAP , &ocmap) == -1) + { + perror("ioctl FBIOGETCMAP"); + return; + } + } +#if 0 + if (isatty(0)) + tty = 0; + else if ((tty = open("/dev/tty",O_RDWR)) == -1) + { + CITICAL("open %s: %s", "/dev/tty", strerror(errno)); + return; + } + if (tty) + { + if (ioctl(tty, KDGETMODE, &kd_mode) == -1) + { + perror("ioctl KDGETMODE"); + return; + } + if (ioctl(tty, VT_GETMODE, &vt_omode) == -1) + { + perror("ioctl VT_GETMODE"); + return; + } + } +#endif +} + +int +fb_postinit(FB_Mode *mode) +{ + if (ioctl(fb,FBIOGET_FSCREENINFO, &fb_fix) == -1) + { + perror("ioctl FBIOGET_FSCREENINFO"); + fb_cleanup(); + return 0; + } + + if (fb_fix.type != FB_TYPE_PACKED_PIXELS) + { + CRIT("can handle only packed pixel frame buffers"); + fb_cleanup(); + return 0; + } + mode->mem_offset = (unsigned)(fb_fix.smem_start) & (getpagesize()-1); + mode->mem = (unsigned char *)mmap(NULL, fb_fix.smem_len + mode->mem_offset, + PROT_WRITE | PROT_READ, MAP_SHARED, fb, 0); + if (mode->mem == MAP_FAILED) + { + perror("mmap"); + fb_cleanup(); + } + /* move viewport to upper left corner */ + if ((mode->fb_var.xoffset != 0) || (mode->fb_var.yoffset != 0)) + { + mode->fb_var.xoffset = 0; + mode->fb_var.yoffset = 0; + + if (ioctl(fb, FBIOPAN_DISPLAY, &(mode->fb_var)) == -1) + { + perror("ioctl FBIOPAN_DISPLAY"); + fb_cleanup(); + } + } +#if 0 + if (tty) + { + if (ioctl(tty,KDSETMODE, KD_GRAPHICS) == -1) + { + perror("ioctl KDSETMODE"); + fb_cleanup(); + } + } +#endif + mode->fb_fd = fb; + return fb; +} + +static void +fb_cleanup(void) +{ + /* restore console */ + if (ioctl(fb, FBIOPUT_VSCREENINFO, &fb_ovar) == -1) + perror("ioctl FBIOPUT_VSCREENINFO"); + if (ioctl(fb, FBIOGET_FSCREENINFO, &fb_fix) == -1) + perror("ioctl FBIOGET_FSCREENINFO"); + if ((fb_ovar.bits_per_pixel == 8) || + (fb_fix.visual == FB_VISUAL_DIRECTCOLOR)) + { + if (ioctl(fb, FBIOPUTCMAP, &ocmap) == -1) + perror("ioctl FBIOPUTCMAP"); + } + close(fb); + if (tty) + { + if (ioctl(tty, KDSETMODE, kd_mode) == -1) + perror("ioctl KDSETMODE"); + if (ioctl(tty, VT_SETMODE, &vt_omode) == -1) + perror("ioctl VT_SETMODE"); +#if 0 + if ((ioctl(tty, VT_ACTIVATE, orig_vt_no) == -1) && (orig_vt_no)) + perror("ioctl VT_ACTIVATE"); +#endif + } + close(tty); +} -- cgit v1.1