first commit

This commit is contained in:
2025-11-01 06:00:52 +05:30
parent 6a49b604a7
commit ae7194a9f2
2110 changed files with 382375 additions and 0 deletions

View File

@@ -0,0 +1,46 @@
# Xlib.ext.__init__ -- X extension modules
#
# Copyright (C) 2000 Peter Liljenberg <petli@ctrl-c.liu.se>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public License
# as published by the Free Software Foundation; either version 2.1
# of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the
# Free Software Foundation, Inc.,
# 59 Temple Place,
# Suite 330,
# Boston, MA 02111-1307 USA
# __extensions__ is a list of tuples: (extname, extmod)
# extname is the name of the extension according to the X
# protocol. extmod is the name of the module in this package.
__extensions__ = [
# We load this first so other extensions can register generic event data
# structures.
('Generic Event Extension', 'ge'),
('XTEST', 'xtest'),
('SHAPE', 'shape'),
('XINERAMA', 'xinerama'),
('RECORD', 'record'),
('Composite', 'composite'),
('RANDR', 'randr'),
('XFIXES', 'xfixes'),
('SECURITY', 'security'),
('XInputExtension', 'xinput'),
('NV-CONTROL', 'nvcontrol'),
('DAMAGE', 'damage'),
('DPMS', 'dpms'),
('X-Resource', 'res'),
('MIT-SCREEN-SAVER', 'screensaver'),
]
__all__ = map(lambda x: x[1], __extensions__)

View File

@@ -0,0 +1,271 @@
# $Id: xtest.py,v 1.1 2000/08/21 10:03:45 petli Exp $
#
# Xlib.ext.composite -- Composite extension module
#
# Copyright (C) 2007 Peter Liljenberg <peter.liljenberg@gmail.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public License
# as published by the Free Software Foundation; either version 2.1
# of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the
# Free Software Foundation, Inc.,
# 59 Temple Place,
# Suite 330,
# Boston, MA 02111-1307 USA
"""Composite extension, allowing windows to be rendered to off-screen
storage.
For detailed description, see the protocol specification at
http://freedesktop.org/wiki/Software/CompositeExt
By itself this extension is not very useful, it is intended to be used
together with the DAMAGE and XFIXES extensions. Typically you would
also need RENDER or glX or some similar method of creating fancy
graphics.
"""
from Xlib.protocol import rq
from Xlib.xobject import drawable
extname = 'Composite'
RedirectAutomatic = 0
RedirectManual = 1
class QueryVersion(rq.ReplyRequest):
_request = rq.Struct(
rq.Card8('opcode'),
rq.Opcode(0),
rq.RequestLength(),
rq.Card32('major_version'),
rq.Card32('minor_version')
)
_reply = rq.Struct(
rq.ReplyCode(),
rq.Pad(1),
rq.Card16('sequence_number'),
rq.ReplyLength(),
rq.Card32('major_version'),
rq.Card32('minor_version'),
rq.Pad(16),
)
def query_version(self):
return QueryVersion(
display = self.display,
opcode = self.display.get_extension_major(extname),
major_version=0,
minor_version=4
)
class RedirectWindow(rq.Request):
_request = rq.Struct(
rq.Card8('opcode'),
rq.Opcode(1),
rq.RequestLength(),
rq.Window('window'),
rq.Set('update', 1, (RedirectAutomatic, RedirectManual)),
rq.Pad(3),
)
def redirect_window(self, update, onerror = None):
"""Redirect the hierarchy starting at this window to off-screen
storage.
"""
RedirectWindow(display = self.display,
onerror = onerror,
opcode = self.display.get_extension_major(extname),
window = self,
update = update,
)
class RedirectSubwindows(rq.Request):
_request = rq.Struct(
rq.Card8('opcode'),
rq.Opcode(2),
rq.RequestLength(),
rq.Window('window'),
rq.Set('update', 1, (RedirectAutomatic, RedirectManual)),
rq.Pad(3),
)
def redirect_subwindows(self, update, onerror = None):
"""Redirect the hierarchies starting at all current and future
children to this window to off-screen storage.
"""
RedirectSubwindows(display = self.display,
onerror = onerror,
opcode = self.display.get_extension_major(extname),
window = self,
update = update,
)
class UnredirectWindow(rq.Request):
_request = rq.Struct(
rq.Card8('opcode'),
rq.Opcode(3),
rq.RequestLength(),
rq.Window('window'),
rq.Set('update', 1, (RedirectAutomatic, RedirectManual)),
rq.Pad(3),
)
def unredirect_window(self, update, onerror = None):
"""Stop redirecting this window hierarchy.
"""
UnredirectWindow(display = self.display,
onerror = onerror,
opcode = self.display.get_extension_major(extname),
window = self,
update = update,
)
class UnredirectSubindows(rq.Request):
_request = rq.Struct(
rq.Card8('opcode'),
rq.Opcode(4),
rq.RequestLength(),
rq.Window('window'),
rq.Set('update', 1, (RedirectAutomatic, RedirectManual)),
rq.Pad(3),
)
def unredirect_subwindows(self, update, onerror = None):
"""Stop redirecting the hierarchies of children to this window.
"""
RedirectWindow(display = self.display,
onerror = onerror,
opcode = self.display.get_extension_major(extname),
window = self,
update = update,
)
class CreateRegionFromBorderClip(rq.Request):
_request = rq.Struct(
rq.Card8('opcode'),
rq.Opcode(5),
rq.RequestLength(),
rq.Card32('region'), # FIXME: this should be a Region from XFIXES extension
rq.Window('window'),
)
def create_region_from_border_clip(self, onerror = None):
"""Create a region of the border clip of the window, i.e. the area
that is not clipped by the parent and any sibling windows.
"""
rid = self.display.allocate_resource_id()
CreateRegionFromBorderClip(
display = self.display,
onerror = onerror,
opcode = self.display.get_extension_major(extname),
region = rid,
window = self,
)
# FIXME: create Region object and return it
return rid
class NameWindowPixmap(rq.Request):
_request = rq.Struct(
rq.Card8('opcode'),
rq.Opcode(6),
rq.RequestLength(),
rq.Window('window'),
rq.Pixmap('pixmap'),
)
def name_window_pixmap(self, onerror = None):
"""Create a new pixmap that refers to the off-screen storage of
the window, including its border.
This pixmap will remain allocated until freed whatever happens
with the window. However, the window will get a new off-screen
pixmap every time it is mapped or resized, so to keep track of the
contents you must listen for these events and get a new pixmap
after them.
"""
pid = self.display.allocate_resource_id()
NameWindowPixmap(display = self.display,
onerror = onerror,
opcode = self.display.get_extension_major(extname),
window = self,
pixmap = pid,
)
cls = self.display.get_resource_class('pixmap', drawable.Pixmap)
return cls(self.display, pid, owner = 1)
class GetOverlayWindow(rq.ReplyRequest):
_request = rq.Struct(
rq.Card8('opcode'),
rq.Opcode(7),
rq.RequestLength(),
rq.Window('window')
)
_reply = rq.Struct(
rq.ReplyCode(),
rq.Pad(1),
rq.Card16('sequence_number'),
rq.ReplyLength(),
rq.Window('overlay_window'),
rq.Pad(20),
)
def get_overlay_window(self):
"""Return the overlay window of the root window.
"""
return GetOverlayWindow(display = self.display,
opcode = self.display.get_extension_major(extname),
window = self)
def init(disp, info):
disp.extension_add_method('display',
'composite_query_version',
query_version)
disp.extension_add_method('window',
'composite_redirect_window',
redirect_window)
disp.extension_add_method('window',
'composite_redirect_subwindows',
redirect_subwindows)
disp.extension_add_method('window',
'composite_unredirect_window',
unredirect_window)
disp.extension_add_method('window',
'composite_unredirect_subwindows',
unredirect_subwindows)
disp.extension_add_method('window',
'composite_create_region_from_border_clip',
create_region_from_border_clip)
disp.extension_add_method('window',
'composite_name_window_pixmap',
name_window_pixmap)
disp.extension_add_method('window',
'composite_get_overlay_window',
get_overlay_window)

View File

@@ -0,0 +1,181 @@
# Xlib.ext.damage -- DAMAGE extension module
#
# Copyright (C) 2018 Joseph Kogut <joseph.kogut@gmail.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public License
# as published by the Free Software Foundation; either version 2.1
# of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the
# Free Software Foundation, Inc.,
# 59 Temple Place,
# Suite 330,
# Boston, MA 02111-1307 USA
from Xlib import X
from Xlib.protocol import rq, structs
from Xlib.error import XError
extname = 'DAMAGE'
# Event codes #
DamageNotifyCode = 0
# Error codes #
BadDamageCode = 0
class BadDamageError(XError):
pass
# DamageReportLevel options
DamageReportRawRectangles = 0
DamageReportDeltaRectangles = 1
DamageReportBoundingBox = 2
DamageReportNonEmpty = 3
DamageReportLevel = (
DamageReportRawRectangles,
DamageReportDeltaRectangles,
DamageReportBoundingBox,
DamageReportNonEmpty,
)
DAMAGE = rq.Card32
# Methods
class QueryVersion(rq.ReplyRequest):
_request = rq.Struct(rq.Card8('opcode'),
rq.Opcode(0),
rq.RequestLength(),
rq.Card32('major_version'),
rq.Card32('minor_version'),
)
_reply = rq.Struct(rq.ReplyCode(),
rq.Pad(1),
rq.Card16('sequence_number'),
rq.ReplyLength(),
rq.Card32('major_version'),
rq.Card32('minor_version'),
rq.Pad(16),
)
def query_version(self):
return QueryVersion(display=self.display,
opcode=self.display.get_extension_major(extname),
major_version=1,
minor_version=1)
class DamageCreate(rq.Request):
_request = rq.Struct(rq.Card8('opcode'),
rq.Opcode(1),
rq.RequestLength(),
DAMAGE('damage'),
rq.Drawable('drawable'),
rq.Set('level', 1, DamageReportLevel),
rq.Pad(3),
)
def damage_create(self, level):
did = self.display.allocate_resource_id()
DamageCreate(display=self.display,
opcode=self.display.get_extension_major(extname),
damage=did,
drawable=self.id,
level=level,
)
return did
class DamageDestroy(rq.Request):
_request = rq.Struct(rq.Card8('opcode'),
rq.Opcode(2),
rq.RequestLength(),
DAMAGE('damage')
)
def damage_destroy(self, damage):
DamageDestroy(display=self.display,
opcode=self.display.get_extension_major(extname),
damage=damage,
)
self.display.free_resource_id(damage)
class DamageSubtract(rq.Request):
_request = rq.Struct(rq.Card8('opcode'),
rq.Opcode(3),
rq.RequestLength(),
DAMAGE('damage'),
rq.Card32('repair'),
rq.Card32('parts')
)
def damage_subtract(self, damage, repair=X.NONE, parts=X.NONE):
DamageSubtract(display=self.display,
opcode=self.display.get_extension_major(extname),
damage=damage,
repair=repair,
parts=parts)
class DamageAdd(rq.Request):
_request = rq.Struct(rq.Card8('opcode'),
rq.Opcode(4),
rq.RequestLength(),
rq.Card32('repair'),
rq.Card32('parts'),
)
def damage_add(self, repair, parts):
DamageAdd(display=self.display,
opcode=self.display.get_extension_major(extname),
repair=repair,
parts=parts)
# Events #
class DamageNotify(rq.Event):
_code = None
_fields = rq.Struct(
rq.Card8('type'),
rq.Card8('level'),
rq.Card16('sequence_number'),
rq.Drawable('drawable'),
DAMAGE('damage'),
rq.Card32('timestamp'),
rq.Object('area', structs.Rectangle),
rq.Object('drawable_geometry', structs.Rectangle)
)
def init(disp, info):
disp.extension_add_method('display',
'damage_query_version',
query_version)
disp.extension_add_method('drawable',
'damage_create',
damage_create)
disp.extension_add_method('display',
'damage_destroy',
damage_destroy)
disp.extension_add_method('display',
'damage_subtract',
damage_subtract)
disp.extension_add_method('drawable',
'damage_add',
damage_add)
disp.extension_add_event(info.first_event + DamageNotifyCode, DamageNotify)
disp.extension_add_error(code=BadDamageCode, err=BadDamageError)

