Compare commits
3 Commits
master
...
x11-inhibi
Author | SHA1 | Date | |
---|---|---|---|
|
c702cdd1c8 | ||
|
e07f0c9b6b | ||
|
35682ec3fa |
21
CMake/modules/FindDBus.cmake
Normal file
21
CMake/modules/FindDBus.cmake
Normal file
@ -0,0 +1,21 @@
|
||||
# Find libdbus
|
||||
#
|
||||
# DBUS_INCLUDE_DIRS
|
||||
# DBUS_LIBRARY
|
||||
# DBUS_FOUND
|
||||
|
||||
find_package(PkgConfig)
|
||||
if (PKG_CONFIG_FOUND)
|
||||
|
||||
pkg_check_modules(PC_DBUS dbus-1 QUIET)
|
||||
if (PC_DBUS_FOUND)
|
||||
set(DBUS_INCLUDE_DIRS ${PC_DBUS_INCLUDE_DIRS})
|
||||
find_library(DBUS_LIBRARY dbus-1 PATHS ${PC_DBUS_LIBRARY_DIRS})
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(DBus DEFAULT_MSG DBUS_LIBRARY DBUS_INCLUDE_DIRS)
|
||||
mark_as_advanced(DBUS_INCLUDE_DIRS DBUS_LIBRARY)
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
@ -215,6 +215,11 @@ if (UNIX AND NOT APPLE)
|
||||
list(APPEND glfw_LIBRARIES "${CMAKE_DL_LIBS}")
|
||||
list(APPEND glfw_PKG_LIBS "-l${CMAKE_DL_LIBS}")
|
||||
endif()
|
||||
|
||||
find_package(DBus)
|
||||
if (DBUS_FOUND)
|
||||
list(APPEND glfw_INCLUDE_DIRS ${DBUS_INCLUDE_DIRS})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
|
@ -219,6 +219,8 @@ information on what to include when reporting a bug.
|
||||
- [Win32] Bugfix: The HID device notification was not unregistered (#1170)
|
||||
- [Win32] Bugfix: `glfwCreateWindow` activated window even with `GLFW_FOCUSED`
|
||||
hint set to false (#1179,#1180)
|
||||
- [X11] Added support for `org.freedesktop.ScreenSaver` (#854)
|
||||
- [X11] Added support for the MIT screensaver extension (#854)
|
||||
- [X11] Moved to XI2 `XI_RawMotion` for disable cursor mode motion input (#125)
|
||||
- [X11] Replaced `_GLFW_HAS_XF86VM` compile-time option with dynamic loading
|
||||
- [X11] Bugfix: `glfwGetVideoMode` would segfault on Cygwin/X
|
||||
|
@ -88,10 +88,11 @@ Once you have Xcode installed, move on to @ref compile_generate.
|
||||
|
||||
@subsubsection compile_deps_x11 Dependencies for Linux and X11
|
||||
|
||||
To compile GLFW for X11, you need to have the X11 packages installed, as well as
|
||||
the basic development tools like GCC and make. For example, on Ubuntu and other
|
||||
distributions based on Debian GNU/Linux, you need to install the `xorg-dev`
|
||||
package, which pulls in all X.org header packages.
|
||||
To compile GLFW for X11, you need to have the X11 and libdbus development
|
||||
packages installed, as well as the basic development tools like GCC and make.
|
||||
For example, on Ubuntu and other distributions based on Debian GNU/Linux, you
|
||||
need to install the `xorg-dev` and `libdbus-1-dev` packages. The `xorg-dev`
|
||||
package in turn pulls in all X.org header packages.
|
||||
|
||||
Once you have installed the necessary packages, move on to @ref
|
||||
compile_generate.
|
||||
|
@ -623,6 +623,23 @@ static GLFWbool initExtensions(void)
|
||||
}
|
||||
}
|
||||
|
||||
_glfw.x11.xss.handle = _glfw_dlopen("libXss.so.1");
|
||||
if (_glfw.x11.xss.handle)
|
||||
{
|
||||
_glfw.x11.xss.QueryExtension = (PFN_XScreenSaverQueryExtension)
|
||||
_glfw_dlsym(_glfw.x11.xss.handle, "XScreenSaverQueryExtension");
|
||||
_glfw.x11.xss.Suspend = (PFN_XScreenSaverSuspend)
|
||||
_glfw_dlsym(_glfw.x11.xss.handle, "XScreenSaverSuspend");
|
||||
|
||||
if (XScreenSaverQueryExtension(_glfw.x11.display,
|
||||
&_glfw.x11.xss.eventBase,
|
||||
&_glfw.x11.xss.errorBase))
|
||||
{
|
||||
_glfw.x11.xss.available = GLFW_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if Xkb is supported on this display
|
||||
_glfw.x11.xkb.major = 1;
|
||||
_glfw.x11.xkb.minor = 0;
|
||||
_glfw.x11.xkb.available =
|
||||
@ -674,6 +691,45 @@ static GLFWbool initExtensions(void)
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(__CYGWIN__)
|
||||
_glfw.x11.dbus.handle = _glfw_dlopen("libdbus-1-3.so");
|
||||
#else
|
||||
_glfw.x11.dbus.handle = _glfw_dlopen("libdbus-1.so.3");
|
||||
#endif
|
||||
if (_glfw.x11.dbus.handle)
|
||||
{
|
||||
DBusError error;
|
||||
|
||||
_glfw.x11.dbus.error_init =
|
||||
_glfw_dlsym(_glfw.x11.dbus.handle, "dbus_error_init");
|
||||
_glfw.x11.dbus.error_is_set =
|
||||
_glfw_dlsym(_glfw.x11.dbus.handle, "dbus_error_is_set");
|
||||
_glfw.x11.dbus.bus_get_private =
|
||||
_glfw_dlsym(_glfw.x11.dbus.handle, "dbus_bus_get_private");
|
||||
_glfw.x11.dbus.connection_set_exit_on_disconnect =
|
||||
_glfw_dlsym(_glfw.x11.dbus.handle, "dbus_connection_set_exit_on_disconnect");
|
||||
_glfw.x11.dbus.connection_send_with_reply_and_block =
|
||||
_glfw_dlsym(_glfw.x11.dbus.handle, "dbus_connection_send_with_reply_and_block");
|
||||
_glfw.x11.dbus.connection_close =
|
||||
_glfw_dlsym(_glfw.x11.dbus.handle, "dbus_connection_close");
|
||||
_glfw.x11.dbus.connection_unref =
|
||||
_glfw_dlsym(_glfw.x11.dbus.handle, "dbus_connection_unref");
|
||||
_glfw.x11.dbus.message_new_method_call =
|
||||
_glfw_dlsym(_glfw.x11.dbus.handle, "dbus_message_new_method_call");
|
||||
_glfw.x11.dbus.message_append_args =
|
||||
_glfw_dlsym(_glfw.x11.dbus.handle, "dbus_message_append_args");
|
||||
_glfw.x11.dbus.message_get_args =
|
||||
_glfw_dlsym(_glfw.x11.dbus.handle, "dbus_message_get_args");
|
||||
_glfw.x11.dbus.message_unref =
|
||||
_glfw_dlsym(_glfw.x11.dbus.handle, "dbus_message_unref");
|
||||
|
||||
dbus_error_init(&error);
|
||||
|
||||
_glfw.x11.dbus.session = dbus_bus_get_private(DBUS_BUS_SESSION, &error);
|
||||
if (!dbus_error_is_set(&error))
|
||||
dbus_connection_set_exit_on_disconnect(_glfw.x11.dbus.session, FALSE);
|
||||
}
|
||||
|
||||
// Update the key code LUT
|
||||
// FIXME: We should listen to XkbMapNotify events to track changes to
|
||||
// the keyboard mapping.
|
||||
@ -1024,6 +1080,21 @@ void _glfwPlatformTerminate(void)
|
||||
_glfw.x11.xinerama.handle = NULL;
|
||||
}
|
||||
|
||||
if (_glfw.x11.xss.handle)
|
||||
{
|
||||
_glfw_dlclose(_glfw.x11.xss.handle);
|
||||
_glfw.x11.xss.handle = NULL;
|
||||
}
|
||||
|
||||
if (_glfw.x11.dbus.session)
|
||||
{
|
||||
dbus_connection_close(_glfw.x11.dbus.session);
|
||||
dbus_connection_unref(_glfw.x11.dbus.session);
|
||||
}
|
||||
|
||||
if (_glfw.x11.dbus.handle)
|
||||
_glfw_dlclose(_glfw.x11.dbus.handle);
|
||||
|
||||
// NOTE: These need to be unloaded after XCloseDisplay, as they register
|
||||
// cleanup callbacks that get called by that function
|
||||
_glfwTerminateEGL();
|
||||
|
@ -47,6 +47,9 @@
|
||||
// The XInput extension provides raw mouse motion input
|
||||
#include <X11/extensions/XInput2.h>
|
||||
|
||||
// DBus is used to inhibit the screensaver
|
||||
#include <dbus/dbus.h>
|
||||
|
||||
typedef XRRCrtcGamma* (* PFN_XRRAllocGamma)(int);
|
||||
typedef void (* PFN_XRRFreeCrtcInfo)(XRRCrtcInfo*);
|
||||
typedef void (* PFN_XRRFreeGamma)(XRRCrtcGamma*);
|
||||
@ -123,6 +126,34 @@ typedef XRenderPictFormat* (* PFN_XRenderFindVisualFormat)(Display*,Visual const
|
||||
#define XRenderQueryVersion _glfw.x11.xrender.QueryVersion
|
||||
#define XRenderFindVisualFormat _glfw.x11.xrender.FindVisualFormat
|
||||
|
||||
typedef Bool (* PFN_XScreenSaverQueryExtension)(Display*,int*,int*);
|
||||
typedef void (* PFN_XScreenSaverSuspend)(Display*,Bool);
|
||||
#define XScreenSaverQueryExtension _glfw.x11.xss.QueryExtension
|
||||
#define XScreenSaverSuspend _glfw.x11.xss.Suspend
|
||||
|
||||
typedef void (*PFN_dbus_error_init)(DBusError*);
|
||||
typedef dbus_bool_t (*PFN_dbus_error_is_set)(const DBusError*);
|
||||
typedef DBusConnection* (*PFN_dbus_bus_get_private)(DBusBusType,DBusError*);
|
||||
typedef void (*PFN_dbus_connection_set_exit_on_disconnect)(DBusConnection*,dbus_bool_t);
|
||||
typedef void (*PFN_dbus_connection_close)(DBusConnection*);
|
||||
typedef void (*PFN_dbus_connection_unref)(DBusConnection*);
|
||||
typedef DBusMessage* (*PFN_dbus_connection_send_with_reply_and_block)(DBusConnection*,DBusMessage*,int,DBusError*);
|
||||
typedef DBusMessage* (*PFN_dbus_message_new_method_call)(const char*,const char*,const char*,const char*);
|
||||
typedef dbus_bool_t (*PFN_dbus_message_append_args)(DBusMessage*,int,...);
|
||||
typedef dbus_bool_t (*PFN_dbus_message_get_args)(DBusMessage*,DBusError*,int,...);
|
||||
typedef void (*PFN_dbus_message_unref)(DBusMessage*);
|
||||
#define dbus_error_init _glfw.x11.dbus.error_init
|
||||
#define dbus_error_is_set _glfw.x11.dbus.error_is_set
|
||||
#define dbus_bus_get_private _glfw.x11.dbus.bus_get_private
|
||||
#define dbus_connection_set_exit_on_disconnect _glfw.x11.dbus.connection_set_exit_on_disconnect
|
||||
#define dbus_connection_close _glfw.x11.dbus.connection_close
|
||||
#define dbus_connection_unref _glfw.x11.dbus.connection_unref
|
||||
#define dbus_connection_send_with_reply_and_block _glfw.x11.dbus.connection_send_with_reply_and_block
|
||||
#define dbus_message_new_method_call _glfw.x11.dbus.message_new_method_call
|
||||
#define dbus_message_append_args _glfw.x11.dbus.message_append_args
|
||||
#define dbus_message_get_args _glfw.x11.dbus.message_get_args
|
||||
#define dbus_message_unref _glfw.x11.dbus.message_unref
|
||||
|
||||
typedef VkFlags VkXlibSurfaceCreateFlagsKHR;
|
||||
typedef VkFlags VkXcbSurfaceCreateFlagsKHR;
|
||||
|
||||
@ -237,6 +268,8 @@ typedef struct _GLFWlibraryX11
|
||||
double restoreCursorPosX, restoreCursorPosY;
|
||||
// The window whose disabled cursor mode is active
|
||||
_GLFWwindow* disabledCursorWindow;
|
||||
// The number of full screen windows active on their monitors
|
||||
int acquiredMonitorCount;
|
||||
|
||||
// Window manager atoms
|
||||
Atom WM_PROTOCOLS;
|
||||
@ -329,7 +362,6 @@ typedef struct _GLFWlibraryX11
|
||||
} xkb;
|
||||
|
||||
struct {
|
||||
int count;
|
||||
int timeout;
|
||||
int interval;
|
||||
int blanking;
|
||||
@ -359,6 +391,15 @@ typedef struct _GLFWlibraryX11
|
||||
PFN_XineramaQueryScreens QueryScreens;
|
||||
} xinerama;
|
||||
|
||||
struct {
|
||||
GLFWbool available;
|
||||
void* handle;
|
||||
int eventBase;
|
||||
int errorBase;
|
||||
PFN_XScreenSaverQueryExtension QueryExtension;
|
||||
PFN_XScreenSaverSuspend Suspend;
|
||||
} xss;
|
||||
|
||||
struct {
|
||||
void* handle;
|
||||
PFN_XGetXCBConnection GetXCBConnection;
|
||||
@ -399,6 +440,23 @@ typedef struct _GLFWlibraryX11
|
||||
PFN_XRenderFindVisualFormat FindVisualFormat;
|
||||
} xrender;
|
||||
|
||||
struct {
|
||||
void* handle;
|
||||
DBusConnection* session;
|
||||
uint32_t cookie;
|
||||
PFN_dbus_error_init error_init;
|
||||
PFN_dbus_error_is_set error_is_set;
|
||||
PFN_dbus_bus_get_private bus_get_private;
|
||||
PFN_dbus_connection_set_exit_on_disconnect connection_set_exit_on_disconnect;
|
||||
PFN_dbus_connection_close connection_close;
|
||||
PFN_dbus_connection_unref connection_unref;
|
||||
PFN_dbus_connection_send_with_reply_and_block connection_send_with_reply_and_block;
|
||||
PFN_dbus_message_new_method_call message_new_method_call;
|
||||
PFN_dbus_message_append_args message_append_args;
|
||||
PFN_dbus_message_get_args message_get_args;
|
||||
PFN_dbus_message_unref message_unref;
|
||||
} dbus;
|
||||
|
||||
} _GLFWlibraryX11;
|
||||
|
||||
// X11-specific per-monitor data
|
||||
|
@ -1078,22 +1078,55 @@ static const char* getSelectionString(Atom selection)
|
||||
//
|
||||
static void acquireMonitor(_GLFWwindow* window)
|
||||
{
|
||||
if (_glfw.x11.saver.count == 0)
|
||||
if (_glfw.x11.acquiredMonitorCount == 0)
|
||||
{
|
||||
// Remember old screen saver settings
|
||||
XGetScreenSaver(_glfw.x11.display,
|
||||
&_glfw.x11.saver.timeout,
|
||||
&_glfw.x11.saver.interval,
|
||||
&_glfw.x11.saver.blanking,
|
||||
&_glfw.x11.saver.exposure);
|
||||
if (_glfw.x11.xss.available)
|
||||
XScreenSaverSuspend(_glfw.x11.display, True);
|
||||
else
|
||||
{
|
||||
XGetScreenSaver(_glfw.x11.display,
|
||||
&_glfw.x11.saver.timeout,
|
||||
&_glfw.x11.saver.interval,
|
||||
&_glfw.x11.saver.blanking,
|
||||
&_glfw.x11.saver.exposure);
|
||||
XSetScreenSaver(_glfw.x11.display, 0, 0, DontPreferBlanking,
|
||||
DefaultExposures);
|
||||
}
|
||||
|
||||
// Disable screen saver
|
||||
XSetScreenSaver(_glfw.x11.display, 0, 0, DontPreferBlanking,
|
||||
DefaultExposures);
|
||||
if (_glfw.x11.dbus.session)
|
||||
{
|
||||
DBusError error;
|
||||
DBusMessage* call;
|
||||
DBusMessage* reply;
|
||||
const char* name = "GLFW";
|
||||
const char* reason = "Active fullscreen window";
|
||||
|
||||
call = dbus_message_new_method_call("org.freedesktop.ScreenSaver",
|
||||
"/org/freedesktop/ScreenSaver",
|
||||
"org.freedesktop.ScreenSaver",
|
||||
"Inhibit");
|
||||
dbus_message_append_args(call,
|
||||
DBUS_TYPE_STRING, &name,
|
||||
DBUS_TYPE_STRING, &reason,
|
||||
DBUS_TYPE_INVALID);
|
||||
dbus_error_init(&error);
|
||||
reply = dbus_connection_send_with_reply_and_block(_glfw.x11.dbus.session,
|
||||
call, 100, &error);
|
||||
dbus_message_unref(call);
|
||||
|
||||
if (!dbus_error_is_set(&error))
|
||||
{
|
||||
dbus_error_init(&error);
|
||||
dbus_message_get_args(reply, &error,
|
||||
DBUS_TYPE_UINT32, &_glfw.x11.dbus.cookie,
|
||||
DBUS_TYPE_INVALID);
|
||||
dbus_message_unref(reply);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!window->monitor->window)
|
||||
_glfw.x11.saver.count++;
|
||||
_glfw.x11.acquiredMonitorCount++;
|
||||
|
||||
_glfwSetVideoModeX11(window->monitor, &window->videoMode);
|
||||
|
||||
@ -1123,16 +1156,33 @@ static void releaseMonitor(_GLFWwindow* window)
|
||||
_glfwInputMonitorWindow(window->monitor, NULL);
|
||||
_glfwRestoreVideoModeX11(window->monitor);
|
||||
|
||||
_glfw.x11.saver.count--;
|
||||
|
||||
if (_glfw.x11.saver.count == 0)
|
||||
_glfw.x11.acquiredMonitorCount--;
|
||||
if (_glfw.x11.acquiredMonitorCount == 0)
|
||||
{
|
||||
// Restore old screen saver settings
|
||||
XSetScreenSaver(_glfw.x11.display,
|
||||
_glfw.x11.saver.timeout,
|
||||
_glfw.x11.saver.interval,
|
||||
_glfw.x11.saver.blanking,
|
||||
_glfw.x11.saver.exposure);
|
||||
if (_glfw.x11.xss.available)
|
||||
XScreenSaverSuspend(_glfw.x11.display, False);
|
||||
else
|
||||
{
|
||||
XSetScreenSaver(_glfw.x11.display,
|
||||
_glfw.x11.saver.timeout,
|
||||
_glfw.x11.saver.interval,
|
||||
_glfw.x11.saver.blanking,
|
||||
_glfw.x11.saver.exposure);
|
||||
}
|
||||
|
||||
if (_glfw.x11.dbus.session)
|
||||
{
|
||||
DBusMessage* call;
|
||||
|
||||
call = dbus_message_new_method_call("org.freedesktop.ScreenSaver",
|
||||
"/org/freedesktop/ScreenSaver",
|
||||
"org.freedesktop.ScreenSaver",
|
||||
"UnInhibit");
|
||||
dbus_message_append_args(call,
|
||||
DBUS_TYPE_UINT32, &_glfw.x11.dbus.cookie,
|
||||
DBUS_TYPE_INVALID);
|
||||
dbus_message_unref(call);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user