2534 lines
		
	
	
		
			50 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			2534 lines
		
	
	
		
			50 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /* $Id: terms.c,v 1.63 2010/08/20 09:34:47 htrb Exp $ */
 | |
| /* 
 | |
|  * An original curses library for EUC-kanji by Akinori ITO,     December 1989
 | |
|  * revised by Akinori ITO, January 1995
 | |
|  */
 | |
| #include <stdio.h>
 | |
| #include <signal.h>
 | |
| #include <sys/types.h>
 | |
| #include <fcntl.h>
 | |
| #include <errno.h>
 | |
| #include <sys/time.h>
 | |
| #include <unistd.h>
 | |
| #include "config.h"
 | |
| #include <string.h>
 | |
| #include <sys/wait.h>
 | |
| #ifdef HAVE_SYS_SELECT_H
 | |
| #include <sys/select.h>
 | |
| #endif
 | |
| #ifndef __MINGW32_VERSION
 | |
| #include <sys/ioctl.h>
 | |
| #else
 | |
| #include <winsock.h>
 | |
| #endif /* __MINGW32_VERSION */
 | |
| #ifdef USE_MOUSE
 | |
| #ifdef USE_GPM
 | |
| #include <gpm.h>
 | |
| #endif				/* USE_GPM */
 | |
| #ifdef USE_SYSMOUSE
 | |
| #include <osreldate.h>
 | |
| #if (__FreeBSD_version >= 400017) || (__FreeBSD_kernel_version >= 400017)
 | |
| #include <sys/consio.h>
 | |
| #include <sys/fbio.h>
 | |
| #else
 | |
| #include <machine/console.h>
 | |
| #endif
 | |
| int (*sysm_handler) (int x, int y, int nbs, int obs);
 | |
| static int cwidth = 8, cheight = 16;
 | |
| static int xpix, ypix, nbs, obs = 0;
 | |
| #endif				/* use_SYSMOUSE */
 | |
| 
 | |
| static int is_xterm = 0;
 | |
| 
 | |
| void mouse_init(), mouse_end();
 | |
| int mouseActive = 0;
 | |
| #endif				/* USE_MOUSE */
 | |
| 
 | |
| static char *title_str = NULL;
 | |
| 
 | |
| static int tty;
 | |
| 
 | |
| #include "terms.h"
 | |
| #include "fm.h"
 | |
| #include "myctype.h"
 | |
| 
 | |
| #ifdef __EMX__
 | |
| #define INCL_DOSNLS
 | |
| #include <os2.h>
 | |
| #endif				/* __EMX__ */
 | |
| 
 | |
| #if defined(__CYGWIN__)
 | |
| #include <windows.h>
 | |
| #include <sys/cygwin.h>
 | |
| static int isWinConsole = 0;
 | |
| #define TERM_CYGWIN 1
 | |
| #define TERM_CYGWIN_RESERVE_IME 2
 | |
| static int isLocalConsole = 0;
 | |
| 
 | |
| #if CYGWIN_VERSION_DLL_MAJOR < 1005 && defined(USE_MOUSE)
 | |
| int cygwin_mouse_btn_swapped = 0;
 | |
| #endif
 | |
| 
 | |
| #if defined(SUPPORT_WIN9X_CONSOLE_MBCS)
 | |
| static HANDLE hConIn = INVALID_HANDLE_VALUE;
 | |
| static int isWin95 = 0;
 | |
| static char *ConInV;
 | |
| static int iConIn, nConIn, nConInMax;
 | |
| 
 | |
| static void
 | |
| check_win9x(void)
 | |
| {
 | |
|     OSVERSIONINFO winVersionInfo;
 | |
| 
 | |
|     winVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
 | |
|     if (GetVersionEx(&winVersionInfo) == 0) {
 | |
| 	fprintf(stderr, "can't get Windows version information.\n");
 | |
| 	exit(1);
 | |
|     }
 | |
|     if (winVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) {
 | |
| 	isWin95 = 1;
 | |
|     }
 | |
|     else {
 | |
| 	isWin95 = 0;
 | |
|     }
 | |
| }
 | |
| 
 | |
| void
 | |
| enable_win9x_console_input(void)
 | |
| {
 | |
|     if (isWin95 && isWinConsole && isLocalConsole &&
 | |
| 	hConIn == INVALID_HANDLE_VALUE) {
 | |
| 	hConIn = CreateFile("CONIN$", GENERIC_READ | GENERIC_WRITE,
 | |
| 			    FILE_SHARE_READ | FILE_SHARE_WRITE,
 | |
| 			    NULL, OPEN_EXISTING, 0, NULL);
 | |
| 	if (hConIn != INVALID_HANDLE_VALUE) {
 | |
| 	    getch();
 | |
| 	}
 | |
|     }
 | |
| }
 | |
| 
 | |
| void
 | |
| disable_win9x_console_input(void)
 | |
| {
 | |
|     if (hConIn != INVALID_HANDLE_VALUE) {
 | |
| 	CloseHandle(hConIn);
 | |
| 	hConIn = INVALID_HANDLE_VALUE;
 | |
|     }
 | |
| }
 | |
| 
 | |
| static void
 | |
| expand_win32_console_input_buffer(int n)
 | |
| {
 | |
|     if (nConIn + n >= nConInMax) {
 | |
| 	char *oldv;
 | |
| 
 | |
| 	nConInMax = ((nConIn + n) / 2 + 1) * 3;
 | |
| 	oldv = ConInV;
 | |
| 	ConInV = GC_MALLOC_ATOMIC(nConInMax);
 | |
| 	memcpy(ConInV, oldv, nConIn);
 | |
|     }
 | |
| }
 | |
| 
 | |
| static int
 | |
| read_win32_console_input(void)
 | |
| {
 | |
|     INPUT_RECORD rec;
 | |
|     DWORD nevents;
 | |
| 
 | |
|     if (PeekConsoleInput(hConIn, &rec, 1, &nevents) && nevents) {
 | |
| 	switch (rec.EventType) {
 | |
| 	case KEY_EVENT:
 | |
| 	    expand_win32_console_input_buffer(3);
 | |
| 
 | |
| 	    if (ReadConsole(hConIn, &ConInV[nConIn], 1, &nevents, NULL)) {
 | |
| 		nConIn += nevents;
 | |
| 		return nevents;
 | |
| 	    }
 | |
| 
 | |
| 	    break;
 | |
| 	default:
 | |
| 	    break;
 | |
| 	}
 | |
| 
 | |
| 	ReadConsoleInput(hConIn, &rec, 1, &nevents);
 | |
|     }
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| static int
 | |
| read_win32_console(char *s, int n)
 | |
| {
 | |
|     KEY_EVENT_RECORD *ker;
 | |
| 
 | |
|     if (hConIn == INVALID_HANDLE_VALUE)
 | |
| 	return read(tty, s, n);
 | |
| 
 | |
|     if (n > 0)
 | |
| 	for (;;) {
 | |
| 	    if (iConIn < nConIn) {
 | |
| 		if (n > nConIn - iConIn)
 | |
| 		    n = nConIn - iConIn;
 | |
| 
 | |
| 		memcpy(s, ConInV, n);
 | |
| 
 | |
| 		if ((iConIn += n) >= nConIn)
 | |
| 		    iConIn = nConIn = 0;
 | |
| 
 | |
| 		break;
 | |
| 	    }
 | |
| 
 | |
| 	    iConIn = nConIn = 0;
 | |
| 
 | |
| 	    while (!read_win32_console_input()) ;
 | |
| 	}
 | |
| 
 | |
|     return n;
 | |
| }
 | |
| 
 | |
| #endif				/* SUPPORT_WIN9X_CONSOLE_MBCS */
 | |
| 
 | |
| static HWND
 | |
| GetConsoleHwnd(void)
 | |
| {
 | |
| #define MY_BUFSIZE 1024
 | |
|     HWND hwndFound;
 | |
|     char pszNewWindowTitle[MY_BUFSIZE];
 | |
|     char pszOldWindowTitle[MY_BUFSIZE];
 | |
| 
 | |
|     GetConsoleTitle(pszOldWindowTitle, MY_BUFSIZE);
 | |
|     wsprintf(pszNewWindowTitle, "%d/%d",
 | |
| 	     GetTickCount(), GetCurrentProcessId());
 | |
|     SetConsoleTitle(pszNewWindowTitle);
 | |
|     Sleep(40);
 | |
|     hwndFound = FindWindow(NULL, pszNewWindowTitle);
 | |
|     SetConsoleTitle(pszOldWindowTitle);
 | |
|     return (hwndFound);
 | |
| }
 | |
| 
 | |
| #if CYGWIN_VERSION_DLL_MAJOR < 1005 && defined(USE_MOUSE)
 | |
| static unsigned long
 | |
| cygwin_version(void)
 | |
| {
 | |
|     struct per_process *p;
 | |
| 
 | |
|     p = (struct per_process *)cygwin_internal(CW_USER_DATA);
 | |
|     if (p != NULL) {
 | |
| 	return (p->dll_major * 1000) + p->dll_minor;
 | |
|     }
 | |
|     return 0;
 | |
| }
 | |
| #endif
 | |
| 
 | |
| static void
 | |
| check_cygwin_console(void)
 | |
| {
 | |
|     char *term = getenv("TERM");
 | |
|     char *ctype;
 | |
|     HANDLE hWnd;
 | |
| 
 | |
|     if (term == NULL)
 | |
| 	term = DEFAULT_TERM;
 | |
|     if (term && strncmp(term, "cygwin", 6) == 0) {
 | |
| 	isWinConsole = TERM_CYGWIN;
 | |
|     }
 | |
|     if (isWinConsole) {
 | |
| 	hWnd = GetConsoleHwnd();
 | |
| 	if (hWnd != INVALID_HANDLE_VALUE) {
 | |
| 	    if (IsWindowVisible(hWnd)) {
 | |
| 		isLocalConsole = 1;
 | |
| 	    }
 | |
| 	}
 | |
| 	if (((ctype = getenv("LC_ALL")) ||
 | |
| 	     (ctype = getenv("LC_CTYPE")) ||
 | |
| 	     (ctype = getenv("LANG"))) && strncmp(ctype, "ja", 2) == 0) {
 | |
| 	    isWinConsole = TERM_CYGWIN_RESERVE_IME;
 | |
| 	}
 | |
| #ifdef SUPPORT_WIN9X_CONSOLE_MBCS
 | |
| 	check_win9x();
 | |
| 	if (isWin95 && ttyslot() != -1) {
 | |
| 	    isLocalConsole = 0;
 | |
| 	}
 | |
| #endif
 | |
|     }
 | |
| #if CYGWIN_VERSION_DLL_MAJOR < 1005 && defined(USE_MOUSE)
 | |
|     if (cygwin_version() <= 1003015) {
 | |
| 	/* cygwin DLL 1.3.15 or earler */
 | |
| 	cygwin_mouse_btn_swapped = 1;
 | |
|     }
 | |
| #endif
 | |
| }
 | |
| #endif				/* __CYGWIN__ */
 | |
| 
 | |
| char *getenv(const char *);
 | |
| MySignalHandler reset_exit(SIGNAL_ARG), reset_error_exit(SIGNAL_ARG), error_dump(SIGNAL_ARG);
 | |
| void setlinescols(void);
 | |
| void flush_tty();
 | |
| 
 | |
| #ifndef SIGIOT
 | |
| #define SIGIOT SIGABRT
 | |
| #endif				/* not SIGIOT */
 | |
| 
 | |
| #ifdef HAVE_TERMIO_H
 | |
| #include <termio.h>
 | |
| typedef struct termio TerminalMode;
 | |
| #define TerminalSet(fd,x)       ioctl(fd,TCSETA,x)
 | |
| #define TerminalGet(fd,x)       ioctl(fd,TCGETA,x)
 | |
| #define MODEFLAG(d)     ((d).c_lflag)
 | |
| #define IMODEFLAG(d)    ((d).c_iflag)
 | |
| #endif				/* HAVE_TERMIO_H */
 | |
| 
 | |
| #ifdef HAVE_TERMIOS_H
 | |
| #include <termios.h>
 | |
| #include <unistd.h>
 | |
| typedef struct termios TerminalMode;
 | |
| #define TerminalSet(fd,x)       tcsetattr(fd,TCSANOW,x)
 | |
| #define TerminalGet(fd,x)       tcgetattr(fd,x)
 | |
| #define MODEFLAG(d)     ((d).c_lflag)
 | |
| #define IMODEFLAG(d)    ((d).c_iflag)
 | |
| #endif				/* HAVE_TERMIOS_H */
 | |
| 
 | |
| #ifdef HAVE_SGTTY_H
 | |
| #include <sgtty.h>
 | |
| typedef struct sgttyb TerminalMode;
 | |
| #define TerminalSet(fd,x)       ioctl(fd,TIOCSETP,x)
 | |
| #define TerminalGet(fd,x)       ioctl(fd,TIOCGETP,x)
 | |
| #define MODEFLAG(d)     ((d).sg_flags)
 | |
| #endif				/* HAVE_SGTTY_H */
 | |
| 
 | |
| #ifdef __MINGW32_VERSION
 | |
| /* dummy struct */
 | |
| typedef unsigned char   cc_t;
 | |
| typedef unsigned int    speed_t;
 | |
| typedef unsigned int    tcflag_t;
 | |
| 
 | |
| #define NCCS 32
 | |
| struct termios
 | |
|   {
 | |
|     tcflag_t c_iflag;           /* input mode flags */
 | |
|     tcflag_t c_oflag;           /* output mode flags */
 | |
|     tcflag_t c_cflag;           /* control mode flags */
 | |
|     tcflag_t c_lflag;           /* local mode flags */
 | |
|     cc_t c_line;                        /* line discipline */
 | |
|     cc_t c_cc[NCCS];            /* control characters */
 | |
|     speed_t c_ispeed;           /* input speed */
 | |
|     speed_t c_ospeed;           /* output speed */
 | |
|   };
 | |
| typedef struct termios TerminalMode;
 | |
| #define TerminalSet(fd,x)       (0)
 | |
| #define TerminalGet(fd,x)       (0)
 | |
| #define MODEFLAG(d)     (0)
 | |
| 
 | |
| /* dummy defines */
 | |
| #define SIGHUP (0)
 | |
| #define SIGQUIT (0)
 | |
| #define ECHO (0)
 | |
| #define ISIG (0)
 | |
| #define VEOF (0)
 | |
| #define ICANON (0)
 | |
| #define IXON (0)
 | |
| #define IXOFF (0)
 | |
| 
 | |
| char *ttyname(int);
 | |
| #endif /* __MINGW32_VERSION */
 | |
| 
 | |
| #define MAX_LINE        200
 | |
| #define MAX_COLUMN      400
 | |
| 
 | |
| /* Screen properties */
 | |
| #define S_SCREENPROP    0x0f
 | |
| #define S_NORMAL        0x00
 | |
| #define S_STANDOUT      0x01
 | |
| #define S_UNDERLINE     0x02
 | |
| #define S_BOLD          0x04
 | |
| #define S_EOL           0x08
 | |
| 
 | |
| /* Sort of Character */
 | |
| #define C_WHICHCHAR     0xc0
 | |
| #define C_ASCII         0x00
 | |
| #ifdef USE_M17N
 | |
| #define C_WCHAR1        0x40
 | |
| #define C_WCHAR2        0x80
 | |
| #endif
 | |
| #define C_CTRL          0xc0
 | |
| 
 | |
| #define CHMODE(c)       ((c)&C_WHICHCHAR)
 | |
| #define SETCHMODE(var,mode)	((var) = (((var)&~C_WHICHCHAR) | mode))
 | |
| #ifdef USE_M17N
 | |
| #define SETCH(var,ch,len)	((var) = New_Reuse(char, (var), (len) + 1), \
 | |
| 				strncpy((var), (ch), (len)), (var)[len] = '\0')
 | |
