📄 sdl_fbvideo.c
字号:
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 + -