omdev 0.0.0.dev376__py3-none-any.whl → 0.0.0.dev378__py3-none-any.whl

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.
omdev/capi/__init__.py ADDED
File without changes
@@ -0,0 +1,5 @@
1
+ import sys
2
+
3
+
4
+ if getattr(sys, 'platform') != 'darwin':
5
+ raise OSError(sys.platform)
@@ -0,0 +1,39 @@
1
+ import ctypes as ct
2
+ import ctypes.util
3
+ import typing as ta
4
+
5
+ from omlish import check
6
+
7
+ from . import cf
8
+
9
+
10
+ ##
11
+
12
+
13
+ aps = ct.cdll.LoadLibrary(check.not_none(ct.util.find_library('ApplicationServices')))
14
+
15
+
16
+ OSStatus: ta.TypeAlias = ct.c_int32
17
+
18
+ PasteboardItemID: ta.TypeAlias = ct.c_ulong
19
+ PasteboardRef: ta.TypeAlias = ct.c_void_p
20
+
21
+ PasteboardCopyItemFlavorData = aps.PasteboardCopyItemFlavorData
22
+ PasteboardCopyItemFlavorData.argtypes = [PasteboardRef, PasteboardItemID, cf.CFStringRef, ct.POINTER(cf.CFDataRef)]
23
+ PasteboardCopyItemFlavorData.restype = OSStatus
24
+
25
+ PasteboardCopyItemFlavors = aps.PasteboardCopyItemFlavors
26
+ PasteboardCopyItemFlavors.argtypes = [PasteboardRef, PasteboardItemID, ct.POINTER(cf.CFArrayRef)]
27
+ PasteboardCopyItemFlavors.restype = OSStatus
28
+
29
+ PasteboardCreate = aps.PasteboardCreate
30
+ PasteboardCreate.argtypes = [cf.CFStringRef, ct.POINTER(PasteboardRef)]
31
+ PasteboardCreate.restype = OSStatus
32
+
33
+ PasteboardGetItemCount = aps.PasteboardGetItemCount
34
+ PasteboardGetItemCount.argtypes = [PasteboardRef, ct.POINTER(ct.c_ulong)]
35
+ PasteboardGetItemCount.restype = OSStatus
36
+
37
+ PasteboardGetItemIdentifier = aps.PasteboardGetItemIdentifier
38
+ PasteboardGetItemIdentifier.argtypes = [PasteboardRef, ct.c_ulong, ct.POINTER(PasteboardItemID)]
39
+ PasteboardGetItemIdentifier.restype = OSStatus
@@ -0,0 +1,54 @@
1
+ import ctypes as ct
2
+
3
+
4
+ ##
5
+
6
+
7
+ ax = ct.CDLL('/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/HIServices.framework/Versions/A/HIServices') # noqa
8
+
9
+
10
+ # AXUIElementCreateApplication(pid_t pid)
11
+ AXUIElementCreateApplication = ax.AXUIElementCreateApplication
12
+ AXUIElementCreateApplication.argtypes = [ct.c_int]
13
+ AXUIElementCreateApplication.restype = ct.c_void_p
14
+
15
+ # AXUIElementSetAttributeValue(AXUIElementRef element, CFStringRef attr, CFTypeRef value)
16
+ AXUIElementSetAttributeValue = ax.AXUIElementSetAttributeValue
17
+ AXUIElementSetAttributeValue.argtypes = [ct.c_void_p, ct.c_void_p, ct.c_void_p]
18
+ AXUIElementSetAttributeValue.restype = ct.c_int
19
+
20
+ # AXUIElementCopyAttributeValue(AXUIElementRef element, CFStringRef attr, CFTypeRef *value)
21
+ AXUIElementCopyAttributeValue = ax.AXUIElementCopyAttributeValue
22
+ AXUIElementCopyAttributeValue.argtypes = [ct.c_void_p, ct.c_void_p, ct.POINTER(ct.c_void_p)]
23
+ AXUIElementCopyAttributeValue.restype = ct.c_int
24
+
25
+ # AXValueCreate functions
26
+ AXValueCreate = ax.AXValueCreate
27
+ AXValueCreate.argtypes = [ct.c_int, ct.c_void_p]
28
+ AXValueCreate.restype = ct.c_void_p
29
+
30
+ # AXValueGetValue - extract data from AXValue objects
31
+ AXValueGetValue = ax.AXValueGetValue
32
+ AXValueGetValue.argtypes = [ct.c_void_p, ct.c_int, ct.c_void_p]
33
+ AXValueGetValue.restype = ct.c_bool
34
+
35
+ # AX value types
36
+ kAXValueCGPointType = 1 # noqa
37
+ kAXValueCGSizeType = 2 # noqa
38
+
39
+ # Accessibility permissions checking
40
+ AXIsProcessTrusted = ax.AXIsProcessTrusted
41
+ AXIsProcessTrusted.argtypes = []
42
+ AXIsProcessTrusted.restype = ct.c_bool
43
+
44
+ AXIsProcessTrustedWithOptions = ax.AXIsProcessTrustedWithOptions
45
+ AXIsProcessTrustedWithOptions.argtypes = [ct.c_void_p]
46
+ AXIsProcessTrustedWithOptions.restype = ct.c_bool
47
+
48
+ AXUIElementCopyAttributeNames = ax.AXUIElementCopyAttributeNames
49
+ AXUIElementCopyAttributeNames.argtypes = [ct.c_void_p, ct.POINTER(ct.c_void_p)]
50
+ AXUIElementCopyAttributeNames.restype = ct.c_int
51
+
52
+ AXUIElementGetAttributeValueCount = ax.AXUIElementGetAttributeValueCount
53
+ AXUIElementGetAttributeValueCount.argtypes = [ct.c_void_p, ct.c_void_p, ct.POINTER(ct.c_long)]
54
+ AXUIElementGetAttributeValueCount.restype = ct.c_int
@@ -0,0 +1,152 @@
1
+ import contextlib
2
+ import ctypes as ct
3
+ import ctypes.util
4
+ import typing as ta
5
+
6
+
7
+ T = ta.TypeVar('T')
8
+
9
+
10
+ ##
11
+
12
+
13
+ cf = ct.CDLL(ct.util.find_library('CoreFoundation'))
14
+
15
+
16
+ ##
17
+ # type aliases
18
+
19
+ CFArrayRef: ta.TypeAlias = ct.c_void_p
20
+ CFDataRef: ta.TypeAlias = ct.c_void_p
21
+ CFIndex: ta.TypeAlias = ct.c_long
22
+ CFStringEncoding: ta.TypeAlias = ct.c_uint32
23
+ CFStringRef: ta.TypeAlias = ct.c_void_p
24
+ CFTypeID: ta.TypeAlias = ct.c_ulong
25
+
26
+ ##
27
+ # ref counts
28
+
29
+ CFRetain = cf.CFRetain
30
+ CFRetain.argtypes = [ct.c_void_p]
31
+ CFRetain.restype = ct.c_void_p
32
+
33
+ # void CFRelease(CFTypeRef cf)
34
+ CFRelease = cf.CFRelease
35
+ CFRelease.argtypes = [ct.c_void_p]
36
+ CFRelease.restype = None
37
+
38
+ ##
39
+ # arrays
40
+
41
+ # CFIndex CFArrayGetCount(CFArrayRef theArray)
42
+ CFArrayGetCount = cf.CFArrayGetCount
43
+ CFArrayGetCount.argtypes = [CFArrayRef]
44
+ CFArrayGetCount.restype = CFIndex
45
+
46
+ # const void *CFArrayGetValueAtIndex(CFArrayRef theArray, CFIndex idx)
47
+ CFArrayGetValueAtIndex = cf.CFArrayGetValueAtIndex
48
+ CFArrayGetValueAtIndex.argtypes = [CFArrayRef, CFIndex]
49
+ CFArrayGetValueAtIndex.restype = CFStringRef
50
+
51
+ ##
52
+ # dicts
53
+
54
+ # const void *CFDictionaryGetValue(CFDictionaryRef theDict, const void *key)
55
+ CFDictionaryGetValue = cf.CFDictionaryGetValue
56
+ CFDictionaryGetValue.argtypes = [ct.c_void_p, ct.c_void_p]
57
+ CFDictionaryGetValue.restype = ct.c_void_p
58
+
59
+ ##
60
+ # strings
61
+
62
+ kCFStringEncodingUTF8 = 0x08000100 # noqa
63
+
64
+ # CFStringRef CFStringCreateWithCString(CFAllocatorRef alloc, const char *cStr, CFStringEncoding encoding)
65
+ CFStringCreateWithCString = cf.CFStringCreateWithCString
66
+ CFStringCreateWithCString.argtypes = [ct.c_void_p, ct.c_char_p, ct.c_uint32]
67
+ CFStringCreateWithCString.restype = CFStringRef
68
+
69
+ # Boolean CFStringGetCString(CFStringRef theString, char *buffer, CFIndex bufferSize, CFStringEncoding encoding)
70
+ CFStringGetCString = cf.CFStringGetCString
71
+ CFStringGetCString.argtypes = [CFStringRef, ct.c_char_p, ct.c_long, ct.c_uint32]
72
+ CFStringGetCString.restype = ct.c_bool
73
+
74
+ CFStringGetLength = cf.CFStringGetLength
75
+ CFStringGetLength.argtypes = [CFStringRef]
76
+ CFStringGetLength.restype = CFIndex
77
+
78
+ CFStringGetMaximumSizeForEncoding = cf.CFStringGetMaximumSizeForEncoding
79
+ CFStringGetMaximumSizeForEncoding.argtypes = [CFIndex, CFStringEncoding]
80
+ CFStringGetMaximumSizeForEncoding.restype = CFIndex
81
+
82
+ CFStringGetTypeID = cf.CFStringGetTypeID
83
+ CFStringGetTypeID.argtypes = []
84
+ CFStringGetTypeID.restype = CFTypeID
85
+
86
+ ##
87
+ # numbers
88
+
89
+ kCFNumberIntType = 9 # noqa
90
+ kCFNumberCGFloatType = 16 # noqa
91
+
92
+ # Boolean CFNumberGetValue(CFNumberRef number, CFNumberType theType, void *valuePtr)
93
+ CFNumberGetValue = cf.CFNumberGetValue
94
+ CFNumberGetValue.argtypes = [ct.c_void_p, ct.c_int, ct.c_void_p]
95
+ CFNumberGetValue.restype = ct.c_bool
96
+
97
+ ##
98
+ # other
99
+
100
+ CFDataGetBytePtr = cf.CFDataGetBytePtr
101
+ CFDataGetBytePtr.argtypes = [CFDataRef]
102
+ CFDataGetBytePtr.restype = ct.POINTER(ct.c_uint8)
103
+
104
+ CFDataGetLength = cf.CFDataGetLength
105
+ CFDataGetLength.argtypes = [CFDataRef]
106
+ CFDataGetLength.restype = CFIndex
107
+
108
+ CFGetTypeID = cf.CFGetTypeID
109
+ CFGetTypeID.argtypes = [ct.c_void_p]
110
+ CFGetTypeID.restype = CFTypeID
111
+
112
+
113
+ ##
114
+
115
+
116
+ def es_release(es: contextlib.ExitStack, p: T) -> T:
117
+ if p:
118
+ es.callback(CFRelease, p)
119
+ return p
120
+
121
+
122
+ #
123
+
124
+
125
+ def string(s: ta.Any, encoding: ta.Any = None) -> CFStringRef:
126
+ if isinstance(s, str) and encoding is None:
127
+ s = s.encode('utf-8')
128
+ encoding = kCFStringEncodingUTF8
129
+ elif encoding is None:
130
+ encoding = kCFStringEncodingUTF8
131
+ return CFStringCreateWithCString(None, s, encoding)
132
+
133
+
134
+ def es_string(es: contextlib.ExitStack, s: ta.Any, encoding: ta.Any = None) -> CFStringRef:
135
+ p = string(s, encoding)
136
+ es_release(es, p)
137
+ return p
138
+
139
+
140
+ def read_string(p: CFStringRef) -> str | None:
141
+ if not p:
142
+ return None
143
+
144
+ sz = cf.CFStringGetLength(p)
145
+ max_sz = cf.CFStringGetMaximumSizeForEncoding(sz, kCFStringEncodingUTF8) + 1
146
+ buf = ct.create_string_buffer(max_sz)
147
+
148
+ rc = cf.CFStringGetCString(p, buf, max_sz, kCFStringEncodingUTF8)
149
+ if not rc:
150
+ return None
151
+
152
+ return buf.value.decode('utf-8')
@@ -0,0 +1,105 @@
1
+ import ctypes as ct
2
+ import ctypes.util
3
+
4
+
5
+ ##
6
+
7
+
8
+ cg = ct.CDLL(ct.util.find_library('CoreGraphics'))
9
+
10
+
11
+ # Define constants (from CGWindow.h)
12
+ kCGWindowListExcludeDesktopElements = 1 << 4 # 16 # noqa
13
+ kCGWindowListOptionOnScreenOnly = 1 << 0 # 1 # noqa
14
+ kCGNullWindowID = 0 # noqa
15
+
16
+ # Define Core Foundation string constants. These are defined as extern const CFStringRef in the headers.
17
+ kCGWindowNumber = ct.c_char_p(b"kCGWindowNumber") # noqa
18
+ kCGWindowOwnerName = ct.c_char_p(b"kCGWindowOwnerName") # noqa
19
+ kCGWindowName = ct.c_char_p(b"kCGWindowName") # noqa
20
+ kCGWindowBounds = ct.c_char_p(b"kCGWindowBounds") # noqa
21
+ kCGWindowOwnerPID = ct.c_char_p(b"kCGWindowOwnerPID") # noqa
22
+
23
+ # CFArrayRef CGWindowListCopyWindowInfo(CGWindowListOption option, CGWindowID relativeToWindow)
24
+ CGWindowListCopyWindowInfo = cg.CGWindowListCopyWindowInfo
25
+ CGWindowListCopyWindowInfo.argtypes = [ct.c_uint32, ct.c_uint32]
26
+ CGWindowListCopyWindowInfo.restype = ct.c_void_p
27
+
28
+ # CGPreflightScreenCaptureAccess() - available on macOS 10.15+
29
+ CGPreflightScreenCaptureAccess = cg.CGPreflightScreenCaptureAccess
30
+ CGPreflightScreenCaptureAccess.argtypes = []
31
+ CGPreflightScreenCaptureAccess.restype = ct.c_bool
32
+
33
+ CGWindowListCreateImage = cg.CGWindowListCreateImage
34
+ CGWindowListCreateImage.argtypes = [ct.c_void_p, ct.c_uint32, ct.c_uint32, ct.c_uint32]
35
+ CGWindowListCreateImage.restype = ct.c_void_p
36
+
37
+ # CGMainDisplayID() - get the main display
38
+ CGMainDisplayID = cg.CGMainDisplayID
39
+ CGMainDisplayID.argtypes = []
40
+ CGMainDisplayID.restype = ct.c_uint32
41
+
42
+
43
+ # Define CGRect structure
44
+ class CGRect(ct.Structure):
45
+ _fields_ = (
46
+ ('origin_x', ct.c_double),
47
+ ('origin_y', ct.c_double),
48
+ ('size_width', ct.c_double),
49
+ ('size_height', ct.c_double),
50
+ )
51
+
52
+
53
+ # CGDisplayBounds(CGDirectDisplayID display) - get display bounds
54
+ CGDisplayBounds = cg.CGDisplayBounds
55
+ CGDisplayBounds.argtypes = [ct.c_uint32]
56
+ CGDisplayBounds.restype = CGRect
57
+
58
+ # Get process PID from window number - we'll use GetWindowProperty or similar
59
+ CGWindowListCopyWindowInfo = cg.CGWindowListCopyWindowInfo
60
+ CGWindowListCopyWindowInfo.argtypes = [ct.c_uint32, ct.c_uint32]
61
+ CGWindowListCopyWindowInfo.restype = ct.c_void_p
62
+
63
+
64
+ # Define CGPoint and CGSize structures for Accessibility API
65
+ class CGPoint(ct.Structure):
66
+ _fields_ = (
67
+ ('x', ct.c_double),
68
+ ('y', ct.c_double),
69
+ )
70
+
71
+
72
+ class CGSize(ct.Structure):
73
+ _fields_ = (
74
+ ('width', ct.c_double),
75
+ ('height', ct.c_double),
76
+ )
77
+
78
+
79
+ # CoreGraphics functions for mouse events
80
+ CGEventCreateMouseEvent = cg.CGEventCreateMouseEvent
81
+ CGEventCreateMouseEvent.argtypes = [ct.c_void_p, ct.c_uint32, CGPoint, ct.c_uint32]
82
+ CGEventCreateMouseEvent.restype = ct.c_void_p
83
+
84
+ CGEventPost = cg.CGEventPost
85
+ CGEventPost.argtypes = [ct.c_uint32, ct.c_void_p]
86
+ CGEventPost.restype = None
87
+
88
+ CGEventSetType = cg.CGEventSetType
89
+ CGEventSetType.argtypes = [ct.c_void_p, ct.c_uint32]
90
+ CGEventSetType.restype = None
91
+
92
+ # Mouse event types
93
+ kCGEventLeftMouseDown = 1 # noqa
94
+ kCGEventLeftMouseUp = 2 # noqa
95
+ kCGEventRightMouseDown = 3 # noqa
96
+ kCGEventRightMouseUp = 4 # noqa
97
+ kCGEventMouseMoved = 5 # noqa
98
+ kCGHIDEventTap = 0 # noqa
99
+
100
+ # Event tap locations
101
+ kCGSessionEventTap = 1 # noqa
102
+
103
+ # Mouse button constants
104
+ kCGMouseButtonLeft = 0 # noqa
105
+ kCGMouseButtonRight = 1 # noqa
@@ -0,0 +1,5 @@
1
+ import sys
2
+
3
+
4
+ if getattr(sys, 'platform') != 'linux':
5
+ raise OSError(sys.platform)
@@ -0,0 +1,107 @@
1
+ import ctypes as ct
2
+ import ctypes.util
3
+ import typing as ta
4
+
5
+
6
+ ##
7
+
8
+
9
+ x11 = ct.CDLL(ct.util.find_library('X11'))
10
+
11
+
12
+ Atom: ta.TypeAlias = ct.c_ulong
13
+ Bool: ta.TypeAlias = ct.c_int
14
+ Display: ta.TypeAlias = ct.c_void_p
15
+ Status: ta.TypeAlias = ct.c_int
16
+ Time: ta.TypeAlias = ct.c_ulong
17
+ Window: ta.TypeAlias = ct.c_ulong
18
+
19
+
20
+ class XEvent(ct.Structure):
21
+ _fields_ = (
22
+ ('type', ct.c_int),
23
+ ('xselection', ct.c_ulong * 24), # noqa
24
+ )
25
+
26
+
27
+ XCloseDisplay = x11.XCloseDisplay
28
+ XCloseDisplay.argtypes = [Display]
29
+ XCloseDisplay.restype = None
30
+
31
+ XConvertSelection = x11.XConvertSelection
32
+ XConvertSelection.argtypes = [Display, Atom, Atom, Atom, Window, Time]
33
+ XConvertSelection.restype = None
34
+
35
+ XCreateSimpleWindow = x11.XCreateSimpleWindow
36
+ XCreateSimpleWindow.argtypes = [
37
+ Display,
38
+ Window,
39
+ ct.c_int,
40
+ ct.c_int,
41
+ ct.c_uint,
42
+ ct.c_uint,
43
+ ct.c_uint,
44
+ ct.c_ulong,
45
+ ct.c_ulong,
46
+ ]
47
+ XCreateSimpleWindow.restype = Window
48
+
49
+ XDefaultScreen = x11.XDefaultScreen
50
+ XDefaultScreen.argtypes = [Display]
51
+ XDefaultScreen.restype = ct.c_int
52
+
53
+ XDestroyWindow = x11.XDestroyWindow
54
+ XDestroyWindow.argtypes = [Display, Window]
55
+ XDestroyWindow.restype = None
56
+
57
+ XFlush = x11.XFlush
58
+ XFlush.argtypes = [Display]
59
+ XFlush.restype = None
60
+
61
+ XFree = x11.XFree
62
+ XFree.argtypes = [ct.c_void_p]
63
+ XFree.restype = None
64
+
65
+ XGetWindowProperty = x11.XGetWindowProperty
66
+ XGetWindowProperty.argtypes = [
67
+ Display,
68
+ Window,
69
+ Atom,
70
+ ct.c_long,
71
+ ct.c_long,
72
+ Bool,
73
+ Atom,
74
+ ct.POINTER(Atom),
75
+ ct.POINTER(ct.c_int),
76
+ ct.POINTER(ct.c_ulong),
77
+ ct.POINTER(ct.c_ulong),
78
+ ct.POINTER(ct.c_void_p),
79
+ ]
80
+ XGetWindowProperty.restype = Status
81
+
82
+ XInternAtom = x11.XInternAtom
83
+ XInternAtom.argtypes = [Display, ct.c_char_p, Bool]
84
+ XInternAtom.restype = Atom
85
+
86
+ XNextEvent = x11.XNextEvent
87
+ XNextEvent.argtypes = [Display, ct.POINTER(XEvent)]
88
+ XNextEvent.restype = None
89
+
90
+ XOpenDisplay = x11.XOpenDisplay
91
+ XOpenDisplay.argtypes = [ct.c_char_p]
92
+ XOpenDisplay.restype = Display
93
+
94
+ XRootWindow = x11.XRootWindow
95
+ XRootWindow.argtypes = [Display, ct.c_int]
96
+ XRootWindow.restype = Window
97
+
98
+ XGetAtomName = x11.XGetAtomName
99
+ XGetAtomName.argtypes = [Display, Atom]
100
+ XGetAtomName.restype = ct.c_char_p
101
+
102
+
103
+ ##
104
+
105
+
106
+ def atom_to_string(display, atom) -> str:
107
+ return XGetAtomName(display, atom).decode('utf-8')
@@ -1,12 +1,10 @@
1
1
  # ruff: noqa: N802 N816
