diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/fe-common/core/formats.c | 33 | ||||
-rw-r--r-- | src/fe-common/core/formats.h | 22 | ||||
-rw-r--r-- | src/fe-text/gui-printtext.c | 88 | ||||
-rw-r--r-- | src/fe-text/gui-printtext.h | 7 | ||||
-rw-r--r-- | src/fe-text/gui-windows.c | 38 | ||||
-rw-r--r-- | src/fe-text/gui-windows.h | 2 | ||||
-rw-r--r-- | src/fe-text/textbuffer-view.c | 180 | ||||
-rw-r--r-- | src/fe-text/textbuffer-view.h | 19 | ||||
-rw-r--r-- | src/fe-text/textbuffer.c | 3 | ||||
-rw-r--r-- | src/fe-text/textbuffer.h | 1 | ||||
-rw-r--r-- | src/perl/textui/TextBufferView.xs | 65 | ||||
-rw-r--r-- | src/perl/textui/TextUI.xs | 2 |
12 files changed, 368 insertions, 92 deletions
diff --git a/src/fe-common/core/formats.c b/src/fe-common/core/formats.c index 515a48a3..dbdd51f2 100644 --- a/src/fe-common/core/formats.c +++ b/src/fe-common/core/formats.c @@ -60,7 +60,7 @@ int format_find_tag(const char *module, const char *tag) return -1; } -static void format_expand_code(const char **format, int *flags) +static void format_expand_code(const char **format, GString *out, int *flags) { int set; @@ -73,12 +73,28 @@ static void format_expand_code(const char **format, int *flags) set = TRUE; (*format)++; - while (**format != ']') { + while (**format != ']' && **format != '\0') { if (**format == '+') set = TRUE; else if (**format == '-') set = FALSE; else switch (**format) { + case 'i': + /* indent function */ + (*format)++; + if (**format == '=') + (*format)++; + + g_string_append_c(out, 4); + g_string_append_c(out, FORMAT_STYLE_INDENT_FUNC); + while (**format != ']' && **format != '\0' && + **format != ',') { + g_string_append_c(out, **format); + (*format)++; + } + g_string_append_c(out, ','); + (*format)--; + break; case 's': case 'S': *flags |= !set ? PRINT_FLAG_UNSET_LINE_START : @@ -154,7 +170,7 @@ int format_expand_styles(GString *out, const char **format, int *flags) break; case '[': /* code */ - format_expand_code(format, flags); + format_expand_code(format, out, flags); break; default: /* check if it's a background color */ @@ -945,6 +961,17 @@ void format_send_to_gui(TEXT_DEST_REC *dest, const char *text) case FORMAT_STYLE_INDENT: flags |= GUI_PRINT_FLAG_INDENT; break; + case FORMAT_STYLE_INDENT_FUNC: { + const char *start = ptr; + while (*ptr != ',' && *ptr != '\0') + ptr++; + if (*ptr != '\0') *ptr++ = '\0'; + signal_emit_id(signal_gui_print_text, 6, + dest->window, NULL, NULL, + GINT_TO_POINTER(GUI_PRINT_FLAG_INDENT_FUNC), + str, start, dest->level); + break; + } case FORMAT_STYLE_DEFAULTS: fgcolor = bgcolor = -1; flags &= GUI_PRINT_FLAG_INDENT; diff --git a/src/fe-common/core/formats.h b/src/fe-common/core/formats.h index f8b91d1b..27e87715 100644 --- a/src/fe-common/core/formats.h +++ b/src/fe-common/core/formats.h @@ -4,14 +4,15 @@ #include "themes.h" #include "fe-windows.h" -#define GUI_PRINT_FLAG_BOLD 0x01 -#define GUI_PRINT_FLAG_REVERSE 0x02 -#define GUI_PRINT_FLAG_UNDERLINE 0x04 -#define GUI_PRINT_FLAG_BLINK 0x08 -#define GUI_PRINT_FLAG_MIRC_COLOR 0x10 -#define GUI_PRINT_FLAG_INDENT 0x20 -#define GUI_PRINT_FLAG_NEWLINE 0x40 -#define GUI_PRINT_FLAG_CLRTOEOL 0x80 +#define GUI_PRINT_FLAG_BOLD 0x0001 +#define GUI_PRINT_FLAG_REVERSE 0x0002 +#define GUI_PRINT_FLAG_UNDERLINE 0x0004 +#define GUI_PRINT_FLAG_BLINK 0x0008 +#define GUI_PRINT_FLAG_MIRC_COLOR 0x0010 +#define GUI_PRINT_FLAG_INDENT 0x0020 +#define GUI_PRINT_FLAG_INDENT_FUNC 0x0040 +#define GUI_PRINT_FLAG_NEWLINE 0x0080 +#define GUI_PRINT_FLAG_CLRTOEOL 0x0100 #define MAX_FORMAT_PARAMS 10 #define DEFAULT_FORMAT_ARGLIST_SIZE 200 @@ -121,8 +122,9 @@ void format_send_to_gui(TEXT_DEST_REC *dest, const char *text); #define FORMAT_STYLE_BOLD (0x03 + FORMAT_STYLE_SPECIAL) #define FORMAT_STYLE_REVERSE (0x04 + FORMAT_STYLE_SPECIAL) #define FORMAT_STYLE_INDENT (0x05 + FORMAT_STYLE_SPECIAL) -#define FORMAT_STYLE_DEFAULTS (0x06 + FORMAT_STYLE_SPECIAL) -#define FORMAT_STYLE_CLRTOEOL (0x07 + FORMAT_STYLE_SPECIAL) +#define FORMAT_STYLE_INDENT_FUNC (0x06 + FORMAT_STYLE_SPECIAL) +#define FORMAT_STYLE_DEFAULTS (0x07 + FORMAT_STYLE_SPECIAL) +#define FORMAT_STYLE_CLRTOEOL (0x08 + FORMAT_STYLE_SPECIAL) int format_expand_styles(GString *out, const char **format, int *flags); void formats_init(void); diff --git a/src/fe-text/gui-printtext.c b/src/fe-text/gui-printtext.c index 364d68c3..79f86674 100644 --- a/src/fe-text/gui-printtext.c +++ b/src/fe-text/gui-printtext.c @@ -26,6 +26,7 @@ #include "printtext.h" #include "screen.h" +#include "gui-printtext.h" #include "gui-windows.h" int mirc_colors[] = { 15, 0, 1, 2, 12, 6, 5, 4, 14, 10, 3, 11, 9, 13, 8, 7 }; @@ -34,6 +35,63 @@ static int scrollback_lines, scrollback_hours, scrollback_burst_remove; static int last_color, last_flags; static int next_xpos, next_ypos; +static GHashTable *indent_functions; +static INDENT_FUNC default_indent_func; + +void gui_register_indent_func(const char *name, INDENT_FUNC func) +{ + gpointer key, value; + GSList *list; + + if (g_hash_table_lookup_extended(indent_functions, name, &key, &value)) { + list = value; + g_hash_table_remove(indent_functions, key); + } else { + key = g_strdup(name); + list = NULL; + } + + list = g_slist_append(list, func); + g_hash_table_insert(indent_functions, key, list); +} + +void gui_unregister_indent_func(const char *name, INDENT_FUNC func) +{ + gpointer key, value; + GSList *list; + + if (g_hash_table_lookup_extended(indent_functions, name, &key, &value)) { + list = value; + + list = g_slist_remove(list, func); + g_hash_table_remove(indent_functions, key); + if (list == NULL) + g_free(key); + else + g_hash_table_insert(indent_functions, key, list); + } + + if (default_indent_func == func) + gui_set_default_indent(NULL); + + textbuffer_views_unregister_indent_func(func); +} + +void gui_set_default_indent(const char *name) +{ + GSList *list; + + list = name == NULL ? NULL : + g_hash_table_lookup(indent_functions, name); + default_indent_func = list == NULL ? NULL : list->data; + gui_windows_reset_settings(); +} + +INDENT_FUNC get_default_indent_func(void) +{ + return default_indent_func; +} + void gui_printtext(int xpos, int ypos, const char *str) { next_xpos = xpos; @@ -154,6 +212,21 @@ static void line_add_colors(TEXT_BUFFER_REC *buffer, LINE_REC **line, last_color = fg | (bg << 4); } +static void line_add_indent_func(TEXT_BUFFER_REC *buffer, LINE_REC **line, + const char *function) +{ + GSList *list; + unsigned char data[1+sizeof(INDENT_FUNC)]; + + list = g_hash_table_lookup(indent_functions, function); + if (list != NULL) { + data[0] = LINE_CMD_INDENT_FUNC; + memcpy(data+1, list->data, sizeof(INDENT_FUNC)); + *line = textbuffer_insert(buffer, *line, + data, sizeof(data), NULL); + } +} + static void view_add_eol(TEXT_BUFFER_VIEW_REC *view, LINE_REC **line) { static const unsigned char eol[] = { 0, LINE_CMD_EOL }; @@ -203,8 +276,14 @@ static void sig_gui_print_text(WINDOW_REC *window, void *fgcolor, if (flags & GUI_PRINT_FLAG_NEWLINE) view_add_eol(view, &insert_after); line_add_colors(view->buffer, &insert_after, fg, bg, flags); - insert_after = textbuffer_insert(view->buffer, insert_after, - str, strlen(str), &lineinfo); + + if (flags & GUI_PRINT_FLAG_INDENT_FUNC) { + /* specify the indentation function */ + line_add_indent_func(view->buffer, &insert_after, str); + } else { + insert_after = textbuffer_insert(view->buffer, insert_after, + str, strlen(str), &lineinfo); + } if (gui->use_insert_after) gui->insert_after = insert_after; } @@ -235,6 +314,9 @@ static void read_settings(void) void gui_printtext_init(void) { next_xpos = next_ypos = -1; + default_indent_func = NULL; + indent_functions = g_hash_table_new((GHashFunc) g_str_hash, + (GCompareFunc) g_str_equal); settings_add_int("history", "scrollback_lines", 500); settings_add_int("history", "scrollback_hours", 24); @@ -249,6 +331,8 @@ void gui_printtext_init(void) void gui_printtext_deinit(void) { + g_hash_table_destroy(indent_functions); + signal_remove("gui print text", (SIGNAL_FUNC) sig_gui_print_text); signal_remove("gui print text finished", (SIGNAL_FUNC) sig_gui_printtext_finished); signal_remove("setup changed", (SIGNAL_FUNC) read_settings); diff --git a/src/fe-text/gui-printtext.h b/src/fe-text/gui-printtext.h index 44f2b44e..47cd3c23 100644 --- a/src/fe-text/gui-printtext.h +++ b/src/fe-text/gui-printtext.h @@ -2,6 +2,7 @@ #define __GUI_PRINTTEXT_H #include "gui-windows.h" +#include "textbuffer-view.h" #include "formats.h" extern int mirc_colors[]; @@ -9,6 +10,12 @@ extern int mirc_colors[]; void gui_printtext_init(void); void gui_printtext_deinit(void); +void gui_register_indent_func(const char *name, INDENT_FUNC func); +void gui_unregister_indent_func(const char *name, INDENT_FUNC func); + +void gui_set_default_indent(const char *name); +INDENT_FUNC get_default_indent_func(void); + void gui_printtext(int xpos, int ypos, const char *str); void gui_printtext_after(TEXT_DEST_REC *dest, LINE_REC *prev, const char *str); diff --git a/src/fe-text/gui-windows.c b/src/fe-text/gui-windows.c index 0f4a6702..f3266828 100644 --- a/src/fe-text/gui-windows.c +++ b/src/fe-text/gui-windows.c @@ -43,9 +43,11 @@ static GUI_WINDOW_REC *gui_window_init(WINDOW_REC *window, gui->parent = parent; gui->view = textbuffer_view_create(textbuffer_create(), window->width, window->height, + settings_get_bool("scroll")); + textbuffer_view_set_default_indent(gui->view, settings_get_int("indent"), settings_get_bool("indent_always"), - settings_get_bool("scroll")); + get_default_indent_func()); return gui; } @@ -182,6 +184,25 @@ void gui_window_reparent(WINDOW_REC *window, MAIN_WINDOW_REC *parent) } } +void gui_windows_reset_settings(void) +{ + GSList *tmp; + + for (tmp = windows; tmp != NULL; tmp = tmp->next) { + WINDOW_REC *rec = tmp->data; + GUI_WINDOW_REC *gui = WINDOW_GUI(rec); + + textbuffer_view_set_default_indent(gui->view, + settings_get_int("indent"), + settings_get_bool("indent_always"), + get_default_indent_func()); + + textbuffer_view_set_scroll(gui->view, + gui->use_scroll ? gui->scroll : + settings_get_bool("scroll")); + } +} + static MAIN_WINDOW_REC *mainwindow_find_unsticky(void) { GSList *tmp; @@ -239,20 +260,7 @@ static void signal_window_changed(WINDOW_REC *window) static void read_settings(void) { - GSList *tmp; - - for (tmp = windows; tmp != NULL; tmp = tmp->next) { - WINDOW_REC *rec = tmp->data; - GUI_WINDOW_REC *gui = WINDOW_GUI(rec); - - textbuffer_view_set_default_indent(gui->view, - settings_get_int("indent"), - settings_get_bool("indent_always")); - - textbuffer_view_set_scroll(gui->view, - gui->use_scroll ? gui->scroll : - settings_get_bool("scroll")); - } + gui_windows_reset_settings(); } void gui_windows_init(void) diff --git a/src/fe-text/gui-windows.h b/src/fe-text/gui-windows.h index b67f6de7..9d4afac7 100644 --- a/src/fe-text/gui-windows.h +++ b/src/fe-text/gui-windows.h @@ -39,4 +39,6 @@ void gui_window_scroll_line(WINDOW_REC *window, LINE_REC *line); void gui_window_set_sticky(WINDOW_REC *window); void gui_window_set_unsticky(WINDOW_REC *window); +void gui_windows_reset_settings(void); + #endif diff --git a/src/fe-text/textbuffer-view.c b/src/fe-text/textbuffer-view.c index 12191f05..adb9a320 100644 --- a/src/fe-text/textbuffer-view.c +++ b/src/fe-text/textbuffer-view.c @@ -105,6 +105,7 @@ static void textbuffer_cache_unref(TEXT_BUFFER_CACHE_REC *cache) static LINE_CACHE_REC * view_update_line_cache(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line) { + INDENT_FUNC indent_func; LINE_CACHE_REC *rec; LINE_CACHE_SUB_REC *sub; GSList *lines; @@ -117,6 +118,7 @@ view_update_line_cache(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line) xpos = 0; color = 0; indent_pos = view->default_indent; last_space = last_color = 0; last_space_ptr = NULL; sub = NULL; + indent_func = view->default_indent_func; linecount = 1; lines = NULL; for (ptr = line->text;;) { @@ -162,6 +164,12 @@ view_update_line_cache(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line) it if we're too close to right border */ if (xpos < view->width-5) indent_pos = xpos; break; + case LINE_CMD_INDENT_FUNC: + memcpy(&indent_func, ptr, sizeof(INDENT_FUNC)); + ptr += sizeof(INDENT_FUNC); + if (indent_func == NULL) + indent_func = view->default_indent_func; + break; } continue; } @@ -175,7 +183,8 @@ view_update_line_cache(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line) } if (xpos == view->width) { - xpos = indent_pos; + xpos = indent_func == NULL ? indent_pos : + indent_func(view, line, -1); sub = g_new0(LINE_CACHE_SUB_REC, 1); if (last_space > indent_pos && last_space > 10) { @@ -191,6 +200,7 @@ view_update_line_cache(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line) sub->start = ptr; sub->indent = xpos; + sub->indent_func = indent_func; sub->color = color; lines = g_slist_append(lines, sub); @@ -227,9 +237,52 @@ view_update_line_cache(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line) return rec; } +static void view_remove_cache(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line, + unsigned char update_counter) +{ + LINE_CACHE_REC *cache; + + if (view->cache->update_counter == update_counter) + return; + view->cache->update_counter = update_counter; + + cache = g_hash_table_lookup(view->cache->line_cache, line); + if (cache != NULL) { + g_free(cache); + g_hash_table_remove(view->cache->line_cache, line); + } +} + +static void view_update_cache(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line, + unsigned char update_counter) +{ + view_remove_cache(view, line, update_counter); + + if (view->buffer->cur_line == line) + view->cache->last_linecount = view_get_linecount(view, line); +} + +static void view_reset_cache(TEXT_BUFFER_VIEW_REC *view) +{ + GSList *tmp; + + /* destroy line caches - note that you can't do simultaneously + unrefs + cache_get()s or it will keep using the old caches */ + textbuffer_cache_unref(view->cache); + g_slist_foreach(view->siblings, (GFunc) textbuffer_cache_unref, NULL); + + view->cache = textbuffer_cache_get(view->siblings, view->width); + for (tmp = view->siblings; tmp != NULL; tmp = tmp->next) { + TEXT_BUFFER_VIEW_REC *rec = tmp->data; + + rec->cache = textbuffer_cache_get(rec->siblings, rec->width); + } +} + static int view_line_draw(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line, int subline, int ypos, int max) { + INDENT_FUNC indent_func; LINE_CACHE_REC *cache; const unsigned char *text, *text_newline; char *tmp; @@ -252,15 +305,19 @@ static int view_line_draw(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line, break; } - if (subline > 0) { - xpos = cache->lines[subline-1].indent; - color = cache->lines[subline-1].color; - } - + /* first clear the line */ screen_set_color(view->window, 0); screen_move(view->window, 0, ypos); screen_clrtoeol(view->window); + if (subline > 0) { + indent_func = cache->lines[subline-1].indent_func; + xpos = indent_func != NULL ? + indent_func(view, line, ypos) : + cache->lines[subline-1].indent; + color = cache->lines[subline-1].color; + } + screen_move(view->window, xpos, ypos); screen_set_color(view->window, color); @@ -302,6 +359,9 @@ static int view_line_draw(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line, break; case LINE_CMD_BLINK: color |= 0x80; + break; + case LINE_CMD_INDENT_FUNC: + text += sizeof(INDENT_FUNC); break; } screen_set_color(view->window, color); @@ -378,8 +438,6 @@ static void textbuffer_view_init_ypos(TEXT_BUFFER_VIEW_REC *view) /* Create new view. */ TEXT_BUFFER_VIEW_REC *textbuffer_view_create(TEXT_BUFFER_REC *buffer, int width, int height, - int default_indent, - int longword_noindent, int scroll) { TEXT_BUFFER_VIEW_REC *view; @@ -393,8 +451,6 @@ TEXT_BUFFER_VIEW_REC *textbuffer_view_create(TEXT_BUFFER_REC *buffer, view->width = width; view->height = height; - view->default_indent = default_indent; - view->longword_noindent = longword_noindent; view->scroll = scroll; view->cache = textbuffer_cache_get(view->siblings, width); @@ -445,10 +501,65 @@ void textbuffer_view_destroy(TEXT_BUFFER_VIEW_REC *view) /* Change the default indent position */ void textbuffer_view_set_default_indent(TEXT_BUFFER_VIEW_REC *view, int default_indent, - int longword_noindent) + int longword_noindent, + INDENT_FUNC indent_func) { - view->default_indent = default_indent; - view->longword_noindent = longword_noindent; + if (default_indent != -1) + view->default_indent = default_indent; + if (view->longword_noindent != -1) + view->longword_noindent = longword_noindent; + + view->default_indent_func = indent_func; +} + +static void view_unregister_indent_func(TEXT_BUFFER_VIEW_REC *view, + INDENT_FUNC indent_func) +{ + INDENT_FUNC func; + LINE_REC *line; + const unsigned char *text, *tmp; + + if (view->default_indent_func == indent_func) + view->default_indent_func = NULL; + + /* recreate cache so it won't contain references + to the indent function */ + view_reset_cache(view); + view->cache = textbuffer_cache_get(view->siblings, view->width); + + /* remove all references to the indent function from buffer */ + line = view->buffer->first_line; + while (line != NULL) { + text = line->text; + + for (text = line->text;; text++) { + if (*text != '\0') + continue; + + text++; + if (*text == LINE_CMD_EOL) + break; + + if (*text == LINE_CMD_INDENT_FUNC) { + text++; + memcpy(&func, text, sizeof(INDENT_FUNC)); + if (func == indent_func) + memset(&func, 0, sizeof(INDENT_FUNC)); + text += sizeof(INDENT_FUNC); + } else if (*text == LINE_CMD_CONTINUE) { + memcpy(&tmp, text+1, sizeof(char *)); + text = tmp-1; + } + } + + line = line->next; + } +} + +void textbuffer_views_unregister_indent_func(INDENT_FUNC indent_func) +{ + g_slist_foreach(views, (GFunc) view_unregister_indent_func, + indent_func); } void textbuffer_view_set_scroll(TEXT_BUFFER_VIEW_REC *view, int scroll) @@ -721,31 +832,6 @@ LINE_CACHE_REC *textbuffer_view_get_line_cache(TEXT_BUFFER_VIEW_REC *view, return cache; } -static void view_remove_cache(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line, - unsigned char update_counter) -{ - LINE_CACHE_REC *cache; - - if (view->cache->update_counter == update_counter) - return; - view->cache->update_counter = update_counter; - - cache = g_hash_table_lookup(view->cache->line_cache, line); - if (cache != NULL) { - g_free(cache); - g_hash_table_remove(view->cache->line_cache, line); - } -} - -static void view_update_cache(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line, - unsigned char update_counter) -{ - view_remove_cache(view, line, update_counter); - - if (view->buffer->cur_line == line) - view->cache->last_linecount = view_get_linecount(view, line); -} - static void view_insert_line(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line) { int linecount, ypos, subline; @@ -1003,8 +1089,6 @@ static int g_free_true(void *data) /* Remove all lines from buffer. */ void textbuffer_view_remove_all_lines(TEXT_BUFFER_VIEW_REC *view) { - GSList *tmp; - g_return_if_fail(view != NULL); textbuffer_remove_all_lines(view->buffer); @@ -1012,21 +1096,9 @@ void textbuffer_view_remove_all_lines(TEXT_BUFFER_VIEW_REC *view) g_hash_table_foreach_remove(view->bookmarks, (GHRFunc) g_free_true, NULL); - /* destroy line caches - note that you can't do simultaneously - unrefs + cache_get()s or it will keep using the old caches */ - textbuffer_cache_unref(view->cache); - g_slist_foreach(view->siblings, (GFunc) textbuffer_cache_unref, NULL); - - /* recreate caches, clear screens */ - view->cache = textbuffer_cache_get(view->siblings, view->width); + view_reset_cache(view); textbuffer_view_clear(view); - - for (tmp = view->siblings; tmp != NULL; tmp = tmp->next) { - TEXT_BUFFER_VIEW_REC *rec = tmp->data; - - rec->cache = textbuffer_cache_get(rec->siblings, rec->width); - textbuffer_view_clear(rec); - } + g_slist_foreach(view->siblings, (GFunc) textbuffer_view_clear, NULL); } /* Set a bookmark in view */ diff --git a/src/fe-text/textbuffer-view.h b/src/fe-text/textbuffer-view.h index d49798df..c5fc7ba2 100644 --- a/src/fe-text/textbuffer-view.h +++ b/src/fe-text/textbuffer-view.h @@ -4,9 +4,16 @@ #include "textbuffer.h" #include "screen.h" +typedef struct _TEXT_BUFFER_VIEW_REC TEXT_BUFFER_VIEW_REC; + +/* if ypos == -1, don't print anything, just return the indent size */ +typedef int (*INDENT_FUNC) (TEXT_BUFFER_VIEW_REC *view, + LINE_REC *line, int ypos); + typedef struct { unsigned char *start; int indent; + INDENT_FUNC indent_func; int color; /* first word in line belong to the end of the last word in @@ -37,7 +44,7 @@ typedef struct { int last_linecount; } TEXT_BUFFER_CACHE_REC; -typedef struct { +struct _TEXT_BUFFER_VIEW_REC { TEXT_BUFFER_REC *buffer; GSList *siblings; /* other views that use the same buffer */ @@ -45,6 +52,7 @@ typedef struct { int width, height; int default_indent; + INDENT_FUNC default_indent_func; unsigned int longword_noindent:1; unsigned int scroll:1; /* scroll down automatically when at bottom */ @@ -67,20 +75,21 @@ typedef struct { /* Bookmarks to the lines in the buffer - removed automatically when the line gets removed from buffer */ GHashTable *bookmarks; -} TEXT_BUFFER_VIEW_REC; +}; /* Create new view. */ TEXT_BUFFER_VIEW_REC *textbuffer_view_create(TEXT_BUFFER_REC *buffer, int width, int height, - int default_indent, - int longword_noindent, int scroll); /* Destroy the view. */ void textbuffer_view_destroy(TEXT_BUFFER_VIEW_REC *view); /* Change the default indent position */ void textbuffer_view_set_default_indent(TEXT_BUFFER_VIEW_REC *view, int default_indent, - int longword_noindent); + int longword_noindent, + INDENT_FUNC indent_func); +void textbuffer_views_unregister_indent_func(INDENT_FUNC indent_func); + void textbuffer_view_set_scroll(TEXT_BUFFER_VIEW_REC *view, int scroll); /* Resize the view. */ diff --git a/src/fe-text/textbuffer.c b/src/fe-text/textbuffer.c index 1016905c..f99aacca 100644 --- a/src/fe-text/textbuffer.c +++ b/src/fe-text/textbuffer.c @@ -403,6 +403,9 @@ void textbuffer_line2text(LINE_REC *line, int coloring, GString *str) break; case LINE_CMD_INDENT: break; + case LINE_CMD_INDENT_FUNC: + ptr += sizeof(void *); + break; } } } diff --git a/src/fe-text/textbuffer.h b/src/fe-text/textbuffer.h index cc01667b..8256309f 100644 --- a/src/fe-text/textbuffer.h +++ b/src/fe-text/textbuffer.h @@ -11,6 +11,7 @@ enum { LINE_CMD_UNDERLINE, /* enable/disable underlining */ LINE_CMD_REVERSE, /* enable/disable reversed text */ LINE_CMD_INDENT, /* if line is split, indent it at this position */ + LINE_CMD_INDENT_FUNC, /* if line is split, use the specified indentation function */ LINE_CMD_BLINK, /* blinking background */ LINE_CMD_FORMAT, /* end of line, but next will come the format that was used to create the text in format <module><format_name><arg><arg2...> - fields are separated diff --git a/src/perl/textui/TextBufferView.xs b/src/perl/textui/TextBufferView.xs index dfb1d036..37efc856 100644 --- a/src/perl/textui/TextBufferView.xs +++ b/src/perl/textui/TextBufferView.xs @@ -1,17 +1,74 @@ #include "module.h" +static char *default_indent_func; + +static int perl_indent_func(TEXT_BUFFER_VIEW_REC *view, + LINE_REC *line, int ypos) +{ + dSP; + int retcount, ret; + + ENTER; + SAVETMPS; + + PUSHMARK(SP); + XPUSHs(sv_2mortal(plain_bless(view, "Irssi::TextUI::TextBufferView"))); + XPUSHs(sv_2mortal(plain_bless(line, "Irssi::TextUI::Line"))); + XPUSHs(sv_2mortal(newSViv(ypos))); + PUTBACK; + + retcount = perl_call_pv(default_indent_func, G_EVAL|G_DISCARD); + SPAGAIN; + + ret = 0; + if (SvTRUE(ERRSV)) { + STRLEN n_a; + char *package; + + package = perl_function_get_package(default_indent_func); + signal_emit("script error", 2, + perl_script_find_package(package), + SvPV(ERRSV, n_a)); + g_free(package); + } else if (retcount > 0) { + ret = POPi; + } + + PUTBACK; + FREETMPS; + LEAVE; + + return ret; +} + +void perl_textbuffer_view_init(void) +{ + default_indent_func = NULL; +} + +void perl_textbuffer_view_deinit(void) +{ + g_free_not_null(default_indent_func); +} + MODULE = Irssi::TextUI::TextBufferView PACKAGE = Irssi::TextUI::TextBuffer PREFIX = textbuffer_ PROTOTYPES: ENABLE Irssi::TextUI::TextBufferView -textbuffer_view_create(buffer, width, height, default_indent, longword_noindent, scroll) +textbuffer_view_create(buffer, width, height, scroll) Irssi::TextUI::TextBuffer buffer int width int height - int default_indent - int longword_noindent int scroll +void +gui_windows_set_default_indent_func(func) + char *func +CODE: + g_free_not_null(default_indent_func); + default_indent_func = g_strdup(func); + gui_windows_set_default_indent_func(perl_indent_func); + #******************************* MODULE = Irssi::TextUI::TextBufferView PACKAGE = Irssi::TextUI::TextBufferView PREFIX = textbuffer_view_ #******************************* @@ -25,6 +82,8 @@ textbuffer_view_set_default_indent(view, default_indent, longword_noindent) Irssi::TextUI::TextBufferView view int default_indent int longword_noindent +CODE: + textbuffer_view_set_default_indent(view, default_indent, longword_noindent, NULL); void textbuffer_view_set_scroll(view, scroll) diff --git a/src/perl/textui/TextUI.xs b/src/perl/textui/TextUI.xs index c92da84a..9ebd2c6b 100644 --- a/src/perl/textui/TextUI.xs +++ b/src/perl/textui/TextUI.xs @@ -96,11 +96,13 @@ CODE: irssi_add_plains(textui_plains); perl_statusbar_init(); + perl_textbuffer_view_init(); void deinit() CODE: perl_statusbar_deinit(); + perl_textbuffer_view_deinit(); MODULE = Irssi::TextUI PACKAGE = Irssi |