summaryrefslogtreecommitdiff
path: root/src/caps.c
diff options
context:
space:
mode:
authorHenrik Rydberg <rydberg@euromail.se>2010-12-22 18:29:00 +0100
committerHenrik Rydberg <rydberg@euromail.se>2010-12-22 18:29:00 +0100
commit56a77e68fb91eef928d8a95c50ae14508e37ae0f (patch)
tree51af9bb9dd508bca58e8b9416479e79f8bb7ee10 /src/caps.c
parent0e2ab3b5940e70493aaabdfe5e8da1c75db4db72 (diff)
Introduce a stable ABI
The current mtdev is not ABI stable, and the upcoming additions to the kernel api will break ABI. This patch starts the process of keeping binary compatibility with old programs, by moving the abi-specific parts under a special flag, MTDEV_NO_LEGACY_API, and makes sure the internal parts compiles with MTDEV_NO_LEGACY_API set. This way, older programs will still work, old programs will still compile, and new programs will be able to use the additions. Signed-off-by: Henrik Rydberg <rydberg@euromail.se>
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