Spaces:
Runtime error
Runtime error
# Xlib.ext.randr -- RandR 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 | |
"""RandR - provide access to the RandR extension information. | |
This implementation is based off version 1.5 of the XRandR protocol, and may | |
not be compatible with other versions. | |
Version 1.5 of the protocol is documented at: | |
http://cgit.freedesktop.org/xorg/proto/randrproto/tree/randrproto.txt | |
Version 1.3.1 here: | |
http://www.x.org/releases/X11R7.5/doc/randrproto/randrproto.txt | |
""" | |
from Xlib import X | |
from Xlib.protocol import rq | |
extname = 'RANDR' | |
# Event codes # | |
RRScreenChangeNotify = 0 | |
# V1.2 additions | |
RRNotify = 1 | |
# RRNotify Subcodes | |
RRNotify_CrtcChange = 0 | |
RRNotify_OutputChange = 1 | |
RRNotify_OutputProperty = 2 | |
# Event selection bits # | |
RRScreenChangeNotifyMask = (1 << 0) | |
# V1.2 additions | |
RRCrtcChangeNotifyMask = (1 << 1) | |
RROutputChangeNotifyMask = (1 << 2) | |
RROutputPropertyNotifyMask = (1 << 3) | |
# Constants # | |
SetConfigSuccess = 0 | |
SetConfigInvalidConfigTime = 1 | |
SetConfigInvalidTime = 2 | |
SetConfigFailed = 3 | |
# used in the rotation field; rotation and reflection in 0.1 proto. | |
Rotate_0 = 1 | |
Rotate_90 = 2 | |
Rotate_180 = 4 | |
Rotate_270 = 8 | |
# new in 1.0 protocol, to allow reflection of screen | |
Reflect_X = 16 | |
Reflect_Y = 32 | |
# new in 1.2 protocol | |
HSyncPositive = 0x00000001 | |
HSyncNegative = 0x00000002 | |
VSyncPositive = 0x00000004 | |
VSyncNegative = 0x00000008 | |
Interlace = 0x00000010 | |
DoubleScan = 0x00000020 | |
CSync = 0x00000040 | |
CSyncPositive = 0x00000080 | |
CSyncNegative = 0x00000100 | |
HSkewPresent = 0x00000200 | |
BCast = 0x00000400 | |
PixelMultiplex = 0x00000800 | |
DoubleClock = 0x00001000 | |
ClockDivideBy2 = 0x00002000 | |
# event types? | |
Connected = 0 | |
Disconnected = 1 | |
UnknownConnection = 2 | |
# Conventional RandR output properties | |
PROPERTY_RANDR_EDID = "EDID" | |
PROPERTY_SIGNAL_FORMAT = "SignalFormat" | |
PROPERTY_SIGNAL_PROPERTIES = "SignalProperties" | |
PROPERTY_CONNECTOR_TYPE = "ConnectorType" | |
PROPERTY_CONNECTOR_NUMBER = "ConnectorNumber" | |
PROPERTY_COMPATIBILITY_LIST = "CompatibilityList" | |
PROPERTY_CLONE_LIST = "CloneList" | |
# subpixel order - TODO: These constants are part of the RENDER extension and | |
# should be moved there if/when that extension is added to python-xlib. | |
SubPixelUnknown = 0 | |
SubPixelHorizontalRGB = 1 | |
SubPixelHorizontalBGR = 2 | |
SubPixelVerticalRGB = 3 | |
SubPixelVerticalBGR = 4 | |
SubPixelNone = 5 | |
# Error Codes # | |
BadRROutput = 0 | |
BadRRCrtc = 1 | |
BadRRMode = 2 | |
# Error classes # | |
class BadRROutputError(Exception): pass | |
class BadRRCrtcError(Exception): pass | |
class BadRRModeError(Exception): pass | |
# Data Structures # | |
RandR_ScreenSizes = rq.Struct( | |
rq.Card16('width_in_pixels'), | |
rq.Card16('height_in_pixels'), | |
rq.Card16('width_in_millimeters'), | |
rq.Card16('height_in_millimeters'), | |
) | |
RandR_ModeInfo = rq.Struct( | |
rq.Card32('id'), | |
rq.Card16('width'), | |
rq.Card16('height'), | |
rq.Card32('dot_clock'), | |
rq.Card16('h_sync_start'), | |
rq.Card16('h_sync_end'), | |
rq.Card16('h_total'), | |
rq.Card16('h_skew'), | |
rq.Card16('v_sync_start'), | |
rq.Card16('v_sync_end'), | |
rq.Card16('v_total'), | |
rq.Card16('name_length'), | |
rq.Card32('flags'), | |
) | |
RandR_Rates = rq.Struct( | |
rq.LengthOf('rates', 2), | |
rq.List('rates', rq.Card16Obj) | |
) | |
# TODO: This struct is part of the RENDER extension and should be moved there | |
# if/when that extension is added to python-xlib. | |
Render_Transform = rq.Struct( | |
rq.Card32('matrix11'), #FIXME: All of these are listed as FIXED in the protocol header. | |
rq.Card32('matrix12'), | |
rq.Card32('matrix13'), | |
rq.Card32('matrix21'), | |
rq.Card32('matrix22'), | |
rq.Card32('matrix23'), | |
rq.Card32('matrix31'), | |
rq.Card32('matrix32'), | |
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 # | |
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): | |
"""Get the current version of the RandR extension. | |
""" | |
return QueryVersion( | |
display=self.display, | |
opcode=self.display.get_extension_major(extname), | |
major_version=1, | |
minor_version=5, | |
) | |
class _1_0SetScreenConfig(rq.ReplyRequest): | |
_request = rq.Struct( | |
rq.Card8('opcode'), | |
rq.Opcode(2), | |
rq.RequestLength(), | |
rq.Drawable('drawable'), | |
rq.Card32('timestamp'), | |
rq.Card32('config_timestamp'), | |
rq.Card16('size_id'), | |
rq.Card16('rotation'), | |
) | |
_reply = rq.Struct( | |
rq.ReplyCode(), | |
rq.Card8('status'), | |
rq.Card16('sequence_number'), | |
rq.ReplyLength(), | |
rq.Card32('new_timestamp'), | |
rq.Card32('new_config_timestamp'), | |
rq.Window('root'), | |
rq.Card16('subpixel_order'), | |
rq.Pad(10), | |
) | |
def _1_0set_screen_config(self, size_id, rotation, config_timestamp, timestamp=X.CurrentTime): | |
"""Sets the screen to the specified size and rotation. | |
""" | |
return _1_0SetScreenConfig( | |
display=self.display, | |
opcode=self.display.get_extension_major(extname), | |
drawable=self, | |
timestamp=timestamp, | |
config_timestamp=config_timestamp, | |
size_id=size_id, | |
rotation=rotation, | |
) | |
class SetScreenConfig(rq.ReplyRequest): | |
_request = rq.Struct( | |
rq.Card8('opcode'), | |
rq.Opcode(2), | |
rq.RequestLength(), | |
rq.Drawable('drawable'), | |
rq.Card32('timestamp'), | |
rq.Card32('config_timestamp'), | |
rq.Card16('size_id'), | |
rq.Card16('rotation'), | |
rq.Card16('rate'), # added in version 1.1 | |
rq.Pad(2), | |
) | |
_reply = rq.Struct( | |
rq.ReplyCode(), | |
rq.Card8('status'), | |
rq.Card16('sequence_number'), | |
rq.ReplyLength(), | |
rq.Card32('new_timestamp'), | |
rq.Card32('new_config_timestamp'), | |
rq.Window('root'), | |
rq.Card16('subpixel_order'), | |
rq.Pad(10), | |
) | |
def set_screen_config(self, size_id, rotation, config_timestamp, rate=0, timestamp=X.CurrentTime): | |
"""Sets the screen to the specified size, rate, rotation and reflection. | |
rate can be 0 to have the server select an appropriate rate. | |
""" | |
return SetScreenConfig( | |
display=self.display, | |
opcode=self.display.get_extension_major(extname), | |
drawable=self, | |
timestamp=timestamp, | |
config_timestamp=config_timestamp, | |
size_id=size_id, | |
rotation=rotation, | |
rate=rate, | |
) | |
class SelectInput(rq.Request): | |
_request = rq.Struct( | |
rq.Card8('opcode'), | |
rq.Opcode(4), | |
rq.RequestLength(), | |
rq.Window('window'), | |
rq.Card16('mask'), | |
rq.Pad(2), | |
) | |
def select_input(self, mask): | |
return SelectInput( | |
display=self.display, | |
opcode=self.display.get_extension_major(extname), | |
window=self, | |
mask=mask, | |
) | |
class GetScreenInfo(rq.ReplyRequest): | |
_request = rq.Struct( | |
rq.Card8('opcode'), | |
rq.Opcode(5), | |
rq.RequestLength(), | |
rq.Window('window'), | |
) | |
_reply = rq.Struct( | |
rq.ReplyCode(), | |
rq.Card8('set_of_rotations'), | |
rq.Card16('sequence_number'), | |
rq.ReplyLength(), | |
rq.Window('root'), | |
rq.Card32('timestamp'), | |
rq.Card32('config_timestamp'), | |
rq.LengthOf('sizes', 2), | |
rq.Card16('size_id'), | |
rq.Card16('rotation'), | |
rq.Card16('rate'), # added in version 1.1 | |
rq.Card16('n_rate_ents'), # XCB's protocol description disagrees with the X headers on this; ignoring. | |
rq.Pad(2), | |
rq.List('sizes', RandR_ScreenSizes), | |
#rq.List('rates', RandR_Rates) #FIXME: Why does uncommenting this cause an error? | |
) | |
def get_screen_info(self): | |
"""Retrieve information about the current and available configurations for | |
the screen associated with this window. | |
""" | |
return GetScreenInfo( | |
display=self.display, | |
opcode=self.display.get_extension_major(extname), | |
window=self, | |
) | |
# version 1.2 | |
class GetScreenSizeRange(rq.ReplyRequest): | |
_request = rq.Struct( | |
rq.Card8('opcode'), | |
rq.Opcode(6), | |
rq.RequestLength(), | |
rq.Window('window'), | |
) | |
_reply = rq.Struct( | |
rq.ReplyCode(), | |
rq.Pad(1), | |
rq.Card16('sequence_number'), | |
rq.ReplyLength(), | |
rq.Card16('min_width'), | |
rq.Card16('min_height'), | |
rq.Card16('max_width'), | |
rq.Card16('max_height'), | |
rq.Pad(16), | |
) | |
def get_screen_size_range(self): | |
"""Retrieve the range of possible screen sizes. The screen may be set to | |
any size within this range. | |
""" | |
return GetScreenSizeRange( | |
display=self.display, | |
opcode=self.display.get_extension_major(extname), | |
window=self, | |
) | |
class SetScreenSize(rq.Request): | |
_request = rq.Struct( | |
rq.Card8('opcode'), | |
rq.Opcode(7), | |
rq.RequestLength(), | |
rq.Window('window'), | |
rq.Card16('width'), | |
rq.Card16('height'), | |
rq.Card32('width_in_millimeters'), | |
rq.Card32('height_in_millimeters'), | |
) | |
def set_screen_size(self, width, height, width_in_millimeters=None, height_in_millimeters=None): | |
return SetScreenSize( | |
display=self.display, | |
opcode=self.display.get_extension_major(extname), | |
window=self, | |
width=width, | |
height=height, | |
width_in_millimeters=width_in_millimeters, | |
height_in_millimeters=height_in_millimeters, | |
) | |
class GetScreenResources(rq.ReplyRequest): | |
_request = rq.Struct( | |
rq.Card8('opcode'), | |
rq.Opcode(8), | |
rq.RequestLength(), | |
rq.Window('window'), | |
) | |
_reply = rq.Struct( | |
rq.ReplyCode(), | |
rq.Pad(1), | |
rq.Card16('sequence_number'), | |
rq.ReplyLength(), | |
rq.Card32('timestamp'), | |
rq.Card32('config_timestamp'), | |
rq.LengthOf('crtcs', 2), | |
rq.LengthOf('outputs', 2), | |
rq.LengthOf('modes', 2), | |
rq.LengthOf('mode_names', 2), | |
rq.Pad(8), | |
rq.List('crtcs', rq.Card32Obj), | |
rq.List('outputs', rq.Card32Obj), | |
rq.List('modes', RandR_ModeInfo), | |
rq.String8('mode_names'), | |
) | |
def get_screen_resources(self): | |
return GetScreenResources( | |
display=self.display, | |
opcode=self.display.get_extension_major(extname), | |
window=self, | |
) | |
class GetOutputInfo(rq.ReplyRequest): | |
_request = rq.Struct( | |
rq.Card8('opcode'), | |
rq.Opcode(9), | |
rq.RequestLength(), | |
rq.Card32('output'), | |
rq.Card32('config_timestamp'), | |
) | |
_reply = rq.Struct( | |
rq.ReplyCode(), | |
rq.Card8('status'), | |
rq.Card16('sequence_number'), | |
rq.ReplyLength(), | |
rq.Card32('timestamp'), | |
rq.Card32('crtc'), | |
rq.Card32('mm_width'), | |
rq.Card32('mm_height'), | |
rq.Card8('connection'), | |
rq.Card8('subpixel_order'), | |
rq.LengthOf('crtcs', 2), | |
rq.LengthOf('modes', 2), | |
rq.Card16('num_preferred'), | |
rq.LengthOf('clones', 2), | |
rq.LengthOf('name', 2), | |
rq.List('crtcs', rq.Card32Obj), | |
rq.List('modes', rq.Card32Obj), | |
rq.List('clones', rq.Card32Obj), | |
rq.String8('name'), | |
) | |
def get_output_info(self, output, config_timestamp): | |
return GetOutputInfo( | |
display=self.display, | |
opcode=self.display.get_extension_major(extname), | |
output=output, | |
config_timestamp=config_timestamp, | |
) | |
class ListOutputProperties(rq.ReplyRequest): | |
_request = rq.Struct( | |
rq.Card8('opcode'), | |
rq.Opcode(10), | |
rq.RequestLength(), | |
rq.Card32('output'), | |
) | |
_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_output_properties(self, output): | |
return ListOutputProperties ( | |
display=self.display, | |
opcode=self.display.get_extension_major(extname), | |
output=output, | |
) | |
class QueryOutputProperty(rq.ReplyRequest): | |
_request = rq.Struct( | |
rq.Card8('opcode'), | |
rq.Opcode(11), | |
rq.RequestLength(), | |
rq.Card32('output'), | |
rq.Card32('property'), | |
) | |
_reply = rq.Struct( | |
rq.ReplyCode(), | |
rq.Pad(1), | |
rq.Card16('sequence_number'), | |
rq.ReplyLength(), | |
rq.Bool('pending'), | |
rq.Bool('range'), | |
rq.Bool('immutable'), | |
rq.Pad(21), | |
rq.List('valid_values', rq.Card32Obj), | |
) | |
def query_output_property(self, output, property): | |
return QueryOutputProperty ( | |
display=self.display, | |
opcode=self.display.get_extension_major(extname), | |
output=output, | |
property=property, | |
) | |
class ConfigureOutputProperty (rq.Request): | |
_request = rq.Struct( | |
rq.Card8('opcode'), | |
rq.Opcode(12), | |
rq.RequestLength(), | |
rq.Card32('output'), | |
rq.Card32('property'), | |
rq.Bool('pending'), | |
rq.Bool('range'), | |
rq.Pad(2), | |
rq.List('valid_values', rq.Card32Obj), | |
) | |
def configure_output_property (self, output, property): | |
return ConfigureOutputProperty ( | |
display=self.display, | |
opcode=self.display.get_extension_major(extname), | |
output=output, | |
property=property, | |
) | |
class ChangeOutputProperty(rq.Request): | |
_request = rq.Struct( | |
rq.Card8('opcode'), | |
rq.Opcode(13), | |
rq.RequestLength(), | |
rq.Card32('output'), | |
rq.Card32('property'), | |
rq.Card32('type'), | |
rq.Format('value', 1), | |
rq.Card8('mode'), | |
rq.Pad(2), | |
rq.LengthOf('value', 4), | |
rq.PropertyData('value'), | |
) | |
def change_output_property(self, output, property, type, mode, value): | |
return ChangeOutputProperty( | |
display=self.display, | |
opcode=self.display.get_extension_major(extname), | |
output=output, | |
property=property, | |
type=type, | |
mode=mode, | |
value=value, | |
) | |
class DeleteOutputProperty(rq.Request): | |
_request = rq.Struct( | |
rq.Card8('opcode'), | |
rq.Opcode(14), | |
rq.RequestLength(), | |
rq.Card32('output'), | |
rq.Card32('property'), | |
) | |
def delete_output_property(self, output, property): | |
return DeleteOutputProperty( | |
display=self.display, | |
opcode=self.display.get_extension_major(extname), | |
output=output, | |
property=property, | |
) | |
class GetOutputProperty(rq.ReplyRequest): | |
_request = rq.Struct( | |
rq.Card8('opcode'), | |
rq.Opcode(15), | |
rq.RequestLength(), | |
rq.Card32('output'), | |
rq.Card32('property'), | |
rq.Card32('type'), | |
rq.Card32('long_offset'), | |
rq.Card32('long_length'), | |
rq.Bool('delete'), | |
rq.Bool('pending'), | |
rq.Pad(2), | |
) | |
_reply = rq.Struct( | |
rq.ReplyCode(), | |
rq.Format('value', 1), | |
rq.Card16('sequence_number'), | |
rq.ReplyLength(), | |
rq.Card32('property_type'), | |
rq.Card32('bytes_after'), | |
rq.LengthOf('value', 4), | |
rq.Pad(12), | |
rq.List('value', rq.Card8Obj), | |
) | |
def get_output_property(self, output, property, type, long_offset, long_length, delete=False, pending=False): | |
return GetOutputProperty( | |
display=self.display, | |
opcode=self.display.get_extension_major(extname), | |
output=output, | |
property=property, | |
type=type, | |
long_offset=long_offset, | |
long_length=long_length, | |
delete=delete, | |
pending=pending, | |
) | |
class CreateMode(rq.ReplyRequest): | |
_request = rq.Struct( | |
rq.Card8('opcode'), | |
rq.Opcode(16), | |
rq.RequestLength(), | |
rq.Window('window'), | |
rq.Object('mode', RandR_ModeInfo), | |
rq.String8('name'), | |
) | |
_reply = rq.Struct( | |
rq.ReplyCode(), | |
rq.Pad(1), | |
rq.Card16('sequence_number'), | |
rq.ReplyLength(), | |
rq.Card32('mode'), | |
rq.Pad(20), | |
) | |
def create_mode(self, mode, name): | |
return CreateMode ( | |
display=self.display, | |
opcode=self.display.get_extension_major(extname), | |
window=self, | |
mode=mode, | |
name=name, | |
) | |
class DestroyMode(rq.Request): | |
_request = rq.Struct( | |
rq.Card8('opcode'), | |
rq.Opcode(17), | |
rq.RequestLength(), | |
rq.Card32('mode'), | |
) | |
def destroy_mode(self, mode): | |
return DestroyMode( | |
display=self.display, | |
opcode=self.display.get_extension_major(extname), | |
mode=mode, | |
) | |
class AddOutputMode(rq.Request): | |
_request = rq.Struct( | |
rq.Card8('opcode'), | |
rq.Opcode(18), | |
rq.RequestLength(), | |
rq.Card32('output'), | |
rq.Card32('mode'), | |
) | |
def add_output_mode(self, output, mode): | |
return AddOutputMode( | |
display=self.display, | |
opcode=self.display.get_extension_major(extname), | |
output=output, | |
mode=mode, | |
) | |
class DeleteOutputMode(rq.Request): | |
_request = rq.Struct( | |
rq.Card8('opcode'), | |
rq.Opcode(19), | |
rq.RequestLength(), | |
rq.Card32('output'), | |
rq.Card32('mode'), | |
) | |
def delete_output_mode(self, output, mode): | |
return DeleteOutputMode( | |
display=self.display, | |
opcode=self.display.get_extension_major(extname), | |
output=output, | |
mode=mode, | |
) | |
class GetCrtcInfo(rq.ReplyRequest): | |
_request = rq.Struct( | |
rq.Card8('opcode'), | |
rq.Opcode(20), | |
rq.RequestLength(), | |
rq.Card32('crtc'), | |
rq.Card32('config_timestamp'), | |
) | |
_reply = rq.Struct( | |
rq.ReplyCode(), | |
rq.Card8('status'), | |
rq.Card16('sequence_number'), | |
rq.ReplyLength(), | |
rq.Card32('timestamp'), | |
rq.Int16('x'), | |
rq.Int16('y'), | |
rq.Card16('width'), | |
rq.Card16('height'), | |
rq.Card32('mode'), | |
rq.Card16('rotation'), | |
rq.Card16('possible_rotations'), | |
rq.LengthOf('outputs', 2), | |
rq.LengthOf('possible_outputs', 2), | |
rq.List('outputs', rq.Card32Obj), | |
rq.List('possible_outputs', rq.Card32Obj), | |
) | |
def get_crtc_info(self, crtc, config_timestamp): | |
return GetCrtcInfo ( | |
display=self.display, | |
opcode=self.display.get_extension_major(extname), | |
crtc=crtc, | |
config_timestamp=config_timestamp, | |
) | |
class SetCrtcConfig(rq.ReplyRequest): | |
_request = rq.Struct( | |
rq.Card8('opcode'), | |
rq.Opcode(21), | |
rq.RequestLength(), | |
rq.Card32('crtc'), | |
rq.Card32('timestamp'), | |
rq.Card32('config_timestamp'), | |
rq.Int16('x'), | |
rq.Int16('y'), | |
rq.Card32('mode'), | |
rq.Card16('rotation'), | |
rq.Pad(2), | |
rq.List('outputs', rq.Card32Obj), | |
) | |
_reply = rq.Struct( | |
rq.ReplyCode(), | |
rq.Card8('status'), | |
rq.Card16('sequence_number'), | |
rq.ReplyLength(), | |
rq.Card32('new_timestamp'), | |
rq.Pad(20), | |
) | |
def set_crtc_config(self, crtc, config_timestamp, x, y, mode, rotation, outputs, timestamp=X.CurrentTime): | |
return SetCrtcConfig ( | |
display=self.display, | |
opcode=self.display.get_extension_major(extname), | |
crtc=crtc, | |
config_timestamp=config_timestamp, | |
x=x, | |
y=y, | |
mode=mode, | |
rotation=rotation, | |
outputs=outputs, | |
timestamp=timestamp, | |
) | |
class GetCrtcGammaSize(rq.ReplyRequest): | |
_request = rq.Struct( | |
rq.Card8('opcode'), | |
rq.Opcode(22), | |
rq.RequestLength(), | |
rq.Card32('crtc'), | |
) | |
_reply = rq.Struct( | |
rq.ReplyCode(), | |
rq.Card8('status'), | |
rq.Card16('sequence_number'), | |
rq.ReplyLength(), | |
rq.Card16('size'), | |
rq.Pad(22), | |
) | |
def get_crtc_gamma_size(self, crtc): | |
return GetCrtcGammaSize ( | |
display=self.display, | |
opcode=self.display.get_extension_major(extname), | |
crtc=crtc, | |
) | |
class GetCrtcGamma(rq.ReplyRequest): | |
_request = rq.Struct( | |
rq.Card8('opcode'), | |
rq.Opcode(23), | |
rq.RequestLength(), | |
rq.Card32('crtc'), | |
) | |
_reply = rq.Struct( | |
rq.ReplyCode(), | |
rq.Card8('status'), | |
rq.Card16('sequence_number'), | |
rq.ReplyLength(), | |
rq.LengthOf(('red', 'green', 'blue'), 2), | |
rq.Pad(22), | |
rq.List('red', rq.Card16Obj), | |
rq.List('green', rq.Card16Obj), | |
rq.List('blue', rq.Card16Obj), | |
) | |
def get_crtc_gamma(self, crtc): | |
return GetCrtcGamma ( | |
display=self.display, | |
opcode=self.display.get_extension_major(extname), | |
crtc=crtc, | |
) | |
class SetCrtcGamma(rq.Request): | |
_request = rq.Struct( | |
rq.Card8('opcode'), | |
rq.Opcode(24), | |
rq.RequestLength(), | |
rq.Card32('crtc'), | |
rq.Card16('size'), | |
rq.Pad(2), | |
rq.List('red', rq.Card16Obj), | |
rq.List('green', rq.Card16Obj), | |
rq.List('blue', rq.Card16Obj), | |
) | |
def set_crtc_gamma(self, crtc, size, red, green, blue): | |
return SetCrtcGamma( | |
display=self.display, | |
opcode=self.display.get_extension_major(extname), | |
crtc=crtc, | |
size=size, | |
red=red, | |
green=green, | |
blue=blue, | |
) | |
# version 1.3 | |
class GetScreenResourcesCurrent(rq.ReplyRequest): | |
_request = rq.Struct( | |
rq.Card8('opcode'), | |
rq.Opcode(25), | |
rq.RequestLength(), | |
rq.Window('window'), | |
) | |
_reply = rq.Struct( | |
rq.ReplyCode(), | |
rq.Pad(1), | |
rq.Card16('sequence_number'), | |
rq.ReplyLength(), | |
rq.Card32('timestamp'), | |
rq.Card32('config_timestamp'), | |
rq.LengthOf('crtcs', 2), | |
rq.LengthOf('outputs', 2), | |
rq.LengthOf('modes', 2), | |
rq.LengthOf('names', 2), | |
rq.Pad(8), | |
rq.List('crtcs', rq.Card32Obj), | |
rq.List('outputs', rq.Card32Obj), | |
rq.List('modes', RandR_ModeInfo), | |
rq.String8('names'), | |
) | |
def get_screen_resources_current(self): | |
return GetScreenResourcesCurrent( | |
display=self.display, | |
opcode=self.display.get_extension_major(extname), | |
window=self, | |
) | |
class SetCrtcTransform(rq.Request): | |
_request = rq.Struct( | |
rq.Card8('opcode'), | |
rq.Opcode(26), | |
rq.RequestLength(), | |
rq.Card32('crtc'), | |
rq.Object('transform', Render_Transform), | |
rq.LengthOf('filter_name', 2), | |
rq.Pad(2), | |
rq.String8('filter_name'), | |
rq.List('filter_params', rq.Card32Obj), #FIXME: The protocol says FIXED? http://cgit.freedesktop.org/xorg/proto/randrproto/tree/randrproto.txt#n2161 | |
) | |
def set_crtc_transform(self, crtc, n_bytes_filter): | |
return SetCrtcTransform( | |
display=self.display, | |
opcode=self.display.get_extension_major(extname), | |
crtc=crtc, | |
n_bytes_filter=n_bytes_filter, | |
) | |
class GetCrtcTransform(rq.ReplyRequest): | |
_request = rq.Struct( | |
rq.Card8('opcode'), | |
rq.Opcode(27), | |
rq.RequestLength(), | |
rq.Card32('crtc'), | |
) | |
_reply = rq.Struct( | |
rq.ReplyCode(), | |
rq.Card8('status'), | |
rq.Card16('sequence_number'), | |
rq.ReplyLength(), | |
rq.Object('pending_transform', Render_Transform), | |
rq.Bool('has_transforms'), | |
rq.Pad(3), | |
rq.Object('current_transform', Render_Transform), | |
rq.Pad(4), | |
rq.LengthOf('pending_filter_name', 2), | |
rq.LengthOf('pending_filter_params', 2), | |
rq.LengthOf('current_filter_name', 2), | |
rq.LengthOf('current_filter_params', 2), | |
rq.String8('pending_filter_name'), | |
rq.List('pending_filter_params', rq.Card32Obj), #FIXME: The protocol says FIXED? http://cgit.freedesktop.org/xorg/proto/randrproto/tree/randrproto.txt#n2161 | |
rq.String8('current_filter_name'), | |
rq.List('current_filter_params', rq.Card32Obj), #FIXME: The protocol says FIXED? http://cgit.freedesktop.org/xorg/proto/randrproto/tree/randrproto.txt#n2161 | |
) | |
def get_crtc_transform(self, crtc): | |
return GetCrtcTransform( | |
display=self.display, | |
opcode=self.display.get_extension_major(extname), | |
crtc=crtc, | |
) | |
class GetPanning(rq.ReplyRequest): | |
_request = rq.Struct( | |
rq.Card8('opcode'), | |
rq.Opcode(28), | |
rq.RequestLength(), | |
rq.Card32('crtc'), | |
) | |
_reply = rq.Struct( | |
rq.ReplyCode(), | |
rq.Card8('status'), | |
rq.Card16('sequence_number'), | |
rq.ReplyLength(), | |
rq.Card32('timestamp'), | |
rq.Card16('left'), | |
rq.Card16('top'), | |
rq.Card16('width'), | |
rq.Card16('height'), | |
rq.Card16('track_left'), | |
rq.Card16('track_top'), | |
rq.Card16('track_width'), | |
rq.Card16('track_height'), | |
rq.Int16('border_left'), | |
rq.Int16('border_top'), | |
rq.Int16('border_right'), | |
rq.Int16('border_bottom'), | |
) | |
def get_panning(self, crtc): | |
return GetPanning ( | |
display=self.display, | |
opcode=self.display.get_extension_major(extname), | |
crtc=crtc, | |
) | |
class SetPanning(rq.ReplyRequest): | |
_request = rq.Struct( | |
rq.Card8('opcode'), | |
rq.Opcode(29), | |
rq.RequestLength(), | |
rq.Card32('crtc'), | |
rq.Card32('timestamp'), | |
rq.Card16('left'), | |
rq.Card16('top'), | |
rq.Card16('width'), | |
rq.Card16('height'), | |
rq.Card16('track_left'), | |
rq.Card16('track_top'), | |
rq.Card16('track_width'), | |
rq.Card16('track_height'), | |
rq.Int16('border_left'), | |
rq.Int16('border_top'), | |
rq.Int16('border_right'), | |
rq.Int16('border_bottom'), | |
) | |
_reply = rq.Struct( | |
rq.ReplyCode(), | |
rq.Card8('status'), | |
rq.Card16('sequence_number'), | |
rq.ReplyLength(), | |
rq.Card32('new_timestamp'), | |
rq.Pad(20), | |
) | |
def set_panning(self, crtc, left, top, width, height, track_left, track_top, track_width, track_height, border_left, border_top, border_width, border_height, timestamp=X.CurrentTime): | |
return SetPanning ( | |
display=self.display, | |
opcode=self.display.get_extension_major(extname), | |
crtc=crtc, | |
left=left, | |
top=top, | |
width=width, | |
height=height, | |
track_left=track_left, | |
track_top=track_top, | |
track_width=track_width, | |
track_height=track_height, | |
border_left=border_left, | |
border_top=border_top, | |
border_width=border_width, | |
border_height=border_height, | |
timestamp=timestamp, | |
) | |
class SetOutputPrimary(rq.Request): | |
_request = rq.Struct( | |
rq.Card8('opcode'), | |
rq.Opcode(30), | |
rq.RequestLength(), | |
rq.Window('window'), | |
rq.Card32('output'), | |
) | |
def set_output_primary(self, output): | |
return SetOutputPrimary( | |
display=self.display, | |
opcode=self.display.get_extension_major(extname), | |
window=self, | |
output=output, | |
) | |
class GetOutputPrimary(rq.ReplyRequest): | |
_request = rq.Struct( | |
rq.Card8('opcode'), | |
rq.Opcode(31), | |
rq.RequestLength(), | |
rq.Window('window'), | |
) | |
_reply = rq.Struct( | |
rq.ReplyCode(), | |
rq.Pad(1), | |
rq.Card16('sequence_number'), | |
rq.ReplyLength(), | |
rq.Card32('output'), | |
rq.Pad(20), | |
) | |
def get_output_primary(self): | |
return GetOutputPrimary( | |
display=self.display, | |
opcode=self.display.get_extension_major(extname), | |
window=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): | |
_code = None | |
_fields = rq.Struct( | |
rq.Card8('type'), | |
rq.Card8('rotation'), | |
rq.Card16('sequence_number'), | |
rq.Card32('timestamp'), | |
rq.Card32('config_timestamp'), | |
rq.Window('root'), | |
rq.Window('window'), | |
rq.Card16('size_id'), | |
rq.Card16('subpixel_order'), | |
rq.Card16('width_in_pixels'), | |
rq.Card16('height_in_pixels'), | |
rq.Card16('width_in_millimeters'), | |
rq.Card16('height_in_millimeters'), | |
) | |
class CrtcChangeNotify(rq.Event): | |
_code = None | |
_fields = rq.Struct( | |
rq.Card8('type'), | |
rq.Card8('sub_code'), | |
rq.Card16('sequence_number'), | |
rq.Card32('timestamp'), | |
rq.Window('window'), | |
rq.Card32('crtc'), | |
rq.Card32('mode'), | |
rq.Card16('rotation'), | |
rq.Pad(2), | |
rq.Int16('x'), | |
rq.Int16('y'), | |
rq.Card16('width'), | |
rq.Card16('height'), | |
) | |
class OutputChangeNotify(rq.Event): | |
_code = None | |
_fields = rq.Struct( | |
rq.Card8('type'), | |
rq.Card8('sub_code'), | |
rq.Card16('sequence_number'), | |
rq.Card32('timestamp'), | |
rq.Card32('config_timestamp'), | |
rq.Window('window'), | |
rq.Card32('output'), | |
rq.Card32('crtc'), | |
rq.Card32('mode'), | |
rq.Card16('rotation'), | |
rq.Card8('connection'), | |
rq.Card8('subpixel_order'), | |
) | |
class OutputPropertyNotify(rq.Event): | |
_code = None | |
_fields = rq.Struct( | |
rq.Card8('type'), | |
rq.Card8('sub_code'), | |
rq.Card16('sequence_number'), | |
rq.Window('window'), | |
rq.Card32('output'), | |
rq.Card32('atom'), | |
rq.Card32('timestamp'), | |
rq.Card8('state'), | |
rq.Pad(11), | |
) | |
# Initialization # | |
def init(disp, info): | |
disp.extension_add_method('display', 'xrandr_query_version', query_version) | |
disp.extension_add_method('window', 'xrandr_select_input', select_input) | |
disp.extension_add_method('window', 'xrandr_get_screen_info', get_screen_info) | |
disp.extension_add_method('drawable', 'xrandr_1_0set_screen_config', _1_0set_screen_config) | |
disp.extension_add_method('drawable', 'xrandr_set_screen_config', set_screen_config) | |
disp.extension_add_method('window', 'xrandr_get_screen_size_range', get_screen_size_range) | |
disp.extension_add_method('window', 'xrandr_set_screen_size', set_screen_size) | |
disp.extension_add_method('window', 'xrandr_get_screen_resources', get_screen_resources) | |
disp.extension_add_method('display', 'xrandr_get_output_info', get_output_info) | |
disp.extension_add_method('display', 'xrandr_list_output_properties', list_output_properties) | |
disp.extension_add_method('display', 'xrandr_query_output_property', query_output_property) | |
disp.extension_add_method('display', 'xrandr_configure_output_property ', configure_output_property ) | |
disp.extension_add_method('display', 'xrandr_change_output_property', change_output_property) | |
disp.extension_add_method('display', 'xrandr_delete_output_property', delete_output_property) | |
disp.extension_add_method('display', 'xrandr_get_output_property', get_output_property) | |
disp.extension_add_method('window', 'xrandr_create_mode', create_mode) | |
disp.extension_add_method('display', 'xrandr_destroy_mode', destroy_mode) | |
disp.extension_add_method('display', 'xrandr_add_output_mode', add_output_mode) | |
disp.extension_add_method('display', 'xrandr_delete_output_mode', delete_output_mode) | |
disp.extension_add_method('display', 'xrandr_get_crtc_info', get_crtc_info) | |
disp.extension_add_method('display', 'xrandr_set_crtc_config', set_crtc_config) | |
disp.extension_add_method('display', 'xrandr_get_crtc_gamma_size', get_crtc_gamma_size) | |
disp.extension_add_method('display', 'xrandr_get_crtc_gamma', get_crtc_gamma) | |
disp.extension_add_method('display', 'xrandr_set_crtc_gamma', set_crtc_gamma) | |
disp.extension_add_method('window', 'xrandr_get_screen_resources_current', get_screen_resources_current) | |
disp.extension_add_method('display', 'xrandr_set_crtc_transform', set_crtc_transform) | |
disp.extension_add_method('display', 'xrandr_get_crtc_transform', get_crtc_transform) | |
disp.extension_add_method('window', 'xrandr_set_output_primary', set_output_primary) | |
disp.extension_add_method('window', 'xrandr_get_output_primary', get_output_primary) | |
disp.extension_add_method('display', 'xrandr_get_panning', get_panning) | |
disp.extension_add_method('display', 'xrandr_set_panning', set_panning) | |
# If the server is running RANDR 1.5+, enable 1.5 compatible methods and events | |
version = query_version(disp) | |
if version.major_version == 1 and version.minor_version >= 5: | |
# 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) | |
disp.extension_add_subevent(info.first_event + RRNotify, RRNotify_OutputChange, OutputChangeNotify) | |
disp.extension_add_subevent(info.first_event + RRNotify, RRNotify_OutputProperty, OutputPropertyNotify) | |
disp.extension_add_error(BadRROutput, BadRROutputError) | |
disp.extension_add_error(BadRRCrtc, BadRRCrtcError) | |
disp.extension_add_error(BadRRMode, BadRRModeError) | |