move sunshine to src
- this will allow for common cpp workflow files within org
This commit is contained in:
parent
0de52efdb1
commit
a4acaf15b0
86 changed files with 3031 additions and 3031 deletions
2
.github/workflows/localize.yml
vendored
2
.github/workflows/localize.yml
vendored
|
|
@ -6,7 +6,7 @@ on:
|
||||||
branches: [nightly]
|
branches: [nightly]
|
||||||
paths: # prevents workflow from running unless these files change
|
paths: # prevents workflow from running unless these files change
|
||||||
- '.github/workflows/localize.yml'
|
- '.github/workflows/localize.yml'
|
||||||
- 'sunshine/**'
|
- 'src/**'
|
||||||
- 'locale/sunshine.po'
|
- 'locale/sunshine.po'
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
|
|
|
||||||
162
CMakeLists.txt
162
CMakeLists.txt
|
|
@ -100,18 +100,18 @@ if(WIN32)
|
||||||
if(NOT DEFINED SUNSHINE_ICON_PATH)
|
if(NOT DEFINED SUNSHINE_ICON_PATH)
|
||||||
set(SUNSHINE_ICON_PATH "${CMAKE_CURRENT_SOURCE_DIR}/sunshine.ico")
|
set(SUNSHINE_ICON_PATH "${CMAKE_CURRENT_SOURCE_DIR}/sunshine.ico")
|
||||||
endif()
|
endif()
|
||||||
configure_file(sunshine/platform/windows/windows.rs.in windows.rc @ONLY)
|
configure_file(src/platform/windows/windows.rs.in windows.rc @ONLY)
|
||||||
set(PLATFORM_TARGET_FILES
|
set(PLATFORM_TARGET_FILES
|
||||||
"${CMAKE_CURRENT_BINARY_DIR}/windows.rc"
|
"${CMAKE_CURRENT_BINARY_DIR}/windows.rc"
|
||||||
sunshine/platform/windows/publish.cpp
|
src/platform/windows/publish.cpp
|
||||||
sunshine/platform/windows/misc.h
|
src/platform/windows/misc.h
|
||||||
sunshine/platform/windows/misc.cpp
|
src/platform/windows/misc.cpp
|
||||||
sunshine/platform/windows/input.cpp
|
src/platform/windows/input.cpp
|
||||||
sunshine/platform/windows/display.h
|
src/platform/windows/display.h
|
||||||
sunshine/platform/windows/display_base.cpp
|
src/platform/windows/display_base.cpp
|
||||||
sunshine/platform/windows/display_vram.cpp
|
src/platform/windows/display_vram.cpp
|
||||||
sunshine/platform/windows/display_ram.cpp
|
src/platform/windows/display_ram.cpp
|
||||||
sunshine/platform/windows/audio.cpp
|
src/platform/windows/audio.cpp
|
||||||
third-party/ViGEmClient/src/ViGEmClient.cpp
|
third-party/ViGEmClient/src/ViGEmClient.cpp
|
||||||
third-party/ViGEmClient/include/ViGEm/Client.h
|
third-party/ViGEmClient/include/ViGEm/Client.h
|
||||||
third-party/ViGEmClient/include/ViGEm/Common.h
|
third-party/ViGEmClient/include/ViGEm/Common.h
|
||||||
|
|
@ -180,19 +180,19 @@ elseif(APPLE)
|
||||||
set(APPLE_PLIST_FILE ${SUNSHINE_SOURCE_ASSETS_DIR}/macos/assets/Info.plist)
|
set(APPLE_PLIST_FILE ${SUNSHINE_SOURCE_ASSETS_DIR}/macos/assets/Info.plist)
|
||||||
|
|
||||||
set(PLATFORM_TARGET_FILES
|
set(PLATFORM_TARGET_FILES
|
||||||
sunshine/platform/macos/av_audio.h
|
src/platform/macos/av_audio.h
|
||||||
sunshine/platform/macos/av_audio.m
|
src/platform/macos/av_audio.m
|
||||||
sunshine/platform/macos/av_img_t.h
|
src/platform/macos/av_img_t.h
|
||||||
sunshine/platform/macos/av_video.h
|
src/platform/macos/av_video.h
|
||||||
sunshine/platform/macos/av_video.m
|
src/platform/macos/av_video.m
|
||||||
sunshine/platform/macos/display.mm
|
src/platform/macos/display.mm
|
||||||
sunshine/platform/macos/input.cpp
|
src/platform/macos/input.cpp
|
||||||
sunshine/platform/macos/microphone.mm
|
src/platform/macos/microphone.mm
|
||||||
sunshine/platform/macos/misc.cpp
|
src/platform/macos/misc.cpp
|
||||||
sunshine/platform/macos/misc.h
|
src/platform/macos/misc.h
|
||||||
sunshine/platform/macos/nv12_zero_device.cpp
|
src/platform/macos/nv12_zero_device.cpp
|
||||||
sunshine/platform/macos/nv12_zero_device.h
|
src/platform/macos/nv12_zero_device.h
|
||||||
sunshine/platform/macos/publish.cpp
|
src/platform/macos/publish.cpp
|
||||||
third-party/TPCircularBuffer/TPCircularBuffer.c
|
third-party/TPCircularBuffer/TPCircularBuffer.c
|
||||||
third-party/TPCircularBuffer/TPCircularBuffer.h
|
third-party/TPCircularBuffer/TPCircularBuffer.h
|
||||||
${APPLE_PLIST_FILE})
|
${APPLE_PLIST_FILE})
|
||||||
|
|
@ -242,14 +242,14 @@ else()
|
||||||
if(X11_FOUND)
|
if(X11_FOUND)
|
||||||
add_compile_definitions(SUNSHINE_BUILD_X11)
|
add_compile_definitions(SUNSHINE_BUILD_X11)
|
||||||
include_directories(${X11_INCLUDE_DIR})
|
include_directories(${X11_INCLUDE_DIR})
|
||||||
list(APPEND PLATFORM_TARGET_FILES sunshine/platform/linux/x11grab.cpp)
|
list(APPEND PLATFORM_TARGET_FILES src/platform/linux/x11grab.cpp)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(CUDA_FOUND)
|
if(CUDA_FOUND)
|
||||||
include_directories(third-party/nvfbc)
|
include_directories(third-party/nvfbc)
|
||||||
list(APPEND PLATFORM_TARGET_FILES
|
list(APPEND PLATFORM_TARGET_FILES
|
||||||
sunshine/platform/linux/cuda.cu
|
src/platform/linux/cuda.cu
|
||||||
sunshine/platform/linux/cuda.cpp
|
src/platform/linux/cuda.cpp
|
||||||
third-party/nvfbc/NvFBC.h)
|
third-party/nvfbc/NvFBC.h)
|
||||||
|
|
||||||
add_compile_definitions(SUNSHINE_BUILD_CUDA)
|
add_compile_definitions(SUNSHINE_BUILD_CUDA)
|
||||||
|
|
@ -259,7 +259,7 @@ else()
|
||||||
add_compile_definitions(SUNSHINE_BUILD_DRM)
|
add_compile_definitions(SUNSHINE_BUILD_DRM)
|
||||||
include_directories(${LIBDRM_INCLUDE_DIRS} ${LIBCAP_INCLUDE_DIRS})
|
include_directories(${LIBDRM_INCLUDE_DIRS} ${LIBCAP_INCLUDE_DIRS})
|
||||||
list(APPEND PLATFORM_LIBRARIES ${LIBDRM_LIBRARIES} ${LIBCAP_LIBRARIES})
|
list(APPEND PLATFORM_LIBRARIES ${LIBDRM_LIBRARIES} ${LIBCAP_LIBRARIES})
|
||||||
list(APPEND PLATFORM_TARGET_FILES sunshine/platform/linux/kmsgrab.cpp)
|
list(APPEND PLATFORM_TARGET_FILES src/platform/linux/kmsgrab.cpp)
|
||||||
list(APPEND SUNSHINE_DEFINITIONS EGL_NO_X11=1)
|
list(APPEND SUNSHINE_DEFINITIONS EGL_NO_X11=1)
|
||||||
elseif(LIBDRM_FOUND)
|
elseif(LIBDRM_FOUND)
|
||||||
message(WARNING "Found libdrm, yet there is no libcap")
|
message(WARNING "Found libdrm, yet there is no libcap")
|
||||||
|
|
@ -301,26 +301,26 @@ else()
|
||||||
|
|
||||||
list(APPEND PLATFORM_LIBRARIES ${WAYLAND_LIBRARIES})
|
list(APPEND PLATFORM_LIBRARIES ${WAYLAND_LIBRARIES})
|
||||||
list(APPEND PLATFORM_TARGET_FILES
|
list(APPEND PLATFORM_TARGET_FILES
|
||||||
sunshine/platform/linux/wlgrab.cpp
|
src/platform/linux/wlgrab.cpp
|
||||||
sunshine/platform/linux/wayland.cpp)
|
src/platform/linux/wayland.cpp)
|
||||||
endif()
|
endif()
|
||||||
if(NOT ${X11_FOUND} AND NOT (${LIBDRM_FOUND} AND ${LIBCAP_FOUND}) AND NOT ${WAYLAND_FOUND} AND NOT ${})
|
if(NOT ${X11_FOUND} AND NOT (${LIBDRM_FOUND} AND ${LIBCAP_FOUND}) AND NOT ${WAYLAND_FOUND} AND NOT ${})
|
||||||
message(FATAL_ERROR "Couldn't find either x11, wayland, cuda or (libdrm and libcap)")
|
message(FATAL_ERROR "Couldn't find either x11, wayland, cuda or (libdrm and libcap)")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
list(APPEND PLATFORM_TARGET_FILES
|
list(APPEND PLATFORM_TARGET_FILES
|
||||||
sunshine/platform/linux/publish.cpp
|
src/platform/linux/publish.cpp
|
||||||
sunshine/platform/linux/vaapi.h
|
src/platform/linux/vaapi.h
|
||||||
sunshine/platform/linux/vaapi.cpp
|
src/platform/linux/vaapi.cpp
|
||||||
sunshine/platform/linux/cuda.h
|
src/platform/linux/cuda.h
|
||||||
sunshine/platform/linux/graphics.h
|
src/platform/linux/graphics.h
|
||||||
sunshine/platform/linux/graphics.cpp
|
src/platform/linux/graphics.cpp
|
||||||
sunshine/platform/linux/misc.h
|
src/platform/linux/misc.h
|
||||||
sunshine/platform/linux/misc.cpp
|
src/platform/linux/misc.cpp
|
||||||
sunshine/platform/linux/audio.cpp
|
src/platform/linux/audio.cpp
|
||||||
sunshine/platform/linux/input.cpp
|
src/platform/linux/input.cpp
|
||||||
sunshine/platform/linux/x11grab.h
|
src/platform/linux/x11grab.h
|
||||||
sunshine/platform/linux/wayland.h
|
src/platform/linux/wayland.h
|
||||||
third-party/glad/src/egl.c
|
third-party/glad/src/egl.c
|
||||||
third-party/glad/src/gl.c
|
third-party/glad/src/gl.c
|
||||||
third-party/glad/include/EGL/eglplatform.h
|
third-party/glad/include/EGL/eglplatform.h
|
||||||
|
|
@ -356,47 +356,47 @@ set(SUNSHINE_TARGET_FILES
|
||||||
third-party/moonlight-common-c/src/Rtsp.h
|
third-party/moonlight-common-c/src/Rtsp.h
|
||||||
third-party/moonlight-common-c/src/RtspParser.c
|
third-party/moonlight-common-c/src/RtspParser.c
|
||||||
third-party/moonlight-common-c/src/Video.h
|
third-party/moonlight-common-c/src/Video.h
|
||||||
sunshine/upnp.cpp
|
src/upnp.cpp
|
||||||
sunshine/upnp.h
|
src/upnp.h
|
||||||
sunshine/cbs.cpp
|
src/cbs.cpp
|
||||||
sunshine/utility.h
|
src/utility.h
|
||||||
sunshine/uuid.h
|
src/uuid.h
|
||||||
sunshine/config.h
|
src/config.h
|
||||||
sunshine/config.cpp
|
src/config.cpp
|
||||||
sunshine/main.cpp
|
src/main.cpp
|
||||||
sunshine/main.h
|
src/main.h
|
||||||
sunshine/crypto.cpp
|
src/crypto.cpp
|
||||||
sunshine/crypto.h
|
src/crypto.h
|
||||||
sunshine/nvhttp.cpp
|
src/nvhttp.cpp
|
||||||
sunshine/nvhttp.h
|
src/nvhttp.h
|
||||||
sunshine/httpcommon.cpp
|
src/httpcommon.cpp
|
||||||
sunshine/httpcommon.h
|
src/httpcommon.h
|
||||||
sunshine/confighttp.cpp
|
src/confighttp.cpp
|
||||||
sunshine/confighttp.h
|
src/confighttp.h
|
||||||
sunshine/rtsp.cpp
|
src/rtsp.cpp
|
||||||
sunshine/rtsp.h
|
src/rtsp.h
|
||||||
sunshine/stream.cpp
|
src/stream.cpp
|
||||||
sunshine/stream.h
|
src/stream.h
|
||||||
sunshine/video.cpp
|
src/video.cpp
|
||||||
sunshine/video.h
|
src/video.h
|
||||||
sunshine/input.cpp
|
src/input.cpp
|
||||||
sunshine/input.h
|
src/input.h
|
||||||
sunshine/audio.cpp
|
src/audio.cpp
|
||||||
sunshine/audio.h
|
src/audio.h
|
||||||
sunshine/platform/common.h
|
src/platform/common.h
|
||||||
sunshine/process.cpp
|
src/process.cpp
|
||||||
sunshine/process.h
|
src/process.h
|
||||||
sunshine/network.cpp
|
src/network.cpp
|
||||||
sunshine/network.h
|
src/network.h
|
||||||
sunshine/move_by_copy.h
|
src/move_by_copy.h
|
||||||
sunshine/task_pool.h
|
src/task_pool.h
|
||||||
sunshine/thread_pool.h
|
src/thread_pool.h
|
||||||
sunshine/thread_safe.h
|
src/thread_safe.h
|
||||||
sunshine/sync.h
|
src/sync.h
|
||||||
sunshine/round_robin.h
|
src/round_robin.h
|
||||||
${PLATFORM_TARGET_FILES})
|
${PLATFORM_TARGET_FILES})
|
||||||
|
|
||||||
set_source_files_properties(sunshine/upnp.cpp PROPERTIES COMPILE_FLAGS -Wno-pedantic)
|
set_source_files_properties(src/upnp.cpp PROPERTIES COMPILE_FLAGS -Wno-pedantic)
|
||||||
|
|
||||||
include_directories(
|
include_directories(
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}
|
${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
|
|
@ -414,7 +414,7 @@ string(TOUPPER "x${CMAKE_BUILD_TYPE}" BUILD_TYPE)
|
||||||
if("${BUILD_TYPE}" STREQUAL "XDEBUG")
|
if("${BUILD_TYPE}" STREQUAL "XDEBUG")
|
||||||
list(APPEND SUNSHINE_COMPILE_OPTIONS -O0 -ggdb3)
|
list(APPEND SUNSHINE_COMPILE_OPTIONS -O0 -ggdb3)
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
set_source_files_properties(sunshine/nvhttp.cpp PROPERTIES COMPILE_FLAGS -O2)
|
set_source_files_properties(src/nvhttp.cpp PROPERTIES COMPILE_FLAGS -O2)
|
||||||
endif()
|
endif()
|
||||||
else()
|
else()
|
||||||
add_definitions(-DNDEBUG)
|
add_definitions(-DNDEBUG)
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,7 @@ any of the following paths are modified.
|
||||||
|
|
||||||
.. code-block:: yaml
|
.. code-block:: yaml
|
||||||
|
|
||||||
- 'sunshine/**'
|
- 'src/**'
|
||||||
|
|
||||||
When testing locally it may be desirable to manually extract, initialize, update, and compile strings. Python is
|
When testing locally it may be desirable to manually extract, initialize, update, and compile strings. Python is
|
||||||
required for this, along with the python dependencies in the `./scripts/requirements.txt` file. Additionally,
|
required for this, along with the python dependencies in the `./scripts/requirements.txt` file. Additionally,
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,8 @@
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "sunshine/thread_safe.h"
|
#include "src/thread_safe.h"
|
||||||
#include "sunshine/utility.h"
|
#include "src/utility.h"
|
||||||
|
|
||||||
struct sockaddr;
|
struct sockaddr;
|
||||||
struct AVFrame;
|
struct AVFrame;
|
||||||
|
|
@ -10,11 +10,11 @@
|
||||||
#include <pulse/pulseaudio.h>
|
#include <pulse/pulseaudio.h>
|
||||||
#include <pulse/simple.h>
|
#include <pulse/simple.h>
|
||||||
|
|
||||||
#include "sunshine/platform/common.h"
|
#include "src/platform/common.h"
|
||||||
|
|
||||||
#include "sunshine/config.h"
|
#include "src/config.h"
|
||||||
#include "sunshine/main.h"
|
#include "src/main.h"
|
||||||
#include "sunshine/thread_safe.h"
|
#include "src/thread_safe.h"
|
||||||
|
|
||||||
namespace platf {
|
namespace platf {
|
||||||
using namespace std::literals;
|
using namespace std::literals;
|
||||||
|
|
@ -11,8 +11,8 @@ extern "C" {
|
||||||
|
|
||||||
#include "cuda.h"
|
#include "cuda.h"
|
||||||
#include "graphics.h"
|
#include "graphics.h"
|
||||||
#include "sunshine/main.h"
|
#include "src/main.h"
|
||||||
#include "sunshine/utility.h"
|
#include "src/utility.h"
|
||||||
#include "wayland.h"
|
#include "wayland.h"
|
||||||
|
|
||||||
#define SUNSHINE_STRINGVIEW_HELPER(x) x##sv
|
#define SUNSHINE_STRINGVIEW_HELPER(x) x##sv
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
#include "graphics.h"
|
#include "graphics.h"
|
||||||
#include "sunshine/video.h"
|
#include "src/video.h"
|
||||||
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
|
@ -8,9 +8,9 @@
|
||||||
#include <glad/gl.h>
|
#include <glad/gl.h>
|
||||||
|
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "sunshine/main.h"
|
#include "src/main.h"
|
||||||
#include "sunshine/platform/common.h"
|
#include "src/platform/common.h"
|
||||||
#include "sunshine/utility.h"
|
#include "src/utility.h"
|
||||||
|
|
||||||
#define SUNSHINE_STRINGIFY_HELPER(x) #x
|
#define SUNSHINE_STRINGIFY_HELPER(x) #x
|
||||||
#define SUNSHINE_STRINGIFY(x) SUNSHINE_STRINGIFY_HELPER(x)
|
#define SUNSHINE_STRINGIFY(x) SUNSHINE_STRINGIFY_HELPER(x)
|
||||||
|
|
@ -9,11 +9,11 @@
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
|
||||||
#include "sunshine/main.h"
|
#include "src/main.h"
|
||||||
#include "sunshine/platform/common.h"
|
#include "src/platform/common.h"
|
||||||
#include "sunshine/utility.h"
|
#include "src/utility.h"
|
||||||
|
|
||||||
#include "sunshine/platform/common.h"
|
#include "src/platform/common.h"
|
||||||
|
|
||||||
// Support older versions
|
// Support older versions
|
||||||
#ifndef REL_HWHEEL_HI_RES
|
#ifndef REL_HWHEEL_HI_RES
|
||||||
|
|
@ -8,10 +8,10 @@
|
||||||
|
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
|
||||||
#include "sunshine/main.h"
|
#include "src/main.h"
|
||||||
#include "sunshine/platform/common.h"
|
#include "src/platform/common.h"
|
||||||
#include "sunshine/round_robin.h"
|
#include "src/round_robin.h"
|
||||||
#include "sunshine/utility.h"
|
#include "src/utility.h"
|
||||||
|
|
||||||
// Cursor rendering support through x11
|
// Cursor rendering support through x11
|
||||||
#include "graphics.h"
|
#include "graphics.h"
|
||||||
|
|
@ -11,8 +11,8 @@
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "vaapi.h"
|
#include "vaapi.h"
|
||||||
|
|
||||||
#include "sunshine/main.h"
|
#include "src/main.h"
|
||||||
#include "sunshine/platform/common.h"
|
#include "src/platform/common.h"
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
#define SUNSHINE_GNUC_EXTENSION __extension__
|
#define SUNSHINE_GNUC_EXTENSION __extension__
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "sunshine/utility.h"
|
#include "src/utility.h"
|
||||||
|
|
||||||
KITTY_USING_MOVE_T(file_t, int, -1, {
|
KITTY_USING_MOVE_T(file_t, int, -1, {
|
||||||
if(el >= 0) {
|
if(el >= 0) {
|
||||||
|
|
@ -3,10 +3,10 @@
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "sunshine/main.h"
|
#include "src/main.h"
|
||||||
#include "sunshine/nvhttp.h"
|
#include "src/nvhttp.h"
|
||||||
#include "sunshine/platform/common.h"
|
#include "src/platform/common.h"
|
||||||
#include "sunshine/utility.h"
|
#include "src/utility.h"
|
||||||
|
|
||||||
using namespace std::literals;
|
using namespace std::literals;
|
||||||
|
|
||||||
|
|
@ -9,10 +9,10 @@ extern "C" {
|
||||||
|
|
||||||
#include "graphics.h"
|
#include "graphics.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "sunshine/config.h"
|
#include "src/config.h"
|
||||||
#include "sunshine/main.h"
|
#include "src/main.h"
|
||||||
#include "sunshine/platform/common.h"
|
#include "src/platform/common.h"
|
||||||
#include "sunshine/utility.h"
|
#include "src/utility.h"
|
||||||
|
|
||||||
using namespace std::literals;
|
using namespace std::literals;
|
||||||
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
#define SUNSHINE_VAAPI_H
|
#define SUNSHINE_VAAPI_H
|
||||||
|
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "sunshine/platform/common.h"
|
#include "src/platform/common.h"
|
||||||
|
|
||||||
namespace egl {
|
namespace egl {
|
||||||
struct surface_descriptor_t;
|
struct surface_descriptor_t;
|
||||||
|
|
@ -4,10 +4,10 @@
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
#include "graphics.h"
|
#include "graphics.h"
|
||||||
#include "sunshine/main.h"
|
#include "src/main.h"
|
||||||
#include "sunshine/platform/common.h"
|
#include "src/platform/common.h"
|
||||||
#include "sunshine/round_robin.h"
|
#include "src/round_robin.h"
|
||||||
#include "sunshine/utility.h"
|
#include "src/utility.h"
|
||||||
#include "wayland.h"
|
#include "wayland.h"
|
||||||
|
|
||||||
extern const wl_interface wl_output_interface;
|
extern const wl_interface wl_output_interface;
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
#include "sunshine/platform/common.h"
|
#include "src/platform/common.h"
|
||||||
|
|
||||||
#include "sunshine/main.h"
|
#include "src/main.h"
|
||||||
#include "vaapi.h"
|
#include "vaapi.h"
|
||||||
#include "wayland.h"
|
#include "wayland.h"
|
||||||
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
// Created by loki on 6/21/19.
|
// Created by loki on 6/21/19.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "sunshine/platform/common.h"
|
#include "src/platform/common.h"
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
|
|
@ -16,9 +16,9 @@
|
||||||
#include <xcb/shm.h>
|
#include <xcb/shm.h>
|
||||||
#include <xcb/xfixes.h>
|
#include <xcb/xfixes.h>
|
||||||
|
|
||||||
#include "sunshine/config.h"
|
#include "src/config.h"
|
||||||
#include "sunshine/main.h"
|
#include "src/main.h"
|
||||||
#include "sunshine/task_pool.h"
|
#include "src/task_pool.h"
|
||||||
|
|
||||||
#include "cuda.h"
|
#include "cuda.h"
|
||||||
#include "graphics.h"
|
#include "graphics.h"
|
||||||
|
|
@ -3,8 +3,8 @@
|
||||||
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
|
||||||
#include "sunshine/platform/common.h"
|
#include "src/platform/common.h"
|
||||||
#include "sunshine/utility.h"
|
#include "src/utility.h"
|
||||||
|
|
||||||
// X11 Display
|
// X11 Display
|
||||||
extern "C" struct _XDisplay;
|
extern "C" struct _XDisplay;
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef av_img_t_h
|
#ifndef av_img_t_h
|
||||||
#define av_img_t_h
|
#define av_img_t_h
|
||||||
|
|
||||||
#include "sunshine/platform/common.h"
|
#include "src/platform/common.h"
|
||||||
|
|
||||||
#include <CoreMedia/CoreMedia.h>
|
#include <CoreMedia/CoreMedia.h>
|
||||||
#include <CoreVideo/CoreVideo.h>
|
#include <CoreVideo/CoreVideo.h>
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
#include "sunshine/platform/common.h"
|
#include "src/platform/common.h"
|
||||||
#include "sunshine/platform/macos/av_img_t.h"
|
#include "src/platform/macos/av_img_t.h"
|
||||||
#include "sunshine/platform/macos/av_video.h"
|
#include "src/platform/macos/av_video.h"
|
||||||
#include "sunshine/platform/macos/nv12_zero_device.h"
|
#include "src/platform/macos/nv12_zero_device.h"
|
||||||
|
|
||||||
#include "sunshine/config.h"
|
#include "src/config.h"
|
||||||
#include "sunshine/main.h"
|
#include "src/main.h"
|
||||||
|
|
||||||
namespace fs = std::filesystem;
|
namespace fs = std::filesystem;
|
||||||
|
|
||||||
|
|
@ -2,9 +2,9 @@
|
||||||
#include <mach/mach.h>
|
#include <mach/mach.h>
|
||||||
#include <mach/mach_time.h>
|
#include <mach/mach_time.h>
|
||||||
|
|
||||||
#include "sunshine/main.h"
|
#include "src/main.h"
|
||||||
#include "sunshine/platform/common.h"
|
#include "src/platform/common.h"
|
||||||
#include "sunshine/utility.h"
|
#include "src/utility.h"
|
||||||
|
|
||||||
// Delay for a double click
|
// Delay for a double click
|
||||||
// FIXME: we probably want to make this configurable
|
// FIXME: we probably want to make this configurable
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
#include "sunshine/platform/common.h"
|
#include "src/platform/common.h"
|
||||||
#include "sunshine/platform/macos/av_audio.h"
|
#include "src/platform/macos/av_audio.h"
|
||||||
|
|
||||||
#include "sunshine/config.h"
|
#include "src/config.h"
|
||||||
#include "sunshine/main.h"
|
#include "src/main.h"
|
||||||
|
|
||||||
namespace platf {
|
namespace platf {
|
||||||
using namespace std::literals;
|
using namespace std::literals;
|
||||||
|
|
@ -6,8 +6,8 @@
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
|
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "sunshine/main.h"
|
#include "src/main.h"
|
||||||
#include "sunshine/platform/common.h"
|
#include "src/platform/common.h"
|
||||||
|
|
||||||
using namespace std::literals;
|
using namespace std::literals;
|
||||||
namespace fs = std::filesystem;
|
namespace fs = std::filesystem;
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#include "sunshine/platform/macos/nv12_zero_device.h"
|
#include "src/platform/macos/nv12_zero_device.h"
|
||||||
#include "sunshine/platform/macos/av_img_t.h"
|
#include "src/platform/macos/av_img_t.h"
|
||||||
|
|
||||||
#include "sunshine/video.h"
|
#include "src/video.h"
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include "libavutil/imgutils.h"
|
#include "libavutil/imgutils.h"
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef vtdevice_h
|
#ifndef vtdevice_h
|
||||||
#define vtdevice_h
|
#define vtdevice_h
|
||||||
|
|
||||||
#include "sunshine/platform/common.h"
|
#include "src/platform/common.h"
|
||||||
|
|
||||||
namespace platf {
|
namespace platf {
|
||||||
|
|
||||||
|
|
@ -3,10 +3,10 @@
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "sunshine/main.h"
|
#include "src/main.h"
|
||||||
#include "sunshine/nvhttp.h"
|
#include "src/nvhttp.h"
|
||||||
#include "sunshine/platform/common.h"
|
#include "src/platform/common.h"
|
||||||
#include "sunshine/utility.h"
|
#include "src/utility.h"
|
||||||
|
|
||||||
using namespace std::literals;
|
using namespace std::literals;
|
||||||
|
|
||||||
|
|
@ -1,164 +1,164 @@
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// PolicyConfig.h
|
// PolicyConfig.h
|
||||||
// Undocumented COM-interface IPolicyConfig.
|
// Undocumented COM-interface IPolicyConfig.
|
||||||
// Use for set default audio render endpoint
|
// Use for set default audio render endpoint
|
||||||
// @author EreTIk
|
// @author EreTIk
|
||||||
// http://eretik.omegahg.com/
|
// http://eretik.omegahg.com/
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#ifdef __MINGW32__
|
#ifdef __MINGW32__
|
||||||
#undef DEFINE_GUID
|
#undef DEFINE_GUID
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) EXTERN_C const GUID DECLSPEC_SELECTANY name = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }
|
#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) EXTERN_C const GUID DECLSPEC_SELECTANY name = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }
|
||||||
#else
|
#else
|
||||||
#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) const GUID DECLSPEC_SELECTANY name = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }
|
#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) const GUID DECLSPEC_SELECTANY name = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DEFINE_GUID(IID_IPolicyConfig, 0xf8679f50, 0x850a, 0x41cf, 0x9c, 0x72, 0x43, 0x0f, 0x29, 0x02, 0x90, 0xc8);
|
DEFINE_GUID(IID_IPolicyConfig, 0xf8679f50, 0x850a, 0x41cf, 0x9c, 0x72, 0x43, 0x0f, 0x29, 0x02, 0x90, 0xc8);
|
||||||
DEFINE_GUID(CLSID_CPolicyConfigClient, 0x870af99c, 0x171d, 0x4f9e, 0xaf, 0x0d, 0xe6, 0x3d, 0xf4, 0x0c, 0x2b, 0xc9);
|
DEFINE_GUID(CLSID_CPolicyConfigClient, 0x870af99c, 0x171d, 0x4f9e, 0xaf, 0x0d, 0xe6, 0x3d, 0xf4, 0x0c, 0x2b, 0xc9);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
interface DECLSPEC_UUID("f8679f50-850a-41cf-9c72-430f290290c8") IPolicyConfig;
|
interface DECLSPEC_UUID("f8679f50-850a-41cf-9c72-430f290290c8") IPolicyConfig;
|
||||||
class DECLSPEC_UUID("870af99c-171d-4f9e-af0d-e63df40c2bc9") CPolicyConfigClient;
|
class DECLSPEC_UUID("870af99c-171d-4f9e-af0d-e63df40c2bc9") CPolicyConfigClient;
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// class CPolicyConfigClient
|
// class CPolicyConfigClient
|
||||||
// {870af99c-171d-4f9e-af0d-e63df40c2bc9}
|
// {870af99c-171d-4f9e-af0d-e63df40c2bc9}
|
||||||
//
|
//
|
||||||
// interface IPolicyConfig
|
// interface IPolicyConfig
|
||||||
// {f8679f50-850a-41cf-9c72-430f290290c8}
|
// {f8679f50-850a-41cf-9c72-430f290290c8}
|
||||||
//
|
//
|
||||||
// Query interface:
|
// Query interface:
|
||||||
// CComPtr<IPolicyConfig> PolicyConfig;
|
// CComPtr<IPolicyConfig> PolicyConfig;
|
||||||
// PolicyConfig.CoCreateInstance(__uuidof(CPolicyConfigClient));
|
// PolicyConfig.CoCreateInstance(__uuidof(CPolicyConfigClient));
|
||||||
//
|
//
|
||||||
// @compatible: Windows 7 and Later
|
// @compatible: Windows 7 and Later
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
interface IPolicyConfig : public IUnknown {
|
interface IPolicyConfig : public IUnknown {
|
||||||
public:
|
public:
|
||||||
virtual HRESULT GetMixFormat(
|
virtual HRESULT GetMixFormat(
|
||||||
PCWSTR,
|
PCWSTR,
|
||||||
WAVEFORMATEX **);
|
WAVEFORMATEX **);
|
||||||
|
|
||||||
virtual HRESULT STDMETHODCALLTYPE GetDeviceFormat(
|
virtual HRESULT STDMETHODCALLTYPE GetDeviceFormat(
|
||||||
PCWSTR,
|
PCWSTR,
|
||||||
INT,
|
INT,
|
||||||
WAVEFORMATEX **);
|
WAVEFORMATEX **);
|
||||||
|
|
||||||
virtual HRESULT STDMETHODCALLTYPE ResetDeviceFormat(
|
virtual HRESULT STDMETHODCALLTYPE ResetDeviceFormat(
|
||||||
PCWSTR);
|
PCWSTR);
|
||||||
|
|
||||||
virtual HRESULT STDMETHODCALLTYPE SetDeviceFormat(
|
virtual HRESULT STDMETHODCALLTYPE SetDeviceFormat(
|
||||||
PCWSTR,
|
PCWSTR,
|
||||||
WAVEFORMATEX *,
|
WAVEFORMATEX *,
|
||||||
WAVEFORMATEX *);
|
WAVEFORMATEX *);
|
||||||
|
|
||||||
virtual HRESULT STDMETHODCALLTYPE GetProcessingPeriod(
|
virtual HRESULT STDMETHODCALLTYPE GetProcessingPeriod(
|
||||||
PCWSTR,
|
PCWSTR,
|
||||||
INT,
|
INT,
|
||||||
PINT64,
|
PINT64,
|
||||||
PINT64);
|
PINT64);
|
||||||
|
|
||||||
virtual HRESULT STDMETHODCALLTYPE SetProcessingPeriod(
|
virtual HRESULT STDMETHODCALLTYPE SetProcessingPeriod(
|
||||||
PCWSTR,
|
PCWSTR,
|
||||||
PINT64);
|
PINT64);
|
||||||
|
|
||||||
virtual HRESULT STDMETHODCALLTYPE GetShareMode(
|
virtual HRESULT STDMETHODCALLTYPE GetShareMode(
|
||||||
PCWSTR,
|
PCWSTR,
|
||||||
struct DeviceShareMode *);
|
struct DeviceShareMode *);
|
||||||
|
|
||||||
virtual HRESULT STDMETHODCALLTYPE SetShareMode(
|
virtual HRESULT STDMETHODCALLTYPE SetShareMode(
|
||||||
PCWSTR,
|
PCWSTR,
|
||||||
struct DeviceShareMode *);
|
struct DeviceShareMode *);
|
||||||
|
|
||||||
virtual HRESULT STDMETHODCALLTYPE GetPropertyValue(
|
virtual HRESULT STDMETHODCALLTYPE GetPropertyValue(
|
||||||
PCWSTR,
|
PCWSTR,
|
||||||
const PROPERTYKEY &,
|
const PROPERTYKEY &,
|
||||||
PROPVARIANT *);
|
PROPVARIANT *);
|
||||||
|
|
||||||
virtual HRESULT STDMETHODCALLTYPE SetPropertyValue(
|
virtual HRESULT STDMETHODCALLTYPE SetPropertyValue(
|
||||||
PCWSTR,
|
PCWSTR,
|
||||||
const PROPERTYKEY &,
|
const PROPERTYKEY &,
|
||||||
PROPVARIANT *);
|
PROPVARIANT *);
|
||||||
|
|
||||||
virtual HRESULT STDMETHODCALLTYPE SetDefaultEndpoint(
|
virtual HRESULT STDMETHODCALLTYPE SetDefaultEndpoint(
|
||||||
PCWSTR wszDeviceId,
|
PCWSTR wszDeviceId,
|
||||||
ERole eRole);
|
ERole eRole);
|
||||||
|
|
||||||
virtual HRESULT STDMETHODCALLTYPE SetEndpointVisibility(
|
virtual HRESULT STDMETHODCALLTYPE SetEndpointVisibility(
|
||||||
PCWSTR,
|
PCWSTR,
|
||||||
INT);
|
INT);
|
||||||
};
|
};
|
||||||
|
|
||||||
interface DECLSPEC_UUID("568b9108-44bf-40b4-9006-86afe5b5a620") IPolicyConfigVista;
|
interface DECLSPEC_UUID("568b9108-44bf-40b4-9006-86afe5b5a620") IPolicyConfigVista;
|
||||||
class DECLSPEC_UUID("294935CE-F637-4E7C-A41B-AB255460B862") CPolicyConfigVistaClient;
|
class DECLSPEC_UUID("294935CE-F637-4E7C-A41B-AB255460B862") CPolicyConfigVistaClient;
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// class CPolicyConfigVistaClient
|
// class CPolicyConfigVistaClient
|
||||||
// {294935CE-F637-4E7C-A41B-AB255460B862}
|
// {294935CE-F637-4E7C-A41B-AB255460B862}
|
||||||
//
|
//
|
||||||
// interface IPolicyConfigVista
|
// interface IPolicyConfigVista
|
||||||
// {568b9108-44bf-40b4-9006-86afe5b5a620}
|
// {568b9108-44bf-40b4-9006-86afe5b5a620}
|
||||||
//
|
//
|
||||||
// Query interface:
|
// Query interface:
|
||||||
// CComPtr<IPolicyConfigVista> PolicyConfig;
|
// CComPtr<IPolicyConfigVista> PolicyConfig;
|
||||||
// PolicyConfig.CoCreateInstance(__uuidof(CPolicyConfigVistaClient));
|
// PolicyConfig.CoCreateInstance(__uuidof(CPolicyConfigVistaClient));
|
||||||
//
|
//
|
||||||
// @compatible: Windows Vista and Later
|
// @compatible: Windows Vista and Later
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
interface IPolicyConfigVista : public IUnknown {
|
interface IPolicyConfigVista : public IUnknown {
|
||||||
public:
|
public:
|
||||||
virtual HRESULT GetMixFormat(
|
virtual HRESULT GetMixFormat(
|
||||||
PCWSTR,
|
PCWSTR,
|
||||||
WAVEFORMATEX **); // not available on Windows 7, use method from IPolicyConfig
|
WAVEFORMATEX **); // not available on Windows 7, use method from IPolicyConfig
|
||||||
|
|
||||||
virtual HRESULT STDMETHODCALLTYPE GetDeviceFormat(
|
virtual HRESULT STDMETHODCALLTYPE GetDeviceFormat(
|
||||||
PCWSTR,
|
PCWSTR,
|
||||||
INT,
|
INT,
|
||||||
WAVEFORMATEX **);
|
WAVEFORMATEX **);
|
||||||
|
|
||||||
virtual HRESULT STDMETHODCALLTYPE SetDeviceFormat(
|
virtual HRESULT STDMETHODCALLTYPE SetDeviceFormat(
|
||||||
PCWSTR,
|
PCWSTR,
|
||||||
WAVEFORMATEX *,
|
WAVEFORMATEX *,
|
||||||
WAVEFORMATEX *);
|
WAVEFORMATEX *);
|
||||||
|
|
||||||
virtual HRESULT STDMETHODCALLTYPE GetProcessingPeriod(
|
virtual HRESULT STDMETHODCALLTYPE GetProcessingPeriod(
|
||||||
PCWSTR,
|
PCWSTR,
|
||||||
INT,
|
INT,
|
||||||
PINT64,
|
PINT64,
|
||||||
PINT64); // not available on Windows 7, use method from IPolicyConfig
|
PINT64); // not available on Windows 7, use method from IPolicyConfig
|
||||||
|
|
||||||
virtual HRESULT STDMETHODCALLTYPE SetProcessingPeriod(
|
virtual HRESULT STDMETHODCALLTYPE SetProcessingPeriod(
|
||||||
PCWSTR,
|
PCWSTR,
|
||||||
PINT64); // not available on Windows 7, use method from IPolicyConfig
|
PINT64); // not available on Windows 7, use method from IPolicyConfig
|
||||||
|
|
||||||
virtual HRESULT STDMETHODCALLTYPE GetShareMode(
|
virtual HRESULT STDMETHODCALLTYPE GetShareMode(
|
||||||
PCWSTR,
|
PCWSTR,
|
||||||
struct DeviceShareMode *); // not available on Windows 7, use method from IPolicyConfig
|
struct DeviceShareMode *); // not available on Windows 7, use method from IPolicyConfig
|
||||||
|
|
||||||
virtual HRESULT STDMETHODCALLTYPE SetShareMode(
|
virtual HRESULT STDMETHODCALLTYPE SetShareMode(
|
||||||
PCWSTR,
|
PCWSTR,
|
||||||
struct DeviceShareMode *); // not available on Windows 7, use method from IPolicyConfig
|
struct DeviceShareMode *); // not available on Windows 7, use method from IPolicyConfig
|
||||||
|
|
||||||
virtual HRESULT STDMETHODCALLTYPE GetPropertyValue(
|
virtual HRESULT STDMETHODCALLTYPE GetPropertyValue(
|
||||||
PCWSTR,
|
PCWSTR,
|
||||||
const PROPERTYKEY &,
|
const PROPERTYKEY &,
|
||||||
PROPVARIANT *);
|
PROPVARIANT *);
|
||||||
|
|
||||||
virtual HRESULT STDMETHODCALLTYPE SetPropertyValue(
|
virtual HRESULT STDMETHODCALLTYPE SetPropertyValue(
|
||||||
PCWSTR,
|
PCWSTR,
|
||||||
const PROPERTYKEY &,
|
const PROPERTYKEY &,
|
||||||
PROPVARIANT *);
|
PROPVARIANT *);
|
||||||
|
|
||||||
virtual HRESULT STDMETHODCALLTYPE SetDefaultEndpoint(
|
virtual HRESULT STDMETHODCALLTYPE SetDefaultEndpoint(
|
||||||
PCWSTR wszDeviceId,
|
PCWSTR wszDeviceId,
|
||||||
ERole eRole);
|
ERole eRole);
|
||||||
|
|
||||||
virtual HRESULT STDMETHODCALLTYPE SetEndpointVisibility(
|
virtual HRESULT STDMETHODCALLTYPE SetEndpointVisibility(
|
||||||
PCWSTR,
|
PCWSTR,
|
||||||
INT); // not available on Windows 7, use method from IPolicyConfig
|
INT); // not available on Windows 7, use method from IPolicyConfig
|
||||||
};
|
};
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,177 +1,177 @@
|
||||||
//
|
//
|
||||||
// Created by loki on 4/23/20.
|
// Created by loki on 4/23/20.
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifndef SUNSHINE_DISPLAY_H
|
#ifndef SUNSHINE_DISPLAY_H
|
||||||
#define SUNSHINE_DISPLAY_H
|
#define SUNSHINE_DISPLAY_H
|
||||||
|
|
||||||
#include <d3d11.h>
|
#include <d3d11.h>
|
||||||
#include <d3d11_4.h>
|
#include <d3d11_4.h>
|
||||||
#include <d3dcommon.h>
|
#include <d3dcommon.h>
|
||||||
#include <dwmapi.h>
|
#include <dwmapi.h>
|
||||||
#include <dxgi.h>
|
#include <dxgi.h>
|
||||||
#include <dxgi1_2.h>
|
#include <dxgi1_2.h>
|
||||||
|
|
||||||
#include "sunshine/platform/common.h"
|
#include "src/platform/common.h"
|
||||||
#include "sunshine/utility.h"
|
#include "src/utility.h"
|
||||||
|
|
||||||
namespace platf::dxgi {
|
namespace platf::dxgi {
|
||||||
extern const char *format_str[];
|
extern const char *format_str[];
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
void Release(T *dxgi) {
|
void Release(T *dxgi) {
|
||||||
dxgi->Release();
|
dxgi->Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
using factory1_t = util::safe_ptr<IDXGIFactory1, Release<IDXGIFactory1>>;
|
using factory1_t = util::safe_ptr<IDXGIFactory1, Release<IDXGIFactory1>>;
|
||||||
using dxgi_t = util::safe_ptr<IDXGIDevice, Release<IDXGIDevice>>;
|
using dxgi_t = util::safe_ptr<IDXGIDevice, Release<IDXGIDevice>>;
|
||||||
using dxgi1_t = util::safe_ptr<IDXGIDevice1, Release<IDXGIDevice1>>;
|
using dxgi1_t = util::safe_ptr<IDXGIDevice1, Release<IDXGIDevice1>>;
|
||||||
using device_t = util::safe_ptr<ID3D11Device, Release<ID3D11Device>>;
|
using device_t = util::safe_ptr<ID3D11Device, Release<ID3D11Device>>;
|
||||||
using device_ctx_t = util::safe_ptr<ID3D11DeviceContext, Release<ID3D11DeviceContext>>;
|
using device_ctx_t = util::safe_ptr<ID3D11DeviceContext, Release<ID3D11DeviceContext>>;
|
||||||
using adapter_t = util::safe_ptr<IDXGIAdapter1, Release<IDXGIAdapter1>>;
|
using adapter_t = util::safe_ptr<IDXGIAdapter1, Release<IDXGIAdapter1>>;
|
||||||
using output_t = util::safe_ptr<IDXGIOutput, Release<IDXGIOutput>>;
|
using output_t = util::safe_ptr<IDXGIOutput, Release<IDXGIOutput>>;
|
||||||
using output1_t = util::safe_ptr<IDXGIOutput1, Release<IDXGIOutput1>>;
|
using output1_t = util::safe_ptr<IDXGIOutput1, Release<IDXGIOutput1>>;
|
||||||
using dup_t = util::safe_ptr<IDXGIOutputDuplication, Release<IDXGIOutputDuplication>>;
|
using dup_t = util::safe_ptr<IDXGIOutputDuplication, Release<IDXGIOutputDuplication>>;
|
||||||
using texture2d_t = util::safe_ptr<ID3D11Texture2D, Release<ID3D11Texture2D>>;
|
using texture2d_t = util::safe_ptr<ID3D11Texture2D, Release<ID3D11Texture2D>>;
|
||||||
using texture1d_t = util::safe_ptr<ID3D11Texture1D, Release<ID3D11Texture1D>>;
|
using texture1d_t = util::safe_ptr<ID3D11Texture1D, Release<ID3D11Texture1D>>;
|
||||||
using resource_t = util::safe_ptr<IDXGIResource, Release<IDXGIResource>>;
|
using resource_t = util::safe_ptr<IDXGIResource, Release<IDXGIResource>>;
|
||||||
using multithread_t = util::safe_ptr<ID3D11Multithread, Release<ID3D11Multithread>>;
|
using multithread_t = util::safe_ptr<ID3D11Multithread, Release<ID3D11Multithread>>;
|
||||||
using vs_t = util::safe_ptr<ID3D11VertexShader, Release<ID3D11VertexShader>>;
|
using vs_t = util::safe_ptr<ID3D11VertexShader, Release<ID3D11VertexShader>>;
|
||||||
using ps_t = util::safe_ptr<ID3D11PixelShader, Release<ID3D11PixelShader>>;
|
using ps_t = util::safe_ptr<ID3D11PixelShader, Release<ID3D11PixelShader>>;
|
||||||
using blend_t = util::safe_ptr<ID3D11BlendState, Release<ID3D11BlendState>>;
|
using blend_t = util::safe_ptr<ID3D11BlendState, Release<ID3D11BlendState>>;
|
||||||
using input_layout_t = util::safe_ptr<ID3D11InputLayout, Release<ID3D11InputLayout>>;
|
using input_layout_t = util::safe_ptr<ID3D11InputLayout, Release<ID3D11InputLayout>>;
|
||||||
using render_target_t = util::safe_ptr<ID3D11RenderTargetView, Release<ID3D11RenderTargetView>>;
|
using render_target_t = util::safe_ptr<ID3D11RenderTargetView, Release<ID3D11RenderTargetView>>;
|
||||||
using shader_res_t = util::safe_ptr<ID3D11ShaderResourceView, Release<ID3D11ShaderResourceView>>;
|
using shader_res_t = util::safe_ptr<ID3D11ShaderResourceView, Release<ID3D11ShaderResourceView>>;
|
||||||
using buf_t = util::safe_ptr<ID3D11Buffer, Release<ID3D11Buffer>>;
|
using buf_t = util::safe_ptr<ID3D11Buffer, Release<ID3D11Buffer>>;
|
||||||
using raster_state_t = util::safe_ptr<ID3D11RasterizerState, Release<ID3D11RasterizerState>>;
|
using raster_state_t = util::safe_ptr<ID3D11RasterizerState, Release<ID3D11RasterizerState>>;
|
||||||
using sampler_state_t = util::safe_ptr<ID3D11SamplerState, Release<ID3D11SamplerState>>;
|
using sampler_state_t = util::safe_ptr<ID3D11SamplerState, Release<ID3D11SamplerState>>;
|
||||||
using blob_t = util::safe_ptr<ID3DBlob, Release<ID3DBlob>>;
|
using blob_t = util::safe_ptr<ID3DBlob, Release<ID3DBlob>>;
|
||||||
using depth_stencil_state_t = util::safe_ptr<ID3D11DepthStencilState, Release<ID3D11DepthStencilState>>;
|
using depth_stencil_state_t = util::safe_ptr<ID3D11DepthStencilState, Release<ID3D11DepthStencilState>>;
|
||||||
using depth_stencil_view_t = util::safe_ptr<ID3D11DepthStencilView, Release<ID3D11DepthStencilView>>;
|
using depth_stencil_view_t = util::safe_ptr<ID3D11DepthStencilView, Release<ID3D11DepthStencilView>>;
|
||||||
|
|
||||||
namespace video {
|
namespace video {
|
||||||
using device_t = util::safe_ptr<ID3D11VideoDevice, Release<ID3D11VideoDevice>>;
|
using device_t = util::safe_ptr<ID3D11VideoDevice, Release<ID3D11VideoDevice>>;
|
||||||
using ctx_t = util::safe_ptr<ID3D11VideoContext, Release<ID3D11VideoContext>>;
|
using ctx_t = util::safe_ptr<ID3D11VideoContext, Release<ID3D11VideoContext>>;
|
||||||
using processor_t = util::safe_ptr<ID3D11VideoProcessor, Release<ID3D11VideoProcessor>>;
|
using processor_t = util::safe_ptr<ID3D11VideoProcessor, Release<ID3D11VideoProcessor>>;
|
||||||
using processor_out_t = util::safe_ptr<ID3D11VideoProcessorOutputView, Release<ID3D11VideoProcessorOutputView>>;
|
using processor_out_t = util::safe_ptr<ID3D11VideoProcessorOutputView, Release<ID3D11VideoProcessorOutputView>>;
|
||||||
using processor_in_t = util::safe_ptr<ID3D11VideoProcessorInputView, Release<ID3D11VideoProcessorInputView>>;
|
using processor_in_t = util::safe_ptr<ID3D11VideoProcessorInputView, Release<ID3D11VideoProcessorInputView>>;
|
||||||
using processor_enum_t = util::safe_ptr<ID3D11VideoProcessorEnumerator, Release<ID3D11VideoProcessorEnumerator>>;
|
using processor_enum_t = util::safe_ptr<ID3D11VideoProcessorEnumerator, Release<ID3D11VideoProcessorEnumerator>>;
|
||||||
} // namespace video
|
} // namespace video
|
||||||
|
|
||||||
class hwdevice_t;
|
class hwdevice_t;
|
||||||
struct cursor_t {
|
struct cursor_t {
|
||||||
std::vector<std::uint8_t> img_data;
|
std::vector<std::uint8_t> img_data;
|
||||||
|
|
||||||
DXGI_OUTDUPL_POINTER_SHAPE_INFO shape_info;
|
DXGI_OUTDUPL_POINTER_SHAPE_INFO shape_info;
|
||||||
int x, y;
|
int x, y;
|
||||||
bool visible;
|
bool visible;
|
||||||
};
|
};
|
||||||
|
|
||||||
class gpu_cursor_t {
|
class gpu_cursor_t {
|
||||||
public:
|
public:
|
||||||
gpu_cursor_t() : cursor_view { 0, 0, 0, 0, 0.0f, 1.0f } {};
|
gpu_cursor_t() : cursor_view { 0, 0, 0, 0, 0.0f, 1.0f } {};
|
||||||
void set_pos(LONG rel_x, LONG rel_y, bool visible) {
|
void set_pos(LONG rel_x, LONG rel_y, bool visible) {
|
||||||
cursor_view.TopLeftX = rel_x;
|
cursor_view.TopLeftX = rel_x;
|
||||||
cursor_view.TopLeftY = rel_y;
|
cursor_view.TopLeftY = rel_y;
|
||||||
|
|
||||||
this->visible = visible;
|
this->visible = visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_texture(LONG width, LONG height, texture2d_t &&texture) {
|
void set_texture(LONG width, LONG height, texture2d_t &&texture) {
|
||||||
cursor_view.Width = width;
|
cursor_view.Width = width;
|
||||||
cursor_view.Height = height;
|
cursor_view.Height = height;
|
||||||
|
|
||||||
this->texture = std::move(texture);
|
this->texture = std::move(texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
texture2d_t texture;
|
texture2d_t texture;
|
||||||
shader_res_t input_res;
|
shader_res_t input_res;
|
||||||
|
|
||||||
D3D11_VIEWPORT cursor_view;
|
D3D11_VIEWPORT cursor_view;
|
||||||
|
|
||||||
bool visible;
|
bool visible;
|
||||||
};
|
};
|
||||||
|
|
||||||
class duplication_t {
|
class duplication_t {
|
||||||
public:
|
public:
|
||||||
dup_t dup;
|
dup_t dup;
|
||||||
bool has_frame {};
|
bool has_frame {};
|
||||||
bool use_dwmflush {};
|
bool use_dwmflush {};
|
||||||
|
|
||||||
capture_e next_frame(DXGI_OUTDUPL_FRAME_INFO &frame_info, std::chrono::milliseconds timeout, resource_t::pointer *res_p);
|
capture_e next_frame(DXGI_OUTDUPL_FRAME_INFO &frame_info, std::chrono::milliseconds timeout, resource_t::pointer *res_p);
|
||||||
capture_e reset(dup_t::pointer dup_p = dup_t::pointer());
|
capture_e reset(dup_t::pointer dup_p = dup_t::pointer());
|
||||||
capture_e release_frame();
|
capture_e release_frame();
|
||||||
|
|
||||||
~duplication_t();
|
~duplication_t();
|
||||||
};
|
};
|
||||||
|
|
||||||
class display_base_t : public display_t {
|
class display_base_t : public display_t {
|
||||||
public:
|
public:
|
||||||
int init(int framerate, const std::string &display_name);
|
int init(int framerate, const std::string &display_name);
|
||||||
|
|
||||||
std::chrono::nanoseconds delay;
|
std::chrono::nanoseconds delay;
|
||||||
|
|
||||||
factory1_t factory;
|
factory1_t factory;
|
||||||
adapter_t adapter;
|
adapter_t adapter;
|
||||||
output_t output;
|
output_t output;
|
||||||
device_t device;
|
device_t device;
|
||||||
device_ctx_t device_ctx;
|
device_ctx_t device_ctx;
|
||||||
duplication_t dup;
|
duplication_t dup;
|
||||||
|
|
||||||
DXGI_FORMAT format;
|
DXGI_FORMAT format;
|
||||||
D3D_FEATURE_LEVEL feature_level;
|
D3D_FEATURE_LEVEL feature_level;
|
||||||
|
|
||||||
typedef enum _D3DKMT_SCHEDULINGPRIORITYCLASS {
|
typedef enum _D3DKMT_SCHEDULINGPRIORITYCLASS {
|
||||||
D3DKMT_SCHEDULINGPRIORITYCLASS_IDLE,
|
D3DKMT_SCHEDULINGPRIORITYCLASS_IDLE,
|
||||||
D3DKMT_SCHEDULINGPRIORITYCLASS_BELOW_NORMAL,
|
D3DKMT_SCHEDULINGPRIORITYCLASS_BELOW_NORMAL,
|
||||||
D3DKMT_SCHEDULINGPRIORITYCLASS_NORMAL,
|
D3DKMT_SCHEDULINGPRIORITYCLASS_NORMAL,
|
||||||
D3DKMT_SCHEDULINGPRIORITYCLASS_ABOVE_NORMAL,
|
D3DKMT_SCHEDULINGPRIORITYCLASS_ABOVE_NORMAL,
|
||||||
D3DKMT_SCHEDULINGPRIORITYCLASS_HIGH,
|
D3DKMT_SCHEDULINGPRIORITYCLASS_HIGH,
|
||||||
D3DKMT_SCHEDULINGPRIORITYCLASS_REALTIME
|
D3DKMT_SCHEDULINGPRIORITYCLASS_REALTIME
|
||||||
} D3DKMT_SCHEDULINGPRIORITYCLASS;
|
} D3DKMT_SCHEDULINGPRIORITYCLASS;
|
||||||
|
|
||||||
typedef NTSTATUS WINAPI (*PD3DKMTSetProcessSchedulingPriorityClass)(HANDLE, D3DKMT_SCHEDULINGPRIORITYCLASS);
|
typedef NTSTATUS WINAPI (*PD3DKMTSetProcessSchedulingPriorityClass)(HANDLE, D3DKMT_SCHEDULINGPRIORITYCLASS);
|
||||||
};
|
};
|
||||||
|
|
||||||
class display_ram_t : public display_base_t {
|
class display_ram_t : public display_base_t {
|
||||||
public:
|
public:
|
||||||
capture_e capture(snapshot_cb_t &&snapshot_cb, std::shared_ptr<img_t> img, bool *cursor) override;
|
capture_e capture(snapshot_cb_t &&snapshot_cb, std::shared_ptr<img_t> img, bool *cursor) override;
|
||||||
capture_e snapshot(img_t *img, std::chrono::milliseconds timeout, bool cursor_visible);
|
capture_e snapshot(img_t *img, std::chrono::milliseconds timeout, bool cursor_visible);
|
||||||
|
|
||||||
|
|
||||||
std::shared_ptr<img_t> alloc_img() override;
|
std::shared_ptr<img_t> alloc_img() override;
|
||||||
int dummy_img(img_t *img) override;
|
int dummy_img(img_t *img) override;
|
||||||
|
|
||||||
int init(int framerate, const std::string &display_name);
|
int init(int framerate, const std::string &display_name);
|
||||||
|
|
||||||
cursor_t cursor;
|
cursor_t cursor;
|
||||||
D3D11_MAPPED_SUBRESOURCE img_info;
|
D3D11_MAPPED_SUBRESOURCE img_info;
|
||||||
texture2d_t texture;
|
texture2d_t texture;
|
||||||
};
|
};
|
||||||
|
|
||||||
class display_vram_t : public display_base_t, public std::enable_shared_from_this<display_vram_t> {
|
class display_vram_t : public display_base_t, public std::enable_shared_from_this<display_vram_t> {
|
||||||
public:
|
public:
|
||||||
capture_e capture(snapshot_cb_t &&snapshot_cb, std::shared_ptr<img_t> img, bool *cursor) override;
|
capture_e capture(snapshot_cb_t &&snapshot_cb, std::shared_ptr<img_t> img, bool *cursor) override;
|
||||||
capture_e snapshot(img_t *img, std::chrono::milliseconds timeout, bool cursor_visible);
|
capture_e snapshot(img_t *img, std::chrono::milliseconds timeout, bool cursor_visible);
|
||||||
|
|
||||||
std::shared_ptr<img_t> alloc_img() override;
|
std::shared_ptr<img_t> alloc_img() override;
|
||||||
int dummy_img(img_t *img_base) override;
|
int dummy_img(img_t *img_base) override;
|
||||||
|
|
||||||
int init(int framerate, const std::string &display_name);
|
int init(int framerate, const std::string &display_name);
|
||||||
|
|
||||||
std::shared_ptr<platf::hwdevice_t> make_hwdevice(pix_fmt_e pix_fmt) override;
|
std::shared_ptr<platf::hwdevice_t> make_hwdevice(pix_fmt_e pix_fmt) override;
|
||||||
|
|
||||||
sampler_state_t sampler_linear;
|
sampler_state_t sampler_linear;
|
||||||
|
|
||||||
blend_t blend_enable;
|
blend_t blend_enable;
|
||||||
blend_t blend_disable;
|
blend_t blend_disable;
|
||||||
|
|
||||||
ps_t scene_ps;
|
ps_t scene_ps;
|
||||||
vs_t scene_vs;
|
vs_t scene_vs;
|
||||||
|
|
||||||
texture2d_t src;
|
texture2d_t src;
|
||||||
gpu_cursor_t cursor;
|
gpu_cursor_t cursor;
|
||||||
};
|
};
|
||||||
} // namespace platf::dxgi
|
} // namespace platf::dxgi
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -7,9 +7,9 @@
|
||||||
|
|
||||||
#include "display.h"
|
#include "display.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "sunshine/config.h"
|
#include "src/config.h"
|
||||||
#include "sunshine/main.h"
|
#include "src/main.h"
|
||||||
#include "sunshine/platform/common.h"
|
#include "src/platform/common.h"
|
||||||
|
|
||||||
namespace platf {
|
namespace platf {
|
||||||
using namespace std::literals;
|
using namespace std::literals;
|
||||||
|
|
@ -1,327 +1,327 @@
|
||||||
#include "display.h"
|
#include "display.h"
|
||||||
#include "sunshine/main.h"
|
#include "src/main.h"
|
||||||
|
|
||||||
namespace platf {
|
namespace platf {
|
||||||
using namespace std::literals;
|
using namespace std::literals;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace platf::dxgi {
|
namespace platf::dxgi {
|
||||||
struct img_t : public ::platf::img_t {
|
struct img_t : public ::platf::img_t {
|
||||||
~img_t() override {
|
~img_t() override {
|
||||||
delete[] data;
|
delete[] data;
|
||||||
data = nullptr;
|
data = nullptr;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void blend_cursor_monochrome(const cursor_t &cursor, img_t &img) {
|
void blend_cursor_monochrome(const cursor_t &cursor, img_t &img) {
|
||||||
int height = cursor.shape_info.Height / 2;
|
int height = cursor.shape_info.Height / 2;
|
||||||
int width = cursor.shape_info.Width;
|
int width = cursor.shape_info.Width;
|
||||||
int pitch = cursor.shape_info.Pitch;
|
int pitch = cursor.shape_info.Pitch;
|
||||||
|
|
||||||
// img cursor.{x,y} < 0, skip parts of the cursor.img_data
|
// img cursor.{x,y} < 0, skip parts of the cursor.img_data
|
||||||
auto cursor_skip_y = -std::min(0, cursor.y);
|
auto cursor_skip_y = -std::min(0, cursor.y);
|
||||||
auto cursor_skip_x = -std::min(0, cursor.x);
|
auto cursor_skip_x = -std::min(0, cursor.x);
|
||||||
|
|
||||||
// img cursor.{x,y} > img.{x,y}, truncate parts of the cursor.img_data
|
// img cursor.{x,y} > img.{x,y}, truncate parts of the cursor.img_data
|
||||||
auto cursor_truncate_y = std::max(0, cursor.y - img.height);
|
auto cursor_truncate_y = std::max(0, cursor.y - img.height);
|
||||||
auto cursor_truncate_x = std::max(0, cursor.x - img.width);
|
auto cursor_truncate_x = std::max(0, cursor.x - img.width);
|
||||||
|
|
||||||
auto cursor_width = width - cursor_skip_x - cursor_truncate_x;
|
auto cursor_width = width - cursor_skip_x - cursor_truncate_x;
|
||||||
auto cursor_height = height - cursor_skip_y - cursor_truncate_y;
|
auto cursor_height = height - cursor_skip_y - cursor_truncate_y;
|
||||||
|
|
||||||
if(cursor_height > height || cursor_width > width) {
|
if(cursor_height > height || cursor_width > width) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto img_skip_y = std::max(0, cursor.y);
|
auto img_skip_y = std::max(0, cursor.y);
|
||||||
auto img_skip_x = std::max(0, cursor.x);
|
auto img_skip_x = std::max(0, cursor.x);
|
||||||
|
|
||||||
auto cursor_img_data = cursor.img_data.data() + cursor_skip_y * pitch;
|
auto cursor_img_data = cursor.img_data.data() + cursor_skip_y * pitch;
|
||||||
|
|
||||||
int delta_height = std::min(cursor_height - cursor_truncate_y, std::max(0, img.height - img_skip_y));
|
int delta_height = std::min(cursor_height - cursor_truncate_y, std::max(0, img.height - img_skip_y));
|
||||||
int delta_width = std::min(cursor_width - cursor_truncate_x, std::max(0, img.width - img_skip_x));
|
int delta_width = std::min(cursor_width - cursor_truncate_x, std::max(0, img.width - img_skip_x));
|
||||||
|
|
||||||
auto pixels_per_byte = width / pitch;
|
auto pixels_per_byte = width / pitch;
|
||||||
auto bytes_per_row = delta_width / pixels_per_byte;
|
auto bytes_per_row = delta_width / pixels_per_byte;
|
||||||
|
|
||||||
auto img_data = (int *)img.data;
|
auto img_data = (int *)img.data;
|
||||||
for(int i = 0; i < delta_height; ++i) {
|
for(int i = 0; i < delta_height; ++i) {
|
||||||
auto and_mask = &cursor_img_data[i * pitch];
|
auto and_mask = &cursor_img_data[i * pitch];
|
||||||
auto xor_mask = &cursor_img_data[(i + height) * pitch];
|
auto xor_mask = &cursor_img_data[(i + height) * pitch];
|
||||||
|
|
||||||
auto img_pixel_p = &img_data[(i + img_skip_y) * (img.row_pitch / img.pixel_pitch) + img_skip_x];
|
auto img_pixel_p = &img_data[(i + img_skip_y) * (img.row_pitch / img.pixel_pitch) + img_skip_x];
|
||||||
|
|
||||||
auto skip_x = cursor_skip_x;
|
auto skip_x = cursor_skip_x;
|
||||||
for(int x = 0; x < bytes_per_row; ++x) {
|
for(int x = 0; x < bytes_per_row; ++x) {
|
||||||
for(auto bit = 0u; bit < 8; ++bit) {
|
for(auto bit = 0u; bit < 8; ++bit) {
|
||||||
if(skip_x > 0) {
|
if(skip_x > 0) {
|
||||||
--skip_x;
|
--skip_x;
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
int and_ = *and_mask & (1 << (7 - bit)) ? -1 : 0;
|
int and_ = *and_mask & (1 << (7 - bit)) ? -1 : 0;
|
||||||
int xor_ = *xor_mask & (1 << (7 - bit)) ? -1 : 0;
|
int xor_ = *xor_mask & (1 << (7 - bit)) ? -1 : 0;
|
||||||
|
|
||||||
*img_pixel_p &= and_;
|
*img_pixel_p &= and_;
|
||||||
*img_pixel_p ^= xor_;
|
*img_pixel_p ^= xor_;
|
||||||
|
|
||||||
++img_pixel_p;
|
++img_pixel_p;
|
||||||
}
|
}
|
||||||
|
|
||||||
++and_mask;
|
++and_mask;
|
||||||
++xor_mask;
|
++xor_mask;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void apply_color_alpha(int *img_pixel_p, int cursor_pixel) {
|
void apply_color_alpha(int *img_pixel_p, int cursor_pixel) {
|
||||||
auto colors_out = (std::uint8_t *)&cursor_pixel;
|
auto colors_out = (std::uint8_t *)&cursor_pixel;
|
||||||
auto colors_in = (std::uint8_t *)img_pixel_p;
|
auto colors_in = (std::uint8_t *)img_pixel_p;
|
||||||
|
|
||||||
//TODO: When use of IDXGIOutput5 is implemented, support different color formats
|
//TODO: When use of IDXGIOutput5 is implemented, support different color formats
|
||||||
auto alpha = colors_out[3];
|
auto alpha = colors_out[3];
|
||||||
if(alpha == 255) {
|
if(alpha == 255) {
|
||||||
*img_pixel_p = cursor_pixel;
|
*img_pixel_p = cursor_pixel;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
colors_in[0] = colors_out[0] + (colors_in[0] * (255 - alpha) + 255 / 2) / 255;
|
colors_in[0] = colors_out[0] + (colors_in[0] * (255 - alpha) + 255 / 2) / 255;
|
||||||
colors_in[1] = colors_out[1] + (colors_in[1] * (255 - alpha) + 255 / 2) / 255;
|
colors_in[1] = colors_out[1] + (colors_in[1] * (255 - alpha) + 255 / 2) / 255;
|
||||||
colors_in[2] = colors_out[2] + (colors_in[2] * (255 - alpha) + 255 / 2) / 255;
|
colors_in[2] = colors_out[2] + (colors_in[2] * (255 - alpha) + 255 / 2) / 255;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void apply_color_masked(int *img_pixel_p, int cursor_pixel) {
|
void apply_color_masked(int *img_pixel_p, int cursor_pixel) {
|
||||||
//TODO: When use of IDXGIOutput5 is implemented, support different color formats
|
//TODO: When use of IDXGIOutput5 is implemented, support different color formats
|
||||||
auto alpha = ((std::uint8_t *)&cursor_pixel)[3];
|
auto alpha = ((std::uint8_t *)&cursor_pixel)[3];
|
||||||
if(alpha == 0xFF) {
|
if(alpha == 0xFF) {
|
||||||
*img_pixel_p ^= cursor_pixel;
|
*img_pixel_p ^= cursor_pixel;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
*img_pixel_p = cursor_pixel;
|
*img_pixel_p = cursor_pixel;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void blend_cursor_color(const cursor_t &cursor, img_t &img, const bool masked) {
|
void blend_cursor_color(const cursor_t &cursor, img_t &img, const bool masked) {
|
||||||
int height = cursor.shape_info.Height;
|
int height = cursor.shape_info.Height;
|
||||||
int width = cursor.shape_info.Width;
|
int width = cursor.shape_info.Width;
|
||||||
int pitch = cursor.shape_info.Pitch;
|
int pitch = cursor.shape_info.Pitch;
|
||||||
|
|
||||||
// img cursor.y < 0, skip parts of the cursor.img_data
|
// img cursor.y < 0, skip parts of the cursor.img_data
|
||||||
auto cursor_skip_y = -std::min(0, cursor.y);
|
auto cursor_skip_y = -std::min(0, cursor.y);
|
||||||
auto cursor_skip_x = -std::min(0, cursor.x);
|
auto cursor_skip_x = -std::min(0, cursor.x);
|
||||||
|
|
||||||
// img cursor.{x,y} > img.{x,y}, truncate parts of the cursor.img_data
|
// img cursor.{x,y} > img.{x,y}, truncate parts of the cursor.img_data
|
||||||
auto cursor_truncate_y = std::max(0, cursor.y - img.height);
|
auto cursor_truncate_y = std::max(0, cursor.y - img.height);
|
||||||
auto cursor_truncate_x = std::max(0, cursor.x - img.width);
|
auto cursor_truncate_x = std::max(0, cursor.x - img.width);
|
||||||
|
|
||||||
auto img_skip_y = std::max(0, cursor.y);
|
auto img_skip_y = std::max(0, cursor.y);
|
||||||
auto img_skip_x = std::max(0, cursor.x);
|
auto img_skip_x = std::max(0, cursor.x);
|
||||||
|
|
||||||
auto cursor_width = width - cursor_skip_x - cursor_truncate_x;
|
auto cursor_width = width - cursor_skip_x - cursor_truncate_x;
|
||||||
auto cursor_height = height - cursor_skip_y - cursor_truncate_y;
|
auto cursor_height = height - cursor_skip_y - cursor_truncate_y;
|
||||||
|
|
||||||
if(cursor_height > height || cursor_width > width) {
|
if(cursor_height > height || cursor_width > width) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto cursor_img_data = (int *)&cursor.img_data[cursor_skip_y * pitch];
|
auto cursor_img_data = (int *)&cursor.img_data[cursor_skip_y * pitch];
|
||||||
|
|
||||||
int delta_height = std::min(cursor_height - cursor_truncate_y, std::max(0, img.height - img_skip_y));
|
int delta_height = std::min(cursor_height - cursor_truncate_y, std::max(0, img.height - img_skip_y));
|
||||||
int delta_width = std::min(cursor_width - cursor_truncate_x, std::max(0, img.width - img_skip_x));
|
int delta_width = std::min(cursor_width - cursor_truncate_x, std::max(0, img.width - img_skip_x));
|
||||||
|
|
||||||
auto img_data = (int *)img.data;
|
auto img_data = (int *)img.data;
|
||||||
|
|
||||||
for(int i = 0; i < delta_height; ++i) {
|
for(int i = 0; i < delta_height; ++i) {
|
||||||
auto cursor_begin = &cursor_img_data[i * cursor.shape_info.Width + cursor_skip_x];
|
auto cursor_begin = &cursor_img_data[i * cursor.shape_info.Width + cursor_skip_x];
|
||||||
auto cursor_end = &cursor_begin[delta_width];
|
auto cursor_end = &cursor_begin[delta_width];
|
||||||
|
|
||||||
auto img_pixel_p = &img_data[(i + img_skip_y) * (img.row_pitch / img.pixel_pitch) + img_skip_x];
|
auto img_pixel_p = &img_data[(i + img_skip_y) * (img.row_pitch / img.pixel_pitch) + img_skip_x];
|
||||||
std::for_each(cursor_begin, cursor_end, [&](int cursor_pixel) {
|
std::for_each(cursor_begin, cursor_end, [&](int cursor_pixel) {
|
||||||
if(masked) {
|
if(masked) {
|
||||||
apply_color_masked(img_pixel_p, cursor_pixel);
|
apply_color_masked(img_pixel_p, cursor_pixel);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
apply_color_alpha(img_pixel_p, cursor_pixel);
|
apply_color_alpha(img_pixel_p, cursor_pixel);
|
||||||
}
|
}
|
||||||
++img_pixel_p;
|
++img_pixel_p;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void blend_cursor(const cursor_t &cursor, img_t &img) {
|
void blend_cursor(const cursor_t &cursor, img_t &img) {
|
||||||
switch(cursor.shape_info.Type) {
|
switch(cursor.shape_info.Type) {
|
||||||
case DXGI_OUTDUPL_POINTER_SHAPE_TYPE_COLOR:
|
case DXGI_OUTDUPL_POINTER_SHAPE_TYPE_COLOR:
|
||||||
blend_cursor_color(cursor, img, false);
|
blend_cursor_color(cursor, img, false);
|
||||||
break;
|
break;
|
||||||
case DXGI_OUTDUPL_POINTER_SHAPE_TYPE_MONOCHROME:
|
case DXGI_OUTDUPL_POINTER_SHAPE_TYPE_MONOCHROME:
|
||||||
blend_cursor_monochrome(cursor, img);
|
blend_cursor_monochrome(cursor, img);
|
||||||
break;
|
break;
|
||||||
case DXGI_OUTDUPL_POINTER_SHAPE_TYPE_MASKED_COLOR:
|
case DXGI_OUTDUPL_POINTER_SHAPE_TYPE_MASKED_COLOR:
|
||||||
blend_cursor_color(cursor, img, true);
|
blend_cursor_color(cursor, img, true);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
BOOST_LOG(warning) << "Unsupported cursor format ["sv << cursor.shape_info.Type << ']';
|
BOOST_LOG(warning) << "Unsupported cursor format ["sv << cursor.shape_info.Type << ']';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
capture_e display_ram_t::capture(snapshot_cb_t &&snapshot_cb, std::shared_ptr<::platf::img_t> img, bool *cursor) {
|
capture_e display_ram_t::capture(snapshot_cb_t &&snapshot_cb, std::shared_ptr<::platf::img_t> img, bool *cursor) {
|
||||||
auto next_frame = std::chrono::steady_clock::now();
|
auto next_frame = std::chrono::steady_clock::now();
|
||||||
|
|
||||||
while(img) {
|
while(img) {
|
||||||
auto now = std::chrono::steady_clock::now();
|
auto now = std::chrono::steady_clock::now();
|
||||||
while(next_frame > now) {
|
while(next_frame > now) {
|
||||||
now = std::chrono::steady_clock::now();
|
now = std::chrono::steady_clock::now();
|
||||||
}
|
}
|
||||||
next_frame = now + delay;
|
next_frame = now + delay;
|
||||||
|
|
||||||
auto status = snapshot(img.get(), 1000ms, *cursor);
|
auto status = snapshot(img.get(), 1000ms, *cursor);
|
||||||
switch(status) {
|
switch(status) {
|
||||||
case platf::capture_e::reinit:
|
case platf::capture_e::reinit:
|
||||||
case platf::capture_e::error:
|
case platf::capture_e::error:
|
||||||
return status;
|
return status;
|
||||||
case platf::capture_e::timeout:
|
case platf::capture_e::timeout:
|
||||||
std::this_thread::sleep_for(1ms);
|
std::this_thread::sleep_for(1ms);
|
||||||
continue;
|
continue;
|
||||||
case platf::capture_e::ok:
|
case platf::capture_e::ok:
|
||||||
img = snapshot_cb(img);
|
img = snapshot_cb(img);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
BOOST_LOG(error) << "Unrecognized capture status ["sv << (int)status << ']';
|
BOOST_LOG(error) << "Unrecognized capture status ["sv << (int)status << ']';
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return capture_e::ok;
|
return capture_e::ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
capture_e display_ram_t::snapshot(::platf::img_t *img_base, std::chrono::milliseconds timeout, bool cursor_visible) {
|
capture_e display_ram_t::snapshot(::platf::img_t *img_base, std::chrono::milliseconds timeout, bool cursor_visible) {
|
||||||
auto img = (img_t *)img_base;
|
auto img = (img_t *)img_base;
|
||||||
|
|
||||||
HRESULT status;
|
HRESULT status;
|
||||||
|
|
||||||
DXGI_OUTDUPL_FRAME_INFO frame_info;
|
DXGI_OUTDUPL_FRAME_INFO frame_info;
|
||||||
|
|
||||||
resource_t::pointer res_p {};
|
resource_t::pointer res_p {};
|
||||||
auto capture_status = dup.next_frame(frame_info, timeout, &res_p);
|
auto capture_status = dup.next_frame(frame_info, timeout, &res_p);
|
||||||
resource_t res { res_p };
|
resource_t res { res_p };
|
||||||
|
|
||||||
if(capture_status != capture_e::ok) {
|
if(capture_status != capture_e::ok) {
|
||||||
return capture_status;
|
return capture_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(frame_info.PointerShapeBufferSize > 0) {
|
if(frame_info.PointerShapeBufferSize > 0) {
|
||||||
auto &img_data = cursor.img_data;
|
auto &img_data = cursor.img_data;
|
||||||
|
|
||||||
img_data.resize(frame_info.PointerShapeBufferSize);
|
img_data.resize(frame_info.PointerShapeBufferSize);
|
||||||
|
|
||||||
UINT dummy;
|
UINT dummy;
|
||||||
status = dup.dup->GetFramePointerShape(img_data.size(), img_data.data(), &dummy, &cursor.shape_info);
|
status = dup.dup->GetFramePointerShape(img_data.size(), img_data.data(), &dummy, &cursor.shape_info);
|
||||||
if(FAILED(status)) {
|
if(FAILED(status)) {
|
||||||
BOOST_LOG(error) << "Failed to get new pointer shape [0x"sv << util::hex(status).to_string_view() << ']';
|
BOOST_LOG(error) << "Failed to get new pointer shape [0x"sv << util::hex(status).to_string_view() << ']';
|
||||||
|
|
||||||
return capture_e::error;
|
return capture_e::error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(frame_info.LastMouseUpdateTime.QuadPart) {
|
if(frame_info.LastMouseUpdateTime.QuadPart) {
|
||||||
cursor.x = frame_info.PointerPosition.Position.x;
|
cursor.x = frame_info.PointerPosition.Position.x;
|
||||||
cursor.y = frame_info.PointerPosition.Position.y;
|
cursor.y = frame_info.PointerPosition.Position.y;
|
||||||
cursor.visible = frame_info.PointerPosition.Visible;
|
cursor.visible = frame_info.PointerPosition.Visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If frame has been updated
|
// If frame has been updated
|
||||||
if(frame_info.LastPresentTime.QuadPart != 0) {
|
if(frame_info.LastPresentTime.QuadPart != 0) {
|
||||||
{
|
{
|
||||||
texture2d_t src {};
|
texture2d_t src {};
|
||||||
status = res->QueryInterface(IID_ID3D11Texture2D, (void **)&src);
|
status = res->QueryInterface(IID_ID3D11Texture2D, (void **)&src);
|
||||||
|
|
||||||
if(FAILED(status)) {
|
if(FAILED(status)) {
|
||||||
BOOST_LOG(error) << "Couldn't query interface [0x"sv << util::hex(status).to_string_view() << ']';
|
BOOST_LOG(error) << "Couldn't query interface [0x"sv << util::hex(status).to_string_view() << ']';
|
||||||
return capture_e::error;
|
return capture_e::error;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Copy from GPU to CPU
|
//Copy from GPU to CPU
|
||||||
device_ctx->CopyResource(texture.get(), src.get());
|
device_ctx->CopyResource(texture.get(), src.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
if(img_info.pData) {
|
if(img_info.pData) {
|
||||||
device_ctx->Unmap(texture.get(), 0);
|
device_ctx->Unmap(texture.get(), 0);
|
||||||
img_info.pData = nullptr;
|
img_info.pData = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = device_ctx->Map(texture.get(), 0, D3D11_MAP_READ, 0, &img_info);
|
status = device_ctx->Map(texture.get(), 0, D3D11_MAP_READ, 0, &img_info);
|
||||||
if(FAILED(status)) {
|
if(FAILED(status)) {
|
||||||
BOOST_LOG(error) << "Failed to map texture [0x"sv << util::hex(status).to_string_view() << ']';
|
BOOST_LOG(error) << "Failed to map texture [0x"sv << util::hex(status).to_string_view() << ']';
|
||||||
|
|
||||||
return capture_e::error;
|
return capture_e::error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool mouse_update =
|
const bool mouse_update =
|
||||||
(frame_info.LastMouseUpdateTime.QuadPart || frame_info.PointerShapeBufferSize > 0) &&
|
(frame_info.LastMouseUpdateTime.QuadPart || frame_info.PointerShapeBufferSize > 0) &&
|
||||||
(cursor_visible && cursor.visible);
|
(cursor_visible && cursor.visible);
|
||||||
|
|
||||||
const bool update_flag = frame_info.LastPresentTime.QuadPart != 0 || mouse_update;
|
const bool update_flag = frame_info.LastPresentTime.QuadPart != 0 || mouse_update;
|
||||||
|
|
||||||
if(!update_flag) {
|
if(!update_flag) {
|
||||||
return capture_e::timeout;
|
return capture_e::timeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::copy_n((std::uint8_t *)img_info.pData, height * img_info.RowPitch, (std::uint8_t *)img->data);
|
std::copy_n((std::uint8_t *)img_info.pData, height * img_info.RowPitch, (std::uint8_t *)img->data);
|
||||||
|
|
||||||
if(cursor_visible && cursor.visible) {
|
if(cursor_visible && cursor.visible) {
|
||||||
blend_cursor(cursor, *img);
|
blend_cursor(cursor, *img);
|
||||||
}
|
}
|
||||||
|
|
||||||
return capture_e::ok;
|
return capture_e::ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<platf::img_t> display_ram_t::alloc_img() {
|
std::shared_ptr<platf::img_t> display_ram_t::alloc_img() {
|
||||||
auto img = std::make_shared<img_t>();
|
auto img = std::make_shared<img_t>();
|
||||||
|
|
||||||
img->pixel_pitch = 4;
|
img->pixel_pitch = 4;
|
||||||
img->row_pitch = img_info.RowPitch;
|
img->row_pitch = img_info.RowPitch;
|
||||||
img->width = width;
|
img->width = width;
|
||||||
img->height = height;
|
img->height = height;
|
||||||
img->data = new std::uint8_t[img->row_pitch * height];
|
img->data = new std::uint8_t[img->row_pitch * height];
|
||||||
|
|
||||||
return img;
|
return img;
|
||||||
}
|
}
|
||||||
|
|
||||||
int display_ram_t::dummy_img(platf::img_t *img) {
|
int display_ram_t::dummy_img(platf::img_t *img) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int display_ram_t::init(int framerate, const std::string &display_name) {
|
int display_ram_t::init(int framerate, const std::string &display_name) {
|
||||||
if(display_base_t::init(framerate, display_name)) {
|
if(display_base_t::init(framerate, display_name)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
D3D11_TEXTURE2D_DESC t {};
|
D3D11_TEXTURE2D_DESC t {};
|
||||||
t.Width = width;
|
t.Width = width;
|
||||||
t.Height = height;
|
t.Height = height;
|
||||||
t.MipLevels = 1;
|
t.MipLevels = 1;
|
||||||
t.ArraySize = 1;
|
t.ArraySize = 1;
|
||||||
t.SampleDesc.Count = 1;
|
t.SampleDesc.Count = 1;
|
||||||
t.Usage = D3D11_USAGE_STAGING;
|
t.Usage = D3D11_USAGE_STAGING;
|
||||||
t.Format = format;
|
t.Format = format;
|
||||||
t.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
|
t.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
|
||||||
|
|
||||||
auto status = device->CreateTexture2D(&t, nullptr, &texture);
|
auto status = device->CreateTexture2D(&t, nullptr, &texture);
|
||||||
|
|
||||||
if(FAILED(status)) {
|
if(FAILED(status)) {
|
||||||
BOOST_LOG(error) << "Failed to create texture [0x"sv << util::hex(status).to_string_view() << ']';
|
BOOST_LOG(error) << "Failed to create texture [0x"sv << util::hex(status).to_string_view() << ']';
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// map the texture simply to get the pitch and stride
|
// map the texture simply to get the pitch and stride
|
||||||
status = device_ctx->Map(texture.get(), 0, D3D11_MAP_READ, 0, &img_info);
|
status = device_ctx->Map(texture.get(), 0, D3D11_MAP_READ, 0, &img_info);
|
||||||
if(FAILED(status)) {
|
if(FAILED(status)) {
|
||||||
BOOST_LOG(error) << "Failed to map the texture [0x"sv << util::hex(status).to_string_view() << ']';
|
BOOST_LOG(error) << "Failed to map the texture [0x"sv << util::hex(status).to_string_view() << ']';
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
} // namespace platf::dxgi
|
} // namespace platf::dxgi
|
||||||
File diff suppressed because it is too large
Load diff
6
sunshine/platform/windows/input.cpp → src/platform/windows/input.cpp
Executable file → Normal file
6
sunshine/platform/windows/input.cpp → src/platform/windows/input.cpp
Executable file → Normal file
|
|
@ -5,9 +5,9 @@
|
||||||
#include <ViGEm/Client.h>
|
#include <ViGEm/Client.h>
|
||||||
|
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "sunshine/config.h"
|
#include "src/config.h"
|
||||||
#include "sunshine/main.h"
|
#include "src/main.h"
|
||||||
#include "sunshine/platform/common.h"
|
#include "src/platform/common.h"
|
||||||
|
|
||||||
namespace platf {
|
namespace platf {
|
||||||
using namespace std::literals;
|
using namespace std::literals;
|
||||||
|
|
@ -1,123 +1,123 @@
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
|
|
||||||
// prevent clang format from "optimizing" the header include order
|
// prevent clang format from "optimizing" the header include order
|
||||||
// clang-format off
|
// clang-format off
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
#include <iphlpapi.h>
|
#include <iphlpapi.h>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <winuser.h>
|
#include <winuser.h>
|
||||||
#include <ws2tcpip.h>
|
#include <ws2tcpip.h>
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
#include "sunshine/main.h"
|
#include "src/main.h"
|
||||||
#include "sunshine/utility.h"
|
#include "src/utility.h"
|
||||||
|
|
||||||
using namespace std::literals;
|
using namespace std::literals;
|
||||||
namespace platf {
|
namespace platf {
|
||||||
using adapteraddrs_t = util::c_ptr<IP_ADAPTER_ADDRESSES>;
|
using adapteraddrs_t = util::c_ptr<IP_ADAPTER_ADDRESSES>;
|
||||||
|
|
||||||
std::filesystem::path appdata() {
|
std::filesystem::path appdata() {
|
||||||
return L"."sv;
|
return L"."sv;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string from_sockaddr(const sockaddr *const socket_address) {
|
std::string from_sockaddr(const sockaddr *const socket_address) {
|
||||||
char data[INET6_ADDRSTRLEN];
|
char data[INET6_ADDRSTRLEN];
|
||||||
|
|
||||||
auto family = socket_address->sa_family;
|
auto family = socket_address->sa_family;
|
||||||
if(family == AF_INET6) {
|
if(family == AF_INET6) {
|
||||||
inet_ntop(AF_INET6, &((sockaddr_in6 *)socket_address)->sin6_addr, data, INET6_ADDRSTRLEN);
|
inet_ntop(AF_INET6, &((sockaddr_in6 *)socket_address)->sin6_addr, data, INET6_ADDRSTRLEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(family == AF_INET) {
|
if(family == AF_INET) {
|
||||||
inet_ntop(AF_INET, &((sockaddr_in *)socket_address)->sin_addr, data, INET_ADDRSTRLEN);
|
inet_ntop(AF_INET, &((sockaddr_in *)socket_address)->sin_addr, data, INET_ADDRSTRLEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::string { data };
|
return std::string { data };
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<std::uint16_t, std::string> from_sockaddr_ex(const sockaddr *const ip_addr) {
|
std::pair<std::uint16_t, std::string> from_sockaddr_ex(const sockaddr *const ip_addr) {
|
||||||
char data[INET6_ADDRSTRLEN];
|
char data[INET6_ADDRSTRLEN];
|
||||||
|
|
||||||
auto family = ip_addr->sa_family;
|
auto family = ip_addr->sa_family;
|
||||||
std::uint16_t port;
|
std::uint16_t port;
|
||||||
if(family == AF_INET6) {
|
if(family == AF_INET6) {
|
||||||
inet_ntop(AF_INET6, &((sockaddr_in6 *)ip_addr)->sin6_addr, data, INET6_ADDRSTRLEN);
|
inet_ntop(AF_INET6, &((sockaddr_in6 *)ip_addr)->sin6_addr, data, INET6_ADDRSTRLEN);
|
||||||
port = ((sockaddr_in6 *)ip_addr)->sin6_port;
|
port = ((sockaddr_in6 *)ip_addr)->sin6_port;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(family == AF_INET) {
|
if(family == AF_INET) {
|
||||||
inet_ntop(AF_INET, &((sockaddr_in *)ip_addr)->sin_addr, data, INET_ADDRSTRLEN);
|
inet_ntop(AF_INET, &((sockaddr_in *)ip_addr)->sin_addr, data, INET_ADDRSTRLEN);
|
||||||
port = ((sockaddr_in *)ip_addr)->sin_port;
|
port = ((sockaddr_in *)ip_addr)->sin_port;
|
||||||
}
|
}
|
||||||
|
|
||||||
return { port, std::string { data } };
|
return { port, std::string { data } };
|
||||||
}
|
}
|
||||||
|
|
||||||
adapteraddrs_t get_adapteraddrs() {
|
adapteraddrs_t get_adapteraddrs() {
|
||||||
adapteraddrs_t info { nullptr };
|
adapteraddrs_t info { nullptr };
|
||||||
ULONG size = 0;
|
ULONG size = 0;
|
||||||
|
|
||||||
while(GetAdaptersAddresses(AF_UNSPEC, 0, nullptr, info.get(), &size) == ERROR_BUFFER_OVERFLOW) {
|
while(GetAdaptersAddresses(AF_UNSPEC, 0, nullptr, info.get(), &size) == ERROR_BUFFER_OVERFLOW) {
|
||||||
info.reset((PIP_ADAPTER_ADDRESSES)malloc(size));
|
info.reset((PIP_ADAPTER_ADDRESSES)malloc(size));
|
||||||
}
|
}
|
||||||
|
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string get_mac_address(const std::string_view &address) {
|
std::string get_mac_address(const std::string_view &address) {
|
||||||
adapteraddrs_t info = get_adapteraddrs();
|
adapteraddrs_t info = get_adapteraddrs();
|
||||||
for(auto adapter_pos = info.get(); adapter_pos != nullptr; adapter_pos = adapter_pos->Next) {
|
for(auto adapter_pos = info.get(); adapter_pos != nullptr; adapter_pos = adapter_pos->Next) {
|
||||||
for(auto addr_pos = adapter_pos->FirstUnicastAddress; addr_pos != nullptr; addr_pos = addr_pos->Next) {
|
for(auto addr_pos = adapter_pos->FirstUnicastAddress; addr_pos != nullptr; addr_pos = addr_pos->Next) {
|
||||||
if(adapter_pos->PhysicalAddressLength != 0 && address == from_sockaddr(addr_pos->Address.lpSockaddr)) {
|
if(adapter_pos->PhysicalAddressLength != 0 && address == from_sockaddr(addr_pos->Address.lpSockaddr)) {
|
||||||
std::stringstream mac_addr;
|
std::stringstream mac_addr;
|
||||||
mac_addr << std::hex;
|
mac_addr << std::hex;
|
||||||
for(int i = 0; i < adapter_pos->PhysicalAddressLength; i++) {
|
for(int i = 0; i < adapter_pos->PhysicalAddressLength; i++) {
|
||||||
if(i > 0) {
|
if(i > 0) {
|
||||||
mac_addr << ':';
|
mac_addr << ':';
|
||||||
}
|
}
|
||||||
mac_addr << std::setw(2) << std::setfill('0') << (int)adapter_pos->PhysicalAddress[i];
|
mac_addr << std::setw(2) << std::setfill('0') << (int)adapter_pos->PhysicalAddress[i];
|
||||||
}
|
}
|
||||||
return mac_addr.str();
|
return mac_addr.str();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BOOST_LOG(warning) << "Unable to find MAC address for "sv << address;
|
BOOST_LOG(warning) << "Unable to find MAC address for "sv << address;
|
||||||
return "00:00:00:00:00:00"s;
|
return "00:00:00:00:00:00"s;
|
||||||
}
|
}
|
||||||
|
|
||||||
HDESK syncThreadDesktop() {
|
HDESK syncThreadDesktop() {
|
||||||
auto hDesk = OpenInputDesktop(DF_ALLOWOTHERACCOUNTHOOK, FALSE, GENERIC_ALL);
|
auto hDesk = OpenInputDesktop(DF_ALLOWOTHERACCOUNTHOOK, FALSE, GENERIC_ALL);
|
||||||
if(!hDesk) {
|
if(!hDesk) {
|
||||||
auto err = GetLastError();
|
auto err = GetLastError();
|
||||||
BOOST_LOG(error) << "Failed to Open Input Desktop [0x"sv << util::hex(err).to_string_view() << ']';
|
BOOST_LOG(error) << "Failed to Open Input Desktop [0x"sv << util::hex(err).to_string_view() << ']';
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!SetThreadDesktop(hDesk)) {
|
if(!SetThreadDesktop(hDesk)) {
|
||||||
auto err = GetLastError();
|
auto err = GetLastError();
|
||||||
BOOST_LOG(error) << "Failed to sync desktop to thread [0x"sv << util::hex(err).to_string_view() << ']';
|
BOOST_LOG(error) << "Failed to sync desktop to thread [0x"sv << util::hex(err).to_string_view() << ']';
|
||||||
}
|
}
|
||||||
|
|
||||||
CloseDesktop(hDesk);
|
CloseDesktop(hDesk);
|
||||||
|
|
||||||
return hDesk;
|
return hDesk;
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_status(const std::string_view &prefix, HRESULT status) {
|
void print_status(const std::string_view &prefix, HRESULT status) {
|
||||||
char err_string[1024];
|
char err_string[1024];
|
||||||
|
|
||||||
DWORD bytes = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
DWORD bytes = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||||
nullptr,
|
nullptr,
|
||||||
status,
|
status,
|
||||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||||
err_string,
|
err_string,
|
||||||
sizeof(err_string),
|
sizeof(err_string),
|
||||||
nullptr);
|
nullptr);
|
||||||
|
|
||||||
BOOST_LOG(error) << prefix << ": "sv << std::string_view { err_string, bytes };
|
BOOST_LOG(error) << prefix << ": "sv << std::string_view { err_string, bytes };
|
||||||
}
|
}
|
||||||
} // namespace platf
|
} // namespace platf
|
||||||
|
|
@ -1,13 +1,13 @@
|
||||||
#ifndef SUNSHINE_WINDOWS_MISC_H
|
#ifndef SUNSHINE_WINDOWS_MISC_H
|
||||||
#define SUNSHINE_WINDOWS_MISC_H
|
#define SUNSHINE_WINDOWS_MISC_H
|
||||||
|
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <winnt.h>
|
#include <winnt.h>
|
||||||
|
|
||||||
namespace platf {
|
namespace platf {
|
||||||
void print_status(const std::string_view &prefix, HRESULT status);
|
void print_status(const std::string_view &prefix, HRESULT status);
|
||||||
HDESK syncThreadDesktop();
|
HDESK syncThreadDesktop();
|
||||||
} // namespace platf
|
} // namespace platf
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -1,195 +1,195 @@
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
#include <windns.h>
|
#include <windns.h>
|
||||||
#include <winerror.h>
|
#include <winerror.h>
|
||||||
|
|
||||||
#include <boost/asio/ip/host_name.hpp>
|
#include <boost/asio/ip/host_name.hpp>
|
||||||
|
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "sunshine/config.h"
|
#include "src/config.h"
|
||||||
#include "sunshine/main.h"
|
#include "src/main.h"
|
||||||
#include "sunshine/network.h"
|
#include "src/network.h"
|
||||||
#include "sunshine/nvhttp.h"
|
#include "src/nvhttp.h"
|
||||||
#include "sunshine/platform/common.h"
|
#include "src/platform/common.h"
|
||||||
#include "sunshine/thread_safe.h"
|
#include "src/thread_safe.h"
|
||||||
|
|
||||||
#define _FN(x, ret, args) \
|
#define _FN(x, ret, args) \
|
||||||
typedef ret(*x##_fn) args; \
|
typedef ret(*x##_fn) args; \
|
||||||
static x##_fn x
|
static x##_fn x
|
||||||
|
|
||||||
using namespace std::literals;
|
using namespace std::literals;
|
||||||
|
|
||||||
#define __SV(quote) L##quote##sv
|
#define __SV(quote) L##quote##sv
|
||||||
#define SV(quote) __SV(quote)
|
#define SV(quote) __SV(quote)
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#ifndef __MINGW32__
|
#ifndef __MINGW32__
|
||||||
constexpr auto DNS_REQUEST_PENDING = 9506L;
|
constexpr auto DNS_REQUEST_PENDING = 9506L;
|
||||||
constexpr auto DNS_QUERY_REQUEST_VERSION1 = 0x1;
|
constexpr auto DNS_QUERY_REQUEST_VERSION1 = 0x1;
|
||||||
constexpr auto DNS_QUERY_RESULTS_VERSION1 = 0x1;
|
constexpr auto DNS_QUERY_RESULTS_VERSION1 = 0x1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define SERVICE_DOMAIN "local"
|
#define SERVICE_DOMAIN "local"
|
||||||
|
|
||||||
constexpr auto SERVICE_INSTANCE_NAME = SV(SERVICE_NAME "." SERVICE_TYPE "." SERVICE_DOMAIN);
|
constexpr auto SERVICE_INSTANCE_NAME = SV(SERVICE_NAME "." SERVICE_TYPE "." SERVICE_DOMAIN);
|
||||||
constexpr auto SERVICE_TYPE_DOMAIN = SV(SERVICE_TYPE "." SERVICE_DOMAIN);
|
constexpr auto SERVICE_TYPE_DOMAIN = SV(SERVICE_TYPE "." SERVICE_DOMAIN);
|
||||||
|
|
||||||
#ifndef __MINGW32__
|
#ifndef __MINGW32__
|
||||||
typedef struct _DNS_SERVICE_INSTANCE {
|
typedef struct _DNS_SERVICE_INSTANCE {
|
||||||
LPWSTR pszInstanceName;
|
LPWSTR pszInstanceName;
|
||||||
LPWSTR pszHostName;
|
LPWSTR pszHostName;
|
||||||
|
|
||||||
IP4_ADDRESS *ip4Address;
|
IP4_ADDRESS *ip4Address;
|
||||||
IP6_ADDRESS *ip6Address;
|
IP6_ADDRESS *ip6Address;
|
||||||
|
|
||||||
WORD wPort;
|
WORD wPort;
|
||||||
WORD wPriority;
|
WORD wPriority;
|
||||||
WORD wWeight;
|
WORD wWeight;
|
||||||
|
|
||||||
// Property list
|
// Property list
|
||||||
DWORD dwPropertyCount;
|
DWORD dwPropertyCount;
|
||||||
|
|
||||||
PWSTR *keys;
|
PWSTR *keys;
|
||||||
PWSTR *values;
|
PWSTR *values;
|
||||||
|
|
||||||
DWORD dwInterfaceIndex;
|
DWORD dwInterfaceIndex;
|
||||||
} DNS_SERVICE_INSTANCE, *PDNS_SERVICE_INSTANCE;
|
} DNS_SERVICE_INSTANCE, *PDNS_SERVICE_INSTANCE;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef VOID WINAPI DNS_SERVICE_REGISTER_COMPLETE(
|
typedef VOID WINAPI DNS_SERVICE_REGISTER_COMPLETE(
|
||||||
_In_ DWORD Status,
|
_In_ DWORD Status,
|
||||||
_In_ PVOID pQueryContext,
|
_In_ PVOID pQueryContext,
|
||||||
_In_ PDNS_SERVICE_INSTANCE pInstance);
|
_In_ PDNS_SERVICE_INSTANCE pInstance);
|
||||||
|
|
||||||
typedef DNS_SERVICE_REGISTER_COMPLETE *PDNS_SERVICE_REGISTER_COMPLETE;
|
typedef DNS_SERVICE_REGISTER_COMPLETE *PDNS_SERVICE_REGISTER_COMPLETE;
|
||||||
|
|
||||||
#ifndef __MINGW32__
|
#ifndef __MINGW32__
|
||||||
typedef struct _DNS_SERVICE_CANCEL {
|
typedef struct _DNS_SERVICE_CANCEL {
|
||||||
PVOID reserved;
|
PVOID reserved;
|
||||||
} DNS_SERVICE_CANCEL, *PDNS_SERVICE_CANCEL;
|
} DNS_SERVICE_CANCEL, *PDNS_SERVICE_CANCEL;
|
||||||
|
|
||||||
typedef struct _DNS_SERVICE_REGISTER_REQUEST {
|
typedef struct _DNS_SERVICE_REGISTER_REQUEST {
|
||||||
ULONG Version;
|
ULONG Version;
|
||||||
ULONG InterfaceIndex;
|
ULONG InterfaceIndex;
|
||||||
PDNS_SERVICE_INSTANCE pServiceInstance;
|
PDNS_SERVICE_INSTANCE pServiceInstance;
|
||||||
PDNS_SERVICE_REGISTER_COMPLETE pRegisterCompletionCallback;
|
PDNS_SERVICE_REGISTER_COMPLETE pRegisterCompletionCallback;
|
||||||
PVOID pQueryContext;
|
PVOID pQueryContext;
|
||||||
HANDLE hCredentials;
|
HANDLE hCredentials;
|
||||||
BOOL unicastEnabled;
|
BOOL unicastEnabled;
|
||||||
} DNS_SERVICE_REGISTER_REQUEST, *PDNS_SERVICE_REGISTER_REQUEST;
|
} DNS_SERVICE_REGISTER_REQUEST, *PDNS_SERVICE_REGISTER_REQUEST;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
_FN(_DnsServiceFreeInstance, VOID, (_In_ PDNS_SERVICE_INSTANCE pInstance));
|
_FN(_DnsServiceFreeInstance, VOID, (_In_ PDNS_SERVICE_INSTANCE pInstance));
|
||||||
_FN(_DnsServiceDeRegister, DWORD, (_In_ PDNS_SERVICE_REGISTER_REQUEST pRequest, _Inout_opt_ PDNS_SERVICE_CANCEL pCancel));
|
_FN(_DnsServiceDeRegister, DWORD, (_In_ PDNS_SERVICE_REGISTER_REQUEST pRequest, _Inout_opt_ PDNS_SERVICE_CANCEL pCancel));
|
||||||
_FN(_DnsServiceRegister, DWORD, (_In_ PDNS_SERVICE_REGISTER_REQUEST pRequest, _Inout_opt_ PDNS_SERVICE_CANCEL pCancel));
|
_FN(_DnsServiceRegister, DWORD, (_In_ PDNS_SERVICE_REGISTER_REQUEST pRequest, _Inout_opt_ PDNS_SERVICE_CANCEL pCancel));
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
|
|
||||||
namespace platf::publish {
|
namespace platf::publish {
|
||||||
VOID WINAPI register_cb(DWORD status, PVOID pQueryContext, PDNS_SERVICE_INSTANCE pInstance) {
|
VOID WINAPI register_cb(DWORD status, PVOID pQueryContext, PDNS_SERVICE_INSTANCE pInstance) {
|
||||||
auto alarm = (safe::alarm_t<DNS_STATUS>::element_type *)pQueryContext;
|
auto alarm = (safe::alarm_t<DNS_STATUS>::element_type *)pQueryContext;
|
||||||
|
|
||||||
auto fg = util::fail_guard([&]() {
|
auto fg = util::fail_guard([&]() {
|
||||||
if(pInstance) {
|
if(pInstance) {
|
||||||
_DnsServiceFreeInstance(pInstance);
|
_DnsServiceFreeInstance(pInstance);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if(status) {
|
if(status) {
|
||||||
print_status("register_cb()"sv, status);
|
print_status("register_cb()"sv, status);
|
||||||
alarm->ring(-1);
|
alarm->ring(-1);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
alarm->ring(0);
|
alarm->ring(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int service(bool enable) {
|
static int service(bool enable) {
|
||||||
auto alarm = safe::make_alarm<DNS_STATUS>();
|
auto alarm = safe::make_alarm<DNS_STATUS>();
|
||||||
|
|
||||||
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t> converter;
|
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t> converter;
|
||||||
|
|
||||||
std::wstring name { SERVICE_INSTANCE_NAME.data(), SERVICE_INSTANCE_NAME.size() };
|
std::wstring name { SERVICE_INSTANCE_NAME.data(), SERVICE_INSTANCE_NAME.size() };
|
||||||
std::wstring domain { SERVICE_TYPE_DOMAIN.data(), SERVICE_TYPE_DOMAIN.size() };
|
std::wstring domain { SERVICE_TYPE_DOMAIN.data(), SERVICE_TYPE_DOMAIN.size() };
|
||||||
|
|
||||||
auto host = converter.from_bytes(boost::asio::ip::host_name() + ".local");
|
auto host = converter.from_bytes(boost::asio::ip::host_name() + ".local");
|
||||||
|
|
||||||
DNS_SERVICE_INSTANCE instance {};
|
DNS_SERVICE_INSTANCE instance {};
|
||||||
instance.pszInstanceName = name.data();
|
instance.pszInstanceName = name.data();
|
||||||
instance.wPort = map_port(nvhttp::PORT_HTTP);
|
instance.wPort = map_port(nvhttp::PORT_HTTP);
|
||||||
instance.pszHostName = host.data();
|
instance.pszHostName = host.data();
|
||||||
|
|
||||||
DNS_SERVICE_REGISTER_REQUEST req {};
|
DNS_SERVICE_REGISTER_REQUEST req {};
|
||||||
req.Version = DNS_QUERY_REQUEST_VERSION1;
|
req.Version = DNS_QUERY_REQUEST_VERSION1;
|
||||||
req.pQueryContext = alarm.get();
|
req.pQueryContext = alarm.get();
|
||||||
req.pServiceInstance = &instance;
|
req.pServiceInstance = &instance;
|
||||||
req.pRegisterCompletionCallback = register_cb;
|
req.pRegisterCompletionCallback = register_cb;
|
||||||
|
|
||||||
DNS_STATUS status {};
|
DNS_STATUS status {};
|
||||||
|
|
||||||
if(enable) {
|
if(enable) {
|
||||||
status = _DnsServiceRegister(&req, nullptr);
|
status = _DnsServiceRegister(&req, nullptr);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
status = _DnsServiceDeRegister(&req, nullptr);
|
status = _DnsServiceDeRegister(&req, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
alarm->wait();
|
alarm->wait();
|
||||||
|
|
||||||
status = *alarm->status();
|
status = *alarm->status();
|
||||||
if(status) {
|
if(status) {
|
||||||
BOOST_LOG(error) << "No mDNS service"sv;
|
BOOST_LOG(error) << "No mDNS service"sv;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
class deinit_t : public ::platf::deinit_t {
|
class deinit_t : public ::platf::deinit_t {
|
||||||
public:
|
public:
|
||||||
~deinit_t() override {
|
~deinit_t() override {
|
||||||
if(service(false)) {
|
if(service(false)) {
|
||||||
std::abort();
|
std::abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_LOG(info) << "Unregistered Sunshine Gamestream service"sv;
|
BOOST_LOG(info) << "Unregistered Sunshine Gamestream service"sv;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
int load_funcs(HMODULE handle) {
|
int load_funcs(HMODULE handle) {
|
||||||
auto fg = util::fail_guard([handle]() {
|
auto fg = util::fail_guard([handle]() {
|
||||||
FreeLibrary(handle);
|
FreeLibrary(handle);
|
||||||
});
|
});
|
||||||
|
|
||||||
_DnsServiceFreeInstance = (_DnsServiceFreeInstance_fn)GetProcAddress(handle, "DnsServiceFreeInstance");
|
_DnsServiceFreeInstance = (_DnsServiceFreeInstance_fn)GetProcAddress(handle, "DnsServiceFreeInstance");
|
||||||
_DnsServiceDeRegister = (_DnsServiceDeRegister_fn)GetProcAddress(handle, "DnsServiceDeRegister");
|
_DnsServiceDeRegister = (_DnsServiceDeRegister_fn)GetProcAddress(handle, "DnsServiceDeRegister");
|
||||||
_DnsServiceRegister = (_DnsServiceRegister_fn)GetProcAddress(handle, "DnsServiceRegister");
|
_DnsServiceRegister = (_DnsServiceRegister_fn)GetProcAddress(handle, "DnsServiceRegister");
|
||||||
|
|
||||||
if(!(_DnsServiceFreeInstance && _DnsServiceDeRegister && _DnsServiceRegister)) {
|
if(!(_DnsServiceFreeInstance && _DnsServiceDeRegister && _DnsServiceRegister)) {
|
||||||
BOOST_LOG(error) << "mDNS service not available in dnsapi.dll"sv;
|
BOOST_LOG(error) << "mDNS service not available in dnsapi.dll"sv;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
fg.disable();
|
fg.disable();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<::platf::deinit_t> start() {
|
std::unique_ptr<::platf::deinit_t> start() {
|
||||||
HMODULE handle = LoadLibrary("dnsapi.dll");
|
HMODULE handle = LoadLibrary("dnsapi.dll");
|
||||||
|
|
||||||
if(!handle || load_funcs(handle)) {
|
if(!handle || load_funcs(handle)) {
|
||||||
BOOST_LOG(error) << "Couldn't load dnsapi.dll, You'll need to add PC manually from Moonlight"sv;
|
BOOST_LOG(error) << "Couldn't load dnsapi.dll, You'll need to add PC manually from Moonlight"sv;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(service(true)) {
|
if(service(true)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_LOG(info) << "Registered Sunshine Gamestream service"sv;
|
BOOST_LOG(info) << "Registered Sunshine Gamestream service"sv;
|
||||||
|
|
||||||
return std::make_unique<deinit_t>();
|
return std::make_unique<deinit_t>();
|
||||||
}
|
}
|
||||||
} // namespace platf::publish
|
} // namespace platf::publish
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include "sunshine/utility.h"
|
#include "src/utility.h"
|
||||||
|
|
||||||
DEFINE_PROPERTYKEY(PKEY_Device_DeviceDesc, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 2); // DEVPROP_TYPE_STRING
|
DEFINE_PROPERTYKEY(PKEY_Device_DeviceDesc, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 2); // DEVPROP_TYPE_STRING
|
||||||
DEFINE_PROPERTYKEY(PKEY_Device_FriendlyName, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 14); // DEVPROP_TYPE_STRING
|
DEFINE_PROPERTYKEY(PKEY_Device_FriendlyName, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 14); // DEVPROP_TYPE_STRING
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include "sunshine/utility.h"
|
#include "src/utility.h"
|
||||||
|
|
||||||
using namespace std::literals;
|
using namespace std::literals;
|
||||||
namespace dxgi {
|
namespace dxgi {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue