summaryrefslogtreecommitdiff
path: root/sys/src/9/omap/mouse.c
diff options
context:
space:
mode:
authorTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
committerTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
commite5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch)
treed8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/9/omap/mouse.c
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/9/omap/mouse.c')
-rwxr-xr-xsys/src/9/omap/mouse.c255
1 files changed, 255 insertions, 0 deletions
diff --git a/sys/src/9/omap/mouse.c b/sys/src/9/omap/mouse.c
new file mode 100755
index 000000000..f0f62c8a1
--- /dev/null
+++ b/sys/src/9/omap/mouse.c
@@ -0,0 +1,255 @@
+#include "u.h"
+#include "../port/lib.h"
+#include "mem.h"
+#include "dat.h"
+#include "fns.h"
+#include "../port/error.h"
+#include "io.h"
+
+#define Image IMAGE
+#include <draw.h>
+#include <memdraw.h>
+#include <cursor.h>
+#include "screen.h"
+
+/*
+ * mouse types
+ */
+enum
+{
+ Mouseother= 0,
+ Mouseserial= 1,
+ MousePS2= 2,
+};
+
+extern int mouseshifted;
+
+static QLock mousectlqlock;
+static int mousetype;
+static int intellimouse;
+static int packetsize;
+static int resolution;
+static int accelerated;
+static int mousehwaccel;
+static char mouseport[5];
+
+enum
+{
+ CMaccelerated,
+ CMhwaccel,
+ CMintellimouse,
+ CMlinear,
+ CMps2,
+ CMps2intellimouse,
+ CMres,
+ CMreset,
+ CMserial,
+};
+
+static Cmdtab mousectlmsg[] =
+{
+ CMaccelerated, "accelerated", 0,
+ CMhwaccel, "hwaccel", 2,
+ CMintellimouse, "intellimouse", 1,
+ CMlinear, "linear", 1,
+ CMps2, "ps2", 1,
+ CMps2intellimouse, "ps2intellimouse", 1,
+ CMres, "res", 0,
+ CMreset, "reset", 1,
+ CMserial, "serial", 0,
+};
+
+/*
+ * ps/2 mouse message is three bytes
+ *
+ * byte 0 - 0 0 SDY SDX 1 M R L
+ * byte 1 - DX
+ * byte 2 - DY
+ *
+ * shift & right button is the same as middle button
+ *
+ * Intellimouse and AccuPoint with extra buttons deliver
+ * byte 3 - 00 or 01 or FF according to extra button state.
+ * extra buttons are mapped in this code to buttons 4 and 5.
+ * AccuPoint generates repeated events for these buttons;
+* it and Intellimouse generate 'down' events only, so
+ * user-level code is required to generate button 'up' events
+ * if they are needed by the application.
+ * Also on laptops with AccuPoint AND external mouse, the
+ * controller may deliver 3 or 4 bytes according to the type
+ * of the external mouse; code must adapt.
+ *
+ * On the NEC Versa series (and perhaps others?) we seem to
+ * lose a byte from the packet every once in a while, which
+ * means we lose where we are in the instruction stream.
+ * To resynchronize, if we get a byte more than two seconds
+ * after the previous byte, we assume it's the first in a packet.
+ */
+static void
+ps2mouseputc(int c, int shift)
+{
+ static short msg[4];
+ static int nb;
+ static uchar b[] = {0, 1, 4, 5, 2, 3, 6, 7, 0, 1, 2, 3, 2, 3, 6, 7 };
+ static ulong lasttick;
+ ulong m;
+ int buttons, dx, dy;
+
+ shift |= mouseshifted;
+ m = MACHP(0)->ticks;
+ if(TK2SEC(m - lasttick) > 2)
+ nb = 0;
+ lasttick = m;
+ if(nb==0 && (c&0xc8)!=0x08)
+ if(intellimouse && (c==0x00 || c==0x01 || c==0xFF)){
+ packetsize = 4;
+ return;
+ }
+
+ msg[nb] = c;
+ if(++nb == packetsize){
+ nb = 0;
+ if(msg[0] & 0x10)
+ msg[1] |= 0xFF00;
+ if(msg[0] & 0x20)
+ msg[2] |= 0xFF00;
+
+ buttons = b[(msg[0]&7) | (shift ? 8 : 0)];
+ if(intellimouse && packetsize==4){
+ if((msg[3]&0xc8) == 0x08){
+ packetsize = 3;
+ msg[0] = msg[3];
+ nb = 1;
+ }else{
+ if((msg[3] >> 3) & 1)
+ buttons |= 1<<3;
+ else if(msg[3] & 0x7)
+ buttons |= 1<<4;
+ }
+ }
+ dx = msg[1];
+ dy = -msg[2];
+ mousetrack(dx, dy, buttons, TK2MS(MACHP(0)->ticks));
+ }
+}
+
+/*
+ * set up a ps2 mouse
+ */
+static void
+ps2mouse(void)
+{
+ if(mousetype == MousePS2)
+ return;
+
+// i8042auxenable(ps2mouseputc);
+// i8042auxcmd(0xEA); // TODO
+// i8042auxcmd(0xF4);
+
+ mousetype = MousePS2;
+ packetsize = 3;
+ mousehwaccel = 1;
+}
+
+/*
+ * The PS/2 Trackpoint multiplexor on the IBM Thinkpad T23 ignores
+ * acceleration commands. It is supposed to pass them on
+ * to the attached device, but my Logitech mouse is simply
+ * not behaving any differently. For such devices, we allow
+ * the user to use "hwaccel off" to tell us to back off to
+ * software acceleration even if we're using the PS/2 port.
+ * (Serial mice are always software accelerated.)
+ * For more information on the Thinkpad multiplexor, see
+ * http://wwwcssrv.almaden.ibm.com/trackpoint/
+ */
+static void
+setaccelerated(int x)
+{
+ accelerated = x;
+ mouseaccelerate(x);
+}
+
+static void
+setlinear(void)
+{
+ accelerated = 0;
+ mouseaccelerate(0);
+}
+
+static void
+setres(int n)
+{
+ resolution = n;
+}
+
+static void
+setintellimouse(void)
+{
+ intellimouse = 1;
+ packetsize = 4;
+}
+
+static void
+resetmouse(void)
+{
+ packetsize = 3;
+}
+
+void
+mousectl(Cmdbuf *cb)
+{
+ Cmdtab *ct;
+
+ qlock(&mousectlqlock);
+ if(waserror()){
+ qunlock(&mousectlqlock);
+ nexterror();
+ }
+
+ ct = lookupcmd(cb, mousectlmsg, nelem(mousectlmsg));
+ switch(ct->index){
+ case CMaccelerated:
+ setaccelerated(cb->nf == 1? 1: atoi(cb->f[1]));
+ break;
+ case CMintellimouse:
+ setintellimouse();
+ break;
+ case CMlinear:
+ setlinear();
+ break;
+ case CMps2:
+ intellimouse = 0;
+ break;
+ case CMps2intellimouse:
+ setintellimouse();
+ break;
+ case CMres:
+ if(cb->nf >= 2)
+ setres(atoi(cb->f[1]));
+ else
+ setres(1);
+ break;
+ case CMreset:
+ resetmouse();
+ if(accelerated)
+ setaccelerated(accelerated);
+ if(resolution)
+ setres(resolution);
+ if(intellimouse)
+ setintellimouse();
+ break;
+ case CMserial:
+ error("serial mice not supported");
+ break;
+ case CMhwaccel:
+ if(strcmp(cb->f[1], "on")==0)
+ mousehwaccel = 1;
+ else if(strcmp(cb->f[1], "off")==0)
+ mousehwaccel = 0;
+ else
+ cmderror(cb, "bad mouse control message");
+ }
+
+ qunlock(&mousectlqlock);
+ poperror();
+}