This repository has been archived by the owner on Feb 11, 2021. It is now read-only.
/
SDL_DirectFB_window.c
522 lines (423 loc) · 16.1 KB
1
/*
2
3
Simple DirectMedia Layer
Copyright (C) 1997-2011 Sam Lantinga <slouken@libsdl.org>
4
5
6
7
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
8
9
10
11
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
12
13
14
15
16
17
18
19
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
20
*/
21
22
#include "SDL_DirectFB_video.h"
23
24
25
26
#include "SDL_DirectFB_modes.h"
#include "SDL_DirectFB_window.h"
#include "SDL_DirectFB_shape.h"
27
28
29
#if SDL_DIRECTFB_OPENGL
#include "SDL_DirectFB_opengl.h"
#endif
30
31
32
33
#include "SDL_syswm.h"
#include "../SDL_pixels_c.h"
34
35
36
37
38
int
DirectFB_CreateWindow(_THIS, SDL_Window * window)
{
SDL_DFB_DEVICEDATA(_this);
39
SDL_DFB_DISPLAYDATA(window);
40
DFB_WindowData *windata = NULL;
41
42
DFBWindowOptions wopts;
DFBWindowDescription desc;
43
int x, y;
44
int bshaped = 0;
45
46
SDL_DFB_ALLOC_CLEAR(window->driverdata, sizeof(DFB_WindowData));
47
48
windata = (DFB_WindowData *) window->driverdata;
49
windata->is_managed = devdata->has_own_wm;
50
#if 1
51
52
53
54
SDL_DFB_CHECKERR(devdata->dfb->SetCooperativeLevel(devdata->dfb,
DFSCL_NORMAL));
SDL_DFB_CHECKERR(dispdata->layer->SetCooperativeLevel(dispdata->layer,
DLSCL_ADMINISTRATIVE));
55
56
57
58
59
#endif
/* FIXME ... ughh, ugly */
if (window->x == -1000 && window->y == -1000)
bshaped = 1;
60
/* Fill the window description. */
61
62
x = window->x;
y = window->y;
63
64
DirectFB_WM_AdjustWindowLayout(window, window->flags, window->w, window->h);
65
66
/* Create Window */
67
desc.caps = 0;
68
desc.flags =
69
70
71
72
73
74
75
76
77
78
79
80
81
82
DWDESC_WIDTH | DWDESC_HEIGHT | DWDESC_POSX | DWDESC_POSY | DWDESC_SURFACE_CAPS;
if (bshaped) {
desc.flags |= DWDESC_CAPS;
desc.caps |= DWCAPS_ALPHACHANNEL;
}
else
{
desc.flags |= DWDESC_PIXELFORMAT;
}
if (!(window->flags & SDL_WINDOW_BORDERLESS))
desc.caps |= DWCAPS_NODECORATION;
83
84
desc.posx = x;
desc.posy = y;
85
86
desc.width = windata->size.w;
desc.height = windata->size.h;
87
88
desc.pixelformat = dispdata->pixelformat;
desc.surface_caps = DSCAPS_PREMULTIPLIED;
89
90
/* Create the window. */
91
SDL_DFB_CHECKERR(dispdata->layer->CreateWindow(dispdata->layer, &desc,
92
&windata->dfbwin));
93
94
/* Set Options */
95
SDL_DFB_CHECK(windata->dfbwin->GetOptions(windata->dfbwin, &wopts));
96
97
98
99
100
101
102
/* explicit rescaling of surface */
wopts |= DWOP_SCALE;
if (window->flags & SDL_WINDOW_RESIZABLE) {
wopts &= ~DWOP_KEEP_SIZE;
}
else {
103
wopts |= DWOP_KEEP_SIZE;
104
}
105
106
if (window->flags & SDL_WINDOW_FULLSCREEN) {
107
wopts |= DWOP_KEEP_POSITION | DWOP_KEEP_STACKING | DWOP_KEEP_SIZE;
108
109
110
111
112
113
SDL_DFB_CHECK(windata->dfbwin->SetStackingClass(windata->dfbwin, DWSC_UPPER));
}
if (bshaped) {
wopts |= DWOP_SHAPED | DWOP_ALPHACHANNEL;
wopts &= ~DWOP_OPAQUE_REGION;
114
}
115
116
SDL_DFB_CHECK(windata->dfbwin->SetOptions(windata->dfbwin, wopts));
117
118
/* See what we got */
119
SDL_DFB_CHECK(DirectFB_WM_GetClientSize
120
(_this, window, &window->w, &window->h));
121
122
/* Get the window's surface. */
123
SDL_DFB_CHECKERR(windata->dfbwin->GetSurface(windata->dfbwin,
124
&windata->window_surface));
125
126
127
128
129
130
/* And get a subsurface for rendering */
SDL_DFB_CHECKERR(windata->window_surface->
GetSubSurface(windata->window_surface, &windata->client,
&windata->surface));
131
SDL_DFB_CHECK(windata->dfbwin->SetOpacity(windata->dfbwin, 0xFF));
132
133
/* Create Eventbuffer */
134
135
SDL_DFB_CHECKERR(windata->dfbwin->CreateEventBuffer(windata->dfbwin,
136
137
&windata->
eventbuffer));
138
139
SDL_DFB_CHECKERR(windata->dfbwin->
EnableEvents(windata->dfbwin, DWET_ALL));
140
141
142
/* Create a font */
/* FIXME: once during Video_Init */
143
windata->font = NULL;
144
145
/* Make it the top most window. */
146
SDL_DFB_CHECK(windata->dfbwin->RaiseToTop(windata->dfbwin));
147
148
/* remember parent */
149
//windata->sdlwin = window;
150
151
152
153
154
/* Add to list ... */
windata->next = devdata->firstwin;
windata->opacity = 0xFF;
155
devdata->firstwin = window;
156
157
/* Draw Frame */
158
DirectFB_WM_RedrawLayout(_this, window);
159
160
161
return 0;
error:
162
163
SDL_DFB_RELEASE(windata->surface);
SDL_DFB_RELEASE(windata->dfbwin);
164
165
166
167
168
169
170
171
172
173
174
175
176
return -1;
}
int
DirectFB_CreateWindowFrom(_THIS, SDL_Window * window, const void *data)
{
SDL_Unsupported();
return -1;
}
void
DirectFB_SetWindowTitle(_THIS, SDL_Window * window)
{
177
178
179
180
SDL_DFB_WINDOWDATA(window);
if (windata->is_managed) {
windata->wm_needs_redraw = 1;
181
DirectFB_WM_RedrawLayout(_this, window);
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
} else
SDL_Unsupported();
}
void
DirectFB_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon)
{
SDL_DFB_DEVICEDATA(_this);
SDL_DFB_WINDOWDATA(window);
SDL_Surface *surface = NULL;
if (icon) {
SDL_PixelFormat format;
DFBSurfaceDescription dsc;
Uint32 *dest;
Uint32 *p;
int pitch, i;
/* Convert the icon to ARGB for modern window managers */
201
SDL_InitFormat(&format, SDL_PIXELFORMAT_ARGB8888);
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
surface = SDL_ConvertSurface(icon, &format, 0);
if (!surface) {
return;
}
dsc.flags =
DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS;
dsc.caps = DSCAPS_VIDEOONLY;
dsc.width = surface->w;
dsc.height = surface->h;
dsc.pixelformat = DSPF_ARGB;
SDL_DFB_CHECKERR(devdata->dfb->CreateSurface(devdata->dfb, &dsc,
&windata->icon));
SDL_DFB_CHECKERR(windata->icon->Lock(windata->icon, DSLF_WRITE,
(void *) &dest, &pitch));
p = surface->pixels;
for (i = 0; i < surface->h; i++)
memcpy((char *) dest + i * pitch,
(char *) p + i * surface->pitch, 4 * surface->w);
224
SDL_DFB_CHECK(windata->icon->Unlock(windata->icon));
225
226
227
228
229
230
231
232
233
234
SDL_FreeSurface(surface);
} else {
SDL_DFB_RELEASE(windata->icon);
}
return;
error:
if (surface)
SDL_FreeSurface(surface);
SDL_DFB_RELEASE(windata->icon);
return;
235
236
237
238
239
240
241
242
}
void
DirectFB_SetWindowPosition(_THIS, SDL_Window * window)
{
SDL_DFB_WINDOWDATA(window);
int x, y;
243
244
x = window->x;
y = window->y;
245
246
DirectFB_WM_AdjustWindowLayout(window, window->flags, window->w, window->h);
247
SDL_DFB_CHECK(windata->dfbwin->MoveTo(windata->dfbwin, x, y));
248
249
250
251
252
253
254
}
void
DirectFB_SetWindowSize(_THIS, SDL_Window * window)
{
SDL_DFB_WINDOWDATA(window);
255
256
257
if(SDL_IsShapedWindow(window))
DirectFB_ResizeWindowShape(window);
258
259
260
261
262
if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
int cw;
int ch;
/* Make sure all events are disabled for this operation ! */
263
SDL_DFB_CHECKERR(windata->dfbwin->DisableEvents(windata->dfbwin,
264
265
266
267
268
DWET_ALL));
SDL_DFB_CHECKERR(DirectFB_WM_GetClientSize(_this, window, &cw, &ch));
if (cw != window->w || ch != window->h) {
269
DirectFB_WM_AdjustWindowLayout(window, window->flags, window->w, window->h);
270
SDL_DFB_CHECKERR(windata->dfbwin->Resize(windata->dfbwin,
271
272
273
274
windata->size.w,
windata->size.h));
}
275
276
SDL_DFB_CHECKERR(DirectFB_WM_GetClientSize
(_this, window, &window->w, &window->h));
277
DirectFB_AdjustWindowSurface(window);
278
279
SDL_DFB_CHECKERR(windata->dfbwin->EnableEvents(windata->dfbwin,
280
281
DWET_ALL));
282
283
284
}
return;
error:
285
SDL_DFB_CHECK(windata->dfbwin->EnableEvents(windata->dfbwin, DWET_ALL));
286
287
288
289
290
291
292
293
return;
}
void
DirectFB_ShowWindow(_THIS, SDL_Window * window)
{
SDL_DFB_WINDOWDATA(window);
294
SDL_DFB_CHECK(windata->dfbwin->SetOpacity(windata->dfbwin, windata->opacity));
295
296
297
298
299
300
301
302
}
void
DirectFB_HideWindow(_THIS, SDL_Window * window)
{
SDL_DFB_WINDOWDATA(window);
303
304
SDL_DFB_CHECK(windata->dfbwin->GetOpacity(windata->dfbwin, &windata->opacity));
SDL_DFB_CHECK(windata->dfbwin->SetOpacity(windata->dfbwin, 0));
305
306
307
308
309
310
311
}
void
DirectFB_RaiseWindow(_THIS, SDL_Window * window)
{
SDL_DFB_WINDOWDATA(window);
312
313
SDL_DFB_CHECK(windata->dfbwin->RaiseToTop(windata->dfbwin));
SDL_DFB_CHECK(windata->dfbwin->RequestFocus(windata->dfbwin));
314
315
316
317
318
}
void
DirectFB_MaximizeWindow(_THIS, SDL_Window * window)
{
319
SDL_DFB_WINDOWDATA(window);
320
SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
321
DFBWindowOptions wopts;
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
SDL_DFB_CHECK(windata->dfbwin->GetPosition(windata->dfbwin,
&windata->restore.x, &windata->restore.y));
SDL_DFB_CHECK(windata->dfbwin->GetSize(windata->dfbwin, &windata->restore.w,
&windata->restore.h));
DirectFB_WM_AdjustWindowLayout(window, window->flags | SDL_WINDOW_MAXIMIZED, display->current_mode.w, display->current_mode.h) ;
SDL_DFB_CHECK(windata->dfbwin->MoveTo(windata->dfbwin, 0, 0));
SDL_DFB_CHECK(windata->dfbwin->Resize(windata->dfbwin,
display->current_mode.w, display->current_mode.h));
/* Set Options */
SDL_DFB_CHECK(windata->dfbwin->GetOptions(windata->dfbwin, &wopts));
wopts |= DWOP_KEEP_SIZE | DWOP_KEEP_POSITION;
SDL_DFB_CHECK(windata->dfbwin->SetOptions(windata->dfbwin, wopts));
338
339
340
341
342
343
344
345
346
347
348
349
350
}
void
DirectFB_MinimizeWindow(_THIS, SDL_Window * window)
{
/* FIXME: Size to 32x32 ? */
SDL_Unsupported();
}
void
DirectFB_RestoreWindow(_THIS, SDL_Window * window)
{
351
SDL_DFB_WINDOWDATA(window);
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
DFBWindowOptions wopts;
/* Set Options */
SDL_DFB_CHECK(windata->dfbwin->GetOptions(windata->dfbwin, &wopts));
wopts &= ~(DWOP_KEEP_SIZE | DWOP_KEEP_POSITION);
SDL_DFB_CHECK(windata->dfbwin->SetOptions(windata->dfbwin, wopts));
/* Window layout */
DirectFB_WM_AdjustWindowLayout(window, window->flags & ~(SDL_WINDOW_MAXIMIZED | SDL_WINDOW_MINIMIZED),
windata->restore.w, windata->restore.h);
SDL_DFB_CHECK(windata->dfbwin->Resize(windata->dfbwin, windata->restore.w,
windata->restore.h));
SDL_DFB_CHECK(windata->dfbwin->MoveTo(windata->dfbwin, windata->restore.x,
windata->restore.y));
if (!(window->flags & SDL_WINDOW_RESIZABLE))
wopts |= DWOP_KEEP_SIZE;
if (window->flags & SDL_WINDOW_FULLSCREEN)
wopts |= DWOP_KEEP_POSITION | DWOP_KEEP_SIZE;
SDL_DFB_CHECK(windata->dfbwin->SetOptions(windata->dfbwin, wopts));
374
375
376
377
378
379
}
void
DirectFB_SetWindowGrab(_THIS, SDL_Window * window)
{
380
SDL_DFB_DEVICEDATA(_this);
381
SDL_DFB_WINDOWDATA(window);
382
DFB_WindowData *gwindata = ((devdata->grabbed_window) ? (DFB_WindowData *) ((devdata->grabbed_window)->driverdata) : NULL);
383
384
if ((window->flags & SDL_WINDOW_INPUT_GRABBED)) {
385
386
if (gwindata != NULL)
{
387
388
SDL_DFB_CHECK(gwindata->dfbwin->UngrabPointer(gwindata->dfbwin));
SDL_DFB_CHECK(gwindata->dfbwin->UngrabKeyboard(gwindata->dfbwin));
389
}
390
391
SDL_DFB_CHECK(windata->dfbwin->GrabPointer(windata->dfbwin));
SDL_DFB_CHECK(windata->dfbwin->GrabKeyboard(windata->dfbwin));
392
devdata->grabbed_window = window;
393
} else {
394
395
SDL_DFB_CHECK(windata->dfbwin->UngrabPointer(windata->dfbwin));
SDL_DFB_CHECK(windata->dfbwin->UngrabKeyboard(windata->dfbwin));
396
devdata->grabbed_window = NULL;
397
398
399
400
401
402
403
404
405
406
}
}
void
DirectFB_DestroyWindow(_THIS, SDL_Window * window)
{
SDL_DFB_DEVICEDATA(_this);
SDL_DFB_WINDOWDATA(window);
DFB_WindowData *p;
407
/* Some cleanups */
408
409
SDL_DFB_CHECK(windata->dfbwin->UngrabPointer(windata->dfbwin));
SDL_DFB_CHECK(windata->dfbwin->UngrabKeyboard(windata->dfbwin));
410
411
412
413
414
#if SDL_DIRECTFB_OPENGL
DirectFB_GL_DestroyWindowContexts(_this, window);
#endif
415
416
417
418
419
420
421
422
423
if (window->shaper)
{
SDL_ShapeData *data = window->shaper->driverdata;
SDL_DFB_CHECK(data->surface->ReleaseSource(data->surface));
SDL_DFB_RELEASE(data->surface);
SDL_DFB_FREE(data);
SDL_DFB_FREE(window->shaper);
}
424
425
426
427
428
SDL_DFB_CHECK(windata->window_surface->SetFont(windata->window_surface, NULL));
SDL_DFB_CHECK(windata->surface->ReleaseSource(windata->surface));
SDL_DFB_CHECK(windata->window_surface->ReleaseSource(windata->window_surface));
SDL_DFB_RELEASE(windata->icon);
SDL_DFB_RELEASE(windata->font);
429
430
SDL_DFB_RELEASE(windata->eventbuffer);
SDL_DFB_RELEASE(windata->surface);
431
432
SDL_DFB_RELEASE(windata->window_surface);
433
SDL_DFB_RELEASE(windata->dfbwin);
434
435
436
/* Remove from list ... */
437
438
439
440
p = devdata->firstwin->driverdata;
while (p && p->next != window)
p = (p->next ? p->next->driverdata : NULL);
441
442
443
444
445
446
447
448
449
450
451
452
if (p)
p->next = windata->next;
else
devdata->firstwin = windata->next;
SDL_free(windata);
return;
}
SDL_bool
DirectFB_GetWindowWMInfo(_THIS, SDL_Window * window,
struct SDL_SysWMinfo * info)
{
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
SDL_DFB_DEVICEDATA(_this);
SDL_DFB_WINDOWDATA(window);
if (info->version.major == SDL_MAJOR_VERSION &&
info->version.minor == SDL_MINOR_VERSION) {
info->subsystem = SDL_SYSWM_DIRECTFB;
info->info.dfb.dfb = devdata->dfb;
info->info.dfb.window = windata->dfbwin;
info->info.dfb.surface = windata->surface;
return SDL_TRUE;
} else {
SDL_SetError("Application not compiled with SDL %d.%d\n",
SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
return SDL_FALSE;
}
468
}
469
470
471
void
DirectFB_AdjustWindowSurface(SDL_Window * window)
472
473
474
475
476
{
SDL_DFB_WINDOWDATA(window);
int adjust = windata->wm_needs_redraw;
int cw, ch;
477
DirectFB_WM_AdjustWindowLayout(window, window->flags, window->w, window->h);
478
479
480
481
482
483
484
485
486
SDL_DFB_CHECKERR(windata->
window_surface->GetSize(windata->window_surface, &cw,
&ch));
if (cw != windata->size.w || ch != windata->size.h) {
adjust = 1;
}
if (adjust) {
487
#if SDL_DIRECTFB_OPENGL
488
DirectFB_GL_FreeWindowContexts(SDL_GetVideoDevice(), window);
489
490
#endif
491
492
#if (DFB_VERSION_ATLEAST(1,2,1))
SDL_DFB_CHECKERR(windata->dfbwin->ResizeSurface(windata->dfbwin,
493
494
windata->size.w,
windata->size.h));
495
SDL_DFB_CHECKERR(windata->surface->MakeSubSurface(windata->surface,
496
497
498
windata->
window_surface,
&windata->client));
499
#else
500
501
DFBWindowOptions opts;
502
SDL_DFB_CHECKERR(windata->dfbwin->GetOptions(windata->dfbwin, &opts));
503
504
505
506
/* recreate subsurface */
SDL_DFB_RELEASE(windata->surface);
if (opts & DWOP_SCALE)
507
SDL_DFB_CHECKERR(windata->dfbwin->ResizeSurface(windata->dfbwin,
508
509
510
511
512
windata->size.w,
windata->size.h));
SDL_DFB_CHECKERR(windata->window_surface->
GetSubSurface(windata->window_surface,
&windata->client, &windata->surface));
513
#endif
514
DirectFB_WM_RedrawLayout(SDL_GetVideoDevice(), window);
515
516
#if SDL_DIRECTFB_OPENGL
517
DirectFB_GL_ReAllocWindowContexts(SDL_GetVideoDevice(), window);
518
519
#endif
}
520
521
522
error:
return;
}