Cleanup spec file and remove obsolete yaml files
[external/mtdev.git] / src / caps.c
1 /*****************************************************************************
2  *
3  * mtdev - Multitouch Protocol Translation Library (MIT license)
4  *
5  * Copyright (C) 2010 Henrik Rydberg <rydberg@euromail.se>
6  * Copyright (C) 2010 Canonical Ltd.
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining a
9  * copy of this software and associated documentation files (the "Software"),
10  * to deal in the Software without restriction, including without limitation
11  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12  * and/or sell copies of the Software, and to permit persons to whom the
13  * Software is furnished to do so, subject to the following conditions:
14  *
15  * The above copyright notice and this permission notice (including the next
16  * paragraph) shall be included in all copies or substantial portions of the
17  * Software.
18  *
19  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
22  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25  * DEALINGS IN THE SOFTWARE.
26  *
27  ****************************************************************************/
28
29 #include "common.h"
30
31 #define SETABS(c, x, map, key, fd)                                      \
32         (c->has_##x = getbit(map, key) && getabs(&c->x, key, fd))
33
34 static const int SN_COORD = 250;        /* coordinate signal-to-noise ratio */
35 static const int SN_WIDTH = 100;        /* width signal-to-noise ratio */
36 static const int SN_ORIENT = 10;        /* orientation signal-to-noise ratio */
37
38 static const int bits_per_long = 8 * sizeof(long);
39
40 static inline int nlongs(int nbit)
41 {
42         return (nbit + bits_per_long - 1) / bits_per_long;
43 }
44
45 static inline int getbit(const unsigned long *map, int key)
46 {
47         return (map[key / bits_per_long] >> (key % bits_per_long)) & 0x01;
48 }
49
50 static int getabs(struct input_absinfo *abs, int key, int fd)
51 {
52         int rc;
53         SYSCALL(rc = ioctl(fd, EVIOCGABS(key), abs));
54         return rc >= 0;
55 }
56
57 static int has_mt_data(const struct mtdev_caps *cap)
58 {
59         return cap->has_abs[MTDEV_POSITION_X] && cap->has_abs[MTDEV_POSITION_Y];
60 }
61
62 static void default_fuzz(struct mtdev_caps *cap, int bit, int sn)
63 {
64         if (cap->has_abs[bit] && cap->abs[bit].fuzz == 0)
65                 cap->abs[bit].fuzz =
66                         (cap->abs[bit].maximum - cap->abs[bit].minimum) / sn;
67 }
68
69 static int read_caps(struct mtdev_caps *cap, int fd)
70 {
71         unsigned long absbits[nlongs(ABS_MAX)];
72         int rc, i;
73
74         memset(cap, 0, sizeof(struct mtdev_caps));
75
76         SYSCALL(rc = ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absbits)), absbits));
77         if (rc < 0)
78                 return rc;
79
80         SETABS(cap, slot, absbits, ABS_MT_SLOT, fd);
81         for (i = 0; i < MT_ABS_SIZE; i++)
82                 SETABS(cap, abs[i], absbits, mtdev_mt2abs(i), fd);
83
84         cap->has_mtdata = has_mt_data(cap);
85
86         if (!cap->has_abs[MTDEV_POSITION_X])
87                 getabs(&cap->abs[MTDEV_POSITION_X], ABS_X, fd);
88         if (!cap->has_abs[MTDEV_POSITION_Y])
89                 getabs(&cap->abs[MTDEV_POSITION_Y], ABS_Y, fd);
90         if (!cap->has_abs[MTDEV_PRESSURE])
91                 getabs(&cap->abs[MTDEV_PRESSURE], ABS_PRESSURE, fd);
92
93         if (!cap->has_abs[MTDEV_TRACKING_ID]) {
94                 cap->abs[MTDEV_TRACKING_ID].minimum = MT_ID_MIN;
95                 cap->abs[MTDEV_TRACKING_ID].maximum = MT_ID_MAX;
96         }
97
98         default_fuzz(cap, MTDEV_POSITION_X, SN_COORD);
99         default_fuzz(cap, MTDEV_POSITION_Y, SN_COORD);
100         default_fuzz(cap, MTDEV_TOUCH_MAJOR, SN_WIDTH);
101         default_fuzz(cap, MTDEV_TOUCH_MINOR, SN_WIDTH);
102         default_fuzz(cap, MTDEV_WIDTH_MAJOR, SN_WIDTH);
103         default_fuzz(cap, MTDEV_WIDTH_MINOR, SN_WIDTH);
104         default_fuzz(cap, MTDEV_ORIENTATION, SN_ORIENT);
105
106         return 0;
107 }
108
109 int mtdev_configure(struct mtdev *dev, int fd)
110 {
111         return read_caps(&dev->caps, fd);
112 }