2 SDL - Simple DirectMedia Layer
3 Copyright (C) 1997-2011 Sam Lantinga
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 SDL1.3 DirectFB driver by couriersud@arcor.de
26 #include "SDL_DirectFB_video.h"
27 #include "SDL_DirectFB_modes.h"
28 #include "SDL_DirectFB_window.h"
29 #include "SDL_DirectFB_shape.h"
31 #if SDL_DIRECTFB_OPENGL
32 #include "SDL_DirectFB_opengl.h"
35 #include "SDL_syswm.h"
37 #include "../SDL_pixels_c.h"
40 DirectFB_CreateWindow(_THIS, SDL_Window * window)
42 SDL_DFB_DEVICEDATA(_this);
43 SDL_DFB_DISPLAYDATA(window);
44 DFB_WindowData *windata = NULL;
45 DFBWindowOptions wopts;
46 DFBWindowDescription desc;
50 SDL_DFB_ALLOC_CLEAR(window->driverdata, sizeof(DFB_WindowData));
51 windata = (DFB_WindowData *) window->driverdata;
53 windata->is_managed = devdata->has_own_wm;
55 SDL_DFB_CHECKERR(devdata->dfb->SetCooperativeLevel(devdata->dfb,
57 SDL_DFB_CHECKERR(dispdata->layer->SetCooperativeLevel(dispdata->layer,
58 DLSCL_ADMINISTRATIVE));
60 /* FIXME ... ughh, ugly */
61 if (window->x == -1000 && window->y == -1000)
64 /* Fill the window description. */
65 if (SDL_WINDOWPOS_ISCENTERED(window->x)) {
66 x = (dispdata->cw - window->w) / 2;
67 } else if (SDL_WINDOWPOS_ISUNDEFINED(window->x)) {
73 if (SDL_WINDOWPOS_ISCENTERED(window->y)) {
74 y = (dispdata->ch - window->h) / 2;
75 } else if (SDL_WINDOWPOS_ISUNDEFINED(window->y)) {
81 if (window->flags & SDL_WINDOW_FULLSCREEN) {
86 DirectFB_WM_AdjustWindowLayout(window, window->flags, window->w, window->h);
91 DWDESC_WIDTH | DWDESC_HEIGHT | DWDESC_POSX | DWDESC_POSY | DWDESC_SURFACE_CAPS;
94 desc.flags |= DWDESC_CAPS;
95 desc.caps |= DWCAPS_ALPHACHANNEL;
99 desc.flags |= DWDESC_PIXELFORMAT;
102 if (!(window->flags & SDL_WINDOW_BORDERLESS))
103 desc.caps |= DWCAPS_NODECORATION;
107 desc.width = windata->size.w;
108 desc.height = windata->size.h;
109 desc.pixelformat = dispdata->pixelformat;
110 desc.surface_caps = DSCAPS_PREMULTIPLIED;
112 /* Create the window. */
113 SDL_DFB_CHECKERR(dispdata->layer->CreateWindow(dispdata->layer, &desc,
117 SDL_DFB_CHECK(windata->dfbwin->GetOptions(windata->dfbwin, &wopts));
119 /* explicit rescaling of surface */
121 if (window->flags & SDL_WINDOW_RESIZABLE) {
122 wopts &= ~DWOP_KEEP_SIZE;
125 wopts |= DWOP_KEEP_SIZE;
128 if (window->flags & SDL_WINDOW_FULLSCREEN) {
129 wopts |= DWOP_KEEP_POSITION | DWOP_KEEP_STACKING | DWOP_KEEP_SIZE;
130 SDL_DFB_CHECK(windata->dfbwin->SetStackingClass(windata->dfbwin, DWSC_UPPER));
134 wopts |= DWOP_SHAPED | DWOP_ALPHACHANNEL;
135 wopts &= ~DWOP_OPAQUE_REGION;
138 SDL_DFB_CHECK(windata->dfbwin->SetOptions(windata->dfbwin, wopts));
140 /* See what we got */
141 SDL_DFB_CHECK(DirectFB_WM_GetClientSize
142 (_this, window, &window->w, &window->h));
144 /* Get the window's surface. */
145 SDL_DFB_CHECKERR(windata->dfbwin->GetSurface(windata->dfbwin,
146 &windata->window_surface));
148 /* And get a subsurface for rendering */
149 SDL_DFB_CHECKERR(windata->window_surface->
150 GetSubSurface(windata->window_surface, &windata->client,
153 SDL_DFB_CHECK(windata->dfbwin->SetOpacity(windata->dfbwin, 0xFF));
155 /* Create Eventbuffer */
157 SDL_DFB_CHECKERR(windata->dfbwin->CreateEventBuffer(windata->dfbwin,
160 SDL_DFB_CHECKERR(windata->dfbwin->
161 EnableEvents(windata->dfbwin, DWET_ALL));
164 /* FIXME: once during Video_Init */
165 windata->font = NULL;
167 /* Make it the top most window. */
168 SDL_DFB_CHECK(windata->dfbwin->RaiseToTop(windata->dfbwin));
170 /* remember parent */
171 //windata->sdlwin = window;
173 /* Add to list ... */
175 windata->next = devdata->firstwin;
176 windata->opacity = 0xFF;
177 devdata->firstwin = window;
180 DirectFB_WM_RedrawLayout(_this, window);
184 SDL_DFB_RELEASE(windata->surface);
185 SDL_DFB_RELEASE(windata->dfbwin);
190 DirectFB_CreateWindowFrom(_THIS, SDL_Window * window, const void *data)
197 DirectFB_SetWindowTitle(_THIS, SDL_Window * window)
199 SDL_DFB_WINDOWDATA(window);
201 if (windata->is_managed) {
202 windata->wm_needs_redraw = 1;
203 DirectFB_WM_RedrawLayout(_this, window);
209 DirectFB_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon)
211 SDL_DFB_DEVICEDATA(_this);
212 SDL_DFB_WINDOWDATA(window);
213 SDL_Surface *surface = NULL;
216 SDL_PixelFormat format;
217 DFBSurfaceDescription dsc;
222 /* Convert the icon to ARGB for modern window managers */
223 SDL_InitFormat(&format, 32, 0x00FF0000, 0x0000FF00, 0x000000FF,
225 surface = SDL_ConvertSurface(icon, &format, 0);
230 DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS;
231 dsc.caps = DSCAPS_VIDEOONLY;
232 dsc.width = surface->w;
233 dsc.height = surface->h;
234 dsc.pixelformat = DSPF_ARGB;
236 SDL_DFB_CHECKERR(devdata->dfb->CreateSurface(devdata->dfb, &dsc,
239 SDL_DFB_CHECKERR(windata->icon->Lock(windata->icon, DSLF_WRITE,
240 (void *) &dest, &pitch));
243 for (i = 0; i < surface->h; i++)
244 memcpy((char *) dest + i * pitch,
245 (char *) p + i * surface->pitch, 4 * surface->w);
247 SDL_DFB_CHECK(windata->icon->Unlock(windata->icon));
248 SDL_FreeSurface(surface);
250 SDL_DFB_RELEASE(windata->icon);
255 SDL_FreeSurface(surface);
256 SDL_DFB_RELEASE(windata->icon);
261 DirectFB_SetWindowPosition(_THIS, SDL_Window * window)
263 SDL_DFB_WINDOWDATA(window);
264 SDL_DFB_DISPLAYDATA(window);
267 if (SDL_WINDOWPOS_ISCENTERED(window->x)) {
268 x = (dispdata->cw - window->w) / 2;
269 } else if (SDL_WINDOWPOS_ISUNDEFINED(window->x)) {
275 if (SDL_WINDOWPOS_ISCENTERED(window->y)) {
276 y = (dispdata->ch - window->h) / 2;
277 } else if (SDL_WINDOWPOS_ISUNDEFINED(window->y)) {
283 if (window->flags & SDL_WINDOW_FULLSCREEN) {
287 DirectFB_WM_AdjustWindowLayout(window, window->flags, window->w, window->h);
288 SDL_DFB_CHECK(windata->dfbwin->MoveTo(windata->dfbwin, x, y));
292 DirectFB_SetWindowSize(_THIS, SDL_Window * window)
294 SDL_DFB_WINDOWDATA(window);
296 if(SDL_IsShapedWindow(window))
297 DirectFB_ResizeWindowShape(window);
299 if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
303 /* Make sure all events are disabled for this operation ! */
304 SDL_DFB_CHECKERR(windata->dfbwin->DisableEvents(windata->dfbwin,
306 SDL_DFB_CHECKERR(DirectFB_WM_GetClientSize(_this, window, &cw, &ch));
308 if (cw != window->w || ch != window->h) {
310 DirectFB_WM_AdjustWindowLayout(window, window->flags, window->w, window->h);
311 SDL_DFB_CHECKERR(windata->dfbwin->Resize(windata->dfbwin,
316 SDL_DFB_CHECKERR(DirectFB_WM_GetClientSize
317 (_this, window, &window->w, &window->h));
318 DirectFB_AdjustWindowSurface(window);
320 SDL_DFB_CHECKERR(windata->dfbwin->EnableEvents(windata->dfbwin,
326 SDL_DFB_CHECK(windata->dfbwin->EnableEvents(windata->dfbwin, DWET_ALL));
331 DirectFB_ShowWindow(_THIS, SDL_Window * window)
333 SDL_DFB_WINDOWDATA(window);
335 SDL_DFB_CHECK(windata->dfbwin->SetOpacity(windata->dfbwin, windata->opacity));
340 DirectFB_HideWindow(_THIS, SDL_Window * window)
342 SDL_DFB_WINDOWDATA(window);
344 SDL_DFB_CHECK(windata->dfbwin->GetOpacity(windata->dfbwin, &windata->opacity));
345 SDL_DFB_CHECK(windata->dfbwin->SetOpacity(windata->dfbwin, 0));
349 DirectFB_RaiseWindow(_THIS, SDL_Window * window)
351 SDL_DFB_WINDOWDATA(window);
353 SDL_DFB_CHECK(windata->dfbwin->RaiseToTop(windata->dfbwin));
354 SDL_DFB_CHECK(windata->dfbwin->RequestFocus(windata->dfbwin));
358 DirectFB_MaximizeWindow(_THIS, SDL_Window * window)
360 SDL_DFB_WINDOWDATA(window);
361 SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
362 DFBWindowOptions wopts;
364 SDL_DFB_CHECK(windata->dfbwin->GetPosition(windata->dfbwin,
365 &windata->restore.x, &windata->restore.y));
366 SDL_DFB_CHECK(windata->dfbwin->GetSize(windata->dfbwin, &windata->restore.w,
367 &windata->restore.h));
369 DirectFB_WM_AdjustWindowLayout(window, window->flags | SDL_WINDOW_MAXIMIZED, display->current_mode.w, display->current_mode.h) ;
371 SDL_DFB_CHECK(windata->dfbwin->MoveTo(windata->dfbwin, 0, 0));
372 SDL_DFB_CHECK(windata->dfbwin->Resize(windata->dfbwin,
373 display->current_mode.w, display->current_mode.h));
376 SDL_DFB_CHECK(windata->dfbwin->GetOptions(windata->dfbwin, &wopts));
377 wopts |= DWOP_KEEP_SIZE | DWOP_KEEP_POSITION;
378 SDL_DFB_CHECK(windata->dfbwin->SetOptions(windata->dfbwin, wopts));
382 DirectFB_MinimizeWindow(_THIS, SDL_Window * window)
384 /* FIXME: Size to 32x32 ? */
390 DirectFB_RestoreWindow(_THIS, SDL_Window * window)
392 SDL_DFB_WINDOWDATA(window);
393 DFBWindowOptions wopts;
396 SDL_DFB_CHECK(windata->dfbwin->GetOptions(windata->dfbwin, &wopts));
397 wopts &= ~(DWOP_KEEP_SIZE | DWOP_KEEP_POSITION);
398 SDL_DFB_CHECK(windata->dfbwin->SetOptions(windata->dfbwin, wopts));
401 DirectFB_WM_AdjustWindowLayout(window, window->flags & ~(SDL_WINDOW_MAXIMIZED | SDL_WINDOW_MINIMIZED),
402 windata->restore.w, windata->restore.h);
403 SDL_DFB_CHECK(windata->dfbwin->Resize(windata->dfbwin, windata->restore.w,
404 windata->restore.h));
405 SDL_DFB_CHECK(windata->dfbwin->MoveTo(windata->dfbwin, windata->restore.x,
406 windata->restore.y));
408 if (!(window->flags & SDL_WINDOW_RESIZABLE))
409 wopts |= DWOP_KEEP_SIZE;
411 if (window->flags & SDL_WINDOW_FULLSCREEN)
412 wopts |= DWOP_KEEP_POSITION | DWOP_KEEP_SIZE;
413 SDL_DFB_CHECK(windata->dfbwin->SetOptions(windata->dfbwin, wopts));
419 DirectFB_SetWindowGrab(_THIS, SDL_Window * window)
421 SDL_DFB_DEVICEDATA(_this);
422 SDL_DFB_WINDOWDATA(window);
423 DFB_WindowData *gwindata = ((devdata->grabbed_window) ? (DFB_WindowData *) ((devdata->grabbed_window)->driverdata) : NULL);
425 if ((window->flags & SDL_WINDOW_INPUT_GRABBED)) {
426 if (gwindata != NULL)
428 SDL_DFB_CHECK(gwindata->dfbwin->UngrabPointer(gwindata->dfbwin));
429 SDL_DFB_CHECK(gwindata->dfbwin->UngrabKeyboard(gwindata->dfbwin));
431 SDL_DFB_CHECK(windata->dfbwin->GrabPointer(windata->dfbwin));
432 SDL_DFB_CHECK(windata->dfbwin->GrabKeyboard(windata->dfbwin));
433 devdata->grabbed_window = window;
435 SDL_DFB_CHECK(windata->dfbwin->UngrabPointer(windata->dfbwin));
436 SDL_DFB_CHECK(windata->dfbwin->UngrabKeyboard(windata->dfbwin));
437 devdata->grabbed_window = NULL;
442 DirectFB_DestroyWindow(_THIS, SDL_Window * window)
444 SDL_DFB_DEVICEDATA(_this);
445 SDL_DFB_WINDOWDATA(window);
449 SDL_DFB_CHECK(windata->dfbwin->UngrabPointer(windata->dfbwin));
450 SDL_DFB_CHECK(windata->dfbwin->UngrabKeyboard(windata->dfbwin));
452 #if SDL_DIRECTFB_OPENGL
453 DirectFB_GL_DestroyWindowContexts(_this, window);
458 SDL_ShapeData *data = window->shaper->driverdata;
459 SDL_DFB_CHECK(data->surface->ReleaseSource(data->surface));
460 SDL_DFB_RELEASE(data->surface);
462 SDL_DFB_FREE(window->shaper);
465 SDL_DFB_CHECK(windata->window_surface->SetFont(windata->window_surface, NULL));
466 SDL_DFB_CHECK(windata->surface->ReleaseSource(windata->surface));
467 SDL_DFB_CHECK(windata->window_surface->ReleaseSource(windata->window_surface));
468 SDL_DFB_RELEASE(windata->icon);
469 SDL_DFB_RELEASE(windata->font);
470 SDL_DFB_RELEASE(windata->eventbuffer);
471 SDL_DFB_RELEASE(windata->surface);
472 SDL_DFB_RELEASE(windata->window_surface);
474 SDL_DFB_RELEASE(windata->dfbwin);
476 /* Remove from list ... */
478 p = devdata->firstwin->driverdata;
480 while (p && p->next != window)
481 p = (p->next ? p->next->driverdata : NULL);
483 p->next = windata->next;
485 devdata->firstwin = windata->next;
491 DirectFB_GetWindowWMInfo(_THIS, SDL_Window * window,
492 struct SDL_SysWMinfo * info)
494 SDL_DFB_DEVICEDATA(_this);
495 SDL_DFB_WINDOWDATA(window);
497 if (info->version.major == SDL_MAJOR_VERSION &&
498 info->version.minor == SDL_MINOR_VERSION) {
499 info->subsystem = SDL_SYSWM_DIRECTFB;
500 info->info.dfb.dfb = devdata->dfb;
501 info->info.dfb.window = windata->dfbwin;
502 info->info.dfb.surface = windata->surface;
505 SDL_SetError("Application not compiled with SDL %d.%d\n",
506 SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
512 DirectFB_AdjustWindowSurface(SDL_Window * window)
514 SDL_DFB_WINDOWDATA(window);
515 int adjust = windata->wm_needs_redraw;
518 DirectFB_WM_AdjustWindowLayout(window, window->flags, window->w, window->h);
520 SDL_DFB_CHECKERR(windata->
521 window_surface->GetSize(windata->window_surface, &cw,
523 if (cw != windata->size.w || ch != windata->size.h) {
528 #if SDL_DIRECTFB_OPENGL
529 DirectFB_GL_FreeWindowContexts(SDL_GetVideoDevice(), window);
532 #if (DFB_VERSION_ATLEAST(1,2,1))
533 SDL_DFB_CHECKERR(windata->dfbwin->ResizeSurface(windata->dfbwin,
536 SDL_DFB_CHECKERR(windata->surface->MakeSubSurface(windata->surface,
541 DFBWindowOptions opts;
543 SDL_DFB_CHECKERR(windata->dfbwin->GetOptions(windata->dfbwin, &opts));
544 /* recreate subsurface */
545 SDL_DFB_RELEASE(windata->surface);
547 if (opts & DWOP_SCALE)
548 SDL_DFB_CHECKERR(windata->dfbwin->ResizeSurface(windata->dfbwin,
551 SDL_DFB_CHECKERR(windata->window_surface->
552 GetSubSurface(windata->window_surface,
553 &windata->client, &windata->surface));
555 DirectFB_WM_RedrawLayout(SDL_GetVideoDevice(), window);
557 #if SDL_DIRECTFB_OPENGL
558 DirectFB_GL_ReAllocWindowContexts(SDL_GetVideoDevice(), window);