diff options
author | Eduardo Chappa <echappa@gmx.com> | 2013-02-03 00:59:38 -0700 |
---|---|---|
committer | Eduardo Chappa <echappa@gmx.com> | 2013-02-03 00:59:38 -0700 |
commit | 094ca96844842928810f14844413109fc6cdd890 (patch) | |
tree | e60efbb980f38ba9308ccb4fb2b77b87bbc115f3 /pico/osdep/tty.c | |
download | alpine-094ca96844842928810f14844413109fc6cdd890.tar.xz |
Initial Alpine Version
Diffstat (limited to 'pico/osdep/tty.c')
-rw-r--r-- | pico/osdep/tty.c | 372 |
1 files changed, 372 insertions, 0 deletions
diff --git a/pico/osdep/tty.c b/pico/osdep/tty.c new file mode 100644 index 00000000..100b37ea --- /dev/null +++ b/pico/osdep/tty.c @@ -0,0 +1,372 @@ +#if !defined(lint) && !defined(DOS) +static char rcsid[] = "$Id: tty.c 769 2007-10-24 00:15:40Z hubert@u.washington.edu $"; +#endif + +/* + * ======================================================================== + * Copyright 2006-2007 University of Washington + * Copyright 2013 Eduardo Chappa + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * ======================================================================== + * + * Program: tty routines + */ + +#include <system.h> +#include <general.h> + +#include "../estruct.h" +#include "../mode.h" +#include "../pico.h" +#include "../edef.h" +#include "../efunc.h" +#include "../keydefs.h" + +#include "signals.h" +#ifndef _WINDOWS +#include "terminal.h" +#include "raw.h" +#include "read.h" +#else +#include "mswin.h" +#endif /* _WINDOWS */ + +#ifdef MOUSE +#include "mouse.h" +#endif /* MOUSE */ + +#include "tty.h" + + +#ifndef _WINDOWS +/* + * ttopen - this function is called once to set up the terminal device + * streams. if called as pine composer, don't mess with + * tty modes, but set signal handlers. + */ +int +ttopen(void) +{ + if(Pmaster == NULL){ + Raw(1); +#ifdef MOUSE + if(gmode & MDMOUSE) + init_mouse(); +#endif /* MOUSE */ + xonxoff_proc(preserve_start_stop); + } + + picosigs(); + + return(1); +} + + +/* + * ttclose - this function gets called just before we go back home to + * the command interpreter. If called as pine composer, don't + * worry about modes, but set signals to default, pine will + * rewire things as needed. + */ +int +ttclose(void) +{ + if(Pmaster){ + signal(SIGHUP, SIG_DFL); +#ifdef SIGCONT + signal(SIGCONT, SIG_DFL); +#endif +#if defined(SIGWINCH) && defined(TIOCGWINSZ) + signal(SIGWINCH, SIG_DFL); +#endif + } + else{ + Raw(0); +#ifdef MOUSE + end_mouse(); +#endif + } + + return(1); +} + + +/* + * ttgetc - Read a character from the terminal, performing no editing + * and doing no echo at all. + * + * Args: return_on_intr -- Function to get a single character from stdin, + * recorder -- If non-NULL, function used to record keystroke. + * bail_handler -- Function used to bail out on read error. + * + * Returns: The character read from stdin. + * Return_on_intr is returned if read is interrupted. + * If read error, BAIL_OUT is returned unless bail_handler is + * non-NULL, in which case it is called (and usually it exits). + * + * If recorder is non-null, it is used to record the keystroke. + */ +int +ttgetc(int return_on_intr, int (*recorder)(int), void (*bail_handler)(void)) +{ + int c; + + switch(c = read_one_char()){ + case READ_INTR: + return(return_on_intr); + + case BAIL_OUT: + if(bail_handler) + (*bail_handler)(); + else + return(BAIL_OUT); + + default: + return(recorder ? (*recorder)(c) : c); + } +} + + +/* + * Simple version of ttgetc with simple error handling + * + * Args: recorder -- If non-NULL, function used to record keystroke. + * bail_handler -- Function used to bail out on read error. + * + * Returns: The character read from stdin. + * If read error, BAIL_OUT is returned unless bail_handler is + * non-NULL, in which case it is called (and usually it exits). + * + * If recorder is non-null, it is used to record the keystroke. + * Retries if interrupted. + */ +int +simple_ttgetc(int (*recorder)(int), void (*bail_handler)(void)) +{ + int res; + unsigned char c; + + while((res = read(STDIN_FD, &c, 1)) <= 0) + if(!(res < 0 && errno == EINTR)) + (*bail_handler)(); + + return(recorder ? (*recorder)((int)c) : (int)c); +} + + +/* + * ttputc - Write a character to the display. + */ +int +ttputc(UCS ucs) +{ + unsigned char obuf[MAX(MB_LEN_MAX,32)]; + int r, i, width = 0, outchars = 0; + int ret = 0; + + if(ucs < 0x80) + return(putchar((unsigned char) ucs)); + + width = wcellwidth(ucs); + + if(width < 0){ + width = 1; + obuf[outchars++] = '?'; + } + else{ + /* + * Convert the ucs into the multibyte + * character that corresponds to the + * ucs in the users locale. + */ + outchars = wtomb((char *) obuf, ucs); + if(outchars < 0){ + width = 1; + obuf[0] = '?'; + outchars = 1; + } + } + + for(i = 0; i < outchars; i++){ + r = putchar(obuf[i]); + ret = (ret == EOF) ? EOF : r; + } + + return(ret); +} + + +/* + * ttflush - flush terminal buffer. Does real work where the terminal + * output is buffered up. A no-operation on systems where byte + * at a time terminal I/O is done. + */ +int +ttflush(void) +{ + return(fflush(stdout)); +} + + +/* + * ttresize - recompute the screen dimensions if necessary, and then + * adjust pico's internal buffers accordingly. + */ +void +ttresize(void) +{ + int row = -1, col = -1; + + ttgetwinsz(&row, &col); + resize_pico(row, col); +} + + + +/* + * ttgetwinsz - set global row and column values (if we can get them) + * and return. + */ +void +ttgetwinsz(int *row, int *col) +{ + extern int _tlines, _tcolumns; + + if(*row < 0) + *row = (_tlines > 0) ? _tlines - 1 : NROW - 1; + if(*col <= 0) + *col = (_tcolumns > 0) ? _tcolumns : NCOL; +#if defined(SIGWINCH) && defined(TIOCGWINSZ) + { + struct winsize win; + + if (ioctl(0, TIOCGWINSZ, &win) == 0) { /* set to anything useful.. */ + if(win.ws_row) /* ... the tty drivers says */ + *row = win.ws_row - 1; + + if(win.ws_col) + *col = win.ws_col; + } + + signal(SIGWINCH, winch_handler); /* window size changes */ + } +#endif + + if(*col > NLINE-1) + *col = NLINE-1; +} + +#else /* _WINDOWS */ + +#define MARGIN 8 /* size of minimim margin and */ +#define SCRSIZ 64 /* scroll size for extended lines */ +#define MROW 2 /* rows in menu */ + +/* internal prototypes */ +int mswin_resize (int, int); + +/* + * Standard terminal interface dispatch table. Fields point to functions + * that operate the terminal. All these functions live in mswin.c, but + * this structure is defined here because it is specific to pico. + */ +TERM term = { + 0, + 0, + MARGIN, + MROW, + ttopen, + NULL, + ttclose, + NULL, /* was mswin_getc, but not used? */ + mswin_putc, + mswin_flush, + mswin_move, + mswin_eeol, + mswin_eeop, + mswin_beep, + mswin_rev +}; + +/* + * This function is called once to set up the terminal device streams. + */ +int +ttopen(void) +{ + int rows, columns; + + + mswin_getscreensize (&rows, &columns); + term.t_nrow = rows - 1; + term.t_ncol = columns; + /* term.t_scrsiz = (columns * 2) / 3; */ + + /* + * Do we implement optimized character insertion and deletion? + * o_insert() and o_delete() + */ + /* inschar = delchar = FALSE; */ + /* revexist = TRUE; dead code? */ + + mswin_setresizecallback (mswin_resize); + + init_mouse(); + + return(1); +} + +/* + * This function gets called just before we go back home to the command + * interpreter. + */ +int +ttclose(void) +{ + mswin_clearresizecallback (mswin_resize); + return(1); +} + +/* + * Flush terminal buffer. Does real work where the terminal output is buffered + * up. A no-operation on systems where byte at a time terminal I/O is done. + */ +int +ttflush(void) +{ + return(1); +} + +/* + * ttresize - recompute the screen dimensions if necessary, and then + * adjust pico's internal buffers accordingly. + */ +void +ttresize(void) +{ + int row, col; + + mswin_getscreensize(&row, &col); + resize_pico (row-1, col); +} + + +/* + * mswin_resize - windows specific callback to set pico's internal tables + * to new screen dimensions. + */ +int +mswin_resize(int row, int col) +{ + if (wheadp) + resize_pico (row-1, col); + return (0); +} + +#endif /* _WINDOWS */ |