summary refs log tree commit diff stats
path: root/plugins/xtray
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/xtray')
-rw-r--r--plugins/xtray/bitmaps/sd.bmpbin0 -> 32824 bytes
-rw-r--r--plugins/xtray/callbacks.cpp734
-rw-r--r--plugins/xtray/callbacks.h37
-rw-r--r--plugins/xtray/icons/banned.icobin0 -> 1406 bytes
-rw-r--r--plugins/xtray/icons/chan_msg.icobin0 -> 1406 bytes
-rw-r--r--plugins/xtray/icons/disconnected.icobin0 -> 1406 bytes
-rw-r--r--plugins/xtray/icons/highlight-1-3.icobin0 -> 1406 bytes
-rw-r--r--plugins/xtray/icons/highlight.icobin0 -> 1406 bytes
-rw-r--r--plugins/xtray/icons/kicked.icobin0 -> 1406 bytes
-rw-r--r--plugins/xtray/icons/priv_msg-1-2-2.icobin0 -> 1406 bytes
-rw-r--r--plugins/xtray/icons/sd.icobin0 -> 24358 bytes
-rw-r--r--plugins/xtray/icons/server_notice.icobin0 -> 1406 bytes
-rw-r--r--plugins/xtray/icons/xchat.icobin0 -> 25670 bytes
-rw-r--r--plugins/xtray/makefile.mak37
-rw-r--r--plugins/xtray/plugin.h335
-rw-r--r--plugins/xtray/resource.h47
-rw-r--r--plugins/xtray/resource.rc309
-rw-r--r--plugins/xtray/sdAlerts.cpp109
-rw-r--r--plugins/xtray/sdAlerts.h26
-rw-r--r--plugins/xtray/sdTray.cpp207
-rw-r--r--plugins/xtray/sdTray.h39
-rw-r--r--plugins/xtray/utility.cpp563
-rw-r--r--plugins/xtray/utility.h52
-rw-r--r--plugins/xtray/xchat.cpp319
-rw-r--r--plugins/xtray/xchat.h32
-rw-r--r--plugins/xtray/xtray.cpp219
-rw-r--r--plugins/xtray/xtray.h77
27 files changed, 3142 insertions, 0 deletions
diff --git a/plugins/xtray/bitmaps/sd.bmp b/plugins/xtray/bitmaps/sd.bmp
new file mode 100644
index 00000000..9d6b7f95
--- /dev/null
+++ b/plugins/xtray/bitmaps/sd.bmp
Binary files differdiff --git a/plugins/xtray/callbacks.cpp b/plugins/xtray/callbacks.cpp
new file mode 100644
index 00000000..636c114e
--- /dev/null
+++ b/plugins/xtray/callbacks.cpp
@@ -0,0 +1,734 @@
+/* X-Tray

+ * Copyright (C) 2005 Michael Hotaling <Mike.Hotaling@SinisterDevelopments.com>

+ *

+ * X-Tray 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.

+ * 

+ * X-Tray 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 X-Tray; if not, write to the Free Software

+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

+ */

+

+#define _WIN32_IE 0x0601

+

+#include <windows.h>

+#include <stdio.h>

+#include <commctrl.h>

+#include <tchar.h>

+#include "utility.h"

+#include "plugin.h"

+#include "xtray.h"

+#include "xchat.h"

+#include "callbacks.h"

+#include "resource.h"

+#include "sdTray.h"

+#include "sdAlerts.h"

+

+HWND	g_hPrefTabEvents;

+HWND	g_hPrefTabSettings;

+HWND	g_hPrefTabAlerts;

+HWND	g_hPrefTabAbout;

+bool	g_bCanQuit;

+int		g_iIsActive = 1;

+

+

+BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam)

+{

+	TCHAR szTitle[10];

+	GetWindowText(hWnd, szTitle, 9);

+

+	if(_tcsstr(szTitle, _T("XChat [")))

+	{

+		g_hXchatWnd = hWnd;

+		return false;

+	}

+	

+	return true;

+}

+

+/***********************************************************************************************/

+/******* our xchat event call back, get the name and info for each event and save it ***********/

+/******* for our alerts later														***********/

+/***********************************************************************************************/

+int event_cb(char *word[], void *userdata)

+{

+	int iEvent = (int)userdata;

+

+	if(iEvent > 10 && iEvent != 21)

+		return XCHAT_EAT_NONE;

+

+	/***************************************************************************************/

+	/***** if the window is minimized or if we're allowed to show alerts when its not	 **/

+	/***** and if the option to show the specified alert is true and if we're even		**/

+	/***** allowed to show alerts at all then we show them (a bit confusing but it works) **/

+	/***************************************************************************************/

+	if(((g_iIsActive == 0) || !(g_dwPrefs & (1<<PREF_OSBWM))) && (g_dwPrefs & (1<<PREF_AMAE)) && (g_dwPrefs & (1<<iEvent)))

+	{	

+		/*********************************/

+		/*********** Our Buffers *********/

+		/*********************************/

+		char			szInfo[512];

+		char			szName[64];

+		DWORD			dwInfoFlags;

+		int iTime		= g_iTime*1000;

+		char *szTemp	= NULL;

+

+		if(g_dwPrefs & (1<<PREF_KAOI))

+		{

+			iTime = 0;

+		}

+

+		switch(iEvent)

+		{

+		case CHAN_HILIGHT:

+			_snprintf(szInfo, 512, "%s:\r\n%s", word[1], word[2]);

+			_snprintf(szName, 64, "Hilight");

+			dwInfoFlags = NIIF_INFO;

+			break;

+		case CHAN_MESSAGE:

+			_snprintf(szInfo, 512, "%s:\r\n%s", word[1], word[2]);

+			_snprintf(szName, 64, "Channel Message");

+			dwInfoFlags = NIIF_INFO;

+			break;

+		case CHAN_TOPIC_CHANGE:

+			_snprintf(szInfo, 512, "%s has changed the topic to %s", word[1], word[2]);

+			_snprintf(szName, 64, "Topic Change: %s", word[3]);

+			dwInfoFlags = NIIF_INFO;

+			break;

+		case CHAN_INVITE:

+			_snprintf(szInfo, 512, "%s has invited you into %s", word[1], word[2]);

+			_snprintf(szName, 64, "Invite");

+			dwInfoFlags = NIIF_INFO;

+			break;

+		case CHAN_KICKED:

+			_snprintf(szInfo, 512, "Kicked from %s by %s:\r\n%s", word[2], word[3], word[4]);

+			_snprintf(szName, 64, "Kick");

+			dwInfoFlags = NIIF_WARNING;

+			break;

+		case CHAN_BANNED:

+			_snprintf(szInfo, 512, "Cannot join #%s You are banned.", word[1]);

+			_snprintf(szName, 64, "Banned");

+			dwInfoFlags = NIIF_WARNING;

+			break;

+		case CTCP_GENERIC:

+			_snprintf(szInfo, 512, "%s:\r\nCTCP %s", word[2], word[1]);

+			_snprintf(szName, 64, "CTCP");

+			dwInfoFlags = NIIF_INFO;

+			break;

+		case PMSG_RECEIVE:

+			_snprintf(szInfo, 512, "%s:\r\n%s", word[1], word[2]);

+			_snprintf(szName, 64, "Private Message");

+			dwInfoFlags = NIIF_INFO;

+			break;

+		case SERV_DISCONNECT:

+			_snprintf(szInfo, 512, "Disconnected\r\nError: %s", word[1]);

+			_snprintf(szName, 64, "Disconnect");

+			dwInfoFlags = NIIF_ERROR;

+			break;

+		case SERV_KILLED:

+			_snprintf(szInfo, 512, "Killed(%s(%s))", word[1], word[2]);

+			_snprintf(szName, 64, "Server Admin has killed you");

+			dwInfoFlags = NIIF_ERROR;

+			break;

+		case SERV_NOTICE:

+			_snprintf(szInfo, 512, "Notice:\r\n%s: %s", word[1], word[2]);

+			_snprintf(szName, 64, "Notice");

+			dwInfoFlags = NIIF_INFO;

+			break;

+		case 11:

+			_snprintf(szInfo, 512, ":\r\n%s: %s", word[1], word[2]);

+			_snprintf(szName, 64, "Notice");

+			dwInfoFlags = NIIF_INFO;

+			break;

+		}

+

+		/**************************************************************************************/

+		/***** Use windows instead of balloons, and if its a window should we keep it open ****/

+		/***** indefinately?															   ****/

+		/**************************************************************************************/

+		szTemp = xchat_strip_color(szInfo);

+

+		if(g_dwPrefs & (1<<PREF_UWIOB))

+		{

+			sdSystemAlert((HINSTANCE)g_hInstance, IDD_ALERT, szTemp, szName, iTime);

+		}

+		else

+		{

+			ShowBalloon(g_hXchatWnd, 1, szTemp, szName, iTime, dwInfoFlags);

+		}

+

+		free(szTemp);

+	}

+

+	if(g_dwPrefs & (1<<PREF_BLINK))

+	{

+		BlinkIcon(g_hXchatWnd, 1, g_hIcons[0], g_hIcons[(iEvent+1)], 700, 5);

+		

+	}

+

+	/***********************************/

+	/***** pass the events to xchat ****/

+	/***********************************/

+	return XCHAT_EAT_NONE;

+}

+

+int command_cb(char *word[], char *word_eol[], void *userdata)

+{

+	char szInfo[512];

+	char *szTemp	= NULL;

+	int iTime		= g_iTime*1000;

+

+	_snprintf(szInfo, 512, word_eol[2]);

+	szTemp = xchat_strip_color(szInfo);

+

+	if(g_dwPrefs & (1<<PREF_KAOI))

+	{

+		iTime = 0;

+	}

+

+	if(((g_iIsActive == 0) || !(g_dwPrefs & (1<<PREF_OSBWM))) && (g_dwPrefs & (1<<PREF_AMAE)))

+	{

+		if(g_dwPrefs & (1<<PREF_UWIOB))

+		{

+			sdSystemAlert((HINSTANCE)g_hInstance, IDD_ALERT, szTemp, "Alert", iTime);

+		}

+		else

+		{

+			ShowBalloon(g_hXchatWnd, 1, szTemp, "Alert", iTime, NIIF_INFO);

+		}

+	}

+

+	free(szTemp);

+

+	return XCHAT_EAT_ALL;

+}

+

+LRESULT CALLBACK WindowProc(HWND hWnd, UINT msg, WPARAM wparam, LPARAM lparam)

+{

+	switch(msg)

+	{

+	case WM_CLOSE:

+		{

+			if((g_dwPrefs & (1<<PREF_MIOC)) && (g_bCanQuit == false))

+			{

+				/*******************************************/

+				/**** to autoaway or not to autoaway...  ***/

+				/*******************************************/

+				if(g_dwPrefs & (1<<PREF_AOM))

+				{

+					xchat_globally_away(g_szAway);

+				}

+

+				/**************************************************/

+				/**** Win32 API call to hide the window and	     **/

+				/**** save the fact that its minimized for later **/

+				/**************************************************/

+				g_iIsActive = 0;

+				ShowWindow(hWnd, SW_HIDE);

+

+				return 0;

+			}

+			else

+			{

+				if(g_hPrefDlg != NULL)

+				{

+					DestroyWindow(g_hPrefDlg);

+				}

+

+				StopBlink(hWnd, 1, g_hIcons[0]);

+				

+				if(sdAlertNum())

+				{

+					sdCloseAlerts();

+					HoldClose();

+					return 0;

+				}

+			}

+		}

+		break;

+	case WM_SIZE:

+		{

+			/******************************************/

+			/***** User wants to minimize xChat, ******/

+			/***** are we allowed to go to tray? ******/

+			/******************************************/

+			if((g_dwPrefs & (1<<PREF_TOT)) && (wparam == SIZE_MINIMIZED))

+			{

+				/*******************************************/

+				/**** to autoaway or not to autoaway...  ***/

+				/*******************************************/

+				if(g_dwPrefs & (1<<PREF_AOM))

+				{

+					xchat_globally_away(g_szAway);

+				}

+

+				/**************************************************/

+				/**** Win32 API call to hide the window and	     **/

+				/**** save the fact that its minimized for later **/

+				/**************************************************/

+				g_iIsActive = 0;

+				ShowWindow(hWnd, SW_HIDE);

+			}

+		}

+		break;

+	/**********************************/

+	/*** user clicked the tray icon ***/

+	/**********************************/

+	case WM_TRAYMSG:

+		{

+			switch(lparam)

+			{

+			case WM_LBUTTONDOWN:

+				{

+					if(!g_iIsActive)

+					{

+						/*********************************************************/

+						/*** 0: its hiden, restore it and show it, if autoaway ***/

+						/*** is on, set us as back							 ***/

+						/*********************************************************/

+						SendMessage(hWnd, WM_SYSCOMMAND, SC_RESTORE, 0);

+						SetForegroundWindow(hWnd);

+						g_iIsActive = 1;

+

+						if(g_dwPrefs & (1<<PREF_AOM))

+						{

+							xchat_globally_back();

+						}

+					}

+					else

+					{

+						SendMessage(hWnd, WM_SYSCOMMAND, SC_MINIMIZE, 0);

+					}

+				}

+				break;

+			case WM_RBUTTONDOWN:

+				{

+					/******************************************/

+					/*** user wants to see the menu find out **/

+					/*** where the mouse is and show it	  **/

+					/******************************************/

+					POINT pt;

+					int iRet;

+

+					GetCursorPos(&pt);

+					SetForegroundWindow(hWnd);

+

+					ModifyMenu(g_hTrayMenu, 2, (MF_POPUP | MF_BYPOSITION), (UINT)setServerMenu(), _T("Away"));

+

+					Sleep(175);

+

+					iRet = TrackPopupMenuEx(g_hTrayMenu, (TPM_RETURNCMD | TPM_LEFTALIGN), pt.x, pt.y, hWnd, NULL);

+

+					/***********************************/

+					/*** nRet is the users selection, **/

+					/*** process it				   **/

+					/***********************************/

+					sdTrayProc(hWnd, iRet);

+				}

+				break;

+			}

+		}

+		break;

+	default:

+		{

+			/*****************************************************/

+			/*** the taskbar has been restarted, re-add our icon */

+			/*****************************************************/

+			if(msg == RegisterWindowMessage(_T("TaskbarCreated")))

+			{

+				char szVersion[64];

+				_snprintf(szVersion, 64, "XChat-WDK [%s]", xchat_get_info(ph, "version"));

+				AddIcon(g_hXchatWnd, 1, g_hIcons[0], szVersion, (NIF_ICON | NIF_MESSAGE | NIF_TIP), WM_TRAYMSG);

+			}

+		}

+		break;

+	}

+

+	return CallWindowProc(g_hOldProc, hWnd, msg, wparam, lparam);

+}

+

+/****************************************************/

+/*** process messages from the tray menu ************/

+/****************************************************/

+LRESULT CALLBACK sdTrayProc(HWND hWnd, int msg)

+{

+	switch(msg)

+	{

+	case ACT_EXIT:

+		{

+			g_bCanQuit = true;

+			PostMessage(hWnd, WM_CLOSE, 0, 0);

+		}

+		break;

+	case ACT_RESTORE:

+		{

+			/***********************************************/

+			/** user wants us to restore the xchat window **/

+			/** and of autoaway is on, set as back		**/

+			/***********************************************/

+			SendMessage(g_hXchatWnd, WM_SYSCOMMAND, SC_RESTORE, 0);

+			SetForegroundWindow(hWnd);

+			

+			if((!g_iIsActive) && (g_dwPrefs & (1<<PREF_AOM)))

+			{

+				xchat_globally_back();

+				g_iIsActive = 1;

+			}

+		}

+		break;

+	case ACT_SETTINGS:

+		{

+			ShowWindow(g_hPrefDlg, SW_SHOW);

+		}

+		break;

+	case ACT_AWAY:

+		{

+			xchat_globally_away(g_szAway);

+		}

+		break;

+	case ACT_BACK:

+		{

+			xchat_globally_back();

+		}

+		break;

+	default:

+		{

+			if(msg > 0)

+			{

+				xchat_set_context(ph, xchat_find_server(msg-1));

+

+				if(!xchat_get_info(ph, "away"))

+				{

+					xchat_away(g_szAway);

+				}

+				else

+				{

+					xchat_back();

+				}

+			}

+		}

+		break;

+	}

+

+	return 1;

+}

+

+int CALLBACK PrefProc(HWND hWnd, UINT msg, WPARAM wparam, LPARAM lparam)

+{

+	switch(msg)

+	{

+	case WM_INITDIALOG:

+		{

+			TCITEM tci1;

+			TCITEM tci2;

+			TCITEM tci3;

+			TCITEM tci4;

+

+			tci1.mask		= TCIF_TEXT;

+			tci1.pszText	= _T("Settings");

+			tci1.cchTextMax	= strlen("Settings");

+			SendDlgItemMessage(hWnd, IDC_TAB_CONTROL, TCM_INSERTITEM, 0, (LPARAM)&tci1);

+

+			tci2.mask		= TCIF_TEXT;

+			tci2.pszText	= _T("Alerts");

+			tci2.cchTextMax	= strlen("Alerts");

+			SendDlgItemMessage(hWnd, IDC_TAB_CONTROL, TCM_INSERTITEM, 1, (LPARAM)&tci2);

+

+			tci3.mask		= TCIF_TEXT;

+			tci3.pszText	= _T("Events");

+			tci3.cchTextMax	= strlen("Events");

+			SendDlgItemMessage(hWnd, IDC_TAB_CONTROL, TCM_INSERTITEM, 2, (LPARAM)&tci3);

+

+			tci4.mask		= TCIF_TEXT;

+			tci4.pszText	= _T("About");

+			tci4.cchTextMax	= strlen("About");

+			SendDlgItemMessage(hWnd, IDC_TAB_CONTROL, TCM_INSERTITEM, 3, (LPARAM)&tci4);

+

+

+			/***********************************************************************************/

+			/***********************************************************************************/

+			/***********************************************************************************/

+

+			g_hPrefTabSettings	= CreateDialog((HINSTANCE)g_hInstance,

+									MAKEINTRESOURCE(IDD_SETTINGS),

+									hWnd,		

+									(DLGPROC)SettingsProc);

+			SetDialog(g_hPrefTabSettings,	IDD_SETTINGS);

+

+			g_hPrefTabAlerts	= CreateDialog((HINSTANCE)g_hInstance,

+									MAKEINTRESOURCE(IDD_ALERTS),

+									hWnd,

+									(DLGPROC)AlertsProc);

+			SetDialog(g_hPrefTabAlerts,		IDD_ALERTS);

+

+			g_hPrefTabEvents	= CreateDialog((HINSTANCE)g_hInstance,

+									MAKEINTRESOURCE(IDD_EVENTS),

+									hWnd,		

+									(DLGPROC)EventsProc);

+			SetDialog(g_hPrefTabEvents,		IDD_EVENTS);

+

+			g_hPrefTabAbout		= CreateDialog((HINSTANCE)g_hInstance,

+									MAKEINTRESOURCE(IDD_ABOUT),

+									hWnd,

+									(DLGPROC)AboutProc);

+		}

+		break;

+	case WM_SHOWWINDOW:

+		{

+			if(wparam)

+			{

+				SendDlgItemMessage(hWnd, IDC_TAB_CONTROL, TCM_SETCURSEL, 0, 0);

+				ShowWindow(g_hPrefTabSettings,	SW_SHOW);

+				ShowWindow(g_hPrefTabAlerts,	SW_HIDE);

+				ShowWindow(g_hPrefTabEvents,	SW_HIDE);

+				ShowWindow(g_hPrefTabAbout,		SW_HIDE);

+			}

+		}

+		break;

+	case WM_NOTIFY:

+		{

+			NMHDR *pData = (NMHDR *)lparam;

+

+			switch(pData->code)

+			{

+			case TCN_SELCHANGE:

+				{

+					switch(SendDlgItemMessage(hWnd, IDC_TAB_CONTROL, TCM_GETCURSEL, 0, 0))

+					{

+					case 0:

+						{

+							ShowWindow(g_hPrefTabSettings,	SW_SHOW);

+							ShowWindow(g_hPrefTabAlerts,	SW_HIDE);

+							ShowWindow(g_hPrefTabEvents,	SW_HIDE);

+							ShowWindow(g_hPrefTabAbout,		SW_HIDE);

+						}

+						break;

+					case 1:

+						{

+							ShowWindow(g_hPrefTabSettings,	SW_HIDE);

+							ShowWindow(g_hPrefTabAlerts,	SW_SHOW);

+							ShowWindow(g_hPrefTabEvents,	SW_HIDE);

+							ShowWindow(g_hPrefTabAbout,		SW_HIDE);

+						}

+						break;

+					case 2:

+						{

+							ShowWindow(g_hPrefTabSettings,	SW_HIDE);

+							ShowWindow(g_hPrefTabAlerts,	SW_HIDE);

+							ShowWindow(g_hPrefTabEvents,	SW_SHOW);

+							ShowWindow(g_hPrefTabAbout,		SW_HIDE);

+						}

+						break;

+					case 3:

+						{

+							ShowWindow(g_hPrefTabSettings,	SW_HIDE);

+							ShowWindow(g_hPrefTabAlerts,	SW_HIDE);

+							ShowWindow(g_hPrefTabEvents,	SW_HIDE);

+							ShowWindow(g_hPrefTabAbout,		SW_SHOW);

+						}

+						break;

+					}

+				}

+				break;

+			}

+		}

+		break;

+	case WM_CLOSE:

+		{

+			ShowWindow(g_hPrefTabEvents,	SW_HIDE);

+			ShowWindow(g_hPrefTabSettings,	SW_HIDE);

+			ShowWindow(g_hPrefTabAlerts,	SW_HIDE);

+			ShowWindow(g_hPrefTabAbout,		SW_HIDE);

+			ShowWindow(hWnd,				SW_HIDE);

+			return TRUE;

+		}

+		break;

+	case WM_COMMAND:

+		{

+			switch(wparam)

+			{

+			case IDC_PREF_OK:

+				{

+					CheckPrefs(g_hPrefTabEvents,	IDD_EVENTS);

+					CheckPrefs(g_hPrefTabSettings,	IDD_SETTINGS);

+					CheckPrefs(g_hPrefTabAlerts,	IDD_ALERTS);

+

+					SavePrefs(0);

+

+					ShowWindow(g_hPrefTabEvents,	SW_HIDE);

+					ShowWindow(g_hPrefTabSettings,	SW_HIDE);

+					ShowWindow(g_hPrefTabAlerts,	SW_HIDE);

+					ShowWindow(g_hPrefTabAbout,		SW_HIDE);

+					ShowWindow(hWnd,				SW_HIDE);

+					return TRUE;

+				}

+				break;

+			case IDC_PREF_CANCEL:

+				{

+					ShowWindow(g_hPrefTabEvents,	SW_HIDE);

+					ShowWindow(g_hPrefTabSettings,	SW_HIDE);

+					ShowWindow(g_hPrefTabAlerts,	SW_HIDE);

+					ShowWindow(g_hPrefTabAbout,		SW_HIDE);

+					ShowWindow(hWnd,				SW_HIDE);

+					return TRUE;

+				}

+				break;

+			case IDC_PREF_APPLY:

+				{

+					CheckPrefs(g_hPrefTabEvents,	IDD_EVENTS);

+					CheckPrefs(g_hPrefTabSettings,	IDD_SETTINGS);

+					CheckPrefs(g_hPrefTabAlerts,	IDD_ALERTS);

+

+					SavePrefs(0);

+					return FALSE;

+				}

+				break;

+			}

+		}

+		break;

+	case WM_DESTROY:

+		{

+			SendMessage(g_hPrefTabEvents,	WM_CLOSE, 0, 0);

+			SendMessage(g_hPrefTabSettings,	WM_CLOSE, 0, 0);

+			SendMessage(g_hPrefTabAbout,	WM_CLOSE, 0, 0);

+			SendMessage(g_hPrefTabAlerts,	WM_CLOSE, 0, 0);

+		}

+		break;

+	}

+

+	return FALSE;

+}

+

+/****************************************************/

+/****************************************************/

+/****************************************************/

+LRESULT CALLBACK AlertsProc(HWND hWnd, UINT msg, WPARAM wparam, LPARAM lparam)

+{

+	switch(msg)

+	{

+	case WM_CLOSE:

+		{

+			DestroyWindow(hWnd);

+			return TRUE;

+			break;

+		}

+		break;

+	case WM_COMMAND:

+		{

+			switch(LOWORD(wparam))

+			{

+			case PREF_AMAE:

+				{

+					SetToggle(hWnd, PREF_OSBWM,			PREF_AMAE, TRUE);

+					SetToggle(hWnd, PREF_UWIOB,			PREF_AMAE, TRUE);

+					SetToggle(hWnd, PREF_KAOI,			PREF_AMAE, TRUE);

+					

+					if(IsDlgButtonChecked(hWnd, PREF_AMAE))

+					{

+						SetToggle(hWnd, IDC_ALERT_HOTKEY,		PREF_UWIOB, TRUE);

+						SetToggle(hWnd, IDC_ALERT_HOTKEY_TEXT,	PREF_UWIOB, TRUE);

+						SetToggle(hWnd, IDC_ALERT_TIME,			PREF_KAOI, FALSE);

+						SetToggle(hWnd, IDC_ALERT_TIME_TEXT,	PREF_KAOI, FALSE);

+					}

+					else

+					{

+						SetToggle(hWnd, IDC_ALERT_HOTKEY,		PREF_AMAE, TRUE);

+						SetToggle(hWnd, IDC_ALERT_HOTKEY_TEXT,	PREF_AMAE, TRUE);

+						SetToggle(hWnd, IDC_ALERT_TIME,			PREF_AMAE, TRUE);

+						SetToggle(hWnd, IDC_ALERT_TIME_TEXT,	PREF_AMAE, TRUE);

+					}

+				}

+				break;

+			case PREF_UWIOB:

+				{

+					SetToggle(hWnd, IDC_ALERT_HOTKEY,		PREF_UWIOB, TRUE);

+					SetToggle(hWnd, IDC_ALERT_HOTKEY_TEXT,	PREF_UWIOB, TRUE);

+				}

+				break;

+			case PREF_KAOI:

+				{

+					SetToggle(hWnd, IDC_ALERT_TIME,			PREF_KAOI, FALSE);

+					SetToggle(hWnd, IDC_ALERT_TIME_TEXT,	PREF_KAOI, FALSE);

+				}

+				break;

+			}

+			break;

+		}

+	}

+

+	return FALSE;

+}

+

+/****************************************************/

+/****************************************************/

+/****************************************************/

+LRESULT CALLBACK AboutProc(HWND hWnd, UINT msg, WPARAM wparam, LPARAM lparam)

+{

+	if(msg == WM_CLOSE)

+	{

+		DestroyWindow(hWnd);

+		return true;

+	}

+

+	return FALSE;

+}

+

+/*****************************************************/

+/** Process the events for our event dialog **********/

+/*****************************************************/

+LRESULT CALLBACK EventsProc(HWND hWnd, UINT msg, WPARAM wparam, LPARAM lparam)

+{

+	if(msg == WM_CLOSE)

+	{

+		DestroyWindow(hWnd);

+		return true;

+	}

+

+	return FALSE;

+}

+

+/*****************************************************/

+/** Process the events for our settings dialog this **/

+/** is alot more complicated because options are	**/

+/** enabled/disabled based on the state of others   **/

+/*****************************************************/

+LRESULT CALLBACK SettingsProc(HWND hWnd, UINT msg, WPARAM wparam, LPARAM lparam)

+{

+	if(msg == WM_CLOSE)

+	{

+		DestroyWindow(hWnd);

+		return true;

+	}

+

+	return FALSE;

+}

+

+/*****************************************************/

+/** this is the hotkey message  processing function **/

+/** this window is always open and ready to be told **/

+/** if someone has hit the hotkey, if they did, we  **/

+/** need to close out all of the tray alerts, for   **/

+/** this I wrote sdCloseAlerts, more info there	 **/

+/*****************************************************/

+LRESULT CALLBACK HotKeyProc(HWND hWnd, UINT msg, WPARAM wparam, LPARAM lparam)

+{

+	if(msg == WM_CLOSE)

+	{

+		DestroyWindow(hWnd);

+		return true;

+	}

+	else if(msg == WM_HOTKEY)

+	{

+		sdCloseAlerts();

+	}

+

+	return FALSE;

+}

+

diff --git a/plugins/xtray/callbacks.h b/plugins/xtray/callbacks.h
new file mode 100644
index 00000000..99cbae74
--- /dev/null
+++ b/plugins/xtray/callbacks.h
@@ -0,0 +1,37 @@
+/* X-Tray

+ * Copyright (C) 2005 Michael Hotaling <Mike.Hotaling@SinisterDevelopments.com>

+ *

+ * X-Tray 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.

+ * 

+ * X-Tray 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 X-Tray; if not, write to the Free Software

+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

+ */

+

+#ifndef _H_CALLBACKS_H

+#define _H_CALLBACKS_H

+

+int					event_cb		(char *word[], void *userdata);

+int					command_cb		(char *word[], char *word_eol[], void *userdata);

+

+LRESULT CALLBACK	WindowProc		(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);

+BOOL	CALLBACK	EnumWindowsProc	(HWND hWnd, LPARAM lParam);

+LRESULT CALLBACK	sdTrayProc		(HWND hwnd, int msg);

+

+LRESULT CALLBACK	AlertProc		(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);

+LRESULT CALLBACK	HotKeyProc		(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);

+LRESULT CALLBACK	EventsProc		(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);

+LRESULT CALLBACK	AboutProc		(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);

+LRESULT CALLBACK	AlertsProc		(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);

+LRESULT CALLBACK	SettingsProc	(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);

+int		CALLBACK	PrefProc		(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);

+

