Files
Justin Marshall 7806bb8ef8 Added uisrc.
2026-04-27 10:37:37 -07:00

770 lines
20 KiB
C++

//****************************************************************************
// SelModem.cpp
// Diablo UI select modem from a list of modems
//
// By Frank Pearce
// created 11.22.96
//****************************************************************************
#include "pch.h"
#include "artfont.h"
#include "uisnd.h"
//****************************************************************************
//****************************************************************************
extern int SelOkDialog(HWND parent, LPCTSTR text, LPCTSTR title, BOOL loadfocus);
extern BOOL CALLBACK ModmStatStatusCallback(
LPCSTR statstr,
DWORD completed,
DWORD remaining,
DWORD flags,
SNETABORTPROC abortfcn
);
//****************************************************************************
//****************************************************************************
#define OLDPROCPROP TEXT("UIOLDPROC")
#define MILLISEC_PER_SEC 1000
#define FOCUS_TIMER_ID 1
#define FOCUS_FPS 16 // frames per second
#define FOCUS_TIMER_DELAY 55 //(MILLISEC_PER_SEC / FOCUS_FPS)
#define MAX_VISIBLE (IDC_MODEMBTN6 - IDC_MODEMBTN1 + 1)
//****************************************************************************
//****************************************************************************
static TPMODEM sgModemList;
static int sgNumModems;
static DWORD sgDeviceID;
static SNETPROGRAMDATAPTR sgSMProgramData;
static SNETPLAYERDATAPTR sgSMPlayerData;
static SNETUIDATAPTR sgSMInterfaceData;
static SNETVERSIONDATAPTR sgSMVersionData;
static int sgTextIDs[] = {
IDC_DLGTITLE,
0
};
static int sgText2IDs[] = {
IDC_DLGTITLE2,
IDC_DLGTITLE3,
0
};
static int sgDescID[] = {
IDC_REQDESC,
0
};
static int sgBtnIDs[] = {
IDC_FAKEOK,
IDC_FAKECANCEL,
0
};
static int sgListIDs[] = {
IDC_MODEMBTN1,
IDC_MODEMBTN2,
IDC_MODEMBTN3,
IDC_MODEMBTN4,
IDC_MODEMBTN5,
IDC_MODEMBTN6,
0
};
//****************************************************************************
//****************************************************************************
static TPMODEM ModemAllocNode(void) {
return (TPMODEM) ALLOC(sizeof(TMODEM));
}
//****************************************************************************
//****************************************************************************
static void ModemFreeNode(TPMODEM node) {
if (node) FREE(node);
}
//****************************************************************************
//****************************************************************************
static void ModemFreeList(TPMODEM list) {
TPMODEM next;
while (list) {
next = list->next;
ModemFreeNode(list);
list = next;
}
}
//****************************************************************************
//****************************************************************************
static TPMODEM ModemAddNode(TPMODEM list, TPMODEM node) {
node->next = list;
return node;
}
//****************************************************************************
//****************************************************************************
static TPMODEM ModemFindNode(TPMODEM list, DWORD deviceid) {
while (list) {
if (list->deviceid == deviceid)
break;
list = list->next;
}
return list;
}
//****************************************************************************
//****************************************************************************
static BOOL CALLBACK SelModemEnum(DWORD deviceid,
LPCSTR devicename,
LPCSTR devicedesc) {
TPMODEM modem;
modem = ModemAllocNode();
if (! modem) return FALSE;
modem->next = NULL;
modem->deviceid = deviceid;
strcpy(modem->devicename, devicename);
strcpy(modem->devicedesc, devicedesc);
sgModemList = ModemAddNode(sgModemList, modem);
sgNumModems++;
return TRUE;
}
//****************************************************************************
//****************************************************************************
static void SelModemDestroy(HWND window) {
SbarDestroy(window, IDC_SCROLLBAR);
UiDoomCtrlsDestroy(window, sgListIDs);
UiDoomCtrlsDestroy(window, sgBtnIDs);
UiDoomCtrlsDestroy(window, sgTextIDs);
UiDoomCtrlsDestroy(window, sgText2IDs);
UiDoomCtrlsDestroy(window, sgDescID);
// free the background of the dlg
UiFreeBmp((TPBMP) GetWindowLong(window, GWL_USERDATA));
SetWindowLong(window, GWL_USERDATA, (LONG) 0);
}
//****************************************************************************
//****************************************************************************
static void SelModemSetList(HWND window, TPMODEM firstmodem) {
HWND child;
TPBMP tpBmp;
int *ListID;
for (ListID = sgListIDs; *ListID; ListID++) {
child = GetDlgItem(window, *ListID);
if (! child)
continue;
if (! firstmodem) {
EnableWindow(child, FALSE);
continue;
}
EnableWindow(child, TRUE);
tpBmp = (TPBMP) GetWindowLong(child, GWL_USERDATA);
UiSetBmpText(tpBmp, firstmodem->devicename);
if (tpBmp)
tpBmp->userdata = (LONG) firstmodem;
firstmodem = firstmodem->next;
}
UiDoomButtonsReset(window, sgListIDs, AF_SMALL);
}
//****************************************************************************
//****************************************************************************
static void SelModemTab(HWND child) {
HWND parent, newfocus;
int index;
int NewID[] = {
IDC_MODEMBTN2,
IDC_MODEMBTN3,
IDC_MODEMBTN4,
IDC_MODEMBTN5,
IDC_MODEMBTN6,
IDC_MODEMBTN1
};
parent = GetParent(child);
newfocus = child;
do {
index = GetWindowLong(newfocus, GWL_ID) - IDC_MODEMBTN1;
newfocus = GetDlgItem(parent, NewID[index]);
} while (! IsWindowEnabled(newfocus));
SetFocus(newfocus);
}
//****************************************************************************
//****************************************************************************
static void SelModemShiftTab(HWND child) {
HWND parent, newfocus;
int index;
int NewID[] = {
IDC_MODEMBTN6,
IDC_MODEMBTN1,
IDC_MODEMBTN2,
IDC_MODEMBTN3,
IDC_MODEMBTN4,
IDC_MODEMBTN5
};
parent = GetParent(child);
newfocus = child;
do {
index = GetWindowLong(newfocus, GWL_ID) - IDC_MODEMBTN1;
newfocus = GetDlgItem(parent, NewID[index]);
} while (! IsWindowEnabled(newfocus));
SetFocus(newfocus);
}
//****************************************************************************
//****************************************************************************
static int GetNumNode(HWND btn) {
if (! btn) return 0;
TPBMP tpBmp = (TPBMP) GetWindowLong(btn, GWL_USERDATA);
if (! tpBmp) return 0;
TPMODEM list = sgModemList;
if (! list) return 0;
TPMODEM node = (TPMODEM) tpBmp->userdata;
if (! node) return 0;
int nodenum = 0;
while (list && (list != node)) {
nodenum++;
list = list->next;
}
return nodenum;
}
//****************************************************************************
//****************************************************************************
static TPMODEM GetModem(int index) {
TPMODEM list = sgModemList;
while (list && index) {
list = list->next;
index--;
}
return list;
}
//****************************************************************************
//****************************************************************************
static void SelModemUpdateSbar(HWND window) {
SbarDraw(window, IDC_SCROLLBAR, sgNumModems, GetNumNode(GetFocus()));
}
//****************************************************************************
//****************************************************************************
static void SelModemPageDown(HWND focus) {
HWND parent = GetParent(focus);
if (! parent) return;
// get info of 1st btn
HWND btn1 = GetDlgItem(parent, IDC_MODEMBTN1);
if (! btn1) return;
// see if there is info below the bottom
TPBMP tpBmp = (TPBMP) GetWindowLong(GetDlgItem(parent, IDC_MODEMBTN6), GWL_USERDATA);
if (! tpBmp) return;
TPMODEM tpModem = (TPMODEM) tpBmp->userdata;
if ((! tpModem) || (! tpModem->next)) {
SelModemShiftTab(btn1);
return;
}
// calc the index of the new top
int newtop = GetNumNode(btn1) + MAX_VISIBLE;
if (newtop > (sgNumModems - MAX_VISIBLE))
newtop = sgNumModems - MAX_VISIBLE;
// get the pointer to that index
tpModem = GetModem(newtop);
if (! tpModem) return;
// update everything on the screen
UiSndPlayClick();
SelModemSetList(parent, tpModem);
SelModemUpdateSbar(parent);
}
//****************************************************************************
//****************************************************************************
static void SelModemPageUp(HWND focus) {
HWND parent = GetParent(focus);
if (! parent) return;
HWND btn1 = GetDlgItem(parent, IDC_MODEMBTN1);
if (! btn1) return;
// see if there is info off the top
TPBMP tpBmp = (TPBMP) GetWindowLong(btn1, GWL_USERDATA);
if (! tpBmp) return;
TPMODEM tpModem = (TPMODEM) tpBmp->userdata;
if (! tpModem) return;
if (tpModem == sgModemList) {
SelModemTab(GetDlgItem(parent, IDC_MODEMBTN6));
return;
}
// calc the index of the new top
int newtop = GetNumNode(btn1) - MAX_VISIBLE;
if (newtop < 0)
newtop = 0;
// get the pointer to that index
tpModem = GetModem(newtop);
if (! tpModem) return;
// update everything on the screen
UiSndPlayClick();
SelModemSetList(parent, tpModem);
SelModemUpdateSbar(parent);
}
//****************************************************************************
//****************************************************************************
static void SelModemScrollDown(HWND focus) {
// see if there is info below the focus
TPBMP tpBmp = (TPBMP) GetWindowLong(focus, GWL_USERDATA);
if (! tpBmp) return;
TPMODEM tpModem = (TPMODEM) tpBmp->userdata;
if (! tpModem) return;
if (! tpModem->next) return;
if (GetWindowLong(focus, GWL_ID) < IDC_MODEMBTN6) {
// handle it just like a tab
SelModemTab(focus);
return;
}
// advance the list
HWND child = GetDlgItem(GetParent(focus), IDC_MODEMBTN2);
if (! child) return;
tpBmp = (TPBMP) GetWindowLong(child, GWL_USERDATA);
if (! tpBmp) return;
tpModem = (TPMODEM) tpBmp->userdata;
if (! tpModem) return;
UiSndPlayClick();
SelModemSetList(GetParent(focus), tpModem);
SelModemUpdateSbar(GetParent(focus));
}
//****************************************************************************
//****************************************************************************
static void SelModemScrollUp(HWND focus) {
if (GetWindowLong(focus, GWL_ID) > IDC_MODEMBTN1) {
// handle it just like a shift-tab
SelModemShiftTab(focus);
return;
}
// see if there is info off the top
TPBMP tpBmp = (TPBMP) GetWindowLong(focus, GWL_USERDATA);
if (! tpBmp) return;
TPMODEM tpModem = (TPMODEM) tpBmp->userdata;
TPMODEM tpModemList;
if (! tpModem) return;
if (tpModem == (tpModemList = sgModemList)) return;
// retreat the list
while (tpModemList && (tpModemList->next != tpModem)) {
tpModemList = tpModemList->next;
}
UiSndPlayClick();
SelModemSetList(GetParent(focus), tpModemList);
SelModemUpdateSbar(GetParent(focus));
}
//****************************************************************************
//****************************************************************************
static LRESULT CALLBACK ModemListWndProc (HWND window,
UINT message,
WPARAM wparam,
LPARAM lparam) {
LRESULT result;
WNDPROC oldproc = (WNDPROC) GetProp(window, OLDPROCPROP);
switch (message) {
case WM_GETDLGCODE:
return DLGC_WANTALLKEYS;
case WM_KEYDOWN:
switch (wparam) {
case VK_SPACE:
case VK_RETURN:
SendMessage(GetParent(window), WM_COMMAND, IDOK, (LPARAM)NULL);
break;
case VK_ESCAPE:
SendMessage(GetParent(window), WM_COMMAND, IDCANCEL, (LPARAM)NULL);
break;
case VK_TAB:
if (GetKeyState(VK_SHIFT) < 0) {
SelModemShiftTab(window);
}
else {
SelModemTab(window);
}
break;
case VK_UP:
case VK_LEFT:
SelModemScrollUp(window);
break;
case VK_DOWN:
case VK_RIGHT:
SelModemScrollDown(window);
break;
case VK_PRIOR:
SelModemPageUp(window);
break;
case VK_NEXT:
SelModemPageDown(window);
break;
}
return 0;
case WM_DESTROY:
RemoveProp(window, OLDPROCPROP);
if (oldproc) {
SetWindowLong(window, GWL_WNDPROC, (LONG) oldproc);
}
break;
case WM_PAINT:
UiPaintBtn(window);
return 0;
}
if (oldproc)
result = CallWindowProc(oldproc, window, message, wparam, lparam);
else
result = DefWindowProc(window, message, wparam, lparam);
return result;
}
//****************************************************************************
//****************************************************************************
static void SelModemSubclassEntries(HWND window) {
HWND child;
int *ListID;
WNDPROC oldproc;
for (ListID = sgListIDs; *ListID; ListID++) {
child = GetDlgItem(window, *ListID);
if (! child) continue;
oldproc = (WNDPROC) GetWindowLong(child, GWL_WNDPROC);
SetProp(child, OLDPROCPROP,(HANDLE) oldproc);
SetWindowLong(child, GWL_WNDPROC, (LONG) ModemListWndProc);
}
}
//****************************************************************************
//****************************************************************************
static void SelModemInit(HWND window) {
HWND parent = GetParent(window);
SelModemSubclassEntries(window);
// load texture maps for this dialog
TPBMP tpBmp = UiAllocBmp();
if (tpBmp) {
SetWindowLong(window, GWL_USERDATA, (LONG) tpBmp);
LoadArtFile(
window,
NULL,
TEXT("popup"),
SDLG_STYLE_ANY,
SDLG_USAGE_BACKGROUND,
TEXT("ui_art\\seldiff.pcx"),
&tpBmp->data,
&tpBmp->datasize,
FALSE
);
}
// set up a doom-like interface
UiDoomStaticInit(window, sgDescID, AF_SMALLGRAY);
UiDoomStaticInit(window, sgText2IDs, AF_MEDGRAY);
UiDoomStaticInit(window, sgTextIDs, AF_BIGGRAY);
UiDoomButtonsInit(window, sgBtnIDs, AF_BIG, FALSE);
UiDoomButtonsInit(window, sgListIDs, AF_SMALL);
// set the names into the fake listbox
SelModemSetList(window, sgModemList);
// set up the animating focus indicator
SDlgSetTimer(window, FOCUS_TIMER_ID, FOCUS_TIMER_DELAY, NULL);
// init the scroll bar
SbarInit(window, IDC_SCROLLBAR);
if (sgNumModems <= MAX_VISIBLE) {
ShowWindow(GetDlgItem(window, IDC_SCROLLBAR), FALSE);
}
}
//****************************************************************************
//****************************************************************************
static void SelModemAbort(HWND window, int ReturnVal) {
UiSndPlayEnter();
SDlgKillTimer(window, FOCUS_TIMER_ID);
if (ReturnVal == IDOK) {
// get the id of the selected device
HWND focus = GetFocus();
if (focus) {
TPBMP tpBmp = (TPBMP) GetWindowLong(focus, GWL_USERDATA);
if (tpBmp) {
TPMODEM tpModem = (TPMODEM) tpBmp->userdata;
if (tpModem) {
sgDeviceID = tpModem->deviceid;
}
}
}
}
SDlgEndDialog(window, ReturnVal);
}
//****************************************************************************
//****************************************************************************
static void SelModemInterpretClick(HWND window, int x, int y) {
if (UiIsPtInWindow(window, GetDlgItem(window, IDC_FAKEOK), x, y)) {
SelModemAbort(window, IDOK);
}
else if (UiIsPtInWindow(window, GetDlgItem(window, IDC_FAKECANCEL), x, y)) {
SelModemAbort(window, IDCANCEL);
}
else if (UiIsPtInWindow(window, GetDlgItem(window, IDC_SCROLLBAR), x, y)) {
int SbarClick = SbarInterpretClick(GetDlgItem(window, IDC_SCROLLBAR), x, y);
switch (SbarClick) {
case DSB_UP:
SelModemScrollUp(GetFocus());
break;
case DSB_DOWN:
SelModemScrollDown(GetFocus());
break;
case DSB_PAGEUP:
SelModemPageUp(GetFocus());
break;
case DSB_PAGEDOWN:
SelModemPageDown(GetFocus());
break;
default:
break;
}
}
}
//****************************************************************************
//****************************************************************************
static BOOL CALLBACK SelModemDialogProc(HWND window,
UINT message,
WPARAM wparam,
LPARAM lparam) {
switch (message) {
case WM_COMMAND:
if (HIWORD(wparam) == BN_KILLFOCUS) {
FocusLost(window, (HWND) lparam);
}
else if (HIWORD(wparam) == BN_SETFOCUS) {
FocusSnd((HWND) lparam);
FocusAnimate(window, (HWND) lparam);
SelModemUpdateSbar(window);
}
else if (HIWORD(wparam) == BN_DOUBLECLICKED) {
SelModemAbort(window, IDOK);
}
else if (LOWORD(wparam) == IDOK) {
SelModemAbort(window, IDOK);
}
else if (LOWORD(wparam) == IDCANCEL) {
SelModemAbort(window, IDCANCEL);
}
break;
case WM_LBUTTONDBLCLK:
case WM_LBUTTONDOWN:
SelModemInterpretClick(window, LOWORD(lparam), HIWORD(lparam));
break;
case WM_LBUTTONUP:
if (SbarUpClick(GetDlgItem(window, IDC_SCROLLBAR))) {
SelModemUpdateSbar(window);
}
break;
case WM_DESTROY:
SelModemDestroy(window);
break;
case WM_INITDIALOG:
SelModemInit(window);
return 0;
case WM_TIMER:
FocusAnimate(window, GetFocus());
return 0;
case WM_SYSKEYUP:
case WM_SYSKEYDOWN:
SendMessage(SDrawGetFrameWindow(), message, wparam, lparam);
break;
}
return SDlgDefDialogProc(window,message,wparam,lparam);
}
//****************************************************************************
//****************************************************************************
static BOOL SelModemInitDevice(HWND window, DWORD deviceid) {
SNETUIDATA uidata;
// create new interface data
CopyMemory(&uidata,sgSMInterfaceData,sizeof(SNETUIDATA));
uidata.statuscallback = ModmStatStatusCallback;
uidata.size = sizeof(SNETUIDATA);
uidata.parentwindow = window;
return SNetInitializeDevice(
deviceid,
sgSMProgramData,
sgSMPlayerData,
&uidata,
sgSMVersionData
);
}
//****************************************************************************
//****************************************************************************
static BOOL SelModemNoModem(DWORD providerid) {
if (providerid == 'MODM') {
TCHAR err[128];
LoadString(global_hinstance, IDS_NOMODEM_ERR, err, 127);
SelOkDialog(sgSMInterfaceData->parentwindow, err, NULL, FALSE);
return FALSE;
}
else {
return TRUE;
}
}
//****************************************************************************
//****************************************************************************
static BOOL SelModemOneModem(void) {
if (SelModemInitDevice(sgSMInterfaceData->parentwindow, sgModemList->deviceid)) {
ModemFreeList(sgModemList);
return TRUE;
}
else {
// error initializing modem
TCHAR initerr[128];
LoadString(global_hinstance, IDS_INITMODEM_ERR, initerr, 127);
SelOkDialog(sgSMInterfaceData->parentwindow, initerr, NULL, FALSE);
ModemFreeList(sgModemList);
return TRUE;
}
}
//****************************************************************************
//****************************************************************************
static BOOL SelModemListModems(void) {
int result = SDlgDialogBox(
global_hinstance,
TEXT("SELMODEM_DIALOG"),
sgSMInterfaceData->parentwindow,
SelModemDialogProc
);
if (result == IDOK) {
if (SelModemInitDevice(sgSMInterfaceData->parentwindow, sgDeviceID)) {
ModemFreeList(sgModemList);
return TRUE;
}
else {
// error initializing device
TCHAR initerr[128];
LoadString(global_hinstance, IDS_INITMODEM_ERR, initerr, 127);
SelOkDialog(sgSMInterfaceData->parentwindow, initerr, NULL, FALSE);
ModemFreeList(sgModemList);
return FALSE;
}
}
else {
// user cancelled
ModemFreeList(sgModemList);
SetLastError(SNET_ERROR_CANCELLED);
return FALSE;
}
}
//****************************************************************************
//****************************************************************************
BOOL UiSelectDevice(DWORD providerid,
SNETPROGRAMDATAPTR programdata,
SNETPLAYERDATAPTR playerdata,
SNETUIDATAPTR interfacedata,
SNETVERSIONDATAPTR versiondata) {
sgSMProgramData = programdata;
sgSMPlayerData = playerdata;
sgSMInterfaceData = interfacedata;
sgSMVersionData = versiondata;
// enum all devices
sgModemList = NULL;
sgNumModems = 0;
SNetEnumDevices(SelModemEnum);
switch (sgNumModems) {
case 0:
return SelModemNoModem(providerid);
case 1:
return SelModemOneModem();
default:
return SelModemListModems();
}
}