Blame gdk/x11/gdkinput-xfree.c

Packit Service fb6fa5
/* GDK - The GIMP Drawing Kit
Packit Service fb6fa5
 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * This library is free software; you can redistribute it and/or
Packit Service fb6fa5
 * modify it under the terms of the GNU Lesser General Public
Packit Service fb6fa5
 * License as published by the Free Software Foundation; either
Packit Service fb6fa5
 * version 2 of the License, or (at your option) any later version.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * This library is distributed in the hope that it will be useful,
Packit Service fb6fa5
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service fb6fa5
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service fb6fa5
 * Lesser General Public License for more details.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * You should have received a copy of the GNU Lesser General Public
Packit Service fb6fa5
 * License along with this library; if not, write to the
Packit Service fb6fa5
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Packit Service fb6fa5
 * Boston, MA 02111-1307, USA.
Packit Service fb6fa5
 */
Packit Service fb6fa5
Packit Service fb6fa5
#include "config.h"
Packit Service fb6fa5
#include <string.h>
Packit Service fb6fa5
#include "gdkinputprivate.h"
Packit Service fb6fa5
#include "gdkdisplay-x11.h"
Packit Service fb6fa5
#include "gdkalias.h"
Packit Service fb6fa5
Packit Service fb6fa5
/*
Packit Service fb6fa5
 * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
Packit Service fb6fa5
 * file for a list of people on the GTK+ Team.  See the ChangeLog
Packit Service fb6fa5
 * files for a list of changes.  These files are distributed with
Packit Service fb6fa5
 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
Packit Service fb6fa5
 */
