initial windows stuff
This commit is contained in:
parent
269122d30c
commit
22348bd469
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -21,3 +21,4 @@ config.toml
|
||||||
draconis++
|
draconis++
|
||||||
Makefile
|
Makefile
|
||||||
result
|
result
|
||||||
|
/include/
|
||||||
|
|
0
meson-vcpkg.txt
Normal file
0
meson-vcpkg.txt
Normal file
91
meson.build
91
meson.build
|
@ -1,9 +1,7 @@
|
||||||
project(
|
project(
|
||||||
'draconis++', 'cpp',
|
'draconis++', 'cpp',
|
||||||
version: '0.1.0',
|
version : '0.1.0',
|
||||||
default_options: [
|
default_options : [
|
||||||
'objc_std=c++20',
|
|
||||||
'objcpp_std=c++20',
|
|
||||||
'cpp_std=c++20',
|
'cpp_std=c++20',
|
||||||
'default_library=static',
|
'default_library=static',
|
||||||
'warning_level=everything',
|
'warning_level=everything',
|
||||||
|
@ -11,17 +9,11 @@ project(
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
clangtidy = find_program('clang-tidy', required: false)
|
|
||||||
|
|
||||||
cpp = meson.get_compiler('cpp')
|
cpp = meson.get_compiler('cpp')
|
||||||
|
|
||||||
if host_machine.system() == 'darwin'
|
add_project_arguments(
|
||||||
add_languages('objcpp')
|
cpp.get_supported_arguments(
|
||||||
|
[
|
||||||
objcpp = meson.get_compiler('objcpp')
|
|
||||||
|
|
||||||
add_project_arguments(
|
|
||||||
objcpp.get_supported_arguments([
|
|
||||||
'-Wno-c++20-compat',
|
'-Wno-c++20-compat',
|
||||||
'-Wno-c++20-extensions',
|
'-Wno-c++20-extensions',
|
||||||
'-Wno-c++98-compat',
|
'-Wno-c++98-compat',
|
||||||
|
@ -32,79 +24,36 @@ if host_machine.system() == 'darwin'
|
||||||
'-Wno-pre-c++20-compat-pedantic',
|
'-Wno-pre-c++20-compat-pedantic',
|
||||||
'-Wno-switch-default',
|
'-Wno-switch-default',
|
||||||
'-Wunused-function',
|
'-Wunused-function',
|
||||||
]),
|
]
|
||||||
language: 'objcpp'
|
),
|
||||||
)
|
language : 'cpp'
|
||||||
endif
|
|
||||||
|
|
||||||
add_project_arguments(
|
|
||||||
cpp.get_supported_arguments([
|
|
||||||
'-Wno-c++20-compat',
|
|
||||||
'-Wno-c++20-extensions',
|
|
||||||
'-Wno-c++98-compat',
|
|
||||||
'-Wno-c++98-compat-pedantic',
|
|
||||||
'-Wno-disabled-macro-expansion',
|
|
||||||
'-Wno-missing-prototypes',
|
|
||||||
'-Wno-padded',
|
|
||||||
'-Wno-pre-c++20-compat-pedantic',
|
|
||||||
'-Wno-switch-default',
|
|
||||||
'-Wunused-function',
|
|
||||||
]),
|
|
||||||
language: 'cpp'
|
|
||||||
)
|
)
|
||||||
|
|
||||||
source_file_names = [
|
source_file_names = [
|
||||||
'src/main.cpp',
|
'src/main.cpp',
|
||||||
'src/config/config.cpp',
|
'src/config/config.cpp',
|
||||||
'src/config/weather.cpp'
|
'src/config/weather.cpp',
|
||||||
|
'src/os/windows.cpp'
|
||||||
]
|
]
|
||||||
|
|
||||||
if host_machine.system() == 'linux'
|
|
||||||
source_file_names += ['src/os/linux.cpp']
|
|
||||||
endif
|
|
||||||
|
|
||||||
if host_machine.system() == 'darwin'
|
|
||||||
source_file_names += [
|
|
||||||
'src/os/macos.cpp',
|
|
||||||
'src/os/macos/bridge.mm',
|
|
||||||
]
|
|
||||||
endif
|
|
||||||
|
|
||||||
sources = []
|
sources = []
|
||||||
|
|
||||||
foreach file : source_file_names
|
foreach file : source_file_names
|
||||||
sources += files(file)
|
sources += files(file)
|
||||||
endforeach
|
endforeach
|
||||||
|
|
||||||
|
windows_sdk_lib_dir = 'C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64'
|
||||||
|
link_args = ['-L' + windows_sdk_lib_dir, '-lwindowsapp', '-lcurl']
|
||||||
|
|
||||||
deps = []
|
deps = []
|
||||||
|
|
||||||
deps += dependency('fmt')
|
deps += dependency('fmt', static : true)
|
||||||
deps += dependency('libcurl')
|
deps += dependency('libcurl', static : true)
|
||||||
deps += dependency('tomlplusplus')
|
deps += dependency('tomlplusplus', static : true)
|
||||||
deps += cpp.find_library('yyjson')
|
deps += dependency('yyjson', static : true)
|
||||||
deps += cpp.find_library('reflectcpp')
|
|
||||||
|
|
||||||
if host_machine.system() == 'darwin'
|
|
||||||
deps += dependency('Foundation')
|
|
||||||
deps += dependency('MediaPlayer')
|
|
||||||
endif
|
|
||||||
|
|
||||||
if host_machine.system() == 'linux'
|
|
||||||
deps += cpp.find_library('sdbus-c++')
|
|
||||||
endif
|
|
||||||
|
|
||||||
objc_args = []
|
|
||||||
link_args = []
|
|
||||||
|
|
||||||
if host_machine.system() == 'darwin'
|
|
||||||
objc_args += ['-fobjc-arc']
|
|
||||||
link_args += ['-framework', 'Foundation', '-framework', 'MediaPlayer']
|
|
||||||
endif
|
|
||||||
|
|
||||||
executable(
|
executable(
|
||||||
'draconis++',
|
'draconis++',
|
||||||
sources,
|
sources,
|
||||||
objc_args: objc_args,
|
dependencies : deps,
|
||||||
link_args: link_args,
|
link_args : link_args
|
||||||
dependencies: deps
|
)
|
||||||
)
|
|
|
@ -8,7 +8,13 @@
|
||||||
|
|
||||||
// Function to read cache from file
|
// Function to read cache from file
|
||||||
fn ReadCacheFromFile() -> Result<WeatherOutput> {
|
fn ReadCacheFromFile() -> Result<WeatherOutput> {
|
||||||
|
#ifdef __WIN32__
|
||||||
|
const char* tempPath = getenv("TEMP");
|
||||||
|
const string path = string(tempPath) + "\\weather_cache.json";
|
||||||
|
std::ifstream ifs(path);
|
||||||
|
#else
|
||||||
std::ifstream ifs("/tmp/weather_cache.json");
|
std::ifstream ifs("/tmp/weather_cache.json");
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!ifs.is_open())
|
if (!ifs.is_open())
|
||||||
return Error("Cache file not found.");
|
return Error("Cache file not found.");
|
||||||
|
@ -34,7 +40,13 @@ fn ReadCacheFromFile() -> Result<WeatherOutput> {
|
||||||
fn WriteCacheToFile(const WeatherOutput& data) -> Result<> {
|
fn WriteCacheToFile(const WeatherOutput& data) -> Result<> {
|
||||||
fmt::println("Writing to cache file...");
|
fmt::println("Writing to cache file...");
|
||||||
|
|
||||||
|
#ifdef __WIN32__
|
||||||
|
const char* tempPath = getenv("TEMP");
|
||||||
|
const string path = string(tempPath) + "\\weather_cache.json";
|
||||||
|
std::ofstream ofs(path);
|
||||||
|
#else
|
||||||
std::ofstream ofs("/tmp/weather_cache.json");
|
std::ofstream ofs("/tmp/weather_cache.json");
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!ofs.is_open())
|
if (!ofs.is_open())
|
||||||
return Error("Failed to open cache file for writing.");
|
return Error("Failed to open cache file for writing.");
|
||||||
|
|
23
src/main.cpp
23
src/main.cpp
|
@ -60,12 +60,26 @@ fn main() -> i32 {
|
||||||
future<string> dateFuture = std::async(std::launch::async, GetDate);
|
future<string> dateFuture = std::async(std::launch::async, GetDate);
|
||||||
future<u64> memInfoFuture = std::async(std::launch::async, GetMemInfo);
|
future<u64> memInfoFuture = std::async(std::launch::async, GetMemInfo);
|
||||||
|
|
||||||
const WeatherOutput json = weatherFuture.get();
|
const auto
|
||||||
const i64 temp = std::lround(json.main.temp);
|
[clouds,
|
||||||
const string townName = json.name;
|
timezone,
|
||||||
|
visibility,
|
||||||
|
main,
|
||||||
|
coords,
|
||||||
|
rain,
|
||||||
|
snow,
|
||||||
|
base,
|
||||||
|
townName,
|
||||||
|
weather,
|
||||||
|
sys,
|
||||||
|
cod,
|
||||||
|
dt,
|
||||||
|
id,
|
||||||
|
wind] = weatherFuture.get();
|
||||||
|
const i64 temp = std::lround(main.temp);
|
||||||
|
|
||||||
const bool nowPlayingEnabled = nowPlayingEnabledFuture.get();
|
const bool nowPlayingEnabled = nowPlayingEnabledFuture.get();
|
||||||
const char* version = osVersionFuture.get();
|
const string version = osVersionFuture.get();
|
||||||
const string date = dateFuture.get();
|
const string date = dateFuture.get();
|
||||||
const string name = config.general.get().name.get();
|
const string name = config.general.get().name.get();
|
||||||
const u64 mem = memInfoFuture.get();
|
const u64 mem = memInfoFuture.get();
|
||||||
|
@ -79,6 +93,5 @@ fn main() -> i32 {
|
||||||
if (nowPlayingEnabled)
|
if (nowPlayingEnabled)
|
||||||
fmt::println("{}", GetNowPlaying());
|
fmt::println("{}", GetNowPlaying());
|
||||||
|
|
||||||
delete[] version;
|
|
||||||
delete &config;
|
delete &config;
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,12 +39,12 @@ fn MeminfoParse(std::ifstream input) -> u64 {
|
||||||
|
|
||||||
fn GetMemInfo() -> u64 { return MeminfoParse(std::ifstream("/proc/meminfo")) * 1024; }
|
fn GetMemInfo() -> u64 { return MeminfoParse(std::ifstream("/proc/meminfo")) * 1024; }
|
||||||
|
|
||||||
fn GetOSVersion() -> const char* {
|
fn GetOSVersion() -> string {
|
||||||
std::ifstream file("/etc/os-release");
|
std::ifstream file("/etc/os-release");
|
||||||
|
|
||||||
if (!file.is_open()) {
|
if (!file.is_open()) {
|
||||||
std::cerr << "Failed to open /etc/os-release" << std::endl;
|
std::cerr << "Failed to open /etc/os-release" << std::endl;
|
||||||
return nullptr;
|
return ""; // Return empty string indicating failure
|
||||||
}
|
}
|
||||||
|
|
||||||
string line;
|
string line;
|
||||||
|
@ -58,15 +58,11 @@ fn GetOSVersion() -> const char* {
|
||||||
if (!prettyName.empty() && prettyName.front() == '"' && prettyName.back() == '"')
|
if (!prettyName.empty() && prettyName.front() == '"' && prettyName.back() == '"')
|
||||||
prettyName = prettyName.substr(1, prettyName.size() - 2);
|
prettyName = prettyName.substr(1, prettyName.size() - 2);
|
||||||
|
|
||||||
// Allocate memory for the C-string and copy the content
|
return prettyName;
|
||||||
char* cstr = new char[prettyName.size() + 1];
|
|
||||||
std::strcpy(cstr, prettyName.c_str());
|
|
||||||
|
|
||||||
return cstr;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nullptr;
|
return ""; // Return empty string if PRETTY_NAME= line not found
|
||||||
}
|
}
|
||||||
|
|
||||||
fn GetMprisPlayers(sdbus::IConnection& connection) -> std::vector<string> {
|
fn GetMprisPlayers(sdbus::IConnection& connection) -> std::vector<string> {
|
||||||
|
|
|
@ -16,4 +16,4 @@ fn GetNowPlaying() -> string;
|
||||||
/**
|
/**
|
||||||
* @brief Get the OS version.
|
* @brief Get the OS version.
|
||||||
*/
|
*/
|
||||||
fn GetOSVersion() -> const char*;
|
fn GetOSVersion() -> string;
|
||||||
|
|
107
src/os/windows.cpp
Normal file
107
src/os/windows.cpp
Normal file
|
@ -0,0 +1,107 @@
|
||||||
|
#include <windows.h>
|
||||||
|
#include <winrt/Windows.Foundation.h> // ReSharper disable once CppUnusedIncludeDirective
|
||||||
|
#include <winrt/Windows.Media.Control.h>
|
||||||
|
#include <winrt/base.h>
|
||||||
|
#include <winrt/impl/Windows.Media.Control.2.h>
|
||||||
|
|
||||||
|
#include "os.h"
|
||||||
|
|
||||||
|
fn GetMemInfo()->u64 {
|
||||||
|
u64 mem = 0;
|
||||||
|
GetPhysicallyInstalledSystemMemory(&mem);
|
||||||
|
return mem * 1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn GetNowPlaying()->string {
|
||||||
|
using namespace winrt::Windows::Media::Control;
|
||||||
|
using namespace winrt::Windows::Foundation;
|
||||||
|
|
||||||
|
using MediaProperties = GlobalSystemMediaTransportControlsSessionMediaProperties;
|
||||||
|
using Session = GlobalSystemMediaTransportControlsSession;
|
||||||
|
using SessionManager = GlobalSystemMediaTransportControlsSessionManager;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Request the session manager asynchronously
|
||||||
|
const IAsyncOperation<SessionManager> sessionManagerOp = SessionManager::RequestAsync();
|
||||||
|
const SessionManager sessionManager = sessionManagerOp.get();
|
||||||
|
|
||||||
|
if (const Session currentSession = sessionManager.GetCurrentSession()) {
|
||||||
|
// Try to get the media properties asynchronously
|
||||||
|
const IAsyncOperation<MediaProperties> mediaPropertiesOp =
|
||||||
|
currentSession.TryGetMediaPropertiesAsync();
|
||||||
|
const MediaProperties mediaProperties = mediaPropertiesOp.get();
|
||||||
|
|
||||||
|
// Convert the hstring title to string
|
||||||
|
return to_string(mediaProperties.Title());
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we reach this point, there is no current session
|
||||||
|
return "No current media session.";
|
||||||
|
} catch (...) { return "Failed to get media properties."; }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn GetRegistryValue(const HKEY& hKey, const string& subKey, const string& valueName)->string {
|
||||||
|
HKEY key = nullptr;
|
||||||
|
if (RegOpenKeyExA(hKey, subKey.c_str(), 0, KEY_READ, &key) != ERROR_SUCCESS)
|
||||||
|
return "";
|
||||||
|
|
||||||
|
DWORD dataSize = 0;
|
||||||
|
if (RegQueryValueExA(key, valueName.c_str(), nullptr, nullptr, nullptr, &dataSize) != ERROR_SUCCESS) {
|
||||||
|
RegCloseKey(key);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
string value(dataSize, '\0');
|
||||||
|
if (RegQueryValueExA(
|
||||||
|
key,
|
||||||
|
valueName.c_str(),
|
||||||
|
nullptr,
|
||||||
|
nullptr,
|
||||||
|
reinterpret_cast<LPBYTE>(value.data()), // NOLINT(*-reinterpret-cast)
|
||||||
|
&dataSize
|
||||||
|
) != ERROR_SUCCESS) {
|
||||||
|
RegCloseKey(key);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
RegCloseKey(key);
|
||||||
|
// Remove null terminator if present
|
||||||
|
if (!value.empty() && value.back() == '\0')
|
||||||
|
value.pop_back();
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn GetOSVersion()->string {
|
||||||
|
string productName = GetRegistryValue(
|
||||||
|
HKEY_LOCAL_MACHINE, R"(SOFTWARE\Microsoft\Windows NT\CurrentVersion)", "ProductName"
|
||||||
|
);
|
||||||
|
|
||||||
|
const string displayVersion = GetRegistryValue(
|
||||||
|
HKEY_LOCAL_MACHINE, R"(SOFTWARE\Microsoft\Windows NT\CurrentVersion)", "DisplayVersion"
|
||||||
|
);
|
||||||
|
|
||||||
|
const string releaseId = GetRegistryValue(
|
||||||
|
HKEY_LOCAL_MACHINE, R"(SOFTWARE\Microsoft\Windows NT\CurrentVersion)", "ReleaseId"
|
||||||
|
);
|
||||||
|
|
||||||
|
// Check for Windows 11
|
||||||
|
if (const i32 buildNumber = stoi(GetRegistryValue(
|
||||||
|
HKEY_LOCAL_MACHINE, R"(SOFTWARE\Microsoft\Windows NT\CurrentVersion)", "CurrentBuildNumber"
|
||||||
|
));
|
||||||
|
buildNumber >= 22000 && productName.find("Windows 10") != string::npos)
|
||||||
|
productName.replace(productName.find("Windows 10"), 10, "Windows 11");
|
||||||
|
|
||||||
|
if (!productName.empty()) {
|
||||||
|
string result = productName;
|
||||||
|
|
||||||
|
if (!displayVersion.empty())
|
||||||
|
result += " " + displayVersion;
|
||||||
|
else if (!releaseId.empty())
|
||||||
|
result += " " + releaseId;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
Loading…
Reference in a new issue