Files
86Box/src/win/win_preferences.c
2023-08-23 04:15:57 -04:00

291 lines
8.5 KiB
C

/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Handle the dialog for changing the program's language and other global settings.
*
*
*
* Authors: Laci bá'
*
* Copyright 2021 Laci bá'
* Copyright 2021-2023 Jasmine Iwanek.
*/
#define UNICODE
#define BITMAP WINDOWS_BITMAP
#include <windows.h>
#include <windowsx.h>
#undef BITMAP
#include <commctrl.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <wchar.h>
#include <86box/86box.h>
#include <86box/config.h>
#include <86box/plat.h>
#include <86box/sound.h>
#include <86box/win.h>
#include <86box/ui.h>
#include <86box/resource.h>
/* Language */
static LCID temp_language;
static char temp_icon_set[256] = { 0 };
int enum_helper;
int c;
HWND hwndPreferences;
BOOL CALLBACK
EnumResLangProc(UNUSED(HMODULE hModule), UNUSED(LPCTSTR lpszType), UNUSED(LPCTSTR lpszName), WORD wIDLanguage, LONG_PTR lParam)
{
wchar_t temp[LOCALE_NAME_MAX_LENGTH + 1];
LCIDToLocaleName(wIDLanguage, temp, LOCALE_NAME_MAX_LENGTH, 0);
wchar_t dispname[MAX_PATH + 1];
GetLocaleInfoEx(temp, LOCALE_SENGLISHDISPLAYNAME, dispname, MAX_PATH);
SendMessage((HWND) lParam, CB_ADDSTRING, 0, (LPARAM) dispname);
SendMessage((HWND) lParam, CB_SETITEMDATA, c, (LPARAM) wIDLanguage);
if (wIDLanguage == lang_id)
enum_helper = c;
c++;
return 1;
}
/* Load available languages */
static void
preferences_fill_languages(HWND hdlg)
{
temp_language = GetThreadUILanguage();
HWND lang_combo = GetDlgItem(hdlg, IDC_COMBO_LANG);
SendMessage(lang_combo, CB_RESETCONTENT, 0, 0);
SendMessage(lang_combo, CB_ADDSTRING, 0, win_get_string(IDS_7168));
SendMessage(lang_combo, CB_SETITEMDATA, 0, 0xFFFF);
enum_helper = 0;
c = 1;
// if no one is selected, then it was 0xFFFF or unsupported language, in either case go with index enum_helper=0
// also start enum index from c=1
EnumResourceLanguages(hinstance, RT_MENU, L"MainMenu", &EnumResLangProc, (LPARAM) lang_combo);
SendMessage(lang_combo, CB_SETCURSEL, enum_helper, 0);
}
/* Load available iconsets */
static void
preferences_fill_iconsets(HWND hdlg)
{
HWND icon_combo = GetDlgItem(hdlg, IDC_COMBO_ICON);
/* Add the default one */
wchar_t buffer[512] = L"(";
wcscat(buffer, plat_get_string(IDS_DEFAULT));
wcscat(buffer, L")");
SendMessage(icon_combo, CB_RESETCONTENT, 0, 0);
SendMessage(icon_combo, CB_ADDSTRING, 0, (LPARAM) buffer);
SendMessage(icon_combo, CB_SETITEMDATA, 0, (LPARAM) strdup(""));
int combo_index = -1;
/* Find for extra ones */
HANDLE hFind;
WIN32_FIND_DATA data;
char icon_path_root[512];
win_get_icons_path(icon_path_root);
wchar_t search[512];
mbstoc16s(search, icon_path_root, strlen(icon_path_root) + 1);
wcscat(search, L"*.*");
hFind = FindFirstFile((LPCWSTR) search, &data);
if (hFind != INVALID_HANDLE_VALUE) {
do {
if (wcscmp(data.cFileName, L".") && wcscmp(data.cFileName, L"..") && (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
wchar_t temp[512] = { 0 };
wchar_t dispname[512] = { 0 };
mbstoc16s(temp, icon_path_root, strlen(icon_path_root) + 1);
wcscat(temp, data.cFileName);
wcscat(temp, L"\\iconinfo.txt");
wcscpy(dispname, data.cFileName);
FILE *fp = _wfopen(temp, L"r");
if (fp) {
char line[512] = { 0 };
if (fgets(line, 511, fp)) {
mbstoc16s(dispname, line, strlen(line) + 1);
}
fclose(fp);
}
char filename[512];
c16stombs(filename, data.cFileName, 511);
int index = SendMessage(icon_combo, CB_ADDSTRING, 0, (LPARAM) dispname);
SendMessage(icon_combo, CB_SETITEMDATA, index, (LPARAM) (strdup(filename)));
if (!strcmp(filename, icon_set))
combo_index = index;
}
} while (FindNextFile(hFind, &data));
FindClose(hFind);
}
if (combo_index == -1) {
combo_index = 0;
strcpy(temp_icon_set, "");
}
SendMessage(icon_combo, CB_SETCURSEL, combo_index, 0);
}
/* This returns 1 if any variable has changed, 0 if not. */
static int
preferences_settings_changed(void)
{
int i = 0;
/* Language */
i = i || has_language_changed(temp_language);
i = i || strcmp(temp_icon_set, icon_set);
return i;
}
/* IndexOf by ItemData */
static int
preferences_indexof(HWND combo, LPARAM itemdata)
{
for (int i = 0; i < SendMessage(combo, CB_GETCOUNT, 0, 0); i++)
if (SendMessage(combo, CB_GETITEMDATA, i, 0) == itemdata)
return i;
return -1;
}
/* This saves the settings back to the global variables. */
static void
preferences_settings_save(void)
{
/* Language */
set_language(temp_language);
/* Iconset */
strcpy(icon_set, temp_icon_set);
win_load_icon_set();
/* Update title bar */
update_mouse_msg();
/* Update status bar */
config_changed = 1;
ui_sb_set_ready(-1);
ui_sb_update_panes();
ui_sb_update_text();
/* Save the language changes */
config_save();
}
#if defined(__amd64__) || defined(__aarch64__)
static LRESULT CALLBACK
#else
static BOOL CALLBACK
#endif
PreferencesDlgProcedure(HWND hdlg, UINT message, WPARAM wParam, UNUSED(LPARAM lParam))
{
switch (message) {
case WM_INITDIALOG:
hwndPreferences = hdlg;
/* Language */
temp_language = lang_id;
strcpy(temp_icon_set, icon_set);
preferences_fill_languages(hdlg);
preferences_fill_iconsets(hdlg);
break;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDOK:
if (preferences_settings_changed())
preferences_settings_save();
EndDialog(hdlg, 0);
return TRUE;
case IDCANCEL:
EndDialog(hdlg, 0);
return TRUE;
case IDC_COMBO_LANG:
if (HIWORD(wParam) == CBN_SELCHANGE) {
HWND combo = GetDlgItem(hdlg, IDC_COMBO_LANG);
int index = SendMessage(combo, CB_GETCURSEL, 0, 0);
temp_language = SendMessage(combo, CB_GETITEMDATA, index, 0);
}
break;
case IDC_COMBO_ICON:
if (HIWORD(wParam) == CBN_SELCHANGE) {
HWND combo = GetDlgItem(hdlg, IDC_COMBO_ICON);
int index = SendMessage(combo, CB_GETCURSEL, 0, 0);
strcpy(temp_icon_set, (char *) SendMessage(combo, CB_GETITEMDATA, index, 0));
}
break;
case IDC_BUTTON_DEFAULT:
{
HWND combo = GetDlgItem(hdlg, IDC_COMBO_LANG);
int index = preferences_indexof(combo, DEFAULT_LANGUAGE);
SendMessage(combo, CB_SETCURSEL, index, 0);
temp_language = DEFAULT_LANGUAGE;
break;
}
case IDC_BUTTON_DEFICON:
{
SendMessage(GetDlgItem(hdlg, IDC_COMBO_ICON), CB_SETCURSEL, 0, 0);
strcpy(temp_icon_set, "");
break;
}
default:
break;
}
break;
case WM_DESTROY:
{
LRESULT temp;
HWND combo = GetDlgItem(hdlg, IDC_COMBO_ICON);
for (int i = 0; i < SendMessage(combo, CB_GETCOUNT, 0, 0); i++) {
temp = SendMessage(combo, CB_GETITEMDATA, i, 0);
if (temp) {
free((void *) temp);
SendMessage(combo, CB_SETITEMDATA, i, 0);
}
}
}
break;
}
return FALSE;
}
void
PreferencesDlgCreate(HWND hwnd)
{
DialogBox(hinstance, (LPCTSTR) DLG_PREFERENCES, hwnd, PreferencesDlgProcedure);
}