Packit Service fb6fa5
Packit Service fb6fa5
/* forward declarations */
Packit Service fb6fa5
Packit Service fb6fa5
static void gdk_input_check_proximity (GdkDisplay *display);
Packit Service fb6fa5
Packit Service fb6fa5
void
Packit Service fb6fa5
_gdk_input_init(GdkDisplay *display)
Packit Service fb6fa5
{
Packit Service fb6fa5
  _gdk_init_input_core (display);
Packit Service fb6fa5
  display->ignore_core_events = FALSE;
Packit Service fb6fa5
  _gdk_input_common_init (display, FALSE);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
gboolean
Packit Service fb6fa5
gdk_device_set_mode (GdkDevice      *device,
Packit Service fb6fa5
		     GdkInputMode    mode)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GList *tmp_list;
Packit Service fb6fa5
  GdkDevicePrivate *gdkdev;
Packit Service fb6fa5
  GdkInputWindow *input_window;
Packit Service fb6fa5
  GdkDisplayX11 *display_impl;
Packit Service fb6fa5
Packit Service fb6fa5
  if (GDK_IS_CORE (device))
Packit Service fb6fa5
    return FALSE;
Packit Service fb6fa5
Packit Service fb6fa5
  gdkdev = (GdkDevicePrivate *)device;
Packit Service fb6fa5
Packit Service fb6fa5
  if (device->mode == mode)
Packit Service fb6fa5
    return TRUE;
Packit Service fb6fa5
Packit Service fb6fa5
  device->mode = mode;
Packit Service fb6fa5
Packit Service fb6fa5
  if (mode == GDK_MODE_WINDOW)
Packit Service fb6fa5
    device->has_cursor = FALSE;
Packit Service fb6fa5
  else if (mode == GDK_MODE_SCREEN)
Packit Service fb6fa5
    device->has_cursor = TRUE;
Packit Service fb6fa5
Packit Service fb6fa5
  display_impl = GDK_DISPLAY_X11 (gdkdev->display);
Packit Service fb6fa5
  for (tmp_list = display_impl->input_windows; tmp_list; tmp_list = tmp_list->next)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      input_window = (GdkInputWindow *)tmp_list->data;
Packit Service fb6fa5
      _gdk_input_select_events (input_window->impl_window, gdkdev);
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  return TRUE;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static int
Packit Service fb6fa5
ignore_errors (Display *display, XErrorEvent *event)
Packit Service fb6fa5
{
Packit Service fb6fa5
  return True;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static void
Packit Service fb6fa5
gdk_input_check_proximity (GdkDisplay *display)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GdkDisplayX11 *display_impl = GDK_DISPLAY_X11 (display);
Packit Service fb6fa5
  GList *tmp_list = display_impl->input_devices;
Packit Service fb6fa5
  gint new_proximity = 0;
Packit Service fb6fa5
Packit Service fb6fa5
  while (tmp_list && !new_proximity)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      GdkDevicePrivate *gdkdev = (GdkDevicePrivate *)(tmp_list->data);
Packit Service fb6fa5
Packit Service fb6fa5
      if (gdkdev->info.mode != GDK_MODE_DISABLED
Packit Service fb6fa5
	  && !GDK_IS_CORE (gdkdev)
Packit Service fb6fa5
	  && gdkdev->xdevice)
Packit Service fb6fa5
	{
Packit Service fb6fa5
      int (*old_handler) (Display *, XErrorEvent *);
Packit Service fb6fa5
      XDeviceState *state = NULL;
Packit Service fb6fa5
      XInputClass *xic;
Packit Service fb6fa5
      int i;
Packit Service fb6fa5
Packit Service fb6fa5
      /* From X11 doc: "XQueryDeviceState can generate a BadDevice error."
Packit Service fb6fa5
       * This would occur in particular when a device is unplugged,
Packit Service fb6fa5
       * which would cause the program to crash (see bug 575767).
Packit Service fb6fa5
       *
Packit Service fb6fa5
       * To handle this case gracefully, we simply ignore the device.
Packit Service fb6fa5
       * GTK+ 3 handles this better with XInput 2's hotplugging support;
Packit Service fb6fa5
       * but this is better than a crash in GTK+ 2.
Packit Service fb6fa5
       */
Packit Service fb6fa5
      old_handler = XSetErrorHandler (ignore_errors);
Packit Service fb6fa5
      state = XQueryDeviceState(display_impl->xdisplay, gdkdev->xdevice);
Packit Service fb6fa5
      XSetErrorHandler (old_handler);
Packit Service fb6fa5
Packit Service fb6fa5
      if (! state)
Packit Service fb6fa5
        {
Packit Service fb6fa5
          /* Broken device. It may have been disconnected.
Packit Service fb6fa5
           * Ignore it.
Packit Service fb6fa5
           */
Packit Service fb6fa5
          tmp_list = tmp_list->next;
Packit Service fb6fa5
          continue;
Packit Service fb6fa5
        }
Packit Service fb6fa5
Packit Service fb6fa5
	  xic = state->data;
Packit Service fb6fa5
	  for (i=0; i<state->num_classes; i++)
Packit Service fb6fa5
	    {
Packit Service fb6fa5
	      if (xic->class == ValuatorClass)
Packit Service fb6fa5
		{
Packit Service fb6fa5
		  XValuatorState *xvs = (XValuatorState *)xic;
Packit Service fb6fa5
		  if ((xvs->mode & ProximityState) == InProximity)
Packit Service fb6fa5
		    {
Packit Service fb6fa5
		      new_proximity = TRUE;
Packit Service fb6fa5
		    }
Packit Service fb6fa5
		  break;
Packit Service fb6fa5
		}
Packit Service fb6fa5
	      xic = (XInputClass *)((char *)xic + xic->length);
Packit Service fb6fa5
	    }
Packit Service fb6fa5
Packit Service fb6fa5
	  XFreeDeviceState (state);
Packit Service fb6fa5
	}
Packit Service fb6fa5
      tmp_list = tmp_list->next;
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  display->ignore_core_events = new_proximity;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
void
Packit Service fb6fa5
_gdk_input_configure_event (XConfigureEvent *xevent,
Packit Service fb6fa5
			    GdkWindow       *window)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GdkWindowObject *priv = (GdkWindowObject *)window;
Packit Service fb6fa5
  GdkInputWindow *input_window;
Packit Service fb6fa5
  gint root_x, root_y;
Packit Service fb6fa5
Packit Service fb6fa5
  input_window = priv->input_window;
Packit Service fb6fa5
  if (input_window != NULL)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      _gdk_input_get_root_relative_geometry (window, &root_x, &root_y);
Packit Service fb6fa5
      input_window->root_x = root_x;
Packit Service fb6fa5
      input_window->root_y = root_y;
Packit Service fb6fa5
    }
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
void
Packit Service fb6fa5
_gdk_input_crossing_event (GdkWindow *window,
Packit Service fb6fa5
			   gboolean enter)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GdkDisplay *display = GDK_WINDOW_DISPLAY (window);
Packit Service fb6fa5
  GdkDisplayX11 *display_impl = GDK_DISPLAY_X11 (display);
Packit Service fb6fa5
  GdkWindowObject *priv = (GdkWindowObject *)window;
Packit Service fb6fa5
  GdkInputWindow *input_window;
Packit Service fb6fa5
  gint root_x, root_y;
Packit Service fb6fa5
Packit Service fb6fa5
  if (enter)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      gdk_input_check_proximity(display);
Packit Service fb6fa5
Packit Service fb6fa5
      input_window = priv->input_window;
Packit Service fb6fa5
      if (input_window != NULL)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  _gdk_input_get_root_relative_geometry (window, &root_x, &root_y);
Packit Service fb6fa5
	  input_window->root_x = root_x;
Packit Service fb6fa5
	  input_window->root_y = root_y;
Packit Service fb6fa5
	}