+#endif
\ No newline at end of file
diff --git a/plugins/xtray/icons/banned.ico b/plugins/xtray/icons/banned.ico
new file mode 100644
index 00000000..fef8df8c
--- /dev/null
+++ b/plugins/xtray/icons/banned.ico
Binary files differdiff --git a/plugins/xtray/icons/chan_msg.ico b/plugins/xtray/icons/chan_msg.ico
new file mode 100644
index 00000000..793d050e
--- /dev/null
+++ b/plugins/xtray/icons/chan_msg.ico
Binary files differdiff --git a/plugins/xtray/icons/disconnected.ico b/plugins/xtray/icons/disconnected.ico
new file mode 100644
index 00000000..9063e7e3
--- /dev/null
+++ b/plugins/xtray/icons/disconnected.ico
Binary files differdiff --git a/plugins/xtray/icons/highlight-1-3.ico b/plugins/xtray/icons/highlight-1-3.ico
new file mode 100644
index 00000000..a759145b
--- /dev/null
+++ b/plugins/xtray/icons/highlight-1-3.ico
Binary files differdiff --git a/plugins/xtray/icons/highlight.ico b/plugins/xtray/icons/highlight.ico
new file mode 100644
index 00000000..625cca9a
--- /dev/null
+++ b/plugins/xtray/icons/highlight.ico
Binary files differdiff --git a/plugins/xtray/icons/kicked.ico b/plugins/xtray/icons/kicked.ico
new file mode 100644
index 00000000..845a74e1
--- /dev/null
+++ b/plugins/xtray/icons/kicked.ico
Binary files differdiff --git a/plugins/xtray/icons/priv_msg-1-2-2.ico b/plugins/xtray/icons/priv_msg-1-2-2.ico
new file mode 100644
index 00000000..7941ff77
--- /dev/null
+++ b/plugins/xtray/icons/priv_msg-1-2-2.ico
Binary files differdiff --git a/plugins/xtray/icons/sd.ico b/plugins/xtray/icons/sd.ico
new file mode 100644
index 00000000..ca179621
--- /dev/null
+++ b/plugins/xtray/icons/sd.ico
Binary files differdiff --git a/plugins/xtray/icons/server_notice.ico b/plugins/xtray/icons/server_notice.ico
new file mode 100644
index 00000000..ff765d87
--- /dev/null
+++ b/plugins/xtray/icons/server_notice.ico
Binary files differdiff --git a/plugins/xtray/icons/xchat.ico b/plugins/xtray/icons/xchat.ico
new file mode 100644
index 00000000..73247fd0
--- /dev/null
+++ b/plugins/xtray/icons/xchat.ico
Binary files differdiff --git a/plugins/xtray/makefile.mak b/plugins/xtray/makefile.mak
new file mode 100644
index 00000000..d1f8d295
--- /dev/null
+++ b/plugins/xtray/makefile.mak
@@ -0,0 +1,37 @@
+include "..\..\src\makeinc.mak"
+
+TARGET = xtray.dll
+
+TRAY_OBJECTS = \
+callbacks.obj \
+sdAlerts.obj \
+sdTray.obj \
+utility.obj \
+xchat.obj \
+xtray.obj
+
+CPPFLAGS = $(CPPFLAGS) /D_STL70_ /D_STATIC_CPPLIB /EHsc /DUNICODE /D_UNICODE
+
+all: $(TRAY_OBJECTS) $(TARGET)
+
+xtray.def:
+	echo EXPORTS > xtray.def
+	echo xchat_plugin_init >> xtray.def
+	echo xchat_plugin_deinit >> xtray.def
+
+.cpp.obj:
+	$(CC) $(CPPFLAGS) /c $<
+
+res:
+	rc /nologo resource.rc
+	
+$(TARGET): $(TRAY_OBJECTS) xtray.def res
+	$(LINK) /DLL /out:$(TARGET) $(LDFLAGS) $(TRAY_OBJECTS) ntstc_msvcrt.lib $(LIBS) /def:xtray.def resource.res
+
+clean:
+	del $(TARGET)
+	del *.obj
+	del xtray.def
+	del resource.res
+	del *.lib
+	del *.exp
diff --git a/plugins/xtray/plugin.h b/plugins/xtray/plugin.h
new file mode 100644
index 00000000..50b0de21
--- /dev/null
+++ b/plugins/xtray/plugin.h
@@ -0,0 +1,335 @@
+/* You can distribute this header with your plugins for easy compilation */
+#ifndef XCHAT_PLUGIN_H
+#define XCHAT_PLUGIN_H
+
+#include <time.h>
+
+#define XCHAT_IFACE_MAJOR	1
+#define XCHAT_IFACE_MINOR	9
+#define XCHAT_IFACE_MICRO	11
+#define XCHAT_IFACE_VERSION	((XCHAT_IFACE_MAJOR * 10000) + \
+				 (XCHAT_IFACE_MINOR * 100) + \
+				 (XCHAT_IFACE_MICRO))
+
+#define XCHAT_PRI_HIGHEST	127
+#define XCHAT_PRI_HIGH		64
+#define XCHAT_PRI_NORM		0
+#define XCHAT_PRI_LOW		(-64)
+#define XCHAT_PRI_LOWEST	(-128)
+
+#define XCHAT_FD_READ		1
+#define XCHAT_FD_WRITE		2
+#define XCHAT_FD_EXCEPTION	4
+#define XCHAT_FD_NOTSOCKET	8
+
+#define XCHAT_EAT_NONE		0	/* pass it on through! */
+#define XCHAT_EAT_XCHAT		1	/* don't let xchat see this event */
+#define XCHAT_EAT_PLUGIN	2	/* don't let other plugins see this event */
+#define XCHAT_EAT_ALL		(XCHAT_EAT_XCHAT|XCHAT_EAT_PLUGIN)	/* don't let anything see this event */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct _xchat_plugin xchat_plugin;
+typedef struct _xchat_list xchat_list;
+typedef struct _xchat_hook xchat_hook;
+#ifndef PLUGIN_C
+typedef struct _xchat_context xchat_context;
+#endif
+
+#ifndef PLUGIN_C
+struct _xchat_plugin
+{
+	/* these are only used on win32 */
+	xchat_hook *(*xchat_hook_command) (xchat_plugin *ph,
+		    const char *name,
+		    int pri,
+		    int (*callback) (char *word[], char *word_eol[], void *user_data),
+		    const char *help_text,
+		    void *userdata);
+	xchat_hook *(*xchat_hook_server) (xchat_plugin *ph,
+		   const char *name,
+		   int pri,
+		   int (*callback) (char *word[], char *word_eol[], void *user_data),
+		   void *userdata);
+	xchat_hook *(*xchat_hook_print) (xchat_plugin *ph,
+		  const char *name,
+		  int pri,
+		  int (*callback) (char *word[], void *user_data),
+		  void *userdata);
+	xchat_hook *(*xchat_hook_timer) (xchat_plugin *ph,
+		  int timeout,
+		  int (*callback) (void *user_data),
+		  void *userdata);
+	xchat_hook *(*xchat_hook_fd) (xchat_plugin *ph,
+		   int fd,
+		   int flags,
+		   int (*callback) (int fd, int flags, void *user_data),
+		   void *userdata);
+	void *(*xchat_unhook) (xchat_plugin *ph,
+	      xchat_hook *hook);
+	void (*xchat_print) (xchat_plugin *ph,
+	     const char *text);
+	void (*xchat_printf) (xchat_plugin *ph,
+	      const char *format, ...);
+	void (*xchat_command) (xchat_plugin *ph,
+	       const char *command);
+	void (*xchat_commandf) (xchat_plugin *ph,
+		const char *format, ...);
+	int (*xchat_nickcmp) (xchat_plugin *ph,
+	       const char *s1,
+	       const char *s2);
+	int (*xchat_set_context) (xchat_plugin *ph,
+		   xchat_context *ctx);
+	xchat_context *(*xchat_find_context) (xchat_plugin *ph,
+		    const char *servname,
+		    const char *channel);
+	xchat_context *(*xchat_get_context) (xchat_plugin *ph);
+	const char *(*xchat_get_info) (xchat_plugin *ph,
+		const char *id);
+	int (*xchat_get_prefs) (xchat_plugin *ph,
+		 const char *name,
+		 const char **string,
+		 int *integer);
+	xchat_list * (*xchat_list_get) (xchat_plugin *ph,
+		const char *name);
+	void (*xchat_list_free) (xchat_plugin *ph,
+		 xchat_list *xlist);
+	const char * const * (*xchat_list_fields) (xchat_plugin *ph,
+		   const char *name);
+	int (*xchat_list_next) (xchat_plugin *ph,
+		 xchat_list *xlist);
+	const char * (*xchat_list_str) (xchat_plugin *ph,
+		xchat_list *xlist,
+		const char *name);
+	int (*xchat_list_int) (xchat_plugin *ph,
+		xchat_list *xlist,
+		const char *name);
+	void * (*xchat_plugingui_add) (xchat_plugin *ph,
+		     const char *filename,
+		     const char *name,
+		     const char *desc,
+		     const char *version,
+		     char *reserved);
+	void (*xchat_plugingui_remove) (xchat_plugin *ph,
+			void *handle);
+	int (*xchat_emit_print) (xchat_plugin *ph,
+			const char *event_name, ...);
+	int (*xchat_read_fd) (xchat_plugin *ph,
+			void *src,
+			char *buf,
+			int *len);
+	time_t (*xchat_list_time) (xchat_plugin *ph,
+		xchat_list *xlist,
+		const char *name);
+	char *(*xchat_gettext) (xchat_plugin *ph,
+		const char *msgid);
+	void (*xchat_send_modes) (xchat_plugin *ph,
+		  const char **targets,
+		  int ntargets,
+		  int modes_per_line,
+		  char sign,
+		  char mode);
+	char *(*xchat_strip) (xchat_plugin *ph,
+	     const char *str,
+	     int len,
+	     int flags);
+	void (*xchat_free) (xchat_plugin *ph,
+	    void *ptr);
+};
+#endif
+
+
+
+xchat_hook *
+xchat_hook_command (xchat_plugin *ph,
+		    const char *name,
+		    int pri,
+		    int (*callback) (char *word[], char *word_eol[], void *user_data),
+		    const char *help_text,
+		    void *userdata);
+
+xchat_hook *
+xchat_hook_server (xchat_plugin *ph,
+		   const char *name,
+		   int pri,
+		   int (*callback) (char *word[], char *word_eol[], void *user_data),
+		   void *userdata);
+
+xchat_hook *
+xchat_hook_print (xchat_plugin *ph,
+		  const char *name,
+		  int pri,
+		  int (*callback) (char *word[], void *user_data),
+		  void *userdata);
+
+xchat_hook *
+xchat_hook_timer (xchat_plugin *ph,
+		  int timeout,
+		  int (*callback) (void *user_data),
+		  void *userdata);
+
+xchat_hook *
+xchat_hook_fd (xchat_plugin *ph,
+		int fd,
+		int flags,
+		int (*callback) (int fd, int flags, void *user_data),
+		void *userdata);
+
+void *
+xchat_unhook (xchat_plugin *ph,
+	      xchat_hook *hook);
+
+void
+xchat_print (xchat_plugin *ph,
+	     const char *text);
+
+void
+xchat_printf (xchat_plugin *ph,
+	      const char *format, ...);
+
+void
+xchat_command (xchat_plugin *ph,
+	       const char *command);
+
+void
+xchat_commandf (xchat_plugin *ph,
+		const char *format, ...);
+
+int
+xchat_nickcmp (xchat_plugin *ph,
+	       const char *s1,
+	       const char *s2);
+
+int
+xchat_set_context (xchat_plugin *ph,
+		   xchat_context *ctx);
+
+xchat_context *
+xchat_find_context (xchat_plugin *ph,
+		    const char *servname,
+		    const char *channel);
+
+xchat_context *
+xchat_get_context (xchat_plugin *ph);
+
+const char *
+xchat_get_info (xchat_plugin *ph,
+		const char *id);
+
+int
+xchat_get_prefs (xchat_plugin *ph,
+		 const char *name,
+		 const char **string,
+		 int *integer);
+
+xchat_list *
+xchat_list_get (xchat_plugin *ph,
+		const char *name);
+
+void
+xchat_list_free (xchat_plugin *ph,
+		 xchat_list *xlist);
+
+const char * const *
+xchat_list_fields (xchat_plugin *ph,
+		   const char *name);
+
+int
+xchat_list_next (xchat_plugin *ph,
+		 xchat_list *xlist);
+
+const char *
+xchat_list_str (xchat_plugin *ph,
+		xchat_list *xlist,
+		const char *name);
+
+int
+xchat_list_int (xchat_plugin *ph,
+		xchat_list *xlist,
+		const char *name);
+
+time_t
+xchat_list_time (xchat_plugin *ph,
+		 xchat_list *xlist,
+		 const char *name);
+
+void *
+xchat_plugingui_add (xchat_plugin *ph,
+		     const char *filename,
+		     const char *name,
+		     const char *desc,
+		     const char *version,
+		     char *reserved);
+
+void
+xchat_plugingui_remove (xchat_plugin *ph,
+			void *handle);
+
+int 
+xchat_emit_print (xchat_plugin *ph,
+		  const char *event_name, ...);
+
+char *
+xchat_gettext (xchat_plugin *ph,
+	       const char *msgid);
+
+void
+xchat_send_modes (xchat_plugin *ph,
+		  const char **targets,
+		  int ntargets,
+		  int modes_per_line,
+		  char sign,
+		  char mode);
+
+char *
+xchat_strip (xchat_plugin *ph,
+	     const char *str,
+	     int len,
+	     int flags);
+
+void
+xchat_free (xchat_plugin *ph,
+	    void *ptr);
+
+#if !defined(PLUGIN_C) && defined(WIN32)
+#ifndef XCHAT_PLUGIN_HANDLE
+#define XCHAT_PLUGIN_HANDLE (ph)
+#endif
+#define xchat_hook_command ((XCHAT_PLUGIN_HANDLE)->xchat_hook_command)
+#define xchat_hook_server ((XCHAT_PLUGIN_HANDLE)->xchat_hook_server)
+#define xchat_hook_print ((XCHAT_PLUGIN_HANDLE)->xchat_hook_print)
+#define xchat_hook_timer ((XCHAT_PLUGIN_HANDLE)->xchat_hook_timer)
+#define xchat_hook_fd ((XCHAT_PLUGIN_HANDLE)->xchat_hook_fd)
+#define xchat_unhook ((XCHAT_PLUGIN_HANDLE)->xchat_unhook)
+#define xchat_print ((XCHAT_PLUGIN_HANDLE)->xchat_print)
+#define xchat_printf ((XCHAT_PLUGIN_HANDLE)->xchat_printf)
+#define xchat_command ((XCHAT_PLUGIN_HANDLE)->xchat_command)
+#define xchat_commandf ((XCHAT_PLUGIN_HANDLE)->xchat_commandf)
+#define xchat_nickcmp ((XCHAT_PLUGIN_HANDLE)->xchat_nickcmp)
+#define xchat_set_context ((XCHAT_PLUGIN_HANDLE)->xchat_set_context)
+#define xchat_find_context ((XCHAT_PLUGIN_HANDLE)->xchat_find_context)
+#define xchat_get_context ((XCHAT_PLUGIN_HANDLE)->xchat_get_context)
+#define xchat_get_info ((XCHAT_PLUGIN_HANDLE)->xchat_get_info)
+#define xchat_get_prefs ((XCHAT_PLUGIN_HANDLE)->xchat_get_prefs)
+#define xchat_list_get ((XCHAT_PLUGIN_HANDLE)->xchat_list_get)
+#define xchat_list_free ((XCHAT_PLUGIN_HANDLE)->xchat_list_free)
+#define xchat_list_fields ((XCHAT_PLUGIN_HANDLE)->xchat_list_fields)
+#define xchat_list_str ((XCHAT_PLUGIN_HANDLE)->xchat_list_str)
+#define xchat_list_int ((XCHAT_PLUGIN_HANDLE)->xchat_list_int)
+#define xchat_list_time ((XCHAT_PLUGIN_HANDLE)->xchat_list_time)
+#define xchat_list_next ((XCHAT_PLUGIN_HANDLE)->xchat_list_next)
+#define xchat_plugingui_add ((XCHAT_PLUGIN_HANDLE)->xchat_plugingui_add)
+#define xchat_plugingui_remove ((XCHAT_PLUGIN_HANDLE)->xchat_plugingui_remove)
+#define xchat_emit_print ((XCHAT_PLUGIN_HANDLE)->xchat_emit_print)
+#define xchat_gettext ((XCHAT_PLUGIN_HANDLE)->xchat_gettext)
+#define xchat_send_modes ((XCHAT_PLUGIN_HANDLE)->xchat_send_modes)
+#define xchat_strip ((XCHAT_PLUGIN_HANDLE)->xchat_strip)
+#define xchat_free ((XCHAT_PLUGIN_HANDLE)->xchat_free)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/plugins/xtray/resource.h b/plugins/xtray/resource.h
new file mode 100644
index 00000000..b8008c2c
--- /dev/null
+++ b/plugins/xtray/resource.h
@@ -0,0 +1,47 @@
+//{{NO_DEPENDENCIES}}

