Mercurial > sdl-ios-xcode
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 } |