2
2
  import ctypes as ct
3
- import ctypes.util
4
3
  import dataclasses as dc
5
- import sys
6
4
  import typing as ta
7
5
 
8
- from omlish import check
9
-
6
+ from ..capi.darwin import aps
7
+ from ..capi.darwin import cf
10
8
  from .clipboard import Clipboard
11
9
  from .clipboard import ClipboardContents
12
10
  from .clipboard import ImageClipboardContents
@@ -16,113 +14,7 @@ from .clipboard import TextClipboardContents
16
14
  ##
17
15
 
18
16
 
19
- if getattr(sys, 'platform') != 'darwin':
20
- raise OSError(sys.platform)
21
-
22
-
23
- ##
24
- # CoreFoundation
25
-
26
- cf = ct.cdll.LoadLibrary(check.not_none(ct.util.find_library('CoreFoundation')))
27
-
28
- #
29
-
30
- CFArrayRef = ct.c_void_p
31
- CFDataRef = ct.c_void_p
32
- CFIndex = ct.c_long
33
- CFStringEncoding = ct.c_uint32
34
- CFStringRef = ct.c_void_p
35
- CFTypeID = ct.c_ulong
36
-
37
- #
38
-
39
- cf.CFArrayGetCount.argtypes = [CFArrayRef]
40
- cf.CFArrayGetCount.restype = CFIndex
41
-
42
- cf.CFArrayGetValueAtIndex.argtypes = [CFArrayRef, CFIndex]
43
- cf.CFArrayGetValueAtIndex.restype = CFStringRef
44
-
45
- cf.CFDataGetBytePtr.argtypes = [CFDataRef]
46
- cf.CFDataGetBytePtr.restype = ct.POINTER(ct.c_uint8)
47
-
48
- cf.CFDataGetLength.argtypes = [CFDataRef]
49
- cf.CFDataGetLength.restype = CFIndex
50
-
51
- cf.CFGetTypeID.argtypes = [ct.c_void_p]
52
- cf.CFGetTypeID.restype = CFTypeID
53
-
54
- cf.CFRelease.argtypes = [ct.c_void_p]
55
- cf.CFRelease.restype = None
56
-
57
- cf.CFStringCreateWithCString.argtypes = [ct.c_void_p, ct.c_char_p, ct.c_int32]
58
- cf.CFStringCreateWithCString.restype = CFStringRef
59
-
60
- cf.CFStringGetCString.argtypes = [CFStringRef, ct.c_char_p, ct.c_long, ct.c_uint32]
61
- cf.CFStringGetCString.restype = ct.c_bool
62
-
63
- cf.CFStringGetLength.argtypes = [CFStringRef]
64
- cf.CFStringGetLength.restype = CFIndex
65
-
66
- cf.CFStringGetMaximumSizeForEncoding.argtypes = [CFIndex, CFStringEncoding]
67
- cf.CFStringGetMaximumSizeForEncoding.restype = CFIndex
68
-
69
- cf.CFStringGetTypeID.argtypes = []
70
- cf.CFStringGetTypeID.restype = CFTypeID
71
-
72
-
73
- ##
74
- # ApplicationServices
75
-
76
- aps = ct.cdll.LoadLibrary(check.not_none(ct.util.find_library('ApplicationServices')))
77
-
78
- #
79
-
80
- OSStatus = ct.c_int32
81
-
82
- PasteboardItemID = ct.c_ulong
83
- PasteboardRef = ct.c_void_p
84
-
85
- #
86
-
87
- aps.PasteboardCopyItemFlavorData.argtypes = [PasteboardRef, PasteboardItemID, CFStringRef, ct.POINTER(CFDataRef)]
88
- aps.PasteboardCopyItemFlavorData.restype = OSStatus
89
-
90
- aps.PasteboardCopyItemFlavors.argtypes = [PasteboardRef, PasteboardItemID, ct.POINTER(CFArrayRef)]
91
- aps.PasteboardCopyItemFlavors.restype = OSStatus
92
-
93
- aps.PasteboardCreate.argtypes = [CFStringRef, ct.POINTER(PasteboardRef)]
94
- aps.PasteboardCreate.restype = OSStatus
95
-
96
- aps.PasteboardGetItemCount.argtypes = [PasteboardRef, ct.POINTER(ct.c_ulong)]
97
- aps.PasteboardGetItemCount.restype = OSStatus
98
-
99
- aps.PasteboardGetItemIdentifier.argtypes = [PasteboardRef, ct.c_ulong, ct.POINTER(PasteboardItemID)]
100
- aps.PasteboardGetItemIdentifier.restype = OSStatus
101
-
102
-
103
- ##
104
-
105
-
106
- def CFSTR(string):
107
- return cf.CFStringCreateWithCString(None, string.encode('utf-8'), 0)
108
-
109
-
110
- kCFStringEncodingUTF8 = 0x08000100
111
- kPasteboardClipboard = CFSTR('com.apple.pasteboard.clipboard')
112
-
113
-
114
- def cfstring_to_string(cf_string: CFStringRef) -> str:
115
- if not cf_string:
116
- return ''
117
-
118
- length = cf.CFStringGetLength(cf_string)
119
- max_size = cf.CFStringGetMaximumSizeForEncoding(length, kCFStringEncodingUTF8) + 1
120
- buffer = ct.create_string_buffer(max_size)
121
-
122
- if not (success := cf.CFStringGetCString(cf_string, buffer, max_size, kCFStringEncodingUTF8)): # noqa
123
- return ''
124
-
125
- return buffer.value.decode('utf-8')
17
+ kPasteboardClipboard = cf.string('com.apple.pasteboard.clipboard')
126
18
 
