aioxlib 0.3.0__tar.gz → 0.4.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. {aioxlib-0.3.0 → aioxlib-0.4.0}/PKG-INFO +6 -2
  2. {aioxlib-0.3.0 → aioxlib-0.4.0}/README.md +5 -1
  3. {aioxlib-0.3.0 → aioxlib-0.4.0}/aioxlib/__init__.py +1 -1
  4. {aioxlib-0.3.0 → aioxlib-0.4.0}/aioxlib/display.py +49 -34
  5. {aioxlib-0.3.0 → aioxlib-0.4.0}/aioxlib/glx.py +96 -22
  6. {aioxlib-0.3.0 → aioxlib-0.4.0}/aioxlib/protocol.py +8 -6
  7. {aioxlib-0.3.0 → aioxlib-0.4.0}/aioxlib.egg-info/PKG-INFO +6 -2
  8. {aioxlib-0.3.0 → aioxlib-0.4.0}/tests/test_glx.py +4 -4
  9. {aioxlib-0.3.0 → aioxlib-0.4.0}/aioxlib/_extensions.py +0 -0
  10. {aioxlib-0.3.0 → aioxlib-0.4.0}/aioxlib/api.py +0 -0
  11. {aioxlib-0.3.0 → aioxlib-0.4.0}/aioxlib/authority.py +0 -0
  12. {aioxlib-0.3.0 → aioxlib-0.4.0}/aioxlib/bigreq.py +0 -0
  13. {aioxlib-0.3.0 → aioxlib-0.4.0}/aioxlib/connection.py +0 -0
  14. {aioxlib-0.3.0 → aioxlib-0.4.0}/aioxlib/constants.py +0 -0
  15. {aioxlib-0.3.0 → aioxlib-0.4.0}/aioxlib/dbe.py +0 -0
  16. {aioxlib-0.3.0 → aioxlib-0.4.0}/aioxlib/dri3.py +0 -0
  17. {aioxlib-0.3.0 → aioxlib-0.4.0}/aioxlib/present.py +0 -0
  18. {aioxlib-0.3.0 → aioxlib-0.4.0}/aioxlib/render.py +0 -0
  19. {aioxlib-0.3.0 → aioxlib-0.4.0}/aioxlib/shm.py +0 -0
  20. {aioxlib-0.3.0 → aioxlib-0.4.0}/aioxlib.egg-info/SOURCES.txt +0 -0
  21. {aioxlib-0.3.0 → aioxlib-0.4.0}/aioxlib.egg-info/dependency_links.txt +0 -0
  22. {aioxlib-0.3.0 → aioxlib-0.4.0}/aioxlib.egg-info/top_level.txt +0 -0
  23. {aioxlib-0.3.0 → aioxlib-0.4.0}/pyproject.toml +0 -0
  24. {aioxlib-0.3.0 → aioxlib-0.4.0}/setup.cfg +0 -0
  25. {aioxlib-0.3.0 → aioxlib-0.4.0}/tests/test_api.py +0 -0
  26. {aioxlib-0.3.0 → aioxlib-0.4.0}/tests/test_authority.py +0 -0
  27. {aioxlib-0.3.0 → aioxlib-0.4.0}/tests/test_bigreq.py +0 -0
  28. {aioxlib-0.3.0 → aioxlib-0.4.0}/tests/test_connection.py +0 -0
  29. {aioxlib-0.3.0 → aioxlib-0.4.0}/tests/test_constants.py +0 -0
  30. {aioxlib-0.3.0 → aioxlib-0.4.0}/tests/test_dbe.py +0 -0
  31. {aioxlib-0.3.0 → aioxlib-0.4.0}/tests/test_display.py +0 -0
  32. {aioxlib-0.3.0 → aioxlib-0.4.0}/tests/test_dri3.py +0 -0
  33. {aioxlib-0.3.0 → aioxlib-0.4.0}/tests/test_examples.py +0 -0
  34. {aioxlib-0.3.0 → aioxlib-0.4.0}/tests/test_present.py +0 -0
  35. {aioxlib-0.3.0 → aioxlib-0.4.0}/tests/test_protocol.py +0 -0
  36. {aioxlib-0.3.0 → aioxlib-0.4.0}/tests/test_render.py +0 -0
  37. {aioxlib-0.3.0 → aioxlib-0.4.0}/tests/test_shm.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aioxlib
