~ubuntu-branches/ubuntu/trusty/xf86-input-mtrack-lts-utopic/trusty-proposed

« back to all changes in this revision

Viewing changes to src/capabilities.c

  • Committer: Package Import Robot
  • Author(s): Maarten Lankhorst
  • Date: 2015-01-22 10:02:01 UTC
  • Revision ID: package-import@ubuntu.com-20150122100201-9lz7tgip6vq5k2pm
Tags: upstream-0.3.0
ImportĀ upstreamĀ versionĀ 0.3.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 "capabilities.h"
 
23
 
 
24
#define SETABS(c, x, map, key, fd)                                      \
 
25
        (c->has_##x = getbit(map, key) && getabs(&c->x, key, fd))
 
26
 
 
27
#define ADDCAP(s, c, x) strcat(s, c->has_##x ? " " #x : "")
 
28
 
 
29
static const int SN_COORD = 250;        /* coordinate signal-to-noise ratio */
 
30
static const int SN_WIDTH = 100;        /* width signal-to-noise ratio */
 
31
static const int SN_ORIENT = 10;        /* orientation signal-to-noise ratio */
 
32
 
 
33
static const int bits_per_long = 8 * sizeof(long);
 
34
 
 
35
static inline int nlongs(int nbit)
 
36
{
 
37
        return (nbit + bits_per_long - 1) / bits_per_long;
 
38
}
 
39
 
 
40
static inline int getbit(const unsigned long *map, int key)
 
41
{
 
42
        return (map[key / bits_per_long] >> (key % bits_per_long)) & 0x01;
 
43
}
 
44
 
 
45
static int getabs(struct input_absinfo *abs, int key, int fd)
 
46
{
 
47
        int rc;
 
48
        SYSCALL(rc = ioctl(fd, EVIOCGABS(key), abs));
 
49
        return rc >= 0;
 
50
}
 
51
 
 
52
static int has_mt_data(const struct Capabilities *cap)
 
53
{
 
54
        return cap->has_abs[MTDEV_POSITION_X] && cap->has_abs[MTDEV_POSITION_Y];
 
55
}
 
56
 
 
57
static int has_integrated_button(const struct Capabilities *cap)
 
58
{
 
59
        static const int bcm5974_vmask_ibt = 1;
 
60
        /* magic trackpad */
 
61
        if (cap->devid.vendor == 0x05ac && cap->devid.product == 0x030e)
 
62
                return 1;
 
63
        /* macbooks */
 
64
        if (strcmp(cap->devname, "bcm5974"))
 
65
                return 0;
 
66
        return cap->devid.version & bcm5974_vmask_ibt;
 
67
}
 
68
 
 
69
static void default_fuzz(struct Capabilities *cap, unsigned int code, int sn)
 
70
{
 
71
        int bit = mtdev_abs2mt(code);
 
72
        if (cap->has_abs[bit] && cap->abs[bit].fuzz == 0)
 
73
                cap->abs[bit].fuzz =
 
74
                        (cap->abs[bit].maximum - cap->abs[bit].minimum) / sn;
 
75
}
 
76
 
 
77
int read_capabilities(struct Capabilities *cap, int fd)
 
78
{
 
79
        unsigned long evbits[nlongs(EV_MAX)];
 
80
        unsigned long absbits[nlongs(ABS_MAX)];
 
81
        unsigned long keybits[nlongs(KEY_MAX)];
 
82
        int rc, i;
 
83
 
 
84
        memset(cap, 0, sizeof(struct Capabilities));
 
85
 
 
86
        SYSCALL(rc = ioctl(fd, EVIOCGID, &cap->devid));
 
87
        if (rc < 0)
 
88
                return rc;
 
89
        SYSCALL(rc = ioctl(fd, EVIOCGNAME(sizeof(cap->devname)), cap->devname));
 
90
        if (rc < 0)
 
91
                return rc;
 
92
        SYSCALL(rc = ioctl(fd, EVIOCGBIT(EV_SYN, sizeof(evbits)), evbits));
 
93
        if (rc < 0)
 
94
                return rc;
 
95
        SYSCALL(rc = ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybits)), keybits));
 
96
        if (rc < 0)
 
97
                return rc;
 
98
        SYSCALL(rc = ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absbits)), absbits));
 
99
        if (rc < 0)
 
100
                return rc;
 
101
 
 
102
        cap->has_left = getbit(keybits, BTN_LEFT);
 
