2014-06-05 23:20:36 -04:00
|
|
|
/*
|
|
|
|
|
* Copyright © 2014 Red Hat, Inc.
|
2017-11-17 08:40:07 +10:00
|
|
|
* Copyright © 2014 Lyude Paul
|
2014-06-05 23:20:36 -04:00
|
|
|
*
|
2018-08-07 08:26:53 +10:00
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
|
|
|
* copy of this software and associated documentation files (the "Software"),
|
|
|
|
|
* to deal in the Software without restriction, including without limitation
|
|
|
|
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
|
|
|
* and/or sell copies of the Software, and to permit persons to whom the
|
|
|
|
|
* Software is furnished to do so, subject to the following conditions:
|
2014-06-05 23:20:36 -04:00
|
|
|
*
|
2018-08-07 08:26:53 +10:00
|
|
|
* The above copyright notice and this permission notice (including the next
|
|
|
|
|
* paragraph) shall be included in all copies or substantial portions of the
|
|
|
|
|
* Software.
|
|
|
|
|
*
|
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
|
|
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
|
|
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
|
|
|
* DEALINGS IN THE SOFTWARE.
|
2014-06-05 23:20:36 -04:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#ifndef EVDEV_TABLET_H
|
|
|
|
|
#define EVDEV_TABLET_H
|
|
|
|
|
|
|
|
|
|
#include "evdev.h"
|
|
|
|
|
|
2015-11-16 15:36:30 +10:00
|
|
|
#define LIBINPUT_TABLET_TOOL_AXIS_NONE 0
|
2015-02-19 10:59:46 +10:00
|
|
|
#define LIBINPUT_TOOL_NONE 0
|
2015-11-16 15:40:43 +10:00
|
|
|
#define LIBINPUT_TABLET_TOOL_TYPE_MAX LIBINPUT_TABLET_TOOL_TYPE_LENS
|
2015-02-10 11:29:34 +10:00
|
|
|
|
2017-03-07 13:11:51 +10:00
|
|
|
#define TABLET_HISTORY_LENGTH 4
|
|
|
|
|
|
2014-06-05 23:20:36 -04:00
|
|
|
enum tablet_status {
|
2019-02-06 15:29:23 +10:00
|
|
|
TABLET_NONE = 0,
|
|
|
|
|
TABLET_AXES_UPDATED = bit(0),
|
|
|
|
|
TABLET_BUTTONS_PRESSED = bit(1),
|
|
|
|
|
TABLET_BUTTONS_RELEASED = bit(2),
|
2019-06-17 11:18:57 +10:00
|
|
|
TABLET_TOOL_UPDATED = bit(3),
|
|
|
|
|
TABLET_TOOL_IN_CONTACT = bit(4),
|
|
|
|
|
TABLET_TOOL_LEAVING_PROXIMITY = bit(5),
|
|
|
|
|
TABLET_TOOL_OUT_OF_PROXIMITY = bit(6),
|
|
|
|
|
TABLET_TOOL_ENTERING_PROXIMITY = bit(7),
|
|
|
|
|
TABLET_TOOL_ENTERING_CONTACT = bit(8),
|
|
|
|
|
TABLET_TOOL_LEAVING_CONTACT = bit(9),
|
|
|
|
|
TABLET_TOOL_OUT_OF_RANGE = bit(10),
|
2014-06-10 23:14:41 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct button_state {
|
2016-02-10 09:24:51 +10:00
|
|
|
unsigned char bits[NCHARS(KEY_CNT)];
|
2014-06-05 23:20:36 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct tablet_dispatch {
|
|
|
|
|
struct evdev_dispatch base;
|
|
|
|
|
struct evdev_device *device;
|
2015-11-11 14:03:05 +10:00
|
|
|
unsigned int status;
|
2015-11-16 15:36:30 +10:00
|
|
|
unsigned char changed_axes[NCHARS(LIBINPUT_TABLET_TOOL_AXIS_MAX + 1)];
|
2017-03-07 16:00:45 +10:00
|
|
|
struct tablet_axes axes; /* for assembling the current state */
|
|
|
|
|
struct device_coords last_smooth_point;
|
2017-03-07 13:11:51 +10:00
|
|
|
struct {
|
|
|
|
|
unsigned int index;
|
|
|
|
|
unsigned int count;
|
|
|
|
|
struct tablet_axes samples[TABLET_HISTORY_LENGTH];
|
|
|
|
|
} history;
|
|
|
|
|
|
2015-11-16 15:36:30 +10:00
|
|
|
unsigned char axis_caps[NCHARS(LIBINPUT_TABLET_TOOL_AXIS_MAX + 1)];
|
2016-04-12 08:36:48 +10:00
|
|
|
int current_value[LIBINPUT_TABLET_TOOL_AXIS_MAX + 1];
|
|
|
|
|
int prev_value[LIBINPUT_TABLET_TOOL_AXIS_MAX + 1];
|
2014-06-10 16:48:19 -04:00
|
|
|
|
2014-08-07 19:00:52 -04:00
|
|
|
/* Only used for tablets that don't report serial numbers */
|
|
|
|
|
struct list tool_list;
|
|
|
|
|
|
2014-06-10 23:14:41 -04:00
|
|
|
struct button_state button_state;
|
|
|
|
|
struct button_state prev_button_state;
|
|
|
|
|
|
2019-04-05 14:58:56 +10:00
|
|
|
uint32_t tool_state;
|
|
|
|
|
uint32_t prev_tool_state;
|
|
|
|
|
|
2019-04-01 15:10:55 +10:00
|
|
|
struct {
|
|
|
|
|
enum libinput_tablet_tool_type type;
|
|
|
|
|
uint32_t id;
|
|
|
|
|
uint32_t serial;
|
|
|
|
|
} current_tool;
|
2015-12-02 17:16:18 +10:00
|
|
|
|
|
|
|
|
uint32_t cursor_proximity_threshold;
|
2016-07-04 14:34:56 +10:00
|
|
|
|
|
|
|
|
struct libinput_device_config_calibration calibration;
|
2016-06-28 11:28:34 +10:00
|
|
|
|
|
|
|
|
/* The paired touch device on devices with both pen & touch */
|
|
|
|
|
struct evdev_device *touch_device;
|
2018-09-28 11:47:32 +10:00
|
|
|
enum evdev_arbitration_state arbitration;
|
2016-12-22 12:11:43 +10:00
|
|
|
|
2019-05-03 15:56:54 +10:00
|
|
|
struct {
|
|
|
|
|
/* The device locked for rotation */
|
|
|
|
|
struct evdev_device *touch_device;
|
|
|
|
|
/* Last known left-handed state of the touchpad */
|
|
|
|
|
bool touch_device_left_handed_state;
|
|
|
|
|
bool rotate;
|
|
|
|
|
bool want_rotate;
|
|
|
|
|
} rotation;
|
|
|
|
|
|
2016-12-22 12:11:43 +10:00
|
|
|
struct {
|
|
|
|
|
struct libinput_timer prox_out_timer;
|
|
|
|
|
bool proximity_out_forced;
|
|
|
|
|
uint64_t last_event_time;
|
|
|
|
|
} quirks;
|
2014-06-05 23:20:36 -04:00
|
|
|
};
|
|
|
|
|
|
2017-01-30 18:01:09 +10:00
|
|
|
static inline struct tablet_dispatch*
|
|
|
|
|
tablet_dispatch(struct evdev_dispatch *dispatch)
|
|
|
|
|
{
|
|
|
|
|
evdev_verify_dispatch_type(dispatch, DISPATCH_TABLET);
|
|
|
|
|
|
2017-05-15 13:08:17 +02:00
|
|
|
return container_of(dispatch, struct tablet_dispatch, base);
|
2017-01-30 18:01:09 +10:00
|
|
|
}
|
|
|
|
|
|
2015-11-16 15:35:40 +10:00
|
|
|
static inline enum libinput_tablet_tool_axis
|
2014-06-05 23:20:36 -04:00
|
|
|
evcode_to_axis(const uint32_t evcode)
|
|
|
|
|
{
|
2015-11-16 15:35:40 +10:00
|
|
|
enum libinput_tablet_tool_axis axis;
|
2014-06-05 23:20:36 -04:00
|
|
|
|
|
|
|
|
switch (evcode) {
|
|
|
|
|
case ABS_X:
|
2015-11-16 15:36:30 +10:00
|
|
|
axis = LIBINPUT_TABLET_TOOL_AXIS_X;
|
2014-06-05 23:20:36 -04:00
|
|
|
break;
|
|
|
|
|
case ABS_Y:
|
2015-11-16 15:36:30 +10:00
|
|
|
axis = LIBINPUT_TABLET_TOOL_AXIS_Y;
|
2014-06-05 23:20:36 -04:00
|
|
|
break;
|
2015-02-18 11:40:55 +10:00
|
|
|
case ABS_Z:
|
2015-11-16 15:36:30 +10:00
|
|
|
axis = LIBINPUT_TABLET_TOOL_AXIS_ROTATION_Z;
|
2015-02-18 11:40:55 +10:00
|
|
|
break;
|
2014-06-06 20:31:38 -04:00
|
|
|
case ABS_DISTANCE:
|
2015-11-16 15:36:30 +10:00
|
|
|
axis = LIBINPUT_TABLET_TOOL_AXIS_DISTANCE;
|
2014-06-06 20:31:38 -04:00
|
|
|
break;
|
|
|
|
|
case ABS_PRESSURE:
|
2015-11-16 15:36:30 +10:00
|
|
|
axis = LIBINPUT_TABLET_TOOL_AXIS_PRESSURE;
|
2014-06-06 20:31:38 -04:00
|
|
|
break;
|
|
|
|
|
case ABS_TILT_X:
|
2015-11-16 15:36:30 +10:00
|
|
|
axis = LIBINPUT_TABLET_TOOL_AXIS_TILT_X;
|
2014-06-06 20:31:38 -04:00
|
|
|
break;
|
|
|
|
|
case ABS_TILT_Y:
|
2015-11-16 15:36:30 +10:00
|
|
|
axis = LIBINPUT_TABLET_TOOL_AXIS_TILT_Y;
|
2014-06-06 20:31:38 -04:00
|
|
|
break;
|
2015-02-17 13:04:06 +10:00
|
|
|
case ABS_WHEEL:
|
2015-11-16 15:36:30 +10:00
|
|
|
axis = LIBINPUT_TABLET_TOOL_AXIS_SLIDER;
|
2015-02-17 13:04:06 +10:00
|
|
|
break;
|
2014-06-05 23:20:36 -04:00
|
|
|
default:
|
2015-11-16 15:36:30 +10:00
|
|
|
axis = LIBINPUT_TABLET_TOOL_AXIS_NONE;
|
2014-06-05 23:20:36 -04:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return axis;
|
|
|
|
|
}
|
|
|
|
|
|
2015-11-16 15:35:40 +10:00
|
|
|
static inline enum libinput_tablet_tool_axis
|
2015-02-20 11:41:06 +10:00
|
|
|
rel_evcode_to_axis(const uint32_t evcode)
|
|
|
|
|
{
|
2015-11-16 15:35:40 +10:00
|
|
|
enum libinput_tablet_tool_axis axis;
|
2015-02-20 11:41:06 +10:00
|
|
|
|
|
|
|
|
switch (evcode) {
|
|
|
|
|
case REL_WHEEL:
|
2015-11-16 15:36:30 +10:00
|
|
|
axis = LIBINPUT_TABLET_TOOL_AXIS_REL_WHEEL;
|
2015-02-20 11:41:06 +10:00
|
|
|
break;
|
|
|
|
|
default:
|
2015-11-16 15:36:30 +10:00
|
|
|
axis = LIBINPUT_TABLET_TOOL_AXIS_NONE;
|
2015-02-20 11:41:06 +10:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return axis;
|
|
|
|
|
}
|
|
|
|
|
|
2014-06-05 23:20:36 -04:00
|
|
|
static inline uint32_t
|
2015-11-16 15:35:40 +10:00
|
|
|
axis_to_evcode(const enum libinput_tablet_tool_axis axis)
|
2014-06-05 23:20:36 -04:00
|
|
|
{
|
|
|
|
|
uint32_t evcode;
|
|
|
|
|
|
|
|
|
|
switch (axis) {
|
2015-11-16 15:36:30 +10:00
|
|
|
case LIBINPUT_TABLET_TOOL_AXIS_X:
|
2014-06-05 23:20:36 -04:00
|
|
|
evcode = ABS_X;
|
|
|
|
|
break;
|
2015-11-16 15:36:30 +10:00
|
|
|
case LIBINPUT_TABLET_TOOL_AXIS_Y:
|
2014-06-05 23:20:36 -04:00
|
|
|
evcode = ABS_Y;
|
|
|
|
|
break;
|
2015-11-16 15:36:30 +10:00
|
|
|
case LIBINPUT_TABLET_TOOL_AXIS_DISTANCE:
|
2014-06-06 20:31:38 -04:00
|
|
|
evcode = ABS_DISTANCE;
|
|
|
|
|
break;
|
2015-11-16 15:36:30 +10:00
|
|
|
case LIBINPUT_TABLET_TOOL_AXIS_PRESSURE:
|
2014-06-06 20:31:38 -04:00
|
|
|
evcode = ABS_PRESSURE;
|
|
|
|
|
break;
|
2015-11-16 15:36:30 +10:00
|
|
|
case LIBINPUT_TABLET_TOOL_AXIS_TILT_X:
|
2014-06-06 20:31:38 -04:00
|
|
|
evcode = ABS_TILT_X;
|
|
|
|
|
break;
|
2015-11-16 15:36:30 +10:00
|
|
|
case LIBINPUT_TABLET_TOOL_AXIS_TILT_Y:
|
2014-06-06 20:31:38 -04:00
|
|
|
evcode = ABS_TILT_Y;
|
|
|
|
|
break;
|
2015-11-16 15:36:30 +10:00
|
|
|
case LIBINPUT_TABLET_TOOL_AXIS_ROTATION_Z:
|
2015-02-18 11:40:55 +10:00
|
|
|
evcode = ABS_Z;
|
|
|
|
|
break;
|
2015-11-16 15:36:30 +10:00
|
|
|
case LIBINPUT_TABLET_TOOL_AXIS_SLIDER:
|
2015-02-17 13:04:06 +10:00
|
|
|
evcode = ABS_WHEEL;
|
|
|
|
|
break;
|
2018-09-13 13:26:22 +10:00
|
|
|
case LIBINPUT_TABLET_TOOL_AXIS_SIZE_MAJOR:
|
|
|
|
|
evcode = ABS_MT_TOUCH_MAJOR;
|
|
|
|
|
break;
|
|
|
|
|
case LIBINPUT_TABLET_TOOL_AXIS_SIZE_MINOR:
|
|
|
|
|
evcode = ABS_MT_TOUCH_MINOR;
|
|
|
|
|
break;
|
2014-06-05 23:20:36 -04:00
|
|
|
default:
|
|
|
|
|
abort();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return evcode;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-26 13:55:08 +10:00
|
|
|
static inline int
|
2015-11-16 15:39:07 +10:00
|
|
|
tablet_tool_to_evcode(enum libinput_tablet_tool_type type)
|
2015-02-26 13:55:08 +10:00
|
|
|
{
|
|
|
|
|
int code;
|
|
|
|
|
|
|
|
|
|
switch (type) {
|
2015-11-16 15:40:43 +10:00
|
|
|
case LIBINPUT_TABLET_TOOL_TYPE_PEN: code = BTN_TOOL_PEN; break;
|
|
|
|
|
case LIBINPUT_TABLET_TOOL_TYPE_ERASER: code = BTN_TOOL_RUBBER; break;
|
|
|
|
|
case LIBINPUT_TABLET_TOOL_TYPE_BRUSH: code = BTN_TOOL_BRUSH; break;
|
|
|
|
|
case LIBINPUT_TABLET_TOOL_TYPE_PENCIL: code = BTN_TOOL_PENCIL; break;
|
2015-11-26 06:37:56 +10:00
|
|
|
case LIBINPUT_TABLET_TOOL_TYPE_AIRBRUSH: code = BTN_TOOL_AIRBRUSH; break;
|
2015-11-16 15:40:43 +10:00
|
|
|
case LIBINPUT_TABLET_TOOL_TYPE_MOUSE: code = BTN_TOOL_MOUSE; break;
|
|
|
|
|
case LIBINPUT_TABLET_TOOL_TYPE_LENS: code = BTN_TOOL_LENS; break;
|
2015-02-26 13:55:08 +10:00
|
|
|
default:
|
|
|
|
|
abort();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return code;
|
|
|
|
|
}
|
2015-12-01 11:07:57 +10:00
|
|
|
|
|
|
|
|
static inline const char *
|
|
|
|
|
tablet_tool_type_to_string(enum libinput_tablet_tool_type type)
|
|
|
|
|
{
|
|
|
|
|
const char *str;
|
|
|
|
|
|
|
|
|
|
switch (type) {
|
|
|
|
|
case LIBINPUT_TABLET_TOOL_TYPE_PEN: str = "pen"; break;
|
|
|
|
|
case LIBINPUT_TABLET_TOOL_TYPE_ERASER: str = "eraser"; break;
|
|
|
|
|
case LIBINPUT_TABLET_TOOL_TYPE_BRUSH: str = "brush"; break;
|
|
|
|
|
case LIBINPUT_TABLET_TOOL_TYPE_PENCIL: str = "pencil"; break;
|
|
|
|
|
case LIBINPUT_TABLET_TOOL_TYPE_AIRBRUSH: str = "airbrush"; break;
|
|
|
|
|
case LIBINPUT_TABLET_TOOL_TYPE_MOUSE: str = "mouse"; break;
|
|
|
|
|
case LIBINPUT_TABLET_TOOL_TYPE_LENS: str = "lens"; break;
|
|
|
|
|
default:
|
|
|
|
|
abort();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return str;
|
|
|
|
|
}
|
|
|
|
|
|
2016-06-09 11:15:51 +10:00
|
|
|
static inline struct libinput *
|
|
|
|
|
tablet_libinput_context(const struct tablet_dispatch *tablet)
|
|
|
|
|
{
|
|
|
|
|
return evdev_libinput_context(tablet->device);
|
|
|
|
|
}
|
|
|
|
|
|
2014-06-05 23:20:36 -04:00
|
|
|
#endif
|