View File

@@ -0,0 +1,232 @@
# Xlib.ext.dpms -- X Display Power Management Signaling
#
# Copyright (C) 2020 Thiago Kenji Okada <thiagokokada@gmail.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public License
# as published by the Free Software Foundation; either version 2.1
# of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the
# Free Software Foundation, Inc.,
# 59 Temple Place,
# Suite 330,
# Boston, MA 02111-1307 USA
'''
This extension provides X Protocol control over the VESA Display
Power Management Signaling (DPMS) characteristics of video boards
under control of the X Window System.
Documentation: https://www.x.org/releases/X11R7.7/doc/xextproto/dpms.html
'''
from Xlib.protocol import rq
extname = 'DPMS'
# DPMS Extension Power Levels
# 0 DPMSModeOn In use
# 1 DPMSModeStandby Blanked, low power
# 2 DPMSModeSuspend Blanked, lower power
# 3 DPMSModeOff Shut off, awaiting activity
DPMSModeOn = 0
DPMSModeStandby = 1
DPMSModeSuspend = 2
DPMSModeOff = 3
DPMSPowerLevel = (
DPMSModeOn,
DPMSModeStandby,
DPMSModeSuspend,
DPMSModeOff,
)
class DPMSGetVersion(rq.ReplyRequest):
_request = rq.Struct(
rq.Card8('opcode'),
rq.Opcode(0),
rq.RequestLength(),
rq.Card16('major_version'),
rq.Card16('minor_version'),
)
_reply = rq.Struct(
rq.ReplyCode(),
rq.Pad(1),
rq.Card16('sequence_number'),
rq.ReplyLength(),
rq.Card16('major_version'),
rq.Card16('minor_version'),
rq.Pad(20),
)
def get_version(self):
return DPMSGetVersion(display=self.display,
opcode=self.display.get_extension_major(extname),
major_version=1,
minor_version=1)
class DPMSCapable(rq.ReplyRequest):
_request = rq.Struct(
rq.Card8('opcode'),
rq.Opcode(1),
rq.RequestLength(),
)
_reply = rq.Struct(
rq.ReplyCode(),
rq.Pad(1),
rq.Card16('sequence_number'),
rq.ReplyLength(),
rq.Bool('capable'),
rq.Pad(23),
)
def capable(self):
return DPMSCapable(display=self.display,
opcode=self.display.get_extension_major(extname),
major_version=1,
minor_version=1)
class DPMSGetTimeouts(rq.ReplyRequest):
_request = rq.Struct(
rq.Card8('opcode'),
rq.Opcode(2),
rq.RequestLength(),
)
_reply = rq.Struct(
rq.ReplyCode(),
rq.Pad(1),
rq.Card16('sequence_number'),
rq.ReplyLength(),
rq.Card16('standby_timeout'),
rq.Card16('suspend_timeout'),
rq.Card16('off_timeout'),
rq.Pad(18),
)
def get_timeouts(self):
return DPMSGetTimeouts(display=self.display,
opcode=self.display.get_extension_major(extname),
major_version=1,
minor_version=1)
class DPMSSetTimeouts(rq.Request):
_request = rq.Struct(
rq.Card8('opcode'),
rq.Opcode(3),
rq.RequestLength(),
rq.Card16('standby_timeout'),
rq.Card16('suspend_timeout'),
rq.Card16('off_timeout'),
rq.Pad(2)
)
def set_timeouts(self, standby_timeout, suspend_timeout, off_timeout):
return DPMSSetTimeouts(display=self.display,
opcode=self.display.get_extension_major(extname),
major_version=1,
minor_version=1,
standby_timeout=standby_timeout,
suspend_timeout=suspend_timeout,
off_timeout=off_timeout)
class DPMSEnable(rq.Request):
_request = rq.Struct(
rq.Card8('opcode'),
rq.Opcode(4),
rq.RequestLength(),
)
def enable(self):
return DPMSEnable(display=self.display,
opcode=self.display.get_extension_major(extname),
major_version=1,
minor_version=1)
class DPMSDisable(rq.Request):
_request = rq.Struct(
rq.Card8('opcode'),
rq.Opcode(5),
rq.RequestLength(),
)
def disable(self):
return DPMSDisable(display=self.display,
opcode=self.display.get_extension_major(extname),
major_version=1,
minor_version=1)
class DPMSForceLevel(rq.Request):
_request = rq.Struct(
rq.Card8('opcode'),
rq.Opcode(6),
rq.RequestLength(),
rq.Resource('power_level', DPMSPowerLevel),
)
def force_level(self, power_level):
return DPMSForceLevel(display=self.display,
opcode=self.display.get_extension_major(extname),
major_version=1,
minor_version=1,
power_level=power_level)
class DPMSInfo(rq.ReplyRequest):
_request = rq.Struct(
rq.Card8('opcode'),
rq.Opcode(7),
rq.RequestLength(),
)
_reply = rq.Struct(
rq.ReplyCode(),
rq.Pad(1),
rq.Card16('sequence_number'),
rq.ReplyLength(),
rq.Card16('power_level'),
rq.Bool('state'),
rq.Pad(21),
)
def info(self):
return DPMSInfo(display=self.display,
opcode=self.display.get_extension_major(extname),
major_version=1,
minor_version=1)
def init(disp, _info):
disp.extension_add_method('display', 'dpms_get_version', get_version)
disp.extension_add_method('display', 'dpms_capable', capable)
disp.extension_add_method('display', 'dpms_get_timeouts', get_timeouts)
disp.extension_add_method('display', 'dpms_set_timeouts', set_timeouts)
disp.extension_add_method('display', 'dpms_enable', enable)
disp.extension_add_method('display', 'dpms_disable', disable)
disp.extension_add_method('display', 'dpms_force_level', force_level)
disp.extension_add_method('display', 'dpms_info', info)

View File

