Mercurial > sdl-ios-xcode
comparison src/video/directfb/SDL_DirectFB_window.c @ 4636:b196d2758026
Couriersud to Sam
Hi Sam,
20100815_1.diff contains updates for the directfb driver:
- more documentation, mainly on software OpenGL in README.directfb
- Revised error handling leading to leaner code
- Improved/fixed OpenGL handling of multiple contexts.
- Made the built-in simple window manager handle OpenGL windows.
- Rewrote pixelformat mapping - this was quite ugly before.
Well, all software GL, but working :-)
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Mon, 16 Aug 2010 09:04:55 -0700 |
parents | 25b9cd8bdc30 |
children | 164f20ba08eb |
comparison
equal
deleted
inserted
replaced
4635:0a07d002f10b | 4636:b196d2758026 |
---|---|
22 #include "SDL_config.h" | 22 #include "SDL_config.h" |
23 | 23 |
24 #include "SDL_syswm.h" | 24 #include "SDL_syswm.h" |
25 #include "../SDL_sysvideo.h" | 25 #include "../SDL_sysvideo.h" |
26 #include "../../events/SDL_keyboard_c.h" | 26 #include "../../events/SDL_keyboard_c.h" |
27 #include "../../video/SDL_pixels_c.h" | |
27 | 28 |
28 #include "SDL_DirectFB_video.h" | 29 #include "SDL_DirectFB_video.h" |
29 | 30 #if SDL_DIRECTFB_OPENGL |
31 #include "SDL_DirectFB_opengl.h" | |
32 #endif | |
33 | |
34 static void DirectFB_AdjustWindowSurface(_THIS, SDL_Window * window); | |
30 | 35 |
31 int | 36 int |
32 DirectFB_CreateWindow(_THIS, SDL_Window * window) | 37 DirectFB_CreateWindow(_THIS, SDL_Window * window) |
33 { | 38 { |
34 SDL_DFB_DEVICEDATA(_this); | 39 SDL_DFB_DEVICEDATA(_this); |
35 SDL_DFB_DISPLAYDATA(_this, window); | 40 SDL_DFB_DISPLAYDATA(_this, window); |
36 DFB_WindowData *windata = NULL; | 41 DFB_WindowData *windata = NULL; |
37 DFBWindowOptions wopts; | 42 DFBWindowOptions wopts; |
38 DFBWindowDescription desc; | 43 DFBWindowDescription desc; |
39 IDirectFBFont *font; | 44 int x, y; |
40 int ret, x, y; | |
41 | 45 |
42 SDL_DFB_CALLOC(window->driverdata, 1, sizeof(DFB_WindowData)); | 46 SDL_DFB_CALLOC(window->driverdata, 1, sizeof(DFB_WindowData)); |
43 windata = (DFB_WindowData *) window->driverdata; | 47 windata = (DFB_WindowData *) window->driverdata; |
44 | 48 |
45 windata->is_managed = devdata->has_own_wm; | 49 windata->is_managed = devdata->has_own_wm; |
67 if (window->flags & SDL_WINDOW_FULLSCREEN) { | 71 if (window->flags & SDL_WINDOW_FULLSCREEN) { |
68 x = 0; | 72 x = 0; |
69 y = 0; | 73 y = 0; |
70 } | 74 } |
71 | 75 |
72 DirectFB_WM_AdjustWindowLayout(window); | 76 DirectFB_WM_AdjustWindowLayout(window, window->flags, window->w, window->h); |
73 | 77 |
74 /* Create Window */ | 78 /* Create Window */ |
75 desc.flags = | 79 desc.flags = |
76 DWDESC_WIDTH | DWDESC_HEIGHT | DWDESC_PIXELFORMAT | DWDESC_POSX | 80 DWDESC_WIDTH | DWDESC_HEIGHT | DWDESC_PIXELFORMAT | DWDESC_POSX |
77 | DWDESC_POSY | DWDESC_SURFACE_CAPS; | 81 | DWDESC_POSY | DWDESC_SURFACE_CAPS; |
85 /* Create the window. */ | 89 /* Create the window. */ |
86 SDL_DFB_CHECKERR(dispdata->layer->CreateWindow(dispdata->layer, &desc, | 90 SDL_DFB_CHECKERR(dispdata->layer->CreateWindow(dispdata->layer, &desc, |
87 &windata->window)); | 91 &windata->window)); |
88 | 92 |
89 /* Set Options */ | 93 /* Set Options */ |
90 windata->window->GetOptions(windata->window, &wopts); | 94 SDL_DFB_CHECK(windata->window->GetOptions(windata->window, &wopts)); |
91 | 95 |
92 if (window->flags & SDL_WINDOW_RESIZABLE) | 96 if (window->flags & SDL_WINDOW_RESIZABLE) |
93 wopts |= DWOP_SCALE; | 97 wopts |= DWOP_SCALE; |
94 else | 98 else |
95 wopts |= DWOP_KEEP_SIZE; | 99 wopts |= DWOP_KEEP_SIZE; |
96 | 100 |
97 if (window->flags & SDL_WINDOW_FULLSCREEN) { | 101 if (window->flags & SDL_WINDOW_FULLSCREEN) { |
98 wopts |= DWOP_KEEP_POSITION | DWOP_KEEP_STACKING | DWOP_KEEP_SIZE; | 102 wopts |= DWOP_KEEP_POSITION | DWOP_KEEP_STACKING | DWOP_KEEP_SIZE; |
99 windata->window->SetStackingClass(windata->window, DWSC_UPPER); | 103 SDL_DFB_CHECK(windata->window->SetStackingClass(windata->window, DWSC_UPPER)); |
100 } | 104 } |
101 windata->window->SetOptions(windata->window, wopts); | 105 SDL_DFB_CHECK(windata->window->SetOptions(windata->window, wopts)); |
102 | 106 |
103 /* See what we got */ | 107 /* See what we got */ |
104 SDL_DFB_CHECKERR(DirectFB_WM_GetClientSize | 108 SDL_DFB_CHECKERR(DirectFB_WM_GetClientSize |
105 (_this, window, &window->w, &window->h)); | 109 (_this, window, &window->w, &window->h)); |
106 | 110 |
110 /* And get a subsurface for rendering */ | 114 /* And get a subsurface for rendering */ |
111 SDL_DFB_CHECKERR(windata->window_surface-> | 115 SDL_DFB_CHECKERR(windata->window_surface-> |
112 GetSubSurface(windata->window_surface, &windata->client, | 116 GetSubSurface(windata->window_surface, &windata->client, |
113 &windata->surface)); | 117 &windata->surface)); |
114 | 118 |
115 windata->window->SetOpacity(windata->window, 0xFF); | 119 SDL_DFB_CHECK(windata->window->SetOpacity(windata->window, 0xFF)); |
116 | 120 |
117 /* Create Eventbuffer */ | 121 /* Create Eventbuffer */ |
118 SDL_DFB_CHECKERR(windata->window->CreateEventBuffer(windata->window, | 122 SDL_DFB_CHECKERR(windata->window->CreateEventBuffer(windata->window, |
119 &windata-> | 123 &windata-> |
120 eventbuffer)); | 124 eventbuffer)); |
121 SDL_DFB_CHECKERR(windata->window-> | 125 SDL_DFB_CHECKERR(windata->window-> |
122 EnableEvents(windata->window, DWET_ALL)); | 126 EnableEvents(windata->window, DWET_ALL)); |
123 | 127 |
124 /* Create a font */ | 128 /* Create a font */ |
125 /* FIXME: once during Video_Init */ | 129 /* FIXME: once during Video_Init */ |
126 if (windata->is_managed) { | 130 windata->font = NULL; |
127 DFBFontDescription fdesc; | |
128 | |
129 fdesc.flags = DFDESC_HEIGHT; | |
130 fdesc.height = windata->theme.font_size; | |
131 font = NULL; | |
132 SDL_DFB_CHECK(devdata-> | |
133 dfb->CreateFont(devdata->dfb, windata->theme.font, | |
134 &fdesc, &font)); | |
135 windata->window_surface->SetFont(windata->window_surface, font); | |
136 SDL_DFB_RELEASE(font); | |
137 } | |
138 | 131 |
139 /* Make it the top most window. */ | 132 /* Make it the top most window. */ |
140 windata->window->RaiseToTop(windata->window); | 133 SDL_DFB_CHECK(windata->window->RaiseToTop(windata->window)); |
141 | 134 |
142 /* remember parent */ | 135 /* remember parent */ |
143 windata->sdl_window = window; | 136 windata->sdl_window = window; |
144 | 137 |
145 /* Add to list ... */ | 138 /* Add to list ... */ |
147 windata->next = devdata->firstwin; | 140 windata->next = devdata->firstwin; |
148 windata->opacity = 0xFF; | 141 windata->opacity = 0xFF; |
149 devdata->firstwin = windata; | 142 devdata->firstwin = windata; |
150 | 143 |
151 /* Draw Frame */ | 144 /* Draw Frame */ |
152 DirectFB_WM_RedrawLayout(window); | 145 DirectFB_WM_RedrawLayout(_this, window); |
153 | 146 |
154 return 0; | 147 return 0; |
155 error: | 148 error: |
156 SDL_DFB_RELEASE(windata->window); | 149 SDL_DFB_RELEASE(windata->window); |
157 SDL_DFB_RELEASE(windata->surface); | 150 SDL_DFB_RELEASE(windata->surface); |
170 { | 163 { |
171 SDL_DFB_WINDOWDATA(window); | 164 SDL_DFB_WINDOWDATA(window); |
172 | 165 |
173 if (windata->is_managed) { | 166 if (windata->is_managed) { |
174 windata->wm_needs_redraw = 1; | 167 windata->wm_needs_redraw = 1; |
168 DirectFB_WM_RedrawLayout(_this, window); | |
175 } else | 169 } else |
176 SDL_Unsupported(); | 170 SDL_Unsupported(); |
177 } | 171 } |
178 | 172 |
179 void | 173 void |
180 DirectFB_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon) | 174 DirectFB_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon) |
181 { | 175 { |
182 SDL_DFB_DEVICEDATA(_this); | 176 SDL_DFB_DEVICEDATA(_this); |
183 SDL_DFB_WINDOWDATA(window); | 177 SDL_DFB_WINDOWDATA(window); |
184 SDL_Surface *surface = NULL; | 178 SDL_Surface *surface = NULL; |
185 DFBResult ret; | |
186 | 179 |
187 if (icon) { | 180 if (icon) { |
188 SDL_PixelFormat format; | 181 SDL_PixelFormat format; |
189 DFBSurfaceDescription dsc; | 182 DFBSurfaceDescription dsc; |
190 Uint32 *dest; | 183 Uint32 *dest; |
214 p = surface->pixels; | 207 p = surface->pixels; |
215 for (i = 0; i < surface->h; i++) | 208 for (i = 0; i < surface->h; i++) |
216 memcpy((char *) dest + i * pitch, | 209 memcpy((char *) dest + i * pitch, |
217 (char *) p + i * surface->pitch, 4 * surface->w); | 210 (char *) p + i * surface->pitch, 4 * surface->w); |
218 | 211 |
219 windata->icon->Unlock(windata->icon); | 212 SDL_DFB_CHECK(windata->icon->Unlock(windata->icon)); |
220 SDL_FreeSurface(surface); | 213 SDL_FreeSurface(surface); |
221 } else { | 214 } else { |
222 SDL_DFB_RELEASE(windata->icon); | 215 SDL_DFB_RELEASE(windata->icon); |
223 } | 216 } |
224 return; | 217 return; |
247 | 240 |
248 if (window->flags & SDL_WINDOW_FULLSCREEN) { | 241 if (window->flags & SDL_WINDOW_FULLSCREEN) { |
249 x = 0; | 242 x = 0; |
250 y = 0; | 243 y = 0; |
251 } | 244 } |
252 DirectFB_WM_AdjustWindowLayout(window); | 245 DirectFB_WM_AdjustWindowLayout(window, window->flags, window->w, window->h); |
253 windata->window->MoveTo(windata->window, x, y); | 246 SDL_DFB_CHECK(windata->window->MoveTo(windata->window, x, y)); |
254 } | 247 } |
255 | 248 |
256 void | 249 void |
257 DirectFB_SetWindowSize(_THIS, SDL_Window * window) | 250 DirectFB_SetWindowSize(_THIS, SDL_Window * window) |
258 { | 251 { |
259 SDL_DFB_DEVICEDATA(_this); | 252 //SDL_DFB_DEVICEDATA(_this); |
260 SDL_DFB_WINDOWDATA(window); | 253 SDL_DFB_WINDOWDATA(window); |
261 int ret; | |
262 | 254 |
263 if (!(window->flags & SDL_WINDOW_FULLSCREEN)) { | 255 if (!(window->flags & SDL_WINDOW_FULLSCREEN)) { |
264 int cw; | 256 int cw; |
265 int ch; | 257 int ch; |
266 | 258 |
270 | 262 |
271 SDL_DFB_CHECKERR(DirectFB_WM_GetClientSize(_this, window, &cw, &ch)); | 263 SDL_DFB_CHECKERR(DirectFB_WM_GetClientSize(_this, window, &cw, &ch)); |
272 | 264 |
273 if (cw != window->w || ch != window->h) { | 265 if (cw != window->w || ch != window->h) { |
274 | 266 |
275 DirectFB_WM_AdjustWindowLayout(window); | 267 DirectFB_WM_AdjustWindowLayout(window, window->flags, window->w, window->h); |
276 SDL_DFB_CHECKERR(windata->window->Resize(windata->window, | 268 SDL_DFB_CHECKERR(windata->window->Resize(windata->window, |
277 windata->size.w, | 269 windata->size.w, |
278 windata->size.h)); | 270 windata->size.h)); |
279 } | 271 } |
280 | 272 |
273 SDL_DFB_CHECKERR(DirectFB_WM_GetClientSize | |
274 (_this, window, &window->w, &window->h)); | |
275 DirectFB_AdjustWindowSurface(_this, window); | |
276 | |
281 SDL_DFB_CHECKERR(windata->window->EnableEvents(windata->window, | 277 SDL_DFB_CHECKERR(windata->window->EnableEvents(windata->window, |
282 DWET_ALL)); | 278 DWET_ALL)); |
283 | 279 |
284 SDL_DFB_CHECKERR(DirectFB_WM_GetClientSize | |
285 (_this, window, &window->w, &window->h)); | |
286 | |
287 SDL_OnWindowResized(window); | |
288 } | 280 } |
289 return; | 281 return; |
290 error: | 282 error: |
291 windata->window->EnableEvents(windata->window, DWET_ALL); | 283 SDL_DFB_CHECK(windata->window->EnableEvents(windata->window, DWET_ALL)); |
292 return; | 284 return; |
293 } | 285 } |
294 | 286 |
295 void | 287 void |
296 DirectFB_ShowWindow(_THIS, SDL_Window * window) | 288 DirectFB_ShowWindow(_THIS, SDL_Window * window) |
297 { | 289 { |
298 SDL_DFB_WINDOWDATA(window); | 290 SDL_DFB_WINDOWDATA(window); |
299 | 291 |
300 windata->window->SetOpacity(windata->window, windata->opacity); | 292 SDL_DFB_CHECK(windata->window->SetOpacity(windata->window, windata->opacity)); |
301 | 293 |
302 } | 294 } |
303 | 295 |
304 void | 296 void |
305 DirectFB_HideWindow(_THIS, SDL_Window * window) | 297 DirectFB_HideWindow(_THIS, SDL_Window * window) |
306 { | 298 { |
307 SDL_DFB_WINDOWDATA(window); | 299 SDL_DFB_WINDOWDATA(window); |
308 | 300 |
309 windata->window->GetOpacity(windata->window, &windata->opacity); | 301 SDL_DFB_CHECK(windata->window->GetOpacity(windata->window, &windata->opacity)); |
310 windata->window->SetOpacity(windata->window, 0); | 302 SDL_DFB_CHECK(windata->window->SetOpacity(windata->window, 0)); |
311 } | 303 } |
312 | 304 |
313 void | 305 void |
314 DirectFB_RaiseWindow(_THIS, SDL_Window * window) | 306 DirectFB_RaiseWindow(_THIS, SDL_Window * window) |
315 { | 307 { |
316 SDL_DFB_WINDOWDATA(window); | 308 SDL_DFB_WINDOWDATA(window); |
317 | 309 |
318 windata->window->RaiseToTop(windata->window); | 310 SDL_DFB_CHECK(windata->window->RaiseToTop(windata->window)); |
319 windata->window->RequestFocus(windata->window); | 311 SDL_DFB_CHECK(windata->window->RequestFocus(windata->window)); |
320 } | 312 } |
321 | 313 |
322 void | 314 void |
323 DirectFB_MaximizeWindow(_THIS, SDL_Window * window) | 315 DirectFB_MaximizeWindow(_THIS, SDL_Window * window) |
324 { | 316 { |
350 } | 342 } |
351 | 343 |
352 void | 344 void |
353 DirectFB_SetWindowGrab(_THIS, SDL_Window * window) | 345 DirectFB_SetWindowGrab(_THIS, SDL_Window * window) |
354 { | 346 { |
355 SDL_DFB_WINDOWDATA(window); | 347 SDL_DFB_DEVICEDATA(_this); |
348 SDL_DFB_WINDOWDATA(window); | |
349 DFB_WindowData *gwindata = ((devdata->grabbed_window) ? (DFB_WindowData *) ((devdata->grabbed_window)->driverdata) : NULL); | |
356 | 350 |
357 if ((window->flags & SDL_WINDOW_INPUT_GRABBED)) { | 351 if ((window->flags & SDL_WINDOW_INPUT_GRABBED)) { |
358 windata->window->GrabPointer(windata->window); | 352 if (gwindata != NULL) |
359 windata->window->GrabKeyboard(windata->window); | 353 { |
354 SDL_DFB_CHECK(gwindata->window->UngrabPointer(gwindata->window)); | |
355 SDL_DFB_CHECK(gwindata->window->UngrabKeyboard(gwindata->window)); | |
356 } | |
357 SDL_DFB_CHECK(windata->window->GrabPointer(windata->window)); | |
358 SDL_DFB_CHECK(windata->window->GrabKeyboard(windata->window)); | |
359 devdata->grabbed_window = window; | |
360 } else { | 360 } else { |
361 windata->window->UngrabPointer(windata->window); | 361 SDL_DFB_CHECK(windata->window->UngrabPointer(windata->window)); |
362 windata->window->UngrabKeyboard(windata->window); | 362 SDL_DFB_CHECK(windata->window->UngrabKeyboard(windata->window)); |
363 devdata->grabbed_window = NULL; | |
363 } | 364 } |
364 } | 365 } |
365 | 366 |
366 void | 367 void |
367 DirectFB_DestroyWindow(_THIS, SDL_Window * window) | 368 DirectFB_DestroyWindow(_THIS, SDL_Window * window) |
368 { | 369 { |
369 SDL_DFB_DEVICEDATA(_this); | 370 SDL_DFB_DEVICEDATA(_this); |
370 SDL_DFB_WINDOWDATA(window); | 371 SDL_DFB_WINDOWDATA(window); |
371 DFB_WindowData *p; | 372 DFB_WindowData *p; |
372 | 373 |
373 SDL_DFB_DEBUG("Trace\n"); | |
374 | |
375 /* Some cleanups */ | 374 /* Some cleanups */ |
376 windata->window->UngrabPointer(windata->window); | 375 SDL_DFB_CHECK(windata->window->UngrabPointer(windata->window)); |
377 windata->window->UngrabKeyboard(windata->window); | 376 SDL_DFB_CHECK(windata->window->UngrabKeyboard(windata->window)); |
378 | 377 |
379 windata->window_surface->SetFont(windata->window_surface, NULL); | 378 #if SDL_DIRECTFB_OPENGL |
380 SDL_DFB_RELEASE(windata->icon); | 379 DirectFB_GL_DestroyWindowContexts(_this, window); |
380 #endif | |
381 | |
382 SDL_DFB_CHECK(windata->window_surface->SetFont(windata->window_surface, NULL)); | |
383 SDL_DFB_CHECK(windata->surface->ReleaseSource(windata->surface)); | |
384 SDL_DFB_CHECK(windata->window_surface->ReleaseSource(windata->window_surface)); | |
385 SDL_DFB_RELEASE(windata->icon); | |
386 SDL_DFB_RELEASE(windata->font); | |
381 SDL_DFB_RELEASE(windata->eventbuffer); | 387 SDL_DFB_RELEASE(windata->eventbuffer); |
382 SDL_DFB_RELEASE(windata->surface); | 388 SDL_DFB_RELEASE(windata->surface); |
383 SDL_DFB_RELEASE(windata->window_surface); | 389 SDL_DFB_RELEASE(windata->window_surface); |
384 | 390 |
385 SDL_DFB_RELEASE(windata->window); | 391 SDL_DFB_RELEASE(windata->window); |
403 { | 409 { |
404 SDL_Unsupported(); | 410 SDL_Unsupported(); |
405 return SDL_FALSE; | 411 return SDL_FALSE; |
406 } | 412 } |
407 | 413 |
408 void | 414 static void |
409 DirectFB_AdjustWindowSurface(SDL_Window * window) | 415 DirectFB_AdjustWindowSurface(_THIS, SDL_Window * window) |
410 { | 416 { |
411 SDL_DFB_WINDOWDATA(window); | 417 SDL_DFB_WINDOWDATA(window); |
412 int adjust = windata->wm_needs_redraw; | 418 int adjust = windata->wm_needs_redraw; |
413 int cw, ch; | 419 int cw, ch; |
414 int ret; | 420 |
415 | 421 DirectFB_WM_AdjustWindowLayout(window, window->flags, window->w, window->h); |
416 DirectFB_WM_AdjustWindowLayout(window); | |
417 | 422 |
418 SDL_DFB_CHECKERR(windata-> | 423 SDL_DFB_CHECKERR(windata-> |
419 window_surface->GetSize(windata->window_surface, &cw, | 424 window_surface->GetSize(windata->window_surface, &cw, |
420 &ch)); | 425 &ch)); |
421 if (cw != windata->size.w || ch != windata->size.h) { | 426 if (cw != windata->size.w || ch != windata->size.h) { |
422 adjust = 1; | 427 adjust = 1; |
423 } | 428 } |
424 | 429 |
425 if (adjust) { | 430 if (adjust) { |
431 #if SDL_DIRECTFB_OPENGL | |
432 DirectFB_GL_FreeWindowContexts(_this, window); | |
433 #endif | |
434 | |
426 #if DFB_VERSION_ATLEAST(1,2,1) | 435 #if DFB_VERSION_ATLEAST(1,2,1) |
427 SDL_DFB_CHECKERR(windata->window->ResizeSurface(windata->window, | 436 SDL_DFB_CHECKERR(windata->window->ResizeSurface(windata->window, |
428 windata->size.w, | 437 windata->size.w, |
429 windata->size.h)); | 438 windata->size.h)); |
430 SDL_DFB_CHECKERR(windata->surface->MakeSubSurface(windata->surface, | 439 SDL_DFB_CHECKERR(windata->surface->MakeSubSurface(windata->surface, |
444 windata->size.h)); | 453 windata->size.h)); |
445 SDL_DFB_CHECKERR(windata->window_surface-> | 454 SDL_DFB_CHECKERR(windata->window_surface-> |
446 GetSubSurface(windata->window_surface, | 455 GetSubSurface(windata->window_surface, |
447 &windata->client, &windata->surface)); | 456 &windata->client, &windata->surface)); |
448 #endif | 457 #endif |
449 DirectFB_WM_RedrawLayout(window); | 458 DirectFB_WM_RedrawLayout(_this, window); |
450 } | 459 |
460 #if SDL_DIRECTFB_OPENGL | |
461 DirectFB_GL_ReAllocWindowContexts(_this, window); | |
462 #endif | |
463 } | |
451 error: | 464 error: |
452 return; | 465 return; |
453 } | 466 } |