void tty_erase_screen (void) { #ifdef _WIN32 CONSOLE_SCREEN_BUFFER_INFO info; if (!GetConsoleScreenBufferInfo (tty_stdout, &info)) { printf ("tty_erase_screen: can't get Console buffer info!\r\n"); return; } if (info.srWindow.Top + 25 > info.dwSize.Y) tty_start_y = info.dwSize.Y - 25; else tty_start_y = info.srWindow.Top; tty_start_x = 0; tty_max_x = 79; tty_max_y = info.srWindow.Bottom; #if 0 printf ("Cursor: X=%u, Y=%u\r\n", info.dwCursorPosition.X, info.dwCursorPosition.Y); printf ("Max. window size: Width=%u, Height=%u\r\n", info.dwMaximumWindowSize.X, info.dwMaximumWindowSize.Y); printf ("Size: Width=%u, Height=%u\r\n", info.dwSize.X, info.dwSize.Y); printf ("Window: Bottom=%u, Left=%u, Right=%u, Top=%u\r\n", info.srWindow.Bottom, info.srWindow.Left, info.srWindow.Right, info.srWindow.Top); printf ("Attributes: 0x%04x\r\n", info.wAttributes); #endif setregion (tty_start_x, tty_start_y, ' ', tty_attribs, tty_max_x - tty_start_x + 1, tty_max_y - tty_start_y + 1); setxy (tty_start_x, tty_start_y); #else printf ("\x1b[2J"); tty_gotoxy (1, 1); fflush (stdout); #endif }
void screensaver() { c[1] = 0; while(1) { for (j=0;j<10;j++) { for (i=1;i<25;i++) { disp[j][i] = disp[j][i-1]; } } for (j=0;j<10;j++) { i = uniform(3)+1; switch (i) { case 1: disp[j][0] = uniform(2)+48; break; case 2: disp[j][0] = ' '; break; case 3: disp[j][0] = ' '; break; } } for (i=0;i<25;i++) { for (j=0;j<10;j++) { tty_gotoxy(scr_handle,(j+1)*(6+uniform(4)),i); c[0] = disp[j][i] + uniform(1); tty_print(scr_handle,c); } //delay(2); } delay(3); } delay(1); }
static void tty_emulate(ShellState *s, int c) { int i, offset, offset1, offset2, n; char buf1[10]; #define ESC2(c1,c2) (((c1)<<8)|((unsigned char)c2)) /* some bytes are state independent */ switch (c) { case 0x18: case 0x1A: s->state = TTY_STATE_NORM; return; case 0x1B: s->state = TTY_STATE_ESC; return; #if 0 case 0x9B: goto csi_entry; #endif } switch (s->state) { case TTY_STATE_NORM: switch (c) { /* BEL Bell (Ctrl-G) */ /* FF Form Feed or New Page (NP) (Ctrl-L) same as LF */ /* TAB Horizontal Tab (HT) (Ctrl-I) */ /* VT Vertical Tab (Ctrl-K) same as LF */ case 8: /* ^H BS = backspace */ { int c1; c1 = eb_prevc(s->b, s->cur_offset, &offset); if (c1 != '\n') s->cur_offset = offset; } break; case 10: /* ^J NL = line feed */ /* go to next line */ /* CG: should check if column should be kept */ offset = s->cur_offset; for (;;) { if (offset == s->b->total_size) { /* add a new line */ buf1[0] = '\n'; eb_insert(s->b, offset, buf1, 1); offset = s->b->total_size; break; } c = eb_nextc(s->b, offset, &offset); if (c == '\n') break; } s->cur_offset = offset; break; case 13: /* ^M CR = carriage return */ /* move to bol */ for (;;) { c = eb_prevc(s->b, s->cur_offset, &offset1); if (c == '\n') break; s->cur_offset = offset1; } break; case 14: /* ^N SO = shift out */ s->shifted = 1; break; case 15: /* ^O SI = shift in */ s->shifted = 0; break; default: if (c >= 32 || c == 9) { int c1, cur_len, len; /* CG: assuming ISO-8859-1 characters */ /* CG: horrible kludge for alternate charset support */ if (s->shifted && c >= 96 && c < 128) c += 32; /* write char (should factorize with do_char() code */ len = unicode_to_charset(buf1, c, s->b->charset); c1 = eb_nextc(s->b, s->cur_offset, &offset); /* XXX: handle tab case */ if (c1 == '\n') { /* insert */ eb_insert(s->b, s->cur_offset, buf1, len); } else { cur_len = offset - s->cur_offset; if (cur_len == len) { eb_write(s->b, s->cur_offset, buf1, len); } else { eb_delete(s->b, s->cur_offset, cur_len); eb_insert(s->b, s->cur_offset, buf1, len); } } s->cur_offset += len; } break; } break; case TTY_STATE_ESC: if (c == '[') { for (i = 0; i < MAX_ESC_PARAMS; i++) { s->esc_params[i] = 0; s->has_params[i] = 0; } s->nb_esc_params = 0; s->esc1 = 0; s->state = TTY_STATE_CSI; } else { /* CG: should deal with other sequences: * ansi: hts=\EH, s0ds=\E(B, s1ds=\E)B, s2ds=\E*B, s3ds=\E+B, * linux: hts=\EH, rc=\E8, ri=\EM, rs1=\Ec\E]R, sc=\E7, * vt100: enacs=\E(B\E)0, hts=\EH, rc=\E8, ri=\EM$<5>, * rmkx=\E[?1l\E>, * rs2=\E>\E[?3l\E[?4l\E[?5l\E[?7h\E[?8h, sc=\E7, * smkx=\E[?1h\E=, * xterm: enacs=\E(B\E)0, hts=\EH, is2=\E[!p\E[?3;4l\E[4l\E>, * rc=\E8, ri=\EM, rmkx=\E[?1l\E>, rs1=\Ec, * rs2=\E[!p\E[?3;4l\E[4l\E>, sc=\E7, smkx=\E[?1h\E=, */ switch (c) { case '(': case ')': case '*': case '+': case ']': s->esc1 = c; s->state = TTY_STATE_ESC2; break; case 'H': // hts case '7': // sc case '8': // rc case 'M': // ri case 'c': // rs1 case '>': // rmkx, is2, rs2 case '=': // smkx // XXX: do these default: s->state = TTY_STATE_NORM; break; } } break; case TTY_STATE_ESC2: s->state = TTY_STATE_NORM; switch (ESC2(s->esc1, c)) { case ESC2('(','B'): case ESC2(')','B'): case ESC2('(','0'): case ESC2(')','0'): case ESC2('*','B'): case ESC2('+','B'): case ESC2(']','R'): /* XXX: ??? */ break; } break; case TTY_STATE_CSI: if (c == '?') { s->esc1 = c; break; } if (c >= '0' && c <= '9') { if (s->nb_esc_params < MAX_ESC_PARAMS) { s->esc_params[s->nb_esc_params] = s->esc_params[s->nb_esc_params] * 10 + c - '0'; s->has_params[s->nb_esc_params] = 1; } } else { s->nb_esc_params++; if (c == ';') break; s->state = TTY_STATE_NORM; switch (ESC2(s->esc1,c)) { case ESC2('?','h'): /* set terminal mode */ /* 1047, 1048 -> cup mode: * xterm 1049 private mode, * should grab all keys while active! */ if (s->esc_params[0] == 1047 || s->esc_params[0] == 1048 || s->esc_params[0] == 1049) { s->grab_keys = 1; qe_grab_keys(shell_key, s); /* Should also clear screen */ } break; case ESC2('?','l'): /* reset terminal mode */ if (s->esc_params[0] == 1047 || s->esc_params[0] == 1048 || s->esc_params[0] == 1049) { qe_ungrab_keys(); s->grab_keys = 0; } break; case 'A': /* move relative up */ tty_gotoxy(s, 0, -(s->esc_params[0] + 1 - s->has_params[0]), 1); break; case 'B': /* move relative down */ tty_gotoxy(s, 0, (s->esc_params[0] + 1 - s->has_params[0]), 1); break; case 'C': /* move relative forward */ tty_gotoxy(s, (s->esc_params[0] + 1 - s->has_params[0]), 0, 1); break; case 'D': /* move relative backward */ tty_gotoxy(s, -(s->esc_params[0] + 1 - s->has_params[0]), 0, 1); break; case 'H': /* goto xy */ tty_gotoxy(s, s->esc_params[1] - s->has_params[1], s->esc_params[0] - s->has_params[0], 0); break; case 'J': /* clear to end of screen */ case 'L': /* insert lines */ case 'M': /* delete lines */ case 'S': /* scroll forward P lines */ case 'T': /* scroll back P lines */ case 'X': /* erase P characters */ break; case 'K': /* clear eol (parm=1 -> bol) */ offset1 = s->cur_offset; for (;;) { c = eb_nextc(s->b, offset1, &offset2); if (c == '\n') break; offset1 = offset2; } eb_delete(s->b, s->cur_offset, offset1 - s->cur_offset); break; case 'P': /* delete chars */ n = s->esc_params[0]; if (n <= 0) n = 1; offset1 = s->cur_offset; for (; n > 0; n--) { c = eb_nextc(s->b, offset1, &offset2); if (c == '\n') break; offset1 = offset2; } eb_delete(s->b, s->cur_offset, offset1 - s->cur_offset); break; case '@': /* insert chars */ n = s->esc_params[0]; if (n <= 0) n = 1; buf1[0] = ' '; for (; n > 0; n--) { eb_insert(s->b, s->cur_offset, buf1, 1); } break; case 'm': /* colors */ n = s->nb_esc_params; if (n == 0) n = 1; for (i = 0; i < n; i++) tty_csi_m(s, s->esc_params[i]); break; case 'n': if (s->esc_params[0] == 6) { /* XXX: send cursor position, just to be able to launch qemacs in qemacs (in 8859-1) ! */ char buf2[20]; snprintf(buf2, sizeof(buf2), "\033[%d;%dR", 1, 1); tty_write(s, buf2, -1); } break; default: break; } } break; } #undef ESC2 tty_update_cursor(s); }
/* * start an editing session: process the EDIT/VIEW message * if view == 1, text will be viewed, else edited */ void message_edit __P4 (char *,text, int,msglen, char,view, char,builtin) { char tmpname[BUFSIZE], command_str[BUFSIZE], buf[BUFSIZE]; char *errdesc = "#warning: protocol error (message_edit, no %s)\n"; int tmpfd, i, childpid; unsigned int key; editsess *s; char *editor, *descr; char *args[4]; int waitforeditor; status(1); args[0] = "/bin/sh"; args[1] = "-c"; args[2] = command_str; args[3] = 0; if (view) { key = (unsigned int)-1; i = 0; } else { if (text[0] != 'M') { tty_printf(errdesc, "M"); free(text); return; } for (i = 1; i < msglen && isdigit(text[i]); i++) ; if (text[i++] != '\n' || i >= msglen) { tty_printf(errdesc, "\\n"); free(text); return; } key = strtoul(text + 1, NULL, 10); } descr = text + i; while (i < msglen && text[i] != '\n') i++; if (i >= msglen) { tty_printf(errdesc, "desc"); free(text); return; } text[i++] = '\0'; sprintf(tmpname, "/tmp/powwow.%u.%d%d", key, getpid(), abs(rand()) >> 8); if ((tmpfd = open(tmpname, O_WRONLY | O_CREAT, 0600)) < 0) { errmsg("create temp edit file"); free(text); return; } if (write(tmpfd, text + i, msglen - i) < msglen - i) { errmsg("write to temp edit file"); free(text); close(tmpfd); return; } close(tmpfd); s = (editsess*)malloc(sizeof(editsess)); if (!s) { errmsg("malloc"); return; } s->ctime = time((time_t*)NULL); s->oldsize = msglen - i; s->key = key; s->fd = (view || builtin) ? -1 : tcp_fd; /* MUME doesn't expect a reply. */ s->cancel = 0; s->descr = my_strdup(descr); s->file = my_strdup(tmpname); free(text); /* send a edit_start message (if wanted) */ if ((!edit_sess) && (*edit_start)) { error = 0; parse_instruction(edit_start, 0, 0, 1); history_done = 0; } if (view) { if (!(editor = getenv("POWWOWPAGER")) && !(editor = getenv("PAGER"))) editor = "more"; } else { if (!(editor = getenv("POWWOWEDITOR")) && !(editor = getenv("EDITOR"))) editor = "emacs"; } if (editor[0] == '&') { waitforeditor = 0; editor++; } else waitforeditor = 1; if (waitforeditor) { tty_quit(); /* ignore SIGINT since interrupting the child would interrupt us too, if we are in the same tty group */ sig_permanent(SIGINT, SIG_IGN); sig_permanent(SIGCHLD, SIG_DFL); } switch(childpid = fork()) { /* let's get schizophrenic */ case 0: sprintf(command_str, "%s %s", editor, s->file); sprintf(buf, "TITLE=%s", s->descr); putenv(buf); /* setenv("TITLE", s->descr, 1);*/ execvp((char *)args[0], (char **)args); syserr("execve"); break; case -1: errmsg("fork"); free(s->descr); free(s->file); free(s); return; } s->pid = childpid; if (waitforeditor) { while ((i = waitpid(childpid, (int*)NULL, 0)) == -1 && errno == EINTR) ; signal_start(); /* reset SIGINT and SIGCHLD handlers */ tty_start(); if (s->fd != -1) { tty_gotoxy(0, lines - 1); tty_putc('\n'); } if (i == -1) errmsg("waitpid"); else finish_edit(s); free(s->descr); free(s->file); if (i != -1 && !edit_sess && *edit_end) { error = 0; parse_instruction(edit_end, 0, 0, 1); history_done = 0; } free(s); } else { s->next = edit_sess; edit_sess = s; } }
static void tty_emulate(ShellState *s, int c) { int i, offset, offset1, offset2, n; unsigned char buf1[10]; switch(s->state) { case TTY_STATE_NORM: switch(c) { case 8: { int c1; c1 = eb_prevc(s->b, s->cur_offset, &offset); if (c1 != '\n') s->cur_offset = offset; } break; case 10: /* go to next line */ offset = s->cur_offset; for(;;) { if (offset == s->b->total_size) { /* add a new line */ buf1[0] = '\n'; eb_insert(s->b, offset, buf1, 1); offset = s->b->total_size; break; } c = eb_nextc(s->b, offset, &offset); if (c == '\n') break; } s->cur_offset = offset; break; case 13: /* move to bol */ for(;;) { c = eb_prevc(s->b, s->cur_offset, &offset1); if (c == '\n') break; s->cur_offset = offset1; } break; case 27: s->state = TTY_STATE_ESC; break; default: if (c >= 32 || c == 9) { int c1, cur_len, len; /* write char (should factorize with do_char() code */ len = unicode_to_charset(buf1, c, s->b->charset); c1 = eb_nextc(s->b, s->cur_offset, &offset); /* XXX: handle tab case */ if (c1 == '\n') { /* insert */ eb_insert(s->b, s->cur_offset, buf1, len); } else { cur_len = offset - s->cur_offset; if (cur_len == len) { eb_write(s->b, s->cur_offset, buf1, len); } else { eb_delete(s->b, s->cur_offset, cur_len); eb_insert(s->b, s->cur_offset, buf1, len); } } s->cur_offset += len; } break; } break; case TTY_STATE_ESC: if (c == '[') { for(i=0;i<MAX_ESC_PARAMS;i++) s->esc_params[i] = 0; s->nb_esc_params = 0; s->state = TTY_STATE_CSI; } else { s->state = TTY_STATE_NORM; } break; case TTY_STATE_CSI: if (c >= '0' && c <= '9') { if (s->nb_esc_params < MAX_ESC_PARAMS) { s->esc_params[s->nb_esc_params] = s->esc_params[s->nb_esc_params] * 10 + c - '0'; } } else { s->nb_esc_params++; if (c == ';') break; s->state = TTY_STATE_NORM; switch(c) { case 'H': /* goto xy */ { int x, y; y = s->esc_params[0] - 1; x = s->esc_params[1] - 1; if (y < 0) y = 0; else if (y >= TTY_YSIZE) y = TTY_YSIZE - 1; if (x < 0) x = 0; tty_gotoxy(s, x, y); } break; case 'K': /* clear to eol */ offset1 = s->cur_offset; for(;;) { c = eb_nextc(s->b, offset1, &offset2); if (c == '\n') break; offset1 = offset2; } eb_delete(s->b, s->cur_offset, offset1 - s->cur_offset); break; case 'P': /* delete chars */ n = s->esc_params[0]; if (n <= 0) n = 1; offset1 = s->cur_offset; for(;n > 0;n--) { c = eb_nextc(s->b, offset1, &offset2); if (c == '\n') break; offset1 = offset2; } eb_delete(s->b, s->cur_offset, offset1 - s->cur_offset); break; case '@': /* insert chars */ n = s->esc_params[0]; if (n <= 0) n = 1; buf1[0] = ' '; for(;n > 0;n--) { eb_insert(s->b, s->cur_offset, buf1, 1); } break; case 'm': /* colors */ n = s->nb_esc_params; if (n == 0) n = 1; for(i=0;i<n;i++) tty_csi_m(s, s->esc_params[i]); break; case 'n': if (s->esc_params[0] == 6) { /* XXX: send cursor position, just to be able to launch qemacs in qemacs ! */ char buf2[20]; snprintf(buf2, sizeof(buf2), "\033[%d;%dR", 1, 1); tty_write(s, buf2, -1); } break; default: break; } } break; } tty_update_cursor(s); }