@@ -0,0 +1,112 @@
# Xlib.ext.ge -- Generic Event extension module
#
# Copyright (C) 2012 Outpost Embedded, LLC
# Forest Bond <forest.bond@rapidrollout.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public License
# as published by the Free Software Foundation; either version 2.1
# of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the
# Free Software Foundation, Inc.,
# 59 Temple Place,
# Suite 330,
# Boston, MA 02111-1307 USA
'''
ge - Generic Event Extension
'''
from Xlib.protocol import rq
extname = 'Generic Event Extension'
GenericEventCode = 35
class GEQueryVersion(rq.ReplyRequest):
_request = rq.Struct(
rq.Card8('opcode'),
rq.Opcode(0),
rq.RequestLength(),
rq.Card32('major_version'),
rq.Card32('minor_version'),
)
_reply = rq.Struct(
rq.ReplyCode(),
rq.Pad(1),
rq.Card16('sequence_number'),
rq.ReplyLength(),
rq.Card32('major_version'),
rq.Card32('minor_version'),
rq.Pad(16),
)
def query_version(self):
return GEQueryVersion(
display=self.display,
opcode=self.display.get_extension_major(extname),
major_version=1,
minor_version=0,
)
class GenericEvent(rq.Event):
_code = GenericEventCode
_fields = rq.Struct(
rq.Card8('type'),
rq.Card8('extension'),
rq.Card16('sequence_number'),
rq.Card32('length'),
rq.Card16('evtype'),
# Some generic events make use of this space, but with
# others the data is simply discarded. In any case we
# don't need to explicitly pad this out as we are
# always given at least 32 bytes and we save
# everything after the first ten as the "data" field.
#rq.Pad(22),
)
def __init__(self, binarydata = None, display = None, **keys):
if binarydata:
data = binarydata[10:]
binarydata = binarydata[:10]
else:
data = ''
rq.Event.__init__(
self,
binarydata=binarydata,
display=display,
**keys
)
if display:
ge_event_data = getattr(display, 'ge_event_data', None)
if ge_event_data:
estruct = ge_event_data.get((self.extension, self.evtype), None)
if estruct:
data, _ = estruct.parse_binary(data, display)
self._data['data'] = data
def add_event_data(self, extension, evtype, estruct):
if not hasattr(self.display, 'ge_event_data'):
self.display.ge_event_data = {}
self.display.ge_event_data[(extension, evtype)] = estruct
def init(disp, info):
disp.extension_add_method('display', 'ge_query_version', query_version)
disp.extension_add_method('display', 'ge_add_event_data', add_event_data)
disp.extension_add_event(GenericEventCode, GenericEvent)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,282 @@
# Xlib.ext.record -- RECORD extension module
#
# Copyright (C) 2006 Alex Badea <vamposdecampos@gmail.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public License
# as published by the Free Software Foundation; either version 2.1
# of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the
# Free Software Foundation, Inc.,
# 59 Temple Place,
# Suite 330,
# Boston, MA 02111-1307 USA
from Xlib.protocol import rq
extname = 'RECORD'
FromServerTime = 0x01
FromClientTime = 0x02
FromClientSequence = 0x04
CurrentClients = 1
FutureClients = 2
AllClients = 3
FromServer = 0
FromClient = 1
ClientStarted = 2
ClientDied = 3
StartOfData = 4
EndOfData = 5
Record_Range8 = rq.Struct(
rq.Card8('first'),
rq.Card8('last'))
Record_Range16 = rq.Struct(
rq.Card16('first'),
rq.Card16('last'))
Record_ExtRange = rq.Struct(
rq.Card8('major_range_first'),
rq.Card8('major_range_last'),
rq.Card16('minor_range_first'),
rq.Card16('minor_range_last'))
Record_Range = rq.Struct(
rq.Object('core_requests', Record_Range8),
rq.Object('core_replies', Record_Range8),
rq.Object('ext_requests', Record_ExtRange),
rq.Object('ext_replies', Record_ExtRange),
rq.Object('delivered_events', Record_Range8),
rq.Object('device_events', Record_Range8),
rq.Object('errors', Record_Range8),
rq.Bool('client_started'),
rq.Bool('client_died'))
Record_ClientInfo = rq.Struct(
rq.Card32('client_resource'),
rq.LengthOf('ranges', 4),
rq.List('ranges', Record_Range))
class RawField(rq.ValueField):
"""A field with raw data, stored as a string"""
structcode = None
def pack_value(self, val):
return val, len(val), None
def parse_binary_value(self, data, display, length, format):
return data, ''
class GetVersion(rq.ReplyRequest):
_request = rq.Struct(
rq.Card8('opcode'),
rq.Opcode(0),
rq.RequestLength(),
rq.Card16('major_version'),
rq.Card16('minor_version'))
_reply = rq.Struct(
rq.Pad(2),
rq.Card16('sequence_number'),
rq.ReplyLength(),
rq.Card16('major_version'),
rq.Card16('minor_version'),
rq.Pad(20))
def get_version(self, major, minor):
return GetVersion(
display = self.display,
opcode = self.display.get_extension_major(extname),
major_version = major,
minor_version = minor)
class CreateContext(rq.Request):
_request = rq.Struct(
rq.Card8('opcode'),
rq.Opcode(1),
rq.RequestLength(),
rq.Card32('context'), # Record_RC
rq.Card8('element_header'), # Record_Element_Header
rq.Pad(3),
rq.LengthOf('clients', 4),
rq.LengthOf('ranges', 4),
rq.List('clients', rq.Card32Obj),
rq.List('ranges', Record_Range))
def create_context(self, datum_flags, clients, ranges):
context = self.display.allocate_resource_id()
CreateContext(
display = self.display,
opcode = self.display.get_extension_major(extname),
context = context,
element_header = datum_flags,
clients = clients,
ranges = ranges)
return context
class RegisterClients(rq.Request):
_request = rq.Struct(
rq.Card8('opcode'),
rq.Opcode(2),
rq.RequestLength(),
rq.Card32('context'), # Record_RC
rq.Card8('element_header'), # Record_Element_Header
rq.Pad(3),
rq.LengthOf('clients', 4),
rq.LengthOf('ranges', 4),
rq.List('clients', rq.Card32Obj),
rq.List('ranges', Record_Range))
def register_clients(self, context, element_header, clients, ranges):
RegisterClients(
display = self.display,
opcode = self.display.get_extension_major(extname),
context = context,
element_header = element_header,
clients = clients,
ranges = ranges)
class UnregisterClients(rq.Request):
_request = rq.Struct(
rq.Card8('opcode'),
rq.Opcode(3),
rq.RequestLength(),
rq.Card32('context'), # Record_RC
rq.LengthOf('clients', 4),
rq.List('clients', rq.Card32Obj))
def unregister_clients(self, context, clients):
UnregisterClients(
display = self.display,
opcode = self.display.get_extension_major(extname),
context = context,
clients = clients)
class GetContext(rq.ReplyRequest):
_request = rq.Struct(
rq.Card8('opcode'),
rq.Opcode(4),
rq.RequestLength(),
rq.Card32('context')) # Record_RC
_reply = rq.Struct(
rq.Pad(2),
rq.Card16('sequence_number'),
rq.ReplyLength(),
rq.Card8('element_header'), # Record_Element_Header
rq.Pad(3),
rq.LengthOf('client_info', 4),
rq.Pad(16),
rq.List('client_info', Record_ClientInfo))
def get_context(self, context):
return GetContext(
display = self.display,
opcode = self.display.get_extension_major(extname),
context = context)
class EnableContext(rq.ReplyRequest):
_request = rq.Struct(
rq.Card8('opcode'),
rq.Opcode(5),
rq.RequestLength(),
rq.Card32('context')) # Record_RC
_reply = rq.Struct(
rq.Pad(1),
rq.Card8('category'),
rq.Card16('sequence_number'),
rq.ReplyLength(),
rq.Card8('element_header'), # Record_Element_Header
rq.Bool('client_swapped'),
rq.Pad(2),
rq.Card32('id_base'), # Record_XIDBase
rq.Card32('server_time'),
rq.Card32('recorded_sequence_number'),
rq.Pad(8),
RawField('data'))
# This request receives multiple responses, so we need to keep
# ourselves in the 'sent_requests' list in order to receive them all.
# See the discussion on ListFonstsWithInfo in request.py
def __init__(self, callback, *args, **keys):
self._callback = callback
rq.ReplyRequest.__init__(self, *args, **keys)
def _parse_response(self, data):
r, d = self._reply.parse_binary(data, self._display)
self._callback(r)
if r.category == StartOfData:
# Hack ourselves a sequence number, used by the code in
# Xlib.protocol.display.Display.parse_request_response()
self.sequence_number = r.sequence_number
if r.category == EndOfData:
self._response_lock.acquire()
self._data = r
self._response_lock.release()
else:
self._display.sent_requests.insert(0, self)
def enable_context(self, context, callback):
EnableContext(
callback = callback,
display = self.display,
opcode = self.display.get_extension_major(extname),
context = context)
class DisableContext(rq.Request):
_request = rq.Struct(
rq.Card8('opcode'),
rq.Opcode(6),
rq.RequestLength(),
rq.Card32('context')) # Record_RC
def disable_context(self, context):
DisableContext(
display = self.display,
opcode = self.display.get_extension_major(extname),
context = context)
class FreeContext(rq.Request):
_request = rq.Struct(
rq.Card8('opcode'),
rq.Opcode(7),
rq.RequestLength(),
rq.Card32('context')) # Record_RC
def free_context(self, context):
FreeContext(
display = self.display,
opcode = self.display.get_extension_major(extname),
context = context)
self.display.free_resource_id(context)
def init(disp, info):
disp.extension_add_method('display', 'record_get_version', get_version)
disp.extension_add_method('display', 'record_create_context', create_context)
disp.extension_add_method('display', 'record_register_clients', register_clients)
disp.extension_add_method('display', 'record_unregister_clients', unregister_clients)
disp.extension_add_method('display', 'record_get_context', get_context)
disp.extension_add_method('display', 'record_enable_context', enable_context)
disp.extension_add_method('display', 'record_disable_context', disable_context)
disp.extension_add_method('display', 'record_free_context', free_context)

View File

@@ -0,0 +1,288 @@
# Xlib.ext.res -- X-Resource extension module
#
# Copyright (C) 2021 Aleksei Bavshin <alebastr89@gmail.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public License
# as published by the Free Software Foundation; either version 2.1
# of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street,
# Fifth Floor,
# Boston, MA 02110-1301 USA
"""X-Resource extension allows a client to query the X server about its usage
of various resources.
For detailed description see any of the following documents.
Protocol specification:
https://www.x.org/releases/current/doc/resourceproto/resproto.txt
XCB Protocol specification:
https://cgit.freedesktop.org/xcb/proto/tree/src/res.xml
"""
from Xlib.protocol import rq
RES_MAJOR_VERSION = 1
RES_MINOR_VERSION = 2
extname = "X-Resource"
# v1.0
ResQueryVersion = 0
ResQueryClients = 1
ResQueryClientResources = 2
ResQueryClientPixmapBytes = 3
# v1.2
ResQueryClientIds = 4
ResQueryResourceBytes = 5
class QueryVersion(rq.ReplyRequest):
_request = rq.Struct(
rq.Card8("opcode"),
rq.Opcode(ResQueryVersion),
rq.RequestLength(),
rq.Card8("client_major"),
rq.Card8("client_minor"),
rq.Pad(2))
_reply = rq.Struct(
rq.ReplyCode(),
rq.Pad(1),
rq.Card16("sequence_number"),
rq.ReplyLength(),
rq.Card16("server_major"),
rq.Card16("server_minor"),
rq.Pad(20))
def query_version(self, client_major=RES_MAJOR_VERSION,
client_minor=RES_MINOR_VERSION):
""" Query the protocol version supported by the X server.
The client sends the highest supported version to the server and the
server sends the highest version it supports, but no higher than the
requested version."""
return QueryVersion(
display=self.display,
opcode=self.display.get_extension_major(extname),
client_major=client_major,
client_minor=client_minor)
Client = rq.Struct(
rq.Card32("resource_base"),
rq.Card32("resource_mask"))
class QueryClients(rq.ReplyRequest):
_request = rq.Struct(
rq.Card8("opcode"),
rq.Opcode(ResQueryClients),
rq.RequestLength())
_reply = rq.Struct(
rq.ReplyCode(),
rq.Pad(1),
rq.Card16("sequence_number"),
rq.ReplyLength(),
rq.LengthOf("clients", 4),
rq.Pad(20),
rq.List("clients", Client))
def query_clients(self):
"""Request the list of all currently connected clients."""
return QueryClients(
display=self.display,
opcode=self.display.get_extension_major(extname))
Type = rq.Struct(
rq.Card32("resource_type"),
rq.Card32("count"))
class QueryClientResources(rq.ReplyRequest):
_request = rq.Struct(
rq.Card8("opcode"),
rq.Opcode(ResQueryClientResources),
rq.RequestLength(),
rq.Card32("client"))
_reply = rq.Struct(
rq.ReplyCode(),
rq.Pad(1),
rq.Card16("sequence_number"),
rq.ReplyLength(),
rq.LengthOf("types", 4),
rq.Pad(20),
rq.List("types", Type))
def query_client_resources(self, client):
"""Request the number of resources owned by a client.
The server will return the counts of each type of resource.
"""
return QueryClientResources(
display=self.display,
opcode=self.display.get_extension_major(extname),
client=client)
class QueryClientPixmapBytes(rq.ReplyRequest):
_request = rq.Struct(
rq.Card8("opcode"),
rq.Opcode(ResQueryClientPixmapBytes),
rq.RequestLength(),
rq.Card32("client"))
_reply = rq.Struct(
rq.ReplyCode(),
rq.Pad(1),
rq.Card16("sequence_number"),
rq.ReplyLength(),
rq.Card32("bytes"),
rq.Card32("bytes_overflow"),
rq.Pad(16))
def query_client_pixmap_bytes(self, client):
"""Query the pixmap usage of some client.
The returned number is a sum of memory usage of each pixmap that can be
attributed to the given client.
"""
return QueryClientPixmapBytes(
display=self.display,
opcode=self.display.get_extension_major(extname),
client=client)
class SizeOf(rq.LengthOf):
"""A SizeOf stores the size in bytes of some other Field whose size
may vary, e.g. List
"""
def __init__(self, name, size, item_size):
rq.LengthOf.__init__(self, name, size)
self.item_size = item_size
def parse_value(self, length, display):
return length // self.item_size
ClientXIDMask = 1 << 0
LocalClientPIDMask = 1 << 1
ClientIdSpec = rq.Struct(
rq.Card32("client"),
rq.Card32("mask"))
ClientIdValue = rq.Struct(
rq.Object("spec", ClientIdSpec),
SizeOf("value", 4, 4),
rq.List("value", rq.Card32Obj))
class QueryClientIds(rq.ReplyRequest):
_request = rq.Struct(
rq.Card8("opcode"),
rq.Opcode(ResQueryClientIds),
rq.RequestLength(),
rq.LengthOf("specs", 4),
rq.List("specs", ClientIdSpec))
_reply = rq.Struct(
rq.ReplyCode(),
rq.Pad(1),
rq.Card16("sequence_number"),
rq.ReplyLength(),
rq.LengthOf("ids", 4),
rq.Pad(20),
rq.List("ids", ClientIdValue))
def query_client_ids(self, specs):
"""Request to identify a given set of clients with some identification method.
The request sends a list of specifiers that select clients and
identification methods to server. The server then tries to identify the
chosen clients using the identification methods specified for each client.
The server returns IDs for those clients that were successfully identified.
"""
return QueryClientIds(
display=self.display,
opcode=self.display.get_extension_major(extname),
specs=specs)
ResourceIdSpec = rq.Struct(
rq.Card32("resource"),
rq.Card32("type"))
ResourceSizeSpec = rq.Struct(
# inline struct ResourceIdSpec to work around
# a parser bug with nested objects
rq.Card32("resource"),
rq.Card32("type"),
rq.Card32("bytes"),
rq.Card32("ref_count"),
rq.Card32("use_count"))
ResourceSizeValue = rq.Struct(
rq.Object("size", ResourceSizeSpec),
rq.LengthOf("cross_references", 4),
rq.List("cross_references", ResourceSizeSpec))
class QueryResourceBytes(rq.ReplyRequest):
_request = rq.Struct(
rq.Card8("opcode"),
rq.Opcode(ResQueryResourceBytes),
rq.RequestLength(),
rq.Card32("client"),
rq.LengthOf("specs", 4),
rq.List("specs", ResourceIdSpec))
_reply = rq.Struct(
rq.ReplyCode(),
rq.Pad(1),
rq.Card16("sequence_number"),
rq.ReplyLength(),
rq.LengthOf("sizes", 4),
rq.Pad(20),
rq.List("sizes", ResourceSizeValue))
def query_resource_bytes(self, client, specs):
"""Query the sizes of resources from X server.
The request sends a list of specifiers that selects resources for size
calculation. The server tries to calculate the sizes of chosen resources
and returns an estimate for a resource only if the size could be determined
"""
return QueryResourceBytes(
display=self.display,
opcode=self.display.get_extension_major(extname),
client=client,
specs=specs)
def init(disp, info):
disp.extension_add_method("display", "res_query_version", query_version)
disp.extension_add_method("display", "res_query_clients", query_clients)
disp.extension_add_method("display", "res_query_client_resources",
query_client_resources)
disp.extension_add_method("display", "res_query_client_pixmap_bytes",
query_client_pixmap_bytes)
disp.extension_add_method("display", "res_query_client_ids",
query_client_ids)
disp.extension_add_method("display", "res_query_resource_bytes",
query_resource_bytes)

