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 }