summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '3rdParty/Snarl')
-rw-r--r--3rdParty/Snarl/SConscript17
-rw-r--r--3rdParty/Snarl/SnarlInterface.cpp812
-rw-r--r--3rdParty/Snarl/SnarlInterface.h218
3 files changed, 1047 insertions, 0 deletions
diff --git a/3rdParty/Snarl/SConscript b/3rdParty/Snarl/SConscript
new file mode 100644
index 0000000..99900f7
--- /dev/null
+++ b/3rdParty/Snarl/SConscript
@@ -0,0 +1,17 @@
+Import("env")
+
+################################################################################
+# Flags
+################################################################################
+if env.get("HAVE_SNARL", True) :
+ if env["SCONS_STAGE"] == "flags" :
+ env["SNARL_FLAGS"] = {
+ "CPPPATH": [Dir(".")],
+ "LIBPATH": [Dir(".")],
+ "LIBS": ["Snarl"],
+ }
+
+ elif env["SCONS_STAGE"] == "build" :
+ myenv = env.Clone()
+ myenv.Replace(CCFLAGS = [flag for flag in env["CCFLAGS"] if flag not in ["-W", "-Wall"]])
+ myenv.StaticLibrary("Snarl", ["SnarlInterface.cpp"], CPPPATH = ["."])
diff --git a/3rdParty/Snarl/SnarlInterface.cpp b/3rdParty/Snarl/SnarlInterface.cpp
new file mode 100644
index 0000000..f287b8e
--- /dev/null
+++ b/3rdParty/Snarl/SnarlInterface.cpp
@@ -0,0 +1,812 @@
+// About:
+// Snarl C++ interface implementation
+// To understand what the different functions do and what they return, please
+// have a look at the API on http://www.fullphat.net/dev/api.htm.
+// Also have a look at mSnarl_i.bas found in the CVS/SVN repository for Snarl.
+//
+// The functions in SnarlInterface both have ANSI(UTF8) and UNICODE versions.
+// If the LPCWSTR (unicode) version of the functions are called, the strings
+// are converted to UTF8 by SnarlInterface before sent to Snarl. So using the
+// ANSI/UTF8/LPCSTR versions of the functions are faster!
+//
+//
+// Difference to VB implementation:
+// Please note that string functions return NULL when they fail and not an
+// empty string. So check for NULL...
+// Function names doesn't have the pre "sn".
+//
+//
+// Authors:
+// Written and maintained by Toke Noer Nøttrup
+// Original C++ version by "Whitman"
+//
+// License etc. :
+// Feel free to use this code and class as you see fit.
+// If you improve the code, it would be nice of you to take contact to the
+// authors, so all can get the benifit.
+//
+// There is no guarantee that the code is correct or functional.
+// USE AT YOUR OWN RISK
+//-----------------------------------------------------------------------------
+
+// History
+// 2008/12/31 : Implemented V39 API
+// : Moved SnarlInterface into new Snarl namespace and moved enums etc. out of class
+// : Added WCHAR overloads for all functions
+// 2008/08/27 : Fixed return value of IsMessageVisible and HideMessage (returns false on failure now)
+// : Fixed critical error in the new overloaded UpdateMessage() function
+// 2008/08/27 : x64 compiler fix
+// 2008/08/24 : Renamed all functions to not have prepended "sn".
+// : Memory allocation functions added. (Use FreeString to free strings returned by Snarl)
+// : Added m_nLastMessageId to the class. (Use GetLastMessageId() to get it)
+// : Overloaded a few functions, so one don't have include the message id. (UpdateMessage f.i.)
+
+// 2008/06/20 : Fixed snShowMessageEx so it actually sends the extended version - oops
+// : Fixed compiler warning C4800: forcing value to bool 'true' or 'false' (performance warning)
+
+// 2008/05/19 : uSend and uSendEx would always set return value to M_OK on successfull call
+// 2008/04/14 : Updated to follow (what should be) the final Snarl 2.0 API
+// 2008/03/28 : Few fixes for Snarl 2.0
+// 2007/05/23 : snGetGlobalMsg & snGetSnarlWindow made static
+// 2007/03/25 : 1.6 RC1 fixup
+// 2007/03/04 : Added - snGetAppPath, snGetIconsPath, snGetVersionEx,
+// snSetTimeout, uSendEx
+
+
+#include "SnarlInterface.h"
+
+using namespace Snarl;
+
+
+//-----------------------------------------------------------------------------
+// Constructor/Destructor
+//-----------------------------------------------------------------------------
+SnarlInterface::SnarlInterface()
+: m_hwndFrom(NULL), m_nLastMessageId(0)
+{
+
+}
+
+SnarlInterface::~SnarlInterface()
+{
+
+}
+
+
+//-----------------------------------------------------------------------------
+// snShowMessage()
+
+/// Displays a message with Title and Text. Timeout controls how long the
+/// message is displayed for (in seconds) (omitting this value means the message
+/// is displayed indefinately). IconPath specifies the location of a PNG image
+/// which will be displayed alongside the message text.
+/// <returns>Message Id on success or M_RESULT on failure</returns>
+
+LONG32 SnarlInterface::ShowMessage(LPCSTR szTitle, LPCSTR szText, LONG32 timeout, LPCSTR szIconPath, HWND hWndReply, WPARAM uReplyMsg)
+{
+ SNARLSTRUCT ss;
+ ZeroMemory((void*)&ss, sizeof(ss));
+
+ ss.Cmd = SNARL_SHOW;
+ StringCbCopyA((LPSTR)&ss.Title, SNARL_STRING_LENGTH, szTitle);
+ StringCbCopyA((LPSTR)&ss.Text, SNARL_STRING_LENGTH, szText);
+ StringCbCopyA((LPSTR)&ss.Icon, SNARL_STRING_LENGTH, szIconPath);
+ ss.Timeout = timeout;
+
+ ss.LngData2 = reinterpret_cast<LONG32>(hWndReply);
+ ss.Id = static_cast<LONG32>(uReplyMsg);
+
+ m_nLastMessageId = Send(ss);
+ return m_nLastMessageId;
+}
+
+LONG32 SnarlInterface::ShowMessage(LPCWSTR szTitle, LPCWSTR szText, LONG32 timeout, LPCWSTR szIconPath, HWND hWndReply, WPARAM uReplyMsg)
+{
+ LPSTR szUTF8Title = WideToUTF8(szTitle);
+ LPSTR szUTF8Text = WideToUTF8(szText);
+ LPSTR szUFT8IconPath = WideToUTF8(szIconPath);
+
+ LONG32 result = ShowMessage(szUTF8Title, szUTF8Text, timeout, szUFT8IconPath, hWndReply, uReplyMsg);
+
+ delete [] szUTF8Title;
+ delete [] szUTF8Text;
+ delete [] szUFT8IconPath;
+
+ return result;
+}
+
+//-----------------------------------------------------------------------------
+// snShowMessageEx()
+
+/// Displays a notification. This function is identical to snShowMessage()
+/// except that Class specifies an alert previously registered with
+/// snRegisterAlert() and SoundFile can optionally specify a WAV sound to play
+/// when the notification is displayed on screen.
+
+/// <returns>Message Id on success or M_RESULT on failure</returns>
+
+LONG32 SnarlInterface::ShowMessageEx(LPCSTR szClass, LPCSTR szTitle, LPCSTR szText, LONG32 timeout, LPCSTR szIconPath, HWND hWndReply, WPARAM uReplyMsg, LPCSTR szSoundFile)
+{
+ SNARLSTRUCTEX ssex;
+ ZeroMemory((void*)&ssex, sizeof(ssex));
+
+ ssex.Cmd = SNARL_EX_SHOW;
+ ssex.Timeout = timeout;
+ ssex.LngData2 = reinterpret_cast<LONG32>(hWndReply);
+ ssex.Id = static_cast<LONG32>(uReplyMsg);
+
+ StringCbCopyA((LPSTR)&ssex.Class, SNARL_STRING_LENGTH, szClass);
+ StringCbCopyA((LPSTR)&ssex.Title, SNARL_STRING_LENGTH, szTitle);
+ StringCbCopyA((LPSTR)&ssex.Text, SNARL_STRING_LENGTH, szText);
+ StringCbCopyA((LPSTR)&ssex.Icon, SNARL_STRING_LENGTH, szIconPath);
+ StringCbCopyA((LPSTR)&ssex.Extra, SNARL_STRING_LENGTH, szSoundFile);
+
+ m_nLastMessageId = Send(ssex);
+ return m_nLastMessageId;
+}
+
+LONG32 SnarlInterface::ShowMessageEx(LPCWSTR szClass, LPCWSTR szTitle, LPCWSTR szText, LONG32 timeout, LPCWSTR szIconPath, HWND hWndReply, WPARAM uReplyMsg, LPCWSTR szSoundFile)
+{
+ LPSTR szUTF8Class = WideToUTF8(szClass);
+ LPSTR szUTF8Title = WideToUTF8(szTitle);
+ LPSTR szUTF8Text = WideToUTF8(szText);
+ LPSTR szUFT8IconPath = WideToUTF8(szIconPath);
+ LPSTR szUFT8SoundFile = WideToUTF8(szSoundFile);
+
+ LONG32 result = ShowMessageEx(szUTF8Class, szUTF8Title, szUTF8Text, timeout, szUFT8IconPath, hWndReply, uReplyMsg, szUFT8SoundFile);
+
+ delete [] szUTF8Class;
+ delete [] szUTF8Title;
+ delete [] szUTF8Text;
+ delete [] szUFT8IconPath;
+ delete [] szUFT8SoundFile;
+
+ return result;
+}
+
+//-----------------------------------------------------------------------------
+// snHideMessage()
+
+/// Hides the notification specified by Id. Id is the value returned by
+/// snShowMessage() or snShowMessageEx() when the notification was initially
+/// created. This function returns True if the notification was successfully
+/// hidden or False otherwise (for example, the notification may no longer exist).
+
+BOOL SnarlInterface::HideMessage(LONG32 Id)
+{
+ SNARLSTRUCT ss;
+ ss.Cmd = SNARL_HIDE;
+ ss.Id = Id;
+
+ LONG32 n = Send(ss);
+ return (n == -1 || n == 1) ? TRUE : FALSE;
+}
+
+BOOL SnarlInterface::HideMessage()
+{
+ return HideMessage(m_nLastMessageId);
+}
+
+//-----------------------------------------------------------------------------
+// snIsMessageVisible()
+
+/// Returns True if the notification specified by Id is still visible, or
+/// False if not. Id is the value returned by snShowMessage() or
+/// snShowMessageEx() when the notification was initially created.
+
+BOOL SnarlInterface::IsMessageVisible(LONG32 Id)
+{
+ SNARLSTRUCT ss;
+ ss.Cmd = SNARL_IS_VISIBLE;
+ ss.Id = Id;
+
+ // We are getting -1 when true, checking for 1 just in case. We don't want to return true for the other M_RESULT returns
+ LONG32 n = Send(ss);
+ return (n == -1 || n == 1) ? TRUE : FALSE;
+}
+
+BOOL SnarlInterface::IsMessageVisible()
+{
+ if (m_nLastMessageId == 0)
+ return FALSE;
+
+ return IsMessageVisible(m_nLastMessageId);
+}
+
+//-----------------------------------------------------------------------------
+// snUpdateMessage()
+
+/// Changes the title and text in the message specified by Id to the values
+/// specified by Title and Text respectively. Id is the value returned by
+/// snShowMessage() or snShowMessageEx() when the notification was originally
+/// created. To change the timeout parameter of a notification, use snSetTimeout()
+
+M_RESULT SnarlInterface::UpdateMessage(LONG32 id, LPCSTR szTitle, LPCSTR szText, LPCSTR szIconPath)
+{
+ SNARLSTRUCT ss;
+ ZeroMemory((void*)&ss, sizeof(ss));
+
+ ss.Cmd = SNARL_UPDATE;
+ ss.Id = id;
+
+ StringCbCopyA((LPSTR)&ss.Title, SNARL_STRING_LENGTH, szTitle);
+ StringCbCopyA((LPSTR)&ss.Text, SNARL_STRING_LENGTH, szText);
+ StringCbCopyA((LPSTR)&ss.Icon, SNARL_STRING_LENGTH, szIconPath);
+
+ return static_cast<M_RESULT>(Send(ss));
+}
+
+M_RESULT SnarlInterface::UpdateMessage(LONG32 id, LPCWSTR szTitle, LPCWSTR szText, LPCWSTR szIconPath)
+{
+ LPSTR szParam1 = WideToUTF8(szTitle);
+ LPSTR szParam2 = WideToUTF8(szText);
+ LPSTR szParam3 = WideToUTF8(szIconPath);
+
+ M_RESULT result = UpdateMessage(id, szParam1, szParam2, szParam3);
+
+ delete [] szParam1;
+ delete [] szParam2;
+ delete [] szParam3;
+
+ return result;
+}
+
+M_RESULT SnarlInterface::UpdateMessage(LPCSTR szTitle, LPCSTR szText, LPCSTR szIconPath)
+{
+ return UpdateMessage(m_nLastMessageId, szTitle, szText, szIconPath);
+}
+
+M_RESULT SnarlInterface::UpdateMessage(LPCWSTR szTitle, LPCWSTR szText, LPCWSTR szIconPath)
+{
+ return UpdateMessage(m_nLastMessageId, szTitle, szText, szIconPath);
+}
+
+//-----------------------------------------------------------------------------
+// snRegisterConfig
+
+/// Registers an application's configuration interface with Snarl.
+/// AppName is the text that's displayed in the Applications list so it should
+/// be people friendly ("My cool app" rather than "my_cool_app").
+
+M_RESULT SnarlInterface::RegisterConfig(HWND hWnd, LPCSTR szAppName, LONG32 replyMsg)
+{
+ return RegisterConfig2(hWnd, szAppName, replyMsg, "");
+}
+
+M_RESULT SnarlInterface::RegisterConfig(HWND hWnd, LPCWSTR szAppName, LONG32 replyMsg)
+{
+ return RegisterConfig2(hWnd, szAppName, replyMsg, L"");
+}
+
+//-----------------------------------------------------------------------------
+// snRegisterConfig2
+
+/// Registers an application's configuration interface with Snarl.
+/// This function is identical to snRegisterConfig() except that Icon can be
+/// used to specify a PNG image which will be displayed against the
+/// application's entry in Snarl's Preferences panel.
+
+M_RESULT SnarlInterface::RegisterConfig2(HWND hWnd, LPCSTR szAppName, LONG32 replyMsg, LPCSTR szIcon)
+{
+ if (!szAppName || !szIcon)
+ return M_BAD_POINTER;
+
+ SNARLSTRUCT ss;
+
+ m_hwndFrom = hWnd;
+
+ ss.Cmd = SNARL_REGISTER_CONFIG_WINDOW_2;
+ ss.LngData2 = reinterpret_cast<LONG32>(hWnd);
+ ss.Id = replyMsg;
+ StringCbCopyA((LPSTR)&ss.Title, SNARL_STRING_LENGTH, szAppName);
+ StringCbCopyA((LPSTR)&ss.Icon, SNARL_STRING_LENGTH, szIcon);
+
+ return static_cast<M_RESULT>(Send(ss));
+}
+
+M_RESULT SnarlInterface::RegisterConfig2(HWND hWnd, LPCWSTR szAppName, LONG32 replyMsg, LPCWSTR szIcon)
+{
+ LPSTR szParam1 = WideToUTF8(szAppName);
+ LPSTR szParam2 = WideToUTF8(szIcon);
+
+ M_RESULT result = RegisterConfig2(hWnd, szParam1, replyMsg, szParam2);
+
+ delete [] szParam1;
+ delete [] szParam2;
+
+ return result;
+}
+
+
+//-----------------------------------------------------------------------------
+// snRevokeConfig
+
+/// Removes the application previously registered using snRegisterConfig() or
+/// snRegisterConfig2(). hWnd should be the same as that used during registration.
+
+M_RESULT SnarlInterface::RevokeConfig(HWND hWnd)
+{
+ SNARLSTRUCT ss;
+
+ m_hwndFrom = NULL;
+
+ ss.Cmd = SNARL_REVOKE_CONFIG_WINDOW;
+ ss.LngData2 = reinterpret_cast<LONG32>(hWnd);
+
+ return static_cast<M_RESULT>(Send(ss));
+}
+
+
+//-----------------------------------------------------------------------------
+// snGetVersion()
+
+/// Checks if Snarl is currently running and, if it is, retrieves the major and
+/// minor release version numbers in Major and Minor respectively.
+/// Returns True if Snarl is running, False otherwise.
+
+BOOL SnarlInterface::GetVersion(WORD* Major, WORD* Minor)
+{
+ SNARLSTRUCT ss;
+ ss.Cmd = SNARL_GET_VERSION;
+ LONG32 versionInfo = Send(ss);
+ if (versionInfo > 0 && versionInfo != M_FAILED && versionInfo != M_TIMED_OUT) {
+ *Major = HIWORD(versionInfo);
+ *Minor = LOWORD(versionInfo);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+//-----------------------------------------------------------------------------
+// snGetVersionEx
+
+/// Returns the Snarl system version number. This is an integer value which
+/// represents the system build number and can be used to identify the specific
+/// version of Snarl running
+
+LONG32 SnarlInterface::GetVersionEx()
+{
+ SNARLSTRUCT ss;
+ ss.Cmd = SNARL_GET_VERSION_EX;
+ return Send(ss);
+}
+
+
+//-----------------------------------------------------------------------------
+// snSetTimeout()
+
+/// Sets the timeout of existing notification Id to Timeout seconds. Id is the
+/// value returned by snShowMessage() or snShowMessageEx() when the notification
+/// was first created.
+
+M_RESULT SnarlInterface::SetTimeout(LONG32 Id, LONG32 Timeout)
+{
+ SNARLSTRUCT ss;
+ ss.Cmd = SNARL_SET_TIMEOUT;
+ ss.Id = Id;
+ ss.LngData2 = Timeout;
+
+ return static_cast<M_RESULT>(Send(ss));
+}
+
+M_RESULT SnarlInterface::SetTimeout(LONG32 Timeout)
+{
+ return SetTimeout(m_nLastMessageId, Timeout);
+}
+
+//-----------------------------------------------------------------------------
+// snRegisterAlert()
+
+/// Registers an alert of Class for application AppName which must have previously
+/// been registered with either snRegisterConfig() or snRegisterConfig2().
+
+M_RESULT SnarlInterface::RegisterAlert(LPCSTR szAppName, LPCSTR szClass)
+{
+ SNARLSTRUCT ss;
+ ss.Cmd = SNARL_REGISTER_ALERT;
+ StringCbCopyA((LPSTR)&ss.Title, SNARL_STRING_LENGTH, szAppName);
+ StringCbCopyA((LPSTR)&ss.Text, SNARL_STRING_LENGTH, szClass);
+
+ return static_cast<M_RESULT>(Send(ss));
+}
+
+M_RESULT SnarlInterface::RegisterAlert(LPCWSTR szAppName, LPCWSTR szClass)
+{
+ LPSTR szParam1 = WideToUTF8(szAppName);
+ LPSTR szParam2 = WideToUTF8(szClass);
+
+ M_RESULT result = RegisterAlert(szParam1, szParam2);
+
+ delete [] szParam1;
+ delete [] szParam2;
+
+ return result;
+}
+
+//-----------------------------------------------------------------------------
+// snGetGlobalMsg()
+
+/// Returns the atom that corresponds to the "SnarlGlobalEvent" registered
+/// Windows message. This message is sent by Snarl when it is first starts and
+/// when it shuts down.
+
+LONG32 SnarlInterface::GetGlobalMsg()
+{
+ return RegisterWindowMessage(SNARL_GLOBAL_MSG);
+}
+
+
+//-----------------------------------------------------------------------------
+// snGetSnarlWindow
+
+HWND SnarlInterface::GetSnarlWindow()
+{
+ return FindWindow(NULL, _T("Snarl"));
+}
+
+
+//-----------------------------------------------------------------------------
+// snGetAppPath()
+
+/// Returns a pointer to the path.
+/// ** Remember to call FreeString
+
+LPCTSTR SnarlInterface::GetAppPath()
+{
+ HWND hWnd = GetSnarlWindow();
+ if (hWnd)
+ {
+ HWND hWndPath = FindWindowEx(hWnd, 0, _T("static"), NULL);
+ if (hWndPath)
+ {
+ TCHAR strTmp[MAX_PATH] = {0};
+ int nReturn = GetWindowText(hWndPath, strTmp, MAX_PATH);
+ if (nReturn > 0) {
+ TCHAR* strReturn = AllocateString(nReturn + 1);
+ StringCchCopy(strReturn, nReturn + 1, strTmp);
+ return strReturn;
+ }
+ }
+ }
+ return NULL;
+}
+
+
+//-----------------------------------------------------------------------------
+// snGetIconsPath()
+
+/// Returns a pointer to the iconpath.
+/// ** Remember to call FreeString when done with the string
+
+LPCTSTR SnarlInterface::GetIconsPath()
+{
+ TCHAR* szIconPath = NULL;
+ LPCTSTR szPath = GetAppPath();
+ if (!szPath)
+ return NULL;
+
+ size_t nLen = 0;
+ if (SUCCEEDED(StringCbLength(szPath, MAX_PATH, &nLen)))
+ {
+ nLen += 10 + 1; // etc\\icons\\ + NULL
+ szIconPath = AllocateString(nLen);
+
+ StringCbCopy(szIconPath, nLen * sizeof(TCHAR), szPath);
+ StringCbCat(szIconPath, nLen * sizeof(TCHAR), _T("etc\\icons\\"));
+ }
+
+ FreeString(szPath);
+
+ return szIconPath;
+}
+
+
+//-----------------------------------------------------------------------------
+// snSetAsSnarlApp()
+
+/// Identifies an application as a Snarl App. (V39)
+
+void SnarlInterface::SetAsSnarlApp(HWND hWndOwner, SNARL_APP_FLAGS Flags)
+{
+ if (IsWindow(hWndOwner)) {
+ SetProp(hWndOwner, _T("snarl_app"), reinterpret_cast<HANDLE>(1));
+ SetProp(hWndOwner, _T("snarl_app_flags"), reinterpret_cast<HANDLE>(Flags));
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// snGetAppMsg()
+
+/// Returns the global Snarl Application message (V39)
+
+LONG32 SnarlInterface::GetAppMsg()
+{
+ return RegisterWindowMessage(SNARL_APP_MSG);
+}
+
+
+//-----------------------------------------------------------------------------
+// snRegisterApp()
+
+/// Registers an application with Snarl (V39)
+
+M_RESULT SnarlInterface::RegisterApp(LPCSTR Application, LPCSTR SmallIcon, LPCSTR LargeIcon, HWND hWnd, LONG32 ReplyMsg)
+{
+ m_hwndFrom = hWnd;
+
+ SNARLSTRUCT ss;
+ ss.Cmd = SNARL_REGISTER_APP;
+
+ StringCbCopyA((LPSTR)&ss.Title, SNARL_STRING_LENGTH, Application);
+ StringCbCopyA((LPSTR)&ss.Icon, SNARL_STRING_LENGTH, SmallIcon);
+ StringCbCopyA((LPSTR)&ss.Text, SNARL_STRING_LENGTH, LargeIcon);
+
+ ss.LngData2 = reinterpret_cast<LONG32>(hWnd);
+ ss.Id = ReplyMsg;
+ ss.Timeout = GetCurrentProcessId();
+
+ return static_cast<M_RESULT>(Send(ss));
+}
+
+M_RESULT SnarlInterface::RegisterApp(LPCWSTR Application, LPCWSTR SmallIcon, LPCWSTR LargeIcon, HWND hWnd, LONG32 ReplyMsg)
+{
+ LPSTR szParam1 = WideToUTF8(Application);
+ LPSTR szParam2 = WideToUTF8(SmallIcon);
+ LPSTR szParam3 = WideToUTF8(LargeIcon);
+
+ M_RESULT result = RegisterApp(szParam1, szParam2, szParam3, hWnd, ReplyMsg);
+
+ delete [] szParam1;
+ delete [] szParam2;
+ delete [] szParam3;
+
+ return result;
+}
+
+
+//-----------------------------------------------------------------------------
+// snUnregisterApp()
+
+/// Unregisters an application with Snarl (V39)
+
+M_RESULT SnarlInterface::UnregisterApp()
+{
+ SNARLSTRUCT ss;
+ ss.Cmd = SNARL_UNREGISTER_APP;
+ ss.LngData2 = GetCurrentProcessId();
+
+ m_hwndFrom = NULL;
+
+ return static_cast<M_RESULT>(Send(ss));
+}
+
+
+//-----------------------------------------------------------------------------
+// snShowNotification()
+
+/// Displays a Snarl notification using registered class (V39)
+/// <returns>Message Id on success or M_RESULT on failure</returns>
+
+LONG32 SnarlInterface::ShowNotification(LPCSTR Class, LPCSTR Title, LPCSTR Text, LONG32 Timeout, LPCSTR Icon, HWND hWndReply, LONG32 uReplyMsg, LPCSTR Sound)
+{
+ SNARLSTRUCTEX ssex;
+ ssex.Cmd = SNARL_SHOW_NOTIFICATION;
+
+ StringCbCopyExA((LPSTR)&ssex.Title, SNARL_STRING_LENGTH, Title, NULL, NULL, STRSAFE_IGNORE_NULLS);
+ StringCbCopyExA((LPSTR)&ssex.Text, SNARL_STRING_LENGTH, Text, NULL, NULL, STRSAFE_IGNORE_NULLS);
+ StringCbCopyExA((LPSTR)&ssex.Icon, SNARL_STRING_LENGTH, Icon, NULL, NULL, STRSAFE_IGNORE_NULLS);
+
+ ssex.Timeout = Timeout;
+ ssex.LngData2 = reinterpret_cast<LONG32>(hWndReply);
+ ssex.Id = uReplyMsg;
+
+ StringCbCopyExA((LPSTR)&ssex.Extra, SNARL_STRING_LENGTH, Sound, NULL, NULL, STRSAFE_IGNORE_NULLS);
+ StringCbCopyA((LPSTR)&ssex.Class, SNARL_STRING_LENGTH, Class);
+
+ ssex.Reserved1 = GetCurrentProcessId();
+
+ m_nLastMessageId = Send(ssex);
+ return m_nLastMessageId;
+}
+
+LONG32 SnarlInterface::ShowNotification(LPCWSTR Class, LPCWSTR Title, LPCWSTR Text, LONG32 Timeout, LPCWSTR Icon, HWND hWndReply, LONG32 uReplyMsg, LPCWSTR Sound)
+{
+ LPSTR szParam1 = WideToUTF8(Class);
+ LPSTR szParam2 = WideToUTF8(Title);
+ LPSTR szParam3 = WideToUTF8(Text);
+ LPSTR szParam4 = WideToUTF8(Icon);
+ LPSTR szParam5 = WideToUTF8(Sound);
+
+ LONG32 result = ShowNotification(szParam1, szParam2, szParam3, Timeout, szParam4, hWndReply, uReplyMsg, szParam5);
+
+ delete [] szParam1;
+ delete [] szParam2;
+ delete [] szParam3;
+ delete [] szParam4;
+ delete [] szParam5;
+
+ return result;
+}
+
+
+//-----------------------------------------------------------------------------
+// snChangeAttribute()
+
+/// (V39)
+
+M_RESULT SnarlInterface::ChangeAttribute(LONG32 Id, SNARL_ATTRIBUTES Attr, LPCSTR Value)
+{
+ SNARLSTRUCT ss;
+ ss.Cmd = SNARL_CHANGE_ATTR;
+ ss.Id = Id;
+ ss.LngData2 = Attr;
+
+ StringCbCopyExA((LPSTR)&ss.Text, SNARL_STRING_LENGTH, Value, NULL, NULL, STRSAFE_IGNORE_NULLS);
+
+ return static_cast<M_RESULT>(Send(ss));
+}
+
+M_RESULT SnarlInterface::ChangeAttribute(LONG32 Id, SNARL_ATTRIBUTES Attr, LPCWSTR Value)
+{
+ LPSTR szParam1 = WideToUTF8(Value);
+
+ M_RESULT result = ChangeAttribute(Id, Attr, szParam1);
+
+ delete [] szParam1;
+
+ return result;
+}
+
+M_RESULT SnarlInterface::ChangeAttribute(SNARL_ATTRIBUTES Attr, LPCSTR Value)
+{
+ return ChangeAttribute(m_nLastMessageId, Attr, Value);
+}
+
+M_RESULT SnarlInterface::ChangeAttribute(SNARL_ATTRIBUTES Attr, LPCWSTR Value)
+{
+ return ChangeAttribute(m_nLastMessageId, Attr, Value);
+}
+
+
+//-----------------------------------------------------------------------------
+// snSetClassDefault()
+
+/// Sets the default value for an alert class (V39)
+
+M_RESULT SnarlInterface::SetClassDefault(LPCSTR Class, SNARL_ATTRIBUTES Attr, LPCSTR Value)
+{
+ SNARLSTRUCT ss;
+ ss.Cmd = SNARL_SET_CLASS_DEFAULT;
+ ss.LngData2 = Attr;
+ ss.Timeout = GetCurrentProcessId();
+
+ StringCbCopyExA((LPSTR)&ss.Text, SNARL_STRING_LENGTH, Class, NULL, NULL, STRSAFE_IGNORE_NULLS);
+ StringCbCopyExA((LPSTR)&ss.Icon, SNARL_STRING_LENGTH, Value, NULL, NULL, STRSAFE_IGNORE_NULLS);
+
+ return static_cast<M_RESULT>(Send(ss));
+}
+
+M_RESULT SnarlInterface::SetClassDefault(LPCWSTR Class, SNARL_ATTRIBUTES Attr, LPCWSTR Value)
+{
+ LPSTR szParam1 = WideToUTF8(Class);
+ LPSTR szParam2 = WideToUTF8(Value);
+
+ M_RESULT result = SetClassDefault(szParam1, Attr, szParam2);
+
+ delete [] szParam1;
+ delete [] szParam2;
+
+ return result;
+}
+
+
+//-----------------------------------------------------------------------------
+// snGetRevision()
+
+/// Gets the current Snarl revision (build) number (V39)
+/// Returns the build version number, or M_RESULT on failure.
+
+LONG32 SnarlInterface::GetRevision()
+{
+ SNARLSTRUCT ss;
+ ss.Cmd = SNARL_GET_REVISION;
+ ss.LngData2 = 0xFFFE;
+
+ return Send(ss);
+}
+
+
+//-----------------------------------------------------------------------------
+// snAddClass()
+
+/// (V39)
+
+M_RESULT SnarlInterface::AddClass(LPCSTR Class, LPCSTR Description, SNARL_CLASS_FLAGS Flags, LPCSTR DefaultTitle, LPCSTR DefaultIcon, LONG32 DefaultTimeout)
+{
+ SNARLSTRUCT ss;
+ ss.Cmd = SNARL_ADD_CLASS;
+ ss.LngData2 = Flags;
+ ss.Timeout = GetCurrentProcessId();
+
+ StringCbCopyExA((LPSTR)&ss.Text, SNARL_STRING_LENGTH, Class, NULL, NULL, STRSAFE_IGNORE_NULLS);
+ StringCbCopyExA((LPSTR)&ss.Title, SNARL_STRING_LENGTH, Description, NULL, NULL, STRSAFE_IGNORE_NULLS);
+
+ LONG32 result = Send(ss);
+
+ if (static_cast<M_RESULT>(result) == M_OK)
+ {
+ SetClassDefault(Class, SNARL_ATTRIBUTE_TITLE, DefaultTitle);
+ SetClassDefault(Class, SNARL_ATTRIBUTE_ICON, DefaultIcon);
+ if (DefaultTimeout > 0) {
+ char str[64] = {0};
+ StringCbPrintfA((LPSTR)&str, sizeof(str), "%d", DefaultTimeout);
+ SetClassDefault(Class, SNARL_ATTRIBUTE_TIMEOUT, str);
+ }
+
+ return M_OK;
+ }
+ else
+ return M_FAILED;
+}
+
+M_RESULT SnarlInterface::AddClass(LPCWSTR Class, LPCWSTR Description, SNARL_CLASS_FLAGS Flags, LPCWSTR DefaultTitle, LPCWSTR DefaultIcon, LONG32 DefaultTimeout)
+{
+ LPCSTR szClass = WideToUTF8(Class);
+ LPCSTR szDescription = WideToUTF8(Description);
+ LPCSTR szDefaultTitle = WideToUTF8(DefaultTitle);
+ LPCSTR szDefaultIcon = WideToUTF8(DefaultIcon);
+
+ M_RESULT result = AddClass(szClass, szDescription, Flags, szDefaultTitle, szDefaultIcon, DefaultTimeout);
+
+ delete [] szClass;
+ delete [] szDescription;
+ delete [] szDefaultTitle;
+ delete [] szDefaultIcon;
+
+ return result;
+}
+
+//-----------------------------------------------------------------------------
+// Private functions
+//-----------------------------------------------------------------------------
+
+template <class T>
+LONG32 SnarlInterface::Send(T ss)
+{
+ DWORD_PTR nReturn = M_FAILED;
+
+ HWND hWnd = GetSnarlWindow();
+ if (IsWindow(hWnd))
+ {
+ COPYDATASTRUCT cds;
+ cds.dwData = 2;
+ cds.cbData = sizeof(ss);
+ cds.lpData = &ss;
+
+ if (SendMessageTimeout(hWnd, WM_COPYDATA, (WPARAM)m_hwndFrom, (LPARAM)&cds, SMTO_ABORTIFHUNG | SMTO_NOTIMEOUTIFNOTHUNG, 1000, &nReturn) == 0)
+ {
+ if (GetLastError() == ERROR_TIMEOUT)
+ nReturn = M_TIMED_OUT;
+ }
+ }
+
+ return static_cast<LONG32>(nReturn);
+}
+
+//-----------------------------------------------------------------------------
+
+// Remember to : delete [] returned string
+
+LPSTR SnarlInterface::WideToUTF8(LPCWSTR szWideStr)
+{
+ if (szWideStr == NULL)
+ return NULL;
+
+ int nSize = WideCharToMultiByte(CP_UTF8, 0, szWideStr, -1, NULL, 0, NULL, NULL);
+ LPSTR szUTF8 = new char[nSize];
+ WideCharToMultiByte(CP_UTF8, 0, szWideStr, -1, szUTF8, nSize, NULL, NULL);
+
+ return szUTF8;
+} \ No newline at end of file
diff --git a/3rdParty/Snarl/SnarlInterface.h b/3rdParty/Snarl/SnarlInterface.h
new file mode 100644
index 0000000..137d597
--- /dev/null
+++ b/3rdParty/Snarl/SnarlInterface.h
@@ -0,0 +1,218 @@
+#ifndef SNARL_INTERFACE
+#define SNARL_INTERFACE
+
+#include <tchar.h>
+#include <windows.h>
+#include <strsafe.h>
+
+
+namespace Snarl {
+
+ static const LPCTSTR SNARL_GLOBAL_MSG = _T("SnarlGlobalEvent");
+ static const LPCTSTR SNARL_APP_MSG = _T("SnarlAppMessage");
+
+ static const int SNARL_STRING_LENGTH = 1024;
+ static const int SNARL_UNICODE_LENGTH = SNARL_STRING_LENGTH / 2;
+
+ static const LONG32 SNARL_LAUNCHED = 1; // Snarl has just started running
+ static const LONG32 SNARL_QUIT = 2; // Snarl is about to stop running
+ static const LONG32 SNARL_ASK_APPLET_VER = 3; // (R1.5) Reserved for future use
+ static const LONG32 SNARL_SHOW_APP_UI = 4; // (R1.6) Application should show its UI
+
+ static const LONG32 SNARL_NOTIFICATION_CLICKED = 32; // notification was right-clicked by user
+ static const LONG32 SNARL_NOTIFICATION_TIMED_OUT = 33;
+ static const LONG32 SNARL_NOTIFICATION_ACK = 34; // notification was left-clicked by user
+ static const LONG32 SNARL_NOTIFICATION_MENU = 35; // V39 - menu item selected
+ static const LONG32 SNARL_NOTIFICATION_MIDDLE_BUTTON = 36; // V39 - notification middle-clicked by user
+ static const LONG32 SNARL_NOTIFICATION_CLOSED = 37; // V39 - user clicked the close gadget
+
+ static const LONG32 SNARL_NOTIFICATION_CANCELLED = SNARL_NOTIFICATION_CLICKED; // Added in R1.6
+
+ static const DWORD WM_SNARLTEST = WM_USER + 237; // note hardcoded WM_USER value!
+
+ // --------------------------------------------------------------------
+
+ typedef enum M_RESULT {
+ M_ABORTED = 0x80000007,
+ M_ACCESS_DENIED = 0x80000009,
+ M_ALREADY_EXISTS = 0x8000000C,
+ M_BAD_HANDLE = 0x80000006,
+ M_BAD_POINTER = 0x80000005,
+ M_FAILED = 0x80000008,
+ M_INVALID_ARGS = 0x80000003,
+ M_NO_INTERFACE = 0x80000004,
+ M_NOT_FOUND = 0x8000000B,
+ M_NOT_IMPLEMENTED = 0x80000001,
+ M_OK = 0x00000000,
+ M_OUT_OF_MEMORY = 0x80000002,
+ M_TIMED_OUT = 0x8000000A
+ };
+
+ enum SNARL_COMMANDS {
+ SNARL_SHOW = 1,
+ SNARL_HIDE,
+ SNARL_UPDATE,
+ SNARL_IS_VISIBLE,
+ SNARL_GET_VERSION,
+ SNARL_REGISTER_CONFIG_WINDOW,
+ SNARL_REVOKE_CONFIG_WINDOW,
+
+ /* R1.6 onwards */
+ SNARL_REGISTER_ALERT,
+ SNARL_REVOKE_ALERT, // for future use
+ SNARL_REGISTER_CONFIG_WINDOW_2,
+ SNARL_GET_VERSION_EX,
+ SNARL_SET_TIMEOUT,
+
+ /* following introduced in Snarl V39 (R2.1) */
+ SNARL_SET_CLASS_DEFAULT,
+ SNARL_CHANGE_ATTR,
+ SNARL_REGISTER_APP,
+ SNARL_UNREGISTER_APP,
+ SNARL_ADD_CLASS,
+
+ /* extended commands (all use SNARLSTRUCTEX) */
+ SNARL_EX_SHOW = 0x20,
+ SNARL_SHOW_NOTIFICATION // V39
+ };
+
+ static const SNARL_COMMANDS SNARL_GET_REVISION = SNARL_REVOKE_ALERT;
+
+ typedef enum SNARL_APP_FLAGS {
+ SNARL_APP_HAS_PREFS = 1,
+ SNARL_APP_HAS_ABOUT = 2
+ };
+
+ static const LONG32 SNARL_APP_PREFS = 1;
+ static const LONG32 SNARL_APP_ABOUT = 2;
+
+
+ /* --------------- V39 additions --------------- */
+
+ /* snAddClass() flags */
+ enum SNARL_CLASS_FLAGS {
+ SNARL_CLASS_ENABLED = 0,
+ SNARL_CLASS_DISABLED = 1,
+ SNARL_CLASS_NO_DUPLICATES = 2, // means Snarl will suppress duplicate notifications
+ SNARL_CLASS_DELAY_DUPLICATES = 4 // means Snarl will suppress duplicate notifications within a pre-set time period
+ };
+
+ /* Class attributes */
+ typedef enum SNARL_ATTRIBUTES {
+ SNARL_ATTRIBUTE_TITLE = 1,
+ SNARL_ATTRIBUTE_TEXT,
+ SNARL_ATTRIBUTE_ICON,
+ SNARL_ATTRIBUTE_TIMEOUT,
+ SNARL_ATTRIBUTE_SOUND,
+ SNARL_ATTRIBUTE_ACK, // file to run on ACK
+ SNARL_ATTRIBUTE_MENU
+ };
+
+ /* ------------------- end of V39 additions ------------------ */
+
+ struct SNARLSTRUCT {
+ SNARL_COMMANDS Cmd;
+ LONG32 Id;
+ LONG32 Timeout;
+ LONG32 LngData2;
+ char Title[SNARL_STRING_LENGTH];
+ char Text[SNARL_STRING_LENGTH];
+ char Icon[SNARL_STRING_LENGTH];
+ };
+
+ struct SNARLSTRUCTEX {
+ SNARL_COMMANDS Cmd;
+ LONG32 Id;
+ LONG32 Timeout;
+ LONG32 LngData2;
+ char Title[SNARL_STRING_LENGTH];
+ char Text[SNARL_STRING_LENGTH];
+ char Icon[SNARL_STRING_LENGTH];
+
+ char Class[SNARL_STRING_LENGTH];
+ char Extra[SNARL_STRING_LENGTH];
+ char Extra2[SNARL_STRING_LENGTH];
+ LONG32 Reserved1;
+ LONG32 Reserved2;
+ };
+
+
+
+ // ------------------------------------------------------------------------
+ // SnarlInterface class definition
+ // ------------------------------------------------------------------------
+
+ class SnarlInterface {
+ public:
+ SnarlInterface();
+ ~SnarlInterface();
+
+ static HWND GetSnarlWindow();
+ static LONG32 GetGlobalMsg();
+
+
+ LPTSTR AllocateString(size_t n) { return new TCHAR[n]; }
+ void FreeString(LPCTSTR str) { delete [] str; str = NULL; }
+
+
+ LONG32 ShowMessage(LPCSTR szTitle, LPCSTR szText, LONG32 timeout = 0, LPCSTR szIconPath = "", HWND hWndReply = NULL, WPARAM uReplyMsg = 0);
+ LONG32 ShowMessage(LPCWSTR szTitle, LPCWSTR szText, LONG32 timeout = 0, LPCWSTR szIconPath = L"", HWND hWndReply = NULL, WPARAM uReplyMsg = 0);
+ LONG32 ShowMessageEx(LPCSTR szClass, LPCSTR szTitle, LPCSTR szText, LONG32 timeout = 0, LPCSTR szIconPath = "", HWND hWndReply = NULL, WPARAM uReplyMsg = 0, LPCSTR szSoundFile = "");
+ LONG32 ShowMessageEx(LPCWSTR szClass, LPCWSTR szTitle, LPCWSTR szText, LONG32 timeout = 0, LPCWSTR szIconPath = L"", HWND hWndReply = NULL, WPARAM uReplyMsg = 0, LPCWSTR szSoundFile = L"");
+
+ LPCTSTR GetAppPath(); // ** Remember to FreeString when finished with the string !
+ LPCTSTR GetIconsPath(); // ** Remember to FreeString when finished with the string !
+
+ BOOL GetVersion(WORD* Major, WORD* Minor);
+ LONG32 GetVersionEx();
+ BOOL HideMessage();
+ BOOL HideMessage(LONG32 Id);
+ BOOL IsMessageVisible();
+ BOOL IsMessageVisible(LONG32 Id);
+ M_RESULT RegisterAlert(LPCSTR szAppName, LPCSTR szClass);
+ M_RESULT RegisterAlert(LPCWSTR szAppName, LPCWSTR szClass);
+ M_RESULT RegisterConfig(HWND hWnd, LPCSTR szAppName, LONG32 replyMsg);
+ M_RESULT RegisterConfig(HWND hWnd, LPCWSTR szAppName, LONG32 replyMsg);
+ M_RESULT RegisterConfig2(HWND hWnd, LPCSTR szAppName, LONG32 replyMsg, LPCSTR szIcon);
+ M_RESULT RegisterConfig2(HWND hWnd, LPCWSTR szAppName, LONG32 replyMsg, LPCWSTR szIcon);
+ M_RESULT RevokeConfig(HWND hWnd);
+ M_RESULT SetTimeout(LONG32 Timeout);
+ M_RESULT SetTimeout(LONG32 Id, LONG32 Timeout);
+ M_RESULT UpdateMessage(LPCSTR szTitle, LPCSTR szText, LPCSTR szIconPath = "");
+ M_RESULT UpdateMessage(LPCWSTR szTitle, LPCWSTR szText, LPCWSTR szIconPath = L"");
+ M_RESULT UpdateMessage(LONG32 Id, LPCSTR szTitle, LPCSTR szText, LPCSTR szIconPath = "");
+ M_RESULT UpdateMessage(LONG32 Id, LPCWSTR szTitle, LPCWSTR szText, LPCWSTR szIconPath = L"");
+
+ /* V39 */
+ M_RESULT AddClass(LPCSTR Class, LPCSTR Description = NULL, SNARL_CLASS_FLAGS Flags = SNARL_CLASS_ENABLED, LPCSTR DefaultTitle = NULL, LPCSTR DefaultIcon = NULL, LONG32 DefaultTimeout = 0);
+ M_RESULT AddClass(LPCWSTR Class, LPCWSTR Description = NULL, SNARL_CLASS_FLAGS Flags = SNARL_CLASS_ENABLED, LPCWSTR DefaultTitle = NULL, LPCWSTR DefaultIcon = NULL, LONG32 DefaultTimeout = 0);
+ M_RESULT ChangeAttribute(SNARL_ATTRIBUTES Attr, LPCSTR Value);
+ M_RESULT ChangeAttribute(SNARL_ATTRIBUTES Attr, LPCWSTR Value);
+ M_RESULT ChangeAttribute(LONG32 Id, SNARL_ATTRIBUTES Attr, LPCSTR Value);
+ M_RESULT ChangeAttribute(LONG32 Id, SNARL_ATTRIBUTES Attr, LPCWSTR Value);
+ LONG32 GetAppMsg();
+ LONG32 GetRevision();
+
+ M_RESULT RegisterApp(LPCSTR Application, LPCSTR SmallIcon, LPCSTR LargeIcon, HWND hWnd = 0, LONG32 ReplyMsg = 0);
+ M_RESULT RegisterApp(LPCWSTR Application, LPCWSTR SmallIcon, LPCWSTR LargeIcon, HWND hWnd = 0, LONG32 ReplyMsg = 0);
+ void SetAsSnarlApp(HWND hWndOwner, SNARL_APP_FLAGS Flags = (SNARL_APP_FLAGS)(SNARL_APP_HAS_ABOUT | SNARL_APP_HAS_PREFS));
+ M_RESULT SetClassDefault(LPCSTR Class, SNARL_ATTRIBUTES Attr, LPCSTR Value);
+ M_RESULT SetClassDefault(LPCWSTR Class, SNARL_ATTRIBUTES Attr, LPCWSTR Value);
+ LONG32 ShowNotification(LPCSTR Class, LPCSTR Title = NULL, LPCSTR Text = NULL, LONG32 Timeout = 0, LPCSTR Icon = NULL, HWND hWndReply = NULL, LONG32 uReplyMsg = 0, LPCSTR Sound = NULL);
+ LONG32 ShowNotification(LPCWSTR Class, LPCWSTR Title = NULL, LPCWSTR Text = NULL, LONG32 Timeout = 0, LPCWSTR Icon = NULL, HWND hWndReply = NULL, LONG32 uReplyMsg = 0, LPCWSTR Sound = NULL);
+ M_RESULT UnregisterApp();
+
+ LONG32 GetLastMessageId() { return m_nLastMessageId; }
+
+ private:
+ template <class T> LONG32 Send(T ss);
+ LPSTR WideToUTF8(LPCWSTR szWideStr);
+
+ LONG32 m_nLastMessageId;
+ HWND m_hwndFrom; // set during snRegisterConfig() or snRegisterConfig2()
+
+ };
+
+}
+
+#endif // SNARL_INTERFACE