📄 terminal.c
字号:
unsigned char A = ch >> 8 & 0x7f; \ if (s->mode == TERM_LINUX) { \ if (s->m11_hack) { \ if ((int)(ch >> 15) != mode) { \ if (!(mode = ch >> 15)) add_to_str(&a, &l, "\033[10m"); \ else add_to_str(&a, &l, "\033[11m"); \ } \ } \ if (s->restrict_852 && (ch >> 15) && c >= 176 && c < 224) { \ if (frame_restrict[c - 176]) c = frame_restrict[c - 176]; \ } \ } else if (s->mode == TERM_VT100) { \ if ((int)(ch >> 15) != mode) { \ if (!(mode = ch >> 15)) add_to_str(&a, &l, "\017"); \ else add_to_str(&a, &l, "\016"); \ } \ if (mode && c >= 176 && c < 224) c = frame_vt100[c - 176]; \ } else if (s->mode == TERM_KOI8 && (ch >> 15) && c >= 176 && c < 224) { c = frame_koi[c - 176];\ } else if (s->mode == TERM_FREEBSD && (ch >> 15) && c >= 176 && c < 224) { c = frame_freebsd[c - 176];\ } else if (s->mode == TERM_DUMB && (ch >> 15) && c >= 176 && c < 224) c = frame_dumb[c - 176];\ if (!(A & 0100) && (A >> 3) == (A & 7)) A = (A & 070) | 7 * !(A & 020); \ if (A != attrib) { \ attrib = A; \ add_to_str(&a, &l, "\033[0"); \ if (s->col) { \ unsigned char m[4]; \ m[0] = ';'; m[1] = '3'; m[3] = 0; \ m[2] = (attrib & 7) + '0'; \ add_to_str(&a, &l, m); \ m[1] = '4'; \ m[2] = ((attrib >> 3) & 7) + '0'; \ add_to_str(&a, &l, m); \ } else if (getcompcode(attrib & 7) < getcompcode(attrib >> 3 & 7)) \ add_to_str(&a, &l, ";7"); \ if (attrib & 0100) add_to_str(&a, &l, ";1"); \ add_to_str(&a, &l, "m"); \ } \ if (c >= ' ' && c != 127/* && c != 155*/) add_chr_to_str(&a, &l, c); \ else if (!c || c == 1) add_chr_to_str(&a, &l, ' '); \ else add_chr_to_str(&a, &l, '.'); \ cx++; \} \void redraw_all_terminals(void){ struct terminal *term; foreach(term, terminals) redraw_screen(term);}void redraw_screen(struct terminal *term){ int x, y, p = 0; int cx = term->lcx, cy = term->lcy; unsigned char *a; int attrib = -1; int mode = -1; int l = 0; struct term_spec *s; NO_GFX; if (!term->dirty || (term->master && is_blocked())) return; a = init_str(); s = term->spec; for (y = 0; y < term->y; y++) for (x = 0; x < term->x; x++, p++) { if (y == term->y - 1 && x == term->x - 1) break; if (term->screen[p] == term->last_screen[p]) continue; if ((term->screen[p] & 0x3800) == (term->last_screen[p] & 0x3800) && ((term->screen[p] & 0xff) == 0 || (term->screen[p] & 0xff) == 1 || (term->screen[p] & 0xff) == ' ') && ((term->last_screen[p] & 0xff) == 0 || (term->last_screen[p] & 0xff) == 1 || (term->last_screen[p] & 0xff) == ' ') && (x != term->cx || y != term->cy)) continue; term->last_screen[p] = term->screen[p]; if (cx == x && cy == y) goto pc;/*PRINT_CHAR(p)*/ else if (cy == y && x - cx < 10 && x - cx > 0) { int i; for (i = x - cx; i >= 0; i--) PRINT_CHAR(p - i); } else { add_to_str(&a, &l, "\033["); add_num_to_str(&a, &l, y + 1); add_to_str(&a, &l, ";"); add_num_to_str(&a, &l, x + 1); add_to_str(&a, &l, "H"); cx = x; cy = y; pc: PRINT_CHAR(p); } } if (l) { if (s->col) add_to_str(&a, &l, "\033[37;40m"); add_to_str(&a, &l, "\033[0m"); if (s->mode == TERM_LINUX && s->m11_hack) add_to_str(&a, &l, "\033[10m"); if (s->mode == TERM_VT100) add_to_str(&a, &l, "\017"); } term->lcx = cx; term->lcy = cy; if (term->cx != term->lcx || term->cy != term->lcy) { term->lcx = term->cx; term->lcy = term->cy; add_to_str(&a, &l, "\033["); add_num_to_str(&a, &l, term->cy + 1); add_to_str(&a, &l, ";"); add_num_to_str(&a, &l, term->cx + 1); add_to_str(&a, &l, "H"); } if (l && term->master) want_draw(); hard_write(term->fdout, a, l); if (l && term->master) done_draw(); mem_free(a); term->dirty = 0;}void destroy_terminal(struct terminal *term){ while ((term->windows.next) != &term->windows) delete_window(term->windows.next); /*if (term->cwd) mem_free(term->cwd);*/ del_from_list(term); if (term->blocked != -1) { close(term->blocked); set_handlers(term->blocked, NULL, NULL, NULL, NULL); } if (term->title) mem_free(term->title); if (!F) { mem_free(term->screen); mem_free(term->last_screen); set_handlers(term->fdin, NULL, NULL, NULL, NULL); mem_free(term->input_queue); close(term->fdin); if (term->fdout != 1) { if (term->fdout != term->fdin) close(term->fdout); } else { unhandle_terminal_signals(term); free_all_itrms();#ifndef NO_FORK_ON_EXIT if (!list_empty(terminals)) { if (fork() > 0) _exit(0); }#endif }#ifdef G } else { drv->shutdown_device(term->dev);#endif } mem_free(term); check_if_no_terminal();}void destroy_all_terminals(void){ struct terminal *term; while ((void *)(term = terminals.next) != &terminals) destroy_terminal(term);}void check_if_no_terminal(void){ if (!list_empty(terminals)) return; terminate_loop = 1;}void set_char(struct terminal *t, int x, int y, unsigned c){ NO_GFX; t->dirty = 1; if (x >= 0 && x < t->x && y >= 0 && y < t->y) t->screen[x + t->x * y] = c;}unsigned get_char(struct terminal *t, int x, int y){ NO_GFX; if (x >= t->x) x = t->x - 1; if (x < 0) x = 0; if (y >= t->y) y = t->y - 1; if (y < 0) y = 0; return t->screen[x + t->x * y];}void set_color(struct terminal *t, int x, int y, unsigned c){ NO_GFX; t->dirty = 1; if (x >= 0 && x < t->x && y >= 0 && y < t->y) t->screen[x + t->x * y] = (t->screen[x + t->x * y] & 0x80ff) | (c & ~0x80ff);}void set_only_char(struct terminal *t, int x, int y, unsigned c){ NO_GFX; t->dirty = 1; if (x >= 0 && x < t->x && y >= 0 && y < t->y) t->screen[x + t->x * y] = (t->screen[x + t->x * y] & ~0x80ff) | (c & 0x80ff);}void set_line(struct terminal *t, int x, int y, int l, chr *line){ int i; NO_GFX; t->dirty = 1; if (y < 0 || y >= t->y) return; for (i = x >= 0 ? 0 : -x; i < (x+l <= t->x ? l : t->x-x); i++) t->screen[x+i + t->x * y] = line[i];}void set_line_color(struct terminal *t, int x, int y, int l, unsigned c){ int i; NO_GFX; t->dirty = 1; if (y < 0 || y >= t->y) return; for (i = x >= 0 ? 0 : -x; i < (x+l <= t->x ? l : t->x-x); i++) t->screen[x+i + t->x * y] = (t->screen[x+i + t->x * y] & 0x80ff) | (c & ~0x80ff);}void fill_area(struct terminal *t, int x, int y, int xw, int yw, unsigned c){ int i,j; NO_GFX; t->dirty = 1; for (j = y >= 0 ? 0 : -y; j < yw && y+j < t->y; j++) for (i = x >= 0 ? 0 : -x; i < xw && x+i < t->x; i++) t->screen[x+i + t->x*(y+j)] = c;}int p1[] = { 218, 191, 192, 217, 179, 196 };int p2[] = { 201, 187, 200, 188, 186, 205 };void draw_frame(struct terminal *t, int x, int y, int xw, int yw, unsigned c, int w){ int *p = w > 1 ? p2 : p1; NO_GFX; c |= ATTR_FRAME; set_char(t, x, y, c+p[0]); set_char(t, x+xw-1, y, c+p[1]); set_char(t, x, y+yw-1, c+p[2]); set_char(t, x+xw-1, y+yw-1, c+p[3]); fill_area(t, x, y+1, 1, yw-2, c+p[4]); fill_area(t, x+xw-1, y+1, 1, yw-2, c+p[4]); fill_area(t, x+1, y, xw-2, 1, c+p[5]); fill_area(t, x+1, y+yw-1, xw-2, 1, c+p[5]);}void print_text(struct terminal *t, int x, int y, int l, unsigned char *text, unsigned c){ NO_GFX; for (; l-- && *text; text++, x++) set_char(t, x, y, *text + c);}void set_cursor(struct terminal *term, int x, int y, int altx, int alty){ NO_GFX; term->dirty = 1; if (term->spec->block_cursor && !term->spec->braille) x = altx, y = alty; if (x >= term->x) x = term->x - 1; if (y >= term->y) y = term->y - 1; if (x < 0) x = 0; if (y < 0) y = 0; term->cx = x; term->cy = y;}void exec_thread(unsigned char *path, int p){#if defined(HAVE_SETPGID) && !defined(BEOS) && !defined(HAVE_BEGINTHREAD) if (path[0] == 2) setpgid(0, 0);#endif exe(path + 1, path[0]); /*close(p);*/ if (path[1 + strlen(path + 1) + 1]) unlink(path + 1 + strlen(path + 1) + 1);}void close_handle(void *p){ long h = (my_intptr_t)p; close(h); set_handlers(h, NULL, NULL, NULL, NULL);}void unblock_terminal(struct terminal *term){ close_handle((void *)(my_intptr_t)term->blocked); term->blocked = -1; if (!F) { set_handlers(term->fdin, (void (*)(void *))in_term, NULL, (void (*)(void *))destroy_terminal, term); unblock_itrm(term->fdin); redraw_terminal_cls(term);#ifdef G } else { drv->unblock(term->dev);#endif }}void exec_on_terminal(struct terminal *term, unsigned char *path, unsigned char *delete, int fg){ if (path && !*path) return; if (!path) path="";#ifdef NO_FG_EXEC fg = 0;#endif if (term->master) { if (!*path) { if (!F) dispatch_special(delete); } else { long blockh; unsigned char *param; if ((!F ? is_blocked() : term->blocked != -1) && fg) { unlink(delete); return; } param = mem_alloc(strlen(path) + strlen(delete) + 3); param[0] = fg; strcpy(param + 1, path); strcpy(param + 1 + strlen(path) + 1, delete); if (fg == 1) { if (!F) block_itrm(term->fdin);#ifdef G else if (drv->block(term->dev)) { mem_free(param); unlink(delete); return; }#endif } if ((blockh = start_thread((void (*)(void *, int))exec_thread, param, strlen(path) + strlen(delete) + 3)) == -1) { if (fg == 1) { if (!F) unblock_itrm(term->fdin);#ifdef G else drv->unblock(term->dev);#endif } mem_free(param); return; } mem_free(param); if (fg == 1) { term->blocked = blockh; set_handlers(blockh, (void (*)(void *))unblock_terminal, NULL, (void (*)(void *))unblock_terminal, term); if (!F) set_handlers(term->fdin, NULL, NULL, (void (*)(void *))destroy_terminal, term); /*block_itrm(term->fdin);*/ } else { set_handlers(blockh, close_handle, NULL, close_handle, (void *)blockh); } } } else { unsigned char *data; data = mem_alloc(strlen(path) + strlen(delete) + 4); data[0] = 0; data[1] = fg; strcpy(data + 2, path); strcpy(data + 3 + strlen(path), delete); hard_write(term->fdout, data, strlen(path) + strlen(delete) + 4); mem_free(data); /*char x = 0; hard_write(term->fdout, &x, 1); x = fg; hard_write(term->fdout, &x, 1); hard_write(term->fdout, path, strlen(path) + 1); hard_write(term->fdout, delete, strlen(delete) + 1);*/ }}void do_terminal_function(struct terminal *term, unsigned char code, unsigned char *data){ unsigned char *x_data; NO_GFX; x_data = mem_alloc(strlen(data) + 2); x_data[0] = code; strcpy(x_data + 1, data); exec_on_terminal(term, NULL, x_data, 0); mem_free(x_data);}void set_terminal_title(struct terminal *term, unsigned char *title){ int i; for (i = 0; i < 10000; i++) if (!title[i]) goto s; title[10000] = 0; s: if (strchr(title, 1)) { unsigned char *a, *b; for (a = title, b = title; *a; a++) if (*a != 1) *b++ = *a; *b = 0; } if (term->title && !strcmp(title, term->title)) goto ret; if (term->title) mem_free(term->title); term->title = stracpy(title);#ifdef SET_WINDOW_TITLE_UTF_8 { struct conv_table *table; mem_free(title); table = get_translation_table(term->spec->charset, get_cp_index("utf-8")); title = convert_string(table, term->title, strlen(term->title), NULL); }#endif if (!F) do_terminal_function(term, TERM_FN_TITLE, title);#ifdef G else if (drv->set_title) drv->set_title(term->dev, title);#endif ret: mem_free(title);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -