Merge pull request #992 from driver1998/dpi

HiDPI support
This commit is contained in:
Miran Grča
2020-09-07 01:33:40 +02:00
committed by GitHub
10 changed files with 354 additions and 157 deletions

View File

@@ -459,7 +459,8 @@ load_general(void)
force_43 = !!config_get_int(cat, "force_43", 0);
scale = config_get_int(cat, "scale", 1);
if (scale > 3)
scale = 3;
scale = 3;
dpi_scale = config_get_int(cat, "dpi_scale", 1);
enable_overscan = !!config_get_int(cat, "enable_overscan", 0);
vid_cga_contrast = !!config_get_int(cat, "vid_cga_contrast", 0);
@@ -1605,6 +1606,11 @@ save_general(void)
else
config_set_int(cat, "scale", scale);
if (dpi_scale == 1)
config_delete_var(cat, "dpi_scale");
else
config_set_int(cat, "dpi_scale", dpi_scale);
if (enable_overscan == 0)
config_delete_var(cat, "enable_overscan");
else

View File

@@ -82,6 +82,7 @@ extern int window_w, window_h, /* (C) window size and */
invert_display, /* (C) invert the display */
suppress_overscan; /* (C) suppress overscans */
extern int scale; /* (C) screen scale factor */
extern int dpi_scale; /* (C) DPI scaling of the emulated screen */
extern int vid_api; /* (C) video renderer */
extern int vid_cga_contrast, /* (C) video */
video_fullscreen, /* (C) video */

View File

@@ -296,6 +296,7 @@
#define IDM_VID_SCALE_2X 40056
#define IDM_VID_SCALE_3X 40057
#define IDM_VID_SCALE_4X 40058
#define IDM_VID_HIDPI 40059
#define IDM_VID_FULLSCREEN 40060
#define IDM_VID_FS_FULL 40061
#define IDM_VID_FS_43 40062

View File

@@ -33,6 +33,19 @@
# include "resource.h"
# undef BITMAP
/* DPI Awareness Context, copied from MinGW-w64 windef.h */
#ifndef _DPI_AWARENESS_CONTEXTS_
DECLARE_HANDLE(DPI_AWARENESS_CONTEXT);
#define DPI_AWARENESS_CONTEXT_UNAWARE ((DPI_AWARENESS_CONTEXT)-1)
#define DPI_AWARENESS_CONTEXT_SYSTEM_AWARE ((DPI_AWARENESS_CONTEXT)-2)
#define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE ((DPI_AWARENESS_CONTEXT)-3)
#define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 ((DPI_AWARENESS_CONTEXT)-4)
#define DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED ((DPI_AWARENESS_CONTEXT)-5)
#endif
#ifndef WM_DPICHANGED_AFTERPARENT
#define WM_DPICHANGED_AFTERPARENT 0x02E3
#endif
/* Class names and such. */
#define CLASS_NAME L"86BoxMainWnd"
@@ -119,6 +132,8 @@ extern void win_joystick_handle(PRAWINPUT raw);
extern void win_notify_dlg_open(void);
extern void win_notify_dlg_closed(void);
extern int win_get_dpi(HWND hwnd);
extern int win_get_system_metrics(int i, int dpi);
extern LPARAM win_get_string(int id);

View File

@@ -116,6 +116,7 @@ int window_w, window_h, /* (C) window size and */
invert_display = 0, /* (C) invert the display */
suppress_overscan = 0; /* (C) suppress overscans */
int scale = 0; /* (C) screen scale factor */
int dpi_scale = 0; /* (C) DPI scaling of the emulated screen */
int vid_api = 0; /* (C) video renderer */
int vid_cga_contrast = 0, /* (C) video */
video_fullscreen = 0, /* (C) video */

View File

@@ -1,21 +1,27 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity
version="1.20.0.0"
processorArchitecture="*"
name="86Box.exe"
type="win32"
/>
<dependency>
<assemblyIdentity
version="1.20.0.0"
processorArchitecture="*"
name="86Box.exe"
type="win32"
/>
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="*"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="*"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>
</dependency>
<application>
<windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">permonitorv2</dpiAwareness>
</windowsSettings>
</application>
</assembly>

View File

