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