+// Microsoft Visual C++ generated include file.

+// Used by resource.rc

+//

+#define IDD_ALERTS                      104

+#define IDD_EVENTS                      105

+#define IDD_SETTINGS                    106

+#define IDD_ALERT                       107

+#define IDD_PREF                        108

+#define IDD_ABOUT                       109

+#define IDR_TRAY_MENU                   110

+#define ICO_XCHAT                       111

+#define ICO_BANNED                      112

+#define ICO_CHANMSG                     113

+#define ICO_DISCONNECTED                114

+#define ICO_HIGHLIGHT                   115

+#define ICO_KICKED                      116

+#define ICO_PMSG                        117

+#define ICO_SNOTICE                     118

+#define IDB_SD_LOGO                     119

+#define IDC_PREF_OK                     1014

+#define IDC_PREF_CANCEL                 1015

+#define IDC_PREF_APPLY                  1016

+#define IDC_AWAY_MSG                    1017

+#define IDC_ALERT_TIME                  1018

+#define IDC_TAB_CONTROL                 1019

+#define IDC_ALERT_HOTKEY                1020

+#define IDC_ALERT_MSG                   1021

+#define IDC_ALERT_HOTKEY_TEXT           1022

+#define IDC_ALERT_TIME_TEXT             1023

+#define ACT_EXIT                        40001

+#define ACT_SETTINGS                    40002

+#define ACT_AWAY                        40003

+#define ACT_BACK                        40004

+#define ACT_RESTORE                     40005

+#define IDC_STATIC                      -1

+

+// Next default values for new objects

+// 

+#ifdef APSTUDIO_INVOKED

+#ifndef APSTUDIO_READONLY_SYMBOLS

+#define _APS_NEXT_RESOURCE_VALUE        120

+#define _APS_NEXT_COMMAND_VALUE         40006

+#define _APS_NEXT_CONTROL_VALUE         1024

+#define _APS_NEXT_SYMED_VALUE           101

+#endif

+#endif

diff --git a/plugins/xtray/resource.rc b/plugins/xtray/resource.rc
new file mode 100644
index 00000000..906cf591
--- /dev/null
+++ b/plugins/xtray/resource.rc
@@ -0,0 +1,309 @@
+// Microsoft Visual C++ generated resource script.

+//

+#include "resource.h"

+

+#define APSTUDIO_READONLY_SYMBOLS

+/////////////////////////////////////////////////////////////////////////////

+//

+// Generated from the TEXTINCLUDE 2 resource.

+//

+#define APSTUDIO_HIDDEN_SYMBOLS

+#include "windows.h"

+#undef APSTUDIO_HIDDEN_SYMBOLS

+

+/////////////////////////////////////////////////////////////////////////////

+#undef APSTUDIO_READONLY_SYMBOLS

+

+/////////////////////////////////////////////////////////////////////////////

+// English (U.S.) resources

+

+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)

+#ifdef _WIN32

+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US

+#pragma code_page(1252)

+#endif //_WIN32

+

+/////////////////////////////////////////////////////////////////////////////

+//

+// Dialog

+//

+

+IDD_EVENTS DIALOGEX 8, 20, 216, 143

+STYLE DS_SETFONT | DS_SETFOREGROUND | WS_CHILD

+FONT 8, "Tahoma", 0, 0, 0x0

+BEGIN

+    GROUPBOX        "XChat Events",IDC_STATIC,5,5,205,77

+    CONTROL         "Banned",4,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,18,49,10

+    CONTROL         "Kicked",5,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,32,49,10

+    CONTROL         "Killed",8,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,46,49,10

+    CONTROL         "Disconnect",10,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,60,49,10

+    CONTROL         "Private Message",7,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,70,18,69,10

+    CONTROL         "Channel Message",21,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,70,32,69,10

+    CONTROL         "Highlight",1,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,70,46,69,10

+    CONTROL         "CTCP",6,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,70,60,69,10

+    CONTROL         "Topic Change",3,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,145,18,55,10

+    CONTROL         "Server Notice",9,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,145,32,55,10

+    CONTROL         "Invite",2,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,145,46,55,10

+END

+

+IDD_SETTINGS DIALOGEX 8, 20, 216, 143

+STYLE DS_SETFONT | WS_CHILD

+FONT 8, "Tahoma", 0, 0, 0x0

+BEGIN

+    GROUPBOX        "Options",IDC_STATIC,5,5,205,135

+    CONTROL         "Auto away on minimize",11,"Button",BS_AUTOCHECKBOX | 

+                    WS_TABSTOP,16,60,100,10

+    CONTROL         "Minimize XChat to the system tray",12,"Button",

+                    BS_AUTOCHECKBOX | WS_TABSTOP,16,18,133,10

+    CONTROL         "Minimize to the tray instead of closing",17,"Button",

+                    BS_AUTOCHECKBOX | WS_TABSTOP,16,32,174,9

+    EDITTEXT        IDC_AWAY_MSG,33,86,169,50,ES_AUTOHSCROLL

+    LTEXT           "Away Msg:",IDC_STATIC,27,72,35,8

+    CONTROL         "Remove XChat from the taskbar (only show in tray)",

+                    20,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,46,191,9

+END

+

+IDD_ALERT DIALOGEX 0, 0, 151, 28

+STYLE DS_LOCALEDIT | DS_SETFONT | DS_NOIDLEMSG | DS_CENTER | WS_CAPTION | 

+    WS_SYSMENU

+EXSTYLE WS_EX_NOPARENTNOTIFY | WS_EX_ACCEPTFILES | WS_EX_TOOLWINDOW

+CAPTION "Event Name"

+FONT 8, "Tahoma", 0, 0, 0x1

+BEGIN

+    LTEXT           "Event Text",IDC_ALERT_MSG,3,0,147,27

+END

+

+IDD_PREF DIALOGEX 0, 0, 233, 190

+STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | 

+    WS_SYSMENU

+CAPTION "X-Tray Preferences"

+FONT 8, "Tahoma", 0, 0, 0x0

+BEGIN

+    DEFPUSHBUTTON   "Ok",IDC_PREF_OK,57,173,50,14

+    PUSHBUTTON      "Cancel",IDC_PREF_CANCEL,115,173,50,14

+    PUSHBUTTON      "Apply",IDC_PREF_APPLY,175,173,50,14

+    CONTROL         "Tab1",IDC_TAB_CONTROL,"SysTabControl32",0x0,7,7,218,159

+END

+

+IDD_ABOUT DIALOGEX 8, 20, 216, 143

+STYLE DS_SETFONT | WS_CHILD

+FONT 8, "Tahoma", 0, 0, 0x0

+BEGIN

+    CONTROL         119,IDC_STATIC,"Static",SS_BITMAP | SS_SUNKEN | 

+                    WS_BORDER,3,6,88,81

+    CTEXT           "X-Tray\r\nBy: Michael Hotaling\r\n www.SinisterDevelopments.com",

+                    IDC_STATIC,95,33,118,30

+    LTEXT           "Folken\r\nBasket\r\nDonatzsky\r\nDaemon404",IDC_STATIC,

+                    15,103,64,33

+    GROUPBOX        "Special Thanks To:",IDC_STATIC,3,91,89,50

+    GROUPBOX        "Version Information:",IDC_STATIC,101,92,109,49

+    LTEXT           "1.2.4",IDC_STATIC,170,105,33,8,0,WS_EX_RIGHT

+    LTEXT           "Compiled In: ",IDC_STATIC,110,117,54,8

+    LTEXT           "2011",IDC_STATIC,170,117,33,8,0,WS_EX_RIGHT

+    LTEXT           "Version Number:",IDC_STATIC,110,105,54,8

+END

+

+IDD_ALERTS DIALOGEX 8, 20, 216, 143

+STYLE DS_SETFONT | WS_CHILD

+FONT 8, "Tahoma", 0, 0, 0x0

+BEGIN

+    GROUPBOX        "Alerts",IDC_STATIC,5,5,205,117

+    CONTROL         "Only show alerts while minimized",14,"Button",

+                    BS_AUTOCHECKBOX | WS_TABSTOP,27,46,117,10

+    CONTROL         "Use tray alerts to notify me about events",13,"Button",

+                    BS_AUTOCHECKBOX | WS_TABSTOP,16,32,152,10

+    CONTROL         "Use window instead of balloons",15,"Button",

+                    BS_AUTOCHECKBOX | WS_TABSTOP,27,60,141,11

+    EDITTEXT        IDC_ALERT_TIME,137,101,61,12,ES_AUTOHSCROLL | ES_NUMBER,

+                    WS_EX_RIGHT

+    LTEXT           "Show alert for x seconds:",IDC_ALERT_TIME_TEXT,40,103,

+                    83,9

+    CONTROL         "Alert Hotkey",IDC_ALERT_HOTKEY,"msctls_hotkey32",

+                    WS_BORDER | WS_TABSTOP,137,74,61,13

+    LTEXT           "Close all alerts hotkey:",IDC_ALERT_HOTKEY_TEXT,39,75,

+                    76,10

+    CONTROL         "Leave alerts open indefinately",16,"Button",

+                    BS_AUTOCHECKBOX | WS_TABSTOP,27,88,115,11

+    CONTROL         "Blink Icon to alert me about events",18,"Button",

+                    BS_AUTOCHECKBOX | WS_TABSTOP,16,18,127,10

+END

+

+

+/////////////////////////////////////////////////////////////////////////////

+//

+// DESIGNINFO

+//

+

+#ifdef APSTUDIO_INVOKED

+GUIDELINES DESIGNINFO 

+BEGIN

+    IDD_EVENTS, DIALOG

+    BEGIN

+        BOTTOMMARGIN, 56

+    END

+

+    IDD_SETTINGS, DIALOG

+    BEGIN

+        BOTTOMMARGIN, 66

+    END

+

+    IDD_ALERT, DIALOG

+    BEGIN

+        RIGHTMARGIN, 150

+        BOTTOMMARGIN, 26

+    END

+

+    IDD_PREF, DIALOG

+    BEGIN

+        LEFTMARGIN, 7

+        RIGHTMARGIN, 232

+        TOPMARGIN, 7

+        BOTTOMMARGIN, 176

+    END

+

+    IDD_ABOUT, DIALOG

+    BEGIN

+        LEFTMARGIN, 7

+        RIGHTMARGIN, 209

+        TOPMARGIN, 7

+        BOTTOMMARGIN, 136

+    END

+

+    IDD_ALERTS, DIALOG

+    BEGIN

+        LEFTMARGIN, 7

+        RIGHTMARGIN, 208

+        TOPMARGIN, 7

+        BOTTOMMARGIN, 136

+    END

+END

+#endif    // APSTUDIO_INVOKED

+

+

+#ifdef APSTUDIO_INVOKED

+/////////////////////////////////////////////////////////////////////////////

+//

+// TEXTINCLUDE

+//

+

+1 TEXTINCLUDE 

+BEGIN

+    "resource.h\0"

+END

+

+2 TEXTINCLUDE 

+BEGIN

+    "#define APSTUDIO_HIDDEN_SYMBOLS\r\n"

+    "#include ""windows.h""\r\n"

+    "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n"

+    "\0"

+END

+

+3 TEXTINCLUDE 

+BEGIN

+    "xtray.h\0"

+END

+

+4 TEXTINCLUDE 

+BEGIN

+    "\r\n"

+    "\0"

+END

+

+#endif    // APSTUDIO_INVOKED

+

+

+/////////////////////////////////////////////////////////////////////////////

+//

+// Version

+//

+

+VS_VERSION_INFO VERSIONINFO

+ FILEVERSION 1,2,4,0

+ PRODUCTVERSION 1,2,4,0

+ FILEFLAGSMASK 0x3fL

+#ifdef _DEBUG

+ FILEFLAGS 0x1L

+#else

+ FILEFLAGS 0x0L

+#endif

+ FILEOS 0x40004L

+ FILETYPE 0x2L

+ FILESUBTYPE 0x0L

+BEGIN

+    BLOCK "StringFileInfo"

+    BEGIN

+        BLOCK "040904b0"

+        BEGIN

+            VALUE "CompanyName", "SinisterDevelopments"

+            VALUE "FileDescription", "X-Tray"

+            VALUE "FileVersion", "1, 2, 4, 0"

+            VALUE "InternalName", "X-Tray"

+            VALUE "LegalCopyright", "Copyright © 2005"

+            VALUE "OriginalFilename", "xtray.dll"

+            VALUE "ProductName", "X-Tray - XChat Win32 System Tray Plugin"

+            VALUE "ProductVersion", "1, 2, 4, 0"

+        END

+    END

+    BLOCK "VarFileInfo"

+    BEGIN

+        VALUE "Translation", 0x409, 1200

+    END

+END

+

+

+/////////////////////////////////////////////////////////////////////////////

+//

+// Menu

+//

+

+IDR_TRAY_MENU MENU 

+BEGIN

+    POPUP "TRAY"

+    BEGIN

+        MENUITEM "Restore",                     ACT_RESTORE

+        MENUITEM SEPARATOR

+        MENUITEM "Away",                        65535

+        MENUITEM "Settings",                    ACT_SETTINGS

+        MENUITEM SEPARATOR

+        MENUITEM "Exit",                        ACT_EXIT

+    END

+END

+

+

+/////////////////////////////////////////////////////////////////////////////

+//

+// Icon

+//

+

+// Icon with lowest ID value placed first to ensure application icon

+// remains consistent on all systems.

+ICO_XCHAT               ICON                    "icons\\xchat.ico"

+ICO_BANNED              ICON                    "icons\\banned.ico"

+ICO_CHANMSG             ICON                    "icons\\chan_msg.ico"

+ICO_HIGHLIGHT           ICON                    "icons\\highlight.ico"

+ICO_KICKED              ICON                    "icons\\kicked.ico"

+ICO_PMSG                ICON                    "icons\\priv_msg-1-2-2.ico"

+ICO_SNOTICE             ICON                    "icons\\server_notice.ico"

+ICO_DISCONNECTED        ICON                    "icons\\disconnected.ico"

+

+/////////////////////////////////////////////////////////////////////////////

+//

+// Bitmap

+//

+

+IDB_SD_LOGO             BITMAP                  "bitmaps\\sd.bmp"

+#endif    // English (U.S.) resources

+/////////////////////////////////////////////////////////////////////////////

+

+

+

+#ifndef APSTUDIO_INVOKED

+/////////////////////////////////////////////////////////////////////////////

+//

+// Generated from the TEXTINCLUDE 3 resource.

+//

+xtray.h

+/////////////////////////////////////////////////////////////////////////////

+#endif    // not APSTUDIO_INVOKED

+

