summaryrefslogtreecommitdiff
path: root/src/caps.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/caps.c')
-rw-r--r--src/caps.c163
1 files changed, 129 insertions, 34 deletions
diff --git a/src/caps.c b/src/caps.c
index bf578fa..23f16fc 100644
--- a/src/caps.c
+++ b/src/caps.c
@@ -26,10 +26,7 @@
26 * 26 *
27 ****************************************************************************/ 27 ****************************************************************************/
28 28
29#include "common.h" 29#include "state.h"
30
31#define SETABS(c, x, map, key, fd) \
32 (c->has_##x = getbit(map, key) && getabs(&c->x, key, fd))
33 30
34static const int SN_COORD = 250; /* coordinate signal-to-noise ratio */ 31static const int SN_COORD = 250; /* coordinate signal-to-noise ratio */
35static const int SN_WIDTH = 100; /* width signal-to-noise ratio */ 32static const int SN_WIDTH = 100; /* width signal-to-noise ratio */
@@ -54,59 +51,157 @@ static int getabs(struct input_absinfo *abs, int key, int fd)
54 return rc >= 0; 51 return rc >= 0;
55} 52}
56 53
57static int has_mt_data(const struct mtdev_caps *cap) 54static struct input_absinfo *get_info(struct mtdev *dev, int code)
58{ 55{
59 return cap->has_abs[MTDEV_POSITION_X] && cap->has_abs[MTDEV_POSITION_Y]; 56 int ix;
57
58 if (code == ABS_MT_SLOT)
59 return &dev->slot;
60 if (!mtdev_is_absmt(code))
61 return NULL;
62
63 ix = mtdev_abs2mt(code);
64 if (ix < 11)
65 return &dev->abs[ix];
66 else
67 return &dev->state->ext_abs[ix - 11];
60} 68}
61 69
62static void default_fuzz(struct mtdev_caps *cap, int bit, int sn) 70static void set_info(struct mtdev *dev, int code,
71 const unsigned long *bits, int fd)
63{ 72{
64 if (cap->has_abs[bit] && cap->abs[bit].fuzz == 0) 73 int has = getbit(bits, code) && getabs(get_info(dev, code), code, fd);
65 cap->abs[bit].fuzz = 74 mtdev_set_mt_event(dev, code, has);
66 (cap->abs[bit].maximum - cap->abs[bit].minimum) / sn;
67} 75}
68 76
69static int read_caps(struct mtdev_caps *cap, int fd) 77static void default_fuzz(struct mtdev *dev, int code, int sn)
78{
79 struct input_absinfo *abs = get_info(dev, code);
80 if (!mtdev_has_mt_event(dev, code) || abs->fuzz)
81 return;
82 abs->fuzz = (abs->maximum - abs->minimum) / sn;
83}
84
85int mtdev_configure(struct mtdev *dev, int fd)
70{ 86{
71 unsigned long absbits[nlongs(ABS_MAX)]; 87 unsigned long absbits[nlongs(ABS_MAX)];
72 int rc, i; 88 int rc, i;
73 89
74 memset(cap, 0, sizeof(struct mtdev_caps));
75
76 SYSCALL(rc = ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absbits)), absbits)); 90 SYSCALL(rc = ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absbits)), absbits));
77 if (rc < 0) 91 if (rc < 0)
78 return rc; 92 return rc;
79 93
80 SETABS(cap, slot, absbits, ABS_MT_SLOT, fd); 94 set_info(dev, ABS_MT_SLOT, absbits, fd);
81 for (i = 0; i < MT_ABS_SIZE; i++) 95 for (i = 0; i < MT_ABS_SIZE; i++)
82 SETABS(cap, abs[i], absbits, mtdev_mt2abs(i), fd); 96 set_info(dev, mtdev_mt2abs(i), absbits, fd);
83 97
84 cap->has_mtdata = has_mt_data(cap); 98 dev->has_mtdata = mtdev_has_mt_event(dev, ABS_MT_POSITION_X) &&
99 mtdev_has_mt_event(dev, ABS_MT_POSITION_Y);
85 100
86 if (!cap->has_abs[MTDEV_POSITION_X]) 101 if (!mtdev_has_mt_event(dev, ABS_MT_POSITION_X))
87 getabs(&cap->abs[MTDEV_POSITION_X], ABS_X, fd); 102 getabs(get_info(dev, ABS_MT_POSITION_X), ABS_X, fd);
88 if (!cap->has_abs[MTDEV_POSITION_Y]) 103 if (!mtdev_has_mt_event(dev, ABS_MT_POSITION_Y))
89 getabs(&cap->abs[MTDEV_POSITION_Y], ABS_Y, fd); 104 getabs(get_info(dev, ABS_MT_POSITION_Y), ABS_Y, fd);
90 if (!cap->has_abs[MTDEV_PRESSURE]) 105 if (!mtdev_has_mt_event(dev, ABS_MT_PRESSURE))
91 getabs(&cap->abs[MTDEV_PRESSURE], ABS_PRESSURE, fd); 106 getabs(get_info(dev, ABS_MT_PRESSURE), ABS_PRESSURE, fd);
92 107
93 if (!cap->has_abs[MTDEV_TRACKING_ID]) { 108 if (!mtdev_has_mt_event(dev, ABS_MT_TRACKING_ID)) {
94 cap->abs[MTDEV_TRACKING_ID].minimum = MT_ID_MIN; 109 mtdev_set_abs_minimum(dev, ABS_MT_TRACKING_ID, MT_ID_MIN);
95 cap->abs[MTDEV_TRACKING_ID].maximum = MT_ID_MAX; 110 mtdev_set_abs_maximum(dev, ABS_MT_TRACKING_ID, MT_ID_MAX);
96 } 111 }
97 112
98 default_fuzz(cap, MTDEV_POSITION_X, SN_COORD); 113 default_fuzz(dev, ABS_MT_POSITION_X, SN_COORD);
99 default_fuzz(cap, MTDEV_POSITION_Y, SN_COORD); 114 default_fuzz(dev, ABS_MT_POSITION_Y, SN_COORD);
100 default_fuzz(cap, MTDEV_TOUCH_MAJOR, SN_WIDTH); 115 default_fuzz(dev, ABS_MT_TOUCH_MAJOR, SN_WIDTH);
101 default_fuzz(cap, MTDEV_TOUCH_MINOR, SN_WIDTH); 116 default_fuzz(dev, ABS_MT_TOUCH_MINOR, SN_WIDTH);
102 default_fuzz(cap, MTDEV_WIDTH_MAJOR, SN_WIDTH); 117 default_fuzz(dev, ABS_MT_WIDTH_MAJOR, SN_WIDTH);
103 default_fuzz(cap, MTDEV_WIDTH_MINOR, SN_WIDTH); 118 default_fuzz(dev, ABS_MT_WIDTH_MINOR, SN_WIDTH);
104 default_fuzz(cap, MTDEV_ORIENTATION, SN_ORIENT); 119 default_fuzz(dev, ABS_MT_ORIENTATION, SN_ORIENT);
105 120
106 return 0; 121 return 0;
107} 122}
108 123
109int mtdev_configure(struct mtdev *dev, int fd) 124int mtdev_has_mt_event(const struct mtdev *dev, int code)
125{
126 int ix;
127
128 if (code == ABS_MT_SLOT)
129 return dev->has_slot;
130 if (!mtdev_is_absmt(code))
131 return 0;
132
133 ix = mtdev_abs2mt(code);
134 if (ix < 11)
135 return dev->has_abs[ix];
136 else
137 return dev->state->has_ext_abs[ix - 11];
138}
139
140int mtdev_get_abs_minimum(const struct mtdev *dev, int code)
110{ 141{
111 return read_caps(&dev->caps, fd); 142 const struct input_absinfo *abs = get_info((struct mtdev *)dev, code);
143 return abs ? abs->minimum : 0;
112} 144}
145
146int mtdev_get_abs_maximum(const struct mtdev *dev, int code)
147{
148 const struct input_absinfo *abs = get_info((struct mtdev *)dev, code);
149 return abs ? abs->maximum : 0;
150}
151
152int mtdev_get_abs_fuzz(const struct mtdev *dev, int code)
153{
154 const struct input_absinfo *abs = get_info((struct mtdev *)dev, code);
155 return abs ? abs->fuzz : 0;
156}
157
158int mtdev_get_abs_resolution(const struct mtdev *dev, int code)
159{
160 const struct input_absinfo *abs = get_info((struct mtdev *)dev, code);
161 return abs ? abs->resolution : 0;
162}
163
164void mtdev_set_abs_minimum(struct mtdev *dev, int code, int value)
165{
166 struct input_absinfo *abs = get_info(dev, code);
167 if (abs)
168 abs->minimum = value;
169}
170
171void mtdev_set_mt_event(struct mtdev *dev, int code, int value)
172{
173 int ix;
174
175 if (code == ABS_MT_SLOT)
176 dev->has_slot = value;
177 if (!mtdev_is_absmt(code))
178 return;
179
180 ix = mtdev_abs2mt(code);
181 if (ix < 11)
182 dev->has_abs[ix] = value;
183 else
184 dev->state->has_ext_abs[ix - 11] = value;
185}
186
187void mtdev_set_abs_maximum(struct mtdev *dev, int code, int value)
188{
189 struct input_absinfo *abs = get_info(dev, code);
190 if (abs)
191 abs->maximum = value;
192}
193
194void mtdev_set_abs_fuzz(struct mtdev *dev, int code, int value)
195{
196 struct input_absinfo *abs = get_info(dev, code);
197 if (abs)
198 abs->fuzz = value;
199}
200
201void mtdev_set_abs_resolution(struct mtdev *dev, int code, int value)
202{
203 struct input_absinfo *abs = get_info(dev, code);
204 if (abs)
205 abs->resolution = value;
206}
207