127
19
 
128
20
  ##
@@ -153,7 +45,7 @@ def get_darwin_clipboard_data(
153
45
  ) -> list[DarwinClipboardItem]:
154
46
  lst: list[DarwinClipboardItem] = []
155
47
 
156
- pasteboard = PasteboardRef()
48
+ pasteboard = aps.PasteboardRef()
157
49
  if status := aps.PasteboardCreate(kPasteboardClipboard, ct.byref(pasteboard)):
158
50
  raise StatusDarwinClipboardError('PasteboardCreate', status)
159
51
 
@@ -163,11 +55,11 @@ def get_darwin_clipboard_data(
163
55
  raise StatusDarwinClipboardError('PasteboardGetItemCount', status)
164
56
 
165
57
  for i in range(1, item_count.value + 1):
166
- item_id = PasteboardItemID()
58
+ item_id = aps.PasteboardItemID()
167
59
  if status := aps.PasteboardGetItemIdentifier(pasteboard, i, ct.byref(item_id)):
168
60
  raise StatusDarwinClipboardError('PasteboardGetItemIdentifier', status)
169
61
 
170
- data_types = CFArrayRef()
62
+ data_types = cf.CFArrayRef()
171
63
  if status := aps.PasteboardCopyItemFlavors(pasteboard, item_id, ct.byref(data_types)):
172
64
  raise StatusDarwinClipboardError('PasteboardCopyItemFlavors', status)
173
65
  if not data_types:
@@ -179,7 +71,7 @@ def get_darwin_clipboard_data(
179
71
  data_type = cf.CFArrayGetValueAtIndex(data_types, j)
180
72
 
181
73
  if cf.CFGetTypeID(data_type) == cf.CFStringGetTypeID():
182
- data_type_str = cfstring_to_string(data_type)
74
+ data_type_str = cf.read_string(data_type)
183
75
  else:
184
76
  data_type_str = None
185
77
 
@@ -195,7 +87,7 @@ def get_darwin_clipboard_data(
195
87
  ))
196
88
  continue
197
89
 
198
- data = CFDataRef()
90
+ data = cf.CFDataRef()
199
91
 
200
92
  # FIXME: dumps to stderr lol:
201
93
  # data_type_str = 'public.heics'
@@ -1,108 +1,8 @@
1
1
  # ruff: noqa: RUF012
2
2
  # flake8: noqa: E302 E305
3
3
  import ctypes as ct
4
- import ctypes.util
5
- import sys
6
4
 
7
-
8
- ##
9
-
10
-
11
- if getattr(sys, 'platform') != 'linux':
12
- raise OSError(sys.platform)
13
-
14
-
15
- ##
16
- # x11
17
-
18
- x11 = ct.CDLL(ct.util.find_library('X11'))
19
-
20
- #
21
-
22
- Atom = ct.c_ulong
23
- Bool = ct.c_int
24
- Display = ct.c_void_p
25
- Status = ct.c_int
26
- Time = ct.c_ulong
27
- Window = ct.c_ulong
28
-
29
- #
30
-
31
- class XEvent(ct.Structure):
32
- _fields_ = [
33
- ('type', ct.c_int),
34
- ('xselection', ct.c_ulong * 24), # noqa
35
- ]
36
-
37
- #
38
-
39
- x11.XCloseDisplay.argtypes = [Display]
40
- x11.XCloseDisplay.restype = None
41
-
42
- x11.XConvertSelection.argtypes = [Display, Atom, Atom, Atom, Window, Time]
43
- x11.XConvertSelection.restype = None
44
-
45
- x11.XCreateSimpleWindow.argtypes = [
46
- Display,
47
- Window,
48
- ct.c_int,
49
- ct.c_int,
50
- ct.c_uint,
51
- ct.c_uint,
52
- ct.c_uint,
53
- ct.c_ulong,
54
- ct.c_ulong,
55
- ]
56
- x11.XCreateSimpleWindow.restype = Window
57
-
58
- x11.XDefaultScreen.argtypes = [Display]
59
- x11.XDefaultScreen.restype = ct.c_int
60
-
61
- x11.XDestroyWindow.argtypes = [Display, Window]
62
- x11.XDestroyWindow.restype = None
63
-
64
- x11.XFlush.argtypes = [Display]
65
- x11.XFlush.restype = None
66
-
67
- x11.XFree.argtypes = [ct.c_void_p]
68
- x11.XFree.restype = None
69
-
70
- x11.XGetWindowProperty.argtypes = [
71
- Display,
72
- Window,
73
- Atom,
74
- ct.c_long,
75
- ct.c_long,
76
- Bool,
77
- Atom,
78
- ct.POINTER(Atom),
79
- ct.POINTER(ct.c_int),
80
- ct.POINTER(ct.c_ulong),
81
- ct.POINTER(ct.c_ulong),
82
- ct.POINTER(ct.c_void_p),
83
- ]
84
- x11.XGetWindowProperty.restype = Status
85
-
86
- x11.XInternAtom.argtypes = [Display, ct.c_char_p, Bool]
87
- x11.XInternAtom.restype = Atom
88
-
89
- x11.XNextEvent.argtypes = [Display, ct.POINTER(XEvent)]
90
- x11.XNextEvent.restype = None
91
-
92
- x11.XOpenDisplay.argtypes = [ct.c_char_p]
93
- x11.XOpenDisplay.restype = Display
94
-
95
- x11.XRootWindow.argtypes = [Display, ct.c_int]
96
- x11.XRootWindow.restype = Window
97
-
98
-
99
- ##
100
-
101
-
102
- def atom_to_string(display, atom) -> str:
103
- x11.XGetAtomName.argtypes = [Display, Atom]
104
- x11.XGetAtomName.restype = ct.c_char_p
105
- return x11.XGetAtomName(display, atom).decode('utf-8')
5
+ from ..capi.linux import x11
106
6
 
107
7
 
108
8
  ##
@@ -123,7 +23,7 @@ def get_clipboard_text(display, window):
123
23
  )
