* Fix of the list of files in the browser for terminals that need to erase
[alpine.git] / pico / osdep / tty.c
blobc24a8a550d8f6184719dabad3bd384e2ae88ff49
1 #if !defined(lint) && !defined(DOS)
2 static char rcsid[] = "$Id: tty.c 769 2007-10-24 00:15:40Z hubert@u.washington.edu $";
3 #endif
5 /*
6 * ========================================================================
7 * Copyright 2006-2007 University of Washington
8 * Copyright 2013-2021 Eduardo Chappa
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
14 * http://www.apache.org/licenses/LICENSE-2.0
16 * ========================================================================
18 * Program: tty routines
21 #include <system.h>
22 #include <general.h>
24 #include "../estruct.h"
25 #include "../mode.h"
26 #include "../pico.h"
27 #include "../edef.h"
28 #include "../efunc.h"
29 #include "../keydefs.h"
31 #include "signals.h"
32 #ifndef _WINDOWS
33 #include "terminal.h"
34 #include "raw.h"
35 #include "read.h"
36 #else
37 #include "mswin.h"
38 #endif /* _WINDOWS */
40 #ifdef MOUSE
41 #include "mouse.h"
42 #endif /* MOUSE */
44 #include "tty.h"
47 #ifndef _WINDOWS
49 * ttopen - this function is called once to set up the terminal device
50 * streams. if called as pine composer, don't mess with
51 * tty modes, but set signal handlers.
53 int
54 ttopen(void)
56 if(Pmaster == NULL){
57 Raw(1);
58 #ifdef MOUSE
59 if(gmode & MDMOUSE)
60 init_mouse();
61 #endif /* MOUSE */
62 xonxoff_proc(preserve_start_stop);
65 picosigs();
67 return(1);
72 * ttclose - this function gets called just before we go back home to
73 * the command interpreter. If called as pine composer, don't
74 * worry about modes, but set signals to default, pine will
75 * rewire things as needed.
77 int
78 ttclose(void)
80 if(Pmaster){
81 signal(SIGHUP, SIG_DFL);
82 #ifdef SIGCONT
83 signal(SIGCONT, SIG_DFL);
84 #endif
85 #if defined(SIGWINCH) && defined(TIOCGWINSZ)
86 signal(SIGWINCH, SIG_DFL);
87 #endif
89 else{
90 Raw(0);
91 #ifdef MOUSE
92 end_mouse();
93 #endif
96 return(1);
101 * ttgetc - Read a character from the terminal, performing no editing
102 * and doing no echo at all.
104 * Args: return_on_intr -- Function to get a single character from stdin,
105 * recorder -- If non-NULL, function used to record keystroke.
106 * bail_handler -- Function used to bail out on read error.
108 * Returns: The character read from stdin.
109 * Return_on_intr is returned if read is interrupted.
110 * If read error, BAIL_OUT is returned unless bail_handler is
111 * non-NULL, in which case it is called (and usually it exits).
113 * If recorder is non-null, it is used to record the keystroke.
116 ttgetc(int return_on_intr, int (*recorder)(int), void (*bail_handler)(void))
118 int c;
120 switch(c = read_one_char()){
121 case READ_INTR:
122 return(return_on_intr);
124 case BAIL_OUT:
125 if(bail_handler)
126 (*bail_handler)();
127 else
128 return(BAIL_OUT);
130 default:
131 return(recorder ? (*recorder)(c) : c);
137 * Simple version of ttgetc with simple error handling
139 * Args: recorder -- If non-NULL, function used to record keystroke.
140 * bail_handler -- Function used to bail out on read error.
142 * Returns: The character read from stdin.
143 * If read error, BAIL_OUT is returned unless bail_handler is
144 * non-NULL, in which case it is called (and usually it exits).
146 * If recorder is non-null, it is used to record the keystroke.
147 * Retries if interrupted.
150 simple_ttgetc(int (*recorder)(int), void (*bail_handler)(void))
152 int res;
153 unsigned char c;
155 while((res = read(STDIN_FD, &c, 1)) <= 0)
156 if(!(res < 0 && errno == EINTR))
157 (*bail_handler)();
159 return(recorder ? (*recorder)((int)c) : (int)c);
164 * ttputc - Write a character to the display.
167 ttputc(UCS ucs)
169 unsigned char obuf[MAX(MB_LEN_MAX,32)];
170 int r, i, width = 0, outchars = 0;
171 int ret = 0;
173 if(ucs < 0x80)
174 return(putchar((unsigned char) ucs));
176 width = wcellwidth(ucs);
178 if(width < 0){
179 width = 1;
180 obuf[outchars++] = '?';
182 else{
184 * Convert the ucs into the multibyte
185 * character that corresponds to the
186 * ucs in the users locale.
188 outchars = wtomb((char *) obuf, ucs);
189 if(outchars < 0){
190 width = 1;
191 obuf[0] = '?';
192 outchars = 1;
196 for(i = 0; i < outchars; i++){
197 r = putchar(obuf[i]);
198 ret = (ret == EOF) ? EOF : r;
201 return(ret);
206 * ttflush - flush terminal buffer. Does real work where the terminal
207 * output is buffered up. A no-operation on systems where byte
208 * at a time terminal I/O is done.
211 ttflush(void)
213 return(fflush(stdout));
218 * ttresize - recompute the screen dimensions if necessary, and then
219 * adjust pico's internal buffers accordingly.
221 void
222 ttresize(void)
224 int row = -1, col = -1;
226 ttgetwinsz(&row, &col);
227 resize_pico(row, col);
233 * ttgetwinsz - set global row and column values (if we can get them)
234 * and return.
236 void
237 ttgetwinsz(int *row, int *col)
239 extern int _tlines, _tcolumns;
241 if(*row < 0)
242 *row = (_tlines > 0) ? _tlines - 1 : NROW - 1;
243 if(*col <= 0)
244 *col = (_tcolumns > 0) ? _tcolumns : NCOL;
245 #if defined(SIGWINCH) && defined(TIOCGWINSZ)
247 struct winsize win;
249 if (ioctl(0, TIOCGWINSZ, &win) == 0) { /* set to anything useful.. */
250 if(win.ws_row) /* ... the tty drivers says */
251 *row = win.ws_row - 1;
253 if(win.ws_col)
254 *col = win.ws_col;
257 signal(SIGWINCH, winch_handler); /* window size changes */
259 #endif
261 if(*col > NLINE-1)
262 *col = NLINE-1;
265 #else /* _WINDOWS */
267 #define MARGIN 8 /* size of minimim margin and */
268 #define SCRSIZ 64 /* scroll size for extended lines */
269 #define MROW 2 /* rows in menu */
271 /* internal prototypes */
272 int mswin_resize (int, int);
275 * Standard terminal interface dispatch table. Fields point to functions
276 * that operate the terminal. All these functions live in mswin.c, but
277 * this structure is defined here because it is specific to pico.
279 TERM term = {
282 MARGIN,
283 MROW,
284 ttopen,
285 NULL,
286 ttclose,
287 NULL, /* was mswin_getc, but not used? */
288 mswin_putc,
289 mswin_flush,
290 mswin_move,
291 mswin_eeol,
292 mswin_eeop,
293 mswin_beep,
294 mswin_rev,
295 NULL /* no standout glitch in Windows */
299 * This function is called once to set up the terminal device streams.
302 ttopen(void)
304 int rows, columns;
307 mswin_getscreensize (&rows, &columns);
308 term.t_nrow = rows - 1;
309 term.t_ncol = columns;
310 /* term.t_scrsiz = (columns * 2) / 3; */
313 * Do we implement optimized character insertion and deletion?
314 * o_insert() and o_delete()
316 /* inschar = delchar = FALSE; */
317 /* revexist = TRUE; dead code? */
319 mswin_setresizecallback (mswin_resize);
321 init_mouse();
323 return(1);
327 * This function gets called just before we go back home to the command
328 * interpreter.
331 ttclose(void)
333 mswin_clearresizecallback (mswin_resize);
334 return(1);
338 * Flush terminal buffer. Does real work where the terminal output is buffered
339 * up. A no-operation on systems where byte at a time terminal I/O is done.
342 ttflush(void)
344 return(1);
348 * ttresize - recompute the screen dimensions if necessary, and then
349 * adjust pico's internal buffers accordingly.
351 void
352 ttresize(void)
354 int row, col;
356 mswin_getscreensize(&row, &col);
357 resize_pico (row-1, col);
362 * mswin_resize - windows specific callback to set pico's internal tables
363 * to new screen dimensions.
366 mswin_resize(int row, int col)
368 if (wheadp)
369 resize_pico (row-1, col);
370 return (0);
373 #endif /* _WINDOWS */