mirror of
https://github.com/gnif/LookingGlass.git
synced 2026-11-12 14:57:20 +00:00
[common] windows: add native path and UTF support
This commit is contained in:
29
common/include/common/win32.h
Normal file
29
common/include/common/win32.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* Looking Glass
|
||||
* Copyright © 2017-2026 The Looking Glass Authors
|
||||
* https://looking-glass.io
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., 59
|
||||
* Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _H_LG_COMMON_WIN32_
|
||||
#define _H_LG_COMMON_WIN32_
|
||||
|
||||
#include <wchar.h>
|
||||
|
||||
wchar_t * lgUtf8ToWide(const char * input);
|
||||
char * lgWideToUtf8(const wchar_t * input);
|
||||
|
||||
#endif
|
||||
@@ -40,6 +40,9 @@ add_library(lg_common_platform_code STATIC
|
||||
windebug.c
|
||||
ivshmem.c
|
||||
time.c
|
||||
win32.c
|
||||
paths.c
|
||||
open.c
|
||||
cpuinfo.c
|
||||
display.c
|
||||
proctitle.c
|
||||
@@ -50,6 +53,9 @@ target_link_libraries(lg_common_platform_code
|
||||
setupapi
|
||||
bcrypt
|
||||
ntdll
|
||||
ole32
|
||||
shell32
|
||||
uuid
|
||||
)
|
||||
|
||||
if (ENABLE_BACKTRACE)
|
||||
|
||||
@@ -23,11 +23,12 @@
|
||||
|
||||
bool display_getPathInfo(HMONITOR monitor, DISPLAYCONFIG_PATH_INFO * info)
|
||||
{
|
||||
bool result = false;
|
||||
UINT32 numPath, numMode;
|
||||
bool result = false;
|
||||
UINT32 numPath;
|
||||
UINT32 numMode;
|
||||
|
||||
MONITORINFOEXW viewInfo = { .cbSize = sizeof(viewInfo) };
|
||||
if (!GetMonitorInfoW(monitor, (MONITORINFO*)&viewInfo))
|
||||
if (!GetMonitorInfoW(monitor, (MONITORINFO*)&viewInfo))
|
||||
{
|
||||
DEBUG_ERROR("Failed to get the monitor info");
|
||||
goto err;
|
||||
@@ -37,11 +38,11 @@ err_retry:
|
||||
if (FAILED(GetDisplayConfigBufferSizes(QDC_ONLY_ACTIVE_PATHS, &numPath, &numMode)))
|
||||
goto err;
|
||||
|
||||
DISPLAYCONFIG_PATH_INFO * pathInfo = calloc(sizeof(*pathInfo), numPath);
|
||||
DISPLAYCONFIG_PATH_INFO * pathInfo = calloc(numPath, sizeof(*pathInfo));
|
||||
if (!pathInfo)
|
||||
goto err_mem_pathInfo;
|
||||
|
||||
DISPLAYCONFIG_MODE_INFO * modeInfo = calloc(sizeof(*modeInfo), numMode);
|
||||
DISPLAYCONFIG_MODE_INFO * modeInfo = calloc(numMode, sizeof(*modeInfo));
|
||||
if (!modeInfo)
|
||||
goto err_mem_modeInfo;
|
||||
|
||||
|
||||
45
common/src/platform/windows/open.c
Normal file
45
common/src/platform/windows/open.c
Normal file
@@ -0,0 +1,45 @@
|
||||
/**
|
||||
* Looking Glass
|
||||
* Copyright © 2017-2026 The Looking Glass Authors
|
||||
* https://looking-glass.io
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., 59
|
||||
* Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "common/open.h"
|
||||
|
||||
#include "common/debug.h"
|
||||
#include "common/win32.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <windows.h>
|
||||
|
||||
bool lgOpenURL(const char * url)
|
||||
{
|
||||
wchar_t * wideUrl = lgUtf8ToWide(url);
|
||||
if (!wideUrl)
|
||||
return false;
|
||||
|
||||
const INT_PTR result = (INT_PTR)ShellExecuteW(
|
||||
NULL, L"open", wideUrl, NULL, NULL, SW_SHOWNORMAL);
|
||||
free(wideUrl);
|
||||
if (result > 32)
|
||||
return true;
|
||||
|
||||
DEBUG_ERROR("Failed to open URL (ShellExecute result: %lld)",
|
||||
(long long)result);
|
||||
return false;
|
||||
}
|
||||
116
common/src/platform/windows/paths.c
Normal file
116
common/src/platform/windows/paths.c
Normal file
@@ -0,0 +1,116 @@
|
||||
/**
|
||||
* Looking Glass
|
||||
* Copyright © 2017-2026 The Looking Glass Authors
|
||||
* https://looking-glass.io
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., 59
|
||||
* Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "common/paths.h"
|
||||
|
||||
#include "common/debug.h"
|
||||
#include "common/windebug.h"
|
||||
#include "common/win32.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <windows.h>
|
||||
#include <knownfolders.h>
|
||||
#include <shlobj.h>
|
||||
|
||||
static char * configDir;
|
||||
static char * dataDir;
|
||||
|
||||
static char * makePath(
|
||||
REFKNOWNFOLDERID folderId, const wchar_t * appName)
|
||||
{
|
||||
PWSTR base;
|
||||
const HRESULT status = SHGetKnownFolderPath(folderId, 0, NULL, &base);
|
||||
if (FAILED(status))
|
||||
{
|
||||
DEBUG_WINERROR("Failed to locate application data directory", status);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const size_t baseLength = wcslen(base);
|
||||
const size_t appLength = wcslen(appName);
|
||||
if (baseLength > SIZE_MAX - appLength - 2)
|
||||
{
|
||||
CoTaskMemFree(base);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
wchar_t * path = malloc(
|
||||
(baseLength + appLength + 2) * sizeof(*path));
|
||||
if (!path)
|
||||
{
|
||||
CoTaskMemFree(base);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy(path, base, baseLength * sizeof(*path));
|
||||
path[baseLength] = L'\\';
|
||||
memcpy(path + baseLength + 1, appName,
|
||||
(appLength + 1) * sizeof(*path));
|
||||
CoTaskMemFree(base);
|
||||
|
||||
if (!CreateDirectoryW(path, NULL) && GetLastError() != ERROR_ALREADY_EXISTS)
|
||||
{
|
||||
DEBUG_WINERROR("Failed to create application data directory",
|
||||
GetLastError());
|
||||
free(path);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char * result = lgWideToUtf8(path);
|
||||
free(path);
|
||||
return result;
|
||||
}
|
||||
|
||||
void lgPathsInit(const char * appName)
|
||||
{
|
||||
wchar_t * wideName = lgUtf8ToWide(appName);
|
||||
if (!wideName)
|
||||
{
|
||||
DEBUG_ERROR("Invalid UTF-8 application name");
|
||||
return;
|
||||
}
|
||||
|
||||
char * newConfigDir = makePath(&FOLDERID_RoamingAppData, wideName);
|
||||
char * newDataDir = makePath(&FOLDERID_LocalAppData, wideName);
|
||||
free(wideName);
|
||||
if (!newConfigDir || !newDataDir)
|
||||
{
|
||||
free(newConfigDir);
|
||||
free(newDataDir);
|
||||
return;
|
||||
}
|
||||
|
||||
free(configDir);
|
||||
free(dataDir);
|
||||
configDir = newConfigDir;
|
||||
dataDir = newDataDir;
|
||||
}
|
||||
|
||||
const char * lgConfigDir(void)
|
||||
{
|
||||
return configDir ? configDir : ".";
|
||||
}
|
||||
|
||||
const char * lgDataDir(void)
|
||||
{
|
||||
return dataDir ? dataDir : ".";
|
||||
}
|
||||
@@ -22,6 +22,9 @@
|
||||
|
||||
void lgInitProcessTitle(int argc, char **pargv[])
|
||||
{
|
||||
(void)argc;
|
||||
(void)pargv;
|
||||
|
||||
// not implemented on Windows
|
||||
}
|
||||
|
||||
@@ -32,5 +35,7 @@ bool lgCanSetProcessTitle(void)
|
||||
|
||||
void lgSetProcessTitle(const char * title)
|
||||
{
|
||||
(void)title;
|
||||
|
||||
// not implemented on Windows
|
||||
}
|
||||
|
||||
72
common/src/platform/windows/win32.c
Normal file
72
common/src/platform/windows/win32.c
Normal file
@@ -0,0 +1,72 @@
|
||||
/**
|
||||
* Looking Glass
|
||||
* Copyright © 2017-2026 The Looking Glass Authors
|
||||
* https://looking-glass.io
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., 59
|
||||
* Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "common/win32.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <windows.h>
|
||||
|
||||
wchar_t * lgUtf8ToWide(const char * input)
|
||||
{
|
||||
if (!input)
|
||||
return NULL;
|
||||
|
||||
const int length = MultiByteToWideChar(
|
||||
CP_UTF8, MB_ERR_INVALID_CHARS, input, -1, NULL, 0);
|
||||
if (!length)
|
||||
return NULL;
|
||||
|
||||
wchar_t * output = malloc((size_t)length * sizeof(*output));
|
||||
if (!output)
|
||||
return NULL;
|
||||
|
||||
if (!MultiByteToWideChar(
|
||||
CP_UTF8, MB_ERR_INVALID_CHARS, input, -1, output, length))
|
||||
{
|
||||
free(output);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
char * lgWideToUtf8(const wchar_t * input)
|
||||
{
|
||||
if (!input)
|
||||
return NULL;
|
||||
|
||||
const int length = WideCharToMultiByte(
|
||||
CP_UTF8, WC_ERR_INVALID_CHARS, input, -1, NULL, 0, NULL, NULL);
|
||||
if (!length)
|
||||
return NULL;
|
||||
|
||||
char * output = malloc((size_t)length);
|
||||
if (!output)
|
||||
return NULL;
|
||||
|
||||
if (!WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS,
|
||||
input, -1, output, length, NULL, NULL))
|
||||
{
|
||||
free(output);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
Reference in New Issue
Block a user