Mercurial > sdl-ios-xcode
annotate src/video/x11/SDL_x11mouse.c @ 1248:d2c6881935be
Catch X11 extension errors...since most of these are notifications that we
queried for a missing extension (such as the XiG vidmode one that most
people don't have), and default Xlib behaviour is to write notification to
stderr, this tends to generate incorrect bug reports.
Since we'll actually deal with the missing extension when querying for it,
we ignore these errors in our hook. The rest continue to pass through to
the default handler.
Fixes Bugzilla #42.
--ryan.
author | Ryan C. Gordon <icculus@icculus.org> |
---|---|
date | Sat, 14 Jan 2006 08:15:38 +0000 |
parents | 045f186426e1 |
children | c9b51268668f |
rev | line source |
---|---|
0 | 1 /* |
2 SDL - Simple DirectMedia Layer | |
769
b8d311d90021
Updated copyright information for 2004 (Happy New Year!)
Sam Lantinga <slouken@libsdl.org>
parents:
527
diff
changeset
|
3 Copyright (C) 1997-2004 Sam Lantinga |
0 | 4 |
5 This library is free software; you can redistribute it and/or | |
6 modify it under the terms of the GNU Library General Public | |
7 License as published by the Free Software Foundation; either | |
8 version 2 of the License, or (at your option) any later version. | |
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 | |
13 Library General Public License for more details. | |
14 | |
15 You should have received a copy of the GNU Library General Public | |
16 License along with this library; if not, write to the Free | |
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
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 */ |
22 | |
23 #ifdef SAVE_RCSID | |
24 static char rcsid = | |
25 "@(#) $Id$"; | |
26 #endif | |
27 | |
28 #include <stdlib.h> | |
29 #include <stdio.h> | |
30 #include <string.h> | |
31 | |
32 #include <X11/Xlib.h> | |
33 #include <X11/Xutil.h> | |
34 | |
35 #include "SDL_error.h" | |
36 #include "SDL_mouse.h" | |
37 #include "SDL_events_c.h" | |
38 #include "SDL_cursor_c.h" | |
39 #include "SDL_x11dga_c.h" | |
40 #include "SDL_x11mouse_c.h" | |
41 | |
42 | |
43 /* The implementation dependent data for the window manager cursor */ | |
44 struct WMcursor { | |
45 Cursor x_cursor; | |
46 }; | |
47 | |
48 | |
49 void X11_FreeWMCursor(_THIS, WMcursor *cursor) | |
50 { | |
51 if ( SDL_Display != NULL ) { | |
52 SDL_Lock_EventThread(); | |
1168
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
888
diff
changeset
|
53 pXFreeCursor(SDL_Display, cursor->x_cursor); |
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
888
diff
changeset
|
54 pXSync(SDL_Display, False); |
0 | 55 SDL_Unlock_EventThread(); |
56 } | |
57 free(cursor); | |
58 } | |
59 | |
60 WMcursor *X11_CreateWMCursor(_THIS, | |
61 Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y) | |
62 { | |
63 WMcursor *cursor; | |
64 XGCValues GCvalues; | |
65 GC GCcursor; | |
66 XImage *data_image, *mask_image; | |
67 Pixmap data_pixmap, mask_pixmap; | |
68 int clen, i; | |
69 char *x_data, *x_mask; | |
70 static XColor black = { 0, 0, 0, 0 }; | |
71 static XColor white = { 0xffff, 0xffff, 0xffff, 0xffff }; | |
72 | |
73 /* Allocate the cursor memory */ | |
74 cursor = (WMcursor *)malloc(sizeof(WMcursor)); | |
75 if ( cursor == NULL ) { | |
76 SDL_OutOfMemory(); | |
77 return(NULL); | |
78 } | |
79 | |
80 /* Mix the mask and the data */ | |
81 clen = (w/8)*h; | |
82 x_data = (char *)malloc(clen); | |
83 if ( x_data == NULL ) { | |
84 free(cursor); | |
85 SDL_OutOfMemory(); | |
86 return(NULL); | |
87 } | |
88 x_mask = (char *)malloc(clen); | |
89 if ( x_mask == NULL ) { | |
90 free(cursor); | |
91 free(x_data); | |
92 SDL_OutOfMemory(); | |
93 return(NULL); | |
94 } | |
95 for ( i=0; i<clen; ++i ) { | |
96 /* The mask is OR'd with the data to turn inverted color | |
97 pixels black since inverted color cursors aren't supported | |
98 under X11. | |
99 */ | |
100 x_mask[i] = data[i] | mask[i]; | |
101 x_data[i] = data[i]; | |
102 } | |
103 | |
104 /* Prevent the event thread from running while we use the X server */ | |
105 SDL_Lock_EventThread(); | |
106 | |
107 /* Create the data image */ | |
1168
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
888
diff
changeset
|
108 data_image = pXCreateImage(SDL_Display, |
0 | 109 DefaultVisual(SDL_Display, SDL_Screen), |
110 1, XYBitmap, 0, x_data, w, h, 8, w/8); | |
111 data_image->byte_order = MSBFirst; | |
112 data_image->bitmap_bit_order = MSBFirst; | |
1168
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
888
diff
changeset
|
113 data_pixmap = pXCreatePixmap(SDL_Display, SDL_Root, w, h, 1); |
0 | 114 |
115 /* Create the data mask */ | |
1168
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
888
diff
changeset
|
116 mask_image = pXCreateImage(SDL_Display, |
0 | 117 DefaultVisual(SDL_Display, SDL_Screen), |
118 1, XYBitmap, 0, x_mask, w, h, 8, w/8); | |
119 mask_image->byte_order = MSBFirst; | |
120 mask_image->bitmap_bit_order = MSBFirst; | |
1168
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
888
diff
changeset
|
121 mask_pixmap = pXCreatePixmap(SDL_Display, SDL_Root, w, h, 1); |
0 | 122 |
123 /* Create the graphics context */ | |
124 GCvalues.function = GXcopy; | |
125 GCvalues.foreground = ~0; | |
126 GCvalues.background = 0; | |
127 GCvalues.plane_mask = AllPlanes; | |
1168
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
888
diff
changeset
|
128 GCcursor = pXCreateGC(SDL_Display, data_pixmap, |
0 | 129 (GCFunction|GCForeground|GCBackground|GCPlaneMask), |
130 &GCvalues); | |
131 | |
132 /* Blit the images to the pixmaps */ | |
1168
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
888
diff
changeset
|
133 pXPutImage(SDL_Display, data_pixmap, GCcursor, data_image, |
0 | 134 0, 0, 0, 0, w, h); |
1168
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
888
diff
changeset
|
135 pXPutImage(SDL_Display, mask_pixmap, GCcursor, mask_image, |
0 | 136 0, 0, 0, 0, w, h); |
1168
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
888
diff
changeset
|
137 pXFreeGC(SDL_Display, GCcursor); |
0 | 138 /* These free the x_data and x_mask memory pointers */ |
1168
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
888
diff
changeset
|
139 pXDestroyImage(data_image); |
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
888
diff
changeset
|
140 pXDestroyImage(mask_image); |
0 | 141 |
142 /* Create the cursor */ | |
1168
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
888
diff
changeset
|
143 cursor->x_cursor = pXCreatePixmapCursor(SDL_Display, data_pixmap, |
0 | 144 mask_pixmap, &black, &white, hot_x, hot_y); |
1168
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
888
diff
changeset
|
145 pXFreePixmap(SDL_Display, data_pixmap); |
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
888
diff
changeset
|
146 pXFreePixmap(SDL_Display, mask_pixmap); |
0 | 147 |
148 /* Release the event thread */ | |
1168
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
888
diff
changeset
|
149 pXSync(SDL_Display, False); |
0 | 150 SDL_Unlock_EventThread(); |
151 | |
152 return(cursor); | |
153 } | |
154 | |
155 int X11_ShowWMCursor(_THIS, WMcursor *cursor) | |
156 { | |
157 /* Don't do anything if the display is gone */ | |
158 if ( SDL_Display == NULL ) { | |
159 return(0); | |
160 } | |
161 | |
162 /* Set the X11 cursor cursor, or blank if cursor is NULL */ | |
163 if ( SDL_Window ) { | |
164 SDL_Lock_EventThread(); | |
165 if ( cursor == NULL ) { | |
166 if ( SDL_BlankCursor != NULL ) { | |
1168
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
888
diff
changeset
|
167 pXDefineCursor(SDL_Display, SDL_Window, |
0 | 168 SDL_BlankCursor->x_cursor); |
169 } | |
170 } else { | |
1168
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
888
diff
changeset
|
171 pXDefineCursor(SDL_Display, SDL_Window, cursor->x_cursor); |
0 | 172 } |
1168
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
888
diff
changeset
|
173 pXSync(SDL_Display, False); |
0 | 174 SDL_Unlock_EventThread(); |
175 } | |
176 return(1); | |
177 } | |
178 | |
179 void X11_WarpWMCursor(_THIS, Uint16 x, Uint16 y) | |
180 { | |
181 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
|
182 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
|
183 } else if ( mouse_relative) { |
5c74ac147358
Fixed mouse warp position bug with offset video modes
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
184 /* RJR: March 28, 2000 |
5c74ac147358
Fixed mouse warp position bug with offset video modes
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
185 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
|
186 mouse hidden and grabbed */ |
0 | 187 SDL_PrivateMouseMotion(0, 0, x, y); |
188 } else { | |
189 SDL_Lock_EventThread(); | |
1168
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
888
diff
changeset
|
190 pXWarpPointer(SDL_Display, None, SDL_Window, 0, 0, 0, 0, x, y); |
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
888
diff
changeset
|
191 pXSync(SDL_Display, False); |
0 | 192 SDL_Unlock_EventThread(); |
193 } | |
194 } | |
195 | |
196 /* Sets the mouse acceleration from a string of the form: | |
197 2/1/0 | |
198 The first number is the numerator, followed by the acceleration | |
199 denumenator and threshold. | |
200 */ | |
201 static void SetMouseAccel(_THIS, const char *accel_param) | |
202 { | |
203 int i; | |
204 int accel_value[3]; | |
205 char *mouse_param, *mouse_param_buf, *pin; | |
206 | |
207 mouse_param_buf = (char *)malloc(strlen(accel_param)+1); | |
208 if ( ! mouse_param_buf ) { | |
209 return; | |
210 } | |
211 strcpy(mouse_param_buf, accel_param); | |
212 mouse_param = mouse_param_buf; | |
213 | |
214 for ( i=0; (i < 3) && mouse_param; ++i ) { | |
215 pin = strchr(mouse_param, '/'); | |
216 if ( pin ) { | |
217 *pin = '\0'; | |
218 } | |
219 accel_value[i] = atoi(mouse_param); | |
220 if ( pin ) { | |
221 mouse_param = pin+1; | |
222 } else { | |
223 mouse_param = NULL; | |
224 } | |
225 } | |
226 if ( mouse_param_buf ) { | |
1168
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
888
diff
changeset
|
227 pXChangePointerControl(SDL_Display, True, True, |
0 | 228 accel_value[0], accel_value[1], accel_value[2]); |
229 free(mouse_param_buf); | |
230 } | |
231 } | |
232 | |
233 /* Check to see if we need to enter or leave mouse relative mode */ | |
234 void X11_CheckMouseModeNoLock(_THIS) | |
235 { | |
79
ffadd05de74d
Allow the user to override the relative mouse mode.
Sam Lantinga <slouken@lokigames.com>
parents:
78
diff
changeset
|
236 char *env_override; |
ffadd05de74d
Allow the user to override the relative mouse mode.
Sam Lantinga <slouken@lokigames.com>
parents:
78
diff
changeset
|
237 int enable_relative = 1; |
ffadd05de74d
Allow the user to override the relative mouse mode.
Sam Lantinga <slouken@lokigames.com>
parents:
78
diff
changeset
|
238 |
ffadd05de74d
Allow the user to override the relative mouse mode.
Sam Lantinga <slouken@lokigames.com>
parents:
78
diff
changeset
|
239 /* 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
|
240 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
|
241 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
|
242 */ |
80
8806bc1eb80e
Oops, reversed the logic of the variable
Sam Lantinga <slouken@lokigames.com>
parents:
79
diff
changeset
|
243 env_override = getenv("SDL_MOUSE_RELATIVE"); |
79
ffadd05de74d
Allow the user to override the relative mouse mode.
Sam Lantinga <slouken@lokigames.com>
parents:
78
diff
changeset
|
244 if ( env_override ) { |
ffadd05de74d
Allow the user to override the relative mouse mode.
Sam Lantinga <slouken@lokigames.com>
parents:
78
diff
changeset
|
245 enable_relative = atoi(env_override); |
ffadd05de74d
Allow the user to override the relative mouse mode.
Sam Lantinga <slouken@lokigames.com>
parents:
78
diff
changeset
|
246 } |
ffadd05de74d
Allow the user to override the relative mouse mode.
Sam Lantinga <slouken@lokigames.com>
parents:
78
diff
changeset
|
247 |
0 | 248 /* 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
|
249 if ( enable_relative && |
ffadd05de74d
Allow the user to override the relative mouse mode.
Sam Lantinga <slouken@lokigames.com>
parents:
78
diff
changeset
|
250 !(SDL_cursorstate & CURSOR_VISIBLE) && |
0 | 251 (this->input_grab != SDL_GRAB_OFF) && |
79
ffadd05de74d
Allow the user to override the relative mouse mode.
Sam Lantinga <slouken@lokigames.com>
parents:
78
diff
changeset
|
252 (SDL_GetAppState() & SDL_APPACTIVE) ) { |
0 | 253 if ( ! mouse_relative ) { |
254 X11_EnableDGAMouse(this); | |
255 if ( ! (using_dga & DGA_MOUSE) ) { | |
256 char *xmouse_accel; | |
257 | |
258 SDL_GetMouseState(&mouse_last.x, &mouse_last.y); | |
259 /* Use as raw mouse mickeys as possible */ | |
1168
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
888
diff
changeset
|
260 pXGetPointerControl(SDL_Display, |
0 | 261 &mouse_accel.numerator, |
262 &mouse_accel.denominator, | |
263 &mouse_accel.threshold); | |
264 xmouse_accel=getenv("SDL_VIDEO_X11_MOUSEACCEL"); | |
265 if ( xmouse_accel ) { | |
266 SetMouseAccel(this, xmouse_accel); | |
267 } | |
268 } | |
269 mouse_relative = 1; | |
270 } | |
271 } else { | |
272 if ( mouse_relative ) { | |
273 if ( using_dga & DGA_MOUSE ) { | |
274 X11_DisableDGAMouse(this); | |
275 } else { | |
1168
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
888
diff
changeset
|
276 pXChangePointerControl(SDL_Display, True, True, |
0 | 277 mouse_accel.numerator, |
278 mouse_accel.denominator, | |
279 mouse_accel.threshold); | |
280 } | |
281 mouse_relative = 0; | |
282 } | |
283 } | |
284 } | |
285 void X11_CheckMouseMode(_THIS) | |
286 { | |
287 SDL_Lock_EventThread(); | |
288 X11_CheckMouseModeNoLock(this); | |
289 SDL_Unlock_EventThread(); | |
290 } |