SDL 2.0
SDL_DirectFB_window.c
Go to the documentation of this file.
1/*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2019 Sam Lantinga <slouken@libsdl.org>
4
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.
8
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:
12
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.
20*/
21#include "../../SDL_internal.h"
22
23#if SDL_VIDEO_DRIVER_DIRECTFB
24
25#include "SDL_DirectFB_video.h"
26#include "SDL_DirectFB_modes.h"
27#include "SDL_DirectFB_window.h"
28#include "SDL_DirectFB_shape.h"
29
30#if SDL_DIRECTFB_OPENGL
31#include "SDL_DirectFB_opengl.h"
32#endif
33
34#include "SDL_syswm.h"
35
36#include "../SDL_pixels_c.h"
37
38int
40{
43 DFB_WindowData *windata = NULL;
44 DFBWindowOptions wopts;
45 DFBWindowDescription desc;
46 int x, y;
47 int bshaped = 0;
48
49 SDL_DFB_ALLOC_CLEAR(window->driverdata, sizeof(DFB_WindowData));
50 SDL_memset(&desc, 0, sizeof(DFBWindowDescription));
51 windata = (DFB_WindowData *) window->driverdata;
52
53 windata->is_managed = devdata->has_own_wm;
54#if 1
55 SDL_DFB_CHECKERR(devdata->dfb->SetCooperativeLevel(devdata->dfb,
56 DFSCL_NORMAL));
57 SDL_DFB_CHECKERR(dispdata->layer->SetCooperativeLevel(dispdata->layer,
58 DLSCL_ADMINISTRATIVE));
59#endif
60 /* FIXME ... ughh, ugly */
61 if (window->x == -1000 && window->y == -1000)
62 bshaped = 1;
63
64 /* Fill the window description. */
65 x = window->x;
66 y = window->y;
67
69
70 /* Create Window */
71 desc.caps = 0;
72 desc.flags =
73 DWDESC_WIDTH | DWDESC_HEIGHT | DWDESC_POSX | DWDESC_POSY | DWDESC_SURFACE_CAPS;
74
75 if (bshaped) {
76 desc.flags |= DWDESC_CAPS;
77 desc.caps |= DWCAPS_ALPHACHANNEL;
78 }
79 else
80 {
81 desc.flags |= DWDESC_PIXELFORMAT;
82 }
83
84 if (!(window->flags & SDL_WINDOW_BORDERLESS))
85 desc.caps |= DWCAPS_NODECORATION;
86
87 desc.posx = x;
88 desc.posy = y;
89 desc.width = windata->size.w;
90 desc.height = windata->size.h;
91 desc.pixelformat = dispdata->pixelformat;
92 desc.surface_caps = DSCAPS_PREMULTIPLIED;
93#if DIRECTFB_MAJOR_VERSION == 1 && DIRECTFB_MINOR_VERSION >= 6
94 if (window->flags & SDL_WINDOW_OPENGL) {
95 desc.surface_caps |= DSCAPS_GL;
96 }
97#endif
98
99 /* Create the window. */
100 SDL_DFB_CHECKERR(dispdata->layer->CreateWindow(dispdata->layer, &desc,
101 &windata->dfbwin));
102
103 /* Set Options */
104 SDL_DFB_CHECK(windata->dfbwin->GetOptions(windata->dfbwin, &wopts));
105
106 /* explicit rescaling of surface */
107 wopts |= DWOP_SCALE;
108 if (window->flags & SDL_WINDOW_RESIZABLE) {
109 wopts &= ~DWOP_KEEP_SIZE;
110 }
111 else {
112 wopts |= DWOP_KEEP_SIZE;
113 }
114
115 if (window->flags & SDL_WINDOW_FULLSCREEN) {
116 wopts |= DWOP_KEEP_POSITION | DWOP_KEEP_STACKING | DWOP_KEEP_SIZE;
117 SDL_DFB_CHECK(windata->dfbwin->SetStackingClass(windata->dfbwin, DWSC_UPPER));
118 }
119
120 if (bshaped) {
121 wopts |= DWOP_SHAPED | DWOP_ALPHACHANNEL;
122 wopts &= ~DWOP_OPAQUE_REGION;
123 }
124
125 SDL_DFB_CHECK(windata->dfbwin->SetOptions(windata->dfbwin, wopts));
126
127 /* See what we got */
129 (_this, window, &window->w, &window->h));
130
131 /* Get the window's surface. */
132 SDL_DFB_CHECKERR(windata->dfbwin->GetSurface(windata->dfbwin,
133 &windata->window_surface));
134
135 /* And get a subsurface for rendering */
136 SDL_DFB_CHECKERR(windata->window_surface->
137 GetSubSurface(windata->window_surface, &windata->client,
138 &windata->surface));
139
140 SDL_DFB_CHECK(windata->dfbwin->SetOpacity(windata->dfbwin, 0xFF));
141
142 /* Create Eventbuffer */
143
144 SDL_DFB_CHECKERR(windata->dfbwin->CreateEventBuffer(windata->dfbwin,
145 &windata->
146 eventbuffer));
147 SDL_DFB_CHECKERR(windata->dfbwin->
148 EnableEvents(windata->dfbwin, DWET_ALL));
149
150 /* Create a font */
151 /* FIXME: once during Video_Init */
152 windata->font = NULL;
153
154 /* Make it the top most window. */
155 SDL_DFB_CHECK(windata->dfbwin->RaiseToTop(windata->dfbwin));
156
157 /* remember parent */
158 /* windata->sdlwin = window; */
159
160 /* Add to list ... */
161
162 windata->next = devdata->firstwin;
163 windata->opacity = 0xFF;
164 devdata->firstwin = window;
165
166 /* Draw Frame */
168
169 return 0;
170 error:
171 SDL_DFB_RELEASE(windata->surface);
172 SDL_DFB_RELEASE(windata->dfbwin);
173 return -1;
174}
175
176int
178{
179 return SDL_Unsupported();
180}
181
182void
184{
186
187 if (windata->is_managed) {
188 windata->wm_needs_redraw = 1;
190 } else {
192 }
193}
194
195void
197{
201
202 if (icon) {
204 DFBSurfaceDescription dsc;
205 Uint32 *dest;
206 Uint32 *p;
207 int pitch, i;
208
209 /* Convert the icon to ARGB for modern window managers */
211 surface = SDL_ConvertSurface(icon, &format, 0);
212 if (!surface) {
213 return;
214 }
215 dsc.flags =
216 DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS;
217 dsc.caps = DSCAPS_VIDEOONLY;
218 dsc.width = surface->w;
219 dsc.height = surface->h;
220 dsc.pixelformat = DSPF_ARGB;
221
222 SDL_DFB_CHECKERR(devdata->dfb->CreateSurface(devdata->dfb, &dsc,
223 &windata->icon));
224
225 SDL_DFB_CHECKERR(windata->icon->Lock(windata->icon, DSLF_WRITE,
226 (void *) &dest, &pitch));
227
228 p = surface->pixels;
229 for (i = 0; i < surface->h; i++)
230 memcpy((char *) dest + i * pitch,
231 (char *) p + i * surface->pitch, 4 * surface->w);
232
233 SDL_DFB_CHECK(windata->icon->Unlock(windata->icon));
235 } else {
236 SDL_DFB_RELEASE(windata->icon);
237 }
238 return;
239 error:
241 SDL_DFB_RELEASE(windata->icon);
242 return;
243}
244
245void
247{
249 int x, y;
250
251 x = window->x;
252 y = window->y;
253
255 SDL_DFB_CHECK(windata->dfbwin->MoveTo(windata->dfbwin, x, y));
256}
257
258void
260{
262
265
266 if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
267 int cw;
268 int ch;
269
270 /* Make sure all events are disabled for this operation ! */
271 SDL_DFB_CHECKERR(windata->dfbwin->DisableEvents(windata->dfbwin,
272 DWET_ALL));
274
275 if (cw != window->w || ch != window->h) {
276
278 SDL_DFB_CHECKERR(windata->dfbwin->Resize(windata->dfbwin,
279 windata->size.w,
280 windata->size.h));
281 }
282
284 (_this, window, &window->w, &window->h));
286
287 SDL_DFB_CHECKERR(windata->dfbwin->EnableEvents(windata->dfbwin,
288 DWET_ALL));
289
290 }
291 return;
292 error:
293 SDL_DFB_CHECK(windata->dfbwin->EnableEvents(windata->dfbwin, DWET_ALL));
294 return;
295}
296
297void
299{
301
302 SDL_DFB_CHECK(windata->dfbwin->SetOpacity(windata->dfbwin, windata->opacity));
303
304}
305
306void
308{
310
311 SDL_DFB_CHECK(windata->dfbwin->GetOpacity(windata->dfbwin, &windata->opacity));
312 SDL_DFB_CHECK(windata->dfbwin->SetOpacity(windata->dfbwin, 0));
313}
314
315void
317{
319
320 SDL_DFB_CHECK(windata->dfbwin->RaiseToTop(windata->dfbwin));
321 SDL_DFB_CHECK(windata->dfbwin->RequestFocus(windata->dfbwin));
322}
323
324void
326{
329 DFBWindowOptions wopts;
330
331 SDL_DFB_CHECK(windata->dfbwin->GetPosition(windata->dfbwin,
332 &windata->restore.x, &windata->restore.y));
333 SDL_DFB_CHECK(windata->dfbwin->GetSize(windata->dfbwin, &windata->restore.w,
334 &windata->restore.h));
335
337
338 SDL_DFB_CHECK(windata->dfbwin->MoveTo(windata->dfbwin, 0, 0));
339 SDL_DFB_CHECK(windata->dfbwin->Resize(windata->dfbwin,
340 display->current_mode.w, display->current_mode.h));
341
342 /* Set Options */
343 SDL_DFB_CHECK(windata->dfbwin->GetOptions(windata->dfbwin, &wopts));
344 wopts |= DWOP_KEEP_SIZE | DWOP_KEEP_POSITION;
345 SDL_DFB_CHECK(windata->dfbwin->SetOptions(windata->dfbwin, wopts));
346}
347
348void
350{
351 /* FIXME: Size to 32x32 ? */
352
354}
355
356void
358{
360 DFBWindowOptions wopts;
361
362 /* Set Options */
363 SDL_DFB_CHECK(windata->dfbwin->GetOptions(windata->dfbwin, &wopts));
364 wopts &= ~(DWOP_KEEP_SIZE | DWOP_KEEP_POSITION);
365 SDL_DFB_CHECK(windata->dfbwin->SetOptions(windata->dfbwin, wopts));
366
367 /* Window layout */
369 windata->restore.w, windata->restore.h);
370 SDL_DFB_CHECK(windata->dfbwin->Resize(windata->dfbwin, windata->restore.w,
371 windata->restore.h));
372 SDL_DFB_CHECK(windata->dfbwin->MoveTo(windata->dfbwin, windata->restore.x,
373 windata->restore.y));
374
375 if (!(window->flags & SDL_WINDOW_RESIZABLE))
376 wopts |= DWOP_KEEP_SIZE;
377
378 if (window->flags & SDL_WINDOW_FULLSCREEN)
379 wopts |= DWOP_KEEP_POSITION | DWOP_KEEP_SIZE;
380 SDL_DFB_CHECK(windata->dfbwin->SetOptions(windata->dfbwin, wopts));
381
382
383}
384
385void
387{
390 DFB_WindowData *gwindata = ((devdata->grabbed_window) ? (DFB_WindowData *) ((devdata->grabbed_window)->driverdata) : NULL);
391
392 if ((window->flags & SDL_WINDOW_INPUT_GRABBED)) {
393 if (gwindata != NULL)
394 {
395 SDL_DFB_CHECK(gwindata->dfbwin->UngrabPointer(gwindata->dfbwin));
396 SDL_DFB_CHECK(gwindata->dfbwin->UngrabKeyboard(gwindata->dfbwin));
397 }
398 SDL_DFB_CHECK(windata->dfbwin->GrabPointer(windata->dfbwin));
399 SDL_DFB_CHECK(windata->dfbwin->GrabKeyboard(windata->dfbwin));
400 devdata->grabbed_window = window;
401 } else {
402 SDL_DFB_CHECK(windata->dfbwin->UngrabPointer(windata->dfbwin));
403 SDL_DFB_CHECK(windata->dfbwin->UngrabKeyboard(windata->dfbwin));
404 devdata->grabbed_window = NULL;
405 }
406}
407
408void
410{
413 DFB_WindowData *p;
414
415 /* Some cleanups */
416 SDL_DFB_CHECK(windata->dfbwin->UngrabPointer(windata->dfbwin));
417 SDL_DFB_CHECK(windata->dfbwin->UngrabKeyboard(windata->dfbwin));
418
419#if SDL_DIRECTFB_OPENGL
420 DirectFB_GL_DestroyWindowContexts(_this, window);
421#endif
422
423 if (window->shaper)
424 {
425 SDL_ShapeData *data = window->shaper->driverdata;
426 SDL_DFB_CHECK(data->surface->ReleaseSource(data->surface));
427 SDL_DFB_RELEASE(data->surface);
429 SDL_DFB_FREE(window->shaper);
430 }
431
432 SDL_DFB_CHECK(windata->window_surface->SetFont(windata->window_surface, NULL));
433 SDL_DFB_CHECK(windata->surface->ReleaseSource(windata->surface));
434 SDL_DFB_CHECK(windata->window_surface->ReleaseSource(windata->window_surface));
435 SDL_DFB_RELEASE(windata->icon);
436 SDL_DFB_RELEASE(windata->font);
437 SDL_DFB_RELEASE(windata->eventbuffer);
438 SDL_DFB_RELEASE(windata->surface);
439 SDL_DFB_RELEASE(windata->window_surface);
440
441 SDL_DFB_RELEASE(windata->dfbwin);
442
443 /* Remove from list ... */
444
445 p = devdata->firstwin->driverdata;
446
447 while (p && p->next != window)
448 p = (p->next ? p->next->driverdata : NULL);
449 if (p)
450 p->next = windata->next;
451 else
452 devdata->firstwin = windata->next;
453 SDL_free(windata);
454 return;
455}
456
459 struct SDL_SysWMinfo * info)
460{
461 const Uint32 version = ((((Uint32) info->version.major) * 1000000) +
462 (((Uint32) info->version.minor) * 10000) +
463 (((Uint32) info->version.patch)));
464
467
468 /* Before 2.0.6, it was possible to build an SDL with DirectFB support
469 (SDL_SysWMinfo will be large enough to hold DirectFB info), but build
470 your app against SDL headers that didn't have DirectFB support
471 (SDL_SysWMinfo could be smaller than DirectFB needs. This would lead
472 to an app properly using SDL_GetWindowWMInfo() but we'd accidentally
473 overflow memory on the stack or heap. To protect against this, we've
474 padded out the struct unconditionally in the headers and DirectFB will
475 just return an error for older apps using this function. Those apps
476 will need to be recompiled against newer headers or not use DirectFB,
477 maybe by forcing SDL_VIDEODRIVER=x11. */
478 if (version < 2000006) {
480 SDL_SetError("Version must be 2.0.6 or newer");
481 return SDL_FALSE;
482 }
483
484 if (info->version.major == SDL_MAJOR_VERSION &&
487 info->info.dfb.dfb = devdata->dfb;
488 info->info.dfb.window = windata->dfbwin;
489 info->info.dfb.surface = windata->surface;
490 return SDL_TRUE;
491 } else {
492 SDL_SetError("Application not compiled with SDL %d.%d",
494 return SDL_FALSE;
495 }
496}
497
498void
500{
502 int adjust = windata->wm_needs_redraw;
503 int cw, ch;
504
506
507 SDL_DFB_CHECKERR(windata->
508 window_surface->GetSize(windata->window_surface, &cw,
509 &ch));
510 if (cw != windata->size.w || ch != windata->size.h) {
511 adjust = 1;
512 }
513
514 if (adjust) {
515#if SDL_DIRECTFB_OPENGL
516 DirectFB_GL_FreeWindowContexts(SDL_GetVideoDevice(), window);
517#endif
518
519#if (DFB_VERSION_ATLEAST(1,2,1))
520 SDL_DFB_CHECKERR(windata->dfbwin->ResizeSurface(windata->dfbwin,
521 windata->size.w,
522 windata->size.h));
523 SDL_DFB_CHECKERR(windata->surface->MakeSubSurface(windata->surface,
524 windata->
525 window_surface,
526 &windata->client));
527#else
528 DFBWindowOptions opts;
529
530 SDL_DFB_CHECKERR(windata->dfbwin->GetOptions(windata->dfbwin, &opts));
531 /* recreate subsurface */
532 SDL_DFB_RELEASE(windata->surface);
533
534 if (opts & DWOP_SCALE)
535 SDL_DFB_CHECKERR(windata->dfbwin->ResizeSurface(windata->dfbwin,
536 windata->size.w,
537 windata->size.h));
538 SDL_DFB_CHECKERR(windata->window_surface->
539 GetSubSurface(windata->window_surface,
540 &windata->client, &windata->surface));
541#endif
543
544#if SDL_DIRECTFB_OPENGL
545 DirectFB_GL_ReAllocWindowContexts(SDL_GetVideoDevice(), window);
546#endif
547 }
548 error:
549 return;
550}
551
552int
554{
555 const Uint8 alpha = (Uint8) ((unsigned int) (opacity * 255.0f));
557 SDL_DFB_CHECKERR(windata->dfbwin->SetOpacity(windata->dfbwin, alpha));
558 windata->opacity = alpha;
559 return 0;
560
561error:
562 return -1;
563}
564
565#endif /* SDL_VIDEO_DRIVER_DIRECTFB */
void DirectFB_WM_RedrawLayout(_THIS, SDL_Window *window)
void DirectFB_WM_AdjustWindowLayout(SDL_Window *window, int flags, int w, int h)
DFBResult DirectFB_WM_GetClientSize(_THIS, SDL_Window *window, int *cw, int *ch)
#define SDL_DFB_DISPLAYDATA(win)
int DirectFB_ResizeWindowShape(SDL_Window *window)
#define SDL_DFB_CHECKERR(x...)
#define SDL_DFB_FREE(x)
#define SDL_DFB_ALLOC_CLEAR(r, s)
#define SDL_DFB_CHECK(x...)
#define SDL_DFB_DEVICEDATA(dev)
#define SDL_DFB_RELEASE(x)
void DirectFB_DestroyWindow(_THIS, SDL_Window *window)
void DirectFB_SetWindowPosition(_THIS, SDL_Window *window)
void DirectFB_SetWindowGrab(_THIS, SDL_Window *window, SDL_bool grabbed)
void DirectFB_ShowWindow(_THIS, SDL_Window *window)
void DirectFB_MinimizeWindow(_THIS, SDL_Window *window)
void DirectFB_SetWindowTitle(_THIS, SDL_Window *window)
void DirectFB_SetWindowSize(_THIS, SDL_Window *window)
void DirectFB_SetWindowIcon(_THIS, SDL_Window *window, SDL_Surface *icon)
void DirectFB_RestoreWindow(_THIS, SDL_Window *window)
int DirectFB_CreateWindow(_THIS, SDL_Window *window)
int DirectFB_CreateWindowFrom(_THIS, SDL_Window *window, const void *data)
#define SDL_DFB_WINDOWDATA(win)
void DirectFB_HideWindow(_THIS, SDL_Window *window)
SDL_bool DirectFB_GetWindowWMInfo(_THIS, SDL_Window *window, struct SDL_SysWMinfo *info)
void DirectFB_AdjustWindowSurface(SDL_Window *window)
int DirectFB_SetWindowOpacity(_THIS, SDL_Window *window, float opacity)
void DirectFB_MaximizeWindow(_THIS, SDL_Window *window)
void DirectFB_RaiseWindow(_THIS, SDL_Window *window)
#define _THIS
#define SDL_SetError
#define SDL_memset
#define SDL_free
#define SDL_IsShapedWindow
#define SDL_FreeSurface
#define SDL_ConvertSurface
#define SDL_Unsupported()
Definition: SDL_error.h:53
#define memcpy
Definition: SDL_malloc.c:630
GLint GLint GLint GLint GLint GLint y
Definition: SDL_opengl.h:1574
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1974
GLint GLint GLint GLint GLint x
Definition: SDL_opengl.h:1574
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: SDL_opengl.h:1572
GLfloat GLfloat p
GLfloat GLfloat GLfloat alpha
int SDL_InitFormat(SDL_PixelFormat *format, Uint32 pixel_format)
Definition: SDL_pixels.c:537
@ SDL_PIXELFORMAT_ARGB8888
Definition: SDL_pixels.h:248
SDL_bool
Definition: SDL_stdinc.h:162
@ SDL_TRUE
Definition: SDL_stdinc.h:164
@ SDL_FALSE
Definition: SDL_stdinc.h:163
uint32_t Uint32
Definition: SDL_stdinc.h:203
uint8_t Uint8
Definition: SDL_stdinc.h:179
SDL_VideoDisplay * SDL_GetDisplayForWindow(SDL_Window *window)
Definition: SDL_video.c:1089
SDL_VideoDevice * SDL_GetVideoDevice(void)
Definition: SDL_video.c:583
@ SDL_SYSWM_DIRECTFB
Definition: SDL_syswm.h:124
@ SDL_SYSWM_UNKNOWN
Definition: SDL_syswm.h:121
#define SDL_MINOR_VERSION
Definition: SDL_version.h:61
#define SDL_MAJOR_VERSION
Definition: SDL_version.h:60
static SDL_VideoDevice * _this
Definition: SDL_video.c:118
@ SDL_WINDOW_OPENGL
Definition: SDL_video.h:101
@ SDL_WINDOW_MINIMIZED
Definition: SDL_video.h:106
@ SDL_WINDOW_INPUT_GRABBED
Definition: SDL_video.h:108
@ SDL_WINDOW_RESIZABLE
Definition: SDL_video.h:105
@ SDL_WINDOW_FULLSCREEN
Definition: SDL_video.h:100
@ SDL_WINDOW_MAXIMIZED
Definition: SDL_video.h:107
@ SDL_WINDOW_BORDERLESS
Definition: SDL_video.h:104
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
Definition: SDL_x11sym.h:50
#define NULL
Definition: begin_code.h:167
EGLSurface surface
Definition: eglext.h:248
EGLSurface EGLNativeWindowType * window
Definition: eglext.h:1025
A collection of pixels used in software blitting.
Definition: SDL_surface.h:71
union SDL_SysWMinfo::@17 info
struct wl_surface * surface
Definition: SDL_syswm.h:259
SDL_SYSWM_TYPE subsystem
Definition: SDL_syswm.h:200
Window window
Definition: SDL_syswm.h:221
SDL_version version
Definition: SDL_syswm.h:199
SDL_DisplayMode current_mode
Definition: SDL_sysvideo.h:132
The type used to identify a window.
Definition: SDL_sysvideo.h:74
Uint8 minor
Definition: SDL_version.h:54
Uint8 patch
Definition: SDL_version.h:55
Uint8 major
Definition: SDL_version.h:53