3516. Jumbo Tiny-X patch with Itsy support (#3527, Keith Packard).
[gstreamer-omap:xserver.git] / hw / kdrive / ps2.c
1 /*
2  * $Id$
3  *
4  * Copyright © 1999 Keith Packard
5  *
6  * Permission to use, copy, modify, distribute, and sell this software and its
7  * documentation for any purpose is hereby granted without fee, provided that
8  * the above copyright notice appear in all copies and that both that
9  * copyright notice and this permission notice appear in supporting
10  * documentation, and that the name of Keith Packard not be used in
11  * advertising or publicity pertaining to distribution of the software without
12  * specific, written prior permission.  Keith Packard makes no
13  * representations about the suitability of this software for any purpose.  It
14  * is provided "as is" without express or implied warranty.
15  *
16  * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
18  * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
19  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
20  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
21  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
22  * PERFORMANCE OF THIS SOFTWARE.
23  */
24 /* $XFree86: $ */
25
26 #define NEED_EVENTS
27 #include "X.h"
28 #include "Xproto.h"
29 #include "inputstr.h"
30 #include "scrnintstr.h"
31 #include "kdrive.h"
32 #include "Xpoll.h"
33
34 int
35 Ps2ReadBytes (int fd, char *buf, int len, int min)
36 {
37     int             n, tot;
38     fd_set          set;
39     struct timeval  tv;
40
41     tot = 0;
42     while (len)
43     {
44         n = read (fd, buf, len);
45         if (n > 0)
46         {
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
64 void
65 Ps2Read (int ps2Port)
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 = Ps2ReadBytes (ps2Port, buf, sizeof (buf), 3)) > 0)
74     {
75         b = buf;
76         while (n >= 3)
77         {
78             flags = KD_MOUSE_DELTA;
79             if (b[0] & 4)
80                 flags |= KD_BUTTON_2;
81             if (b[0] & 2)
82                 flags |= KD_BUTTON_3;
83             if (b[0] & 1)
84                 flags |= KD_BUTTON_1;
85             
86             dx = b[1];
87             if (b[0] & 0x10)
88                 dx -= 256;
89             dy = b[2];
90             if (b[0] & 0x20)
91                 dy -= 256;
92             dy = -dy;
93             n -= 3;
94             b += 3;
95             KdEnqueueMouseEvent (flags, dx, dy);
96         }
97     }
98 }
99
100 char    *Ps2Names[] = {
101     "/dev/psaux",
102     "/dev/mouse",
103 };
104
105 #define NUM_PS2_NAMES   (sizeof (Ps2Names) / sizeof (Ps2Names[0]))
106
107 int
108 Ps2Init (void)
109 {
110     int     i;
111     int     ps2Port;
112
113     for (i = 0; i < NUM_PS2_NAMES; i++)
114     {
115         ps2Port = open (Ps2Names[i], 0);
116         if (ps2Port >= 0)
117             return ps2Port;
118     }
119 }
120
121 void
122 Ps2Fini (int ps2Port)
123 {
124     if (ps2Port >= 0)
125         close (ps2Port);
126 }
127
128 KdMouseFuncs Ps2MouseFuncs = {
129     Ps2Init,
130     Ps2Read,
131     Ps2Fini
132 };