# Xlib.ext.record -- RECORD extension module # # Copyright (C) 2006 Alex Badea # # 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 = '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)