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 (at) 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 649