124
24
  x11.XFlush(display)
125
25
 
126
- event = XEvent()
26
+ event = x11.XEvent()
127
27
  x11.XNextEvent(display, ct.byref(event))
128
28
 
129
29
  if event.type != 31: # SelectionNotify event type
@@ -134,7 +34,7 @@ def get_clipboard_text(display, window):
134
34
  print('No clipboard data available')
135
35
  return
136
36
 
137
- actual_type = Atom()
37
+ actual_type = x11.Atom()
138
38
  actual_format = ct.c_int()
139
39
  nitems = ct.c_ulong()
140
40
  bytes_after = ct.c_ulong()
@@ -181,14 +81,14 @@ def get_clipboard_image(display, window):
181
81
  )
182
82
  x11.XFlush(display)
183
83
 
184
- event = XEvent()
84
+ event = x11.XEvent()
185
85
  x11.XNextEvent(display, ct.byref(event))
186
86
 
187
87
  if event.type != 31 or event.xselection[4] == 0:
188
88
  print('Failed to receive SelectionNotify event for image')
189
89
  return
190
90
 
191
- actual_type = Atom()
91
+ actual_type = x11.Atom()
192
92
  actual_format = ct.c_int()
193
93
  nitems = ct.c_ulong()
194
94
  bytes_after = ct.c_ulong()
