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

📄 sdl_fbvideo.c

📁 linux下面的一个开源的多媒体中间件
💻 C
📖 第 1 页 / 共 4 页
字号:
/*    SDL - Simple DirectMedia Layer    Copyright (C) 1997-2006 Sam Lantinga    This library is free software; you can redistribute it and/or    modify it under the terms of the GNU Lesser General Public    License as published by the Free Software Foundation; either    version 2.1 of the License, or (at your option) any later version.    This library 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    Lesser General Public License for more details.    You should have received a copy of the GNU Lesser General Public    License along with this library; if not, write to the Free Software    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA    Sam Lantinga    slouken@libsdl.org*/#include "SDL_config.h"/* Framebuffer console based SDL video driver implementation.*/#include <stdio.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 "SDL_video.h"#include "SDL_mouse.h"#include "../SDL_sysvideo.h"#include "../SDL_pixels_c.h"#include "../../events/SDL_events_c.h"#include "SDL_fbvideo.h"#include "SDL_fbmouse_c.h"#include "SDL_fbevents_c.h"#include "SDL_fb3dfx.h"#include "SDL_fbmatrox.h"#include "SDL_fbriva.h"/*#define FBCON_DEBUG*/#if defined(i386) && defined(FB_TYPE_VGA_PLANES)#define VGA16_FBCON_SUPPORT#include <sys/io.h>		/* For ioperm() */#ifndef FB_AUX_VGA_PLANES_VGA4#define FB_AUX_VGA_PLANES_VGA4	0#endif/*static inline void outb (unsigned char value, unsigned short port){  __asm__ __volatile__ ("outb %b0,%w1"::"a" (value), "Nd" (port));} */#endif /* FB_TYPE_VGA_PLANES *//* A list of video resolutions that we query for (sorted largest to smallest) */static const SDL_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,  720,  576 },		/* PAL */	{  0, 0,  720,  480 },		/* NTSC */	{  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 }};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, SDL_PixelFormat *vformat);static SDL_Rect **FB_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);static SDL_Surface *FB_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);#ifdef VGA16_FBCON_SUPPORTstatic SDL_Surface *FB_SetVGA16Mode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);#endifstatic int FB_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors);static void FB_VideoQuit(_THIS);/* Hardware surface functions */static int FB_InitHWSurfaces(_THIS, SDL_Surface *screen, char *base, int size);static void FB_FreeHWSurfaces(_THIS);static int FB_AllocHWSurface(_THIS, SDL_Surface *surface);static int FB_LockHWSurface(_THIS, SDL_Surface *surface);static void FB_UnlockHWSurface(_THIS, SDL_Surface *surface);static void FB_FreeHWSurface(_THIS, SDL_Surface *surface);static void FB_WaitVBL(_THIS);static void FB_WaitIdle(_THIS);static int FB_FlipHWSurface(_THIS, SDL_Surface *surface);/* Internal palette functions */static void FB_SavePalette(_THIS, struct fb_fix_screeninfo *finfo,                                  struct fb_var_screeninfo *vinfo);static void FB_RestorePalette(_THIS);/* Small wrapper for mmap() so we can play nicely with no-mmu hosts * (non-mmu hosts disallow the MAP_SHARED flag) */static void *do_mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset){	void *ret;	ret = mmap(start, length, prot, flags, fd, offset);	if ( ret == (char *)-1 && (flags & MAP_SHARED) ) {		ret = mmap(start, length, prot,		           (flags & ~MAP_SHARED) | MAP_PRIVATE, fd, offset);	}	return ret;}/* FB driver bootstrap functions */static int FB_Available(void){	int console = -1;	/* Added check for /fb/0 (devfs) */	/* but - use environment variable first... if it fails, still check defaults */	int idx = 0;	const char *SDL_fbdevs[4] = { NULL, "/dev/fb0", "/dev/fb/0", NULL };	SDL_fbdevs[0] = SDL_getenv("SDL_FBDEV");	if( !SDL_fbdevs[0] )		idx++;	for( ; SDL_fbdevs[idx]; idx++ )	{		console = open(SDL_fbdevs[idx], O_RDWR, 0);		if ( console >= 0 ) {			close(console);			break;		}	}	return(console >= 0);}static void FB_DeleteDevice(SDL_VideoDevice *device){	SDL_free(device->hidden);	SDL_free(device);}static SDL_VideoDevice *FB_CreateDevice(int devindex){	SDL_VideoDevice *this;	/* Initialize all variables that we clean on shutdown */	this = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice));	if ( this ) {		SDL_memset(this, 0, (sizeof *this));		this->hidden = (struct SDL_PrivateVideoData *)				SDL_malloc((sizeof *this->hidden));	}	if ( (this == NULL) || (this->hidden == NULL) ) {		SDL_OutOfMemory();		if ( this ) {			SDL_free(this);		}		return(0);	}	SDL_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->UpdateRects = NULL;	this->VideoQuit = FB_VideoQuit;	this->AllocHWSurface = FB_AllocHWSurface;	this->CheckHWBlit = NULL;	this->FillHWRect = NULL;	this->SetHWColorKey = NULL;	this->SetHWAlpha = NULL;	this->LockHWSurface = FB_LockHWSurface;	this->UnlockHWSurface = FB_UnlockHWSurface;	this->FlipHWSurface = FB_FlipHWSurface;	this->FreeHWSurface = FB_FreeHWSurface;	this->SetCaption = NULL;	this->SetIcon = NULL;	this->IconifyWindow = NULL;	this->GrabInput = NULL;	this->GetWMInfo = NULL;	this->InitOSKeymap = FB_InitOSKeymap;	this->PumpEvents = FB_PumpEvents;	this->free = FB_DeleteDevice;	return this;}VideoBootStrap FBCON_bootstrap = {	"fbcon", "Linux Framebuffer Console",	FB_Available, FB_CreateDevice};#define FB_MODES_DB	"/etc/fb.modes"static int read_fbmodes_line(FILE*f, char* line, int length){	int blank;	char* c;	int i;		blank=0;	/* find a relevant line */	do	{		if (fgets(line,length,f)<=0)			return 0;		c=line;		while(((*c=='\t')||(*c==' '))&&(*c!=0))			c++;				if ((*c=='\n')||(*c=='#')||(*c==0))			blank=1;		else			blank=0;	}	while(blank);	/* remove whitespace at the begining of the string */	i=0;	do	{		line[i]=c[i];		i++;	}	while(c[i]!=0);	return 1;}static int read_fbmodes_mode(FILE *f, struct fb_var_screeninfo *vinfo){	char line[1024];	char option[256];	/* Find a "geometry" */	do {		if (read_fbmodes_line(f, line, sizeof(line))==0)			return 0;		if (SDL_strncmp(line,"geometry",8)==0)			break;	}	while(1);	SDL_sscanf(line, "geometry %d %d %d %d %d", &vinfo->xres, &vinfo->yres, 			&vinfo->xres_virtual, &vinfo->yres_virtual, &vinfo->bits_per_pixel);	if (read_fbmodes_line(f, line, sizeof(line))==0)		return 0;				SDL_sscanf(line, "timings %d %d %d %d %d %d %d", &vinfo->pixclock, 			&vinfo->left_margin, &vinfo->right_margin, &vinfo->upper_margin, 			&vinfo->lower_margin, &vinfo->hsync_len, &vinfo->vsync_len);			vinfo->sync=0;	vinfo->vmode=FB_VMODE_NONINTERLACED;					/* Parse misc options */	do {		if (read_fbmodes_line(f, line, sizeof(line))==0)			return 0;		if (SDL_strncmp(line,"hsync",5)==0) {			SDL_sscanf(line,"hsync %s",option);			if (SDL_strncmp(option,"high",4)==0)				vinfo->sync |= FB_SYNC_HOR_HIGH_ACT;		}		else if (SDL_strncmp(line,"vsync",5)==0) {			SDL_sscanf(line,"vsync %s",option);			if (SDL_strncmp(option,"high",4)==0)				vinfo->sync |= FB_SYNC_VERT_HIGH_ACT;		}		else if (SDL_strncmp(line,"csync",5)==0) {			SDL_sscanf(line,"csync %s",option);			if (SDL_strncmp(option,"high",4)==0)				vinfo->sync |= FB_SYNC_COMP_HIGH_ACT;		}		else if (SDL_strncmp(line,"extsync",5)==0) {			SDL_sscanf(line,"extsync %s",option);			if (SDL_strncmp(option,"true",4)==0)				vinfo->sync |= FB_SYNC_EXT;		}		else if (SDL_strncmp(line,"laced",5)==0) {			SDL_sscanf(line,"laced %s",option);			if (SDL_strncmp(option,"true",4)==0)				vinfo->vmode |= FB_VMODE_INTERLACED;		}		else if (SDL_strncmp(line,"double",6)==0) {			SDL_sscanf(line,"double %s",option);			if (SDL_strncmp(option,"true",4)==0)				vinfo->vmode |= FB_VMODE_DOUBLE;		}	}	while(SDL_strncmp(line,"endmode",7)!=0);	return 1;}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, int check_timings){	SDL_Rect *mode;	int i;	int next_mode;	/* Check to see if we already have this mode */	if ( SDL_nummodes[index] > 0 ) {		mode = SDL_modelist[index][SDL_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);		}	}	/* Only allow a mode if we have a valid timing for it */	if ( check_timings ) {		int found_timing = 0;		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 ) {				found_timing = 1;				break;			}		}		if ( !found_timing ) {#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 = (SDL_Rect *)SDL_malloc(sizeof *mode);	if ( mode == NULL ) {		SDL_OutOfMemory();		return(-1);	}

⌨️ 快捷键说明

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