3
- Version: 0.3.0
3
+ Version: 0.4.0
4
4
  Summary: Human friendly interface to XLib subsystems using asyncio python
5
5
  Author-email: Jose Tiago Macara Coutinho <coutinhotiago@gmail.com>
6
6
  License-Expression: GPL-3.0-or-later
@@ -52,6 +52,7 @@ The **root package** exposes the functional API and `get_display` only:
52
52
  import asyncio
53
53
  import aioxlib
54
54
 
55
+
55
56
  async def main():
56
57
  wnd = await aioxlib.create_window(640, 480, title="Hello from aioxlib")
57
58
  await wnd.show()
@@ -60,6 +61,7 @@ async def main():
60
61
  if wnd.is_delete_window(event):
61
62
  break
62
63
 
64
+
63
65
  asyncio.run(main())
64
66
  ```
65
67
 
@@ -69,6 +71,7 @@ asyncio.run(main())
69
71
  import asyncio
70
72
  import aioxlib
71
73
 
74
+
72
75
  async def main():
73
76
  display = await aioxlib.get_display()
74
77
  async with display:
@@ -80,6 +83,7 @@ async def main():
80
83
  if wnd.is_delete_window(event):
81
84
  break
82
85
 
86
+
83
87
  asyncio.run(main())
84
88
  ```
85
89
 
@@ -134,5 +138,5 @@ GPLv3 or later — see [LICENSE](LICENSE).
134
138
 
135
139
  ## Author
136
140
 
137
- José Tiago Macara Coutinho
141
+ José Tiago Macara Coutinho
138
142
  <https://codeberg.org/tiagocoutinho>
@@ -28,6 +28,7 @@ The **root package** exposes the functional API and `get_display` only:
28
28
  import asyncio
29
29
  import aioxlib
30
30
 
31
+
31
32
  async def main():
32
33
  wnd = await aioxlib.create_window(640, 480, title="Hello from aioxlib")
33
34
  await wnd.show()
@@ -36,6 +37,7 @@ async def main():
36
37
  if wnd.is_delete_window(event):
37
38
  break
38
39
 
40
+
39
41
  asyncio.run(main())
40
42
  ```
41
43
 
@@ -45,6 +47,7 @@ asyncio.run(main())
45
47
  import asyncio
46
48
  import aioxlib
47
49
 
50
+
48
51
  async def main():
49
52
  display = await aioxlib.get_display()
50
53
  async with display:
@@ -56,6 +59,7 @@ async def main():
56
59
  if wnd.is_delete_window(event):
57
60
  break
58
61
 
62
+
59
63
  asyncio.run(main())
60
64
  ```
61
65
 
@@ -110,5 +114,5 @@ GPLv3 or later — see [LICENSE](LICENSE).
110
114
 
111
115
  ## Author
112
116
 
113
- José Tiago Macara Coutinho
117
+ José Tiago Macara Coutinho
114
118
  <https://codeberg.org/tiagocoutinho>
@@ -16,7 +16,7 @@ Types and protocol helpers live in submodules::
16
16
  from aioxlib.protocol import pack_create_window
17
17
  """
18
18
 
19
- __version__ = "0.3.0"
19
+ __version__ = "0.4.0"
20
20
 
21
21
  from .api import * # noqa: F403
22
22
  from .api import __all__ as _api_all
@@ -772,7 +772,7 @@ class Display:
772
772
 
773
773
  async def poly_fill_rectangles(self, drawable, gc, rectangles):
774
774
  """Poly fill rectangles."""
775
- if isinstance(rectangles, (bytes, bytearray)):
775
+ if isinstance(rectangles, bytes | bytearray):
776
776
  payload = pack_poly_fill_raw_rectangles(drawable, gc, rectangles)
777
777
  else:
778
778
  payload = pack_poly_fill_rectangles(drawable, gc, rectangles)
@@ -784,7 +784,7 @@ class Display:
784
784
  *arcs* is a sequence of ``(x, y, width, height, angle1, angle2)``
785
785
  with angles in 1/64 degree units, or a pre-packed ``bytes`` LISTofARC.
786
786
  """
