16
16
# along with this program; if not, write to the Free Software
17
17
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25
25
from array import array
31
30
from Xlib.support import lock
33
_PY3 = sys.version[0] >= '3'
35
# in Python 3, bytes are an actual array; in python 2, bytes are still
36
# string-like, so in order to get an array element we need to call ord()
34
44
class BadDataError(Exception): pass
36
46
# These are struct codes, we know their byte sizes
53
63
size = array(c).itemsize
55
array_unsigned_codes[size] = string.upper(c)
65
array_unsigned_codes[size] = c.upper()
57
67
struct_to_array_codes[signed_codes[size]] = c
58
struct_to_array_codes[unsigned_codes[size]] = string.upper(c)
68
struct_to_array_codes[unsigned_codes[size]] = c.upper()
192
202
def calc_length(self, length):
195
205
class ReplyLength(TotalLengthField):
199
209
def calc_length(self, length):
200
return (length - 32) / 4
210
return (length - 32) // 4
203
213
class LengthOf(LengthField):
280
290
self.codes = codes
282
292
def check_value(self, value):
283
if type(value) is types.InstanceType:
284
294
return getattr(value, self.cast_function)()
295
except AttributeError:
288
298
def parse_value(self, value, display):
380
390
def pack_value(self, val):
393
if _PY3 and type(val) is str:
394
val = val.encode('UTF-8')
384
return val + '\0' * ((4 - slen % 4) % 4), slen, None
397
return val + b'\0' * ((4 - slen % 4) % 4), slen, None
386
399
return val, slen, None
388
401
def parse_binary_value(self, data, display, length, format):
389
402
if length is None:
404
return data.decode('UTF-8'), b''
405
except UnicodeDecodeError:
393
409
slen = length + ((4 - length % 4) % 4)
397
return str(data[:length]), buffer(data, slen)
415
s = s.decode('UTF-8')
416
except UnicodeDecodeError:
417
pass # return as bytes
418
return s, data[slen:]
400
421
class String16(ValueField):
407
428
def pack_value(self, val):
408
429
# Convert 8-byte string into 16-byte list
409
if type(val) is types.StringType:
410
val = map(lambda c: ord(c), val)
431
val = list(map(lambda c: ord(c), val))
415
pad = '\0\0' * (slen % 2)
436
pad = b'\0\0' * (slen % 2)
419
return apply(struct.pack, ('>' + 'H' * slen, ) + tuple(val)) + pad, slen, None
440
return struct.pack(*('>' + 'H' * slen, ) + tuple(val)) + pad, slen, None
421
442
def parse_binary_value(self, data, display, length, format):
422
443
if length == 'odd':
423
length = len(data) / 2 - 1
444
length = len(data) // 2 - 1
424
445
elif length == 'even':
425
length = len(data) / 2
446
length = len(data) // 2
428
449
slen = length + (length % 2)
432
return struct.unpack('>' + 'H' * length, data[:length * 2]), buffer(data, slen * 2)
453
return struct.unpack('>' + 'H' * length, data[:length * 2]), data[slen * 2:]
516
537
data.append(self.type.pack_value(v))
518
data = string.join(data, '')
539
data = b''.join(data)
522
data = data + '\0' * ((4 - dlen % 4) % 4)
543
data = data + b'\0' * ((4 - dlen % 4) % 4)
524
545
return data, len(val), None
562
583
if self.type.parse_value is not None:
563
584
v = self.type.parse_value(v, display)
565
return v, buffer(data, slen)
586
return v, data[slen:]
567
588
def parse_value(self, val, display):
568
589
if self.type.parse_value is None:
581
602
if self.type.structcode is None:
584
if type(val) is types.TupleType:
605
if type(val) is tuple:
587
if type(val) is types.DictType:
608
if type(val) is dict:
589
610
elif isinstance(val, DictWrapper):
605
626
def parse_binary_value(self, data, display, length, format):
606
627
if length is None:
607
length = len(data) / (format / 8)
628
length = len(data) // (format // 8)
609
630
length = int(length)
614
636
elif format == 8:
615
ret = (8, str(data[:length]))
616
data = buffer(data, length + ((4 - length % 4) % 4))
637
ret = (8, data[:length])
638
data = data[length + ((4 - length % 4) % 4):]
618
640
elif format == 16:
619
ret = (16, array(array_unsigned_codes[2], str(data[:2 * length])))
620
data = buffer(data, 2 * (length + length % 2))
641
ret = (16, array(array_unsigned_codes[2], data[:2 * length]))
642
data = data[2 * (length + length % 2):]
622
644
elif format == 32:
623
ret = (32, array(array_unsigned_codes[4], str(data[:4 * length])))
624
data = buffer(data, 4 * length)
645
ret = (32, array(array_unsigned_codes[4], data[:4 * length]))
646
data = data[4 * length:]
648
if type(ret[1]) is bytes:
650
ret = (ret[0], ret[1].decode('UTF-8'))
651
except UnicodeDecodeError:
652
pass # return as bytes
631
659
if fmt not in (8, 16, 32):
632
660
raise BadDataError('Invalid property data format %d' % fmt)
634
if type(val) is types.StringType:
662
if _PY3 and type(val) is str:
663
val = val.encode('UTF-8')
665
if type(val) is bytes:
638
669
vlen = vlen - vlen % size
646
if type(val) is types.TupleType:
677
if type(val) is tuple:
650
681
data = array(array_unsigned_codes[size], val).tostring()
654
data = data + '\0' * ((4 - dl % 4) % 4)
685
data = data + b'\0' * ((4 - dl % 4) % 4)
656
687
return data, dlen, fmt
664
695
def parse_binary_value(self, data, display, length, format):
665
696
return PropertyData.parse_binary_value(self, data, display,
666
self.size / (format / 8), format)
697
self.size // (format // 8), format)
668
699
def pack_value(self, value):
669
700
data, dlen, fmt = PropertyData.pack_value(self, value)
708
739
val = field.check_value(val)
710
741
d = struct.pack('=' + field.structcode, val)
711
data = data + d + '\0' * (4 - len(d))
742
data = data + d + b'\0' * (4 - len(d))
713
744
return struct.pack(self.maskcode, mask) + data, None, None
718
749
mask = int(struct.unpack(self.maskcode, data[:self.maskcodelen])[0])
719
data = buffer(data, self.maskcodelen)
750
data = data[self.maskcodelen:]
721
752
for field, flag in self.fields:
748
779
dlen = 4 * length * format
750
a = array(array_unsigned_codes[4], str(data[:dlen]))
781
a = array(array_unsigned_codes[4], data[:dlen])
753
784
for i in range(0, len(a), format):
754
785
ret.append(a[i : i + format])
756
return ret, buffer(data, dlen)
787
return ret, data[dlen:]
758
789
def pack_value(self, value):
775
806
structcode = None
777
808
def parse_binary_value(self, data, display, length, format):
778
a = array(array_unsigned_codes[1], str(data[:8 * format]))
809
a = array(array_unsigned_codes[1], data[:8 * format])
781
812
for i in range(0, 8):
782
813
ret.append(a[i * format : (i + 1) * format])
784
return ret, buffer(data, 8 * format)
815
return ret, data[8 * format:]
786
817
def pack_value(self, value):
787
818
if len(value) != 8:
811
842
return value._binary, None, None
813
844
def parse_binary_value(self, data, display, length, format):
816
estruct = display.event_classes.get(ord(data[0]) & 0x7f, event.AnyEvent)
818
return estruct(display = display, binarydata = data[:32]), buffer(data, 32)
845
from Xlib.protocol import event
847
estruct = display.event_classes.get(_bytes_item(data[0]) & 0x7f, event.AnyEvent)
849
return estruct(display = display, binarydata = data[:32]), data[32:]
856
887
structcode = None
858
889
def pack_value(self, val):
859
return chr(len(val)) + val
890
if type(val) is not bytes:
891
val = val.encode('UTF-8')
893
val = bytes([len(val)]) + val
895
val = chr(len(val)) + val
861
898
def parse_binary(self, data, display):
862
slen = ord(data[0]) + 1
863
return data[1:slen], buffer(data, slen)
899
slen = _bytes_item(data[0]) + 1
902
s = s.decode('UTF-8')
903
except UnicodeDecodeError:
904
pass # return as bytes
905
return s, data[slen:]
1029
1072
if f.check_value is not None:
1030
1073
code = code + (' %s = self.static_fields[%d].check_value(%s)\n'
1031
% (string.join(a, ', '), i, f.name))
1074
% (', '.join(a), i, f.name))
1033
code = code + ' %s = %s\n' % (string.join(a, ', '), f.name)
1076
code = code + ' %s = %s\n' % (', '.join(a), f.name)
1035
1078
pack_args = pack_args + a
1047
1089
# Construct call to struct.pack
1048
pack = 'struct.pack(%s)' % string.join(pack_args, ', ')
1090
pack = 'struct.pack(%s)' % ', '.join(pack_args)
1050
1092
# If there are any varfields, we append the packed strings to build
1051
1093
# the resulting binary value
1052
1094
if self.var_fields:
1053
code = code + ' return %s + %s\n' % (pack, string.join(joins, ' + '))
1095
code = code + ' return %s + %s\n' % (pack, ' + '.join(joins))
1055
1097
# If there's only static fields, return the packed value
1070
1112
args.append('**_keyword_args')
1072
1114
# Add function header
1073
code = 'def to_binary(self, %s):\n' % string.join(args, ', ') + code
1115
code = 'def to_binary(self, %s):\n' % ', '.join(args) + code
1075
1117
# self._pack_code = code
1088
1130
# memory leak isn't that serious. Besides, Python 2.0 has
1089
1131
# real garbage collect.
1092
self.to_binary = new.instancemethod(to_binary, self, self.__class__)
1133
g = globals().copy()
1135
self.to_binary = types.MethodType(g['to_binary'], self)
1094
1137
# Finally call it manually
1095
return apply(self.to_binary, varargs, keys)
1138
return self.to_binary(*varargs, **keys)
1098
1141
def pack_value(self, value):
1106
if type(value) is types.TupleType:
1107
return apply(self.to_binary, value, {})
1108
elif type(value) is types.DictionaryType:
1109
return apply(self.to_binary, (), value)
1149
if type(value) is tuple:
1150
return self.to_binary(*value, **{})
1151
elif type(value) is dict:
1152
return self.to_binary(*(), **value)
1110
1153
elif isinstance(value, DictWrapper):
1111
return apply(self.to_binary, (), value._data)
1154
return self.to_binary(*(), **value._data)
1113
1156
raise BadDataError('%s is not a tuple or a list' % (value))
1174
1217
# Finally, compile function as for to_binary.
1177
self.parse_value = new.instancemethod(parse_value, self, self.__class__)
1219
g = globals().copy()
1221
self.parse_value = types.MethodType(g['parse_value'], self)
1179
1223
# Call it manually
1180
1224
return self.parse_value(val, display, rawdict)
1250
1294
vno = vno + f.structvalues
1252
code = code + ' data = buffer(data, %d)\n' % self.static_size
1296
code = code + ' data = data[%d:]\n' % self.static_size
1254
1298
# Call parse_binary_value for each var_field, passing the
1255
1299
# length and format values from the unpacked val.
1274
1318
# Finally, compile function as for to_binary.
1277
self.parse_binary = new.instancemethod(parse_binary, self, self.__class__)
1320
g = globals().copy()
1322
self.parse_binary = types.MethodType(g['parse_binary'], self)
1279
1324
# Call it manually
1280
1325
return self.parse_binary(data, display, rawdict)
1286
1331
String8('string', pad = 0) )
1288
1333
def pack_value(self, value):
1292
1337
for v in value:
1293
1338
# Let values be simple strings, meaning a delta of 0
1294
if type(v) is types.StringType:
1339
if _PY3 and type(v) is str:
1340
v = v.encode('UTF-8')
1342
if type(v) is bytes:
1297
1345
# A tuple, it should be (delta, string)
1298
1346
# Encode it as one or more textitems
1300
if type(v) in (types.TupleType, types.DictType) or \
1348
if type(v) in (tuple, dict) or \
1301
1349
isinstance(v, DictWrapper):
1303
if type(v) is types.TupleType:
1351
if type(v) is tuple:
1306
1354
delta = v['delta']
1310
1358
args['delta'] = delta
1311
args['string'] = str[:254]
1359
args['string'] = s[:254]
1313
data = data + apply(self.string_textitem.to_binary, (), args)
1361
data = data + self.string_textitem.to_binary(*(), **args)
1318
1366
# Else an integer, i.e. a font change
1320
1368
# Use fontable cast function if instance
1321
if type(v) is types.InstanceType:
1369
if hasattr(v, '__fontable__'):
1322
1370
v = v.__fontable__()
1324
1372
data = data + struct.pack('>BL', 255, v)
1326
1374
# Pad out to four byte length
1327
1375
dlen = len(data)
1328
return data + '\0' * ((4 - dlen % 4) % 4), None, None
1376
return data + b'\0' * ((4 - dlen % 4) % 4), None, None
1330
1378
def parse_binary_value(self, data, display, length, format):
1337
if ord(data[0]) == 255:
1338
values.append(struct.unpack('>L', str(data[1:5]))[0])
1339
data = buffer(data, 5)
1385
if _bytes_item(data[0]) == 255:
1386
values.append(struct.unpack('>L', data[1:5])[0])
1341
1389
# skip null strings
1342
elif ord(data[0]) == 0 and ord(data[1]) == 0:
1343
data = buffer(data, 2)
1390
elif _bytes_item(data[0]) == 0 and _bytes_item(data[1]) == 0:
1345
1393
# string with delta
1347
1395
v, data = self.string_textitem.parse_binary(data, display)
1348
1396
values.append(v)
1393
1441
def __repr__(self):
1394
1442
return '%s(%s)' % (self.__class__, repr(self._data))
1396
def __cmp__(self, other):
1444
def __eq__(self, other):
1397
1445
if isinstance(other, DictWrapper):
1398
return cmp(self._data, other._data)
1446
return self._data == other._data
1400
return cmp(self._data, other)
1448
return self._data == other
1450
def __ne__(self, other):
1451
return not self.__eq__(other)
1404
1454
def __init__(self, display, onerror = None, *args, **keys):
1405
1455
self._errorhandler = onerror
1406
self._binary = apply(self._request.to_binary, args, keys)
1456
self._binary = self._request.to_binary(*args, **keys)
1407
1457
self._serial = None
1408
1458
display.send_request(self, onerror is not None)
1416
1466
class ReplyRequest(GetAttrData):
1417
1467
def __init__(self, display, defer = 0, *args, **keys):
1418
1468
self._display = display
1419
self._binary = apply(self._request.to_binary, args, keys)
1469
self._binary = self._request.to_binary(*args, **keys)
1420
1470
self._serial = None
1421
1471
self._data = None
1422
1472
self._error = None
1479
1529
keys['sequence_number'] = 0
1481
self._binary = apply(self._fields.to_binary, (), keys)
1531
self._binary = self._fields.to_binary(*(), **keys)
1483
1533
keys['send_event'] = 0
1484
1534
self._data = keys
1492
1542
val = val | 0x80
1493
1543
kwlist.append('%s = %s' % (kw, repr(val)))
1495
kws = string.join(kwlist, ', ')
1545
kws = ', '.join(kwlist)
1496
1546
return '%s(%s)' % (self.__class__, kws)
1498
def __cmp__(self, other):
1548
def __eq__(self, other):
1499
1549
if isinstance(other, Event):
1500
return cmp(self._data, other._data)
1550
return self._data == other._data
1502
1552
return cmp(self._data, other)
1505
1554
def call_error_handler(handler, error, request):
1507
1556
return handler(error, request)