1
1
#define PY_SSIZE_T_CLEAN
2
2
#include <Python.h>
3
+ #ifdef __linux__
4
+ #include <dlfcn.h>
5
+ #endif
3
6
#ifdef _WIN32
4
7
#include <Objbase.h>
5
8
#include <Shobjidl.h>
6
9
#include <Windows.h>
7
10
#endif
8
11
9
- static PyObject * mpl_GetCurrentProcessExplicitAppUserModelID (PyObject * module )
12
+ static PyObject *
13
+ mpl_display_is_valid (PyObject * module )
14
+ {
15
+ #ifdef __linux__
16
+ void * libX11 ;
17
+ // The getenv check is redundant but helps performance as it is much faster
18
+ // than dlopen().
19
+ if (getenv ("DISPLAY" )
20
+ && (libX11 = dlopen ("libX11.so.6" , RTLD_LAZY ))) {
21
+ struct Display * display = NULL ;
22
+ struct Display * (* XOpenDisplay )(char const * ) =
23
+ dlsym (libX11 , "XOpenDisplay" );
24
+ int (* XCloseDisplay )(struct Display * ) =
25
+ dlsym (libX11 , "XCloseDisplay" );
26
+ if (XOpenDisplay && XCloseDisplay
27
+ && (display = XOpenDisplay (NULL ))) {
28
+ XCloseDisplay (display );
29
+ }
30
+ if (dlclose (libX11 )) {
31
+ PyErr_SetString (PyExc_RuntimeError , dlerror ());
32
+ return NULL ;
33
+ }
34
+ if (display ) {
35
+ Py_RETURN_TRUE ;
36
+ }
37
+ }
38
+ void * libwayland_client ;
39
+ if (getenv ("WAYLAND_DISPLAY" )
40
+ && (libwayland_client = dlopen ("libwayland-client.so.0" , RTLD_LAZY ))) {
41
+ struct wl_display * display = NULL ;
42
+ struct wl_display * (* wl_display_connect )(char const * ) =
43
+ dlsym (libwayland_client , "wl_display_connect" );
44
+ void (* wl_display_disconnect )(struct wl_display * ) =
45
+ dlsym (libwayland_client , "wl_display_disconnect" );
46
+ if (wl_display_connect && wl_display_disconnect
47
+ && (display = wl_display_connect (NULL ))) {
48
+ wl_display_disconnect (display );
49
+ }
50
+ if (dlclose (libwayland_client )) {
51
+ PyErr_SetString (PyExc_RuntimeError , dlerror ());
52
+ return NULL ;
53
+ }
54
+ if (display ) {
55
+ Py_RETURN_TRUE ;
56
+ }
57
+ }
58
+ Py_RETURN_FALSE ;
59
+ #else
60
+ Py_RETURN_TRUE ;
61
+ #endif
62
+ }
63
+
64
+ static PyObject *
65
+ mpl_GetCurrentProcessExplicitAppUserModelID (PyObject * module )
10
66
{
11
67
#ifdef _WIN32
12
68
wchar_t * appid = NULL ;
@@ -22,7 +78,8 @@ static PyObject* mpl_GetCurrentProcessExplicitAppUserModelID(PyObject* module)
22
78
#endif
23
79
}
24
80
25
- static PyObject * mpl_SetCurrentProcessExplicitAppUserModelID (PyObject * module , PyObject * arg )
81
+ static PyObject *
82
+ mpl_SetCurrentProcessExplicitAppUserModelID (PyObject * module , PyObject * arg )
26
83
{
27
84
#ifdef _WIN32
28
85
wchar_t * appid = PyUnicode_AsWideCharString (arg , NULL );
@@ -40,7 +97,8 @@ static PyObject* mpl_SetCurrentProcessExplicitAppUserModelID(PyObject* module, P
40
97
#endif
41
98
}
42
99
43
- static PyObject * mpl_GetForegroundWindow (PyObject * module )
100
+ static PyObject *
101
+ mpl_GetForegroundWindow (PyObject * module )
44
102
{
45
103
#ifdef _WIN32
46
104
return PyLong_FromVoidPtr (GetForegroundWindow ());
@@ -49,7 +107,8 @@ static PyObject* mpl_GetForegroundWindow(PyObject* module)
49
107
#endif
50
108
}
51
109
52
- static PyObject * mpl_SetForegroundWindow (PyObject * module , PyObject * arg )
110
+ static PyObject *
111
+ mpl_SetForegroundWindow (PyObject * module , PyObject * arg )
53
112
{
54
113
#ifdef _WIN32
55
114
HWND handle = PyLong_AsVoidPtr (arg );
@@ -66,6 +125,12 @@ static PyObject* mpl_SetForegroundWindow(PyObject* module, PyObject *arg)
66
125
}
67
126
68
127
static PyMethodDef functions [] = {
128
+ {"display_is_valid" , (PyCFunction )mpl_display_is_valid , METH_NOARGS ,
129
+ "display_is_valid()\n--\n\n"
130
+ "Check whether the current X11 or Wayland display is valid.\n\n"
131
+ "On Linux, returns True if either $DISPLAY is set and XOpenDisplay(NULL)\n"
132
+ "succeeds, or $WAYLAND_DISPLAY is set and wl_display_connect(NULL)\n"
133
+ "succeeds. On other platforms, always returns True." },
69
134
{"Win32_GetCurrentProcessExplicitAppUserModelID" ,
70
135
(PyCFunction )mpl_GetCurrentProcessExplicitAppUserModelID , METH_NOARGS ,
71
136
"Win32_GetCurrentProcessExplicitAppUserModelID()\n--\n\n"
@@ -83,7 +148,7 @@ static PyMethodDef functions[] = {
83
148
"always returns None." },
84
149
{"Win32_SetForegroundWindow" ,
85
150
(PyCFunction )mpl_SetForegroundWindow , METH_O ,
86
- "Win32_SetForegroundWindow(hwnd)\n--\n\n"
151
+ "Win32_SetForegroundWindow(hwnd, / )\n--\n\n"
87
152
"Wrapper for Windows' SetForegroundWindow. On non-Windows platforms, \n"
88
153
"a no-op." },
89
154
{NULL , NULL }}; // sentinel.
0 commit comments