diff --git a/CHANGES.md b/CHANGES.md index 444f6238b6..29d55435d6 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -16,6 +16,7 @@ - INPUT: Map clear button to DEL key. - LINUX/X11: Add RetroArch logo to window title bar. - LINUX/X11: Input driver now supports new lightgun code. +- LINUX/X11: Support window transparency (requires a compositing window manager). - LOBBIES: Fix for crash on join netplay rooms via touch / glui. - LOCALIZATION: Update Italian translation. - LOCALIZATION: Update Japanese translation. @@ -33,6 +34,7 @@ - WINDOWS: Use configured OSD/text message color on GDI driver. - WINDOWS/XINPUT: Populate XInput VID/PID from DInput so autoconfig doesn't rely solely on joypad names - WINDOWS: Improve version reporting under System Information. +- WINDOWS: Support window transparency. # 1.6.9 - COMMON: Small memory leak. diff --git a/Makefile.common b/Makefile.common index b70cdb6ec3..1ba0da7f23 100644 --- a/Makefile.common +++ b/Makefile.common @@ -900,10 +900,11 @@ ifeq ($(HAVE_X11), 1) OBJ += input/common/input_x11_common.o \ input/drivers/x11_input.o \ gfx/common/x11_common.o \ - gfx/common/xinerama_common.o + gfx/common/xinerama_common.o \ + gfx/display_servers/dispserv_x11.o LIBS += $(X11_LIBS) $(XEXT_LIBS) $(XF86VM_LIBS) $(XINERAMA_LIBS) - DEFINES += $(X11_CFLAGS) $(XEXT_CFLAGS) $(XF86VM_CFLAGS) $(XINERAMA_CFLAGS) + DEFINES += -DHAVE_X11 $(X11_CFLAGS) $(XEXT_CFLAGS) $(XF86VM_CFLAGS) $(XINERAMA_CFLAGS) ifeq ($(HAVE_XCB),1) LIBS += -lX11-xcb endif diff --git a/gfx/display_servers/dispserv_win32.c b/gfx/display_servers/dispserv_win32.c index 41958aabd8..8165d9e3bf 100644 --- a/gfx/display_servers/dispserv_win32.c +++ b/gfx/display_servers/dispserv_win32.c @@ -45,7 +45,7 @@ static bool win32_set_window_opacity(void *data, unsigned opacity) #if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0500 /* Set window transparency on Windows 2000 and above */ - return SetLayeredWindowAttributes(hwnd, 0, opacity, LWA_ALPHA); + return SetLayeredWindowAttributes(hwnd, 0, (255 * opacity) / 100, LWA_ALPHA); #else return false; #endif diff --git a/gfx/display_servers/dispserv_x11.c b/gfx/display_servers/dispserv_x11.c new file mode 100644 index 0000000000..1d53ca9052 --- /dev/null +++ b/gfx/display_servers/dispserv_x11.c @@ -0,0 +1,64 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2014 - Hans-Kristian Arntzen + * Copyright (C) 2011-2017 - Daniel De Matteis + * Copyright (C) 2016-2017 - Brad Parker + * + * 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 . + */ + +#include "../video_display_server.h" +#include "../common/x11_common.h" +#include "../../configuration.h" + +typedef struct +{ + unsigned opacity; +} dispserv_x11_t; + +static void* x11_display_server_init(void) +{ + dispserv_x11_t *dispserv = (dispserv_x11_t*)calloc(1, sizeof(*dispserv)); + + return dispserv; +} + +static void x11_display_server_destroy(void) +{ + +} + +static bool x11_set_window_opacity(void *data, unsigned opacity) +{ + dispserv_x11_t *serv = (dispserv_x11_t*)data; + Atom net_wm_opacity = XInternAtom(g_x11_dpy, "_NET_WM_WINDOW_OPACITY", False); + Atom cardinal = XInternAtom(g_x11_dpy, "CARDINAL", False); + settings_t *settings = config_get_ptr(); + + serv->opacity = opacity; + + opacity = opacity * ((unsigned)-1 / 100.0); + + if (opacity == (unsigned)-1) + XDeleteProperty(g_x11_dpy, g_x11_win, net_wm_opacity); + else + XChangeProperty(g_x11_dpy, g_x11_win, net_wm_opacity, cardinal, 32, PropModeReplace, (const unsigned char*)&opacity, 1); + + return true; +} + +const video_display_server_t dispserv_x11 = { + x11_display_server_init, + x11_display_server_destroy, + x11_set_window_opacity, + "x11" +}; + diff --git a/gfx/drivers_context/x_ctx.c b/gfx/drivers_context/x_ctx.c index 64673379cd..ca228881ea 100644 --- a/gfx/drivers_context/x_ctx.c +++ b/gfx/drivers_context/x_ctx.c @@ -623,7 +623,10 @@ static bool gfx_ctx_x_set_video_mode(void *data, int (*old_handler)(Display*, XErrorEvent*) = NULL; gfx_ctx_x_data_t *x = (gfx_ctx_x_data_t*)data; Atom net_wm_icon = XInternAtom(g_x11_dpy, "_NET_WM_ICON", False); + Atom net_wm_opacity = XInternAtom(g_x11_dpy, "_NET_WM_WINDOW_OPACITY", False); Atom cardinal = XInternAtom(g_x11_dpy, "CARDINAL", False); + settings_t *settings = config_get_ptr(); + unsigned opacity = settings->uints.video_window_opacity * ((unsigned)-1 / 100.0); frontend_driver_install_signal_handler(); @@ -713,6 +716,9 @@ static bool gfx_ctx_x_set_video_mode(void *data, XChangeProperty(g_x11_dpy, g_x11_win, net_wm_icon, cardinal, 32, PropModeReplace, (const unsigned char*)retroarch_icon_data, sizeof(retroarch_icon_data) / sizeof(*retroarch_icon_data)); + if (opacity < (unsigned)-1) + XChangeProperty(g_x11_dpy, g_x11_win, net_wm_opacity, cardinal, 32, PropModeReplace, (const unsigned char*)&opacity, 1); + switch (x_api) { case GFX_CTX_OPENGL_API: diff --git a/gfx/video_display_server.c b/gfx/video_display_server.c index 2aa1af04c6..22f481ce45 100644 --- a/gfx/video_display_server.c +++ b/gfx/video_display_server.c @@ -29,11 +29,16 @@ void* video_display_server_init(void) switch (type) { - case RARCH_DISPLAY_WIN32: #if defined(_WIN32) && !defined(_XBOX) + case RARCH_DISPLAY_WIN32: current_display_server = &dispserv_win32; -#endif break; +#endif +#if defined(HAVE_X11) + case RARCH_DISPLAY_X11: + current_display_server = &dispserv_x11; + break; +#endif default: current_display_server = &dispserv_null; break; diff --git a/gfx/video_display_server.h b/gfx/video_display_server.h index 1b16c75b97..ae5387c578 100644 --- a/gfx/video_display_server.h +++ b/gfx/video_display_server.h @@ -36,6 +36,7 @@ void video_display_server_destroy(void); bool video_display_server_set_window_opacity(unsigned opacity); extern const video_display_server_t dispserv_win32; +extern const video_display_server_t dispserv_x11; extern const video_display_server_t dispserv_null; RETRO_END_DECLS diff --git a/menu/menu_setting.c b/menu/menu_setting.c index c5ad60c223..265b6004fb 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -1836,7 +1836,7 @@ void general_write_handler(void *data) #endif break; case MENU_ENUM_LABEL_VIDEO_WINDOW_OPACITY: - video_display_server_set_window_opacity((255 * settings->uints.video_window_opacity) / 100); + video_display_server_set_window_opacity(settings->uints.video_window_opacity); break; default: break;