| #else
 | |
| #define SETCH(var,ch,len)	((var) = (ch))
 | |
| #endif
 | |
| 
 | |
| /* Charactor Color */
 | |
| #define COL_FCOLOR      0xf00
 | |
| #define COL_FBLACK      0x800
 | |
| #define COL_FRED        0x900
 | |
| #define COL_FGREEN      0xa00
 | |
| #define COL_FYELLOW     0xb00
 | |
| #define COL_FBLUE       0xc00
 | |
| #define COL_FMAGENTA    0xd00
 | |
| #define COL_FCYAN       0xe00
 | |
| #define COL_FWHITE      0xf00
 | |
| #define COL_FTERM       0x000
 | |
| 
 | |
| #define S_COLORED       0xf00
 | |
| 
 | |
| #ifdef USE_BG_COLOR
 | |
| /* Background Color */
 | |
| #define COL_BCOLOR      0xf000
 | |
| #define COL_BBLACK      0x8000
 | |
| #define COL_BRED        0x9000
 | |
| #define COL_BGREEN      0xa000
 | |
| #define COL_BYELLOW     0xb000
 | |
| #define COL_BBLUE       0xc000
 | |
| #define COL_BMAGENTA    0xd000
 | |
| #define COL_BCYAN       0xe000
 | |
| #define COL_BWHITE      0xf000
 | |
| #define COL_BTERM       0x0000
 | |
| 
 | |
| #define S_BCOLORED      0xf000
 | |
| #endif				/* USE_BG_COLOR */
 | |
| 
 | |
| 
 | |
| #define S_GRAPHICS      0x10
 | |
| 
 | |
| #define S_DIRTY         0x20
 | |
| 
 | |
| #define SETPROP(var,prop) (var = (((var)&S_DIRTY) | prop))
 | |
| 
 | |
| /* Line status */
 | |
| #define L_DIRTY         0x01
 | |
| #define L_UNUSED        0x02
 | |
| #define L_NEED_CE       0x04
 | |
| #define L_CLRTOEOL      0x08
 | |
| 
 | |
| #define ISDIRTY(d)      ((d) & L_DIRTY)
 | |
| #define ISUNUSED(d)     ((d) & L_UNUSED)
 | |
| #define NEED_CE(d)      ((d) & L_NEED_CE)
 | |
| 
 | |
| typedef unsigned short l_prop;
 | |
| 
 | |
| typedef struct scline {
 | |
| #ifdef USE_M17N
 | |
|     char **lineimage;
 | |
| #else
 | |
|     char *lineimage;
 | |
| #endif
 | |
|     l_prop *lineprop;
 | |
|     short isdirty;
 | |
|     short eol;
 | |
| } Screen;
 | |
| 
 | |
| static TerminalMode d_ioval;
 | |
| static int tty = -1;
 | |
| static FILE *ttyf = NULL;
 | |
| 
 | |
| static
 | |
| char bp[1024], funcstr[256];
 | |
| 
 | |
| char *T_cd, *T_ce, *T_kr, *T_kl, *T_cr, *T_bt, *T_ta, *T_sc, *T_rc,
 | |
|     *T_so, *T_se, *T_us, *T_ue, *T_cl, *T_cm, *T_al, *T_sr, *T_md, *T_me,
 | |
|     *T_ti, *T_te, *T_nd, *T_as, *T_ae, *T_eA, *T_ac, *T_op;
 | |
| 
 | |
| int LINES, COLS;
 | |
| #if defined(__CYGWIN__)
 | |
| int LASTLINE;
 | |
| #endif				/* defined(__CYGWIN__) */
 | |
| 
 | |
| static int max_LINES = 0, max_COLS = 0;
 | |
| static int tab_step = 8;
 | |
| static int CurLine, CurColumn;
 | |
| static Screen *ScreenElem = NULL, **ScreenImage = NULL;
 | |
| static l_prop CurrentMode = 0;
 | |
| static int graph_enabled = 0;
 | |
| 
 | |
| static char gcmap[96];
 | |
| 
 | |
| extern int tgetent(char *, char *);
 | |
| extern int tgetnum(char *);
 | |
| extern int tgetflag(char *);
 | |
| extern char *tgetstr(char *, char **);
 | |
| extern char *tgoto(char *, int, int);
 | |
| extern int tputs(char *, int, int (*)(char));
 | |
| void clear(), wrap(), touch_line(), touch_column(int);
 | |
| #if 0
 | |
| void need_clrtoeol(void);
 | |
| #endif
 | |
| void clrtoeol(void);		/* conflicts with curs_clear(3)? */
 | |
| 
 | |
| static int write1(char);
 | |
| 
 | |
| static void
 | |
| writestr(char *s)
 | |
| {
 | |
|     tputs(s, 1, write1);
 | |
| }
 | |
| 
 | |
| #define MOVE(line,column)       writestr(tgoto(T_cm,column,line));
 | |
| 
 | |
| #ifdef USE_IMAGE
 | |
| void
 | |
| put_image_osc5379(char *url, int x, int y, int w, int h, int sx, int sy, int sw, int sh, int n_terminal_image)
 | |
| {
 | |
|     Str buf;
 | |
|     char *size ;
 | |
| 
 | |
|     if (w > 0 && h > 0)
 | |
| 	size = Sprintf("%dx%d",w,h)->ptr;
 | |
|     else
 | |
| 	size = "";
 | |
| 
 | |
|     MOVE(y,x);
 | |
|     buf = Sprintf("\x1b]5379;show_picture %s %s %dx%d+%d+%d\x07",url,size,sw,sh,sx,sy);
 | |
|     writestr(buf->ptr);
 | |
|     MOVE(Currentbuf->cursorY,Currentbuf->cursorX);
 | |
| }
 | |
| 
 | |
| static void
 | |
| save_gif(const char *path, u_char *header, size_t  header_size, u_char *body, size_t body_size)
 | |
| {
 | |
|     int	fd;
 | |
| 
 | |
|     if ((fd = open(path, O_WRONLY|O_CREAT, 0600)) >= 0) {
 | |
| 	write(fd, header, header_size) ;
 | |
| 	write(fd, body, body_size) ;
 | |
| 	write(fd, "\x3b" , 1) ;
 | |
| 	close(fd) ;
 | |
|     }
 | |
| }
 | |
| 
 | |
| static u_char *
 | |
| skip_gif_header(u_char *p)
 | |
| {
 | |
|     /* Header */
 | |
|     p += 10;
 | |
| 
 | |
|     if (*(p) & 0x80) {
 | |
| 	p += (3 * (2 << ((*p) & 0x7)));
 | |
|     }
 | |
|     p += 3;
 | |
| 
 | |
|     return p;
 | |
| }
 | |
| 
 | |
| static Str
 | |
| save_first_animation_frame(const char *path)
 | |
| {
 | |
|     int	fd;
 | |
|     struct stat	st;
 | |
|     u_char *header;
 | |
|     size_t header_size;
 | |
|     u_char *body;
 | |
|     u_char *p;
 | |
|     ssize_t len;
 | |
|     Str new_path;
 | |
| 
 | |
|     new_path = Strnew_charp(path);
 | |
|     Strcat_charp(new_path, "-1");
 | |
|     if (stat(new_path->ptr, &st) == 0) {
 | |
| 	return new_path;
 | |
|     }
 | |
| 
 | |
|     if ((fd = open( path, O_RDONLY)) < 0) {
 | |
| 	return NULL;
 | |
|     }
 | |
| 
 | |
|     if (fstat( fd, &st) != 0 || ! (header = GC_malloc( st.st_size))){
 | |
| 	close( fd);
 | |
| 	return NULL;
 | |
|     }
 | |
| 
 | |
|     len = read(fd, header, st.st_size);
 | |
|     close(fd);
 | |
| 
 | |
|     /* Header */
 | |
| 
 | |
|     if (len != st.st_size || strncmp(header, "GIF89a", 6) != 0) {
 | |
| 	return NULL;
 | |
|     }
 | |
| 
 | |
|     p = skip_gif_header(header);
 | |
|     header_size = p - header;
 | |
| 
 | |
|     /* Application Extension */
 | |
|     if (p[0] == 0x21 && p[1] == 0xff) {
 | |
| 	p += 19;
 | |
|     }
 | |
| 
 | |
|     /* Other blocks */
 | |
|     body = NULL;
 | |
|     while (p + 2 < header + st.st_size) {
 | |
| 	if (*(p++) == 0x21 && *(p++) == 0xf9 && *(p++) == 0x04) {
 | |
| 	    if( body) {
 | |
| 		/* Graphic Control Extension */
 | |
| 		save_gif(new_path->ptr, header, header_size, body, p - 3 - body);
 | |
| 		return new_path;
 | |
| 	    }
 | |
| 	    else {
 | |
| 		/* skip the first frame. */
 | |
| 	    }
 | |
| 	    body = p - 3;
 | |
| 	}
 | |
|     }
 | |
| 
 | |
|     return NULL;
 | |
| }
 | |
| 
 | |
| void ttymode_set(int mode, int imode);
 | |
| void ttymode_reset(int mode, int imode);
 | |
| 
 | |
| void
 | |
| put_image_sixel(char *url, int x, int y, int w, int h, int sx, int sy, int sw, int sh, int n_terminal_image)
 | |
