/* Miranda IM: the free IM client for Microsoft* Windows* Copyright 2000-2006 Miranda ICQ/IM project, all portions of this codebase are copyrighted to the people listed in contributors.txt. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "globals.h" //#include "../../miranda-IM/core/commonheaders.h" //int idleCheckPerm = 0; //int idleMethodPerm = 0; //int idleTimeFirstPerm = 5; // this is in mins //int idleTimeSecondPerm = 10; // //int idleTimeFirstOnPerm = 0; //int idleTimeSecondOnPerm = 0; //int idleOnSaverPerm = 0; //int idleOnLockPerm = 0; //int idleGLIPerm = 1; //int idlePrivatePerm = 0; BOOL (WINAPI * MyGetLastInputInfo)(PLASTINPUTINFO); unsigned long idleOptsPerm; // C G L S M P L S --LONG-- --SHORT- unsigned long idleOpts; // C G L S M P L S --LONG-- --SHORT- static BOOL idleDialogInInit = FALSE; BOOL InitDialogIdlePart(HWND hwndDlg) { // TranslateDialogDefault(hwndDlg); CheckDlgButton(hwndDlg, IDC_IDLECHECK, (idleOpts&IdleBitsCheck) ? BST_CHECKED : BST_UNCHECKED); // check/uncheck options CheckDlgButton(hwndDlg, IDC_IDLEONWINDOWS, (idleOpts&IdleBitsMethod) ? BST_UNCHECKED : BST_CHECKED); CheckDlgButton(hwndDlg, IDC_IDLEONMIRANDA, (idleOpts&IdleBitsMethod) ? BST_CHECKED : BST_UNCHECKED); CheckDlgButton(hwndDlg, IDC_IDLEUSEGLI, (idleOpts&IdleBitsGLI) ? BST_CHECKED : BST_UNCHECKED); CheckDlgButton(hwndDlg, IDC_SCREENSAVER, (idleOpts&IdleBitsOnSaver) ? BST_CHECKED : BST_UNCHECKED); CheckDlgButton(hwndDlg, IDC_LOCKED, (idleOpts&IdleBitsOnLock) ? BST_CHECKED : BST_UNCHECKED); CheckDlgButton(hwndDlg, IDC_IDLESHORT, (idleOpts&IdleBitsFirstOn) ? BST_CHECKED : BST_UNCHECKED); CheckDlgButton(hwndDlg, IDC_IDLELONG, (idleOpts&IdleBitsSecondOn) ? BST_CHECKED : BST_UNCHECKED); CheckDlgButton(hwndDlg, IDC_IDLEPRIVATE, (idleOpts&IdleBitsPrivate) ? BST_CHECKED : BST_UNCHECKED); CheckDlgButton(hwndDlg, IDC_DISBABLEAUTOHERE, (idleOpts&IdleSuppressAutoHere) ? BST_CHECKED : BST_UNCHECKED); CheckDlgButton(hwndDlg, IDC_DISABLEIDLEMENU, (idleOpts&IdleSuppressIdleMenu) ? BST_CHECKED : BST_UNCHECKED); CheckDlgButton(hwndDlg, IDC_HEREONSTATUSCHANGE, (idleOpts&IdleHereOnStatusChange)? BST_CHECKED : BST_UNCHECKED); // set times idleDialogInInit = TRUE; SetDlgItemInt(hwndDlg, IDC_IDLE1STTIME, GetBits(idleOpts,IdleBitsTimeFirst), FALSE); SetDlgItemInt(hwndDlg, IDC_IDLE2NDTIME, GetBits(idleOpts,IdleBitsTimeSecond), FALSE); idleDialogInInit = FALSE; // enable options SendMessage(hwndDlg, WM_USER+4, (WPARAM)((idleOpts&IdleBitsCheck)!=0), 0); return TRUE; } // delphi code here http://www.swissdelphicenter.ch/torry/printcode.php?id=2048 BOOL IsWorkstationLocked(void) { BOOL rc=0; HDESK hDesk = OpenDesktopA("default", 0, FALSE, DESKTOP_SWITCHDESKTOP); if ( hDesk != 0 ) { rc = SwitchDesktop(hDesk) == FALSE; CloseDesktop(hDesk); } return rc; } // ticks every 2 seconds int FirstTick; unsigned long secondsAfterLastActivity; unsigned long lastIdleEventTime = 0; int isCurrentlyIdle=0; //0 notidle //1 short //2long VOID CALLBACK IdleTimer(HWND hwnd, UINT message, UINT idEvent, DWORD dwTime) { DWORD dwTick = GetTickCount(); int isIdle[3] = {0}; static int isEventFired[3] = {0}; int j; if (FirstTick) { FirstTick--; if (FirstTick==0){ int flags = 0; starting = 1; switch (isCurrentlyIdle) { default : {flags = 0;/*MessageBox(theDialog,"BeHere","Button Pressed",0);*/ break;} case 1: {flags = IDF_SHORT|IDF_ISIDLE; /*MessageBox(theDialog,"BeAway","Button Pressed",0);*/ break;} case 2: {flags = IDF_LONG|IDF_ISIDLE; /*MessageBox(theDialog,"BeNA","Button Pressed",0);*/ break;} } if (isCurrentlyIdle) { lastIdleEventTime = DBGetContactSettingDword(NULL,AA_MODULE,AA_LASTIDLETIME,(DWORD)time(NULL)); secondsAfterLastActivity = time(NULL) - lastIdleEventTime; } else secondsAfterLastActivity = 0; flags |= idleOpts&IdleBitsPrivate?IDF_PRIVACY:0; NotifyEventHooks( hIdleEvent, 0, flags ); //Tell everyone we are here return; } } for (j = 0 ; j < protoCount ; j++) { if ( !isInterestingProto(j) ) continue; if (isWaitingForRestoreStatusMessage[j]) { isWaitingForRestoreStatusMessage[j]--; if (!(isWaitingForRestoreStatusMessage[j])) { #ifdef UNICODE TCHAR *awayMsg=0; if (HasAwayMessageW){ awayMsg = (TCHAR *) CallService(MS_AWAYMSG_GETSTATUSMSGW, (WPARAM) courAwayStatus[j], 0); } else { char *temp=(char *)CallService(MS_AWAYMSG_GETSTATUSMSG, (WPARAM) courAwayStatus[j], 0); if ((int)temp == CALLSERVICE_NOTFOUND) awayMsg = 0; else{ awayMsg = (TCHAR *)mir_alloc((maxMessageLength+1)*sizeof(TCHAR)); my_a2u(temp,awayMsg,maxMessageLength); mir_free(temp); } } #else char * awayMsg = (char *) CallService(MS_AWAYMSG_GETSTATUSMSG, (WPARAM) courAwayStatus[j], 0); if ((int)awayMsg==CALLSERVICE_NOTFOUND) awayMsg = NULL; #endif #ifdef AALOG { char str[1000]; sprintf(str,"%s: Restoring the default \"StatusMessage\": %s",proto[j]->szName,awayMsg ? awayMsg : "none"); CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str); } #endif #ifdef UNICODE if (protoHasAwayMessageW[j]) CallProtoService(proto[j]->szName, PS_SETAWAYMSGW, courAwayStatus[j], (LPARAM) awayMsg); else { char temp[maxMessageLength+1]; my_u2a(awayMsg,temp,maxMessageLength); CallProtoService(proto[j]->szName, PS_SETAWAYMSG, courAwayStatus[j], (LPARAM) temp); } #else CallProtoService(proto[j]->szName, PS_SETAWAYMSG, courAwayStatus[j], (LPARAM) awayMsg); #endif if (awayMsg) { #ifdef AALOG char str[1000]; sprintf(str,"%s: Cleaning after MS_AWAYMSG_GETSTATUSMSG: %s",proto[j]->szName,awayMsg); CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str); #endif mir_free(awayMsg); } } } } TimerProc(); //for the reconnect secondsAfterLastActivity = 0; isCurrentlyIdle = 0; if ( (idleOptsPerm&IdleBitsCheck) == 0 ) return; if ( (idleOptsPerm&IdleBitsMethod) == 0 ) { // use windows idle time if ( GetBits(idleOptsPerm,IdleBitsGLI) && (MyGetLastInputInfo != 0) ) { LASTINPUTINFO ii; memset(&ii,0,sizeof(ii)); ii.cbSize=sizeof(ii); if ( MyGetLastInputInfo(&ii) ) dwTick = ii.dwTime; } else { // mouse check static int mouseIdle = 0; static POINT lastMousePos = {0}; POINT pt; GetCursorPos(&pt); if ( pt.x != lastMousePos.x || pt.y != lastMousePos.y ) { mouseIdle=0; lastMousePos=pt; } else mouseIdle += 2; // interval of timer if ( mouseIdle ) dwTick = GetTickCount() - (mouseIdle * 1000); } } else { // use miranda idle time CallService(MS_SYSTEM_GETIDLE, 0, (LPARAM)&dwTick); } secondsAfterLastActivity = (GetTickCount() - dwTick)/1000; #ifdef AALOG { char log[1024]; sprintf(log,"%d seconds after last activity",secondsAfterLastActivity); CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)log);} #endif // has the first idle elapsed? If not permited FirstIdle time:ignore isIdle[0] = (idleOptsPerm&IdleBitsFirstOn)? (secondsAfterLastActivity >= (DWORD)( GetBits(idleOptsPerm,IdleBitsTimeFirst) * 60 )):0; // and the second? if not permited the SecondIdleTime: idnore isIdle[1] = (idleOptsPerm&IdleBitsSecondOn)?(secondsAfterLastActivity >= (DWORD)( GetBits(idleOptsPerm,IdleBitsTimeSecond) * 60 )):0; isIdle[2] = FALSE; if ( idleOptsPerm&IdleBitsOnSaver ) { // check saver BOOL isScreenSaverRunning = FALSE; SystemParametersInfo(SPI_GETSCREENSAVERRUNNING, 0, &isScreenSaverRunning, FALSE); isIdle[2] |= isScreenSaverRunning; } // check workstation? if ( idleOptsPerm&IdleBitsOnLock ) { // check station locked? isIdle[2] |= IsWorkstationLocked(); } { //check if the new idle is more idle than the previous idle is idle ;) int temp = isIdle[1]?2:((isIdle[0] || isIdle[2])?1:0); if (temp>=isCurrentlyIdle) isCurrentlyIdle = temp; else return; //if we are alredy idle then exit } for ( j = 0; j<3; j++ ) { int flags = ( idleOptsPerm&IdleBitsPrivate ? IDF_PRIVACY:0 ); switch (j) { case 0: flags |= IDF_SHORT; break; case 1: flags |= IDF_LONG; break; case 2: flags |= IDF_ONFORCE; break; } if ( isIdle[j]==1 && isEventFired[j] == 0 ) { // idle and no one knows isEventFired[j]=1; NotifyEventHooks( hIdleEvent, 0, IDF_ISIDLE | flags ); } if ( isIdle[j]==0 && isEventFired[j] == 1 ) { // not idle, no one knows isEventFired[j]=0; if ( !(idleOptsPerm&IdleSuppressAutoHere) ) NotifyEventHooks( hIdleEvent, 0, flags ); } }//for // { // int flags = ( idleOptsPerm&IdleBitsPrivate ? IDF_PRIVACY:0 ); // if (isIdle[0]||isIdle[1]||isIdle[2]) flags |= IDF_ISIDLE; // if (isIdle[0]) flags |= IDF_SHORT; // if (isIdle[1]) flags |= IDF_LONG; // if (isIdle[2]) flags |= IDF_ONFORCE; // NotifyEventHooks( hIdleEvent, 0, flags ); // } } int IdleGetInfo(WPARAM wParam, LPARAM lParam) { MIRANDA_IDLE_INFO * mii = (MIRANDA_IDLE_INFO *) lParam; if (mii) { int minutesAfterLastActivity = (time(NULL)-lastIdleEventTime)/60; #ifdef AALOG char log[1024]; sprintf(log,"\"%s\": %d came.", MS_IDLE_GETIDLEINFO, mii->cbSize/sizeof(mii->cbSize)); CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)log); #endif if (minutesAfterLastActivity<=0) minutesAfterLastActivity = 1; //this is the only field with similar meaning in "old" and "new miranda"; if (mii->cbSize/sizeof(mii->cbSize)>=2) mii->idleTime = isCurrentlyIdle?minutesAfterLastActivity:0; if (mii->cbSize/sizeof(mii->cbSize)>=3) mii->privacy = (idleOptsPerm&IdleBitsPrivate) !=0; if (mii->cbSize/sizeof(mii->cbSize)>=4) mii->aaStatus = isCurrentlyIdle==1?ID_STATUS_AWAY:(isCurrentlyIdle>1?ID_STATUS_NA:ID_STATUS_ONLINE); //dont know what to with that if (mii->cbSize/sizeof(mii->cbSize)>=5) mii->aaLock = (idleOptsPerm&IdleSuppressAutoHere) !=0; if (mii->cbSize/sizeof(mii->cbSize)>=6) mii->idleType = isCurrentlyIdle?1:0; return 0; } else return 1; } BOOL CALLBACK DlgProcOptsIdle(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_INITDIALOG: TranslateDialogDefault(hwndDlg); InitDialogIdlePart(hwndDlg); return TRUE; case WM_USER+4: { DWORD nID[] = { IDC_IDLEONWINDOWS, IDC_IDLEUSEGLI, IDC_IDLEONMIRANDA, IDC_SCREENSAVER, IDC_LOCKED, IDC_IDLESHORT, IDC_IDLE1STTIME, IDC_IDLELONG, IDC_IDLE2NDTIME//,IDC_IDLEPRIVATE }; int j; // enable/disable all sub controls, for (j = 0; j < sizeof(nID) / sizeof(nID[0]); j++) { int nEnable = wParam; switch ( nID[j] ) { case IDC_IDLEUSEGLI: nEnable &= IsDlgButtonChecked(hwndDlg, IDC_IDLEONWINDOWS) == BST_CHECKED ? 1 : 0; break; case IDC_IDLE1STTIME: nEnable &= IsDlgButtonChecked(hwndDlg, IDC_IDLESHORT) == BST_CHECKED ? 1 : 0; break; case IDC_IDLE2NDTIME: nEnable &= IsDlgButtonChecked(hwndDlg, IDC_IDLELONG) == BST_CHECKED ? 1 : 0; break; } EnableWindow(GetDlgItem(hwndDlg, nID[j]), nEnable); } idleOpts=SetBits(idleOpts,IdleBitsCheck, IsDlgButtonChecked(hwndDlg, IDC_IDLECHECK) == BST_CHECKED); idleOpts=SetBits(idleOpts,IdleBitsMethod, IsDlgButtonChecked(hwndDlg, IDC_IDLEONMIRANDA) == BST_CHECKED); idleOpts=SetBits(idleOpts,IdleBitsFirstOn, IsDlgButtonChecked(hwndDlg, IDC_IDLESHORT) == BST_CHECKED); idleOpts=SetBits(idleOpts,IdleBitsSecondOn, IsDlgButtonChecked(hwndDlg, IDC_IDLELONG) == BST_CHECKED); idleOpts=SetBits(idleOpts,IdleBitsGLI, IsDlgButtonChecked(hwndDlg, IDC_IDLEUSEGLI) == BST_CHECKED); idleOpts=SetBits(idleOpts,IdleBitsOnSaver, IsDlgButtonChecked(hwndDlg, IDC_SCREENSAVER) == BST_CHECKED); idleOpts=SetBits(idleOpts,IdleBitsOnLock, IsDlgButtonChecked(hwndDlg, IDC_LOCKED) == BST_CHECKED); idleOpts=SetBits(idleOpts,IdleBitsPrivate, IsDlgButtonChecked(hwndDlg, IDC_IDLEPRIVATE) == BST_CHECKED); idleOpts=SetBits(idleOpts,IdleSuppressAutoHere, IsDlgButtonChecked(hwndDlg, IDC_DISBABLEAUTOHERE) == BST_CHECKED); idleOpts=SetBits(idleOpts,IdleSuppressIdleMenu, IsDlgButtonChecked(hwndDlg, IDC_DISABLEIDLEMENU) == BST_CHECKED); idleOpts=SetBits(idleOpts,IdleHereOnStatusChange, IsDlgButtonChecked(hwndDlg, IDC_HEREONSTATUSCHANGE) == BST_CHECKED); break; } case WM_USER+8: { if (wParam == IDC_IDLE1STTIME) idleOpts = SetBits(idleOpts,IdleBitsTimeFirst,GetDlgItemInt(hwndDlg, wParam, NULL, FALSE)); if (wParam == IDC_IDLE2NDTIME) idleOpts = SetBits(idleOpts,IdleBitsTimeSecond,GetDlgItemInt(hwndDlg, wParam, NULL, FALSE)); break; } case WM_COMMAND: switch (LOWORD(wParam)) { case IDC_IDLEBUTTON: case IDC_IDLEBUTTON+1: case IDC_IDLEBUTTON+2:SimulateIdle(LOWORD(wParam)-IDC_IDLEBUTTON); break; case IDC_IDLECHECK: case IDC_IDLEONWINDOWS: case IDC_IDLEONMIRANDA: case IDC_IDLESHORT: case IDC_IDLELONG: case IDC_IDLEUSEGLI: case IDC_SCREENSAVER: case IDC_LOCKED: case IDC_IDLEPRIVATE: case IDC_DISBABLEAUTOHERE: case IDC_HEREONSTATUSCHANGE: case IDC_DISABLEIDLEMENU: { SendMessage(hwndDlg, WM_USER+4, (WPARAM)IsDlgButtonChecked(hwndDlg, IDC_IDLECHECK) == BST_CHECKED, 0); break; } case IDC_IDLE1STTIME: case IDC_IDLE2NDTIME: { if ( HIWORD(wParam) != EN_CHANGE ) return TRUE; SendMessage(hwndDlg, WM_USER+8, LOWORD(wParam), 0); break; } } if (!idleDialogInInit) if ((HIWORD(wParam)==BN_CLICKED)||(HIWORD(wParam)==EN_CHANGE)) { if ((LOWORD(wParam)!=IDC_IDLEBUTTON)&&(LOWORD(wParam)!=IDC_IDLEBUTTON+1)&&(LOWORD(wParam)!=IDC_IDLEBUTTON+2)) SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); } break; case WM_NOTIFY: switch (((LPNMHDR) lParam)->idFrom) { case 0: switch (((LPNMHDR) lParam)->code) { case PSN_APPLY: { return TRUE; } } break; } break; case WM_DESTROY: break; } return FALSE; }