Extract Windows platform services

This commit is contained in:
2026-06-03 04:20:14 +02:00
parent ead7f58285
commit 6369c3c969
7 changed files with 244 additions and 220 deletions

View File

@@ -5,11 +5,11 @@
#include "texture.h"
#include "image.h"
#include "app.h"
#include "platform_api/platform_services.h"
#include "canvas.h"
#include "keymap.h"
#include "hmd.h"
#include "renderer_gl/opengl_capabilities.h"
#include "platform_windows/windows_platform_services.h"
#include "../resource.h"
#include <shellscalingapi.h>
@@ -244,212 +244,6 @@ void win32_update_fps(int frames)
PostMessage(hWnd, WM_USER_WAKEUP, 0, 0);
}
void win32_show_cursor(bool visible)
{
std::lock_guard<std::mutex> lock(main_task_mutex);
main_tasklist.emplace_back([=] {
if (visible)
while (ShowCursor(true) < 0);
else
while (ShowCursor(false) >= 0);
});
}
std::string win32_clipboard_get_text()
{
std::string ret;
if (OpenClipboard(hWnd))
{
if (HANDLE h = GetClipboardData(CF_TEXT))
{
if (char* s = (char*)GlobalLock(h))
{
ret = s;
GlobalUnlock(h);
}
}
CloseClipboard();
}
return ret;
}
bool win32_clipboard_set_text(const std::string& s)
{
bool success = false;
if (OpenClipboard(hWnd))
{
// owned by SetClipboardData
if (HGLOBAL h = GlobalAlloc(GMEM_MOVEABLE, s.size() + 1))
{
if (char* p = (char*)GlobalLock(h))
{
std::copy(s.begin(), s.end(), p);
p[s.size()] = 0; // string null-termination
GlobalUnlock(h);
success = true;
}
EmptyClipboard();
SetClipboardData(CF_TEXT, h);
}
CloseClipboard();
}
return success;
}
std::string win32_open_file(const char* filter)
{
OPENFILENAMEA ofn;
char fileName[MAX_PATH] = "";
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = hWnd;
ofn.lpstrFilter = filter;
ofn.lpstrFile = fileName;
ofn.nMaxFile = MAX_PATH;
ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_NOCHANGEDIR;
ofn.lpstrDefExt = "";
ofn.lpstrInitialDir = "";
if (GetOpenFileNameA(&ofn) != NULL)
{
return fileName;
}
return "";
}
std::string win32_save_file(const char* filter)
{
OPENFILENAMEA ofn;
char fileName[MAX_PATH] = "";
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = hWnd;
ofn.lpstrFilter = filter;
ofn.lpstrFile = fileName;
ofn.nMaxFile = MAX_PATH;
ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_NOCHANGEDIR | OFN_OVERWRITEPROMPT;
ofn.lpstrDefExt = "";
ofn.lpstrInitialDir = "";
if (GetSaveFileNameA(&ofn) != NULL)
{
return fileName;
}
return "";
}
std::string win32_open_dir()
{
BROWSEINFOA bi;
char Buffer[MAX_PATH];
ZeroMemory(Buffer, MAX_PATH);
ZeroMemory(&bi, sizeof(bi));
bi.hwndOwner = hWnd;
bi.pszDisplayName = Buffer;
bi.lpszTitle = "Title";
bi.ulFlags = BIF_EDITBOX | BIF_NEWDIALOGSTYLE | BIF_RETURNONLYFSDIRS | BIF_SHAREABLE;
LPCITEMIDLIST pFolder = SHBrowseForFolderA(&bi);
if (pFolder == NULL) return "";
if (!SHGetPathFromIDListA(pFolder, Buffer)) return "";
return Buffer;
}
namespace {
void invoke_selected_path(
const std::string& path,
const pp::platform::PickedPathCallback& callback)
{
if (!path.empty())
callback(path);
}
std::string build_supported_files_filter(const std::vector<std::string>& types)
{
std::string filter = "Supported Files (";
bool first_type = true;
for (const auto& t : types)
{
filter.append(std::string(first_type ? "" : " ,") + "*." + t);
first_type = false;
}
filter.append(")");
filter.push_back(0);
first_type = true;
for (const auto& t : types)
{
filter.append(std::string(first_type ? "" : ";") + "*." + t);
first_type = false;
}
filter.push_back(0);
return filter;
}
class WindowsPlatformServices final : public pp::platform::PlatformServices {
public:
[[nodiscard]] std::string clipboard_text() override
{
return win32_clipboard_get_text();
}
[[nodiscard]] bool set_clipboard_text(std::string_view text) override
{
return win32_clipboard_set_text(std::string(text));
}
void set_cursor_visible(bool visible) override
{
win32_show_cursor(visible);
}
void set_virtual_keyboard_visible(bool visible) override
{
(void)visible;
}
void display_file(std::string_view path) override
{
(void)path;
}
void share_file(std::string_view path) override
{
(void)path;
}
void pick_image(pp::platform::PickedPathCallback callback) override
{
const std::string path = win32_open_file("Image Files (*.jpg, *.png)\0*.jpg;*.png");
invoke_selected_path(path, callback);
}
void pick_file(std::vector<std::string> file_types, pp::platform::PickedPathCallback callback) override
{
const std::string filter = build_supported_files_filter(file_types);
const std::string path = win32_open_file(filter.c_str());
invoke_selected_path(path, callback);
}
void pick_save_file(std::vector<std::string> file_types, pp::platform::PickedPathCallback callback) override
{
const std::string filter = build_supported_files_filter(file_types);
const std::string path = win32_save_file(filter.c_str());
invoke_selected_path(path, callback);
}
void pick_directory(pp::platform::PickedPathCallback callback) override
{
const std::string path = win32_open_dir();
invoke_selected_path(path, callback);
}
};
[[nodiscard]] WindowsPlatformServices& windows_platform_services()
{
static WindowsPlatformServices services;
return services;
}
}
int read_WMI_info()
{
// see: http://win32easy.blogspot.co.uk/2011/03/wmi-in-c-query-everyting-from-your-os.html
@@ -940,7 +734,7 @@ int main(int argc, char** argv)
PIXELFORMATDESCRIPTOR pfd;
App::I = new App();
App::I->set_platform_services(&windows_platform_services());
App::I->set_platform_services(&pp::platform::windows::platform_services());
App::I->initLog();
init_shcore_API();
@@ -1268,7 +1062,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
}
case WM_ACTIVATE:
{
win32_show_cursor(true);
pp::platform::windows::platform_services().set_cursor_visible(true);
App::I->ui_task_async([=] {
int active = GET_WM_ACTIVATE_STATE(wp, lp);
WacomTablet::I.set_focus(active);