View File

@@ -0,0 +1,198 @@
# Xlib.ext.screensaver -- X ScreenSaver extension module
#
# Copyright (C) 2022 Vladimir Panteleev <git@cy.md>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public License
# as published by the Free Software Foundation; either version 2.1
# of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street,
# Fifth Floor,
# Boston, MA 02110-1301 USA
"""This extension allows registering the client as an X screensaver,
or query information about the current screensaver.
For detailed description see any of the following documents.
Protocol specification:
https://www.x.org/releases/X11R7.7/doc/scrnsaverproto/saver.html
XCB Protocol specification:
https://cgit.freedesktop.org/xcb/proto/tree/src/screensaver.xml
"""
from Xlib import X
from Xlib.protocol import rq, structs
extname = 'MIT-SCREEN-SAVER'
# Event members
NotifyMask = 1
CycleMask = 2
# Notify state
StateOff = 0
StateOn = 1
StateCycle = 2
# Notify kind
KindBlanked = 0
KindInternal = 1
KindExternal = 2
class QueryVersion(rq.ReplyRequest):
_request = rq.Struct(
rq.Card8('opcode'),
rq.Opcode(0),
rq.RequestLength(),
rq.Card8('major_version'),
rq.Card8('minor_version'),
rq.Pad(2),
)
_reply = rq.Struct(
rq.ReplyCode(),
rq.Pad(1),
rq.Card16('sequence_number'),
rq.ReplyLength(),
rq.Card16('major_version'),
rq.Card16('minor_version'),
rq.Pad(20),
)
def query_version(self):
return QueryVersion(display=self.display,
opcode=self.display.get_extension_major(extname),
major_version=1,
minor_version=0)
class QueryInfo(rq.ReplyRequest):
_request = rq.Struct(
rq.Card8('opcode'),
rq.Opcode(1),
rq.RequestLength(),
rq.Drawable('drawable'),
)
_reply = rq.Struct(
rq.ReplyCode(),
rq.Card8('state'),
rq.Card16('sequence_number'),
rq.ReplyLength(),
rq.Window('saver_window'),
rq.Card32('til_or_since'),
rq.Card32('idle'),
rq.Card32('event_mask'), # rq.Set('event_mask', 4, (NotifyMask, CycleMask)),
rq.Card8('kind'),
rq.Pad(7),
)
def query_info(self):
return QueryInfo(display=self.display,
opcode=self.display.get_extension_major(extname),
drawable=self,
)
class SelectInput(rq.Request):
_request = rq.Struct(
rq.Card8('opcode'),
rq.Opcode(2),
rq.RequestLength(),
rq.Drawable('drawable'),
rq.Card32('event_mask'), # rq.Set('event_mask', 4, (NotifyMask, CycleMask)),
)
def select_input(self, mask):
return SelectInput(display=self.display,
opcode=self.display.get_extension_major(extname),
drawable=self,
event_mask=mask,
)
class SetAttributes(rq.Request):
_request = rq.Struct(
rq.Card8('opcode'),
rq.Opcode(3),
rq.RequestLength(),
rq.Drawable('drawable'),
rq.Int16('x'),
rq.Int16('y'),
rq.Card16('width'),
rq.Card16('height'),
rq.Card16('border_width'),
rq.Set('window_class', 1, (X.CopyFromParent, X.InputOutput, X.InputOnly)),
rq.Card8('depth'),
rq.Card32('visual'),
structs.WindowValues('attrs'),
)
def set_attributes(self, x, y, width, height, border_width,
window_class = X.CopyFromParent,
depth = X.CopyFromParent,
visual = X.CopyFromParent,
onerror = None,
**keys):
return SetAttributes(display=self.display,
onerror = onerror,
opcode=self.display.get_extension_major(extname),
drawable=self,
x = x,
y = y,
width = width,
height = height,
border_width = border_width,
window_class = window_class,
depth = depth,
visual = visual,
attrs = keys)
class UnsetAttributes(rq.Request):
_request = rq.Struct(
rq.Card8('opcode'),
rq.Opcode(4),
rq.RequestLength(),
rq.Drawable('drawable'),
)
def unset_attributes(self, onerror = None):
return UnsetAttributes(display=self.display,
onerror = onerror,
opcode=self.display.get_extension_major(extname),
drawable=self)
class Notify(rq.Event):
_code = None
_fields = rq.Struct(
rq.Card8('type'),
rq.Set('state', 1, (StateOff, StateOn, StateCycle)),
rq.Card16('sequence_number'),
rq.Card32('timestamp'),
rq.Window('root'),
rq.Window('window'),
rq.Set('kind', 1, (KindBlanked, KindInternal, KindExternal)),
rq.Bool('forced'),
rq.Pad(14),
)
def init(disp, info):
disp.extension_add_method('display', 'screensaver_query_version', query_version)
disp.extension_add_method('drawable', 'screensaver_query_info', query_info)
disp.extension_add_method('drawable', 'screensaver_select_input', select_input)
disp.extension_add_method('drawable', 'screensaver_set_attributes', set_attributes)
disp.extension_add_method('drawable', 'screensaver_unset_attributes', unset_attributes)
disp.extension_add_event(info.first_event + 0, Notify)

View File

@@ -0,0 +1,139 @@
# Xlib.ext.security -- SECURITY extension module
#
# Copyright (C) 2010-2013 Outpost Embedded, LLC
# Forest Bond <forest.bond@rapidrollout.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public License
# as published by the Free Software Foundation; either version 2.1
# of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the
# Free Software Foundation, Inc.,
# 59 Temple Place,
# Suite 330,
# Boston, MA 02111-1307 USA
'''
A partial implementation of the SECURITY extension. Support for the
SecurityAuthorizationRevoked event is not implemented.
'''
from Xlib.protocol import rq
extname = 'SECURITY'
SecurityClientTrusted = 0
SecurityClientUntrusted = 1
SecurityAuthorizationRevokedMask = 1
AUTHID = rq.Card32
class QueryVersion(rq.ReplyRequest):
_request = rq.Struct(rq.Card8('opcode'),
rq.Opcode(0),
rq.RequestLength(),
rq.Card16('major_version'),
rq.Card16('minor_version')
)
_reply = rq.Struct(rq.ReplyCode(),
rq.Pad(1),
rq.Card16('sequence_number'),
rq.ReplyLength(),
rq.Card16('major_version'),
rq.Card16('minor_version'),
rq.Pad(20)
)
def query_version(self):
return QueryVersion(display=self.display,
opcode=self.display.get_extension_major(extname),
major_version=1,
minor_version=0)
class SecurityGenerateAuthorization(rq.ReplyRequest):
# The order of fields here does not match the specifications I've seen
# online, but it *does* match with the X.org implementation. I guess the
# spec is out-of-date.
_request = rq.Struct(rq.Card8('opcode'),
rq.Opcode(1),
rq.RequestLength(),
rq.LengthOf('auth_proto', 2),
rq.LengthOf('auth_data', 2),
rq.Card32('value_mask'),
rq.String8('auth_proto'),
rq.Binary('auth_data'),
rq.List('values', rq.Card32Obj)
)
_reply = rq.Struct(rq.ReplyCode(),
rq.Pad(1),
rq.Card16('sequence_number'),
rq.ReplyLength(),
AUTHID('authid'),
rq.LengthOf('auth_data_return', 2),
rq.Pad(18),
rq.Binary('auth_data_return')
)
def generate_authorization(self, auth_proto, auth_data=b'', timeout=None,
trust_level=None, group=None, event_mask=None):
value_mask = 0
values = []
if timeout is not None:
value_mask |= 1
values.append(timeout)
if trust_level is not None:
value_mask |= 2
values.append(trust_level)
if group is not None:
value_mask |= 4
values.append(group)
if event_mask is not None:
value_mask |= 8
values.append(event_mask)
return SecurityGenerateAuthorization(display=self.display,
opcode=self.display.get_extension_major(extname),
value_mask=value_mask,
auth_proto=auth_proto,
auth_data=auth_data,
values=values)
class SecurityRevokeAuthorization(rq.Request):
_request = rq.Struct(rq.Card8('opcode'),
rq.Opcode(2),
rq.RequestLength(),
AUTHID('authid')
)
def revoke_authorization(self, authid):
return SecurityRevokeAuthorization(display=self.display,
opcode=self.display.get_extension_major(extname),
authid=authid)
def init(disp, info):
disp.extension_add_method('display',
'security_query_version',
query_version)
disp.extension_add_method('display',
'security_generate_authorization',
generate_authorization)
disp.extension_add_method('display',
'security_revoke_authorization',
revoke_authorization)

