This repository has been archived by the owner on Feb 11, 2021. It is now read-only.
/
SDL_DirectFB_video.c
426 lines (340 loc) · 15.2 KB
1
/*
2
SDL - Simple DirectMedia Layer
3
Copyright (C) 1997-2011 Sam Lantinga
4
5
6
7
8
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
9
10
11
12
13
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
14
15
16
17
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
19
20
Sam Lantinga
slouken@libsdl.org
21
22
SDL1.3 DirectFB driver by couriersud@arcor.de
23
24
*/
25
26
27
28
29
30
31
32
33
34
35
36
37
#include "SDL_DirectFB_video.h"
#include "SDL_DirectFB_events.h"
/*
* #include "SDL_DirectFB_keyboard.h"
*/
#include "SDL_DirectFB_modes.h"
#include "SDL_DirectFB_mouse.h"
#include "SDL_DirectFB_opengl.h"
#include "SDL_DirectFB_window.h"
#include "SDL_DirectFB_WM.h"
38
39
#include "SDL_config.h"
40
41
42
43
44
45
46
47
48
/* DirectFB video driver implementation.
*/
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <directfb.h>
49
#include <directfb_version.h>
50
#include <directfb_strings.h>
51
52
53
#include "SDL_video.h"
#include "SDL_mouse.h"
54
55
56
#include "../SDL_sysvideo.h"
#include "../SDL_pixels_c.h"
#include "../../events/SDL_events_c.h"
57
58
#include "SDL_DirectFB_video.h"
#include "SDL_DirectFB_events.h"
59
60
#include "SDL_DirectFB_render.h"
#include "SDL_DirectFB_mouse.h"
61
62
#include "SDL_DirectFB_shape.h"
63
64
65
#include "SDL_DirectFB_dyn.h"
66
67
68
69
/* Initialization/Query functions */
static int DirectFB_VideoInit(_THIS);
static void DirectFB_VideoQuit(_THIS);
70
71
static int DirectFB_Available(void);
static SDL_VideoDevice *DirectFB_CreateDevice(int devindex);
72
73
74
75
76
VideoBootStrap DirectFB_bootstrap = {
"directfb", "DirectFB",
DirectFB_Available, DirectFB_CreateDevice
};
77
78
79
80
81
static const DirectFBSurfaceDrawingFlagsNames(drawing_flags);
static const DirectFBSurfaceBlittingFlagsNames(blitting_flags);
static const DirectFBAccelerationMaskNames(acceleration_mask);
82
83
/* DirectFB driver bootstrap functions */
84
85
static int
DirectFB_Available(void)
86
{
87
88
89
if (!SDL_DirectFB_LoadLibrary())
return 0;
SDL_DirectFB_UnLoadLibrary();
90
return 1;
91
92
}
93
94
static void
DirectFB_DeleteDevice(SDL_VideoDevice * device)
95
{
96
97
98
SDL_DirectFB_UnLoadLibrary();
SDL_DFB_FREE(device->driverdata);
SDL_DFB_FREE(device);
99
100
}
101
102
static SDL_VideoDevice *
DirectFB_CreateDevice(int devindex)
103
{
104
105
SDL_VideoDevice *device;
106
107
108
if (!SDL_DirectFB_LoadLibrary())
return NULL;
109
/* Initialize all variables that we clean on shutdown */
110
SDL_DFB_ALLOC_CLEAR(device, sizeof(SDL_VideoDevice));
111
112
/* Set the function pointers */
113
114
115
116
/* Set the function pointers */
device->VideoInit = DirectFB_VideoInit;
device->VideoQuit = DirectFB_VideoQuit;
117
118
119
120
121
122
device->GetDisplayModes = DirectFB_GetDisplayModes;
device->SetDisplayMode = DirectFB_SetDisplayMode;
device->PumpEvents = DirectFB_PumpEventsWindow;
device->CreateWindow = DirectFB_CreateWindow;
device->CreateWindowFrom = DirectFB_CreateWindowFrom;
device->SetWindowTitle = DirectFB_SetWindowTitle;
123
device->SetWindowIcon = DirectFB_SetWindowIcon;
124
125
126
127
128
129
130
131
132
133
134
135
device->SetWindowPosition = DirectFB_SetWindowPosition;
device->SetWindowSize = DirectFB_SetWindowSize;
device->ShowWindow = DirectFB_ShowWindow;
device->HideWindow = DirectFB_HideWindow;
device->RaiseWindow = DirectFB_RaiseWindow;
device->MaximizeWindow = DirectFB_MaximizeWindow;
device->MinimizeWindow = DirectFB_MinimizeWindow;
device->RestoreWindow = DirectFB_RestoreWindow;
device->SetWindowGrab = DirectFB_SetWindowGrab;
device->DestroyWindow = DirectFB_DestroyWindow;
device->GetWindowWMInfo = DirectFB_GetWindowWMInfo;
136
137
138
139
/* Not supported by DFB, for completeness */
device->SetWindowGammaRamp = DirectFB_SetWindowGammaRamp;
device->GetWindowGammaRamp = DirectFB_GetWindowGammaRamp;
140
141
142
143
144
145
146
147
148
149
150
151
#if SDL_DIRECTFB_OPENGL
device->GL_LoadLibrary = DirectFB_GL_LoadLibrary;
device->GL_GetProcAddress = DirectFB_GL_GetProcAddress;
device->GL_MakeCurrent = DirectFB_GL_MakeCurrent;
device->GL_CreateContext = DirectFB_GL_CreateContext;
device->GL_SetSwapInterval = DirectFB_GL_SetSwapInterval;
device->GL_GetSwapInterval = DirectFB_GL_GetSwapInterval;
device->GL_SwapWindow = DirectFB_GL_SwapWindow;
device->GL_DeleteContext = DirectFB_GL_DeleteContext;
#endif
152
153
154
155
156
157
/* Shaped window support */
device->shape_driver.CreateShaper = DirectFB_CreateShaper;
device->shape_driver.SetWindowShape = DirectFB_SetWindowShape;
device->shape_driver.ResizeWindowShape = DirectFB_ResizeWindowShape;
158
device->free = DirectFB_DeleteDevice;
159
160
return device;
161
162
163
164
error:
if (device)
free(device);
return (0);
165
166
}
167
168
169
170
171
172
173
174
static void
DirectFB_DeviceInformation(IDirectFB * dfb)
{
DFBGraphicsDeviceDescription desc;
int n;
dfb->GetDeviceDescription(dfb, &desc);
175
176
177
178
179
180
181
SDL_DFB_LOG( "DirectFB Device Information");
SDL_DFB_LOG( "===========================");
SDL_DFB_LOG( "Name: %s", desc.name);
SDL_DFB_LOG( "Vendor: %s", desc.vendor);
SDL_DFB_LOG( "Driver Name: %s", desc.driver.name);
SDL_DFB_LOG( "Driver Vendor: %s", desc.driver.vendor);
SDL_DFB_LOG( "Driver Version: %d.%d", desc.driver.major,
182
183
desc.driver.minor);
184
SDL_DFB_LOG( "Video memoory: %d", desc.video_memory);
185
186
SDL_DFB_LOG( "Blitting flags:");
187
188
for (n = 0; blitting_flags[n].flag; n++) {
if (desc.blitting_flags & blitting_flags[n].flag)
189
SDL_DFB_LOG( " %s", blitting_flags[n].name);
190
191
}
192
SDL_DFB_LOG( "Drawing flags:");
193
194
for (n = 0; drawing_flags[n].flag; n++) {
if (desc.drawing_flags & drawing_flags[n].flag)
195
SDL_DFB_LOG( " %s", drawing_flags[n].name);
196
197
}
198
199
SDL_DFB_LOG( "Acceleration flags:");
200
201
for (n = 0; acceleration_mask[n].mask; n++) {
if (desc.acceleration_mask & acceleration_mask[n].mask)
202
SDL_DFB_LOG( " %s", acceleration_mask[n].name);
203
204
205
206
207
}
}
208
209
210
211
212
213
214
215
216
217
218
static int readBoolEnv(const char *env_name, int def_val)
{
char *stemp;
stemp = SDL_getenv(env_name);
if (stemp)
return atoi(stemp);
else
return def_val;
}
219
220
static int
DirectFB_VideoInit(_THIS)
221
{
222
IDirectFB *dfb = NULL;
223
DFB_DeviceData *devdata = NULL;
224
DFBResult ret;
225
226
SDL_DFB_ALLOC_CLEAR(devdata, sizeof(*devdata));
227
228
SDL_DFB_CHECKERR(DirectFBInit(NULL, NULL));
229
230
231
/* avoid switching to the framebuffer when we
* are running X11 */
232
ret = readBoolEnv(DFBENV_USE_X11_CHECK , 1);
233
if (ret) {
234
if (SDL_getenv("DISPLAY"))
235
236
237
238
239
DirectFBSetOption("system", "x11");
else
DirectFBSetOption("disable-module", "x11input");
}
240
/* FIXME: Reenable as default once multi kbd/mouse interface is sorted out */
241
devdata->use_linux_input = readBoolEnv(DFBENV_USE_LINUX_INPUT, 0); /* default: on */
242
243
if (!devdata->use_linux_input)
244
245
{
SDL_DFB_LOG("Disabling linxu input\n");
246
DirectFBSetOption("disable-module", "linux_input");
247
248
}
249
SDL_DFB_CHECKERR(DirectFBCreate(&dfb));
250
251
DirectFB_DeviceInformation(dfb);
252
253
254
devdata->use_yuv_underlays = readBoolEnv(DFBENV_USE_YUV_UNDERLAY, 0); /* default: off */
devdata->use_yuv_direct = readBoolEnv(DFBENV_USE_YUV_DIRECT, 0); /* default is off! */
255
256
/* Create global Eventbuffer for axis events */
257
if (devdata->use_linux_input) {
258
259
260
SDL_DFB_CHECKERR(dfb->CreateInputEventBuffer(dfb, DICAPS_ALL,
DFB_TRUE,
&devdata->events));
261
} else {
262
263
264
265
SDL_DFB_CHECKERR(dfb->CreateInputEventBuffer(dfb, DICAPS_AXES
/*DICAPS_ALL */ ,
DFB_TRUE,
&devdata->events));
266
}
267
268
/* simple window manager support */
269
270
271
devdata->has_own_wm = readBoolEnv(DFBENV_USE_WM, 0);
devdata->initialized = 1;
272
273
274
devdata->dfb = dfb;
devdata->firstwin = NULL;
275
devdata->grabbed_window = NULL;
276
277
_this->driverdata = devdata;
278
279
DirectFB_InitModes(_this);
280
281
#if SDL_DIRECTFB_OPENGL
282
DirectFB_GL_Initialize(_this);
283
#endif
284
285
DirectFB_InitMouse(_this);
286
DirectFB_InitKeyboard(_this);
287
288
return 0;
289
290
291
error:
292
SDL_DFB_FREE(devdata);
293
294
SDL_DFB_RELEASE(dfb);
return -1;
295
296
}
297
298
static void
DirectFB_VideoQuit(_THIS)
299
{
300
301
DFB_DeviceData *devdata = (DFB_DeviceData *) _this->driverdata;
302
303
304
DirectFB_QuitModes(_this);
DirectFB_QuitKeyboard(_this);
DirectFB_QuitMouse(_this);
305
306
devdata->events->Reset(devdata->events);
307
SDL_DFB_RELEASE(devdata->events);
308
SDL_DFB_RELEASE(devdata->dfb);
309
310
#if SDL_DIRECTFB_OPENGL
311
DirectFB_GL_Shutdown(_this);
312
#endif
313
314
315
devdata->initialized = 0;
}
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
/* DirectFB driver general support functions */
static const struct {
DFBSurfacePixelFormat dfb;
Uint32 sdl;
} pixelformat_tab[] =
{
{ DSPF_RGB32, SDL_PIXELFORMAT_RGB888 }, /* 24 bit RGB (4 byte, nothing@24, red 8@16, green 8@8, blue 8@0) */
{ DSPF_ARGB, SDL_PIXELFORMAT_ARGB8888 }, /* 32 bit ARGB (4 byte, alpha 8@24, red 8@16, green 8@8, blue 8@0) */
{ DSPF_RGB16, SDL_PIXELFORMAT_RGB565 }, /* 16 bit RGB (2 byte, red 5@11, green 6@5, blue 5@0) */
{ DSPF_RGB332, SDL_PIXELFORMAT_RGB332 }, /* 8 bit RGB (1 byte, red 3@5, green 3@2, blue 2@0) */
{ DSPF_ARGB4444, SDL_PIXELFORMAT_ARGB4444 }, /* 16 bit ARGB (2 byte, alpha 4@12, red 4@8, green 4@4, blue 4@0) */
{ DSPF_ARGB1555, SDL_PIXELFORMAT_ARGB1555 }, /* 16 bit ARGB (2 byte, alpha 1@15, red 5@10, green 5@5, blue 5@0) */
{ DSPF_RGB24, SDL_PIXELFORMAT_RGB24 }, /* 24 bit RGB (3 byte, red 8@16, green 8@8, blue 8@0) */
{ DSPF_RGB444, SDL_PIXELFORMAT_RGB444 }, /* 16 bit RGB (2 byte, nothing @12, red 4@8, green 4@4, blue 4@0) */
{ DSPF_YV12, SDL_PIXELFORMAT_YV12 }, /* 12 bit YUV (8 bit Y plane followed by 8 bit quarter size V/U planes) */
{ DSPF_I420,SDL_PIXELFORMAT_IYUV }, /* 12 bit YUV (8 bit Y plane followed by 8 bit quarter size U/V planes) */
{ DSPF_YUY2, SDL_PIXELFORMAT_YUY2 }, /* 16 bit YUV (4 byte/ 2 pixel, macropixel contains CbYCrY [31:0]) */
{ DSPF_UYVY, SDL_PIXELFORMAT_UYVY }, /* 16 bit YUV (4 byte/ 2 pixel, macropixel contains YCbYCr [31:0]) */
{ DSPF_RGB555, SDL_PIXELFORMAT_RGB555 }, /* 16 bit RGB (2 byte, nothing @15, red 5@10, green 5@5, blue 5@0) */
#if (ENABLE_LUT8)
{ DSPF_LUT8, SDL_PIXELFORMAT_INDEX8 }, /* 8 bit LUT (8 bit color and alpha lookup from palette) */
#endif
#if (DFB_VERSION_ATLEAST(1,2,0))
{ DSPF_BGR555, SDL_PIXELFORMAT_BGR555 }, /* 16 bit BGR (2 byte, nothing @15, blue 5@10, green 5@5, red 5@0) */
#else
{ DSPF_UNKNOWN, SDL_PIXELFORMAT_BGR555 },
#endif
/* Pfff ... nonmatching formats follow */
{ DSPF_ALUT44, SDL_PIXELFORMAT_UNKNOWN }, /* 8 bit ALUT (1 byte, alpha 4@4, color lookup 4@0) */
{ DSPF_A8, SDL_PIXELFORMAT_UNKNOWN }, /* 8 bit alpha (1 byte, alpha 8@0), e.g. anti-aliased glyphs */
{ DSPF_AiRGB, SDL_PIXELFORMAT_UNKNOWN }, /* 32 bit ARGB (4 byte, inv. alpha 8@24, red 8@16, green 8@8, blue 8@0) */
{ DSPF_A1, SDL_PIXELFORMAT_UNKNOWN }, /* 1 bit alpha (1 byte/ 8 pixel, most significant bit used first) */
{ DSPF_NV12, SDL_PIXELFORMAT_UNKNOWN }, /* 12 bit YUV (8 bit Y plane followed by one 16 bit quarter size CbCr [15:0] plane) */
{ DSPF_NV16, SDL_PIXELFORMAT_UNKNOWN }, /* 16 bit YUV (8 bit Y plane followed by one 16 bit half width CbCr [15:0] plane) */
{ DSPF_ARGB2554, SDL_PIXELFORMAT_UNKNOWN }, /* 16 bit ARGB (2 byte, alpha 2@14, red 5@9, green 5@4, blue 4@0) */
{ DSPF_NV21, SDL_PIXELFORMAT_UNKNOWN }, /* 12 bit YUV (8 bit Y plane followed by one 16 bit quarter size CrCb [15:0] plane) */
{ DSPF_AYUV, SDL_PIXELFORMAT_UNKNOWN }, /* 32 bit AYUV (4 byte, alpha 8@24, Y 8@16, Cb 8@8, Cr 8@0) */
{ DSPF_A4, SDL_PIXELFORMAT_UNKNOWN }, /* 4 bit alpha (1 byte/ 2 pixel, more significant nibble used first) */
{ DSPF_ARGB1666, SDL_PIXELFORMAT_UNKNOWN }, /* 1 bit alpha (3 byte/ alpha 1@18, red 6@16, green 6@6, blue 6@0) */
{ DSPF_ARGB6666, SDL_PIXELFORMAT_UNKNOWN }, /* 6 bit alpha (3 byte/ alpha 6@18, red 6@16, green 6@6, blue 6@0) */
{ DSPF_RGB18, SDL_PIXELFORMAT_UNKNOWN }, /* 6 bit RGB (3 byte/ red 6@16, green 6@6, blue 6@0) */
{ DSPF_LUT2, SDL_PIXELFORMAT_UNKNOWN }, /* 2 bit LUT (1 byte/ 4 pixel, 2 bit color and alpha lookup from palette) */
#if (DFB_VERSION_ATLEAST(1,3,0))
{ DSPF_RGBA4444, SDL_PIXELFORMAT_UNKNOWN }, /* 16 bit RGBA (2 byte, red 4@12, green 4@8, blue 4@4, alpha 4@0) */
#endif
#if (DFB_VERSION_ATLEAST(1,4,3))
{ DSPF_RGBA5551, SDL_PIXELFORMAT_UNKNOWN }, /* 16 bit RGBA (2 byte, red 5@11, green 5@6, blue 5@1, alpha 1@0) */
{ DSPF_YUV444P, SDL_PIXELFORMAT_UNKNOWN }, /* 24 bit full YUV planar (8 bit Y plane followed by an 8 bit Cb and an 8 bit Cr plane) */
{ DSPF_ARGB8565, SDL_PIXELFORMAT_UNKNOWN }, /* 24 bit ARGB (3 byte, alpha 8@16, red 5@11, green 6@5, blue 5@0) */
{ DSPF_AVYU, SDL_PIXELFORMAT_UNKNOWN }, /* 32 bit AVYU 4:4:4 (4 byte, alpha 8@24, Cr 8@16, Y 8@8, Cb 8@0) */
{ DSPF_VYU, SDL_PIXELFORMAT_UNKNOWN }, /* 24 bit VYU 4:4:4 (3 byte, Cr 8@16, Y 8@8, Cb 8@0) */
#endif
{ DSPF_UNKNOWN, SDL_PIXELFORMAT_INDEX1LSB },
{ DSPF_UNKNOWN, SDL_PIXELFORMAT_INDEX1MSB },
{ DSPF_UNKNOWN, SDL_PIXELFORMAT_INDEX4LSB },
{ DSPF_UNKNOWN, SDL_PIXELFORMAT_INDEX4MSB },
{ DSPF_UNKNOWN, SDL_PIXELFORMAT_BGR24 },
{ DSPF_UNKNOWN, SDL_PIXELFORMAT_BGR888 },
{ DSPF_UNKNOWN, SDL_PIXELFORMAT_RGBA8888 },
{ DSPF_UNKNOWN, SDL_PIXELFORMAT_ABGR8888 },
{ DSPF_UNKNOWN, SDL_PIXELFORMAT_BGRA8888 },
{ DSPF_UNKNOWN, SDL_PIXELFORMAT_ARGB2101010 },
{ DSPF_UNKNOWN, SDL_PIXELFORMAT_ABGR4444 },
{ DSPF_UNKNOWN, SDL_PIXELFORMAT_ABGR1555 },
{ DSPF_UNKNOWN, SDL_PIXELFORMAT_BGR565 },
{ DSPF_UNKNOWN, SDL_PIXELFORMAT_YVYU }, /**< Packed mode: Y0+V0+Y1+U0 (1 pla */
};
Uint32
DirectFB_DFBToSDLPixelFormat(DFBSurfacePixelFormat pixelformat)
{
int i;
for (i=0; pixelformat_tab[i].dfb != DSPF_UNKNOWN; i++)
if (pixelformat_tab[i].dfb == pixelformat)
{
return pixelformat_tab[i].sdl;
}
return SDL_PIXELFORMAT_UNKNOWN;
}
DFBSurfacePixelFormat
DirectFB_SDLToDFBPixelFormat(Uint32 format)
{
int i;
for (i=0; pixelformat_tab[i].dfb != DSPF_UNKNOWN; i++)
if (pixelformat_tab[i].sdl == format)
{
return pixelformat_tab[i].dfb;
}
return DSPF_UNKNOWN;
}
void DirectFB_SetSupportedPixelFormats(SDL_RendererInfo* ri)
{
int i, j;
for (i=0, j=0; pixelformat_tab[i].dfb != DSPF_UNKNOWN; i++)
if (pixelformat_tab[i].sdl != SDL_PIXELFORMAT_UNKNOWN)
ri->texture_formats[j++] = pixelformat_tab[i].sdl;
ri->num_texture_formats = j;
}