Esempio n. 1
0
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--;
		}
	}
}
Esempio n. 2
0
/*
 * 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();
}
Esempio n. 3
0
/*
 * 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 ();
}
Esempio n. 4
0
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++;
			}
		}
	}
}
Esempio n. 5
0
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;
}
Esempio n. 6
0
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;
    }
}
Esempio n. 7
0
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;
}
Esempio n. 8
0
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);
}
Esempio n. 9
0
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);
}
Esempio n. 10
0
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++;
		}
	}
}
Esempio n. 11
0
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);
  }
}
Esempio n. 12
0
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;
}
Esempio n. 13
0
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;
}
Esempio n. 14
0
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;
    }
}