From cb4a46e7fbe62d788e66ed6121c717a2d22a4d7c Mon Sep 17 00:00:00 2001 From: watcherhd Date: Thu, 21 Apr 2011 14:14:52 +0000 Subject: svn.miranda.im is moving to a new home! git-svn-id: http://miranda-plugins.googlecode.com/svn/trunk@7 e753b5eb-9565-29b2-b5c5-2cc6f99dfbcb --- icqj_mod/icq_xstatus.c | 1249 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1249 insertions(+) create mode 100644 icqj_mod/icq_xstatus.c (limited to 'icqj_mod/icq_xstatus.c') diff --git a/icqj_mod/icq_xstatus.c b/icqj_mod/icq_xstatus.c new file mode 100644 index 0000000..4346fac --- /dev/null +++ b/icqj_mod/icq_xstatus.c @@ -0,0 +1,1249 @@ +// ---------------------------------------------------------------------------80 +// ICQ plugin for Miranda Instant Messenger +// ________________________________________ +// +// Copyright © 2000,2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede +// Copyright © 2001,2002 Jon Keating, Richard Hughes +// Copyright © 2002,2003,2004 Martin Öberg, Sam Kothari, Robert Rainwater +// Copyright © 2004,2005,2006 Angeli-Ka, Joe Kucera +// +// 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. +// +// ----------------------------------------------------------------------------- +// +// File name : $Source: /cvsroot/miranda/miranda/protocols/IcqOscarJ/icq_xstatus.c,v $ +// Revision : $Revision: 3075 $ +// Last change on : $Date: 2006-06-07 21:47:37 +0200 (st, 07 VI 2006) $ +// Last change by : $Author: jokusoftware $ +// +// DESCRIPTION: +// +// Support for Custom Statuses +// +// ----------------------------------------------------------------------------- + +#include "icqoscar.h" +#include "m_cluiframes.h" + + +extern void setUserInfo(); + +extern HANDLE hxstatusiconchanged; + +int bHideXStatusUI = 0; +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]; +static HANDLE hXStatusItems[33]; + +void CListShowMenuItem(HANDLE hMenuItem, BYTE bShow); +void CListSetMenuItemIcon(HANDLE hMenuItem, HICON hIcon); + + +DWORD sendXStatusDetailsRequest(HANDLE hContact, int bForced) +{ + char *szNotify; + int nNotifyLen; + DWORD dwCookie; + + nNotifyLen = 94 + UINMAXLEN; + szNotify = (char*)_alloca(nNotifyLen); + nNotifyLen = null_snprintf(szNotify, nNotifyLen, "cAwaySrvAwayStat1%d", dwLocalUIN); + + dwCookie = SendXtrazNotifyRequest(hContact, "srvMng", szNotify, bForced); + + return dwCookie; +} + + + +static DWORD requestXStatusDetails(HANDLE hContact, BOOL bAllowDelay) +{ + rate_record rr = {0}; + + if (!validateStatusMessageRequest(hContact, MTYPE_SCRIPT_NOTIFY)) + return 0; // apply privacy rules + + // delay is disabled only if fired from dialog + if (!CheckContactCapabilities(hContact, CAPF_XTRAZ) && bAllowDelay) + return 0; // Contact does not support xtraz, do not request details + + rr.hContact = hContact; + rr.bType = RIT_XSTATUS_REQUEST; + rr.rate_group = 0x101; // request + rr.nMinDelay = 1000; // delay at least 1s + + if (!handleRateItem(&rr, bAllowDelay)) + return sendXStatusDetailsRequest(hContact, !bAllowDelay); + + return -1; // delayed +} + + + +static char* InitXStatusIconLibrary(char* buf) +{ + 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 = LoadLibrary(path); + + if (!hXStatusIconsDLL) + { + strcpy(p, "\\Icons"); + strcat(p, "\\xstatus_icons.dll"); + hXStatusIconsDLL = LoadLibrary(path); + } + if (hXStatusIconsDLL) + { + strcpy(buf, path); + } + + return buf; +} + + + +HICON LoadDefaultXStatusIcon(int bStatus) +{ + if (hXStatusIconsDLL) + return LoadImage(hXStatusIconsDLL, MAKEINTRESOURCE(IDI_XSTATUS1 + bStatus - 1), IMAGE_ICON, 0, 0, 0); + else + return NULL; +} + + + +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) +{ + IconExtraColumn iec; + + iec.cbSize = sizeof(iec); + iec.hImage = hIcon; + iec.ColumnType = EXTRA_ICON_ADV1; + CallService(MS_CLIST_EXTRA_SET_ICON, (WPARAM)hContact, (LPARAM)&iec); + + NotifyEventHooks(hxstatusiconchanged, (WPARAM)hContact, (LPARAM)hIcon); +} + + + +static int CListMW_ExtraIconsRebuild(WPARAM wParam, LPARAM lParam) +{ + int i; + + if (gbXStatusEnabled && 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 (gbXStatusEnabled && ServiceExists(MS_CLIST_EXTRA_SET_ICON)) + { + if (IsICQContact((HANDLE)wParam)) + { // only apply icons to our contacts, do not mess others + DWORD bXStatus = ICQGetContactSettingByte((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 capstr capXStatus[32] = { + {0x01, 0xD8, 0xD7, 0xEE, 0xAC, 0x3B, 0x49, 0x2A, 0xA5, 0x8D, 0xD3, 0xD8, 0x77, 0xE6, 0x6B, 0x92}, + {0x5A, 0x58, 0x1E, 0xA1, 0xE5, 0x80, 0x43, 0x0C, 0xA0, 0x6F, 0x61, 0x22, 0x98, 0xB7, 0xE4, 0xC7}, + {0x83, 0xC9, 0xB7, 0x8E, 0x77, 0xE7, 0x43, 0x78, 0xB2, 0xC5, 0xFB, 0x6C, 0xFC, 0xC3, 0x5B, 0xEC}, + {0xE6, 0x01, 0xE4, 0x1C, 0x33, 0x73, 0x4B, 0xD1, 0xBC, 0x06, 0x81, 0x1D, 0x6C, 0x32, 0x3D, 0x81}, + {0x8C, 0x50, 0xDB, 0xAE, 0x81, 0xED, 0x47, 0x86, 0xAC, 0xCA, 0x16, 0xCC, 0x32, 0x13, 0xC7, 0xB7}, + {0x3F, 0xB0, 0xBD, 0x36, 0xAF, 0x3B, 0x4A, 0x60, 0x9E, 0xEF, 0xCF, 0x19, 0x0F, 0x6A, 0x5A, 0x7F}, + {0xF8, 0xE8, 0xD7, 0xB2, 0x82, 0xC4, 0x41, 0x42, 0x90, 0xF8, 0x10, 0xC6, 0xCE, 0x0A, 0x89, 0xA6}, + {0x80, 0x53, 0x7D, 0xE2, 0xA4, 0x67, 0x4A, 0x76, 0xB3, 0x54, 0x6D, 0xFD, 0x07, 0x5F, 0x5E, 0xC6}, + {0xF1, 0x8A, 0xB5, 0x2E, 0xDC, 0x57, 0x49, 0x1D, 0x99, 0xDC, 0x64, 0x44, 0x50, 0x24, 0x57, 0xAF}, + {0x1B, 0x78, 0xAE, 0x31, 0xFA, 0x0B, 0x4D, 0x38, 0x93, 0xD1, 0x99, 0x7E, 0xEE, 0xAF, 0xB2, 0x18}, + {0x61, 0xBE, 0xE0, 0xDD, 0x8B, 0xDD, 0x47, 0x5D, 0x8D, 0xEE, 0x5F, 0x4B, 0xAA, 0xCF, 0x19, 0xA7}, + {0x48, 0x8E, 0x14, 0x89, 0x8A, 0xCA, 0x4A, 0x08, 0x82, 0xAA, 0x77, 0xCE, 0x7A, 0x16, 0x52, 0x08}, + {0x10, 0x7A, 0x9A, 0x18, 0x12, 0x32, 0x4D, 0xA4, 0xB6, 0xCD, 0x08, 0x79, 0xDB, 0x78, 0x0F, 0x09}, + {0x6F, 0x49, 0x30, 0x98, 0x4F, 0x7C, 0x4A, 0xFF, 0xA2, 0x76, 0x34, 0xA0, 0x3B, 0xCE, 0xAE, 0xA7}, + {0x12, 0x92, 0xE5, 0x50, 0x1B, 0x64, 0x4F, 0x66, 0xB2, 0x06, 0xB2, 0x9A, 0xF3, 0x78, 0xE4, 0x8D}, + {0xD4, 0xA6, 0x11, 0xD0, 0x8F, 0x01, 0x4E, 0xC0, 0x92, 0x23, 0xC5, 0xB6, 0xBE, 0xC6, 0xCC, 0xF0}, + {0x60, 0x9D, 0x52, 0xF8, 0xA2, 0x9A, 0x49, 0xA6, 0xB2, 0xA0, 0x25, 0x24, 0xC5, 0xE9, 0xD2, 0x60}, + {0x63, 0x62, 0x73, 0x37, 0xA0, 0x3F, 0x49, 0xFF, 0x80, 0xE5, 0xF7, 0x09, 0xCD, 0xE0, 0xA4, 0xEE}, + {0x1F, 0x7A, 0x40, 0x71, 0xBF, 0x3B, 0x4E, 0x60, 0xBC, 0x32, 0x4C, 0x57, 0x87, 0xB0, 0x4C, 0xF1}, + {0x78, 0x5E, 0x8C, 0x48, 0x40, 0xD3, 0x4C, 0x65, 0x88, 0x6F, 0x04, 0xCF, 0x3F, 0x3F, 0x43, 0xDF}, + {0xA6, 0xED, 0x55, 0x7E, 0x6B, 0xF7, 0x44, 0xD4, 0xA5, 0xD4, 0xD2, 0xE7, 0xD9, 0x5C, 0xE8, 0x1F}, + {0x12, 0xD0, 0x7E, 0x3E, 0xF8, 0x85, 0x48, 0x9E, 0x8E, 0x97, 0xA7, 0x2A, 0x65, 0x51, 0xE5, 0x8D}, + {0xBA, 0x74, 0xDB, 0x3E, 0x9E, 0x24, 0x43, 0x4B, 0x87, 0xB6, 0x2F, 0x6B, 0x8D, 0xFE, 0xE5, 0x0F}, + {0x63, 0x4F, 0x6B, 0xD8, 0xAD, 0xD2, 0x4A, 0xA1, 0xAA, 0xB9, 0x11, 0x5B, 0xC2, 0x6D, 0x05, 0xA1}, + {0x2C, 0xE0, 0xE4, 0xE5, 0x7C, 0x64, 0x43, 0x70, 0x9C, 0x3A, 0x7A, 0x1C, 0xE8, 0x78, 0xA7, 0xDC}, + {0x10, 0x11, 0x17, 0xC9, 0xA3, 0xB0, 0x40, 0xF9, 0x81, 0xAC, 0x49, 0xE1, 0x59, 0xFB, 0xD5, 0xD4}, + {0x16, 0x0C, 0x60, 0xBB, 0xDD, 0x44, 0x43, 0xF3, 0x91, 0x40, 0x05, 0x0F, 0x00, 0xE6, 0xC0, 0x09}, + {0x64, 0x43, 0xC6, 0xAF, 0x22, 0x60, 0x45, 0x17, 0xB5, 0x8C, 0xD7, 0xDF, 0x8E, 0x29, 0x03, 0x52}, + {0x16, 0xF5, 0xB7, 0x6F, 0xA9, 0xD2, 0x40, 0x35, 0x8C, 0xC5, 0xC0, 0x84, 0x70, 0x3C, 0x98, 0xFA}, + {0x63, 0x14, 0x36, 0xff, 0x3f, 0x8a, 0x40, 0xd0, 0xa5, 0xcb, 0x7b, 0x66, 0xe0, 0x51, 0xb3, 0x64}, + {0xb7, 0x08, 0x67, 0xf5, 0x38, 0x25, 0x43, 0x27, 0xa1, 0xff, 0xcf, 0x4c, 0xc1, 0x93, 0x97, 0x97}, + {0xdd, 0xcf, 0x0e, 0xa9, 0x71, 0x95, 0x40, 0x48, 0xa9, 0xc6, 0x41, 0x32, 0x06, 0xd6, 0xf2, 0x80}}; + +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", + "Watching pro7 on TV", + "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(&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; + HICON hDlgIcon; +} 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->type != ICQACKTYPE_XSTATUS_RESPONSE) break; + 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,ICQTranslateUtfStatic("Close", str)); + UnhookEvent(dat->hEvent); dat->hEvent = NULL; + szText = ICQGetContactSettingUtf(dat->hContact, DBSETTING_XSTATUSNAME, ""); + SetDlgItemTextUtf(hwndDlg, IDC_XTITLE, szText); + SAFE_FREE(&szText); + szText = ICQGetContactSettingUtf(dat->hContact, DBSETTING_XSTATUSMSG, ""); + SetDlgItemTextUtf(hwndDlg, IDC_XMSG, szText); + SAFE_FREE(&szText); + + break; + } + case WM_INITDIALOG: + { + InitXStatusData *init = (InitXStatusData*)lParam; + + ICQTranslateDialog(hwndDlg); + dat = (SetXStatusData*)SAFE_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 = ICQGetContactSettingUtf(NULL, szSetting, ""); + SetDlgItemTextUtf(hwndDlg, IDC_XTITLE, szValue); + SAFE_FREE(&szValue); + + sprintf(szSetting, "XStatus%dMsg", dat->bXStatus); + szValue = ICQGetContactSettingUtf(NULL, szSetting, ""); + SetDlgItemTextUtf(hwndDlg, IDC_XMSG, szValue); + SAFE_FREE(&szValue); + } + else + { // retrieve contact's xStatus + dat->hContact = init->hContact; + dat->bXStatus = ICQGetContactSettingByte(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 (!ICQGetContactSettingByte(NULL, "XStatusAuto", DEFAULT_XSTATUS_AUTO)) + { + SetDlgItemTextUtf(hwndDlg,IDOK,ICQTranslateUtfStatic("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,ICQTranslateUtfStatic("Close", str)); + dat->hEvent = NULL; + szText = ICQGetContactSettingUtf(dat->hContact, DBSETTING_XSTATUSNAME, ""); + SetDlgItemTextUtf(hwndDlg, IDC_XTITLE, szText); + SAFE_FREE(&szText); + szText = ICQGetContactSettingUtf(dat->hContact, DBSETTING_XSTATUSMSG, ""); + SetDlgItemTextUtf(hwndDlg, IDC_XMSG, szText); + SAFE_FREE(&szText); + } + } + + if (dat->bXStatus) + { + HICON iXStatus = GetXStatusIcon(dat->bXStatus); + + dat->hDlgIcon = iXStatus; + } + SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)dat->hDlgIcon); + + { + char *format; + char buf[MAX_PATH]; + + format = GetWindowTextUtf(hwndDlg); + null_snprintf(str, sizeof(str), format, dat->bXStatus?ICQTranslateUtfStatic(nameXStatus[dat->bXStatus-1], buf):""); + SetWindowTextUtf(hwndDlg, str); + SAFE_FREE(&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,ICQTranslateUtfStatic("OK", str)); + } + break; + } + break; + + case WM_DESTROY: + if (!dat->bAction) + { // set our xStatus + char szSetting[64]; + char* szValue; + char *ansi = NULL; + CLISTMENUITEM mi = {0}; + szValue = GetDlgItemTextUtf(hwndDlg,IDC_XMSG); + sprintf(szSetting, "XStatus%dMsg", dat->bXStatus); + ICQWriteContactSettingUtf(NULL, szSetting, szValue); + ICQWriteContactSettingUtf(NULL, DBSETTING_XSTATUSMSG, szValue); + SAFE_FREE(&szValue); + szValue = GetDlgItemTextUtf(hwndDlg,IDC_XTITLE); + sprintf(szSetting, "XStatus%dName", dat->bXStatus); + ICQWriteContactSettingUtf(NULL, szSetting, szValue); + ICQWriteContactSettingUtf(NULL, DBSETTING_XSTATUSNAME, szValue); + mi.cbSize = sizeof(mi); + utf8_decode(szValue, &ansi); + mi.pszName = strlen(ansi) > 0 ? ansi : ICQTranslate(nameXStatus[dat->bXStatus-1]); + mi.flags = CMIM_NAME; + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hXStatusItems[dat->bXStatus], (LPARAM)&mi); + + SAFE_FREE(&szValue); + SAFE_FREE(&ansi); + + + setUserInfo(); + + 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(&dat->okButtonFormat); + if (dat->hDlgIcon && !IconLibInstalled()) + DestroyIcon(dat->hDlgIcon); // release dialog icon + SAFE_FREE(&dat); + break; + + case WM_CLOSE: + DestroyWindow(hwndDlg); + break; + } + return FALSE; +} + + + +static void setXStatusEx(BYTE bXStatus, BYTE bQuiet) +{ + + CLISTMENUITEM mi = {0}; + BYTE bOldXStatus = ICQGetContactSettingByte(NULL, DBSETTING_XSTATUSID, 0); + + mi.cbSize = sizeof(mi); + + if (bOldXStatus <= 32) + { + mi.flags = CMIM_FLAGS; + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hXStatusItems[bOldXStatus], (LPARAM)&mi); + } + + + ICQWriteContactSettingByte(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 = ICQGetContactSettingUtf(NULL, szSetting, ICQTranslateUtfStatic(nameXStatus[bXStatus-1], str)); + ICQWriteContactSettingUtf(NULL, DBSETTING_XSTATUSNAME, szUtf); + SAFE_FREE(&szUtf); + + sprintf(szSetting, "XStatus%dMsg", bXStatus); + szUtf = ICQGetContactSettingUtf(NULL, szSetting, ""); + ICQWriteContactSettingUtf(NULL, DBSETTING_XSTATUSMSG, szUtf); + SAFE_FREE(&szUtf); + + sprintf(szSetting, "XStatus%dStat", bXStatus); + if (!bQuiet && !ICQGetContactSettingByte(NULL, szSetting, 0)) + { + InitXStatusData init; + + init.bAction = 0; // set + init.bXStatus = bXStatus; + DialogBoxUtf(FALSE, hInst, MAKEINTRESOURCEA(IDD_SETXSTATUS),NULL,SetXStatusDlgProc,(LPARAM)&init); + } + else + setUserInfo(); + } + else + { + ICQDeleteContactSetting(NULL, DBSETTING_XSTATUSNAME); + ICQDeleteContactSetting(NULL, DBSETTING_XSTATUSMSG); + + setUserInfo(); + } +} + + + +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 = ICQGetContactSettingByte(NULL, DBSETTING_XSTATUSID, 0); + + if (!gbXStatusEnabled) return; + + if (bStatusMenu && !bAllowStatus) return; + + null_snprintf(szItem, sizeof(szItem), ICQTranslate("%s Custom Status"), gpszICQProtoName); + mi.cbSize = sizeof(mi); + mi.pszPopupName = szItem; + mi.popupPosition= 500084000; + mi.position = 2000040000; + + for(i = 0; i <= 32; i++) + { + char szTemp[64]; + char* szValue; + char* ansi = NULL; + HICON hIIcon = (i > 0) ? LoadDefaultXStatusIcon(i) : NULL; + + null_snprintf(srvFce, sizeof(srvFce), "%s/menuXStatus%d", gpszICQProtoName, 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; + + sprintf(szTemp, "XStatus%dName", i); + szValue = ICQGetContactSettingUtf(NULL, szTemp, ""); + + utf8_decode(szValue, &ansi); + mi.pszName = (strlen(ansi) == 0) ? ICQTranslate(i?nameXStatus[i-1]:"None") : ansi; + mi.pszService = srvFce; + mi.pszContactOwner = gpszICQProtoName; + + 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); + SAFE_FREE(&szValue); + SAFE_FREE(&ansi); + + } + + bXStatusMenuBuilt = 1; +} + + + +void InitXStatusIcons() +{ + char szSection[MAX_PATH + 64]; + char str[MAX_PATH], prt[MAX_PATH]; + char lib[2*MAX_PATH] = {0}; + char* icon_lib; + int i; + + if (!gbXStatusEnabled) return; + + icon_lib = InitXStatusIconLibrary(lib); + + null_snprintf(szSection, sizeof(szSection), ICQTranslateUtfStatic("%s/Custom Status", str), ICQTranslateUtfStatic(gpszICQProtoName, prt)); + + for (i = 0; i < 32; i++) + { + char szTemp[64]; + + null_snprintf(szTemp, sizeof(szTemp), "xstatus%d", i); + IconLibDefine(ICQTranslateUtfStatic(nameXStatus[i], str), szSection, szTemp, NULL, icon_lib, -(IDI_XSTATUS1+i)); + } + + if (bXStatusMenuBuilt) + ChangedIconsXStatus(); +} + + + +void ChangedIconsXStatus() +{ // reload icons + int i; + + if (!gbXStatusEnabled) return; + + for (i = 1; i < 33; i++) + { + HICON hIcon = GetXStatusIcon(i); + + CListSetMenuItemIcon(hXStatusItems[i], hIcon); + if (!IconLibInstalled()) + DestroyIcon(hIcon); // if not IconLib resource release + } +} + + + +int IcqShowXStatusDetails(WPARAM wParam, LPARAM lParam) +{ + InitXStatusData init; + + init.bAction = 1; // retrieve + init.hContact = (HANDLE)wParam; + DialogBoxUtf(FALSE, hInst, MAKEINTRESOURCEA(IDD_SETXSTATUS), NULL, SetXStatusDlgProc, (LPARAM)&init); + + return 0; +} + + + +int IcqSetXStatus(WPARAM wParam, LPARAM lParam) +{ // obsolete (TODO: remove in next version) + if (!gbXStatusEnabled) return 0; + + if (wParam >= 0 && wParam <= 32) + { + setXStatusEx((BYTE)wParam, 1); + + return wParam; + } + return 0; +} + + + +int IcqGetXStatus(WPARAM wParam, LPARAM lParam) +{ // obsolete (TODO: remove in next version) + BYTE status = ICQGetContactSettingByte(NULL, DBSETTING_XSTATUSID, 0); + + if (!gbXStatusEnabled) return 0; + + if (!icqOnline) return 0; + + if (status < 1 || status > 32) status = 0; + + if (wParam) *((char**)wParam) = DBSETTING_XSTATUSNAME; + if (lParam) *((char**)lParam) = DBSETTING_XSTATUSMSG; + + return status; +} + + + +int IcqSetXStatusEx(WPARAM wParam, LPARAM lParam) +{ + ICQ_CUSTOM_STATUS *pData = (ICQ_CUSTOM_STATUS*)lParam; + + if (!gbXStatusEnabled) return 1; + + if (pData->cbSize < sizeof(ICQ_CUSTOM_STATUS)) return 1; // Failure + + if (pData->flags & CSSF_MASK_STATUS) + { // set custom status + int status = *pData->status; + + if (status >= 0 && status <= 32) + { + setXStatusEx((BYTE)status, 1); + } + else + return 1; // Failure + } + + if (pData->flags & (CSSF_MASK_NAME | CSSF_MASK_MESSAGE)) + { + BYTE status = ICQGetContactSettingByte(NULL, DBSETTING_XSTATUSID, 0); + + if (status < 1 || status > 32) return 1; // Failure + + if (pData->flags & CSSF_MASK_NAME) + { // set custom status name + if (pData->flags & CSSF_UNICODE) + { + char* utf = make_utf8_string(pData->pwszName); + + ICQWriteContactSettingUtf(NULL, DBSETTING_XSTATUSNAME, utf); + SAFE_FREE(&utf); + } + else + ICQWriteContactSettingString(NULL, DBSETTING_XSTATUSNAME, pData->pszName); + } + if (pData->flags & CSSF_MASK_MESSAGE) + { // set custom status message + if (pData->flags & CSSF_UNICODE) + { + char* utf = make_utf8_string(pData->pwszMessage); + + ICQWriteContactSettingUtf(NULL, DBSETTING_XSTATUSMSG, utf); + SAFE_FREE(&utf); + } + else + ICQWriteContactSettingString(NULL, DBSETTING_XSTATUSMSG, pData->pszMessage); + } + } + + if (pData->flags & CSSF_DISABLE_UI) + { // hide menu items + int n; + + bHideXStatusUI = (*pData->wParam) ? 0 : 1; + + for (n = 0; n<=32; n++) + CListShowMenuItem(hXStatusItems[n], (BYTE)!bHideXStatusUI); + } + + return 0; // Success +} + + + +int IcqGetXStatusEx(WPARAM wParam, LPARAM lParam) +{ + ICQ_CUSTOM_STATUS *pData = (ICQ_CUSTOM_STATUS*)lParam; + HANDLE hContact = (HANDLE)wParam; + + if (!gbXStatusEnabled) return 1; + + if (pData->cbSize < sizeof(ICQ_CUSTOM_STATUS)) return 1; // Failure + + if (pData->flags & CSSF_MASK_STATUS) + { // fill status member + *pData->status = ICQGetContactSettingByte(NULL, DBSETTING_XSTATUSID, 0); + } + + if (pData->flags & CSSF_MASK_NAME) + { // fill status name member + if (pData->flags & CSSF_DEFAULT_NAME) + { + int status = *pData->wParam; + + if (status < 1 || status > 32) return 1; // Failure + + if (pData->flags & CSSF_UNICODE) + { + char *text = (char*)nameXStatus[status -1]; + + MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, text, strlennull(text), pData->pwszName, MAX_PATH); + } + else + strcpy(pData->pszName, nameXStatus[status - 1]); + } + else + { + if (pData->flags & CSSF_UNICODE) + { + char* str = ICQGetContactSettingUtf(hContact, DBSETTING_XSTATUSNAME, ""); + wchar_t* wstr = make_unicode_string(str); + + wcscpy(pData->pwszName, wstr); + SAFE_FREE(&str); + SAFE_FREE(&wstr); + } + else + { + DBVARIANT dbv = {0}; + + ICQGetContactSetting(hContact, DBSETTING_XSTATUSNAME, &dbv); + strcpy(pData->pszName, dbv.pszVal); + + ICQFreeVariant(&dbv); + } + } + } + + if (pData->flags & CSSF_MASK_MESSAGE) + { // fill status message member + if (pData->flags & CSSF_UNICODE) + { + char* str = ICQGetContactSettingUtf(hContact, DBSETTING_XSTATUSMSG, ""); + wchar_t* wstr = make_unicode_string(str); + + wcscpy(pData->pwszMessage, wstr); + SAFE_FREE(&str); + SAFE_FREE(&wstr); + } + else + { + DBVARIANT dbv = {0}; + + ICQGetContactSetting(hContact, DBSETTING_XSTATUSMSG, &dbv); + strcpy(pData->pszMessage, dbv.pszVal); + + ICQFreeVariant(&dbv); + } + } + + if (pData->flags & CSSF_DISABLE_UI) + { + if (pData->wParam) *pData->wParam = !bHideXStatusUI; + } + + if (pData->flags & CSSF_STATUSES_COUNT) + { + if (pData->wParam) *pData->wParam = 32; + } + + if (pData->flags & CSSF_STR_SIZES) + { + DBVARIANT dbv = {0}; + + if (pData->wParam) + { + if (!ICQGetContactSetting(hContact, DBSETTING_XSTATUSNAME, &dbv)) + { + *pData->wParam = strlennull(dbv.pszVal); + ICQFreeVariant(&dbv); + } + else + *pData->wParam = 0; + } + if (pData->lParam) + { + if (!ICQGetContactSetting(hContact, DBSETTING_XSTATUSMSG, &dbv)) + { + *pData->lParam = strlennull(dbv.pszVal); + ICQFreeVariant(&dbv); + } + else + *pData->lParam = 0; + } + } + + return 0; // Success +} + + + +int IcqGetXStatusIcon(WPARAM wParam, LPARAM lParam) +{ + if (!gbXStatusEnabled) return 0; + + if (!wParam) + wParam = ICQGetContactSettingByte(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 IcqRequestXStatusDetails(WPARAM wParam, LPARAM lParam) +{ + HANDLE hContact = (HANDLE)wParam; + + if (!gbXStatusEnabled) return 0; + + if (hContact && !ICQGetContactSettingByte(NULL, "XStatusAuto", DEFAULT_XSTATUS_AUTO) && + ICQGetContactSettingByte(hContact, DBSETTING_XSTATUSID, 0)) + { // user has xstatus, no auto-retrieve details, valid contact, request details + return requestXStatusDetails(hContact, TRUE); + } + return 0; +} -- cgit v1.2.3