From 23e53ae46c20eeb65a5e70721c07a2436c1b3090 Mon Sep 17 00:00:00 2001 From: "berkeviktor@aol.com" Date: Mon, 10 Jan 2011 08:56:37 +0100 Subject: [PATCH] add Orville's patches until they got committed to upstream --- xchat-wdk.patch | 709 ++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 658 insertions(+), 51 deletions(-) diff --git a/xchat-wdk.patch b/xchat-wdk.patch index 570e7f0d..a4661598 100644 --- a/xchat-wdk.patch +++ b/xchat-wdk.patch @@ -2008,8 +2008,8 @@ diff -ruN --strip-trailing-cr xchat-wdk.orig/src/fe-gtk/xtext.h xchat-wdk/src/fe #endif diff -ruN --strip-trailing-cr xchat-wdk.orig/src/fe-text/fe-text.c xchat-wdk/src/fe-text/fe-text.c --- xchat-wdk.orig/src/fe-text/fe-text.c 2008-08-29 13:24:17 +0200 -+++ xchat-wdk/src/fe-text/fe-text.c 2010-12-28 14:57:33 +0100 -@@ -22,9 +22,13 @@ ++++ xchat-wdk/src/fe-text/fe-text.c 2011-01-10 08:55:20 +0100 +@@ -22,60 +22,51 @@ #ifdef HAVE_STRINGS_H #include #endif @@ -2017,70 +2017,677 @@ diff -ruN --strip-trailing-cr xchat-wdk.orig/src/fe-text/fe-text.c xchat-wdk/src +#define STDIN_FILENO 0 +#define STDOUT_FILENO 1 +#else ++#include #include +#endif #include -#include #include ++#include #include "../common/xchat.h" #include "../common/xchatc.h" -@@ -339,7 +343,11 @@ - te->callback = callback; - te->userdata = userdata; ++#include "../common/cfgfiles.h" + #include "../common/outbound.h" + #include "../common/util.h" + #include "../common/fe.h" + #include "fe-text.h" -- gettimeofday (&now, NULL); -+#ifdef WIN32 -+ g_get_current_time (&now); + +-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 @@ + 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) +@@ -133,15 +125,21 @@ + } + + 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 @@ + if (prefs.timestamp) + { + newtext[0] = 0; +- j += timecat (newtext); ++ j += timecat (newtext, stamp); + } + while (i < len) + { +@@ -165,7 +163,7 @@ + { + dotime = FALSE; + newtext[j] = 0; +- j += timecat (newtext); ++ j += timecat (newtext, stamp); + } + switch (text[i]) + { +@@ -179,8 +177,7 @@ + j++; + newtext[j] = 'm'; + j++; +- i--; +- goto jump2; ++ goto endloop; + } + k = 0; + comma = FALSE; +@@ -226,13 +223,16 @@ + 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 @@ + 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 -+ gettimeofday (&now, NULL); -+#endif - te->next_call = now.tv_sec * 1000 + (now.tv_usec / 1000) + te->interval; ++/* 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); - tmr_list = g_slist_prepend (tmr_list, te); -@@ -417,7 +425,12 @@ +- 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); ++ } ++ 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++; + } +- list = list->next; ++ 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)); +- +- se_list_count++; /* this overflows at 2.2Billion, who cares!! */ ++ int tag, type = 0; ++ GIOChannel *channel; + +- 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); ++ channel = g_io_channel_unix_new (sok); + +- return se->tag; +-} ++ 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; ++ ++ 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 (!strcasecmp (argv[1], "--version") || !strcasecmp (argv[1], "-v")) ++ 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) ++ { ++#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 @@ void fe_main (void) { - struct timeval timeout, now; -+ struct timeval timeout; -+#ifdef WIN32 -+ GTimeVal now; -+#else -+ struct timeval now; -+#endif - socketevent *se; - timerevent *te; - fd_set rd, wd, ex; -@@ -428,7 +441,7 @@ - new_ircwindow (NULL, NULL, SESS_SERVER, 0); +- socketevent *se; +- timerevent *te; +- fd_set rd, wd, ex; +- GSList *list; +- guint64 shortest, delay; ++ GIOChannel *keyboard_input; - #ifdef ENABLE_NLS +- 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"); -+ bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); - bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); - textdomain (GETTEXT_PACKAGE); +- 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 -@@ -464,7 +477,11 @@ - shortest = te->next_call; - list = list->next; - } -+#ifdef WIN32 -+ g_get_current_time (&now); -+#else - gettimeofday (&now, NULL); -+#endif - delay = shortest - ((now.tv_sec * 1000) + (now.tv_usec / 1000)); - timeout.tv_sec = delay / 1000; - timeout.tv_usec = (delay % 1000) * 1000; -@@ -514,7 +531,11 @@ - } - /* now check our list of timeout events, some might need to be called! */ -+#ifdef WIN32 -+ g_get_current_time (&now); -+#else - gettimeofday (&now, NULL); -+#endif - list = tmr_list; - while (list) - { +- 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 */ ++ g_io_add_watch(keyboard_input, G_IO_IN, handle_line, NULL); + +- /* 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; +- } ++ g_main_loop_run(main_loop); + +- /* 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; +- } +- } +- } +- +- /* 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; +- } +- } +- } +- +- } ++ return; + } + + void + fe_exit (void) + { + done = TRUE; ++ g_main_loop_quit(main_loop); + } + + void +@@ -793,10 +819,23 @@ + 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 -ruN --strip-trailing-cr xchat-wdk.orig/src/fe-text/fe-text.h xchat-wdk/src/fe-text/fe-text.h +--- xchat-wdk.orig/src/fe-text/fe-text.h 2002-11-28 11:41:32 +0100 ++++ xchat-wdk/src/fe-text/fe-text.h 2011-01-10 08:55:20 +0100 +@@ -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;