~jderose/ubuntu/saucy/xserver-xorg-input-synaptics/clickpad

« back to all changes in this revision

Viewing changes to src/eventcomm.c

  • Committer: Package Import Robot
  • Author(s): Maarten Lankhorst
  • Date: 2012-05-21 14:14:49 UTC
  • mfrom: (0.3.14 sid)
  • Revision ID: package-import@ubuntu.com-20120521141449-xj02s01b4b9yx2f1
Tags: 1.6.1-1ubuntu1
* Merged from Debian unstable
* Refreshed patches for indentation changes
  - 101_resolution_detect_option.patch
  - 118_quell_error_msg.patch
  - 124_syndaemon_events.patch
  - 125_option_rec_revert.patch
* Add temporary patches, for upstream git commits on synaptics-1.6-branch
* Fix memory corruption by driver (LP: #941953) FDo #49439
 - 201-Avoid-out-of-bounds-access-by-running-num_active_tou.patch
 - 202-Ignore-pre-existing-touches.patch
* Fix FDo #49966
 - 203-Fix-coasting-for-negative-ScrollDelta.patch
* Fix jumpy cursor after suspend/resume
 - 204-Reset-open-slots-array-on-device-disable.patch
* Fix another resume bug
 - 205-Reset-hw-x-y-to-INT_MIN-and-skip-HandleState-until-w.patch
* Fix division by 0 or infinite loop with zero scroll distance FDo #49965
 - 206-Don-t-allow-for-scroll-distances-of-0-49965.patch

Show diffs side-by-side

added added

removed removed

Lines of Context:
63
63
/**
64
64
 * Protocol-specific data.
65
65
 */
66
 
struct eventcomm_proto_data
67
 
{
 
66
struct eventcomm_proto_data {
68
67
    /**
69
68
     * Do we need to grab the event device?
70
69
     * Note that in the current flow, this variable is always false and
99
98
 
100
99
#ifdef HAVE_MULTITOUCH
101
100
static int
102
 
last_mt_vals_slot(const SynapticsPrivate *priv)
 
101
last_mt_vals_slot(const SynapticsPrivate * priv)
103
102
{
104
 
    struct eventcomm_proto_data *proto_data = (struct eventcomm_proto_data*)priv->proto_data;
 
103
    struct eventcomm_proto_data *proto_data =
 
104
        (struct eventcomm_proto_data *) priv->proto_data;
105
105
    int value = proto_data->cur_slot - proto_data->mtdev->caps.slot.minimum;
106
106
 
107
107
    return value < priv->num_slots ? value : -1;
110
110
static void
111
111
UninitializeTouch(InputInfoPtr pInfo)
112
112
{
113
 
    SynapticsPrivate *priv = (SynapticsPrivate *)pInfo->private;
114
 
    struct eventcomm_proto_data *proto_data = (struct eventcomm_proto_data*)priv->proto_data;
 
113
    SynapticsPrivate *priv = (SynapticsPrivate *) pInfo->private;
 
114
    struct eventcomm_proto_data *proto_data =
 
115
        (struct eventcomm_proto_data *) priv->proto_data;
115
116
 
116
117
    if (!priv->has_touch)
117
118
        return;
118
119
 
119
 
    if (proto_data->last_mt_vals)
120
 
    {
 
120
    if (proto_data->last_mt_vals) {
121
121
        int i;
122
122
 
123
123
        for (i = 0; i < priv->num_slots; i++)
134
134
static void
135
135
InitializeTouch(InputInfoPtr pInfo)
136
136
{
137
 
    SynapticsPrivate *priv = (SynapticsPrivate *)pInfo->private;
138
 
    struct eventcomm_proto_data *proto_data = (struct eventcomm_proto_data*)priv->proto_data;
 
137
    SynapticsPrivate *priv = (SynapticsPrivate *) pInfo->private;
 
138
    struct eventcomm_proto_data *proto_data =
 
139
        (struct eventcomm_proto_data *) priv->proto_data;
139
140
    int i;
140
141
 
141
142
    if (!priv->has_touch)
142
143
        return;
143
144
 
144
145
    proto_data->mtdev = mtdev_new_open(pInfo->fd);
145
 
    if (!proto_data->mtdev)
146
 
    {
 
146
    if (!proto_data->mtdev) {
147
147
        xf86IDrvMsg(pInfo, X_WARNING,
148
148
                    "failed to create mtdev instance, ignoring touch events\n");
149
149
        return;
152
152
    proto_data->cur_slot = proto_data->mtdev->caps.slot.value;
153
153
    proto_data->num_touches = 0;
154
154
 
155
 
    proto_data->last_mt_vals = calloc(priv->num_slots,
156
 
                                      sizeof(ValuatorMask *));
157
 
    if (!proto_data->last_mt_vals)
158
 
    {
 
155
    proto_data->last_mt_vals = calloc(priv->num_slots, sizeof(ValuatorMask *));
 
156
    if (!proto_data->last_mt_vals) {
159
157
        xf86IDrvMsg(pInfo, X_WARNING,
160
158
                    "failed to allocate MT last values mask array\n");
161
159
        UninitializeTouch(pInfo);
162
160
        return;
163
161
    }
164
162
 
165
 
    for (i = 0; i < priv->num_slots; i++)
166
 
    {
 
163
    for (i = 0; i < priv->num_slots; i++) {
167
164
        int j;
168
165
 
169
166
        proto_data->last_mt_vals[i] = valuator_mask_new(4 + priv->num_mt_axes);
170
 
        if (!proto_data->last_mt_vals[i])
171
 
        {
 
167
        if (!proto_data->last_mt_vals[i]) {
172
168
            xf86IDrvMsg(pInfo, X_WARNING,
173
169
                        "failed to allocate MT last values mask\n");
174
170
            UninitializeTouch(pInfo);
186
182
#endif
187
183
 
188
184
static Bool
189
 
EventDeviceOnHook(InputInfoPtr pInfo, SynapticsParameters *para)
 
185
EventDeviceOnHook(InputInfoPtr pInfo, SynapticsParameters * para)
190
186
{
191
 
    SynapticsPrivate *priv = (SynapticsPrivate *)pInfo->private;
192
 
    struct eventcomm_proto_data *proto_data = (struct eventcomm_proto_data*)priv->proto_data;
 
187
    SynapticsPrivate *priv = (SynapticsPrivate *) pInfo->private;
 
188
    struct eventcomm_proto_data *proto_data =
 
189
        (struct eventcomm_proto_data *) priv->proto_data;
193
190
 
194
191
    if (para->grab_event_device) {
195
 
        /* Try to grab the event device so that data don't leak to /dev/input/mice */
196
 
        int ret;
197
 
        SYSCALL(ret = ioctl(pInfo->fd, EVIOCGRAB, (pointer)1));
198
 
        if (ret < 0) {
199
 
            xf86IDrvMsg(pInfo, X_WARNING, "can't grab event device, errno=%d\n",
200
 
                        errno);
201
 
            return FALSE;
202
 
        }
 
192
        /* Try to grab the event device so that data don't leak to /dev/input/mice */
 
193
        int ret;
 
194
 
 
195
        SYSCALL(ret = ioctl(pInfo->fd, EVIOCGRAB, (pointer) 1));
 
196
        if (ret < 0) {
 
197
            xf86IDrvMsg(pInfo, X_WARNING, "can't grab event device, errno=%d\n",
 
198
                        errno);
 
199
            return FALSE;
 
200
        }
203
201
    }
204
202
 
205
203
    proto_data->need_grab = FALSE;
239
237
event_query_is_touchpad(int fd, BOOL test_grab)
240
238
{
241
239
    int ret = FALSE, rc;
242
 
    unsigned long evbits[NBITS(EV_MAX)] = {0};
243
 
    unsigned long absbits[NBITS(ABS_MAX)] = {0};
244
 
    unsigned long keybits[NBITS(KEY_MAX)] = {0};
 
240
    unsigned long evbits[NBITS(EV_MAX)] = { 0 };
 
241
    unsigned long absbits[NBITS(ABS_MAX)] = { 0 };
 
242
    unsigned long keybits[NBITS(KEY_MAX)] = { 0 };
245
243
 
246
 
    if (test_grab)
247
 
    {
248
 
        SYSCALL(rc = ioctl(fd, EVIOCGRAB, (pointer)1));
 
244
    if (test_grab) {
 
245
        SYSCALL(rc = ioctl(fd, EVIOCGRAB, (pointer) 1));
249
246
        if (rc < 0)
250
247
            return FALSE;
251
248
    }
254
251
 
255
252
    SYSCALL(rc = ioctl(fd, EVIOCGBIT(0, sizeof(evbits)), evbits));
256
253
    if (rc < 0)
257
 
        goto unwind;
 
254
        goto unwind;
258
255
    if (!TEST_BIT(EV_SYN, evbits) ||
259
 
        !TEST_BIT(EV_ABS, evbits) ||
260
 
        !TEST_BIT(EV_KEY, evbits))
261
 
        goto unwind;
 
256
        !TEST_BIT(EV_ABS, evbits) || !TEST_BIT(EV_KEY, evbits))
 
257
        goto unwind;
262
258
 
263
259
    SYSCALL(rc = ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absbits)), absbits));
