2 Simple DirectMedia Layer
3 Copyright (C) 1997-2011 Sam Lantinga <slouken@libsdl.org>
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
21 #include "SDL_config.h"
23 #if SDL_VIDEO_DRIVER_DIRECTFB
25 #include "SDL_DirectFB_video.h"
26 #include "SDL_DirectFB_modes.h"
27 #include "SDL_DirectFB_window.h"
28 #include "SDL_DirectFB_shape.h"
30 #if SDL_DIRECTFB_OPENGL
31 #include "SDL_DirectFB_opengl.h"
34 #include "SDL_syswm.h"
36 #include "../SDL_pixels_c.h"
39 DirectFB_CreateWindow(_THIS, SDL_Window * window)
41 SDL_DFB_DEVICEDATA(_this);
42 SDL_DFB_DISPLAYDATA(window);
43 DFB_WindowData *windata = NULL;
44 DFBWindowOptions wopts;
45 DFBWindowDescription desc;
49 SDL_DFB_ALLOC_CLEAR(window->driverdata, sizeof(DFB_WindowData));
50 windata = (DFB_WindowData *) window->driverdata;
52 windata->is_managed = devdata->has_own_wm;
54 SDL_DFB_CHECKERR(devdata->dfb->SetCooperativeLevel(devdata->dfb,
56 SDL_DFB_CHECKERR(dispdata->layer->SetCooperativeLevel(dispdata->layer,
57 DLSCL_ADMINISTRATIVE));
59 /* FIXME ... ughh, ugly */
60 if (window->x == -1000 && window->y == -1000)
63 /* Fill the window description. */
67 DirectFB_WM_AdjustWindowLayout(window, window->flags, window->w, window->h);
72 DWDESC_WIDTH | DWDESC_HEIGHT | DWDESC_POSX | DWDESC_POSY | DWDESC_SURFACE_CAPS;
75 desc.flags |= DWDESC_CAPS;
76 desc.caps |= DWCAPS_ALPHACHANNEL;
80 desc.flags |= DWDESC_PIXELFORMAT;
83 if (!(window->flags & SDL_WINDOW_BORDERLESS))
84 desc.caps |= DWCAPS_NODECORATION;
88 desc.width = windata->size.w;
89 desc.height = windata->size.h;
90 desc.pixelformat = dispdata->pixelformat;
91 desc.surface_caps = DSCAPS_PREMULTIPLIED;
93 /* Create the window. */
94 SDL_DFB_CHECKERR(dispdata->layer->CreateWindow(dispdata->layer, &desc,
98 SDL_DFB_CHECK(windata->dfbwin->GetOptions(windata->dfbwin, &wopts));
100 /* explicit rescaling of surface */
102 if (window->flags & SDL_WINDOW_RESIZABLE) {
103 wopts &= ~DWOP_KEEP_SIZE;
106 wopts |= DWOP_KEEP_SIZE;
109 if (window->flags & SDL_WINDOW_FULLSCREEN) {
110 wopts |= DWOP_KEEP_POSITION | DWOP_KEEP_STACKING | DWOP_KEEP_SIZE;
111 SDL_DFB_CHECK(windata->dfbwin->SetStackingClass(windata->dfbwin, DWSC_UPPER));
115 wopts |= DWOP_SHAPED | DWOP_ALPHACHANNEL;
116 wopts &= ~DWOP_OPAQUE_REGION;
119 SDL_DFB_CHECK(windata->dfbwin->SetOptions(windata->dfbwin, wopts));
121 /* See what we got */
122 SDL_DFB_CHECK(DirectFB_WM_GetClientSize
123 (_this, window, &window->w, &window->h));
125 /* Get the window's surface. */
126 SDL_DFB_CHECKERR(windata->dfbwin->GetSurface(windata->dfbwin,
127 &windata->window_surface));
129 /* And get a subsurface for rendering */
130 SDL_DFB_CHECKERR(windata->window_surface->
131 GetSubSurface(windata->window_surface, &windata->client,
134 SDL_DFB_CHECK(windata->dfbwin->SetOpacity(windata->dfbwin, 0xFF));
136 /* Create Eventbuffer */
138 SDL_DFB_CHECKERR(windata->dfbwin->CreateEventBuffer(windata->dfbwin,
141 SDL_DFB_CHECKERR(windata->dfbwin->
142 EnableEvents(windata->dfbwin, DWET_ALL));
145 /* FIXME: once during Video_Init */
146 windata->font = NULL;
148 /* Make it the top most window. */
149 SDL_DFB_CHECK(windata->dfbwin->RaiseToTop(windata->dfbwin));
151 /* remember parent */
152 //windata->sdlwin = window;
154 /* Add to list ... */
156 windata->next = devdata->firstwin;
157 windata->opacity = 0xFF;
158 devdata->firstwin = window;
161 DirectFB_WM_RedrawLayout(_this, window);
165 SDL_DFB_RELEASE(windata->surface);
166 SDL_DFB_RELEASE(windata->dfbwin);
171 DirectFB_CreateWindowFrom(_THIS, SDL_Window * window, const void *data)
178 DirectFB_SetWindowTitle(_THIS, SDL_Window * window)
180 SDL_DFB_WINDOWDATA(window);
182 if (windata->is_managed) {
183 windata->wm_needs_redraw = 1;
184 DirectFB_WM_RedrawLayout(_this, window);
190 DirectFB_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon)
192 SDL_DFB_DEVICEDATA(_this);
193 SDL_DFB_WINDOWDATA(window);
194 SDL_Surface *surface = NULL;
197 SDL_PixelFormat format;
198 DFBSurfaceDescription dsc;
203 /* Convert the icon to ARGB for modern window managers */
204 SDL_InitFormat(&format, SDL_PIXELFORMAT_ARGB8888);
205 surface = SDL_ConvertSurface(icon, &format, 0);
210 DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS;
211 dsc.caps = DSCAPS_VIDEOONLY;
212 dsc.width = surface->w;
213 dsc.height = surface->h;
214 dsc.pixelformat = DSPF_ARGB;
216 SDL_DFB_CHECKERR(devdata->dfb->CreateSurface(devdata->dfb, &dsc,
219 SDL_DFB_CHECKERR(windata->icon->Lock(windata->icon, DSLF_WRITE,
220 (void *) &dest, &pitch));
223 for (i = 0; i < surface->h; i++)
224 memcpy((char *) dest + i * pitch,
225 (char *) p + i * surface->pitch, 4 * surface->w);
227 SDL_DFB_CHECK(windata->icon->Unlock(windata->icon));
228 SDL_FreeSurface(surface);
230 SDL_DFB_RELEASE(windata->icon);
235 SDL_FreeSurface(surface);
236 SDL_DFB_RELEASE(windata->icon);
241 DirectFB_SetWindowPosition(_THIS, SDL_Window * window)
243 SDL_DFB_WINDOWDATA(window);
249 DirectFB_WM_AdjustWindowLayout(window, window->flags, window->w, window->h);
250 SDL_DFB_CHECK(windata->dfbwin->MoveTo(windata->dfbwin, x, y));
254 DirectFB_SetWindowSize(_THIS, SDL_Window * window)
256 SDL_DFB_WINDOWDATA(window);
258 if(SDL_IsShapedWindow(window))
259 DirectFB_ResizeWindowShape(window);
261 if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
265 /* Make sure all events are disabled for this operation ! */
266 SDL_DFB_CHECKERR(windata->dfbwin->DisableEvents(windata->dfbwin,
268 SDL_DFB_CHECKERR(DirectFB_WM_GetClientSize(_this, window, &cw, &ch));
270 if (cw != window->w || ch != window->h) {
272 DirectFB_WM_AdjustWindowLayout(window, window->flags, window->w, window->h);
273 SDL_DFB_CHECKERR(windata->dfbwin->Resize(windata->dfbwin,
278 SDL_DFB_CHECKERR(DirectFB_WM_GetClientSize
279 (_this, window, &window->w, &window->h));
280 DirectFB_AdjustWindowSurface(window);
282 SDL_DFB_CHECKERR(windata->dfbwin->EnableEvents(windata->dfbwin,
288 SDL_DFB_CHECK(windata->dfbwin->EnableEvents(windata->dfbwin, DWET_ALL));
293 DirectFB_ShowWindow(_THIS, SDL_Window * window)
295 SDL_DFB_WINDOWDATA(window);
297 SDL_DFB_CHECK(windata->dfbwin->SetOpacity(windata->dfbwin, windata->opacity));
302 DirectFB_HideWindow(_THIS, SDL_Window * window)
304 SDL_DFB_WINDOWDATA(window);
306 SDL_DFB_CHECK(windata->dfbwin->GetOpacity(windata->dfbwin, &windata->opacity));
307 SDL_DFB_CHECK(windata->dfbwin->SetOpacity(windata->dfbwin, 0));
311 DirectFB_RaiseWindow(_THIS, SDL_Window * window)
313 SDL_DFB_WINDOWDATA(window);
315 SDL_DFB_CHECK(windata->dfbwin->RaiseToTop(windata->dfbwin));
316 SDL_DFB_CHECK(windata->dfbwin->RequestFocus(windata->dfbwin));
320 DirectFB_MaximizeWindow(_THIS, SDL_Window * window)
322 SDL_DFB_WINDOWDATA(window);
323 SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
324 DFBWindowOptions wopts;
326 SDL_DFB_CHECK(windata->dfbwin->GetPosition(windata->dfbwin,
327 &windata->restore.x, &windata->restore.y));
328 SDL_DFB_CHECK(windata->dfbwin->GetSize(windata->dfbwin, &windata->restore.w,
329 &windata->restore.h));
331 DirectFB_WM_AdjustWindowLayout(window, window->flags | SDL_WINDOW_MAXIMIZED, display->current_mode.w, display->current_mode.h) ;
333 SDL_DFB_CHECK(windata->dfbwin->MoveTo(windata->dfbwin, 0, 0));
334 SDL_DFB_CHECK(windata->dfbwin->Resize(windata->dfbwin,
335 display->current_mode.w, display->current_mode.h));
338 SDL_DFB_CHECK(windata->dfbwin->GetOptions(windata->dfbwin, &wopts));
339 wopts |= DWOP_KEEP_SIZE | DWOP_KEEP_POSITION;
340 SDL_DFB_CHECK(windata->dfbwin->SetOptions(windata->dfbwin, wopts));
344 DirectFB_MinimizeWindow(_THIS, SDL_Window * window)
346 /* FIXME: Size to 32x32 ? */
352 DirectFB_RestoreWindow(_THIS, SDL_Window * window)
354 SDL_DFB_WINDOWDATA(window);
355 DFBWindowOptions wopts;
358 SDL_DFB_CHECK(windata->dfbwin->GetOptions(windata->dfbwin, &wopts));
359 wopts &= ~(DWOP_KEEP_SIZE | DWOP_KEEP_POSITION);
360 SDL_DFB_CHECK(windata->dfbwin->SetOptions(windata->dfbwin, wopts));
363 DirectFB_WM_AdjustWindowLayout(window, window->flags & ~(SDL_WINDOW_MAXIMIZED | SDL_WINDOW_MINIMIZED),
364 windata->restore.w, windata->restore.h);
365 SDL_DFB_CHECK(windata->dfbwin->Resize(windata->dfbwin, windata->restore.w,
366 windata->restore.h));
367 SDL_DFB_CHECK(windata->dfbwin->MoveTo(windata->dfbwin, windata->restore.x,
368 windata->restore.y));
370 if (!(window->flags & SDL_WINDOW_RESIZABLE))
371 wopts |= DWOP_KEEP_SIZE;
373 if (window->flags & SDL_WINDOW_FULLSCREEN)
374 wopts |= DWOP_KEEP_POSITION | DWOP_KEEP_SIZE;
375 SDL_DFB_CHECK(windata->dfbwin->SetOptions(windata->dfbwin, wopts));
381 DirectFB_SetWindowGrab(_THIS, SDL_Window * window)
383 SDL_DFB_DEVICEDATA(_this);
384 SDL_DFB_WINDOWDATA(window);
385 DFB_WindowData *gwindata = ((devdata->grabbed_window) ? (DFB_WindowData *) ((devdata->grabbed_window)->driverdata) : NULL);
387 if ((window->flags & SDL_WINDOW_INPUT_GRABBED)) {
388 if (gwindata != NULL)
390 SDL_DFB_CHECK(gwindata->dfbwin->UngrabPointer(gwindata->dfbwin));
391 SDL_DFB_CHECK(gwindata->dfbwin->UngrabKeyboard(gwindata->dfbwin));
393 SDL_DFB_CHECK(windata->dfbwin->GrabPointer(windata->dfbwin));
394 SDL_DFB_CHECK(windata->dfbwin->GrabKeyboard(windata->dfbwin));
395 devdata->grabbed_window = window;
397 SDL_DFB_CHECK(windata->dfbwin->UngrabPointer(windata->dfbwin));
398 SDL_DFB_CHECK(windata->dfbwin->UngrabKeyboard(windata->dfbwin));
399 devdata->grabbed_window = NULL;
404 DirectFB_DestroyWindow(_THIS, SDL_Window * window)
406 SDL_DFB_DEVICEDATA(_this);
407 SDL_DFB_WINDOWDATA(window);
411 SDL_DFB_CHECK(windata->dfbwin->UngrabPointer(windata->dfbwin));
412 SDL_DFB_CHECK(windata->dfbwin->UngrabKeyboard(windata->dfbwin));
414 #if SDL_DIRECTFB_OPENGL
415 DirectFB_GL_DestroyWindowContexts(_this, window);
420 SDL_ShapeData *data = window->shaper->driverdata;
421 SDL_DFB_CHECK(data->surface->ReleaseSource(data->surface));
422 SDL_DFB_RELEASE(data->surface);
424 SDL_DFB_FREE(window->shaper);
427 SDL_DFB_CHECK(windata->window_surface->SetFont(windata->window_surface, NULL));
428 SDL_DFB_CHECK(windata->surface->ReleaseSource(windata->surface));
429 SDL_DFB_CHECK(windata->window_surface->ReleaseSource(windata->window_surface));
430 SDL_DFB_RELEASE(windata->icon);
431 SDL_DFB_RELEASE(windata->font);
432 SDL_DFB_RELEASE(windata->eventbuffer);
433 SDL_DFB_RELEASE(windata->surface);
434 SDL_DFB_RELEASE(windata->window_surface);
436 SDL_DFB_RELEASE(windata->dfbwin);
438 /* Remove from list ... */
440 p = devdata->firstwin->driverdata;
442 while (p && p->next != window)
443 p = (p->next ? p->next->driverdata : NULL);
445 p->next = windata->next;
447 devdata->firstwin = windata->next;
453 DirectFB_GetWindowWMInfo(_THIS, SDL_Window * window,
454 struct SDL_SysWMinfo * info)
456 SDL_DFB_DEVICEDATA(_this);
457 SDL_DFB_WINDOWDATA(window);
459 if (info->version.major == SDL_MAJOR_VERSION &&
460 info->version.minor == SDL_MINOR_VERSION) {
461 info->subsystem = SDL_SYSWM_DIRECTFB;
462 info->info.dfb.dfb = devdata->dfb;
463 info->info.dfb.window = windata->dfbwin;
464 info->info.dfb.surface = windata->surface;
467 SDL_SetError("Application not compiled with SDL %d.%d\n",
468 SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
474 DirectFB_AdjustWindowSurface(SDL_Window * window)
476 SDL_DFB_WINDOWDATA(window);
477 int adjust = windata->wm_needs_redraw;
480 DirectFB_WM_AdjustWindowLayout(window, window->flags, window->w, window->h);
482 SDL_DFB_CHECKERR(windata->
483 window_surface->GetSize(windata->window_surface, &cw,
485 if (cw != windata->size.w || ch != windata->size.h) {
490 #if SDL_DIRECTFB_OPENGL
491 DirectFB_GL_FreeWindowContexts(SDL_GetVideoDevice(), window);
494 #if (DFB_VERSION_ATLEAST(1,2,1))
495 SDL_DFB_CHECKERR(windata->dfbwin->ResizeSurface(windata->dfbwin,
498 SDL_DFB_CHECKERR(windata->surface->MakeSubSurface(windata->surface,
503 DFBWindowOptions opts;
505 SDL_DFB_CHECKERR(windata->dfbwin->GetOptions(windata->dfbwin, &opts));
506 /* recreate subsurface */
507 SDL_DFB_RELEASE(windata->surface);
509 if (opts & DWOP_SCALE)
510 SDL_DFB_CHECKERR(windata->dfbwin->ResizeSurface(windata->dfbwin,
513 SDL_DFB_CHECKERR(windata->window_surface->
514 GetSubSurface(windata->window_surface,
515 &windata->client, &windata->surface));
517 DirectFB_WM_RedrawLayout(SDL_GetVideoDevice(), window);
519 #if SDL_DIRECTFB_OPENGL
520 DirectFB_GL_ReAllocWindowContexts(SDL_GetVideoDevice(), window);
527 #endif /* SDL_VIDEO_DRIVER_DIRECTFB */