summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common/cfgfiles.c37
-rw-r--r--src/common/chanopt.c1
-rw-r--r--src/common/ctcp.c5
-rw-r--r--src/common/dcc.c6
-rw-r--r--src/common/dirent.c199
-rw-r--r--src/common/dirent.h28
-rw-r--r--src/common/ignore.c1
-rw-r--r--src/common/inbound.c1
-rw-r--r--src/common/inet.h3
-rw-r--r--src/common/makefile.mak45
-rw-r--r--src/common/msproxy.c1
-rw-r--r--src/common/network.c1
-rw-r--r--src/common/notify.c1
-rw-r--r--src/common/outbound.c1
-rw-r--r--src/common/plugin-timer.c2
-rw-r--r--src/common/plugin.c7
-rw-r--r--src/common/proto-irc.c1
-rw-r--r--src/common/server.c37
-rw-r--r--src/common/servlist.c1
-rw-r--r--src/common/ssl.c2
-rw-r--r--src/common/text.c33
-rw-r--r--src/common/thread.c33
-rw-r--r--src/common/thread.h10
-rw-r--r--src/common/util.c126
-rw-r--r--src/common/util.h6
-rw-r--r--src/common/wdkutil.c27
-rw-r--r--src/common/wdkutil.h2
-rw-r--r--src/common/xchat.c4
-rw-r--r--src/common/xchat.h12
-rw-r--r--src/fe-gtk/about.c46
-rw-r--r--src/fe-gtk/banlist.c1
-rw-r--r--src/fe-gtk/chanlist.c1
-rw-r--r--src/fe-gtk/chanview-tabs.c8
-rw-r--r--src/fe-gtk/editlist.c1
-rw-r--r--src/fe-gtk/fe-gtk.c87
-rw-r--r--src/fe-gtk/fe-gtk.h2
-rw-r--r--src/fe-gtk/fkeys.c1
-rw-r--r--src/fe-gtk/gtkutil.c248
-rw-r--r--src/fe-gtk/joind.c1
-rw-r--r--src/fe-gtk/maingui.c67
-rw-r--r--src/fe-gtk/makefile.mak60
-rw-r--r--src/fe-gtk/menu.c12
-rw-r--r--src/fe-gtk/palette.c1
-rw-r--r--src/fe-gtk/plugin-tray.c48
-rw-r--r--src/fe-gtk/plugingui.c6
-rw-r--r--src/fe-gtk/rawlog.c1
-rw-r--r--src/fe-gtk/search.c2
-rw-r--r--src/fe-gtk/setup.c54
-rw-r--r--src/fe-gtk/sexy-spell-entry.c8
-rw-r--r--src/fe-gtk/typedef.h11
-rw-r--r--src/fe-gtk/xchat.rc22
-rw-r--r--src/fe-gtk/xtext.c35
-rw-r--r--src/fe-gtk/xtext.h1
-rw-r--r--src/fe-text/fe-text.c473
-rw-r--r--src/fe-text/fe-text.h30
-rw-r--r--src/fe-text/makefile.mak20
-rw-r--r--src/makefile.mak17
-rw-r--r--src/makeinc.skel.mak48
-rw-r--r--src/pixmaps/makefile.mak18
59 files changed, 1449 insertions, 514 deletions
diff --git a/src/common/cfgfiles.c b/src/common/cfgfiles.c
index 8bb2a61b..d26198ed 100644
--- a/src/common/cfgfiles.c
+++ b/src/common/cfgfiles.c
@@ -17,7 +17,6 @@
  */
 
 #include <fcntl.h>
-#include <unistd.h>
 #include <stdlib.h>
 #include <string.h>
 #include <stdio.h>
@@ -30,10 +29,9 @@
 #include "fe.h"
 #include "text.h"
 #include "xchatc.h"
+#include "wdkutil.h"
 
-#ifdef WIN32
-#define XCHAT_DIR "X-Chat 2"
-#else
+#ifndef WIN32
 #define XCHAT_DIR ".xchat2"
 #endif
 #define DEF_FONT "Monospace 9"
@@ -308,12 +306,19 @@ get_xdir_fs (void)
 {
 	if (!xdir_fs)
 	{
-		char out[256];
+		if (portable_mode ())
+		{
+			xdir_fs = ".\\config";
+		}
+		else
+		{
+			char out[256];
 
-		if (!get_reg_str ("Software\\Microsoft\\Windows\\CurrentVersion\\"
-				"Explorer\\Shell Folders", "AppData", out, sizeof (out)))
-			return "./config";
-		xdir_fs = g_strdup_printf ("%s\\" XCHAT_DIR, out);
+			if (!get_reg_str ("Software\\Microsoft\\Windows\\CurrentVersion\\"
+					"Explorer\\Shell Folders", "AppData", out, sizeof (out)))
+				return "./config";
+			xdir_fs = g_strdup_printf ("%s\\" "X-Chat 2", out);
+		}
 	}
 	return xdir_fs;
 }