diff --git a/plugins/xtray/sdAlerts.cpp b/plugins/xtray/sdAlerts.cpp
new file mode 100644
index 00000000..5e042806
--- /dev/null
+++ b/plugins/xtray/sdAlerts.cpp
@@ -0,0 +1,109 @@
+/* X-Tray

+ * Copyright (C) 2005 Michael Hotaling <Mike.Hotaling@SinisterDevelopments.com>

+ *

+ * X-Tray 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.

+ * 

+ * X-Tray 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 X-Tray; if not, write to the Free Software

+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

+ */

+

+#include <windows.h>

+#include <winuser.h>

+#include <stdio.h>

+#include "utility.h"

+#include "resource.h"

+#include "sdAlerts.h"

+

+int g_iAlerts = 0;

+

+void sdSystemAlert(HINSTANCE hModule, UINT uiDialog, char *szMsg, char *szName, unsigned int iTime)

+{

+	TCHAR wszMsg[256];

+	TCHAR wszName[64];

+

+	HWND hDialog;

+	RECT rcWorkArea, rcDlg;

+	int ixPos, iyPos;

+	int iNumPerCol;

+	

+	hDialog = CreateDialog(hModule, MAKEINTRESOURCE(uiDialog), NULL, (DLGPROC)sdAlertProc);

+

+	SystemParametersInfo(SPI_GETWORKAREA, 0, &rcWorkArea, 0);

+	GetWindowRect(hDialog, &rcDlg);

+

+	iNumPerCol = ((rcWorkArea.bottom - rcWorkArea.top) / (rcDlg.bottom - rcDlg.top));

+	ixPos = rcWorkArea.right - (rcDlg.right - rcDlg.left) + 1;

+	iyPos = rcWorkArea.bottom - (rcDlg.bottom - rcDlg.top);

+

+	if((g_iAlerts >= iNumPerCol) && (iNumPerCol > 0))

+	{

+		ixPos -= ((g_iAlerts / iNumPerCol) * (rcDlg.right - rcDlg.left));

+		iyPos -= ((g_iAlerts - (iNumPerCol * (g_iAlerts / iNumPerCol))) * (rcDlg.bottom - rcDlg.top));

+	}

+	else

+	{

+		iyPos -= (g_iAlerts * (rcDlg.bottom - rcDlg.top));

+	}

+	SetWindowPos(hDialog, HWND_TOPMOST, ixPos, iyPos, 0, 0, SWP_NOSIZE | SWP_NOACTIVATE);

+	

+	ConvertString(szName, wszName, 64);

+	ConvertString(szMsg, wszMsg, 256);

+

+	SetWindowText(hDialog, wszName);

+	SetDlgItemText(hDialog, IDC_ALERT_MSG, wszMsg);

+	ShowWindow(hDialog, SW_SHOWNA);

+

+	if(iTime > 0)

+	{

+		SetTimer(hDialog, 1, iTime, NULL);

+	}

+

+	g_iAlerts++;

+}

+

+void sdCloseAlerts()

+{

+	PostMessage(HWND_BROADCAST, RegisterWindowMessage(TEXT("xTray:CloseAllAlertWindows")), 0, 0);

+}

+

+LRESULT CALLBACK sdAlertProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)

+{

+	switch(msg)

+	{

+	case WM_CLOSE:

+		if(g_iAlerts > 0){ g_iAlerts--; }

+		DestroyWindow(hwnd);

+		return TRUE;

+		break;

+	case WM_TIMER:

+		if(g_iAlerts > 0){ g_iAlerts--; }

+		AnimateWindow(hwnd, 600, AW_SLIDE | AW_HIDE | AW_VER_POSITIVE);

+		DestroyWindow(hwnd);

+		return TRUE;

+		break;

+	default:

+		if(msg == RegisterWindowMessage(TEXT("xTray:CloseAllAlertWindows")))

+		{

+			if(g_iAlerts > 0){ g_iAlerts--; }

+			DestroyWindow(hwnd);

+			return TRUE;

+		}

+		break;

+	}

+

+	return FALSE;

+}

+

+int sdAlertNum()

+{

+	return g_iAlerts;

+}
\ No newline at end of file
diff --git a/plugins/xtray/sdAlerts.h b/plugins/xtray/sdAlerts.h
new file mode 100644
index 00000000..cd45a05b
--- /dev/null
+++ b/plugins/xtray/sdAlerts.h
@@ -0,0 +1,26 @@
+/* X-Tray

+ * Copyright (C) 2005 Michael Hotaling <Mike.Hotaling@SinisterDevelopments.com>

+ *

+ * X-Tray 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.

+ * 

+ * X-Tray 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 X-Tray; if not, write to the Free Software

+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

+ */

+

+#ifndef _H_SDALERTS_H

+#define _H_SDALERTS_H

+

+void				sdSystemAlert	(HINSTANCE, UINT, char *, char *, UINT);

+LRESULT CALLBACK	sdAlertProc		(HWND, UINT, WPARAM, LPARAM);

+int					sdAlertNum		();

+void				sdCloseAlerts	();

+#endif
\ No newline at end of file
diff --git a/plugins/xtray/sdTray.cpp b/plugins/xtray/sdTray.cpp
new file mode 100644
index 00000000..3a91a61b
--- /dev/null
+++ b/plugins/xtray/sdTray.cpp
@@ -0,0 +1,207 @@
+/* X-Tray

+ * Copyright (C) 2005 Michael Hotaling <Mike.Hotaling@SinisterDevelopments.com>

+ *

+ * X-Tray 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.

+ * 

+ * X-Tray 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 X-Tray; if not, write to the Free Software

+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

+ */

+#define _WIN32_IE 0x601

+#include <windows.h>

+#include <stdio.h>

+#include <tchar.h>

+#include "sdTray.h"

+#include "utility.h"

+

+HANDLE hThread;

+iBlink *tData	= NULL;

+

+int AddIcon(HWND hwnd, UINT id, HICON hicon, char *szTip, unsigned short flags, unsigned int cbMsg)

+{

+	NOTIFYICONDATA nidata;

+

+	nidata.cbSize			= NOTIFYICONDATA_V2_SIZE;

+	nidata.hIcon			= hicon;

+	nidata.hWnd				= hwnd;

+	nidata.uCallbackMessage = cbMsg;

+	nidata.uFlags			= flags;

+	nidata.uID				= id;

+

+	if(szTip != NULL)

+	{

+		TCHAR *szTemp = new TCHAR[64];

+

+		ConvertString(szTip, szTemp, 64);

+		_tcsncpy(nidata.szTip, szTemp, 64);

+

+		delete[] szTemp;

+	}

+

+	return Shell_NotifyIcon(NIM_ADD, &nidata);

+}

+

+int RemoveIcon(HWND hwnd, UINT id)

+{

+	if(hThread != NULL)

+	{

+		TerminateThread(hThread, 0);

+		hThread = NULL;

+

+		delete tData;

+	}

+

+	NOTIFYICONDATA nidata;

+

+	nidata.cbSize = NOTIFYICONDATA_V2_SIZE;

+	nidata.hWnd   = hwnd;

+	nidata.uID    = id;

+

+	return Shell_NotifyIcon(NIM_DELETE, &nidata);

+}

+

+int SetIcon(HWND hwnd, UINT id, HICON hicon)

+{

+	NOTIFYICONDATA nidata;

+

+	nidata.cbSize = NOTIFYICONDATA_V2_SIZE;

+	nidata.hWnd   = hwnd;

+	nidata.uID    = id;

+	nidata.hIcon  = hicon;

+	nidata.uFlags = NIF_ICON;

+

+	return Shell_NotifyIcon(NIM_MODIFY, &nidata);

+}

+

+int SetTooltip(HWND hwnd, UINT id, char *szTip)

+{

+	NOTIFYICONDATA nidata;

+

+	nidata.cbSize = NOTIFYICONDATA_V2_SIZE;

+	nidata.hWnd   = hwnd;

+	nidata.uID    = id;

+	nidata.uFlags = NIF_TIP;

+

+	if(szTip != NULL)

+	{

+		TCHAR *szTemp = new TCHAR[64];

+		ConvertString(szTip, szTemp, 64);

+		_tcsncpy(nidata.szTip, szTemp, 64);

+		delete[] szTemp;

+	}

+

+	return Shell_NotifyIcon(NIM_MODIFY, &nidata);

+}

+

+int ShowBalloon(HWND hwnd, UINT id, char *szInfo, char *szTitle, UINT time, UINT infoFlags)

+{

+	NOTIFYICONDATA nidata;

+

+	nidata.cbSize	= NOTIFYICONDATA_V2_SIZE;

+	nidata.hWnd		= hwnd;

+	nidata.uID		= id;

+	nidata.uFlags	= NIF_INFO;

+	nidata.dwInfoFlags = infoFlags;

+

+	if(time > 0)

+		nidata.uTimeout = time;

+	else

+		nidata.uTimeout = 500000;

+

+	if(szInfo != NULL)

+	{

+		TCHAR *szTemp = new TCHAR[255];

+

+		ConvertString(szInfo, szTemp, 251);

+		szTemp[250] = 0;

+		

+		if(strlen(szInfo) > 255)

+		{

+			_sntprintf(szTemp, 255, _T("%s..."), szTemp);

+		}

+		_tcsncpy(nidata.szInfo, szTemp, 255);

+

+		delete[] szTemp;

+	}

+	if(szTitle != NULL)

+	{

+		TCHAR *wszTitle = new TCHAR[64];

+		ConvertString(szTitle, wszTitle, 64);

+		_tcsncpy(nidata.szInfoTitle, wszTitle, 64);

+		delete[] wszTitle;

+	}

+

+	return Shell_NotifyIcon(NIM_MODIFY, &nidata);

+}

+

+

+DWORD WINAPI BlinkThread(LPVOID lpParam)

+{

+	NOTIFYICONDATA nidata;

+

+	nidata.cbSize = NOTIFYICONDATA_V2_SIZE;

+	nidata.hWnd   = tData->hwnd;

+	nidata.uID    = tData->id;

+	nidata.uFlags = NIF_ICON;

+

+	for(UINT i = 0; i < tData->num; i++)

+	{

+		nidata.hIcon = tData->hBlink;

+		Shell_NotifyIcon(NIM_MODIFY, &nidata);

+

+		Sleep(tData->time);

+

+		nidata.hIcon = tData->hBase;

+		Shell_NotifyIcon(NIM_MODIFY, &nidata);

+

+		Sleep(tData->time);

+	}

+

+	delete tData;

+	hThread = NULL;

+

+	return 0;

+}

+

+int BlinkIcon(HWND hwnd, UINT id, HICON hBase, HICON hBlink, UINT time, UINT num)

+{

+	if(hThread != NULL)

+	{

+		StopBlink(hwnd, id, hBase);

+	}

+

+	DWORD dwThreadID;

+	tData = new iBlink;

+

+	tData->hwnd		= hwnd;

+	tData->id		= id;

+	tData->hBase	= hBase;

+	tData->hBlink	= hBlink;

+	tData->time		= time;

+	tData->num		= num;

+

+	hThread = CreateThread(NULL, 0, BlinkThread, tData, 0, &dwThreadID);

+

+	return 0;

+}

+

+void StopBlink(HWND hwnd, UINT id, HICON hBase)

+{

+	if(hThread != NULL)

+	{

+		TerminateThread(hThread, 0);

+		hThread = NULL;

+

+		delete tData;

+	}

+

+	SetIcon(hwnd, id, hBase);

+}
\ No newline at end of file
diff --git a/plugins/xtray/sdTray.h b/plugins/xtray/sdTray.h
new file mode 100644
index 00000000..68469fe0
--- /dev/null
+++ b/plugins/xtray/sdTray.h
@@ -0,0 +1,39 @@
+/* X-Tray

+ * Copyright (C) 2005 Michael Hotaling <Mike.Hotaling@SinisterDevelopments.com>

+ *

+ * X-Tray 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.

+ * 

+ * X-Tray 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 X-Tray; if not, write to the Free Software

+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

+ */

+

+#ifndef _H_SDTRAY_H

+#define _H_SDTRAY_H

+

+int				AddIcon		(HWND, UINT, HICON, char *, unsigned short, UINT);

+int				ShowBalloon	(HWND, UINT, char *, char *, UINT, UINT);

+int				BlinkIcon	(HWND, UINT, HICON, HICON, UINT, UINT);

+int				SetTooltip	(HWND, UINT, char *);

+int				SetIcon		(HWND, UINT, HICON);

+void			StopBlink	(HWND, UINT, HICON);

+int				RemoveIcon	(HWND, UINT);

+

+typedef struct IBLINK

+{

+	HICON hBase;

+	HICON hBlink;

+	HWND hwnd;

+	UINT id;

+	UINT time;

+	UINT num;

+}iBlink;

+#endif
\ No newline at end of file
diff --git a/plugins/xtray/utility.cpp b/plugins/xtray/utility.cpp
new file mode 100644
index 00000000..60f3f2f0
--- /dev/null
+++ b/plugins/xtray/utility.cpp
@@ -0,0 +1,563 @@
+/* X-Tray

+ * Copyright (C) 2005 Michael Hotaling <Mike.Hotaling@SinisterDevelopments.com>

+ *

+ * X-Tray 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.

+ * 

+ * X-Tray 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 X-Tray; if not, write to the Free Software

+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

+ */

+

+#include <windows.h>

+#include <stdio.h>

+#include <commctrl.h>

+#include <tchar.h>

+#include "utility.h"

+#include "plugin.h"

+#include "xtray.h"

+#include "callbacks.h"

+#include "resource.h"

+

+TCHAR BACKUP_INI_FILE[] = _T(".\\plugins\\config\\xtray.conf");

+struct HOTKEY g_hHotKey;

+

+void SavePrefs(int iDlg)

+{

+	/**************************************************************************************************/

+	/********** allocate space for our string, and then set it to the currently logged on user ********/

+	/**************************************************************************************************/

+	DWORD dBuff = 257;

+	TCHAR szUser[257];

+

+	GetUserName(szUser, &dBuff);

+

+	/**************************************************************************************************/

+	/*********************** Test if the file exists, If it doesn't, Create It ************************/

+	/**************************************************************************************************/

+	TCHAR XTRAY_INI_FILE[1024];

+	

+#ifdef UNICODE

+	char temp[1024];

+    TCHAR TEMP_INI_FILE[1024];

+	

+	_snprintf(temp, 1024, "%s\\xtray.conf", xchat_get_info(ph, "xchatdir"));

+	ConvertString(temp, TEMP_INI_FILE, 1024);

+

+	// ok this one is really ugly

+	// it checks to see if the file exists in two locations

+	// X-Chat default config dir, if that fails it trys xchat\plugins\config

+	// if neither one exists it tries to create it in

+	// X-Chat default config dir, if that fails it trys xchat\plugins\config

+	// In either case it writes \xFF\xFE to the file ( on creation )

+	// so that we can save unicode away messages WritePrivateProfile doesn't 

+	// do this for us, though I think it really should

+

+	if(FileExists(TEMP_INI_FILE))

+	{

+		_tcscpy(XTRAY_INI_FILE, TEMP_INI_FILE);

+	}

+	else

+	{

+		if(FileExists(BACKUP_INI_FILE))

+		{

+			_tcscpy(XTRAY_INI_FILE, BACKUP_INI_FILE);

+		}

+		else

+		{

+			HANDLE xTemp;

+			DWORD dwBytesTemp;

+

+			if(xTemp = CreateFile(TEMP_INI_FILE, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL))

+			{

+				if(GetLastError() != ERROR_ALREADY_EXISTS)

+				{

+					WriteFile(xTemp, _T("\xFF\xFE"), 4, &dwBytesTemp, NULL);

+				}

+				CloseHandle(xTemp);

+			}

+

+			if(FileExists(TEMP_INI_FILE))

+			{

+				_tcscpy(XTRAY_INI_FILE, TEMP_INI_FILE);

+			}

+			else

+			{

+				HANDLE xBackup;

+				DWORD dwBytesBackup;

+

+				if(xBackup = CreateFile(TEMP_INI_FILE, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL))

+				{

+					if(GetLastError() != ERROR_ALREADY_EXISTS)

+					{

+						WriteFile(xBackup, _T("\xFF\xFE"), 4, &dwBytesBackup, NULL);

+					}

+

+					CloseHandle(xBackup);

+				}

+

+				if(FileExists(BACKUP_INI_FILE))

+				{

+					_tcscpy(XTRAY_INI_FILE, BACKUP_INI_FILE);

+				}

+			}

+		}

+	}

+

+#else

+	_tcscpy(XTRAY_INI_FILE, BACKUP_INI_FILE);

+#endif

+

+	WritePrivateProfileInt(szUser, _T("SETTINGS"),		g_dwPrefs,		XTRAY_INI_FILE);

+	WritePrivateProfileInt(szUser, _T("AOT"),			g_iTime,		XTRAY_INI_FILE);

+	WritePrivateProfileInt(szUser, _T("KEY"),			g_hHotKey.key,	XTRAY_INI_FILE);

+	WritePrivateProfileInt(szUser, _T("MOD"),			g_hHotKey.mod,	XTRAY_INI_FILE);

+	WritePrivateProfileString(szUser, _T("AWAY"),		g_szAway,		XTRAY_INI_FILE);

+}

