mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-09-12 10:22:12 +02:00
Media (Windows): finalize Windows support
This commit is contained in:
@@ -460,7 +460,7 @@ jobs:
|
||||
with:
|
||||
msystem: CLANG64
|
||||
update: true
|
||||
install: git mingw-w64-clang-x86_64-7zip mingw-w64-clang-x86_64-cmake mingw-w64-clang-x86_64-clang mingw-w64-clang-x86_64-vulkan-loader mingw-w64-clang-x86_64-vulkan-headers mingw-w64-clang-x86_64-opencl-icd
|
||||
install: git mingw-w64-clang-x86_64-7zip mingw-w64-clang-x86_64-cmake mingw-w64-clang-x86_64-clang mingw-w64-clang-x86_64-vulkan-loader mingw-w64-clang-x86_64-vulkan-headers mingw-w64-clang-x86_64-opencl-icd mingw-w64-clang-x86_64-cppwinrt
|
||||
|
||||
- name: print msys version
|
||||
run: uname -a
|
||||
@@ -522,7 +522,7 @@ jobs:
|
||||
with:
|
||||
msystem: CLANG32
|
||||
update: true
|
||||
install: git p7zip mingw-w64-clang-i686-cmake mingw-w64-clang-i686-clang mingw-w64-clang-i686-vulkan-loader mingw-w64-clang-i686-vulkan-headers mingw-w64-clang-i686-opencl-icd
|
||||
install: git p7zip mingw-w64-clang-i686-cmake mingw-w64-clang-i686-clang mingw-w64-clang-i686-vulkan-loader mingw-w64-clang-i686-vulkan-headers mingw-w64-clang-i686-opencl-icd mingw-w64-clang-i686-cppwinrt
|
||||
|
||||
- name: print msys version
|
||||
run: uname -a
|
||||
|
||||
+40
-39
@@ -115,14 +115,9 @@ set(WARNING_FLAGS "-Wall -Wextra -Wconversion -Werror=uninitialized -Werror=retu
|
||||
set(CMAKE_C_STANDARD 11)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WARNING_FLAGS} -Werror=incompatible-pointer-types -Werror=implicit-function-declaration -Werror=int-conversion")
|
||||
|
||||
if(WIN32)
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
elseif(ENABLE_DIRECTX_HEADERS)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
endif()
|
||||
|
||||
if(WIN32 OR ENABLE_DIRECTX_HEADERS)
|
||||
enable_language(CXX)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WARNING_FLAGS} -fno-exceptions -fno-rtti")
|
||||
endif()
|
||||
|
||||
@@ -700,7 +695,7 @@ elseif(WIN32)
|
||||
src/detection/locale/locale_windows.c
|
||||
src/detection/localip/localip_windows.c
|
||||
src/detection/gamepad/gamepad_windows.c
|
||||
src/detection/media/media_windows.cpp
|
||||
src/detection/media/media_windows.c
|
||||
src/detection/memory/memory_windows.c
|
||||
src/detection/physicalmemory/physicalmemory_linux.c
|
||||
src/detection/monitor/monitor_windows.c
|
||||
@@ -1040,7 +1035,6 @@ elseif(WIN32)
|
||||
PRIVATE "setupapi"
|
||||
PRIVATE "hid"
|
||||
PRIVATE "wtsapi32"
|
||||
PRIVATE "RuntimeObject"
|
||||
)
|
||||
elseif(BSD)
|
||||
target_link_libraries(libfastfetch
|
||||
@@ -1073,6 +1067,39 @@ target_link_libraries(libfastfetch
|
||||
PRIVATE ${CMAKE_DL_LIBS}
|
||||
)
|
||||
|
||||
if(WIN32)
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
include(CheckIncludeFileCXX)
|
||||
CHECK_INCLUDE_FILE_CXX("winrt/Windows.Media.Control.h" HAVE_WINRT)
|
||||
if(HAVE_WINRT)
|
||||
add_library(ffwinrt SHARED src/detection/media/media_windows.dll.cpp)
|
||||
target_link_libraries(ffwinrt PRIVATE "RuntimeObject")
|
||||
|
||||
include(CheckCXXSymbolExists)
|
||||
if(cxx_std_20 IN_LIST CMAKE_CXX_COMPILE_FEATURES)
|
||||
set(header version)
|
||||
else()
|
||||
set(header ciso646)
|
||||
endif()
|
||||
|
||||
check_cxx_symbol_exists(_LIBCPP_VERSION ${header} LIBCPP)
|
||||
if(LIBCPP)
|
||||
target_link_libraries(ffwinrt
|
||||
PRIVATE "libc++.a"
|
||||
)
|
||||
endif()
|
||||
|
||||
check_cxx_symbol_exists(__GLIBCXX__ ${header} GLIBCXX)
|
||||
if(GLIBCXX)
|
||||
target_link_libraries(ffwinrt
|
||||
PRIVATE "libstdc++.a"
|
||||
)
|
||||
endif()
|
||||
else()
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
######################
|
||||
# Executable targets #
|
||||
######################
|
||||
@@ -1097,34 +1124,11 @@ target_link_libraries(flashfetch
|
||||
PRIVATE libfastfetch
|
||||
)
|
||||
|
||||
if(NOT WIN32)
|
||||
# Prevent fastfetch from linking to libstdc++
|
||||
set(CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "")
|
||||
set(CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES "")
|
||||
set_target_properties(fastfetch PROPERTIES LINKER_LANGUAGE C)
|
||||
set_target_properties(flashfetch PROPERTIES LINKER_LANGUAGE C)
|
||||
else()
|
||||
include(CheckCXXSymbolExists)
|
||||
if(cxx_std_20 IN_LIST CMAKE_CXX_COMPILE_FEATURES)
|
||||
set(header version)
|
||||
else()
|
||||
set(header ciso646)
|
||||
endif()
|
||||
|
||||
check_cxx_symbol_exists(_LIBCPP_VERSION ${header} LIBCPP)
|
||||
if(LIBCPP)
|
||||
target_link_libraries(libfastfetch
|
||||
PRIVATE "libc++.a"
|
||||
)
|
||||
endif()
|
||||
|
||||
check_cxx_symbol_exists(__GLIBCXX__ ${header} GLIBCXX)
|
||||
if(GLIBCXX)
|
||||
target_link_libraries(libfastfetch
|
||||
PRIVATE "libstdc++.a"
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
# Prevent fastfetch from linking to libstdc++
|
||||
set(CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "")
|
||||
set(CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES "")
|
||||
set_target_properties(fastfetch PROPERTIES LINKER_LANGUAGE C)
|
||||
set_target_properties(flashfetch PROPERTIES LINKER_LANGUAGE C)
|
||||
|
||||
if(yyjson_FOUND)
|
||||
target_compile_definitions(fastfetch PRIVATE FF_USE_SYSTEM_YYJSON)
|
||||
@@ -1134,12 +1138,9 @@ if(yyjson_FOUND)
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
set(TARGET_NAME fastfetch)
|
||||
target_sources(fastfetch
|
||||
PRIVATE src/util/windows/version.rc
|
||||
)
|
||||
|
||||
set(TARGET_NAME flashfetch)
|
||||
target_sources(flashfetch
|
||||
PRIVATE src/util/windows/version.rc
|
||||
)
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
#include "common/library.h"
|
||||
#include "util/windows/unicode.h"
|
||||
#include "media.h"
|
||||
#include "media_windows.dll.h"
|
||||
|
||||
static const char* getMedia(FFMediaResult* media)
|
||||
{
|
||||
FF_LIBRARY_LOAD(libffwinrt, NULL, "dlopen libffwinrt" FF_LIBRARY_EXTENSION " failed", "libffwinrt" FF_LIBRARY_EXTENSION, 0)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libffwinrt, ffWinrtDetectMedia)
|
||||
libffwinrt = NULL; // Don't close libffwinrt or it may crash
|
||||
|
||||
FFWinrtMediaResult result = {};
|
||||
|
||||
const char* error = ffffWinrtDetectMedia(&result);
|
||||
if (error)
|
||||
{
|
||||
ffStrbufSetStatic(&media->error, error);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ffStrbufSetWS(&media->playerId, result.playerId);
|
||||
ffStrbufSet(&media->player, &media->playerId);
|
||||
if (ffStrbufEndsWithIgnCaseS(&media->player, ".exe"))
|
||||
ffStrbufSubstrBefore(&media->player, media->player.length - 4);
|
||||
else
|
||||
ffStrbufSubstrAfterFirstC(&media->player, '!'); // UWP ID
|
||||
ffStrbufSetWS(&media->song, result.song);
|
||||
ffStrbufSetWS(&media->artist, result.artist);
|
||||
ffStrbufSetWS(&media->album, result.album);
|
||||
ffStrbufSetStatic(&media->status, result.status);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void ffDetectMediaImpl(FFMediaResult* media)
|
||||
{
|
||||
const char* error = getMedia(media);
|
||||
ffStrbufAppendS(&media->error, error);
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
extern "C"
|
||||
{
|
||||
#include "media.h"
|
||||
#include "util/windows/unicode.h"
|
||||
}
|
||||
|
||||
#include <winrt/Windows.Foundation.h>
|
||||
#include <winrt/windows.Media.Control.h>
|
||||
#include <winrt/Windows.Media.Playback.h>
|
||||
|
||||
extern "C"
|
||||
{
|
||||
static const char* getMedia(FFMediaResult* media)
|
||||
{
|
||||
using namespace winrt::Windows::Media::Control;
|
||||
auto manager = GlobalSystemMediaTransportControlsSessionManager::RequestAsync().get();
|
||||
if (!manager)
|
||||
return "GlobalSystemMediaTransportControlsSessionManager::RequestAsync() failed";
|
||||
|
||||
auto session = manager.GetCurrentSession();
|
||||
if (!session)
|
||||
return "GetCurrentSession() failed";
|
||||
|
||||
auto mediaProps = session
|
||||
.TryGetMediaPropertiesAsync()
|
||||
.get();
|
||||
if (!mediaProps)
|
||||
return "TryGetMediaPropertiesAsync() failed";
|
||||
|
||||
if (auto playbackInfo = session.GetPlaybackInfo())
|
||||
{
|
||||
switch (playbackInfo.PlaybackStatus())
|
||||
{
|
||||
#define FF_MEDIA_SET_STATUS(status_code) \
|
||||
case GlobalSystemMediaTransportControlsSessionPlaybackStatus::status_code: ffStrbufSetStatic(&media->status, #status_code); break
|
||||
FF_MEDIA_SET_STATUS(Closed);
|
||||
FF_MEDIA_SET_STATUS(Opened);
|
||||
FF_MEDIA_SET_STATUS(Changing);
|
||||
FF_MEDIA_SET_STATUS(Stopped);
|
||||
FF_MEDIA_SET_STATUS(Playing);
|
||||
FF_MEDIA_SET_STATUS(Paused);
|
||||
#undef FF_MEDIA_SET_STATUS
|
||||
}
|
||||
}
|
||||
|
||||
ffStrbufSetNWS(&media->playerId, session.SourceAppUserModelId().size(), session.SourceAppUserModelId().data());
|
||||
ffStrbufSet(&media->player, &media->playerId);
|
||||
if (ffStrbufEndsWithIgnCaseS(&media->player, ".exe"))
|
||||
ffStrbufSubstrBefore(&media->player, media->player.length - 4);
|
||||
else
|
||||
ffStrbufSubstrAfterFirstC(&media->player, '!'); // UWP ID
|
||||
|
||||
ffStrbufSetNWS(&media->song, mediaProps.Title().size(), mediaProps.Title().data());
|
||||
ffStrbufSetNWS(&media->artist, mediaProps.Artist().size(), mediaProps.Artist().data());
|
||||
ffStrbufSetNWS(&media->album, mediaProps.AlbumTitle().size(), mediaProps.AlbumTitle().data());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void ffDetectMediaImpl(FFMediaResult* media)
|
||||
{
|
||||
const char* error = getMedia(media);
|
||||
ffStrbufAppendS(&media->error, error);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
#include <winrt/Windows.Foundation.h>
|
||||
#include <winrt/Windows.Media.Control.h>
|
||||
#include <wchar.h>
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "media_windows.dll.h"
|
||||
|
||||
const char* ffWinrtDetectMedia(FFWinrtMediaResult* result)
|
||||
{
|
||||
// C++/WinRT requires Windows 8.1 or later and C++ runtime (std::string and other stuff)
|
||||
// Make it a separate dll in order not to break Windows 7 support
|
||||
using namespace winrt::Windows::Media::Control;
|
||||
|
||||
auto manager = GlobalSystemMediaTransportControlsSessionManager::RequestAsync().get();
|
||||
if (!manager)
|
||||
return "winrt: GlobalSystemMediaTransportControlsSessionManager::RequestAsync() failed";
|
||||
|
||||
auto session = manager.GetCurrentSession();
|
||||
if (!session)
|
||||
return "winrt: GetCurrentSession() failed";
|
||||
|
||||
auto mediaProps = session
|
||||
.TryGetMediaPropertiesAsync()
|
||||
.get();
|
||||
if (!mediaProps)
|
||||
return "winrt: TryGetMediaPropertiesAsync() failed";
|
||||
|
||||
if (auto playbackInfo = session.GetPlaybackInfo())
|
||||
{
|
||||
switch (playbackInfo.PlaybackStatus())
|
||||
{
|
||||
#define FF_MEDIA_SET_STATUS(status_code) \
|
||||
case GlobalSystemMediaTransportControlsSessionPlaybackStatus::status_code: result->status = #status_code; break
|
||||
FF_MEDIA_SET_STATUS(Closed);
|
||||
FF_MEDIA_SET_STATUS(Opened);
|
||||
FF_MEDIA_SET_STATUS(Changing);
|
||||
FF_MEDIA_SET_STATUS(Stopped);
|
||||
FF_MEDIA_SET_STATUS(Playing);
|
||||
FF_MEDIA_SET_STATUS(Paused);
|
||||
#undef FF_MEDIA_SET_STATUS
|
||||
}
|
||||
}
|
||||
|
||||
::wcsncpy(result->playerId, session.SourceAppUserModelId().data(), FF_MEDIA_WIN_RESULT_BUFLEN);
|
||||
::wcsncpy(result->song, mediaProps.Title().data(), FF_MEDIA_WIN_RESULT_BUFLEN);
|
||||
::wcsncpy(result->artist, mediaProps.Artist().data(), FF_MEDIA_WIN_RESULT_BUFLEN);
|
||||
::wcsncpy(result->album, mediaProps.AlbumTitle().data(), FF_MEDIA_WIN_RESULT_BUFLEN);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#define FF_MEDIA_WIN_RESULT_BUFLEN 256
|
||||
|
||||
typedef struct FFWinrtMediaResult
|
||||
{
|
||||
wchar_t playerId[FF_MEDIA_WIN_RESULT_BUFLEN];
|
||||
wchar_t song[FF_MEDIA_WIN_RESULT_BUFLEN];
|
||||
wchar_t artist[FF_MEDIA_WIN_RESULT_BUFLEN];
|
||||
wchar_t album[FF_MEDIA_WIN_RESULT_BUFLEN];
|
||||
const char* status;
|
||||
} FFWinrtMediaResult;
|
||||
|
||||
__attribute__((__dllexport__))
|
||||
const char* ffWinrtDetectMedia(FFWinrtMediaResult* result);
|
||||
Reference in New Issue
Block a user