1 |
/* |
2 |
SDL - Simple DirectMedia Layer |
3 |
Copyright (C) 1997-2011 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 |
/* This file contains functions for backwards compatibility with SDL 1.2 */ |
25 |
|
26 |
#include "SDL.h" |
27 |
#include "SDL_syswm.h" |
28 |
|
29 |
#include "video/SDL_sysvideo.h" |
30 |
#include "video/SDL_pixels_c.h" |
31 |
#include "render/SDL_yuv_sw_c.h" |
32 |
|
33 |
|
34 |
static SDL_Window *SDL_VideoWindow = NULL; |
35 |
static SDL_Surface *SDL_WindowSurface = NULL; |
36 |
static SDL_Surface *SDL_VideoSurface = NULL; |
37 |
static SDL_Surface *SDL_ShadowSurface = NULL; |
38 |
static SDL_Surface *SDL_PublicSurface = NULL; |
39 |
static SDL_GLContext *SDL_VideoContext = NULL; |
40 |
static Uint32 SDL_VideoFlags = 0; |
41 |
static SDL_Rect SDL_VideoViewport; |
42 |
static char *wm_title = NULL; |
43 |
static SDL_Surface *SDL_VideoIcon; |
44 |
static int SDL_enabled_UNICODE = 0; |
45 |
|
46 |
const char * |
47 |
SDL_AudioDriverName(char *namebuf, int maxlen) |
48 |
{ |
49 |
const char *name = SDL_GetCurrentAudioDriver(); |
50 |
if (name) { |
51 |
if (namebuf) { |
52 |
SDL_strlcpy(namebuf, name, maxlen); |
53 |
return namebuf; |
54 |
} else { |
55 |
return name; |
56 |
} |
57 |
} |
58 |
return NULL; |
59 |
} |
60 |
|
61 |
const char * |
62 |
SDL_VideoDriverName(char *namebuf, int maxlen) |
63 |
{ |
64 |
const char *name = SDL_GetCurrentVideoDriver(); |
65 |
if (name) { |
66 |
if (namebuf) { |
67 |
SDL_strlcpy(namebuf, name, maxlen); |
68 |
return namebuf; |
69 |
} else { |
70 |
return name; |
71 |
} |
72 |
} |
73 |
return NULL; |
74 |
} |
75 |
|
76 |
static int |
77 |
GetVideoDisplay() |
78 |
{ |
79 |
const char *variable = SDL_getenv("SDL_VIDEO_FULLSCREEN_DISPLAY"); |
80 |
if ( !variable ) { |
81 |
variable = SDL_getenv("SDL_VIDEO_FULLSCREEN_HEAD"); |
82 |
} |
83 |
if ( variable ) { |
84 |
return SDL_atoi(variable); |
85 |
} else { |
86 |
return 0; |
87 |
} |
88 |
} |
89 |
|
90 |
const SDL_VideoInfo * |
91 |
SDL_GetVideoInfo(void) |
92 |
{ |
93 |
static SDL_VideoInfo info; |
94 |
SDL_DisplayMode mode; |
95 |
|
96 |
/* Memory leak, compatibility code, who cares? */ |
97 |
if (!info.vfmt && SDL_GetDesktopDisplayMode(GetVideoDisplay(), &mode) == 0) { |
98 |
info.vfmt = SDL_AllocFormat(mode.format); |
99 |
info.current_w = mode.w; |
100 |
info.current_h = mode.h; |
101 |
} |
102 |
return &info; |
103 |
} |
104 |
|
105 |
int |
106 |
SDL_VideoModeOK(int width, int height, int bpp, Uint32 flags) |
107 |
{ |
108 |
int i, actual_bpp = 0; |
109 |
|
110 |
if (!SDL_GetVideoDevice()) { |
111 |
return 0; |
112 |
} |
113 |
|
114 |
if (!(flags & SDL_FULLSCREEN)) { |
115 |
SDL_DisplayMode mode; |
116 |
SDL_GetDesktopDisplayMode(GetVideoDisplay(), &mode); |
117 |
return SDL_BITSPERPIXEL(mode.format); |
118 |
} |
119 |
|
120 |
for (i = 0; i < SDL_GetNumDisplayModes(GetVideoDisplay()); ++i) { |
121 |
SDL_DisplayMode mode; |
122 |
SDL_GetDisplayMode(GetVideoDisplay(), i, &mode); |
123 |
if (!mode.w || !mode.h || (width == mode.w && height == mode.h)) { |
124 |
if (!mode.format) { |
125 |
return bpp; |
126 |
} |
127 |
if (SDL_BITSPERPIXEL(mode.format) >= (Uint32) bpp) { |
128 |
actual_bpp = SDL_BITSPERPIXEL(mode.format); |
129 |
} |
130 |
} |
131 |
} |
132 |
return actual_bpp; |
133 |
} |
134 |
|
135 |
SDL_Rect ** |
136 |
SDL_ListModes(const SDL_PixelFormat * format, Uint32 flags) |
137 |
{ |
138 |
int i, nmodes; |
139 |
SDL_Rect **modes; |
140 |
|
141 |
if (!SDL_GetVideoDevice()) { |
142 |
return NULL; |
143 |
} |
144 |
|
145 |
if (!(flags & SDL_FULLSCREEN)) { |
146 |
return (SDL_Rect **) (-1); |
147 |
} |
148 |
|
149 |
if (!format) { |
150 |
format = SDL_GetVideoInfo()->vfmt; |
151 |
} |
152 |
|
153 |
/* Memory leak, but this is a compatibility function, who cares? */ |
154 |
nmodes = 0; |
155 |
modes = NULL; |
156 |
for (i = 0; i < SDL_GetNumDisplayModes(GetVideoDisplay()); ++i) { |
157 |
SDL_DisplayMode mode; |
158 |
int bpp; |
159 |
|
160 |
SDL_GetDisplayMode(GetVideoDisplay(), i, &mode); |
161 |
if (!mode.w || !mode.h) { |
162 |
return (SDL_Rect **) (-1); |
163 |
} |
164 |
|
165 |
/* Copied from src/video/SDL_pixels.c:SDL_PixelFormatEnumToMasks */ |
166 |
if (SDL_BYTESPERPIXEL(mode.format) <= 2) { |
167 |
bpp = SDL_BITSPERPIXEL(mode.format); |
168 |
} else { |
169 |
bpp = SDL_BYTESPERPIXEL(mode.format) * 8; |
170 |
} |
171 |
|
172 |
if (bpp != format->BitsPerPixel) { |
173 |
continue; |
174 |
} |
175 |
if (nmodes > 0 && modes[nmodes - 1]->w == mode.w |
176 |
&& modes[nmodes - 1]->h == mode.h) { |
177 |
continue; |
178 |
} |
179 |
|
180 |
modes = SDL_realloc(modes, (nmodes + 2) * sizeof(*modes)); |
181 |
if (!modes) { |
182 |
return NULL; |
183 |
} |
184 |
modes[nmodes] = (SDL_Rect *) SDL_malloc(sizeof(SDL_Rect)); |
185 |
if (!modes[nmodes]) { |
186 |
return NULL; |
187 |
} |
188 |
modes[nmodes]->x = 0; |
189 |
modes[nmodes]->y = 0; |
190 |
modes[nmodes]->w = mode.w; |
191 |
modes[nmodes]->h = mode.h; |
192 |
++nmodes; |
193 |
} |
194 |
if (modes) { |
195 |
modes[nmodes] = NULL; |
196 |
} |
197 |
return modes; |
198 |
} |
199 |
|
200 |
static int |
201 |
SDL_CompatEventFilter(void *userdata, SDL_Event * event) |
202 |
{ |
203 |
SDL_Event fake; |
204 |
|
205 |
switch (event->type) { |
206 |
case SDL_WINDOWEVENT: |
207 |
switch (event->window.event) { |
208 |
case SDL_WINDOWEVENT_EXPOSED: |
209 |
if (!SDL_HasEvent(SDL_VIDEOEXPOSE)) { |
210 |
fake.type = SDL_VIDEOEXPOSE; |
211 |
SDL_PushEvent(&fake); |
212 |
} |
213 |
break; |
214 |
case SDL_WINDOWEVENT_RESIZED: |
215 |
SDL_FlushEvent(SDL_VIDEORESIZE); |
216 |
/* We don't want to expose that the window width and height will |
217 |
be different if we don't get the desired fullscreen mode. |
218 |
*/ |
219 |
if (SDL_VideoWindow && !(SDL_GetWindowFlags(SDL_VideoWindow) & SDL_WINDOW_FULLSCREEN)) { |
220 |
fake.type = SDL_VIDEORESIZE; |
221 |
fake.resize.w = event->window.data1; |
222 |
fake.resize.h = event->window.data2; |
223 |
SDL_PushEvent(&fake); |
224 |
} |
225 |
break; |
226 |
case SDL_WINDOWEVENT_MINIMIZED: |
227 |
fake.type = SDL_ACTIVEEVENT; |
228 |
fake.active.gain = 0; |
229 |
fake.active.state = SDL_APPACTIVE; |
230 |
SDL_PushEvent(&fake); |
231 |
break; |
232 |
case SDL_WINDOWEVENT_RESTORED: |
233 |
fake.type = SDL_ACTIVEEVENT; |
234 |
fake.active.gain = 1; |
235 |
fake.active.state = SDL_APPACTIVE; |
236 |
SDL_PushEvent(&fake); |
237 |
break; |
238 |
case SDL_WINDOWEVENT_ENTER: |
239 |
fake.type = SDL_ACTIVEEVENT; |
240 |
fake.active.gain = 1; |
241 |
fake.active.state = SDL_APPMOUSEFOCUS; |
242 |
SDL_PushEvent(&fake); |
243 |
break; |
244 |
case SDL_WINDOWEVENT_LEAVE: |
245 |
fake.type = SDL_ACTIVEEVENT; |
246 |
fake.active.gain = 0; |
247 |
fake.active.state = SDL_APPMOUSEFOCUS; |
248 |
SDL_PushEvent(&fake); |
249 |
break; |
250 |
case SDL_WINDOWEVENT_FOCUS_GAINED: |
251 |
fake.type = SDL_ACTIVEEVENT; |
252 |
fake.active.gain = 1; |
253 |
fake.active.state = SDL_APPINPUTFOCUS; |
254 |
SDL_PushEvent(&fake); |
255 |
break; |
256 |
case SDL_WINDOWEVENT_FOCUS_LOST: |
257 |
fake.type = SDL_ACTIVEEVENT; |
258 |
fake.active.gain = 0; |
259 |
fake.active.state = SDL_APPINPUTFOCUS; |
260 |
SDL_PushEvent(&fake); |
261 |
break; |
262 |
case SDL_WINDOWEVENT_CLOSE: |
263 |
fake.type = SDL_QUIT; |
264 |
SDL_PushEvent(&fake); |
265 |
break; |
266 |
} |
267 |
case SDL_KEYDOWN: |
268 |
case SDL_KEYUP: |
269 |
{ |
270 |
Uint32 unicode = 0; |
271 |
if (event->key.type == SDL_KEYDOWN && event->key.keysym.sym < 256) { |
272 |
unicode = event->key.keysym.sym; |
273 |
if (unicode >= 'a' && unicode <= 'z') { |
274 |
int shifted = !!(event->key.keysym.mod & KMOD_SHIFT); |
275 |
int capslock = !!(event->key.keysym.mod & KMOD_CAPS); |
276 |
if ((shifted ^ capslock) != 0) { |
277 |
unicode = SDL_toupper(unicode); |
278 |
} |
279 |
} |
280 |
} |
281 |
if (unicode) { |
282 |
event->key.keysym.unicode = unicode; |
283 |
} |
284 |
break; |
285 |
} |
286 |
case SDL_TEXTINPUT: |
287 |
{ |
288 |
/* FIXME: Generate an old style key repeat event if needed */ |
289 |
//printf("TEXTINPUT: '%s'\n", event->text.text); |
290 |
break; |
291 |
} |
292 |
case SDL_MOUSEMOTION: |
293 |
{ |
294 |
event->motion.x -= SDL_VideoViewport.x; |
295 |
event->motion.y -= SDL_VideoViewport.y; |
296 |
break; |
297 |
} |
298 |
case SDL_MOUSEBUTTONDOWN: |
299 |
case SDL_MOUSEBUTTONUP: |
300 |
{ |
301 |
event->button.x -= SDL_VideoViewport.x; |
302 |
event->button.y -= SDL_VideoViewport.y; |
303 |
break; |
304 |
} |
305 |
case SDL_MOUSEWHEEL: |
306 |
{ |
307 |
Uint8 button; |
308 |
int x, y; |
309 |
|
310 |
if (event->wheel.y == 0) { |
311 |
break; |
312 |
} |
313 |
|
314 |
SDL_GetMouseState(&x, &y); |
315 |
|
316 |
if (event->wheel.y > 0) { |
317 |
button = SDL_BUTTON_WHEELUP; |
318 |
} else { |
319 |
button = SDL_BUTTON_WHEELDOWN; |
320 |
} |
321 |
|
322 |
fake.button.button = button; |
323 |
fake.button.x = x; |
324 |
fake.button.y = y; |
325 |
fake.button.windowID = event->wheel.windowID; |
326 |
|
327 |
fake.type = SDL_MOUSEBUTTONDOWN; |
328 |
fake.button.state = SDL_PRESSED; |
329 |
SDL_PushEvent(&fake); |
330 |
|
331 |
fake.type = SDL_MOUSEBUTTONUP; |
332 |
fake.button.state = SDL_RELEASED; |
333 |
SDL_PushEvent(&fake); |
334 |
break; |
335 |
} |
336 |
|
337 |
} |
338 |
return 1; |
339 |
} |
340 |
|
341 |
static void |
342 |
GetEnvironmentWindowPosition(int w, int h, int *x, int *y) |
343 |
{ |
344 |
int display = GetVideoDisplay(); |
345 |
const char *window = SDL_getenv("SDL_VIDEO_WINDOW_POS"); |
346 |
const char *center = SDL_getenv("SDL_VIDEO_CENTERED"); |
347 |
if (window) { |
348 |
if (SDL_sscanf(window, "%d,%d", x, y) == 2) { |
349 |
return; |
350 |
} |
351 |
if (SDL_strcmp(window, "center") == 0) { |
352 |
center = window; |
353 |
} |
354 |
} |
355 |
if (center) { |
356 |
*x = SDL_WINDOWPOS_CENTERED_DISPLAY(display); |
357 |
*y = SDL_WINDOWPOS_CENTERED_DISPLAY(display); |
358 |
} |
359 |
} |
360 |
|
361 |
static void |
362 |
ClearVideoSurface() |
363 |
{ |
364 |
if (SDL_ShadowSurface) { |
365 |
SDL_FillRect(SDL_ShadowSurface, NULL, |
366 |
SDL_MapRGB(SDL_ShadowSurface->format, 0, 0, 0)); |
367 |
} |
368 |
SDL_FillRect(SDL_WindowSurface, NULL, 0); |
369 |
SDL_UpdateWindowSurface(SDL_VideoWindow); |
370 |
} |
371 |
|
372 |
static void |
373 |
SetupScreenSaver(int flags) |
374 |
{ |
375 |
const char *env; |
376 |
SDL_bool allow_screensaver; |
377 |
|
378 |
/* Allow environment override of screensaver disable */ |
379 |
env = SDL_getenv("SDL_VIDEO_ALLOW_SCREENSAVER"); |
380 |
if (env) { |
381 |
allow_screensaver = SDL_atoi(env) ? SDL_TRUE : SDL_FALSE; |
382 |
} else if (flags & SDL_FULLSCREEN) { |
383 |
allow_screensaver = SDL_FALSE; |
384 |
} else { |
385 |
allow_screensaver = SDL_TRUE; |
386 |
} |
387 |
if (allow_screensaver) { |
388 |
SDL_EnableScreenSaver(); |
389 |
} else { |
390 |
SDL_DisableScreenSaver(); |
391 |
} |
392 |
} |
393 |
|
394 |
static int |
395 |
SDL_ResizeVideoMode(int width, int height, int bpp, Uint32 flags) |
396 |
{ |
397 |
int w, h; |
398 |
|
399 |
/* We can't resize something we don't have... */ |
400 |
if (!SDL_VideoSurface) { |
401 |
return -1; |
402 |
} |
403 |
|
404 |
/* We probably have to recreate the window in fullscreen mode */ |
405 |
if (flags & SDL_FULLSCREEN) { |
406 |
return -1; |
407 |
} |
408 |
|
409 |
/* I don't think there's any change we can gracefully make in flags */ |
410 |
if (flags != SDL_VideoFlags) { |
411 |
return -1; |
412 |
} |
413 |
if (bpp != SDL_VideoSurface->format->BitsPerPixel) { |
414 |
return -1; |
415 |
} |
416 |
|
417 |
/* Resize the window */ |
418 |
SDL_GetWindowSize(SDL_VideoWindow, &w, &h); |
419 |
if (w != width || h != height) { |
420 |
SDL_SetWindowSize(SDL_VideoWindow, width, height); |
421 |
} |
422 |
|
423 |
/* If we're in OpenGL mode, just resize the stub surface and we're done! */ |
424 |
if (flags & SDL_OPENGL) { |
425 |
SDL_VideoSurface->w = width; |
426 |
SDL_VideoSurface->h = height; |
427 |
return 0; |
428 |
} |
429 |
|
430 |
SDL_WindowSurface = SDL_GetWindowSurface(SDL_VideoWindow); |
431 |
if (!SDL_WindowSurface) { |
432 |
return -1; |
433 |
} |
434 |
if (SDL_VideoSurface->format != SDL_WindowSurface->format) { |
435 |
return -1; |
436 |
} |
437 |
SDL_VideoSurface->w = width; |
438 |
SDL_VideoSurface->h = height; |
439 |
SDL_VideoSurface->pixels = SDL_WindowSurface->pixels; |
440 |
SDL_VideoSurface->pitch = SDL_WindowSurface->pitch; |
441 |
SDL_SetClipRect(SDL_VideoSurface, NULL); |
442 |
|
443 |
if (SDL_ShadowSurface) { |
444 |
SDL_ShadowSurface->w = width; |
445 |
SDL_ShadowSurface->h = height; |
446 |
SDL_ShadowSurface->pitch = SDL_CalculatePitch(SDL_ShadowSurface); |
447 |
SDL_ShadowSurface->pixels = |
448 |
SDL_realloc(SDL_ShadowSurface->pixels, |
449 |
SDL_ShadowSurface->h * SDL_ShadowSurface->pitch); |
450 |
SDL_SetClipRect(SDL_ShadowSurface, NULL); |
451 |
SDL_InvalidateMap(SDL_ShadowSurface->map); |
452 |
} else { |
453 |
SDL_PublicSurface = SDL_VideoSurface; |
454 |
} |
455 |
|
456 |
ClearVideoSurface(); |
457 |
|
458 |
return 0; |
459 |
} |
460 |
|
461 |
SDL_Surface * |
462 |
SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags) |
463 |
{ |
464 |
SDL_DisplayMode desktop_mode; |
465 |
int display = GetVideoDisplay(); |
466 |
int window_x = SDL_WINDOWPOS_UNDEFINED_DISPLAY(display); |
467 |
int window_y = SDL_WINDOWPOS_UNDEFINED_DISPLAY(display); |
468 |
int window_w; |
469 |
int window_h; |
470 |
Uint32 window_flags; |
471 |
Uint32 surface_flags; |
472 |
|
473 |
if (!SDL_GetVideoDevice()) { |
474 |
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE) < 0) { |
475 |
return NULL; |
476 |
} |
477 |
} |
478 |
|
479 |
SDL_GetDesktopDisplayMode(display, &desktop_mode); |
480 |
|
481 |
if (width == 0) { |
482 |
width = desktop_mode.w; |
483 |
} |
484 |
if (height == 0) { |
485 |
height = desktop_mode.h; |
486 |
} |
487 |
if (bpp == 0) { |
488 |
bpp = SDL_BITSPERPIXEL(desktop_mode.format); |
489 |
} |
490 |
|
491 |
/* See if we can simply resize the existing window and surface */ |
492 |
if (SDL_ResizeVideoMode(width, height, bpp, flags) == 0) { |
493 |
return SDL_PublicSurface; |
494 |
} |
495 |
|
496 |
/* Destroy existing window */ |
497 |
SDL_PublicSurface = NULL; |
498 |
if (SDL_ShadowSurface) { |
499 |
SDL_ShadowSurface->flags &= ~SDL_DONTFREE; |
500 |
SDL_FreeSurface(SDL_ShadowSurface); |
501 |
SDL_ShadowSurface = NULL; |
502 |
} |
503 |
if (SDL_VideoSurface) { |
504 |
SDL_VideoSurface->flags &= ~SDL_DONTFREE; |
505 |
SDL_FreeSurface(SDL_VideoSurface); |
506 |
SDL_VideoSurface = NULL; |
507 |
} |
508 |
if (SDL_VideoContext) { |
509 |
/* SDL_GL_MakeCurrent(0, NULL); *//* Doesn't do anything */ |
510 |
SDL_GL_DeleteContext(SDL_VideoContext); |
511 |
SDL_VideoContext = NULL; |
512 |
} |
513 |
if (SDL_VideoWindow) { |
514 |
SDL_GetWindowPosition(SDL_VideoWindow, &window_x, &window_y); |
515 |
SDL_DestroyWindow(SDL_VideoWindow); |
516 |
} |
517 |
|
518 |
/* Set up the event filter */ |
519 |
if (!SDL_GetEventFilter(NULL, NULL)) { |
520 |
SDL_SetEventFilter(SDL_CompatEventFilter, NULL); |
521 |
} |
522 |
|
523 |
/* Create a new window */ |
524 |
window_flags = SDL_WINDOW_SHOWN; |
525 |
if (flags & SDL_FULLSCREEN) { |
526 |
window_flags |= SDL_WINDOW_FULLSCREEN; |
527 |
} |
528 |
if (flags & SDL_OPENGL) { |
529 |
window_flags |= SDL_WINDOW_OPENGL; |
530 |
} |
531 |
if (flags & SDL_RESIZABLE) { |
532 |
window_flags |= SDL_WINDOW_RESIZABLE; |
533 |
} |
534 |
if (flags & SDL_NOFRAME) { |
535 |
window_flags |= SDL_WINDOW_BORDERLESS; |
536 |
} |
537 |
GetEnvironmentWindowPosition(width, height, &window_x, &window_y); |
538 |
SDL_VideoWindow = |
539 |
SDL_CreateWindow(wm_title, window_x, window_y, width, height, |
540 |
window_flags); |
541 |
if (!SDL_VideoWindow) { |
542 |
return NULL; |
543 |
} |
544 |
SDL_SetWindowIcon(SDL_VideoWindow, SDL_VideoIcon); |
545 |
|
546 |
SetupScreenSaver(flags); |
547 |
|
548 |
window_flags = SDL_GetWindowFlags(SDL_VideoWindow); |
549 |
surface_flags = 0; |
550 |
if (window_flags & SDL_WINDOW_FULLSCREEN) { |
551 |
surface_flags |= SDL_FULLSCREEN; |
552 |
} |
553 |
if ((window_flags & SDL_WINDOW_OPENGL) && (flags & SDL_OPENGL)) { |
554 |
surface_flags |= SDL_OPENGL; |
555 |
} |
556 |
if (window_flags & SDL_WINDOW_RESIZABLE) { |
557 |
surface_flags |= SDL_RESIZABLE; |
558 |
} |
559 |
if (window_flags & SDL_WINDOW_BORDERLESS) { |
560 |
surface_flags |= SDL_NOFRAME; |
561 |
} |
562 |
|
563 |
SDL_VideoFlags = flags; |
564 |
|
565 |
/* If we're in OpenGL mode, just create a stub surface and we're done! */ |
566 |
if (flags & SDL_OPENGL) { |
567 |
SDL_VideoContext = SDL_GL_CreateContext(SDL_VideoWindow); |
568 |
if (!SDL_VideoContext) { |
569 |
return NULL; |
570 |
} |
571 |
if (SDL_GL_MakeCurrent(SDL_VideoWindow, SDL_VideoContext) < 0) { |
572 |
return NULL; |
573 |
} |
574 |
SDL_VideoSurface = |
575 |
SDL_CreateRGBSurfaceFrom(NULL, width, height, bpp, 0, 0, 0, 0, 0); |
576 |
if (!SDL_VideoSurface) { |
577 |
return NULL; |
578 |
} |
579 |
SDL_VideoSurface->flags |= surface_flags; |
580 |
SDL_PublicSurface = SDL_VideoSurface; |
581 |
return SDL_PublicSurface; |
582 |
} |
583 |
|
584 |
/* Create the screen surface */ |
585 |
SDL_WindowSurface = SDL_GetWindowSurface(SDL_VideoWindow); |
586 |
if (!SDL_WindowSurface) { |
587 |
return NULL; |
588 |
} |
589 |
|
590 |
/* Center the public surface in the window surface */ |
591 |
SDL_GetWindowSize(SDL_VideoWindow, &window_w, &window_h); |
592 |
SDL_VideoViewport.x = (window_w - width)/2; |
593 |
SDL_VideoViewport.y = (window_h - height)/2; |
594 |
SDL_VideoViewport.w = width; |
595 |
SDL_VideoViewport.h = height; |
596 |
|
597 |
SDL_VideoSurface = SDL_CreateRGBSurfaceFrom(NULL, 0, 0, 32, 0, 0, 0, 0, 0); |
598 |
SDL_VideoSurface->flags |= surface_flags; |
599 |
SDL_VideoSurface->flags |= SDL_DONTFREE; |
600 |
SDL_FreeFormat(SDL_VideoSurface->format); |
601 |
SDL_VideoSurface->format = SDL_WindowSurface->format; |
602 |
SDL_VideoSurface->format->refcount++; |
603 |
SDL_VideoSurface->w = width; |
604 |
SDL_VideoSurface->h = height; |
605 |
SDL_VideoSurface->pitch = SDL_WindowSurface->pitch; |
606 |
SDL_VideoSurface->pixels = (void *)((Uint8 *)SDL_WindowSurface->pixels + |
607 |
SDL_VideoViewport.y * SDL_VideoSurface->pitch + |
608 |
SDL_VideoViewport.x * SDL_VideoSurface->format->BytesPerPixel); |
609 |
SDL_SetClipRect(SDL_VideoSurface, NULL); |
610 |
|
611 |
/* Create a shadow surface if necessary */ |
612 |
if ((bpp != SDL_VideoSurface->format->BitsPerPixel) |
613 |
&& !(flags & SDL_ANYFORMAT)) { |
614 |
SDL_ShadowSurface = |
615 |
SDL_CreateRGBSurface(0, width, height, bpp, 0, 0, 0, 0); |
616 |
if (!SDL_ShadowSurface) { |
617 |
return NULL; |
618 |
} |
619 |
SDL_ShadowSurface->flags |= surface_flags; |
620 |
SDL_ShadowSurface->flags |= SDL_DONTFREE; |
621 |
|
622 |
/* 8-bit SDL_ShadowSurface surfaces report that they have exclusive palette */ |
623 |
if (SDL_ShadowSurface->format->palette) { |
624 |
SDL_ShadowSurface->flags |= SDL_HWPALETTE; |
625 |
SDL_DitherColors(SDL_ShadowSurface->format->palette->colors, |
626 |
SDL_ShadowSurface->format->BitsPerPixel); |
627 |
} |
628 |
SDL_FillRect(SDL_ShadowSurface, NULL, |
629 |
SDL_MapRGB(SDL_ShadowSurface->format, 0, 0, 0)); |
630 |
} |
631 |
SDL_PublicSurface = |
632 |
(SDL_ShadowSurface ? SDL_ShadowSurface : SDL_VideoSurface); |
633 |
|
634 |
ClearVideoSurface(); |
635 |
|
636 |
/* We're finally done! */ |
637 |
return SDL_PublicSurface; |
638 |
} |
639 |
|
640 |
SDL_Surface * |
641 |
SDL_GetVideoSurface(void) |
642 |
{ |
643 |
return SDL_PublicSurface; |
644 |
} |
645 |
|
646 |
int |
647 |
SDL_SetAlpha(SDL_Surface * surface, Uint32 flag, Uint8 value) |
648 |
{ |
649 |
if (flag & SDL_SRCALPHA) { |
650 |
/* According to the docs, value is ignored for alpha surfaces */ |
651 |
if (surface->format->Amask) { |
652 |
value = 0xFF; |
653 |
} |
654 |
SDL_SetSurfaceAlphaMod(surface, value); |
655 |
SDL_SetSurfaceBlendMode(surface, SDL_BLENDMODE_BLEND); |
656 |
} else { |
657 |
SDL_SetSurfaceAlphaMod(surface, 0xFF); |
658 |
SDL_SetSurfaceBlendMode(surface, SDL_BLENDMODE_NONE); |
659 |
} |
660 |
SDL_SetSurfaceRLE(surface, (flag & SDL_RLEACCEL)); |
661 |
|
662 |
return 0; |
663 |
} |
664 |
|
665 |
SDL_Surface * |
666 |
SDL_DisplayFormat(SDL_Surface * surface) |
667 |
{ |
668 |
SDL_PixelFormat *format; |
669 |
|
670 |
if (!SDL_PublicSurface) { |
671 |
SDL_SetError("No video mode has been set"); |
672 |
return NULL; |
673 |
} |
674 |
format = SDL_PublicSurface->format; |
675 |
|
676 |
/* Set the flags appropriate for copying to display surface */ |
677 |
return SDL_ConvertSurface(surface, format, SDL_RLEACCEL); |
678 |
} |
679 |
|
680 |
SDL_Surface * |
681 |
SDL_DisplayFormatAlpha(SDL_Surface * surface) |
682 |
{ |
683 |
SDL_PixelFormat *vf; |
684 |
SDL_PixelFormat *format; |
685 |
SDL_Surface *converted; |
686 |
/* default to ARGB8888 */ |
687 |
Uint32 amask = 0xff000000; |
688 |
Uint32 rmask = 0x00ff0000; |
689 |
Uint32 gmask = 0x0000ff00; |
690 |
Uint32 bmask = 0x000000ff; |
691 |
|
692 |
if (!SDL_PublicSurface) { |
693 |
SDL_SetError("No video mode has been set"); |
694 |
return NULL; |
695 |
} |
696 |
vf = SDL_PublicSurface->format; |
697 |
|
698 |
switch (vf->BytesPerPixel) { |
699 |
case 2: |
700 |
/* For XGY5[56]5, use, AXGY8888, where {X, Y} = {R, B}. |
701 |
For anything else (like ARGB4444) it doesn't matter |
702 |
since we have no special code for it anyway */ |
703 |
if ((vf->Rmask == 0x1f) && |
704 |
(vf->Bmask == 0xf800 || vf->Bmask == 0x7c00)) { |
705 |
rmask = 0xff; |
706 |
bmask = 0xff0000; |
707 |
} |
708 |
break; |
709 |
|
710 |
case 3: |
711 |
case 4: |
712 |
/* Keep the video format, as long as the high 8 bits are |
713 |
unused or alpha */ |
714 |
if ((vf->Rmask == 0xff) && (vf->Bmask == 0xff0000)) { |
715 |
rmask = 0xff; |
716 |
bmask = 0xff0000; |
717 |
} |
718 |
break; |
719 |
|
720 |
default: |
721 |
/* We have no other optimised formats right now. When/if a new |
722 |
optimised alpha format is written, add the converter here */ |
723 |
break; |
724 |
} |
725 |
format = SDL_AllocFormat(SDL_MasksToPixelFormatEnum(32, rmask, |
726 |
gmask, |
727 |
bmask, |
728 |
amask)); |
729 |
if (!format) { |
730 |
return NULL; |
731 |
} |
732 |
converted = SDL_ConvertSurface(surface, format, SDL_RLEACCEL); |
733 |
SDL_FreeFormat(format); |
734 |
return converted; |
735 |
} |
736 |
|
737 |
int |
738 |
SDL_Flip(SDL_Surface * screen) |
739 |
{ |
740 |
SDL_UpdateRect(screen, 0, 0, 0, 0); |
741 |
return 0; |
742 |
} |
743 |
|
744 |
void |
745 |
SDL_UpdateRect(SDL_Surface * screen, Sint32 x, Sint32 y, Uint32 w, Uint32 h) |
746 |
{ |
747 |
if (screen) { |
748 |
SDL_Rect rect; |
749 |
|
750 |
/* Fill the rectangle */ |
751 |
rect.x = (int) x; |
752 |
rect.y = (int) y; |
753 |
rect.w = (int) (w ? w : screen->w); |
754 |
rect.h = (int) (h ? h : screen->h); |
755 |
SDL_UpdateRects(screen, 1, &rect); |
756 |
} |
757 |
} |
758 |
|
759 |
void |
760 |
SDL_UpdateRects(SDL_Surface * screen, int numrects, SDL_Rect * rects) |
761 |
{ |
762 |
int i; |
763 |
|
764 |
if (screen == SDL_ShadowSurface) { |
765 |
for (i = 0; i < numrects; ++i) { |
766 |
SDL_LowerBlit(SDL_ShadowSurface, &rects[i], SDL_VideoSurface, |
767 |
&rects[i]); |
768 |
} |
769 |
|
770 |
/* Fall through to video surface update */ |
771 |
screen = SDL_VideoSurface; |
772 |
} |
773 |
if (screen == SDL_VideoSurface) { |
774 |
if (SDL_VideoViewport.x || SDL_VideoViewport.y) { |
775 |
SDL_Rect *stackrects = SDL_stack_alloc(SDL_Rect, numrects); |
776 |
SDL_Rect *stackrect; |
777 |
const SDL_Rect *rect; |
778 |
|
779 |
/* Offset all the rectangles before updating */ |
780 |
for (i = 0; i < numrects; ++i) { |
781 |
rect = &rects[i]; |
782 |
stackrect = &stackrects[i]; |
783 |
stackrect->x = SDL_VideoViewport.x + rect->x; |
784 |
stackrect->y = SDL_VideoViewport.y + rect->y; |
785 |
stackrect->w = rect->w; |
786 |
stackrect->h = rect->h; |
787 |
} |
788 |
SDL_UpdateWindowSurfaceRects(SDL_VideoWindow, stackrects, numrects); |
789 |
SDL_stack_free(stackrects); |
790 |
} else { |
791 |
SDL_UpdateWindowSurfaceRects(SDL_VideoWindow, rects, numrects); |
792 |
} |
793 |
} |
794 |
} |
795 |
|
796 |
void |
797 |
SDL_WM_SetCaption(const char *title, const char *icon) |
798 |
{ |
799 |
if (wm_title) { |
800 |
SDL_free(wm_title); |
801 |
} |
802 |
if (title) { |
803 |
wm_title = SDL_strdup(title); |
804 |
} else { |
805 |
wm_title = NULL; |
806 |
} |
807 |
SDL_SetWindowTitle(SDL_VideoWindow, wm_title); |
808 |
} |
809 |
|
810 |
void |
811 |
SDL_WM_GetCaption(const char **title, const char **icon) |
812 |
{ |
813 |
if (title) { |
814 |
*title = wm_title; |
815 |
} |
816 |
if (icon) { |
817 |
*icon = ""; |
818 |
} |
819 |
} |
820 |
|
821 |
void |
822 |
SDL_WM_SetIcon(SDL_Surface * icon, Uint8 * mask) |
823 |
{ |
824 |
SDL_VideoIcon = icon; |
825 |
} |
826 |
|
827 |
int |
828 |
SDL_WM_IconifyWindow(void) |
829 |
{ |
830 |
SDL_MinimizeWindow(SDL_VideoWindow); |
831 |
return 0; |
832 |
} |
833 |
|
834 |
int |
835 |
SDL_WM_ToggleFullScreen(SDL_Surface * surface) |
836 |
{ |
837 |
int length; |
838 |
void *pixels; |
839 |
Uint8 *src, *dst; |
840 |
int row; |
841 |
int window_w; |
842 |
int window_h; |
843 |
|
844 |
if (!SDL_PublicSurface) { |
845 |
SDL_SetError("SDL_SetVideoMode() hasn't been called"); |
846 |
return 0; |
847 |
} |
848 |
|
849 |
/* Copy the old bits out */ |
850 |
length = SDL_PublicSurface->w * SDL_PublicSurface->format->BytesPerPixel; |
851 |
pixels = SDL_malloc(SDL_PublicSurface->h * length); |
852 |
if (pixels) { |
853 |
src = (Uint8*)SDL_PublicSurface->pixels; |
854 |
dst = (Uint8*)pixels; |
855 |
for (row = 0; row < SDL_PublicSurface->h; ++row) { |
856 |
SDL_memcpy(dst, src, length); |
857 |
src += SDL_PublicSurface->pitch; |
858 |
dst += length; |
859 |
} |
860 |
} |
861 |
|
862 |
/* Do the physical mode switch */ |
863 |
if (SDL_GetWindowFlags(SDL_VideoWindow) & SDL_WINDOW_FULLSCREEN) { |
864 |
if (SDL_SetWindowFullscreen(SDL_VideoWindow, 0) < 0) { |
865 |
return 0; |
866 |
} |
867 |
SDL_PublicSurface->flags &= ~SDL_FULLSCREEN; |
868 |
} else { |
869 |
if (SDL_SetWindowFullscreen(SDL_VideoWindow, 1) < 0) { |
870 |
return 0; |
871 |
} |
872 |
SDL_PublicSurface->flags |= SDL_FULLSCREEN; |
873 |
} |
874 |
|
875 |
/* Recreate the screen surface */ |
876 |
SDL_WindowSurface = SDL_GetWindowSurface(SDL_VideoWindow); |
877 |
if (!SDL_WindowSurface) { |
878 |
/* We're totally hosed... */ |
879 |
return 0; |
880 |
} |
881 |
|
882 |
/* Center the public surface in the window surface */ |
883 |
SDL_GetWindowSize(SDL_VideoWindow, &window_w, &window_h); |
884 |
SDL_VideoViewport.x = (window_w - SDL_VideoSurface->w)/2; |
885 |
SDL_VideoViewport.y = (window_h - SDL_VideoSurface->h)/2; |
886 |
SDL_VideoViewport.w = SDL_VideoSurface->w; |
887 |
SDL_VideoViewport.h = SDL_VideoSurface->h; |
888 |
|
889 |
/* Do some shuffling behind the application's back if format changes */ |
890 |
if (SDL_VideoSurface->format->format != SDL_WindowSurface->format->format) { |
891 |
if (SDL_ShadowSurface) { |
892 |
if (SDL_ShadowSurface->format->format == SDL_WindowSurface->format->format) { |
893 |
/* Whee! We don't need a shadow surface anymore! */ |
894 |
SDL_VideoSurface->flags &= ~SDL_DONTFREE; |
895 |
SDL_FreeSurface(SDL_VideoSurface); |
896 |
SDL_free(SDL_ShadowSurface->pixels); |
897 |
SDL_VideoSurface = SDL_ShadowSurface; |
898 |
SDL_VideoSurface->flags |= SDL_PREALLOC; |
899 |
SDL_ShadowSurface = NULL; |
900 |
} else { |
901 |
/* No problem, just change the video surface format */ |
902 |
SDL_FreeFormat(SDL_VideoSurface->format); |
903 |
SDL_VideoSurface->format = SDL_WindowSurface->format; |
904 |
SDL_VideoSurface->format->refcount++; |
905 |
SDL_InvalidateMap(SDL_ShadowSurface->map); |
906 |
} |
907 |
} else { |
908 |
/* We can make the video surface the shadow surface */ |
909 |
SDL_ShadowSurface = SDL_VideoSurface; |
910 |
SDL_ShadowSurface->pitch = SDL_CalculatePitch(SDL_ShadowSurface); |
911 |
SDL_ShadowSurface->pixels = SDL_malloc(SDL_ShadowSurface->h * SDL_ShadowSurface->pitch); |
912 |
if (!SDL_ShadowSurface->pixels) { |
913 |
/* Uh oh, we're hosed */ |
914 |
SDL_ShadowSurface = NULL; |
915 |
return 0; |
916 |
} |
917 |
SDL_ShadowSurface->flags &= ~SDL_PREALLOC; |
918 |
|
919 |
SDL_VideoSurface = SDL_CreateRGBSurfaceFrom(NULL, 0, 0, 32, 0, 0, 0, 0, 0); |
920 |
SDL_VideoSurface->flags = SDL_ShadowSurface->flags; |
921 |
SDL_VideoSurface->flags |= SDL_PREALLOC; |
922 |
SDL_FreeFormat(SDL_VideoSurface->format); |
923 |
SDL_VideoSurface->format = SDL_WindowSurface->format; |
924 |
SDL_VideoSurface->format->refcount++; |
925 |
SDL_VideoSurface->w = SDL_ShadowSurface->w; |
926 |
SDL_VideoSurface->h = SDL_ShadowSurface->h; |
927 |
} |
928 |
} |
929 |
|
930 |
/* Update the video surface */ |
931 |
SDL_VideoSurface->pitch = SDL_WindowSurface->pitch; |
932 |
SDL_VideoSurface->pixels = (void *)((Uint8 *)SDL_WindowSurface->pixels + |
933 |
SDL_VideoViewport.y * SDL_VideoSurface->pitch + |
934 |
SDL_VideoViewport.x * SDL_VideoSurface->format->BytesPerPixel); |
935 |
SDL_SetClipRect(SDL_VideoSurface, NULL); |
936 |
|
937 |
/* Copy the old bits back */ |
938 |
if (pixels) { |
939 |
src = (Uint8*)pixels; |
940 |
dst = (Uint8*)SDL_PublicSurface->pixels; |
941 |
for (row = 0; row < SDL_PublicSurface->h; ++row) { |
942 |
SDL_memcpy(dst, src, length); |
943 |
src += length; |
944 |
dst += SDL_PublicSurface->pitch; |
945 |
} |
946 |
SDL_Flip(SDL_PublicSurface); |
947 |
SDL_free(pixels); |
948 |
} |
949 |
|
950 |
/* We're done! */ |
951 |
return 1; |
952 |
} |
953 |
|
954 |
SDL_GrabMode |
955 |
SDL_WM_GrabInput(SDL_GrabMode mode) |
956 |
{ |
957 |
if (mode != SDL_GRAB_QUERY) { |
958 |
SDL_SetWindowGrab(SDL_VideoWindow, mode); |
959 |
} |
960 |
return (SDL_GrabMode) SDL_GetWindowGrab(SDL_VideoWindow); |
961 |
} |
962 |
|
963 |
void |
964 |
SDL_WarpMouse(Uint16 x, Uint16 y) |
965 |
{ |
966 |
SDL_WarpMouseInWindow(SDL_VideoWindow, x, y); |
967 |
} |
968 |
|
969 |
Uint8 |
970 |
SDL_GetAppState(void) |
971 |
{ |
972 |
Uint8 state = 0; |
973 |
Uint32 flags = 0; |
974 |
|
975 |
flags = SDL_GetWindowFlags(SDL_VideoWindow); |
976 |
if ((flags & SDL_WINDOW_SHOWN) && !(flags & SDL_WINDOW_MINIMIZED)) { |
977 |
state |= SDL_APPACTIVE; |
978 |
} |
979 |
if (flags & SDL_WINDOW_INPUT_FOCUS) { |
980 |
state |= SDL_APPINPUTFOCUS; |
981 |
} |
982 |
if (flags & SDL_WINDOW_MOUSE_FOCUS) { |
983 |
state |= SDL_APPMOUSEFOCUS; |
984 |
} |
985 |
return state; |
986 |
} |
987 |
|
988 |
const SDL_version * |
989 |
SDL_Linked_Version(void) |
990 |
{ |
991 |
static SDL_version version; |
992 |
SDL_VERSION(&version); |
993 |
return &version; |
994 |
} |
995 |
|
996 |
int |
997 |
SDL_SetPalette(SDL_Surface * surface, int flags, const SDL_Color * colors, |
998 |
int firstcolor, int ncolors) |
999 |
{ |
1000 |
return SDL_SetColors(surface, colors, firstcolor, ncolors); |
1001 |
} |
1002 |
|
1003 |
int |
1004 |
SDL_SetColors(SDL_Surface * surface, const SDL_Color * colors, int firstcolor, |
1005 |
int ncolors) |
1006 |
{ |
1007 |
if (SDL_SetPaletteColors |
1008 |
(surface->format->palette, colors, firstcolor, ncolors) == 0) { |
1009 |
return 1; |
1010 |
} else { |
1011 |
return 0; |
1012 |
} |
1013 |
} |
1014 |
|
1015 |
int |
1016 |
SDL_GetWMInfo(SDL_SysWMinfo * info) |
1017 |
{ |
1018 |
return SDL_GetWindowWMInfo(SDL_VideoWindow, info); |
1019 |
} |
1020 |
|
1021 |
#if 0 |
1022 |
void |
1023 |
SDL_MoveCursor(int x, int y) |
1024 |
{ |
1025 |
SDL_VideoDevice *_this = SDL_GetVideoDevice(); |
1026 |
|
1027 |
/* Erase and update the current mouse position */ |
1028 |
if (SHOULD_DRAWCURSOR(SDL_cursorstate)) { |
1029 |
/* Erase and redraw mouse cursor in new position */ |
1030 |
SDL_LockCursor(); |
1031 |
SDL_EraseCursor(SDL_VideoSurface); |
1032 |
SDL_cursor->area.x = (x - SDL_cursor->hot_x); |
1033 |
SDL_cursor->area.y = (y - SDL_cursor->hot_y); |
1034 |
SDL_DrawCursor(SDL_VideoSurface); |
1035 |
SDL_UnlockCursor(); |
1036 |
} else if (_this->MoveWMCursor) { |
1037 |
_this->MoveWMCursor(_this, x, y); |
1038 |
} |
1039 |
} |
1040 |
|
1041 |
/* Keep track of the current cursor colors */ |
1042 |
static int palette_changed = 1; |
1043 |
static Uint8 pixels8[2]; |
1044 |
|
1045 |
void |
1046 |
SDL_CursorPaletteChanged(void) |
1047 |
{ |
1048 |
palette_changed = 1; |
1049 |
} |
1050 |
|
1051 |
void |
1052 |
SDL_MouseRect(SDL_Rect * area) |
1053 |
{ |
1054 |
SDL_VideoDevice *_this = SDL_GetVideoDevice(); |
1055 |
int clip_diff; |
1056 |
|
1057 |
*area = SDL_cursor->area; |
1058 |
if (area->x < 0) { |
1059 |
area->w += area->x; |
1060 |
area->x = 0; |
1061 |
} |
1062 |
if (area->y < 0) { |
1063 |
area->h += area->y; |
1064 |
area->y = 0; |
1065 |
} |
1066 |
clip_diff = (area->x + area->w) - SDL_VideoSurface->w; |
1067 |
if (clip_diff > 0) { |
1068 |
area->w = area->w < clip_diff ? 0 : area->w - clip_diff; |
1069 |
} |
1070 |
clip_diff = (area->y + area->h) - SDL_VideoSurface->h; |
1071 |
if (clip_diff > 0) { |
1072 |
area->h = area->h < clip_diff ? 0 : area->h - clip_diff; |
1073 |
} |
1074 |
} |
1075 |
|
1076 |
static void |
1077 |
SDL_DrawCursorFast(SDL_Surface * screen, SDL_Rect * area) |
1078 |
{ |
1079 |
const Uint32 pixels[2] = { 0xFFFFFFFF, 0x00000000 }; |
1080 |
int i, w, h; |
1081 |
Uint8 *data, datab; |
1082 |
Uint8 *mask, maskb; |
1083 |
|
1084 |
data = SDL_cursor->data + area->y * SDL_cursor->area.w / 8; |
1085 |
mask = SDL_cursor->mask + area->y * SDL_cursor->area.w / 8; |
1086 |
switch (screen->format->BytesPerPixel) { |
1087 |
|
1088 |
case 1: |
1089 |
{ |
1090 |
Uint8 *dst; |
1091 |
int dstskip; |
1092 |
|
1093 |
if (palette_changed) { |
1094 |
pixels8[0] = |
1095 |
(Uint8) SDL_MapRGB(screen->format, 255, 255, 255); |
1096 |
pixels8[1] = (Uint8) SDL_MapRGB(screen->format, 0, 0, 0); |
1097 |
palette_changed = 0; |
1098 |
} |
1099 |
dst = (Uint8 *) screen->pixels + |
1100 |
(SDL_cursor->area.y + area->y) * screen->pitch + |
1101 |
SDL_cursor->area.x; |
1102 |
dstskip = screen->pitch - area->w; |
1103 |
|
1104 |
for (h = area->h; h; h--) { |
1105 |
for (w = area->w / 8; w; w--) { |
1106 |
maskb = *mask++; |
1107 |
datab = *data++; |
1108 |
for (i = 0; i < 8; ++i) { |
1109 |
if (maskb & 0x80) { |
1110 |
*dst = pixels8[datab >> 7]; |
1111 |
} |
1112 |
maskb <<= 1; |
1113 |
datab <<= 1; |
1114 |
dst++; |
1115 |
} |
1116 |
} |
1117 |
dst += dstskip; |
1118 |
} |
1119 |
} |
1120 |
break; |
1121 |
|
1122 |
case 2: |
1123 |
{ |
1124 |
Uint16 *dst; |
1125 |
int dstskip; |
1126 |
|
1127 |
dst = (Uint16 *) screen->pixels + |
1128 |
(SDL_cursor->area.y + area->y) * screen->pitch / 2 + |
1129 |
SDL_cursor->area.x; |
1130 |
dstskip = (screen->pitch / 2) - area->w; |
1131 |
|
1132 |
for (h = area->h; h; h--) { |
1133 |
for (w = area->w / 8; w; w--) { |
1134 |
maskb = *mask++; |
1135 |
datab = *data++; |
1136 |
for (i = 0; i < 8; ++i) { |
1137 |
if (maskb & 0x80) { |
1138 |
*dst = (Uint16) pixels[datab >> 7]; |
1139 |
} |
1140 |
maskb <<= 1; |
1141 |
datab <<= 1; |
1142 |
dst++; |
1143 |
} |
1144 |
} |
1145 |
dst += dstskip; |
1146 |
} |
1147 |
} |
1148 |
break; |
1149 |
|
1150 |
case 3: |
1151 |
{ |
1152 |
Uint8 *dst; |
1153 |
int dstskip; |
1154 |
|
1155 |
dst = (Uint8 *) screen->pixels + |
1156 |
(SDL_cursor->area.y + area->y) * screen->pitch + |
1157 |
SDL_cursor->area.x * 3; |
1158 |
dstskip = screen->pitch - area->w * 3; |
1159 |
|
1160 |
for (h = area->h; h; h--) { |
1161 |
for (w = area->w / 8; w; w--) { |
1162 |
maskb = *mask++; |
1163 |
datab = *data++; |
1164 |
for (i = 0; i < 8; ++i) { |
1165 |
if (maskb & 0x80) { |
1166 |
SDL_memset(dst, pixels[datab >> 7], 3); |
1167 |
} |
1168 |
maskb <<= 1; |
1169 |
datab <<= 1; |
1170 |
dst += 3; |
1171 |
} |
1172 |
} |
1173 |
dst += dstskip; |
1174 |
} |
1175 |
} |
1176 |
break; |
1177 |
|
1178 |
case 4: |
1179 |
{ |
1180 |
Uint32 *dst; |
1181 |
int dstskip; |
1182 |
|
1183 |
dst = (Uint32 *) screen->pixels + |
1184 |
(SDL_cursor->area.y + area->y) * screen->pitch / 4 + |
1185 |
SDL_cursor->area.x; |
1186 |
dstskip = (screen->pitch / 4) - area->w; |
1187 |
|
1188 |
for (h = area->h; h; h--) { |
1189 |
for (w = area->w / 8; w; w--) { |
1190 |
maskb = *mask++; |
1191 |
datab = *data++; |
1192 |
for (i = 0; i < 8; ++i) { |
1193 |
if (maskb & 0x80) { |
1194 |
*dst = pixels[datab >> 7]; |
1195 |
} |
1196 |
maskb <<= 1; |
1197 |
datab <<= 1; |
1198 |
dst++; |
1199 |
} |
1200 |
} |
1201 |
dst += dstskip; |
1202 |
} |
1203 |
} |
1204 |
break; |
1205 |
} |
1206 |
} |
1207 |
|
1208 |
static void |
1209 |
SDL_DrawCursorSlow(SDL_Surface * screen, SDL_Rect * area) |
1210 |
{ |
1211 |
const Uint32 pixels[2] = { 0xFFFFFF, 0x000000 }; |
1212 |
int h; |
1213 |
int x, minx, maxx; |
1214 |
Uint8 *data, datab = 0; |
1215 |
Uint8 *mask, maskb = 0; |
1216 |
Uint8 *dst; |
1217 |
int dstbpp, dstskip; |
1218 |
|
1219 |
data = SDL_cursor->data + area->y * SDL_cursor->area.w / 8; |
1220 |
mask = SDL_cursor->mask + area->y * SDL_cursor->area.w / 8; |
1221 |
dstbpp = screen->format->BytesPerPixel; |
1222 |
dst = (Uint8 *) screen->pixels + |
1223 |
(SDL_cursor->area.y + area->y) * screen->pitch + |
1224 |
SDL_cursor->area.x * dstbpp; |
1225 |
dstskip = screen->pitch - SDL_cursor->area.w * dstbpp; |
1226 |
|
1227 |
minx = area->x; |
1228 |
maxx = area->x + area->w; |
1229 |
if (screen->format->BytesPerPixel == 1) { |
1230 |
if (palette_changed) { |
1231 |
pixels8[0] = (Uint8) SDL_MapRGB(screen->format, 255, 255, 255); |
1232 |
pixels8[1] = (Uint8) SDL_MapRGB(screen->format, 0, 0, 0); |
1233 |
palette_changed = 0; |
1234 |
} |
1235 |
for (h = area->h; h; h--) { |
1236 |
for (x = 0; x < SDL_cursor->area.w; ++x) { |
1237 |
if ((x % 8) == 0) { |
1238 |
maskb = *mask++; |
1239 |
datab = *data++; |
1240 |
} |
1241 |
if ((x >= minx) && (x < maxx)) { |
1242 |
if (maskb & 0x80) { |
1243 |
SDL_memset(dst, pixels8[datab >> 7], dstbpp); |
1244 |
} |
1245 |
} |
1246 |
maskb <<= 1; |
1247 |
datab <<= 1; |
1248 |
dst += dstbpp; |
1249 |
} |
1250 |
dst += dstskip; |
1251 |
} |
1252 |
} else { |
1253 |
for (h = area->h; h; h--) { |
1254 |
for (x = 0; x < SDL_cursor->area.w; ++x) { |
1255 |
if ((x % 8) == 0) { |
1256 |
maskb = *mask++; |
1257 |
datab = *data++; |
1258 |
} |
1259 |
if ((x >= minx) && (x < maxx)) { |
1260 |
if (maskb & 0x80) { |
1261 |
SDL_memset(dst, pixels[datab >> 7], dstbpp); |
1262 |
} |
1263 |
} |
1264 |
maskb <<= 1; |
1265 |
datab <<= 1; |
1266 |
dst += dstbpp; |
1267 |
} |
1268 |
dst += dstskip; |
1269 |
} |
1270 |
} |
1271 |
} |
1272 |
|
1273 |
/* This handles the ugly work of converting the saved cursor background from |
1274 |
the pixel format of the shadow surface to that of the video surface. |
1275 |
This is only necessary when blitting from a shadow surface of a different |
1276 |
pixel format than the video surface, and using a software rendered cursor. |
1277 |
*/ |
1278 |
static void |
1279 |
SDL_ConvertCursorSave(SDL_Surface * screen, int w, int h) |
1280 |
{ |
1281 |
SDL_VideoDevice *_this = SDL_GetVideoDevice(); |
1282 |
SDL_BlitInfo info; |
1283 |
SDL_loblit RunBlit; |
1284 |
|
1285 |
/* Make sure we can steal the blit mapping */ |
1286 |
if (screen->map->dst != SDL_VideoSurface) { |
1287 |
return; |
1288 |
} |
1289 |
|
1290 |
/* Set up the blit information */ |
1291 |
info.s_pixels = SDL_cursor->save[1]; |
1292 |
info.s_width = w; |
1293 |
info.s_height = h; |
1294 |
info.s_skip = 0; |
1295 |
info.d_pixels = SDL_cursor->save[0]; |
1296 |
info.d_width = w; |
1297 |
info.d_height = h; |
1298 |
info.d_skip = 0; |
1299 |
info.aux_data = screen->map->sw_data->aux_data; |
1300 |
info.src = screen->format; |
1301 |
info.table = screen->map->table; |
1302 |
info.dst = SDL_VideoSurface->format; |
1303 |
RunBlit = screen->map->sw_data->blit; |
1304 |
|
1305 |
/* Run the actual software blit */ |
1306 |
RunBlit(&info); |
1307 |
} |
1308 |
|
1309 |
void |
1310 |
SDL_DrawCursorNoLock(SDL_Surface * screen) |
1311 |
{ |
1312 |
SDL_VideoDevice *_this = SDL_GetVideoDevice(); |
1313 |
SDL_Rect area; |
1314 |
|
1315 |
/* Get the mouse rectangle, clipped to the screen */ |
1316 |
SDL_MouseRect(&area); |
1317 |
if ((area.w == 0) || (area.h == 0)) { |
1318 |
return; |
1319 |
} |
1320 |
|
1321 |
/* Copy mouse background */ |
1322 |
{ |
1323 |
int w, h, screenbpp; |
1324 |
Uint8 *src, *dst; |
1325 |
|
1326 |
/* Set up the copy pointers */ |
1327 |
screenbpp = screen->format->BytesPerPixel; |
1328 |
if ((screen == SDL_VideoSurface) || |
1329 |
FORMAT_EQUAL(screen->format, SDL_VideoSurface->format)) { |
1330 |
dst = SDL_cursor->save[0]; |
1331 |
} else { |
1332 |
dst = SDL_cursor->save[1]; |
1333 |
} |
1334 |
src = (Uint8 *) screen->pixels + area.y * screen->pitch + |
1335 |
area.x * screenbpp; |
1336 |
|
1337 |
/* Perform the copy */ |
1338 |
w = area.w * screenbpp; |
1339 |
h = area.h; |
1340 |
while (h--) { |
1341 |
SDL_memcpy(dst, src, w); |
1342 |
dst += w; |
1343 |
src += screen->pitch; |
1344 |
} |
1345 |
} |
1346 |
|
1347 |
/* Draw the mouse cursor */ |
1348 |
area.x -= SDL_cursor->area.x; |
1349 |
area.y -= SDL_cursor->area.y; |
1350 |
if ((area.x == 0) && (area.w == SDL_cursor->area.w)) { |
1351 |
SDL_DrawCursorFast(screen, &area); |
1352 |
} else { |
1353 |
SDL_DrawCursorSlow(screen, &area); |
1354 |
} |
1355 |
} |
1356 |
|
1357 |
void |
1358 |
SDL_DrawCursor(SDL_Surface * screen) |
1359 |
{ |
1360 |
/* Lock the screen if necessary */ |
1361 |
if (screen == NULL) { |
1362 |
return; |
1363 |
} |
1364 |
if (SDL_MUSTLOCK(screen)) { |
1365 |
if (SDL_LockSurface(screen) < 0) { |
1366 |
return; |
1367 |
} |
1368 |
} |
1369 |
|
1370 |
SDL_DrawCursorNoLock(screen); |
1371 |
|
1372 |
/* Unlock the screen and update if necessary */ |
1373 |
if (SDL_MUSTLOCK(screen)) { |
1374 |
SDL_UnlockSurface(screen); |
1375 |
} |
1376 |
if (screen->flags & SDL_SCREEN_SURFACE) { |
1377 |
SDL_VideoDevice *_this = SDL_GetVideoDevice(); |
1378 |
SDL_Window *window; |
1379 |
SDL_Rect area; |
1380 |
|
1381 |
window = SDL_GetWindowFromSurface(screen); |
1382 |
if (!window) { |
1383 |
return; |
1384 |
} |
1385 |
|
1386 |
SDL_MouseRect(&area); |
1387 |
|
1388 |
if (_this->UpdateWindowSurface) { |
1389 |
_this->UpdateWindowSurface(_this, window, 1, &area); |
1390 |
} |
1391 |
} |
1392 |
} |
1393 |
|
1394 |
void |
1395 |
SDL_EraseCursorNoLock(SDL_Surface * screen) |
1396 |
{ |
1397 |
SDL_VideoDevice *_this = SDL_GetVideoDevice(); |
1398 |
SDL_Window *window; |
1399 |
SDL_Rect area; |
1400 |
|
1401 |
/* Get the window associated with the surface */ |
1402 |
window = SDL_GetWindowFromSurface(screen); |
1403 |
if (!window || !window->surface) { |
1404 |
return; |
1405 |
} |
1406 |
|
1407 |
/* Get the mouse rectangle, clipped to the screen */ |
1408 |
SDL_MouseRect(&area); |
1409 |
if ((area.w == 0) || (area.h == 0)) { |
1410 |
return; |
1411 |
} |
1412 |
|
1413 |
/* Copy mouse background */ |
1414 |
{ |
1415 |
int w, h, screenbpp; |
1416 |
Uint8 *src, *dst; |
1417 |
|
1418 |
/* Set up the copy pointers */ |
1419 |
screenbpp = screen->format->BytesPerPixel; |
1420 |
if ((screen->flags & SDL_SCREEN_SURFACE) || |
1421 |
FORMAT_EQUAL(screen->format, window->surface->format)) { |
1422 |
src = SDL_cursor->save[0]; |
1423 |
} else { |
1424 |
src = SDL_cursor->save[1]; |
1425 |
} |
1426 |
dst = (Uint8 *) screen->pixels + area.y * screen->pitch + |
1427 |
area.x * screenbpp; |
1428 |
|
1429 |
/* Perform the copy */ |
1430 |
w = area.w * screenbpp; |
1431 |
h = area.h; |
1432 |
while (h--) { |
1433 |
SDL_memcpy(dst, src, w); |
1434 |
src += w; |
1435 |
dst += screen->pitch; |
1436 |
} |
1437 |
|
1438 |
/* Perform pixel conversion on cursor background */ |
1439 |
if (src > SDL_cursor->save[1]) { |
1440 |
SDL_ConvertCursorSave(screen, area.w, area.h); |
1441 |
} |
1442 |
} |
1443 |
} |
1444 |
|
1445 |
void |
1446 |
SDL_EraseCursor(SDL_Surface * screen) |
1447 |
{ |
1448 |
/* Lock the screen if necessary */ |
1449 |
if (screen == NULL) { |
1450 |
return; |
1451 |
} |
1452 |
if (SDL_MUSTLOCK(screen)) { |
1453 |
if (SDL_LockSurface(screen) < 0) { |
1454 |
return; |
1455 |
} |
1456 |
} |
1457 |
|
1458 |
SDL_EraseCursorNoLock(screen); |
1459 |
|
1460 |
/* Unlock the screen and update if necessary */ |
1461 |
if (SDL_MUSTLOCK(screen)) { |
1462 |
SDL_UnlockSurface(screen); |
1463 |
} |
1464 |
if (screen->flags & SDL_SCREEN_SURFACE) { |
1465 |
SDL_VideoDevice *_this = SDL_GetVideoDevice(); |
1466 |
SDL_Window *window; |
1467 |
SDL_Rect area; |
1468 |
|
1469 |
window = SDL_GetWindowFromSurface(screen); |
1470 |
if (!window) { |
1471 |
return; |
1472 |
} |
1473 |
|
1474 |
SDL_MouseRect(&area); |
1475 |
|
1476 |
if (_this->UpdateWindowSurface) { |
1477 |
_this->UpdateWindowSurface(_this, window, 1, &area); |
1478 |
} |
1479 |
} |
1480 |
} |
1481 |
|
1482 |
/* Reset the cursor on video mode change |
1483 |
FIXME: Keep track of all cursors, and reset them all. |
1484 |
*/ |
1485 |
void |
1486 |
SDL_ResetCursor(void) |
1487 |
{ |
1488 |
int savelen; |
1489 |
|
1490 |
if (SDL_cursor) { |
1491 |
savelen = SDL_cursor->area.w * 4 * SDL_cursor->area.h; |
1492 |
SDL_cursor->area.x = 0; |
1493 |
SDL_cursor->area.y = 0; |
1494 |
SDL_memset(SDL_cursor->save[0], 0, savelen); |
1495 |
} |
1496 |
} |
1497 |
#endif |
1498 |
|
1499 |
struct private_yuvhwdata |
1500 |
{ |
1501 |
SDL_SW_YUVTexture *texture; |
1502 |
SDL_Surface *display; |
1503 |
Uint32 display_format; |
1504 |
}; |
1505 |
|
1506 |
SDL_Overlay * |
1507 |
SDL_CreateYUVOverlay(int w, int h, Uint32 format, SDL_Surface * display) |
1508 |
{ |
1509 |
SDL_Overlay *overlay; |
1510 |
Uint32 texture_format; |
1511 |
SDL_SW_YUVTexture *texture; |
1512 |
|
1513 |
if ((display->flags & SDL_OPENGL) == SDL_OPENGL) { |
1514 |
SDL_SetError("YUV overlays are not supported in OpenGL mode"); |
1515 |
return NULL; |
1516 |
} |
1517 |
|
1518 |
if (display != SDL_PublicSurface) { |
1519 |
SDL_SetError("YUV display is only supported on the screen surface"); |
1520 |
return NULL; |
1521 |
} |
1522 |
|
1523 |
switch (format) { |
1524 |
case SDL_YV12_OVERLAY: |
1525 |
texture_format = SDL_PIXELFORMAT_YV12; |
1526 |
break; |
1527 |
case SDL_IYUV_OVERLAY: |
1528 |
texture_format = SDL_PIXELFORMAT_IYUV; |
1529 |
break; |
1530 |
case SDL_YUY2_OVERLAY: |
1531 |
texture_format = SDL_PIXELFORMAT_YUY2; |
1532 |
break; |
1533 |
case SDL_UYVY_OVERLAY: |
1534 |
texture_format = SDL_PIXELFORMAT_UYVY; |
1535 |
break; |
1536 |
case SDL_YVYU_OVERLAY: |
1537 |
texture_format = SDL_PIXELFORMAT_YVYU; |
1538 |
break; |
1539 |
default: |
1540 |
SDL_SetError("Unknown YUV format"); |
1541 |
return NULL; |
1542 |
} |
1543 |
|
1544 |
overlay = (SDL_Overlay *) SDL_malloc(sizeof(*overlay)); |
1545 |
if (!overlay) { |
1546 |
SDL_OutOfMemory(); |
1547 |
return NULL; |
1548 |
} |
1549 |
SDL_zerop(overlay); |
1550 |
|
1551 |
overlay->hwdata = |
1552 |
(struct private_yuvhwdata *) SDL_malloc(sizeof(*overlay->hwdata)); |
1553 |
if (!overlay->hwdata) { |
1554 |
SDL_free(overlay); |
1555 |
SDL_OutOfMemory(); |
1556 |
return NULL; |
1557 |
} |
1558 |
|
1559 |
texture = SDL_SW_CreateYUVTexture(texture_format, w, h); |
1560 |
if (!texture) { |
1561 |
SDL_free(overlay->hwdata); |
1562 |
SDL_free(overlay); |
1563 |
return NULL; |
1564 |
} |
1565 |
overlay->hwdata->texture = texture; |
1566 |
overlay->hwdata->display = NULL; |
1567 |
overlay->hwdata->display_format = SDL_PIXELFORMAT_UNKNOWN; |
1568 |
|
1569 |
overlay->format = format; |
1570 |
overlay->w = w; |
1571 |
overlay->h = h; |
1572 |
if (format == SDL_YV12_OVERLAY || format == SDL_IYUV_OVERLAY) { |
1573 |
overlay->planes = 3; |
1574 |
} else { |
1575 |
overlay->planes = 1; |
1576 |
} |
1577 |
overlay->pitches = texture->pitches; |
1578 |
overlay->pixels = texture->planes; |
1579 |
|
1580 |
return overlay; |
1581 |
} |
1582 |
|
1583 |
int |
1584 |
SDL_LockYUVOverlay(SDL_Overlay * overlay) |
1585 |
{ |
1586 |
SDL_Rect rect; |
1587 |
void *pixels; |
1588 |
int pitch; |
1589 |
|
1590 |
if (!overlay) { |
1591 |
SDL_SetError("Passed a NULL overlay"); |
1592 |
return -1; |
1593 |
} |
1594 |
|
1595 |
rect.x = 0; |
1596 |
rect.y = 0; |
1597 |
rect.w = overlay->w; |
1598 |
rect.h = overlay->h; |
1599 |
|
1600 |
if (SDL_SW_LockYUVTexture(overlay->hwdata->texture, &rect, &pixels, &pitch) < 0) { |
1601 |
return -1; |
1602 |
} |
1603 |
|
1604 |
overlay->pixels[0] = (Uint8 *) pixels; |
1605 |
overlay->pitches[0] = pitch; |
1606 |
switch (overlay->format) { |
1607 |
case SDL_YV12_OVERLAY: |
1608 |
case SDL_IYUV_OVERLAY: |
1609 |
overlay->pitches[1] = pitch / 2; |
1610 |
overlay->pitches[2] = pitch / 2; |
1611 |
overlay->pixels[1] = |
1612 |
overlay->pixels[0] + overlay->pitches[0] * overlay->h; |
1613 |
overlay->pixels[2] = |
1614 |
overlay->pixels[1] + overlay->pitches[1] * overlay->h / 2; |
1615 |
break; |
1616 |
case SDL_YUY2_OVERLAY: |
1617 |
case SDL_UYVY_OVERLAY: |
1618 |
case SDL_YVYU_OVERLAY: |
1619 |
break; |
1620 |
} |
1621 |
return 0; |
1622 |
} |
1623 |
|
1624 |
void |
1625 |
SDL_UnlockYUVOverlay(SDL_Overlay * overlay) |
1626 |
{ |
1627 |
if (!overlay) { |
1628 |
return; |
1629 |
} |
1630 |
|
1631 |
SDL_SW_UnlockYUVTexture(overlay->hwdata->texture); |
1632 |
} |
1633 |
|
1634 |
int |
1635 |
SDL_DisplayYUVOverlay(SDL_Overlay * overlay, SDL_Rect * dstrect) |
1636 |
{ |
1637 |
SDL_Surface *display; |
1638 |
SDL_Rect src_rect; |
1639 |
SDL_Rect dst_rect; |
1640 |
void *pixels; |
1641 |
|
1642 |
if (!overlay || !dstrect) { |
1643 |
SDL_SetError("Passed a NULL overlay or dstrect"); |
1644 |
return -1; |
1645 |
} |
1646 |
|
1647 |
display = overlay->hwdata->display; |
1648 |
if (display != SDL_VideoSurface) { |
1649 |
overlay->hwdata->display = display = SDL_VideoSurface; |
1650 |
overlay->hwdata->display_format = SDL_MasksToPixelFormatEnum( |
1651 |
display->format->BitsPerPixel, |
1652 |
display->format->Rmask, |
1653 |
display->format->Gmask, |
1654 |
display->format->Bmask, |
1655 |
display->format->Amask); |
1656 |
} |
1657 |
|
1658 |
src_rect.x = 0; |
1659 |
src_rect.y = 0; |
1660 |
src_rect.w = overlay->w; |
1661 |
src_rect.h = overlay->h; |
1662 |
|
1663 |
if (!SDL_IntersectRect(&display->clip_rect, dstrect, &dst_rect)) { |
1664 |
return 0; |
1665 |
} |
1666 |
|
1667 |
pixels = (void *)((Uint8 *)display->pixels + |
1668 |
dst_rect.y * display->pitch + |
1669 |
dst_rect.x * display->format->BytesPerPixel); |
1670 |
|
1671 |
if (SDL_SW_CopyYUVToRGB(overlay->hwdata->texture, &src_rect, |
1672 |
overlay->hwdata->display_format, |
1673 |
dst_rect.w, dst_rect.h, |
1674 |
pixels, display->pitch) < 0) { |
1675 |
return -1; |
1676 |
} |
1677 |
SDL_UpdateWindowSurface(SDL_VideoWindow); |
1678 |
return 0; |
1679 |
} |
1680 |
|
1681 |
void |
1682 |
SDL_FreeYUVOverlay(SDL_Overlay * overlay) |
1683 |
{ |
1684 |
if (!overlay) { |
1685 |
return; |
1686 |
} |
1687 |
if (overlay->hwdata) { |
1688 |
if (overlay->hwdata->texture) { |
1689 |
SDL_SW_DestroyYUVTexture(overlay->hwdata->texture); |
1690 |
} |
1691 |
SDL_free(overlay->hwdata); |
1692 |
} |
1693 |
SDL_free(overlay); |
1694 |
} |
1695 |
|
1696 |
void |
1697 |
SDL_GL_SwapBuffers(void) |
1698 |
{ |
1699 |
SDL_GL_SwapWindow(SDL_VideoWindow); |
1700 |
} |
1701 |
|
1702 |
int |
1703 |
SDL_SetGamma(float red, float green, float blue) |
1704 |
{ |
1705 |
SDL_Unsupported(); |
1706 |
return -1; |
1707 |
} |
1708 |
|
1709 |
int |
1710 |
SDL_SetGammaRamp(const Uint16 * red, const Uint16 * green, const Uint16 * blue) |
1711 |
{ |
1712 |
SDL_Unsupported(); |
1713 |
return -1; |
1714 |
} |
1715 |
|
1716 |
int |
1717 |
SDL_GetGammaRamp(Uint16 * red, Uint16 * green, Uint16 * blue) |
1718 |
{ |
1719 |
SDL_Unsupported(); |
1720 |
return -1; |
1721 |
} |
1722 |
|
1723 |
int |
1724 |
SDL_EnableKeyRepeat(int delay, int interval) |
1725 |
{ |
1726 |
return 0; |
1727 |
} |
1728 |
|
1729 |
void |
1730 |
SDL_GetKeyRepeat(int *delay, int *interval) |
1731 |
{ |
1732 |
if (delay) { |
1733 |
*delay = SDL_DEFAULT_REPEAT_DELAY; |
1734 |
} |
1735 |
if (interval) { |
1736 |
*interval = SDL_DEFAULT_REPEAT_INTERVAL; |
1737 |
} |
1738 |
} |
1739 |
|
1740 |
int |
1741 |
SDL_EnableUNICODE(int enable) |
1742 |
{ |
1743 |
int previous = SDL_enabled_UNICODE; |
1744 |
|
1745 |
switch (enable) { |
1746 |
case 1: |
1747 |
SDL_enabled_UNICODE = 1; |
1748 |
SDL_StartTextInput(); |
1749 |
break; |
1750 |
case 0: |
1751 |
SDL_enabled_UNICODE = 0; |
1752 |
SDL_StopTextInput(); |
1753 |
break; |
1754 |
} |
1755 |
return previous; |
1756 |
} |
1757 |
|
1758 |
static Uint32 |
1759 |
SDL_SetTimerCallback(Uint32 interval, void* param) |
1760 |
{ |
1761 |
return ((SDL_OldTimerCallback)param)(interval); |
1762 |
} |
1763 |
|
1764 |
int |
1765 |
SDL_SetTimer(Uint32 interval, SDL_OldTimerCallback callback) |
1766 |
{ |
1767 |
static SDL_TimerID compat_timer; |
1768 |
|
1769 |
if (compat_timer) { |
1770 |
SDL_RemoveTimer(compat_timer); |
1771 |
compat_timer = 0; |
1772 |
} |
1773 |
|
1774 |
if (interval && callback) { |
1775 |
compat_timer = SDL_AddTimer(interval, SDL_SetTimerCallback, callback); |
1776 |
if (!compat_timer) { |
1777 |
return -1; |
1778 |
} |
1779 |
} |
1780 |
return 0; |
1781 |
} |
1782 |
|
1783 |
int |
1784 |
SDL_putenv(const char *_var) |
1785 |
{ |
1786 |
char *ptr = NULL; |
1787 |
char *var = SDL_strdup(_var); |
1788 |
if (var == NULL) { |
1789 |
return -1; /* we don't set errno. */ |
1790 |
} |
1791 |
|
1792 |
ptr = SDL_strchr(var, '='); |
1793 |
if (ptr == NULL) { |
1794 |
SDL_free(var); |
1795 |
return -1; |
1796 |
} |
1797 |
|
1798 |
*ptr = '\0'; /* split the string into name and value. */ |
1799 |
SDL_setenv(var, ptr + 1, 1); |
1800 |
SDL_free(var); |
1801 |
return 0; |
1802 |
} |
1803 |
|
1804 |
/* vi: set ts=4 sw=4 expandtab: */ |