comparison src/video/directfb/SDL_DirectFB_video.c @ 2226:0e70b4b8cf84

Date: Sat, 11 Aug 2007 02:03:16 +0200 (CEST) From: couriersud arcor.de To: slouken@libsdl.org Subject: Directfb driver for SDL1.3 Hi, the attachment contains a patch for a SDL1.3 directfb driver. It supports: - Renderer "directfb": Hardware acceleration as supported by the underlying directfb driver. With a radeon X850, testsprite2 runs at 50% to 70% of OpenGL (X11, dri) performance. Also supports hardware accelerated yuv overlays. This must be enabled by sett ing: export SDL_DIRECTFB_YUV_DIRECT=1 - Renderer "opengl" Supports software opengl using mesa opengl (make linux-directfb). Some more information may be found in README.DirectFB There will certainly still be some bugs, and there is some debug code around. When I find some time, I will compile against directfb-0.9.25 as distributed with ubuntu 7.04. The diff also contains a fix for SDL_LockYUVOverlay fixing a bug in *pixels and pitches initialization. Kind regards, couriersud
author Sam Lantinga <slouken@libsdl.org>
date Sat, 11 Aug 2007 21:51:19 +0000
parents 6264c973814a
children b252359547ed
comparison
equal deleted inserted replaced
2225:3bca1b7ca25b 2226:0e70b4b8cf84
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 18
19 Sam Lantinga 19 Sam Lantinga
20 slouken@libsdl.org 20 slouken@libsdl.org
21 21
22 MGA CRTC2 support by Thomas Jarosch - tomj@simonv.com 22 SDL1.3 implementation by couriersud@arcor.de
23 CRTC2 support is inspired by mplayer's dfbmga driver 23
24 written by Ville Syrj��<syrjala@sci.fi>
25 */ 24 */
25
26 /* TODO: Various
27 * Add Mouse support from 1.2 directfb driver
28 * - Interface is defined in SDL_Mouse.c.h
29 * - Default Cursor automatically created
30 */
31
26 #include "SDL_config.h" 32 #include "SDL_config.h"
27 33
28 /* DirectFB video driver implementation. 34 /* DirectFB video driver implementation.
29 */ 35 */
30 36
40 #include "../SDL_sysvideo.h" 46 #include "../SDL_sysvideo.h"
41 #include "../SDL_pixels_c.h" 47 #include "../SDL_pixels_c.h"
42 #include "../../events/SDL_events_c.h" 48 #include "../../events/SDL_events_c.h"
43 #include "SDL_DirectFB_video.h" 49 #include "SDL_DirectFB_video.h"
44 #include "SDL_DirectFB_events.h" 50 #include "SDL_DirectFB_events.h"
45 #include "SDL_DirectFB_yuv.h"
46
47 /* The implementation dependent data for the window manager cursor */
48 struct WMcursor
49 {
50 int unused;
51 };
52
53
54 /* Initialization/Query functions */
55 static int DirectFB_VideoInit(_THIS, SDL_PixelFormat * vformat);
56 static SDL_Rect **DirectFB_ListModes(_THIS, SDL_PixelFormat * format,
57 Uint32 flags);
58 static SDL_Surface *DirectFB_SetVideoMode(_THIS, SDL_Surface * current,
59 int width, int height, int bpp,
60 Uint32 flags);
61 static int DirectFB_SetColors(_THIS, int firstcolor, int ncolors,
62 SDL_Color * colors);
63 static void DirectFB_VideoQuit(_THIS);
64
65 /* Hardware surface functions */
66 static int DirectFB_AllocHWSurface(_THIS, SDL_Surface * surface);
67 static int DirectFB_FillHWRect(_THIS, SDL_Surface * dst, SDL_Rect * dstrect,
68 Uint32 color);
69 static int DirectFB_LockHWSurface(_THIS, SDL_Surface * surface);
70 static void DirectFB_UnlockHWSurface(_THIS, SDL_Surface * surface);
71 static void DirectFB_FreeHWSurface(_THIS, SDL_Surface * surface);
72 static int DirectFB_CheckHWBlit(_THIS, SDL_Surface * src, SDL_Surface * dst);
73 static int DirectFB_HWAccelBlit(SDL_Surface * src, SDL_Rect * srcrect,
74 SDL_Surface * dst, SDL_Rect * dstrect);
75 static int DirectFB_SetHWColorKey(_THIS, SDL_Surface * surface, Uint32 key);
76 static int DirectFB_SetHWAlpha(_THIS, SDL_Surface * surface, Uint8 alpha);
77 static int DirectFB_FlipHWSurface(_THIS, SDL_Surface * surface);
78 static int DirectFB_ShowWMCursor(_THIS, WMcursor * cursor);
79
80 /* Various screen update functions available */
81 static void DirectFB_DirectUpdate(_THIS, int numrects, SDL_Rect * rects);
82 static void DirectFB_WindowedUpdate(_THIS, int numrects, SDL_Rect * rects);
83 51
84 /* This is the rect EnumModes2 uses */ 52 /* This is the rect EnumModes2 uses */
85 struct DirectFBEnumRect 53 struct DirectFBEnumRect
86 { 54 {
87 SDL_Rect r; 55 SDL_Rect r;
88 struct DirectFBEnumRect *next; 56 struct DirectFBEnumRect *next;
89 }; 57 };
90 58
91 static struct DirectFBEnumRect *enumlist = NULL; 59 struct DirectFB_GLContext
92 60 {
61 IDirectFBGL *context;
62 };
63
64 /* Initialization/Query functions */
65 static int DirectFB_VideoInit(_THIS);
66 static void DirectFB_VideoQuit(_THIS);
67
68 static int DirectFB_CreateWindow(_THIS, SDL_Window * window);
69 static int DirectFB_CreateWindowFrom(_THIS, SDL_Window * window,
70 const void *data);
71 static void DirectFB_SetWindowTitle(_THIS, SDL_Window * window);
72 static void DirectFB_SetWindowPosition(_THIS, SDL_Window * window);
73 static void DirectFB_SetWindowSize(_THIS, SDL_Window * window);
74 static void DirectFB_ShowWindow(_THIS, SDL_Window * window);
75 static void DirectFB_HideWindow(_THIS, SDL_Window * window);
76 static void DirectFB_RaiseWindow(_THIS, SDL_Window * window);
77 static void DirectFB_MaximizeWindow(_THIS, SDL_Window * window);
78 static void DirectFB_MinimizeWindow(_THIS, SDL_Window * window);
79 static void DirectFB_RestoreWindow(_THIS, SDL_Window * window);
80 static void DirectFB_SetWindowGrab(_THIS, SDL_Window * window);
81 static void DirectFB_DestroyWindow(_THIS, SDL_Window * window);
82 static SDL_bool DirectFB_GetWindowWMInfo(_THIS, SDL_Window * window,
83 struct SDL_SysWMinfo *info);
84
85 static void DirectFB_GetDisplayModes(_THIS);
86 static int DirectFB_SetDisplayMode(_THIS, SDL_DisplayMode * mode);
87
88 static int DirectFB_SetDisplayGammaRamp(_THIS, Uint16 * ramp);
89 static int DirectFB_GetDisplayGammaRamp(_THIS, Uint16 * ramp);
90
91 #if SDL_DIRECTFB_OPENGL
92 static int DirectFB_GL_LoadLibrary(_THIS, const char *path);
93 static void DirectFB_GL_UnloadLibrary(_THIS);
94 static void *DirectFB_GL_GetProcAddress(_THIS, const char *proc);
95 static SDL_GLContext DirectFB_GL_CreateContext(_THIS, SDL_Window * window);
96 static int DirectFB_GL_MakeCurrent(_THIS, SDL_Window * window,
97 SDL_GLContext context);
98 static int DirectFB_GL_SetSwapInterval(_THIS, int interval);
99 static int DirectFB_GL_GetSwapInterval(_THIS);
100 static void DirectFB_GL_SwapWindow(_THIS, SDL_Window * window);
101 static void DirectFB_GL_DeleteContext(_THIS, SDL_GLContext context);
102
103 #endif
93 104
94 /* DirectFB driver bootstrap functions */ 105 /* DirectFB driver bootstrap functions */
95 106
96 static int 107 static int
97 DirectFB_Available(void) 108 DirectFB_Available(void)
100 } 111 }
101 112
102 static void 113 static void
103 DirectFB_DeleteDevice(SDL_VideoDevice * device) 114 DirectFB_DeleteDevice(SDL_VideoDevice * device)
104 { 115 {
105 SDL_free(device->hidden); 116 SDL_free(device->driverdata);
106 SDL_free(device); 117 SDL_free(device);
107 } 118 }
108 119
109 static SDL_VideoDevice * 120 static SDL_VideoDevice *
110 DirectFB_CreateDevice(int devindex) 121 DirectFB_CreateDevice(int devindex)
111 { 122 {
112 SDL_VideoDevice *device; 123 SDL_VideoDevice *device;
113 124
114 /* Initialize all variables that we clean on shutdown */ 125 /* Initialize all variables that we clean on shutdown */
115 device = (SDL_VideoDevice *) SDL_malloc(sizeof(SDL_VideoDevice)); 126 SDL_DFB_CALLOC(device, 1, sizeof(SDL_VideoDevice));
116 if (device) { 127 SDL_DFB_CALLOC(device->gl_data, 1, sizeof(*device->gl_data));
117 SDL_memset(device, 0, (sizeof *device)); 128
118 device->hidden = (struct SDL_PrivateVideoData *) 129 /* Set the function pointers */
119 malloc(sizeof(*device->hidden));
120 }
121 if (device == NULL || device->hidden == NULL) {
122 SDL_OutOfMemory();
123 if (device) {
124 free(device);
125 }
126 return (0);
127 }
128 SDL_memset(device->hidden, 0, sizeof(*device->hidden));
129 130
130 /* Set the function pointers */ 131 /* Set the function pointers */
131 device->VideoInit = DirectFB_VideoInit; 132 device->VideoInit = DirectFB_VideoInit;
132 device->ListModes = DirectFB_ListModes;
133 device->SetVideoMode = DirectFB_SetVideoMode;
134 device->SetColors = DirectFB_SetColors;
135 device->UpdateRects = NULL;
136 device->CreateYUVOverlay = DirectFB_CreateYUVOverlay;
137 device->VideoQuit = DirectFB_VideoQuit; 133 device->VideoQuit = DirectFB_VideoQuit;
138 device->AllocHWSurface = DirectFB_AllocHWSurface; 134 device->GetDisplayModes = DirectFB_GetDisplayModes;
139 device->CheckHWBlit = DirectFB_CheckHWBlit; 135 device->SetDisplayMode = DirectFB_SetDisplayMode;
140 device->FillHWRect = DirectFB_FillHWRect; 136 #if 0
141 device->SetHWColorKey = DirectFB_SetHWColorKey; 137 device->SetDisplayGammaRamp = DirectFB_SetDisplayGammaRamp;
142 device->SetHWAlpha = DirectFB_SetHWAlpha; 138 device->GetDisplayGammaRamp = DirectFB_GetDisplayGammaRamp;
143 device->LockHWSurface = DirectFB_LockHWSurface; 139 #else
144 device->UnlockHWSurface = DirectFB_UnlockHWSurface; 140 device->SetDisplayGammaRamp = NULL;
145 device->FlipHWSurface = DirectFB_FlipHWSurface; 141 device->GetDisplayGammaRamp = NULL;
146 device->FreeHWSurface = DirectFB_FreeHWSurface; 142 #endif
147 device->ShowWMCursor = DirectFB_ShowWMCursor; 143 device->PumpEvents = DirectFB_PumpEventsWindow;
148 device->SetCaption = NULL; 144
149 device->SetIcon = NULL; 145 device->CreateWindow = DirectFB_CreateWindow;
150 device->IconifyWindow = NULL; 146 device->CreateWindowFrom = DirectFB_CreateWindowFrom;
151 device->GrabInput = NULL; 147 device->SetWindowTitle = DirectFB_SetWindowTitle;
152 device->GetWMInfo = NULL; 148 device->SetWindowPosition = DirectFB_SetWindowPosition;
153 device->InitOSKeymap = DirectFB_InitOSKeymap; 149 device->SetWindowSize = DirectFB_SetWindowSize;
154 device->PumpEvents = DirectFB_PumpEvents; 150 device->ShowWindow = DirectFB_ShowWindow;
151 device->HideWindow = DirectFB_HideWindow;
152 device->RaiseWindow = DirectFB_RaiseWindow;
153 device->MaximizeWindow = DirectFB_MaximizeWindow;
154 device->MinimizeWindow = DirectFB_MinimizeWindow;
155 device->RestoreWindow = DirectFB_RestoreWindow;
156 device->SetWindowGrab = DirectFB_SetWindowGrab;
157 device->DestroyWindow = DirectFB_DestroyWindow;
158 device->GetWindowWMInfo = DirectFB_GetWindowWMInfo;
159
160 #if SDL_DIRECTFB_OPENGL
161 device->GL_LoadLibrary = DirectFB_GL_LoadLibrary;
162 device->GL_GetProcAddress = DirectFB_GL_GetProcAddress;
163 device->GL_MakeCurrent = DirectFB_GL_MakeCurrent;
164
165 device->GL_CreateContext = DirectFB_GL_CreateContext;
166 device->GL_SetSwapInterval = DirectFB_GL_SetSwapInterval;
167 device->GL_GetSwapInterval = DirectFB_GL_GetSwapInterval;
168 device->GL_SwapWindow = DirectFB_GL_SwapWindow;
169 device->GL_DeleteContext = DirectFB_GL_DeleteContext;
170
171 #endif
155 172
156 device->free = DirectFB_DeleteDevice; 173 device->free = DirectFB_DeleteDevice;
157 174
158 return device; 175 return device;
176 error:
177 if (device)
178 free(device);
179 return (0);
159 } 180 }
160 181
161 VideoBootStrap DirectFB_bootstrap = { 182 VideoBootStrap DirectFB_bootstrap = {
162 "directfb", "DirectFB", 183 "directfb", "DirectFB",
163 DirectFB_Available, DirectFB_CreateDevice 184 DirectFB_Available, DirectFB_CreateDevice
164 }; 185 };
165 186
166 static DFBSurfacePixelFormat
167 GetFormatForBpp(int bpp, IDirectFBDisplayLayer * layer)
168 {
169 DFBDisplayLayerConfig dlc;
170 int bytes = (bpp + 7) / 8;
171
172 layer->GetConfiguration(layer, &dlc);
173
174 if (bytes == DFB_BYTES_PER_PIXEL(dlc.pixelformat) && bytes > 1)
175 return dlc.pixelformat;
176
177 switch (bytes) {
178 case 1:
179 return DSPF_LUT8;
180 case 2:
181 return DSPF_RGB16;
182 case 3:
183 return DSPF_RGB24;
184 case 4:
185 return DSPF_RGB32;
186 }
187
188 return DSPF_UNKNOWN;
189 }
190
191 static DFBEnumerationResult 187 static DFBEnumerationResult
192 EnumModesCallback(int width, int height, int bpp, void *data) 188 EnumModesCallback(int width, int height, int bpp, void *data)
193 { 189 {
194 SDL_VideoDevice *this = (SDL_VideoDevice *) data; 190 SDL_VideoDisplay *this = (SDL_VideoDisplay *) data;
195 struct DirectFBEnumRect *enumrect; 191 DFB_DisplayData *dispdata = (DFB_DisplayData *) this->driverdata;
196 192 SDL_DisplayMode mode;
197 HIDDEN->nummodes++; 193
198 194 mode.w = width;
199 if (enumlist && enumlist->r.w == width && enumlist->r.h == height) 195 mode.h = height;
200 return DFENUM_OK; 196 mode.refresh_rate = 0;
201 197 mode.driverdata = NULL;
202 enumrect = SDL_calloc(1, sizeof(struct DirectFBEnumRect)); 198 mode.format = 0;
203 if (!enumrect) { 199
204 SDL_OutOfMemory(); 200 if (dispdata->nummodes < DFB_MAX_MODES) {
205 return DFENUM_CANCEL; 201 dispdata->modelist[dispdata->nummodes++] = mode;
206 } 202 }
207 203
208 enumrect->r.w = (Uint16) width; 204 SDL_DFB_DEBUG("w %d h %d bpp %d\n", width, height, bpp);
209 enumrect->r.h = (Uint16) height;
210 enumrect->next = enumlist;
211
212 enumlist = enumrect;
213
214 return DFENUM_OK; 205 return DFENUM_OK;
215 } 206 }
216 207
217 struct private_hwdata 208 static int
218 { 209 DFBToSDLPixelFormat(DFBSurfacePixelFormat pixelformat, Uint32 * fmt)
219 IDirectFBSurface *surface; 210 {
220 IDirectFBPalette *palette; 211 switch (pixelformat) {
221 }; 212 case DSPF_ALUT44:
222 213 *fmt = SDL_PIXELFORMAT_INDEX4LSB;
223 void 214 break;
224 SetDirectFBerror(const char *function, DFBResult code) 215 case DSPF_LUT8:
225 { 216 *fmt = SDL_PIXELFORMAT_INDEX8;
226 const char *error = DirectFBErrorString(code); 217 break;
227 218 case DSPF_RGB332:
228 if (error) 219 *fmt = SDL_PIXELFORMAT_RGB332;
229 SDL_SetError("%s: %s", function, error); 220 break;
230 else 221 case DSPF_ARGB4444:
231 SDL_SetError("Unknown error code from %s", function); 222 *fmt = SDL_PIXELFORMAT_ARGB4444;
232 } 223 break;
233 224 case SDL_PIXELFORMAT_ARGB1555:
234 static DFBSurfacePixelFormat 225 *fmt = SDL_PIXELFORMAT_ARGB1555;
235 SDLToDFBPixelFormat(SDL_PixelFormat * format) 226 break;
236 { 227 case DSPF_RGB16:
237 if (format->Rmask && format->Gmask && format->Bmask) { 228 *fmt = SDL_PIXELFORMAT_RGB565;
238 switch (format->BitsPerPixel) { 229 break;
239 case 8: 230 case DSPF_RGB24:
240 return DSPF_LUT8; 231 *fmt = SDL_PIXELFORMAT_RGB24;
241 232 break;
242 case 16: 233 case DSPF_RGB32:
243 if (format->Rmask == 0xF800 && 234 *fmt = SDL_PIXELFORMAT_RGB888;
244 format->Gmask == 0x07E0 && format->Bmask == 0x001F) 235 break;
245 return DSPF_RGB16; 236 case DSPF_ARGB:
246 /* fall through */ 237 *fmt = SDL_PIXELFORMAT_ARGB8888;
247 238 break;
248 case 15: 239 case DSPF_YV12:
249 if (format->Rmask == 0x7C00 && 240 *fmt = SDL_PIXELFORMAT_YV12;
250 format->Gmask == 0x03E0 && format->Bmask == 0x001F) 241 break; /* Planar mode: Y + V + U (3 planes) */
251 return DSPF_ARGB1555; 242 case DSPF_I420:
252 break; 243 *fmt = SDL_PIXELFORMAT_IYUV;
253 244 break; /* Planar mode: Y + U + V (3 planes) */
254 case 24: 245 case DSPF_YUY2:
255 if (format->Rmask == 0xFF0000 && 246 *fmt = SDL_PIXELFORMAT_YUY2;
256 format->Gmask == 0x00FF00 && format->Bmask == 0x0000FF) 247 break; /* Packed mode: Y0+U0+Y1+V0 (1 plane) */
257 return DSPF_RGB24; 248 case DSPF_UYVY:
258 break; 249 *fmt = SDL_PIXELFORMAT_UYVY;
259 250 break; /* Packed mode: U0+Y0+V0+Y1 (1 plane) */
260 case 32: 251 default:
261 if (format->Rmask == 0xFF0000 && 252 return -1;
262 format->Gmask == 0x00FF00 && format->Bmask == 0x0000FF) { 253 }
263 if (format->Amask == 0xFF000000) 254 return 0;
264 return DSPF_ARGB; 255 }
265 else 256
266 return DSPF_RGB32; 257 static DFBEnumerationResult
267 } 258 cbScreens(DFBScreenID screen_id, DFBScreenDescription desc,
268 break; 259 void *callbackdata)
260 {
261 DFB_DeviceData *devdata = (DFB_DeviceData *) callbackdata;
262
263 devdata->screenid[devdata->numscreens++] = screen_id;
264 return DFENUM_OK;
265 }
266
267 DFBEnumerationResult
268 cbLayers(DFBDisplayLayerID layer_id, DFBDisplayLayerDescription desc,
269 void *callbackdata)
270 {
271 DFB_DeviceData *devdata = (DFB_DeviceData *) callbackdata;
272
273 if (desc.caps & DLCAPS_SURFACE) {
274 if ((desc.type & DLTF_GRAPHICS) && (desc.type & DLTF_VIDEO)) {
275 if (devdata->vidlayer[devdata->aux] == -1)
276 devdata->vidlayer[devdata->aux] = layer_id;
277 } else if (desc.type & DLTF_GRAPHICS) {
278 if (devdata->gralayer[devdata->aux] == -1)
279 devdata->gralayer[devdata->aux] = layer_id;
269 } 280 }
270 } else { 281 }
271 switch (format->BitsPerPixel) { 282 return DFENUM_OK;
272 case 8:
273 return DSPF_LUT8;
274 case 15:
275 return DSPF_ARGB1555;
276 case 16:
277 return DSPF_RGB16;
278 case 24:
279 return DSPF_RGB24;
280 case 32:
281 return DSPF_RGB32;
282 }
283 }
284
285 return DSPF_UNKNOWN;
286 }
287
288 static SDL_Palette *
289 AllocatePalette(int size)
290 {
291 SDL_Palette *palette;
292 SDL_Color *colors;
293
294 palette = SDL_calloc(1, sizeof(SDL_Palette));
295 if (!palette) {
296 SDL_OutOfMemory();
297 return NULL;
298 }
299
300 colors = SDL_calloc(size, sizeof(SDL_Color));
301 if (!colors) {
302 SDL_OutOfMemory();
303 return NULL;
304 }
305
306 palette->ncolors = size;
307 palette->colors = colors;
308
309 return palette;
310 } 283 }
311 284
312 static int 285 static int
313 DFBToSDLPixelFormat(DFBSurfacePixelFormat pixelformat, 286 DirectFB_VideoInit(_THIS)
314 SDL_PixelFormat * format) 287 {
315 {
316 format->Amask = format->Rmask = format->Gmask = format->Bmask = 0;
317 format->BitsPerPixel = format->BytesPerPixel = 0;
318
319 switch (pixelformat) {
320 case DSPF_A8:
321 format->Amask = 0x000000FF;
322 break;
323
324 case DSPF_ARGB1555:
325 format->Rmask = 0x00007C00;
326 format->Gmask = 0x000003E0;
327 format->Bmask = 0x0000001F;
328 break;
329
330 case DSPF_RGB16:
331 format->Rmask = 0x0000F800;
332 format->Gmask = 0x000007E0;
333 format->Bmask = 0x0000001F;
334 break;
335
336 case DSPF_ARGB:
337 format->Amask = 0; /* apps don't seem to like that: 0xFF000000; */
338 /* fall through */
339 case DSPF_RGB24:
340 case DSPF_RGB32:
341 format->Rmask = 0x00FF0000;
342 format->Gmask = 0x0000FF00;
343 format->Bmask = 0x000000FF;
344 break;
345
346 case DSPF_LUT8:
347 format->Rmask = 0x000000FF;
348 format->Gmask = 0x000000FF;
349 format->Bmask = 0x000000FF;
350
351 if (!format->palette)
352 format->palette = AllocatePalette(256);
353 break;
354
355 default:
356 fprintf(stderr,
357 "SDL_DirectFB: Unsupported pixelformat (0x%08x)!\n",
358 pixelformat);
359 return -1;
360 }
361
362 format->BitsPerPixel = DFB_BYTES_PER_PIXEL(pixelformat) * 8;
363 format->BytesPerPixel = DFB_BYTES_PER_PIXEL(pixelformat);
364
365 return 0;
366 }
367
368
369 int
370 DirectFB_VideoInit(_THIS, SDL_PixelFormat * vformat)
371 {
372 int i;
373 DFBResult ret;
374 #if (DIRECTFB_MAJOR_VERSION == 0) && (DIRECTFB_MINOR_VERSION == 9) && (DIRECTFB_MICRO_VERSION < 23) 288 #if (DIRECTFB_MAJOR_VERSION == 0) && (DIRECTFB_MINOR_VERSION == 9) && (DIRECTFB_MICRO_VERSION < 23)
375 DFBCardCapabilities caps; 289 DFBCardCapabilities caps;
376 #else 290 #else
377 DFBGraphicsDeviceDescription caps; 291 DFBGraphicsDeviceDescription caps;
378 #endif 292 #endif
379 DFBDisplayLayerConfig dlc; 293 DFBDisplayLayerConfig dlc;
380 struct DirectFBEnumRect *rect; 294 struct DirectFBEnumRect *rect;
381 IDirectFB *dfb = NULL; 295 IDirectFB *dfb = NULL;
382 IDirectFBDisplayLayer *layer = NULL; 296 IDirectFBDisplayLayer *layer = NULL;
383 IDirectFBEventBuffer *events = NULL; 297
384 298 SDL_VideoDisplay display;
385 HIDDEN->c2layer = NULL, HIDDEN->c2frame = NULL; 299 DFB_DisplayData *dispdata;
386 HIDDEN->enable_mga_crtc2 = 0; 300 DFB_DeviceData *devdata;
387 HIDDEN->mga_crtc2_stretch_overscan = 1; 301 SDL_DisplayMode mode;
388 302 SDL_Keyboard keyboard;
389 ret = DirectFBInit(NULL, NULL); 303 int i;
390 if (ret) { 304 DFBResult ret;
391 SetDirectFBerror("DirectFBInit", ret); 305 int tcw[DFB_MAX_SCREENS];
392 goto error; 306 int tch[DFB_MAX_SCREENS];
393 } 307
394 308 SDL_zero(keyboard);
395 ret = DirectFBCreate(&dfb); 309
396 if (ret) { 310 SDL_DFB_CHECKERR(DirectFBInit(NULL, NULL));
397 SetDirectFBerror("DirectFBCreate", ret); 311 SDL_DFB_CHECKERR(DirectFBCreate(&dfb));
398 goto error; 312
399 } 313 SDL_DFB_CALLOC(devdata, 1, sizeof(*devdata));
400 314 devdata->numscreens = 0;
401 ret = dfb->GetDisplayLayer(dfb, DLID_PRIMARY, &layer); 315 for (i = 0; i < DFB_MAX_SCREENS; i++) {
402 if (ret) { 316 devdata->gralayer[i] = -1;
403 SetDirectFBerror("dfb->GetDisplayLayer", ret); 317 devdata->vidlayer[i] = -1;
404 goto error; 318 }
405 } 319 SDL_DFB_CHECKERR(dfb->EnumScreens(dfb, &cbScreens, devdata));
406 320 for (i = 0; i < devdata->numscreens; i++) {
407 ret = dfb->CreateInputEventBuffer(dfb, DICAPS_ALL, DFB_FALSE, &events); 321 IDirectFBScreen *screen;
408 if (ret) { 322
409 SetDirectFBerror("dfb->CreateEventBuffer", ret); 323 SDL_DFB_CHECKERR(dfb->GetScreen(dfb, devdata->screenid[i], &screen));
410 goto error; 324
411 } 325 devdata->aux = i;
412 326 SDL_DFB_CHECKERR(screen->
413 layer->EnableCursor(layer, 1); 327 EnumDisplayLayers(screen, &cbLayers, devdata));
414 328 screen->GetSize(screen, &tcw[i], &tch[i]);
415 /* Query layer configuration to determine the current mode and pixelformat */ 329 screen->Release(screen);
416 layer->GetConfiguration(layer, &dlc); 330 }
417 331
418 /* If current format is not supported use LUT8 as the default */ 332 /* Query card capabilities */
419 if (DFBToSDLPixelFormat(dlc.pixelformat, vformat)) 333
420 DFBToSDLPixelFormat(DSPF_LUT8, vformat); 334 dfb->GetDeviceDescription(dfb, &caps);
421 335
422 /* Enumerate the available fullscreen modes */ 336 SDL_DFB_DEBUG("SDL directfb video driver - %s %s\n", __DATE__, __TIME__);
423 ret = dfb->EnumVideoModes(dfb, EnumModesCallback, this); 337 SDL_DFB_DEBUG("Using %s (%s) driver.\n", caps.name, caps.vendor);
424 if (ret) { 338 SDL_DFB_DEBUG("Found %d screens\n", devdata->numscreens);
425 SetDirectFBerror("dfb->EnumVideoModes", ret); 339
426 goto error; 340 for (i = 0; i < devdata->numscreens; i++) {
427 } 341 //SDL_DFB_CHECKERR( dfb->GetDisplayLayer (dfb, DLID_PRIMARY, &layer) );
428 342 SDL_DFB_CHECKERR(dfb->
429 HIDDEN->modelist = SDL_calloc(HIDDEN->nummodes + 1, sizeof(SDL_Rect *)); 343 GetDisplayLayer(dfb, devdata->gralayer[i], &layer));
430 if (!HIDDEN->modelist) { 344 //SDL_DFB_CHECKERR( dfb->CreateInputEventBuffer (dfb, DICAPS_ALL, DFB_FALSE, &events) );
431 SDL_OutOfMemory(); 345
432 goto error; 346 SDL_DFB_CHECKERR(layer->
433 } 347 SetCooperativeLevel(layer, DLSCL_ADMINISTRATIVE));
434 348 layer->EnableCursor(layer, 1);
435 for (i = 0, rect = enumlist; rect; ++i, rect = rect->next) { 349 SDL_DFB_CHECKERR(layer->SetCursorOpacity(layer, 0xC0));
436 HIDDEN->modelist[i] = &rect->r; 350 SDL_DFB_CHECKERR(layer->SetCooperativeLevel(layer, DLSCL_SHARED));
437 } 351
438 352 /* Query layer configuration to determine the current mode and pixelformat */
439 HIDDEN->modelist[i] = NULL; 353 layer->GetConfiguration(layer, &dlc);
440 354
441 355 DFBToSDLPixelFormat(dlc.pixelformat, &mode.format);
442 /* Query card capabilities to get the video memory size */ 356
443 #if (DIRECTFB_MAJOR_VERSION == 0) && (DIRECTFB_MINOR_VERSION == 9) && (DIRECTFB_MICRO_VERSION < 23) 357 mode.w = dlc.width;
444 dfb->GetCardCapabilities(dfb, &caps); 358 mode.h = dlc.height;
359 mode.refresh_rate = 0;
360 mode.driverdata = NULL;
361
362 SDL_DFB_CALLOC(dispdata, 1, sizeof(*dispdata));
363
364 dispdata->layer = layer;
365 dispdata->pixelformat = dlc.pixelformat;
366 dispdata->cw = tcw[i];
367 dispdata->ch = tch[i];
368
369 /* YUV - Video layer */
370
371 dispdata->vidID = devdata->vidlayer[i];
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->
383 EnumVideoModes(dfb, EnumModesCallback, &display));
384
385 SDL_AddVideoDisplay(&display);
386 }
387
388 devdata->initialized = 1;
389 devdata->dfb = dfb;
390 devdata->firstwin = NULL;
391
392 _this->driverdata = devdata;
393
394
395 #if SDL_DIRECTFB_OPENGL
396 /* Opengl */
397 _this->gl_data->gl_active = 0;
398 _this->gl_data->gl_context = NULL;
399 #endif
400
401 DirectFB_AddRenderDriver(_this);
402 DirectFB_InitMouse(_this);
403 //devdata->mouse = SDL_AddMouse(&mouse, -1);
404 devdata->keyboard = SDL_AddKeyboard(&keyboard, -1);
405 DirectFB_InitOSKeymap(_this);
406
407 return 0;
408
409
410 error:
411 //FIXME: Cleanup not complete, Free existing displays
412 SDL_DFB_FREE(dispdata);
413 SDL_DFB_FREE(dispdata->modelist);
414 SDL_DFB_RELEASE(layer);
415 SDL_DFB_RELEASE(dfb);
416 return -1;
417 }
418
419 static void
420 DirectFB_VideoQuit(_THIS)
421 {
422 DFB_DeviceData *devdata = (DFB_DeviceData *) _this->driverdata;
423 SDL_DisplayMode tmode;
424 DFBResult ret;
425 int i;
426
427 tmode = _this->displays[0].desktop_mode;
428 tmode.format = SDL_PIXELFORMAT_UNKNOWN;
429 DirectFB_SetDisplayMode(_this, &tmode);
430 tmode = _this->displays[0].desktop_mode;
431 DirectFB_SetDisplayMode(_this, &tmode);
432
433 for (i = 0; i < devdata->numscreens; i++) {
434 DFB_DisplayData *dispdata =
435 (DFB_DisplayData *) _this->displays[i].driverdata;
436 if (dispdata->layer) {
437 SDL_DFB_CHECK(dispdata->layer->
438 SetCooperativeLevel(dispdata->layer,
439 DLSCL_ADMINISTRATIVE));
440 SDL_DFB_CHECK(dispdata->layer->
441 SetCursorOpacity(dispdata->layer, 0x00));
442 SDL_DFB_CHECK(dispdata->layer->
443 SetCooperativeLevel(dispdata->layer, 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->eventbuffer);
457
458 SDL_DFB_RELEASE(devdata->dfb);
459
460 SDL_DelMouse(devdata->mouse);
461 SDL_DelKeyboard(devdata->keyboard);
462
463 #if SDL_DIRECTFB_OPENGL
464 DirectFB_GL_UnloadLibrary(_this);
465 #endif
466
467 devdata->initialized = 0;
468 }
469
470
471 static DFBSurfacePixelFormat
472 SDLToDFBPixelFormat(Uint32 format)
473 {
474 switch (format) {
475 case SDL_PIXELFORMAT_INDEX4LSB:
476 return DSPF_ALUT44;
477 case SDL_PIXELFORMAT_INDEX8:
478 return DSPF_LUT8;
479 case SDL_PIXELFORMAT_RGB332:
480 return DSPF_RGB332;
481 case SDL_PIXELFORMAT_RGB555:
482 return DSPF_ARGB1555;
483 case SDL_PIXELFORMAT_ARGB4444:
484 return DSPF_ARGB4444;
485 case SDL_PIXELFORMAT_ARGB1555:
486 return DSPF_ARGB1555;
487 case SDL_PIXELFORMAT_RGB565:
488 return DSPF_RGB16;
489 case SDL_PIXELFORMAT_RGB24:
490 return DSPF_RGB24;
491 case SDL_PIXELFORMAT_RGB888:
492 return DSPF_RGB32;
493 case SDL_PIXELFORMAT_ARGB8888:
494 return DSPF_ARGB;
495 case SDL_PIXELFORMAT_YV12:
496 return DSPF_YV12; /* Planar mode: Y + V + U (3 planes) */
497 case SDL_PIXELFORMAT_IYUV:
498 return DSPF_I420; /* Planar mode: Y + U + V (3 planes) */
499 case SDL_PIXELFORMAT_YUY2:
500 return DSPF_YUY2; /* Packed mode: Y0+U0+Y1+V0 (1 plane) */
501 case SDL_PIXELFORMAT_UYVY:
502 return DSPF_UYVY; /* Packed mode: U0+Y0+V0+Y1 (1 plane) */
503 case SDL_PIXELFORMAT_YVYU:
504 return DSPF_UNKNOWN; /* Packed mode: Y0+V0+Y1+U0 (1 plane) */
505 case SDL_PIXELFORMAT_INDEX1LSB:
506 return DSPF_UNKNOWN;
507 case SDL_PIXELFORMAT_INDEX1MSB:
508 return DSPF_UNKNOWN;
509 case SDL_PIXELFORMAT_INDEX4MSB:
510 return DSPF_UNKNOWN;
511 case SDL_PIXELFORMAT_RGB444:
512 return DSPF_UNKNOWN;
513 case SDL_PIXELFORMAT_BGR24:
514 return DSPF_UNKNOWN;
515 case SDL_PIXELFORMAT_BGR888:
516 return DSPF_UNKNOWN;
517 case SDL_PIXELFORMAT_RGBA8888:
518 return DSPF_UNKNOWN;
519 case SDL_PIXELFORMAT_ABGR8888:
520 return DSPF_UNKNOWN;
521 case SDL_PIXELFORMAT_BGRA8888:
522 return DSPF_UNKNOWN;
523 case SDL_PIXELFORMAT_ARGB2101010:
524 return DSPF_UNKNOWN;
525 default:
526 return DSPF_UNKNOWN;
527 }
528 }
529
530 static void
531 CheckSetDisplayMode(_THIS, DFB_DisplayData * data, SDL_DisplayMode * mode)
532 {
533 DFBDisplayLayerConfig config;
534 DFBDisplayLayerConfigFlags failed;
535
536 config.width = mode->w;
537 config.height = mode->h;
538 config.pixelformat = SDLToDFBPixelFormat(mode->format);
539 config.flags = DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT;
540 failed = 0;
541 data->layer->TestConfiguration(data->layer, &config, &failed);
542 if (failed == 0)
543 SDL_AddDisplayMode(_this->current_display, mode);
544
545 }
546
547 static void
548 DirectFB_GetDisplayModes(_THIS)
549 {
550 //SDL_DisplayData *data = (SDL_DisplayData *) SDL_CurrentDisplay.driverdata;
551 //SDL_DisplayMode mode;
552 //SDL_AddDisplayMode(_this->current_display, &mode);
553
554 SDL_DFB_DEVICEDATA(_this);
555 DFB_DisplayData *data = (DFB_DisplayData *) SDL_CurrentDisplay.driverdata;
556 int i;
557 SDL_DisplayMode mode;
558
559 for (i = 0; i < data->nummodes; ++i) {
560 mode = data->modelist[i];
561 //mode.format = SDL_PIXELFORMAT_UNKNOWN;
562
563 mode.format = SDL_PIXELFORMAT_INDEX8;
564 CheckSetDisplayMode(_this, data, &mode);
565 mode.format = SDL_PIXELFORMAT_RGB565;
566 CheckSetDisplayMode(_this, data, &mode);
567 mode.format = SDL_PIXELFORMAT_RGB24;
568 CheckSetDisplayMode(_this, data, &mode);
569 mode.format = SDL_PIXELFORMAT_RGB888;
570 CheckSetDisplayMode(_this, data, &mode);
571 }
572 }
573
574 int
575 DirectFB_SetDisplayMode(_THIS, SDL_DisplayMode * mode)
576 {
577 SDL_DFB_DEVICEDATA(_this);
578 DFB_DisplayData *data = (DFB_DisplayData *) SDL_CurrentDisplay.driverdata;
579 DFBDisplayLayerConfig config, rconfig;
580 DFBDisplayLayerConfigFlags fail = 0;
581 DFBResult ret;
582
583 SDL_DFB_CHECKERR(data->layer->
584 SetCooperativeLevel(data->layer, DLSCL_ADMINISTRATIVE));
585
586 SDL_DFB_CHECKERR(data->layer->GetConfiguration(data->layer, &config));
587 config.flags = DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_BUFFERMODE;
588 if (mode->format != SDL_PIXELFORMAT_UNKNOWN) {
589 config.flags |= DLCONF_PIXELFORMAT;
590 config.pixelformat = SDLToDFBPixelFormat(mode->format);
591 data->pixelformat = config.pixelformat;
592 }
593 config.width = mode->w;
594 config.height = mode->h;
595
596 config.buffermode = DLBM_BACKVIDEO;
597
598 //config.pixelformat = GetFormatForBpp (bpp, HIDDEN->layer);
599
600 data->layer->TestConfiguration(data->layer, &config, &fail);
601 if (fail & (DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT)) {
602 SDL_DFB_DEBUG("Error setting mode %dx%d-%x\n", mode->w, mode->h,
603 mode->format);
604 return -1;
605 }
606 SDL_DFB_DEBUG("Trace\n");
607 config.flags &= ~fail;
608 SDL_DFB_CHECKERR(data->layer->SetConfiguration(data->layer, &config));
609 SDL_DFB_CHECKERR(data->layer->
610 SetCooperativeLevel(data->layer, DLSCL_ADMINISTRATIVE));
611
612 /* Double check */
613 SDL_DFB_CHECKERR(data->layer->GetConfiguration(data->layer, &rconfig));
614
615 if ((config.width != rconfig.width) ||
616 (config.height != rconfig.height) ||
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 return 0;
624 error:
625 return -1;
626 }
627
628 static int
629 DirectFB_SetDisplayGammaRamp(_THIS, Uint16 * ramp)
630 {
631 return -1;
632 }
633
634 static int
635 DirectFB_GetDisplayGammaRamp(_THIS, Uint16 * ramp)
636 {
637 return -1;
638 }
639
640 static int
641 DirectFB_CreateWindow(_THIS, SDL_Window * window)
642 {
643 SDL_DFB_DEVICEDATA(_this);
644 SDL_DFB_DISPLAYDATA(_this, window);
645 DFB_WindowData *windata;
646 DFBWindowOptions wopts;
647 DFBWindowDescription desc;
648 int ret, x, y;
649
650 SDL_DFB_DEBUG("Trace x %d y %d w %d h %d\n", window->x, window->y,
651 window->w, window->h);
652 window->driverdata = NULL;
653 SDL_DFB_CALLOC(window->driverdata, 1, sizeof(DFB_WindowData));
654 windata = (DFB_WindowData *) window->driverdata;
655
656 SDL_DFB_CHECKERR(devdata->dfb->
657 SetCooperativeLevel(devdata->dfb, DFSCL_NORMAL));
658 SDL_DFB_CHECKERR(dispdata->layer->
659 SetCooperativeLevel(dispdata->layer,
660 DLSCL_ADMINISTRATIVE));
661
662 /* Fill the window description. */
663 if (window->x == SDL_WINDOWPOS_CENTERED) {
664 x = (dispdata->cw - window->w) / 2;
665 } else if (window->x == SDL_WINDOWPOS_UNDEFINED) {
666 x = 0;
667 } else {
668 x = window->x;
669 }
670 if (window->y == SDL_WINDOWPOS_CENTERED) {
671 y = (dispdata->ch - window->h) / 2;
672 } else if (window->y == SDL_WINDOWPOS_UNDEFINED) {
673 y = 0;
674 } else {
675 y = window->y;
676 }
677
678 desc.flags =
679 DWDESC_WIDTH | DWDESC_HEIGHT | DWDESC_CAPS | DWDESC_PIXELFORMAT;
680 desc.flags |= DWDESC_POSX | DWDESC_POSY | DWDESC_SURFACE_CAPS;
681 desc.posx = x;
682 desc.posy = y;
683 desc.width = window->w;
684 desc.height = window->h;
685
686 desc.pixelformat = dispdata->pixelformat;
687
688 desc.caps = 0; //DWCAPS_DOUBLEBUFFER;
689 desc.surface_caps = DSCAPS_DOUBLE | DSCAPS_TRIPLE; //| DSCAPS_PREMULTIPLIED;
690
691 /* Create the window. */
692 SDL_DFB_CHECKERR(dispdata->layer->
693 CreateWindow(dispdata->layer, &desc, &windata->window));
694
695 windata->window->GetOptions(windata->window, &wopts);
696 #if (DIRECTFB_MAJOR_VERSION == 1) && (DIRECTFB_MINOR_VERSION >= 0)
697
698 if (window->flags & SDL_WINDOW_RESIZABLE)
699 wopts |= DWOP_SCALE;
700 else
701 wopts |= DWOP_KEEP_SIZE;
445 #else 702 #else
446 dfb->GetDeviceDescription(dfb, &caps); 703 wopts |= DWOP_KEEP_SIZE; // if not we will crash ...
447 #endif 704 #endif
448 705
449 this->info.wm_available = 1; 706 if (window->flags & SDL_WINDOW_FULLSCREEN)
450 this->info.hw_available = 1; 707 wopts |= DWOP_KEEP_POSITION | DWOP_KEEP_STACKING | DWOP_KEEP_SIZE;
451 this->info.blit_hw = 1; 708
452 this->info.blit_hw_CC = 1; 709 windata->window->SetOptions(windata->window, wopts);
453 this->info.blit_hw_A = 1; 710 /* Get the window's surface. */
454 this->info.blit_fill = 1; 711 SDL_DFB_CHECKERR(windata->window->
455 this->info.video_mem = caps.video_memory / 1024; 712 GetSurface(windata->window, &windata->surface));
456 this->info.current_w = dlc.width; 713 windata->window->SetOpacity(windata->window, 0xFF);
457 this->info.current_h = dlc.height; 714 SDL_DFB_CHECKERR(windata->window->
458 715 CreateEventBuffer(windata->window,
459 HIDDEN->initialized = 1; 716 &(windata->eventbuffer)));
460 HIDDEN->dfb = dfb; 717 SDL_DFB_CHECKERR(windata->window->
461 HIDDEN->layer = layer; 718 EnableEvents(windata->window,
462 HIDDEN->eventbuffer = events; 719 DWET_POSITION | DWET_SIZE | DWET_CLOSE |
463 720 DWET_ALL));
464 if (SDL_getenv("SDL_DIRECTFB_MGA_CRTC2") != NULL) 721
465 HIDDEN->enable_mga_crtc2 = 1; 722 if (window->flags & SDL_WINDOW_FULLSCREEN)
466 723 windata->window->SetStackingClass(windata->window, DWSC_UPPER);
467 if (HIDDEN->enable_mga_crtc2) { 724 /* Make it the top most window. */
468 DFBDisplayLayerConfig dlc; 725 windata->window->RaiseToTop(windata->window);
469 DFBDisplayLayerConfigFlags failed; 726
470 727 windata->window->GetID(windata->window, &windata->windowID);
471 ret = dfb->GetDisplayLayer(dfb, 2, &HIDDEN->c2layer); 728 windata->id = window->id;
472 if (ret) { 729
473 SetDirectFBerror("dfb->GetDisplayLayer(CRTC2)", ret); 730 #if SDL_DIRECTFB_OPENGL
474 goto error; 731 if (window->flags & SDL_WINDOW_OPENGL) {
732 if (!_this->gl_config.driver_loaded) {
733 /* no driver has been loaded, use default (ourselves) */
734 if (DirectFB_GL_LoadLibrary(_this, NULL) < 0) {
735 goto error;
736 }
475 } 737 }
476 738 _this->gl_data->gl_active = 1;
477 ret = 739 }
478 HIDDEN->layer->SetCooperativeLevel(HIDDEN->layer, 740 #endif
479 DLSCL_EXCLUSIVE); 741
480 if (ret) { 742 /* Add to list ... */
481 SetDirectFBerror 743
482 ("layer->SetCooperativeLevel(CRTC2, EXCLUSIVE)", ret); 744 windata->next = devdata->firstwin;
483 goto error; 745 windata->opacity = 0xFF;
746 devdata->firstwin = windata;
747
748 //SDL_DFB_CHECKERR( windata->surface->GetPalette(windata->surface, &windata->palette) );
749
750 return 0;
751 error:
752 SDL_DFB_RELEASE(windata->window);
753 SDL_DFB_RELEASE(windata->surface);
754 return -1;
755 }
756
757 static int
758 DirectFB_CreateWindowFrom(_THIS, SDL_Window * window, const void *data)
759 {
760 SDL_DFB_DEVICEDATA(_this);
761 SDL_DFB_WINDOWDATA(window);
762 SDL_DFB_DISPLAYDATA(_this, window);
763
764 SDL_Unsupported();
765 return -1;
766 }
767
768 static void
769 DirectFB_SetWindowTitle(_THIS, SDL_Window * window)
770 {
771 SDL_DFB_DEVICEDATA(_this);
772 SDL_DFB_WINDOWDATA(window);
773 SDL_DFB_DISPLAYDATA(_this, window);
774
775 SDL_Unsupported();
776 //return -1;
777
778 }
779 static void
780 DirectFB_SetWindowPosition(_THIS, SDL_Window * window)
781 {
782 SDL_DFB_DEVICEDATA(_this);
783 SDL_DFB_WINDOWDATA(window);
784 SDL_DFB_DISPLAYDATA(_this, window);
785
786 windata->window->MoveTo(windata->window, window->x, window->y);
787 }
788
789 static void
790 DirectFB_SetWindowSize(_THIS, SDL_Window * window)
791 {
792 SDL_DFB_DEVICEDATA(_this);
793 SDL_DFB_WINDOWDATA(window);
794 SDL_DFB_DISPLAYDATA(_this, window);
795
796 windata->window->Resize(windata->window, window->w, window->h);
797
798 }
799 static void
800 DirectFB_ShowWindow(_THIS, SDL_Window * window)
801 {
802 SDL_DFB_DEVICEDATA(_this);
803 SDL_DFB_WINDOWDATA(window);
804 SDL_DFB_DISPLAYDATA(_this, window);
805
806 windata->window->SetOpacity(windata->window, windata->opacity);
807
808 }
809
810 static void
811 DirectFB_HideWindow(_THIS, SDL_Window * window)
812 {
813 SDL_DFB_DEVICEDATA(_this);
814 SDL_DFB_WINDOWDATA(window);
815 SDL_DFB_DISPLAYDATA(_this, window);
816
817 windata->window->GetOpacity(windata->window, &windata->opacity);
818 windata->window->SetOpacity(windata->window, 0);
819
820 }
821 static void
822 DirectFB_RaiseWindow(_THIS, SDL_Window * window)
823 {
824 SDL_DFB_DEVICEDATA(_this);
825 SDL_DFB_WINDOWDATA(window);
826 SDL_DFB_DISPLAYDATA(_this, window);
827
828 windata->window->Raise(windata->window);
829
830 }
831
832 static void
833 DirectFB_MaximizeWindow(_THIS, SDL_Window * window)
834 {
835 SDL_DFB_DEVICEDATA(_this);
836 SDL_DFB_WINDOWDATA(window);
837 SDL_DFB_DISPLAYDATA(_this, window);
838
839 SDL_Unsupported();
840
841 }
842 static void
843 DirectFB_MinimizeWindow(_THIS, SDL_Window * window)
844 {
845 SDL_DFB_DEVICEDATA(_this);
846 SDL_DFB_WINDOWDATA(window);
847 SDL_DFB_DISPLAYDATA(_this, window);
848
849 SDL_Unsupported();
850
851 }
852
853 static void
854 DirectFB_RestoreWindow(_THIS, SDL_Window * window)
855 {
856 SDL_DFB_DEVICEDATA(_this);
857 SDL_DFB_WINDOWDATA(window);
858 SDL_DFB_DISPLAYDATA(_this, window);
859
860 SDL_Unsupported();
861
862 }
863 static void
864 DirectFB_SetWindowGrab(_THIS, SDL_Window * window)
865 {
866 SDL_DFB_DEVICEDATA(_this);
867 SDL_DFB_WINDOWDATA(window);
868 SDL_DFB_DISPLAYDATA(_this, window);
869
870 SDL_Unsupported();
871
872 }
873
874 static void
875 DirectFB_DestroyWindow(_THIS, SDL_Window * window)
876 {
877 SDL_DFB_DEVICEDATA(_this);
878 SDL_DFB_WINDOWDATA(window);
879 SDL_DFB_DISPLAYDATA(_this, window);
880 DFB_WindowData *p;
881
882 SDL_DFB_DEBUG("Trace\n");
883
884 SDL_DFB_RELEASE(windata->palette);
885 SDL_DFB_RELEASE(windata->eventbuffer);
886 SDL_DFB_RELEASE(windata->surface);
887 SDL_DFB_RELEASE(windata->window);
888
889 /* Remove from list ... */
890
891 p = devdata->firstwin;
892 while (p && p->next != windata)
893 p = p->next;
894 if (p)
895 p->next = windata->next;
896 else
897 devdata->firstwin = windata->next;
898 SDL_free(windata);
899 }
900 static SDL_bool
901 DirectFB_GetWindowWMInfo(_THIS, SDL_Window * window,
902 struct SDL_SysWMinfo *info)
903 {
904 SDL_DFB_DEVICEDATA(_this);
905 SDL_DFB_WINDOWDATA(window);
906 SDL_DFB_DISPLAYDATA(_this, window);
907
908 SDL_Unsupported();
909 return SDL_FALSE;
910 }
911
912 #if SDL_DIRECTFB_OPENGL
913
914 #define OPENGL_REQUIRS_DLOPEN
915 #if defined(OPENGL_REQUIRS_DLOPEN) && defined(SDL_LOADSO_DLOPEN)
916 #include <dlfcn.h>
917 #define GL_LoadObject(X) dlopen(X, (RTLD_NOW|RTLD_GLOBAL))
918 #define GL_LoadFunction dlsym
919 #define GL_UnloadObject dlclose
920 #else
921 #define GL_LoadObject SDL_LoadObject
922 #define GL_LoadFunction SDL_LoadFunction
923 #define GL_UnloadObject SDL_UnloadObject
924 #endif
925
926 static int
927 DirectFB_GL_LoadLibrary(_THIS, const char *path)
928 {
929 SDL_DFB_DEVICEDATA(_this);
930 #
931 void *handle = NULL;
932
933 SDL_DFB_DEBUG("Loadlibrary : %s\n", path);
934
935 if (_this->gl_data->gl_active) {
936 SDL_SetError("OpenGL context already created");
937 return -1;
938 }
939
940
941 if (path == NULL) {
942 path = SDL_getenv("SDL_VIDEO_GL_DRIVER");
943 if (path == NULL) {
944 path = "libGL.so";
484 } 945 }
485 946 }
486 ret = 947
487 HIDDEN->c2layer->SetCooperativeLevel(HIDDEN->c2layer, 948 handle = GL_LoadObject(path);
488 DLSCL_EXCLUSIVE); 949 if (handle == NULL) {
489 if (ret) { 950 SDL_DFB_ERR("Library not found: %s\n", path);
490 SetDirectFBerror 951 /* SDL_LoadObject() will call SDL_SetError() for us. */
491 ("c2layer->SetCooperativeLevel(CRTC2, EXCLUSIVE)", ret); 952 return -1;
492 goto error; 953 }
493 } 954
494 955 SDL_DFB_DEBUG("Loaded library: %s\n", path);
495 HIDDEN->c2layer->SetOpacity(HIDDEN->c2layer, 0x0); 956
496 957 /* Unload the old driver and reset the pointers */
497 /* Init the surface here as it got a fixed size */ 958 DirectFB_GL_UnloadLibrary(_this);
498 dlc.flags = DLCONF_PIXELFORMAT | DLCONF_BUFFERMODE; 959
499 dlc.buffermode = DLBM_BACKVIDEO; 960 _this->gl_config.dll_handle = handle;
500 dlc.pixelformat = DSPF_RGB32; 961 _this->gl_config.driver_loaded = 1;
501 962 if (path) {
502 ret = 963 SDL_strlcpy(_this->gl_config.driver_path, path,
503 HIDDEN->c2layer->TestConfiguration(HIDDEN->c2layer, &dlc, 964 SDL_arraysize(_this->gl_config.driver_path));
504 &failed); 965 } else {
505 if (ret) { 966 *_this->gl_config.driver_path = '\0';
506 SetDirectFBerror("c2layer->TestConfiguration", ret); 967 }
507 goto error; 968
508 } 969 devdata->glFinish = DirectFB_GL_GetProcAddress(_this, "glFinish");
509 970 devdata->glFlush = DirectFB_GL_GetProcAddress(_this, "glFlush");
510 ret = HIDDEN->c2layer->SetConfiguration(HIDDEN->c2layer, &dlc); 971 return 0;
511 if (ret) { 972 }
512 SetDirectFBerror("c2layer->SetConfiguration", ret); 973
513 goto error; 974 static void
514 } 975 DirectFB_GL_UnloadLibrary(_THIS)
515 976 {
516 ret = HIDDEN->c2layer->GetSurface(HIDDEN->c2layer, &HIDDEN->c2frame); 977 SDL_DFB_DEVICEDATA(_this);
517 if (ret) { 978
518 SetDirectFBerror("c2layer->GetSurface", ret); 979 int ret;
519 goto error; 980
520 } 981 if (_this->gl_config.driver_loaded) {
521 982
522 HIDDEN->c2framesize.x = 0; 983 ret = GL_UnloadObject(_this->gl_config.dll_handle);
523 HIDDEN->c2framesize.y = 0; 984 if (ret)
524 HIDDEN->c2frame->GetSize(HIDDEN->c2frame, &HIDDEN->c2framesize.w, 985 SDL_DFB_ERR("Error #%d trying to unload library.\n", ret);
525 &HIDDEN->c2framesize.h); 986 _this->gl_config.dll_handle = NULL;
526 987 _this->gl_config.driver_loaded = 0;
527 HIDDEN->c2frame->SetBlittingFlags(HIDDEN->c2frame, DSBLIT_NOFX); 988 }
528 HIDDEN->c2frame->SetColor(HIDDEN->c2frame, 0, 0, 0, 0xff); 989 }
529 990
530 /* Clear CRTC2 */ 991 static void *
531 HIDDEN->c2frame->Clear(HIDDEN->c2frame, 0, 0, 0, 0xff); 992 DirectFB_GL_GetProcAddress(_THIS, const char *proc)
532 HIDDEN->c2frame->Flip(HIDDEN->c2frame, NULL, 0); 993 {
533 HIDDEN->c2frame->Clear(HIDDEN->c2frame, 0, 0, 0, 0xff); 994 SDL_DFB_DEVICEDATA(_this);
534 HIDDEN->c2frame->Flip(HIDDEN->c2frame, NULL, 0); 995 int ret;
535 HIDDEN->c2frame->Clear(HIDDEN->c2frame, 0, 0, 0, 0xff); 996 void *handle;
536 997
537 HIDDEN->c2layer->SetOpacity(HIDDEN->c2layer, 0xFF); 998 SDL_DFB_DEBUG("Trace %s\n", proc);
538 999 handle = _this->gl_config.dll_handle;
539 /* Check if overscan is possibly set */ 1000 return GL_LoadFunction(handle, proc);
540 if (SDL_getenv("SDL_DIRECTFB_MGA_OVERSCAN") != NULL) { 1001 }
541 float overscan = 0; 1002
542 if (SDL_sscanf 1003 static SDL_GLContext
543 (SDL_getenv("SDL_DIRECTFB_MGA_OVERSCAN"), "%f", 1004 DirectFB_GL_CreateContext(_THIS, SDL_Window * window)
544 &overscan) == 1) 1005 {
545 if (overscan > 0 && overscan < 2) 1006 SDL_DFB_DEVICEDATA(_this);
546 HIDDEN->mga_crtc2_stretch_overscan = overscan; 1007 SDL_DFB_WINDOWDATA(window);
547 } 1008 SDL_DFB_DISPLAYDATA(_this, window);
548 #ifdef DIRECTFB_CRTC2_DEBUG 1009 int ret;
549 printf("CRTC2 overscan: %f\n", HIDDEN->mga_crtc2_stretch_overscan); 1010 IDirectFBGL *context = NULL;
1011
1012 SDL_DFB_DEBUG("Trace\n");
1013 SDL_DFB_CHECKERR(windata->surface->GetGL(windata->surface, &context));
1014 SDL_DFB_CHECKERR(context->Unlock(context));
1015
1016 if (DirectFB_GL_MakeCurrent(_this, window, context) < 0) {
1017 DirectFB_GL_DeleteContext(_this, context);
1018 return NULL;
1019 }
1020
1021 return context;
1022
1023 error:
1024 return NULL;
1025 }
1026
1027 static int
1028 DirectFB_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
1029 {
1030 SDL_DFB_DEVICEDATA(_this);
1031 SDL_DFB_WINDOWDATA(window);
1032 SDL_DFB_DISPLAYDATA(_this, window);
1033 IDirectFBGL *dfb_context = (IDirectFBGL *) context;
1034 int ret;
1035
1036 if (dfb_context) {
1037 dfb_context->Unlock(dfb_context);
1038 SDL_DFB_CHECKERR(dfb_context->Lock(dfb_context));
1039 }
1040 if (windata)
1041 windata->gl_context = dfb_context;
1042
1043 return 0;
1044 error:
1045 return -1;
1046 }
1047
1048 static int
1049 DirectFB_GL_SetSwapInterval(_THIS, int interval)
1050 {
1051 SDL_DFB_DEVICEDATA(_this);
1052
1053 SDL_Unsupported();
1054 return -1;
1055
1056 }
1057
1058 static int
1059 DirectFB_GL_GetSwapInterval(_THIS)
1060 {
1061 SDL_DFB_DEVICEDATA(_this);
1062
1063 SDL_Unsupported();
1064 return -1;
1065
1066 }
1067
1068 static void
1069 DirectFB_GL_SwapWindow(_THIS, SDL_Window * window)
1070 {
1071 SDL_DFB_DEVICEDATA(_this);
1072 SDL_DFB_WINDOWDATA(window);
1073 SDL_DFB_DISPLAYDATA(_this, window);
1074 int ret;
1075 void *p;
1076 int pitch;
1077 DFBRegion region;
1078
1079 region.x1 = 0;
1080 region.y1 = 0;
1081 region.x2 = window->w;
1082 region.y2 = window->h;
1083
1084 if (devdata->glFinish)
1085 devdata->glFinish();
1086 else if (devdata->glFlush)
1087 devdata->glFlush();
1088
1089 SDL_DFB_CHECKERR(windata->gl_context->Unlock(windata->gl_context));
1090 SDL_DFB_CHECKERR(windata->surface->
1091 Flip(windata->surface, &region, DSFLIP_ONSYNC));
1092 SDL_DFB_CHECKERR(windata->gl_context->Lock(windata->gl_context));
1093
1094 return;
1095 error:
1096 return;
1097 }
1098
1099 static void
1100 DirectFB_GL_DeleteContext(_THIS, SDL_GLContext context)
1101 {
1102 IDirectFBGL *dfb_context = (IDirectFBGL *) context;
1103 SDL_DFB_DEVICEDATA(_this);
1104
1105 dfb_context->Unlock(dfb_context);
1106 dfb_context->Release(dfb_context);
1107 }
1108
550 #endif 1109 #endif
551 }
552
553 return 0;
554
555 error:
556 if (events)
557 events->Release(events);
558
559 if (HIDDEN->c2frame)
560 HIDDEN->c2frame->Release(HIDDEN->c2frame);
561
562 if (HIDDEN->c2layer)
563 HIDDEN->c2layer->Release(HIDDEN->c2layer);
564
565 if (layer)
566 layer->Release(layer);
567
568 if (dfb)
569 dfb->Release(dfb);
570
571 return -1;
572 }
573
574 static SDL_Rect **
575 DirectFB_ListModes(_THIS, SDL_PixelFormat * format, Uint32 flags)
576 {
577 if (flags & SDL_FULLSCREEN)
578 return HIDDEN->modelist;
579 else if (SDLToDFBPixelFormat(format) != DSPF_UNKNOWN)
580 return (SDL_Rect **) - 1;
581
582 return NULL;
583 }
584
585 static SDL_Surface *
586 DirectFB_SetVideoMode(_THIS, SDL_Surface * current, int width, int height,
587 int bpp, Uint32 flags)
588 {
589 DFBResult ret;
590 DFBSurfaceDescription dsc;
591 DFBSurfacePixelFormat pixelformat;
592 IDirectFBSurface *surface;
593
594 fprintf(stderr, "SDL DirectFB_SetVideoMode: %dx%d@%d, flags: 0x%08x\n",
595 width, height, bpp, flags);
596
597 flags |= SDL_FULLSCREEN;
598
599 /* Release previous primary surface */
600 if (current->hwdata && current->hwdata->surface) {
601 current->hwdata->surface->Release(current->hwdata->surface);
602 current->hwdata->surface = NULL;
603
604 /* And its palette if present */
605 if (current->hwdata->palette) {
606 current->hwdata->palette->Release(current->hwdata->palette);
607 current->hwdata->palette = NULL;
608 }
609 } else if (!current->hwdata) {
610 /* Allocate the hardware acceleration data */
611 current->hwdata =
612 (struct private_hwdata *) SDL_calloc(1, sizeof(*current->hwdata));
613 if (!current->hwdata) {
614 SDL_OutOfMemory();
615 return NULL;
616 }
617 }
618
619 /* Set cooperative level depending on flag SDL_FULLSCREEN */
620 if (flags & SDL_FULLSCREEN) {
621 ret = HIDDEN->dfb->SetCooperativeLevel(HIDDEN->dfb, DFSCL_FULLSCREEN);
622 if (ret && !HIDDEN->enable_mga_crtc2) {
623 DirectFBError("dfb->SetCooperativeLevel", ret);
624 flags &= ~SDL_FULLSCREEN;
625 }
626 } else
627 HIDDEN->dfb->SetCooperativeLevel(HIDDEN->dfb, DFSCL_NORMAL);
628
629 /* Set video mode */
630 ret = HIDDEN->dfb->SetVideoMode(HIDDEN->dfb, width, height, bpp);
631 if (ret) {
632 if (flags & SDL_FULLSCREEN) {
633 flags &= ~SDL_FULLSCREEN;
634 HIDDEN->dfb->SetCooperativeLevel(HIDDEN->dfb, DFSCL_NORMAL);
635 ret = HIDDEN->dfb->SetVideoMode(HIDDEN->dfb, width, height, bpp);
636 }
637
638 if (ret) {
639 SetDirectFBerror("dfb->SetVideoMode", ret);
640 return NULL;
641 }
642 }
643
644 /* Create primary surface */
645 dsc.flags = DSDESC_CAPS | DSDESC_PIXELFORMAT;
646 dsc.caps =
647 DSCAPS_PRIMARY | ((flags & SDL_DOUBLEBUF) ? DSCAPS_FLIPPING : 0);
648 dsc.pixelformat = GetFormatForBpp(bpp, HIDDEN->layer);
649
650 ret = HIDDEN->dfb->CreateSurface(HIDDEN->dfb, &dsc, &surface);
651 if (ret && (flags & SDL_DOUBLEBUF)) {
652 /* Try without double buffering */
653 dsc.caps &= ~DSCAPS_FLIPPING;
654 ret = HIDDEN->dfb->CreateSurface(HIDDEN->dfb, &dsc, &surface);
655 }
656 if (ret) {
657 SetDirectFBerror("dfb->CreateSurface", ret);
658 return NULL;
659 }
660
661 current->w = width;
662 current->h = height;
663 current->flags = SDL_HWSURFACE | SDL_PREALLOC;
664
665 if (flags & SDL_FULLSCREEN) {
666 current->flags |= SDL_FULLSCREEN;
667 this->UpdateRects = DirectFB_DirectUpdate;
668 } else
669 this->UpdateRects = DirectFB_WindowedUpdate;
670
671 if (dsc.caps & DSCAPS_FLIPPING)
672 current->flags |= SDL_DOUBLEBUF;
673
674 surface->GetPixelFormat(surface, &pixelformat);
675
676 DFBToSDLPixelFormat(pixelformat, current->format);
677
678 /* Get the surface palette (if supported) */
679 if (DFB_PIXELFORMAT_IS_INDEXED(pixelformat)) {
680 surface->GetPalette(surface, &current->hwdata->palette);
681
682 current->flags |= SDL_HWPALETTE;
683 }
684
685 current->hwdata->surface = surface;
686
687 /* MGA CRTC2 stuff */
688 if (HIDDEN->enable_mga_crtc2) {
689 /* no stretching if c2ssize == c2framesize */
690 HIDDEN->c2ssize.x = 0, HIDDEN->c2ssize.y = 0;
691 HIDDEN->c2ssize.w = width;
692 HIDDEN->c2ssize.h = height;
693
694 HIDDEN->c2dsize.x = 0, HIDDEN->c2dsize.y = 0;
695 HIDDEN->c2dsize.w = width;
696 HIDDEN->c2dsize.h = height;
697
698 HIDDEN->mga_crtc2_stretch = 0;
699
700 if (SDL_getenv("SDL_DIRECTFB_MGA_STRETCH") != NULL) {
701 /* Normally assume a picture aspect ratio of 4:3 */
702 int zoom_aspect_x = 4, zoom_aspect_y = 3, i, j;
703
704 for (i = 1; i < 20; i++) {
705 for (j = 1; j < 10; j++) {
706 if ((float) width / (float) i * (float) j == height) {
707 zoom_aspect_x = i;
708 zoom_aspect_y = j;
709
710 /* break the loop */
711 i = 21;
712 break;
713 }
714 }
715 }
716
717 #ifdef DIRECTFB_CRTC2_DEBUG
718 printf
719 ("Source resolution: X: %d, Y: %d, Aspect ratio: %d:%d\n",
720 width, height, zoom_aspect_x, zoom_aspect_y);
721 printf("CRTC2 resolution: X: %d, Y: %d\n",
722 HIDDEN->c2framesize.w, HIDDEN->c2framesize.h);
723 #endif
724
725 /* don't stretch only slightly smaller/larger images */
726 if ((float) width < (float) HIDDEN->c2framesize.w * 0.95
727 || (float) height < (float) HIDDEN->c2framesize.h * 0.95) {
728 while ((float) HIDDEN->c2dsize.w <
729 (float) HIDDEN->c2framesize.w *
730 HIDDEN->mga_crtc2_stretch_overscan
731 && (float) HIDDEN->c2dsize.h <
732 (float) HIDDEN->c2framesize.h *
733 HIDDEN->mga_crtc2_stretch_overscan) {
734 HIDDEN->c2dsize.w += zoom_aspect_x;
735 HIDDEN->c2dsize.h += zoom_aspect_y;
736 }
737
738 /* one step down */
739 HIDDEN->c2dsize.w -= zoom_aspect_x;
740 HIDDEN->c2dsize.h -= zoom_aspect_y;
741
742 #ifdef DIRECTFB_CRTC2_DEBUG
743 printf("Stretched resolution: X: %d, Y: %d\n",
744 HIDDEN->c2dsize.w, HIDDEN->c2dsize.h);
745 #endif
746
747 HIDDEN->mga_crtc2_stretch = 1;
748 } else if ((float) width > (float) HIDDEN->c2framesize.w * 0.95
749 || (float) height >
750 (float) HIDDEN->c2framesize.h * 0.95) {
751 while ((float) HIDDEN->c2dsize.w >
752 (float) HIDDEN->c2framesize.w *
753 HIDDEN->mga_crtc2_stretch_overscan
754 || (float) HIDDEN->c2dsize.h >
755 (float) HIDDEN->c2framesize.h *
756 HIDDEN->mga_crtc2_stretch_overscan) {
757 HIDDEN->c2dsize.w -= zoom_aspect_x;
758 HIDDEN->c2dsize.h -= zoom_aspect_y;
759 }
760
761 #ifdef DIRECTFB_CRTC2_DEBUG
762 printf("Down-Stretched resolution: X: %d, Y: %d\n",
763 HIDDEN->c2dsize.w, HIDDEN->c2dsize.h);
764 #endif
765
766 HIDDEN->mga_crtc2_stretch = 1;
767 } else {
768 #ifdef DIRECTFB_CRTC2_DEBUG
769 printf("Not stretching image\n");
770 #endif
771 }
772
773 /* Panning */
774 if (HIDDEN->c2framesize.w > HIDDEN->c2dsize.w)
775 HIDDEN->c2dsize.x =
776 (HIDDEN->c2framesize.w - HIDDEN->c2dsize.w) / 2;
777 else
778 HIDDEN->c2dsize.x =
779 (HIDDEN->c2dsize.w - HIDDEN->c2framesize.w) / 2;
780
781 if (HIDDEN->c2framesize.h > HIDDEN->c2dsize.h)
782 HIDDEN->c2dsize.y =
783 (HIDDEN->c2framesize.h - HIDDEN->c2dsize.h) / 2;
784 else
785 HIDDEN->c2dsize.y =
786 (HIDDEN->c2dsize.h - HIDDEN->c2framesize.h) / 2;
787
788 #ifdef DIRECTFB_CRTC2_DEBUG
789 printf("CRTC2 position X: %d, Y: %d\n", HIDDEN->c2dsize.x,
790 HIDDEN->c2dsize.y);
791 #endif
792 }
793 }
794
795 return current;
796 }
797
798 static int
799 DirectFB_AllocHWSurface(_THIS, SDL_Surface * surface)
800 {
801 DFBResult ret;
802 DFBSurfaceDescription dsc;
803
804 /* fprintf(stderr, "SDL: DirectFB_AllocHWSurface (%dx%d@%d, flags: 0x%08x)\n",
805 surface->w, surface->h, surface->format->BitsPerPixel, surface->flags); */
806
807 if (surface->w < 8 || surface->h < 8)
808 return -1;
809
810 /* fill surface description */
811 dsc.flags =
812 DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS;
813 dsc.width = surface->w;
814 dsc.height = surface->h;
815 dsc.caps = (surface->flags & SDL_DOUBLEBUF) ? DSCAPS_FLIPPING : 0;
816
817 /* find the right pixelformat */
818 dsc.pixelformat = SDLToDFBPixelFormat(surface->format);
819 if (dsc.pixelformat == DSPF_UNKNOWN)
820 return -1;
821
822 /* Allocate the hardware acceleration data */
823 surface->hwdata =
824 (struct private_hwdata *) SDL_calloc(1, sizeof(*surface->hwdata));
825 if (surface->hwdata == NULL) {
826 SDL_OutOfMemory();
827 return -1;
828 }
829
830 /* Create the surface */
831 ret =
832 HIDDEN->dfb->CreateSurface(HIDDEN->dfb, &dsc,
833 &surface->hwdata->surface);
834 if (ret) {
835 SetDirectFBerror("dfb->CreateSurface", ret);
836 free(surface->hwdata);
837 surface->hwdata = NULL;
838 return -1;
839 }
840
841 surface->flags |= SDL_HWSURFACE | SDL_PREALLOC;
842
843 return 0;
844 }
845
846 static void
847 DirectFB_FreeHWSurface(_THIS, SDL_Surface * surface)
848 {
849 if (surface->hwdata && HIDDEN->initialized) {
850 surface->hwdata->surface->Release(surface->hwdata->surface);
851 free(surface->hwdata);
852 surface->hwdata = NULL;
853 }
854 }
855
856 static int
857 DirectFB_CheckHWBlit(_THIS, SDL_Surface * src, SDL_Surface * dst)
858 {
859 /* fprintf(stderr, "SDL: DirectFB_CheckHWBlit (src->hwdata: %p, dst->hwdata: %p)\n",
860 src->hwdata, dst->hwdata); */
861
862 if (!src->hwdata || !dst->hwdata)
863 return 0;
864
865 src->flags |= SDL_HWACCEL;
866 src->map->hw_blit = DirectFB_HWAccelBlit;
867
868 return 1;
869 }
870
871 static int
872 DirectFB_HWAccelBlit(SDL_Surface * src, SDL_Rect * srcrect,
873 SDL_Surface * dst, SDL_Rect * dstrect)
874 {
875 DFBSurfaceBlittingFlags flags = DSBLIT_NOFX;
876
877 DFBRectangle sr = { srcrect->x, srcrect->y, srcrect->w, srcrect->h };
878 DFBRectangle dr = { dstrect->x, dstrect->y, dstrect->w, dstrect->h };
879
880 IDirectFBSurface *surface = dst->hwdata->surface;
881
882 if (src->flags & SDL_SRCCOLORKEY) {
883 flags |= DSBLIT_SRC_COLORKEY;
884 DirectFB_SetHWColorKey(NULL, src, src->format->colorkey);
885 }
886
887 if (src->flags & SDL_SRCALPHA) {
888 flags |= DSBLIT_BLEND_COLORALPHA;
889 surface->SetColor(surface, 0xff, 0xff, 0xff, src->format->alpha);
890 }
891
892 surface->SetBlittingFlags(surface, flags);
893
894 if (sr.w == dr.w && sr.h == dr.h)
895 surface->Blit(surface, src->hwdata->surface, &sr, dr.x, dr.y);
896 else
897 surface->StretchBlit(surface, src->hwdata->surface, &sr, &dr);
898
899 return 0;
900 }
901
902 static int
903 DirectFB_FillHWRect(_THIS, SDL_Surface * dst, SDL_Rect * dstrect,
904 Uint32 color)
905 {
906 SDL_PixelFormat *fmt = dst->format;
907 IDirectFBSurface *surface = dst->hwdata->surface;
908
909 /* ugly */
910 surface->SetColor(surface,
911 (color & fmt->Rmask) >> (fmt->Rshift - fmt->Rloss),
912 (color & fmt->Gmask) >> (fmt->Gshift - fmt->Gloss),
913 (color & fmt->Bmask) << (fmt->Bloss - fmt->Bshift),
914 0xFF);
915 surface->FillRectangle(surface, dstrect->x, dstrect->y, dstrect->w,
916 dstrect->h);
917
918 return 0;
919 }
920
921 static int
922 DirectFB_SetHWColorKey(_THIS, SDL_Surface * src, Uint32 key)
923 {
924 SDL_PixelFormat *fmt = src->format;
925 IDirectFBSurface *surface = src->hwdata->surface;
926
927 if (fmt->BitsPerPixel == 8)
928 surface->SetSrcColorKeyIndex(surface, key);
929 else
930 /* ugly */
931 surface->SetSrcColorKey(surface,
932 (key & fmt->Rmask) >> (fmt->Rshift -
933 fmt->Rloss),
934 (key & fmt->Gmask) >> (fmt->Gshift -
935 fmt->Gloss),
936 (key & fmt->Bmask) << (fmt->Bloss -
937 fmt->Bshift));
938
939 return 0;
940 }
941
942 static int
943 DirectFB_SetHWAlpha(_THIS, SDL_Surface * surface, Uint8 alpha)
944 {
945 return 0;
946 }
947
948 static int
949 DirectFB_FlipHWSurface(_THIS, SDL_Surface * surface)
950 {
951 if (HIDDEN->enable_mga_crtc2) {
952 int rtn =
953 surface->hwdata->surface->Flip(surface->hwdata->surface, NULL,
954 0);
955 if (HIDDEN->mga_crtc2_stretch)
956 HIDDEN->c2frame->StretchBlit(HIDDEN->c2frame,
957 surface->hwdata->surface,
958 &HIDDEN->c2ssize, &HIDDEN->c2dsize);
959 else
960 HIDDEN->c2frame->Blit(HIDDEN->c2frame,
961 surface->hwdata->surface, NULL,
962 HIDDEN->c2dsize.x, HIDDEN->c2dsize.y);
963
964 HIDDEN->c2frame->Flip(HIDDEN->c2frame, NULL, DSFLIP_WAITFORSYNC);
965 return rtn;
966 } else
967 return surface->hwdata->surface->Flip(surface->hwdata->surface, NULL,
968 DSFLIP_WAITFORSYNC);
969 }
970
971 static int
972 DirectFB_LockHWSurface(_THIS, SDL_Surface * surface)
973 {
974 DFBResult ret;
975 void *data;
976 int pitch;
977
978 ret = surface->hwdata->surface->Lock(surface->hwdata->surface,
979 DSLF_WRITE, &data, &pitch);
980 if (ret) {
981 SetDirectFBerror("surface->Lock", ret);
982 return -1;
983 }
984
985 surface->pixels = data;
986 surface->pitch = pitch;
987
988 return 0;
989 }
990
991 static void
992 DirectFB_UnlockHWSurface(_THIS, SDL_Surface * surface)
993 {
994 surface->hwdata->surface->Unlock(surface->hwdata->surface);
995 surface->pixels = NULL;
996 }
997
998 static void
999 DirectFB_DirectUpdate(_THIS, int numrects, SDL_Rect * rects)
1000 {
1001 if (HIDDEN->enable_mga_crtc2) {
1002 if (HIDDEN->mga_crtc2_stretch)
1003 HIDDEN->c2frame->StretchBlit(HIDDEN->c2frame,
1004 this->screen->hwdata->surface,
1005 &HIDDEN->c2ssize, &HIDDEN->c2dsize);
1006 else
1007 HIDDEN->c2frame->Blit(HIDDEN->c2frame,
1008 this->screen->hwdata->surface, NULL,
1009 HIDDEN->c2dsize.x, HIDDEN->c2dsize.y);
1010
1011 HIDDEN->c2frame->Flip(HIDDEN->c2frame, NULL, DSFLIP_WAITFORSYNC);
1012 }
1013 }
1014
1015 static void
1016 DirectFB_WindowedUpdate(_THIS, int numrects, SDL_Rect * rects)
1017 {
1018 DFBRegion region;
1019 int i;
1020 int region_valid = 0;
1021 IDirectFBSurface *surface = this->screen->hwdata->surface;
1022
1023 for (i = 0; i < numrects; ++i) {
1024 int x2, y2;
1025
1026 if (!rects[i].w) /* Clipped? */
1027 continue;
1028
1029 x2 = rects[i].x + rects[i].w - 1;
1030 y2 = rects[i].y + rects[i].h - 1;
1031
1032 if (region_valid) {
1033 if (rects[i].x < region.x1)
1034 region.x1 = rects[i].x;
1035
1036 if (rects[i].y < region.y1)
1037 region.y1 = rects[i].y;
1038
1039 if (x2 > region.x2)
1040 region.x2 = x2;
1041
1042 if (y2 > region.y2)
1043 region.y2 = y2;
1044 } else {
1045 region.x1 = rects[i].x;
1046 region.y1 = rects[i].y;
1047 region.x2 = x2;
1048 region.y2 = y2;
1049
1050 region_valid = 1;
1051 }
1052 }
1053
1054 if (region_valid) {
1055 if (HIDDEN->enable_mga_crtc2) {
1056 if (HIDDEN->mga_crtc2_stretch)
1057 HIDDEN->c2frame->StretchBlit(HIDDEN->c2frame, surface,
1058 &HIDDEN->c2ssize,
1059 &HIDDEN->c2dsize);
1060 else
1061 HIDDEN->c2frame->Blit(HIDDEN->c2frame, surface, NULL,
1062 HIDDEN->c2dsize.x, HIDDEN->c2dsize.y);
1063
1064 HIDDEN->c2frame->Flip(HIDDEN->c2frame, NULL, DSFLIP_WAITFORSYNC);
1065 } else
1066 surface->Flip(surface, &region, DSFLIP_WAITFORSYNC);
1067 }
1068 }
1069
1070 int
1071 DirectFB_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color * colors)
1072 {
1073 IDirectFBPalette *palette = this->screen->hwdata->palette;
1074
1075 if (!palette)
1076 return 0;
1077
1078 if (firstcolor > 255)
1079 return 0;
1080
1081 if (firstcolor + ncolors > 256)
1082 ncolors = 256 - firstcolor;
1083
1084 if (ncolors > 0) {
1085 int i;
1086 DFBColor entries[ncolors];
1087
1088 for (i = 0; i < ncolors; i++) {
1089 entries[i].a = 0xff;
1090 entries[i].r = colors[i].r;
1091 entries[i].g = colors[i].g;
1092 entries[i].b = colors[i].b;
1093 }
1094
1095 palette->SetEntries(palette, entries, ncolors, firstcolor);
1096 }
1097
1098 return 1;
1099 }
1100
1101 void
1102 DirectFB_VideoQuit(_THIS)
1103 {
1104 struct DirectFBEnumRect *rect = enumlist;
1105
1106 if (this->screen && this->screen->hwdata) {
1107 IDirectFBSurface *surface = this->screen->hwdata->surface;
1108 IDirectFBPalette *palette = this->screen->hwdata->palette;
1109
1110 if (palette)
1111 palette->Release(palette);
1112
1113 if (surface)
1114 surface->Release(surface);
1115
1116 this->screen->hwdata->surface = NULL;
1117 this->screen->hwdata->palette = NULL;
1118 }
1119
1120 if (HIDDEN->c2frame) {
1121 HIDDEN->c2frame->Release(HIDDEN->c2frame);
1122 HIDDEN->c2frame = NULL;
1123 }
1124
1125 if (HIDDEN->eventbuffer) {
1126 HIDDEN->eventbuffer->Release(HIDDEN->eventbuffer);
1127 HIDDEN->eventbuffer = NULL;
1128 }
1129
1130 if (HIDDEN->c2layer) {
1131 HIDDEN->c2layer->Release(HIDDEN->c2layer);
1132 HIDDEN->c2layer = NULL;
1133 }
1134
1135 if (HIDDEN->layer) {
1136 HIDDEN->layer->Release(HIDDEN->layer);
1137 HIDDEN->layer = NULL;
1138 }
1139
1140 if (HIDDEN->dfb) {
1141 HIDDEN->dfb->Release(HIDDEN->dfb);
1142 HIDDEN->dfb = NULL;
1143 }
1144
1145 /* Free video mode list */
1146 if (HIDDEN->modelist) {
1147 free(HIDDEN->modelist);
1148 HIDDEN->modelist = NULL;
1149 }
1150
1151 /* Free mode enumeration list */
1152 while (rect) {
1153 struct DirectFBEnumRect *next = rect->next;
1154 free(rect);
1155 rect = next;
1156 }
1157 enumlist = NULL;
1158
1159 HIDDEN->initialized = 0;
1160 }
1161
1162
1163 int
1164 DirectFB_ShowWMCursor(_THIS, WMcursor * cursor)
1165 {
1166 /* We can only hide or show the default cursor */
1167 if (cursor == NULL) {
1168 HIDDEN->layer->SetCursorOpacity(HIDDEN->layer, 0x00);
1169 } else {
1170 HIDDEN->layer->SetCursorOpacity(HIDDEN->layer, 0xFF);
1171 }
1172 return 1;
1173 }
1174
1175 void
1176 DirectFB_FinalQuit(void)
1177 {
1178 }
1179
1180 /* vi: set ts=4 sw=4 expandtab: */