Packit Service fb6fa5
    }
Packit Service fb6fa5
  else
Packit Service fb6fa5
    display->ignore_core_events = FALSE;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static GdkEventType
Packit Service fb6fa5
get_input_event_type (GdkDevicePrivate *gdkdev,
Packit Service fb6fa5
		      XEvent *xevent,
Packit Service fb6fa5
		      int *core_x, int *core_y)
Packit Service fb6fa5
{
Packit Service fb6fa5
  if (xevent->type == gdkdev->buttonpress_type)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      XDeviceButtonEvent *xie = (XDeviceButtonEvent *)(xevent);
Packit Service fb6fa5
      *core_x = xie->x;
Packit Service fb6fa5
      *core_y = xie->y;
Packit Service fb6fa5
      return GDK_BUTTON_PRESS;
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  if (xevent->type == gdkdev->buttonrelease_type)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      XDeviceButtonEvent *xie = (XDeviceButtonEvent *)(xevent);
Packit Service fb6fa5
      *core_x = xie->x;
Packit Service fb6fa5
      *core_y = xie->y;
Packit Service fb6fa5
      return GDK_BUTTON_RELEASE;
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  if (xevent->type == gdkdev->keypress_type)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      XDeviceKeyEvent *xie = (XDeviceKeyEvent *)(xevent);
Packit Service fb6fa5
      *core_x = xie->x;
Packit Service fb6fa5
      *core_y = xie->y;
Packit Service fb6fa5
      return GDK_KEY_PRESS;
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  if (xevent->type == gdkdev->keyrelease_type)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      XDeviceKeyEvent *xie = (XDeviceKeyEvent *)(xevent);
Packit Service fb6fa5
      *core_x = xie->x;
Packit Service fb6fa5
      *core_y = xie->y;
Packit Service fb6fa5
      return GDK_KEY_RELEASE;
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  if (xevent->type == gdkdev->motionnotify_type)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      XDeviceMotionEvent *xie = (XDeviceMotionEvent *)(xevent);
Packit Service fb6fa5
      *core_x = xie->x;
Packit Service fb6fa5
      *core_y = xie->y;
Packit Service fb6fa5
      return GDK_MOTION_NOTIFY;
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  if (xevent->type == gdkdev->proximityin_type)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      XProximityNotifyEvent *xie = (XProximityNotifyEvent *)(xevent);
Packit Service fb6fa5
      *core_x = xie->x;
Packit Service fb6fa5
      *core_y = xie->y;
Packit Service fb6fa5
      return GDK_PROXIMITY_IN;
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  if (xevent->type == gdkdev->proximityout_type)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      XProximityNotifyEvent *xie = (XProximityNotifyEvent *)(xevent);
Packit Service fb6fa5
      *core_x = xie->x;
Packit Service fb6fa5
      *core_y = xie->y;
Packit Service fb6fa5
      return GDK_PROXIMITY_OUT;
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  *core_x = 0;
Packit Service fb6fa5
  *core_y = 0;
Packit Service fb6fa5
  return GDK_NOTHING;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
Packit Service fb6fa5
gboolean
Packit Service fb6fa5
_gdk_input_other_event (GdkEvent *event,
Packit Service fb6fa5
			XEvent *xevent,
Packit Service fb6fa5
			GdkWindow *event_window)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GdkWindow *window;
Packit Service fb6fa5
  GdkWindowObject *priv;
Packit Service fb6fa5
  GdkInputWindow *iw;
Packit Service fb6fa5
  GdkDevicePrivate *gdkdev;
Packit Service fb6fa5
  GdkEventType event_type;
Packit Service fb6fa5
  int x, y;
Packit Service fb6fa5
  GdkDisplay *display = GDK_WINDOW_DISPLAY (event_window);
Packit Service fb6fa5
  GdkDisplayX11 *display_impl = GDK_DISPLAY_X11 (display);
Packit Service fb6fa5
Packit Service fb6fa5
  /* This is a sort of a hack, as there isn't any XDeviceAnyEvent -
Packit Service fb6fa5
     but it's potentially faster than scanning through the types of
Packit Service fb6fa5
     every device. If we were deceived, then it won't match any of
Packit Service fb6fa5
     the types for the device anyways */
Packit Service fb6fa5
  gdkdev = _gdk_input_find_device (display,
Packit Service fb6fa5
				   ((XDeviceButtonEvent *)xevent)->deviceid);
Packit Service fb6fa5
  if (!gdkdev)
Packit Service fb6fa5
    return FALSE;			/* we don't handle it - not an XInput event */
Packit Service fb6fa5
Packit Service fb6fa5
  event_type = get_input_event_type (gdkdev, xevent, &x, &y);
Packit Service fb6fa5
  if (event_type == GDK_NOTHING)
Packit Service fb6fa5
    return FALSE;
Packit Service fb6fa5
Packit Service fb6fa5
  /* If we're not getting any event window its likely because we're outside the
Packit Service fb6fa5
     window and there is no grab. We should still report according to the
Packit Service fb6fa5
     implicit grab though. */
Packit Service fb6fa5
  iw = ((GdkWindowObject *)event_window)->input_window;
Packit Service fb6fa5
Packit Service fb6fa5
  if (iw->button_down_window)
Packit Service fb6fa5
    window = iw->button_down_window;
Packit Service fb6fa5
  else
Packit Service fb6fa5
    window = _gdk_window_get_input_window_for_event (event_window,
Packit Service fb6fa5
                                                     event_type,
Packit Service fb6fa5
						     /* TODO: Seems wrong, but the code used to ignore button motion handling here... */
Packit Service fb6fa5
						     0, 
Packit Service fb6fa5
                                                     x, y,
Packit Service fb6fa5
                                                     xevent->xany.serial);
Packit Service fb6fa5
  priv = (GdkWindowObject *)window;
Packit Service fb6fa5
  if (window == NULL)
Packit Service fb6fa5
    return FALSE;
Packit Service fb6fa5
Packit Service fb6fa5
  if (gdkdev->info.mode == GDK_MODE_DISABLED ||
Packit Service fb6fa5
      priv->extension_events == 0 ||
Packit Service fb6fa5
      !(gdkdev->info.has_cursor || (priv->extension_events & GDK_ALL_DEVICES_MASK)))
Packit Service fb6fa5
    return FALSE;
Packit Service fb6fa5
Packit Service fb6fa5
  if (!display->ignore_core_events && priv->extension_events != 0)
Packit Service fb6fa5
    gdk_input_check_proximity (GDK_WINDOW_DISPLAY (window));
Packit Service fb6fa5
Packit Service fb6fa5
  if (!_gdk_input_common_other_event (event, xevent, window, gdkdev))
Packit Service fb6fa5
    return FALSE;
Packit Service fb6fa5
Packit Service fb6fa5
  if (event->type == GDK_BUTTON_PRESS)
Packit Service fb6fa5
    iw->button_down_window = window;
Packit Service fb6fa5
  if (event->type == GDK_BUTTON_RELEASE && !gdkdev->button_count)
Packit Service fb6fa5
    iw->button_down_window = NULL;
Packit Service fb6fa5
Packit Service fb6fa5
  if (event->type == GDK_PROXIMITY_OUT &&
Packit Service fb6fa5
      display->ignore_core_events)
Packit Service fb6fa5
    gdk_input_check_proximity (GDK_WINDOW_DISPLAY (window));
Packit Service fb6fa5
Packit Service fb6fa5
  return _gdk_input_common_event_selected(event, window, gdkdev);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
gint
Packit Service fb6fa5
_gdk_input_grab_pointer (GdkWindow      *window,
Packit Service fb6fa5
			 GdkWindow      *native_window, /* This is the toplevel */
Packit Service fb6fa5
			 gint            owner_events,
Packit Service fb6fa5
			 GdkEventMask    event_mask,
Packit Service fb6fa5
			 GdkWindow *     confine_to,
Packit Service fb6fa5
			 guint32         time)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GdkInputWindow *input_window;
Packit Service fb6fa5
  GdkWindowObject *priv, *impl_window;
Packit Service fb6fa5
  gboolean need_ungrab;
Packit Service fb6fa5
  GdkDevicePrivate *gdkdev;
Packit Service fb6fa5
  GList *tmp_list;
Packit Service fb6fa5
  XEventClass event_classes[GDK_MAX_DEVICE_CLASSES];
Packit Service fb6fa5
  gint num_classes;
Packit Service fb6fa5
  gint result;
Packit Service fb6fa5
  GdkDisplayX11 *display_impl  = GDK_DISPLAY_X11 (GDK_WINDOW_DISPLAY (window));
Packit Service fb6fa5
Packit Service fb6fa5
  tmp_list = display_impl->input_windows;
Packit Service fb6fa5
  need_ungrab = FALSE;
Packit Service fb6fa5
Packit Service fb6fa5
  while (tmp_list)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      input_window = (GdkInputWindow *)tmp_list->data;
Packit Service fb6fa5
Packit Service fb6fa5
      if (input_window->grabbed)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  input_window->grabbed = FALSE;
Packit Service fb6fa5
	  need_ungrab = TRUE;
Packit Service fb6fa5
	  break;
Packit Service fb6fa5
	}
