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