SDL  2.0
SDL_DirectFB_WM.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2018 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_window.h"
27 
28 #include "../../events/SDL_windowevents_c.h"
29 
30 #define COLOR_EXPAND(col) col.r, col.g, col.b, col.a
31 
32 static DFB_Theme theme_std = {
33  4, 4, 8, 8,
34  {255, 200, 200, 200},
35  24,
36  {255, 0, 0, 255},
37  16,
38  {255, 255, 255, 255},
39  "/usr/share/fonts/truetype/freefont/FreeSans.ttf",
40  {255, 255, 0, 0},
41  {255, 255, 255, 0},
42 };
43 
44 static DFB_Theme theme_none = {
45  0, 0, 0, 0,
46  {0, 0, 0, 0},
47  0,
48  {0, 0, 0, 0},
49  0,
50  {0, 0, 0, 0},
51  NULL
52 };
53 
54 static void
55 DrawTriangle(IDirectFBSurface * s, int down, int x, int y, int w)
56 {
57  int x1, x2, x3;
58  int y1, y2, y3;
59 
60  if (down) {
61  x1 = x + w / 2;
62  x2 = x;
63  x3 = x + w;
64  y1 = y + w;
65  y2 = y;
66  y3 = y;
67  } else {
68  x1 = x + w / 2;
69  x2 = x;
70  x3 = x + w;
71  y1 = y;
72  y2 = y + w;
73  y3 = y + w;
74  }
75  s->FillTriangle(s, x1, y1, x2, y2, x3, y3);
76 }
77 
78 static void
79 LoadFont(_THIS, SDL_Window * window)
80 {
82  SDL_DFB_WINDOWDATA(window);
83 
84  if (windata->font != NULL) {
85  SDL_DFB_RELEASE(windata->font);
86  windata->font = NULL;
87  SDL_DFB_CHECK(windata->window_surface->SetFont(windata->window_surface, windata->font));
88  }
89 
90  if (windata->theme.font != NULL)
91  {
92  DFBFontDescription fdesc;
93 
94  SDL_zero(fdesc);
95  fdesc.flags = DFDESC_HEIGHT;
96  fdesc.height = windata->theme.font_size;
97  SDL_DFB_CHECK(devdata->
98  dfb->CreateFont(devdata->dfb, windata->theme.font,
99  &fdesc, &windata->font));
100  SDL_DFB_CHECK(windata->window_surface->SetFont(windata->window_surface, windata->font));
101  }
102 }
103 
104 static void
105 DrawCraption(_THIS, IDirectFBSurface * s, int x, int y, char *text)
106 {
107  DFBSurfaceTextFlags flags;
108 
109  flags = DSTF_CENTER | DSTF_TOP;
110 
111  s->DrawString(s, text, -1, x, y, flags);
112 }
113 
114 void
116 {
117  SDL_DFB_WINDOWDATA(window);
118  IDirectFBSurface *s = windata->window_surface;
119  DFB_Theme *t = &windata->theme;
120  int i;
121  int d = (t->caption_size - t->font_size) / 2;
122  int x, y, w;
123 
124 
125  if (!windata->is_managed || (window->flags & SDL_WINDOW_FULLSCREEN))
126  return;
127 
128  SDL_DFB_CHECK(s->SetSrcBlendFunction(s, DSBF_ONE));
129  SDL_DFB_CHECK(s->SetDstBlendFunction(s, DSBF_ZERO));
130  SDL_DFB_CHECK(s->SetDrawingFlags(s, DSDRAW_NOFX));
131  SDL_DFB_CHECK(s->SetBlittingFlags(s, DSBLIT_NOFX));
132 
133  LoadFont(_this, window);
134  /* s->SetDrawingFlags(s, DSDRAW_BLEND); */
135  s->SetColor(s, COLOR_EXPAND(t->frame_color));
136  /* top */
137  for (i = 0; i < t->top_size; i++)
138  s->DrawLine(s, 0, i, windata->size.w, i);
139  /* bottom */
140  for (i = windata->size.h - t->bottom_size; i < windata->size.h; i++)
141  s->DrawLine(s, 0, i, windata->size.w, i);
142  /* left */
143  for (i = 0; i < t->left_size; i++)
144  s->DrawLine(s, i, 0, i, windata->size.h);
145  /* right */
146  for (i = windata->size.w - t->right_size; i < windata->size.w; i++)
147  s->DrawLine(s, i, 0, i, windata->size.h);
148  /* Caption */
149  s->SetColor(s, COLOR_EXPAND(t->caption_color));
150  s->FillRectangle(s, t->left_size, t->top_size, windata->client.w,
151  t->caption_size);
152  /* Close Button */
153  w = t->caption_size;
154  x = windata->size.w - t->right_size - w + d;
155  y = t->top_size + d;
156  s->SetColor(s, COLOR_EXPAND(t->close_color));
157  DrawTriangle(s, 1, x, y, w - 2 * d);
158  /* Max Button */
159  s->SetColor(s, COLOR_EXPAND(t->max_color));
160  DrawTriangle(s, window->flags & SDL_WINDOW_MAXIMIZED ? 1 : 0, x - w,
161  y, w - 2 * d);
162 
163  /* Caption */
164  if (*window->title) {
165  s->SetColor(s, COLOR_EXPAND(t->font_color));
166  DrawCraption(_this, s, (x - w) / 2, t->top_size + d, window->title);
167  }
168  /* Icon */
169  if (windata->icon) {
170  DFBRectangle dr;
171 
172  dr.x = t->left_size + d;
173  dr.y = t->top_size + d;
174  dr.w = w - 2 * d;
175  dr.h = w - 2 * d;
176  s->SetBlittingFlags(s, DSBLIT_BLEND_ALPHACHANNEL);
177 
178  s->StretchBlit(s, windata->icon, NULL, &dr);
179  }
180  windata->wm_needs_redraw = 0;
181 }
182 
183 DFBResult
184 DirectFB_WM_GetClientSize(_THIS, SDL_Window * window, int *cw, int *ch)
185 {
186  SDL_DFB_WINDOWDATA(window);
187  IDirectFBWindow *dfbwin = windata->dfbwin;
188 
189  SDL_DFB_CHECK(dfbwin->GetSize(dfbwin, cw, ch));
190  dfbwin->GetSize(dfbwin, cw, ch);
191  *cw -= windata->theme.left_size + windata->theme.right_size;
192  *ch -=
193  windata->theme.top_size + windata->theme.caption_size +
194  windata->theme.bottom_size;
195  return DFB_OK;
196 }
197 
198 void
199 DirectFB_WM_AdjustWindowLayout(SDL_Window * window, int flags, int w, int h)
200 {
201  SDL_DFB_WINDOWDATA(window);
202 
203  if (!windata->is_managed)
204  windata->theme = theme_none;
205  else if (flags & SDL_WINDOW_BORDERLESS)
206  /* desc.caps |= DWCAPS_NODECORATION;) */
207  windata->theme = theme_none;
208  else if (flags & SDL_WINDOW_FULLSCREEN) {
209  windata->theme = theme_none;
210  } else if (flags & SDL_WINDOW_MAXIMIZED) {
211  windata->theme = theme_std;
212  windata->theme.left_size = 0;
213  windata->theme.right_size = 0;
214  windata->theme.top_size = 0;
215  windata->theme.bottom_size = 0;
216  } else {
217  windata->theme = theme_std;
218  }
219 
220  windata->client.x = windata->theme.left_size;
221  windata->client.y = windata->theme.top_size + windata->theme.caption_size;
222  windata->client.w = w;
223  windata->client.h = h;
224  windata->size.w =
225  w + windata->theme.left_size + windata->theme.right_size;
226  windata->size.h =
227  h + windata->theme.top_size +
228  windata->theme.caption_size + windata->theme.bottom_size;
229 }
230 
231 
232 enum
233 {
234  WM_POS_NONE = 0x00,
235  WM_POS_CAPTION = 0x01,
236  WM_POS_CLOSE = 0x02,
237  WM_POS_MAX = 0x04,
238  WM_POS_LEFT = 0x08,
239  WM_POS_RIGHT = 0x10,
240  WM_POS_TOP = 0x20,
241  WM_POS_BOTTOM = 0x40,
242 };
243 
244 static int
245 WMIsClient(DFB_WindowData * p, int x, int y)
246 {
247  x -= p->client.x;
248  y -= p->client.y;
249  if (x < 0 || y < 0)
250  return 0;
251  if (x >= p->client.w || y >= p->client.h)
252  return 0;
253  return 1;
254 }
255 
256 static int
257 WMPos(DFB_WindowData * p, int x, int y)
258 {
259  int pos = WM_POS_NONE;
260 
261  if (!WMIsClient(p, x, y)) {
262  if (y < p->theme.top_size) {
263  pos |= WM_POS_TOP;
264  } else if (y < p->client.y) {
265  if (x <
266  p->size.w - p->theme.right_size - 2 * p->theme.caption_size) {
267  pos |= WM_POS_CAPTION;
268  } else if (x <
269  p->size.w - p->theme.right_size -
270  p->theme.caption_size) {
271  pos |= WM_POS_MAX;
272  } else {
273  pos |= WM_POS_CLOSE;
274  }
275  } else if (y >= p->size.h - p->theme.bottom_size) {
276  pos |= WM_POS_BOTTOM;
277  }
278  if (x < p->theme.left_size) {
279  pos |= WM_POS_LEFT;
280  } else if (x >= p->size.w - p->theme.right_size) {
281  pos |= WM_POS_RIGHT;
282  }
283  }
284  return pos;
285 }
286 
287 int
288 DirectFB_WM_ProcessEvent(_THIS, SDL_Window * window, DFBWindowEvent * evt)
289 {
291  SDL_DFB_WINDOWDATA(window);
292  DFB_WindowData *gwindata = ((devdata->grabbed_window) ? (DFB_WindowData *) ((devdata->grabbed_window)->driverdata) : NULL);
293  IDirectFBWindow *dfbwin = windata->dfbwin;
294  DFBWindowOptions wopts;
295 
296  if (!windata->is_managed)
297  return 0;
298 
299  SDL_DFB_CHECK(dfbwin->GetOptions(dfbwin, &wopts));
300 
301  switch (evt->type) {
302  case DWET_BUTTONDOWN:
303  if (evt->buttons & DIBM_LEFT) {
304  int pos = WMPos(windata, evt->x, evt->y);
305  switch (pos) {
306  case WM_POS_NONE:
307  return 0;
308  case WM_POS_CLOSE:
309  windata->wm_grab = WM_POS_NONE;
311  0);
312  return 1;
313  case WM_POS_MAX:
314  windata->wm_grab = WM_POS_NONE;
315  if (window->flags & SDL_WINDOW_MAXIMIZED) {
316  SDL_RestoreWindow(window);
317  } else {
318  SDL_MaximizeWindow(window);
319  }
320  return 1;
321  case WM_POS_CAPTION:
322  if (!(wopts & DWOP_KEEP_STACKING)) {
323  DirectFB_RaiseWindow(_this, window);
324  }
325  if (window->flags & SDL_WINDOW_MAXIMIZED)
326  return 1;
327  /* fall through */
328  default:
329  windata->wm_grab = pos;
330  if (gwindata != NULL)
331  SDL_DFB_CHECK(gwindata->dfbwin->UngrabPointer(gwindata->dfbwin));
332  SDL_DFB_CHECK(dfbwin->GrabPointer(dfbwin));
333  windata->wm_lastx = evt->cx;
334  windata->wm_lasty = evt->cy;
335  }
336  }
337  return 1;
338  case DWET_BUTTONUP:
339  if (!windata->wm_grab)
340  return 0;
341  if (!(evt->buttons & DIBM_LEFT)) {
342  if (windata->wm_grab & (WM_POS_RIGHT | WM_POS_BOTTOM)) {
343  int dx = evt->cx - windata->wm_lastx;
344  int dy = evt->cy - windata->wm_lasty;
345 
346  if (!(wopts & DWOP_KEEP_SIZE)) {
347  int cw, ch;
348  if ((windata->wm_grab & (WM_POS_BOTTOM | WM_POS_RIGHT)) == WM_POS_BOTTOM)
349  dx = 0;
350  else if ((windata->wm_grab & (WM_POS_BOTTOM | WM_POS_RIGHT)) == WM_POS_RIGHT)
351  dy = 0;
352  SDL_DFB_CHECK(dfbwin->GetSize(dfbwin, &cw, &ch));
353 
354  /* necessary to trigger an event - ugly */
355  SDL_DFB_CHECK(dfbwin->DisableEvents(dfbwin, DWET_ALL));
356  SDL_DFB_CHECK(dfbwin->Resize(dfbwin, cw + dx + 1, ch + dy));
357  SDL_DFB_CHECK(dfbwin->EnableEvents(dfbwin, DWET_ALL));
358 
359  SDL_DFB_CHECK(dfbwin->Resize(dfbwin, cw + dx, ch + dy));
360  }
361  }
362  SDL_DFB_CHECK(dfbwin->UngrabPointer(dfbwin));
363  if (gwindata != NULL)
364  SDL_DFB_CHECK(gwindata->dfbwin->GrabPointer(gwindata->dfbwin));
365  windata->wm_grab = WM_POS_NONE;
366  return 1;
367  }
368  break;
369  case DWET_MOTION:
370  if (!windata->wm_grab)
371  return 0;
372  if (evt->buttons & DIBM_LEFT) {
373  int dx = evt->cx - windata->wm_lastx;
374  int dy = evt->cy - windata->wm_lasty;
375 
376  if (windata->wm_grab & WM_POS_CAPTION) {
377  if (!(wopts & DWOP_KEEP_POSITION))
378  SDL_DFB_CHECK(dfbwin->Move(dfbwin, dx, dy));
379  }
380  if (windata->wm_grab & (WM_POS_RIGHT | WM_POS_BOTTOM)) {
381  if (!(wopts & DWOP_KEEP_SIZE)) {
382  int cw, ch;
383 
384  /* Make sure all events are disabled for this operation ! */
385  SDL_DFB_CHECK(dfbwin->DisableEvents(dfbwin, DWET_ALL));
386 
387  if ((windata->wm_grab & (WM_POS_BOTTOM | WM_POS_RIGHT)) == WM_POS_BOTTOM)
388  dx = 0;
389  else if ((windata->wm_grab & (WM_POS_BOTTOM | WM_POS_RIGHT)) == WM_POS_RIGHT)
390  dy = 0;
391 
392  SDL_DFB_CHECK(dfbwin->GetSize(dfbwin, &cw, &ch));
393  SDL_DFB_CHECK(dfbwin->Resize(dfbwin, cw + dx, ch + dy));
394 
395  SDL_DFB_CHECK(dfbwin->EnableEvents(dfbwin, DWET_ALL));
396  }
397  }
398  windata->wm_lastx = evt->cx;
399  windata->wm_lasty = evt->cy;
400  return 1;
401  }
402  break;
403  case DWET_KEYDOWN:
404  break;
405  case DWET_KEYUP:
406  break;
407  default:
408  ;
409  }
410  return 0;
411 }
412 
413 #endif /* SDL_VIDEO_DRIVER_DIRECTFB */
GLuint GLfloat GLfloat GLfloat x1
GLdouble s
Definition: SDL_opengl.h:2063
int DirectFB_WM_ProcessEvent(_THIS, SDL_Window *window, DFBWindowEvent *evt)
GLint GLint GLint GLint GLint x
Definition: SDL_opengl.h:1574
GLfloat GLfloat GLfloat GLfloat h
GLfixed GLfixed GLfixed y2
GLfloat GLfloat p
void DirectFB_RaiseWindow(_THIS, SDL_Window *window)
void DirectFB_WM_AdjustWindowLayout(SDL_Window *window, int flags, int w, int h)
int SDL_SendWindowEvent(SDL_Window *window, Uint8 windowevent, int data1, int data2)
GLfixed GLfixed x2
#define SDL_DFB_RELEASE(x)
GLfixed y1
static SDL_VideoDevice * _this
Definition: SDL_video.c:121
#define SDL_DFB_DEVICEDATA(dev)
SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char const char SDL_SCANF_FORMAT_STRING const char return SDL_ThreadFunction const char void return Uint32 return Uint32 SDL_AssertionHandler void SDL_SpinLock SDL_atomic_t int int return SDL_atomic_t return void void void return void return int return SDL_AudioSpec SDL_AudioSpec return int int return return int SDL_RWops int SDL_AudioSpec Uint8 ** d
DFBResult DirectFB_WM_GetClientSize(_THIS, SDL_Window *window, int *cw, int *ch)
#define _THIS
GLubyte GLubyte GLubyte GLubyte w
#define SDL_zero(x)
Definition: SDL_stdinc.h:416
char * title
Definition: SDL_sysvideo.h:77
GLint GLint GLint GLint GLint GLint y
Definition: SDL_opengl.h:1574
GLsizeiptr size
#define SDL_RestoreWindow
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:164
GLbitfield flags
static char text[MAX_TEXT_LENGTH]
Definition: testime.c:47
#define SDL_DFB_WINDOWDATA(win)
EGLSurface EGLNativeWindowType * window
Definition: eglext.h:1025
void DirectFB_WM_RedrawLayout(_THIS, SDL_Window *window)
#define SDL_DFB_CHECK(x...)
The type used to identify a window.
Definition: SDL_sysvideo.h:73
#define SDL_MaximizeWindow
Uint32 flags
Definition: SDL_sysvideo.h:83
GLdouble GLdouble t
Definition: SDL_opengl.h:2071