135 lines
4.5 KiB
Python
Executable File
135 lines
4.5 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
import sys
|
|
import os
|
|
import time
|
|
|
|
# Change path so we find Xlib
|
|
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
|
|
|
|
from Xlib.display import Display
|
|
from Xlib.ext import xinerama, xinput, xfixes
|
|
from Xlib.protocol import rq
|
|
|
|
xfixes_extname = 'XFIXES'
|
|
|
|
BarrierPositiveX = (1 << 0)
|
|
BarrierPositiveY = (1 << 1)
|
|
BarrierNegativeX = (1 << 2)
|
|
BarrierNegativeY = (1 << 3)
|
|
|
|
class CreatePointerBarrier(rq.Request):
|
|
_request = rq.Struct(rq.Card8('opcode'),
|
|
rq.Opcode(31),
|
|
rq.RequestLength(),
|
|
rq.Resource('barrier'),
|
|
rq.Window('window'),
|
|
rq.Int16('x1'),
|
|
rq.Int16('y1'),
|
|
rq.Int16('x2'),
|
|
rq.Int16('y2'),
|
|
rq.Card32('directions'),
|
|
rq.Pad(2),
|
|
rq.LengthOf('devices', 2),
|
|
rq.List('devices', xinput.DEVICEID),
|
|
)
|
|
|
|
def create_pointer_barrier(self, x1, y1, x2, y2, barrier_directions, devices=None):
|
|
barrier = self.display.allocate_resource_id()
|
|
CreatePointerBarrier(
|
|
display=self.display,
|
|
opcode=self.display.get_extension_major(xfixes_extname),
|
|
window=self,
|
|
x1=x1,
|
|
y1=y1,
|
|
x2=x2,
|
|
y2=y2,
|
|
directions=barrier_directions,
|
|
devices=[] if not devices else devices,
|
|
barrier=barrier)
|
|
return barrier
|
|
|
|
def main(argv):
|
|
display = Display()
|
|
screen = display.screen()
|
|
window = screen.root
|
|
|
|
|
|
def check_extension(name):
|
|
if not display.has_extension(name):
|
|
sys.stderr.write('%s: server does not have the %s extension\n' % (sys.argv[0], name))
|
|
ext = display.query_extension(name)
|
|
print(ext)
|
|
sys.stderr.write("\n".join(display.list_extensions()))
|
|
if ext is None:
|
|
sys.exit(1)
|
|
|
|
check_extension('XFIXES')
|
|
check_extension('XInputExtension')
|
|
check_extension('XINERAMA')
|
|
|
|
xfixes_version = xfixes.QueryVersion(display=window.display, opcode=window.display.get_extension_major(xfixes_extname), major_version=5, minor_version=0)
|
|
print('Found XFIXES version %s.%s' % (
|
|
xfixes_version.major_version,
|
|
xfixes_version.minor_version,
|
|
), file=sys.stderr)
|
|
|
|
xinput_version = display.xinput_query_version()
|
|
print('Found XInputExtension version %s.%s' % (
|
|
xinput_version.major_version,
|
|
xinput_version.minor_version,
|
|
), file=sys.stderr)
|
|
|
|
xinerama_version = display.xinerama_query_version()
|
|
print('Found XINERAMA version %s.%s' % (
|
|
xinerama_version.major_version,
|
|
xinerama_version.minor_version,
|
|
), file=sys.stderr)
|
|
|
|
print()
|
|
print('Available screens:')
|
|
screens = xinerama.query_screens(window).screens
|
|
for (idx, screen) in enumerate(screens):
|
|
x, y, w, h = screen.x, screen.y, screen.width, screen.height
|
|
print('screen %d: %s' % (idx, screen))
|
|
|
|
print()
|
|
print('Available pointers:')
|
|
pointer_name = {}
|
|
devices = xinput.query_device(window, xinput.AllMasterDevices).devices
|
|
for device in devices:
|
|
if 'pointer' in device.name:
|
|
pointer_name[device.deviceid] = 'device %d: %s' % (device.deviceid, device.name)
|
|
print(pointer_name[device.deviceid])
|
|
|
|
if len(sys.argv) != 3:
|
|
print()
|
|
print('USAGE: %s [device] [screen]' % (sys.argv[0]))
|
|
return -2
|
|
lock_device = int(sys.argv[1])
|
|
lock_screen = int(sys.argv[2])
|
|
|
|
screen = screens[lock_screen]
|
|
|
|
print()
|
|
print('Creating barrier to force pointer %s to screen %d (%s)...' %\
|
|
(pointer_name[lock_device], lock_screen, screens[lock_screen]))
|
|
top = screen.y + 3
|
|
bottom = screen.y + screen.height - 3
|
|
left = screen.x + 1
|
|
right = screen.x + screen.width - 1
|
|
print('Barrier bounds: left=%d, top=%d, right=%d, bottom=%d' % (left, top, right, bottom))
|
|
# top
|
|
create_pointer_barrier(window, left, top, right, top, BarrierPositiveY, [lock_device])
|
|
# left
|
|
create_pointer_barrier(window, left, top, left, bottom, BarrierPositiveX, [lock_device])
|
|
# bottom
|
|
create_pointer_barrier(window, left, bottom, right, bottom, BarrierNegativeY, [lock_device])
|
|
# right
|
|
create_pointer_barrier(window, right, top, right, bottom, BarrierNegativeX, [lock_device])
|
|
display.sync()
|
|
print('Created barrier.')
|
|
input()
|
|
|
|
if __name__ == '__main__':
|
|
sys.exit(main(sys.argv))
|