@@ -393,7 +398,7 @@ const struct prefs vars[] = {
 	{"dcc_blocksize", P_OFFINT (dcc_blocksize), TYPE_INT},
 	{"dcc_completed_dir", P_OFFSET (dcc_completed_dir), TYPE_STR},
 	{"dcc_dir", P_OFFSET (dccdir), TYPE_STR},
-	{"dcc_fast_send", P_OFFINT (fastdccsend), TYPE_BOOL},
+	/* {"dcc_fast_send", P_OFFINT (fastdccsend), TYPE_BOOL}, */
 	{"dcc_global_max_get_cps", P_OFFINT (dcc_global_max_get_cps), TYPE_INT},
 	{"dcc_global_max_send_cps", P_OFFINT (dcc_global_max_send_cps), TYPE_INT},
 	{"dcc_ip", P_OFFSET (dcc_ip_str), TYPE_STR},
@@ -536,6 +541,7 @@ const struct prefs vars[] = {
 
 	{"tab_chans", P_OFFINT (tabchannels), TYPE_BOOL},
 	{"tab_dialogs", P_OFFINT (privmsgtab), TYPE_BOOL},
+	{"tab_icons", P_OFFINT (tab_icons), TYPE_BOOL},
 	{"tab_layout", P_OFFINT (tab_layout), TYPE_INT},
 	{"tab_new_to_front", P_OFFINT (newtabstofront), TYPE_INT},
 	{"tab_notices", P_OFFINT (notices_tabs), TYPE_BOOL},
@@ -546,9 +552,14 @@ const struct prefs vars[] = {
 	{"tab_sort", P_OFFINT (tab_sort), TYPE_BOOL},
 	{"tab_trunc", P_OFFINT (truncchans), TYPE_INT},
 	{"tab_utils", P_OFFINT (windows_as_tabs), TYPE_BOOL},
+	{"tab_xp", P_OFFINT (tab_xp), TYPE_BOOL},
 
+	{"text_auto_copy_text", P_OFFINT (autocopy_text), TYPE_BOOL},
+	{"text_auto_copy_stamp", P_OFFINT (autocopy_stamp), TYPE_BOOL},
+	{"text_auto_copy_color", P_OFFINT (autocopy_color), TYPE_BOOL},
 	{"text_background", P_OFFSET (background), TYPE_STR},
 	{"text_color_nicks", P_OFFINT (colorednicks), TYPE_BOOL},
+	{"text_emoticons", P_OFFINT (emoticons), TYPE_BOOL},
 	{"text_font", P_OFFSET (font_normal), TYPE_STR},
 	{"text_indent", P_OFFINT (indent_nicks), TYPE_BOOL},
 	{"text_max_indent", P_OFFINT (max_auto_indent), TYPE_INT},
@@ -561,7 +572,7 @@ const struct prefs vars[] = {
 	{"text_tint_blue", P_OFFINT (tint_blue), TYPE_INT},
 	{"text_tint_green", P_OFFINT (tint_green), TYPE_INT},
 	{"text_tint_red", P_OFFINT (tint_red), TYPE_INT},
-	{"text_transparent", P_OFFINT (transparent), TYPE_BOOL},
+	/* {"text_transparent", P_OFFINT (transparent), TYPE_BOOL}, */
 	{"text_wordwrap", P_OFFINT (wordwrap), TYPE_BOOL},
 
 	{0, 0, 0},
@@ -624,13 +635,14 @@ load_config (void)
 	prefs.indent_nicks = 1;
 	prefs.thin_separator = 1;
 	prefs._tabs_position = 2; /* 2 = left */
-	prefs.fastdccsend = 1;
+	/* prefs.fastdccsend = 1; */
 	prefs.wordwrap = 1;
 	prefs.autosave = 1;
 	prefs.autodialog = 1;
 	prefs.gui_input_spell = 1;
 	prefs.autoreconnect = 1;
 	prefs.recon_delay = 10;
+	prefs.autocopy_text = 1;
 	prefs.text_replay = 1;
 	prefs.tabchannels = 1;
 	prefs.tab_layout = 2;	/* 0=Tabs 1=Reserved 2=Tree */
@@ -648,6 +660,7 @@ load_config (void)
 	prefs.dialog_height = 256;
 	prefs.gui_join_dialog = 1;
 	prefs.gui_quit_dialog = 1;
+	prefs.slist_skip = 1;
 	prefs.dcctimeout = 180;
 	prefs.dccstalltimeout = 60;
 	prefs.notify_timeout = 15;
diff --git a/src/common/chanopt.c b/src/common/chanopt.c
index a4fd8faa..ce37157a 100644
--- a/src/common/chanopt.c
+++ b/src/common/chanopt.c
@@ -3,7 +3,6 @@
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
-#include <unistd.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
diff --git a/src/common/ctcp.c b/src/common/ctcp.c
index 574cda79..37392372 100644
--- a/src/common/ctcp.c
+++ b/src/common/ctcp.c
@@ -18,7 +18,6 @@
 
 #include <stdio.h>
 #include <string.h>
-#include <unistd.h>
 #include <stdlib.h>
 
 #include "xchat.h"
@@ -134,8 +133,8 @@ ctcp_handle (session *sess, char *to, char *nick, char *ip,
 
 	if (!strcasecmp (msg, "VERSION") && !prefs.hidever)
 	{
-		snprintf (outbuf, sizeof (outbuf), "VERSION xchat "PACKAGE_VERSION" %s",
-					 get_cpu_str ());
+		snprintf (outbuf, sizeof (outbuf), "VERSION XChat-WDK "PACKAGE_VERSION" [x%d] / %s",
+					 get_cpu_arch (), get_cpu_str ());
 		serv->p_nctcp (serv, nick, outbuf);
 	}
 
diff --git a/src/common/dcc.c b/src/common/dcc.c
index 8f289342..9375095e 100644
--- a/src/common/dcc.c
+++ b/src/common/dcc.c
@@ -31,7 +31,6 @@
 #include <time.h>
 #include <errno.h>
 #include <sys/stat.h>
-#include <unistd.h>
 #include <fcntl.h>
 
 #define WANTSOCKET
@@ -57,6 +56,7 @@
 
 #ifdef USE_DCC64
 #define BIG_STR_TO_INT(x) strtoull(x,NULL,10)
+#define stat _stat64
 #else
 #define BIG_STR_TO_INT(x) strtoul(x,NULL,10)
 #endif
@@ -1983,9 +1983,7 @@ is_same_file (struct DCC *dcc, struct DCC *new_dcc)
 		return TRUE;
 
 	/* now handle case-insensitive Filesystems: HFS+, FAT */
-#ifdef WIN32
-#warning no win32 implementation - behaviour may be unreliable
-#else
+#ifndef WIN32
 	/* this fstat() shouldn't really fail */
 	if ((dcc->fp == -1 ? stat (dcc->destfile_fs, &st_a) : fstat (dcc->fp, &st_a)) == -1)
 		return FALSE;
diff --git a/src/common/dirent.c b/src/common/dirent.c
new file mode 100644
index 00000000..a84f1b65
--- /dev/null
+++ b/src/common/dirent.c
@@ -0,0 +1,199 @@
+/*****************************************************************************
+ * dirent.h - dirent API for Microsoft Visual Studio
+ *
+ * Copyright (C) 2006 Toni Ronkko
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * ``Software''), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL TONI RONKKO BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Dec 15, 2009, John Cunningham
+ * Added rewinddir member function
+ *
+ * Jan 18, 2008, Toni Ronkko
+ * Using FindFirstFileA and WIN32_FIND_DATAA to avoid converting string
+ * between multi-byte and unicode representations.  This makes the
+ * code simpler and also allows the code to be compiled under MingW.  Thanks
+ * to Azriel Fasten for the suggestion.
+ *
+ * Mar 4, 2007, Toni Ronkko
+ * Bug fix: due to the strncpy_s() function this file only compiled in
+ * Visual Studio 2005.  Using the new string functions only when the
+ * compiler version allows.
+ *
+ * Nov  2, 2006, Toni Ronkko
+ * Major update: removed support for Watcom C, MS-DOS and Turbo C to
+ * simplify the file, updated the code to compile cleanly on Visual
+ * Studio 2005 with both unicode and multi-byte character strings,
+ * removed rewinddir() as it had a bug.
+ *
+ * Aug 20, 2006, Toni Ronkko
+ * Removed all remarks about MSVC 1.0, which is antiqued now.  Simplified
+ * comments by removing SGML tags.
+ *
+ * May 14 2002, Toni Ronkko
+ * Embedded the function definitions directly to the header so that no
+ * source modules need to be included in the Visual Studio project.  Removed
+ * all the dependencies to other projects so that this very header can be
+ * used independently.
+ *
+ * May 28 1998, Toni Ronkko
+ * First version.
+ *****************************************************************************/
+
+#include "dirent.h"
+
+/* Use the new safe string functions introduced in Visual Studio 2005 */
+#if defined(_MSC_VER) && _MSC_VER >= 1400
+# define STRNCPY(dest,src,size) strncpy_s((dest),(size),(src),_TRUNCATE)
+#else
+# define STRNCPY(dest,src,size) strncpy((dest),(src),(size))
+#endif
+
+
+/*****************************************************************************
+ * Open directory stream DIRNAME for read and return a pointer to the
+ * internal working area that is used to retrieve individual directory
+ * entries.
+ */
+DIR *opendir(const char *dirname)
+{
+   DIR *dirp;
+   assert (dirname != NULL);
+   assert (strlen (dirname) < MAX_PATH);
+
+   /* construct new DIR structure */
+   dirp = (DIR*) malloc (sizeof (struct DIR));
+   if (dirp != NULL) {
+      char *p;
+
+      /* take directory name... */
+      STRNCPY (dirp->patt, dirname, sizeof(dirp->patt));
+      dirp->patt[MAX_PATH] = '\0';
+
+      /* ... and append search pattern to it */
+      p = strchr (dirp->patt, '\0');
+      if (dirp->patt < p  &&  *(p-1) != '\\'  &&  *(p-1) != ':') {
+         *p++ = '\\';
+      }
+      *p++ = '*';
+      *p = '\0';
+
+      /* open stream and retrieve first file */
+      dirp->search_handle = FindFirstFileA (dirp->patt, &dirp->current.data);
+      if (dirp->search_handle == INVALID_HANDLE_VALUE) {
+         /* invalid search pattern? */
+         free (dirp);
+         return NULL;
+      }
+
+      /* there is an un-processed directory entry in memory now */
+      dirp->cached = 1;
+   }
+
+   return dirp;
+}
+
+
+/*****************************************************************************
+ * Read a directory entry, and return a pointer to a dirent structure
+ * containing the name of the entry in d_name field.  Individual directory
+ * entries returned by this very function include regular files,
+ * sub-directories, pseudo-directories "." and "..", but also volume labels,
+ * hidden files and system files may be returned.
+ */
+struct dirent *readdir(DIR *dirp)
+{
+   assert (dirp != NULL);
+
+   if (dirp->search_handle == INVALID_HANDLE_VALUE) {
+      /* directory stream was opened/rewound incorrectly or ended normally */
+      return NULL;
+   }
+
+   /* get next directory entry */
+   if (dirp->cached != 0) {
+      /* a valid directory entry already in memory */
+      dirp->cached = 0;
+   } else {
+      /* read next directory entry from disk */
+      if (FindNextFileA (dirp->search_handle, &dirp->current.data) == FALSE) {
+         /* the very last file has been processed or an error occured */
+         FindClose (dirp->search_handle);
+         dirp->search_handle = INVALID_HANDLE_VALUE;
+         return NULL;
+      }
+   }
+
+   /* copy as a multibyte character string */
+   STRNCPY ( dirp->current.d_name,
+             dirp->current.data.cFileName,
+             sizeof(dirp->current.d_name) );
+   dirp->current.d_name[MAX_PATH] = '\0';
+
+   return &dirp->current;
+}
+
+
+/*****************************************************************************
+ * Close directory stream opened by opendir() function.  Close of the
+ * directory stream invalidates the DIR structure as well as any previously
+ * read directory entry.
+ */
+int closedir(DIR *dirp)
+{
+   assert (dirp != NULL);
+
+   /* release search handle */
+   if (dirp->search_handle != INVALID_HANDLE_VALUE) {
+      FindClose (dirp->search_handle);
+      dirp->search_handle = INVALID_HANDLE_VALUE;
+   }
+
+   /* release directory handle */
+   free (dirp);
+   return 0;
+}
+
+
+/*****************************************************************************
+ * Resets the position of the directory stream to which dirp refers to the
+ * beginning of the directory. It also causes the directory stream to refer
+ * to the current state of the corresponding directory, as a call to opendir()
+ * would have done. If dirp does not refer to a directory stream, the effect
+ * is undefined.
+ */
+void rewinddir(DIR* dirp)
+{
+   /* release search handle */
+   if (dirp->search_handle != INVALID_HANDLE_VALUE) {
+      FindClose (dirp->search_handle);
+      dirp->search_handle = INVALID_HANDLE_VALUE;
+   }
+
+   /* open new search handle and retrieve first file */
+   dirp->search_handle = FindFirstFileA (dirp->patt, &dirp->current.data);
+   if (dirp->search_handle == INVALID_HANDLE_VALUE) {
+      /* invalid search pattern? */
+      free (dirp);
+      return;
+   }
+
+   /* there is an un-processed directory entry in memory now */
+   dirp->cached = 1;
+}
diff --git a/src/common/dirent.h b/src/common/dirent.h
new file mode 100644
index 00000000..cbb753e6
--- /dev/null
+++ b/src/common/dirent.h
@@ -0,0 +1,28 @@
+#ifndef DIRENT_H
+#define DIRENT_H
+
+#include <windows.h>
+#include <string.h>
+#include <assert.h>
+
+typedef struct dirent
+{
+   char d_name[MAX_PATH + 1]; /* current dir entry (multi-byte char string) */
+   WIN32_FIND_DATAA data;     /* file attributes */
+}  dirent;
+
+typedef struct DIR
+{
+   dirent current;            /* Current directory entry */
+   int    cached;             /* Indicates un-processed entry in memory */
+   HANDLE search_handle;      /* File search handle */
+   char   patt[MAX_PATH + 3]; /* search pattern (3 = pattern + "\\*\0") */
+} DIR;
+
+/* Forward declarations */
+DIR *opendir (const char *dirname);
+struct dirent *readdir (DIR *dirp);
+int closedir (DIR *dirp);
+void rewinddir(DIR* dirp);
+
+#endif /*DIRENT_H*/
diff --git a/src/common/ignore.c b/src/common/ignore.c
index c3544f30..adb61f37 100644
--- a/src/common/ignore.c
+++ b/src/common/ignore.c
@@ -19,7 +19,6 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
-#include <unistd.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
diff --git a/src/common/inbound.c b/src/common/inbound.c
index 41f5cff3..3485dfd4 100644
--- a/src/common/inbound.c
+++ b/src/common/inbound.c
@@ -21,7 +21,6 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <sys/types.h>
-#include <unistd.h>
 #include <time.h>
 
 #define WANTARPA
diff --git a/src/common/inet.h b/src/common/inet.h
index b420c9c6..02473fe2 100644
--- a/src/common/inet.h
+++ b/src/common/inet.h
@@ -24,9 +24,8 @@
 #ifdef USE_IPV6
 #include <winsock2.h>
 #include <ws2tcpip.h>
-#include <tpipv6.h>
 #else
-#include <winsock.h>
+#include <winsock2.h>
 #endif
 
 #define set_blocking(sok)	{ \
diff --git a/src/common/makefile.mak b/src/common/makefile.mak
new file mode 100644
index 00000000..424316c0
--- /dev/null
+++ b/src/common/makefile.mak
@@ -0,0 +1,45 @@
+include "..\makeinc.mak"
+
+COMMON_OBJECTS = \
+cfgfiles.obj \
+chanopt.obj \
+ctcp.obj \
+dcc.obj \
+dirent.obj \
+history.obj \
+ignore.obj \
+inbound.obj \
+modes.obj \
+network.obj \
+notify.obj \
+outbound.obj \
+plugin.obj \
+plugin-timer.obj \
+proto-irc.obj \
+server.obj \
+servlist.obj \
+ssl.obj \
+text.obj \
+thread.obj \
+tree.obj \
+url.obj \
+userlist.obj \
+util.obj \
+wdkutil.obj \
+xchat.obj
+
+all: $(COMMON_OBJECTS) xchatcommon.lib dirent.lib
+
+xchatcommon.lib: $(COMMON_OBJECTS)
+	lib /nologo /out:xchatcommon.lib $(COMMON_OBJECTS)
+
+dirent.lib: dirent.obj
+	lib /nologo /out:dirent.lib dirent.obj
+
+.c.obj::
+	$(CC) $(CFLAGS) $(GLIB) $<
+
+clean:
+	@del *.obj
+	@del xchatcommon.lib
+	@del dirent.lib
diff --git a/src/common/msproxy.c b/src/common/msproxy.c
index 9c85394d..8ad37ffc 100644
--- a/src/common/msproxy.c
+++ b/src/common/msproxy.c
@@ -26,7 +26,6 @@
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
-#include <unistd.h>
 #include <fcntl.h>
 
 #define WANTSOCKET
diff --git a/src/common/network.c b/src/common/network.c
index 0c409506..b7d9aa1f 100644
--- a/src/common/network.c
+++ b/src/common/network.c
@@ -21,7 +21,6 @@
 #include <stdlib.h>
 #include <string.h>
 #include <stdio.h>
-#include <unistd.h>
 #include <glib.h>
 
 #include "../../config.h"				  /* grab USE_IPV6 and LOOKUPD defines */
diff --git a/src/common/notify.c b/src/common/notify.c
index 04795849..4aa5ea17 100644
--- a/src/common/notify.c
+++ b/src/common/notify.c
@@ -22,7 +22,6 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
-#include <unistd.h>
 #include <time.h>
 
 #include "xchat.h"
diff --git a/src/common/outbound.c b/src/common/outbound.c
index 7c6e5e6a..df8eddbd 100644
--- a/src/common/outbound.c
+++ b/src/common/outbound.c
@@ -32,7 +32,6 @@
 #include <sys/wait.h>
 #endif
 
-#include <unistd.h>
 #include <time.h>
 #include <signal.h>
 #include <sys/stat.h>
diff --git a/src/common/plugin-timer.c b/src/common/plugin-timer.c
index f09074a8..2524439d 100644
--- a/src/common/plugin-timer.c
+++ b/src/common/plugin-timer.c
@@ -1,7 +1,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <glib.h>
-#include "xchat-plugin.h"
+#include "../../plugins/xchat-plugin.h"
 
 #ifdef WIN32
 #define strcasecmp stricmp
diff --git a/src/common/plugin.c b/src/common/plugin.c
index ada4d3be..b40660a1 100644
--- a/src/common/plugin.c
+++ b/src/common/plugin.c
@@ -34,7 +34,7 @@
 #include "text.h"
 #define PLUGIN_C
 typedef struct session xchat_context;
-#include "xchat-plugin.h"
+#include "../../plugins/xchat-plugin.h"
 #include "plugin.h"
 
 
@@ -996,13 +996,16 @@ xchat_get_info (xchat_plugin *ph, const char *id)
 		return XCHATLIBDIR;
 
 	case 0x14f51cd8: /* version */
-		return PACKAGE_VERSION;
+		return XCHAT_RELEASE;
 
 	case 0xdd9b1abd:	/* xchatdir */
 		return get_xdir_utf8 ();
 
 	case 0xe33f6c4a:	/* xchatdirfs */
 		return get_xdir_fs ();
+
+	case 0x3d1e70d7:	/* wdk_version */
+		return PACKAGE_VERSION;
 	}
 
 	sess = ph->context;
diff --git a/src/common/proto-irc.c b/src/common/proto-irc.c
index f1df6ccd..3d45e1b0 100644
--- a/src/common/proto-irc.c
+++ b/src/common/proto-irc.c
@@ -18,7 +18,6 @@
 
 /* IRC RFC1459(+commonly used extensions) protocol implementation */
 
-#include <unistd.h>
 #include <string.h>
 #include <stdio.h>
 #include <stdlib.h>
diff --git a/src/common/server.c b/src/common/server.c
index 99894687..f7347052 100644
--- a/src/common/server.c
+++ b/src/common/server.c
@@ -26,7 +26,6 @@
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
-#include <unistd.h>
 #include <errno.h>
 #include <fcntl.h>
 
@@ -845,33 +844,6 @@ server_flush_queue (server *serv)
 	fe_set_throttle (serv);
 }
 
-#ifdef WIN32
-
-static int
-waitline2 (GIOChannel *source, char *buf, int bufsize)
-{
-	int i = 0;
-	int len;
-
-	while (1)
-	{
-		if (g_io_channel_read (source, &buf[i], 1, &len) != G_IO_ERROR_NONE)
-			return -1;
-		if (buf[i] == '\n' || bufsize == i + 1)
-		{
-			buf[i] = 0;
-			return i;
-		}
-		i++;
-	}
-}
-
-#else
-
-#define waitline2(source,buf,size) waitline(serv->childread,buf,size,0)
-
-#endif
-
 /* connect() successed */
 
 static void
@@ -1395,12 +1367,7 @@ base64_encode (char *to, char *from, unsigned int len)
 static int
 http_read_line (int print_fd, int sok, char *buf, int len)
 {
-#ifdef WIN32
-	/* make sure waitline() uses recv() or it'll fail on win32 */
-	len = waitline (sok, buf, len, FALSE);
-#else
 	len = waitline (sok, buf, len, TRUE);
-#endif
 	if (len >= 1)
 	{
 		/* print the message out (send it to the parent process) */
@@ -1526,7 +1493,7 @@ server_child (server * serv)
 		if (FALSE)
 			;
 #ifdef USE_LIBPROXY
-		else if (prefs.proxy_type == 5)
+		} else if (prefs.proxy_type == 5)
 		{
 			char **proxy_list;
 			char *url, *proxy;
@@ -1796,7 +1763,7 @@ server_connect (server *serv, char *hostname, int port, int no_login)
 	}
 #endif
 	serv->childpid = pid;
-	serv->iotag = fe_input_add (serv->childread, FIA_READ, server_read_child,
+	serv->iotag = fe_input_add (serv->childread, FIA_READ|FIA_FD, server_read_child,
 										 serv);
 }
 
diff --git a/src/common/servlist.c b/src/common/servlist.c
index 29731b14..1ca63201 100644
--- a/src/common/servlist.c
+++ b/src/common/servlist.c
@@ -21,7 +21,6 @@
 #include <string.h>
 #include <sys/types.h>
 #include <sys/stat.h>
-#include <unistd.h>
 
 #include "xchat.h"
 #include <glib/ghash.h>
diff --git a/src/common/ssl.c b/src/common/ssl.c
index a18ad47c..daa7416b 100644
--- a/src/common/ssl.c
+++ b/src/common/ssl.c
@@ -17,12 +17,12 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
  */
 
+#include "inet.h"				  /* make it first to avoid macro redefinitions */
 #include <openssl/ssl.h>		  /* SSL_() */
 #include <openssl/err.h>		  /* ERR_() */
 #include <time.h>					  /* asctime() */
 #include <string.h>				  /* strncpy() */
 #include "ssl.h"					  /* struct cert_info */
-#include "inet.h"
 #include "../../config.h"		  /* HAVE_SNPRINTF */
 
 #ifndef HAVE_SNPRINTF
diff --git a/src/common/text.c b/src/common/text.c
index a2198517..fcde5870 100644
--- a/src/common/text.c
+++ b/src/common/text.c
@@ -19,13 +19,11 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
-#include <unistd.h>
 #include <ctype.h>
 #include <time.h>
 #include <sys/types.h>
 #include <fcntl.h>
 #include <sys/stat.h>
-#include <sys/mman.h>
 
 #include "xchat.h"
 #include <glib/ghash.h>
@@ -271,9 +269,6 @@ scrollback_load (session *sess)
 	char *text;
 	time_t stamp;
 	int lines;
-	char *map, *end_map;
-	struct stat statbuf;
-	const char *begin, *eol;
 
 	if (sess->text_scrollback == SET_DEFAULT)
 	{
@@ -293,32 +288,9 @@ scrollback_load (session *sess)
 	if (fh == -1)
 		return;
 
-	if (fstat (fh, &statbuf) < 0)
-		return;
-
-	map = mmap (NULL, statbuf.st_size, PROT_READ, MAP_PRIVATE, fh, 0);
-	if (map == MAP_FAILED)
-		return;
-
-	end_map = map + statbuf.st_size;
-	
 	lines = 0;
-	begin = map;
-	while (begin < end_map)
+	while (waitline (fh, buf, sizeof buf, FALSE) != -1)
 	{
-		int n_bytes;
-
-		eol = memchr (begin, '\n', end_map - begin);
-
-		if (!eol)
-			eol = end_map;
-
-		n_bytes = MIN (eol - begin, sizeof (buf) - 1);
-		
-		strncpy (buf, begin, n_bytes);
-
-		buf[n_bytes] = 0;
-		
 		if (buf[0] == 'T')
 		{
 			if (sizeof (time_t) == 4)
@@ -334,8 +306,6 @@ scrollback_load (session *sess)
 			}
 			lines++;
 		}
-
-		begin = eol + 1;
 	}
 
 	sess->scrollwritten = lines;
@@ -349,7 +319,6 @@ scrollback_load (session *sess)
 		/*EMIT_SIGNAL (XP_TE_GENMSG, sess, "*", buf, NULL, NULL, NULL, 0);*/
 	}
 
-	munmap (map, statbuf.st_size);
 	close (fh);
 }
 
diff --git a/src/common/thread.c b/src/common/thread.c
new file mode 100644
index 00000000..02b17cfb
--- /dev/null
+++ b/src/common/thread.c
@@ -0,0 +1,33 @@
+#include <fcntl.h>
+#include "thread.h"
+
+thread *
+thread_new (void)
+{
+	thread *th;
+
+	th = calloc (1, sizeof (*th));
+	if (!th)
+	{
+		return NULL;
+	}
+
+	if (_pipe (th->pipe_fd, 4096, _O_BINARY) == -1)
+	{
+		free (th);
+		return NULL;
+	}
+
+	return th;
+}
+
+int
+thread_start (thread *th, void *(*start_routine)(void *), void *arg)
+{
+	DWORD id;
+
+	CloseHandle (CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE)start_routine, arg, 0, (DWORD *)&id));
+	th->threadid = id;
+
+	return 1;
+}
diff --git a/src/common/thread.h b/src/common/thread.h
new file mode 100644
index 00000000..7ca0f937
--- /dev/null
+++ b/src/common/thread.h
@@ -0,0 +1,10 @@
+#include <windows.h>
+
+typedef struct
+{
+	DWORD threadid;
+	int pipe_fd[2];
+} thread;
+
+thread *thread_new (void);
+int thread_start (thread *th, void *(*start_routine)(void *), void *arg);
diff --git a/src/common/util.c b/src/common/util.c
index 49517ec4..5677e82a 100644
--- a/src/common/util.c
+++ b/src/common/util.c
@@ -16,11 +16,13 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
  */
 