@@ -214,7 +114,7 @@ def get_clipboard_image(display, window):
214
114
  return
215
115
 
216
116
  png_atom = x11.XInternAtom(display, b'image/png', False)
217
- atoms = ct.cast(data, ct.POINTER(Atom))
117
+ atoms = ct.cast(data, ct.POINTER(x11.Atom))
218
118
  for i in range(nitems.value):
219
119
  if atoms[i] != png_atom:
220
120
  continue
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: omdev
3
- Version: 0.0.0.dev376
3
+ Version: 0.0.0.dev378
4
4
  Summary: omdev
5
5
  Author: wrmsr
6
6
  License: BSD-3-Clause
@@ -12,7 +12,7 @@ Classifier: Operating System :: OS Independent
12
12
  Classifier: Operating System :: POSIX
13
13
  Requires-Python: >=3.13
14
14
  License-File: LICENSE
15
- Requires-Dist: omlish==0.0.0.dev376
15
+ Requires-Dist: omlish==0.0.0.dev378
16
16
  Provides-Extra: all
17
17
  Requires-Dist: black~=25.1; extra == "all"
18
18
  Requires-Dist: pycparser~=2.22; extra == "all"
@@ -32,6 +32,14 @@ omdev/cache/data/consts.py,sha256=d6W_aeMqgah6PmPYi9RA8Be54oQ4BcNCy8kDQ7FlB_Q,26
32
32
  omdev/cache/data/defaults.py,sha256=NL_mT7kaSLm2Mk9VO5wdSu-DIcHTR1KgcihJqdSd4TY,312
