Merge pull request #62723 from hansemro/eraser-detect-3.x

This commit is contained in:
Rémi Verschelde 2022-07-15 00:13:15 +02:00 committed by GitHub
commit 101cbe5d5b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 71 additions and 8 deletions

View file

@ -597,6 +597,14 @@ float InputEventMouseMotion::get_pressure() const {
return pressure; return pressure;
} }
void InputEventMouseMotion::set_pen_inverted(bool p_inverted) {
pen_inverted = p_inverted;
}
bool InputEventMouseMotion::get_pen_inverted() const {
return pen_inverted;
}
void InputEventMouseMotion::set_relative(const Vector2 &p_relative) { void InputEventMouseMotion::set_relative(const Vector2 &p_relative) {
relative = p_relative; relative = p_relative;
} }
@ -628,6 +636,7 @@ Ref<InputEvent> InputEventMouseMotion::xformed_by(const Transform2D &p_xform, co
mm->set_position(l); mm->set_position(l);
mm->set_pressure(get_pressure()); mm->set_pressure(get_pressure());
mm->set_pen_inverted(get_pen_inverted());
mm->set_tilt(get_tilt()); mm->set_tilt(get_tilt());
mm->set_global_position(g); mm->set_global_position(g);
@ -660,7 +669,7 @@ String InputEventMouseMotion::as_text() const {
button_mask_string = itos(get_button_mask()); button_mask_string = itos(get_button_mask());
break; break;
} }
return "InputEventMouseMotion : button_mask=" + button_mask_string + ", position=(" + String(get_position()) + "), relative=(" + String(get_relative()) + "), speed=(" + String(get_speed()) + "), pressure=(" + rtos(get_pressure()) + "), tilt=(" + String(get_tilt()) + ")"; return "InputEventMouseMotion : button_mask=" + button_mask_string + ", position=(" + String(get_position()) + "), relative=(" + String(get_relative()) + "), speed=(" + String(get_speed()) + "), pressure=(" + rtos(get_pressure()) + "), tilt=(" + String(get_tilt()) + "), pen_inverted=(" + rtos(get_pen_inverted()) + ")";
} }
bool InputEventMouseMotion::accumulate(const Ref<InputEvent> &p_event) { bool InputEventMouseMotion::accumulate(const Ref<InputEvent> &p_event) {
@ -708,6 +717,9 @@ void InputEventMouseMotion::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_pressure", "pressure"), &InputEventMouseMotion::set_pressure); ClassDB::bind_method(D_METHOD("set_pressure", "pressure"), &InputEventMouseMotion::set_pressure);
ClassDB::bind_method(D_METHOD("get_pressure"), &InputEventMouseMotion::get_pressure); ClassDB::bind_method(D_METHOD("get_pressure"), &InputEventMouseMotion::get_pressure);
ClassDB::bind_method(D_METHOD("set_pen_inverted", "pen_inverted"), &InputEventMouseMotion::set_pen_inverted);
ClassDB::bind_method(D_METHOD("get_pen_inverted"), &InputEventMouseMotion::get_pen_inverted);
ClassDB::bind_method(D_METHOD("set_relative", "relative"), &InputEventMouseMotion::set_relative); ClassDB::bind_method(D_METHOD("set_relative", "relative"), &InputEventMouseMotion::set_relative);
ClassDB::bind_method(D_METHOD("get_relative"), &InputEventMouseMotion::get_relative); ClassDB::bind_method(D_METHOD("get_relative"), &InputEventMouseMotion::get_relative);
@ -716,12 +728,14 @@ void InputEventMouseMotion::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "tilt"), "set_tilt", "get_tilt"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "tilt"), "set_tilt", "get_tilt");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "pressure"), "set_pressure", "get_pressure"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "pressure"), "set_pressure", "get_pressure");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "pen_inverted"), "set_pen_inverted", "get_pen_inverted");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "relative"), "set_relative", "get_relative"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "relative"), "set_relative", "get_relative");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "speed"), "set_speed", "get_speed"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "speed"), "set_speed", "get_speed");
} }
InputEventMouseMotion::InputEventMouseMotion() { InputEventMouseMotion::InputEventMouseMotion() {
pressure = 0; pressure = 0;
pen_inverted = false;
} }
//////////////////////////////////////// ////////////////////////////////////////

