summaryrefslogtreecommitdiff
path: root/src/xf86Wacom.h
blob: 260347089e314ea056f9218658456dce1a6fe6ad (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
/*
 * Copyright 1995-2002 by Frederic Lepied, France. <Lepied@XFree86.org>
 * Copyright 2002-2010 by Ping Cheng, Wacom. <pingc@wacom.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

#ifndef __XF86_XF86WACOM_H
#define __XF86_XF86WACOM_H

#include <xorg-server.h>

#include "Xwacom.h"

#include <string.h>
#include <errno.h>

#include <xf86.h>
#include <xf86Xinput.h>

#include <wacom-util.h>

#ifndef _fallthrough_
#define _fallthrough_ __attribute__((fallthrough))
#endif

#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 23
#define HAVE_THREADED_INPUT 1
#endif

#ifndef SW_MUTE_DEVICE
#define SW_MUTE_DEVICE	0x0e
#endif

/******************************************************************************
 * Debugging support
 *****************************************************************************/

#ifdef DBG
#undef DBG
#endif

#ifdef DEBUG
#define DBG(lvl, priv, ...) \
	do { \
		if ((lvl) <= priv->debugLevel) { \
			wcmLog(NULL, W_INFO, "%s (%d:%s): ", \
				((WacomDeviceRec*)priv)->name, lvl, __func__); \
			wcmLog(NULL, W_NONE, __VA_ARGS__); \
		} \
	} while (0)
#else
#define DBG(lvl, priv, ...) do {} while(0)
#endif

/* The rest are defined in a separate .h-file */
#include "xf86WacomDefs.h"

/* Identical to MessageType */
typedef enum {
      W_PROBED,                   /* Value was probed */
      W_CONFIG,                   /* Value was given in the config file */
      W_DEFAULT,                  /* Value is a default */
      W_CMDLINE,                  /* Value was given on the command line */
      W_NOTICE,                   /* Notice */
      W_ERROR,                    /* Error message */
      W_WARNING,                  /* Warning message */
      W_INFO,                     /* Informational message */
      W_NONE,                     /* No prefix */
      W_NOT_IMPLEMENTED,          /* Not implemented */
      W_DEBUG,                    /* Debug message */
      W_UNKNOWN = -1              /* unknown -- this must always be last */
} WacomLogType;

_X_ATTRIBUTE_PRINTF(3, 4)
static inline void
wcmLog(WacomDevicePtr priv, WacomLogType type, const char *format, ...)
{
	MessageType xtype = (MessageType)type;
	va_list args;

	va_start(args, format);
	if (!priv) {
		LogVMessageVerbSigSafe(xtype, -1, format, args);
	} else {
		xf86VIDrvMsgVerb(priv->pInfo, xtype, 0, format, args);
	}
	va_end(args);
}

/*****************************************************************************
 * General Inlined functions and Prototypes
 ****************************************************************************/
/* BIG HAIRY WARNING:
 * Don't overuse SYSCALL(): use it ONLY when you call low-level functions such
 * as ioctl(), read(), write() and such. Otherwise you can easily lock up X11,
 * for example: you pull out the USB tablet, the handle becomes invalid,
 * xf86ReadSerial() returns -1 AND errno is left as EINTR from hell knows where.
 * Then you'll loop forever, and even Ctrl+Alt+Backspace doesn't help.
 * xf86ReadSerial, WriteSerial, CloseSerial & company already use SYSCALL()
 * internally; there's no need to duplicate it outside the call.
 */
#define SYSCALL(call) while(((call) == -1) && (errno == EINTR))

WacomDevicePtr wcmAllocate(InputInfoPtr pInfo, const char *name);
int wcmPreInit(WacomDevicePtr priv);
void wcmUnInit(WacomDevicePtr priv);
/* Open the **shared** fd, if necessary */
int wcmDevOpen(WacomDevicePtr priv);
int wcmDevInit(WacomDevicePtr priv);
/* Close the **shared** fd, if necessary */
void wcmDevClose(WacomDevicePtr priv);
Bool wcmDevStart(WacomDevicePtr priv);
void wcmDevStop(WacomDevicePtr priv);

/* Open the device with the right serial parmeters */
extern Bool wcmOpen(WacomDevicePtr priv);

/* Close the device */
extern void wcmClose(WacomDevicePtr priv);

void wcmRemoveActive(WacomDevicePtr priv);

/* device autoprobing */
char *wcmEventAutoDevProbe (WacomDevicePtr priv);

/* common tablet initialization regime */
int wcmInitTablet(WacomDevicePtr priv);

/* standard packet handler */
int wcmReadPacket(WacomDevicePtr priv);

/* handles suppression, filtering, and dispatch. */
void wcmEvent(WacomCommonPtr common, unsigned int channel, const WacomDeviceState* ds);

/* dispatches data to XInput event system */
void wcmSendEvents(WacomDevicePtr priv, const WacomDeviceState* ds);

/* validation */
extern Bool wcmIsAValidType(WacomDevicePtr priv, const char* type);
extern int wcmIsDuplicate(const char* device, WacomDevicePtr priv);
extern int wcmDeviceTypeKeys(WacomDevicePtr priv);

/* hotplug */
extern int wcmNeedAutoHotplug(WacomDevicePtr priv, char **type);
extern void wcmHotplugOthers(WacomDevicePtr priv, const char *basename);

/* setup */
extern Bool wcmPreInitParseOptions(WacomDevicePtr priv, Bool is_primary, Bool is_dependent);
extern Bool wcmPostInitParseOptions(WacomDevicePtr priv, Bool is_primary, Bool is_dependent);
extern int wcmParseSerials(WacomDevicePtr priv);

extern int wcmDevSwitchModeCall(WacomDevicePtr priv, int mode);

extern void wcmResetButtonAction(WacomDevicePtr priv, int button);
extern void wcmResetStripAction(WacomDevicePtr priv, int index);
extern void wcmResetWheelAction(WacomDevicePtr priv, int index);

extern void wcmEnableTool(WacomDevicePtr priv);
extern void wcmDisableTool(WacomDevicePtr priv);
extern void wcmUnlinkTouchAndPen(WacomDevicePtr priv);

/* run-time modifications */
extern int wcmTilt2R(int x, int y, double offset);
extern void wcmSoftOutEvent(WacomDevicePtr priv);
extern void wcmCancelGesture(WacomDevicePtr priv);

extern void wcmRotateTablet(WacomDevicePtr priv, int value);
extern void wcmRotateAndScaleCoordinates(WacomDevicePtr priv, int* x, int* y);

extern int wcmCheckPressureCurveValues(int x0, int y0, int x1, int y1);
extern int wcmGetPhyDeviceID(WacomDevicePtr priv);

/* device properties */
extern void InitWcmDeviceProperties(WacomDevicePtr priv);
extern void wcmUpdateRotationProperty(WacomDevicePtr priv);
extern void wcmUpdateSerialProperty(WacomDevicePtr priv);
extern void wcmUpdateHWTouchProperty(WacomDevicePtr priv);

/* Utility functions */
extern Bool is_absolute(WacomDevicePtr priv);
extern void set_absolute(WacomDevicePtr priv, Bool absolute);
extern WacomCommonPtr wcmRefCommon(WacomCommonPtr common);
extern void wcmFreeCommon(WacomCommonPtr *common);
extern WacomCommonPtr wcmNewCommon(void);
extern void usbListModels(void);
extern int wcmScaleAxis(int Cx, int to_max, int to_min, int from_max, int from_min);

static inline void wcmActionCopy(WacomAction *dest, WacomAction *src)
{
	memset(dest, 0, sizeof(*dest));
	memcpy(dest, src, sizeof(*src));
}
static inline const unsigned* wcmActionData(const WacomAction *action)
{
	return action->action;
}
static inline size_t wcmActionSize(const WacomAction *action)
{
	return action->nactions;
}
static inline void wcmActionSet(WacomAction *action, unsigned idx, unsigned act)
{
	if (idx >= ARRAY_SIZE(action->action))
		return;
	action->action[idx] = act;
	action->nactions = idx + 1;
}

/* Axis and event handling */

enum WacomAxisType {
	WACOM_AXIS_X		= (1 << 0),
	WACOM_AXIS_Y		= (1 << 1),
	WACOM_AXIS_PRESSURE	= (1 << 2),
	WACOM_AXIS_TILT_X	= (1 << 3),
	WACOM_AXIS_TILT_Y	= (1 << 4),
	WACOM_AXIS_STRIP_X	= (1 << 5),
	WACOM_AXIS_STRIP_Y	= (1 << 6),
	WACOM_AXIS_ROTATION	= (1 << 7),
	WACOM_AXIS_THROTTLE	= (1 << 8),
	WACOM_AXIS_WHEEL	= (1 << 9),
	WACOM_AXIS_RING		= (1 << 10),
	WACOM_AXIS_RING2	= (1 << 11),

	_WACOM_AXIS_LAST = WACOM_AXIS_RING2,
};

typedef struct {
	uint32_t mask;
	int x, y;
	int pressure;
	int tilt_x, tilt_y;
	int strip_x, strip_y;
	int rotation;
	int throttle;
	int wheel;
	int ring, ring2;
} WacomAxisData;

static inline void wcmAxisSet(WacomAxisData *data,
			      enum WacomAxisType which, int value)
{
	data->mask |= which;
	switch (which){
	case WACOM_AXIS_X: data->x = value; break;
	case WACOM_AXIS_Y: data->y = value; break;
	case WACOM_AXIS_PRESSURE: data->pressure = value; break;
	case WACOM_AXIS_TILT_X: data->tilt_x = value; break;
	case WACOM_AXIS_TILT_Y: data->tilt_y = value; break;
	case WACOM_AXIS_STRIP_X: data->strip_x = value; break;
	case WACOM_AXIS_STRIP_Y: data->strip_y = value; break;
	case WACOM_AXIS_ROTATION: data->rotation = value; break;
	case WACOM_AXIS_THROTTLE: data->wheel = value; break;
	case WACOM_AXIS_WHEEL: data->wheel = value; break;
	case WACOM_AXIS_RING: data->ring = value; break;
	case WACOM_AXIS_RING2: data->ring2 = value; break;
	default:
		abort();
	}
}

static inline Bool wcmAxisGet(const WacomAxisData *data,
			      enum WacomAxisType which, int *value_out)
{
	if (!(data->mask & which))
		return FALSE;

	switch (which){
	case WACOM_AXIS_X: *value_out = data->x; break;
	case WACOM_AXIS_Y: *value_out = data->y; break;
	case WACOM_AXIS_PRESSURE: *value_out = data->pressure; break;
	case WACOM_AXIS_TILT_X: *value_out = data->tilt_x; break;
	case WACOM_AXIS_TILT_Y: *value_out = data->tilt_y; break;
	case WACOM_AXIS_STRIP_X: *value_out = data->strip_x; break;
	case WACOM_AXIS_STRIP_Y: *value_out = data->strip_y; break;
	case WACOM_AXIS_ROTATION: *value_out = data->rotation; break;
	case WACOM_AXIS_THROTTLE: *value_out = data->wheel; break;
	case WACOM_AXIS_WHEEL: *value_out = data->wheel; break;
	case WACOM_AXIS_RING: *value_out = data->ring; break;
	case WACOM_AXIS_RING2: *value_out = data->ring2; break;
	default:
		abort();
	}
	return TRUE;
}

void wcmInitAxis(WacomDevicePtr priv, enum WacomAxisType type, int min, int max, int res);
Bool wcmInitButtons(WacomDevicePtr priv, unsigned int nbuttons);
Bool wcmInitKeyboard(WacomDevicePtr priv);
Bool wcmInitPointer(WacomDevicePtr priv, int naxes, Bool is_absolute);
Bool wcmInitTouch(WacomDevicePtr priv, int ntouches, Bool is_direct_touch);


void wcmEmitKeycode(WacomDevicePtr priv, int keycode, int state);
void wcmEmitMotion(WacomDevicePtr priv, Bool is_absolute, const WacomAxisData *axes);
void wcmEmitButton(WacomDevicePtr priv, Bool is_absolute, int button, Bool is_press,
		   const WacomAxisData *axes);
void wcmEmitProximity(WacomDevicePtr priv, Bool is_proximity_in,
		      const WacomAxisData *axes);
void wcmEmitTouch(WacomDevicePtr priv, int type, unsigned int touchid, int x, int y);


enum WacomSuppressMode {
	SUPPRESS_NONE = 8,	/* Process event normally */
	SUPPRESS_ALL,		/* Supress and discard the whole event */
	SUPPRESS_NON_MOTION	/* Supress all events but x/y motion */
};

/****************************************************************************/

#ifndef UNIT_TESTS

# define TEST_NON_STATIC static

#else

# define TEST_NON_STATIC

/* For test suite */
/* xf86Wacom.c */
extern void wcmInitialToolSize(WacomDevicePtr priv);

/* wcmConfig.c */
extern int wcmSetType(WacomDevicePtr priv, const char *type);

/* wcmCommon.c */
extern int getScrollDelta(int current, int old, int wrap, int flags);
extern int getWheelButton(int delta, int action_up, int action_dn);
extern int rebasePressure(const WacomDevicePtr priv, const WacomDeviceState *ds);
extern int normalizePressure(const WacomDevicePtr priv, const int raw_pressure);
extern enum WacomSuppressMode wcmCheckSuppress(WacomCommonPtr common,
						const WacomDeviceState* dsOrig,
						WacomDeviceState* dsNew);

/* wcmUSB.c */
extern int mod_buttons(int buttons, int btn, int state);
#endif /* UNIT_TESTS */

#endif /* __XF86WACOM_H */

/* vim: set noexpandtab tabstop=8 shiftwidth=8: */