comparison src/video/directfb/SDL_DirectFB_video.c @ 2737:140a7edcf2bd

Date: Sun, 31 Aug 2008 17:53:59 +0200 From: Couriersud Subject: Re: Updated DirectFB driver for SDL1.3 attached is a patch which brings the directfb driver in line with current svn. In addition: * driver now is in line with the structure of the X11 driver. This adds a couple of files. * driver now supports relative mouse movements
author Sam Lantinga <slouken@libsdl.org>
date Sun, 31 Aug 2008 16:04:32 +0000
parents 204be4fc2726
children 99210400e8b9
comparison
equal deleted inserted replaced
2736:ae653575d4af 2737:140a7edcf2bd
41 #include "../SDL_sysvideo.h" 41 #include "../SDL_sysvideo.h"
42 #include "../SDL_pixels_c.h" 42 #include "../SDL_pixels_c.h"
43 #include "../../events/SDL_events_c.h" 43 #include "../../events/SDL_events_c.h"
44 #include "SDL_DirectFB_video.h" 44 #include "SDL_DirectFB_video.h"
45 #include "SDL_DirectFB_events.h" 45 #include "SDL_DirectFB_events.h"
46 46 #include "SDL_DirectFB_render.h"
47 /* This is the rect EnumModes2 uses */ 47 #include "SDL_DirectFB_mouse.h"
48 struct DirectFBEnumRect
49 {
50 SDL_Rect r;
51 struct DirectFBEnumRect *next;
52 };
53
54 struct DirectFB_GLContext
55 {
56 IDirectFBGL *context;
57 };
58 48
59 /* Initialization/Query functions */ 49 /* Initialization/Query functions */
60 static int DirectFB_VideoInit(_THIS); 50 static int DirectFB_VideoInit(_THIS);
61 static void DirectFB_VideoQuit(_THIS); 51 static void DirectFB_VideoQuit(_THIS);
62 52
63 static int DirectFB_CreateWindow(_THIS, SDL_Window * window); 53 static int DirectFB_Available(void);
64 static int DirectFB_CreateWindowFrom(_THIS, SDL_Window * window, 54 static SDL_VideoDevice *DirectFB_CreateDevice(int devindex);
65 const void *data);
66 static void DirectFB_SetWindowTitle(_THIS, SDL_Window * window);
67 static void DirectFB_SetWindowPosition(_THIS, SDL_Window * window);
68 static void DirectFB_SetWindowSize(_THIS, SDL_Window * window);
69 static void DirectFB_ShowWindow(_THIS, SDL_Window * window);
70 static void DirectFB_HideWindow(_THIS, SDL_Window * window);
71 static void DirectFB_RaiseWindow(_THIS, SDL_Window * window);
72 static void DirectFB_MaximizeWindow(_THIS, SDL_Window * window);
73 static void DirectFB_MinimizeWindow(_THIS, SDL_Window * window);
74 static void DirectFB_RestoreWindow(_THIS, SDL_Window * window);
75 static void DirectFB_SetWindowGrab(_THIS, SDL_Window * window);
76 static void DirectFB_DestroyWindow(_THIS, SDL_Window * window);
77 static SDL_bool DirectFB_GetWindowWMInfo(_THIS, SDL_Window * window,
78 struct SDL_SysWMinfo *info);
79
80 static void DirectFB_GetDisplayModes(_THIS);
81 static int DirectFB_SetDisplayMode(_THIS, SDL_DisplayMode * mode);
82 55
83 static int DirectFB_SetDisplayGammaRamp(_THIS, Uint16 * ramp); 56 static int DirectFB_SetDisplayGammaRamp(_THIS, Uint16 * ramp);
84 static int DirectFB_GetDisplayGammaRamp(_THIS, Uint16 * ramp); 57 static int DirectFB_GetDisplayGammaRamp(_THIS, Uint16 * ramp);
85 58
86 #if SDL_DIRECTFB_OPENGL 59 VideoBootStrap DirectFB_bootstrap = {
87 static int DirectFB_GL_LoadLibrary(_THIS, const char *path); 60 "directfb", "DirectFB",
88 static void DirectFB_GL_UnloadLibrary(_THIS); 61 DirectFB_Available, DirectFB_CreateDevice
89 static void *DirectFB_GL_GetProcAddress(_THIS, const char *proc); 62 };
90 static SDL_GLContext DirectFB_GL_CreateContext(_THIS, SDL_Window * window);
91 static int DirectFB_GL_MakeCurrent(_THIS, SDL_Window * window,
92 SDL_GLContext context);
93 static int DirectFB_GL_SetSwapInterval(_THIS, int interval);
94 static int DirectFB_GL_GetSwapInterval(_THIS);
95 static void DirectFB_GL_SwapWindow(_THIS, SDL_Window * window);
96 static void DirectFB_GL_DeleteContext(_THIS, SDL_GLContext context);
97
98 #endif
99 63
100 /* DirectFB driver bootstrap functions */ 64 /* DirectFB driver bootstrap functions */
101 65
102 static int 66 static int
103 DirectFB_Available(void) 67 DirectFB_Available(void)
117 { 81 {
118 SDL_VideoDevice *device; 82 SDL_VideoDevice *device;
119 83
120 /* Initialize all variables that we clean on shutdown */ 84 /* Initialize all variables that we clean on shutdown */
121 SDL_DFB_CALLOC(device, 1, sizeof(SDL_VideoDevice)); 85 SDL_DFB_CALLOC(device, 1, sizeof(SDL_VideoDevice));
122 SDL_DFB_CALLOC(device->gl_data, 1, sizeof(*device->gl_data));
123 86
124 /* Set the function pointers */ 87 /* Set the function pointers */
125 88
126 /* Set the function pointers */ 89 /* Set the function pointers */
127 device->VideoInit = DirectFB_VideoInit; 90 device->VideoInit = DirectFB_VideoInit;
171 if (device) 134 if (device)
172 free(device); 135 free(device);
173 return (0); 136 return (0);
174 } 137 }
175 138
176 VideoBootStrap DirectFB_bootstrap = {
177 "directfb", "DirectFB",
178 DirectFB_Available, DirectFB_CreateDevice
179 };
180
181 static DFBEnumerationResult
182 EnumModesCallback(int width, int height, int bpp, void *data)
183 {
184 SDL_VideoDisplay *this = (SDL_VideoDisplay *) data;
185 DFB_DisplayData *dispdata = (DFB_DisplayData *) this->driverdata;
186 SDL_DisplayMode mode;
187
188 mode.w = width;
189 mode.h = height;
190 mode.refresh_rate = 0;
191 mode.driverdata = NULL;
192 mode.format = 0;
193
194 if (dispdata->nummodes < DFB_MAX_MODES) {
195 dispdata->modelist[dispdata->nummodes++] = mode;
196 }
197
198 SDL_DFB_DEBUG("w %d h %d bpp %d\n", width, height, bpp);
199 return DFENUM_OK;
200 }
201
202 static int
203 DFBToSDLPixelFormat(DFBSurfacePixelFormat pixelformat, Uint32 * fmt)
204 {
205 switch (pixelformat) {
206 case DSPF_ALUT44:
207 *fmt = SDL_PIXELFORMAT_INDEX4LSB;
208 break;
209 case DSPF_LUT8:
210 *fmt = SDL_PIXELFORMAT_INDEX8;
211 break;
212 case DSPF_RGB332:
213 *fmt = SDL_PIXELFORMAT_RGB332;
214 break;
215 case DSPF_ARGB4444:
216 *fmt = SDL_PIXELFORMAT_ARGB4444;
217 break;
218 case SDL_PIXELFORMAT_ARGB1555:
219 *fmt = SDL_PIXELFORMAT_ARGB1555;
220 break;
221 case DSPF_RGB16:
222 *fmt = SDL_PIXELFORMAT_RGB565;
223 break;
224 case DSPF_RGB24:
225 *fmt = SDL_PIXELFORMAT_RGB24;
226 break;
227 case DSPF_RGB32:
228 *fmt = SDL_PIXELFORMAT_RGB888;
229 break;
230 case DSPF_ARGB:
231 *fmt = SDL_PIXELFORMAT_ARGB8888;
232 break;
233 case DSPF_YV12:
234 *fmt = SDL_PIXELFORMAT_YV12;
235 break; /* Planar mode: Y + V + U (3 planes) */
236 case DSPF_I420:
237 *fmt = SDL_PIXELFORMAT_IYUV;
238 break; /* Planar mode: Y + U + V (3 planes) */
239 case DSPF_YUY2:
240 *fmt = SDL_PIXELFORMAT_YUY2;
241 break; /* Packed mode: Y0+U0+Y1+V0 (1 plane) */
242 case DSPF_UYVY:
243 *fmt = SDL_PIXELFORMAT_UYVY;
244 break; /* Packed mode: U0+Y0+V0+Y1 (1 plane) */
245 default:
246 return -1;
247 }
248 return 0;
249 }
250
251 static DFBEnumerationResult
252 cbScreens(DFBScreenID screen_id, DFBScreenDescription desc,
253 void *callbackdata)
254 {
255 DFB_DeviceData *devdata = (DFB_DeviceData *) callbackdata;
256
257 devdata->screenid[devdata->numscreens++] = screen_id;
258 return DFENUM_OK;
259 }
260
261 DFBEnumerationResult
262 cbLayers(DFBDisplayLayerID layer_id, DFBDisplayLayerDescription desc,
263 void *callbackdata)
264 {
265 DFB_DeviceData *devdata = (DFB_DeviceData *) callbackdata;
266
267 if (desc.caps & DLCAPS_SURFACE) {
268 if ((desc.type & DLTF_GRAPHICS) && (desc.type & DLTF_VIDEO)) {
269 if (devdata->vidlayer[devdata->aux] == -1)
270 devdata->vidlayer[devdata->aux] = layer_id;
271 } else if (desc.type & DLTF_GRAPHICS) {
272 if (devdata->gralayer[devdata->aux] == -1)
273 devdata->gralayer[devdata->aux] = layer_id;
274 }
275 }
276 return DFENUM_OK;
277 }
278
279 static int 139 static int
280 DirectFB_VideoInit(_THIS) 140 DirectFB_VideoInit(_THIS)
281 { 141 {
282 #if (DIRECTFB_MAJOR_VERSION == 0) && (DIRECTFB_MINOR_VERSION == 9) && (DIRECTFB_MICRO_VERSION < 23)
283 DFBCardCapabilities caps;
284 #else
285 DFBGraphicsDeviceDescription caps;
286 #endif
287 DFBDisplayLayerConfig dlc;
288 struct DirectFBEnumRect *rect;
289 IDirectFB *dfb = NULL; 142 IDirectFB *dfb = NULL;
290 IDirectFBDisplayLayer *layer = NULL;
291
292 SDL_VideoDisplay display;
293 DFB_DisplayData *dispdata;
294 DFB_DeviceData *devdata; 143 DFB_DeviceData *devdata;
295 SDL_DisplayMode mode; 144 char *stemp;
296 int i;
297 DFBResult ret; 145 DFBResult ret;
298 int tcw[DFB_MAX_SCREENS];
299 int tch[DFB_MAX_SCREENS];
300 146
301 SDL_DFB_CHECKERR(DirectFBInit(NULL, NULL)); 147 SDL_DFB_CHECKERR(DirectFBInit(NULL, NULL));
302 SDL_DFB_CHECKERR(DirectFBCreate(&dfb)); 148 SDL_DFB_CHECKERR(DirectFBCreate(&dfb));
303 149
304 SDL_DFB_CALLOC(devdata, 1, sizeof(*devdata)); 150 SDL_DFB_CALLOC(devdata, 1, sizeof(*devdata));
305 devdata->numscreens = 0; 151
306 for (i = 0; i < DFB_MAX_SCREENS; i++) { 152 devdata->use_yuv_underlays = 0; /* default: off */
307 devdata->gralayer[i] = -1; 153 stemp = getenv(DFBENV_USE_YUV_UNDERLAY);
308 devdata->vidlayer[i] = -1; 154 if (stemp)
309 } 155 devdata->use_yuv_underlays = atoi(stemp);
310 SDL_DFB_CHECKERR(dfb->EnumScreens(dfb, &cbScreens, devdata)); 156
311 for (i = 0; i < devdata->numscreens; i++) { 157 /* Create global Eventbuffer for axis events */
312 IDirectFBScreen *screen; 158 SDL_DFB_CHECKERR(dfb->
313 159 CreateInputEventBuffer(dfb, DICAPS_AXES /*DICAPS_ALL */ ,
314 SDL_DFB_CHECKERR(dfb->GetScreen(dfb, devdata->screenid[i], &screen)); 160 DFB_TRUE, &devdata->events));
315
316 devdata->aux = i;
317 SDL_DFB_CHECKERR(screen->EnumDisplayLayers
318 (screen, &cbLayers, devdata));
319 #if (DIRECTFB_MAJOR_VERSION >= 1)
320 screen->GetSize(screen, &tcw[i], &tch[i]);
321 #else
322 /* FIXME: this is only used to center windows
323 * Should be done otherwise, e.g. get surface from layer
324 */
325 tcw[i] = 800;
326 tch[i] = 600;
327 #endif
328 screen->Release(screen);
329 }
330
331 /* Query card capabilities */
332
333 dfb->GetDeviceDescription(dfb, &caps);
334
335 SDL_DFB_DEBUG("SDL directfb video driver - %s %s\n", __DATE__, __TIME__);
336 SDL_DFB_DEBUG("Using %s (%s) driver.\n", caps.name, caps.vendor);
337 SDL_DFB_DEBUG("Found %d screens\n", devdata->numscreens);
338
339 for (i = 0; i < devdata->numscreens; i++) {
340 //SDL_DFB_CHECKERR( dfb->GetDisplayLayer (dfb, DLID_PRIMARY, &layer) );
341 SDL_DFB_CHECKERR(dfb->GetDisplayLayer
342 (dfb, devdata->gralayer[i], &layer));
343 //SDL_DFB_CHECKERR( dfb->CreateInputEventBuffer (dfb, DICAPS_ALL, DFB_FALSE, &events) );
344
345 SDL_DFB_CHECKERR(layer->SetCooperativeLevel
346 (layer, DLSCL_ADMINISTRATIVE));
347 layer->EnableCursor(layer, 1);
348 SDL_DFB_CHECKERR(layer->SetCursorOpacity(layer, 0xC0));
349 SDL_DFB_CHECKERR(layer->SetCooperativeLevel(layer, DLSCL_SHARED));
350
351 /* Query layer configuration to determine the current mode and pixelformat */
352 layer->GetConfiguration(layer, &dlc);
353
354 DFBToSDLPixelFormat(dlc.pixelformat, &mode.format);
355
356 mode.w = dlc.width;
357 mode.h = dlc.height;
358 mode.refresh_rate = 0;
359 mode.driverdata = NULL;
360
361 SDL_DFB_CALLOC(dispdata, 1, sizeof(*dispdata));
362
363 dispdata->layer = layer;
364 dispdata->pixelformat = dlc.pixelformat;
365 dispdata->cw = tcw[i];
366 dispdata->ch = tch[i];
367
368 /* YUV - Video layer */
369
370 dispdata->vidID = devdata->vidlayer[i];
371 dispdata->vidIDinuse = 0;
372
373 SDL_zero(display);
374
375 display.desktop_mode = mode;
376 display.current_mode = mode;
377 display.driverdata = dispdata;
378
379 /* Enumerate the available fullscreen modes */
380 SDL_DFB_CALLOC(dispdata->modelist, DFB_MAX_MODES,
381 sizeof(SDL_DisplayMode));
382 SDL_DFB_CHECKERR(dfb->EnumVideoModes
383 (dfb, EnumModesCallback, &display));
384
385 SDL_AddVideoDisplay(&display);
386 }
387 161
388 devdata->initialized = 1; 162 devdata->initialized = 1;
389 devdata->dfb = dfb; 163 devdata->dfb = dfb;
390 devdata->firstwin = NULL; 164 devdata->firstwin = NULL;
391 165
392 _this->driverdata = devdata; 166 _this->driverdata = devdata;
393 167
168 DirectFB_InitModes(_this);
394 169
395 #if SDL_DIRECTFB_OPENGL 170 #if SDL_DIRECTFB_OPENGL
396 /* Opengl */ 171 DirectFB_GL_Initialize(_this);
397 _this->gl_data->gl_active = 0;
398 _this->gl_data->gl_context = NULL;
399 #endif 172 #endif
400 173
401 DirectFB_AddRenderDriver(_this); 174 DirectFB_AddRenderDriver(_this);
402 DirectFB_InitMouse(_this); 175 DirectFB_InitMouse(_this);
403 DirectFB_InitKeyboard(_this); 176 DirectFB_InitKeyboard(_this);
404 //devdata->mouse = SDL_AddMouse(&mouse, -1); 177
405 178
406 return 0; 179 return 0;
407 180
408 181
409 error: 182 error:
410 //FIXME: Cleanup not complete, Free existing displays
411 SDL_DFB_FREE(dispdata);
412 SDL_DFB_FREE(dispdata->modelist);
413 SDL_DFB_RELEASE(layer);
414 SDL_DFB_RELEASE(dfb); 183 SDL_DFB_RELEASE(dfb);
415 return -1; 184 return -1;
416 } 185 }
417 186
418 static void 187 static void
419 DirectFB_VideoQuit(_THIS) 188 DirectFB_VideoQuit(_THIS)
420 { 189 {
421 DFB_DeviceData *devdata = (DFB_DeviceData *) _this->driverdata; 190 DFB_DeviceData *devdata = (DFB_DeviceData *) _this->driverdata;
422 SDL_DisplayMode tmode; 191
423 DFBResult ret; 192 DirectFB_QuitModes(_this);
424 int i; 193 DirectFB_QuitKeyboard(_this);
425 194 DirectFB_QuitMouse(_this);
426 tmode = _this->displays[0].desktop_mode; 195
427 tmode.format = SDL_PIXELFORMAT_UNKNOWN; 196 SDL_DFB_RELEASE(devdata->events);
428 DirectFB_SetDisplayMode(_this, &tmode);
429 tmode = _this->displays[0].desktop_mode;
430 DirectFB_SetDisplayMode(_this, &tmode);
431
432 for (i = 0; i < devdata->numscreens; i++) {
433 DFB_DisplayData *dispdata =
434 (DFB_DisplayData *) _this->displays[i].driverdata;
435 if (dispdata->layer) {
436 SDL_DFB_CHECK(dispdata->
437 layer->SetCooperativeLevel(dispdata->layer,
438 DLSCL_ADMINISTRATIVE));
439 SDL_DFB_CHECK(dispdata->
440 layer->SetCursorOpacity(dispdata->layer, 0x00));
441 SDL_DFB_CHECK(dispdata->
442 layer->SetCooperativeLevel(dispdata->layer,
443 DLSCL_SHARED));
444 }
445 SDL_DFB_RELEASE(dispdata->layer);
446
447 /* Free video mode list */
448 if (dispdata->modelist) {
449 SDL_free(dispdata->modelist);
450 dispdata->modelist = NULL;
451 }
452 // Done by core
453 //SDL_free(dispdata);
454 }
455
456 SDL_DFB_RELEASE(devdata->dfb); 197 SDL_DFB_RELEASE(devdata->dfb);
457 198 SDL_DFB_FREE(_this->driverdata);
458 SDL_DelMouse(devdata->mouse);
459 SDL_DelKeyboard(devdata->keyboard);
460 199
461 #if SDL_DIRECTFB_OPENGL 200 #if SDL_DIRECTFB_OPENGL
462 DirectFB_GL_UnloadLibrary(_this); 201 DirectFB_GL_Shutdown(_this);
463 #endif 202 #endif
464 203
465 devdata->initialized = 0; 204 devdata->initialized = 0;
466 } 205 }
467 206
468 207 static int
469 static DFBSurfacePixelFormat 208 DirectFB_SetDisplayGammaRamp(_THIS, Uint16 * ramp)
470 SDLToDFBPixelFormat(Uint32 format) 209 {
471 {
472 switch (format) {
473 case SDL_PIXELFORMAT_INDEX4LSB:
474 return DSPF_ALUT44;
475 case SDL_PIXELFORMAT_INDEX8:
476 return DSPF_LUT8;
477 case SDL_PIXELFORMAT_RGB332:
478 return DSPF_RGB332;
479 case SDL_PIXELFORMAT_RGB555:
480 return DSPF_ARGB1555;
481 case SDL_PIXELFORMAT_ARGB4444:
482 return DSPF_ARGB4444;
483 case SDL_PIXELFORMAT_ARGB1555:
484 return DSPF_ARGB1555;
485 case SDL_PIXELFORMAT_RGB565:
486 return DSPF_RGB16;
487 case SDL_PIXELFORMAT_RGB24:
488 return DSPF_RGB24;
489 case SDL_PIXELFORMAT_RGB888:
490 return DSPF_RGB32;
491 case SDL_PIXELFORMAT_ARGB8888:
492 return DSPF_ARGB;
493 case SDL_PIXELFORMAT_YV12:
494 return DSPF_YV12; /* Planar mode: Y + V + U (3 planes) */
495 case SDL_PIXELFORMAT_IYUV:
496 return DSPF_I420; /* Planar mode: Y + U + V (3 planes) */
497 case SDL_PIXELFORMAT_YUY2:
498 return DSPF_YUY2; /* Packed mode: Y0+U0+Y1+V0 (1 plane) */
499 case SDL_PIXELFORMAT_UYVY:
500 return DSPF_UYVY; /* Packed mode: U0+Y0+V0+Y1 (1 plane) */
501 case SDL_PIXELFORMAT_YVYU:
502 return DSPF_UNKNOWN; /* Packed mode: Y0+V0+Y1+U0 (1 plane) */
503 case SDL_PIXELFORMAT_INDEX1LSB:
504 return DSPF_UNKNOWN;
505 case SDL_PIXELFORMAT_INDEX1MSB:
506 return DSPF_UNKNOWN;
507 case SDL_PIXELFORMAT_INDEX4MSB:
508 return DSPF_UNKNOWN;
509 case SDL_PIXELFORMAT_RGB444:
510 return DSPF_UNKNOWN;
511 case SDL_PIXELFORMAT_BGR24:
512 return DSPF_UNKNOWN;
513 case SDL_PIXELFORMAT_BGR888:
514 return DSPF_UNKNOWN;
515 case SDL_PIXELFORMAT_RGBA8888:
516 return DSPF_UNKNOWN;
517 case SDL_PIXELFORMAT_ABGR8888:
518 return DSPF_UNKNOWN;
519 case SDL_PIXELFORMAT_BGRA8888:
520 return DSPF_UNKNOWN;
521 case SDL_PIXELFORMAT_ARGB2101010:
522 return DSPF_UNKNOWN;
523 default:
524 return DSPF_UNKNOWN;
525 }
526 }
527
528 static void
529 CheckSetDisplayMode(_THIS, DFB_DisplayData * data, SDL_DisplayMode * mode)
530 {
531 DFBDisplayLayerConfig config;
532 DFBDisplayLayerConfigFlags failed;
533
534 config.width = mode->w;
535 config.height = mode->h;
536 config.pixelformat = SDLToDFBPixelFormat(mode->format);
537 config.flags = DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT;
538 failed = 0;
539 data->layer->TestConfiguration(data->layer, &config, &failed);
540 if (failed == 0)
541 SDL_AddDisplayMode(_this->current_display, mode);
542
543 }
544
545 static void
546 DirectFB_GetDisplayModes(_THIS)
547 {
548 //SDL_DisplayData *data = (SDL_DisplayData *) SDL_CurrentDisplay.driverdata;
549 //SDL_DisplayMode mode;
550 //SDL_AddDisplayMode(_this->current_display, &mode);
551
552 SDL_DFB_DEVICEDATA(_this);
553 DFB_DisplayData *data = (DFB_DisplayData *) SDL_CurrentDisplay.driverdata;
554 int i;
555 SDL_DisplayMode mode;
556
557 for (i = 0; i < data->nummodes; ++i) {
558 mode = data->modelist[i];
559 //mode.format = SDL_PIXELFORMAT_UNKNOWN;
560
561 mode.format = SDL_PIXELFORMAT_INDEX8;
562 CheckSetDisplayMode(_this, data, &mode);
563 mode.format = SDL_PIXELFORMAT_RGB565;
564 CheckSetDisplayMode(_this, data, &mode);
565 mode.format = SDL_PIXELFORMAT_RGB24;
566 CheckSetDisplayMode(_this, data, &mode);
567 mode.format = SDL_PIXELFORMAT_RGB888;
568 CheckSetDisplayMode(_this, data, &mode);
569 }
570 }
571
572 int
573 DirectFB_SetDisplayMode(_THIS, SDL_DisplayMode * mode)
574 {
575 SDL_DFB_DEVICEDATA(_this);
576 DFB_DisplayData *data = (DFB_DisplayData *) SDL_CurrentDisplay.driverdata;
577 DFBDisplayLayerConfig config, rconfig;
578 DFBDisplayLayerConfigFlags fail = 0;
579 DFBResult ret;
580 DFB_WindowData *win;
581
582 SDL_DFB_CHECKERR(data->layer->SetCooperativeLevel(data->layer,
583 DLSCL_ADMINISTRATIVE));
584
585 SDL_DFB_CHECKERR(data->layer->GetConfiguration(data->layer, &config));
586 config.flags = DLCONF_WIDTH | DLCONF_HEIGHT; // | DLCONF_BUFFERMODE;
587 if (mode->format != SDL_PIXELFORMAT_UNKNOWN) {
588 config.flags |= DLCONF_PIXELFORMAT;
589 config.pixelformat = SDLToDFBPixelFormat(mode->format);
590 data->pixelformat = config.pixelformat;
591 }
592 config.width = mode->w;
593 config.height = mode->h;
594
595 //config.buffermode = DLBM_BACKVIDEO;
596
597 //config.pixelformat = GetFormatForBpp (bpp, HIDDEN->layer);
598
599 data->layer->TestConfiguration(data->layer, &config, &fail);
600 if (fail & (DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT)) {
601 SDL_DFB_DEBUG("Error setting mode %dx%d-%x\n", mode->w, mode->h,
602 mode->format);
603 return -1;
604 }
605 SDL_DFB_DEBUG("Trace\n");
606 config.flags &= ~fail;
607 SDL_DFB_CHECKERR(data->layer->SetConfiguration(data->layer, &config));
608 SDL_DFB_CHECKERR(data->layer->SetCooperativeLevel(data->layer,
609 DLSCL_ADMINISTRATIVE));
610
611 /* Double check */
612 SDL_DFB_CHECKERR(data->layer->GetConfiguration(data->layer, &rconfig));
613
614 if ((config.width != rconfig.width) ||
615 (config.height != rconfig.height) ||
616 ((mode->format != SDL_PIXELFORMAT_UNKNOWN)
617 && (config.pixelformat != rconfig.pixelformat))) {
618 SDL_DFB_DEBUG("Error setting mode %dx%d-%x\n", mode->w, mode->h,
619 mode->format);
620 return -1;
621 }
622
623 data->pixelformat = rconfig.pixelformat;
624 data->cw = config.width;
625 data->ch = config.height;
626 SDL_CurrentDisplay.current_mode = *mode;
627
628 /*
629 * FIXME: video mode switch is currently broken
630 *
631 * DirectFB 1.2.0-rc1 even has a broken cursor after a switch
632 * The following code needs to be revisited whether it is still
633 * needed once the switch works again.
634 */
635
636 win = devdata->firstwin;
637
638 while (win) {
639 SDL_DFB_RELEASE(win->surface);
640 SDL_DFB_CHECKERR(win->window->GetSurface(win->window, &win->surface));
641 win = win->next;
642 }
643
644
645 return 0;
646 error:
647 return -1; 210 return -1;
648 } 211 }
649 212
650 static int 213 static int
651 DirectFB_SetDisplayGammaRamp(_THIS, Uint16 * ramp) 214 DirectFB_GetDisplayGammaRamp(_THIS, Uint16 * ramp)
652 { 215 {
653 return -1; 216 return -1;
654 } 217 }
655
656 static int
657 DirectFB_GetDisplayGammaRamp(_THIS, Uint16 * ramp)
658 {
659 return -1;
660 }
661
662 static int
663 DirectFB_CreateWindow(_THIS, SDL_Window * window)
664 {
665 SDL_DFB_DEVICEDATA(_this);
666 SDL_DFB_DISPLAYDATA(_this, window);
667 DFB_WindowData *windata;
668 DFBWindowOptions wopts;
669 DFBWindowDescription desc;
670 int ret, x, y;
671
672 SDL_DFB_DEBUG("Trace x %d y %d w %d h %d\n", window->x, window->y,
673 window->w, window->h);
674 window->driverdata = NULL;
675 SDL_DFB_CALLOC(window->driverdata, 1, sizeof(DFB_WindowData));
676 windata = (DFB_WindowData *) window->driverdata;
677
678 SDL_DFB_CHECKERR(devdata->
679 dfb->SetCooperativeLevel(devdata->dfb, DFSCL_NORMAL));
680 SDL_DFB_CHECKERR(dispdata->
681 layer->SetCooperativeLevel(dispdata->layer,
682 DLSCL_ADMINISTRATIVE));
683
684 /* Fill the window description. */
685 if (window->x == SDL_WINDOWPOS_CENTERED) {
686 x = (dispdata->cw - window->w) / 2;
687 } else if (window->x == SDL_WINDOWPOS_UNDEFINED) {
688 x = 0;
689 } else {
690 x = window->x;
691 }
692 if (window->y == SDL_WINDOWPOS_CENTERED) {
693 y = (dispdata->ch - window->h) / 2;
694 } else if (window->y == SDL_WINDOWPOS_UNDEFINED) {
695 y = 0;
696 } else {
697 y = window->y;
698 }
699 if (window->flags & SDL_WINDOW_FULLSCREEN) {
700 x = 0;
701 y = 0;
702 }
703
704 desc.flags = DWDESC_WIDTH | DWDESC_HEIGHT /*| DWDESC_CAPS */ | DWDESC_PIXELFORMAT
705 | DWDESC_SURFACE_CAPS;
706
707 #if (DIRECTFB_MAJOR_VERSION == 1) && (DIRECTFB_MINOR_VERSION >= 0)
708 /* Needed for 1.2 */
709 desc.flags |= DWDESC_POSX | DWDESC_POSY;
710 desc.posx = x;
711 desc.posy = y;
712 #else
713 if (!(window->flags & SDL_WINDOW_FULLSCREEN)
714 && window->x != SDL_WINDOWPOS_UNDEFINED
715 && window->y != SDL_WINDOWPOS_UNDEFINED) {
716 desc.flags |= DWDESC_POSX | DWDESC_POSY;
717 desc.posx = x;
718 desc.posy = y;
719 }
720 #endif
721
722 desc.width = window->w;
723 desc.height = window->h;
724 desc.pixelformat = dispdata->pixelformat;
725 desc.caps = 0; // DWCAPS_DOUBLEBUFFER;
726 desc.surface_caps = DSCAPS_DOUBLE | DSCAPS_TRIPLE / DSCAPS_PREMULTIPLIED;
727
728 /* Create the window. */
729 SDL_DFB_CHECKERR(dispdata->layer->CreateWindow(dispdata->layer, &desc,
730 &windata->window));
731
732 windata->window->GetOptions(windata->window, &wopts);
733 #if (DIRECTFB_MAJOR_VERSION == 1) && (DIRECTFB_MINOR_VERSION >= 0)
734
735 if (window->flags & SDL_WINDOW_RESIZABLE)
736 wopts |= DWOP_SCALE;
737 else
738 wopts |= DWOP_KEEP_SIZE;
739 #else
740 wopts |= DWOP_KEEP_SIZE; // if not we will crash ...
741 #endif
742
743 if (window->flags & SDL_WINDOW_FULLSCREEN)
744 wopts |= DWOP_KEEP_POSITION | DWOP_KEEP_STACKING | DWOP_KEEP_SIZE;
745
746 windata->window->SetOptions(windata->window, wopts);
747 /* Get the window's surface. */
748 SDL_DFB_CHECKERR(windata->
749 window->GetSurface(windata->window, &windata->surface));
750 windata->window->SetOpacity(windata->window, 0xFF);
751 SDL_DFB_CHECKERR(windata->window->CreateEventBuffer(windata->window,
752 &
753 (windata->
754 eventbuffer)));
755 SDL_DFB_CHECKERR(windata->window->
756 EnableEvents(windata->window,
757 DWET_POSITION | DWET_SIZE | DWET_CLOSE |
758 DWET_ALL));
759
760 if (window->flags & SDL_WINDOW_FULLSCREEN)
761 windata->window->SetStackingClass(windata->window, DWSC_UPPER);
762 /* Make it the top most window. */
763 windata->window->RaiseToTop(windata->window);
764
765 windata->window->GetID(windata->window, &windata->windowID);
766 windata->id = window->id;
767
768 #if SDL_DIRECTFB_OPENGL
769 if (window->flags & SDL_WINDOW_OPENGL) {
770 if (!_this->gl_config.driver_loaded) {
771 /* no driver has been loaded, use default (ourselves) */
772 if (DirectFB_GL_LoadLibrary(_this, NULL) < 0) {
773 goto error;
774 }
775 }
776 _this->gl_data->gl_active = 1;
777 }
778 #endif
779
780 /* Add to list ... */
781
782 windata->next = devdata->firstwin;
783 windata->opacity = 0xFF;
784 devdata->firstwin = windata;
785
786 //SDL_DFB_CHECKERR( windata->surface->GetPalette(windata->surface, &windata->palette) );
787
788 return 0;
789 error:
790 SDL_DFB_RELEASE(windata->window);
791 SDL_DFB_RELEASE(windata->surface);
792 return -1;
793 }
794
795 static int
796 DirectFB_CreateWindowFrom(_THIS, SDL_Window * window, const void *data)
797 {
798 SDL_DFB_DEVICEDATA(_this);
799 SDL_DFB_WINDOWDATA(window);
800 SDL_DFB_DISPLAYDATA(_this, window);
801
802 SDL_Unsupported();
803 return -1;
804 }
805
806 static void
807 DirectFB_SetWindowTitle(_THIS, SDL_Window * window)
808 {
809 SDL_DFB_DEVICEDATA(_this);
810 SDL_DFB_WINDOWDATA(window);
811 SDL_DFB_DISPLAYDATA(_this, window);
812
813 SDL_Unsupported();
814 //return -1;
815
816 }
817
818 static void
819 DirectFB_SetWindowPosition(_THIS, SDL_Window * window)
820 {
821 SDL_DFB_DEVICEDATA(_this);
822 SDL_DFB_WINDOWDATA(window);
823 SDL_DFB_DISPLAYDATA(_this, window);
824 int x, y;
825
826 if (window->y == SDL_WINDOWPOS_UNDEFINED)
827 y = 0;
828 else
829 y = window->y;
830
831 if (window->x == SDL_WINDOWPOS_UNDEFINED)
832 x = 0;
833 else
834 x = window->x;
835
836 if (window->flags & SDL_WINDOW_FULLSCREEN) {
837 x = 0;
838 y = 0;
839 }
840 //if (!(window->flags & SDL_WINDOW_FULLSCREEN))
841 windata->window->MoveTo(windata->window, x, y);
842 }
843
844 static void
845 DirectFB_SetWindowSize(_THIS, SDL_Window * window)
846 {
847 int ret;
848 SDL_DFB_DEVICEDATA(_this);
849 SDL_DFB_WINDOWDATA(window);
850 SDL_DFB_DISPLAYDATA(_this, window);
851
852 if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
853 int ch, cw;
854
855 // SDL_DFB_DEBUG("Resize %d %d %d %d\n", cw, ch, window->w, window->h);
856 #if (DIRECTFB_MAJOR_VERSION == 1) && (DIRECTFB_MINOR_VERSION >= 0)
857 SDL_DFB_CHECKERR(windata->window->
858 ResizeSurface(windata->window, window->w,
859 window->h));
860 #else
861 SDL_DFB_CHECKERR(windata->window->
862 Resize(windata->window, window->w, window->h));
863 #endif
864 SDL_DFB_CHECKERR(windata->window->GetSize(windata->window, &window->w, &window->h)); /* if a window manager should have decided otherwise */
865 }
866 error:
867 return;
868 }
869
870 static void
871 DirectFB_ShowWindow(_THIS, SDL_Window * window)
872 {
873 SDL_DFB_DEVICEDATA(_this);
874 SDL_DFB_WINDOWDATA(window);
875 SDL_DFB_DISPLAYDATA(_this, window);
876
877 windata->window->SetOpacity(windata->window, windata->opacity);
878
879 }
880
881 static void
882 DirectFB_HideWindow(_THIS, SDL_Window * window)
883 {
884 SDL_DFB_DEVICEDATA(_this);
885 SDL_DFB_WINDOWDATA(window);
886 SDL_DFB_DISPLAYDATA(_this, window);
887
888 windata->window->GetOpacity(windata->window, &windata->opacity);
889 windata->window->SetOpacity(windata->window, 0);
890
891 }
892
893 static void
894 DirectFB_RaiseWindow(_THIS, SDL_Window * window)
895 {
896 SDL_DFB_DEVICEDATA(_this);
897 SDL_DFB_WINDOWDATA(window);
898 SDL_DFB_DISPLAYDATA(_this, window);
899
900 windata->window->Raise(windata->window);
901
902 }
903
904 static void
905 DirectFB_MaximizeWindow(_THIS, SDL_Window * window)
906 {
907 SDL_DFB_DEVICEDATA(_this);
908 SDL_DFB_WINDOWDATA(window);
909 SDL_DFB_DISPLAYDATA(_this, window);
910
911 SDL_Unsupported();
912
913 }
914
915 static void
916 DirectFB_MinimizeWindow(_THIS, SDL_Window * window)
917 {
918 SDL_DFB_DEVICEDATA(_this);
919 SDL_DFB_WINDOWDATA(window);
920 SDL_DFB_DISPLAYDATA(_this, window);
921
922 SDL_Unsupported();
923
924 }
925
926 static void
927 DirectFB_RestoreWindow(_THIS, SDL_Window * window)
928 {
929 SDL_DFB_DEVICEDATA(_this);
930 SDL_DFB_WINDOWDATA(window);
931 SDL_DFB_DISPLAYDATA(_this, window);
932
933 SDL_Unsupported();
934
935 }
936
937 static void
938 DirectFB_SetWindowGrab(_THIS, SDL_Window * window)
939 {
940 SDL_DFB_DEVICEDATA(_this);
941 SDL_DFB_WINDOWDATA(window);
942 SDL_DFB_DISPLAYDATA(_this, window);
943
944 SDL_Unsupported();
945
946 }
947
948 static void
949 DirectFB_DestroyWindow(_THIS, SDL_Window * window)
950 {
951 SDL_DFB_DEVICEDATA(_this);
952 SDL_DFB_WINDOWDATA(window);
953 SDL_DFB_DISPLAYDATA(_this, window);
954 DFB_WindowData *p;
955
956 SDL_DFB_DEBUG("Trace\n");
957
958 SDL_DFB_RELEASE(windata->palette);
959 SDL_DFB_RELEASE(windata->eventbuffer);
960 SDL_DFB_RELEASE(windata->surface);
961 SDL_DFB_RELEASE(windata->window);
962
963 /* Remove from list ... */
964
965 p = devdata->firstwin;
966 while (p && p->next != windata)
967 p = p->next;
968 if (p)
969 p->next = windata->next;
970 else
971 devdata->firstwin = windata->next;
972 SDL_free(windata);
973 }
974
975 static SDL_bool
976 DirectFB_GetWindowWMInfo(_THIS, SDL_Window * window,
977 struct SDL_SysWMinfo *info)
978 {
979 SDL_DFB_DEVICEDATA(_this);
980 SDL_DFB_WINDOWDATA(window);
981 SDL_DFB_DISPLAYDATA(_this, window);
982
983 SDL_Unsupported();
984 return SDL_FALSE;
985 }
986
987 #if SDL_DIRECTFB_OPENGL
988
989 #define OPENGL_REQUIRS_DLOPEN
990 #if defined(OPENGL_REQUIRS_DLOPEN) && defined(SDL_LOADSO_DLOPEN)
991 #include <dlfcn.h>
992 #define GL_LoadObject(X) dlopen(X, (RTLD_NOW|RTLD_GLOBAL))
993 #define GL_LoadFunction dlsym
994 #define GL_UnloadObject dlclose
995 #else
996 #define GL_LoadObject SDL_LoadObject
997 #define GL_LoadFunction SDL_LoadFunction
998 #define GL_UnloadObject SDL_UnloadObject
999 #endif
1000
1001 static int
1002 DirectFB_GL_LoadLibrary(_THIS, const char *path)
1003 {
1004 SDL_DFB_DEVICEDATA(_this);
1005 #
1006 void *handle = NULL;
1007
1008 SDL_DFB_DEBUG("Loadlibrary : %s\n", path);
1009
1010 if (_this->gl_data->gl_active) {
1011 SDL_SetError("OpenGL context already created");
1012 return -1;
1013 }
1014
1015
1016 if (path == NULL) {
1017 path = SDL_getenv("SDL_VIDEO_GL_DRIVER");
1018 if (path == NULL) {
1019 path = "libGL.so";
1020 }
1021 }
1022
1023 handle = GL_LoadObject(path);
1024 if (handle == NULL) {
1025 SDL_DFB_ERR("Library not found: %s\n", path);
1026 /* SDL_LoadObject() will call SDL_SetError() for us. */
1027 return -1;
1028 }
1029
1030 SDL_DFB_DEBUG("Loaded library: %s\n", path);
1031
1032 /* Unload the old driver and reset the pointers */
1033 DirectFB_GL_UnloadLibrary(_this);
1034
1035 _this->gl_config.dll_handle = handle;
1036 _this->gl_config.driver_loaded = 1;
1037 if (path) {
1038 SDL_strlcpy(_this->gl_config.driver_path, path,
1039 SDL_arraysize(_this->gl_config.driver_path));
1040 } else {
1041 *_this->gl_config.driver_path = '\0';
1042 }
1043
1044 devdata->glFinish = DirectFB_GL_GetProcAddress(_this, "glFinish");
1045 devdata->glFlush = DirectFB_GL_GetProcAddress(_this, "glFlush");
1046 return 0;
1047 }
1048
1049 static void
1050 DirectFB_GL_UnloadLibrary(_THIS)
1051 {
1052 SDL_DFB_DEVICEDATA(_this);
1053
1054 int ret;
1055
1056 if (_this->gl_config.driver_loaded) {
1057
1058 ret = GL_UnloadObject(_this->gl_config.dll_handle);
1059 if (ret)
1060 SDL_DFB_ERR("Error #%d trying to unload library.\n", ret);
1061 _this->gl_config.dll_handle = NULL;
1062 _this->gl_config.driver_loaded = 0;
1063 }
1064 }
1065
1066 static void *
1067 DirectFB_GL_GetProcAddress(_THIS, const char *proc)
1068 {
1069 SDL_DFB_DEVICEDATA(_this);
1070 int ret;
1071 void *handle;
1072
1073 SDL_DFB_DEBUG("Trace %s\n", proc);
1074 handle = _this->gl_config.dll_handle;
1075 return GL_LoadFunction(handle, proc);
1076 }
1077
1078 static SDL_GLContext
1079 DirectFB_GL_CreateContext(_THIS, SDL_Window * window)
1080 {
1081 SDL_DFB_DEVICEDATA(_this);
1082 SDL_DFB_WINDOWDATA(window);
1083 SDL_DFB_DISPLAYDATA(_this, window);
1084 int ret;
1085 IDirectFBGL *context = NULL;
1086
1087 SDL_DFB_DEBUG("Trace\n");
1088 SDL_DFB_CHECKERR(windata->surface->GetGL(windata->surface, &context));
1089 SDL_DFB_CHECKERR(context->Unlock(context));
1090
1091 if (DirectFB_GL_MakeCurrent(_this, window, context) < 0) {
1092 DirectFB_GL_DeleteContext(_this, context);
1093 return NULL;
1094 }
1095
1096 return context;
1097
1098 error:
1099 return NULL;
1100 }
1101
1102 static int
1103 DirectFB_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
1104 {
1105 SDL_DFB_DEVICEDATA(_this);
1106 SDL_DFB_WINDOWDATA(window);
1107 SDL_DFB_DISPLAYDATA(_this, window);
1108 IDirectFBGL *dfb_context = (IDirectFBGL *) context;
1109 int ret;
1110
1111 if (dfb_context) {
1112 dfb_context->Unlock(dfb_context);
1113 SDL_DFB_CHECKERR(dfb_context->Lock(dfb_context));
1114 }
1115 if (windata)
1116 windata->gl_context = dfb_context;
1117
1118 return 0;
1119 error:
1120 return -1;
1121 }
1122
1123 static int
1124 DirectFB_GL_SetSwapInterval(_THIS, int interval)
1125 {
1126 SDL_DFB_DEVICEDATA(_this);
1127
1128 SDL_Unsupported();
1129 return -1;
1130
1131 }
1132
1133 static int
1134 DirectFB_GL_GetSwapInterval(_THIS)
1135 {
1136 SDL_DFB_DEVICEDATA(_this);
1137
1138 SDL_Unsupported();
1139 return -1;
1140
1141 }
1142
1143 static void
1144 DirectFB_GL_SwapWindow(_THIS, SDL_Window * window)
1145 {
1146 SDL_DFB_DEVICEDATA(_this);
1147 SDL_DFB_WINDOWDATA(window);
1148 SDL_DFB_DISPLAYDATA(_this, window);
1149 int ret;
1150 void *p;
1151 int pitch;
1152 DFBRegion region;
1153
1154 region.x1 = 0;
1155 region.y1 = 0;
1156 region.x2 = window->w;
1157 region.y2 = window->h;
1158
1159 if (devdata->glFinish)
1160 devdata->glFinish();
1161 else if (devdata->glFlush)
1162 devdata->glFlush();
1163
1164 SDL_DFB_CHECKERR(windata->gl_context->Unlock(windata->gl_context));
1165 SDL_DFB_CHECKERR(windata->
1166 surface->Flip(windata->surface, &region, DSFLIP_ONSYNC));
1167 SDL_DFB_CHECKERR(windata->gl_context->Lock(windata->gl_context));
1168
1169 return;
1170 error:
1171 return;
1172 }
1173
1174 static void
1175 DirectFB_GL_DeleteContext(_THIS, SDL_GLContext context)
1176 {
1177 IDirectFBGL *dfb_context = (IDirectFBGL *) context;
1178 SDL_DFB_DEVICEDATA(_this);
1179
1180 dfb_context->Unlock(dfb_context);
1181 dfb_context->Release(dfb_context);
1182 }
1183
1184 #endif