View File

@@ -0,0 +1,297 @@
# Automatically generated file; DO NOT EDIT.
# Generated from: /usr/share/xcb/shape.xml
from Xlib.protocol import rq, structs
extname = 'SHAPE'
OP = rq.Card8
class SO:
Set = 0
Union = 1
Intersect = 2
Subtract = 3
Invert = 4
class SK:
Bounding = 0
Clip = 1
Input = 2
class KIND(rq.Set):
def __init__(self, name):
super(KIND, self).__init__(name, 1,
values=(SK.Bounding,
SK.Clip,
SK.Input))
class NotifyEventData(rq.Event):
_code = None
_fields = rq.Struct(
rq.Card8('type'),
KIND('shape_kind'),
rq.Card16('sequence_number'),
rq.Window('affected_window'),
rq.Int16('extents_x'),
rq.Int16('extents_y'),
rq.Card16('extents_width'),
rq.Card16('extents_height'),
rq.Card32('server_time'),
rq.Card8('shaped'),
rq.Pad(11),
)
class QueryVersion(rq.ReplyRequest):
_request = rq.Struct(
rq.Card8('opcode'),
rq.Opcode(0),
rq.RequestLength(),
)
_reply = rq.Struct(
rq.ReplyCode(),
rq.Pad(1),
rq.Card16('sequence_number'),
rq.ReplyLength(),
rq.Card16('major_version'),
rq.Card16('minor_version'),
)
class Rectangles(rq.Request):
_request = rq.Struct(
rq.Card8('opcode'),
rq.Opcode(1),
rq.RequestLength(),
OP('operation'),
KIND('destination_kind'),
rq.Card8('ordering'),
rq.Pad(1),
rq.Window('destination_window'),
rq.Int16('x_offset'),
rq.Int16('y_offset'),
rq.List('rectangles', structs.Rectangle, pad=0),
)
class Mask(rq.Request):
_request = rq.Struct(
rq.Card8('opcode'),
rq.Opcode(2),
rq.RequestLength(),
OP('operation'),
KIND('destination_kind'),
rq.Pad(2),
rq.Window('destination_window'),
rq.Int16('x_offset'),
rq.Int16('y_offset'),
rq.Pixmap('source_bitmap'),
)
class Combine(rq.Request):
_request = rq.Struct(
rq.Card8('opcode'),
rq.Opcode(3),
rq.RequestLength(),
OP('operation'),
KIND('destination_kind'),
KIND('source_kind'),
rq.Pad(1),
rq.Window('destination_window'),
rq.Int16('x_offset'),
rq.Int16('y_offset'),
rq.Window('source_window'),
)
class Offset(rq.Request):
_request = rq.Struct(
rq.Card8('opcode'),
rq.Opcode(4),
rq.RequestLength(),
KIND('destination_kind'),
rq.Pad(3),
rq.Window('destination_window'),
rq.Int16('x_offset'),
rq.Int16('y_offset'),
)
class QueryExtents(rq.ReplyRequest):
_request = rq.Struct(
rq.Card8('opcode'),
rq.Opcode(5),
rq.RequestLength(),
rq.Window('destination_window'),
)
_reply = rq.Struct(
rq.ReplyCode(),
rq.Pad(1),
rq.Card16('sequence_number'),
rq.ReplyLength(),
rq.Card8('bounding_shaped'),
rq.Card8('clip_shaped'),
rq.Pad(2),
rq.Int16('bounding_shape_extents_x'),
rq.Int16('bounding_shape_extents_y'),
rq.Card16('bounding_shape_extents_width'),
rq.Card16('bounding_shape_extents_height'),
rq.Int16('clip_shape_extents_x'),
rq.Int16('clip_shape_extents_y'),
rq.Card16('clip_shape_extents_width'),
rq.Card16('clip_shape_extents_height'),
)
class SelectInput(rq.Request):
_request = rq.Struct(
rq.Card8('opcode'),
rq.Opcode(6),
rq.RequestLength(),
rq.Window('destination_window'),
rq.Card8('enable'),
rq.Pad(3),
)
class InputSelected(rq.ReplyRequest):
_request = rq.Struct(
rq.Card8('opcode'),
rq.Opcode(7),
rq.RequestLength(),
rq.Window('destination_window'),
)
_reply = rq.Struct(
rq.ReplyCode(),
rq.Card8('enabled'),
rq.Card16('sequence_number'),
rq.ReplyLength(),
)
class GetRectangles(rq.ReplyRequest):
_request = rq.Struct(
rq.Card8('opcode'),
rq.Opcode(8),
rq.RequestLength(),
rq.Window('window'),
KIND('source_kind'),
rq.Pad(3),
)
_reply = rq.Struct(
rq.ReplyCode(),
rq.Card8('ordering'),
rq.Card16('sequence_number'),
rq.ReplyLength(),
rq.LengthOf('rectangles', 4),
rq.Pad(20),
rq.List('rectangles', structs.Rectangle, pad=0),
)
class Event:
# Sub events.
Notify = 0
def combine(self, operation, destination_kind, source_kind, x_offset, y_offset):
Combine(
display=self.display,
opcode=self.display.get_extension_major(extname),
source_window=self,
operation=operation,
destination_kind=destination_kind,
source_kind=source_kind,
x_offset=x_offset,
y_offset=y_offset,
)
def get_rectangles(self, source_kind):
return GetRectangles(
display=self.display,
opcode=self.display.get_extension_major(extname),
window=self,
source_kind=source_kind,
)
def input_selected(self, ):
return InputSelected(
display=self.display,
opcode=self.display.get_extension_major(extname),
destination_window=self,
)
def mask(self, operation, destination_kind, x_offset, y_offset, source_bitmap):
Mask(
display=self.display,
opcode=self.display.get_extension_major(extname),
destination_window=self,
operation=operation,
destination_kind=destination_kind,
x_offset=x_offset,
y_offset=y_offset,
source_bitmap=source_bitmap,
)
def offset(self, destination_kind, x_offset, y_offset):
Offset(
display=self.display,
opcode=self.display.get_extension_major(extname),
destination_window=self,
destination_kind=destination_kind,
x_offset=x_offset,
y_offset=y_offset,
)
def query_extents(self, ):
return QueryExtents(
display=self.display,
opcode=self.display.get_extension_major(extname),
destination_window=self,
)
def query_version(self, ):
return QueryVersion(
display=self.display,
opcode=self.display.get_extension_major(extname),
)
def rectangles(self, operation, destination_kind, ordering, x_offset, y_offset, rectangles):
Rectangles(
display=self.display,
opcode=self.display.get_extension_major(extname),
destination_window=self,
operation=operation,
destination_kind=destination_kind,
ordering=ordering,
x_offset=x_offset,
y_offset=y_offset,
rectangles=rectangles,
)
def select_input(self, enable):
SelectInput(
display=self.display,
opcode=self.display.get_extension_major(extname),
destination_window=self,
enable=enable,
)
def init(disp, info):
disp.extension_add_method('window', 'shape_combine', combine)
disp.extension_add_method('window', 'shape_get_rectangles', get_rectangles)
disp.extension_add_method('window', 'shape_input_selected', input_selected)
disp.extension_add_method('window', 'shape_mask', mask)
disp.extension_add_method('window', 'shape_offset', offset)
disp.extension_add_method('window', 'shape_query_extents', query_extents)
disp.extension_add_method('display', 'shape_query_version', query_version)
disp.extension_add_method('window', 'shape_rectangles', rectangles)
disp.extension_add_method('window', 'shape_select_input', select_input)
disp.extension_add_event(info.first_event + Event.Notify, NotifyEventData, 'ShapeNotify')

View File

@@ -0,0 +1,200 @@
# Xlib.ext.xfixes -- XFIXES extension module
#
# Copyright (C) 2010-2011 Outpost Embedded, LLC
# Forest Bond <forest.bond@rapidrollout.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public License
# as published by the Free Software Foundation; either version 2.1
# of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the
# Free Software Foundation, Inc.,
# 59 Temple Place,
# Suite 330,
# Boston, MA 02111-1307 USA
'''
A partial implementation of the XFIXES extension. Only the HideCursor and
ShowCursor requests and SelectionNotify events are provided.
'''
from Xlib.protocol import rq
extname = 'XFIXES'
XFixesSelectionNotify = 0
XFixesCursorNotify = 1
XFixesSetSelectionOwnerNotifyMask = (1 << 0)
XFixesSelectionWindowDestroyNotifyMask = (1 << 1)
XFixesSelectionClientCloseNotifyMask = (1 << 2)
XFixesDisplayCursorNotifyMask = (1 << 0)
XFixesSetSelectionOwnerNotify = 0
XFixesSelectionWindowDestroyNotify = 1
XFixesSelectionClientCloseNotify = 2
XFixesDisplayCursorNotify = 0
class QueryVersion(rq.ReplyRequest):
_request = rq.Struct(rq.Card8('opcode'),
rq.Opcode(0),
rq.RequestLength(),
rq.Card32('major_version'),
rq.Card32('minor_version')
)
_reply = rq.Struct(rq.ReplyCode(),
rq.Pad(1),
rq.Card16('sequence_number'),
rq.ReplyLength(),
rq.Card32('major_version'),
rq.Card32('minor_version'),
rq.Pad(16)
)
def query_version(self):
return QueryVersion(display=self.display,
opcode=self.display.get_extension_major(extname),
major_version=4,
minor_version=0)
class HideCursor(rq.Request):
_request = rq.Struct(rq.Card8('opcode'),
rq.Opcode(29),
rq.RequestLength(),
rq.Window('window')
)
def hide_cursor(self):
HideCursor(display=self.display,
opcode=self.display.get_extension_major(extname),
window=self)
class ShowCursor(rq.Request):
_request = rq.Struct(rq.Card8('opcode'),
rq.Opcode(30),
rq.RequestLength(),
rq.Window('window')
)
def show_cursor(self):
ShowCursor(display=self.display,
opcode=self.display.get_extension_major(extname),
window=self)
class SelectSelectionInput(rq.Request):
_request = rq.Struct(rq.Card8('opcode'),
rq.Opcode(2),
rq.RequestLength(),
rq.Window('window'),
rq.Card32('selection'),
rq.Card32('mask')
)
def select_selection_input(self, window, selection, mask):
return SelectSelectionInput(opcode=self.display.get_extension_major(extname),
display=self.display,
window=window,
selection=selection,
mask=mask)
class SelectionNotify(rq.Event):
_code = None
_fields = rq.Struct(rq.Card8('type'),
rq.Card8('sub_code'),
rq.Card16('sequence_number'),
rq.Window('window'),
rq.Window('owner'),
rq.Card32('selection'),
rq.Card32('timestamp'),
rq.Card32('selection_timestamp'),
rq.Pad(8))
class SetSelectionOwnerNotify(SelectionNotify):
pass
class SelectionWindowDestroyNotify(SelectionNotify):
pass
class SelectionClientCloseNotify(SelectionNotify):
pass
class SelectCursorInput(rq.Request):
_request = rq.Struct(rq.Card8('opcode'),
rq.Opcode(3),
rq.RequestLength(),
rq.Window('window'),
rq.Card32('mask')
)
def select_cursor_input(self, window, mask):
return SelectCursorInput(opcode=self.display.get_extension_major(extname),
display=self.display,
window=window,
cursor_serial=0,
mask=mask)
class GetCursorImage(rq.ReplyRequest):
_request = rq.Struct(rq.Card8('opcode'),
rq.Opcode(4),
rq.RequestLength()
)
_reply = rq.Struct(rq.ReplyCode(),
rq.Pad(1),
rq.Card16('sequence_number'),
rq.ReplyLength(),
rq.Int16('x'),
rq.Int16('y'),
rq.Card16('width'),
rq.Card16('height'),
rq.Card16('xhot'),
rq.Card16('yhot'),
rq.Card32('cursor_serial'),
rq.Pad(8),
rq.List('cursor_image', rq.Card32)
)
def get_cursor_image(self, window):
return GetCursorImage(opcode=self.display.get_extension_major(extname),
display=self.display,
)
class DisplayCursorNotify(rq.Event):
_code = None
_fields = rq.Struct(rq.Card8('type'),
rq.Card8('sub_code'),
rq.Card16('sequence_number'),
rq.Window('window'),
rq.Card32('cursor_serial'),
rq.Card32('timestamp'))
def init(disp, info):
disp.extension_add_method('display', 'xfixes_select_selection_input', select_selection_input)
disp.extension_add_method('display', 'xfixes_query_version', query_version)
disp.extension_add_method('window', 'xfixes_hide_cursor', hide_cursor)
disp.extension_add_method('window', 'xfixes_show_cursor', show_cursor)
disp.extension_add_method('display', 'xfixes_select_cursor_input', select_cursor_input)
disp.extension_add_method('display', 'xfixes_get_cursor_image', get_cursor_image)
disp.extension_add_subevent(info.first_event + XFixesSelectionNotify, XFixesSetSelectionOwnerNotify, SetSelectionOwnerNotify)
disp.extension_add_subevent(info.first_event + XFixesSelectionNotify, XFixesSelectionWindowDestroyNotify, SelectionWindowDestroyNotify)
disp.extension_add_subevent(info.first_event + XFixesSelectionNotify, XFixesSelectionClientCloseNotify, SelectionClientCloseNotify)
disp.extension_add_subevent(info.first_event + XFixesCursorNotify, XFixesDisplayCursorNotify, DisplayCursorNotify)