264
260
    if (rc < 0)
265
 
        goto unwind;
266
 
    if (!TEST_BIT(ABS_X, absbits) ||
267
 
        !TEST_BIT(ABS_Y, absbits))
268
 
        goto unwind;
 
261
        goto unwind;
 
262
    if (!TEST_BIT(ABS_X, absbits) || !TEST_BIT(ABS_Y, absbits))
 
263
        goto unwind;
269
264
 
270
265
    SYSCALL(rc = ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybits)), keybits));
271
266
    if (rc < 0)
272
 
        goto unwind;
 
267
        goto unwind;
273
268
 
274
269
    /* we expect touchpad either report raw pressure or touches */
275
270
    if (!TEST_BIT(ABS_PRESSURE, absbits) && !TEST_BIT(BTN_TOUCH, keybits))
276
 
        goto unwind;
 
271
        goto unwind;
277
272
    /* all Synaptics-like touchpad report BTN_TOOL_FINGER */
278
273
    if (!TEST_BIT(BTN_TOOL_FINGER, keybits))
279
 
        goto unwind;
 
274
        goto unwind;
280
275
    if (TEST_BIT(BTN_TOOL_PEN, keybits))
281
 
        goto unwind;                        /* Don't match wacom tablets */
 
276
        goto unwind;            /* Don't match wacom tablets */
282
277
 
283
278
    ret = TRUE;
284
279
 
285
 
unwind:
 
280
 unwind:
286
281
    if (test_grab)
287
 
        SYSCALL(ioctl(fd, EVIOCGRAB, (pointer)0));
 
282
        SYSCALL(ioctl(fd, EVIOCGRAB, (pointer) 0));
288
283
 
289
284
    return (ret == TRUE);
290
285
}
291
286
 
292
287
typedef struct {
293
 
        short vendor;
294
 
        short product;
295
 
        enum TouchpadModel model;
 
288
    short vendor;
 
289
    short product;
 
290
    enum TouchpadModel model;
296
291
} model_lookup_t;
 
292
 
297
293
#define PRODUCT_ANY 0x0000
298
294
 
299
295
static model_lookup_t model_lookup_table[] = {
300
 
        {0x0002, 0x0007, MODEL_SYNAPTICS},
301
 
        {0x0002, 0x0008, MODEL_ALPS},
302
 
        {0x05ac, PRODUCT_ANY, MODEL_APPLETOUCH},
303
 
        {0x0002, 0x000e, MODEL_ELANTECH},
304
 
        {0x0, 0x0, 0x0}
 
296
    {0x0002, 0x0007, MODEL_SYNAPTICS},
 
297
    {0x0002, 0x0008, MODEL_ALPS},
 
298
    {0x05ac, PRODUCT_ANY, MODEL_APPLETOUCH},
 
299
    {0x0002, 0x000e, MODEL_ELANTECH},
 
300
    {0x0, 0x0, 0x0}
305
301
};
306
302
 
307
303
/**
315
311
 * @return TRUE on success or FALSE otherwise.
316
312
 */
317
313
static Bool
318
 
event_query_model(int fd, enum TouchpadModel *model_out, unsigned short *vendor_id, unsigned short *product_id)
 
314
event_query_model(int fd, enum TouchpadModel *model_out,
 
315
                  unsigned short *vendor_id, unsigned short *product_id)
