comparison src/video/dga/SDL_dgavideo.c @ 1168:045f186426e1

Dynamically load X11 libraries like we currently do for alsa, esd, etc. This allows you to run an SDL program on a system without Xlib, since it'll just report the x11 target unavailable at runtime.
author Ryan C. Gordon <icculus@icculus.org>
date Sat, 05 Nov 2005 19:53:37 +0000
parents f72cc0c7305f
children 0c105755b110
comparison
equal deleted inserted replaced
1167:435c2e481299 1168:045f186426e1
46 #include "SDL_events_c.h" 46 #include "SDL_events_c.h"
47 #include "SDL_dgavideo.h" 47 #include "SDL_dgavideo.h"
48 #include "SDL_dgamouse_c.h" 48 #include "SDL_dgamouse_c.h"
49 #include "SDL_dgaevents_c.h" 49 #include "SDL_dgaevents_c.h"
50 50
51 /* get function pointers... */
52 #include "../x11/SDL_x11dyn.h"
53
51 /* Initialization/Query functions */ 54 /* Initialization/Query functions */
52 static int DGA_VideoInit(_THIS, SDL_PixelFormat *vformat); 55 static int DGA_VideoInit(_THIS, SDL_PixelFormat *vformat);
53 static SDL_Rect **DGA_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags); 56 static SDL_Rect **DGA_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
54 static SDL_Surface *DGA_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags); 57 static SDL_Surface *DGA_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
55 static int DGA_SetColors(_THIS, int firstcolor, int ncolors, 58 static int DGA_SetColors(_THIS, int firstcolor, int ncolors,
70 73
71 /* DGA driver bootstrap functions */ 74 /* DGA driver bootstrap functions */
72 75
73 static int DGA_Available(void) 76 static int DGA_Available(void)
74 { 77 {
75 const char *display; 78 const char *display = NULL;
76 Display *dpy; 79 Display *dpy = NULL;
77 int available; 80 int available = 0;
78 81
79 /* The driver is available is available if the display is local 82 /* The driver is available is available if the display is local
80 and the DGA 2.0+ extension is available, and we can map mem. 83 and the DGA 2.0+ extension is available, and we can map mem.
81 */ 84 */
82 available = 0; 85 if ( SDL_X11_LoadSymbols() ) {
83 display = NULL; 86 if ( (strncmp(pXDisplayName(display), ":", 1) == 0) ||
84 if ( (strncmp(XDisplayName(display), ":", 1) == 0) || 87 (strncmp(pXDisplayName(display), "unix:", 5) == 0) ) {
85 (strncmp(XDisplayName(display), "unix:", 5) == 0) ) { 88 dpy = pXOpenDisplay(display);
86 dpy = XOpenDisplay(display); 89 if ( dpy ) {
87 if ( dpy ) { 90 int events, errors, major, minor;
88 int events, errors, major, minor; 91
89 92 if ( SDL_NAME(XDGAQueryExtension)(dpy, &events, &errors) &&
90 if ( SDL_NAME(XDGAQueryExtension)(dpy, &events, &errors) && 93 SDL_NAME(XDGAQueryVersion)(dpy, &major, &minor) ) {
91 SDL_NAME(XDGAQueryVersion)(dpy, &major, &minor) ) { 94 int screen;
92 int screen; 95
93 96 screen = DefaultScreen(dpy);
94 screen = DefaultScreen(dpy); 97 if ( (major >= 2) &&
95 if ( (major >= 2) && 98 SDL_NAME(XDGAOpenFramebuffer)(dpy, screen) ) {
96 SDL_NAME(XDGAOpenFramebuffer)(dpy, screen) ) { 99 available = 1;
97 available = 1; 100 SDL_NAME(XDGACloseFramebuffer)(dpy, screen);
98 SDL_NAME(XDGACloseFramebuffer)(dpy, screen); 101 }
99 } 102 }
103 pXCloseDisplay(dpy);
100 } 104 }
101 XCloseDisplay(dpy); 105 }
102 } 106 SDL_X11_UnloadSymbols();
103 } 107 }
104 return(available); 108 return(available);
105 } 109 }
106 110
107 static void DGA_DeleteDevice(SDL_VideoDevice *device) 111 static void DGA_DeleteDevice(SDL_VideoDevice *device)
108 { 112 {
109 free(device->hidden); 113 if (device != NULL) {
110 free(device); 114 free(device->hidden);
115 free(device);
116 SDL_X11_UnloadSymbols();
117 }
111 } 118 }
112 119
113 static SDL_VideoDevice *DGA_CreateDevice(int devindex) 120 static SDL_VideoDevice *DGA_CreateDevice(int devindex)
114 { 121 {
115 SDL_VideoDevice *device; 122 SDL_VideoDevice *device = NULL;
116 123
117 /* Initialize all variables that we clean on shutdown */ 124 /* Initialize all variables that we clean on shutdown */
118 device = (SDL_VideoDevice *)malloc(sizeof(SDL_VideoDevice)); 125 if (SDL_X11_LoadSymbols()) {
119 if ( device ) { 126 device = (SDL_VideoDevice *)malloc(sizeof(SDL_VideoDevice));
120 memset(device, 0, (sizeof *device));
121 device->hidden = (struct SDL_PrivateVideoData *)
122 malloc((sizeof *device->hidden));
123 }
124 if ( (device == NULL) || (device->hidden == NULL) ) {
125 SDL_OutOfMemory();
126 if ( device ) { 127 if ( device ) {
127 free(device); 128 memset(device, 0, (sizeof *device));
128 } 129 device->hidden = (struct SDL_PrivateVideoData *)
129 return(0); 130 malloc((sizeof *device->hidden));
130 } 131 }
131 memset(device->hidden, 0, (sizeof *device->hidden)); 132 if ( (device == NULL) || (device->hidden == NULL) ) {
132 133 SDL_OutOfMemory();
133 /* Set the function pointers */ 134 if ( device ) {
134 device->VideoInit = DGA_VideoInit; 135 free(device);
135 device->ListModes = DGA_ListModes; 136 }
136 device->SetVideoMode = DGA_SetVideoMode; 137 SDL_X11_UnloadSymbols();
137 device->SetColors = DGA_SetColors; 138 return(0);
138 device->UpdateRects = NULL; 139 }
139 device->VideoQuit = DGA_VideoQuit; 140 memset(device->hidden, 0, (sizeof *device->hidden));
140 device->AllocHWSurface = DGA_AllocHWSurface; 141
141 device->CheckHWBlit = DGA_CheckHWBlit; 142 /* Set the function pointers */
142 device->FillHWRect = DGA_FillHWRect; 143 device->VideoInit = DGA_VideoInit;
143 device->SetHWColorKey = NULL; 144 device->ListModes = DGA_ListModes;
144 device->SetHWAlpha = NULL; 145 device->SetVideoMode = DGA_SetVideoMode;
145 device->LockHWSurface = DGA_LockHWSurface; 146 device->SetColors = DGA_SetColors;
146 device->UnlockHWSurface = DGA_UnlockHWSurface; 147 device->UpdateRects = NULL;
147 device->FlipHWSurface = DGA_FlipHWSurface; 148 device->VideoQuit = DGA_VideoQuit;
148 device->FreeHWSurface = DGA_FreeHWSurface; 149 device->AllocHWSurface = DGA_AllocHWSurface;
149 device->SetGammaRamp = DGA_SetGammaRamp; 150 device->CheckHWBlit = DGA_CheckHWBlit;
150 device->GetGammaRamp = NULL; 151 device->FillHWRect = DGA_FillHWRect;
151 device->SetCaption = NULL; 152 device->SetHWColorKey = NULL;
152 device->SetIcon = NULL; 153 device->SetHWAlpha = NULL;
153 device->IconifyWindow = NULL; 154 device->LockHWSurface = DGA_LockHWSurface;
154 device->GrabInput = NULL; 155 device->UnlockHWSurface = DGA_UnlockHWSurface;
155 device->GetWMInfo = NULL; 156 device->FlipHWSurface = DGA_FlipHWSurface;
156 device->InitOSKeymap = DGA_InitOSKeymap; 157 device->FreeHWSurface = DGA_FreeHWSurface;
157 device->PumpEvents = DGA_PumpEvents; 158 device->SetGammaRamp = DGA_SetGammaRamp;
158 159 device->GetGammaRamp = NULL;
159 device->free = DGA_DeleteDevice; 160 device->SetCaption = NULL;
161 device->SetIcon = NULL;
162 device->IconifyWindow = NULL;
163 device->GrabInput = NULL;
164 device->GetWMInfo = NULL;
165 device->InitOSKeymap = DGA_InitOSKeymap;
166 device->PumpEvents = DGA_PumpEvents;
167
168 device->free = DGA_DeleteDevice;
169 }
160 170
161 return device; 171 return device;
162 } 172 }
163 173
164 VideoBootStrap DGA_bootstrap = { 174 VideoBootStrap DGA_bootstrap = {
327 int i, num_modes; 337 int i, num_modes;
328 338
329 /* Open the X11 display */ 339 /* Open the X11 display */
330 display = NULL; /* Get it from DISPLAY environment variable */ 340 display = NULL; /* Get it from DISPLAY environment variable */
331 341
332 DGA_Display = XOpenDisplay(display); 342 DGA_Display = pXOpenDisplay(display);
333 if ( DGA_Display == NULL ) { 343 if ( DGA_Display == NULL ) {
334 SDL_SetError("Couldn't open X11 display"); 344 SDL_SetError("Couldn't open X11 display");
335 return(-1); 345 return(-1);
336 } 346 }
337 347
338 /* Check for the DGA extension */ 348 /* Check for the DGA extension */
339 if ( ! SDL_NAME(XDGAQueryExtension)(DGA_Display, &event_base, &error_base) || 349 if ( ! SDL_NAME(XDGAQueryExtension)(DGA_Display, &event_base, &error_base) ||
340 ! SDL_NAME(XDGAQueryVersion)(DGA_Display, &major_version, &minor_version) ) { 350 ! SDL_NAME(XDGAQueryVersion)(DGA_Display, &major_version, &minor_version) ) {
341 SDL_SetError("DGA extension not available"); 351 SDL_SetError("DGA extension not available");
342 XCloseDisplay(DGA_Display); 352 pXCloseDisplay(DGA_Display);
343 return(-1); 353 return(-1);
344 } 354 }
345 if ( major_version < 2 ) { 355 if ( major_version < 2 ) {
346 SDL_SetError("DGA driver requires DGA 2.0 or newer"); 356 SDL_SetError("DGA driver requires DGA 2.0 or newer");
347 XCloseDisplay(DGA_Display); 357 pXCloseDisplay(DGA_Display);
348 return(-1); 358 return(-1);
349 } 359 }
350 DGA_event_base = event_base; 360 DGA_event_base = event_base;
351 361
352 /* Determine the current screen depth */ 362 /* Determine the current screen depth */
354 { 364 {
355 XPixmapFormatValues *pix_format; 365 XPixmapFormatValues *pix_format;
356 int i, num_formats; 366 int i, num_formats;
357 367
358 vformat->BitsPerPixel = DefaultDepth(DGA_Display, DGA_Screen); 368 vformat->BitsPerPixel = DefaultDepth(DGA_Display, DGA_Screen);
359 pix_format = XListPixmapFormats(DGA_Display, &num_formats); 369 pix_format = pXListPixmapFormats(DGA_Display, &num_formats);
360 if ( pix_format == NULL ) { 370 if ( pix_format == NULL ) {
361 SDL_SetError("Couldn't determine screen formats"); 371 SDL_SetError("Couldn't determine screen formats");
362 XCloseDisplay(DGA_Display); 372 pXCloseDisplay(DGA_Display);
363 return(-1); 373 return(-1);
364 } 374 }
365 for ( i=0; i<num_formats; ++i ) { 375 for ( i=0; i<num_formats; ++i ) {
366 if ( vformat->BitsPerPixel == pix_format[i].depth ) 376 if ( vformat->BitsPerPixel == pix_format[i].depth )
367 break; 377 break;
368 } 378 }
369 if ( i != num_formats ) 379 if ( i != num_formats )
370 vformat->BitsPerPixel = pix_format[i].bits_per_pixel; 380 vformat->BitsPerPixel = pix_format[i].bits_per_pixel;
371 XFree((char *)pix_format); 381 pXFree((char *)pix_format);
372 } 382 }
373 if ( vformat->BitsPerPixel > 8 ) { 383 if ( vformat->BitsPerPixel > 8 ) {
374 vformat->Rmask = visual->red_mask; 384 vformat->Rmask = visual->red_mask;
375 vformat->Gmask = visual->green_mask; 385 vformat->Gmask = visual->green_mask;
376 vformat->Bmask = visual->blue_mask; 386 vformat->Bmask = visual->blue_mask;
377 } 387 }
378 388
379 /* Open access to the framebuffer */ 389 /* Open access to the framebuffer */
380 if ( ! SDL_NAME(XDGAOpenFramebuffer)(DGA_Display, DGA_Screen) ) { 390 if ( ! SDL_NAME(XDGAOpenFramebuffer)(DGA_Display, DGA_Screen) ) {
381 SDL_SetError("Unable to map the video memory"); 391 SDL_SetError("Unable to map the video memory");
382 XCloseDisplay(DGA_Display); 392 pXCloseDisplay(DGA_Display);
383 return(-1); 393 return(-1);
384 } 394 }
385 395
386 /* Query for the list of available video modes */ 396 /* Query for the list of available video modes */
387 modes = SDL_NAME(XDGAQueryModes)(DGA_Display, DGA_Screen, &num_modes); 397 modes = SDL_NAME(XDGAQueryModes)(DGA_Display, DGA_Screen, &num_modes);
397 modes[i].viewportWidth, 407 modes[i].viewportWidth,
398 modes[i].viewportHeight); 408 modes[i].viewportHeight);
399 } 409 }
400 } 410 }
401 UpdateHWInfo(this, modes); 411 UpdateHWInfo(this, modes);
402 XFree(modes); 412 pXFree(modes);
403 413
404 /* Create the hardware surface lock mutex */ 414 /* Create the hardware surface lock mutex */
405 hw_lock = SDL_CreateMutex(); 415 hw_lock = SDL_CreateMutex();
406 if ( hw_lock == NULL ) { 416 if ( hw_lock == NULL ) {
407 SDL_SetError("Unable to create lock mutex"); 417 SDL_SetError("Unable to create lock mutex");
436 Uint8 *surfaces_mem; 446 Uint8 *surfaces_mem;
437 int surfaces_len; 447 int surfaces_len;
438 448
439 /* Free any previous colormap */ 449 /* Free any previous colormap */
440 if ( DGA_colormap ) { 450 if ( DGA_colormap ) {
441 XFreeColormap(DGA_Display, DGA_colormap); 451 pXFreeColormap(DGA_Display, DGA_colormap);
442 DGA_colormap = 0; 452 DGA_colormap = 0;
443 } 453 }
444 454
445 /* Search for a matching video mode */ 455 /* Search for a matching video mode */
446 modes = SDL_NAME(XDGAQueryModes)(DGA_Display, DGA_Screen, &num_modes); 456 modes = SDL_NAME(XDGAQueryModes)(DGA_Display, DGA_Screen, &num_modes);
467 return(NULL); 477 return(NULL);
468 } 478 }
469 479
470 /* Set the video mode */ 480 /* Set the video mode */
471 mode = SDL_NAME(XDGASetMode)(DGA_Display, DGA_Screen, modes[i].num); 481 mode = SDL_NAME(XDGASetMode)(DGA_Display, DGA_Screen, modes[i].num);
472 XFree(modes); 482 pXFree(modes);
473 if ( mode == NULL ) { 483 if ( mode == NULL ) {
474 SDL_SetError("Unable to switch to requested mode"); 484 SDL_SetError("Unable to switch to requested mode");
475 return(NULL); 485 return(NULL);
476 } 486 }
477 DGA_visualClass = mode->mode.visualClass; 487 DGA_visualClass = mode->mode.visualClass;
815 #if 0 825 #if 0
816 printf("Hardware accelerated rectangle fill: %dx%d at %d,%d\n", w, h, x, y); 826 printf("Hardware accelerated rectangle fill: %dx%d at %d,%d\n", w, h, x, y);
817 #endif 827 #endif
818 SDL_NAME(XDGAFillRectangle)(DGA_Display, DGA_Screen, x, y, w, h, color); 828 SDL_NAME(XDGAFillRectangle)(DGA_Display, DGA_Screen, x, y, w, h, color);
819 if ( !(this->screen->flags & SDL_DOUBLEBUF) ) { 829 if ( !(this->screen->flags & SDL_DOUBLEBUF) ) {
820 XFlush(DGA_Display); 830 pXFlush(DGA_Display);
821 } 831 }
822 DGA_AddBusySurface(dst); 832 DGA_AddBusySurface(dst);
823 UNLOCK_DISPLAY(); 833 UNLOCK_DISPLAY();
824 return(0); 834 return(0);
825 } 835 }
857 } else { 867 } else {
858 SDL_NAME(XDGACopyArea)(DGA_Display, DGA_Screen, 868 SDL_NAME(XDGACopyArea)(DGA_Display, DGA_Screen,
859 srcx, srcy, w, h, dstx, dsty); 869 srcx, srcy, w, h, dstx, dsty);
860 } 870 }
861 if ( !(this->screen->flags & SDL_DOUBLEBUF) ) { 871 if ( !(this->screen->flags & SDL_DOUBLEBUF) ) {
862 XFlush(DGA_Display); 872 pXFlush(DGA_Display);
863 } 873 }
864 DGA_AddBusySurface(src); 874 DGA_AddBusySurface(src);
865 DGA_AddBusySurface(dst); 875 DGA_AddBusySurface(dst);
866 UNLOCK_DISPLAY(); 876 UNLOCK_DISPLAY();
867 return(0); 877 return(0);
937 DGA_WaitBusySurfaces(this); 947 DGA_WaitBusySurfaces(this);
938 } 948 }
939 DGA_WaitFlip(this); 949 DGA_WaitFlip(this);
940 SDL_NAME(XDGASetViewport)(DGA_Display, DGA_Screen, 950 SDL_NAME(XDGASetViewport)(DGA_Display, DGA_Screen,
941 0, flip_yoffset[flip_page], XDGAFlipRetrace); 951 0, flip_yoffset[flip_page], XDGAFlipRetrace);
942 XFlush(DGA_Display); 952 pXFlush(DGA_Display);
943 UNLOCK_DISPLAY(); 953 UNLOCK_DISPLAY();
944 was_flipped = 1; 954 was_flipped = 1;
945 flip_page = !flip_page; 955 flip_page = !flip_page;
946 956
947 surface->pixels = flip_address[flip_page]; 957 surface->pixels = flip_address[flip_page];
970 xcmap[i].green = (colors[i].g<<8)|colors[i].g; 980 xcmap[i].green = (colors[i].g<<8)|colors[i].g;
971 xcmap[i].blue = (colors[i].b<<8)|colors[i].b; 981 xcmap[i].blue = (colors[i].b<<8)|colors[i].b;
972 xcmap[i].flags = (DoRed|DoGreen|DoBlue); 982 xcmap[i].flags = (DoRed|DoGreen|DoBlue);
973 } 983 }
974 LOCK_DISPLAY(); 984 LOCK_DISPLAY();
975 XStoreColors(DGA_Display, DGA_colormap, xcmap, ncolors); 985 pXStoreColors(DGA_Display, DGA_colormap, xcmap, ncolors);
976 XSync(DGA_Display, False); 986 pXSync(DGA_Display, False);
977 UNLOCK_DISPLAY(); 987 UNLOCK_DISPLAY();
978 988
979 /* That was easy. :) */ 989 /* That was easy. :) */
980 return(1); 990 return(1);
981 } 991 }
1004 xcmap[i].green = ramp[1*256+c]; 1014 xcmap[i].green = ramp[1*256+c];
1005 xcmap[i].blue = ramp[2*256+c]; 1015 xcmap[i].blue = ramp[2*256+c];
1006 xcmap[i].flags = (DoRed|DoGreen|DoBlue); 1016 xcmap[i].flags = (DoRed|DoGreen|DoBlue);
1007 } 1017 }
1008 LOCK_DISPLAY(); 1018 LOCK_DISPLAY();
1009 XStoreColors(DGA_Display, DGA_colormap, xcmap, ncolors); 1019 pXStoreColors(DGA_Display, DGA_colormap, xcmap, ncolors);
1010 XSync(DGA_Display, False); 1020 pXSync(DGA_Display, False);
1011 UNLOCK_DISPLAY(); 1021 UNLOCK_DISPLAY();
1012 return(0); 1022 return(0);
1013 } 1023 }
1014 1024
1015 void DGA_VideoQuit(_THIS) 1025 void DGA_VideoQuit(_THIS)
1017 int i, j; 1027 int i, j;
1018 1028
1019 if ( DGA_Display ) { 1029 if ( DGA_Display ) {
1020 /* Free colormap, if necessary */ 1030 /* Free colormap, if necessary */
1021 if ( DGA_colormap ) { 1031 if ( DGA_colormap ) {
1022 XFreeColormap(DGA_Display, DGA_colormap); 1032 pXFreeColormap(DGA_Display, DGA_colormap);
1023 DGA_colormap = 0; 1033 DGA_colormap = 0;
1024 } 1034 }
1025 1035
1026 /* Unmap memory and reset video mode */ 1036 /* Unmap memory and reset video mode */
1027 SDL_NAME(XDGACloseFramebuffer)(DGA_Display, DGA_Screen); 1037 SDL_NAME(XDGACloseFramebuffer)(DGA_Display, DGA_Screen);
1057 1067
1058 /* Clean up the memory bucket list */ 1068 /* Clean up the memory bucket list */
1059 DGA_FreeHWSurfaces(this); 1069 DGA_FreeHWSurfaces(this);
1060 1070
1061 /* Close up the display */ 1071 /* Close up the display */
1062 XCloseDisplay(DGA_Display); 1072 pXCloseDisplay(DGA_Display);
1063 } 1073 }
1064 } 1074 }