Mercurial > sdl-ios-xcode
annotate src/video/x11/SDL_x11mouse.c @ 3958:85b6fb6a5e3c SDL-1.2
Actually, this is a better fix...clear the error state once if everything we
need loaded; it's more efficient, and works even if the last unnecessary
xrandr symbol failed to load. Otherwise, leave the original loadso error, so
the end user can find out what symbol failed.
author | Ryan C. Gordon <icculus@icculus.org> |
---|---|
date | Wed, 13 Jun 2007 08:00:10 +0000 |
parents | 79a4c9017550 |
children | a1b03ba2fcd0 |
rev | line source |
---|---|
0 | 1 /* |
2 SDL - Simple DirectMedia Layer | |
1312
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
1168
diff
changeset
|
3 Copyright (C) 1997-2006 Sam Lantinga |
0 | 4 |
5 This library is free software; you can redistribute it and/or | |
1312
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
1168
diff
changeset
|
6 modify it under the terms of the GNU Lesser General Public |
0 | 7 License as published by the Free Software Foundation; either |
1312
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
1168
diff
changeset
|
8 version 2.1 of the License, or (at your option) any later version. |
0 | 9 |
10 This library is distributed in the hope that it will be useful, | |
11 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
1312
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
1168
diff
changeset
|
13 Lesser General Public License for more details. |
0 | 14 |
1312
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
1168
diff
changeset
|
15 You should have received a copy of the GNU Lesser General Public |
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
1168
diff
changeset
|
16 License along with this library; if not, write to the Free Software |
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
1168
diff
changeset
|
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
0 | 18 |
19 Sam Lantinga | |
252
e8157fcb3114
Updated the source with the correct e-mail address
Sam Lantinga <slouken@libsdl.org>
parents:
80
diff
changeset
|
20 slouken@libsdl.org |
0 | 21 */ |
1402
d910939febfa
Use consistent identifiers for the various platforms we support.
Sam Lantinga <slouken@libsdl.org>
parents:
1379
diff
changeset
|
22 #include "SDL_config.h" |
0 | 23 |
24 #include <X11/Xlib.h> | |
25 #include <X11/Xutil.h> | |
26 | |
27 #include "SDL_mouse.h" | |
1361
19418e4422cb
New configure-based build system. Still work in progress, but much improved
Sam Lantinga <slouken@libsdl.org>
parents:
1358
diff
changeset
|
28 #include "../../events/SDL_events_c.h" |
19418e4422cb
New configure-based build system. Still work in progress, but much improved
Sam Lantinga <slouken@libsdl.org>
parents:
1358
diff
changeset
|
29 #include "../SDL_cursor_c.h" |
0 | 30 #include "SDL_x11dga_c.h" |
31 #include "SDL_x11mouse_c.h" | |
32 | |
33 | |
34 /* The implementation dependent data for the window manager cursor */ | |
35 struct WMcursor { | |
36 Cursor x_cursor; | |
37 }; | |
38 | |
39 | |
40 void X11_FreeWMCursor(_THIS, WMcursor *cursor) | |
41 { | |
42 if ( SDL_Display != NULL ) { | |
43 SDL_Lock_EventThread(); | |
1575
3ba88cb7eb1b
Updated dynamic X11 code. See details in Bugzilla #170.
Ryan C. Gordon <icculus@icculus.org>
parents:
1402
diff
changeset
|
44 XFreeCursor(SDL_Display, cursor->x_cursor); |
3ba88cb7eb1b
Updated dynamic X11 code. See details in Bugzilla #170.
Ryan C. Gordon <icculus@icculus.org>
parents:
1402
diff
changeset
|
45 XSync(SDL_Display, False); |
0 | 46 SDL_Unlock_EventThread(); |
47 } | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
48 SDL_free(cursor); |
0 | 49 } |
50 | |
51 WMcursor *X11_CreateWMCursor(_THIS, | |
52 Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y) | |
53 { | |
54 WMcursor *cursor; | |
55 XGCValues GCvalues; | |
56 GC GCcursor; | |
57 XImage *data_image, *mask_image; | |
58 Pixmap data_pixmap, mask_pixmap; | |
59 int clen, i; | |
60 char *x_data, *x_mask; | |
61 static XColor black = { 0, 0, 0, 0 }; | |
62 static XColor white = { 0xffff, 0xffff, 0xffff, 0xffff }; | |
63 | |
64 /* Allocate the cursor memory */ | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
65 cursor = (WMcursor *)SDL_malloc(sizeof(WMcursor)); |
0 | 66 if ( cursor == NULL ) { |
67 SDL_OutOfMemory(); | |
68 return(NULL); | |
69 } | |
70 | |
71 /* Mix the mask and the data */ | |
72 clen = (w/8)*h; | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
73 x_data = (char *)SDL_malloc(clen); |
0 | 74 if ( x_data == NULL ) { |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
75 SDL_free(cursor); |
0 | 76 SDL_OutOfMemory(); |
77 return(NULL); | |
78 } | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
79 x_mask = (char *)SDL_malloc(clen); |
0 | 80 if ( x_mask == NULL ) { |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
81 SDL_free(cursor); |
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
82 SDL_free(x_data); |
0 | 83 SDL_OutOfMemory(); |
84 return(NULL); | |
85 } | |
86 for ( i=0; i<clen; ++i ) { | |
87 /* The mask is OR'd with the data to turn inverted color | |
88 pixels black since inverted color cursors aren't supported | |
89 under X11. | |
90 */ | |
91 x_mask[i] = data[i] | mask[i]; | |
92 x_data[i] = data[i]; | |
93 } | |
94 | |
95 /* Prevent the event thread from running while we use the X server */ | |
96 SDL_Lock_EventThread(); | |
97 | |
98 /* Create the data image */ | |
1575
3ba88cb7eb1b
Updated dynamic X11 code. See details in Bugzilla #170.
Ryan C. Gordon <icculus@icculus.org>
parents:
1402
diff
changeset
|
99 data_image = XCreateImage(SDL_Display, |
0 | 100 DefaultVisual(SDL_Display, SDL_Screen), |
101 1, XYBitmap, 0, x_data, w, h, 8, w/8); | |
102 data_image->byte_order = MSBFirst; | |
103 data_image->bitmap_bit_order = MSBFirst; | |
1575
3ba88cb7eb1b
Updated dynamic X11 code. See details in Bugzilla #170.
Ryan C. Gordon <icculus@icculus.org>
parents:
1402
diff
changeset
|
104 data_pixmap = XCreatePixmap(SDL_Display, SDL_Root, w, h, 1); |
0 | 105 |
106 /* Create the data mask */ | |
1575
3ba88cb7eb1b
Updated dynamic X11 code. See details in Bugzilla #170.
Ryan C. Gordon <icculus@icculus.org>
parents:
1402
diff
changeset
|
107 mask_image = XCreateImage(SDL_Display, |
0 | 108 DefaultVisual(SDL_Display, SDL_Screen), |
109 1, XYBitmap, 0, x_mask, w, h, 8, w/8); | |
110 mask_image->byte_order = MSBFirst; | |
111 mask_image->bitmap_bit_order = MSBFirst; | |
1575
3ba88cb7eb1b
Updated dynamic X11 code. See details in Bugzilla #170.
Ryan C. Gordon <icculus@icculus.org>
parents:
1402
diff
changeset
|
112 mask_pixmap = XCreatePixmap(SDL_Display, SDL_Root, w, h, 1); |
0 | 113 |
114 /* Create the graphics context */ | |
115 GCvalues.function = GXcopy; | |
116 GCvalues.foreground = ~0; | |
117 GCvalues.background = 0; | |
118 GCvalues.plane_mask = AllPlanes; | |
1575
3ba88cb7eb1b
Updated dynamic X11 code. See details in Bugzilla #170.
Ryan C. Gordon <icculus@icculus.org>
parents:
1402
diff
changeset
|
119 GCcursor = XCreateGC(SDL_Display, data_pixmap, |
0 | 120 (GCFunction|GCForeground|GCBackground|GCPlaneMask), |
121 &GCvalues); | |
122 | |
123 /* Blit the images to the pixmaps */ | |
1575
3ba88cb7eb1b
Updated dynamic X11 code. See details in Bugzilla #170.
Ryan C. Gordon <icculus@icculus.org>
parents:
1402
diff
changeset
|
124 XPutImage(SDL_Display, data_pixmap, GCcursor, data_image, |
0 | 125 0, 0, 0, 0, w, h); |
1575
3ba88cb7eb1b
Updated dynamic X11 code. See details in Bugzilla #170.
Ryan C. Gordon <icculus@icculus.org>
parents:
1402
diff
changeset
|
126 XPutImage(SDL_Display, mask_pixmap, GCcursor, mask_image, |
0 | 127 0, 0, 0, 0, w, h); |
1575
3ba88cb7eb1b
Updated dynamic X11 code. See details in Bugzilla #170.
Ryan C. Gordon <icculus@icculus.org>
parents:
1402
diff
changeset
|
128 XFreeGC(SDL_Display, GCcursor); |
0 | 129 /* These free the x_data and x_mask memory pointers */ |
1575
3ba88cb7eb1b
Updated dynamic X11 code. See details in Bugzilla #170.
Ryan C. Gordon <icculus@icculus.org>
parents:
1402
diff
changeset
|
130 XDestroyImage(data_image); |
3ba88cb7eb1b
Updated dynamic X11 code. See details in Bugzilla #170.
Ryan C. Gordon <icculus@icculus.org>
parents:
1402
diff
changeset
|
131 XDestroyImage(mask_image); |
0 | 132 |
133 /* Create the cursor */ | |
1575
3ba88cb7eb1b
Updated dynamic X11 code. See details in Bugzilla #170.
Ryan C. Gordon <icculus@icculus.org>
parents:
1402
diff
changeset
|
134 cursor->x_cursor = XCreatePixmapCursor(SDL_Display, data_pixmap, |
0 | 135 mask_pixmap, &black, &white, hot_x, hot_y); |
1575
3ba88cb7eb1b
Updated dynamic X11 code. See details in Bugzilla #170.
Ryan C. Gordon <icculus@icculus.org>
parents:
1402
diff
changeset
|
136 XFreePixmap(SDL_Display, data_pixmap); |
3ba88cb7eb1b
Updated dynamic X11 code. See details in Bugzilla #170.
Ryan C. Gordon <icculus@icculus.org>
parents:
1402
diff
changeset
|
137 XFreePixmap(SDL_Display, mask_pixmap); |
0 | 138 |
139 /* Release the event thread */ | |
1575
3ba88cb7eb1b
Updated dynamic X11 code. See details in Bugzilla #170.
Ryan C. Gordon <icculus@icculus.org>
parents:
1402
diff
changeset
|
140 XSync(SDL_Display, False); |
0 | 141 SDL_Unlock_EventThread(); |
142 | |
143 return(cursor); | |
144 } | |
145 | |
146 int X11_ShowWMCursor(_THIS, WMcursor *cursor) | |
147 { | |
148 /* Don't do anything if the display is gone */ | |
149 if ( SDL_Display == NULL ) { | |
150 return(0); | |
151 } | |
152 | |
153 /* Set the X11 cursor cursor, or blank if cursor is NULL */ | |
154 if ( SDL_Window ) { | |
155 SDL_Lock_EventThread(); | |
156 if ( cursor == NULL ) { | |
157 if ( SDL_BlankCursor != NULL ) { | |
1575
3ba88cb7eb1b
Updated dynamic X11 code. See details in Bugzilla #170.
Ryan C. Gordon <icculus@icculus.org>
parents:
1402
diff
changeset
|
158 XDefineCursor(SDL_Display, SDL_Window, |
0 | 159 SDL_BlankCursor->x_cursor); |
160 } | |
161 } else { | |
1575
3ba88cb7eb1b
Updated dynamic X11 code. See details in Bugzilla #170.
Ryan C. Gordon <icculus@icculus.org>
parents:
1402
diff
changeset
|
162 XDefineCursor(SDL_Display, SDL_Window, cursor->x_cursor); |
0 | 163 } |
1575
3ba88cb7eb1b
Updated dynamic X11 code. See details in Bugzilla #170.
Ryan C. Gordon <icculus@icculus.org>
parents:
1402
diff
changeset
|
164 XSync(SDL_Display, False); |
0 | 165 SDL_Unlock_EventThread(); |
166 } | |
167 return(1); | |
168 } | |
169 | |
170 void X11_WarpWMCursor(_THIS, Uint16 x, Uint16 y) | |
171 { | |
172 if ( using_dga & DGA_MOUSE ) { | |
527
5c74ac147358
Fixed mouse warp position bug with offset video modes
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
173 SDL_PrivateMouseMotion(0, 0, x, y); |
5c74ac147358
Fixed mouse warp position bug with offset video modes
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
174 } else if ( mouse_relative) { |
5c74ac147358
Fixed mouse warp position bug with offset video modes
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
175 /* RJR: March 28, 2000 |
5c74ac147358
Fixed mouse warp position bug with offset video modes
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
176 leave physical cursor at center of screen if |
5c74ac147358
Fixed mouse warp position bug with offset video modes
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
177 mouse hidden and grabbed */ |
0 | 178 SDL_PrivateMouseMotion(0, 0, x, y); |
179 } else { | |
180 SDL_Lock_EventThread(); | |
1575
3ba88cb7eb1b
Updated dynamic X11 code. See details in Bugzilla #170.
Ryan C. Gordon <icculus@icculus.org>
parents:
1402
diff
changeset
|
181 XWarpPointer(SDL_Display, None, SDL_Window, 0, 0, 0, 0, x, y); |
3ba88cb7eb1b
Updated dynamic X11 code. See details in Bugzilla #170.
Ryan C. Gordon <icculus@icculus.org>
parents:
1402
diff
changeset
|
182 XSync(SDL_Display, False); |
0 | 183 SDL_Unlock_EventThread(); |
184 } | |
185 } | |
186 | |
187 /* Sets the mouse acceleration from a string of the form: | |
188 2/1/0 | |
189 The first number is the numerator, followed by the acceleration | |
190 denumenator and threshold. | |
191 */ | |
192 static void SetMouseAccel(_THIS, const char *accel_param) | |
193 { | |
194 int i; | |
1379
c0a74f199ecf
Use only safe string functions
Sam Lantinga <slouken@libsdl.org>
parents:
1361
diff
changeset
|
195 size_t len; |
0 | 196 int accel_value[3]; |
197 char *mouse_param, *mouse_param_buf, *pin; | |
198 | |
1379
c0a74f199ecf
Use only safe string functions
Sam Lantinga <slouken@libsdl.org>
parents:
1361
diff
changeset
|
199 len = SDL_strlen(accel_param)+1; |
c0a74f199ecf
Use only safe string functions
Sam Lantinga <slouken@libsdl.org>
parents:
1361
diff
changeset
|
200 mouse_param_buf = SDL_stack_alloc(char, len); |
0 | 201 if ( ! mouse_param_buf ) { |
202 return; | |
203 } | |
1379
c0a74f199ecf
Use only safe string functions
Sam Lantinga <slouken@libsdl.org>
parents:
1361
diff
changeset
|
204 SDL_strlcpy(mouse_param_buf, accel_param, len); |
0 | 205 mouse_param = mouse_param_buf; |
206 | |
207 for ( i=0; (i < 3) && mouse_param; ++i ) { | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
208 pin = SDL_strchr(mouse_param, '/'); |
0 | 209 if ( pin ) { |
210 *pin = '\0'; | |
211 } | |
212 accel_value[i] = atoi(mouse_param); | |
213 if ( pin ) { | |
214 mouse_param = pin+1; | |
215 } else { | |
216 mouse_param = NULL; | |
217 } | |
218 } | |
3930
79a4c9017550
Fixed buggy SDL_VIDEO_X11_MOUSEACCEL behaviour...correctly free buffer, and
Ryan C. Gordon <icculus@icculus.org>
parents:
1740
diff
changeset
|
219 if ( i == 3 ) { |
1575
3ba88cb7eb1b
Updated dynamic X11 code. See details in Bugzilla #170.
Ryan C. Gordon <icculus@icculus.org>
parents:
1402
diff
changeset
|
220 XChangePointerControl(SDL_Display, True, True, |
0 | 221 accel_value[0], accel_value[1], accel_value[2]); |
222 } | |
3930
79a4c9017550
Fixed buggy SDL_VIDEO_X11_MOUSEACCEL behaviour...correctly free buffer, and
Ryan C. Gordon <icculus@icculus.org>
parents:
1740
diff
changeset
|
223 SDL_stack_free(mouse_param_buf); |
0 | 224 } |
225 | |
226 /* Check to see if we need to enter or leave mouse relative mode */ | |
227 void X11_CheckMouseModeNoLock(_THIS) | |
228 { | |
1740 | 229 const Uint8 full_focus = (SDL_APPACTIVE|SDL_APPINPUTFOCUS|SDL_APPMOUSEFOCUS); |
79
ffadd05de74d
Allow the user to override the relative mouse mode.
Sam Lantinga <slouken@lokigames.com>
parents:
78
diff
changeset
|
230 char *env_override; |
ffadd05de74d
Allow the user to override the relative mouse mode.
Sam Lantinga <slouken@lokigames.com>
parents:
78
diff
changeset
|
231 int enable_relative = 1; |
ffadd05de74d
Allow the user to override the relative mouse mode.
Sam Lantinga <slouken@lokigames.com>
parents:
78
diff
changeset
|
232 |
ffadd05de74d
Allow the user to override the relative mouse mode.
Sam Lantinga <slouken@lokigames.com>
parents:
78
diff
changeset
|
233 /* Allow the user to override the relative mouse mode. |
ffadd05de74d
Allow the user to override the relative mouse mode.
Sam Lantinga <slouken@lokigames.com>
parents:
78
diff
changeset
|
234 They almost never want to do this, as it seriously affects |
ffadd05de74d
Allow the user to override the relative mouse mode.
Sam Lantinga <slouken@lokigames.com>
parents:
78
diff
changeset
|
235 applications that rely on continuous relative mouse motion. |
ffadd05de74d
Allow the user to override the relative mouse mode.
Sam Lantinga <slouken@lokigames.com>
parents:
78
diff
changeset
|
236 */ |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
237 env_override = SDL_getenv("SDL_MOUSE_RELATIVE"); |
79
ffadd05de74d
Allow the user to override the relative mouse mode.
Sam Lantinga <slouken@lokigames.com>
parents:
78
diff
changeset
|
238 if ( env_override ) { |
ffadd05de74d
Allow the user to override the relative mouse mode.
Sam Lantinga <slouken@lokigames.com>
parents:
78
diff
changeset
|
239 enable_relative = atoi(env_override); |
ffadd05de74d
Allow the user to override the relative mouse mode.
Sam Lantinga <slouken@lokigames.com>
parents:
78
diff
changeset
|
240 } |
ffadd05de74d
Allow the user to override the relative mouse mode.
Sam Lantinga <slouken@lokigames.com>
parents:
78
diff
changeset
|
241 |
0 | 242 /* If the mouse is hidden and input is grabbed, we use relative mode */ |
79
ffadd05de74d
Allow the user to override the relative mouse mode.
Sam Lantinga <slouken@lokigames.com>
parents:
78
diff
changeset
|
243 if ( enable_relative && |
ffadd05de74d
Allow the user to override the relative mouse mode.
Sam Lantinga <slouken@lokigames.com>
parents:
78
diff
changeset
|
244 !(SDL_cursorstate & CURSOR_VISIBLE) && |
0 | 245 (this->input_grab != SDL_GRAB_OFF) && |
1740 | 246 (SDL_GetAppState() & full_focus) == full_focus ) { |
0 | 247 if ( ! mouse_relative ) { |
248 X11_EnableDGAMouse(this); | |
249 if ( ! (using_dga & DGA_MOUSE) ) { | |
250 char *xmouse_accel; | |
251 | |
252 SDL_GetMouseState(&mouse_last.x, &mouse_last.y); | |
253 /* Use as raw mouse mickeys as possible */ | |
1575
3ba88cb7eb1b
Updated dynamic X11 code. See details in Bugzilla #170.
Ryan C. Gordon <icculus@icculus.org>
parents:
1402
diff
changeset
|
254 XGetPointerControl(SDL_Display, |
0 | 255 &mouse_accel.numerator, |
256 &mouse_accel.denominator, | |
257 &mouse_accel.threshold); | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
258 xmouse_accel=SDL_getenv("SDL_VIDEO_X11_MOUSEACCEL"); |
0 | 259 if ( xmouse_accel ) { |
260 SetMouseAccel(this, xmouse_accel); | |
261 } | |
262 } | |
263 mouse_relative = 1; | |
264 } | |
265 } else { | |
266 if ( mouse_relative ) { | |
267 if ( using_dga & DGA_MOUSE ) { | |
268 X11_DisableDGAMouse(this); | |
269 } else { | |
1575
3ba88cb7eb1b
Updated dynamic X11 code. See details in Bugzilla #170.
Ryan C. Gordon <icculus@icculus.org>
parents:
1402
diff
changeset
|
270 XChangePointerControl(SDL_Display, True, True, |
0 | 271 mouse_accel.numerator, |
272 mouse_accel.denominator, | |
273 mouse_accel.threshold); | |
274 } | |
275 mouse_relative = 0; | |
276 } | |
277 } | |
278 } | |
279 void X11_CheckMouseMode(_THIS) | |
280 { | |
281 SDL_Lock_EventThread(); | |
282 X11_CheckMouseModeNoLock(this); | |
283 SDL_Unlock_EventThread(); | |
284 } |