コード例 #1
0
void
gdk_property_change (GdkWindow    *window,
		     GdkAtom       property,
		     GdkAtom       type,
		     gint          format,
		     GdkPropMode   mode,
		     const guchar *data,
		     gint          nelements)
{
  GdkDisplay *display;
  Window xwindow;
  Atom xproperty;
  Atom xtype;

  g_return_if_fail (!window || GDK_IS_WINDOW (window));

  if (!window)
    {
      GdkScreen *screen;
      
      screen = gdk_screen_get_default ();
      window = gdk_screen_get_root_window (screen);
      
      GDK_NOTE (MULTIHEAD, g_message ("gdk_property_change(): window is NULL\n"));
    }


  if (GDK_WINDOW_DESTROYED (window))
    return;

  display = gdk_drawable_get_display (window);
  
  xproperty = gdk_x11_atom_to_xatom_for_display (display, property);
  xtype = gdk_x11_atom_to_xatom_for_display (display, type);
  xwindow = GDK_WINDOW_XID (window);

  if (xtype == XA_ATOM ||
      xtype == gdk_x11_get_xatom_by_name_for_display (display, "ATOM_PAIR"))
    {
      /*
       * data is an array of GdkAtom, we need to convert it
       * to an array of X Atoms
       */
      gint i;
      GdkAtom *atoms = (GdkAtom*) data;
      Atom *xatoms;

      xatoms = g_new (Atom, nelements);
      for (i = 0; i < nelements; i++)
	xatoms[i] = gdk_x11_atom_to_xatom_for_display (display, atoms[i]);

      XChangeProperty (GDK_DISPLAY_XDISPLAY (display), xwindow,
		       xproperty, xtype,
		       format, mode, (guchar *)xatoms, nelements);
      g_free (xatoms);
    }
  else
    XChangeProperty (GDK_DISPLAY_XDISPLAY (display), xwindow, xproperty, 
		     xtype, format, mode, (guchar *)data, nelements);
}
コード例 #2
0
ファイル: gdkinput.c プロジェクト: Aridna/gtk2
gboolean
gdk_device_get_history  (GdkDevice         *device,
			 GdkWindow         *window,
			 guint32            start,
			 guint32            stop,
			 GdkTimeCoord    ***events,
			 gint              *n_events)
{
  g_return_val_if_fail (window != NULL, FALSE);
  g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
  g_return_val_if_fail (events != NULL, FALSE);
  g_return_val_if_fail (n_events != NULL, FALSE);

  if (n_events)
    *n_events = 0;
  if (events)
    *events = NULL;

  if (GDK_WINDOW_DESTROYED (window))
    return FALSE;
    
  if (GDK_IS_CORE (device))
    return FALSE;
  else
    return _gdk_device_get_history (device, window, start, stop, events, n_events);
}
コード例 #3
0
void
gdk_property_delete (GdkWindow *window,
		     GdkAtom    property)
{
  g_return_if_fail (!window || GDK_IS_WINDOW (window));

  if (!window)
    {
      GdkScreen *screen = gdk_screen_get_default ();
      window = gdk_screen_get_root_window (screen);
      
      GDK_NOTE (MULTIHEAD, 
		g_message ("gdk_property_delete(): window is NULL\n"));
    }

  if (GDK_WINDOW_DESTROYED (window))
    return;

  gi_atom_id_t aid;
  GdkDisplay *display = GDK_DISPLAY_OBJECT(_gdk_display);

  aid = gdk_x11_atom_to_xatom_for_display (display, property);

  gi_delete_property ( GDK_DRAWABLE_GIX_ID (window), aid);
}
コード例 #4
0
GdkGrabStatus
gdk_keyboard_grab (GdkWindow *	   window,
		   gboolean	   owner_events,
		   guint32	   time)
{
  gint return_val;
  unsigned long serial;
  GdkDisplay *display;
  GdkDisplayX11 *display_x11;
  GdkWindow *native;

  g_return_val_if_fail (window != NULL, 0);
  g_return_val_if_fail (GDK_IS_WINDOW (window), 0);

  native = gdk_window_get_toplevel (window);

  /* TODO: What do we do for offscreens and  children? We need to proxy the grab somehow */
  if (!GDK_IS_WINDOW_IMPL_X11 (GDK_WINDOW_OBJECT (native)->impl))
    return GDK_GRAB_SUCCESS;

  display = GDK_WINDOW_DISPLAY (native);
  display_x11 = GDK_DISPLAY_X11 (display);

  serial = NextRequest (GDK_WINDOW_XDISPLAY (native));

  if (!GDK_WINDOW_DESTROYED (native))
    {
#ifdef G_ENABLE_DEBUG
      if (_gdk_debug_flags & GDK_DEBUG_NOGRABS)
	return_val = GrabSuccess;
      else
#endif
	return_val = XGrabKeyboard (GDK_WINDOW_XDISPLAY (native),
				    GDK_WINDOW_XID (native),
				    owner_events,
				    GrabModeAsync, GrabModeAsync,
				    time);
	if (G_UNLIKELY (!display_x11->trusted_client && 
			return_val == AlreadyGrabbed))
	  /* we can't grab the keyboard, but we can do a GTK-local grab */
	  return_val = GrabSuccess;
    }
  else
    return_val = AlreadyGrabbed;

  if (return_val == GrabSuccess)
    _gdk_display_set_has_keyboard_grab (display,
					window,	native,
					owner_events,
					serial, time);

  return gdk_x11_convert_grab_status (return_val);
}
コード例 #5
0
static cairo_surface_t *
gdk_quartz_ref_cairo_surface (GdkDrawable *drawable)
{
  GdkDrawableImplQuartz *impl = GDK_DRAWABLE_IMPL_QUARTZ (drawable);

  if (GDK_IS_WINDOW_IMPL_QUARTZ (drawable) &&
      GDK_WINDOW_DESTROYED (impl->wrapper))
    return NULL;

  if (!impl->cairo_surface)
    {
      int width, height;

      gdk_drawable_get_size (drawable, &width, &height);
      impl->cairo_surface = _gdk_windowing_create_cairo_surface (drawable,
                                                                 width, height);
    }
  else
    cairo_surface_reference (impl->cairo_surface);

  return impl->cairo_surface;
}
コード例 #6
0
void
gdk_property_delete (GdkWindow *window,
		     GdkAtom    property)
{
  g_return_if_fail (!window || GDK_IS_WINDOW (window));

  if (!window)
    {
      GdkScreen *screen = gdk_screen_get_default ();
      window = gdk_screen_get_root_window (screen);
      
      GDK_NOTE (MULTIHEAD, 
		g_message ("gdk_property_delete(): window is NULL\n"));
    }

  if (GDK_WINDOW_DESTROYED (window))
    return;

  XDeleteProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XWINDOW (window),
		   gdk_x11_atom_to_xatom_for_display (GDK_WINDOW_DISPLAY (window),
						      property));
}
コード例 #7
0
ファイル: gdkinput.c プロジェクト: Pfiver/gtk
void
gdk_input_set_extension_events (GdkWindow *window, gint mask,
                                GdkExtensionMode mode)
{
  GdkDeviceManager *device_manager;
  GList *devices, *d;

  g_return_if_fail (GDK_IS_WINDOW (window));

  if (GDK_WINDOW_DESTROYED (window))
    return;

  if (mode == GDK_EXTENSION_EVENTS_NONE)
    mask = 0;

  window->extension_events = mask;

  device_manager = gdk_display_get_device_manager (_gdk_display);
  devices = gdk_device_manager_list_devices (device_manager,
                                             GDK_DEVICE_TYPE_FLOATING);

  for (d = devices; d; d = d->next)
    {
      GdkDevice *dev;
      gint dev_mask;

      dev = d->data;
      dev_mask = mask;

      if (gdk_device_get_mode (dev) == GDK_MODE_DISABLED ||
          (!gdk_device_get_has_cursor (dev) && mode == GDK_EXTENSION_EVENTS_CURSOR))
        dev_mask = 0;

      gdk_window_set_device_events (window, dev, mask);
    }

  g_list_free (devices);
}
コード例 #8
0
GdkGrabStatus
_gdk_windowing_pointer_grab (GdkWindow *window,
			     GdkWindow *native,
			     gboolean owner_events,
			     GdkEventMask event_mask,
			     GdkWindow *confine_to,
			     GdkCursor *cursor,
			     guint32 time)
{
  gint return_val;
  GdkCursorPrivate *cursor_private;
  GdkDisplayX11 *display_x11;
  guint xevent_mask;
  Window xwindow;
  Window xconfine_to;
  Cursor xcursor;
  int i;

  if (confine_to)
    confine_to = _gdk_window_get_impl_window (confine_to);

  display_x11 = GDK_DISPLAY_X11 (GDK_WINDOW_DISPLAY (native));

  cursor_private = (GdkCursorPrivate*) cursor;

  xwindow = GDK_WINDOW_XID (native);

  if (!confine_to || GDK_WINDOW_DESTROYED (confine_to))
    xconfine_to = None;
  else
    xconfine_to = GDK_WINDOW_XID (confine_to);

  if (!cursor)
    xcursor = None;
  else
    {
      _gdk_x11_cursor_update_theme (cursor);
      xcursor = cursor_private->xcursor;
    }

  xevent_mask = 0;
  for (i = 0; i < _gdk_nenvent_masks; i++)
    {
      if (event_mask & (1 << (i + 1)))
	xevent_mask |= _gdk_event_mask_table[i];
    }

  /* We don't want to set a native motion hint mask, as we're emulating motion
   * hints. If we set a native one we just wouldn't get any events.
   */
  xevent_mask &= ~PointerMotionHintMask;

  return_val = _gdk_input_grab_pointer (window,
					native,
					owner_events,
					event_mask,
					confine_to,
					time);

  if (return_val == GrabSuccess ||
      G_UNLIKELY (!display_x11->trusted_client && return_val == AlreadyGrabbed))
    {
      if (!GDK_WINDOW_DESTROYED (native))
	{
#ifdef G_ENABLE_DEBUG
	  if (_gdk_debug_flags & GDK_DEBUG_NOGRABS)
	    return_val = GrabSuccess;
	  else
#endif
	    return_val = XGrabPointer (GDK_WINDOW_XDISPLAY (native),
				       xwindow,
				       owner_events,
				       xevent_mask,
				       GrabModeAsync, GrabModeAsync,
				       xconfine_to,
				       xcursor,
				       time);
	}
      else
	return_val = AlreadyGrabbed;
    }

  if (return_val == GrabSuccess)
    _gdk_x11_roundtrip_async (GDK_DISPLAY_OBJECT (display_x11),
			      has_pointer_grab_callback,
			      NULL);

  return gdk_x11_convert_grab_status (return_val);
}
コード例 #9
0
ファイル: gdkpixmap-gix.c プロジェクト: grimtraveller/netbas
GdkPixmap*
gdk_pixmap_new (GdkDrawable *drawable,
                gint       width,
                gint       height,
                gint       depth)
{
  GIXSurfacePixelFormat    format;
  GdkPixmap               *pixmap;
  GdkDrawableImplGix *draw_impl;

  g_return_val_if_fail (drawable == NULL || GDK_IS_DRAWABLE (drawable), NULL);
  g_return_val_if_fail (drawable != NULL || depth != -1, NULL);
  g_return_val_if_fail (width > 0 && height > 0, NULL);

  if (!drawable)
    drawable = _gdk_parent_root;

  if (GDK_IS_WINDOW (drawable) && GDK_WINDOW_DESTROYED (drawable))
    return NULL;

  GDK_NOTE (MISC, g_print ("gdk_pixmap_new: %dx%dx%d\n",
                           width, height, depth));

  if (depth == -1)
    {
      draw_impl =
        GDK_DRAWABLE_IMPL_GIX (GDK_WINDOW_OBJECT (drawable)->impl);

      g_return_val_if_fail (draw_impl != NULL, NULL);

	  format = gi_screen_format();
	  depth = GI_RENDER_FORMAT_BPP (format);      
    }
  else
    {
      switch (depth)
        {
        case  1:
          format = GI_RENDER_a8;
          break;
        case  8:
          format = GI_RENDER_r3g3b2;
          break;
        case 15:
          format = GI_RENDER_x1r5g5b5;
          break;
        case 16:
          format = GI_RENDER_r5g6b5;
          break;
        case 24:
          format = GI_RENDER_r8g8b8;
          break;
        case 32:
          format = GI_RENDER_x8r8g8b8;
          break;
        default:
          g_message ("unimplemented %s for depth %d", __FUNCTION__, depth);
          return NULL;
        }
    }

 
  pixmap = g_object_new (gdk_pixmap_get_type (), NULL);
  draw_impl = GDK_DRAWABLE_IMPL_GIX (GDK_PIXMAP_OBJECT (pixmap)->impl);
  draw_impl->window_id = gi_create_pixmap_window(
	  GDK_DRAWABLE_IMPL_GIX (drawable)->window_id,width,height,format);

  //surface->Clear (surface, 0x0, 0x0, 0x0, 0x0);
  //surface->GetSize (surface, &draw_impl->width, &draw_impl->height);
  //surface->GetPixelFormat (surface, &draw_impl->format);

  draw_impl->width = width;
  draw_impl->height = height;
  draw_impl->format = format;
  draw_impl->abs_x = draw_impl->abs_y = 0;
  GDK_PIXMAP_OBJECT (pixmap)->depth = depth;
  return pixmap;
}
コード例 #10
0
gboolean
gdk_property_get (GdkWindow   *window,
		  GdkAtom      property,
		  GdkAtom      type,
		  gulong       offset,
		  gulong       length,
		  gint         pdelete,
		  GdkAtom     *actual_property_type,
		  gint        *actual_format_type,
		  gint        *actual_length,
		  guchar     **data)
{
  GdkDisplay *display;
  Atom ret_prop_type;
  gint ret_format;
  gulong ret_nitems;
  gulong ret_bytes_after;
  gulong get_length;
  gulong ret_length;
  guchar *ret_data;
  Atom xproperty;
  Atom xtype;
  int res;

  g_return_val_if_fail (!window || GDK_WINDOW_IS_X11 (window), FALSE);

  if (!window)
    {
      GdkScreen *screen = gdk_screen_get_default ();
      window = gdk_screen_get_root_window (screen);
      
      GDK_NOTE (MULTIHEAD, g_message ("gdk_property_get(): window is NULL\n"));
    }
  else if (!GDK_WINDOW_IS_X11 (window))
    return FALSE;

  if (GDK_WINDOW_DESTROYED (window))
    return FALSE;

  display = gdk_drawable_get_display (window);
  xproperty = gdk_x11_atom_to_xatom_for_display (display, property);
  if (type == GDK_NONE)
    xtype = AnyPropertyType;
  else
    xtype = gdk_x11_atom_to_xatom_for_display (display, type);

  ret_data = NULL;
  
  /* 
   * Round up length to next 4 byte value.  Some code is in the (bad?)
   * habit of passing G_MAXLONG as the length argument, causing an
   * overflow to negative on the add.  In this case, we clamp the
   * value to G_MAXLONG.
   */
  get_length = length + 3;
  if (get_length > G_MAXLONG)
    get_length = G_MAXLONG;

  /* To fail, either the user passed 0 or G_MAXULONG */
  get_length = get_length / 4;
  if (get_length == 0)
    {
      g_warning ("gdk_propery-get(): invalid length 0");
      return FALSE;
    }

  res = XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display),
			    GDK_WINDOW_XWINDOW (window), xproperty,
			    offset, get_length, pdelete,
			    xtype, &ret_prop_type, &ret_format,
			    &ret_nitems, &ret_bytes_after,
			    &ret_data);

  if (res != Success || (ret_prop_type == None && ret_format == 0))
    {
      return FALSE;
    }

  if (actual_property_type)
    *actual_property_type = gdk_x11_xatom_to_atom_for_display (display, ret_prop_type);
  if (actual_format_type)
    *actual_format_type = ret_format;

  if ((xtype != AnyPropertyType) && (ret_prop_type != xtype))
    {
      XFree (ret_data);
      g_warning ("Couldn't match property type %s to %s\n", 
		 gdk_x11_get_xatom_name_for_display (display, ret_prop_type), 
		 gdk_x11_get_xatom_name_for_display (display, xtype));
      return FALSE;
    }

  /* FIXME: ignoring bytes_after could have very bad effects */

  if (data)
    {
      if (ret_prop_type == XA_ATOM ||
	  ret_prop_type == gdk_x11_get_xatom_by_name_for_display (display, "ATOM_PAIR"))
	{
	  /*
	   * data is an array of X atom, we need to convert it
	   * to an array of GDK Atoms
	   */
	  gint i;
	  GdkAtom *ret_atoms = g_new (GdkAtom, ret_nitems);
	  Atom *xatoms = (Atom *)ret_data;

	  *data = (guchar *)ret_atoms;

	  for (i = 0; i < ret_nitems; i++)
	    ret_atoms[i] = gdk_x11_xatom_to_atom_for_display (display, xatoms[i]);
	  
	  if (actual_length)
	    *actual_length = ret_nitems * sizeof (GdkAtom);
	}
      else
	{
	  switch (ret_format)
	    {
	    case 8:
	      ret_length = ret_nitems;
	      break;
	    case 16:
	      ret_length = sizeof(short) * ret_nitems;
	      break;
	    case 32:
	      ret_length = sizeof(long) * ret_nitems;
	      break;
	    default:
	      g_warning ("unknown property return format: %d", ret_format);
	      XFree (ret_data);
	      return FALSE;
	    }
	  
	  *data = g_new (guchar, ret_length);
	  memcpy (*data, ret_data, ret_length);
	  if (actual_length)
	    *actual_length = ret_length;
	}
    }

  XFree (ret_data);

  return TRUE;
}
コード例 #11
0
void
gdk_window_move_region (GdkWindow *window,
			GdkRegion *region,
			gint       dx,
			gint       dy)
{
  GdkRegion *invalidate_region;
  GdkWindowImplWin32 *impl;
  GdkWindowObject *obj;
  GdkRectangle src_rect, dest_rect;
  HRGN hrgn;
  RECT clipRect, destRect;

  g_return_if_fail (GDK_IS_WINDOW (window));

  if (GDK_WINDOW_DESTROYED (window))
    return;
  
  obj = GDK_WINDOW_OBJECT (window);
  impl = GDK_WINDOW_IMPL_WIN32 (obj->impl);  

  if (dx == 0 && dy == 0)
    return;
  
  /* Move the current invalid region */
  if (obj->update_area)
    gdk_region_offset (obj->update_area, dx, dy);
  
  /* impl->position_info.clip_rect isn't meaningful for toplevels */
  if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_CHILD)
    src_rect = impl->position_info.clip_rect;
  else
    {
      src_rect.x = 0;
      src_rect.y = 0;
      src_rect.width = impl->width;
      src_rect.height = impl->height;
    }
  
  invalidate_region = gdk_region_rectangle (&src_rect);

  dest_rect = src_rect;
  dest_rect.x += dx;
  dest_rect.y += dy;
  gdk_rectangle_intersect (&dest_rect, &src_rect, &dest_rect);

  if (dest_rect.width > 0 && dest_rect.height > 0)
    {
      GdkRegion *tmp_region;

      tmp_region = gdk_region_rectangle (&dest_rect);
      gdk_region_subtract (invalidate_region, tmp_region);
      gdk_region_destroy (tmp_region);
    }
  
  /* no guffaw scroll on win32 */
  hrgn = _gdk_win32_gdkregion_to_hrgn(invalidate_region, 0, 0);
  gdk_region_destroy (invalidate_region);
  destRect.left = dest_rect.y;
  destRect.top = dest_rect.x;
  destRect.right = dest_rect.x + dest_rect.width;
  destRect.bottom = dest_rect.y + dest_rect.height;
  clipRect.left = src_rect.y;
  clipRect.top = src_rect.x;
  clipRect.right = src_rect.x + src_rect.width;
  clipRect.bottom = src_rect.y + src_rect.height;

  g_print ("ScrollWindowEx(%d, %d, ...) - if you see this work, remove trace;)\n", dx, dy);
  API_CALL(ScrollWindowEx, (GDK_WINDOW_HWND (window),
                       dx, dy, /* in: scroll offsets */
                       NULL, /* in: scroll rect, NULL == entire client area */
                       &clipRect, /* in: restrict to */
                       hrgn, /* in: update region */
                       NULL, /* out: update rect */
                       SW_INVALIDATE));
  API_CALL(DeleteObject, (hrgn));
}
コード例 #12
0
void
gdk_window_scroll (GdkWindow *window,
		   gint       dx,
		   gint       dy)
{
  GdkRegion *invalidate_region;
  GdkWindowImplWin32 *impl;
  GdkWindowObject *obj;
  GList *tmp_list;
  GdkWindowParentPos parent_pos;
  HRGN native_invalidate_region;
  
  g_return_if_fail (GDK_IS_WINDOW (window));

  if (GDK_WINDOW_DESTROYED (window))
    return;
  
  GDK_NOTE (EVENTS, g_print ("gdk_window_scroll: %p %d,%d\n",
			     GDK_WINDOW_HWND (window), dx, dy));

  obj = GDK_WINDOW_OBJECT (window);
  impl = GDK_WINDOW_IMPL_WIN32 (obj->impl);  

  if (dx == 0 && dy == 0)
    return;
  
  /* Move the current invalid region */
  if (obj->update_area)
    gdk_region_offset (obj->update_area, dx, dy);
  
  gdk_window_compute_parent_pos (impl, &parent_pos);

  parent_pos.x += obj->x;
  parent_pos.y += obj->y;
  parent_pos.win32_x += impl->position_info.x;
  parent_pos.win32_y += impl->position_info.y;
  parent_pos.clip_rect = impl->position_info.clip_rect;

  gdk_window_tmp_unset_bg (window);

  native_invalidate_region = CreateRectRgn (0, 0, 0, 0);
  if (native_invalidate_region == NULL)
    WIN32_API_FAILED ("CreateRectRgn");

  API_CALL (ScrollWindowEx, (GDK_WINDOW_HWND (window),
			     dx, dy, NULL, NULL,
			     native_invalidate_region, NULL, SW_SCROLLCHILDREN));

  if (impl->position_info.no_bg)
    gdk_window_tmp_reset_bg (window);
  
  tmp_list = obj->children;
  while (tmp_list)
    {
      GDK_WINDOW_OBJECT(tmp_list->data)->x += dx;
      GDK_WINDOW_OBJECT(tmp_list->data)->y += dy;
      gdk_window_postmove (tmp_list->data, &parent_pos, FALSE);
      tmp_list = tmp_list->next;
    }

  if (native_invalidate_region != NULL)
    {
      invalidate_region = _gdk_win32_hrgn_to_region (native_invalidate_region);
      gdk_region_offset (invalidate_region, impl->position_info.x_offset,
                         impl->position_info.y_offset);
      gdk_window_invalidate_region (window, invalidate_region, TRUE);
      gdk_region_destroy (invalidate_region);
      GDI_CALL (DeleteObject, (native_invalidate_region));
    }
}
コード例 #13
0
ファイル: gdkdevicemanager-core-x11.c プロジェクト: BYC/gtk
static gboolean
gdk_x11_device_manager_core_translate_event (GdkEventTranslator *translator,
                                             GdkDisplay         *display,
                                             GdkEvent           *event,
                                             XEvent             *xevent)
{
  GdkX11DeviceManagerCore *device_manager;
  GdkWindow *window;
  gboolean return_val;
  GdkToplevelX11 *toplevel = NULL;
  GdkX11Display *display_x11 = GDK_X11_DISPLAY (display);

  device_manager = GDK_X11_DEVICE_MANAGER_CORE (translator);
  return_val = FALSE;

  window = get_event_window (translator, xevent);

  if (window)
    {
      if (GDK_WINDOW_DESTROYED (window) || !GDK_IS_WINDOW (window))
        return FALSE;

      toplevel = _gdk_x11_window_get_toplevel (window);
      g_object_ref (window);
    }

  event->any.window = window;
  event->any.send_event = xevent->xany.send_event ? TRUE : FALSE;

  if (window && GDK_WINDOW_DESTROYED (window))
    {
      if (xevent->type != DestroyNotify)
        {
          return_val = FALSE;
          goto done;
        }
    }

  if (window &&
      (xevent->type == MotionNotify ||
       xevent->type == ButtonRelease))
    {
      if (_gdk_x11_moveresize_handle_event (xevent))
        {
          return_val = FALSE;
          goto done;
        }
    }

  /* We do a "manual" conversion of the XEvent to a
   *  GdkEvent. The structures are mostly the same so
   *  the conversion is fairly straightforward. We also
   *  optionally print debugging info regarding events
   *  received.
   */

  return_val = TRUE;

  switch (xevent->type)
    {
    case KeyPress:
      if (window == NULL)
        {
          return_val = FALSE;
          break;
        }
      translate_key_event (display, device_manager, event, xevent);
      set_user_time (window, event);
      break;

    case KeyRelease:
      if (window == NULL)
        {
          return_val = FALSE;
          break;
        }

      /* Emulate detectable auto-repeat by checking to see
       * if the next event is a key press with the same
       * keycode and timestamp, and if so, ignoring the event.
       */

      if (!display_x11->have_xkb_autorepeat && XPending (xevent->xkey.display))
        {
          XEvent next_event;

          XPeekEvent (xevent->xkey.display, &next_event);

          if (next_event.type == KeyPress &&
              next_event.xkey.keycode == xevent->xkey.keycode &&
              next_event.xkey.time == xevent->xkey.time)
            {
              return_val = FALSE;
              break;
            }
        }

      translate_key_event (display, device_manager, event, xevent);
      break;

    case ButtonPress:
      GDK_NOTE (EVENTS,
                g_message ("button press:\t\twindow: %ld  x,y: %d %d  button: %d",
                           xevent->xbutton.window,
                           xevent->xbutton.x, xevent->xbutton.y,
                           xevent->xbutton.button));

      if (window == NULL)
        {
          return_val = FALSE;
          break;
        }

      /* If we get a ButtonPress event where the button is 4 or 5,
         it's a Scroll event */
      switch (xevent->xbutton.button)
        {
        case 4: /* up */
        case 5: /* down */
        case 6: /* left */
        case 7: /* right */
          event->scroll.type = GDK_SCROLL;

          if (xevent->xbutton.button == 4)
            event->scroll.direction = GDK_SCROLL_UP;
          else if (xevent->xbutton.button == 5)
            event->scroll.direction = GDK_SCROLL_DOWN;
          else if (xevent->xbutton.button == 6)
            event->scroll.direction = GDK_SCROLL_LEFT;
          else
            event->scroll.direction = GDK_SCROLL_RIGHT;

          event->scroll.window = window;
          event->scroll.time = xevent->xbutton.time;
          event->scroll.x = (gdouble) xevent->xbutton.x;
          event->scroll.y = (gdouble) xevent->xbutton.y;
          event->scroll.x_root = (gdouble) xevent->xbutton.x_root;
          event->scroll.y_root = (gdouble) xevent->xbutton.y_root;
          event->scroll.state = (GdkModifierType) xevent->xbutton.state;
          event->scroll.device = device_manager->core_pointer;

          if (!set_screen_from_root (display, event, xevent->xbutton.root))
            {
              return_val = FALSE;
              break;
            }

          break;

        default:
          event->button.type = GDK_BUTTON_PRESS;
          event->button.window = window;
          event->button.time = xevent->xbutton.time;
          event->button.x = (gdouble) xevent->xbutton.x;
          event->button.y = (gdouble) xevent->xbutton.y;
          event->button.x_root = (gdouble) xevent->xbutton.x_root;
          event->button.y_root = (gdouble) xevent->xbutton.y_root;
          event->button.axes = NULL;
          event->button.state = (GdkModifierType) xevent->xbutton.state;
          event->button.button = xevent->xbutton.button;
          event->button.device = device_manager->core_pointer;

          if (!set_screen_from_root (display, event, xevent->xbutton.root))
            return_val = FALSE;

          break;
        }

      set_user_time (window, event);

      break;

    case ButtonRelease:
      GDK_NOTE (EVENTS,
                g_message ("button release:\twindow: %ld  x,y: %d %d  button: %d",
                           xevent->xbutton.window,
                           xevent->xbutton.x, xevent->xbutton.y,
                           xevent->xbutton.button));

      if (window == NULL)
        {
          return_val = FALSE;
          break;
        }

      /* We treat button presses as scroll wheel events, so ignore the release */
      if (xevent->xbutton.button == 4 || xevent->xbutton.button == 5 ||
          xevent->xbutton.button == 6 || xevent->xbutton.button == 7)
        {
          return_val = FALSE;
          break;
        }

      event->button.type = GDK_BUTTON_RELEASE;
      event->button.window = window;
      event->button.time = xevent->xbutton.time;
      event->button.x = (gdouble) xevent->xbutton.x;
      event->button.y = (gdouble) xevent->xbutton.y;
      event->button.x_root = (gdouble) xevent->xbutton.x_root;
      event->button.y_root = (gdouble) xevent->xbutton.y_root;
      event->button.axes = NULL;
      event->button.state = (GdkModifierType) xevent->xbutton.state;
      event->button.button = xevent->xbutton.button;
      event->button.device = device_manager->core_pointer;

      if (!set_screen_from_root (display, event, xevent->xbutton.root))
        return_val = FALSE;

      break;

    case MotionNotify:
      GDK_NOTE (EVENTS,
                g_message ("motion notify:\t\twindow: %ld  x,y: %d %d  hint: %s",
                           xevent->xmotion.window,
                           xevent->xmotion.x, xevent->xmotion.y,
                           (xevent->xmotion.is_hint) ? "true" : "false"));

      if (window == NULL)
        {
          return_val = FALSE;
          break;
        }

      event->motion.type = GDK_MOTION_NOTIFY;
      event->motion.window = window;
      event->motion.time = xevent->xmotion.time;
      event->motion.x = (gdouble) xevent->xmotion.x;
      event->motion.y = (gdouble) xevent->xmotion.y;
      event->motion.x_root = (gdouble) xevent->xmotion.x_root;
      event->motion.y_root = (gdouble) xevent->xmotion.y_root;
      event->motion.axes = NULL;
      event->motion.state = (GdkModifierType) xevent->xmotion.state;
      event->motion.is_hint = xevent->xmotion.is_hint;
      event->motion.device = device_manager->core_pointer;

      if (!set_screen_from_root (display, event, xevent->xbutton.root))
        {
          return_val = FALSE;
          break;
        }

      break;

    case EnterNotify:
      GDK_NOTE (EVENTS,
                g_message ("enter notify:\t\twindow: %ld  detail: %d subwin: %ld",
                           xevent->xcrossing.window,
                           xevent->xcrossing.detail,
                           xevent->xcrossing.subwindow));

      if (window == NULL)
        {
          return_val = FALSE;
          break;
        }

      if (!set_screen_from_root (display, event, xevent->xbutton.root))
        {
          return_val = FALSE;
          break;
        }

      event->crossing.type = GDK_ENTER_NOTIFY;
      event->crossing.window = window;
      gdk_event_set_device (event, device_manager->core_pointer);

      /* If the subwindow field of the XEvent is non-NULL, then
       *  lookup the corresponding GdkWindow.
       */
      if (xevent->xcrossing.subwindow != None)
        event->crossing.subwindow = gdk_x11_window_lookup_for_display (display, xevent->xcrossing.subwindow);
      else
        event->crossing.subwindow = NULL;

      event->crossing.time = xevent->xcrossing.time;
      event->crossing.x = (gdouble) xevent->xcrossing.x;
      event->crossing.y = (gdouble) xevent->xcrossing.y;
      event->crossing.x_root = (gdouble) xevent->xcrossing.x_root;
      event->crossing.y_root = (gdouble) xevent->xcrossing.y_root;

      event->crossing.mode = translate_crossing_mode (xevent->xcrossing.mode);
      event->crossing.detail = translate_notify_type (xevent->xcrossing.detail);

      event->crossing.focus = xevent->xcrossing.focus;
      event->crossing.state = xevent->xcrossing.state;

      break;

    case LeaveNotify:
      GDK_NOTE (EVENTS,
                g_message ("leave notify:\t\twindow: %ld  detail: %d subwin: %ld",
                           xevent->xcrossing.window,
                           xevent->xcrossing.detail, xevent->xcrossing.subwindow));

      if (window == NULL)
        {
          return_val = FALSE;
          break;
        }

      if (!set_screen_from_root (display, event, xevent->xbutton.root))
        {
          return_val = FALSE;
          break;
        }

      event->crossing.type = GDK_LEAVE_NOTIFY;
      event->crossing.window = window;
      gdk_event_set_device (event, device_manager->core_pointer);

      /* If the subwindow field of the XEvent is non-NULL, then
       *  lookup the corresponding GdkWindow.
       */
      if (xevent->xcrossing.subwindow != None)
        event->crossing.subwindow = gdk_x11_window_lookup_for_display (display, xevent->xcrossing.subwindow);
      else
        event->crossing.subwindow = NULL;

      event->crossing.time = xevent->xcrossing.time;
      event->crossing.x = (gdouble) xevent->xcrossing.x;
      event->crossing.y = (gdouble) xevent->xcrossing.y;
      event->crossing.x_root = (gdouble) xevent->xcrossing.x_root;
      event->crossing.y_root = (gdouble) xevent->xcrossing.y_root;

      event->crossing.mode = translate_crossing_mode (xevent->xcrossing.mode);
      event->crossing.detail = translate_notify_type (xevent->xcrossing.detail);

      event->crossing.focus = xevent->xcrossing.focus;
      event->crossing.state = xevent->xcrossing.state;

      break;

      /* We only care about focus events that indicate that _this_
       * window (not a ancestor or child) got or lost the focus
       */
    case FocusIn:
      GDK_NOTE (EVENTS,
                g_message ("focus in:\t\twindow: %ld, detail: %s, mode: %s",
                           xevent->xfocus.window,
                           notify_details[xevent->xfocus.detail],
                           notify_modes[xevent->xfocus.mode]));

      if (toplevel)
        {
          gboolean had_focus = HAS_FOCUS (toplevel);

          switch (xevent->xfocus.detail)
            {
            case NotifyAncestor:
            case NotifyVirtual:
              /* When the focus moves from an ancestor of the window to
               * the window or a descendent of the window, *and* the
               * pointer is inside the window, then we were previously
               * receiving keystroke events in the has_pointer_focus
               * case and are now receiving them in the
               * has_focus_window case.
               */
              if (toplevel->has_pointer &&
                  xevent->xfocus.mode != NotifyGrab &&
                  xevent->xfocus.mode != NotifyUngrab)
                toplevel->has_pointer_focus = FALSE;

              /* fall through */
            case NotifyNonlinear:
            case NotifyNonlinearVirtual:
              if (xevent->xfocus.mode != NotifyGrab &&
                  xevent->xfocus.mode != NotifyUngrab)
                toplevel->has_focus_window = TRUE;
              /* We pretend that the focus moves to the grab
               * window, so we pay attention to NotifyGrab
               * NotifyUngrab, and ignore NotifyWhileGrabbed
               */
              if (xevent->xfocus.mode != NotifyWhileGrabbed)
                toplevel->has_focus = TRUE;
              break;
            case NotifyPointer:
              /* The X server sends NotifyPointer/NotifyGrab,
               * but the pointer focus is ignored while a
               * grab is in effect
               */
              if (xevent->xfocus.mode != NotifyGrab &&
                  xevent->xfocus.mode != NotifyUngrab)
                toplevel->has_pointer_focus = TRUE;
              break;
            case NotifyInferior:
            case NotifyPointerRoot:
            case NotifyDetailNone:
              break;
            }

          if (HAS_FOCUS (toplevel) != had_focus)
            generate_focus_event (device_manager, window, TRUE);
        }
      break;
    case FocusOut:
      GDK_NOTE (EVENTS,
                g_message ("focus out:\t\twindow: %ld, detail: %s, mode: %s",
                           xevent->xfocus.window,
                           notify_details[xevent->xfocus.detail],
                           notify_modes[xevent->xfocus.mode]));

      if (toplevel)
        {
          gboolean had_focus = HAS_FOCUS (toplevel);

          switch (xevent->xfocus.detail)
            {
            case NotifyAncestor:
            case NotifyVirtual:
              /* When the focus moves from the window or a descendent
               * of the window to an ancestor of the window, *and* the
               * pointer is inside the window, then we were previously
               * receiving keystroke events in the has_focus_window
               * case and are now receiving them in the
               * has_pointer_focus case.
               */
              if (toplevel->has_pointer &&
                  xevent->xfocus.mode != NotifyGrab &&
                  xevent->xfocus.mode != NotifyUngrab)
                toplevel->has_pointer_focus = TRUE;

              /* fall through */
            case NotifyNonlinear:
            case NotifyNonlinearVirtual:
              if (xevent->xfocus.mode != NotifyGrab &&
                  xevent->xfocus.mode != NotifyUngrab)
                toplevel->has_focus_window = FALSE;
              if (xevent->xfocus.mode != NotifyWhileGrabbed)
                toplevel->has_focus = FALSE;
              break;
            case NotifyPointer:
              if (xevent->xfocus.mode != NotifyGrab &&
                  xevent->xfocus.mode != NotifyUngrab)
                toplevel->has_pointer_focus = FALSE;
            break;
            case NotifyInferior:
            case NotifyPointerRoot:
            case NotifyDetailNone:
              break;
            }

          if (HAS_FOCUS (toplevel) != had_focus)
            generate_focus_event (device_manager, window, FALSE);
        }
      break;

    default:
        return_val = FALSE;
    }

 done:
  if (return_val)
    {
      if (event->any.window)
        g_object_ref (event->any.window);

      if (((event->any.type == GDK_ENTER_NOTIFY) ||
           (event->any.type == GDK_LEAVE_NOTIFY)) &&
          (event->crossing.subwindow != NULL))
        g_object_ref (event->crossing.subwindow);
    }
  else
    {
      /* Mark this event as having no resources to be freed */
      event->any.window = NULL;
      event->any.type = GDK_NOTHING;
    }

  if (window)
    g_object_unref (window);

  return return_val;
}
コード例 #14
0
ファイル: gdkdevicemanager-core-x11.c プロジェクト: Vort/gtk
static gboolean
gdk_x11_device_manager_core_translate_event (GdkEventTranslator *translator,
                                             GdkDisplay         *display,
                                             GdkEvent           *event,
                                             XEvent             *xevent)
{
  GdkWindowImplX11 *impl;
  GdkX11DeviceManagerCore *device_manager;
  GdkWindow *window;
  gboolean return_val;
  int scale;
  GdkX11Display *display_x11 = GDK_X11_DISPLAY (display);

  device_manager = GDK_X11_DEVICE_MANAGER_CORE (translator);

  window = get_event_window (translator, xevent);

  scale = 1;
  if (window)
    {
      if (GDK_WINDOW_DESTROYED (window) || !GDK_IS_WINDOW (window))
        return FALSE;

      g_object_ref (window);
      impl = GDK_WINDOW_IMPL_X11 (window->impl);
      scale = impl->window_scale;
    }

  event->any.window = window;
  event->any.send_event = xevent->xany.send_event ? TRUE : FALSE;

  if (window && GDK_WINDOW_DESTROYED (window))
    {
      if (xevent->type != DestroyNotify)
        {
          return_val = FALSE;
          goto done;
        }
    }

  if (window &&
      (xevent->type == MotionNotify ||
       xevent->type == ButtonRelease))
    {
      if (_gdk_x11_moveresize_handle_event (xevent))
        {
          return_val = FALSE;
          goto done;
        }
    }

  /* We do a "manual" conversion of the XEvent to a
   *  GdkEvent. The structures are mostly the same so
   *  the conversion is fairly straightforward. We also
   *  optionally print debugging info regarding events
   *  received.
   */

  return_val = TRUE;

  switch (xevent->type)
    {
    case KeyPress:
      if (window == NULL)
        {
          return_val = FALSE;
          break;
        }
      translate_key_event (display, device_manager, event, xevent);
      set_user_time (window, event);
      break;

    case KeyRelease:
      if (window == NULL)
        {
          return_val = FALSE;
          break;
        }

      /* Emulate detectable auto-repeat by checking to see
       * if the next event is a key press with the same
       * keycode and timestamp, and if so, ignoring the event.
       */

      if (!display_x11->have_xkb_autorepeat && XPending (xevent->xkey.display))
        {
          XEvent next_event;

          XPeekEvent (xevent->xkey.display, &next_event);

          if (next_event.type == KeyPress &&
              next_event.xkey.keycode == xevent->xkey.keycode &&
              next_event.xkey.time == xevent->xkey.time)
            {
              return_val = FALSE;
              break;
            }
        }

      translate_key_event (display, device_manager, event, xevent);
      break;

    case ButtonPress:
      GDK_NOTE (EVENTS,
                g_message ("button press:\t\twindow: %ld  x,y: %d %d  button: %d",
                           xevent->xbutton.window,
                           xevent->xbutton.x, xevent->xbutton.y,
                           xevent->xbutton.button));

      if (window == NULL)
        {
          return_val = FALSE;
          break;
        }

      /* If we get a ButtonPress event where the button is 4 or 5,
         it's a Scroll event */
      switch (xevent->xbutton.button)
        {
        case 4: /* up */
        case 5: /* down */
        case 6: /* left */
        case 7: /* right */
          event->scroll.type = GDK_SCROLL;

          if (xevent->xbutton.button == 4)
            event->scroll.direction = GDK_SCROLL_UP;
          else if (xevent->xbutton.button == 5)
            event->scroll.direction = GDK_SCROLL_DOWN;
          else if (xevent->xbutton.button == 6)
            event->scroll.direction = GDK_SCROLL_LEFT;
          else
            event->scroll.direction = GDK_SCROLL_RIGHT;

          event->scroll.window = window;
          event->scroll.time = xevent->xbutton.time;
          event->scroll.x = (gdouble) xevent->xbutton.x / scale;
          event->scroll.y = (gdouble) xevent->xbutton.y / scale;
          event->scroll.x_root = (gdouble) xevent->xbutton.x_root / scale;
          event->scroll.y_root = (gdouble) xevent->xbutton.y_root / scale;
          event->scroll.state = (GdkModifierType) xevent->xbutton.state;
          event->scroll.device = device_manager->core_pointer;

          event->scroll.delta_x = 0;
          event->scroll.delta_y = 0;

          if (!set_screen_from_root (display, event, xevent->xbutton.root))
            {
              return_val = FALSE;
              break;
            }

          break;

        default:
          event->button.type = GDK_BUTTON_PRESS;
          event->button.window = window;
          event->button.time = xevent->xbutton.time;
          event->button.x = (gdouble) xevent->xbutton.x / scale;
          event->button.y = (gdouble) xevent->xbutton.y / scale;
          event->button.x_root = (gdouble) xevent->xbutton.x_root / scale;
          event->button.y_root = (gdouble) xevent->xbutton.y_root / scale;
          event->button.axes = NULL;
          event->button.state = (GdkModifierType) xevent->xbutton.state;
          event->button.button = xevent->xbutton.button;
          event->button.device = device_manager->core_pointer;

          if (!set_screen_from_root (display, event, xevent->xbutton.root))
            return_val = FALSE;

          break;
        }

      set_user_time (window, event);

      break;

    case ButtonRelease:
      GDK_NOTE (EVENTS,
                g_message ("button release:\twindow: %ld  x,y: %d %d  button: %d",
                           xevent->xbutton.window,
                           xevent->xbutton.x, xevent->xbutton.y,
                           xevent->xbutton.button));

      if (window == NULL)
        {
          return_val = FALSE;
          break;
        }

      /* We treat button presses as scroll wheel events, so ignore the release */
      if (xevent->xbutton.button == 4 || xevent->xbutton.button == 5 ||
          xevent->xbutton.button == 6 || xevent->xbutton.button == 7)
        {
          return_val = FALSE;
          break;
        }

      event->button.type = GDK_BUTTON_RELEASE;
      event->button.window = window;
      event->button.time = xevent->xbutton.time;
      event->button.x = (gdouble) xevent->xbutton.x / scale;
      event->button.y = (gdouble) xevent->xbutton.y / scale;
      event->button.x_root = (gdouble) xevent->xbutton.x_root / scale;
      event->button.y_root = (gdouble) xevent->xbutton.y_root / scale;
      event->button.axes = NULL;
      event->button.state = (GdkModifierType) xevent->xbutton.state;
      event->button.button = xevent->xbutton.button;
      event->button.device = device_manager->core_pointer;

      if (!set_screen_from_root (display, event, xevent->xbutton.root))
        return_val = FALSE;

      break;

    case MotionNotify:
      GDK_NOTE (EVENTS,
                g_message ("motion notify:\t\twindow: %ld  x,y: %d %d  hint: %s",
                           xevent->xmotion.window,
                           xevent->xmotion.x, xevent->xmotion.y,
                           (xevent->xmotion.is_hint) ? "true" : "false"));

      if (window == NULL)
        {
          return_val = FALSE;
          break;
        }

      event->motion.type = GDK_MOTION_NOTIFY;
      event->motion.window = window;
      event->motion.time = xevent->xmotion.time;
      event->motion.x = (gdouble) xevent->xmotion.x / scale;
      event->motion.y = (gdouble) xevent->xmotion.y / scale;
      event->motion.x_root = (gdouble) xevent->xmotion.x_root / scale;
      event->motion.y_root = (gdouble) xevent->xmotion.y_root / scale;
      event->motion.axes = NULL;
      event->motion.state = (GdkModifierType) xevent->xmotion.state;
      event->motion.is_hint = xevent->xmotion.is_hint;
      event->motion.device = device_manager->core_pointer;

      if (!set_screen_from_root (display, event, xevent->xbutton.root))
        {
          return_val = FALSE;
          break;
        }

      break;

    case EnterNotify:
      GDK_NOTE (EVENTS,
                g_message ("enter notify:\t\twindow: %ld  detail: %d subwin: %ld",
                           xevent->xcrossing.window,
                           xevent->xcrossing.detail,
                           xevent->xcrossing.subwindow));

      if (window == NULL)
        {
          return_val = FALSE;
          break;
        }

      if (!set_screen_from_root (display, event, xevent->xbutton.root))
        {
          return_val = FALSE;
          break;
        }

      event->crossing.type = GDK_ENTER_NOTIFY;
      event->crossing.window = window;
      gdk_event_set_device (event, device_manager->core_pointer);

      /* If the subwindow field of the XEvent is non-NULL, then
       *  lookup the corresponding GdkWindow.
       */
      if (xevent->xcrossing.subwindow != None)
        event->crossing.subwindow = gdk_x11_window_lookup_for_display (display, xevent->xcrossing.subwindow);
      else
        event->crossing.subwindow = NULL;

      event->crossing.time = xevent->xcrossing.time;
      event->crossing.x = (gdouble) xevent->xcrossing.x / scale;
      event->crossing.y = (gdouble) xevent->xcrossing.y / scale;
      event->crossing.x_root = (gdouble) xevent->xcrossing.x_root / scale;
      event->crossing.y_root = (gdouble) xevent->xcrossing.y_root / scale;

      event->crossing.mode = translate_crossing_mode (xevent->xcrossing.mode);
      event->crossing.detail = translate_notify_type (xevent->xcrossing.detail);

      event->crossing.focus = xevent->xcrossing.focus;
      event->crossing.state = xevent->xcrossing.state;

      break;

    case LeaveNotify:
      GDK_NOTE (EVENTS,
                g_message ("leave notify:\t\twindow: %ld  detail: %d subwin: %ld",
                           xevent->xcrossing.window,
                           xevent->xcrossing.detail, xevent->xcrossing.subwindow));

      if (window == NULL)
        {
          return_val = FALSE;
          break;
        }

      if (!set_screen_from_root (display, event, xevent->xbutton.root))
        {
          return_val = FALSE;
          break;
        }

      event->crossing.type = GDK_LEAVE_NOTIFY;
      event->crossing.window = window;
      gdk_event_set_device (event, device_manager->core_pointer);

      /* If the subwindow field of the XEvent is non-NULL, then
       *  lookup the corresponding GdkWindow.
       */
      if (xevent->xcrossing.subwindow != None)
        event->crossing.subwindow = gdk_x11_window_lookup_for_display (display, xevent->xcrossing.subwindow);
      else
        event->crossing.subwindow = NULL;

      event->crossing.time = xevent->xcrossing.time;
      event->crossing.x = (gdouble) xevent->xcrossing.x / scale;
      event->crossing.y = (gdouble) xevent->xcrossing.y / scale;
      event->crossing.x_root = (gdouble) xevent->xcrossing.x_root / scale;
      event->crossing.y_root = (gdouble) xevent->xcrossing.y_root / scale;

      event->crossing.mode = translate_crossing_mode (xevent->xcrossing.mode);
      event->crossing.detail = translate_notify_type (xevent->xcrossing.detail);

      event->crossing.focus = xevent->xcrossing.focus;
      event->crossing.state = xevent->xcrossing.state;

      break;

    case FocusIn:
    case FocusOut:
      if (window)
        _gdk_device_manager_core_handle_focus (window,
                                               xevent->xfocus.window,
                                               device_manager->core_keyboard,
                                               NULL,
                                               xevent->type == FocusIn,
                                               xevent->xfocus.detail,
                                               xevent->xfocus.mode);
      return_val = FALSE;
      break;
                                              
    default:
        return_val = FALSE;
    }

 done:
  if (return_val)
    {
      if (event->any.window)
        g_object_ref (event->any.window);

      if (((event->any.type == GDK_ENTER_NOTIFY) ||
           (event->any.type == GDK_LEAVE_NOTIFY)) &&
          (event->crossing.subwindow != NULL))
        g_object_ref (event->crossing.subwindow);
    }
  else
    {
      /* Mark this event as having no resources to be freed */
      event->any.window = NULL;
      event->any.type = GDK_NOTHING;
    }

  if (window)
    g_object_unref (window);

  return return_val;
}