|
10 | 10 | from types import SimpleNamespace |
11 | 11 | from typing import TYPE_CHECKING |
12 | 12 |
|
13 | | -from .base import MSSBase |
| 13 | +from .base import MSSBase, lock |
14 | 14 | from .exception import ScreenShotError |
15 | 15 |
|
16 | 16 | if TYPE_CHECKING: |
@@ -227,10 +227,36 @@ def __init__(self, display=None): |
227 | 227 |
|
228 | 228 | self.root = self.xlib.XDefaultRootWindow(self._get_display(display)) |
229 | 229 |
|
| 230 | + if not self.has_extension("RANDR"): |
| 231 | + raise ScreenShotError("No Xrandr extension found.") |
| 232 | + |
230 | 233 | # Fix for XRRGetScreenResources and XGetImage: |
231 | 234 | # expected LP_Display instance instead of LP_XWindowAttributes |
232 | 235 | self.drawable = ctypes.cast(self.root, ctypes.POINTER(Display)) |
233 | 236 |
|
| 237 | + def has_extension(self, extension): |
| 238 | + # type: (str) -> bool |
| 239 | + """Return True if the given *extension* is part of the extensions list of the server.""" |
| 240 | + with lock: |
| 241 | + byref = ctypes.byref |
| 242 | + c_int = ctypes.c_int |
| 243 | + major_opcode_return = c_int() |
| 244 | + first_event_return = c_int() |
| 245 | + first_error_return = c_int() |
| 246 | + |
| 247 | + try: |
| 248 | + self.xlib.XQueryExtension( |
| 249 | + self._get_display(), |
| 250 | + extension.encode("latin1"), |
| 251 | + byref(major_opcode_return), |
| 252 | + byref(first_event_return), |
| 253 | + byref(first_error_return), |
| 254 | + ) |
| 255 | + except ScreenShotError: |
| 256 | + return False |
| 257 | + else: |
| 258 | + return True |
| 259 | + |
234 | 260 | def _get_display(self, disp=None): |
235 | 261 | """ |
236 | 262 | Retrieve a thread-safe display from XOpenDisplay(). |
@@ -297,6 +323,11 @@ def cfactory(func, argtypes, restype, attr=self.xlib): |
297 | 323 | pointer(XImage), |
298 | 324 | ) |
299 | 325 | cfactory("XDestroyImage", [pointer(XImage)], void) |
| 326 | + cfactory( |
| 327 | + "XQueryExtension", |
| 328 | + [pointer(Display), char_p, pointer(c_int), pointer(c_int), pointer(c_int)], |
| 329 | + uint, |
| 330 | + ) |
300 | 331 |
|
301 | 332 | # A simple benchmark calling 10 times those 2 functions: |
302 | 333 | # XRRGetScreenResources(): 0.1755971429956844 s |
|
0 commit comments