zenilib  0.5.3.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
SDL_DirectFB_modes.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
4 
5  This software is provided 'as-is', without any express or implied
6  warranty. In no event will the authors be held liable for any damages
7  arising from the use of this software.
8 
9  Permission is granted to anyone to use this software for any purpose,
10  including commercial applications, and to alter it and redistribute it
11  freely, subject to the following restrictions:
12 
13  1. The origin of this software must not be misrepresented; you must not
14  claim that you wrote the original software. If you use this software
15  in a product, an acknowledgment in the product documentation would be
16  appreciated but is not required.
17  2. Altered source versions must be plainly marked as such, and must not be
18  misrepresented as being the original software.
19  3. This notice may not be removed or altered from any source distribution.
20 */
21 #include "SDL_config.h"
22 
23 #if SDL_VIDEO_DRIVER_DIRECTFB
24 
25 #include "SDL_DirectFB_video.h"
26 #include "SDL_DirectFB_modes.h"
27 
28 #define DFB_MAX_MODES 200
29 
30 struct screen_callback_t
31 {
32  int numscreens;
33  DFBScreenID screenid[DFB_MAX_SCREENS];
34  DFBDisplayLayerID gralayer[DFB_MAX_SCREENS];
35  DFBDisplayLayerID vidlayer[DFB_MAX_SCREENS];
36  int aux; /* auxiliary integer for callbacks */
37 };
38 
39 struct modes_callback_t
40 {
41  int nummodes;
42  SDL_DisplayMode *modelist;
43 };
44 
45 static DFBEnumerationResult
46 EnumModesCallback(int width, int height, int bpp, void *data)
47 {
48  struct modes_callback_t *modedata = (struct modes_callback_t *) data;
50 
51  mode.w = width;
52  mode.h = height;
53  mode.refresh_rate = 0;
54  mode.driverdata = NULL;
56 
57  if (modedata->nummodes < DFB_MAX_MODES) {
58  modedata->modelist[modedata->nummodes++] = mode;
59  }
60 
61  return DFENUM_OK;
62 }
63 
64 static DFBEnumerationResult
65 EnumScreensCallback(DFBScreenID screen_id, DFBScreenDescription desc,
66  void *callbackdata)
67 {
68  struct screen_callback_t *devdata = (struct screen_callback_t *) callbackdata;
69 
70  devdata->screenid[devdata->numscreens++] = screen_id;
71  return DFENUM_OK;
72 }
73 
74 static DFBEnumerationResult
75 EnumLayersCallback(DFBDisplayLayerID layer_id, DFBDisplayLayerDescription desc,
76  void *callbackdata)
77 {
78  struct screen_callback_t *devdata = (struct screen_callback_t *) callbackdata;
79 
80  if (desc.caps & DLCAPS_SURFACE) {
81  if ((desc.type & DLTF_GRAPHICS) && (desc.type & DLTF_VIDEO)) {
82  if (devdata->vidlayer[devdata->aux] == -1)
83  devdata->vidlayer[devdata->aux] = layer_id;
84  } else if (desc.type & DLTF_GRAPHICS) {
85  if (devdata->gralayer[devdata->aux] == -1)
86  devdata->gralayer[devdata->aux] = layer_id;
87  }
88  }
89  return DFENUM_OK;
90 }
91 
92 static void
93 CheckSetDisplayMode(_THIS, SDL_VideoDisplay * display, DFB_DisplayData * data, SDL_DisplayMode * mode)
94 {
96  DFBDisplayLayerConfig config;
97  DFBDisplayLayerConfigFlags failed;
98 
99  SDL_DFB_CHECKERR(data->layer->SetCooperativeLevel(data->layer,
100  DLSCL_ADMINISTRATIVE));
101  config.width = mode->w;
102  config.height = mode->h;
103  config.pixelformat = DirectFB_SDLToDFBPixelFormat(mode->format);
104  config.flags = DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT;
105  if (devdata->use_yuv_underlays) {
106  config.flags |= DLCONF_OPTIONS;
107  config.options = DLOP_ALPHACHANNEL;
108  }
109  failed = 0;
110  data->layer->TestConfiguration(data->layer, &config, &failed);
111  SDL_DFB_CHECKERR(data->layer->SetCooperativeLevel(data->layer,
112  DLSCL_SHARED));
113  if (failed == 0)
114  {
115  SDL_AddDisplayMode(display, mode);
116  SDL_DFB_LOG("Mode %d x %d Added\n", mode->w, mode->h);
117  }
118  else
119  SDL_DFB_ERR("Mode %d x %d not available: %x\n", mode->w,
120  mode->h, failed);
121 
122  return;
123  error:
124  return;
125 }
126 
127 
128 void
130 {
131 #if (DFB_VERSION_ATLEAST(1,0,0))
132  /* FIXME: does not work on 1.0/1.2 with radeon driver
133  * the approach did work with the matrox driver
134  * This has simply no effect.
135  */
136 
137  SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
138  DFB_DisplayData *dispdata = (DFB_DisplayData *) display->driverdata;
139 
140  /* FIXME: should we handle the error */
141  if (dispdata->vidIDinuse)
142  SDL_DFB_CHECK(dispdata->vidlayer->SwitchContext(dispdata->vidlayer,
143  DFB_TRUE));
144 #endif
145 }
146 
147 void
149 {
151  IDirectFBDisplayLayer *layer = NULL;
153  DFB_DisplayData *dispdata = NULL;
155  DFBGraphicsDeviceDescription caps;
156  DFBDisplayLayerConfig dlc;
157  struct screen_callback_t *screencbdata;
158 
159  int tcw[DFB_MAX_SCREENS];
160  int tch[DFB_MAX_SCREENS];
161  int i;
162  DFBResult ret;
163 
164  SDL_DFB_ALLOC_CLEAR(screencbdata, sizeof(*screencbdata));
165 
166  screencbdata->numscreens = 0;
167 
168  for (i = 0; i < DFB_MAX_SCREENS; i++) {
169  screencbdata->gralayer[i] = -1;
170  screencbdata->vidlayer[i] = -1;
171  }
172 
173  SDL_DFB_CHECKERR(devdata->dfb->EnumScreens(devdata->dfb, &EnumScreensCallback,
174  screencbdata));
175 
176  for (i = 0; i < screencbdata->numscreens; i++) {
177  IDirectFBScreen *screen;
178 
179  SDL_DFB_CHECKERR(devdata->dfb->GetScreen(devdata->dfb,
180  screencbdata->screenid
181  [i], &screen));
182 
183  screencbdata->aux = i;
184  SDL_DFB_CHECKERR(screen->EnumDisplayLayers(screen, &EnumLayersCallback,
185  screencbdata));
186  screen->GetSize(screen, &tcw[i], &tch[i]);
187 
188  screen->Release(screen);
189  }
190 
191  /* Query card capabilities */
192 
193  devdata->dfb->GetDeviceDescription(devdata->dfb, &caps);
194 
195  for (i = 0; i < screencbdata->numscreens; i++) {
196  SDL_DFB_CHECKERR(devdata->dfb->GetDisplayLayer(devdata->dfb,
197  screencbdata->gralayer
198  [i], &layer));
199 
200  SDL_DFB_CHECKERR(layer->SetCooperativeLevel(layer,
201  DLSCL_ADMINISTRATIVE));
202  layer->EnableCursor(layer, 1);
203  SDL_DFB_CHECKERR(layer->SetCursorOpacity(layer, 0xC0));
204 
205  if (devdata->use_yuv_underlays) {
206  dlc.flags = DLCONF_PIXELFORMAT | DLCONF_OPTIONS;
207  dlc.pixelformat = DSPF_ARGB;
208  dlc.options = DLOP_ALPHACHANNEL;
209 
210  ret = layer->SetConfiguration(layer, &dlc);
211  if (ret != DFB_OK) {
212  /* try AiRGB if the previous failed */
213  dlc.pixelformat = DSPF_AiRGB;
214  SDL_DFB_CHECKERR(layer->SetConfiguration(layer, &dlc));
215  }
216  }
217 
218  /* Query layer configuration to determine the current mode and pixelformat */
219  dlc.flags = DLCONF_ALL;
220  SDL_DFB_CHECKERR(layer->GetConfiguration(layer, &dlc));
221 
222  mode.format = DirectFB_DFBToSDLPixelFormat(dlc.pixelformat);
223 
224  if (mode.format == SDL_PIXELFORMAT_UNKNOWN) {
225  SDL_DFB_ERR("Unknown dfb pixelformat %x !\n", dlc.pixelformat);
226  goto error;
227  }
228 
229  mode.w = dlc.width;
230  mode.h = dlc.height;
231  mode.refresh_rate = 0;
232  mode.driverdata = NULL;
233 
234  SDL_DFB_ALLOC_CLEAR(dispdata, sizeof(*dispdata));
235 
236  dispdata->layer = layer;
237  dispdata->pixelformat = dlc.pixelformat;
238  dispdata->cw = tcw[i];
239  dispdata->ch = tch[i];
240 
241  /* YUV - Video layer */
242 
243  dispdata->vidID = screencbdata->vidlayer[i];
244  dispdata->vidIDinuse = 0;
245 
246  SDL_zero(display);
247 
248  display.desktop_mode = mode;
249  display.current_mode = mode;
250  display.driverdata = dispdata;
251 
252 #if (DFB_VERSION_ATLEAST(1,2,0))
253  dlc.flags =
254  DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT |
255  DLCONF_OPTIONS;
256  ret = layer->SetConfiguration(layer, &dlc);
257 #endif
258 
259  SDL_DFB_CHECKERR(layer->SetCooperativeLevel(layer, DLSCL_SHARED));
260 
261  SDL_AddVideoDisplay(&display);
262  }
263  SDL_DFB_FREE(screencbdata);
264  return;
265  error:
266  /* FIXME: Cleanup not complete, Free existing displays */
267  SDL_DFB_FREE(dispdata);
268  SDL_DFB_RELEASE(layer);
269  return;
270 }
271 
272 void
274 {
276  DFB_DisplayData *dispdata = (DFB_DisplayData *) display->driverdata;
277  SDL_DisplayMode mode;
278  struct modes_callback_t data;
279  int i;
280 
281  data.nummodes = 0;
282  /* Enumerate the available fullscreen modes */
283  SDL_DFB_CALLOC(data.modelist, DFB_MAX_MODES, sizeof(SDL_DisplayMode));
284  SDL_DFB_CHECKERR(devdata->dfb->EnumVideoModes(devdata->dfb,
285  EnumModesCallback, &data));
286 
287  for (i = 0; i < data.nummodes; ++i) {
288  mode = data.modelist[i];
289 
291  CheckSetDisplayMode(_this, display, dispdata, &mode);
293  CheckSetDisplayMode(_this, display, dispdata, &mode);
295  CheckSetDisplayMode(_this, display, dispdata, &mode);
297  CheckSetDisplayMode(_this, display, dispdata, &mode);
299  CheckSetDisplayMode(_this, display, dispdata, &mode);
300  }
301 
302  SDL_DFB_FREE(data.modelist);
303 error:
304  return;
305 }
306 
307 int
309 {
310  /*
311  * FIXME: video mode switch is currently broken for 1.2.0
312  *
313  */
314 
316  DFB_DisplayData *data = (DFB_DisplayData *) display->driverdata;
317  DFBDisplayLayerConfig config, rconfig;
318  DFBDisplayLayerConfigFlags fail = 0;
319 
320  SDL_DFB_CHECKERR(data->layer->SetCooperativeLevel(data->layer,
321  DLSCL_ADMINISTRATIVE));
322 
323  SDL_DFB_CHECKERR(data->layer->GetConfiguration(data->layer, &config));
324  config.flags = DLCONF_WIDTH | DLCONF_HEIGHT;
325  if (mode->format != SDL_PIXELFORMAT_UNKNOWN) {
326  config.flags |= DLCONF_PIXELFORMAT;
327  config.pixelformat = DirectFB_SDLToDFBPixelFormat(mode->format);
328  data->pixelformat = config.pixelformat;
329  }
330  config.width = mode->w;
331  config.height = mode->h;
332 
333  if (devdata->use_yuv_underlays) {
334  config.flags |= DLCONF_OPTIONS;
335  config.options = DLOP_ALPHACHANNEL;
336  }
337 
338  data->layer->TestConfiguration(data->layer, &config, &fail);
339 
340  if (fail &
341  (DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT |
342  DLCONF_OPTIONS)) {
343  SDL_DFB_ERR("Error setting mode %dx%d-%x\n", mode->w, mode->h,
344  mode->format);
345  return -1;
346  }
347 
348  config.flags &= ~fail;
349  SDL_DFB_CHECKERR(data->layer->SetConfiguration(data->layer, &config));
350 #if (DFB_VERSION_ATLEAST(1,2,0))
351  /* Need to call this twice ! */
352  SDL_DFB_CHECKERR(data->layer->SetConfiguration(data->layer, &config));
353 #endif
354 
355  /* Double check */
356  SDL_DFB_CHECKERR(data->layer->GetConfiguration(data->layer, &rconfig));
357  SDL_DFB_CHECKERR(data->
358  layer->SetCooperativeLevel(data->layer, DLSCL_SHARED));
359 
360  if ((config.width != rconfig.width) || (config.height != rconfig.height)
361  || ((mode->format != SDL_PIXELFORMAT_UNKNOWN)
362  && (config.pixelformat != rconfig.pixelformat))) {
363  SDL_DFB_ERR("Error setting mode %dx%d-%x\n", mode->w, mode->h,
364  mode->format);
365  return -1;
366  }
367 
368  data->pixelformat = rconfig.pixelformat;
369  data->cw = config.width;
370  data->ch = config.height;
371  display->current_mode = *mode;
372 
373  return 0;
374  error:
375  return -1;
376 }
377 
378 void
380 {
381  SDL_DisplayMode tmode;
382  int i;
383 
384  for (i = 0; i < _this->num_displays; ++i) {
385  SDL_VideoDisplay *display = &_this->displays[i];
386  DFB_DisplayData *dispdata = (DFB_DisplayData *) display->driverdata;
387 
388  SDL_GetDesktopDisplayMode(i, &tmode);
390  DirectFB_SetDisplayMode(_this, display, &tmode);
391 
392  SDL_GetDesktopDisplayMode(i, &tmode);
393  DirectFB_SetDisplayMode(_this, display, &tmode);
394 
395  if (dispdata->layer) {
396  SDL_DFB_CHECK(dispdata->
397  layer->SetCooperativeLevel(dispdata->layer,
398  DLSCL_ADMINISTRATIVE));
399  SDL_DFB_CHECK(dispdata->
400  layer->SetCursorOpacity(dispdata->layer, 0x00));
401  SDL_DFB_CHECK(dispdata->
402  layer->SetCooperativeLevel(dispdata->layer,
403  DLSCL_SHARED));
404  }
405 
406  SDL_DFB_RELEASE(dispdata->layer);
407  SDL_DFB_RELEASE(dispdata->vidlayer);
408 
409  }
410 }
411 
412 #endif /* SDL_VIDEO_DRIVER_DIRECTFB */
413 
414 /* vi: set ts=4 sw=4 expandtab: */
#define SDL_DFB_LOG(x...)
#define SDL_DFB_FREE(x)
#define NULL
Definition: ftobjs.h:61
DFBSurfacePixelFormat DirectFB_SDLToDFBPixelFormat(Uint32 format)
The structure that defines a display mode.
Definition: SDL_video.h:53
EGLSurface EGLint EGLint EGLint EGLint height
Definition: eglext.h:293
void DirectFB_SetContext(_THIS, SDL_Window *window)
GLint GLboolean GLint layer
Definition: glew.h:3462
Uint32 DirectFB_DFBToSDLPixelFormat(DFBSurfacePixelFormat pixelformat)
char * display
Definition: visualinfo.c:85
if(!yyg->yy_init)
int SDL_AddVideoDisplay(const SDL_VideoDisplay *display)
Definition: SDL_video.c:568
ret
Definition: glew_str_glx.c:2
#define SDL_DFB_RELEASE(x)
static SDL_VideoDevice * _this
Definition: SDL_video.c:92
void DirectFB_GetDisplayModes(_THIS, SDL_VideoDisplay *display)
#define SDL_DFB_DEVICEDATA(dev)
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl2ext.h:848
FT_Error error
Definition: cffdrivr.c:407
EGLSurface EGLint EGLint EGLint width
Definition: eglext.h:293
#define _THIS
DECLSPEC int SDLCALL SDL_GetDesktopDisplayMode(int displayIndex, SDL_DisplayMode *mode)
Fill in information about the desktop display mode.
Definition: SDL_video.c:739
void * driverdata
Definition: SDL_video.h:59
void DirectFB_QuitModes(_THIS)
void DirectFB_InitModes(_THIS)
SDL_DisplayMode current_mode
Definition: SDL_sysvideo.h:120
#define DFB_MAX_SCREENS
SDL_VideoDisplay * displays
Definition: SDL_sysvideo.h:265
DFBSurfacePixelFormat pixelformat
SDL_DisplayMode desktop_mode
Definition: SDL_sysvideo.h:119
#define SDL_DFB_ALLOC_CLEAR(r, s)
#define SDL_DFB_ERR(x...)
#define SDL_DFB_CHECKERR(x...)
SDL_VideoDisplay * SDL_GetDisplayForWindow(SDL_Window *window)
Definition: SDL_video.c:996
#define SDL_DFB_CHECK(x...)
EGLConfig config
Definition: eglext.h:257
SDL_bool SDL_AddDisplayMode(SDL_VideoDisplay *display, const SDL_DisplayMode *mode)
Definition: SDL_video.c:666
IDirectFBDisplayLayer * vidlayer
#define SDL_zero(x)
Definition: SDL_stdinc.h:254
DFBDisplayLayerID vidID
Uint32 format
Definition: SDL_video.h:55
int i
Definition: pngrutil.c:1377
IDirectFBDisplayLayer * layer
GLenum mode
Definition: glew.h:2394
int DirectFB_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode)
#define SDL_DFB_CALLOC(r, n, s)