Imported Upstream version 1.15.1
[deb_xorg-server.git] / hw / kdrive / linux / ms.c
CommitLineData
a09e091a
JB
1/*
2Copyright (c) 2001 by Juliusz Chroboczek
3Copyright (c) 1999 by Keith Packard
4
5Permission is hereby granted, free of charge, to any person obtaining a copy
6of this software and associated documentation files (the "Software"), to deal
7in the Software without restriction, including without limitation the rights
8to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9copies of the Software, and to permit persons to whom the Software is
10furnished to do so, subject to the following conditions:
11
12The above copyright notice and this permission notice shall be included in
13all copies or substantial portions of the Software.
14
15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21THE SOFTWARE.
22*/
23
24#ifdef HAVE_CONFIG_H
25#include <kdrive-config.h>
26#endif
27#include <errno.h>
28#include <termios.h>
29#include <X11/X.h>
30#include <X11/Xproto.h>
31#include <X11/Xpoll.h>
32#include "inputstr.h"
33#include "scrnintstr.h"
34#include "kdrive.h"
35
36static int
37MsReadBytes(int fd, char *buf, int len, int min)
38{
39 int n, tot;
40 fd_set set;
41 struct timeval tv;
42
43 tot = 0;
44 while (len) {
45 n = read(fd, buf, len);
46 if (n > 0) {
47 tot += n;
48 buf += n;
49 len -= n;
50 }
51 if (tot % min == 0)
52 break;
53 FD_ZERO(&set);
54 FD_SET(fd, &set);
55 tv.tv_sec = 0;
56 tv.tv_usec = 100 * 1000;
57 n = select(fd + 1, &set, 0, 0, &tv);
58 if (n <= 0)
59 break;
60 }
61 return tot;
62}
63
64static void
65MsRead(int port, void *closure)
66{
67 unsigned char buf[3 * 200];
68 unsigned char *b;
69 int n;
70 int dx, dy;
71 unsigned long flags;
72
73 while ((n = MsReadBytes(port, (char *) buf, sizeof(buf), 3)) > 0) {
74 b = buf;
75 while (n >= 3) {
76 flags = KD_MOUSE_DELTA;
77
78 if (b[0] & 0x20)
79 flags |= KD_BUTTON_1;
80 if (b[0] & 0x10)
81 flags |= KD_BUTTON_3;
82
83 dx = (char) (((b[0] & 0x03) << 6) | (b[1] & 0x3F));
84 dy = (char) (((b[0] & 0x0C) << 4) | (b[2] & 0x3F));
85 n -= 3;
86 b += 3;
87 KdEnqueuePointerEvent(closure, flags, dx, dy, 0);
88 }
89 }
90}
91
92static Status
93MsInit(KdPointerInfo * pi)
94{
95 if (!pi)
96 return BadImplementation;
97
98 if (!pi->path || strcmp(pi->path, "auto"))
99 pi->path = strdup("/dev/mouse");
100 if (!pi->name)
101 pi->name = strdup("Microsoft protocol mouse");
102
103 return Success;
104}
105
106static Status
107MsEnable(KdPointerInfo * pi)
108{
109 int port;
110 struct termios t;
111 int ret;
112
113 port = open(pi->path, O_RDWR | O_NONBLOCK);
114 if (port < 0) {
115 ErrorF("Couldn't open %s (%d)\n", pi->path, (int) errno);
116 return 0;
117 }
118 else if (port == 0) {
119 ErrorF("Opening %s returned 0! Please complain to Keith.\n", pi->path);
120 goto bail;
121 }
122
123 if (!isatty(port)) {
124 ErrorF("%s is not a tty\n", pi->path);
125 goto bail;
126 }
127
128 ret = tcgetattr(port, &t);
129 if (ret < 0) {
130 ErrorF("Couldn't tcgetattr(%s): %d\n", pi->path, errno);
131 goto bail;
132 }
133 t.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR |
134 IGNCR | ICRNL | IXON | IXOFF);
135 t.c_oflag &= ~OPOST;
136 t.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
137 t.c_cflag &= ~(CSIZE | PARENB);
138 t.c_cflag |= CS8 | CLOCAL | CSTOPB;
139
140 cfsetispeed(&t, B1200);
141 cfsetospeed(&t, B1200);
142 t.c_cc[VMIN] = 1;
143 t.c_cc[VTIME] = 0;
144 ret = tcsetattr(port, TCSANOW, &t);
145 if (ret < 0) {
146 ErrorF("Couldn't tcsetattr(%s): %d\n", pi->path, errno);
147 goto bail;
148 }
149 if (KdRegisterFd(port, MsRead, pi))
150 return TRUE;
151 pi->driverPrivate = (void *) (intptr_t) port;
152
153 return Success;
154
155 bail:
156 close(port);
157 return BadMatch;
158}
159
160static void
161MsDisable(KdPointerInfo * pi)
162{
163 KdUnregisterFd(pi, (int) (intptr_t) pi->driverPrivate, TRUE);
164}
165
166static void
167MsFini(KdPointerInfo * pi)
168{
169}
170
171KdPointerDriver MsMouseDriver = {
172 "ms",
173 MsInit,
174 MsEnable,
175 MsDisable,
176 MsFini,
177 NULL,
178};