Packit Service fb6fa5
      tmp_list = tmp_list->next;
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  priv = (GdkWindowObject *)window;
Packit Service fb6fa5
  impl_window = (GdkWindowObject *)_gdk_window_get_impl_window (window);
Packit Service fb6fa5
  input_window = impl_window->input_window;
Packit Service fb6fa5
  if (priv->extension_events)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      g_assert (input_window != NULL);
Packit Service fb6fa5
      input_window->grabbed = TRUE;
Packit Service fb6fa5
Packit Service fb6fa5
      tmp_list = display_impl->input_devices;
Packit Service fb6fa5
      while (tmp_list)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  gdkdev = (GdkDevicePrivate *)tmp_list->data;
Packit Service fb6fa5
	  if (!GDK_IS_CORE (gdkdev) && gdkdev->xdevice)
Packit Service fb6fa5
	    {
Packit Service fb6fa5
	      _gdk_input_common_find_events (gdkdev, event_mask,
Packit Service fb6fa5
					     event_classes, &num_classes);
Packit Service fb6fa5
#ifdef G_ENABLE_DEBUG
Packit Service fb6fa5
	      if (_gdk_debug_flags & GDK_DEBUG_NOGRABS)
Packit Service fb6fa5
		result = GrabSuccess;
Packit Service fb6fa5
	      else
Packit Service fb6fa5
#endif
Packit Service fb6fa5
		result = XGrabDevice (display_impl->xdisplay, gdkdev->xdevice,
Packit Service fb6fa5
				      GDK_WINDOW_XWINDOW (native_window),
Packit Service fb6fa5
				      owner_events, num_classes, event_classes,
Packit Service fb6fa5
				      GrabModeAsync, GrabModeAsync, time);
Packit Service fb6fa5
Packit Service fb6fa5
	      /* FIXME: if failure occurs on something other than the first
Packit Service fb6fa5
		 device, things will be badly inconsistent */
Packit Service fb6fa5
	      if (result != Success)
Packit Service fb6fa5
		return result;
Packit Service fb6fa5
	    }