+#define WANTSOCKET
+#include "inet.h"				/* make it first to avoid macro redefinitions */
+
 #define __APPLE_API_STRICT_CONFORMANCE
 
 #define _FILE_OFFSET_BITS 64
 #include <stdio.h>
-#include <unistd.h>
 #include <string.h>
 #include <stdlib.h>
 #include <sys/types.h>
@@ -35,7 +37,7 @@
 #include <sys/utsname.h>
 #endif
 #include <fcntl.h>
-#include <dirent.h>
+#include "dirent.h"
 #include <errno.h>
 #include "xchat.h"
 #include "xchatc.h"
@@ -44,9 +46,6 @@
 #include "util.h"
 #include "../../config.h"
 
-#define WANTSOCKET
-#include "inet.h"
-
 #if defined (USING_FREEBSD) || defined (__APPLE__)
 #include <sys/sysctl.h>
 #endif
@@ -54,9 +53,11 @@
 #include <socks.h>
 #endif
 
+#ifndef ENABLE_NLS
 #ifndef HAVE_SNPRINTF
 #define snprintf g_snprintf
 #endif
+#endif
 
 #ifdef USE_DEBUG
 
@@ -383,6 +384,28 @@ waitline (int sok, char *buf, int bufsize, int use_recv)
 	}
 }
 
+#ifdef WIN32
+/* waitline2 using win32 file descriptor and glib instead of _read. win32 can't _read() sok! */
+int
+waitline2 (GIOChannel *source, char *buf, int bufsize)
+{
+	int i = 0;
+	int len;
+
+	while (1)
+	{
+		if (g_io_channel_read (source, &buf[i], 1, &len) != G_IO_ERROR_NONE)
+			return -1;
+		if (buf[i] == '\n' || bufsize == i + 1)
+		{
+			buf[i] = 0;
+			return i;
+		}
+		i++;
+	}
+}
+#endif
+
 /* checks for "~" in a file and expands */
 
 char *
@@ -624,30 +647,101 @@ get_mhz (void)
 	return 0;	/* fails on Win9x */
 }
 
+int
+get_cpu_arch (void)
+{
+	SYSTEM_INFO si;
+	unsigned short int cpu_arch;
+
+	GetSystemInfo (&si);
+
+	if (si.wProcessorArchitecture == 9)
+	{
+		return 64;
+	}
+	else
+	{
+		return 86;
+	}
+}
+
 char *
 get_cpu_str (void)
 {
 	static char verbuf[64];
-	OSVERSIONINFO osvi;
-	SYSTEM_INFO si;
+	static char winver[20];
+	OSVERSIONINFOEX osvi;
 	double mhz;
 
-	osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
+	osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFOEX);
 	GetVersionEx (&osvi);
-	GetSystemInfo (&si);
+
+	switch (osvi.dwMajorVersion)
+	{
+		case 5:
+			switch (osvi.dwMinorVersion)
+			{
+				case 1:
+					strcpy (winver, "XP");
+					break;
+				case 2:
+					if (osvi.wProductType == VER_NT_WORKSTATION)
+					{
+						strcpy (winver, "XP x64 Edition");
+					}
+					else
+					{
+						if (GetSystemMetrics(SM_SERVERR2) == 0)
+						{
+							strcpy (winver, "Server 2003");
+						}
+						else
+						{
+							strcpy (winver, "Server 2003 R2");
+						}
+					}
+					break;
+			}
+			break;
+		case 6:
+			switch (osvi.dwMinorVersion)
+			{
+				case 0:
+					if (osvi.wProductType == VER_NT_WORKSTATION)
+					{
+						strcpy (winver, "Vista");
+					}
+					else
+					{
+						strcpy (winver, "Server 2008");
+					}
+					break;
+				case 1:
+					if (osvi.wProductType == VER_NT_WORKSTATION)
+					{
+						strcpy (winver, "7");
+					}
+					else
+					{
+						strcpy (winver, "Server 2008 R2");
+					}
+					break;
+			}
+			break;
+	}
 
 	mhz = get_mhz ();
 	if (mhz)
 	{
 		double cpuspeed = ( mhz > 1000 ) ? mhz / 1000 : mhz;
 		const char *cpuspeedstr = ( mhz > 1000 ) ? "GHz" : "MHz";
-		sprintf (verbuf, "Windows %ld.%ld [i%d86/%.2f%s]",
-					osvi.dwMajorVersion, osvi.dwMinorVersion, si.wProcessorLevel, 
-					cpuspeed, cpuspeedstr);
-	} else
-		sprintf (verbuf, "Windows %ld.%ld [i%d86]",
-			osvi.dwMajorVersion, osvi.dwMinorVersion, si.wProcessorLevel);
-
+		sprintf (verbuf, "Windows %s [%.2f%s]",	winver, cpuspeed, cpuspeedstr);
+	}
+	else
+	{
+		sprintf (verbuf, "Windows %s", winver);
+	}
+	
 	return verbuf;
 }
 
diff --git a/src/common/util.h b/src/common/util.h
index fce45def..92d2a843 100644
--- a/src/common/util.h
+++ b/src/common/util.h
@@ -43,6 +43,12 @@ int strip_color2 (const char *src, int len, char *dst, int flags);
 int strip_hidden_attribute (char *src, char *dst);
 char *errorstring (int err);
 int waitline (int sok, char *buf, int bufsize, int);
+#ifdef WIN32
+int waitline2 (GIOChannel *source, char *buf, int bufsize);
+int get_cpu_arch (void);
+#else
+#define waitline2(source,buf,size) waitline(serv->childread,buf,size,0)
+#endif
 unsigned long make_ping_time (void);
 void move_file_utf8 (char *src_dir, char *dst_dir, char *fname, int dccpermissions);
 int mkdir_utf8 (char *dir);
diff --git a/src/common/wdkutil.c b/src/common/wdkutil.c
new file mode 100644
index 00000000..5bf4f0c0
--- /dev/null
+++ b/src/common/wdkutil.c
@@ -0,0 +1,27 @@
+#include <io.h>
+
+int
+portable_mode ()
+{
+	if ((_access( "portable-mode", 0 )) != -1)
+	{
+		return 1;
+	}
+	else
+	{
+		return 0;
+	}
+}
+
+int
+xtray_mode ()
+{
+	if ((_access( "plugins/xtray.dll", 0 )) != -1)
+	{
+		return 1;
+	}
+	else
+	{
+		return 0;
+	}
+}
diff --git a/src/common/wdkutil.h b/src/common/wdkutil.h
new file mode 100644
index 00000000..2e4c693a
--- /dev/null
+++ b/src/common/wdkutil.h
@@ -0,0 +1,2 @@
+int portable_mode ();
+int xtray_mode ();
diff --git a/src/common/xchat.c b/src/common/xchat.c
index afac9a0e..ba2f5d41 100644
--- a/src/common/xchat.c
+++ b/src/common/xchat.c
@@ -22,7 +22,6 @@
 #include <time.h>
 #include <sys/types.h>
 #include <sys/stat.h>
-#include <unistd.h>
 
 #define WANTSOCKET
 #include "inet.h"
@@ -38,7 +37,7 @@
 #include "cfgfiles.h"
 #include "chanopt.h"
 #include "ignore.h"
-#include "xchat-plugin.h"
+#include "../../plugins/xchat-plugin.h"
 #include "plugin.h"
 #include "plugin-timer.h"
 #include "notify.h"
@@ -590,6 +589,7 @@ static char defaultconf_commands[] =
 	"NAME DMSG\n"			"CMD msg =%2 &3\n\n"\
 	"NAME EXIT\n"			"CMD quit\n\n"\
 	"NAME GREP\n"			"CMD lastlog -r &2\n\n"\
+	"NAME IGNALL\n"			"CMD ignore %2!*@* ALL\n\n"\
 	"NAME J\n"				"CMD join &2\n\n"\
 	"NAME KILL\n"			"CMD quote KILL %2 :&3\n\n"\
 	"NAME LEAVE\n"			"CMD part &2\n\n"\
diff --git a/src/common/xchat.h b/src/common/xchat.h
index db7a6c4b..2f695599 100644
--- a/src/common/xchat.h
+++ b/src/common/xchat.h
@@ -12,12 +12,14 @@
 
 #include "history.h"
 
+#ifndef ENABLE_NLS
 #ifndef HAVE_SNPRINTF
 #define snprintf g_snprintf
 #endif
 
 #ifndef HAVE_VSNPRINTF
-#define vsnprintf g_vsnprintf
+#define vsnprintf _vsnprintf
+#endif
 #endif
 
 #ifdef USE_DEBUG
@@ -58,7 +60,7 @@ void *xchat_realloc (char *old, int len, char *file, int line);
 
 #ifdef WIN32						/* for win32 */
 #define OFLAGS O_BINARY
-#define sleep(t) _sleep(t*1000)
+#define sleep(t) Sleep(t*1000)
 #include <direct.h>
 #define	F_OK	0
 #define	X_OK	1
@@ -209,6 +211,9 @@ struct xchatprefs
 	unsigned int wallops;
 	unsigned int skipmotd;
 	unsigned int autorejoin;
+	unsigned int autocopy_text;
+	unsigned int autocopy_stamp;
+	unsigned int autocopy_color;
 	unsigned int colorednicks;
 	unsigned int chanmodebuttons;
 	unsigned int userlistbuttons;
@@ -297,6 +302,9 @@ struct xchatprefs
 	unsigned int confmode;
 	unsigned int utf8_locale;
 	unsigned int identd;
+	unsigned int emoticons;
+	unsigned int tab_icons;
+	unsigned int tab_xp;
 
 	unsigned int ctcp_number_limit;	/*flood */
 	unsigned int ctcp_time_limit;	/*seconds of floods */
diff --git a/src/fe-gtk/about.c b/src/fe-gtk/about.c
index 60700aec..6e69b646 100644
--- a/src/fe-gtk/about.c
+++ b/src/fe-gtk/about.c
@@ -39,6 +39,7 @@
 
 #include "../common/xchat.h"
 #include "../common/util.h"
+#include "../common/wdkutil.h"
 #include "palette.h"
 #include "pixmaps.h"
 #include "gtkutil.h"
@@ -95,7 +96,7 @@ menu_about (GtkWidget * wid, gpointer sess)
 	}
 
 	about = gtk_dialog_new ();
-	gtk_window_set_position (GTK_WINDOW (about), GTK_WIN_POS_CENTER);
+	gtk_window_set_position (GTK_WINDOW (about), GTK_WIN_POS_CENTER_ON_PARENT);
 	gtk_window_set_resizable (GTK_WINDOW (about), FALSE);
 	gtk_window_set_title (GTK_WINDOW (about), _("About "DISPLAY_NAME));
 	if (parent_window)
@@ -114,35 +115,42 @@ menu_about (GtkWidget * wid, gpointer sess)
 	g_get_charset (&locale);
 	(snprintf) (buf, sizeof (buf),
 				"<span size=\"x-large\"><b>"DISPLAY_NAME" "PACKAGE_VERSION"</b></span>\n\n"
-				"%s\n\n"
 #ifdef WIN32
-				/* leave this message to avoid time wasting bug reports! */
-				"This version is unofficial and comes with no support.\n\n"
-#endif
-				"%s\n"
+				"<b>XChat Release</b>: "XCHAT_RELEASE"\n\n"
+				"<b>OS</b>: %s\n"
 				"<b>Charset</b>: %s "
-#ifdef WIN32 
 				"<b>GTK+</b>: %i.%i.%i\n"
+				"<b>Compiled</b>: "__DATE__"\n"
+				"<b>Portable Mode</b>: %s\n"
+				"<b>Build Type</b>: x%d\n\n"
+				"<small>This version is unofficial and comes with no support.\n"
+				"\302\251 1998-2010 Peter \305\275elezn\303\275 &lt;zed@xchat.org>"
+				/* "\n<a href=\"http://code.google.com/p/xchat-wdk/\">http://code.google.com/p/xchat-wdk/</a>" this is broken in gtk ATM */
+				"</small>",
+				get_cpu_str (),
+				locale,
+				gtk_major_version,
+				gtk_minor_version,
+				gtk_micro_version,
+				(portable_mode () ? "Yes" : "No"),
+				get_cpu_arch ()
 #else
+				"%s\n\n"
+				"%s\n"
+				"<b>Charset</b>: %s "
 				"<b>Renderer</b>: %s\n"
-#endif
 				"<b>Compiled</b>: "__DATE__"\n\n"
 				"<small>\302\251 1998-2010 Peter \305\275elezn\303\275 &lt;zed@xchat.org></small>",
-					_("A multiplatform IRC Client"),
-					get_cpu_str(),
-					locale,
-#ifdef WIN32
-					gtk_major_version,
-					gtk_minor_version,
-					gtk_micro_version
-#else
+				_("A multiplatform IRC Client"),
+				get_cpu_str (),
+				locale,
 #ifdef USE_XFT
-					"Xft"
+				"Xft"
 #else
-					"Pango"
+				"Pango"
 #endif
 #endif
-					);
+				);
 	gtk_label_set_markup (GTK_LABEL (label), buf);
 	gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_CENTER);
 
diff --git a/src/fe-gtk/banlist.c b/src/fe-gtk/banlist.c
index afaa7eb4..f587a0c0 100644
--- a/src/fe-gtk/banlist.c
+++ b/src/fe-gtk/banlist.c
@@ -19,7 +19,6 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <unistd.h>
 #include <fcntl.h>
 #include <time.h>
 
diff --git a/src/fe-gtk/chanlist.c b/src/fe-gtk/chanlist.c
index 2f65b518..6203083b 100644
--- a/src/fe-gtk/chanlist.c
+++ b/src/fe-gtk/chanlist.c
@@ -19,7 +19,6 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <unistd.h>
 #include <fcntl.h>
 #include <time.h>
 
diff --git a/src/fe-gtk/chanview-tabs.c b/src/fe-gtk/chanview-tabs.c
index 8e3da8e6..f99e61f1 100644
--- a/src/fe-gtk/chanview-tabs.c
+++ b/src/fe-gtk/chanview-tabs.c
@@ -144,8 +144,8 @@ tab_scroll_left_up_clicked (GtkWidget *widget, chanview *cv)
 		for (i = adj->value; ((i > new_value) && (tab_left_is_moving)); i -= 0.1)
 		{
 			gtk_adjustment_set_value (adj, i);
-			while (g_main_pending ())
-				g_main_iteration (TRUE);
+			while (g_main_context_pending (NULL))
+				g_main_context_iteration (NULL, TRUE);
 		}
 
 		gtk_adjustment_set_value (adj, new_value);
