zenilib  0.5.3.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
SDL_x11mouse.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_X11
24 
25 #include <X11/cursorfont.h>
26 #include "SDL_assert.h"
27 #include "SDL_x11video.h"
28 #include "SDL_x11mouse.h"
29 #include "SDL_x11xinput2.h"
30 #include "../../events/SDL_mouse_c.h"
31 
32 
33 /* FIXME: Find a better place to put this... */
34 static Cursor x11_empty_cursor = None;
35 
36 static Display *
37 GetDisplay(void)
38 {
39  return ((SDL_VideoData *)SDL_GetVideoDevice()->driverdata)->display;
40 }
41 
42 static Cursor
43 X11_CreateEmptyCursor()
44 {
45  if (x11_empty_cursor == None) {
46  Display *display = GetDisplay();
47  char data[1];
48  XColor color;
49  Pixmap pixmap;
50 
51  SDL_zero(data);
52  color.red = color.green = color.blue = 0;
53  pixmap = XCreateBitmapFromData(display, DefaultRootWindow(display),
54  data, 1, 1);
55  if (pixmap) {
56  x11_empty_cursor = XCreatePixmapCursor(display, pixmap, pixmap,
57  &color, &color, 0, 0);
58  XFreePixmap(display, pixmap);
59  }
60  }
61  return x11_empty_cursor;
62 }
63 
64 static void
65 X11_DestroyEmptyCursor(void)
66 {
67  if (x11_empty_cursor != None) {
68  XFreeCursor(GetDisplay(), x11_empty_cursor);
69  x11_empty_cursor = None;
70  }
71 }
72 
73 static SDL_Cursor *
74 X11_CreateDefaultCursor()
75 {
76  SDL_Cursor *cursor;
77 
78  cursor = SDL_calloc(1, sizeof(*cursor));
79  if (cursor) {
80  /* None is used to indicate the default cursor */
81  cursor->driverdata = (void*)None;
82  } else {
84  }
85 
86  return cursor;
87 }
88 
89 #if SDL_VIDEO_DRIVER_X11_XCURSOR
90 static Cursor
91 X11_CreateXCursorCursor(SDL_Surface * surface, int hot_x, int hot_y)
92 {
93  Display *display = GetDisplay();
94  Cursor cursor = None;
95  XcursorImage *image;
96 
97  image = XcursorImageCreate(surface->w, surface->h);
98  if (!image) {
100  return None;
101  }
102  image->xhot = hot_x;
103  image->yhot = hot_y;
104  image->delay = 0;
105 
107  SDL_assert(surface->pitch == surface->w * 4);
108  SDL_memcpy(image->pixels, surface->pixels, surface->h * surface->pitch);
109 
110  cursor = XcursorImageLoadCursor(display, image);
111 
112  XcursorImageDestroy(image);
113 
114  return cursor;
115 }
116 #endif /* SDL_VIDEO_DRIVER_X11_XCURSOR */
117 
118 static Cursor
119 X11_CreatePixmapCursor(SDL_Surface * surface, int hot_x, int hot_y)
120 {
121  Display *display = GetDisplay();
122  XColor fg, bg;
123  Cursor cursor = None;
124  Uint32 *ptr;
125  Uint8 *data_bits, *mask_bits;
126  Pixmap data_pixmap, mask_pixmap;
127  int x, y;
128  unsigned int rfg, gfg, bfg, rbg, gbg, bbg, fgBits, bgBits;
129  unsigned int width_bytes = ((surface->w + 7) & ~7) / 8;
130 
131  data_bits = SDL_calloc(1, surface->h * width_bytes);
132  if (!data_bits) {
133  SDL_OutOfMemory();
134  return None;
135  }
136 
137  mask_bits = SDL_calloc(1, surface->h * width_bytes);
138  if (!mask_bits) {
139  SDL_free(data_bits);
140  SDL_OutOfMemory();
141  return None;
142  }
143 
144  /* Code below assumes ARGB pixel format */
146 
147  rfg = gfg = bfg = rbg = gbg = bbg = fgBits = bgBits = 0;
148  for (y = 0; y < surface->h; ++y) {
149  ptr = (Uint32 *)((Uint8 *)surface->pixels + y * surface->pitch);
150  for (x = 0; x < surface->w; ++x) {
151  int alpha = (*ptr >> 24) & 0xff;
152  int red = (*ptr >> 16) & 0xff;
153  int green = (*ptr >> 8) & 0xff;
154  int blue = (*ptr >> 0) & 0xff;
155  if (alpha > 25) {
156  mask_bits[y * width_bytes + x / 8] |= (0x01 << (x % 8));
157 
158  if ((red + green + blue) > 0x40) {
159  fgBits++;
160  rfg += red;
161  gfg += green;
162  bfg += blue;
163  data_bits[y * width_bytes + x / 8] |= (0x01 << (x % 8));
164  } else {
165  bgBits++;
166  rbg += red;
167  gbg += green;
168  bbg += blue;
169  }
170  }
171  ++ptr;
172  }
173  }
174 
175  if (fgBits) {
176  fg.red = rfg * 257 / fgBits;
177  fg.green = gfg * 257 / fgBits;
178  fg.blue = bfg * 257 / fgBits;
179  }
180  else fg.red = fg.green = fg.blue = 0;
181 
182  if (bgBits) {
183  bg.red = rbg * 257 / bgBits;
184  bg.green = gbg * 257 / bgBits;
185  bg.blue = bbg * 257 / bgBits;
186  }
187  else bg.red = bg.green = bg.blue = 0;
188 
189  data_pixmap = XCreateBitmapFromData(display, DefaultRootWindow(display),
190  (char*)data_bits,
191  surface->w, surface->h);
192  mask_pixmap = XCreateBitmapFromData(display, DefaultRootWindow(display),
193  (char*)mask_bits,
194  surface->w, surface->h);
195  cursor = XCreatePixmapCursor(display, data_pixmap, mask_pixmap,
196  &fg, &bg, hot_x, hot_y);
197  XFreePixmap(display, data_pixmap);
198  XFreePixmap(display, mask_pixmap);
199 
200  return cursor;
201 }
202 
203 static SDL_Cursor *
204 X11_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y)
205 {
206  SDL_Cursor *cursor;
207 
208  cursor = SDL_calloc(1, sizeof(*cursor));
209  if (cursor) {
210  Cursor x11_cursor = None;
211 
212 #if SDL_VIDEO_DRIVER_X11_XCURSOR
213  if (SDL_X11_HAVE_XCURSOR) {
214  x11_cursor = X11_CreateXCursorCursor(surface, hot_x, hot_y);
215  }
216 #endif
217  if (x11_cursor == None) {
218  x11_cursor = X11_CreatePixmapCursor(surface, hot_x, hot_y);
219  }
220  cursor->driverdata = (void*)x11_cursor;
221  } else {
222  SDL_OutOfMemory();
223  }
224 
225  return cursor;
226 }
227 
228 static SDL_Cursor *
229 X11_CreateSystemCursor(SDL_SystemCursor id)
230 {
231  SDL_Cursor *cursor;
232  unsigned int shape;
233 
234  switch(id)
235  {
236  default:
237  SDL_assert(0);
238  return NULL;
239  /* X Font Cursors reference: */
240  /* http://tronche.com/gui/x/xlib/appendix/b/ */
241  case SDL_SYSTEM_CURSOR_ARROW: shape = XC_left_ptr; break;
242  case SDL_SYSTEM_CURSOR_IBEAM: shape = XC_xterm; break;
243  case SDL_SYSTEM_CURSOR_WAIT: shape = XC_watch; break;
244  case SDL_SYSTEM_CURSOR_CROSSHAIR: shape = XC_tcross; break;
245  case SDL_SYSTEM_CURSOR_WAITARROW: shape = XC_watch; break;
246  case SDL_SYSTEM_CURSOR_SIZENWSE: shape = XC_fleur; break;
247  case SDL_SYSTEM_CURSOR_SIZENESW: shape = XC_fleur; break;
248  case SDL_SYSTEM_CURSOR_SIZEWE: shape = XC_sb_h_double_arrow; break;
249  case SDL_SYSTEM_CURSOR_SIZENS: shape = XC_sb_v_double_arrow; break;
250  case SDL_SYSTEM_CURSOR_SIZEALL: shape = XC_fleur; break;
251  case SDL_SYSTEM_CURSOR_NO: shape = XC_pirate; break;
252  case SDL_SYSTEM_CURSOR_HAND: shape = XC_hand2; break;
253  }
254 
255  cursor = SDL_calloc(1, sizeof(*cursor));
256  if (cursor) {
257  Cursor x11_cursor;
258 
259  x11_cursor = XCreateFontCursor(GetDisplay(), shape);
260 
261  cursor->driverdata = (void*)x11_cursor;
262  } else {
263  SDL_OutOfMemory();
264  }
265 
266  return cursor;
267 }
268 
269 static void
270 X11_FreeCursor(SDL_Cursor * cursor)
271 {
272  Cursor x11_cursor = (Cursor)cursor->driverdata;
273 
274  if (x11_cursor != None) {
275  XFreeCursor(GetDisplay(), x11_cursor);
276  }
277  SDL_free(cursor);
278 }
279 
280 static int
281 X11_ShowCursor(SDL_Cursor * cursor)
282 {
283  Cursor x11_cursor = 0;
284 
285  if (cursor) {
286  x11_cursor = (Cursor)cursor->driverdata;
287  } else {
288  x11_cursor = X11_CreateEmptyCursor();
289  }
290 
291  /* FIXME: Is there a better way than this? */
292  {
294  Display *display = GetDisplay();
295  SDL_Window *window;
297 
298  for (window = video->windows; window; window = window->next) {
299  data = (SDL_WindowData *)window->driverdata;
300  if (x11_cursor != None) {
301  XDefineCursor(display, data->xwindow, x11_cursor);
302  } else {
303  XUndefineCursor(display, data->xwindow);
304  }
305  }
306  XFlush(display);
307  }
308  return 0;
309 }
310 
311 static void
312 X11_WarpMouse(SDL_Window * window, int x, int y)
313 {
314  SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
315  Display *display = data->videodata->display;
316 
317  XWarpPointer(display, None, data->xwindow, 0, 0, 0, 0, x, y);
318  XSync(display, False);
319 }
320 
321 static int
322 X11_SetRelativeMouseMode(SDL_bool enabled)
323 {
324 #if SDL_VIDEO_DRIVER_X11_XINPUT2
326  return 0;
327 #else
328  SDL_Unsupported();
329 #endif
330  return -1;
331 }
332 
333 void
335 {
336  SDL_Mouse *mouse = SDL_GetMouse();
337 
338  mouse->CreateCursor = X11_CreateCursor;
339  mouse->CreateSystemCursor = X11_CreateSystemCursor;
340  mouse->ShowCursor = X11_ShowCursor;
341  mouse->FreeCursor = X11_FreeCursor;
342  mouse->WarpMouse = X11_WarpMouse;
343  mouse->SetRelativeMouseMode = X11_SetRelativeMouseMode;
344 
345  SDL_SetDefaultCursor(X11_CreateDefaultCursor());
346 }
347 
348 void
350 {
351  X11_DestroyEmptyCursor();
352 }
353 
354 #endif /* SDL_VIDEO_DRIVER_X11 */
355 
356 /* vi: set ts=4 sw=4 expandtab: */
SDL_Window * next
Definition: SDL_sysvideo.h:102
Display * display
Definition: SDL_x11video.h:75
SDL_Mouse * SDL_GetMouse(void)
Definition: SDL_mouse.c:62
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 int return Display Window Cursor return Display Window return Display Drawable GC int int unsigned int unsigned int return Display Drawable GC int int _Xconst char int return Display Drawable GC int int unsigned int unsigned int return Display return Display Cursor return Display GC return XModifierKeymap return char Display Window int return Display return Display Atom return Display Window XWindowAttributes return Display Window return Display XEvent Bool(*) XPointer return Display Window Bool unsigned int int int Window Cursor Time return Display Window int return KeySym return Display _Xconst char Bool return Display _Xconst char return XKeyEvent char int KeySym XComposeStatus return Display int int int XVisualInfo return Display Window int int return _Xconst char return Display XEvent return Display Drawable GC XImage int int int int unsigned int unsigned int return Display Window Window Window int int int int unsigned int return Display Window Window int int return Display Window unsigned int unsigned int return Display Window Bool long XEvent return Display GC unsigned long return Display Window int Time return Display Window Window return Display Window unsigned long return Display Window XSizeHints Display Colormap XColor int return char int XTextProperty return XFontStruct _Xconst char int int int int XCharStruct return Display Window return Display Time return Display Colormap retur XWarpPointer)
Definition: SDL_x11sym.h:128
DECLSPEC void *SDLCALL SDL_calloc(size_t nmemb, size_t size)
GLuint color
Definition: glew.h:7185
#define NULL
Definition: ftobjs.h:61
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 int return Display Window Cursor return Display Window return Display Drawable GC int int unsigned int unsigned int return Display Drawable GC int int _Xconst char int return Display Drawable GC int int unsigned int unsigned int retur XFlush)
Definition: SDL_x11sym.h:54
SDL_bool
Definition: SDL_stdinc.h:116
GLenum GLsizei const GLuint GLboolean enabled
Definition: glew.h:2538
EGLSurface EGLint x
Definition: eglext.h:293
EGLSurface surface
Definition: eglext.h:74
A collection of pixels used in software blitting.
Definition: SDL_surface.h:69
DECLSPEC void SDLCALL SDL_free(void *mem)
GLclampf green
Definition: glew.h:1506
void X11_InitMouse(_THIS)
char * display
Definition: visualinfo.c:85
if(!yyg->yy_init)
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 int retur XDefineCursor)
Definition: SDL_x11sym.h:44
EGLImageKHR image
Definition: eglext.h:88
const GLubyte GLuint red
Definition: SDL_glfuncs.h:57
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 retur XCreatePixmapCursor)
Definition: SDL_x11sym.h:38
uint32_t Uint32
An unsigned 32-bit integer type.
Definition: SDL_stdinc.h:145
void(* FreeCursor)(SDL_Cursor *cursor)
Definition: SDL_mouse_c.h:51
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 int return Display Window Cursor return Display Window return Display Drawable GC int int unsigned int unsigned int return Display Drawable GC int int _Xconst char int return Display Drawable GC int int unsigned int unsigned int return Display return Display Cursor return Display GC return XModifierKeymap return char Display Window int return Display return Display Atom return Display Window XWindowAttributes return Display Window return Display XEvent Bool(*) XPointer return Display Window Bool unsigned int int int Window Cursor Time return Display Window int return KeySym return Display _Xconst char Bool return Display _Xconst char return XKeyEvent char int KeySym XComposeStatus return Display int int int XVisualInfo return Display Window int int return _Xconst char return Display XEvent return Display Drawable GC XImage int int int int unsigned int unsigned int return Display Window Window Window int int int int unsigned int return Display Window Window int int return Display Window unsigned int unsigned int return Display Window Bool long XEvent return Display GC unsigned long return Display Window int Time return Display Window Window return Display Window unsigned long return Display Window XSizeHints Display Colormap XColor int return char int XTextProperty return XFontStruct _Xconst char int int int int XCharStruct retur XUndefineCursor)
Definition: SDL_x11sym.h:122
SDL_Cursor *(* CreateCursor)(SDL_Surface *surface, int hot_x, int hot_y)
Definition: SDL_mouse_c.h:39
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl2ext.h:848
void * pixels
Definition: SDL_surface.h:75
#define _THIS
struct SDL_VideoData * videodata
int(* ShowCursor)(SDL_Cursor *cursor)
Definition: SDL_mouse_c.h:45
SDL_SystemCursor
Cursor types for SDL_CreateSystemCursor.
Definition: SDL_mouse.h:46
int(* SetRelativeMouseMode)(SDL_bool enabled)
Definition: SDL_mouse_c.h:57
GLclampf GLclampf GLclampf alpha
Definition: glew.h:1506
SDL_Window * windows
Definition: SDL_sysvideo.h:266
void SDL_SetDefaultCursor(SDL_Cursor *cursor)
Definition: SDL_mouse.c:51
void X11_QuitMouse(_THIS)
#define SDL_assert(condition)
Definition: SDL_assert.h:159
EGLSurface EGLint EGLint y
Definition: eglext.h:293
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
SDL_PixelFormat * format
Definition: SDL_surface.h:72
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display retur XCreateBitmapFromData)
Definition: SDL_x11sym.h:36
EGLConfig struct EGLClientPixmapHI * pixmap
Definition: eglext.h:257
DECLSPEC void *SDLCALL SDL_memcpy(void *dst, const void *src, size_t len)
Definition: SDL_string.c:293
uint8_t Uint8
An unsigned 8-bit integer type.
Definition: SDL_stdinc.h:129
SDL_VideoDevice * SDL_GetVideoDevice(void)
Definition: SDL_video.c:548
#define SDL_zero(x)
Definition: SDL_stdinc.h:254
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 int return Display Window Cursor return Display Window return Display Drawable GC int int unsigned int unsigned int return Display Drawable GC int int _Xconst char int return Display Drawable GC int int unsigned int unsigned int return Display retur XFreeCursor)
Definition: SDL_x11sym.h:56
void * driverdata
Definition: SDL_sysvideo.h:99
int X11_Xinput2IsInitialized(void)
GLclampf GLclampf blue
Definition: glew.h:1506
void * driverdata
Definition: SDL_mouse_c.h:33
#define SDL_Unsupported()
Definition: SDL_error.h:53
SDL_Cursor *(* CreateSystemCursor)(SDL_SystemCursor id)
Definition: SDL_mouse_c.h:42
void(* WarpMouse)(SDL_Window *window, int x, int y)
Definition: SDL_mouse_c.h:54