Exemplo n.º 1
0
static void _print_string(const char *ptr, size_t width, bool utf8,
		bool left_adjust)
{
	if (!ptr)
		ptr = nullstr;

	size_t padding = 0;
	if (width) {
		size_t w = screen_display_width(ptr, utf8);
		if (w < width)
			padding = width - w;
	}

	if (padding && !left_adjust)
		tui_repeat_char(' ', padding);

	if (utf8) {
		screen_puts(ptr, 0);
	} else {
		convert(CONVERT_G2U, ptr, CONVERT_ALL, NULL, 0,
				screen_put_gbk_helper, NULL);
	}

	if (padding && left_adjust)
		tui_repeat_char(' ', padding);
}
Exemplo n.º 2
0
/**
 * 重绘屏幕
 */
void screen_redraw(void)
{
	if (!screen.buf)
		return;

	ansi_cmd(ANSI_CMD_CL);
	screen.tc_col = 0;
	screen.tc_line = 0;

	for (int i = 0; i < screen.lines; ++i) {
		screen_line_t *sl = get_screen_line(i);
		if (!sl->len)
			continue;

		move_terminal_cursor(0, i);
		screen_write_cached(sl->data, sl->len);

		screen.tc_col += sl->len;
		if (screen.tc_col >= screen.columns) {
			screen.tc_col = screen.columns - 1;
		}
		sl->modified = false;
		sl->data[sl->len] = '\0';
		sl->old_width = screen_display_width((char *) sl->data, true);
	}
	move_terminal_cursor(screen.cur_col, screen.cur_ln);
	screen.redraw = false;
	screen.scrollcnt = 0;
	terminal_flush();
}
Exemplo n.º 3
0
void screen_flush(void)
{
	if (!screen.buf) {
		terminal_flush();
		return;
	}

	if (!terminal_input_buffer_empty())
		return;
	if (screen.redraw || (abs(screen.scrollcnt) >= (screen.lines - 3))) {
		screen_redraw();
		return;
	}
	if (screen.scrollcnt < 0) {
		move_terminal_cursor(0, 0);
		while (screen.scrollcnt < 0) {
			ansi_cmd(ANSI_CMD_SR);
			screen.scrollcnt++;
		}
	}
	if (screen.scrollcnt > 0) {
		move_terminal_cursor(0, screen.lines - 1);
		while (screen.scrollcnt > 0) {
			terminal_putchar('\n');
			screen.scrollcnt--;
		}
	}
	for (int i = 0; i < screen.lines; i++) {
		screen_line_t *sl = get_screen_line(i);

		sl->data[sl->len] = '\0';
		int width = screen_display_width((char *) sl->data, true);

		if (sl->modified) {
			sl->modified = false;
			move_terminal_cursor(0, i);

			screen_write_cached(sl->data, sl->len);

			screen.tc_col = width;
			if (screen.tc_col >= screen.columns) {
				screen.tc_col -= screen.columns;
				screen.tc_line++;
				if (screen.tc_line >= screen.lines)
					screen.tc_line = screen.lines - 1;
			}
		}

		if (sl->old_width > width) {
			move_terminal_cursor(width, i);
			ansi_cmd(ANSI_CMD_CE);
		}
		sl->old_width = width;
	}
	move_terminal_cursor(screen.cur_col, screen.cur_ln);
	terminal_flush();
}
Exemplo n.º 4
0
Arquivo: tui.c Projeto: fbbs/fbbs
void tui_update_status_line(void)
{
	extern time_t login_start_time; //main.c

	char date[STRLEN];

	screen_move_clear(-1);

	if (!DEFINE(DEF_ENDLINE))
		return;

	fb_time_t now = fb_time();
	int cur_sec = now % 10;

	if (cur_sec < 5) {
		strlcpy(date, format_time(now, TIME_FORMAT_UTF8_ZH), sizeof(date));
	} else {
		if (resolve_boards() >= 0)
			convert_g2u(brdshm->date, date);
		else
			date[0] = '\0';
	}

	if (cur_sec >= 5 && is_birth(&currentuser)) {
		screen_printf("\033[0;1;33;44m[\033[36m                      "
				"啦啦~~生日快乐!记得要请客哟 :P"
				"                       \033[33m]\033[m");
	} else {
		int stay = (now - login_start_time) / 60;
		char stay_str[20];
		describe_stay(stay, stay_str, sizeof(stay_str));

		char notice[128];
		notice_string(notice, sizeof(notice));
		int notice_width = screen_display_width(notice, true);

		screen_printf("\033[1;44;33m[\033[36m%29s\033[33m]"
			"[\033[36m%5d\033[33m人\033[36m%3d\033[33m友]",
			date, session_count_online(),
			session_count_online_followed(!HAS_PERM(PERM_SEECLOAK)));
		// 剩下35列
		if (notice_width) {
			int space = 33 - notice_width;
			if (space > 0)
				tui_repeat_char(' ', space);
			screen_printf("[\033[%d;36m%s\033[m\033[1;33;44m]\033[m",
					_suppress_notice ? 1 : 5, notice);
		} else {
			int space = 27 - strlen(currentuser.userid);
			tui_repeat_char(' ', space);
			prints("[\033[36m%s\033[33m]%s\033[m", currentuser.userid,
					stay_str);
		}
	}
}
Exemplo n.º 5
0
Arquivo: tui.c Projeto: fbbs/fbbs
void tui_header_line(const char *menu, bool check_mail)
{
	extern int mailXX; //main.c
	char title[36];

	if (check_mail && chkmail())
		strlcpy(title, strstr(menu, "讨论区列表") ? "[您有信件,按 M 看新信]"
				: "[您有信件]", sizeof(title));
	else if (check_mail && mailXX == 1)
		strlcpy(title, "[信件过量,请整理信件!]", sizeof(title));
	else
		strlcpy(title, BBSNAME_UTF8, sizeof(title));

	bool show_board = true;
	int w1 = screen_display_width(menu, true),
		w2 = screen_display_width(title, true),
		w3 = screen_display_width(currboard, true) + 2;
	int spaces = 80 - w1 - w2 - w3;
	if (spaces < 0) {
		spaces = 80 - w1 - w2;
		show_board = false;
	}

	screen_move_clear(0);
	screen_printf("\033[1;33;44m%s", menu);
	if (spaces > 0)
		tui_repeat_char(' ', spaces / 2);
	if (streq(title, BBSNAME_UTF8))
		screen_printf("\033[37m%s", title);
	else if (title[0] == '[')
		screen_printf("\033[5;36m%s\033[0;1;44m", title);
	else
		screen_printf("\033[36m%s", title);
	if (spaces > 0)
		tui_repeat_char(' ', spaces - spaces / 2);
	if (show_board)
		screen_printf("\033[33m[%s]\033[m", currboard);
	tui_update_status_line();
	screen_move(1, 0);
}
Exemplo n.º 6
0
Arquivo: tui.c Projeto: fbbs/fbbs
static void notice_string(char *buf, size_t size)
{
	*buf = '\0';

	int replies, mentions;
	notice_count(&replies, &mentions);

	bool empty = !(replies || mentions);
	if (!empty) {
		char **dst = &buf;
		if (replies > 0) {
			char str[24];
			snprintf(str, sizeof(str), "%d篇回复", replies);
			strappend(dst, &size, str);
		}
		if (mentions > 0) {
			char str[24];
			snprintf(str, sizeof(str), "%d篇提及", mentions);
			strappend(dst, &size, str);
		}
		if (!_suppress_notice && screen_display_width(buf, true) <= 24)
			strappend(dst, &size, " 按^T查看");
	}
}
Exemplo n.º 7
0
Arquivo: tui.c Projeto: fbbs/fbbs
static int _tui_input(int line, int col, const char *prompt, char *buf,
		int len, int echo, int clear, bool utf8)
{
	extern int RMSG;
	extern int msg_num;

	if (clear)
		buf[0] = '\0';
	buf[len - 1] = '\0';

	int real_x = prompt ? screen_display_width(prompt, utf8) : 0;

	int cur, clen;
	cur = clen = strlen(buf);

	bool inited = screen_inited(), prompted = false;
	while (1) {
		if (inited || !prompted) {
			screen_move(line, col);
			clrtoeol();
			if (prompt) {
				if (utf8)
					screen_printf("%s", prompt);
				else
					prints("%s", prompt);
			}
			prompted = true;
		}
		if (inited) {
			if (echo)
				prints("%s", buf);
			else
				tui_repeat_char('*', clen);
			screen_move(line, real_x + cur);
		}

		if (RMSG)
			screen_flush();

		int ch = terminal_getchar();

		if (RMSG && msg_num == 0) {
			if (ch == Ctrl('Z') || ch == KEY_UP) {
				buf[0] = Ctrl('Z');
				clen = 1;
				break;
			}
			if (ch == Ctrl('A') || ch == KEY_DOWN) {
				buf[0] = Ctrl('A');
				clen = 1;
				break;
			}
		}

		if (ch == '\n' || ch == '\r')
			break;

		if (!inited) {
			if (ch == '\x7f' || ch == Ctrl('H')) {
				int dec = remove_character(buf, &cur, clen, true);
				if (dec) {
					clen -= dec;
					screen_puts("\x8 \x8", 3);
				}
			} else if (isprint2(ch) && clen < len - 1) {
				buf[cur] = ch;
				buf[++cur] = '\0';
				++clen;
				screen_putc(echo ? ch : '*');
			}
			continue;
		}

		if (ch == '\x7f' || ch == Ctrl('H')) {
			clen -= remove_character(buf, &cur, clen, true);
		} else if (ch == KEY_DEL) {
			clen -= remove_character(buf, &cur, clen, false);
		} else if (ch == KEY_LEFT) {
			if (cur > 0)
				--cur;
		} else if (ch == KEY_RIGHT) {
			if (cur < clen)
				++cur;
		} else if (ch == Ctrl('E') || ch == KEY_END) {
			cur = clen;
		} else if (ch == Ctrl('A') || ch == KEY_HOME) {
			cur = 0;
		} else if (isprint2(ch) && clen < len - 1) {
			if (buf[cur] != '\0')
				memmove(buf + cur + 1, buf + cur, clen - cur);
			buf[cur++] = ch;
			buf[++clen] = '\0';
		}
	}

	screen_putc('\n');
	screen_flush();
	return clen;
}