514 lines
16 KiB
C
514 lines
16 KiB
C
|
/*===========================================================================*/
|
||
|
/* */
|
||
|
/* Windows DynaComm version 1.x -- Dynamic Communications for Windows 2.x */
|
||
|
/* */
|
||
|
/* Copyright (c) 1987 - 1988, Future Soft Engineering, Inc. */
|
||
|
/* Houston, Texas */
|
||
|
/*---------------------------------------------------------------------------*/
|
||
|
/* This material is an unpublished work containing trade secrets which are */
|
||
|
/* the property of Future Soft Engineering, Inc., and is subject to a */
|
||
|
/* license therefrom. It may not be disclosed, reproduced, adapted, merged, */
|
||
|
/* translated, or used in any manner without prior written consent from FSE. */
|
||
|
/*===========================================================================*/
|
||
|
|
||
|
#define NOLSTRING TRUE /* jtf win3 mod */
|
||
|
#include <windows.h>
|
||
|
#include "port1632.h"
|
||
|
#include "dcrc.h"
|
||
|
#include "dynacomm.h"
|
||
|
#include "task.h"
|
||
|
#include "dcdata.h"
|
||
|
#include "video.h"
|
||
|
#include "printfil.h"
|
||
|
|
||
|
|
||
|
/*---------------------------------------------------------------------------*/
|
||
|
/* mainProcess() - main process loop; called from _INITCODE:WINMAIN [mbb] */
|
||
|
/*---------------------------------------------------------------------------*/
|
||
|
|
||
|
VOID FAR mainProcess()
|
||
|
{
|
||
|
DWORD dwThreadID;
|
||
|
|
||
|
doneFlag =
|
||
|
gbThreadDoneFlag = FALSE;
|
||
|
CommThreadExit = FALSE;
|
||
|
dwTimerRes = 100;
|
||
|
|
||
|
commThread = CreateThread(NULL, 0, checkCommEvent,
|
||
|
IntToPtr(dwTimerRes), CREATE_SUSPENDED | STANDARD_RIGHTS_REQUIRED,
|
||
|
&dwThreadID);
|
||
|
|
||
|
if (commThread)
|
||
|
{
|
||
|
SetThreadPriority(commThread, THREAD_PRIORITY_BELOW_NORMAL);
|
||
|
ResumeThread(commThread);
|
||
|
}
|
||
|
|
||
|
overlapEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||
|
hMutex = CreateMutex(NULL, FALSE, NULL);
|
||
|
|
||
|
repeat
|
||
|
{
|
||
|
mainEventLoop();
|
||
|
}
|
||
|
until(doneFlag);
|
||
|
|
||
|
// terminate threads here, not just close handles!!!!
|
||
|
|
||
|
// TerminateThread(hwndThread, (DWORD)0);
|
||
|
// CloseHandle(hwndThread);
|
||
|
|
||
|
// while(WaitForSingleObject(hMutex, 1000) != 0)
|
||
|
// {
|
||
|
// Sleep((DWORD)50);
|
||
|
// MessageBeep(0);
|
||
|
// }
|
||
|
|
||
|
if (WaitForSingleObject(hMutex, 2000) != 0)
|
||
|
{
|
||
|
// the comevent thread did not comeout in 2 sec, something wrong
|
||
|
// Just kill it and indicate by Beep (for the timebeing) that
|
||
|
// we have this wierd condition
|
||
|
MessageBeep(0);
|
||
|
TerminateThread(commThread, (DWORD)0);
|
||
|
}
|
||
|
|
||
|
else
|
||
|
{
|
||
|
// just in case if that thread as not done ExitThread(), kill it
|
||
|
// maybe this is a overkill!
|
||
|
TerminateThread(commThread, (DWORD)0);
|
||
|
ReleaseMutex(hMutex);
|
||
|
}
|
||
|
|
||
|
|
||
|
CloseHandle(commThread);
|
||
|
CloseHandle(hMutex);
|
||
|
}
|
||
|
|
||
|
|
||
|
/*---------------------------------------------------------------------------*/
|
||
|
/* mainEventLoop() - Main input from the application queue [mbb] */
|
||
|
/*---------------------------------------------------------------------------*/
|
||
|
|
||
|
VOID FAR mainEventLoop()
|
||
|
{
|
||
|
idleProcess();
|
||
|
|
||
|
if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
|
||
|
{
|
||
|
if(!IsDialogMessage(hdbmyControls, &msg) &&
|
||
|
!IsDialogMessage(hdbXferCtrls, &msg))
|
||
|
{
|
||
|
DispatchMessage(&msg);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
DWORD xSndThread (LPVOID lpParameter)
|
||
|
{
|
||
|
DWORD parentId = PtrToInt(lpParameter);
|
||
|
AttachThreadInput (GetCurrentThreadId(), parentId, TRUE);
|
||
|
xSndBFile();
|
||
|
xferEnd();
|
||
|
MessageBeep(10);
|
||
|
gbXferActive = FALSE;
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
DWORD xRcvThread (LPVOID lpParameter)
|
||
|
{
|
||
|
DWORD parentId = PtrToInt(lpParameter);
|
||
|
AttachThreadInput (GetCurrentThreadId(), parentId, TRUE);
|
||
|
xRcvBFile();
|
||
|
xferEnd();
|
||
|
MessageBeep(10);
|
||
|
gbXferActive = FALSE;
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/*---------------------------------------------------------------------------*/
|
||
|
/* idleProcess() - [mbb] */
|
||
|
/*---------------------------------------------------------------------------*/
|
||
|
|
||
|
void APIENTRY idleProcess(VOID)
|
||
|
{
|
||
|
// sdj: was unref local - LONG secs;
|
||
|
// sdj: was unref local - LONG finalTicks;
|
||
|
// sdj: was unref local - HWND hwnd;
|
||
|
|
||
|
static HANDLE hThread;
|
||
|
static DWORD dwId;
|
||
|
|
||
|
|
||
|
updateTimer();
|
||
|
|
||
|
if(!gbXferActive)
|
||
|
{
|
||
|
if (xferFlag == XFRBSND)
|
||
|
{
|
||
|
gbXferActive = TRUE;
|
||
|
hThread = CreateThread (NULL,
|
||
|
0,
|
||
|
xSndThread,
|
||
|
IntToPtr(GetCurrentThreadId()),
|
||
|
TRUE,
|
||
|
&dwId);
|
||
|
}
|
||
|
else if(xferFlag == XFRBRCV)
|
||
|
{
|
||
|
gbXferActive = TRUE;
|
||
|
hThread = CreateThread (NULL,
|
||
|
0,
|
||
|
xRcvThread,
|
||
|
IntToPtr(GetCurrentThreadId()),
|
||
|
TRUE,
|
||
|
&dwId);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (activTerm)
|
||
|
termSpecial ();
|
||
|
|
||
|
if(mdmConnect())
|
||
|
{
|
||
|
modemReset();
|
||
|
timerAction(mdmOnLine, mdmOnLine); /* mbbx 1.03 */
|
||
|
}
|
||
|
|
||
|
cursorAdjust();
|
||
|
if(activTerm)
|
||
|
blinkCursor();
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Sleep((DWORD)10);
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
/*---------------------------------------------------------------------------*/
|
||
|
/* updateTimer() - [mbb] */
|
||
|
/*---------------------------------------------------------------------------*/
|
||
|
|
||
|
VOID FAR updateTimer() /* mbbx 2.00: fkeys... */
|
||
|
{
|
||
|
|
||
|
#ifdef WIN32
|
||
|
WPARAM wParam;
|
||
|
#endif
|
||
|
|
||
|
/* rjs bug2 001 */
|
||
|
if(GetCurrentTime() - gIdleTimer >= 900)
|
||
|
{
|
||
|
gIdleTimer = GetCurrentTime();
|
||
|
|
||
|
if((hItWnd != NULL) && IsWindowVisible(hdbmyControls))
|
||
|
#ifdef ORGCODE
|
||
|
updateFKeyButton(MAKELONG(GetDlgItem(hdbmyControls, IDTIMER), BN_PAINT), FKB_UPDATE_TIMER);
|
||
|
#else
|
||
|
// sdj: 10/8/91 for bug#3277 changed
|
||
|
// wParam = MAKELONG(BN_PAINT, NULL); /* set HIWORD to cmd, LOWORD not used*/
|
||
|
// to:
|
||
|
wParam = MAKELONG(NULL,BN_PAINT); /* set HIWORD to cmd, LOWORD not used*/
|
||
|
|
||
|
updateFKeyButton(wParam,(LPARAM)GetDlgItem(hdbmyControls, IDTIMER), FKB_UPDATE_TIMER);
|
||
|
#endif
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*---------------------------------------------------------------------------*/
|
||
|
/* updateFKeyButton() - [mbb] */
|
||
|
/*---------------------------------------------------------------------------*/
|
||
|
|
||
|
|
||
|
/* *****NOTE NOTE ****** this function will not work under win16, as */
|
||
|
/* I removed the textExtent variable and replaced with iHeigth and iWidth */
|
||
|
/* and didn't ifdef ORGCODE around the old code (JAP)*/
|
||
|
|
||
|
BOOL updateFKeyButton(WPARAM wParam ,LPARAM lParam,WORD status) /* mbbx 2.01.163 ... */
|
||
|
{
|
||
|
BOOL updateFKeyButton = FALSE;
|
||
|
HDC hDC;
|
||
|
RECT timerRect, saveRect;
|
||
|
DOSTIME time;
|
||
|
LONG delta;
|
||
|
BYTE text[80];
|
||
|
HBRUSH hBrush, hOldBrush;
|
||
|
#ifdef ORGCODE
|
||
|
DWORD textExtent;
|
||
|
#else
|
||
|
int iHeight;
|
||
|
int iWidth;
|
||
|
#endif
|
||
|
LONG secs; /* rjs bugs 004 */
|
||
|
|
||
|
|
||
|
|
||
|
if(IsWindowVisible((HWND)GET_WM_COMMAND_HWND(wParam, lParam)))
|
||
|
{
|
||
|
hDC = GetWindowDC((HWND) GET_WM_COMMAND_HWND(wParam, lParam));
|
||
|
|
||
|
GetClientRect(GET_WM_COMMAND_HWND(wParam,lParam), (LPRECT)&timerRect);
|
||
|
CopyRect( &saveRect, &timerRect);
|
||
|
InflateRect(&timerRect, -1, -1);
|
||
|
|
||
|
switch(GET_WM_COMMAND_CMD(wParam, lParam))
|
||
|
{
|
||
|
case BN_CLICKED:
|
||
|
if(updateFKeyButton = !(status & FKB_DISABLE_CTRL))
|
||
|
{
|
||
|
InvertRect(hDC, (LPRECT) &timerRect);
|
||
|
delay(6, NULL);
|
||
|
InvertRect(hDC, (LPRECT) &timerRect);
|
||
|
}
|
||
|
else
|
||
|
sysBeep();
|
||
|
break;
|
||
|
|
||
|
case BN_PAINT:
|
||
|
if(status & FKB_UPDATE_TIMER)
|
||
|
{
|
||
|
readDateTime(&time);
|
||
|
|
||
|
if(timerActiv)
|
||
|
{
|
||
|
date2secs(&time, &delta);
|
||
|
|
||
|
date2secs(startTimer, &secs);
|
||
|
|
||
|
delta -= secs;
|
||
|
|
||
|
if(delta < 0) /* rjs - msoft 4061 */
|
||
|
{
|
||
|
delta = 0;
|
||
|
readDateTime(&startTimer);
|
||
|
}
|
||
|
|
||
|
time.hour = delta / 3600;
|
||
|
delta -= (LONG) time.hour * 3600;
|
||
|
time.minute = delta / 60;
|
||
|
time.second = delta - time.minute * 60;
|
||
|
sprintf(text, "%2.2d:%2.2d:%2.2d", time.hour, time.minute, time.second);
|
||
|
}
|
||
|
else
|
||
|
getTimeString(text, &time);
|
||
|
|
||
|
if(time.hour != lastTime.hour)
|
||
|
status |= FKB_UPDATE_BKGD;
|
||
|
}
|
||
|
else
|
||
|
SendMessage((HWND)GET_WM_COMMAND_HWND(wParam, lParam), WM_GETTEXT, 80, (LPARAM) text);
|
||
|
|
||
|
if(status & FKB_UPDATE_BKGD)
|
||
|
{
|
||
|
hBrush = CreateSolidBrush(RGB(vidAttr[ANORMAL & AMASK].bkgd[VID_RED],
|
||
|
vidAttr[ANORMAL & AMASK].bkgd[VID_GREEN],
|
||
|
vidAttr[ANORMAL & AMASK].bkgd[VID_BLUE]));
|
||
|
hOldBrush = (HBRUSH) SelectObject(hDC, hBrush);
|
||
|
|
||
|
RoundRect(hDC, timerRect.left, timerRect.top,
|
||
|
timerRect.right, timerRect.bottom, 10, 10);
|
||
|
|
||
|
SelectObject(hDC, hOldBrush);
|
||
|
DeleteObject(hBrush);
|
||
|
}
|
||
|
|
||
|
if((status & FKB_UPDATE_BKGD) || (time.second != lastTime.second))
|
||
|
{
|
||
|
InflateRect(&timerRect, -4, -1);
|
||
|
MGetTextExtent(hDC, (LPSTR) text, strlen(text), &iHeight, &iWidth);
|
||
|
SetBkColor(hDC, RGB(vidAttr[ANORMAL & AMASK].bkgd[VID_RED],
|
||
|
vidAttr[ANORMAL & AMASK].bkgd[VID_GREEN],
|
||
|
vidAttr[ANORMAL & AMASK].bkgd[VID_BLUE]));
|
||
|
|
||
|
if(!(status & FKB_DISABLE_CTRL))
|
||
|
{
|
||
|
SetTextColor(hDC, RGB(vidAttr[ANORMAL & AMASK].text[VID_RED],
|
||
|
vidAttr[ANORMAL & AMASK].text[VID_GREEN],
|
||
|
vidAttr[ANORMAL & AMASK].text[VID_BLUE]));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
SetTextColor(hDC, (COLORREF)GetSysColor(COLOR_GRAYTEXT));
|
||
|
}
|
||
|
|
||
|
DrawText(hDC, (LPSTR) text, strlen(text), (LPRECT) &timerRect,
|
||
|
(iWidth < (timerRect.right - timerRect.left)) ?
|
||
|
DT_CENTER | DT_SINGLELINE | DT_VCENTER : DT_LEFT | DT_SINGLELINE | DT_VCENTER);
|
||
|
|
||
|
if(status & FKB_UPDATE_TIMER)
|
||
|
lastTime = time;
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
ReleaseDC((HWND)GET_WM_COMMAND_HWND(wParam, lParam), hDC);
|
||
|
}
|
||
|
|
||
|
return(updateFKeyButton);
|
||
|
}
|
||
|
|
||
|
|
||
|
/*---------------------------------------------------------------------------*/
|
||
|
/* getTimeString() - [mbb] */
|
||
|
/*---------------------------------------------------------------------------*/
|
||
|
|
||
|
VOID getTimeString(BYTE *str, DOSTIME *time)
|
||
|
{
|
||
|
BYTE work[16];
|
||
|
BYTE str1[MINRESSTR], str2[MINRESSTR];
|
||
|
|
||
|
work[0] = 0;
|
||
|
|
||
|
|
||
|
//sdj: the bug is about terminal not updating the timeformat
|
||
|
//sdj: when control panel changes, it only updates while coming
|
||
|
//sdj: up, when it inits the intlData elements. To fix this
|
||
|
//sdj: update the iTime structure element before generating the
|
||
|
//sdj: string, so that it reflects the current state saved by
|
||
|
//sdj: the control panel applet. It is expensive to do this
|
||
|
//sdj: because each time the paint msg comes, getprofile is called
|
||
|
//sdj: but the other way is too complecated where you can wait
|
||
|
//sdj: for the change in this value in the registry and signal
|
||
|
//sdj: the change and call profile apis only when this flag is set
|
||
|
//sdj: saving grace is that, this performance hit is only present
|
||
|
//sdj: when bn_paint is received AND the timer mode is not on!
|
||
|
|
||
|
LoadString(hInst, STR_INI_INTL, (LPSTR) str1, MINRESSTR);
|
||
|
LoadString(hInst, STR_INI_IDATE, (LPSTR) str2, MINRESSTR);
|
||
|
intlData.iDate = GetProfileInt((LPSTR) str1, (LPSTR) str2, 0);
|
||
|
LoadString(hInst, STR_INI_SDATE, (LPSTR) str2, MINRESSTR);
|
||
|
GetProfileString((LPSTR) str1, (LPSTR) str2, (LPSTR) "/", (LPSTR) intlData.sDate, 2);
|
||
|
LoadString(hInst, STR_INI_ITIME, (LPSTR) str2, MINRESSTR);
|
||
|
intlData.iTime = GetProfileInt((LPSTR) str1, (LPSTR) str2, 0);
|
||
|
LoadString(hInst, STR_INI_STIME, (LPSTR) str2, MINRESSTR);
|
||
|
GetProfileString((LPSTR) str1, (LPSTR) str2, (LPSTR) ":", (LPSTR) intlData.sTime, 2);
|
||
|
LoadString(hInst, STR_INI_S1159, (LPSTR) str2, MINRESSTR);
|
||
|
GetProfileString((LPSTR) str1, (LPSTR) str2, (LPSTR) "AM", (LPSTR) intlData.s1159, 4);
|
||
|
LoadString(hInst, STR_INI_S2359, (LPSTR) str2, MINRESSTR);
|
||
|
GetProfileString((LPSTR) str1, (LPSTR) str2, (LPSTR) "PM", (LPSTR) intlData.s2359, 4);
|
||
|
|
||
|
|
||
|
|
||
|
if(!intlData.iTime) /* 12 Hour Clock */
|
||
|
{
|
||
|
if(time->hour < 12)
|
||
|
{
|
||
|
if(intlData.s1159[0] != 0)
|
||
|
sprintf(work, " %s", intlData.s1159);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
time->hour -= 12;
|
||
|
|
||
|
if(intlData.s2359[0] != 0)
|
||
|
sprintf(work, " %s", intlData.s2359);
|
||
|
}
|
||
|
|
||
|
if(time->hour == 0)
|
||
|
time->hour = 12;
|
||
|
}
|
||
|
|
||
|
sprintf(str, "%02d%s%02d%s%02d%s", time->hour, intlData.sTime, time->minute, intlData.sTime, time->second, work);
|
||
|
}
|
||
|
|
||
|
|
||
|
/*---------------------------------------------------------------------------*/
|
||
|
/* cursorAdjust() - Catch terminal paint up with received characters. [scf] */
|
||
|
/*---------------------------------------------------------------------------*/
|
||
|
|
||
|
VOID FAR cursorAdjust ()
|
||
|
{
|
||
|
if(termDirty || (nScroll != 0)) /* mbbx: termLine -> termDirty */
|
||
|
termCleanUp();
|
||
|
}
|
||
|
|
||
|
|
||
|
/*---------------------------------------------------------------------------*/
|
||
|
/* blinkCursor() - [scf]*/
|
||
|
/*---------------------------------------------------------------------------*/
|
||
|
|
||
|
VOID NEAR blinkCursor()
|
||
|
{
|
||
|
RECT rect;
|
||
|
|
||
|
// BUG: Does not handle timer wraparound
|
||
|
if(activTerm && (cursorOn > 0) && (GetCurrentTime() >= cursorTick)) /* mbbx 1.10: use msec... */
|
||
|
{
|
||
|
rectCursor(&rect);
|
||
|
if(cursBlinkOn && memcmp(&cursorRect, &rect, sizeof(RECT)))
|
||
|
toggleCursor(&cursorRect);
|
||
|
|
||
|
cursorRect = rect;
|
||
|
if(!cursBlinkOn || trmParams.cursorBlink) /* mbbx 1.10: CUA */
|
||
|
toggleCursor(&cursorRect);
|
||
|
cursorTick = GetCurrentTime() + GetCaretBlinkTime(); /* mbbx 1.10: lilly... */
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
/*---------------------------------------------------------------------------*/
|
||
|
/* checkInputBuffer() - support keystroke buffering (type-ahead) [mbb] */
|
||
|
/*---------------------------------------------------------------------------*/
|
||
|
#ifdef OLDCODE
|
||
|
#define MAX_INPUT_BUFFER 64 /* allows 32 keystrokes */
|
||
|
|
||
|
WORD inputBufferItems = 0;
|
||
|
MSG inputBuffer[MAX_INPUT_BUFFER];
|
||
|
|
||
|
BOOL NEAR checkInputBuffer(MSG *msg)
|
||
|
{
|
||
|
WORD ndx;
|
||
|
|
||
|
if((kbdLock == KBD_BUFFER) || ((kbdLock == KBD_WAIT) ) ||
|
||
|
((inputBufferItems > 0) ))
|
||
|
{
|
||
|
while(PeekMessage(msg, NULL, WM_KEYFIRST, WM_KEYLAST, TRUE))
|
||
|
{
|
||
|
if((msg->message == WM_KEYUP) && (inputBufferItems == 0))
|
||
|
return(TRUE);
|
||
|
else if(((msg->message == WM_KEYDOWN) || (msg->message == WM_KEYUP)) &&
|
||
|
(((msg->wParam >= '0') && (msg->wParam <= 'Z')) || (msg->wParam >= 0x80)))
|
||
|
{
|
||
|
/* mbbx 2.00: new xlate scheme... */
|
||
|
if(!TranslateMessage(msg) || !PeekMessage(msg, NULL, WM_CHAR, WM_CHAR, TRUE))
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
if(inputBufferItems < MAX_INPUT_BUFFER)
|
||
|
inputBuffer[inputBufferItems++] = *msg;
|
||
|
else
|
||
|
sysBeep();
|
||
|
}
|
||
|
}
|
||
|
else if(PeekMessage(msg, NULL, WM_CHAR, WM_CHAR, TRUE))
|
||
|
{
|
||
|
return(TRUE);
|
||
|
}
|
||
|
else if(inputBufferItems > 0)
|
||
|
{
|
||
|
*msg = inputBuffer[0];
|
||
|
msg->hwnd = GetFocus();
|
||
|
|
||
|
inputBufferItems -= 1;
|
||
|
for(ndx = 0; ndx < inputBufferItems; ndx++)
|
||
|
inputBuffer[ndx] = inputBuffer[ndx+1];
|
||
|
|
||
|
return(TRUE);
|
||
|
}
|
||
|
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
#endif
|