static void view_draw(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line, int subline, int ypos, int lines, int fill_bottom) { int linecount; if (view->dirty) /* don't bother drawing anything - redraw is coming */ return; while (line != NULL && lines > 0) { linecount = view_line_draw(view, line, subline, ypos, lines); ypos += linecount; lines -= linecount; subline = 0; line = line->next; } if (fill_bottom) { /* clear the rest of the view */ term_set_color(view->window, ATTR_RESET); while (lines > 0) { term_move(view->window, 0, ypos); term_clrtoeol(view->window); ypos++; lines--; } } }
/* * Tidy up the term ready to leave Zile (temporarily or permanently!). */ void term_tidy(void) { term_move(term_height() - 1, 0); term_clrtoeol(); term_attrset(1, FONT_NORMAL); term_refresh(); }
/* * Tidy and close the terminal ready to leave Zile. */ void term_finish (void) { term_move (term_height () - 1, 0); term_clrtoeol (); term_attrset (FONT_NORMAL); term_refresh (); term_close (); }
static void gui_entry_draw_from(GUI_ENTRY_REC *entry, int pos) { int i; int xpos, end_xpos; xpos = entry->xpos + entry->promptlen + pos2scrpos(entry, pos + entry->scrstart) - pos2scrpos(entry, entry->scrstart); end_xpos = entry->xpos + entry->width; if (xpos > end_xpos) return; term_set_color(root_window, ATTR_RESET); term_move(root_window, xpos, entry->ypos); for (i = entry->scrstart + pos; i < entry->text_len; i++) { unichar c = entry->text[i]; if (entry->hidden) xpos++; else if (term_type == TERM_TYPE_BIG5) xpos += big5_width(c); else if (entry->utf8) xpos += unichar_isprint(c) ? mk_wcwidth(c) : 1; else xpos++; if (xpos > end_xpos) break; if (entry->hidden) term_addch(root_window, ' '); else if (unichar_isprint(c)) term_add_unichar(root_window, c); else { term_set_color(root_window, ATTR_RESET|ATTR_REVERSE); term_addch(root_window, (c & 127)+'A'-1); term_set_color(root_window, ATTR_RESET); } } /* clear the rest of the input line */ if (xpos < end_xpos) { if (end_xpos == term_width) term_clrtoeol(root_window); else { while (xpos < end_xpos) { term_addch(root_window, ' '); xpos++; } } } }
static void sig_gui_print_text(WINDOW_REC *window, void *fgcolor, void *bgcolor, void *pflags, char *str, void *level) { GUI_WINDOW_REC *gui; TEXT_BUFFER_VIEW_REC *view; LINE_REC *insert_after; LINE_INFO_REC lineinfo; int fg, bg, flags, attr; flags = GPOINTER_TO_INT(pflags); fg = GPOINTER_TO_INT(fgcolor); bg = GPOINTER_TO_INT(bgcolor); get_colors(flags, &fg, &bg, &attr); if (window == NULL) { g_return_if_fail(next_xpos != -1); attr |= fg >= 0 ? fg : ATTR_RESETFG; attr |= bg >= 0 ? (bg << 4) : ATTR_RESETBG; term_set_color(root_window, attr); term_move(root_window, next_xpos, next_ypos); if (flags & GUI_PRINT_FLAG_CLRTOEOL) term_clrtoeol(root_window); term_addstr(root_window, str); next_xpos += strlen(str); return; } lineinfo.level = GPOINTER_TO_INT(level); lineinfo.time = time(NULL); gui = WINDOW_GUI(window); view = gui->view; insert_after = gui->use_insert_after ? gui->insert_after : view->buffer->cur_line; if (flags & GUI_PRINT_FLAG_NEWLINE) view_add_eol(view, &insert_after); line_add_colors(view->buffer, &insert_after, fg, bg, flags); 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, (unsigned char *) str, strlen(str), &lineinfo); } if (gui->use_insert_after) gui->insert_after = insert_after; }
void term_minibuf_write (const char *s) { size_t x; term_move (term_height () - 1, 0); term_clrtoeol (); for (x = 0; *s != '\0' && x < term_width (); s++) { term_addch (*(unsigned char *) s); ++x; } }
static void sig_gui_print_text(WINDOW_REC *window, void *fgcolor, void *bgcolor, void *pflags, char *str, TEXT_DEST_REC *dest) { GUI_WINDOW_REC *gui; TEXT_BUFFER_VIEW_REC *view; LINE_REC *insert_after; LINE_INFO_REC lineinfo; int fg, bg, flags, attr; flags = GPOINTER_TO_INT(pflags); fg = GPOINTER_TO_INT(fgcolor); bg = GPOINTER_TO_INT(bgcolor); get_colors(flags, &fg, &bg, &attr); if (window == NULL) { g_return_if_fail(next_xpos != -1); term_set_color2(root_window, attr, fg, bg); term_move(root_window, next_xpos, next_ypos); if (flags & GUI_PRINT_FLAG_CLRTOEOL) term_clrtoeol(root_window); term_addstr(root_window, str); next_xpos += strlen(str); /* FIXME utf8 or big5 */ return; } lineinfo.level = dest == NULL ? 0 : dest->level; gui = WINDOW_GUI(window); lineinfo.time = (gui->use_insert_after && gui->insert_after_time) ? gui->insert_after_time : time(NULL); view = gui->view; insert_after = gui->use_insert_after ? gui->insert_after : view->buffer->cur_line; if (flags & GUI_PRINT_FLAG_NEWLINE) { view_add_eol(view, &insert_after); } textbuffer_line_add_colors(view->buffer, &insert_after, fg, bg, flags); insert_after = textbuffer_insert(view->buffer, insert_after, (unsigned char *) str, strlen(str), &lineinfo); if (gui->use_insert_after) gui->insert_after = insert_after; }
void show_splash_screen(const char *splash) { size_t i; const char *p; for (i = 0; i < term_height() - 2; ++i) { term_move(i, 0); term_clrtoeol(); } term_move(0, 0); for (i = 0, p = splash; *p != '\0' && i < term_height() - 2; ++p) if (*p == '\n') term_move(++i, 0); else term_addch(*p); }
static void draw_window (size_t topline, Window wp) { size_t i, o; Region r; int highlight = calculate_highlight_region (wp, &r); /* Find the first line to display on the first screen line. */ for (o = buffer_start_of_line (get_window_bp (wp), window_o (wp)), i = get_window_topdelta (wp); i > 0 && o > 0; assert ((o = buffer_prev_line (get_window_bp (wp), o)) != SIZE_MAX), --i) ; /* Draw the window lines. */ size_t cur_tab_width = tab_width (get_window_bp (wp)); for (i = topline; i < get_window_eheight (wp) + topline; ++i) { /* Clear the line. */ term_move (i, 0); term_clrtoeol (); /* If at the end of the buffer, don't write any text. */ if (o == SIZE_MAX) continue; draw_line (i, get_window_start_column (wp), wp, o, r, highlight, cur_tab_width); if (get_window_start_column (wp) > 0) { term_move (i, 0); term_addstr("$"); } o = buffer_next_line (get_window_bp (wp), o); } set_window_all_displayed (wp, o >= get_buffer_size (get_window_bp (wp))); /* Draw the status line only if there is available space after the buffer text space. */ if (get_window_fheight (wp) - get_window_eheight (wp) > 0) draw_status_line (topline + get_window_eheight (wp), wp); }
static void gui_entry_draw_from(GUI_ENTRY_REC *entry, int pos) { const unichar *p; int xpos, end_xpos; xpos = entry->xpos + entry->promptlen + pos; end_xpos = entry->xpos + entry->width; if (xpos > end_xpos) return; term_set_color(root_window, ATTR_RESET); term_move(root_window, xpos, entry->ypos); p = entry->scrstart + pos < entry->text_len ? entry->text + entry->scrstart + pos : empty_str; for (; *p != '\0'; p++) { xpos += utf8_width(*p); if (xpos > end_xpos) break; if (entry->hidden) term_addch(root_window, ' '); else if (*p >= 32 && (entry->utf8 || (*p & 127) >= 32)) term_add_unichar(root_window, *p); else { term_set_color(root_window, ATTR_RESET|ATTR_REVERSE); term_addch(root_window, *p+'A'-1); term_set_color(root_window, ATTR_RESET); } } /* clear the rest of the input line */ if (end_xpos == term_width) term_clrtoeol(root_window); else { while (xpos < end_xpos) { term_addch(root_window, ' '); xpos++; } } }
static void draw_window(size_t topline, Window *wp) { size_t i, startcol, lineno; Line *lp; Region r; int highlight; Point pt = window_pt(wp); calculate_highlight_region(wp, &r, &highlight); /* Find the first line to display on the first screen line. */ for (lp = pt.p, lineno = pt.n, i = wp->topdelta; i > 0 && list_prev(lp) != wp->bp->lines; lp = list_prev(lp), --i, --lineno) ; cur_tab_width = tab_width(wp->bp); /* Draw the window lines. */ for (i = topline; i < wp->eheight + topline; ++i, ++lineno) { /* Clear the line. */ term_move(i, 0); term_clrtoeol(); /* If at the end of the buffer, don't write any text. */ if (lp == wp->bp->lines) continue; startcol = wp->start_column; draw_line(i, startcol, wp, lp, lineno, &r, highlight); if (wp->start_column > 0) { term_move(i, 0); term_addch('$'); } lp = list_next(lp); } }
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, *end, *text_newline; unsigned char *tmp; int xpos, color, drawcount, first, need_move, need_clrtoeol, char_width; if (view->dirty) /* don't bother drawing anything - redraw is coming */ return 0; cache = textbuffer_view_get_line_cache(view, line); if (subline >= cache->count) return 0; color = ATTR_RESET; need_move = TRUE; need_clrtoeol = FALSE; xpos = drawcount = 0; first = TRUE; text_newline = text = subline == 0 ? line->text : cache->lines[subline-1].start; for (;;) { if (text == text_newline) { if (need_clrtoeol && xpos < term_width) { term_set_color(view->window, ATTR_RESET); term_clrtoeol(view->window); } if (first) first = FALSE; else { ypos++; if (--max == 0) break; } if (subline > 0) { /* continuing previous line - indent it */ indent_func = cache->lines[subline-1].indent_func; if (indent_func == NULL) xpos = cache->lines[subline-1].indent; color = cache->lines[subline-1].color; } else { indent_func = NULL; } if (xpos == 0 && indent_func == NULL) need_clrtoeol = TRUE; else { /* line was indented - need to clear the indented area first */ term_set_color(view->window, ATTR_RESET); term_move(view->window, 0, ypos); term_clrtoeol(view->window); if (indent_func != NULL) xpos = indent_func(view, line, ypos); } if (need_move || xpos > 0) term_move(view->window, xpos, ypos); term_set_color(view->window, color); if (subline == cache->count-1) { text_newline = NULL; need_move = FALSE; } else { /* get the beginning of the next subline */ text_newline = cache->lines[subline].start; need_move = !cache->lines[subline].continues; } drawcount++; subline++; } if (*text == '\0') { /* command */ text++; if (*text == LINE_CMD_EOL || *text == LINE_CMD_FORMAT) break; if (*text == LINE_CMD_CONTINUE) { /* jump to next block */ memcpy(&tmp, text+1, sizeof(unsigned char *)); text = tmp; continue; } else if (*text == LINE_CMD_INDENT_FUNC) { text += sizeof(INDENT_FUNC); } else { update_cmd_color(*text, &color); term_set_color(view->window, color); } text++; continue; } end = text; if (view->utf8) { unichar chr; if (get_utf8_char(&end, 6, &chr)<0) char_width = 1; else char_width = utf8_width(chr); } else { if (term_type == TERM_TYPE_BIG5 && is_big5(end[0], end[1])) char_width = 2; else char_width = 1; end += char_width-1; } xpos += char_width; if (xpos <= term_width) { if (*text >= 32 && (end != text || (*text & 127) >= 32)) { for (; text < end; text++) term_addch(view->window, *text); term_addch(view->window, *text); } else { /* low-ascii */ term_set_color(view->window, ATTR_RESET|ATTR_REVERSE); term_addch(view->window, (*text & 127)+'A'-1); term_set_color(view->window, color); } } text++; } if (need_clrtoeol && xpos < term_width) { term_set_color(view->window, ATTR_RESET); term_clrtoeol(view->window); } return drawcount; }
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, *end, *text_newline; unsigned char *tmp; unichar chr; int xpos, color, fg24, bg24, drawcount, first, need_move, need_clrtoeol, char_width; if (view->dirty) /* don't bother drawing anything - redraw is coming */ return 0; cache = textbuffer_view_get_line_cache(view, line); if (subline >= cache->count) return 0; color = ATTR_RESET; need_move = TRUE; need_clrtoeol = FALSE; xpos = drawcount = 0; first = TRUE; text_newline = text = subline == 0 ? line->text : cache->lines[subline-1].start; for (;;) { if (text == text_newline) { if (need_clrtoeol && xpos < term_width) { term_set_color(view->window, ATTR_RESET); term_clrtoeol(view->window); } if (first) first = FALSE; else { ypos++; if (--max == 0) break; } if (subline > 0) { /* continuing previous line - indent it */ indent_func = cache->lines[subline-1].indent_func; if (indent_func == NULL) xpos = cache->lines[subline-1].indent; color = cache->lines[subline-1].color; #ifdef TERM_TRUECOLOR fg24 = cache->lines[subline-1].fg24; bg24 = cache->lines[subline-1].bg24; #endif } else { indent_func = NULL; } if (xpos == 0 && indent_func == NULL) need_clrtoeol = TRUE; else { /* line was indented - need to clear the indented area first */ term_set_color(view->window, ATTR_RESET); term_move(view->window, 0, ypos); term_clrtoeol(view->window); if (indent_func != NULL) xpos = indent_func(view, line, ypos); } if (need_move || xpos > 0) term_move(view->window, xpos, ypos); term_set_color2(view->window, color, fg24, bg24); if (subline == cache->count-1) { text_newline = NULL; need_move = FALSE; } else { /* get the beginning of the next subline */ text_newline = cache->lines[subline].start; need_move = !cache->lines[subline].continues; } drawcount++; subline++; } if (*text == '\0') { /* command */ text++; if (*text == LINE_CMD_EOL) break; if (*text == LINE_CMD_CONTINUE) { /* jump to next block */ memcpy(&tmp, text+1, sizeof(unsigned char *)); text = tmp; continue; } else { if (*text == LINE_COLOR_EXT) color = (color & BGATTR & ~ATTR_FGCOLOR24) | *++text; else if (*text == LINE_COLOR_EXT_BG) color = (color & FGATTR & ~ATTR_BGCOLOR24) | (*++text << BG_SHIFT); #ifdef TERM_TRUECOLOR else if (*text == LINE_COLOR_24) unformat_24bit_line_color(&text, 1, &color, &fg24, &bg24); #endif else update_cmd_color(*text, &color); term_set_color2(view->window, color, fg24, bg24); } text++; continue; } if (view->utf8) { chr = read_unichar(text, &end, &char_width); } else { chr = *text; end = text; if (term_type == TERM_TYPE_BIG5 && is_big5(end[0], end[1])) char_width = 2; else char_width = 1; end += char_width; } xpos += char_width; if (xpos <= term_width) { if (unichar_isprint(chr)) { if (view->utf8) term_add_unichar(view->window, chr); else for (; text < end; text++) term_addch(view->window, *text); } else { /* low-ascii */ term_set_color(view->window, ATTR_RESET|ATTR_REVERSE); term_addch(view->window, (chr & 127)+'A'-1); term_set_color2(view->window, color, fg24, bg24); } } text = end; } if (need_clrtoeol && xpos < term_width) { term_set_color(view->window, ATTR_RESET); term_clrtoeol(view->window); } return drawcount; }
static astr do_minibuf_read (const char *prompt, const char *value, size_t pos, Completion * cp, History * hp) { static int overwrite_mode = 0; int c, thistab, lasttab = -1; size_t prompt_len; char *s; astr as = astr_new_cstr (value), saved = NULL; prompt_len = strlen (prompt); if (pos == SIZE_MAX) pos = astr_len (as); for (;;) { switch (lasttab) { case COMPLETION_MATCHEDNONUNIQUE: s = " [Complete, but not unique]"; break; case COMPLETION_NOTMATCHED: s = " [No match]"; break; case COMPLETION_MATCHED: s = " [Sole completion]"; break; default: s = ""; } draw_minibuf_read (prompt, astr_cstr (as), prompt_len, s, pos); thistab = -1; switch (c = getkey ()) { case KBD_NOKEY: break; case KBD_CTRL | 'z': FUNCALL (suspend_emacs); break; case KBD_RET: term_move (term_height () - 1, 0); term_clrtoeol (); if (saved) astr_delete (saved); return as; case KBD_CANCEL: term_move (term_height () - 1, 0); term_clrtoeol (); if (saved) astr_delete (saved); astr_delete (as); return NULL; case KBD_CTRL | 'a': case KBD_HOME: pos = 0; break; case KBD_CTRL | 'e': case KBD_END: pos = astr_len (as); break; case KBD_CTRL | 'b': case KBD_LEFT: if (pos > 0) --pos; else ding (); break; case KBD_CTRL | 'f': case KBD_RIGHT: if (pos < astr_len (as)) ++pos; else ding (); break; case KBD_CTRL | 'k': /* FIXME: do kill-register save. */ if (pos < astr_len (as)) astr_truncate (as, pos); else ding (); break; case KBD_BS: if (pos > 0) astr_remove (as, --pos, 1); else ding (); break; case KBD_CTRL | 'd': case KBD_DEL: if (pos < astr_len (as)) astr_remove (as, pos, 1); else ding (); break; case KBD_INS: overwrite_mode = overwrite_mode ? 0 : 1; break; case KBD_META | 'v': case KBD_PGUP: if (cp == NULL) { ding (); break; } if (get_completion_flags (cp) & CFLAG_POPPEDUP) { completion_scroll_down (); thistab = lasttab; } break; case KBD_CTRL | 'v': case KBD_PGDN: if (cp == NULL) { ding (); break; } if (get_completion_flags (cp) & CFLAG_POPPEDUP) { completion_scroll_up (); thistab = lasttab; } break; case KBD_UP: case KBD_META | 'p': if (hp) { const char *elem = previous_history_element (hp); if (elem) { if (!saved) saved = astr_cpy (astr_new (), as); astr_cpy_cstr (as, elem); } } break; case KBD_DOWN: case KBD_META | 'n': if (hp) { const char *elem = next_history_element (hp); if (elem) astr_cpy_cstr (as, elem); else if (saved) { astr_cpy (as, saved); astr_delete (saved); saved = NULL; } } break; case KBD_TAB: got_tab: if (cp == NULL) { ding (); break; } if (lasttab != -1 && lasttab != COMPLETION_NOTMATCHED && get_completion_flags (cp) & CFLAG_POPPEDUP) { completion_scroll_up (); thistab = lasttab; } else { astr bs = astr_new (); astr_cpy (bs, as); thistab = completion_try (cp, bs, true); astr_delete (bs); switch (thistab) { case COMPLETION_MATCHED: case COMPLETION_MATCHEDNONUNIQUE: case COMPLETION_NONUNIQUE: { bs = astr_new (); if (get_completion_flags (cp) & CFLAG_FILENAME) astr_cat (bs, get_completion_path (cp)); astr_ncat_cstr (bs, get_completion_match (cp), get_completion_matchsize (cp)); if (strncmp (astr_cstr (as), astr_cstr (bs), astr_len (bs)) != 0) thistab = -1; astr_delete (as); as = bs; pos = astr_len (as); break; } case COMPLETION_NOTMATCHED: ding (); } } break; case ' ': if (cp != NULL) goto got_tab; /* FALLTHROUGH */ default: if (c > 255 || !isprint (c)) { ding (); break; } astr_insert_char (as, pos++, c); if (overwrite_mode && pos != astr_len (as)) astr_remove (as, pos, 1); } lasttab = thistab; } }