コード例 #1
0
ファイル: gdkdevice-wintab.c プロジェクト: GNOME/gtk
static void
gdk_device_wintab_get_state (GdkDevice       *device,
                             GdkSurface       *window,
                             gdouble         *axes,
                             GdkModifierType *mask)
{
  GdkDeviceWintab *device_wintab;

  device_wintab = GDK_DEVICE_WINTAB (device);

  /* For now just use the last known button and axis state of the device.
   * Since graphical tablets send an insane amount of motion events each
   * second, the info should be fairly up to date */
  if (mask)
    {
      *mask = get_current_mask ();
      *mask &= 0xFF; /* Mask away core pointer buttons */
      *mask |= ((device_wintab->button_state << 8)
                & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK
                   | GDK_BUTTON3_MASK | GDK_BUTTON4_MASK
                   | GDK_BUTTON5_MASK));
    }

  if (axes && device_wintab->last_axis_data)
    _gdk_device_wintab_translate_axes (device_wintab, window, axes, NULL, NULL);
}
コード例 #2
0
ファイル: gdkdevicemanager-win32.c プロジェクト: BYC/gtk
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;
}