319
316
{
320
317
    struct input_id id;
321
318
    int rc;
325
322
    if (rc < 0)
326
323
        return FALSE;
327
324
 
328
 
    for(model_lookup = model_lookup_table; model_lookup->vendor; model_lookup++) {
329
 
        if(model_lookup->vendor == id.vendor &&
330
 
           (model_lookup->product == id.product|| model_lookup->product == PRODUCT_ANY))
 
325
    for (model_lookup = model_lookup_table; model_lookup->vendor;
 
326
         model_lookup++) {
 
327
        if (model_lookup->vendor == id.vendor &&
 
328
            (model_lookup->product == id.product ||
 
329
             model_lookup->product == PRODUCT_ANY))
331
330
            *model_out = model_lookup->model;
332
331
    }
333
332
 
356
355
              int *min, int *max, int *fuzz, int *res)
357
356
{
358
357
    int rc;
359
 
    struct input_absinfo abs =  {0};
 
358
    struct input_absinfo abs = { 0 };
360
359
 
361
360
    SYSCALL(rc = ioctl(fd, EVIOCGABS(code), &abs));
362
361
    if (rc < 0) {
363
 
        xf86IDrvMsg(pInfo, X_ERROR, "%s EVIOCGABS error on %d (%s)\n",
364
 
                    __func__, code, strerror(errno));
365
 
        return errno;
 
362
        xf86IDrvMsg(pInfo, X_ERROR, "%s EVIOCGABS error on %d (%s)\n",
 
363
                    __func__, code, strerror(errno));
 
364
        return errno;
366
365
    }
367
366
 
368
367
    *min = abs.minimum;
369
368
    *max = abs.maximum;
370
369
    /* We dont trust a zero fuzz as it probably is just a lazy value */
371
370
    if (fuzz && abs.fuzz > 0)
372
 
        *fuzz = abs.fuzz;
 
371
        *fuzz = abs.fuzz;
373
372
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,30)
374
373
    if (res)
375
 
        *res = abs.resolution;
 
374
        *res = abs.resolution;
376
375
#endif
377
376
 
378
377
    return 0;
379
378
}
380
379
 
381
 
 
382
380
/* Query device for axis ranges */
383
381
static void
384
382
event_query_axis_ranges(InputInfoPtr pInfo)
385
383
{
386
 
    SynapticsPrivate *priv = (SynapticsPrivate *)pInfo->private;
 
384
    SynapticsPrivate *priv = (SynapticsPrivate *) pInfo->private;
387
385
    struct eventcomm_proto_data *proto_data = priv->proto_data;
388
 
    unsigned long absbits[NBITS(ABS_MAX)] = {0};
389
 
    unsigned long keybits[NBITS(KEY_MAX)] = {0};
390
 
    char buf[256] = {0};
 
386
    unsigned long absbits[NBITS(ABS_MAX)] = { 0 };
 
387
    unsigned long keybits[NBITS(KEY_MAX)] = { 0 };
 
388
    char buf[256] = { 0 };
391
389
    int rc;
392
390
 
393
391
    /* The kernel's fuzziness concept seems a bit weird, but it can more or
394
392
     * less be applied as hysteresis directly, i.e. no factor here. */
395
393
    event_get_abs(pInfo, pInfo->fd, ABS_X, &priv->minx, &priv->maxx,
396
 
                  &priv->synpara.hyst_x, &priv->resx);
 
394
                  &priv->synpara.hyst_x, &priv->resx);
397
395
 
398
396
    event_get_abs(pInfo, pInfo->fd, ABS_Y, &priv->miny, &priv->maxy,
399
 
                  &priv->synpara.hyst_y, &priv->resy);
 
397
                  &priv->synpara.hyst_y, &priv->resy);
400
398
 
401
399
    priv->has_pressure = FALSE;
402
400
    priv->has_width = FALSE;
403
401
    SYSCALL(rc = ioctl(pInfo->fd, EVIOCGBIT(EV_ABS, sizeof(absbits)), absbits));
404
 
    if (rc >= 0)
