How do I read the pressure value from a graphics tablet stylus in Linux?

2.5k views Asked by At

I am trying to add pressure sensitivity support to Synergy on Linux. I believe the first step should be to detect the pressure value on the server side. The stylus movement comes in as a MotionNotify event when XNextEvent is called. However, this line does not output a pressure value when the stylus is used:

   case MotionNotify:
           XDeviceMotionEvent* motionEvent = reinterpret_cast<XDeviceMotionEvent*>(xevent);
           LOG((CLOG_INFO "tablet event: pressure=%d", motionEvent->axis_data[2]));

To solve this, I guessed that I might not be "subscribed" to such info, so following some examples I found on the web, I have attempted to open the Wacom device:

   void
   CXWindowsScreen::openWacom()
   {
           // init tablet (e.g. wacom)
           int deviceCount;
           XDeviceInfo* deviceInfo = XListInputDevices(m_display, &deviceCount);
           for (int i = 0; i < deviceCount; ++i) {

                   if (CString(deviceInfo[i].name).find("stylus") != CString::npos) {

                           LOG((CLOG_INFO "tablet device: name='%s', id=%d",
                                           deviceInfo[i].name, deviceInfo[i].id));

                           XDevice* tabletStylusDevice = XOpenDevice(m_display, deviceInfo[i].id);
                           if (tabletStylusDevice == NULL) {
                                   LOG((CLOG_ERR "failed to open tablet device"));
                                   return;
                           }

                           XEventClass eventClass;
                           DeviceMotionNotify(tabletStylusDevice, m_tabletMotionEvent, eventClass);
                           XSelectExtensionEvent(m_display, m_window, &eventClass, 1);

                           LOG((CLOG_INFO "tablet motion event=%d class=%d",
                                           m_tabletMotionEvent, eventClass));
                   }
           }
           XFreeDeviceList(deviceInfo);
   }

This does indeed detect a Wacom device...

   2012-01-30T11:15:59 INFO: tablet device: name='Wacom Intuos4 6x9 stylus', id=8
           /home/nick/Projects/synergy/1.4/src/lib/platform/CXWindowsScreen.cpp,1144
   2012-01-30T11:15:59 INFO: tablet motion event=105 class=2153
           /home/nick/Projects/synergy/1.4/src/lib/platform/CXWindowsScreen.cpp,1157

But I have so far never received the stylus event 105 (m_tabletMotionEvent) from XNextEvent...

   if (xevent->type == m_tabletMotionEvent) {
           XDeviceMotionEvent* motionEvent = reinterpret_cast<XDeviceMotionEvent*>(xevent);
           LOG((CLOG_INFO "tablet event: pressure=%d", motionEvent->axis_data[2]));
           return;
   }

In other words, the above if never evaluates to true.

I hope someone can help me with this, I've been trying to solve it for weeks.

The next challenge will be to fake the pressure level on the Synergy client so that programs like GIMP will receive it (and I'm not even sure where to start with that).

0

There are 0 answers