Compare commits

...

3 Commits

Author SHA1 Message Date
Camilla Löwy
c702cdd1c8 Fixup: Fixup 2018-02-20 16:24:29 +01:00
Camilla Löwy
e07f0c9b6b X11: Add support for MIT XSS
Related to #854.
2018-02-20 16:20:09 +01:00
Camilla Löwy
35682ec3fa X11: Add support for org.freedesktop.ScreenSaver
Related to #854.
2018-02-20 16:09:35 +01:00
7 changed files with 233 additions and 25 deletions

View 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()

View File

@ -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()
#--------------------------------------------------------------------

View File

@ -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

View File

@ -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.

View File

@ -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();

View File

@ -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

View File

@ -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);
}
}
}