Skip to content

Commit 2fbd1f8

Browse files
committed
MSS: reworked how C functions are initialised
1 parent cb517e9 commit 2fbd1f8

File tree

6 files changed

+319
-260
lines changed

6 files changed

+319
-260
lines changed

CHANGELOG

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ History:
33
<see Git checking messages for history>
44

55
6.0.1 2020/xx/xx
6+
- MSS: reworked how C functions are initialised
67
- Mac: reduce the number of function calls
78
- Mac: support macOS Big Sur (fixes #178)
89
- tests: fix macOS intepreter not found on Travis-CI

docs/source/api.rst

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,20 @@ MSS API
55
Classes
66
=======
77

8+
macOS
9+
-----
10+
11+
.. module:: mss.darwin
12+
13+
.. attribute:: CFUNCTIONS
14+
815
GNU/Linux
916
---------
1017

1118
.. module:: mss.linux
1219

20+
.. attribute:: CFUNCTIONS
21+
1322
.. attribute:: ERROR
1423

1524
:type: types.SimpleNamspacedict
@@ -18,6 +27,10 @@ GNU/Linux
1827

1928
.. versionadded:: 5.0.0
2029

30+
.. attribute:: PLAINMASK
31+
32+
.. attribute:: ZPIXMAP
33+
2134
.. class:: MSS
2235

2336
.. method:: __init__([display=None])
@@ -76,6 +89,18 @@ GNU/Linux
7689

7790
.. versionadded:: 3.3.0
7891

92+
Windows
93+
-------
94+
95+
.. module:: mss.windows
96+
97+
.. attribute:: CAPTUREBLT
98+
99+
.. attribute:: CFUNCTIONS
100+
101+
.. attribute:: DIB_RGB_COLORS
102+
103+
.. attribute:: SRCCOPY
79104

80105
Methods
81106
=======

mss/darwin.py

Lines changed: 63 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,17 @@
66
import ctypes
77
import ctypes.util
88
import sys
9+
from ctypes import (
10+
POINTER,
11+
Structure,
12+
c_double,
13+
c_float,
14+
c_int32,
15+
c_uint64,
16+
c_ubyte,
17+
c_uint32,
18+
c_void_p,
19+
)
920
from platform import mac_ver
1021
from typing import TYPE_CHECKING
1122

@@ -23,13 +34,13 @@
2334

2435

2536
def cgfloat():
26-
# type: () -> Union[Type[ctypes.c_double], Type[ctypes.c_float]]
37+
# type: () -> Union[Type[c_double], Type[c_float]]
2738
""" Get the appropriate value for a float. """
2839

29-
return ctypes.c_double if sys.maxsize > 2 ** 32 else ctypes.c_float
40+
return c_double if sys.maxsize > 2 ** 32 else c_float
3041

3142

32-
class CGPoint(ctypes.Structure):
43+
class CGPoint(Structure):
3344
""" Structure that contains coordinates of a rectangle. """
3445

3546
_fields_ = [("x", cgfloat()), ("y", cgfloat())]
@@ -38,7 +49,7 @@ def __repr__(self):
3849
return "{}(left={} top={})".format(type(self).__name__, self.x, self.y)
3950

4051

41-
class CGSize(ctypes.Structure):
52+
class CGSize(Structure):
4253
""" Structure that contains dimensions of an rectangle. """
4354

4455
_fields_ = [("width", cgfloat()), ("height", cgfloat())]
@@ -49,7 +60,7 @@ def __repr__(self):
4960
)
5061

5162

52-
class CGRect(ctypes.Structure):
63+
class CGRect(Structure):
5364
""" Structure that contains information about a rectangle. """
5465

5566
_fields_ = [("origin", CGPoint), ("size", CGSize)]
@@ -58,6 +69,42 @@ def __repr__(self):
5869
return "{}<{} {}>".format(type(self).__name__, self.origin, self.size)
5970

6071