View File

@@ -0,0 +1,222 @@
# Xlib.ext.xinerama -- Xinerama extension module
#
# Copyright (C) 2006 Mike Meyer <mwm@mired.org>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public License
# as published by the Free Software Foundation; either version 2.1
# of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the
# Free Software Foundation, Inc.,
# 59 Temple Place,
# Suite 330,
# Boston, MA 02111-1307 USA
"""Xinerama - provide access to the Xinerama extension information.
There are at least there different - and mutually incomparable -
Xinerama extensions available. This uses the one bundled with XFree86
4.6 and/or Xorg 6.9 in the ati/radeon driver. It uses the include
files from that X distribution, so should work with it as well. I
provide code for the lone Sun 1.0 request that isn't part of 1.1, but
this is untested because I don't have a server that implements it.
The functions loosely follow the libXineram functions. Mostly, they
return an rq.Struct in lieu of passing in pointers that get data from
the rq.Struct crammed into them. The exception is isActive, which
returns the state information - because that's what libXinerama does."""
from Xlib.protocol import rq, structs
extname = 'XINERAMA'
class QueryVersion(rq.ReplyRequest):
_request = rq.Struct(
rq.Card8('opcode'),
rq.Opcode(0),
rq.RequestLength(),
rq.Card8('major_version'),
rq.Card8('minor_version'),
rq.Pad(2),
)
_reply = rq.Struct(
rq.ReplyCode(),
rq.Pad(1),
rq.Card16('sequence_number'),
rq.ReplyLength(),
rq.Card16('major_version'),
rq.Card16('minor_version'),
rq.Pad(20),
)
def query_version(self):
return QueryVersion(display=self.display,
opcode=self.display.get_extension_major(extname),
major_version=1,
minor_version=1)
class GetState(rq.ReplyRequest):
_request = rq.Struct(
rq.Card8('opcode'),
rq.Opcode(1),
rq.RequestLength(),
rq.Window('window'),
)
_reply = rq.Struct(
rq.ReplyCode(),
rq.Bool('state'),
rq.Card16('sequence_number'),
rq.ReplyLength(),
rq.Window('window'),
rq.Pad(20),
)
def get_state(self):
return GetState(display=self.display,
opcode=self.display.get_extension_major(extname),
window=self.id,
)
class GetScreenCount(rq.ReplyRequest):
_request = rq.Struct(
rq.Card8('opcode'),
rq.Opcode(2),
rq.RequestLength(),
rq.Window('window'),
)
_reply = rq.Struct(
rq.ReplyCode(),
rq.Card8('screen_count'),
rq.Card16('sequence_number'),
rq.ReplyLength(),
rq.Window('window'),
rq.Pad(20),
)
def get_screen_count(self):
return GetScreenCount(display=self.display,
opcode=self.display.get_extension_major(extname),
window=self.id,
)
class GetScreenSize(rq.ReplyRequest):
_request = rq.Struct(
rq.Card8('opcode'),
rq.Opcode(3),
rq.RequestLength(),
rq.Window('window'),
rq.Card32('screen'),
)
_reply = rq.Struct(
rq.ReplyCode(),
rq.Pad(1),
rq.Card16('sequence_number'),
rq.Card32('length'),
rq.Card32('width'),
rq.Card32('height'),
rq.Window('window'),
rq.Card32('screen'),
rq.Pad(8),
)
def get_screen_size(self, screen_no):
"""Returns the size of the given screen number"""
return GetScreenSize(display=self.display,
opcode=self.display.get_extension_major(extname),
window=self.id,
screen=screen_no,
)
# IsActive is only available from Xinerama 1.1 and later.
# It should be used in preference to GetState.
class IsActive(rq.ReplyRequest):
_request = rq.Struct(
rq.Card8('opcode'),
rq.Opcode(4),
rq.RequestLength(),
)
_reply = rq.Struct(
rq.ReplyCode(),
rq.Pad(1),
rq.Card16('sequence_number'),
rq.ReplyLength(),
rq.Card32('state'),
rq.Pad(20),
)
def is_active(self):
r = IsActive(display=self.display,
opcode=self.display.get_extension_major(extname),
)
return r.state
# QueryScreens is only available from Xinerama 1.1 and later
class QueryScreens(rq.ReplyRequest):
_request = rq.Struct(
rq.Card8('opcode'),
rq.Opcode(5),
rq.RequestLength(),
)
_reply = rq.Struct(
rq.ReplyCode(),
rq.Pad(1),
rq.Card16('sequence_number'),
rq.ReplyLength(),
rq.Card32('number'),
rq.Pad(20),
rq.List('screens', structs.Rectangle),
)
def query_screens(self):
# Hmm. This one needs to read the screen data from the socket. Ooops...
return QueryScreens(display=self.display,
opcode=self.display.get_extension_major(extname),
)
# GetInfo is only available from some Xinerama 1.0, and *NOT* later! Untested
class GetInfo(rq.ReplyRequest):
_request = rq.Struct(
rq.Card8('opcode'),
rq.Opcode(4),
rq.RequestLength(),
rq.Card32('visual'),
)
_reply = rq.Struct(
rq.ReplyCode(),
rq.Pad(1),
rq.Card16('sequence_number'),
rq.ReplyLength(),
rq.Window('window'),
# An array of subwindow slots goes here. Bah.
)
def get_info(self, visual):
r = GetInfo(display=self.display,
opcode=self.display.get_extension_major(extname),
visual=visual)
def init(disp, info):
disp.extension_add_method('display', 'xinerama_query_version', query_version)
disp.extension_add_method('window', 'xinerama_get_state', get_state)
disp.extension_add_method('window', 'xinerama_get_screen_count', get_screen_count)
disp.extension_add_method('window', 'xinerama_get_screen_size', get_screen_size)
disp.extension_add_method('display', 'xinerama_is_active', is_active)
disp.extension_add_method('display', 'xinerama_query_screens', query_screens)
disp.extension_add_method('display', 'xinerama_get_info', get_info)

View File

@@ -0,0 +1,777 @@
# Xlib.ext.xinput -- XInput extension module
#
# Copyright (C) 2012 Outpost Embedded, LLC
# Forest Bond <forest.bond@rapidrollout.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public License
# as published by the Free Software Foundation; either version 2.1
# of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the
# Free Software Foundation, Inc.,
# 59 Temple Place,
# Suite 330,
# Boston, MA 02111-1307 USA
'''
A very incomplete implementation of the XInput extension.
'''
import sys
import array
import struct
# Python 2/3 compatibility.
from six import integer_types
from Xlib.protocol import rq
from Xlib import X
extname = 'XInputExtension'
PropertyDeleted = 0
PropertyCreated = 1
PropertyModified = 2
NotifyNormal = 0
NotifyGrab = 1
NotifyUngrab = 2
NotifyWhileGrabbed = 3
NotifyPassiveGrab = 4
NotifyPassiveUngrab = 5
NotifyAncestor = 0
NotifyVirtual = 1
NotifyInferior = 2
NotifyNonlinear = 3
NotifyNonlinearVirtual = 4
NotifyPointer = 5
NotifyPointerRoot = 6
NotifyDetailNone = 7
GrabtypeButton = 0
GrabtypeKeycode = 1
GrabtypeEnter = 2
GrabtypeFocusIn = 3
GrabtypeTouchBegin = 4
AnyModifier = (1 << 31)
AnyButton = 0
AnyKeycode = 0
AsyncDevice = 0
SyncDevice = 1
ReplayDevice = 2
AsyncPairedDevice = 3
AsyncPair = 4
SyncPair = 5
SlaveSwitch = 1
DeviceChange = 2
MasterAdded = (1 << 0)
MasterRemoved = (1 << 1)
SlaveAdded = (1 << 2)
SlaveRemoved = (1 << 3)
SlaveAttached = (1 << 4)
SlaveDetached = (1 << 5)
DeviceEnabled = (1 << 6)
DeviceDisabled = (1 << 7)
AddMaster = 1
RemoveMaster = 2
AttachSlave = 3
DetachSlave = 4
AttachToMaster = 1
Floating = 2
ModeRelative = 0
ModeAbsolute = 1
MasterPointer = 1
MasterKeyboard = 2
SlavePointer = 3
SlaveKeyboard = 4
FloatingSlave = 5
KeyClass = 0
ButtonClass = 1
ValuatorClass = 2
ScrollClass = 3
TouchClass = 8
KeyRepeat = (1 << 16)
AllDevices = 0
AllMasterDevices = 1
DeviceChanged = 1
KeyPress = 2
KeyRelease = 3
ButtonPress = 4
ButtonRelease = 5
Motion = 6
Enter = 7
Leave = 8
FocusIn = 9
FocusOut = 10
HierarchyChanged = 11
PropertyEvent = 12
RawKeyPress = 13
RawKeyRelease = 14
RawButtonPress = 15
RawButtonRelease = 16
RawMotion = 17
DeviceChangedMask = (1 << DeviceChanged)
KeyPressMask = (1 << KeyPress)
KeyReleaseMask = (1 << KeyRelease)
ButtonPressMask = (1 << ButtonPress)
ButtonReleaseMask = (1 << ButtonRelease)
MotionMask = (1 << Motion)
EnterMask = (1 << Enter)
LeaveMask = (1 << Leave)
FocusInMask = (1 << FocusIn)
FocusOutMask = (1 << FocusOut)
HierarchyChangedMask = (1 << HierarchyChanged)
PropertyEventMask = (1 << PropertyEvent)
RawKeyPressMask = (1 << RawKeyPress)
RawKeyReleaseMask = (1 << RawKeyRelease)
RawButtonPressMask = (1 << RawButtonPress)
RawButtonReleaseMask = (1 << RawButtonRelease)
RawMotionMask = (1 << RawMotion)
GrabModeSync = 0
GrabModeAsync = 1
GrabModeTouch = 2
DEVICEID = rq.Card16
DEVICE = rq.Card16
DEVICEUSE = rq.Card8
PROPERTY_TYPE_FLOAT = 'FLOAT'
class FP1616(rq.Int32):
def check_value(self, value):
return int(value * 65536.0)
def parse_value(self, value, display):
return float(value) / float(1 << 16)
class FP3232(rq.ValueField):
structcode = 'lL'
structvalues = 2
def check_value(self, value):
return value
def parse_value(self, value, display):
integral, frac = value
ret = float(integral)
# optimised math.ldexp(float(frac), -32)
ret += float(frac) * (1.0 / (1 << 32))
return ret
class XIQueryVersion(rq.ReplyRequest):
_request = rq.Struct(
rq.Card8('opcode'),
rq.Opcode(47),
rq.RequestLength(),
rq.Card16('major_version'),
rq.Card16('minor_version'),
)
_reply = rq.Struct(
rq.ReplyCode(),
rq.Pad(1),
rq.Card16('sequence_number'),
rq.ReplyLength(),
rq.Card16('major_version'),
rq.Card16('minor_version'),
rq.Pad(20),
)
def query_version(self):
return XIQueryVersion(
display=self.display,
opcode=self.display.get_extension_major(extname),
major_version=2,
minor_version=0,
)
class Mask(rq.List):
def __init__(self, name):
rq.List.__init__(self, name, rq.Card32, pad=0)
def pack_value(self, val):
mask_seq = array.array(rq.struct_to_array_codes['L'])
if isinstance(val, integer_types):
# We need to build a "binary mask" that (as far as I can tell) is
# encoded in native byte order from end to end. The simple case is
# with a single unsigned 32-bit value, for which we construct an
# array with just one item. For values too big to fit inside 4
# bytes we build a longer array, being careful to maintain native
# byte order across the entire set of values.
if sys.byteorder == 'little':
def fun(val):
mask_seq.insert(0, val)
elif sys.byteorder == 'big':
fun = mask_seq.append
else:
raise AssertionError(sys.byteorder)
while val:
fun(val & 0xFFFFFFFF)
val = val >> 32
else:
mask_seq.extend(val)
return rq.encode_array(mask_seq), len(mask_seq), None
EventMask = rq.Struct(
DEVICE('deviceid'),
rq.LengthOf('mask', 2),
Mask('mask'),
)
class XISelectEvents(rq.Request):
_request = rq.Struct(
rq.Card8('opcode'),
rq.Opcode(46),
rq.RequestLength(),
rq.Window('window'),
rq.LengthOf('masks', 2),
rq.Pad(2),
rq.List('masks', EventMask),
)
def select_events(self, event_masks):
'''
select_events(event_masks)
event_masks:
Sequence of (deviceid, mask) pairs, where deviceid is a numerical device
ID, or AllDevices or AllMasterDevices, and mask is either an unsigned
integer or sequence of 32 bits unsigned values
'''
return XISelectEvents(
display=self.display,
opcode=self.display.get_extension_major(extname),
window=self,
masks=event_masks,
)
AnyInfo = rq.Struct(
rq.Card16('type'),
rq.Card16('length'),
rq.Card16('sourceid'),
rq.Pad(2),
)
class ButtonMask(object):
def __init__(self, value, length):
self._value = value
self._length = length
def __len__(self):
return self._length
def __getitem__(self, key):
return self._value & (1 << key)
def __str__(self):
return repr(self)
def __repr__(self):
return '0b{value:0{width}b}'.format(value=self._value,
width=self._length)
class ButtonState(rq.ValueField):
structcode = None
def __init__(self, name):
rq.ValueField.__init__(self, name)
def parse_binary_value(self, data, display, length, fmt):
# Mask: bitfield of <length> button states.
mask_len = 4 * ((((length + 7) >> 3) + 3) >> 2)
mask_data = data[:mask_len]
mask_value = 0
for byte in reversed(struct.unpack('={0:d}B'.format(mask_len), mask_data)):
mask_value <<= 8
mask_value |= byte
data = data[mask_len:]
assert (mask_value & 1) == 0
return ButtonMask(mask_value >> 1, length), data
ButtonInfo = rq.Struct(
rq.Card16('type'),
rq.Card16('length'),
rq.Card16('sourceid'),
rq.LengthOf(('state', 'labels'), 2),
ButtonState('state'),
rq.List('labels', rq.Card32),
)
KeyInfo = rq.Struct(
rq.Card16('type'),
rq.Card16('length'),
rq.Card16('sourceid'),
rq.LengthOf('keycodes', 2),
rq.List('keycodes', rq.Card32),
)
ValuatorInfo = rq.Struct(
rq.Card16('type'),
rq.Card16('length'),
rq.Card16('sourceid'),
rq.Card16('number'),
rq.Card32('label'),
FP3232('min'),
FP3232('max'),
FP3232('value'),
rq.Card32('resolution'),
rq.Card8('mode'),
rq.Pad(3),
)
ScrollInfo = rq.Struct(
rq.Card16('type'),
rq.Card16('length'),
rq.Card16('sourceid'),
rq.Card16('number'),
rq.Card16('scroll_type'),
rq.Pad(2),
rq.Card32('flags'),
FP3232('increment'),
)
TouchInfo = rq.Struct(
rq.Card16('type'),
rq.Card16('length'),
rq.Card16('sourceid'),
rq.Card8('mode'),
rq.Card8('num_touches'),
)
INFO_CLASSES = {
KeyClass: KeyInfo,
ButtonClass: ButtonInfo,
ValuatorClass: ValuatorInfo,
ScrollClass: ScrollInfo,
TouchClass: TouchInfo,
}
class ClassInfoClass(object):
structcode = None
def parse_binary(self, data, display):
class_type, length = struct.unpack('=HH', data[:4])
class_struct = INFO_CLASSES.get(class_type, AnyInfo)
class_data, _ = class_struct.parse_binary(data, display)
data = data[length * 4:]
return class_data, data
ClassInfo = ClassInfoClass()
DeviceInfo = rq.Struct(
DEVICEID('deviceid'),
rq.Card16('use'),
rq.Card16('attachment'),
rq.LengthOf('classes', 2),
rq.LengthOf('name', 2),
rq.Bool('enabled'),
rq.Pad(1),
rq.String8('name', 4),
rq.List('classes', ClassInfo),
)
class XIQueryDevice(rq.ReplyRequest):
_request = rq.Struct(
rq.Card8('opcode'),
rq.Opcode(48),
rq.RequestLength(),
DEVICEID('deviceid'),
rq.Pad(2),
)
_reply = rq.Struct(
rq.ReplyCode(),
rq.Pad(1),
rq.Card16('sequence_number'),
rq.ReplyLength(),
rq.LengthOf('devices', 2),
rq.Pad(22),
rq.List('devices', DeviceInfo),
)
def query_device(self, deviceid):
return XIQueryDevice(
display=self.display,
opcode=self.display.get_extension_major(extname),
deviceid=deviceid,
)
class XIListProperties(rq.ReplyRequest):
_request = rq.Struct(
rq.Card8('opcode'),
rq.Opcode(56),
rq.RequestLength(),
DEVICEID('deviceid'),
rq.Pad(2),
)
_reply = rq.Struct(
rq.ReplyCode(),
rq.Pad(1),
rq.Card16('sequence_number'),
rq.ReplyLength(),
rq.LengthOf('atoms', 2),
rq.Pad(22),
rq.List('atoms', rq.Card32Obj),
)
def list_device_properties(self, deviceid):
return XIListProperties(
display=self.display,
opcode=self.display.get_extension_major(extname),
deviceid=deviceid,
)
class XIGetProperty(rq.ReplyRequest):
_request = rq.Struct(
rq.Card8('opcode'),
rq.Opcode(59),
rq.RequestLength(),
DEVICEID('deviceid'),
rq.Card8('delete'),
rq.Pad(1),
rq.Card32('property'),
rq.Card32('type'),
rq.Card32('offset'),
rq.Card32('length'),
)
_reply = rq.Struct(
rq.ReplyCode(),
rq.Pad(1),
rq.Card16('sequence_number'),
rq.ReplyLength(),
rq.Card32('type'),
rq.Card32('bytes_after'),
rq.LengthOf('value', 4),
rq.Format('value', 1),
rq.Pad(11),
rq.PropertyData('value')
)
def get_device_property(self, deviceid, property, type, offset, length, delete=False):
return XIGetProperty(
display=self.display,
opcode=self.display.get_extension_major(extname),
deviceid=deviceid,
property=property,
type=type,
offset=offset,
length=length,
delete=delete,
)
class XIChangeProperty(rq.Request):
_request = rq.Struct(
rq.Card8('opcode'),
rq.Opcode(57),
rq.RequestLength(),
DEVICEID('deviceid'),
rq.Card8('mode'),
rq.Format('value', 1),
rq.Card32('property'),
rq.Card32('type'),
rq.LengthOf('value', 4),
rq.PropertyData('value'),
)
def change_device_property(self, deviceid, property, type, mode, value):
return XIChangeProperty(
display=self.display,
opcode=self.display.get_extension_major(extname),
deviceid=deviceid,
property=property,
type=type,
mode=mode,
value=value,
)
class XIDeleteProperty(rq.Request):
_request = rq.Struct(
rq.Card8('opcode'),
rq.Opcode(58),
rq.RequestLength(),
DEVICEID('deviceid'),
rq.Pad(2),
rq.Card32('property'),
)
def delete_device_property(self, deviceid, property):
return XIDeleteProperty(
display=self.display,
opcode=self.display.get_extension_major(extname),
deviceid=deviceid,
property=property,
)
class XIGrabDevice(rq.ReplyRequest):
_request = rq.Struct(
rq.Card8('opcode'),
rq.Opcode(51),
rq.RequestLength(),
rq.Window('grab_window'),
rq.Card32('time'),
rq.Cursor('cursor', (X.NONE, )),
DEVICEID('deviceid'),
rq.Set('grab_mode', 1, (GrabModeSync, GrabModeAsync)),
rq.Set('paired_device_mode', 1, (GrabModeSync, GrabModeAsync)),
rq.Bool('owner_events'),
rq.Pad(1),
rq.LengthOf('mask', 2),
Mask('mask'),
)
_reply = rq.Struct(
rq.ReplyCode(),
rq.Pad(1),
rq.Card16('sequence_number'),
rq.ReplyLength(),
rq.Card8('status'),
rq.Pad(23),
)
def grab_device(self, deviceid, time, grab_mode, paired_device_mode, owner_events, event_mask):
return XIGrabDevice(
display=self.display,
opcode=self.display.get_extension_major(extname),
deviceid=deviceid,
grab_window=self,
time=time,
cursor=X.NONE,
grab_mode=grab_mode,
paired_device_mode=paired_device_mode,
owner_events=owner_events,
mask=event_mask,
)
class XIUngrabDevice(rq.Request):
_request = rq.Struct(
rq.Card8('opcode'),
rq.Opcode(52),
rq.RequestLength(),
rq.Card32('time'),
DEVICEID('deviceid'),
rq.Pad(2),
)
def ungrab_device(self, deviceid, time):
return XIUngrabDevice(
display=self.display,
opcode=self.display.get_extension_major(extname),
time=time,
deviceid=deviceid,
)
class XIPassiveGrabDevice(rq.ReplyRequest):
_request = rq.Struct(
rq.Card8('opcode'),
rq.Opcode(54),
rq.RequestLength(),
rq.Card32('time'),
rq.Window('grab_window'),
rq.Cursor('cursor', (X.NONE, )),
rq.Card32('detail'),
DEVICEID('deviceid'),
rq.LengthOf('modifiers', 2),
rq.LengthOf('mask', 2),
rq.Set('grab_type', 1, (GrabtypeButton, GrabtypeKeycode, GrabtypeEnter,
GrabtypeFocusIn, GrabtypeTouchBegin)),
rq.Set('grab_mode', 1, (GrabModeSync, GrabModeAsync)),
rq.Set('paired_device_mode', 1, (GrabModeSync, GrabModeAsync)),
rq.Bool('owner_events'),
rq.Pad(2),
Mask('mask'),
rq.List('modifiers', rq.Card32),
)
_reply = rq.Struct(
rq.ReplyCode(),
rq.Pad(1),
rq.Card16('sequence_number'),
rq.ReplyLength(),
rq.LengthOf('modifiers', 2),
rq.Pad(22),
rq.List('modifiers', rq.Card32),
)
def passive_grab_device(self, deviceid, time, detail,
grab_type, grab_mode, paired_device_mode,
owner_events, event_mask, modifiers):
return XIPassiveGrabDevice(
display=self.display,
opcode=self.display.get_extension_major(extname),
deviceid=deviceid,
grab_window=self,
time=time,
cursor=X.NONE,
detail=detail,
grab_type=grab_type,
grab_mode=grab_mode,
paired_device_mode=paired_device_mode,
owner_events=owner_events,
mask=event_mask,
modifiers=modifiers,
)
def grab_keycode(self, deviceid, time, keycode,
grab_mode, paired_device_mode,
owner_events, event_mask, modifiers):
return passive_grab_device(self, deviceid, time, keycode,
GrabtypeKeycode,
grab_mode, paired_device_mode,
owner_events, event_mask, modifiers)
class XIPassiveUngrabDevice(rq.Request):
_request = rq.Struct(
rq.Card8('opcode'),
rq.Opcode(55),
rq.RequestLength(),
rq.Window('grab_window'),
rq.Card32('detail'),
DEVICEID('deviceid'),
rq.LengthOf('modifiers', 2),
rq.Set('grab_type', 1, (GrabtypeButton, GrabtypeKeycode,
GrabtypeEnter, GrabtypeFocusIn,
GrabtypeTouchBegin)),
rq.Pad(3),
rq.List('modifiers', rq.Card32),
)
def passive_ungrab_device(self, deviceid, detail, grab_type, modifiers):
return XIPassiveUngrabDevice(
display=self.display,
opcode=self.display.get_extension_major(extname),
deviceid=deviceid,
grab_window=self,
detail=detail,
grab_type=grab_type,
modifiers=modifiers,
)
def ungrab_keycode(self, deviceid, keycode, modifiers):
return passive_ungrab_device(self, deviceid, keycode,
GrabtypeKeycode, modifiers)
HierarchyInfo = rq.Struct(
DEVICEID('deviceid'),
DEVICEID('attachment'),
DEVICEUSE('type'),
rq.Bool('enabled'),
rq.Pad(2),
rq.Card32('flags'),
)
HierarchyEventData = rq.Struct(
DEVICEID('deviceid'),
rq.Card32('time'),
rq.Card32('flags'),
rq.LengthOf('info', 2),
rq.Pad(10),
rq.List('info', HierarchyInfo),
)
ModifierInfo = rq.Struct(
rq.Card32('base_mods'),
rq.Card32('latched_mods'),
rq.Card32('locked_mods'),
rq.Card32('effective_mods'),
)
GroupInfo = rq.Struct(
rq.Card8('base_group'),
rq.Card8('latched_group'),
rq.Card8('locked_group'),
rq.Card8('effective_group'),
)
DeviceEventData = rq.Struct(
DEVICEID('deviceid'),
rq.Card32('time'),
rq.Card32('detail'),
rq.Window('root'),
rq.Window('event'),
rq.Window('child'),
FP1616('root_x'),
FP1616('root_y'),
FP1616('event_x'),
FP1616('event_y'),
rq.LengthOf('buttons', 2),
rq.Card16('valulators_len'),
DEVICEID('sourceid'),
rq.Pad(2),
rq.Card32('flags'),
rq.Object('mods', ModifierInfo),
rq.Object('groups', GroupInfo),
ButtonState('buttons'),
)
DeviceChangedEventData = rq.Struct(
DEVICEID('deviceid'),
rq.Card32('time'),
rq.LengthOf('classes', 2),
DEVICEID('sourceid'),
rq.Card8('reason'),
rq.Pad(11),
rq.List('classes', ClassInfo),
)
PropertyEventData = rq.Struct(
DEVICEID('deviceid'),
rq.Card32('time'),
rq.Card32('property'),
rq.Card8('what'),
rq.Pad(11),
)
def init(disp, info):
disp.extension_add_method('display', 'xinput_query_version', query_version)
disp.extension_add_method('window', 'xinput_select_events', select_events)
disp.extension_add_method('display', 'xinput_query_device', query_device)
disp.extension_add_method('window', 'xinput_grab_device', grab_device)
disp.extension_add_method('display', 'xinput_ungrab_device', ungrab_device)
disp.extension_add_method('window', 'xinput_grab_keycode', grab_keycode)
disp.extension_add_method('window', 'xinput_ungrab_keycode', ungrab_keycode)
disp.extension_add_method('display', 'xinput_get_device_property', get_device_property)
disp.extension_add_method('display', 'xinput_list_device_properties', list_device_properties)
disp.extension_add_method('display', 'xinput_change_device_property', change_device_property)
disp.extension_add_method('display', 'xinput_delete_device_property', delete_device_property)
if hasattr(disp,"ge_add_event_data"):
for device_event in (ButtonPress, ButtonRelease, KeyPress, KeyRelease, Motion):
disp.ge_add_event_data(info.major_opcode, device_event, DeviceEventData)
disp.ge_add_event_data(info.major_opcode, DeviceChanged, DeviceEventData)
disp.ge_add_event_data(info.major_opcode, HierarchyChanged, HierarchyEventData)
disp.ge_add_event_data(info.major_opcode, PropertyEvent, PropertyEventData)