33
33
  omdev/cache/data/manifests.py,sha256=4BparztsMZo9DDVVPhv6iv5g4kK7QAi8Vqtj3PbKkco,989
34
34
  omdev/cache/data/specs.py,sha256=P50VSvMf2Jp3VHjhHy4i1-PwYwEGD4MMXEpxIg0CQis,2468
35
+ omdev/capi/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
36
+ omdev/capi/darwin/__init__.py,sha256=iAlc3ReV3LJOv5X9zGME1FKeZ2yf0auUuj1I3sGSo4E,86
37
+ omdev/capi/darwin/aps.py,sha256=_DAGaOZYk9T1VoO22H5ZiV8F1qeTIQDO7UkYSj5UisE,1278
38
+ omdev/capi/darwin/ax.py,sha256=SIYZJrCLcPud98UHCbu8qzo6kCNixyX3BjGnxltM3dU,2123
39
+ omdev/capi/darwin/cf.py,sha256=1ws9CyLpSxV_mpzdjm8xv3ok-d1oxpMIl2H_fxifbVo,3952
40
+ omdev/capi/darwin/cg.py,sha256=ypFb1yPkjxpNWSAMgAJodEqkwT81LFc4xuixoSDOAq4,3266
41
+ omdev/capi/linux/__init__.py,sha256=JkNEnNAxfwFrcuEmaxqEEQlbDzUbaYA6tjYf_Q0Hnao,85
42
+ omdev/capi/linux/x11.py,sha256=Bi-QA_hUZYIycy_SLKgiIWXJNoydCeg_A5jg5lOa4v8,2260
35
43
  omdev/cc/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
