~ubuntu-branches/debian/wheezy/libwacom/wheezy

« back to all changes in this revision

Viewing changes to .pc/git_touchpad_tablet.patch/libwacom/libwacom.c

  • Committer: Package Import Robot
  • Author(s): Timo Aaltonen
  • Date: 2012-03-30 11:28:44 UTC
  • mfrom: (1.1.1)
  • Revision ID: package-import@ubuntu.com-20120330112844-fkwwo4yy947m6vaq
Tags: 0.4-1
* New upstream release. (Closes: #667064)
  - Add Intuos 5, Bamboo One definitions
* Drop git_touchpad_tablet.patch, included upstream.
* Add git-add-missing-buttons.patch, missing button sections for Intuos
  and Cintiq series.
* libwacom2.symbols: Add a new symbol.
* control: Add DM-Upload-Allowed field.
* copyright: Update the format url.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright © 2011 Red Hat, Inc.
3
 
 *
4
 
 * Permission to use, copy, modify, distribute, and sell this software
5
 
 * and its documentation for any purpose is hereby granted without
6
 
 * fee, provided that the above copyright notice appear in all copies
7
 
 * and that both that copyright notice and this permission notice
8
 
 * appear in supporting documentation, and that the name of Red Hat
9
 
 * not be used in advertising or publicity pertaining to distribution
10
 
 * of the software without specific, written prior permission.  Red
11
 
 * Hat makes no representations about the suitability of this software
12
 
 * for any purpose.  It is provided "as is" without express or implied
13
 
 * warranty.
14
 
 *
15
 
 * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16
 
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
17
 
 * NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18
 
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
19
 
 * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
20
 
 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
21
 
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22
 
 *
23
 
 * Authors:
24
 
 *      Peter Hutterer (peter.hutterer@redhat.com)
25
 
 */
26
 
 
27
 
#ifdef HAVE_CONFIG_H
28
 
#include "config.h"
29
 
#endif
30
 
 
31
 
#include "libwacomint.h"
32
 
#include <stdlib.h>
33
 
#include <stdio.h>
34
 
#include <string.h>
35
 
#include <gudev/gudev.h>
36
 
 
37
 
static const WacomDevice *
38
 
libwacom_get_device(WacomDeviceDatabase *db, const char *match)
39
 
{
40
 
        return (WacomDevice *) g_hash_table_lookup (db->device_ht, match);
41
 
}
42
 
 
43
 
static gboolean
44
 
get_device_info (const char   *path,
45
 
                 int          *vendor_id,
46
 
                 int          *product_id,
47
 
                 char        **name,
48
 
                 WacomBusType *bus,
49
 
                 IsBuiltin    *builtin,
50
 
                 WacomError   *error)
51
 
{
52
 
        GUdevClient *client;
53
 
        GUdevDevice *device;
54
 
        const char * const subsystems[] = { "input", NULL };
55
 
        gboolean retval;
56
 
        const char *bus_str;
57
 
        const char *devname;
58
 
 
59
 
        retval = FALSE;
60
 
        *builtin = IS_BUILTIN_UNSET;
61
 
        *name = NULL;
62
 
        client = g_udev_client_new (subsystems);
63
 
        device = g_udev_client_query_by_device_file (client, path);
64
 
        if (device == NULL) {
65
 
                libwacom_error_set(error, WERROR_INVALID_PATH, "Could not find device '%s' in udev", path);
66
 
                goto bail;
67
 
        }
68
 
 
69
 
        if (g_udev_device_get_property_as_boolean (device, "ID_INPUT_TABLET") == FALSE) {
70
 
                libwacom_error_set(error, WERROR_INVALID_PATH, "Device '%s' is not a tablet", path);
71
 
                goto bail;
72
 
        }
73
 
 
74
 
        bus_str = g_udev_device_get_property (device, "ID_BUS");
75
 
        /* Serial devices are weird */
76
 
        if (bus_str == NULL) {
77
 
                if (g_strcmp0 (g_udev_device_get_subsystem (device), "tty") == 0)
78
 
                        bus_str = "serial";
79
 
        }
80
 
        /* Poke the parent device for Bluetooth models */
81
 
        if (bus_str == NULL) {
82
 
                GUdevDevice *parent;
83
 
 
84
 
                parent = g_udev_device_get_parent (device);
85
 
 
86
 
                g_object_unref (device);
87
 
                device = parent;
88
 
                bus_str = "bluetooth";
89
 
        }
90
 
 
91
 
        /* Is the device builtin? */
92
 
        devname = g_udev_device_get_name (device);
93
 
        if (devname != NULL) {
94
 
                char *sysfs_path, *contents;
95
 
 
96
 
                sysfs_path = g_build_filename ("/sys/class/input", devname, "device/properties", NULL);
97
 
                if (g_file_get_contents (sysfs_path, &contents, NULL, NULL)) {
98
 
                        int flag;
99
 
                        /* 0x01: POINTER flag
100
 
                         * 0x02: DIRECT flag */
101
 
                        flag = atoi(contents);
102
 
                        *builtin = (flag & 0x02) == 0x02 ? IS_BUILTIN_TRUE : IS_BUILTIN_FALSE;
103
 
                        g_free (contents);
104
 
                }
105
 
                g_free (sysfs_path);
106
 
        }
107
 
 
108
 
        *name = g_strdup (g_udev_device_get_sysfs_attr (device, "name"));
109
 
        /* Try getting the name from the parent if that fails */
110
 
        if (*name == NULL) {
111
 
                GUdevDevice *parent;
112
 
 
113
 
                parent = g_udev_device_get_parent (device);
114
 
                *name = g_strdup (g_udev_device_get_sysfs_attr (parent, "name"));
115
 
                g_object_unref (parent);
116
 
        }
117
 
 
118
 
        *bus = bus_from_str (bus_str);
119
 
        if (*bus == WBUSTYPE_USB) {
120
 
                const char *vendor_str, *product_str;
121
 
 
122
 
                vendor_str = g_udev_device_get_property (device, "ID_VENDOR_ID");
123
 
                product_str = g_udev_device_get_property (device, "ID_MODEL_ID");
124
 
 
125
 
                *vendor_id = strtol (vendor_str, NULL, 16);
126
 
                *product_id = strtol (product_str, NULL, 16);
127
 
        } else if (*bus == WBUSTYPE_BLUETOOTH) {
128
 
                const char *product_str;
129
 
                int garbage;
130
 
 
131
 
                /* Parse that:
132
 
                 * E: PRODUCT=5/56a/81/100
133
 
                 * into:
134
 
                 * vendor 0x56a
135
 
                 * product 0x81 */
136
 
                product_str = g_udev_device_get_property (device, "PRODUCT");
137
 
                g_assert (product_str);
138
 
                if (sscanf(product_str, "%d/%x/%x/%d", &garbage, vendor_id, product_id, &garbage) != 4) {
139
 
                        libwacom_error_set(error, WERROR_UNKNOWN_MODEL, "Unimplemented serial bus");
140
 
                        goto bail;
141
 
                }
142
 
        } else if (*bus == WBUSTYPE_SERIAL) {
143
 
                /* FIXME This matches the declaration in serial-wacf004.tablet
144
 
                 * Might not be good enough though */
145
 
                vendor_id = 0;
146
 
                product_id = 0;
147
 
        } else {
148
 
                libwacom_error_set(error, WERROR_UNKNOWN_MODEL, "Unsupported bus '%s'", bus_str);
149
 
                goto bail;
150
 
        }
151
 
 
152
 
        if (*bus != WBUSTYPE_UNKNOWN &&
153
 
            vendor_id != 0 &&
154
 
            product_id != 0)
155
 
                retval = TRUE;
156
 
        /* The serial bus uses 0:0 as the vid/pid */
157
 
        if (*bus == WBUSTYPE_SERIAL)
158
 
                retval = TRUE;
159
 
 
160
 
bail:
161
 
        if (retval == FALSE)
162
 
                g_free (*name);
163
 
        if (device != NULL)
164
 
                g_object_unref (device);
165
 
        if (client != NULL)
166
 
                g_object_unref (client);
167
 
        return retval;
168
 
}
169
 
 
170
 
static WacomDevice *
171
 
libwacom_copy(const WacomDevice *device)
172
 
{
173
 
        WacomDevice *d;
174
 
 
175
 
        d = g_new0 (WacomDevice, 1);
176
 
        d->name = g_strdup (device->name);
177
 
        d->width = device->width;
178
 
        d->height = device->height;
179
 
        d->match = g_strdup (device->match);
180
 
        d->vendor_id = device->vendor_id;
181
 
        d->product_id = device->product_id;
182
 
        d->cls = device->cls;
183
 
        d->bus = device->bus;
184
 
        d->num_strips = device->num_strips;
185
 
        d->features = device->features;
186
 
        d->strips_num_modes = device->strips_num_modes;
187
 
        d->ring_num_modes = device->ring_num_modes;
188
 
        d->ring2_num_modes = device->ring2_num_modes;
189
 
        d->num_styli = device->num_styli;
190
 
        d->supported_styli = g_memdup (device->supported_styli, sizeof(int) * device->num_styli);
191
 
        d->num_buttons = device->num_buttons;
192
 
        d->buttons = g_memdup (device->buttons, sizeof(WacomButtonFlags) * device->num_buttons);
193
 
        return d;
194
 
}
195
 
 
196
 
static const WacomDevice *
197
 
libwacom_new (WacomDeviceDatabase *db, int vendor_id, int product_id, WacomBusType bus, WacomError *error)
198
 
{
199
 
    const WacomDevice *device;
200
 
    char *match;
201
 
 
202
 
    if (!db) {
203
 
        libwacom_error_set(error, WERROR_INVALID_DB, "db is NULL");
204
 
        return NULL;
205
 
    }
206
 
 
207
 
    match = g_strdup_printf ("%s:%04x:%04x", bus_to_str (bus), vendor_id, product_id);
208
 
    device = libwacom_get_device(db, match);
209
 
    g_free (match);
210
 
 
211
 
    return device;
212
 
}
213
 
 
214
 
WacomDevice*
215
 
libwacom_new_from_path(WacomDeviceDatabase *db, const char *path, int fallback, WacomError *error)
216
 
{
217
 
    int vendor_id, product_id;
218
 
    WacomBusType bus;
219
 
    const WacomDevice *device;
220
 
    WacomDevice *ret;
221
 
    IsBuiltin builtin;
222
 
    char *name;
223
 
 
224
 
    if (!db) {
225
 
        libwacom_error_set(error, WERROR_INVALID_DB, "db is NULL");
226
 
        return NULL;
227
 
    }
228
 
 
229
 
    if (!path) {
230
 
        libwacom_error_set(error, WERROR_INVALID_PATH, "path is NULL");
231
 
        return NULL;
232
 
    }
233
 
 
234
 
    if (!get_device_info (path, &vendor_id, &product_id, &name, &bus, &builtin, error))
235
 
        return NULL;
236
 
 
237
 
    device = libwacom_new (db, vendor_id, product_id, bus, error);
238
 
    if (device != NULL)
239
 
            ret = libwacom_copy(device);
240
 
    else if (!fallback)
241
 
            goto bail;
242
 
 
243
 
    if (device == NULL && fallback) {
244
 
            device = libwacom_get_device(db, "generic");
245
 
            if (device == NULL)
246
 
                    goto bail;
247
 
 
248
 
            ret = libwacom_copy(device);
249
 
 
250
 
            if (name != NULL) {
251
 
                    g_free (ret->name);
252
 
                    ret->name = name;
253
 
            }
254
 
            ret->vendor_id = vendor_id;
255
 
            ret->product_id = product_id;
256
 
            ret->bus = bus;
257
 
            g_free (ret->match);
258
 
            ret->match = g_strdup_printf ("%s:0x%x:0x%x", bus_to_str (bus), vendor_id, product_id);
259
 
    } else {
260
 
            g_free (name);
261
 
    }
262
 
 
263
 
    if (device) {
264
 
            if (builtin == IS_BUILTIN_TRUE)
265
 
                ret->features |= FEATURE_BUILTIN;
266
 
            else if (builtin == IS_BUILTIN_FALSE)
267
 
                ret->features &= ~FEATURE_BUILTIN;
268
 
 
269
 
            return ret;
270
 
    }
271
 
 
272
 
bail:
273
 
    g_free (name);
274
 
    libwacom_error_set(error, WERROR_UNKNOWN_MODEL, NULL);
275
 
    return NULL;
276
 
}
277
 
 
278
 
WacomDevice*
279
 
libwacom_new_from_usbid(WacomDeviceDatabase *db, int vendor_id, int product_id, WacomError *error)
280
 
{
281
 
    const WacomDevice *device;
282
 
 
283
 
    if (!db) {
284
 
        libwacom_error_set(error, WERROR_INVALID_DB, "db is NULL");
285
 
        return NULL;
286
 
    }
287
 
 
288
 
    device = libwacom_new(db, vendor_id, product_id, WBUSTYPE_USB, error);
289
 
 
290
 
    if (device)
291
 
            return libwacom_copy(device);
292
 
 
293
 
    libwacom_error_set(error, WERROR_UNKNOWN_MODEL, NULL);
294
 
    return NULL;
295
 
}
296
 
 
297
 
WacomDevice*
298
 
libwacom_new_from_name(WacomDeviceDatabase *db, const char *name, WacomError *error)
299
 
{
300
 
    const WacomDevice *device;
301
 
    GList *keys, *l;
302
 
 
303
 
    if (!db) {
304
 
        libwacom_error_set(error, WERROR_INVALID_DB, "db is NULL");
305
 
        return NULL;
306
 
    }
307
 
 
308
 
    device = NULL;
309
 
    keys = g_hash_table_get_values (db->device_ht);
310
 
    for (l = keys; l; l = l->next) {
311
 
        WacomDevice *d = l->data;
312
 
 
313
 
        if (g_strcmp0 (d->name, name) == 0) {
314
 
            device = d;
315
 
            break;
316
 
        }
317
 
    }
318
 
    g_list_free (keys);
319
 
 
320
 
    if (device)
321
 
            return libwacom_copy(device);
322
 
 
323
 
    libwacom_error_set(error, WERROR_UNKNOWN_MODEL, NULL);
324
 
    return NULL;
325
 
}
326
 
 
327
 
void
328
 
libwacom_destroy(WacomDevice *device)
329
 
{
330
 
        g_free (device->name);
331
 
 
332
 
        g_free (device->match);
333
 
        g_free (device->supported_styli);
334
 
        g_free (device->buttons);
335
 
        g_free (device);
336
 
}
337
 
 
338
 
int libwacom_get_vendor_id(WacomDevice *device)
339
 
{
340
 
    return device->vendor_id;
341
 
}
342
 
 
343
 
const char* libwacom_get_name(WacomDevice *device)
344
 
{
345
 
    return device->name;
346
 
}
347
 
 
348
 
int libwacom_get_product_id(WacomDevice *device)
349
 
{
350
 
    return device->product_id;
351
 
}
352
 
 
353
 
const char* libwacom_get_match(WacomDevice *device)
354
 
{
355
 
    /* FIXME make sure this only returns the first match
356
 
     * when we implement multiple matching */
357
 
    return device->match;
358
 
}
359
 
 
360
 
int libwacom_get_width(WacomDevice *device)
361
 
{
362
 
    return device->width;
363
 
}
364
 
 
365
 
int libwacom_get_height(WacomDevice *device)
366
 
{
367
 
    return device->height;
368
 
}
369
 
 
370
 
WacomClass
371
 
libwacom_get_class(WacomDevice *device)
372
 
{
373
 
    return device->cls;
374
 
}
375
 
 
376
 
int libwacom_has_stylus(WacomDevice *device)
377
 
{
378
 
    return !!(device->features & FEATURE_STYLUS);
379
 
}
380
 
 
381
 
int libwacom_has_touch(WacomDevice *device)
382
 
{
383
 
    return !!(device->features & FEATURE_TOUCH);
384
 
}
385
 
 
386
 
int libwacom_get_num_buttons(WacomDevice *device)
387
 
{
388
 
    return device->num_buttons;
389
 
}
390
 
 
391
 
int *libwacom_get_supported_styli(WacomDevice *device, int *num_styli)
392
 
{
393
 
    *num_styli = device->num_styli;
394
 
    return device->supported_styli;
395
 
}
396
 
 
397
 
int libwacom_has_ring(WacomDevice *device)
398
 
{
399
 
    return !!(device->features & FEATURE_RING);
400
 
}
401
 
 
402
 
int libwacom_has_ring2(WacomDevice *device)
403
 
{
404
 
    return !!(device->features & FEATURE_RING2);
405
 
}
406
 
 
407
 
int libwacom_get_ring_num_modes(WacomDevice *device)
408
 
{
409
 
    return device->ring_num_modes;
410
 
}
411
 
 
412
 
int libwacom_get_ring2_num_modes(WacomDevice *device)
413
 
{
414
 
    return device->ring2_num_modes;
415
 
}
416
 
 
417
 
int libwacom_get_num_strips(WacomDevice *device)
418
 
{
419
 
    return device->num_strips;
420
 
}
421
 
 
422
 
int libwacom_get_strips_num_modes(WacomDevice *device)
423
 
{
424
 
    return device->strips_num_modes;
425
 
}
426
 
 
427
 
int libwacom_is_builtin(WacomDevice *device)
428
 
{
429
 
    return !!(device->features & FEATURE_BUILTIN);
430
 
}
431
 
 
432
 
int libwacom_is_reversible(WacomDevice *device)
433
 
{
434
 
    return !!(device->features & FEATURE_REVERSIBLE);
435
 
}
436
 
 
437
 
WacomBusType libwacom_get_bustype(WacomDevice *device)
438
 
{
439
 
    return device->bus;
440
 
}
441
 
 
442
 
WacomButtonFlags
443
 
libwacom_get_button_flag(WacomDevice *device,
444
 
                         char         button)
445
 
{
446
 
        int index;
447
 
 
448
 
        g_return_val_if_fail (device->num_buttons > 0, WACOM_BUTTON_NONE);
449
 
        g_return_val_if_fail (button >= 'A', WACOM_BUTTON_NONE);
450
 
        g_return_val_if_fail (button < 'A' + device->num_buttons, WACOM_BUTTON_NONE);
451
 
 
452
 
        index = button - 'A';
453
 
 
454
 
        return device->buttons[index];
455
 
}
456
 
 
457
 
const WacomStylus *libwacom_stylus_get_for_id (WacomDeviceDatabase *db, int id)
458
 
{
459
 
        return g_hash_table_lookup (db->stylus_ht, GINT_TO_POINTER(id));
460
 
}
461
 
 
462
 
int libwacom_stylus_get_id (const WacomStylus *stylus)
463
 
{
464
 
        return stylus->id;
465
 
}
466
 
 
467
 
const char *libwacom_stylus_get_name (const WacomStylus *stylus)
468
 
{
469
 
        return stylus->name;
470
 
}
471
 
 
472
 
int libwacom_stylus_get_num_buttons (const WacomStylus *stylus)
473
 
{
474
 
        if (stylus->num_buttons == -1) {
475
 
                g_warning ("Stylus '0x%x' has no number of buttons defined, falling back to 2", stylus->id);
476
 
                return 2;
477
 
        }
478
 
        return stylus->num_buttons;
479
 
}
480
 
 
481
 
int libwacom_stylus_has_eraser (const WacomStylus *stylus)
482
 
{
483
 
        return stylus->has_eraser;
484
 
}
485
 
 
486
 
int libwacom_stylus_is_eraser (const WacomStylus *stylus)
487
 
{
488
 
        return stylus->is_eraser;
489
 
}
490
 
 
491
 
int libwacom_stylus_has_lens (const WacomStylus *stylus)
492
 
{
493
 
        return stylus->has_lens;
494
 
}
495
 
 
496
 
WacomStylusType libwacom_stylus_get_type (const WacomStylus *stylus)
497
 
{
498
 
        if (stylus->type == WSTYLUS_UNKNOWN) {
499
 
                g_warning ("Stylus '0x%x' has no type defined, falling back to 'General'", stylus->id);
500
 
                return WSTYLUS_GENERAL;
501
 
        }
502
 
        return stylus->type;
503
 
}
504
 
 
505
 
void libwacom_stylus_destroy(WacomStylus *stylus)
506
 
{
507
 
        g_free (stylus->name);
508
 
        g_free (stylus);
509
 
}
510
 
 
511
 
/* vim :noexpandtab shiftwidth=8: */