示例#1
0
static void
gdk_x11_device_manager_core_constructed (GObject *object)
{
  GdkX11DeviceManagerCore *device_manager;
  GdkDisplay *display;

  device_manager = GDK_X11_DEVICE_MANAGER_CORE (object);
  display = gdk_device_manager_get_display (GDK_DEVICE_MANAGER (object));
  device_manager->core_pointer = create_core_pointer (GDK_DEVICE_MANAGER (device_manager), display);
  device_manager->core_keyboard = create_core_keyboard (GDK_DEVICE_MANAGER (device_manager), display);

  _gdk_device_set_associated_device (device_manager->core_pointer, device_manager->core_keyboard);
  _gdk_device_set_associated_device (device_manager->core_keyboard, device_manager->core_pointer);

  /* We expect subclasses to handle their own seats */
  if (G_OBJECT_TYPE (object) == GDK_TYPE_X11_DEVICE_MANAGER_CORE)
    {
      GdkSeat *seat;

      seat = gdk_seat_default_new_for_master_pair (device_manager->core_pointer,
                                                   device_manager->core_keyboard);

      gdk_display_add_seat (display, seat);
      g_object_unref (seat);
  }
}
示例#2
0
static void
gdk_device_manager_win32_constructed (GObject *object)
{
  GdkDeviceManagerWin32 *device_manager;

  device_manager = GDK_DEVICE_MANAGER_WIN32 (object);
  device_manager->core_pointer = create_core_pointer (GDK_DEVICE_MANAGER (device_manager));
  device_manager->core_keyboard = create_core_keyboard (GDK_DEVICE_MANAGER (device_manager));

  _gdk_device_set_associated_device (device_manager->core_pointer, device_manager->core_keyboard);
  _gdk_device_set_associated_device (device_manager->core_keyboard, device_manager->core_pointer);

  _gdk_input_wintab_init_check (device_manager);
}
示例#3
0
static void
gdk_x11_device_manager_core_constructed (GObject *object)
{
  GdkX11DeviceManagerCore *device_manager;
  GdkDisplay *display;

  device_manager = GDK_X11_DEVICE_MANAGER_CORE (object);
  display = gdk_device_manager_get_display (GDK_DEVICE_MANAGER (object));
  device_manager->core_pointer = create_core_pointer (GDK_DEVICE_MANAGER (device_manager), display);
  device_manager->core_keyboard = create_core_keyboard (GDK_DEVICE_MANAGER (device_manager), display);

  _gdk_device_set_associated_device (device_manager->core_pointer, device_manager->core_keyboard);
  _gdk_device_set_associated_device (device_manager->core_keyboard, device_manager->core_pointer);
}
示例#4
0
static void
gdk_device_manager_win32_constructed (GObject *object)
{
  GdkDeviceManagerWin32 *device_manager;
  GdkSeat *seat;

  device_manager = GDK_DEVICE_MANAGER_WIN32 (object);
  device_manager->core_pointer =
    create_pointer (GDK_DEVICE_MANAGER (device_manager),
		    GDK_TYPE_DEVICE_VIRTUAL,
		    "Virtual Core Pointer",
		    GDK_DEVICE_TYPE_MASTER);
  device_manager->system_pointer =
    create_pointer (GDK_DEVICE_MANAGER (device_manager),
		    GDK_TYPE_DEVICE_WIN32,
		    "System Aggregated Pointer",
		    GDK_DEVICE_TYPE_SLAVE);
  _gdk_device_virtual_set_active (device_manager->core_pointer,
				  device_manager->system_pointer);
  _gdk_device_set_associated_device (device_manager->system_pointer, device_manager->core_pointer);
  _gdk_device_add_slave (device_manager->core_pointer, device_manager->system_pointer);

  device_manager->core_keyboard =
    create_keyboard (GDK_DEVICE_MANAGER (device_manager),
		     GDK_TYPE_DEVICE_VIRTUAL,
		     "Virtual Core Keyboard",
		     GDK_DEVICE_TYPE_MASTER);
  device_manager->system_keyboard =
    create_keyboard (GDK_DEVICE_MANAGER (device_manager),
		    GDK_TYPE_DEVICE_WIN32,
		     "System Aggregated Keyboard",
		     GDK_DEVICE_TYPE_SLAVE);
  _gdk_device_virtual_set_active (device_manager->core_keyboard,
				  device_manager->system_keyboard);
  _gdk_device_set_associated_device (device_manager->system_keyboard, device_manager->core_keyboard);
  _gdk_device_add_slave (device_manager->core_keyboard, device_manager->system_keyboard);

  _gdk_device_set_associated_device (device_manager->core_pointer, device_manager->core_keyboard);
  _gdk_device_set_associated_device (device_manager->core_keyboard, device_manager->core_pointer);

  seat = gdk_seat_default_new_for_master_pair (device_manager->core_pointer,
                                               device_manager->core_keyboard);
  gdk_display_add_seat (gdk_device_manager_get_display (GDK_DEVICE_MANAGER (object)), seat);
  gdk_seat_default_add_slave (GDK_SEAT_DEFAULT (seat), device_manager->system_pointer);
  gdk_seat_default_add_slave (GDK_SEAT_DEFAULT (seat), device_manager->system_keyboard);
  g_object_unref (seat);

  wintab_init_check (device_manager);
}
示例#5
0
static GdkWindow *
get_event_window (GdkEventTranslator *translator,
                  XEvent             *xevent)
{
  GdkDeviceManager *device_manager;
  GdkDisplay *display;
  GdkWindow *window;

  device_manager = GDK_DEVICE_MANAGER (translator);
  display = gdk_device_manager_get_display (device_manager);
  window = gdk_x11_window_lookup_for_display (display, xevent->xany.window);

  /* Apply keyboard grabs to non-native windows */
  if (xevent->type == KeyPress || xevent->type == KeyRelease)
    {
      GdkDeviceGrabInfo *info;
      gulong serial;

      serial = _gdk_display_get_next_serial (display);
      info = _gdk_display_has_device_grab (display,
                                           GDK_X11_DEVICE_MANAGER_CORE (device_manager)->core_keyboard,
                                           serial);
      if (info &&
          (!is_parent_of (info->window, window) ||
           !info->owner_events))
        {
          /* Report key event against grab window */
          window = info->window;
        }
    }

  return window;
}
示例#6
0
static void
gdk_quartz_device_manager_core_constructed (GObject *object)
{
  GdkQuartzDeviceManagerCore *device_manager;
  GdkDisplay *display;
  GdkSeat *seat;

  device_manager = GDK_QUARTZ_DEVICE_MANAGER_CORE (object);
  display = gdk_device_manager_get_display (GDK_DEVICE_MANAGER (object));
  device_manager->core_pointer = create_core_pointer (GDK_DEVICE_MANAGER (device_manager), display);
  device_manager->core_keyboard = create_core_keyboard (GDK_DEVICE_MANAGER (device_manager), display);

  _gdk_device_set_associated_device (device_manager->core_pointer, device_manager->core_keyboard);
  _gdk_device_set_associated_device (device_manager->core_keyboard, device_manager->core_pointer);

  seat = gdk_seat_default_new_for_master_pair (device_manager->core_pointer,
                                               device_manager->core_keyboard);
  gdk_display_add_seat (display, seat);
  g_object_unref (seat);
}
示例#7
0
static void
gdk_device_manager_win32_constructed (GObject *object)
{
  GdkDeviceManagerWin32 *device_manager;

  device_manager = GDK_DEVICE_MANAGER_WIN32 (object);
  device_manager->core_pointer =
    create_pointer (GDK_DEVICE_MANAGER (device_manager),
		    GDK_TYPE_DEVICE_VIRTUAL,
		    "Virtual Core Pointer",
		    GDK_DEVICE_TYPE_MASTER);
  device_manager->system_pointer =
    create_pointer (GDK_DEVICE_MANAGER (device_manager),
		    GDK_TYPE_DEVICE_WIN32,
		    "System Aggregated Pointer",
		    GDK_DEVICE_TYPE_SLAVE);
  _gdk_device_virtual_set_active (device_manager->core_pointer,
				  device_manager->system_pointer);
  _gdk_device_set_associated_device (device_manager->system_pointer, device_manager->core_pointer);
  _gdk_device_add_slave (device_manager->core_pointer, device_manager->system_pointer);

  device_manager->core_keyboard =
    create_keyboard (GDK_DEVICE_MANAGER (device_manager),
		     GDK_TYPE_DEVICE_VIRTUAL,
		     "Virtual Core Keyboard",
		     GDK_DEVICE_TYPE_MASTER);
  device_manager->system_keyboard =
    create_keyboard (GDK_DEVICE_MANAGER (device_manager),
		    GDK_TYPE_DEVICE_WIN32,
		     "System Aggregated Keyboard",
		     GDK_DEVICE_TYPE_SLAVE);
  _gdk_device_virtual_set_active (device_manager->core_keyboard,
				  device_manager->system_keyboard);
  _gdk_device_set_associated_device (device_manager->system_keyboard, device_manager->core_keyboard);
  _gdk_device_add_slave (device_manager->core_keyboard, device_manager->system_keyboard);

  _gdk_device_set_associated_device (device_manager->core_pointer, device_manager->core_keyboard);
  _gdk_device_set_associated_device (device_manager->core_keyboard, device_manager->core_pointer);
}
static void
gdk_device_manager_set_property (GObject      *object,
                                 guint         prop_id,
                                 const GValue *value,
                                 GParamSpec   *pspec)
{
  switch (prop_id)
    {
    case PROP_DISPLAY:
      GDK_DEVICE_MANAGER (object)->display = g_value_get_object (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
    }
}
示例#9
0
GdkDeviceManager *
_gdk_x11_device_manager_new (GdkDisplay *display)
{
  if (!g_getenv ("GDK_CORE_DEVICE_EVENTS"))
    {
#ifdef XINPUT_2
      int opcode, firstevent, firsterror;
      Display *xdisplay;

      xdisplay = GDK_DISPLAY_XDISPLAY (display);

      if (XQueryExtension (xdisplay, "XInputExtension",
                           &opcode, &firstevent, &firsterror))
        {
          int major, minor;

          major = 2;
	  minor = 3;

          if (!_gdk_disable_multidevice &&
              XIQueryVersion (xdisplay, &major, &minor) != BadRequest)
            {
              GdkX11DeviceManagerXI2 *device_manager_xi2;

              GDK_NOTE (INPUT, g_message ("Creating XI2 device manager"));

              device_manager_xi2 = g_object_new (GDK_TYPE_X11_DEVICE_MANAGER_XI2,
                                                 "display", display,
                                                 "opcode", opcode,
                                                 "major", major,
                                                 "minor", minor,
                                                 NULL);

              return GDK_DEVICE_MANAGER (device_manager_xi2);
            }
        }
#endif /* XINPUT_2 */
    }

  GDK_NOTE (INPUT, g_message ("Creating core device manager"));

  return g_object_new (GDK_TYPE_X11_DEVICE_MANAGER_CORE,
                       "display", display,
                       NULL);
}
示例#10
0
文件: gdkinput.c 项目: Pfiver/gtk
void
_gdk_input_init (GdkDisplay *display)
{
  GdkDeviceManagerWin32 *device_manager;

  _gdk_input_ignore_core = FALSE;

  device_manager = g_object_new (GDK_TYPE_DEVICE_MANAGER_WIN32,
                                 "display", display,
                                 NULL);
  display->device_manager = GDK_DEVICE_MANAGER (device_manager);

  display->core_pointer = device_manager->core_pointer;

  _gdk_input_devices = g_list_append (NULL, display->core_pointer);
  _gdk_input_devices = g_list_concat (_gdk_input_devices,
                                      g_list_copy (device_manager->wintab_devices));

  _gdk_input_wintab_init_check (device_manager);

}
示例#11
0
static void
wintab_init_check (GdkDeviceManagerWin32 *device_manager)
{
  GdkDisplay *display = gdk_device_manager_get_display (GDK_DEVICE_MANAGER (device_manager));
  GdkWindow *root = gdk_screen_get_root_window (gdk_display_get_default_screen (display));
  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];
  UINT devix, cursorix;
  int i, 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_WTGetA = (t_WTGetA) GetProcAddress (wintab32, "WTGetA")) == NULL)
    return;
  if ((p_WTSetA = (t_WTSetA) GetProcAddress (wintab32, "WTSetA")) == 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 (root, &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 %u: %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 | CXO_CSRMESSAGES;
      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 + 1;
      lc.lcOutExtY = axis_y.axMax - axis_y.axMin + 1;
      lc.lcOutExtY = -lc.lcOutExtY; /* We want Y growing downward */
#if DEBUG_WINTAB
      GDK_NOTE (INPUT, (g_print("context for device %u:\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 %u %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 %u 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 = 128; 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 %u:\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_FLOATING,
                                 "input-source", GDK_SOURCE_PEN,
                                 "input-mode", GDK_MODE_SCREEN,
                                 "has-cursor", lc.lcOptions & CXO_SYSTEM,
                                 "display", display,
                                 "device-manager", device_manager,
                                 NULL);

	  device->sends_core = lc.lcOptions & CXO_SYSTEM;
	  if (device->sends_core)
	    {
	      _gdk_device_set_associated_device (device_manager->system_pointer, GDK_DEVICE (device));
	      _gdk_device_add_slave (device_manager->core_pointer, GDK_DEVICE (device));
	    }

          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: (%u) %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);
    }
}