/* SYNTAX: SCROLLBACK REDRAW */ static void cmd_scrollback_redraw(void) { GUI_WINDOW_REC *gui; LINE_REC *line, *next; gui = WINDOW_GUI(active_win); term_refresh_freeze(); line = textbuffer_view_get_lines(gui->view); while (line != NULL) { next = line->next; textbuffer_reformat_line(active_win, line); line = next; } gui_window_redraw(active_win); term_refresh_thaw(); }
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 void gui_window_destroyed(WINDOW_REC *window) { MAIN_WINDOW_REC *parent; GUI_WINDOW_REC *gui; g_return_if_fail(window != NULL); gui = WINDOW_GUI(window); parent = gui->parent; signal_emit("gui window destroyed", 1, window); gui_window_deinit(gui); window->gui_data = NULL; if (parent->active == window && mainwindows->next != NULL) mainwindow_destroy(parent); }
static void sig_main_statusbar_changed(WINDOW_REC *window) { MAIN_WINDOW_REC *parent; if (window == NULL) return; parent = WINDOW_GUI(window)->parent; if (mainbar == parent->statusbar) return; if (mainbar != NULL) { mainbar_remove_items(); sidebar_add_items(mainbar_window); } sidebar_remove_items(parent); mainbar_add_items(parent); }
void gui_printtext_after_time(TEXT_DEST_REC *dest, LINE_REC *prev, const char *str, time_t time) { GUI_WINDOW_REC *gui; gui = WINDOW_GUI(dest->window); if (prev == NULL && !gui->view->buffer->last_eol) { /* we have an unfinished line in the buffer still */ view_add_eol(gui->view, &gui->insert_after); } gui->use_insert_after = TRUE; gui->insert_after = prev; gui->insert_after_time = time; format_send_to_gui(dest, str); gui->use_insert_after = FALSE; signal_emit("gui print text after finished", 3, dest->window, gui->insert_after, prev); }
/* SYNTAX: SCROLLBACK HOME */ static void cmd_scrollback_home(const char *data) { GUI_WINDOW_REC *gui; gui = WINDOW_GUI(active_win); if (gui->startline == gui->lines) return; gui->startline = gui->lines; gui->subline = 0; gui_window_update_ypos(gui); gui->bottom = is_window_bottom(gui); if (is_window_visible(active_win)) gui_window_redraw(active_win); signal_emit("gui page scrolled", 1, active_win); }
static void sig_activity_update(Window *window) { GSList *tmp; for (tmp = WINDOW_GUI(window)->views; tmp != NULL; tmp = tmp->next) { WindowView *view = tmp->data; if (window->data_level == 0) { if (view->pane->tab->data_level != 0) tab_clear_activity(view->pane->tab); continue; } if (view->pane->tab->data_level < window->data_level) { /* update tab's main label's color too */ tab_update_activity(view->pane->tab); } } }
static void sig_gui_printtext_finished(WINDOW_REC *window) { GUI_WINDOW_REC *gui; LINE_REC *insert_after; if (format->len == 0) return; /* save format of the line */ gui = WINDOW_GUI(window); insert_after = gui->use_insert_after ? gui->insert_after : gui->view->buffer->cur_line; textbuffer_insert(gui->view->buffer, insert_after, (unsigned char *) format->str, format->len, NULL); g_string_truncate(format, 0); }
static void window_lastlog_clear(WINDOW_REC *window) { TEXT_BUFFER_VIEW_REC *view; LINE_REC *line, *next; term_refresh_freeze(); view = WINDOW_GUI(window)->view; line = textbuffer_view_get_lines(view); while (line != NULL) { next = line->next; if (line->info.level & MSGLEVEL_LASTLOG) textbuffer_view_remove_line(view, line); line = next; } textbuffer_view_redraw(view); term_refresh_thaw(); }
static void gui_window_destroyed(WINDOW_REC *window) { MAIN_WINDOW_REC *parent; GUI_WINDOW_REC *gui; g_return_if_fail(window != NULL); gui = WINDOW_GUI(window); parent = gui->parent; gui_window_set_unsticky(window); signal_emit("gui window destroyed", 1, window); gui_window_deinit(gui); window->gui_data = NULL; if (parent->active == window) mainwindow_change_active(parent, window); }
static void remove_old_lines(WINDOW_REC *window) { GUI_WINDOW_REC *gui; LINE_REC *line; time_t old_time; gui = WINDOW_GUI(window); old_time = time(NULL)-(scrollback_hours*3600); if (scrollback_lines > 0) { /* remove lines by line count */ while (window->lines > scrollback_lines) { line = gui->lines->data; if (line->time >= old_time) { /* too new line, don't remove yet */ break; } remove_first_line(window); } } }
MAIN_WINDOW_REC *mainwindow_create(void) { MAIN_WINDOW_REC *rec, *parent; int space; rec = g_new0(MAIN_WINDOW_REC, 1); rec->statusbar_lines = 1; if (mainwindows == NULL) { active_mainwin = rec; rec->first_line = reserved_up; rec->last_line = LINES-1-reserved_down-rec->statusbar_lines; rec->lines = rec->last_line-rec->first_line+1; } else { parent = WINDOW_GUI(active_win)->parent; if (parent->lines < WINDOW_MIN_SIZE+NEW_WINDOW_SIZE) parent = find_window_with_room(); if (parent == NULL) return NULL; /* not enough space */ space = (parent->lines-parent->statusbar_lines)/2; rec->first_line = parent->first_line; rec->last_line = rec->first_line + space-rec->statusbar_lines; rec->lines = rec->last_line-rec->first_line+1; parent->first_line = rec->last_line+1+rec->statusbar_lines; parent->lines = parent->last_line-parent->first_line+1; mainwindow_resize(parent, -space-1, FALSE); } #ifdef USE_CURSES_WINDOWS rec->curses_win = newwin(rec->lines, COLS, rec->first_line, 0); refresh(); #endif mainwindows = g_slist_append(mainwindows, rec); signal_emit("mainwindow created", 1, rec); return rec; }
/* SYNTAX: WINDOW STICK [<ref#>] [ON|OFF] */ static void cmd_window_stick(const char *data) { MAIN_WINDOW_REC *mainwin; WINDOW_REC *win; mainwin = active_mainwin; win = active_mainwin->active; if (is_numeric(data, ' ')) { /* ref# specified */ win = window_find_refnum(atoi(data)); if (win == NULL) { printformat_window(active_win, MSGLEVEL_CLIENTERROR, TXT_REFNUM_NOT_FOUND, data); return; } while (*data != ' ' && *data != '\0') data++; while (*data == ' ') data++; } if (g_strncasecmp(data, "OF", 2) == 0 || i_toupper(*data) == 'N') { /* unset sticky */ if (!WINDOW_GUI(win)->sticky) { printformat_window(win, MSGLEVEL_CLIENTERROR, TXT_WINDOW_NOT_STICKY); } else { gui_window_set_unsticky(win); printformat_window(win, MSGLEVEL_CLIENTNOTICE, TXT_WINDOW_UNSET_STICKY); } } else { /* set sticky */ window_reparent(win, mainwin); gui_window_set_sticky(win); printformat_window(active_win, MSGLEVEL_CLIENTNOTICE, TXT_WINDOW_SET_STICKY); } }
void gui_window_scroll(WINDOW_REC *window, int lines) { GUI_WINDOW_REC *gui; g_return_if_fail(window != NULL); gui = WINDOW_GUI(window); if (lines < 0) { if (gui->startline == NULL || gui->startline->prev == NULL) return; gui_window_scroll_up(gui, -lines); } else { if (is_scrolled_bottom(gui)) return; gui_window_scroll_down(gui, lines); } if (is_window_visible(window)) gui_window_redraw(window); signal_emit("gui page scrolled", 1, window); }
static void remove_first_line(WINDOW_REC *window) { GUI_WINDOW_REC *gui; TEXT_CHUNK_REC *chunk; g_return_if_fail(window != NULL); gui = WINDOW_GUI(window); chunk = gui->text_chunks->data; if (--chunk->lines == 0) text_chunk_free(gui, chunk); if (gui->lastlog_last_check != NULL && gui->lastlog_last_check->data == window) gui->lastlog_last_check = NULL; if (gui->lastlog_last_away != NULL && gui->lastlog_last_away->data == window) gui->lastlog_last_away = NULL; if (gui->startline->prev == NULL) { /* first line in screen removed */ gui->startline = gui->startline->next; gui->subline = 0; gui->ypos--; } if (gui->bottom_startline->prev == NULL) { /* bottom line removed (shouldn't happen?) */ gui->bottom_startline = gui->bottom_startline->next; gui->bottom_subline = 0; } window->lines--; g_mem_chunk_free(gui->line_chunk, gui->lines->data); gui->lines = g_list_remove(gui->lines, gui->lines->data); if (gui->startline->prev == NULL && is_window_visible(window)) gui_window_redraw(window); }
void gui_window_reparent(WINDOW_REC *window, MAIN_WINDOW_REC *parent) { MAIN_WINDOW_REC *oldparent; oldparent = WINDOW_MAIN(window); if (oldparent == parent) return; gui_window_set_unsticky(window); textbuffer_view_set_window(WINDOW_GUI(window)->view, NULL); WINDOW_MAIN(window) = parent; if (parent->sticky_windows) gui_window_set_sticky(window); if (MAIN_WINDOW_TEXT_HEIGHT(parent) != MAIN_WINDOW_TEXT_HEIGHT(oldparent) || parent->width != oldparent->width) { gui_window_resize(window, parent->width, MAIN_WINDOW_TEXT_HEIGHT(parent)); } }
static void cmd_scrollback_status(void) { GSList *tmp; int window_kb, total_lines, total_kb; total_lines = 0; total_kb = 0; for (tmp = windows; tmp != NULL; tmp = tmp->next) { WINDOW_REC *window = tmp->data; GUI_WINDOW_REC *gui = WINDOW_GUI(window); window_kb = g_slist_length(gui->text_chunks)* LINE_TEXT_CHUNK_SIZE/1024; total_lines += window->lines; total_kb += window_kb; printtext(NULL, NULL, MSGLEVEL_CLIENTCRAP, "Window %d: %d lines, %dkB of data", window->refnum, window->lines, window_kb); } printtext(NULL, NULL, MSGLEVEL_CLIENTCRAP, "Total: %d lines, %dkB of data", total_lines, total_kb); }
static void mainwindow_resize_windows(MAIN_WINDOW_REC *window) { GSList *tmp; int resized; mainwindow_set_screen_size(window); resized = FALSE; for (tmp = windows; tmp != NULL; tmp = tmp->next) { WINDOW_REC *rec = tmp->data; if (rec->gui_data != NULL && WINDOW_GUI(rec)->parent == window && !window_size_equals(rec, window)) { resized = TRUE; gui_window_resize(rec, window->width, MAIN_WINDOW_TEXT_HEIGHT(window)); } } if (resized) signal_emit("mainwindow resized", 1, window); }
static void item_more(SBAR_ITEM_REC *item, int get_size_only) { MAIN_WINDOW_REC *mainwin; int visible; if (active_win == NULL) { mainwin = NULL; visible = FALSE; } else { mainwin = WINDOW_MAIN(active_win); visible = WINDOW_GUI(active_win)->view->more_text; } if (!visible) { if (mainwin != NULL) more_visible = g_slist_remove(more_visible, mainwin); if (get_size_only) item->min_size = item->max_size = 0; return; } more_visible = g_slist_prepend(more_visible, mainwin); statusbar_item_default_handler(item, get_size_only, NULL, "", FALSE); }
void quassel_irssi_backlog(void* arg, int msg_id, int timestamp, int bufferid, int network, char* buffer_id, char* sender, int type, int flags, char* content) { (void) msg_id; (void) bufferid; (void) type; (void) flags; Quassel_SERVER_REC *server = (Quassel_SERVER_REC*)arg; char *chan = channame(network, buffer_id); char *nick = strdup(sender); char *address; if( (address=index(nick, '!')) != NULL) *address = 0; address++; GSList *win = windows; while(win) { WINDOW_REC* winrec = (WINDOW_REC*) win->data; if(winrec->active_server != SERVER(server) && winrec->connect_server != SERVER(server)) goto next; if(!winrec->active) goto next; if(strcmp(winrec->active->visible_name, chan)!=0) goto next; if(!WINDOW_GUI(winrec) || !WINDOW_GUI(winrec)->view || !WINDOW_GUI(winrec)->view->buffer) goto next; LINE_INFO_REC lineinforec; lineinforec.time=timestamp; lineinforec.level = 0; LINE_REC* pos = WINDOW_GUI(winrec)->view->buffer->first_line; LINE_REC* before = pos; for(; pos!=NULL; pos = pos->next) { if(pos->info.time >= timestamp) break; before = pos; } unsigned char *data = NULL; int len = asprintf((char**)&data, "%d:%s:%sxx", timestamp, nick, content); data[len-2]=0; data[len-1]=0x80; LINE_REC *linerec = textbuffer_insert(WINDOW_GUI(winrec)->view->buffer, before, data, len, &lineinforec); free(data); textbuffer_view_insert_line(WINDOW_GUI(winrec)->view, linerec); if(WINDOW_GUI(winrec)->insert_after) WINDOW_GUI(winrec)->insert_after = linerec; WINDOW_GUI(winrec)->view->dirty = 1; winrec->last_line = time(NULL); mainwindows_redraw(); next: win = g_slist_next(win); } free(nick); }
static void show_lastlog(const char *searchtext, GHashTable *optlist, int start, int count, FILE *fhandle) { WINDOW_REC *window; LINE_REC *startline; GList *list, *tmp; GString *line; char *str; int level, before, after, len, date = FALSE; level = cmd_options_get_level("lastlog", optlist); if (level == -1) return; /* error in options */ if (level == 0) level = MSGLEVEL_ALL; if (g_hash_table_lookup(optlist, "clear") != NULL) { textbuffer_view_remove_lines_by_level(WINDOW_GUI(active_win)->view, MSGLEVEL_LASTLOG); if (*searchtext == '\0') return; } /* which window's lastlog to look at? */ window = active_win; str = g_hash_table_lookup(optlist, "window"); if (str != NULL) { window = is_numeric(str, '\0') ? window_find_refnum(atoi(str)) : window_find_item(NULL, str); if (window == NULL) { printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, TXT_REFNUM_NOT_FOUND, str); return; } } if (g_hash_table_lookup(optlist, "new") != NULL) startline = textbuffer_view_get_bookmark(WINDOW_GUI(window)->view, "lastlog_last_check"); else if (g_hash_table_lookup(optlist, "away") != NULL) startline = textbuffer_view_get_bookmark(WINDOW_GUI(window)->view, "lastlog_last_away"); else startline = NULL; if (startline == NULL) startline = textbuffer_view_get_lines(WINDOW_GUI(window)->view); str = g_hash_table_lookup(optlist, "#"); if (str != NULL) { before = after = atoi(str); } else { str = g_hash_table_lookup(optlist, "before"); before = str == NULL ? 0 : *str != '\0' ? atoi(str) : DEFAULT_LASTLOG_BEFORE; str = g_hash_table_lookup(optlist, "after"); if (str == NULL) str = g_hash_table_lookup(optlist, "a"); after = str == NULL ? 0 : *str != '\0' ? atoi(str) : DEFAULT_LASTLOG_AFTER; } if (g_hash_table_lookup(optlist, "date") != NULL) date = TRUE; list = textbuffer_find_text(WINDOW_GUI(window)->view->buffer, startline, level, MSGLEVEL_LASTLOG, searchtext, before, after, g_hash_table_lookup(optlist, "regexp") != NULL, g_hash_table_lookup(optlist, "word") != NULL, g_hash_table_lookup(optlist, "case") != NULL); len = g_list_length(list); if (count <= 0) tmp = list; else { int pos = len-count-start; if (pos < 0) pos = 0; tmp = pos > len ? NULL : g_list_nth(list, pos); len = g_list_length(tmp); } if (g_hash_table_lookup(optlist, "count") != NULL) { printformat_window(active_win, MSGLEVEL_CLIENTNOTICE, TXT_LASTLOG_COUNT, len); g_list_free(list); return; } if (len > MAX_LINES_WITHOUT_FORCE && fhandle == NULL && g_hash_table_lookup(optlist, "force") == NULL) { printformat_window(active_win, MSGLEVEL_CLIENTNOTICE|MSGLEVEL_LASTLOG, TXT_LASTLOG_TOO_LONG, len); g_list_free(list); return; } if (fhandle == NULL && g_hash_table_lookup(optlist, "-") == NULL) printformat(NULL, NULL, MSGLEVEL_LASTLOG, TXT_LASTLOG_START); line = g_string_new(NULL); while (tmp != NULL && (count < 0 || count > 0)) { LINE_REC *rec = tmp->data; if (rec == NULL) { if (tmp->next == NULL) break; if (fhandle != NULL) { fwrite("--\n", 3, 1, fhandle); } else { printformat_window(active_win, MSGLEVEL_LASTLOG, TXT_LASTLOG_SEPARATOR); } tmp = tmp->next; continue; } /* get the line text */ textbuffer_line2text(rec, fhandle == NULL, line); if (!settings_get_bool("timestamps")) { struct tm *tm = localtime(&rec->info.time); char timestamp[10]; g_snprintf(timestamp, sizeof(timestamp), "%02d:%02d ", tm->tm_hour, tm->tm_min); g_string_prepend(line, timestamp); } if (date == TRUE) prepend_date(window, rec, line); /* write to file/window */ if (fhandle != NULL) { fwrite(line->str, line->len, 1, fhandle); fputc('\n', fhandle); } else { printtext_window(active_win, MSGLEVEL_LASTLOG, "%s", line->str); } count--; tmp = tmp->next; } g_string_free(line, TRUE); if (fhandle == NULL && g_hash_table_lookup(optlist, "-") == NULL) printformat(NULL, NULL, MSGLEVEL_LASTLOG, TXT_LASTLOG_END); textbuffer_view_set_bookmark_bottom(WINDOW_GUI(window)->view, "lastlog_last_check"); g_list_free(list); }
static void window_next_page(void) { GUI_WINDOW_REC *gui = WINDOW_GUI(active_win); gui_window_scroll(active_win, (gui->parent->last_line-gui->parent->first_line)/2); }
void gui_window_line_remove(WINDOW_REC *window, LINE_REC *line, int redraw) { GUI_WINDOW_REC *gui; GList *last; int screenchange; g_return_if_fail(window != NULL); g_return_if_fail(line != NULL); gui = WINDOW_GUI(window); screenchange = g_list_find(gui->startline, line) != NULL; if (screenchange) gui->ypos -= gui_window_get_linecount(gui, line); gui_window_cache_remove(gui, line); gui_window_line_text_free(gui, line); if (gui->lastlog_last_check != NULL && gui->lastlog_last_check->data == line) gui->lastlog_last_check = NULL; if (gui->lastlog_last_away != NULL && gui->lastlog_last_away->data == line) gui->lastlog_last_away = NULL; last = g_list_last(gui->bottom_startline); if (last->data == line) { /* removing last line */ gui->last_subline = gui_window_get_linecount(gui, last->prev->data)-1; } if (gui->bottom_startline->data == line) { /* bottom line removed */ if (gui->bottom_startline->next != NULL) { gui->bottom_startline = gui->bottom_startline->next; gui->bottom_subline = 0; } else { gui->bottom_startline = gui->bottom_startline->prev; gui->bottom_subline = gui->last_subline+1; } } if (gui->startline->data == line) { /* first line in screen removed */ if (gui->startline->next != NULL) { gui->startline = gui->startline->next; gui->subline = 0; } else { gui->startline = gui->startline->prev; gui->subline = gui->last_subline+1; gui->ypos = -1; gui->empty_linecount = gui->parent->lines; gui->bottom = TRUE; } } window->lines--; g_mem_chunk_free(gui->line_chunk, line); gui->lines = g_list_remove(gui->lines, line); if (window->lines == 0) gui_window_clear(window); if (redraw && screenchange && is_window_visible(window)) gui_window_redraw(window); }
static void sig_gui_print_text(WINDOW_REC *window, void *fgcolor, void *bgcolor, void *pflags, char *str, void *level) { GUI_WINDOW_REC *gui; LINE_REC *line; int fg, bg, flags, new_lines, n, visible, ypos, subline; flags = GPOINTER_TO_INT(pflags); fg = GPOINTER_TO_INT(fgcolor); bg = GPOINTER_TO_INT(bgcolor); get_colors(flags, &fg, &bg); if (window == NULL && next_xpos != -1) { wmove(stdscr, next_ypos, next_xpos); set_color(stdscr, fg | (bg << 4)); addstr(str); next_xpos += strlen(str); return; } g_return_if_fail(window != NULL); gui = WINDOW_GUI(window); visible = is_window_visible(window) && gui->bottom; if (gui->cur_text == NULL) create_text_chunk(gui); /* newline can be only at the start of the line.. */ if (flags & PRINTFLAG_NEWLINE) { remove_old_lines(window); if (!gui->eol_marked) { if (format->len > 0 || gui->temp_line != NULL) { /* mark format continuing to next line */ char tmp[2] = { 0, (char)LINE_CMD_FORMAT_CONT }; linebuf_add(gui, tmp, 2); } linebuf_add(gui, "\0\200", 2); /* mark EOL */ } gui->eol_marked = FALSE; line = create_line(gui, 0); if (gui->temp_line == NULL || g_list_find(gui->startline, gui->temp_line) != NULL) gui_window_newline(gui, visible); gui->last_subline = 0; } else { line = gui->temp_line != NULL ? gui->temp_line : gui->cur_line != NULL ? gui->cur_line : create_line(gui, 0); if (line->level == 0) line->level = GPOINTER_TO_INT(level); } line_add_colors(gui, fg, bg, flags); linebuf_add(gui, str, strlen(str)); mark_temp_eol(gui->cur_text); gui_window_cache_remove(gui, line); if (gui->temp_line != NULL) { /* updating existing line - don't even try to print it to screen */ return; } new_lines = gui_window_get_linecount(gui, line)-1 - gui->last_subline; for (n = 0; n < new_lines; n++) gui_window_newline(gui, visible); if (visible) { /* draw the line to screen. */ ypos = gui->ypos-new_lines; if (new_lines > 0) { #ifdef USE_CURSES_WINDOWS set_color(gui->parent->curses_win, 0); wmove(gui->parent->curses_win, ypos, 0); wclrtoeol(gui->parent->curses_win); #else set_color(stdscr, 0); move(ypos + gui->parent->first_line, 0); wclrtoeol(stdscr); #endif } if (ypos >= 0) subline = gui->last_subline; else { /* *LONG* line - longer than screen height */ subline = -ypos+gui->last_subline; ypos = 0; } gui_window_line_draw(gui, line, ypos, subline, -1); } gui->last_subline += new_lines; }
void gui_window_redraw(WINDOW_REC *window) { GUI_WINDOW_REC *gui; WINDOW *cwin; GList *line; int ypos, lines, skip, max; g_return_if_fail(window != NULL); gui = WINDOW_GUI(window); #ifdef USE_CURSES_WINDOWS cwin = gui->parent->curses_win; #else cwin = stdscr; #endif /* clear the lines first */ set_color(cwin, 0); #ifdef USE_CURSES_WINDOWS for (ypos = 0; ypos <= gui->parent->lines; ypos++) { #else for (ypos = gui->parent->first_line; ypos <= gui->parent->last_line; ypos++) { #endif wmove(cwin, ypos, 0); wclrtoeol(cwin); } skip = gui->subline; ypos = 0; for (line = gui->startline; line != NULL; line = line->next) { LINE_REC *rec = line->data; max = gui->parent->lines-1 - ypos+1; if (max < 0) break; lines = gui_window_line_draw(gui, rec, ypos, skip, max); ypos += lines-skip; skip = 0; } screen_refresh(cwin); } static void gui_window_scroll_up(GUI_WINDOW_REC *gui, int lines) { LINE_REC *line; int count, linecount; if (gui->startline == NULL) return; count = lines-gui->subline; gui->ypos += gui->subline; gui->subline = 0; while (gui->startline->prev != NULL && count > 0) { gui->startline = gui->startline->prev; line = gui->startline->data; linecount = gui_window_get_linecount(gui, line); count -= linecount; gui->ypos += linecount; } if (count < 0) { gui->subline = -count; gui->ypos -= -count; } gui->bottom = is_window_bottom(gui); }
static void gui_printtext(WINDOW_REC *window, gpointer fgcolor, gpointer bgcolor, gpointer pflags, char *str, gpointer level) { GUI_WINDOW_REC *gui; LINE_REC *line; int fg, bg, flags, new_lines, n, visible, ypos, subline; g_return_if_fail(window != NULL); remove_old_lines(window); gui = WINDOW_GUI(window); visible = is_window_visible(window) && gui->bottom; flags = GPOINTER_TO_INT(pflags); fg = GPOINTER_TO_INT(fgcolor); bg = GPOINTER_TO_INT(bgcolor); if (gui->cur_text == NULL) create_text_chunk(gui); /* \n can be only at the start of the line.. */ if (*str == '\n') { str++; linebuf_add(gui, "\0\x80", 2); /* mark EOL */ line = create_line(gui, 0); gui_window_newline(gui, visible); gui->cur_text->lines++; gui->last_subline = 0; } else { line = gui->cur_line != NULL ? gui->cur_line : create_line(gui, 0); if (line->level == 0) line->level = GPOINTER_TO_INT(level); } get_colors(flags, &fg, &bg); line_add_colors(gui, fg, bg, flags); linebuf_add(gui, str, strlen(str)); mark_temp_eol(gui->cur_text); gui_window_cache_remove(gui, line); new_lines = gui_window_get_linecount(gui, line)-1 - gui->last_subline; for (n = 0; n < new_lines; n++) gui_window_newline(gui, visible); if (visible) { /* draw the line to screen. */ ypos = gui->ypos-new_lines; if (new_lines > 0) { set_color(0); move(gui->parent->first_line+ypos, 0); clrtoeol(); } if (ypos >= 0) subline = gui->last_subline; else { /* *LONG* line - longer than screen height */ subline = -ypos+gui->last_subline; ypos = 0; } ypos += gui->parent->first_line; gui_window_line_draw(gui, line, ypos, subline, -1); } gui->last_subline += new_lines; }
GList *gui_window_find_text(WINDOW_REC *window, const char *text, GList *startline, int regexp, int fullword) { #ifdef HAVE_REGEX_H regex_t preg; #endif GList *tmp; GList *matches; gchar *str, *ptr; gint n, size; g_return_val_if_fail(window != NULL, NULL); g_return_val_if_fail(text != NULL, NULL); matches = NULL; size = 1024; str = g_malloc(1024); #ifdef HAVE_REGEX_H if (regcomp(&preg, text, REG_ICASE|REG_EXTENDED|REG_NOSUB) != 0) return 0; #endif if (startline == NULL) startline = WINDOW_GUI(window)->lines; for (tmp = startline; tmp != NULL; tmp = tmp->next) { LINE_REC *rec = tmp->data; if (*text == '\0') { matches = g_list_append(matches, rec); continue; } for (n = 0, ptr = rec->text; ; ptr++) { if (*ptr != 0) { if (n+2 > size) { size += 1024; str = g_realloc(str, size); } str[n++] = toupper(*ptr); } else { ptr++; if ((guchar) *ptr == LINE_CMD_CONTINUE) { gchar *tmp; memcpy(&tmp, ptr+1, sizeof(gchar *)); ptr = tmp-1; } else if ((guchar) *ptr == LINE_CMD_EOL || (guchar) *ptr == LINE_CMD_FORMAT) break; } } str[n] = '\0'; if ( #ifdef HAVE_REGEX_H regexp ? regexec(&preg, str, 0, NULL, 0) == 0 : #endif fullword ? stristr_full(str, text) != NULL : stristr(str, text) != NULL) { /* matched */ matches = g_list_append(matches, rec); } } #ifdef HAVE_REGEX_H regfree(&preg); #endif if (str != NULL) g_free(str); return matches; }
/* SYNTAX: SCROLLBACK CLEAR */ static void cmd_scrollback_clear(void) { textbuffer_view_remove_all_lines(WINDOW_GUI(active_win)->view); }
/* SYNTAX: SCROLLBACK GOTO <+|-linecount>|<linenum>|<timestamp> */ static void cmd_scrollback_goto(gchar *data) { GList *pos; gchar *arg1, *arg2; void *free_arg; gint lines; if (!cmd_get_params(data, &free_arg, 2, &arg1, &arg2)) return; if (*arg2 == '\0' && (*arg1 == '-' || *arg1 == '+')) { /* go forward/backward n lines */ if (sscanf(arg1 + (*arg1 == '-' ? 0 : 1), "%d", &lines) == 1) gui_window_scroll(active_win, lines); } else if (*arg2 == '\0' && strchr(arg1, ':') == NULL && strchr(arg1, '.') == NULL && sscanf(arg1, "%d", &lines) == 1) { /* go to n'th line. */ pos = g_list_nth(WINDOW_GUI(active_win)->lines, lines); if (pos != NULL) scrollback_goto_pos(active_win, pos); } else { struct tm tm; time_t stamp; gint day, month; /* [dd.mm | -<days ago>] hh:mi[:ss] */ stamp = time(NULL); if (*arg1 == '-') { /* -<days ago> */ if (sscanf(arg1+1, "%d", &day) == 1) stamp -= day*3600*24; memcpy(&tm, localtime(&stamp), sizeof(struct tm)); } else if (*arg2 != '\0') { /* dd.mm */ if (sscanf(arg1, "%d.%d", &day, &month) == 2) { month--; memcpy(&tm, localtime(&stamp), sizeof(struct tm)); if (tm.tm_mon < month) tm.tm_year--; tm.tm_mon = month; tm.tm_mday = day; stamp = mktime(&tm); } } else { /* move time argument to arg2 */ arg2 = arg1; } /* hh:mi[:ss] */ memcpy(&tm, localtime(&stamp), sizeof(struct tm)); tm.tm_sec = 0; sscanf(arg2, "%d:%d:%d", &tm.tm_hour, &tm.tm_min, &tm.tm_sec); stamp = mktime(&tm); if (stamp > time(NULL) && arg1 == arg2) { /* we used /SB GOTO 23:59 or something, we want to jump to previous day's 23:59 time instead of into future. */ stamp -= 3600*24; } if (stamp > time(NULL)) { /* we're still looking into future, don't bother checking */ cmd_params_free(free_arg); return; } /* find the first line after timestamp */ for (pos = WINDOW_GUI(active_win)->lines; pos != NULL; pos = pos->next) { LINE_REC *rec = pos->data; if (rec->time >= stamp) { scrollback_goto_pos(active_win, pos); break; } } } cmd_params_free(free_arg); }
static void scrollback_goto_time(const char *datearg, const char *timearg) { LINE_REC *line; struct tm tm; time_t now, stamp; int day, month; /* [dd[.mm] | -<days ago>] hh:mi[:ss] */ now = stamp = time(NULL); if (*datearg == '-') { /* -<days ago> */ stamp -= atoi(datearg+1) * 3600*24; memcpy(&tm, localtime(&stamp), sizeof(struct tm)); } else if (*timearg != '\0') { /* dd[.mm] */ memcpy(&tm, localtime(&stamp), sizeof(struct tm)); day = month = 0; sscanf(datearg, "%d.%d", &day, &month); if (day <= 0) return; if (month <= 0) { /* month not given */ if (day > tm.tm_mday) { /* last month's day */ if (tm.tm_mon > 0) tm.tm_mon--; else { /* last year's day.. */ tm.tm_year--; tm.tm_mon = 11; } } } else { month--; if (month > tm.tm_mon) tm.tm_year--; tm.tm_mon = month; } tm.tm_mday = day; stamp = mktime(&tm); } else { /* only time given, move it to timearg */ timearg = datearg; } /* hh:mi[:ss] */ memcpy(&tm, localtime(&stamp), sizeof(struct tm)); tm.tm_sec = 0; sscanf(timearg, "%d:%d:%d", &tm.tm_hour, &tm.tm_min, &tm.tm_sec); stamp = mktime(&tm); if (stamp > now && timearg == datearg) { /* we used /SB GOTO 23:59 or something, we want to jump to previous day's 23:59 time instead of into future. */ stamp -= 3600*24; } if (stamp > now) { /* we're still looking into future, don't bother checking */ return; } /* scroll to first line after timestamp */ line = textbuffer_view_get_lines(WINDOW_GUI(active_win)->view); for (; line != NULL; line = line->next) { if (line->info.time >= stamp) { gui_window_scroll_line(active_win, line); break; } } }