+

+void LoadPrefs()

+{

+	/**************************************************************************************************/

+	/*********************** Our Settings Section *****************************************************/

+	/**************************************************************************************************/

+	DWORD dBuff = 257;

+	TCHAR szUser[257];

+

+	GetUserName(szUser, &dBuff);

+

+	/**************************************************************************************************/

+	/*********************** Test if the file exists, If it doesn't, Create It ************************/

+	/**************************************************************************************************/

+	TCHAR XTRAY_INI_FILE[1024];

+

+#ifdef UNICODE

+	char temp[1024];

+	TCHAR TEMP_INI_FILE[1024];

+

+	_snprintf(temp, 1024, "%s\\xtray.conf", xchat_get_info(ph, "xchatdir"));

+	ConvertString(temp, TEMP_INI_FILE, 1024);

+

+	if(FileExists(TEMP_INI_FILE))

+	{

+		_tcscpy(XTRAY_INI_FILE, TEMP_INI_FILE);

+	}

+	else

+	{

+		if(FileExists(BACKUP_INI_FILE))

+		{

+			_tcscpy(XTRAY_INI_FILE, BACKUP_INI_FILE);

+		}

+		else

+		{

+			HANDLE xTemp;

+			DWORD dwBytesTemp;

+

+			if(xTemp = CreateFile(TEMP_INI_FILE, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL))

+			{

+				if(GetLastError() != ERROR_ALREADY_EXISTS)

+				{

+					WriteFile(xTemp, _T("\xFF\xFE"), 4, &dwBytesTemp, NULL);

+				}

+

+				CloseHandle(xTemp);

+			}

+

+			if(FileExists(TEMP_INI_FILE))

+			{

+				_tcscpy(XTRAY_INI_FILE, TEMP_INI_FILE);

+			}

+			else

+			{

+				HANDLE xBackup;

+				DWORD dwBytesBackup;

+

+				if(xBackup = CreateFile(TEMP_INI_FILE, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL))

+				{

+					if(GetLastError() != ERROR_ALREADY_EXISTS)

+					{

+						WriteFile(xBackup, _T("\xFF\xFE"), 4, &dwBytesBackup, NULL);

+					}

+

+					CloseHandle(xBackup);

+				}

+

+				if(FileExists(BACKUP_INI_FILE))

+				{

+					_tcscpy(XTRAY_INI_FILE, BACKUP_INI_FILE);

+				}

+			}

+		}

+	}

+

+#else

+	_tcscpy(XTRAY_INI_FILE, BACKUP_INI_FILE);

+#endif

+

+	/**************************************************************************************************/

+	/*************************** Get the value for each of our preferances ****************************/

+	/**************************************************************************************************/

+	g_dwPrefs = GetPrivateProfileInt(szUser, _T("SETTINGS"),	0,  XTRAY_INI_FILE);

+

+	// backwards compatability

+	// also allows us to set defaults if its a new installation

+	// disable topic change, channel message and server notice by default

+	if(g_dwPrefs == 0)

+	{

+		g_dwPrefs	|= (GetPrivateProfileInt(szUser, _T("HILIGHT"),		1,  XTRAY_INI_FILE)<<1);

+		g_dwPrefs	|= (GetPrivateProfileInt(szUser, _T("INVITE"),		1,  XTRAY_INI_FILE)<<2);

+		/* g_dwPrefs	|= (GetPrivateProfileInt(szUser, _T("TOPIC"),		1,  XTRAY_INI_FILE)<<3); */

+		g_dwPrefs	|= (GetPrivateProfileInt(szUser, _T("BANNED"),		1,  XTRAY_INI_FILE)<<4);

+		g_dwPrefs	|= (GetPrivateProfileInt(szUser, _T("KICKED"),		1,  XTRAY_INI_FILE)<<5);

+		g_dwPrefs	|= (GetPrivateProfileInt(szUser, _T("CTCP"),		1,  XTRAY_INI_FILE)<<6);

+		g_dwPrefs	|= (GetPrivateProfileInt(szUser, _T("PMSG"),		1,  XTRAY_INI_FILE)<<7);

+		g_dwPrefs	|= (GetPrivateProfileInt(szUser, _T("KILLED"),		1,  XTRAY_INI_FILE)<<8);

+		/* g_dwPrefs	|= (GetPrivateProfileInt(szUser, _T("NOTICE"),		1,  XTRAY_INI_FILE)<<9); */

+		g_dwPrefs	|= (GetPrivateProfileInt(szUser, _T("DISCONNECT"),	1,  XTRAY_INI_FILE)<<10);

+

+		g_dwPrefs	|= (GetPrivateProfileInt(szUser, _T("AOM"),			0,  XTRAY_INI_FILE)<<11);

+		g_dwPrefs	|= (GetPrivateProfileInt(szUser, _T("TOT"),			1,  XTRAY_INI_FILE)<<12);

+		g_dwPrefs	|= (GetPrivateProfileInt(szUser, _T("AMAE"),		1,  XTRAY_INI_FILE)<<13);

+		g_dwPrefs	|= (GetPrivateProfileInt(szUser, _T("OSBWM"),		0,  XTRAY_INI_FILE)<<14);

+		g_dwPrefs	|= (GetPrivateProfileInt(szUser, _T("UWIOB"),		0,  XTRAY_INI_FILE)<<15);

+		g_dwPrefs	|= (GetPrivateProfileInt(szUser, _T("KAOI"),		0,  XTRAY_INI_FILE)<<16);

+		g_dwPrefs	|= (GetPrivateProfileInt(szUser, _T("MIOC"),		0,  XTRAY_INI_FILE)<<17);

+	}

+	

+	g_hHotKey.key	= GetPrivateProfileInt(szUser, _T("KEY"),	84, XTRAY_INI_FILE);

+	g_hHotKey.mod	= GetPrivateProfileInt(szUser, _T("MOD"),	(MOD_CONTROL | MOD_SHIFT),  XTRAY_INI_FILE);

+	g_iTime			= GetPrivateProfileInt(szUser, _T("AOT"),	5,  XTRAY_INI_FILE);

+

+	GetPrivateProfileString(szUser, _T("AWAY"), _T(""),	g_szAway, 1024, XTRAY_INI_FILE);

+	

+	/**************************************************************************************************/

+	/******************************** Register our hotkey with windows ********************************/

+	/**************************************************************************************************/

+	if(g_dwPrefs & (1<<PREF_UWIOB))

+	{

+		RegisterHotKey(g_hHotkeyWnd, 1, g_hHotKey.mod, g_hHotKey.key);

+	}

+}

+

+void CheckPrefs(HWND hwnd, int iDlg)

+{

+	/**************************************************************************************************/

+	/**************** save the preferances based on the checkmarks/options ****************************/

+	/**************************************************************************************************/

+	switch(iDlg)

+	{

+	case IDD_EVENTS:

+		{

+			SetOption(hwnd, CHAN_HILIGHT,		CHAN_HILIGHT);

+			SetOption(hwnd, CHAN_INVITE,		CHAN_INVITE);

+			SetOption(hwnd, CHAN_TOPIC_CHANGE,	CHAN_TOPIC_CHANGE);

+			SetOption(hwnd, CHAN_BANNED,		CHAN_BANNED);

+			SetOption(hwnd, CHAN_KICKED,		CHAN_KICKED);

+			SetOption(hwnd, CTCP_GENERIC,		CTCP_GENERIC);

+			SetOption(hwnd, PMSG_RECEIVE,		PMSG_RECEIVE);

+			SetOption(hwnd, SERV_KILLED,		SERV_KILLED);

+			SetOption(hwnd, SERV_NOTICE,		SERV_NOTICE);

+			SetOption(hwnd, SERV_DISCONNECT,	SERV_DISCONNECT);

+			SetOption(hwnd, CHAN_MESSAGE,		CHAN_MESSAGE);

+		}

+		break;

+	case IDD_ALERTS:

+		{

+			SetOption(hwnd, PREF_AMAE,	PREF_AMAE);

+			SetOption(hwnd, PREF_OSBWM,	PREF_OSBWM);

+			SetOption(hwnd, PREF_UWIOB,	PREF_UWIOB);

+			SetOption(hwnd, PREF_KAOI,	PREF_KAOI);

+			SetOption(hwnd, PREF_BLINK,	PREF_BLINK);

+

+			/**************************************************************************/

+			/**************************************************************************/

+			/**************************************************************************/

+			TCHAR tTime[512];

+

+			GetWindowText(GetDlgItem(hwnd, IDC_ALERT_TIME), tTime, 511);

+			

+			g_iTime = _tstoi(tTime);

+			

+			/**************************************************************************/

+			/**************** Get our Hotkey and save it                     **********/

+			/**************** then remove the old hotkey and add the new one **********/

+			/**************************************************************************/

+			DWORD hHotkey;

+			hHotkey = SendDlgItemMessage(hwnd, IDC_ALERT_HOTKEY, HKM_GETHOTKEY, 0, 0);

+			

+			g_hHotKey.key = LOBYTE(hHotkey);

+			g_hHotKey.mod = HIBYTE(hHotkey);

+			

+			if(IsDlgButtonChecked(hwnd, PREF_UWIOB) == BST_CHECKED)

+			{

+				UnregisterHotKey(g_hHotkeyWnd, 1);

+				RegisterHotKey(g_hHotkeyWnd, 1, g_hHotKey.mod, g_hHotKey.key);

+			}

+			else

+			{

+				UnregisterHotKey(g_hHotkeyWnd, 1);

+			}

+

+			/*************************************************************************/

+			/*********** Get and save the away msg and alert time ********************/

+			/*************************************************************************/

+		}

+		break;

+	case IDD_SETTINGS:

+		{

+			SetOption(hwnd, PREF_AOM, PREF_AOM);

+			SetOption(hwnd, PREF_TOT, PREF_TOT);

+			SetOption(hwnd, PREF_MIOC, PREF_MIOC);

+			SetOption(hwnd, PREF_DNSIT, PREF_DNSIT);

+

+			GetDlgItemText(hwnd, IDC_AWAY_MSG, g_szAway, 511);

+

+			if(g_dwPrefs & (1<<PREF_DNSIT))

+			{

+				DWORD dwStyle;

+				dwStyle = GetWindowLong(g_hXchatWnd, GWL_STYLE);

+				dwStyle |= (1<<WS_CHILD);

+				SetWindowLongPtr(g_hXchatWnd, GWL_STYLE, (LONG_PTR)dwStyle);

+				SetWindowLongPtr(g_hXchatWnd, GWL_HWNDPARENT, (LONG_PTR)g_hHotkeyWnd);

+			}

+			else

+			{

+				DWORD dwStyle;

+				dwStyle = GetWindowLong(g_hXchatWnd, GWL_STYLE);

+				dwStyle &= ~(1<<WS_CHILD);

+				SetWindowLongPtr(g_hXchatWnd, GWL_STYLE, (LONG_PTR)dwStyle);

+				SetWindowLongPtr(g_hXchatWnd, GWL_HWNDPARENT, NULL);

+			}

+		}

+		break;

+	} 

+}

+

+void SetDialog(HWND hwnd, int iDlg)

+{

+	switch(iDlg)

+	{

+	case IDD_EVENTS:

+		{

+			SetCheck(hwnd, CHAN_HILIGHT,		CHAN_HILIGHT);

+			SetCheck(hwnd, CHAN_INVITE,			CHAN_INVITE);

+			SetCheck(hwnd, CHAN_TOPIC_CHANGE,	CHAN_TOPIC_CHANGE);

+			SetCheck(hwnd, CHAN_BANNED,			CHAN_BANNED);

+			SetCheck(hwnd, CHAN_KICKED,			CHAN_KICKED);

+			SetCheck(hwnd, CTCP_GENERIC,		CTCP_GENERIC);

+			SetCheck(hwnd, PMSG_RECEIVE,		PMSG_RECEIVE);

+			SetCheck(hwnd, SERV_KILLED,			SERV_KILLED);

+			SetCheck(hwnd, SERV_NOTICE,			SERV_NOTICE);

+			SetCheck(hwnd, SERV_DISCONNECT,		SERV_DISCONNECT);

+			SetCheck(hwnd, CHAN_MESSAGE,		CHAN_MESSAGE);

+		}

+		break;

+	case IDD_SETTINGS:

+		{

+			SetCheck(hwnd, PREF_TOT,	PREF_TOT);

+			SetCheck(hwnd, PREF_MIOC,	PREF_MIOC);

+			SetCheck(hwnd, PREF_AOM,	PREF_AOM);

+			SetCheck(hwnd, PREF_DNSIT,	PREF_DNSIT);

+

+			SetDlgItemText(hwnd, IDC_AWAY_MSG, g_szAway);

+		}

+		break;

+	case IDD_ALERTS:

+		{

+			

+			SetCheck(hwnd, PREF_BLINK,	PREF_BLINK);

+			SetCheck(hwnd, PREF_OSBWM,	PREF_OSBWM);

+			SetCheck(hwnd, PREF_UWIOB,	PREF_UWIOB);

+			SetCheck(hwnd, PREF_KAOI,	PREF_KAOI);

+

+			/**********************************************************/

+			/**********************************************************/

+			/**********************************************************/

+			if(SetCheck(hwnd, PREF_AMAE, PREF_AMAE) == false)

+			{

+				SetToggle(hwnd, PREF_OSBWM,				PREF_AMAE, TRUE);

+				SetToggle(hwnd, PREF_UWIOB,				PREF_AMAE, TRUE);

+				SetToggle(hwnd, PREF_KAOI,				PREF_AMAE, TRUE);

+				SetToggle(hwnd, IDC_ALERT_TIME,			PREF_AMAE, TRUE);

+				SetToggle(hwnd, IDC_ALERT_TIME_TEXT,	PREF_AMAE, TRUE);

+				SetToggle(hwnd, IDC_ALERT_HOTKEY,		PREF_AMAE, TRUE);

+				SetToggle(hwnd, IDC_ALERT_HOTKEY_TEXT,	PREF_AMAE, TRUE);

+			}

+			else

+			{

+

+				SetToggle(hwnd, IDC_ALERT_HOTKEY,		PREF_UWIOB, TRUE);

+				SetToggle(hwnd, IDC_ALERT_HOTKEY_TEXT,	PREF_UWIOB, TRUE);

+				SetToggle(hwnd, IDC_ALERT_TIME,			PREF_KAOI, FALSE);

+				SetToggle(hwnd, IDC_ALERT_TIME_TEXT,	PREF_KAOI, FALSE);

+			}

+

+			/**********************************************************/

+			/**********************************************************/

+			/**********************************************************/

+			TCHAR tTime[255];

+			SendDlgItemMessage(hwnd, IDC_ALERT_TIME,	WM_SETTEXT, 0, (LPARAM)_itot(g_iTime, tTime, 10));

+			SendDlgItemMessage(hwnd, IDC_ALERT_HOTKEY,	HKM_SETHOTKEY, MAKEWORD(g_hHotKey.key, g_hHotKey.mod), 0);

+		}

+		break;

+	}

+}