36
44
  omdev/cc/__main__.py,sha256=n7gxSRYZ1QZOUxQPCT0_n9Xl26zi2UIvCwyGW_m67nA,166
37
45
  omdev/cc/cdeps.py,sha256=Uou-V1qcwWhe14iTu39W7yxOlDdr_P96Ai8wQjAp3zQ,1535
@@ -110,8 +118,8 @@ omdev/cli/managers.py,sha256=BV98_n30Jj63OJrFgRoVZRfICxMLXEZKoEn4rMj9LV4,1160
110
118
  omdev/cli/types.py,sha256=SH88B81otsSYNM-PM3Ry1wgLLvyg2M6fBJkWOajWIWM,485
111
119
  omdev/clipboard/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
112
120
  omdev/clipboard/clipboard.py,sha256=9HFpcijpn0XDTI89ZRm2WA1G7O4HsTdVXZHqMULu3N0,1630
113
- omdev/clipboard/darwin_cf.py,sha256=1gFkxEN6w9HTcA0eiWw14oL7xjC1wSmY_hUrRr5OU4Y,7687
114
- omdev/clipboard/linux_x11.py,sha256=oa-mxMRNaZJOdBAZ8Nki-CAGIb63X8OFUTXKjmiwfSo,6718
121
+ omdev/clipboard/darwin_cf.py,sha256=LhJ9aB_tpXBltOTo2e8687g6D8bQIV9Q7eAIP_NHb64,4821
122
+ omdev/clipboard/linux_x11.py,sha256=o_T-iYqoqozUrJ-F1xU-QSeoNCk3_ZAh6rs9quhxzhg,4844
115
123
  omdev/cmdlog/__init__.py,sha256=026o1leEXU5bsNZPpEOeLf_Ml1wQXzbiFDmlcKHX-Nw,95
