summaryrefslogtreecommitdiff
path: root/mtdev
diff options
context:
space:
mode:
authorHenrik Rydberg <rydberg@euromail.se>2010-06-16 02:27:32 +0200
committerHenrik Rydberg <rydberg@euromail.se>2010-06-16 02:27:32 +0200
commitff88de5cd38b5b51bad0e63d373d66745f1f8d31 (patch)
tree3fbf4adc8c807bc79a8272c4df1623c3677a9b2f /mtdev
parentad6faf6c53bc1924986e1cc10bb42e5d157cba8f (diff)
refactor: Move files
Move all headers into include, separate source files into modules match, mtdev, src and driver, move some common definitions to common.h, and include define support for the MT slot protocol. This patch does not introduce any logical changes. Signed-off-by: Henrik Rydberg <rydberg@euromail.se>
Diffstat (limited to 'mtdev')
-rw-r--r--mtdev/caps.c181
-rw-r--r--mtdev/hwdata.c133
-rw-r--r--mtdev/iobuf.c54
3 files changed, 368 insertions, 0 deletions
diff --git a/mtdev/caps.c b/mtdev/caps.c
new file mode 100644
index 0000000..51e7f5b
--- /dev/null
+++ b/mtdev/caps.c
@@ -0,0 +1,181 @@
1/***************************************************************************
2 *
3 * Multitouch X driver
4 * Copyright (C) 2008 Henrik Rydberg <rydberg@euromail.se>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 *
20 **************************************************************************/
21
22#include <mtdev-caps.h>
23
24#define SETABS(c, x, map, key, fd) \
25 (c->has_##x = getbit(map, key) && getabs(&c->abs_##x, key, fd))
26
27#define ADDCAP(s, c, x) strcat(s, c->has_##x ? " " #x : "")
28
29#define CLICK_AREA(c) ((c->has_ibt ? 0.20 : 0.00) * get_cap_ysize(c))
30
31static const int SN_COORD = 250; /* coordinate signal-to-noise ratio */
32static const int SN_WIDTH = 100; /* width signal-to-noise ratio */
33
34static const int bits_per_long = 8 * sizeof(long);
35
36static inline int nlongs(int nbit)
37{
38 return (nbit + bits_per_long - 1) / bits_per_long;
39}
40
41static inline int getbit(const unsigned long *map, int key)
42{
43 return (map[key / bits_per_long] >> (key % bits_per_long)) & 0x01;
44}
45
46static int getabs(struct input_absinfo *abs, int key, int fd)
47{
48 int rc;
49 SYSCALL(rc = ioctl(fd, EVIOCGABS(key), abs));
50 return rc >= 0;
51}
52
53static int has_integrated_button(const struct Capabilities *cap)
54{
55 static const int bcm5974_vmask_ibt = 1;
56 if (strcmp(cap->devname, "bcm5974"))
57 return 0;
58 return cap->devid.version & bcm5974_vmask_ibt;
59}
60
61int read_capabilities(struct Capabilities *cap, int fd)
62{
63 unsigned long evbits[nlongs(EV_MAX)];
64 unsigned long absbits[nlongs(ABS_MAX)];
65 unsigned long keybits[nlongs(KEY_MAX)];
66 int rc;
67
68 memset(cap, 0, sizeof(struct Capabilities));
69
70 SYSCALL(rc = ioctl(fd, EVIOCGID, &cap->devid));
71 if (rc < 0)
72 return rc;
73 SYSCALL(rc = ioctl(fd, EVIOCGNAME(sizeof(cap->devname)), cap->devname));
74 if (rc < 0)
75 return rc;
76 SYSCALL(rc = ioctl(fd, EVIOCGBIT(EV_SYN, sizeof(evbits)), evbits));
77 if (rc < 0)
78 return rc;
79 SYSCALL(rc = ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybits)), keybits));
80 if (rc < 0)
81 return rc;
82 SYSCALL(rc = ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absbits)), absbits));
83 if (rc < 0)
84 return rc;
85
86 cap->has_left = getbit(keybits, BTN_LEFT);
87 cap->has_middle = getbit(keybits, BTN_MIDDLE);
88 cap->has_right = getbit(keybits, BTN_RIGHT);
89
90 SETABS(cap, touch_major, absbits, ABS_MT_TOUCH_MAJOR, fd);
91 SETABS(cap, touch_minor, absbits, ABS_MT_TOUCH_MINOR, fd);
92 SETABS(cap, width_major, absbits, ABS_MT_WIDTH_MAJOR, fd);
93 SETABS(cap, width_minor, absbits, ABS_MT_WIDTH_MINOR, fd);
94 SETABS(cap, orientation, absbits, ABS_MT_ORIENTATION, fd);
95 SETABS(cap, position_x, absbits, ABS_MT_POSITION_X, fd);
96 SETABS(cap, position_y, absbits, ABS_MT_POSITION_Y, fd);
97
98 cap->has_mtdata = cap->has_position_x && cap->has_position_y;
99 cap->has_ibt = has_integrated_button(cap);
100
101 cap->xfuzz = cap->abs_position_x.fuzz;
102 cap->yfuzz = cap->abs_position_y.fuzz;
103 if (cap->xfuzz <= 0 || cap->yfuzz <= 0) {
104 cap->xfuzz = get_cap_xsize(cap) / SN_COORD;
105 cap->yfuzz = get_cap_ysize(cap) / SN_COORD;
106 }
107 cap->wfuzz = cap->abs_touch_major.fuzz;
108 if (cap->wfuzz <= 0)
109 cap->wfuzz = get_cap_wsize(cap) / SN_WIDTH;
110
111 cap->yclick = cap->abs_position_y.maximum - CLICK_AREA(cap);
112
113 return 0;
114}
115
116int get_cap_xsize(const struct Capabilities *cap)
117{
118 return cap->abs_position_x.maximum - cap->abs_position_x.minimum;
119}
120
121int get_cap_ysize(const struct Capabilities *cap)
122{
123 return cap->abs_position_y.maximum - cap->abs_position_y.minimum;
124}
125
126int get_cap_wsize(const struct Capabilities *cap)
127{
128 return cap->abs_touch_major.maximum - cap->abs_touch_major.minimum;
129}
130
131int get_cap_xmid(const struct Capabilities *cap)
132{
133 return (cap->abs_position_x.maximum + cap->abs_position_x.minimum) >> 1;
134}
135
136int get_cap_ymid(const struct Capabilities *cap)
137{
138 return (cap->abs_position_y.maximum + cap->abs_position_y.minimum) >> 1;
139}
140
141void output_capabilities(const struct Capabilities *cap)
142{
143 char line[1024];
144 memset(line, 0, sizeof(line));
145 ADDCAP(line, cap, left);
146 ADDCAP(line, cap, middle);
147 ADDCAP(line, cap, right);
148 ADDCAP(line, cap, mtdata);
149 ADDCAP(line, cap, ibt);
150 ADDCAP(line, cap, touch_major);
151 ADDCAP(line, cap, touch_minor);
152 ADDCAP(line, cap, width_major);
153 ADDCAP(line, cap, width_minor);
154 ADDCAP(line, cap, orientation);
155 ADDCAP(line, cap, position_x);
156 ADDCAP(line, cap, position_y);
157 xf86Msg(X_INFO, "multitouch: devname: %s\n", cap->devname);
158 xf86Msg(X_INFO, "multitouch: devid: %x %x %x\n",
159 cap->devid.vendor, cap->devid.product, cap->devid.version);
160 xf86Msg(X_INFO, "multitouch: caps:%s\n", line);
161 if (cap->has_touch_major)
162 xf86Msg(X_INFO, "multitouch: touch: %d %d\n",
163 cap->abs_touch_major.minimum,
164 cap->abs_touch_major.maximum);
165 if (cap->has_width_major)
166 xf86Msg(X_INFO, "multitouch: width: %d %d\n",
167 cap->abs_width_major.minimum,
168 cap->abs_width_major.maximum);
169 if (cap->has_orientation)
170 xf86Msg(X_INFO, "multitouch: orientation: %d %d\n",
171 cap->abs_orientation.minimum,
172 cap->abs_orientation.maximum);
173 if (cap->has_position_x)
174 xf86Msg(X_INFO, "multitouch: position_x: %d %d\n",
175 cap->abs_position_x.minimum,
176 cap->abs_position_x.maximum);
177 if (cap->has_position_y)
178 xf86Msg(X_INFO, "multitouch: position_y: %d %d\n",
179 cap->abs_position_y.minimum,
180 cap->abs_position_y.maximum);
181}
diff --git a/mtdev/hwdata.c b/mtdev/hwdata.c
new file mode 100644
index 0000000..689418e
--- /dev/null
+++ b/mtdev/hwdata.c
@@ -0,0 +1,133 @@
1/***************************************************************************
2 *
3 * Multitouch X driver
4 * Copyright (C) 2008 Henrik Rydberg <rydberg@euromail.se>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 *
20 **************************************************************************/
21
22#include "hwdata.h"
23
24void init_hwdata(struct HWData *hw)
25{
26 memset(hw, 0, sizeof(struct HWData));
27}
28
29static void set_value(struct HWData *hw, int code, int value)
30{
31 if (hw->nread < DIM_FINGER) {
32 (&hw->finger[hw->nread].touch_major)[code] = value;
33 SETBIT(hw->mread[hw->nread], code);
34 }
35 hw->mtread++;
36}
37
38static void accept_finger(struct HWData *hw)
39{
40 if (hw->nread < DIM_FINGER &&
41 GETBIT(hw->mread[hw->nread], BIT_MT_POSITION_X) &&
42 GETBIT(hw->mread[hw->nread], BIT_MT_POSITION_Y)) {
43 hw->mask[hw->nread] = hw->mread[hw->nread];
44 hw->nread++;
45 }
46 if (hw->nread < DIM_FINGER)
47 hw->mread[hw->nread] = 0;
48}
49
50static void accept_packet(struct HWData *hw, const struct timeval* tv)
51{
52 static const mstime_t ms = 1000;
53 if (hw->mtread)
54 hw->nfinger = hw->nread;
55 hw->mtread = 0;
56 hw->nread = 0;
57 hw->mread[hw->nread] = 0;
58 hw->evtime = tv->tv_usec / ms + tv->tv_sec * ms;
59}
60
61int read_hwdata(struct HWData *hw, const struct input_event* ev)
62{
63 switch (ev->type) {
64 case EV_SYN:
65 switch (ev->code) {
66 case SYN_REPORT:
67 accept_packet(hw, &ev->time);
68 return 1;
69 case SYN_MT_REPORT:
70 accept_finger(hw);
71 break;
72 }
73 break;
74 case EV_KEY:
75 switch (ev->code) {
76 case BTN_TOUCH:
77 hw->mtread++;
78 break;
79 case BTN_LEFT:
80 if (ev->value)
81 SETBIT(hw->button, MT_BUTTON_LEFT);
82 else
83 CLEARBIT(hw->button, MT_BUTTON_LEFT);
84 break;
85 case BTN_MIDDLE:
86 if (ev->value)
87 SETBIT(hw->button, MT_BUTTON_MIDDLE);
88 else
89 CLEARBIT(hw->button, MT_BUTTON_MIDDLE);
90 break;
91 case BTN_RIGHT:
92 if (ev->value)
93 SETBIT(hw->button, MT_BUTTON_RIGHT);
94 else
95 CLEARBIT(hw->button, MT_BUTTON_RIGHT);
96 break;
97 }
98 break;
99 case EV_ABS:
100 switch (ev->code) {
101 case ABS_MT_TOUCH_MAJOR:
102 set_value(hw, BIT_MT_TOUCH_MAJOR, ev->value);
103 break;
104 case ABS_MT_TOUCH_MINOR:
105 set_value(hw, BIT_MT_TOUCH_MINOR, ev->value);
106 break;
107 case ABS_MT_WIDTH_MAJOR:
108 set_value(hw, BIT_MT_WIDTH_MAJOR, ev->value);
109 break;
110 case ABS_MT_WIDTH_MINOR:
111 set_value(hw, BIT_MT_WIDTH_MINOR, ev->value);
112 break;
113 case ABS_MT_ORIENTATION:
114 set_value(hw, BIT_MT_ORIENTATION, ev->value);
115 break;
116 case ABS_MT_PRESSURE:
117 set_value(hw, BIT_MT_PRESSURE, ev->value);
118 break;
119 case ABS_MT_POSITION_X:
120 set_value(hw, BIT_MT_POSITION_X, ev->value);
121 break;
122 case ABS_MT_POSITION_Y:
123 set_value(hw, BIT_MT_POSITION_Y, ev->value);
124 break;
125 }
126 break;
127 }
128 return 0;
129}
130
131void output_hwdata(const struct HWData *hw)
132{
133}
diff --git a/mtdev/iobuf.c b/mtdev/iobuf.c
new file mode 100644
index 0000000..8e367b8
--- /dev/null
+++ b/mtdev/iobuf.c
@@ -0,0 +1,54 @@
1/***************************************************************************
2 *
3 * Multitouch X driver
4 * Copyright (C) 2008 Henrik Rydberg <rydberg@euromail.se>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 *
20 **************************************************************************/
21
22#include <mtdev-iobuf.h>
23
24void init_iobuf(struct IOBuffer *buf)
25{
26 memset(buf, 0, sizeof(struct IOBuffer));
27 buf->at = buf->begin;
28 buf->top = buf->at;
29 buf->end = buf->begin + DIM_BUFFER;
30}
31
32const struct input_event *get_iobuf_event(struct IOBuffer *buf, int fd)
33{
34 const struct input_event *ev;
35 int n = buf->top - buf->at;
36 if (n < EVENT_SIZE) {
37 /* partial event is available: save it */
38 if (buf->at != buf->begin && n > 0)
39 memmove(buf->begin, buf->at, n);
40 /* start from the beginning */
41 buf->at = buf->begin;
42 buf->top = buf->at + n;
43 /* read more data */
44 SYSCALL(n = read(fd, buf->top, buf->end - buf->top));
45 if (n <= 0)
46 return NULL;
47 buf->top += n;
48 }
49 if (buf->top - buf->at < EVENT_SIZE)
50 return NULL;
51 ev = (const struct input_event *)buf->at;
52 buf->at += EVENT_SIZE;
53 return ev;
54}