@@ -80,6 +80,7 @@ BEGIN
MENUITEM "1.&5x", IDM_VID_SCALE_3X
MENUITEM "&2x", IDM_VID_SCALE_4X
END
MENUITEM "Hi&DPI scaling", IDM_VID_HIDPI
MENUITEM SEPARATOR
MENUITEM "&Fullscreen\tCtrl+Alt+PageUP", IDM_VID_FULLSCREEN
POPUP "Fullscreen &stretch mode"
@@ -316,7 +317,7 @@ BEGIN
WS_BORDER,53,45,166,14
END
DLG_CONFIG DIALOG DISCARDABLE 0, 0, 366, 256
DLG_CONFIG DIALOG DISCARDABLE 0, 0, 376, 256
STYLE DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "86Box Settings"
FONT 9, "Segoe UI"
@@ -324,8 +325,8 @@ BEGIN
DEFPUSHBUTTON "OK",IDOK,246,235,50,14
PUSHBUTTON "Cancel",IDCANCEL,307,235,50,14
CONTROL "List2",IDC_SETTINGSCATLIST,"SysListView32",LVS_LIST |
LVS_SHOWSELALWAYS | LVS_SINGLESEL | WS_BORDER | WS_TABSTOP,7,7,90,212
CONTROL "",-1,"Static",SS_BLACKFRAME | SS_SUNKEN,1,226,363,1
LVS_SHOWSELALWAYS | LVS_SINGLESEL | WS_BORDER | WS_TABSTOP,7,7,100,212
CONTROL "",-1,"Static",SS_BLACKFRAME | SS_SUNKEN,1,226,373,1
/* Leave this commented out until we get into localization. */
#if 0
LTEXT "Language:",IDT_1700,7,237,41,10
@@ -334,7 +335,7 @@ BEGIN
#endif
END
DLG_CFG_MACHINE DIALOG DISCARDABLE 97, 0, 305, 199
DLG_CFG_MACHINE DIALOG DISCARDABLE 107, 0, 305, 199
STYLE DS_CONTROL | WS_CHILD
FONT 9, "Segoe UI"
BEGIN
@@ -376,7 +377,7 @@ BEGIN
#endif
END
DLG_CFG_VIDEO DIALOG DISCARDABLE 97, 0, 267, 45
DLG_CFG_VIDEO DIALOG DISCARDABLE 107, 0, 267, 45
STYLE DS_CONTROL | WS_CHILD
FONT 9, "Segoe UI"
BEGIN
@@ -389,7 +390,7 @@ BEGIN
PUSHBUTTON "Configure",IDC_BUTTON_VOODOO,222,26,38,12
END
DLG_CFG_INPUT DIALOG DISCARDABLE 97, 0, 267, 65
DLG_CFG_INPUT DIALOG DISCARDABLE 107, 0, 267, 65
STYLE DS_CONTROL | WS_CHILD
FONT 9, "Segoe UI"
BEGIN
@@ -406,7 +407,7 @@ BEGIN
PUSHBUTTON "Joystick 4...",IDC_JOY4,209,44,50,14
END
DLG_CFG_SOUND DIALOG DISCARDABLE 97, 0, 267, 199
DLG_CFG_SOUND DIALOG DISCARDABLE 107, 0, 267, 199
STYLE DS_CONTROL | WS_CHILD
FONT 9, "Segoe UI"
BEGIN
@@ -442,7 +443,7 @@ BEGIN
BS_AUTOCHECKBOX | WS_TABSTOP,7,115,94,10
END
DLG_CFG_NETWORK DIALOG DISCARDABLE 97, 0, 267, 63
DLG_CFG_NETWORK DIALOG DISCARDABLE 107, 0, 267, 63
STYLE DS_CONTROL | WS_CHILD
FONT 9, "Segoe UI"
BEGIN
@@ -460,7 +461,7 @@ BEGIN
PUSHBUTTON "Configure",IDC_CONFIGURE_NET,214,43,46,12
END
DLG_CFG_PORTS DIALOG DISCARDABLE 97, 0, 267, 135
DLG_CFG_PORTS DIALOG DISCARDABLE 107, 0, 267, 135
STYLE DS_CONTROL | WS_CHILD
FONT 9, "Segoe UI"
BEGIN
@@ -493,7 +494,7 @@ BEGIN
BS_AUTOCHECKBOX | WS_TABSTOP,7,118,94,10
END
DLG_CFG_PERIPHERALS DIALOG DISCARDABLE 97, 0, 267, 220
DLG_CFG_PERIPHERALS DIALOG DISCARDABLE 107, 0, 267, 220
STYLE DS_CONTROL | WS_CHILD
FONT 9, "Segoe UI"
BEGIN
@@ -550,7 +551,7 @@ BEGIN
PUSHBUTTON "Configure",IDC_CONFIGURE_ISAMEM_4,217,190,38,12
END
DLG_CFG_HARD_DISKS DIALOG DISCARDABLE 97, 0, 267, 154
DLG_CFG_HARD_DISKS DIALOG DISCARDABLE 107, 0, 267, 154
STYLE DS_CONTROL | WS_CHILD
FONT 9, "Segoe UI"
BEGIN
@@ -611,7 +612,7 @@ BEGIN
WS_BORDER,7,16,204,12
END
DLG_CFG_FLOPPY_AND_CDROM_DRIVES DIALOG DISCARDABLE 97, 0, 267, 222
DLG_CFG_FLOPPY_AND_CDROM_DRIVES DIALOG DISCARDABLE 107, 0, 267, 222
STYLE DS_CONTROL | WS_CHILD
FONT 9, "Segoe UI"
BEGIN
@@ -645,7 +646,7 @@ BEGIN
LTEXT "Speed:",IDT_1758,7,207,24,8
END
DLG_CFG_OTHER_REMOVABLE_DEVICES DIALOG DISCARDABLE 97, 0, 267, 222
DLG_CFG_OTHER_REMOVABLE_DEVICES DIALOG DISCARDABLE 107, 0, 267, 222
STYLE DS_CONTROL | WS_CHILD
FONT 9, "Segoe UI"
BEGIN

View File

