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

📄 modeswitch.c

📁 Linux游戏编程源码
💻 C
字号:
/* An example of framebuffer mode switching. */#include <stdio.h>#include <stdlib.h>#include <fcntl.h>#include <errno.h>#include <string.h>#include <unistd.h>#include <asm/page.h>#include <sys/mman.h>#include <sys/ioctl.h>#include <asm/page.h>#include <linux/fb.h>#include "fbmodedb.h"int main(int argc, char *argv[]){    char *fbname;    int fbdev;    struct fb_fix_screeninfo fixed_info;    struct fb_var_screeninfo var_info, old_var_info;    FbModeline *modelist;    FbModeline *selected;    u_int8_t pixel_r, pixel_g, pixel_b;    int x, y;    u_int32_t pixel_value;    void *framebuffer;    int framebuffer_size;    int ppc_fix;    /* Let the user specify an alternate framebuffer       device on the command line. Default to       /dev/fb0. */    if (argc >= 2)	fbname = argv[1];    else	fbname = "/dev/fb0";    printf("Using framebuffer device %s.\n", fbname);    /* Open the framebuffer device. */    fbdev = open(fbname, O_RDWR);    if (fbdev < 0) {	printf("Error opening %s.\n", fbname);	return 1;    }    /* Get the variable screen info. */    if (ioctl(fbdev, FBIOGET_VSCREENINFO, &var_info) < 0) {	printf("Unable to retrieve variable screen info: %s\n",	       strerror(errno));	close(fbdev);	return 1;    }    /* Back up this info so we can restore it later. */    old_var_info = var_info;    /* Load the modes database. */    modelist = FB_ParseModeDB("/etc/fb.modes");    if (modelist == NULL) {	printf("Unable to load /etc/fb.modes.\n");	close(fbdev);	return 1;    }    /* Switch into a 640x480 mode. Take the first one we find. */    selected = modelist;    while (selected != NULL) {	if (selected->xres == 640 && selected->yres == 480)	    break;	selected = selected->next;    }    if (selected == NULL) {	printf("No 640x480 modes found in /etc/fb.modes. That's odd.\n");	FB_FreeModeDB(modelist);	close(fbdev);	return 1;    }    /* Copy the timing parameters into the variable info structure. */    var_info.xres = selected->xres;    var_info.yres = selected->yres;    var_info.xres_virtual = var_info.xres;    var_info.yres_virtual = var_info.yres;    var_info.pixclock = selected->dotclock;    var_info.left_margin = selected->left;    var_info.right_margin = selected->right;    var_info.upper_margin = selected->upper;    var_info.lower_margin = selected->lower;    var_info.hsync_len = selected->hslen;    var_info.vsync_len = selected->vslen;    /* Ask for 16bpp. */    var_info.bits_per_pixel = 16;    /* This is a bitmask of sync flags. */    var_info.sync = selected->hsync * FB_SYNC_HOR_HIGH_ACT +	selected->vsync * FB_SYNC_VERT_HIGH_ACT +	selected->csync * FB_SYNC_COMP_HIGH_ACT +	selected->extsync * FB_SYNC_EXT;    /* This is a bitmask of mode attributes. */    var_info.vmode = selected->laced * FB_VMODE_INTERLACED +	selected->doublescan * FB_VMODE_DOUBLE;    var_info.activate = FB_ACTIVATE_NOW;    /* Set the mode with an ioctl. It may not accept the exact       parameters we provide, in which case it will edit the       structure. If our selection is completely unacceptable,       the ioctl will fail. */    if (ioctl(fbdev, FBIOPUT_VSCREENINFO, &var_info) < 0) {	printf("Unable to set variable screen info: %s\n",	       strerror(errno));	close(fbdev);	return 1;    }    printf("Mode switch ioctl succeeded.\n");    printf("Got resolution %ix%i @ %ibpp.\n",	   var_info.xres,	   var_info.yres,	   var_info.bits_per_pixel);    /* Retrieve the fixed screen info. */    if (ioctl(fbdev, FBIOGET_FSCREENINFO, &fixed_info) < 0) {	printf("Unable to retrieve fixed screen info: %s\n",	       strerror(errno));	close(fbdev);	return 1;    }	    /* Now memory-map the framebuffer.       According to the SDL source code, it's necessary to       compensate for a buggy mmap implementation on the       PowerPC. This should not be a problem for other       architectures. (This fix is lifted from SDL_fbvideo.c) */    ppc_fix = (((long)fixed_info.smem_start) -	       ((long) fixed_info.smem_start & ~(PAGE_SIZE-1)));    framebuffer_size = fixed_info.smem_len + ppc_fix;    framebuffer = mmap(NULL,		       framebuffer_size,		       PROT_READ | PROT_WRITE,		       MAP_SHARED,		       fbdev,		       0);    if (framebuffer == NULL) {	printf("Unable to mmap framebuffer: %s\n",	       strerror(errno));	close(fbdev);	return 1;    }    printf("Mapped framebuffer.\n");    if ((fixed_info.visual == FB_VISUAL_TRUECOLOR) &&	(var_info.bits_per_pixel == 16)) {	/* White pixel. */	pixel_r = 0xFF;	pixel_g = 0xFF;	pixel_b = 0xFF;	/* We used this same pixel-packing technique	   back when we were working with SDL. */	pixel_value = (((pixel_r >> (8-var_info.red.length)) <<			var_info.red.offset) +		       ((pixel_g >> (8-var_info.green.length)) <<			var_info.green.offset) +		       ((pixel_b >> (8-var_info.blue.length)) <<			var_info.blue.offset));	/* Draw a pixel in the center of the screen. */	x = var_info.xres / 2 + var_info.xoffset;	y = var_info.yres / 2 + var_info.yoffset;	*((u_int16_t *)framebuffer +	  fixed_info.line_length/2 * y + x) = (u_int16_t)pixel_value;    } else {	printf("Unsupported visual. (Asked for 16bpp.)\n");	pixel_value = 0;    }    /* Wait a few seconds. */    sleep(5);    /* Restore the old video mode. */    old_var_info.activate = FB_ACTIVATE_NOW;    if (ioctl(fbdev, FBIOPUT_VSCREENINFO, &old_var_info) < 0) {	printf("Warning: Unable to restore video mode: %s\n",	       strerror(errno));    }    /* Close the fbdev. */    munmap(framebuffer, framebuffer_size);    close(fbdev);    return 0;}

⌨️ 快捷键说明

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