Exemplo n.º 1
0
gboolean
_gdk_x11_window_simulate_button (GdkWindow      *window,
                                 gint            x,
                                 gint            y,
                                 guint           button, /*1..3*/
                                 GdkModifierType modifiers,
                                 GdkEventType    button_pressrelease)
{
    GdkScreen *screen;
    XButtonEvent xev = {
        0,  /* type */
        0,  /* serial */
        1,  /* send_event */
    };
    gboolean success;

    g_return_val_if_fail (button_pressrelease == GDK_BUTTON_PRESS || button_pressrelease == GDK_BUTTON_RELEASE, FALSE);
    g_return_val_if_fail (window != NULL, FALSE);

    if (!GDK_WINDOW_IS_MAPPED (window))
        return FALSE;

    screen = gdk_window_get_screen (window);

    if (x < 0 && y < 0)
    {
        x = window->width / 2;
        y = window->height / 2;
    }

    /* Convert to impl coordinates */
    x = x + window->abs_x;
    y = y + window->abs_y;

    xev.type = button_pressrelease == GDK_BUTTON_PRESS ? ButtonPress : ButtonRelease;
    xev.display = GDK_WINDOW_XDISPLAY (window);
    xev.window = GDK_WINDOW_XID (window);
    xev.root = RootWindow (xev.display, GDK_X11_SCREEN (screen)->screen_num);
    xev.subwindow = 0;
    xev.time = 0;
    xev.x = x;
    xev.y = y;
    xev.x_root = 0;
    xev.y_root = 0;
    xev.state = modifiers;
    xev.button = button;
    gdk_x11_display_error_trap_push (GDK_WINDOW_DISPLAY (window));
    xev.same_screen = XTranslateCoordinates (xev.display, xev.window, xev.root,
                      xev.x, xev.y, &xev.x_root, &xev.y_root,
                      &xev.subwindow);
    if (!xev.subwindow)
        xev.subwindow = xev.window;
    success = xev.same_screen;
    success &= 0 != XWarpPointer (xev.display, None, xev.window, 0, 0, 0, 0, xev.x, xev.y);
    success &= 0 != XSendEvent (xev.display, xev.window, True, button_pressrelease == GDK_BUTTON_PRESS ? ButtonPressMask : ButtonReleaseMask, (XEvent*) &xev);
    XSync (xev.display, False);
    success &= 0 == gdk_x11_display_error_trap_pop(GDK_WINDOW_DISPLAY (window));
    return success;
}
Exemplo n.º 2
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);
}
void
gdk_x11_window_force_focus (GdkWindow *window,
                            guint32    timestamp)
{
    GdkDisplay *display;

    g_return_if_fail (GDK_IS_WINDOW (window));

    display = GDK_WINDOW_DISPLAY (window);

    if (GTK_CHECK_VERSION(3,0,0) && !GDK_IS_X11_DISPLAY (display))
        return;

    if (gdk_x11_screen_supports_net_wm_hint (gdk_window_get_screen (window),
                        gdk_atom_intern_static_string ("_NET_ACTIVE_WINDOW")))
    {
        if (!timestamp)
        {
            GTimeVal t;
            g_get_current_time (&t);
            timestamp = t.tv_sec;
        }

        XClientMessageEvent xclient;

        memset (&xclient, 0, sizeof (xclient));
        xclient.type = ClientMessage;
        xclient.window = GDK_WINDOW_XID (window);
        xclient.message_type = gdk_x11_get_xatom_by_name_for_display (display,
                                                                    "_NET_ACTIVE_WINDOW");
        xclient.format = 32;
        xclient.data.l[0] = 2; /* requestor type; we're a tool */
        xclient.data.l[1] = timestamp;
        xclient.data.l[2] = None; /* currently active window */
        xclient.data.l[3] = 0;
        xclient.data.l[4] = 0;

        XSendEvent (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XROOTWIN (window), False,
                    SubstructureRedirectMask | SubstructureNotifyMask,
                    (XEvent *)&xclient);
    }
}
Exemplo n.º 4
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));
}
Exemplo n.º 5
0
void
_gdk_x11_window_process_expose (GdkWindow    *window,
                                gulong        serial,
                                GdkRectangle *area)
{
  cairo_region_t *invalidate_region = cairo_region_create_rectangle (area);
  GdkX11Display *display_x11 = GDK_X11_DISPLAY (GDK_WINDOW_DISPLAY (window));

  if (display_x11->translate_queue)
    {
      GList *tmp_list = display_x11->translate_queue->head;

      while (tmp_list)
        {
          GdkWindowQueueItem *item = tmp_list->data;
          GList *next = tmp_list->next;

          /* an overflow-safe (serial < item->serial) */
          if (serial - item->serial > (gulong) G_MAXLONG)
            {
              if (item->window == window)
		cairo_region_subtract (invalidate_region, item->antiexpose_area);
            }
          else
            {
              queue_delete_link (display_x11->translate_queue, tmp_list);
              queue_item_free (item);
            }
          tmp_list = next;
        }
    }

  if (!cairo_region_is_empty (invalidate_region))
    _gdk_window_invalidate_for_expose (window, invalidate_region);

  cairo_region_destroy (invalidate_region);
}
Exemplo n.º 6
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);
}
Exemplo n.º 7
0
static void
gdk_window_queue (GdkWindow          *window,
		  GdkWindowQueueItem *item)
{
  GdkX11Display *display_x11 = GDK_X11_DISPLAY (GDK_WINDOW_DISPLAY (window));
  
  if (!display_x11->translate_queue)
    display_x11->translate_queue = g_queue_new ();

  /* Keep length of queue finite by, if it grows too long,
   * figuring out the latest relevant serial and discarding
   * irrelevant queue items.
   */
  if (display_x11->translate_queue->length >= 64)
    {
      gulong serial = find_current_serial (GDK_WINDOW_XDISPLAY (window));
      GList *tmp_list = display_x11->translate_queue->head;
      
      while (tmp_list)
	{
	  GdkWindowQueueItem *item = tmp_list->data;
	  GList *next = tmp_list->next;
	  
	  /* an overflow-safe (item->serial < serial) */
	  if (item->serial - serial > (gulong) G_MAXLONG)
	    {
	      queue_delete_link (display_x11->translate_queue, tmp_list);
	      queue_item_free (item);
	    }

	  tmp_list = next;
	}
    }

  /* Catch the case where someone isn't processing events and there
   * is an event stuck in the event queue with an old serial:
   * If we can't reduce the queue length by the above method,
   * discard anti-expose items. (We can't discard translate
   * items 
   */
  if (display_x11->translate_queue->length >= 64)
    {
      GList *tmp_list = display_x11->translate_queue->head;
      
      while (tmp_list)
	{
	  GdkWindowQueueItem *item = tmp_list->data;
	  GList *next = tmp_list->next;
	  
	  queue_delete_link (display_x11->translate_queue, tmp_list);
	  queue_item_free (item);

	  tmp_list = next;
	}
    }

  item->window = window;
  item->serial = NextRequest (GDK_WINDOW_XDISPLAY (window));
  
  g_object_add_weak_pointer (G_OBJECT (window),
			     (gpointer *)&(item->window));

  g_queue_push_tail (display_x11->translate_queue, item);
}
Exemplo n.º 8
0
gboolean
_gdk_x11_window_simulate_key (GdkWindow      *window,
                              gint            x,
                              gint            y,
                              guint           keyval,
                              GdkModifierType modifiers,
                              GdkEventType    key_pressrelease)
{
    GdkScreen *screen;
    GdkKeymapKey *keys = NULL;
    gboolean success;
    gint n_keys = 0;
    XKeyEvent xev = {
        0,  /* type */
        0,  /* serial */
        1,  /* send_event */
    };
    g_return_val_if_fail (key_pressrelease == GDK_KEY_PRESS || key_pressrelease == GDK_KEY_RELEASE, FALSE);
    g_return_val_if_fail (window != NULL, FALSE);
    if (!GDK_WINDOW_IS_MAPPED (window))
        return FALSE;

    screen = gdk_window_get_screen (window);

    if (x < 0 && y < 0)
    {
        x = window->width / 2;
        y = window->height / 2;
    }

    /* Convert to impl coordinates */
    x = x + window->abs_x;
    y = y + window->abs_y;

    xev.type = key_pressrelease == GDK_KEY_PRESS ? KeyPress : KeyRelease;
    xev.display = GDK_WINDOW_XDISPLAY (window);
    xev.window = GDK_WINDOW_XID (window);
    xev.root = RootWindow (xev.display, GDK_X11_SCREEN (screen)->screen_num);
    xev.subwindow = 0;
    xev.time = 0;
    xev.x = MAX (x, 0);
    xev.y = MAX (y, 0);
    xev.x_root = 0;
    xev.y_root = 0;
    xev.state = modifiers;
    xev.keycode = 0;
    success = gdk_keymap_get_entries_for_keyval (gdk_keymap_get_for_display (gdk_window_get_display (window)), keyval, &keys, &n_keys);
    success &= n_keys > 0;
    if (success)
    {
        gint i;
        for (i = 0; i < n_keys; i++)
            if (keys[i].group == 0 && (keys[i].level == 0 || keys[i].level == 1))
            {
                xev.keycode = keys[i].keycode;
                if (keys[i].level == 1)
                {
                    /* Assume shift takes us to level 1 */
                    xev.state |= GDK_SHIFT_MASK;
                }
                break;
            }
        if (i >= n_keys) /* no match for group==0 and level==0 or 1 */
            xev.keycode = keys[0].keycode;
    }
    g_free (keys);
    if (!success)
        return FALSE;
    gdk_x11_display_error_trap_push (GDK_WINDOW_DISPLAY (window));
    xev.same_screen = XTranslateCoordinates (xev.display, xev.window, xev.root,
                      xev.x, xev.y, &xev.x_root, &xev.y_root,
                      &xev.subwindow);
    if (!xev.subwindow)
        xev.subwindow = xev.window;
    success &= xev.same_screen;
    if (x >= 0 && y >= 0)
        success &= 0 != XWarpPointer (xev.display, None, xev.window, 0, 0, 0, 0, xev.x, xev.y);
    success &= 0 != XSendEvent (xev.display, xev.window, True, key_pressrelease == GDK_KEY_PRESS ? KeyPressMask : KeyReleaseMask, (XEvent*) &xev);
    XSync (xev.display, False);
    success &= 0 == gdk_x11_display_error_trap_pop (GDK_WINDOW_DISPLAY (window));
    return success;
}