Skip to content
This repository has been archived by the owner on Feb 11, 2021. It is now read-only.

Latest commit

 

History

History
409 lines (333 loc) · 12.9 KB

SDL_DirectFB_modes.c

File metadata and controls

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