@@ -71,6 +71,7 @@
static int first_cat = 0;
static int dpi = 96;
/* Machine category */
static int temp_machine_type, temp_machine, temp_cpu_m, temp_cpu, temp_wait_states, temp_fpu, temp_sync;
@@ -153,8 +154,11 @@ image_list_init(HWND hwndList, const uint8_t *icon_ids)
int i = 0;
hSmall = ImageList_Create(GetSystemMetrics(SM_CXSMICON),
GetSystemMetrics(SM_CYSMICON),
hSmall = ListView_GetImageList(hwndList, LVSIL_SMALL);
if (hSmall != 0) ImageList_Destroy(hSmall);
hSmall = ImageList_Create(win_get_system_metrics(SM_CXSMICON, dpi),
win_get_system_metrics(SM_CYSMICON, dpi),
ILC_MASK | ILC_COLOR32, 1, 1);
while(1) {
@@ -2680,6 +2684,16 @@ win_settings_hard_disks_recalc_list(HWND hwndList)
return TRUE;
}
static void
win_settings_hard_disks_resize_columns(HWND hwndList)
{
int iCol;
/* Bus, File, Cylinders, Heads, Sectors, Size */
int width[C_COLUMNS_HARD_DISKS] = {130, 130, 41, 25, 25, 41};
for (iCol = 0; iCol < C_COLUMNS_HARD_DISKS; iCol++) {
ListView_SetColumnWidth(hwndList, iCol, MulDiv(width[iCol], dpi, 96));
}
}
static BOOL
win_settings_hard_disks_init_columns(HWND hwndList)
@@ -2695,7 +2709,7 @@ win_settings_hard_disks_init_columns(HWND hwndList)
switch(iCol) {
case 0: /* Bus */
lvc.cx = 135;
lvc.cx = 130;
lvc.fmt = LVCFMT_LEFT;
break;
case 2: /* Cylinders */
@@ -2708,7 +2722,7 @@ win_settings_hard_disks_init_columns(HWND hwndList)
lvc.fmt = LVCFMT_RIGHT;
break;
case 1: /* File */
lvc.cx = 150;
lvc.cx = 130;
lvc.fmt = LVCFMT_LEFT;
break;
case 5: /* Size (MB) 8 */
@@ -2721,6 +2735,7 @@ win_settings_hard_disks_init_columns(HWND hwndList)
return FALSE;
}
win_settings_hard_disks_resize_columns(hwndList);
return TRUE;
}
@@ -3682,6 +3697,11 @@ hd_bus_skip:
return FALSE;
}
case WM_DPICHANGED_AFTERPARENT:
h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS);
win_settings_hard_disks_resize_columns(h);
image_list_init(h, (const uint8_t *) hd_icons);
break;
default:
return FALSE;
}
@@ -3920,6 +3940,14 @@ win_settings_zip_drives_recalc_list(HWND hwndList)
}
static void
win_settings_floppy_drives_resize_columns(HWND hwndList)
{
ListView_SetColumnWidth(hwndList, 0, MulDiv(250, dpi, 96));
ListView_SetColumnWidth(hwndList, 1, MulDiv(50, dpi, 96));
ListView_SetColumnWidth(hwndList, 2, MulDiv(75, dpi, 96));
}
static BOOL
win_settings_floppy_drives_init_columns(HWND hwndList)
{
@@ -3930,7 +3958,7 @@ win_settings_floppy_drives_init_columns(HWND hwndList)
lvc.iSubItem = 0;
lvc.pszText = plat_get_string(IDS_2092);
lvc.cx = 292;
lvc.cx = 250;
lvc.fmt = LVCFMT_LEFT;
if (ListView_InsertColumn(hwndList, 0, &lvc) == -1)
@@ -3952,12 +3980,20 @@ win_settings_floppy_drives_init_columns(HWND hwndList)
lvc.fmt = LVCFMT_LEFT;
if (ListView_InsertColumn(hwndList, 2, &lvc) == -1)
return FALSE;
return FALSE;
win_settings_floppy_drives_resize_columns(hwndList);
return TRUE;
}
static void
win_settings_cdrom_drives_resize_columns(HWND hwndList)
{
ListView_SetColumnWidth(hwndList, 0, MulDiv(342, dpi, 96));
ListView_SetColumnWidth(hwndList, 1, MulDiv(50, dpi, 96));
}
static BOOL
win_settings_cdrom_drives_init_columns(HWND hwndList)
{
@@ -3981,11 +4017,18 @@ win_settings_cdrom_drives_init_columns(HWND hwndList)
lvc.fmt = LVCFMT_LEFT;
if (ListView_InsertColumn(hwndList, 1, &lvc) == -1)
return FALSE;
return FALSE;
win_settings_cdrom_drives_resize_columns(hwndList);
return TRUE;
}
static void
win_settings_mo_drives_resize_columns(HWND hwndList)
{
ListView_SetColumnWidth(hwndList, 0, MulDiv(120, dpi, 96));
ListView_SetColumnWidth(hwndList, 1, MulDiv(260, dpi, 96));
}
static BOOL
win_settings_mo_drives_init_columns(HWND hwndList)
@@ -4010,11 +4053,18 @@ win_settings_mo_drives_init_columns(HWND hwndList)
lvc.fmt = LVCFMT_LEFT;
if (ListView_InsertColumn(hwndList, 1, &lvc) == -1)
return FALSE;
return FALSE;
win_settings_mo_drives_resize_columns(hwndList);
return TRUE;
}
static void
win_settings_zip_drives_resize_columns(HWND hwndList)
{
ListView_SetColumnWidth(hwndList, 0, MulDiv(342, dpi, 96));
ListView_SetColumnWidth(hwndList, 1, MulDiv(50, dpi, 96));
}
static BOOL
win_settings_zip_drives_init_columns(HWND hwndList)
@@ -4039,8 +4089,9 @@ win_settings_zip_drives_init_columns(HWND hwndList)
lvc.fmt = LVCFMT_LEFT;
if (ListView_InsertColumn(hwndList, 1, &lvc) == -1)
return FALSE;
return FALSE;
win_settings_zip_drives_resize_columns(hwndList);
return TRUE;
}
@@ -4856,6 +4907,14 @@ win_settings_floppy_and_cdrom_drives_proc(HWND hdlg, UINT message, WPARAM wParam
}
ignore_change = 0;
case WM_DPICHANGED_AFTERPARENT:
h = GetDlgItem(hdlg, IDC_LIST_FLOPPY_DRIVES);
win_settings_floppy_drives_resize_columns(h);
image_list_init(h, (const uint8_t *) fd_icons);
h = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES);
win_settings_cdrom_drives_resize_columns(h);
image_list_init(h, (const uint8_t *) cd_icons);
break;
default:
return FALSE;
}
@@ -5122,6 +5181,14 @@ win_settings_other_removable_devices_proc(HWND hdlg, UINT message, WPARAM wParam
}
ignore_change = 0;
case WM_DPICHANGED_AFTERPARENT:
h = GetDlgItem(hdlg, IDC_LIST_MO_DRIVES);
win_settings_mo_drives_resize_columns(h);
image_list_init(h, (const uint8_t *) mo_icons);
h = GetDlgItem(hdlg, IDC_LIST_ZIP_DRIVES);
win_settings_zip_drives_resize_columns(h);
image_list_init(h, (const uint8_t *) zip_icons);
break;
default:
return FALSE;
}
@@ -5244,6 +5311,7 @@ win_settings_main_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
switch (message) {
case WM_INITDIALOG:
dpi = win_get_dpi(hdlg);
win_settings_init();
displayed_category = -1;
h = GetDlgItem(hdlg, IDC_SETTINGSCATLIST);
@@ -5277,6 +5345,11 @@ win_settings_main_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
return TRUE;
}
break;
case WM_DPICHANGED:
dpi = HIWORD(wParam);
h = GetDlgItem(hdlg, IDC_SETTINGSCATLIST);
image_list_init(h, (const uint8_t *) cat_icons);
break;
default:
return FALSE;
}

