5 #include "../../rtlib/unix/fb_private_console.h"
10 #include <sys/ioctl.h>
16 #ifndef FB_AUX_VGA_PLANES_VGA4
17 #define FB_AUX_VGA_PLANES_VGA4 0
20 #define OUTB(port,value) { __asm__ __volatile__ ("outb %b0, %w1" : : "a"(value), "Nd"(port)); }
32 static int driver_init(
char *title,
int w,
int h,
int depth,
int refresh_rate,
int flags);
38 static int driver_get_mouse(
int *x,
int *y,
int *z,
int *buttons,
int *clip);
67 { 320, 200 }, { 320, 240 }, { 400, 300 }, { 512, 384 }, { 640, 400 }, { 640, 480 },
68 { 800, 600 }, { 1024, 768 }, { 1280, 1024 }, { 1600, 1200 }, { 0, 0 }
87 static pthread_cond_t
cond;
92 unsigned char buffer[fb_fbdev.
w], pattern;
94 int x, y, plane, i,
offset;
108 for (y = 0; y < fb_fbdev.
h; y++) {
112 for (x = 0; x < fb_fbdev.
w; x += 8) {
113 for (plane = 0; plane < 4; plane++) {
115 for (i = 0; i < 8; i++) {
118 color =
color_conv[((color & 0xF0) >> 4) | ((color & 0xF000) >> 8) | ((color & 0xF00000) >> 12)];
124 if (color & (1 << plane))
125 pattern |= 1 << (7 - i);
127 buffer[((fb_fbdev.
w >> 3) * plane) +
offset] = pattern;
132 for (plane = 0; plane < 4; plane++) {
134 OUTB(0x3C5, (1 << plane));
135 fb_hMemCpy(dest, buffer + ((fb_fbdev.
w >> 3) * plane), (fb_fbdev.
w >> 3));
145 struct fb_vblank vblank;
146 unsigned int count, cur_time;
148 struct timeval cur_tv, tv = { 0, 0 };
149 unsigned char buffer[1024];
150 int buttons, bytes_read, bytes_left = 0;
157 pthread_mutex_lock(&
mutex);
158 pthread_cond_signal(&
cond);
159 pthread_mutex_unlock(&
mutex);
162 pthread_mutex_lock(&
mutex);
167 if (select(FD_SETSIZE, &set,
NULL,
NULL, &tv) > 0) {
168 bytes_read = read(
mouse_fd, &buffer[bytes_left],
sizeof(buffer) - bytes_left);
169 if (bytes_read > 0) {
170 bytes_left += bytes_read;
176 e.
dx = (
unsigned int)buffer[1] - ((
int)(buffer[0] & 0x10) << 4);
177 e.
dy = -(
unsigned int)buffer[2] + ((
int)(buffer[0] & 0x20) << 3);
189 mouse_z += (((buffer[3] & 0xF) - 7) >> 3);
198 gettimeofday(&cur_tv,
NULL);
199 cur_time = (cur_tv.tv_sec * 1000) + (cur_tv.tv_usec / 1000);
213 bytes_left -= bytes_read;
214 memcpy(buffer, &buffer[bytes_read], bytes_left);
220 if (
vsync_flags & (FB_VBLANK_HAVE_VBLANK | FB_VBLANK_HAVE_VCOUNT)) {
222 ioctl(
device_fd, FBIOGET_VBLANK, &vblank);
224 count = vblank.vcount;
225 }
while ((ioctl(
device_fd, FBIOGET_VBLANK, &vblank) == 0) && (vblank.vcount >= count));
228 while ((ioctl(
device_fd, FBIOGET_VBLANK, &vblank) == 0) && (vblank.flags & FB_VBLANK_VBLANKING))
230 while ((ioctl(
device_fd, FBIOGET_VBLANK, &vblank) == 0) && (!(vblank.flags & FB_VBLANK_VBLANKING)))
234 pthread_cond_signal(&
cond);
254 pthread_mutex_unlock(&
mutex);
256 if (
vsync_flags & (FB_VBLANK_HAVE_VBLANK | FB_VBLANK_HAVE_VCOUNT))
269 pthread_mutex_lock(&
mutex);
271 pthread_mutex_unlock(&
mutex);
281 pthread_mutex_lock(&
mutex);
286 pthread_mutex_unlock(&
mutex);
308 e.
ascii = ((key < 0) || (key > 0xFF)) ? 0 :
key;
313 static int driver_init(
char *title,
int w,
int h,
int depth,
int refresh_rate,
int flags)
315 const char *device_name;
316 int try, res_index, i, j, r, g, b, dist, best_dist, best_index = 0;
319 struct fb_vblank vblank;
320 const char *mouse_device[] = {
"/dev/input/mice",
"/dev/usbmouse",
"/dev/psaux",
NULL };
321 const unsigned char im_init[] = { 243, 200, 243, 100, 243, 80 };
328 fb_fbdev.
flags = flags;
329 depth =
MAX(depth, 4);
331 device_name = getenv(
"FBGFX_FRAMEBUFFER");
333 device_name =
"/dev/fb0";
334 device_fd = open(device_name, O_RDWR, 0);
341 #
if defined(i386) && defined(FB_TYPE_VGA_PLANES)
353 #if defined(i386) && defined(FB_TYPE_VGA_PLANES)
373 for (
try = 0;
try < 4;
try++) {
380 mode.bits_per_pixel = depth;
384 mode.red.offset = 10; mode.red.length = 5;
385 mode.green.offset = 5; mode.green.length = 5;
386 mode.blue.offset = 0; mode.blue.length = 5;
389 mode.red.offset = 11; mode.red.length = 5;
390 mode.green.offset = 5; mode.green.length = 6;
391 mode.blue.offset = 0; mode.blue.length = 5;
395 mode.red.offset = 16; mode.red.length = 8;
396 mode.green.offset = 8; mode.green.length = 8;
397 mode.blue.offset = 0; mode.blue.length = 8;
400 mode.red.offset = mode.red.length = 0;
401 mode.green.offset = mode.green.length = 0;
402 mode.blue.offset = mode.blue.length = 0;
405 mode.red.msb_right = mode.green.msb_right = mode.blue.msb_right = 0;
409 for (res_index = 0; standard_mode[res_index].
w; res_index++) {
410 if ((standard_mode[res_index].w >= w) && (standard_mode[res_index].h > h)) {
411 mode.xres = mode.xres_virtual = standard_mode[res_index].
w;
412 mode.yres = mode.yres_virtual = standard_mode[res_index].
h;
413 if (ioctl(
device_fd, FBIOPUT_VSCREENINFO, &mode) == 0)
419 mode.xres = mode.xres_virtual = w;
420 mode.yres = mode.yres_virtual = h;
421 if (ioctl(
device_fd, FBIOPUT_VSCREENINFO, &mode) == 0)
427 if ((mode.xres >= w) && (mode.yres >= h))
450 if (mode.bits_per_pixel == 4) {
452 framebuffer_offset = (((mode.yres - h) >> 1) * (mode.xres >> 3)) + ((mode.xres - w) >> 4);
464 for (
try = 0; mouse_device[
try];
try++) {
465 mouse_fd = open(mouse_device[
try], O_RDWR, 0);
466 if ((
mouse_fd >= 0) && (write(
mouse_fd, im_init,
sizeof(im_init)) ==
sizeof(im_init))) {
471 mouse_fd = open(mouse_device[
try], O_RDONLY, 0);
483 palette = (
unsigned short *)malloc(
sizeof(
unsigned short) * 1536);
492 cmap.len = palette_len;
497 if ((mode.bits_per_pixel == 4) && (depth == 8)) {
499 for (i = 0; i < 16; i++) {
506 for (i = 0; i < 4096; i++) {
510 b = (i & 0xF00) >> 4;
511 for (j = 0; j < 16; j++) {
513 if (dist < best_dist) {
522 if (ioctl(
device_fd, FBIOGET_VBLANK, &vblank) == 0)
527 pthread_mutex_lock(&
mutex);
529 pthread_mutex_unlock(&
mutex);
533 pthread_mutex_unlock(&
mutex);
543 pthread_mutex_destroy(&
mutex);
544 pthread_cond_destroy(&
cond);
572 pthread_mutex_lock(&
mutex);
577 pthread_mutex_unlock(&
mutex);
582 cmap.red[index] = r << 8;
583 cmap.green[index] = g << 8;
584 cmap.blue[index] = b << 8;
590 pthread_mutex_lock(&
mutex);
592 pthread_mutex_unlock(&
mutex);
609 if ((x >= 0) && (x < __fb_gfx->w))
611 if ((y >= 0) && (y < __fb_gfx->h))
622 const char *device_name;
623 int i, fd, num_sizes = 0, *sizes =
NULL;
625 if ((depth != 8) && (depth != 15) && (depth != 16) && (depth != 24) && (depth != 32))
629 device_name = getenv(
"FBGFX_FRAMEBUFFER");
631 device_name =
"/dev/fb0";
632 fd = open(device_name, O_RDWR, 0);
639 ioctl(fd, FBIOGET_VSCREENINFO, &mode);
640 for (i = 0; standard_mode[i].
w; i++) {
641 mode.bits_per_pixel = depth;
642 mode.activate = FB_ACTIVATE_TEST;
643 mode.xres = mode.xres_virtual = standard_mode[i].
w;
644 mode.yres = mode.yres_virtual = standard_mode[i].
h;
645 if (ioctl(fd, FBIOPUT_VSCREENINFO, &mode) == 0) {
647 sizes = realloc(sizes, num_sizes *
sizeof(
int));
648 sizes[num_sizes - 1] = (mode.xres << 16) | mode.yres;
659 int fb_hFBDevInfo(ssize_t *width, ssize_t *height, ssize_t *depth, ssize_t *refresh)
661 struct fb_var_screeninfo temp, *info;
662 int fd = -1, htotal, vtotal, flags, res;
665 if ((fd = open(
"/dev/fb0", O_RDWR, 0)) < 0)
667 res = ioctl(fd, FBIOGET_VSCREENINFO, &temp);
676 htotal = info->left_margin + info->xres + info->right_margin + info->hsync_len;
677 vtotal = info->upper_margin + info->yres + info->lower_margin + info->vsync_len;
678 flags = info->vmode & FB_VMODE_MASK;
680 if (!(flags == FB_VMODE_INTERLACED))
682 if (flags == FB_VMODE_DOUBLE)
686 *height = info->yres;
687 *depth = info->bits_per_pixel;
688 if ((info->pixclock) && (htotal) && (vtotal))
689 *refresh = (((1e12 / info->pixclock) / htotal) / vtotal) * 2;