+

+int SetCheck(HWND hDialog, unsigned int uiCheckBox, unsigned int uiPref)

+{

+	if((g_dwPrefs & (1<<uiPref)))

+	{

+		CheckDlgButton(hDialog, uiCheckBox, BST_CHECKED);

+		return 1;

+	}

+	else

+	{

+		CheckDlgButton(hDialog, uiCheckBox, BST_UNCHECKED);

+		return 0;

+	}

+

+	return 0;

+}

+

+int SetToggle(HWND hDialog, unsigned int uiCheckBox, unsigned int uiTestbox, bool offeqoff)

+{

+	/**************************************************************************************************/

+	/*********************** if(true) then if option is off turn toggle off ***************************/

+	/*********************** if(false) then if option is off turn toggle on ***************************/

+	/**************************************************************************************************/

+	if(offeqoff)

+	{

+		if(IsDlgButtonChecked(hDialog, uiTestbox) == BST_CHECKED)

+		{

+			EnableWindow(GetDlgItem(hDialog, uiCheckBox), TRUE);

+			return 1;

+		}

+		else

+		{

+			EnableWindow(GetDlgItem(hDialog, uiCheckBox), FALSE);

+			return 0;

+		}

+	}

+	else

+	{

+		if(IsDlgButtonChecked(hDialog, uiTestbox) == BST_CHECKED)

+		{

+			EnableWindow(GetDlgItem(hDialog, uiCheckBox), FALSE);

+			return 1;

+		}

+		else

+		{

+			EnableWindow(GetDlgItem(hDialog, uiCheckBox), TRUE);

+			return 0;

+		}

+	}

+

+	return 0;

+}

+

+int SetOption(HWND hDialog, unsigned int uiCheckBox, unsigned int uiPref)

+{

+	if(IsDlgButtonChecked(hDialog, uiCheckBox) == BST_CHECKED)

+	{

+		g_dwPrefs |= (1<<uiPref);

+	}

+	else

+	{

+		g_dwPrefs &= ~(1<<uiPref);

+	}

+

+	return (g_dwPrefs & (1<<uiPref));

+}

+

+int WritePrivateProfileIntA(char *szSection, char *szItem, int iData, char *szPath)

+{

+	char szData[33];

+	itoa(iData, szData, 10);

+	return WritePrivateProfileStringA(szSection, szItem, szData, szPath);

+}

+

+int WritePrivateProfileIntW(wchar_t *wszSection, wchar_t *wszItem, int iData, wchar_t *wszPath)

+{

+	wchar_t wszData[33];

+	_itow(iData, wszData, 10);

+	return WritePrivateProfileStringW(wszSection, wszItem, wszData, wszPath);

+}

+

+// For cleanup ( Closing windows and the such )

+void HoldClose()

+{

+	HANDLE hcThread;

+	DWORD dwThreadID;

+	hcThread = CreateThread(NULL, 0, HoldCloseThread, 0, 0, &dwThreadID);

+}

+

+DWORD WINAPI HoldCloseThread(LPVOID lpParam)

+{

+	Sleep(1000);

+	PostMessage(g_hXchatWnd, WM_CLOSE, 0, 0);

+	return 0;

+}

+

+bool FileExists(TCHAR *file)

+{

+	HANDLE hTemp = CreateFile(file, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

+	int nRet = GetLastError();

+	CloseHandle(hTemp);

+

+	if(nRet == 0)

+	{

+		return true;

+	}

+	else

+	{

+		return false;

+	}

+

+	return false;

+}

+

+void ConvertString(const char *in, wchar_t *out, int size)

+{

+	MultiByteToWideChar(CP_UTF8, 0, in,  -1, out, size);

+}

+

+void ConvertString(const wchar_t *in, char *out, int size)

+{

+	WideCharToMultiByte(CP_UTF8, 0, in, (size - 1), out, size, NULL, NULL);

+}

+

+void ConvertString(const char *in, char *out, int size)

+{

+	strncpy(out, in, size);

+}

+

+void ErrorDebug(LPTSTR lpszFunction)

+{ 

+    TCHAR szBuf[80]; 

+    LPVOID lpMsgBuf;

+    DWORD dw = GetLastError(); 

+

+    FormatMessage(

+        FORMAT_MESSAGE_ALLOCATE_BUFFER | 

+        FORMAT_MESSAGE_FROM_SYSTEM,

+        NULL,

+        dw,

+        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),

+        (LPTSTR) &lpMsgBuf,

+        0, NULL );

+

+    _stprintf(szBuf, 

+        _T("%s failed with error %d: %s"), 

+        lpszFunction, dw, lpMsgBuf); 

+ 

+    MessageBox(NULL, szBuf, _T("Error"), MB_OK); 

+

+    LocalFree(lpMsgBuf);

+}

+

diff --git a/plugins/xtray/utility.h b/plugins/xtray/utility.h
new file mode 100644
index 00000000..ce3d541c
--- /dev/null
+++ b/plugins/xtray/utility.h
@@ -0,0 +1,52 @@
+/* X-Tray

+ * Copyright (C) 2005 Michael Hotaling <Mike.Hotaling@SinisterDevelopments.com>

+ *

+ * X-Tray 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.

+ * 

+ * X-Tray 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 X-Tray; if not, write to the Free Software

+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

+ */

+

+#ifndef _H_UTILITY_H

+#define _H_UTILITY_H

+

+int						SetOption		(HWND, unsigned int, unsigned int);

+int						SetCheck		(HWND, unsigned int, unsigned int);

+int						SetToggle		(HWND, unsigned int, unsigned int, bool);

+void					ErrorDebug		(LPTSTR lpszFunction);

+void					SetDialog		(HWND, int);

+void					CheckPrefs		(HWND, int);

+bool					FileExists		(TCHAR *);

+DWORD WINAPI			HoldCloseThread	(LPVOID);

+void					SavePrefs		(int);

+void					LoadPrefs		();

+void					HoldClose		();

+

+void ConvertString(const char *in,		wchar_t *out,	int size);

+void ConvertString(const wchar_t *in,	char *out,		int size);

+void ConvertString(const char *in,		char *out,		int size);

+

+int WritePrivateProfileIntA(char *, char *, int, char *);

+int WritePrivateProfileIntW(wchar_t *, wchar_t *, int, wchar_t *);

+

+#ifdef UNICODE

+#define WritePrivateProfileInt WritePrivateProfileIntW

+#else

+#define WritePrivateProfileInt WritePrivateProfileIntA

+#endif

+

+struct HOTKEY

+{

+	WORD key;

+	WORD mod;

+};

+#endif
\ No newline at end of file
diff --git a/plugins/xtray/xchat.cpp b/plugins/xtray/xchat.cpp
new file mode 100644
index 00000000..581970f1
--- /dev/null
+++ b/plugins/xtray/xchat.cpp
@@ -0,0 +1,319 @@
+/* X-Tray

+ * Copyright (C) 1998, 2005 Peter Zelezny, Michael Hotaling <Mike.Hotaling@SinisterDevelopments.com>

+ *

+ * X-Tray 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.

+ * 

+ * X-Tray 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 X-Tray; if not, write to the Free Software

+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

+ */

+

+#include <windows.h>

+#include <vector>

+#include <algorithm>

+#include <stdio.h>

+#include <tchar.h>

+#include "plugin.h"

+#include "xtray.h"

+#include "resource.h"

+#include "xchat.h"

+#include "utility.h"

+

+// from util.c of xchat source code ( slightly modified to fit X-Tray Syntax )

+char *xchat_strip_color (char *text)

+{

+	int nc	= 0;

+	int i	= 0;

+	int col	= 0;

+	int len	= strlen(text);

+	char *new_str = (char *)malloc(len + 2);

+

+	while (len > 0)

+	{

+		if ((col && isdigit(*text) && (nc < 2)) || (col && isdigit(*(text+1)) && (nc < 3) && (*text == ',')))

+		{

+			nc++;

+

+			if(*text == ',')

+			{

+				nc = 0;

+			}

+		}

+		else

+		{

+			col = 0;

+

+			switch (*text)

+			{

+			case '\003':			  /*ATTR_COLOR: */

+				{

+					col = 1;

+					nc = 0;

+				}

+				break;

+			case '\007':			  /*ATTR_BEEP: */

+			case '\017':			  /*ATTR_RESET: */

+			case '\026':			  /*ATTR_REVERSE: */

+			case '\002':			  /*ATTR_BOLD: */

+			case '\037':			  /*ATTR_UNDERLINE: */

+				break;

+			default:

+				{

+					new_str[i] = *text;

+					i++;

+				}

+				break;

+			}

+		}

+

+		text++;

+		len--;

+	}

+

+	new_str[i] = 0;

+

+	return new_str;

+}

+

+void check_special_chars (char *cmd)

+{

+	int occur	= 0;

+	int len		= strlen (cmd);

+	int i = 0, j = 0;

+	char *buf;

+

+	if (!len)

+		return;

+

+	buf = (char *)malloc (len + 1);

+

+	if (buf)

+	{

+		while (cmd[j])

+		{

+			switch (cmd[j])

+			{

+			case '%':

+				{

+					occur++;

+

+					switch (cmd[j + 1])

+					{

+					case 'R':

+						buf[i] = '\026';

+						break;

+					case 'U':

+						buf[i] = '\037';

+						break;

+					case 'B':

+						buf[i] = '\002';

+						break;

+					case 'C':

+						buf[i] = '\003';

+						break;

+					case 'O':

+						buf[i] = '\017';

+						break;

+					case '%':

+						buf[i] = '%';

+						break;

+					default:

+						buf[i] = '%';

+						j--;

+						break;

+					}

+

+					j++;

+				}

+				break;

+			default:

+				{

+					buf[i] = cmd[j];

+				}

+				break;

+			}

+

+			j++;

+			i++;

+		}

+

+		buf[i] = 0;

+

+		if (occur)

+			strcpy (cmd, buf);

+

+		free (buf);

+	}

+}

+

+void xchat_globally_away(TCHAR *tszAway)

+{

+	char szTemp[512];

+	char szAway[512];

+

+	ConvertString(tszAway, szAway, 512);

+	_snprintf(szTemp, 512, "ALLSERV AWAY %s\0", szAway);

+	check_special_chars(szTemp);

+	xchat_exec(szTemp);

+}

+

+void xchat_away(TCHAR *tszAway)

+{

+	char szTemp[512];

+	char szAway[512];

+

+	ConvertString(tszAway, szAway, 512);

+	_snprintf(szTemp, 512, szAway);

+	check_special_chars(szTemp);

+	xchat_commandf(ph, "AWAY %s\0", szTemp);

+}

+

+void xchat_globally_back()

+{

+	std::vector<int> xs;

+	std::vector<int>::iterator xsi;

+	xchat_list *xl = xchat_list_get(ph, "channels");

+

+	if(xl)

+	{

+		while(xchat_list_next(ph, xl))

+		{

+			xsi = std::find(xs.begin(), xs.end(), xchat_list_int(ph, xl, "id"));

+

+			if((xsi == xs.end()) &&

+				((strlen(xchat_list_str(ph, xl, "server")) > 0) || 

+				(strlen(xchat_list_str(ph, xl, "channel")) > 0)))

+			{

+				xs.push_back(xchat_list_int(ph, xl, "id"));

+				xchat_set_context(ph, (xchat_context *)xchat_list_str(ph, xl, "context"));

+				xchat_back();

+			}

+		}

+

+		xchat_list_free(ph, xl);

+	}

+}

+

+

+

+void xchat_back()

+{

+	if(xchat_get_info(ph, "away"))

+	{

+		xchat_command(ph, "BACK");

+	}

+}

+

+HMENU setServerMenu()

+{

+	HMENU sTemp = CreateMenu();

+	TCHAR wszServer[128];

+	TCHAR wszNick[128];

+	TCHAR wszMenuEntry[256];

+

+	std::vector<int> xs;

+	std::vector<int>::iterator xsi;

+	xchat_list *xl = xchat_list_get(ph, "channels");

+

+	AppendMenu(sTemp, MF_STRING, ACT_AWAY, _T("Set Globally Away"));

+	AppendMenu(sTemp, MF_STRING, ACT_BACK, _T("Set Globally Back"));

+	AppendMenu(sTemp, MF_SEPARATOR, 0, NULL);

+

+	if(xl)

+	{

+		while(xchat_list_next(ph, xl))

+		{

+			xsi = std::find(xs.begin(), xs.end(), xchat_list_int(ph, xl, "id"));

+

+			if( (xsi == xs.end()) &&

+				((strlen(xchat_list_str(ph, xl, "server")) > 0) || 

+				(strlen(xchat_list_str(ph, xl, "channel")) > 0)))

+			{

+				xchat_set_context(ph, (xchat_context *)xchat_list_str(ph, xl, "context"));

+				xs.push_back(xchat_list_int(ph, xl, "id"));

+

+				char *network	= _strdup(xchat_list_str(ph, xl, "network"));

+				char *server	= _strdup(xchat_list_str(ph, xl, "server"));

+				char *nick		= _strdup(xchat_get_info(ph, "nick"));

+

+				if(network != NULL)

+				{

+					ConvertString(network, wszServer, 128);

+				}

+				else

+				{

+					ConvertString(server, wszServer, 128);

+				}

+

+				if(server != NULL)

+				{

+					ConvertString(nick, wszNick, 128);

+					_sntprintf(wszMenuEntry, 256, _T("%s @ %s\0"), wszNick, wszServer);

+

+					if(!xchat_get_info(ph, "away"))

+					{

+						AppendMenu(sTemp, MF_STRING, (xchat_list_int(ph, xl, "id") + 1), wszMenuEntry);

+					}

+					else

+					{

+						AppendMenu(sTemp, (MF_CHECKED | MF_STRING), (xchat_list_int(ph, xl, "id") + 1), wszMenuEntry);							

+					}

+				}

+

+				free(network);

+				free(server);

+				free(nick);

+			}

+		}

+

+		xchat_list_free(ph, xl);

+	}

+

+	return sTemp;

+}

+

+struct _xchat_context *xchat_find_server(int find_id)

+{

+	xchat_context *xc;

+	xchat_list *xl = xchat_list_get(ph, "channels");

+	int id;

+

+	if(!xl)

+		return NULL;

+

+	while(xchat_list_next(ph, xl))

+	{

+		id = xchat_list_int(ph, xl, "id");

+		

+		if(id == -1)

+		{

+			return NULL;

+		}

+		else if(id == find_id)

+		{

+			xc = (xchat_context *)xchat_list_str(ph, xl, "context");

+			

+			xchat_list_free(ph, xl);

+

+			return xc;

+		}

+	}

+

+	xchat_list_free(ph, xl);

+

+	return NULL;

+}

