def __init__(self, proto, display=None, auth_file=None, auth_type=None, auth_key=None): self.proto = proto if display is None: display = os.environ.get('DISPLAY', ':0') if auth_file is None and auth_type is None: auth_file = os.environ.get('XAUTHORITY') if auth_file is None: auth_file = os.path.expanduser('~/.XAuthority') host, port = display.split(':') if '.' in port: maj, min = map(int, port.split('.')) else: maj = int(port) min = 0 assert min == 0, 'Subdisplays are not not supported so far' if auth_type is None: if host != "": haddr = socket.inet_aton(socket.gethostbyname(host)) for auth in read_auth(): if host == "": if auth.family == 1 and maj == auth.number: auth_type = auth.name auth_key = auth.data break else: if auth.family == 0 and auth.address == haddr: auth_type = auth.name auth_key = auth.data break else: raise RuntimeError("Can't find X auth type") self.unixsock = '/tmp/.X11-unix/X{:d}'.format(maj) self.auth_type = auth_type self.auth_key = auth_key self._channel = None self._channel_lock = Lock() self._condition = Condition() self.events = deque()
class Connection(object): def __init__(self, proto, display=None, auth_file=None, auth_type=None, auth_key=None): self.proto = proto if display is None: display = os.environ.get('DISPLAY', ':0') if auth_file is None and auth_type is None: auth_file = os.environ.get('XAUTHORITY') if auth_file is None: auth_file = os.path.expanduser('~/.XAuthority') host, port = display.split(':') if '.' in port: maj, min = map(int, port.split('.')) else: maj = int(port) min = 0 assert min == 0, 'Subdisplays are not not supported so far' if auth_type is None: if host != "": haddr = socket.inet_aton(socket.gethostbyname(host)) for auth in read_auth(): if host == "": if auth.family == 1 and maj == auth.number: auth_type = auth.name auth_key = auth.data break else: if auth.family == 0 and auth.address == haddr: auth_type = auth.name auth_key = auth.data break else: raise RuntimeError("Can't find X auth type") self.unixsock = '/tmp/.X11-unix/X{:d}'.format(maj) self.auth_type = auth_type self.auth_key = auth_key self._channel = None self._channel_lock = Lock() self._condition = Condition() self.events = deque() def connection(self): if self._channel is None: with self._channel_lock: if self._channel is None: chan = Channel(unixsock=self.unixsock, proto=self.proto, event_dispatcher=self.event_dispatcher) data = chan.connect(self.auth_type, self.auth_key) core = self.proto.subprotos['xproto'] value, pos = core.types['Setup'].read_from(data) assert pos == len(data) self.init_data = value assert self.init_data['status'] == 1 assert self.init_data['protocol_major_version'] == 11 self._init_values() self._channel = chan self._eventreg = core.events_by_num.copy() return self._channel def _init_values(self): d = self.init_data base = self.init_data["resource_id_base"] mask = self.init_data["resource_id_mask"] inc = mask & -mask self.xid_generator = iter(range(base, base | mask, inc)) def query_extension(self, name): sub = self.proto.subprotos[name] conn = self.connection() res = self.do_request( self.proto.subprotos['xproto'].requests['QueryExtension'], name=sub.xname) if res['present']: if res['first_event']: self.register_event(res['first_event'], sub) if res['first_error']: conn.register_error(res['first_error'], sub) return res def do_request(self, rtype, *, _opcode=None, _ignore_error=False, **kw): conn = self.connection() for i in list(kw): n = i + '_len' if n in rtype.items and n not in kw: kw[n] = len(kw[i]) buf = bytearray() rtype.write_to(buf, kw) if _opcode is None: buf.insert(0, rtype.opcode) if len(buf) < 2: buf.append(0) else: buf.insert(0, _opcode) buf.insert(1, rtype.opcode) ln = int(ceil((len(buf) + 2) / 4)) buf[2:2] = struct.pack('<H', ln) buf += b'\x00' * (ln * 4 - len(buf)) if rtype.reply: res = conn.request(buf, rtype.reply).get() if isinstance(res, XError): raise res else: return res else: conn.push(buf, ignore_error=_ignore_error) def new_xid(self): return next(self.xid_generator) def register_event(self, code, subpro): for ev in subpro.events.values(): self._eventreg[code + ev.number] = ev def event_dispatcher(self, seq, buf): etype = self._eventreg[buf[0] & 127] if etype.no_seq: seq = None else: buf = buf[:2] + buf[4:] ev, pos = etype.read_from(buf, 1) assert pos <= 32 self.events.append(etype.type(seq, **ev)) self._condition.notify() def get_events(self): while True: while self.events: yield self.events.popleft() self._condition.wait()
class Connection(object): def __init__(self, proto, display=None, auth_file=None, auth_type=None, auth_key=None): self.proto = proto if display is None: display = os.environ.get('DISPLAY', ':0') if auth_file is None and auth_type is None: auth_file = os.environ.get('XAUTHORITY') if auth_file is None: auth_file = os.path.expanduser('~/.XAuthority') host, port = display.split(':') if '.' in port: maj, min = map(int, port.split('.')) else: maj = int(port) min = 0 assert min == 0, 'Subdisplays are not not supported so far' if auth_type is None: if host != "": haddr = socket.inet_aton(socket.gethostbyname(host)) for auth in read_auth(): if host == "": if auth.family == 1 and maj == auth.number: auth_type = auth.name auth_key = auth.data break else: if auth.family == 0 and auth.address == haddr: auth_type = auth.name auth_key = auth.data break else: raise RuntimeError("Can't find X auth type") self.unixsock = '/tmp/.X11-unix/X{:d}'.format(maj) self.auth_type = auth_type self.auth_key = auth_key self._channel = None self._channel_lock = Lock() self._condition = Condition() self.events = deque() def connection(self): if self._channel is None: with self._channel_lock: if self._channel is None: chan = Channel(unixsock=self.unixsock, proto=self.proto, event_dispatcher=self.event_dispatcher) data = chan.connect(self.auth_type, self.auth_key) core = self.proto.subprotos['xproto'] value, pos = core.types['Setup'].read_from(data) assert pos == len(data) self.init_data = value assert self.init_data['status'] == 1 assert self.init_data['protocol_major_version'] == 11 self._init_values() self._channel = chan self._eventreg = core.events_by_num.copy() return self._channel def _init_values(self): d = self.init_data base = self.init_data["resource_id_base"] mask = self.init_data["resource_id_mask"] inc = mask & -mask self.xid_generator = iter(range(base, base | mask, inc)) def query_extension(self, name): sub = self.proto.subprotos[name] conn = self.connection() res = self.do_request( self.proto.subprotos['xproto'].requests['QueryExtension'], name=sub.xname) if res['present']: if res['first_event']: self.register_event(res['first_event'], sub) if res['first_error']: conn.register_error(res['first_error'], sub) return res def do_request(self, rtype, *, _opcode=None, _ignore_error=False, **kw): conn = self.connection() for i in list(kw): n = i + '_len' if n in rtype.items and n not in kw: kw[n] = len(kw[i]) buf = bytearray() rtype.write_to(buf, kw) if _opcode is None: buf.insert(0, rtype.opcode) if len(buf) < 2: buf.append(0) else: buf.insert(0, _opcode) buf.insert(1, rtype.opcode) ln = int(ceil((len(buf)+2)/4)) buf[2:2] = struct.pack('<H', ln) buf += b'\x00'*(ln*4 - len(buf)) if rtype.reply: res = conn.request(buf, rtype.reply).get() if isinstance(res, XError): raise res else: return res else: conn.push(buf, ignore_error=_ignore_error) def new_xid(self): return next(self.xid_generator) def register_event(self, code, subpro): for ev in subpro.events.values(): self._eventreg[code + ev.number] = ev def event_dispatcher(self, seq, buf): etype = self._eventreg[buf[0] & 127] if etype.no_seq: seq = None else: buf = buf[:2] + buf[4:] ev, pos = etype.read_from(buf, 1) assert pos <= 32 self.events.append(etype.type(seq, **ev)) self._condition.notify() def get_events(self): while True: while self.events: yield self.events.popleft() self._condition.wait()