1706f2543Smrg/* 2706f2543Smrg * Copyright � 1999 Keith Packard 3706f2543Smrg * 4706f2543Smrg * Permission to use, copy, modify, distribute, and sell this software and its 5706f2543Smrg * documentation for any purpose is hereby granted without fee, provided that 6706f2543Smrg * the above copyright notice appear in all copies and that both that 7706f2543Smrg * copyright notice and this permission notice appear in supporting 8706f2543Smrg * documentation, and that the name of Keith Packard not be used in 9706f2543Smrg * advertising or publicity pertaining to distribution of the software without 10706f2543Smrg * specific, written prior permission. Keith Packard makes no 11706f2543Smrg * representations about the suitability of this software for any purpose. It 12706f2543Smrg * is provided "as is" without express or implied warranty. 13706f2543Smrg * 14706f2543Smrg * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15706f2543Smrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 16706f2543Smrg * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17706f2543Smrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 18706f2543Smrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 19706f2543Smrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 20706f2543Smrg * PERFORMANCE OF THIS SOFTWARE. 21706f2543Smrg */ 22706f2543Smrg 23706f2543Smrg#ifdef HAVE_CONFIG_H 24706f2543Smrg#include <kdrive-config.h> 25706f2543Smrg#endif 26706f2543Smrg#include <X11/X.h> 27706f2543Smrg#include <X11/Xproto.h> 28706f2543Smrg#include <X11/Xpoll.h> 29706f2543Smrg#include "inputstr.h" 30706f2543Smrg#include "scrnintstr.h" 31706f2543Smrg#include "kdrive.h" 32706f2543Smrg 33706f2543Smrgstatic int 34706f2543SmrgPs2ReadBytes (int fd, char *buf, int len, int min) 35706f2543Smrg{ 36706f2543Smrg int n, tot; 37706f2543Smrg fd_set set; 38706f2543Smrg struct timeval tv; 39706f2543Smrg 40706f2543Smrg tot = 0; 41706f2543Smrg while (len) 42706f2543Smrg { 43706f2543Smrg n = read (fd, buf, len); 44706f2543Smrg if (n > 0) 45706f2543Smrg { 46706f2543Smrg tot += n; 47706f2543Smrg buf += n; 48706f2543Smrg len -= n; 49706f2543Smrg } 50706f2543Smrg if (tot % min == 0) 51706f2543Smrg break; 52706f2543Smrg FD_ZERO (&set); 53706f2543Smrg FD_SET (fd, &set); 54706f2543Smrg tv.tv_sec = 0; 55706f2543Smrg tv.tv_usec = 100 * 1000; 56706f2543Smrg n = select (fd + 1, &set, 0, 0, &tv); 57706f2543Smrg if (n <= 0) 58706f2543Smrg break; 59706f2543Smrg } 60706f2543Smrg return tot; 61706f2543Smrg} 62706f2543Smrg 63706f2543Smrgchar *Ps2Names[] = { 64706f2543Smrg "/dev/psaux", 65706f2543Smrg/* "/dev/mouse", */ 66706f2543Smrg "/dev/input/mice", 67706f2543Smrg}; 68706f2543Smrg 69706f2543Smrg#define NUM_PS2_NAMES (sizeof (Ps2Names) / sizeof (Ps2Names[0])) 70706f2543Smrg 71706f2543Smrgstatic void 72706f2543SmrgPs2Read (int ps2Port, void *closure) 73706f2543Smrg{ 74706f2543Smrg unsigned char buf[3 * 200]; 75706f2543Smrg unsigned char *b; 76706f2543Smrg int n; 77706f2543Smrg int dx, dy; 78706f2543Smrg unsigned long flags; 79706f2543Smrg unsigned long left_button = KD_BUTTON_1; 80706f2543Smrg unsigned long right_button = KD_BUTTON_3; 81706f2543Smrg 82706f2543Smrg#undef SWAP_USB 83706f2543Smrg#ifdef SWAP_USB 84706f2543Smrg if (id == 2) 85706f2543Smrg { 86706f2543Smrg left_button = KD_BUTTON_3; 87706f2543Smrg right_button = KD_BUTTON_1; 88706f2543Smrg } 89706f2543Smrg#endif 90706f2543Smrg while ((n = Ps2ReadBytes (ps2Port, (char *) buf, sizeof (buf), 3)) > 0) 91706f2543Smrg { 92706f2543Smrg b = buf; 93706f2543Smrg while (n >= 3) 94706f2543Smrg { 95706f2543Smrg flags = KD_MOUSE_DELTA; 96706f2543Smrg if (b[0] & 4) 97706f2543Smrg flags |= KD_BUTTON_2; 98706f2543Smrg if (b[0] & 2) 99706f2543Smrg flags |= right_button; 100706f2543Smrg if (b[0] & 1) 101706f2543Smrg flags |= left_button; 102706f2543Smrg 103706f2543Smrg dx = b[1]; 104706f2543Smrg if (b[0] & 0x10) 105706f2543Smrg dx -= 256; 106706f2543Smrg dy = b[2]; 107706f2543Smrg if (b[0] & 0x20) 108706f2543Smrg dy -= 256; 109706f2543Smrg dy = -dy; 110706f2543Smrg n -= 3; 111706f2543Smrg b += 3; 112706f2543Smrg KdEnqueuePointerEvent (closure, flags, dx, dy, 0); 113706f2543Smrg } 114706f2543Smrg } 115706f2543Smrg} 116706f2543Smrg 117706f2543Smrgstatic Status 118706f2543SmrgPs2Init (KdPointerInfo *pi) 119706f2543Smrg{ 120706f2543Smrg int ps2Port, i; 121706f2543Smrg 122706f2543Smrg if (!pi->path) { 123706f2543Smrg for (i = 0; i < NUM_PS2_NAMES; i++) { 124706f2543Smrg ps2Port = open (Ps2Names[i], 0); 125706f2543Smrg if (ps2Port >= 0) { 126706f2543Smrg pi->path = strdup (Ps2Names[i]); 127706f2543Smrg break; 128706f2543Smrg } 129706f2543Smrg } 130706f2543Smrg } 131706f2543Smrg else { 132706f2543Smrg ps2Port = open (pi->path, 0); 133706f2543Smrg } 134706f2543Smrg 135706f2543Smrg if (ps2Port < 0) 136706f2543Smrg return BadMatch; 137706f2543Smrg 138706f2543Smrg close(ps2Port); 139706f2543Smrg if (!pi->name) 140706f2543Smrg pi->name = strdup ("PS/2 Mouse"); 141706f2543Smrg 142706f2543Smrg return Success; 143706f2543Smrg} 144706f2543Smrg 145706f2543Smrgstatic Status 146706f2543SmrgPs2Enable (KdPointerInfo *pi) 147706f2543Smrg{ 148706f2543Smrg int fd; 149706f2543Smrg 150706f2543Smrg if (!pi) 151706f2543Smrg return BadImplementation; 152706f2543Smrg 153706f2543Smrg fd = open (pi->path, 0); 154706f2543Smrg if (fd < 0) 155706f2543Smrg return BadMatch; 156706f2543Smrg 157706f2543Smrg if (!KdRegisterFd (fd, Ps2Read, pi)) { 158706f2543Smrg close(fd); 159706f2543Smrg return BadAlloc; 160706f2543Smrg } 161706f2543Smrg 162706f2543Smrg pi->driverPrivate = (void *)(intptr_t)fd; 163706f2543Smrg 164706f2543Smrg return Success; 165706f2543Smrg} 166706f2543Smrg 167706f2543Smrg 168706f2543Smrgstatic void 169706f2543SmrgPs2Disable (KdPointerInfo *pi) 170706f2543Smrg{ 171706f2543Smrg KdUnregisterFd (pi, (int)(intptr_t)pi->driverPrivate, TRUE); 172706f2543Smrg} 173706f2543Smrg 174706f2543Smrgstatic void 175706f2543SmrgPs2Fini (KdPointerInfo *pi) 176706f2543Smrg{ 177706f2543Smrg} 178706f2543Smrg 179706f2543SmrgKdPointerDriver Ps2MouseDriver = { 180706f2543Smrg "ps2", 181706f2543Smrg Ps2Init, 182706f2543Smrg Ps2Enable, 183706f2543Smrg Ps2Disable, 184706f2543Smrg Ps2Fini, 185706f2543Smrg NULL, 186706f2543Smrg}; 187