116
124
  omdev/cmdlog/__main__.py,sha256=m31h6AcI9rjRNVeBGoLcR-5pWp-yS8LXCorf4iBhX9w,162
117
125
  omdev/cmdlog/_cmdlog.py,sha256=9VSuUKXBMBHAH3OfBCeqp16YPddPT9Man2zDHgzzCtI,1507
@@ -307,9 +315,9 @@ omdev/tools/jsonview/resources/jsonview.js,sha256=faDvXDOXKvEvjOuIlz4D3F2ReQXb_b
307
315
  omdev/tools/pawk/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
308
316
  omdev/tools/pawk/__main__.py,sha256=VCqeRVnqT1RPEoIrqHFSu4PXVMg4YEgF4qCQm90-eRI,66
309
317
  omdev/tools/pawk/pawk.py,sha256=ao5mdrpiSU4AZ8mBozoEaV3UVlmVTnRG9wD9XP70MZE,11429
310
- omdev-0.0.0.dev376.dist-info/licenses/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
311
- omdev-0.0.0.dev376.dist-info/METADATA,sha256=XQlzye1ZvRRChfWau_4lvvz0gUmfnOufyrLGLnHu0rQ,1674
312
- omdev-0.0.0.dev376.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
313
- omdev-0.0.0.dev376.dist-info/entry_points.txt,sha256=dHLXFmq5D9B8qUyhRtFqTGWGxlbx3t5ejedjrnXNYLU,33
314
- omdev-0.0.0.dev376.dist-info/top_level.txt,sha256=1nr7j30fEWgLYHW3lGR9pkdHkb7knv1U1ES1XRNVQ6k,6
315
- omdev-0.0.0.dev376.dist-info/RECORD,,
318
+ omdev-0.0.0.dev378.dist-info/licenses/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
319
+ omdev-0.0.0.dev378.dist-info/METADATA,sha256=vKWV1kGeVbMXxNlxC4F1jtm53laIIfcLUYMLWoksSqM,1674
320
+ omdev-0.0.0.dev378.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
321
+ omdev-0.0.0.dev378.dist-info/entry_points.txt,sha256=dHLXFmq5D9B8qUyhRtFqTGWGxlbx3t5ejedjrnXNYLU,33
322
+ omdev-0.0.0.dev378.dist-info/top_level.txt,sha256=1nr7j30fEWgLYHW3lGR9pkdHkb7knv1U1ES1XRNVQ6k,6
323
+ omdev-0.0.0.dev378.dist-info/RECORD,,