| {
 | |
|     pid_t pid;
 | |
|     int do_anim;
 | |
|     MySignalHandler(*volatile previntr) (SIGNAL_ARG);
 | |
|     MySignalHandler(*volatile prevquit) (SIGNAL_ARG);
 | |
|     MySignalHandler(*volatile prevstop) (SIGNAL_ARG);
 | |
| 
 | |
|     MOVE(y,x);
 | |
|     flush_tty();
 | |
| 
 | |
|     do_anim = (n_terminal_image == 1 && x == 0 && y == 0 && sx == 0 && sy == 0);
 | |
| 
 | |
|     previntr = mySignal(SIGINT, SIG_IGN);
 | |
|     prevquit = mySignal(SIGQUIT, SIG_IGN);
 | |
|     prevstop = mySignal(SIGTSTP, SIG_IGN);
 | |
| 
 | |
|     if ((pid = fork()) == 0) {
 | |
| 	char *env;
 | |
| 	int n = 0;
 | |
| 	char *argv[20];
 | |
| 	char digit[2][11+1];
 | |
| 	char clip[44+3+1];
 | |
| 	Str str_url;
 | |
| 
 | |
| 	close(STDERR_FILENO);	/* Don't output error message. */
 | |
| 	if (do_anim) {
 | |
| 	    writestr("\x1b[?80h");
 | |
| 	}
 | |
| 	else if (!strstr(url, "://") && strcmp(url+strlen(url)-4, ".gif") == 0 &&
 | |
|                  (str_url = save_first_animation_frame(url))) {
 | |
| 	    url = str_url->ptr;
 | |
| 	}
 | |
| 	ttymode_set(ISIG, 0);
 | |
| 
 | |
| 	if ((env = getenv("W3M_IMG2SIXEL"))) {
 | |
| 	    char *p;
 | |
| 	    env = Strnew_charp(env)->ptr;
 | |
| 	    while (n < 8 && (p = strchr(env, ' '))) {
 | |
| 		*p = '\0';
 | |
| 		if (*env != '\0') {
 | |
| 		    argv[n++] = env;
 | |
| 		}
 | |
| 		env = p+1;
 | |
| 	    }
 | |
| 	    if (*env != '\0') {
 | |
| 		argv[n++] = env;
 | |
| 	    }
 | |
| 	}
 | |
| 	else {
 | |
| 		argv[n++] = "img2sixel";
 | |
| 	}
 | |
| 	argv[n++] = "-l";
 | |
| 	argv[n++] = do_anim ? "auto" : "disable";
 | |
| 	argv[n++] = "-w";
 | |
| 	sprintf(digit[0], "%d", w*pixel_per_char_i);
 | |
| 	argv[n++] = digit[0];
 | |
| 	argv[n++] = "-h";
 | |
| 	sprintf(digit[1], "%d", h*pixel_per_line_i);
 | |
| 	argv[n++] = digit[1];
 | |
| 	argv[n++] = "-c";
 | |
| 	sprintf(clip, "%dx%d+%d+%d", sw*pixel_per_char_i, sh*pixel_per_line_i,
 | |
| 			sx*pixel_per_char_i, sy*pixel_per_line_i);
 | |
| 	argv[n++] = clip;
 | |
| 	argv[n++] = url;
 | |
| 	if (getenv("TERM") && strcmp(getenv("TERM"), "screen") == 0 &&
 | |
| 	    (!getenv("SCREEN_VARIANT") || strcmp(getenv("SCREEN_VARIANT"), "sixel") != 0)) {
 | |
| 	    argv[n++] = "-P";
 | |
| 	}
 | |
| 	argv[n++] = NULL;
 | |
| 	execvp(argv[0],argv);
 | |
| 	exit(0);
 | |
|     }
 | |
|     else if (pid > 0) {
 | |
| 	int status;
 | |
| 	waitpid(pid, &status, 0);
 | |
| 	ttymode_reset(ISIG, 0);
 | |
| 	mySignal(SIGINT, previntr);
 | |
| 	mySignal(SIGQUIT, prevquit);
 | |
| 	mySignal(SIGTSTP, prevstop);
 | |
| 	if (do_anim) {
 | |
| 	    writestr("\x1b[?80l");
 | |
| 	}
 | |
|     }
 | |
| 
 | |
|     MOVE(Currentbuf->cursorY,Currentbuf->cursorX);
 | |
| }
 | |
| 
 | |
| int
 | |
| get_pixel_per_cell(int *ppc, int *ppl)
 | |
| {
 | |
|     fd_set  rfd;
 | |
|     struct timeval tval;
 | |
|     char buf[100];
 | |
|     char *p;
 | |
|     ssize_t len;
 | |
|     ssize_t left;
 | |
|     int wp,hp,wc,hc;
 | |
|     int i;
 | |
| 
 | |
| #ifdef  TIOCGWINSZ
 | |
|     struct winsize ws;
 | |
|     if (ioctl(tty, TIOCGWINSZ, &ws) == 0 && ws.ws_ypixel > 0 && ws.ws_row > 0 &&
 | |
|         ws.ws_xpixel > 0 && ws.ws_col > 0) {
 | |
| 	*ppc = ws.ws_xpixel / ws.ws_col;
 | |
| 	*ppl = ws.ws_ypixel / ws.ws_row;
 | |
| 	return 1;
 | |
|     }
 | |
| #endif
 | |
| 
 | |
|     fputs("\x1b[14t\x1b[18t",ttyf); flush_tty();
 | |
| 
 | |
|     p = buf;
 | |
|     left = sizeof(buf) - 1;
 | |
|     for (i = 0; i < 10; i++) {
 | |
| 	tval.tv_usec = 200000;	/* 0.2 sec * 10 */
 | |
| 	tval.tv_sec = 0;
 | |
| 	FD_ZERO(&rfd);
 | |
| 	FD_SET(tty,&rfd);
 | |
| 	if (select(tty+1,&rfd,NULL,NULL,&tval) <= 0 || ! FD_ISSET(tty,&rfd))
 | |
| 	    continue;
 | |
| 
 | |
| 	if ((len = read(tty,p,left)) <= 0)
 | |
| 	    continue;
 | |
| 	p[len] = '\0';
 | |
| 
 | |
| 	if (sscanf(buf,"\x1b[4;%d;%dt\x1b[8;%d;%dt",&hp,&wp,&hc,&wc) == 4) {
 | |
| 	    if (wp > 0 && wc > 0 && hp > 0 && hc > 0) {
 | |
| 		*ppc = wp / wc;
 | |
| 		*ppl = hp / hc;
 | |
| 		return 1;
 | |
| 	    }
 | |
| 	    else {
 | |
| 		return 0;
 | |
| 	    }
 | |
| 	}
 | |
| 	p += len;
 | |
| 	left -= len;
 | |
|     }
 | |
| 
 | |
|     return 0;
 | |
| }
 | |
| #endif				/* USE_IMAGE */
 | |
| 
 | |
| #ifdef USE_MOUSE
 | |
| #define W3M_TERM_INFO(name, title, mouse)	name, title, mouse
 | |
| #define NEED_XTERM_ON   (1)
 | |
| #define NEED_XTERM_OFF  (1<<1)
 | |
| #ifdef __CYGWIN__
 | |
| #define NEED_CYGWIN_ON  (1<<2)
 | |
| #define NEED_CYGWIN_OFF (1<<3)
 | |
| #endif
 | |
| #else
 | |
| #define W3M_TERM_INFO(name, title, mouse)	name, title
 | |
| #endif
 | |
| 
 | |
| static char XTERM_TITLE[] = "\033]0;w3m: %s\007";
 | |
| static char SCREEN_TITLE[] = "\033k%s\033\134";
 | |
| #ifdef __CYGWIN__
 | |
| static char CYGWIN_TITLE[] = "w3m: %s";
 | |
| #endif
 | |
| 
 | |
| /* *INDENT-OFF* */
 | |
| static struct w3m_term_info {
 | |
|     char *term;
 | |
|     char *title_str;
 | |
| #ifdef USE_MOUSE
 | |
|     int mouse_flag;
 | |
| #endif
 | |
| } w3m_term_info_list[] = {
 | |
|     {W3M_TERM_INFO("xterm", XTERM_TITLE, (NEED_XTERM_ON|NEED_XTERM_OFF))},
 | |
|     {W3M_TERM_INFO("kterm", XTERM_TITLE, (NEED_XTERM_ON|NEED_XTERM_OFF))},
 | |
|     {W3M_TERM_INFO("rxvt", XTERM_TITLE, (NEED_XTERM_ON|NEED_XTERM_OFF))},
 | |
|     {W3M_TERM_INFO("Eterm", XTERM_TITLE, (NEED_XTERM_ON|NEED_XTERM_OFF))},
 | |
|     {W3M_TERM_INFO("mlterm", XTERM_TITLE, (NEED_XTERM_ON|NEED_XTERM_OFF))},
 | |
|     {W3M_TERM_INFO("screen", SCREEN_TITLE, 0)},
 | |
| #ifdef __CYGWIN__
 | |
|     {W3M_TERM_INFO("cygwin", CYGWIN_TITLE, (NEED_CYGWIN_ON|NEED_CYGWIN_OFF))},
 | |
| #endif
 | |
|     {W3M_TERM_INFO(NULL, NULL, 0)}
 | |
| };
 | |
| #undef W3M_TERM_INFO
 | |
| /* *INDENT-ON * */
 | |
| 
 | |
| int
 | |
| set_tty(void)
 | |
