Mercurial > sdl-ios-xcode
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, ®ion, 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, ¤t->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, ®ion, 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: */ |