123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- MODULE UsbMouse; (** AUTHOR "staubesv"; PURPOSE "USB Mouse Driver"; *)
- (**
- * Bluebottle USB Mouse Driver (HID boot protocol)
- *
- * Usage:
- * UsbMouse.Install ~ loads this driver
- * SystemTools.Free UsbMouse ~ unloads this driver
- *
- * The HID boot protocol for USB mice supports 3 buttons and 2 axes.
- *
- * References:
- * Device Class Definition for Human Interface Devices (HID), Version 1.11, 27.06.2001, www.usb.org
- *
- * History:
- * 01.12.2005 Added MouseSpeed & MouseAcceleration (staubesv)
- * 10.10.2006 Adapted to UsbHid (staubesv)
- * 28.02.2007 Removed mouse wheel hack since new HID driver can correctly handle it (staubesv)
- *)
- IMPORT SYSTEM, KernelLog, Modules, Inputs, Usbdi, UsbHid;
- CONST
- Name = "UsbMouse";
- Description = "HID boot protocol mouse driver";
- (* Mouse Configuration *)
- MouseSpeed = 50;
- MouseAcceleration = 0;
- Debug = TRUE;
- TYPE
- MouseDriver= OBJECT (UsbHid.HidDriver);
- VAR
- buffer : Usbdi.BufferPtr;
- pipe : Usbdi.Pipe;
- lastDx, lastDy : LONGINT;
- accelX, accelY : REAL;
- PROCEDURE HandleEvent(status : Usbdi.Status; actLen : LONGINT);
- VAR mm : Inputs.MouseMsg; dx, dy : LONGINT;
- BEGIN
- IF (status = Usbdi.Ok) OR ((status = Usbdi.ShortPacket) & (actLen >= 3)) THEN
- dx := SYSTEM.VAL(SHORTINT, buffer[1]);
- dy := SYSTEM.VAL(SHORTINT, buffer[2]);
- accelX := 1.0 + ABS(dx - lastDx) / 128 * MouseAcceleration;
- accelY := 1.0 + ABS(dy - lastDy) / 128 * MouseAcceleration;
- lastDx := dx;
- lastDy := dy;
- mm.dx :=ENTIER(MouseSpeed / 50.0 * dx * accelX);
- mm.dy := ENTIER(MouseSpeed / 50.0 * dy * accelY);
- IF (SYSTEM.VAL(SET, buffer[0]) * {0}) # {} THEN mm.keys := mm.keys + {0}; END;
- IF (SYSTEM.VAL(SET, buffer[0]) * {1}) # {} THEN mm.keys := mm.keys + {2}; END;
- IF (SYSTEM.VAL(SET, buffer[0]) * {2}) # {} THEN mm.keys := mm.keys + {1}; END;
- Inputs.mouse.Handle(mm);
- status := pipe.Transfer(pipe.maxPacketSize, 0, buffer);
- ELSE
- IF status = Usbdi.Stalled THEN
- IF pipe.ClearHalt() THEN
- IF Debug THEN KernelLog.String("UsbMouse: Stall on Interrupt Pipe cleared."); KernelLog.Ln; END;
- status := pipe.Transfer(pipe.maxPacketSize, 0, buffer); (* ignore status *)
- ELSE
- IF Debug THEN KernelLog.String("UsbMouse: Couldn't clear stall on interrupt pipe. Abort."); KernelLog.Ln; END;
- device.FreePipe(pipe);
- END;
- END;
- END;
- END HandleEvent;
- PROCEDURE Connect() : BOOLEAN;
- VAR endpoint, i : LONGINT; status : Usbdi.Status;
- BEGIN
- (* Set the HID boot protocol *)
- IF SetProtocol(UsbHid.BootProtocol) = FALSE THEN
- IF Debug THEN KernelLog.String("UsbMouse: Error: Cannot set boot protocol."); KernelLog.Ln; END;
- RETURN FALSE
- END;
- (* Look for the first interrupt IN endpoint of this device *)
- LOOP
- IF i >= LEN(interface.endpoints) THEN EXIT; END;
- IF interface.endpoints[i].type = Usbdi.InterruptIn THEN
- endpoint := interface.endpoints[i].bEndpointAddress;
- EXIT;
- END;
- INC(i);
- END;
- IF endpoint = 0 THEN
- IF Debug THEN KernelLog.String("UsbMouse: No interrupt IN endpoint found."); KernelLog.Ln; END;
- RETURN FALSE;
- END;
- pipe := device.GetPipe(endpoint);
- IF pipe = NIL THEN RETURN FALSE END;
- NEW(buffer, pipe.maxPacketSize);
- pipe.SetTimeout(0);
- pipe.SetCompletionHandler(HandleEvent);
- status := pipe.Transfer(pipe.maxPacketSize, 0, buffer); (* ignore res *)
- RETURN TRUE;
- END Connect;
- PROCEDURE Disconnect;
- BEGIN
- KernelLog.String("USB mouse disconnected."); KernelLog.Ln;
- END Disconnect;
- END MouseDriver;
- PROCEDURE Probe(dev : Usbdi.UsbDevice; id : Usbdi.InterfaceDescriptor) : Usbdi.Driver;
- VAR driver : MouseDriver;
- BEGIN
- IF id.bInterfaceClass # 3 THEN RETURN NIL END; (* HID class *)
- IF id.bInterfaceSubClass # 1 THEN RETURN NIL END; (* Boot protocol subclass *)
- IF id.bInterfaceProtocol # 2 THEN RETURN NIL END; (* Mouse *)
- NEW(driver); RETURN driver;
- END Probe;
- PROCEDURE Install*;
- END Install;
- PROCEDURE Cleanup;
- BEGIN
- Usbdi.drivers.Remove(Name);
- END Cleanup;
- BEGIN
- Modules.InstallTermHandler(Cleanup);
- Usbdi.drivers.Add(Probe, Name, Description, 10)
- END UsbMouse.
- UsbMouse.Install ~ SystemTools.Free UsbMouse ~
|