diff options
Diffstat (limited to 'ExternalAPI')
-rw-r--r-- | ExternalAPI/m_ContactSettings.h | 235 | ||||
-rw-r--r-- | ExternalAPI/m_DataAsMessage.h | 182 | ||||
-rw-r--r-- | ExternalAPI/m_LogService.h | 217 | ||||
-rw-r--r-- | ExternalAPI/m_NewAwaySys.h | 2 |
4 files changed, 635 insertions, 1 deletions
diff --git a/ExternalAPI/m_ContactSettings.h b/ExternalAPI/m_ContactSettings.h new file mode 100644 index 0000000..3f58d4c --- /dev/null +++ b/ExternalAPI/m_ContactSettings.h @@ -0,0 +1,235 @@ +/*
+ Contact Settings plugin for Miranda IM
+ Copyright (c) 2007-2008 Chervov Dmitry
+
+ 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
+*/
+
+#ifndef __M_CONTACTSETTINGS_H
+#define __M_CONTACTSETTINGS_H
+
+
+typedef struct {
+ int cbSize; // sizeof(CONTACTSETTINGSINIT)
+ int Type; // one of CSIT_ constants; value of this field depends on what settings dialog was opened: contact settings or group settings
+ union
+ {
+ HANDLE hContact; // used when Type == CSIT_CONTACT
+ int groupID; // used when Type == CSIT_GROUP
+ };
+} CONTACTSETTINGSINIT;
+
+// CONTACTSETTINGSINIT::Type
+#define CSIT_CONTACT 1 // CONTACTSETTINGSINIT::hContact is valid
+#define CSIT_GROUP 2 // CONTACTSETTINGSINIT::groupID is valid; in general, if Type == CSIT_GROUP, you MUST call MS_CONTACTSETTINGS_ADDCONTROL and add _all_ your per-contact controls, independently of current group contents, because potentially the group can contain any contacts in future.
+
+/* ME_CONTACTSETTINGS_INITIALISE
+The user opened a contact settings dialog. Modules should do whatever initialisation they need and call MS_CONTACTSETTINGS_ADDCONTROL one or more times if they want controls displayed in the dialog
+wParam=(WPARAM)(CONTACTSETTINGSINIT*)csi
+lParam=0
+*/
+#define ME_CONTACTSETTINGS_INITIALISE "ContactSettings/Init"
+
+
+/* MS_CONTACTSETTINGS_ADDCONTROL
+Must only be called during a ME_CONTACTSETTINGS_INITIALISE hook
+Adds a control to the contact settings dialog
+wParam=(WPARAM)(CONTACTSETTINGSINIT*)csi
+lParam=(LPARAM)(CONTACTSETTINGSCONTROL*)csc
+Returns 0 on success, nonzero on failure
+csi must have come straight from the wParam of ME_CONTACTSETTINGS_INITIALISE
+Strings in the structure can be released as soon as the service returns.
+*/
+
+// CONTACTSETTINGSCONTROL::Position
+#define CSPOS_SORTBYALPHABET 0x40000000 // recommended value for Position if you don't need a specific sorting order
+// Group = "Notifications":
+#define CSPOS_NOTIFICATIONS_SERVICES 0x20000000 // recommended control position for notification SERVICE PROVIDERS (popups, osd, tickers, etc). Notification plugins that use these services should use CSPOS_SORTBYALPHABET, so that notification service provider settings are above any other specific notification settings.
+
+// CONTACTSETTINGSCONTROL::Flags
+#define CSCF_UNICODE 1 // string fields in CONTACTSETTINGSCONTROL and CSCONTROLSTATE are WCHAR*
+#define CSCF_DONT_TRANSLATE_STRINGS 2 // specifies that strings in CONTACTSETTINGSCONTROL and CSCONTROLSTATE are translated already
+
+#ifdef _UNICODE
+#define CSCF_TCHAR CSCF_UNICODE
+#else
+#define CSCF_TCHAR 0
+#endif
+
+// CONTACTSETTINGSCONTROL::ControlType
+typedef enum
+{
+ CSCT_LABEL = -1, // CSCT_LABEL is used internally in ContactSettings, and mustn't be used by other plugins
+ CSCT_CHECKBOX, // checkbox control
+ CSCT_COMBOBOX // combobox control with a title above it
+} CSCONTROLTYPE;
+
+// some common values for CONTACTSETTINGSCONTROL::ptszGroup
+#define CSGROUP_NOTIFICATIONS LPGENT("Notifications")
+
+// special values for CONTACTSETTINGSCONTROL::szModule
+#define CSMODULE_PROTO "%proto%" // ContactSettings will replace this by contact's protocol module name
+
+struct CSCONTROLSTATE
+{
+#ifdef __cplusplus
+ CSCONTROLSTATE(): ptszName(NULL) {dbvValue.type = 0; dbvValue.dVal = 0; dbvValue.pbVal = 0; }
+ CSCONTROLSTATE(char *pszName, BYTE Value) { this->pszName = pszName; dbvValue.type = DBVT_BYTE; dbvValue.bVal = Value; }
+ CSCONTROLSTATE(char *pszName, char Value) { this->pszName = pszName; dbvValue.type = DBVT_BYTE; dbvValue.cVal = Value; }
+ CSCONTROLSTATE(char *pszName, WORD Value) { this->pszName = pszName; dbvValue.type = DBVT_WORD; dbvValue.wVal = Value; }
+ CSCONTROLSTATE(char *pszName, short Value) { this->pszName = pszName; dbvValue.type = DBVT_WORD; dbvValue.sVal = Value; }
+ CSCONTROLSTATE(char *pszName, DWORD Value) { this->pszName = pszName; dbvValue.type = DBVT_DWORD; dbvValue.dVal = Value; }
+ CSCONTROLSTATE(char *pszName, long Value) { this->pszName = pszName; dbvValue.type = DBVT_DWORD; dbvValue.lVal = Value; }
+ CSCONTROLSTATE(char *pszName, const char *szValue) { this->pszName = pszName; dbvValue.type = DBVT_ASCIIZ; dbvValue.pszVal = (char*)szValue; }
+ CSCONTROLSTATE(char *pszName, const WCHAR *wszValue) { this->pszName = pszName; dbvValue.type = DBVT_WCHAR; dbvValue.pwszVal = (WCHAR*)wszValue; }
+ CSCONTROLSTATE(WCHAR *pwszName, BYTE Value) { this->pwszName = pwszName; dbvValue.type = DBVT_BYTE; dbvValue.bVal = Value; }
+ CSCONTROLSTATE(WCHAR *pwszName, char Value) { this->pwszName = pwszName; dbvValue.type = DBVT_BYTE; dbvValue.cVal = Value; }
+ CSCONTROLSTATE(WCHAR *pwszName, WORD Value) { this->pwszName = pwszName; dbvValue.type = DBVT_WORD; dbvValue.wVal = Value; }
+ CSCONTROLSTATE(WCHAR *pwszName, short Value) { this->pwszName = pwszName; dbvValue.type = DBVT_WORD; dbvValue.sVal = Value; }
+ CSCONTROLSTATE(WCHAR *pwszName, DWORD Value) { this->pwszName = pwszName; dbvValue.type = DBVT_DWORD; dbvValue.dVal = Value; }
+ CSCONTROLSTATE(WCHAR *pwszName, long Value) { this->pwszName = pwszName; dbvValue.type = DBVT_DWORD; dbvValue.lVal = Value; }
+ CSCONTROLSTATE(WCHAR *pwszName, const char *szValue) { this->pwszName = pwszName; dbvValue.type = DBVT_ASCIIZ; dbvValue.pszVal = (char*)szValue; }
+ CSCONTROLSTATE(WCHAR *pwszName, const WCHAR *wszValue) { this->pwszName = pwszName; dbvValue.type = DBVT_WCHAR; dbvValue.pwszVal = (WCHAR*)wszValue; }
+#endif
+
+ union
+ {
+ TCHAR *ptszName; // item text for CSCT_COMBOBOX; not used for CSCT_CHECKBOX
+ char *pszName;
+ WCHAR *pwszName;
+ };
+ DBVARIANT dbvValue; // database value for this state
+};
+
+// WARNING: do not use Translate(TS) for ptszTitle, ptszGroup, ptszTooltip or CSCONTROLSTATE::ptszName as they are translated by ContactSettings. The only exception is when you use CSCF_DONT_TRANSLATE_STRINGS flag
+typedef struct {
+ int cbSize; // sizeof(CONTACTSETTINGSCONTROL)
+ int cbStateSize; // sizeof(CSCONTROLSTATE)
+ int Position; // position in the group, lower numbers are topmost. CSPOS_SORTBYALPHABET is recommended if you don't need a specific sorting order
+ DWORD Flags; // a combination of CSCF_ constants
+ CSCONTROLTYPE ControlType; // one of CSCT_ constants
+ union
+ {
+ TCHAR *ptszTitle; // label above the control
+ char *pszTitle;
+ WCHAR *pwszTitle;
+ };
+ union
+ {
+ TCHAR *ptszGroup; // group title (several controls may be grouped together); may be NULL.
+ char *pszGroup;
+ WCHAR *pwszGroup;
+ };
+ union
+ {
+ TCHAR *ptszTooltip; // tooltip for the control; may be NULL
+ char *pszTooltip;
+ WCHAR *pwszTooltip;
+ };
+ const char *szModule; // database module; may contain variables (see above; currently the only existing variable is CSMODULE_PROTO)
+ const char *szSetting; // database setting
+ int StateNum; // number of possible states; always 2 or 3 for CSCT_CHECKBOX, and can be any number starting from 2 for CSCT_COMBOBOX
+ int DefState; // default state index
+ CSCONTROLSTATE *pStates; // array of StateNum items, describing all possible control states. Can be NULL for CSCT_COMBOBOX, in this case ContactSettings will use DBVT_BYTE database values, 0 is unchecked, 1 is checked, 2 is indeterminate. Can't be NULL for CSCT_COMBOBOX.
+ DWORD ValueMask; // in most cases simply set this to 0. when not 0, it allows to define a bit mask to access separate bits of a db value instead of reading/writing the whole value. is valid only for DBVT_BYTE, DBVT_WORD and DBVT_DWORD values
+} CONTACTSETTINGSCONTROL;
+
+#define MS_CONTACTSETTINGS_ADDCONTROL "ContactSettings/AddControl"
+
+
+typedef struct {
+ int cbSize; // sizeof(CONTACTSETTINGSCHANGEINFO)
+ HANDLE hContact;
+ const char *szModule; // variables in szModule and szSetting are NOT parsed, i.e. ContactSettings copies the values straight from CONTACTSETTINGSCONTROL
+ const char *szSetting;
+} CONTACTSETTINGSCHANGEINFO;
+
+/* ME_CONTACTSETTINGS_SETTINGCHANGED
+Called for every changed setting when the user applied changes in a contact settings dialog
+wParam=(WPARAM)(CONTACTSETTINGSCHANGEINFO*)csci
+lParam=0
+This event will be triggered many times rapidly when a whole bunch of values are set.
+Modules which hook this should be aware of this fact and quickly return if they are not interested in the value that has been changed.
+*/
+#define ME_CONTACTSETTINGS_SETTINGCHANGED "ContactSettings/SettingChanged"
+
+
+/* MS_CONTACTSETTINGS_SHOWDIALOG
+Shows Contact Settings dialog for a contact
+wParam=hContact
+lParam=0
+*/
+#define MS_CONTACTSETTINGS_SHOWDIALOG "ContactSettings/ShowDialog"
+
+/* MS_CONTACTSETTINGS_SHOWGROUPDIALOG. Not implemented yet.
+Shows dialog for a group
+wParam=groupId (0 is the main group)
+lParam=0
+*/
+#define MS_CONTACTSETTINGS_SHOWGROUPDIALOG "ContactSettings/ShowGroupDialog"
+
+
+/*
+Example of use:
+
+// in ME_SYSTEM_MODULESLOADED handler:
+ HookEvent(ME_CONTACTSETTINGS_INITIALISE, ContactSettingsInit);
+
+// ME_CONTACTSETTINGS_INITIALISE handler
+static int ContactSettingsInit(WPARAM wParam, LPARAM lParam)
+{
+ CONTACTSETTINGSINIT *csi = (CONTACTSETTINGSINIT*)wParam;
+
+// check first whether to add controls or not
+// we need to get a protocol name for that, if it's a contact settings dialog:
+ char *szProto = (csi->Type == CSIT_CONTACT) ? (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)csi->hContact, 0) : NULL;
+// in general, you MUST add all your controls if csi->Type == CSIT_GROUP (i.e. user opened a group settings dialog), otherwise your plugin won't support group settings well:
+ if ((csi->Type == CSIT_GROUP) ||
+// otherwise (for a contact settings dialog), you can add controls depending on some conditions, like protocol caps, etc.
+// in this example, we check whether the protocol has a PS_GETCUSTOMSTATUSICON service (i.e. does it support xstatuses or not):
+ (csi->Type == CSIT_CONTACT && szProto && ProtoServiceExists(szProto, PS_GETCUSTOMSTATUSICON)))
+// your plugin must ignore cases when csi->Type is neither CSIT_GROUP nor CSIT_CONTACT
+ {
+ CONTACTSETTINGSCONTROL csc = {0};
+ csc.cbSize = sizeof(csc);
+ csc.Position = CSPOS_SORTBYALPHABET;
+ csc.Flags = CSCF_TCHAR;
+ csc.ControlType = CSCT_COMBOBOX;
+ csc.StateNum = 3;
+ csc.ptszTitle = LPGENT("XStatus change notifications:") _T("\0") LPGENT("Ignore") _T("\0") LPGENT("Notify always") _T("\0") LPGENT("Use global settings") _T("\0");
+ csc.ptszGroup = CSGROUP_NOTIFICATIONS;
+ csc.ptszTooltip = LPGENT("Tooltip text");
+ csc.pszDBSetting = "ModuleName/XSNotifications";
+ csc.DefValue = 2; // "Use global settings"
+ CallService(MS_CONTACTSETTINGS_ADDCONTROL, wParam, (LPARAM)&csc);
+
+ // and CSCT_CHECKBOX example:
+ csc.Position = CSPOS_SORTBYALPHABET;
+ csc.Flags = CSCF_TCHAR;
+ csc.ControlType = CSCT_CHECKBOX;
+ csc.StateNum = 3;
+ csc.ptszTitle = LPGENT("Other setting");
+ csc.ptszGroup = LPGENT("Some group");
+ csc.ptszTooltip = LPGENT("Tooltip text");
+ csc.pszDBSetting = "ModuleName/OtherSetting";
+ csc.DefValue = 2; // BST_INDETERMINATE
+ CallService(MS_CONTACTSETTINGS_ADDCONTROL, wParam, (LPARAM)&csc);
+ }
+ return 0;
+}
+
+*/
+
+#endif // __M_CONTACTSETTINGS_H
diff --git a/ExternalAPI/m_DataAsMessage.h b/ExternalAPI/m_DataAsMessage.h new file mode 100644 index 0000000..2f1f2eb --- /dev/null +++ b/ExternalAPI/m_DataAsMessage.h @@ -0,0 +1,182 @@ +/*
+ DataAsMessage plugin for Miranda IM
+ Copyright (c) 2006-2007 Chervov Dmitry
+
+ 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
+*/
+
+#ifndef __M_DATAASMESSAGE_H
+#define __M_DATAASMESSAGE_H
+
+// DAM_SENDRESULTINFO::iResult values
+#define DAM_SR_SUCCESS 0
+#define DAM_SR_TIMEOUT 1 // timeout period expired; this value is returned also if the contact went offline for a time longer than a timeout period
+#define DAM_SR_NOTSUPPORTED 2 // means this szDataType is not supported by the remote side
+#define DAM_SR_NODAM 3 // means there is no DataAsMessage plugin on the remote side; keep in mind that this error can also appear accidentally because of a bad connectivity during the handshake (if there was a timeout when waiting for a response)
+#define DAM_SR_CANCELLEDLOCAL 4 // cancelled from the local(sending) side
+#define DAM_SR_CANCELLEDREMOTE 5 // cancelled from the remote(receiving) side
+#define DAM_SR_BADCRC 6 // bad CRC; we can't do anything with this error. the most probable cause is that protocol filters some of characters in our messages
+#define DAM_SR_UNKNOWN 7 // unknown error
+
+// Return values for DAM_SENDRESULTPROC
+#define DAM_SRA_RETRY 1
+
+typedef struct
+{
+ int cbSize; // sizeof(DAM_SENDRESULTINFO)
+ HANDLE hContact;
+ char *szDataType;
+ DWORD SessionID;
+ int iResult; // transmission result code
+} DAM_SENDRESULTINFO; // hContact, szDataType and SessionID fields correspond to the fields of the DAM_SENDDATAINFO structure
+
+typedef int (*DAM_SENDRESULTPROC)(DAM_SENDRESULTINFO *sri); // this procedure receives the result of the transmission. it's called when the session closes (either the data was sent successfully or there was an error)
+// you can return DAM_SRA_RETRY when iResult is DAM_SR_TIMEOUT if you want to retry sending
+
+
+// DAM_SENDDATAINFO::Flags constants
+#define DAM_SDF_DONTPACK 1 // don't compress the data (by default all the data is compressed)
+#define DAM_SDF_NOTIMEOUT 2 // don't generate a timeout error ever, keep trying to send the data. If the contact is offline, the data is saved in the memory until the contact goes online. Loss of the data occurs only if the sender's miranda closes (this may change in future to allow fully functional offline sending that will guarantee the data to be sent in any case, but of course the sending starts only when the both contacts are online). other errors than the timeout error can be still generated though.
+
+typedef struct
+{
+ int cbSize; // sizeof(DAM_SENDDATAINFO)
+ HANDLE hContact;
+ char *szDataType; // zero-terminated string, containing data type, preferably in format "YourPluginName" or "YourPluginName/Something" (make sure this string won't coincide by an accident with someone else's string!). you can identify your data by this ID later
+ int nDataLen; // keep in mind that if the length is too big (more than about 8 KB), it's more preferable to split your data into several chunks, as you won't be able to "pick up" your data at the other end until all the data is transferred
+ char *cData;
+ int Flags; // combination of the DAM_SDF_ constants
+ DWORD SendAfterSessionID; // may be NULL; otherwise it's guaranteed that the sending starts only after successful completion of SendAfterSessionID session
+ DAM_SENDRESULTPROC SendResultProc; // pointer to a procedure that receives the result; can be NULL
+ DWORD SessionID; // OUT; receives the session ID
+} DAM_SENDDATAINFO;
+
+// MS_DAM_SENDDATA return values
+#define DAM_SDA_NOERROR 0
+#define DAM_SDA_NOTSUPPORTED (-1) // contact's protocol doesn't support sending/receiving messages
+#define DAM_SDA_TOOMANYSESSIONS (-2) // too many sessions
+
+// MS_DAM_SENDDATA
+// sends the data
+// wParam = (WPARAM)(DAM_SENDDATAINFO*)sdi;
+// lParam = 0
+// Returns 0 (DAM_SDA_NOERROR) and fills SessionID if the session was queued for sending successfully; returns one of the DAM_SDA_ values on failure
+#define MS_DAM_SENDDATA "DataAsMessage/SendData"
+
+static int __inline DAMSendData(HANDLE hContact, char *szDataType, int nDataLen, char *cData, int Flags, DWORD SendAfterSessionID, DAM_SENDRESULTPROC SendResultProc, DWORD *pSessionID)
+{
+ int Result;
+ DAM_SENDDATAINFO sdi;
+ ZeroMemory(&sdi, sizeof(sdi));
+ sdi.cbSize = sizeof(sdi);
+ sdi.hContact = hContact;
+ sdi.szDataType = szDataType;
+ sdi.nDataLen = nDataLen;
+ sdi.cData = cData;
+ sdi.Flags = Flags;
+ sdi.SendAfterSessionID = SendAfterSessionID;
+ sdi.SendResultProc = SendResultProc;
+ Result = CallService(MS_DAM_SENDDATA, (WPARAM)&sdi, 0);
+ if (pSessionID)
+ {
+ *pSessionID = sdi.SessionID;
+ }
+ return Result;
+}
+
+
+typedef struct
+{
+ int cbSize; // sizeof(DAM_RECVDATAINFO)
+ HANDLE hContact;
+ char *szDataType;
+ int nDataLen;
+ char *cData;
+} DAM_RECVDATAINFO;
+
+// ME_DAM_RECVDATA
+// hook up to this event to check for incoming data
+// make sure rdi->szDataType is yours before doing anything!
+// The important thing here is that your plugin will receive TWO ME_DAM_RECVDATA notifications on every single MS_DAM_SENDDATA call from a remote side:
+// The first notification arrives when the remote side starts to transmit the data. In this case DAM_RECVDATAINFO::cData = NULL (and DAM_RECVDATAINFO::nDataLen = -1) as we didn't receive any data yet. Return 1 to indicate that your plugin recognized the DAM_RECVDATAINFO::szDataType, otherwise return 0. If there are no any plugin that recognized the data, DAM cancels the transfer and there won't be any second notification for it.
+// The second notification is when the data is transmitted successfully. nDataLen contains the usual data size and cData points to the data buffer. cData is guaranteed to be valid only during the ME_DAM_RECVDATA call. You must copy the data to your own plugin's memory if you need to use it later. And again, return 1 to indicate that your plugin recognized the data, otherwise return 0
+// wParam = (WPARAM)(DAM_RECVDATAINFO*)rdi;
+// lParam = 0
+#define ME_DAM_RECVDATA "DataAsMessage/RecvData"
+
+
+typedef struct
+{
+ int cbSize; // sizeof(DAM_COMPRESSION_DATA)
+ void *(*malloc)(size_t); // pointer to the malloc() function of the calling module
+ int nInputDataLen; // IN; length of the input data in bytes
+ char *cInputData; // IN; pointer to the input data
+ int nOutputDataLen; // OUT; length of the output data in bytes
+ char *cOutputData; // OUT; pointer to the output data
+} DAM_COMPRESSION_DATA;
+
+// Compression/decompression services. You DON'T have to use them if you want to send compressed data using DAM services, as DAM compresses the data automatically. These services are here just in case you need to compress/decompress data for your own needs
+
+// MS_DAM_COMPRESS
+// compresses the data using BZip2
+// wParam = (WPARAM)(DAM_COMPRESSION_DATA*)bd;
+// lParam = 0
+// cbSize, malloc, nInputDataLen and cInputData fields must be valid when calling the service.
+// Returns 0 and fills nOutputDataLen and cOutputData on success; returns non-zero on failure
+// This service allocates the memory for cOutputData using the specified malloc function; you must call free(cOutputData) when you've finished working with cOutputData
+#define MS_DAM_COMPRESS "DataAsMessage/Compress"
+
+// MS_DAM_DECOMPRESS
+// decompresses the data
+// wParam = (WPARAM)(DAM_COMPRESSION_DATA*)bd;
+// lParam = 0
+// cbSize, malloc, nInputDataLen and cInputData fields must be valid when calling the service.
+// Returns 0 and fills nOutputDataLen and cOutputData on success; returns non-zero on failure
+// This service allocates the memory for cOutputData using the specified malloc function; you must call free(cOutputData) when you've finished working with cOutputData
+#define MS_DAM_DECOMPRESS "DataAsMessage/Decompress"
+
+
+__inline int DAM_Compress(char *cInputData, int nInputDataLen, char **cOutputData, int *nOutputDataLen)
+{
+ int Result;
+ DAM_COMPRESSION_DATA bd;
+ ZeroMemory(&bd, sizeof(bd));
+ bd.cbSize = sizeof(bd);
+ bd.malloc = malloc;
+ bd.nInputDataLen = nInputDataLen;
+ bd.cInputData = cInputData;
+ Result = CallService(MS_DAM_COMPRESS, (WPARAM)&bd, 0);
+ *nOutputDataLen = bd.nOutputDataLen;
+ *cOutputData = bd.cOutputData;
+ return Result;
+}
+
+__inline int DAM_Decompress(char *cInputData, int nInputDataLen, char **cOutputData, int *nOutputDataLen)
+{
+ int Result;
+ DAM_COMPRESSION_DATA bd;
+ ZeroMemory(&bd, sizeof(bd));
+ bd.cbSize = sizeof(bd);
+ bd.malloc = malloc;
+ bd.nInputDataLen = nInputDataLen;
+ bd.cInputData = cInputData;
+ Result = CallService(MS_DAM_DECOMPRESS, (WPARAM)&bd, 0);
+ *nOutputDataLen = bd.nOutputDataLen;
+ *cOutputData = bd.cOutputData;
+ return Result;
+}
+
+
+#endif // __M_DATAASMESSAGE_H
diff --git a/ExternalAPI/m_LogService.h b/ExternalAPI/m_LogService.h new file mode 100644 index 0000000..dc6c9f0 --- /dev/null +++ b/ExternalAPI/m_LogService.h @@ -0,0 +1,217 @@ +/*
+ LogService - Plugin for Miranda IM
+ Copyright (c) 2006-2008 Chervov Dmitry
+
+ 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
+*/
+
+#ifndef __M_LOGSERVICE_H
+#define __M_LOGSERVICE_H
+
+#define MIID_LOGSERVICE {0xe60bc9eb, 0xa099, 0x4846, {0xbc, 0x11, 0xba, 0x39, 0xf6, 0x60, 0x8b, 0x94}}
+// {E60BC9EB-A099-4846-BC11-BA39F6608B94}
+
+
+// LS_REGINFO::Flags constants
+#define LSRF_WCHAR 1 // specifies that LS_REGINFO::szTitle, szDefLogPath and szDefFormat are WCHAR*
+#ifdef _UNICODE
+ #define LSRF_TCHAR LSRF_WCHAR
+#else
+ #define LSRF_TCHAR 0
+#endif
+
+typedef struct {
+ int cbSize; // sizeof(LS_REGINFO)
+ char *szID; // Log ID; it's a good idea to use your plugin name here
+ union
+ {
+ char *szTitle; // Title shown in the options. Cannot be NULL or empty. This is translated by LogService automatically
+ WCHAR *wszTitle;
+ TCHAR *tszTitle;
+ };
+ union
+ {
+ char *szDefLogPath; // Default log file path, may contain variables. May be NULL - in this case the default path is "<log ID>.log". Usually it's relative to <Miranda profile dir>\Logs dir, but it can be changed by user through Folders plugin.
+ WCHAR *wszDefLogPath; // if there's no Variables plugin installed, LogService will use szDefLogPath with all the variables removed from it
+ TCHAR *tszDefLogPath;
+ };
+ union
+ {
+ char *szDefFormat; // Default log format; contains variables. May be NULL - in this case the default formatting is "`[`!cdate()-!ctime()`]` %extratext%"
+ WCHAR *wszDefFormat;
+ TCHAR *tszDefFormat;
+ };
+ int Flags;
+} LS_REGINFO;
+
+// MS_LOGSERVICE_REGISTER
+// Registers a log. Your plugin can register several different logs with different settings. This service must be called once for every needed log ID at every startup.
+// wParam = (WPARAM)(LS_REGINFO*)pri - pointer to LS_REGINFO item
+// lParam = 0
+// returns 0 on success
+#define MS_LOGSERVICE_REGISTER "LogService/Register"
+
+__inline static int logservice_register(char *szID, TCHAR *tszTitle, TCHAR *tszDefLogPath, TCHAR *tszDefFormat)
+{
+ LS_REGINFO ri;
+ ZeroMemory(&ri, sizeof(LS_REGINFO));
+ ri.cbSize = sizeof(LS_REGINFO);
+ ri.szID = szID;
+ ri.tszTitle = tszTitle;
+ ri.tszDefLogPath = tszDefLogPath;
+ ri.tszDefFormat = tszDefFormat;
+ ri.Flags = LSRF_TCHAR;
+ return CallService(MS_LOGSERVICE_REGISTER, (WPARAM)&ri, 0);
+}
+
+
+
+// LS_MSGINFO::Flags constants
+#define LSMF_WCHAR 1 // specifies that LS_MSGINFO::szMsg is a WCHAR*
+#ifdef _UNICODE
+ #define LSMF_TCHAR LSMF_WCHAR
+#else
+ #define LSMF_TCHAR 0
+#endif
+
+typedef struct {
+ int cbSize; // sizeof(LS_MSGINFO)
+ char *szID;
+ HANDLE hContact; // may be NULL if no contact is associated with the message
+ union
+ {
+ char *szMsg; // the message
+ WCHAR *wszMsg;
+ TCHAR *tszMsg;
+ };
+ int Flags;
+} LS_MSGINFO;
+
+// MS_LOGSERVICE_LOG
+// Logs szMsg message. You don't have to specify in szMsg anything else than the actual message. i.e. LogService will take care of date, time, contact nick etc by itself, using the format string
+// wParam = (WPARAM)(LS_MSGINFO*)pmi - pointer to LS_MSGINFO item
+// lParam = 0
+// returns 0 on success
+#define MS_LOGSERVICE_LOG "LogService/Log"
+
+__inline static int logservice_log(char *szID, HANDLE hContact, TCHAR *tszMsg)
+{
+ LS_MSGINFO mi;
+ ZeroMemory(&mi, sizeof(LS_MSGINFO));
+ mi.cbSize = sizeof(LS_MSGINFO);
+ mi.szID = szID;
+ mi.hContact = hContact;
+ mi.tszMsg = tszMsg;
+ mi.Flags = LSMF_TCHAR;
+ return CallService(MS_LOGSERVICE_LOG, (WPARAM)&mi, 0);
+}
+
+
+// LS_LOGINFO::Flags constants
+#define LSLI_WCHAR 1 // [in]; specifies that LS_LOGINFO::szLogPath is a WCHAR*
+#ifdef _UNICODE
+ #define LSLI_TCHAR LSLI_WCHAR
+#else
+ #define LSLI_TCHAR 0
+#endif
+#define LSLI_LOGENABLED 2 // [out]; LogService will set this flag if log with ID szID is enabled in the options. Setting this flag before calling MS_LOGSERVICE_GETLOGINFO is ignored. This flag is independent of hContact.
+
+typedef struct {
+ int cbSize; // [in]; sizeof(LS_LOGINFO)
+ char *szID; // [in]
+ HANDLE hContact; // [in]; may be NULL
+ union
+ {
+ char *szLogPath; // [in]; pointer to a string to receive log file name, including full path. May be NULL. The string must be at least MAX_PATH characters long
+ WCHAR *wszLogPath;
+ TCHAR *tszLogPath;
+ };
+ int Flags; // [in,out]
+} LS_LOGINFO;
+
+// MS_LOGSERVICE_GETLOGINFO
+// Returns various information about log with ID szID.
+// wParam = (WPARAM)(LS_LOGINFO*)pli - pointer to LS_LOGINFO item
+// lParam = 0
+// If szFileName is not NULL, MS_LOGSERVICE_GETLOGINFO gets full log file path by szID and hContact and copies it to *szLogPath
+// Also the service will set LSLI_LOGENABLED flag if the specified log is enabled in the options.
+// returns 0 on success
+#define MS_LOGSERVICE_GETLOGINFO "LogService/GetLogInfo"
+
+
+/*
+1) Example of the simpliest way to use LogService:
+
+ // define szID
+ #define LOG_ID "MyPluginName"
+
+ // in ME_SYSTEM_MODULESLOADED handler:
+ logservice_register(LOG_ID, LPGENT("My plugin - log title"), NULL, NULL);
+
+ // whenever you need to log something:
+ logservice_log(LOG_ID, NULL, _T("Test message"));
+ // (don't forget to specify hContact instead of NULL here if there's a contact associated with the message)
+
+MyPluginName.log will be created with the following contents:
+[20.08.2007-14:30:00] Test message
+
+
+2) If you want to offer additional customizability of log format using Variables, but still want the log to be usable even when Variables plugin is not installed, you can specify different messages depending on existence of MS_VARS_FORMATSTRING service. This example will explain how to do this and also will show you some other useful hints related to Variables plugin.
+
+ // define szID
+ #define LOG_ID "ClientChangeNotify"
+
+ // For example, say, we want to append user's ICQ UIN (or Yahoo ID, etc) to file name, to log CCN events to different files, depending on protocol (i.e. ClientChangeNotify_310927.log for ICQ). That's why custom log file path with variables is used here:
+
+ logservice_register(LOG_ID, LPGENT("ClientChangeNotify"),
+ _T("ClientChangeNotify?puts(p,?dbsetting(%subject%,Protocol,p))?if2(_?dbsetting(,?get(p),?pinfo(?get(p),uidsetting)),).log"),
+ TranslateT("`[`!cdate()-!ctime()`]` ?cinfo(%subject%,display) (?cinfo(%subject%,id)) changed client to %extratext%"));
+
+ // When Variables plugin is not installed, LogService will automatically cut all the variables from the log path, and we'll get usual "ClientChangeNotify.log" - so everyting is ok here.
+ // But note that %extratext% in the log format is supposed to contain only client name in CCN, and without some special measures, we would get something like this in the log when Variables plugin is not installed:
+ // [20.08.2007-14:30:00] Miranda IM 0.7.0.33 alpha (ICQ v0.3.8.105 alpha)
+ // Without at least contact nick, such log will be just useless. So when logging, we'll handle this case in a special way:
+
+ if (ServiceExists(MS_VARS_FORMATSTRING))
+ { // Variables plugin is installed
+ logservice_log(LOG_ID, hContact, tszClientName);
+ } else
+ { // Variables plugin is not installed, so we have to generate the string by ourselves, using some simple predefined format:
+ TCHAR tszNickAndClient[1024];
+ mir_sntprintf(tszNickAndClient, SIZEOF(tszNickAndClient), TranslateT("%s changed his client to %s"),
+ (TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, GCDNF_TCHAR), tszClientName);
+ logservice_log(LOG_ID, hContact, tszNickAndClient);
+ }
+
+3) The other solution to the case when there's no Variables plugin, is to sacrifice customizability of log format for a simplier implementation:
+
+ // define szID
+ #define LOG_ID "ClientChangeNotify"
+
+ // in ME_SYSTEM_MODULESLOADED handler:
+ logservice_register(LOG_ID, LPGENT("ClientChangeNotify"),
+ _T("ClientChangeNotify?puts(p,?dbsetting(%subject%,Protocol,p))?if2(_?dbsetting(,?get(p),?pinfo(?get(p),uidsetting)),).log"),
+ NULL);
+
+ // logging:
+ TCHAR tszNickAndClient[1024];
+ mir_sntprintf(tszNickAndClient, SIZEOF(tszNickAndClient), TranslateT("%s changed his client to %s"),
+ (TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, GCDNF_TCHAR), tszClientName);
+ logservice_log(LOG_ID, hContact, tszNickAndClient);
+
+ // Note that %extratext% now always contains the whole "<contact> changed his client to <client>" string, and user is almost unable to customize this; perhaps only by using another translation or some advanced Variables scripts.
+*/
+
+#endif // __M_LOGSERVICE_H
\ No newline at end of file diff --git a/ExternalAPI/m_NewAwaySys.h b/ExternalAPI/m_NewAwaySys.h index 4038fad..596c85e 100644 --- a/ExternalAPI/m_NewAwaySys.h +++ b/ExternalAPI/m_NewAwaySys.h @@ -1,6 +1,6 @@ /*
New Away System plugin for Miranda IM
- Copyright (c) 2005-2006 Chervov Dmitry
+ Copyright (c) 2005-2007 Chervov Dmitry
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
|