View File

@@ -0,0 +1,122 @@
# Xlib.ext.xtest -- XTEST extension module
#
# Copyright (C) 2000 Peter Liljenberg <petli@ctrl-c.liu.se>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public License
# as published by the Free Software Foundation; either version 2.1
# of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the
# Free Software Foundation, Inc.,
# 59 Temple Place,
# Suite 330,
# Boston, MA 02111-1307 USA
from Xlib import X
from Xlib.protocol import rq
extname = 'XTEST'
CurrentCursor = 1
class GetVersion(rq.ReplyRequest):
_request = rq.Struct(rq.Card8('opcode'),
rq.Opcode(0),
rq.RequestLength(),
rq.Card8('major_version'),
rq.Pad(1),
rq.Card16('minor_version')
)
_reply = rq.Struct(rq.Pad(1),
rq.Card8('major_version'),
rq.Card16('sequence_number'),
rq.Pad(4),
rq.Card16('minor_version'),
rq.Pad(22)
)
def get_version(self, major, minor):
return GetVersion(display = self.display,
opcode = self.display.get_extension_major(extname),
major_version = major,
minor_version = minor)
class CompareCursor(rq.ReplyRequest):
_request = rq.Struct(rq.Card8('opcode'),
rq.Opcode(1),
rq.RequestLength(),
rq.Window('window'),
rq.Cursor('cursor', (X.NONE, CurrentCursor)),
)
_reply = rq.Struct(rq.Pad(1),
rq.Card8('same'),
rq.Card16('sequence_number'),
rq.Pad(28),
)
def compare_cursor(self, cursor):
r = CompareCursor(display = self.display,
opcode = self.display.get_extension_major(extname),
window = self.id,
cursor = cursor)
return r.same
class FakeInput(rq.Request):
_request = rq.Struct(rq.Card8('opcode'),
rq.Opcode(2),
rq.RequestLength(),
rq.Set('event_type', 1, (X.KeyPress,
X.KeyRelease,
X.ButtonPress,
X.ButtonRelease,
X.MotionNotify)),
rq.Card8('detail'),
rq.Pad(2),
rq.Card32('time'),
rq.Window('root', (X.NONE, )),
rq.Pad(8),
rq.Int16('x'),
rq.Int16('y'),
rq.Pad(8)
)
def fake_input(self, event_type, detail = 0, time = X.CurrentTime,
root = X.NONE, x = 0, y = 0):
FakeInput(display = self.display,
opcode = self.display.get_extension_major(extname),
event_type = event_type,
detail = detail,
time = time,
root = root,
x = x,
y = y)
class GrabControl(rq.Request):
_request = rq.Struct(rq.Card8('opcode'),
rq.Opcode(3),
rq.RequestLength(),
rq.Bool('impervious'),
rq.Pad(3)
)
def grab_control(self, impervious):
GrabControl(display = self.display,
opcode = self.display.get_extension_major(extname),
impervious = impervious)
def init(disp, info):
disp.extension_add_method('display', 'xtest_get_version', get_version)
disp.extension_add_method('window', 'xtest_compare_cursor', compare_cursor)
disp.extension_add_method('display', 'xtest_fake_input', fake_input)
disp.extension_add_method('display', 'xtest_grab_control', grab_control)