aboutsummaryrefslogtreecommitdiff
path: root/dotfiles/.local/bin
diff options
context:
space:
mode:
Diffstat (limited to 'dotfiles/.local/bin')
-rwxr-xr-xdotfiles/.local/bin/intellimouse-classic91
1 files changed, 91 insertions, 0 deletions
diff --git a/dotfiles/.local/bin/intellimouse-classic b/dotfiles/.local/bin/intellimouse-classic
new file mode 100755
index 0000000..3b320a3
--- /dev/null
+++ b/dotfiles/.local/bin/intellimouse-classic
@@ -0,0 +1,91 @@
+#!/usr/bin/env python3
+import sys
+import usb.core
+import usb.util
+
+# Script to set the DPI of the Microsoft Classic Intellimouse
+# Taken from https://gist.github.com/K-Visscher/22561ca69a64339a7383d67db6e79818
+
+VID = 0x045E
+PID = 0x0823
+
+DPI_WRITE_PROPERTY = 0x96
+
+WRITE_REPORT_ID = 0x24
+WRITE_REPORT_LENGTH = 0x20
+
+INTERFACE = 0x01
+
+class IntelliMouse():
+ def __init__(self):
+ self.reattach = False
+ self.device = usb.core.find(idVendor=VID, idProduct=PID)
+ if self.device is None:
+ raise ValueError("couldn't find the intellimouse...")
+
+ def set_configuration(self):
+ if sys.platform.startswith("linux"):
+ for config in self.device:
+ for interface in config:
+ if self.device.is_kernel_driver_active(interface.bInterfaceNumber):
+ self.device.detach_kernel_driver(interface.bInterfaceNumber)
+ self.reattach = True
+
+ self.device.set_configuration()
+
+ def detach(self):
+ usb.util.dispose_resources(self.device)
+ if self.reattach:
+ for config in self.device:
+ for interface in config:
+ if not self.device.is_kernel_driver_active(interface.bInterfaceNumber):
+ self.device.attach_kernel_driver(interface.bInterfaceNumber)
+
+ def __enter__(self):
+ self.set_configuration()
+
+ def __exit__(self, exc_type, exc_value, exc_traceback):
+ self.detach()
+
+ def __write_property(self, property, data):
+ if not isinstance(property, int):
+ raise TypeError("please make sure to pass a integer for the property argument...")
+ if not isinstance(data, list) or not all(isinstance(x, int) for x in data):
+ raise TypeError("please make sure to pass a list of integers for the data argument...")
+ report = self.__pad_right([WRITE_REPORT_ID, property, len(data)] + data, WRITE_REPORT_LENGTH)
+ self.device.ctrl_transfer(0x21, 0x09, 0x03 << 8 | WRITE_REPORT_ID, INTERFACE, report)
+
+
+ def __pad_right(self, data, until):
+ if not isinstance(data, list) or not all(isinstance(x, int) for x in data):
+ raise TypeError("please make sure to pass a list of integers for the data argument...")
+ if not isinstance(until, int):
+ raise TypeError("please make sure to pass a integer for the until argument...")
+ if until <= 0:
+ raise ValueError("please pass a positive integer for the until argument...")
+ if len(data) >= until:
+ return
+ return data + ((until - len(data)) * [0x00])
+
+ def set_dpi(self, dpi):
+ if not isinstance(dpi, int):
+ raise TypeError("please make sure to pass an integer...")
+ if dpi % 200 != 0 or not (dpi >= 400 and dpi <= 3200):
+ raise ValueError("please make sure to pass a valid value (dpi % 200 == 0 and (dpi >= 400 and dpi <= 3200))")
+ self.__write_property(DPI_WRITE_PROPERTY, [0x00] + list(dpi.to_bytes(2, byteorder="little")))
+
+if __name__ == "__main__":
+ if len(sys.argv) < 2:
+ sys.stderr.write("Usage: {} [400 — 3200 DPI]\n".format(sys.argv[0]))
+ sys.exit(1)
+ try:
+ dpi = int(sys.argv[1])
+ if dpi < 400 or dpi > 3200:
+ raise ValueError
+ except ValueError:
+ sys.stderr.write("DPI value must be a number between 400 and 3200 inclusively")
+ exit(1)
+
+ mouse = IntelliMouse()
+ with mouse:
+ mouse.set_dpi(dpi)