+

+void xchat_exec(char *command)

+{

+	xchat_set_context(ph, xchat_find_context(ph, NULL, NULL));

+	xchat_command(ph, command);

+}
\ No newline at end of file
diff --git a/plugins/xtray/xchat.h b/plugins/xtray/xchat.h
new file mode 100644
index 00000000..76452aeb
--- /dev/null
+++ b/plugins/xtray/xchat.h
@@ -0,0 +1,32 @@
+/* X-Tray

+ * Copyright (C) 2005 Michael Hotaling <Mike.Hotaling@SinisterDevelopments.com>

+ *

+ * X-Tray 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.

+ * 

+ * X-Tray 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 X-Tray; if not, write to the Free Software

+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

+ */

+

+#ifndef _H_XCHAT_H

+#define _H_XCHAT_H

+

+void					xchat_exec			(char *);

+char					*xchat_strip_color	(char *);

+void					xchat_parse			(char *);

+struct _xchat_context	*xchat_find_server	(int);

+void					xchat_globally_away	(TCHAR *);

+void					xchat_away			(TCHAR *);

+void					xchat_globally_back	();

+void					xchat_back			();

+HMENU					setServerMenu		();

+

+#endif
\ No newline at end of file
diff --git a/plugins/xtray/xtray.cpp b/plugins/xtray/xtray.cpp
new file mode 100644
index 00000000..a7c8c8bd
--- /dev/null
+++ b/plugins/xtray/xtray.cpp
@@ -0,0 +1,219 @@
+/* X-Tray

+ * Copyright (C) 2005 Michael Hotaling <Mike.Hotaling@SinisterDevelopments.com>

+ *

+ * X-Tray 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.

+ * 

+ * X-Tray 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 X-Tray; if not, write to the Free Software

+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

+ */

+

+#define _WIN32_IE 0x0601

+

+#include <windows.h>

+#include <list>

+#include <string>

+#include <shobjidl.h>

+#include "resource.h"

+#include "callbacks.h"

+#include "plugin.h"

+#include "utility.h"

+#include "xtray.h"

+#include "sdTray.h"

+#include "sdAlerts.h"

+#include "plugin.h"

+

+/*****************************************************/

+/**** Don't want to pollute the namespace do we? *****/

+/*****************************************************/

+std::list<xchat_hook *> g_vHooks;

+

+/*****************************************************/

+/************ Global Identifiers *********************/

+/*****************************************************/

+WNDPROC g_hOldProc;

+xchat_plugin *ph;

+

+/*****************************************************/

+/***************** Resources *************************/

+/*****************************************************/

+HWND	g_hXchatWnd;

+HWND	g_hHotkeyWnd;

+HWND	g_hPrefDlg;

+HMENU	g_hTrayMenu;

+HICON	g_hIcons[11];

+HANDLE	g_hInstance;

+/*****************************************************/

+/***************** Preferences ***********************/

+/*****************************************************/

+unsigned int g_dwPrefs;

+TCHAR	g_szAway[512];

+int		g_iTime;

+

+

+BOOL WINAPI DllMain(HANDLE hModule, DWORD fdwReason, LPVOID lpVoid)

+{

+	if((fdwReason == DLL_PROCESS_ATTACH) || (fdwReason == DLL_THREAD_ATTACH))

+	{

+		g_hInstance = hModule;

+	}

+

+	return TRUE;

+}

+

+int xchat_plugin_init(xchat_plugin *plugin_handle, char **plugin_name, char **plugin_desc, char **plugin_version, char *arg)

+{

+	ph = plugin_handle;

+

+	*plugin_name	= "X-Tray";

+	*plugin_desc	= "Minimize XChat to the Windows system tray";

+	*plugin_version = "1.2.4";

+

+	/***************************************************************************************************************************/

+	/************************* Load our preferances from xTray.ini *************************************************************/

+	/***************************************************************************************************************************/

+	LoadPrefs();

+

+	/***************************************************************************************************************************/

+	/************************* Finds the xChat window and saves it for later use ***********************************************/

+	/***************************************************************************************************************************/

+	g_hXchatWnd = (HWND)xchat_get_info(ph, "win_ptr");

+

+	if(g_hXchatWnd == NULL)

+	{

+		EnumThreadWindows(GetCurrentThreadId(), EnumWindowsProc, 0);

+	}

+

+	g_hOldProc	= (WNDPROC)GetWindowLongPtr(g_hXchatWnd, GWLP_WNDPROC);

+	SetWindowLongPtr(g_hXchatWnd, GWLP_WNDPROC, (LONG_PTR)WindowProc);

+

+	/***************************************************************************************************************************/	

+	/************************* Grab the xChat Icon, Load our menu, create the window to receive the hotkey messages  ***********/

+	/************************* and register the windows message so we know if explorer crashes                       ***********/

+	/***************************************************************************************************************************/

+	g_hTrayMenu		= GetSubMenu(LoadMenu((HINSTANCE)g_hInstance, MAKEINTRESOURCE(IDR_TRAY_MENU)), 0);

+	g_hHotkeyWnd	= CreateDialog((HINSTANCE)g_hInstance, MAKEINTRESOURCE(IDD_ALERT), NULL,		(DLGPROC)HotKeyProc);

+	g_hPrefDlg		= CreateDialog((HINSTANCE)g_hInstance, MAKEINTRESOURCE(IDD_PREF),  g_hXchatWnd, (DLGPROC)PrefProc);

+

+	g_hIcons[0]	= (HICON)LoadImage((HINSTANCE)g_hInstance, MAKEINTRESOURCE(ICO_XCHAT),			IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);

+	g_hIcons[1]	= (HICON)LoadImage((HINSTANCE)g_hInstance, MAKEINTRESOURCE(ICO_CHANMSG),		IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);

+	g_hIcons[2]	= (HICON)LoadImage((HINSTANCE)g_hInstance, MAKEINTRESOURCE(ICO_HIGHLIGHT),		IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);

+	g_hIcons[5]	= (HICON)LoadImage((HINSTANCE)g_hInstance, MAKEINTRESOURCE(ICO_BANNED),			IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);

+	g_hIcons[6]	= (HICON)LoadImage((HINSTANCE)g_hInstance, MAKEINTRESOURCE(ICO_KICKED),			IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);

+	g_hIcons[8]	= (HICON)LoadImage((HINSTANCE)g_hInstance, MAKEINTRESOURCE(ICO_PMSG),			IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);

+	g_hIcons[10]= (HICON)LoadImage((HINSTANCE)g_hInstance, MAKEINTRESOURCE(ICO_SNOTICE),		IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);

+	g_hIcons[11]= (HICON)LoadImage((HINSTANCE)g_hInstance, MAKEINTRESOURCE(ICO_DISCONNECTED),	IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);

+

+	/***************************************************************************************************************************/

+	/************************* Add our icon to the tray ************************************************************************/

+	/***************************************************************************************************************************/

+	char szVersion[64];

+	_snprintf(szVersion, 64, "XChat-WDK [%s]", xchat_get_info(ph, "version"));

+	AddIcon(g_hXchatWnd, 1, g_hIcons[0], szVersion, (NIF_ICON | NIF_MESSAGE | NIF_TIP), WM_TRAYMSG);

+

+	/***************************************************************************************************************************/

+	/***************************************************************************************************************************/

+	/***************************************************************************************************************************/

+	if(g_dwPrefs & (1<<PREF_DNSIT))

+	{

+		DWORD dwStyle;

+		dwStyle = GetWindowLong(g_hXchatWnd, GWL_STYLE);

+		dwStyle |= (1<<WS_CHILD);

+		SetWindowLongPtr(g_hXchatWnd, GWL_STYLE, (LONG_PTR)dwStyle);

+		SetWindowLongPtr(g_hXchatWnd, GWL_HWNDPARENT, (LONG_PTR)g_hHotkeyWnd);

+	}

+

+	/***************************************************************************************************************************/

+	/************************* Set our hooks and save them for later so we can unhook them *************************************/

+	/***************************************************************************************************************************/

+	g_vHooks.push_back(xchat_hook_print(ph, "Channel Msg Hilight",			XCHAT_PRI_NORM, event_cb,	(void *)CHAN_HILIGHT));

+	g_vHooks.push_back(xchat_hook_print(ph, "Channel Message",				XCHAT_PRI_NORM, event_cb,	(void *)CHAN_MESSAGE));

+	g_vHooks.push_back(xchat_hook_print(ph, "Topic Change",					XCHAT_PRI_NORM, event_cb,	(void *)CHAN_TOPIC_CHANGE));

+	g_vHooks.push_back(xchat_hook_print(ph, "Channel Action Hilight",		XCHAT_PRI_NORM, event_cb,	(void *)CHAN_HILIGHT));

+	g_vHooks.push_back(xchat_hook_print(ph, "Channel INVITE",				XCHAT_PRI_NORM, event_cb,	(void *)CHAN_INVITE));

+	g_vHooks.push_back(xchat_hook_print(ph, "You Kicked",					XCHAT_PRI_NORM, event_cb,	(void *)CHAN_KICKED));

+	g_vHooks.push_back(xchat_hook_print(ph, "Banned",						XCHAT_PRI_NORM, event_cb,	(void *)CHAN_BANNED));

+	g_vHooks.push_back(xchat_hook_print(ph, "CTCP Generic",					XCHAT_PRI_NORM, event_cb,	(void *)CTCP_GENERIC));

+	g_vHooks.push_back(xchat_hook_print(ph, "Private Message",				XCHAT_PRI_NORM, event_cb,	(void *)PMSG_RECEIVE));

+	g_vHooks.push_back(xchat_hook_print(ph, "Private Message to Dialog",	XCHAT_PRI_NORM, event_cb,	(void *)PMSG_RECEIVE));

+	g_vHooks.push_back(xchat_hook_print(ph, "Disconnected",					XCHAT_PRI_NORM, event_cb,	(void *)SERV_DISCONNECT));

+	g_vHooks.push_back(xchat_hook_print(ph, "Killed",						XCHAT_PRI_NORM, event_cb,	(void *)SERV_KILLED));

+	g_vHooks.push_back(xchat_hook_print(ph, "Notice",						XCHAT_PRI_NORM, event_cb,	(void *)SERV_NOTICE));

+	g_vHooks.push_back(xchat_hook_command(ph, "tray_alert",					XCHAT_PRI_NORM, command_cb,	"Create an Alert", NULL));

+

+	return 1;

+}

+

+int xchat_plugin_deinit(xchat_plugin *plugin_handle)

+{

+	/******************************************/

+	/****** Remove the Icon from the tray *****/

+	/******************************************/

+	StopBlink(g_hXchatWnd, 1, g_hIcons[0]);

+	RemoveIcon(g_hXchatWnd, 1);

+	

+	/*******************************************/

+	/*******************************************/

+	/*******************************************/

+	if(g_dwPrefs & (1<<PREF_DNSIT))

+	{

+		DWORD dwStyle;

+		dwStyle = GetWindowLong(g_hXchatWnd, GWL_STYLE);

+		dwStyle &= ~(1<<WS_CHILD);

+		SetWindowLongPtr(g_hXchatWnd, GWL_STYLE, (LONG_PTR)dwStyle);

+		SetWindowLongPtr(g_hXchatWnd, GWL_HWNDPARENT, NULL);

+	}

+

+	/******************************************/

+	/****** Unload our resources **************/

+	/******************************************/

+	DestroyMenu(g_hTrayMenu);

+

+	for(int i = 0; i <= 11; i++)

+	{

+		DestroyIcon(g_hIcons[i]);

+	}

+

+	/******************************************/

+	/****** Remove our window hook ************/

+	/******************************************/

+	SetWindowLongPtr(g_hXchatWnd, GWLP_WNDPROC, (LONG_PTR)g_hOldProc);

+

+	/******************************************/

+	/****** Remove our hotkey, and destroy ****/

+	/****** the window that receives its   ****/

+	/****** messages                       ****/

+	/******************************************/

+	UnregisterHotKey(g_hHotkeyWnd, 1);

+	DestroyWindow(g_hHotkeyWnd);

+	DestroyWindow(g_hPrefDlg);

+

+	/******************************************/

+	/************* Clean up Isle 7 ************/

+	/******************************************/

+	if(sdAlertNum())

+	{

+		sdCloseAlerts();

+	}

+	/******************************************/

+	/****** remove our xchat_hook_*s **********/

+	/******************************************/

+	while(!g_vHooks.empty())

+	{

+		if(g_vHooks.back() != NULL)

+		{

+			xchat_unhook(ph, g_vHooks.back());

+		}

+		g_vHooks.pop_back();

+	}

+

+	return 1;

+}

diff --git a/plugins/xtray/xtray.h b/plugins/xtray/xtray.h
new file mode 100644
index 00000000..56323cf2
--- /dev/null
+++ b/plugins/xtray/xtray.h
@@ -0,0 +1,77 @@
+/* X-Tray

+ * Copyright (C) 2005 Michael Hotaling <Mike.Hotaling@SinisterDevelopments.com>

+ *

+ * X-Tray 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.

+ * 

+ * X-Tray 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 X-Tray; if not, write to the Free Software

+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

+ */

+

+#ifndef _XTRAY_H

+#define _XTRAY_H

+

+/******************** Globals *************************/

+extern HWND				g_hXchatWnd;

+extern HWND				g_hHotkeyWnd;

+extern HWND				g_hPrefDlg;

+extern HMENU			g_hTrayMenu;

+extern HICON			g_hIcons[11];

+extern HANDLE			g_hInstance;

+extern unsigned int		g_dwPrefs;

+extern TCHAR			g_szAway[512];

+extern int				g_iTime;

+extern WNDPROC			g_hOldProc;

+extern struct _xchat_plugin *ph;

+/******************************************************/

+

+/******************** Messages ************************/

+#define WM_TRAYMSG WM_APP

+/******************************************************/

+

+/********************* Events *************************/

+#define CHAN_HILIGHT			1

+#define CHAN_INVITE				2

+#define CHAN_TOPIC_CHANGE		3

+#define CHAN_BANNED				4

+#define CHAN_KICKED				5

+

+#define CTCP_GENERIC			6

+#define PMSG_RECEIVE			7

+

+#define SERV_KILLED				8

+#define SERV_NOTICE				9

+#define SERV_DISCONNECT			10

+

+/* new events */

+#define CHAN_MESSAGE			21

+

+#define PREF_AOM				11 // away on minimize

+#define PREF_TOT				12 // Tray on Taskbar

+#define PREF_AMAE				13 // alert me about events

+#define PREF_OSBWM				14 // Only Show Balloon When Minimized

+#define PREF_UWIOB				15 // Use Window Instead of Balloon

+#define PREF_KAOI				16 // Keep alerts open indefinately

+#define PREF_MIOC				17 // Minimize instead of close

+#define PREF_BLINK				18 // blink icon

+#define PREF_CICO				19 // change icon - not implemented

+#define PREF_DNSIT				20 // Do not show in taskbar

+/******************************************************/

+#endif

+

+#ifdef _WIN64

+/* use replacement with the same value, and use SetWindowLongPtr instead

+   of SetWindowLong. more info:

+

+   http://msdn.microsoft.com/en-us/library/ms633591.aspx

+   http://msdn.microsoft.com/en-us/library/ms644898.aspx */

+#define GWL_HWNDPARENT GWLP_HWNDPARENT

+#endif