4
4
#define WINVER 0x0A00
5
5
#define _WIN32_WINNT 0x0A00
6
6
#endif
7
- #define PY_SSIZE_T_CLEAN
8
- #include < Python.h>
7
+ #include < pybind11/pybind11.h>
9
8
#ifdef __linux__
10
9
#include < dlfcn.h>
11
10
#endif
12
11
#ifdef _WIN32
13
12
#include < Objbase.h>
14
13
#include < Shobjidl.h>
15
14
#include < Windows.h>
15
+ #define UNUSED_ON_NON_WINDOWS (x ) x
16
+ #else
17
+ #define UNUSED_ON_NON_WINDOWS Py_UNUSED
16
18
#endif
17
19
18
- static PyObject*
19
- mpl_display_is_valid (PyObject* module)
20
+ namespace py = pybind11;
21
+
22
+ static bool
23
+ mpl_display_is_valid (void )
20
24
{
21
25
#ifdef __linux__
22
26
void * libX11;
@@ -34,11 +38,10 @@ mpl_display_is_valid(PyObject* module)
34
38
XCloseDisplay (display);
35
39
}
36
40
if (dlclose (libX11)) {
37
- PyErr_SetString (PyExc_RuntimeError, dlerror ());
38
- return NULL ;
41
+ throw std::runtime_error (dlerror ());
39
42
}
40
43
if (display) {
41
- Py_RETURN_TRUE ;
44
+ return true ;
42
45
}
43
46
}
44
47
void * libwayland_client;
@@ -56,84 +59,74 @@ mpl_display_is_valid(PyObject* module)
56
59
wl_display_disconnect (display);
57
60
}
58
61
if (dlclose (libwayland_client)) {
59
- PyErr_SetString (PyExc_RuntimeError, dlerror ());
60
- return NULL ;
62
+ throw std::runtime_error (dlerror ());
61
63
}
62
64
if (display) {
63
- Py_RETURN_TRUE ;
65
+ return true ;
64
66
}
65
67
}
66
- Py_RETURN_FALSE ;
68
+ return false ;
67
69
#else
68
- Py_RETURN_TRUE ;
70
+ return true ;
69
71
#endif
70
72
}
71
73
72
- static PyObject*
73
- mpl_GetCurrentProcessExplicitAppUserModelID (PyObject* module )
74
+ static py::object
75
+ mpl_GetCurrentProcessExplicitAppUserModelID (void )
74
76
{
75
77
#ifdef _WIN32
76
78
wchar_t * appid = NULL ;
77
79
HRESULT hr = GetCurrentProcessExplicitAppUserModelID (&appid);
78
80
if (FAILED (hr)) {
79
- return PyErr_SetFromWindowsErr (hr);
81
+ PyErr_SetFromWindowsErr (hr);
82
+ throw py::error_already_set ();
80
83
}
81
- PyObject* py_appid = PyUnicode_FromWideChar (appid, - 1 );
84
+ auto py_appid = py::cast (appid);
82
85
CoTaskMemFree (appid);
83
86
return py_appid;
84
87
#else
85
- Py_RETURN_NONE ;
88
+ return py::none () ;
86
89
#endif
87
90
}
88
91
89
- static PyObject*
90
- mpl_SetCurrentProcessExplicitAppUserModelID (PyObject* module, PyObject* arg )
92
+ static void
93
+ mpl_SetCurrentProcessExplicitAppUserModelID (const wchar_t * UNUSED_ON_NON_WINDOWS (appid) )
91
94
{
92
95
#ifdef _WIN32
93
- wchar_t * appid = PyUnicode_AsWideCharString (arg, NULL );
94
- if (!appid) {
95
- return NULL ;
96
- }
97
96
HRESULT hr = SetCurrentProcessExplicitAppUserModelID (appid);
98
- PyMem_Free (appid);
99
97
if (FAILED (hr)) {
100
- return PyErr_SetFromWindowsErr (hr);
98
+ PyErr_SetFromWindowsErr (hr);
99
+ throw py::error_already_set ();
101
100
}
102
- Py_RETURN_NONE;
103
- #else
104
- Py_RETURN_NONE;
105
101
#endif
106
102
}
107
103
108
- static PyObject*
109
- mpl_GetForegroundWindow (PyObject* module )
104
+ static py::object
105
+ mpl_GetForegroundWindow (void )
110
106
{
111
107
#ifdef _WIN32
112
- return PyLong_FromVoidPtr (GetForegroundWindow ());
108
+ return py::capsule (GetForegroundWindow (), " HWND " );
113
109
#else
114
- Py_RETURN_NONE ;
110
+ return py::none () ;
115
111
#endif
116
112
}
117
113
118
- static PyObject*
119
- mpl_SetForegroundWindow (PyObject* module, PyObject *arg )
114
+ static void
115
+ mpl_SetForegroundWindow (py::capsule UNUSED_ON_NON_WINDOWS (handle_p) )
120
116
{
121
117
#ifdef _WIN32
122
- HWND handle = PyLong_AsVoidPtr (arg);
123
- if (PyErr_Occurred ()) {
124
- return NULL ;
125
- }
126
- if (!SetForegroundWindow (handle)) {
127
- return PyErr_Format (PyExc_RuntimeError, " Error setting window" );
128
- }
129
- Py_RETURN_NONE;
130
- #else
131
- Py_RETURN_NONE;
118
+ if (handle_p.name () != " HWND" ) {
119
+ throw std::runtime_error (" Handle must be a value returned from Win32_GetForegroundWindow" );
120
+ }
121
+ HWND handle = static_cast <HWND>(handle_p.get_pointer ());
122
+ if (!SetForegroundWindow (handle)) {
123
+ throw std::runtime_error (" Error setting window" );
124
+ }
132
125
#endif
133
126
}
134
127
135
- static PyObject*
136
- mpl_SetProcessDpiAwareness_max (PyObject* module )
128
+ static void
129
+ mpl_SetProcessDpiAwareness_max (void )
137
130
{
138
131
#ifdef _WIN32
139
132
#ifdef _DPI_AWARENESS_CONTEXTS_
@@ -171,49 +164,52 @@ mpl_SetProcessDpiAwareness_max(PyObject* module)
171
164
SetProcessDPIAware ();
172
165
#endif
173
166
#endif
174
- Py_RETURN_NONE;
175
167
}
176
168
177
- static PyMethodDef functions[] = {
178
- {" display_is_valid" , (PyCFunction)mpl_display_is_valid, METH_NOARGS,
179
- " display_is_valid()\n --\n\n "
180
- " Check whether the current X11 or Wayland display is valid.\n\n "
181
- " On Linux, returns True if either $DISPLAY is set and XOpenDisplay(NULL)\n "
182
- " succeeds, or $WAYLAND_DISPLAY is set and wl_display_connect(NULL)\n "
183
- " succeeds.\n\n "
184
- " On other platforms, always returns True." },
185
- {" Win32_GetCurrentProcessExplicitAppUserModelID" ,
186
- (PyCFunction)mpl_GetCurrentProcessExplicitAppUserModelID, METH_NOARGS,
187
- " Win32_GetCurrentProcessExplicitAppUserModelID()\n --\n\n "
188
- " Wrapper for Windows's GetCurrentProcessExplicitAppUserModelID.\n\n "
189
- " On non-Windows platforms, always returns None." },
190
- {" Win32_SetCurrentProcessExplicitAppUserModelID" ,
191
- (PyCFunction)mpl_SetCurrentProcessExplicitAppUserModelID, METH_O,
192
- " Win32_SetCurrentProcessExplicitAppUserModelID(appid, /)\n --\n\n "
193
- " Wrapper for Windows's SetCurrentProcessExplicitAppUserModelID.\n\n "
194
- " On non-Windows platforms, does nothing." },
195
- {" Win32_GetForegroundWindow" ,
196
- (PyCFunction)mpl_GetForegroundWindow, METH_NOARGS,
197
- " Win32_GetForegroundWindow()\n --\n\n "
198
- " Wrapper for Windows' GetForegroundWindow.\n\n "
199
- " On non-Windows platforms, always returns None." },
200
- {" Win32_SetForegroundWindow" ,
201
- (PyCFunction)mpl_SetForegroundWindow, METH_O,
202
- " Win32_SetForegroundWindow(hwnd, /)\n --\n\n "
203
- " Wrapper for Windows' SetForegroundWindow.\n\n "
204
- " On non-Windows platforms, does nothing." },
205
- {" Win32_SetProcessDpiAwareness_max" ,
206
- (PyCFunction)mpl_SetProcessDpiAwareness_max, METH_NOARGS,
207
- " Win32_SetProcessDpiAwareness_max()\n --\n\n "
208
- " Set Windows' process DPI awareness to best option available.\n\n "
209
- " On non-Windows platforms, does nothing." },
210
- {NULL , NULL }}; // sentinel.
211
- static PyModuleDef util_module = {
212
- PyModuleDef_HEAD_INIT, " _c_internal_utils" , NULL , 0 , functions
213
- };
214
-
215
- #pragma GCC visibility push(default)
216
- PyMODINIT_FUNC PyInit__c_internal_utils (void )
169
+ PYBIND11_MODULE (_c_internal_utils, m)
217
170
{
218
- return PyModule_Create (&util_module);
171
+ m.def (
172
+ " display_is_valid" , &mpl_display_is_valid,
173
+ R"""( --
174
+ Check whether the current X11 or Wayland display is valid.
175
+
176
+ On Linux, returns True if either $DISPLAY is set and XOpenDisplay(NULL)
177
+ succeeds, or $WAYLAND_DISPLAY is set and wl_display_connect(NULL)
178
+ succeeds.
179
+
180
+ On other platforms, always returns True.)""" );
181
+ m.def (
182
+ " Win32_GetCurrentProcessExplicitAppUserModelID" ,
183
+ &mpl_GetCurrentProcessExplicitAppUserModelID,
184
+ R"""( --
185
+ Wrapper for Windows's GetCurrentProcessExplicitAppUserModelID.
186
+
187
+ On non-Windows platforms, always returns None.)""" );
188
+ m.def (
189
+ " Win32_SetCurrentProcessExplicitAppUserModelID" ,
190
+ &mpl_SetCurrentProcessExplicitAppUserModelID,
191
+ py::arg (" appid" ), py::pos_only (),
192
+ R"""( --
193
+ Wrapper for Windows's SetCurrentProcessExplicitAppUserModelID.
194
+
195
+ On non-Windows platforms, does nothing.)""" );
196
+ m.def (
197
+ " Win32_GetForegroundWindow" , &mpl_GetForegroundWindow,
198
+ R"""( --
199
+ Wrapper for Windows' GetForegroundWindow.
200
+
201
+ On non-Windows platforms, always returns None.)""" );
202
+ m.def (
203
+ " Win32_SetForegroundWindow" , &mpl_SetForegroundWindow,
204
+ py::arg (" hwnd" ),
205
+ R"""( --
206
+ Wrapper for Windows' SetForegroundWindow.
207
+
208
+ On non-Windows platforms, does nothing.)""" );
209
+ m.def (
210
+ " Win32_SetProcessDpiAwareness_max" , &mpl_SetProcessDpiAwareness_max,
211
+ R"""( --
212
+ Set Windows' process DPI awareness to best option available.
213
+
214
+ On non-Windows platforms, does nothing.)""" );
219
215
}
0 commit comments