SDL  2.0
SDL_x11mouse.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_X11
24 
25 #include <X11/cursorfont.h>
26 #include "SDL_x11video.h"
27 #include "SDL_x11mouse.h"
28 #include "SDL_x11xinput2.h"
29 #include "../../events/SDL_mouse_c.h"
30 
31 
32 /* FIXME: Find a better place to put this... */
33 static Cursor x11_empty_cursor = None;
34 
35 static Display *
36 GetDisplay(void)
37 {
38  return ((SDL_VideoData *)SDL_GetVideoDevice()->driverdata)->display;
39 }
40 
41 static Cursor
42 X11_CreateEmptyCursor()
43 {
44  if (x11_empty_cursor == None) {
45  Display *display = GetDisplay();
46  char data[1];
47  XColor color;
48  Pixmap pixmap;
49 
50  SDL_zeroa(data);
51  color.red = color.green = color.blue = 0;
52  pixmap = X11_XCreateBitmapFromData(display, DefaultRootWindow(display),
53  data, 1, 1);
54  if (pixmap) {
55  x11_empty_cursor = X11_XCreatePixmapCursor(display, pixmap, pixmap,
56  &color, &color, 0, 0);
57  X11_XFreePixmap(display, pixmap);
58  }
59  }
60  return x11_empty_cursor;
61 }
62 
63 static void
64 X11_DestroyEmptyCursor(void)
65 {
66  if (x11_empty_cursor != None) {
67  X11_XFreeCursor(GetDisplay(), x11_empty_cursor);
68  x11_empty_cursor = None;
69  }
70 }
71 
72 static SDL_Cursor *
73 X11_CreateDefaultCursor()
74 {
76 
77  cursor = SDL_calloc(1, sizeof(*cursor));
78  if (cursor) {
79  /* None is used to indicate the default cursor */
80  cursor->driverdata = (void*)None;
81  } else {
83  }
84 
85  return cursor;
86 }
87 
88 #if SDL_VIDEO_DRIVER_X11_XCURSOR
89 static Cursor
90 X11_CreateXCursorCursor(SDL_Surface * surface, int hot_x, int hot_y)
91 {
92  Display *display = GetDisplay();
93  Cursor cursor = None;
94  XcursorImage *image;
95 
96  image = X11_XcursorImageCreate(surface->w, surface->h);
97  if (!image) {
99  return None;
100  }
101  image->xhot = hot_x;
102  image->yhot = hot_y;
103  image->delay = 0;
104 
105  SDL_assert(surface->format->format == SDL_PIXELFORMAT_ARGB8888);
106  SDL_assert(surface->pitch == surface->w * 4);
107  SDL_memcpy(image->pixels, surface->pixels, surface->h * surface->pitch);
108 
109  cursor = X11_XcursorImageLoadCursor(display, image);
110 
111  X11_XcursorImageDestroy(image);
112 
113  return cursor;
114 }
115 #endif /* SDL_VIDEO_DRIVER_X11_XCURSOR */
116 
117 static Cursor
118 X11_CreatePixmapCursor(SDL_Surface * surface, int hot_x, int hot_y)
119 {
120  Display *display = GetDisplay();
121  XColor fg, bg;
122  Cursor cursor = None;
123  Uint32 *ptr;
124  Uint8 *data_bits, *mask_bits;
125  Pixmap data_pixmap, mask_pixmap;
126  int x, y;
127  unsigned int rfg, gfg, bfg, rbg, gbg, bbg, fgBits, bgBits;
128  unsigned int width_bytes = ((surface->w + 7) & ~7) / 8;
129 
130  data_bits = SDL_calloc(1, surface->h * width_bytes);
131  if (!data_bits) {
132  SDL_OutOfMemory();
133  return None;
134  }
135 
136  mask_bits = SDL_calloc(1, surface->h * width_bytes);
137  if (!mask_bits) {
138  SDL_free(data_bits);
139  SDL_OutOfMemory();
140  return None;
141  }
142 
143  /* Code below assumes ARGB pixel format */
144  SDL_assert(surface->format->format == SDL_PIXELFORMAT_ARGB8888);
145 
146  rfg = gfg = bfg = rbg = gbg = bbg = fgBits = bgBits = 0;
147  for (y = 0; y < surface->h; ++y) {
148  ptr = (Uint32 *)((Uint8 *)surface->pixels + y * surface->pitch);
149  for (x = 0; x < surface->w; ++x) {
150  int alpha = (*ptr >> 24) & 0xff;
151  int red = (*ptr >> 16) & 0xff;
152  int green = (*ptr >> 8) & 0xff;
153  int blue = (*ptr >> 0) & 0xff;
154  if (alpha > 25) {
155  mask_bits[y * width_bytes + x / 8] |= (0x01 << (x % 8));
156 
157  if ((red + green + blue) > 0x40) {
158  fgBits++;
159  rfg += red;
160  gfg += green;
161  bfg += blue;
162  data_bits[y * width_bytes + x / 8] |= (0x01 << (x % 8));
163  } else {
164  bgBits++;
165  rbg += red;
166  gbg += green;
167  bbg += blue;
168  }
169  }
170  ++ptr;
171  }
172  }
173 
174  if (fgBits) {
175  fg.red = rfg * 257 / fgBits;
176  fg.green = gfg * 257 / fgBits;
177  fg.blue = bfg * 257 / fgBits;
178  }
179  else fg.red = fg.green = fg.blue = 0;
180 
181  if (bgBits) {
182  bg.red = rbg * 257 / bgBits;
183  bg.green = gbg * 257 / bgBits;
184  bg.blue = bbg * 257 / bgBits;
185  }
186  else bg.red = bg.green = bg.blue = 0;
187 
188  data_pixmap = X11_XCreateBitmapFromData(display, DefaultRootWindow(display),
189  (char*)data_bits,
190  surface->w, surface->h);
191  mask_pixmap = X11_XCreateBitmapFromData(display, DefaultRootWindow(display),
192  (char*)mask_bits,
193  surface->w, surface->h);
194  cursor = X11_XCreatePixmapCursor(display, data_pixmap, mask_pixmap,
195  &fg, &bg, hot_x, hot_y);
196  X11_XFreePixmap(display, data_pixmap);
197  X11_XFreePixmap(display, mask_pixmap);
198 
199  return cursor;
200 }
201 
202 static SDL_Cursor *
203 X11_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y)
204 {
206 
207  cursor = SDL_calloc(1, sizeof(*cursor));
208  if (cursor) {
209  Cursor x11_cursor = None;
210 
211 #if SDL_VIDEO_DRIVER_X11_XCURSOR
212  if (SDL_X11_HAVE_XCURSOR) {
213  x11_cursor = X11_CreateXCursorCursor(surface, hot_x, hot_y);
214  }
215 #endif
216  if (x11_cursor == None) {
217  x11_cursor = X11_CreatePixmapCursor(surface, hot_x, hot_y);
218  }
219  cursor->driverdata = (void*)x11_cursor;
220  } else {
221  SDL_OutOfMemory();
222  }
223 
224  return cursor;
225 }
226 
227 static SDL_Cursor *
228 X11_CreateSystemCursor(SDL_SystemCursor id)
229 {
231  unsigned int shape;
232 
233  switch(id)
234  {
235  default:
236  SDL_assert(0);
237  return NULL;
238  /* X Font Cursors reference: */
239  /* http://tronche.com/gui/x/xlib/appendix/b/ */
240  case SDL_SYSTEM_CURSOR_ARROW: shape = XC_left_ptr; break;
241  case SDL_SYSTEM_CURSOR_IBEAM: shape = XC_xterm; break;
242  case SDL_SYSTEM_CURSOR_WAIT: shape = XC_watch; break;
243  case SDL_SYSTEM_CURSOR_CROSSHAIR: shape = XC_tcross; break;
244  case SDL_SYSTEM_CURSOR_WAITARROW: shape = XC_watch; break;
245  case SDL_SYSTEM_CURSOR_SIZENWSE: shape = XC_fleur; break;
246  case SDL_SYSTEM_CURSOR_SIZENESW: shape = XC_fleur; break;
247  case SDL_SYSTEM_CURSOR_SIZEWE: shape = XC_sb_h_double_arrow; break;
248  case SDL_SYSTEM_CURSOR_SIZENS: shape = XC_sb_v_double_arrow; break;
249  case SDL_SYSTEM_CURSOR_SIZEALL: shape = XC_fleur; break;
250  case SDL_SYSTEM_CURSOR_NO: shape = XC_pirate; break;
251  case SDL_SYSTEM_CURSOR_HAND: shape = XC_hand2; break;
252  }
253 
254  cursor = SDL_calloc(1, sizeof(*cursor));
255  if (cursor) {
256  Cursor x11_cursor;
257 
258  x11_cursor = X11_XCreateFontCursor(GetDisplay(), shape);
259 
260  cursor->driverdata = (void*)x11_cursor;
261  } else {
262  SDL_OutOfMemory();
263  }
264 
265  return cursor;
266 }
267 
268 static void
269 X11_FreeCursor(SDL_Cursor * cursor)
270 {
271  Cursor x11_cursor = (Cursor)cursor->driverdata;
272 
273  if (x11_cursor != None) {
274  X11_XFreeCursor(GetDisplay(), x11_cursor);
275  }
276  SDL_free(cursor);
277 }
278 
279 static int
280 X11_ShowCursor(SDL_Cursor * cursor)
281 {
282  Cursor x11_cursor = 0;
283 
284  if (cursor) {
285  x11_cursor = (Cursor)cursor->driverdata;
286  } else {
287  x11_cursor = X11_CreateEmptyCursor();
288  }
289 
290  /* FIXME: Is there a better way than this? */
291  {
293  Display *display = GetDisplay();
296 
297  for (window = video->windows; window; window = window->next) {
298  data = (SDL_WindowData *)window->driverdata;
299  if (x11_cursor != None) {
300  X11_XDefineCursor(display, data->xwindow, x11_cursor);
301  } else {
302  X11_XUndefineCursor(display, data->xwindow);
303  }
304  }
305  X11_XFlush(display);
306  }
307  return 0;
308 }
309 
310 static void
311 WarpMouseInternal(Window xwindow, const int x, const int y)
312 {
314  Display *display = videodata->display;
315  X11_XWarpPointer(display, None, xwindow, 0, 0, 0, 0, x, y);
316  X11_XSync(display, False);
317  videodata->global_mouse_changed = SDL_TRUE;
318 }
319 
320 static void
321 X11_WarpMouse(SDL_Window * window, int x, int y)
322 {
323  SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
324  WarpMouseInternal(data->xwindow, x, y);
325 }
326 
327 static int
328 X11_WarpMouseGlobal(int x, int y)
329 {
330  WarpMouseInternal(DefaultRootWindow(GetDisplay()), x, y);
331  return 0;
332 }
333 
334 static int
335 X11_SetRelativeMouseMode(SDL_bool enabled)
336 {
337 #if SDL_VIDEO_DRIVER_X11_XINPUT2
339  return 0;
340 #else
341  SDL_Unsupported();
342 #endif
343  return -1;
344 }
345 
346 static int
347 X11_CaptureMouse(SDL_Window *window)
348 {
349  Display *display = GetDisplay();
350 
351  if (window) {
352  SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
353  const unsigned int mask = ButtonPressMask | ButtonReleaseMask | PointerMotionMask | FocusChangeMask;
354  const int rc = X11_XGrabPointer(display, data->xwindow, False,
355  mask, GrabModeAsync, GrabModeAsync,
356  None, None, CurrentTime);
357  if (rc != GrabSuccess) {
358  return SDL_SetError("X server refused mouse capture");
359  }
360  } else {
361  X11_XUngrabPointer(display, CurrentTime);
362  }
363 
364  X11_XSync(display, False);
365 
366  return 0;
367 }
368 
369 static Uint32
370 X11_GetGlobalMouseState(int *x, int *y)
371 {
373  Display *display = GetDisplay();
374  const int num_screens = SDL_GetNumVideoDisplays();
375  int i;
376 
377  /* !!! FIXME: should we XSync() here first? */
378 
379 #if !SDL_VIDEO_DRIVER_X11_XINPUT2
380  videodata->global_mouse_changed = SDL_TRUE;
381 #endif
382 
383  /* check if we have this cached since XInput last saw the mouse move. */
384  /* !!! FIXME: can we just calculate this from XInput's events? */
385  if (videodata->global_mouse_changed) {
386  for (i = 0; i < num_screens; i++) {
388  if (data != NULL) {
389  Window root, child;
390  int rootx, rooty, winx, winy;
391  unsigned int mask;
392  if (X11_XQueryPointer(display, RootWindow(display, data->screen), &root, &child, &rootx, &rooty, &winx, &winy, &mask)) {
393  XWindowAttributes root_attrs;
394  Uint32 buttons = 0;
395  buttons |= (mask & Button1Mask) ? SDL_BUTTON_LMASK : 0;
396  buttons |= (mask & Button2Mask) ? SDL_BUTTON_MMASK : 0;
397  buttons |= (mask & Button3Mask) ? SDL_BUTTON_RMASK : 0;
398  /* SDL_DisplayData->x,y point to screen origin, and adding them to mouse coordinates relative to root window doesn't do the right thing
399  * (observed on dual monitor setup with primary display being the rightmost one - mouse was offset to the right).
400  *
401  * Adding root position to root-relative coordinates seems to be a better way to get absolute position. */
402  X11_XGetWindowAttributes(display, root, &root_attrs);
403  videodata->global_mouse_position.x = root_attrs.x + rootx;
404  videodata->global_mouse_position.y = root_attrs.y + rooty;
405  videodata->global_mouse_buttons = buttons;
406  videodata->global_mouse_changed = SDL_FALSE;
407  break;
408  }
409  }
410  }
411  }
412 
413  SDL_assert(!videodata->global_mouse_changed); /* The pointer wasn't on any X11 screen?! */
414 
415  *x = videodata->global_mouse_position.x;
416  *y = videodata->global_mouse_position.y;
417  return videodata->global_mouse_buttons;
418 }
419 
420 
421 void
423 {
424  SDL_Mouse *mouse = SDL_GetMouse();
425 
426  mouse->CreateCursor = X11_CreateCursor;
427  mouse->CreateSystemCursor = X11_CreateSystemCursor;
428  mouse->ShowCursor = X11_ShowCursor;
429  mouse->FreeCursor = X11_FreeCursor;
430  mouse->WarpMouse = X11_WarpMouse;
431  mouse->WarpMouseGlobal = X11_WarpMouseGlobal;
432  mouse->SetRelativeMouseMode = X11_SetRelativeMouseMode;
433  mouse->CaptureMouse = X11_CaptureMouse;
434  mouse->GetGlobalMouseState = X11_GetGlobalMouseState;
435 
436  SDL_SetDefaultCursor(X11_CreateDefaultCursor());
437 }
438 
439 void
441 {
442  X11_DestroyEmptyCursor();
443 }
444 
445 #endif /* SDL_VIDEO_DRIVER_X11 */
446 
447 /* vi: set ts=4 sw=4 expandtab: */
#define _THIS
#define SDL_assert(condition)
Definition: SDL_assert.h:171
#define SDL_SetError
#define SDL_free
#define SDL_memcpy
#define SDL_GetNumVideoDisplays
#define SDL_calloc
#define SDL_OutOfMemory()
Definition: SDL_error.h:88
#define SDL_Unsupported()
Definition: SDL_error.h:89
const GLubyte GLuint red
Definition: SDL_glfuncs.h:80
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
SDL_Mouse * SDL_GetMouse(void)
Definition: SDL_mouse.c:175
void SDL_SetDefaultCursor(SDL_Cursor *cursor)
Definition: SDL_mouse.c:164
SDL_SystemCursor
Cursor types for SDL_CreateSystemCursor().
Definition: SDL_mouse.h:47
@ SDL_SYSTEM_CURSOR_SIZENS
Definition: SDL_mouse.h:56
@ SDL_SYSTEM_CURSOR_HAND
Definition: SDL_mouse.h:59
@ SDL_SYSTEM_CURSOR_ARROW
Definition: SDL_mouse.h:48
@ SDL_SYSTEM_CURSOR_SIZENWSE
Definition: SDL_mouse.h:53
@ SDL_SYSTEM_CURSOR_SIZENESW
Definition: SDL_mouse.h:54
@ SDL_SYSTEM_CURSOR_IBEAM
Definition: SDL_mouse.h:49
@ SDL_SYSTEM_CURSOR_NO
Definition: SDL_mouse.h:58
@ SDL_SYSTEM_CURSOR_WAITARROW
Definition: SDL_mouse.h:52
@ SDL_SYSTEM_CURSOR_SIZEALL
Definition: SDL_mouse.h:57
@ SDL_SYSTEM_CURSOR_WAIT
Definition: SDL_mouse.h:50
@ SDL_SYSTEM_CURSOR_SIZEWE
Definition: SDL_mouse.h:55
@ SDL_SYSTEM_CURSOR_CROSSHAIR
Definition: SDL_mouse.h:51
#define SDL_BUTTON_MMASK
Definition: SDL_mouse.h:288
#define SDL_BUTTON_LMASK
Definition: SDL_mouse.h:287
#define SDL_BUTTON_RMASK
Definition: SDL_mouse.h:289
GLeglImageOES image
Definition: SDL_opengl.h:2148
GLint GLint GLint GLint GLint GLint y
Definition: SDL_opengl.h:1574
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1974
GLint GLint GLint GLint GLint x
Definition: SDL_opengl.h:1574
GLenum GLenum GLsizei const GLuint GLboolean enabled
GLbyte GLbyte blue
GLuint color
GLfloat GLfloat GLfloat alpha
GLbyte green
GLenum GLint GLuint mask
@ SDL_PIXELFORMAT_ARGB8888
Definition: SDL_pixels.h:257
#define SDL_zeroa(x)
Definition: SDL_stdinc.h:428
SDL_bool
Definition: SDL_stdinc.h:168
@ SDL_TRUE
Definition: SDL_stdinc.h:170
@ SDL_FALSE
Definition: SDL_stdinc.h:169
uint8_t Uint8
Definition: SDL_stdinc.h:185
uint32_t Uint32
Definition: SDL_stdinc.h:209
void * SDL_GetDisplayDriverData(int displayIndex)
Definition: SDL_video.c:680
SDL_VideoDevice * SDL_GetVideoDevice(void)
Definition: SDL_video.c:587
void X11_QuitMouse(_THIS)
void X11_InitMouse(_THIS)
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
int X11_Xinput2IsInitialized(void)
#define NULL
Definition: begin_code.h:163
EGLSurface surface
Definition: eglext.h:248
EGLSurface EGLNativeWindowType * window
Definition: eglext.h:1025
EGLConfig struct EGLClientPixmapHI * pixmap
Definition: eglext.h:899
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp *numpix else pixst endif endm macro pixld1_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl else error unsupported endif endm macro pixld2_s mem_operand if mov asr add asl add asl mov asr sub UNIT_X add asl mov asr add asl add asl mov asr add UNIT_X add asl else pixld1_s mem_operand pixld1_s mem_operand endif endm macro pixld0_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl endif endm macro pixld_s_internal mem_operand if mem_operand pixld2_s mem_operand pixdeinterleave basereg elseif mem_operand elseif mem_operand elseif mem_operand elseif mem_operand pixld0_s mem_operand else pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else error unsupported mem_operand if bpp mem_operand endif endm macro vuzp8 reg2 vuzp d d &reg2 endm macro vzip8 reg2 vzip d d &reg2 endm macro pixdeinterleave basereg basereg basereg basereg basereg endif endm macro pixinterleave basereg basereg basereg basereg basereg endif endm macro PF boost_increment endif if endif PF tst PF addne PF subne PF cmp ORIG_W if endif if endif if endif PF subge ORIG_W PF subges if endif if endif if endif endif endm macro cache_preload_simple endif if dst_r_bpp pld[DST_R, #(PREFETCH_DISTANCE_SIMPLE *dst_r_bpp/8)] endif if mask_bpp pld if[MASK, #(PREFETCH_DISTANCE_SIMPLE *mask_bpp/8)] endif endif endm macro fetch_mask_pixblock pixld mask_basereg pixblock_size MASK endm macro ensure_destination_ptr_alignment process_pixblock_tail_head if beq irp skip1(dst_w_bpp<=(lowbit *8)) &&((lowbit *8)<(pixblock_size *dst_w_bpp)) .if lowbit< 16 tst DST_R
set set set set set set set set set set set set set set set set set set set set *set set set macro pixldst op &r &cond WK op &r &cond WK op &r &cond WK else op &m &cond &ia op &r &cond WK else op &m &cond &ia elseif elseif else error unsupported base if elseif elseif else error unsupported unaligned pixldst unaligned endm macro pixst base base else pixldst base endif endm macro PF ptr
void * driverdata
Definition: SDL_mouse_c.h:33
int(* SetRelativeMouseMode)(SDL_bool enabled)
Definition: SDL_mouse_c.h:67
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
int(* WarpMouseGlobal)(int x, int y)
Definition: SDL_mouse_c.h:64
SDL_Cursor *(* CreateSystemCursor)(SDL_SystemCursor id)
Definition: SDL_mouse_c.h:49
Uint32(* GetGlobalMouseState)(int *x, int *y)
Definition: SDL_mouse_c.h:73
int(* CaptureMouse)(SDL_Window *window)
Definition: SDL_mouse_c.h:70
int x
Definition: SDL_rect.h:50
int y
Definition: SDL_rect.h:51
A collection of pixels used in software blitting.
Definition: SDL_surface.h:71
Uint32 global_mouse_buttons
Definition: SDL_x11video.h:135
struct wl_display * display
SDL_bool global_mouse_changed
Definition: SDL_x11video.h:133
SDL_Point global_mouse_position
Definition: SDL_x11video.h:134
SDL_Window * windows
Definition: SDL_sysvideo.h:327
The type used to identify a window.
Definition: SDL_sysvideo.h:75
SDL_Window * next
Definition: SDL_sysvideo.h:115
SDL_Cursor * cursor
Definition: testwm2.c:40