#ifdef PM #define CSTD_WITH_OS2 #include #define INCL_WIN #define INCL_DOS #include #endif #ifdef WIN #include #include #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); }