787
- if isinstance(arcs, (bytes, bytearray)):
787
+ if isinstance(arcs, bytes | bytearray):
788
788
  payload = pack_poly_fill_raw_arcs(drawable, gc, arcs)
789
789
  else:
790
790
  payload = pack_poly_fill_arcs(drawable, gc, arcs)
@@ -871,42 +871,57 @@ class Display:
871
871
  break
872
872
  return error
873
873
 
874
+ async def _handle_buffer(self, buffer, current_decoder=None):
875
+ packet_type = buffer[0]
876
+ if packet_type == Status.Success:
877
+ if current_decoder is None:
878
+ current_decoder = await self.requests.get()
879
+ decode, future = current_decoder
880
+ if decode == unpack_setup:
881
+ size = 8 + 4 * int.from_bytes(buffer[6:8], BYTE_ORDER_TEXT)
882
+ else:
883
+ size = 32 + 4 * int.from_bytes(buffer[4:8], BYTE_ORDER_TEXT)
884
+ if len(buffer) < size:
885
+ return True, buffer, current_decoder
886
+ try:
887
+ reply, offset = decode(buffer, 0)
888
+ future.set_result(reply)
889
+ except Exception as error:
890
+ future.set_exception(error)
891
+ return False, buffer[offset:], None
892
+ elif packet_type == Status.Failed and not self.requests.empty():
893
+ decode, future = await self.requests.get()
894
+ if decode == unpack_setup:
895
+ # todo: check if buffer is complete
896
+ error, offset = unpack_setup_error(buffer)
897
+ future.set_exception(RuntimeError(error))
898
+ else:
899
+ if len(buffer) < 32:
900
+ return True, buffer, current_decoder
901
+ error, offset = unpack_error(buffer)
902
+ error = self._handle_error(error)
903
+ log.warning("ERROR: %s", error)
904
+ future.set_exception(X11Error(error))
905
+ return False, buffer[offset:], None
906
+
907
+ # An event
908
+ if len(buffer) < 32:
909
+ return True, buffer, current_decoder
910
+ event, offset = unpack_event(self._events, buffer)
911
+ for listener in self.listeners:
912
+ await listener.put(event)
913
+ return False, buffer[offset:], current_decoder
914
+
874
915
  async def _loop(self):
875
- buffer, decoder = b"", None
916
+ buffer, context = b"", None
876
917
  while True:
877
- if not (data := await self.read(4 * 1024)):
918
+ if not (data := await self.read(4096)):
878
919
  log.info("Connection closed")
879
920
  return
880
921
  buffer += data
881
- packet_type = buffer[0]
882
- if packet_type == Status.Success:
883
- if decoder is None:
884
- decoder = await self.requests.get()
885
- decode, future = decoder
886
- if decode == unpack_setup:
887
- size = 8 + 4 * int.from_bytes(buffer[6:8], BYTE_ORDER_TEXT)
888
- else:
889
- size = 32 + 4 * int.from_bytes(buffer[4:8], BYTE_ORDER_TEXT)
890
- if len(buffer) < size:
891
- continue
892
- reply, offset = decode(buffer, 0)
893
- future.set_result(reply)
894
- decoder = None
895
- elif packet_type == Status.Failed and not self.requests.empty():
896
- decode, future = await self.requests.get()
897
- if decode == unpack_setup:
898
- error, offset = unpack_setup_error(buffer)
899
- future.set_exception(RuntimeError(error))
900
- else:
901
- error, offset = unpack_error(buffer)
902
- error = self._handle_error(error)
903
- log.warning("ERROR: %s", error)
904
- future.set_exception(X11Error(error))
905
- else:
906
- event, offset = unpack_event(self._events, buffer)
907
- for listener in self.listeners:
908
- await listener.put(event)
909
- buffer = buffer[offset:]
922
+ need_more = False
923
+ while not need_more and buffer:
924
+ need_more, buffer, context = await self._handle_buffer(buffer, context)
910
925
 
