/* IRC plugin for Miranda IM Copyright (C) 2003 Jörgen Persson 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 "irc.h" extern char * IRCPROTONAME; extern char * ALTIRCPROTONAME; extern int GlobalStatus; static int bStatusMenu = 0; static int bXStatusMenuBuilt = 0; static HANDLE hHookExtraIconsRebuild = NULL; static HANDLE hHookStatusBuild = NULL; static HANDLE hHookExtraIconsApply = NULL; static HMODULE hXStatusIconsDLL = NULL; //static HANDLE hXStatusIcons[32]; HANDLE hXStatusIcons[32]; static HANDLE hXStatusItems[33]; extern PREFERENCES * prefs; static DWORD requestXStatusDetails(HANDLE hContact, BOOL bAllowDelay) { DBVARIANT dbv; DBCONTACTGETSETTING dcs; dcs.szModule=IRCPROTONAME; dcs.szSetting="Nick"; dcs.pValue=&dbv; dbv.type=DBVT_ASCIIZ; CallService(MS_DB_CONTACT_GETSETTING,(WPARAM)hContact,(LPARAM)&dcs); PostIrcMessage( "/PRIVMSG %s \001XSTATUS\001", dbv.pszVal); DBFreeVariant(&dbv); return 1; } static void InitXStatusIconLibrary() { char path[2*MAX_PATH]; char* p; // get miranda's exe path GetModuleFileNameA(NULL, path, MAX_PATH); // find the last \ and null it out, this leaves no trailing slash p = strrchr(path, '\\'); strcpy(p, "\\plugins"); strcat(p, "\\xstatus_icons.dll"); hXStatusIconsDLL = LoadLibraryA(path); if (!hXStatusIconsDLL) { strcpy(p, "\\icons"); strcat(p, "\\xstatus_icons.dll"); hXStatusIconsDLL = LoadLibraryA(path); if (!hXStatusIconsDLL) { MessageBoxA(0, "Critical: cannot init IcoLib, no resource DLL found.", "IRC", MB_OK | MB_ICONEXCLAMATION); return; } } if (hXStatusIconsDLL) { if (LoadStringA(hXStatusIconsDLL, IDS_IDENTIFY, path, sizeof(path)) == 0 || strcmp(path, "# Custom Status Icons #")) { MessageBoxA(0, "Critical: cannot init IcoLib, wrong resource DLL found.", "IRC", MB_OK | MB_ICONEXCLAMATION); FreeLibrary(hXStatusIconsDLL); hXStatusIconsDLL = NULL; } } } HICON LoadDefaultXStatusIcon(int bStatus) { if (hXStatusIconsDLL) return (HICON)LoadImage(hXStatusIconsDLL, MAKEINTRESOURCE(IDI_XSTATUS1 + bStatus - 1), IMAGE_ICON, 0, 0, 0); else return (HICON)LoadImage(g_hInstance, MAKEINTRESOURCE(IDI_ICON_INFORMATION), IMAGE_ICON, 0, 0, 0); } HICON GetXStatusIcon(int bStatus) { char szTemp[64]; null_snprintf(szTemp, sizeof(szTemp), "xstatus%d", bStatus - 1); if (IconLibInstalled()) return IconLibProcess(NULL, szTemp); return LoadDefaultXStatusIcon(bStatus); } //static void setContactExtraIcon(HANDLE hContact, HANDLE hIcon) void setContactExtraIcon(HANDLE hContact, HANDLE hIcon) { IconExtraColumn iec; iec.cbSize = sizeof(iec); iec.hImage = hIcon; iec.ColumnType = EXTRA_ICON_ADV1 + DBGetContactSettingByte(NULL,ALTIRCPROTONAME,"XStatusAdv",0); CallService(MS_CLIST_EXTRA_SET_ICON, (WPARAM)hContact, (LPARAM)&iec); } static int CListMW_ExtraIconsRebuild(WPARAM wParam, LPARAM lParam) { int i; if (IRCGetContactSettingByte(NULL, "XStatusEnabled", 0) && ServiceExists(MS_CLIST_EXTRA_ADD_ICON)) { for (i = 0; i < 32; i++) { HICON hXIcon = LoadDefaultXStatusIcon(i + 1); char szTemp[64]; null_snprintf(szTemp, sizeof(szTemp), "xstatus%d", i); hXStatusIcons[i] = (HANDLE)CallService(MS_CLIST_EXTRA_ADD_ICON, (WPARAM)IconLibProcess(hXIcon, szTemp), 0); DestroyIcon(hXIcon); } } return 0; } static int CListMW_ExtraIconsApply(WPARAM wParam, LPARAM lParam) { if (IRCGetContactSettingByte(NULL, "XStatusEnabled", 0) && ServiceExists(MS_CLIST_EXTRA_SET_ICON)) { DWORD bXStatus = IRCGetContactSettingByte((HANDLE)wParam, DBSETTING_XSTATUSID, 0); if (bXStatus > 0 && bXStatus < 33) { setContactExtraIcon((HANDLE)wParam, hXStatusIcons[bXStatus-1]); } else { setContactExtraIcon((HANDLE)wParam, (HANDLE)-1); } } return 0; } static int CListMW_BuildStatusItems(WPARAM wParam, LPARAM lParam) { InitXStatusItems(TRUE); return 0; } void InitXStatusEvents() { if (!hHookStatusBuild) if (bStatusMenu = ServiceExists(MS_CLIST_ADDSTATUSMENUITEM)) hHookStatusBuild = HookEvent(ME_CLIST_PREBUILDSTATUSMENU, CListMW_BuildStatusItems); if (!hHookExtraIconsRebuild) hHookExtraIconsRebuild = HookEvent(ME_CLIST_EXTRA_LIST_REBUILD, CListMW_ExtraIconsRebuild); if (!hHookExtraIconsApply) hHookExtraIconsApply = HookEvent(ME_CLIST_EXTRA_IMAGE_APPLY, CListMW_ExtraIconsApply); } void UninitXStatusEvents() { if (hHookStatusBuild) UnhookEvent(hHookStatusBuild); if (hHookExtraIconsRebuild) UnhookEvent(hHookExtraIconsRebuild); if (hHookExtraIconsApply) UnhookEvent(hHookExtraIconsApply); } const char* nameXStatus[32] = { "Angry", "Taking a bath", "Tired", "Party", "Drinking beer", "Thinking", "Eating", "Watching TV", "Meeting", "Coffee", "Listening to music", "Business", "Shooting", "Having fun", "On the phone", "Gaming", "Studying", "Shopping", "Feeling sick", "Sleeping", "Surfing", "Browsing", "Working", "Typing", "Picnic", "Cooking", "Smoking", "I'm high", "On WC", "To be or not to be", "Reading", "Love"}; /* void handleXStatusCaps(HANDLE hContact, char* caps, int capsize) { HANDLE hIcon = (HANDLE)-1; // if (!gbXStatusEnabled) return; if (caps) { int i; for (i = 0; i<32; i++) { if (MatchCap(caps, capsize, (const capstr*)capXStatus[i], 0x10)) { char str[MAX_PATH]; ICQWriteContactSettingByte(hContact, DBSETTING_XSTATUSID, (BYTE)(i+1)); ICQWriteContactSettingUtf(hContact, DBSETTING_XSTATUSNAME, ICQTranslateUtfStatic(nameXStatus[i], str)); if (ICQGetContactSettingByte(NULL, "XStatusAuto", DEFAULT_XSTATUS_AUTO)) requestXStatusDetails(hContact, TRUE); hIcon = hXStatusIcons[i]; break; } } } if (hIcon == (HANDLE)-1) { ICQDeleteContactSetting(hContact, DBSETTING_XSTATUSID); ICQDeleteContactSetting(hContact, DBSETTING_XSTATUSNAME); ICQDeleteContactSetting(hContact, DBSETTING_XSTATUSMSG); } if (gbXStatusEnabled != 10) { setContactExtraIcon(hContact, hIcon); } } */ static WNDPROC OldMessageEditProc; static LRESULT CALLBACK MessageEditSubclassProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam) { switch(msg) { case WM_CHAR: if(wParam=='\n' && GetKeyState(VK_CONTROL)&0x8000) { PostMessage(GetParent(hwnd),WM_COMMAND,IDOK,0); return 0; } if (wParam == 1 && GetKeyState(VK_CONTROL) & 0x8000) { // ctrl-a SendMessage(hwnd, EM_SETSEL, 0, -1); return 0; } if (wParam == 23 && GetKeyState(VK_CONTROL) & 0x8000) { // ctrl-w SendMessage(GetParent(hwnd), WM_CLOSE, 0, 0); return 0; } if (wParam == 127 && GetKeyState(VK_CONTROL) & 0x8000) { // ctrl-backspace DWORD start, end; wchar_t *text; SendMessage(hwnd, EM_GETSEL, (WPARAM) & end, (LPARAM) (PDWORD) NULL); SendMessage(hwnd, WM_KEYDOWN, VK_LEFT, 0); SendMessage(hwnd, EM_GETSEL, (WPARAM) & start, (LPARAM) (PDWORD) NULL); text = GetWindowTextUcs(hwnd); MoveMemory(text + start, text + end, sizeof(wchar_t) * (wcslen(text) + 1 - end)); SetWindowTextUcs(hwnd, text); SAFE_FREE((void **)&text); SendMessage(hwnd, EM_SETSEL, start, start); SendMessage(GetParent(hwnd), WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(hwnd), EN_CHANGE), (LPARAM) hwnd); return 0; } break; } return CallWindowProcUtf(OldMessageEditProc,hwnd,msg,wParam,lParam); } typedef struct SetXStatusData_s { BYTE bAction; BYTE bXStatus; HANDLE hContact; HANDLE hEvent; DWORD iEvent; int countdown; char *okButtonFormat; } SetXStatusData; typedef struct InitXStatusData_s { BYTE bAction; BYTE bXStatus; HANDLE hContact; } InitXStatusData; #define HM_PROTOACK (WM_USER+10) static BOOL CALLBACK SetXStatusDlgProc(HWND hwndDlg,UINT message,WPARAM wParam,LPARAM lParam) { SetXStatusData *dat = (SetXStatusData*)GetWindowLong(hwndDlg,GWL_USERDATA); char str[MAX_PATH]; switch(message) { case HM_PROTOACK: { ACKDATA *ack = (ACKDATA*)lParam; char *szText; if (ack->hContact != dat->hContact) break; if ((DWORD)ack->hProcess != dat->iEvent) break; ShowWindow(GetDlgItem(hwndDlg, IDC_RETRXSTATUS), SW_HIDE); ShowWindow(GetDlgItem(hwndDlg, IDC_XMSG), SW_SHOW); ShowWindow(GetDlgItem(hwndDlg, IDC_XTITLE), SW_SHOW); SetDlgItemTextUtf(hwndDlg,IDOK,IRCTranslateUtfStatic("Close", str)); UnhookEvent(dat->hEvent); dat->hEvent = NULL; szText = IRCGetContactSettingUtf(dat->hContact, DBSETTING_XSTATUSNAME, ""); SetDlgItemTextUtf(hwndDlg, IDC_XTITLE, szText); SAFE_FREE((void **)&szText); szText = IRCGetContactSettingUtf(dat->hContact, DBSETTING_XSTATUSMSG, ""); SetDlgItemTextUtf(hwndDlg, IDC_XMSG, szText); SAFE_FREE((void **)&szText); break; } case WM_INITDIALOG: { InitXStatusData *init = (InitXStatusData*)lParam; TranslateDialogDefault(hwndDlg); dat = (SetXStatusData*)malloc(sizeof(SetXStatusData)); SetWindowLong(hwndDlg,GWL_USERDATA,(LONG)dat); dat->bAction = init->bAction; if (!init->bAction) { // set our xStatus char szSetting[64]; char* szValue; dat->bXStatus = init->bXStatus; SendDlgItemMessage(hwndDlg, IDC_XTITLE, EM_LIMITTEXT, 256, 0); SendDlgItemMessage(hwndDlg, IDC_XMSG, EM_LIMITTEXT, 1024, 0); OldMessageEditProc = (WNDPROC)SetWindowLongUtf(GetDlgItem(hwndDlg,IDC_XTITLE),GWL_WNDPROC,(LONG)MessageEditSubclassProc); OldMessageEditProc = (WNDPROC)SetWindowLongUtf(GetDlgItem(hwndDlg,IDC_XMSG),GWL_WNDPROC,(LONG)MessageEditSubclassProc); dat->okButtonFormat = GetDlgItemTextUtf(hwndDlg,IDOK); dat->countdown=5; SendMessage(hwndDlg, WM_TIMER, 0, 0); SetTimer(hwndDlg,1,1000,0); sprintf(szSetting, "XStatus%dName", dat->bXStatus); szValue = IRCGetContactSettingUtf(NULL, szSetting, ""); SetDlgItemTextUtf(hwndDlg, IDC_XTITLE, szValue); SAFE_FREE((void **)&szValue); sprintf(szSetting, "XStatus%dMsg", dat->bXStatus); szValue = IRCGetContactSettingUtf(NULL, szSetting, ""); SetDlgItemTextUtf(hwndDlg, IDC_XMSG, szValue); SAFE_FREE((void **)&szValue); } else { // retrieve contact's xStatus dat->hContact = init->hContact; dat->bXStatus = IRCGetContactSettingByte(dat->hContact, DBSETTING_XSTATUSID, 0); dat->okButtonFormat = NULL; SendMessage(GetDlgItem(hwndDlg, IDC_XTITLE), EM_SETREADONLY, 1, 0); SendMessage(GetDlgItem(hwndDlg, IDC_XMSG), EM_SETREADONLY, 1, 0); if (!IRCGetContactSettingByte(NULL, "XStatusAuto", DEFAULT_XSTATUS_AUTO)) { SetDlgItemTextUtf(hwndDlg,IDOK,IRCTranslateUtfStatic("Cancel", str)); dat->hEvent = HookEventMessage(ME_PROTO_ACK, hwndDlg, HM_PROTOACK); ShowWindow(GetDlgItem(hwndDlg, IDC_RETRXSTATUS), SW_SHOW); ShowWindow(GetDlgItem(hwndDlg, IDC_XMSG), SW_HIDE); ShowWindow(GetDlgItem(hwndDlg, IDC_XTITLE), SW_HIDE); dat->iEvent = requestXStatusDetails(dat->hContact, FALSE); } else { char *szText; SetDlgItemTextUtf(hwndDlg,IDOK,IRCTranslateUtfStatic("Close", str)); dat->hEvent = NULL; szText = IRCGetContactSettingUtf(dat->hContact, DBSETTING_XSTATUSNAME, ""); SetDlgItemTextUtf(hwndDlg, IDC_XTITLE, szText); SAFE_FREE((void **)&szText); szText = IRCGetContactSettingUtf(dat->hContact, DBSETTING_XSTATUSMSG, ""); SetDlgItemTextUtf(hwndDlg, IDC_XMSG, szText); SAFE_FREE((void **)&szText); } } { char *format; char buf[MAX_PATH]; format = GetWindowTextUtf(hwndDlg); null_snprintf(str, sizeof(str), format, dat->bXStatus?IRCTranslateUtfStatic(nameXStatus[dat->bXStatus-1], buf):""); SetWindowTextUtf(hwndDlg, str); SAFE_FREE((void **)&format); } return TRUE; } case WM_TIMER: if(dat->countdown==-1) { DestroyWindow(hwndDlg); break; } { null_snprintf(str,sizeof(str),dat->okButtonFormat,dat->countdown); SetDlgItemTextUtf(hwndDlg,IDOK,str); } dat->countdown--; break; case WM_COMMAND: switch(LOWORD(wParam)) { case IDOK: DestroyWindow(hwndDlg); break; case IDC_XTITLE: case IDC_XMSG: if (!dat->bAction) { // set our xStatus KillTimer(hwndDlg,1); SetDlgItemTextUtf(hwndDlg,IDOK,IRCTranslateUtfStatic("OK", str)); } break; } break; case WM_DESTROY: if (!dat->bAction) { // set our xStatus char szSetting[64]; char* szValue; szValue = GetDlgItemTextUtf(hwndDlg,IDC_XMSG); sprintf(szSetting, "XStatus%dMsg", dat->bXStatus); IRCWriteContactSettingUtf(NULL, szSetting, szValue); IRCWriteContactSettingUtf(NULL, DBSETTING_XSTATUSMSG, szValue); SAFE_FREE((void **)&szValue); szValue = GetDlgItemTextUtf(hwndDlg,IDC_XTITLE); sprintf(szSetting, "XStatus%dName", dat->bXStatus); IRCWriteContactSettingUtf(NULL, szSetting, szValue); IRCWriteContactSettingUtf(NULL, DBSETTING_XSTATUSNAME, szValue); SAFE_FREE((void **)&szValue); SetWindowLongUtf(GetDlgItem(hwndDlg,IDC_XMSG),GWL_WNDPROC,(LONG)OldMessageEditProc); SetWindowLongUtf(GetDlgItem(hwndDlg,IDC_XTITLE),GWL_WNDPROC,(LONG)OldMessageEditProc); } if (dat->hEvent) UnhookEvent(dat->hEvent); SAFE_FREE((void **)&dat->okButtonFormat); SAFE_FREE((void **)&dat); break; case WM_CLOSE: DestroyWindow(hwndDlg); break; } return FALSE; } static void setXStatusEx(BYTE bXStatus, BYTE bQuiet) { CLISTMENUITEM mi = {0}; BYTE bOldXStatus = IRCGetContactSettingByte(NULL, DBSETTING_XSTATUSID, 0); mi.cbSize = sizeof(mi); if (bOldXStatus <= 32) { mi.flags = CMIM_FLAGS; CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hXStatusItems[bOldXStatus], (LPARAM)&mi); } IRCWriteContactSettingByte(NULL, DBSETTING_XSTATUSID, bXStatus); mi.flags = CMIM_FLAGS | (bXStatus?CMIF_CHECKED:0); CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hXStatusItems[bXStatus], (LPARAM)&mi); if (bXStatus) { char szSetting[64]; char str[MAX_PATH]; char* szUtf; sprintf(szSetting, "XStatus%dName", bXStatus); szUtf = IRCGetContactSettingUtf(NULL, szSetting, IRCTranslateUtfStatic(nameXStatus[bXStatus-1], str)); IRCWriteContactSettingUtf(NULL, DBSETTING_XSTATUSNAME, szUtf); SAFE_FREE((void **)&szUtf); sprintf(szSetting, "XStatus%dMsg", bXStatus); szUtf = IRCGetContactSettingUtf(NULL, szSetting, ""); IRCWriteContactSettingUtf(NULL, DBSETTING_XSTATUSMSG, szUtf); SAFE_FREE((void **)&szUtf); sprintf(szSetting, "XStatus%dStat", bXStatus); if (!bQuiet && !IRCGetContactSettingByte(NULL, szSetting, 0)) { InitXStatusData init; init.bAction = 0; // set init.bXStatus = bXStatus; DialogBoxUtf(FALSE, g_hInstance, MAKEINTRESOURCEA(IDD_SETXSTATUS),NULL,SetXStatusDlgProc,(LPARAM)&init); } } else { IRCDeleteContactSetting(NULL, DBSETTING_XSTATUSNAME); IRCDeleteContactSetting(NULL, DBSETTING_XSTATUSMSG); } } static void __fastcall setXStatus(BYTE bXStatus) { // for menu commands setXStatusEx(bXStatus, 0); } static int menuXStatus0(WPARAM wParam,LPARAM lParam) { setXStatus(0); return 0; } static int menuXStatus1(WPARAM wParam,LPARAM lParam) { setXStatus(1); return 0; } static int menuXStatus2(WPARAM wParam,LPARAM lParam) { setXStatus(2); return 0; } static int menuXStatus3(WPARAM wParam,LPARAM lParam) { setXStatus(3); return 0; } static int menuXStatus4(WPARAM wParam,LPARAM lParam) { setXStatus(4); return 0; } static int menuXStatus5(WPARAM wParam,LPARAM lParam) { setXStatus(5); return 0; } static int menuXStatus6(WPARAM wParam,LPARAM lParam) { setXStatus(6); return 0; } static int menuXStatus7(WPARAM wParam,LPARAM lParam) { setXStatus(7); return 0; } static int menuXStatus8(WPARAM wParam,LPARAM lParam) { setXStatus(8); return 0; } static int menuXStatus9(WPARAM wParam,LPARAM lParam) { setXStatus(9); return 0; } static int menuXStatus10(WPARAM wParam,LPARAM lParam) { setXStatus(10); return 0; } static int menuXStatus11(WPARAM wParam,LPARAM lParam) { setXStatus(11); return 0; } static int menuXStatus12(WPARAM wParam,LPARAM lParam) { setXStatus(12); return 0; } static int menuXStatus13(WPARAM wParam,LPARAM lParam) { setXStatus(13); return 0; } static int menuXStatus14(WPARAM wParam,LPARAM lParam) { setXStatus(14); return 0; } static int menuXStatus15(WPARAM wParam,LPARAM lParam) { setXStatus(15); return 0; } static int menuXStatus16(WPARAM wParam,LPARAM lParam) { setXStatus(16); return 0; } static int menuXStatus17(WPARAM wParam,LPARAM lParam) { setXStatus(17); return 0; } static int menuXStatus18(WPARAM wParam,LPARAM lParam) { setXStatus(18); return 0; } static int menuXStatus19(WPARAM wParam,LPARAM lParam) { setXStatus(19); return 0; } static int menuXStatus20(WPARAM wParam,LPARAM lParam) { setXStatus(20); return 0; } static int menuXStatus21(WPARAM wParam,LPARAM lParam) { setXStatus(21); return 0; } static int menuXStatus22(WPARAM wParam,LPARAM lParam) { setXStatus(22); return 0; } static int menuXStatus23(WPARAM wParam,LPARAM lParam) { setXStatus(23); return 0; } static int menuXStatus24(WPARAM wParam,LPARAM lParam) { setXStatus(24); return 0; } static int menuXStatus25(WPARAM wParam,LPARAM lParam) { setXStatus(25); return 0; } static int menuXStatus26(WPARAM wParam,LPARAM lParam) { setXStatus(26); return 0; } static int menuXStatus27(WPARAM wParam,LPARAM lParam) { setXStatus(27); return 0; } static int menuXStatus28(WPARAM wParam,LPARAM lParam) { setXStatus(28); return 0; } static int menuXStatus29(WPARAM wParam,LPARAM lParam) { setXStatus(29); return 0; } static int menuXStatus30(WPARAM wParam,LPARAM lParam) { setXStatus(30); return 0; } static int menuXStatus31(WPARAM wParam,LPARAM lParam) { setXStatus(31); return 0; } static int menuXStatus32(WPARAM wParam,LPARAM lParam) { setXStatus(32); return 0; } void InitXStatusItems(BOOL bAllowStatus) { CLISTMENUITEM mi; int i = 0; char srvFce[MAX_PATH + 64]; char szItem[MAX_PATH + 64]; HANDLE hXStatusRoot; BYTE bXStatus = IRCGetContactSettingByte(NULL, DBSETTING_XSTATUSID, 0); if (!IRCGetContactSettingByte(NULL, "XStatusEnabled", 0)) return; if (bStatusMenu && !bAllowStatus) return; null_snprintf(szItem, sizeof(szItem), Translate("%s Custom Status"), ALTIRCPROTONAME); mi.cbSize = sizeof(mi); mi.pszPopupName = szItem; mi.popupPosition= 500084000; mi.position = 2000040000; for(i = 0; i <= 32; i++) { char szTemp[64]; HICON hIIcon = (i > 0) ? LoadDefaultXStatusIcon(i) : NULL; null_snprintf(srvFce, sizeof(srvFce), "%s/menuXStatus%d", ALTIRCPROTONAME, i); null_snprintf(szTemp, sizeof(szTemp), "xstatus%d", i-1); mi.hIcon = IconLibProcess(hIIcon, szTemp); mi.position++; if (!bXStatusMenuBuilt) { switch(i) { case 0: CreateServiceFunction(srvFce, menuXStatus0); break; case 1: CreateServiceFunction(srvFce, menuXStatus1); break; case 2: CreateServiceFunction(srvFce, menuXStatus2); break; case 3: CreateServiceFunction(srvFce, menuXStatus3); break; case 4: CreateServiceFunction(srvFce, menuXStatus4); break; case 5: CreateServiceFunction(srvFce, menuXStatus5); break; case 6: CreateServiceFunction(srvFce, menuXStatus6); break; case 7: CreateServiceFunction(srvFce, menuXStatus7); break; case 8: CreateServiceFunction(srvFce, menuXStatus8); break; case 9: CreateServiceFunction(srvFce, menuXStatus9); break; case 10: CreateServiceFunction(srvFce, menuXStatus10); break; case 11: CreateServiceFunction(srvFce, menuXStatus11); break; case 12: CreateServiceFunction(srvFce, menuXStatus12); break; case 13: CreateServiceFunction(srvFce, menuXStatus13); break; case 14: CreateServiceFunction(srvFce, menuXStatus14); break; case 15: CreateServiceFunction(srvFce, menuXStatus15); break; case 16: CreateServiceFunction(srvFce, menuXStatus16); break; case 17: CreateServiceFunction(srvFce, menuXStatus17); break; case 18: CreateServiceFunction(srvFce, menuXStatus18); break; case 19: CreateServiceFunction(srvFce, menuXStatus19); break; case 20: CreateServiceFunction(srvFce, menuXStatus20); break; case 21: CreateServiceFunction(srvFce, menuXStatus21); break; case 22: CreateServiceFunction(srvFce, menuXStatus22); break; case 23: CreateServiceFunction(srvFce, menuXStatus23); break; case 24: CreateServiceFunction(srvFce, menuXStatus24); break; case 25: CreateServiceFunction(srvFce, menuXStatus25); break; case 26: CreateServiceFunction(srvFce, menuXStatus26); break; case 27: CreateServiceFunction(srvFce, menuXStatus27); break; case 28: CreateServiceFunction(srvFce, menuXStatus28); break; case 29: CreateServiceFunction(srvFce, menuXStatus29); break; case 30: CreateServiceFunction(srvFce, menuXStatus30); break; case 31: CreateServiceFunction(srvFce, menuXStatus31); break; case 32: CreateServiceFunction(srvFce, menuXStatus32); break; } } mi.flags = bXStatus == i?CMIF_CHECKED:0; mi.pszName = IRCTranslate(i?nameXStatus[i-1]:"None"); mi.pszService = srvFce; mi.pszContactOwner = ALTIRCPROTONAME; if (bStatusMenu) hXStatusItems[i] = (HANDLE)CallService(MS_CLIST_ADDSTATUSMENUITEM, (WPARAM)&hXStatusRoot, (LPARAM)&mi); else hXStatusItems[i] = (HANDLE)CallService(MS_CLIST_ADDMAINMENUITEM, 0, (LPARAM)&mi); if (i) DestroyIcon(hIIcon); } bXStatusMenuBuilt = 1; } void InitXStatusIcons() { char szSection[MAX_PATH + 64]; char str[MAX_PATH], prt[MAX_PATH]; int i; if (!prefs->XStatusEnabled) return; InitXStatusIconLibrary(); null_snprintf(szSection, sizeof(szSection), IRCTranslateUtfStatic("%s/Custom Status", str), IRCTranslateUtfStatic(IRCPROTONAME, prt)); for (i = 0; i < 32; i++) { HICON hXIcon = LoadDefaultXStatusIcon(i + 1); char szTemp[64]; null_snprintf(szTemp, sizeof(szTemp), "xstatus%d", i); IconLibDefine(IRCTranslateUtfStatic(nameXStatus[i], str), szSection, szTemp, hXIcon); DestroyIcon(hXIcon); } if (bXStatusMenuBuilt) ChangedIconsXStatus(); } void ChangedIconsXStatus() { // reload icons CLISTMENUITEM mi; int i; ZeroMemory(&mi, sizeof(mi)); mi.cbSize = sizeof(mi); mi.flags = CMIM_FLAGS | CMIM_ICON; for (i = 1; i < 33; i++) { mi.hIcon = GetXStatusIcon(i); CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hXStatusItems[i], (LPARAM)&mi); if (!IconLibInstalled()) DestroyIcon(mi.hIcon); // if not IconLib resource release } } int IRCShowXStatusDetails(WPARAM wParam, LPARAM lParam) { InitXStatusData init; init.bAction = 1; // retrieve init.hContact = (HANDLE)wParam; DialogBoxUtf(FALSE, g_hInstance, MAKEINTRESOURCEA(IDD_SETXSTATUS), NULL, SetXStatusDlgProc, (LPARAM)&init); return 0; } int IRCSetXStatus(WPARAM wParam, LPARAM lParam) { if (wParam >= 0 && wParam <= 32) { setXStatusEx((BYTE)wParam, 1); return wParam; } return 0; } int IRCGetXStatusIcon(WPARAM wParam, LPARAM lParam) { if (!wParam) wParam = IRCGetContactSettingByte(NULL, DBSETTING_XSTATUSID, 0); if (wParam >= 1 && wParam <= 32) { HICON icon = GetXStatusIcon((BYTE)wParam); if (IconLibInstalled()) icon = CopyIcon(icon); return (int)icon; } return 0; } int IRCGetXStatus(WPARAM wParam, LPARAM lParam) { BYTE status = IRCGetContactSettingByte(NULL, DBSETTING_XSTATUSID, 0); if (GlobalStatus == ID_STATUS_OFFLINE) return 0; if (status < 1 || status > 32) status = 0; if (wParam) *((char**)wParam) = DBSETTING_XSTATUSNAME; if (lParam) *((char**)lParam) = DBSETTING_XSTATUSMSG; return status; } int IRCRequestXStatusDetails(WPARAM wParam, LPARAM lParam) { HANDLE hContact = (HANDLE)wParam; if (hContact && !IRCGetContactSettingByte(NULL, "XStatusAuto", DEFAULT_XSTATUS_AUTO) && IRCGetContactSettingByte(hContact, DBSETTING_XSTATUSID, 0)) { // user has xstatus, no auto-retrieve details, valid contact, request details return requestXStatusDetails(hContact, TRUE); } return 0; }