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

📄 sdl_fbvideo.c

📁 linux下面的一个开源的多媒体中间件
💻 C
📖 第 1 页 / 共 4 页
字号:
	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 = SDL_nummodes[index];	SDL_modelist[index] = (SDL_Rect **)	       SDL_realloc(SDL_modelist[index], (1+next_mode+1)*sizeof(SDL_Rect *));	if ( SDL_modelist[index] == NULL ) {		SDL_OutOfMemory();		SDL_nummodes[index] = 0;		SDL_free(mode);		return(-1);	}	SDL_modelist[index][next_mode] = mode;	SDL_modelist[index][next_mode+1] = NULL;	SDL_nummodes[index]++;	return(0);}static int cmpmodes(const void *va, const void *vb){    const SDL_Rect *a = *(const SDL_Rect**)va;    const SDL_Rect *b = *(const SDL_Rect**)vb;    if ( a->h == b->h )        return b->w - a->w;    else        return b->h - a->h;}static void FB_SortModes(_THIS){	int i;	for ( i=0; i<NUM_MODELISTS; ++i ) {		if ( SDL_nummodes[i] > 0 ) {			SDL_qsort(SDL_modelist[i], SDL_nummodes[i], sizeof *SDL_modelist[i], cmpmodes);		}	}}static int FB_VideoInit(_THIS, SDL_PixelFormat *vformat){	struct fb_fix_screeninfo finfo;	struct fb_var_screeninfo vinfo;	int i, j;	int current_index;	unsigned int current_w;	unsigned int current_h;	const char *SDL_fbdev;	FILE *modesdb;	/* Initialize the library */	SDL_fbdev = SDL_getenv("SDL_FBDEV");	if ( SDL_fbdev == NULL ) {		SDL_fbdev = "/dev/fb0";	}	console_fd = open(SDL_fbdev, O_RDWR, 0);	if ( console_fd < 0 ) {		SDL_SetError("Unable to open %s", SDL_fbdev);		return(-1);	}#if !SDL_THREADS_DISABLED	/* Create the hardware surface lock mutex */	hw_lock = SDL_CreateMutex();	if ( hw_lock == NULL ) {		SDL_SetError("Unable to create lock mutex");		FB_VideoQuit(this);		return(-1);	}#endif	/* Get the type of video hardware */	if ( ioctl(console_fd, FBIOGET_FSCREENINFO, &finfo) < 0 ) {		SDL_SetError("Couldn't get console hardware info");		FB_VideoQuit(this);		return(-1);	}	switch (finfo.type) {		case FB_TYPE_PACKED_PIXELS:			/* Supported, no worries.. */			break;#ifdef VGA16_FBCON_SUPPORT		case FB_TYPE_VGA_PLANES:			/* VGA16 is supported, but that's it */			if ( finfo.type_aux == FB_AUX_VGA_PLANES_VGA4 ) {				if ( ioperm(0x3b4, 0x3df - 0x3b4 + 1, 1) < 0 ) {					SDL_SetError("No I/O port permissions");					FB_VideoQuit(this);					return(-1);				}				this->SetVideoMode = FB_SetVGA16Mode;				break;			}			/* Fall through to unsupported case */#endif /* VGA16_FBCON_SUPPORT */		default:			SDL_SetError("Unsupported console hardware");			FB_VideoQuit(this);			return(-1);	}	switch (finfo.visual) {		case FB_VISUAL_TRUECOLOR:		case FB_VISUAL_PSEUDOCOLOR:		case FB_VISUAL_STATIC_PSEUDOCOLOR:		case FB_VISUAL_DIRECTCOLOR:			break;		default:			SDL_SetError("Unsupported console hardware");			FB_VideoQuit(this);			return(-1);	}	/* Check if the user wants to disable hardware acceleration */	{ const char *fb_accel;		fb_accel = SDL_getenv("SDL_FBACCEL");		if ( fb_accel ) {			finfo.accel = SDL_atoi(fb_accel);		}	}	/* Memory map the device, compensating for buggy PPC mmap() */	mapped_offset = (((long)finfo.smem_start) -	                (((long)finfo.smem_start)&~(PAGE_SIZE-1)));	mapped_memlen = finfo.smem_len+mapped_offset;	mapped_mem = do_mmap(NULL, mapped_memlen,	                  PROT_READ|PROT_WRITE, MAP_SHARED, console_fd, 0);	if ( mapped_mem == (char *)-1 ) {		SDL_SetError("Unable to memory map the video hardware");		mapped_mem = NULL;		FB_VideoQuit(this);		return(-1);	}	/* Determine the current screen depth */	if ( ioctl(console_fd, FBIOGET_VSCREENINFO, &vinfo) < 0 ) {		SDL_SetError("Couldn't get console pixel format");		FB_VideoQuit(this);		return(-1);	}	vformat->BitsPerPixel = vinfo.bits_per_pixel;	if ( vformat->BitsPerPixel < 8 ) {		/* Assuming VGA16, we handle this via a shadow framebuffer */		vformat->BitsPerPixel = 8;	}	for ( i=0; i<vinfo.red.length; ++i ) {		vformat->Rmask <<= 1;		vformat->Rmask |= (0x00000001<<vinfo.red.offset);	}	for ( i=0; i<vinfo.green.length; ++i ) {		vformat->Gmask <<= 1;		vformat->Gmask |= (0x00000001<<vinfo.green.offset);	}	for ( i=0; i<vinfo.blue.length; ++i ) {		vformat->Bmask <<= 1;		vformat->Bmask |= (0x00000001<<vinfo.blue.offset);	}	saved_vinfo = vinfo;	/* Save hardware palette, if needed */	FB_SavePalette(this, &finfo, &vinfo);	/* If the I/O registers are available, memory map them so we	   can take advantage of any supported hardware acceleration.	 */	vinfo.accel_flags = 0;	/* Temporarily reserve registers */	ioctl(console_fd, FBIOPUT_VSCREENINFO, &vinfo);	if ( finfo.accel && finfo.mmio_len ) {		mapped_iolen = finfo.mmio_len;		mapped_io = do_mmap(NULL, mapped_iolen, PROT_READ|PROT_WRITE,		                 MAP_SHARED, console_fd, mapped_memlen);		if ( mapped_io == (char *)-1 ) {			/* Hmm, failed to memory map I/O registers */			mapped_io = NULL;		}	}	/* Query for the list of available video modes */	current_w = vinfo.xres;	current_h = vinfo.yres;	current_index = ((vinfo.bits_per_pixel+7)/8)-1;	modesdb = fopen(FB_MODES_DB, "r");	for ( i=0; i<NUM_MODELISTS; ++i ) {		SDL_nummodes[i] = 0;		SDL_modelist[i] = NULL;	}	if ( SDL_getenv("SDL_FB_BROKEN_MODES") != NULL ) {		FB_AddMode(this, current_index, current_w, current_h, 0);	} else if(modesdb) {		while ( read_fbmodes_mode(modesdb, &vinfo) ) {			for ( i=0; i<NUM_MODELISTS; ++i ) {				unsigned int w, h;				/* See if we are querying for the current mode */				w = vinfo.xres;				h = vinfo.yres;				if ( i == current_index ) {					if ( (current_w > w) || (current_h > h) ) {						/* Only check once */						FB_AddMode(this, i, current_w, current_h, 0);						current_index = -1;					}				}				if ( FB_CheckMode(this, &vinfo, i, &w, &h) ) {					FB_AddMode(this, i, w, h, 0);				}			}		}		fclose(modesdb);		FB_SortModes(this);	} else {		for ( i=0; i<NUM_MODELISTS; ++i ) {			for ( j=0; j<(sizeof(checkres)/sizeof(checkres[0])); ++j ) {				unsigned int w, h;				/* See if we are querying for the current mode */				w = checkres[j].w;				h = checkres[j].h;				if ( i == current_index ) {					if ( (current_w > w) || (current_h > h) ) {						/* Only check once */						FB_AddMode(this, i, current_w, current_h, 0);						current_index = -1;					}				}				if ( FB_CheckMode(this, &vinfo, i, &w, &h) ) {					FB_AddMode(this, i, w, h, 1);				}			}		}	}	/* Fill in our hardware acceleration capabilities */	this->info.current_w = current_w;	this->info.current_h = current_h;	this->info.wm_available = 0;	this->info.hw_available = 1;	this->info.video_mem = finfo.smem_len/1024;	if ( mapped_io ) {		switch (finfo.accel) {		    case FB_ACCEL_MATROX_MGA2064W:		    case FB_ACCEL_MATROX_MGA1064SG:		    case FB_ACCEL_MATROX_MGA2164W:		    case FB_ACCEL_MATROX_MGA2164W_AGP:		    case FB_ACCEL_MATROX_MGAG100:		    /*case FB_ACCEL_MATROX_MGAG200: G200 acceleration broken! */		    case FB_ACCEL_MATROX_MGAG400:#ifdef FBACCEL_DEBUG			printf("Matrox hardware accelerator!\n");#endif			FB_MatroxAccel(this, finfo.accel);			break;		    case FB_ACCEL_3DFX_BANSHEE:#ifdef FBACCEL_DEBUG			printf("3DFX hardware accelerator!\n");#endif			FB_3DfxAccel(this, finfo.accel);			break;		    case FB_ACCEL_NV3:		    case FB_ACCEL_NV4:#ifdef FBACCEL_DEBUG			printf("NVidia hardware accelerator!\n");#endif			FB_RivaAccel(this, finfo.accel);			break;		    default:#ifdef FBACCEL_DEBUG			printf("Unknown hardware accelerator.\n");#endif			break;		}	}	/* Enable mouse and keyboard support */	if ( FB_OpenKeyboard(this) < 0 ) {		FB_VideoQuit(this);		return(-1);	}	if ( FB_OpenMouse(this) < 0 ) {		const char *sdl_nomouse;		sdl_nomouse = SDL_getenv("SDL_NOMOUSE");		if ( ! sdl_nomouse ) {			SDL_SetError("Unable to open mouse");			FB_VideoQuit(this);			return(-1);		}	}	/* We're done! */	return(0);}static SDL_Rect **FB_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags){	return(SDL_modelist[((format->BitsPerPixel+7)/8)-1]);}/* Various screen update functions available */static void FB_DirectUpdate(_THIS, int numrects, SDL_Rect *rects);#ifdef VGA16_FBCON_SUPPORTstatic void FB_VGA16Update(_THIS, int numrects, SDL_Rect *rects);#endif#ifdef FBCON_DEBUGstatic void print_vinfo(struct fb_var_screeninfo *vinfo){	fprintf(stderr, "Printing vinfo:\n");	fprintf(stderr, "\txres: %d\n", vinfo->xres);	fprintf(stderr, "\tyres: %d\n", vinfo->yres);	fprintf(stderr, "\txres_virtual: %d\n", vinfo->xres_virtual);	fprintf(stderr, "\tyres_virtual: %d\n", vinfo->yres_virtual);	fprintf(stderr, "\txoffset: %d\n", vinfo->xoffset);	fprintf(stderr, "\tyoffset: %d\n", vinfo->yoffset);	fprintf(stderr, "\tbits_per_pixel: %d\n", vinfo->bits_per_pixel);	fprintf(stderr, "\tgrayscale: %d\n", vinfo->grayscale);	fprintf(stderr, "\tnonstd: %d\n", vinfo->nonstd);	fprintf(stderr, "\tactivate: %d\n", vinfo->activate);	fprintf(stderr, "\theight: %d\n", vinfo->height);	fprintf(stderr, "\twidth: %d\n", vinfo->width);	fprintf(stderr, "\taccel_flags: %d\n", vinfo->accel_flags);	fprintf(stderr, "\tpixclock: %d\n", vinfo->pixclock);	fprintf(stderr, "\tleft_margin: %d\n", vinfo->left_margin);	fprintf(stderr, "\tright_margin: %d\n", vinfo->right_margin);	fprintf(stderr, "\tupper_margin: %d\n", vinfo->upper_margin);	fprintf(stderr, "\tlower_margin: %d\n", vinfo->lower_margin);	fprintf(stderr, "\thsync_len: %d\n", vinfo->hsync_len);	fprintf(stderr, "\tvsync_len: %d\n", vinfo->vsync_len);	fprintf(stderr, "\tsync: %d\n", vinfo->sync);	fprintf(stderr, "\tvmode: %d\n", vinfo->vmode);	fprintf(stderr, "\tred: %d/%d\n", vinfo->red.length, vinfo->red.offset);	fprintf(stderr, "\tgreen: %d/%d\n", vinfo->green.length, vinfo->green.offset);	fprintf(stderr, "\tblue: %d/%d\n", vinfo->blue.length, vinfo->blue.offset);	fprintf(stderr, "\talpha: %d/%d\n", vinfo->transp.length, vinfo->transp.offset);}static void print_finfo(struct fb_fix_screeninfo *finfo){	fprintf(stderr, "Printing finfo:\n");	fprintf(stderr, "\tsmem_start = %p\n", (char *)finfo->smem_start);	fprintf(stderr, "\tsmem_len = %d\n", finfo->smem_len);	fprintf(stderr, "\ttype = %d\n", finfo->type);	fprintf(stderr, "\ttype_aux = %d\n", finfo->type_aux);	fprintf(stderr, "\tvisual = %d\n", finfo->visual);	fprintf(stderr, "\txpanstep = %d\n", finfo->xpanstep);	fprintf(stderr, "\typanstep = %d\n", finfo->ypanstep);	fprintf(stderr, "\tywrapstep = %d\n", finfo->ywrapstep);	fprintf(stderr, "\tline_length = %d\n", finfo->line_length);	fprintf(stderr, "\tmmio_start = %p\n", (char *)finfo->mmio_start);	fprintf(stderr, "\tmmio_len = %d\n", finfo->mmio_len);	fprintf(stderr, "\taccel = %d\n", finfo->accel);}#endifstatic int choose_fbmodes_mode(struct fb_var_screeninfo *vinfo){	int matched;	FILE *modesdb;	struct fb_var_screeninfo cinfo;	matched = 0;	modesdb = fopen(FB_MODES_DB, "r");	if ( modesdb ) {		/* Parse the mode definition file */		while ( read_fbmodes_mode(modesdb, &cinfo) ) {			if ( (vinfo->xres == cinfo.xres && vinfo->yres == cinfo.yres) &&			     (!matched || (vinfo->bits_per_pixel == cinfo.bits_per_pixel)) ) {				vinfo->pixclock = cinfo.pixclock;				vinfo->left_margin = cinfo.left_margin;				vinfo->right_margin = cinfo.right_margin;				vinfo->upper_margin = cinfo.upper_margin;				vinfo->lower_margin = cinfo.lower_margin;				vinfo->hsync_len = cinfo.hsync_len;				vinfo->vsync_len = cinfo.vsync_len;				if ( matched ) {					break;				}				matched = 1;			}		}		fclose(modesdb);	}	return(matched);}static int choose_vesa_mode(struct fb_var_screeninfo *vinfo){	int matched;	int i;	/* Check for VESA timings */	matched = 0;	for ( i=0; i<(sizeof(vesa_timings)/sizeof(vesa_timings[0])); ++i ) {		if ( (vinfo->xres == vesa_timings[i].xres) &&		     (vinfo->yres == vesa_timings[i].yres) ) {#ifdef FBCON_DEBUG			fprintf(stderr, "Using VESA timings for %dx%d\n",						vinfo->xres, vinfo->yres);#endif			if ( vesa_timings[i].pixclock ) {				vinfo->pixclock = vesa_timings[i].pixclock;			}			vinfo->left_margin = vesa_timings[i].left;			vinfo->right_margin = vesa_timings[i].right;			vinfo->upper_margin = vesa_timings[i].upper;			vinfo->lower_margin = vesa_timings[i].lower;			vinfo->hsync_len = vesa_timings[i].hslen;			vinfo->vsync_len = vesa_timings[i].vslen;			vinfo->sync = vesa_timings[i].sync;			vinfo->vmode = vesa_timings[i].vmode;			matched = 1;			break;		}	}	return(matched);}

⌨️ 快捷键说明

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