Skip to content

Commit 83f9456

Browse files
fix get_image on linux
1 parent d7972f7 commit 83f9456

File tree

1 file changed

+42
-36
lines changed

1 file changed

+42
-36
lines changed

display_server_interactions/linux.py

Lines changed: 42 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@
77

88
# built-in modules
99
from typing import Optional
10-
import logging
11-
import ctypes.util
10+
from logging import getLogger, CRITICAL, Logger
11+
from ctypes.util import find_library
12+
from ctypes import cdll
1213
from ctypes import (
1314
POINTER,
1415
byref,
@@ -24,7 +25,9 @@
2425
c_uint,
2526
c_void_p,
2627
c_uint32,
27-
_SimpleCData
28+
_SimpleCData,
29+
Union,
30+
CFUNCTYPE
2831
)
2932

3033
# local modules
@@ -38,6 +41,9 @@
3841

3942
# pylint: disable=too-few-public-methods
4043

44+
PLAINMASK = 0x00FFFFFF
45+
ZPIXMAP = 2
46+
4147

4248
class Display(Structure):
4349
"""
@@ -129,41 +135,41 @@ class XKeyEvent(Structure):
129135
]
130136

131137

132-
class XButtonEvent(ctypes.Structure):
138+
class XButtonEvent(Structure):
133139
"""
134140
https://tronche.com/gui/x/xlib/events/keyboard-pointer/keyboard-pointer.html#XButtonEvent\n
135141
/usr/include/X11/Xlib.h: 575-589
136142
"""
137143

138144
_fields_ = [
139-
('type', ctypes.c_int),
140-
('serial', ctypes.c_ulong),
141-
('send_event', ctypes.c_int),
142-
('display', ctypes.POINTER(Display)),
143-
('window', ctypes.c_ulong), # Window (XID)
144-
('root', ctypes.c_ulong), # Window (XID)
145-
('subwindow', ctypes.c_ulong), # Window (XID)
146-
('time', ctypes.c_ulong), # Time
147-
('x', ctypes.c_int),
148-
('y', ctypes.c_int),
149-
('x_root', ctypes.c_int),
150-
('y_root', ctypes.c_int),
151-
('state', ctypes.c_uint),
152-
('button', ctypes.c_uint),
153-
('same_screen', ctypes.c_int),
145+
('type', c_int),
146+
('serial', c_ulong),
147+
('send_event', c_int),
148+
('display', POINTER(Display)),
149+
('window', c_ulong), # Window (XID)
150+
('root', c_ulong), # Window (XID)
151+
('subwindow', c_ulong), # Window (XID)
152+
('time', c_ulong), # Time
153+
('x', c_int),
154+
('y', c_int),
155+
('x_root', c_int),
156+
('y_root', c_int),
157+
('state', c_uint),
158+
('button', c_uint),
159+
('same_screen', c_int),
154160
]
155161

156162

157-
class XEvent(ctypes.Union):
163+
class XEvent(Union):
158164
"""
159165
https://tronche.com/gui/x/xlib/events/structures.html#XEvent\n
160166
/usr/include/X11/Xlib.h: 973-1009
161167
"""
162168
_fields_ = [
163-
('type', ctypes.c_int),
169+
('type', c_int),
164170
('xkey', XKeyEvent),
165171
('xbutton', XButtonEvent),
166-
('pad', ctypes.c_long*24),
172+
('pad', c_long*24),
167173
]
168174

169175

@@ -188,11 +194,11 @@ def __repr__(self) -> str:
188194
]
189195

190196

191-
logger = logging.getLogger(__name__)
192-
logger.setLevel(logging.CRITICAL)
197+
logger = getLogger(__name__)
198+
logger.setLevel(CRITICAL)
193199

194200

195-
@ctypes.CFUNCTYPE(c_int, POINTER(Display), POINTER(XErrorEvent))
201+
@CFUNCTYPE(c_int, POINTER(Display), POINTER(XErrorEvent))
196202
def error_handler(_, event):
197203
"""
198204
A C function that handles X11 errors.
@@ -201,7 +207,7 @@ def error_handler(_, event):
201207
return 0
202208

203209

204-
def get_logger() -> logging.Logger:
210+
def get_logger() -> Logger:
205211
"""
206212
Returns a logger that is responsible for logging XErrorEvents.
207213
The logger is set to CRITICAL. So it will not log anything.
@@ -310,10 +316,10 @@ class Xlib:
310316

311317
def __init__(self):
312318
# load libX11.so.6
313-
x11 = ctypes.util.find_library("X11")
319+
x11 = find_library("X11")
314320
if not x11:
315321
raise FileNotFoundError("X11 library not found!")
316-
self.xlib = ctypes.cdll.LoadLibrary(x11)
322+
self.xlib = cdll.LoadLibrary(x11)
317323

318324
self.xlib.XSetErrorHandler(error_handler)
319325

@@ -477,15 +483,15 @@ def get_image(self, geometry: Optional[Box] = None) -> Image:
477483
ximage = self.xlib.XGetImage(
478484
self.xlib.display, # Display
479485
self.xid, # Drawable (Window XID)
480-
geometry.x, # x
481-
geometry.y, # y
486+
geometry.x - self.geometry.x, # x
487+
geometry.y - self.geometry.y, # y
482488
geometry.width, # width
483489
geometry.height, # height
484-
0x00FFFFFF, # plane_mask
485-
2 # format = ZPixmap
490+
PLAINMASK, # plane_mask
491+
ZPIXMAP # format
486492
)
487493

488-
raw_data = ctypes.cast(
494+
raw_data = cast(
489495
ximage.contents.data,
490496
POINTER(c_ubyte * geometry.height * geometry.width * 4)
491497
)
@@ -520,7 +526,7 @@ def send_chr(self, character: chr) -> None:
520526
key.window, # Window w
521527
True, # Bool propagate
522528
Masks.KeyPressMask, # long event_mask
523-
ctypes.byref(key) # XEvent *event_send
529+
byref(key) # XEvent *event_send
524530
)
525531

526532
# flush display or events will run delayed cus thai'r only called on the next update
@@ -575,7 +581,7 @@ def send_mouse_click(self, x: int, y: int, button: MouseButtons = MouseButtons.L
575581
event.window,
576582
True,
577583
Masks.ButtonPressMask,
578-
ctypes.byref(event)
584+
byref(event)
579585
)
580586

581587
# flush display or events will run delayed cus thai'r only called on the next update
@@ -588,7 +594,7 @@ def send_mouse_click(self, x: int, y: int, button: MouseButtons = MouseButtons.L
588594
event.window,
589595
True,
590596
Masks.ButtonReleaseMask,
591-
ctypes.byref(event)
597+
byref(event)
592598
)
593599

594600
# flush display or events will run delayed cus thai'r only called on the next update

0 commit comments

Comments
 (0)