19682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* 29682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL - Simple DirectMedia Layer 39682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Copyright (C) 1997-2012 Sam Lantinga 49682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 59682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall This library is free software; you can redistribute it and/or 69682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall modify it under the terms of the GNU Lesser General Public 79682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall License as published by the Free Software Foundation; either 89682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall version 2.1 of the License, or (at your option) any later version. 99682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall This library is distributed in the hope that it will be useful, 119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall but WITHOUT ANY WARRANTY; without even the implied warranty of 129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Lesser General Public License for more details. 149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall You should have received a copy of the GNU Lesser General Public 169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall License along with this library; if not, write to the Free Software 179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Sam Lantinga 209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall slouken@libsdl.org 219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall*/ 229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include "SDL_config.h" 239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Framebuffer console based SDL video driver implementation. 259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall*/ 269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include <stdio.h> 289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include <fcntl.h> 299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include <unistd.h> 309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include <sys/ioctl.h> 319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include <sys/mman.h> 329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifndef HAVE_GETPAGESIZE 349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include <asm/page.h> /* For definition of PAGE_SIZE */ 359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include <linux/vt.h> 389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include "SDL_video.h" 409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include "SDL_mouse.h" 419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include "../SDL_sysvideo.h" 429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include "../SDL_pixels_c.h" 439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include "../../events/SDL_events_c.h" 449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include "SDL_fbvideo.h" 459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include "SDL_fbmouse_c.h" 469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include "SDL_fbevents_c.h" 479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include "SDL_fb3dfx.h" 489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include "SDL_fbmatrox.h" 499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include "SDL_fbriva.h" 509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/*#define FBCON_DEBUG*/ 529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if defined(i386) && defined(FB_TYPE_VGA_PLANES) 549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define VGA16_FBCON_SUPPORT 559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include <sys/io.h> /* For ioperm() */ 569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifndef FB_AUX_VGA_PLANES_VGA4 579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define FB_AUX_VGA_PLANES_VGA4 0 589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* 609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic inline void outb (unsigned char value, unsigned short port) 619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall __asm__ __volatile__ ("outb %b0,%w1"::"a" (value), "Nd" (port)); 639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall*/ 659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* FB_TYPE_VGA_PLANES */ 669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* A list of video resolutions that we query for (sorted largest to smallest) */ 689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic const SDL_Rect checkres[] = { 699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall { 0, 0, 1600, 1200 }, /* 16 bpp: 0x11E, or 286 */ 709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall { 0, 0, 1408, 1056 }, /* 16 bpp: 0x19A, or 410 */ 719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall { 0, 0, 1280, 1024 }, /* 16 bpp: 0x11A, or 282 */ 729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall { 0, 0, 1152, 864 }, /* 16 bpp: 0x192, or 402 */ 739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall { 0, 0, 1024, 768 }, /* 16 bpp: 0x117, or 279 */ 749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall { 0, 0, 960, 720 }, /* 16 bpp: 0x18A, or 394 */ 759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall { 0, 0, 800, 600 }, /* 16 bpp: 0x114, or 276 */ 769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall { 0, 0, 768, 576 }, /* 16 bpp: 0x182, or 386 */ 779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall { 0, 0, 720, 576 }, /* PAL */ 789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall { 0, 0, 720, 480 }, /* NTSC */ 799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall { 0, 0, 640, 480 }, /* 16 bpp: 0x111, or 273 */ 809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall { 0, 0, 640, 400 }, /* 8 bpp: 0x100, or 256 */ 819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall { 0, 0, 512, 384 }, 829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall { 0, 0, 320, 240 }, 839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall { 0, 0, 320, 200 } 849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall}; 859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic const struct { 869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int xres; 879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int yres; 889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int pixclock; 899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int left; 909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int right; 919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int upper; 929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int lower; 939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int hslen; 949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int vslen; 959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int sync; 969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int vmode; 979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} vesa_timings[] = { 989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifdef USE_VESA_TIMINGS /* Only tested on Matrox Millenium I */ 999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall { 640, 400, 39771, 48, 16, 39, 8, 96, 2, 2, 0 }, /* 70 Hz */ 1009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall { 640, 480, 39683, 48, 16, 33, 10, 96, 2, 0, 0 }, /* 60 Hz */ 1019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall { 768, 576, 26101, 144, 16, 28, 6, 112, 4, 0, 0 }, /* 60 Hz */ 1029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall { 800, 600, 24038, 144, 24, 28, 8, 112, 6, 0, 0 }, /* 60 Hz */ 1039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall { 960, 720, 17686, 144, 24, 28, 8, 112, 4, 0, 0 }, /* 60 Hz */ 1049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall { 1024, 768, 15386, 160, 32, 30, 4, 128, 4, 0, 0 }, /* 60 Hz */ 1059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall { 1152, 864, 12286, 192, 32, 30, 4, 128, 4, 0, 0 }, /* 60 Hz */ 1069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall { 1280, 1024, 9369, 224, 32, 32, 4, 136, 4, 0, 0 }, /* 60 Hz */ 1079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall { 1408, 1056, 8214, 256, 40, 32, 5, 144, 5, 0, 0 }, /* 60 Hz */ 1089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall { 1600, 1200,/*?*/0, 272, 48, 32, 5, 152, 5, 0, 0 }, /* 60 Hz */ 1099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#else 1109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* You can generate these timings from your XF86Config file using 1119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall the 'modeline2fb' perl script included with the fbset package. 1129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall These timings were generated for Matrox Millenium I, 15" monitor. 1139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall */ 1149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall { 320, 200, 79440, 16, 16, 20, 4, 48, 1, 0, 2 }, /* 70 Hz */ 1159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall { 320, 240, 63492, 16, 16, 16, 4, 48, 2, 0, 2 }, /* 72 Hz */ 1169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall { 512, 384, 49603, 48, 16, 16, 1, 64, 3, 0, 0 }, /* 78 Hz */ 1179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall { 640, 400, 31746, 96, 32, 41, 1, 64, 3, 2, 0 }, /* 85 Hz */ 1189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall { 640, 480, 31746, 120, 16, 16, 1, 64, 3, 0, 0 }, /* 75 Hz */ 1199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall { 768, 576, 26101, 144, 16, 28, 6, 112, 4, 0, 0 }, /* 60 Hz */ 1209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall { 800, 600, 20000, 64, 56, 23, 37, 120, 6, 3, 0 }, /* 72 Hz */ 1219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall { 960, 720, 17686, 144, 24, 28, 8, 112, 4, 0, 0 }, /* 60 Hz */ 1229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall { 1024, 768, 13333, 144, 24, 29, 3, 136, 6, 0, 0 }, /* 70 Hz */ 1239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall { 1152, 864, 12286, 192, 32, 30, 4, 128, 4, 0, 0 }, /* 60 Hz */ 1249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall { 1280, 1024, 9369, 224, 32, 32, 4, 136, 4, 0, 0 }, /* 60 Hz */ 1259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall { 1408, 1056, 8214, 256, 40, 32, 5, 144, 5, 0, 0 }, /* 60 Hz */ 1269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall { 1600, 1200,/*?*/0, 272, 48, 32, 5, 152, 5, 0, 0 }, /* 60 Hz */ 1279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 1289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall}; 1299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallenum { 1309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall FBCON_ROTATE_NONE = 0, 1319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall FBCON_ROTATE_CCW = 90, 1329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall FBCON_ROTATE_UD = 180, 1339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall FBCON_ROTATE_CW = 270 1349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall}; 1359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define min(a,b) ((a)<(b)?(a):(b)) 1379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Initialization/Query functions */ 1399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic int FB_VideoInit(_THIS, SDL_PixelFormat *vformat); 1409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic SDL_Rect **FB_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags); 1419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic SDL_Surface *FB_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags); 1429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifdef VGA16_FBCON_SUPPORT 1439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic SDL_Surface *FB_SetVGA16Mode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags); 1449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 1459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic int FB_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors); 1469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void FB_VideoQuit(_THIS); 1479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Hardware surface functions */ 1499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic int FB_InitHWSurfaces(_THIS, SDL_Surface *screen, char *base, int size); 1509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void FB_FreeHWSurfaces(_THIS); 1519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic int FB_AllocHWSurface(_THIS, SDL_Surface *surface); 1529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic int FB_LockHWSurface(_THIS, SDL_Surface *surface); 1539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void FB_UnlockHWSurface(_THIS, SDL_Surface *surface); 1549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void FB_FreeHWSurface(_THIS, SDL_Surface *surface); 1559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void FB_WaitVBL(_THIS); 1569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void FB_WaitIdle(_THIS); 1579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic int FB_FlipHWSurface(_THIS, SDL_Surface *surface); 1589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Internal palette functions */ 1609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void FB_SavePalette(_THIS, struct fb_fix_screeninfo *finfo, 1619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall struct fb_var_screeninfo *vinfo); 1629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void FB_RestorePalette(_THIS); 1639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Shadow buffer functions */ 1659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic FB_bitBlit FB_blit16; 1669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic FB_bitBlit FB_blit16blocked; 1679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic int SDL_getpagesize(void) 1699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 1709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifdef HAVE_GETPAGESIZE 1719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return getpagesize(); 1729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#elif defined(PAGE_SIZE) 1739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return PAGE_SIZE; 1749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#else 1759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#error Can not determine system page size. 1769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return 4096; /* this is what it USED to be in Linux... */ 1779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 1789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 1799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Small wrapper for mmap() so we can play nicely with no-mmu hosts 1829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * (non-mmu hosts disallow the MAP_SHARED flag) */ 1839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void *do_mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset) 1859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 1869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall void *ret; 1879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ret = mmap(start, length, prot, flags, fd, offset); 1889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( ret == (char *)-1 && (flags & MAP_SHARED) ) { 1899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ret = mmap(start, length, prot, 1909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (flags & ~MAP_SHARED) | MAP_PRIVATE, fd, offset); 1919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 1929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return ret; 1939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 1949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* FB driver bootstrap functions */ 1969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic int FB_Available(void) 1989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 1999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int console = -1; 2009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Added check for /fb/0 (devfs) */ 2019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* but - use environment variable first... if it fails, still check defaults */ 2029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int idx = 0; 2039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall const char *SDL_fbdevs[4] = { NULL, "/dev/fb0", "/dev/fb/0", NULL }; 2049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_fbdevs[0] = SDL_getenv("SDL_FBDEV"); 2069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if( !SDL_fbdevs[0] ) 2079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall idx++; 2089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for( ; SDL_fbdevs[idx]; idx++ ) 2099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall { 2109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall console = open(SDL_fbdevs[idx], O_RDWR, 0); 2119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( console >= 0 ) { 2129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall close(console); 2139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall break; 2149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 2159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 2169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return(console >= 0); 2179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 2189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void FB_DeleteDevice(SDL_VideoDevice *device) 2209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 2219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_free(device->hidden); 2229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_free(device); 2239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 2249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic SDL_VideoDevice *FB_CreateDevice(int devindex) 2269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 2279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_VideoDevice *this; 2289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Initialize all variables that we clean on shutdown */ 2309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall this = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice)); 2319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( this ) { 2329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_memset(this, 0, (sizeof *this)); 2339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall this->hidden = (struct SDL_PrivateVideoData *) 2349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_malloc((sizeof *this->hidden)); 2359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 2369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( (this == NULL) || (this->hidden == NULL) ) { 2379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_OutOfMemory(); 2389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( this ) { 2399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_free(this); 2409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 2419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return(0); 2429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 2439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_memset(this->hidden, 0, (sizeof *this->hidden)); 2449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall wait_vbl = FB_WaitVBL; 2459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall wait_idle = FB_WaitIdle; 2469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mouse_fd = -1; 2479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall keyboard_fd = -1; 2489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Set the function pointers */ 2509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall this->VideoInit = FB_VideoInit; 2519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall this->ListModes = FB_ListModes; 2529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall this->SetVideoMode = FB_SetVideoMode; 2539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall this->SetColors = FB_SetColors; 2549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall this->UpdateRects = NULL; 2559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall this->VideoQuit = FB_VideoQuit; 2569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall this->AllocHWSurface = FB_AllocHWSurface; 2579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall this->CheckHWBlit = NULL; 2589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall this->FillHWRect = NULL; 2599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall this->SetHWColorKey = NULL; 2609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall this->SetHWAlpha = NULL; 2619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall this->LockHWSurface = FB_LockHWSurface; 2629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall this->UnlockHWSurface = FB_UnlockHWSurface; 2639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall this->FlipHWSurface = FB_FlipHWSurface; 2649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall this->FreeHWSurface = FB_FreeHWSurface; 2659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall this->SetCaption = NULL; 2669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall this->SetIcon = NULL; 2679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall this->IconifyWindow = NULL; 2689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall this->GrabInput = NULL; 2699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall this->GetWMInfo = NULL; 2709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall this->InitOSKeymap = FB_InitOSKeymap; 2719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall this->PumpEvents = FB_PumpEvents; 2729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall this->free = FB_DeleteDevice; 2749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return this; 2769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 2779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse HallVideoBootStrap FBCON_bootstrap = { 2799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall "fbcon", "Linux Framebuffer Console", 2809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall FB_Available, FB_CreateDevice 2819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall}; 2829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define FB_MODES_DB "/etc/fb.modes" 2849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic int read_fbmodes_line(FILE*f, char* line, int length) 2869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 2879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int blank; 2889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall char* c; 2899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int i; 2909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall blank=0; 2929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* find a relevant line */ 2939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall do 2949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall { 2959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (!fgets(line,length,f)) 2969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return 0; 2979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall c=line; 2989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall while(((*c=='\t')||(*c==' '))&&(*c!=0)) 2999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall c++; 3009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 3019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ((*c=='\n')||(*c=='#')||(*c==0)) 3029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall blank=1; 3039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else 3049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall blank=0; 3059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 3069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall while(blank); 3079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* remove whitespace at the begining of the string */ 3089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall i=0; 3099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall do 3109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall { 3119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall line[i]=c[i]; 3129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall i++; 3139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 3149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall while(c[i]!=0); 3159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return 1; 3169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 3179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 3189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic int read_fbmodes_mode(FILE *f, struct fb_var_screeninfo *vinfo) 3199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 3209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall char line[1024]; 3219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall char option[256]; 3229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 3239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Find a "geometry" */ 3249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall do { 3259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (read_fbmodes_line(f, line, sizeof(line))==0) 3269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return 0; 3279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (SDL_strncmp(line,"geometry",8)==0) 3289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall break; 3299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 3309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall while(1); 3319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 3329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_sscanf(line, "geometry %d %d %d %d %d", &vinfo->xres, &vinfo->yres, 3339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall &vinfo->xres_virtual, &vinfo->yres_virtual, &vinfo->bits_per_pixel); 3349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (read_fbmodes_line(f, line, sizeof(line))==0) 3359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return 0; 3369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 3379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_sscanf(line, "timings %d %d %d %d %d %d %d", &vinfo->pixclock, 3389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall &vinfo->left_margin, &vinfo->right_margin, &vinfo->upper_margin, 3399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall &vinfo->lower_margin, &vinfo->hsync_len, &vinfo->vsync_len); 3409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 3419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall vinfo->sync=0; 3429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall vinfo->vmode=FB_VMODE_NONINTERLACED; 3439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 3449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Parse misc options */ 3459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall do { 3469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (read_fbmodes_line(f, line, sizeof(line))==0) 3479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return 0; 3489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 3499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (SDL_strncmp(line,"hsync",5)==0) { 3509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_sscanf(line,"hsync %s",option); 3519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (SDL_strncmp(option,"high",4)==0) 3529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall vinfo->sync |= FB_SYNC_HOR_HIGH_ACT; 3539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 3549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else if (SDL_strncmp(line,"vsync",5)==0) { 3559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_sscanf(line,"vsync %s",option); 3569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (SDL_strncmp(option,"high",4)==0) 3579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall vinfo->sync |= FB_SYNC_VERT_HIGH_ACT; 3589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 3599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else if (SDL_strncmp(line,"csync",5)==0) { 3609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_sscanf(line,"csync %s",option); 3619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (SDL_strncmp(option,"high",4)==0) 3629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall vinfo->sync |= FB_SYNC_COMP_HIGH_ACT; 3639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 3649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else if (SDL_strncmp(line,"extsync",5)==0) { 3659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_sscanf(line,"extsync %s",option); 3669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (SDL_strncmp(option,"true",4)==0) 3679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall vinfo->sync |= FB_SYNC_EXT; 3689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 3699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else if (SDL_strncmp(line,"laced",5)==0) { 3709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_sscanf(line,"laced %s",option); 3719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (SDL_strncmp(option,"true",4)==0) 3729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall vinfo->vmode |= FB_VMODE_INTERLACED; 3739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 3749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else if (SDL_strncmp(line,"double",6)==0) { 3759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_sscanf(line,"double %s",option); 3769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (SDL_strncmp(option,"true",4)==0) 3779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall vinfo->vmode |= FB_VMODE_DOUBLE; 3789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 3799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 3809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall while(SDL_strncmp(line,"endmode",7)!=0); 3819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 3829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return 1; 3839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 3849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 3859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic int FB_CheckMode(_THIS, struct fb_var_screeninfo *vinfo, 3869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int index, unsigned int *w, unsigned int *h) 3879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 3889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int mode_okay; 3899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 3909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mode_okay = 0; 3919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall vinfo->bits_per_pixel = (index+1)*8; 3929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall vinfo->xres = *w; 3939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall vinfo->xres_virtual = *w; 3949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall vinfo->yres = *h; 3959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall vinfo->yres_virtual = *h; 3969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall vinfo->activate = FB_ACTIVATE_TEST; 3979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( ioctl(console_fd, FBIOPUT_VSCREENINFO, vinfo) == 0 ) { 3989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifdef FBCON_DEBUG 3999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 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); 4009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 4019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( (((vinfo->bits_per_pixel+7)/8)-1) == index ) { 4029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall *w = vinfo->xres; 4039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall *h = vinfo->yres; 4049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mode_okay = 1; 4059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 4069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 4079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return mode_okay; 4089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 4099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 4109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic int FB_AddMode(_THIS, int index, unsigned int w, unsigned int h, int check_timings) 4119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 4129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_Rect *mode; 4139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int i; 4149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int next_mode; 4159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 4169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Check to see if we already have this mode */ 4179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( SDL_nummodes[index] > 0 ) { 4189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mode = SDL_modelist[index][SDL_nummodes[index]-1]; 4199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( (mode->w == w) && (mode->h == h) ) { 4209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifdef FBCON_DEBUG 4219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fprintf(stderr, "We already have mode %dx%d at %d bytes per pixel\n", w, h, index+1); 4229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 4239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return(0); 4249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 4259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 4269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 4279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Only allow a mode if we have a valid timing for it */ 4289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( check_timings ) { 4299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int found_timing = 0; 4309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for ( i=0; i<(sizeof(vesa_timings)/sizeof(vesa_timings[0])); ++i ) { 4319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( (w == vesa_timings[i].xres) && 4329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (h == vesa_timings[i].yres) && vesa_timings[i].pixclock ) { 4339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall found_timing = 1; 4349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall break; 4359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 4369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 4379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( !found_timing ) { 4389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifdef FBCON_DEBUG 4399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fprintf(stderr, "No valid timing line for mode %dx%d\n", w, h); 4409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 4419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return(0); 4429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 4439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 4449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 4459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Set up the new video mode rectangle */ 4469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mode = (SDL_Rect *)SDL_malloc(sizeof *mode); 4479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( mode == NULL ) { 4489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_OutOfMemory(); 4499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return(-1); 4509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 4519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mode->x = 0; 4529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mode->y = 0; 4539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mode->w = w; 4549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mode->h = h; 4559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifdef FBCON_DEBUG 4569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fprintf(stderr, "Adding mode %dx%d at %d bytes per pixel\n", w, h, index+1); 4579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 4589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 4599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Allocate the new list of modes, and fill in the new mode */ 4609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall next_mode = SDL_nummodes[index]; 4619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_modelist[index] = (SDL_Rect **) 4629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_realloc(SDL_modelist[index], (1+next_mode+1)*sizeof(SDL_Rect *)); 4639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( SDL_modelist[index] == NULL ) { 4649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_OutOfMemory(); 4659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_nummodes[index] = 0; 4669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_free(mode); 4679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return(-1); 4689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 4699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_modelist[index][next_mode] = mode; 4709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_modelist[index][next_mode+1] = NULL; 4719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_nummodes[index]++; 4729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 4739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return(0); 4749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 4759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 4769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic int cmpmodes(const void *va, const void *vb) 4779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 4789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall const SDL_Rect *a = *(const SDL_Rect**)va; 4799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall const SDL_Rect *b = *(const SDL_Rect**)vb; 4809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( a->h == b->h ) 4819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return b->w - a->w; 4829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else 4839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return b->h - a->h; 4849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 4859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 4869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void FB_SortModes(_THIS) 4879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 4889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int i; 4899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for ( i=0; i<NUM_MODELISTS; ++i ) { 4909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( SDL_nummodes[i] > 0 ) { 4919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_qsort(SDL_modelist[i], SDL_nummodes[i], sizeof *SDL_modelist[i], cmpmodes); 4929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 4939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 4949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 4959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 4969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic int FB_VideoInit(_THIS, SDL_PixelFormat *vformat) 4979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 4989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall const int pagesize = SDL_getpagesize(); 4999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall struct fb_fix_screeninfo finfo; 5009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall struct fb_var_screeninfo vinfo; 5019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int i, j; 5029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int current_index; 5039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall unsigned int current_w; 5049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall unsigned int current_h; 5059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall const char *SDL_fbdev; 5069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall const char *rotation; 5079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall FILE *modesdb; 5089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 5099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Initialize the library */ 5109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_fbdev = SDL_getenv("SDL_FBDEV"); 5119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( SDL_fbdev == NULL ) { 5129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_fbdev = "/dev/fb0"; 5139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 5149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall console_fd = open(SDL_fbdev, O_RDWR, 0); 5159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( console_fd < 0 ) { 5169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_SetError("Unable to open %s", SDL_fbdev); 5179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return(-1); 5189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 5199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 5209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if !SDL_THREADS_DISABLED 5219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Create the hardware surface lock mutex */ 5229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall hw_lock = SDL_CreateMutex(); 5239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( hw_lock == NULL ) { 5249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_SetError("Unable to create lock mutex"); 5259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall FB_VideoQuit(this); 5269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return(-1); 5279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 5289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 5299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 5309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Get the type of video hardware */ 5319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( ioctl(console_fd, FBIOGET_FSCREENINFO, &finfo) < 0 ) { 5329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_SetError("Couldn't get console hardware info"); 5339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall FB_VideoQuit(this); 5349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return(-1); 5359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 5369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall switch (finfo.type) { 5379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall case FB_TYPE_PACKED_PIXELS: 5389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Supported, no worries.. */ 5399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall break; 5409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifdef VGA16_FBCON_SUPPORT 5419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall case FB_TYPE_VGA_PLANES: 5429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* VGA16 is supported, but that's it */ 5439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( finfo.type_aux == FB_AUX_VGA_PLANES_VGA4 ) { 5449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( ioperm(0x3b4, 0x3df - 0x3b4 + 1, 1) < 0 ) { 5459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_SetError("No I/O port permissions"); 5469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall FB_VideoQuit(this); 5479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return(-1); 5489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 5499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall this->SetVideoMode = FB_SetVGA16Mode; 5509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall break; 5519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 5529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Fall through to unsupported case */ 5539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* VGA16_FBCON_SUPPORT */ 5549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall default: 5559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_SetError("Unsupported console hardware"); 5569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall FB_VideoQuit(this); 5579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return(-1); 5589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 5599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall switch (finfo.visual) { 5609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall case FB_VISUAL_TRUECOLOR: 5619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall case FB_VISUAL_PSEUDOCOLOR: 5629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall case FB_VISUAL_STATIC_PSEUDOCOLOR: 5639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall case FB_VISUAL_DIRECTCOLOR: 5649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall break; 5659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall default: 5669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_SetError("Unsupported console hardware"); 5679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall FB_VideoQuit(this); 5689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return(-1); 5699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 5709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 5719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Check if the user wants to disable hardware acceleration */ 5729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall { const char *fb_accel; 5739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fb_accel = SDL_getenv("SDL_FBACCEL"); 5749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( fb_accel ) { 5759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall finfo.accel = SDL_atoi(fb_accel); 5769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 5779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 5789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 5799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Memory map the device, compensating for buggy PPC mmap() */ 5809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mapped_offset = (((long)finfo.smem_start) - 5819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (((long)finfo.smem_start)&~(pagesize-1))); 5829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mapped_memlen = finfo.smem_len+mapped_offset; 5839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mapped_mem = do_mmap(NULL, mapped_memlen, 5849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall PROT_READ|PROT_WRITE, MAP_SHARED, console_fd, 0); 5859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( mapped_mem == (char *)-1 ) { 5869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_SetError("Unable to memory map the video hardware"); 5879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mapped_mem = NULL; 5889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall FB_VideoQuit(this); 5899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return(-1); 5909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 5919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 5929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Determine the current screen depth */ 5939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( ioctl(console_fd, FBIOGET_VSCREENINFO, &vinfo) < 0 ) { 5949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_SetError("Couldn't get console pixel format"); 5959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall FB_VideoQuit(this); 5969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return(-1); 5979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 5989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall vformat->BitsPerPixel = vinfo.bits_per_pixel; 5999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( vformat->BitsPerPixel < 8 ) { 6009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Assuming VGA16, we handle this via a shadow framebuffer */ 6019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall vformat->BitsPerPixel = 8; 6029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 6039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for ( i=0; i<vinfo.red.length; ++i ) { 6049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall vformat->Rmask <<= 1; 6059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall vformat->Rmask |= (0x00000001<<vinfo.red.offset); 6069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 6079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for ( i=0; i<vinfo.green.length; ++i ) { 6089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall vformat->Gmask <<= 1; 6099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall vformat->Gmask |= (0x00000001<<vinfo.green.offset); 6109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 6119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for ( i=0; i<vinfo.blue.length; ++i ) { 6129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall vformat->Bmask <<= 1; 6139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall vformat->Bmask |= (0x00000001<<vinfo.blue.offset); 6149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 6159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall saved_vinfo = vinfo; 6169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 6179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Save hardware palette, if needed */ 6189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall FB_SavePalette(this, &finfo, &vinfo); 6199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 6209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* If the I/O registers are available, memory map them so we 6219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall can take advantage of any supported hardware acceleration. 6229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall */ 6239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall vinfo.accel_flags = 0; /* Temporarily reserve registers */ 6249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ioctl(console_fd, FBIOPUT_VSCREENINFO, &vinfo); 6259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( finfo.accel && finfo.mmio_len ) { 6269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mapped_iolen = finfo.mmio_len; 6279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mapped_io = do_mmap(NULL, mapped_iolen, PROT_READ|PROT_WRITE, 6289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall MAP_SHARED, console_fd, mapped_memlen); 6299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( mapped_io == (char *)-1 ) { 6309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Hmm, failed to memory map I/O registers */ 6319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mapped_io = NULL; 6329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 6339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 6349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 6359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall rotate = FBCON_ROTATE_NONE; 6369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall rotation = SDL_getenv("SDL_VIDEO_FBCON_ROTATION"); 6379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (rotation != NULL) { 6389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (SDL_strlen(rotation) == 0) { 6399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall shadow_fb = 0; 6409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall rotate = FBCON_ROTATE_NONE; 6419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifdef FBCON_DEBUG 6429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall printf("Not rotating, no shadow\n"); 6439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 6449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } else if (!SDL_strcmp(rotation, "NONE")) { 6459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall shadow_fb = 1; 6469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall rotate = FBCON_ROTATE_NONE; 6479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifdef FBCON_DEBUG 6489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall printf("Not rotating, but still using shadow\n"); 6499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 6509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } else if (!SDL_strcmp(rotation, "CW")) { 6519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall shadow_fb = 1; 6529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall rotate = FBCON_ROTATE_CW; 6539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifdef FBCON_DEBUG 6549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall printf("Rotating screen clockwise\n"); 6559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 6569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } else if (!SDL_strcmp(rotation, "CCW")) { 6579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall shadow_fb = 1; 6589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall rotate = FBCON_ROTATE_CCW; 6599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifdef FBCON_DEBUG 6609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall printf("Rotating screen counter clockwise\n"); 6619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 6629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } else if (!SDL_strcmp(rotation, "UD")) { 6639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall shadow_fb = 1; 6649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall rotate = FBCON_ROTATE_UD; 6659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifdef FBCON_DEBUG 6669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall printf("Rotating screen upside down\n"); 6679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 6689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } else { 6699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_SetError("\"%s\" is not a valid value for " 6709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall "SDL_VIDEO_FBCON_ROTATION", rotation); 6719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return(-1); 6729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 6739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 6749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 6759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (rotate == FBCON_ROTATE_CW || rotate == FBCON_ROTATE_CCW) { 6769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall current_w = vinfo.yres; 6779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall current_h = vinfo.xres; 6789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } else { 6799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall current_w = vinfo.xres; 6809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall current_h = vinfo.yres; 6819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 6829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 6839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Query for the list of available video modes */ 6849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall current_index = ((vinfo.bits_per_pixel+7)/8)-1; 6859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall modesdb = fopen(FB_MODES_DB, "r"); 6869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for ( i=0; i<NUM_MODELISTS; ++i ) { 6879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_nummodes[i] = 0; 6889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_modelist[i] = NULL; 6899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 6909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( SDL_getenv("SDL_FB_BROKEN_MODES") != NULL ) { 6919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall FB_AddMode(this, current_index, current_w, current_h, 0); 6929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } else if(modesdb) { 6939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall while ( read_fbmodes_mode(modesdb, &vinfo) ) { 6949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for ( i=0; i<NUM_MODELISTS; ++i ) { 6959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall unsigned int w, h; 6969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 6979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (rotate == FBCON_ROTATE_CW || rotate == FBCON_ROTATE_CCW) { 6989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall w = vinfo.yres; 6999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall h = vinfo.xres; 7009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } else { 7019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall w = vinfo.xres; 7029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall h = vinfo.yres; 7039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 7049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* See if we are querying for the current mode */ 7059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( i == current_index ) { 7069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( (current_w > w) || (current_h > h) ) { 7079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Only check once */ 7089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall FB_AddMode(this, i, current_w, current_h, 0); 7099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall current_index = -1; 7109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 7119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 7129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( FB_CheckMode(this, &vinfo, i, &w, &h) ) { 7139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall FB_AddMode(this, i, w, h, 0); 7149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 7159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 7169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 7179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fclose(modesdb); 7189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall FB_SortModes(this); 7199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } else { 7209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for ( i=0; i<NUM_MODELISTS; ++i ) { 7219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for ( j=0; j<(sizeof(checkres)/sizeof(checkres[0])); ++j ) { 7229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall unsigned int w, h; 7239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 7249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (rotate == FBCON_ROTATE_CW || rotate == FBCON_ROTATE_CCW) { 7259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall w = checkres[j].h; 7269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall h = checkres[j].w; 7279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } else { 7289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall w = checkres[j].w; 7299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall h = checkres[j].h; 7309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 7319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* See if we are querying for the current mode */ 7329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( i == current_index ) { 7339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( (current_w > w) || (current_h > h) ) { 7349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Only check once */ 7359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall FB_AddMode(this, i, current_w, current_h, 0); 7369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall current_index = -1; 7379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 7389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 7399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( FB_CheckMode(this, &vinfo, i, &w, &h) ) { 7409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall FB_AddMode(this, i, w, h, 1); 7419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 7429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 7439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 7449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 7459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 7469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall this->info.current_w = current_w; 7479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall this->info.current_h = current_h; 7489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall this->info.wm_available = 0; 7499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall this->info.hw_available = !shadow_fb; 7509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall this->info.video_mem = shadow_fb ? 0 : finfo.smem_len/1024; 7519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Fill in our hardware acceleration capabilities */ 7529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( mapped_io ) { 7539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall switch (finfo.accel) { 7549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall case FB_ACCEL_MATROX_MGA2064W: 7559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall case FB_ACCEL_MATROX_MGA1064SG: 7569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall case FB_ACCEL_MATROX_MGA2164W: 7579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall case FB_ACCEL_MATROX_MGA2164W_AGP: 7589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall case FB_ACCEL_MATROX_MGAG100: 7599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /*case FB_ACCEL_MATROX_MGAG200: G200 acceleration broken! */ 7609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall case FB_ACCEL_MATROX_MGAG400: 7619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifdef FBACCEL_DEBUG 7629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall printf("Matrox hardware accelerator!\n"); 7639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 7649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall FB_MatroxAccel(this, finfo.accel); 7659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall break; 7669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall case FB_ACCEL_3DFX_BANSHEE: 7679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifdef FBACCEL_DEBUG 7689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall printf("3DFX hardware accelerator!\n"); 7699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 7709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall FB_3DfxAccel(this, finfo.accel); 7719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall break; 7729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall case FB_ACCEL_NV3: 7739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall case FB_ACCEL_NV4: 7749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifdef FBACCEL_DEBUG 7759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall printf("NVidia hardware accelerator!\n"); 7769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 7779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall FB_RivaAccel(this, finfo.accel); 7789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall break; 7799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall default: 7809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifdef FBACCEL_DEBUG 7819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall printf("Unknown hardware accelerator.\n"); 7829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 7839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall break; 7849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 7859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 7869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 7879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (shadow_fb) { 7889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall shadow_mem = (char *)SDL_malloc(mapped_memlen); 7899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (shadow_mem == NULL) { 7909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_SetError("No memory for shadow"); 7919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return (-1); 7929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 7939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 7949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 7959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Enable mouse and keyboard support */ 7969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( FB_OpenKeyboard(this) < 0 ) { 7979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall FB_VideoQuit(this); 7989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return(-1); 7999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 8009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( FB_OpenMouse(this) < 0 ) { 8019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall const char *sdl_nomouse; 8029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 8039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall sdl_nomouse = SDL_getenv("SDL_NOMOUSE"); 8049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( ! sdl_nomouse ) { 8059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_SetError("Unable to open mouse"); 8069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall FB_VideoQuit(this); 8079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return(-1); 8089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 8099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 8109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 8119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* We're done! */ 8129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return(0); 8139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 8149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 8159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic SDL_Rect **FB_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags) 8169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 8179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return(SDL_modelist[((format->BitsPerPixel+7)/8)-1]); 8189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 8199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 8209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Various screen update functions available */ 8219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void FB_DirectUpdate(_THIS, int numrects, SDL_Rect *rects); 8229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifdef VGA16_FBCON_SUPPORT 8239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void FB_VGA16Update(_THIS, int numrects, SDL_Rect *rects); 8249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 8259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 8269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifdef FBCON_DEBUG 8279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void print_vinfo(struct fb_var_screeninfo *vinfo) 8289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 8299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fprintf(stderr, "Printing vinfo:\n"); 8309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fprintf(stderr, "\txres: %d\n", vinfo->xres); 8319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fprintf(stderr, "\tyres: %d\n", vinfo->yres); 8329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fprintf(stderr, "\txres_virtual: %d\n", vinfo->xres_virtual); 8339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fprintf(stderr, "\tyres_virtual: %d\n", vinfo->yres_virtual); 8349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fprintf(stderr, "\txoffset: %d\n", vinfo->xoffset); 8359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fprintf(stderr, "\tyoffset: %d\n", vinfo->yoffset); 8369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fprintf(stderr, "\tbits_per_pixel: %d\n", vinfo->bits_per_pixel); 8379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fprintf(stderr, "\tgrayscale: %d\n", vinfo->grayscale); 8389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fprintf(stderr, "\tnonstd: %d\n", vinfo->nonstd); 8399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fprintf(stderr, "\tactivate: %d\n", vinfo->activate); 8409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fprintf(stderr, "\theight: %d\n", vinfo->height); 8419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fprintf(stderr, "\twidth: %d\n", vinfo->width); 8429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fprintf(stderr, "\taccel_flags: %d\n", vinfo->accel_flags); 8439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fprintf(stderr, "\tpixclock: %d\n", vinfo->pixclock); 8449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fprintf(stderr, "\tleft_margin: %d\n", vinfo->left_margin); 8459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fprintf(stderr, "\tright_margin: %d\n", vinfo->right_margin); 8469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fprintf(stderr, "\tupper_margin: %d\n", vinfo->upper_margin); 8479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fprintf(stderr, "\tlower_margin: %d\n", vinfo->lower_margin); 8489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fprintf(stderr, "\thsync_len: %d\n", vinfo->hsync_len); 8499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fprintf(stderr, "\tvsync_len: %d\n", vinfo->vsync_len); 8509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fprintf(stderr, "\tsync: %d\n", vinfo->sync); 8519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fprintf(stderr, "\tvmode: %d\n", vinfo->vmode); 8529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fprintf(stderr, "\tred: %d/%d\n", vinfo->red.length, vinfo->red.offset); 8539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fprintf(stderr, "\tgreen: %d/%d\n", vinfo->green.length, vinfo->green.offset); 8549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fprintf(stderr, "\tblue: %d/%d\n", vinfo->blue.length, vinfo->blue.offset); 8559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fprintf(stderr, "\talpha: %d/%d\n", vinfo->transp.length, vinfo->transp.offset); 8569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 8579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void print_finfo(struct fb_fix_screeninfo *finfo) 8589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 8599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fprintf(stderr, "Printing finfo:\n"); 8609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fprintf(stderr, "\tsmem_start = %p\n", (char *)finfo->smem_start); 8619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fprintf(stderr, "\tsmem_len = %d\n", finfo->smem_len); 8629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fprintf(stderr, "\ttype = %d\n", finfo->type); 8639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fprintf(stderr, "\ttype_aux = %d\n", finfo->type_aux); 8649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fprintf(stderr, "\tvisual = %d\n", finfo->visual); 8659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fprintf(stderr, "\txpanstep = %d\n", finfo->xpanstep); 8669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fprintf(stderr, "\typanstep = %d\n", finfo->ypanstep); 8679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fprintf(stderr, "\tywrapstep = %d\n", finfo->ywrapstep); 8689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fprintf(stderr, "\tline_length = %d\n", finfo->line_length); 8699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fprintf(stderr, "\tmmio_start = %p\n", (char *)finfo->mmio_start); 8709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fprintf(stderr, "\tmmio_len = %d\n", finfo->mmio_len); 8719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fprintf(stderr, "\taccel = %d\n", finfo->accel); 8729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 8739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 8749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 8759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic int choose_fbmodes_mode(struct fb_var_screeninfo *vinfo) 8769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 8779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int matched; 8789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall FILE *modesdb; 8799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall struct fb_var_screeninfo cinfo; 8809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 8819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall matched = 0; 8829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall modesdb = fopen(FB_MODES_DB, "r"); 8839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( modesdb ) { 8849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Parse the mode definition file */ 8859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall while ( read_fbmodes_mode(modesdb, &cinfo) ) { 8869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( (vinfo->xres == cinfo.xres && vinfo->yres == cinfo.yres) && 8879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (!matched || (vinfo->bits_per_pixel == cinfo.bits_per_pixel)) ) { 8889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall vinfo->pixclock = cinfo.pixclock; 8899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall vinfo->left_margin = cinfo.left_margin; 8909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall vinfo->right_margin = cinfo.right_margin; 8919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall vinfo->upper_margin = cinfo.upper_margin; 8929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall vinfo->lower_margin = cinfo.lower_margin; 8939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall vinfo->hsync_len = cinfo.hsync_len; 8949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall vinfo->vsync_len = cinfo.vsync_len; 8959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( matched ) { 8969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall break; 8979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 8989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall matched = 1; 8999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 9009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 9019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fclose(modesdb); 9029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 9039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return(matched); 9049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 9059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 9069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic int choose_vesa_mode(struct fb_var_screeninfo *vinfo) 9079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 9089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int matched; 9099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int i; 9109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 9119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Check for VESA timings */ 9129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall matched = 0; 9139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for ( i=0; i<(sizeof(vesa_timings)/sizeof(vesa_timings[0])); ++i ) { 9149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( (vinfo->xres == vesa_timings[i].xres) && 9159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (vinfo->yres == vesa_timings[i].yres) ) { 9169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifdef FBCON_DEBUG 9179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fprintf(stderr, "Using VESA timings for %dx%d\n", 9189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall vinfo->xres, vinfo->yres); 9199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 9209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( vesa_timings[i].pixclock ) { 9219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall vinfo->pixclock = vesa_timings[i].pixclock; 9229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 9239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall vinfo->left_margin = vesa_timings[i].left; 9249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall vinfo->right_margin = vesa_timings[i].right; 9259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall vinfo->upper_margin = vesa_timings[i].upper; 9269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall vinfo->lower_margin = vesa_timings[i].lower; 9279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall vinfo->hsync_len = vesa_timings[i].hslen; 9289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall vinfo->vsync_len = vesa_timings[i].vslen; 9299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall vinfo->sync = vesa_timings[i].sync; 9309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall vinfo->vmode = vesa_timings[i].vmode; 9319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall matched = 1; 9329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall break; 9339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 9349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 9359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return(matched); 9369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 9379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 9389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifdef VGA16_FBCON_SUPPORT 9399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic SDL_Surface *FB_SetVGA16Mode(_THIS, SDL_Surface *current, 9409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int width, int height, int bpp, Uint32 flags) 9419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 9429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall struct fb_fix_screeninfo finfo; 9439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall struct fb_var_screeninfo vinfo; 9449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 9459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Set the terminal into graphics mode */ 9469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( FB_EnterGraphicsMode(this) < 0 ) { 9479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return(NULL); 9489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 9499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 9509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Restore the original palette */ 9519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall FB_RestorePalette(this); 9529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 9539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Set the video mode and get the final screen format */ 9549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( ioctl(console_fd, FBIOGET_VSCREENINFO, &vinfo) < 0 ) { 9559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_SetError("Couldn't get console screen info"); 9569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return(NULL); 9579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 9589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall cache_vinfo = vinfo; 9599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifdef FBCON_DEBUG 9609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fprintf(stderr, "Printing actual vinfo:\n"); 9619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall print_vinfo(&vinfo); 9629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 9639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( ! SDL_ReallocFormat(current, bpp, 0, 0, 0, 0) ) { 9649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return(NULL); 9659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 9669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall current->format->palette->ncolors = 16; 9679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 9689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Get the fixed information about the console hardware. 9699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall This is necessary since finfo.line_length changes. 9709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall */ 9719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( ioctl(console_fd, FBIOGET_FSCREENINFO, &finfo) < 0 ) { 9729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_SetError("Couldn't get console hardware info"); 9739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return(NULL); 9749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 9759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifdef FBCON_DEBUG 9769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fprintf(stderr, "Printing actual finfo:\n"); 9779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall print_finfo(&finfo); 9789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 9799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 9809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Save hardware palette, if needed */ 9819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall FB_SavePalette(this, &finfo, &vinfo); 9829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 9839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Set up the new mode framebuffer */ 9849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall current->flags = SDL_FULLSCREEN; 9859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall current->w = vinfo.xres; 9869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall current->h = vinfo.yres; 9879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall current->pitch = current->w; 9889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall current->pixels = SDL_malloc(current->h*current->pitch); 9899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 9909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Set the update rectangle function */ 9919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall this->UpdateRects = FB_VGA16Update; 9929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 9939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* We're done */ 9949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return(current); 9959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 9969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* VGA16_FBCON_SUPPORT */ 9979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 9989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic SDL_Surface *FB_SetVideoMode(_THIS, SDL_Surface *current, 9999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int width, int height, int bpp, Uint32 flags) 10009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 10019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall struct fb_fix_screeninfo finfo; 10029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall struct fb_var_screeninfo vinfo; 10039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int i; 10049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Uint32 Rmask; 10059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Uint32 Gmask; 10069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Uint32 Bmask; 10079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall char *surfaces_mem; 10089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int surfaces_len; 10099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 10109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Set the terminal into graphics mode */ 10119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( FB_EnterGraphicsMode(this) < 0 ) { 10129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return(NULL); 10139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 10149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 10159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Restore the original palette */ 10169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall FB_RestorePalette(this); 10179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 10189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Set the video mode and get the final screen format */ 10199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( ioctl(console_fd, FBIOGET_VSCREENINFO, &vinfo) < 0 ) { 10209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_SetError("Couldn't get console screen info"); 10219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return(NULL); 10229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 10239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifdef FBCON_DEBUG 10249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fprintf(stderr, "Printing original vinfo:\n"); 10259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall print_vinfo(&vinfo); 10269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 10279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Do not use double buffering with shadow buffer */ 10289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (shadow_fb) { 10299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall flags &= ~SDL_DOUBLEBUF; 10309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 10319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 10329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( (vinfo.xres != width) || (vinfo.yres != height) || 10339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (vinfo.bits_per_pixel != bpp) || (flags & SDL_DOUBLEBUF) ) { 10349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall vinfo.activate = FB_ACTIVATE_NOW; 10359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall vinfo.accel_flags = 0; 10369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall vinfo.bits_per_pixel = bpp; 10379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall vinfo.xres = width; 10389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall vinfo.xres_virtual = width; 10399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall vinfo.yres = height; 10409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( flags & SDL_DOUBLEBUF ) { 10419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall vinfo.yres_virtual = height*2; 10429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } else { 10439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall vinfo.yres_virtual = height; 10449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 10459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall vinfo.xoffset = 0; 10469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall vinfo.yoffset = 0; 10479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall vinfo.red.length = vinfo.red.offset = 0; 10489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall vinfo.green.length = vinfo.green.offset = 0; 10499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall vinfo.blue.length = vinfo.blue.offset = 0; 10509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall vinfo.transp.length = vinfo.transp.offset = 0; 10519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( ! choose_fbmodes_mode(&vinfo) ) { 10529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall choose_vesa_mode(&vinfo); 10539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 10549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifdef FBCON_DEBUG 10559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fprintf(stderr, "Printing wanted vinfo:\n"); 10569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall print_vinfo(&vinfo); 10579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 10589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( !shadow_fb && 10599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ioctl(console_fd, FBIOPUT_VSCREENINFO, &vinfo) < 0 ) { 10609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall vinfo.yres_virtual = height; 10619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( ioctl(console_fd, FBIOPUT_VSCREENINFO, &vinfo) < 0 ) { 10629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_SetError("Couldn't set console screen info"); 10639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return(NULL); 10649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 10659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 10669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } else { 10679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int maxheight; 10689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 10699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Figure out how much video memory is available */ 10709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( flags & SDL_DOUBLEBUF ) { 10719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall maxheight = height*2; 10729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } else { 10739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall maxheight = height; 10749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 10759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( vinfo.yres_virtual > maxheight ) { 10769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall vinfo.yres_virtual = maxheight; 10779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 10789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 10799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall cache_vinfo = vinfo; 10809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifdef FBCON_DEBUG 10819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fprintf(stderr, "Printing actual vinfo:\n"); 10829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall print_vinfo(&vinfo); 10839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 10849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Rmask = 0; 10859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for ( i=0; i<vinfo.red.length; ++i ) { 10869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Rmask <<= 1; 10879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Rmask |= (0x00000001<<vinfo.red.offset); 10889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 10899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Gmask = 0; 10909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for ( i=0; i<vinfo.green.length; ++i ) { 10919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Gmask <<= 1; 10929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Gmask |= (0x00000001<<vinfo.green.offset); 10939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 10949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Bmask = 0; 10959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for ( i=0; i<vinfo.blue.length; ++i ) { 10969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Bmask <<= 1; 10979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Bmask |= (0x00000001<<vinfo.blue.offset); 10989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 10999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( ! SDL_ReallocFormat(current, vinfo.bits_per_pixel, 11009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Rmask, Gmask, Bmask, 0) ) { 11019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return(NULL); 11029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 11039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 11049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Get the fixed information about the console hardware. 11059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall This is necessary since finfo.line_length changes. 11069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall */ 11079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( ioctl(console_fd, FBIOGET_FSCREENINFO, &finfo) < 0 ) { 11089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_SetError("Couldn't get console hardware info"); 11099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return(NULL); 11109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 11119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 11129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Save hardware palette, if needed */ 11139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall FB_SavePalette(this, &finfo, &vinfo); 11149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 11159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (shadow_fb) { 11169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (vinfo.bits_per_pixel == 16) { 11179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall blitFunc = (rotate == FBCON_ROTATE_NONE || 11189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall rotate == FBCON_ROTATE_UD) ? 11199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall FB_blit16 : FB_blit16blocked; 11209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } else { 11219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifdef FBCON_DEBUG 11229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fprintf(stderr, "Init vinfo:\n"); 11239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall print_vinfo(&vinfo); 11249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 11259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_SetError("Using software buffer, but no blitter " 11269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall "function is available for %d bpp.", 11279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall vinfo.bits_per_pixel); 11289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return(NULL); 11299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 11309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 11319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 11329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Set up the new mode framebuffer */ 11339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall current->flags &= SDL_FULLSCREEN; 11349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (shadow_fb) { 11359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall current->flags |= SDL_SWSURFACE; 11369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } else { 11379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall current->flags |= SDL_HWSURFACE; 11389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 11399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall current->w = vinfo.xres; 11409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall current->h = vinfo.yres; 11419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (shadow_fb) { 11429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall current->pitch = current->w * ((vinfo.bits_per_pixel + 7) / 8); 11439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall current->pixels = shadow_mem; 11449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall physlinebytes = finfo.line_length; 11459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } else { 11469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall current->pitch = finfo.line_length; 11479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall current->pixels = mapped_mem+mapped_offset; 11489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 11499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 11509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Set up the information for hardware surfaces */ 11519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall surfaces_mem = (char *)current->pixels + 11529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall vinfo.yres_virtual*current->pitch; 11539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall surfaces_len = (shadow_fb) ? 11549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 0 : (mapped_memlen-(surfaces_mem-mapped_mem)); 11559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 11569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall FB_FreeHWSurfaces(this); 11579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall FB_InitHWSurfaces(this, current, surfaces_mem, surfaces_len); 11589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 11599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Let the application know we have a hardware palette */ 11609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall switch (finfo.visual) { 11619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall case FB_VISUAL_PSEUDOCOLOR: 11629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall current->flags |= SDL_HWPALETTE; 11639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall break; 11649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall default: 11659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall break; 11669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 11679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 11689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Update for double-buffering, if we can */ 11699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( flags & SDL_DOUBLEBUF ) { 11709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( vinfo.yres_virtual == (height*2) ) { 11719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall current->flags |= SDL_DOUBLEBUF; 11729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall flip_page = 0; 11739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall flip_address[0] = (char *)current->pixels; 11749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall flip_address[1] = (char *)current->pixels+ 11759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall current->h*current->pitch; 11769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall this->screen = current; 11779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall FB_FlipHWSurface(this, current); 11789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall this->screen = NULL; 11799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 11809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 11819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 11829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Set the update rectangle function */ 11839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall this->UpdateRects = FB_DirectUpdate; 11849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 11859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* We're done */ 11869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return(current); 11879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 11889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 11899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifdef FBCON_DEBUG 11909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallvoid FB_DumpHWSurfaces(_THIS) 11919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 11929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall vidmem_bucket *bucket; 11939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 11949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall printf("Memory left: %d (%d total)\n", surfaces_memleft, surfaces_memtotal); 11959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall printf("\n"); 11969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall printf(" Base Size\n"); 11979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for ( bucket=&surfaces; bucket; bucket=bucket->next ) { 11989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall printf("Bucket: %p, %d (%s)\n", bucket->base, bucket->size, bucket->used ? "used" : "free"); 11999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( bucket->prev ) { 12009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( bucket->base != bucket->prev->base+bucket->prev->size ) { 12019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall printf("Warning, corrupt bucket list! (prev)\n"); 12029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 12039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } else { 12049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( bucket != &surfaces ) { 12059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall printf("Warning, corrupt bucket list! (!prev)\n"); 12069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 12079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 12089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( bucket->next ) { 12099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( bucket->next->base != bucket->base+bucket->size ) { 12109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall printf("Warning, corrupt bucket list! (next)\n"); 12119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 12129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 12139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 12149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall printf("\n"); 12159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 12169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 12179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 12189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic int FB_InitHWSurfaces(_THIS, SDL_Surface *screen, char *base, int size) 12199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 12209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall vidmem_bucket *bucket; 12219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 12229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall surfaces_memtotal = size; 12239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall surfaces_memleft = size; 12249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 12259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( surfaces_memleft > 0 ) { 12269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall bucket = (vidmem_bucket *)SDL_malloc(sizeof(*bucket)); 12279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( bucket == NULL ) { 12289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_OutOfMemory(); 12299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return(-1); 12309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 12319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall bucket->prev = &surfaces; 12329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall bucket->used = 0; 12339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall bucket->dirty = 0; 12349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall bucket->base = base; 12359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall bucket->size = size; 12369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall bucket->next = NULL; 12379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } else { 12389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall bucket = NULL; 12399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 12409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 12419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall surfaces.prev = NULL; 12429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall surfaces.used = 1; 12439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall surfaces.dirty = 0; 12449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall surfaces.base = screen->pixels; 12459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall surfaces.size = (unsigned int)((long)base - (long)surfaces.base); 12469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall surfaces.next = bucket; 12479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall screen->hwdata = (struct private_hwdata *)&surfaces; 12489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return(0); 12499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 12509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void FB_FreeHWSurfaces(_THIS) 12519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 12529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall vidmem_bucket *bucket, *freeable; 12539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 12549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall bucket = surfaces.next; 12559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall while ( bucket ) { 12569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall freeable = bucket; 12579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall bucket = bucket->next; 12589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_free(freeable); 12599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 12609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall surfaces.next = NULL; 12619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 12629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 12639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic int FB_AllocHWSurface(_THIS, SDL_Surface *surface) 12649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 12659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall vidmem_bucket *bucket; 12669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int size; 12679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int extra; 12689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 12699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Temporarily, we only allow surfaces the same width as display. 12709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Some blitters require the pitch between two hardware surfaces 12719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall to be the same. Others have interesting alignment restrictions. 12729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Until someone who knows these details looks at the code... 12739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall*/ 12749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallif ( surface->pitch > SDL_VideoSurface->pitch ) { 12759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_SetError("Surface requested wider than screen"); 12769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return(-1); 12779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 12789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallsurface->pitch = SDL_VideoSurface->pitch; 12799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size = surface->h * surface->pitch; 12809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifdef FBCON_DEBUG 12819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fprintf(stderr, "Allocating bucket of %d bytes\n", size); 12829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 12839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 12849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Quick check for available mem */ 12859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( size > surfaces_memleft ) { 12869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_SetError("Not enough video memory"); 12879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return(-1); 12889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 12899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 12909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Search for an empty bucket big enough */ 12919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for ( bucket=&surfaces; bucket; bucket=bucket->next ) { 12929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( ! bucket->used && (size <= bucket->size) ) { 12939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall break; 12949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 12959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 12969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( bucket == NULL ) { 12979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_SetError("Video memory too fragmented"); 12989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return(-1); 12999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 13009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 13019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Create a new bucket for left-over memory */ 13029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall extra = (bucket->size - size); 13039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( extra ) { 13049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall vidmem_bucket *newbucket; 13059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 13069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifdef FBCON_DEBUG 13079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fprintf(stderr, "Adding new free bucket of %d bytes\n", extra); 13089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 13099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall newbucket = (vidmem_bucket *)SDL_malloc(sizeof(*newbucket)); 13109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( newbucket == NULL ) { 13119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_OutOfMemory(); 13129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return(-1); 13139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 13149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall newbucket->prev = bucket; 13159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall newbucket->used = 0; 13169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall newbucket->base = bucket->base+size; 13179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall newbucket->size = extra; 13189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall newbucket->next = bucket->next; 13199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( bucket->next ) { 13209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall bucket->next->prev = newbucket; 13219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 13229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall bucket->next = newbucket; 13239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 13249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 13259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Set the current bucket values and return it! */ 13269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall bucket->used = 1; 13279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall bucket->size = size; 13289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall bucket->dirty = 0; 13299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifdef FBCON_DEBUG 13309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fprintf(stderr, "Allocated %d bytes at %p\n", bucket->size, bucket->base); 13319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 13329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall surfaces_memleft -= size; 13339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall surface->flags |= SDL_HWSURFACE; 13349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall surface->pixels = bucket->base; 13359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall surface->hwdata = (struct private_hwdata *)bucket; 13369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return(0); 13379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 13389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void FB_FreeHWSurface(_THIS, SDL_Surface *surface) 13399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 13409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall vidmem_bucket *bucket, *freeable; 13419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 13429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Look for the bucket in the current list */ 13439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for ( bucket=&surfaces; bucket; bucket=bucket->next ) { 13449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( bucket == (vidmem_bucket *)surface->hwdata ) { 13459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall break; 13469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 13479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 13489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( bucket && bucket->used ) { 13499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Add the memory back to the total */ 13509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifdef DGA_DEBUG 13519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall printf("Freeing bucket of %d bytes\n", bucket->size); 13529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 13539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall surfaces_memleft += bucket->size; 13549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 13559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Can we merge the space with surrounding buckets? */ 13569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall bucket->used = 0; 13579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( bucket->next && ! bucket->next->used ) { 13589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifdef DGA_DEBUG 13599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall printf("Merging with next bucket, for %d total bytes\n", bucket->size+bucket->next->size); 13609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 13619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall freeable = bucket->next; 13629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall bucket->size += bucket->next->size; 13639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall bucket->next = bucket->next->next; 13649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( bucket->next ) { 13659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall bucket->next->prev = bucket; 13669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 13679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_free(freeable); 13689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 13699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( bucket->prev && ! bucket->prev->used ) { 13709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifdef DGA_DEBUG 13719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall printf("Merging with previous bucket, for %d total bytes\n", bucket->prev->size+bucket->size); 13729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 13739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall freeable = bucket; 13749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall bucket->prev->size += bucket->size; 13759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall bucket->prev->next = bucket->next; 13769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( bucket->next ) { 13779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall bucket->next->prev = bucket->prev; 13789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 13799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_free(freeable); 13809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 13819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 13829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall surface->pixels = NULL; 13839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall surface->hwdata = NULL; 13849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 13859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 13869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic int FB_LockHWSurface(_THIS, SDL_Surface *surface) 13879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 13889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( switched_away ) { 13899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return -2; /* no hardware access */ 13909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 13919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( surface == this->screen ) { 13929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_mutexP(hw_lock); 13939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( FB_IsSurfaceBusy(surface) ) { 13949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall FB_WaitBusySurfaces(this); 13959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 13969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } else { 13979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( FB_IsSurfaceBusy(surface) ) { 13989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall FB_WaitBusySurfaces(this); 13999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 14009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 14019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return(0); 14029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 14039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void FB_UnlockHWSurface(_THIS, SDL_Surface *surface) 14049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 14059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( surface == this->screen ) { 14069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_mutexV(hw_lock); 14079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 14089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 14099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 14109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void FB_WaitVBL(_THIS) 14119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 14129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifdef FBIOWAITRETRACE /* Heheh, this didn't make it into the main kernel */ 14139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ioctl(console_fd, FBIOWAITRETRACE, 0); 14149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 14159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return; 14169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 14179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 14189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void FB_WaitIdle(_THIS) 14199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 14209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return; 14219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 14229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 14239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic int FB_FlipHWSurface(_THIS, SDL_Surface *surface) 14249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 14259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( switched_away ) { 14269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return -2; /* no hardware access */ 14279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 14289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 14299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Wait for vertical retrace and then flip display */ 14309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall cache_vinfo.yoffset = flip_page*surface->h; 14319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( FB_IsSurfaceBusy(this->screen) ) { 14329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall FB_WaitBusySurfaces(this); 14339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 14349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall wait_vbl(this); 14359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( ioctl(console_fd, FBIOPAN_DISPLAY, &cache_vinfo) < 0 ) { 14369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_SetError("ioctl(FBIOPAN_DISPLAY) failed"); 14379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return(-1); 14389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 14399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall flip_page = !flip_page; 14409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 14419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall surface->pixels = flip_address[flip_page]; 14429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return(0); 14439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 14449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 14459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void FB_blit16(Uint8 *byte_src_pos, int src_right_delta, int src_down_delta, 14469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Uint8 *byte_dst_pos, int dst_linebytes, int width, int height) 14479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 14489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int w; 14499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Uint16 *src_pos = (Uint16 *)byte_src_pos; 14509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Uint16 *dst_pos = (Uint16 *)byte_dst_pos; 14519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 14529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall while (height) { 14539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Uint16 *src = src_pos; 14549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Uint16 *dst = dst_pos; 14559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for (w = width; w != 0; w--) { 14569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall *dst = *src; 14579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall src += src_right_delta; 14589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall dst++; 14599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 14609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall dst_pos = (Uint16 *)((Uint8 *)dst_pos + dst_linebytes); 14619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall src_pos += src_down_delta; 14629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall height--; 14639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 14649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 14659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 14669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define BLOCKSIZE_W 32 14679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define BLOCKSIZE_H 32 14689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 14699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void FB_blit16blocked(Uint8 *byte_src_pos, int src_right_delta, int src_down_delta, 14709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Uint8 *byte_dst_pos, int dst_linebytes, int width, int height) 14719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 14729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int w; 14739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Uint16 *src_pos = (Uint16 *)byte_src_pos; 14749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Uint16 *dst_pos = (Uint16 *)byte_dst_pos; 14759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 14769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall while (height > 0) { 14779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Uint16 *src = src_pos; 14789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Uint16 *dst = dst_pos; 14799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for (w = width; w > 0; w -= BLOCKSIZE_W) { 14809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall FB_blit16((Uint8 *)src, 14819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall src_right_delta, 14829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall src_down_delta, 14839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (Uint8 *)dst, 14849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall dst_linebytes, 14859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall min(w, BLOCKSIZE_W), 14869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall min(height, BLOCKSIZE_H)); 14879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall src += src_right_delta * BLOCKSIZE_W; 14889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall dst += BLOCKSIZE_W; 14899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 14909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall dst_pos = (Uint16 *)((Uint8 *)dst_pos + dst_linebytes * BLOCKSIZE_H); 14919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall src_pos += src_down_delta * BLOCKSIZE_H; 14929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall height -= BLOCKSIZE_H; 14939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 14949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 14959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 14969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void FB_DirectUpdate(_THIS, int numrects, SDL_Rect *rects) 14979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 14989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int width = cache_vinfo.xres; 14999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int height = cache_vinfo.yres; 15009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int bytes_per_pixel = (cache_vinfo.bits_per_pixel + 7) / 8; 15019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int i; 15029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 15039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (!shadow_fb) { 15049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* The application is already updating the visible video memory */ 15059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return; 15069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 15079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 15089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (cache_vinfo.bits_per_pixel != 16) { 15099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_SetError("Shadow copy only implemented for 16 bpp"); 15109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return; 15119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 15129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 15139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for (i = 0; i < numrects; i++) { 15149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int x1, y1, x2, y2; 15159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int scr_x1, scr_y1, scr_x2, scr_y2; 15169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int sha_x1, sha_y1; 15179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int shadow_right_delta; /* Address change when moving right in dest */ 15189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int shadow_down_delta; /* Address change when moving down in dest */ 15199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall char *src_start; 15209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall char *dst_start; 15219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 15229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall x1 = rects[i].x; 15239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall y1 = rects[i].y; 15249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall x2 = x1 + rects[i].w; 15259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall y2 = y1 + rects[i].h; 15269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 15279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (x1 < 0) { 15289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall x1 = 0; 15299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } else if (x1 > width) { 15309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall x1 = width; 15319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 15329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (x2 < 0) { 15339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall x2 = 0; 15349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } else if (x2 > width) { 15359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall x2 = width; 15369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 15379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (y1 < 0) { 15389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall y1 = 0; 15399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } else if (y1 > height) { 15409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall y1 = height; 15419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 15429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (y2 < 0) { 15439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall y2 = 0; 15449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } else if (y2 > height) { 15459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall y2 = height; 15469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 15479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (x2 <= x1 || y2 <= y1) { 15489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall continue; 15499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 15509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 15519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall switch (rotate) { 15529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall case FBCON_ROTATE_NONE: 15539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall sha_x1 = scr_x1 = x1; 15549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall sha_y1 = scr_y1 = y1; 15559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall scr_x2 = x2; 15569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall scr_y2 = y2; 15579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall shadow_right_delta = 1; 15589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall shadow_down_delta = width; 15599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall break; 15609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall case FBCON_ROTATE_CCW: 15619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall scr_x1 = y1; 15629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall scr_y1 = width - x2; 15639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall scr_x2 = y2; 15649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall scr_y2 = width - x1; 15659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall sha_x1 = x2 - 1; 15669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall sha_y1 = y1; 15679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall shadow_right_delta = width; 15689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall shadow_down_delta = -1; 15699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall break; 15709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall case FBCON_ROTATE_UD: 15719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall scr_x1 = width - x2; 15729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall scr_y1 = height - y2; 15739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall scr_x2 = width - x1; 15749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall scr_y2 = height - y1; 15759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall sha_x1 = x2 - 1; 15769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall sha_y1 = y2 - 1; 15779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall shadow_right_delta = -1; 15789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall shadow_down_delta = -width; 15799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall break; 15809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall case FBCON_ROTATE_CW: 15819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall scr_x1 = height - y2; 15829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall scr_y1 = x1; 15839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall scr_x2 = height - y1; 15849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall scr_y2 = x2; 15859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall sha_x1 = x1; 15869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall sha_y1 = y2 - 1; 15879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall shadow_right_delta = -width; 15889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall shadow_down_delta = 1; 15899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall break; 15909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall default: 15919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_SetError("Unknown rotation"); 15929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return; 15939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 15949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 15959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall src_start = shadow_mem + 15969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (sha_y1 * width + sha_x1) * bytes_per_pixel; 15979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall dst_start = mapped_mem + mapped_offset + scr_y1 * physlinebytes + 15989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall scr_x1 * bytes_per_pixel; 15999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 16009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall blitFunc((Uint8 *) src_start, 16019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall shadow_right_delta, 16029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall shadow_down_delta, 16039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (Uint8 *) dst_start, 16049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall physlinebytes, 16059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall scr_x2 - scr_x1, 16069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall scr_y2 - scr_y1); 16079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 16089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 16099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 16109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifdef VGA16_FBCON_SUPPORT 16119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Code adapted with thanks from the XFree86 VGA16 driver! :) */ 16129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define writeGr(index, value) \ 16139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Halloutb(index, 0x3CE); \ 16149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Halloutb(value, 0x3CF); 16159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define writeSeq(index, value) \ 16169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Halloutb(index, 0x3C4); \ 16179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Halloutb(value, 0x3C5); 16189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 16199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void FB_VGA16Update(_THIS, int numrects, SDL_Rect *rects) 16209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 16219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_Surface *screen; 16229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int width, height, FBPitch, left, i, j, SRCPitch, phase; 16239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall register Uint32 m; 16249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Uint8 s1, s2, s3, s4; 16259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Uint32 *src, *srcPtr; 16269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Uint8 *dst, *dstPtr; 16279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 16289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( switched_away ) { 16299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return; /* no hardware access */ 16309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 16319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 16329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall screen = this->screen; 16339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall FBPitch = screen->w >> 3; 16349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SRCPitch = screen->pitch >> 2; 16359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 16369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall writeGr(0x03, 0x00); 16379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall writeGr(0x05, 0x00); 16389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall writeGr(0x01, 0x00); 16399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall writeGr(0x08, 0xFF); 16409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 16419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall while(numrects--) { 16429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall left = rects->x & ~7; 16439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall width = (rects->w + 7) >> 3; 16449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall height = rects->h; 16459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall src = (Uint32*)screen->pixels + (rects->y * SRCPitch) + (left >> 2); 16469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall dst = (Uint8*)mapped_mem + (rects->y * FBPitch) + (left >> 3); 16479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 16489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if((phase = (long)dst & 3L)) { 16499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall phase = 4 - phase; 16509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if(phase > width) phase = width; 16519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall width -= phase; 16529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 16539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 16549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall while(height--) { 16559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall writeSeq(0x02, 1 << 0); 16569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall dstPtr = dst; 16579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall srcPtr = src; 16589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall i = width; 16599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall j = phase; 16609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall while(j--) { 16619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall m = (srcPtr[1] & 0x01010101) | ((srcPtr[0] & 0x01010101) << 4); 16629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall *dstPtr++ = (m >> 24) | (m >> 15) | (m >> 6) | (m << 3); 16639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall srcPtr += 2; 16649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 16659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall while(i >= 4) { 16669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall m = (srcPtr[1] & 0x01010101) | ((srcPtr[0] & 0x01010101) << 4); 16679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall s1 = (m >> 24) | (m >> 15) | (m >> 6) | (m << 3); 16689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall m = (srcPtr[3] & 0x01010101) | ((srcPtr[2] & 0x01010101) << 4); 16699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall s2 = (m >> 24) | (m >> 15) | (m >> 6) | (m << 3); 16709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall m = (srcPtr[5] & 0x01010101) | ((srcPtr[4] & 0x01010101) << 4); 16719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall s3 = (m >> 24) | (m >> 15) | (m >> 6) | (m << 3); 16729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall m = (srcPtr[7] & 0x01010101) | ((srcPtr[6] & 0x01010101) << 4); 16739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall s4 = (m >> 24) | (m >> 15) | (m >> 6) | (m << 3); 16749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall *((Uint32*)dstPtr) = s1 | (s2 << 8) | (s3 << 16) | (s4 << 24); 16759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall srcPtr += 8; 16769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall dstPtr += 4; 16779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall i -= 4; 16789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 16799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall while(i--) { 16809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall m = (srcPtr[1] & 0x01010101) | ((srcPtr[0] & 0x01010101) << 4); 16819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall *dstPtr++ = (m >> 24) | (m >> 15) | (m >> 6) | (m << 3); 16829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall srcPtr += 2; 16839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 16849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 16859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall writeSeq(0x02, 1 << 1); 16869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall dstPtr = dst; 16879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall srcPtr = src; 16889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall i = width; 16899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall j = phase; 16909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall while(j--) { 16919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall m = (srcPtr[1] & 0x02020202) | ((srcPtr[0] & 0x02020202) << 4); 16929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall *dstPtr++ = (m >> 25) | (m >> 16) | (m >> 7) | (m << 2); 16939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall srcPtr += 2; 16949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 16959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall while(i >= 4) { 16969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall m = (srcPtr[1] & 0x02020202) | ((srcPtr[0] & 0x02020202) << 4); 16979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall s1 = (m >> 25) | (m >> 16) | (m >> 7) | (m << 2); 16989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall m = (srcPtr[3] & 0x02020202) | ((srcPtr[2] & 0x02020202) << 4); 16999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall s2 = (m >> 25) | (m >> 16) | (m >> 7) | (m << 2); 17009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall m = (srcPtr[5] & 0x02020202) | ((srcPtr[4] & 0x02020202) << 4); 17019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall s3 = (m >> 25) | (m >> 16) | (m >> 7) | (m << 2); 17029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall m = (srcPtr[7] & 0x02020202) | ((srcPtr[6] & 0x02020202) << 4); 17039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall s4 = (m >> 25) | (m >> 16) | (m >> 7) | (m << 2); 17049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall *((Uint32*)dstPtr) = s1 | (s2 << 8) | (s3 << 16) | (s4 << 24); 17059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall srcPtr += 8; 17069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall dstPtr += 4; 17079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall i -= 4; 17089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 17099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall while(i--) { 17109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall m = (srcPtr[1] & 0x02020202) | ((srcPtr[0] & 0x02020202) << 4); 17119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall *dstPtr++ = (m >> 25) | (m >> 16) | (m >> 7) | (m << 2); 17129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall srcPtr += 2; 17139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 17149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 17159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall writeSeq(0x02, 1 << 2); 17169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall dstPtr = dst; 17179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall srcPtr = src; 17189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall i = width; 17199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall j = phase; 17209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall while(j--) { 17219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall m = (srcPtr[1] & 0x04040404) | ((srcPtr[0] & 0x04040404) << 4); 17229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall *dstPtr++ = (m >> 26) | (m >> 17) | (m >> 8) | (m << 1); 17239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall srcPtr += 2; 17249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 17259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall while(i >= 4) { 17269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall m = (srcPtr[1] & 0x04040404) | ((srcPtr[0] & 0x04040404) << 4); 17279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall s1 = (m >> 26) | (m >> 17) | (m >> 8) | (m << 1); 17289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall m = (srcPtr[3] & 0x04040404) | ((srcPtr[2] & 0x04040404) << 4); 17299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall s2 = (m >> 26) | (m >> 17) | (m >> 8) | (m << 1); 17309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall m = (srcPtr[5] & 0x04040404) | ((srcPtr[4] & 0x04040404) << 4); 17319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall s3 = (m >> 26) | (m >> 17) | (m >> 8) | (m << 1); 17329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall m = (srcPtr[7] & 0x04040404) | ((srcPtr[6] & 0x04040404) << 4); 17339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall s4 = (m >> 26) | (m >> 17) | (m >> 8) | (m << 1); 17349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall *((Uint32*)dstPtr) = s1 | (s2 << 8) | (s3 << 16) | (s4 << 24); 17359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall srcPtr += 8; 17369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall dstPtr += 4; 17379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall i -= 4; 17389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 17399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall while(i--) { 17409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall m = (srcPtr[1] & 0x04040404) | ((srcPtr[0] & 0x04040404) << 4); 17419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall *dstPtr++ = (m >> 26) | (m >> 17) | (m >> 8) | (m << 1); 17429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall srcPtr += 2; 17439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 17449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 17459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall writeSeq(0x02, 1 << 3); 17469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall dstPtr = dst; 17479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall srcPtr = src; 17489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall i = width; 17499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall j = phase; 17509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall while(j--) { 17519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall m = (srcPtr[1] & 0x08080808) | ((srcPtr[0] & 0x08080808) << 4); 17529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall *dstPtr++ = (m >> 27) | (m >> 18) | (m >> 9) | m; 17539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall srcPtr += 2; 17549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 17559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall while(i >= 4) { 17569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall m = (srcPtr[1] & 0x08080808) | ((srcPtr[0] & 0x08080808) << 4); 17579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall s1 = (m >> 27) | (m >> 18) | (m >> 9) | m; 17589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall m = (srcPtr[3] & 0x08080808) | ((srcPtr[2] & 0x08080808) << 4); 17599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall s2 = (m >> 27) | (m >> 18) | (m >> 9) | m; 17609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall m = (srcPtr[5] & 0x08080808) | ((srcPtr[4] & 0x08080808) << 4); 17619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall s3 = (m >> 27) | (m >> 18) | (m >> 9) | m; 17629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall m = (srcPtr[7] & 0x08080808) | ((srcPtr[6] & 0x08080808) << 4); 17639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall s4 = (m >> 27) | (m >> 18) | (m >> 9) | m; 17649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall *((Uint32*)dstPtr) = s1 | (s2 << 8) | (s3 << 16) | (s4 << 24); 17659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall srcPtr += 8; 17669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall dstPtr += 4; 17679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall i -= 4; 17689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 17699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall while(i--) { 17709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall m = (srcPtr[1] & 0x08080808) | ((srcPtr[0] & 0x08080808) << 4); 17719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall *dstPtr++ = (m >> 27) | (m >> 18) | (m >> 9) | m; 17729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall srcPtr += 2; 17739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 17749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 17759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall dst += FBPitch; 17769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall src += SRCPitch; 17779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 17789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall rects++; 17799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 17809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 17819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* VGA16_FBCON_SUPPORT */ 17829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 17839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallvoid FB_SavePaletteTo(_THIS, int palette_len, __u16 *area) 17849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 17859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall struct fb_cmap cmap; 17869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 17879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall cmap.start = 0; 17889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall cmap.len = palette_len; 17899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall cmap.red = &area[0*palette_len]; 17909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall cmap.green = &area[1*palette_len]; 17919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall cmap.blue = &area[2*palette_len]; 17929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall cmap.transp = NULL; 17939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ioctl(console_fd, FBIOGETCMAP, &cmap); 17949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 17959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 17969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallvoid FB_RestorePaletteFrom(_THIS, int palette_len, __u16 *area) 17979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 17989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall struct fb_cmap cmap; 17999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 18009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall cmap.start = 0; 18019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall cmap.len = palette_len; 18029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall cmap.red = &area[0*palette_len]; 18039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall cmap.green = &area[1*palette_len]; 18049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall cmap.blue = &area[2*palette_len]; 18059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall cmap.transp = NULL; 18069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ioctl(console_fd, FBIOPUTCMAP, &cmap); 18079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 18089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 18099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void FB_SavePalette(_THIS, struct fb_fix_screeninfo *finfo, 18109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall struct fb_var_screeninfo *vinfo) 18119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 18129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int i; 18139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 18149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Save hardware palette, if needed */ 18159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( finfo->visual == FB_VISUAL_PSEUDOCOLOR ) { 18169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall saved_cmaplen = 1<<vinfo->bits_per_pixel; 18179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall saved_cmap=(__u16 *)SDL_malloc(3*saved_cmaplen*sizeof(*saved_cmap)); 18189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( saved_cmap != NULL ) { 18199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall FB_SavePaletteTo(this, saved_cmaplen, saved_cmap); 18209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 18219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 18229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 18239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Added support for FB_VISUAL_DIRECTCOLOR. 18249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall With this mode pixel information is passed through the palette... 18259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Neat fading and gamma correction effects can be had by simply 18269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fooling around with the palette instead of changing the pixel 18279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall values themselves... Very neat! 18289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 18299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Adam Meyerowitz 1/19/2000 18309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ameyerow@optonline.com 18319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall */ 18329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( finfo->visual == FB_VISUAL_DIRECTCOLOR ) { 18339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall __u16 new_entries[3*256]; 18349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 18359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Save the colormap */ 18369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall saved_cmaplen = 256; 18379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall saved_cmap=(__u16 *)SDL_malloc(3*saved_cmaplen*sizeof(*saved_cmap)); 18389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( saved_cmap != NULL ) { 18399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall FB_SavePaletteTo(this, saved_cmaplen, saved_cmap); 18409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 18419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 18429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Allocate new identity colormap */ 18439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for ( i=0; i<256; ++i ) { 18449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall new_entries[(0*256)+i] = 18459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall new_entries[(1*256)+i] = 18469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall new_entries[(2*256)+i] = (i<<8)|i; 18479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 18489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall FB_RestorePaletteFrom(this, 256, new_entries); 18499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 18509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 18519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 18529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void FB_RestorePalette(_THIS) 18539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 18549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Restore the original palette */ 18559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( saved_cmap ) { 18569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall FB_RestorePaletteFrom(this, saved_cmaplen, saved_cmap); 18579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_free(saved_cmap); 18589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall saved_cmap = NULL; 18599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 18609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 18619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 18629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic int FB_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) 18639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 18649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int i; 18659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall __u16 r[256]; 18669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall __u16 g[256]; 18679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall __u16 b[256]; 18689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall struct fb_cmap cmap; 18699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 18709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Set up the colormap */ 18719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for (i = 0; i < ncolors; i++) { 18729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall r[i] = colors[i].r << 8; 18739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall g[i] = colors[i].g << 8; 18749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall b[i] = colors[i].b << 8; 18759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 18769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall cmap.start = firstcolor; 18779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall cmap.len = ncolors; 18789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall cmap.red = r; 18799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall cmap.green = g; 18809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall cmap.blue = b; 18819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall cmap.transp = NULL; 18829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 18839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if( (ioctl(console_fd, FBIOPUTCMAP, &cmap) < 0) || 18849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall !(this->screen->flags & SDL_HWPALETTE) ) { 18859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall colors = this->screen->format->palette->colors; 18869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ncolors = this->screen->format->palette->ncolors; 18879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall cmap.start = 0; 18889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall cmap.len = ncolors; 18899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_memset(r, 0, sizeof(r)); 18909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_memset(g, 0, sizeof(g)); 18919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_memset(b, 0, sizeof(b)); 18929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( ioctl(console_fd, FBIOGETCMAP, &cmap) == 0 ) { 18939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for ( i=ncolors-1; i>=0; --i ) { 18949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall colors[i].r = (r[i]>>8); 18959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall colors[i].g = (g[i]>>8); 18969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall colors[i].b = (b[i]>>8); 18979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 18989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 18999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return(0); 19009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 19019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return(1); 19029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 19039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 19049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Note: If we are terminated, this could be called in the middle of 19059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall another SDL video routine -- notably UpdateRects. 19069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall*/ 19079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void FB_VideoQuit(_THIS) 19089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 19099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int i, j; 19109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 19119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( this->screen ) { 19129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Clear screen and tell SDL not to free the pixels */ 19139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 19149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall const char *dontClearPixels = SDL_getenv("SDL_FBCON_DONT_CLEAR"); 19159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 19169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* If the framebuffer is not to be cleared, make sure that we won't 19179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * display the previous frame when disabling double buffering. */ 19189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( dontClearPixels && flip_page == 0 ) { 19199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_memcpy(flip_address[0], flip_address[1], this->screen->pitch * this->screen->h); 19209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 19219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 19229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( !dontClearPixels && this->screen->pixels && FB_InGraphicsMode(this) ) { 19239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if defined(__powerpc__) || defined(__ia64__) /* SIGBUS when using SDL_memset() ?? */ 19249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Uint8 *rowp = (Uint8 *)this->screen->pixels; 19259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int left = this->screen->pitch*this->screen->h; 19269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall while ( left-- ) { *rowp++ = 0; } 19279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#else 19289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_memset(this->screen->pixels,0,this->screen->h*this->screen->pitch); 19299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 19309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 19319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* This test fails when using the VGA16 shadow memory */ 19329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( ((char *)this->screen->pixels >= mapped_mem) && 19339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ((char *)this->screen->pixels < (mapped_mem+mapped_memlen)) ) { 19349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall this->screen->pixels = NULL; 19359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 19369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 19379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 19389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Clear the lock mutex */ 19399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( hw_lock ) { 19409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_DestroyMutex(hw_lock); 19419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall hw_lock = NULL; 19429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 19439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 19449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Clean up defined video modes */ 19459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for ( i=0; i<NUM_MODELISTS; ++i ) { 19469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( SDL_modelist[i] != NULL ) { 19479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for ( j=0; SDL_modelist[i][j]; ++j ) { 19489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_free(SDL_modelist[i][j]); 19499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 19509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_free(SDL_modelist[i]); 19519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_modelist[i] = NULL; 19529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 19539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 19549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 19559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Clean up the memory bucket list */ 19569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall FB_FreeHWSurfaces(this); 19579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 19589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Close console and input file descriptors */ 19599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( console_fd > 0 ) { 19609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Unmap the video framebuffer and I/O registers */ 19619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( mapped_mem ) { 19629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall munmap(mapped_mem, mapped_memlen); 19639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mapped_mem = NULL; 19649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 19659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( mapped_io ) { 19669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall munmap(mapped_io, mapped_iolen); 19679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mapped_io = NULL; 19689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 19699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 19709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Restore the original video mode and palette */ 19719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( FB_InGraphicsMode(this) ) { 19729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall FB_RestorePalette(this); 19739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ioctl(console_fd, FBIOPUT_VSCREENINFO, &saved_vinfo); 19749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 19759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 19769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* We're all done with the framebuffer */ 19779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall close(console_fd); 19789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall console_fd = -1; 19799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 19809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall FB_CloseMouse(this); 19819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall FB_CloseKeyboard(this); 19829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 1983