Commit | Line | Data |
---|---|---|
a09e091a JB |
1 | /* |
2 | * Copyright © 1999 Keith Packard | |
3 | * | |
4 | * Permission to use, copy, modify, distribute, and sell this software and its | |
5 | * documentation for any purpose is hereby granted without fee, provided that | |
6 | * the above copyright notice appear in all copies and that both that | |
7 | * copyright notice and this permission notice appear in supporting | |
8 | * documentation, and that the name of Keith Packard not be used in | |
9 | * advertising or publicity pertaining to distribution of the software without | |
10 | * specific, written prior permission. Keith Packard makes no | |
11 | * representations about the suitability of this software for any purpose. It | |
12 | * is provided "as is" without express or implied warranty. | |
13 | * | |
14 | * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, | |
15 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO | |
16 | * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR | |
17 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, | |
18 | * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER | |
19 | * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR | |
20 | * PERFORMANCE OF THIS SOFTWARE. | |
21 | */ | |
22 | ||
23 | #ifdef HAVE_CONFIG_H | |
24 | #include <kdrive-config.h> | |
25 | #endif | |
26 | #include <X11/X.h> | |
27 | #include <X11/Xproto.h> | |
28 | #include <X11/Xpoll.h> | |
29 | #include "inputstr.h" | |
30 | #include "scrnintstr.h" | |
31 | #include "kdrive.h" | |
32 | ||
33 | static int | |
34 | Ps2ReadBytes(int fd, char *buf, int len, int min) | |
35 | { | |
36 | int n, tot; | |
37 | fd_set set; | |
38 | struct timeval tv; | |
39 | ||
40 | tot = 0; | |
41 | while (len) { | |
42 | n = read(fd, buf, len); | |
43 | if (n > 0) { | |
44 | tot += n; | |
45 | buf += n; | |
46 | len -= n; | |
47 | } | |
48 | if (tot % min == 0) | |
49 | break; | |
50 | FD_ZERO(&set); | |
51 | FD_SET(fd, &set); | |
52 | tv.tv_sec = 0; | |
53 | tv.tv_usec = 100 * 1000; | |
54 | n = select(fd + 1, &set, 0, 0, &tv); | |
55 | if (n <= 0) | |
56 | break; | |
57 | } | |
58 | return tot; | |
59 | } | |
60 | ||
61 | const char *Ps2Names[] = { | |
62 | "/dev/psaux", | |
63 | /* "/dev/mouse", */ | |
64 | "/dev/input/mice", | |
65 | }; | |
66 | ||
67 | #define NUM_PS2_NAMES (sizeof (Ps2Names) / sizeof (Ps2Names[0])) | |
68 | ||
69 | static void | |
70 | Ps2Read(int ps2Port, void *closure) | |
71 | { | |
72 | unsigned char buf[3 * 200]; | |
73 | unsigned char *b; | |
74 | int n; | |
75 | int dx, dy; | |
76 | unsigned long flags; | |
77 | unsigned long left_button = KD_BUTTON_1; | |
78 | unsigned long right_button = KD_BUTTON_3; | |
79 | ||
80 | #undef SWAP_USB | |
81 | #ifdef SWAP_USB | |
82 | if (id == 2) { | |
83 | left_button = KD_BUTTON_3; | |
84 | right_button = KD_BUTTON_1; | |
85 | } | |
86 | #endif | |
87 | while ((n = Ps2ReadBytes(ps2Port, (char *) buf, sizeof(buf), 3)) > 0) { | |
88 | b = buf; | |
89 | while (n >= 3) { | |
90 | flags = KD_MOUSE_DELTA; | |
91 | if (b[0] & 4) | |
92 | flags |= KD_BUTTON_2; | |
93 | if (b[0] & 2) | |
94 | flags |= right_button; | |
95 | if (b[0] & 1) | |
96 | flags |= left_button; | |
97 | ||
98 | dx = b[1]; | |
99 | if (b[0] & 0x10) | |
100 | dx -= 256; | |
101 | dy = b[2]; | |
102 | if (b[0] & 0x20) | |
103 | dy -= 256; | |
104 | dy = -dy; | |
105 | n -= 3; | |
106 | b += 3; | |
107 | KdEnqueuePointerEvent(closure, flags, dx, dy, 0); | |
108 | } | |
109 | } | |
110 | } | |
111 | ||
112 | static Status | |
113 | Ps2Init(KdPointerInfo * pi) | |
114 | { | |
115 | int ps2Port, i; | |
116 | ||
117 | if (!pi->path) { | |
118 | for (i = 0; i < NUM_PS2_NAMES; i++) { | |
119 | ps2Port = open(Ps2Names[i], 0); | |
120 | if (ps2Port >= 0) { | |
121 | pi->path = strdup(Ps2Names[i]); | |
122 | break; | |
123 | } | |
124 | } | |
125 | } | |
126 | else { | |
127 | ps2Port = open(pi->path, 0); | |
128 | } | |
129 | ||
130 | if (ps2Port < 0) | |
131 | return BadMatch; | |
132 | ||
133 | close(ps2Port); | |
134 | if (!pi->name) | |
135 | pi->name = strdup("PS/2 Mouse"); | |
136 | ||
137 | return Success; | |
138 | } | |
139 | ||
140 | static Status | |
141 | Ps2Enable(KdPointerInfo * pi) | |
142 | { | |
143 | int fd; | |
144 | ||
145 | if (!pi) | |
146 | return BadImplementation; | |
147 | ||
148 | fd = open(pi->path, 0); | |
149 | if (fd < 0) | |
150 | return BadMatch; | |
151 | ||
152 | if (!KdRegisterFd(fd, Ps2Read, pi)) { | |
153 | close(fd); | |
154 | return BadAlloc; | |
155 | } | |
156 | ||
157 | pi->driverPrivate = (void *) (intptr_t) fd; | |
158 | ||
159 | return Success; | |
160 | } | |
161 | ||
162 | static void | |
163 | Ps2Disable(KdPointerInfo * pi) | |
164 | { | |
165 | KdUnregisterFd(pi, (int) (intptr_t) pi->driverPrivate, TRUE); | |
166 | } | |
167 | ||
168 | static void | |
169 | Ps2Fini(KdPointerInfo * pi) | |
170 | { | |
171 | } | |
172 | ||
173 | KdPointerDriver Ps2MouseDriver = { | |
174 | "ps2", | |
175 | Ps2Init, | |
176 | Ps2Enable, | |
177 | Ps2Disable, | |
178 | Ps2Fini, | |
179 | NULL, | |
180 | }; |