source: trunk/third/gtk/gdk/gdkinputxfree.h @ 14482

Revision 14482, 10.5 KB checked in by ghudson, 24 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r14481, which included commits to RCS files with non-trunk default branches.
Line 
1/* GDK - The GIMP Drawing Kit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
18 */
19
20/*
21 * Modified by the GTK+ Team and others 1997-1999.  See the AUTHORS
22 * file for a list of people on the GTK+ Team.  See the ChangeLog
23 * files for a list of changes.  These files are distributed with
24 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
25 */
26
27#ifdef XINPUT_XFREE
28
29/* forward declarations */
30
31static gint gdk_input_xfree_set_mode (guint32 deviceid, GdkInputMode mode);
32static void gdk_input_check_proximity (void);
33static void gdk_input_xfree_configure_event (XConfigureEvent *xevent,
34                                             GdkWindow *window);
35static void gdk_input_xfree_enter_event (XCrossingEvent *xevent,
36                                       GdkWindow *window);
37static gint gdk_input_xfree_other_event (GdkEvent *event,
38                                         XEvent *xevent,
39                                         GdkWindow *window);
40static gint gdk_input_xfree_enable_window(GdkWindow *window,
41                                          GdkDevicePrivate *gdkdev);
42static gint gdk_input_xfree_disable_window(GdkWindow *window,
43                                           GdkDevicePrivate *gdkdev);
44static gint gdk_input_xfree_grab_pointer (GdkWindow *     window,
45                                        gint            owner_events,
46                                        GdkEventMask    event_mask,
47                                        GdkWindow *     confine_to,
48                                        guint32         time);
49static void gdk_input_xfree_ungrab_pointer (guint32 time);
50
51void
52gdk_input_init(void)
53{
54  gdk_input_vtable.set_mode           = gdk_input_xfree_set_mode;
55  gdk_input_vtable.set_axes           = gdk_input_common_set_axes;
56  gdk_input_vtable.set_key            = gdk_input_common_set_key;
57  gdk_input_vtable.motion_events      = gdk_input_common_motion_events;
58  gdk_input_vtable.get_pointer        = gdk_input_common_get_pointer;
59  gdk_input_vtable.grab_pointer       = gdk_input_xfree_grab_pointer;
60  gdk_input_vtable.ungrab_pointer     = gdk_input_xfree_ungrab_pointer;
61  gdk_input_vtable.configure_event    = gdk_input_xfree_configure_event;
62  gdk_input_vtable.enter_event        = gdk_input_xfree_enter_event;
63  gdk_input_vtable.other_event        = gdk_input_xfree_other_event;
64  gdk_input_vtable.window_none_event  = NULL;
65  gdk_input_vtable.enable_window      = gdk_input_xfree_enable_window;
66  gdk_input_vtable.disable_window     = gdk_input_xfree_disable_window;
67
68  gdk_input_ignore_core = FALSE;
69  gdk_input_common_init(FALSE);
70}
71
72static gint
73gdk_input_xfree_set_mode (guint32 deviceid, GdkInputMode mode)
74{
75  GList *tmp_list;
76  GdkDevicePrivate *gdkdev;
77  GdkInputMode old_mode;
78  GdkInputWindow *input_window;
79
80  gdkdev = gdk_input_find_device(deviceid);
81  g_return_val_if_fail (gdkdev != NULL,FALSE);
82  old_mode = gdkdev->info.mode;
83
84  if (gdkdev->info.mode == mode)
85    return TRUE;
86
87  gdkdev->info.mode = mode;
88
89  if (mode == GDK_MODE_WINDOW)
90    {
91      gdkdev->info.has_cursor = FALSE;
92      for (tmp_list = gdk_input_windows; tmp_list; tmp_list = tmp_list->next)
93        {
94          input_window = (GdkInputWindow *)tmp_list->data;
95          if (input_window->mode != GDK_EXTENSION_EVENTS_CURSOR)
96            gdk_input_enable_window (input_window->window, gdkdev);
97          else
98            if (old_mode != GDK_MODE_DISABLED)
99              gdk_input_disable_window (input_window->window, gdkdev);
100        }
101    }
102  else if (mode == GDK_MODE_SCREEN)
103    {
104      gdkdev->info.has_cursor = TRUE;
105      for (tmp_list = gdk_input_windows; tmp_list; tmp_list = tmp_list->next)
106        gdk_input_enable_window (((GdkInputWindow *)tmp_list->data)->window,
107                                 gdkdev);
108    }
109  else  /* mode == GDK_MODE_DISABLED */
110    {
111      for (tmp_list = gdk_input_windows; tmp_list; tmp_list = tmp_list->next)
112        {
113          input_window = (GdkInputWindow *)tmp_list->data;
114          if (old_mode != GDK_MODE_WINDOW ||
115              input_window->mode != GDK_EXTENSION_EVENTS_CURSOR)
116            gdk_input_disable_window (input_window->window, gdkdev);
117        }
118    }
119
120  return TRUE;
121 
122}
123
124static void
125gdk_input_check_proximity (void)
126{
127  gint new_proximity = 0;
128  GList *tmp_list = gdk_input_devices;
129
130  while (tmp_list && !new_proximity)
131    {
132      GdkDevicePrivate *gdkdev = (GdkDevicePrivate *)(tmp_list->data);
133
134      if (gdkdev->info.mode != GDK_MODE_DISABLED
135          && gdkdev->info.deviceid != GDK_CORE_POINTER
136          && gdkdev->xdevice)
137        {
138          XDeviceState *state = XQueryDeviceState(GDK_DISPLAY(),
139                                                  gdkdev->xdevice);
140          XInputClass *xic;
141          int i;
142         
143          xic = state->data;
144          for (i=0; i<state->num_classes; i++)
145            {
146              if (xic->class == ValuatorClass)
147                {
148                  XValuatorState *xvs = (XValuatorState *)xic;
149                  if ((xvs->mode & ProximityState) == InProximity)
150                    {
151                      new_proximity = TRUE;
152                    }
153                  break;
154                }
155              xic = (XInputClass *)((char *)xic + xic->length);
156            }
157
158          XFreeDeviceState (state);
159        }
160      tmp_list = tmp_list->next;
161    }
162
163  gdk_input_ignore_core = new_proximity;
164}
165
166static void
167gdk_input_xfree_configure_event (XConfigureEvent *xevent, GdkWindow *window)
168{
169  GdkInputWindow *input_window;
170  gint root_x, root_y;
171
172  input_window = gdk_input_window_find(window);
173  g_return_if_fail (window != NULL);
174
175  gdk_input_get_root_relative_geometry(GDK_DISPLAY(),GDK_WINDOW_XWINDOW(window),
176                                 &root_x,
177                                 &root_y, NULL, NULL);
178
179  input_window->root_x = root_x;
180  input_window->root_y = root_y;
181}
182
183static void
184gdk_input_xfree_enter_event (XCrossingEvent *xevent,
185                             GdkWindow      *window)
186{
187  GdkInputWindow *input_window;
188  gint root_x, root_y;
189
190  input_window = gdk_input_window_find(window);
191  g_return_if_fail (window != NULL);
192
193  gdk_input_check_proximity();
194
195  gdk_input_get_root_relative_geometry(GDK_DISPLAY(),GDK_WINDOW_XWINDOW(window),
196                                 &root_x,
197                                 &root_y, NULL, NULL);
198
199  input_window->root_x = root_x;
200  input_window->root_y = root_y;
201}
202
203static gint
204gdk_input_xfree_other_event (GdkEvent *event,
205                             XEvent *xevent,
206                             GdkWindow *window)
207{
208  GdkInputWindow *input_window;
209
210  GdkDevicePrivate *gdkdev;
211  gint return_val;
212
213  input_window = gdk_input_window_find(window);
214  g_return_val_if_fail (window != NULL, -1);
215
216  /* This is a sort of a hack, as there isn't any XDeviceAnyEvent -
217     but it's potentially faster than scanning through the types of
218     every device. If we were deceived, then it won't match any of
219     the types for the device anyways */
220  gdkdev = gdk_input_find_device(((XDeviceButtonEvent *)xevent)->deviceid);
221
222  if (!gdkdev) {
223    return -1;                  /* we don't handle it - not an XInput event */
224  }
225
226  /* FIXME: It would be nice if we could just get rid of the events
227     entirely, instead of having to ignore them */
228  if (gdkdev->info.mode == GDK_MODE_DISABLED ||
229      (gdkdev->info.mode == GDK_MODE_WINDOW
230       && input_window->mode == GDK_EXTENSION_EVENTS_CURSOR))
231    return FALSE;
232 
233  if (!gdk_input_ignore_core)
234    gdk_input_check_proximity();
235
236  return_val = gdk_input_common_other_event (event, xevent,
237                                             input_window, gdkdev);
238
239  if (return_val > 0 && event->type == GDK_PROXIMITY_OUT &&
240      gdk_input_ignore_core)
241    gdk_input_check_proximity();
242
243  return return_val;
244}
245
246static gint
247gdk_input_xfree_enable_window(GdkWindow *window, GdkDevicePrivate *gdkdev)
248{
249  /* FIXME: watchout, gdkdev might be core pointer, never opened */
250  gdk_input_common_select_events (window, gdkdev);
251  return TRUE;
252}
253
254static gint
255gdk_input_xfree_disable_window(GdkWindow *window, GdkDevicePrivate *gdkdev)
256{
257  gdk_input_common_select_events (window, gdkdev);
258  return TRUE;
259}
260
261static gint
262gdk_input_xfree_grab_pointer (GdkWindow *     window,
263                              gint            owner_events,
264                              GdkEventMask    event_mask,
265                              GdkWindow *     confine_to,
266                              guint32         time)
267{
268  GdkInputWindow *input_window, *new_window;
269  gboolean need_ungrab;
270  GdkDevicePrivate *gdkdev;
271  GList *tmp_list;
272  XEventClass event_classes[GDK_MAX_DEVICE_CLASSES];
273  gint num_classes;
274  gint result;
275
276  tmp_list = gdk_input_windows;
277  new_window = NULL;
278  need_ungrab = FALSE;
279
280  while (tmp_list)
281    {
282      input_window = (GdkInputWindow *)tmp_list->data;
283
284      if (input_window->window == window)
285        new_window = input_window;
286      else if (input_window->grabbed)
287        {
288          input_window->grabbed = FALSE;
289          need_ungrab = TRUE;
290        }
291
292      tmp_list = tmp_list->next;
293    }
294
295  if (new_window)
296    {
297      new_window->grabbed = TRUE;
298     
299      tmp_list = gdk_input_devices;
300      while (tmp_list)
301        {
302          gdkdev = (GdkDevicePrivate *)tmp_list->data;
303          if (gdkdev->info.deviceid != GDK_CORE_POINTER &&
304              gdkdev->xdevice)
305            {
306              gdk_input_common_find_events (window, gdkdev,
307                                            event_mask,
308                                            event_classes, &num_classes);
309             
310              result = XGrabDevice( GDK_DISPLAY(), gdkdev->xdevice,
311                                    GDK_WINDOW_XWINDOW (window),
312                                    owner_events, num_classes, event_classes,
313                                    GrabModeAsync, GrabModeAsync, time);
314             
315              /* FIXME: if failure occurs on something other than the first
316                 device, things will be badly inconsistent */
317              if (result != Success)
318                return result;
319            }
320          tmp_list = tmp_list->next;
321        }
322    }
323  else
324    {
325      tmp_list = gdk_input_devices;
326      while (tmp_list)
327        {
328          gdkdev = (GdkDevicePrivate *)tmp_list->data;
329          if (gdkdev->info.deviceid != GDK_CORE_POINTER && gdkdev->xdevice &&
330              ((gdkdev->button_state != 0) || need_ungrab))
331            {
332              XUngrabDevice( gdk_display, gdkdev->xdevice, time);
333              gdkdev->button_state = 0;
334            }
335         
336          tmp_list = tmp_list->next;
337        }
338    }
339
340  return Success;
341     
342}
343
344static void
345gdk_input_xfree_ungrab_pointer (guint32 time)
346{
347  GdkInputWindow *input_window;
348  GdkDevicePrivate *gdkdev;
349  GList *tmp_list;
350
351  tmp_list = gdk_input_windows;
352  while (tmp_list)
353    {
354      input_window = (GdkInputWindow *)tmp_list->data;
355      if (input_window->grabbed)
356        break;
357      tmp_list = tmp_list->next;
358    }
359
360  if (tmp_list)                 /* we found a grabbed window */
361    {
362      input_window->grabbed = FALSE;
363
364      tmp_list = gdk_input_devices;
365      while (tmp_list)
366        {
367          gdkdev = (GdkDevicePrivate *)tmp_list->data;
368          if (gdkdev->info.deviceid != GDK_CORE_POINTER && gdkdev->xdevice)
369            XUngrabDevice( gdk_display, gdkdev->xdevice, time);
370
371          tmp_list = tmp_list->next;
372        }
373    }
374}
375
376#endif /* XINPUT_XFREE */
Note: See TracBrowser for help on using the repository browser.