comparison src/video/x11/SDL_x11mouse.c @ 1662:782fd950bd46 SDL-1.3

Revamp of the video system in progress - adding support for multiple displays, multiple windows, and a full video mode selection API. WARNING: None of the video drivers have been updated for the new API yet! The API is still under design and very fluid. The code is now run through a consistent indent format: indent -i4 -nut -nsc -br -ce The headers are being converted to automatically generate doxygen documentation.
author Sam Lantinga <slouken@libsdl.org>
date Sun, 28 May 2006 13:04:16 +0000
parents 5b0805ceb50f
children 4da1ee79c9af
comparison
equal deleted inserted replaced
1661:281d3f4870e5 1662:782fd950bd46
30 #include "SDL_x11dga_c.h" 30 #include "SDL_x11dga_c.h"
31 #include "SDL_x11mouse_c.h" 31 #include "SDL_x11mouse_c.h"
32 32
33 33
34 /* The implementation dependent data for the window manager cursor */ 34 /* The implementation dependent data for the window manager cursor */
35 struct WMcursor { 35 struct WMcursor
36 Cursor x_cursor; 36 {
37 Cursor x_cursor;
37 }; 38 };
38 39
39 40
40 void X11_FreeWMCursor(_THIS, WMcursor *cursor) 41 void
41 { 42 X11_FreeWMCursor (_THIS, WMcursor * cursor)
42 if ( SDL_Display != NULL ) { 43 {
43 SDL_Lock_EventThread(); 44 if (SDL_Display != NULL) {
44 XFreeCursor(SDL_Display, cursor->x_cursor); 45 SDL_Lock_EventThread ();
45 XSync(SDL_Display, False); 46 XFreeCursor (SDL_Display, cursor->x_cursor);
46 SDL_Unlock_EventThread(); 47 XSync (SDL_Display, False);
47 } 48 SDL_Unlock_EventThread ();
48 SDL_free(cursor); 49 }
49 } 50 SDL_free (cursor);
50 51 }
51 WMcursor *X11_CreateWMCursor(_THIS, 52
52 Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y) 53 WMcursor *
53 { 54 X11_CreateWMCursor (_THIS,
54 WMcursor *cursor; 55 Uint8 * data, Uint8 * mask, int w, int h, int hot_x,
55 XGCValues GCvalues; 56 int hot_y)
56 GC GCcursor; 57 {
57 XImage *data_image, *mask_image; 58 WMcursor *cursor;
58 Pixmap data_pixmap, mask_pixmap; 59 XGCValues GCvalues;
59 int clen, i; 60 GC GCcursor;
60 char *x_data, *x_mask; 61 XImage *data_image, *mask_image;
61 static XColor black = { 0, 0, 0, 0 }; 62 Pixmap data_pixmap, mask_pixmap;
62 static XColor white = { 0xffff, 0xffff, 0xffff, 0xffff }; 63 int clen, i;
63 64 char *x_data, *x_mask;
64 /* Allocate the cursor memory */ 65 static XColor black = { 0, 0, 0, 0 };
65 cursor = (WMcursor *)SDL_malloc(sizeof(WMcursor)); 66 static XColor white = { 0xffff, 0xffff, 0xffff, 0xffff };
66 if ( cursor == NULL ) { 67
67 SDL_OutOfMemory(); 68 /* Allocate the cursor memory */
68 return(NULL); 69 cursor = (WMcursor *) SDL_malloc (sizeof (WMcursor));
69 } 70 if (cursor == NULL) {
70 71 SDL_OutOfMemory ();
71 /* Mix the mask and the data */ 72 return (NULL);
72 clen = (w/8)*h; 73 }
73 x_data = (char *)SDL_malloc(clen); 74
74 if ( x_data == NULL ) { 75 /* Mix the mask and the data */
75 SDL_free(cursor); 76 clen = (w / 8) * h;
76 SDL_OutOfMemory(); 77 x_data = (char *) SDL_malloc (clen);
77 return(NULL); 78 if (x_data == NULL) {
78 } 79 SDL_free (cursor);
79 x_mask = (char *)SDL_malloc(clen); 80 SDL_OutOfMemory ();
80 if ( x_mask == NULL ) { 81 return (NULL);
81 SDL_free(cursor); 82 }
82 SDL_free(x_data); 83 x_mask = (char *) SDL_malloc (clen);
83 SDL_OutOfMemory(); 84 if (x_mask == NULL) {
84 return(NULL); 85 SDL_free (cursor);
85 } 86 SDL_free (x_data);
86 for ( i=0; i<clen; ++i ) { 87 SDL_OutOfMemory ();
87 /* The mask is OR'd with the data to turn inverted color 88 return (NULL);
88 pixels black since inverted color cursors aren't supported 89 }
89 under X11. 90 for (i = 0; i < clen; ++i) {
90 */ 91 /* The mask is OR'd with the data to turn inverted color
91 x_mask[i] = data[i] | mask[i]; 92 pixels black since inverted color cursors aren't supported
92 x_data[i] = data[i]; 93 under X11.
93 } 94 */
94 95 x_mask[i] = data[i] | mask[i];
95 /* Prevent the event thread from running while we use the X server */ 96 x_data[i] = data[i];
96 SDL_Lock_EventThread(); 97 }
97 98
98 /* Create the data image */ 99 /* Prevent the event thread from running while we use the X server */
99 data_image = XCreateImage(SDL_Display, 100 SDL_Lock_EventThread ();
100 DefaultVisual(SDL_Display, SDL_Screen), 101
101 1, XYBitmap, 0, x_data, w, h, 8, w/8); 102 /* Create the data image */
102 data_image->byte_order = MSBFirst; 103 data_image = XCreateImage (SDL_Display,
103 data_image->bitmap_bit_order = MSBFirst; 104 DefaultVisual (SDL_Display, SDL_Screen),
104 data_pixmap = XCreatePixmap(SDL_Display, SDL_Root, w, h, 1); 105 1, XYBitmap, 0, x_data, w, h, 8, w / 8);
105 106 data_image->byte_order = MSBFirst;
106 /* Create the data mask */ 107 data_image->bitmap_bit_order = MSBFirst;
107 mask_image = XCreateImage(SDL_Display, 108 data_pixmap = XCreatePixmap (SDL_Display, SDL_Root, w, h, 1);
108 DefaultVisual(SDL_Display, SDL_Screen), 109
109 1, XYBitmap, 0, x_mask, w, h, 8, w/8); 110 /* Create the data mask */
110 mask_image->byte_order = MSBFirst; 111 mask_image = XCreateImage (SDL_Display,
111 mask_image->bitmap_bit_order = MSBFirst; 112 DefaultVisual (SDL_Display, SDL_Screen),
112 mask_pixmap = XCreatePixmap(SDL_Display, SDL_Root, w, h, 1); 113 1, XYBitmap, 0, x_mask, w, h, 8, w / 8);
113 114 mask_image->byte_order = MSBFirst;
114 /* Create the graphics context */ 115 mask_image->bitmap_bit_order = MSBFirst;
115 GCvalues.function = GXcopy; 116 mask_pixmap = XCreatePixmap (SDL_Display, SDL_Root, w, h, 1);
116 GCvalues.foreground = ~0; 117
117 GCvalues.background = 0; 118 /* Create the graphics context */
118 GCvalues.plane_mask = AllPlanes; 119 GCvalues.function = GXcopy;
119 GCcursor = XCreateGC(SDL_Display, data_pixmap, 120 GCvalues.foreground = ~0;
120 (GCFunction|GCForeground|GCBackground|GCPlaneMask), 121 GCvalues.background = 0;
121 &GCvalues); 122 GCvalues.plane_mask = AllPlanes;
122 123 GCcursor = XCreateGC (SDL_Display, data_pixmap,
123 /* Blit the images to the pixmaps */ 124 (GCFunction | GCForeground | GCBackground |
124 XPutImage(SDL_Display, data_pixmap, GCcursor, data_image, 125 GCPlaneMask), &GCvalues);
125 0, 0, 0, 0, w, h); 126
126 XPutImage(SDL_Display, mask_pixmap, GCcursor, mask_image, 127 /* Blit the images to the pixmaps */
127 0, 0, 0, 0, w, h); 128 XPutImage (SDL_Display, data_pixmap, GCcursor, data_image,
128 XFreeGC(SDL_Display, GCcursor); 129 0, 0, 0, 0, w, h);
129 /* These free the x_data and x_mask memory pointers */ 130 XPutImage (SDL_Display, mask_pixmap, GCcursor, mask_image,
130 XDestroyImage(data_image); 131 0, 0, 0, 0, w, h);
131 XDestroyImage(mask_image); 132 XFreeGC (SDL_Display, GCcursor);
132 133 /* These free the x_data and x_mask memory pointers */
133 /* Create the cursor */ 134 XDestroyImage (data_image);
134 cursor->x_cursor = XCreatePixmapCursor(SDL_Display, data_pixmap, 135 XDestroyImage (mask_image);
135 mask_pixmap, &black, &white, hot_x, hot_y); 136
136 XFreePixmap(SDL_Display, data_pixmap); 137 /* Create the cursor */
137 XFreePixmap(SDL_Display, mask_pixmap); 138 cursor->x_cursor = XCreatePixmapCursor (SDL_Display, data_pixmap,
138 139 mask_pixmap, &black, &white,
139 /* Release the event thread */ 140 hot_x, hot_y);
140 XSync(SDL_Display, False); 141 XFreePixmap (SDL_Display, data_pixmap);
141 SDL_Unlock_EventThread(); 142 XFreePixmap (SDL_Display, mask_pixmap);
142 143
143 return(cursor); 144 /* Release the event thread */
144 } 145 XSync (SDL_Display, False);
145 146 SDL_Unlock_EventThread ();
146 int X11_ShowWMCursor(_THIS, WMcursor *cursor) 147
147 { 148 return (cursor);
148 /* Don't do anything if the display is gone */ 149 }
149 if ( SDL_Display == NULL ) { 150
150 return(0); 151 int
151 } 152 X11_ShowWMCursor (_THIS, WMcursor * cursor)
152 153 {
153 /* Set the X11 cursor cursor, or blank if cursor is NULL */ 154 /* Don't do anything if the display is gone */
154 if ( SDL_Window ) { 155 if (SDL_Display == NULL) {
155 SDL_Lock_EventThread(); 156 return (0);
156 if ( cursor == NULL ) { 157 }
157 if ( SDL_BlankCursor != NULL ) { 158
158 XDefineCursor(SDL_Display, SDL_Window, 159 /* Set the X11 cursor cursor, or blank if cursor is NULL */
159 SDL_BlankCursor->x_cursor); 160 if (SDL_Window) {
160 } 161 SDL_Lock_EventThread ();
161 } else { 162 if (cursor == NULL) {
162 XDefineCursor(SDL_Display, SDL_Window, cursor->x_cursor); 163 if (SDL_BlankCursor != NULL) {
163 } 164 XDefineCursor (SDL_Display, SDL_Window,
164 XSync(SDL_Display, False); 165 SDL_BlankCursor->x_cursor);
165 SDL_Unlock_EventThread(); 166 }
166 } 167 } else {
167 return(1); 168 XDefineCursor (SDL_Display, SDL_Window, cursor->x_cursor);
168 } 169 }
169 170 XSync (SDL_Display, False);
170 void X11_WarpWMCursor(_THIS, Uint16 x, Uint16 y) 171 SDL_Unlock_EventThread ();
171 { 172 }
172 if ( using_dga & DGA_MOUSE ) { 173 return (1);
173 SDL_PrivateMouseMotion(0, 0, x, y); 174 }
174 } else if ( mouse_relative) { 175
175 /* RJR: March 28, 2000 176 void
176 leave physical cursor at center of screen if 177 X11_WarpWMCursor (_THIS, Uint16 x, Uint16 y)
177 mouse hidden and grabbed */ 178 {
178 SDL_PrivateMouseMotion(0, 0, x, y); 179 if (using_dga & DGA_MOUSE) {
179 } else { 180 SDL_PrivateMouseMotion (0, 0, x, y);
180 SDL_Lock_EventThread(); 181 } else if (mouse_relative) {
181 XWarpPointer(SDL_Display, None, SDL_Window, 0, 0, 0, 0, x, y); 182 /* RJR: March 28, 2000
182 XSync(SDL_Display, False); 183 leave physical cursor at center of screen if
183 SDL_Unlock_EventThread(); 184 mouse hidden and grabbed */
184 } 185 SDL_PrivateMouseMotion (0, 0, x, y);
186 } else {
187 SDL_Lock_EventThread ();
188 XWarpPointer (SDL_Display, None, SDL_Window, 0, 0, 0, 0, x, y);
189 XSync (SDL_Display, False);
190 SDL_Unlock_EventThread ();
191 }
185 } 192 }
186 193
187 /* Sets the mouse acceleration from a string of the form: 194 /* Sets the mouse acceleration from a string of the form:
188 2/1/0 195 2/1/0
189 The first number is the numerator, followed by the acceleration 196 The first number is the numerator, followed by the acceleration
190 denumenator and threshold. 197 denumenator and threshold.
191 */ 198 */
192 static void SetMouseAccel(_THIS, const char *accel_param) 199 static void
193 { 200 SetMouseAccel (_THIS, const char *accel_param)
194 int i; 201 {
195 size_t len; 202 int i;
196 int accel_value[3]; 203 size_t len;
197 char *mouse_param, *mouse_param_buf, *pin; 204 int accel_value[3];
198 205 char *mouse_param, *mouse_param_buf, *pin;
199 len = SDL_strlen(accel_param)+1; 206
200 mouse_param_buf = SDL_stack_alloc(char, len); 207 len = SDL_strlen (accel_param) + 1;
201 if ( ! mouse_param_buf ) { 208 mouse_param_buf = SDL_stack_alloc (char, len);
202 return; 209 if (!mouse_param_buf) {
203 } 210 return;
204 SDL_strlcpy(mouse_param_buf, accel_param, len); 211 }
205 mouse_param = mouse_param_buf; 212 SDL_strlcpy (mouse_param_buf, accel_param, len);
206 213 mouse_param = mouse_param_buf;
207 for ( i=0; (i < 3) && mouse_param; ++i ) { 214
208 pin = SDL_strchr(mouse_param, '/'); 215 for (i = 0; (i < 3) && mouse_param; ++i) {
209 if ( pin ) { 216 pin = SDL_strchr (mouse_param, '/');
210 *pin = '\0'; 217 if (pin) {
211 } 218 *pin = '\0';
212 accel_value[i] = atoi(mouse_param); 219 }
213 if ( pin ) { 220 accel_value[i] = atoi (mouse_param);
214 mouse_param = pin+1; 221 if (pin) {
215 } else { 222 mouse_param = pin + 1;
216 mouse_param = NULL; 223 } else {
217 } 224 mouse_param = NULL;
218 } 225 }
219 if ( mouse_param_buf ) { 226 }
220 XChangePointerControl(SDL_Display, True, True, 227 if (mouse_param_buf) {
221 accel_value[0], accel_value[1], accel_value[2]); 228 XChangePointerControl (SDL_Display, True, True,
222 SDL_free(mouse_param_buf); 229 accel_value[0], accel_value[1],
223 } 230 accel_value[2]);
231 SDL_free (mouse_param_buf);
232 }
224 } 233 }
225 234
226 /* Check to see if we need to enter or leave mouse relative mode */ 235 /* Check to see if we need to enter or leave mouse relative mode */
227 void X11_CheckMouseModeNoLock(_THIS) 236 void
228 { 237 X11_CheckMouseModeNoLock (_THIS)
229 const Uint8 full_focus = (SDL_APPACTIVE|SDL_APPINPUTFOCUS|SDL_APPMOUSEFOCUS); 238 {
230 char *env_override; 239 const Uint8 full_focus =
231 int enable_relative = 1; 240 (SDL_APPACTIVE | SDL_APPINPUTFOCUS | SDL_APPMOUSEFOCUS);
232 241 char *env_override;
233 /* Allow the user to override the relative mouse mode. 242 int enable_relative = 1;
234 They almost never want to do this, as it seriously affects 243
235 applications that rely on continuous relative mouse motion. 244 /* Allow the user to override the relative mouse mode.
236 */ 245 They almost never want to do this, as it seriously affects
237 env_override = SDL_getenv("SDL_MOUSE_RELATIVE"); 246 applications that rely on continuous relative mouse motion.
238 if ( env_override ) { 247 */
239 enable_relative = atoi(env_override); 248 env_override = SDL_getenv ("SDL_MOUSE_RELATIVE");
240 } 249 if (env_override) {
241 250 enable_relative = atoi (env_override);
242 /* If the mouse is hidden and input is grabbed, we use relative mode */ 251 }
243 if ( enable_relative && 252
244 !(SDL_cursorstate & CURSOR_VISIBLE) && 253 /* If the mouse is hidden and input is grabbed, we use relative mode */
245 (this->input_grab != SDL_GRAB_OFF) && 254 if (enable_relative &&
246 (SDL_GetAppState() & full_focus) == full_focus ) { 255 !(SDL_cursorstate & CURSOR_VISIBLE) &&
247 if ( ! mouse_relative ) { 256 (SDL_CurrentWindow.input_grab != SDL_GRAB_OFF) &&
248 X11_EnableDGAMouse(this); 257 (SDL_GetAppState () & full_focus) == full_focus) {
249 if ( ! (using_dga & DGA_MOUSE) ) { 258 if (!mouse_relative) {
250 char *xmouse_accel; 259 X11_EnableDGAMouse (this);
251 260 if (!(using_dga & DGA_MOUSE)) {
252 SDL_GetMouseState(&mouse_last.x, &mouse_last.y); 261 char *xmouse_accel;
253 /* Use as raw mouse mickeys as possible */ 262
254 XGetPointerControl(SDL_Display, 263 SDL_GetMouseState (&mouse_last.x, &mouse_last.y);
255 &mouse_accel.numerator, 264 /* Use as raw mouse mickeys as possible */
256 &mouse_accel.denominator, 265 XGetPointerControl (SDL_Display,
257 &mouse_accel.threshold); 266 &mouse_accel.numerator,
258 xmouse_accel=SDL_getenv("SDL_VIDEO_X11_MOUSEACCEL"); 267 &mouse_accel.denominator,
259 if ( xmouse_accel ) { 268 &mouse_accel.threshold);
260 SetMouseAccel(this, xmouse_accel); 269 xmouse_accel = SDL_getenv ("SDL_VIDEO_X11_MOUSEACCEL");
261 } 270 if (xmouse_accel) {
262 } 271 SetMouseAccel (this, xmouse_accel);
263 mouse_relative = 1; 272 }
264 } 273 }
265 } else { 274 mouse_relative = 1;
266 if ( mouse_relative ) { 275 }
267 if ( using_dga & DGA_MOUSE ) { 276 } else {
268 X11_DisableDGAMouse(this); 277 if (mouse_relative) {
269 } else { 278 if (using_dga & DGA_MOUSE) {
270 XChangePointerControl(SDL_Display, True, True, 279 X11_DisableDGAMouse (this);
271 mouse_accel.numerator, 280 } else {
272 mouse_accel.denominator, 281 XChangePointerControl (SDL_Display, True, True,
273 mouse_accel.threshold); 282 mouse_accel.numerator,
274 } 283 mouse_accel.denominator,
275 mouse_relative = 0; 284 mouse_accel.threshold);
276 } 285 }
277 } 286 mouse_relative = 0;
278 } 287 }
279 void X11_CheckMouseMode(_THIS) 288 }
280 { 289 }
281 SDL_Lock_EventThread(); 290 void
282 X11_CheckMouseModeNoLock(this); 291 X11_CheckMouseMode (_THIS)
283 SDL_Unlock_EventThread(); 292 {
284 } 293 SDL_Lock_EventThread ();
294 X11_CheckMouseModeNoLock (this);
295 SDL_Unlock_EventThread ();
296 }
297
298 /* vi: set ts=4 sw=4 expandtab: */