RetroArch/gfx/common/x11_common.h
Nicolas Guillaumin 05df632bd8 WIP: Fixes #2026 Screensaver suspend on Linux via Dbus
One some systems (tested with Gnome 3 on Arch Linux) the current method
of using `xdg-screensaver` to suspend the screensaver does not work.
Instead, using DBus to issue an `Inhibit` request is recommended.

The request returns a cookie that needs to be re-used to un-inhibit the
screensaver later. Additionally if the DBus connection is closed the
current inhibition is discarded. Thus, the DBus connection needs to stay
connected for the duration of the screenshot inhibition.

The code is heavily inspired from the [SDL 2.x
code](http://hg.libsdl.org/SDL/file/default/src/core/linux/SDL_dbus.c#l172).
I didn't call the SDL 2 code though since this it to fix the issue with
the GL driver, and I assume one would want to have screensaver inhibited
even when SDL 2 is not available (but GL is).

I've set "WIP" because:
* I haven't done C in a long time so my code is probably not great
* There's a dependency on DBus which I don't know is acceptable or
not
* I've put my code where I could to check it works, but `x11_common` may
not be the best place
* The code need and "init" and "deinit" kind of method as it needs to
initialise the DBus connection, and on deinit close it properly. I've
used `x11_connect` and `x11_window_destroy` but they don't sound like
the best choices.
* I'm a bit unclear as to what happens when "suspend screensaver" is
ticked on/off in the menu. This doesn't seem to call
`x11_suspend_screensaver` everytime, so I'm not sure if there's a hook
somewhere (as disabling screensaver suspend in the menu should cause a
DBus unhinibit request to be sent).
* Should I just call the SDL 2.x code (meaning that the GL driver would
depend on SDL 2.x at runtime)?

So, first of all are you ok with the approach, and if yes I'd gladly get
feedback about the code, how to architecture it and the best place to
put it.

Thanks!
2016-09-08 15:23:41 -07:00

105 lines
3.0 KiB
C

/* RetroArch - A frontend for libretro.
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
* Copyright (C) 2011-2016 - Daniel De Matteis
*
* RetroArch is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with RetroArch.
* If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef X11_COMMON_H__
#define X11_COMMON_H__
#ifdef HAVE_CONFIG_H
#include "../../config.h"
#endif
#include <signal.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/extensions/xf86vmode.h>
#ifdef HAVE_XINERAMA
#include <X11/extensions/Xinerama.h>
#endif
#include <boolean.h>
#include "../video_context_driver.h"
extern Window g_x11_win;
extern Display *g_x11_dpy;
extern Colormap g_x11_cmap;
extern unsigned g_x11_screen;
void x11_save_last_used_monitor(Window win);
void x11_show_mouse(Display *dpy, Window win, bool state);
void x11_windowed_fullscreen(Display *dpy, Window win);
void x11_suspend_screensaver(Window win, bool enable);
void x11_suspend_screensaver_xdg_screensaver(Window win, bool enable);
#ifdef HAVE_DBUS
void x11_suspend_screensaver_dbus(bool enable);
#endif
bool x11_enter_fullscreen(Display *dpy, unsigned width,
unsigned height, XF86VidModeModeInfo *desktop_mode);
void x11_exit_fullscreen(Display *dpy, XF86VidModeModeInfo *desktop_mode);
void x11_move_window(Display *dpy, Window win,
int x, int y, unsigned width, unsigned height);
/* Set icon, class, default stuff. */
void x11_set_window_attr(Display *dpy, Window win);
#ifdef HAVE_XINERAMA
bool x11_get_xinerama_coord(Display *dpy, int screen,
int *x, int *y, unsigned *w, unsigned *h);
unsigned x11_get_xinerama_monitor(Display *dpy,
int x, int y, int w, int h);
#endif
bool x11_create_input_context(Display *dpy, Window win, XIM *xim, XIC *xic);
void x11_destroy_input_context(XIM *xim, XIC *xic);
void x11_handle_key_event(XEvent *event, XIC ic, bool filter);
bool x11_get_metrics(void *data,
enum display_metric_types type, float *value);
void x11_check_window(void *data, bool *quit,
bool *resize, unsigned *width, unsigned *height, unsigned frame_count);
void x11_get_video_size(void *data, unsigned *width, unsigned *height);
bool x11_has_focus(void *data);
bool x11_has_focus_internal(void *data);
bool x11_alive(void *data);
bool x11_connect(void);
void x11_update_window_title(void *data);
bool x11_input_ctx_new(bool true_full);
void x11_input_ctx_destroy(void);
void x11_window_destroy(bool fullscreen);
void x11_colormap_destroy(void);
void x11_install_quit_atom(void);
void x11_event_queue_check(XEvent *event);
#endif