SDL  2.0
SDL_DirectFB_mouse.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_assert.h"
26 
27 #include "SDL_DirectFB_video.h"
28 #include "SDL_DirectFB_mouse.h"
29 #include "SDL_DirectFB_modes.h"
30 #include "SDL_DirectFB_window.h"
31 
32 #include "../SDL_sysvideo.h"
33 #include "../../events/SDL_mouse_c.h"
34 
35 static SDL_Cursor *DirectFB_CreateDefaultCursor(void);
36 static SDL_Cursor *DirectFB_CreateCursor(SDL_Surface * surface,
37  int hot_x, int hot_y);
38 static int DirectFB_ShowCursor(SDL_Cursor * cursor);
39 static void DirectFB_FreeCursor(SDL_Cursor * cursor);
40 static void DirectFB_WarpMouse(SDL_Window * window, int x, int y);
41 
42 static const char *arrow[] = {
43  /* pixels */
44  "X ",
45  "XX ",
46  "X.X ",
47  "X..X ",
48  "X...X ",
49  "X....X ",
50  "X.....X ",
51  "X......X ",
52  "X.......X ",
53  "X........X ",
54  "X.....XXXXX ",
55  "X..X..X ",
56  "X.X X..X ",
57  "XX X..X ",
58  "X X..X ",
59  " X..X ",
60  " X..X ",
61  " X..X ",
62  " XX ",
63  " ",
64  " ",
65  " ",
66  " ",
67  " ",
68  " ",
69  " ",
70  " ",
71  " ",
72  " ",
73  " ",
74  " ",
75  " ",
76 };
77 
78 static SDL_Cursor *
79 DirectFB_CreateDefaultCursor(void)
80 {
82 
83  SDL_DFB_DEVICEDATA(dev);
84  DFB_CursorData *curdata;
85  DFBSurfaceDescription dsc;
87  Uint32 *dest;
88  int pitch, i, j;
89 
90  SDL_DFB_ALLOC_CLEAR( cursor, sizeof(*cursor));
91  SDL_DFB_ALLOC_CLEAR(curdata, sizeof(*curdata));
92 
93  dsc.flags =
94  DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS;
95  dsc.caps = DSCAPS_VIDEOONLY;
96  dsc.width = 32;
97  dsc.height = 32;
98  dsc.pixelformat = DSPF_ARGB;
99 
100  SDL_DFB_CHECKERR(devdata->dfb->CreateSurface(devdata->dfb, &dsc,
101  &curdata->surf));
102  curdata->hotx = 0;
103  curdata->hoty = 0;
104  cursor->driverdata = curdata;
105 
106  SDL_DFB_CHECKERR(curdata->surf->Lock(curdata->surf, DSLF_WRITE,
107  (void *) &dest, &pitch));
108 
109  /* Relies on the fact that this is only called with ARGB surface. */
110  for (i = 0; i < 32; i++)
111  {
112  for (j = 0; j < 32; j++)
113  {
114  switch (arrow[i][j])
115  {
116  case ' ': dest[j] = 0x00000000; break;
117  case '.': dest[j] = 0xffffffff; break;
118  case 'X': dest[j] = 0xff000000; break;
119  }
120  }
121  dest += (pitch >> 2);
122  }
123 
124  curdata->surf->Unlock(curdata->surf);
125  return cursor;
126  error:
127  return NULL;
128 }
129 
130 /* Create a cursor from a surface */
131 static SDL_Cursor *
132 DirectFB_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y)
133 {
135 
136  SDL_DFB_DEVICEDATA(dev);
137  DFB_CursorData *curdata;
138  DFBSurfaceDescription dsc;
140  Uint32 *dest;
141  Uint32 *p;
142  int pitch, i;
143 
145  SDL_assert(surface->pitch == surface->w * 4);
146 
147  SDL_DFB_ALLOC_CLEAR( cursor, sizeof(*cursor));
148  SDL_DFB_ALLOC_CLEAR(curdata, sizeof(*curdata));
149 
150  dsc.flags =
151  DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS;
152  dsc.caps = DSCAPS_VIDEOONLY;
153  dsc.width = surface->w;
154  dsc.height = surface->h;
155  dsc.pixelformat = DSPF_ARGB;
156 
157  SDL_DFB_CHECKERR(devdata->dfb->CreateSurface(devdata->dfb, &dsc,
158  &curdata->surf));
159  curdata->hotx = hot_x;
160  curdata->hoty = hot_y;
161  cursor->driverdata = curdata;
162 
163  SDL_DFB_CHECKERR(curdata->surf->Lock(curdata->surf, DSLF_WRITE,
164  (void *) &dest, &pitch));
165 
166  p = surface->pixels;
167  for (i = 0; i < surface->h; i++)
168  memcpy((char *) dest + i * pitch,
169  (char *) p + i * surface->pitch, 4 * surface->w);
170 
171  curdata->surf->Unlock(curdata->surf);
172  return cursor;
173  error:
174  return NULL;
175 }
176 
177 /* Show the specified cursor, or hide if cursor is NULL */
178 static int
179 DirectFB_ShowCursor(SDL_Cursor * cursor)
180 {
181  SDL_DFB_CURSORDATA(cursor);
183 
184  window = SDL_GetFocusWindow();
185  if (!window)
186  return -1;
187  else {
188  SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
189 
190  if (display) {
191  DFB_DisplayData *dispdata =
192  (DFB_DisplayData *) display->driverdata;
193  DFB_WindowData *windata = (DFB_WindowData *) window->driverdata;
194 
195  if (cursor)
196  SDL_DFB_CHECKERR(windata->dfbwin->
197  SetCursorShape(windata->dfbwin,
198  curdata->surf, curdata->hotx,
199  curdata->hoty));
200 
201  SDL_DFB_CHECKERR(dispdata->layer->
202  SetCooperativeLevel(dispdata->layer,
203  DLSCL_ADMINISTRATIVE));
204  SDL_DFB_CHECKERR(dispdata->layer->
205  SetCursorOpacity(dispdata->layer,
206  cursor ? 0xC0 : 0x00));
207  SDL_DFB_CHECKERR(dispdata->layer->
208  SetCooperativeLevel(dispdata->layer,
209  DLSCL_SHARED));
210  }
211  }
212 
213  return 0;
214  error:
215  return -1;
216 }
217 
218 /* Free a window manager cursor */
219 static void
220 DirectFB_FreeCursor(SDL_Cursor * cursor)
221 {
222  SDL_DFB_CURSORDATA(cursor);
223 
224  SDL_DFB_RELEASE(curdata->surf);
225  SDL_DFB_FREE(cursor->driverdata);
226  SDL_DFB_FREE(cursor);
227 }
228 
229 /* Warp the mouse to (x,y) */
230 static void
231 DirectFB_WarpMouse(SDL_Window * window, int x, int y)
232 {
233  SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
234  DFB_DisplayData *dispdata = (DFB_DisplayData *) display->driverdata;
235  DFB_WindowData *windata = (DFB_WindowData *) window->driverdata;
236  int cx, cy;
237 
238  SDL_DFB_CHECKERR(windata->dfbwin->GetPosition(windata->dfbwin, &cx, &cy));
239  SDL_DFB_CHECKERR(dispdata->layer->WarpCursor(dispdata->layer,
240  cx + x + windata->client.x,
241  cy + y + windata->client.y));
242 
243  error:
244  return;
245 }
246 
247 #if USE_MULTI_API
248 
249 static void DirectFB_MoveCursor(SDL_Cursor * cursor);
250 static void DirectFB_WarpMouse(SDL_Mouse * mouse, SDL_Window * window,
251  int x, int y);
252 static void DirectFB_FreeMouse(SDL_Mouse * mouse);
253 
254 static int id_mask;
255 
256 static DFBEnumerationResult
257 EnumMice(DFBInputDeviceID device_id, DFBInputDeviceDescription desc,
258  void *callbackdata)
259 {
260  DFB_DeviceData *devdata = callbackdata;
261 
262  if ((desc.type & DIDTF_MOUSE) && (device_id & id_mask)) {
263  SDL_Mouse mouse;
264 
265  SDL_zero(mouse);
266  mouse.id = device_id;
267  mouse.CreateCursor = DirectFB_CreateCursor;
268  mouse.ShowCursor = DirectFB_ShowCursor;
269  mouse.MoveCursor = DirectFB_MoveCursor;
270  mouse.FreeCursor = DirectFB_FreeCursor;
271  mouse.WarpMouse = DirectFB_WarpMouse;
272  mouse.FreeMouse = DirectFB_FreeMouse;
273  mouse.cursor_shown = 1;
274 
275  SDL_AddMouse(&mouse, desc.name, 0, 0, 1);
276  devdata->mouse_id[devdata->num_mice++] = device_id;
277  }
278  return DFENUM_OK;
279 }
280 
281 void
283 {
285 
286  devdata->num_mice = 0;
287  if (devdata->use_linux_input) {
288  /* try non-core devices first */
289  id_mask = 0xF0;
290  devdata->dfb->EnumInputDevices(devdata->dfb, EnumMice, devdata);
291  if (devdata->num_mice == 0) {
292  /* try core devices */
293  id_mask = 0x0F;
294  devdata->dfb->EnumInputDevices(devdata->dfb, EnumMice, devdata);
295  }
296  }
297  if (devdata->num_mice == 0) {
298  SDL_Mouse mouse;
299 
300  SDL_zero(mouse);
301  mouse.CreateCursor = DirectFB_CreateCursor;
302  mouse.ShowCursor = DirectFB_ShowCursor;
303  mouse.MoveCursor = DirectFB_MoveCursor;
304  mouse.FreeCursor = DirectFB_FreeCursor;
305  mouse.WarpMouse = DirectFB_WarpMouse;
306  mouse.FreeMouse = DirectFB_FreeMouse;
307  mouse.cursor_shown = 1;
308 
309  SDL_AddMouse(&mouse, "Mouse", 0, 0, 1);
310  devdata->num_mice = 1;
311  }
312 }
313 
314 void
316 {
318 
319  if (devdata->use_linux_input) {
320  SDL_MouseQuit();
321  } else {
322  SDL_DelMouse(0);
323  }
324 }
325 
326 
327 /* This is called when a mouse motion event occurs */
328 static void
329 DirectFB_MoveCursor(SDL_Cursor * cursor)
330 {
331 
332 }
333 
334 /* Warp the mouse to (x,y) */
335 static void
336 DirectFB_WarpMouse(SDL_Mouse * mouse, SDL_Window * window, int x, int y)
337 {
338  SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
339  DFB_DisplayData *dispdata = (DFB_DisplayData *) display->driverdata;
340  DFB_WindowData *windata = (DFB_WindowData *) window->driverdata;
341  DFBResult ret;
342  int cx, cy;
343 
344  SDL_DFB_CHECKERR(windata->dfbwin->GetPosition(windata->dfbwin, &cx, &cy));
345  SDL_DFB_CHECKERR(dispdata->layer->WarpCursor(dispdata->layer,
346  cx + x + windata->client.x,
347  cy + y + windata->client.y));
348 
349  error:
350  return;
351 }
352 
353 /* Free the mouse when it's time */
354 static void
355 DirectFB_FreeMouse(SDL_Mouse * mouse)
356 {
357  /* nothing yet */
358 }
359 
360 #else /* USE_MULTI_API */
361 
362 void
364 {
366 
367  SDL_Mouse *mouse = SDL_GetMouse();
368 
369  mouse->CreateCursor = DirectFB_CreateCursor;
370  mouse->ShowCursor = DirectFB_ShowCursor;
371  mouse->WarpMouse = DirectFB_WarpMouse;
372  mouse->FreeCursor = DirectFB_FreeCursor;
373 
374  SDL_SetDefaultCursor(DirectFB_CreateDefaultCursor());
375 
376  devdata->num_mice = 1;
377 }
378 
379 void
381 {
382 }
383 
384 
385 #endif
386 
387 #endif /* SDL_VIDEO_DRIVER_DIRECTFB */
388 
389 /* vi: set ts=4 sw=4 expandtab: */
SDL_Mouse * SDL_GetMouse(void)
Definition: SDL_mouse.c:112
#define SDL_DFB_FREE(x)
int(* ShowCursor)(SDL_Cursor *cursor)
Definition: SDL_mouse_c.h:52
GLint GLint GLint GLint GLint x
Definition: SDL_opengl.h:1574
GLfloat GLfloat p
EGLSurface surface
Definition: eglext.h:248
A collection of pixels used in software blitting.
Definition: SDL_surface.h:69
uint32_t Uint32
Definition: SDL_stdinc.h:181
void SDL_MouseQuit(void)
Definition: SDL_mouse.c:566
#define SDL_DFB_RELEASE(x)
void DirectFB_QuitMouse(_THIS)
static SDL_VideoDevice * _this
Definition: SDL_video.c:121
void DirectFB_InitMouse(_THIS)
static const char * arrow[]
SDL_Cursor *(* CreateCursor)(SDL_Surface *surface, int hot_x, int hot_y)
Definition: SDL_mouse_c.h:46
#define SDL_DFB_DEVICEDATA(dev)
void * pixels
Definition: SDL_surface.h:75
#define _THIS
SDL_Window * SDL_GetFocusWindow(void)
Definition: SDL_video.c:2594
SDL_bool cursor_shown
Definition: SDL_mouse_c.h:102
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 int in j)
Definition: SDL_x11sym.h:50
#define SDL_zero(x)
Definition: SDL_stdinc.h:416
GLint GLint GLint GLint GLint GLint y
Definition: SDL_opengl.h:1574
void SDL_SetDefaultCursor(SDL_Cursor *cursor)
Definition: SDL_mouse.c:101
SDL_Cursor * cursor
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
void(* FreeCursor)(SDL_Cursor *cursor)
Definition: SDL_mouse_c.h:58
#define SDL_assert(condition)
Definition: SDL_assert.h:169
#define NULL
Definition: begin_code.h:164
#define SDL_DFB_ALLOC_CLEAR(r, s)
#define SDL_DFB_CHECKERR(x...)
SDL_PixelFormat * format
Definition: SDL_surface.h:72
SDL_VideoDisplay * SDL_GetDisplayForWindow(SDL_Window *window)
Definition: SDL_video.c:1073
EGLSurface EGLNativeWindowType * window
Definition: eglext.h:1025
#define memcpy
Definition: SDL_malloc.c:622
The type used to identify a window.
Definition: SDL_sysvideo.h:73
#define SDL_DFB_CURSORDATA(curs)
void(* WarpMouse)(SDL_Window *window, int x, int y)
Definition: SDL_mouse_c.h:61
SDL_VideoDevice * SDL_GetVideoDevice(void)
Definition: SDL_video.c:586
void * driverdata
Definition: SDL_sysvideo.h:111
void(* MoveCursor)(SDL_Cursor *cursor)
Definition: SDL_mouse_c.h:55
void * driverdata
Definition: SDL_mouse_c.h:33
int uint32_t uint32_t uint32_t uint32_t uint32_t int drmModeModeInfoPtr mode int uint32_t uint32_t uint32_t uint32_t int32_t hot_x
Definition: SDL_kmsdrmsym.h:55