View file

@ -387,6 +387,7 @@ class InputEventMouseMotion : public InputEventMouse {
float pressure; float pressure;
Vector2 relative; Vector2 relative;
Vector2 speed; Vector2 speed;
bool pen_inverted;
protected: protected:
static void _bind_methods(); static void _bind_methods();
@ -398,6 +399,9 @@ public:
void set_pressure(float p_pressure); void set_pressure(float p_pressure);
float get_pressure() const; float get_pressure() const;
void set_pen_inverted(bool p_inverted);
bool get_pen_inverted() const;
void set_relative(const Vector2 &p_relative); void set_relative(const Vector2 &p_relative);
Vector2 get_relative() const; Vector2 get_relative() const;

View file

@ -15,6 +15,10 @@
<methods> <methods>
</methods> </methods>
<members> <members>
<member name="pen_inverted" type="bool" setter="set_pen_inverted" getter="get_pen_inverted" default="false">
Returns [code]true[/code] when using the eraser end of a stylus pen.
[b]Note:[/b] This property is implemented on Linux, macOS and Windows.
</member>
<member name="pressure" type="float" setter="set_pressure" getter="get_pressure" default="0.0"> <member name="pressure" type="float" setter="set_pressure" getter="get_pressure" default="0.0">
Represents the pressure the user puts on the pen. Ranges from [code]0.0[/code] to [code]1.0[/code]. Represents the pressure the user puts on the pen. Ranges from [code]0.0[/code] to [code]1.0[/code].
</member> </member>

View file

@ -74,6 +74,8 @@ public:
NSTimeInterval last_warp = 0; NSTimeInterval last_warp = 0;
bool ignore_warp = false; bool ignore_warp = false;
bool last_pen_inverted = false;
Vector<KeyEvent> key_event_buffer; Vector<KeyEvent> key_event_buffer;
int key_event_pos; int key_event_pos;

View file

@ -809,9 +809,15 @@ static void _mouseDownEvent(NSEvent *event, int index, int mask, bool pressed) {
const Vector2 pos = get_mouse_pos(mpos); const Vector2 pos = get_mouse_pos(mpos);
mm->set_position(pos); mm->set_position(pos);
mm->set_pressure([event pressure]); mm->set_pressure([event pressure]);
if ([event subtype] == NSEventSubtypeTabletPoint) { NSEventSubtype subtype = [event subtype];
if (subtype == NSEventSubtypeTabletPoint) {
const NSPoint p = [event tilt]; const NSPoint p = [event tilt];
mm->set_tilt(Vector2(p.x, p.y)); mm->set_tilt(Vector2(p.x, p.y));
mm->set_pen_inverted(OS_OSX::singleton->last_pen_inverted);
} else if (subtype == NSEventSubtypeTabletProximity) {
// Check if using the eraser end of pen only on proximity event.
OS_OSX::singleton->last_pen_inverted = [event pointingDeviceType] == NSPointingDeviceTypeEraser;
mm->set_pen_inverted(OS_OSX::singleton->last_pen_inverted);
} }
mm->set_global_position(pos); mm->set_global_position(pos);
mm->set_speed(OS_OSX::singleton->input->get_last_mouse_speed()); mm->set_speed(OS_OSX::singleton->input->get_last_mouse_speed());

View file

@ -490,6 +490,8 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
last_tilt = Vector2(); last_tilt = Vector2();
} }
last_pen_inverted = packet.pkStatus & TPS_INVERT;
POINT coords; POINT coords;
GetCursorPos(&coords); GetCursorPos(&coords);
ScreenToClient(hWnd, &coords); ScreenToClient(hWnd, &coords);
@ -504,6 +506,7 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
mm->set_shift(GetKeyState(VK_SHIFT) < 0); mm->set_shift(GetKeyState(VK_SHIFT) < 0);
mm->set_alt(alt_mem); mm->set_alt(alt_mem);
mm->set_pen_inverted(last_pen_inverted);
mm->set_pressure(last_pressure); mm->set_pressure(last_pressure);
mm->set_tilt(last_tilt); mm->set_tilt(last_tilt);
@ -631,6 +634,8 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
Ref<InputEventMouseMotion> mm; Ref<InputEventMouseMotion> mm;
mm.instance(); mm.instance();
mm->set_pen_inverted(pen_info.penFlags & (PEN_FLAG_INVERTED | PEN_FLAG_ERASER));
if (pen_info.penMask & PEN_MASK_PRESSURE) { if (pen_info.penMask & PEN_MASK_PRESSURE) {
mm->set_pressure((float)pen_info.pressure / 1024); mm->set_pressure((float)pen_info.pressure / 1024);
} else { } else {
@ -742,14 +747,17 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
} else { } else {
last_tilt = Vector2(); last_tilt = Vector2();
last_pressure = (wParam & MK_LBUTTON) ? 1.0f : 0.0f; last_pressure = (wParam & MK_LBUTTON) ? 1.0f : 0.0f;
last_pen_inverted = false;
} }
} else { } else {
last_tilt = Vector2(); last_tilt = Vector2();
last_pressure = (wParam & MK_LBUTTON) ? 1.0f : 0.0f; last_pressure = (wParam & MK_LBUTTON) ? 1.0f : 0.0f;
last_pen_inverted = false;
} }
mm->set_pressure(last_pressure); mm->set_pressure(last_pressure);
mm->set_tilt(last_tilt); mm->set_tilt(last_tilt);
mm->set_pen_inverted(last_pen_inverted);
mm->set_button_mask(last_button_state); mm->set_button_mask(last_button_state);
@ -1478,8 +1486,8 @@ Error OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int
if ((get_current_tablet_driver() == "wintab") && wintab_available) { if ((get_current_tablet_driver() == "wintab") && wintab_available) {
wintab_WTInfo(WTI_DEFSYSCTX, 0, &wtlc); wintab_WTInfo(WTI_DEFSYSCTX, 0, &wtlc);
wtlc.lcOptions |= CXO_MESSAGES; wtlc.lcOptions |= CXO_MESSAGES;
wtlc.lcPktData = PK_NORMAL_PRESSURE | PK_TANGENT_PRESSURE | PK_ORIENTATION; wtlc.lcPktData = PK_STATUS | PK_NORMAL_PRESSURE | PK_TANGENT_PRESSURE | PK_ORIENTATION;
wtlc.lcMoveMask = PK_NORMAL_PRESSURE | PK_TANGENT_PRESSURE; wtlc.lcMoveMask = PK_STATUS | PK_NORMAL_PRESSURE | PK_TANGENT_PRESSURE;
wtlc.lcPktMode = 0; wtlc.lcPktMode = 0;
wtlc.lcOutOrgX = 0; wtlc.lcOutOrgX = 0;
wtlc.lcOutExtX = wtlc.lcInExtX; wtlc.lcOutExtX = wtlc.lcInExtX;
@ -1507,6 +1515,7 @@ Error OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int
last_pressure = 0; last_pressure = 0;
last_pressure_update = 0; last_pressure_update = 0;
last_tilt = Vector2(); last_tilt = Vector2();
last_pen_inverted = false;
#if defined(OPENGL_ENABLED) #if defined(OPENGL_ENABLED)
@ -3823,8 +3832,8 @@ void OS_Windows::set_current_tablet_driver(const String &p_driver) {
if ((p_driver == "wintab") && wintab_available) { if ((p_driver == "wintab") && wintab_available) {
wintab_WTInfo(WTI_DEFSYSCTX, 0, &wtlc); wintab_WTInfo(WTI_DEFSYSCTX, 0, &wtlc);
wtlc.lcOptions |= CXO_MESSAGES; wtlc.lcOptions |= CXO_MESSAGES;
wtlc.lcPktData = PK_NORMAL_PRESSURE | PK_TANGENT_PRESSURE | PK_ORIENTATION; wtlc.lcPktData = PK_STATUS | PK_NORMAL_PRESSURE | PK_TANGENT_PRESSURE | PK_ORIENTATION;
wtlc.lcMoveMask = PK_NORMAL_PRESSURE | PK_TANGENT_PRESSURE; wtlc.lcMoveMask = PK_STATUS | PK_NORMAL_PRESSURE | PK_TANGENT_PRESSURE;
wtlc.lcPktMode = 0; wtlc.lcPktMode = 0;
wtlc.lcOutOrgX = 0; wtlc.lcOutOrgX = 0;
wtlc.lcOutExtX = wtlc.lcInExtX; wtlc.lcOutExtX = wtlc.lcInExtX;

View file

@ -71,10 +71,13 @@
#define DVC_ROTATION 18 #define DVC_ROTATION 18
#define CXO_MESSAGES 0x0004 #define CXO_MESSAGES 0x0004
#define PK_STATUS 0x0002
#define PK_NORMAL_PRESSURE 0x0400 #define PK_NORMAL_PRESSURE 0x0400
#define PK_TANGENT_PRESSURE 0x0800 #define PK_TANGENT_PRESSURE 0x0800
#define PK_ORIENTATION 0x1000 #define PK_ORIENTATION 0x1000
#define TPS_INVERT 0x0010 /* 1.1 */
typedef struct tagLOGCONTEXTW { typedef struct tagLOGCONTEXTW {
WCHAR lcName[40]; WCHAR lcName[40];
UINT lcOptions; UINT lcOptions;
@ -126,6 +129,7 @@ typedef struct tagORIENTATION {
} ORIENTATION; } ORIENTATION;
typedef struct tagPACKET { typedef struct tagPACKET {
int pkStatus;
int pkNormalPressure; int pkNormalPressure;
int pkTangentPressure; int pkTangentPressure;
ORIENTATION pkOrientation; ORIENTATION pkOrientation;
@ -147,6 +151,14 @@ typedef UINT32 POINTER_FLAGS;
typedef UINT32 PEN_FLAGS; typedef UINT32 PEN_FLAGS;
typedef UINT32 PEN_MASK; typedef UINT32 PEN_MASK;
#ifndef PEN_FLAG_INVERTED
#define PEN_FLAG_INVERTED 0x00000002
#endif
#ifndef PEN_FLAG_ERASER
#define PEN_FLAG_ERASER 0x00000004
#endif
#ifndef PEN_MASK_PRESSURE #ifndef PEN_MASK_PRESSURE
#define PEN_MASK_PRESSURE 0x00000001 #define PEN_MASK_PRESSURE 0x00000001
#endif #endif
@ -272,11 +284,13 @@ class OS_Windows : public OS {
int min_pressure; int min_pressure;
int max_pressure; int max_pressure;
bool tilt_supported; bool tilt_supported;
bool pen_inverted = false;
bool block_mm = false; bool block_mm = false;
int last_pressure_update; int last_pressure_update;
float last_pressure; float last_pressure;
Vector2 last_tilt; Vector2 last_tilt;
bool last_pen_inverted = false;
enum { enum {
KEY_EVENT_BUFFER_SIZE = 512 KEY_EVENT_BUFFER_SIZE = 512

View file

@ -660,6 +660,7 @@ bool OS_X11::refresh_device_info() {
xi.absolute_devices.clear(); xi.absolute_devices.clear();
xi.touch_devices.clear(); xi.touch_devices.clear();
xi.pen_inverted_devices.clear();
int dev_count; int dev_count;
XIDeviceInfo *info = XIQueryDevice(x11_display, XIAllDevices, &dev_count); XIDeviceInfo *info = XIQueryDevice(x11_display, XIAllDevices, &dev_count);
@ -669,7 +670,7 @@ bool OS_X11::refresh_device_info() {
if (!dev->enabled) { if (!dev->enabled) {
continue; continue;
} }
if (!(dev->use == XIMasterPointer || dev->use == XIFloatingSlave)) { if (!(dev->use == XISlavePointer || dev->use == XIFloatingSlave)) {
continue; continue;
} }
@ -738,6 +739,7 @@ bool OS_X11::refresh_device_info() {
xi.pen_pressure_range[dev->deviceid] = Vector2(pressure_min, pressure_max); xi.pen_pressure_range[dev->deviceid] = Vector2(pressure_min, pressure_max);
xi.pen_tilt_x_range[dev->deviceid] = Vector2(tilt_x_min, tilt_x_max); xi.pen_tilt_x_range[dev->deviceid] = Vector2(tilt_x_min, tilt_x_max);
xi.pen_tilt_y_range[dev->deviceid] = Vector2(tilt_y_min, tilt_y_max); xi.pen_tilt_y_range[dev->deviceid] = Vector2(tilt_y_min, tilt_y_max);
xi.pen_inverted_devices[dev->deviceid] = (bool)strstr(dev->name, "eraser");
} }
XIFreeDeviceInfo(info); XIFreeDeviceInfo(info);
@ -2556,7 +2558,7 @@ void OS_X11::process_xevents() {
} break; } break;
case XI_RawMotion: { case XI_RawMotion: {
XIRawEvent *raw_event = (XIRawEvent *)event_data; XIRawEvent *raw_event = (XIRawEvent *)event_data;
int device_id = raw_event->deviceid; int device_id = raw_event->sourceid;
// Determine the axis used (called valuators in XInput for some forsaken reason) // Determine the axis used (called valuators in XInput for some forsaken reason)
// Mask is a bitmask indicating which axes are involved. // Mask is a bitmask indicating which axes are involved.
@ -2622,6 +2624,11 @@ void OS_X11::process_xevents() {
values++; values++;
} }
Map<int, bool>::Element *pen_inverted = xi.pen_inverted_devices.find(device_id);
if (pen_inverted) {
xi.pen_inverted = pen_inverted->value();
}
// https://bugs.freedesktop.org/show_bug.cgi?id=71609 // https://bugs.freedesktop.org/show_bug.cgi?id=71609
// http://lists.libsdl.org/pipermail/commits-libsdl.org/2015-June/000282.html // http://lists.libsdl.org/pipermail/commits-libsdl.org/2015-June/000282.html
if (raw_event->time == xi.last_relative_time && rel_x == xi.relative_motion.x && rel_y == xi.relative_motion.y) { if (raw_event->time == xi.last_relative_time && rel_x == xi.relative_motion.x && rel_y == xi.relative_motion.y) {
@ -2966,6 +2973,7 @@ void OS_X11::process_xevents() {
} else { } else {
mm->set_pressure((get_mouse_button_state() & (1 << (BUTTON_LEFT - 1))) ? 1.0f : 0.0f); mm->set_pressure((get_mouse_button_state() & (1 << (BUTTON_LEFT - 1))) ? 1.0f : 0.0f);
} }
mm->set_pen_inverted(xi.pen_inverted);
mm->set_tilt(xi.tilt); mm->set_tilt(xi.tilt);
// Make the absolute position integral so it doesn't look _too_ weird :) // Make the absolute position integral so it doesn't look _too_ weird :)

View file

@ -133,11 +133,13 @@ class OS_X11 : public OS_Unix {
Map<int, Vector2> pen_pressure_range; Map<int, Vector2> pen_pressure_range;
Map<int, Vector2> pen_tilt_x_range; Map<int, Vector2> pen_tilt_x_range;
Map<int, Vector2> pen_tilt_y_range; Map<int, Vector2> pen_tilt_y_range;
Map<int, bool> pen_inverted_devices;
XIEventMask all_event_mask; XIEventMask all_event_mask;
XIEventMask all_master_event_mask; XIEventMask all_master_event_mask;
Map<int, Vector2> state; Map<int, Vector2> state;
double pressure; double pressure;
bool pressure_supported; bool pressure_supported;
bool pen_inverted;
Vector2 tilt; Vector2 tilt;
Vector2 mouse_pos_to_filter; Vector2 mouse_pos_to_filter;
Vector2 relative_motion; Vector2 relative_motion;