Mercurial > sdl-ios-xcode
annotate src/video/wscons/SDL_wsconsvideo.c @ 1348:40d0975c1769
Date: Mon, 6 Feb 2006 11:41:04 -0500
From: "mystml@adinet.com.uy"
Subject: [SDL] ALT-F4 using DirectX
My game isn't getting SDL_QUIT when I press ALT-F4 using the DirectX
driver; it does get SDL_QUIT when I press the red X in the window.
I tracked this down to DX5_HandleMessage() in SDL_dx5events.c;
WM_SYSKEYDOWN is being trapped and ignored which causes Windows not to post
a WM_CLOSE, hence no SDL_QUIT is being generated.
The relevant code is this :
/* The keyboard is handled via DirectInput */
case WM_SYSKEYUP:
case WM_SYSKEYDOWN:
case WM_KEYUP:
case WM_KEYDOWN: {
/* Ignore windows keyboard messages */;
}
return(0);
If I comment the WM_SYSKEYDOWN case, it falls through DefWindowProc() and
ALT-F4 starts working again.
I'm not sure about the best way to fix this. One option is handling ALT-F4
as a particular case somehow, but doesn't sound good. Another option would
be to handle WM_SYSKEYDOWN separately and breaking instead of returning 0,
so processing falls through and goes to DefWindowProc which does The Right
Thing (TM). This seems to be the minimal change that makes ALT-F4 work and
normal keyboard input continues to work.
Does this sound reasonable? Am I overlooking anything? Do I submit a patch?
--Gabriel
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Wed, 08 Feb 2006 17:19:43 +0000 |
parents | 604d73db6802 |
children | c71e05b4dc2e |
rev | line source |
---|---|
1187 | 1 /* |
2 SDL - Simple DirectMedia Layer | |
1312
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
1187
diff
changeset
|
3 Copyright (C) 1997-2006 Sam Lantinga |
1187 | 4 |
5 This library is free software; you can redistribute it and/or | |
1312
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
1187
diff
changeset
|
6 modify it under the terms of the GNU Lesser General Public |
1187 | 7 License as published by the Free Software Foundation; either |
1312
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
1187
diff
changeset
|
8 version 2.1 of the License, or (at your option) any later version. |
1187 | 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 | |
1312
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
1187
diff
changeset
|
13 Lesser General Public License for more details. |
1187 | 14 |
1312
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
1187
diff
changeset
|
15 You should have received a copy of the GNU Lesser General Public |
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
1187
diff
changeset
|
16 License along with this library; if not, write to the Free Software |
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
1187
diff
changeset
|
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
1187 | 18 |
19 Sam Lantinga | |
20 slouken@libsdl.org | |
21 */ | |
22 | |
23 #include <sys/time.h> | |
24 #include <sys/mman.h> | |
25 #include <sys/ioctl.h> | |
26 #include <dev/wscons/wsdisplay_usl_io.h> | |
27 #include <fcntl.h> | |
28 #include <unistd.h> | |
29 #include <errno.h> | |
30 | |
31 #include "SDL.h" | |
1338
604d73db6802
Removed uses of stdlib.h and string.h
Sam Lantinga <slouken@libsdl.org>
parents:
1336
diff
changeset
|
32 #include "SDL_stdlib.h" |
604d73db6802
Removed uses of stdlib.h and string.h
Sam Lantinga <slouken@libsdl.org>
parents:
1336
diff
changeset
|
33 #include "SDL_string.h" |
1187 | 34 #include "SDL_error.h" |
35 #include "SDL_video.h" | |
36 #include "SDL_mouse.h" | |
37 #include "SDL_sysvideo.h" | |
38 #include "SDL_pixels_c.h" | |
39 #include "SDL_events_c.h" | |
40 | |
41 #include "SDL_wsconsvideo.h" | |
42 #include "SDL_wsconsevents_c.h" | |
43 #include "SDL_wsconsmouse_c.h" | |
44 | |
45 #define WSCONSVID_DRIVER_NAME "wscons" | |
46 enum { | |
47 WSCONS_ROTATE_NONE = 0, | |
48 WSCONS_ROTATE_CCW = 90, | |
49 WSCONS_ROTATE_UD = 180, | |
50 WSCONS_ROTATE_CW = 270 | |
51 }; | |
52 | |
53 #define min(a,b) ((a)<(b)?(a):(b)) | |
54 | |
55 /* Initialization/Query functions */ | |
56 static int WSCONS_VideoInit(_THIS, SDL_PixelFormat *vformat); | |
57 static SDL_Rect **WSCONS_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags); | |
58 static SDL_Surface *WSCONS_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags); | |
59 static int WSCONS_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors); | |
60 static void WSCONS_VideoQuit(_THIS); | |
61 | |
62 /* Hardware surface functions */ | |
63 static int WSCONS_AllocHWSurface(_THIS, SDL_Surface *surface); | |
64 static int WSCONS_LockHWSurface(_THIS, SDL_Surface *surface); | |
65 static void WSCONS_UnlockHWSurface(_THIS, SDL_Surface *surface); | |
66 static void WSCONS_FreeHWSurface(_THIS, SDL_Surface *surface); | |
67 | |
68 /* etc. */ | |
69 static WSCONS_bitBlit WSCONS_blit16; | |
70 static WSCONS_bitBlit WSCONS_blit16blocked; | |
71 static void WSCONS_UpdateRects(_THIS, int numrects, SDL_Rect *rects); | |
72 | |
73 void WSCONS_ReportError(char *fmt, ...) | |
74 { | |
75 char message[200]; | |
76 | |
77 message[199] = '\0'; | |
78 | |
79 va_list vaArgs; | |
80 va_start(vaArgs, fmt); | |
81 vsnprintf(message, 199, fmt, vaArgs); | |
82 va_end(vaArgs); | |
83 | |
84 SDL_SetError(message); | |
85 fprintf(stderr, "WSCONS error: %s\n", message); | |
86 } | |
87 | |
88 /* WSCONS driver bootstrap functions */ | |
89 | |
90 static int WSCONS_Available(void) | |
91 { | |
92 return 1; | |
93 } | |
94 | |
95 static void WSCONS_DeleteDevice(SDL_VideoDevice *device) | |
96 { | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
97 SDL_free(device->hidden); |
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
98 SDL_free(device); |
1187 | 99 } |
100 | |
101 static SDL_VideoDevice *WSCONS_CreateDevice(int devindex) | |
102 { | |
103 SDL_VideoDevice *device; | |
104 | |
105 /* Initialize all variables that we clean on shutdown */ | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
106 device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice)); |
1187 | 107 if (device == NULL) { |
108 SDL_OutOfMemory(); | |
109 return 0; | |
110 } | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
111 SDL_memset(device, 0, (sizeof *device)); |
1187 | 112 device->hidden = |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
113 (struct SDL_PrivateVideoData *)SDL_malloc((sizeof *device->hidden)); |
1187 | 114 if (device->hidden == NULL) { |
115 SDL_OutOfMemory(); | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
116 SDL_free(device); |
1187 | 117 return(0); |
118 } | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
119 SDL_memset(device->hidden, 0, (sizeof *device->hidden)); |
1187 | 120 device->hidden->fd = -1; |
121 | |
122 /* Set the function pointers */ | |
123 device->VideoInit = WSCONS_VideoInit; | |
124 device->ListModes = WSCONS_ListModes; | |
125 device->SetVideoMode = WSCONS_SetVideoMode; | |
126 device->SetColors = WSCONS_SetColors; | |
127 device->UpdateRects = WSCONS_UpdateRects; | |
128 device->VideoQuit = WSCONS_VideoQuit; | |
129 device->AllocHWSurface = WSCONS_AllocHWSurface; | |
130 device->LockHWSurface = WSCONS_LockHWSurface; | |
131 device->UnlockHWSurface = WSCONS_UnlockHWSurface; | |
132 device->FreeHWSurface = WSCONS_FreeHWSurface; | |
133 device->InitOSKeymap = WSCONS_InitOSKeymap; | |
134 device->PumpEvents = WSCONS_PumpEvents; | |
135 device->free = WSCONS_DeleteDevice; | |
136 | |
137 return device; | |
138 } | |
139 | |
140 VideoBootStrap WSCONS_bootstrap = { | |
141 WSCONSVID_DRIVER_NAME, | |
142 "SDL wscons video driver", | |
143 WSCONS_Available, | |
144 WSCONS_CreateDevice | |
145 }; | |
146 | |
147 #define WSCONSDEV_FORMAT "/dev/ttyC%01x" | |
148 | |
149 int WSCONS_VideoInit(_THIS, SDL_PixelFormat *vformat) | |
150 { | |
151 char devnamebuf[30]; | |
152 char *devname; | |
153 char *rotation; | |
154 int wstype; | |
155 int wsmode = WSDISPLAYIO_MODE_DUMBFB; | |
156 size_t len, mapsize; | |
157 int pagemask; | |
158 int width, height; | |
159 | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
160 devname = SDL_getenv("SDL_WSCONSDEV"); |
1187 | 161 if (devname == NULL) { |
162 int activeVT; | |
163 if (ioctl(STDIN_FILENO, VT_GETACTIVE, &activeVT) == -1) { | |
164 WSCONS_ReportError("Unable to determine active terminal: %s", | |
165 strerror(errno)); | |
166 return -1; | |
167 } | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
168 SDL_snprintf(devnamebuf, sizeof(devnamebuf), WSCONSDEV_FORMAT, activeVT - 1); |
1187 | 169 devname = devnamebuf; |
170 } | |
171 | |
172 private->fd = open(devname, O_RDWR | O_NONBLOCK, 0); | |
173 if (private->fd == -1) { | |
174 WSCONS_ReportError("open %s: %s", devname, strerror(errno)); | |
175 return -1; | |
176 } | |
177 if (ioctl(private->fd, WSDISPLAYIO_GINFO, &private->info) == -1) { | |
178 WSCONS_ReportError("ioctl WSDISPLAY_GINFO: %s", strerror(errno)); | |
179 return -1; | |
180 } | |
181 if (ioctl(private->fd, WSDISPLAYIO_GTYPE, &wstype) == -1) { | |
182 WSCONS_ReportError("ioctl WSDISPLAY_GTYPE: %s", strerror(errno)); | |
183 return -1; | |
184 } | |
185 if (ioctl(private->fd, WSDISPLAYIO_LINEBYTES, &private->physlinebytes) == -1) { | |
186 WSCONS_ReportError("ioctl WSDISPLAYIO_LINEBYTES: %s", strerror(errno)); | |
187 return -1; | |
188 } | |
189 if (private->info.depth > 8) { | |
190 if (wstype == WSDISPLAY_TYPE_SUN24 || | |
191 wstype == WSDISPLAY_TYPE_SUNCG12 || | |
192 wstype == WSDISPLAY_TYPE_SUNCG14 || | |
193 wstype == WSDISPLAY_TYPE_SUNTCX || | |
194 wstype == WSDISPLAY_TYPE_SUNFFB) { | |
195 private->redMask = 0x0000ff; | |
196 private->greenMask = 0x00ff00; | |
197 private->blueMask = 0xff0000; | |
198 } else if (wstype == WSDISPLAY_TYPE_PXALCD) { | |
199 private->redMask = 0x1f << 11; | |
200 private->greenMask = 0x3f << 5; | |
201 private->blueMask = 0x1f; | |
202 } else { | |
203 WSCONS_ReportError("Unknown video hardware"); | |
204 return -1; | |
205 } | |
206 } else { | |
207 WSCONS_ReportError("Displays with 8 bpp or less are not supported"); | |
208 return -1; | |
209 } | |
210 | |
211 private->rotate = WSCONS_ROTATE_NONE; | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
212 rotation = SDL_getenv("SDL_VIDEO_WSCONS_ROTATION"); |
1187 | 213 if (rotation != NULL) { |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
214 if (SDL_strlen(rotation) == 0) { |
1187 | 215 private->shadowFB = 0; |
216 private->rotate = WSCONS_ROTATE_NONE; | |
217 printf("Not rotating, no shadow\n"); | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
218 } else if (!SDL_strcmp(rotation, "NONE")) { |
1187 | 219 private->shadowFB = 1; |
220 private->rotate = WSCONS_ROTATE_NONE; | |
221 printf("Not rotating, but still using shadow\n"); | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
222 } else if (!SDL_strcmp(rotation, "CW")) { |
1187 | 223 private->shadowFB = 1; |
224 private->rotate = WSCONS_ROTATE_CW; | |
225 printf("Rotating screen clockwise\n"); | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
226 } else if (!SDL_strcmp(rotation, "CCW")) { |
1187 | 227 private->shadowFB = 1; |
228 private->rotate = WSCONS_ROTATE_CCW; | |
229 printf("Rotating screen counter clockwise\n"); | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
230 } else if (!SDL_strcmp(rotation, "UD")) { |
1187 | 231 private->shadowFB = 1; |
232 private->rotate = WSCONS_ROTATE_UD; | |
233 printf("Rotating screen upside down\n"); | |
234 } else { | |
235 WSCONS_ReportError("\"%s\" is not a valid value for " | |
236 "SDL_VIDEO_WSCONS_ROTATION", rotation); | |
237 return -1; | |
238 } | |
239 } | |
240 | |
241 switch (private->info.depth) { | |
242 case 1: | |
243 case 4: | |
244 case 8: | |
245 len = private->physlinebytes * private->info.height; | |
246 break; | |
247 case 16: | |
248 if (private->physlinebytes == private->info.width) { | |
249 len = private->info.width * private->info.height * sizeof(short); | |
250 } else { | |
251 len = private->physlinebytes * private->info.height; | |
252 } | |
253 if (private->rotate == WSCONS_ROTATE_NONE || | |
254 private->rotate == WSCONS_ROTATE_UD) { | |
255 private->blitFunc = WSCONS_blit16; | |
256 } else { | |
257 private->blitFunc = WSCONS_blit16blocked; | |
258 } | |
259 break; | |
260 case 32: | |
261 if (private->physlinebytes == private->info.width) { | |
262 len = private->info.width * private->info.height * sizeof(int); | |
263 } else { | |
264 len = private->physlinebytes * private->info.height; | |
265 } | |
266 break; | |
267 default: | |
268 WSCONS_ReportError("unsupported depth %d", private->info.depth); | |
269 return -1; | |
270 } | |
271 | |
272 if (private->shadowFB && private->blitFunc == NULL) { | |
273 WSCONS_ReportError("Using software buffer, but no blitter function is " | |
274 "available for this %d bpp.", private->info.depth); | |
275 return -1; | |
276 } | |
277 | |
278 if (ioctl(private->fd, WSDISPLAYIO_SMODE, &wsmode) == -1) { | |
279 WSCONS_ReportError("ioctl SMODE"); | |
280 return -1; | |
281 } | |
282 | |
283 pagemask = getpagesize() - 1; | |
284 mapsize = ((int)len + pagemask) & ~pagemask; | |
285 private->physmem = (Uint8 *)mmap(NULL, mapsize, | |
286 PROT_READ | PROT_WRITE, MAP_SHARED, | |
287 private->fd, (off_t)0); | |
288 if (private->physmem == (Uint8 *)MAP_FAILED) { | |
289 private->physmem = NULL; | |
290 WSCONS_ReportError("mmap: %s", strerror(errno)); | |
291 return -1; | |
292 } | |
293 private->fbmem_len = len; | |
294 | |
295 if (private->rotate == WSCONS_ROTATE_CW || | |
296 private->rotate == WSCONS_ROTATE_CCW) { | |
297 width = private->info.height; | |
298 height = private->info.width; | |
299 } else { | |
300 width = private->info.width; | |
301 height = private->info.height; | |
302 } | |
303 | |
304 if (private->shadowFB) { | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
305 private->shadowmem = (Uint8 *)SDL_malloc(len); |
1187 | 306 if (private->shadowmem == NULL) { |
307 WSCONS_ReportError("No memory for shadow"); | |
308 return -1; | |
309 } | |
310 private->fbstart = private->shadowmem; | |
311 private->fblinebytes = width * ((private->info.depth + 7) / 8); | |
312 } else { | |
313 private->fbstart = private->physmem; | |
314 private->fblinebytes = private->physlinebytes; | |
315 } | |
316 | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
317 private->SDL_modelist[0] = (SDL_Rect *)SDL_malloc(sizeof(SDL_Rect)); |
1187 | 318 private->SDL_modelist[0]->w = width; |
319 private->SDL_modelist[0]->h = height; | |
320 | |
321 vformat->BitsPerPixel = private->info.depth; | |
322 vformat->BytesPerPixel = private->info.depth / 8; | |
323 | |
324 if (WSCONS_InitKeyboard(this) == -1) { | |
325 return -1; | |
326 } | |
327 | |
328 return 0; | |
329 } | |
330 | |
331 SDL_Rect **WSCONS_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags) | |
332 { | |
333 if (format->BitsPerPixel == private->info.depth) { | |
334 return private->SDL_modelist; | |
335 } else { | |
336 return NULL; | |
337 } | |
338 } | |
339 | |
340 SDL_Surface *WSCONS_SetVideoMode(_THIS, SDL_Surface *current, | |
341 int width, int height, int bpp, Uint32 flags) | |
342 { | |
343 if (width != private->SDL_modelist[0]->w || | |
344 height != private->SDL_modelist[0]->h) { | |
345 WSCONS_ReportError("Requested video mode %dx%d not supported.", | |
346 width, height); | |
347 return NULL; | |
348 } | |
349 if (bpp != private->info.depth) { | |
350 WSCONS_ReportError("Requested video depth %d bpp not supported.", bpp); | |
351 return NULL; | |
352 } | |
353 | |
354 if (!SDL_ReallocFormat(current, | |
355 bpp, | |
356 private->redMask, | |
357 private->greenMask, | |
358 private->blueMask, | |
359 0)) { | |
360 WSCONS_ReportError("Couldn't allocate new pixel format"); | |
361 return NULL; | |
362 } | |
363 | |
364 current->flags &= SDL_FULLSCREEN; | |
365 if (private->shadowFB) { | |
366 current->flags |= SDL_SWSURFACE; | |
367 } else { | |
368 current->flags |= SDL_HWSURFACE; | |
369 } | |
370 current->w = width; | |
371 current->h = height; | |
372 current->pitch = private->fblinebytes; | |
373 current->pixels = private->fbstart; | |
374 | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
375 SDL_memset(private->fbstart, 0, private->fbmem_len); |
1187 | 376 |
377 return current; | |
378 } | |
379 | |
380 static int WSCONS_AllocHWSurface(_THIS, SDL_Surface *surface) | |
381 { | |
382 return -1; | |
383 } | |
384 static void WSCONS_FreeHWSurface(_THIS, SDL_Surface *surface) | |
385 { | |
386 } | |
387 | |
388 static int WSCONS_LockHWSurface(_THIS, SDL_Surface *surface) | |
389 { | |
390 return 0; | |
391 } | |
392 | |
393 static void WSCONS_UnlockHWSurface(_THIS, SDL_Surface *surface) | |
394 { | |
395 } | |
396 | |
397 static void WSCONS_blit16(Uint8 *byte_src_pos, | |
398 int srcRightDelta, | |
399 int srcDownDelta, | |
400 Uint8 *byte_dst_pos, | |
401 int dst_linebytes, | |
402 int width, | |
403 int height) | |
404 { | |
405 int w; | |
406 Uint16 *src_pos = (Uint16 *)byte_src_pos; | |
407 Uint16 *dst_pos = (Uint16 *)byte_dst_pos; | |
408 | |
409 while (height) { | |
410 Uint16 *src = src_pos; | |
411 Uint16 *dst = dst_pos; | |
412 for (w = width; w != 0; w--) { | |
413 *dst = *src; | |
414 src += srcRightDelta; | |
415 dst++; | |
416 } | |
417 dst_pos = (Uint16 *)((Uint8 *)dst_pos + dst_linebytes); | |
418 src_pos += srcDownDelta; | |
419 height--; | |
420 } | |
421 } | |
422 | |
423 #define BLOCKSIZE_W 32 | |
424 #define BLOCKSIZE_H 32 | |
425 | |
426 static void WSCONS_blit16blocked(Uint8 *byte_src_pos, | |
427 int srcRightDelta, | |
428 int srcDownDelta, | |
429 Uint8 *byte_dst_pos, | |
430 int dst_linebytes, | |
431 int width, | |
432 int height) | |
433 { | |
434 int w; | |
435 Uint16 *src_pos = (Uint16 *)byte_src_pos; | |
436 Uint16 *dst_pos = (Uint16 *)byte_dst_pos; | |
437 | |
438 while (height > 0) { | |
439 Uint16 *src = src_pos; | |
440 Uint16 *dst = dst_pos; | |
441 for (w = width; w > 0; w -= BLOCKSIZE_W) { | |
442 WSCONS_blit16((Uint8 *)src, | |
443 srcRightDelta, | |
444 srcDownDelta, | |
445 (Uint8 *)dst, | |
446 dst_linebytes, | |
447 min(w, BLOCKSIZE_W), | |
448 min(height, BLOCKSIZE_H)); | |
449 src += srcRightDelta * BLOCKSIZE_W; | |
450 dst += BLOCKSIZE_W; | |
451 } | |
452 dst_pos = (Uint16 *)((Uint8 *)dst_pos + dst_linebytes * BLOCKSIZE_H); | |
453 src_pos += srcDownDelta * BLOCKSIZE_H; | |
454 height -= BLOCKSIZE_H; | |
455 } | |
456 } | |
457 | |
458 static void WSCONS_UpdateRects(_THIS, int numrects, SDL_Rect *rects) | |
459 { | |
460 int width = private->SDL_modelist[0]->w; | |
461 int height = private->SDL_modelist[0]->h; | |
462 int bytesPerPixel = (private->info.depth + 7) / 8; | |
463 int i; | |
464 | |
465 if (!private->shadowFB) { | |
466 return; | |
467 } | |
468 | |
469 if (private->info.depth != 16) { | |
470 WSCONS_ReportError("Shadow copy only implemented for 16 bpp"); | |
471 return; | |
472 } | |
473 | |
474 for (i = 0; i < numrects; i++) { | |
475 int x1, y1, x2, y2; | |
476 int scr_x1, scr_y1, scr_x2, scr_y2; | |
477 int sha_x1, sha_y1; | |
478 int shadowRightDelta; /* Address change when moving right in dest */ | |
479 int shadowDownDelta; /* Address change when moving down in dest */ | |
480 Uint8 *src_start; | |
481 Uint8 *dst_start; | |
482 | |
483 x1 = rects[i].x; | |
484 y1 = rects[i].y; | |
485 x2 = x1 + rects[i].w; | |
486 y2 = y1 + rects[i].h; | |
487 | |
488 if (x1 < 0) { | |
489 x1 = 0; | |
490 } else if (x1 > width) { | |
491 x1 = width; | |
492 } | |
493 if (x2 < 0) { | |
494 x2 = 0; | |
495 } else if (x2 > width) { | |
496 x2 = width; | |
497 } | |
498 if (y1 < 0) { | |
499 y1 = 0; | |
500 } else if (y1 > height) { | |
501 y1 = height; | |
502 } | |
503 if (y2 < 0) { | |
504 y2 = 0; | |
505 } else if (y2 > height) { | |
506 y2 = height; | |
507 } | |
508 if (x2 <= x1 || y2 <= y1) { | |
509 continue; | |
510 } | |
511 | |
512 switch (private->rotate) { | |
513 case WSCONS_ROTATE_NONE: | |
514 sha_x1 = scr_x1 = x1; | |
515 sha_y1 = scr_y1 = y1; | |
516 scr_x2 = x2; | |
517 scr_y2 = y2; | |
518 shadowRightDelta = 1; | |
519 shadowDownDelta = width; | |
520 break; | |
521 case WSCONS_ROTATE_CCW: | |
522 scr_x1 = y1; | |
523 scr_y1 = width - x2; | |
524 scr_x2 = y2; | |
525 scr_y2 = width - x1; | |
526 sha_x1 = x2 - 1; | |
527 sha_y1 = y1; | |
528 shadowRightDelta = width; | |
529 shadowDownDelta = -1; | |
530 break; | |
531 case WSCONS_ROTATE_UD: | |
532 scr_x1 = width - x2; | |
533 scr_y1 = height - y2; | |
534 scr_x2 = width - x1; | |
535 scr_y2 = height - y1; | |
536 sha_x1 = x2 - 1; | |
537 sha_y1 = y2 - 1; | |
538 shadowRightDelta = -1; | |
539 shadowDownDelta = -width; | |
540 break; | |
541 case WSCONS_ROTATE_CW: | |
542 scr_x1 = height - y2; | |
543 scr_y1 = x1; | |
544 scr_x2 = height - y1; | |
545 scr_y2 = x2; | |
546 sha_x1 = x1; | |
547 sha_y1 = y2 - 1; | |
548 shadowRightDelta = -width; | |
549 shadowDownDelta = 1; | |
550 break; | |
551 default: | |
552 WSCONS_ReportError("Unknown rotation"); | |
553 return; | |
554 } | |
555 | |
556 src_start = private->shadowmem + (sha_y1 * width + sha_x1) * bytesPerPixel; | |
557 dst_start = private->physmem + scr_y1 * private->physlinebytes + | |
558 scr_x1 * bytesPerPixel; | |
559 | |
560 private->blitFunc(src_start, | |
561 shadowRightDelta, | |
562 shadowDownDelta, | |
563 dst_start, | |
564 private->physlinebytes, | |
565 scr_x2 - scr_x1, | |
566 scr_y2 - scr_y1); | |
567 } | |
568 } | |
569 | |
570 int WSCONS_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) | |
571 { | |
572 return 0; | |
573 } | |
574 | |
575 /* | |
576 * Note: If we are terminated, this could be called in the middle of | |
577 * another SDL video routine -- notably UpdateRects. | |
578 */ | |
579 void WSCONS_VideoQuit(_THIS) | |
580 { | |
581 int mode = WSDISPLAYIO_MODE_EMUL; | |
582 | |
583 if (private->shadowmem != NULL) { | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
584 SDL_free(private->shadowmem); |
1187 | 585 private->shadowmem = NULL; |
586 } | |
587 private->fbstart = NULL; | |
588 if (this->screen != NULL) { | |
589 this->screen->pixels = NULL; | |
590 } | |
591 | |
592 if (private->SDL_modelist[0] != NULL) { | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
593 SDL_free(private->SDL_modelist[0]); |
1187 | 594 private->SDL_modelist[0] = NULL; |
595 } | |
596 | |
597 if (ioctl(private->fd, WSDISPLAYIO_SMODE, &mode) == -1) { | |
598 WSCONS_ReportError("ioctl SMODE"); | |
599 } | |
600 | |
601 WSCONS_ReleaseKeyboard(this); | |
602 | |
603 if (private->fd != -1) { | |
604 close(private->fd); | |
605 private->fd = -1; | |
606 } | |
607 } |