Packit Service fb6fa5
	  tmp_list = tmp_list->next;
Packit Service fb6fa5
	}
Packit Service fb6fa5
    }
Packit Service fb6fa5
  else
Packit Service fb6fa5
    {
Packit Service fb6fa5
      tmp_list = display_impl->input_devices;
Packit Service fb6fa5
      while (tmp_list)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  gdkdev = (GdkDevicePrivate *)tmp_list->data;
Packit Service fb6fa5
	  if (!GDK_IS_CORE (gdkdev) && gdkdev->xdevice &&
Packit Service fb6fa5
	      ((gdkdev->button_count != 0) || need_ungrab))
Packit Service fb6fa5
	    {
Packit Service fb6fa5
	      XUngrabDevice (display_impl->xdisplay, gdkdev->xdevice, time);
Packit Service fb6fa5
	      memset (gdkdev->button_state, 0, sizeof (gdkdev->button_state));
Packit Service fb6fa5
	      gdkdev->button_count = 0;
Packit Service fb6fa5
	    }
Packit Service fb6fa5
Packit Service fb6fa5
	  tmp_list = tmp_list->next;
Packit Service fb6fa5
	}
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  return Success;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
void
Packit Service fb6fa5
_gdk_input_ungrab_pointer (GdkDisplay *display,
Packit Service fb6fa5
			   guint32 time)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GdkInputWindow *input_window = NULL; /* Quiet GCC */