@@ -191,8 +191,8 @@ tab_scroll_right_down_clicked (GtkWidget *widget, chanview *cv)
 		for (i = adj->value; ((i < new_value) && (tab_right_is_moving)); i += 0.1)
 		{
 			gtk_adjustment_set_value (adj, i);
-			while (g_main_pending ())
-				g_main_iteration (TRUE);
+			while (g_main_context_pending (NULL))
+				g_main_context_iteration (NULL, TRUE);
 		}
 
 		gtk_adjustment_set_value (adj, new_value);
diff --git a/src/fe-gtk/editlist.c b/src/fe-gtk/editlist.c
index 5af67e32..fd2d6810 100644
--- a/src/fe-gtk/editlist.c
+++ b/src/fe-gtk/editlist.c
@@ -19,7 +19,6 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <unistd.h>
 #include <fcntl.h>
 #include <sys/types.h>
 #include <sys/stat.h>
diff --git a/src/fe-gtk/fe-gtk.c b/src/fe-gtk/fe-gtk.c
index 5efcaeec..3f403f94 100644
--- a/src/fe-gtk/fe-gtk.c
+++ b/src/fe-gtk/fe-gtk.c
@@ -19,7 +19,6 @@
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
-#include <unistd.h>
 
 #include "fe-gtk.h"
 
@@ -32,6 +31,8 @@
 #include <gtk/gtkmessagedialog.h>
 #include <gtk/gtkversion.h>
 
+#include <gdk/gdkwin32.h>
+
 #include "../common/xchat.h"
 #include "../common/fe.h"
 #include "../common/util.h"
@@ -39,6 +40,7 @@
 #include "../common/cfgfiles.h"
 #include "../common/xchatc.h"
 #include "../common/plugin.h"
+#include "../common/server.h"
 #include "gtkutil.h"
 #include "maingui.h"
 #include "pixmaps.h"
@@ -136,11 +138,26 @@ static const GOptionEntry gopt_entries[] =
  {NULL}
 };
 
+#ifdef WIN32
+static void
+create_msg_dialog (gchar *title, gchar *message)
+{
+	GtkWidget *dialog;
+	dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE, message);
+	gtk_window_set_title (GTK_WINDOW (dialog), title);
+	gtk_dialog_run (GTK_DIALOG (dialog));
+	gtk_widget_destroy (dialog);
+}
+#endif
+
 int
 fe_args (int argc, char *argv[])
 {
 	GError *error = NULL;
 	GOptionContext *context;
+#ifdef WIN32
+	char *buffer[2048];
+#endif
 
 #ifdef ENABLE_NLS
 	bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
@@ -149,22 +166,67 @@ fe_args (int argc, char *argv[])
 #endif
 
 	context = g_option_context_new (NULL);
+#ifdef WIN32
+	g_option_context_set_help_enabled (context, FALSE);	/* disable stdout help as stdout is unavailable for subsystem:windows */
+#endif
 	g_option_context_add_main_entries (context, gopt_entries, GETTEXT_PACKAGE);
 	g_option_context_add_group (context, gtk_get_option_group (FALSE));
 	g_option_context_parse (context, &argc, &argv, &error);
 
+#ifdef WIN32
+	if (error)											/* workaround for argv not being available when using subsystem:windows */
+	{
+		if (error->message)								/* the error message contains argv so search for patterns in that */
+		{
+			if (strstr (error->message, "--help-all") != NULL)
+			{
+				if (snprintf (buffer, 2048, g_option_context_get_help (context, FALSE, NULL)))
+				{
+					gtk_init (&argc, &argv);
+					create_msg_dialog ("Long Help", buffer);
+				}
+				return 0;
+			} else if (strstr (error->message, "--help") != NULL || strstr (error->message, "-?") != NULL)
+			{
+				if (snprintf (buffer, 2048, g_option_context_get_help (context, TRUE, NULL)))
+				{
+					gtk_init (&argc, &argv);
+					create_msg_dialog ("Help", buffer);
+				}
+				return 0;
+			} else 
+			{
+				if (snprintf (buffer, 2048, "%s\n", error->message))
+				{
+					gtk_init (&argc, &argv);
+					create_msg_dialog ("Error", buffer);
+				}
+				return 1;
+			}
+		}
+	}
+#else
 	if (error)
 	{
 		if (error->message)
 			printf ("%s\n", error->message);
 		return 1;
 	}
+#endif
 
 	g_option_context_free (context);
 
 	if (arg_show_version)
 	{
+#ifdef WIN32
+		if (snprintf (buffer, 2048, DISPLAY_NAME" "PACKAGE_VERSION"\n"))
+		{
+			gtk_init (&argc, &argv);
+			create_msg_dialog ("Version Information", buffer);
+		}
+#else
 		printf (PACKAGE_TARNAME" "PACKAGE_VERSION"\n");
+#endif
 		return 0;
 	}
 
@@ -177,7 +239,18 @@ fe_args (int argc, char *argv[])
 		if (sl)
 		{
 			*sl = 0;
-			printf ("%s\\plugins\n", exe);
+			if (snprintf (buffer, 2048, "%s\\plugins\n", exe))
+			{
+				gtk_init (&argc, &argv);
+				create_msg_dialog ("Plugin Auto-load Directory", buffer);
+			}
+		} else
+		{
+			if (snprintf (buffer, 2048, ".\\plugins\n"))
+			{
+				gtk_init (&argc, &argv);
+				create_msg_dialog ("Plugin Auto-load Directory", buffer);
+			}
 		}
 #else
 		printf ("%s\n", XCHATLIBDIR"/plugins");
@@ -187,7 +260,15 @@ fe_args (int argc, char *argv[])
 
 	if (arg_show_config)
 	{
+#ifdef WIN32
+		if (snprintf (buffer, 2048, "%s\n", get_xdir_fs ()))
+		{
+			gtk_init (&argc, &argv);
+			create_msg_dialog ("User Config Directory", buffer);
+		}
+#else
 		printf ("%s\n", get_xdir_fs ());
+#endif
 		return 0;
 	}
 
@@ -330,7 +411,7 @@ log_handler (const gchar   *log_domain,
 {
 	session *sess;
 
-	if (getenv ("XCHAT_WARNING_IGNORE"))
+	/* if (getenv ("XCHAT_WARNING_IGNORE")) */
 		return;
 
 	sess = find_dialog (serv_list->data, "(warnings)");
diff --git a/src/fe-gtk/fe-gtk.h b/src/fe-gtk/fe-gtk.h
index 12516259..4183f559 100644
--- a/src/fe-gtk/fe-gtk.h
+++ b/src/fe-gtk/fe-gtk.h
@@ -4,7 +4,7 @@
 /* If you're compiling this for Windows, your release is un-official
  * and not condoned. Please don't use the XChat name. Make up your
  * own name! */
-#define DISPLAY_NAME "XChat-Unofficial"
+#define DISPLAY_NAME "XChat-WDK"
 #else
 #define DISPLAY_NAME "XChat"
 #endif
diff --git a/src/fe-gtk/fkeys.c b/src/fe-gtk/fkeys.c
index 014b5cc3..a09c8608 100644
--- a/src/fe-gtk/fkeys.c
+++ b/src/fe-gtk/fkeys.c
@@ -20,7 +20,6 @@
 #include <stdlib.h>
 #include <sys/types.h>
 #include <sys/stat.h>
-#include <unistd.h>
 #include <string.h>
 #include <fcntl.h>
 #include <ctype.h>
diff --git a/src/fe-gtk/gtkutil.c b/src/fe-gtk/gtkutil.c
index 63ab491b..522b44df 100644
--- a/src/fe-gtk/gtkutil.c
+++ b/src/fe-gtk/gtkutil.c
@@ -22,7 +22,6 @@
 #include <stdarg.h>
 #include <sys/types.h>
 #include <sys/stat.h>
-#include <unistd.h>
 #include <fcntl.h>
 #include "fe-gtk.h"
 
@@ -51,6 +50,10 @@
 #include "../common/util.h"
 #include "gtkutil.h"
 #include "pixmaps.h"
+#ifdef WIN32
+#include "../common/fe.h"
+#include "../common/thread.h"
+#endif
 
 /* gtkutil.c, just some gtk wrappers */
 
@@ -63,6 +66,13 @@ struct file_req
 	void *userdata;
 	filereqcallback callback;
 	int flags;		/* FRF_* flags */
+
+#ifdef WIN32
+	int multiple;
+	thread *th;
+	char *title;	/* native locale */
+	char *filter;
+#endif
 };
 
 static char last_dir[256] = "";
@@ -164,6 +174,190 @@ gtkutil_file_req_response (GtkWidget *dialog, gint res, struct file_req *freq)
 	}
 }
 
+#ifdef WIN32
+static int
+win32_openfile (char *file_buf, int file_buf_len, char *title_text, char *filter,
+			   int multiple)
+{
+	OPENFILENAME o;
+
+	memset (&o, 0, sizeof (o));
+
+	o.lStructSize = sizeof (o);
+	o.lpstrFilter = filter;
+	o.lpstrFile = file_buf;
+	o.nMaxFile = file_buf_len;
+	o.lpstrTitle = title_text;
+	o.Flags = 0x02000000 | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY |
+				OFN_NOCHANGEDIR | OFN_EXPLORER | OFN_LONGNAMES | OFN_NONETWORKBUTTON;
+	if (multiple)
+	{
+		o.Flags |= OFN_ALLOWMULTISELECT;
+	}
+
+	return GetOpenFileName (&o);
+}
+
+static int
+win32_savefile (char *file_buf, int file_buf_len, char *title_text, char *filter,
+               int multiple)
+{
+	/* we need the filter to get the default filename. it is from fe-gtk.c (fe_confirm);
+	 * but that filter is actually the whole filename, so apply an empty filter and all good.
+	 * in win32_thread2 we copy the filter ( = the filename) after the last dir into our
+	 * LPTSTR file buffer to make it actually work. the docs for this amazingly retard api:
+	 *
+	 * http://msdn.microsoft.com/en-us/library/ms646839%28VS.85%29.aspx
+	 */
+
+	OPENFILENAME o;
+
+	memset (&o, 0, sizeof (o));
+
+	o.lStructSize = sizeof (o);
+	o.lpstrFilter = "All files\0*.*\0\0";
+	o.lpstrFile = file_buf;
+	o.nMaxFile = file_buf_len;
+	o.lpstrTitle = title_text;
+	o.Flags = 0x02000000 | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY |
+				OFN_NOCHANGEDIR | OFN_EXPLORER | OFN_LONGNAMES | OFN_NONETWORKBUTTON;
+	if (multiple)
+	{
+		o.Flags |= OFN_ALLOWMULTISELECT;
+	}
+
+	return GetSaveFileName (&o);
+}
+
+static void *
+win32_thread (struct file_req *freq)
+{
+	char buf[1024 + 32];
+	char file[1024];
+
+	memset (file, 0, sizeof (file));
+	safe_strcpy (file, last_dir, sizeof (file));
+
+	if (win32_openfile (file, sizeof (file), freq->title, freq->filter, freq->multiple))
+	{
+		if (freq->multiple)
+		{
+			char *f = file;
+
+			if (f[strlen (f) + 1] == 0)	/* only selected one file */
+			{
+				snprintf (buf, sizeof (buf), "1\n%s\n", file);
+				write (freq->th->pipe_fd[1], buf, strlen (buf));
+			} else
+			{
+				f += strlen (f) + 1; /* skip first, it's only the dir */
+				while (f[0])
+				{
+					snprintf (buf, sizeof (buf), "1\n%s\\%s\n", /*dir!*/file, f);
+					write (freq->th->pipe_fd[1], buf, strlen (buf));
+					f += strlen (f) + 1;
+				}
+			}
+
+		} else
+		{
+			snprintf (buf, sizeof (buf), "1\n%s\n", file);
+			write (freq->th->pipe_fd[1], buf, strlen (buf));
+		}
+	}
+
+	write (freq->th->pipe_fd[1], "0\n", 2);
+	Sleep (2000);
+
+	return NULL;
+}
+
+static void *
+win32_thread2 (struct file_req *freq)
+{
+	char buf[1024 + 32];
+	char file[1024];
+
+	memset (file, 0, sizeof (file));
+	safe_strcpy (file, last_dir, sizeof (file));
+	safe_strcpy (file, freq->filter, sizeof (file));
+
+	if (win32_savefile (file, sizeof (file), freq->title, NULL, freq->multiple))
+	{
+		if (freq->multiple)
+		{
+			char *f = file;
+
+			if (f[strlen (f) + 1] == 0)    /* only selected one file */
+			{
+				snprintf (buf, sizeof (buf), "1\n%s\n", file);
+				write (freq->th->pipe_fd[1], buf, strlen (buf));
+			} else
+			{
+				f += strlen (f) + 1; /* skip first, it's only the dir */
+				while (f[0])
+				{
+					snprintf (buf, sizeof (buf), "1\n%s\\%s\n", /*dir!*/file, f);
+					write (freq->th->pipe_fd[1], buf, strlen (buf));
+					f += strlen (f) + 1;
+				}
+			}
+
+		} else
+		{
+			snprintf (buf, sizeof (buf), "1\n%s\n", file);
+			write (freq->th->pipe_fd[1], buf, strlen (buf));
+		}
+	}
+
+	write (freq->th->pipe_fd[1], "0\n", 2);
+	Sleep (2000);
+
+	return NULL;
+}
+
+static gboolean
+win32_close_pipe (int fd)
+{
+	close (fd);
+	return 0;
+}
+
+static gboolean
+win32_read_thread (GIOChannel *source, GIOCondition cond, struct file_req *freq)
+{
+	char buf[512];
+	char *file;
+
+	waitline2 (source, buf, sizeof buf);
+
+	switch (buf[0])
+	{
+	case '0':	/* filedialog has closed */
+		freq->callback (freq->userdata, NULL);
+		break;
+
+	case '1':	/* got a filename! */
+		waitline2 (source, buf, sizeof buf);
+		file = g_filename_to_utf8 (buf, -1, 0, 0, 0);
+		freq->callback (freq->userdata, file);
+		g_free (file);
+		return TRUE;
+	}
+
+	/* it doesn't work to close them here, because of the weird
+		way giowin32 works. We must _return_ before closing them */
+	g_timeout_add(3000, (GSourceFunc)win32_close_pipe, freq->th->pipe_fd[0]);
+	g_timeout_add(2000, (GSourceFunc)win32_close_pipe, freq->th->pipe_fd[1]);
+
+	g_free (freq->title);
+	free (freq->th);
+	free (freq);
+
+	return FALSE;
+}
+#endif
+
 void
 gtkutil_file_req (const char *title, void *callback, void *userdata, char *filter,
 						int flags)
