diff options
author | Sebastien Helleu <flashcode@flashtux.org> | 2006-02-03 00:36:03 +0000 |
---|---|---|
committer | Sebastien Helleu <flashcode@flashtux.org> | 2006-02-03 00:36:03 +0000 |
commit | 480974b8de118560845cbaa36221eda059a1c756 (patch) | |
tree | b223bc21c4964af385185b97dbc4f82b1c96a84e | |
parent | abeb5a2f481a8801d7195c8a7e0d6e8abb9f4277 (diff) | |
download | weechat-480974b8de118560845cbaa36221eda059a1c756.zip |
Gtk GUI changes, now compile is ok
-rw-r--r-- | configure.in | 11 | ||||
-rw-r--r-- | src/gui/curses/gui-display.c | 93 | ||||
-rw-r--r-- | src/gui/gtk/Makefile.am | 19 | ||||
-rw-r--r-- | src/gui/gtk/gui-display.c | 2185 | ||||
-rw-r--r-- | src/gui/gtk/gui-input.c | 138 | ||||
-rw-r--r-- | src/gui/gui-common.c | 24 | ||||
-rw-r--r-- | src/gui/gui.h | 3 | ||||
-rw-r--r-- | weechat/configure.in | 11 | ||||
-rw-r--r-- | weechat/src/gui/curses/gui-display.c | 93 | ||||
-rw-r--r-- | weechat/src/gui/gtk/Makefile.am | 19 | ||||
-rw-r--r-- | weechat/src/gui/gtk/gui-display.c | 2185 | ||||
-rw-r--r-- | weechat/src/gui/gtk/gui-input.c | 138 | ||||
-rw-r--r-- | weechat/src/gui/gui-common.c | 24 | ||||
-rw-r--r-- | weechat/src/gui/gui.h | 3 |
14 files changed, 4134 insertions, 812 deletions
diff --git a/configure.in b/configure.in index db12397cb..90c78ae31 100644 --- a/configure.in +++ b/configure.in @@ -97,7 +97,7 @@ AH_VERBATIM([DEBUG], [#undef DEBUG]) AC_ARG_ENABLE(ncurses, [ --disable-ncurses Turn off ncurses interface (default=compiled if found)],enable_ncurses=$enableval,enable_ncurses=yes) AC_ARG_ENABLE(wxwidgets, [ --enable-wxwidgets Turn on WxWidgets interface (default=no wxwidgets)],enable_wxwidgets=$enableval,enable_wxwidgets=no) -AC_ARG_ENABLE(gtk, [ --enable-gtk Turn on Gtk+ interface (default=no Gtk+)],enable_gtk=$enableval,enable_gtk=no) +AC_ARG_ENABLE(gtk, [ --enable-gtk Turn on Gtk interface (default=no Gtk)],enable_gtk=$enableval,enable_gtk=no) AC_ARG_ENABLE(qt, [ --enable-qt Turn on Qt interface (default=no Qt)],enable_qt=$enableval,enable_qt=no) AC_ARG_ENABLE(plugins, [ --disable-plugins Turn off plugins support (default=plugins enabled)],enable_plugins=$enableval,enable_plugins=yes) AC_ARG_ENABLE(perl, [ --enable-perl Turn on Perl script plugin (default=no Perl plugin)],enable_perl=$enableval,enable_perl=no) @@ -169,9 +169,10 @@ fi #fi if test "x$enable_gtk" = "xyes" ; then - #if test "$LIBGTK_FOUND" = "0" ; then - # AC_MSG_ERROR([Gtk+ library not found! Install Gtk+ (2.0 or higher) library or run ./configure without --enable-gtk parameter.]) - #fi + AM_PATH_GTK_2_0(2.4.0, LIBGTK_FOUND=1, LIBGTK_FOUND=0) + if test "$LIBGTK_FOUND" = "0" ; then + AC_MSG_ERROR([Gtk library not found! Install Gtk library (2.4 or higher) or run ./configure without --enable-gtk parameter.]) + fi GTK_CFLAGS=`pkg-config --cflags gtk+-2.0` GTK_LIBS=`pkg-config --libs gtk+-2.0` AC_SUBST(GTK_CFLAGS) @@ -528,7 +529,7 @@ if test "x$enable_wxwidgets" = "xyes"; then listgui="$listgui WxWidgets" fi if test "x$enable_gtk" = "xyes" ; then - listgui="$listgui Gtk+" + listgui="$listgui Gtk" fi if test "x$enable_qt" = "xyes" ; then listgui="$listgui Qt" diff --git a/src/gui/curses/gui-display.c b/src/gui/curses/gui-display.c index 33f1dcdcf..f95b1bafc 100644 --- a/src/gui/curses/gui-display.c +++ b/src/gui/curses/gui-display.c @@ -843,12 +843,12 @@ gui_draw_buffer_title (t_gui_buffer *buffer, int erase) } /* - * gui_display_new_line: display a new line + * gui_curses_display_new_line: display a new line */ void -gui_display_new_line (t_gui_window *window, int num_lines, int count, - int *lines_displayed, int simulate) +gui_curses_display_new_line (t_gui_window *window, int num_lines, int count, + int *lines_displayed, int simulate) { if ((count == 0) || (*lines_displayed >= num_lines - count)) { @@ -1147,8 +1147,8 @@ gui_display_word (t_gui_window *window, (((simulate) || (window->win_chat_cursor_y <= window->win_chat_height - 1)) && (window->win_chat_cursor_x > (window->win_chat_width - 1)))) - gui_display_new_line (window, num_lines, count, - lines_displayed, simulate); + gui_curses_display_new_line (window, num_lines, count, + lines_displayed, simulate); if ((data >= end_line) || ((!simulate) && (window->win_chat_cursor_y >= window->win_chat_height))) @@ -1220,16 +1220,19 @@ gui_get_word_info (t_gui_window *window, } /* - * gui_display_line: display a line in the chat window - * if count == 0, display whole line - * if count > 0, display 'count' lines (beginning from the end) - * if simulate == 1, nothing is displayed (for counting how - * many lines would have been lines displayed) - * returns: number of lines displayed (or simulated) + * gui_curses_display_line: display a line in the chat window + * if count == 0, display whole line + * if count > 0, display 'count' lines + * (beginning from the end) + * if simulate == 1, nothing is displayed + * (for counting how many lines would have been + * lines displayed) + * returns: number of lines displayed (or simulated) */ int -gui_display_line (t_gui_window *window, t_gui_line *line, int count, int simulate) +gui_curses_display_line (t_gui_window *window, t_gui_line *line, int count, + int simulate) { int num_lines, x, y, lines_displayed; int read_marker_x, read_marker_y; @@ -1252,7 +1255,7 @@ gui_display_line (t_gui_window *window, t_gui_line *line, int count, int simulat return 0; x = window->win_chat_cursor_x; y = window->win_chat_cursor_y; - num_lines = gui_display_line (window, line, 0, 1); + num_lines = gui_curses_display_line (window, line, 0, 1); window->win_chat_cursor_x = x; window->win_chat_cursor_y = y; } @@ -1290,8 +1293,8 @@ gui_display_line (t_gui_window *window, t_gui_line *line, int count, int simulat if ((window->win_chat_cursor_x + word_length_with_spaces > window->win_chat_width) && (word_length <= window->win_chat_width - line->length_align)) { - gui_display_new_line (window, num_lines, count, - &lines_displayed, simulate); + gui_curses_display_new_line (window, num_lines, count, + &lines_displayed, simulate); /* apply styles before jumping to start of word */ if (!simulate && (word_start_offset > 0)) { @@ -1341,8 +1344,8 @@ gui_display_line (t_gui_window *window, t_gui_line *line, int count, int simulat } else { - gui_display_new_line (window, num_lines, count, - &lines_displayed, simulate); + gui_curses_display_new_line (window, num_lines, count, + &lines_displayed, simulate); ptr_data = NULL; } } @@ -1392,7 +1395,7 @@ gui_calculate_line_diff (t_gui_window *window, t_gui_line **line, int *line_pos, *line = window->buffer->last_line; if (!(*line)) return; - current_size = gui_display_line (window, *line, 0, 1); + current_size = gui_curses_display_line (window, *line, 0, 1); if (current_size == 0) current_size = 1; *line_pos = current_size - 1; @@ -1404,11 +1407,11 @@ gui_calculate_line_diff (t_gui_window *window, t_gui_line **line, int *line_pos, if (!(*line)) return; *line_pos = 0; - current_size = gui_display_line (window, *line, 0, 1); + current_size = gui_curses_display_line (window, *line, 0, 1); } } else - current_size = gui_display_line (window, *line, 0, 1); + current_size = gui_curses_display_line (window, *line, 0, 1); while ((*line) && (difference != 0)) { @@ -1422,7 +1425,7 @@ gui_calculate_line_diff (t_gui_window *window, t_gui_line **line, int *line_pos, *line = (*line)->prev_line; if (*line) { - current_size = gui_display_line (window, *line, 0, 1); + current_size = gui_curses_display_line (window, *line, 0, 1); if (current_size == 0) current_size = 1; *line_pos = current_size - 1; @@ -1440,7 +1443,7 @@ gui_calculate_line_diff (t_gui_window *window, t_gui_line **line, int *line_pos, *line = (*line)->next_line; if (*line) { - current_size = gui_display_line (window, *line, 0, 1); + current_size = gui_curses_display_line (window, *line, 0, 1); if (current_size == 0) current_size = 1; *line_pos = 0; @@ -1648,9 +1651,11 @@ gui_draw_buffer_chat (t_gui_buffer *buffer, int erase) if (line_pos > 0) { /* display end of first line at top of screen */ - gui_display_line (ptr_win, ptr_line, - gui_display_line (ptr_win, ptr_line, 0, 1) - - line_pos, 0); + gui_curses_display_line (ptr_win, ptr_line, + gui_curses_display_line (ptr_win, + ptr_line, + 0, 1) - + line_pos, 0); ptr_line = ptr_line->next_line; ptr_win->first_line_displayed = 0; } @@ -1662,7 +1667,7 @@ gui_draw_buffer_chat (t_gui_buffer *buffer, int erase) count = 0; while (ptr_line && (ptr_win->win_chat_cursor_y <= ptr_win->win_chat_height - 1)) { - count = gui_display_line (ptr_win, ptr_line, 0, 0); + count = gui_curses_display_line (ptr_win, ptr_line, 0, 0); ptr_line = ptr_line->next_line; } @@ -1672,7 +1677,7 @@ gui_draw_buffer_chat (t_gui_buffer *buffer, int erase) /* if so, disable scroll indicator */ if (!ptr_line && ptr_win->scroll) { - if (count == gui_display_line (ptr_win, ptr_win->buffer->last_line, 0, 1)) + if (count == gui_curses_display_line (ptr_win, ptr_win->buffer->last_line, 0, 1)) { ptr_win->scroll = 0; ptr_win->start_line = NULL; @@ -1700,6 +1705,19 @@ gui_draw_buffer_chat (t_gui_buffer *buffer, int erase) } /* + * gui_draw_buffer_chat_line: add a line to chat window for a buffer + */ + +void +gui_draw_buffer_chat_line (t_gui_buffer *buffer, t_gui_line *line) +{ + /* This function does nothing in Curses GUI, + line will be displayed by gui_buffer_draw_chat() */ + (void) buffer; + (void) line; +} + +/* * gui_draw_buffer_nick: draw nick window for a buffer */ @@ -2633,27 +2651,6 @@ gui_switch_to_buffer (t_gui_window *window, t_gui_buffer *buffer) } /* - * gui_get_dcc_buffer: get pointer to DCC buffer (DCC buffer created if not existing) - */ - -t_gui_buffer * -gui_get_dcc_buffer (t_gui_window *window) -{ - t_gui_buffer *ptr_buffer; - - /* check if dcc buffer exists */ - for (ptr_buffer = gui_buffers; ptr_buffer; ptr_buffer = ptr_buffer->next_buffer) - { - if (ptr_buffer->dcc) - break; - } - if (ptr_buffer) - return ptr_buffer; - else - return gui_buffer_new (window, NULL, NULL, 1, 0); -} - -/* * gui_window_page_up: display previous page on buffer */ diff --git a/src/gui/gtk/Makefile.am b/src/gui/gtk/Makefile.am index 10b5ed4d3..655a03d40 100644 --- a/src/gui/gtk/Makefile.am +++ b/src/gui/gtk/Makefile.am @@ -19,11 +19,24 @@ INCLUDES = -DLOCALEDIR=\"$(datadir)/locale\" $(GTK_CFLAGS) bin_PROGRAMS = weechat-gtk -weechat_gtk_LDADD = ../lib_weechat_gui_common.a \ +if PLUGINS +weechat_gtk_LDADD = ../gui-common.o ../gui-keyboard.o \ + ../gui-action.o \ ../../common/lib_weechat_main.a \ ../../irc/lib_weechat_irc.a \ + ../../plugins/lib_weechat_plugins.a \ + $(PLUGINS_LIBS) \ $(GTK_LIBS) \ - ../../plugins/lib_weechat_plugins.a $(PLUGINS_LIBS) + $(GNUTLS_LFLAGS) +else +weechat_gtk_LDADD = ../gui-common.o ../gui-keyboard.o \ + ../gui-action.o \ + ../../common/lib_weechat_main.a \ + ../../irc/lib_weechat_irc.a \ + $(PLUGINS_LIBS) \ + $(GTK_LIBS) \ + $(GNUTLS_LFLAGS) +endif weechat_gtk_SOURCES = gui-display.c \ - gui-input.c + gui-input.c diff --git a/src/gui/gtk/gui-display.c b/src/gui/gtk/gui-display.c index ec7376ae4..7d108b8d3 100644 --- a/src/gui/gtk/gui-display.c +++ b/src/gui/gtk/gui-display.c @@ -30,39 +30,72 @@ #include <string.h> #include <signal.h> #include <time.h> +#include <ctype.h> #include <gtk/gtk.h> #include "../../common/weechat.h" #include "../gui.h" #include "../../common/weeconfig.h" +#include "../../common/hotlist.h" +#include "../../common/log.h" +#include "../../common/utf8.h" #include "../../irc/irc.h" -t_gui_color gui_colors[] = -{ { "default", 0 }, - { "black", 0 }, - { "red", 0 }, - { "lightred", 0 }, - { "green", 0 }, - { "lightgreen", 0 }, - { "brown", 0 }, - { "yellow", 0 }, - { "blue", 0 }, - { "lightblue", 0 }, - { "magenta", 0L }, - { "lightmagenta", 0 }, - { "cyan", 0 }, - { "lightcyan", 0 }, - { "gray", 0 }, - { "white", 0 }, - { NULL, 0 } +/* TODO: remove these temporary defines */ + +#define A_BOLD 1 +#define A_UNDERLINE 2 +#define A_REVERSE 4 + +#define COLOR_BLACK 0 +#define COLOR_BLUE 1 +#define COLOR_GREEN 2 +#define COLOR_CYAN 3 +#define COLOR_RED 4 +#define COLOR_MAGENTA 5 +#define COLOR_YELLOW 6 +#define COLOR_WHITE 7 + +t_gui_color gui_weechat_colors[] = +{ { -1, 0, 0, "default" }, + { WEECHAT_COLOR_BLACK, 0, 0, "black" }, + { WEECHAT_COLOR_RED, 0, 0, "red" }, + { WEECHAT_COLOR_RED, 0, A_BOLD, "lightred" }, + { WEECHAT_COLOR_GREEN, 0, 0, "green" }, + { WEECHAT_COLOR_GREEN, 0, A_BOLD, "lightgreen" }, + { WEECHAT_COLOR_YELLOW, 0, 0, "brown" }, + { WEECHAT_COLOR_YELLOW, 0, A_BOLD, "yellow" }, + { WEECHAT_COLOR_BLUE, 0, 0, "blue" }, + { WEECHAT_COLOR_BLUE, 0, A_BOLD, "lightblue" }, + { WEECHAT_COLOR_MAGENTA, 0, 0, "magenta" }, + { WEECHAT_COLOR_MAGENTA, 0, A_BOLD, "lightmagenta" }, + { WEECHAT_COLOR_CYAN, 0, 0, "cyan" }, + { WEECHAT_COLOR_CYAN, 0, A_BOLD, "lightcyan" }, + { WEECHAT_COLOR_WHITE, 0, A_BOLD, "white" }, + { 0, 0, 0, NULL } }; -char *nicks_colors[COLOR_WIN_NICK_NUMBER] = -{ "cyan", "magenta", "green", "brown", "lightblue", "gray", - "lightcyan", "lightmagenta", "lightgreen", "blue" }; +int gui_irc_colors[16][2] = +{ { /* 0 */ WEECHAT_COLOR_WHITE, A_BOLD }, + { /* 1 */ WEECHAT_COLOR_BLACK, 0 }, + { /* 2 */ WEECHAT_COLOR_BLUE, 0 }, + { /* 3 */ WEECHAT_COLOR_GREEN, 0 }, + { /* 4 */ WEECHAT_COLOR_RED, A_BOLD }, + { /* 5 */ WEECHAT_COLOR_RED, 0 }, + { /* 6 */ WEECHAT_COLOR_MAGENTA, 0 }, + { /* 7 */ WEECHAT_COLOR_YELLOW, 0 }, + { /* 8 */ WEECHAT_COLOR_YELLOW, A_BOLD }, + { /* 9 */ WEECHAT_COLOR_GREEN, A_BOLD }, + { /* 10 */ WEECHAT_COLOR_CYAN, 0 }, + { /* 11 */ WEECHAT_COLOR_CYAN, A_BOLD }, + { /* 12 */ WEECHAT_COLOR_BLUE, A_BOLD }, + { /* 13 */ WEECHAT_COLOR_MAGENTA, A_BOLD }, + { /* 14 */ WEECHAT_COLOR_WHITE, 0 }, + { /* 15 */ WEECHAT_COLOR_WHITE, A_BOLD } +}; -int color_attr[NUM_COLORS]; +t_gui_color *gui_color[NUM_COLORS]; GtkWidget *gtk_main_window; GtkWidget *vbox1; @@ -70,6 +103,7 @@ GtkWidget *entry_topic; GtkWidget *notebook1; GtkWidget *vbox2; GtkWidget *hbox1; +GtkWidget *hpaned1; GtkWidget *scrolledwindow_chat; GtkWidget *scrolledwindow_nick; GtkWidget *entry_input; @@ -77,7 +111,7 @@ GtkWidget *label1; /* - * gui_assign_color: assign a color (read from config) + * gui_assign_color: assign a WeeChat color (read from config) */ int @@ -85,13 +119,13 @@ gui_assign_color (int *color, char *color_name) { int i; - /* look for Gtk colors in table */ + /* look for curses colors in table */ i = 0; - while (gui_colors[i].name) + while (gui_weechat_colors[i].string) { - if (ascii_strcasecmp (gui_colors[i].name, color_name) == 0) + if (ascii_strcasecmp (gui_weechat_colors[i].string, color_name) == 0) { - *color = gui_colors[i].color; + *color = i; return 1; } i++; @@ -102,350 +136,1190 @@ gui_assign_color (int *color, char *color_name) } /* - * gui_get_color_by_name: get color by name + * gui_get_color_name: get color name */ -int -gui_get_color_by_name (char *color_name) +char * +gui_get_color_name (int num_color) { - int i; + return gui_weechat_colors[num_color].string; +} + +/* + * gui_color_decode: parses a message (coming from IRC server), + * and according: + * - remove any color/style in message + * or: + * - change colors by codes to be compatible with + * other IRC clients + * After use, string returned has to be free() + */ + +unsigned char * +gui_color_decode (unsigned char *string, int keep_colors) +{ + unsigned char *out; + int out_length, out_pos; + char str_fg[3], str_bg[3]; + int fg, bg, attr; - /* look for Gtk in table */ - i = 0; - while (gui_colors[i].name) + out_length = (strlen ((char *)string) * 2) + 1; + out = (unsigned char *)malloc (out_length); + if (!out) + return NULL; + + out_pos = 0; + while (string[0] && (out_pos < out_length - 1)) { - if (ascii_strcasecmp (gui_colors[i].name, color_name) == 0) - return gui_colors[i].color; - i++; + switch (string[0]) + { + case GUI_ATTR_BOLD_CHAR: + case GUI_ATTR_RESET_CHAR: + case GUI_ATTR_FIXED_CHAR: + case GUI_ATTR_REVERSE_CHAR: + case GUI_ATTR_REVERSE2_CHAR: + case GUI_ATTR_ITALIC_CHAR: + case GUI_ATTR_UNDERLINE_CHAR: + if (keep_colors) + out[out_pos++] = string[0]; + string++; + break; + case GUI_ATTR_COLOR_CHAR: + string++; + str_fg[0] = '\0'; + str_bg[0] = '\0'; + if (isdigit (string[0])) + { + str_fg[0] = string[0]; + str_fg[1] = '\0'; + string++; + if (isdigit (string[0])) + { + str_fg[1] = string[0]; + str_fg[2] = '\0'; + string++; + } + } + if (string[0] == ',') + { + string++; + if (isdigit (string[0])) + { + str_bg[0] = string[0]; + str_bg[1] = '\0'; + string++; + if (isdigit (string[0])) + { + str_bg[1] = string[0]; + str_bg[2] = '\0'; + string++; + } + } + } + if (keep_colors) + { + if (!str_fg[0] && !str_bg[0]) + out[out_pos++] = GUI_ATTR_COLOR_CHAR; + else + { + attr = 0; + if (str_fg[0]) + { + sscanf (str_fg, "%d", &fg); + fg %= 16; + attr |= gui_irc_colors[fg][1]; + } + if (str_bg[0]) + { + sscanf (str_bg, "%d", &bg); + bg %= 16; + attr |= gui_irc_colors[bg][1]; + } + if (attr & A_BOLD) + { + out[out_pos++] = GUI_ATTR_WEECHAT_SET_CHAR; + out[out_pos++] = GUI_ATTR_BOLD_CHAR; + } + else + { + out[out_pos++] = GUI_ATTR_WEECHAT_REMOVE_CHAR; + out[out_pos++] = GUI_ATTR_BOLD_CHAR; + } + out[out_pos++] = GUI_ATTR_COLOR_CHAR; + if (str_fg[0]) + { + out[out_pos++] = (gui_irc_colors[fg][0] / 10) + '0'; + out[out_pos++] = (gui_irc_colors[fg][0] % 10) + '0'; + } + if (str_bg[0]) + { + out[out_pos++] = ','; + out[out_pos++] = (gui_irc_colors[bg][0] / 10) + '0'; + out[out_pos++] = (gui_irc_colors[bg][0] % 10) + '0'; + } + } + } + break; + case GUI_ATTR_WEECHAT_COLOR_CHAR: + string++; + if (isdigit (string[0]) && isdigit (string[1])) + { + if (keep_colors) + { + out[out_pos++] = string[0]; + out[out_pos++] = string[1]; + } + string += 2; + } + break; + case GUI_ATTR_WEECHAT_SET_CHAR: + case GUI_ATTR_WEECHAT_REMOVE_CHAR: + string++; + if (string[0]) + { + if (keep_colors) + { + out[out_pos++] = *(string - 1); + out[out_pos++] = string[0]; + } + string++; + } + break; + default: + out[out_pos++] = string[0]; + string++; + } } + out[out_pos] = '\0'; + return out; +} + +/* + * gui_color_decode_for_user_entry: parses a message (coming from IRC server), + * and replaces colors/bold/.. by %C, %B, .. + * After use, string returned has to be free() + */ + +unsigned char * +gui_color_decode_for_user_entry (unsigned char *string) +{ + unsigned char *out; + int out_length, out_pos; - /* color not found */ - return -1; + out_length = (strlen ((char *)string) * 2) + 1; + out = (unsigned char *)malloc (out_length); + if (!out) + return NULL; + + out_pos = 0; + while (string[0] && (out_pos < out_length - 1)) + { + switch (string[0]) + { + case GUI_ATTR_BOLD_CHAR: + out[out_pos++] = '%'; + out[out_pos++] = 'B'; + string++; + break; + case GUI_ATTR_FIXED_CHAR: + string++; + break; + case GUI_ATTR_RESET_CHAR: + out[out_pos++] = '%'; + out[out_pos++] = 'O'; + string++; + break; + case GUI_ATTR_REVERSE_CHAR: + case GUI_ATTR_REVERSE2_CHAR: + out[out_pos++] = '%'; + out[out_pos++] = 'R'; + string++; + break; + case GUI_ATTR_ITALIC_CHAR: + string++; + break; + case GUI_ATTR_UNDERLINE_CHAR: + out[out_pos++] = '%'; + out[out_pos++] = 'R'; + string++; + break; + case GUI_ATTR_COLOR_CHAR: + out[out_pos++] = '%'; + out[out_pos++] = 'C'; + string++; + break; + default: + out[out_pos++] = string[0]; + string++; + } + } + out[out_pos] = '\0'; + return out; } /* - * gui_get_color_by_value: get color name by value + * gui_color_encode: parses a message (entered by user), and + * encode special chars (%B, %C, ..) in IRC colors + * After use, string returned has to be free() */ -char * -gui_get_color_by_value (int color_value) +unsigned char * +gui_color_encode (unsigned char *string) { - int i; + unsigned char *out; + int out_length, out_pos; - /* look for Gtk colors in table */ - i = 0; - while (gui_colors[i].name) + out_length = (strlen ((char *)string) * 2) + 1; + out = (unsigned char *)malloc (out_length); + if (!out) + return NULL; + + out_pos = 0; + while (string[0] && (out_pos < out_length - 1)) { - if (gui_colors[i].color == color_value) - return gui_colors[i].name; - i++; + switch (string[0]) + { + case '%': + string++; + switch (string[0]) + { + case '\0': + out[out_pos++] = '%'; + break; + case '%': /* double '%' replaced by single '%' */ + out[out_pos++] = string[0]; + string++; + break; + case 'B': /* bold */ + out[out_pos++] = GUI_ATTR_BOLD_CHAR; + string++; + break; + case 'C': /* color */ + out[out_pos++] = GUI_ATTR_COLOR_CHAR; + string++; + if (isdigit (string[0])) + { + out[out_pos++] = string[0]; + string++; + if (isdigit (string[0])) + { + out[out_pos++] = string[0]; + string++; + } + } + if (string[0] == ',') + { + out[out_pos++] = ','; + string++; + if (isdigit (string[0])) + { + out[out_pos++] = string[0]; + string++; + if (isdigit (string[0])) + { + out[out_pos++] = string[0]; + string++; + } + } + } + break; + case 'O': /* reset */ + out[out_pos++] = GUI_ATTR_RESET_CHAR; + string++; + break; + case 'R': /* reverse */ + out[out_pos++] = GUI_ATTR_REVERSE_CHAR; + string++; + break; + case 'U': /* underline */ + out[out_pos++] = GUI_ATTR_UNDERLINE_CHAR; + string++; + break; + default: + out[out_pos++] = '%'; + out[out_pos++] = string[0]; + string++; + } + break; + default: + out[out_pos++] = string[0]; + string++; + } } + out[out_pos] = '\0'; + return out; +} + +/* + * gui_color_build: build a WeeChat color with foreground, + * background and attributes (attributes are + * given with foreground color, with a OR) + */ + +t_gui_color * +gui_color_build (int number, int foreground, int background) +{ + t_gui_color *new_color; - /* color not found */ - return NULL; + new_color = (t_gui_color *)malloc (sizeof (t_gui_color)); + if (!new_color) + return NULL; + + new_color->foreground = gui_weechat_colors[foreground].foreground; + new_color->background = gui_weechat_colors[background].foreground; + new_color->attributes = gui_weechat_colors[foreground].attributes; + new_color->string = (char *)malloc (4); + if (new_color->string) + snprintf (new_color->string, 4, + "%s%02d", + GUI_ATTR_WEECHAT_COLOR_STR, number); + + return new_color; } /* - * gui_window_has_nicklist: returns 1 if window has nicklist + * gui_color_get_pair: get color pair with a WeeChat color number */ int -gui_window_has_nicklist (t_gui_window *window) +gui_color_get_pair (int num_color) { - return (window->textbuffer_nicklist != NULL); + int fg, bg; + + if ((num_color < 0) || (num_color > NUM_COLORS - 1)) + return WEECHAT_COLOR_WHITE; + + fg = gui_color[num_color]->foreground; + bg = gui_color[num_color]->background; + + if (((fg == -1) || (fg == 99)) + && ((bg == -1) || (bg == 99))) + return 63; + if ((fg == -1) || (fg == 99)) + fg = WEECHAT_COLOR_WHITE; + if ((bg == -1) || (bg == 99)) + bg = 0; + + return (bg * 8) + fg; } /* - * gui_calculate_pos_size: calculate position and size for a window & sub-win + * gui_window_set_weechat_color: set WeeChat color for window + */ + +/* TODO: write this function for Gtk */ +/*void +gui_window_set_weechat_color (WINDOW *window, int num_color) +{ + if ((num_color >= 0) && (num_color <= NUM_COLORS - 1)) + { + wattroff (window, A_BOLD | A_UNDERLINE | A_REVERSE); + wattron (window, COLOR_PAIR(gui_color_get_pair (num_color)) | + gui_color[num_color]->attributes); + } +}*/ + +/* + * gui_window_chat_set_style: set style (bold, underline, ..) + * for a chat window */ void -gui_calculate_pos_size (t_gui_window *window) +gui_window_chat_set_style (t_gui_window *window, int style) { - /* TODO: write gui_calculate_pos_size for Gtk GUI */ + /* TODO: write this function for Gtk */ + /*wattron (window->win_chat, style);*/ (void) window; + (void) style; } /* - * gui_draw_window_title: draw title window + * gui_window_chat_remove_style: remove style (bold, underline, ..) + * for a chat window */ void -gui_draw_window_title (t_gui_window *window) +gui_window_chat_remove_style (t_gui_window *window, int style) { - char format[32]; - - /* TODO: manage splitted windows! */ - if (window != gui_current_window) - return; + /* TODO: write this function for Gtk */ + /*wattroff (window->win_chat, style);*/ + (void) window; + (void) style; +} + +/* + * gui_window_chat_toggle_style: toggle a style (bold, underline, ..) + * for a chat window + */ + +void +gui_window_chat_toggle_style (t_gui_window *window, int style) +{ + window->current_style_attr ^= style; + if (window->current_style_attr & style) + gui_window_chat_set_style (window, style); + else + gui_window_chat_remove_style (window, style); +} + +/* + * gui_window_chat_reset_style: reset style (color and attr) + * for a chat window + */ + +void +gui_window_chat_reset_style (t_gui_window *window) +{ + window->current_style_fg = -1; + window->current_style_bg = -1; + window->current_style_attr = 0; + window->current_color_attr = 0; - if (CHANNEL(window)) - { - sprintf (format, "%%-%ds", window->win_width); - /* TODO: display topic */ - } + /* TODO: change following function call */ + /*gui_window_set_weechat_color (window->win_chat, COLOR_WIN_CHAT);*/ + gui_window_chat_remove_style (window, + A_BOLD | A_UNDERLINE | A_REVERSE); +} + +/* + * gui_window_chat_set_color_style: set style for color + */ + +void +gui_window_chat_set_color_style (t_gui_window *window, int style) +{ + window->current_color_attr |= style; + /* TODO: change following function call */ + /*wattron (window->win_chat, style);*/ +} + +/* + * gui_window_chat_remove_color_style: remove style for color + */ + +void +gui_window_chat_remove_color_style (t_gui_window *window, int style) +{ + window->current_color_attr &= !style; + /* TODO: change following function call */ + /*wattroff (window->win_chat, style);*/ +} + +/* + * gui_window_chat_reset_color_style: reset style for color + */ + +void +gui_window_chat_reset_color_style (t_gui_window *window) +{ + /* TODO: change following function call */ + /*wattroff (window->win_chat, window->current_color_attr);*/ + window->current_color_attr = 0; +} + +/* + * gui_window_chat_set_color: set color for a chat window + */ + +void +gui_window_chat_set_color (t_gui_window *window, int fg, int bg) +{ + /* TODO: write this function for Gtk */ + /*if (((fg == -1) || (fg == 99)) + && ((bg == -1) || (bg == 99))) + wattron (window->win_chat, COLOR_PAIR(63)); else { - /* TODO: display title for server window */ - } + if ((fg == -1) || (fg == 99)) + fg = WEECHAT_COLOR_WHITE; + if ((bg == -1) || (bg == 99)) + bg = 0; + wattron (window->win_chat, COLOR_PAIR((bg * 8) + fg)); + }*/ + (void) window; + (void) fg; + (void) bg; } /* - * gui_redraw_window_title: redraw title window + * gui_window_chat_set_weechat_color: set a WeeChat color for a chat window */ void -gui_redraw_window_title (t_gui_window *window) +gui_window_chat_set_weechat_color (t_gui_window *window, int weechat_color) { - /* TODO: manage splitted windows! */ - if (window != gui_current_window) - return; - - /* TODO: first delete window content */ - gui_draw_window_title (window); + gui_window_chat_reset_style (window); + gui_window_chat_set_style (window, + gui_color[weechat_color]->attributes); + gui_window_chat_set_color (window, + gui_color[weechat_color]->foreground, + gui_color[weechat_color]->background); } /* - * gui_get_line_num_splits: returns number of lines on window - * (depending on window width and type (server/channel) - * for alignment) + * gui_calculate_pos_size: calculate position and size for a window & sub-win */ -int -gui_get_line_num_splits (t_gui_window *window, t_gui_line *line) +void +gui_calculate_pos_size (t_gui_window *window) +{ + /* TODO: write this function for Gtk */ + (void) window; +} + +/* + * gui_draw_window_separator: draw window separation + */ + +void +gui_draw_window_separator (t_gui_window *window) { - int length, width; + /* TODO: write this function for Gtk */ + /*if (window->win_separator) + delwin (window->win_separator); - /* TODO: modify arbitraty value for non aligning messages on time/nick? */ - if (line->length_align >= window->win_chat_width - 5) + if (window->win_x > 0) { - length = line->length; - width = window->win_chat_width; - } - else + window->win_separator = newwin (window->win_height, + 1, + window->win_y, + window->win_x - 1); + gui_window_set_weechat_color (window->win_separator, COLOR_WIN_SEPARATOR); + wborder (window->win_separator, ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '); + wnoutrefresh (window->win_separator); + refresh (); + }*/ + (void) window; +} + +/* + * gui_draw_buffer_title: draw title window for a buffer + */ + +void +gui_draw_buffer_title (t_gui_buffer *buffer, int erase) +{ + /* TODO: write this function for Gtk */ + (void) buffer; + (void) erase; +} + +/* + * gui_word_get_next_char: returns next char of a word + * special chars like colors, bold, .. are skipped + */ + +char * +gui_word_get_next_char (t_gui_window *window, unsigned char *string, int apply_style) +{ + char str_fg[3], str_bg[3]; + int fg, bg, weechat_color; + + while (string[0]) { - length = line->length - line->length_align; - width = window->win_chat_width - line->length_align; + switch (string[0]) + { + case GUI_ATTR_BOLD_CHAR: + string++; + if (apply_style) + gui_window_chat_toggle_style (window, A_BOLD); + break; + case GUI_ATTR_COLOR_CHAR: + string++; + str_fg[0] = '\0'; + str_bg[0] = '\0'; + fg = 99; + bg = 99; + if (isdigit (string[0])) + { + str_fg[0] = string[0]; + str_fg[1] = '\0'; + string++; + if (isdigit (string[0])) + { + str_fg[1] = string[0]; + str_fg[2] = '\0'; + string++; + } + } + if (string[0] == ',') + { + string++; + if (isdigit (string[0])) + { + str_bg[0] = string[0]; + str_bg[1] = '\0'; + string++; + if (isdigit (string[0])) + { + str_bg[1] = string[0]; + str_bg[2] = '\0'; + string++; + } + } + } + if (apply_style) + { + if (str_fg[0] || str_bg[0]) + { + if (str_fg[0]) + sscanf (str_fg, "%d", &fg); + else + fg = window->current_style_fg; + if (str_bg[0]) + sscanf (str_bg, "%d", &bg); + else + bg = window->current_style_bg; + } + if (!str_fg[0] && !str_bg[0]) + gui_window_chat_reset_color_style (window); + window->current_style_fg = fg; + window->current_style_bg = bg; + gui_window_chat_set_color (window, fg, bg); + } + break; + case GUI_ATTR_RESET_CHAR: + string++; + if (apply_style) + gui_window_chat_reset_style (window); + break; + case GUI_ATTR_FIXED_CHAR: + string++; + break; + case GUI_ATTR_REVERSE_CHAR: + case GUI_ATTR_REVERSE2_CHAR: + string++; + if (apply_style) + gui_window_chat_toggle_style (window, A_REVERSE); + break; + case GUI_ATTR_WEECHAT_COLOR_CHAR: + string++; + if (isdigit (string[0]) && isdigit (string[1])) + { + str_fg[0] = string[0]; + str_fg[1] = string[1]; + str_fg[2] = '\0'; + string += 2; + if (apply_style) + { + sscanf (str_fg, "%d", &weechat_color); + gui_window_chat_set_weechat_color (window, weechat_color); + } + } + break; + case GUI_ATTR_WEECHAT_SET_CHAR: + string++; + switch (string[0]) + { + case GUI_ATTR_BOLD_CHAR: + string++; + if (apply_style) + gui_window_chat_set_color_style (window, A_BOLD); + break; + case GUI_ATTR_REVERSE_CHAR: + case GUI_ATTR_REVERSE2_CHAR: + string++; + if (apply_style) + gui_window_chat_set_color_style (window, A_REVERSE); + break; + case GUI_ATTR_UNDERLINE_CHAR: + string++; + if (apply_style) + gui_window_chat_set_color_style (window, A_UNDERLINE); + break; + } + break; + case GUI_ATTR_WEECHAT_REMOVE_CHAR: + string++; + switch (string[0]) + { + case GUI_ATTR_BOLD_CHAR: + string++; + if (apply_style) + gui_window_chat_remove_color_style (window, A_BOLD); + break; + case GUI_ATTR_REVERSE_CHAR: + case GUI_ATTR_REVERSE2_CHAR: + string++; + if (apply_style) + gui_window_chat_remove_color_style (window, A_REVERSE); + break; + case GUI_ATTR_UNDERLINE_CHAR: + string++; + if (apply_style) + gui_window_chat_remove_color_style (window, A_UNDERLINE); + break; + } + break; + case GUI_ATTR_ITALIC_CHAR: + string++; + break; + case GUI_ATTR_UNDERLINE_CHAR: + string++; + if (apply_style) + gui_window_chat_toggle_style (window, A_UNDERLINE); + break; + default: + if (string[0] < 32) + string++; + else + return utf8_next_char ((char *)string); + } + } - return (length % width == 0) ? (length / width) : ((length / width) + 1); + /* nothing found except color/attrib codes, so return NULL */ + return NULL; } /* - * gui_display_end_of_line: display end of a line in the chat window + * gui_display_word_raw: display word on chat buffer, letter by letter + * special chars like color, bold, .. are interpreted */ void -gui_display_end_of_line (t_gui_window *window, t_gui_line *line, int count) +gui_display_word_raw (t_gui_window *window, char *string) { - /* TODO: display end of line! */ + /*char *prev_char, *next_char, saved_char;*/ + + /* TODO: write this function for Gtk */ (void) window; - (void) line; - (void) count; + (void) string; } /* - * gui_display_line: display a line in the chat window - * if stop_at_end == 1, screen will not scroll and then we - * exit since chat window is full - * returns: 1 if stop_at_end == 0 or screen not full - * 0 if screen is full and if stop_at_end == 1 + * gui_display_word: display a word on chat buffer */ -int -gui_display_line (t_gui_window *window, t_gui_line *line, int stop_at_end) +void +gui_display_word (t_gui_window *window, + t_gui_line *line, + char *data, + char *end_offset, + int num_lines, int count, int *lines_displayed, int simulate) { - /* TODO: display line! */ + /*char *end_line, saved_char_end, saved_char; + int pos_saved_char, chars_to_display, num_displayed;*/ + + /* TODO: write this function for Gtk */ (void) window; (void) line; - (void) stop_at_end; - return 1; + (void) data; + (void) end_offset; + (void) num_lines; + (void) count; + (void) lines_displayed; + (void) simulate; } /* - * gui_draw_window_chat: draw chat window + * gui_get_word_info: returns info about next word: beginning, end, length */ void -gui_draw_window_chat (t_gui_window *window) +gui_get_word_info (t_gui_window *window, + char *data, + int *word_start_offset, int *word_end_offset, + int *word_length_with_spaces, int *word_length) { - /* TODO: manage splitted windows! */ - if (window != gui_current_window) - return; + char *start_data, *prev_char, *next_char; + int leading_spaces, char_size; + + *word_start_offset = 0; + *word_end_offset = 0; + *word_length_with_spaces = 0; + *word_length = 0; - /* TODO: draw chat window */ + start_data = data; + + leading_spaces = 1; + while (data && data[0]) + { + next_char = gui_word_get_next_char (window, (unsigned char *)data, 0); + if (next_char) + { + prev_char = utf8_prev_char (data, next_char); + if (prev_char) + { + if (prev_char[0] != ' ') + { + if (leading_spaces) + *word_start_offset = prev_char - start_data; + leading_spaces = 0; + char_size = next_char - prev_char; + *word_end_offset = next_char - start_data - 1; + (*word_length_with_spaces) += char_size; + (*word_length) += char_size; + } + else + { + if (leading_spaces) + (*word_length_with_spaces)++; + else + { + *word_end_offset = prev_char - start_data - 1; + return; + } + } + data = next_char; + } + } + else + { + *word_end_offset = data + strlen (data) - start_data - 1; + return; + } + } } /* - * gui_redraw_window_chat: redraw chat window + * gui_display_line: display a line in the chat window + * if count == 0, display whole line + * if count > 0, display 'count' lines (beginning from the end) + * if simulate == 1, nothing is displayed (for counting how + * many lines would have been lines displayed) + * returns: number of lines displayed (or simulated) */ -void -gui_redraw_window_chat (t_gui_window *window) +int +gui_display_line (t_gui_window *window, t_gui_line *line, int count, int simulate) { - /* TODO: manage splitted windows! */ - if (window != gui_current_window) - return; - - /* TODO: first delete window content */ - gui_draw_window_chat (window); + /* TODO: write this function for Gtk */ + (void) window; + (void) line; + (void) count; + (void) simulate; + return 1; } /* - * gui_draw_window_nick: draw nick window + * gui_calculate_line_diff: returns pointer to line & offset for a difference + * with given line */ void -gui_draw_window_nick (t_gui_window *window) +gui_calculate_line_diff (t_gui_window *window, t_gui_line **line, int *line_pos, + int difference) { - /* TODO: manage splitted windows! */ - if (window != gui_current_window) + int backward, current_size; + + if (!line || !line_pos) return; - /* TODO: display nicklist for Gtk GUI */ + backward = (difference < 0); + + if (!(*line)) + { + /* if looking backward, start at last line of buffer */ + if (backward) + { + *line = window->buffer->last_line; + if (!(*line)) + return; + current_size = gui_display_line (window, *line, 0, 1); + if (current_size == 0) + current_size = 1; + *line_pos = current_size - 1; + } + /* if looking forward, start at first line of buffer */ + else + { + *line = window->buffer->lines; + if (!(*line)) + return; + *line_pos = 0; + current_size = gui_display_line (window, *line, 0, 1); + } + } + else + current_size = gui_display_line (window, *line, 0, 1); + + while ((*line) && (difference != 0)) + { + /* looking backward */ + if (backward) + { + if (*line_pos > 0) + (*line_pos)--; + else + { + *line = (*line)->prev_line; + if (*line) + { + current_size = gui_display_line (window, *line, 0, 1); + if (current_size == 0) + current_size = 1; + *line_pos = current_size - 1; + } + } + difference++; + } + /* looking forward */ + else + { + if (*line_pos < current_size - 1) + (*line_pos)++; + else + { + *line = (*line)->next_line; + if (*line) + { + current_size = gui_display_line (window, *line, 0, 1); + if (current_size == 0) + current_size = 1; + *line_pos = 0; + } + } + difference--; + } + } + + /* first or last line reached */ + if (!(*line)) + { + if (backward) + { + /* first line reached */ + *line = window->buffer->lines; + *line_pos = 0; + } + else + { + /* last line reached => consider we'll display all until the end */ + *line_pos = 0; + } + } } /* - * gui_redraw_window_nick: redraw nick window + * gui_draw_buffer_chat: draw chat window for a buffer */ void -gui_redraw_window_nick (t_gui_window *window) +gui_draw_buffer_chat (t_gui_buffer *buffer, int erase) { - /* TODO: manage splitted windows! */ - if (window != gui_current_window) + /*t_gui_window *ptr_win; + t_gui_line *ptr_line; + t_irc_dcc *dcc_first, *dcc_selected, *ptr_dcc; + char format_empty[32]; + int i, j, line_pos, count, num_bars; + char *unit_name[] = { N_("bytes"), N_("Kb"), N_("Mb"), N_("Gb") }; + char *unit_format[] = { "%.0Lf", "%.1Lf", "%.02Lf", "%.02Lf" }; + long unit_divide[] = { 1, 1024, 1024*1024, 1024*1024,1024 }; + int num_unit; + char format[32], date[128], *buf; + struct tm *date_tmp;*/ + + if (!gui_ok) return; - /* TODO: first delete window content */ - gui_draw_window_nick (window); + /* TODO: write this function for Gtk */ + (void) buffer; + (void) erase; } /* - * gui_draw_window_status: draw status window + * gui_draw_buffer_chat_line: add a line to chat window for a buffer */ void -gui_draw_window_status (t_gui_window *window) +gui_draw_buffer_chat_line (t_gui_buffer *buffer, t_gui_line *line) { - /* TODO: manage splitted windows! */ - if (window != gui_current_window) - return; + t_gui_window *ptr_win; + unsigned char *text_without_color; + GtkTextIter start, end; - /* TODO: draw status window! */ + ptr_win = gui_buffer_find_window (buffer); + if (ptr_win) + { + text_without_color = gui_color_decode ((unsigned char *)(line->data), 0); + if (text_without_color) + { + gtk_text_buffer_insert_at_cursor (ptr_win->textbuffer_chat, + (char *)text_without_color, -1); + gtk_text_buffer_insert_at_cursor (ptr_win->textbuffer_chat, + "\n", -1); + gtk_text_buffer_get_bounds (ptr_win->textbuffer_chat, + &start, &end); + /* TODO */ + /*gtk_text_buffer_apply_tag (ptr_win->textbuffer_chat, ptr_win->texttag_chat, &start, &end);*/ + free (text_without_color); + } + } } /* - * gui_redraw_window_status: redraw status window + * gui_draw_buffer_nick: draw nick window for a buffer */ void -gui_redraw_window_status (t_gui_window *window) +gui_draw_buffer_nick (t_gui_buffer *buffer, int erase) { - /* TODO: manage splitted windows! */ - if (window != gui_current_window) + /*t_gui_window *ptr_win; + int i, j, x, y, column, max_length, nicks_displayed; + char format[32], format_empty[32]; + t_irc_nick *ptr_nick;*/ + + if (!gui_ok || !BUFFER_HAS_NICKLIST(buffer)) return; - /* TODO: first delete window content */ - gui_draw_window_status (window); + /* TODO: write this function for Gtk */ + (void) buffer; + (void) erase; } /* - * gui_draw_window_infobar: draw infobar window + * gui_draw_buffer_status: draw status window for a buffer */ void -gui_draw_window_infobar (t_gui_window *window) +gui_draw_buffer_status (t_gui_buffer *buffer, int erase) { - /* TODO: manage splitted windows! */ - if (window != gui_current_window) + /*t_gui_window *ptr_win; + t_weechat_hotlist *ptr_hotlist; + char format[32], str_nicks[32], *more; + int i, first_mode, x, server_pos, server_total; + int display_name, names_count;*/ + + /* make gcc happy */ + (void) buffer; + + if (!gui_ok) return; - /* TODO: draw infobar window! */ + /* TODO: write this function for Gtk */ + (void) buffer; + (void) erase; } /* - * gui_redraw_window_infobar: redraw infobar window + * gui_draw_buffer_infobar_time: draw time in infobar window */ void -gui_redraw_window_infobar (t_gui_window *window) +gui_draw_buffer_infobar_time (t_gui_buffer *buffer) { - /* TODO: manage splitted windows! */ - if (window != gui_current_window) + /*t_gui_window *ptr_win; + time_t time_seconds; + struct tm *local_time;*/ + + /* make gcc happy */ + (void) buffer; + + if (!gui_ok) return; - /* TODO: first delete window content */ - gui_draw_window_infobar (window); + /* TODO: write this function for Gtk */ + (void) buffer; } /* - * gui_draw_window_input: draw input window + * gui_draw_buffer_infobar: draw infobar window for a buffer */ void -gui_draw_window_input (t_gui_window *window) +gui_draw_buffer_infobar (t_gui_buffer *buffer, int erase) { - /* TODO: manage splitted windows! */ - if (window != gui_current_window) + /*t_gui_window *ptr_win; + time_t time_seconds; + struct tm *local_time; + char text_time[1024 + 1];*/ + + /* make gcc happy */ + (void) buffer; + + if (!gui_ok) return; - /* TODO: draw input window */ + /* TODO: write this function for Gtk */ + (void) buffer; + (void) erase; } /* - * gui_redraw_window_input: redraw input window + * gui_get_input_width: return input width (max # chars displayed) */ -void -gui_redraw_window_input (t_gui_window *window) +int +gui_get_input_width (t_gui_window *window, char *nick) { - /* TODO: manage splitted windows! */ - if (window != gui_current_window) - return; - - /* TODO: first delete window content */ - gui_draw_window_input (window); + if (CHANNEL(window->buffer)) + return (window->win_width - strlen (CHANNEL(window->buffer)->name) - + strlen (nick) - 4); + else + return (window->win_width - strlen (nick) - 3); } /* - * gui_redraw_window: redraw a window + * gui_draw_buffer_input: draw input window for a buffer */ void -gui_redraw_window (t_gui_window *window) +gui_draw_buffer_input (t_gui_buffer *buffer, int erase) { - /* TODO: manage splitted windows! */ - if (window != gui_current_window) + /*t_gui_window *ptr_win; + char format[32]; + char *ptr_nickname; + int input_width; + t_irc_dcc *dcc_selected;*/ + + if (!gui_ok) return; - gui_redraw_window_title (window); - gui_redraw_window_chat (window); - if (gui_window_has_nicklist (window)) - gui_redraw_window_nick (window); - gui_redraw_window_status (window); - gui_redraw_window_input (window); + /* TODO: write this function for Gtk */ + (void) buffer; + (void) erase; } /* - * gui_switch_to_window: switch to another window + * gui_redraw_buffer: redraw a buffer */ void -gui_switch_to_window (t_gui_window *window) +gui_redraw_buffer (t_gui_buffer *buffer) { t_gui_window *ptr_win; - GtkTextIter start, end; + + if (!gui_ok) + return; for (ptr_win = gui_windows; ptr_win; ptr_win = ptr_win->next_window) { - if (ptr_win->is_displayed) + if (ptr_win->buffer == buffer) { - /* TODO: manage splitted windows */ - ptr_win->is_displayed = 0; - break; + gui_draw_buffer_title (buffer, 1); + gui_draw_buffer_chat (buffer, 1); + if (ptr_win->win_nick) + gui_draw_buffer_nick (buffer, 1); + gui_draw_buffer_status (buffer, 1); + if (cfg_look_infobar) + gui_draw_buffer_infobar (buffer, 1); + gui_draw_buffer_input (buffer, 1); } } +} + +/* + * gui_switch_to_buffer: switch to another buffer + */ + +void +gui_switch_to_buffer (t_gui_window *window, t_gui_buffer *buffer) +{ + GtkTextIter start, end; + + if (window->buffer->num_displayed > 0) + window->buffer->num_displayed--; + if (window->buffer != buffer) + { + window->buffer->last_read_line = window->buffer->last_line; + if (buffer->last_read_line == buffer->last_line) + buffer->last_read_line = NULL; + } + + window->buffer = buffer; + window->win_nick_start = 0; gui_calculate_pos_size (window); if (!window->textview_chat) @@ -460,13 +1334,12 @@ gui_switch_to_window (t_gui_window *window) window->textbuffer_chat = gtk_text_buffer_new (NULL); gtk_text_view_set_buffer (GTK_TEXT_VIEW (window->textview_chat), window->textbuffer_chat); - window->texttag_chat = gtk_text_buffer_create_tag(window->textbuffer_chat, "courier", "font_family", "lucida"); + /*window->texttag_chat = gtk_text_buffer_create_tag(window->textbuffer_chat, "courier", "font_family", "lucida");*/ gtk_text_buffer_get_bounds (window->textbuffer_chat, &start, &end); gtk_text_buffer_apply_tag (window->textbuffer_chat, window->texttag_chat, &start, &end); } - if (WIN_IS_CHANNEL (window) && !window->textbuffer_nicklist) + if (BUFFER_IS_CHANNEL(buffer) && !window->textbuffer_nicklist) { - window->textview_nicklist = gtk_text_view_new (); gtk_widget_show (window->textview_nicklist); gtk_container_add (GTK_CONTAINER (scrolledwindow_nick), window->textview_nicklist); @@ -477,91 +1350,225 @@ gui_switch_to_window (t_gui_window *window) gtk_text_view_set_buffer (GTK_TEXT_VIEW (window->textview_nicklist), window->textbuffer_nicklist); } - /* change current window to the new window */ - gui_current_window = window; + window->start_line = NULL; + window->start_line_pos = 0; - window->is_displayed = 1; - window->unread_data = 0; + buffer->num_displayed++; + + hotlist_remove_buffer (buffer); } /* - * gui_switch_to_previous_window: switch to previous window + * gui_window_page_up: display previous page on buffer */ void -gui_switch_to_previous_window () +gui_window_page_up (t_gui_window *window) { - /* if only one windows then return */ - if (gui_windows == last_gui_window) + if (!gui_ok) return; - if (gui_current_window->prev_window) - gui_switch_to_window (gui_current_window->prev_window); - else - gui_switch_to_window (last_gui_window); - gui_redraw_window (gui_current_window); + if (!window->first_line_displayed) + { + gui_calculate_line_diff (window, &window->start_line, + &window->start_line_pos, + (window->start_line) ? + (-1) * (window->win_chat_height - 1) : + (-1) * ((window->win_chat_height - 1) * 2)); + gui_draw_buffer_chat (window->buffer, 0); + gui_draw_buffer_status (window->buffer, 0); + } } /* - * gui_switch_to_next_window: switch to next window + * gui_window_page_down: display next page on buffer */ void -gui_switch_to_next_window () +gui_window_page_down (t_gui_window *window) { - /* if only one windows then return */ - if (gui_windows == last_gui_window) + t_gui_line *ptr_line; + int line_pos; + + if (!gui_ok) return; - if (gui_current_window->next_window) - gui_switch_to_window (gui_current_window->next_window); - else - gui_switch_to_window (gui_windows); - gui_redraw_window (gui_current_window); + if (window->start_line) + { + gui_calculate_line_diff (window, &window->start_line, + &window->start_line_pos, + window->win_chat_height - 1); + + /* check if we can display all */ + ptr_line = window->start_line; + line_pos = window->start_line_pos; + gui_calculate_line_diff (window, &ptr_line, + &line_pos, + window->win_chat_height - 1); + if (!ptr_line) + { + window->start_line = NULL; + window->start_line_pos = 0; + } + + gui_draw_buffer_chat (window->buffer, 0); + gui_draw_buffer_status (window->buffer, 0); + } +} + +/* + * gui_window_scroll_up: display previous few lines in buffer + */ + +void +gui_window_scroll_up (t_gui_window *window) +{ + if (!gui_ok) + return; + + if (!window->first_line_displayed) + { + gui_calculate_line_diff (window, &window->start_line, + &window->start_line_pos, + (window->start_line) ? + (-1) * cfg_look_scroll_amount : + (-1) * ( (window->win_chat_height - 1) + cfg_look_scroll_amount)); + gui_draw_buffer_chat (window->buffer, 0); + gui_draw_buffer_status (window->buffer, 0); + } } /* - * gui_move_page_up: display previous page on window + * gui_window_scroll_down: display next few lines in buffer */ void -gui_move_page_up () +gui_window_scroll_down (t_gui_window *window) { - if (!gui_current_window->first_line_displayed) + t_gui_line *ptr_line; + int line_pos; + + if (!gui_ok) + return; + + if (window->start_line) { - gui_current_window->sub_lines += gui_current_window->win_chat_height - 1; - gui_redraw_window_chat (gui_current_window); - gui_redraw_window_status (gui_current_window); + gui_calculate_line_diff (window, &window->start_line, + &window->start_line_pos, + cfg_look_scroll_amount); + + /* check if we can display all */ + ptr_line = window->start_line; + line_pos = window->start_line_pos; + gui_calculate_line_diff (window, &ptr_line, + &line_pos, + window->win_chat_height - 1); + + if (!ptr_line) + { + window->start_line = NULL; + window->start_line_pos = 0; + } + + gui_draw_buffer_chat (window->buffer, 0); + gui_draw_buffer_status (window->buffer, 0); + } +} + +/* + * gui_window_nick_beginning: go to beginning of nicklist + */ + +void +gui_window_nick_beginning (t_gui_window *window) +{ + if (!gui_ok) + return; + + if (BUFFER_HAS_NICKLIST(window->buffer)) + { + if (window->win_nick_start > 0) + { + window->win_nick_start = 0; + gui_draw_buffer_nick (window->buffer, 1); + } + } +} + +/* + * gui_window_nick_end: go to the end of nicklist + */ + +void +gui_window_nick_end (t_gui_window *window) +{ + int new_start; + + if (!gui_ok) + return; + + if (BUFFER_HAS_NICKLIST(window->buffer)) + { + new_start = + CHANNEL(window->buffer)->nicks_count - window->win_nick_height; + if (new_start < 0) + new_start = 0; + else if (new_start >= 1) + new_start++; + + if (new_start != window->win_nick_start) + { + window->win_nick_start = new_start; + gui_draw_buffer_nick (window->buffer, 1); + } } } /* - * gui_move_page_down: display next page on window + * gui_window_nick_page_up: scroll one page up in nicklist */ void -gui_move_page_down () +gui_window_nick_page_up (t_gui_window *window) { - if (gui_current_window->sub_lines > 0) + if (!gui_ok) + return; + + if (BUFFER_HAS_NICKLIST(window->buffer)) { - gui_current_window->sub_lines -= gui_current_window->win_chat_height - 1; - if (gui_current_window->sub_lines < 0) - gui_current_window->sub_lines = 0; - if (gui_current_window->sub_lines == 0) - gui_current_window->unread_data = 0; - gui_redraw_window_chat (gui_current_window); - gui_redraw_window_status (gui_current_window); + if (window->win_nick_start > 0) + { + window->win_nick_start -= (window->win_nick_height - 1); + if (window->win_nick_start <= 1) + window->win_nick_start = 0; + gui_draw_buffer_nick (window->buffer, 1); + } } } /* - * gui_gtk_resize_handler: called when term size is modified + * gui_window_nick_page_down: scroll one page down in nicklist */ void -gui_gtk_resize_handler () +gui_window_nick_page_down (t_gui_window *window) { - /* TODO: write resize handler for Gtk */ + if (!gui_ok) + return; + + if (BUFFER_HAS_NICKLIST(window->buffer)) + { + if ((CHANNEL(window->buffer)->nicks_count > window->win_nick_height) + && (window->win_nick_start + window->win_nick_height - 1 + < CHANNEL(window->buffer)->nicks_count)) + { + if (window->win_nick_start == 0) + window->win_nick_start += (window->win_nick_height - 1); + else + window->win_nick_start += (window->win_nick_height - 2); + gui_draw_buffer_nick (window->buffer, 1); + } + } } /* @@ -579,34 +1586,562 @@ gui_window_init_subwindows (t_gui_window *window) } /* + * gui_window_auto_resize: auto-resize all windows, according to % of global size + * This function is called after a terminal resize. + * Returns 0 if ok, -1 if all window should be merged + * (not enough space according to windows %) + */ + +int +gui_window_auto_resize (t_gui_window_tree *tree, + int x, int y, int width, int height, + int simulate) +{ + int size1, size2; + + if (tree) + { + if (tree->window) + { + if ((width < WINDOW_MIN_WIDTH) || (height < WINDOW_MIN_HEIGHT)) + return -1; + if (!simulate) + { + tree->window->win_x = x; + tree->window->win_y = y; + tree->window->win_width = width; + tree->window->win_height = height; + } + } + else + { + if (tree->split_horiz) + { + size1 = (height * tree->split_pct) / 100; + size2 = height - size1; + if (gui_window_auto_resize (tree->child1, x, y + size1, + width, size2, simulate) < 0) + return -1; + if (gui_window_auto_resize (tree->child2, x, y, + width, size1, simulate) < 0) + return -1; + } + else + { + size1 = (width * tree->split_pct) / 100; + size2 = width - size1 - 1; + if (gui_window_auto_resize (tree->child1, x, y, + size1, height, simulate) < 0) + return -1; + if (gui_window_auto_resize (tree->child2, x + size1 + 1, y, + size2, height, simulate) < 0) + return -1; + } + } + } + return 0; +} + +/* + * gui_refresh_windows: auto resize and refresh all windows + */ + +void +gui_refresh_windows () +{ + /*t_gui_window *ptr_win, *old_current_window;*/ + + if (gui_ok) + { + /* TODO: write this function for Gtk */ + } +} + +/* + * gui_window_split_horiz: split a window horizontally + */ + +void +gui_window_split_horiz (t_gui_window *window, int pourcentage) +{ + t_gui_window *new_window; + int height1, height2; + + if (!gui_ok) + return; + + height1 = (window->win_height * pourcentage) / 100; + height2 = window->win_height - height1; + + if ((height1 >= WINDOW_MIN_HEIGHT) && (height2 >= WINDOW_MIN_HEIGHT) + && (pourcentage > 0) && (pourcentage <= 100)) + { + if ((new_window = gui_window_new (window, + window->win_x, window->win_y, + window->win_width, height1, + 100, pourcentage))) + { + /* reduce old window height (bottom window) */ + window->win_y = new_window->win_y + new_window->win_height; + window->win_height = height2; + window->win_height_pct = 100 - pourcentage; + + /* assign same buffer for new window (top window) */ + new_window->buffer = window->buffer; + new_window->buffer->num_displayed++; + + gui_switch_to_buffer (window, window->buffer); + + gui_current_window = new_window; + gui_switch_to_buffer (gui_current_window, gui_current_window->buffer); + gui_redraw_buffer (gui_current_window->buffer); + } + } +} + +/* + * gui_window_split_vertic: split a window vertically + */ + +void +gui_window_split_vertic (t_gui_window *window, int pourcentage) +{ + t_gui_window *new_window; + int width1, width2; + + if (!gui_ok) + return; + + width1 = (window->win_width * pourcentage) / 100; + width2 = window->win_width - width1 - 1; + + if ((width1 >= WINDOW_MIN_WIDTH) && (width2 >= WINDOW_MIN_WIDTH) + && (pourcentage > 0) && (pourcentage <= 100)) + { + if ((new_window = gui_window_new (window, + window->win_x + width1 + 1, window->win_y, + width2, window->win_height, + pourcentage, 100))) + { + /* reduce old window height (left window) */ + window->win_width = width1; + window->win_width_pct = 100 - pourcentage; + + /* assign same buffer for new window (right window) */ + new_window->buffer = window->buffer; + new_window->buffer->num_displayed++; + + gui_switch_to_buffer (window, window->buffer); + + gui_current_window = new_window; + gui_switch_to_buffer (gui_current_window, gui_current_window->buffer); + gui_redraw_buffer (gui_current_window->buffer); + + /* create & draw separator */ + gui_draw_window_separator (gui_current_window); + } + } +} + +/* + * gui_window_resize: resize window + */ + +void +gui_window_resize (t_gui_window *window, int pourcentage) +{ + /* TODO: write this function for Gtk */ + (void) window; + (void) pourcentage; +} + +/* + * gui_window_merge: merge window with its sister + */ + +int +gui_window_merge (t_gui_window *window) +{ + t_gui_window_tree *parent, *sister; + + parent = window->ptr_tree->parent_node; + if (parent) + { + sister = (parent->child1->window == window) ? + parent->child2 : parent->child1; + + if (!(sister->window)) + return 0; + + if (window->win_y == sister->window->win_y) + { + /* horizontal merge */ + window->win_width += sister->window->win_width + 1; + window->win_width_pct += sister->window->win_width_pct; + } + else + { + /* vertical merge */ + window->win_height += sister->window->win_height; + window->win_height_pct += sister->window->win_height_pct; + } + if (sister->window->win_x < window->win_x) + window->win_x = sister->window->win_x; + if (sister->window->win_y < window->win_y) + window->win_y = sister->window->win_y; + + gui_window_free (sister->window); + gui_window_tree_node_to_leaf (parent, window); + + gui_switch_to_buffer (window, window->buffer); + gui_redraw_buffer (window->buffer); + return 1; + } + return 0; +} + +/* + * gui_window_merge_all: merge all windows into only one + */ + +void +gui_window_merge_all (t_gui_window *window) +{ + /* TODO: write this function for Gtk */ + (void) window; +} + +/* + * gui_window_side_by_side: return a code about position of 2 windows: + * 0 = they're not side by side + * 1 = side by side (win2 is over the win1) + * 2 = side by side (win2 on the right) + * 3 = side by side (win2 below win1) + * 4 = side by side (win2 on the left) + */ + +int +gui_window_side_by_side (t_gui_window *win1, t_gui_window *win2) +{ + /* win2 over win1 ? */ + if (win2->win_y + win2->win_height == win1->win_y) + { + if (win2->win_x >= win1->win_x + win1->win_width) + return 0; + if (win2->win_x + win2->win_width <= win1->win_x) + return 0; + return 1; + } + + /* win2 on the right ? */ + if (win2->win_x == win1->win_x + win1->win_width + 1) + { + if (win2->win_y >= win1->win_y + win1->win_height) + return 0; + if (win2->win_y + win2->win_height <= win1->win_y) + return 0; + return 2; + } + + /* win2 below win1 ? */ + if (win2->win_y == win1->win_y + win1->win_height) + { + if (win2->win_x >= win1->win_x + win1->win_width) + return 0; + if (win2->win_x + win2->win_width <= win1->win_x) + return 0; + return 3; + } + + /* win2 on the left ? */ + if (win2->win_x + win2->win_width + 1 == win1->win_x) + { + if (win2->win_y >= win1->win_y + win1->win_height) + return 0; + if (win2->win_y + win2->win_height <= win1->win_y) + return 0; + return 4; + } + + return 0; +} + +/* + * gui_window_switch_up: search and switch to a window over current window + */ + +void +gui_window_switch_up (t_gui_window *window) +{ + t_gui_window *ptr_win; + + for (ptr_win = gui_windows; ptr_win; + ptr_win = ptr_win->next_window) + { + if ((ptr_win != window) && + (gui_window_side_by_side (window, ptr_win) == 1)) + { + gui_current_window = ptr_win; + gui_switch_to_buffer (gui_current_window, gui_current_window->buffer); + gui_redraw_buffer (gui_current_window->buffer); + return; + } + } +} + +/* + * gui_window_switch_down: search and switch to a window below current window + */ + +void +gui_window_switch_down (t_gui_window *window) +{ + t_gui_window *ptr_win; + + for (ptr_win = gui_windows; ptr_win; + ptr_win = ptr_win->next_window) + { + if ((ptr_win != window) && + (gui_window_side_by_side (window, ptr_win) == 3)) + { + gui_current_window = ptr_win; + gui_switch_to_buffer (gui_current_window, gui_current_window->buffer); + gui_redraw_buffer (gui_current_window->buffer); + return; + } + } +} + +/* + * gui_window_switch_left: search and switch to a window on the left of current window + */ + +void +gui_window_switch_left (t_gui_window *window) +{ + t_gui_window *ptr_win; + + for (ptr_win = gui_windows; ptr_win; + ptr_win = ptr_win->next_window) + { + if ((ptr_win != window) && + (gui_window_side_by_side (window, ptr_win) == 4)) + { + gui_current_window = ptr_win; + gui_switch_to_buffer (gui_current_window, gui_current_window->buffer); + gui_redraw_buffer (gui_current_window->buffer); + return; + } + } +} + +/* + * gui_window_switch_right: search and switch to a window on the right of current window + */ + +void +gui_window_switch_right (t_gui_window *window) +{ + t_gui_window *ptr_win; + + for (ptr_win = gui_windows; ptr_win; + ptr_win = ptr_win->next_window) + { + if ((ptr_win != window) && + (gui_window_side_by_side (window, ptr_win) == 2)) + { + gui_current_window = ptr_win; + gui_switch_to_buffer (gui_current_window, gui_current_window->buffer); + gui_redraw_buffer (gui_current_window->buffer); + return; + } + } +} + +/* + * gui_refresh_screen: called when term size is modified + */ + +void +gui_refresh_screen () +{ + /* TODO: write this function for Gtk */ +} + +/* + * gui_refresh_screen_sigwinch: called when signal SIGWINCH is received + */ + +void +gui_refresh_screen_sigwinch () +{ + gui_refresh_screen (); + signal (SIGWINCH, gui_refresh_screen_sigwinch); +} + +/* * gui_pre_init: pre-initialize GUI (called before gui_init) */ void gui_pre_init (int *argc, char **argv[]) { - /* Initialise Gtk+ */ + /* Initialise Gtk */ gtk_init (argc, argv); } /* + * gui_init_color_pairs: init color pairs + */ + +void +gui_init_color_pairs () +{ + /* This function does nothing in Gtk GUI */ +} + +/* + * gui_init_weechat_colors: init WeeChat colors + */ + +void +gui_init_weechat_colors () +{ + int i; + + /* init WeeChat colors */ + gui_color[COLOR_WIN_SEPARATOR] = gui_color_build (COLOR_WIN_SEPARATOR, cfg_col_separator, cfg_col_separator); + gui_color[COLOR_WIN_TITLE] = gui_color_build (COLOR_WIN_TITLE, cfg_col_title, cfg_col_title_bg); + gui_color[COLOR_WIN_CHAT] = gui_color_build (COLOR_WIN_CHAT, cfg_col_chat, cfg_col_chat_bg); + gui_color[COLOR_WIN_CHAT_TIME] = gui_color_build (COLOR_WIN_CHAT_TIME, cfg_col_chat_time, cfg_col_chat_bg); + gui_color[COLOR_WIN_CHAT_TIME_SEP] = gui_color_build (COLOR_WIN_CHAT_TIME_SEP, cfg_col_chat_time_sep, cfg_col_chat_bg); + gui_color[COLOR_WIN_CHAT_PREFIX1] = gui_color_build (COLOR_WIN_CHAT_PREFIX1, cfg_col_chat_prefix1, cfg_col_chat_bg); + gui_color[COLOR_WIN_CHAT_PREFIX2] = gui_color_build (COLOR_WIN_CHAT_PREFIX2, cfg_col_chat_prefix2, cfg_col_chat_bg); + gui_color[COLOR_WIN_CHAT_SERVER] = gui_color_build (COLOR_WIN_CHAT_SERVER, cfg_col_chat_server, cfg_col_chat_bg); + gui_color[COLOR_WIN_CHAT_JOIN] = gui_color_build (COLOR_WIN_CHAT_JOIN, cfg_col_chat_join, cfg_col_chat_bg); + gui_color[COLOR_WIN_CHAT_PART] = gui_color_build (COLOR_WIN_CHAT_PART, cfg_col_chat_part, cfg_col_chat_bg); + gui_color[COLOR_WIN_CHAT_NICK] = gui_color_build (COLOR_WIN_CHAT_NICK, cfg_col_chat_nick, cfg_col_chat_bg); + gui_color[COLOR_WIN_CHAT_HOST] = gui_color_build (COLOR_WIN_CHAT_HOST, cfg_col_chat_host, cfg_col_chat_bg); + gui_color[COLOR_WIN_CHAT_CHANNEL] = gui_color_build (COLOR_WIN_CHAT_CHANNEL, cfg_col_chat_channel, cfg_col_chat_bg); + gui_color[COLOR_WIN_CHAT_DARK] = gui_color_build (COLOR_WIN_CHAT_DARK, cfg_col_chat_dark, cfg_col_chat_bg); + gui_color[COLOR_WIN_CHAT_HIGHLIGHT] = gui_color_build (COLOR_WIN_CHAT_HIGHLIGHT, cfg_col_chat_highlight, cfg_col_chat_bg); + gui_color[COLOR_WIN_CHAT_READ_MARKER] = gui_color_build (COLOR_WIN_CHAT_READ_MARKER, cfg_col_chat_read_marker, cfg_col_chat_read_marker_bg); + gui_color[COLOR_WIN_STATUS] = gui_color_build (COLOR_WIN_STATUS, cfg_col_status, cfg_col_status_bg); + gui_color[COLOR_WIN_STATUS_DELIMITERS] = gui_color_build (COLOR_WIN_STATUS_DELIMITERS, cfg_col_status_delimiters, cfg_col_status_bg); + gui_color[COLOR_WIN_STATUS_CHANNEL] = gui_color_build (COLOR_WIN_STATUS_CHANNEL, cfg_col_status_channel, cfg_col_status_bg); + gui_color[COLOR_WIN_STATUS_DATA_MSG] = gui_color_build (COLOR_WIN_STATUS_DATA_MSG, cfg_col_status_data_msg, cfg_col_status_bg); + gui_color[COLOR_WIN_STATUS_DATA_PRIVATE] = gui_color_build (COLOR_WIN_STATUS_DATA_PRIVATE, cfg_col_status_data_private, cfg_col_status_bg); + gui_color[COLOR_WIN_STATUS_DATA_HIGHLIGHT] = gui_color_build (COLOR_WIN_STATUS_DATA_HIGHLIGHT, cfg_col_status_data_highlight, cfg_col_status_bg); + gui_color[COLOR_WIN_STATUS_DATA_OTHER] = gui_color_build (COLOR_WIN_STATUS_DATA_OTHER, cfg_col_status_data_other, cfg_col_status_bg); + gui_color[COLOR_WIN_STATUS_MORE] = gui_color_build (COLOR_WIN_STATUS_MORE, cfg_col_status_more, cfg_col_status_bg); + gui_color[COLOR_WIN_INFOBAR] = gui_color_build (COLOR_WIN_INFOBAR, cfg_col_infobar, cfg_col_infobar_bg); + gui_color[COLOR_WIN_INFOBAR_DELIMITERS] = gui_color_build (COLOR_WIN_INFOBAR_DELIMITERS, cfg_col_infobar_delimiters, cfg_col_infobar_bg); + gui_color[COLOR_WIN_INFOBAR_HIGHLIGHT] = gui_color_build (COLOR_WIN_INFOBAR_HIGHLIGHT, cfg_col_infobar_highlight, cfg_col_infobar_bg); + gui_color[COLOR_WIN_INPUT] = gui_color_build (COLOR_WIN_INPUT, cfg_col_input, cfg_col_input_bg); + gui_color[COLOR_WIN_INPUT_CHANNEL] = gui_color_build (COLOR_WIN_INPUT_CHANNEL, cfg_col_input_channel, cfg_col_input_bg); + gui_color[COLOR_WIN_INPUT_NICK] = gui_color_build (COLOR_WIN_INPUT_NICK, cfg_col_input_nick, cfg_col_input_bg); + gui_color[COLOR_WIN_INPUT_DELIMITERS] = gui_color_build (COLOR_WIN_INPUT_DELIMITERS, cfg_col_input_delimiters, cfg_col_input_bg); + gui_color[COLOR_WIN_NICK] = gui_color_build (COLOR_WIN_NICK, cfg_col_nick, cfg_col_nick_bg); + gui_color[COLOR_WIN_NICK_AWAY] = gui_color_build (COLOR_WIN_NICK_AWAY, cfg_col_nick_away, cfg_col_nick_bg); + gui_color[COLOR_WIN_NICK_CHANOWNER] = gui_color_build (COLOR_WIN_NICK_CHANOWNER, cfg_col_nick_chanowner, cfg_col_nick_bg); + gui_color[COLOR_WIN_NICK_CHANADMIN] = gui_color_build (COLOR_WIN_NICK_CHANADMIN, cfg_col_nick_chanadmin, cfg_col_nick_bg); + gui_color[COLOR_WIN_NICK_OP] = gui_color_build (COLOR_WIN_NICK_OP, cfg_col_nick_op, cfg_col_nick_bg); + gui_color[COLOR_WIN_NICK_HALFOP] = gui_color_build (COLOR_WIN_NICK_HALFOP, cfg_col_nick_halfop, cfg_col_nick_bg); + gui_color[COLOR_WIN_NICK_VOICE] = gui_color_build (COLOR_WIN_NICK_VOICE, cfg_col_nick_voice, cfg_col_nick_bg); + gui_color[COLOR_WIN_NICK_MORE] = gui_color_build (COLOR_WIN_NICK_MORE, cfg_col_nick_more, cfg_col_nick_bg); + gui_color[COLOR_WIN_NICK_SEP] = gui_color_build (COLOR_WIN_NICK_SEP, cfg_col_nick_sep, cfg_col_nick_bg); + gui_color[COLOR_WIN_NICK_SELF] = gui_color_build (COLOR_WIN_NICK_SELF, cfg_col_nick_self, cfg_col_nick_bg); + gui_color[COLOR_WIN_NICK_PRIVATE] = gui_color_build (COLOR_WIN_NICK_PRIVATE, cfg_col_nick_private, cfg_col_nick_bg); + + for (i = 0; i < COLOR_WIN_NICK_NUMBER; i++) + { + gui_color[COLOR_WIN_NICK_1 + i] = gui_color_build (COLOR_WIN_NICK_1 + i, cfg_col_nick_colors[i], cfg_col_chat_bg); + } + + gui_color[COLOR_DCC_SELECTED] = gui_color_build (COLOR_DCC_SELECTED, cfg_col_dcc_selected, cfg_col_chat_bg); + gui_color[COLOR_DCC_WAITING] = gui_color_build (COLOR_DCC_WAITING, cfg_col_dcc_waiting, cfg_col_chat_bg); + gui_color[COLOR_DCC_CONNECTING] = gui_color_build (COLOR_DCC_CONNECTING, cfg_col_dcc_connecting, cfg_col_chat_bg); + gui_color[COLOR_DCC_ACTIVE] = gui_color_build (COLOR_DCC_ACTIVE, cfg_col_dcc_active, cfg_col_chat_bg); + gui_color[COLOR_DCC_DONE] = gui_color_build (COLOR_DCC_DONE, cfg_col_dcc_done, cfg_col_chat_bg); + gui_color[COLOR_DCC_FAILED] = gui_color_build (COLOR_DCC_FAILED, cfg_col_dcc_failed, cfg_col_chat_bg); + gui_color[COLOR_DCC_ABORTED] = gui_color_build (COLOR_DCC_ABORTED, cfg_col_dcc_aborted, cfg_col_chat_bg); +} + +/* + * gui_rebuild_weechat_colors: rebuild WeeChat colors + */ + +void +gui_rebuild_weechat_colors () +{ + int i; + + for (i = 0; i < NUM_COLORS; i++) + { + if (gui_color[i]) + { + if (gui_color[i]->string) + free (gui_color[i]->string); + free (gui_color[i]); + gui_color[i] = NULL; + } + } + gui_init_weechat_colors (); +} + +/* * gui_init_colors: init GUI colors */ void gui_init_colors () { - /* TODO: init colors for Gtk */ + gui_init_color_pairs (); + gui_init_weechat_colors (); } /* - * gui_set_window_title: set window title + * gui_set_window_title: set terminal title */ void gui_set_window_title () { - /* TODO: set window title for Gtk */ + char *envterm = getenv ("TERM"); + + if (envterm) + { + if (strcmp( envterm, "sun-cmd") == 0) + printf ("\033]l%s %s\033\\", PACKAGE_NAME, PACKAGE_VERSION); + else if (strcmp(envterm, "hpterm") == 0) + printf ("\033&f0k%dD%s %s", strlen(PACKAGE_NAME) + + strlen(PACKAGE_VERSION) + 1, + PACKAGE_NAME, PACKAGE_VERSION); + /* the following term supports the xterm excapes */ + else if (strncmp (envterm, "xterm", 5) == 0 + || strncmp (envterm, "rxvt", 4) == 0 + || strcmp (envterm, "Eterm") == 0 + || strcmp (envterm, "aixterm") == 0 + || strcmp (envterm, "iris-ansi") == 0 + || strcmp (envterm, "dtterm") == 0) + printf ("\33]0;%s %s\7", PACKAGE_NAME, PACKAGE_VERSION); + else if (strcmp (envterm, "screen") == 0) + { + printf ("\033k%s %s\033\\", PACKAGE_NAME, PACKAGE_VERSION); + /* tryning to set the title of a backgrounded xterm like terminal */ + printf ("\33]0;%s %s\7", PACKAGE_NAME, PACKAGE_VERSION); + } + } +} + +/* + * gui_reset_window_title: reset terminal title + */ + +void +gui_reset_window_title () +{ + /* This function does nothing in Gtk GUI */ } /* @@ -616,9 +2151,28 @@ gui_set_window_title () void gui_init () { + GdkColor color_fg, color_bg; + GtkRcStyle *rc_style; + + gui_init_colors (); + + gui_infobar = NULL; + + gui_ok = 1; + + /* init clipboard buffer */ + gui_input_clipboard = NULL; + + /* create Gtk widgets */ + + gdk_color_parse ("white", &color_fg); + gdk_color_parse ("black", &color_bg); + gtk_main_window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_set_title (GTK_WINDOW (gtk_main_window), PACKAGE_STRING); + g_signal_connect (G_OBJECT (gtk_main_window), "destroy", gtk_main_quit, NULL); + vbox1 = gtk_vbox_new (FALSE, 0); gtk_widget_show (vbox1); gtk_container_add (GTK_CONTAINER (gtk_main_window), vbox1); @@ -626,6 +2180,8 @@ gui_init () entry_topic = gtk_entry_new (); gtk_widget_show (entry_topic); gtk_box_pack_start (GTK_BOX (vbox1), entry_topic, FALSE, FALSE, 0); + gtk_widget_modify_text (entry_topic, GTK_STATE_NORMAL, &color_fg); + gtk_widget_modify_base (entry_topic, GTK_STATE_NORMAL, &color_bg); notebook1 = gtk_notebook_new (); gtk_widget_show (notebook1); @@ -640,19 +2196,32 @@ gui_init () gtk_widget_show (hbox1); gtk_box_pack_start (GTK_BOX (vbox2), hbox1, TRUE, TRUE, 0); + hpaned1 = gtk_hpaned_new (); + gtk_widget_show (hpaned1); + gtk_box_pack_start (GTK_BOX (hbox1), hpaned1, TRUE, TRUE, 0); + gtk_paned_set_position (GTK_PANED (hpaned1), 0); + scrolledwindow_chat = gtk_scrolled_window_new (NULL, NULL); gtk_widget_show (scrolledwindow_chat); - gtk_box_pack_start (GTK_BOX (hbox1), scrolledwindow_chat, TRUE, TRUE, 0); + gtk_paned_pack1 (GTK_PANED (hpaned1), scrolledwindow_chat, FALSE, TRUE); + //gtk_box_pack_start (GTK_PANED (hpaned1), scrolledwindow_chat, TRUE, TRUE, 0); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow_chat), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS); + gtk_widget_modify_text (scrolledwindow_chat, GTK_STATE_NORMAL, &color_fg); + gtk_widget_modify_base (scrolledwindow_chat, GTK_STATE_NORMAL, &color_bg); scrolledwindow_nick = gtk_scrolled_window_new (NULL, NULL); gtk_widget_show (scrolledwindow_nick); - gtk_box_pack_start (GTK_BOX (hbox1), scrolledwindow_nick, TRUE, TRUE, 0); + gtk_paned_pack2 (GTK_PANED (hpaned1), scrolledwindow_nick, FALSE, TRUE); + //gtk_box_pack_start (GTK_PANED (hpaned1), scrolledwindow_nick, TRUE, TRUE, 0); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow_nick), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS); + gtk_widget_modify_text (scrolledwindow_nick, GTK_STATE_NORMAL, &color_fg); + gtk_widget_modify_base (scrolledwindow_nick, GTK_STATE_NORMAL, &color_bg); entry_input = gtk_entry_new (); gtk_widget_show (entry_input); gtk_box_pack_start (GTK_BOX (vbox2), entry_input, FALSE, FALSE, 0); + gtk_widget_modify_text (entry_input, GTK_STATE_NORMAL, &color_fg); + gtk_widget_modify_base (entry_input, GTK_STATE_NORMAL, &color_bg); label1 = gtk_label_new (_("server")); gtk_widget_show (label1); @@ -661,11 +2230,19 @@ gui_init () gtk_widget_show_all (gtk_main_window); - /* create a new window */ - gui_current_window = gui_window_new (NULL, NULL, 1 /*0, 0, COLS, LINES*/); - - /* TODO: set gui_ready to 1 when Gtk display functions will be ok */ - gui_ready = 1; + /* create new window/buffer */ + if (gui_window_new (NULL, 0, 0, 0, 0, 100, 100)) + { + gui_current_window = gui_windows; + gui_buffer_new (gui_windows, NULL, NULL, 0, 1); + + signal (SIGWINCH, gui_refresh_screen_sigwinch); + + if (cfg_look_set_title) + gui_set_window_title (); + + gui_init_ok = 1; + } } /* @@ -677,113 +2254,33 @@ gui_end () { t_gui_window *ptr_win; + /* free clipboard buffer */ + if (gui_input_clipboard) + free(gui_input_clipboard); + /* delete all windows */ for (ptr_win = gui_windows; ptr_win; ptr_win = ptr_win->next_window) { - /* TODO: delete Gtk windows */ - /* TODO: free input buffer, lines, messages, completion */ + /* TODO: destroy Gtk widgets */ } -} - -/* - * gui_add_message: add a message to a window - */ - -void -gui_add_message (t_gui_window *window, int type, int color, char *message) -{ - char *pos; - int length; - GtkTextIter start, end; - /* create new line if previous was ending by '\n' (or if 1st line) */ - if (window->line_complete) - { - gtk_text_buffer_insert_at_cursor (window->textbuffer_chat, "\n", -1); - window->line_complete = 0; - } + /* delete all buffers */ + while (gui_buffers) + gui_buffer_free (gui_buffers, 0); - pos = strchr (message, '\n'); - if (pos) - { - pos[0] = '\0'; - window->line_complete = 1; - } + /* delete all windows */ + while (gui_windows) + gui_window_free (gui_windows); + gui_window_tree_free (&gui_windows_tree); - gtk_text_buffer_insert_at_cursor (window->textbuffer_chat, message, -1); - gtk_text_buffer_get_bounds (window->textbuffer_chat, &start, &end); - gtk_text_buffer_apply_tag (window->textbuffer_chat, window->texttag_chat, &start, &end); + /* delete global history */ + history_global_free (); - if (pos) - pos[0] = '\n'; -} + /* delete infobar messages */ + while (gui_infobar) + gui_infobar_remove (); -/* - * gui_printf_color_type: display a message in a window - */ - -void -gui_printf_color_type (t_gui_window *window, int type, int color, char *message, ...) -{ - static char buffer[8192]; - char timestamp[16]; - char *pos; - va_list argptr; - static time_t seconds; - struct tm *date_tmp; - - if (gui_ready) - { - if (color == -1) - color = COLOR_WIN_CHAT; - - if (window == NULL) - { - if (SERVER(gui_current_window)) - window = SERVER(gui_current_window)->window; - else - window = gui_current_window; - } - - if (window == NULL) - { - wee_log_printf ("gui_printf without window! this is a bug, please send to developers - thanks\n"); - return; - } - } - - va_start (argptr, message); - vsnprintf (buffer, sizeof (buffer) - 1, message, argptr); - va_end (argptr); - - if (gui_ready) - { - seconds = time (NULL); - date_tmp = localtime (&seconds); - - pos = buffer - 1; - while (pos) - { - /* TODO: read timestamp format from config! */ - if (window->line_complete) - { - gui_add_message (window, MSG_TYPE_TIME, COLOR_WIN_CHAT_DARK, "["); - sprintf (timestamp, "%02d", date_tmp->tm_hour); - gui_add_message (window, MSG_TYPE_TIME, COLOR_WIN_CHAT_TIME, timestamp); - gui_add_message (window, MSG_TYPE_TIME, COLOR_WIN_CHAT_TIME_SEP, ":"); - sprintf (timestamp, "%02d", date_tmp->tm_min); - gui_add_message (window, MSG_TYPE_TIME, COLOR_WIN_CHAT_TIME, timestamp); - gui_add_message (window, MSG_TYPE_TIME, COLOR_WIN_CHAT_TIME_SEP, ":"); - sprintf (timestamp, "%02d", date_tmp->tm_sec); - gui_add_message (window, MSG_TYPE_TIME, COLOR_WIN_CHAT_TIME, timestamp); - gui_add_message (window, MSG_TYPE_TIME, COLOR_WIN_CHAT_DARK, "] "); - } - gui_add_message (window, type, color, pos + 1); - pos = strchr (pos + 1, '\n'); - if (pos && !pos[1]) - pos = NULL; - } - } - else - g_print ("%s", buffer); + /* reset title */ + if (cfg_look_set_title) + gui_reset_window_title (); } diff --git a/src/gui/gtk/gui-input.c b/src/gui/gtk/gui-input.c index 297d6404f..79555fc4c 100644 --- a/src/gui/gtk/gui-input.c +++ b/src/gui/gtk/gui-input.c @@ -37,26 +37,154 @@ #include "../gui.h" #include "../../common/weeconfig.h" #include "../../common/command.h" +#include "../../common/hotlist.h" +#include "../../common/fifo.h" +#include "../../common/utf8.h" #include "../../irc/irc.h" /* - * gui_read_keyb: read keyboard line + * gui_input_default_key_bindings: create default key bindings */ void -gui_read_keyb () +gui_input_default_key_bindings () { - /* TODO: read keyboard for Gtk GUI */ + int i; + char key_str[32], command[32]; + + /* keys binded with internal functions */ + gui_key_bind ( /* RC */ "ctrl-M", "return"); + gui_key_bind ( /* RC */ "ctrl-J", "return"); + gui_key_bind ( /* tab */ "ctrl-I", "tab"); + gui_key_bind ( /* basckp */ "ctrl-H", "backspace"); + gui_key_bind ( /* basckp */ "ctrl-?", "backspace"); + gui_key_bind ( /* del */ "meta2-3~", "delete"); + gui_key_bind ( /* ^K */ "ctrl-K", "delete_end_line"); + gui_key_bind ( /* ^U */ "ctrl-U", "delete_beginning_line"); + gui_key_bind ( /* ^W */ "ctrl-W", "delete_previous_word"); + gui_key_bind ( /* ^Y */ "ctrl-Y", "clipboard_paste"); + gui_key_bind ( /* ^T */ "ctrl-T", "transpose_chars"); + gui_key_bind ( /* home */ "meta2-1~", "home"); + gui_key_bind ( /* home */ "meta2-H", "home"); + gui_key_bind ( /* home */ "meta2-7~", "home"); + gui_key_bind ( /* ^A */ "ctrl-A", "home"); + gui_key_bind ( /* end */ "meta2-4~", "end"); + gui_key_bind ( /* end */ "meta2-F", "end"); + gui_key_bind ( /* end */ "meta2-8~", "end"); + gui_key_bind ( /* ^E */ "ctrl-E", "end"); + gui_key_bind ( /* left */ "meta2-D", "left"); + gui_key_bind ( /* right */ "meta2-C", "right"); + gui_key_bind ( /* up */ "meta2-A", "up"); + gui_key_bind ( /* ^up */ "meta-Oa", "up_global"); + gui_key_bind ( /* down */ "meta2-B", "down"); + gui_key_bind ( /* ^down */ "meta-Ob", "down_global"); + gui_key_bind ( /* pgup */ "meta2-5~", "page_up"); + gui_key_bind ( /* pgdn */ "meta2-6~", "page_down"); + gui_key_bind ( /* m-pgup */ "meta-meta2-5~", "scroll_up"); + gui_key_bind ( /* m-pgdn */ "meta-meta2-6~", "scroll_down"); + gui_key_bind ( /* F10 */ "meta2-21~", "infobar_clear"); + gui_key_bind ( /* F11 */ "meta2-23~", "nick_page_up"); + gui_key_bind ( /* F12 */ "meta2-24~", "nick_page_down"); + gui_key_bind ( /* m-F11 */ "meta-meta2-1~", "nick_beginning"); + gui_key_bind ( /* m-F12 */ "meta-meta2-4~", "nick_end"); + gui_key_bind ( /* ^L */ "ctrl-L", "refresh"); + gui_key_bind ( /* m-a */ "meta-a", "jump_smart"); + gui_key_bind ( /* m-b */ "meta-b", "previous_word"); + gui_key_bind ( /* ^left */ "meta-Od", "previous_word"); + gui_key_bind ( /* m-d */ "meta-d", "delete_next_word"); + gui_key_bind ( /* m-f */ "meta-f", "next_word"); + gui_key_bind ( /* ^right */ "meta-Oc", "next_word"); + gui_key_bind ( /* m-h */ "meta-h", "hotlist_clear"); + gui_key_bind ( /* m-j,m-d */ "meta-jmeta-d", "jump_dcc"); + gui_key_bind ( /* m-j,m-l */ "meta-jmeta-l", "jump_last_buffer"); + gui_key_bind ( /* m-j,m-s */ "meta-jmeta-s", "jump_server"); + gui_key_bind ( /* m-j,m-x */ "meta-jmeta-x", "jump_next_server"); + gui_key_bind ( /* m-k */ "meta-k", "grab_key"); + gui_key_bind ( /* m-n */ "meta-n", "scroll_next_highlight"); + gui_key_bind ( /* m-p */ "meta-p", "scroll_previous_highlight"); + gui_key_bind ( /* m-r */ "meta-r", "delete_line"); + gui_key_bind ( /* m-s */ "meta-s", "switch_server"); + gui_key_bind ( /* m-u */ "meta-u", "scroll_unread"); + + /* keys binded with commands */ + gui_key_bind ( /* m-left */ "meta-meta2-D", "/buffer -1"); + gui_key_bind ( /* F5 */ "meta2-15~", "/buffer -1"); + gui_key_bind ( /* m-right */ "meta-meta2-C", "/buffer +1"); + gui_key_bind ( /* F6 */ "meta2-17~", "/buffer +1"); + gui_key_bind ( /* F7 */ "meta2-18~", "/window -1"); + gui_key_bind ( /* F8 */ "meta2-19~", "/window +1"); + gui_key_bind ( /* m-w,m-up */ "meta-wmeta-meta2-A", "/window up"); + gui_key_bind ( /* m-w,m-down */ "meta-wmeta-meta2-B", "/window down"); + gui_key_bind ( /* m-w,m-left */ "meta-wmeta-meta2-D", "/window left"); + gui_key_bind ( /* m-w,m-right */ "meta-wmeta-meta2-C", "/window right"); + gui_key_bind ( /* m-0 */ "meta-0", "/buffer 10"); + gui_key_bind ( /* m-1 */ "meta-1", "/buffer 1"); + gui_key_bind ( /* m-2 */ "meta-2", "/buffer 2"); + gui_key_bind ( /* m-3 */ "meta-3", "/buffer 3"); + gui_key_bind ( /* m-4 */ "meta-4", "/buffer 4"); + gui_key_bind ( /* m-5 */ "meta-5", "/buffer 5"); + gui_key_bind ( /* m-6 */ "meta-6", "/buffer 6"); + gui_key_bind ( /* m-7 */ "meta-7", "/buffer 7"); + gui_key_bind ( /* m-8 */ "meta-8", "/buffer 8"); + gui_key_bind ( /* m-9 */ "meta-9", "/buffer 9"); + + /* bind meta-j + {01..99} to switch to buffers # > 10 */ + for (i = 1; i < 100; i++) + { + sprintf (key_str, "meta-j%02d", i); + sprintf (command, "/buffer %d", i); + gui_key_bind (key_str, command); + } } /* - * gui_main_loop: main loop for WeeChat with Gtk GUI + * gui_input_grab_end: insert grabbed key in input buffer + */ + +void +gui_input_grab_end () +{ + char *expanded_key; + + /* get expanded name (for example: ^U => ctrl-u) */ + expanded_key = gui_key_get_expanded_name (gui_key_buffer); + + if (expanded_key) + { + if (gui_current_window->buffer->has_input) + { + gui_insert_string_input (gui_current_window, expanded_key, -1); + gui_current_window->buffer->input_buffer_pos += utf8_strlen (expanded_key); + gui_draw_buffer_input (gui_current_window->buffer, 1); + } + free (expanded_key); + } + + /* end grab mode */ + gui_key_grab = 0; + gui_key_grab_count = 0; + gui_key_buffer[0] = '\0'; +} + +/* + * gui_input_read: read keyboard chars + */ + +void +gui_input_read () +{ + /* TODO: write this function for Gtk */ +} + +/* + * gui_main_loop: main loop for WeeChat with ncurses GUI */ void gui_main_loop () { - /* TODO: main loop function for Gtk GUI */ + /* TODO: write this function for Gtk */ gtk_main (); } + diff --git a/src/gui/gui-common.c b/src/gui/gui-common.c index 445fe9b34..52545c3ac 100644 --- a/src/gui/gui-common.c +++ b/src/gui/gui-common.c @@ -366,6 +366,27 @@ gui_buffer_servers_search () } /* + * gui_get_dcc_buffer: get pointer to DCC buffer (DCC buffer created if not existing) + */ + +t_gui_buffer * +gui_get_dcc_buffer (t_gui_window *window) +{ + t_gui_buffer *ptr_buffer; + + /* check if dcc buffer exists */ + for (ptr_buffer = gui_buffers; ptr_buffer; ptr_buffer = ptr_buffer->next_buffer) + { + if (ptr_buffer->dcc) + break; + } + if (ptr_buffer) + return ptr_buffer; + else + return gui_buffer_new (window, NULL, NULL, 1, 0); +} + +/* * gui_buffer_new: create a new buffer in current window */ @@ -848,7 +869,10 @@ gui_add_to_line (t_gui_buffer *buffer, int type, char *message) { pos[0] = '\n'; if (buffer->num_displayed > 0) + { + gui_draw_buffer_chat_line (buffer, buffer->last_line); gui_draw_buffer_chat (buffer, 0); + } if (gui_add_hotlist && (buffer->num_displayed == 0)) { if (3 - buffer->last_line->line_with_message - diff --git a/src/gui/gui.h b/src/gui/gui.h index 2e50bcc6e..f05ee22f6 100644 --- a/src/gui/gui.h +++ b/src/gui/gui.h @@ -404,6 +404,7 @@ extern void gui_window_tree_free (t_gui_window_tree **); extern t_gui_window *gui_window_new (t_gui_window *, int, int, int, int, int, int); extern t_gui_buffer *gui_buffer_search (char *, char *); extern t_gui_window *gui_buffer_find_window (t_gui_buffer *); +extern t_gui_buffer *gui_get_dcc_buffer (t_gui_window *); extern t_gui_buffer *gui_buffer_new (t_gui_window *, void *, void *, int, int); extern void gui_buffer_clear (t_gui_buffer *); extern void gui_buffer_clear_all (); @@ -505,6 +506,7 @@ extern void gui_calculate_pos_size (t_gui_window *); extern void gui_draw_buffer_title (t_gui_buffer *, int); extern char *gui_word_get_next_char (t_gui_window *, unsigned char *, int); extern void gui_draw_buffer_chat (t_gui_buffer *, int); +extern void gui_draw_buffer_chat_line (t_gui_buffer *, t_gui_line *); extern void gui_draw_buffer_nick (t_gui_buffer *, int); extern void gui_draw_buffer_status (t_gui_buffer *, int); extern void gui_draw_buffer_infobar_time (t_gui_buffer *); @@ -512,7 +514,6 @@ extern void gui_draw_buffer_infobar (t_gui_buffer *, int); extern void gui_draw_buffer_input (t_gui_buffer *, int); extern void gui_redraw_buffer (t_gui_buffer *); extern void gui_switch_to_buffer (t_gui_window *, t_gui_buffer *); -extern t_gui_buffer *gui_get_dcc_buffer (t_gui_window *); extern void gui_window_page_up (t_gui_window *); extern void gui_window_page_down (t_gui_window *); extern void gui_window_scroll_up (t_gui_window *); diff --git a/weechat/configure.in b/weechat/configure.in index db12397cb..90c78ae31 100644 --- a/weechat/configure.in +++ b/weechat/configure.in @@ -97,7 +97,7 @@ AH_VERBATIM([DEBUG], [#undef DEBUG]) AC_ARG_ENABLE(ncurses, [ --disable-ncurses Turn off ncurses interface (default=compiled if found)],enable_ncurses=$enableval,enable_ncurses=yes) AC_ARG_ENABLE(wxwidgets, [ --enable-wxwidgets Turn on WxWidgets interface (default=no wxwidgets)],enable_wxwidgets=$enableval,enable_wxwidgets=no) -AC_ARG_ENABLE(gtk, [ --enable-gtk Turn on Gtk+ interface (default=no Gtk+)],enable_gtk=$enableval,enable_gtk=no) +AC_ARG_ENABLE(gtk, [ --enable-gtk Turn on Gtk interface (default=no Gtk)],enable_gtk=$enableval,enable_gtk=no) AC_ARG_ENABLE(qt, [ --enable-qt Turn on Qt interface (default=no Qt)],enable_qt=$enableval,enable_qt=no) AC_ARG_ENABLE(plugins, [ --disable-plugins Turn off plugins support (default=plugins enabled)],enable_plugins=$enableval,enable_plugins=yes) AC_ARG_ENABLE(perl, [ --enable-perl Turn on Perl script plugin (default=no Perl plugin)],enable_perl=$enableval,enable_perl=no) @@ -169,9 +169,10 @@ fi #fi if test "x$enable_gtk" = "xyes" ; then - #if test "$LIBGTK_FOUND" = "0" ; then - # AC_MSG_ERROR([Gtk+ library not found! Install Gtk+ (2.0 or higher) library or run ./configure without --enable-gtk parameter.]) - #fi + AM_PATH_GTK_2_0(2.4.0, LIBGTK_FOUND=1, LIBGTK_FOUND=0) + if test "$LIBGTK_FOUND" = "0" ; then + AC_MSG_ERROR([Gtk library not found! Install Gtk library (2.4 or higher) or run ./configure without --enable-gtk parameter.]) + fi GTK_CFLAGS=`pkg-config --cflags gtk+-2.0` GTK_LIBS=`pkg-config --libs gtk+-2.0` AC_SUBST(GTK_CFLAGS) @@ -528,7 +529,7 @@ if test "x$enable_wxwidgets" = "xyes"; then listgui="$listgui WxWidgets" fi if test "x$enable_gtk" = "xyes" ; then - listgui="$listgui Gtk+" + listgui="$listgui Gtk" fi if test "x$enable_qt" = "xyes" ; then listgui="$listgui Qt" diff --git a/weechat/src/gui/curses/gui-display.c b/weechat/src/gui/curses/gui-display.c index 33f1dcdcf..f95b1bafc 100644 --- a/weechat/src/gui/curses/gui-display.c +++ b/weechat/src/gui/curses/gui-display.c @@ -843,12 +843,12 @@ gui_draw_buffer_title (t_gui_buffer *buffer, int erase) } /* - * gui_display_new_line: display a new line + * gui_curses_display_new_line: display a new line */ void -gui_display_new_line (t_gui_window *window, int num_lines, int count, - int *lines_displayed, int simulate) +gui_curses_display_new_line (t_gui_window *window, int num_lines, int count, + int *lines_displayed, int simulate) { if ((count == 0) || (*lines_displayed >= num_lines - count)) { @@ -1147,8 +1147,8 @@ gui_display_word (t_gui_window *window, (((simulate) || (window->win_chat_cursor_y <= window->win_chat_height - 1)) && (window->win_chat_cursor_x > (window->win_chat_width - 1)))) - gui_display_new_line (window, num_lines, count, - lines_displayed, simulate); + gui_curses_display_new_line (window, num_lines, count, + lines_displayed, simulate); if ((data >= end_line) || ((!simulate) && (window->win_chat_cursor_y >= window->win_chat_height))) @@ -1220,16 +1220,19 @@ gui_get_word_info (t_gui_window *window, } /* - * gui_display_line: display a line in the chat window - * if count == 0, display whole line - * if count > 0, display 'count' lines (beginning from the end) - * if simulate == 1, nothing is displayed (for counting how - * many lines would have been lines displayed) - * returns: number of lines displayed (or simulated) + * gui_curses_display_line: display a line in the chat window + * if count == 0, display whole line + * if count > 0, display 'count' lines + * (beginning from the end) + * if simulate == 1, nothing is displayed + * (for counting how many lines would have been + * lines displayed) + * returns: number of lines displayed (or simulated) */ int -gui_display_line (t_gui_window *window, t_gui_line *line, int count, int simulate) +gui_curses_display_line (t_gui_window *window, t_gui_line *line, int count, + int simulate) { int num_lines, x, y, lines_displayed; int read_marker_x, read_marker_y; @@ -1252,7 +1255,7 @@ gui_display_line (t_gui_window *window, t_gui_line *line, int count, int simulat return 0; x = window->win_chat_cursor_x; y = window->win_chat_cursor_y; - num_lines = gui_display_line (window, line, 0, 1); + num_lines = gui_curses_display_line (window, line, 0, 1); window->win_chat_cursor_x = x; window->win_chat_cursor_y = y; } @@ -1290,8 +1293,8 @@ gui_display_line (t_gui_window *window, t_gui_line *line, int count, int simulat if ((window->win_chat_cursor_x + word_length_with_spaces > window->win_chat_width) && (word_length <= window->win_chat_width - line->length_align)) { - gui_display_new_line (window, num_lines, count, - &lines_displayed, simulate); + gui_curses_display_new_line (window, num_lines, count, + &lines_displayed, simulate); /* apply styles before jumping to start of word */ if (!simulate && (word_start_offset > 0)) { @@ -1341,8 +1344,8 @@ gui_display_line (t_gui_window *window, t_gui_line *line, int count, int simulat } else { - gui_display_new_line (window, num_lines, count, - &lines_displayed, simulate); + gui_curses_display_new_line (window, num_lines, count, + &lines_displayed, simulate); ptr_data = NULL; } } @@ -1392,7 +1395,7 @@ gui_calculate_line_diff (t_gui_window *window, t_gui_line **line, int *line_pos, *line = window->buffer->last_line; if (!(*line)) return; - current_size = gui_display_line (window, *line, 0, 1); + current_size = gui_curses_display_line (window, *line, 0, 1); if (current_size == 0) current_size = 1; *line_pos = current_size - 1; @@ -1404,11 +1407,11 @@ gui_calculate_line_diff (t_gui_window *window, t_gui_line **line, int *line_pos, if (!(*line)) return; *line_pos = 0; - current_size = gui_display_line (window, *line, 0, 1); + current_size = gui_curses_display_line (window, *line, 0, 1); } } else - current_size = gui_display_line (window, *line, 0, 1); + current_size = gui_curses_display_line (window, *line, 0, 1); while ((*line) && (difference != 0)) { @@ -1422,7 +1425,7 @@ gui_calculate_line_diff (t_gui_window *window, t_gui_line **line, int *line_pos, *line = (*line)->prev_line; if (*line) { - current_size = gui_display_line (window, *line, 0, 1); + current_size = gui_curses_display_line (window, *line, 0, 1); if (current_size == 0) current_size = 1; *line_pos = current_size - 1; @@ -1440,7 +1443,7 @@ gui_calculate_line_diff (t_gui_window *window, t_gui_line **line, int *line_pos, *line = (*line)->next_line; if (*line) { - current_size = gui_display_line (window, *line, 0, 1); + current_size = gui_curses_display_line (window, *line, 0, 1); if (current_size == 0) current_size = 1; *line_pos = 0; @@ -1648,9 +1651,11 @@ gui_draw_buffer_chat (t_gui_buffer *buffer, int erase) if (line_pos > 0) { /* display end of first line at top of screen */ - gui_display_line (ptr_win, ptr_line, - gui_display_line (ptr_win, ptr_line, 0, 1) - - line_pos, 0); + gui_curses_display_line (ptr_win, ptr_line, + gui_curses_display_line (ptr_win, + ptr_line, + 0, 1) - + line_pos, 0); ptr_line = ptr_line->next_line; ptr_win->first_line_displayed = 0; } @@ -1662,7 +1667,7 @@ gui_draw_buffer_chat (t_gui_buffer *buffer, int erase) count = 0; while (ptr_line && (ptr_win->win_chat_cursor_y <= ptr_win->win_chat_height - 1)) { - count = gui_display_line (ptr_win, ptr_line, 0, 0); + count = gui_curses_display_line (ptr_win, ptr_line, 0, 0); ptr_line = ptr_line->next_line; } @@ -1672,7 +1677,7 @@ gui_draw_buffer_chat (t_gui_buffer *buffer, int erase) /* if so, disable scroll indicator */ if (!ptr_line && ptr_win->scroll) { - if (count == gui_display_line (ptr_win, ptr_win->buffer->last_line, 0, 1)) + if (count == gui_curses_display_line (ptr_win, ptr_win->buffer->last_line, 0, 1)) { ptr_win->scroll = 0; ptr_win->start_line = NULL; @@ -1700,6 +1705,19 @@ gui_draw_buffer_chat (t_gui_buffer *buffer, int erase) } /* + * gui_draw_buffer_chat_line: add a line to chat window for a buffer + */ + +void +gui_draw_buffer_chat_line (t_gui_buffer *buffer, t_gui_line *line) +{ + /* This function does nothing in Curses GUI, + line will be displayed by gui_buffer_draw_chat() */ + (void) buffer; + (void) line; +} + +/* * gui_draw_buffer_nick: draw nick window for a buffer */ @@ -2633,27 +2651,6 @@ gui_switch_to_buffer (t_gui_window *window, t_gui_buffer *buffer) } /* - * gui_get_dcc_buffer: get pointer to DCC buffer (DCC buffer created if not existing) - */ - -t_gui_buffer * -gui_get_dcc_buffer (t_gui_window *window) -{ - t_gui_buffer *ptr_buffer; - - /* check if dcc buffer exists */ - for (ptr_buffer = gui_buffers; ptr_buffer; ptr_buffer = ptr_buffer->next_buffer) - { - if (ptr_buffer->dcc) - break; - } - if (ptr_buffer) - return ptr_buffer; - else - return gui_buffer_new (window, NULL, NULL, 1, 0); -} - -/* * gui_window_page_up: display previous page on buffer */ diff --git a/weechat/src/gui/gtk/Makefile.am b/weechat/src/gui/gtk/Makefile.am index 10b5ed4d3..655a03d40 100644 --- a/weechat/src/gui/gtk/Makefile.am +++ b/weechat/src/gui/gtk/Makefile.am @@ -19,11 +19,24 @@ INCLUDES = -DLOCALEDIR=\"$(datadir)/locale\" $(GTK_CFLAGS) bin_PROGRAMS = weechat-gtk -weechat_gtk_LDADD = ../lib_weechat_gui_common.a \ +if PLUGINS +weechat_gtk_LDADD = ../gui-common.o ../gui-keyboard.o \ + ../gui-action.o \ ../../common/lib_weechat_main.a \ ../../irc/lib_weechat_irc.a \ + ../../plugins/lib_weechat_plugins.a \ + $(PLUGINS_LIBS) \ $(GTK_LIBS) \ - ../../plugins/lib_weechat_plugins.a $(PLUGINS_LIBS) + $(GNUTLS_LFLAGS) +else +weechat_gtk_LDADD = ../gui-common.o ../gui-keyboard.o \ + ../gui-action.o \ + ../../common/lib_weechat_main.a \ + ../../irc/lib_weechat_irc.a \ + $(PLUGINS_LIBS) \ + $(GTK_LIBS) \ + $(GNUTLS_LFLAGS) +endif weechat_gtk_SOURCES = gui-display.c \ - gui-input.c + gui-input.c diff --git a/weechat/src/gui/gtk/gui-display.c b/weechat/src/gui/gtk/gui-display.c index ec7376ae4..7d108b8d3 100644 --- a/weechat/src/gui/gtk/gui-display.c +++ b/weechat/src/gui/gtk/gui-display.c @@ -30,39 +30,72 @@ #include <string.h> #include <signal.h> #include <time.h> +#include <ctype.h> #include <gtk/gtk.h> #include "../../common/weechat.h" #include "../gui.h" #include "../../common/weeconfig.h" +#include "../../common/hotlist.h" +#include "../../common/log.h" +#include "../../common/utf8.h" #include "../../irc/irc.h" -t_gui_color gui_colors[] = -{ { "default", 0 }, - { "black", 0 }, - { "red", 0 }, - { "lightred", 0 }, - { "green", 0 }, - { "lightgreen", 0 }, - { "brown", 0 }, - { "yellow", 0 }, - { "blue", 0 }, - { "lightblue", 0 }, - { "magenta", 0L }, - { "lightmagenta", 0 }, - { "cyan", 0 }, - { "lightcyan", 0 }, - { "gray", 0 }, - { "white", 0 }, - { NULL, 0 } +/* TODO: remove these temporary defines */ + +#define A_BOLD 1 +#define A_UNDERLINE 2 +#define A_REVERSE 4 + +#define COLOR_BLACK 0 +#define COLOR_BLUE 1 +#define COLOR_GREEN 2 +#define COLOR_CYAN 3 +#define COLOR_RED 4 +#define COLOR_MAGENTA 5 +#define COLOR_YELLOW 6 +#define COLOR_WHITE 7 + +t_gui_color gui_weechat_colors[] = +{ { -1, 0, 0, "default" }, + { WEECHAT_COLOR_BLACK, 0, 0, "black" }, + { WEECHAT_COLOR_RED, 0, 0, "red" }, + { WEECHAT_COLOR_RED, 0, A_BOLD, "lightred" }, + { WEECHAT_COLOR_GREEN, 0, 0, "green" }, + { WEECHAT_COLOR_GREEN, 0, A_BOLD, "lightgreen" }, + { WEECHAT_COLOR_YELLOW, 0, 0, "brown" }, + { WEECHAT_COLOR_YELLOW, 0, A_BOLD, "yellow" }, + { WEECHAT_COLOR_BLUE, 0, 0, "blue" }, + { WEECHAT_COLOR_BLUE, 0, A_BOLD, "lightblue" }, + { WEECHAT_COLOR_MAGENTA, 0, 0, "magenta" }, + { WEECHAT_COLOR_MAGENTA, 0, A_BOLD, "lightmagenta" }, + { WEECHAT_COLOR_CYAN, 0, 0, "cyan" }, + { WEECHAT_COLOR_CYAN, 0, A_BOLD, "lightcyan" }, + { WEECHAT_COLOR_WHITE, 0, A_BOLD, "white" }, + { 0, 0, 0, NULL } }; -char *nicks_colors[COLOR_WIN_NICK_NUMBER] = -{ "cyan", "magenta", "green", "brown", "lightblue", "gray", - "lightcyan", "lightmagenta", "lightgreen", "blue" }; +int gui_irc_colors[16][2] = +{ { /* 0 */ WEECHAT_COLOR_WHITE, A_BOLD }, + { /* 1 */ WEECHAT_COLOR_BLACK, 0 }, + { /* 2 */ WEECHAT_COLOR_BLUE, 0 }, + { /* 3 */ WEECHAT_COLOR_GREEN, 0 }, + { /* 4 */ WEECHAT_COLOR_RED, A_BOLD }, + { /* 5 */ WEECHAT_COLOR_RED, 0 }, + { /* 6 */ WEECHAT_COLOR_MAGENTA, 0 }, + { /* 7 */ WEECHAT_COLOR_YELLOW, 0 }, + { /* 8 */ WEECHAT_COLOR_YELLOW, A_BOLD }, + { /* 9 */ WEECHAT_COLOR_GREEN, A_BOLD }, + { /* 10 */ WEECHAT_COLOR_CYAN, 0 }, + { /* 11 */ WEECHAT_COLOR_CYAN, A_BOLD }, + { /* 12 */ WEECHAT_COLOR_BLUE, A_BOLD }, + { /* 13 */ WEECHAT_COLOR_MAGENTA, A_BOLD }, + { /* 14 */ WEECHAT_COLOR_WHITE, 0 }, + { /* 15 */ WEECHAT_COLOR_WHITE, A_BOLD } +}; -int color_attr[NUM_COLORS]; +t_gui_color *gui_color[NUM_COLORS]; GtkWidget *gtk_main_window; GtkWidget *vbox1; @@ -70,6 +103,7 @@ GtkWidget *entry_topic; GtkWidget *notebook1; GtkWidget *vbox2; GtkWidget *hbox1; +GtkWidget *hpaned1; GtkWidget *scrolledwindow_chat; GtkWidget *scrolledwindow_nick; GtkWidget *entry_input; @@ -77,7 +111,7 @@ GtkWidget *label1; /* - * gui_assign_color: assign a color (read from config) + * gui_assign_color: assign a WeeChat color (read from config) */ int @@ -85,13 +119,13 @@ gui_assign_color (int *color, char *color_name) { int i; - /* look for Gtk colors in table */ + /* look for curses colors in table */ i = 0; - while (gui_colors[i].name) + while (gui_weechat_colors[i].string) { - if (ascii_strcasecmp (gui_colors[i].name, color_name) == 0) + if (ascii_strcasecmp (gui_weechat_colors[i].string, color_name) == 0) { - *color = gui_colors[i].color; + *color = i; return 1; } i++; @@ -102,350 +136,1190 @@ gui_assign_color (int *color, char *color_name) } /* - * gui_get_color_by_name: get color by name + * gui_get_color_name: get color name */ -int -gui_get_color_by_name (char *color_name) +char * +gui_get_color_name (int num_color) { - int i; + return gui_weechat_colors[num_color].string; +} + +/* + * gui_color_decode: parses a message (coming from IRC server), + * and according: + * - remove any color/style in message + * or: + * - change colors by codes to be compatible with + * other IRC clients + * After use, string returned has to be free() + */ + +unsigned char * +gui_color_decode (unsigned char *string, int keep_colors) +{ + unsigned char *out; + int out_length, out_pos; + char str_fg[3], str_bg[3]; + int fg, bg, attr; - /* look for Gtk in table */ - i = 0; - while (gui_colors[i].name) + out_length = (strlen ((char *)string) * 2) + 1; + out = (unsigned char *)malloc (out_length); + if (!out) + return NULL; + + out_pos = 0; + while (string[0] && (out_pos < out_length - 1)) { - if (ascii_strcasecmp (gui_colors[i].name, color_name) == 0) - return gui_colors[i].color; - i++; + switch (string[0]) + { + case GUI_ATTR_BOLD_CHAR: + case GUI_ATTR_RESET_CHAR: + case GUI_ATTR_FIXED_CHAR: + case GUI_ATTR_REVERSE_CHAR: + case GUI_ATTR_REVERSE2_CHAR: + case GUI_ATTR_ITALIC_CHAR: + case GUI_ATTR_UNDERLINE_CHAR: + if (keep_colors) + out[out_pos++] = string[0]; + string++; + break; + case GUI_ATTR_COLOR_CHAR: + string++; + str_fg[0] = '\0'; + str_bg[0] = '\0'; + if (isdigit (string[0])) + { + str_fg[0] = string[0]; + str_fg[1] = '\0'; + string++; + if (isdigit (string[0])) + { + str_fg[1] = string[0]; + str_fg[2] = '\0'; + string++; + } + } + if (string[0] == ',') + { + string++; + if (isdigit (string[0])) + { + str_bg[0] = string[0]; + str_bg[1] = '\0'; + string++; + if (isdigit (string[0])) + { + str_bg[1] = string[0]; + str_bg[2] = '\0'; + string++; + } + } + } + if (keep_colors) + { + if (!str_fg[0] && !str_bg[0]) + out[out_pos++] = GUI_ATTR_COLOR_CHAR; + else + { + attr = 0; + if (str_fg[0]) + { + sscanf (str_fg, "%d", &fg); + fg %= 16; + attr |= gui_irc_colors[fg][1]; + } + if (str_bg[0]) + { + sscanf (str_bg, "%d", &bg); + bg %= 16; + attr |= gui_irc_colors[bg][1]; + } + if (attr & A_BOLD) + { + out[out_pos++] = GUI_ATTR_WEECHAT_SET_CHAR; + out[out_pos++] = GUI_ATTR_BOLD_CHAR; + } + else + { + out[out_pos++] = GUI_ATTR_WEECHAT_REMOVE_CHAR; + out[out_pos++] = GUI_ATTR_BOLD_CHAR; + } + out[out_pos++] = GUI_ATTR_COLOR_CHAR; + if (str_fg[0]) + { + out[out_pos++] = (gui_irc_colors[fg][0] / 10) + '0'; + out[out_pos++] = (gui_irc_colors[fg][0] % 10) + '0'; + } + if (str_bg[0]) + { + out[out_pos++] = ','; + out[out_pos++] = (gui_irc_colors[bg][0] / 10) + '0'; + out[out_pos++] = (gui_irc_colors[bg][0] % 10) + '0'; + } + } + } + break; + case GUI_ATTR_WEECHAT_COLOR_CHAR: + string++; + if (isdigit (string[0]) && isdigit (string[1])) + { + if (keep_colors) + { + out[out_pos++] = string[0]; + out[out_pos++] = string[1]; + } + string += 2; + } + break; + case GUI_ATTR_WEECHAT_SET_CHAR: + case GUI_ATTR_WEECHAT_REMOVE_CHAR: + string++; + if (string[0]) + { + if (keep_colors) + { + out[out_pos++] = *(string - 1); + out[out_pos++] = string[0]; + } + string++; + } + break; + default: + out[out_pos++] = string[0]; + string++; + } } + out[out_pos] = '\0'; + return out; +} + +/* + * gui_color_decode_for_user_entry: parses a message (coming from IRC server), + * and replaces colors/bold/.. by %C, %B, .. + * After use, string returned has to be free() + */ + +unsigned char * +gui_color_decode_for_user_entry (unsigned char *string) +{ + unsigned char *out; + int out_length, out_pos; - /* color not found */ - return -1; + out_length = (strlen ((char *)string) * 2) + 1; + out = (unsigned char *)malloc (out_length); + if (!out) + return NULL; + + out_pos = 0; + while (string[0] && (out_pos < out_length - 1)) + { + switch (string[0]) + { + case GUI_ATTR_BOLD_CHAR: + out[out_pos++] = '%'; + out[out_pos++] = 'B'; + string++; + break; + case GUI_ATTR_FIXED_CHAR: + string++; + break; + case GUI_ATTR_RESET_CHAR: + out[out_pos++] = '%'; + out[out_pos++] = 'O'; + string++; + break; + case GUI_ATTR_REVERSE_CHAR: + case GUI_ATTR_REVERSE2_CHAR: + out[out_pos++] = '%'; + out[out_pos++] = 'R'; + string++; + break; + case GUI_ATTR_ITALIC_CHAR: + string++; + break; + case GUI_ATTR_UNDERLINE_CHAR: + out[out_pos++] = '%'; + out[out_pos++] = 'R'; + string++; + break; + case GUI_ATTR_COLOR_CHAR: + out[out_pos++] = '%'; + out[out_pos++] = 'C'; + string++; + break; + default: + out[out_pos++] = string[0]; + string++; + } + } + out[out_pos] = '\0'; + return out; } /* - * gui_get_color_by_value: get color name by value + * gui_color_encode: parses a message (entered by user), and + * encode special chars (%B, %C, ..) in IRC colors + * After use, string returned has to be free() */ -char * -gui_get_color_by_value (int color_value) +unsigned char * +gui_color_encode (unsigned char *string) { - int i; + unsigned char *out; + int out_length, out_pos; - /* look for Gtk colors in table */ - i = 0; - while (gui_colors[i].name) + out_length = (strlen ((char *)string) * 2) + 1; + out = (unsigned char *)malloc (out_length); + if (!out) + return NULL; + + out_pos = 0; + while (string[0] && (out_pos < out_length - 1)) { - if (gui_colors[i].color == color_value) - return gui_colors[i].name; - i++; + switch (string[0]) + { + case '%': + string++; + switch (string[0]) + { + case '\0': + out[out_pos++] = '%'; + break; + case '%': /* double '%' replaced by single '%' */ + out[out_pos++] = string[0]; + string++; + break; + case 'B': /* bold */ + out[out_pos++] = GUI_ATTR_BOLD_CHAR; + string++; + break; + case 'C': /* color */ + out[out_pos++] = GUI_ATTR_COLOR_CHAR; + string++; + if (isdigit (string[0])) + { + out[out_pos++] = string[0]; + string++; + if (isdigit (string[0])) + { + out[out_pos++] = string[0]; + string++; + } + } + if (string[0] == ',') + { + out[out_pos++] = ','; + string++; + if (isdigit (string[0])) + { + out[out_pos++] = string[0]; + string++; + if (isdigit (string[0])) + { + out[out_pos++] = string[0]; + string++; + } + } + } + break; + case 'O': /* reset */ + out[out_pos++] = GUI_ATTR_RESET_CHAR; + string++; + break; + case 'R': /* reverse */ + out[out_pos++] = GUI_ATTR_REVERSE_CHAR; + string++; + break; + case 'U': /* underline */ + out[out_pos++] = GUI_ATTR_UNDERLINE_CHAR; + string++; + break; + default: + out[out_pos++] = '%'; + out[out_pos++] = string[0]; + string++; + } + break; + default: + out[out_pos++] = string[0]; + string++; + } } + out[out_pos] = '\0'; + return out; +} + +/* + * gui_color_build: build a WeeChat color with foreground, + * background and attributes (attributes are + * given with foreground color, with a OR) + */ + +t_gui_color * +gui_color_build (int number, int foreground, int background) +{ + t_gui_color *new_color; - /* color not found */ - return NULL; + new_color = (t_gui_color *)malloc (sizeof (t_gui_color)); + if (!new_color) + return NULL; + + new_color->foreground = gui_weechat_colors[foreground].foreground; + new_color->background = gui_weechat_colors[background].foreground; + new_color->attributes = gui_weechat_colors[foreground].attributes; + new_color->string = (char *)malloc (4); + if (new_color->string) + snprintf (new_color->string, 4, + "%s%02d", + GUI_ATTR_WEECHAT_COLOR_STR, number); + + return new_color; } /* - * gui_window_has_nicklist: returns 1 if window has nicklist + * gui_color_get_pair: get color pair with a WeeChat color number */ int -gui_window_has_nicklist (t_gui_window *window) +gui_color_get_pair (int num_color) { - return (window->textbuffer_nicklist != NULL); + int fg, bg; + + if ((num_color < 0) || (num_color > NUM_COLORS - 1)) + return WEECHAT_COLOR_WHITE; + + fg = gui_color[num_color]->foreground; + bg = gui_color[num_color]->background; + + if (((fg == -1) || (fg == 99)) + && ((bg == -1) || (bg == 99))) + return 63; + if ((fg == -1) || (fg == 99)) + fg = WEECHAT_COLOR_WHITE; + if ((bg == -1) || (bg == 99)) + bg = 0; + + return (bg * 8) + fg; } /* - * gui_calculate_pos_size: calculate position and size for a window & sub-win + * gui_window_set_weechat_color: set WeeChat color for window + */ + +/* TODO: write this function for Gtk */ +/*void +gui_window_set_weechat_color (WINDOW *window, int num_color) +{ + if ((num_color >= 0) && (num_color <= NUM_COLORS - 1)) + { + wattroff (window, A_BOLD | A_UNDERLINE | A_REVERSE); + wattron (window, COLOR_PAIR(gui_color_get_pair (num_color)) | + gui_color[num_color]->attributes); + } +}*/ + +/* + * gui_window_chat_set_style: set style (bold, underline, ..) + * for a chat window */ void -gui_calculate_pos_size (t_gui_window *window) +gui_window_chat_set_style (t_gui_window *window, int style) { - /* TODO: write gui_calculate_pos_size for Gtk GUI */ + /* TODO: write this function for Gtk */ + /*wattron (window->win_chat, style);*/ (void) window; + (void) style; } /* - * gui_draw_window_title: draw title window + * gui_window_chat_remove_style: remove style (bold, underline, ..) + * for a chat window */ void -gui_draw_window_title (t_gui_window *window) +gui_window_chat_remove_style (t_gui_window *window, int style) { - char format[32]; - - /* TODO: manage splitted windows! */ - if (window != gui_current_window) - return; + /* TODO: write this function for Gtk */ + /*wattroff (window->win_chat, style);*/ + (void) window; + (void) style; +} + +/* + * gui_window_chat_toggle_style: toggle a style (bold, underline, ..) + * for a chat window + */ + +void +gui_window_chat_toggle_style (t_gui_window *window, int style) +{ + window->current_style_attr ^= style; + if (window->current_style_attr & style) + gui_window_chat_set_style (window, style); + else + gui_window_chat_remove_style (window, style); +} + +/* + * gui_window_chat_reset_style: reset style (color and attr) + * for a chat window + */ + +void +gui_window_chat_reset_style (t_gui_window *window) +{ + window->current_style_fg = -1; + window->current_style_bg = -1; + window->current_style_attr = 0; + window->current_color_attr = 0; - if (CHANNEL(window)) - { - sprintf (format, "%%-%ds", window->win_width); - /* TODO: display topic */ - } + /* TODO: change following function call */ + /*gui_window_set_weechat_color (window->win_chat, COLOR_WIN_CHAT);*/ + gui_window_chat_remove_style (window, + A_BOLD | A_UNDERLINE | A_REVERSE); +} + +/* + * gui_window_chat_set_color_style: set style for color + */ + +void +gui_window_chat_set_color_style (t_gui_window *window, int style) +{ + window->current_color_attr |= style; + /* TODO: change following function call */ + /*wattron (window->win_chat, style);*/ +} + +/* + * gui_window_chat_remove_color_style: remove style for color + */ + +void +gui_window_chat_remove_color_style (t_gui_window *window, int style) +{ + window->current_color_attr &= !style; + /* TODO: change following function call */ + /*wattroff (window->win_chat, style);*/ +} + +/* + * gui_window_chat_reset_color_style: reset style for color + */ + +void +gui_window_chat_reset_color_style (t_gui_window *window) +{ + /* TODO: change following function call */ + /*wattroff (window->win_chat, window->current_color_attr);*/ + window->current_color_attr = 0; +} + +/* + * gui_window_chat_set_color: set color for a chat window + */ + +void +gui_window_chat_set_color (t_gui_window *window, int fg, int bg) +{ + /* TODO: write this function for Gtk */ + /*if (((fg == -1) || (fg == 99)) + && ((bg == -1) || (bg == 99))) + wattron (window->win_chat, COLOR_PAIR(63)); else { - /* TODO: display title for server window */ - } + if ((fg == -1) || (fg == 99)) + fg = WEECHAT_COLOR_WHITE; + if ((bg == -1) || (bg == 99)) + bg = 0; + wattron (window->win_chat, COLOR_PAIR((bg * 8) + fg)); + }*/ + (void) window; + (void) fg; + (void) bg; } /* - * gui_redraw_window_title: redraw title window + * gui_window_chat_set_weechat_color: set a WeeChat color for a chat window */ void -gui_redraw_window_title (t_gui_window *window) +gui_window_chat_set_weechat_color (t_gui_window *window, int weechat_color) { - /* TODO: manage splitted windows! */ - if (window != gui_current_window) - return; - - /* TODO: first delete window content */ - gui_draw_window_title (window); + gui_window_chat_reset_style (window); + gui_window_chat_set_style (window, + gui_color[weechat_color]->attributes); + gui_window_chat_set_color (window, + gui_color[weechat_color]->foreground, + gui_color[weechat_color]->background); } /* - * gui_get_line_num_splits: returns number of lines on window - * (depending on window width and type (server/channel) - * for alignment) + * gui_calculate_pos_size: calculate position and size for a window & sub-win */ -int -gui_get_line_num_splits (t_gui_window *window, t_gui_line *line) +void +gui_calculate_pos_size (t_gui_window *window) +{ + /* TODO: write this function for Gtk */ + (void) window; +} + +/* + * gui_draw_window_separator: draw window separation + */ + +void +gui_draw_window_separator (t_gui_window *window) { - int length, width; + /* TODO: write this function for Gtk */ + /*if (window->win_separator) + delwin (window->win_separator); - /* TODO: modify arbitraty value for non aligning messages on time/nick? */ - if (line->length_align >= window->win_chat_width - 5) + if (window->win_x > 0) { - length = line->length; - width = window->win_chat_width; - } - else + window->win_separator = newwin (window->win_height, + 1, + window->win_y, + window->win_x - 1); + gui_window_set_weechat_color (window->win_separator, COLOR_WIN_SEPARATOR); + wborder (window->win_separator, ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '); + wnoutrefresh (window->win_separator); + refresh (); + }*/ + (void) window; +} + +/* + * gui_draw_buffer_title: draw title window for a buffer + */ + +void +gui_draw_buffer_title (t_gui_buffer *buffer, int erase) +{ + /* TODO: write this function for Gtk */ + (void) buffer; + (void) erase; +} + +/* + * gui_word_get_next_char: returns next char of a word + * special chars like colors, bold, .. are skipped + */ + +char * +gui_word_get_next_char (t_gui_window *window, unsigned char *string, int apply_style) +{ + char str_fg[3], str_bg[3]; + int fg, bg, weechat_color; + + while (string[0]) { - length = line->length - line->length_align; - width = window->win_chat_width - line->length_align; + switch (string[0]) + { + case GUI_ATTR_BOLD_CHAR: + string++; + if (apply_style) + gui_window_chat_toggle_style (window, A_BOLD); + break; + case GUI_ATTR_COLOR_CHAR: + string++; + str_fg[0] = '\0'; + str_bg[0] = '\0'; + fg = 99; + bg = 99; + if (isdigit (string[0])) + { + str_fg[0] = string[0]; + str_fg[1] = '\0'; + string++; + if (isdigit (string[0])) + { + str_fg[1] = string[0]; + str_fg[2] = '\0'; + string++; + } + } + if (string[0] == ',') + { + string++; + if (isdigit (string[0])) + { + str_bg[0] = string[0]; + str_bg[1] = '\0'; + string++; + if (isdigit (string[0])) + { + str_bg[1] = string[0]; + str_bg[2] = '\0'; + string++; + } + } + } + if (apply_style) + { + if (str_fg[0] || str_bg[0]) + { + if (str_fg[0]) + sscanf (str_fg, "%d", &fg); + else + fg = window->current_style_fg; + if (str_bg[0]) + sscanf (str_bg, "%d", &bg); + else + bg = window->current_style_bg; + } + if (!str_fg[0] && !str_bg[0]) + gui_window_chat_reset_color_style (window); + window->current_style_fg = fg; + window->current_style_bg = bg; + gui_window_chat_set_color (window, fg, bg); + } + break; + case GUI_ATTR_RESET_CHAR: + string++; + if (apply_style) + gui_window_chat_reset_style (window); + break; + case GUI_ATTR_FIXED_CHAR: + string++; + break; + case GUI_ATTR_REVERSE_CHAR: + case GUI_ATTR_REVERSE2_CHAR: + string++; + if (apply_style) + gui_window_chat_toggle_style (window, A_REVERSE); + break; + case GUI_ATTR_WEECHAT_COLOR_CHAR: + string++; + if (isdigit (string[0]) && isdigit (string[1])) + { + str_fg[0] = string[0]; + str_fg[1] = string[1]; + str_fg[2] = '\0'; + string += 2; + if (apply_style) + { + sscanf (str_fg, "%d", &weechat_color); + gui_window_chat_set_weechat_color (window, weechat_color); + } + } + break; + case GUI_ATTR_WEECHAT_SET_CHAR: + string++; + switch (string[0]) + { + case GUI_ATTR_BOLD_CHAR: + string++; + if (apply_style) + gui_window_chat_set_color_style (window, A_BOLD); + break; + case GUI_ATTR_REVERSE_CHAR: + case GUI_ATTR_REVERSE2_CHAR: + string++; + if (apply_style) + gui_window_chat_set_color_style (window, A_REVERSE); + break; + case GUI_ATTR_UNDERLINE_CHAR: + string++; + if (apply_style) + gui_window_chat_set_color_style (window, A_UNDERLINE); + break; + } + break; + case GUI_ATTR_WEECHAT_REMOVE_CHAR: + string++; + switch (string[0]) + { + case GUI_ATTR_BOLD_CHAR: + string++; + if (apply_style) + gui_window_chat_remove_color_style (window, A_BOLD); + break; + case GUI_ATTR_REVERSE_CHAR: + case GUI_ATTR_REVERSE2_CHAR: + string++; + if (apply_style) + gui_window_chat_remove_color_style (window, A_REVERSE); + break; + case GUI_ATTR_UNDERLINE_CHAR: + string++; + if (apply_style) + gui_window_chat_remove_color_style (window, A_UNDERLINE); + break; + } + break; + case GUI_ATTR_ITALIC_CHAR: + string++; + break; + case GUI_ATTR_UNDERLINE_CHAR: + string++; + if (apply_style) + gui_window_chat_toggle_style (window, A_UNDERLINE); + break; + default: + if (string[0] < 32) + string++; + else + return utf8_next_char ((char *)string); + } + } - return (length % width == 0) ? (length / width) : ((length / width) + 1); + /* nothing found except color/attrib codes, so return NULL */ + return NULL; } /* - * gui_display_end_of_line: display end of a line in the chat window + * gui_display_word_raw: display word on chat buffer, letter by letter + * special chars like color, bold, .. are interpreted */ void -gui_display_end_of_line (t_gui_window *window, t_gui_line *line, int count) +gui_display_word_raw (t_gui_window *window, char *string) { - /* TODO: display end of line! */ + /*char *prev_char, *next_char, saved_char;*/ + + /* TODO: write this function for Gtk */ (void) window; - (void) line; - (void) count; + (void) string; } /* - * gui_display_line: display a line in the chat window - * if stop_at_end == 1, screen will not scroll and then we - * exit since chat window is full - * returns: 1 if stop_at_end == 0 or screen not full - * 0 if screen is full and if stop_at_end == 1 + * gui_display_word: display a word on chat buffer */ -int -gui_display_line (t_gui_window *window, t_gui_line *line, int stop_at_end) +void +gui_display_word (t_gui_window *window, + t_gui_line *line, + char *data, + char *end_offset, + int num_lines, int count, int *lines_displayed, int simulate) { - /* TODO: display line! */ + /*char *end_line, saved_char_end, saved_char; + int pos_saved_char, chars_to_display, num_displayed;*/ + + /* TODO: write this function for Gtk */ (void) window; (void) line; - (void) stop_at_end; - return 1; + (void) data; + (void) end_offset; + (void) num_lines; + (void) count; + (void) lines_displayed; + (void) simulate; } /* - * gui_draw_window_chat: draw chat window + * gui_get_word_info: returns info about next word: beginning, end, length */ void -gui_draw_window_chat (t_gui_window *window) +gui_get_word_info (t_gui_window *window, + char *data, + int *word_start_offset, int *word_end_offset, + int *word_length_with_spaces, int *word_length) { - /* TODO: manage splitted windows! */ - if (window != gui_current_window) - return; + char *start_data, *prev_char, *next_char; + int leading_spaces, char_size; + + *word_start_offset = 0; + *word_end_offset = 0; + *word_length_with_spaces = 0; + *word_length = 0; - /* TODO: draw chat window */ + start_data = data; + + leading_spaces = 1; + while (data && data[0]) + { + next_char = gui_word_get_next_char (window, (unsigned char *)data, 0); + if (next_char) + { + prev_char = utf8_prev_char (data, next_char); + if (prev_char) + { + if (prev_char[0] != ' ') + { + if (leading_spaces) + *word_start_offset = prev_char - start_data; + leading_spaces = 0; + char_size = next_char - prev_char; + *word_end_offset = next_char - start_data - 1; + (*word_length_with_spaces) += char_size; + (*word_length) += char_size; + } + else + { + if (leading_spaces) + (*word_length_with_spaces)++; + else + { + *word_end_offset = prev_char - start_data - 1; + return; + } + } + data = next_char; + } + } + else + { + *word_end_offset = data + strlen (data) - start_data - 1; + return; + } + } } /* - * gui_redraw_window_chat: redraw chat window + * gui_display_line: display a line in the chat window + * if count == 0, display whole line + * if count > 0, display 'count' lines (beginning from the end) + * if simulate == 1, nothing is displayed (for counting how + * many lines would have been lines displayed) + * returns: number of lines displayed (or simulated) */ -void -gui_redraw_window_chat (t_gui_window *window) +int +gui_display_line (t_gui_window *window, t_gui_line *line, int count, int simulate) { - /* TODO: manage splitted windows! */ - if (window != gui_current_window) - return; - - /* TODO: first delete window content */ - gui_draw_window_chat (window); + /* TODO: write this function for Gtk */ + (void) window; + (void) line; + (void) count; + (void) simulate; + return 1; } /* - * gui_draw_window_nick: draw nick window + * gui_calculate_line_diff: returns pointer to line & offset for a difference + * with given line */ void -gui_draw_window_nick (t_gui_window *window) +gui_calculate_line_diff (t_gui_window *window, t_gui_line **line, int *line_pos, + int difference) { - /* TODO: manage splitted windows! */ - if (window != gui_current_window) + int backward, current_size; + + if (!line || !line_pos) return; - /* TODO: display nicklist for Gtk GUI */ + backward = (difference < 0); + + if (!(*line)) + { + /* if looking backward, start at last line of buffer */ + if (backward) + { + *line = window->buffer->last_line; + if (!(*line)) + return; + current_size = gui_display_line (window, *line, 0, 1); + if (current_size == 0) + current_size = 1; + *line_pos = current_size - 1; + } + /* if looking forward, start at first line of buffer */ + else + { + *line = window->buffer->lines; + if (!(*line)) + return; + *line_pos = 0; + current_size = gui_display_line (window, *line, 0, 1); + } + } + else + current_size = gui_display_line (window, *line, 0, 1); + + while ((*line) && (difference != 0)) + { + /* looking backward */ + if (backward) + { + if (*line_pos > 0) + (*line_pos)--; + else + { + *line = (*line)->prev_line; + if (*line) + { + current_size = gui_display_line (window, *line, 0, 1); + if (current_size == 0) + current_size = 1; + *line_pos = current_size - 1; + } + } + difference++; + } + /* looking forward */ + else + { + if (*line_pos < current_size - 1) + (*line_pos)++; + else + { + *line = (*line)->next_line; + if (*line) + { + current_size = gui_display_line (window, *line, 0, 1); + if (current_size == 0) + current_size = 1; + *line_pos = 0; + } + } + difference--; + } + } + + /* first or last line reached */ + if (!(*line)) + { + if (backward) + { + /* first line reached */ + *line = window->buffer->lines; + *line_pos = 0; + } + else + { + /* last line reached => consider we'll display all until the end */ + *line_pos = 0; + } + } } /* - * gui_redraw_window_nick: redraw nick window + * gui_draw_buffer_chat: draw chat window for a buffer */ void -gui_redraw_window_nick (t_gui_window *window) +gui_draw_buffer_chat (t_gui_buffer *buffer, int erase) { - /* TODO: manage splitted windows! */ - if (window != gui_current_window) + /*t_gui_window *ptr_win; + t_gui_line *ptr_line; + t_irc_dcc *dcc_first, *dcc_selected, *ptr_dcc; + char format_empty[32]; + int i, j, line_pos, count, num_bars; + char *unit_name[] = { N_("bytes"), N_("Kb"), N_("Mb"), N_("Gb") }; + char *unit_format[] = { "%.0Lf", "%.1Lf", "%.02Lf", "%.02Lf" }; + long unit_divide[] = { 1, 1024, 1024*1024, 1024*1024,1024 }; + int num_unit; + char format[32], date[128], *buf; + struct tm *date_tmp;*/ + + if (!gui_ok) return; - /* TODO: first delete window content */ - gui_draw_window_nick (window); + /* TODO: write this function for Gtk */ + (void) buffer; + (void) erase; } /* - * gui_draw_window_status: draw status window + * gui_draw_buffer_chat_line: add a line to chat window for a buffer */ void -gui_draw_window_status (t_gui_window *window) +gui_draw_buffer_chat_line (t_gui_buffer *buffer, t_gui_line *line) { - /* TODO: manage splitted windows! */ - if (window != gui_current_window) - return; + t_gui_window *ptr_win; + unsigned char *text_without_color; + GtkTextIter start, end; - /* TODO: draw status window! */ + ptr_win = gui_buffer_find_window (buffer); + if (ptr_win) + { + text_without_color = gui_color_decode ((unsigned char *)(line->data), 0); + if (text_without_color) + { + gtk_text_buffer_insert_at_cursor (ptr_win->textbuffer_chat, + (char *)text_without_color, -1); + gtk_text_buffer_insert_at_cursor (ptr_win->textbuffer_chat, + "\n", -1); + gtk_text_buffer_get_bounds (ptr_win->textbuffer_chat, + &start, &end); + /* TODO */ + /*gtk_text_buffer_apply_tag (ptr_win->textbuffer_chat, ptr_win->texttag_chat, &start, &end);*/ + free (text_without_color); + } + } } /* - * gui_redraw_window_status: redraw status window + * gui_draw_buffer_nick: draw nick window for a buffer */ void -gui_redraw_window_status (t_gui_window *window) +gui_draw_buffer_nick (t_gui_buffer *buffer, int erase) { - /* TODO: manage splitted windows! */ - if (window != gui_current_window) + /*t_gui_window *ptr_win; + int i, j, x, y, column, max_length, nicks_displayed; + char format[32], format_empty[32]; + t_irc_nick *ptr_nick;*/ + + if (!gui_ok || !BUFFER_HAS_NICKLIST(buffer)) return; - /* TODO: first delete window content */ - gui_draw_window_status (window); + /* TODO: write this function for Gtk */ + (void) buffer; + (void) erase; } /* - * gui_draw_window_infobar: draw infobar window + * gui_draw_buffer_status: draw status window for a buffer */ void -gui_draw_window_infobar (t_gui_window *window) +gui_draw_buffer_status (t_gui_buffer *buffer, int erase) { - /* TODO: manage splitted windows! */ - if (window != gui_current_window) + /*t_gui_window *ptr_win; + t_weechat_hotlist *ptr_hotlist; + char format[32], str_nicks[32], *more; + int i, first_mode, x, server_pos, server_total; + int display_name, names_count;*/ + + /* make gcc happy */ + (void) buffer; + + if (!gui_ok) return; - /* TODO: draw infobar window! */ + /* TODO: write this function for Gtk */ + (void) buffer; + (void) erase; } /* - * gui_redraw_window_infobar: redraw infobar window + * gui_draw_buffer_infobar_time: draw time in infobar window */ void -gui_redraw_window_infobar (t_gui_window *window) +gui_draw_buffer_infobar_time (t_gui_buffer *buffer) { - /* TODO: manage splitted windows! */ - if (window != gui_current_window) + /*t_gui_window *ptr_win; + time_t time_seconds; + struct tm *local_time;*/ + + /* make gcc happy */ + (void) buffer; + + if (!gui_ok) return; - /* TODO: first delete window content */ - gui_draw_window_infobar (window); + /* TODO: write this function for Gtk */ + (void) buffer; } /* - * gui_draw_window_input: draw input window + * gui_draw_buffer_infobar: draw infobar window for a buffer */ void -gui_draw_window_input (t_gui_window *window) +gui_draw_buffer_infobar (t_gui_buffer *buffer, int erase) { - /* TODO: manage splitted windows! */ - if (window != gui_current_window) + /*t_gui_window *ptr_win; + time_t time_seconds; + struct tm *local_time; + char text_time[1024 + 1];*/ + + /* make gcc happy */ + (void) buffer; + + if (!gui_ok) return; - /* TODO: draw input window */ + /* TODO: write this function for Gtk */ + (void) buffer; + (void) erase; } /* - * gui_redraw_window_input: redraw input window + * gui_get_input_width: return input width (max # chars displayed) */ -void -gui_redraw_window_input (t_gui_window *window) +int +gui_get_input_width (t_gui_window *window, char *nick) { - /* TODO: manage splitted windows! */ - if (window != gui_current_window) - return; - - /* TODO: first delete window content */ - gui_draw_window_input (window); + if (CHANNEL(window->buffer)) + return (window->win_width - strlen (CHANNEL(window->buffer)->name) - + strlen (nick) - 4); + else + return (window->win_width - strlen (nick) - 3); } /* - * gui_redraw_window: redraw a window + * gui_draw_buffer_input: draw input window for a buffer */ void -gui_redraw_window (t_gui_window *window) +gui_draw_buffer_input (t_gui_buffer *buffer, int erase) { - /* TODO: manage splitted windows! */ - if (window != gui_current_window) + /*t_gui_window *ptr_win; + char format[32]; + char *ptr_nickname; + int input_width; + t_irc_dcc *dcc_selected;*/ + + if (!gui_ok) return; - gui_redraw_window_title (window); - gui_redraw_window_chat (window); - if (gui_window_has_nicklist (window)) - gui_redraw_window_nick (window); - gui_redraw_window_status (window); - gui_redraw_window_input (window); + /* TODO: write this function for Gtk */ + (void) buffer; + (void) erase; } /* - * gui_switch_to_window: switch to another window + * gui_redraw_buffer: redraw a buffer */ void -gui_switch_to_window (t_gui_window *window) +gui_redraw_buffer (t_gui_buffer *buffer) { t_gui_window *ptr_win; - GtkTextIter start, end; + + if (!gui_ok) + return; for (ptr_win = gui_windows; ptr_win; ptr_win = ptr_win->next_window) { - if (ptr_win->is_displayed) + if (ptr_win->buffer == buffer) { - /* TODO: manage splitted windows */ - ptr_win->is_displayed = 0; - break; + gui_draw_buffer_title (buffer, 1); + gui_draw_buffer_chat (buffer, 1); + if (ptr_win->win_nick) + gui_draw_buffer_nick (buffer, 1); + gui_draw_buffer_status (buffer, 1); + if (cfg_look_infobar) + gui_draw_buffer_infobar (buffer, 1); + gui_draw_buffer_input (buffer, 1); } } +} + +/* + * gui_switch_to_buffer: switch to another buffer + */ + +void +gui_switch_to_buffer (t_gui_window *window, t_gui_buffer *buffer) +{ + GtkTextIter start, end; + + if (window->buffer->num_displayed > 0) + window->buffer->num_displayed--; + if (window->buffer != buffer) + { + window->buffer->last_read_line = window->buffer->last_line; + if (buffer->last_read_line == buffer->last_line) + buffer->last_read_line = NULL; + } + + window->buffer = buffer; + window->win_nick_start = 0; gui_calculate_pos_size (window); if (!window->textview_chat) @@ -460,13 +1334,12 @@ gui_switch_to_window (t_gui_window *window) window->textbuffer_chat = gtk_text_buffer_new (NULL); gtk_text_view_set_buffer (GTK_TEXT_VIEW (window->textview_chat), window->textbuffer_chat); - window->texttag_chat = gtk_text_buffer_create_tag(window->textbuffer_chat, "courier", "font_family", "lucida"); + /*window->texttag_chat = gtk_text_buffer_create_tag(window->textbuffer_chat, "courier", "font_family", "lucida");*/ gtk_text_buffer_get_bounds (window->textbuffer_chat, &start, &end); gtk_text_buffer_apply_tag (window->textbuffer_chat, window->texttag_chat, &start, &end); } - if (WIN_IS_CHANNEL (window) && !window->textbuffer_nicklist) + if (BUFFER_IS_CHANNEL(buffer) && !window->textbuffer_nicklist) { - window->textview_nicklist = gtk_text_view_new (); gtk_widget_show (window->textview_nicklist); gtk_container_add (GTK_CONTAINER (scrolledwindow_nick), window->textview_nicklist); @@ -477,91 +1350,225 @@ gui_switch_to_window (t_gui_window *window) gtk_text_view_set_buffer (GTK_TEXT_VIEW (window->textview_nicklist), window->textbuffer_nicklist); } - /* change current window to the new window */ - gui_current_window = window; + window->start_line = NULL; + window->start_line_pos = 0; - window->is_displayed = 1; - window->unread_data = 0; + buffer->num_displayed++; + + hotlist_remove_buffer (buffer); } /* - * gui_switch_to_previous_window: switch to previous window + * gui_window_page_up: display previous page on buffer */ void -gui_switch_to_previous_window () +gui_window_page_up (t_gui_window *window) { - /* if only one windows then return */ - if (gui_windows == last_gui_window) + if (!gui_ok) return; - if (gui_current_window->prev_window) - gui_switch_to_window (gui_current_window->prev_window); - else - gui_switch_to_window (last_gui_window); - gui_redraw_window (gui_current_window); + if (!window->first_line_displayed) + { + gui_calculate_line_diff (window, &window->start_line, + &window->start_line_pos, + (window->start_line) ? + (-1) * (window->win_chat_height - 1) : + (-1) * ((window->win_chat_height - 1) * 2)); + gui_draw_buffer_chat (window->buffer, 0); + gui_draw_buffer_status (window->buffer, 0); + } } /* - * gui_switch_to_next_window: switch to next window + * gui_window_page_down: display next page on buffer */ void -gui_switch_to_next_window () +gui_window_page_down (t_gui_window *window) { - /* if only one windows then return */ - if (gui_windows == last_gui_window) + t_gui_line *ptr_line; + int line_pos; + + if (!gui_ok) return; - if (gui_current_window->next_window) - gui_switch_to_window (gui_current_window->next_window); - else - gui_switch_to_window (gui_windows); - gui_redraw_window (gui_current_window); + if (window->start_line) + { + gui_calculate_line_diff (window, &window->start_line, + &window->start_line_pos, + window->win_chat_height - 1); + + /* check if we can display all */ + ptr_line = window->start_line; + line_pos = window->start_line_pos; + gui_calculate_line_diff (window, &ptr_line, + &line_pos, + window->win_chat_height - 1); + if (!ptr_line) + { + window->start_line = NULL; + window->start_line_pos = 0; + } + + gui_draw_buffer_chat (window->buffer, 0); + gui_draw_buffer_status (window->buffer, 0); + } +} + +/* + * gui_window_scroll_up: display previous few lines in buffer + */ + +void +gui_window_scroll_up (t_gui_window *window) +{ + if (!gui_ok) + return; + + if (!window->first_line_displayed) + { + gui_calculate_line_diff (window, &window->start_line, + &window->start_line_pos, + (window->start_line) ? + (-1) * cfg_look_scroll_amount : + (-1) * ( (window->win_chat_height - 1) + cfg_look_scroll_amount)); + gui_draw_buffer_chat (window->buffer, 0); + gui_draw_buffer_status (window->buffer, 0); + } } /* - * gui_move_page_up: display previous page on window + * gui_window_scroll_down: display next few lines in buffer */ void -gui_move_page_up () +gui_window_scroll_down (t_gui_window *window) { - if (!gui_current_window->first_line_displayed) + t_gui_line *ptr_line; + int line_pos; + + if (!gui_ok) + return; + + if (window->start_line) { - gui_current_window->sub_lines += gui_current_window->win_chat_height - 1; - gui_redraw_window_chat (gui_current_window); - gui_redraw_window_status (gui_current_window); + gui_calculate_line_diff (window, &window->start_line, + &window->start_line_pos, + cfg_look_scroll_amount); + + /* check if we can display all */ + ptr_line = window->start_line; + line_pos = window->start_line_pos; + gui_calculate_line_diff (window, &ptr_line, + &line_pos, + window->win_chat_height - 1); + + if (!ptr_line) + { + window->start_line = NULL; + window->start_line_pos = 0; + } + + gui_draw_buffer_chat (window->buffer, 0); + gui_draw_buffer_status (window->buffer, 0); + } +} + +/* + * gui_window_nick_beginning: go to beginning of nicklist + */ + +void +gui_window_nick_beginning (t_gui_window *window) +{ + if (!gui_ok) + return; + + if (BUFFER_HAS_NICKLIST(window->buffer)) + { + if (window->win_nick_start > 0) + { + window->win_nick_start = 0; + gui_draw_buffer_nick (window->buffer, 1); + } + } +} + +/* + * gui_window_nick_end: go to the end of nicklist + */ + +void +gui_window_nick_end (t_gui_window *window) +{ + int new_start; + + if (!gui_ok) + return; + + if (BUFFER_HAS_NICKLIST(window->buffer)) + { + new_start = + CHANNEL(window->buffer)->nicks_count - window->win_nick_height; + if (new_start < 0) + new_start = 0; + else if (new_start >= 1) + new_start++; + + if (new_start != window->win_nick_start) + { + window->win_nick_start = new_start; + gui_draw_buffer_nick (window->buffer, 1); + } } } /* - * gui_move_page_down: display next page on window + * gui_window_nick_page_up: scroll one page up in nicklist */ void -gui_move_page_down () +gui_window_nick_page_up (t_gui_window *window) { - if (gui_current_window->sub_lines > 0) + if (!gui_ok) + return; + + if (BUFFER_HAS_NICKLIST(window->buffer)) { - gui_current_window->sub_lines -= gui_current_window->win_chat_height - 1; - if (gui_current_window->sub_lines < 0) - gui_current_window->sub_lines = 0; - if (gui_current_window->sub_lines == 0) - gui_current_window->unread_data = 0; - gui_redraw_window_chat (gui_current_window); - gui_redraw_window_status (gui_current_window); + if (window->win_nick_start > 0) + { + window->win_nick_start -= (window->win_nick_height - 1); + if (window->win_nick_start <= 1) + window->win_nick_start = 0; + gui_draw_buffer_nick (window->buffer, 1); + } } } /* - * gui_gtk_resize_handler: called when term size is modified + * gui_window_nick_page_down: scroll one page down in nicklist */ void -gui_gtk_resize_handler () +gui_window_nick_page_down (t_gui_window *window) { - /* TODO: write resize handler for Gtk */ + if (!gui_ok) + return; + + if (BUFFER_HAS_NICKLIST(window->buffer)) + { + if ((CHANNEL(window->buffer)->nicks_count > window->win_nick_height) + && (window->win_nick_start + window->win_nick_height - 1 + < CHANNEL(window->buffer)->nicks_count)) + { + if (window->win_nick_start == 0) + window->win_nick_start += (window->win_nick_height - 1); + else + window->win_nick_start += (window->win_nick_height - 2); + gui_draw_buffer_nick (window->buffer, 1); + } + } } /* @@ -579,34 +1586,562 @@ gui_window_init_subwindows (t_gui_window *window) } /* + * gui_window_auto_resize: auto-resize all windows, according to % of global size + * This function is called after a terminal resize. + * Returns 0 if ok, -1 if all window should be merged + * (not enough space according to windows %) + */ + +int +gui_window_auto_resize (t_gui_window_tree *tree, + int x, int y, int width, int height, + int simulate) +{ + int size1, size2; + + if (tree) + { + if (tree->window) + { + if ((width < WINDOW_MIN_WIDTH) || (height < WINDOW_MIN_HEIGHT)) + return -1; + if (!simulate) + { + tree->window->win_x = x; + tree->window->win_y = y; + tree->window->win_width = width; + tree->window->win_height = height; + } + } + else + { + if (tree->split_horiz) + { + size1 = (height * tree->split_pct) / 100; + size2 = height - size1; + if (gui_window_auto_resize (tree->child1, x, y + size1, + width, size2, simulate) < 0) + return -1; + if (gui_window_auto_resize (tree->child2, x, y, + width, size1, simulate) < 0) + return -1; + } + else + { + size1 = (width * tree->split_pct) / 100; + size2 = width - size1 - 1; + if (gui_window_auto_resize (tree->child1, x, y, + size1, height, simulate) < 0) + return -1; + if (gui_window_auto_resize (tree->child2, x + size1 + 1, y, + size2, height, simulate) < 0) + return -1; + } + } + } + return 0; +} + +/* + * gui_refresh_windows: auto resize and refresh all windows + */ + +void +gui_refresh_windows () +{ + /*t_gui_window *ptr_win, *old_current_window;*/ + + if (gui_ok) + { + /* TODO: write this function for Gtk */ + } +} + +/* + * gui_window_split_horiz: split a window horizontally + */ + +void +gui_window_split_horiz (t_gui_window *window, int pourcentage) +{ + t_gui_window *new_window; + int height1, height2; + + if (!gui_ok) + return; + + height1 = (window->win_height * pourcentage) / 100; + height2 = window->win_height - height1; + + if ((height1 >= WINDOW_MIN_HEIGHT) && (height2 >= WINDOW_MIN_HEIGHT) + && (pourcentage > 0) && (pourcentage <= 100)) + { + if ((new_window = gui_window_new (window, + window->win_x, window->win_y, + window->win_width, height1, + 100, pourcentage))) + { + /* reduce old window height (bottom window) */ + window->win_y = new_window->win_y + new_window->win_height; + window->win_height = height2; + window->win_height_pct = 100 - pourcentage; + + /* assign same buffer for new window (top window) */ + new_window->buffer = window->buffer; + new_window->buffer->num_displayed++; + + gui_switch_to_buffer (window, window->buffer); + + gui_current_window = new_window; + gui_switch_to_buffer (gui_current_window, gui_current_window->buffer); + gui_redraw_buffer (gui_current_window->buffer); + } + } +} + +/* + * gui_window_split_vertic: split a window vertically + */ + +void +gui_window_split_vertic (t_gui_window *window, int pourcentage) +{ + t_gui_window *new_window; + int width1, width2; + + if (!gui_ok) + return; + + width1 = (window->win_width * pourcentage) / 100; + width2 = window->win_width - width1 - 1; + + if ((width1 >= WINDOW_MIN_WIDTH) && (width2 >= WINDOW_MIN_WIDTH) + && (pourcentage > 0) && (pourcentage <= 100)) + { + if ((new_window = gui_window_new (window, + window->win_x + width1 + 1, window->win_y, + width2, window->win_height, + pourcentage, 100))) + { + /* reduce old window height (left window) */ + window->win_width = width1; + window->win_width_pct = 100 - pourcentage; + + /* assign same buffer for new window (right window) */ + new_window->buffer = window->buffer; + new_window->buffer->num_displayed++; + + gui_switch_to_buffer (window, window->buffer); + + gui_current_window = new_window; + gui_switch_to_buffer (gui_current_window, gui_current_window->buffer); + gui_redraw_buffer (gui_current_window->buffer); + + /* create & draw separator */ + gui_draw_window_separator (gui_current_window); + } + } +} + +/* + * gui_window_resize: resize window + */ + +void +gui_window_resize (t_gui_window *window, int pourcentage) +{ + /* TODO: write this function for Gtk */ + (void) window; + (void) pourcentage; +} + +/* + * gui_window_merge: merge window with its sister + */ + +int +gui_window_merge (t_gui_window *window) +{ + t_gui_window_tree *parent, *sister; + + parent = window->ptr_tree->parent_node; + if (parent) + { + sister = (parent->child1->window == window) ? + parent->child2 : parent->child1; + + if (!(sister->window)) + return 0; + + if (window->win_y == sister->window->win_y) + { + /* horizontal merge */ + window->win_width += sister->window->win_width + 1; + window->win_width_pct += sister->window->win_width_pct; + } + else + { + /* vertical merge */ + window->win_height += sister->window->win_height; + window->win_height_pct += sister->window->win_height_pct; + } + if (sister->window->win_x < window->win_x) + window->win_x = sister->window->win_x; + if (sister->window->win_y < window->win_y) + window->win_y = sister->window->win_y; + + gui_window_free (sister->window); + gui_window_tree_node_to_leaf (parent, window); + + gui_switch_to_buffer (window, window->buffer); + gui_redraw_buffer (window->buffer); + return 1; + } + return 0; +} + +/* + * gui_window_merge_all: merge all windows into only one + */ + +void +gui_window_merge_all (t_gui_window *window) +{ + /* TODO: write this function for Gtk */ + (void) window; +} + +/* + * gui_window_side_by_side: return a code about position of 2 windows: + * 0 = they're not side by side + * 1 = side by side (win2 is over the win1) + * 2 = side by side (win2 on the right) + * 3 = side by side (win2 below win1) + * 4 = side by side (win2 on the left) + */ + +int +gui_window_side_by_side (t_gui_window *win1, t_gui_window *win2) +{ + /* win2 over win1 ? */ + if (win2->win_y + win2->win_height == win1->win_y) + { + if (win2->win_x >= win1->win_x + win1->win_width) + return 0; + if (win2->win_x + win2->win_width <= win1->win_x) + return 0; + return 1; + } + + /* win2 on the right ? */ + if (win2->win_x == win1->win_x + win1->win_width + 1) + { + if (win2->win_y >= win1->win_y + win1->win_height) + return 0; + if (win2->win_y + win2->win_height <= win1->win_y) + return 0; + return 2; + } + + /* win2 below win1 ? */ + if (win2->win_y == win1->win_y + win1->win_height) + { + if (win2->win_x >= win1->win_x + win1->win_width) + return 0; + if (win2->win_x + win2->win_width <= win1->win_x) + return 0; + return 3; + } + + /* win2 on the left ? */ + if (win2->win_x + win2->win_width + 1 == win1->win_x) + { + if (win2->win_y >= win1->win_y + win1->win_height) + return 0; + if (win2->win_y + win2->win_height <= win1->win_y) + return 0; + return 4; + } + + return 0; +} + +/* + * gui_window_switch_up: search and switch to a window over current window + */ + +void +gui_window_switch_up (t_gui_window *window) +{ + t_gui_window *ptr_win; + + for (ptr_win = gui_windows; ptr_win; + ptr_win = ptr_win->next_window) + { + if ((ptr_win != window) && + (gui_window_side_by_side (window, ptr_win) == 1)) + { + gui_current_window = ptr_win; + gui_switch_to_buffer (gui_current_window, gui_current_window->buffer); + gui_redraw_buffer (gui_current_window->buffer); + return; + } + } +} + +/* + * gui_window_switch_down: search and switch to a window below current window + */ + +void +gui_window_switch_down (t_gui_window *window) +{ + t_gui_window *ptr_win; + + for (ptr_win = gui_windows; ptr_win; + ptr_win = ptr_win->next_window) + { + if ((ptr_win != window) && + (gui_window_side_by_side (window, ptr_win) == 3)) + { + gui_current_window = ptr_win; + gui_switch_to_buffer (gui_current_window, gui_current_window->buffer); + gui_redraw_buffer (gui_current_window->buffer); + return; + } + } +} + +/* + * gui_window_switch_left: search and switch to a window on the left of current window + */ + +void +gui_window_switch_left (t_gui_window *window) +{ + t_gui_window *ptr_win; + + for (ptr_win = gui_windows; ptr_win; + ptr_win = ptr_win->next_window) + { + if ((ptr_win != window) && + (gui_window_side_by_side (window, ptr_win) == 4)) + { + gui_current_window = ptr_win; + gui_switch_to_buffer (gui_current_window, gui_current_window->buffer); + gui_redraw_buffer (gui_current_window->buffer); + return; + } + } +} + +/* + * gui_window_switch_right: search and switch to a window on the right of current window + */ + +void +gui_window_switch_right (t_gui_window *window) +{ + t_gui_window *ptr_win; + + for (ptr_win = gui_windows; ptr_win; + ptr_win = ptr_win->next_window) + { + if ((ptr_win != window) && + (gui_window_side_by_side (window, ptr_win) == 2)) + { + gui_current_window = ptr_win; + gui_switch_to_buffer (gui_current_window, gui_current_window->buffer); + gui_redraw_buffer (gui_current_window->buffer); + return; + } + } +} + +/* + * gui_refresh_screen: called when term size is modified + */ + +void +gui_refresh_screen () +{ + /* TODO: write this function for Gtk */ +} + +/* + * gui_refresh_screen_sigwinch: called when signal SIGWINCH is received + */ + +void +gui_refresh_screen_sigwinch () +{ + gui_refresh_screen (); + signal (SIGWINCH, gui_refresh_screen_sigwinch); +} + +/* * gui_pre_init: pre-initialize GUI (called before gui_init) */ void gui_pre_init (int *argc, char **argv[]) { - /* Initialise Gtk+ */ + /* Initialise Gtk */ gtk_init (argc, argv); } /* + * gui_init_color_pairs: init color pairs + */ + +void +gui_init_color_pairs () +{ + /* This function does nothing in Gtk GUI */ +} + +/* + * gui_init_weechat_colors: init WeeChat colors + */ + +void +gui_init_weechat_colors () +{ + int i; + + /* init WeeChat colors */ + gui_color[COLOR_WIN_SEPARATOR] = gui_color_build (COLOR_WIN_SEPARATOR, cfg_col_separator, cfg_col_separator); + gui_color[COLOR_WIN_TITLE] = gui_color_build (COLOR_WIN_TITLE, cfg_col_title, cfg_col_title_bg); + gui_color[COLOR_WIN_CHAT] = gui_color_build (COLOR_WIN_CHAT, cfg_col_chat, cfg_col_chat_bg); + gui_color[COLOR_WIN_CHAT_TIME] = gui_color_build (COLOR_WIN_CHAT_TIME, cfg_col_chat_time, cfg_col_chat_bg); + gui_color[COLOR_WIN_CHAT_TIME_SEP] = gui_color_build (COLOR_WIN_CHAT_TIME_SEP, cfg_col_chat_time_sep, cfg_col_chat_bg); + gui_color[COLOR_WIN_CHAT_PREFIX1] = gui_color_build (COLOR_WIN_CHAT_PREFIX1, cfg_col_chat_prefix1, cfg_col_chat_bg); + gui_color[COLOR_WIN_CHAT_PREFIX2] = gui_color_build (COLOR_WIN_CHAT_PREFIX2, cfg_col_chat_prefix2, cfg_col_chat_bg); + gui_color[COLOR_WIN_CHAT_SERVER] = gui_color_build (COLOR_WIN_CHAT_SERVER, cfg_col_chat_server, cfg_col_chat_bg); + gui_color[COLOR_WIN_CHAT_JOIN] = gui_color_build (COLOR_WIN_CHAT_JOIN, cfg_col_chat_join, cfg_col_chat_bg); + gui_color[COLOR_WIN_CHAT_PART] = gui_color_build (COLOR_WIN_CHAT_PART, cfg_col_chat_part, cfg_col_chat_bg); + gui_color[COLOR_WIN_CHAT_NICK] = gui_color_build (COLOR_WIN_CHAT_NICK, cfg_col_chat_nick, cfg_col_chat_bg); + gui_color[COLOR_WIN_CHAT_HOST] = gui_color_build (COLOR_WIN_CHAT_HOST, cfg_col_chat_host, cfg_col_chat_bg); + gui_color[COLOR_WIN_CHAT_CHANNEL] = gui_color_build (COLOR_WIN_CHAT_CHANNEL, cfg_col_chat_channel, cfg_col_chat_bg); + gui_color[COLOR_WIN_CHAT_DARK] = gui_color_build (COLOR_WIN_CHAT_DARK, cfg_col_chat_dark, cfg_col_chat_bg); + gui_color[COLOR_WIN_CHAT_HIGHLIGHT] = gui_color_build (COLOR_WIN_CHAT_HIGHLIGHT, cfg_col_chat_highlight, cfg_col_chat_bg); + gui_color[COLOR_WIN_CHAT_READ_MARKER] = gui_color_build (COLOR_WIN_CHAT_READ_MARKER, cfg_col_chat_read_marker, cfg_col_chat_read_marker_bg); + gui_color[COLOR_WIN_STATUS] = gui_color_build (COLOR_WIN_STATUS, cfg_col_status, cfg_col_status_bg); + gui_color[COLOR_WIN_STATUS_DELIMITERS] = gui_color_build (COLOR_WIN_STATUS_DELIMITERS, cfg_col_status_delimiters, cfg_col_status_bg); + gui_color[COLOR_WIN_STATUS_CHANNEL] = gui_color_build (COLOR_WIN_STATUS_CHANNEL, cfg_col_status_channel, cfg_col_status_bg); + gui_color[COLOR_WIN_STATUS_DATA_MSG] = gui_color_build (COLOR_WIN_STATUS_DATA_MSG, cfg_col_status_data_msg, cfg_col_status_bg); + gui_color[COLOR_WIN_STATUS_DATA_PRIVATE] = gui_color_build (COLOR_WIN_STATUS_DATA_PRIVATE, cfg_col_status_data_private, cfg_col_status_bg); + gui_color[COLOR_WIN_STATUS_DATA_HIGHLIGHT] = gui_color_build (COLOR_WIN_STATUS_DATA_HIGHLIGHT, cfg_col_status_data_highlight, cfg_col_status_bg); + gui_color[COLOR_WIN_STATUS_DATA_OTHER] = gui_color_build (COLOR_WIN_STATUS_DATA_OTHER, cfg_col_status_data_other, cfg_col_status_bg); + gui_color[COLOR_WIN_STATUS_MORE] = gui_color_build (COLOR_WIN_STATUS_MORE, cfg_col_status_more, cfg_col_status_bg); + gui_color[COLOR_WIN_INFOBAR] = gui_color_build (COLOR_WIN_INFOBAR, cfg_col_infobar, cfg_col_infobar_bg); + gui_color[COLOR_WIN_INFOBAR_DELIMITERS] = gui_color_build (COLOR_WIN_INFOBAR_DELIMITERS, cfg_col_infobar_delimiters, cfg_col_infobar_bg); + gui_color[COLOR_WIN_INFOBAR_HIGHLIGHT] = gui_color_build (COLOR_WIN_INFOBAR_HIGHLIGHT, cfg_col_infobar_highlight, cfg_col_infobar_bg); + gui_color[COLOR_WIN_INPUT] = gui_color_build (COLOR_WIN_INPUT, cfg_col_input, cfg_col_input_bg); + gui_color[COLOR_WIN_INPUT_CHANNEL] = gui_color_build (COLOR_WIN_INPUT_CHANNEL, cfg_col_input_channel, cfg_col_input_bg); + gui_color[COLOR_WIN_INPUT_NICK] = gui_color_build (COLOR_WIN_INPUT_NICK, cfg_col_input_nick, cfg_col_input_bg); + gui_color[COLOR_WIN_INPUT_DELIMITERS] = gui_color_build (COLOR_WIN_INPUT_DELIMITERS, cfg_col_input_delimiters, cfg_col_input_bg); + gui_color[COLOR_WIN_NICK] = gui_color_build (COLOR_WIN_NICK, cfg_col_nick, cfg_col_nick_bg); + gui_color[COLOR_WIN_NICK_AWAY] = gui_color_build (COLOR_WIN_NICK_AWAY, cfg_col_nick_away, cfg_col_nick_bg); + gui_color[COLOR_WIN_NICK_CHANOWNER] = gui_color_build (COLOR_WIN_NICK_CHANOWNER, cfg_col_nick_chanowner, cfg_col_nick_bg); + gui_color[COLOR_WIN_NICK_CHANADMIN] = gui_color_build (COLOR_WIN_NICK_CHANADMIN, cfg_col_nick_chanadmin, cfg_col_nick_bg); + gui_color[COLOR_WIN_NICK_OP] = gui_color_build (COLOR_WIN_NICK_OP, cfg_col_nick_op, cfg_col_nick_bg); + gui_color[COLOR_WIN_NICK_HALFOP] = gui_color_build (COLOR_WIN_NICK_HALFOP, cfg_col_nick_halfop, cfg_col_nick_bg); + gui_color[COLOR_WIN_NICK_VOICE] = gui_color_build (COLOR_WIN_NICK_VOICE, cfg_col_nick_voice, cfg_col_nick_bg); + gui_color[COLOR_WIN_NICK_MORE] = gui_color_build (COLOR_WIN_NICK_MORE, cfg_col_nick_more, cfg_col_nick_bg); + gui_color[COLOR_WIN_NICK_SEP] = gui_color_build (COLOR_WIN_NICK_SEP, cfg_col_nick_sep, cfg_col_nick_bg); + gui_color[COLOR_WIN_NICK_SELF] = gui_color_build (COLOR_WIN_NICK_SELF, cfg_col_nick_self, cfg_col_nick_bg); + gui_color[COLOR_WIN_NICK_PRIVATE] = gui_color_build (COLOR_WIN_NICK_PRIVATE, cfg_col_nick_private, cfg_col_nick_bg); + + for (i = 0; i < COLOR_WIN_NICK_NUMBER; i++) + { + gui_color[COLOR_WIN_NICK_1 + i] = gui_color_build (COLOR_WIN_NICK_1 + i, cfg_col_nick_colors[i], cfg_col_chat_bg); + } + + gui_color[COLOR_DCC_SELECTED] = gui_color_build (COLOR_DCC_SELECTED, cfg_col_dcc_selected, cfg_col_chat_bg); + gui_color[COLOR_DCC_WAITING] = gui_color_build (COLOR_DCC_WAITING, cfg_col_dcc_waiting, cfg_col_chat_bg); + gui_color[COLOR_DCC_CONNECTING] = gui_color_build (COLOR_DCC_CONNECTING, cfg_col_dcc_connecting, cfg_col_chat_bg); + gui_color[COLOR_DCC_ACTIVE] = gui_color_build (COLOR_DCC_ACTIVE, cfg_col_dcc_active, cfg_col_chat_bg); + gui_color[COLOR_DCC_DONE] = gui_color_build (COLOR_DCC_DONE, cfg_col_dcc_done, cfg_col_chat_bg); + gui_color[COLOR_DCC_FAILED] = gui_color_build (COLOR_DCC_FAILED, cfg_col_dcc_failed, cfg_col_chat_bg); + gui_color[COLOR_DCC_ABORTED] = gui_color_build (COLOR_DCC_ABORTED, cfg_col_dcc_aborted, cfg_col_chat_bg); +} + +/* + * gui_rebuild_weechat_colors: rebuild WeeChat colors + */ + +void +gui_rebuild_weechat_colors () +{ + int i; + + for (i = 0; i < NUM_COLORS; i++) + { + if (gui_color[i]) + { + if (gui_color[i]->string) + free (gui_color[i]->string); + free (gui_color[i]); + gui_color[i] = NULL; + } + } + gui_init_weechat_colors (); +} + +/* * gui_init_colors: init GUI colors */ void gui_init_colors () { - /* TODO: init colors for Gtk */ + gui_init_color_pairs (); + gui_init_weechat_colors (); } /* - * gui_set_window_title: set window title + * gui_set_window_title: set terminal title */ void gui_set_window_title () { - /* TODO: set window title for Gtk */ + char *envterm = getenv ("TERM"); + + if (envterm) + { + if (strcmp( envterm, "sun-cmd") == 0) + printf ("\033]l%s %s\033\\", PACKAGE_NAME, PACKAGE_VERSION); + else if (strcmp(envterm, "hpterm") == 0) + printf ("\033&f0k%dD%s %s", strlen(PACKAGE_NAME) + + strlen(PACKAGE_VERSION) + 1, + PACKAGE_NAME, PACKAGE_VERSION); + /* the following term supports the xterm excapes */ + else if (strncmp (envterm, "xterm", 5) == 0 + || strncmp (envterm, "rxvt", 4) == 0 + || strcmp (envterm, "Eterm") == 0 + || strcmp (envterm, "aixterm") == 0 + || strcmp (envterm, "iris-ansi") == 0 + || strcmp (envterm, "dtterm") == 0) + printf ("\33]0;%s %s\7", PACKAGE_NAME, PACKAGE_VERSION); + else if (strcmp (envterm, "screen") == 0) + { + printf ("\033k%s %s\033\\", PACKAGE_NAME, PACKAGE_VERSION); + /* tryning to set the title of a backgrounded xterm like terminal */ + printf ("\33]0;%s %s\7", PACKAGE_NAME, PACKAGE_VERSION); + } + } +} + +/* + * gui_reset_window_title: reset terminal title + */ + +void +gui_reset_window_title () +{ + /* This function does nothing in Gtk GUI */ } /* @@ -616,9 +2151,28 @@ gui_set_window_title () void gui_init () { + GdkColor color_fg, color_bg; + GtkRcStyle *rc_style; + + gui_init_colors (); + + gui_infobar = NULL; + + gui_ok = 1; + + /* init clipboard buffer */ + gui_input_clipboard = NULL; + + /* create Gtk widgets */ + + gdk_color_parse ("white", &color_fg); + gdk_color_parse ("black", &color_bg); + gtk_main_window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_set_title (GTK_WINDOW (gtk_main_window), PACKAGE_STRING); + g_signal_connect (G_OBJECT (gtk_main_window), "destroy", gtk_main_quit, NULL); + vbox1 = gtk_vbox_new (FALSE, 0); gtk_widget_show (vbox1); gtk_container_add (GTK_CONTAINER (gtk_main_window), vbox1); @@ -626,6 +2180,8 @@ gui_init () entry_topic = gtk_entry_new (); gtk_widget_show (entry_topic); gtk_box_pack_start (GTK_BOX (vbox1), entry_topic, FALSE, FALSE, 0); + gtk_widget_modify_text (entry_topic, GTK_STATE_NORMAL, &color_fg); + gtk_widget_modify_base (entry_topic, GTK_STATE_NORMAL, &color_bg); notebook1 = gtk_notebook_new (); gtk_widget_show (notebook1); @@ -640,19 +2196,32 @@ gui_init () gtk_widget_show (hbox1); gtk_box_pack_start (GTK_BOX (vbox2), hbox1, TRUE, TRUE, 0); + hpaned1 = gtk_hpaned_new (); + gtk_widget_show (hpaned1); + gtk_box_pack_start (GTK_BOX (hbox1), hpaned1, TRUE, TRUE, 0); + gtk_paned_set_position (GTK_PANED (hpaned1), 0); + scrolledwindow_chat = gtk_scrolled_window_new (NULL, NULL); gtk_widget_show (scrolledwindow_chat); - gtk_box_pack_start (GTK_BOX (hbox1), scrolledwindow_chat, TRUE, TRUE, 0); + gtk_paned_pack1 (GTK_PANED (hpaned1), scrolledwindow_chat, FALSE, TRUE); + //gtk_box_pack_start (GTK_PANED (hpaned1), scrolledwindow_chat, TRUE, TRUE, 0); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow_chat), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS); + gtk_widget_modify_text (scrolledwindow_chat, GTK_STATE_NORMAL, &color_fg); + gtk_widget_modify_base (scrolledwindow_chat, GTK_STATE_NORMAL, &color_bg); scrolledwindow_nick = gtk_scrolled_window_new (NULL, NULL); gtk_widget_show (scrolledwindow_nick); - gtk_box_pack_start (GTK_BOX (hbox1), scrolledwindow_nick, TRUE, TRUE, 0); + gtk_paned_pack2 (GTK_PANED (hpaned1), scrolledwindow_nick, FALSE, TRUE); + //gtk_box_pack_start (GTK_PANED (hpaned1), scrolledwindow_nick, TRUE, TRUE, 0); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow_nick), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS); + gtk_widget_modify_text (scrolledwindow_nick, GTK_STATE_NORMAL, &color_fg); + gtk_widget_modify_base (scrolledwindow_nick, GTK_STATE_NORMAL, &color_bg); entry_input = gtk_entry_new (); gtk_widget_show (entry_input); gtk_box_pack_start (GTK_BOX (vbox2), entry_input, FALSE, FALSE, 0); + gtk_widget_modify_text (entry_input, GTK_STATE_NORMAL, &color_fg); + gtk_widget_modify_base (entry_input, GTK_STATE_NORMAL, &color_bg); label1 = gtk_label_new (_("server")); gtk_widget_show (label1); @@ -661,11 +2230,19 @@ gui_init () gtk_widget_show_all (gtk_main_window); - /* create a new window */ - gui_current_window = gui_window_new (NULL, NULL, 1 /*0, 0, COLS, LINES*/); - - /* TODO: set gui_ready to 1 when Gtk display functions will be ok */ - gui_ready = 1; + /* create new window/buffer */ + if (gui_window_new (NULL, 0, 0, 0, 0, 100, 100)) + { + gui_current_window = gui_windows; + gui_buffer_new (gui_windows, NULL, NULL, 0, 1); + + signal (SIGWINCH, gui_refresh_screen_sigwinch); + + if (cfg_look_set_title) + gui_set_window_title (); + + gui_init_ok = 1; + } } /* @@ -677,113 +2254,33 @@ gui_end () { t_gui_window *ptr_win; + /* free clipboard buffer */ + if (gui_input_clipboard) + free(gui_input_clipboard); + /* delete all windows */ for (ptr_win = gui_windows; ptr_win; ptr_win = ptr_win->next_window) { - /* TODO: delete Gtk windows */ - /* TODO: free input buffer, lines, messages, completion */ + /* TODO: destroy Gtk widgets */ } -} - -/* - * gui_add_message: add a message to a window - */ - -void -gui_add_message (t_gui_window *window, int type, int color, char *message) -{ - char *pos; - int length; - GtkTextIter start, end; - /* create new line if previous was ending by '\n' (or if 1st line) */ - if (window->line_complete) - { - gtk_text_buffer_insert_at_cursor (window->textbuffer_chat, "\n", -1); - window->line_complete = 0; - } + /* delete all buffers */ + while (gui_buffers) + gui_buffer_free (gui_buffers, 0); - pos = strchr (message, '\n'); - if (pos) - { - pos[0] = '\0'; - window->line_complete = 1; - } + /* delete all windows */ + while (gui_windows) + gui_window_free (gui_windows); + gui_window_tree_free (&gui_windows_tree); - gtk_text_buffer_insert_at_cursor (window->textbuffer_chat, message, -1); - gtk_text_buffer_get_bounds (window->textbuffer_chat, &start, &end); - gtk_text_buffer_apply_tag (window->textbuffer_chat, window->texttag_chat, &start, &end); + /* delete global history */ + history_global_free (); - if (pos) - pos[0] = '\n'; -} + /* delete infobar messages */ + while (gui_infobar) + gui_infobar_remove (); -/* - * gui_printf_color_type: display a message in a window - */ - -void -gui_printf_color_type (t_gui_window *window, int type, int color, char *message, ...) -{ - static char buffer[8192]; - char timestamp[16]; - char *pos; - va_list argptr; - static time_t seconds; - struct tm *date_tmp; - - if (gui_ready) - { - if (color == -1) - color = COLOR_WIN_CHAT; - - if (window == NULL) - { - if (SERVER(gui_current_window)) - window = SERVER(gui_current_window)->window; - else - window = gui_current_window; - } - - if (window == NULL) - { - wee_log_printf ("gui_printf without window! this is a bug, please send to developers - thanks\n"); - return; - } - } - - va_start (argptr, message); - vsnprintf (buffer, sizeof (buffer) - 1, message, argptr); - va_end (argptr); - - if (gui_ready) - { - seconds = time (NULL); - date_tmp = localtime (&seconds); - - pos = buffer - 1; - while (pos) - { - /* TODO: read timestamp format from config! */ - if (window->line_complete) - { - gui_add_message (window, MSG_TYPE_TIME, COLOR_WIN_CHAT_DARK, "["); - sprintf (timestamp, "%02d", date_tmp->tm_hour); - gui_add_message (window, MSG_TYPE_TIME, COLOR_WIN_CHAT_TIME, timestamp); - gui_add_message (window, MSG_TYPE_TIME, COLOR_WIN_CHAT_TIME_SEP, ":"); - sprintf (timestamp, "%02d", date_tmp->tm_min); - gui_add_message (window, MSG_TYPE_TIME, COLOR_WIN_CHAT_TIME, timestamp); - gui_add_message (window, MSG_TYPE_TIME, COLOR_WIN_CHAT_TIME_SEP, ":"); - sprintf (timestamp, "%02d", date_tmp->tm_sec); - gui_add_message (window, MSG_TYPE_TIME, COLOR_WIN_CHAT_TIME, timestamp); - gui_add_message (window, MSG_TYPE_TIME, COLOR_WIN_CHAT_DARK, "] "); - } - gui_add_message (window, type, color, pos + 1); - pos = strchr (pos + 1, '\n'); - if (pos && !pos[1]) - pos = NULL; - } - } - else - g_print ("%s", buffer); + /* reset title */ + if (cfg_look_set_title) + gui_reset_window_title (); } diff --git a/weechat/src/gui/gtk/gui-input.c b/weechat/src/gui/gtk/gui-input.c index 297d6404f..79555fc4c 100644 --- a/weechat/src/gui/gtk/gui-input.c +++ b/weechat/src/gui/gtk/gui-input.c @@ -37,26 +37,154 @@ #include "../gui.h" #include "../../common/weeconfig.h" #include "../../common/command.h" +#include "../../common/hotlist.h" +#include "../../common/fifo.h" +#include "../../common/utf8.h" #include "../../irc/irc.h" /* - * gui_read_keyb: read keyboard line + * gui_input_default_key_bindings: create default key bindings */ void -gui_read_keyb () +gui_input_default_key_bindings () { - /* TODO: read keyboard for Gtk GUI */ + int i; + char key_str[32], command[32]; + + /* keys binded with internal functions */ + gui_key_bind ( /* RC */ "ctrl-M", "return"); + gui_key_bind ( /* RC */ "ctrl-J", "return"); + gui_key_bind ( /* tab */ "ctrl-I", "tab"); + gui_key_bind ( /* basckp */ "ctrl-H", "backspace"); + gui_key_bind ( /* basckp */ "ctrl-?", "backspace"); + gui_key_bind ( /* del */ "meta2-3~", "delete"); + gui_key_bind ( /* ^K */ "ctrl-K", "delete_end_line"); + gui_key_bind ( /* ^U */ "ctrl-U", "delete_beginning_line"); + gui_key_bind ( /* ^W */ "ctrl-W", "delete_previous_word"); + gui_key_bind ( /* ^Y */ "ctrl-Y", "clipboard_paste"); + gui_key_bind ( /* ^T */ "ctrl-T", "transpose_chars"); + gui_key_bind ( /* home */ "meta2-1~", "home"); + gui_key_bind ( /* home */ "meta2-H", "home"); + gui_key_bind ( /* home */ "meta2-7~", "home"); + gui_key_bind ( /* ^A */ "ctrl-A", "home"); + gui_key_bind ( /* end */ "meta2-4~", "end"); + gui_key_bind ( /* end */ "meta2-F", "end"); + gui_key_bind ( /* end */ "meta2-8~", "end"); + gui_key_bind ( /* ^E */ "ctrl-E", "end"); + gui_key_bind ( /* left */ "meta2-D", "left"); + gui_key_bind ( /* right */ "meta2-C", "right"); + gui_key_bind ( /* up */ "meta2-A", "up"); + gui_key_bind ( /* ^up */ "meta-Oa", "up_global"); + gui_key_bind ( /* down */ "meta2-B", "down"); + gui_key_bind ( /* ^down */ "meta-Ob", "down_global"); + gui_key_bind ( /* pgup */ "meta2-5~", "page_up"); + gui_key_bind ( /* pgdn */ "meta2-6~", "page_down"); + gui_key_bind ( /* m-pgup */ "meta-meta2-5~", "scroll_up"); + gui_key_bind ( /* m-pgdn */ "meta-meta2-6~", "scroll_down"); + gui_key_bind ( /* F10 */ "meta2-21~", "infobar_clear"); + gui_key_bind ( /* F11 */ "meta2-23~", "nick_page_up"); + gui_key_bind ( /* F12 */ "meta2-24~", "nick_page_down"); + gui_key_bind ( /* m-F11 */ "meta-meta2-1~", "nick_beginning"); + gui_key_bind ( /* m-F12 */ "meta-meta2-4~", "nick_end"); + gui_key_bind ( /* ^L */ "ctrl-L", "refresh"); + gui_key_bind ( /* m-a */ "meta-a", "jump_smart"); + gui_key_bind ( /* m-b */ "meta-b", "previous_word"); + gui_key_bind ( /* ^left */ "meta-Od", "previous_word"); + gui_key_bind ( /* m-d */ "meta-d", "delete_next_word"); + gui_key_bind ( /* m-f */ "meta-f", "next_word"); + gui_key_bind ( /* ^right */ "meta-Oc", "next_word"); + gui_key_bind ( /* m-h */ "meta-h", "hotlist_clear"); + gui_key_bind ( /* m-j,m-d */ "meta-jmeta-d", "jump_dcc"); + gui_key_bind ( /* m-j,m-l */ "meta-jmeta-l", "jump_last_buffer"); + gui_key_bind ( /* m-j,m-s */ "meta-jmeta-s", "jump_server"); + gui_key_bind ( /* m-j,m-x */ "meta-jmeta-x", "jump_next_server"); + gui_key_bind ( /* m-k */ "meta-k", "grab_key"); + gui_key_bind ( /* m-n */ "meta-n", "scroll_next_highlight"); + gui_key_bind ( /* m-p */ "meta-p", "scroll_previous_highlight"); + gui_key_bind ( /* m-r */ "meta-r", "delete_line"); + gui_key_bind ( /* m-s */ "meta-s", "switch_server"); + gui_key_bind ( /* m-u */ "meta-u", "scroll_unread"); + + /* keys binded with commands */ + gui_key_bind ( /* m-left */ "meta-meta2-D", "/buffer -1"); + gui_key_bind ( /* F5 */ "meta2-15~", "/buffer -1"); + gui_key_bind ( /* m-right */ "meta-meta2-C", "/buffer +1"); + gui_key_bind ( /* F6 */ "meta2-17~", "/buffer +1"); + gui_key_bind ( /* F7 */ "meta2-18~", "/window -1"); + gui_key_bind ( /* F8 */ "meta2-19~", "/window +1"); + gui_key_bind ( /* m-w,m-up */ "meta-wmeta-meta2-A", "/window up"); + gui_key_bind ( /* m-w,m-down */ "meta-wmeta-meta2-B", "/window down"); + gui_key_bind ( /* m-w,m-left */ "meta-wmeta-meta2-D", "/window left"); + gui_key_bind ( /* m-w,m-right */ "meta-wmeta-meta2-C", "/window right"); + gui_key_bind ( /* m-0 */ "meta-0", "/buffer 10"); + gui_key_bind ( /* m-1 */ "meta-1", "/buffer 1"); + gui_key_bind ( /* m-2 */ "meta-2", "/buffer 2"); + gui_key_bind ( /* m-3 */ "meta-3", "/buffer 3"); + gui_key_bind ( /* m-4 */ "meta-4", "/buffer 4"); + gui_key_bind ( /* m-5 */ "meta-5", "/buffer 5"); + gui_key_bind ( /* m-6 */ "meta-6", "/buffer 6"); + gui_key_bind ( /* m-7 */ "meta-7", "/buffer 7"); + gui_key_bind ( /* m-8 */ "meta-8", "/buffer 8"); + gui_key_bind ( /* m-9 */ "meta-9", "/buffer 9"); + + /* bind meta-j + {01..99} to switch to buffers # > 10 */ + for (i = 1; i < 100; i++) + { + sprintf (key_str, "meta-j%02d", i); + sprintf (command, "/buffer %d", i); + gui_key_bind (key_str, command); + } } /* - * gui_main_loop: main loop for WeeChat with Gtk GUI + * gui_input_grab_end: insert grabbed key in input buffer + */ + +void +gui_input_grab_end () +{ + char *expanded_key; + + /* get expanded name (for example: ^U => ctrl-u) */ + expanded_key = gui_key_get_expanded_name (gui_key_buffer); + + if (expanded_key) + { + if (gui_current_window->buffer->has_input) + { + gui_insert_string_input (gui_current_window, expanded_key, -1); + gui_current_window->buffer->input_buffer_pos += utf8_strlen (expanded_key); + gui_draw_buffer_input (gui_current_window->buffer, 1); + } + free (expanded_key); + } + + /* end grab mode */ + gui_key_grab = 0; + gui_key_grab_count = 0; + gui_key_buffer[0] = '\0'; +} + +/* + * gui_input_read: read keyboard chars + */ + +void +gui_input_read () +{ + /* TODO: write this function for Gtk */ +} + +/* + * gui_main_loop: main loop for WeeChat with ncurses GUI */ void gui_main_loop () { - /* TODO: main loop function for Gtk GUI */ + /* TODO: write this function for Gtk */ gtk_main (); } + diff --git a/weechat/src/gui/gui-common.c b/weechat/src/gui/gui-common.c index 445fe9b34..52545c3ac 100644 --- a/weechat/src/gui/gui-common.c +++ b/weechat/src/gui/gui-common.c @@ -366,6 +366,27 @@ gui_buffer_servers_search () } /* + * gui_get_dcc_buffer: get pointer to DCC buffer (DCC buffer created if not existing) + */ + +t_gui_buffer * +gui_get_dcc_buffer (t_gui_window *window) +{ + t_gui_buffer *ptr_buffer; + + /* check if dcc buffer exists */ + for (ptr_buffer = gui_buffers; ptr_buffer; ptr_buffer = ptr_buffer->next_buffer) + { + if (ptr_buffer->dcc) + break; + } + if (ptr_buffer) + return ptr_buffer; + else + return gui_buffer_new (window, NULL, NULL, 1, 0); +} + +/* * gui_buffer_new: create a new buffer in current window */ @@ -848,7 +869,10 @@ gui_add_to_line (t_gui_buffer *buffer, int type, char *message) { pos[0] = '\n'; if (buffer->num_displayed > 0) + { + gui_draw_buffer_chat_line (buffer, buffer->last_line); gui_draw_buffer_chat (buffer, 0); + } if (gui_add_hotlist && (buffer->num_displayed == 0)) { if (3 - buffer->last_line->line_with_message - diff --git a/weechat/src/gui/gui.h b/weechat/src/gui/gui.h index 2e50bcc6e..f05ee22f6 100644 --- a/weechat/src/gui/gui.h +++ b/weechat/src/gui/gui.h @@ -404,6 +404,7 @@ extern void gui_window_tree_free (t_gui_window_tree **); extern t_gui_window *gui_window_new (t_gui_window *, int, int, int, int, int, int); extern t_gui_buffer *gui_buffer_search (char *, char *); extern t_gui_window *gui_buffer_find_window (t_gui_buffer *); +extern t_gui_buffer *gui_get_dcc_buffer (t_gui_window *); extern t_gui_buffer *gui_buffer_new (t_gui_window *, void *, void *, int, int); extern void gui_buffer_clear (t_gui_buffer *); extern void gui_buffer_clear_all (); @@ -505,6 +506,7 @@ extern void gui_calculate_pos_size (t_gui_window *); extern void gui_draw_buffer_title (t_gui_buffer *, int); extern char *gui_word_get_next_char (t_gui_window *, unsigned char *, int); extern void gui_draw_buffer_chat (t_gui_buffer *, int); +extern void gui_draw_buffer_chat_line (t_gui_buffer *, t_gui_line *); extern void gui_draw_buffer_nick (t_gui_buffer *, int); extern void gui_draw_buffer_status (t_gui_buffer *, int); extern void gui_draw_buffer_infobar_time (t_gui_buffer *); @@ -512,7 +514,6 @@ extern void gui_draw_buffer_infobar (t_gui_buffer *, int); extern void gui_draw_buffer_input (t_gui_buffer *, int); extern void gui_redraw_buffer (t_gui_buffer *); extern void gui_switch_to_buffer (t_gui_window *, t_gui_buffer *); -extern t_gui_buffer *gui_get_dcc_buffer (t_gui_window *); extern void gui_window_page_up (t_gui_window *); extern void gui_window_page_down (t_gui_window *); extern void gui_window_scroll_up (t_gui_window *); |