1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-07-01 03:22:48 -05:00

Merge legacy-Windows fixes (mostly) from 'pre-0.77'.

This commit is contained in:
Simon Tatham
2022-03-12 18:56:06 +00:00
18 changed files with 607 additions and 89 deletions

View File

@ -91,8 +91,6 @@ void modalfatalbox(const char *fmt, ...)
exit(1);
}
static bool has_security;
struct PassphraseProcStruct {
bool modal;
const char *help_topic;
@ -999,7 +997,7 @@ static char *answer_filemapping_message(const char *mapname)
debug("maphandle = %p\n", maphandle);
#endif
if (has_security) {
if (should_have_security()) {
DWORD retd;
if ((expectedsid = get_user_sid()) == NULL) {
@ -1387,6 +1385,23 @@ static NORETURN void opt_error(const char *fmt, ...)
exit(1);
}
#ifdef LEGACY_WINDOWS
BOOL sw_PeekMessage(LPMSG msg, HWND hwnd, UINT min, UINT max, UINT remove)
{
static bool unicode_unavailable = false;
if (!unicode_unavailable) {
BOOL ret = PeekMessageW(msg, hwnd, min, max, remove);
if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
unicode_unavailable = true; /* don't try again */
else
return ret;
}
return PeekMessageA(msg, hwnd, min, max, remove);
}
#else
#define sw_PeekMessage PeekMessageW
#endif
int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
{
MSG msg;
@ -1409,14 +1424,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
hinst = inst;
/*
* Determine whether we're an NT system (should have security
* APIs) or a non-NT system (don't do security).
*/
init_winver();
has_security = (osPlatformId == VER_PLATFORM_WIN32_NT);
if (has_security) {
if (should_have_security()) {
/*
* Attempt to get the security API we need.
*/
@ -1576,7 +1584,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
*/
wpc->plc.vt = &winpgnt_vtable;
wpc->plc.suppress_logging = true;
{
if (should_have_security()) {
Plug *pl_plug;
struct pageant_listen_state *pl =
pageant_listener_new(&pl_plug, &wpc->plc);
@ -1771,7 +1779,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
handle_wait_activate(hwl, n - WAIT_OBJECT_0);
handle_wait_list_free(hwl);
while (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE)) {
while (sw_PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
if (msg.message == WM_QUIT)
goto finished; /* two-level break */

View File

@ -576,6 +576,7 @@ void dll_hijacking_protection(void);
const char *get_system_dir(void);
HMODULE load_system32_dll(const char *libname);
const char *win_strerror(int error);
bool should_have_security(void);
void restrict_process_acl(void);
bool restricted_acl(void);
void escape_registry_key(const char *in, strbuf *out);
@ -608,7 +609,6 @@ void EnableSizeTip(bool bEnable);
/*
* Exports from unicode.c.
*/
struct unicode_data;
void init_ucs(Conf *, struct unicode_data *);
/*

View File

@ -1195,16 +1195,93 @@ int wc_to_mb(int codepage, int flags, const wchar_t *wcstr, int wclen,
}
return p - mbstr;
} else {
int defused;
return WideCharToMultiByte(codepage, flags, wcstr, wclen,
mbstr, mblen, defchr, &defused);
int defused, ret;
ret = WideCharToMultiByte(codepage, flags, wcstr, wclen,
mbstr, mblen, defchr, &defused);
if (ret)
return ret;
#ifdef LEGACY_WINDOWS
/*
* Fallback for legacy platforms too old to support UTF-8: if
* the codepage is UTF-8, we can do the translation ourselves.
*/
if (codepage == CP_UTF8 && mblen > 0 && wclen > 0) {
size_t remaining = mblen;
char *p = mbstr;
while (wclen > 0) {
unsigned long wc = (wclen--, *wcstr++);
if (wclen > 0 && IS_SURROGATE_PAIR(wc, *wcstr)) {
wc = FROM_SURROGATES(wc, *wcstr);
wclen--, wcstr++;
}
char utfbuf[6];
size_t utflen = encode_utf8(utfbuf, wc);
if (utflen <= remaining) {
memcpy(p, utfbuf, utflen);
p += utflen;
remaining -= utflen;
} else {
return p - mbstr;
}
}
return p - mbstr;
}
#endif
/* No other fallbacks are available */
return 0;
}
}
int mb_to_wc(int codepage, int flags, const char *mbstr, int mblen,
wchar_t *wcstr, int wclen)
{
return MultiByteToWideChar(codepage, flags, mbstr, mblen, wcstr, wclen);
int ret = MultiByteToWideChar(codepage, flags, mbstr, mblen, wcstr, wclen);
if (ret)
return ret;
#ifdef LEGACY_WINDOWS
/*
* Fallback for legacy platforms too old to support UTF-8: if the
* codepage is UTF-8, we can do the translation ourselves.
*/
if (codepage == CP_UTF8 && mblen > 0 && wclen > 0) {
size_t remaining = wclen;
wchar_t *p = wcstr;
while (mblen > 0) {
char utfbuf[7];
int thissize = mblen < 6 ? mblen : 6;
memcpy(utfbuf, mbstr, thissize);
utfbuf[thissize] = '\0';
const char *utfptr = utfbuf;
wchar_t wcbuf[2];
size_t nwc = decode_utf8_to_wchar(&utfptr, wcbuf);
for (size_t i = 0; i < nwc; i++) {
if (remaining > 0) {
remaining--;
*p++ = wcbuf[i];
} else {
return p - wcstr;
}
}
mbstr += (utfptr - utfbuf);
mblen -= (utfptr - utfbuf);
}
return p - wcstr;
}
#endif
/* No other fallbacks are available */
return 0;
}
bool is_dbcs_leadbyte(int codepage, char byte)

View File

@ -13,8 +13,8 @@ HANDLE lock_interprocess_mutex(const char *mutexname, char **error)
PACL acl = NULL;
HANDLE mutex = NULL;
if (!make_private_security_descriptor(MUTEX_ALL_ACCESS,
&psd, &acl, error))
if (should_have_security() && !make_private_security_descriptor(
MUTEX_ALL_ACCESS, &psd, &acl, error))
goto out;
SECURITY_ATTRIBUTES sa;

View File

@ -4,20 +4,19 @@
#include "putty.h"
bool open_for_write_would_lose_data(const Filename *fn)
/*
* This is slightly fiddly because we want to be backwards-compatible
* with systems too old to have GetFileAttributesEx. The next best
* thing is FindFirstFile, which will return a different data
* structure, but one that also contains the fields we want. (But it
* will behave more unhelpfully - for this application - in the
* presence of wildcards, so we'd prefer to use GFAE if we can.)
*/
static inline bool open_for_write_would_lose_data_impl(
DWORD dwFileAttributes, DWORD nFileSizeHigh, DWORD nFileSizeLow)
{
WIN32_FILE_ATTRIBUTE_DATA attrs;
if (!GetFileAttributesEx(fn->path, GetFileExInfoStandard, &attrs)) {
/*
* Generally, if we don't identify a specific reason why we
* should return true from this function, we return false, and
* let the subsequent attempt to open the file for real give a
* more useful error message.
*/
return false;
}
if (attrs.dwFileAttributes & (FILE_ATTRIBUTE_DEVICE |
FILE_ATTRIBUTE_DIRECTORY)) {
if (dwFileAttributes & (FILE_ATTRIBUTE_DEVICE|FILE_ATTRIBUTE_DIRECTORY)) {
/*
* File is something other than an ordinary disk file, so
* opening it for writing will not cause truncation. (It may
@ -25,7 +24,7 @@ bool open_for_write_would_lose_data(const Filename *fn)
*/
return false;
}
if (attrs.nFileSizeHigh == 0 && attrs.nFileSizeLow == 0) {
if (nFileSizeHigh == 0 && nFileSizeLow == 0) {
/*
* File is zero-length (or may be a named pipe, which
* dwFileAttributes can't tell apart from a regular file), so
@ -36,3 +35,42 @@ bool open_for_write_would_lose_data(const Filename *fn)
}
return true;
}
bool open_for_write_would_lose_data(const Filename *fn)
{
static HMODULE kernel32_module;
DECL_WINDOWS_FUNCTION(static, BOOL, GetFileAttributesExA,
(LPCSTR, GET_FILEEX_INFO_LEVELS, LPVOID));
if (!kernel32_module) {
kernel32_module = load_system32_dll("kernel32.dll");
GET_WINDOWS_FUNCTION(kernel32_module, GetFileAttributesExA);
}
if (p_GetFileAttributesExA) {
WIN32_FILE_ATTRIBUTE_DATA attrs;
if (!p_GetFileAttributesExA(fn->path, GetFileExInfoStandard, &attrs)) {
/*
* Generally, if we don't identify a specific reason why we
* should return true from this function, we return false, and
* let the subsequent attempt to open the file for real give a
* more useful error message.
*/
return false;
}
return open_for_write_would_lose_data_impl(
attrs.dwFileAttributes, attrs.nFileSizeHigh, attrs.nFileSizeLow);
} else {
WIN32_FIND_DATA fd;
HANDLE h = FindFirstFile(fn->path, &fd);
if (h == INVALID_HANDLE_VALUE) {
/*
* As above, if we can't find the file at all, return false.
*/
return false;
}
CloseHandle(h);
return open_for_write_would_lose_data_impl(
fd.dwFileAttributes, fd.nFileSizeHigh, fd.nFileSizeLow);
}
}

View File

@ -20,6 +20,20 @@ DEF_WINDOWS_FUNCTION(GetSecurityInfo);
DEF_WINDOWS_FUNCTION(SetSecurityInfo);
DEF_WINDOWS_FUNCTION(SetEntriesInAclA);
bool should_have_security(void)
{
#ifdef LEGACY_WINDOWS
/* Legacy pre-NT platforms are not expected to have any of these APIs */
init_winver();
return (osPlatformId == VER_PLATFORM_WIN32_NT);
#else
/* In the up-to-date PuTTY builds which do not support those
* platforms, unconditionally return true, to minimise the risk of
* compiling out security checks. */
return true;
#endif
}
bool got_advapi(void)
{
static bool attempted = false;

View File

@ -4,6 +4,11 @@ DWORD osMajorVersion, osMinorVersion, osPlatformId;
void init_winver(void)
{
static bool initialised = false;
if (initialised)
return;
initialised = true;
OSVERSIONINFO osVersion;
static HMODULE kernel32_module;
DECL_WINDOWS_FUNCTION(static, BOOL, GetVersionExA, (LPOSVERSIONINFO));

View File

@ -191,6 +191,9 @@ bool tried_pal = false;
COLORREF colorref_modifier = 0;
enum MONITOR_DPI_TYPE { MDT_EFFECTIVE_DPI, MDT_ANGULAR_DPI, MDT_RAW_DPI, MDT_DEFAULT };
DECL_WINDOWS_FUNCTION(static, BOOL, GetMonitorInfoA, (HMONITOR, LPMONITORINFO));
DECL_WINDOWS_FUNCTION(static, HMONITOR, MonitorFromPoint, (POINT, DWORD));
DECL_WINDOWS_FUNCTION(static, HMONITOR, MonitorFromWindow, (HWND, DWORD));
DECL_WINDOWS_FUNCTION(static, HRESULT, GetDpiForMonitor, (HMONITOR hmonitor, enum MONITOR_DPI_TYPE dpiType, UINT *dpiX, UINT *dpiY));
DECL_WINDOWS_FUNCTION(static, HRESULT, GetSystemMetricsForDpi, (int nIndex, UINT dpi));
DECL_WINDOWS_FUNCTION(static, HRESULT, AdjustWindowRectExForDpi, (LPRECT lpRect, DWORD dwStyle, BOOL bMenu, DWORD dwExStyle, UINT dpi));
@ -441,6 +444,72 @@ static void close_session(void *ignored_context)
}
}
/*
* Some machinery to deal with switching the window type between ANSI
* and Unicode. We prefer Unicode, but some PuTTY builds still try to
* run on machines so old that they don't support that mode. So we're
* prepared to fall back to an ANSI window if we have to. For this
* purpose, we swap out a few Windows API functions, and wrap
* SetWindowText so that if we're not in Unicode mode we first convert
* the wide string we're given.
*/
static bool unicode_window;
static BOOL (WINAPI *sw_PeekMessage)(LPMSG, HWND, UINT, UINT, UINT);
static LRESULT (WINAPI *sw_DispatchMessage)(const MSG *);
static LRESULT (WINAPI *sw_DefWindowProc)(HWND, UINT, WPARAM, LPARAM);
static void sw_SetWindowText(HWND hwnd, wchar_t *text)
{
if (unicode_window) {
SetWindowTextW(hwnd, text);
} else {
char *mb = dup_wc_to_mb(DEFAULT_CODEPAGE, 0, text, "?", &ucsdata);
SetWindowTextA(hwnd, mb);
sfree(mb);
}
}
static HINSTANCE hprev;
/*
* Also, registering window classes has to be done in a fiddly way.
*/
#define SETUP_WNDCLASS(wndclass, classname) do { \
wndclass.style = 0; \
wndclass.lpfnWndProc = WndProc; \
wndclass.cbClsExtra = 0; \
wndclass.cbWndExtra = 0; \
wndclass.hInstance = hinst; \
wndclass.hIcon = LoadIcon(hinst, MAKEINTRESOURCE(IDI_MAINICON)); \
wndclass.hCursor = LoadCursor(NULL, IDC_IBEAM); \
wndclass.hbrBackground = NULL; \
wndclass.lpszMenuName = NULL; \
wndclass.lpszClassName = classname; \
} while (0)
wchar_t *terminal_window_class_w(void)
{
static wchar_t *classname = NULL;
if (!classname)
classname = dup_mb_to_wc(DEFAULT_CODEPAGE, 0, appname);
if (!hprev) {
WNDCLASSW wndclassw;
SETUP_WNDCLASS(wndclassw, classname);
RegisterClassW(&wndclassw);
}
return classname;
}
char *terminal_window_class_a(void)
{
static char *classname = NULL;
if (!classname)
classname = dupcat(appname, ".ansi");
if (!hprev) {
WNDCLASSA wndclassa;
SETUP_WNDCLASS(wndclassa, classname);
RegisterClassA(&wndclassa);
}
return classname;
}
const unsigned cmdline_tooltype =
TOOLTYPE_HOST_ARG |
TOOLTYPE_PORT_ARG |
@ -457,6 +526,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
dll_hijacking_protection();
hinst = inst;
hprev = prev;
sk_init();
@ -505,23 +575,6 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
*/
gui_term_process_cmdline(conf, cmdline);
if (!prev) {
WNDCLASSW wndclass;
wndclass.style = 0;
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = inst;
wndclass.hIcon = LoadIcon(inst, MAKEINTRESOURCE(IDI_MAINICON));
wndclass.hCursor = LoadCursor(NULL, IDC_IBEAM);
wndclass.hbrBackground = NULL;
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = dup_mb_to_wc(DEFAULT_CODEPAGE, 0, appname);
RegisterClassW(&wndclass);
}
memset(&ucsdata, 0, sizeof(ucsdata));
conf_cache_data();
@ -557,6 +610,8 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
if (vt && vt->flags & BACKEND_RESIZE_FORBIDDEN)
resize_forbidden = true;
wchar_t *uappname = dup_mb_to_wc(DEFAULT_CODEPAGE, 0, appname);
window_name = dup_mb_to_wc(DEFAULT_CODEPAGE, 0, appname);
icon_name = dup_mb_to_wc(DEFAULT_CODEPAGE, 0, appname);
if (!conf_get_bool(conf, CONF_scrollbar))
winmode &= ~(WS_VSCROLL);
if (conf_get_int(conf, CONF_resize_action) == RESIZE_DISABLED ||
@ -566,9 +621,42 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
exwinmode |= WS_EX_TOPMOST;
if (conf_get_bool(conf, CONF_sunken_edge))
exwinmode |= WS_EX_CLIENTEDGE;
#ifdef TEST_ANSI_WINDOW
/* For developer testing of ANSI window support, pretend
* CreateWindowExW failed */
wgs.term_hwnd = NULL;
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
#else
unicode_window = true;
sw_PeekMessage = PeekMessageW;
sw_DispatchMessage = DispatchMessageW;
sw_DefWindowProc = DefWindowProcW;
wgs.term_hwnd = CreateWindowExW(
exwinmode, uappname, uappname, winmode, CW_USEDEFAULT,
CW_USEDEFAULT, guess_width, guess_height, NULL, NULL, inst, NULL);
exwinmode, terminal_window_class_w(), uappname,
winmode, CW_USEDEFAULT, CW_USEDEFAULT,
guess_width, guess_height, NULL, NULL, inst, NULL);
#endif
#if defined LEGACY_WINDOWS || defined TEST_ANSI_WINDOW
if (!wgs.term_hwnd && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) {
/* Fall back to an ANSI window, swapping in all the ANSI
* window message handling functions */
unicode_window = false;
sw_PeekMessage = PeekMessageA;
sw_DispatchMessage = DispatchMessageA;
sw_DefWindowProc = DefWindowProcA;
wgs.term_hwnd = CreateWindowExA(
exwinmode, terminal_window_class_a(), appname,
winmode, CW_USEDEFAULT, CW_USEDEFAULT,
guess_width, guess_height, NULL, NULL, inst, NULL);
}
#endif
if (!wgs.term_hwnd) {
modalfatalbox("Unable to create terminal window: %s",
win_strerror(GetLastError()));
}
memset(&dpi_info, 0, sizeof(struct _dpi_info));
init_dpi_info();
sfree(uappname);
@ -761,13 +849,13 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
handle_wait_activate(hwl, n - WAIT_OBJECT_0);
handle_wait_list_free(hwl);
while (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE)) {
while (sw_PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
if (msg.message == WM_QUIT)
goto finished; /* two-level break */
HWND logbox = event_log_window();
if (!(IsWindow(logbox) && IsDialogMessage(logbox, &msg)))
DispatchMessageW(&msg);
sw_DispatchMessage(&msg);
/*
* WM_NETEVENT messages seem to jump ahead of others in
@ -1271,9 +1359,9 @@ static int get_font_width(HDC hdc, const TEXTMETRIC *tm)
static void init_dpi_info(void)
{
if (dpi_info.cur_dpi.x == 0 || dpi_info.cur_dpi.y == 0) {
if (p_GetDpiForMonitor) {
if (p_GetDpiForMonitor && p_MonitorFromWindow) {
UINT dpiX, dpiY;
HMONITOR currentMonitor = MonitorFromWindow(
HMONITOR currentMonitor = p_MonitorFromWindow(
wgs.term_hwnd, MONITOR_DEFAULTTOPRIMARY);
if (p_GetDpiForMonitor(currentMonitor, MDT_EFFECTIVE_DPI,
&dpiX, &dpiY) == S_OK) {
@ -2177,7 +2265,8 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
* within an interactive scrollbar-drag can be handled
* differently. */
in_scrollbar_loop = true;
LRESULT result = DefWindowProcW(hwnd, message, wParam, lParam);
LRESULT result = sw_DefWindowProc(
hwnd, message, wParam, lParam);
in_scrollbar_loop = false;
return result;
}
@ -2596,27 +2685,26 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
GetCursorPos(&pt);
#ifndef NO_MULTIMON
{
if (p_GetMonitorInfoA && p_MonitorFromPoint) {
HMONITOR mon;
MONITORINFO mi;
mon = MonitorFromPoint(pt, MONITOR_DEFAULTTONULL);
mon = p_MonitorFromPoint(pt, MONITOR_DEFAULTTONULL);
if (mon != NULL) {
mi.cbSize = sizeof(MONITORINFO);
GetMonitorInfo(mon, &mi);
p_GetMonitorInfoA(mon, &mi);
if (mi.rcMonitor.left == pt.x &&
mi.rcMonitor.top == pt.y) {
mouse_on_hotspot = true;
}
}
}
#else
} else
#endif
if (pt.x == 0 && pt.y == 0) {
mouse_on_hotspot = true;
}
#endif
if (is_full_screen() && press &&
button == MBT_LEFT && mouse_on_hotspot) {
SendMessage(hwnd, WM_SYSCOMMAND, SC_MOUSEMENU,
@ -2960,11 +3048,11 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
term, r.right - r.left, r.bottom - r.top);
}
if (wParam == SIZE_MINIMIZED)
SetWindowTextW(hwnd,
conf_get_bool(conf, CONF_win_name_always) ?
window_name : icon_name);
sw_SetWindowText(hwnd,
conf_get_bool(conf, CONF_win_name_always) ?
window_name : icon_name);
if (wParam == SIZE_RESTORED || wParam == SIZE_MAXIMIZED)
SetWindowTextW(hwnd, window_name);
sw_SetWindowText(hwnd, window_name);
if (wParam == SIZE_RESTORED) {
processed_resize = false;
clear_full_screen();
@ -3186,7 +3274,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
} else {
len = TranslateKey(message, wParam, lParam, buf);
if (len == -1)
return DefWindowProcW(hwnd, message, wParam, lParam);
return sw_DefWindowProc(hwnd, message, wParam, lParam);
if (len != 0) {
/*
@ -3284,7 +3372,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
* post the things to us as part of a macro manoeuvre,
* we're ready to cope.
*/
{
if (unicode_window) {
static wchar_t pending_surrogate = 0;
wchar_t c = wParam;
@ -3298,6 +3386,11 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
} else if (!IS_SURROGATE(c)) {
term_keyinputw(term, &c, 1);
}
} else {
char c = (unsigned char)wParam;
term_seen_key_event(term);
if (ldisc)
term_keyinput(term, CP_ACP, &c, 1);
}
return 0;
case WM_SYSCOLORCHANGE:
@ -3373,7 +3466,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
* Any messages we don't process completely above are passed through to
* DefWindowProc() for default processing.
*/
return DefWindowProcW(hwnd, message, wParam, lParam);
return sw_DefWindowProc(hwnd, message, wParam, lParam);
}
/*
@ -4041,6 +4134,9 @@ static void init_winfuncs(void)
GET_WINDOWS_FUNCTION(user32_module, FlashWindowEx);
GET_WINDOWS_FUNCTION(user32_module, ToUnicodeEx);
GET_WINDOWS_FUNCTION_PP(winmm_module, PlaySound);
GET_WINDOWS_FUNCTION_NO_TYPECHECK(user32_module, GetMonitorInfoA);
GET_WINDOWS_FUNCTION_NO_TYPECHECK(user32_module, MonitorFromPoint);
GET_WINDOWS_FUNCTION_NO_TYPECHECK(user32_module, MonitorFromWindow);
GET_WINDOWS_FUNCTION_NO_TYPECHECK(shcore_module, GetDpiForMonitor);
GET_WINDOWS_FUNCTION_NO_TYPECHECK(user32_module, GetSystemMetricsForDpi);
GET_WINDOWS_FUNCTION_NO_TYPECHECK(user32_module, AdjustWindowRectExForDpi);
@ -4724,18 +4820,28 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
static void wintw_set_title(TermWin *tw, const char *title, int codepage)
{
wchar_t *new_window_name = dup_mb_to_wc(codepage, 0, title);
if (!wcscmp(new_window_name, window_name)) {
sfree(new_window_name);
return;
}
sfree(window_name);
window_name = dup_mb_to_wc(codepage, 0, title);
window_name = new_window_name;
if (conf_get_bool(conf, CONF_win_name_always) || !IsIconic(wgs.term_hwnd))
SetWindowTextW(wgs.term_hwnd, window_name);
sw_SetWindowText(wgs.term_hwnd, window_name);
}
static void wintw_set_icon_title(TermWin *tw, const char *title, int codepage)
{
wchar_t *new_icon_name = dup_mb_to_wc(codepage, 0, title);
if (!wcscmp(new_icon_name, icon_name)) {
sfree(new_icon_name);
return;
}
sfree(icon_name);
icon_name = dup_mb_to_wc(codepage, 0, title);
icon_name = new_icon_name;
if (!conf_get_bool(conf, CONF_win_name_always) && IsIconic(wgs.term_hwnd))
SetWindowTextW(wgs.term_hwnd, icon_name);
sw_SetWindowText(wgs.term_hwnd, icon_name);
}
static void wintw_set_scrollbar(TermWin *tw, int total, int start, int page)
@ -5641,23 +5747,24 @@ static bool is_full_screen()
static bool get_fullscreen_rect(RECT * ss)
{
#if defined(MONITOR_DEFAULTTONEAREST) && !defined(NO_MULTIMON)
if (p_GetMonitorInfoA && p_MonitorFromWindow) {
HMONITOR mon;
MONITORINFO mi;
mon = MonitorFromWindow(wgs.term_hwnd, MONITOR_DEFAULTTONEAREST);
mon = p_MonitorFromWindow(wgs.term_hwnd, MONITOR_DEFAULTTONEAREST);
mi.cbSize = sizeof(mi);
GetMonitorInfo(mon, &mi);
p_GetMonitorInfoA(mon, &mi);
/* structure copy */
*ss = mi.rcMonitor;
return true;
#else
}
#endif
/* could also use code like this:
ss->left = ss->top = 0;
ss->right = GetSystemMetrics(SM_CXSCREEN);
ss->bottom = GetSystemMetrics(SM_CYSCREEN);
*/
return GetClientRect(GetDesktopWindow(), ss);
#endif
}