windows-nt/Source/XPSP1/NT/shell/osshell/ep/idlewild/library/library.c
2020-09-26 16:20:57 +08:00

1487 lines
24 KiB
C

#ifdef PM
#define CSTD_WITH_OS2
#include <cstd.h>
#define INCL_WIN
#define INCL_DOS
#include <os2.h>
#endif
#ifdef WIN
#include <windows.h>
#include <port1632.h>
#endif
#include "std.h"
#include "scrsave.h"
#ifdef PM
#define prioNormal PRTYC_REGULAR
#define prioIdle PRTYC_IDLETIME
INT _acrtused = 0; // 'cause this is a DLL
#endif
#ifdef WIN
#define prioNormal 0
#define prioIdle 1
#endif
HWND hwndHook;
BOOL fDelayAction;
// Timer identifiers...
#define tidSecond 1
#define tidAnimate 2
#ifdef WIN
HHOOK lpfnSysMsgHookNext;
#endif
#ifdef PM
MRESULT APIENTRY WinProcBlanker(HWND, USHORT, MPARAM, MPARAM);
#endif
VOID APIENTRY ScrChooseRandomServer(void);
F FSendSsm(INT, LPVOID, LONG_PTR, LONG_PTR);
BOOL FDosModeHwnd(HWND hwnd);
VOID BlankScreen(F);
VOID BlankMouse(F);
VOID QuarterSecond(void);
VOID EverySecond(void);
VOID DelayAction(void);
void MoveHwndToFront(HWND hwnd);
void ShowMouse(F fShow);
void GetMousePos(LPPOINT ppt);
void InvalHwnd(HWND hwnd);
void EraseScreen(void);
void MoveHwndToBack(HWND hwnd);
void ShowHwnd(HWND hwnd, F fShow);
void SetPrio(INT prio);
VOID CopyPszToPsz(PSZ, PSZ);
INT CchLenPsz(PSZ);
VOID APIENTRY TermScrSave(void);
void StopTimer(INT tid);
void ReleaseCvs( HWND hwnd, CVS cvs);
F FAnyMouseDown(void);
CVS CvsFromHwnd(HWND);
F FStartTimer(INT, INT);
typedef struct _ssb
{
#ifdef PM
struct _ssb FAR * pssbNext;
#endif
#ifdef WIN
HANDLE hssbNext;
HMODULE hdll;
#endif
SCRSAVEPROC lpfnSaver;
CHAR szName [2];
} SSB;
#define cbSSBBase (sizeof (SSB) - 2)
#ifdef PM
SSB FAR * pssbList = NULL;
SSB FAR * pssbCur = NULL;
#endif
#ifdef WIN
HANDLE hssbList = NULL;
HANDLE hssbCur = NULL;
#endif
INT cssbRegistered = 0;
#ifdef PM
SSB FAR * PssbFindSz(PSZ);
#endif
#ifdef WIN
HANDLE HssbFindSz(PSZ);
#endif
SCRSAVEPROC lpfnSaver;
HWND hwnd;
HWND hwndClient;
HWND hwndApp;
CVS cvs;
HAB hab; // NOTE: really an hInstance in Windows!
#ifdef WIN
BOOL fWin30 = TRUE;
#endif
UINT wmScrSave; // REVIEW: for win 3.1
#ifdef PM
SEL selHeap;
HHEAP hheap;
#endif
POINT ptMouseOld;
INT dxScreen, dyScreen;
INT csecTilReblank = 0;
INT csecIgnoreDelay = 0;
INT csecTilBlank = 0;
F fMouseHidden = fFalse;
F fScreenHidden = fFalse;
INT csecTimeout = 60 * 5; /* 5 minutes */
F fNoBlackout = fFalse;
F fRandServer = fFalse;
F fBlankPtr = fTrue;
F fBackground = fFalse;
F fInited = fFalse;
INT csecTilMouseBlank = 5;
INT csecMouseTimeout = 5;
#ifdef WIN
#ifdef WIN32
INT APIENTRY LibMain(HANDLE hInst, ULONG ul_reason_being_called, LPVOID lpReserved) {
UNREFERENCED_PARAMETER(ul_reason_being_called);
UNREFERENCED_PARAMETER(lpReserved);
UNREFERENCED_PARAMETER(hInst);
#else
int LibMain(HMODULE hModule, WORD wDataSeg, WORD cbHeap, WORD sz) {
if (cbHeap != 0)
(VOID)MUnlockData(0);
UNREFERENCED_PARAMETER(sz);
UNREFERENCED_PARAMETER(cbheap);
UNREFERENCED_PARAMETER(wDataSeg);
UNREFERENCED_PARAMETER(hModule);
#endif /* WIN32 */
return 1;
}
VOID APIENTRY WEP(INT fSysShutdown)
{
UNREFERENCED_PARAMETER(fSysShutdown);
}
#endif
#ifdef PM
VOID SetPssbCur(SSB FAR * pssb)
#endif
#ifdef WIN
VOID SetHssbCur(HANDLE hssb)
#endif
{
if (fScreenHidden || fBackground)
FSendSsm(SSM_UNBLANK, cvs, 0L, 0L);
#ifdef PM
pssbCur = pssb;
#endif
#ifdef WIN
hssbCur = hssb;
#endif
if (fScreenHidden)
{
InvalHwnd(hwnd);
fNoBlackout = FSendSsm(SSM_BLANK, cvs, 0L, 0L);
}
else if (fBackground)
{
if (!FSendSsm(SSM_BLANK, cvs, 0L, 0L))
{
EraseScreen();
}
}
}
F FSendSsm(ssm, l1, l2, l3)
INT ssm;
LPVOID l1;
LONG_PTR l2, l3;
{
#ifdef PM
if (pssbCur == NULL)
return fFalse;
return (*pssbCur->lpfnSaver)(ssm, l1, l2, l3);
#endif
#ifdef WIN
SCRSAVEPROC lpfn;
if (hssbCur == NULL)
return fFalse;
lpfn = ((SSB *) LocalLock(hssbCur))->lpfnSaver;
LocalUnlock(hssbCur);
return (*lpfn)(ssm, l1, l2, l3);
#endif
}
#ifdef PM
APIENTRY BlankerHook(HAB hab, PQMSG pqmsg)
{
if (hwnd == NULL)
return;
switch (pqmsg->msg)
{
case WM_MOUSEMOVE:
if (fMouseHidden)
{
POINT pt;
GetCursorPos(&pt);
if (pt.x != ptMouseOld.x || pt.y != ptMouseOld.y)
BlankMouse(fFalse);
}
break;
case WM_BUTTON1DOWN:
case WM_BUTTON2DOWN:
case WM_BUTTON3DOWN:
case WM_VIOCHAR:
case WM_CHAR:
WinSendMsg(hwnd, WM_USER, (MPARAM) 0, (MPARAM) 0);
break;
}
}
#endif
#ifdef WIN
LRESULT APIENTRY BlankerHook(INT nCode, WPARAM wParam, LPARAM lParam)
{
if (csecTilBlank != csecTimeout && csecIgnoreDelay == 0)
fDelayAction = TRUE;
return DefHookProc(nCode, wParam, lParam,
&lpfnSysMsgHookNext);
}
#endif
#ifdef WIN_JOURNAL
VOID APIENTRY BlankerHook(msgf, wParam, lParam)
LONG lParam;
{
if (msgf >= 0)
{
LPEVENTMSGMSG lpevmsg;
lpevmsg = (LPEVENTMSGMSG) lParam;
switch (lpevmsg->message)
{
static POINT pt;
case WM_LBUTTONDOWN:
case WM_MBUTTONDOWN:
case WM_RBUTTONDOWN:
BlankMouse(FALSE);
goto LDelay;
case WM_MOUSEMOVE:
GetMousePos(&pt);
if (pt.x == ptMouseOld.x && pt.y == ptMouseOld.y)
break;
ptMouseOld = pt;
if (fMouseHidden)
BlankMouse(FALSE);
if (csecIgnoreDelay > 0)
break;
/* FALL THROUGH */
case WM_KEYDOWN:
case WM_SYSKEYDOWN:
LDelay:
PostMessage(hwnd, WM_USER, 0, 0);
break;
}
}
DefHookProc(msgf, wParam, lParam,
&lpfnSysMsgHookNext);
}
#endif
BOOL FSetHwndHook(HAB hab, HWND hwnd)
{
#ifdef PM
HMODULE hmodule;
DosGetModHandle("sos", &hmodule);
hwndHook = hwnd;
return (hwnd != NULL ? WinSetHook : WinReleaseHook)
(hab, NULL, HK_JOURNALRECORD, BlankerHook, hmodule);
#endif
#ifdef WIN
lpfnSysMsgHookNext = SetWindowsHook(/*WH_JOURNALRECORD*/WH_KEYBOARD, &BlankerHook);
return TRUE;
UNREFERENCED_PARAMETER(hab);
UNREFERENCED_PARAMETER(hwnd);
#endif
}
VOID APIENTRY ScrBlank(SHORT fBlank)
{
BlankScreen(fBlank);
csecTilBlank = 0;
}
VOID APIENTRY ScrSetTimeout(INT csec)
{
if ((csecTimeout = csec) == 0)
csecTimeout = 60 * 5;
}
INT APIENTRY ScrGetTimeout()
{
return csecTimeout;
}
VOID APIENTRY ScrSetIgnore(SHORT csec)
{
csecIgnoreDelay = csec;
}
VOID APIENTRY ScrEnablePtrBlank(INT fEnable)
{
fBlankPtr = fEnable;
}
INT APIENTRY ScrQueryPtrBlank()
{
return fBlankPtr;
}
VOID APIENTRY ScrSetBackground(SHORT fOn)
{
if (!fBackground == !fOn)
return;
fBackground = fOn;
if (fOn && !fScreenHidden)
{
if (cvs == NULL) // if it's not NULL, something bad happend
{
MoveHwndToBack(hwnd);
ShowHwnd(hwnd, fTrue);
if ((cvs = CvsFromHwnd(hwnd)) != NULL)
{
if (!FSendSsm(SSM_BLANK, cvs, 0L, 0L))
{
EraseScreen();
FStartTimer(tidAnimate, 0);
SetPrio(prioIdle);
}
}
}
}
else if (!fOn && !fScreenHidden)
{
if (cvs != NULL)
{
FSendSsm(SSM_UNBLANK, cvs, 0L, 0L);
ReleaseCvs(hwndClient, cvs);
cvs = NULL;
}
StopTimer(tidAnimate);
ShowHwnd(hwnd, fFalse);
SetPrio(prioNormal);
}
}
INT APIENTRY ScrQueryBackground()
{
return fBackground;
}
#ifdef PM
INIT APIENTRY FInitScrSave(HAB habExe)
{
ULONG flFrameFlags = 0;
if (hab != NULL)
return fFalse;
hab = habExe;
if (DosAllocSeg(256, &selHeap, SEG_NONSHARED) != 0)
return fFalse;
if ((hheap = WinCreateHeap(selHeap, 256, 256, 0, 0, 0)) == NULL)
{
DosFreeSeg(selHeap);
return fFalse;
}
if (!WinRegisterClass(hab, "sos", WinProcBlanker, 0L, NULL))
{
WinDestroyHeap(hheap);
return fFalse;
}
// REVIEW: I should probably be using WinCreateWindow, but I couldn't get
// it to work...
if ((hwnd = WinCreateStdWindow(HWND_DESKTOP, WS_VISIBLE,
&flFrameFlags, "sos", NULL, 0L, NULL, 1, &hwndClient)) == NULL)
{
WinDestroyHeap(hheap);
return fFalse;
}
dxScreen = WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN);
dyScreen = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN);
// This timer ticks every second and is used for various things
while (!WinStartTimer(hab, hwndClient, tidSecond, 1000))
{
if (WinMessageBox(HWND_DESKTOP, hwnd,
"Too many clocks or timers!", "Screen Saver", 0,
MB_ICONEXCLAMATION | MB_RETRYCANCEL) == MBID_CANCEL)
{
return fFalse;
}
}
if (!FSetHwndHook(hab, hwndClient))
{
WinDestroyWindow(hwnd);
WinDestroyHeap(hheap);
return fFalse;
}
DelayAction();
fInited = fTrue;
return fTrue;
}
VOID APIENTRY TermScrSave()
{
if (!fInited)
return;
BlankScreen(fFalse);
FSetHwndHook(hab, NULL);
WinDestroyWindow(hwnd);
WinDestroyHeap(hheap);
DosFreeSeg(selHeap);
hab = NULL;
fInited = fFalse;
}
MRESULT APIENTRY WinProcBlanker(HWND hwnd, USHORT wm, MPARAM mp1, MPARAM mp2)
{
switch (wm)
{
default:
return WinDefWindowProc(hwnd, wm, mp1, mp2);
case WM_BUTTON2DOWN:
return WinSendMsg(HWND_DESKTOP, wm, mp1, mp2);
case WM_TIMER:
if (SHORT1FROMMP(mp1) == tidSecond)
{
EverySecond();
}
else if (cvs != NULL)
{
FSendSsm(SSM_ANIMATE, cvs, 0L, 0L);
}
break;
case WM_CREATE:
WinQueryPointerPos(HWND_DESKTOP, &ptMouseOld);
break;
case WM_PAINT:
// BLOCK
{
CVS cvs;
RECTL rectl;
cvs = WinBeginPaint(hwnd, NULL, &rectl);
if (!fNoBlackout)
WinFillRect(cvs, &rectl, CLR_BLACK);
WinEndPaint(cvs);
}
break;
case WM_MOUSEMOVE:
// BLOCK
{
PT pt;
// WM_MOUSEMOVE does not mean the mouse has moved
WinQueryPointerPos(HWND_DESKTOP, &pt);
if (pt.x == ptMouseOld.x && pt.y == ptMouseOld.y)
{
break;
}
csecTilMouseBlank = csecMouseTimeout;
}
// FALL THROUGH
case WM_USER:
// Sent by the hook when the user does something...
if (csecIgnoreDelay == 0)
DelayAction();
break;
}
return (MRESULT) 0;
}
#endif
#ifdef WIN
LRESULT APIENTRY WinProcBlanker(HWND hwnd, UINT wm, WPARAM wParam, LPARAM lParam)
{
DWORD pos;
switch (wm)
{
case WM_PAINT:
{
CVS cvs;
PAINTSTRUCT paint;
cvs = BeginPaint(hwnd, &paint);
if (!fNoBlackout)
EraseScreen();
EndPaint(hwnd, &paint);
}
break;
case WM_MOUSEMOVE:
pos = GetMessagePos();
if (ptMouseOld.x == LOWORD(pos) &&
ptMouseOld.y == HIWORD(pos))
break;
csecTilMouseBlank = csecMouseTimeout;
/* FALL THROUGH */
case WM_KEYDOWN:
case WM_SYSKEYDOWN:
case WM_LBUTTONDOWN:
case WM_MBUTTONDOWN:
case WM_RBUTTONDOWN:
case WM_USER:
if (csecIgnoreDelay == 0)
DelayAction();
break;
case WM_TIMER:
if (wParam == tidSecond)
{
static INT iqsec;
iqsec += 1;
if (iqsec == 4)
{
iqsec = 0;
EverySecond();
}
QuarterSecond();
}
else if (cvs != NULL)
{
// Ignore events for a bit after blanking to allow
// for key-up, mouse jiggle, etc...
if (csecIgnoreDelay > 0)
csecIgnoreDelay -= 1;
BlankMouse(TRUE);
FSendSsm(SSM_ANIMATE, cvs, 0L, 0L);
}
break;
default:
return DefWindowProc(hwnd, wm, wParam, lParam);
}
return 0;
}
BOOL APIENTRY FInitScrSave(HAB habExe, HWND hwndUI) /* NOTE: hab is hInstance for Win */
{
WNDCLASS wndclass;
if (fInited)
{
#ifdef DEBUG
MessageBox(NULL, "Already initialized!", "IdleWild", MB_OK);
#endif
return FALSE;
}
fWin30 = (GETMAJORVERSION(GetVersion()) == 0x0003);
hwndApp = hwndUI;
wmScrSave = RegisterWindowMessage("SCRSAVE"); // REVIEW: for win 3.1
dxScreen = GetSystemMetrics(SM_CXSCREEN);
dyScreen = GetSystemMetrics(SM_CYSCREEN);
wndclass.style = 0;
wndclass.lpfnWndProc = WinProcBlanker;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hab;
wndclass.hIcon = NULL;
wndclass.hCursor = NULL;
wndclass.hbrBackground = NULL;
wndclass.lpszMenuName = (LPSTR) 0;
wndclass.lpszClassName = "IWBKG";
if (!RegisterClass(&wndclass))
{
#ifdef DEBUG
MessageBox(NULL, "Cannot register IWBKG class!", "IdleWild", MB_OK);
#endif
return fFalse;
}
if ((hwnd = hwndClient = CreateWindow("IWBKG", NULL, WS_POPUP,
-2, 0, 1, 1, NULL, NULL, hab, NULL)) == hNil)
{
MessageBox(NULL, "Cannot create a window!",
"IdleWild", MB_OK);
return fFalse;
}
while (!SetTimer(hwnd, tidSecond, 250, hNil))
{
if (MessageBox(hwnd, "Too many clocks or timers!",
"IdleWild", MB_RETRYCANCEL) == IDCANCEL)
{
return FALSE;
}
}
ShowWindow(hwnd, SW_HIDE);
SetWindowPos(hwnd, NULL, 0, 0, dxScreen, dyScreen,
SWP_NOACTIVATE | SWP_NOZORDER);
if (fWin30 && !FSetHwndHook(hab, hwnd))
{
#ifdef DEBUG
MessageBox(NULL, "Cannot set hook!", "IdleWild", MB_OK);
#endif
return FALSE;
}
DelayAction();
fInited = fTrue;
UNREFERENCED_PARAMETER(habExe);
return TRUE;
}
VOID APIENTRY TermScrSave()
{
HANDLE hssb, hssbNext;
SSB * pssb;
if (!fInited)
return;
BlankScreen(FALSE);
if (fWin30)
UnhookWindowsHook(WH_KEYBOARD, BlankerHook);
DestroyWindow(hwnd);
UnregisterClass("IWBKG", hab);
for (hssb = hssbList; hssb != NULL; hssb = hssbNext)
{
pssb = (SSB *) LocalLock(hssb);
FreeLibrary(pssb->hdll);
hssbNext = pssb->hssbNext;
LocalUnlock(hssb);
LocalFree(hssb);
}
hwnd = NULL;
hab = NULL;
fInited = fFalse;
}
#endif
VOID QuarterSecond()
{
static POINT pt;
if (fDelayAction)
{
fDelayAction = FALSE;
if (csecIgnoreDelay == 0)
DelayAction();
}
GetMousePos(&pt);
// Check for mouse movement...
if (pt.x != ptMouseOld.x || pt.y != ptMouseOld.y)
{
BlankMouse(FALSE);
if (csecIgnoreDelay == 0)
DelayAction();
}
if (pt.x == dxScreen - 1)
{
#ifdef PM
if (pt.y == dyScreen - 1)
#endif
#ifdef WIN
if (pt.y == 0)
#endif
{
// Blank the screen if mouse is moved to the
// upper-right corner...
BlankScreen(fTrue);
csecTilBlank = 0;
}
#ifdef PM
else if (pt.y == 0)
#endif
#ifdef WIN
else if (pt.y == dyScreen - 1)
#endif
{
// Disable the blanker when the mouse is in
// the lower-right corner...
BlankScreen(fFalse);
csecTilBlank = csecTimeout;
}
}
ptMouseOld = pt;
}
VOID EverySecond()
{
// Take care of mouse blanking...
if (fBlankPtr && csecTilMouseBlank > 0 && !FAnyMouseDown())
{
csecTilMouseBlank -= 1;
if (csecTilMouseBlank == 0)
BlankMouse(TRUE);
}
// Countdown screen blank timer or send second message to blanker...
if (fWin30 && csecTilBlank > 0)
{
csecTilBlank -= 1;
if (csecTilBlank == 0)
BlankScreen(fTrue);
}
if (fScreenHidden || fBackground)
{
if (fScreenHidden)
MoveHwndToFront(hwnd);
else
MoveHwndToBack(hwnd);
if (csecTilReblank > 0 && --csecTilReblank == 0)
ScrChooseRandomServer();
FSendSsm(SSM_SECOND, 0L, 0L, 0L);
}
}
VOID DelayAction()
{
csecTilBlank = csecTimeout;
if (fScreenHidden)
{
if (!fBackground)
{
// It *should* be safe to stop the timer even if
// it was never started.
StopTimer(tidAnimate);
}
BlankScreen(fFalse);
}
GetMousePos(&ptMouseOld);
}
VOID BlankMouse(F fBlank)
{
if (!fBlank)
csecTilMouseBlank = csecMouseTimeout;
if (!fBlank == !fMouseHidden)
return;
fMouseHidden = fBlank;
ShowMouse(!fBlank);
}
VOID BlankScreen(F fBlank)
{
#ifdef WIN
if (fBlank)
{
HWND hwnd;
hwnd = GetActiveWindow();
if (FDosModeHwnd(hwnd) /*&& !IsIconic(hwnd)*/ ||
FindWindow("CbtComm", NULL))
{
DelayAction();
return;
}
}
#endif
BlankMouse(fBlank);
if (!fBlank == !fScreenHidden)
return;
if (fBlank)
{
PostMessage((HWND)0xffff, wmScrSave, 1, 0); // REVIEW: for win 3.1
MoveHwndToFront(hwnd);
ShowHwnd(hwnd, fTrue);
GetMousePos(&ptMouseOld);
// If we can't get a canvas, there will be no animation...
if (cvs == NULL && (cvs = CvsFromHwnd(hwndClient)) == NULL)
return;
SetPrio(prioIdle);
if (fRandServer)
ScrChooseRandomServer();
fScreenHidden = fTrue;
fNoBlackout = FSendSsm(SSM_BLANK, cvs, 0L, 0L);
// Starting that timer might fail, in which case there will
// be no animation, but the screen will still be blank...
if (!FStartTimer(tidAnimate, 0))
fNoBlackout = fFalse;
csecIgnoreDelay = 4;
}
else
{
PostMessage((HWND)0xffff, wmScrSave, 0, 0); // REVIEW: for win 3.1
FSendSsm(SSM_UNBLANK, cvs, 0L, 0L);
fScreenHidden = fFalse;
if (fBackground)
{
MoveHwndToBack(hwnd);
/* ShowHwnd(hwnd, fTrue); /* already shown */
}
else
{
SetPrio(prioNormal);
ShowHwnd(hwnd, fFalse);
if (cvs != NULL)
{
ReleaseCvs(hwndClient, cvs);
cvs = NULL;
}
}
}
}
BOOL APIENTRY ScrSetServer(PSZ szName)
{
#ifdef PM
SSB FAR * pssb;
#endif
#ifdef WIN
HANDLE hssb;
#endif
csecTilReblank = 0; // Disable random re-blanker for now...
// Random
if (szName == NULL)
{
fRandServer = fTrue;
return fTrue;
}
// Blackness
if (szName[0] == '\0')
{
#ifdef PM
SetPssbCur(NULL);
#endif
#ifdef WIN
SetHssbCur(NULL);
#endif
fRandServer = fFalse;
return fTrue;
}
// Named server
#ifdef PM
if ((pssb = PssbFindSz(szName)) == NULL)
return fFalse;
SetPssbCur(pssb);
#endif
#ifdef WIN
if ((hssb = HssbFindSz(szName)) == NULL)
return FALSE;
SetHssbCur(hssb);
#endif
fRandServer = fFalse;
return fTrue;
}
SHORT FCompPszPsz(PSZ psz1, PSZ psz2)
{
CHAR FAR * lpch1, FAR * lpch2;
lpch1 = psz1;
lpch2 = psz2;
while (*lpch1 == *lpch2 && *lpch1 != '\0')
{
lpch1 += 1;
lpch2 += 1;
}
return *lpch1 == '\0' && *lpch2 == '\0';
}
#ifdef PM
SSB FAR * PssbFindSz(PSZ sz)
{
SSB FAR * pssb;
for (pssb = pssbList; pssb != NULL; pssb = pssb->pssbNext)
{
if (FCompPszPsz(pssb->szName, sz))
return pssb;
}
return NULL;
}
#endif
#ifdef WIN
HANDLE HssbFindSz(PSZ sz)
{
HANDLE hssb, hssbNext;
SSB * pssb;
for (hssb = hssbList; hssb != NULL; hssb = hssbNext)
{
F fSame;
pssb = (SSB *) LocalLock(hssb);
fSame = FCompPszPsz(pssb->szName, sz);
hssbNext = pssb->hssbNext;
LocalUnlock(hssb);
if (fSame)
return hssb;
}
return NULL;
}
#endif
#ifdef PM
SSB FAR * PssbIssb(issb)
INT issb;
{
SSB FAR * pssb;
for (pssb = pssbList; pssb != NULL && issb-- > 0;
pssb = pssb->pssbNext)
;
return pssb;
}
#endif
#ifdef WIN
HANDLE HssbIssb(issb)
INT issb;
{
HANDLE hssb, hssbNext;
SSB * pssb;
for (hssb = hssbList; hssb != NULL && issb-- > 0; hssb = hssbNext)
{
pssb = (SSB *) LocalLock(hssb);
hssbNext = pssb->hssbNext;
LocalUnlock(hssb);
}
return hssb;
}
#endif
VOID APIENTRY ScrChooseRandomServer()
{
csecTilReblank = csecTimeout * 4; // REVIEW: make an option?
#ifdef PM
SetPssbCur(PssbIssb(WRand(cssbRegistered)));
#endif
#ifdef WIN
SetHssbCur(HssbIssb(WRand(cssbRegistered)));
#endif
}
SHORT APIENTRY ScrLoadServer(PSZ szDllName)
{
#ifdef PM
NPBYTE npb;
SSB FAR * pssb;
HMODULE hmod;
SCRSAVEPROC lpfnSaver;
CHAR szFailure [80];
CHAR szName [80];
CHAR szDesc [256];
if (DosLoadModule(szFailure, sizeof (szFailure), szDllName, &hmod) != 0)
return fFalse;
if (DosGetProcAddr(hmod, "SCRSAVEPROC", &lpfnSaver) != 0)
{
DosFreeModule(hmod);
return fFalse;
}
CopyPszToPsz(szDllName, szName);
(*lpfnSaver)(SSM_OPEN, szName,
(LONG_PTR) szDesc, ((LONG) dyScreen << 16) + dxScreen);
if ((npb = WinAllocMem(hheap,
cbSSBBase + CchLenPsz(szName) + 1)) == NULL)
{
DosFreeModule(hmod);
return fFalse;
}
pssb = (SSB FAR *) MAKEP(selHeap, npb);
pssb->lpfnSaver = lpfnSaver;
pssb->pssbNext = pssbList;
CopyPszToPsz(szName, pssb->szName);
pssbList = pssb;
cssbRegistered += 1;
SetPssbCur(pssb);
return fTrue;
#endif
#ifdef WIN
HMODULE hdll;
HANDLE hssb;
SSB * pssb;
SCRSAVEPROC lpfnSaver;
CHAR szName [80];
CHAR szDesc [256];
if ((hdll = MLoadLibrary(szDllName)) == NULL)
{
#ifdef DEBUG
MessageBox(NULL, szDllName, "IdleWild cannot load:", MB_OK);
#endif
return FALSE;
}
if ((lpfnSaver = (SCRSAVEPROC)GetProcAddress(hdll, "SCRSAVEPROC")) == NULL)
{
MessageBox(NULL, "Invalid module!", "IdleWild", MB_OK);
FreeLibrary(hdll);
return FALSE;
}
CopyPszToPsz(szDllName, szName);
szDesc[0] = '\0';
(*lpfnSaver)(SSM_OPEN, szName,
(LONG_PTR) szDesc, ((LONG) dyScreen << 16) + dxScreen);
hssb = LocalAlloc(LMEM_MOVEABLE, cbSSBBase + CchLenPsz(szName) + 1 +
CchLenPsz(szDesc) + 1);
if (hssb == NULL)
{
MessageBox(NULL, "Not enough memory!", "IdleWild", MB_OK);
FreeLibrary(hdll);
return FALSE;
}
pssb = (SSB *) LocalLock(hssb);
pssb->lpfnSaver = lpfnSaver;
pssb->hdll = hdll;
pssb->hssbNext = hssbList;
CopyPszToPsz(szName, pssb->szName);
CopyPszToPsz(szDesc, pssb->szName + CchLenPsz(szName) + 1);
LocalUnlock(hssb);
hssbList = hssb;
cssbRegistered += 1;
SetHssbCur(hssb);
return TRUE;
#endif
}
VOID APIENTRY ScrQueryServerDesc(PSZ szBuf)
{
#ifdef PM
if (fRandServer || pssbCur == NULL)
szBuf[0] = '\0';
else
{
CopyPszToPsz(pssbCur->szName + CchLenPsz(pssbCur->szName) + 1,
szBuf);
}
#endif
#ifdef WIN
if (fRandServer || hssbCur == NULL)
szBuf[0] = '\0';
else
{
SSB * pssb;
pssb = (SSB *) LocalLock(hssbCur);
CopyPszToPsz(pssb->szName + CchLenPsz(pssb->szName) + 1,
szBuf);
LocalUnlock(hssbCur);
}
#endif
}
VOID APIENTRY ScrQueryServerName(PSZ szBuf)
{
#ifdef PM
if (pssbCur == NULL)
szBuf[0] = '\0';
else
CopyPszToPsz(pssbCur->szName, szBuf);
#endif
#ifdef WIN
if (hssbCur == NULL)
szBuf[0] = '\0';
else
{
SSB * pssb;
pssb = (SSB *) LocalLock(hssbCur);
CopyPszToPsz(pssb->szName, szBuf);
LocalUnlock(hssbCur);
}
#endif
}
VOID CopyPszToPsz(PSZ pszFrom, PSZ pszTo)
{
CHAR FAR * lpchFrom, FAR * lpchTo;
lpchFrom = pszFrom;
lpchTo = pszTo;
while ((*lpchTo++ = *lpchFrom++) != '\0')
;
}
INT CchLenPsz(PSZ psz)
{
CHAR FAR * pch;
for (pch = psz; *pch != '\0'; pch += 1)
;
return (INT) (pch - psz);
}
void GetMousePos(ppt)
LPPOINT ppt;
{
#ifdef PM
WinQueryPointerPos(HWND_DESKTOP, ppt);
#endif
#ifdef WIN
GetCursorPos(ppt);
#endif
}
F FStartTimer(tid, ms)
INT tid, ms;
{
#ifdef PM
return WinStartTimer(hab, hwndClient, tid, ms);
#endif
#ifdef WIN
return (F)SetTimer(hwndClient, tid, ms, NULL);
#endif
}
void StopTimer(INT tid)
{
#ifdef PM
WinStopTimer(hab, hwndClient, tid);
#endif
#ifdef WIN
KillTimer(hwndClient, tid);
#endif
}
void ShowHwnd(hwnd, fShow)
HWND hwnd;
F fShow;
{
#ifdef PM
WinShowWindow(hwnd, fShow);
#endif
#ifdef WIN
ShowWindow(hwnd, fShow ? SW_SHOW : SW_HIDE);
#endif
}
void MoveHwndToFront(hwnd)
HWND hwnd;
{
#ifdef PM
WinSetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_ZORDER);
#endif
#ifdef WIN
SetWindowPos(hwnd, (HWND) 0, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
#endif
}
void MoveHwndToBack(hwnd)
HWND hwnd;
{
#ifdef PM
WinSetWindowPos(hwnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_ZORDER);
#endif
#ifdef WIN
SetWindowPos(hwnd, (HWND) 1, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
#endif
}
CVS CvsFromHwnd(hwnd)
HWND hwnd;
{
#ifdef PM
return WinGetPS(hwnd);
#endif
#ifdef WIN
return GetDC(hwnd);
#endif
}
void ReleaseCvs(hwnd, cvs)
HWND hwnd;
CVS cvs;
{
#ifdef PM
WinReleasePS(cvs);
#endif
#ifdef WIN
ReleaseDC(hwnd, cvs);
#endif
}
void InvalHwnd(hwnd)
HWND hwnd;
{
#ifdef PM
WinInvalidateRect(hwnd, NULL, TRUE);
#endif
#ifdef WIN
InvalidateRect(hwnd, NULL, FALSE);
#endif
}
void EraseScreen()
{
#ifdef PM
RECTL rectl;
rectl.xLeft = 0;
rectl.yBottom = 0;
rectl.xRight = dxScreen;
rectl.yTop = dyScreen;
WinFillRect(cvs, &rectl, CLR_BLACK);
#endif
#ifdef WIN
PatBlt(cvs, 0, 0, dxScreen, dyScreen, BLACKNESS);
#endif
}
void SetPrio(INT prio)
{
#ifdef PM
DosSetPrty(PRTYS_PROCESS, prio, 0, 0);
#else
UNREFERENCED_PARAMETER(prio);
#endif
}
F FAnyMouseDown()
{
#ifdef PM
return (WinGetKeyState(HWND_DESKTOP, VK_BUTTON1) & 0x8000) != 0 ||
(WinGetKeyState(HWND_DESKTOP, VK_BUTTON2) & 0x8000) != 0 ||
(WinGetKeyState(HWND_DESKTOP, VK_BUTTON3) & 0x8000) != 0;
#endif
#ifdef WIN
return (GetKeyState(VK_LBUTTON) & 0x8000) != 0 ||
(GetKeyState(VK_MBUTTON) & 0x8000) != 0 ||
(GetKeyState(VK_RBUTTON) & 0x8000) != 0;
#endif
}
void ShowMouse(fShow)
F fShow;
{
#ifdef PM
WinShowPointer(HWND_DESKTOP, fShow);
#endif
#ifdef WIN
ShowCursor(fShow);
#endif
}
#ifdef WIN
VOID APIENTRY ScrInvokeDlg(HANDLE hInst, HWND hwnd)
{
FSendSsm(SSM_DIALOG, hInst, (LONG_PTR) hwnd, 0L);
}
#endif
#ifdef WIN
BOOL FDosModeHwnd(HWND hwnd)
{
#ifdef YUCKY
extern BOOL APIENTRY IsWinOldAppTask(HANDLE);
if (GETMAJORVERSION(GetVersion()) == 0x0003)
#endif
return FALSE;
#ifdef YUCKY
return IsWinOldAppTask(GetWindowTask(hwnd));
#endif
#ifdef YUCKY
HMENU hmenu;
INT iItem, cItems;
BOOL fFoundPopup;
hmenu = GetSystemMenu(hwnd, FALSE);
cItems = GetMenuItemCount(hmenu);
fFoundPopup = FALSE;
for (iItem = 0; iItem < cItems; iItem += 1)
{
if (GetSubMenu(hmenu, iItem) != NULL)
{
fFoundPopup = TRUE;
break;
}
}
return fFoundPopup;
#endif
UNREFERENCED_PARAMETER(hwnd);
}
#endif
INT APIENTRY RestoreEnumProc(HWND hwnd, LPARAM lParam)
{
UpdateWindow(hwnd);
UNREFERENCED_PARAMETER(lParam);
return TRUE;
}
VOID APIENTRY ScrRestoreScreen()
{
ShowHwnd(hwnd, fFalse);
EnumWindows(RestoreEnumProc, 0);
ShowHwnd(hwnd, fTrue);
}