103
        cap->has_middle = getbit(keybits, BTN_MIDDLE);
 
104
        cap->has_right = getbit(keybits, BTN_RIGHT);
 
105
 
 
106
        SETABS(cap, slot, absbits, ABS_MT_SLOT, fd);
 
107
        for (i = 0; i < MT_ABS_SIZE; i++)
 
108
                SETABS(cap, abs[i], absbits, mtdev_mt2abs(i), fd);
 
109
 
 
110
        cap->has_mtdata = has_mt_data(cap);
 
111
        cap->has_ibt = has_integrated_button(cap);
 
112
 
 
113
        default_fuzz(cap, ABS_MT_POSITION_X, SN_COORD);
 
114
        default_fuzz(cap, ABS_MT_POSITION_Y, SN_COORD);
 
115
        default_fuzz(cap, ABS_MT_TOUCH_MAJOR, SN_WIDTH);
 
116
        default_fuzz(cap, ABS_MT_TOUCH_MINOR, SN_WIDTH);
 
117
        default_fuzz(cap, ABS_MT_WIDTH_MAJOR, SN_WIDTH);
 
118
        default_fuzz(cap, ABS_MT_WIDTH_MINOR, SN_WIDTH);
 
119
        default_fuzz(cap, ABS_MT_ORIENTATION, SN_ORIENT);
 
120
 
 
121
        return 0;
 
122
}
 
123
 
 
124
int get_cap_xsize(const struct Capabilities *cap)
 
125
{
 
126
        const struct input_absinfo *x = &cap->abs[MTDEV_POSITION_X];
 
127
        return x->maximum - x->minimum;
 
128
}
 
129
 
 
130
int get_cap_ysize(const struct Capabilities *cap)
 
131
{
 
132
        const struct input_absinfo *y = &cap->abs[MTDEV_POSITION_Y];
 
133
        return y->maximum - y->minimum;
 
134
}
 
135
 
 
136
int get_cap_wsize(const struct Capabilities *cap)
 
137
{
 
138
        const struct input_absinfo *w = &cap->abs[MTDEV_TOUCH_MAJOR];
 
139
        return w->maximum - w->minimum;
 
140
}
 
141
 
 
142
int get_cap_xmid(const struct Capabilities *cap)
 
143
{
 
144
        const struct input_absinfo *x = &cap->abs[MTDEV_POSITION_X];
 
145
        return (x->maximum + x->minimum) >> 1;
 
146
}
 
147
 
 
148
int get_cap_ymid(const struct Capabilities *cap)
 
149
{
 
150
        const struct input_absinfo *y = &cap->abs[MTDEV_POSITION_Y];
 
151
        return (y->maximum + y->minimum) >> 1;
 
152
}
 
153
 
 
154
int get_cap_xflip(const struct Capabilities *cap, int x)
 
155
{
 
156
        const struct input_absinfo *i = &cap->abs[MTDEV_POSITION_X];
 
157
        return i->maximum - (x - i->minimum);
 
158
}
 
159
 
 
160
int get_cap_yflip(const struct Capabilities *cap, int y)
 
161
{
 
162
        const struct input_absinfo *i = &cap->abs[MTDEV_POSITION_Y];
 
163
        return i->maximum - (y - i->minimum);
 
164
}
 
165
 
 
166
void output_capabilities(const struct Capabilities *cap)
 
167
{
 
168
        char line[1024];
 
169
        int i;
 
170
        memset(line, 0, sizeof(line));
 
171
        ADDCAP(line, cap, left);
 
172
        ADDCAP(line, cap, middle);
 
173
        ADDCAP(line, cap, right);
 
174
        ADDCAP(line, cap, mtdata);
 
175
        ADDCAP(line, cap, ibt);
 
176
        xf86Msg(X_INFO, "mtrack: devname: %s\n", cap->devname);
 
177
        xf86Msg(X_INFO, "mtrack: devid: %x %x %x\n",
 
178
                cap->devid.vendor, cap->devid.product, cap->devid.version);
 
179
        xf86Msg(X_INFO, "mtrack: caps:%s\n", line);
 
180
        for (i = 0; i < MT_ABS_SIZE; i++) {
 
181
                if (cap->has_abs[i])
 
182
                        xf86Msg(X_INFO, "mtrack: %d: min: %d max: %d\n",
 
183
                                i,
 
184
                                cap->abs[i].minimum,
 
185
                                cap->abs[i].maximum);
 
186
        }
 
187
}