@@ -172,6 +366,58 @@ gtkutil_file_req (const char *title, void *callback, void *userdata, char *filte
 	GtkWidget *dialog;
 	extern char *get_xdir_fs (void);
 
+#ifdef WIN32
+	if (!(flags & FRF_WRITE))
+	{
+		freq = malloc (sizeof (struct file_req));
+		freq->th = thread_new ();
+		freq->flags = 0;
+		freq->multiple = (flags & FRF_MULTIPLE);
+		freq->callback = callback;
+		freq->userdata = userdata;
+		freq->title = g_locale_from_utf8 (title, -1, 0, 0, 0);
+		if (!filter)
+		{
+			freq->filter =	"All files\0*.*\0"
+							"Executables\0*.exe\0"
+							"ZIP files\0*.zip\0\0";
+		}
+		else
+		{
+			freq->filter = filter;
+		}
+
+		thread_start (freq->th, win32_thread, freq);
+		fe_input_add (freq->th->pipe_fd[0], FIA_FD|FIA_READ, win32_read_thread, freq);
+
+		return;
+
+	}
+	
+	else {
+		freq = malloc (sizeof (struct file_req));
+		freq->th = thread_new ();
+		freq->flags = 0;
+		freq->multiple = (flags & FRF_MULTIPLE);
+		freq->callback = callback;
+		freq->userdata = userdata;
+		freq->title = g_locale_from_utf8 (title, -1, 0, 0, 0);
+		if (!filter)
+		{
+			freq->filter = "All files\0*.*\0\0";
+		}
+		else
+		{
+			freq->filter = filter;
+		}
+
+		thread_start (freq->th, win32_thread2, freq);
+		fe_input_add (freq->th->pipe_fd[0], FIA_FD|FIA_READ, win32_read_thread, freq);
+
+	return;
+	}
+#endif
+
 	if (flags & FRF_WRITE)
 	{
 		dialog = gtk_file_chooser_dialog_new (title, NULL,
diff --git a/src/fe-gtk/joind.c b/src/fe-gtk/joind.c
index ee5c56d1..6cd812cf 100644
--- a/src/fe-gtk/joind.c
+++ b/src/fe-gtk/joind.c
@@ -9,7 +9,6 @@
 
 #include <sys/types.h>
 #include <sys/stat.h>
-#include <unistd.h>
 #include <string.h>
 #include <stdio.h>
 
diff --git a/src/fe-gtk/maingui.c b/src/fe-gtk/maingui.c
index ef269f95..27d47731 100644
--- a/src/fe-gtk/maingui.c
+++ b/src/fe-gtk/maingui.c
@@ -53,6 +53,7 @@
 #include "../common/plugin.h"
 #include "../common/modes.h"
 #include "../common/url.h"
+#include "../common/wdkutil.h"
 #include "fe-gtk.h"
 #include "banlist.h"
 #include "gtkutil.h"
@@ -214,60 +215,10 @@ mg_create_tab_colors (void)
 	away_list = mg_attr_list_create (&colors[COL_AWAY], FALSE);
 }
 
-#ifdef WIN32
-#define WINVER 0x0501	/* needed for vc6? */
-#include <windows.h>
-#include <gdk/gdkwin32.h>
-
-/* Flash the taskbar button on Windows when there's a highlight event. */
-
-static void
-flash_window (GtkWidget *win)
-{
-	FLASHWINFO fi;
-	static HMODULE user = NULL;
-	static BOOL (*flash) (PFLASHWINFO) = NULL;
-
-	if (!user)
-	{
-		user = GetModuleHandleA ("USER32");
-		if (!user)
-			return;	/* this should never fail */
-	}
-
-	if (!flash)
-	{
-		flash = (void *)GetProcAddress (user, "FlashWindowEx");
-		if (!flash)
-			return;	/* this fails on NT4.0 and Win95 */
-	}
-
-	fi.cbSize = sizeof (fi);
-	fi.hwnd = GDK_WINDOW_HWND (win->window);
-	fi.dwFlags = FLASHW_ALL | FLASHW_TIMERNOFG;
-	fi.uCount = 0;
-	fi.dwTimeout = 500;
-	flash (&fi);
-	/*FlashWindowEx (&fi);*/
-}
-#else
-
-#ifdef USE_XLIB
-#include <gdk/gdkx.h>
-
 static void
 set_window_urgency (GtkWidget *win, gboolean set)
 {
-	XWMHints *hints;
-
-	hints = XGetWMHints(GDK_WINDOW_XDISPLAY(win->window), GDK_WINDOW_XWINDOW(win->window));
-	if (set)
-		hints->flags |= XUrgencyHint;
-	else
-		hints->flags &= ~XUrgencyHint;
-	XSetWMHints(GDK_WINDOW_XDISPLAY(win->window),
-	            GDK_WINDOW_XWINDOW(win->window), hints);
-	XFree(hints);
+	gtk_window_set_urgency_hint (GTK_WINDOW (win), set);
 }
 
 static void
@@ -281,18 +232,14 @@ unflash_window (GtkWidget *win)
 {
 	set_window_urgency (win, FALSE);
 }
-#endif
-#endif
 
 /* flash the taskbar button */
 
 void
 fe_flash_window (session *sess)
 {
-#if defined(WIN32) || defined(USE_XLIB)
 	if (fe_gui_info (sess, 0) != 1)	/* only do it if not focused */
 		flash_window (sess->gui->window);
-#endif
 }
 
 /* set a tab plain, red, light-red, or blue */
@@ -1334,7 +1281,7 @@ mg_open_quit_dialog (gboolean minimize_button)
 	gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area1),
 										GTK_BUTTONBOX_END);
 
-	if (minimize_button)
+	if (minimize_button && !xtray_mode ())
 	{
 		button = gtk_button_new_with_mnemonic (_("_Minimize to Tray"));
 		gtk_widget_show (button);
@@ -2972,11 +2919,7 @@ mg_tabwin_focus_cb (GtkWindow * win, GdkEventFocus *event, gpointer userdata)
 		gtk_xtext_check_marker_visibility (GTK_XTEXT (current_sess->gui->xtext));
 		plugin_emit_dummy_print (current_sess, "Focus Window");
 	}
-#ifndef WIN32
-#ifdef USE_XLIB
 	unflash_window (GTK_WIDGET (win));
-#endif
-#endif
 	return FALSE;
 }
 
@@ -2987,11 +2930,7 @@ mg_topwin_focus_cb (GtkWindow * win, GdkEventFocus *event, session *sess)
 	if (!sess->server->server_session)
 		sess->server->server_session = sess;
 	gtk_xtext_check_marker_visibility(GTK_XTEXT (current_sess->gui->xtext));
-#ifndef WIN32
-#ifdef USE_XLIB
 	unflash_window (GTK_WIDGET (win));
-#endif
-#endif
 	plugin_emit_dummy_print (sess, "Focus Window");
 	return FALSE;
 }
diff --git a/src/fe-gtk/makefile.mak b/src/fe-gtk/makefile.mak
new file mode 100644
index 00000000..f210181a
--- /dev/null
+++ b/src/fe-gtk/makefile.mak
@@ -0,0 +1,60 @@
+include "..\makeinc.mak"
+
+FEGTK_OBJECTS = \
+about.obj \
+ascii.obj \
+banlist.obj \
+chanlist.obj \
+chanview.obj \
+custom-list.obj \
+dccgui.obj \
+editlist.obj \
+fe-gtk.obj \
+fkeys.obj \
+gtkutil.obj \
+ignoregui.obj \
+joind.obj \
+maingui.obj \
+menu.obj \
+notifygui.obj \
+palette.obj \
+pixmaps.obj \
+plugingui.obj \
+plugin-tray.obj \
+rawlog.obj \
+search.obj \
+servlistgui.obj \
+setup.obj \
+sexy-spell-entry.obj \
+textgui.obj \
+urlgrab.obj \
+userlistgui.obj \
+xtext.obj
+
+!ifdef X64
+MACHINE_FLAG = /MACHINE:X64
+!else
+MACHINE_FLAG = /MACHINE:X86
+!endif
+
+COMLIB = ..\common\xchatcommon.lib
+PROG = xchat.exe
+
+all: $(PROG)
+
+.c.obj::
+	$(CC) $(CFLAGS) -I..\..\plugins $(GLIB) $(GTK) $<
+
+$(PROG): $(FEGTK_OBJECTS) $(COMLIB) xchat-icon.obj
+	$(LINK) /out:$(PROG) /entry:mainCRTStartup $(LDFLAGS) $(LIBS) $(FEGTK_OBJECTS) $(COMLIB) xchat-icon.obj
+
+xchat.res: xchat.rc ../../xchat.ico
+	rc /nologo /r xchat.rc
+
+xchat-icon.obj: xchat.res
+	cvtres /nologo $(MACHINE_FLAG) /OUT:xchat-icon.obj xchat.res
+
+clean:
+	@del *.obj
+	@del $(PROG)
+	@del xchat.res
diff --git a/src/fe-gtk/menu.c b/src/fe-gtk/menu.c
index d04be222..559211c2 100644
--- a/src/fe-gtk/menu.c
+++ b/src/fe-gtk/menu.c
@@ -20,7 +20,6 @@
 #include <stdlib.h>
 #include <fcntl.h>
 #include <string.h>
-#include <unistd.h>
 
 #ifdef WIN32
 #include <windows.h>
@@ -1204,6 +1203,12 @@ menu_resetmarker (GtkWidget * wid, gpointer none)
 }
 
 static void