405
 
    {
406
 
        priv->has_pressure = (TEST_BIT(ABS_PRESSURE, absbits) != 0);
407
 
        priv->has_width = (TEST_BIT(ABS_TOOL_WIDTH, absbits) != 0);
 
402
    if (rc >= 0) {
 
403
        priv->has_pressure = (TEST_BIT(ABS_PRESSURE, absbits) != 0);
 
404
        priv->has_width = (TEST_BIT(ABS_TOOL_WIDTH, absbits) != 0);
408
405
    }
409
406
    else
410
 
        xf86IDrvMsg(pInfo, X_ERROR, "failed to query ABS bits (%s)\n", strerror(errno));
 
407
        xf86IDrvMsg(pInfo, X_ERROR, "failed to query ABS bits (%s)\n",
 
408
                    strerror(errno));
411
409
 
412
410
    if (priv->has_pressure)
413
 
        event_get_abs(pInfo, pInfo->fd, ABS_PRESSURE, &priv->minp, &priv->maxp,
414
 
                      NULL, NULL);
 
411
        event_get_abs(pInfo, pInfo->fd, ABS_PRESSURE, &priv->minp, &priv->maxp,
 
412
                      NULL, NULL);
415
413
 
416
414
    if (priv->has_width)
417
 
        event_get_abs(pInfo, pInfo->fd, ABS_TOOL_WIDTH,
418
 
                      &priv->minw, &priv->maxw,
419
 
                      NULL, NULL);
 
415
        event_get_abs(pInfo, pInfo->fd, ABS_TOOL_WIDTH,
 
416
                      &priv->minw, &priv->maxw, NULL, NULL);
420
417
 
421
418
#if HAVE_MULTITOUCH
422
 
    if (priv->has_touch)
423
 
    {
 
419
    if (priv->has_touch) {
424
420
        int st_minx = priv->minx;
425
421
        int st_maxx = priv->maxx;
426
422
        int st_miny = priv->miny;
441
437
#endif
442
438
 
443
439
    SYSCALL(rc = ioctl(pInfo->fd, EVIOCGBIT(EV_KEY, sizeof(keybits)), keybits));
444
 
    if (rc >= 0)
445
 
    {
446
 
        priv->has_left = (TEST_BIT(BTN_LEFT, keybits) != 0);
447
 
        priv->has_right = (TEST_BIT(BTN_RIGHT, keybits) != 0);
448
 
        priv->has_middle = (TEST_BIT(BTN_MIDDLE, keybits) != 0);
449
 
        priv->has_double = (TEST_BIT(BTN_TOOL_DOUBLETAP, keybits) != 0);
450
 
        priv->has_triple = (TEST_BIT(BTN_TOOL_TRIPLETAP, keybits) != 0);
 
440
    if (rc >= 0) {
 
441
        priv->has_left = (TEST_BIT(BTN_LEFT, keybits) != 0);
 
442
        priv->has_right = (TEST_BIT(BTN_RIGHT, keybits) != 0);
 
443
        priv->has_middle = (TEST_BIT(BTN_MIDDLE, keybits) != 0);
 
444
        priv->has_double = (TEST_BIT(BTN_TOOL_DOUBLETAP, keybits) != 0);
 
445
        priv->has_triple = (TEST_BIT(BTN_TOOL_TRIPLETAP, keybits) != 0);
451
446
 
452
 
        if ((TEST_BIT(BTN_0, keybits) != 0) ||
453
 
            (TEST_BIT(BTN_1, keybits) != 0) ||
454
 
            (TEST_BIT(BTN_2, keybits) != 0) ||
455
 
            (TEST_BIT(BTN_3, keybits) != 0))
456
 
            priv->has_scrollbuttons = 1;
 
447
        if ((TEST_BIT(BTN_0, keybits) != 0) ||
 
448
            (TEST_BIT(BTN_1, keybits) != 0) ||
 
449
            (TEST_BIT(BTN_2, keybits) != 0) || (TEST_BIT(BTN_3, keybits) != 0))
 
450
            priv->has_scrollbuttons = 1;
457
451
    }
458
452
 
459
453
    /* Now print the device information */
460
454
    xf86IDrvMsg(pInfo, X_PROBED, "x-axis range %d - %d\n",
461
 
                priv->minx, priv->maxx);
 
455
                priv->minx, priv->maxx);
462
456
    xf86IDrvMsg(pInfo, X_PROBED, "y-axis range %d - %d\n",
463
 
                priv->miny, priv->maxy);
 
457
                priv->miny, priv->maxy);
464
458
    if (priv->has_pressure)
465
 
        xf86IDrvMsg(pInfo, X_PROBED, "pressure range %d - %d\n",
466
 
                    priv->minp, priv->maxp);
 
459
        xf86IDrvMsg(pInfo, X_PROBED, "pressure range %d - %d\n",
 
460
                    priv->minp, priv->maxp);
467
461
    else
468
 
        xf86IDrvMsg(pInfo, X_INFO,
469
 
                    "device does not report pressure, will use touch data.\n");
 
462
        xf86IDrvMsg(pInfo, X_INFO,
 
463
                    "device does not report pressure, will use touch data.\n");
470
464
    if (priv->has_width)
471
 
        xf86IDrvMsg(pInfo, X_PROBED, "finger width range %d - %d\n",
472
 
                    priv->minw, priv->maxw);
 
465
        xf86IDrvMsg(pInfo, X_PROBED, "finger width range %d - %d\n",
 
466
                    priv->minw, priv->maxw);
473
467
    else
474
 
        xf86IDrvMsg(pInfo, X_INFO,
475
 
                    "device does not report finger width.\n");
 
468
        xf86IDrvMsg(pInfo, X_INFO, "device does not report finger width.\n");
476
469
 
477
470
    if (priv->has_left)
478
 
        strcat(buf, " left");
 
471
        strcat(buf, " left");
479
472
    if (priv->has_right)
480
 
        strcat(buf, " right");
 
473
        strcat(buf, " right");
481
474
    if (priv->has_middle)
482
 
        strcat(buf, " middle");
 
475
        strcat(buf, " middle");
483
476
    if (priv->has_double)
484
 
        strcat(buf, " double");
 
477
        strcat(buf, " double");
485
478
    if (priv->has_triple)
486
 
        strcat(buf, " triple");
 
479
        strcat(buf, " triple");
487
480
    if (priv->has_scrollbuttons)
488
 
        strcat(buf, " scroll-buttons");
 
481
        strcat(buf, " scroll-buttons");
489
482
 
490
483
    xf86IDrvMsg(pInfo, X_PROBED, "buttons:%s\n", buf);
491
484
}
493
486
static Bool
494
487
EventQueryHardware(InputInfoPtr pInfo)
495
488
{
496
 
    SynapticsPrivate *priv = (SynapticsPrivate *)pInfo->private;
 
489
    SynapticsPrivate *priv = (SynapticsPrivate *) pInfo->private;
497
490
    struct eventcomm_proto_data *proto_data = priv->proto_data;
498
491
 
499
 
    if (!event_query_is_touchpad(pInfo->fd, (proto_data) ? proto_data->need_grab : TRUE))
500
 
        return FALSE;
 
492
    if (!event_query_is_touchpad
 
493
        (pInfo->fd, (proto_data) ? proto_data->need_grab : TRUE))
 
494
        return FALSE;
501
495
 
502
496
    xf86IDrvMsg(pInfo, X_PROBED, "touchpad found\n");
503
497
 
508
502
SynapticsReadEvent(InputInfoPtr pInfo, struct input_event *ev)
509
503
{
510
504
#ifdef HAVE_MULTITOUCH
511
 
    SynapticsPrivate *priv = (SynapticsPrivate *)pInfo->private;
 
505
    SynapticsPrivate *priv = (SynapticsPrivate *) pInfo->private;
512
506
    struct eventcomm_proto_data *proto_data = priv->proto_data;
513
507
#endif
514
508
    int rc = TRUE;
517
511
#ifdef HAVE_MULTITOUCH
518
512
    if (proto_data->mtdev)
519
513
        len = mtdev_get(proto_data->mtdev, pInfo->fd, ev, 1) *
520
 
              sizeof(struct input_event);
 
514
            sizeof(struct input_event);
521
515
    else
522
516
#endif
523
517
        len = read(pInfo->fd, ev, sizeof(*ev));
524
 
    if (len <= 0)
525
 
    {
 
518
    if (len <= 0) {
526
519
        /* We use X_NONE here because it doesn't alloc */
527
520
        if (errno != EAGAIN)
528
 
            xf86MsgVerb(X_NONE, 0, "%s: Read error %s\n", pInfo->name, strerror(errno));
 
521
            xf86MsgVerb(X_NONE, 0, "%s: Read error %s\n", pInfo->name,
 
522
                        strerror(errno));
529
523
        rc = FALSE;
530
 
    } else if (len % sizeof(*ev)) {
531
 
        xf86MsgVerb(X_NONE, 0, "%s: Read error, invalid number of bytes.", pInfo->name);
 
524
    }
 
525
    else if (len % sizeof(*ev)) {
 
526
        xf86MsgVerb(X_NONE, 0, "%s: Read error, invalid number of bytes.",
 
527
                    pInfo->name);
532
528
        rc = FALSE;
533
529
    }
534
530
    return rc;
536
532
 
537
533
#ifdef HAVE_MULTITOUCH
538
534
static Bool
539
 
EventTouchSlotPreviouslyOpen(SynapticsPrivate *priv, int slot)
 
535
EventTouchSlotPreviouslyOpen(SynapticsPrivate * priv, int slot)
540
536
{
541
537
    int i;
542
538
 
553
549
                       struct input_event *ev)
554
550
{
555
551
#ifdef HAVE_MULTITOUCH
556
 
    SynapticsPrivate *priv = (SynapticsPrivate *)pInfo->private;
 
552
    SynapticsPrivate *priv = (SynapticsPrivate *) pInfo->private;
557
553
    struct eventcomm_proto_data *proto_data = priv->proto_data;
558
554
 
559
555
    if (!priv->has_touch)
560
556
        return;
561
557
 
562
 
    if (ev->code == ABS_MT_SLOT)
563
 
    {
 
558
    if (ev->code == ABS_MT_SLOT) {
564
559
        proto_data->cur_slot = ev->value;
565
 
    } else
566
 
    {
 
560
    }
 
561
    else {
567
562
        int slot_index = last_mt_vals_slot(priv);
568
563
 
569
564
        if (slot_index < 0)
572
567
        if (hw->slot_state[slot_index] == SLOTSTATE_EMPTY ||
573
568
            hw->slot_state[slot_index] == SLOTSTATE_OPEN_EMPTY)
574
569
            hw->slot_state[slot_index] = SLOTSTATE_UPDATE;
575
 
        if (ev->code == ABS_MT_TRACKING_ID)
576
 
        {
577
 
            if (ev->value >= 0)
578
 
            {
 
570
        if (ev->code == ABS_MT_TRACKING_ID) {
 
571
            if (ev->value >= 0) {
579
572
                hw->slot_state[slot_index] = SLOTSTATE_OPEN;
580
573
                proto_data->num_touches++;
581
574
 
586
579
                    xf86IDrvMsg(pInfo, X_WARNING,
587
580
                                "Attempted to copy values from out-of-range "
588
581
                                "slot, touch events may be incorrect.\n");
589
 
            } else
590
 
            {
 
582
            }
 
583
            else {
591
584
                hw->slot_state[slot_index] = SLOTSTATE_CLOSE;
592
585
                proto_data->num_touches--;
593
586
            }
594
 
        } else
595
 
        {
 
587
        }
 
588
        else {
596
589
            int map = proto_data->axis_map[ev->code - ABS_MT_TOUCH_MAJOR];
 
590
 
597
591
            valuator_mask_set(hw->mt_mask[slot_index], map, ev->value);
598
 
            if (slot_index >= 0)
599
 
            {
 
592
            if (slot_index >= 0) {
600
593
                ValuatorMask *mask = proto_data->last_mt_vals[slot_index];
601
594
                int last_val = valuator_mask_get(mask, map);
602
595
 
603
 
                if (EventTouchSlotPreviouslyOpen(priv, slot_index))
604
 
                {
 
596
                if (EventTouchSlotPreviouslyOpen(priv, slot_index)) {
605
597
                    if (ev->code == ABS_MT_POSITION_X)
606
598
                        hw->cumulative_dx += ev->value - last_val;
607
599
                    else if (ev->code == ABS_MT_POSITION_Y)
623
615
 * @param comm Assembled information from previous events.
624
616
 * @return The number of fingers currently set.
625
617
 */
626
 
static int count_fingers(InputInfoPtr pInfo, const struct CommData *comm)
 
618
static int
 
619
count_fingers(InputInfoPtr pInfo, const struct CommData *comm)
627
620
{
628
 
    SynapticsPrivate *priv = (SynapticsPrivate *)pInfo->private;
 
621
    SynapticsPrivate *priv = (SynapticsPrivate *) pInfo->private;
629
622
    struct eventcomm_proto_data *proto_data = priv->proto_data;
630
623
    int fingers = 0;
631
624
 
632
625
    if (comm->oneFinger)
633
 
        fingers = 1;
 
626
        fingers = 1;
634
627
    else if (comm->twoFingers)
635
 
        fingers = 2;
 
628
        fingers = 2;
636
629
    else if (comm->threeFingers)
637
 
        fingers = 3;
 
630
        fingers = 3;
638
631
 
639
632
#ifdef HAVE_MULTITOUCH
640
633
    if (priv->has_touch && proto_data->num_touches > fingers)
644
637
    return fingers;
645
638
}
646
639
 
647
 
 
648
640
static inline double
649
641
apply_st_scaling(struct eventcomm_proto_data *proto_data, int value, int axis)
650
642
{
651
 
    return value * proto_data->st_to_mt_scale[axis] + proto_data->st_to_mt_offset[axis];
 
643
    return value * proto_data->st_to_mt_scale[axis] +
 
644
        proto_data->st_to_mt_offset[axis];
652
645
}
653
646
 
654
647
Bool
655
648
EventReadHwState(InputInfoPtr pInfo,
656
 
                 struct CommData *comm, struct SynapticsHwState *hwRet)
 
649
                 struct CommData *comm, struct SynapticsHwState *hwRet)
657
650
{
658
651
    struct input_event ev;
659
652
    Bool v;
660
653
    struct SynapticsHwState *hw = comm->hwState;
661
 
    SynapticsPrivate *priv = (SynapticsPrivate *)pInfo->private;
 
654
    SynapticsPrivate *priv = (SynapticsPrivate *) pInfo->private;
662
655
    SynapticsParameters *para = &priv->synpara;
663
656
    struct eventcomm_proto_data *proto_data = priv->proto_data;
664
657
 
665
658
    SynapticsResetTouchHwState(hw, FALSE);
666
659
 
667
660
    /* Reset cumulative values if buttons were not previously pressed */
668
 
    if (!hw->left && !hw->right && !hw->middle)
669
 
    {
 
661
    if (!hw->left && !hw->right && !hw->middle) {
670
662
        hw->cumulative_dx = hw->x;
671
663
        hw->cumulative_dy = hw->y;
672
664
    }
673
665
 
674
666
    while (SynapticsReadEvent(pInfo, &ev)) {
675
 
        switch (ev.type) {
676
 
        case EV_SYN:
677
 
            switch (ev.code) {
678
 
            case SYN_REPORT:
679
 
                hw->numFingers = count_fingers(pInfo, comm);
680
 
                hw->millis = 1000 * ev.time.tv_sec + ev.time.tv_usec / 1000;
681
 
                SynapticsCopyHwState(hwRet, hw);
682
 
                return TRUE;
683
 
            }
684
 
            break;
685
 
        case EV_KEY:
686
 
            v = (ev.value ? TRUE : FALSE);
687
 
            switch (ev.code) {
688
 
            case BTN_LEFT:
689
 
                hw->left = v;
690
 
                break;
691
 
            case BTN_RIGHT:
692
 
                hw->right = v;
693
 
                break;
694
 
            case BTN_MIDDLE:
695
 
                hw->middle = v;
696
 
                break;
697
 
            case BTN_FORWARD:
698
 
                hw->up = v;
699
 
                break;
700
 
            case BTN_BACK:
701
 
                hw->down = v;
702
 
                break;
703
 
            case BTN_0:
704
 
                hw->multi[0] = v;
705
 
                break;
706
 
            case BTN_1:
707
 
                hw->multi[1] = v;
708
 
                break;
709
 
            case BTN_2:
710
 
                hw->multi[2] = v;
711
 
                break;
712
 
            case BTN_3:
713
 
                hw->multi[3] = v;
714
 
                break;
715
 
            case BTN_4:
716
 
                hw->multi[4] = v;
717
 
                break;
718
 
            case BTN_5:
719
 
                hw->multi[5] = v;
720
 
                break;
721
 
            case BTN_6:
722
 
                hw->multi[6] = v;
723
 
                break;
724
 
            case BTN_7:
725
 
                hw->multi[7] = v;
726
 
                break;
727
 
            case BTN_TOOL_FINGER:
728
 
                comm->oneFinger = v;
729
 
                break;
730
 
            case BTN_TOOL_DOUBLETAP:
731
 
                comm->twoFingers = v;
732
 
                break;
733
 
            case BTN_TOOL_TRIPLETAP:
734
 
                comm->threeFingers = v;
735
 
                break;
736
 
            case BTN_TOUCH:
737
 
                if (!priv->has_pressure)
738
 
                        hw->z = v ? para->finger_high + 1 : 0;
739
 
                break;
740
 
            }
741
 
            break;
742
 
        case EV_ABS:
743
 
            if (ev.code < ABS_MT_SLOT) {
744
 
                switch (ev.code) {
745
 
                case ABS_X:
746
 
                    hw->x = apply_st_scaling(proto_data, ev.value, 0);
747
 
                    break;
748
 
                case ABS_Y:
749
 
                    hw->y = apply_st_scaling(proto_data, ev.value, 1);
750
 
                    break;
751
 
                case ABS_PRESSURE:
752
 
                    hw->z = ev.value;
753
 
                    break;
754
 
                case ABS_TOOL_WIDTH:
755
 
                    hw->fingerWidth = ev.value;
756
 
                    break;
757
 
                }
758
 
            } else
759
 
                EventProcessTouchEvent(pInfo, hw, &ev);
760
 
            break;
761
 
        }
 
667
        switch (ev.type) {
 
668
        case EV_SYN:
 
669
            switch (ev.code) {
 
670
            case SYN_REPORT:
 
671
                hw->numFingers = count_fingers(pInfo, comm);
 
672
                hw->millis = 1000 * ev.time.tv_sec + ev.time.tv_usec / 1000;
 
673
                SynapticsCopyHwState(hwRet, hw);
 
674
                return TRUE;
 
675
            }
 
676
            break;
 
677
        case EV_KEY:
 
678
            v = (ev.value ? TRUE : FALSE);
 
679
            switch (ev.code) {
 
680
            case BTN_LEFT:
 
681
                hw->left = v;
 
682
                break;
 
683
            case BTN_RIGHT:
 
684
                hw->right = v;
 
685
                break;
 
686
            case BTN_MIDDLE:
 
687
                hw->middle = v;
 
688
                break;
 
689
            case BTN_FORWARD:
 
690
                hw->up = v;
 
691
                break;
 
692
            case BTN_BACK:
 
693
                hw->down = v;
 
694
                break;
 
695
            case BTN_0:
 
696
                hw->multi[0] = v;
 
697
                break;
 
698
            case BTN_1:
 
699
                hw->multi[1] = v;
 
700
                break;
 
701
            case BTN_2:
 
702
                hw->multi[2] = v;
 
703
                break;
 
704
            case BTN_3:
 
705
                hw->multi[3] = v;
 
706
                break;
 
707
            case BTN_4:
 
708
                hw->multi[4] = v;
 
709
                break;
 
710
            case BTN_5:
 
711
                hw->multi[5] = v;
 
712
                break;
 
713
            case BTN_6:
 
714
                hw->multi[6] = v;
 
715
                break;
 
716
            case BTN_7:
 
717
                hw->multi[7] = v;
 
718
                break;
 
719
            case BTN_TOOL_FINGER:
 
720
                comm->oneFinger = v;
 
721
                break;
 
722
            case BTN_TOOL_DOUBLETAP:
 
723
                comm->twoFingers = v;
 
724
                break;
 
725
            case BTN_TOOL_TRIPLETAP:
 
726
                comm->threeFingers = v;
 
727
                break;
 
728
            case BTN_TOUCH:
 
729
                if (!priv->has_pressure)
 
730
                    hw->z = v ? para->finger_high + 1 : 0;
 
731
                break;
 
732
            }
 
733
            break;
 
734
        case EV_ABS:
 
735
            if (ev.code < ABS_MT_SLOT) {
 
736
                switch (ev.code) {
 
737
                case ABS_X:
 
738
                    hw->x = apply_st_scaling(proto_data, ev.value, 0);
 
739
                    break;
 
740
                case ABS_Y:
 
741
                    hw->y = apply_st_scaling(proto_data, ev.value, 1);
 
742
                    break;
 
743
                case ABS_PRESSURE:
 
744
                    hw->z = ev.value;
 
745
                    break;
 
746
                case ABS_TOOL_WIDTH:
 
747
                    hw->fingerWidth = ev.value;
 
748
                    break;
 
749
                }
 
750
            }
 
751
            else
 
752
                EventProcessTouchEvent(pInfo, hw, &ev);
 
753
            break;
 
754
        }
762
755
    }
763
756
    return FALSE;
764
757
}
765
758
 
766
759
/* filter for the AutoDevProbe scandir on /dev/input */
767
 
static int EventDevOnly(const struct dirent *dir) {
768
 
        return strncmp(EVENT_DEV_NAME, dir->d_name, 5) == 0;
 
760
static int
 
761
EventDevOnly(const struct dirent *dir)
 
762
{
 
763
    return strncmp(EVENT_DEV_NAME, dir->d_name, 5) == 0;
769
764
}
770
765
 
771
766
#ifdef HAVE_MULTITOUCH
772
767
static void
773
768
event_query_touch(InputInfoPtr pInfo)
774
769
{
775
 
    SynapticsPrivate *priv = (SynapticsPrivate *)pInfo->private;
 
770
    SynapticsPrivate *priv = (SynapticsPrivate *) pInfo->private;
776
771
    SynapticsParameters *para = &priv->synpara;
777
772
    struct eventcomm_proto_data *proto_data = priv->proto_data;
778
773
    struct mtdev *mtdev;
785
780
 
786
781
#ifdef EVIOCGPROP
787
782
    SYSCALL(rc = ioctl(pInfo->fd, EVIOCGPROP(sizeof(prop)), &prop));
788
 
    if (rc >= 0 && BitIsOn(&prop, INPUT_PROP_SEMI_MT))
789
 
    {
 
783
    if (rc >= 0 && BitIsOn(&prop, INPUT_PROP_SEMI_MT)) {
790
784
        xf86IDrvMsg(pInfo, X_INFO,
791
785
                    "ignoring touch events for semi-multitouch device\n");
792
786
        priv->has_semi_mt = TRUE;
793
787
    }
794
788
 
795
 
    if (rc >= 0 && BitIsOn(&prop, INPUT_PROP_BUTTONPAD))
796
 
    {
 
789
    if (rc >= 0 && BitIsOn(&prop, INPUT_PROP_BUTTONPAD)) {
797
790
        xf86IDrvMsg(pInfo, X_INFO, "found clickpad property\n");
798
791
        para->clickpad = TRUE;
799
792
    }
800
793
#endif
801
794
 
802
795
    mtdev = mtdev_new_open(pInfo->fd);
803
 
    if (!mtdev)
804
 
    {
 
796
    if (!mtdev) {
805
797
        xf86IDrvMsg(pInfo, X_WARNING,
806
798
                    "failed to open mtdev when querying touch capabilities\n");
807
799
        return;
808
800
    }
809
801
 
810
 
    for (i = 0; i < MT_ABS_SIZE; i++)
811
 
    {
812
 
        if (mtdev->caps.has_abs[i])
813
 
        {
814
 
            switch (i)
815
 
            {
 
802
    for (i = 0; i < MT_ABS_SIZE; i++) {
 
803
        if (mtdev->caps.has_abs[i]) {
 
804
            switch (i) {
816
805
                /* X and Y axis info is handed by synaptics already */
817
 
                case ABS_MT_POSITION_X - ABS_MT_TOUCH_MAJOR:
818
 
                case ABS_MT_POSITION_Y - ABS_MT_TOUCH_MAJOR:
 
806
            case ABS_MT_POSITION_X - ABS_MT_TOUCH_MAJOR:
 
807
            case ABS_MT_POSITION_Y - ABS_MT_TOUCH_MAJOR:
819
808
                /* Skip tracking ID info */
820
 
                case ABS_MT_TRACKING_ID - ABS_MT_TOUCH_MAJOR:
821
 
                    break;
822
 
                default:
823
 
                    priv->num_mt_axes++;
824
 
                    break;
 
809
            case ABS_MT_TRACKING_ID - ABS_MT_TOUCH_MAJOR:
 
810
                break;
 
811
            default:
 
812
                priv->num_mt_axes++;
 
813
                break;
825
814
            }
826
815
            priv->has_touch = TRUE;
827
816
        }
828
817
    }
829
818
 
830
 
    if (priv->has_touch)
831
 
    {
 
819
    if (priv->has_touch) {
832
820
        int axnum;
833
 
        static const char *labels[] =
834
 
        {
 
821
 
 
822
        static const char *labels[] = {
835
823
            AXIS_LABEL_PROP_ABS_MT_TOUCH_MAJOR,
836
824
            AXIS_LABEL_PROP_ABS_MT_TOUCH_MINOR,
837
825
            AXIS_LABEL_PROP_ABS_MT_WIDTH_MAJOR,
847
835
 
848
836
        if (mtdev->caps.slot.maximum > 0)
849
837
            priv->max_touches = mtdev->caps.slot.maximum -
850
 
                                mtdev->caps.slot.minimum + 1;
 
838
                mtdev->caps.slot.minimum + 1;
851
839
 
852
840
        priv->touch_axes = malloc(priv->num_mt_axes *
853
841
                                  sizeof(SynapticsTouchAxisRec));
854
 
        if (!priv->touch_axes)
855
 
        {
 
842
        if (!priv->touch_axes) {
856
843
            priv->has_touch = FALSE;
857
844
            goto out;
858
845
        }
859
846
 
860
847
        axnum = 0;
861
 
        for (i = 0; i < MT_ABS_SIZE; i++)
862
 
        {
863
 
            if (mtdev->caps.has_abs[i])
864
 
            {
865
 
                switch (i)
866
 
                {
 
848
        for (i = 0; i < MT_ABS_SIZE; i++) {
 
849
            if (mtdev->caps.has_abs[i]) {
 
850
                switch (i) {
867
851
                    /* X and Y axis info is handed by synaptics already, we just
868
852
                     * need to map the evdev codes to the valuator numbers */
869
 
                    case ABS_MT_POSITION_X - ABS_MT_TOUCH_MAJOR:
870
 
                        proto_data->axis_map[i] = 0;
871
 
                        break;
 
853
                case ABS_MT_POSITION_X - ABS_MT_TOUCH_MAJOR:
 
854
                    proto_data->axis_map[i] = 0;
 
855
                    break;
872
856
 
873
 
                    case ABS_MT_POSITION_Y - ABS_MT_TOUCH_MAJOR:
874
 
                        proto_data->axis_map[i] = 1;
875
 
                        break;
 
857
                case ABS_MT_POSITION_Y - ABS_MT_TOUCH_MAJOR:
 
858
                    proto_data->axis_map[i] = 1;
 
859
                    break;
876
860
 
877
861
                    /* Skip tracking ID info */
878
 
                    case ABS_MT_TRACKING_ID - ABS_MT_TOUCH_MAJOR:
879
 
                        break;
 
862
                case ABS_MT_TRACKING_ID - ABS_MT_TOUCH_MAJOR:
 
863
                    break;
880
864
 
881
 
                    default:
882
 
                        priv->touch_axes[axnum].label = labels[i];
883
 
                        priv->touch_axes[axnum].min =
884
 
                            mtdev->caps.abs[i].minimum;
885
 
                        priv->touch_axes[axnum].max =
886
 
                            mtdev->caps.abs[i].maximum;
887
 
                        /* Kernel provides units/mm, X wants units/m */
888
 
                        priv->touch_axes[axnum].res =
889
 
                            mtdev->caps.abs[i].resolution * 1000;
890
 
                        /* Valuators 0-3 are used for X, Y, and scrolling */
891
 
                        proto_data->axis_map[i] = 4 + axnum;
892
 
                        axnum++;
893
 
                        break;
 
865
                default:
 
866
                    priv->touch_axes[axnum].label = labels[i];
 
867
                    priv->touch_axes[axnum].min = mtdev->caps.abs[i].minimum;
 
868
                    priv->touch_axes[axnum].max = mtdev->caps.abs[i].maximum;
 
869
                    /* Kernel provides units/mm, X wants units/m */
 
870
                    priv->touch_axes[axnum].res =
 
871
                        mtdev->caps.abs[i].resolution * 1000;
 
872
                    /* Valuators 0-3 are used for X, Y, and scrolling */
 
873
                    proto_data->axis_map[i] = 4 + axnum;
 
874
                    axnum++;
 
875
                    break;
894
876
                }
895
877
            }
896
878
        }
897
879
    }
898
880
 
899
 
out:
 
881
 out:
900
882
    mtdev_close(mtdev);
901
883
}
902
884
#endif
907
889
static void
908
890
EventReadDevDimensions(InputInfoPtr pInfo)
909
891
{
910
 
    SynapticsPrivate *priv = (SynapticsPrivate *)pInfo->private;
 
892
    SynapticsPrivate *priv = (SynapticsPrivate *) pInfo->private;
911
893
    struct eventcomm_proto_data *proto_data = priv->proto_data;
 
894
 
912
895
#ifdef HAVE_MULTITOUCH
913
896
    int i;
914
897
#endif
922
905
    proto_data->cur_slot = -1;
923
906
#endif
924
907
 
925
 
    if (event_query_is_touchpad(pInfo->fd, (proto_data) ? proto_data->need_grab : TRUE))
926
 
    {
 
908
    if (event_query_is_touchpad
 
909
        (pInfo->fd, (proto_data) ? proto_data->need_grab : TRUE)) {
927
910
#ifdef HAVE_MULTITOUCH
928
911
        event_query_touch(pInfo);
929
912
#endif
930
913
        event_query_axis_ranges(pInfo);
931
914
    }
932
 
    event_query_model(pInfo->fd, &priv->model, &priv->id_vendor, &priv->id_product);
 
915
    event_query_model(pInfo->fd, &priv->model, &priv->id_vendor,
 
916
                      &priv->id_product);
933
917
 
934
918
    xf86IDrvMsg(pInfo, X_PROBED, "Vendor %#hx Product %#hx\n",
935
919
                priv->id_vendor, priv->id_product);
945
929
    struct dirent **namelist;
946
930
 
947
931
    if (device) {
948
 
        int fd = -1;
949
 
        SYSCALL(fd = open(device, O_RDONLY));
950
 
        if (fd >= 0)
951
 
        {
952
 
            touchpad_found = event_query_is_touchpad(fd, TRUE);
953
 
 
954
 
            SYSCALL(close(fd));
 
932
        int fd = -1;
 
933
 
 
934
        SYSCALL(fd = open(device, O_RDONLY));
 
935
        if (fd >= 0) {
 
936
            touchpad_found = event_query_is_touchpad(fd, TRUE);
 
937
 
 
938
            SYSCALL(close(fd));
955
939
            /* if a device is set and not a touchpad (or already grabbed),
956
940
             * we must return FALSE.  Otherwise, we'll add a device that
957
941
             * wasn't requested for and repeat
958
942
             * f5687a6741a19ef3081e7fd83ac55f6df8bcd5c2. */
959
 
            return touchpad_found;
960
 
        }
 
943
            return touchpad_found;
 
944
        }
961
945
    }
962
946
 
963
947
    i = scandir(DEV_INPUT_EVENT, &namelist, EventDevOnly, alphasort);
964
948
    if (i < 0) {
965
 
                xf86IDrvMsg(pInfo, X_ERROR, "Couldn't open %s\n", DEV_INPUT_EVENT);
966
 
                return FALSE;
 
949
        xf86IDrvMsg(pInfo, X_ERROR, "Couldn't open %s\n", DEV_INPUT_EVENT);
 
950
        return FALSE;
967
951
    }
968
952
    else if (i == 0) {
969
 
                xf86IDrvMsg(pInfo, X_ERROR, "The /dev/input/event* device nodes seem to be missing\n");
970
 
                free(namelist);
971
 
                return FALSE;
 
953
        xf86IDrvMsg(pInfo, X_ERROR,
 
954
                    "The /dev/input/event* device nodes seem to be missing\n");
 
955
        free(namelist);
 
956
        return FALSE;
972
957
    }
973
958
 
974
959
    while (i--) {
975
 
                char fname[64];
976
 
                int fd = -1;
977
 
 
978
 
                if (!touchpad_found) {
979
 
                        sprintf(fname, "%s/%s", DEV_INPUT_EVENT, namelist[i]->d_name);
980
 
                        SYSCALL(fd = open(fname, O_RDONLY));
981
 
                        if (fd < 0)
982
 
                                continue;
983
 
 
984
 
                        if (event_query_is_touchpad(fd, TRUE)) {
985
 
                                touchpad_found = TRUE;
986
 
                            xf86IDrvMsg(pInfo, X_PROBED, "auto-dev sets device to %s\n",
987
 
                                        fname);
988
 
                            pInfo->options =
989
 
                                xf86ReplaceStrOption(pInfo->options, "Device", fname);
990
 
                        }
991
 
                        SYSCALL(close(fd));
992
 
                }
993
 
                free(namelist[i]);
 
960
        char fname[64];
 
961
        int fd = -1;
 
962
 
 
963
        if (!touchpad_found) {
 
964
            sprintf(fname, "%s/%s", DEV_INPUT_EVENT, namelist[i]->d_name);
 
965
            SYSCALL(fd = open(fname, O_RDONLY));
 
966
            if (fd < 0)
 
967
                continue;
 
968
 
 
969
            if (event_query_is_touchpad(fd, TRUE)) {
 
970
                touchpad_found = TRUE;
 
971
                xf86IDrvMsg(pInfo, X_PROBED, "auto-dev sets device to %s\n",
 
972
                            fname);
 
973
                pInfo->options =
 
974
                    xf86ReplaceStrOption(pInfo->options, "Device", fname);
 
975
            }
 
976
            SYSCALL(close(fd));
 
977
        }
 
978
        free(namelist[i]);
994
979
    }
995
980
 
996
981
    free(namelist);
997
982
 
998
983
    if (!touchpad_found) {
999
 
        xf86IDrvMsg(pInfo, X_ERROR, "no synaptics event device found\n");
1000
 
        return FALSE;
 
984
        xf86IDrvMsg(pInfo, X_ERROR, "no synaptics event device found\n");
 
985
        return FALSE;
1001
986
    }
1002
987
 
1003
988
    return TRUE;