WIP: Wacom twist support for GHOST #107729
|
@ -142,6 +142,7 @@ typedef struct GHOST_TabletData {
|
|||
float Pressure; /* range 0.0 (not touching) to 1.0 (full pressure) */
|
||||
float Xtilt; /* range 0.0 (upright) to 1.0 (tilted fully against the tablet surface) */
|
||||
float Ytilt; /* as above */
|
||||
float Twist; /* range (-pi,pi), stylus button side towards left is 0.0. */
|
||||
} GHOST_TabletData;
|
||||
|
||||
static const GHOST_TabletData GHOST_TABLET_DATA_NONE = {
|
||||
|
|
|
@ -59,6 +59,9 @@
|
|||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/* M_PI */
|
||||
#include <math.h>
|
||||
|
||||
#include <cstdio> /* for fprintf only */
|
||||
#include <cstdlib> /* for exit */
|
||||
#include <iostream>
|
||||
|
@ -1558,6 +1561,13 @@ void GHOST_SystemX11::processEvent(XEvent *xe)
|
|||
window->GetTabletData().Ytilt = short(axis_value & 0xffff) /
|
||||
float(xtablet.YtiltLevels);
|
||||
}
|
||||
if (AXIS_VALUE_GET(5, axis_value)) {
|
||||
window->GetTabletData().Twist = short(axis_value & 0xffff) /
|
||||
float(xtablet.TwistLevels) * M_PI;
|
||||
# ifdef WITH_GHOST_DEBUG
|
||||
printf("Twist: %f\n", window->GetTabletData().Twist);
|
||||
# endif
|
||||
}
|
||||
|
||||
# undef AXIS_VALUE_GET
|
||||
}
|
||||
|
@ -2721,6 +2731,12 @@ void GHOST_SystemX11::refreshXInputDevices()
|
|||
xtablet.XtiltLevels = 0;
|
||||
xtablet.YtiltLevels = 0;
|
||||
}
|
||||
if (xvi->num_axes > 5) {
|
||||
xtablet.TwistLevels = xvi->axes[5].max_value;
|
||||
}
|
||||
else {
|
||||
xtablet.TwistLevels = 0;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -271,6 +271,7 @@ class GHOST_SystemX11 : public GHOST_System {
|
|||
|
||||
int PressureLevels;
|
||||
int XtiltLevels, YtiltLevels;
|
||||
int TwistLevels;
|
||||
} GHOST_TabletX11;
|
||||
|
||||
std::vector<GHOST_TabletX11> &GetXTablets()
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
* \ingroup GHOST
|
||||
*/
|
||||
|
||||
#define _USE_MATH_DEFINES
|
||||
|
||||
#include "GHOST_WindowWin32.hh"
|
||||
#include "GHOST_ContextD3D.hh"
|
||||
#include "GHOST_ContextNone.hh"
|
||||
|
@ -953,6 +955,7 @@ GHOST_TSuccess GHOST_WindowWin32::getPointerInfo(
|
|||
outPointerInfo[i].tabletData.Pressure = 1.0f;
|
||||
outPointerInfo[i].tabletData.Xtilt = 0.0f;
|
||||
outPointerInfo[i].tabletData.Ytilt = 0.0f;
|
||||
outPointerInfo[i].tabletData.Twist = 0.0f;
|
||||
outPointerInfo[i].time = system->performanceCounterToMillis(pointerApiInfo.PerformanceCount);
|
||||
|
||||
if (pointerPenInfo[i].penMask & PEN_MASK_PRESSURE) {
|
||||
|
@ -970,6 +973,13 @@ GHOST_TSuccess GHOST_WindowWin32::getPointerInfo(
|
|||
if (pointerPenInfo[i].penMask & PEN_MASK_TILT_Y) {
|
||||
outPointerInfo[i].tabletData.Ytilt = fmin(fabs(pointerPenInfo[i].tiltY / 90.0f), 1.0f);
|
||||
}
|
||||
|
||||
if (pointerPenInfo[i].penMask & PEN_MASK_ROTATION) {
|
||||
/* POINTER_PEN_INFO specifies rotation range to be [0,359], convert to radiant here. */
|
||||
outPointerInfo[i].tabletData.Twist = ((float)pointerPenInfo[i].rotation / 360.0f) * M_PI * 2;
|
||||
/* Debug only. */
|
||||
printf("Twist (ink): %f\n", outPointerInfo[i].tabletData.Twist);
|
||||
}
|
||||
}
|
||||
|
||||
if (!outPointerInfo.empty()) {
|
||||
|
|
|
@ -263,7 +263,7 @@ void GHOST_Wintab::remapCoordinates()
|
|||
|
||||
void GHOST_Wintab::updateCursorInfo()
|
||||
{
|
||||
AXIS Pressure, Orientation[3];
|
||||
AXIS Pressure, Orientation[3], Rotation;
|
||||
|
||||
BOOL pressureSupport = m_fpInfo(WTI_DEVICES, DVC_NPRESSURE, &Pressure);
|
||||
m_maxPressure = pressureSupport ? Pressure.axMax : 0;
|
||||
|
@ -278,11 +278,23 @@ void GHOST_Wintab::updateCursorInfo()
|
|||
else {
|
||||
m_maxAzimuth = m_maxAltitude = 0;
|
||||
}
|
||||
WINTAB_PRINTF("HCTX %p %s maxAzimuth: %d, maxAltitude: %d\n",
|
||||
|
||||
if (Orientation[2].axResolution) {
|
||||
m_maxTwist = Orientation[2].axMax;
|
||||
}
|
||||
else {
|
||||
BOOL rotationSupport = m_fpInfo(WTI_DEVICES, DVC_ROTATION, &Rotation);
|
||||
if (rotationSupport && Rotation.axResolution) {
|
||||
m_maxTwist = Rotation.axMax;
|
||||
}
|
||||
}
|
||||
|
||||
WINTAB_PRINTF("HCTX %p %s maxAzimuth: %d, maxAltitude: %d, maxTwist: %d\n",
|
||||
m_context.get(),
|
||||
__func__,
|
||||
m_maxAzimuth,
|
||||
m_maxAltitude);
|
||||
m_maxAltitude,
|
||||
m_maxTwist);
|
||||
}
|
||||
|
||||
void GHOST_Wintab::processInfoChange(LPARAM lParam)
|
||||
|
@ -362,6 +374,11 @@ void GHOST_Wintab::getInput(std::vector<GHOST_WintabInfoWin32> &outWintabInfo)
|
|||
out.tabletData.Ytilt = float(sin(M_PI_2 - azmRad) * vecLen);
|
||||
}
|
||||
|
||||
if (m_maxTwist > 0) {
|
||||
ORIENTATION ort = pkt.pkOrientation;
|
||||
out.tabletData.Twist = float(float(ort.orTwist) / float(m_maxTwist) * M_PI);
|
||||
}
|
||||
|
||||
out.time = pkt.pkTime;
|
||||
|
||||
/* Some Wintab libraries don't handle relative button input, so we track button presses
|
||||
|
|
|
@ -214,6 +214,7 @@ class GHOST_Wintab {
|
|||
int m_maxPressure = 0;
|
||||
int m_maxAzimuth = 0;
|
||||
int m_maxAltitude = 0;
|
||||
int m_maxTwist = 0;
|
||||
|
||||
/** Number of connected Wintab devices. */
|
||||
UINT m_numDevices = 0;
|
||||
|
|
|
@ -639,6 +639,8 @@ typedef struct wmTabletData {
|
|||
float x_tilt;
|
||||
/** as above. */
|
||||
float y_tilt;
|
||||
/** range (-pi,pi), with stylus button to the left side being 0. */
|
||||
float twist;
|
||||
/** Interpret mouse motion as absolute as typical for tablets. */
|
||||
char is_motion_absolute;
|
||||
} wmTabletData;
|
||||
|
|
|
@ -5138,6 +5138,7 @@ void wm_tablet_data_from_ghost(const GHOST_TabletData *tablet_data, wmTabletData
|
|||
wmtab->pressure = wm_pressure_curve(tablet_data->Pressure);
|
||||
wmtab->x_tilt = tablet_data->Xtilt;
|
||||
wmtab->y_tilt = tablet_data->Ytilt;
|
||||
wmtab->twist = tablet_data->Twist;
|
||||
/* We could have a preference to support relative tablet motion (we can't detect that). */
|
||||
wmtab->is_motion_absolute = true;
|
||||
// printf("%s: using tablet %.5f\n", __func__, wmtab->pressure);
|
||||
|
|
Loading…
Reference in New Issue