72+
# C functions that will be initialised later.
73+
#
74+
# This is a dict:
75+
# cfunction: (attr, argtypes, restype)
76+
#
77+
# Available attr: core.
78+
#
79+
# Note: keep it sorted by cfunction.
80+
CFUNCTIONS = {
81+
"CGDataProviderCopyData": ("core", [c_void_p], c_void_p),
82+
"CGDisplayBounds": ("core", [c_uint32], CGRect),
83+
"CGDisplayRotation": ("core", [c_uint32], c_float),
84+
"CFDataGetBytePtr": ("core", [c_void_p], c_void_p),
85+
"CFDataGetLength": ("core", [c_void_p], c_uint64),
86+
"CFRelease": ("core", [c_void_p], c_void_p),
87+
"CGDataProviderRelease": ("core", [c_void_p], c_void_p),
88+
"CGGetActiveDisplayList": (
89+
"core",
90+
[c_uint32, POINTER(c_uint32), POINTER(c_uint32)],
91+
c_int32,
92+
),
93+
"CGImageGetBitsPerPixel": ("core", [c_void_p], int),
94+
"CGImageGetBytesPerRow": ("core", [c_void_p], int),
95+
"CGImageGetDataProvider": ("core", [c_void_p], c_void_p),
96+
"CGImageGetHeight": ("core", [c_void_p], int),
97+
"CGImageGetWidth": ("core", [c_void_p], int),
98+
"CGRectStandardize": ("core", [CGRect], CGRect),
99+
"CGRectUnion": ("core", [CGRect, CGRect], CGRect),
100+
"CGWindowListCreateImage": (
101+
"core",
102+
[CGRect, c_uint32, c_uint32, c_uint32],
103+
c_void_p,
104+
),
105+
}
106+
107+
61108
class MSS(MSSBase):
62109
"""
63110
Multiple ScreenShots implementation for macOS.
@@ -94,36 +141,15 @@ def _set_cfunctions(self):
94141
# type: () -> None
95142
""" Set all ctypes functions and attach them to attributes. """
96143

97-
uint32 = ctypes.c_uint32
98-
void = ctypes.c_void_p
99-
pointer = ctypes.POINTER
100144
cfactory = self._cfactory
101-
core = self.core
102-
103-
# Note: keep it sorted
104-
for func, argtypes, restype in (
105-
("CGDataProviderCopyData", [void], void),
106-
("CGDisplayBounds", [uint32], CGRect),
107-
("CGDisplayRotation", [uint32], ctypes.c_float),
108-
("CFDataGetBytePtr", [void], void),
109-
("CFDataGetLength", [void], ctypes.c_uint64),
110-
("CFRelease", [void], void),
111-
("CGDataProviderRelease", [void], void),
112-
(
113-
"CGGetActiveDisplayList",
114-
[uint32, pointer(uint32), pointer(uint32)],
115-
ctypes.c_int32,
116-
),
117-
("CGImageGetBitsPerPixel", [void], int),
118-
("CGImageGetBytesPerRow", [void], int),
119-
("CGImageGetDataProvider", [void], void),
120-
("CGImageGetHeight", [void], int),
121-
("CGImageGetWidth", [void], int),
122-
("CGRectStandardize", [CGRect], CGRect),
123-
("CGRectUnion", [CGRect, CGRect], CGRect),
124-
("CGWindowListCreateImage", [CGRect, uint32, uint32, uint32], void),
125-
):
126-
cfactory(attr=core, func=func, argtypes=argtypes, restype=restype) # type: ignore
145+
attrs = {"core": self.core}
146+
for func, (attr, argtypes, restype) in CFUNCTIONS.items():
147+
cfactory(
148+
attr=attrs[attr],
149+
func=func,
150+
argtypes=argtypes, # type: ignore
151+
restype=restype,
152+
)
127153

128154
def _monitors_impl(self):
129155
# type: () -> None
@@ -139,8 +165,8 @@ def _monitors_impl(self):
139165
self._monitors.append({})
140166

141167
# Each monitors
142-
display_count = ctypes.c_uint32(0)
143-
active_displays = (ctypes.c_uint32 * self.max_displays)()
168+
display_count = c_uint32(0)
169+
active_displays = (c_uint32 * self.max_displays)()
144170
core.CGGetActiveDisplayList(
145171
self.max_displays, active_displays, ctypes.byref(display_count)
146172
)
@@ -196,7 +222,7 @@ def _grab_impl(self, monitor):
196222
copy_data = core.CGDataProviderCopyData(prov)
197223
data_ref = core.CFDataGetBytePtr(copy_data)
198224
buf_len = core.CFDataGetLength(copy_data)
199-
raw = ctypes.cast(data_ref, ctypes.POINTER(ctypes.c_ubyte * buf_len))
225+
raw = ctypes.cast(data_ref, POINTER(c_ubyte * buf_len))
200226
data = bytearray(raw.contents)
201227

202228
# Remove padding per row

0 commit comments

Comments
 (0)