11#define PY_SSIZE_T_CLEAN
22#include <Python.h>
3+ #ifdef __linux__
4+ #include <dlfcn.h>
5+ #endif
36#ifdef _WIN32
47#include <Objbase.h>
58#include <Shobjidl.h>
69#include <Windows.h>
710#endif
811
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 )
1066{
1167#ifdef _WIN32
1268 wchar_t * appid = NULL ;
@@ -22,7 +78,8 @@ static PyObject* mpl_GetCurrentProcessExplicitAppUserModelID(PyObject* module)
2278#endif
2379}
2480
25- static PyObject * mpl_SetCurrentProcessExplicitAppUserModelID (PyObject * module , PyObject * arg )
81+ static PyObject *
82+ mpl_SetCurrentProcessExplicitAppUserModelID (PyObject * module , PyObject * arg )
2683{
2784#ifdef _WIN32
2885 wchar_t * appid = PyUnicode_AsWideCharString (arg , NULL );
@@ -40,7 +97,8 @@ static PyObject* mpl_SetCurrentProcessExplicitAppUserModelID(PyObject* module, P
4097#endif
4198}
4299
43- static PyObject * mpl_GetForegroundWindow (PyObject * module )
100+ static PyObject *
101+ mpl_GetForegroundWindow (PyObject * module )
44102{
45103#ifdef _WIN32
46104 return PyLong_FromVoidPtr (GetForegroundWindow ());
@@ -49,7 +107,8 @@ static PyObject* mpl_GetForegroundWindow(PyObject* module)
49107#endif
50108}
51109
52- static PyObject * mpl_SetForegroundWindow (PyObject * module , PyObject * arg )
110+ static PyObject *
111+ mpl_SetForegroundWindow (PyObject * module , PyObject * arg )
53112{
54113#ifdef _WIN32
55114 HWND handle = PyLong_AsVoidPtr (arg );
@@ -66,6 +125,12 @@ static PyObject* mpl_SetForegroundWindow(PyObject* module, PyObject *arg)
66125}
67126
68127static 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." },
69134 {"Win32_GetCurrentProcessExplicitAppUserModelID" ,
70135 (PyCFunction )mpl_GetCurrentProcessExplicitAppUserModelID , METH_NOARGS ,
71136 "Win32_GetCurrentProcessExplicitAppUserModelID()\n--\n\n"
@@ -83,7 +148,7 @@ static PyMethodDef functions[] = {
83148 "always returns None." },
84149 {"Win32_SetForegroundWindow" ,
85150 (PyCFunction )mpl_SetForegroundWindow , METH_O ,
86- "Win32_SetForegroundWindow(hwnd)\n--\n\n"
151+ "Win32_SetForegroundWindow(hwnd, / )\n--\n\n"
87152 "Wrapper for Windows' SetForegroundWindow. On non-Windows platforms, \n"
88153 "a no-op." },
89154 {NULL , NULL }}; // sentinel.
0 commit comments