static void IdleObject_Tick(IdleObject * obj) { bool idle = false; int idleType = 0, flags = 0; if (obj->useridlecheck && IdleObject_IsUserIdle(obj)) { idleType = 1; idle = true; } else if (IdleObject_IdleCheckSaver(obj) && IsScreenSaverRunning()) { idleType = 2; idle = true; } else if (IdleObject_IdleCheckFullScr(obj) && IsFullScreen()) { idleType = 5; idle = true; } else if (IdleObject_IdleCheckWorkstation(obj) && IsWorkstationLocked()) { idleType = 3; idle = true; } else if (IdleObject_IdleCheckTerminal(obj) && IsTerminalDisconnected()) { idleType = 4; idle = true; } if (IdleObject_IsPrivacy(obj)) flags |= IDF_PRIVACY; if ( !IdleObject_IsIdle(obj) && idle) { IdleObject_SetIdle(obj); obj->idleType = idleType; NotifyEventHooks(hIdleEvent, 0, IDF_ISIDLE | flags); } if (IdleObject_IsIdle(obj) && !idle) { IdleObject_ClearIdle(obj); obj->idleType = 0; NotifyEventHooks(hIdleEvent, 0, flags); } }
BOOL checkNotifyOptions() { BOOL screenSaverIsRunning = IsScreenSaverRunning(); if (screenSaverIsRunning && bScreenSaverRunning) return TRUE; BOOL workstationIsLocked = IsWorkstationLocked(); if (workstationIsLocked && bWorkstationLocked) return TRUE; BOOL fullScreenMode = IsFullScreen() && !screenSaverIsRunning; if (fullScreenMode && bFullScreenMode) return TRUE; BOOL processesRunning = areThereProcessesRunning(); if (processesRunning && bProcessesAreRunning) return TRUE; return (!fullScreenMode && !screenSaverIsRunning && !workstationIsLocked && !processesRunning && bWorkstationActive); }
static DWORD ShutdownNow(BYTE shutdownType) { DWORD dwErrCode = ERROR_SUCCESS; switch (shutdownType) { case SDSDT_CLOSEMIRANDA: if (!Miranda_Terminated()) { /* waiting for short until ready (but not too long...) */ DWORD dwLastTickCount = GetTickCount(); while (!CallService(MS_SYSTEM_OKTOEXIT, 0, 0)) { /* infinite loop protection (max 5 sec) */ if (GetTickCount() - dwLastTickCount >= 5000) { /* wraparound works */ OutputDebugStringA("Timeout (5 sec)\n"); /* tell others, all ascii */ break; } SleepEx(1000, TRUE); if (Miranda_Terminated()) break; /* someone else did it */ OutputDebugStringA("Not ready to exit. Waiting...\n"); /* tell others, all ascii */ } /* shutdown service must be called from main thread anyway */ if (!DestroyWindow(pcli->hwndContactList)) dwErrCode = GetLastError(); } break; case SDSDT_SETMIRANDAOFFLINE: /* set global status mode to offline (is remembered by Miranda on exit) */ CallService(MS_CLIST_SETSTATUSMODE, (WPARAM)ID_STATUS_OFFLINE, 0); break; case SDSDT_STANDBY: case SDSDT_HIBERNATE: WinNT_SetPrivilege(SE_SHUTDOWN_NAME, TRUE); if (!SetSystemPowerState(shutdownType == SDSDT_STANDBY, TRUE)) dwErrCode = GetLastError(); WinNT_SetPrivilege(SE_SHUTDOWN_NAME, FALSE); break; case SDSDT_LOCKWORKSTATION: if (!IsWorkstationLocked()) dwErrCode = GetLastError(); break; case SDSDT_CLOSERASCONNECTIONS: ShutdownNow(SDSDT_SETMIRANDAOFFLINE); /* set Miranda offline */ /* hang up all ras connections */ { DWORD dwRetries; RASCONNSTATUS rcs; DWORD dw, dwLastTickCount; DWORD dwConnSize = sizeof(RASCONN); DWORD dwConnItems = 0; RASCONN *paConn = (RASCONN*)mir_alloc(dwConnSize); dwErrCode = ERROR_NOT_ENOUGH_MEMORY; if (paConn != NULL) { for (dwRetries = 5; dwRetries != 0; dwRetries--) { /* prevent infinite loop (rare) */ memset(paConn, 0, dwConnSize); paConn[0].dwSize = sizeof(RASCONN); dwErrCode = RasEnumConnections(paConn, &dwConnSize, &dwConnItems); if (dwErrCode != ERROR_BUFFER_TOO_SMALL) break; RASCONN *paConnBuf = (RASCONN*)mir_realloc(paConn, dwConnSize); if (paConnBuf == NULL) { mir_free(paConn); paConn = NULL; dwErrCode = ERROR_NOT_ENOUGH_MEMORY; break; } paConn = paConnBuf; } if (dwErrCode == ERROR_SUCCESS || dwErrCode == ERROR_BUFFER_TOO_SMALL) { for (dw = 0; dw < dwConnItems; ++dw) { if (dwErrCode) { if (RasHangUp(paConn[dw].hrasconn)) paConn[dw].hrasconn = NULL; /* do not wait for on error */ } else { dwErrCode = RasHangUp(paConn[dw].hrasconn); if (!dwErrCode) paConn[dw].hrasconn = NULL; /* do not wait for on error */ } } /* RAS does not allow to quit directly after HangUp (see docs) */ dwLastTickCount = GetTickCount(); memset(&rcs, 0, sizeof(RASCONNSTATUS)); rcs.dwSize = sizeof(RASCONNSTATUS); for (dw = 0; dw < dwConnItems; ++dw) { if (paConn[dw].hrasconn != NULL) { while (RasGetConnectStatus(paConn[dw].hrasconn, &rcs) != ERROR_INVALID_HANDLE) { Sleep(0); /* give rest of time silce to other threads with equal priority */ /* infinite loop protection (3000ms defined in docs) */ dwRetries = GetTickCount(); if (dwRetries - dwLastTickCount > 3000) break; /* wraparound works */ } } } } mir_free(paConn); /* does NULL check */ } } /* set Miranda to offline again, to remain offline with reconnection plugins */ ShutdownNow(SDSDT_SETMIRANDAOFFLINE); break; case SDSDT_REBOOT: case SDSDT_SHUTDOWN: if (GetSystemMetrics(SM_SHUTTINGDOWN)) { /* Win2000+, 0 on error */ dwErrCode = ERROR_SHUTDOWN_IN_PROGRESS; break; } /* WinNT4/2000/XP */ { WinNT_SetPrivilege(SE_SHUTDOWN_NAME, TRUE); /* does not send out WM_ENDSESSION messages, so we do it manually to * give the applications the chance to save their data */ WinNT_SetPrivilege(SE_TCB_NAME, TRUE); /* for BSM_ALLDESKTOPS */ BroadcastEndSession(BSM_APPLICATIONS | BSM_ALLDESKTOPS, ENDSESSION_CLOSEAPP); /* app should close itself */ WinNT_SetPrivilege(SE_TCB_NAME, FALSE); if (!InitiateSystemShutdownEx(NULL, TranslateT("AutoShutdown"), 0, TRUE, shutdownType == SDSDT_REBOOT, SHTDN_REASON_MAJOR_OTHER | SHTDN_REASON_MINOR_OTHER | SHTDN_REASON_FLAG_PLANNED)) dwErrCode = GetLastError(); /* cleanly close Miranda */ if (!dwErrCode) ShutdownNow(SDSDT_CLOSEMIRANDA); break; } /* fall through for Win9x */ case SDSDT_LOGOFF: { UINT flags; switch (shutdownType) { case SDSDT_LOGOFF: flags = EWX_LOGOFF; break; case SDSDT_REBOOT: flags = EWX_REBOOT; break; default: flags = EWX_SHUTDOWN | EWX_POWEROFF; } if (shutdownType == SDSDT_LOGOFF && !IsWorkstationLocked()) flags |= EWX_FORCEIFHUNG; /* only considered for WM_ENDSESSION messages */ else flags |= EWX_FORCE; /* must be used when workstation locked */ if (flags & EWX_FORCE) { /* EWX_FORCE does not send out WM_ENDSESSION messages, so we do it * manually to give the applications the chance to save their data */ BroadcastEndSession(BSM_APPLICATIONS, (shutdownType == SDSDT_LOGOFF) ? ENDSESSION_LOGOFF : 0); /* Windows Me/98/95 (msdn): Because of the design of the shell, * calling ExitWindowsEx with EWX_FORCE fails to completely log off * the user (the system terminates the applications and displays the * Enter Windows Password dialog box, however, the user's desktop remains.) * To log off the user forcibly, terminate the Explorer process before calling * ExitWindowsEx with EWX_LOGOFF and EWX_FORCE. */ } if (!ExitWindowsEx(flags, SHTDN_REASON_MAJOR_OTHER | SHTDN_REASON_MINOR_OTHER | SHTDN_REASON_FLAG_PLANNED)) dwErrCode = GetLastError(); /* cleanly close Miranda */ if (!dwErrCode) ShutdownNow(SDSDT_CLOSEMIRANDA); } break; } return dwErrCode; }
unsigned __stdcall MessagePumpThread(void* param) { if (param) SetEvent((HANDLE)param); MSG hwndMsg = { 0 }; while (GetMessage(&hwndMsg, 0, 0, 0) > 0 && !bShutdown) { if (hwndMsg.hwnd != NULL && IsDialogMessage(hwndMsg.hwnd, &hwndMsg)) /* Wine fix. */ continue; switch(hwndMsg.message) { case MUM_CREATEPOPUP: { bool enabled = true; int status = CallService(MS_CLIST_GETSTATUSMODE, 0, 0); if (status >= ID_STATUS_OFFLINE && status <= ID_STATUS_OUTTOLUNCH && options.disable_status[status - ID_STATUS_OFFLINE]) enabled = false; if ((options.disable_full_screen && IsFullScreen()) || IsWorkstationLocked()) enabled = false; PopupData *pd = (PopupData*)hwndMsg.lParam; if (enabled && num_popups < MAX_POPUPS) { //HWND hwnd = CreateWindowEx(WS_EX_TOOLWINDOW | WS_EX_TOPMOST, POP_WIN_CLASS, _T("Popup"), WS_POPUP, 0, 0, 0, 0, GetDesktopWindow(), 0, hInst, (LPVOID)hwndMsg.lParam); HWND hwnd = CreateWindowEx(WS_EX_TOOLWINDOW | WS_EX_TOPMOST, POP_WIN_CLASS, _T("Popup"), WS_POPUP, 0, 0, 0, 0, 0, 0, hInst, (LPVOID)hwndMsg.lParam); num_popups++; if (hwndMsg.wParam) // set notifyer handle SendMessage(hwnd, PUM_SETNOTIFYH, hwndMsg.wParam, 0); } else if (pd) { mir_free(pd->pwzTitle); mir_free(pd->pwzText); mir_free(pd); } } break; case MUM_DELETEPOPUP: { HWND hwnd = (HWND)hwndMsg.lParam; if (IsWindow(hwnd)) { DestroyWindow(hwnd); num_popups--; } } break; case MUM_NMUPDATE: BroadcastMessage(PUM_UPDATENOTIFY, hwndMsg.wParam, 0); break; case MUM_NMREMOVE: BroadcastMessage(PUM_KILLNOTIFY, hwndMsg.wParam, 0); break; case MUM_NMAVATAR: RepositionWindows(); break; default: TranslateMessage(&hwndMsg); DispatchMessage(&hwndMsg); break; } } DeinitWindowStack(); num_popups = 0; return 0; }