Mercurial > sdl-ios-xcode
annotate src/video/fbcon/SDL_fbvideo.c @ 1287:15a89a0c52bf
Date: Tue, 15 Feb 2005 21:28:48 +0900 (JST)
From: "Michael Leonhard"
Subject: [SDL] resize bug on Win32 and patch
This is my first post to this mailing list. In this email I will detail a
bug in the behavior of resizable SDL windows on Win32. Then I will
explain the solution and provide a patch.
Symptoms:
Under Windows, an SDL display created with the SDL_RESIZABLE flag exhibits
quirky behavior when being maximized. The window is resized to the proper
size, but it is shifted upwards about half the height of the title bar.
Similarly, a window whose origin is above the top of the screen will
spontaneously move its upper-left origin upon being resized. After two
such resize-induced moves, the title bar will be entirely off the top edge
of the screen. Subsequently, when the mouse is clicked and released on
the window border, the window will shrink its height spontaneously. This
height shrinkage occurs even if the user did not resize the border.
To observe this curious situation, please invoke:
SDL-1.2.8/test/testwm.exe -resize
Cause:
A pair of integers, SDL_windowX and SDL_windowY, are defined in
video/wincommon/SDL_sysevents.c. They are used by the DirectX video
driver and the DIB video driver:
video/windx5/SDL_dx5video.c
video/windib/SDL_dibvideo.c
As I understand the source code, the primary use of these variables is to
create a rectangle that represents the surface area in CLIENT SPACE.
Client space refers to a coordinate system that originates at the upper
left corner of a Win32 Window's drawable area. This is just inside the
window border and title bar. This client space rectangle, called bounds,
is subsequently converted to screen space with a call to
AdjustWindowRectEx. The problem is found in SDL's handling of the
WM_WINDOWPOSCHANGED message. According to MSDN,
"The WM_WINDOWPOSCHANGED message is sent to a window whose
size, position, or place in the Z order has changed as a
result of a call to the SetWindowPos function or another
window-management function."
I have confirmed that this message is indeed being sent to the SDL window
when the mouse is clicked on the window border, even if the window border
is not dragged.
In video/wincommon/SDL_sysevents.c, on line 464, in response to the
WM_WINDOWPOSCHANGED message, the (potentially) new client rectangle is
obtained. This rectangle is translated into screen coordinates and THEN
assigned to the SDL_windowX and Y variables. Thus screen coordinates are
being assigned to client coordinate variables. Once this is understood,
the solution is apparent: assign SDL_windowX and Y before translating the
rectangle to screen coordinates. This is accomplished by the following
patch.
-Mike_L
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Sun, 29 Jan 2006 08:50:06 +0000 |
parents | ae9981987c2f |
children | c9b51268668f |
rev | line source |
---|---|
0 | 1 /* |
2 SDL - Simple DirectMedia Layer | |
769
b8d311d90021
Updated copyright information for 2004 (Happy New Year!)
Sam Lantinga <slouken@libsdl.org>
parents:
487
diff
changeset
|
3 Copyright (C) 1997-2004 Sam Lantinga |
0 | 4 |
5 This library is free software; you can redistribute it and/or | |
6 modify it under the terms of the GNU Library General Public | |
7 License as published by the Free Software Foundation; either | |
8 version 2 of the License, or (at your option) any later version. | |
9 | |
10 This library is distributed in the hope that it will be useful, | |
11 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 Library General Public License for more details. | |
14 | |
15 You should have received a copy of the GNU Library General Public | |
16 License along with this library; if not, write to the Free | |
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
18 | |
19 Sam Lantinga | |
252
e8157fcb3114
Updated the source with the correct e-mail address
Sam Lantinga <slouken@libsdl.org>
parents:
133
diff
changeset
|
20 slouken@libsdl.org |
0 | 21 */ |
22 | |
23 #ifdef SAVE_RCSID | |
24 static char rcsid = | |
25 "@(#) $Id$"; | |
26 #endif | |
27 | |
28 /* Framebuffer console based SDL video driver implementation. | |
29 */ | |
30 | |
31 #include <stdlib.h> | |
32 #include <stdio.h> | |
33 #include <string.h> | |
34 #include <fcntl.h> | |
35 #include <unistd.h> | |
36 #include <sys/ioctl.h> | |
37 #include <sys/mman.h> | |
38 #include <asm/page.h> /* For definition of PAGE_SIZE */ | |
39 | |
40 #include "SDL.h" | |
41 #include "SDL_error.h" | |
42 #include "SDL_video.h" | |
43 #include "SDL_mouse.h" | |
44 #include "SDL_sysvideo.h" | |
45 #include "SDL_pixels_c.h" | |
46 #include "SDL_events_c.h" | |
47 #include "SDL_fbvideo.h" | |
48 #include "SDL_fbmouse_c.h" | |
49 #include "SDL_fbevents_c.h" | |
50 #include "SDL_fb3dfx.h" | |
51 #include "SDL_fbmatrox.h" | |
133
5d4bafca35cd
Added support for hardware accelerated NVidia driver on framebuffer console
Sam Lantinga <slouken@libsdl.org>
parents:
106
diff
changeset
|
52 #include "SDL_fbriva.h" |
5d4bafca35cd
Added support for hardware accelerated NVidia driver on framebuffer console
Sam Lantinga <slouken@libsdl.org>
parents:
106
diff
changeset
|
53 |
1215
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
54 /*#define FBCON_DEBUG*/ |
0 | 55 |
56 #if defined(i386) && defined(FB_TYPE_VGA_PLANES) | |
57 #define VGA16_FBCON_SUPPORT | |
58 #ifndef FB_AUX_VGA_PLANES_VGA4 | |
59 #define FB_AUX_VGA_PLANES_VGA4 0 | |
60 #endif | |
61 static inline void outb (unsigned char value, unsigned short port) | |
62 { | |
63 __asm__ __volatile__ ("outb %b0,%w1"::"a" (value), "Nd" (port)); | |
64 } | |
65 #endif /* FB_TYPE_VGA_PLANES */ | |
66 | |
67 /* A list of video resolutions that we query for (sorted largest to smallest) */ | |
91
e85e03f195b4
From: "Markus F.X.J. Oberhumer"
Sam Lantinga <slouken@lokigames.com>
parents:
6
diff
changeset
|
68 static const SDL_Rect checkres[] = { |
0 | 69 { 0, 0, 1600, 1200 }, /* 16 bpp: 0x11E, or 286 */ |
70 { 0, 0, 1408, 1056 }, /* 16 bpp: 0x19A, or 410 */ | |
71 { 0, 0, 1280, 1024 }, /* 16 bpp: 0x11A, or 282 */ | |
72 { 0, 0, 1152, 864 }, /* 16 bpp: 0x192, or 402 */ | |
73 { 0, 0, 1024, 768 }, /* 16 bpp: 0x117, or 279 */ | |
74 { 0, 0, 960, 720 }, /* 16 bpp: 0x18A, or 394 */ | |
75 { 0, 0, 800, 600 }, /* 16 bpp: 0x114, or 276 */ | |
76 { 0, 0, 768, 576 }, /* 16 bpp: 0x182, or 386 */ | |
330
5fed858d551c
Date: 03 Apr 2002 15:28:09 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
77 { 0, 0, 720, 576 }, /* PAL */ |
5fed858d551c
Date: 03 Apr 2002 15:28:09 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
78 { 0, 0, 720, 480 }, /* NTSC */ |
0 | 79 { 0, 0, 640, 480 }, /* 16 bpp: 0x111, or 273 */ |
80 { 0, 0, 640, 400 }, /* 8 bpp: 0x100, or 256 */ | |
81 { 0, 0, 512, 384 }, | |
82 { 0, 0, 320, 240 }, | |
83 { 0, 0, 320, 200 } | |
84 }; | |
91
e85e03f195b4
From: "Markus F.X.J. Oberhumer"
Sam Lantinga <slouken@lokigames.com>
parents:
6
diff
changeset
|
85 static const struct { |
0 | 86 int xres; |
87 int yres; | |
88 int pixclock; | |
89 int left; | |
90 int right; | |
91 int upper; | |
92 int lower; | |
93 int hslen; | |
94 int vslen; | |
95 int sync; | |
96 int vmode; | |
97 } vesa_timings[] = { | |
98 #ifdef USE_VESA_TIMINGS /* Only tested on Matrox Millenium I */ | |
99 { 640, 400, 39771, 48, 16, 39, 8, 96, 2, 2, 0 }, /* 70 Hz */ | |
100 { 640, 480, 39683, 48, 16, 33, 10, 96, 2, 0, 0 }, /* 60 Hz */ | |
101 { 768, 576, 26101, 144, 16, 28, 6, 112, 4, 0, 0 }, /* 60 Hz */ | |
102 { 800, 600, 24038, 144, 24, 28, 8, 112, 6, 0, 0 }, /* 60 Hz */ | |
103 { 960, 720, 17686, 144, 24, 28, 8, 112, 4, 0, 0 }, /* 60 Hz */ | |
104 { 1024, 768, 15386, 160, 32, 30, 4, 128, 4, 0, 0 }, /* 60 Hz */ | |
105 { 1152, 864, 12286, 192, 32, 30, 4, 128, 4, 0, 0 }, /* 60 Hz */ | |
106 { 1280, 1024, 9369, 224, 32, 32, 4, 136, 4, 0, 0 }, /* 60 Hz */ | |
107 { 1408, 1056, 8214, 256, 40, 32, 5, 144, 5, 0, 0 }, /* 60 Hz */ | |
108 { 1600, 1200,/*?*/0, 272, 48, 32, 5, 152, 5, 0, 0 }, /* 60 Hz */ | |
109 #else | |
110 /* You can generate these timings from your XF86Config file using | |
111 the 'modeline2fb' perl script included with the fbset package. | |
112 These timings were generated for Matrox Millenium I, 15" monitor. | |
113 */ | |
114 { 320, 200, 79440, 16, 16, 20, 4, 48, 1, 0, 2 }, /* 70 Hz */ | |
115 { 320, 240, 63492, 16, 16, 16, 4, 48, 2, 0, 2 }, /* 72 Hz */ | |
116 { 512, 384, 49603, 48, 16, 16, 1, 64, 3, 0, 0 }, /* 78 Hz */ | |
117 { 640, 400, 31746, 96, 32, 41, 1, 64, 3, 2, 0 }, /* 85 Hz */ | |
118 { 640, 480, 31746, 120, 16, 16, 1, 64, 3, 0, 0 }, /* 75 Hz */ | |
119 { 768, 576, 26101, 144, 16, 28, 6, 112, 4, 0, 0 }, /* 60 Hz */ | |
120 { 800, 600, 20000, 64, 56, 23, 37, 120, 6, 3, 0 }, /* 72 Hz */ | |
121 { 960, 720, 17686, 144, 24, 28, 8, 112, 4, 0, 0 }, /* 60 Hz */ | |
122 { 1024, 768, 13333, 144, 24, 29, 3, 136, 6, 0, 0 }, /* 70 Hz */ | |
123 { 1152, 864, 12286, 192, 32, 30, 4, 128, 4, 0, 0 }, /* 60 Hz */ | |
124 { 1280, 1024, 9369, 224, 32, 32, 4, 136, 4, 0, 0 }, /* 60 Hz */ | |
125 { 1408, 1056, 8214, 256, 40, 32, 5, 144, 5, 0, 0 }, /* 60 Hz */ | |
126 { 1600, 1200,/*?*/0, 272, 48, 32, 5, 152, 5, 0, 0 }, /* 60 Hz */ | |
127 #endif | |
128 }; | |
129 | |
130 /* Initialization/Query functions */ | |
131 static int FB_VideoInit(_THIS, SDL_PixelFormat *vformat); | |
132 static SDL_Rect **FB_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags); | |
133 static SDL_Surface *FB_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags); | |
134 #ifdef VGA16_FBCON_SUPPORT | |
135 static SDL_Surface *FB_SetVGA16Mode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags); | |
136 #endif | |
137 static int FB_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors); | |
138 static void FB_VideoQuit(_THIS); | |
139 | |
140 /* Hardware surface functions */ | |
106
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
141 static int FB_InitHWSurfaces(_THIS, SDL_Surface *screen, char *base, int size); |
0 | 142 static void FB_FreeHWSurfaces(_THIS); |
143 static int FB_AllocHWSurface(_THIS, SDL_Surface *surface); | |
144 static int FB_LockHWSurface(_THIS, SDL_Surface *surface); | |
145 static void FB_UnlockHWSurface(_THIS, SDL_Surface *surface); | |
146 static void FB_FreeHWSurface(_THIS, SDL_Surface *surface); | |
147 static void FB_WaitVBL(_THIS); | |
106
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
148 static void FB_WaitIdle(_THIS); |
0 | 149 static int FB_FlipHWSurface(_THIS, SDL_Surface *surface); |
150 | |
151 /* Internal palette functions */ | |
152 static void FB_SavePalette(_THIS, struct fb_fix_screeninfo *finfo, | |
153 struct fb_var_screeninfo *vinfo); | |
154 static void FB_RestorePalette(_THIS); | |
155 | |
156 /* FB driver bootstrap functions */ | |
157 | |
158 static int FB_Available(void) | |
159 { | |
160 int console; | |
161 const char *SDL_fbdev; | |
162 | |
163 SDL_fbdev = getenv("SDL_FBDEV"); | |
164 if ( SDL_fbdev == NULL ) { | |
165 SDL_fbdev = "/dev/fb0"; | |
166 } | |
167 console = open(SDL_fbdev, O_RDWR, 0); | |
168 if ( console >= 0 ) { | |
169 close(console); | |
170 } | |
171 return(console >= 0); | |
172 } | |
173 | |
174 static void FB_DeleteDevice(SDL_VideoDevice *device) | |
175 { | |
176 free(device->hidden); | |
177 free(device); | |
178 } | |
179 | |
180 static SDL_VideoDevice *FB_CreateDevice(int devindex) | |
181 { | |
182 SDL_VideoDevice *this; | |
183 | |
184 /* Initialize all variables that we clean on shutdown */ | |
185 this = (SDL_VideoDevice *)malloc(sizeof(SDL_VideoDevice)); | |
186 if ( this ) { | |
187 memset(this, 0, (sizeof *this)); | |
188 this->hidden = (struct SDL_PrivateVideoData *) | |
189 malloc((sizeof *this->hidden)); | |
190 } | |
191 if ( (this == NULL) || (this->hidden == NULL) ) { | |
192 SDL_OutOfMemory(); | |
193 if ( this ) { | |
194 free(this); | |
195 } | |
196 return(0); | |
197 } | |
198 memset(this->hidden, 0, (sizeof *this->hidden)); | |
199 wait_vbl = FB_WaitVBL; | |
106
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
200 wait_idle = FB_WaitIdle; |
0 | 201 mouse_fd = -1; |
202 keyboard_fd = -1; | |
203 | |
204 /* Set the function pointers */ | |
205 this->VideoInit = FB_VideoInit; | |
206 this->ListModes = FB_ListModes; | |
207 this->SetVideoMode = FB_SetVideoMode; | |
208 this->SetColors = FB_SetColors; | |
209 this->UpdateRects = NULL; | |
210 this->VideoQuit = FB_VideoQuit; | |
211 this->AllocHWSurface = FB_AllocHWSurface; | |
212 this->CheckHWBlit = NULL; | |
213 this->FillHWRect = NULL; | |
214 this->SetHWColorKey = NULL; | |
215 this->SetHWAlpha = NULL; | |
216 this->LockHWSurface = FB_LockHWSurface; | |
217 this->UnlockHWSurface = FB_UnlockHWSurface; | |
218 this->FlipHWSurface = FB_FlipHWSurface; | |
219 this->FreeHWSurface = FB_FreeHWSurface; | |
220 this->SetCaption = NULL; | |
221 this->SetIcon = NULL; | |
222 this->IconifyWindow = NULL; | |
223 this->GrabInput = NULL; | |
224 this->GetWMInfo = NULL; | |
225 this->InitOSKeymap = FB_InitOSKeymap; | |
226 this->PumpEvents = FB_PumpEvents; | |
227 | |
228 this->free = FB_DeleteDevice; | |
229 | |
230 return this; | |
231 } | |
232 | |
233 VideoBootStrap FBCON_bootstrap = { | |
234 "fbcon", "Linux Framebuffer Console", | |
235 FB_Available, FB_CreateDevice | |
236 }; | |
237 | |
1215
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
238 #define FB_MODES_DB "/etc/fb.modes" |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
239 |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
240 static int read_fbmodes_line(FILE*f, char* line, int length) |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
241 { |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
242 int blank; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
243 char* c; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
244 int i; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
245 |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
246 blank=0; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
247 /* find a relevant line */ |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
248 do |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
249 { |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
250 if (fgets(line,length,f)<=0) |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
251 return 0; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
252 c=line; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
253 while(((*c=='\t')||(*c==' '))&&(*c!=0)) |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
254 c++; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
255 |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
256 if ((*c=='\n')||(*c=='#')||(*c==0)) |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
257 blank=1; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
258 else |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
259 blank=0; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
260 } |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
261 while(blank); |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
262 /* remove whitespace at the begining of the string */ |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
263 i=0; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
264 do |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
265 { |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
266 line[i]=c[i]; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
267 i++; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
268 } |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
269 while(c[i]!=0); |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
270 return 1; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
271 } |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
272 |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
273 static int read_fbmodes_mode(FILE *f, struct fb_var_screeninfo *vinfo) |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
274 { |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
275 char line[1024]; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
276 char option[256]; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
277 |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
278 /* Find a "geometry" */ |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
279 do { |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
280 if (read_fbmodes_line(f, line, sizeof(line))==0) |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
281 return 0; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
282 if (strncmp(line,"geometry",8)==0) |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
283 break; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
284 } |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
285 while(1); |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
286 |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
287 sscanf(line, "geometry %d %d %d %d %d", &vinfo->xres, &vinfo->yres, |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
288 &vinfo->xres_virtual, &vinfo->yres_virtual, &vinfo->bits_per_pixel); |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
289 if (read_fbmodes_line(f, line, sizeof(line))==0) |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
290 return 0; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
291 |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
292 sscanf(line, "timings %d %d %d %d %d %d %d", &vinfo->pixclock, |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
293 &vinfo->left_margin, &vinfo->right_margin, &vinfo->upper_margin, |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
294 &vinfo->lower_margin, &vinfo->hsync_len, &vinfo->vsync_len); |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
295 |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
296 vinfo->sync=0; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
297 vinfo->vmode=FB_VMODE_NONINTERLACED; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
298 |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
299 /* Parse misc options */ |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
300 do { |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
301 if (read_fbmodes_line(f, line, sizeof(line))==0) |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
302 return 0; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
303 |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
304 if (strncmp(line,"hsync",5)==0) { |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
305 sscanf(line,"hsync %s",option); |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
306 if (strncmp(option,"high",4)==0) |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
307 vinfo->sync |= FB_SYNC_HOR_HIGH_ACT; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
308 } |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
309 else if (strncmp(line,"vsync",5)==0) { |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
310 sscanf(line,"vsync %s",option); |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
311 if (strncmp(option,"high",4)==0) |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
312 vinfo->sync |= FB_SYNC_VERT_HIGH_ACT; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
313 } |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
314 else if (strncmp(line,"csync",5)==0) { |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
315 sscanf(line,"csync %s",option); |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
316 if (strncmp(option,"high",4)==0) |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
317 vinfo->sync |= FB_SYNC_COMP_HIGH_ACT; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
318 } |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
319 else if (strncmp(line,"extsync",5)==0) { |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
320 sscanf(line,"extsync %s",option); |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
321 if (strncmp(option,"true",4)==0) |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
322 vinfo->sync |= FB_SYNC_EXT; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
323 } |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
324 else if (strncmp(line,"laced",5)==0) { |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
325 sscanf(line,"laced %s",option); |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
326 if (strncmp(option,"true",4)==0) |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
327 vinfo->vmode |= FB_VMODE_INTERLACED; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
328 } |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
329 else if (strncmp(line,"double",6)==0) { |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
330 sscanf(line,"double %s",option); |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
331 if (strncmp(option,"true",4)==0) |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
332 vinfo->vmode |= FB_VMODE_DOUBLE; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
333 } |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
334 } |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
335 while(strncmp(line,"endmode",7)!=0); |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
336 |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
337 return 1; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
338 } |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
339 |
0 | 340 static int FB_CheckMode(_THIS, struct fb_var_screeninfo *vinfo, |
341 int index, unsigned int *w, unsigned int *h) | |
342 { | |
343 int mode_okay; | |
344 | |
345 mode_okay = 0; | |
346 vinfo->bits_per_pixel = (index+1)*8; | |
347 vinfo->xres = *w; | |
348 vinfo->xres_virtual = *w; | |
349 vinfo->yres = *h; | |
350 vinfo->yres_virtual = *h; | |
351 vinfo->activate = FB_ACTIVATE_TEST; | |
352 if ( ioctl(console_fd, FBIOPUT_VSCREENINFO, vinfo) == 0 ) { | |
353 #ifdef FBCON_DEBUG | |
354 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); | |
355 #endif | |
356 if ( (((vinfo->bits_per_pixel+7)/8)-1) == index ) { | |
357 *w = vinfo->xres; | |
358 *h = vinfo->yres; | |
359 mode_okay = 1; | |
360 } | |
361 } | |
362 return mode_okay; | |
363 } | |
364 | |
1215
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
365 static int FB_AddMode(_THIS, int index, unsigned int w, unsigned int h, int check_timings) |
0 | 366 { |
367 SDL_Rect *mode; | |
368 int i; | |
369 int next_mode; | |
370 | |
371 /* Check to see if we already have this mode */ | |
372 if ( SDL_nummodes[index] > 0 ) { | |
373 mode = SDL_modelist[index][SDL_nummodes[index]-1]; | |
374 if ( (mode->w == w) && (mode->h == h) ) { | |
375 #ifdef FBCON_DEBUG | |
376 fprintf(stderr, "We already have mode %dx%d at %d bytes per pixel\n", w, h, index+1); | |
377 #endif | |
378 return(0); | |
379 } | |
380 } | |
381 | |
382 /* Only allow a mode if we have a valid timing for it */ | |
1215
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
383 if ( check_timings ) { |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
384 int found_timing = 0; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
385 for ( i=0; i<(sizeof(vesa_timings)/sizeof(vesa_timings[0])); ++i ) { |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
386 if ( (w == vesa_timings[i].xres) && |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
387 (h == vesa_timings[i].yres) && vesa_timings[i].pixclock ) { |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
388 found_timing = 1; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
389 break; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
390 } |
0 | 391 } |
1215
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
392 if ( !found_timing ) { |
0 | 393 #ifdef FBCON_DEBUG |
1215
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
394 fprintf(stderr, "No valid timing line for mode %dx%d\n", w, h); |
0 | 395 #endif |
1215
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
396 return(0); |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
397 } |
0 | 398 } |
399 | |
400 /* Set up the new video mode rectangle */ | |
401 mode = (SDL_Rect *)malloc(sizeof *mode); | |
402 if ( mode == NULL ) { | |
403 SDL_OutOfMemory(); | |
404 return(-1); | |
405 } | |
406 mode->x = 0; | |
407 mode->y = 0; | |
408 mode->w = w; | |
409 mode->h = h; | |
410 #ifdef FBCON_DEBUG | |
411 fprintf(stderr, "Adding mode %dx%d at %d bytes per pixel\n", w, h, index+1); | |
412 #endif | |
413 | |
414 /* Allocate the new list of modes, and fill in the new mode */ | |
415 next_mode = SDL_nummodes[index]; | |
416 SDL_modelist[index] = (SDL_Rect **) | |
417 realloc(SDL_modelist[index], (1+next_mode+1)*sizeof(SDL_Rect *)); | |
418 if ( SDL_modelist[index] == NULL ) { | |
419 SDL_OutOfMemory(); | |
420 SDL_nummodes[index] = 0; | |
421 free(mode); | |
422 return(-1); | |
423 } | |
424 SDL_modelist[index][next_mode] = mode; | |
425 SDL_modelist[index][next_mode+1] = NULL; | |
426 SDL_nummodes[index]++; | |
427 | |
428 return(0); | |
429 } | |
430 | |
1215
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
431 static int cmpmodes(const void *va, const void *vb) |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
432 { |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
433 const SDL_Rect *a = *(const SDL_Rect**)va; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
434 const SDL_Rect *b = *(const SDL_Rect**)vb; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
435 if ( a->h == b->h ) |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
436 return b->w - a->w; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
437 else |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
438 return b->h - a->h; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
439 } |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
440 |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
441 static int FB_SortModes(_THIS) |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
442 { |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
443 int i; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
444 for ( i=0; i<NUM_MODELISTS; ++i ) { |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
445 if ( SDL_nummodes[i] > 0 ) { |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
446 qsort(SDL_modelist[i], SDL_nummodes[i], sizeof *SDL_modelist[i], cmpmodes); |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
447 } |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
448 } |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
449 } |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
450 |
0 | 451 static int FB_VideoInit(_THIS, SDL_PixelFormat *vformat) |
452 { | |
453 struct fb_fix_screeninfo finfo; | |
454 struct fb_var_screeninfo vinfo; | |
455 int i, j; | |
456 int current_index; | |
457 unsigned int current_w; | |
458 unsigned int current_h; | |
459 const char *SDL_fbdev; | |
1215
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
460 FILE *modesdb; |
0 | 461 |
462 /* Initialize the library */ | |
463 SDL_fbdev = getenv("SDL_FBDEV"); | |
464 if ( SDL_fbdev == NULL ) { | |
465 SDL_fbdev = "/dev/fb0"; | |
466 } | |
467 console_fd = open(SDL_fbdev, O_RDWR, 0); | |
468 if ( console_fd < 0 ) { | |
469 SDL_SetError("Unable to open %s", SDL_fbdev); | |
470 return(-1); | |
471 } | |
472 | |
473 #ifndef DISABLE_THREADS | |
474 /* Create the hardware surface lock mutex */ | |
475 hw_lock = SDL_CreateMutex(); | |
476 if ( hw_lock == NULL ) { | |
477 SDL_SetError("Unable to create lock mutex"); | |
478 FB_VideoQuit(this); | |
479 return(-1); | |
480 } | |
481 #endif | |
482 | |
483 /* Get the type of video hardware */ | |
484 if ( ioctl(console_fd, FBIOGET_FSCREENINFO, &finfo) < 0 ) { | |
485 SDL_SetError("Couldn't get console hardware info"); | |
486 FB_VideoQuit(this); | |
487 return(-1); | |
488 } | |
489 switch (finfo.type) { | |
490 case FB_TYPE_PACKED_PIXELS: | |
491 /* Supported, no worries.. */ | |
492 break; | |
493 #ifdef VGA16_FBCON_SUPPORT | |
494 case FB_TYPE_VGA_PLANES: | |
495 /* VGA16 is supported, but that's it */ | |
496 if ( finfo.type_aux == FB_AUX_VGA_PLANES_VGA4 ) { | |
497 if ( ioperm(0x3b4, 0x3df - 0x3b4 + 1, 1) < 0 ) { | |
498 SDL_SetError("No I/O port permissions"); | |
499 FB_VideoQuit(this); | |
500 return(-1); | |
501 } | |
502 this->SetVideoMode = FB_SetVGA16Mode; | |
503 break; | |
504 } | |
505 /* Fall through to unsupported case */ | |
506 #endif /* VGA16_FBCON_SUPPORT */ | |
507 default: | |
508 SDL_SetError("Unsupported console hardware"); | |
509 FB_VideoQuit(this); | |
510 return(-1); | |
511 } | |
512 switch (finfo.visual) { | |
513 case FB_VISUAL_TRUECOLOR: | |
514 case FB_VISUAL_PSEUDOCOLOR: | |
515 case FB_VISUAL_STATIC_PSEUDOCOLOR: | |
516 case FB_VISUAL_DIRECTCOLOR: | |
517 break; | |
518 default: | |
519 SDL_SetError("Unsupported console hardware"); | |
520 FB_VideoQuit(this); | |
521 return(-1); | |
522 } | |
523 | |
524 /* Check if the user wants to disable hardware acceleration */ | |
525 { const char *fb_accel; | |
526 fb_accel = getenv("SDL_FBACCEL"); | |
527 if ( fb_accel ) { | |
528 finfo.accel = atoi(fb_accel); | |
529 } | |
530 } | |
531 | |
532 /* Memory map the device, compensating for buggy PPC mmap() */ | |
533 mapped_offset = (((long)finfo.smem_start) - | |
534 (((long)finfo.smem_start)&~(PAGE_SIZE-1))); | |
535 mapped_memlen = finfo.smem_len+mapped_offset; | |
536 mapped_mem = mmap(NULL, mapped_memlen, | |
537 PROT_READ|PROT_WRITE, MAP_SHARED, console_fd, 0); | |
538 if ( mapped_mem == (char *)-1 ) { | |
539 SDL_SetError("Unable to memory map the video hardware"); | |
540 mapped_mem = NULL; | |
541 FB_VideoQuit(this); | |
542 return(-1); | |
543 } | |
544 | |
545 /* Determine the current screen depth */ | |
546 if ( ioctl(console_fd, FBIOGET_VSCREENINFO, &vinfo) < 0 ) { | |
547 SDL_SetError("Couldn't get console pixel format"); | |
548 FB_VideoQuit(this); | |
549 return(-1); | |
550 } | |
551 vformat->BitsPerPixel = vinfo.bits_per_pixel; | |
552 if ( vformat->BitsPerPixel < 8 ) { | |
553 /* Assuming VGA16, we handle this via a shadow framebuffer */ | |
554 vformat->BitsPerPixel = 8; | |
555 } | |
556 for ( i=0; i<vinfo.red.length; ++i ) { | |
557 vformat->Rmask <<= 1; | |
558 vformat->Rmask |= (0x00000001<<vinfo.red.offset); | |
559 } | |
560 for ( i=0; i<vinfo.green.length; ++i ) { | |
561 vformat->Gmask <<= 1; | |
562 vformat->Gmask |= (0x00000001<<vinfo.green.offset); | |
563 } | |
564 for ( i=0; i<vinfo.blue.length; ++i ) { | |
565 vformat->Bmask <<= 1; | |
566 vformat->Bmask |= (0x00000001<<vinfo.blue.offset); | |
567 } | |
568 saved_vinfo = vinfo; | |
569 | |
570 /* Save hardware palette, if needed */ | |
571 FB_SavePalette(this, &finfo, &vinfo); | |
572 | |
573 /* If the I/O registers are available, memory map them so we | |
574 can take advantage of any supported hardware acceleration. | |
575 */ | |
576 vinfo.accel_flags = 0; /* Temporarily reserve registers */ | |
577 ioctl(console_fd, FBIOPUT_VSCREENINFO, &vinfo); | |
578 if ( finfo.accel && finfo.mmio_len ) { | |
579 mapped_iolen = finfo.mmio_len; | |
580 mapped_io = mmap(NULL, mapped_iolen, PROT_READ|PROT_WRITE, | |
581 MAP_SHARED, console_fd, mapped_memlen); | |
582 if ( mapped_io == (char *)-1 ) { | |
583 /* Hmm, failed to memory map I/O registers */ | |
584 mapped_io = NULL; | |
585 } | |
586 } | |
587 | |
588 /* Query for the list of available video modes */ | |
589 current_w = vinfo.xres; | |
590 current_h = vinfo.yres; | |
591 current_index = ((vinfo.bits_per_pixel+7)/8)-1; | |
1215
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
592 modesdb = fopen(FB_MODES_DB, "r"); |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
593 for ( i=0; i<NUM_MODELISTS; ++i ) { |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
594 SDL_nummodes[i] = 0; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
595 SDL_modelist[i] = NULL; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
596 } |
941
5095c4a264aa
Date: Mon, 12 Jul 2004 14:17:47 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
597 if ( getenv("SDL_FB_BROKEN_MODES") != NULL ) { |
1215
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
598 FB_AddMode(this, current_index, current_w, current_h, 0); |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
599 } else if(modesdb) { |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
600 while ( read_fbmodes_mode(modesdb, &vinfo) ) { |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
601 for ( i=0; i<NUM_MODELISTS; ++i ) { |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
602 unsigned int w, h; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
603 |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
604 /* See if we are querying for the current mode */ |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
605 w = vinfo.xres; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
606 h = vinfo.yres; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
607 if ( i == current_index ) { |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
608 if ( (current_w > w) || (current_h > h) ) { |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
609 /* Only check once */ |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
610 FB_AddMode(this, i, current_w, current_h, 0); |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
611 current_index = -1; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
612 } |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
613 } |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
614 if ( FB_CheckMode(this, &vinfo, i, &w, &h) ) { |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
615 FB_AddMode(this, i, w, h, 0); |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
616 } |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
617 } |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
618 } |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
619 fclose(modesdb); |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
620 FB_SortModes(this); |
941
5095c4a264aa
Date: Mon, 12 Jul 2004 14:17:47 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
621 } else { |
5095c4a264aa
Date: Mon, 12 Jul 2004 14:17:47 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
622 for ( i=0; i<NUM_MODELISTS; ++i ) { |
5095c4a264aa
Date: Mon, 12 Jul 2004 14:17:47 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
623 for ( j=0; j<(sizeof(checkres)/sizeof(checkres[0])); ++j ) { |
5095c4a264aa
Date: Mon, 12 Jul 2004 14:17:47 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
624 unsigned int w, h; |
0 | 625 |
941
5095c4a264aa
Date: Mon, 12 Jul 2004 14:17:47 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
626 /* See if we are querying for the current mode */ |
5095c4a264aa
Date: Mon, 12 Jul 2004 14:17:47 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
627 w = checkres[j].w; |
5095c4a264aa
Date: Mon, 12 Jul 2004 14:17:47 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
628 h = checkres[j].h; |
5095c4a264aa
Date: Mon, 12 Jul 2004 14:17:47 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
629 if ( i == current_index ) { |
5095c4a264aa
Date: Mon, 12 Jul 2004 14:17:47 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
630 if ( (current_w > w) || (current_h > h) ) { |
5095c4a264aa
Date: Mon, 12 Jul 2004 14:17:47 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
631 /* Only check once */ |
1215
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
632 FB_AddMode(this, i, current_w, current_h, 0); |
941
5095c4a264aa
Date: Mon, 12 Jul 2004 14:17:47 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
633 current_index = -1; |
5095c4a264aa
Date: Mon, 12 Jul 2004 14:17:47 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
634 } |
0 | 635 } |
941
5095c4a264aa
Date: Mon, 12 Jul 2004 14:17:47 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
636 if ( FB_CheckMode(this, &vinfo, i, &w, &h) ) { |
1215
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
637 FB_AddMode(this, i, w, h, 1); |
941
5095c4a264aa
Date: Mon, 12 Jul 2004 14:17:47 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
638 } |
0 | 639 } |
640 } | |
641 } | |
642 | |
643 /* Fill in our hardware acceleration capabilities */ | |
644 this->info.wm_available = 0; | |
645 this->info.hw_available = 1; | |
646 this->info.video_mem = finfo.smem_len/1024; | |
647 if ( mapped_io ) { | |
648 switch (finfo.accel) { | |
649 case FB_ACCEL_MATROX_MGA2064W: | |
650 case FB_ACCEL_MATROX_MGA1064SG: | |
651 case FB_ACCEL_MATROX_MGA2164W: | |
652 case FB_ACCEL_MATROX_MGA2164W_AGP: | |
653 case FB_ACCEL_MATROX_MGAG100: | |
654 /*case FB_ACCEL_MATROX_MGAG200: G200 acceleration broken! */ | |
655 case FB_ACCEL_MATROX_MGAG400: | |
656 #ifdef FBACCEL_DEBUG | |
657 printf("Matrox hardware accelerator!\n"); | |
658 #endif | |
659 FB_MatroxAccel(this, finfo.accel); | |
660 break; | |
661 case FB_ACCEL_3DFX_BANSHEE: | |
662 #ifdef FBACCEL_DEBUG | |
663 printf("3DFX hardware accelerator!\n"); | |
664 #endif | |
665 FB_3DfxAccel(this, finfo.accel); | |
666 break; | |
133
5d4bafca35cd
Added support for hardware accelerated NVidia driver on framebuffer console
Sam Lantinga <slouken@libsdl.org>
parents:
106
diff
changeset
|
667 case FB_ACCEL_NV3: |
5d4bafca35cd
Added support for hardware accelerated NVidia driver on framebuffer console
Sam Lantinga <slouken@libsdl.org>
parents:
106
diff
changeset
|
668 case FB_ACCEL_NV4: |
5d4bafca35cd
Added support for hardware accelerated NVidia driver on framebuffer console
Sam Lantinga <slouken@libsdl.org>
parents:
106
diff
changeset
|
669 #ifdef FBACCEL_DEBUG |
5d4bafca35cd
Added support for hardware accelerated NVidia driver on framebuffer console
Sam Lantinga <slouken@libsdl.org>
parents:
106
diff
changeset
|
670 printf("NVidia hardware accelerator!\n"); |
5d4bafca35cd
Added support for hardware accelerated NVidia driver on framebuffer console
Sam Lantinga <slouken@libsdl.org>
parents:
106
diff
changeset
|
671 #endif |
5d4bafca35cd
Added support for hardware accelerated NVidia driver on framebuffer console
Sam Lantinga <slouken@libsdl.org>
parents:
106
diff
changeset
|
672 FB_RivaAccel(this, finfo.accel); |
5d4bafca35cd
Added support for hardware accelerated NVidia driver on framebuffer console
Sam Lantinga <slouken@libsdl.org>
parents:
106
diff
changeset
|
673 break; |
0 | 674 default: |
675 #ifdef FBACCEL_DEBUG | |
676 printf("Unknown hardware accelerator.\n"); | |
677 #endif | |
678 break; | |
679 } | |
680 } | |
681 | |
682 /* Enable mouse and keyboard support */ | |
683 if ( FB_OpenKeyboard(this) < 0 ) { | |
684 FB_VideoQuit(this); | |
685 return(-1); | |
686 } | |
687 if ( FB_OpenMouse(this) < 0 ) { | |
688 const char *sdl_nomouse; | |
689 | |
690 sdl_nomouse = getenv("SDL_NOMOUSE"); | |
691 if ( ! sdl_nomouse ) { | |
692 SDL_SetError("Unable to open mouse"); | |
693 FB_VideoQuit(this); | |
694 return(-1); | |
695 } | |
696 } | |
697 | |
698 /* We're done! */ | |
699 return(0); | |
700 } | |
701 | |
702 static SDL_Rect **FB_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags) | |
703 { | |
704 return(SDL_modelist[((format->BitsPerPixel+7)/8)-1]); | |
705 } | |
706 | |
707 /* Various screen update functions available */ | |
708 static void FB_DirectUpdate(_THIS, int numrects, SDL_Rect *rects); | |
709 #ifdef VGA16_FBCON_SUPPORT | |
710 static void FB_VGA16Update(_THIS, int numrects, SDL_Rect *rects); | |
711 #endif | |
712 | |
713 #ifdef FBCON_DEBUG | |
714 static void print_vinfo(struct fb_var_screeninfo *vinfo) | |
715 { | |
716 fprintf(stderr, "Printing vinfo:\n"); | |
717 fprintf(stderr, "\txres: %d\n", vinfo->xres); | |
718 fprintf(stderr, "\tyres: %d\n", vinfo->yres); | |
719 fprintf(stderr, "\txres_virtual: %d\n", vinfo->xres_virtual); | |
720 fprintf(stderr, "\tyres_virtual: %d\n", vinfo->yres_virtual); | |
721 fprintf(stderr, "\txoffset: %d\n", vinfo->xoffset); | |
722 fprintf(stderr, "\tyoffset: %d\n", vinfo->yoffset); | |
723 fprintf(stderr, "\tbits_per_pixel: %d\n", vinfo->bits_per_pixel); | |
724 fprintf(stderr, "\tgrayscale: %d\n", vinfo->grayscale); | |
725 fprintf(stderr, "\tnonstd: %d\n", vinfo->nonstd); | |
726 fprintf(stderr, "\tactivate: %d\n", vinfo->activate); | |
727 fprintf(stderr, "\theight: %d\n", vinfo->height); | |
728 fprintf(stderr, "\twidth: %d\n", vinfo->width); | |
729 fprintf(stderr, "\taccel_flags: %d\n", vinfo->accel_flags); | |
730 fprintf(stderr, "\tpixclock: %d\n", vinfo->pixclock); | |
731 fprintf(stderr, "\tleft_margin: %d\n", vinfo->left_margin); | |
732 fprintf(stderr, "\tright_margin: %d\n", vinfo->right_margin); | |
733 fprintf(stderr, "\tupper_margin: %d\n", vinfo->upper_margin); | |
734 fprintf(stderr, "\tlower_margin: %d\n", vinfo->lower_margin); | |
735 fprintf(stderr, "\thsync_len: %d\n", vinfo->hsync_len); | |
736 fprintf(stderr, "\tvsync_len: %d\n", vinfo->vsync_len); | |
737 fprintf(stderr, "\tsync: %d\n", vinfo->sync); | |
738 fprintf(stderr, "\tvmode: %d\n", vinfo->vmode); | |
739 fprintf(stderr, "\tred: %d/%d\n", vinfo->red.length, vinfo->red.offset); | |
740 fprintf(stderr, "\tgreen: %d/%d\n", vinfo->green.length, vinfo->green.offset); | |
741 fprintf(stderr, "\tblue: %d/%d\n", vinfo->blue.length, vinfo->blue.offset); | |
742 fprintf(stderr, "\talpha: %d/%d\n", vinfo->transp.length, vinfo->transp.offset); | |
743 } | |
744 static void print_finfo(struct fb_fix_screeninfo *finfo) | |
745 { | |
746 fprintf(stderr, "Printing finfo:\n"); | |
747 fprintf(stderr, "\tsmem_start = %p\n", (char *)finfo->smem_start); | |
748 fprintf(stderr, "\tsmem_len = %d\n", finfo->smem_len); | |
749 fprintf(stderr, "\ttype = %d\n", finfo->type); | |
750 fprintf(stderr, "\ttype_aux = %d\n", finfo->type_aux); | |
751 fprintf(stderr, "\tvisual = %d\n", finfo->visual); | |
752 fprintf(stderr, "\txpanstep = %d\n", finfo->xpanstep); | |
753 fprintf(stderr, "\typanstep = %d\n", finfo->ypanstep); | |
754 fprintf(stderr, "\tywrapstep = %d\n", finfo->ywrapstep); | |
755 fprintf(stderr, "\tline_length = %d\n", finfo->line_length); | |
756 fprintf(stderr, "\tmmio_start = %p\n", (char *)finfo->mmio_start); | |
757 fprintf(stderr, "\tmmio_len = %d\n", finfo->mmio_len); | |
758 fprintf(stderr, "\taccel = %d\n", finfo->accel); | |
759 } | |
760 #endif | |
761 | |
762 static int choose_fbmodes_mode(struct fb_var_screeninfo *vinfo) | |
763 { | |
764 int matched; | |
1215
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
765 FILE *modesdb; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
766 struct fb_var_screeninfo cinfo; |
0 | 767 |
768 matched = 0; | |
1215
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
769 modesdb = fopen(FB_MODES_DB, "r"); |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
770 if ( modesdb ) { |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
771 /* Parse the mode definition file */ |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
772 while ( read_fbmodes_mode(modesdb, &cinfo) ) { |
1217
ae9981987c2f
Oops, actually use the timings in the modes db. :)
Sam Lantinga <slouken@libsdl.org>
parents:
1215
diff
changeset
|
773 if ( (vinfo->xres == cinfo.xres && vinfo->yres == cinfo.yres) && |
ae9981987c2f
Oops, actually use the timings in the modes db. :)
Sam Lantinga <slouken@libsdl.org>
parents:
1215
diff
changeset
|
774 (!matched || (vinfo->bits_per_pixel == cinfo.bits_per_pixel)) ) { |
ae9981987c2f
Oops, actually use the timings in the modes db. :)
Sam Lantinga <slouken@libsdl.org>
parents:
1215
diff
changeset
|
775 vinfo->pixclock = cinfo.pixclock; |
ae9981987c2f
Oops, actually use the timings in the modes db. :)
Sam Lantinga <slouken@libsdl.org>
parents:
1215
diff
changeset
|
776 vinfo->left_margin = cinfo.left_margin; |
ae9981987c2f
Oops, actually use the timings in the modes db. :)
Sam Lantinga <slouken@libsdl.org>
parents:
1215
diff
changeset
|
777 vinfo->right_margin = cinfo.right_margin; |
ae9981987c2f
Oops, actually use the timings in the modes db. :)
Sam Lantinga <slouken@libsdl.org>
parents:
1215
diff
changeset
|
778 vinfo->upper_margin = cinfo.upper_margin; |
ae9981987c2f
Oops, actually use the timings in the modes db. :)
Sam Lantinga <slouken@libsdl.org>
parents:
1215
diff
changeset
|
779 vinfo->lower_margin = cinfo.lower_margin; |
ae9981987c2f
Oops, actually use the timings in the modes db. :)
Sam Lantinga <slouken@libsdl.org>
parents:
1215
diff
changeset
|
780 vinfo->hsync_len = cinfo.hsync_len; |
ae9981987c2f
Oops, actually use the timings in the modes db. :)
Sam Lantinga <slouken@libsdl.org>
parents:
1215
diff
changeset
|
781 vinfo->vsync_len = cinfo.vsync_len; |
ae9981987c2f
Oops, actually use the timings in the modes db. :)
Sam Lantinga <slouken@libsdl.org>
parents:
1215
diff
changeset
|
782 if ( matched ) { |
ae9981987c2f
Oops, actually use the timings in the modes db. :)
Sam Lantinga <slouken@libsdl.org>
parents:
1215
diff
changeset
|
783 break; |
ae9981987c2f
Oops, actually use the timings in the modes db. :)
Sam Lantinga <slouken@libsdl.org>
parents:
1215
diff
changeset
|
784 } |
1215
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
785 matched = 1; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
786 } |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
787 } |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
788 fclose(modesdb); |
0 | 789 } |
790 return(matched); | |
791 } | |
792 | |
793 static int choose_vesa_mode(struct fb_var_screeninfo *vinfo) | |
794 { | |
795 int matched; | |
796 int i; | |
797 | |
798 /* Check for VESA timings */ | |
799 matched = 0; | |
800 for ( i=0; i<(sizeof(vesa_timings)/sizeof(vesa_timings[0])); ++i ) { | |
801 if ( (vinfo->xres == vesa_timings[i].xres) && | |
802 (vinfo->yres == vesa_timings[i].yres) ) { | |
803 #ifdef FBCON_DEBUG | |
804 fprintf(stderr, "Using VESA timings for %dx%d\n", | |
805 vinfo->xres, vinfo->yres); | |
806 #endif | |
807 if ( vesa_timings[i].pixclock ) { | |
808 vinfo->pixclock = vesa_timings[i].pixclock; | |
809 } | |
810 vinfo->left_margin = vesa_timings[i].left; | |
811 vinfo->right_margin = vesa_timings[i].right; | |
812 vinfo->upper_margin = vesa_timings[i].upper; | |
813 vinfo->lower_margin = vesa_timings[i].lower; | |
814 vinfo->hsync_len = vesa_timings[i].hslen; | |
815 vinfo->vsync_len = vesa_timings[i].vslen; | |
816 vinfo->sync = vesa_timings[i].sync; | |
817 vinfo->vmode = vesa_timings[i].vmode; | |
818 matched = 1; | |
819 break; | |
820 } | |
821 } | |
822 return(matched); | |
823 } | |
824 | |
825 #ifdef VGA16_FBCON_SUPPORT | |
826 static SDL_Surface *FB_SetVGA16Mode(_THIS, SDL_Surface *current, | |
827 int width, int height, int bpp, Uint32 flags) | |
828 { | |
829 struct fb_fix_screeninfo finfo; | |
830 struct fb_var_screeninfo vinfo; | |
831 | |
832 /* Set the terminal into graphics mode */ | |
833 if ( FB_EnterGraphicsMode(this) < 0 ) { | |
834 return(NULL); | |
835 } | |
836 | |
837 /* Restore the original palette */ | |
838 FB_RestorePalette(this); | |
839 | |
840 /* Set the video mode and get the final screen format */ | |
841 if ( ioctl(console_fd, FBIOGET_VSCREENINFO, &vinfo) < 0 ) { | |
842 SDL_SetError("Couldn't get console screen info"); | |
843 return(NULL); | |
844 } | |
845 cache_vinfo = vinfo; | |
846 #ifdef FBCON_DEBUG | |
847 fprintf(stderr, "Printing actual vinfo:\n"); | |
848 print_vinfo(&vinfo); | |
849 #endif | |
850 if ( ! SDL_ReallocFormat(current, bpp, 0, 0, 0, 0) ) { | |
851 return(NULL); | |
852 } | |
106
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
853 current->format->palette->ncolors = 16; |
0 | 854 |
855 /* Get the fixed information about the console hardware. | |
856 This is necessary since finfo.line_length changes. | |
857 */ | |
858 if ( ioctl(console_fd, FBIOGET_FSCREENINFO, &finfo) < 0 ) { | |
859 SDL_SetError("Couldn't get console hardware info"); | |
860 return(NULL); | |
861 } | |
862 #ifdef FBCON_DEBUG | |
863 fprintf(stderr, "Printing actual finfo:\n"); | |
864 print_finfo(&finfo); | |
865 #endif | |
866 | |
867 /* Save hardware palette, if needed */ | |
868 FB_SavePalette(this, &finfo, &vinfo); | |
869 | |
870 /* Set up the new mode framebuffer */ | |
871 current->flags = SDL_FULLSCREEN; | |
872 current->w = vinfo.xres; | |
873 current->h = vinfo.yres; | |
874 current->pitch = current->w; | |
875 current->pixels = malloc(current->h*current->pitch); | |
876 | |
877 /* Set the update rectangle function */ | |
878 this->UpdateRects = FB_VGA16Update; | |
879 | |
880 /* We're done */ | |
881 return(current); | |
882 } | |
883 #endif /* VGA16_FBCON_SUPPORT */ | |
884 | |
885 static SDL_Surface *FB_SetVideoMode(_THIS, SDL_Surface *current, | |
886 int width, int height, int bpp, Uint32 flags) | |
887 { | |
888 struct fb_fix_screeninfo finfo; | |
889 struct fb_var_screeninfo vinfo; | |
890 int i; | |
891 Uint32 Rmask; | |
892 Uint32 Gmask; | |
893 Uint32 Bmask; | |
894 char *surfaces_mem; | |
895 int surfaces_len; | |
896 | |
897 /* Set the terminal into graphics mode */ | |
898 if ( FB_EnterGraphicsMode(this) < 0 ) { | |
899 return(NULL); | |
900 } | |
901 | |
902 /* Restore the original palette */ | |
903 FB_RestorePalette(this); | |
904 | |
905 /* Set the video mode and get the final screen format */ | |
906 if ( ioctl(console_fd, FBIOGET_VSCREENINFO, &vinfo) < 0 ) { | |
907 SDL_SetError("Couldn't get console screen info"); | |
908 return(NULL); | |
909 } | |
910 #ifdef FBCON_DEBUG | |
911 fprintf(stderr, "Printing original vinfo:\n"); | |
912 print_vinfo(&vinfo); | |
913 #endif | |
914 if ( (vinfo.xres != width) || (vinfo.yres != height) || | |
915 (vinfo.bits_per_pixel != bpp) || (flags & SDL_DOUBLEBUF) ) { | |
916 vinfo.activate = FB_ACTIVATE_NOW; | |
917 vinfo.accel_flags = 0; | |
918 vinfo.bits_per_pixel = bpp; | |
919 vinfo.xres = width; | |
920 vinfo.xres_virtual = width; | |
921 vinfo.yres = height; | |
922 if ( flags & SDL_DOUBLEBUF ) { | |
923 vinfo.yres_virtual = height*2; | |
924 } else { | |
925 vinfo.yres_virtual = height; | |
926 } | |
927 vinfo.xoffset = 0; | |
928 vinfo.yoffset = 0; | |
929 vinfo.red.length = vinfo.red.offset = 0; | |
930 vinfo.green.length = vinfo.green.offset = 0; | |
931 vinfo.blue.length = vinfo.blue.offset = 0; | |
932 vinfo.transp.length = vinfo.transp.offset = 0; | |
933 if ( ! choose_fbmodes_mode(&vinfo) ) { | |
934 choose_vesa_mode(&vinfo); | |
935 } | |
936 #ifdef FBCON_DEBUG | |
937 fprintf(stderr, "Printing wanted vinfo:\n"); | |
938 print_vinfo(&vinfo); | |
939 #endif | |
940 if ( ioctl(console_fd, FBIOPUT_VSCREENINFO, &vinfo) < 0 ) { | |
941 vinfo.yres_virtual = height; | |
942 if ( ioctl(console_fd, FBIOPUT_VSCREENINFO, &vinfo) < 0 ) { | |
943 SDL_SetError("Couldn't set console screen info"); | |
944 return(NULL); | |
945 } | |
946 } | |
106
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
947 } else { |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
948 int maxheight; |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
949 |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
950 /* Figure out how much video memory is available */ |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
951 if ( flags & SDL_DOUBLEBUF ) { |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
952 maxheight = height*2; |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
953 } else { |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
954 maxheight = height; |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
955 } |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
956 if ( vinfo.yres_virtual > maxheight ) { |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
957 vinfo.yres_virtual = maxheight; |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
958 } |
0 | 959 } |
960 cache_vinfo = vinfo; | |
961 #ifdef FBCON_DEBUG | |
962 fprintf(stderr, "Printing actual vinfo:\n"); | |
963 print_vinfo(&vinfo); | |
964 #endif | |
965 Rmask = 0; | |
966 for ( i=0; i<vinfo.red.length; ++i ) { | |
967 Rmask <<= 1; | |
968 Rmask |= (0x00000001<<vinfo.red.offset); | |
969 } | |
970 Gmask = 0; | |
971 for ( i=0; i<vinfo.green.length; ++i ) { | |
972 Gmask <<= 1; | |
973 Gmask |= (0x00000001<<vinfo.green.offset); | |
974 } | |
975 Bmask = 0; | |
976 for ( i=0; i<vinfo.blue.length; ++i ) { | |
977 Bmask <<= 1; | |
978 Bmask |= (0x00000001<<vinfo.blue.offset); | |
979 } | |
980 if ( ! SDL_ReallocFormat(current, vinfo.bits_per_pixel, | |
981 Rmask, Gmask, Bmask, 0) ) { | |
982 return(NULL); | |
983 } | |
984 | |
985 /* Get the fixed information about the console hardware. | |
986 This is necessary since finfo.line_length changes. | |
987 */ | |
988 if ( ioctl(console_fd, FBIOGET_FSCREENINFO, &finfo) < 0 ) { | |
989 SDL_SetError("Couldn't get console hardware info"); | |
990 return(NULL); | |
991 } | |
992 | |
993 /* Save hardware palette, if needed */ | |
994 FB_SavePalette(this, &finfo, &vinfo); | |
995 | |
996 /* Set up the new mode framebuffer */ | |
997 current->flags = (SDL_FULLSCREEN|SDL_HWSURFACE); | |
998 current->w = vinfo.xres; | |
999 current->h = vinfo.yres; | |
1000 current->pitch = finfo.line_length; | |
1001 current->pixels = mapped_mem+mapped_offset; | |
1002 | |
106
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1003 /* Set up the information for hardware surfaces */ |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1004 surfaces_mem = (char *)current->pixels + |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1005 vinfo.yres_virtual*current->pitch; |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1006 surfaces_len = (mapped_memlen-(surfaces_mem-mapped_mem)); |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1007 FB_FreeHWSurfaces(this); |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1008 FB_InitHWSurfaces(this, current, surfaces_mem, surfaces_len); |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1009 |
0 | 1010 /* Let the application know we have a hardware palette */ |
1011 switch (finfo.visual) { | |
1012 case FB_VISUAL_PSEUDOCOLOR: | |
1013 current->flags |= SDL_HWPALETTE; | |
1014 break; | |
1015 default: | |
1016 break; | |
1017 } | |
1018 | |
1019 /* Update for double-buffering, if we can */ | |
1020 if ( flags & SDL_DOUBLEBUF ) { | |
1021 if ( vinfo.yres_virtual == (height*2) ) { | |
1022 current->flags |= SDL_DOUBLEBUF; | |
1023 flip_page = 0; | |
1024 flip_address[0] = (char *)current->pixels; | |
1025 flip_address[1] = (char *)current->pixels+ | |
1026 current->h*current->pitch; | |
106
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1027 this->screen = current; |
0 | 1028 FB_FlipHWSurface(this, current); |
106
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1029 this->screen = NULL; |
0 | 1030 } |
1031 } | |
1032 | |
1033 /* Set the update rectangle function */ | |
1034 this->UpdateRects = FB_DirectUpdate; | |
1035 | |
1036 /* We're done */ | |
1037 return(current); | |
1038 } | |
1039 | |
1040 #ifdef FBCON_DEBUG | |
1041 void FB_DumpHWSurfaces(_THIS) | |
1042 { | |
1043 vidmem_bucket *bucket; | |
1044 | |
1045 printf("Memory left: %d (%d total)\n", surfaces_memleft, surfaces_memtotal); | |
1046 printf("\n"); | |
1047 printf(" Base Size\n"); | |
1048 for ( bucket=&surfaces; bucket; bucket=bucket->next ) { | |
1049 printf("Bucket: %p, %d (%s)\n", bucket->base, bucket->size, bucket->used ? "used" : "free"); | |
1050 if ( bucket->prev ) { | |
1051 if ( bucket->base != bucket->prev->base+bucket->prev->size ) { | |
1052 printf("Warning, corrupt bucket list! (prev)\n"); | |
1053 } | |
1054 } else { | |
1055 if ( bucket != &surfaces ) { | |
1056 printf("Warning, corrupt bucket list! (!prev)\n"); | |
1057 } | |
1058 } | |
1059 if ( bucket->next ) { | |
1060 if ( bucket->next->base != bucket->base+bucket->size ) { | |
1061 printf("Warning, corrupt bucket list! (next)\n"); | |
1062 } | |
1063 } | |
1064 } | |
1065 printf("\n"); | |
1066 } | |
1067 #endif | |
1068 | |
106
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1069 static int FB_InitHWSurfaces(_THIS, SDL_Surface *screen, char *base, int size) |
0 | 1070 { |
106
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1071 vidmem_bucket *bucket; |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1072 |
0 | 1073 surfaces_memtotal = size; |
1074 surfaces_memleft = size; | |
106
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1075 |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1076 if ( surfaces_memleft > 0 ) { |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1077 bucket = (vidmem_bucket *)malloc(sizeof(*bucket)); |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1078 if ( bucket == NULL ) { |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1079 SDL_OutOfMemory(); |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1080 return(-1); |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1081 } |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1082 bucket->prev = &surfaces; |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1083 bucket->used = 0; |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1084 bucket->dirty = 0; |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1085 bucket->base = base; |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1086 bucket->size = size; |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1087 bucket->next = NULL; |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1088 } else { |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1089 bucket = NULL; |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1090 } |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1091 |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1092 surfaces.prev = NULL; |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1093 surfaces.used = 1; |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1094 surfaces.dirty = 0; |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1095 surfaces.base = screen->pixels; |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1096 surfaces.size = (unsigned int)((long)base - (long)surfaces.base); |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1097 surfaces.next = bucket; |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1098 screen->hwdata = (struct private_hwdata *)&surfaces; |
0 | 1099 return(0); |
1100 } | |
1101 static void FB_FreeHWSurfaces(_THIS) | |
1102 { | |
1103 vidmem_bucket *bucket, *freeable; | |
1104 | |
1105 bucket = surfaces.next; | |
1106 while ( bucket ) { | |
1107 freeable = bucket; | |
1108 bucket = bucket->next; | |
1109 free(freeable); | |
1110 } | |
1111 surfaces.next = NULL; | |
1112 } | |
1113 | |
1114 static int FB_AllocHWSurface(_THIS, SDL_Surface *surface) | |
1115 { | |
1116 vidmem_bucket *bucket; | |
1117 int size; | |
1118 int extra; | |
1119 | |
1120 /* Temporarily, we only allow surfaces the same width as display. | |
1121 Some blitters require the pitch between two hardware surfaces | |
1122 to be the same. Others have interesting alignment restrictions. | |
1123 Until someone who knows these details looks at the code... | |
1124 */ | |
1125 if ( surface->pitch > SDL_VideoSurface->pitch ) { | |
1126 SDL_SetError("Surface requested wider than screen"); | |
1127 return(-1); | |
1128 } | |
1129 surface->pitch = SDL_VideoSurface->pitch; | |
1130 size = surface->h * surface->pitch; | |
1131 #ifdef FBCON_DEBUG | |
1132 fprintf(stderr, "Allocating bucket of %d bytes\n", size); | |
1133 #endif | |
1134 | |
1135 /* Quick check for available mem */ | |
1136 if ( size > surfaces_memleft ) { | |
1137 SDL_SetError("Not enough video memory"); | |
1138 return(-1); | |
1139 } | |
1140 | |
1141 /* Search for an empty bucket big enough */ | |
1142 for ( bucket=&surfaces; bucket; bucket=bucket->next ) { | |
1143 if ( ! bucket->used && (size <= bucket->size) ) { | |
1144 break; | |
1145 } | |
1146 } | |
1147 if ( bucket == NULL ) { | |
1148 SDL_SetError("Video memory too fragmented"); | |
1149 return(-1); | |
1150 } | |
1151 | |
1152 /* Create a new bucket for left-over memory */ | |
1153 extra = (bucket->size - size); | |
1154 if ( extra ) { | |
1155 vidmem_bucket *newbucket; | |
1156 | |
1157 #ifdef FBCON_DEBUG | |
1158 fprintf(stderr, "Adding new free bucket of %d bytes\n", extra); | |
1159 #endif | |
1160 newbucket = (vidmem_bucket *)malloc(sizeof(*newbucket)); | |
1161 if ( newbucket == NULL ) { | |
1162 SDL_OutOfMemory(); | |
1163 return(-1); | |
1164 } | |
1165 newbucket->prev = bucket; | |
1166 newbucket->used = 0; | |
1167 newbucket->base = bucket->base+size; | |
1168 newbucket->size = extra; | |
1169 newbucket->next = bucket->next; | |
1170 if ( bucket->next ) { | |
1171 bucket->next->prev = newbucket; | |
1172 } | |
1173 bucket->next = newbucket; | |
1174 } | |
1175 | |
1176 /* Set the current bucket values and return it! */ | |
1177 bucket->used = 1; | |
1178 bucket->size = size; | |
106
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1179 bucket->dirty = 0; |
0 | 1180 #ifdef FBCON_DEBUG |
1181 fprintf(stderr, "Allocated %d bytes at %p\n", bucket->size, bucket->base); | |
1182 #endif | |
1183 surfaces_memleft -= size; | |
1184 surface->flags |= SDL_HWSURFACE; | |
1185 surface->pixels = bucket->base; | |
106
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1186 surface->hwdata = (struct private_hwdata *)bucket; |
0 | 1187 return(0); |
1188 } | |
1189 static void FB_FreeHWSurface(_THIS, SDL_Surface *surface) | |
1190 { | |
1191 vidmem_bucket *bucket, *freeable; | |
1192 | |
1193 /* Look for the bucket in the current list */ | |
1194 for ( bucket=&surfaces; bucket; bucket=bucket->next ) { | |
106
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1195 if ( bucket == (vidmem_bucket *)surface->hwdata ) { |
0 | 1196 break; |
1197 } | |
1198 } | |
106
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1199 if ( bucket && bucket->used ) { |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1200 /* Add the memory back to the total */ |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1201 #ifdef DGA_DEBUG |
0 | 1202 printf("Freeing bucket of %d bytes\n", bucket->size); |
1203 #endif | |
106
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1204 surfaces_memleft += bucket->size; |
0 | 1205 |
106
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1206 /* Can we merge the space with surrounding buckets? */ |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1207 bucket->used = 0; |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1208 if ( bucket->next && ! bucket->next->used ) { |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1209 #ifdef DGA_DEBUG |
0 | 1210 printf("Merging with next bucket, for %d total bytes\n", bucket->size+bucket->next->size); |
1211 #endif | |
106
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1212 freeable = bucket->next; |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1213 bucket->size += bucket->next->size; |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1214 bucket->next = bucket->next->next; |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1215 if ( bucket->next ) { |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1216 bucket->next->prev = bucket; |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1217 } |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1218 free(freeable); |
0 | 1219 } |
106
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1220 if ( bucket->prev && ! bucket->prev->used ) { |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1221 #ifdef DGA_DEBUG |
0 | 1222 printf("Merging with previous bucket, for %d total bytes\n", bucket->prev->size+bucket->size); |
1223 #endif | |
106
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1224 freeable = bucket; |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1225 bucket->prev->size += bucket->size; |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1226 bucket->prev->next = bucket->next; |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1227 if ( bucket->next ) { |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1228 bucket->next->prev = bucket->prev; |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1229 } |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1230 free(freeable); |
0 | 1231 } |
1232 } | |
1233 surface->pixels = NULL; | |
106
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1234 surface->hwdata = NULL; |
0 | 1235 } |
1236 static int FB_LockHWSurface(_THIS, SDL_Surface *surface) | |
1237 { | |
106
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1238 if ( surface == this->screen ) { |
0 | 1239 SDL_mutexP(hw_lock); |
106
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1240 if ( FB_IsSurfaceBusy(surface) ) { |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1241 FB_WaitBusySurfaces(this); |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1242 } |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1243 } else { |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1244 if ( FB_IsSurfaceBusy(surface) ) { |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1245 FB_WaitBusySurfaces(this); |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1246 } |
0 | 1247 } |
1248 return(0); | |
1249 } | |
1250 static void FB_UnlockHWSurface(_THIS, SDL_Surface *surface) | |
1251 { | |
106
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1252 if ( surface == this->screen ) { |
0 | 1253 SDL_mutexV(hw_lock); |
1254 } | |
1255 } | |
1256 | |
1257 static void FB_WaitVBL(_THIS) | |
1258 { | |
1259 #ifdef FBIOWAITRETRACE /* Heheh, this didn't make it into the main kernel */ | |
1260 ioctl(console_fd, FBIOWAITRETRACE, 0); | |
1261 #endif | |
1262 return; | |
1263 } | |
1264 | |
106
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1265 static void FB_WaitIdle(_THIS) |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1266 { |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1267 return; |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1268 } |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1269 |
0 | 1270 static int FB_FlipHWSurface(_THIS, SDL_Surface *surface) |
1271 { | |
1272 /* Wait for vertical retrace and then flip display */ | |
1273 cache_vinfo.yoffset = flip_page*surface->h; | |
106
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1274 if ( FB_IsSurfaceBusy(this->screen) ) { |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1275 FB_WaitBusySurfaces(this); |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1276 } |
0 | 1277 wait_vbl(this); |
1278 if ( ioctl(console_fd, FBIOPAN_DISPLAY, &cache_vinfo) < 0 ) { | |
1279 SDL_SetError("ioctl(FBIOPAN_DISPLAY) failed"); | |
1280 return(-1); | |
1281 } | |
1282 flip_page = !flip_page; | |
1283 | |
1284 surface->pixels = flip_address[flip_page]; | |
1285 return(0); | |
1286 } | |
1287 | |
1288 static void FB_DirectUpdate(_THIS, int numrects, SDL_Rect *rects) | |
1289 { | |
1290 /* The application is already updating the visible video memory */ | |
1291 return; | |
1292 } | |
1293 | |
1294 #ifdef VGA16_FBCON_SUPPORT | |
1295 /* Code adapted with thanks from the XFree86 VGA16 driver! :) */ | |
1296 #define writeGr(index, value) \ | |
1297 outb(index, 0x3CE); \ | |
1298 outb(value, 0x3CF); | |
1299 #define writeSeq(index, value) \ | |
1300 outb(index, 0x3C4); \ | |
1301 outb(value, 0x3C5); | |
1302 | |
1303 static void FB_VGA16Update(_THIS, int numrects, SDL_Rect *rects) | |
1304 { | |
1305 SDL_Surface *screen; | |
1306 int width, height, FBPitch, left, i, j, SRCPitch, phase; | |
1307 register Uint32 m; | |
1308 Uint8 s1, s2, s3, s4; | |
1309 Uint32 *src, *srcPtr; | |
1310 Uint8 *dst, *dstPtr; | |
1311 | |
1312 screen = this->screen; | |
1313 FBPitch = screen->w >> 3; | |
1314 SRCPitch = screen->pitch >> 2; | |
1315 | |
1316 writeGr(0x03, 0x00); | |
1317 writeGr(0x05, 0x00); | |
1318 writeGr(0x01, 0x00); | |
1319 writeGr(0x08, 0xFF); | |
1320 | |
1321 while(numrects--) { | |
1322 left = rects->x & ~7; | |
1323 width = (rects->w + 7) >> 3; | |
1324 height = rects->h; | |
1325 src = (Uint32*)screen->pixels + (rects->y * SRCPitch) + (left >> 2); | |
1326 dst = (Uint8*)mapped_mem + (rects->y * FBPitch) + (left >> 3); | |
1327 | |
1328 if((phase = (long)dst & 3L)) { | |
1329 phase = 4 - phase; | |
1330 if(phase > width) phase = width; | |
1331 width -= phase; | |
1332 } | |
1333 | |
1334 while(height--) { | |
1335 writeSeq(0x02, 1 << 0); | |
1336 dstPtr = dst; | |
1337 srcPtr = src; | |
1338 i = width; | |
1339 j = phase; | |
1340 while(j--) { | |
1341 m = (srcPtr[1] & 0x01010101) | ((srcPtr[0] & 0x01010101) << 4); | |
1342 *dstPtr++ = (m >> 24) | (m >> 15) | (m >> 6) | (m << 3); | |
1343 srcPtr += 2; | |
1344 } | |
1345 while(i >= 4) { | |
1346 m = (srcPtr[1] & 0x01010101) | ((srcPtr[0] & 0x01010101) << 4); | |
1347 s1 = (m >> 24) | (m >> 15) | (m >> 6) | (m << 3); | |
1348 m = (srcPtr[3] & 0x01010101) | ((srcPtr[2] & 0x01010101) << 4); | |
1349 s2 = (m >> 24) | (m >> 15) | (m >> 6) | (m << 3); | |
1350 m = (srcPtr[5] & 0x01010101) | ((srcPtr[4] & 0x01010101) << 4); | |
1351 s3 = (m >> 24) | (m >> 15) | (m >> 6) | (m << 3); | |
1352 m = (srcPtr[7] & 0x01010101) | ((srcPtr[6] & 0x01010101) << 4); | |
1353 s4 = (m >> 24) | (m >> 15) | (m >> 6) | (m << 3); | |
1354 *((Uint32*)dstPtr) = s1 | (s2 << 8) | (s3 << 16) | (s4 << 24); | |
1355 srcPtr += 8; | |
1356 dstPtr += 4; | |
1357 i -= 4; | |
1358 } | |
1359 while(i--) { | |
1360 m = (srcPtr[1] & 0x01010101) | ((srcPtr[0] & 0x01010101) << 4); | |
1361 *dstPtr++ = (m >> 24) | (m >> 15) | (m >> 6) | (m << 3); | |
1362 srcPtr += 2; | |
1363 } | |
1364 | |
1365 writeSeq(0x02, 1 << 1); | |
1366 dstPtr = dst; | |
1367 srcPtr = src; | |
1368 i = width; | |
1369 j = phase; | |
1370 while(j--) { | |
1371 m = (srcPtr[1] & 0x02020202) | ((srcPtr[0] & 0x02020202) << 4); | |
1372 *dstPtr++ = (m >> 25) | (m >> 16) | (m >> 7) | (m << 2); | |
1373 srcPtr += 2; | |
1374 } | |
1375 while(i >= 4) { | |
1376 m = (srcPtr[1] & 0x02020202) | ((srcPtr[0] & 0x02020202) << 4); | |
1377 s1 = (m >> 25) | (m >> 16) | (m >> 7) | (m << 2); | |
1378 m = (srcPtr[3] & 0x02020202) | ((srcPtr[2] & 0x02020202) << 4); | |
1379 s2 = (m >> 25) | (m >> 16) | (m >> 7) | (m << 2); | |
1380 m = (srcPtr[5] & 0x02020202) | ((srcPtr[4] & 0x02020202) << 4); | |
1381 s3 = (m >> 25) | (m >> 16) | (m >> 7) | (m << 2); | |
1382 m = (srcPtr[7] & 0x02020202) | ((srcPtr[6] & 0x02020202) << 4); | |
1383 s4 = (m >> 25) | (m >> 16) | (m >> 7) | (m << 2); | |
1384 *((Uint32*)dstPtr) = s1 | (s2 << 8) | (s3 << 16) | (s4 << 24); | |
1385 srcPtr += 8; | |
1386 dstPtr += 4; | |
1387 i -= 4; | |
1388 } | |
1389 while(i--) { | |
1390 m = (srcPtr[1] & 0x02020202) | ((srcPtr[0] & 0x02020202) << 4); | |
1391 *dstPtr++ = (m >> 25) | (m >> 16) | (m >> 7) | (m << 2); | |
1392 srcPtr += 2; | |
1393 } | |
1394 | |
1395 writeSeq(0x02, 1 << 2); | |
1396 dstPtr = dst; | |
1397 srcPtr = src; | |
1398 i = width; | |
1399 j = phase; | |
1400 while(j--) { | |
1401 m = (srcPtr[1] & 0x04040404) | ((srcPtr[0] & 0x04040404) << 4); | |
1402 *dstPtr++ = (m >> 26) | (m >> 17) | (m >> 8) | (m << 1); | |
1403 srcPtr += 2; | |
1404 } | |
1405 while(i >= 4) { | |
1406 m = (srcPtr[1] & 0x04040404) | ((srcPtr[0] & 0x04040404) << 4); | |
1407 s1 = (m >> 26) | (m >> 17) | (m >> 8) | (m << 1); | |
1408 m = (srcPtr[3] & 0x04040404) | ((srcPtr[2] & 0x04040404) << 4); | |
1409 s2 = (m >> 26) | (m >> 17) | (m >> 8) | (m << 1); | |
1410 m = (srcPtr[5] & 0x04040404) | ((srcPtr[4] & 0x04040404) << 4); | |
1411 s3 = (m >> 26) | (m >> 17) | (m >> 8) | (m << 1); | |
1412 m = (srcPtr[7] & 0x04040404) | ((srcPtr[6] & 0x04040404) << 4); | |
1413 s4 = (m >> 26) | (m >> 17) | (m >> 8) | (m << 1); | |
1414 *((Uint32*)dstPtr) = s1 | (s2 << 8) | (s3 << 16) | (s4 << 24); | |
1415 srcPtr += 8; | |
1416 dstPtr += 4; | |
1417 i -= 4; | |
1418 } | |
1419 while(i--) { | |
1420 m = (srcPtr[1] & 0x04040404) | ((srcPtr[0] & 0x04040404) << 4); | |
1421 *dstPtr++ = (m >> 26) | (m >> 17) | (m >> 8) | (m << 1); | |
1422 srcPtr += 2; | |
1423 } | |
1424 | |
1425 writeSeq(0x02, 1 << 3); | |
1426 dstPtr = dst; | |
1427 srcPtr = src; | |
1428 i = width; | |
1429 j = phase; | |
1430 while(j--) { | |
1431 m = (srcPtr[1] & 0x08080808) | ((srcPtr[0] & 0x08080808) << 4); | |
1432 *dstPtr++ = (m >> 27) | (m >> 18) | (m >> 9) | m; | |
1433 srcPtr += 2; | |
1434 } | |
1435 while(i >= 4) { | |
1436 m = (srcPtr[1] & 0x08080808) | ((srcPtr[0] & 0x08080808) << 4); | |
1437 s1 = (m >> 27) | (m >> 18) | (m >> 9) | m; | |
1438 m = (srcPtr[3] & 0x08080808) | ((srcPtr[2] & 0x08080808) << 4); | |
1439 s2 = (m >> 27) | (m >> 18) | (m >> 9) | m; | |
1440 m = (srcPtr[5] & 0x08080808) | ((srcPtr[4] & 0x08080808) << 4); | |
1441 s3 = (m >> 27) | (m >> 18) | (m >> 9) | m; | |
1442 m = (srcPtr[7] & 0x08080808) | ((srcPtr[6] & 0x08080808) << 4); | |
1443 s4 = (m >> 27) | (m >> 18) | (m >> 9) | m; | |
1444 *((Uint32*)dstPtr) = s1 | (s2 << 8) | (s3 << 16) | (s4 << 24); | |
1445 srcPtr += 8; | |
1446 dstPtr += 4; | |
1447 i -= 4; | |
1448 } | |
1449 while(i--) { | |
1450 m = (srcPtr[1] & 0x08080808) | ((srcPtr[0] & 0x08080808) << 4); | |
1451 *dstPtr++ = (m >> 27) | (m >> 18) | (m >> 9) | m; | |
1452 srcPtr += 2; | |
1453 } | |
1454 | |
1455 dst += FBPitch; | |
1456 src += SRCPitch; | |
1457 } | |
1458 rects++; | |
1459 } | |
1460 } | |
1461 #endif /* VGA16_FBCON_SUPPORT */ | |
1462 | |
1463 void FB_SavePaletteTo(_THIS, int palette_len, __u16 *area) | |
1464 { | |
1465 struct fb_cmap cmap; | |
1466 | |
1467 cmap.start = 0; | |
1468 cmap.len = palette_len; | |
1469 cmap.red = &area[0*palette_len]; | |
1470 cmap.green = &area[1*palette_len]; | |
1471 cmap.blue = &area[2*palette_len]; | |
1472 cmap.transp = NULL; | |
1473 ioctl(console_fd, FBIOGETCMAP, &cmap); | |
1474 } | |
1475 | |
1476 void FB_RestorePaletteFrom(_THIS, int palette_len, __u16 *area) | |
1477 { | |
1478 struct fb_cmap cmap; | |
1479 | |
1480 cmap.start = 0; | |
1481 cmap.len = palette_len; | |
1482 cmap.red = &area[0*palette_len]; | |
1483 cmap.green = &area[1*palette_len]; | |
1484 cmap.blue = &area[2*palette_len]; | |
1485 cmap.transp = NULL; | |
1486 ioctl(console_fd, FBIOPUTCMAP, &cmap); | |
1487 } | |
1488 | |
1489 static void FB_SavePalette(_THIS, struct fb_fix_screeninfo *finfo, | |
1490 struct fb_var_screeninfo *vinfo) | |
1491 { | |
1492 int i; | |
1493 | |
1494 /* Save hardware palette, if needed */ | |
1495 if ( finfo->visual == FB_VISUAL_PSEUDOCOLOR ) { | |
1496 saved_cmaplen = 1<<vinfo->bits_per_pixel; | |
1497 saved_cmap=(__u16 *)malloc(3*saved_cmaplen*sizeof(*saved_cmap)); | |
1498 if ( saved_cmap != NULL ) { | |
1499 FB_SavePaletteTo(this, saved_cmaplen, saved_cmap); | |
1500 } | |
1501 } | |
1502 | |
1503 /* Added support for FB_VISUAL_DIRECTCOLOR. | |
1504 With this mode pixel information is passed through the palette... | |
1505 Neat fading and gamma correction effects can be had by simply | |
1506 fooling around with the palette instead of changing the pixel | |
1507 values themselves... Very neat! | |
1508 | |
1509 Adam Meyerowitz 1/19/2000 | |
1510 ameyerow@optonline.com | |
1511 */ | |
1512 if ( finfo->visual == FB_VISUAL_DIRECTCOLOR ) { | |
1513 __u16 new_entries[3*256]; | |
1514 | |
1515 /* Save the colormap */ | |
1516 saved_cmaplen = 256; | |
1517 saved_cmap=(__u16 *)malloc(3*saved_cmaplen*sizeof(*saved_cmap)); | |
1518 if ( saved_cmap != NULL ) { | |
1519 FB_SavePaletteTo(this, saved_cmaplen, saved_cmap); | |
1520 } | |
1521 | |
1522 /* Allocate new identity colormap */ | |
1523 for ( i=0; i<256; ++i ) { | |
1524 new_entries[(0*256)+i] = | |
1525 new_entries[(1*256)+i] = | |
1526 new_entries[(2*256)+i] = (i<<8)|i; | |
1527 } | |
1528 FB_RestorePaletteFrom(this, 256, new_entries); | |
1529 } | |
1530 } | |
1531 | |
1532 static void FB_RestorePalette(_THIS) | |
1533 { | |
1534 /* Restore the original palette */ | |
1535 if ( saved_cmap ) { | |
1536 FB_RestorePaletteFrom(this, saved_cmaplen, saved_cmap); | |
1537 free(saved_cmap); | |
1538 saved_cmap = NULL; | |
1539 } | |
1540 } | |
1541 | |
1542 static int FB_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) | |
1543 { | |
1544 int i; | |
1545 __u16 r[256]; | |
1546 __u16 g[256]; | |
1547 __u16 b[256]; | |
1548 struct fb_cmap cmap; | |
1549 | |
1550 /* Set up the colormap */ | |
1551 for (i = 0; i < ncolors; i++) { | |
1552 r[i] = colors[i].r << 8; | |
1553 g[i] = colors[i].g << 8; | |
1554 b[i] = colors[i].b << 8; | |
1555 } | |
1556 cmap.start = firstcolor; | |
1557 cmap.len = ncolors; | |
1558 cmap.red = r; | |
1559 cmap.green = g; | |
1560 cmap.blue = b; | |
1561 cmap.transp = NULL; | |
1562 | |
1563 if( (ioctl(console_fd, FBIOPUTCMAP, &cmap) < 0) || | |
1564 !(this->screen->flags & SDL_HWPALETTE) ) { | |
1565 colors = this->screen->format->palette->colors; | |
1566 ncolors = this->screen->format->palette->ncolors; | |
1567 cmap.start = 0; | |
1568 cmap.len = ncolors; | |
1569 memset(r, 0, sizeof(r)); | |
1570 memset(g, 0, sizeof(g)); | |
1571 memset(b, 0, sizeof(b)); | |
1572 if ( ioctl(console_fd, FBIOGETCMAP, &cmap) == 0 ) { | |
1573 for ( i=ncolors-1; i>=0; --i ) { | |
1574 colors[i].r = (r[i]>>8); | |
1575 colors[i].g = (g[i]>>8); | |
1576 colors[i].b = (b[i]>>8); | |
1577 } | |
1578 } | |
1579 return(0); | |
1580 } | |
1581 return(1); | |
1582 } | |
1583 | |
1584 /* Note: If we are terminated, this could be called in the middle of | |
1585 another SDL video routine -- notably UpdateRects. | |
1586 */ | |
1587 static void FB_VideoQuit(_THIS) | |
1588 { | |
1589 int i, j; | |
1590 | |
1591 if ( this->screen ) { | |
1592 /* Clear screen and tell SDL not to free the pixels */ | |
1593 if ( this->screen->pixels && FB_InGraphicsMode(this) ) { | |
1036
50f4e7e4d117
[SDL] [PATCH] fix FB_VideoQuit for ia64
Sam Lantinga <slouken@libsdl.org>
parents:
941
diff
changeset
|
1594 #if defined(__powerpc__) || defined(__ia64__) /* SIGBUS when using memset() ?? */ |
0 | 1595 Uint8 *rowp = (Uint8 *)this->screen->pixels; |
1596 int left = this->screen->pitch*this->screen->h; | |
1597 while ( left-- ) { *rowp++ = 0; } | |
1598 #else | |
1599 memset(this->screen->pixels,0,this->screen->h*this->screen->pitch); | |
1600 #endif | |
1601 } | |
1602 /* This test fails when using the VGA16 shadow memory */ | |
1603 if ( ((char *)this->screen->pixels >= mapped_mem) && | |
1604 ((char *)this->screen->pixels < (mapped_mem+mapped_memlen)) ) { | |
1605 this->screen->pixels = NULL; | |
1606 } | |
1607 } | |
1608 | |
1609 /* Clear the lock mutex */ | |
1610 if ( hw_lock ) { | |
1611 SDL_DestroyMutex(hw_lock); | |
1612 hw_lock = NULL; | |
1613 } | |
1614 | |
1615 /* Clean up defined video modes */ | |
1616 for ( i=0; i<NUM_MODELISTS; ++i ) { | |
1617 if ( SDL_modelist[i] != NULL ) { | |
1618 for ( j=0; SDL_modelist[i][j]; ++j ) { | |
1619 free(SDL_modelist[i][j]); | |
1620 } | |
1621 free(SDL_modelist[i]); | |
1622 SDL_modelist[i] = NULL; | |
1623 } | |
1624 } | |
1625 | |
1626 /* Clean up the memory bucket list */ | |
1627 FB_FreeHWSurfaces(this); | |
1628 | |
1629 /* Close console and input file descriptors */ | |
1630 if ( console_fd > 0 ) { | |
1631 /* Unmap the video framebuffer and I/O registers */ | |
1632 if ( mapped_mem ) { | |
1633 munmap(mapped_mem, mapped_memlen); | |
1634 mapped_mem = NULL; | |
1635 } | |
1636 if ( mapped_io ) { | |
1637 munmap(mapped_io, mapped_iolen); | |
1638 mapped_io = NULL; | |
1639 } | |
1640 | |
1641 /* Restore the original video mode and palette */ | |
1642 if ( FB_InGraphicsMode(this) ) { | |
1643 FB_RestorePalette(this); | |
1644 ioctl(console_fd, FBIOPUT_VSCREENINFO, &saved_vinfo); | |
1645 } | |
1646 | |
1647 /* We're all done with the framebuffer */ | |
1648 close(console_fd); | |
1649 console_fd = -1; | |
1650 } | |
1651 FB_CloseMouse(this); | |
1652 FB_CloseKeyboard(this); | |
1653 } |