⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fbvideo.c

📁 libminigui-1.3.0.tar.gz。 miniGUI的库函数源代码!
💻 C
📖 第 1 页 / 共 4 页
字号:
/***  $Id: fbvideo.c,v 1.27 2003/11/23 05:40:52 weiym Exp $**  **  Port to MiniGUI by Wei Yongming (2001/10/03).**  Copyright (C) 2001 ~ 2002 Wei Yongming.**  Copyright (C) 2003 Feynman Software.****  SDL - Simple DirectMedia Layer**  Copyright (C) 1997, 1998, 1999, 2000, 2001  Sam Lantinga*//*** This program is free software; you can redistribute it and/or modify** it under the terms of the GNU General Public License as published by** the Free Software Foundation; either version 2 of the License, or** (at your option) any later version.**** This program is distributed in the hope that it will be useful,** but WITHOUT ANY WARRANTY; without even the implied warranty of** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the** GNU General Public License for more details.**** You should have received a copy of the GNU General Public License** along with this program; if not, write to the Free Software** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA*//* Framebuffer console based video driver implementation.*/#include <stdlib.h>#include <stdio.h>#include <string.h>#include <fcntl.h>#include <unistd.h>#include <sys/ioctl.h>#include <sys/mman.h>#include <asm/page.h>        /* For definition of PAGE_SIZE */#include <linux/vt.h>#include <linux/kd.h>#include <linux/keyboard.h>#include "common.h"#include "minigui.h"#if defined(_LITE_VERSION) && !defined(_STAND_ALONE)#include "client.h"#endif#include "newgal.h"#include "sysvideo.h"#include "pixels_c.h"#include "fbvideo.h"#include "fb3dfx.h"#include "fbmatrox.h"#include "fbneomagic.h"/*#define FBACCEL_DEBUG   1#define FBCON_DEBUG   1*/#if defined(i386) && defined(FB_TYPE_VGA_PLANES)#if 0#define VGA16_FBCON_SUPPORT#include <sys/io.h>#ifndef FB_AUX_VGA_PLANES_VGA4#define FB_AUX_VGA_PLANES_VGA4    0#endifinline static void outb (unsigned char value, unsigned short port){  __asm__ __volatile__ ("outb %b0,%w1"::"a" (value), "Nd" (port));} #endif#endif /* FB_TYPE_VGA_PLANES *//* A list of video resolutions that we query for (sorted largest to smallest) */static const GAL_Rect checkres[] = {    {  0, 0, 1600, 1200 },        /* 16 bpp: 0x11E, or 286 */    {  0, 0, 1408, 1056 },        /* 16 bpp: 0x19A, or 410 */    {  0, 0, 1280, 1024 },        /* 16 bpp: 0x11A, or 282 */    {  0, 0, 1152,  864 },        /* 16 bpp: 0x192, or 402 */    {  0, 0, 1024,  768 },        /* 16 bpp: 0x117, or 279 */    {  0, 0,  960,  720 },        /* 16 bpp: 0x18A, or 394 */    {  0, 0,  800,  600 },        /* 16 bpp: 0x114, or 276 */    {  0, 0,  768,  576 },        /* 16 bpp: 0x182, or 386 */    {  0, 0,  640,  480 },        /* 16 bpp: 0x111, or 273 */    {  0, 0,  640,  400 },        /*  8 bpp: 0x100, or 256 */    {  0, 0,  512,  384 },    {  0, 0,  320,  240 },    {  0, 0,  320,  200 },    {  0, 0,  240,  320 },    {  0, 0,  160,  160 },    {  0, 0,  60,  60 }};static const struct {    int xres;    int yres;    int pixclock;    int left;    int right;    int upper;    int lower;    int hslen;    int vslen;    int sync;    int vmode;} vesa_timings[] = {#ifdef USE_VESA_TIMINGS    /* Only tested on Matrox Millenium I */    {  640,  400, 39771,  48, 16, 39,  8,  96, 2, 2, 0 },    /* 70 Hz */    {  640,  480, 39683,  48, 16, 33, 10,  96, 2, 0, 0 },    /* 60 Hz */    {  768,  576, 26101, 144, 16, 28,  6, 112, 4, 0, 0 },    /* 60 Hz */    {  800,  600, 24038, 144, 24, 28,  8, 112, 6, 0, 0 },    /* 60 Hz */    {  960,  720, 17686, 144, 24, 28,  8, 112, 4, 0, 0 },    /* 60 Hz */    { 1024,  768, 15386, 160, 32, 30,  4, 128, 4, 0, 0 },    /* 60 Hz */    { 1152,  864, 12286, 192, 32, 30,  4, 128, 4, 0, 0 },    /* 60 Hz */    { 1280, 1024,  9369, 224, 32, 32,  4, 136, 4, 0, 0 },    /* 60 Hz */    { 1408, 1056,  8214, 256, 40, 32,  5, 144, 5, 0, 0 },    /* 60 Hz */    { 1600, 1200,/*?*/0, 272, 48, 32,  5, 152, 5, 0, 0 },    /* 60 Hz */#else    /* You can generate these timings from your XF86Config file using       the 'modeline2fb' perl script included with the fbset package.       These timings were generated for Matrox Millenium I, 15" monitor.    */    {  320,  200, 79440,  16, 16, 20,  4,  48, 1, 0, 2 },    /* 70 Hz */    {  320,  240, 63492,  16, 16, 16,  4,  48, 2, 0, 2 },    /* 72 Hz */    {  512,  384, 49603,  48, 16, 16,  1,  64, 3, 0, 0 },    /* 78 Hz */    {  640,  400, 31746,  96, 32, 41,  1,  64, 3, 2, 0 },    /* 85 Hz */    {  640,  480, 31746, 120, 16, 16,  1,  64, 3, 0, 0 },    /* 75 Hz */    {  768,  576, 26101, 144, 16, 28,  6, 112, 4, 0, 0 },    /* 60 Hz */    {  800,  600, 20000,  64, 56, 23, 37, 120, 6, 3, 0 },    /* 72 Hz */    {  960,  720, 17686, 144, 24, 28,  8, 112, 4, 0, 0 },    /* 60 Hz */    { 1024,  768, 13333, 144, 24, 29,  3, 136, 6, 0, 0 },    /* 70 Hz */    { 1152,  864, 12286, 192, 32, 30,  4, 128, 4, 0, 0 },    /* 60 Hz */    { 1280, 1024,  9369, 224, 32, 32,  4, 136, 4, 0, 0 },    /* 60 Hz */    { 1408, 1056,  8214, 256, 40, 32,  5, 144, 5, 0, 0 },    /* 60 Hz */    { 1600, 1200,/*?*/0, 272, 48, 32,  5, 152, 5, 0, 0 },    /* 60 Hz */#endif};/* Initialization/Query functions */static int FB_VideoInit(_THIS, GAL_PixelFormat *vformat);static GAL_Rect **FB_ListModes(_THIS, GAL_PixelFormat *format, Uint32 flags);static GAL_Surface *FB_SetVideoMode(_THIS, GAL_Surface *current, int width, int height, int bpp, Uint32 flags);#ifdef VGA16_FBCON_SUPPORTstatic GAL_Surface *FB_SetVGA16Mode(_THIS, GAL_Surface *current, int width, int height, int bpp, Uint32 flags);#endifstatic int FB_SetColors(_THIS, int firstcolor, int ncolors, GAL_Color *colors);static void FB_VideoQuit(_THIS);/* Hardware surface functions */static int FB_InitHWSurfaces(_THIS, GAL_Surface *screen, char *base, int size);static void FB_FreeHWSurfaces(_THIS);static void FB_RequestHWSurface (_THIS, const REQ_HWSURFACE* request, REP_HWSURFACE* reply);static int FB_AllocHWSurface(_THIS, GAL_Surface *surface);static void FB_FreeHWSurface(_THIS, GAL_Surface *surface);static void FB_WaitVBL(_THIS);static void FB_WaitIdle(_THIS);#if 0static int FB_LockHWSurface(_THIS, GAL_Surface *surface);static void FB_UnlockHWSurface(_THIS, GAL_Surface *surface);static int FB_FlipHWSurface(_THIS, GAL_Surface *surface);#endif/* Internal palette functions */static void FB_SavePalette(_THIS, struct fb_fix_screeninfo *finfo,                                  struct fb_var_screeninfo *vinfo);static void FB_RestorePalette(_THIS);/* FB driver bootstrap functions */static int FB_Available(void){    int console;    const char *GAL_fbdev;    GAL_fbdev = getenv("FRAMEBUFFER");    if ( GAL_fbdev == NULL ) {        GAL_fbdev = "/dev/fb0";    }    console = open(GAL_fbdev, O_RDWR, 0);    if ( console >= 0 ) {        close(console);    }    return(console >= 0);}static void FB_DeleteDevice(GAL_VideoDevice *device){    free(device->hidden);    free(device);}static GAL_VideoDevice *FB_CreateDevice(int devindex){    GAL_VideoDevice *this;    /* Initialize all variables that we clean on shutdown */    this = (GAL_VideoDevice *)malloc(sizeof(GAL_VideoDevice));    if ( this ) {        memset(this, 0, (sizeof *this));        this->hidden = (struct GAL_PrivateVideoData *)                malloc((sizeof *this->hidden));    }    if ( (this == NULL) || (this->hidden == NULL) ) {        GAL_OutOfMemory();        if ( this ) {            free(this);        }        return(0);    }    memset(this->hidden, 0, (sizeof *this->hidden));    wait_vbl = FB_WaitVBL;    wait_idle = FB_WaitIdle;    mouse_fd = -1;    keyboard_fd = -1;    /* Set the function pointers */    this->VideoInit = FB_VideoInit;    this->ListModes = FB_ListModes;    this->SetVideoMode = FB_SetVideoMode;    this->SetColors = FB_SetColors;    this->VideoQuit = FB_VideoQuit;#if defined(_LITE_VERSION) && !defined(_STAND_ALONE)    this->RequestHWSurface = FB_RequestHWSurface;#endif    this->AllocHWSurface = FB_AllocHWSurface;    this->CheckHWBlit = NULL;    this->FillHWRect = NULL;    this->SetHWColorKey = NULL;    this->SetHWAlpha = NULL;    this->UpdateRects = NULL;#if 0    this->LockHWSurface = FB_LockHWSurface;    this->UnlockHWSurface = FB_UnlockHWSurface;    this->FlipHWSurface = FB_FlipHWSurface;#endif    this->FreeHWSurface = FB_FreeHWSurface;    this->free = FB_DeleteDevice;    return this;}VideoBootStrap FBCON_bootstrap = {    "fbcon", "Linux Framebuffer Console",    FB_Available, FB_CreateDevice};static int FB_CheckMode(_THIS, struct fb_var_screeninfo *vinfo,                        int index, unsigned int *w, unsigned int *h){    int mode_okay;    mode_okay = 0;    vinfo->bits_per_pixel = (index+1)*8;    vinfo->xres = *w;    vinfo->xres_virtual = *w;    vinfo->yres = *h;    vinfo->yres_virtual = *h;    vinfo->activate = FB_ACTIVATE_TEST;    if ( ioctl(console_fd, FBIOPUT_VSCREENINFO, vinfo) == 0 ) {#ifdef FBCON_DEBUG        fprintf(stderr, "Checked mode %dx%d at %d bpp, got mode %dx%d at %d bpp\n", *w, *h, (index+1)*8, vinfo->xres, vinfo->yres, vinfo->bits_per_pixel);#endif        if ( (((vinfo->bits_per_pixel+7)/8)-1) == index ) {            *w = vinfo->xres;            *h = vinfo->yres;            mode_okay = 1;        }    }    return mode_okay;}static int FB_AddMode(_THIS, int index, unsigned int w, unsigned int h){    GAL_Rect *mode;    int i;    int next_mode;    /* Check to see if we already have this mode */    if ( GAL_nummodes[index] > 0 ) {        mode = GAL_modelist[index][GAL_nummodes[index]-1];        if ( (mode->w == w) && (mode->h == h) ) {#ifdef FBCON_DEBUG            fprintf(stderr, "We already have mode %dx%d at %d bytes per pixel\n", w, h, index+1);#endif            return(0);        }    }    if (w >= 320) {        /* Only allow a mode if we have a valid timing for it */        next_mode = -1;        for ( i=0; i<(sizeof(vesa_timings)/sizeof(vesa_timings[0])); ++i ) {            if ( (w == vesa_timings[i].xres) &&                (h == vesa_timings[i].yres) && vesa_timings[i].pixclock ) {                next_mode = i;                break;            }        }        if ( next_mode == -1 ) {#ifdef FBCON_DEBUG            fprintf(stderr, "No valid timing line for mode %dx%d\n", w, h);#endif            return(0);        }    }    /* Set up the new video mode rectangle */    mode = (GAL_Rect *)malloc(sizeof *mode);    if ( mode == NULL ) {        GAL_OutOfMemory();        return(-1);    }    mode->x = 0;    mode->y = 0;    mode->w = w;    mode->h = h;#ifdef FBCON_DEBUG    fprintf(stderr, "Adding mode %dx%d at %d bytes per pixel\n", w, h, index+1);#endif    /* Allocate the new list of modes, and fill in the new mode */    next_mode = GAL_nummodes[index];    GAL_modelist[index] = (GAL_Rect **)           realloc(GAL_modelist[index], (1+next_mode+1)*sizeof(GAL_Rect *));    if ( GAL_modelist[index] == NULL ) {        GAL_OutOfMemory();        GAL_nummodes[index] = 0;        free(mode);        return(-1);    }    GAL_modelist[index][next_mode] = mode;    GAL_modelist[index][next_mode+1] = NULL;    GAL_nummodes[index]++;    return(0);}static int ttyfd = -1;static void FB_LeaveGraphicsMode (_THIS){#ifdef _HAVE_TEXT_MODE#if defined(_LITE_VERSION) && !defined(_STAND_ALONE)    if (mgIsServer) {#endif        /* enter text mode*/        if (ttyfd >= 0) {            ioctl (ttyfd, KDSETMODE, KD_TEXT);            close (ttyfd);            ttyfd = -1;        }#if defined(_LITE_VERSION) && !defined(_STAND_ALONE)    }#endif#endif}static int FB_EnterGraphicsMode (_THIS){#ifdef _HAVE_TEXT_MODE#if defined(_LITE_VERSION) && !defined(_STAND_ALONE)    if (mgIsServer) {#endif        char* tty_dev;        if (geteuid() == 0)            tty_dev = "/dev/tty0";        else    /* not a super user, so try to open the control terminal */            tty_dev = "/dev/tty";        /* open tty, enter graphics mode */        ttyfd = open (tty_dev, O_RDWR);        if (ttyfd < 0) {            fprintf (stderr,"GAL ENGINE: Can't open %s: %m\n", tty_dev);            goto fail;        }        if (ioctl (ttyfd, KDSETMODE, KD_GRAPHICS) == -1) {            fprintf (stderr,"GAL ENGINE: Error when setting the terminal to graphics mode: %m\n");            fprintf (stderr,"GAL ENGINE: Maybe is not a console.\n");            goto fail;        }#if defined(_LITE_VERSION) && !defined(_STAND_ALONE)    }    else {        ttyfd = 0;    }#endif    return ttyfd;fail:    FB_LeaveGraphicsMode (this);    return -1;#else    return 0;#endif}static int FB_OpenKeyboard(_THIS){#if 1    return 0;#else    /* Open only if not already opened */     if ( keyboard_fd < 0 ) {        static const char * const tty0[] = { "/dev/tty0", "/dev/vc/0", NULL };        static const char * const vcs[] = { "/dev/vc/%d", "/dev/tty%d", NULL };        int i, tty0_fd;        /* Try to query for a free virtual terminal */        tty0_fd = -1;        for ( i=0; tty0[i] && (tty0_fd < 0); ++i ) {            tty0_fd = open(tty0[i], O_WRONLY, 0);        }        if ( tty0_fd < 0 ) {            tty0_fd = dup(0); /* Maybe stdin is a VT? */        }        ioctl(tty0_fd, VT_OPENQRY, &current_vt);        close(tty0_fd);        if ( (geteuid() == 0) && (current_vt > 0) ) {            for ( i=0; vcs[i] && (keyboard_fd < 0); ++i ) {                char vtpath[12];                sprintf(vtpath, vcs[i], current_vt);                keyboard_fd = open(vtpath, O_RDWR, 0);#ifdef DEBUG_KEYBOARD                fprintf(stderr, "vtpath = %s, fd = %d\n",                    vtpath, keyboard_fd);#endif /* DEBUG_KEYBOARD */                /* This needs to be our controlling tty                   so that the kernel ioctl() calls work                */                if ( keyboard_fd >= 0 ) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -