예제 #1
0
static void
gdk_broadway_device_ungrab (GdkDevice *device,
			    guint32    time_)
{
  GdkDisplay *display;
  GdkBroadwayDisplay *broadway_display;
  GdkDeviceGrabInfo *grab;
  guint32 serial;

  display = gdk_device_get_display (device);
  broadway_display = GDK_BROADWAY_DISPLAY (display);

  if (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD)
    {
      /* Device is a keyboard */
    }
  else
    {
      /* Device is a pointer */

      if (broadway_display->output)
	{
	  serial = broadway_output_ungrab_pointer (broadway_display->output, time_);

	  gdk_display_flush (display);

	  grab = _gdk_display_get_last_device_grab (display, device);
	  if (grab &&
	      (time_ == GDK_CURRENT_TIME ||
	       grab->time == GDK_CURRENT_TIME ||
	       !TIME_IS_LATER (grab->time, time_)))
	    grab->serial_end = serial;
	}
    }
}
예제 #2
0
파일: gdkmain-x11.c 프로젝트: Davletvm/gtk
/*
 * _gdk_x11_window_grab_check_destroy:
 * @window: a #GdkWindow
 * 
 * Checks to see if window is the current grab window, and if
 * so, clear the current grab window.
 **/
void
_gdk_x11_window_grab_check_destroy (GdkWindow *window)
{
  GdkDisplay *display = gdk_window_get_display (window);
  GdkDeviceManager *device_manager;
  GdkDeviceGrabInfo *grab;
  GList *devices, *d;

  device_manager = gdk_display_get_device_manager (display);

  /* Get all devices */
  devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
  devices = g_list_concat (devices, gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_SLAVE));
  devices = g_list_concat (devices, gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_FLOATING));

  for (d = devices; d; d = d->next)
    {
      /* Make sure there is no lasting grab in this native window */
      grab = _gdk_display_get_last_device_grab (display, d->data);

      if (grab && grab->native_window == window)
        {
          /* We don't know the actual serial to end, but it
             doesn't really matter as this only happens
             after we get told of the destroy from the
             server so we know its ended in the server,
             just make sure its ended. */
          grab->serial_end = grab->serial_start;
          grab->implicit_ungrab = TRUE;
        }
    }

  g_list_free (devices);
}
예제 #3
0
void
_gdk_broadway_window_grab_check_destroy (GdkWindow *window)
{
    GdkDisplay *display = gdk_window_get_display (window);
    GdkDeviceManager *device_manager;
    GdkDeviceGrabInfo *grab;
    GList *devices, *d;

    G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
    device_manager = gdk_display_get_device_manager (display);

    /* Get all devices */
    devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
    G_GNUC_END_IGNORE_DEPRECATIONS;

    for (d = devices; d; d = d->next)
    {
        /* Make sure there is no lasting grab in this native window */
        grab = _gdk_display_get_last_device_grab (display, d->data);

        if (grab && grab->native_window == window)
        {
            grab->serial_end = grab->serial_start;
            grab->implicit_ungrab = TRUE;
        }

    }

    g_list_free (devices);
}
예제 #4
0
static void
gdk_device_win32_ungrab (GdkDevice *device,
                         guint32    time_)
{
    GdkDeviceGrabInfo *info;
    GdkDisplay *display;

    display = gdk_device_get_display (device);
    info = _gdk_display_get_last_device_grab (display, device);

    if (info)
        info->serial_end = 0;

    if (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD)
        ReleaseCapture ();

    _gdk_display_device_grab_update (display, device, NULL, 0);
}
예제 #5
0
gboolean
_gdk_input_other_event (GdkEvent  *event,
                        MSG       *msg,
                        GdkWindow *window)
{
  GdkDisplay *display;
  GdkDeviceWintab *device = NULL;
  GdkDeviceGrabInfo *last_grab;
  GdkEventMask masktest;
  guint key_state;
  POINT pt;

  PACKET packet;
  gdouble root_x, root_y;
  gint num_axes;
  gint x, y;
  guint translated_buttons, button_diff, button_mask;
  /* Translation from tablet button state to GDK button state for
   * buttons 1-3 - swap button 2 and 3.
   */
  static guint button_map[8] = {0, 1, 4, 5, 2, 3, 6, 7};

  if (event->any.window != wintab_window)
    {
      g_warning ("_gdk_input_other_event: not wintab_window?");
      return FALSE;
    }

  window = gdk_window_at_pointer (&x, &y);
  if (window == NULL)
    window = _gdk_root;

  g_object_ref (window);
  display = gdk_window_get_display (window);

  GDK_NOTE (EVENTS_OR_INPUT,
	    g_print ("_gdk_input_other_event: window=%p %+d%+d\n",
               GDK_WINDOW_HWND (window), x, y));

  if (msg->message == WT_PACKET)
    {
      if (!(*p_WTPacket) ((HCTX) msg->lParam, msg->wParam, &packet))
        return FALSE;
    }

  switch (msg->message)
    {
    case WT_PACKET:
      /* Don't produce any button or motion events while a window is being
       * moved or resized, see bug #151090.
       */
      if (_modal_operation_in_progress)
        {
          GDK_NOTE (EVENTS_OR_INPUT, g_print ("... ignored when moving/sizing\n"));
          return FALSE;
        }

      if ((device = _gdk_device_manager_find_wintab_device ((HCTX) msg->lParam,
                                                            packet.pkCursor)) == NULL)
        return FALSE;

      if (gdk_device_get_mode (GDK_DEVICE (device)) == GDK_MODE_DISABLED)
        return FALSE;

      last_grab = _gdk_display_get_last_device_grab (_gdk_display, GDK_DEVICE (device));

      if (last_grab && last_grab->window)
        {
          g_object_unref (window);

          window = g_object_ref (last_grab->window);
        }

      if (window == _gdk_root)
        {
          GDK_NOTE (EVENTS_OR_INPUT, g_print ("... is root\n"));
          return FALSE;
        }

      num_axes = 0;
      if (device->pktdata & PK_X)
        device->last_axis_data[num_axes++] = packet.pkX;
      if (device->pktdata & PK_Y)
        device->last_axis_data[num_axes++] = packet.pkY;
      if (device->pktdata & PK_NORMAL_PRESSURE)
        device->last_axis_data[num_axes++] = packet.pkNormalPressure;
      if (device->pktdata & PK_ORIENTATION)
        {
          decode_tilt (device->last_axis_data + num_axes,
                       device->orientation_axes, &packet);
          num_axes += 2;
        }

      translated_buttons = button_map[packet.pkButtons & 0x07] | (packet.pkButtons & ~0x07);

      if (translated_buttons != device->button_state)
        {
          /* At least one button has changed state so produce a button event
           * If more than one button has changed state (unlikely),
           * just care about the first and act on the next the next time
           * we get a packet
           */
          button_diff = translated_buttons ^ device->button_state;

          /* Gdk buttons are numbered 1.. */
          event->button.button = 1;

          for (button_mask = 1; button_mask != 0x80000000;
               button_mask <<= 1, event->button.button++)
            {
              if (button_diff & button_mask)
                {
                  /* Found a button that has changed state */
                  break;
                }
            }

          if (!(translated_buttons & button_mask))
            {
              event->any.type = GDK_BUTTON_RELEASE;
              masktest = GDK_BUTTON_RELEASE_MASK;
            }
          else
            {
              event->any.type = GDK_BUTTON_PRESS;
              masktest = GDK_BUTTON_PRESS_MASK;
            }
          device->button_state ^= button_mask;
        }
      else
        {
          event->any.type = GDK_MOTION_NOTIFY;
          masktest = GDK_POINTER_MOTION_MASK;
          if (device->button_state & (1 << 0))
            masktest |= GDK_BUTTON_MOTION_MASK | GDK_BUTTON1_MOTION_MASK;
          if (device->button_state & (1 << 1))
            masktest |= GDK_BUTTON_MOTION_MASK | GDK_BUTTON2_MOTION_MASK;
          if (device->button_state & (1 << 2))
            masktest |= GDK_BUTTON_MOTION_MASK | GDK_BUTTON3_MOTION_MASK;
        }

      /* Now we can check if the window wants the event, and
       * propagate if necessary.
       */
      while (gdk_window_get_device_events (window, GDK_DEVICE (device)) == 0)
        {
          GDK_NOTE (EVENTS_OR_INPUT, g_print ("... not selected\n"));

          if (window->parent == GDK_WINDOW (_gdk_root))
            return FALSE;

          /* It is not good to propagate the extended events up to the parent
           * if this window wants normal (not extended) motion/button events */
          if (window->event_mask & masktest)
            {
              GDK_NOTE (EVENTS_OR_INPUT,
                        g_print ("... wants ordinary event, ignoring this\n"));
              return FALSE;
            }

          pt.x = x;
          pt.y = y;
          ClientToScreen (GDK_WINDOW_HWND (window), &pt);
          g_object_unref (window);
          window = window->parent;
          g_object_ref (window);
          ScreenToClient (GDK_WINDOW_HWND (window), &pt);
          x = pt.x;
          y = pt.y;
          GDK_NOTE (EVENTS_OR_INPUT, g_print ("... propagating to %p %+d%+d\n",
                                              GDK_WINDOW_HWND (window), x, y));
        }

      if (gdk_window_get_device_events (window, GDK_DEVICE (device)) == 0)
        return FALSE;

      event->any.window = window;
      key_state = get_modifier_key_state ();
      if (event->any.type == GDK_BUTTON_PRESS ||
          event->any.type == GDK_BUTTON_RELEASE)
        {
          event->button.time = _gdk_win32_get_next_tick (msg->time);
          gdk_event_set_device (event, GDK_DEVICE (device));

          event->button.axes = g_new (gdouble, num_axes);
          _gdk_device_wintab_get_window_coords (window, &root_x, &root_y);

          _gdk_device_wintab_translate_axes (device,
                                             window,
                                             event->button.axes,
                                             &event->button.x,
                                             &event->button.y);

          event->button.x_root = event->button.x + root_x;
          event->button.y_root = event->button.y + root_y;

          event->button.state =
            key_state | ((device->button_state << 8)
                         & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK
                            | GDK_BUTTON3_MASK | GDK_BUTTON4_MASK
                            | GDK_BUTTON5_MASK));

          GDK_NOTE (EVENTS_OR_INPUT,
                    g_print ("WINTAB button %s:%d %g,%g\n",
                             (event->button.type == GDK_BUTTON_PRESS ?
                              "press" : "release"),
                             event->button.button,
                             event->button.x, event->button.y));
        }
      else
        {
          event->motion.time = _gdk_win32_get_next_tick (msg->time);
          event->motion.is_hint = FALSE;
          gdk_event_set_device (event, GDK_DEVICE (device));

          event->motion.axes = g_new (gdouble, num_axes);
          _gdk_device_wintab_get_window_coords (window, &root_x, &root_y);

          _gdk_device_wintab_translate_axes (device,
                                             window,
                                             event->motion.axes,
                                             &event->motion.x,
                                             &event->motion.y);

          event->motion.x_root = event->motion.x + root_x;
          event->motion.y_root = event->motion.y + root_y;

          event->motion.state =
            key_state | ((device->button_state << 8)
                         & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK
                            | GDK_BUTTON3_MASK | GDK_BUTTON4_MASK
                            | GDK_BUTTON5_MASK));

          GDK_NOTE (EVENTS_OR_INPUT,
                    g_print ("WINTAB motion: %g,%g\n",
                             event->motion.x, event->motion.y));
        }
      return TRUE;

    case WT_PROXIMITY:
      if (LOWORD (msg->lParam) == 0)
        {
          event->proximity.type = GDK_PROXIMITY_OUT;
          set_ignore_core (FALSE);
        }
      else
        {
          event->proximity.type = GDK_PROXIMITY_IN;
          set_ignore_core (TRUE);
        }
      event->proximity.time = _gdk_win32_get_next_tick (msg->time);
      gdk_event_set_device (event, GDK_DEVICE (device));

      GDK_NOTE (EVENTS_OR_INPUT,
                g_print ("WINTAB proximity %s\n",
                         (event->proximity.type == GDK_PROXIMITY_IN ?
                          "in" : "out")));
      return TRUE;
    }

  return FALSE;
}