#!/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))