diff options
30 files changed, 1252 insertions, 337 deletions
@@ -1,10 +1,11 @@ WeeChat - Wee Enhanced Environment for Chat =========================================== -ChangeLog - 2008-03-22 +ChangeLog - 2008-03-28 Version 0.2.7 (under dev!): + * added new type of buffer, with free content * added tags for lines and custom filtering by tags or regex (task #7674) * added custom bars, with custom items * command /whois is now authorized in private without argument (task #7482) diff --git a/src/gui/curses/gui-curses-chat.c b/src/gui/curses/gui-curses-chat.c index 2e7375e1f..e82b441b1 100644 --- a/src/gui/curses/gui-curses-chat.c +++ b/src/gui/curses/gui-curses-chat.c @@ -71,8 +71,8 @@ gui_chat_remove_style (struct t_gui_window *window, int style) void gui_chat_toggle_style (struct t_gui_window *window, int style) { - window->current_style_attr ^= style; - if (window->current_style_attr & style) + GUI_CURSES(window)->current_style_attr ^= style; + if (GUI_CURSES(window)->current_style_attr & style) gui_chat_set_style (window, style); else gui_chat_remove_style (window, style); @@ -86,10 +86,10 @@ gui_chat_toggle_style (struct t_gui_window *window, int style) void gui_chat_reset_style (struct t_gui_window *window) { - window->current_style_fg = -1; - window->current_style_bg = -1; - window->current_style_attr = 0; - window->current_color_attr = 0; + GUI_CURSES(window)->current_style_fg = -1; + GUI_CURSES(window)->current_style_bg = -1; + GUI_CURSES(window)->current_style_attr = 0; + GUI_CURSES(window)->current_color_attr = 0; gui_window_set_weechat_color (GUI_CURSES(window)->win_chat, GUI_COLOR_CHAT); gui_chat_remove_style (window, @@ -103,7 +103,7 @@ gui_chat_reset_style (struct t_gui_window *window) void gui_chat_set_color_style (struct t_gui_window *window, int style) { - window->current_color_attr |= style; + GUI_CURSES(window)->current_color_attr |= style; wattron (GUI_CURSES(window)->win_chat, style); } @@ -114,7 +114,7 @@ gui_chat_set_color_style (struct t_gui_window *window, int style) void gui_chat_remove_color_style (struct t_gui_window *window, int style) { - window->current_color_attr &= !style; + GUI_CURSES(window)->current_color_attr &= !style; wattroff (GUI_CURSES(window)->win_chat, style); } @@ -125,8 +125,9 @@ gui_chat_remove_color_style (struct t_gui_window *window, int style) void gui_chat_reset_color_style (struct t_gui_window *window) { - wattroff (GUI_CURSES(window)->win_chat, window->current_color_attr); - window->current_color_attr = 0; + wattroff (GUI_CURSES(window)->win_chat, + GUI_CURSES(window)->current_color_attr); + GUI_CURSES(window)->current_color_attr = 0; } /* @@ -136,6 +137,9 @@ gui_chat_reset_color_style (struct t_gui_window *window) void gui_chat_set_color (struct t_gui_window *window, int fg, int bg) { + GUI_CURSES(window)->current_style_fg = fg; + GUI_CURSES(window)->current_style_bg = bg; + if (((fg == -1) || (fg == 99)) && ((bg == -1) || (bg == 99))) wattron (GUI_CURSES(window)->win_chat, COLOR_PAIR(63)); @@ -156,12 +160,81 @@ gui_chat_set_color (struct t_gui_window *window, int fg, int bg) void gui_chat_set_weechat_color (struct t_gui_window *window, int weechat_color) { - gui_chat_reset_style (window); - gui_chat_set_style (window, - gui_color[weechat_color]->attributes); - gui_chat_set_color (window, - gui_color[weechat_color]->foreground, - gui_color[weechat_color]->background); + if ((weechat_color >= 0) && (weechat_color < GUI_NUM_COLORS)) + { + gui_chat_reset_style (window); + gui_chat_set_style (window, + gui_color[weechat_color]->attributes); + gui_chat_set_color (window, + gui_color[weechat_color]->foreground, + gui_color[weechat_color]->background); + } +} + +/* + * gui_chat_set_custom_color_fg_bg: set a custom color for a chat window + * (foreground and background) + */ + +void +gui_chat_set_custom_color_fg_bg (struct t_gui_window *window, int fg, int bg) +{ + if ((fg >= 0) && (fg < GUI_CURSES_NUM_WEECHAT_COLORS) + && (bg >= 0) && (bg < GUI_CURSES_NUM_WEECHAT_COLORS)) + { + gui_chat_reset_style (window); + gui_chat_set_style (window, + gui_weechat_colors[fg].attributes); + gui_chat_set_color (window, + gui_weechat_colors[fg].foreground, + gui_weechat_colors[bg].foreground); + } +} + +/* + * gui_chat_set_custom_color_fg: set a custom color for a chat window + * (foreground only) + */ + +void +gui_chat_set_custom_color_fg (struct t_gui_window *window, int fg) +{ + int current_attr, current_bg; + + if ((fg >= 0) && (fg < GUI_CURSES_NUM_WEECHAT_COLORS)) + { + current_attr = GUI_CURSES(window)->current_style_attr; + current_bg = GUI_CURSES(window)->current_style_bg; + gui_chat_reset_style (window); + gui_chat_set_color_style (window, current_attr); + gui_chat_remove_color_style (window, A_BOLD); + gui_chat_set_color_style (window, gui_weechat_colors[fg].attributes); + gui_chat_set_color (window, + gui_weechat_colors[fg].foreground, + current_bg); + } +} + +/* + * gui_chat_set_custom_color_bg: set a custom color for a chat window + * (background only) + */ + +void +gui_chat_set_custom_color_bg (struct t_gui_window *window, int bg) +{ + int current_attr, current_fg; + + if ((bg >= 0) && (bg < GUI_CURSES_NUM_WEECHAT_COLORS)) + { + current_attr = GUI_CURSES(window)->current_style_attr; + current_fg = GUI_CURSES(window)->current_style_fg; + gui_chat_reset_style (window); + gui_chat_set_color_style (window, current_attr); + gui_chat_set_color (window, + current_fg, + gui_weechat_colors[bg].foreground); + } } /* @@ -295,8 +368,8 @@ char * gui_chat_string_next_char (struct t_gui_window *window, unsigned char *string, int apply_style) { - char str_fg[3]; - int weechat_color; + char str_fg[3], str_bg[3]; + int weechat_color, fg, bg; while (string[0]) { @@ -309,17 +382,69 @@ gui_chat_string_next_char (struct t_gui_window *window, unsigned char *string, break; case GUI_COLOR_COLOR_CHAR: string++; - if (isdigit (string[0]) && isdigit (string[1])) + switch (string[0]) { - 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_chat_set_weechat_color (window, weechat_color); - } + case 'F': + if (string[1] && string[2]) + { + if (apply_style) + { + str_fg[0] = string[1]; + str_fg[1] = string[2]; + str_fg[2] = '\0'; + sscanf (str_fg, "%d", &fg); + gui_chat_set_custom_color_fg (window, fg); + } + string += 3; + } + break; + case 'B': + if (string[1] && string[2]) + { + if (apply_style) + { + str_bg[0] = string[1]; + str_bg[1] = string[2]; + str_bg[2] = '\0'; + sscanf (str_bg, "%d", &bg); + gui_chat_set_custom_color_bg (window, bg); + } + string += 3; + } + break; + case '*': + if (string[1] && string[2] && (string[3] == ',') + && string[4] && string[5]) + { + if (apply_style) + { + str_fg[0] = string[1]; + str_fg[1] = string[2]; + str_fg[2] = '\0'; + str_bg[0] = string[4]; + str_bg[1] = string[5]; + str_bg[2] = '\0'; + sscanf (str_fg, "%d", &fg); + sscanf (str_bg, "%d", &bg); + gui_chat_set_custom_color_fg_bg (window, fg, bg); + } + string += 6; + } + break; + default: + if (isdigit (string[0]) && isdigit (string[1])) + { + if (apply_style) + { + str_fg[0] = string[0]; + str_fg[1] = string[1]; + str_fg[2] = '\0'; + sscanf (str_fg, "%d", &weechat_color); + gui_chat_set_weechat_color (window, weechat_color); + } + string += 2; + } + break; } break; case GUI_COLOR_SET_CHAR: @@ -853,6 +978,29 @@ gui_chat_display_line (struct t_gui_window *window, struct t_gui_line *line, } /* + * gui_chat_display_line_y: display a line in the chat window (for a buffer + * with free content) + */ + +void +gui_chat_display_line_y (struct t_gui_window *window, struct t_gui_line *line, + int y) +{ + /* reset color & style for a new line */ + gui_chat_reset_style (window); + + window->win_chat_cursor_x = 0; + window->win_chat_cursor_y = y; + + wmove (GUI_CURSES(window)->win_chat, + window->win_chat_cursor_y, + window->win_chat_cursor_x); + wclrtoeol (GUI_CURSES(window)->win_chat); + + gui_chat_display_word_raw (window, line->message, 1); +} + +/* * gui_chat_calculate_line_diff: returns pointer to line & offset for a * difference with given line */ @@ -963,7 +1111,7 @@ gui_chat_draw (struct t_gui_buffer *buffer, int erase) struct t_gui_line *ptr_line; /*t_irc_dcc *dcc_first, *dcc_selected, *ptr_dcc;*/ char format_empty[32]; - int i, line_pos, count, old_scroll; + int i, line_pos, count, old_scroll, y_start, y_end; /*int j, num_bars; unsigned long pct_complete; char *unit_name[] = { N_("bytes"), N_("KB"), N_("MB"), N_("GB") }; @@ -978,7 +1126,7 @@ gui_chat_draw (struct t_gui_buffer *buffer, int erase) for (ptr_win = gui_windows; ptr_win; ptr_win = ptr_win->next_window) { - if ((ptr_win->buffer == buffer) && (buffer->num_displayed > 0)) + if (ptr_win->buffer == buffer) { if (erase) { @@ -1134,79 +1282,116 @@ gui_chat_draw (struct t_gui_buffer *buffer, int erase) { ptr_win->win_chat_cursor_x = 0; ptr_win->win_chat_cursor_y = 0; - - /* display at position of scrolling */ - if (ptr_win->start_line) - { - ptr_line = ptr_win->start_line; - line_pos = ptr_win->start_line_pos; - } - else - { - /* look for first line to display, starting from last line */ - ptr_line = NULL; - line_pos = 0; - gui_chat_calculate_line_diff (ptr_win, &ptr_line, &line_pos, - (-1) * (ptr_win->win_chat_height - 1)); - } - if (line_pos > 0) - { - /* display end of first line at top of screen */ - gui_chat_display_line (ptr_win, ptr_line, - gui_chat_display_line (ptr_win, - ptr_line, - 0, 1) - - line_pos, 0); - ptr_line = gui_chat_get_next_line_displayed (ptr_line); - ptr_win->first_line_displayed = 0; - } - else - ptr_win->first_line_displayed = - (ptr_line == gui_chat_get_first_line_displayed (ptr_win->buffer)); - - /* display lines */ - count = 0; - while (ptr_line && (ptr_win->win_chat_cursor_y <= ptr_win->win_chat_height - 1)) + switch (ptr_win->buffer->type) { - count = gui_chat_display_line (ptr_win, ptr_line, 0, 0); - ptr_line = gui_chat_get_next_line_displayed (ptr_line); - } - - old_scroll = ptr_win->scroll; - - ptr_win->scroll = (ptr_win->win_chat_cursor_y > ptr_win->win_chat_height - 1); - - /* check if last line of buffer is entirely displayed and scrolling */ - /* if so, disable scroll indicator */ - if (!ptr_line && ptr_win->scroll) - { - if (count == gui_chat_display_line (ptr_win, ptr_win->buffer->last_line, 0, 1)) - ptr_win->scroll = 0; - } - - if (ptr_win->scroll != old_scroll) - { - hook_signal_send ("window_scrolled", - WEECHAT_HOOK_SIGNAL_POINTER, ptr_win); - } - - if (!ptr_win->scroll - && (ptr_win->start_line == gui_chat_get_first_line_displayed (ptr_win->buffer))) - { - ptr_win->start_line = NULL; - ptr_win->start_line_pos = 0; - } - - /* cursor is below end line of chat window? */ - if (ptr_win->win_chat_cursor_y > ptr_win->win_chat_height - 1) - { - ptr_win->win_chat_cursor_x = 0; - ptr_win->win_chat_cursor_y = ptr_win->win_chat_height - 1; + case GUI_BUFFER_TYPE_FORMATED: + /* display at position of scrolling */ + if (ptr_win->start_line) + { + ptr_line = ptr_win->start_line; + line_pos = ptr_win->start_line_pos; + } + else + { + /* look for first line to display, starting from last line */ + ptr_line = NULL; + line_pos = 0; + gui_chat_calculate_line_diff (ptr_win, &ptr_line, &line_pos, + (-1) * (ptr_win->win_chat_height - 1)); + } + + if (line_pos > 0) + { + /* display end of first line at top of screen */ + gui_chat_display_line (ptr_win, ptr_line, + gui_chat_display_line (ptr_win, + ptr_line, + 0, 1) - + line_pos, 0); + ptr_line = gui_chat_get_next_line_displayed (ptr_line); + ptr_win->first_line_displayed = 0; + } + else + ptr_win->first_line_displayed = + (ptr_line == gui_chat_get_first_line_displayed (ptr_win->buffer)); + + /* display lines */ + count = 0; + while (ptr_line && (ptr_win->win_chat_cursor_y <= ptr_win->win_chat_height - 1)) + { + count = gui_chat_display_line (ptr_win, ptr_line, 0, 0); + ptr_line = gui_chat_get_next_line_displayed (ptr_line); + } + + old_scroll = ptr_win->scroll; + + ptr_win->scroll = (ptr_win->win_chat_cursor_y > ptr_win->win_chat_height - 1); + + /* check if last line of buffer is entirely displayed and scrolling */ + /* if so, disable scroll indicator */ + if (!ptr_line && ptr_win->scroll) + { + if (count == gui_chat_display_line (ptr_win, ptr_win->buffer->last_line, 0, 1)) + ptr_win->scroll = 0; + } + + if (ptr_win->scroll != old_scroll) + { + hook_signal_send ("window_scrolled", + WEECHAT_HOOK_SIGNAL_POINTER, ptr_win); + } + + if (!ptr_win->scroll + && (ptr_win->start_line == gui_chat_get_first_line_displayed (ptr_win->buffer))) + { + ptr_win->start_line = NULL; + ptr_win->start_line_pos = 0; + } + + /* cursor is below end line of chat window? */ + if (ptr_win->win_chat_cursor_y > ptr_win->win_chat_height - 1) + { + ptr_win->win_chat_cursor_x = 0; + ptr_win->win_chat_cursor_y = ptr_win->win_chat_height - 1; + } + break; + case GUI_BUFFER_TYPE_FREE: + /* display at position of scrolling */ + ptr_line = (ptr_win->start_line) ? + ptr_win->start_line : buffer->lines; + if (ptr_line) + { + if (!ptr_line->displayed) + ptr_line = gui_chat_get_next_line_displayed (ptr_line); + if (ptr_line) + { + y_start = (ptr_win->start_line) ? ptr_line->y : 0; + y_end = y_start + ptr_win->win_chat_height - 1; + while (ptr_line && (ptr_line->y <= y_end)) + { + if (ptr_line->refresh_needed || erase) + { + gui_chat_display_line_y (ptr_win, ptr_line, + ptr_line->y - y_start); + } + ptr_line = gui_chat_get_next_line_displayed (ptr_line); + } + } + } } } wnoutrefresh (GUI_CURSES(ptr_win)->win_chat); refresh (); + + if (buffer->type == GUI_BUFFER_TYPE_FREE) + { + for (ptr_line = buffer->lines; ptr_line; + ptr_line = ptr_line->next_line) + { + ptr_line->refresh_needed = 0; + } + } } } } diff --git a/src/gui/curses/gui-curses-color.c b/src/gui/curses/gui-curses-color.c index 6d0fa729f..8c7476b9e 100644 --- a/src/gui/curses/gui-curses-color.c +++ b/src/gui/curses/gui-curses-color.c @@ -36,7 +36,7 @@ #include "gui-curses.h" -struct t_gui_color gui_weechat_colors[] = +struct t_gui_color gui_weechat_colors[GUI_CURSES_NUM_WEECHAT_COLORS + 1] = { { -1, 0, 0, "default" }, { COLOR_BLACK, 0, 0, "black" }, { COLOR_RED, 0, 0, "red" }, diff --git a/src/gui/curses/gui-curses-main.c b/src/gui/curses/gui-curses-main.c index bf842dfcf..2d7815fcf 100644 --- a/src/gui/curses/gui-curses-main.c +++ b/src/gui/curses/gui-curses-main.c @@ -218,7 +218,8 @@ gui_main_loop () /* refresh chat if needed */ if (ptr_buffer->chat_refresh_needed) { - gui_chat_draw (ptr_buffer, 1); + gui_chat_draw (ptr_buffer, + (ptr_buffer->chat_refresh_needed) > 1 ? 1 : 0); ptr_buffer->chat_refresh_needed = 0; } /* refresh nicklist if needed */ diff --git a/src/gui/curses/gui-curses-status.c b/src/gui/curses/gui-curses-status.c index 0e4c7f2bb..87cbb7805 100644 --- a/src/gui/curses/gui-curses-status.c +++ b/src/gui/curses/gui-curses-status.c @@ -209,38 +209,42 @@ gui_status_draw (int erase) x = ptr_win->win_status_width - utf8_strlen (str_nicks) - 4; } else*/ - x = ptr_win->win_status_width - 2; + x = ptr_win->win_status_width - 1; more = strdup (_("-MORE-")); - x -= utf8_strlen (more) - 1; - if (x < 0) - x = 0; - gui_window_set_weechat_color (GUI_CURSES(ptr_win)->win_status, - GUI_COLOR_STATUS_MORE); - if (ptr_win->scroll) - { - wmove (GUI_CURSES(ptr_win)->win_status, 0, x); - gui_window_wprintw (GUI_CURSES(ptr_win)->win_status, "%s", more); - } - else - { - snprintf (format, sizeof (format) - 1, - "%%-%ds", (int)(utf8_strlen (more))); - wmove (GUI_CURSES(ptr_win)->win_status, 0, x); - gui_window_wprintw (GUI_CURSES(ptr_win)->win_status, format, " "); - } - /*if (ptr_win->buffer->attribs & GUI_BUFFER_ATTRIB_NICKLIST) + if (more) { + x -= utf8_strlen (more) - 1; + if (x < 0) + x = 0; gui_window_set_weechat_color (GUI_CURSES(ptr_win)->win_status, - GUI_COLOR_STATUS_DELIMITERS); - wprintw (GUI_CURSES(ptr_win)->win_status, " ["); - gui_window_set_weechat_color (GUI_CURSES(ptr_win)->win_status, - GUI_COLOR_STATUS); - wprintw (GUI_CURSES(ptr_win)->win_status, "%s", str_nicks); - gui_window_set_weechat_color (GUI_CURSES(ptr_win)->win_status, - GUI_COLOR_STATUS_DELIMITERS); - wprintw (GUI_CURSES(ptr_win)->win_status, "]"); - }*/ - free (more); + GUI_COLOR_STATUS_MORE); + if (ptr_win->scroll) + { + wmove (GUI_CURSES(ptr_win)->win_status, 0, x); + gui_window_wprintw (GUI_CURSES(ptr_win)->win_status, "%s", more); + } + else + { + /*snprintf (format, sizeof (format) - 1, + "%%-%ds", (int)(utf8_strlen (more))); + wmove (GUI_CURSES(ptr_win)->win_status, 0, x); + gui_window_wprintw (GUI_CURSES(ptr_win)->win_status, format, " "); + */ + } + /*if (ptr_win->buffer->attribs & GUI_BUFFER_ATTRIB_NICKLIST) + { + gui_window_set_weechat_color (GUI_CURSES(ptr_win)->win_status, + GUI_COLOR_STATUS_DELIMITERS); + wprintw (GUI_CURSES(ptr_win)->win_status, " ["); + gui_window_set_weechat_color (GUI_CURSES(ptr_win)->win_status, + GUI_COLOR_STATUS); + wprintw (GUI_CURSES(ptr_win)->win_status, "%s", str_nicks); + gui_window_set_weechat_color (GUI_CURSES(ptr_win)->win_status, + GUI_COLOR_STATUS_DELIMITERS); + wprintw (GUI_CURSES(ptr_win)->win_status, "]"); + }*/ + free (more); + } wnoutrefresh (GUI_CURSES(ptr_win)->win_status); refresh (); diff --git a/src/gui/curses/gui-curses-window.c b/src/gui/curses/gui-curses-window.c index f760ba769..953ef7882 100644 --- a/src/gui/curses/gui-curses-window.c +++ b/src/gui/curses/gui-curses-window.c @@ -197,7 +197,7 @@ gui_window_curses_clear (WINDOW *window, int num_color) void gui_window_set_weechat_color (WINDOW *window, int num_color) { - if ((num_color >= 0) && (num_color <= GUI_NUM_COLORS - 1)) + if ((num_color >= 0) && (num_color < GUI_NUM_COLORS)) { wattroff (window, A_BOLD | A_UNDERLINE | A_REVERSE); wattron (window, COLOR_PAIR(gui_color_get_pair (num_color)) | diff --git a/src/gui/curses/gui-curses.h b/src/gui/curses/gui-curses.h index b5899ceb7..aa1bb107e 100644 --- a/src/gui/curses/gui-curses.h +++ b/src/gui/curses/gui-curses.h @@ -31,6 +31,8 @@ #define WINDOW_MIN_WIDTH 10 #define WINDOW_MIN_HEIGHT 5 +#define GUI_CURSES_NUM_WEECHAT_COLORS 15 + #define GUI_CURSES(window) ((struct t_gui_curses_objects *)(window->gui_objects)) struct t_gui_bar_window @@ -55,6 +57,10 @@ struct t_gui_curses_objects WINDOW *win_input; /* input window */ WINDOW *win_separator; /* separation between 2 splited (V) win */ struct t_gui_bar_window *bar_windows; /* bar windows */ + int current_style_fg; /* current foreground color */ + int current_style_bg; /* current background color */ + int current_style_attr; /* current attributes (bold, ..) */ + int current_color_attr; /* attr sum of last color(s) used */ }; extern struct t_gui_color gui_weechat_colors[]; diff --git a/src/gui/gtk/gui-gtk-chat.c b/src/gui/gtk/gui-gtk-chat.c index eca7aa226..e001e0c59 100644 --- a/src/gui/gtk/gui-gtk-chat.c +++ b/src/gui/gtk/gui-gtk-chat.c @@ -74,8 +74,8 @@ gui_chat_remove_style (struct t_gui_window *window, int style) void gui_chat_toggle_style (struct t_gui_window *window, int style) { - window->current_style_attr ^= style; - if (window->current_style_attr & style) + GUI_GTK(window)->current_style_attr ^= style; + if (GUI_GTK(window)->current_style_attr & style) gui_chat_set_style (window, style); else gui_chat_remove_style (window, style); @@ -89,10 +89,10 @@ gui_chat_toggle_style (struct t_gui_window *window, int style) void gui_chat_reset_style (struct t_gui_window *window) { - window->current_style_fg = -1; - window->current_style_bg = -1; - window->current_style_attr = 0; - window->current_color_attr = 0; + GUI_GTK(window)->current_style_fg = -1; + GUI_GTK(window)->current_style_bg = -1; + GUI_GTK(window)->current_style_attr = 0; + GUI_GTK(window)->current_color_attr = 0; /* TODO: change following function call */ /*gui_window_set_weechat_color (window->win_chat, COLOR_WIN_CHAT);*/ @@ -107,7 +107,7 @@ gui_chat_reset_style (struct t_gui_window *window) void gui_chat_set_color_style (struct t_gui_window *window, int style) { - window->current_color_attr |= style; + GUI_GTK(window)->current_color_attr |= style; /* TODO: change following function call */ /*wattron (window->win_chat, style);*/ } @@ -119,7 +119,7 @@ gui_chat_set_color_style (struct t_gui_window *window, int style) void gui_chat_remove_color_style (struct t_gui_window *window, int style) { - window->current_color_attr &= !style; + GUI_GTK(window)->current_color_attr &= !style; /* TODO: change following function call */ /*wattroff (window->win_chat, style);*/ } @@ -133,7 +133,7 @@ gui_chat_reset_color_style (struct t_gui_window *window) { /* TODO: change following function call */ /*wattroff (window->win_chat, window->current_color_attr);*/ - window->current_color_attr = 0; + GUI_GTK(window)->current_color_attr = 0; } /* diff --git a/src/gui/gtk/gui-gtk-color.c b/src/gui/gtk/gui-gtk-color.c index e441a05b3..77d3dcbf8 100644 --- a/src/gui/gtk/gui-gtk-color.c +++ b/src/gui/gtk/gui-gtk-color.c @@ -58,6 +58,26 @@ struct t_gui_color *gui_color[GUI_NUM_COLORS]; /* + * gui_color_search: search a color by name + * Return: number of color in WeeChat colors table + */ + +int +gui_color_search (char *color_name) +{ + int i; + + for (i = 0; gui_weechat_colors[i].string; i++) + { + if (string_strcasecmp (gui_weechat_colors[i].string, color_name) == 0) + return i; + } + + /* color not found */ + return -1; +} + +/* * gui_color_assign: assign a WeeChat color (read from config) */ diff --git a/src/gui/gtk/gui-gtk.h b/src/gui/gtk/gui-gtk.h index 71cfc2e04..ffe8ef707 100644 --- a/src/gui/gtk/gui-gtk.h +++ b/src/gui/gtk/gui-gtk.h @@ -72,6 +72,10 @@ struct t_gui_gtk_objects GtkWidget *textview_nicklist; /* textview widget for nicklist */ GtkTextBuffer *textbuffer_nicklist; /* textbuffer widget for nicklist */ struct t_gui_bar_window *bar_windows; /* bar windows */ + int current_style_fg; /* current foreground color */ + int current_style_bg; /* current background color */ + int current_style_attr; /* current attributes (bold, ..) */ + int current_color_attr; /* attr sum of last color(s) used */ }; //extern t_gui_color gui_weechat_colors[]; diff --git a/src/gui/gui-buffer.c b/src/gui/gui-buffer.c index 7433e813f..229a832f7 100644 --- a/src/gui/gui-buffer.c +++ b/src/gui/gui-buffer.c @@ -108,7 +108,7 @@ gui_buffer_new (struct t_weechat_plugin *plugin, char *category, char *name, new_buffer->title = NULL; new_buffer->title_refresh_needed = 1; - /* chat lines */ + /* chat lines (formated) */ new_buffer->lines = NULL; new_buffer->last_line = NULL; new_buffer->last_read_line = NULL; @@ -297,6 +297,29 @@ gui_buffer_set_name (struct t_gui_buffer *buffer, char *name) } /* + * gui_buffer_set_type: set buffer type + */ + +void +gui_buffer_set_type (struct t_gui_buffer *buffer, enum t_gui_buffer_type type) +{ + if (buffer->type == type) + return; + + gui_chat_line_free_all (buffer); + + switch (type) + { + case GUI_BUFFER_TYPE_FORMATED: + break; + case GUI_BUFFER_TYPE_FREE: + break; + } + buffer->type = type; + buffer->chat_refresh_needed = 1; +} + +/* * gui_buffer_set_title: set title for a buffer */ @@ -367,6 +390,9 @@ gui_buffer_set (struct t_gui_buffer *buffer, char *property, char *value) { long number; char *error; + + if (!buffer || !property || !value) + return; if (string_strcasecmp (property, "display") == 0) { @@ -381,6 +407,13 @@ gui_buffer_set (struct t_gui_buffer *buffer, char *property, char *value) { gui_buffer_set_name (buffer, value); } + else if (string_strcasecmp (property, "type") == 0) + { + if (string_strcasecmp (value, "formated") == 0) + gui_buffer_set_type (buffer, GUI_BUFFER_TYPE_FORMATED); + else if (string_strcasecmp (value, "free") == 0) + gui_buffer_set_type (buffer, GUI_BUFFER_TYPE_FREE); + } else if (string_strcasecmp (property, "title") == 0) { gui_buffer_set_title (buffer, value); @@ -600,30 +633,6 @@ gui_buffer_match_category_name (struct t_gui_buffer *buffer, char *mask, } /* - * gui_buffer_get_dcc: get pointer to DCC buffer (DCC buffer created if not existing) - */ - -struct t_gui_buffer * -gui_buffer_get_dcc (struct t_gui_window *window) -{ - //struct t_gui_buffer *ptr_buffer; - - (void) window; - /* check if dcc buffer exists */ - /*for (ptr_buffer = gui_buffers; ptr_buffer; ptr_buffer = ptr_buffer->next_buffer) - { - if (ptr_buffer->type == GUI_BUFFER_TYPE_DCC) - break; - } - if (ptr_buffer) - return ptr_buffer; - else - return gui_buffer_new (window, weechat_protocols, - NULL, NULL, GUI_BUFFER_TYPE_DCC, 0);*/ - return NULL; -} - -/* * gui_buffer_clear: clear buffer content */ @@ -631,33 +640,15 @@ void gui_buffer_clear (struct t_gui_buffer *buffer) { struct t_gui_window *ptr_win; - struct t_gui_line *ptr_line; - + if (!buffer) return; - - if (buffer->type == GUI_BUFFER_TYPE_FREE) - { - /* TODO: clear buffer with free content */ - return; - } /* remove buffer from hotlist */ gui_hotlist_remove_buffer (buffer); - /* remove lines from buffer */ - while (buffer->lines) - { - ptr_line = buffer->lines->next_line; - if (buffer->lines->message) - free (buffer->lines->message); - free (buffer->lines); - buffer->lines = ptr_line; - } - - buffer->lines = NULL; - buffer->last_line = NULL; - buffer->lines_count = 0; + /* remove all lines */ + gui_chat_line_free_all (buffer); /* remove any scroll for buffer */ for (ptr_win = gui_windows; ptr_win; ptr_win = ptr_win->next_window) @@ -696,7 +687,6 @@ gui_buffer_close (struct t_gui_buffer *buffer, int switch_to_another) { struct t_gui_window *ptr_window; struct t_gui_buffer *ptr_buffer; - struct t_gui_line *ptr_line; hook_signal_send ("buffer_closing", WEECHAT_HOOK_SIGNAL_POINTER, buffer); @@ -733,13 +723,8 @@ gui_buffer_close (struct t_gui_buffer *buffer, int switch_to_another) ptr_buffer->number--; } - /* free lines and messages */ - while (buffer->lines) - { - ptr_line = buffer->lines->next_line; - gui_chat_line_free (buffer->lines); - buffer->lines = ptr_line; - } + /* free all lines */ + gui_chat_line_free_all (buffer); } /* free some data */ @@ -830,32 +815,6 @@ gui_buffer_switch_next (struct t_gui_window *window) } /* - * gui_buffer_switch_dcc: switch to dcc buffer (create it if it does not exist) - */ - -void -gui_buffer_switch_dcc (struct t_gui_window *window) -{ - //struct t_gui_buffer *ptr_buffer; - - (void) window; - /* check if dcc buffer exists */ - /*for (ptr_buffer = gui_buffers; ptr_buffer; ptr_buffer = ptr_buffer->next_buffer) - { - if (ptr_buffer->type == GUI_BUFFER_TYPE_DCC) - break; - } - if (ptr_buffer) - { - gui_window_switch_to_buffer (window, ptr_buffer); - gui_window_redraw_buffer (ptr_buffer); - } - else - gui_buffer_new (window, weechat_protocols, - NULL, NULL, GUI_BUFFER_TYPE_DCC, 1);*/ -} - -/* * gui_buffer_switch_by_number: switch to another buffer with number */ @@ -1130,11 +1089,12 @@ gui_buffer_print_log () { num--; tags = string_build_with_exploded (ptr_line->tags_array, ","); - log_printf (" line N-%05d: str_time:'%s', tags:'%s', " - "displayed:%d, prefix:'%s'", - num, ptr_line->str_time, + log_printf (" line N-%05d: y:%d, str_time:'%s', tags:'%s', " + "displayed:%d, refresh_needed:%d, prefix:'%s'", + num, ptr_line->y, ptr_line->str_time, (tags) ? tags : "", (int)(ptr_line->displayed), + (int)(ptr_line->refresh_needed), ptr_line->prefix); log_printf (" data: '%s'", ptr_line->message); diff --git a/src/gui/gui-buffer.h b/src/gui/gui-buffer.h index 2ffced80d..5c17cb8cd 100644 --- a/src/gui/gui-buffer.h +++ b/src/gui/gui-buffer.h @@ -40,12 +40,14 @@ enum t_gui_buffer_type struct t_gui_line { + int y; /* line position (for free buffer) */ time_t date; /* date/time of line (may be past) */ time_t date_printed; /* date/time when weechat print it */ char *str_time; /* time string (for display) */ int tags_count; /* number of tags for line */ char **tags_array; /* tags for line */ char displayed; /* 1 if line is displayed */ + char refresh_needed; /* 1 if refresh asked (free buffer) */ char *prefix; /* prefix for line (may be NULL) */ int prefix_length; /* prefix length (on screen) */ char *message; /* line content (after prefix) */ diff --git a/src/gui/gui-chat.c b/src/gui/gui-chat.c index f08ab36f6..30198a184 100644 --- a/src/gui/gui-chat.c +++ b/src/gui/gui-chat.c @@ -563,14 +563,15 @@ gui_chat_line_match_tags (struct t_gui_line *line, int tags_count, } /* - * gui_chat_line_free: delete a line from a buffer + * gui_chat_line_free: delete a formated line from a buffer */ void -gui_chat_line_free (struct t_gui_line *line) +gui_chat_line_free (struct t_gui_buffer *buffer, struct t_gui_line *line) { struct t_gui_window *ptr_win; + /* reset scroll for any window starting with this line */ for (ptr_win = gui_windows; ptr_win; ptr_win = ptr_win->next_window) { if (ptr_win->start_line == line) @@ -581,6 +582,8 @@ gui_chat_line_free (struct t_gui_line *line) gui_status_refresh_needed = 1; } } + + /* free data */ if (line->str_time) free (line->str_time); if (line->tags_array) @@ -589,7 +592,37 @@ gui_chat_line_free (struct t_gui_line *line) free (line->prefix); if (line->message) free (line->message); + + /* remove line from lines list */ + if (line->prev_line) + line->prev_line->next_line = line->next_line; + if (line->next_line) + line->next_line->prev_line = line->prev_line; + if (buffer->lines == line) + buffer->lines = line->next_line; + if (buffer->last_line == line) + buffer->last_line = line->prev_line; + free (line); + + buffer->lines_count--; +} + +/* + * gui_chat_line_free_all: delete all formated lines from a buffer + */ + +void +gui_chat_line_free_all (struct t_gui_buffer *buffer) +{ + struct t_gui_line *next_line; + + while (buffer->lines) + { + next_line = buffer->lines->next_line; + gui_chat_line_free (buffer, buffer->lines); + buffer->lines = next_line; + } } /* @@ -601,7 +634,7 @@ gui_chat_line_add (struct t_gui_buffer *buffer, time_t date, time_t date_printed, char *tags, char *prefix, char *message) { - struct t_gui_line *new_line, *ptr_line; + struct t_gui_line *new_line; new_line = malloc (sizeof (*new_line)); if (!new_line) @@ -610,7 +643,8 @@ gui_chat_line_add (struct t_gui_buffer *buffer, time_t date, return; } - /* add new line */ + /* fill data in new line */ + new_line->y = 0; new_line->date = date; new_line->date_printed = date_printed; new_line->str_time = (date == 0) ? @@ -625,6 +659,7 @@ gui_chat_line_add (struct t_gui_buffer *buffer, time_t date, new_line->tags_count = 0; new_line->tags_array = NULL; } + new_line->refresh_needed = 0; new_line->prefix = (prefix) ? strdup (prefix) : ((date != 0) ? strdup ("") : NULL); new_line->prefix_length = (prefix) ? @@ -632,6 +667,8 @@ gui_chat_line_add (struct t_gui_buffer *buffer, time_t date, if (new_line->prefix_length > buffer->prefix_max_length) buffer->prefix_max_length = new_line->prefix_length; new_line->message = (message) ? strdup (message) : strdup (""); + + /* add line to lines list */ if (!buffer->lines) buffer->lines = new_line; else @@ -657,19 +694,105 @@ gui_chat_line_add (struct t_gui_buffer *buffer, time_t date, if ((CONFIG_INTEGER(config_history_max_lines) > 0) && (buffer->lines_count > CONFIG_INTEGER(config_history_max_lines))) { - if (buffer->last_line == buffer->lines) - buffer->last_line = NULL; - ptr_line = buffer->lines->next_line; - gui_chat_line_free (buffer->lines); - buffer->lines = ptr_line; - ptr_line->prev_line = NULL; - buffer->lines_count--; + gui_chat_line_free (buffer, buffer->lines); + } +} + +/* + * gui_chat_line_add_y: add or update a line for a buffer with free content + */ + +void +gui_chat_line_add_y (struct t_gui_buffer *buffer, int y, char *message) +{ + struct t_gui_line *ptr_line, *new_line; + + if (!message || !message[0]) + return; + + /* search if line exists for "y" */ + for (ptr_line = buffer->lines; ptr_line; + ptr_line = ptr_line->next_line) + { + if (ptr_line->y >= y) + break; + } + + if (!ptr_line || (ptr_line->y > y)) + { + new_line = malloc (sizeof (*new_line)); + if (!new_line) + { + log_printf (_("Not enough memory for new line")); + return; + } + + buffer->lines_count++; + + /* fill data in new line */ + new_line->y = y; + new_line->date = 0; + new_line->date_printed = 0; + new_line->str_time = NULL; + new_line->tags_count = 0; + new_line->tags_array = NULL; + new_line->refresh_needed = 1; + new_line->prefix = NULL; + new_line->prefix_length = 0; + new_line->message = NULL; + + /* add line to lines list */ + if (ptr_line) + { + /* add before line found */ + new_line->prev_line = ptr_line->prev_line; + new_line->next_line = ptr_line; + if (ptr_line->prev_line) + (ptr_line->prev_line)->next_line = new_line; + else + buffer->lines = new_line; + ptr_line->prev_line = new_line; + } + else + { + /* add at end of list */ + new_line->prev_line = buffer->last_line; + if (buffer->lines) + buffer->last_line->next_line = new_line; + else + buffer->lines = new_line; + buffer->last_line = new_line; + new_line->next_line = NULL; + } + + ptr_line = new_line; + } + + /* check if line is filtered or not */ + ptr_line->displayed = gui_filter_check_line (buffer, ptr_line); + if (!ptr_line->displayed) + { + if (!buffer->lines_hidden) + { + buffer->lines_hidden = 1; + hook_signal_send ("buffer_lines_hidden", + WEECHAT_HOOK_SIGNAL_POINTER, buffer); + } } + + /* set message for line */ + if (ptr_line->message) + free (ptr_line->message); + ptr_line->message = strdup (message); + + ptr_line->refresh_needed = 1; } /* * gui_chat_printf_date_tags: display a message in a buffer with optional * date and tags + * Info: this function works only with formated + * buffers (not buffers with free content) */ void @@ -677,21 +800,24 @@ gui_chat_printf_date_tags (struct t_gui_buffer *buffer, time_t date, char *tags, char *message, ...) { char buf[8192]; + va_list argptr; time_t date_printed; int display_time; char *pos, *pos_prefix, *pos_tab, *pos_end; - va_list argptr; struct t_gui_line *ptr_line; + if (!message) + return; + if (gui_init_ok) { - if (buffer == NULL) + if (!buffer) buffer = gui_buffer_search_main (); - if (buffer->type == GUI_BUFFER_TYPE_FREE) + if (buffer->type != GUI_BUFFER_TYPE_FORMATED) buffer = gui_buffers; - if (buffer->type == GUI_BUFFER_TYPE_FREE) + if (buffer->type != GUI_BUFFER_TYPE_FORMATED) return; } @@ -773,3 +899,65 @@ gui_chat_printf_date_tags (struct t_gui_buffer *buffer, time_t date, } } } + +/* + * gui_chat_printf_y: display a message on a line in a buffer with free content + * Info: this function works only with free content + * buffers (not formated buffers) + */ + +void +gui_chat_printf_y (struct t_gui_buffer *buffer, int y, char *message, ...) +{ + char buf[8192]; + va_list argptr; + struct t_gui_line *ptr_line; + + if (gui_init_ok) + { + if (!buffer) + buffer = gui_buffer_search_main (); + + if (buffer->type != GUI_BUFFER_TYPE_FREE) + buffer = gui_buffers; + + if (buffer->type != GUI_BUFFER_TYPE_FREE) + return; + } + + /* no message: delete line */ + if (!message) + { + if (gui_init_ok) + { + for (ptr_line = buffer->lines; ptr_line; + ptr_line = ptr_line->next_line) + { + if (ptr_line->y >= y) + break; + } + if (ptr_line && (ptr_line->y == y)) + { + gui_chat_line_free (buffer, ptr_line); + buffer->chat_refresh_needed = 2; + } + } + } + else + { + /* with message: create line or merge content with existing line */ + va_start (argptr, message); + vsnprintf (buf, sizeof (buf) - 1, message, argptr); + va_end (argptr); + + utf8_normalize (buf, '?'); + + if (gui_init_ok) + { + gui_chat_line_add_y (buffer, y, buf); + buffer->chat_refresh_needed = 1; + } + else + string_iconv_fprintf (stdout, "%s\n", buf); + } +} diff --git a/src/gui/gui-chat.h b/src/gui/gui-chat.h index f63d0ae4e..0db9bf6f9 100644 --- a/src/gui/gui-chat.h +++ b/src/gui/gui-chat.h @@ -72,10 +72,14 @@ extern int gui_chat_line_match_regex (struct t_gui_line *line, regex_t *regex_message); extern int gui_chat_line_match_tags (struct t_gui_line *line, int tags_count, char **tags_array); -extern void gui_chat_line_free (struct t_gui_line *line); +extern void gui_chat_line_free (struct t_gui_buffer *buffer, + struct t_gui_line *line); +extern void gui_chat_line_free_all (struct t_gui_buffer *buffer); extern void gui_chat_printf_date_tags (struct t_gui_buffer *buffer, time_t date, char *tags, char *message, ...); +extern void gui_chat_printf_y (struct t_gui_buffer *buffer, int y, + char *message, ...); /* chat functions (GUI dependent) */ diff --git a/src/gui/gui-color.c b/src/gui/gui-color.c index 631bf6879..75e723a2a 100644 --- a/src/gui/gui-color.c +++ b/src/gui/gui-color.c @@ -92,8 +92,23 @@ gui_color_decode (unsigned char *string) { case GUI_COLOR_COLOR_CHAR: string++; - if (isdigit (string[0]) && isdigit (string[1])) - string += 2; + switch (string[0]) + { + case 'F': + case 'B': + if (string[1] && string[2]) + string += 3; + break; + case '*': + if (string[1] && string[2] && (string[3] == ',') + && string[4] && string[5]) + string += 6; + break; + default: + if (isdigit (string[0]) && isdigit (string[1])) + string += 2; + break; + } break; case GUI_COLOR_SET_CHAR: case GUI_COLOR_REMOVE_CHAR: diff --git a/src/gui/gui-color.h b/src/gui/gui-color.h index ff6d431cd..a8c1f671f 100644 --- a/src/gui/gui-color.h +++ b/src/gui/gui-color.h @@ -151,6 +151,7 @@ extern void gui_color_free (struct t_gui_color *color); /* color functions (GUI dependent) */ +extern int gui_color_search (char *color_name); extern int gui_color_assign (int *color, char *color_name); extern char *gui_color_get_name (int num_color); extern void gui_color_init_pairs (); diff --git a/src/gui/gui-window.h b/src/gui/gui-window.h index 83a621e87..567975a33 100644 --- a/src/gui/gui-window.h +++ b/src/gui/gui-window.h @@ -80,11 +80,6 @@ struct t_gui_window /* GUI specific objects */ void *gui_objects; /* pointer to a GUI specific struct */ - int current_style_fg; /* current color used for foreground */ - int current_style_bg; /* current color used for background */ - int current_style_attr; /* current attributes (bold, ..) */ - int current_color_attr; /* attr sum of last color(s) used */ - /* DCC */ void *dcc_first; /* first dcc displayed */ void *dcc_selected; /* selected dcc */ diff --git a/src/plugins/plugin-api.c b/src/plugins/plugin-api.c index 76b8dee7b..ac99a3f59 100644 --- a/src/plugins/plugin-api.c +++ b/src/plugins/plugin-api.c @@ -220,16 +220,66 @@ plugin_api_prefix (char *prefix) char * plugin_api_color (char *color_name) { - int num_color; + int num_color, fg, bg; + static char color[20][16]; + static int index_color = 0; + char *pos_comma, *str_fg, *pos_bg; if (!color_name) return GUI_NO_COLOR; - + + /* name is a weechat color option ? => then return this color */ num_color = gui_color_search_config (color_name); if (num_color >= 0) return GUI_COLOR(num_color); - return GUI_NO_COLOR; + /* custom color name (GUI dependent) */ + pos_comma = strchr (color_name, ','); + if (pos_comma) + { + if (pos_comma == color_name) + str_fg = NULL; + else + str_fg = string_strndup (color_name, pos_comma - color_name); + pos_bg = pos_comma + 1; + } + else + { + str_fg = strdup (color_name); + pos_bg = NULL; + } + + index_color = (index_color + 1) % 20; + + color[index_color][0] = '\0'; + + if (str_fg && pos_bg) + { + fg = gui_color_search (str_fg); + bg = gui_color_search (pos_bg); + snprintf (color[index_color], sizeof (color[index_color]), + "%s*%02d,%02d", + GUI_COLOR_COLOR_STR, fg, bg); + } + else if (str_fg && !pos_bg) + { + fg = gui_color_search (str_fg); + snprintf (color[index_color], sizeof (color[index_color]), + "%sF%02d", + GUI_COLOR_COLOR_STR, fg); + } + else if (!str_fg && pos_bg) + { + bg = gui_color_search (pos_bg); + snprintf (color[index_color], sizeof (color[index_color]), + "%sB%02d", + GUI_COLOR_COLOR_STR, bg); + } + + if (str_fg) + free (str_fg); + + return color[index_color]; } /* diff --git a/src/plugins/plugin.c b/src/plugins/plugin.c index 89f7cbadf..64039dcab 100644 --- a/src/plugins/plugin.c +++ b/src/plugins/plugin.c @@ -339,10 +339,11 @@ plugin_load (char *filename) new_plugin->config_get_weechat = &plugin_api_config_get_weechat; new_plugin->config_get_plugin = &plugin_api_config_get_plugin; new_plugin->config_set_plugin = &plugin_api_config_set_plugin; - + new_plugin->prefix = &plugin_api_prefix; new_plugin->color = &plugin_api_color; new_plugin->printf_date_tags = &gui_chat_printf_date_tags; + new_plugin->printf_y = &gui_chat_printf_y; new_plugin->infobar_printf = &plugin_api_infobar_printf; new_plugin->infobar_remove = &plugin_api_infobar_remove; new_plugin->log_printf = &log_printf; diff --git a/src/plugins/scripts/lua/weechat-lua-api.c b/src/plugins/scripts/lua/weechat-lua-api.c index 57800afa9..cb41daa2c 100644 --- a/src/plugins/scripts/lua/weechat-lua-api.c +++ b/src/plugins/scripts/lua/weechat-lua-api.c @@ -1832,6 +1832,98 @@ weechat_lua_api_print (lua_State *L) } /* + * weechat_lua_api_print_date_tags: print message in a buffer with optional + * date and tags + */ + +static int +weechat_lua_api_print_date_tags (lua_State *L) +{ + const char *buffer, *tags, *message; + int n, date; + + /* make C compiler happy */ + (void) L; + + if (!lua_current_script) + { + WEECHAT_SCRIPT_MSG_NOT_INITIALIZED("print_date_tags"); + LUA_RETURN_ERROR; + } + + buffer = NULL; + date = 0; + tags = NULL; + message = NULL; + + n = lua_gettop (lua_current_interpreter); + + if (n < 4) + { + WEECHAT_SCRIPT_MSG_WRONG_ARGUMENTS("print_date_tags"); + LUA_RETURN_ERROR; + } + + buffer = lua_tostring (lua_current_interpreter, -4); + date = lua_tonumber (lua_current_interpreter, -3); + tags = lua_tostring (lua_current_interpreter, -2); + message = lua_tostring (lua_current_interpreter, -1); + + script_api_printf_date_tags (weechat_lua_plugin, + lua_current_script, + script_str2ptr ((char *)buffer), + date, + (char *)tags, + "%s", (char *)message); + + LUA_RETURN_OK; +} + +/* + * weechat_lua_api_print_y: print message in a buffer with free content + */ + +static int +weechat_lua_api_print_y (lua_State *L) +{ + const char *buffer, *message; + int n, y; + + /* make C compiler happy */ + (void) L; + + if (!lua_current_script) + { + WEECHAT_SCRIPT_MSG_NOT_INITIALIZED("print_y"); + LUA_RETURN_ERROR; + } + + buffer = NULL; + y = 0; + message = NULL; + + n = lua_gettop (lua_current_interpreter); + + if (n < 3) + { + WEECHAT_SCRIPT_MSG_WRONG_ARGUMENTS("print_y"); + LUA_RETURN_ERROR; + } + + buffer = lua_tostring (lua_current_interpreter, -3); + y = lua_tonumber (lua_current_interpreter, -2); + message = lua_tostring (lua_current_interpreter, -1); + + script_api_printf_y (weechat_lua_plugin, + lua_current_script, + script_str2ptr ((char *)buffer), + y, + "%s", (char *)message); + + LUA_RETURN_OK; +} + +/* * weechat_lua_api_infobar_print: print message to infobar */ @@ -4366,6 +4458,8 @@ const struct luaL_reg weechat_lua_api_funcs[] = { { "prefix", &weechat_lua_api_prefix }, { "color", &weechat_lua_api_color }, { "print", &weechat_lua_api_print }, + { "print_date_tags", &weechat_lua_api_print_date_tags }, + { "print_y", &weechat_lua_api_print_y }, { "infobar_print", &weechat_lua_api_infobar_print }, { "infobar_remove", &weechat_lua_api_infobar_remove }, { "log_print", &weechat_lua_api_log_print }, diff --git a/src/plugins/scripts/perl/weechat-perl-api.c b/src/plugins/scripts/perl/weechat-perl-api.c index 9cce80803..2b2064bab 100644 --- a/src/plugins/scripts/perl/weechat-perl-api.c +++ b/src/plugins/scripts/perl/weechat-perl-api.c @@ -1506,6 +1506,79 @@ static XS (XS_weechat_print) } /* + * weechat::print_date_tags: print message in a buffer with optional date and + * tags + */ + +static XS (XS_weechat_print_date_tags) +{ + char *buffer, *tags, *message; + dXSARGS; + + /* make C compiler happy */ + (void) cv; + + if (!perl_current_script) + { + WEECHAT_SCRIPT_MSG_NOT_INITIALIZED("print_date_tags"); + PERL_RETURN_ERROR; + } + + if (items < 4) + { + WEECHAT_SCRIPT_MSG_WRONG_ARGUMENTS("print_date_tags"); + PERL_RETURN_ERROR; + } + + buffer = SvPV (ST (0), PL_na); + tags = SvPV (ST (2), PL_na); + message = SvPV (ST (3), PL_na); + script_api_printf_date_tags (weechat_perl_plugin, + perl_current_script, + script_str2ptr (buffer), + SvIV (ST (1)), + tags, + "%s", message); + + PERL_RETURN_OK; +} + +/* + * weechat::print_y: print message in a buffer with free content + */ + +static XS (XS_weechat_print_y) +{ + char *buffer, *message; + dXSARGS; + + /* make C compiler happy */ + (void) cv; + + if (!perl_current_script) + { + WEECHAT_SCRIPT_MSG_NOT_INITIALIZED("print_y"); + PERL_RETURN_ERROR; + } + + if (items < 3) + { + WEECHAT_SCRIPT_MSG_WRONG_ARGUMENTS("print_y"); + PERL_RETURN_ERROR; + } + + buffer = SvPV (ST (0), PL_na); + message = SvPV (ST (2), PL_na); + script_api_printf_y (weechat_perl_plugin, + perl_current_script, + script_str2ptr (buffer), + SvIV (ST (1)), + "%s", message); + + PERL_RETURN_OK; +} + +/* * weechat::infobar_print: print message to infobar */ @@ -2413,7 +2486,7 @@ static XS (XS_weechat_buffer_new) if (!perl_current_script) { WEECHAT_SCRIPT_MSG_NOT_INITIALIZED("buffer_new"); - PERL_RETURN_EMPTY; + PERL_RETURN_EMPTY; } if (items < 4) @@ -3512,6 +3585,8 @@ weechat_perl_api_init (pTHX) newXS ("weechat::prefix", XS_weechat_prefix, "weechat"); newXS ("weechat::color", XS_weechat_color, "weechat"); newXS ("weechat::print", XS_weechat_print, "weechat"); + newXS ("weechat::print_date_tags", XS_weechat_print_date_tags, "weechat"); + newXS ("weechat::print_y", XS_weechat_print_y, "weechat"); newXS ("weechat::infobar_print", XS_weechat_infobar_print, "weechat"); newXS ("weechat::infobar_remove", XS_weechat_infobar_remove, "weechat"); newXS ("weechat::log_print", XS_weechat_log_print, "weechat"); diff --git a/src/plugins/scripts/perl/weechat-perl.c b/src/plugins/scripts/perl/weechat-perl.c index 2ab653233..6766f94f2 100644 --- a/src/plugins/scripts/perl/weechat-perl.c +++ b/src/plugins/scripts/perl/weechat-perl.c @@ -70,20 +70,20 @@ char *perl_weechat_code = "}" "sub weechat_perl_load_eval_file" "{" -#ifndef MULTIPLICITY - " my ($filename, $package) = @_;" -#else +#ifdef MULTIPLICITY " my $filename = shift;" +#else + " my ($filename, $package) = @_;" #endif " my $content = weechat_perl_load_file ($filename);" " if ($content eq \"__WEECHAT_PERL_ERROR__\")" " {" " return 1;" " }" -#ifndef MULTIPLICITY - " my $eval = qq{package $package; $content;};" -#else +#ifdef MULTIPLICITY " my $eval = $content;" +#else + " my $eval = qq{package $package; $content;};" #endif " {" " eval $eval;" @@ -117,16 +117,16 @@ weechat_perl_exec (struct t_plugin_script *script, /* this code is placed here to conform ISO C90 */ dSP; -#ifndef MULTIPLICITY +#ifdef MULTIPLICITY + (void) length; + func = function; + PERL_SET_CONTEXT (script->interpreter); +#else length = strlen (script->interpreter) + strlen (function) + 3; func = malloc (length); if (!func) return NULL; snprintf (func, length, "%s::%s", (char *) script->interpreter, function); -#else - (void) length; - func = function; - PERL_SET_CONTEXT (script->interpreter); #endif ENTER; @@ -220,11 +220,11 @@ weechat_perl_load (char *filename) struct stat buf; char *perl_argv[2]; -#ifndef MULTIPLICITY - char pkgname[64]; -#else +#ifdef MULTIPLICITY PerlInterpreter *perl_current_interpreter; - char *perl_args[] = { "", "-e", "0" }; + char *perl_args[] = { "", "-e", "0" }; +#else + char pkgname[64]; #endif if (stat (filename, &buf) != 0) @@ -241,16 +241,9 @@ weechat_perl_load (char *filename) perl_current_script = NULL; -#ifndef MULTIPLICITY - snprintf (pkgname, sizeof(pkgname), "%s%d", PKG_NAME_PREFIX, perl_num); - perl_num++; - tempscript.interpreter = "WeechatPerlScriptLoader"; - perl_argv[0] = filename; - perl_argv[1] = pkgname; - perl_argv[2] = NULL; -#else +#ifdef MULTIPLICITY perl_current_interpreter = perl_alloc(); - + if (!perl_current_interpreter) { weechat_printf (NULL, @@ -261,7 +254,7 @@ weechat_perl_load (char *filename) } perl_current_script_filename = filename; - + PERL_SET_CONTEXT (perl_current_interpreter); perl_construct (perl_current_interpreter); tempscript.interpreter = (PerlInterpreter *) perl_current_interpreter; @@ -271,6 +264,13 @@ weechat_perl_load (char *filename) eval_pv (perl_weechat_code, TRUE); perl_argv[0] = filename; perl_argv[1] = NULL; +#else + snprintf (pkgname, sizeof(pkgname), "%s%d", PKG_NAME_PREFIX, perl_num); + perl_num++; + tempscript.interpreter = "WeechatPerlScriptLoader"; + perl_argv[0] = filename; + perl_argv[1] = pkgname; + perl_argv[2] = NULL; #endif eval = weechat_perl_exec (&tempscript, WEECHAT_SCRIPT_EXEC_INT, @@ -285,7 +285,7 @@ weechat_perl_load (char *filename) return 0; } - if ( *eval != 0) + if (*eval != 0) { if (*eval == 2) { @@ -296,12 +296,12 @@ weechat_perl_load (char *filename) weechat_printf (NULL, weechat_gettext ("%s%s: error: %s"), weechat_prefix ("error"), "perl", -#ifndef MULTIPLICITY - SvPV(perl_get_sv("WeechatPerlScriptLoader::" - "weechat_perl_load_eval_file_error", +#ifdef MULTIPLICITY + SvPV(perl_get_sv("weechat_perl_load_eval_file_error", FALSE), len) #else - SvPV(perl_get_sv("weechat_perl_load_eval_file_error", + SvPV(perl_get_sv("WeechatPerlScriptLoader::" + "weechat_perl_load_eval_file_error", FALSE), len) #endif ); @@ -348,10 +348,10 @@ weechat_perl_load (char *filename) return 0; } -#ifndef MULTIPLICITY - perl_current_script->interpreter = strdup (pkgname); -#else +#ifdef MULTIPLICITY perl_current_script->interpreter = (PerlInterpreter *)perl_current_interpreter; +#else + perl_current_script->interpreter = strdup (pkgname); #endif return 1; @@ -384,10 +384,10 @@ weechat_perl_unload (struct t_plugin_script *script) weechat_gettext ("%s%s: unloading script \"%s\""), weechat_prefix ("info"), "perl", script->name); -#ifndef MULTIPLICITY - eval_pv (script->interpreter, TRUE); -#else +#ifdef MULTIPLICITY PERL_SET_CONTEXT (script->interpreter); +#else + eval_pv (script->interpreter, TRUE); #endif if (script->shutdown_func && script->shutdown_func[0]) @@ -400,14 +400,14 @@ weechat_perl_unload (struct t_plugin_script *script) free (r); } -#ifndef MULTIPLICITY - if (script->interpreter) - free (script->interpreter); -#else +#ifdef MULTIPLICITY perl_destruct (script->interpreter); perl_free (script->interpreter); +#else + if (script->interpreter) + free (script->interpreter); #endif - + script_remove (weechat_perl_plugin, &perl_scripts, script); } diff --git a/src/plugins/scripts/python/weechat-python-api.c b/src/plugins/scripts/python/weechat-python-api.c index 20b80882a..39691c1e9 100644 --- a/src/plugins/scripts/python/weechat-python-api.c +++ b/src/plugins/scripts/python/weechat-python-api.c @@ -1599,6 +1599,85 @@ weechat_python_api_prnt (PyObject *self, PyObject *args) } /* + * weechat_python_api_prnt_date_tags: print message in a buffer with optional + * date and tags + */ + +static PyObject * +weechat_python_api_prnt_date_tags (PyObject *self, PyObject *args) +{ + char *buffer, *tags, *message; + int date; + + /* make C compiler happy */ + (void) self; + + if (!python_current_script) + { + WEECHAT_SCRIPT_MSG_NOT_INITIALIZED("prnt_date_tags"); + PYTHON_RETURN_ERROR; + } + + buffer = NULL; + date = 0; + tags = NULL; + message = NULL; + + if (!PyArg_ParseTuple (args, "siss", &buffer, &time, &tags, &message)) + { + WEECHAT_SCRIPT_MSG_WRONG_ARGUMENTS("prnt_date_tags"); + PYTHON_RETURN_ERROR; + } + + script_api_printf_date_tags (weechat_python_plugin, + python_current_script, + script_str2ptr (buffer), + date, + tags, + "%s", message); + + PYTHON_RETURN_OK; +} + +/* + * weechat_python_api_prnt_y: print message in a buffer with free content + */ + +static PyObject * +weechat_python_api_prnt_y (PyObject *self, PyObject *args) +{ + char *buffer, *message; + int y; + + /* make C compiler happy */ + (void) self; + + if (!python_current_script) + { + WEECHAT_SCRIPT_MSG_NOT_INITIALIZED("prnt_y"); + PYTHON_RETURN_ERROR; + } + + buffer = NULL; + y = 0; + message = NULL; + + if (!PyArg_ParseTuple (args, "sis", &buffer, &y, &message)) + { + WEECHAT_SCRIPT_MSG_WRONG_ARGUMENTS("prnt_y"); + PYTHON_RETURN_ERROR; + } + + script_api_printf_y (weechat_python_plugin, + python_current_script, + script_str2ptr (buffer), + y, + "%s", message); + + PYTHON_RETURN_OK; +} + +/* * weechat_python_api_infobar_print: print message to infobar */ @@ -3735,6 +3814,8 @@ PyMethodDef weechat_python_funcs[] = { "prefix", &weechat_python_api_prefix, METH_VARARGS, "" }, { "color", &weechat_python_api_color, METH_VARARGS, "" }, { "prnt", &weechat_python_api_prnt, METH_VARARGS, "" }, + { "prnt_date_tags", &weechat_python_api_prnt_date_tags, METH_VARARGS, "" }, + { "prnt_y", &weechat_python_api_prnt_y, METH_VARARGS, "" }, { "infobar_print", &weechat_python_api_infobar_print, METH_VARARGS, "" }, { "infobar_remove", &weechat_python_api_infobar_remove, METH_VARARGS, "" }, { "log_print", &weechat_python_api_log_print, METH_VARARGS, "" }, diff --git a/src/plugins/scripts/ruby/weechat-ruby-api.c b/src/plugins/scripts/ruby/weechat-ruby-api.c index bc727e142..d9ecbb013 100644 --- a/src/plugins/scripts/ruby/weechat-ruby-api.c +++ b/src/plugins/scripts/ruby/weechat-ruby-api.c @@ -1845,6 +1845,104 @@ weechat_ruby_api_print (VALUE class, VALUE buffer, VALUE message) } /* + * weechat_ruby_api_print_date_tags: print message in a buffer with optional + * date and tags + */ + +static VALUE +weechat_ruby_api_print_date_tags (VALUE class, VALUE buffer, VALUE date, + VALUE tags, VALUE message) +{ + char *c_buffer, *c_tags, *c_message; + int c_date; + + /* make C compiler happy */ + (void) class; + + if (!ruby_current_script) + { + WEECHAT_SCRIPT_MSG_NOT_INITIALIZED("print_date_tags"); + RUBY_RETURN_ERROR; + } + + c_buffer = NULL; + c_date = 0; + c_tags = NULL; + c_message = NULL; + + if (NIL_P (buffer) || NIL_P (date) || NIL_P (tags) || NIL_P (message)) + { + WEECHAT_SCRIPT_MSG_WRONG_ARGUMENTS("print_date_tags"); + RUBY_RETURN_ERROR; + } + + Check_Type (buffer, T_STRING); + Check_Type (date, T_FIXNUM); + Check_Type (tags, T_STRING); + Check_Type (message, T_STRING); + + c_buffer = STR2CSTR (buffer); + c_date = FIX2INT (date); + c_tags = STR2CSTR (tags); + c_message = STR2CSTR (message); + + script_api_printf_date_tags (weechat_ruby_plugin, + ruby_current_script, + script_str2ptr (c_buffer), + c_date, + c_tags, + "%s", c_message); + + RUBY_RETURN_OK; +} + +/* + * weechat_ruby_api_print_y: print message in a buffer with free content + */ + +static VALUE +weechat_ruby_api_print_y (VALUE class, VALUE buffer, VALUE y, VALUE message) +{ + char *c_buffer, *c_message; + int c_y; + + /* make C compiler happy */ + (void) class; + + if (!ruby_current_script) + { + WEECHAT_SCRIPT_MSG_NOT_INITIALIZED("print_y"); + RUBY_RETURN_ERROR; + } + + c_buffer = NULL; + c_y = 0; + c_message = NULL; + + if (NIL_P (buffer) || NIL_P (message)) + { + WEECHAT_SCRIPT_MSG_WRONG_ARGUMENTS("print_y"); + RUBY_RETURN_ERROR; + } + + Check_Type (buffer, T_STRING); + Check_Type (y, T_FIXNUM); + Check_Type (message, T_STRING); + + c_buffer = STR2CSTR (buffer); + c_y = FIX2INT (y); + c_message = STR2CSTR (message); + + script_api_printf_y (weechat_ruby_plugin, + ruby_current_script, + script_str2ptr (c_buffer), + c_y, + "%s", c_message); + + RUBY_RETURN_OK; +} + +/* * weechat_ruby_api_infobar_print: print message to infobar */ @@ -4269,6 +4367,8 @@ weechat_ruby_api_init (VALUE ruby_mWeechat) rb_define_module_function (ruby_mWeechat, "prefix", &weechat_ruby_api_prefix, 1); rb_define_module_function (ruby_mWeechat, "color", &weechat_ruby_api_color, 1); rb_define_module_function (ruby_mWeechat, "print", &weechat_ruby_api_print, 2); + rb_define_module_function (ruby_mWeechat, "print_date_tags", &weechat_ruby_api_print_date_tags, 4); + rb_define_module_function (ruby_mWeechat, "print_y", &weechat_ruby_api_print_y, 3); rb_define_module_function (ruby_mWeechat, "infobar_print", &weechat_ruby_api_infobar_print, 3); rb_define_module_function (ruby_mWeechat, "infobar_remove", &weechat_ruby_api_infobar_remove, -1); rb_define_module_function (ruby_mWeechat, "log_print", &weechat_ruby_api_log_print, 1); diff --git a/src/plugins/scripts/script-api.c b/src/plugins/scripts/script-api.c index 52bb09df3..f12caa768 100644 --- a/src/plugins/scripts/script-api.c +++ b/src/plugins/scripts/script-api.c @@ -69,6 +69,7 @@ script_api_config_new (struct t_weechat_plugin *weechat_plugin, new_script_callback); if (!new_config_file) { + script_callback_free_data (new_script_callback); free (new_script_callback); return NULL; } @@ -137,7 +138,10 @@ script_api_config_new_section (struct t_weechat_plugin *weechat_plugin, if (!new_script_callback2) { if (new_script_callback1) + { + script_callback_free_data (new_script_callback1); free (new_script_callback1); + } return NULL; } callback2 = callback_write; @@ -149,9 +153,15 @@ script_api_config_new_section (struct t_weechat_plugin *weechat_plugin, if (!new_script_callback3) { if (new_script_callback1) + { + script_callback_free_data (new_script_callback1); free (new_script_callback1); + } if (new_script_callback2) + { + script_callback_free_data (new_script_callback2); free (new_script_callback2); + } return NULL; } callback3 = callback_write_default; @@ -168,11 +178,20 @@ script_api_config_new_section (struct t_weechat_plugin *weechat_plugin, if (!new_section) { if (new_script_callback1) + { + script_callback_free_data (new_script_callback1); free (new_script_callback1); + } if (new_script_callback2) + { + script_callback_free_data (new_script_callback2); free (new_script_callback2); + } if (new_script_callback3) + { + script_callback_free_data (new_script_callback3); free (new_script_callback3); + } return NULL; } @@ -193,7 +212,7 @@ script_api_config_new_section (struct t_weechat_plugin *weechat_plugin, new_script_callback2->config_section = new_section; script_callback_add (script, new_script_callback2); } - + if (new_script_callback3) { new_script_callback3->script = script; @@ -238,6 +257,7 @@ script_api_config_new_option (struct t_weechat_plugin *weechat_plugin, new_script_callback); if (!new_option) { + script_callback_free_data (new_script_callback); free (new_script_callback); return NULL; } @@ -269,18 +289,22 @@ script_api_config_free (struct t_weechat_plugin *weechat_plugin, struct t_plugin_script *script, struct t_config_file *config_file) { - struct t_script_callback *ptr_script_callback; + struct t_script_callback *ptr_script_callback, *next_callback; if (!weechat_plugin || !script || !config_file) return; weechat_config_free (config_file); - - for (ptr_script_callback = script->callbacks; ptr_script_callback; - ptr_script_callback = ptr_script_callback->next_callback) + + ptr_script_callback = script->callbacks; + while (ptr_script_callback) { + next_callback = ptr_script_callback->next_callback; + if (ptr_script_callback->config_file == config_file) script_callback_remove (script, ptr_script_callback); + + ptr_script_callback = next_callback; } } @@ -294,7 +318,7 @@ script_api_printf (struct t_weechat_plugin *weechat_plugin, struct t_gui_buffer *buffer, char *format, ...) { va_list argptr; - static char buf[8192]; + char buf[8192]; char *buf2; va_start (argptr, format); @@ -309,6 +333,57 @@ script_api_printf (struct t_weechat_plugin *weechat_plugin, } /* + * script_api_printf_date_tags: print a message with optional date and tags + */ + +void +script_api_printf_date_tags (struct t_weechat_plugin *weechat_plugin, + struct t_plugin_script *script, + struct t_gui_buffer *buffer, + time_t date, char *tags, char *format, ...) +{ + va_list argptr; + char buf[8192]; + char *buf2; + + va_start (argptr, format); + vsnprintf (buf, sizeof (buf) - 1, format, argptr); + va_end (argptr); + + buf2 = (script->charset && script->charset[0]) ? + weechat_iconv_to_internal (script->charset, buf) : NULL; + weechat_printf_date_tags (buffer, date, tags, + "%s", (buf2) ? buf2 : buf); + if (buf2) + free (buf2); +} + +/* + * script_api_printf_y: print a message on a buffer with free content + */ + +void +script_api_printf_y (struct t_weechat_plugin *weechat_plugin, + struct t_plugin_script *script, + struct t_gui_buffer *buffer, int y, + char *format, ...) +{ + va_list argptr; + char buf[8192]; + char *buf2; + + va_start (argptr, format); + vsnprintf (buf, sizeof (buf) - 1, format, argptr); + va_end (argptr); + + buf2 = (script->charset && script->charset[0]) ? + weechat_iconv_to_internal (script->charset, buf) : NULL; + weechat_printf_y (buffer, y, "%s", (buf2) ? buf2 : buf); + if (buf2) + free (buf2); +} + +/* * script_api_infobar_printf: print a message in infobar */ @@ -319,7 +394,7 @@ script_api_infobar_printf (struct t_weechat_plugin *weechat_plugin, char *format, ...) { va_list argptr; - static char buf[1024]; + char buf[1024]; char *buf2; va_start (argptr, format); @@ -343,7 +418,7 @@ script_api_log_printf (struct t_weechat_plugin *weechat_plugin, char *format, ...) { va_list argptr; - static char buf[1024]; + char buf[1024]; char *buf2; va_start (argptr, format); @@ -386,6 +461,7 @@ script_api_hook_command (struct t_weechat_plugin *weechat_plugin, callback, new_script_callback); if (!new_hook) { + script_callback_free_data (new_script_callback); free (new_script_callback); return NULL; } @@ -422,6 +498,7 @@ script_api_hook_timer (struct t_weechat_plugin *weechat_plugin, callback, new_script_callback); if (!new_hook) { + script_callback_free_data (new_script_callback); free (new_script_callback); return NULL; } @@ -429,7 +506,7 @@ script_api_hook_timer (struct t_weechat_plugin *weechat_plugin, new_script_callback->script = script; new_script_callback->function = strdup (function); new_script_callback->hook = new_hook; - + script_callback_add (script, new_script_callback); return new_hook; @@ -459,6 +536,7 @@ script_api_hook_fd (struct t_weechat_plugin *weechat_plugin, callback, new_script_callback); if (!new_hook) { + script_callback_free_data (new_script_callback); free (new_script_callback); return NULL; } @@ -500,6 +578,7 @@ script_api_hook_print (struct t_weechat_plugin *weechat_plugin, callback, new_script_callback); if (!new_hook) { + script_callback_free_data (new_script_callback); free (new_script_callback); return NULL; } @@ -537,6 +616,7 @@ script_api_hook_signal (struct t_weechat_plugin *weechat_plugin, new_hook = weechat_hook_signal (signal, callback, new_script_callback); if (!new_hook) { + script_callback_free_data (new_script_callback); free (new_script_callback); return NULL; } @@ -573,6 +653,7 @@ script_api_hook_config (struct t_weechat_plugin *weechat_plugin, new_hook = weechat_hook_config (type, option, callback, new_script_callback); if (!new_hook) { + script_callback_free_data (new_script_callback); free (new_script_callback); return NULL; } @@ -610,6 +691,7 @@ script_api_hook_completion (struct t_weechat_plugin *weechat_plugin, new_hook = weechat_hook_completion (completion, callback, new_script_callback); if (!new_hook) { + script_callback_free_data (new_script_callback); free (new_script_callback); return NULL; } @@ -646,6 +728,7 @@ script_api_hook_modifier (struct t_weechat_plugin *weechat_plugin, new_hook = weechat_hook_modifier (modifier, callback, new_script_callback); if (!new_hook) { + script_callback_free_data (new_script_callback); free (new_script_callback); return NULL; } @@ -668,18 +751,22 @@ script_api_unhook (struct t_weechat_plugin *weechat_plugin, struct t_plugin_script *script, struct t_hook *hook) { - struct t_script_callback *ptr_script_callback; + struct t_script_callback *ptr_script_callback, *next_callback; if (!weechat_plugin || !script || !hook) return; weechat_unhook (hook); - for (ptr_script_callback = script->callbacks; ptr_script_callback; - ptr_script_callback = ptr_script_callback->next_callback) + ptr_script_callback = script->callbacks; + while (ptr_script_callback) { + next_callback = ptr_script_callback->next_callback; + if (ptr_script_callback->hook == hook) script_callback_remove (script, ptr_script_callback); + + ptr_script_callback = next_callback; } } @@ -743,7 +830,10 @@ script_api_buffer_new (struct t_weechat_plugin *weechat_plugin, if (!new_script_callback_close) { if (new_script_callback_input) + { + script_callback_free_data (new_script_callback_input); free (new_script_callback_input); + } return NULL; } } @@ -752,20 +842,26 @@ script_api_buffer_new (struct t_weechat_plugin *weechat_plugin, (new_script_callback_input) ? input_callback : NULL, (new_script_callback_input) ? - function_input : NULL, + new_script_callback_input : NULL, (new_script_callback_close) ? close_callback : NULL, (new_script_callback_close) ? - function_close : NULL); + new_script_callback_close : NULL); if (!new_buffer) { if (new_script_callback_input) + { + script_callback_free_data (new_script_callback_input); free (new_script_callback_input); + } if (new_script_callback_close) + { + script_callback_free_data (new_script_callback_close); free (new_script_callback_close); + } return NULL; } - + if (new_script_callback_input) { new_script_callback_input->script = script; @@ -773,7 +869,7 @@ script_api_buffer_new (struct t_weechat_plugin *weechat_plugin, new_script_callback_input->buffer = new_buffer; script_callback_add (script, new_script_callback_input); } - + if (new_script_callback_close) { new_script_callback_close->script = script; @@ -795,23 +891,22 @@ script_api_buffer_close (struct t_weechat_plugin *weechat_plugin, struct t_gui_buffer *buffer, int switch_to_another) { - struct t_script_callback *ptr_script_callback; + struct t_script_callback *ptr_script_callback, *next_callback; if (!weechat_plugin || !script || !buffer) return; weechat_buffer_close (buffer, switch_to_another); - for (ptr_script_callback = script->callbacks; ptr_script_callback; - ptr_script_callback = ptr_script_callback->next_callback) + ptr_script_callback = script->callbacks; + while (ptr_script_callback) { + next_callback = ptr_script_callback->next_callback; + if (ptr_script_callback->buffer == buffer) - break; - } - - if (ptr_script_callback) - { - script_callback_remove (script, ptr_script_callback); + script_callback_remove (script, ptr_script_callback); + + ptr_script_callback = next_callback; } } @@ -837,6 +932,10 @@ script_api_bar_item_new (struct t_weechat_plugin *weechat_plugin, if (!new_script_callback) return NULL; + new_script_callback->script = script; + new_script_callback->function = (function_build && function_build[0]) ? + strdup (function_build) : NULL; + new_item = weechat_bar_item_new (name, (function_build && function_build[0]) ? build_callback : NULL, @@ -844,13 +943,11 @@ script_api_bar_item_new (struct t_weechat_plugin *weechat_plugin, new_script_callback : NULL); if (!new_item) { + script_callback_free_data (new_script_callback); free (new_script_callback); return NULL; } - new_script_callback->script = script; - new_script_callback->function = (function_build && function_build[0]) ? - strdup (function_build) : NULL; new_script_callback->bar_item = new_item; script_callback_add (script, new_script_callback); @@ -866,18 +963,22 @@ script_api_bar_item_remove (struct t_weechat_plugin *weechat_plugin, struct t_plugin_script *script, struct t_gui_bar_item *item) { - struct t_script_callback *ptr_script_callback; + struct t_script_callback *ptr_script_callback, *next_callback; if (!weechat_plugin || !script || !item) return; weechat_bar_item_remove (item); - - for (ptr_script_callback = script->callbacks; ptr_script_callback; - ptr_script_callback = ptr_script_callback->next_callback) + + ptr_script_callback = script->callbacks; + while (ptr_script_callback) { + next_callback = ptr_script_callback->next_callback; + if (ptr_script_callback->bar_item == item) script_callback_remove (script, ptr_script_callback); + + ptr_script_callback = next_callback; } } @@ -894,7 +995,9 @@ script_api_command (struct t_weechat_plugin *weechat_plugin, command2 = (script->charset && script->charset[0]) ? weechat_iconv_to_internal (script->charset, command) : NULL; + weechat_command (buffer, (command2) ? command2 : command); + if (command2) free (command2); } diff --git a/src/plugins/scripts/script-api.h b/src/plugins/scripts/script-api.h index 50fa7254c..98217549a 100644 --- a/src/plugins/scripts/script-api.h +++ b/src/plugins/scripts/script-api.h @@ -63,6 +63,15 @@ extern void script_api_printf (struct t_weechat_plugin *weechat_plugin, struct t_plugin_script *script, struct t_gui_buffer *buffer, char *format, ...); +extern void script_api_printf_date_tags (struct t_weechat_plugin *weechat_plugin, + struct t_plugin_script *script, + struct t_gui_buffer *buffer, + time_t date, char *tags, + char *format, ...); +extern void script_api_printf_y (struct t_weechat_plugin *weechat_plugin, + struct t_plugin_script *script, + struct t_gui_buffer *buffer, + int y, char *format, ...); extern void script_api_infobar_printf (struct t_weechat_plugin *weechat_plugin, struct t_plugin_script *script, int delay, char *color_name, diff --git a/src/plugins/scripts/script-callback.c b/src/plugins/scripts/script-callback.c index fb9ae66ca..a7f89e22e 100644 --- a/src/plugins/scripts/script-callback.c +++ b/src/plugins/scripts/script-callback.c @@ -69,6 +69,17 @@ script_callback_add (struct t_plugin_script *script, } /* + * script_callback_free_data: free data of a script callback + */ + +void +script_callback_free_data (struct t_script_callback *script_callback) +{ + if (script_callback->function) + free (script_callback->function); +} + +/* * script_callback_remove: remove a callback from a script */ @@ -86,9 +97,7 @@ script_callback_remove (struct t_plugin_script *script, if (script->callbacks == script_callback) script->callbacks = script_callback->next_callback; - /* free data */ - if (script_callback->function) - free (script_callback->function); + script_callback_free_data (script_callback); free (script_callback); } @@ -115,15 +124,15 @@ script_callback_print_log (struct t_weechat_plugin *weechat_plugin, struct t_script_callback *script_callback) { weechat_log_printf (""); - weechat_log_printf ("[callback (addr:0x%x)]", script_callback); - weechat_log_printf (" script. . . . . . . : 0x%x", script_callback->script); - weechat_log_printf (" function. . . . . . : '%s'", script_callback->function); - weechat_log_printf (" config_file . . . . : '%s'", script_callback->config_file); - weechat_log_printf (" config_section. . . : '%s'", script_callback->config_section); - weechat_log_printf (" config_option . . . : '%s'", script_callback->config_option); - weechat_log_printf (" hook. . . . . . . . : 0x%x", script_callback->hook); - weechat_log_printf (" buffer. . . . . . . : 0x%x", script_callback->buffer); - weechat_log_printf (" bar_item. . . . . . : 0x%x", script_callback->bar_item); - weechat_log_printf (" prev_callback . . . : 0x%x", script_callback->prev_callback); - weechat_log_printf (" next_callback . . . : 0x%x", script_callback->next_callback); + weechat_log_printf (" [callback (addr:0x%x)]", script_callback); + weechat_log_printf (" script. . . . . . . : 0x%x", script_callback->script); + weechat_log_printf (" function. . . . . . : '%s'", script_callback->function); + weechat_log_printf (" config_file . . . . : 0x%x", script_callback->config_file); + weechat_log_printf (" config_section. . . : 0x%x", script_callback->config_section); + weechat_log_printf (" config_option . . . : 0x%x", script_callback->config_option); + weechat_log_printf (" hook. . . . . . . . : 0x%x", script_callback->hook); + weechat_log_printf (" buffer. . . . . . . : 0x%x", script_callback->buffer); + weechat_log_printf (" bar_item. . . . . . : 0x%x", script_callback->bar_item); + weechat_log_printf (" prev_callback . . . : 0x%x", script_callback->prev_callback); + weechat_log_printf (" next_callback . . . : 0x%x", script_callback->next_callback); } diff --git a/src/plugins/scripts/script-callback.h b/src/plugins/scripts/script-callback.h index a9db3db49..947887ef0 100644 --- a/src/plugins/scripts/script-callback.h +++ b/src/plugins/scripts/script-callback.h @@ -36,6 +36,7 @@ struct t_script_callback extern struct t_script_callback *script_callback_alloc (); extern void script_callback_add (struct t_plugin_script *script, struct t_script_callback *callback); +extern void script_callback_free_data (struct t_script_callback *script_callback); extern void script_callback_remove (struct t_plugin_script *script, struct t_script_callback *script_callback); extern void script_callback_remove_all (struct t_plugin_script *script); diff --git a/src/plugins/scripts/script.c b/src/plugins/scripts/script.c index c7c5d507f..94dbf42bf 100644 --- a/src/plugins/scripts/script.c +++ b/src/plugins/scripts/script.c @@ -421,6 +421,7 @@ script_remove (struct t_weechat_plugin *weechat_plugin, { weechat_unhook (ptr_script_callback->hook); } + /* free config file */ if (ptr_script_callback->config_file && !ptr_script_callback->config_section @@ -430,6 +431,7 @@ script_remove (struct t_weechat_plugin *weechat_plugin, weechat_config_write (ptr_script_callback->config_file); weechat_config_free (ptr_script_callback->config_file); } + /* remove bar item */ if (ptr_script_callback->bar_item) weechat_bar_item_remove (ptr_script_callback->bar_item); diff --git a/src/plugins/weechat-plugin.h b/src/plugins/weechat-plugin.h index df041462d..6a5c039da 100644 --- a/src/plugins/weechat-plugin.h +++ b/src/plugins/weechat-plugin.h @@ -216,6 +216,8 @@ struct t_weechat_plugin char *(*color) (char *color_name); void (*printf_date_tags) (struct t_gui_buffer *buffer, time_t date, char *tags, char *message, ...); + void (*printf_y) (struct t_gui_buffer *buffer, int y, + char *message, ...); void (*infobar_printf) (struct t_weechat_plugin *plugin, int delay, char *color_name, char *format, ...); void (*infobar_remove) (int how_many); @@ -567,6 +569,8 @@ extern int weechat_plugin_end (struct t_weechat_plugin *plugin); #define weechat_printf(__buffer, __message, __argz...) \ weechat_plugin->printf_date_tags(__buffer, 0, NULL, __message, \ ##__argz) +#define weechat_printf_y(__buffer, __y, __message, __argz...) \ + weechat_plugin->printf_y(__buffer, __y, __message, ##__argz) #define weechat_printf_date(__buffer, __date, __message, __argz...) \ weechat_plugin->printf_date_tags(__buffer, __date, NULL, \ __message, ##__argz) |