+menu_copy_selection (GtkWidget * wid, gpointer none)
+{
+	gtk_xtext_copy_selection (GTK_XTEXT (current_sess->gui->xtext));
+}
+
+static void
 menu_flushbuffer (GtkWidget * wid, gpointer none)
 {
 	fe_text_clear (current_sess, 0);
@@ -1645,6 +1650,7 @@ static struct mymenu mymenu[] = {
 	{N_("URL Grabber..."), url_opengui, 0, M_MENUITEM, 0, 0, 1},
 	{0, 0, 0, M_SEP, 0, 0, 0},
 	{N_("Reset Marker Line"), menu_resetmarker, 0, M_MENUITEM, 0, 0, 1, GDK_m},
+	{N_("_Copy Selection"), menu_copy_selection, 0, M_MENUITEM, 0, 0, 1, GDK_C},
 	{N_("C_lear Text"), menu_flushbuffer, GTK_STOCK_CLEAR, M_MENUSTOCK, 0, 0, 1, GDK_l},
 #define SEARCH_OFFSET 67
 	{N_("Search Text..."), menu_search, GTK_STOCK_FIND, M_MENUSTOCK, 0, 0, 1, GDK_f},
@@ -2188,7 +2194,9 @@ normalitem:
 										mymenu[i].key,
 										mymenu[i].key == GDK_F1 ? 0 :
 										mymenu[i].key == GDK_w ? close_mask :
-										GDK_CONTROL_MASK,
+										(g_ascii_isupper (mymenu[i].key)) ?
+											GDK_SHIFT_MASK | GDK_CONTROL_MASK :
+											GDK_CONTROL_MASK,
 										GTK_ACCEL_VISIBLE);
 			if (mymenu[i].callback)
 				g_signal_connect (G_OBJECT (item), "activate",
diff --git a/src/fe-gtk/palette.c b/src/fe-gtk/palette.c
index ebae92ff..8d2ee062 100644
--- a/src/fe-gtk/palette.c
+++ b/src/fe-gtk/palette.c
@@ -18,7 +18,6 @@
 
 #include <stdio.h>
 #include <stdlib.h>
-#include <unistd.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
diff --git a/src/fe-gtk/plugin-tray.c b/src/fe-gtk/plugin-tray.c
index e46d9570..62a726a4 100644
--- a/src/fe-gtk/plugin-tray.c
+++ b/src/fe-gtk/plugin-tray.c
@@ -1,14 +1,14 @@
 /* Copyright (C) 2006-2007 Peter Zelezny. */
 
 #include <string.h>
-#include <unistd.h>
-#include "../common/xchat-plugin.h"
+#include "../../plugins/xchat-plugin.h"
 #include "../common/xchat.h"
 #include "../common/xchatc.h"
 #include "../common/inbound.h"
 #include "../common/server.h"
 #include "../common/fe.h"
 #include "../common/util.h"
+#include "../common/wdkutil.h"
 #include "fe-gtk.h"
 #include "pixmaps.h"
 #include "maingui.h"
@@ -217,10 +217,10 @@ tray_stop_flash (void)
 		nets = tray_count_networks ();
 		chans = tray_count_channels ();
 		if (nets)
-			tray_set_tipf (_("XChat: Connected to %u networks and %u channels"),
+			tray_set_tipf (_("XChat-WDK: Connected to %u networks and %u channels"),
 								nets, chans);
 		else
-			tray_set_tipf ("XChat: %s", _("Not connected."));
+			tray_set_tipf ("XChat-WDK: %s", _("Not connected."));
 	}
 
 	if (custom_icon1)
@@ -370,7 +370,7 @@ tray_toggle_visibility (gboolean force_hide)
 	/* ph may have an invalid context now */
 	xchat_set_context (ph, xchat_find_context (ph, NULL, NULL));
 
-	win = (GtkWindow *)xchat_get_info (ph, "win_ptr");
+	win = xchat_get_info (ph, "gtkwin_ptr");
 
 	tray_stop_flash ();
 	tray_reset_counts ();
@@ -505,11 +505,12 @@ tray_menu_cb (GtkWidget *widget, guint button, guint time, gpointer userdata)
 	/*gtk_menu_set_screen (GTK_MENU (menu), gtk_widget_get_screen (widget));*/
 
 	if (tray_get_window_status () == WS_HIDDEN)
-		tray_make_item (menu, _("_Restore"), tray_menu_restore_cb, NULL);
+		tray_make_item (menu, _("_Restore Window"), tray_menu_restore_cb, NULL);
 	else
-		tray_make_item (menu, _("_Hide"), tray_menu_restore_cb, NULL);
+		tray_make_item (menu, _("_Hide Window"), tray_menu_restore_cb, NULL);
 	tray_make_item (menu, NULL, tray_menu_quit_cb, NULL);
 
+#if 0
 	submenu = mg_submenu (menu, _("_Blink on"));
 	blink_item (&prefs.input_tray_chans, submenu, _("Channel Message"));
 	blink_item (&prefs.input_tray_priv, submenu, _("Private Message"));
@@ -526,6 +527,7 @@ tray_menu_cb (GtkWidget *widget, guint button, guint time, gpointer userdata)
 		gtk_widget_set_sensitive (item, FALSE);
 
 	tray_make_item (menu, NULL, tray_menu_quit_cb, NULL);
+#endif
 	mg_create_icon_item (_("_Quit"), GTK_STOCK_QUIT, menu, tray_menu_quit_cb, NULL);
 
 	menu_add_plugin_items (menu, "\x5$TRAY", NULL);
@@ -551,8 +553,8 @@ tray_init (void)
 	sticon = gtk_status_icon_new_from_pixbuf (ICON_NORMAL);
 	if (!sticon)
 		return;
-	g_signal_connect (G_OBJECT (sticon), "popup-menu",
-							G_CALLBACK (tray_menu_cb), sticon);
+	/* g_signal_connect (G_OBJECT (sticon), "popup-menu",
+							G_CALLBACK (tray_menu_cb), sticon); */
 	g_signal_connect (G_OBJECT (sticon), "activate",
 							G_CALLBACK (tray_menu_restore_cb), NULL);
 }
@@ -570,15 +572,15 @@ tray_hilight_cb (char *word[], void *userdata)
 		/* FIXME: hides any previous private messages */
 		tray_hilight_count++;
 		if (tray_hilight_count == 1)
-			tray_set_tipf (_("XChat: Highlighted message from: %s (%s)"),
+			tray_set_tipf (_("XChat-WDK: Highlighted message from: %s (%s)"),
 								word[1], xchat_get_info (ph, "channel"));
 		else
-			tray_set_tipf (_("XChat: %u highlighted messages, latest from: %s (%s)"),
+			tray_set_tipf (_("XChat-WDK: %u highlighted messages, latest from: %s (%s)"),
 								tray_hilight_count, word[1], xchat_get_info (ph, "channel"));
 	}
 
 	if (prefs.input_balloon_hilight)
-		tray_set_balloonf (word[2], _("XChat: Highlighted message from: %s (%s)"),
+		tray_set_balloonf (word[2], _("XChat-WDK: Highlighted message from: %s (%s)"),
 								 word[1], xchat_get_info (ph, "channel"));
 
 	return XCHAT_EAT_NONE;
@@ -596,14 +598,14 @@ tray_message_cb (char *word[], void *userdata)
 
 		tray_pub_count++;
 		if (tray_pub_count == 1)
-			tray_set_tipf (_("XChat: New public message from: %s (%s)"),
+			tray_set_tipf (_("XChat-WDK: New public message from: %s (%s)"),
 								word[1], xchat_get_info (ph, "channel"));
 		else
-			tray_set_tipf (_("XChat: %u new public messages."), tray_pub_count);
+			tray_set_tipf (_("XChat-WDK: %u new public messages."), tray_pub_count);
 	}
 
 	if (prefs.input_balloon_chans)
-		tray_set_balloonf (word[2], _("XChat: New public message from: %s (%s)"),
+		tray_set_balloonf (word[2], _("XChat-WDK: New public message from: %s (%s)"),
 								 word[1], xchat_get_info (ph, "channel"));
 
 	return XCHAT_EAT_NONE;
@@ -625,14 +627,14 @@ tray_priv (char *from, char *text)
 
 	tray_priv_count++;
 	if (tray_priv_count == 1)
-		tray_set_tipf (_("XChat: Private message from: %s (%s)"),
+		tray_set_tipf (_("XChat-WDK: Private message from: %s (%s)"),
 							from, network);
 	else
-		tray_set_tipf (_("XChat: %u private messages, latest from: %s (%s)"),
+		tray_set_tipf (_("XChat-WDK: %u private messages, latest from: %s (%s)"),
 							tray_priv_count, from, network);
 
 	if (prefs.input_balloon_priv)
-		tray_set_balloonf (text, _("XChat: Private message from: %s (%s)"),
+		tray_set_balloonf (text, _("XChat-WDK: Private message from: %s (%s)"),
 								 from, network);
 }
 
@@ -678,15 +680,15 @@ tray_dcc_cb (char *word[], void *userdata)
 
 		tray_file_count++;
 		if (tray_file_count == 1)
-			tray_set_tipf (_("XChat: File offer from: %s (%s)"),
+			tray_set_tipf (_("XChat-WDK: File offer from: %s (%s)"),
 								word[1], network);
 		else
-			tray_set_tipf (_("XChat: %u file offers, latest from: %s (%s)"),
+			tray_set_tipf (_("XChat-WDK: %u file offers, latest from: %s (%s)"),
 								tray_file_count, word[1], network);
 	}
 
 	if (prefs.input_balloon_priv)
-		tray_set_balloonf ("", _("XChat: File offer from: %s (%s)"),
+		tray_set_balloonf ("", _("XChat-WDK: File offer from: %s (%s)"),
 								word[1], network);
 
 	return XCHAT_EAT_NONE;
@@ -722,7 +724,7 @@ tray_apply_setup (void)
 	}
 	else
 	{
-		if (prefs.gui_tray)
+		if (prefs.gui_tray && !xtray_mode ())
 			tray_init ();
 	}
 }
@@ -754,7 +756,7 @@ tray_plugin_init (xchat_plugin *plugin_handle, char **plugin_name,
 
 	xchat_hook_print (ph, "Focus Window", -1, tray_focus_cb, NULL);
 
-	if (prefs.gui_tray)
+	if (prefs.gui_tray && !xtray_mode ())
 		tray_init ();
 
 	return 1;       /* return 1 for success */
diff --git a/src/fe-gtk/plugingui.c b/src/fe-gtk/plugingui.c
index de59e649..0edfc62b 100644
--- a/src/fe-gtk/plugingui.c
+++ b/src/fe-gtk/plugingui.c
@@ -35,7 +35,7 @@
 #include "../common/xchat.h"
 #define PLUGIN_C
 typedef struct session xchat_context;
-#include "../common/xchat-plugin.h"
+#include "../../plugins/xchat-plugin.h"
 #include "../common/plugin.h"
 #include "../common/util.h"
 #include "../common/outbound.h"
@@ -147,7 +147,9 @@ void
 plugingui_load (void)
 {
 	gtkutil_file_req (_("Select a Plugin or Script to load"), plugingui_load_cb,
-							current_sess, NULL, FRF_ADDFOLDER);
+							current_sess,
+							"Plugins and Scripts\0*.dll;*.lua;*.pl;*.py;*.tcl\0"
+							"All files\0*.*\0\0", 0);
 }
 
 static void
diff --git a/src/fe-gtk/rawlog.c b/src/fe-gtk/rawlog.c
index 56ca0510..a3e1a63b 100644
--- a/src/fe-gtk/rawlog.c
+++ b/src/fe-gtk/rawlog.c
@@ -19,7 +19,6 @@
 #include <stdio.h>
 #include <string.h>
 #include <fcntl.h>
-#include <unistd.h>
 #include <stdlib.h>
 
 #include "fe-gtk.h"
diff --git a/src/fe-gtk/search.c b/src/fe-gtk/search.c
index d62e79c7..bbde9c5c 100644
--- a/src/fe-gtk/search.c
+++ b/src/fe-gtk/search.c
@@ -153,7 +153,7 @@ search_open (session * sess)
 								_("_Find"));
 	g_object_set_data (G_OBJECT (wid), "e", entry);
 
-	g_signal_connect (G_OBJECT (win), "key-press-event", G_CALLBACK (search_key_cb), win);
+	g_signal_connect (G_OBJECT (win), "key_press_event", G_CALLBACK (search_key_cb), win);
 
 	gtk_widget_show (win);
 }
diff --git a/src/fe-gtk/setup.c b/src/fe-gtk/setup.c
index 517e0944..bfa49946 100644
--- a/src/fe-gtk/setup.c
+++ b/src/fe-gtk/setup.c
@@ -109,19 +109,32 @@ static const setting textbox_settings[] =
 					N_("Give each person on IRC a different color"),0,0},
 	{ST_TOGGLR, N_("Indent nick names"), P_OFFINTNL(indent_nicks),
 					N_("Make nick names right-justified"),0,0},
-	{ST_TOGGLE, N_("Transparent background"), P_OFFINTNL(transparent),0,0,0},
-	{ST_TOGGLR, N_("Show marker line"), P_OFFINTNL(show_marker),
+	/* {ST_TOGGLE, N_("Transparent background"), P_OFFINTNL(transparent),0,0,0}, */
+	{ST_TOGGLE, N_("Show marker line"), P_OFFINTNL(show_marker),
 					N_("Insert a red line after the last read text."),0,0},
-	{ST_HEADER, N_("Transparency Settings"), 0,0,0},
+	/* {ST_HEADER, N_("Transparency Settings"), 0,0,0},
 	{ST_HSCALE, N_("Red:"), P_OFFINTNL(tint_red),0,0,0},
 	{ST_HSCALE, N_("Green:"), P_OFFINTNL(tint_green),0,0,0},
-	{ST_HSCALE, N_("Blue:"), P_OFFINTNL(tint_blue),0,0,0},
+	{ST_HSCALE, N_("Blue:"), P_OFFINTNL(tint_blue),0,0,0}, */
 
 	{ST_HEADER,	N_("Time Stamps"),0,0,0},
 	{ST_TOGGLE, N_("Enable time stamps"), P_OFFINTNL(timestamp),0,0,2},
 	{ST_ENTRY,  N_("Time stamp format:"), P_OFFSETNL(stamp_format),
 					N_("See strftime manpage for details."),0,sizeof prefs.stamp_format},
 
+	{ST_HEADER,	N_("Auto-Copy Behavior"),0,0,0},
+	{ST_TOGGLE, N_("Automatically copy selected text"), P_OFFINTNL(autocopy_text),
+					N_("Copy selected text to clipboard when left mouse button is released. "
+						"Otherwise, CONTROL-SHIFT-C will copy the "
+						"selected text to the clipboard."), 0, 0},
+	{ST_TOGGLE, N_("Automatically include time stamps"), P_OFFINTNL(autocopy_stamp),
+					N_("Automatically include time stamps in copied lines of text. Otherwise, "
+						"include time stamps if the SHIFT key is held down while selecting."), 0, 0},
+	{ST_TOGGLE, N_("Automatically include color information"), P_OFFINTNL(autocopy_color),
+					N_("Automatically include color information in copied lines of text.  "
+						"Otherwise, include color information if the CONTROL key is held down "
+						"while selecting."), 0, 0},
+
 	{ST_END, 0, 0, 0, 0, 0}
 };
 
@@ -348,6 +361,24 @@ static const setting alert_settings[] =
 	{ST_END, 0, 0, 0, 0, 0}
 };
 
+static const setting alert_settings_xtray[] =
+{
+	{ST_HEADER,	N_("Alerts"),0,0,0},
+
+	{ST_ALERTHEAD},
+	{ST_3OGGLE, N_("Blink task bar on:"), 0, 0, (void *)taskbarlist, 0},
+	{ST_3OGGLE, N_("Make a beep sound on:"), 0, 0, (void *)beeplist, 0},
+
+	{ST_HEADER,	N_("Highlighted Messages"),0,0,0},
+	{ST_LABEL,	N_("Highlighted messages are ones where your nickname is mentioned, but also:"), 0, 0, 0, 1},
+
+	{ST_ENTRY,	N_("Extra words to highlight:"), P_OFFSETNL(irc_extra_hilight), 0, 0, sizeof prefs.irc_extra_hilight},
+	{ST_ENTRY,	N_("Nick names not to highlight:"), P_OFFSETNL(irc_no_hilight), 0, 0, sizeof prefs.irc_no_hilight},
+	{ST_ENTRY,	N_("Nick names to always highlight:"), P_OFFSETNL(irc_nick_hilight), 0, 0, sizeof prefs.irc_nick_hilight},
+	{ST_LABEL,	N_("Separate multiple words with commas.\nWildcards are accepted.")},
+	{ST_END, 0, 0, 0, 0, 0}
+};
+
 static const setting general_settings[] =
 {
 	{ST_HEADER,	N_("Default Messages"),0,0,0},
@@ -363,7 +394,6 @@ static const setting general_settings[] =
 	{ST_END, 0, 0, 0, 0, 0}
 };
 
-#if 0
 static const setting advanced_settings[] =
 {
 	{ST_HEADER,	N_("Advanced Settings"),0,0,0},
@@ -378,7 +408,6 @@ static const setting advanced_settings[] =
 
 	{ST_END, 0, 0, 0, 0, 0}
 };
-#endif
 
 static const setting logging_settings[] =
 {
@@ -1711,7 +1740,7 @@ static const char *const cata[] =
 		N_("General"),
 		N_("Logging"),
 		N_("Sound"),
-/*		N_("Advanced"),*/
+		N_("Advanced"),
 		NULL,
 	N_("Network"),
 		N_("Network setup"),
@@ -1732,10 +1761,19 @@ setup_create_pages (GtkWidget *box)
 	setup_add_page (cata[3], book, setup_create_page (userlist_settings));
 	setup_add_page (cata[4], book, setup_create_page (tabs_settings));
 	setup_add_page (cata[5], book, setup_create_color_page ());
-	setup_add_page (cata[8], book, setup_create_page (alert_settings));
+
+	if (xtray_mode ())
+	{
+		setup_add_page (cata[8], book, setup_create_page (alert_settings_xtray));
+	} else
+	{
+		setup_add_page (cata[8], book, setup_create_page (alert_settings));
+	}
+
 	setup_add_page (cata[9], book, setup_create_page (general_settings));
 	setup_add_page (cata[10], book, setup_create_page (logging_settings));
 	setup_add_page (cata[11], book, setup_create_sound_page ());
+	setup_add_page (cata[12], book, setup_create_page (advanced_settings));
 	setup_add_page (cata[14], book, setup_create_page (network_settings));
 	setup_add_page (cata[15], book, setup_create_page (filexfer_settings));
 
diff --git a/src/fe-gtk/sexy-spell-entry.c b/src/fe-gtk/sexy-spell-entry.c
index d67ffe2d..d2c6a8a8 100644
--- a/src/fe-gtk/sexy-spell-entry.c
+++ b/src/fe-gtk/sexy-spell-entry.c
@@ -31,6 +31,8 @@
 /*#include "gtkspell-iso-codes.h"
 #include "sexy-marshal.h"*/
 
+#include "typedef.h"
+
 /*
  * Bunch of poop to make enchant into a runtime dependency rather than a
  * compile-time dependency.  This makes it so I don't have to hear the
@@ -134,12 +136,10 @@ initialize_enchant ()
 	GModule *enchant;
 	gpointer funcptr;
 
-	enchant = g_module_open("libenchant", 0);
+	enchant = g_module_open("libenchant.dll", 0);
 	if (enchant == NULL)
 	{
-		enchant = g_module_open("libenchant.so.1", 0);
-		if (enchant == NULL)
-			return;
+		return;
 	}
 
 	have_enchant = TRUE;
diff --git a/src/fe-gtk/typedef.h b/src/fe-gtk/typedef.h
new file mode 100644
index 00000000..b20612ea
--- /dev/null
+++ b/src/fe-gtk/typedef.h
@@ -0,0 +1,11 @@
+#ifndef SSIZE_T_DEFINED
+#ifdef ssize_t
+#undef ssize_t
+#endif
+#ifdef _WIN64
+typedef __int64          ssize_t;
+#else
+typedef _W64 int         ssize_t;
+#endif
+#define SSIZE_T_DEFINED
+#endif
diff --git a/src/fe-gtk/xchat.rc b/src/fe-gtk/xchat.rc
new file mode 100644
index 00000000..18c209c1
--- /dev/null
+++ b/src/fe-gtk/xchat.rc
@@ -0,0 +1,22 @@
+#include <winver.h>

+#include "../../config.h"

+

+XC_ICON ICON "../../xchat.ico" 

+

+VS_VERSION_INFO VERSIONINFO

+	BEGIN

+		BLOCK "StringFileInfo"

+		BEGIN

+			BLOCK "040904B0"

+			BEGIN

+				

+				VALUE "FileDescription", "XChat-WDK IRC Client"

+				VALUE "ProductName", "XChat-WDK" 

+				VALUE "ProductVersion", PACKAGE_VERSION

+			END

+		END

+		BLOCK "VarFileInfo"

+		BEGIN

+			VALUE "Translation", 0x0409, 0x04B0

+		END

+	END

diff --git a/src/fe-gtk/xtext.c b/src/fe-gtk/xtext.c
index fa9803c7..47d7e3ee 100644
--- a/src/fe-gtk/xtext.c
+++ b/src/fe-gtk/xtext.c
@@ -42,7 +42,6 @@
 #include <ctype.h>
 #include <stdlib.h>
 #include <time.h>
-#include <unistd.h>
 #include <gtk/gtkmain.h>
 #include <gtk/gtksignal.h>
 #include <gtk/gtkselection.h>
@@ -67,6 +66,8 @@
 #endif
 
 #include "xtext.h"
+#include "../common/xchat.h"
+#include "../common/xchatc.h"
 
 #define charlen(str) g_utf8_skip[*(guchar *)(str)]
 
@@ -1941,7 +1942,7 @@ gtk_xtext_check_mark_stamp (GtkXText *xtext, GdkModifierType mask)
 {
 	gboolean redraw = FALSE;
 
-	if ((mask & GDK_SHIFT_MASK))
+	if (mask & GDK_SHIFT_MASK || prefs.autocopy_stamp)
 	{
 		if (!xtext->mark_stamp)
 		{
@@ -2106,7 +2107,16 @@ gtk_xtext_set_clip_owner (GtkWidget * xtext, GdkEventButton * event)
 		free (str);
 	}
 
-	gtk_selection_owner_set (xtext, GDK_SELECTION_PRIMARY, event->time);
+	if (event)
+	{
+		gtk_selection_owner_set (xtext, GDK_SELECTION_PRIMARY, event->time);
+	}
+}
+
+void
+gtk_xtext_copy_selection (GtkXText *xtext)
+{
+	gtk_xtext_set_clip_owner (xtext, NULL);
 }
 
 static void
@@ -2182,9 +2192,12 @@ gtk_xtext_button_release (GtkWidget * widget, GdkEventButton * event)
 		if (xtext->buffer->last_ent_start)
 		{
 			xtext->color_paste = FALSE;
-			if (event->state & GDK_CONTROL_MASK)
+			if (event->state & GDK_CONTROL_MASK || prefs.autocopy_color)
 				xtext->color_paste = TRUE;
-			gtk_xtext_set_clip_owner (GTK_WIDGET (xtext), event);
+			if (prefs.autocopy_text)
+			{
+				gtk_xtext_set_clip_owner (GTK_WIDGET (xtext), event);
+			}
 		}
 
 		if (xtext->select_start_x == event->x &&
@@ -2249,7 +2262,10 @@ gtk_xtext_button_press (GtkWidget * widget, GdkEventButton * event)
 			ent->mark_end = offset + len;
 			gtk_xtext_selection_render (xtext, ent, offset, ent, offset + len);
 			xtext->word_or_line_select = TRUE;
-			gtk_xtext_set_clip_owner (GTK_WIDGET (xtext), event);
+			if (prefs.autocopy_text)
+			{
+				gtk_xtext_set_clip_owner (GTK_WIDGET (xtext), event);
+			}
 		}
 
 		return FALSE;
@@ -2265,7 +2281,10 @@ gtk_xtext_button_press (GtkWidget * widget, GdkEventButton * event)
 			ent->mark_end = ent->str_len;
 			gtk_xtext_selection_render (xtext, ent, 0, ent, ent->str_len);
 			xtext->word_or_line_select = TRUE;
-			gtk_xtext_set_clip_owner (GTK_WIDGET (xtext), event);
+			if (prefs.autocopy_text)
+			{
+				gtk_xtext_set_clip_owner (GTK_WIDGET (xtext), event);
+			}
 		}
 
 		return FALSE;
@@ -3836,7 +3855,7 @@ gtk_xtext_load_trans (GtkXText * xtext)
 	PaintDesktop (hdc);
 	ReleaseDC (hwnd, hdc);
 
-	gdk_window_get_size (GTK_WIDGET (xtext)->window, &width, &height);
+	gdk_drawable_get_size (GTK_WIDGET (xtext)->window, &width, &height);
 	img = gdk_image_get (GTK_WIDGET (xtext)->window, 0, 0, width+128, height);
 	xtext->pixmap = win32_tint (xtext, img, img->width, img->height);
 
diff --git a/src/fe-gtk/xtext.h b/src/fe-gtk/xtext.h
index a37ddc32..90fa1bca 100644
--- a/src/fe-gtk/xtext.h
+++ b/src/fe-gtk/xtext.h
@@ -270,6 +270,7 @@ void gtk_xtext_set_wordwrap (GtkXText *xtext, gboolean word_wrap);
 xtext_buffer *gtk_xtext_buffer_new (GtkXText *xtext);
 void gtk_xtext_buffer_free (xtext_buffer *buf);
 void gtk_xtext_buffer_show (GtkXText *xtext, xtext_buffer *buf, int render);
+void gtk_xtext_copy_selection (GtkXText *xtext);
 GType gtk_xtext_get_type (void);
 
 #endif
diff --git a/src/fe-text/fe-text.c b/src/fe-text/fe-text.c
index 2bc2e649..f3c1ff05 100644
--- a/src/fe-text/fe-text.c
+++ b/src/fe-text/fe-text.c
@@ -22,60 +22,51 @@
 #ifdef HAVE_STRINGS_H
 #include <strings.h>
 #endif
+#ifdef WIN32
+#define STDIN_FILENO 0
+#define STDOUT_FILENO 1
+#else
+#include <unistd.h>
 #include <sys/time.h>
+#endif
 #include <sys/types.h>
-#include <unistd.h>
 #include <ctype.h>
+#include <glib.h>
 #include "../common/xchat.h"
 #include "../common/xchatc.h"
+#include "../common/cfgfiles.h"
 #include "../common/outbound.h"
 #include "../common/util.h"
 #include "../common/fe.h"
 #include "fe-text.h"
 
 
-static GSList *tmr_list;		  /* timer list */
-static int tmr_list_count;
-static GSList *se_list;			  /* socket event list */
-static int se_list_count;
 static int done = FALSE;		  /* finished ? */
 
 
 static void
 send_command (char *cmd)
 {
-	handle_multiline (sess_list->data, cmd, TRUE, FALSE);
+	handle_multiline (current_tab, cmd, TRUE, FALSE);
 }
 
-static void
-read_stdin (void)
+static gboolean
+handle_line (GIOChannel *channel, GIOCondition cond, gpointer data)
 {
-	int len, i = 0;
-	static int pos = 0;
-	static char inbuf[1024];
-	char tmpbuf[512];
-
-	len = read (STDIN_FILENO, tmpbuf, sizeof tmpbuf - 1);
-
-	while (i < len)
-	{
-		switch (tmpbuf[i])
-		{
-		case '\r':
-			break;
 
-		case '\n':
-			inbuf[pos] = 0;
-			pos = 0;
-			send_command (inbuf);
-			break;
+	gchar *str_return;
+	gsize length, terminator_pos;
+	GError *error = NULL;
+	GIOStatus result;
 
-		default:
-			inbuf[pos] = tmpbuf[i];
-			if (pos < (sizeof inbuf - 2))
-				pos++;
-		}
-		i++;
+	result = g_io_channel_read_line(channel, &str_return, &length, &terminator_pos, &error);
+	if (result == G_IO_STATUS_ERROR) {
+		return FALSE;
+	}
+	else {
+		send_command(str_return);
+		g_free(str_return);
+		return TRUE;
 	}
 }
 
@@ -87,12 +78,13 @@ fe_new_window (struct session *sess, int focus)
 	char buf[512];
 
 	sess->gui = malloc (4);
+	current_sess = sess;
 
 	if (!sess->server->front_session)
 		sess->server->front_session = sess;
 	if (!sess->server->server_session)
 		sess->server->server_session = sess;
-	if (!current_tab)
+	if (!current_tab || focus)
 		current_tab = sess;
 
 	if (done_intro)
@@ -101,7 +93,7 @@ fe_new_window (struct session *sess, int focus)
 
 	snprintf (buf, sizeof (buf),
 				"\n"
-				" \017xchat \00310"PACKAGE_VERSION"\n"
+				" \017XChat-Text \00310"PACKAGE_VERSION"\n"
 				" \017Running on \00310%s \017glib \00310%d.%d.%d\n"
 				" \017This binary compiled \00310"__DATE__"\017\n",
 				get_cpu_str(),
@@ -133,15 +125,21 @@ get_stamp_str (time_t tim, char *dest, int size)
 }
 
 static int
-timecat (char *buf)
+timecat (char *buf, time_t stamp)
 {
 	char stampbuf[64];
 
-	get_stamp_str (time (0), stampbuf, sizeof (stampbuf));
+	/* set the stamp to the current time if not provided */
+	if (!stamp)
+		stamp = time (0);
+
+	get_stamp_str (stamp, stampbuf, sizeof (stampbuf));
 	strcat (buf, stampbuf);
 	return strlen (stampbuf);
 }
 
+/* Windows doesn't handle ANSI codes in cmd.exe, need to not display them */
+#ifndef WIN32
 /*                       0  1  2  3  4  5  6  7   8   9   10 11  12  13  14 15 */
 static const short colconv[] = { 0, 7, 4, 2, 1, 3, 5, 11, 13, 12, 6, 16, 14, 15, 10, 7 };
 
@@ -157,7 +155,7 @@ fe_print_text (struct session *sess, char *text, time_t stamp)
 	if (prefs.timestamp)
 	{
 		newtext[0] = 0;
-		j += timecat (newtext);
+		j += timecat (newtext, stamp);
 	}
 	while (i < len)
 	{
@@ -165,7 +163,7 @@ fe_print_text (struct session *sess, char *text, time_t stamp)
 		{
 			dotime = FALSE;
 			newtext[j] = 0;
-			j += timecat (newtext);
+			j += timecat (newtext, stamp);
 		}
 		switch (text[i])
 		{
@@ -179,8 +177,7 @@ fe_print_text (struct session *sess, char *text, time_t stamp)
 				j++;
 				newtext[j] = 'm';
 				j++;
-				i--;
-				goto jump2;
+				goto endloop;
 			}
 			k = 0;
 			comma = FALSE;
@@ -226,13 +223,16 @@ fe_print_text (struct session *sess, char *text, time_t stamp)
 						comma = TRUE;
 						break;
 					default:
-						goto jump;
+						goto endloop;
 					}
 					k = 0;
 				}
 				i++;
 			}
 			break;
+		/* don't actually want hidden text */
+		case '\010':				  /* hidden */
+			break;
 		case '\026':				  /* REVERSE */
 			if (reverse)
 			{
@@ -296,120 +296,246 @@ fe_print_text (struct session *sess, char *text, time_t stamp)
 			newtext[j] = text[i];
 			j++;
 		}
-	 jump2:
 		i++;
-	 jump:
-		i += 0;
+		endloop:
+			;
 	}
+
+	/* make sure last character is a new line */
+	if (text[i-1] != '\n')
+		newtext[j++] = '\n';
+
 	newtext[j] = 0;
 	write (STDOUT_FILENO, newtext, j);
 	free (newtext);
 }
