Mercurial > sdl-ios-xcode
annotate src/video/ggi/SDL_ggivideo.c @ 934:af585d6efec8
Date: Thu, 17 Jun 2004 11:38:51 -0700 (PDT)
From: Eric Wing <ewing2121@yahoo.com>
Subject: New OS X patch (was Re: [SDL] Bug with inverted mouse coordinates in
I have a new patch for OS X I would like to submit.
First, it appears no further action has been taken on
my fix from Apple on the OpenGL windowed mode mouse
inversion problem. The fix would reunify the code, and
no longer require case checking for which version of
the OS you are running. This is probably a good fix
because the behavior with the old code could change
again with future versions of the OS, so those fixes
are included in this new patch.
But in addition, when I was at Apple, I asked them
about the ability to distinguish between the modifier
keys on the left and right sides of the keyboard (e.g.
Left Shift, Right Shift, Left/Right Alt, L/R Cmd, L/R
Ctrl). They told me that starting with Panther, the OS
began supporting this feature. This has always been a
source of annoyance for me when bringing a program
that comes from Windows or Linux to OS X when the
keybindings happened to need distinguishable left-side
and right-side keys. So the rest of the patch I am
submitting contains new code to support this feature
on Panther (and presumably later versions of the OS).
So after removing the OS version checks for the mouse
inversion problem, I reused the OS version checks to
activate the Left/Right detection of modifier keys. If
you are running Panther (or above), the new code will
attempt to distinguish between sides. For the older
OS's, the code path reverts to the original code.
I've tested with Panther on a G4 Cube, G5 dual
processor, and Powerbook Rev C. The Cube and G5
keyboards demonstrated the ability to distinguish
between sides. The Powerbook seems to only have
left-side keys, but the patch was still able to handle
it by producing the same results as before the patch.
I also wanted to test a non-Apple keyboard.
Unfortunately, I don't have any PC USB keyboards.
However, I was able to borrow a Sun Microsystems USB
keyboard, so I tried that out on the G5, and I got the
correct behavior for left and right sides. I'm
expecting that if it worked with a Sun keyboard, most
other keyboards should work with no problems.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Fri, 20 Aug 2004 22:35:23 +0000 |
parents | b8d311d90021 |
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:
297
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:
17
diff
changeset
|
20 slouken@libsdl.org |
0 | 21 */ |
22 | |
23 #ifdef SAVE_RCSID | |
24 static char rcsid = | |
25 "@(#) $Id$"; | |
26 #endif | |
27 | |
28 /* GGI-based SDL video driver implementation. | |
29 */ | |
30 | |
31 #include <stdlib.h> | |
32 #include <stdio.h> | |
33 #include <fcntl.h> | |
34 #include <unistd.h> | |
35 #include <sys/mman.h> | |
36 | |
37 #include <ggi/ggi.h> | |
38 #include <ggi/gii.h> | |
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_ggivideo.h" | |
48 #include "SDL_ggimouse_c.h" | |
49 #include "SDL_ggievents_c.h" | |
50 | |
51 | |
52 struct private_hwdata | |
53 { | |
54 ggi_visual_t vis; | |
55 }; | |
56 | |
57 ggi_visual_t VIS; | |
58 | |
59 /* Initialization/Query functions */ | |
60 static int GGI_VideoInit(_THIS, SDL_PixelFormat *vformat); | |
61 static SDL_Rect **GGI_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags); | |
62 static SDL_Surface *GGI_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags); | |
63 static int GGI_SetColors(_THIS, int firstcolor, int ncolors, | |
64 SDL_Color *colors); | |
65 static void GGI_VideoQuit(_THIS); | |
66 | |
67 /* Hardware surface functions */ | |
68 static int GGI_AllocHWSurface(_THIS, SDL_Surface *surface); | |
69 static int GGI_LockHWSurface(_THIS, SDL_Surface *surface); | |
70 static void GGI_UnlockHWSurface(_THIS, SDL_Surface *surface); | |
71 static void GGI_FreeHWSurface(_THIS, SDL_Surface *surface); | |
72 | |
73 /* GGI driver bootstrap functions */ | |
74 | |
75 static int GGI_Available(void) | |
76 { | |
77 ggi_visual_t *vis; | |
17
4f22a992f5e9
Fixed crash in GGI detection
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
78 |
4f22a992f5e9
Fixed crash in GGI detection
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
79 vis = NULL; |
4f22a992f5e9
Fixed crash in GGI detection
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
80 if (ggiInit() == 0) { |
4f22a992f5e9
Fixed crash in GGI detection
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
81 vis = ggiOpen(NULL); |
4f22a992f5e9
Fixed crash in GGI detection
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
82 if (vis != NULL) { |
4f22a992f5e9
Fixed crash in GGI detection
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
83 ggiClose(vis); |
4f22a992f5e9
Fixed crash in GGI detection
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
84 } |
0 | 85 } |
86 return (vis != NULL); | |
87 } | |
88 | |
89 static void GGI_DeleteDevice(SDL_VideoDevice *device) | |
90 { | |
91 free(device->hidden); | |
92 free(device); | |
93 } | |
94 | |
95 static SDL_VideoDevice *GGI_CreateDevice(int devindex) | |
96 { | |
97 SDL_VideoDevice *device; | |
98 | |
99 /* Initialize all variables that we clean on shutdown */ | |
100 device = (SDL_VideoDevice *)malloc(sizeof(SDL_VideoDevice)); | |
101 if ( device ) { | |
102 memset(device, 0, (sizeof *device)); | |
103 device->hidden = (struct SDL_PrivateVideoData *) | |
104 malloc((sizeof *device->hidden)); | |
105 } | |
106 if ( (device == NULL) || (device->hidden == NULL) ) { | |
107 SDL_OutOfMemory(); | |
108 if ( device ) { | |
109 free(device); | |
110 } | |
111 return(0); | |
112 } | |
113 memset(device->hidden, 0, (sizeof *device->hidden)); | |
114 | |
115 /* Set the function pointers */ | |
116 device->VideoInit = GGI_VideoInit; | |
117 device->ListModes = GGI_ListModes; | |
118 device->SetVideoMode = GGI_SetVideoMode; | |
119 device->SetColors = GGI_SetColors; | |
120 device->UpdateRects = NULL; | |
121 device->VideoQuit = GGI_VideoQuit; | |
122 device->AllocHWSurface = GGI_AllocHWSurface; | |
123 device->CheckHWBlit = NULL; | |
124 device->FillHWRect = NULL; | |
125 device->SetHWColorKey = NULL; | |
126 device->SetHWAlpha = NULL; | |
127 device->LockHWSurface = GGI_LockHWSurface; | |
128 device->UnlockHWSurface = GGI_UnlockHWSurface; | |
129 device->FlipHWSurface = NULL; | |
130 device->FreeHWSurface = GGI_FreeHWSurface; | |
131 device->SetCaption = NULL; | |
132 device->SetIcon = NULL; | |
133 device->IconifyWindow = NULL; | |
134 device->GrabInput = NULL; | |
135 device->GetWMInfo = NULL; | |
136 device->InitOSKeymap = GGI_InitOSKeymap; | |
137 device->PumpEvents = GGI_PumpEvents; | |
138 | |
139 device->free = GGI_DeleteDevice; | |
140 | |
141 return device; | |
142 } | |
143 | |
144 VideoBootStrap GGI_bootstrap = { | |
145 "ggi", "General Graphics Interface (GGI)", | |
146 GGI_Available, GGI_CreateDevice | |
147 }; | |
148 | |
149 | |
150 static SDL_Rect video_mode; | |
151 static SDL_Rect *SDL_modelist[4] = { NULL, NULL, NULL, NULL }; | |
152 | |
153 int GGI_VideoInit(_THIS, SDL_PixelFormat *vformat) | |
154 { | |
155 ggi_mode mode = | |
156 { | |
157 1, | |
158 { GGI_AUTO, GGI_AUTO }, | |
159 { GGI_AUTO, GGI_AUTO }, | |
160 { 0, 0 }, | |
161 GT_AUTO, | |
162 { GGI_AUTO, GGI_AUTO } | |
163 }; | |
164 struct private_hwdata *priv; | |
165 ggi_color pal[256], map[256]; | |
166 const ggi_directbuffer *db; | |
167 int err, num_bufs; | |
168 ggi_pixel white, black; | |
169 | |
170 priv = malloc(sizeof(struct private_hwdata)); | |
171 if (priv == NULL) | |
172 { | |
173 SDL_SetError("Unhandled GGI mode type!\n"); | |
174 GGI_VideoQuit(NULL); | |
175 } | |
176 | |
177 if (ggiInit() != 0) | |
178 { | |
179 SDL_SetError("Unable to initialize GGI!\n"); | |
180 GGI_VideoQuit(NULL); | |
181 } | |
182 | |
183 VIS = ggiOpen(NULL); | |
184 if (VIS == NULL) | |
185 { | |
186 SDL_SetError("Unable to open default GGI visual!\n"); | |
187 ggiExit(); | |
188 GGI_VideoQuit(NULL); | |
189 } | |
190 | |
191 ggiSetFlags(VIS, GGIFLAG_ASYNC); | |
192 | |
193 /* Validate mode, autodetecting any GGI_AUTO or GT_AUTO fields */ | |
194 ggiCheckMode(VIS, &mode); | |
195 | |
196 /* At this point we should have a valid mode - try to set it */ | |
197 err = ggiSetMode(VIS, &mode); | |
198 | |
199 /* If we couldn't set _any_ modes, something is very wrong */ | |
200 if (err) | |
201 { | |
202 SDL_SetError("Can't set a mode!\n"); | |
203 ggiClose(VIS); | |
204 ggiExit(); | |
205 GGI_VideoQuit(NULL); | |
206 } | |
207 | |
208 /* Set a palette for palletized modes */ | |
209 if (GT_SCHEME(mode.graphtype) == GT_PALETTE) | |
210 { | |
211 ggiSetColorfulPalette(VIS); | |
212 ggiGetPalette(VIS, 0, 1 << vformat->BitsPerPixel, pal); | |
213 } | |
214 | |
215 /* Now we try to get the DirectBuffer info, which determines whether | |
216 * SDL can access hardware surfaces directly. */ | |
217 | |
218 num_bufs = ggiDBGetNumBuffers(VIS); | |
219 | |
220 if (num_bufs > 0) | |
221 { | |
222 db = ggiDBGetBuffer(VIS, 0); /* Only handle one DB for now */ | |
223 | |
224 vformat->BitsPerPixel = db->buffer.plb.pixelformat->depth; | |
225 | |
226 vformat->Rmask = db->buffer.plb.pixelformat->red_mask; | |
227 vformat->Gmask = db->buffer.plb.pixelformat->green_mask; | |
228 vformat->Bmask = db->buffer.plb.pixelformat->blue_mask; | |
229 | |
230 /* Fill in our hardware acceleration capabilities */ | |
231 | |
232 this->info.wm_available = 0; | |
233 this->info.hw_available = 1; | |
234 this->info.video_mem = db->buffer.plb.stride * mode.virt.y; | |
235 } | |
236 | |
237 video_mode.x = 0; | |
238 video_mode.y = 0; | |
239 video_mode.w = mode.virt.x; | |
240 video_mode.h = mode.virt.y; | |
241 SDL_modelist[((vformat->BitsPerPixel + 7) / 8) - 1] = &video_mode; | |
242 | |
243 /* We're done! */ | |
244 return(0); | |
245 } | |
246 | |
247 static SDL_Rect **GGI_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags) | |
248 { | |
249 return(&SDL_modelist[((format->BitsPerPixel + 7) / 8) - 1]); | |
250 } | |
251 | |
252 /* Various screen update functions available */ | |
253 static void GGI_DirectUpdate(_THIS, int numrects, SDL_Rect *rects); | |
254 | |
255 SDL_Surface *GGI_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags) | |
256 { | |
257 ggi_mode mode = | |
258 { | |
259 1, | |
260 { GGI_AUTO, GGI_AUTO }, | |
261 { GGI_AUTO, GGI_AUTO }, | |
262 { 0, 0 }, | |
263 GT_AUTO, | |
264 { GGI_AUTO, GGI_AUTO } | |
265 }; | |
266 const ggi_directbuffer *db; | |
267 ggi_color pal[256]; | |
268 int err; | |
269 | |
270 fprintf(stderr, "GGI_SetVideoMode()\n"); | |
271 | |
272 mode.visible.x = mode.virt.x = width; | |
273 mode.visible.y = mode.virt.y = height; | |
274 | |
275 /* Translate requested SDL bit depth into a GGI mode */ | |
276 switch (bpp) | |
277 { | |
278 case 1: mode.graphtype = GT_1BIT; break; | |
279 case 2: mode.graphtype = GT_2BIT; break; | |
280 case 4: mode.graphtype = GT_4BIT; break; | |
281 case 8: mode.graphtype = GT_8BIT; break; | |
282 case 15: mode.graphtype = GT_15BIT; break; | |
283 case 16: mode.graphtype = GT_16BIT; break; | |
284 case 24: mode.graphtype = GT_24BIT; break; | |
285 case 32: mode.graphtype = GT_32BIT; break; | |
286 default: | |
287 SDL_SetError("Unknown SDL bit depth, using GT_AUTO....\n"); | |
288 mode.graphtype = GT_AUTO; | |
289 } | |
290 | |
291 /* Validate mode, autodetecting any GGI_AUTO or GT_AUTO fields */ | |
292 ggiCheckMode(VIS, &mode); | |
293 | |
294 /* At this point we should have a valid mode - try to set it */ | |
295 err = ggiSetMode(VIS, &mode); | |
296 | |
297 /* If we couldn't set _any_ modes, something is very wrong */ | |
298 if (err) | |
299 { | |
300 SDL_SetError("Can't set a mode!\n"); | |
301 ggiClose(VIS); | |
302 ggiExit(); | |
303 GGI_VideoQuit(NULL); | |
304 } | |
305 | |
306 /* Set a palette for palletized modes */ | |
307 if (GT_SCHEME(mode.graphtype) == GT_PALETTE) | |
308 { | |
309 ggiSetColorfulPalette(VIS); | |
310 ggiGetPalette(VIS, 0, 1 << bpp, pal); | |
311 } | |
312 | |
313 db = ggiDBGetBuffer(VIS, 0); | |
314 | |
315 /* Set up the new mode framebuffer */ | |
316 current->flags = (SDL_FULLSCREEN | SDL_HWSURFACE); | |
317 current->w = mode.virt.x; | |
318 current->h = mode.virt.y; | |
319 current->pitch = db->buffer.plb.stride; | |
320 current->pixels = db->read; | |
321 | |
322 /* Set the blit function */ | |
323 this->UpdateRects = GGI_DirectUpdate; | |
324 | |
325 /* We're done */ | |
326 return(current); | |
327 } | |
328 | |
329 static int GGI_AllocHWSurface(_THIS, SDL_Surface *surface) | |
330 { | |
331 return(-1); | |
332 } | |
333 static void GGI_FreeHWSurface(_THIS, SDL_Surface *surface) | |
334 { | |
335 return; | |
336 } | |
337 static int GGI_LockHWSurface(_THIS, SDL_Surface *surface) | |
338 { | |
339 return(0); | |
340 } | |
341 static void GGI_UnlockHWSurface(_THIS, SDL_Surface *surface) | |
342 { | |
343 return; | |
344 } | |
345 | |
346 static void GGI_DirectUpdate(_THIS, int numrects, SDL_Rect *rects) | |
347 { | |
348 int i; | |
349 | |
350 /* ggiFlush(VIS); */ | |
351 | |
352 for (i = 0; i < numrects; i++) | |
353 { | |
354 ggiFlushRegion(VIS, rects[i].x, rects[i].y, rects[i].w, rects[i].h); | |
355 } | |
356 return; | |
357 } | |
358 | |
359 int GGI_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) | |
360 { | |
361 int i; | |
362 ggi_color pal[256]; | |
363 | |
364 /* Set up the colormap */ | |
365 for (i = 0; i < ncolors; i++) | |
366 { | |
367 pal[i].r = (colors[i].r << 8) | colors[i].r; | |
368 pal[i].g = (colors[i].g << 8) | colors[i].g; | |
369 pal[i].b = (colors[i].b << 8) | colors[i].b; | |
370 } | |
371 | |
372 ggiSetPalette(VIS, firstcolor, ncolors, pal); | |
373 | |
374 return 1; | |
375 } | |
376 | |
377 void GGI_VideoQuit(_THIS) | |
378 { | |
379 } | |
380 void GGI_FinalQuit(void) | |
381 { | |
382 } |