From The Compiler, 6 Years ago, written in Python.
Embed
  1. # Xlib.protocol.rq -- structure primitives for request, events and errors
  2. #
  3. #    Copyright (C) 2000-2002 Peter Liljenberg <petli@ctrl-c.liu.se>
  4. #
  5. #    This program is free software; you can redistribute it and/or modify
  6. #    it under the terms of the GNU General Public License as published by
  7. #    the Free Software Foundation; either version 2 of the License, or
  8. #    (at your option) any later version.
  9. #
  10. #    This program is distributed in the hope that it will be useful,
  11. #    but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. #    GNU General Public License for more details.
  14. #
  15. #    You should have received a copy of the GNU General Public License
  16. #    along with this program; if not, write to the Free Software
  17. #    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18.  
  19.  
  20. # Standard modules
  21. import sys
  22. import traceback
  23. import struct
  24. import string
  25. from array import array
  26. import types
  27.  
  28. # Xlib modules
  29. from Xlib import X
  30. from Xlib.support import lock
  31.  
  32.  
  33. class BadDataError(Exception): pass
  34.  
  35. # These are struct codes, we know their byte sizes
  36.  
  37. signed_codes = { 1: 'b', 2: 'h', 4: 'l' }
  38. unsigned_codes = { 1: 'B', 2: 'H', 4: 'L' }
  39.  
  40.  
  41. # Unfortunately, we don't know the array sizes of B, H and L, since
  42. # these use the underlying architecture's size for a char, short and
  43. # long.  Therefore we probe for their sizes, and additionally create
  44. # a mapping that translates from struct codes to array codes.
  45. #
  46. # Bleah.
  47.  
  48. array_unsigned_codes = { }
  49. struct_to_array_codes = { }
  50.  
  51. for c in 'bhil':
  52.     size = array(c).itemsize
  53.  
  54.     array_unsigned_codes[size] = c.upper()
  55.     try:
  56.         struct_to_array_codes[signed_codes[size]] = c
  57.         struct_to_array_codes[unsigned_codes[size]] = c.upper()
  58.     except KeyError:
  59.         pass
  60.  
  61. # print array_unsigned_codes, struct_to_array_codes
  62.  
  63.  
  64. class Field:
  65.     """Field objects represent the data fields of a Struct.
  66.  
  67.    Field objects must have the following attributes:
  68.  
  69.       name         -- the field name, or None
  70.       structcode   -- the struct codes representing this field
  71.       structvalues -- the number of values encodes by structcode
  72.  
  73.    Additionally, these attributes should either be None or real methods:
  74.  
  75.       check_value  -- check a value before it is converted to binary
  76.       parse_value  -- parse a value after it has been converted from binary
  77.  
  78.    If one of these attributes are None, no check or additional
  79.    parsings will be done one values when converting to or from binary
  80.    form.  Otherwise, the methods should have the following behaviour:
  81.  
  82.       newval = check_value(val)
  83.         Check that VAL is legal when converting to binary form.  The
  84.         value can also be converted to another Python value.  In any
  85.         case, return the possibly new value.  NEWVAL should be a
  86.         single Python value if structvalues is 1, a tuple of
  87.         structvalues elements otherwise.
  88.  
  89.       newval = parse_value(val, display)
  90.         VAL is an unpacked Python value, which now can be further
  91.         refined.  DISPLAY is the current Display object.  Return the
  92.         new value.  VAL will be a single value if structvalues is 1,
  93.         a tuple of structvalues elements otherwise.
  94.  
  95.    If `structcode' is None the Field must have the method
  96.    f.parse_binary_value() instead.  See its documentation string for
  97.    details.
  98.  
  99.    """
  100.  
  101.     name = None
  102.     default = None
  103.  
  104.     structcode = None
  105.     structvalues = 0
  106.  
  107.     check_value = None
  108.     parse_value = None
  109.  
  110.     keyword_args = 0
  111.  
  112.     def __init__(self):
  113.         pass
  114.  
  115.     def parse_binary_value(self, data, display, length, format):
  116.         """value, remaindata = f.parse_binary_value(data, display, length, format)
  117.  
  118.        Decode a value for this field from the binary string DATA.
  119.        If there are a LengthField and/or a FormatField connected to this
  120.        field, their values will be LENGTH and FORMAT, respectively.  If
  121.        there are no such fields the parameters will be None.
  122.  
  123.        DISPLAY is the display involved, which is really only used by
  124.        the Resource fields.
  125.  
  126.        The decoded value is returned as VALUE, and the remaining part
  127.        of DATA shold be returned as REMAINDATA.
  128.        """
  129.  
  130.         raise RuntimeError('Neither structcode or parse_binary_value provided for %s'
  131.                            % self)
  132.  
  133.  
  134. class Pad(Field):
  135.     def __init__(self, size):
  136.         self.size = size
  137.         self.value = '\0' * size
  138.         self.structcode = '%dx' % size
  139.         self.structvalues = 0
  140.  
  141.  
  142. class ConstantField(Field):
  143.     def __init__(self, value):
  144.         self.value = value
  145.  
  146.  
  147. class Opcode(ConstantField):
  148.     structcode = 'B'
  149.     structvalues = 1
  150.  
  151. class ReplyCode(ConstantField):
  152.     structcode = 'B'
  153.     structvalues = 1
  154.  
  155.     def __init__(self):
  156.         self.value = 1
  157.  
  158. class LengthField(Field):
  159.     """A LengthField stores the length of some other Field whose size
  160.    may vary, e.g. List and String8.
  161.  
  162.    Its name should be the same as the name of the field whose size
  163.    it stores.
  164.  
  165.    The lf.get_binary_value() method of LengthFields is not used, instead
  166.    a lf.get_binary_length() should be provided.
  167.  
  168.    Unless LengthField.get_binary_length() is overridden in child classes,
  169.    there should also be a lf.calc_length().
  170.    """
  171.  
  172.     structcode = 'L'
  173.     structvalues = 1
  174.  
  175.     def calc_length(self, length):
  176.         """newlen = lf.calc_length(length)
  177.  
  178.        Return a new length NEWLEN based on the provided LENGTH.
  179.        """
  180.  
  181.         return length
  182.  
  183.  
  184. class TotalLengthField(LengthField):
  185.     pass
  186.  
  187. class RequestLength(TotalLengthField):
  188.     structcode = 'H'
  189.     structvalues = 1
  190.  
  191.     def calc_length(self, length):
  192.         return length / 4
  193.  
  194. class ReplyLength(TotalLengthField):
  195.     structcode = 'L'
  196.     structvalues = 1
  197.  
  198.     def calc_length(self, length):
  199.         return (length - 32) / 4
  200.  
  201.  
  202. class LengthOf(LengthField):
  203.     def __init__(self, name, size):
  204.         self.name = name
  205.         self.structcode = unsigned_codes[size]
  206.  
  207.  
  208. class OddLength(LengthField):
  209.     structcode = 'B'
  210.     structvalues = 1
  211.  
  212.     def __init__(self, name):
  213.         self.name = name
  214.  
  215.     def calc_length(self, length):
  216.         return length % 2
  217.  
  218.     def parse_value(self, value, display):
  219.         if value == 0:
  220.             return 'even'
  221.         else:
  222.             return 'odd'
  223.  
  224.  
  225. class FormatField(Field):
  226.     """A FormatField encodes the format of some other field, in a manner
  227.    similar to LengthFields.
  228.  
  229.    The ff.get_binary_value() method is not used, replaced by
  230.    ff.get_binary_format().
  231.    """
  232.  
  233.     structvalues = 1
  234.  
  235.     def __init__(self, name, size):
  236.         self.name = name
  237.         self.structcode = unsigned_codes[size]
  238.  
  239. Format = FormatField
  240.  
  241.  
  242. class ValueField(Field):
  243.     def __init__(self, name, default = None):
  244.         self.name = name
  245.         self.default = default
  246.  
  247.  
  248. class Int8(ValueField):
  249.     structcode = 'b'
  250.     structvalues = 1
  251.  
  252. class Int16(ValueField):
  253.     structcode = 'h'
  254.     structvalues = 1
  255.  
  256. class Int32(ValueField):
  257.     structcode = 'l'
  258.     structvalues = 1
  259.  
  260. class Card8(ValueField):
  261.     structcode = 'B'
  262.     structvalues = 1
  263.  
  264. class Card16(ValueField):
  265.     structcode = 'H'
  266.     structvalues = 1
  267.  
  268. class Card32(ValueField):
  269.     structcode = 'L'
  270.     structvalues = 1
  271.  
  272.  
  273. class Resource(Card32):
  274.     cast_function = '__resource__'
  275.     class_name = 'resource'
  276.  
  277.     def __init__(self, name, codes = (), default = None):
  278.         Card32.__init__(self, name, default)
  279.         self.codes = codes
  280.  
  281.     def check_value(self, value):
  282.         if type(value) is types.InstanceType:
  283.             return getattr(value, self.cast_function)()
  284.         else:
  285.             return value
  286.  
  287.     def parse_value(self, value, display):
  288.         # if not display:
  289.         #    return value
  290.         if value in self.codes:
  291.             return value
  292.  
  293.         c = display.get_resource_class(self.class_name)
  294.         if c:
  295.             return c(display, value)
  296.         else:
  297.             return value
  298.  
  299. class Window(Resource):
  300.     cast_function = '__window__'
  301.     class_name = 'window'
  302.  
  303. class Pixmap(Resource):
  304.     cast_function = '__pixmap__'
  305.     class_name = 'pixmap'
  306.  
  307. class Drawable(Resource):
  308.     cast_function = '__drawable__'
  309.     class_name = 'drawable'
  310.  
  311. class Fontable(Resource):
  312.     cast_function = '__fontable__'
  313.     class_name = 'fontable'
  314.  
  315. class Font(Resource):
  316.     cast_function = '__font__'
  317.     class_name = 'font'
  318.  
  319. class GC(Resource):
  320.     cast_function = '__gc__'
  321.     class_name = 'gc'
  322.  
  323. class Colormap(Resource):
  324.     cast_function = '__colormap__'
  325.     class_name = 'colormap'
  326.  
  327. class Cursor(Resource):
  328.     cast_function = '__cursor__'
  329.     class_name = 'cursor'
  330.  
  331.  
  332. class Bool(ValueField):
  333.     structvalues = 1
  334.     structcode = 'B'
  335.  
  336.     def check_value(self, value):
  337.         return not not value
  338.  
  339. class Set(ValueField):
  340.     structvalues = 1
  341.  
  342.     def __init__(self, name, size, values, default = None):
  343.         ValueField.__init__(self, name, default)
  344.         self.structcode = unsigned_codes[size]
  345.         self.values = values
  346.  
  347.     def check_value(self, val):
  348.         if val not in self.values:
  349.             raise ValueError('field %s: argument %s not in %s'
  350.                              % (self.name, val, self.values))
  351.  
  352.         return val
  353.  
  354. class Gravity(Set):
  355.     def __init__(self, name):
  356.         Set.__init__(self, name, 1, (X.ForgetGravity, X.StaticGravity,
  357.                                     X.NorthWestGravity, X.NorthGravity,
  358.                                     X.NorthEastGravity, X.WestGravity,
  359.                                     X.CenterGravity, X.EastGravity,
  360.                                     X.SouthWestGravity, X.SouthGravity,
  361.                                     X.SouthEastGravity))
  362.  
  363.  
  364. class FixedString(ValueField):
  365.     structvalues = 1
  366.  
  367.     def __init__(self, name, size):
  368.         ValueField.__init__(self, name)
  369.         self.structcode = '%ds' % size
  370.  
  371.  
  372. class String8(ValueField):
  373.     structcode = None
  374.  
  375.     def __init__(self, name, pad = 1):
  376.         ValueField.__init__(self, name)
  377.         self.pad = pad
  378.  
  379.     def pack_value(self, val):
  380.         slen = len(val)
  381.  
  382.         if self.pad:
  383.             return val + '\0' * ((4 - slen % 4) % 4), slen, None
  384.         else:
  385.             return val, slen, None
  386.  
  387.     def parse_binary_value(self, data, display, length, format):
  388.         if length is None:
  389.             return str(data), ''
  390.  
  391.         if self.pad:
  392.             slen = length + ((4 - length % 4) % 4)
  393.         else:
  394.             slen = length
  395.  
  396.         return str(data[:length]), buffer(data, slen)
  397.  
  398.  
  399. class String16(ValueField):
  400.     structcode = None
  401.  
  402.     def __init__(self, name, pad = 1):
  403.         ValueField.__init__(self, name)
  404.         self.pad = pad
  405.  
  406.     def pack_value(self, val):
  407.         # Convert 8-byte string into 16-byte list
  408.         if type(val) is bytes:
  409.             val = [ord(c) for c in val]
  410.  
  411.         slen = len(val)
  412.  
  413.         if self.pad:
  414.             pad = '\0\0' * (slen % 2)
  415.         else:
  416.             pad = ''
  417.  
  418.         return struct.pack(*('>' + 'H' * slen, ) + tuple(val)) + pad, slen, None
  419.  
  420.     def parse_binary_value(self, data, display, length, format):
  421.         if length == 'odd':
  422.             length = len(data) / 2 - 1
  423.         elif length == 'even':
  424.             length = len(data) / 2
  425.  
  426.         if self.pad:
  427.             slen = length + (length % 2)
  428.         else:
  429.             slen = length
  430.  
  431.         return struct.unpack('>' + 'H' * length, data[:length * 2]), buffer(data, slen * 2)
  432.  
  433.  
  434.  
  435. class List(ValueField):
  436.     """The List, FixedList and Object fields store compound data objects.
  437.    The type of data objects must be provided as an object with the
  438.    following attributes and methods:
  439.  
  440.    ...
  441.  
  442.    """
  443.  
  444.     structcode = None
  445.  
  446.     def __init__(self, name, type, pad = 1):
  447.         ValueField.__init__(self, name)
  448.         self.type = type
  449.         self.pad = pad
  450.  
  451.     def parse_binary_value(self, data, display, length, format):
  452.         if length is None:
  453.             ret = []
  454.             if self.type.structcode is None:
  455.                 while data:
  456.                     val, data = self.type.parse_binary(data, display)
  457.                     ret.append(val)
  458.             else:
  459.                 scode = '=' + self.type.structcode
  460.                 slen = struct.calcsize(scode)
  461.                 pos = 0
  462.                 while pos + slen <= len(data):
  463.                     v = struct.unpack(scode, data[pos: pos + slen])
  464.  
  465.                     if self.type.structvalues == 1:
  466.                         v = v[0]
  467.  
  468.                     if self.type.parse_value is None:
  469.                         ret.append(v)
  470.                     else:
  471.                         ret.append(self.type.parse_value(v, display))
  472.  
  473.                     pos = pos + slen
  474.  
  475.                 data = buffer(data, pos)
  476.  
  477.         else:
  478.             ret = [None] * int(length)
  479.  
  480.             if self.type.structcode is None:
  481.                 for i in range(0, length):
  482.                     ret[i], data = self.type.parse_binary(data, display)
  483.             else:
  484.                 scode = '=' + self.type.structcode
  485.                 slen = struct.calcsize(scode)
  486.                 pos = 0
  487.                 for i in range(0, length):
  488.                     v = struct.unpack(scode, data[pos: pos + slen])
  489.  
  490.                     if self.type.structvalues == 1:
  491.                         v = v[0]
  492.  
  493.                     if self.type.parse_value is None:
  494.                         ret[i] = v
  495.                     else:
  496.                         ret[i] = self.type.parse_value(v, display)
  497.  
  498.                     pos = pos + slen
  499.  
  500.                 data = buffer(data, pos)
  501.  
  502.         if self.pad:
  503.             data = buffer(data, len(data) % 4)
  504.  
  505.         return ret, data
  506.  
  507.     def pack_value(self, val):
  508.         # Single-char values, we'll assume that means integer lists.
  509.         if self.type.structcode and len(self.type.structcode) == 1:
  510.             data = array(struct_to_array_codes[self.type.structcode],
  511.                                val).tostring()
  512.         else:
  513.             data = []
  514.             for v in val:
  515.                 data.append(self.type.pack_value(v))
  516.  
  517.             data = ''.join(data)
  518.  
  519.         if self.pad:
  520.             dlen = len(data)
  521.             data = str(data) + '\0' * ((4 - dlen % 4) % 4)
  522.  
  523.         return data, len(val), None
  524.  
  525.  
  526. class FixedList(List):
  527.     def __init__(self, name, size, type, pad = 1):
  528.         List.__init__(self, name, type, pad)
  529.         self.size = size
  530.  
  531.     def parse_binary_value(self, data, display, length, format):
  532.         return List.parse_binary_value(self, data, display, self.size, format)
  533.  
  534.     def pack_value(self, val):
  535.         if len(val) != self.size:
  536.             raise BadDataError('length mismatch for FixedList %s' % self.name)
  537.         return List.pack_value(self, val)
  538.  
  539.  
  540. class Object(ValueField):
  541.     structcode = None
  542.  
  543.     def __init__(self, name, type, default = None):
  544.         ValueField.__init__(self, name, default)
  545.         self.type = type
  546.         self.structcode = self.type.structcode
  547.         self.structvalues = self.type.structvalues
  548.  
  549.     def parse_binary_value(self, data, display, length, format):
  550.         if self.type.structcode is None:
  551.             return self.type.parse_binary(data, display)
  552.  
  553.         else:
  554.             scode = '=' + self.type.structcode
  555.             slen = struct.calcsize(scode)
  556.  
  557.             v = struct.unpack(scode, data[:slen])
  558.             if self.type.structvalues == 1:
  559.                 v = v[0]
  560.  
  561.             if self.type.parse_value is not None:
  562.                 v = self.type.parse_value(v, display)
  563.  
  564.             return v, buffer(data, slen)
  565.  
  566.     def parse_value(self, val, display):
  567.         if self.type.parse_value is None:
  568.             return val
  569.         else:
  570.             return self.type.parse_value(val, display)
  571.  
  572.     def pack_value(self, val):
  573.         # Single-char values, we'll assume that mean an integer
  574.         if self.type.structcode and len(self.type.structcode) == 1:
  575.             return struct.pack('=' + self.type.structcode, val), None, None
  576.         else:
  577.             return self.type.pack_value(val)
  578.  
  579.     def check_value(self, val):
  580.         if self.type.structcode is None:
  581.             return val
  582.  
  583.         if type(val) is tuple:
  584.             return val
  585.  
  586.         if type(val) is dict:
  587.             data = val
  588.         elif isinstance(val, DictWrapper):
  589.             data = val._data
  590.         else:
  591.             raise TypeError('Object value must be tuple, dictionary or DictWrapper: %s' % val)
  592.  
  593.         vals = []
  594.         for f in self.type.fields:
  595.             if f.name:
  596.                 vals.append(data[f.name])
  597.  
  598.         return vals
  599.  
  600.  
  601. class PropertyData(ValueField):
  602.     structcode = None
  603.  
  604.     def parse_binary_value(self, data, display, length, format):
  605.         if length is None:
  606.             length = len(data) / (format / 8)
  607.         else:
  608.             length = int(length)
  609.  
  610.         if format == 0:
  611.             ret = None
  612.  
  613.         elif format == 8:
  614.             ret = (8, str(data[:length]))
  615.             data = buffer(data, length + ((4 - length % 4) % 4))
  616.  
  617.         elif format == 16:
  618.             ret = (16, array(array_unsigned_codes[2], str(data[:2 * length])))
  619.             data = buffer(data, 2 * (length + length % 2))
  620.  
  621.         elif format == 32:
  622.             ret = (32, array(array_unsigned_codes[4], str(data[:4 * length])))
  623.             data = buffer(data, 4 * length)
  624.  
  625.         return ret, data
  626.  
  627.     def pack_value(self, value):
  628.         fmt, val = value
  629.  
  630.         if fmt not in (8, 16, 32):
  631.             raise BadDataError('Invalid property data format %d' % fmt)
  632.  
  633.         if type(val) is bytes:
  634.             size = fmt / 8
  635.             vlen = len(val)
  636.             if vlen % size:
  637.                 vlen = vlen - vlen % size
  638.                 data = val[:vlen]
  639.             else:
  640.                 data = val
  641.  
  642.             dlen = vlen / size
  643.  
  644.         else:
  645.             if type(val) is tuple:
  646.                 val = list(val)
  647.  
  648.             size = fmt / 8
  649.             data =  array(array_unsigned_codes[size], val).tostring()
  650.             dlen = len(val)
  651.  
  652.         dl = len(data)
  653.         data = str(data) + '\0' * ((4 - dl % 4) % 4)
  654.  
  655.         return data, dlen, fmt
  656.  
  657.  
  658. class FixedPropertyData(PropertyData):
  659.     def __init__(self, name, size):
  660.         PropertyData.__init__(self, name)
  661.         self.size = size
  662.  
  663.     def parse_binary_value(self, data, display, length, format):
  664.         return PropertyData.parse_binary_value(self, data, display,
  665.                                                self.size / (format / 8), format)
  666.  
  667.     def pack_value(self, value):
  668.         data, dlen, fmt = PropertyData.pack_value(self, value)
  669.  
  670.         if len(data) != self.size:
  671.             raise BadDataError('Wrong data length for FixedPropertyData: %s'
  672.                                % (value, ))
  673.  
  674.         return data, dlen, fmt
  675.  
  676.  
  677. class ValueList(Field):
  678.     structcode = None
  679.     keyword_args = 1
  680.     default = 'usekeywords'
  681.  
  682.     def __init__(self, name, mask, pad, *fields):
  683.         self.name = name
  684.         self.maskcode = '=%s%dx' % (unsigned_codes[mask], pad)
  685.         self.maskcodelen = struct.calcsize(self.maskcode)
  686.         self.fields = []
  687.  
  688.         flag = 1
  689.         for f in fields:
  690.             if f.name:
  691.                 self.fields.append((f, flag))
  692.                 flag = flag << 1
  693.  
  694.     def pack_value(self, arg, keys):
  695.         mask = 0
  696.         data = ''
  697.  
  698.         if arg == self.default:
  699.             arg = keys
  700.  
  701.         for field, flag in self.fields:
  702.             if field.name in arg:
  703.                 mask = mask | flag
  704.  
  705.                 val = arg[field.name]
  706.                 if field.check_value is not None:
  707.                     val = field.check_value(val)
  708.  
  709.                 d = struct.pack('=' + field.structcode, val)
  710.                 data = data + d + '\0' * (4 - len(d))
  711.  
  712.         return struct.pack(self.maskcode, mask) + data, None, None
  713.  
  714.     def parse_binary_value(self, data, display, length, format):
  715.         r = {}
  716.  
  717.         mask = int(struct.unpack(self.maskcode, data[:self.maskcodelen])[0])
  718.         data = buffer(data, self.maskcodelen)
  719.  
  720.         for field, flag in self.fields:
  721.             if mask & flag:
  722.                 if field.structcode:
  723.                     vals = struct.unpack('=' + field.structcode,
  724.                                          data[:struct.calcsize('=' + field.structcode)])
  725.                     if field.structvalues == 1:
  726.                         vals = vals[0]
  727.  
  728.                     if field.parse_value is not None:
  729.                         vals = field.parse_value(vals, display)
  730.  
  731.                 else:
  732.                     vals, d = field.parse_binary_value(data[:4], display, None, None)
  733.  
  734.                 r[field.name] = vals
  735.                 data = buffer(data, 4)
  736.  
  737.         return DictWrapper(r), data
  738.  
  739.  
  740. class KeyboardMapping(ValueField):
  741.     structcode = None
  742.  
  743.     def parse_binary_value(self, data, display, length, format):
  744.         if length is None:
  745.             dlen = len(data)
  746.         else:
  747.             dlen = 4 * length * format
  748.  
  749.         a = array(array_unsigned_codes[4], str(data[:dlen]))
  750.  
  751.         ret = []
  752.         for i in range(0, len(a), format):
  753.             ret.append(a[i : i + format])
  754.  
  755.         return ret, buffer(data, dlen)
  756.  
  757.     def pack_value(self, value):
  758.         keycodes = 0
  759.         for v in value:
  760.             keycodes = max(keycodes, len(v))
  761.  
  762.         a = array(array_unsigned_codes[4])
  763.  
  764.         for v in value:
  765.             for k in v:
  766.                 a.append(k)
  767.             for i in range(len(v), keycodes):
  768.                 a.append(X.NoSymbol)
  769.  
  770.         return a.tostring(), len(value), keycodes
  771.  
  772.  
  773. class ModifierMapping(ValueField):
  774.     structcode = None
  775.  
  776.     def parse_binary_value(self, data, display, length, format):
  777.         a = array(array_unsigned_codes[1], str(data[:8 * format]))
  778.  
  779.         ret = []
  780.         for i in range(0, 8):
  781.             ret.append(a[i * format : (i + 1) * format])
  782.  
  783.         return ret, buffer(data, 8 * format)
  784.  
  785.     def pack_value(self, value):
  786.         if len(value) != 8:
  787.             raise BadDataError('ModifierMapping list should have eight elements')
  788.  
  789.         keycodes = 0
  790.         for v in value:
  791.             keycodes = max(keycodes, len(v))
  792.  
  793.         a = array(array_unsigned_codes[1])
  794.  
  795.         for v in value:
  796.             for k in v:
  797.                 a.append(k)
  798.             for i in range(len(v), keycodes):
  799.                 a.append(0)
  800.  
  801.         return a.tostring(), len(value), keycodes
  802.  
  803. class EventField(ValueField):
  804.     structcode = None
  805.  
  806.     def pack_value(self, value):
  807.         if not isinstance(value, Event):
  808.             raise BadDataError('%s is not an Event for field %s' % (value, self.name))
  809.  
  810.         return value._binary, None, None
  811.  
  812.     def parse_binary_value(self, data, display, length, format):
  813.         from . import event
  814.  
  815.         estruct = display.event_classes.get(ord(data[0]) & 0x7f, event.AnyEvent)
  816.  
  817.         return estruct(display = display, binarydata = data[:32]), buffer(data, 32)
  818.  
  819.  
  820. #
  821. # Objects usable for List and FixedList fields.
  822. # Struct is also usable.
  823. #
  824.  
  825. class ScalarObj:
  826.     def __init__(self, code):
  827.         self.structcode = code
  828.         self.structvalues = 1
  829.         self.parse_value = None
  830.  
  831. Card8Obj  = ScalarObj('B')
  832. Card16Obj = ScalarObj('H')
  833. Card32Obj = ScalarObj('L')
  834.  
  835. class ResourceObj:
  836.     structcode = 'L'
  837.     structvalues = 1
  838.  
  839.     def __init__(self, class_name):
  840.         self.class_name = class_name
  841.  
  842.     def parse_value(self, value, display):
  843.         # if not display:
  844.         #     return value
  845.         c = display.get_resource_class(self.class_name)
  846.         if c:
  847.             return c(display, value)
  848.         else:
  849.             return value
  850.  
  851. WindowObj = ResourceObj('window')
  852. ColormapObj = ResourceObj('colormap')
  853.  
  854. class StrClass:
  855.     structcode = None
  856.  
  857.     def pack_value(self, val):
  858.         return chr(len(val)) + val
  859.  
  860.     def parse_binary(self, data, display):
  861.         slen = ord(data[0]) + 1
  862.         return data[1:slen], buffer(data, slen)
  863.  
  864. Str = StrClass()
  865.  
  866.  
  867. class Struct:
  868.  
  869.     """Struct objects represents a binary data structure.  It can
  870.    contain both fields with static and dynamic sizes.  However, all
  871.    static fields must appear before all dynamic fields.
  872.  
  873.    Fields are represented by various subclasses of the abstract base
  874.    class Field.  The fields of a structure are given as arguments
  875.    when instantiating a Struct object.
  876.  
  877.    Struct objects have two public methods:
  878.  
  879.      to_binary()    -- build a binary representation of the structure
  880.                        with the values given as arguments
  881.      parse_binary() -- convert a binary (string) representation into
  882.                        a Python dictionary or object.
  883.  
  884.    These functions will be generated dynamically for each Struct
  885.    object to make conversion as fast as possible.  They are
  886.    generated the first time the methods are called.
  887.  
  888.    """
  889.  
  890.     def __init__(self, *fields):
  891.         self.fields = fields
  892.  
  893.         # Structures for to_binary, parse_value and parse_binary
  894.         self.static_codes = '='
  895.         self.static_values = 0
  896.         self.static_fields = []
  897.         self.static_size = None
  898.         self.var_fields = []
  899.  
  900.         for f in self.fields:
  901.             # Append structcode if there is one and we haven't
  902.             # got any varsize fields yet.
  903.             if f.structcode is not None:
  904.                 assert not self.var_fields
  905.  
  906.                 self.static_codes = self.static_codes + f.structcode
  907.  
  908.                 # Only store fields with values
  909.                 if f.structvalues > 0:
  910.                     self.static_fields.append(f)
  911.                     self.static_values = self.static_values + f.structvalues
  912.  
  913.             # If we have got one varsize field, all the rest must
  914.             # also be varsize fields.
  915.             else:
  916.                 self.var_fields.append(f)
  917.  
  918.         self.static_size = struct.calcsize(self.static_codes)
  919.         if self.var_fields:
  920.             self.structcode = None
  921.             self.structvalues = 0
  922.         else:
  923.             self.structcode = self.static_codes[1:]
  924.             self.structvalues = self.static_values
  925.  
  926.  
  927.     # These functions get called only once, as they will override
  928.     # themselves with dynamically created functions in the Struct
  929.     # object
  930.  
  931.     def to_binary(self, *varargs, **keys):
  932.  
  933.         """data = s.to_binary(...)
  934.  
  935.        Convert Python values into the binary representation.  The
  936.        arguments will be all value fields with names, in the order
  937.        given when the Struct object was instantiated.  With one
  938.        exception: fields with default arguments will be last.
  939.  
  940.        Returns the binary representation as the string DATA.
  941.  
  942.        """
  943.  
  944.         code = ''
  945.         total_length = str(self.static_size)
  946.         joins = []
  947.         args = []
  948.         defargs = []
  949.         kwarg = 0
  950.  
  951.         # First pack all varfields so their lengths and formats are
  952.         # available when we pack their static LengthFields and
  953.         # FormatFields
  954.  
  955.         i = 0
  956.         for f in self.var_fields:
  957.             if f.keyword_args:
  958.                 kwarg = 1
  959.                 kw = ', _keyword_args'
  960.             else:
  961.                 kw = ''
  962.  
  963.             # Call pack_value method for each field, storing
  964.             # the return values for later use
  965.             code = code + ('  _%(name)s, _%(name)s_length, _%(name)s_format'
  966.                            ' = self.var_fields[%(fno)d].pack_value(%(name)s%(kw)s)\n'
  967.                            % { 'name': f.name,
  968.                                'fno': i,
  969.                                'kw': kw })
  970.  
  971.             total_length = total_length + ' + len(_%s)' % f.name
  972.             joins.append('_%s' % f.name)
  973.  
  974.             i = i + 1
  975.  
  976.  
  977.         # Construct argument list for struct.pack call, packing all
  978.         # static fields.  First argument is the structcode, the
  979.         # remaining are values.
  980.  
  981.         pack_args = ['"%s"' % self.static_codes]
  982.  
  983.         i = 0
  984.         for f in self.static_fields:
  985.             if isinstance(f, LengthField):
  986.  
  987.                 # If this is a total length field, insert
  988.                 # the calculated field value here
  989.                 if isinstance(f, TotalLengthField):
  990.                     if self.var_fields:
  991.                         pack_args.append('self.static_fields[%d].calc_length(%s)'
  992.                                          % (i, total_length))
  993.                     else:
  994.                         pack_args.append(str(f.calc_length(self.static_size)))
  995.                 else:
  996.                     pack_args.append('self.static_fields[%d].calc_length(_%s_length)'
  997.                                        % (i, f.name))
  998.  
  999.             # Format field, just insert the value we got previously
  1000.             elif isinstance(f, FormatField):
  1001.                 pack_args.append('_%s_format' % f.name)
  1002.  
  1003.             # A constant field, insert its value directly
  1004.             elif isinstance(f, ConstantField):
  1005.                 pack_args.append(str(f.value))
  1006.  
  1007.             # Value fields
  1008.             else:
  1009.                 if f.structvalues == 1:
  1010.  
  1011.                     # If there's a value check/convert function, call it
  1012.                     if f.check_value is not None:
  1013.                         pack_args.append('self.static_fields[%d].check_value(%s)'
  1014.                                            % (i, f.name))
  1015.  
  1016.                     # Else just use the argument as provided
  1017.                     else:
  1018.                         pack_args.append(f.name)
  1019.  
  1020.                 # Multivalue field.  Handled like single valuefield,
  1021.                 # but the value are tuple unpacked into seperate arguments
  1022.                 # which are appended to pack_args
  1023.                 else:
  1024.                     a = []
  1025.                     for j in range(f.structvalues):
  1026.                         a.append('_%s_%d' % (f.name, j))
  1027.  
  1028.                     if f.check_value is not None:
  1029.                         code = code + ('  %s = self.static_fields[%d].check_value(%s)\n'
  1030.                                        % (', '.join(a), i, f.name))
  1031.                     else:
  1032.                         code = code + '  %s = %s\n' % (', '.join(a), f.name)
  1033.  
  1034.                     pack_args = pack_args + a
  1035.  
  1036.                 # Add field to argument list
  1037.                 if f.name:
  1038.                     if f.default is None:
  1039.                         args.append(f.name)
  1040.                     else:
  1041.                         defargs.append('%s = %s' % (f.name, repr(f.default)))
  1042.  
  1043.             i = i + 1
  1044.  
  1045.  
  1046.         # Construct call to struct.pack
  1047.         pack = 'struct.pack(%s)' % ', '.join(pack_args)
  1048.  
  1049.         # If there are any varfields, we append the packed strings to build
  1050.         # the resulting binary value
  1051.         if self.var_fields:
  1052.             code = code + '  return %s + %s\n' % (pack, ' + '.join(joins))
  1053.  
  1054.         # If there's only static fields, return the packed value
  1055.         else:
  1056.             code = code + '  return %s\n' % pack
  1057.  
  1058.         # Add all varsize fields to argument list.  We do it here
  1059.         # to ensure that they appear after the static fields.
  1060.         for f in self.var_fields:
  1061.             if f.name:
  1062.                 if f.default is None:
  1063.                     args.append(f.name)
  1064.                 else:
  1065.                     defargs.append('%s = %s' % (f.name, repr(f.default)))
  1066.  
  1067.         args = args + defargs
  1068.         if kwarg:
  1069.             args.append('**_keyword_args')
  1070.  
  1071.         # Add function header
  1072.         code = 'def to_binary(self, %s):\n' % ', '.join(args) + code
  1073.  
  1074.         # self._pack_code = code
  1075.  
  1076.         # print
  1077.         # print code
  1078.         # print
  1079.  
  1080.         # Finally, compile function by evaluating it.  This will store
  1081.         # the function in the local variable to_binary, thanks to the
  1082.         # def: line.  Convert it into a instance metod bound to self,
  1083.         # and store it in self.
  1084.  
  1085.         # Unfortunately, this creates a circular reference.  However,
  1086.         # Structs are not really created dynamically so the potential
  1087.         # memory leak isn't that serious.  Besides, Python 2.0 has
  1088.         # real garbage collect.
  1089.  
  1090.         ldict = locals()
  1091.         exec(code, globals(), ldict)
  1092.         to_binary = ldict['to_binary']
  1093.         to_binary = types.MethodType(to_binary, self)
  1094.  
  1095.         # Finally call it manually
  1096.         return to_binary(*varargs, **keys)
  1097.  
  1098.  
  1099.     def pack_value(self, value):
  1100.  
  1101.         """ This function allows Struct objects to be used in List and
  1102.        Object fields.  Each item represents the arguments to pass to
  1103.        to_binary, either a tuple, a dictionary or a DictWrapper.
  1104.  
  1105.        """
  1106.  
  1107.         if type(value) is tuple:
  1108.             return self.to_binary(*value, **{})
  1109.         elif type(value) is dict:
  1110.             return self.to_binary(*(), **value)
  1111.         elif isinstance(value, DictWrapper):
  1112.             return self.to_binary(*(), **value._data)
  1113.         else:
  1114.             raise BadDataError('%s is not a tuple or a list' % (value))
  1115.  
  1116.  
  1117.     def parse_value(self, val, display, rawdict = 0):
  1118.  
  1119.         """This function is used by List and Object fields to convert
  1120.        Struct objects with no var_fields into Python values.
  1121.  
  1122.        """
  1123.  
  1124.         code = ('def parse_value(self, val, display, rawdict = 0):\n'
  1125.                 '  ret = {}\n')
  1126.  
  1127.         vno = 0
  1128.         fno = 0
  1129.         for f in self.static_fields:
  1130.             # Fields without names should be ignored, and there should
  1131.             # not be any length or format fields if this function
  1132.             # ever gets called.  (If there were such fields, there should
  1133.             # be a matching field in var_fields and then parse_binary
  1134.             # would have been called instead.
  1135.  
  1136.             if not f.name:
  1137.                 pass
  1138.  
  1139.             elif isinstance(f, LengthField):
  1140.                 pass
  1141.  
  1142.             elif isinstance(f, FormatField):
  1143.                 pass
  1144.  
  1145.             # Value fields
  1146.             else:
  1147.  
  1148.                 # Get the index or range in val representing this field.
  1149.  
  1150.                 if f.structvalues == 1:
  1151.                     vrange = str(vno)
  1152.                 else:
  1153.                     vrange = '%d:%d' % (vno, vno + f.structvalues)
  1154.  
  1155.                 # If this field has a parse_value method, call it, otherwise
  1156.                 # use the unpacked value as is.
  1157.  
  1158.                 if f.parse_value is None:
  1159.                     code = code + '  ret["%s"] = val[%s]\n' % (f.name, vrange)
  1160.                 else:
  1161.                     code = code + ('  ret["%s"] = self.static_fields[%d].'
  1162.                                    'parse_value(val[%s], display)\n'
  1163.                                    % (f.name, fno, vrange))
  1164.  
  1165.             fno = fno + 1
  1166.             vno = vno + f.structvalues
  1167.  
  1168.         code = code + '  if not rawdict: return DictWrapper(ret)\n'
  1169.         code = code + '  return ret\n'
  1170.  
  1171.         # print
  1172.         # print code
  1173.         # print
  1174.  
  1175.         # Finally, compile function as for to_binary.
  1176.  
  1177.         ldict = locals()
  1178.         exec(code, globals(), ldict)
  1179.         parse_value = ldict['parse_value']
  1180.         self.parse_value = types.MethodType(parse_value, self)
  1181.  
  1182.         # Call it manually
  1183.         return self.parse_value(val, display, rawdict)
  1184.  
  1185.  
  1186.     def parse_binary(self, data, display, rawdict = 0):
  1187.  
  1188.         """values, remdata = s.parse_binary(data, display, rawdict = 0)
  1189.  
  1190.        Convert a binary representation of the structure into Python values.
  1191.  
  1192.        DATA is a string or a buffer containing the binary data.
  1193.        DISPLAY should be a Xlib.protocol.display.Display object if
  1194.        there are any Resource fields or Lists with ResourceObjs.
  1195.  
  1196.        The Python values are returned as VALUES.  If RAWDICT is true,
  1197.        a Python dictionary is returned, where the keys are field
  1198.        names and the values are the corresponding Python value.  If
  1199.        RAWDICT is false, a DictWrapper will be returned where all
  1200.        fields are available as attributes.
  1201.  
  1202.        REMDATA are the remaining binary data, unused by the Struct object.
  1203.  
  1204.        """
  1205.  
  1206.         code = ('def parse_binary(self, data, display, rawdict = 0):\n'
  1207.                 '  ret = {}\n'
  1208.                 '  val = struct.unpack("%s", data[:%d])\n'
  1209.                 % (self.static_codes, self.static_size))
  1210.  
  1211.         lengths = {}
  1212.         formats = {}
  1213.  
  1214.         vno = 0
  1215.         fno = 0
  1216.         for f in self.static_fields:
  1217.  
  1218.             # Fields without name should be ignored.  This is typically
  1219.             # pad and constant fields
  1220.  
  1221.             if not f.name:
  1222.                 pass
  1223.  
  1224.             # Store index in val for Length and Format fields, to be used
  1225.             # when treating varfields.
  1226.  
  1227.             elif isinstance(f, LengthField):
  1228.                 if f.parse_value is None:
  1229.                     lengths[f.name] = 'val[%d]' % vno
  1230.                 else:
  1231.                     lengths[f.name] = ('self.static_fields[%d].'
  1232.                                        'parse_value(val[%d], display)'
  1233.                                        % (fno, vno))
  1234.  
  1235.             elif isinstance(f, FormatField):
  1236.                 formats[f.name] = 'val[%d]' % vno
  1237.  
  1238.             # Treat value fields the same was as in parse_value.
  1239.             else:
  1240.                 if f.structvalues == 1:
  1241.                     vrange = str(vno)
  1242.                 else:
  1243.                     vrange = '%d:%d' % (vno, vno + f.structvalues)
  1244.  
  1245.                 if f.parse_value is None:
  1246.                     code = code + '  ret["%s"] = val[%s]\n' % (f.name, vrange)
  1247.                 else:
  1248.                     code = code + ('  ret["%s"] = self.static_fields[%d].'
  1249.                                    'parse_value(val[%s], display)\n'
  1250.                                    % (f.name, fno, vrange))
  1251.  
  1252.             fno = fno + 1
  1253.             vno = vno + f.structvalues
  1254.  
  1255.         code = code + '  data = buffer(data, %d)\n' % self.static_size
  1256.  
  1257.         # Call parse_binary_value for each var_field, passing the
  1258.         # length and format values from the unpacked val.
  1259.  
  1260.         fno = 0
  1261.         for f in self.var_fields:
  1262.             code = code + ('  ret["%s"], data = '
  1263.                            'self.var_fields[%d].parse_binary_value'
  1264.                            '(data, display, %s, %s)\n'
  1265.                            % (f.name, fno,
  1266.                               lengths.get(f.name, 'None'),
  1267.                               formats.get(f.name, 'None')))
  1268.             fno = fno + 1
  1269.  
  1270.         code = code + '  if not rawdict: ret = DictWrapper(ret)\n'
  1271.         code = code + '  return ret, data\n'
  1272.  
  1273.         # print
  1274.         # print code
  1275.         # print
  1276.  
  1277.         # Finally, compile function as for to_binary.
  1278.  
  1279.         ldict = locals()
  1280.         exec(code, globals(), ldict)
  1281.         parse_binary = ldict['parse_binary']
  1282.         self.parse_binary = types.MethodType(parse_binary, self)
  1283.  
  1284.         # Call it manually
  1285.         return self.parse_binary(data, display, rawdict)
  1286.  
  1287.  
  1288. class TextElements8(ValueField):
  1289.     string_textitem = Struct( LengthOf('string', 1),
  1290.                               Int8('delta'),
  1291.                               String8('string', pad = 0) )
  1292.  
  1293.     def pack_value(self, value):
  1294.         data = ''
  1295.         args = {}
  1296.  
  1297.         for v in value:
  1298.             # Let values be simple strings, meaning a delta of 0
  1299.             if type(v) is bytes:
  1300.                 v = (0, v)
  1301.  
  1302.             # A tuple, it should be (delta, string)
  1303.             # Encode it as one or more textitems
  1304.  
  1305.             if type(v) in (tuple, dict) or \
  1306.                isinstance(v, DictWrapper):
  1307.  
  1308.                 if type(v) is tuple:
  1309.                     delta, str = v
  1310.                 else:
  1311.                     delta = v['delta']
  1312.                     str = v['string']
  1313.  
  1314.                 while delta or str:
  1315.                     args['delta'] = delta
  1316.                     args['string'] = str[:254]
  1317.  
  1318.                     data = data + self.string_textitem.to_binary(*(), **args)
  1319.  
  1320.                     delta = 0
  1321.                     str = str[254:]
  1322.  
  1323.             # Else an integer, i.e. a font change
  1324.             else:
  1325.                 # Use fontable cast function if instance
  1326.                 if type(v) is types.InstanceType:
  1327.                     v = v.__fontable__()
  1328.  
  1329.                 data = data + struct.pack('>BL', 255, v)
  1330.  
  1331.         # Pad out to four byte length
  1332.         dlen = len(data)
  1333.         return data + '\0' * ((4 - dlen % 4) % 4), None, None
  1334.  
  1335.     def parse_binary_value(self, data, display, length, format):
  1336.         values = []
  1337.         while 1:
  1338.             if len(data) < 2:
  1339.                 break
  1340.  
  1341.             # font change
  1342.             if ord(data[0]) == 255:
  1343.                 values.append(struct.unpack('>L', str(data[1:5]))[0])
  1344.                 data = buffer(data, 5)
  1345.  
  1346.             # skip null strings
  1347.             elif ord(data[0]) == 0 and ord(data[1]) == 0:
  1348.                 data = buffer(data, 2)
  1349.  
  1350.             # string with delta
  1351.             else:
  1352.                 v, data = self.string_textitem.parse_binary(data, display)
  1353.                 values.append(v)
  1354.  
  1355.         return values, ''
  1356.  
  1357.  
  1358.  
  1359. class TextElements16(TextElements8):
  1360.     string_textitem = Struct( LengthOf('string', 1),
  1361.                               Int8('delta'),
  1362.                               String16('string', pad = 0) )
  1363.  
  1364.  
  1365.  
  1366. class GetAttrData:
  1367.     def __getattr__(self, attr):
  1368.         try:
  1369.             if self._data:
  1370.                 return self._data[attr]
  1371.             else:
  1372.                 raise AttributeError(attr)
  1373.         except KeyError:
  1374.             raise AttributeError(attr)
  1375.  
  1376. class DictWrapper(GetAttrData):
  1377.     def __init__(self, dict):
  1378.         self.__dict__['_data'] = dict
  1379.  
  1380.     def __getitem__(self, key):
  1381.         return self._data[key]
  1382.  
  1383.     def __setitem__(self, key, value):
  1384.         self._data[key] = value
  1385.  
  1386.     def __delitem__(self, key):
  1387.         del self._data[key]
  1388.  
  1389.     def __setattr__(self, key, value):
  1390.         self._data[key] = value
  1391.  
  1392.     def __delattr__(self, key):
  1393.         del self._data[key]
  1394.  
  1395.     def __str__(self):
  1396.         return str(self._data)
  1397.  
  1398.     def __repr__(self):
  1399.         return '%s(%s)' % (self.__class__, repr(self._data))
  1400.  
  1401.     def __cmp__(self, other):
  1402.         if isinstance(other, DictWrapper):
  1403.             return cmp(self._data, other._data)
  1404.         else:
  1405.             return cmp(self._data, other)
  1406.  
  1407.  
  1408. class Request:
  1409.     def __init__(self, display, onerror = None, *args, **keys):
  1410.         self._errorhandler = onerror
  1411.         self._binary = self._request.to_binary(*args, **keys)
  1412.         self._serial = None
  1413.         display.send_request(self, onerror is not None)
  1414.  
  1415.     def _set_error(self, error):
  1416.         if self._errorhandler is not None:
  1417.             return call_error_handler(self._errorhandler, error, self)
  1418.         else:
  1419.             return 0
  1420.  
  1421. class ReplyRequest(GetAttrData):
  1422.     def __init__(self, display, defer = 0, *args, **keys):
  1423.         self._display = display
  1424.         self._binary = self._request.to_binary(*args, **keys)
  1425.         self._serial = None
  1426.         self._data = None
  1427.         self._error = None
  1428.  
  1429.         self._response_lock = lock.allocate_lock()
  1430.  
  1431.         self._display.send_request(self, 1)
  1432.         if not defer:
  1433.             self.reply()
  1434.  
  1435.     def reply(self):
  1436.         # Send request and wait for reply if we hasn't
  1437.         # already got one.  This means that reply() can safely
  1438.         # be called more than one time.
  1439.  
  1440.         self._response_lock.acquire()
  1441.         while self._data is None and self._error is None:
  1442.             self._display.send_recv_lock.acquire()
  1443.             self._response_lock.release()
  1444.  
  1445.             self._display.send_and_recv(request = self._serial)
  1446.             self._response_lock.acquire()
  1447.  
  1448.         self._response_lock.release()
  1449.         self._display = None
  1450.  
  1451.         # If error has been set, raise it
  1452.         if self._error:
  1453.             raise self._error
  1454.  
  1455.     def _parse_response(self, data):
  1456.         self._response_lock.acquire()
  1457.         self._data, d = self._reply.parse_binary(data, self._display, rawdict = 1)
  1458.         self._response_lock.release()
  1459.  
  1460.     def _set_error(self, error):
  1461.         self._response_lock.acquire()
  1462.         self._error = error
  1463.         self._response_lock.release()
  1464.         return 1
  1465.  
  1466.     def __repr__(self):
  1467.         return '<%s serial = %s, data = %s, error = %s>' % (self.__class__, self._serial, self._data, self._error)
  1468.  
  1469.  
  1470. class Event(GetAttrData):
  1471.     def __init__(self, binarydata = None, display = None,
  1472.                  **keys):
  1473.         if binarydata:
  1474.             self._binary = binarydata
  1475.             self._data, data = self._fields.parse_binary(binarydata, display,
  1476.                                                          rawdict = 1)
  1477.             # split event type into type and send_event bit
  1478.             self._data['send_event'] = not not self._data['type'] & 0x80
  1479.             self._data['type'] = self._data['type'] & 0x7f
  1480.         else:
  1481.             if self._code:
  1482.                 keys['type'] = self._code
  1483.  
  1484.             keys['sequence_number'] = 0
  1485.  
  1486.             self._binary = self._fields.to_binary(*(), **keys)
  1487.  
  1488.             keys['send_event'] = 0
  1489.             self._data = keys
  1490.  
  1491.     def __repr__(self):
  1492.         kwlist = []
  1493.         for kw, val in list(self._data.items()):
  1494.             if kw == 'send_event':
  1495.                 continue
  1496.             if kw == 'type' and self._data['send_event']:
  1497.                 val = val | 0x80
  1498.             kwlist.append('%s = %s' % (kw, repr(val)))
  1499.  
  1500.         kws = ', '.join(kwlist)
  1501.         return '%s(%s)' % (self.__class__, kws)
  1502.  
  1503.     def __cmp__(self, other):
  1504.         if isinstance(other, Event):
  1505.             return cmp(self._data, other._data)
  1506.         else:
  1507.             return cmp(self._data, other)
  1508.  
  1509.  
  1510. def call_error_handler(handler, error, request):
  1511.     try:
  1512.         return handler(error, request)
  1513.     except:
  1514.         sys.stderr.write('Exception raised by error handler.\n')
  1515.         traceback.print_exc()
  1516.         return 0