From a900a0582f94ffa11c622f3bd845c1896a22453a Mon Sep 17 00:00:00 2001 From: allfro Date: Mon, 9 May 2022 17:03:00 -0400 Subject: [PATCH 1/2] Update rq.py Fixes return type inconsistency with the `pack_value` for class `Object`. When using an `Object` field embedded in a request `pack_value` croaks because it calls to_binary which returns a byte buffer instead of a 3-value tuple. This fix addresses the issue. --- Xlib/protocol/rq.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Xlib/protocol/rq.py b/Xlib/protocol/rq.py index 86cb2def..8a0cd6b0 100644 --- a/Xlib/protocol/rq.py +++ b/Xlib/protocol/rq.py @@ -604,7 +604,8 @@ def parse_value(self, val, display): return self.type.parse_value(val, display) def pack_value(self, val): - return self.type.pack_value(val) + val = self.type.pack_value(val) + return val, len(val), None def check_value(self, val): if isinstance(val, tuple): From 1b123ca45c3859073a48dc6844bcf16e2b10c965 Mon Sep 17 00:00:00 2001 From: allfro Date: Mon, 9 May 2022 17:16:32 -0400 Subject: [PATCH 2/2] Update randr.py Add version 1.5 support for RRSetMonitor RRGetMonitors and RRDeleteMonitors --- Xlib/ext/randr.py | 96 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 92 insertions(+), 4 deletions(-) diff --git a/Xlib/ext/randr.py b/Xlib/ext/randr.py index 48f4b635..ba37d60c 100644 --- a/Xlib/ext/randr.py +++ b/Xlib/ext/randr.py @@ -25,7 +25,7 @@ This implementation is based off version 1.3 of the XRandR protocol, and may not be compatible with other versions. -Version 1.2 of the protocol is documented at: +Version 1.5 of the protocol is documented at: http://cgit.freedesktop.org/xorg/proto/randrproto/tree/randrproto.txt Version 1.3.1 here: @@ -168,6 +168,19 @@ rq.Card32('matrix33'), ) +MonitorInfo = rq.Struct( + rq.Card32('name'), + rq.Bool('primary'), + rq.Bool('automatic'), + rq.LengthOf('crtcs', 2), + rq.Int16('x'), + rq.Int16('y'), + rq.Card16('width_in_pixels'), + rq.Card16('height_in_pixels'), + rq.Card32('width_in_millimeters'), + rq.Card32('height_in_millimeters'), + rq.List('crtcs', rq.Card32Obj) +) # Requests # @@ -197,7 +210,7 @@ def query_version(self): display=self.display, opcode=self.display.get_extension_major(extname), major_version=1, - minor_version=3, + minor_version=5, ) @@ -1078,6 +1091,76 @@ def get_output_primary(self): ) +# Version 1.5 methods + +class GetMonitors(rq.ReplyRequest): + _request = rq.Struct( + rq.Card8('opcode'), + rq.Opcode(42), + rq.RequestLength(), + rq.Window('window'), + rq.Bool('is_active'), + rq.Pad(3) + ) + + _reply = rq.Struct( + rq.ReplyCode(), + rq.Pad(1), + rq.Card16('sequence_number'), + rq.ReplyLength(), + rq.Card32('timestamp'), + rq.LengthOf('monitors', 4), + rq.Card32('outputs'), + rq.Pad(12), + rq.List('monitors', MonitorInfo) + ) + + +def get_monitors(self, is_active=True): + return GetMonitors( + display=self.display, + opcode=self.display.get_extension_major(extname), + window=self, + is_active=is_active + ) + +class SetMonitor(rq.Request): + _request = rq.Struct( + rq.Card8('opcode'), + rq.Opcode(43), + rq.RequestLength(), + rq.Window('window'), + rq.Object('monitor_info', MonitorInfo) + ) + + +def set_monitor(self, monitor_info): + return SetMonitor( + display=self.display, + opcode=self.display.get_extension_major(extname), + window=self, + monitor_info=monitor_info + ) + + +class DeleteMonitor(rq.Request): + _request = rq.Struct( + rq.Card8('opcode'), + rq.Opcode(44), + rq.RequestLength(), + rq.Window('window'), + rq.Card32('name') + ) + + +def delete_monitor(self, name): + return DeleteMonitor( + display=self.display, + opcode=self.display.get_extension_major(extname), + window=self, + name=name + ) + # Events # class ScreenChangeNotify(rq.Event): @@ -1149,8 +1232,8 @@ class OutputPropertyNotify(rq.Event): rq.Card8('state'), rq.Pad(11), ) - - + + # Initialization # def init(disp, info): @@ -1186,6 +1269,11 @@ def init(disp, info): disp.extension_add_method('display', 'xrandr_get_panning', get_panning) disp.extension_add_method('display', 'xrandr_set_panning', set_panning) + # version 1.5 compatible + disp.extension_add_method('window', 'xrandr_get_monitors', get_monitors) + disp.extension_add_method('window', 'xrandr_set_monitor', set_monitor) + disp.extension_add_method('window', 'xrandr_delete_monitor', delete_monitor) + disp.extension_add_event(info.first_event + RRScreenChangeNotify, ScreenChangeNotify) # add RRNotify events (1 event code with 3 subcodes) disp.extension_add_subevent(info.first_event + RRNotify, RRNotify_CrtcChange, CrtcChangeNotify)