void prints(int wno, char* str) { while((*str) != 0) tty_putc(wno, *(str++)); }
/* Move cursor to absolute position. */ void tty_cursor(struct tty *tty, u_int cx, u_int cy) { struct tty_term *term = tty->term; u_int thisx, thisy; int change; if (cx > tty->sx - 1) cx = tty->sx - 1; thisx = tty->cx; thisy = tty->cy; /* No change. */ if (cx == thisx && cy == thisy) return; /* Very end of the line, just use absolute movement. */ if (thisx > tty->sx - 1) goto absolute; /* Move to home position (0, 0). */ if (cx == 0 && cy == 0 && tty_term_has(term, TTYC_HOME)) { tty_putcode(tty, TTYC_HOME); goto out; } /* Zero on the next line. */ if (cx == 0 && cy == thisy + 1 && thisy != tty->rlower) { tty_putc(tty, '\r'); tty_putc(tty, '\n'); goto out; } /* Moving column or row. */ if (cy == thisy) { /* * Moving column only, row staying the same. */ /* To left edge. */ if (cx == 0) { tty_putc(tty, '\r'); goto out; } /* One to the left. */ if (cx == thisx - 1 && tty_term_has(term, TTYC_CUB1)) { tty_putcode(tty, TTYC_CUB1); goto out; } /* One to the right. */ if (cx == thisx + 1 && tty_term_has(term, TTYC_CUF1)) { tty_putcode(tty, TTYC_CUF1); goto out; } /* Calculate difference. */ change = thisx - cx; /* +ve left, -ve right */ /* * Use HPA if change is larger than absolute, otherwise move * the cursor with CUB/CUF. */ if ((u_int) abs(change) > cx && tty_term_has(term, TTYC_HPA)) { tty_putcode1(tty, TTYC_HPA, cx); goto out; } else if (change > 0 && tty_term_has(term, TTYC_CUB)) { tty_putcode1(tty, TTYC_CUB, change); goto out; } else if (change < 0 && tty_term_has(term, TTYC_CUF)) { tty_putcode1(tty, TTYC_CUF, -change); goto out; } } else if (cx == thisx) { /* * Moving row only, column staying the same. */ /* One above. */ if (thisy != tty->rupper && cy == thisy - 1 && tty_term_has(term, TTYC_CUU1)) { tty_putcode(tty, TTYC_CUU1); goto out; } /* One below. */ if (thisy != tty->rlower && cy == thisy + 1 && tty_term_has(term, TTYC_CUD1)) { tty_putcode(tty, TTYC_CUD1); goto out; } /* Calculate difference. */ change = thisy - cy; /* +ve up, -ve down */ /* * Try to use VPA if change is larger than absolute or if this * change would cross the scroll region, otherwise use CUU/CUD. */ if ((u_int) abs(change) > cy || (change < 0 && cy - change > tty->rlower) || (change > 0 && cy - change < tty->rupper)) { if (tty_term_has(term, TTYC_VPA)) { tty_putcode1(tty, TTYC_VPA, cy); goto out; } } else if (change > 0 && tty_term_has(term, TTYC_CUU)) { tty_putcode1(tty, TTYC_CUU, change); goto out; } else if (change < 0 && tty_term_has(term, TTYC_CUD)) { tty_putcode1(tty, TTYC_CUD, -change); goto out; } } absolute: /* Absolute movement. */ tty_putcode2(tty, TTYC_CUP, cy, cx); out: tty->cx = cx; tty->cy = cy; }
/* This routine processes a character in response to an interrupt. It * adds the character to the tty input queue, echoing and processing * backspace and carriage return. If the queue contains a full line, * it wakes up anything waiting on it. If it is totally full, it beeps * at the user. * UZI180 - This routine is called from the raw Hardware read routine, * either interrupt or polled, to process the input character. HFB */ int tty_inproc(uint8_t minor, unsigned char c) { unsigned char oc; int canon; uint8_t wr; struct tty *t = &ttydata[minor]; struct s_queue *q = &ttyinq[minor]; canon = t->termios.c_lflag & ICANON; if (t->termios.c_iflag & ISTRIP) c &= 0x7f; /* Strip off parity */ if (canon && !c) return 1; /* Simply quit if Null character */ #ifdef CONFIG_IDUMP if (c == 0x1a) /* ^Z */ idump(); /* (For debugging) */ #endif #ifdef CONFIG_MONITOR if (c == 0x01) /* ^A */ trap_monitor(); #endif if (c == '\r' && (t->termios.c_iflag & ICRNL)) c = '\n'; if (c == '\n' && (t->termios.c_iflag & INLCR)) c = '\r'; if (t->termios.c_lflag & ISIG) { if (c == t->termios.c_cc[VINTR]) { /* ^C */ wr = SIGINT; goto sigout; } else if (c == t->termios.c_cc[VQUIT]) { /* ^\ */ wr = SIGQUIT; sigout: sgrpsig(t->pgrp, wr); clrq(q); t->flag &= ~(TTYF_STOP | TTYF_DISCARD); return 1; } } if (c == t->termios.c_cc[VDISCARD]) { /* ^O */ t->flag ^= TTYF_DISCARD; return 1; } if (t->termios.c_iflag & IXON) { if (c == t->termios.c_cc[VSTOP]) { /* ^S */ t->flag |= TTYF_STOP; return 1; } if (c == t->termios.c_cc[VSTART]) { /* ^Q */ t->flag &= ~TTYF_STOP; wakeup(&t->flag); return 1; } } if (canon) { if (c == t->termios.c_cc[VERASE]) { wr = ECHOE; goto eraseout; } else if (c == t->termios.c_cc[VKILL]) { wr = ECHOK; goto eraseout; } } /* All modes come here */ if (c == '\n') { if ((t->termios.c_oflag & (OPOST | ONLCR)) == (OPOST | ONLCR)) tty_echo(minor, '\r'); } wr = insq(q, c); if (wr) tty_echo(minor, c); else tty_putc(minor, '\007'); /* Beep if no more room */ if (!canon || c == t->termios.c_cc[VEOL] || c == '\n' || c == t->termios.c_cc[VEOF]) wakeup(q); return wr; eraseout: while (uninsq(q, &oc)) { if (oc == '\n' || oc == t->termios.c_cc[VEOL]) { insq(q, oc); /* Don't erase past nl */ break; } if (t->termios.c_lflag & wr) tty_erase(minor); if (wr == ECHOE) break; } return 1; }
/* Output for the system console (kprintf etc) */ void kputchar(char c) { if (c == '\n') tty_putc(1, '\r'); tty_putc(1, c); }
/* Output for the system console (kprintf etc) */ void kputchar(uint8_t c) { if (c == '\n') tty_putc(1, '\r'); tty_putc(1, c); }
/* * 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; } }
/* kernel writes to system console -- never sleep! */ void kputchar(uint_fast8_t c) { tty_putc(TTYDEV & 0xFF, c); if(c == '\n') tty_putc(TTYDEV & 0xFF, '\r'); }
void putchar(int c) { tty_putc(c); }
void putc(char c) { tty_putc(c); }
int print_choices(int selection) { int col, i, j, k; size_t query_length; struct choice *choice; tty_putp(clr_eos); /* Emit query line. */ tty_putc('\n'); query_length = strlen(query); for (choice = choices.v, col = i = 0; i < (ssize_t)choices.length && i < lines - 1 && (query_length == 0 || choice->score > 0); choice++, i++) { if (i == selection) tty_putp(enter_standout_mode); for (col = j = 0; j < (ssize_t)choice->match_start && col < columns; col += !isu8cont(choice->string[j]), j++) if (tty_putc(choice->string[j]) == EOF) err(1, "tty_putc"); tty_putp(enter_underline_mode); for (; j < (ssize_t)choice->match_end && col < columns; col += !isu8cont(choice->string[j]), j++) if (tty_putc(choice->string[j]) == EOF) err(1, "tty_putc"); tty_putp(exit_underline_mode); for (; j < (ssize_t)choice->length && col < columns; col += !isu8cont(choice->string[j]), j++) { /* A null character will be present before the * terminating null character if descriptions is * enabled. */ if (choice->string[j] == '\0') { if (tty_putc(' ') == EOF) err(1, "tty_putc"); } else if (tty_putc(choice->string[j]) == EOF) { err(1, "tty_putc"); } } for (k = MAX(columns - choice->printable_length + (choice->length - col), 0); k > 0; k--) if (tty_putc(' ') == EOF) err(1, "tty_putc"); if (i == selection) tty_putp(exit_standout_mode); } return i; }
void tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy) { const struct grid_cell *gc; struct grid_line *gl; struct grid_cell tmpgc; const struct grid_utf8 *gu; u_int i, sx; tty_update_mode(tty, tty->mode & ~MODE_CURSOR, s); sx = screen_size_x(s); if (sx > s->grid->linedata[s->grid->hsize + py].cellsize) sx = s->grid->linedata[s->grid->hsize + py].cellsize; if (sx > tty->sx) sx = tty->sx; /* * Don't move the cursor to the start permission if it will wrap there * itself. */ gl = NULL; if (py != 0) gl = &s->grid->linedata[s->grid->hsize + py - 1]; if (oy + py == 0 || gl == NULL || !(gl->flags & GRID_LINE_WRAPPED) || tty->cx < tty->sx || ox != 0 || (oy + py != tty->cy + 1 && tty->cy != s->rlower + oy)) tty_cursor(tty, ox, oy + py); for (i = 0; i < sx; i++) { gc = grid_view_peek_cell(s->grid, i, py); gu = NULL; if (gc->flags & GRID_FLAG_UTF8) gu = grid_view_peek_utf8(s->grid, i, py); if (screen_check_selection(s, i, py)) { memcpy(&tmpgc, &s->sel.cell, sizeof tmpgc); tmpgc.data = gc->data; tmpgc.flags = gc->flags & ~(GRID_FLAG_FG256|GRID_FLAG_BG256); tmpgc.flags |= s->sel.cell.flags & (GRID_FLAG_FG256|GRID_FLAG_BG256); tty_cell(tty, &tmpgc, gu); } else tty_cell(tty, gc, gu); } if (sx >= tty->sx) { tty_update_mode(tty, tty->mode, s); return; } tty_reset(tty); tty_cursor(tty, ox + sx, oy + py); if (screen_size_x(s) >= tty->sx && tty_term_has(tty->term, TTYC_EL)) tty_putcode(tty, TTYC_EL); else { for (i = sx; i < screen_size_x(s); i++) tty_putc(tty, ' '); } tty_update_mode(tty, tty->mode, s); }