911
926
  async def events(self):
912
927
  """Async iterator yielding event dicts from the server."""
@@ -933,7 +948,7 @@ def get_display_config(uri: str) -> dict:
933
948
  display["protocol"] = protocol
934
949
  display["port"] = int(display["port"])
935
950
  display["uri"] = uri
936
- display["screen"] = display["screen"] or 0
951
+ display["screen"] = int(display["screen"] or 0)
937
952
  return display
938
953
 
939
954
 
@@ -613,7 +613,7 @@ def pack_glx_is_direct(opcode, context):
613
613
  def unpack_glx_is_direct(data, offset=0):
614
614
  """Unpack a glx is direct reply or event from *data* starting at *offset*."""
615
615
  result, offset = unpack_reply_head(data, offset)
616
- result["is_direct"] = bool(result["n"])
616
+ result["is_direct"] = bool(struct.unpack_from("B", data, offset)[0])
617
617
  offset += 24
618
618
  return result, offset
619
619
 
@@ -754,17 +754,22 @@ def pack_glx_get_fb_configs(opcode, screen):
754
754
 
755
755
  def unpack_glx_get_fb_configs(data, offset=0):
756
756
  """Unpack a glx get fb configs reply or event from *data* starting at *offset*."""
757
+ start = offset
757
758
  result, offset = unpack_reply_head(data, offset)
759
+ # Fixed fields at bytes 8..31 of the reply
758
760
  n_cfgs, n_props = struct.unpack_from("II", data, offset)
759
- offset += 8 + 16
761
+ offset += struct.calcsize("II") + 16
760
762
  total = n_cfgs * n_props
761
- props = list(struct.unpack_from(f"{total}I".format(total=total), data, offset)) if total else []
762
- offset += total * 4
763
+ if total:
764
+ props = list(struct.unpack_from(f"{total}I", data, offset))
765
+ else:
766
+ props = []
763
767
  configs = [props[i * n_props : (i + 1) * n_props] for i in range(n_cfgs)]
764
768
  result["num_fb_configs"] = n_cfgs
765
769
  result["num_properties"] = n_props
766
770
  result["fb_configs"] = configs
767
- return result, offset
771
+ # Always consume the full reply so the connection buffer stays aligned
772
+ return result, start + 32 + 4 * result["length"]
768
773
 
769
774
 
