Bemanitools v5.26 release
This commit is contained in:
@@ -0,0 +1,489 @@
|
||||
#include <windows.h>
|
||||
#include <commctrl.h>
|
||||
#include <commdlg.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
|
||||
#include "config/resource.h"
|
||||
#include "config/schema.h"
|
||||
|
||||
#include "eamio/eam-config.h"
|
||||
|
||||
#include "geninput/hid-mgr.h"
|
||||
#include "geninput/input-config.h"
|
||||
#include "geninput/kbd.h"
|
||||
|
||||
#include "util/array.h"
|
||||
#include "util/defs.h"
|
||||
#include "util/log.h"
|
||||
#include "util/mem.h"
|
||||
#include "util/str.h"
|
||||
|
||||
/* You may or may not have noticed that there is a blank label in the Network
|
||||
tab's dialog resource definition. This is a consequence of the way that
|
||||
Windows UI styles work. WIN32K's (i.e. raw USER32's) GUI routines draw
|
||||
widgets using the Windows 95 chunky bezels and flat surfaces style, but if
|
||||
your app pulls in COMMCTRL v6 or later using an SxS manifest, then it
|
||||
overrides the built-in Win32 widgets with its own glossy versions, in
|
||||
addition to the extended control library that its API provides.
|
||||
|
||||
I'm guessing that top-level windows and dialogs (the tab is a dialog) get
|
||||
subclassed as soon as one of these glossified built-ins gets WM_CREATEd
|
||||
within a window. Hence the presence of the Static control to make sure this
|
||||
takes place.
|
||||
|
||||
Otherwise, you get a flat grey shaded tab body, which looks wrong on Vista
|
||||
and above. */
|
||||
|
||||
struct eam_ui {
|
||||
struct array children;
|
||||
};
|
||||
|
||||
struct eam_unit_ui {
|
||||
const struct eam_unit_def *def;
|
||||
struct array devs;
|
||||
};
|
||||
|
||||
static INT_PTR CALLBACK eam_ui_dlg_proc(HWND hwnd, UINT msg, WPARAM wparam,
|
||||
LPARAM lparam);
|
||||
static INT_PTR eam_ui_handle_init(HWND hwnd, const PROPSHEETPAGE *psp);
|
||||
static INT_PTR eam_ui_handle_activate(HWND hwnd);
|
||||
static INT_PTR eam_ui_handle_passivate(HWND hwnd);
|
||||
static INT_PTR eam_ui_handle_tick(HWND hwnd);
|
||||
static INT_PTR eam_ui_handle_change_alt_10k(HWND hwnd);
|
||||
static INT_PTR eam_ui_handle_change_autogen(HWND hwnd);
|
||||
static INT_PTR eam_ui_handle_fini(HWND hwnd);
|
||||
|
||||
static INT_PTR CALLBACK eam_unit_ui_dlg_proc(HWND hwnd, UINT msg, WPARAM wparam,
|
||||
LPARAM lparam);
|
||||
static INT_PTR eam_unit_ui_handle_init(HWND hwnd,
|
||||
const struct eam_unit_def *def);
|
||||
static void eam_unit_ui_handle_init_devs(HWND hwnd);
|
||||
static void eam_unit_ui_handle_init_path(HWND hwnd);
|
||||
static INT_PTR eam_unit_ui_handle_browse(HWND hwnd);
|
||||
static INT_PTR eam_unit_ui_handle_change_device(HWND hwnd);
|
||||
static INT_PTR eam_unit_ui_handle_tick(HWND hwnd);
|
||||
static INT_PTR eam_unit_ui_handle_fini(HWND hwnd);
|
||||
|
||||
static const struct eam_io_config_api *eam_io_config_api;
|
||||
|
||||
HPROPSHEETPAGE eam_ui_tab_create(HINSTANCE inst, const struct schema *schema,
|
||||
const struct eam_io_config_api *api)
|
||||
{
|
||||
PROPSHEETPAGE psp;
|
||||
|
||||
eam_io_config_api = api;
|
||||
|
||||
memset(&psp, 0, sizeof(psp));
|
||||
psp.dwSize = sizeof(psp);
|
||||
psp.dwFlags = PSP_DEFAULT;
|
||||
psp.hInstance = inst;
|
||||
psp.pszTemplate = MAKEINTRESOURCE(IDD_TAB_NETWORK);
|
||||
psp.pfnDlgProc = eam_ui_dlg_proc;
|
||||
psp.lParam = (LPARAM) schema;
|
||||
|
||||
return CreatePropertySheetPage(&psp);
|
||||
}
|
||||
|
||||
static INT_PTR CALLBACK eam_ui_dlg_proc(HWND hwnd, UINT msg, WPARAM wparam,
|
||||
LPARAM lparam)
|
||||
{
|
||||
const NMHDR *n;
|
||||
|
||||
switch (msg) {
|
||||
case WM_INITDIALOG:
|
||||
return eam_ui_handle_init(hwnd, (PROPSHEETPAGE *) lparam);
|
||||
|
||||
case WM_TIMER:
|
||||
return eam_ui_handle_tick(hwnd);
|
||||
|
||||
case WM_COMMAND:
|
||||
switch (HIWORD(wparam)) {
|
||||
case BN_CLICKED:
|
||||
switch (LOWORD(wparam)) {
|
||||
case IDC_AUTOGEN:
|
||||
return eam_ui_handle_change_autogen(hwnd);
|
||||
|
||||
case IDC_ALT_10K:
|
||||
return eam_ui_handle_change_alt_10k(hwnd);
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
case WM_NOTIFY:
|
||||
n = (NMHDR *) lparam;
|
||||
|
||||
switch (n->code) {
|
||||
case PSN_SETACTIVE:
|
||||
return eam_ui_handle_activate(hwnd);
|
||||
|
||||
case PSN_KILLACTIVE:
|
||||
return eam_ui_handle_passivate(hwnd);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
|
||||
case WM_DESTROY:
|
||||
return eam_ui_handle_fini(hwnd);
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static INT_PTR eam_ui_handle_init(HWND hwnd, const PROPSHEETPAGE *psp)
|
||||
{
|
||||
struct eam_ui *ui;
|
||||
const struct schema *schema;
|
||||
long ypos;
|
||||
size_t i;
|
||||
HINSTANCE inst;
|
||||
HWND child;
|
||||
RECT r;
|
||||
|
||||
ui = xmalloc(sizeof(*ui));
|
||||
array_init(&ui->children);
|
||||
|
||||
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LPARAM) ui);
|
||||
|
||||
inst = (HINSTANCE) GetWindowLongPtr(hwnd, GWLP_HINSTANCE);
|
||||
schema = (struct schema *) psp->lParam;
|
||||
|
||||
ypos = 0;
|
||||
|
||||
for (i = 0 ; i < schema->nunits ; i++) {
|
||||
child = CreateDialogParam(inst, MAKEINTRESOURCE(IDD_READER), hwnd,
|
||||
eam_unit_ui_dlg_proc, (LPARAM) &schema->units[i]);
|
||||
|
||||
GetWindowRect(child, &r);
|
||||
SetWindowPos(child, HWND_BOTTOM, 0, ypos, 0, 0,
|
||||
SWP_NOSIZE | SWP_SHOWWINDOW);
|
||||
|
||||
ypos += r.bottom - r.top;
|
||||
|
||||
*array_append(HWND, &ui->children) = child;
|
||||
}
|
||||
|
||||
if (eam_io_config_api->get_autogen()) {
|
||||
SendMessage(GetDlgItem(hwnd, IDC_AUTOGEN), BM_SETCHECK, BST_CHECKED, 0);
|
||||
}
|
||||
|
||||
if (eam_io_config_api->get_alt_10k()) {
|
||||
SendMessage(GetDlgItem(hwnd, IDC_ALT_10K), BM_SETCHECK, BST_CHECKED, 0);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static INT_PTR eam_ui_handle_activate(HWND hwnd)
|
||||
{
|
||||
SetTimer(hwnd, 17, 1, NULL);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static INT_PTR eam_ui_handle_passivate(HWND hwnd)
|
||||
{
|
||||
KillTimer(hwnd, 1);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static INT_PTR eam_ui_handle_tick(HWND hwnd)
|
||||
{
|
||||
HWND child;
|
||||
struct eam_ui *ui;
|
||||
size_t i;
|
||||
|
||||
ui = (struct eam_ui *) GetWindowLongPtr(hwnd, GWLP_USERDATA);
|
||||
|
||||
mapper_update();
|
||||
|
||||
for (i = 0 ; i < ui->children.nitems ; i++) {
|
||||
child = *array_item(HWND, &ui->children, i);
|
||||
SendMessage(child, WM_USER, 0, 0);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static INT_PTR eam_ui_handle_change_alt_10k(HWND hwnd)
|
||||
{
|
||||
HWND btn;
|
||||
bool alt_10k;
|
||||
|
||||
btn = GetDlgItem(hwnd, IDC_ALT_10K);
|
||||
alt_10k = SendMessage(btn, BM_GETCHECK, 0, 0) == BST_CHECKED;
|
||||
|
||||
eam_io_config_api->set_alt_10k(alt_10k);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static INT_PTR eam_ui_handle_change_autogen(HWND hwnd)
|
||||
{
|
||||
HWND btn;
|
||||
bool autogen;
|
||||
|
||||
btn = GetDlgItem(hwnd, IDC_AUTOGEN);
|
||||
autogen = SendMessage(btn, BM_GETCHECK, 0, 0) == BST_CHECKED;
|
||||
|
||||
eam_io_config_api->set_autogen(autogen);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static INT_PTR eam_ui_handle_fini(HWND hwnd)
|
||||
{
|
||||
struct eam_ui *ui;
|
||||
|
||||
ui = (struct eam_ui *) GetWindowLongPtr(hwnd, GWLP_USERDATA);
|
||||
|
||||
array_fini(&ui->children);
|
||||
free(ui);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static INT_PTR CALLBACK eam_unit_ui_dlg_proc(HWND hwnd, UINT msg, WPARAM wparam,
|
||||
LPARAM lparam)
|
||||
{
|
||||
switch (msg) {
|
||||
case WM_INITDIALOG:
|
||||
return eam_unit_ui_handle_init(hwnd,
|
||||
(struct eam_unit_def *) lparam);
|
||||
|
||||
case WM_USER:
|
||||
return eam_unit_ui_handle_tick(hwnd);
|
||||
|
||||
case WM_COMMAND:
|
||||
switch (LOWORD(wparam)) {
|
||||
case IDC_KBD_DEVICE:
|
||||
switch (HIWORD(wparam)) {
|
||||
case CBN_SELCHANGE:
|
||||
return eam_unit_ui_handle_change_device(hwnd);
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
case IDC_BROWSE:
|
||||
switch (HIWORD(wparam)) {
|
||||
case BN_CLICKED:
|
||||
return eam_unit_ui_handle_browse(hwnd);
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
case WM_DESTROY:
|
||||
return eam_unit_ui_handle_fini(hwnd);
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static INT_PTR eam_unit_ui_handle_init(HWND hwnd,
|
||||
const struct eam_unit_def *def)
|
||||
{
|
||||
struct eam_unit_ui *ui;
|
||||
wchar_t str[128];
|
||||
HINSTANCE inst;
|
||||
|
||||
inst = (HINSTANCE) GetWindowLongPtr(hwnd, GWLP_HINSTANCE);
|
||||
|
||||
LoadString(inst, def->label_rsrc, str, lengthof(str));
|
||||
SetWindowText(GetDlgItem(hwnd, IDC_GROUP), str);
|
||||
|
||||
ui = xmalloc(sizeof(*ui));
|
||||
ui->def = def;
|
||||
array_init(&ui->devs);
|
||||
|
||||
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LPARAM) ui);
|
||||
|
||||
eam_unit_ui_handle_init_devs(hwnd);
|
||||
eam_unit_ui_handle_init_path(hwnd);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void eam_unit_ui_handle_init_devs(HWND hwnd)
|
||||
{
|
||||
struct eam_unit_ui *ui;
|
||||
uint32_t dev_usage;
|
||||
wchar_t *dev_name;
|
||||
struct hid_stub *hid;
|
||||
size_t nchars;
|
||||
LRESULT index;
|
||||
HWND dev_list;
|
||||
|
||||
ui = (struct eam_unit_ui *) GetWindowLongPtr(hwnd, GWLP_USERDATA);
|
||||
dev_list = GetDlgItem(hwnd, IDC_KBD_DEVICE);
|
||||
|
||||
*array_append(struct hid_stub *, &ui->devs) = NULL;
|
||||
SendMessage(dev_list, CB_ADDSTRING, 0, (LPARAM) TEXT(""));
|
||||
|
||||
hid_mgr_lock();
|
||||
|
||||
for (hid = hid_mgr_get_first_stub()
|
||||
; hid != NULL
|
||||
; hid = hid_mgr_get_next_stub(hid)) {
|
||||
if (!hid_stub_get_device_usage(hid, &dev_usage)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (dev_usage != KBD_DEVICE_USAGE_KEYBOARD
|
||||
&& dev_usage != KBD_DEVICE_USAGE_KEYPAD) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!hid_stub_get_name(hid, NULL, &nchars)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
dev_name = xmalloc(nchars * sizeof(*dev_name));
|
||||
|
||||
if (!hid_stub_get_name(hid, dev_name, &nchars)) {
|
||||
free(dev_name);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
index = SendMessage(dev_list, CB_ADDSTRING, 0, (LPARAM) dev_name);
|
||||
|
||||
free(dev_name);
|
||||
|
||||
*array_append(struct hid_stub *, &ui->devs) = hid;
|
||||
|
||||
if (hid == eam_io_config_api->get_keypad_device(ui->def->unit_no)) {
|
||||
SendMessage(dev_list, CB_SETCURSEL, index, 0);
|
||||
}
|
||||
}
|
||||
|
||||
hid_mgr_unlock();
|
||||
}
|
||||
|
||||
static void eam_unit_ui_handle_init_path(HWND hwnd)
|
||||
{
|
||||
struct eam_unit_ui *ui;
|
||||
const char *path;
|
||||
wchar_t *wpath;
|
||||
|
||||
ui = (struct eam_unit_ui *) GetWindowLongPtr(hwnd, GWLP_USERDATA);
|
||||
path = eam_io_config_api->get_card_path(ui->def->unit_no);
|
||||
|
||||
if (path != NULL) {
|
||||
wpath = str_widen(path);
|
||||
SetWindowText(GetDlgItem(hwnd, IDC_CARD_PATH), wpath);
|
||||
free(wpath);
|
||||
}
|
||||
}
|
||||
|
||||
static INT_PTR eam_unit_ui_handle_browse(HWND hwnd)
|
||||
{
|
||||
struct eam_unit_ui *ui;
|
||||
char *path_tmp;
|
||||
OPENFILENAME ofn;
|
||||
TCHAR path[MAX_PATH];
|
||||
HWND path_ctl;
|
||||
|
||||
ui = (struct eam_unit_ui *) GetWindowLongPtr(hwnd, GWLP_USERDATA);
|
||||
path_ctl = GetDlgItem(hwnd, IDC_CARD_PATH);
|
||||
|
||||
path[0] = 0;
|
||||
GetWindowText(path_ctl, path, lengthof(path));
|
||||
|
||||
memset(&ofn, 0, sizeof(ofn));
|
||||
ofn.lStructSize = sizeof(ofn);
|
||||
ofn.hwndOwner = hwnd;
|
||||
ofn.lpstrFile = path;
|
||||
ofn.nMaxFile = lengthof(path);
|
||||
ofn.Flags = OFN_DONTADDTORECENT | OFN_ENABLESIZING | OFN_EXPLORER;
|
||||
|
||||
if (GetOpenFileName(&ofn) && wstr_narrow(path, &path_tmp)) {
|
||||
eam_io_config_api->set_card_path(ui->def->unit_no, path_tmp);
|
||||
free(path_tmp);
|
||||
|
||||
SendMessage(path_ctl, WM_SETTEXT, 0, (LPARAM) path);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static INT_PTR eam_unit_ui_handle_change_device(HWND hwnd)
|
||||
{
|
||||
struct eam_unit_ui *ui;
|
||||
struct hid_stub *hid;
|
||||
HWND dev_list;
|
||||
LRESULT index;
|
||||
|
||||
ui = (struct eam_unit_ui *) GetWindowLongPtr(hwnd, GWLP_USERDATA);
|
||||
dev_list = GetDlgItem(hwnd, IDC_KBD_DEVICE);
|
||||
|
||||
index = SendMessage(dev_list, CB_GETCURSEL, 0, 0);
|
||||
|
||||
if (index != CB_ERR) {
|
||||
log_assert((size_t) index < ui->devs.nitems);
|
||||
|
||||
hid = *array_item(struct hid_stub *, &ui->devs, index);
|
||||
eam_io_config_api->set_keypad_device(ui->def->unit_no, hid);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static INT_PTR eam_unit_ui_handle_tick(HWND hwnd)
|
||||
{
|
||||
struct eam_unit_ui *ui;
|
||||
uint16_t state;
|
||||
wchar_t state_str[9];
|
||||
|
||||
ui = (struct eam_unit_ui *) GetWindowLongPtr(hwnd, GWLP_USERDATA);
|
||||
state = eam_io_get_keypad_state(ui->def->unit_no);
|
||||
|
||||
wstr_format(state_str, lengthof(state_str), L"%04x", state);
|
||||
|
||||
SetWindowText(GetDlgItem(hwnd, IDC_KEYPAD_STATE), state_str);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static INT_PTR eam_unit_ui_handle_fini(HWND hwnd)
|
||||
{
|
||||
struct eam_unit_ui *ui;
|
||||
wchar_t path[MAX_PATH];
|
||||
char *tmp;
|
||||
|
||||
ui = (struct eam_unit_ui *) GetWindowLongPtr(hwnd, GWLP_USERDATA);
|
||||
|
||||
path[0] = 0;
|
||||
GetWindowText(GetDlgItem(hwnd, IDC_CARD_PATH), path, lengthof(path));
|
||||
|
||||
if (path[0]) {
|
||||
if (wstr_narrow(path, &tmp)) {
|
||||
eam_io_config_api->set_card_path(ui->def->unit_no, tmp);
|
||||
free(tmp);
|
||||
}
|
||||
} else {
|
||||
eam_io_config_api->set_card_path(ui->def->unit_no, NULL);
|
||||
}
|
||||
|
||||
array_fini(&ui->devs);
|
||||
free(ui);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user