View File

@@ -70,6 +70,8 @@ static uint8_t *sb_part_icons;
static int sb_parts = 0;
static int sb_ready = 0;
static uint8_t sb_map[256];
static int dpi = 96;
static int icon_width = 24;
/* Also used by win_settings.c */
intptr_t
@@ -537,7 +539,7 @@ ui_sb_update_panes(void)
sb_parts = 0;
for (i=0; i<FDD_NUM; i++) {
if (fdd_get_type(i) != 0) {
edge += SB_ICON_WIDTH;
edge += icon_width;
iStatusWidths[sb_parts] = edge;
sb_part_meanings[sb_parts] = SB_FLOPPY | i;
sb_map[SB_FLOPPY | i] = sb_parts;
@@ -553,7 +555,7 @@ ui_sb_update_panes(void)
if ((cdrom[i].bus_type == CDROM_BUS_SCSI) && (scsi_card_current == 0))
continue;
if (cdrom[i].bus_type != 0) {
edge += SB_ICON_WIDTH;
edge += icon_width;
iStatusWidths[sb_parts] = edge;
sb_part_meanings[sb_parts] = SB_CDROM | i;
sb_map[SB_CDROM | i] = sb_parts;
@@ -568,7 +570,7 @@ ui_sb_update_panes(void)
if ((zip_drives[i].bus_type == ZIP_BUS_SCSI) && (scsi_card_current == 0))
continue;
if (zip_drives[i].bus_type != 0) {
edge += SB_ICON_WIDTH;
edge += icon_width;
iStatusWidths[sb_parts] = edge;
sb_part_meanings[sb_parts] = SB_ZIP | i;
sb_map[SB_ZIP | i] = sb_parts;
@@ -583,7 +585,7 @@ ui_sb_update_panes(void)
if ((mo_drives[i].bus_type == MO_BUS_SCSI) && (scsi_card_current == 0))
continue;
if (mo_drives[i].bus_type != 0) {
edge += SB_ICON_WIDTH;
edge += icon_width;
iStatusWidths[sb_parts] = edge;
sb_part_meanings[sb_parts] = SB_MO | i;
sb_map[SB_MO | i] = sb_parts;
@@ -591,56 +593,55 @@ ui_sb_update_panes(void)
}
}
if (c_mfm && (hdint || !memcmp(hdc_name, "st506", 5))) {
edge += SB_ICON_WIDTH;
edge += icon_width;
iStatusWidths[sb_parts] = edge;
sb_part_meanings[sb_parts] = SB_HDD | HDD_BUS_MFM;
sb_map[SB_HDD | HDD_BUS_MFM] = sb_parts;
sb_parts++;
}
if (c_esdi && (hdint || !memcmp(hdc_name, "esdi", 4))) {
edge += SB_ICON_WIDTH;
edge += icon_width;
iStatusWidths[sb_parts] = edge;
sb_part_meanings[sb_parts] = SB_HDD | HDD_BUS_ESDI;
sb_map[SB_HDD | HDD_BUS_ESDI] = sb_parts;
sb_parts++;
}
if (c_xta && (hdint || !memcmp(hdc_name, "xta", 3))) {
edge += SB_ICON_WIDTH;
edge += icon_width;
iStatusWidths[sb_parts] = edge;
sb_part_meanings[sb_parts] = SB_HDD | HDD_BUS_XTA;
sb_map[SB_HDD | HDD_BUS_XTA] = sb_parts;
sb_parts++;
}
if (c_ide && (hdint || !memcmp(hdc_name, "xtide", 5) || !memcmp(hdc_name, "ide", 3))) {
edge += SB_ICON_WIDTH;
edge += icon_width;
iStatusWidths[sb_parts] = edge;
sb_part_meanings[sb_parts] = SB_HDD | HDD_BUS_IDE;
sb_map[SB_HDD | HDD_BUS_IDE] = sb_parts;
sb_parts++;
}
if (c_scsi && (scsi_card_current != 0)) {
edge += SB_ICON_WIDTH;
edge += icon_width;
iStatusWidths[sb_parts] = edge;
sb_part_meanings[sb_parts] = SB_HDD | HDD_BUS_SCSI;
sb_map[SB_HDD | HDD_BUS_SCSI] = sb_parts;
sb_parts++;
}
if (do_net) {
edge += SB_ICON_WIDTH;
edge += icon_width;
iStatusWidths[sb_parts] = edge;
sb_part_meanings[sb_parts] = SB_NETWORK;
sb_map[SB_NETWORK] = sb_parts;
sb_parts++;
}
edge += SB_ICON_WIDTH;
edge += icon_width;
iStatusWidths[sb_parts] = edge;
sb_part_meanings[sb_parts] = SB_SOUND;
sb_map[SB_SOUND] = sb_parts;
sb_parts++;
if (sb_parts)
iStatusWidths[sb_parts - 1] += (24 - SB_ICON_WIDTH);
iStatusWidths[sb_parts] = -1;
sb_part_meanings[sb_parts] = SB_TEXT;
sb_map[SB_TEXT] = sb_parts;
@@ -718,7 +719,7 @@ StatusBarPopupMenu(HWND hwnd, POINT pt, int id)
if (id >= (sb_parts - 1)) return;
pt.x = id * SB_ICON_WIDTH; /* Justify to the left. */
pt.x = id * icon_width; /* Justify to the left. */
pt.y = 0; /* Justify to the top. */
ClientToScreen(hwnd, (LPPOINT) &pt);
@@ -744,6 +745,48 @@ StatusBarPopupMenu(HWND hwnd, POINT pt, int id)
pt.x, pt.y, 0, hwndSBAR, NULL);
}
/* API: Load status bar icons */
void
StatusBarLoadIcon(HINSTANCE hInst) {
int i;
int x = win_get_system_metrics(SM_CXSMICON, dpi);
for (i=0; i<256; i++) {
if (hIcon[i] != 0)
DestroyIcon(hIcon[i]);
}
for (i = 16; i < 18; i++)
hIcon[i] = LoadImage(hInst, MAKEINTRESOURCE(i), IMAGE_ICON, x, x, LR_DEFAULTCOLOR);
for (i = 24; i < 26; i++)
hIcon[i] = LoadImage(hInst, MAKEINTRESOURCE(i), IMAGE_ICON, x, x, LR_DEFAULTCOLOR);
for (i = 32; i < 34; i++)
hIcon[i] = LoadImage(hInst, MAKEINTRESOURCE(i), IMAGE_ICON, x, x, LR_DEFAULTCOLOR);
for (i = 48; i < 50; i++)
hIcon[i] = LoadImage(hInst, MAKEINTRESOURCE(i), IMAGE_ICON, x, x, LR_DEFAULTCOLOR);
for (i = 56; i < 58; i++)
hIcon[i] = LoadImage(hInst, MAKEINTRESOURCE(i), IMAGE_ICON, x, x, LR_DEFAULTCOLOR);
for (i = 64; i < 66; i++)
hIcon[i] = LoadImage(hInst, MAKEINTRESOURCE(i), IMAGE_ICON, x, x, LR_DEFAULTCOLOR);
for (i = 80; i < 82; i++)
hIcon[i] = LoadImage(hInst, MAKEINTRESOURCE(i), IMAGE_ICON, x, x, LR_DEFAULTCOLOR);
for (i = 96; i < 98; i++)
hIcon[i] = LoadImage(hInst, MAKEINTRESOURCE(i), IMAGE_ICON, x, x, LR_DEFAULTCOLOR);
for (i = 144; i < 146; i++)
hIcon[i] = LoadImage(hInst, MAKEINTRESOURCE(i), IMAGE_ICON, x, x, LR_DEFAULTCOLOR);
for (i = 152; i < 154; i++)
hIcon[i] = LoadImage(hInst, MAKEINTRESOURCE(i), IMAGE_ICON, x, x, LR_DEFAULTCOLOR);
for (i = 160; i < 162; i++)
hIcon[i] = LoadImage(hInst, MAKEINTRESOURCE(i), IMAGE_ICON, x, x, LR_DEFAULTCOLOR);
for (i = 176; i < 178; i++)
hIcon[i] = LoadImage(hInst, MAKEINTRESOURCE(i), IMAGE_ICON, x, x, LR_DEFAULTCOLOR);
for (i = 184; i < 186; i++)
hIcon[i] = LoadImage(hInst, MAKEINTRESOURCE(i), IMAGE_ICON, x, x, LR_DEFAULTCOLOR);
for (i = 192; i < 194; i++)
hIcon[i] = LoadImage(hInst, MAKEINTRESOURCE(i), IMAGE_ICON, x, x, LR_DEFAULTCOLOR);
for (i = 243; i < 244; i++)
hIcon[i] = LoadImage(hInst, MAKEINTRESOURCE(i), IMAGE_ICON, x, x, LR_DEFAULTCOLOR);
}
/* Handle messages for the Status Bar window. */
#if defined(__amd64__) || defined(__aarch64__)
@@ -756,6 +799,8 @@ StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
RECT rc;
POINT pt;
int item_id = 0;
int i;
HINSTANCE hInst;
switch (message) {
case WM_COMMAND:
@@ -768,20 +813,38 @@ StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
pt.x = GET_X_LPARAM(lParam);
pt.y = GET_Y_LPARAM(lParam);
if (PtInRect((LPRECT) &rc, pt))
StatusBarPopupMenu(hwnd, pt, (pt.x / SB_ICON_WIDTH));
StatusBarPopupMenu(hwnd, pt, (pt.x / icon_width));
break;
case WM_LBUTTONDBLCLK:
GetClientRect(hwnd, (LPRECT)& rc);
pt.x = GET_X_LPARAM(lParam);
pt.y = GET_Y_LPARAM(lParam);
item_id = (pt.x / SB_ICON_WIDTH);
item_id = (pt.x / icon_width);
if (PtInRect((LPRECT) &rc, pt) && (item_id < sb_parts)) {
if (sb_part_meanings[item_id] == SB_SOUND)
SoundGainDialogCreate(hwndMain);
}
break;
case WM_DPICHANGED_AFTERPARENT:
/* DPI changed, reload icons */
hInst = (HINSTANCE)GetWindowLongPtr(hwnd, GWLP_HINSTANCE);
dpi = win_get_dpi(hwnd);
icon_width = MulDiv(SB_ICON_WIDTH, dpi, 96);
StatusBarLoadIcon(hInst);
for (i=0; i<sb_parts; i++) {
if (sb_part_icons[i] != 255) {
SendMessage(hwndSBAR, SB_SETICON, i, (LPARAM)hIcon[sb_part_icons[i]]);
}
iStatusWidths[i] = (i+1)*icon_width;
}
iStatusWidths[i-1] = -1;
SendMessage(hwndSBAR, SB_SETPARTS, (WPARAM)sb_parts, (LPARAM)iStatusWidths);
break;
default:
return(CallWindowProc((WNDPROC)OriginalProcedure,
hwnd, message, wParam, lParam));
@@ -797,39 +860,13 @@ StatusBarCreate(HWND hwndParent, uintptr_t idStatus, HINSTANCE hInst)
{
RECT rectDialog;
int dw, dh;
uint8_t i;
/* Get current DPI and calculate icon sizes */
dpi = win_get_dpi(hwndParent);
icon_width = MulDiv(SB_ICON_WIDTH, dpi, 96);
/* Load our icons into the cache for faster access. */
for (i = 16; i < 18; i++)
hIcon[i] = LoadIconEx((PCTSTR) (uintptr_t) i);
for (i = 24; i < 26; i++)
hIcon[i] = LoadIconEx((PCTSTR) (uintptr_t) i);
for (i = 32; i < 34; i++)
hIcon[i] = LoadIconEx((PCTSTR) (uintptr_t) i);
for (i = 48; i < 50; i++)
hIcon[i] = LoadIconEx((PCTSTR) (uintptr_t) i);
for (i = 56; i < 58; i++)
hIcon[i] = LoadIconEx((PCTSTR) (uintptr_t) i);
for (i = 64; i < 66; i++)
hIcon[i] = LoadIconEx((PCTSTR) (uintptr_t) i);
for (i = 80; i < 82; i++)
hIcon[i] = LoadIconEx((PCTSTR) (uintptr_t) i);
for (i = 96; i < 98; i++)
hIcon[i] = LoadIconEx((PCTSTR) (uintptr_t) i);
for (i = 144; i < 146; i++)
hIcon[i] = LoadIconEx((PCTSTR) (uintptr_t) i);
for (i = 152; i < 154; i++)
hIcon[i] = LoadIconEx((PCTSTR) (uintptr_t) i);
for (i = 160; i < 162; i++)
hIcon[i] = LoadIconEx((PCTSTR) (uintptr_t) i);
for (i = 176; i < 178; i++)
hIcon[i] = LoadIconEx((PCTSTR) (uintptr_t) i);
for (i = 184; i < 186; i++)
hIcon[i] = LoadIconEx((PCTSTR) (uintptr_t) i);
for (i = 192; i < 194; i++)
hIcon[i] = LoadIconEx((PCTSTR) (uintptr_t) i);
for (i = 243; i < 244; i++)
hIcon[i] = LoadIconEx((PCTSTR) (uintptr_t) i);
StatusBarLoadIcon(hInst);
GetWindowRect(hwndParent, &rectDialog);
dw = rectDialog.right - rectDialog.left;

View File

@@ -37,6 +37,7 @@
#include <86box/vid_ega.h> // for update_overscan
#include <86box/plat.h>
#include <86box/plat_midi.h>
#include <86box/plat_dynld.h>
#include <86box/ui.h>
#include <86box/win.h>
#include <86box/version.h>
@@ -69,10 +70,67 @@ static wchar_t wTitle[512];
static HHOOK hKeyboardHook;
static int hook_enabled = 0, manager_wm = 0;
static int save_window_pos = 0, pause_state = 0;
static int dpi = 96;
static int padded_frame = 0;
static int vis = -1;
/* Per Monitor DPI Aware v2 APIs, Windows 10 v1703+ */
void* user32_handle = NULL;
static UINT (WINAPI *pGetDpiForWindow)(HWND);
static UINT (WINAPI *pGetSystemMetricsForDpi)(int i, UINT dpi);
static DPI_AWARENESS_CONTEXT (WINAPI *pGetWindowDpiAwarenessContext)(HWND);
static BOOL (WINAPI *pAreDpiAwarenessContextsEqual)(DPI_AWARENESS_CONTEXT A, DPI_AWARENESS_CONTEXT B);
static dllimp_t user32_imports[] = {
{ "GetDpiForWindow", &pGetDpiForWindow },
{ "GetSystemMetricsForDpi", &pGetSystemMetricsForDpi },
{ "GetWindowDpiAwarenessContext", &pGetWindowDpiAwarenessContext },
{ "AreDpiAwarenessContextsEqual", &pAreDpiAwarenessContextsEqual },
{ NULL, NULL }
};
int
win_get_dpi(HWND hwnd) {
if (user32_handle != NULL) {
return pGetDpiForWindow(hwnd);
} else {
HDC dc = GetDC(hwnd);
UINT dpi = GetDeviceCaps(dc, LOGPIXELSX);
ReleaseDC(hwnd, dc);
return dpi;
}
}
int win_get_system_metrics(int index, int dpi) {
if (user32_handle != NULL) {
/* Only call GetSystemMetricsForDpi when we are using PMv2 */
DPI_AWARENESS_CONTEXT c = pGetWindowDpiAwarenessContext(hwndMain);
if (pAreDpiAwarenessContextsEqual(c, DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2))
return pGetSystemMetricsForDpi(index, dpi);
}
return GetSystemMetrics(index);
}
void
ResizeWindowByClientArea(HWND hwnd, int width, int height)
{
if (vid_resize || padded_frame) {
int padding = win_get_system_metrics(SM_CXPADDEDBORDER, dpi);
width += (win_get_system_metrics(SM_CXFRAME, dpi) + padding) * 2;
height += (win_get_system_metrics(SM_CYFRAME, dpi) + padding) * 2;
} else {
width += win_get_system_metrics(SM_CXFIXEDFRAME, dpi) * 2;
height += win_get_system_metrics(SM_CYFIXEDFRAME, dpi) * 2;
}
height += win_get_system_metrics(SM_CYCAPTION, dpi);
height += win_get_system_metrics(SM_CYBORDER, dpi) + win_get_system_metrics(SM_CYMENUSIZE, dpi);
SetWindowPos(hwnd, NULL, 0, 0, width, height, SWP_NOMOVE);
}
/* Set host cursor visible or not. */
void
show_cursor(int val)
@@ -168,6 +226,7 @@ ResetAllMenus(void)
CheckMenuItem(menuMain, IDM_VID_SCALE_1X+1, MF_UNCHECKED);
CheckMenuItem(menuMain, IDM_VID_SCALE_1X+2, MF_UNCHECKED);
CheckMenuItem(menuMain, IDM_VID_SCALE_1X+3, MF_UNCHECKED);
CheckMenuItem(menuMain, IDM_VID_HIDPI, MF_UNCHECKED);
CheckMenuItem(menuMain, IDM_VID_CGACON, MF_UNCHECKED);
CheckMenuItem(menuMain, IDM_VID_GRAYCT_601+0, MF_UNCHECKED);
@@ -217,6 +276,7 @@ ResetAllMenus(void)
CheckMenuItem(menuMain, IDM_VID_FS_FULL+video_fullscreen_scale, MF_CHECKED);
CheckMenuItem(menuMain, IDM_VID_REMEMBER, window_remember?MF_CHECKED:MF_UNCHECKED);
CheckMenuItem(menuMain, IDM_VID_SCALE_1X+scale, MF_CHECKED);
CheckMenuItem(menuMain, IDM_VID_HIDPI, dpi_scale?MF_CHECKED:MF_UNCHECKED);
CheckMenuItem(menuMain, IDM_VID_CGACON, vid_cga_contrast?MF_CHECKED:MF_UNCHECKED);
CheckMenuItem(menuMain, IDM_VID_GRAYCT_601+video_graytype, MF_CHECKED);
@@ -290,8 +350,8 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HMENU hmenu;
int i, sb_borders[3];
RECT rect;
int i;
RECT rect, *rect_p;
int temp_x, temp_y;
@@ -392,42 +452,28 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
if (vid_resize)
SetWindowLongPtr(hwnd, GWL_STYLE, (WS_OVERLAPPEDWINDOW) | WS_VISIBLE);
else
SetWindowLongPtr(hwnd, GWL_STYLE, (WS_OVERLAPPEDWINDOW & ~WS_SIZEBOX & ~WS_THICKFRAME & ~WS_MAXIMIZEBOX) | WS_VISIBLE);
else
SetWindowLongPtr(hwnd, GWL_STYLE, (WS_OVERLAPPEDWINDOW & ~WS_SIZEBOX & ~WS_MAXIMIZEBOX) | WS_VISIBLE);
SendMessage(hwndSBAR, SB_GETBORDERS, 0, (LPARAM) sb_borders);
GetWindowRect(hwnd, &rect);
/* Main Window. */
if (GetSystemMetrics(SM_CXPADDEDBORDER) == 0) {
/* For platforms that subsystem version < 6.0 (default on mingw/msys2) */
/* In this case, border sizes are different between resizable and non-resizable window */
MoveWindow(hwnd, rect.left, rect.top,
unscaled_size_x + (GetSystemMetrics(vid_resize ? SM_CXSIZEFRAME : SM_CXFIXEDFRAME) * 2),
unscaled_size_y + (GetSystemMetrics(vid_resize ? SM_CYSIZEFRAME : SM_CYFIXEDFRAME) * 2) + (GetSystemMetrics(SM_CYBORDER) + GetSystemMetrics(SM_CYMENUSIZE)) + GetSystemMetrics(SM_CYCAPTION) + sbar_height,
TRUE);
/* scale the screen base on DPI */
if (dpi_scale) {
temp_x = MulDiv(unscaled_size_x, dpi, 96);
temp_y = MulDiv(unscaled_size_y, dpi, 96);
} else {
/* For platforms that subsystem version >= 6.0 (default on llvm-mingw, mainly for Windows/ARM) */
/* In this case, border sizes are the same between resizable and non-resizable window */
MoveWindow(hwnd, rect.left, rect.top,
unscaled_size_x + ((GetSystemMetrics(SM_CXFRAME) + GetSystemMetrics(SM_CXPADDEDBORDER)) * 2),
unscaled_size_y + ((GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CXPADDEDBORDER)) * 2) + (GetSystemMetrics(SM_CYBORDER) + GetSystemMetrics(SM_CYMENUSIZE)) + GetSystemMetrics(SM_CYCAPTION) + sbar_height,
TRUE);
temp_x = unscaled_size_x;
temp_y = unscaled_size_y;
}
/* Main Window. */
ResizeWindowByClientArea(hwnd, temp_x, temp_y + sbar_height);
/* Render window. */
MoveWindow(hwndRender, 0, 0, unscaled_size_x, unscaled_size_y, TRUE);
MoveWindow(hwndRender, 0, 0, temp_x, temp_y, TRUE);
GetWindowRect(hwndRender, &rect);
/* Status bar. */
MoveWindow(hwndSBAR,
0, rect.bottom + GetSystemMetrics(SM_CYEDGE),
unscaled_size_x, 17, TRUE);
MoveWindow(hwndSBAR, 0, rect.bottom, temp_x, 17, TRUE);
if (mouse_capture) {
GetWindowRect(hwndRender, &rect);
ClipCursor(&rect);
}
@@ -440,6 +486,9 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
EnableMenuItem(hmenu, IDM_VID_SCALE_2X, vid_resize ? MF_GRAYED : MF_ENABLED);
EnableMenuItem(hmenu, IDM_VID_SCALE_3X, vid_resize ? MF_GRAYED : MF_ENABLED);
EnableMenuItem(hmenu, IDM_VID_SCALE_4X, vid_resize ? MF_GRAYED : MF_ENABLED);
scrnsz_x = unscaled_size_x;
scrnsz_y = unscaled_size_y;
doresize = 1;
config_save();
break;
@@ -496,6 +545,13 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
config_save();
break;
case IDM_VID_HIDPI:
dpi_scale = !dpi_scale;
CheckMenuItem(hmenu, IDM_VID_HIDPI, dpi_scale ? MF_CHECKED : MF_UNCHECKED);
doresize = 1;
config_save();
break;
case IDM_VID_FORCE43:
video_toggle_option(hmenu, &force_43, IDM_VID_FORCE43);
video_force_resize_set(1);
@@ -624,12 +680,22 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
case WM_ENTERMENULOOP:
break;
case WM_DPICHANGED:
dpi = HIWORD(wParam);
GetWindowRect(hwndSBAR, &rect);
sbar_height = rect.bottom - rect.top;
rect_p = (RECT*)lParam;
if (vid_resize) {
MoveWindow(hwnd, rect_p->left, rect_p->top, rect_p->right - rect_p->left, rect_p->bottom - rect_p->top, TRUE);
} else if (!user_resize) {
doresize = 1;
}
break;
case WM_SIZE:
if (user_resize && !vid_resize)
break;
SendMessage(hwndSBAR, SB_GETBORDERS, 0, (LPARAM) sb_borders);
temp_x = (lParam & 0xFFFF);
temp_y = (lParam >> 16);
@@ -646,26 +712,22 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
if (temp_y < 1)
temp_y = 1;
if ((temp_x != scrnsz_x) || (temp_y != scrnsz_y))
if (vid_resize && ((temp_x != scrnsz_x) || (temp_y != scrnsz_y))) {
scrnsz_x = temp_x;
scrnsz_y = temp_y;
doresize = 1;
}
scrnsz_x = temp_x;
scrnsz_y = temp_y;
MoveWindow(hwndRender, 0, 0, scrnsz_x, scrnsz_y, TRUE);
MoveWindow(hwndRender, 0, 0, temp_x, temp_y, TRUE);
GetWindowRect(hwndRender, &rect);
/* Status bar. */
MoveWindow(hwndSBAR,
0, rect.bottom + GetSystemMetrics(SM_CYEDGE),
scrnsz_x, 17, TRUE);
MoveWindow(hwndSBAR, 0, rect.bottom, temp_x, 17, TRUE);
plat_vidsize(scrnsz_x, scrnsz_y);
plat_vidsize(temp_x, temp_y);
if (mouse_capture) {
GetWindowRect(hwndRender, &rect);
ClipCursor(&rect);
}
@@ -894,6 +956,9 @@ ui_init(int nCmdShow)
TASKDIALOGCONFIG tdconfig = {0};
TASKDIALOG_BUTTON tdbuttons[] = {{IDCANCEL, MAKEINTRESOURCE(IDS_2119)}};
/* Load DPI related Windows 10 APIs */
user32_handle = dynld_module("user32.dll", user32_imports);
/* Set up TaskDialog configuration. */
tdconfig.cbSize = sizeof(tdconfig);
tdconfig.dwFlags = TDF_ENABLE_HYPERLINKS;
@@ -973,6 +1038,19 @@ ui_init(int nCmdShow)
ui_window_title(title);
/* Get the current DPI */
dpi = win_get_dpi(hwndMain);
/* Check if we have a padded window frame */
padded_frame = (GetSystemMetrics(SM_CXPADDEDBORDER) != 0);
/* Create the status bar window. */
StatusBarCreate(hwndMain, IDC_STATUS, hinstance);
/* Get the actual height of the status bar */
GetWindowRect(hwndSBAR, &sbar_rect);
sbar_height = sbar_rect.bottom - sbar_rect.top;
/* Set up main window for resizing if configured. */
if (vid_resize)
SetWindowLongPtr(hwnd, GWL_STYLE,
@@ -1019,15 +1097,6 @@ ui_init(int nCmdShow)
/* Initialize the mouse module. */
win_mouse_init();
/* Create the status bar window. */
StatusBarCreate(hwndMain, IDC_STATUS, hinstance);
/* Get the actual height of the statusbar,
* since that is not something we can change.
*/
GetWindowRect(hwndSBAR, &sbar_rect);
sbar_height = sbar_rect.bottom - sbar_rect.top;
/*
* Before we can create the Render window, we first have
* to prepare some other things that it depends on.
@@ -1137,6 +1206,9 @@ ui_init(int nCmdShow)
discord_close();
#endif
if (user32_handle != NULL)
dynld_close(user32_handle);
return(messages.wParam);
}
@@ -1218,42 +1290,26 @@ plat_pause(int p)
void
plat_resize(int x, int y)
{
int sb_borders[3];
RECT r;
/* First, see if we should resize the UI window. */
if (!vid_resize) {
video_wait_for_blit();
SendMessage(hwndSBAR, SB_GETBORDERS, 0, (LPARAM) sb_borders);
GetWindowRect(hwndMain, &r);
if (GetSystemMetrics(SM_CXPADDEDBORDER) == 0) {
/* For platforms that subsystem version < 6.0 (gcc on mingw/msys2) */
/* In this case, border sizes are different between resizable and non-resizable window */
MoveWindow(hwndMain, r.left, r.top,
x + (GetSystemMetrics(vid_resize ? SM_CXSIZEFRAME : SM_CXFIXEDFRAME) * 2),
y + (GetSystemMetrics(vid_resize ? SM_CYSIZEFRAME : SM_CYFIXEDFRAME) * 2) + (GetSystemMetrics(SM_CYBORDER) + GetSystemMetrics(SM_CYMENUSIZE)) + GetSystemMetrics(SM_CYCAPTION) + sbar_height,
TRUE);
} else {
/* For platforms that subsystem version >= 6.0 (clang/llvm on llvm-mingw, mainly for Windows/ARM) */
/* In this case, border sizes are the same between resizable and non-resizable window */
MoveWindow(hwndMain, r.left, r.top,
x + ((GetSystemMetrics(SM_CXFRAME) + GetSystemMetrics(SM_CXPADDEDBORDER)) * 2),
y + ((GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CXPADDEDBORDER)) * 2) + (GetSystemMetrics(SM_CYBORDER) + GetSystemMetrics(SM_CYMENUSIZE)) + GetSystemMetrics(SM_CYCAPTION) + sbar_height,
TRUE);
/* scale the screen base on DPI */
if (dpi_scale) {
x = MulDiv(x, dpi, 96);
y = MulDiv(y, dpi, 96);
}
ResizeWindowByClientArea(hwndMain, x, y + sbar_height);
MoveWindow(hwndRender, 0, 0, x, y, TRUE);
GetWindowRect(hwndRender, &r);
MoveWindow(hwndSBAR,
0, r.bottom + GetSystemMetrics(SM_CYEDGE),
x, 17, TRUE);
MoveWindow(hwndSBAR, 0, y, x, 17, TRUE);
if (mouse_capture) {
GetWindowRect(hwndRender, &r);
ClipCursor(&r);
}
}