e14743d1 |
1 | /* |
2 | SDL - Simple DirectMedia Layer |
3 | Copyright (C) 1997-2009 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 <unistd.h> |
25 | #include <sys/ioctl.h> |
26 | |
27 | #include "SDL_endian.h" |
28 | #include "SDL_timer.h" |
29 | #include "SDL_thread.h" |
30 | #include "SDL_video.h" |
31 | #include "SDL_mouse.h" |
32 | #include "../SDL_sysvideo.h" |
33 | #include "../SDL_pixels_c.h" |
34 | #include "../../events/SDL_events_c.h" |
35 | #include "SDL_ph_video.h" |
36 | #include "SDL_ph_modes_c.h" |
37 | #include "SDL_ph_image_c.h" |
38 | #include "SDL_ph_events_c.h" |
39 | #include "SDL_ph_mouse_c.h" |
40 | #include "SDL_ph_wm_c.h" |
41 | #include "SDL_ph_gl.h" |
42 | #include "SDL_phyuv_c.h" |
43 | #include "../blank_cursor.h" |
44 | |
45 | static int ph_VideoInit(_THIS, SDL_PixelFormat *vformat); |
46 | static SDL_Surface *ph_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags); |
47 | static int ph_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors); |
48 | static void ph_VideoQuit(_THIS); |
49 | static void ph_DeleteDevice(SDL_VideoDevice *device); |
50 | |
51 | static int phstatus=-1; |
52 | |
53 | static int ph_Available(void) |
54 | { |
55 | if (phstatus!=0) |
56 | { |
57 | phstatus=PtInit(NULL); |
58 | if (phstatus==0) |
59 | { |
60 | return 1; |
61 | } |
62 | else |
63 | { |
64 | return 0; |
65 | } |
66 | } |
67 | return 1; |
68 | } |
69 | |
70 | static SDL_VideoDevice* ph_CreateDevice(int devindex) |
71 | { |
72 | SDL_VideoDevice* device; |
73 | |
74 | /* Initialize all variables that we clean on shutdown */ |
75 | device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice)); |
76 | if (device) |
77 | { |
78 | SDL_memset(device, 0, (sizeof *device)); |
79 | device->hidden = (struct SDL_PrivateVideoData*)SDL_malloc((sizeof *device->hidden)); |
80 | device->gl_data = NULL; |
81 | } |
82 | if ((device == NULL) || (device->hidden == NULL)) |
83 | { |
84 | SDL_OutOfMemory(); |
85 | ph_DeleteDevice(device); |
86 | return NULL; |
87 | } |
88 | SDL_memset(device->hidden, 0, (sizeof *device->hidden)); |
89 | |
90 | /* Set the driver flags */ |
91 | device->handles_any_size = 1; |
92 | |
93 | /* Set the function pointers */ |
94 | device->CreateYUVOverlay = ph_CreateYUVOverlay; |
95 | device->VideoInit = ph_VideoInit; |
96 | device->ListModes = ph_ListModes; |
97 | device->SetVideoMode = ph_SetVideoMode; |
98 | device->ToggleFullScreen = ph_ToggleFullScreen; |
99 | device->UpdateMouse = ph_UpdateMouse; |
100 | device->SetColors = ph_SetColors; |
101 | device->UpdateRects = NULL; /* set up in ph_SetupUpdateFunction */ |
102 | device->VideoQuit = ph_VideoQuit; |
103 | device->AllocHWSurface = ph_AllocHWSurface; |
104 | device->CheckHWBlit = ph_CheckHWBlit; |
105 | device->FillHWRect = ph_FillHWRect; |
106 | device->SetHWColorKey = ph_SetHWColorKey; |
107 | device->SetHWAlpha = ph_SetHWAlpha; |
108 | device->LockHWSurface = ph_LockHWSurface; |
109 | device->UnlockHWSurface = ph_UnlockHWSurface; |
110 | device->FlipHWSurface = ph_FlipHWSurface; |
111 | device->FreeHWSurface = ph_FreeHWSurface; |
112 | device->SetCaption = ph_SetCaption; |
113 | device->SetIcon = NULL; |
114 | device->IconifyWindow = ph_IconifyWindow; |
115 | device->GrabInput = ph_GrabInput; |
116 | device->GetWMInfo = ph_GetWMInfo; |
117 | device->FreeWMCursor = ph_FreeWMCursor; |
118 | device->CreateWMCursor = ph_CreateWMCursor; |
119 | device->ShowWMCursor = ph_ShowWMCursor; |
120 | device->WarpWMCursor = ph_WarpWMCursor; |
121 | device->MoveWMCursor = NULL; |
122 | device->CheckMouseMode = ph_CheckMouseMode; |
123 | device->InitOSKeymap = ph_InitOSKeymap; |
124 | device->PumpEvents = ph_PumpEvents; |
125 | |
126 | /* OpenGL support. */ |
127 | #if SDL_VIDEO_OPENGL |
128 | device->GL_MakeCurrent = ph_GL_MakeCurrent; |
129 | device->GL_SwapBuffers = ph_GL_SwapBuffers; |
130 | device->GL_GetAttribute = ph_GL_GetAttribute; |
131 | device->GL_LoadLibrary = ph_GL_LoadLibrary; |
132 | device->GL_GetProcAddress = ph_GL_GetProcAddress; |
133 | #endif /* SDL_VIDEO_OPENGL */ |
134 | |
135 | device->free = ph_DeleteDevice; |
136 | |
137 | return device; |
138 | } |
139 | |
140 | VideoBootStrap ph_bootstrap = { |
141 | "photon", "QNX Photon video output", |
142 | ph_Available, ph_CreateDevice |
143 | }; |
144 | |
145 | static void ph_DeleteDevice(SDL_VideoDevice *device) |
146 | { |
147 | if (device) |
148 | { |
149 | if (device->hidden) |
150 | { |
151 | SDL_free(device->hidden); |
152 | device->hidden = NULL; |
153 | } |
154 | if (device->gl_data) |
155 | { |
156 | SDL_free(device->gl_data); |
157 | device->gl_data = NULL; |
158 | } |
159 | SDL_free(device); |
160 | device = NULL; |
161 | } |
162 | } |
163 | |
164 | static PtWidget_t *ph_CreateWindow(_THIS) |
165 | { |
166 | PtWidget_t *widget; |
167 | |
168 | widget = PtCreateWidget(PtWindow, NULL, 0, NULL); |
169 | |
170 | return widget; |
171 | } |
172 | |
173 | static int ph_SetupWindow(_THIS, int w, int h, int flags) |
174 | { |
175 | PtArg_t args[32]; |
176 | PhPoint_t pos = {0, 0}; |
177 | PhDim_t* olddim; |
178 | PhDim_t dim = {w, h}; |
179 | PhRect_t desktopextent; |
180 | int nargs = 0; |
181 | const char* windowpos; |
182 | const char* iscentered; |
183 | int x, y; |
184 | |
185 | /* check if window size has been changed by Window Manager */ |
186 | PtGetResource(window, Pt_ARG_DIM, &olddim, 0); |
187 | if ((olddim->w!=w) || (olddim->h!=h)) |
188 | { |
189 | PtSetArg(&args[nargs++], Pt_ARG_DIM, &dim, 0); |
190 | } |
191 | |
192 | if ((flags & SDL_RESIZABLE) == SDL_RESIZABLE) |
193 | { |
194 | PtSetArg(&args[nargs++], Pt_ARG_WINDOW_MANAGED_FLAGS, Pt_FALSE, Ph_WM_CLOSE); |
195 | PtSetArg(&args[nargs++], Pt_ARG_WINDOW_MANAGED_FLAGS, Pt_TRUE, Ph_WM_MAX | Ph_WM_RESTORE | Ph_WM_RESIZE); |
196 | PtSetArg(&args[nargs++], Pt_ARG_WINDOW_NOTIFY_FLAGS, Pt_TRUE, Ph_WM_RESIZE | Ph_WM_MOVE | Ph_WM_CLOSE | Ph_WM_MAX | Ph_WM_RESTORE); |
197 | PtSetArg(&args[nargs++], Pt_ARG_WINDOW_RENDER_FLAGS, Pt_TRUE, Ph_WM_RENDER_RESIZE | Ph_WM_RENDER_MAX | Ph_WM_RENDER_COLLAPSE | Ph_WM_RENDER_RETURN); |
198 | PtSetArg(&args[nargs++], Pt_ARG_RESIZE_FLAGS, Pt_TRUE, Pt_RESIZE_XY_AS_REQUIRED); |
199 | } |
200 | else |
201 | { |
202 | PtSetArg(&args[nargs++], Pt_ARG_WINDOW_MANAGED_FLAGS, Pt_FALSE, Ph_WM_RESIZE | Ph_WM_MAX | Ph_WM_RESTORE | Ph_WM_CLOSE); |
203 | PtSetArg(&args[nargs++], Pt_ARG_WINDOW_NOTIFY_FLAGS, Pt_FALSE, Ph_WM_RESIZE | Ph_WM_MAX | Ph_WM_RESTORE); |
204 | PtSetArg(&args[nargs++], Pt_ARG_WINDOW_NOTIFY_FLAGS, Pt_TRUE, Ph_WM_MOVE | Ph_WM_CLOSE); |
205 | PtSetArg(&args[nargs++], Pt_ARG_WINDOW_RENDER_FLAGS, Pt_FALSE, Ph_WM_RENDER_RESIZE | Ph_WM_RENDER_MAX | Ph_WM_RENDER_COLLAPSE | Ph_WM_RENDER_RETURN); |
206 | PtSetArg(&args[nargs++], Pt_ARG_RESIZE_FLAGS, Pt_FALSE, Pt_RESIZE_XY_AS_REQUIRED); |
207 | } |
208 | |
209 | if (((flags & SDL_NOFRAME)==SDL_NOFRAME) || ((flags & SDL_FULLSCREEN)==SDL_FULLSCREEN)) |
210 | { |
211 | if ((flags & SDL_RESIZABLE) != SDL_RESIZABLE) |
212 | { |
213 | PtSetArg(&args[nargs++], Pt_ARG_WINDOW_RENDER_FLAGS, Pt_FALSE, Pt_TRUE); |
214 | } |
215 | else |
216 | { |
217 | PtSetArg(&args[nargs++], Pt_ARG_WINDOW_RENDER_FLAGS, Pt_FALSE, Pt_TRUE); |
218 | PtSetArg(&args[nargs++], Pt_ARG_WINDOW_RENDER_FLAGS, Pt_TRUE, Ph_WM_RENDER_RESIZE | Ph_WM_RENDER_BORDER); |
219 | } |
220 | } |
221 | else |
222 | { |
223 | PtSetArg(&args[nargs++], Pt_ARG_WINDOW_RENDER_FLAGS, Pt_TRUE, Ph_WM_RENDER_BORDER | Ph_WM_RENDER_TITLE | |
224 | Ph_WM_RENDER_CLOSE | Ph_WM_RENDER_MENU | Ph_WM_RENDER_MIN); |
225 | } |
226 | |
227 | if ((flags & SDL_FULLSCREEN) == SDL_FULLSCREEN) |
228 | { |
229 | PtSetArg(&args[nargs++], Pt_ARG_POS, &pos, 0); |
230 | PtSetArg(&args[nargs++], Pt_ARG_BASIC_FLAGS, Pt_TRUE, Pt_BASIC_PREVENT_FILL); |
231 | PtSetArg(&args[nargs++], Pt_ARG_WINDOW_MANAGED_FLAGS, Pt_TRUE, Ph_WM_FFRONT | Ph_WM_MAX | Ph_WM_TOFRONT | Ph_WM_CONSWITCH); |
232 | PtSetArg(&args[nargs++], Pt_ARG_WINDOW_STATE, Pt_TRUE, Ph_WM_STATE_ISFRONT | Ph_WM_STATE_ISFOCUS | Ph_WM_STATE_ISALTKEY); |
233 | } |
234 | else |
235 | { |
236 | PtSetArg(&args[nargs++], Pt_ARG_WINDOW_MANAGED_FLAGS, Pt_FALSE, Ph_WM_FFRONT | Ph_WM_CONSWITCH); |
237 | PtSetArg(&args[nargs++], Pt_ARG_WINDOW_STATE, Pt_FALSE, Ph_WM_STATE_ISFRONT); |
238 | PtSetArg(&args[nargs++], Pt_ARG_WINDOW_STATE, Pt_TRUE, Ph_WM_STATE_ISALTKEY); |
239 | |
240 | if ((flags & SDL_HWSURFACE) == SDL_HWSURFACE) |
241 | { |
242 | PtSetArg(&args[nargs++], Pt_ARG_BASIC_FLAGS, Pt_TRUE, Pt_BASIC_PREVENT_FILL); |
243 | } |
244 | else |
245 | { |
246 | PtSetArg(&args[nargs++], Pt_ARG_FILL_COLOR, Pg_BLACK, 0); |
247 | } |
248 | if (!currently_maximized) |
249 | { |
250 | windowpos = SDL_getenv("SDL_VIDEO_WINDOW_POS"); |
251 | iscentered = SDL_getenv("SDL_VIDEO_CENTERED"); |
252 | |
253 | if ((iscentered) || ((windowpos) && (SDL_strcmp(windowpos, "center")==0))) |
254 | { |
255 | PhWindowQueryVisible(Ph_QUERY_CONSOLE, 0, 0, &desktopextent); |
256 | if (desktop_mode.width>w) |
257 | { |
258 | pos.x = (desktop_mode.width - w)/2; |
259 | } |
260 | if (desktop_mode.height>h) |
261 | { |
262 | pos.y = (desktop_mode.height - h)/2; |
263 | } |
264 | |
265 | pos.x+=desktopextent.ul.x; |
266 | pos.y+=desktopextent.ul.y; |
267 | PtSetArg(&args[nargs++], Pt_ARG_POS, &pos, 0); |
268 | } |
269 | else |
270 | { |
271 | if (windowpos) |
272 | { |
273 | if (SDL_sscanf(windowpos, "%d,%d", &x, &y) == 2) |
274 | { |
275 | if ((x<desktop_mode.width) && (y<desktop_mode.height)) |
276 | { |
277 | PhWindowQueryVisible(Ph_QUERY_CONSOLE, 0, 0, &desktopextent); |
278 | pos.x=x+desktopextent.ul.x; |
279 | pos.y=y+desktopextent.ul.y; |
280 | } |
281 | PtSetArg(&args[nargs++], Pt_ARG_POS, &pos, 0); |
282 | } |
283 | } |
284 | } |
285 | } |
286 | |
287 | /* if window is maximized render it as maximized */ |
288 | if (currently_maximized) |
289 | { |
290 | PtSetArg(&args[nargs++], Pt_ARG_WINDOW_STATE, Pt_TRUE, Ph_WM_STATE_ISMAX); |
291 | } |
292 | else |
293 | { |
294 | PtSetArg(&args[nargs++], Pt_ARG_WINDOW_STATE, Pt_FALSE, Ph_WM_STATE_ISMAX); |
295 | } |
296 | |
297 | /* do not grab the keyboard by default */ |
298 | PtSetArg(&args[nargs++], Pt_ARG_WINDOW_STATE, Pt_FALSE, Ph_WM_STATE_ISALTKEY); |
299 | |
300 | /* bring the focus to the window */ |
301 | PtSetArg(&args[nargs++], Pt_ARG_WINDOW_STATE, Pt_TRUE, Ph_WM_STATE_ISFOCUS); |
302 | |
303 | /* allow to catch hide event */ |
304 | PtSetArg(&args[nargs++], Pt_ARG_WINDOW_MANAGED_FLAGS, Pt_TRUE, Ph_WM_HIDE); |
305 | PtSetArg(&args[nargs++], Pt_ARG_WINDOW_NOTIFY_FLAGS, Pt_TRUE, Ph_WM_HIDE); |
306 | } |
307 | |
308 | PtSetResources(window, nargs, args); |
309 | PtRealizeWidget(window); |
310 | PtWindowToFront(window); |
311 | |
312 | #if 0 /* FIXME */ |
313 | PtGetResource(window, Pt_ARG_POS, &olddim, 0); |
314 | fprintf(stderr, "POSITION: %d, %d\n", olddim->w, olddim->h); |
315 | #endif |
316 | |
317 | return 0; |
318 | } |
319 | |
320 | static const struct ColourMasks* ph_GetColourMasks(int bpp) |
321 | { |
322 | /* The alpha mask doesn't appears to be needed */ |
323 | static const struct ColourMasks phColorMasks[5] = { |
324 | /* 8 bit */ {0, 0, 0, 0, 8}, |
325 | /* 15 bit ARGB */ {0x7C00, 0x03E0, 0x001F, 0x8000, 15}, |
326 | /* 16 bit RGB */ {0xF800, 0x07E0, 0x001F, 0x0000, 16}, |
327 | /* 24 bit RGB */ {0xFF0000, 0x00FF00, 0x0000FF, 0x000000, 24}, |
328 | /* 32 bit ARGB */ {0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000, 32}, |
329 | }; |
330 | |
331 | switch (bpp) |
332 | { |
333 | case 8: |
334 | return &phColorMasks[0]; |
335 | case 15: |
336 | return &phColorMasks[1]; |
337 | case 16: |
338 | return &phColorMasks[2]; |
339 | case 24: |
340 | return &phColorMasks[3]; |
341 | case 32: |
342 | return &phColorMasks[4]; |
343 | } |
344 | return NULL; |
345 | } |
346 | |
347 | static int ph_VideoInit(_THIS, SDL_PixelFormat* vformat) |
348 | { |
349 | PgHWCaps_t hwcaps; |
350 | int i; |
351 | |
352 | window=NULL; |
353 | desktoppal=SDLPH_PAL_NONE; |
354 | |
355 | #if SDL_VIDEO_OPENGL |
356 | oglctx=NULL; |
357 | oglbuffers=NULL; |
358 | oglflags=0; |
359 | oglbpp=0; |
360 | #endif |
361 | |
362 | old_video_mode=-1; |
363 | old_refresh_rate=-1; |
364 | |
365 | if (NULL == (phevent = SDL_malloc(EVENT_SIZE))) |
366 | { |
367 | SDL_OutOfMemory(); |
368 | return -1; |
369 | } |
370 | SDL_memset(phevent, 0x00, EVENT_SIZE); |
371 | |
372 | window = ph_CreateWindow(this); |
373 | if (window == NULL) |
374 | { |
375 | SDL_SetError("ph_VideoInit(): Couldn't create video window !\n"); |
376 | return -1; |
377 | } |
378 | |
379 | /* Create the blank cursor */ |
380 | SDL_BlankCursor = this->CreateWMCursor(this, blank_cdata, blank_cmask, |
381 | (int)BLANK_CWIDTH, (int)BLANK_CHEIGHT, |
382 | (int)BLANK_CHOTX, (int)BLANK_CHOTY); |
383 | |
384 | if (SDL_BlankCursor == NULL) |
385 | { |
386 | return -1; |
387 | } |
388 | |
389 | if (PgGetGraphicsHWCaps(&hwcaps) < 0) |
390 | { |
391 | SDL_SetError("ph_VideoInit(): GetGraphicsHWCaps function failed !\n"); |
392 | this->FreeWMCursor(this, SDL_BlankCursor); |
393 | return -1; |
394 | } |
395 | |
396 | if (PgGetVideoModeInfo(hwcaps.current_video_mode, &desktop_mode) < 0) |
397 | { |
398 | SDL_SetError("ph_VideoInit(): PgGetVideoModeInfo function failed !\n"); |
399 | this->FreeWMCursor(this, SDL_BlankCursor); |
400 | return -1; |
401 | } |
402 | |
403 | /* Determine the current screen size */ |
404 | this->info.current_w = desktop_mode.width; |
405 | this->info.current_h = desktop_mode.height; |
406 | |
407 | /* We need to return BytesPerPixel as it in used by CreateRGBsurface */ |
408 | vformat->BitsPerPixel = desktop_mode.bits_per_pixel; |
409 | vformat->BytesPerPixel = desktop_mode.bytes_per_scanline/desktop_mode.width; |
410 | desktopbpp = desktop_mode.bits_per_pixel; |
411 | |
412 | /* save current palette */ |
413 | if (desktopbpp==8) |
414 | { |
415 | PgGetPalette(savedpal); |
416 | PgGetPalette(syspalph); |
417 | } |
418 | else |
419 | { |
420 | for(i=0; i<_Pg_MAX_PALETTE; i++) |
421 | { |
422 | savedpal[i]=PgRGB(0, 0, 0); |
423 | syspalph[i]=PgRGB(0, 0, 0); |
424 | } |
425 | } |
426 | |
427 | currently_fullscreen = 0; |
428 | currently_hided = 0; |
429 | currently_maximized = 0; |
430 | current_overlay = NULL; |
431 | |
432 | OCImage.direct_context = NULL; |
433 | OCImage.offscreen_context = NULL; |
434 | OCImage.offscreen_backcontext = NULL; |
435 | OCImage.oldDC = NULL; |
436 | OCImage.CurrentFrameData = NULL; |
437 | OCImage.FrameData0 = NULL; |
438 | OCImage.FrameData1 = NULL; |
439 | videomode_emulatemode = 0; |
440 | |
441 | this->info.wm_available = 1; |
442 | |
443 | ph_UpdateHWInfo(this); |
444 | |
445 | return 0; |
446 | } |
447 | |
448 | static SDL_Surface* ph_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags) |
449 | { |
450 | const struct ColourMasks* mask; |
451 | |
452 | /* Lock the event thread, in multi-threading environments */ |
453 | SDL_Lock_EventThread(); |
454 | |
455 | current->flags = flags; |
456 | |
457 | /* if we do not have desired fullscreen mode, then fallback into window mode */ |
458 | if (((current->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN) && (ph_GetVideoMode(width, height, bpp)==0)) |
459 | { |
460 | current->flags &= ~SDL_FULLSCREEN; |
461 | current->flags &= ~SDL_NOFRAME; |
462 | current->flags &= ~SDL_RESIZABLE; |
463 | } |
464 | |
465 | ph_SetupWindow(this, width, height, current->flags); |
466 | |
467 | mask = ph_GetColourMasks(bpp); |
468 | if (mask != NULL) |
469 | { |
470 | SDL_ReallocFormat(current, mask->bpp, mask->red, mask->green, mask->blue, 0); |
471 | } |
472 | else |
473 | { |
474 | SDL_SetError("ph_SetVideoMode(): desired bpp is not supported by photon !\n"); |
475 | return NULL; |
476 | } |
477 | |
478 | if ((current->flags & SDL_OPENGL)==SDL_OPENGL) |
479 | { |
480 | #if !SDL_VIDEO_OPENGL |
481 | /* if no built-in OpenGL support */ |
482 | SDL_SetError("ph_SetVideoMode(): no OpenGL support, you need to recompile SDL.\n"); |
483 | current->flags &= ~SDL_OPENGL; |
484 | return NULL; |
485 | #endif /* SDL_VIDEO_OPENGL */ |
486 | } |
487 | else |
488 | { |
489 | /* Initialize internal variables */ |
490 | if ((current->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN) |
491 | { |
492 | if (bpp==8) |
493 | { |
494 | desktoppal=SDLPH_PAL_SYSTEM; |
495 | } |
496 | |
497 | current->flags &= ~SDL_RESIZABLE; /* no resize for Direct Context */ |
498 | current->flags |= SDL_HWSURFACE; |
499 | } |
500 | else |
501 | { |
502 | /* remove this if we'll have support for the non-fullscreen sw/hw+doublebuf one day */ |
503 | current->flags &= ~SDL_DOUBLEBUF; |
504 | |
505 | /* Use offscreen memory if SDL_HWSURFACE flag is set */ |
506 | if ((current->flags & SDL_HWSURFACE) == SDL_HWSURFACE) |
507 | { |
508 | if (desktopbpp!=bpp) |
509 | { |
510 | current->flags &= ~SDL_HWSURFACE; |
511 | } |
512 | } |
513 | |
514 | /* using palette emulation code in window mode */ |
515 | if (bpp==8) |
516 | { |
517 | if (desktopbpp>=15) |
518 | { |
519 | desktoppal = SDLPH_PAL_EMULATE; |
520 | } |
521 | else |
522 | { |
523 | desktoppal = SDLPH_PAL_SYSTEM; |
524 | } |
525 | } |
526 | else |
527 | { |
528 | desktoppal = SDLPH_PAL_NONE; |
529 | } |
530 | } |
531 | } |
532 | |
533 | current->w = width; |
534 | current->h = height; |
535 | |
536 | if (desktoppal==SDLPH_PAL_SYSTEM) |
537 | { |
538 | current->flags|=SDL_HWPALETTE; |
539 | } |
540 | |
541 | /* Must call at least once for setup image planes */ |
542 | if (ph_SetupUpdateFunction(this, current, current->flags)==-1) |
543 | { |
544 | /* Error string was filled in the ph_SetupUpdateFunction() */ |
545 | return NULL; |
546 | } |
547 | |
548 | /* finish window drawing, if we are not in fullscreen, of course */ |
549 | if ((current->flags & SDL_FULLSCREEN) != SDL_FULLSCREEN) |
550 | { |
551 | PtFlush(); |
552 | } |
553 | else |
554 | { |
555 | PgFlush(); |
556 | } |
557 | |
558 | visualbpp=bpp; |
559 | |
560 | ph_UpdateHWInfo(this); |
561 | |
562 | SDL_Unlock_EventThread(); |
563 | |
564 | /* We've done! */ |
565 | return (current); |
566 | } |
567 | |
568 | static void ph_VideoQuit(_THIS) |
569 | { |
570 | /* restore palette */ |
571 | if (desktopbpp==8) |
572 | { |
573 | PgSetPalette(syspalph, 0, -1, 0, 0, 0); |
574 | PgSetPalette(savedpal, 0, 0, _Pg_MAX_PALETTE, Pg_PALSET_GLOBAL | Pg_PALSET_FORCE_EXPOSE, 0); |
575 | PgFlush(); |
576 | } |
577 | |
578 | ph_DestroyImage(this, SDL_VideoSurface); |
579 | |
580 | if (window) |
581 | { |
582 | PtUnrealizeWidget(window); |
583 | PtDestroyWidget(window); |
584 | window=NULL; |
585 | } |
586 | |
587 | if (phevent!=NULL) |
588 | { |
589 | SDL_free(phevent); |
590 | phevent=NULL; |
591 | } |
592 | } |
593 | |
594 | static int ph_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) |
595 | { |
596 | int i; |
597 | SDL_Rect updaterect; |
598 | |
599 | updaterect.x = updaterect.y = 0; |
600 | updaterect.w = this->screen->w; |
601 | updaterect.h = this->screen->h; |
602 | |
603 | /* palette emulation code, using palette of the PhImage_t struct */ |
604 | if (desktoppal==SDLPH_PAL_EMULATE) |
605 | { |
606 | if ((SDL_Image) && (SDL_Image->palette)) |
607 | { |
608 | for (i=firstcolor; i<firstcolor+ncolors; i++) |
609 | { |
610 | syspalph[i] = PgRGB(colors[i-firstcolor].r, colors[i-firstcolor].g, colors[i-firstcolor].b); |
611 | SDL_Image->palette[i] = syspalph[i]; |
612 | } |
613 | |
614 | /* image needs to be redrawn */ |
615 | this->UpdateRects(this, 1, &updaterect); |
616 | } |
617 | } |
618 | else |
619 | { |
620 | if (desktoppal==SDLPH_PAL_SYSTEM) |
621 | { |
622 | for (i=firstcolor; i<firstcolor+ncolors; i++) |
623 | { |
624 | syspalph[i] = PgRGB(colors[i-firstcolor].r, colors[i-firstcolor].g, colors[i-firstcolor].b); |
625 | } |
626 | |
627 | if ((this->screen->flags & SDL_FULLSCREEN) != SDL_FULLSCREEN) |
628 | { |
629 | /* window mode must use soft palette */ |
630 | PgSetPalette(&syspalph[firstcolor], 0, firstcolor, ncolors, Pg_PALSET_GLOBAL, 0); |
631 | /* image needs to be redrawn */ |
632 | this->UpdateRects(this, 1, &updaterect); |
633 | } |
634 | else |
635 | { |
636 | /* fullscreen mode must use hardware palette */ |
637 | PgSetPalette(&syspalph[firstcolor], 0, firstcolor, ncolors, Pg_PALSET_GLOBAL, 0); |
638 | } |
639 | } |
640 | else |
641 | { |
642 | /* SDLPH_PAL_NONE do nothing */ |
643 | } |
644 | } |
645 | |
646 | return 1; |
647 | } |
648 | |