770
775
  def pack_glx_create_new_context(
@@ -793,32 +798,51 @@ def pack_glx_create_new_context(
793
798
 
794
799
 
795
800
  def pack_glx_make_context_current(opcode, drawable, read_drawable, context, old_context_tag=0):
796
- """Pack a wire-protocol glx make context current request into ``bytes``."""
801
+ """Pack a wire-protocol glx make context current request into ``bytes``.
802
+
803
+ Wire order (glxproto.h)::
804
+
805
+ oldContextTag, drawable, readdrawable, context
806
+ """
797
807
  return struct.pack(
798
808
  "BBHIIII",
799
809
  opcode,
800
810
  GLXCommand.MakeContextCurrent,
801
811
  5,
812
+ int(old_context_tag),
802
813
  int(drawable),
803
814
  int(read_drawable),
804
815
  int(context),
805
- int(old_context_tag),
806
816
  )
807
817
 
808
818
 
809
- def pack_glx_create_pbuffer(opcode, pbuffer, fbconfig, attrs: list[tuple[int, int]] | None = None):
810
- """Pack a wire-protocol glx create pbuffer request into ``bytes``."""
819
+ def pack_glx_create_pbuffer(
820
+ opcode,
821
+ pbuffer,
822
+ fbconfig,
823
+ screen=0,
824
+ attrs: list[tuple[int, int]] | None = None,
825
+ ):
826
+ """Pack a wire-protocol glx create pbuffer request into ``bytes``.
827
+
828
+ Wire order (xcb)::
829
+
830
+ screen, fbconfig, pbuffer, num_attribs, attribs[num_attribs*2]
831
+
832
+ Fixed header ``BBHIIII`` is 5 units plus 2 per attribute pair.
833
+ """
811
834
  attrs = attrs or []
812
835
  n = len(attrs)
813
- length = 3 + 2 * n
836
+ length = 5 + 2 * n
814
837
  parts = [
815
838
  struct.pack(
816
- "BBHIII",
839
+ "BBHIIII",
817
840
  opcode,
818
841
  GLXCommand.CreatePbuffer,
819
842
  length,
820
- int(pbuffer),
843
+ int(screen),
821
844
  int(fbconfig),
845
+ int(pbuffer),
822
846
  n,
823
847
  )
824
848
  ]
@@ -832,20 +856,36 @@ def pack_glx_destroy_pbuffer(opcode, pbuffer):
832
856
  return struct.pack("BBHI", opcode, GLXCommand.DestroyPbuffer, 2, int(pbuffer))
833
857
 
834
858
 
835
- def pack_glx_create_window(opcode, window, fbconfig, x_window, attrs: list[tuple[int, int]] | None = None):
836
- """Pack a wire-protocol glx create window request into ``bytes``."""
859
+ def pack_glx_create_window(
860
+ opcode,
861
+ glx_window,
862
+ fbconfig,
863
+ x_window,
864
+ screen=0,
865
+ attrs: list[tuple[int, int]] | None = None,
866
+ ):
867
+ """Pack a wire-protocol glx create window request into ``bytes``.
868
+
869
+ Wire order (GLX 1.3 / xcb)::
870
+
871
+ screen, fbconfig, x_window, glx_window, num_attribs, attribs[num_attribs*2]
872
+
873
+ Request length is in 4-byte units: fixed header ``BBHIIIII`` is 6 units
874
+ plus 2 units per attribute/value pair.
875
+ """
837
876
  attrs = attrs or []
838
877
  n = len(attrs)
839
- length = 4 + 2 * n
878
+ length = 6 + 2 * n
840
879
  parts = [
841
880
  struct.pack(
842
- "BBHIIII",
881
+ "=BBHIIIII",
843
882
  opcode,
844
883
  GLXCommand.CreateWindow,
845
884
  length,
846
- int(window),
885
+ int(screen),
847
886
  int(fbconfig),
848
887
  int(x_window),
888
+ int(glx_window),
849
889
  n,
850
890
  )
851
891
  ]
@@ -1395,22 +1435,56 @@ class GLX(Extension):
1395
1435
  )
1396
1436
  return context
1397
1437
 
1398
- async def create_window(self, fbconfig, x_window, attrs=None, window=None):
1399
- """Create window."""
1438
+ async def create_window(self, fbconfig, x_window, screen=None, attrs=None, window=None):
1439
+ """Create a GLX window wrapping an X11 window for the given FBConfig.
1440
+
1441
+ Parameters
1442
+ ----------
1443
+ fbconfig:
1444
+ FBConfig id (from :meth:`get_fb_configs`).
1445
+ x_window:
1446
+ Existing X11 window XID (must use a visual compatible with *fbconfig*).
1447
+ screen:
1448
+ Screen number (default: display default screen).
1449
+ attrs:
1450
+ Optional list of ``(attribute, value)`` pairs.
1451
+ window:
1452
+ Optional GLX window id; allocated if omitted (must differ from *x_window*).
1453
+ """
1454
+ x_window = int(x_window)
1455
+ fbconfig = int(fbconfig)
1456
+ if screen is None:
1457
+ screen = self.display.config.get("screen", 0)
1458
+ screen = int(screen)
1400
1459
  if window is None:
1401
1460
  window = self.display.resources.allocate()
1402
- self.display.write(pack_glx_create_window(self.code, window, fbconfig, x_window, attrs))
1461
+ window = int(window)
1462
+ # GLX window XID must be a fresh client ID, not the X11 window
1463
+ if window == x_window or window == 0:
1464
+ window = int(self.display.resources.allocate())
1465
+ self.display.write(
1466
+ pack_glx_create_window(
1467
+ self.code,
1468
+ window,
1469
+ fbconfig,
1470
+ x_window,
1471
+ screen=screen,
1472
+ attrs=attrs,
1473
+ )
1474
+ )
1403
1475
  return window
1404
1476
 
1405
1477
  async def destroy_window(self, window):
1406
1478
  """Destroy window."""
1407
1479
  self.display.write(pack_glx_destroy_window(self.code, window))
1408
1480
 
1409
- async def create_pbuffer(self, fbconfig, attrs=None, pbuffer=None):
1481
+ async def create_pbuffer(self, fbconfig, attrs=None, pbuffer=None, screen=None):
1410
1482
  """Create pbuffer."""
1411
1483
  if pbuffer is None:
1412
1484
  pbuffer = self.display.resources.allocate()
1413
- self.display.write(pack_glx_create_pbuffer(self.code, pbuffer, fbconfig, attrs))
1485
+ if screen is None:
1486
+ screen = self.display.config.get("screen", 0)
1487
+ self.display.write(pack_glx_create_pbuffer(self.code, pbuffer, fbconfig, screen=screen, attrs=attrs))
1414
1488
  return pbuffer
1415
1489
 
1416
1490
  async def destroy_pbuffer(self, pbuffer):
@@ -643,14 +643,14 @@ def pack_clear_area(wnd, x, y, w, h, exposure=False):
643
643
 
644
644
  def pack_change_property(wid, property, property_type, format, data, mode):
645
645
  """Pack a wire-protocol change property request into ``bytes``."""
646
- if not isinstance(data, (bytes, bytearray)):
646
+ if not isinstance(data, bytes | bytearray):
647
647
  format, data = encode_property_value(property_type, data, format)
648
648
  elif format is None:
649
649
  format = 8
650
650
 
651
651
  n = len(data)
652
652
  size = format // 8
653
- if isinstance(data, (bytes, bytearray)):
653
+ if isinstance(data, bytes | bytearray):
654
654
  if n % size:
655
655
  n -= n % size
656
656
  raw = data[:n]
@@ -726,7 +726,7 @@ def encode_property_value(property_type, data, format=None):
726
726
  * ``list``/``tuple`` of ``str`` — NUL-separated STRING
727
727
  * ``list``/``tuple`` of ``int`` — format 16 or 32 array
728
728
  """
729
- if isinstance(data, (bytes, bytearray)):
729
+ if isinstance(data, bytes | bytearray):
730
730
  return (format if format is not None else 8), bytes(data)
731
731
 
732
732
  if isinstance(data, str):
@@ -735,7 +735,7 @@ def encode_property_value(property_type, data, format=None):
735
735
  if isinstance(data, int):
736
736
  return (format if format is not None else 32), [data]
737
737
 
738
- if isinstance(data, (list, tuple)):
738
+ if isinstance(data, list | tuple):
739
739
  if not data:
740
740
  return (format if format is not None else 32), []
741
741
  if isinstance(data[0], str):
@@ -813,13 +813,15 @@ def pack_list_extensions():
813
813
  def unpack_list_strings(data, n, offset):
814
814
  """Unpack a list strings reply or event from *data* starting at *offset*."""
815
815
  result = []
816
+ total = 0
816
817
  for _ in range(n):
817
818
  (size,) = struct.unpack_from("B", data, offset)
818
819
  offset += 1
819
820
  (text,) = struct.unpack_from(f"{size}s", data, offset)
820
821
  offset += size
822
+ total += 1 + size
821
823
  result.append(text.decode())
822
- return result, offset
824
+ return result, offset + pad(total)
823
825
 
824
826
 
825
827
  def unpack_list_extensions(data: bytes, offset: int = 0):
@@ -829,7 +831,7 @@ def unpack_list_extensions(data: bytes, offset: int = 0):
829
831
  n = result["n"]
830
832
  offset += 24
831
833
  result["extensions"], offset = unpack_list_strings(data, n, offset)
832
- return result, offset + 32 + result["length"] * 4
834
+ return result, offset
833
835
 
834
836
 
835
837
  def pack_query_extension(name) -> bytes:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aioxlib
3
- Version: 0.3.0
3
+ Version: 0.4.0
4
4
  Summary: Human friendly interface to XLib subsystems using asyncio python
5
5
  Author-email: Jose Tiago Macara Coutinho <coutinhotiago@gmail.com>
6
6
  License-Expression: GPL-3.0-or-later
@@ -52,6 +52,7 @@ The **root package** exposes the functional API and `get_display` only:
52
52
  import asyncio
53
53
  import aioxlib
54
54
 
55
+
55
56
  async def main():
56
57
  wnd = await aioxlib.create_window(640, 480, title="Hello from aioxlib")
57
58
  await wnd.show()
@@ -60,6 +61,7 @@ async def main():
60
61
  if wnd.is_delete_window(event):
61
62
  break
62
63
 
64
+
63
65
  asyncio.run(main())
64
66
  ```
65
67
 
@@ -69,6 +71,7 @@ asyncio.run(main())
69
71
  import asyncio
70
72
  import aioxlib
71
73
 
74
+
72
75
  async def main():
73
76
  display = await aioxlib.get_display()
74
77
  async with display:
@@ -80,6 +83,7 @@ async def main():
80
83
  if wnd.is_delete_window(event):
81
84
  break
82
85
 
86
+
83
87
  asyncio.run(main())
84
88
  ```
85
89
 
@@ -134,5 +138,5 @@ GPLv3 or later — see [LICENSE](LICENSE).
134
138
 
135
139
  ## Author
136
140
 
137
- José Tiago Macara Coutinho
141
+ José Tiago Macara Coutinho
138
142
  <https://codeberg.org/tiagocoutinho>
@@ -120,13 +120,13 @@ class TestGLXPack:
120
120
  def test_create_new_context_and_pbuffer(self):
121
121
  p = pack_glx_create_new_context(self.OPCODE, 0x10, 0x50, 0, 0x8014, 0, True)
122
122
  assert p[1] == GLXCommand.CreateNewContext
123
- p = pack_glx_create_pbuffer(self.OPCODE, 0x60, 0x50, [(0x801D, 64), (0x801E, 64)])
123
+ p = pack_glx_create_pbuffer(self.OPCODE, 0x60, 0x50, 0, [(0x801D, 64), (0x801E, 64)])
124
124
  assert p[1] == GLXCommand.CreatePbuffer
125
125
  p = pack_glx_destroy_pbuffer(self.OPCODE, 0x60)
126
126
  assert p[1] == GLXCommand.DestroyPbuffer
127
127
 
128
128
  def test_window_and_attribs_arb(self):
129
- p = pack_glx_create_window(self.OPCODE, 0x70, 0x50, 0x100, None)
129
+ p = pack_glx_create_window(self.OPCODE, 0x70, 0x50, 0x100, 0, None)
130
130
  assert p[1] == GLXCommand.CreateWindow
131
131
  p = pack_glx_destroy_window(self.OPCODE, 0x70)
132
132
  assert p[1] == GLXCommand.DestroyWindow
@@ -152,7 +152,7 @@ class TestGLXUnpack:
152
152
 
153
153
  def test_is_direct_reply(self):
154
154
  # n field in reply head is the is_direct flag
155
- data = struct.pack("BBHI", 1, 1, 1, 0) + b"\0" * 24
155
+ data = struct.pack("BBHIB", 1, 1, 1, 0, 1) + b"\0" * 23
156
156
  r, _ = unpack_glx_is_direct(data)
157
157
  assert r["is_direct"] is True
158
158
 
@@ -235,7 +235,7 @@ class TestGLXClass:
235
235
  @pytest.mark.asyncio
236
236
  async def test_is_direct_and_swap(self, glx, display):
237
237
  async def write_read(payload, callback):
238
- data = struct.pack("BBHI", 1, 1, 1, 0) + b"\0" * 24
238
+ data = struct.pack("BBHIB", 1, 1, 1, 0, 1) + b"\0" * 23
239
239
  return callback(data, 0)[0]
240
240
 
241
241
  display.write_read = write_read
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes