Skip to content

Instantly share code, notes, and snippets.

@weskerfoot
Created March 10, 2021 17:21
Show Gist options
  • Save weskerfoot/92816e46846bfeea977e013197ad3c8f to your computer and use it in GitHub Desktop.
Save weskerfoot/92816e46846bfeea977e013197ad3c8f to your computer and use it in GitHub Desktop.
import x11/xlib, x11/x, x11/xinput
import options
#
# PXDeviceInfo* = ptr TXDeviceInfo
# TXDeviceInfo* {.final.} = object
# id*: TXID
# `type`*: TAtom
# name*: cstring
# num_classes*: cint
# use*: cint
# inputclassinfo*: PXAnyClassInfo
template getNumButtons(deviceInfo : TXDeviceInfo) : untyped =
cast[PXButtonInfo](deviceInfo.inputclassinfo)[].num_buttons
proc getButtonMapping(display : PDisplay,
deviceInfo : TXDeviceInfo) : Option[seq[char]] =
let device : PXDevice = display.XOpenDevice(deviceInfo.id)
if cast[int](device) == 0:
return none(seq[char])
let num_buttons : cshort = getNumButtons(deviceInfo)
var mapReturn : seq[char] = newSeq[char](num_buttons)
discard display.XGetDeviceButtonMapping(device,
mapReturn[0].addr,
num_buttons.cuint)
discard display.XCloseDevice(device)
some(mapReturn)
proc setButtonMapping(display : PDisplay,
deviceInfo : TXDeviceInfo,
mapping : seq[char]) : Option[seq[char]] =
var newMapping : seq[char] = mapping
let device : PXDevice = display.XOpenDevice(deviceInfo.id)
if cast[int](device) == 0:
return none(seq[char])
let num_buttons = getNumButtons(deviceInfo)
if newMapping.len >= 3 and newMapping[1] == 2.char:
newMapping[1] = 0.char
echo "Setting mapping"
echo display.XSetDeviceButtonMapping(device,
newMapping[0].addr,
num_buttons)
discard display.XCloseDevice(device)
return some(newMapping)
proc getDisplay() : PDisplay =
result = XOpenDisplay(nil)
if result == nil:
quit("Failed to open display")
iterator getDevices(display : PDisplay) : TXDeviceInfo =
var nDevices : cint
var devInfo = display.XListInputDevices(nDevices.addr)
for i in 0..(nDevices.int - 1):
let dev = cast[PXDeviceInfo](
cast[int](devInfo) + (devInfo[].sizeof * i)
)[]
if dev.type != None and display.XGetAtomName(dev.type) == "MOUSE":
yield dev
discard devInfo.XFree
when isMainModule:
let display = getDisplay()
for dev in display.getDevices():
let deviceAtom : cstring = display.XGetAtomName(dev.type)
echo dev.name, ", ", dev.id
let mapping = display.getButtonMapping(dev)
if mapping.isSome:
discard display.setButtonMapping(dev, mapping.get)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment