chiark / gitweb /
xf86-input-mtrack (0.3.1-1) unstable; urgency=medium
[xf86-input-mtrack.git] / driver / mprops.c
1 /***************************************************************************
2  *
3  * Multitouch X driver
4  * Copyright (C) 2011 Ryan Bourgeois <bluedragonx@gmail.com>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  **************************************************************************/
21
22 #include "mprops.h"
23 #include "common.h"
24 #include "mtouch.h"
25
26 #define MAX_INT_VALUES 4
27 #define MAX_FLOAT_VALUES 4
28
29 #define VALID_BUTTON(x) (x >= 0 && x <= 32)
30 #define VALID_BOOL(x) (x == 0 || x == 1)
31 #define VALID_PCNT(x) (x >= 0 && x <= 100)
32
33 struct MProps mprops;
34
35 Atom atom_init_integer(DeviceIntPtr dev, char* name, int nvalues, int* values, int size) {
36         Atom atom;
37         int i;
38         uint8_t uvals8[MAX_INT_VALUES];
39         uint16_t uvals16[MAX_INT_VALUES];
40         uint32_t uvals32[MAX_INT_VALUES];
41         pointer uvals;
42         nvalues = MINVAL(MAX_INT_VALUES, nvalues);
43
44         switch(size) {
45         case 8:
46                 for (i = 0; i < nvalues; i++) {
47                         uvals8[i] = values[i];
48                 }
49                 uvals = uvals8;
50                 break;
51         case 16:
52                 for (i = 0; i < nvalues; i++) {
53                         uvals16[i] = values[i];
54                 }
55                 uvals = uvals16;
56                 break;
57         default:
58                 for (i = 0; i < nvalues; i++) {
59                         uvals32[i] = values[i];
60                 }
61                 uvals = uvals32;
62                 break;
63         }
64
65         atom = MakeAtom(name, strlen(name), TRUE);
66         XIChangeDeviceProperty(dev, atom, XA_INTEGER, size, PropModeReplace, nvalues, uvals, FALSE);
67         XISetDevicePropertyDeletable(dev, atom, FALSE);
68         return atom;
69 }
70
71 Atom atom_init_float(DeviceIntPtr dev, char* name, int nvalues, float* values, Atom float_type) {
72         Atom atom = MakeAtom(name, strlen(name), TRUE);
73         XIChangeDeviceProperty(dev, atom, float_type, 32, PropModeReplace, nvalues, values, FALSE);
74         XISetDevicePropertyDeletable(dev, atom, FALSE);
75         return atom;
76 }
77
78 void mprops_init(struct MConfig* cfg, InputInfoPtr local) {
79         int ivals[MAX_INT_VALUES];
80         float fvals[MAX_FLOAT_VALUES];
81
82         mprops.float_type = XIGetKnownProperty(XATOM_FLOAT);
83         if (!mprops.float_type) {
84                 mprops.float_type = MakeAtom(XATOM_FLOAT, strlen(XATOM_FLOAT), TRUE);
85                 if (!mprops.float_type) {
86                         xf86Msg(X_ERROR, "mtrack: %s: Failed to init float atom. Property support is disabled.\n", local->name);
87                         return;
88                 }
89         }
90
91         ivals[0] = cfg->trackpad_disable;
92         mprops.trackpad_disable = atom_init_integer(local->dev, MTRACK_PROP_TRACKPAD_DISABLE, 1, ivals, 8);
93
94         fvals[0] = (float)cfg->sensitivity;
95         mprops.sensitivity = atom_init_float(local->dev, MTRACK_PROP_SENSITIVITY, 1, fvals, mprops.float_type);
96
97         ivals[0] = cfg->touch_down;
98         ivals[1] = cfg->touch_up;
99         mprops.pressure = atom_init_integer(local->dev, MTRACK_PROP_PRESSURE, 2, ivals, 8);
100
101         ivals[0] = cfg->button_enable;
102         ivals[1] = cfg->button_integrated;
103         mprops.button_settings = atom_init_integer(local->dev, MTRACK_PROP_BUTTON_SETTINGS, 2, ivals, 8);
104
105         ivals[0] = cfg->button_zones;
106         ivals[1] = cfg->button_move;
107         ivals[2] = cfg->button_expire;
108         mprops.button_emulate_settings = atom_init_integer(local->dev, MTRACK_PROP_BUTTON_EMULATE_SETTINGS, 3, ivals, 16);
109
110         ivals[0] = cfg->button_1touch;
111         ivals[1] = cfg->button_2touch;
112         ivals[2] = cfg->button_3touch;
113         mprops.button_emulate_values = atom_init_integer(local->dev, MTRACK_PROP_BUTTON_EMULATE_VALUES, 3, ivals, 8);
114
115         ivals[0] = cfg->tap_hold;
116         ivals[1] = cfg->tap_timeout;
117         ivals[2] = cfg->tap_dist;
118         mprops.tap_settings = atom_init_integer(local->dev, MTRACK_PROP_TAP_SETTINGS, 3, ivals, 32);
119
120         ivals[0] = cfg->tap_1touch;
121         ivals[1] = cfg->tap_2touch;
122         ivals[2] = cfg->tap_3touch;
123         ivals[3] = cfg->tap_4touch;
124         mprops.tap_emulate = atom_init_integer(local->dev, MTRACK_PROP_TAP_EMULATE, 4, ivals, 8);
125
126         ivals[0] = cfg->ignore_thumb;
127         ivals[1] = cfg->disable_on_thumb;
128         mprops.thumb_detect = atom_init_integer(local->dev, MTRACK_PROP_THUMB_DETECT, 2, ivals, 8);
129
130         ivals[0] = cfg->thumb_size;
131         ivals[1] = cfg->thumb_ratio;
132         mprops.thumb_size = atom_init_integer(local->dev, MTRACK_PROP_THUMB_SIZE, 2, ivals, 32);
133
134         ivals[0] = cfg->ignore_palm;
135         ivals[1] = cfg->disable_on_palm;
136         mprops.palm_detect = atom_init_integer(local->dev, MTRACK_PROP_PALM_DETECT, 2, ivals, 8);
137
138         ivals[0] = cfg->palm_size;
139         mprops.palm_size = atom_init_integer(local->dev, MTRACK_PROP_PALM_SIZE, 1, ivals, 32);
140
141         ivals[0] = cfg->gesture_hold;
142         ivals[1] = cfg->gesture_wait;
143         mprops.gesture_settings = atom_init_integer(local->dev, MTRACK_PROP_GESTURE_SETTINGS, 2, ivals, 16);
144
145         ivals[0] = cfg->scroll_dist;
146         mprops.scroll_dist = atom_init_integer(local->dev, MTRACK_PROP_SCROLL_DIST, 1, ivals, 32);
147
148         ivals[0] = cfg->scroll_up_btn;
149         ivals[1] = cfg->scroll_dn_btn;
150         ivals[2] = cfg->scroll_lt_btn;
151         ivals[3] = cfg->scroll_rt_btn;
152         mprops.scroll_buttons = atom_init_integer(local->dev, MTRACK_PROP_SCROLL_BUTTONS, 4, ivals, 8);
153
154         ivals[0] = cfg->swipe_dist;
155         mprops.swipe_dist = atom_init_integer(local->dev, MTRACK_PROP_SWIPE_DIST, 1, ivals, 32);
156
157         ivals[0] = cfg->swipe_up_btn;
158         ivals[1] = cfg->swipe_dn_btn;
159         ivals[2] = cfg->swipe_lt_btn;
160         ivals[3] = cfg->swipe_rt_btn;
161         mprops.swipe_buttons = atom_init_integer(local->dev, MTRACK_PROP_SWIPE_BUTTONS, 4, ivals, 8);
162
163         ivals[0] = cfg->swipe4_dist;
164         mprops.swipe4_dist = atom_init_integer(local->dev, MTRACK_PROP_SWIPE4_DIST, 1, ivals, 32);
165
166         ivals[0] = cfg->swipe4_up_btn;
167         ivals[1] = cfg->swipe4_dn_btn;
168         ivals[2] = cfg->swipe4_lt_btn;
169         ivals[3] = cfg->swipe4_rt_btn;
170         mprops.swipe4_buttons = atom_init_integer(local->dev, MTRACK_PROP_SWIPE4_BUTTONS, 4, ivals, 8);
171
172         ivals[0] = cfg->scale_dist;
173         mprops.scale_dist = atom_init_integer(local->dev, MTRACK_PROP_SCALE_DIST, 1, ivals, 32);
174
175         ivals[0] = cfg->scale_up_btn;
176         ivals[1] = cfg->scale_dn_btn;
177         mprops.scale_buttons = atom_init_integer(local->dev, MTRACK_PROP_SCALE_BUTTONS, 2, ivals, 8);
178
179         ivals[0] = cfg->rotate_dist;
180         mprops.rotate_dist = atom_init_integer(local->dev, MTRACK_PROP_ROTATE_DIST, 1, ivals, 32);
181
182         ivals[0] = cfg->rotate_lt_btn;
183         ivals[1] = cfg->rotate_rt_btn;
184         mprops.rotate_buttons = atom_init_integer(local->dev, MTRACK_PROP_SCALE_BUTTONS, 2, ivals, 8);
185
186         ivals[0] = cfg->drag_enable;
187         ivals[1] = cfg->drag_timeout;
188         ivals[2] = cfg->drag_wait;
189         ivals[3] = cfg->drag_dist;
190         mprops.drag_settings = atom_init_integer(local->dev, MTRACK_PROP_DRAG_SETTINGS, 4, ivals, 32);
191
192         ivals[0] = cfg->axis_x_invert;
193         ivals[1] = cfg->axis_y_invert;
194         mprops.axis_invert = atom_init_integer(local->dev, MTRACK_PROP_AXIS_INVERT, 2, ivals, 8);
195 }
196
197 int mprops_set_property(DeviceIntPtr dev, Atom property, XIPropertyValuePtr prop, BOOL checkonly) {
198         InputInfoPtr local = dev->public.devicePrivate;
199         struct MConfig* cfg = &((struct MTouch*)local->private)->cfg;
200
201         uint8_t* ivals8;
202         uint16_t* ivals16;
203         uint32_t* ivals32;
204         float* fvals;
205
206         if (property == mprops.trackpad_disable) {
207                 if (prop->size != 1 || prop->format != 8 || prop->type != XA_INTEGER)
208                         return BadMatch;
209
210                 ivals8 = (uint8_t*)prop->data;
211                 if (ivals8[0] < 0 || ivals8[0] > 3)
212                         return BadMatch;
213
214                 if (!checkonly) {
215                         cfg->trackpad_disable = ivals8[0];
216 #ifdef DEBUG_PROPS
217                         if (cfg->trackpad_disable)
218                                 xf86Msg(X_INFO, "mtrack: trackpad input disabled\n");
219                         else
220                                 xf86Msg(X_INFO, "mtrack: trackpad input enabled\n");
221 #endif
222                 }
223         }
224         else if (property == mprops.sensitivity) {
225                 if (prop->size != 1 || prop->format != 32 || prop->type != mprops.float_type)
226                         return BadMatch;
227
228                 fvals = (float*)prop->data;
229                 if (fvals[0] < 0)
230                         return BadMatch;
231
232                 if (!checkonly) {
233                         cfg->sensitivity = fvals[0];
234 #ifdef DEBUG_PROPS
235                         xf86Msg(X_INFO, "mtrack: set sensitivity to %f\n", cfg->sensitivity);
236 #endif
237                 }
238         }
239         else if (property == mprops.pressure) {
240                 if (prop->size != 2 || prop->format != 8 || prop->type != XA_INTEGER) 
241                         return BadMatch;
242
243                 ivals8 = (uint8_t*)prop->data;
244                 if (!VALID_PCNT(ivals8[0]) || !VALID_PCNT(ivals8[1]))
245                         return BadMatch;
246
247                 if (!checkonly) {
248                         cfg->touch_down = ivals8[0];
249                         cfg->touch_up = ivals8[1];
250 #ifdef DEBUG_PROPS
251                         xf86Msg(X_INFO, "mtrack: set touch pressure to %d %d\n",
252                                 cfg->touch_down, cfg->touch_up);
253 #endif
254                 }
255         }
256         else if (property == mprops.button_settings) {
257                 if (prop->size != 2 || prop->format != 8 || prop->type != XA_INTEGER) 
258                         return BadMatch;
259
260                 ivals8 = (uint8_t*)prop->data;
261                 if (!VALID_BOOL(ivals16[0]) || !VALID_BOOL(ivals16[1]))
262                         return BadMatch;
263
264                 if (!checkonly) {
265                         cfg->button_enable = ivals8[0];
266                         cfg->button_integrated = ivals8[1];
267 #ifdef DEBUG_PROPS
268                         xf86Msg(X_INFO, "mtrack: set button settings to %d %d\n",
269                                 cfg->button_enable, cfg->button_integrated);
270 #endif
271                 }
272         }
273         else if (property == mprops.button_emulate_settings) {
274                 if (prop->size != 3 || prop->format != 16 || prop->type != XA_INTEGER)
275                         return BadMatch;
276
277                 ivals16 = (uint16_t*)prop->data;
278                 if (!VALID_BOOL(ivals16[0]) || !VALID_BOOL(ivals16[1]) || ivals16[2] < 0)
279                         return BadMatch;
280
281                 if (!checkonly) {
282                         cfg->button_zones = ivals16[0];
283                         cfg->button_move = ivals16[1];
284                         cfg->button_expire = ivals16[2];
285 #ifdef DEBUG_PROPS
286                         xf86Msg(X_INFO, "mtrack: set button emulate settings to %d %d %d\n",
287                                 cfg->button_zones, cfg->button_move, cfg->button_expire);
288 #endif
289                 }
290         }
291         else if (property == mprops.button_emulate_values) {
292                 if (prop->size != 3 || prop->format != 8 || prop->type != XA_INTEGER)
293                         return BadMatch;
294
295                 ivals8 = (uint8_t*)prop->data;
296                 if (!VALID_BUTTON(ivals8[0]) || !VALID_BUTTON(ivals8[1]) || !VALID_BUTTON(ivals8[2]))
297                         return BadMatch;
298
299                 if (!checkonly) {
300                         cfg->button_1touch = ivals8[0];
301                         cfg->button_2touch = ivals8[1];
302                         cfg->button_3touch = ivals8[2];
303 #ifdef DEBUG_PROPS
304                         xf86Msg(X_INFO, "mtrack: set button emulation to %d %d %s\n",
305                                 cfg->button_1touch, cfg->button_2touch, cfg->button_3touch);
306 #endif
307                 }
308         }
309         else if (property == mprops.tap_settings) {
310                 if (prop->size != 3 || prop->format != 32 || prop->type != XA_INTEGER)
311                         return BadMatch;
312
313                 ivals32 = (uint32_t*)prop->data;
314                 if (ivals32[0] < 1 || ivals32[1] < 1 || ivals32[2] < 1)
315                         return BadMatch;
316
317                 if (!checkonly) {
318                         cfg->tap_hold = ivals32[0];
319                         cfg->tap_timeout = ivals32[1];
320                         cfg->tap_dist = ivals32[2];
321 #ifdef DEBUG_PROPS
322                         xf86Msg(X_INFO, "mtrack: set tap settings to %d %d %d\n",
323                                 cfg->tap_hold, cfg->tap_timeout, cfg->tap_dist);
324 #endif
325                 }
326         }
327         else if (property == mprops.tap_emulate) {
328                 if (prop->size != 4 || prop->format != 8 || prop->type != XA_INTEGER)
329                         return BadMatch;
330
331                 ivals8 = (uint8_t*)prop->data;
332                 if (!VALID_BUTTON(ivals8[0]) || !VALID_BUTTON(ivals8[1]) || !VALID_BUTTON(ivals8[2]) || !VALID_BUTTON(ivals8[3]))
333                         return BadMatch;
334
335                 if (!checkonly) {                       
336                         cfg->tap_1touch = ivals8[0];
337                         cfg->tap_2touch = ivals8[1];
338                         cfg->tap_3touch = ivals8[2];
339                         cfg->tap_4touch = ivals8[3];
340 #ifdef DEBUG_PROPS
341                         xf86Msg(X_INFO, "mtrack: set tap emulation to %d %d %d %d\n",
342                                 cfg->tap_1touch, cfg->tap_2touch, cfg->tap_3touch, cfg->tap_4touch);
343 #endif
344                 }
345         }
346         else if (property == mprops.thumb_detect) {
347                 if (prop->size != 2 || prop->format != 8 || prop->type != XA_INTEGER)
348                         return BadMatch;
349
350                 ivals8 = (uint8_t*)prop->data;
351                 if (!VALID_BOOL(ivals8[0]) || !VALID_BOOL(ivals8[1]))
352                         return BadMatch;
353
354                 if (!checkonly) {
355                         cfg->ignore_thumb = ivals8[0];
356                         cfg->disable_on_thumb = ivals8[1];
357 #ifdef DEBUG_PROPS
358                         xf86Msg(X_INFO, "mtrack: set thumb detect to %d %d\n",
359                                 cfg->ignore_thumb, cfg->disable_on_thumb);
360 #endif
361                 }
362         }
363         else if (property == mprops.thumb_size) {
364                 if (prop->size != 2 || prop->format != 32 || prop->type != XA_INTEGER)
365                         return BadMatch;
366
367                 ivals32 = (uint32_t*)prop->data;
368                 if (ivals32[0] < 0 || !VALID_PCNT(ivals32[1]))
369                         return BadMatch;
370
371                 if (!checkonly) {
372                         cfg->thumb_size = ivals32[0];
373                         cfg->thumb_ratio = ivals32[0];
374 #ifdef DEBUG_PROPS
375                         xf86Msg(X_INFO, "mtrack: set thumb size to %d %d\n",
376                                 cfg->thumb_size, cfg->thumb_ratio);
377 #endif
378                 }
379         }
380         else if (property == mprops.palm_detect) {
381                 if (prop->size != 2 || prop->format != 8 || prop->type != XA_INTEGER)
382                         return BadMatch;
383
384                 ivals8 = (uint8_t*)prop->data;
385                 if (!VALID_BOOL(ivals8[0]) || !VALID_BOOL(ivals8[1]))
386                         return BadMatch;
387
388                 if (!checkonly) {
389                         cfg->ignore_palm = ivals8[0];
390                         cfg->disable_on_palm = ivals8[1];
391 #ifdef DEBUG_PROPS
392                         xf86Msg(X_INFO, "mtrack: set palm detect to %d %d\n",
393                                 cfg->ignore_palm, cfg->disable_on_palm);
394 #endif
395                 }
396         }
397         else if (property == mprops.palm_size) {
398                 if (prop->size != 1 || prop->format != 32 || prop->type != XA_INTEGER)
399                         return BadMatch;
400
401                 ivals32 = (uint32_t*)prop->data;
402                 if (ivals32[0] < 0)
403                         return BadMatch;
404
405                 if (!checkonly) {
406                         cfg->palm_size = ivals32[0];
407 #ifdef DEBUG_PROPS
408                         xf86Msg(X_INFO, "mtrack: set palm size to %d\n",
409                                 cfg->palm_size);
410 #endif
411                 }
412         }
413         else if (property == mprops.gesture_settings) {
414                 if (prop->size != 2 || prop->format != 16 || prop->type != XA_INTEGER)
415                         return BadMatch;
416
417                 ivals16 = (uint16_t*)prop->data;
418                 if (ivals16[0] < 1 || ivals16[1] < 0)
419                         return BadMatch;
420
421                 if (!checkonly) {
422                         cfg->gesture_hold = ivals16[0];
423                         cfg->gesture_wait = ivals16[1];
424 #ifdef DEBUG_PROPS
425                         xf86Msg(X_INFO, "mtrack: set gesture settings to %d %d\n",
426                                 cfg->gesture_hold, cfg->gesture_wait);
427 #endif
428                 }
429         }
430         else if (property == mprops.scroll_dist) {
431                 if (prop->size != 1 || prop->format != 32 || prop->type != XA_INTEGER)
432                         return BadMatch;
433
434                 ivals32 = (uint32_t*)prop->data;
435                 if (ivals32[0] < 1)
436                         return BadMatch;
437
438                 if (!checkonly) {
439                         cfg->scroll_dist = ivals32[0];
440 #ifdef DEBUG_PROPS
441                         xf86Msg(X_INFO, "mtrack: set scroll distance to %d\n",
442                                 cfg->scroll_dist);
443 #endif
444                 }
445         }
446         else if (property == mprops.scroll_buttons) {
447                 if (prop->size != 4 || prop->format != 8 || prop->type != XA_INTEGER)
448                         return BadMatch;
449
450                 ivals8 = (uint8_t*)prop->data;
451                 if (!VALID_BUTTON(ivals8[0]) || !VALID_BUTTON(ivals8[1]) || !VALID_BUTTON(ivals8[2]) || !VALID_BUTTON(ivals8[3]))
452                         return BadMatch;
453
454                 if (!checkonly) {
455                         cfg->scroll_up_btn = ivals8[0];
456                         cfg->scroll_dn_btn = ivals8[1];
457                         cfg->scroll_lt_btn = ivals8[2];
458                         cfg->scroll_rt_btn = ivals8[3];
459 #ifdef DEBUG_PROPS
460                         xf86Msg(X_INFO, "mtrack: set scroll buttons to %d %d %d %d\n",
461                                 cfg->scroll_up_btn, cfg->scroll_dn_btn, cfg->scroll_lt_btn, cfg->scroll_rt_btn);
462 #endif
463                 }
464         }
465         else if (property == mprops.swipe_dist) {
466                 if (prop->size != 1 || prop->format != 32 || prop->type != XA_INTEGER)
467                         return BadMatch;
468
469                 ivals32 = (uint32_t*)prop->data;
470                 if (ivals32[0] < 1)
471                         return BadMatch;
472
473                 if (!checkonly) {
474                         cfg->swipe_dist = ivals32[0];
475 #ifdef DEBUG_PROPS
476                         xf86Msg(X_INFO, "mtrack: set swipe distance to %d\n",
477                                 cfg->swipe_dist);
478 #endif
479                 }
480         }
481         else if (property == mprops.swipe_buttons) {
482                 if (prop->size != 4 || prop->format != 8 || prop->type != XA_INTEGER)
483                         return BadMatch;
484
485                 ivals8 = (uint8_t*)prop->data;
486                 if (!VALID_BUTTON(ivals8[0]) || !VALID_BUTTON(ivals8[1]) || !VALID_BUTTON(ivals8[2]) || !VALID_BUTTON(ivals8[3]))
487                         return BadMatch;
488
489                 if (!checkonly) {
490                         cfg->swipe_up_btn = ivals8[0];
491                         cfg->swipe_dn_btn = ivals8[1];
492                         cfg->swipe_lt_btn = ivals8[2];
493                         cfg->swipe_rt_btn = ivals8[3];
494 #ifdef DEBUG_PROPS
495                         xf86Msg(X_INFO, "mtrack: set swipe buttons to %d %d %d %d\n",
496                                 cfg->swipe_up_btn, cfg->swipe_dn_btn, cfg->swipe_lt_btn, cfg->swipe_rt_btn);
497 #endif
498                 }
499         }
500         else if (property == mprops.swipe4_dist) {
501                 if (prop->size != 1 || prop->format != 32 || prop->type != XA_INTEGER)
502                         return BadMatch;
503
504                 ivals32 = (uint32_t*)prop->data;
505                 if (ivals32[0] < 1)
506                         return BadMatch;
507
508                 if (!checkonly) {
509                         cfg->swipe4_dist = ivals32[0];
510 #ifdef DEBUG_PROPS
511                         xf86Msg(X_INFO, "mtrack: set swipe4 distance to %d\n",
512                                 cfg->swipe4_dist);
513 #endif
514                 }
515         }
516         else if (property == mprops.swipe4_buttons) {
517                 if (prop->size != 4 || prop->format != 8 || prop->type != XA_INTEGER)
518                         return BadMatch;
519
520                 ivals8 = (uint8_t*)prop->data;
521                 if (!VALID_BUTTON(ivals8[0]) || !VALID_BUTTON(ivals8[1]) || !VALID_BUTTON(ivals8[2]) || !VALID_BUTTON(ivals8[3]))
522                         return BadMatch;
523
524                 if (!checkonly) {
525                         cfg->swipe4_up_btn = ivals8[0];
526                         cfg->swipe4_dn_btn = ivals8[1];
527                         cfg->swipe4_lt_btn = ivals8[2];
528                         cfg->swipe4_rt_btn = ivals8[3];
529 #ifdef DEBUG_PROPS
530                         xf86Msg(X_INFO, "mtrack: set swipe4 buttons to %d %d %d %d\n",
531                                 cfg->swipe4_up_btn, cfg->swipe4_dn_btn, cfg->swipe4_lt_btn, cfg->swipe4_rt_btn);
532 #endif
533                 }
534         }
535         else if (property == mprops.scale_dist) {
536                 if (prop->size != 1 || prop->format != 32 || prop->type != XA_INTEGER)
537                         return BadMatch;
538
539                 ivals32 = (uint32_t*)prop->data;
540                 if (ivals32[0] < 1)
541                         return BadMatch;
542
543                 if (!checkonly) {
544                         cfg->scale_dist = ivals32[0];
545 #ifdef DEBUG_PROPS
546                         xf86Msg(X_INFO, "mtrack: set scale distance to %d\n",
547                                 cfg->scale_dist);
548 #endif
549                 }
550         }
551         else if (property == mprops.scale_buttons) {
552                 if (prop->size != 4 || prop->format != 8 || prop->type != XA_INTEGER)
553                         return BadMatch;
554
555                 ivals8 = (uint8_t*)prop->data;
556                 if (!VALID_BUTTON(ivals8[0]) || !VALID_BUTTON(ivals8[1]) || !VALID_BUTTON(ivals8[2]) || !VALID_BUTTON(ivals8[3]))
557                         return BadMatch;
558
559                 if (!checkonly) {
560                         cfg->scale_up_btn = ivals8[0];
561                         cfg->scale_dn_btn = ivals8[1];
562 #ifdef DEBUG_PROPS
563                         xf86Msg(X_INFO, "mtrack: set scale buttons to %d %d\n",
564                                 cfg->scale_up_btn, cfg->scale_dn_btn);
565 #endif
566                 }
567         }
568         else if (property == mprops.rotate_dist) {
569                 if (prop->size != 1 || prop->format != 32 || prop->type != XA_INTEGER)
570                         return BadMatch;
571
572                 ivals32 = (uint32_t*)prop->data;
573                 if (ivals32[0] < 1)
574                         return BadMatch;
575
576                 if (!checkonly) {
577                         cfg->rotate_dist = ivals32[0];
578 #ifdef DEBUG_PROPS
579                         xf86Msg(X_INFO, "mtrack: set rotate distance to %d\n",
580                                 cfg->rotate_dist);
581 #endif
582                 }
583         }
584         else if (property == mprops.rotate_buttons) {
585                 if (prop->size != 4 || prop->format != 8 || prop->type != XA_INTEGER)
586                         return BadMatch;
587
588                 ivals8 = (uint8_t*)prop->data;
589                 if (!VALID_BUTTON(ivals8[0]) || !VALID_BUTTON(ivals8[1]) || !VALID_BUTTON(ivals8[2]) || !VALID_BUTTON(ivals8[3]))
590                         return BadMatch;
591
592                 if (!checkonly) {
593                         cfg->rotate_lt_btn = ivals8[0];
594                         cfg->rotate_rt_btn = ivals8[1];
595 #ifdef DEBUG_PROPS
596                         xf86Msg(X_INFO, "mtrack: set rotate buttons to %d %d\n",
597                                 cfg->rotate_lt_btn, cfg->rotate_rt_btn);
598 #endif
599                 }
600         }
601         else if (property == mprops.drag_settings) {
602                 if (prop->size != 4 || prop->format != 32 || prop->type != XA_INTEGER)
603                         return BadMatch;
604
605                 ivals32 = (uint32_t*)prop->data;
606                 if (!VALID_BOOL(ivals32[0]) || ivals32[1] < 1 || ivals32[2] < 0 || ivals32[3] < 0)
607                         return BadMatch;
608
609                 if (!checkonly) {
610                         cfg->drag_enable = ivals32[0];
611                         cfg->drag_timeout = ivals32[1];
612                         cfg->drag_wait = ivals32[2];
613                         cfg->drag_dist = ivals32[3];
614 #ifdef DEBUG_PROPS
615                         xf86Msg(X_INFO, "mtrack: set drag settings to %d %d %d %d\n",
616                                 cfg->drag_enable, cfg->drag_timeout, cfg->drag_wait, cfg->drag_dist);
617 #endif
618                 }
619         }
620         else if (property == mprops.axis_invert) {
621                 if (prop->size != 2 || prop->format != 8 || prop->type != XA_INTEGER)
622                         return BadMatch;
623
624                 ivals8 = (uint8_t*)prop->data;
625                 if (!VALID_BOOL(ivals8[0]) || !VALID_BOOL(ivals8[1]))
626                         return BadMatch;
627
628                 if (!checkonly) {
629                         cfg->axis_x_invert = ivals8[0];
630                         cfg->axis_y_invert = ivals8[1];
631 #ifdef DEBUG_PROPS
632                         xf86Msg(X_INFO, "mtrack: set axis inversion to %d %d\n",
633                                 cfg->axis_x_invert, cfg->axis_y_invert);
634 #endif
635                 }
636         }
637
638         return Success;
639 }
640