zenilib  0.5.3.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
SDL_DirectFB_WM.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2013 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_config.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 */
GLdouble s
Definition: glew.h:1376
GLfloat GLfloat GLfloat GLfloat h
Definition: glew.h:7294
int DirectFB_WM_ProcessEvent(_THIS, SDL_Window *window, DFBWindowEvent *evt)
#define NULL
Definition: ftobjs.h:61
EGLSurface EGLint x
Definition: eglext.h:293
GLdouble GLdouble t
Definition: glew.h:1384
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)
return Display return Display Bool Bool int d
Definition: SDL_x11sym.h:30
GLuint GLfloat GLfloat GLfloat GLfloat y1
Definition: glew.h:11582
GLfixed GLfixed GLfixed y2
Definition: glext.h:4559
#define SDL_DFB_RELEASE(x)
static SDL_VideoDevice * _this
Definition: SDL_video.c:92
#define SDL_DFB_DEVICEDATA(dev)
IDirectFBWindow * dfbwin
DFBResult DirectFB_WM_GetClientSize(_THIS, SDL_Window *window, int *cw, int *ch)
#define _THIS
DFBColor frame_color
GLfloat GLfloat p
Definition: glew.h:14938
DECLSPEC void SDLCALL SDL_RestoreWindow(SDL_Window *window)
Restore the size and position of a minimized or maximized window.
Definition: SDL_video.c:1799
char * title
Definition: SDL_sysvideo.h:75
DECLSPEC void SDLCALL SDL_MaximizeWindow(SDL_Window *window)
Make a window as large as possible.
Definition: SDL_video.c:1767
GLuint GLfloat GLfloat GLfloat x1
Definition: glew.h:11582
EGLSurface EGLint EGLint y
Definition: eglext.h:293
DFBColor font_color
#define SDL_DFB_WINDOWDATA(win)
GLenum GLsizei GLsizei GLsizei GLsizei GLbitfield flags
Definition: glew.h:2767
void DirectFB_WM_RedrawLayout(_THIS, SDL_Window *window)
#define SDL_DFB_CHECK(x...)
GLfixed GLfixed x2
Definition: glext.h:4559
DFBColor close_color
GLint GLint GLint GLint GLint w
Definition: gl2ext.h:1215
#define SDL_zero(x)
Definition: SDL_stdinc.h:254
DFBColor caption_color
int i
Definition: pngrutil.c:1377
Uint32 flags
Definition: SDL_sysvideo.h:81
DFBColor max_color
GLsizei size
Definition: gl2ext.h:1467