Packit Service fb6fa5
  GdkDevicePrivate *gdkdev;
Packit Service fb6fa5
  GList *tmp_list;
Packit Service fb6fa5
  GdkDisplayX11 *display_impl = GDK_DISPLAY_X11 (display);
Packit Service fb6fa5
Packit Service fb6fa5
  tmp_list = display_impl->input_windows;
Packit Service fb6fa5
  while (tmp_list)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      input_window = (GdkInputWindow *)tmp_list->data;
Packit Service fb6fa5
      if (input_window->grabbed)
Packit Service fb6fa5
	break;
Packit Service fb6fa5
      tmp_list = tmp_list->next;
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  if (tmp_list)			/* we found a grabbed window */
Packit Service fb6fa5
    {
Packit Service fb6fa5
      input_window->grabbed = FALSE;
Packit Service fb6fa5
Packit Service fb6fa5
      tmp_list = display_impl->input_devices;
Packit Service fb6fa5
      while (tmp_list)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  gdkdev = (GdkDevicePrivate *)tmp_list->data;
Packit Service fb6fa5
	  if (!GDK_IS_CORE (gdkdev) && gdkdev->xdevice)
Packit Service fb6fa5
	    XUngrabDevice( display_impl->xdisplay, gdkdev->xdevice, time);
Packit Service fb6fa5
Packit Service fb6fa5
	  tmp_list = tmp_list->next;
Packit Service fb6fa5
	}
Packit Service fb6fa5
    }
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
#define __GDK_INPUT_XFREE_C__
Packit Service fb6fa5
#include "gdkaliasdef.c"