-
+#else
+/* The win32 version for cmd.exe */
 void
-fe_timeout_remove (int tag)
+fe_print_text (struct session *sess, char *text, time_t stamp)
 {
-	timerevent *te;
-	GSList *list;
+	int dotime = FALSE;
+	int comma, k, i = 0, j = 0, len = strlen (text);
+
+	unsigned char *newtext = malloc (len + 1024);
 
-	list = tmr_list;
-	while (list)
+	if (prefs.timestamp)
 	{
-		te = (timerevent *) list->data;
-		if (te->tag == tag)
+		newtext[0] = 0;
+		j += timecat (newtext, stamp);
+	}
+	while (i < len)
+	{
+		if (dotime && text[i] != 0)
 		{
-			tmr_list = g_slist_remove (tmr_list, te);
-			free (te);
-			return;
+			dotime = FALSE;
+			newtext[j] = 0;
+			j += timecat (newtext, stamp);
 		}
-		list = list->next;
+		switch (text[i])
+		{
+		case 3:
+			i++;
+			if (!isdigit (text[i]))
+			{
+				goto endloop;
+			}
+			k = 0;
+			comma = FALSE;
+			while (i < len)
+			{
+				if (text[i] >= '0' && text[i] <= '9' && k < 2)
+				{
+					k++;
+				} else
+				{
+					switch (text[i])
+					{
+					case ',':
+						comma = TRUE;
+						break;
+					default:
+						goto endloop;
+					}
+					k = 0;
+
+				}
+				i++;
+			}
+			break;
+		/* don't actually want hidden text */
+		case '\010':				  /* hidden */
+		case '\026':				  /* REVERSE */
+		case '\037':				  /* underline */
+		case '\002':				  /* bold */
+		case '\017':				  /* reset all */
+			break;
+		case '\007':
+			if (!prefs.filterbeep)
+			{
+				newtext[j] = text[i];
+				j++;
+			}
+			break;
+		case '\t':
+			newtext[j] = ' ';
+			j++;
+			break;
+		case '\n':
+			newtext[j] = '\r';
+			j++;
+			if (prefs.timestamp)
+				dotime = TRUE;
+		default:
+			newtext[j] = text[i];
+			j++;
+		}
+		i++;
+		endloop:
+			;
 	}
+
+	/* make sure last character is a new line */
+	if (text[i-1] != '\n')
+		newtext[j++] = '\n';
+
+	newtext[j] = 0;
+	write (STDOUT_FILENO, newtext, j);
+	free (newtext);
+}
+#endif
+
+void
+fe_timeout_remove (int tag)
+{
+	g_source_remove (tag);
 }
 
 int
 fe_timeout_add (int interval, void *callback, void *userdata)
 {
-	struct timeval now;
-	timerevent *te = malloc (sizeof (timerevent));
-
-	tmr_list_count++;				  /* this overflows at 2.2Billion, who cares!! */
-
-	te->tag = tmr_list_count;
-	te->interval = interval;
-	te->callback = callback;
-	te->userdata = userdata;
-
-	gettimeofday (&now, NULL);
-	te->next_call = now.tv_sec * 1000 + (now.tv_usec / 1000) + te->interval;
-
-	tmr_list = g_slist_prepend (tmr_list, te);
-
-	return te->tag;
+	return g_timeout_add (interval, (GSourceFunc) callback, userdata);
 }
 
 void
 fe_input_remove (int tag)
 {
-	socketevent *se;
-	GSList *list;
-
-	list = se_list;
-	while (list)
-	{
-		se = (socketevent *) list->data;
-		if (se->tag == tag)
-		{
-			se_list = g_slist_remove (se_list, se);
-			free (se);
-			return;
-		}
-		list = list->next;
-	}
+	g_source_remove (tag);
 }
 
 int
 fe_input_add (int sok, int flags, void *func, void *data)
 {
-	socketevent *se = malloc (sizeof (socketevent));
+	int tag, type = 0;
+	GIOChannel *channel;
 
-	se_list_count++;				  /* this overflows at 2.2Billion, who cares!! */
+	channel = g_io_channel_unix_new (sok);
 
-	se->tag = se_list_count;
-	se->sok = sok;
-	se->rread = flags & FIA_READ;
-	se->wwrite = flags & FIA_WRITE;
-	se->eexcept = flags & FIA_EX;
-	se->callback = func;
-	se->userdata = data;
-	se_list = g_slist_prepend (se_list, se);
+	if (flags & FIA_READ)
+		type |= G_IO_IN | G_IO_HUP | G_IO_ERR;
+	if (flags & FIA_WRITE)
+		type |= G_IO_OUT | G_IO_ERR;
+	if (flags & FIA_EX)
+		type |= G_IO_PRI;
 
-	return se->tag;
+	tag = g_io_add_watch (channel, type, (GIOFunc) func, data);
+	g_io_channel_unref (channel);
+
+	return tag;
 }
 
