From d03d6e606b40157d910ddf99ab018156abeb8ef0 Mon Sep 17 00:00:00 2001 From: "berkeviktor@aol.com" Date: Mon, 28 Feb 2011 18:59:32 +0100 Subject: add wdk changes to named branch --- src/common/cfgfiles.c | 37 ++-- src/common/chanopt.c | 1 - src/common/ctcp.c | 3 +- src/common/dcc.c | 6 +- src/common/dirent.c | 199 ++++++++++++++++++ src/common/dirent.h | 28 +++ src/common/ignore.c | 1 - src/common/inbound.c | 1 - src/common/inet.h | 3 +- src/common/makefile.mak | 45 ++++ src/common/msproxy.c | 1 - src/common/network.c | 1 - src/common/notify.c | 1 - src/common/outbound.c | 1 - src/common/plugin-timer.c | 2 +- src/common/plugin.c | 7 +- src/common/proto-irc.c | 1 - src/common/server.c | 38 +--- src/common/servlist.c | 1 - src/common/ssl.c | 2 +- src/common/text.c | 33 +-- src/common/thread.c | 33 +++ src/common/thread.h | 10 + src/common/util.c | 108 ++++++++-- src/common/util.h | 5 + src/common/wdkutil.c | 27 +++ src/common/wdkutil.h | 2 + src/common/xchat.c | 4 +- src/common/xchat.h | 12 +- src/fe-gtk/about.c | 59 ++++-- src/fe-gtk/banlist.c | 1 - src/fe-gtk/chanlist.c | 1 - src/fe-gtk/chanview-tabs.c | 8 +- src/fe-gtk/editlist.c | 1 - src/fe-gtk/fe-gtk.c | 87 +++++++- src/fe-gtk/fe-gtk.h | 2 +- src/fe-gtk/fkeys.c | 1 - src/fe-gtk/gtkutil.c | 248 +++++++++++++++++++++- src/fe-gtk/joind.c | 1 - src/fe-gtk/maingui.c | 67 +----- src/fe-gtk/makefile.mak | 60 ++++++ src/fe-gtk/menu.c | 12 +- src/fe-gtk/palette.c | 1 - src/fe-gtk/plugin-tray.c | 48 +++-- src/fe-gtk/plugingui.c | 6 +- src/fe-gtk/rawlog.c | 1 - src/fe-gtk/search.c | 2 +- src/fe-gtk/setup.c | 54 ++++- src/fe-gtk/sexy-spell-entry.c | 8 +- src/fe-gtk/typedef.h | 11 + src/fe-gtk/xchat.rc | 22 ++ src/fe-gtk/xtext.c | 35 +++- src/fe-gtk/xtext.h | 1 + src/fe-text/fe-text.c | 473 +++++++++++++++++++++++------------------- src/fe-text/fe-text.h | 30 +-- src/fe-text/makefile.mak | 20 ++ src/makefile.mak | 17 ++ src/makeinc.skel.mak | 44 ++++ src/pixmaps/makefile.mak | 18 ++ 59 files changed, 1439 insertions(+), 513 deletions(-) create mode 100644 src/common/dirent.c create mode 100644 src/common/dirent.h create mode 100644 src/common/makefile.mak create mode 100644 src/common/thread.c create mode 100644 src/common/thread.h create mode 100644 src/common/wdkutil.c create mode 100644 src/common/wdkutil.h create mode 100644 src/fe-gtk/makefile.mak create mode 100644 src/fe-gtk/typedef.h create mode 100644 src/fe-gtk/xchat.rc create mode 100644 src/fe-text/makefile.mak create mode 100644 src/makefile.mak create mode 100644 src/makeinc.skel.mak create mode 100644 src/pixmaps/makefile.mak (limited to 'src') 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 -#include #include #include #include @@ -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 #include #include -#include #include #include #include diff --git a/src/common/ctcp.c b/src/common/ctcp.c index 574cda79..a1d70049 100644 --- a/src/common/ctcp.c +++ b/src/common/ctcp.c @@ -18,7 +18,6 @@ #include #include -#include #include #include "xchat.h" @@ -134,7 +133,7 @@ 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", + snprintf (outbuf, sizeof (outbuf), "VERSION XChat-WDK "PACKAGE_VERSION" / %s", 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 #include #include -#include #include #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 +#include +#include + +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 #include #include -#include #include #include #include diff --git a/src/common/inbound.c b/src/common/inbound.c index ec7dd9d0..5cd888c9 100644 --- a/src/common/inbound.c +++ b/src/common/inbound.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #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 #include -#include #else -#include +#include #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 #include #include -#include #include #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 #include #include -#include #include #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 #include #include -#include #include #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 #endif -#include #include #include #include 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 #include #include -#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 #include #include #include diff --git a/src/common/server.c b/src/common/server.c index dd43adff..e72dd24d 100644 --- a/src/common/server.c +++ b/src/common/server.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include @@ -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) */ @@ -1524,9 +1491,10 @@ server_child (server * serv) if (!serv->dont_use_proxy) /* blocked in serverlist? */ { if (FALSE) + { ; #ifdef USE_LIBPROXY - else if (prefs.proxy_type == 5) + } else if (prefs.proxy_type == 5) { char **proxy_list; char *url, *proxy; @@ -1795,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 20a156a8..0f8f8048 100644 --- a/src/common/servlist.c +++ b/src/common/servlist.c @@ -21,7 +21,6 @@ #include #include #include -#include #include "xchat.h" #include 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 /* SSL_() */ #include /* ERR_() */ #include /* asctime() */ #include /* 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 #include #include -#include #include #include #include #include #include -#include #include "xchat.h" #include @@ -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 +#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 + +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..67168a5f 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 -#include #include #include #include @@ -35,7 +37,7 @@ #include #endif #include -#include +#include "dirent.h" #include #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 #endif @@ -54,9 +53,11 @@ #include #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 * @@ -628,26 +651,79 @@ 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..cd9e1fff 100644 --- a/src/common/util.h +++ b/src/common/util.h @@ -43,6 +43,11 @@ 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); +#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 + +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 #include #include -#include #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 #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..453d405c 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" @@ -87,6 +88,19 @@ menu_about (GtkWidget * wid, gpointer sess) char buf[512]; const char *locale = NULL; extern GtkWindow *parent_window; /* maingui.c */ + SYSTEM_INFO si; + unsigned short int cpu_arch; + + GetSystemInfo (&si); + + if (si.wProcessorArchitecture == 9) + { + cpu_arch = 64; + } + else + { + cpu_arch = 86; + } if (about) { @@ -95,7 +109,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 +128,42 @@ menu_about (GtkWidget * wid, gpointer sess) g_get_charset (&locale); (snprintf) (buf, sizeof (buf), ""DISPLAY_NAME" "PACKAGE_VERSION"\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" + "XChat Release: "XCHAT_RELEASE"\n\n" + "OS: %s\n" "Charset: %s " -#ifdef WIN32 "GTK+: %i.%i.%i\n" + "Compiled: "__DATE__"\n" + "Portable Mode: %s\n" + "Build Type: x%d\n\n" + "This version is unofficial and comes with no support.\n" + "\302\251 1998-2010 Peter \305\275elezn\303\275 <zed@xchat.org>" + /* "\nhttp://code.google.com/p/xchat-wdk/" this is broken in gtk ATM */ + "", + get_cpu_str (), + locale, + gtk_major_version, + gtk_minor_version, + gtk_micro_version, + (portable_mode () ? "Yes" : "No"), + cpu_arch #else + "%s\n\n" + "%s\n" + "Charset: %s " "Renderer: %s\n" -#endif "Compiled: "__DATE__"\n\n" "\302\251 1998-2010 Peter \305\275elezn\303\275 <zed@xchat.org>", - _("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 #include #include -#include #include #include 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 #include #include -#include #include #include 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 #include #include -#include #include #include #include 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 #include #include -#include #include "fe-gtk.h" @@ -32,6 +31,8 @@ #include #include +#include + #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 #include #include -#include #include #include #include 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 #include #include -#include #include #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 #include -#include #include #include 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 -#include - -/* 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 - 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 #include #include -#include #ifdef WIN32 #include @@ -1203,6 +1202,12 @@ menu_resetmarker (GtkWidget * wid, gpointer none) gtk_xtext_reset_marker_pos (GTK_XTEXT (current_sess->gui->xtext)); } +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) { @@ -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 #include -#include #include #include #include diff --git a/src/fe-gtk/plugin-tray.c b/src/fe-gtk/plugin-tray.c index 8603abf4..eeed34fa 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 -#include -#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" @@ -297,10 +297,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) @@ -450,7 +450,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 (); @@ -585,11 +585,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")); @@ -606,6 +607,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); @@ -631,8 +633,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); } @@ -650,15 +652,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; @@ -676,14 +678,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; @@ -705,14 +707,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); } @@ -758,15 +760,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; @@ -802,7 +804,7 @@ tray_apply_setup (void) } else { - if (prefs.gui_tray) + if (prefs.gui_tray && !xtray_mode ()) tray_init (); } } @@ -834,7 +836,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 #include #include -#include #include #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 +#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 #include #include -#include #include #include #include @@ -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 #endif +#ifdef WIN32 +#define STDIN_FILENO 0 +#define STDOUT_FILENO 1 +#else +#include #include +#endif #include -#include #include +#include #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..17a16642 --- /dev/null +++ b/src/makeinc.skel.mak @@ -0,0 +1,44 @@ +CC = cl +LINK = link +CFLAGS = $(CFLAGS) /Ox /c /MD /MP2 /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 + +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 +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 +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 -- cgit 1.4.1