1 /* 2 SDL - Simple DirectMedia Layer 3 Copyright (C) 1997-2006 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 /* BWindow based framebuffer implementation */ 25 26 #include <unistd.h> 27 28 #include "SDL_BWin.h" 29 #include "SDL_timer.h" 30 31 extern "C" { 32 33 #include "../SDL_sysvideo.h" 34 #include "../../events/SDL_events_c.h" 35 #include "SDL_sysevents_c.h" 36 #include "SDL_sysmouse_c.h" 37 #include "SDL_syswm_c.h" 38 #include "SDL_lowvideo.h" 39 #include "../SDL_yuvfuncs.h" 40 #include "SDL_sysyuv.h" 41 #include "../blank_cursor.h" 42 43 #define BEOS_HIDDEN_SIZE 32 /* starting hidden window size */ 44 45 /* Initialization/Query functions */ 46 static int BE_VideoInit(_THIS, SDL_PixelFormat *vformat); 47 static SDL_Rect **BE_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags); 48 static SDL_Surface *BE_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags); 49 static void BE_UpdateMouse(_THIS); 50 static int BE_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors); 51 static void BE_VideoQuit(_THIS); 52 53 /* Hardware surface functions */ 54 static int BE_AllocHWSurface(_THIS, SDL_Surface *surface); 55 static int BE_LockHWSurface(_THIS, SDL_Surface *surface); 56 static void BE_UnlockHWSurface(_THIS, SDL_Surface *surface); 57 static void BE_FreeHWSurface(_THIS, SDL_Surface *surface); 58 59 static int BE_ToggleFullScreen(_THIS, int fullscreen); 60 static SDL_Overlay *BE_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface *display); 61 62 /* OpenGL functions */ 63 #if SDL_VIDEO_OPENGL 64 static int BE_GL_LoadLibrary(_THIS, const char *path); 65 static void* BE_GL_GetProcAddress(_THIS, const char *proc); 66 static int BE_GL_GetAttribute(_THIS, SDL_GLattr attrib, int* value); 67 static int BE_GL_MakeCurrent(_THIS); 68 static void BE_GL_SwapBuffers(_THIS); 69 #endif 70 71 /* FB driver bootstrap functions */ 72 73 static int BE_Available(void) 74 { 75 return(1); 76 } 77 78 static void BE_DeleteDevice(SDL_VideoDevice *device) 79 { 80 SDL_free(device->hidden); 81 SDL_free(device); 82 } 83 84 static SDL_VideoDevice *BE_CreateDevice(int devindex) 85 { 86 SDL_VideoDevice *device; 87 88 /* Initialize all variables that we clean on shutdown */ 89 device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice)); 90 if ( device ) { 91 SDL_memset(device, 0, (sizeof *device)); 92 device->hidden = (struct SDL_PrivateVideoData *) 93 SDL_malloc((sizeof *device->hidden)); 94 } 95 if ( (device == NULL) || (device->hidden == NULL) ) { 96 SDL_OutOfMemory(); 97 if ( device ) { 98 SDL_free(device); 99 } 100 return(0); 101 } 102 SDL_memset(device->hidden, 0, (sizeof *device->hidden)); 103 104 /* Set the function pointers */ 105 /* Initialization/Query functions */ 106 device->VideoInit = BE_VideoInit; 107 device->ListModes = BE_ListModes; 108 device->SetVideoMode = BE_SetVideoMode; 109 device->ToggleFullScreen = BE_ToggleFullScreen; 110 device->UpdateMouse = BE_UpdateMouse; 111 device->CreateYUVOverlay = BE_CreateYUVOverlay; 112 device->SetColors = BE_SetColors; 113 device->UpdateRects = NULL; 114 device->VideoQuit = BE_VideoQuit; 115 /* Hardware acceleration functions */ 116 device->AllocHWSurface = BE_AllocHWSurface; 117 device->CheckHWBlit = NULL; 118 device->FillHWRect = NULL; 119 device->SetHWColorKey = NULL; 120 device->SetHWAlpha = NULL; 121 device->LockHWSurface = BE_LockHWSurface; 122 device->UnlockHWSurface = BE_UnlockHWSurface; 123 device->FlipHWSurface = NULL; 124 device->FreeHWSurface = BE_FreeHWSurface; 125 /* Gamma support */ 126 #if SDL_VIDEO_OPENGL 127 /* OpenGL support */ 128 device->GL_LoadLibrary = BE_GL_LoadLibrary; 129 device->GL_GetProcAddress = BE_GL_GetProcAddress; 130 device->GL_GetAttribute = BE_GL_GetAttribute; 131 device->GL_MakeCurrent = BE_GL_MakeCurrent; 132 device->GL_SwapBuffers = BE_GL_SwapBuffers; 133 #endif 134 /* Window manager functions */ 135 device->SetCaption = BE_SetWMCaption; 136 device->SetIcon = NULL; 137 device->IconifyWindow = BE_IconifyWindow; 138 device->GrabInput = BE_GrabInput; 139 device->GetWMInfo = BE_GetWMInfo; 140 /* Cursor manager functions */ 141 device->FreeWMCursor = BE_FreeWMCursor; 142 device->CreateWMCursor = BE_CreateWMCursor; 143 device->ShowWMCursor = BE_ShowWMCursor; 144 device->WarpWMCursor = BE_WarpWMCursor; 145 device->MoveWMCursor = NULL; 146 device->CheckMouseMode = BE_CheckMouseMode; 147 /* Event manager functions */ 148 device->InitOSKeymap = BE_InitOSKeymap; 149 device->PumpEvents = BE_PumpEvents; 150 151 device->free = BE_DeleteDevice; 152 153 /* Set the driver flags */ 154 device->handles_any_size = 1; 155 156 return device; 157 } 158 159 VideoBootStrap BWINDOW_bootstrap = { 160 "bwindow", "BDirectWindow graphics", 161 BE_Available, BE_CreateDevice 162 }; 163 164 static inline int ColorSpaceToBitsPerPixel(uint32 colorspace) 165 { 166 int bitsperpixel; 167 168 bitsperpixel = 0; 169 switch (colorspace) { 170 case B_CMAP8: 171 bitsperpixel = 8; 172 break; 173 case B_RGB15: 174 case B_RGBA15: 175 case B_RGB15_BIG: 176 case B_RGBA15_BIG: 177 bitsperpixel = 15; 178 break; 179 case B_RGB16: 180 case B_RGB16_BIG: 181 bitsperpixel = 16; 182 break; 183 case B_RGB32: 184 case B_RGBA32: 185 case B_RGB32_BIG: 186 case B_RGBA32_BIG: 187 bitsperpixel = 32; 188 break; 189 default: 190 break; 191 } 192 return(bitsperpixel); 193 } 194 195 /* Function to sort the display_list in bscreen */ 196 static int CompareModes(const void *A, const void *B) 197 { 198 const display_mode *a = (display_mode *)A; 199 const display_mode *b = (display_mode *)B; 200 201 if ( a->space == b->space ) { 202 return((b->virtual_width*b->virtual_height)- 203 (a->virtual_width*a->virtual_height)); 204 } else { 205 return(ColorSpaceToBitsPerPixel(b->space)- 206 ColorSpaceToBitsPerPixel(a->space)); 207 } 208 } 209 210 /* Yes, this isn't the fastest it could be, but it works nicely */ 211 static int BE_AddMode(_THIS, int index, unsigned int w, unsigned int h) 212 { 213 SDL_Rect *mode; 214 int i; 215 int next_mode; 216 217 /* Check to see if we already have this mode */ 218 if ( SDL_nummodes[index] > 0 ) { 219 for ( i=SDL_nummodes[index]-1; i >= 0; --i ) { 220 mode = SDL_modelist[index][i]; 221 if ( (mode->w == w) && (mode->h == h) ) { 222 #ifdef BWINDOW_DEBUG 223 fprintf(stderr, "We already have mode %dx%d at %d bytes per pixel\n", w, h, index+1); 224 #endif 225 return(0); 226 } 227 } 228 } 229 230 /* Set up the new video mode rectangle */ 231 mode = (SDL_Rect *)SDL_malloc(sizeof *mode); 232 if ( mode == NULL ) { 233 SDL_OutOfMemory(); 234 return(-1); 235 } 236 mode->x = 0; 237 mode->y = 0; 238 mode->w = w; 239 mode->h = h; 240 #ifdef BWINDOW_DEBUG 241 fprintf(stderr, "Adding mode %dx%d at %d bytes per pixel\n", w, h, index+1); 242 #endif 243 244 /* Allocate the new list of modes, and fill in the new mode */ 245 next_mode = SDL_nummodes[index]; 246 SDL_modelist[index] = (SDL_Rect **) 247 SDL_realloc(SDL_modelist[index], (1+next_mode+1)*sizeof(SDL_Rect *)); 248 if ( SDL_modelist[index] == NULL ) { 249 SDL_OutOfMemory(); 250 SDL_nummodes[index] = 0; 251 SDL_free(mode); 252 return(-1); 253 } 254 SDL_modelist[index][next_mode] = mode; 255 SDL_modelist[index][next_mode+1] = NULL; 256 SDL_nummodes[index]++; 257 258 return(0); 259 } 260 261 int BE_VideoInit(_THIS, SDL_PixelFormat *vformat) 262 { 263 display_mode *modes; 264 uint32 i, nmodes; 265 int bpp; 266 BRect bounds; 267 268 /* Initialize the Be Application for appserver interaction */ 269 if ( SDL_InitBeApp() < 0 ) { 270 return(-1); 271 } 272 273 /* It is important that this be created after SDL_InitBeApp() */ 274 BScreen bscreen; 275 276 /* Save the current display mode */ 277 bscreen.GetMode(&saved_mode); 278 _this->info.current_w = saved_mode.virtual_width; 279 _this->info.current_h = saved_mode.virtual_height; 280 281 /* Determine the screen depth */ 282 vformat->BitsPerPixel = ColorSpaceToBitsPerPixel(bscreen.ColorSpace()); 283 if ( vformat->BitsPerPixel == 0 ) { 284 SDL_SetError("Unknown BScreen colorspace: 0x%x", 285 bscreen.ColorSpace()); 286 return(-1); 287 } 288 289 /* Get the video modes we can switch to in fullscreen mode */ 290 bscreen.GetModeList(&modes, &nmodes); 291 SDL_qsort(modes, nmodes, sizeof *modes, CompareModes); 292 for ( i=0; i<nmodes; ++i ) { 293 bpp = ColorSpaceToBitsPerPixel(modes[i].space); 294 //if ( bpp != 0 ) { // There are bugs in changing colorspace 295 if ( modes[i].space == saved_mode.space ) { 296 BE_AddMode(_this, ((bpp+7)/8)-1, 297 modes[i].virtual_width, 298 modes[i].virtual_height); 299 } 300 } 301 302 /* Create the window and view */ 303 bounds.top = 0; bounds.left = 0; 304 bounds.right = BEOS_HIDDEN_SIZE; 305 bounds.bottom = BEOS_HIDDEN_SIZE; 306 SDL_Win = new SDL_BWin(bounds); 307 308 #if SDL_VIDEO_OPENGL 309 /* testgl application doesn't load library, just tries to load symbols */ 310 /* is it correct? if so we have to load library here */ 311 BE_GL_LoadLibrary(_this, NULL); 312 #endif 313 314 /* Create the clear cursor */ 315 SDL_BlankCursor = BE_CreateWMCursor(_this, blank_cdata, blank_cmask, 316 BLANK_CWIDTH, BLANK_CHEIGHT, BLANK_CHOTX, BLANK_CHOTY); 317 318 /* Fill in some window manager capabilities */ 319 _this->info.wm_available = 1; 320 321 /* We're done! */ 322 return(0); 323 } 324 325 /* We support any dimension at our bit-depth */ 326 SDL_Rect **BE_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags) 327 { 328 SDL_Rect **modes; 329 330 modes = ((SDL_Rect **)0); 331 if ( (flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) { 332 modes = SDL_modelist[((format->BitsPerPixel+7)/8)-1]; 333 } else { 334 if ( format->BitsPerPixel == 335 _this->screen->format->BitsPerPixel ) { 336 modes = ((SDL_Rect **)-1); 337 } 338 } 339 return(modes); 340 } 341 342 /* Various screen update functions available */ 343 static void BE_NormalUpdate(_THIS, int numrects, SDL_Rect *rects); 344 345 346 /* Find the closest display mode for fullscreen */ 347 static bool BE_FindClosestFSMode(_THIS, int width, int height, int bpp, 348 display_mode *mode) 349 { 350 BScreen bscreen; 351 uint32 i, nmodes; 352 SDL_Rect **modes; 353 display_mode *dmodes; 354 display_mode current; 355 float current_refresh; 356 bscreen.GetMode(¤t); 357 current_refresh = (1000 * current.timing.pixel_clock) / 358 (current.timing.h_total * current.timing.v_total); 359 360 modes = SDL_modelist[((bpp+7)/8)-1]; 361 for ( i=0; modes[i] && (modes[i]->w > width) && 362 (modes[i]->h > height); ++i ) { 363 /* still looking */ 364 } 365 if ( ! modes[i] || (modes[i]->w < width) || (modes[i]->h < width) ) { 366 --i; /* We went too far */ 367 } 368 369 width = modes[i]->w; 370 height = modes[i]->h; 371 372 bscreen.GetModeList(&dmodes, &nmodes); 373 for ( i = 0; i < nmodes; ++i ) { 374 if ( (bpp == ColorSpaceToBitsPerPixel(dmodes[i].space)) && 375 (width == dmodes[i].virtual_width) && 376 (height == dmodes[i].virtual_height) ) { 377 break; 378 } 379 } 380 if ( i != nmodes ) { 381 *mode = dmodes[i]; 382 if ((mode->virtual_width <= current.virtual_width) && 383 (mode->virtual_height <= current.virtual_height)) { 384 float new_refresh = (1000 * mode->timing.pixel_clock) / 385 (mode->timing.h_total * mode->timing.v_total); 386 if (new_refresh < current_refresh) { 387 mode->timing.pixel_clock = (uint32)((mode->timing.h_total * mode->timing.v_total) 388 * current_refresh / 1000); 389 } 390 } 391 return true; 392 } else { 393 return false; 394 } 395 } 396 397 static int BE_SetFullScreen(_THIS, SDL_Surface *screen, int fullscreen) 398 { 399 int was_fullscreen; 400 bool needs_unlock; 401 BScreen bscreen; 402 BRect bounds; 403 display_mode mode; 404 int width, height, bpp; 405 406 /* Set the fullscreen mode */ 407 was_fullscreen = SDL_Win->IsFullScreen(); 408 SDL_Win->SetFullScreen(fullscreen); 409 fullscreen = SDL_Win->IsFullScreen(); 410 411 width = screen->w; 412 height = screen->h; 413 414 /* Set the appropriate video mode */ 415 if ( fullscreen ) { 416 bpp = screen->format->BitsPerPixel; 417 bscreen.GetMode(&mode); 418 if ( (bpp != ColorSpaceToBitsPerPixel(mode.space)) || 419 (width != mode.virtual_width) || 420 (height != mode.virtual_height)) { 421 if(BE_FindClosestFSMode(_this, width, height, bpp, &mode)) { 422 bscreen.SetMode(&mode); 423 /* This simply stops the next resize event from being 424 * sent to the SDL handler. 425 */ 426 SDL_Win->InhibitResize(); 427 } else { 428 fullscreen = 0; 429 SDL_Win->SetFullScreen(fullscreen); 430 } 431 } 432 } 433 if ( was_fullscreen && ! fullscreen ) { 434 bscreen.SetMode(&saved_mode); 435 } 436 437 if ( SDL_Win->Lock() ) { 438 int cx, cy; 439 if ( SDL_Win->Shown() ) { 440 needs_unlock = 1; 441 SDL_Win->Hide(); 442 } else { 443 needs_unlock = 0; 444 } 445 /* This resizes the window and view area, but inhibits resizing 446 * of the BBitmap due to the InhibitResize call above. Thus the 447 * bitmap (pixel data) never changes. 448 */ 449 SDL_Win->ResizeTo(width, height); 450 bounds = bscreen.Frame(); 451 /* Calculate offsets - used either to center window 452 * (windowed mode) or to set drawing offsets (fullscreen mode) 453 */ 454 cx = (bounds.IntegerWidth() - width)/2; 455 cy = (bounds.IntegerHeight() - height)/2; 456 457 if ( fullscreen ) { 458 /* Set offset for drawing */ 459 SDL_Win->SetXYOffset(cx, cy); 460 } else { 461 SDL_Win->SetXYOffset(0, 0); 462 } 463 if ( ! needs_unlock || was_fullscreen ) { 464 /* Center the window the first time */ 465 SDL_Win->MoveTo(cx, cy); 466 } 467 SDL_Win->Show(); 468 469 /* Unlock the window manually after the first Show() */ 470 if ( needs_unlock ) { 471 SDL_Win->Unlock(); 472 } 473 } 474 475 /* Set the fullscreen flag in the screen surface */ 476 if ( fullscreen ) { 477 screen->flags |= SDL_FULLSCREEN; 478 } else { 479 screen->flags &= ~SDL_FULLSCREEN; 480 } 481 return(1); 482 } 483 484 static int BE_ToggleFullScreen(_THIS, int fullscreen) 485 { 486 return BE_SetFullScreen(_this, _this->screen, fullscreen); 487 } 488 489 /* FIXME: check return values and cleanup here */ 490 SDL_Surface *BE_SetVideoMode(_THIS, SDL_Surface *current, 491 int width, int height, int bpp, Uint32 flags) 492 { 493 BScreen bscreen; 494 BBitmap *bbitmap; 495 BRect bounds; 496 Uint32 gl_flags = 0; 497 498 /* Only RGB works on r5 currently */ 499 gl_flags = BGL_RGB; 500 if (_this->gl_config.double_buffer) 501 gl_flags |= BGL_DOUBLE; 502 else 503 gl_flags |= BGL_SINGLE; 504 if (_this->gl_config.alpha_size > 0 || bpp == 32) 505 gl_flags |= BGL_ALPHA; 506 if (_this->gl_config.depth_size > 0) 507 gl_flags |= BGL_DEPTH; 508 if (_this->gl_config.stencil_size > 0) 509 gl_flags |= BGL_STENCIL; 510 if (_this->gl_config.accum_red_size > 0 511 || _this->gl_config.accum_green_size > 0 512 || _this->gl_config.accum_blue_size > 0 513 || _this->gl_config.accum_alpha_size > 0) 514 gl_flags |= BGL_ACCUM; 515 516 /* Create the view for this window, using found flags */ 517 if ( SDL_Win->CreateView(flags, gl_flags) < 0 ) { 518 return(NULL); 519 } 520 521 current->flags = 0; /* Clear flags */ 522 current->w = width; 523 current->h = height; 524 SDL_Win->SetType(B_TITLED_WINDOW); 525 if ( flags & SDL_NOFRAME ) { 526 current->flags |= SDL_NOFRAME; 527 SDL_Win->SetLook(B_NO_BORDER_WINDOW_LOOK); 528 } else { 529 if ( (flags & SDL_RESIZABLE) && !(flags & SDL_OPENGL) ) { 530 current->flags |= SDL_RESIZABLE; 531 /* We don't want opaque resizing (TM). :-) */ 532 SDL_Win->SetFlags(B_OUTLINE_RESIZE); 533 } else { 534 SDL_Win->SetFlags(B_NOT_RESIZABLE|B_NOT_ZOOMABLE); 535 } 536 } 537 538 if ( flags & SDL_OPENGL ) { 539 current->flags |= SDL_OPENGL; 540 current->pitch = 0; 541 current->pixels = NULL; 542 _this->UpdateRects = NULL; 543 } else { 544 /* Create the BBitmap framebuffer */ 545 bounds.top = 0; bounds.left = 0; 546 bounds.right = width-1; 547 bounds.bottom = height-1; 548 bbitmap = new BBitmap(bounds, bscreen.ColorSpace()); 549 if ( ! bbitmap->IsValid() ) { 550 SDL_SetError("Couldn't create screen bitmap"); 551 delete bbitmap; 552 return(NULL); 553 } 554 current->pitch = bbitmap->BytesPerRow(); 555 current->pixels = (void *)bbitmap->Bits(); 556 SDL_Win->SetBitmap(bbitmap); 557 _this->UpdateRects = BE_NormalUpdate; 558 } 559 560 /* Set the correct fullscreen mode */ 561 BE_SetFullScreen(_this, current, flags & SDL_FULLSCREEN ? 1 : 0); 562 563 /* We're done */ 564 return(current); 565 } 566 567 /* Update the current mouse state and position */ 568 void BE_UpdateMouse(_THIS) 569 { 570 BPoint point; 571 uint32 buttons; 572 573 if ( SDL_Win->Lock() ) { 574 /* Get new input state, if still active */ 575 if ( SDL_Win->IsActive() ) { 576 (SDL_Win->View())->GetMouse(&point, &buttons, true); 577 } else { 578 point.x = -1; 579 point.y = -1; 580 } 581 SDL_Win->Unlock(); 582 583 if ( (point.x >= 0) && (point.x < SDL_VideoSurface->w) && 584 (point.y >= 0) && (point.y < SDL_VideoSurface->h) ) { 585 SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS); 586 SDL_PrivateMouseMotion(0, 0, 587 (Sint16)point.x, (Sint16)point.y); 588 } else { 589 SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS); 590 } 591 } 592 } 593 594 /* We don't actually allow hardware surfaces other than the main one */ 595 static int BE_AllocHWSurface(_THIS, SDL_Surface *surface) 596 { 597 return(-1); 598 } 599 static void BE_FreeHWSurface(_THIS, SDL_Surface *surface) 600 { 601 return; 602 } 603 static int BE_LockHWSurface(_THIS, SDL_Surface *surface) 604 { 605 return(0); 606 } 607 static void BE_UnlockHWSurface(_THIS, SDL_Surface *surface) 608 { 609 return; 610 } 611 612 static void BE_NormalUpdate(_THIS, int numrects, SDL_Rect *rects) 613 { 614 if ( SDL_Win->BeginDraw() ) { 615 int i; 616 617 for ( i=0; i<numrects; ++i ) { 618 BRect rect; 619 620 rect.top = rects[i].y; 621 rect.left = rects[i].x; 622 rect.bottom = rect.top+rects[i].h-1; 623 rect.right = rect.left+rects[i].w-1; 624 SDL_Win->DrawAsync(rect); 625 } 626 SDL_Win->EndDraw(); 627 } 628 } 629 630 #if SDL_VIDEO_OPENGL 631 /* Passing a NULL path means load pointers from the application */ 632 int BE_GL_LoadLibrary(_THIS, const char *path) 633 { 634 if (path == NULL) { 635 if (_this->gl_config.dll_handle == NULL) { 636 image_info info; 637 int32 cookie = 0; 638 while (get_next_image_info(0,&cookie,&info) == B_OK) { 639 void *location = NULL; 640 if (get_image_symbol((image_id)cookie,"glBegin",B_SYMBOL_TYPE_ANY,&location) == B_OK) { 641 _this->gl_config.dll_handle = (void*)cookie; 642 _this->gl_config.driver_loaded = 1; 643 SDL_strlcpy(_this->gl_config.driver_path, "libGL.so", SDL_arraysize(_this->gl_config.driver_path)); 644 } 645 } 646 } 647 } else { 648 /* 649 FIXME None of BeOS libGL.so implementations have exported functions 650 to load BGLView, which should be reloaded from new lib. 651 So for now just "load" linked libGL.so :( 652 */ 653 if (_this->gl_config.dll_handle == NULL) { 654 return BE_GL_LoadLibrary(_this, NULL); 655 } 656 657 /* Unload old first */ 658 /*if (_this->gl_config.dll_handle != NULL) {*/ 659 /* Do not try to unload application itself (if LoadLibrary was called before with NULL ;) */ 660 /* image_info info; 661 if (get_image_info((image_id)_this->gl_config.dll_handle, &info) == B_OK) { 662 if (info.type != B_APP_IMAGE) { 663 unload_add_on((image_id)_this->gl_config.dll_handle); 664 } 665 } 666 667 } 668 669 if ((_this->gl_config.dll_handle = (void*)load_add_on(path)) != (void*)B_ERROR) { 670 _this->gl_config.driver_loaded = 1; 671 SDL_strlcpy(_this->gl_config.driver_path, path, SDL_arraysize(_this->gl_config.driver_path)); 672 }*/ 673 } 674 675 if (_this->gl_config.dll_handle != NULL) { 676 return 0; 677 } else { 678 _this->gl_config.dll_handle = NULL; 679 _this->gl_config.driver_loaded = 0; 680 *_this->gl_config.driver_path = '\0'; 681 return -1; 682 } 683 } 684 685 void* BE_GL_GetProcAddress(_THIS, const char *proc) 686 { 687 if (_this->gl_config.dll_handle != NULL) { 688 void *location = NULL; 689 status_t err; 690 if ((err = get_image_symbol((image_id)_this->gl_config.dll_handle, proc, B_SYMBOL_TYPE_ANY, &location)) == B_OK) { 691 return location; 692 } else { 693 SDL_SetError("Couldn't find OpenGL symbol"); 694 return NULL; 695 } 696 } else { 697 SDL_SetError("OpenGL library not loaded"); 698 return NULL; 699 } 700 } 701 702 int BE_GL_GetAttribute(_THIS, SDL_GLattr attrib, int* value) 703 { 704 /* 705 FIXME? Right now BE_GL_GetAttribute shouldn't be called between glBegin() and glEnd() - it doesn't use "cached" values 706 */ 707 switch (attrib) 708 { 709 case SDL_GL_RED_SIZE: 710 glGetIntegerv(GL_RED_BITS, (GLint*)value); 711 break; 712 case SDL_GL_GREEN_SIZE: 713 glGetIntegerv(GL_GREEN_BITS, (GLint*)value); 714 break; 715 case SDL_GL_BLUE_SIZE: 716 glGetIntegerv(GL_BLUE_BITS, (GLint*)value); 717 break; 718 case SDL_GL_ALPHA_SIZE: 719 glGetIntegerv(GL_ALPHA_BITS, (GLint*)value); 720 break; 721 case SDL_GL_DOUBLEBUFFER: 722 glGetBooleanv(GL_DOUBLEBUFFER, (GLboolean*)value); 723 break; 724 case SDL_GL_BUFFER_SIZE: 725 int v; 726 glGetIntegerv(GL_RED_BITS, (GLint*)&v); 727 *value = v; 728 glGetIntegerv(GL_GREEN_BITS, (GLint*)&v); 729 *value += v; 730 glGetIntegerv(GL_BLUE_BITS, (GLint*)&v); 731 *value += v; 732 glGetIntegerv(GL_ALPHA_BITS, (GLint*)&v); 733 *value += v; 734 break; 735 case SDL_GL_DEPTH_SIZE: 736 glGetIntegerv(GL_DEPTH_BITS, (GLint*)value); /* Mesa creates 16 only? r5 always 32 */ 737 break; 738 case SDL_GL_STENCIL_SIZE: 739 glGetIntegerv(GL_STENCIL_BITS, (GLint*)value); 740 break; 741 case SDL_GL_ACCUM_RED_SIZE: 742 glGetIntegerv(GL_ACCUM_RED_BITS, (GLint*)value); 743 break; 744 case SDL_GL_ACCUM_GREEN_SIZE: 745 glGetIntegerv(GL_ACCUM_GREEN_BITS, (GLint*)value); 746 break; 747 case SDL_GL_ACCUM_BLUE_SIZE: 748 glGetIntegerv(GL_ACCUM_BLUE_BITS, (GLint*)value); 749 break; 750 case SDL_GL_ACCUM_ALPHA_SIZE: 751 glGetIntegerv(GL_ACCUM_ALPHA_BITS, (GLint*)value); 752 break; 753 case SDL_GL_STEREO: 754 case SDL_GL_MULTISAMPLEBUFFERS: 755 case SDL_GL_MULTISAMPLESAMPLES: 756 default: 757 *value=0; 758 return(-1); 759 } 760 return 0; 761 } 762 763 int BE_GL_MakeCurrent(_THIS) 764 { 765 /* FIXME: should we glview->unlock and then glview->lock()? */ 766 return 0; 767 } 768 769 void BE_GL_SwapBuffers(_THIS) 770 { 771 SDL_Win->SwapBuffers(); 772 } 773 #endif 774 775 /* Is the system palette settable? */ 776 int BE_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) 777 { 778 int i; 779 SDL_Palette *palette; 780 const color_map *cmap = BScreen().ColorMap(); 781 782 /* Get the screen colormap */ 783 palette = _this->screen->format->palette; 784 for ( i=0; i<256; ++i ) { 785 palette->colors[i].r = cmap->color_list[i].red; 786 palette->colors[i].g = cmap->color_list[i].green; 787 palette->colors[i].b = cmap->color_list[i].blue; 788 } 789 return(0); 790 } 791 792 void BE_VideoQuit(_THIS) 793 { 794 int i, j; 795 796 SDL_Win->Quit(); 797 SDL_Win = NULL; 798 799 if ( SDL_BlankCursor != NULL ) { 800 BE_FreeWMCursor(_this, SDL_BlankCursor); 801 SDL_BlankCursor = NULL; 802 } 803 for ( i=0; i<NUM_MODELISTS; ++i ) { 804 if ( SDL_modelist[i] ) { 805 for ( j=0; SDL_modelist[i][j]; ++j ) { 806 SDL_free(SDL_modelist[i][j]); 807 } 808 SDL_free(SDL_modelist[i]); 809 SDL_modelist[i] = NULL; 810 } 811 } 812 /* Restore the original video mode */ 813 if ( _this->screen ) { 814 if ( (_this->screen->flags&SDL_FULLSCREEN) == SDL_FULLSCREEN ) { 815 BScreen bscreen; 816 bscreen.SetMode(&saved_mode); 817 } 818 _this->screen->pixels = NULL; 819 } 820 821 #if SDL_VIDEO_OPENGL 822 if (_this->gl_config.dll_handle != NULL) 823 unload_add_on((image_id)_this->gl_config.dll_handle); 824 #endif 825 826 SDL_QuitBeApp(); 827 } 828 829 }; /* Extern C */ 830