1import xcffib 2import struct 3import six 4MAJOR_VERSION = 3 5MINOR_VERSION = 1 6key = xcffib.ExtensionKey("SYNC") 7_events = {} 8_errors = {} 9from . import xproto 10class ALARMSTATE: 11 Active = 0 12 Inactive = 1 13 Destroyed = 2 14class TESTTYPE: 15 PositiveTransition = 0 16 NegativeTransition = 1 17 PositiveComparison = 2 18 NegativeComparison = 3 19class VALUETYPE: 20 Absolute = 0 21 Relative = 1 22class CA: 23 Counter = 1 << 0 24 ValueType = 1 << 1 25 Value = 1 << 2 26 TestType = 1 << 3 27 Delta = 1 << 4 28 Events = 1 << 5 29class INT64(xcffib.Struct): 30 def __init__(self, unpacker): 31 if isinstance(unpacker, xcffib.Protobj): 32 unpacker = xcffib.MemoryUnpacker(unpacker.pack()) 33 xcffib.Struct.__init__(self, unpacker) 34 base = unpacker.offset 35 self.hi, self.lo = unpacker.unpack("iI") 36 self.bufsize = unpacker.offset - base 37 def pack(self): 38 buf = six.BytesIO() 39 buf.write(struct.pack("=iI", self.hi, self.lo)) 40 return buf.getvalue() 41 fixed_size = 8 42 @classmethod 43 def synthetic(cls, hi, lo): 44 self = cls.__new__(cls) 45 self.hi = hi 46 self.lo = lo 47 return self 48class SYSTEMCOUNTER(xcffib.Struct): 49 def __init__(self, unpacker): 50 if isinstance(unpacker, xcffib.Protobj): 51 unpacker = xcffib.MemoryUnpacker(unpacker.pack()) 52 xcffib.Struct.__init__(self, unpacker) 53 base = unpacker.offset 54 self.counter, = unpacker.unpack("I") 55 self.resolution = INT64(unpacker) 56 self.name_len, = unpacker.unpack("H") 57 unpacker.pad("c") 58 self.name = xcffib.List(unpacker, "c", self.name_len) 59 self.bufsize = unpacker.offset - base 60 def pack(self): 61 buf = six.BytesIO() 62 buf.write(struct.pack("=IH", self.counter, self.name_len)) 63 buf.write(self.resolution.pack() if hasattr(self.resolution, "pack") else INT64.synthetic(*self.resolution).pack()) 64 buf.write(xcffib.pack_list(self.name, "c")) 65 return buf.getvalue() 66 @classmethod 67 def synthetic(cls, counter, resolution, name_len, name): 68 self = cls.__new__(cls) 69 self.counter = counter 70 self.resolution = resolution 71 self.name_len = name_len 72 self.name = name 73 return self 74class TRIGGER(xcffib.Struct): 75 def __init__(self, unpacker): 76 if isinstance(unpacker, xcffib.Protobj): 77 unpacker = xcffib.MemoryUnpacker(unpacker.pack()) 78 xcffib.Struct.__init__(self, unpacker) 79 base = unpacker.offset 80 self.counter, self.wait_type = unpacker.unpack("II") 81 self.wait_value = INT64(unpacker) 82 self.test_type, = unpacker.unpack("I") 83 self.bufsize = unpacker.offset - base 84 def pack(self): 85 buf = six.BytesIO() 86 buf.write(struct.pack("=III", self.counter, self.wait_type, self.test_type)) 87 buf.write(self.wait_value.pack() if hasattr(self.wait_value, "pack") else INT64.synthetic(*self.wait_value).pack()) 88 return buf.getvalue() 89 @classmethod 90 def synthetic(cls, counter, wait_type, wait_value, test_type): 91 self = cls.__new__(cls) 92 self.counter = counter 93 self.wait_type = wait_type 94 self.wait_value = wait_value 95 self.test_type = test_type 96 return self 97class WAITCONDITION(xcffib.Struct): 98 def __init__(self, unpacker): 99 if isinstance(unpacker, xcffib.Protobj): 100 unpacker = xcffib.MemoryUnpacker(unpacker.pack()) 101 xcffib.Struct.__init__(self, unpacker) 102 base = unpacker.offset 103 self.trigger = TRIGGER(unpacker) 104 unpacker.pad(INT64) 105 self.event_threshold = INT64(unpacker) 106 self.bufsize = unpacker.offset - base 107 def pack(self): 108 buf = six.BytesIO() 109 buf.write(self.trigger.pack() if hasattr(self.trigger, "pack") else TRIGGER.synthetic(*self.trigger).pack()) 110 buf.write(self.event_threshold.pack() if hasattr(self.event_threshold, "pack") else INT64.synthetic(*self.event_threshold).pack()) 111 return buf.getvalue() 112 @classmethod 113 def synthetic(cls, trigger, event_threshold): 114 self = cls.__new__(cls) 115 self.trigger = trigger 116 self.event_threshold = event_threshold 117 return self 118class CounterError(xcffib.Error): 119 def __init__(self, unpacker): 120 if isinstance(unpacker, xcffib.Protobj): 121 unpacker = xcffib.MemoryUnpacker(unpacker.pack()) 122 xcffib.Error.__init__(self, unpacker) 123 base = unpacker.offset 124 self.bad_counter, self.minor_opcode, self.major_opcode = unpacker.unpack("xx2xIHB") 125 self.bufsize = unpacker.offset - base 126 def pack(self): 127 buf = six.BytesIO() 128 buf.write(struct.pack("=B", 0)) 129 buf.write(struct.pack("=x2xIHB", self.bad_counter, self.minor_opcode, self.major_opcode)) 130 return buf.getvalue() 131BadCounter = CounterError 132_errors[0] = CounterError 133class AlarmError(xcffib.Error): 134 def __init__(self, unpacker): 135 if isinstance(unpacker, xcffib.Protobj): 136 unpacker = xcffib.MemoryUnpacker(unpacker.pack()) 137 xcffib.Error.__init__(self, unpacker) 138 base = unpacker.offset 139 self.bad_alarm, self.minor_opcode, self.major_opcode = unpacker.unpack("xx2xIHB") 140 self.bufsize = unpacker.offset - base 141 def pack(self): 142 buf = six.BytesIO() 143 buf.write(struct.pack("=B", 1)) 144 buf.write(struct.pack("=x2xIHB", self.bad_alarm, self.minor_opcode, self.major_opcode)) 145 return buf.getvalue() 146BadAlarm = AlarmError 147_errors[1] = AlarmError 148class InitializeReply(xcffib.Reply): 149 def __init__(self, unpacker): 150 if isinstance(unpacker, xcffib.Protobj): 151 unpacker = xcffib.MemoryUnpacker(unpacker.pack()) 152 xcffib.Reply.__init__(self, unpacker) 153 base = unpacker.offset 154 self.major_version, self.minor_version = unpacker.unpack("xx2x4xBB22x") 155 self.bufsize = unpacker.offset - base 156class InitializeCookie(xcffib.Cookie): 157 reply_type = InitializeReply 158class ListSystemCountersReply(xcffib.Reply): 159 def __init__(self, unpacker): 160 if isinstance(unpacker, xcffib.Protobj): 161 unpacker = xcffib.MemoryUnpacker(unpacker.pack()) 162 xcffib.Reply.__init__(self, unpacker) 163 base = unpacker.offset 164 self.counters_len, = unpacker.unpack("xx2x4xI20x") 165 self.counters = xcffib.List(unpacker, SYSTEMCOUNTER, self.counters_len) 166 self.bufsize = unpacker.offset - base 167class ListSystemCountersCookie(xcffib.Cookie): 168 reply_type = ListSystemCountersReply 169class QueryCounterReply(xcffib.Reply): 170 def __init__(self, unpacker): 171 if isinstance(unpacker, xcffib.Protobj): 172 unpacker = xcffib.MemoryUnpacker(unpacker.pack()) 173 xcffib.Reply.__init__(self, unpacker) 174 base = unpacker.offset 175 unpacker.unpack("xx2x4x") 176 self.counter_value = INT64(unpacker) 177 self.bufsize = unpacker.offset - base 178class QueryCounterCookie(xcffib.Cookie): 179 reply_type = QueryCounterReply 180class QueryAlarmReply(xcffib.Reply): 181 def __init__(self, unpacker): 182 if isinstance(unpacker, xcffib.Protobj): 183 unpacker = xcffib.MemoryUnpacker(unpacker.pack()) 184 xcffib.Reply.__init__(self, unpacker) 185 base = unpacker.offset 186 unpacker.unpack("xx2x4x") 187 self.trigger = TRIGGER(unpacker) 188 unpacker.pad(INT64) 189 self.delta = INT64(unpacker) 190 self.events, self.state = unpacker.unpack("BB2x") 191 self.bufsize = unpacker.offset - base 192class QueryAlarmCookie(xcffib.Cookie): 193 reply_type = QueryAlarmReply 194class GetPriorityReply(xcffib.Reply): 195 def __init__(self, unpacker): 196 if isinstance(unpacker, xcffib.Protobj): 197 unpacker = xcffib.MemoryUnpacker(unpacker.pack()) 198 xcffib.Reply.__init__(self, unpacker) 199 base = unpacker.offset 200 self.priority, = unpacker.unpack("xx2x4xi") 201 self.bufsize = unpacker.offset - base 202class GetPriorityCookie(xcffib.Cookie): 203 reply_type = GetPriorityReply 204class QueryFenceReply(xcffib.Reply): 205 def __init__(self, unpacker): 206 if isinstance(unpacker, xcffib.Protobj): 207 unpacker = xcffib.MemoryUnpacker(unpacker.pack()) 208 xcffib.Reply.__init__(self, unpacker) 209 base = unpacker.offset 210 self.triggered, = unpacker.unpack("xx2x4xB23x") 211 self.bufsize = unpacker.offset - base 212class QueryFenceCookie(xcffib.Cookie): 213 reply_type = QueryFenceReply 214class CounterNotifyEvent(xcffib.Event): 215 def __init__(self, unpacker): 216 if isinstance(unpacker, xcffib.Protobj): 217 unpacker = xcffib.MemoryUnpacker(unpacker.pack()) 218 xcffib.Event.__init__(self, unpacker) 219 base = unpacker.offset 220 self.kind, self.counter = unpacker.unpack("xB2xI") 221 self.wait_value = INT64(unpacker) 222 unpacker.pad(INT64) 223 self.counter_value = INT64(unpacker) 224 self.timestamp, self.count, self.destroyed = unpacker.unpack("IHBx") 225 self.bufsize = unpacker.offset - base 226 def pack(self): 227 buf = six.BytesIO() 228 buf.write(struct.pack("=B", 0)) 229 buf.write(struct.pack("=B2xIIHBx", self.kind, self.counter, self.timestamp, self.count, self.destroyed)) 230 buf.write(self.wait_value.pack() if hasattr(self.wait_value, "pack") else INT64.synthetic(*self.wait_value).pack()) 231 buf.write(self.counter_value.pack() if hasattr(self.counter_value, "pack") else INT64.synthetic(*self.counter_value).pack()) 232 buf_len = len(buf.getvalue()) 233 if buf_len < 32: 234 buf.write(struct.pack("x" * (32 - buf_len))) 235 return buf.getvalue() 236 @classmethod 237 def synthetic(cls, kind, counter, wait_value, counter_value, timestamp, count, destroyed): 238 self = cls.__new__(cls) 239 self.kind = kind 240 self.counter = counter 241 self.wait_value = wait_value 242 self.counter_value = counter_value 243 self.timestamp = timestamp 244 self.count = count 245 self.destroyed = destroyed 246 return self 247_events[0] = CounterNotifyEvent 248class AlarmNotifyEvent(xcffib.Event): 249 def __init__(self, unpacker): 250 if isinstance(unpacker, xcffib.Protobj): 251 unpacker = xcffib.MemoryUnpacker(unpacker.pack()) 252 xcffib.Event.__init__(self, unpacker) 253 base = unpacker.offset 254 self.kind, self.alarm = unpacker.unpack("xB2xI") 255 self.counter_value = INT64(unpacker) 256 unpacker.pad(INT64) 257 self.alarm_value = INT64(unpacker) 258 self.timestamp, self.state = unpacker.unpack("IB3x") 259 self.bufsize = unpacker.offset - base 260 def pack(self): 261 buf = six.BytesIO() 262 buf.write(struct.pack("=B", 1)) 263 buf.write(struct.pack("=B2xIIB3x", self.kind, self.alarm, self.timestamp, self.state)) 264 buf.write(self.counter_value.pack() if hasattr(self.counter_value, "pack") else INT64.synthetic(*self.counter_value).pack()) 265 buf.write(self.alarm_value.pack() if hasattr(self.alarm_value, "pack") else INT64.synthetic(*self.alarm_value).pack()) 266 buf_len = len(buf.getvalue()) 267 if buf_len < 32: 268 buf.write(struct.pack("x" * (32 - buf_len))) 269 return buf.getvalue() 270 @classmethod 271 def synthetic(cls, kind, alarm, counter_value, alarm_value, timestamp, state): 272 self = cls.__new__(cls) 273 self.kind = kind 274 self.alarm = alarm 275 self.counter_value = counter_value 276 self.alarm_value = alarm_value 277 self.timestamp = timestamp 278 self.state = state 279 return self 280_events[1] = AlarmNotifyEvent 281class syncExtension(xcffib.Extension): 282 def Initialize(self, desired_major_version, desired_minor_version, is_checked=True): 283 buf = six.BytesIO() 284 buf.write(struct.pack("=xx2xBB", desired_major_version, desired_minor_version)) 285 return self.send_request(0, buf, InitializeCookie, is_checked=is_checked) 286 def ListSystemCounters(self, is_checked=True): 287 buf = six.BytesIO() 288 buf.write(struct.pack("=xx2x")) 289 return self.send_request(1, buf, ListSystemCountersCookie, is_checked=is_checked) 290 def CreateCounter(self, id, initial_value, is_checked=False): 291 buf = six.BytesIO() 292 buf.write(struct.pack("=xx2xI", id)) 293 buf.write(initial_value.pack() if hasattr(initial_value, "pack") else INT64.synthetic(*initial_value).pack()) 294 return self.send_request(2, buf, is_checked=is_checked) 295 def DestroyCounter(self, counter, is_checked=False): 296 buf = six.BytesIO() 297 buf.write(struct.pack("=xx2xI", counter)) 298 return self.send_request(6, buf, is_checked=is_checked) 299 def QueryCounter(self, counter, is_checked=True): 300 buf = six.BytesIO() 301 buf.write(struct.pack("=xx2xI", counter)) 302 return self.send_request(5, buf, QueryCounterCookie, is_checked=is_checked) 303 def Await(self, wait_list_len, wait_list, is_checked=False): 304 buf = six.BytesIO() 305 buf.write(struct.pack("=xx2x")) 306 buf.write(xcffib.pack_list(wait_list, WAITCONDITION)) 307 return self.send_request(7, buf, is_checked=is_checked) 308 def ChangeCounter(self, counter, amount, is_checked=False): 309 buf = six.BytesIO() 310 buf.write(struct.pack("=xx2xI", counter)) 311 buf.write(amount.pack() if hasattr(amount, "pack") else INT64.synthetic(*amount).pack()) 312 return self.send_request(4, buf, is_checked=is_checked) 313 def SetCounter(self, counter, value, is_checked=False): 314 buf = six.BytesIO() 315 buf.write(struct.pack("=xx2xI", counter)) 316 buf.write(value.pack() if hasattr(value, "pack") else INT64.synthetic(*value).pack()) 317 return self.send_request(3, buf, is_checked=is_checked) 318 def CreateAlarm(self, id, value_mask, value_list, is_checked=False): 319 buf = six.BytesIO() 320 buf.write(struct.pack("=xx2xII", id, value_mask)) 321 if value_mask & CA.Counter: 322 counter = value_list.pop(0) 323 buf.write(struct.pack("=I", counter)) 324 if value_mask & CA.ValueType: 325 valueType = value_list.pop(0) 326 buf.write(struct.pack("=I", valueType)) 327 if value_mask & CA.Value: 328 value = value_list.pop(0) 329 buf.write(value.pack() if hasattr(value, "pack") else INT64.synthetic(*value).pack()) 330 if value_mask & CA.TestType: 331 testType = value_list.pop(0) 332 buf.write(struct.pack("=I", testType)) 333 if value_mask & CA.Delta: 334 delta = value_list.pop(0) 335 buf.write(delta.pack() if hasattr(delta, "pack") else INT64.synthetic(*delta).pack()) 336 if value_mask & CA.Events: 337 events = value_list.pop(0) 338 buf.write(struct.pack("=I", events)) 339 return self.send_request(8, buf, is_checked=is_checked) 340 def ChangeAlarm(self, id, value_mask, value_list, is_checked=False): 341 buf = six.BytesIO() 342 buf.write(struct.pack("=xx2xII", id, value_mask)) 343 if value_mask & CA.Counter: 344 counter = value_list.pop(0) 345 buf.write(struct.pack("=I", counter)) 346 if value_mask & CA.ValueType: 347 valueType = value_list.pop(0) 348 buf.write(struct.pack("=I", valueType)) 349 if value_mask & CA.Value: 350 value = value_list.pop(0) 351 buf.write(value.pack() if hasattr(value, "pack") else INT64.synthetic(*value).pack()) 352 if value_mask & CA.TestType: 353 testType = value_list.pop(0) 354 buf.write(struct.pack("=I", testType)) 355 if value_mask & CA.Delta: 356 delta = value_list.pop(0) 357 buf.write(delta.pack() if hasattr(delta, "pack") else INT64.synthetic(*delta).pack()) 358 if value_mask & CA.Events: 359 events = value_list.pop(0) 360 buf.write(struct.pack("=I", events)) 361 return self.send_request(9, buf, is_checked=is_checked) 362 def DestroyAlarm(self, alarm, is_checked=False): 363 buf = six.BytesIO() 364 buf.write(struct.pack("=xx2xI", alarm)) 365 return self.send_request(11, buf, is_checked=is_checked) 366 def QueryAlarm(self, alarm, is_checked=True): 367 buf = six.BytesIO() 368 buf.write(struct.pack("=xx2xI", alarm)) 369 return self.send_request(10, buf, QueryAlarmCookie, is_checked=is_checked) 370 def SetPriority(self, id, priority, is_checked=False): 371 buf = six.BytesIO() 372 buf.write(struct.pack("=xx2xIi", id, priority)) 373 return self.send_request(12, buf, is_checked=is_checked) 374 def GetPriority(self, id, is_checked=True): 375 buf = six.BytesIO() 376 buf.write(struct.pack("=xx2xI", id)) 377 return self.send_request(13, buf, GetPriorityCookie, is_checked=is_checked) 378 def CreateFence(self, drawable, fence, initially_triggered, is_checked=False): 379 buf = six.BytesIO() 380 buf.write(struct.pack("=xx2xIIB", drawable, fence, initially_triggered)) 381 return self.send_request(14, buf, is_checked=is_checked) 382 def TriggerFence(self, fence, is_checked=False): 383 buf = six.BytesIO() 384 buf.write(struct.pack("=xx2xI", fence)) 385 return self.send_request(15, buf, is_checked=is_checked) 386 def ResetFence(self, fence, is_checked=False): 387 buf = six.BytesIO() 388 buf.write(struct.pack("=xx2xI", fence)) 389 return self.send_request(16, buf, is_checked=is_checked) 390 def DestroyFence(self, fence, is_checked=False): 391 buf = six.BytesIO() 392 buf.write(struct.pack("=xx2xI", fence)) 393 return self.send_request(17, buf, is_checked=is_checked) 394 def QueryFence(self, fence, is_checked=True): 395 buf = six.BytesIO() 396 buf.write(struct.pack("=xx2xI", fence)) 397 return self.send_request(18, buf, QueryFenceCookie, is_checked=is_checked) 398 def AwaitFence(self, fence_list_len, fence_list, is_checked=False): 399 buf = six.BytesIO() 400 buf.write(struct.pack("=xx2x")) 401 buf.write(xcffib.pack_list(fence_list, "I")) 402 return self.send_request(19, buf, is_checked=is_checked) 403xcffib._add_ext(key, syncExtension, _events, _errors) 404