| {
 | |
|     char *ttyn;
 | |
| 
 | |
|     if (isatty(0))		/* stdin */
 | |
| 	ttyn = ttyname(0);
 | |
|     else
 | |
| 	ttyn = DEV_TTY_PATH;
 | |
|     tty = open(ttyn, O_RDWR);
 | |
|     if (tty < 0) {
 | |
| 	/* use stderr instead of stdin... is it OK???? */
 | |
| 	tty = 2;
 | |
|     }
 | |
|     ttyf = fdopen(tty, "w");
 | |
| #ifdef __CYGWIN__
 | |
|     check_cygwin_console();
 | |
| #endif
 | |
|     TerminalGet(tty, &d_ioval);
 | |
|     if (displayTitleTerm != NULL) {
 | |
| 	struct w3m_term_info *p;
 | |
| 	for (p = w3m_term_info_list; p->term != NULL; p++) {
 | |
| 	    if (!strncmp(displayTitleTerm, p->term, strlen(p->term))) {
 | |
| 		title_str = p->title_str;
 | |
| 		break;
 | |
| 	    }
 | |
| 	}
 | |
|     }
 | |
| #ifdef USE_MOUSE
 | |
|     {
 | |
| 	char *term = getenv("TERM");
 | |
| 	if (term != NULL) {
 | |
| 	    struct w3m_term_info *p;
 | |
| 	    for (p = w3m_term_info_list; p->term != NULL; p++) {
 | |
| 		if (!strncmp(term, p->term, strlen(p->term))) {
 | |
| 			is_xterm = p->mouse_flag;
 | |
| 			break;
 | |
| 		    }
 | |
| 		}
 | |
| 	}
 | |
|     }
 | |
| #endif
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| void
 | |
| ttymode_set(int mode, int imode)
 | |
| {
 | |
| #ifndef __MINGW32_VERSION
 | |
|     TerminalMode ioval;
 | |
| 
 | |
|     TerminalGet(tty, &ioval);
 | |
|     MODEFLAG(ioval) |= mode;
 | |
| #ifndef HAVE_SGTTY_H
 | |
|     IMODEFLAG(ioval) |= imode;
 | |
| #endif				/* not HAVE_SGTTY_H */
 | |
| 
 | |
|     while (TerminalSet(tty, &ioval) == -1) {
 | |
| 	if (errno == EINTR || errno == EAGAIN)
 | |
| 	    continue;
 | |
| 	printf("Error occured while set %x: errno=%d\n", mode, errno);
 | |
| 	reset_error_exit(SIGNAL_ARGLIST);
 | |
|     }
 | |
| #endif
 | |
| }
 | |
| 
 | |
| void
 | |
| ttymode_reset(int mode, int imode)
 | |
| {
 | |
| #ifndef __MINGW32_VERSION
 | |
|     TerminalMode ioval;
 | |
| 
 | |
|     TerminalGet(tty, &ioval);
 | |
|     MODEFLAG(ioval) &= ~mode;
 | |
| #ifndef HAVE_SGTTY_H
 | |
|     IMODEFLAG(ioval) &= ~imode;
 | |
| #endif				/* not HAVE_SGTTY_H */
 | |
| 
 | |
|     while (TerminalSet(tty, &ioval) == -1) {
 | |
| 	if (errno == EINTR || errno == EAGAIN)
 | |
| 	    continue;
 | |
| 	printf("Error occured while reset %x: errno=%d\n", mode, errno);
 | |
| 	reset_error_exit(SIGNAL_ARGLIST);
 | |
|     }
 | |
| #endif /* __MINGW32_VERSION */
 | |
| }
 | |
| 
 | |
| #ifndef HAVE_SGTTY_H
 | |
| void
 | |
| set_cc(int spec, int val)
 | |
| {
 | |
|     TerminalMode ioval;
 | |
| 
 | |
|     TerminalGet(tty, &ioval);
 | |
|     ioval.c_cc[spec] = val;
 | |
|     while (TerminalSet(tty, &ioval) == -1) {
 | |
| 	if (errno == EINTR || errno == EAGAIN)
 | |
| 	    continue;
 | |
| 	printf("Error occured: errno=%d\n", errno);
 | |
| 	reset_error_exit(SIGNAL_ARGLIST);
 | |
|     }
 | |
| }
 | |
| #endif				/* not HAVE_SGTTY_H */
 | |
| 
 | |
| void
 | |
| close_tty(void)
 | |
| {
 | |
|     if (tty > 2)
 | |
| 	close(tty);
 | |
| }
 | |
| 
 | |
| char *
 | |
| ttyname_tty(void)
 | |
| {
 | |
|     return ttyname(tty);
 | |
| }
 | |
| 
 | |
| void
 | |
| reset_tty(void)
 | |
| {
 | |
|     writestr(T_op);		/* turn off */
 | |
|     writestr(T_me);
 | |
|     if (!Do_not_use_ti_te) {
 | |
| 	if (T_te && *T_te)
 | |
| 	    writestr(T_te);
 | |
| 	else
 | |
| 	    writestr(T_cl);
 | |
|     }
 | |
|     writestr(T_se);		/* reset terminal */
 | |
|     flush_tty();
 | |
|     TerminalSet(tty, &d_ioval);
 | |
|     if (tty != 2)
 | |
|         close_tty();
 | |
| }
 | |
| 
 | |
| static MySignalHandler
 | |
| reset_exit_with_value(SIGNAL_ARG, int rval)
 | |
| {
 | |
| #ifdef USE_MOUSE
 | |
|     if (mouseActive)
 | |
| 	mouse_end();
 | |
| #endif				/* USE_MOUSE */
 | |
|     reset_tty();
 | |
|     w3m_exit(rval);
 | |
|     SIGNAL_RETURN;
 | |
| }
 | |
| 
 | |
| MySignalHandler
 | |
| reset_error_exit(SIGNAL_ARG)
 | |
| {
 | |
|   reset_exit_with_value(SIGNAL_ARGLIST, 1);
 | |
| }
 | |
| 
 | |
| MySignalHandler
 | |
| reset_exit(SIGNAL_ARG)
 | |
| {
 | |
|   reset_exit_with_value(SIGNAL_ARGLIST, 0);
 | |
| }
 | |
| 
 | |
| MySignalHandler
 | |
| error_dump(SIGNAL_ARG)
 | |
| {
 | |
|     mySignal(SIGIOT, SIG_DFL);
 | |
|     reset_tty();
 | |
|     abort();
 | |
|     SIGNAL_RETURN;
 | |
| }
 | |
| 
 | |
| void
 | |
| set_int(void)
 | |
| {
 | |
|     mySignal(SIGHUP, reset_exit);
 | |
|     mySignal(SIGINT, reset_exit);
 | |
|     mySignal(SIGQUIT, reset_exit);
 | |
|     mySignal(SIGTERM, reset_exit);
 | |
|     mySignal(SIGILL, error_dump);
 | |
|     mySignal(SIGIOT, error_dump);
 | |
|     mySignal(SIGFPE, error_dump);
 | |
| #ifdef	SIGBUS
 | |
|     mySignal(SIGBUS, error_dump);
 | |
| #endif				/* SIGBUS */
 | |
|     /* mySignal(SIGSEGV, error_dump); */
 | |
| }
 | |
| 
 | |
| 
 | |
| static void
 | |
| setgraphchar(void)
 | |
| {
 | |
|     int c, i, n;
 | |
| 
 | |
|     for (c = 0; c < 96; c++)
 | |
| 	gcmap[c] = (char)(c + ' ');
 | |
| 
 | |
|     if (!T_ac)
 | |
| 	return;
 | |
| 
 | |
|     n = strlen(T_ac);
 | |
|     for (i = 0; i < n - 1; i += 2) {
 | |
| 	c = (unsigned)T_ac[i] - ' ';
 | |
| 	if (c >= 0 && c < 96)
 | |
| 	    gcmap[c] = T_ac[i + 1];
 | |
|     }
 | |
| }
 | |
| 
 | |
| #define graphchar(c) (((unsigned)(c)>=' ' && (unsigned)(c)<128)? gcmap[(c)-' '] : (c))
 | |
| #define GETSTR(v,s) {v = pt; suc = tgetstr(s,&pt); if (!suc) v = ""; else v = allocStr(suc, -1); }
 | |
| 
 | |
| void
 | |
| getTCstr(void)
 | |
| {
 | |
|     char *ent;
 | |
|     char *suc;
 | |
|     char *pt = funcstr;
 | |
|     int r;
 | |
| 
 | |
|     ent = getenv("TERM") ? getenv("TERM") : DEFAULT_TERM;
 | |
|     if (ent == NULL) {
 | |
| 	fprintf(stderr, "TERM is not set\n");
 | |
| 	reset_error_exit(SIGNAL_ARGLIST);
 | |
|     }
 | |
| 
 | |
|     r = tgetent(bp, ent);
 | |
|     if (r != 1) {
 | |
| 	/* Can't find termcap entry */
 | |
| 	fprintf(stderr, "Can't find termcap entry %s\n", ent);
 | |
| 	reset_error_exit(SIGNAL_ARGLIST);
 | |
|     }
 | |
| 
 | |
|     GETSTR(T_ce, "ce");		/* clear to the end of line */
 | |
|     GETSTR(T_cd, "cd");		/* clear to the end of display */
 | |
|     GETSTR(T_kr, "nd");		/* cursor right */
 | |
|     if (suc == NULL)
 | |
| 	GETSTR(T_kr, "kr");
 | |
|     if (tgetflag("bs"))
 | |
| 	T_kl = "\b";		/* cursor left */
 | |
|     else {
 | |
| 	GETSTR(T_kl, "le");
 | |
| 	if (suc == NULL)
 | |
| 	    GETSTR(T_kl, "kb");
 | |
| 	if (suc == NULL)
 | |
| 	    GETSTR(T_kl, "kl");
 | |
|     }
 | |
|     GETSTR(T_cr, "cr");		/* carriage return */
 | |
|     GETSTR(T_ta, "ta");		/* tab */
 | |
|     GETSTR(T_sc, "sc");		/* save cursor */
 | |
|     GETSTR(T_rc, "rc");		/* restore cursor */
 | |
|     GETSTR(T_so, "so");		/* standout mode */
 | |
|     GETSTR(T_se, "se");		/* standout mode end */
 | |
|     GETSTR(T_us, "us");		/* underline mode */
 | |
|     GETSTR(T_ue, "ue");		/* underline mode end */
 | |
|     GETSTR(T_md, "md");		/* bold mode */
 | |
|     GETSTR(T_me, "me");		/* bold mode end */
 | |
|     GETSTR(T_cl, "cl");		/* clear screen */
 | |
|     GETSTR(T_cm, "cm");		/* cursor move */
 | |
|     GETSTR(T_al, "al");		/* append line */
 | |
|     GETSTR(T_sr, "sr");		/* scroll reverse */
 | |
|     GETSTR(T_ti, "ti");		/* terminal init */
 | |
|     GETSTR(T_te, "te");		/* terminal end */
 | |
|     GETSTR(T_nd, "nd");		/* move right one space */
 | |
|     GETSTR(T_eA, "eA");		/* enable alternative charset */
 | |
|     GETSTR(T_as, "as");		/* alternative (graphic) charset start */
 | |
|     GETSTR(T_ae, "ae");		/* alternative (graphic) charset end */
 | |
|     GETSTR(T_ac, "ac");		/* graphics charset pairs */
 | |
|     GETSTR(T_op, "op");		/* set default color pair to its original value */
 | |
| #if defined( CYGWIN ) && CYGWIN < 1
 | |
|     /* for TERM=pcansi on MS-DOS prompt. */
 | |
| #if 0
 | |
|     T_eA = "";
 | |
|     T_as = "\033[12m";
 | |
|     T_ae = "\033[10m";
 | |
|     T_ac = "l\001k\002m\003j\004x\005q\006n\020a\024v\025w\026u\027t\031";
 | |
| #endif
 | |
|     T_eA = "";
 | |
|     T_as = "";
 | |
|     T_ae = "";
 | |
|     T_ac = "";
 | |
| #endif				/* CYGWIN */
 | |
| 
 | |
|     LINES = COLS = 0;
 | |
|     setlinescols();
 | |
|     setgraphchar();
 | |
| }
 | |
| 
 | |
| void
 | |
| setlinescols(void)
 | |
| {
 | |
|     char *p;
 | |
|     int i;
 | |
| #ifdef __EMX__
 | |
|     {
 | |
| 	int s[2];
 | |
| 	_scrsize(s);
 | |
| 	COLS = s[0];
 | |
| 	LINES = s[1];
 | |
| 
 | |
| 	if (getenv("WINDOWID")) {
 | |
| 	    FILE *fd = popen("scrsize", "rt");
 | |
| 	    if (fd) {
 | |
| 		fscanf(fd, "%i %i", &COLS, &LINES);
 | |
| 		pclose(fd);
 | |
| 	    }
 | |
| 	}
 | |
|     }
 | |
| #elif defined(HAVE_TERMIOS_H) && defined(TIOCGWINSZ)
 | |
|     struct winsize wins;
 | |
| 
 | |
|     i = ioctl(tty, TIOCGWINSZ, &wins);
 | |
|     if (i >= 0 && wins.ws_row != 0 && wins.ws_col != 0) {
 | |
| 	LINES = wins.ws_row;
 | |
| 	COLS = wins.ws_col;
 | |
|     }
 | |
| #endif				/* defined(HAVE-TERMIOS_H) && defined(TIOCGWINSZ) */
 | |
|     if (LINES <= 0 && (p = getenv("LINES")) != NULL && (i = atoi(p)) >= 0)
 | |
| 	LINES = i;
 | |
|     if (COLS <= 0 && (p = getenv("COLUMNS")) != NULL && (i = atoi(p)) >= 0)
 | |
| 	COLS = i;
 | |
|     if (LINES <= 0)
 | |
| 	LINES = tgetnum("li");	/* number of line */
 | |
|     if (COLS <= 0)
 | |
| 	COLS = tgetnum("co");	/* number of column */
 | |
|     if (COLS > MAX_COLUMN)
 | |
| 	COLS = MAX_COLUMN;
 | |
|     if (LINES > MAX_LINE)
 | |
| 	LINES = MAX_LINE;
 | |
| #if defined(__CYGWIN__)
 | |
|     LASTLINE = LINES - (isWinConsole == TERM_CYGWIN_RESERVE_IME ? 2 : 1);
 | |
| #endif				/* defined(__CYGWIN__) */
 | |
| }
 | |
| 
 | |
| void
 | |
| setupscreen(void)
 | |
| {
 | |
|     int i;
 | |
| 
 | |
|     if (LINES + 1 > max_LINES) {
 | |
| 	max_LINES = LINES + 1;
 | |
| 	max_COLS = 0;
 | |
| 	ScreenElem = New_N(Screen, max_LINES);
 | |
| 	ScreenImage = New_N(Screen *, max_LINES);
 | |
|     }
 | |
|     if (COLS + 1 > max_COLS) {
 | |
| 	max_COLS = COLS + 1;
 | |
| 	for (i = 0; i < max_LINES; i++) {
 | |
| #ifdef USE_M17N
 | |
| 	    ScreenElem[i].lineimage = New_N(char *, max_COLS);
 | |
| 	    bzero((void *)ScreenElem[i].lineimage, max_COLS * sizeof(char *));
 | |
| #else
 | |
| 	    ScreenElem[i].lineimage = New_N(char, max_COLS);
 | |
| #endif
 | |
| 	    ScreenElem[i].lineprop = New_N(l_prop, max_COLS);
 | |
| 	}
 | |
|     }
 | |
|     for (i = 0; i < LINES; i++) {
 | |
| 	ScreenImage[i] = &ScreenElem[i];
 | |
| 	ScreenImage[i]->lineprop[0] = S_EOL;
 | |
| 	ScreenImage[i]->isdirty = 0;
 | |
|     }
 | |
|     for (; i < max_LINES; i++) {
 | |
| 	ScreenElem[i].isdirty = L_UNUSED;
 | |
|     }
 | |
| 
 | |
|     clear();
 | |
| }
 | |
| 
 | |
| /* 
 | |
|  * Screen initialize
 | |
|  */
 | |
| int
 | |
| initscr(void)
 | |
| {
 | |
|     if (set_tty() < 0)
 | |
| 	return -1;
 | |
|     set_int();
 | |
|     getTCstr();
 | |
|     if (T_ti && !Do_not_use_ti_te)
 | |
| 	writestr(T_ti);
 | |
|     setupscreen();
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| static int
 | |
| write1(char c)
 | |
| {
 | |
|     putc(c, ttyf);
 | |
| #ifdef SCREEN_DEBUG
 | |
|     flush_tty();
 | |
| #endif				/* SCREEN_DEBUG */
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| void
 | |
| move(int line, int column)
 | |
| {
 | |
|     if (line >= 0 && line < LINES)
 | |
| 	CurLine = line;
 | |
|     if (column >= 0 && column < COLS)
 | |
| 	CurColumn = column;
 | |
| }
 | |
| 
 | |
| #ifdef USE_BG_COLOR
 | |
| #define M_SPACE (S_SCREENPROP|S_COLORED|S_BCOLORED|S_GRAPHICS)
 | |
| #else				/* not USE_BG_COLOR */
 | |
| #define M_SPACE (S_SCREENPROP|S_COLORED|S_GRAPHICS)
 | |
| #endif				/* not USE_BG_COLOR */
 | |
| 
 | |
| static int
 | |
| #ifdef USE_M17N
 | |
| need_redraw(char *c1, l_prop pr1, char *c2, l_prop pr2)
 | |
| {
 | |
|     if (!c1 || !c2 || strcmp(c1, c2))
 | |
| 	return 1;
 | |
|     if (*c1 == ' ')
 | |
| #else
 | |
| need_redraw(char c1, l_prop pr1, char c2, l_prop pr2)
 | |
| {
 | |
|     if (c1 != c2)
 | |
| 	return 1;
 | |
|     if (c1 == ' ')
 | |
| #endif
 | |
| 	return (pr1 ^ pr2) & M_SPACE & ~S_DIRTY;
 | |
| 
 | |
|     if ((pr1 ^ pr2) & ~S_DIRTY)
 | |
| 	return 1;
 | |
| 
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| #define M_CEOL (~(M_SPACE|C_WHICHCHAR))
 | |
| 
 | |
| #ifdef USE_M17N
 | |
| #define SPACE " "
 | |
| #else
 | |
| #define SPACE ' '
 | |
| #endif
 | |
| 
 | |
| #ifdef USE_M17N
 | |
| void
 | |
| addch(char c)
 | |
| {
 | |
|     addmch(&c, 1);
 | |
| }
 | |
| 
 | |
| void
 | |
| addmch(char *pc, size_t len)
 | |
| #else
 | |
| void
 | |
| addch(char pc)
 | |
| #endif
 | |
| {
 | |
|     l_prop *pr;
 | |
|     int dest, i;
 | |
| #ifdef USE_M17N
 | |
|     static Str tmp = NULL;
 | |
|     char **p;
 | |
|     char c = *pc;
 | |
|     int width = wtf_width((wc_uchar *) pc);
 | |
| 
 | |
|     if (tmp == NULL)
 | |
| 	tmp = Strnew();
 | |
|     Strcopy_charp_n(tmp, pc, len);
 | |
|     pc = tmp->ptr;
 | |
| #else
 | |
|     char *p;
 | |
|     char c = pc;
 | |
| #endif
 | |
| 
 | |
|     if (CurColumn == COLS)
 | |
| 	wrap();
 | |
|     if (CurColumn >= COLS)
 | |
| 	return;
 | |
|     p = ScreenImage[CurLine]->lineimage;
 | |
|     pr = ScreenImage[CurLine]->lineprop;
 | |
| 
 | |
| #ifndef USE_M17N
 | |
|     /* Eliminate unprintables according to * iso-8859-*.
 | |
|      * Particularly 0x96 messes up T.Dickey's * (xfree-)xterm */
 | |
|     if (IS_INTSPACE(c))
 | |
| 	c = ' ';
 | |
| #endif
 | |
| 
 | |
|     if (pr[CurColumn] & S_EOL) {
 | |
| 	if (c == ' ' && !(CurrentMode & M_SPACE)) {
 | |
| 	    CurColumn++;
 | |
| 	    return;
 | |
| 	}
 | |
| 	for (i = CurColumn; i >= 0 && (pr[i] & S_EOL); i--) {
 | |
| 	    SETCH(p[i], SPACE, 1);
 | |
| 	    SETPROP(pr[i], (pr[i] & M_CEOL) | C_ASCII);
 | |
| 	}
 | |
|     }
 | |
| 
 | |
|     if (c == '\t' || c == '\n' || c == '\r' || c == '\b')
 | |
| 	SETCHMODE(CurrentMode, C_CTRL);
 | |
| #ifdef USE_M17N
 | |
|     else if (len > 1)
 | |
| 	SETCHMODE(CurrentMode, C_WCHAR1);
 | |
| #endif
 | |
|     else if (!IS_CNTRL(c))
 | |
| 	SETCHMODE(CurrentMode, C_ASCII);
 | |
|     else
 | |
| 	return;
 | |
| 
 | |
|     /* Required to erase bold or underlined character for some * terminal
 | |
|      * emulators. */
 | |
| #ifdef USE_M17N
 | |
|     i = CurColumn + width - 1;
 | |
| #else
 | |
|     i = CurColumn;
 | |
| #endif
 | |
|     if (i < COLS &&
 | |
| 	(((pr[i] & S_BOLD) && need_redraw(p[i], pr[i], pc, CurrentMode)) ||
 | |
| 	 ((pr[i] & S_UNDERLINE) && !(CurrentMode & S_UNDERLINE)))) {
 | |
| 	touch_line();
 | |
| 	i++;
 | |
| 	if (i < COLS) {
 | |
| 	    touch_column(i);
 | |
| 	    if (pr[i] & S_EOL) {
 | |
| 		SETCH(p[i], SPACE, 1);
 | |
| 		SETPROP(pr[i], (pr[i] & M_CEOL) | C_ASCII);
 | |
| 	    }
 | |
| #ifdef USE_M17N
 | |
| 	    else {
 | |
| 		for (i++; i < COLS && CHMODE(pr[i]) == C_WCHAR2; i++)
 | |
| 		    touch_column(i);
 | |
| 	    }
 | |
| #endif
 | |
| 	}
 | |
|     }
 | |
| 
 | |
| #ifdef USE_M17N
 | |
|     if (CurColumn + width > COLS) {
 | |
| 	touch_line();
 | |
| 	for (i = CurColumn; i < COLS; i++) {
 | |
| 	    SETCH(p[i], SPACE, 1);
 | |
| 	    SETPROP(pr[i], (pr[i] & ~C_WHICHCHAR) | C_ASCII);
 | |
| 	    touch_column(i);
 | |
| 	}
 | |
| 	wrap();
 | |
| 	if (CurColumn + width > COLS)
 | |
| 	    return;
 | |
| 	p = ScreenImage[CurLine]->lineimage;
 | |
| 	pr = ScreenImage[CurLine]->lineprop;
 | |
|     }
 | |
|     if (CHMODE(pr[CurColumn]) == C_WCHAR2) {
 | |
| 	touch_line();
 | |
| 	for (i = CurColumn - 1; i >= 0; i--) {
 | |
| 	    l_prop l = CHMODE(pr[i]);
 | |
| 	    SETCH(p[i], SPACE, 1);
 | |
| 	    SETPROP(pr[i], (pr[i] & ~C_WHICHCHAR) | C_ASCII);
 | |
| 	    touch_column(i);
 | |
| 	    if (l != C_WCHAR2)
 | |
| 		break;
 | |
| 	}
 | |
|     }
 | |
| #endif
 | |
|     if (CHMODE(CurrentMode) != C_CTRL) {
 | |
| 	if (need_redraw(p[CurColumn], pr[CurColumn], pc, CurrentMode)) {
 | |
| 	    SETCH(p[CurColumn], pc, len);
 | |
| 	    SETPROP(pr[CurColumn], CurrentMode);
 | |
| 	    touch_line();
 | |
| 	    touch_column(CurColumn);
 | |
| #ifdef USE_M17N
 | |
| 	    SETCHMODE(CurrentMode, C_WCHAR2);
 | |
| 	    for (i = CurColumn + 1; i < CurColumn + width; i++) {
 | |
| 		SETCH(p[i], SPACE, 1);
 | |
| 		SETPROP(pr[i], (pr[CurColumn] & ~C_WHICHCHAR) | C_WCHAR2);
 | |
| 		touch_column(i);
 | |
| 	    }
 | |
| 	    for (; i < COLS && CHMODE(pr[i]) == C_WCHAR2; i++) {
 | |
| 		SETCH(p[i], SPACE, 1);
 | |
| 		SETPROP(pr[i], (pr[i] & ~C_WHICHCHAR) | C_ASCII);
 | |
| 		touch_column(i);
 | |
| 	    }
 | |
| 	}
 | |
| 	CurColumn += width;
 | |
| #else
 | |
| 	}
 | |
| 	CurColumn++;
 | |
| #endif
 | |
|     }
 | |
|     else if (c == '\t') {
 | |
| 	dest = (CurColumn + tab_step) / tab_step * tab_step;
 | |
| 	if (dest >= COLS) {
 | |
| 	    wrap();
 | |
| 	    touch_line();
 | |
| 	    dest = tab_step;
 | |
| 	    p = ScreenImage[CurLine]->lineimage;
 | |
| 	    pr = ScreenImage[CurLine]->lineprop;
 | |
| 	}
 | |
| 	for (i = CurColumn; i < dest; i++) {
 | |
| 	    if (need_redraw(p[i], pr[i], SPACE, CurrentMode)) {
 | |
| 		SETCH(p[i], SPACE, 1);
 | |
| 		SETPROP(pr[i], CurrentMode);
 | |
| 		touch_line();
 | |
| 		touch_column(i);
 | |
| 	    }
 | |
| 	}
 | |
| 	CurColumn = i;
 | |
|     }
 | |
|     else if (c == '\n') {
 | |
| 	wrap();
 | |
|     }
 | |
|     else if (c == '\r') {	/* Carriage return */
 | |
| 	CurColumn = 0;
 | |
|     }
 | |
|     else if (c == '\b' && CurColumn > 0) {	/* Backspace */
 | |
| 	CurColumn--;
 | |
| #ifdef USE_M17N
 | |
| 	while (CurColumn > 0 && CHMODE(pr[CurColumn]) == C_WCHAR2)
 | |
| 	    CurColumn--;
 | |
| #endif
 | |
|     }
 | |
| }
 | |
| 
 | |
| void
 | |
| wrap(void)
 | |
| {
 | |
|     if (CurLine == LASTLINE)
 | |
| 	return;
 | |
|     CurLine++;
 | |
|     CurColumn = 0;
 | |
| }
 | |
| 
 | |
| void
 | |
| touch_column(int col)
 | |
| {
 | |
|     if (col >= 0 && col < COLS)
 | |
| 	ScreenImage[CurLine]->lineprop[col] |= S_DIRTY;
 | |
| }
 | |
| 
 | |
| void
 | |
| touch_line(void)
 | |
| {
 | |
|     if (!(ScreenImage[CurLine]->isdirty & L_DIRTY)) {
 | |
| 	int i;
 | |
| 	for (i = 0; i < COLS; i++)
 | |
| 	    ScreenImage[CurLine]->lineprop[i] &= ~S_DIRTY;
 | |
| 	ScreenImage[CurLine]->isdirty |= L_DIRTY;
 | |
|     }
 | |
| 
 | |
| }
 | |
| 
 | |
| void
 | |
| standout(void)
 | |
| {
 | |
|     CurrentMode |= S_STANDOUT;
 | |
| }
 | |
| 
 | |
| void
 | |
| standend(void)
 | |
| {
 | |
|     CurrentMode &= ~S_STANDOUT;
 | |
| }
 | |
| 
 | |
| void
 | |
| toggle_stand(void)
 | |
| {
 | |
| #ifdef USE_M17N
 | |
|     int i;
 | |
| #endif
 | |
|     l_prop *pr = ScreenImage[CurLine]->lineprop;
 | |
|     pr[CurColumn] ^= S_STANDOUT;
 | |
| #ifdef USE_M17N
 | |
|     if (CHMODE(pr[CurColumn]) != C_WCHAR2) {
 | |
| 	for (i = CurColumn + 1; CHMODE(pr[i]) == C_WCHAR2; i++)
 | |
| 	    pr[i] ^= S_STANDOUT;
 | |
|     }
 | |
| #endif
 | |
| }
 | |
| 
 | |
| void
 | |
| bold(void)
 | |
| {
 | |
|     CurrentMode |= S_BOLD;
 | |
| }
 | |
| 
 | |
| void
 | |
| boldend(void)
 | |
| {
 | |
|     CurrentMode &= ~S_BOLD;
 | |
| }
 | |
| 
 | |
| void
 | |
| underline(void)
 | |
| {
 | |
|     CurrentMode |= S_UNDERLINE;
 | |
| }
 | |
| 
 | |
| void
 | |
| underlineend(void)
 | |
| {
 | |
|     CurrentMode &= ~S_UNDERLINE;
 | |
| }
 | |
| 
 | |
| void
 | |
| graphstart(void)
 | |
| {
 | |
|     CurrentMode |= S_GRAPHICS;
 | |
| }
 | |
| 
 | |
| void
 | |
| graphend(void)
 | |
| {
 | |
|     CurrentMode &= ~S_GRAPHICS;
 | |
| }
 | |
| 
 | |
| int
 | |
| graph_ok(void)
 | |
| {
 | |
|     if (UseGraphicChar != GRAPHIC_CHAR_DEC)
 | |
| 	return 0;
 | |
|     return T_as[0] != 0 && T_ae[0] != 0 && T_ac[0] != 0;
 | |
| }
 | |
| 
 | |
| void
 | |
| setfcolor(int color)
 | |
| {
 | |
|     CurrentMode &= ~COL_FCOLOR;
 | |
|     if ((color & 0xf) <= 7)
 | |
| 	CurrentMode |= (((color & 7) | 8) << 8);
 | |
| }
 | |
| 
 | |
| static char *
 | |
| color_seq(int colmode)
 | |
| {
 | |
|     static char seqbuf[32];
 | |
|     sprintf(seqbuf, "\033[%dm", ((colmode >> 8) & 7) + 30);
 | |
|     return seqbuf;
 | |
| }
 | |
| 
 | |
| #ifdef USE_BG_COLOR
 | |
| void
 | |
| setbcolor(int color)
 | |
| {
 | |
|     CurrentMode &= ~COL_BCOLOR;
 | |
|     if ((color & 0xf) <= 7)
 | |
| 	CurrentMode |= (((color & 7) | 8) << 12);
 | |
| }
 | |
| 
 | |
| static char *
 | |
| bcolor_seq(int colmode)
 | |
| {
 | |
|     static char seqbuf[32];
 | |
|     sprintf(seqbuf, "\033[%dm", ((colmode >> 12) & 7) + 40);
 | |
|     return seqbuf;
 | |
| }
 | |
| #endif				/* USE_BG_COLOR */
 | |
| 
 | |
| #define RF_NEED_TO_MOVE    0
 | |
| #define RF_CR_OK           1
 | |
| #define RF_NONEED_TO_MOVE  2
 | |
| #ifdef USE_BG_COLOR
 | |
| #define M_MEND (S_STANDOUT|S_UNDERLINE|S_BOLD|S_COLORED|S_BCOLORED|S_GRAPHICS)
 | |
| #else				/* not USE_BG_COLOR */
 | |
| #define M_MEND (S_STANDOUT|S_UNDERLINE|S_BOLD|S_COLORED|S_GRAPHICS)
 | |
| #endif				/* not USE_BG_COLOR */
 | |
| void
 | |
| refresh(void)
 | |
| {
 | |
|     int line, col, pcol;
 | |
|     int pline = CurLine;
 | |
|     int moved = RF_NEED_TO_MOVE;
 | |
| #ifdef USE_M17N
 | |
|     char **pc;
 | |
| #else
 | |
|     char *pc;
 | |
| #endif
 | |
|     l_prop *pr, mode = 0;
 | |
|     l_prop color = COL_FTERM;
 | |
| #ifdef USE_BG_COLOR
 | |
|     l_prop bcolor = COL_BTERM;
 | |
| #endif				/* USE_BG_COLOR */
 | |
|     short *dirty;
 | |
| 
 | |
| #ifdef USE_M17N
 | |
|     wc_putc_init(InnerCharset, DisplayCharset);
 | |
| #endif
 | |
|     for (line = 0; line <= LASTLINE; line++) {
 | |
| 	dirty = &ScreenImage[line]->isdirty;
 | |
| 	if (*dirty & L_DIRTY) {
 | |
| 	    *dirty &= ~L_DIRTY;
 | |
| 	    pc = ScreenImage[line]->lineimage;
 | |
| 	    pr = ScreenImage[line]->lineprop;
 | |
| 	    for (col = 0; col < COLS && !(pr[col] & S_EOL); col++) {
 | |
| 		if (*dirty & L_NEED_CE && col >= ScreenImage[line]->eol) {
 | |
| 		    if (need_redraw(pc[col], pr[col], SPACE, 0))
 | |
| 			break;
 | |
| 		}
 | |
| 		else {
 | |
| 		    if (pr[col] & S_DIRTY)
 | |
| 			break;
 | |
| 		}
 | |
| 	    }
 | |
| 	    if (*dirty & (L_NEED_CE | L_CLRTOEOL)) {
 | |
| 		pcol = ScreenImage[line]->eol;
 | |
| 		if (pcol >= COLS) {
 | |
| 		    *dirty &= ~(L_NEED_CE | L_CLRTOEOL);
 | |
| 		    pcol = col;
 | |
| 		}
 | |
| 	    }
 | |
| 	    else {
 | |
| 		pcol = col;
 | |
| 	    }
 | |
| 	    if (line < LINES - 2 && pline == line - 1 && pcol == 0) {
 | |
| 		switch (moved) {
 | |
| 		case RF_NEED_TO_MOVE:
 | |
| 		    MOVE(line, 0);
 | |
| 		    moved = RF_CR_OK;
 | |
| 		    break;
 | |
| 		case RF_CR_OK:
 | |
| 		    write1('\n');
 | |
| 		    write1('\r');
 | |
| 		    break;
 | |
| 		case RF_NONEED_TO_MOVE:
 | |
| 		    moved = RF_CR_OK;
 | |
| 		    break;
 | |
| 		}
 | |
| 	    }
 | |
| 	    else {
 | |
| 		MOVE(line, pcol);
 | |
| 		moved = RF_CR_OK;
 | |
| 	    }
 | |
| 	    if (*dirty & (L_NEED_CE | L_CLRTOEOL)) {
 | |
| 		writestr(T_ce);
 | |
| 		if (col != pcol)
 | |
| 		    MOVE(line, col);
 | |
| 	    }
 | |
| 	    pline = line;
 | |
| 	    pcol = col;
 | |
| 	    for (; col < COLS; col++) {
 | |
| 		if (pr[col] & S_EOL)
 | |
| 		    break;
 | |
| 
 | |
| 		/* 
 | |
| 		 * some terminal emulators do linefeed when a
 | |
| 		 * character is put on COLS-th column. this behavior
 | |
| 		 * is different from one of vt100, but such terminal
 | |
| 		 * emulators are used as vt100-compatible
 | |
| 		 * emulators. This behaviour causes scroll when a
 | |
| 		 * character is drawn on (COLS-1,LINES-1) point.  To
 | |
| 		 * avoid the scroll, I prohibit to draw character on
 | |
| 		 * (COLS-1,LINES-1).
 | |
| 		 */
 | |
| #if !defined(USE_BG_COLOR) || defined(__CYGWIN__)
 | |
| #ifdef __CYGWIN__
 | |
| 		if (isWinConsole)
 | |
| #endif
 | |
| 		    if (line == LINES - 1 && col == COLS - 1)
 | |
| 			break;
 | |
| #endif				/* !defined(USE_BG_COLOR) || defined(__CYGWIN__) */
 | |
| 		if ((!(pr[col] & S_STANDOUT) && (mode & S_STANDOUT)) ||
 | |
| 		    (!(pr[col] & S_UNDERLINE) && (mode & S_UNDERLINE)) ||
 | |
| 		    (!(pr[col] & S_BOLD) && (mode & S_BOLD)) ||
 | |
| 		    (!(pr[col] & S_COLORED) && (mode & S_COLORED))
 | |
| #ifdef USE_BG_COLOR
 | |
| 		    || (!(pr[col] & S_BCOLORED) && (mode & S_BCOLORED))
 | |
| #endif				/* USE_BG_COLOR */
 | |
| 		    || (!(pr[col] & S_GRAPHICS) && (mode & S_GRAPHICS))) {
 | |
| 		    if ((mode & S_COLORED)
 | |
| #ifdef USE_BG_COLOR
 | |
| 			|| (mode & S_BCOLORED)
 | |
| #endif				/* USE_BG_COLOR */
 | |
| 			)
 | |
| 			writestr(T_op);
 | |
| 		    if (mode & S_GRAPHICS)
 | |
| 			writestr(T_ae);
 | |
| 		    writestr(T_me);
 | |
| 		    mode &= ~M_MEND;
 | |
| 		}
 | |
| 		if ((*dirty & L_NEED_CE && col >= ScreenImage[line]->eol) ?
 | |
| 		    need_redraw(pc[col], pr[col], SPACE,
 | |
| 				0) : (pr[col] & S_DIRTY)) {
 | |
| 		    if (pcol == col - 1)
 | |
| 			writestr(T_nd);
 | |
| 		    else if (pcol != col)
 | |
| 			MOVE(line, col);
 | |
| 
 | |
| 		    if ((pr[col] & S_STANDOUT) && !(mode & S_STANDOUT)) {
 | |
| 			writestr(T_so);
 | |
| 			mode |= S_STANDOUT;
 | |
| 		    }
 | |
| 		    if ((pr[col] & S_UNDERLINE) && !(mode & S_UNDERLINE)) {
 | |
| 			writestr(T_us);
 | |
| 			mode |= S_UNDERLINE;
 | |
| 		    }
 | |
| 		    if ((pr[col] & S_BOLD) && !(mode & S_BOLD)) {
 | |
| 			writestr(T_md);
 | |
| 			mode |= S_BOLD;
 | |
| 		    }
 | |
| 		    if ((pr[col] & S_COLORED) && (pr[col] ^ mode) & COL_FCOLOR) {
 | |
| 			color = (pr[col] & COL_FCOLOR);
 | |
| 			mode = ((mode & ~COL_FCOLOR) | color);
 | |
| 			writestr(color_seq(color));
 | |
| 		    }
 | |
| #ifdef USE_BG_COLOR
 | |
| 		    if ((pr[col] & S_BCOLORED)
 | |
| 			&& (pr[col] ^ mode) & COL_BCOLOR) {
 | |
| 			bcolor = (pr[col] & COL_BCOLOR);
 | |
| 			mode = ((mode & ~COL_BCOLOR) | bcolor);
 | |
| 			writestr(bcolor_seq(bcolor));
 | |
| 		    }
 | |
| #endif				/* USE_BG_COLOR */
 | |
| 		    if ((pr[col] & S_GRAPHICS) && !(mode & S_GRAPHICS)) {
 | |
| #ifdef USE_M17N
 | |
| 			wc_putc_end(ttyf);
 | |
| #endif
 | |
| 			if (!graph_enabled) {
 | |
| 			    graph_enabled = 1;
 | |
| 			    writestr(T_eA);
 | |
| 			}
 | |
| 			writestr(T_as);
 | |
| 			mode |= S_GRAPHICS;
 | |
| 		    }
 | |
| #ifdef USE_M17N
 | |
| 		    if (pr[col] & S_GRAPHICS)
 | |
| 			write1(graphchar(*pc[col]));
 | |
| 		    else if (CHMODE(pr[col]) != C_WCHAR2)
 | |
| 			wc_putc(pc[col], ttyf);
 | |
| #else
 | |
| 		    write1((pr[col] & S_GRAPHICS) ? graphchar(pc[col]) :
 | |
| 			   pc[col]);
 | |
| #endif
 | |
| 		    pcol = col + 1;
 | |
| 		}
 | |
| 	    }
 | |
| 	    if (col == COLS)
 | |
| 		moved = RF_NEED_TO_MOVE;
 | |
| 	    for (; col < COLS && !(pr[col] & S_EOL); col++)
 | |
| 		pr[col] |= S_EOL;
 | |
| 	}
 | |
| 	*dirty &= ~(L_NEED_CE | L_CLRTOEOL);
 | |
| 	if (mode & M_MEND) {
 | |
| 	    if (mode & (S_COLORED
 | |
| #ifdef USE_BG_COLOR
 | |
| 			| S_BCOLORED
 | |
| #endif				/* USE_BG_COLOR */
 | |
| 		))
 | |
| 		writestr(T_op);
 | |
| 	    if (mode & S_GRAPHICS) {
 | |
| 		writestr(T_ae);
 | |
| #ifdef USE_M17N
 | |
| 		wc_putc_clear_status();
 | |
| #endif
 | |
| 	    }
 | |
| 	    writestr(T_me);
 | |
| 	    mode &= ~M_MEND;
 | |
| 	}
 | |
|     }
 | |
| #ifdef USE_M17N
 | |
|     wc_putc_end(ttyf);
 | |
| #endif
 | |
|     MOVE(CurLine, CurColumn);
 | |
|     flush_tty();
 | |
| }
 | |
| 
 | |
| void
 | |
| clear(void)
 | |
| {
 | |
|     int i, j;
 | |
|     l_prop *p;
 | |
|     writestr(T_cl);
 | |
|     move(0, 0);
 | |
|     for (i = 0; i < LINES; i++) {
 | |
| 	ScreenImage[i]->isdirty = 0;
 | |
| 	p = ScreenImage[i]->lineprop;
 | |
| 	for (j = 0; j < COLS; j++) {
 | |
| 	    p[j] = S_EOL;
 | |
| 	}
 | |
|     }
 | |
|     CurrentMode = C_ASCII;
 | |
| }
 | |
| 
 | |
| #ifdef USE_RAW_SCROLL
 | |
| static void
 | |
| scroll_raw(void)
 | |
| {				/* raw scroll */
 | |
|     MOVE(LINES - 1, 0);
 | |
|     write1('\n');
 | |
| }
 | |
| 
 | |
| void
 | |
| scroll(int n)
 | |
| {				/* scroll up */
 | |
|     int cli = CurLine, cco = CurColumn;
 | |
|     Screen *t;
 | |
|     int i, j, k;
 | |
| 
 | |
|     i = LINES;
 | |
|     j = n;
 | |
|     do {
 | |
| 	k = j;
 | |
| 	j = i % k;
 | |
| 	i = k;
 | |
|     } while (j);
 | |
|     do {
 | |
| 	k--;
 | |
| 	i = k;
 | |
| 	j = (i + n) % LINES;
 | |
| 	t = ScreenImage[k];
 | |
| 	while (j != k) {
 | |
| 	    ScreenImage[i] = ScreenImage[j];
 | |
| 	    i = j;
 | |
| 	    j = (i + n) % LINES;
 | |
| 	}
 | |
| 	ScreenImage[i] = t;
 | |
|     } while (k);
 | |
| 
 | |
|     for (i = 0; i < n; i++) {
 | |
| 	t = ScreenImage[LINES - 1 - i];
 | |
| 	t->isdirty = 0;
 | |
| 	for (j = 0; j < COLS; j++)
 | |
| 	    t->lineprop[j] = S_EOL;
 | |
| 	scroll_raw();
 | |
|     }
 | |
|     move(cli, cco);
 | |
| }
 | |
| 
 | |
| void
 | |
| rscroll(int n)
 | |
| {				/* scroll down */
 | |
|     int cli = CurLine, cco = CurColumn;
 | |
|     Screen *t;
 | |
|     int i, j, k;
 | |
| 
 | |
|     i = LINES;
 | |
|     j = n;
 | |
|     do {
 | |
| 	k = j;
 | |
| 	j = i % k;
 | |
| 	i = k;
 | |
|     } while (j);
 | |
|     do {
 | |
| 	k--;
 | |
| 	i = k;
 | |
| 	j = (LINES + i - n) % LINES;
 | |
| 	t = ScreenImage[k];
 | |
| 	while (j != k) {
 | |
| 	    ScreenImage[i] = ScreenImage[j];
 | |
| 	    i = j;
 | |
| 	    j = (LINES + i - n) % LINES;
 | |
| 	}
 | |
| 	ScreenImage[i] = t;
 | |
|     } while (k);
 | |
|     if (T_sr && *T_sr) {
 | |
| 	MOVE(0, 0);
 | |
| 	for (i = 0; i < n; i++) {
 | |
| 	    t = ScreenImage[i];
 | |
| 	    t->isdirty = 0;
 | |
| 	    for (j = 0; j < COLS; j++)
 | |
| 		t->lineprop[j] = S_EOL;
 | |
| 	    writestr(T_sr);
 | |
| 	}
 | |
| 	move(cli, cco);
 | |
|     }
 | |
|     else {
 | |
| 	for (i = 0; i < LINES; i++) {
 | |
| 	    t = ScreenImage[i];
 | |
| 	    t->isdirty |= L_DIRTY | L_NEED_CE;
 | |
| 	    for (j = 0; j < COLS; j++) {
 | |
| 		t->lineprop[j] |= S_DIRTY;
 | |
| 	    }
 | |
| 	}
 | |
|     }
 | |
| }
 | |
| #endif
 | |
| 
 | |
| #if 0
 | |
| void
 | |
| need_clrtoeol(void)
 | |
| {
 | |
|     /* Clear to the end of line as the need arises */
 | |
|     l_prop *lprop = ScreenImage[CurLine]->lineprop;
 | |
| 
 | |
|     if (lprop[CurColumn] & S_EOL)
 | |
| 	return;
 | |
| 
 | |
|     if (!(ScreenImage[CurLine]->isdirty & (L_NEED_CE | L_CLRTOEOL)) ||
 | |
| 	ScreenImage[CurLine]->eol > CurColumn)
 | |
| 	ScreenImage[CurLine]->eol = CurColumn;
 | |
| 
 | |
|     ScreenImage[CurLine]->isdirty |= L_NEED_CE;
 | |
| }
 | |
| #endif				/* 0 */
 | |
| 
 | |
| /* XXX: conflicts with curses's clrtoeol(3) ? */
 | |
| void
 | |
| clrtoeol(void)
 | |
| {				/* Clear to the end of line */
 | |
|     int i;
 | |
|     l_prop *lprop = ScreenImage[CurLine]->lineprop;
 | |
| 
 | |
|     if (lprop[CurColumn] & S_EOL)
 | |
| 	return;
 | |
| 
 | |
|     if (!(ScreenImage[CurLine]->isdirty & (L_NEED_CE | L_CLRTOEOL)) ||
 | |
| 	ScreenImage[CurLine]->eol > CurColumn)
 | |
| 	ScreenImage[CurLine]->eol = CurColumn;
 | |
| 
 | |
|     ScreenImage[CurLine]->isdirty |= L_CLRTOEOL;
 | |
|     touch_line();
 | |
|     for (i = CurColumn; i < COLS && !(lprop[i] & S_EOL); i++) {
 | |
| 	lprop[i] = S_EOL | S_DIRTY;
 | |
|     }
 | |
| }
 | |
| 
 | |
| #ifdef USE_BG_COLOR
 | |
| void
 | |
| clrtoeol_with_bcolor(void)
 | |
| {
 | |
|     int i, cli, cco;
 | |
|     l_prop pr;
 | |
| 
 | |
|     if (!(CurrentMode & S_BCOLORED)) {
 | |
| 	clrtoeol();
 | |
| 	return;
 | |
|     }
 | |
|     cli = CurLine;
 | |
|     cco = CurColumn;
 | |
|     pr = CurrentMode;
 | |
|     CurrentMode = (CurrentMode & (M_CEOL | S_BCOLORED)) | C_ASCII;
 | |
|     for (i = CurColumn; i < COLS; i++)
 | |
| 	addch(' ');
 | |
|     move(cli, cco);
 | |
|     CurrentMode = pr;
 | |
| }
 | |
| 
 | |
| void
 | |
| clrtoeolx(void)
 | |
| {
 | |
|     clrtoeol_with_bcolor();
 | |
| }
 | |
| #else				/* not USE_BG_COLOR */
 | |
| 
 | |
| void
 | |
| clrtoeolx(void)
 | |
| {
 | |
|     clrtoeol();
 | |
| }
 | |
| #endif				/* not USE_BG_COLOR */
 | |
| 
 | |
| void
 | |
| clrtobot_eol(void (*clrtoeol) ())
 | |
| {
 | |
|     int l, c;
 | |
| 
 | |
|     l = CurLine;
 | |
|     c = CurColumn;
 | |
|     (*clrtoeol) ();
 | |
|     CurColumn = 0;
 | |
|     CurLine++;
 | |
|     for (; CurLine < LINES; CurLine++)
 | |
| 	(*clrtoeol) ();
 | |
|     CurLine = l;
 | |
|     CurColumn = c;
 | |
| }
 | |
| 
 | |
| void
 | |
| clrtobot(void)
 | |
| {
 | |
|     clrtobot_eol(clrtoeol);
 | |
| }
 | |
| 
 | |
| void
 | |
| clrtobotx(void)
 | |
| {
 | |
|     clrtobot_eol(clrtoeolx);
 | |
| }
 | |
| 
 | |
| #if 0
 | |
| void
 | |
| no_clrtoeol(void)
 | |
| {
 | |
|     int i;
 | |
|     l_prop *lprop = ScreenImage[CurLine]->lineprop;
 | |
| 
 | |
|     ScreenImage[CurLine]->isdirty &= ~L_CLRTOEOL;
 | |
| }
 | |
| #endif				/* 0 */
 | |
| 
 | |
| void
 | |
| addstr(char *s)
 | |
| {
 | |
| #ifdef USE_M17N
 | |
|     int len;
 | |
| 
 | |
|     while (*s != '\0') {
 | |
| 	len = wtf_len((wc_uchar *) s);
 | |
| 	addmch(s, len);
 | |
| 	s += len;
 | |
|     }
 | |
| #else
 | |
|     while (*s != '\0')
 | |
| 	addch(*(s++));
 | |
| #endif
 | |
| }
 | |
| 
 | |
| void
 | |
| addnstr(char *s, int n)
 | |
| {
 | |
|     int i;
 | |
| #ifdef USE_M17N
 | |
|     int len, width;
 | |
| 
 | |
|     for (i = 0; *s != '\0';) {
 | |
| 	width = wtf_width((wc_uchar *) s);
 | |
| 	if (i + width > n)
 | |
| 	    break;
 | |
| 	len = wtf_len((wc_uchar *) s);
 | |
| 	addmch(s, len);
 | |
| 	s += len;
 | |
| 	i += width;
 | |
|     }
 | |
| #else
 | |
|     for (i = 0; i < n && *s != '\0'; i++)
 | |
| 	addch(*(s++));
 | |
| #endif
 | |
| }
 | |
| 
 | |
| void
 | |
| addnstr_sup(char *s, int n)
 | |
| {
 | |
|     int i;
 | |
| #ifdef USE_M17N
 | |
|     int len, width;
 | |
| 
 | |
|     for (i = 0; *s != '\0';) {
 | |
| 	width = wtf_width((wc_uchar *) s);
 | |
| 	if (i + width > n)
 | |
| 	    break;
 | |
| 	len = wtf_len((wc_uchar *) s);
 | |
| 	addmch(s, len);
 | |
| 	s += len;
 | |
| 	i += width;
 | |
|     }
 | |
| #else
 | |
|     for (i = 0; i < n && *s != '\0'; i++)
 | |
| 	addch(*(s++));
 | |
| #endif
 | |
|     for (; i < n; i++)
 | |
| 	addch(' ');
 | |
| }
 | |
| 
 | |
| void
 | |
| crmode(void)
 | |
| #ifndef HAVE_SGTTY_H
 | |
| {
 | |
|     ttymode_reset(ICANON, IXON);
 | |
|     ttymode_set(ISIG, 0);
 | |
| #ifdef HAVE_TERMIOS_H
 | |
|     set_cc(VMIN, 1);
 | |
| #else				/* not HAVE_TERMIOS_H */
 | |
|     set_cc(VEOF, 1);
 | |
| #endif				/* not HAVE_TERMIOS_H */
 | |
| }
 | |
| #else				/* HAVE_SGTTY_H */
 | |
| {
 | |
|     ttymode_set(CBREAK, 0);
 | |
| }
 | |
| #endif				/* HAVE_SGTTY_H */
 | |
| 
 | |
| void
 | |
| nocrmode(void)
 | |
| #ifndef HAVE_SGTTY_H
 | |
| {
 | |
|     ttymode_set(ICANON, 0);
 | |
| #ifdef HAVE_TERMIOS_H
 | |
|     set_cc(VMIN, 4);
 | |
| #else				/* not HAVE_TERMIOS_H */
 | |
|     set_cc(VEOF, 4);
 | |
| #endif				/* not HAVE_TERMIOS_H */
 | |
| }
 | |
| #else				/* HAVE_SGTTY_H */
 | |
| {
 | |
|     ttymode_reset(CBREAK, 0);
 | |
| }
 | |
| #endif				/* HAVE_SGTTY_H */
 | |
| 
 | |
| void
 | |
| term_echo(void)
 | |
| {
 | |
|     ttymode_set(ECHO, 0);
 | |
| }
 | |
| 
 | |
| void
 | |
| term_noecho(void)
 | |
| {
 | |
|     ttymode_reset(ECHO, 0);
 | |
| }
 | |
| 
 | |
| void
 | |
| term_raw(void)
 | |
| #ifndef HAVE_SGTTY_H
 | |
| #ifdef IEXTEN
 | |
| #define TTY_MODE ISIG|ICANON|ECHO|IEXTEN
 | |
| #else				/* not IEXTEN */
 | |
| #define TTY_MODE ISIG|ICANON|ECHO
 | |
| #endif				/* not IEXTEN */
 | |
| {
 | |
|     ttymode_reset(TTY_MODE, IXON | IXOFF);
 | |
| #ifdef HAVE_TERMIOS_H
 | |
|     set_cc(VMIN, 1);
 | |
| #else				/* not HAVE_TERMIOS_H */
 | |
|     set_cc(VEOF, 1);
 | |
| #endif				/* not HAVE_TERMIOS_H */
 | |
| }
 | |
| #else				/* HAVE_SGTTY_H */
 | |
| {
 | |
|     ttymode_set(RAW, 0);
 | |
| }
 | |
| #endif				/* HAVE_SGTTY_H */
 | |
| 
 | |
| void
 | |
| term_cooked(void)
 | |
| #ifndef HAVE_SGTTY_H
 | |
| {
 | |
| #ifdef __EMX__
 | |
|     /* On XFree86/OS2, some scrambled characters
 | |
|      * will appear when asserting IEXTEN flag.
 | |
|      */
 | |
|     ttymode_set((TTY_MODE) & ~IEXTEN, 0);
 | |
| #else
 | |
|     ttymode_set(TTY_MODE, 0);
 | |
| #endif
 | |
| #ifdef HAVE_TERMIOS_H
 | |
|     set_cc(VMIN, 4);
 | |
| #else				/* not HAVE_TERMIOS_H */
 | |
|     set_cc(VEOF, 4);
 | |
| #endif				/* not HAVE_TERMIOS_H */
 | |
| }
 | |
| #else				/* HAVE_SGTTY_H */
 | |
| {
 | |
|     ttymode_reset(RAW, 0);
 | |
| }
 | |
| #endif				/* HAVE_SGTTY_H */
 | |
| 
 | |
| void
 | |
| term_cbreak(void)
 | |
| {
 | |
|     term_cooked();
 | |
|     term_noecho();
 | |
| }
 | |
| 
 | |
| void
 | |
| term_title(char *s)
 | |
| {
 | |
|     if (!fmInitialized)
 | |
|         return;
 | |
|     if (title_str != NULL) {
 | |
| #ifdef __CYGWIN__
 | |
| 	if (isLocalConsole && title_str == CYGWIN_TITLE) {
 | |
| 	    Str buff;
 | |
| 	    buff = Sprintf(title_str, s);
 | |
| 	    if (buff->length > 1024) {
 | |
| 		Strtruncate(buff, 1024);
 | |
| 	    }
 | |
| 	    SetConsoleTitle(buff->ptr);
 | |
| 	}
 | |
| 	else if (isLocalConsole || !isWinConsole)
 | |
| #endif
 | |
|         fprintf(ttyf, title_str, s);
 | |
|     }
 | |
| }
 | |
| 
 | |
| char
 | |
| getch(void)
 | |
| {
 | |
|     char c;
 | |
| 
 | |
|     while (
 | |
| #ifdef SUPPORT_WIN9X_CONSOLE_MBCS
 | |
| 	      read_win32_console(&c, 1)
 | |
| #else
 | |
| 	      read(tty, &c, 1)
 | |
| #endif
 | |
| 	      < (int)1) {
 | |
| 	if (errno == EINTR || errno == EAGAIN)
 | |
| 	    continue;
 | |
| 	/* error happend on read(2) */
 | |
| 	quitfm();
 | |
| 	break;			/* unreachable */
 | |
|     }
 | |
|     return c;
 | |
| }
 | |
| 
 | |
| #ifdef USE_MOUSE
 | |
| #ifdef USE_GPM
 | |
| char
 | |
| wgetch(void *p)
 | |
| {
 | |
|     char c;
 | |
| 
 | |
|     /* read(tty, &c, 1); */
 | |
|     while (read(tty, &c, 1) < (ssize_t) 1) {
 | |
| 	if (errno == EINTR || errno == EAGAIN)
 | |
| 	    continue;
 | |
| 	/* error happend on read(2) */
 | |
| 	quitfm();
 | |
| 	break;			/* unreachable */
 | |
|     }
 | |
|     return c;
 | |
| }
 | |
| 
 | |
| int
 | |
| do_getch()
 | |
| {
 | |
|     if (is_xterm || !gpm_handler)
 | |
| 	return getch();
 | |
|     else
 | |
| 	return Gpm_Getch();
 | |
| }
 | |
| #endif				/* USE_GPM */
 | |
| 
 | |
| #ifdef USE_SYSMOUSE
 | |
| int
 | |
| sysm_getch()
 | |
| {
 | |
|     fd_set rfd;
 | |
|     int key, x, y;
 | |
| 
 | |
|     FD_ZERO(&rfd);
 | |
|     FD_SET(tty, &rfd);
 | |
|     while (select(tty + 1, &rfd, NULL, NULL, NULL) <= 0) {
 | |
| 	if (errno == EINTR) {
 | |
| 	    x = xpix / cwidth;
 | |
| 	    y = ypix / cheight;
 | |
| 	    key = (*sysm_handler) (x, y, nbs, obs);
 | |
| 	    if (key != 0)
 | |
| 		return key;
 | |
| 	}
 | |
|     }
 | |
|     return getch();
 | |
| }
 | |
| 
 | |
| int
 | |
| do_getch()
 | |
| {
 | |
|     if (is_xterm || !sysm_handler)
 | |
| 	return getch();
 | |
|     else
 | |
| 	return sysm_getch();
 | |
| }
 | |
| 
 | |
| MySignalHandler
 | |
| sysmouse(SIGNAL_ARG)
 | |
| {
 | |
|     struct mouse_info mi;
 | |
| 
 | |
|     mi.operation = MOUSE_GETINFO;
 | |
|     if (ioctl(tty, CONS_MOUSECTL, &mi) == -1)
 | |
| 	return;
 | |
|     xpix = mi.u.data.x;
 | |
|     ypix = mi.u.data.y;
 | |
|     obs = nbs;
 | |
|     nbs = mi.u.data.buttons & 0x7;
 | |
|     /* for cosmetic bug in syscons.c on FreeBSD 3.[34] */
 | |
|     mi.operation = MOUSE_HIDE;
 | |
|     ioctl(tty, CONS_MOUSECTL, &mi);
 | |
|     mi.operation = MOUSE_SHOW;
 | |
|     ioctl(tty, CONS_MOUSECTL, &mi);
 | |
| }
 | |
| #endif				/* USE_SYSMOUSE */
 | |
| #endif				/* USE_MOUSE */
 | |
| 
 | |
| void
 | |
| bell(void)
 | |
| {
 | |
|     write1(7);
 | |
| }
 | |
| 
 | |
| void
 | |
| skip_escseq(void)
 | |
| {
 | |
|     int c;
 | |
| 
 | |
|     c = getch();
 | |
|     if (c == '[' || c == 'O') {
 | |
| 	c = getch();
 | |
| #ifdef USE_MOUSE
 | |
| 	if (is_xterm && c == 'M') {
 | |
| 	    getch();
 | |
| 	    getch();
 | |
| 	    getch();
 | |
| 	} else if (is_xterm && c == '<') {
 | |
| 	    c = getch();
 | |
| 	    while (IS_DIGIT(c) || c == ';')
 | |
| 		c = getch();
 | |
| 	}
 | |
| 	else
 | |
| #endif
 | |
| 	    while (IS_DIGIT(c))
 | |
| 		c = getch();
 | |
|     }
 | |
| }
 | |
| 
 | |
| int
 | |
| sleep_till_anykey(int sec, int purge)
 | |
| {
 | |
|     fd_set rfd;
 | |
|     struct timeval tim;
 | |
|     int er, c, ret;
 | |
|     TerminalMode ioval;
 | |
| 
 | |
|     TerminalGet(tty, &ioval);
 | |
|     term_raw();
 | |
| 
 | |
|     tim.tv_sec = sec;
 | |
|     tim.tv_usec = 0;
 | |
| 
 | |
|     FD_ZERO(&rfd);
 | |
|     FD_SET(tty, &rfd);
 | |
| 
 | |
|     ret = select(tty + 1, &rfd, 0, 0, &tim);
 | |
|     if (ret > 0 && purge) {
 | |
| 	c = getch();
 | |
| 	if (c == ESC_CODE)
 | |
| 	    skip_escseq();
 | |
|     }
 | |
|     er = TerminalSet(tty, &ioval);
 | |
|     if (er == -1) {
 | |
| 	printf("Error occured: errno=%d\n", errno);
 | |
| 	reset_error_exit(SIGNAL_ARGLIST);
 | |
|     }
 | |
|     return ret;
 | |
| }
 | |
| 
 | |
| #ifdef USE_MOUSE
 | |
| 
 | |
| #define XTERM_ON   {fputs("\033[?1001s\033[?1000h\033[?1006h",ttyf); flush_tty();}
 | |
| #define XTERM_OFF  {fputs("\033[?1006l\033[?1000l\033[?1001r",ttyf); flush_tty();}
 | |
| #define CYGWIN_ON  {fputs("\033[?1000h",ttyf); flush_tty();}
 | |
| #define CYGWIN_OFF {fputs("\033[?1000l",ttyf); flush_tty();}
 | |
| 
 | |
| #ifdef USE_GPM
 | |
| /* Linux console with GPM support */
 | |
| 
 | |
| void
 | |
| mouse_init()
 | |
| {
 | |
|     Gpm_Connect conn;
 | |
|     extern int gpm_process_mouse(Gpm_Event *, void *);
 | |
|     int r;
 | |
| 
 | |
|     if (mouseActive)
 | |
| 	return;
 | |
|     conn.eventMask = ~0;
 | |
|     conn.defaultMask = 0;
 | |
|     conn.maxMod = 0;
 | |
|     conn.minMod = 0;
 | |
| 
 | |
|     gpm_handler = NULL;
 | |
|     r = Gpm_Open(&conn, 0);
 | |
|     if (r == -2) {
 | |
| 	/*
 | |
| 	 * If Gpm_Open() success, returns >= 0
 | |
| 	 * Gpm_Open() returns -2 in case of xterm.
 | |
| 	 * Gpm_Close() is necessary here. Otherwise,
 | |
| 	 * xterm is being left in the mode where the mouse clicks are
 | |
| 	 * passed through to the application.
 | |
| 	 */
 | |
| 	Gpm_Close();
 | |
| 	is_xterm = (NEED_XTERM_ON | NEED_XTERM_OFF);
 | |
|     }
 | |
|     else if (r >= 0) {
 | |
| 	gpm_handler = gpm_process_mouse;
 | |
| 	is_xterm = 0;
 | |
|     }
 | |
|     if (is_xterm) {
 | |
| 	XTERM_ON;
 | |
|     }
 | |
|     mouseActive = 1;
 | |
| }
 | |
| 
 | |
| void
 | |
| mouse_end()
 | |
| {
 | |
|     if (mouseActive == 0)
 | |
| 	return;
 | |
|     if (is_xterm) {
 | |
| 	XTERM_OFF;
 | |
|     }
 | |
|     else
 | |
| 	Gpm_Close();
 | |
|     mouseActive = 0;
 | |
| }
 | |
| 
 | |
| #elif	defined(USE_SYSMOUSE)
 | |
| /* *BSD console with sysmouse support */
 | |
| void
 | |
| mouse_init()
 | |
| {
 | |
|     mouse_info_t mi;
 | |
|     extern int sysm_process_mouse();
 | |
| 
 | |
|     if (mouseActive)
 | |
| 	return;
 | |
|     if (is_xterm) {
 | |
| 	XTERM_ON;
 | |
|     }
 | |
|     else {
 | |
| #if defined(FBIO_MODEINFO) || defined(CONS_MODEINFO)	/* FreeBSD > 2.x */
 | |
| #ifndef FBIO_GETMODE		/* FreeBSD 3.x */
 | |
| #define FBIO_GETMODE    CONS_GET
 | |
| #define FBIO_MODEINFO   CONS_MODEINFO
 | |
| #endif				/* FBIO_GETMODE */
 | |
| 	video_info_t vi;
 | |
| 
 | |
| 	if (ioctl(tty, FBIO_GETMODE, &vi.vi_mode) != -1 &&
 | |
| 	    ioctl(tty, FBIO_MODEINFO, &vi) != -1) {
 | |
| 	    cwidth = vi.vi_cwidth;
 | |
| 	    cheight = vi.vi_cheight;
 | |
| 	}
 | |
| #endif				/* defined(FBIO_MODEINFO) ||
 | |
| 				 * defined(CONS_MODEINFO) */
 | |
| 	mySignal(SIGUSR2, SIG_IGN);
 | |
| 	mi.operation = MOUSE_MODE;
 | |
| 	mi.u.mode.mode = 0;
 | |
| 	mi.u.mode.signal = SIGUSR2;
 | |
| 	sysm_handler = NULL;
 | |
| 	if (ioctl(tty, CONS_MOUSECTL, &mi) != -1) {
 | |
| 	    mySignal(SIGUSR2, sysmouse);
 | |
| 	    mi.operation = MOUSE_SHOW;
 | |
| 	    ioctl(tty, CONS_MOUSECTL, &mi);
 | |
| 	    sysm_handler = sysm_process_mouse;
 | |
| 	}
 | |
|     }
 | |
|     mouseActive = 1;
 | |
| }
 | |
| 
 | |
| void
 | |
| mouse_end()
 | |
| {
 | |
|     if (mouseActive == 0)
 | |
| 	return;
 | |
|     if (is_xterm) {
 | |
| 	XTERM_OFF;
 | |
|     }
 | |
|     else {
 | |
| 	mouse_info_t mi;
 | |
| 	mi.operation = MOUSE_MODE;
 | |
| 	mi.u.mode.mode = 0;
 | |
| 	mi.u.mode.signal = 0;
 | |
| 	ioctl(tty, CONS_MOUSECTL, &mi);
 | |
|     }
 | |
|     mouseActive = 0;
 | |
| }
 | |
| 
 | |
| #else
 | |
| /* not GPM nor SYSMOUSE, but use mouse with xterm */
 | |
| 
 | |
| void
 | |
| mouse_init()
 | |
| {
 | |
|     if (mouseActive)
 | |
| 	return;
 | |
|     if (is_xterm & NEED_XTERM_ON) {
 | |
| 	XTERM_ON;
 | |
|     }
 | |
| #ifdef __CYGWIN__
 | |
|     else if (is_xterm & NEED_CYGWIN_ON) {
 | |
| 	CYGWIN_ON;
 | |
|     }
 | |
| #endif
 | |
|     mouseActive = 1;
 | |
| }
 | |
| 
 | |
| void
 | |
| mouse_end()
 | |
| {
 | |
|     if (mouseActive == 0)
 | |
| 	return;
 | |
|     if (is_xterm & NEED_XTERM_OFF) {
 | |
| 	XTERM_OFF;
 | |
|     }
 | |
| #ifdef __CYGWIN__
 | |
|     else if (is_xterm & NEED_CYGWIN_OFF) {
 | |
| 	CYGWIN_OFF;
 | |
|     }
 | |
| #endif
 | |
|     mouseActive = 0;
 | |
| }
 | |
| 
 | |
| #endif				/* not USE_GPM nor USE_SYSMOUSE */
 | |
| 
 | |
| 
 | |
| void
 | |
| mouse_active()
 | |
| {
 | |
|     if (!mouseActive)
 | |
| 	mouse_init();
 | |
| }
 | |
| 
 | |
| void
 | |
| mouse_inactive()
 | |
| {
 | |
|     if (mouseActive && is_xterm)
 | |
| 	mouse_end();
 | |
| }
 | |
| 
 | |
| #endif				/* USE_MOUSE */
 | |
| 
 | |
| void
 | |
| flush_tty()
 | |
| {
 | |
|     if (ttyf)
 | |
| 	fflush(ttyf);
 | |
| }
 | |
| 
 | |
| #ifdef USE_IMAGE
 | |
| void
 | |
| touch_cursor()
 | |
| {
 | |
| #ifdef USE_M17N
 | |
|     int i;
 | |
| #endif
 | |
|     touch_line();
 | |
| #ifdef USE_M17N
 | |
|     for (i = CurColumn; i >= 0; i--) {
 | |
| 	touch_column(i);
 | |
| 	if (CHMODE(ScreenImage[CurLine]->lineprop[i]) != C_WCHAR2) 
 | |
| 	    break;
 | |
|     }
 | |
|     for (i = CurColumn + 1; i < COLS; i++) {
 | |
| 	if (CHMODE(ScreenImage[CurLine]->lineprop[i]) != C_WCHAR2) 
 | |
| 	    break;
 | |
| 	touch_column(i);
 | |
|     }
 | |
| #else
 | |
|     touch_column(CurColumn);
 | |
| #endif
 | |
| }
 | |
| #endif
 | |
| 
 | |
| #ifdef __MINGW32_VERSION
 | |
| 
 | |
| int tgetent(char *bp, char *name)
 | |
| {
 | |
|   return 0;
 | |
| }
 | |
| 
 | |
| int tgetnum(char *id)
 | |
| {
 | |
|   return -1;
 | |
| }
 | |
| 
 | |
| int tgetflag(char *id)
 | |
| {
 | |
|   return 0;
 | |
| }
 | |
| 
 | |
| char *tgetstr(char *id, char **area)
 | |
| {
 | |
|   id = "";
 | |
| }
 | |
| 
 | |
| char *tgoto(char *cap, int col, int row)
 | |
| {
 | |
| }
 | |
| 
 | |
| int tputs(char *str, int affcnt, int (*putc)(char))
 | |
| {
 | |
| }
 | |
| 
 | |
| char *ttyname(int tty)
 | |
| {
 | |
|   return "CON";
 | |
| }
 | |
| 
 | |
| #endif /* __MINGW32_VERSION */
 |