+/* === command-line parameter parsing : requires glib 2.6 === */
+
+static char *arg_cfgdir = NULL;
+static gint arg_show_autoload = 0;
+static gint arg_show_config = 0;
+static gint arg_show_version = 0;
+
+static const GOptionEntry gopt_entries[] = 
+{
+ {"no-auto",	'a', 0, G_OPTION_ARG_NONE,	&arg_dont_autoconnect, N_("Don't auto connect to servers"), NULL},
+ {"cfgdir",	'd', 0, G_OPTION_ARG_STRING,	&arg_cfgdir, N_("Use a different config directory"), "PATH"},
+ {"no-plugins",	'n', 0, G_OPTION_ARG_NONE,	&arg_skip_plugins, N_("Don't auto load any plugins"), NULL},
+ {"plugindir",	'p', 0, G_OPTION_ARG_NONE,	&arg_show_autoload, N_("Show plugin auto-load directory"), NULL},
+ {"configdir",	'u', 0, G_OPTION_ARG_NONE,	&arg_show_config, N_("Show user config directory"), NULL},
+ {"url",	 0,  0, G_OPTION_ARG_STRING,	&arg_url, N_("Open an irc://server:port/channel URL"), "URL"},
+ {"version",	'v', 0, G_OPTION_ARG_NONE,	&arg_show_version, N_("Show version information"), NULL},
+ {NULL}
+};
+
 int
 fe_args (int argc, char *argv[])
 {
-	if (argc > 1)
+	GError *error = NULL;
+	GOptionContext *context;
+
+#ifdef ENABLE_NLS
+	bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
+	bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+	textdomain (GETTEXT_PACKAGE);
+#endif
+
+	context = g_option_context_new (NULL);
+	g_option_context_add_main_entries (context, gopt_entries, GETTEXT_PACKAGE);
+	g_option_context_parse (context, &argc, &argv, &error);
+
+	if (error)
+	{
+		if (error->message)
+			printf ("%s\n", error->message);
+		return 1;
+	}
+
+	g_option_context_free (context);
+
+	if (arg_show_version)
+	{
+		printf (PACKAGE_TARNAME" "PACKAGE_VERSION"\n");
+		return 0;
+	}
+
+	if (arg_show_autoload)
 	{
-		if (!strcasecmp (argv[1], "--version") || !strcasecmp (argv[1], "-v"))
+#ifdef WIN32
+		/* see the chdir() below */
+		char *sl, *exe = strdup (argv[0]);
+		sl = strrchr (exe, '\\');
+		if (sl)
 		{
-			puts (PACKAGE_VERSION);
-			return 0;
+			*sl = 0;
+			printf ("%s\\plugins\n", exe);
 		}
+#else
+		printf ("%s\n", XCHATLIBDIR"/plugins");
+#endif
+		return 0;
 	}
+
+	if (arg_show_config)
+	{
+		printf ("%s\n", get_xdir_fs ());
+		return 0;
+	}
+
+	if (arg_cfgdir)	/* we want filesystem encoding */
+	{
+		xdir_fs = strdup (arg_cfgdir);
+		if (xdir_fs[strlen (xdir_fs) - 1] == '/')
+			xdir_fs[strlen (xdir_fs) - 1] = 0;
+		g_free (arg_cfgdir);
+	}
+
 	return -1;
 }
 
 void
 fe_init (void)
 {
-	se_list = 0;
-	se_list_count = 0;
-	tmr_list = 0;
-	tmr_list_count = 0;
+	/* the following should be default generated, not enfoced in binary */
 	prefs.autosave = 0;
 	prefs.use_server_tab = 0;
 	prefs.autodialog = 0;
+	/* except for these, there is no lag meter, there is no server list */
 	prefs.lagometer = 0;
 	prefs.slist_skip = 1;
 }
@@ -417,129 +543,29 @@ fe_init (void)
 void
 fe_main (void)
 {
-	struct timeval timeout, now;
-	socketevent *se;
-	timerevent *te;
-	fd_set rd, wd, ex;
-	GSList *list;
-	guint64 shortest, delay;
+	GIOChannel *keyboard_input;
 
-	if (!sess_list)
-		new_ircwindow (NULL, NULL, SESS_SERVER, 0);
+	main_loop = g_main_loop_new(NULL, FALSE);
 
-#ifdef ENABLE_NLS
-	bindtextdomain (GETTEXT_PACKAGE, PREFIX"/share/locale");
-	bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
-	textdomain (GETTEXT_PACKAGE);
+	/* Keyboard Entry Setup */
+#ifdef G_OS_WIN32
+	keyboard_input = g_io_channel_win32_new_fd(STDIN_FILENO);
+#else
+	keyboard_input = g_io_channel_unix_new(STDIN_FILENO);
 #endif
 
-	while (!done)
-	{
-		FD_ZERO (&rd);
-		FD_ZERO (&wd);
-		FD_ZERO (&ex);
-
-		list = se_list;
-		while (list)
-		{
-			se = (socketevent *) list->data;
-			if (se->rread)
-				FD_SET (se->sok, &rd);
-			if (se->wwrite)
-				FD_SET (se->sok, &wd);
-			if (se->eexcept)
-				FD_SET (se->sok, &ex);
-			list = list->next;
-		}
-
-		FD_SET (STDIN_FILENO, &rd);	/* for reading keyboard */
-
-		/* find the shortest timeout event */
-		shortest = 0;
-		list = tmr_list;
-		while (list)
-		{
-			te = (timerevent *) list->data;
-			if (te->next_call < shortest || shortest == 0)
-				shortest = te->next_call;
-			list = list->next;
-		}
-		gettimeofday (&now, NULL);
-		delay = shortest - ((now.tv_sec * 1000) + (now.tv_usec / 1000));
-		timeout.tv_sec = delay / 1000;
-		timeout.tv_usec = (delay % 1000) * 1000;
-
-		select (FD_SETSIZE, &rd, &wd, &ex, &timeout);
-
-		if (FD_ISSET (STDIN_FILENO, &rd))
-			read_stdin ();
-
-		/* set all checked flags to false */
-		list = se_list;
-		while (list)
-		{
-			se = (socketevent *) list->data;
-			se->checked = 0;
-			list = list->next;
-		}
-
-		/* check all the socket callbacks */
-		list = se_list;
-		while (list)
-		{
-			se = (socketevent *) list->data;
-			se->checked = 1;
-			if (se->rread && FD_ISSET (se->sok, &rd))
-			{
-				se->callback (NULL, 1, se->userdata);
-			} else if (se->wwrite && FD_ISSET (se->sok, &wd))
-			{
-				se->callback (NULL, 2, se->userdata);
-			} else if (se->eexcept && FD_ISSET (se->sok, &ex))
-			{
-				se->callback (NULL, 4, se->userdata);
-			}
-			list = se_list;
-			if (list)
-			{
-				se = (socketevent *) list->data;
-				while (se->checked)
-				{
-					list = list->next;
-					if (!list)
-						break;
-					se = (socketevent *) list->data;
-				}
-			}
-		}
+	g_io_add_watch(keyboard_input, G_IO_IN, handle_line, NULL);
 
-		/* now check our list of timeout events, some might need to be called! */
-		gettimeofday (&now, NULL);
-		list = tmr_list;
-		while (list)
-		{
-			te = (timerevent *) list->data;
-			list = list->next;
-			if (now.tv_sec * 1000 + (now.tv_usec / 1000) >= te->next_call)
-			{
-				/* if the callback returns 0, it must be removed */
-				if (te->callback (te->userdata) == 0)
-				{
-					fe_timeout_remove (te->tag);
-				} else
-				{
-					te->next_call = now.tv_sec * 1000 + (now.tv_usec / 1000) + te->interval;
-				}
-			}
-		}
+	g_main_loop_run(main_loop);
 
-	}
+	return;
 }
 
 void
 fe_exit (void)
 {
 	done = TRUE;
+	g_main_loop_quit(main_loop);
 }
 
 void
@@ -793,10 +819,23 @@ fe_get_int (char *prompt, int def, void *callback, void *ud)
 void
 fe_idle_add (void *func, void *data)
 {
+	g_idle_add (func, data);
 }
 void
 fe_ctrl_gui (session *sess, fe_gui_action action, int arg)
 {
+	/* only one action type handled for now, but could add more */
+	switch (action)
+	{
+	/* gui focus is really the only case xchat-text needs to wory about */
+	case FE_GUI_FOCUS:
+		current_sess = sess;
+		current_tab = sess;
+		sess->server->front_session = sess;
+		break;
+	default:
+		break;
+	}
 }
 int
 fe_gui_info (session *sess, int info_type)
diff --git a/src/fe-text/fe-text.h b/src/fe-text/fe-text.h
index b8afa284..e4f6f6c0 100644
--- a/src/fe-text/fe-text.h
+++ b/src/fe-text/fe-text.h
@@ -1,29 +1 @@
-
-typedef int (*socket_callback) (void *source, int condition, void *user_data);
-typedef int (*timer_callback) (void *user_data);
-
-struct socketeventRec
-{
-	socket_callback callback;
-	void *userdata;
-	int sok;
-	int tag;
-	int rread:1;
-	int wwrite:1;
-	int eexcept:1;
-	int checked:1;
-};
-
-typedef struct socketeventRec socketevent;
-
-
-struct timerRec
-{
-	timer_callback callback;
-	void *userdata;
-	int interval;
-	int tag;
-	guint64 next_call;	/* miliseconds */
-};
-
-typedef struct timerRec timerevent;
+GMainLoop *main_loop;
diff --git a/src/fe-text/makefile.mak b/src/fe-text/makefile.mak
new file mode 100644
index 00000000..59d277d3
--- /dev/null
+++ b/src/fe-text/makefile.mak
@@ -0,0 +1,20 @@
+include "..\makeinc.mak"

+

+COMLIB = ..\common\xchatcommon.lib

+PROG = xchat-text.exe

+

+!ifdef X64

+PLATOBJ = msvcrt_win2003.obj

+!else

+PLATOBJ = msvcrt_winxp.obj

+!endif

+

+all: fe-text.obj

+	link /out:$(PROG) /subsystem:console /nologo $(PLATOBJ) $(LIBS) $(COMLIB) fe-text.obj

+

+fe-text.obj: fe-text.c makefile.mak

+	cl $(CFLAGS) $(GLIB) fe-text.c

+

+clean:

+	@del *.obj

+	@del $(PROG)

diff --git a/src/makefile.mak b/src/makefile.mak
new file mode 100644
index 00000000..670774ed
--- /dev/null
+++ b/src/makefile.mak
@@ -0,0 +1,17 @@
+all:
+	@cd common
+	@-$(MAKE) /nologo /s /f makefile.mak $@
+	@cd ..\fe-gtk
+	@-$(MAKE) /nologo /s /f makefile.mak $@
+	@cd ..\fe-text
+	@-$(MAKE) /nologo /s /f makefile.mak $@
+
+clean:
+	@del common\*.obj
+	@del common\xchatcommon.lib
+	@del fe-gtk\*.obj
+	@del fe-gtk\xchat.exe
+	@del fe-gtk\xchat.res
+	@del fe-text\*.obj
+	@del fe-text\xchat-text.exe
+	@del pixmaps\*.h
diff --git a/src/makeinc.skel.mak b/src/makeinc.skel.mak
new file mode 100644
index 00000000..f7bbeeb7
--- /dev/null
+++ b/src/makeinc.skel.mak
@@ -0,0 +1,48 @@
+CC = cl
+LINK = link
+CFLAGS = $(CFLAGS) /Ox /c /MD /MP /W0 /nologo
+CFLAGS = $(CFLAGS) /DWIN32 /DG_DISABLE_CAST_CHECKS /DG_DISABLE_DEPRECATED /DGDK_PIXBUF_DISABLE_DEPRECATED /DGDK_DISABLE_DEPRECATED /DUSE_IPV6 /DHAVE_STRTOULL /Dstrtoull=_strtoui64 /Dstrcasecmp=stricmp /Dstrncasecmp=strnicmp /DUSE_OPENSSL
+CFLAGS = $(CFLAGS) /I$(DEV)\include
+CPPFLAGS = /c /MD /W0 /nologo /DWIN32
+LDFLAGS = /subsystem:windows /nologo
+LIBS = $(LIBS) gdi32.lib shell32.lib user32.lib advapi32.lib imm32.lib ole32.lib winmm.lib ws2_32.lib wininet.lib comdlg32.lib libeay32.lib ssleay32.lib
+
+GLIB = /I$(DEV)\include\glib-2.0 /I$(DEV)\lib\glib-2.0\include
+GTK = /I$(DEV)\include\gtk-2.0 /I$(DEV)\lib\gtk-2.0\include /I$(DEV)\include\atk-1.0 /I$(DEV)\include\cairo /I$(DEV)\include\pango-1.0 /I$(DEV)\include\gdk-pixbuf-2.0
+LIBS = $(LIBS) /libpath:$(DEV)\lib gtk-win32-2.0.lib gdk-win32-2.0.lib atk-1.0.lib gio-2.0.lib gdk_pixbuf-2.0.lib pangowin32-1.0.lib pangocairo-1.0.lib pango-1.0.lib cairo.lib gobject-2.0.lib gmodule-2.0.lib glib-2.0.lib intl.lib
+
+LUALIB = lua51
+LUAOUTPUT = xclua.dll
+
+PERL510LIB = perl510
+PERL510OUTPUT = xcperl-510.dll
+PERL512LIB = perl512
+PERL512OUTPUT = xcperl-512.dll
+PERL514LIB = perl514
+PERL514OUTPUT = xcperl-514.dll
+
+PYTHONLIB = python27
+PYTHONOUTPUT = xcpython.dll
+
+TCLLIB = tcl85
+TCLOUTPUT = xctcl.dll
+
+!ifdef X64
+CFLAGS = $(CFLAGS) /favor:AMD64 /D_WIN64
+CPPFLAGS = $(CPPFLAGS) /favor:AMD64 /D_WIN64
+LDFLAGS = $(LDFLAGS) msvcrt_win2003.obj
+
+PERL510PATH = c:\mozilla-build\perl-5.10-x64\lib\CORE
+PERL512PATH = c:\mozilla-build\perl-5.12-x64\lib\CORE
+PERL514PATH = c:\mozilla-build\perl-5.14-x64\lib\CORE
+PYTHONPATH = c:\mozilla-build\python-2.7-x64
+TCLPATH = c:\mozilla-build\tcl-8.5-x64
+!else
+LDFLAGS = $(LDFLAGS) msvcrt_winxp.obj
+
+PERL510PATH = c:\mozilla-build\perl-5.10-x86\lib\CORE
+PERL512PATH = c:\mozilla-build\perl-5.12-x86\lib\CORE
+PERL514PATH = c:\mozilla-build\perl-5.14-x86\lib\CORE
+PYTHONPATH = c:\mozilla-build\python-2.7-x86
+TCLPATH = c:\mozilla-build\tcl-8.5-x86
+!endif
diff --git a/src/pixmaps/makefile.mak b/src/pixmaps/makefile.mak
new file mode 100644
index 00000000..f9535dbe
--- /dev/null
+++ b/src/pixmaps/makefile.mak
@@ -0,0 +1,18 @@
+CONV = gdk-pixbuf-csource
+
+LIST =	bookpng book.png \
+			hoppng hop.png \
+			oppng op.png \
+			purplepng purple.png \
+			redpng red.png \
+			trayfilepng fileoffer.png \
+			trayhilightpng highlight.png \
+			traymsgpng message.png \
+			voicepng voice.png \
+			xchatpng ..\..\xchat.png
+
+all: 
+	@$(CONV) --build-list $(LIST) > inline_pngs.h
+
+clean:
+	@del *.h