diff --git a/Makefile.common b/Makefile.common index 5192894c41..3c4e25dcc0 100644 --- a/Makefile.common +++ b/Makefile.common @@ -202,6 +202,7 @@ OBJ += frontend/frontend.o \ $(LIBRETRO_COMM_DIR)/audio/audio_mixer.o \ input/input_driver.o \ gfx/video_coord_array.o \ + gfx/video_display_server.o \ gfx/video_driver.o \ camera/camera_driver.o \ wifi/wifi_driver.o \ @@ -248,6 +249,7 @@ OBJ += frontend/frontend.o \ camera/drivers/nullcamera.o \ wifi/drivers/nullwifi.o \ gfx/drivers/nullgfx.o \ + gfx/display_servers/dispserv_null.o \ audio/drivers/nullaudio.o \ input/drivers/nullinput.o \ input/drivers_hid/null_hid.o \ @@ -1551,6 +1553,7 @@ ifneq ($(findstring Win32,$(OS)),) OBJ += gfx/drivers/gdi_gfx.o \ gfx/drivers_context/gdi_ctx.o \ gfx/drivers_font/gdi_font.o \ + gfx/display_servers/dispserv_win32.o \ menu/drivers_display/menu_display_gdi.o LIBS += -lmsimg32 -lhid -lsetupapi diff --git a/config.def.h b/config.def.h index 4145be9d77..50036db322 100644 --- a/config.def.h +++ b/config.def.h @@ -115,6 +115,11 @@ static const unsigned window_y = 0; static const unsigned fullscreen_x = 0; static const unsigned fullscreen_y = 0; +/* Amount of transparency to use for the main window. + * 1 is the most transparent while 100 is opaque. + */ +static const unsigned window_opacity = 100; + #if defined(RARCH_CONSOLE) || defined(__APPLE__) static const bool load_dummy_on_core_shutdown = false; #else diff --git a/configuration.c b/configuration.c index bcb7b0c578..bec0b42878 100644 --- a/configuration.c +++ b/configuration.c @@ -1378,6 +1378,7 @@ static struct config_uint_setting *populate_settings_uint(settings_t *settings, SETTING_UINT("video_fullscreen_y", &settings->uints.video_fullscreen_y, true, fullscreen_y, false); SETTING_UINT("video_window_x", &settings->uints.video_window_x, true, fullscreen_x, false); SETTING_UINT("video_window_y", &settings->uints.video_window_y, true, fullscreen_y, false); + SETTING_UINT("video_window_opacity", &settings->uints.video_window_opacity, true, window_opacity, false); #ifdef HAVE_COMMAND SETTING_UINT("network_cmd_port", &settings->uints.network_cmd_port, true, network_cmd_port, false); #endif diff --git a/configuration.h b/configuration.h index c81a53f962..c94b215209 100644 --- a/configuration.h +++ b/configuration.h @@ -325,6 +325,7 @@ typedef struct settings unsigned keymapper_port; unsigned video_window_x; unsigned video_window_y; + unsigned video_window_opacity; unsigned video_monitor_index; unsigned video_fullscreen_x; unsigned video_fullscreen_y; diff --git a/gfx/common/win32_common.c b/gfx/common/win32_common.c index a8a696cbb2..426632bbd0 100644 --- a/gfx/common/win32_common.c +++ b/gfx/common/win32_common.c @@ -45,6 +45,7 @@ #include "../../input/input_driver.h" #include "../../input/input_keymaps.h" #include "../video_thread_wrapper.h" +#include "../video_display_server.h" #include #ifdef HAVE_MENU @@ -742,6 +743,7 @@ bool win32_window_create(void *data, unsigned style, RECT *mon_rect, unsigned width, unsigned height, bool fullscreen) { + settings_t *settings = config_get_ptr(); #ifndef _XBOX main_window.hwnd = CreateWindowEx(0, "RetroArch", "RetroArch", @@ -756,6 +758,14 @@ bool win32_window_create(void *data, unsigned style, video_driver_display_type_set(RARCH_DISPLAY_WIN32); video_driver_display_set(0); video_driver_window_set((uintptr_t)main_window.hwnd); + +#if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0500 + /* Windows 2000 and above use layered windows to enable transparency */ + SetWindowLongPtr(main_window.hwnd, + GWL_EXSTYLE, + GetWindowLongPtr(main_window.hwnd, GWL_EXSTYLE) | WS_EX_LAYERED); + SetLayeredWindowAttributes(main_window.hwnd, 0, (255 * settings->uints.video_window_opacity) / 100, LWA_ALPHA); +#endif #endif return true; } diff --git a/gfx/display_servers/dispserv_null.c b/gfx/display_servers/dispserv_null.c new file mode 100644 index 0000000000..c40ef5bfc1 --- /dev/null +++ b/gfx/display_servers/dispserv_null.c @@ -0,0 +1,43 @@ +/* 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" + +static void* null_display_server_init() +{ + return NULL; +} + +static void null_display_server_destroy() +{ + +} + +static bool null_set_window_opacity(void *data, unsigned opacity) +{ + (void)data; + (void)opacity; + return true; +} + +const video_display_server_t dispserv_null = { + null_display_server_init, + null_display_server_destroy, + null_set_window_opacity, + "null" +}; + diff --git a/gfx/display_servers/dispserv_win32.c b/gfx/display_servers/dispserv_win32.c new file mode 100644 index 0000000000..fb66660640 --- /dev/null +++ b/gfx/display_servers/dispserv_win32.c @@ -0,0 +1,60 @@ +/* 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 +#include "../video_display_server.h" +#include "../common/win32_common.h" + +typedef struct +{ + unsigned opacity; +} dispserv_win32_t; + +static void* win32_display_server_init() +{ + dispserv_win32_t *dispserv = calloc(1, sizeof(*dispserv)); + + return dispserv; +} + +static void win32_display_server_destroy() +{ + +} + +static bool win32_set_window_opacity(void *data, unsigned opacity) +{ + HWND hwnd = win32_get_window(); + dispserv_win32_t *serv = (dispserv_win32_t*)data; + + serv->opacity = opacity; + +#if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0500 + /* Set window transparency on Windows 2000 and above */ + return SetLayeredWindowAttributes(hwnd, 0, opacity, LWA_ALPHA); +#else + return false; +#endif +} + +const video_display_server_t dispserv_win32 = { + win32_display_server_init, + win32_display_server_destroy, + win32_set_window_opacity, + "win32" +}; + diff --git a/gfx/video_display_server.c b/gfx/video_display_server.c new file mode 100644 index 0000000000..67793d962f --- /dev/null +++ b/gfx/video_display_server.c @@ -0,0 +1,55 @@ +/* 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 +#include "video_display_server.h" +#include "video_driver.h" +#include "../verbosity.h" + +static const video_display_server_t *current_display_server = NULL; +static void *current_display_server_data = NULL; + +void* video_display_server_init() +{ + enum rarch_display_type type = video_driver_display_type_get(); + + switch (type) + { + case RARCH_DISPLAY_WIN32: + current_display_server = &dispserv_win32; + break; + default: + current_display_server = &dispserv_null; + break; + } + + current_display_server_data = current_display_server->init(); + + RARCH_LOG("[Video]: Found display server: %s\n", current_display_server->ident); + + return current_display_server_data; +} + +void video_display_server_destroy() +{ + +} + +bool video_display_server_set_window_opacity(unsigned opacity) +{ + return current_display_server->set_window_opacity(current_display_server_data, opacity); +} diff --git a/gfx/video_display_server.h b/gfx/video_display_server.h new file mode 100644 index 0000000000..1b16c75b97 --- /dev/null +++ b/gfx/video_display_server.h @@ -0,0 +1,43 @@ +/* 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 . + */ + +#ifndef __VIDEO_DISPLAY_SERVER__H +#define __VIDEO_DISPLAY_SERVER__H + +#include +#include + +RETRO_BEGIN_DECLS + +typedef struct video_display_server +{ + void *(*init)(void); + void (*destroy)(void); + bool (*set_window_opacity)(void *data, unsigned opacity); + const char *ident; +} video_display_server_t; + +void* video_display_server_init(void); +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_null; + +RETRO_END_DECLS + +#endif diff --git a/gfx/video_driver.c b/gfx/video_driver.c index c4174e6726..b07d869967 100644 --- a/gfx/video_driver.c +++ b/gfx/video_driver.c @@ -48,6 +48,7 @@ #include "video_thread_wrapper.h" #include "video_driver.h" +#include "video_display_server.h" #include "../frontend/frontend_driver.h" #include "../record/record_driver.h" @@ -1089,6 +1090,8 @@ static bool video_driver_init_internal(bool *video_is_threaded) video_context_driver_reset(); + video_display_server_init(); + return true; error: @@ -1550,6 +1553,7 @@ static void video_driver_lock_new(void) void video_driver_destroy(void) { + video_display_server_destroy(); video_driver_cb_has_focus = null_driver_has_focus; video_driver_use_rgba = false; video_driver_data_own = false; diff --git a/griffin/griffin.c b/griffin/griffin.c index 9d866cb00e..720965d34d 100644 --- a/griffin/griffin.c +++ b/griffin/griffin.c @@ -188,9 +188,8 @@ VIDEO CONTEXT #include "../gfx/drivers_context/wgl_ctx.c" #endif -#if defined(_WIN32) && !defined(_XBOX) #include "../gfx/drivers_context/gdi_ctx.c" -#endif +#include "../gfx/display_servers/dispserv_win32.c" #if defined(HAVE_FFMPEG) #if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES3) @@ -371,6 +370,7 @@ VIDEO DRIVER #endif #include "../gfx/drivers_renderchain/null_renderchain.c" +#include "../gfx/display_servers/dispserv_null.c" #ifdef HAVE_OPENGL #include "../gfx/common/gl_common.c" @@ -746,6 +746,7 @@ AUDIO DRIVERS ============================================================ */ #include "../gfx/video_driver.c" +#include "../gfx/video_display_server.c" #include "../gfx/video_coord_array.c" #include "../input/input_driver.c" #include "../audio/audio_driver.c" diff --git a/intl/msg_hash_ja.h b/intl/msg_hash_ja.h index ec16dabcc3..ab498da29b 100644 --- a/intl/msg_hash_ja.h +++ b/intl/msg_hash_ja.h @@ -3263,3 +3263,5 @@ MSG_HASH(MENU_ENUM_SUBLABEL_AUTOMATICALLY_ADD_CONTENT_TO_PLAYLIST, "Automatically scans loaded content so they appear inside playlists.") MSG_HASH(MSG_SCANNING_OF_FILE_FINISHED, "Scanning of file finished") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_WINDOW_OPACITY, + "ウィンドウの不透明性") diff --git a/intl/msg_hash_lbl.h b/intl/msg_hash_lbl.h index a097ee5c90..bc5721bce0 100644 --- a/intl/msg_hash_lbl.h +++ b/intl/msg_hash_lbl.h @@ -1377,3 +1377,5 @@ MSG_HASH(MENU_ENUM_LABEL_FRAMECOUNT_SHOW, "framecount_show") MSG_HASH(MENU_ENUM_LABEL_AUTOMATICALLY_ADD_CONTENT_TO_PLAYLIST, "automatically_add_content_to_playlist") +MSG_HASH(MENU_ENUM_LABEL_VIDEO_WINDOW_OPACITY, + "video_window_opacity") diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index 25a36dda4f..e7ad35b7cc 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -3341,3 +3341,5 @@ MSG_HASH(MENU_ENUM_SUBLABEL_AUTOMATICALLY_ADD_CONTENT_TO_PLAYLIST, "Automatically scans loaded content so they appear inside playlists.") MSG_HASH(MSG_SCANNING_OF_FILE_FINISHED, "Scanning of file finished") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_WINDOW_OPACITY, + "Window Opacity") diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index 8a60cf2735..d3167f036a 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -6028,6 +6028,9 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_VIDEO_WINDOW_HEIGHT, PARSE_ONLY_UINT, false); + menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_VIDEO_WINDOW_OPACITY, + PARSE_ONLY_UINT, false); menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_VIDEO_SCALE_INTEGER, PARSE_ONLY_BOOL, false); diff --git a/menu/menu_setting.c b/menu/menu_setting.c index d55a5c8c81..f9ddce0cc1 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -81,6 +81,7 @@ #include "../setting_list.h" #include "../lakka.h" #include "../retroarch.h" +#include "../gfx/video_display_server.h" #include "../tasks/tasks_internal.h" @@ -1834,6 +1835,9 @@ void general_write_handler(void *data) retroarch_override_setting_set(RARCH_OVERRIDE_SETTING_NETPLAY_CHECK_FRAMES, NULL); #endif break; + case MENU_ENUM_LABEL_VIDEO_WINDOW_OPACITY: + video_display_server_set_window_opacity((255 * settings->uints.video_window_opacity) / 100); + break; default: break; } @@ -3628,6 +3632,19 @@ static bool setting_append_list( general_read_handler); menu_settings_list_current_add_range(list, list_info, 0, 4320, 8, true, true); settings_data_list_current_add_flags(list, list_info, SD_FLAG_LAKKA_ADVANCED); + CONFIG_UINT( + list, list_info, + &settings->uints.video_window_opacity, + MENU_ENUM_LABEL_VIDEO_WINDOW_OPACITY, + MENU_ENUM_LABEL_VALUE_VIDEO_WINDOW_OPACITY, + window_opacity, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler); + menu_settings_list_current_add_range(list, list_info, 1, 100, 1, true, true); + settings_data_list_current_add_flags(list, list_info, SD_FLAG_LAKKA_ADVANCED); } CONFIG_BOOL( diff --git a/msg_hash.h b/msg_hash.h index f9e92af1d3..48b55122ee 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -676,6 +676,7 @@ enum msg_hash_enums MENU_LABEL(VIDEO_WINDOWED_FULLSCREEN), MENU_LABEL(VIDEO_WINDOW_WIDTH), MENU_LABEL(VIDEO_WINDOW_HEIGHT), + MENU_LABEL(VIDEO_WINDOW_OPACITY), MENU_LABEL(VIDEO_FULLSCREEN_X), MENU_LABEL(VIDEO_FULLSCREEN_Y), MENU_LABEL(VIDEO_FORCE_SRGB_DISABLE),