diff options
Diffstat (limited to 'src/gui/gtk/gui-display.c')
-rw-r--r-- | src/gui/gtk/gui-display.c | 2185 |
1 files changed, 1841 insertions, 344 deletions
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 (); } |