Ejemplo n.º 1
0
gboolean XInputUtils::onMouseLeaveNotifyEvent(GtkWidget* widget,
                                              GdkEventCrossing* event)
{
	if(!XInputUtils::enableLeafEnterWorkaround)
	{
		return FALSE;
	}

	INPUTDBG("leave notify (mode=%d, details=%d)\n", event->mode, event->detail);

	/* emergency disable XInput to avoid segfaults (GTK+ 2.17) or
	 interface non-responsiveness (GTK+ 2.18) */
	if (!gtk_check_version(2, 17, 0))
	{
		gdk_flush();
		gdk_error_trap_push();
		for (GList* dev_list = gdk_devices_list(); dev_list != NULL;
		     dev_list = dev_list->next)
		{
			GdkDevice* dev = GDK_DEVICE(dev_list->data);
			gdk_device_set_mode(dev, GDK_MODE_DISABLED);
		}
		gdk_flush();
		gdk_error_trap_pop();
	}
	return FALSE;
}
Ejemplo n.º 2
0
gboolean XInputUtils::onMouseEnterNotifyEvent(GtkWidget* widget,
                                              GdkEventCrossing* event)
{
	if(!XInputUtils::enableLeafEnterWorkaround)
	{
		return FALSE;
	}

	INPUTDBG("enter notify\n");

	/* re-enable input devices after they've been emergency-disabled
	 by leave_notify */
	if (!gtk_check_version(2, 17, 0))
	{
		gdk_flush();
		gdk_error_trap_push();
		for (GList* dev_list = gdk_devices_list(); dev_list != NULL;
		     dev_list = dev_list->next)
		{
			GdkDevice* dev = GDK_DEVICE(dev_list->data);
			gdk_device_set_mode(dev, GDK_MODE_SCREEN);
		}
		gdk_flush();
		gdk_error_trap_pop();
	}
	return FALSE;
}
Ejemplo n.º 3
0
static void
gdk_device_virtual_init (GdkDeviceVirtual *device_virtual)
{
  GdkDevice *device;

  device = GDK_DEVICE (device_virtual);

}
Ejemplo n.º 4
0
static void
gdk_device_win32_init (GdkDeviceWin32 *device_win32)
{
  GdkDevice *device;

  device = GDK_DEVICE (device_win32);

  _gdk_device_add_axis (device, GDK_NONE, GDK_AXIS_X, 0, 0, 1);
  _gdk_device_add_axis (device, GDK_NONE, GDK_AXIS_Y, 0, 0, 1);
}
Ejemplo n.º 5
0
static void
gdk_broadway_device_init (GdkBroadwayDevice *device_core)
{
  GdkDevice *device;

  device = GDK_DEVICE (device_core);

  _gdk_device_add_axis (device, GDK_NONE, GDK_AXIS_X, 0, 0, 1);
  _gdk_device_add_axis (device, GDK_NONE, GDK_AXIS_Y, 0, 0, 1);
}
Ejemplo n.º 6
0
USER_OBJECT_
S_GdkDeviceGetNumKeys (USER_OBJECT_ s_obj)
{
   USER_OBJECT_ _result = NULL_USER_OBJECT;

   GdkDevice *obj;
   gint val;

   obj = GDK_DEVICE(getPtrValue(s_obj)) ;
   val = obj->num_keys;
   _result = asRInteger(val);

   return(_result);
} 
Ejemplo n.º 7
0
USER_OBJECT_
S_GdkDeviceGetAxes (USER_OBJECT_ s_obj)
{
   USER_OBJECT_ _result = NULL_USER_OBJECT;

   GdkDevice *obj;
   GdkDeviceAxis* val;

   obj = GDK_DEVICE(getPtrValue(s_obj)) ;
   val = obj->axes;
   _result = toRPointer(val, "GdkDeviceAxis");

   return(_result);
} 
Ejemplo n.º 8
0
USER_OBJECT_
S_GdkDeviceGetHasCursor (USER_OBJECT_ s_obj)
{
   USER_OBJECT_ _result = NULL_USER_OBJECT;

   GdkDevice *obj;
   gboolean val;

   obj = GDK_DEVICE(getPtrValue(s_obj)) ;
   val = obj->has_cursor;
   _result = asRLogical(val);

   return(_result);
} 
Ejemplo n.º 9
0
USER_OBJECT_
S_GdkDeviceGetMode (USER_OBJECT_ s_obj)
{
   USER_OBJECT_ _result = NULL_USER_OBJECT;

   GdkDevice *obj;
   GdkInputMode val;

   obj = GDK_DEVICE(getPtrValue(s_obj)) ;
   val = obj->mode;
   _result = asREnum(val, GDK_TYPE_INPUT_MODE);

   return(_result);
} 
Ejemplo n.º 10
0
USER_OBJECT_
S_GdkDeviceGetName (USER_OBJECT_ s_obj)
{
   USER_OBJECT_ _result = NULL_USER_OBJECT;

   GdkDevice *obj;
   gchar* val;

   obj = GDK_DEVICE(getPtrValue(s_obj)) ;
   val = obj->name;
   _result = asRString(val);

   return(_result);
} 
Ejemplo n.º 11
0
JS_EXPORT_API
void guide_disable_keyboard()
{
    // gdk_keyboard_grab(gtk_widget_get_window(get_container()), FALSE, GDK_CURRENT_TIME);
    GdkWindow* window = gtk_widget_get_window(get_container());
    GdkDisplay* display = gdk_window_get_display(window);
    GdkDeviceManager* manager = gdk_display_get_device_manager(display);
    GList* devices = gdk_device_manager_list_devices(manager, GDK_DEVICE_TYPE_MASTER);
    GdkDevice* device = NULL;
    for (GList* dev = devices; dev != NULL; dev = dev->next) {
        device = GDK_DEVICE(dev->data);

        if (gdk_device_get_source(device) != GDK_SOURCE_KEYBOARD) {
            continue;
        }

        GdkGrabStatus res = gdk_device_grab(device,
                                            window,
                                            GDK_OWNERSHIP_NONE,
                                            FALSE,
                                            GDK_KEY_PRESS_MASK|GDK_KEY_RELEASE_MASK,
                                            NULL,
                                            GDK_CURRENT_TIME
                                           );
        switch (res) {
        case GDK_GRAB_ALREADY_GRABBED:
            g_warning("Grab falied, device %s is already grabbed.", gdk_device_get_name(device));
            break;
        case GDK_GRAB_INVALID_TIME:
            g_warning("Grab failed, the resource is grabbed more recently than the specified time.");
            break;
        case GDK_GRAB_NOT_VIEWABLE:
            g_warning("Grab falied, the window is not viewable.");
            break;
        case GDK_GRAB_FROZEN:
            g_warning("Grab falied, the resources is frozen.");
            break;
        case GDK_GRAB_SUCCESS:
            break;
        }
    }

    g_list_free(devices);
}
Ejemplo n.º 12
0
JS_EXPORT_API
void guide_enable_keyboard()
{
    // gdk_keyboard_ungrab(GDK_CURRENT_TIME);
    GdkWindow* window = gtk_widget_get_window(get_container());
    GdkDisplay* display = gdk_window_get_display(window);
    GdkDeviceManager* manager = gdk_display_get_device_manager(display);
    GList* devices = gdk_device_manager_list_devices(manager, GDK_DEVICE_TYPE_MASTER);
    GdkDevice* device = NULL;
    for (GList* dev = devices; dev != NULL; dev = dev->next) {
        device = GDK_DEVICE(dev->data);

        if (gdk_device_get_source(device) != GDK_SOURCE_KEYBOARD) {
            continue;
        }

        gdk_device_ungrab(device, GDK_CURRENT_TIME);
    }
    g_list_free(devices);
}
Ejemplo n.º 13
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;
}
Ejemplo n.º 14
0
static void
_gdk_input_wintab_init_check (GdkDeviceManagerWin32 *device_manager)
{
  static gboolean wintab_initialized = FALSE;
  GdkDeviceWintab *device;
  GdkWindowAttr wa;
  WORD specversion;
  HCTX *hctx;
  UINT ndevices, ncursors, ncsrtypes, firstcsr, hardware;
  BOOL active;
  DWORD physid;
  AXIS axis_x, axis_y, axis_npressure, axis_or[3];
  int i, devix, cursorix, num_axes = 0;
  wchar_t devname[100], csrname[100];
  gchar *devname_utf8, *csrname_utf8, *device_name;
  BOOL defcontext_done;
  HMODULE wintab32;
  char *wintab32_dll_path;
  char dummy;
  int n, k;

  if (wintab_initialized)
    return;

  wintab_initialized = TRUE;

  wintab_contexts = NULL;

  if (_gdk_input_ignore_wintab)
    return;

  n = GetSystemDirectory (&dummy, 0);

  if (n <= 0)
    return;

  wintab32_dll_path = g_malloc (n + 1 + strlen (WINTAB32_DLL));
  k = GetSystemDirectory (wintab32_dll_path, n);
  
  if (k == 0 || k > n)
    {
      g_free (wintab32_dll_path);
      return;
    }

  if (!G_IS_DIR_SEPARATOR (wintab32_dll_path[strlen (wintab32_dll_path) -1]))
    strcat (wintab32_dll_path, G_DIR_SEPARATOR_S);
  strcat (wintab32_dll_path, WINTAB32_DLL);

  if ((wintab32 = LoadLibrary (wintab32_dll_path)) == NULL)
    return;

  if ((p_WTInfoA = (t_WTInfoA) GetProcAddress (wintab32, "WTInfoA")) == NULL)
    return;
  if ((p_WTInfoW = (t_WTInfoW) GetProcAddress (wintab32, "WTInfoW")) == NULL)
    return;
  if ((p_WTEnable = (t_WTEnable) GetProcAddress (wintab32, "WTEnable")) == NULL)
    return;
  if ((p_WTOpenA = (t_WTOpenA) GetProcAddress (wintab32, "WTOpenA")) == NULL)
    return;
  if ((p_WTOverlap = (t_WTOverlap) GetProcAddress (wintab32, "WTOverlap")) == NULL)
    return;
  if ((p_WTPacket = (t_WTPacket) GetProcAddress (wintab32, "WTPacket")) == NULL)
    return;
  if ((p_WTQueueSizeSet = (t_WTQueueSizeSet) GetProcAddress (wintab32, "WTQueueSizeSet")) == NULL)
    return;

  if (!(*p_WTInfoA) (0, 0, NULL))
    return;

  (*p_WTInfoA) (WTI_INTERFACE, IFC_SPECVERSION, &specversion);
  GDK_NOTE (INPUT, g_print ("Wintab interface version %d.%d\n",
			    HIBYTE (specversion), LOBYTE (specversion)));
  (*p_WTInfoA) (WTI_INTERFACE, IFC_NDEVICES, &ndevices);
  (*p_WTInfoA) (WTI_INTERFACE, IFC_NCURSORS, &ncursors);
#if DEBUG_WINTAB
  GDK_NOTE (INPUT, g_print ("NDEVICES: %d, NCURSORS: %d\n",
			    ndevices, ncursors));
#endif
  /* Create a dummy window to receive wintab events */
  wa.wclass = GDK_INPUT_OUTPUT;
  wa.event_mask = GDK_ALL_EVENTS_MASK;
  wa.width = 2;
  wa.height = 2;
  wa.x = -100;
  wa.y = -100;
  wa.window_type = GDK_WINDOW_TOPLEVEL;
  if ((wintab_window = gdk_window_new (NULL, &wa, GDK_WA_X|GDK_WA_Y)) == NULL)
    {
      g_warning ("gdk_input_wintab_init: gdk_window_new failed");
      return;
    }
  g_object_ref (wintab_window);

  for (devix = 0; devix < ndevices; devix++)
    {
      LOGCONTEXT lc;

      /* We open the Wintab device (hmm, what if there are several, or
       * can there even be several, probably not?) as a system
       * pointing device, i.e. it controls the normal Windows
       * cursor. This seems much more natural.
       */

      (*p_WTInfoW) (WTI_DEVICES + devix, DVC_NAME, devname);
      devname_utf8 = g_utf16_to_utf8 (devname, -1, NULL, NULL, NULL);
#ifdef DEBUG_WINTAB
      GDK_NOTE (INPUT, (g_print("Device %d: %s\n", devix, devname_utf8)));
#endif
      (*p_WTInfoA) (WTI_DEVICES + devix, DVC_NCSRTYPES, &ncsrtypes);
      (*p_WTInfoA) (WTI_DEVICES + devix, DVC_FIRSTCSR, &firstcsr);
      (*p_WTInfoA) (WTI_DEVICES + devix, DVC_HARDWARE, &hardware);
      (*p_WTInfoA) (WTI_DEVICES + devix, DVC_X, &axis_x);
      (*p_WTInfoA) (WTI_DEVICES + devix, DVC_Y, &axis_y);
      (*p_WTInfoA) (WTI_DEVICES + devix, DVC_NPRESSURE, &axis_npressure);
      (*p_WTInfoA) (WTI_DEVICES + devix, DVC_ORIENTATION, axis_or);

      defcontext_done = FALSE;
      if (HIBYTE (specversion) > 1 || LOBYTE (specversion) >= 1)
        {
          /* Try to get device-specific default context */
          /* Some drivers, e.g. Aiptek, don't provide this info */
          if ((*p_WTInfoA) (WTI_DSCTXS + devix, 0, &lc) > 0)
            defcontext_done = TRUE;
#if DEBUG_WINTAB
          if (defcontext_done)
            GDK_NOTE (INPUT, (g_print("Using device-specific default context\n")));
          else
            GDK_NOTE (INPUT, (g_print("Note: Driver did not provide device specific default context info despite claiming to support version 1.1\n")));
#endif
        }

      if (!defcontext_done)
        (*p_WTInfoA) (WTI_DEFSYSCTX, 0, &lc);
#if DEBUG_WINTAB
      GDK_NOTE (INPUT, (g_print("Default context:\n"), print_lc(&lc)));
#endif
      lc.lcOptions |= CXO_MESSAGES;
      lc.lcStatus = 0;
      lc.lcMsgBase = WT_DEFBASE;
      lc.lcPktRate = 0;
      lc.lcPktData = PACKETDATA;
      lc.lcPktMode = PACKETMODE;
      lc.lcMoveMask = PACKETDATA;
      lc.lcBtnUpMask = lc.lcBtnDnMask = ~0;
      lc.lcOutOrgX = axis_x.axMin;
      lc.lcOutOrgY = axis_y.axMin;
      lc.lcOutExtX = axis_x.axMax - axis_x.axMin;
      lc.lcOutExtY = axis_y.axMax - axis_y.axMin;
      lc.lcOutExtY = -lc.lcOutExtY; /* We want Y growing downward */
#if DEBUG_WINTAB
      GDK_NOTE (INPUT, (g_print("context for device %d:\n", devix),
			print_lc(&lc)));
#endif
      hctx = g_new (HCTX, 1);
      if ((*hctx = (*p_WTOpenA) (GDK_WINDOW_HWND (wintab_window), &lc, TRUE)) == NULL)
        {
          g_warning ("gdk_input_wintab_init: WTOpen failed");
          return;
        }
      GDK_NOTE (INPUT, g_print ("opened Wintab device %d %p\n",
                                devix, *hctx));

      wintab_contexts = g_list_append (wintab_contexts, hctx);
#if 0
      (*p_WTEnable) (*hctx, TRUE);
#endif
      (*p_WTOverlap) (*hctx, TRUE);

#if DEBUG_WINTAB
      GDK_NOTE (INPUT, (g_print("context for device %d after WTOpen:\n", devix),
			print_lc(&lc)));
#endif
      /* Increase packet queue size to reduce the risk of lost packets.
       * According to the specs, if the function fails we must try again
       * with a smaller queue size.
       */
      GDK_NOTE (INPUT, g_print("Attempting to increase queue size\n"));
      for (i = 32; i >= 1; i >>= 1)
        {
          if ((*p_WTQueueSizeSet) (*hctx, i))
            {
              GDK_NOTE (INPUT, g_print("Queue size set to %d\n", i));
              break;
            }
        }
      if (!i)
        GDK_NOTE (INPUT, g_print("Whoops, no queue size could be set\n"));
      for (cursorix = firstcsr; cursorix < firstcsr + ncsrtypes; cursorix++)
        {
#ifdef DEBUG_WINTAB
          GDK_NOTE (INPUT, (g_print("Cursor %d:\n", cursorix), print_cursor (cursorix)));
#endif
          active = FALSE;
          (*p_WTInfoA) (WTI_CURSORS + cursorix, CSR_ACTIVE, &active);
          if (!active)
            continue;

          /* Wacom tablets seem to report cursors corresponding to
           * nonexistent pens or pucks. At least my ArtPad II reports
           * six cursors: a puck, pressure stylus and eraser stylus,
           * and then the same three again. I only have a
           * pressure-sensitive pen. The puck instances, and the
           * second instances of the styluses report physid zero. So
           * at least for Wacom, skip cursors with physid zero.
           */
          (*p_WTInfoA) (WTI_CURSORS + cursorix, CSR_PHYSID, &physid);
          if (wcscmp (devname, L"WACOM Tablet") == 0 && physid == 0)
            continue;

          (*p_WTInfoW) (WTI_CURSORS + cursorix, CSR_NAME, csrname);
          csrname_utf8 = g_utf16_to_utf8 (csrname, -1, NULL, NULL, NULL);
          device_name = g_strconcat (devname_utf8, " ", csrname_utf8, NULL);

          device = g_object_new (GDK_TYPE_DEVICE_WINTAB,
                                 "name", device_name,
                                 "type", GDK_DEVICE_TYPE_SLAVE,
                                 "source", GDK_SOURCE_PEN,
                                 "mode", GDK_MODE_SCREEN,
                                 "has-cursor", FALSE,
                                 "display", _gdk_display,
                                 "device-manager", device_manager,
                                 NULL);

          g_free (csrname_utf8);

          device->hctx = *hctx;
          device->cursor = cursorix;
          (*p_WTInfoA) (WTI_CURSORS + cursorix, CSR_PKTDATA, &device->pktdata);

          if (device->pktdata & PK_X)
            {
              _gdk_device_add_axis (GDK_DEVICE (device),
                                    GDK_NONE,
                                    GDK_AXIS_X,
                                    axis_x.axMin,
                                    axis_x.axMax,
                                    axis_x.axResolution / 65535);
              num_axes++;
            }

          if (device->pktdata & PK_Y)
            {
              _gdk_device_add_axis (GDK_DEVICE (device),
                                    GDK_NONE,
                                    GDK_AXIS_Y,
                                    axis_y.axMin,
                                    axis_y.axMax,
                                    axis_y.axResolution / 65535);
              num_axes++;
            }


          if (device->pktdata & PK_NORMAL_PRESSURE)
            {
              _gdk_device_add_axis (GDK_DEVICE (device),
                                    GDK_NONE,
                                    GDK_AXIS_PRESSURE,
                                    axis_npressure.axMin,
                                    axis_npressure.axMax,
                                    axis_npressure.axResolution / 65535);
              num_axes++;
            }

          /* The wintab driver for the Wacom ArtPad II reports
           * PK_ORIENTATION in CSR_PKTDATA, but the tablet doesn't
           * actually sense tilt. Catch this by noticing that the
           * orientation axis's azimuth resolution is zero.
           */
          if ((device->pktdata & PK_ORIENTATION) && axis_or[0].axResolution == 0)
            {
              device->orientation_axes[0] = axis_or[0];
              device->orientation_axes[1] = axis_or[1];

              /* Wintab gives us aximuth and altitude, which
               * we convert to x and y tilt in the -1000..1000 range
               */
              _gdk_device_add_axis (GDK_DEVICE (device),
                                    GDK_NONE,
                                    GDK_AXIS_XTILT,
                                    -1000,
                                    1000,
                                    1000);

              _gdk_device_add_axis (GDK_DEVICE (device),
                                    GDK_NONE,
                                    GDK_AXIS_YTILT,
                                    -1000,
                                    1000,
                                    1000);
              num_axes += 2;
            }

          device->last_axis_data = g_new (gint, num_axes);

          GDK_NOTE (INPUT, g_print ("device: (%d) %s axes: %d\n",
                                    cursorix,
                                    device_name,
                                    num_axes));

#if 0
          for (i = 0; i < gdkdev->info.num_axes; i++)
            GDK_NOTE (INPUT, g_print ("... axis %d: %d--%d@%d\n",
                                      i,
                                      gdkdev->axes[i].min_value,
                                      gdkdev->axes[i].max_value,
                                      gdkdev->axes[i].resolution));
#endif

          device_manager->wintab_devices = g_list_append (device_manager->wintab_devices,
                                                          device);

          g_free (device_name);
        }

      g_free (devname_utf8);
    }
}
Ejemplo n.º 15
0
void
_gdk_device_wintab_translate_axes (GdkDeviceWintab *device_wintab,
                                   GdkSurface       *window,
                                   gdouble         *axes,
                                   gdouble         *x,
                                   gdouble         *y)
{
  GdkDevice *device;
  GdkSurface *impl_surface;
  gint root_x, root_y;
  gdouble temp_x, temp_y;
  gint i;

  device = GDK_DEVICE (device_wintab);
  impl_surface = _gdk_surface_get_impl_surface (window);
  temp_x = temp_y = 0;

  gdk_surface_get_origin (impl_surface, &root_x, &root_y);

  for (i = 0; i < gdk_device_get_n_axes (device); i++)
    {
      GdkAxisUse use;

      use = gdk_device_get_axis_use (device, i);

      switch (use)
        {
        case GDK_AXIS_X:
        case GDK_AXIS_Y:
          if (gdk_device_get_mode (device) == GDK_MODE_SURFACE)
            _gdk_device_translate_surface_coord (device, window, i,
                                                device_wintab->last_axis_data[i],
                                                &axes[i]);
          else
            {
              HMONITOR hmonitor;
              MONITORINFO minfo = {sizeof (MONITORINFO),};

              hmonitor = MonitorFromWindow (GDK_SURFACE_HWND (window),
                                            MONITOR_DEFAULTTONEAREST);
              GetMonitorInfo (hmonitor, &minfo);

              /* XXX: the dimensions from minfo may need to be scaled for HiDPI usage */
              _gdk_device_translate_screen_coord (device, window,
                                                  root_x, root_y,
                                                  minfo.rcWork.right - minfo.rcWork.left,
                                                  minfo.rcWork.bottom - minfo.rcWork.top,
                                                  i,
                                                  device_wintab->last_axis_data[i],
                                                  &axes[i]);
            }
          if (use == GDK_AXIS_X)
            temp_x = axes[i];
          else if (use == GDK_AXIS_Y)
            temp_y = axes[i];

          break;
        default:
          _gdk_device_translate_axis (device, i,
                                      device_wintab->last_axis_data[i],
                                      &axes[i]);
          break;
        }
    }

  if (x)
    *x = temp_x;

  if (y)
    *y = temp_y;
}