terms.c (45697B)
1 /* $Id$ */ 2 /* 3 * An original curses library for EUC-kanji by Akinori ITO, December 1989 4 * revised by Akinori ITO, January 1995 5 */ 6 #include <stdio.h> 7 #include <signal.h> 8 #include <sys/types.h> 9 #include <fcntl.h> 10 #include <errno.h> 11 #include <sys/time.h> 12 #include <unistd.h> 13 #include "config.h" 14 #include <string.h> 15 #ifdef HAVE_SYS_SELECT_H 16 #include <sys/select.h> 17 #endif 18 #ifndef __MINGW32_VERSION 19 #include <sys/ioctl.h> 20 #else 21 #include <winsock.h> 22 #endif /* __MINGW32_VERSION */ 23 #ifdef USE_MOUSE 24 #ifdef USE_GPM 25 #include <gpm.h> 26 #endif /* USE_GPM */ 27 #ifdef USE_SYSMOUSE 28 #include <osreldate.h> 29 #if (__FreeBSD_version >= 400017) || (__FreeBSD_kernel_version >= 400017) 30 #include <sys/consio.h> 31 #include <sys/fbio.h> 32 #else 33 #include <machine/console.h> 34 #endif 35 int (*sysm_handler) (int x, int y, int nbs, int obs); 36 static int cwidth = 8, cheight = 16; 37 static int xpix, ypix, nbs, obs = 0; 38 #endif /* use_SYSMOUSE */ 39 40 static int is_xterm = 0; 41 42 void mouse_init(), mouse_end(); 43 int mouseActive = 0; 44 #endif /* USE_MOUSE */ 45 46 static char *title_str = NULL; 47 48 static int tty; 49 50 #include "terms.h" 51 #include "fm.h" 52 #include "myctype.h" 53 54 #ifdef __EMX__ 55 #define INCL_DOSNLS 56 #include <os2.h> 57 #endif /* __EMX__ */ 58 59 #if defined(__CYGWIN__) 60 #include <windows.h> 61 #include <sys/cygwin.h> 62 static int isWinConsole = 0; 63 #define TERM_CYGWIN 1 64 #define TERM_CYGWIN_RESERVE_IME 2 65 static int isLocalConsole = 0; 66 67 #if CYGWIN_VERSION_DLL_MAJOR < 1005 && defined(USE_MOUSE) 68 int cygwin_mouse_btn_swapped = 0; 69 #endif 70 71 #if defined(SUPPORT_WIN9X_CONSOLE_MBCS) 72 static HANDLE hConIn = INVALID_HANDLE_VALUE; 73 static int isWin95 = 0; 74 static char *ConInV; 75 static int iConIn, nConIn, nConInMax; 76 77 static void 78 check_win9x(void) 79 { 80 OSVERSIONINFO winVersionInfo; 81 82 winVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); 83 if (GetVersionEx(&winVersionInfo) == 0) { 84 fprintf(stderr, "can't get Windows version information.\n"); 85 exit(1); 86 } 87 if (winVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) { 88 isWin95 = 1; 89 } 90 else { 91 isWin95 = 0; 92 } 93 } 94 95 void 96 enable_win9x_console_input(void) 97 { 98 if (isWin95 && isWinConsole && isLocalConsole && 99 hConIn == INVALID_HANDLE_VALUE) { 100 hConIn = CreateFile("CONIN$", GENERIC_READ | GENERIC_WRITE, 101 FILE_SHARE_READ | FILE_SHARE_WRITE, 102 NULL, OPEN_EXISTING, 0, NULL); 103 if (hConIn != INVALID_HANDLE_VALUE) { 104 getch(); 105 } 106 } 107 } 108 109 void 110 disable_win9x_console_input(void) 111 { 112 if (hConIn != INVALID_HANDLE_VALUE) { 113 CloseHandle(hConIn); 114 hConIn = INVALID_HANDLE_VALUE; 115 } 116 } 117 118 static void 119 expand_win32_console_input_buffer(int n) 120 { 121 if (nConIn + n >= nConInMax) { 122 char *oldv; 123 124 nConInMax = ((nConIn + n) / 2 + 1) * 3; 125 oldv = ConInV; 126 ConInV = GC_MALLOC_ATOMIC(nConInMax); 127 memcpy(ConInV, oldv, nConIn); 128 } 129 } 130 131 static int 132 read_win32_console_input(void) 133 { 134 INPUT_RECORD rec; 135 DWORD nevents; 136 137 if (PeekConsoleInput(hConIn, &rec, 1, &nevents) && nevents) { 138 switch (rec.EventType) { 139 case KEY_EVENT: 140 expand_win32_console_input_buffer(3); 141 142 if (ReadConsole(hConIn, &ConInV[nConIn], 1, &nevents, NULL)) { 143 nConIn += nevents; 144 return nevents; 145 } 146 147 break; 148 default: 149 break; 150 } 151 152 ReadConsoleInput(hConIn, &rec, 1, &nevents); 153 } 154 return 0; 155 } 156 157 static int 158 read_win32_console(char *s, int n) 159 { 160 KEY_EVENT_RECORD *ker; 161 162 if (hConIn == INVALID_HANDLE_VALUE) 163 return read(tty, s, n); 164 165 if (n > 0) 166 for (;;) { 167 if (iConIn < nConIn) { 168 if (n > nConIn - iConIn) 169 n = nConIn - iConIn; 170 171 memcpy(s, ConInV, n); 172 173 if ((iConIn += n) >= nConIn) 174 iConIn = nConIn = 0; 175 176 break; 177 } 178 179 iConIn = nConIn = 0; 180 181 while (!read_win32_console_input()) ; 182 } 183 184 return n; 185 } 186 187 #endif /* SUPPORT_WIN9X_CONSOLE_MBCS */ 188 189 static HWND 190 GetConsoleHwnd(void) 191 { 192 #define MY_BUFSIZE 1024 193 HWND hwndFound; 194 char pszNewWindowTitle[MY_BUFSIZE]; 195 char pszOldWindowTitle[MY_BUFSIZE]; 196 197 GetConsoleTitle(pszOldWindowTitle, MY_BUFSIZE); 198 wsprintf(pszNewWindowTitle, "%d/%d", 199 GetTickCount(), GetCurrentProcessId()); 200 SetConsoleTitle(pszNewWindowTitle); 201 Sleep(40); 202 hwndFound = FindWindow(NULL, pszNewWindowTitle); 203 SetConsoleTitle(pszOldWindowTitle); 204 return (hwndFound); 205 } 206 207 #if CYGWIN_VERSION_DLL_MAJOR < 1005 && defined(USE_MOUSE) 208 static unsigned long 209 cygwin_version(void) 210 { 211 struct per_process *p; 212 213 p = (struct per_process *)cygwin_internal(CW_USER_DATA); 214 if (p != NULL) { 215 return (p->dll_major * 1000) + p->dll_minor; 216 } 217 return 0; 218 } 219 #endif 220 221 static void 222 check_cygwin_console(void) 223 { 224 char *term = getenv("TERM"); 225 HANDLE hWnd; 226 227 if (term == NULL) 228 term = DEFAULT_TERM; 229 if (term && strncmp(term, "cygwin", 6) == 0) { 230 isWinConsole = TERM_CYGWIN; 231 } 232 if (isWinConsole) { 233 hWnd = GetConsoleHwnd(); 234 if (hWnd != INVALID_HANDLE_VALUE) { 235 if (IsWindowVisible(hWnd)) { 236 isLocalConsole = 1; 237 } 238 } 239 if (strncmp(getenv("LANG"), "ja", 2) == 0) { 240 isWinConsole = TERM_CYGWIN_RESERVE_IME; 241 } 242 #ifdef SUPPORT_WIN9X_CONSOLE_MBCS 243 check_win9x(); 244 if (isWin95 && ttyslot() != -1) { 245 isLocalConsole = 0; 246 } 247 #endif 248 } 249 #if CYGWIN_VERSION_DLL_MAJOR < 1005 && defined(USE_MOUSE) 250 if (cygwin_version() <= 1003015) { 251 /* cygwin DLL 1.3.15 or earler */ 252 cygwin_mouse_btn_swapped = 1; 253 } 254 #endif 255 } 256 #endif /* __CYGWIN__ */ 257 258 char *getenv(const char *); 259 MySignalHandler reset_exit(SIGNAL_ARG), reset_error_exit(SIGNAL_ARG), error_dump(SIGNAL_ARG); 260 void setlinescols(void); 261 void flush_tty(); 262 263 #ifndef SIGIOT 264 #define SIGIOT SIGABRT 265 #endif /* not SIGIOT */ 266 267 #ifdef HAVE_TERMIO_H 268 #include <termio.h> 269 typedef struct termio TerminalMode; 270 #define TerminalSet(fd,x) ioctl(fd,TCSETA,x) 271 #define TerminalGet(fd,x) ioctl(fd,TCGETA,x) 272 #define MODEFLAG(d) ((d).c_lflag) 273 #define IMODEFLAG(d) ((d).c_iflag) 274 #endif /* HAVE_TERMIO_H */ 275 276 #ifdef HAVE_TERMIOS_H 277 #include <termios.h> 278 #include <unistd.h> 279 typedef struct termios TerminalMode; 280 #define TerminalSet(fd,x) tcsetattr(fd,TCSANOW,x) 281 #define TerminalGet(fd,x) tcgetattr(fd,x) 282 #define MODEFLAG(d) ((d).c_lflag) 283 #define IMODEFLAG(d) ((d).c_iflag) 284 #endif /* HAVE_TERMIOS_H */ 285 286 #ifdef HAVE_SGTTY_H 287 #include <sgtty.h> 288 typedef struct sgttyb TerminalMode; 289 #define TerminalSet(fd,x) ioctl(fd,TIOCSETP,x) 290 #define TerminalGet(fd,x) ioctl(fd,TIOCGETP,x) 291 #define MODEFLAG(d) ((d).sg_flags) 292 #endif /* HAVE_SGTTY_H */ 293 294 #ifdef __MINGW32_VERSION 295 /* dummy struct */ 296 typedef unsigned char cc_t; 297 typedef unsigned int speed_t; 298 typedef unsigned int tcflag_t; 299 300 #define NCCS 32 301 struct termios 302 { 303 tcflag_t c_iflag; /* input mode flags */ 304 tcflag_t c_oflag; /* output mode flags */ 305 tcflag_t c_cflag; /* control mode flags */ 306 tcflag_t c_lflag; /* local mode flags */ 307 cc_t c_line; /* line discipline */ 308 cc_t c_cc[NCCS]; /* control characters */ 309 speed_t c_ispeed; /* input speed */ 310 speed_t c_ospeed; /* output speed */ 311 }; 312 typedef struct termios TerminalMode; 313 #define TerminalSet(fd,x) (0) 314 #define TerminalGet(fd,x) (0) 315 #define MODEFLAG(d) (0) 316 317 /* dummy defines */ 318 #define SIGHUP (0) 319 #define SIGQUIT (0) 320 #define ECHO (0) 321 #define ISIG (0) 322 #define VEOF (0) 323 #define ICANON (0) 324 #define IXON (0) 325 #define IXOFF (0) 326 327 char *ttyname(int); 328 #endif /* __MINGW32_VERSION */ 329 330 #define MAX_LINE 200 331 #define MAX_COLUMN 400 332 333 /* Screen properties */ 334 #define S_SCREENPROP 0x0f 335 #define S_NORMAL 0x00 336 #define S_STANDOUT 0x01 337 #define S_UNDERLINE 0x02 338 #define S_BOLD 0x04 339 #define S_EOL 0x08 340 341 /* Sort of Character */ 342 #define C_WHICHCHAR 0xc0 343 #define C_ASCII 0x00 344 #ifdef USE_M17N 345 #define C_WCHAR1 0x40 346 #define C_WCHAR2 0x80 347 #endif 348 #define C_CTRL 0xc0 349 350 #define CHMODE(c) ((c)&C_WHICHCHAR) 351 #define SETCHMODE(var,mode) ((var) = (((var)&~C_WHICHCHAR) | mode)) 352 #ifdef USE_M17N 353 #define SETCH(var,ch,len) ((var) = New_Reuse(char, (var), (len) + 1), \ 354 strncpy((var), (ch), (len)), (var)[len] = '\0') 355 #else 356 #define SETCH(var,ch,len) ((var) = (ch)) 357 #endif 358 359 /* Charactor Color */ 360 #define COL_FCOLOR 0xf00 361 #define COL_FBLACK 0x800 362 #define COL_FRED 0x900 363 #define COL_FGREEN 0xa00 364 #define COL_FYELLOW 0xb00 365 #define COL_FBLUE 0xc00 366 #define COL_FMAGENTA 0xd00 367 #define COL_FCYAN 0xe00 368 #define COL_FWHITE 0xf00 369 #define COL_FTERM 0x000 370 371 #define S_COLORED 0xf00 372 373 #ifdef USE_BG_COLOR 374 /* Background Color */ 375 #define COL_BCOLOR 0xf000 376 #define COL_BBLACK 0x8000 377 #define COL_BRED 0x9000 378 #define COL_BGREEN 0xa000 379 #define COL_BYELLOW 0xb000 380 #define COL_BBLUE 0xc000 381 #define COL_BMAGENTA 0xd000 382 #define COL_BCYAN 0xe000 383 #define COL_BWHITE 0xf000 384 #define COL_BTERM 0x0000 385 386 #define S_BCOLORED 0xf000 387 #endif /* USE_BG_COLOR */ 388 389 390 #define S_GRAPHICS 0x10 391 392 #define S_DIRTY 0x20 393 394 #define SETPROP(var,prop) (var = (((var)&S_DIRTY) | prop)) 395 396 /* Line status */ 397 #define L_DIRTY 0x01 398 #define L_UNUSED 0x02 399 #define L_NEED_CE 0x04 400 #define L_CLRTOEOL 0x08 401 402 #define ISDIRTY(d) ((d) & L_DIRTY) 403 #define ISUNUSED(d) ((d) & L_UNUSED) 404 #define NEED_CE(d) ((d) & L_NEED_CE) 405 406 typedef unsigned short l_prop; 407 408 typedef struct scline { 409 #ifdef USE_M17N 410 char **lineimage; 411 #else 412 char *lineimage; 413 #endif 414 l_prop *lineprop; 415 short isdirty; 416 short eol; 417 } Screen; 418 419 static TerminalMode d_ioval; 420 static int tty = -1; 421 static FILE *ttyf = NULL; 422 423 static 424 char bp[1024], funcstr[256]; 425 426 char *T_cd, *T_ce, *T_kr, *T_kl, *T_cr, *T_bt, *T_ta, *T_sc, *T_rc, 427 *T_so, *T_se, *T_us, *T_ue, *T_cl, *T_cm, *T_al, *T_sr, *T_md, *T_me, 428 *T_ti, *T_te, *T_nd, *T_as, *T_ae, *T_eA, *T_ac, *T_op; 429 430 int LINES, COLS; 431 #if defined(__CYGWIN__) 432 int LASTLINE; 433 #endif /* defined(__CYGWIN__) */ 434 435 static int max_LINES = 0, max_COLS = 0; 436 static int tab_step = 8; 437 static int CurLine, CurColumn; 438 static Screen *ScreenElem = NULL, **ScreenImage = NULL; 439 static l_prop CurrentMode = 0; 440 static int graph_enabled = 0; 441 442 static char gcmap[96]; 443 444 extern int tgetent(char *, char *); 445 extern int tgetnum(char *); 446 extern int tgetflag(char *); 447 extern char *tgetstr(char *, char **); 448 extern char *tgoto(char *, int, int); 449 extern int tputs(char *, int, int (*)(char)); 450 void clear(), wrap(), touch_line(), touch_column(int); 451 #if 0 452 void need_clrtoeol(void); 453 #endif 454 void clrtoeol(void); /* conflicts with curs_clear(3)? */ 455 456 static int write1(char); 457 458 static void 459 writestr(char *s) 460 { 461 tputs(s, 1, write1); 462 } 463 464 #define MOVE(line,column) writestr(tgoto(T_cm,column,line)); 465 466 #ifdef USE_MOUSE 467 #define W3M_TERM_INFO(name, title, mouse) name, title, mouse 468 #define NEED_XTERM_ON (1) 469 #define NEED_XTERM_OFF (1<<1) 470 #ifdef __CYGWIN__ 471 #define NEED_CYGWIN_ON (1<<2) 472 #define NEED_CYGWIN_OFF (1<<3) 473 #endif 474 #else 475 #define W3M_TERM_INFO(name, title, mouse) name, title 476 #endif 477 478 static char XTERM_TITLE[] = "\033]0;w3m: %s\007"; 479 static char SCREEN_TITLE[] = "\033k%s\033\134"; 480 #ifdef __CYGWIN__ 481 static char CYGWIN_TITLE[] = "w3m: %s"; 482 #endif 483 484 /* *INDENT-OFF* */ 485 static struct w3m_term_info { 486 char *term; 487 char *title_str; 488 #ifdef USE_MOUSE 489 int mouse_flag; 490 #endif 491 } w3m_term_info_list[] = { 492 {W3M_TERM_INFO("xterm", XTERM_TITLE, (NEED_XTERM_ON|NEED_XTERM_OFF))}, 493 {W3M_TERM_INFO("kterm", XTERM_TITLE, (NEED_XTERM_ON|NEED_XTERM_OFF))}, 494 {W3M_TERM_INFO("rxvt", XTERM_TITLE, (NEED_XTERM_ON|NEED_XTERM_OFF))}, 495 {W3M_TERM_INFO("Eterm", XTERM_TITLE, (NEED_XTERM_ON|NEED_XTERM_OFF))}, 496 {W3M_TERM_INFO("mlterm", XTERM_TITLE, (NEED_XTERM_ON|NEED_XTERM_OFF))}, 497 {W3M_TERM_INFO("screen", SCREEN_TITLE, 0)}, 498 #ifdef __CYGWIN__ 499 {W3M_TERM_INFO("cygwin", CYGWIN_TITLE, (NEED_CYGWIN_ON|NEED_CYGWIN_OFF))}, 500 #endif 501 {W3M_TERM_INFO(NULL, NULL, 0)} 502 }; 503 #undef W3M_TERM_INFO 504 /* *INDENT-ON * */ 505 506 int 507 set_tty(void) 508 { 509 char *ttyn; 510 511 if (isatty(0)) /* stdin */ 512 ttyn = ttyname(0); 513 else 514 ttyn = DEV_TTY_PATH; 515 tty = open(ttyn, O_RDWR); 516 if (tty < 0) { 517 /* use stderr instead of stdin... is it OK???? */ 518 tty = 2; 519 } 520 ttyf = fdopen(tty, "w"); 521 #ifdef __CYGWIN__ 522 check_cygwin_console(); 523 #endif 524 TerminalGet(tty, &d_ioval); 525 if (displayTitleTerm != NULL) { 526 struct w3m_term_info *p; 527 for (p = w3m_term_info_list; p->term != NULL; p++) { 528 if (!strncmp(displayTitleTerm, p->term, strlen(p->term))) { 529 title_str = p->title_str; 530 break; 531 } 532 } 533 } 534 #ifdef USE_MOUSE 535 { 536 char *term = getenv("TERM"); 537 if (term != NULL) { 538 struct w3m_term_info *p; 539 for (p = w3m_term_info_list; p->term != NULL; p++) { 540 if (!strncmp(term, p->term, strlen(p->term))) { 541 is_xterm = p->mouse_flag; 542 break; 543 } 544 } 545 } 546 } 547 #endif 548 return 0; 549 } 550 551 void 552 ttymode_set(int mode, int imode) 553 { 554 #ifndef __MINGW32_VERSION 555 TerminalMode ioval; 556 557 TerminalGet(tty, &ioval); 558 MODEFLAG(ioval) |= mode; 559 #ifndef HAVE_SGTTY_H 560 IMODEFLAG(ioval) |= imode; 561 #endif /* not HAVE_SGTTY_H */ 562 563 while (TerminalSet(tty, &ioval) == -1) { 564 if (errno == EINTR || errno == EAGAIN) 565 continue; 566 printf("Error occured while set %x: errno=%d\n", mode, errno); 567 reset_error_exit(SIGNAL_ARGLIST); 568 } 569 #endif 570 } 571 572 void 573 ttymode_reset(int mode, int imode) 574 { 575 #ifndef __MINGW32_VERSION 576 TerminalMode ioval; 577 578 TerminalGet(tty, &ioval); 579 MODEFLAG(ioval) &= ~mode; 580 #ifndef HAVE_SGTTY_H 581 IMODEFLAG(ioval) &= ~imode; 582 #endif /* not HAVE_SGTTY_H */ 583 584 while (TerminalSet(tty, &ioval) == -1) { 585 if (errno == EINTR || errno == EAGAIN) 586 continue; 587 printf("Error occured while reset %x: errno=%d\n", mode, errno); 588 reset_error_exit(SIGNAL_ARGLIST); 589 } 590 #endif /* __MINGW32_VERSION */ 591 } 592 593 #ifndef HAVE_SGTTY_H 594 void 595 set_cc(int spec, int val) 596 { 597 TerminalMode ioval; 598 599 TerminalGet(tty, &ioval); 600 ioval.c_cc[spec] = val; 601 while (TerminalSet(tty, &ioval) == -1) { 602 if (errno == EINTR || errno == EAGAIN) 603 continue; 604 printf("Error occured: errno=%d\n", errno); 605 reset_error_exit(SIGNAL_ARGLIST); 606 } 607 } 608 #endif /* not HAVE_SGTTY_H */ 609 610 void 611 close_tty(void) 612 { 613 if (tty > 2) 614 close(tty); 615 } 616 617 char * 618 ttyname_tty(void) 619 { 620 return ttyname(tty); 621 } 622 623 void 624 reset_tty(void) 625 { 626 writestr(T_op); /* turn off */ 627 writestr(T_me); 628 if (!Do_not_use_ti_te) { 629 if (T_te && *T_te) 630 writestr(T_te); 631 else 632 writestr(T_cl); 633 } 634 writestr(T_se); /* reset terminal */ 635 flush_tty(); 636 TerminalSet(tty, &d_ioval); 637 close_tty(); 638 } 639 640 static MySignalHandler 641 reset_exit_with_value(SIGNAL_ARG, int rval) 642 { 643 #ifdef USE_MOUSE 644 if (mouseActive) 645 mouse_end(); 646 #endif /* USE_MOUSE */ 647 reset_tty(); 648 w3m_exit(rval); 649 SIGNAL_RETURN; 650 } 651 652 MySignalHandler 653 reset_error_exit(SIGNAL_ARG) 654 { 655 reset_exit_with_value(SIGNAL_ARGLIST, 1); 656 } 657 658 MySignalHandler 659 reset_exit(SIGNAL_ARG) 660 { 661 reset_exit_with_value(SIGNAL_ARGLIST, 0); 662 } 663 664 MySignalHandler 665 error_dump(SIGNAL_ARG) 666 { 667 mySignal(SIGIOT, SIG_DFL); 668 reset_tty(); 669 abort(); 670 SIGNAL_RETURN; 671 } 672 673 void 674 set_int(void) 675 { 676 mySignal(SIGHUP, reset_exit); 677 mySignal(SIGINT, reset_exit); 678 mySignal(SIGQUIT, reset_exit); 679 mySignal(SIGTERM, reset_exit); 680 mySignal(SIGILL, error_dump); 681 mySignal(SIGIOT, error_dump); 682 mySignal(SIGFPE, error_dump); 683 #ifdef SIGBUS 684 mySignal(SIGBUS, error_dump); 685 #endif /* SIGBUS */ 686 /* mySignal(SIGSEGV, error_dump); */ 687 } 688 689 690 static void 691 setgraphchar(void) 692 { 693 int c, i, n; 694 695 for (c = 0; c < 96; c++) 696 gcmap[c] = (char)(c + ' '); 697 698 if (!T_ac) 699 return; 700 701 n = strlen(T_ac); 702 for (i = 0; i < n - 1; i += 2) { 703 c = (unsigned)T_ac[i] - ' '; 704 if (c >= 0 && c < 96) 705 gcmap[c] = T_ac[i + 1]; 706 } 707 } 708 709 #define graphchar(c) (((unsigned)(c)>=' ' && (unsigned)(c)<128)? gcmap[(c)-' '] : (c)) 710 #define GETSTR(v,s) {v = pt; suc = tgetstr(s,&pt); if (!suc) v = ""; else v = allocStr(suc, -1); } 711 712 void 713 getTCstr(void) 714 { 715 char *ent; 716 char *suc; 717 char *pt = funcstr; 718 int r; 719 720 ent = getenv("TERM") ? getenv("TERM") : DEFAULT_TERM; 721 if (ent == NULL) { 722 fprintf(stderr, "TERM is not set\n"); 723 reset_error_exit(SIGNAL_ARGLIST); 724 } 725 726 r = tgetent(bp, ent); 727 if (r != 1) { 728 /* Can't find termcap entry */ 729 fprintf(stderr, "Can't find termcap entry %s\n", ent); 730 reset_error_exit(SIGNAL_ARGLIST); 731 } 732 733 GETSTR(T_ce, "ce"); /* clear to the end of line */ 734 GETSTR(T_cd, "cd"); /* clear to the end of display */ 735 GETSTR(T_kr, "nd"); /* cursor right */ 736 if (suc == NULL) 737 GETSTR(T_kr, "kr"); 738 if (tgetflag("bs")) 739 T_kl = "\b"; /* cursor left */ 740 else { 741 GETSTR(T_kl, "le"); 742 if (suc == NULL) 743 GETSTR(T_kl, "kb"); 744 if (suc == NULL) 745 GETSTR(T_kl, "kl"); 746 } 747 GETSTR(T_cr, "cr"); /* carriage return */ 748 GETSTR(T_ta, "ta"); /* tab */ 749 GETSTR(T_sc, "sc"); /* save cursor */ 750 GETSTR(T_rc, "rc"); /* restore cursor */ 751 GETSTR(T_so, "so"); /* standout mode */ 752 GETSTR(T_se, "se"); /* standout mode end */ 753 GETSTR(T_us, "us"); /* underline mode */ 754 GETSTR(T_ue, "ue"); /* underline mode end */ 755 GETSTR(T_md, "md"); /* bold mode */ 756 GETSTR(T_me, "me"); /* bold mode end */ 757 GETSTR(T_cl, "cl"); /* clear screen */ 758 GETSTR(T_cm, "cm"); /* cursor move */ 759 GETSTR(T_al, "al"); /* append line */ 760 GETSTR(T_sr, "sr"); /* scroll reverse */ 761 GETSTR(T_ti, "ti"); /* terminal init */ 762 GETSTR(T_te, "te"); /* terminal end */ 763 GETSTR(T_nd, "nd"); /* move right one space */ 764 GETSTR(T_eA, "eA"); /* enable alternative charset */ 765 GETSTR(T_as, "as"); /* alternative (graphic) charset start */ 766 GETSTR(T_ae, "ae"); /* alternative (graphic) charset end */ 767 GETSTR(T_ac, "ac"); /* graphics charset pairs */ 768 GETSTR(T_op, "op"); /* set default color pair to its original value */ 769 #if defined( CYGWIN ) && CYGWIN < 1 770 /* for TERM=pcansi on MS-DOS prompt. */ 771 #if 0 772 T_eA = ""; 773 T_as = "\033[12m"; 774 T_ae = "\033[10m"; 775 T_ac = "l\001k\002m\003j\004x\005q\006n\020a\024v\025w\026u\027t\031"; 776 #endif 777 T_eA = ""; 778 T_as = ""; 779 T_ae = ""; 780 T_ac = ""; 781 #endif /* CYGWIN */ 782 783 LINES = COLS = 0; 784 setlinescols(); 785 setgraphchar(); 786 } 787 788 void 789 setlinescols(void) 790 { 791 char *p; 792 int i; 793 #ifdef __EMX__ 794 { 795 int s[2]; 796 _scrsize(s); 797 COLS = s[0]; 798 LINES = s[1]; 799 800 if (getenv("WINDOWID")) { 801 FILE *fd = popen("scrsize", "rt"); 802 if (fd) { 803 fscanf(fd, "%i %i", &COLS, &LINES); 804 pclose(fd); 805 } 806 } 807 } 808 #elif defined(HAVE_TERMIOS_H) && defined(TIOCGWINSZ) 809 struct winsize wins; 810 811 i = ioctl(tty, TIOCGWINSZ, &wins); 812 if (i >= 0 && wins.ws_row != 0 && wins.ws_col != 0) { 813 LINES = wins.ws_row; 814 COLS = wins.ws_col; 815 } 816 #endif /* defined(HAVE-TERMIOS_H) && defined(TIOCGWINSZ) */ 817 if (LINES <= 0 && (p = getenv("LINES")) != NULL && (i = atoi(p)) >= 0) 818 LINES = i; 819 if (COLS <= 0 && (p = getenv("COLUMNS")) != NULL && (i = atoi(p)) >= 0) 820 COLS = i; 821 if (LINES <= 0) 822 LINES = tgetnum("li"); /* number of line */ 823 if (COLS <= 0) 824 COLS = tgetnum("co"); /* number of column */ 825 if (COLS > MAX_COLUMN) 826 COLS = MAX_COLUMN; 827 if (LINES > MAX_LINE) 828 LINES = MAX_LINE; 829 #if defined(__CYGWIN__) 830 LASTLINE = LINES - (isWinConsole == TERM_CYGWIN_RESERVE_IME ? 2 : 1); 831 #endif /* defined(__CYGWIN__) */ 832 } 833 834 void 835 setupscreen(void) 836 { 837 int i; 838 839 if (LINES + 1 > max_LINES) { 840 max_LINES = LINES + 1; 841 max_COLS = 0; 842 ScreenElem = New_N(Screen, max_LINES); 843 ScreenImage = New_N(Screen *, max_LINES); 844 } 845 if (COLS + 1 > max_COLS) { 846 max_COLS = COLS + 1; 847 for (i = 0; i < max_LINES; i++) { 848 #ifdef USE_M17N 849 ScreenElem[i].lineimage = New_N(char *, max_COLS); 850 bzero((void *)ScreenElem[i].lineimage, max_COLS * sizeof(char *)); 851 #else 852 ScreenElem[i].lineimage = New_N(char, max_COLS); 853 #endif 854 ScreenElem[i].lineprop = New_N(l_prop, max_COLS); 855 } 856 } 857 for (i = 0; i < LINES; i++) { 858 ScreenImage[i] = &ScreenElem[i]; 859 ScreenImage[i]->lineprop[0] = S_EOL; 860 ScreenImage[i]->isdirty = 0; 861 } 862 for (; i < max_LINES; i++) { 863 ScreenElem[i].isdirty = L_UNUSED; 864 } 865 866 clear(); 867 } 868 869 /* 870 * Screen initialize 871 */ 872 int 873 initscr(void) 874 { 875 if (set_tty() < 0) 876 return -1; 877 set_int(); 878 getTCstr(); 879 if (T_ti && !Do_not_use_ti_te) 880 writestr(T_ti); 881 setupscreen(); 882 return 0; 883 } 884 885 static int 886 write1(char c) 887 { 888 putc(c, ttyf); 889 #ifdef SCREEN_DEBUG 890 flush_tty(); 891 #endif /* SCREEN_DEBUG */ 892 return 0; 893 } 894 895 void 896 move(int line, int column) 897 { 898 if (line >= 0 && line < LINES) 899 CurLine = line; 900 if (column >= 0 && column < COLS) 901 CurColumn = column; 902 } 903 904 #ifdef USE_BG_COLOR 905 #define M_SPACE (S_SCREENPROP|S_COLORED|S_BCOLORED|S_GRAPHICS) 906 #else /* not USE_BG_COLOR */ 907 #define M_SPACE (S_SCREENPROP|S_COLORED|S_GRAPHICS) 908 #endif /* not USE_BG_COLOR */ 909 910 static int 911 #ifdef USE_M17N 912 need_redraw(char *c1, l_prop pr1, char *c2, l_prop pr2) 913 { 914 if (!c1 || !c2 || strcmp(c1, c2)) 915 return 1; 916 if (*c1 == ' ') 917 #else 918 need_redraw(char c1, l_prop pr1, char c2, l_prop pr2) 919 { 920 if (c1 != c2) 921 return 1; 922 if (c1 == ' ') 923 #endif 924 return (pr1 ^ pr2) & M_SPACE & ~S_DIRTY; 925 926 if ((pr1 ^ pr2) & ~S_DIRTY) 927 return 1; 928 929 return 0; 930 } 931 932 #define M_CEOL (~(M_SPACE|C_WHICHCHAR)) 933 934 #ifdef USE_M17N 935 #define SPACE " " 936 #else 937 #define SPACE ' ' 938 #endif 939 940 #ifdef USE_M17N 941 void 942 addch(char c) 943 { 944 addmch(&c, 1); 945 } 946 947 void 948 addmch(char *pc, size_t len) 949 #else 950 void 951 addch(char pc) 952 #endif 953 { 954 l_prop *pr; 955 int dest, i; 956 short *dirty; 957 #ifdef USE_M17N 958 static Str tmp = NULL; 959 char **p; 960 char c = *pc; 961 int width = wtf_width((wc_uchar *) pc); 962 963 if (tmp == NULL) 964 tmp = Strnew(); 965 Strcopy_charp_n(tmp, pc, len); 966 pc = tmp->ptr; 967 #else 968 char *p; 969 char c = pc; 970 #endif 971 972 if (CurColumn == COLS) 973 wrap(); 974 if (CurColumn >= COLS) 975 return; 976 p = ScreenImage[CurLine]->lineimage; 977 pr = ScreenImage[CurLine]->lineprop; 978 dirty = &ScreenImage[CurLine]->isdirty; 979 980 #ifndef USE_M17N 981 /* Eliminate unprintables according to * iso-8859-*. 982 * Particularly 0x96 messes up T.Dickey's * (xfree-)xterm */ 983 if (IS_INTSPACE(c)) 984 c = ' '; 985 #endif 986 987 if (pr[CurColumn] & S_EOL) { 988 if (c == ' ' && !(CurrentMode & M_SPACE)) { 989 CurColumn++; 990 return; 991 } 992 for (i = CurColumn; i >= 0 && (pr[i] & S_EOL); i--) { 993 SETCH(p[i], SPACE, 1); 994 SETPROP(pr[i], (pr[i] & M_CEOL) | C_ASCII); 995 } 996 } 997 998 if (c == '\t' || c == '\n' || c == '\r' || c == '\b') 999 SETCHMODE(CurrentMode, C_CTRL); 1000 #ifdef USE_M17N 1001 else if (len > 1) 1002 SETCHMODE(CurrentMode, C_WCHAR1); 1003 #endif 1004 else if (!IS_CNTRL(c)) 1005 SETCHMODE(CurrentMode, C_ASCII); 1006 else 1007 return; 1008 1009 /* Required to erase bold or underlined character for some * terminal 1010 * emulators. */ 1011 #ifdef USE_M17N 1012 i = CurColumn + width - 1; 1013 #else 1014 i = CurColumn; 1015 #endif 1016 if (i < COLS && 1017 (((pr[i] & S_BOLD) && need_redraw(p[i], pr[i], pc, CurrentMode)) || 1018 ((pr[i] & S_UNDERLINE) && !(CurrentMode & S_UNDERLINE)))) { 1019 touch_line(); 1020 i++; 1021 if (i < COLS) { 1022 touch_column(i); 1023 if (pr[i] & S_EOL) { 1024 SETCH(p[i], SPACE, 1); 1025 SETPROP(pr[i], (pr[i] & M_CEOL) | C_ASCII); 1026 } 1027 #ifdef USE_M17N 1028 else { 1029 for (i++; i < COLS && CHMODE(pr[i]) == C_WCHAR2; i++) 1030 touch_column(i); 1031 } 1032 #endif 1033 } 1034 } 1035 1036 #ifdef USE_M17N 1037 if (CurColumn + width > COLS) { 1038 touch_line(); 1039 for (i = CurColumn; i < COLS; i++) { 1040 SETCH(p[i], SPACE, 1); 1041 SETPROP(pr[i], (pr[i] & ~C_WHICHCHAR) | C_ASCII); 1042 touch_column(i); 1043 } 1044 wrap(); 1045 if (CurColumn + width > COLS) 1046 return; 1047 p = ScreenImage[CurLine]->lineimage; 1048 pr = ScreenImage[CurLine]->lineprop; 1049 } 1050 if (CHMODE(pr[CurColumn]) == C_WCHAR2) { 1051 touch_line(); 1052 for (i = CurColumn - 1; i >= 0; i--) { 1053 l_prop l = CHMODE(pr[i]); 1054 SETCH(p[i], SPACE, 1); 1055 SETPROP(pr[i], (pr[i] & ~C_WHICHCHAR) | C_ASCII); 1056 touch_column(i); 1057 if (l != C_WCHAR2) 1058 break; 1059 } 1060 } 1061 #endif 1062 if (CHMODE(CurrentMode) != C_CTRL) { 1063 if (need_redraw(p[CurColumn], pr[CurColumn], pc, CurrentMode)) { 1064 SETCH(p[CurColumn], pc, len); 1065 SETPROP(pr[CurColumn], CurrentMode); 1066 touch_line(); 1067 touch_column(CurColumn); 1068 #ifdef USE_M17N 1069 SETCHMODE(CurrentMode, C_WCHAR2); 1070 for (i = CurColumn + 1; i < CurColumn + width; i++) { 1071 SETCH(p[i], SPACE, 1); 1072 SETPROP(pr[i], (pr[CurColumn] & ~C_WHICHCHAR) | C_WCHAR2); 1073 touch_column(i); 1074 } 1075 for (; i < COLS && CHMODE(pr[i]) == C_WCHAR2; i++) { 1076 SETCH(p[i], SPACE, 1); 1077 SETPROP(pr[i], (pr[i] & ~C_WHICHCHAR) | C_ASCII); 1078 touch_column(i); 1079 } 1080 } 1081 CurColumn += width; 1082 #else 1083 } 1084 CurColumn++; 1085 #endif 1086 } 1087 else if (c == '\t') { 1088 dest = (CurColumn + tab_step) / tab_step * tab_step; 1089 if (dest >= COLS) { 1090 wrap(); 1091 touch_line(); 1092 dest = tab_step; 1093 p = ScreenImage[CurLine]->lineimage; 1094 pr = ScreenImage[CurLine]->lineprop; 1095 } 1096 for (i = CurColumn; i < dest; i++) { 1097 if (need_redraw(p[i], pr[i], SPACE, CurrentMode)) { 1098 SETCH(p[i], SPACE, 1); 1099 SETPROP(pr[i], CurrentMode); 1100 touch_line(); 1101 touch_column(i); 1102 } 1103 } 1104 CurColumn = i; 1105 } 1106 else if (c == '\n') { 1107 wrap(); 1108 } 1109 else if (c == '\r') { /* Carriage return */ 1110 CurColumn = 0; 1111 } 1112 else if (c == '\b' && CurColumn > 0) { /* Backspace */ 1113 CurColumn--; 1114 #ifdef USE_M17N 1115 while (CurColumn > 0 && CHMODE(pr[CurColumn]) == C_WCHAR2) 1116 CurColumn--; 1117 #endif 1118 } 1119 } 1120 1121 void 1122 wrap(void) 1123 { 1124 if (CurLine == LASTLINE) 1125 return; 1126 CurLine++; 1127 CurColumn = 0; 1128 } 1129 1130 void 1131 touch_column(int col) 1132 { 1133 if (col >= 0 && col < COLS) 1134 ScreenImage[CurLine]->lineprop[col] |= S_DIRTY; 1135 } 1136 1137 void 1138 touch_line(void) 1139 { 1140 if (!(ScreenImage[CurLine]->isdirty & L_DIRTY)) { 1141 int i; 1142 for (i = 0; i < COLS; i++) 1143 ScreenImage[CurLine]->lineprop[i] &= ~S_DIRTY; 1144 ScreenImage[CurLine]->isdirty |= L_DIRTY; 1145 } 1146 1147 } 1148 1149 void 1150 standout(void) 1151 { 1152 CurrentMode |= S_STANDOUT; 1153 } 1154 1155 void 1156 standend(void) 1157 { 1158 CurrentMode &= ~S_STANDOUT; 1159 } 1160 1161 void 1162 toggle_stand(void) 1163 { 1164 #ifdef USE_M17N 1165 int i; 1166 #endif 1167 l_prop *pr = ScreenImage[CurLine]->lineprop; 1168 pr[CurColumn] ^= S_STANDOUT; 1169 #ifdef USE_M17N 1170 if (CHMODE(pr[CurColumn]) != C_WCHAR2) { 1171 for (i = CurColumn + 1; CHMODE(pr[i]) == C_WCHAR2; i++) 1172 pr[i] ^= S_STANDOUT; 1173 } 1174 #endif 1175 } 1176 1177 void 1178 bold(void) 1179 { 1180 CurrentMode |= S_BOLD; 1181 } 1182 1183 void 1184 boldend(void) 1185 { 1186 CurrentMode &= ~S_BOLD; 1187 } 1188 1189 void 1190 underline(void) 1191 { 1192 CurrentMode |= S_UNDERLINE; 1193 } 1194 1195 void 1196 underlineend(void) 1197 { 1198 CurrentMode &= ~S_UNDERLINE; 1199 } 1200 1201 void 1202 graphstart(void) 1203 { 1204 CurrentMode |= S_GRAPHICS; 1205 } 1206 1207 void 1208 graphend(void) 1209 { 1210 CurrentMode &= ~S_GRAPHICS; 1211 } 1212 1213 int 1214 graph_ok(void) 1215 { 1216 if (UseGraphicChar != GRAPHIC_CHAR_DEC) 1217 return 0; 1218 return T_as[0] != 0 && T_ae[0] != 0 && T_ac[0] != 0; 1219 } 1220 1221 void 1222 setfcolor(int color) 1223 { 1224 CurrentMode &= ~COL_FCOLOR; 1225 if ((color & 0xf) <= 7) 1226 CurrentMode |= (((color & 7) | 8) << 8); 1227 } 1228 1229 static char * 1230 color_seq(int colmode) 1231 { 1232 static char seqbuf[32]; 1233 sprintf(seqbuf, "\033[%dm", ((colmode >> 8) & 7) + 30); 1234 return seqbuf; 1235 } 1236 1237 #ifdef USE_BG_COLOR 1238 void 1239 setbcolor(int color) 1240 { 1241 CurrentMode &= ~COL_BCOLOR; 1242 if ((color & 0xf) <= 7) 1243 CurrentMode |= (((color & 7) | 8) << 12); 1244 } 1245 1246 static char * 1247 bcolor_seq(int colmode) 1248 { 1249 static char seqbuf[32]; 1250 sprintf(seqbuf, "\033[%dm", ((colmode >> 12) & 7) + 40); 1251 return seqbuf; 1252 } 1253 #endif /* USE_BG_COLOR */ 1254 1255 #define RF_NEED_TO_MOVE 0 1256 #define RF_CR_OK 1 1257 #define RF_NONEED_TO_MOVE 2 1258 #ifdef USE_BG_COLOR 1259 #define M_MEND (S_STANDOUT|S_UNDERLINE|S_BOLD|S_COLORED|S_BCOLORED|S_GRAPHICS) 1260 #else /* not USE_BG_COLOR */ 1261 #define M_MEND (S_STANDOUT|S_UNDERLINE|S_BOLD|S_COLORED|S_GRAPHICS) 1262 #endif /* not USE_BG_COLOR */ 1263 void 1264 refresh(void) 1265 { 1266 int line, col, pcol; 1267 int pline = CurLine; 1268 int moved = RF_NEED_TO_MOVE; 1269 #ifdef USE_M17N 1270 char **pc; 1271 #else 1272 char *pc; 1273 #endif 1274 l_prop *pr, mode = 0; 1275 l_prop color = COL_FTERM; 1276 #ifdef USE_BG_COLOR 1277 l_prop bcolor = COL_BTERM; 1278 #endif /* USE_BG_COLOR */ 1279 short *dirty; 1280 1281 #ifdef USE_M17N 1282 wc_putc_init(InnerCharset, DisplayCharset); 1283 #endif 1284 for (line = 0; line <= LASTLINE; line++) { 1285 dirty = &ScreenImage[line]->isdirty; 1286 if (*dirty & L_DIRTY) { 1287 *dirty &= ~L_DIRTY; 1288 pc = ScreenImage[line]->lineimage; 1289 pr = ScreenImage[line]->lineprop; 1290 for (col = 0; col < COLS && !(pr[col] & S_EOL); col++) { 1291 if (*dirty & L_NEED_CE && col >= ScreenImage[line]->eol) { 1292 if (need_redraw(pc[col], pr[col], SPACE, 0)) 1293 break; 1294 } 1295 else { 1296 if (pr[col] & S_DIRTY) 1297 break; 1298 } 1299 } 1300 if (*dirty & (L_NEED_CE | L_CLRTOEOL)) { 1301 pcol = ScreenImage[line]->eol; 1302 if (pcol >= COLS) { 1303 *dirty &= ~(L_NEED_CE | L_CLRTOEOL); 1304 pcol = col; 1305 } 1306 } 1307 else { 1308 pcol = col; 1309 } 1310 if (line < LINES - 2 && pline == line - 1 && pcol == 0) { 1311 switch (moved) { 1312 case RF_NEED_TO_MOVE: 1313 MOVE(line, 0); 1314 moved = RF_CR_OK; 1315 break; 1316 case RF_CR_OK: 1317 write1('\n'); 1318 write1('\r'); 1319 break; 1320 case RF_NONEED_TO_MOVE: 1321 moved = RF_CR_OK; 1322 break; 1323 } 1324 } 1325 else { 1326 MOVE(line, pcol); 1327 moved = RF_CR_OK; 1328 } 1329 if (*dirty & (L_NEED_CE | L_CLRTOEOL)) { 1330 writestr(T_ce); 1331 if (col != pcol) 1332 MOVE(line, col); 1333 } 1334 pline = line; 1335 pcol = col; 1336 for (; col < COLS; col++) { 1337 if (pr[col] & S_EOL) 1338 break; 1339 1340 /* 1341 * some terminal emulators do linefeed when a 1342 * character is put on COLS-th column. this behavior 1343 * is different from one of vt100, but such terminal 1344 * emulators are used as vt100-compatible 1345 * emulators. This behaviour causes scroll when a 1346 * character is drawn on (COLS-1,LINES-1) point. To 1347 * avoid the scroll, I prohibit to draw character on 1348 * (COLS-1,LINES-1). 1349 */ 1350 #if !defined(USE_BG_COLOR) || defined(__CYGWIN__) 1351 #ifdef __CYGWIN__ 1352 if (isWinConsole) 1353 #endif 1354 if (line == LINES - 1 && col == COLS - 1) 1355 break; 1356 #endif /* !defined(USE_BG_COLOR) || defined(__CYGWIN__) */ 1357 if ((!(pr[col] & S_STANDOUT) && (mode & S_STANDOUT)) || 1358 (!(pr[col] & S_UNDERLINE) && (mode & S_UNDERLINE)) || 1359 (!(pr[col] & S_BOLD) && (mode & S_BOLD)) || 1360 (!(pr[col] & S_COLORED) && (mode & S_COLORED)) 1361 #ifdef USE_BG_COLOR 1362 || (!(pr[col] & S_BCOLORED) && (mode & S_BCOLORED)) 1363 #endif /* USE_BG_COLOR */ 1364 || (!(pr[col] & S_GRAPHICS) && (mode & S_GRAPHICS))) { 1365 if ((mode & S_COLORED) 1366 #ifdef USE_BG_COLOR 1367 || (mode & S_BCOLORED) 1368 #endif /* USE_BG_COLOR */ 1369 ) 1370 writestr(T_op); 1371 if (mode & S_GRAPHICS) 1372 writestr(T_ae); 1373 writestr(T_me); 1374 mode &= ~M_MEND; 1375 } 1376 if ((*dirty & L_NEED_CE && col >= ScreenImage[line]->eol) ? 1377 need_redraw(pc[col], pr[col], SPACE, 1378 0) : (pr[col] & S_DIRTY)) { 1379 if (pcol == col - 1) 1380 writestr(T_nd); 1381 else if (pcol != col) 1382 MOVE(line, col); 1383 1384 if ((pr[col] & S_STANDOUT) && !(mode & S_STANDOUT)) { 1385 writestr(T_so); 1386 mode |= S_STANDOUT; 1387 } 1388 if ((pr[col] & S_UNDERLINE) && !(mode & S_UNDERLINE)) { 1389 writestr(T_us); 1390 mode |= S_UNDERLINE; 1391 } 1392 if ((pr[col] & S_BOLD) && !(mode & S_BOLD)) { 1393 writestr(T_md); 1394 mode |= S_BOLD; 1395 } 1396 if ((pr[col] & S_COLORED) && (pr[col] ^ mode) & COL_FCOLOR) { 1397 color = (pr[col] & COL_FCOLOR); 1398 mode = ((mode & ~COL_FCOLOR) | color); 1399 writestr(color_seq(color)); 1400 } 1401 #ifdef USE_BG_COLOR 1402 if ((pr[col] & S_BCOLORED) 1403 && (pr[col] ^ mode) & COL_BCOLOR) { 1404 bcolor = (pr[col] & COL_BCOLOR); 1405 mode = ((mode & ~COL_BCOLOR) | bcolor); 1406 writestr(bcolor_seq(bcolor)); 1407 } 1408 #endif /* USE_BG_COLOR */ 1409 if ((pr[col] & S_GRAPHICS) && !(mode & S_GRAPHICS)) { 1410 #ifdef USE_M17N 1411 wc_putc_end(ttyf); 1412 #endif 1413 if (!graph_enabled) { 1414 graph_enabled = 1; 1415 writestr(T_eA); 1416 } 1417 writestr(T_as); 1418 mode |= S_GRAPHICS; 1419 } 1420 #ifdef USE_M17N 1421 if (pr[col] & S_GRAPHICS) 1422 write1(graphchar(*pc[col])); 1423 else if (CHMODE(pr[col]) != C_WCHAR2) 1424 wc_putc(pc[col], ttyf); 1425 #else 1426 write1((pr[col] & S_GRAPHICS) ? graphchar(pc[col]) : 1427 pc[col]); 1428 #endif 1429 pcol = col + 1; 1430 } 1431 } 1432 if (col == COLS) 1433 moved = RF_NEED_TO_MOVE; 1434 for (; col < COLS && !(pr[col] & S_EOL); col++) 1435 pr[col] |= S_EOL; 1436 } 1437 *dirty &= ~(L_NEED_CE | L_CLRTOEOL); 1438 if (mode & M_MEND) { 1439 if (mode & (S_COLORED 1440 #ifdef USE_BG_COLOR 1441 | S_BCOLORED 1442 #endif /* USE_BG_COLOR */ 1443 )) 1444 writestr(T_op); 1445 if (mode & S_GRAPHICS) { 1446 writestr(T_ae); 1447 #ifdef USE_M17N 1448 wc_putc_clear_status(); 1449 #endif 1450 } 1451 writestr(T_me); 1452 mode &= ~M_MEND; 1453 } 1454 } 1455 #ifdef USE_M17N 1456 wc_putc_end(ttyf); 1457 #endif 1458 MOVE(CurLine, CurColumn); 1459 flush_tty(); 1460 } 1461 1462 void 1463 clear(void) 1464 { 1465 int i, j; 1466 l_prop *p; 1467 writestr(T_cl); 1468 move(0, 0); 1469 for (i = 0; i < LINES; i++) { 1470 ScreenImage[i]->isdirty = 0; 1471 p = ScreenImage[i]->lineprop; 1472 for (j = 0; j < COLS; j++) { 1473 p[j] = S_EOL; 1474 } 1475 } 1476 CurrentMode = C_ASCII; 1477 } 1478 1479 #ifdef USE_RAW_SCROLL 1480 static void 1481 scroll_raw(void) 1482 { /* raw scroll */ 1483 MOVE(LINES - 1, 0); 1484 write1('\n'); 1485 } 1486 1487 void 1488 scroll(int n) 1489 { /* scroll up */ 1490 int cli = CurLine, cco = CurColumn; 1491 Screen *t; 1492 int i, j, k; 1493 1494 i = LINES; 1495 j = n; 1496 do { 1497 k = j; 1498 j = i % k; 1499 i = k; 1500 } while (j); 1501 do { 1502 k--; 1503 i = k; 1504 j = (i + n) % LINES; 1505 t = ScreenImage[k]; 1506 while (j != k) { 1507 ScreenImage[i] = ScreenImage[j]; 1508 i = j; 1509 j = (i + n) % LINES; 1510 } 1511 ScreenImage[i] = t; 1512 } while (k); 1513 1514 for (i = 0; i < n; i++) { 1515 t = ScreenImage[LINES - 1 - i]; 1516 t->isdirty = 0; 1517 for (j = 0; j < COLS; j++) 1518 t->lineprop[j] = S_EOL; 1519 scroll_raw(); 1520 } 1521 move(cli, cco); 1522 } 1523 1524 void 1525 rscroll(int n) 1526 { /* scroll down */ 1527 int cli = CurLine, cco = CurColumn; 1528 Screen *t; 1529 int i, j, k; 1530 1531 i = LINES; 1532 j = n; 1533 do { 1534 k = j; 1535 j = i % k; 1536 i = k; 1537 } while (j); 1538 do { 1539 k--; 1540 i = k; 1541 j = (LINES + i - n) % LINES; 1542 t = ScreenImage[k]; 1543 while (j != k) { 1544 ScreenImage[i] = ScreenImage[j]; 1545 i = j; 1546 j = (LINES + i - n) % LINES; 1547 } 1548 ScreenImage[i] = t; 1549 } while (k); 1550 if (T_sr && *T_sr) { 1551 MOVE(0, 0); 1552 for (i = 0; i < n; i++) { 1553 t = ScreenImage[i]; 1554 t->isdirty = 0; 1555 for (j = 0; j < COLS; j++) 1556 t->lineprop[j] = S_EOL; 1557 writestr(T_sr); 1558 } 1559 move(cli, cco); 1560 } 1561 else { 1562 for (i = 0; i < LINES; i++) { 1563 t = ScreenImage[i]; 1564 t->isdirty |= L_DIRTY | L_NEED_CE; 1565 for (j = 0; j < COLS; j++) { 1566 t->lineprop[j] |= S_DIRTY; 1567 } 1568 } 1569 } 1570 } 1571 #endif 1572 1573 #if 0 1574 void 1575 need_clrtoeol(void) 1576 { 1577 /* Clear to the end of line as the need arises */ 1578 l_prop *lprop = ScreenImage[CurLine]->lineprop; 1579 1580 if (lprop[CurColumn] & S_EOL) 1581 return; 1582 1583 if (!(ScreenImage[CurLine]->isdirty & (L_NEED_CE | L_CLRTOEOL)) || 1584 ScreenImage[CurLine]->eol > CurColumn) 1585 ScreenImage[CurLine]->eol = CurColumn; 1586 1587 ScreenImage[CurLine]->isdirty |= L_NEED_CE; 1588 } 1589 #endif /* 0 */ 1590 1591 /* XXX: conflicts with curses's clrtoeol(3) ? */ 1592 void 1593 clrtoeol(void) 1594 { /* Clear to the end of line */ 1595 int i; 1596 l_prop *lprop = ScreenImage[CurLine]->lineprop; 1597 1598 if (lprop[CurColumn] & S_EOL) 1599 return; 1600 1601 if (!(ScreenImage[CurLine]->isdirty & (L_NEED_CE | L_CLRTOEOL)) || 1602 ScreenImage[CurLine]->eol > CurColumn) 1603 ScreenImage[CurLine]->eol = CurColumn; 1604 1605 ScreenImage[CurLine]->isdirty |= L_CLRTOEOL; 1606 touch_line(); 1607 for (i = CurColumn; i < COLS && !(lprop[i] & S_EOL); i++) { 1608 lprop[i] = S_EOL | S_DIRTY; 1609 } 1610 } 1611 1612 #ifdef USE_BG_COLOR 1613 void 1614 clrtoeol_with_bcolor(void) 1615 { 1616 int i, cli, cco; 1617 l_prop pr; 1618 1619 if (!(CurrentMode & S_BCOLORED)) { 1620 clrtoeol(); 1621 return; 1622 } 1623 cli = CurLine; 1624 cco = CurColumn; 1625 pr = CurrentMode; 1626 CurrentMode = (CurrentMode & (M_CEOL | S_BCOLORED)) | C_ASCII; 1627 for (i = CurColumn; i < COLS; i++) 1628 addch(' '); 1629 move(cli, cco); 1630 CurrentMode = pr; 1631 } 1632 1633 void 1634 clrtoeolx(void) 1635 { 1636 clrtoeol_with_bcolor(); 1637 } 1638 #else /* not USE_BG_COLOR */ 1639 1640 void 1641 clrtoeolx(void) 1642 { 1643 clrtoeol(); 1644 } 1645 #endif /* not USE_BG_COLOR */ 1646 1647 void 1648 clrtobot_eol(void (*clrtoeol) ()) 1649 { 1650 int l, c; 1651 1652 l = CurLine; 1653 c = CurColumn; 1654 (*clrtoeol) (); 1655 CurColumn = 0; 1656 CurLine++; 1657 for (; CurLine < LINES; CurLine++) 1658 (*clrtoeol) (); 1659 CurLine = l; 1660 CurColumn = c; 1661 } 1662 1663 void 1664 clrtobot(void) 1665 { 1666 clrtobot_eol(clrtoeol); 1667 } 1668 1669 void 1670 clrtobotx(void) 1671 { 1672 clrtobot_eol(clrtoeolx); 1673 } 1674 1675 #if 0 1676 void 1677 no_clrtoeol(void) 1678 { 1679 int i; 1680 l_prop *lprop = ScreenImage[CurLine]->lineprop; 1681 1682 ScreenImage[CurLine]->isdirty &= ~L_CLRTOEOL; 1683 } 1684 #endif /* 0 */ 1685 1686 void 1687 addstr(char *s) 1688 { 1689 #ifdef USE_M17N 1690 int len; 1691 1692 while (*s != '\0') { 1693 len = wtf_len((wc_uchar *) s); 1694 addmch(s, len); 1695 s += len; 1696 } 1697 #else 1698 while (*s != '\0') 1699 addch(*(s++)); 1700 #endif 1701 } 1702 1703 void 1704 addnstr(char *s, int n) 1705 { 1706 int i; 1707 #ifdef USE_M17N 1708 int len, width; 1709 1710 for (i = 0; *s != '\0';) { 1711 width = wtf_width((wc_uchar *) s); 1712 if (i + width > n) 1713 break; 1714 len = wtf_len((wc_uchar *) s); 1715 addmch(s, len); 1716 s += len; 1717 i += width; 1718 } 1719 #else 1720 for (i = 0; i < n && *s != '\0'; i++) 1721 addch(*(s++)); 1722 #endif 1723 } 1724 1725 void 1726 addnstr_sup(char *s, int n) 1727 { 1728 int i; 1729 #ifdef USE_M17N 1730 int len, width; 1731 1732 for (i = 0; *s != '\0';) { 1733 width = wtf_width((wc_uchar *) s); 1734 if (i + width > n) 1735 break; 1736 len = wtf_len((wc_uchar *) s); 1737 addmch(s, len); 1738 s += len; 1739 i += width; 1740 } 1741 #else 1742 for (i = 0; i < n && *s != '\0'; i++) 1743 addch(*(s++)); 1744 #endif 1745 for (; i < n; i++) 1746 addch(' '); 1747 } 1748 1749 void 1750 crmode(void) 1751 #ifndef HAVE_SGTTY_H 1752 { 1753 ttymode_reset(ICANON, IXON); 1754 ttymode_set(ISIG, 0); 1755 #ifdef HAVE_TERMIOS_H 1756 set_cc(VMIN, 1); 1757 #else /* not HAVE_TERMIOS_H */ 1758 set_cc(VEOF, 1); 1759 #endif /* not HAVE_TERMIOS_H */ 1760 } 1761 #else /* HAVE_SGTTY_H */ 1762 { 1763 ttymode_set(CBREAK, 0); 1764 } 1765 #endif /* HAVE_SGTTY_H */ 1766 1767 void 1768 nocrmode(void) 1769 #ifndef HAVE_SGTTY_H 1770 { 1771 ttymode_set(ICANON, 0); 1772 #ifdef HAVE_TERMIOS_H 1773 set_cc(VMIN, 4); 1774 #else /* not HAVE_TERMIOS_H */ 1775 set_cc(VEOF, 4); 1776 #endif /* not HAVE_TERMIOS_H */ 1777 } 1778 #else /* HAVE_SGTTY_H */ 1779 { 1780 ttymode_reset(CBREAK, 0); 1781 } 1782 #endif /* HAVE_SGTTY_H */ 1783 1784 void 1785 term_echo(void) 1786 { 1787 ttymode_set(ECHO, 0); 1788 } 1789 1790 void 1791 term_noecho(void) 1792 { 1793 ttymode_reset(ECHO, 0); 1794 } 1795 1796 void 1797 term_raw(void) 1798 #ifndef HAVE_SGTTY_H 1799 #ifdef IEXTEN 1800 #define TTY_MODE ISIG|ICANON|ECHO|IEXTEN 1801 #else /* not IEXTEN */ 1802 #define TTY_MODE ISIG|ICANON|ECHO 1803 #endif /* not IEXTEN */ 1804 { 1805 ttymode_reset(TTY_MODE, IXON | IXOFF); 1806 #ifdef HAVE_TERMIOS_H 1807 set_cc(VMIN, 1); 1808 #else /* not HAVE_TERMIOS_H */ 1809 set_cc(VEOF, 1); 1810 #endif /* not HAVE_TERMIOS_H */ 1811 } 1812 #else /* HAVE_SGTTY_H */ 1813 { 1814 ttymode_set(RAW, 0); 1815 } 1816 #endif /* HAVE_SGTTY_H */ 1817 1818 void 1819 term_cooked(void) 1820 #ifndef HAVE_SGTTY_H 1821 { 1822 #ifdef __EMX__ 1823 /* On XFree86/OS2, some scrambled characters 1824 * will appear when asserting IEXTEN flag. 1825 */ 1826 ttymode_set((TTY_MODE) & ~IEXTEN, 0); 1827 #else 1828 ttymode_set(TTY_MODE, 0); 1829 #endif 1830 #ifdef HAVE_TERMIOS_H 1831 set_cc(VMIN, 4); 1832 #else /* not HAVE_TERMIOS_H */ 1833 set_cc(VEOF, 4); 1834 #endif /* not HAVE_TERMIOS_H */ 1835 } 1836 #else /* HAVE_SGTTY_H */ 1837 { 1838 ttymode_reset(RAW, 0); 1839 } 1840 #endif /* HAVE_SGTTY_H */ 1841 1842 void 1843 term_cbreak(void) 1844 { 1845 term_cooked(); 1846 term_noecho(); 1847 } 1848 1849 void 1850 term_title(char *s) 1851 { 1852 if (!fmInitialized) 1853 return; 1854 if (title_str != NULL) { 1855 #ifdef __CYGWIN__ 1856 if (isLocalConsole && title_str == CYGWIN_TITLE) { 1857 Str buff; 1858 buff = Sprintf(title_str, s); 1859 if (buff->length > 1024) { 1860 Strtruncate(buff, 1024); 1861 } 1862 SetConsoleTitle(buff->ptr); 1863 } 1864 else if (isLocalConsole || !isWinConsole) 1865 #endif 1866 fprintf(ttyf, title_str, s); 1867 } 1868 } 1869 1870 char 1871 getch(void) 1872 { 1873 char c; 1874 1875 while ( 1876 #ifdef SUPPORT_WIN9X_CONSOLE_MBCS 1877 read_win32_console(&c, 1) 1878 #else 1879 read(tty, &c, 1) 1880 #endif 1881 < (int)1) { 1882 if (errno == EINTR || errno == EAGAIN) 1883 continue; 1884 /* error happend on read(2) */ 1885 quitfm(); 1886 break; /* unreachable */ 1887 } 1888 return c; 1889 } 1890 1891 #ifdef USE_MOUSE 1892 #ifdef USE_GPM 1893 char 1894 wgetch(void *p) 1895 { 1896 char c; 1897 1898 /* read(tty, &c, 1); */ 1899 while (read(tty, &c, 1) < (ssize_t) 1) { 1900 if (errno == EINTR || errno == EAGAIN) 1901 continue; 1902 /* error happend on read(2) */ 1903 quitfm(); 1904 break; /* unreachable */ 1905 } 1906 return c; 1907 } 1908 1909 int 1910 do_getch() 1911 { 1912 if (is_xterm || !gpm_handler) 1913 return getch(); 1914 else 1915 return Gpm_Getch(); 1916 } 1917 #endif /* USE_GPM */ 1918 1919 #ifdef USE_SYSMOUSE 1920 int 1921 sysm_getch() 1922 { 1923 fd_set rfd; 1924 int key, x, y; 1925 1926 FD_ZERO(&rfd); 1927 FD_SET(tty, &rfd); 1928 while (select(tty + 1, &rfd, NULL, NULL, NULL) <= 0) { 1929 if (errno == EINTR) { 1930 x = xpix / cwidth; 1931 y = ypix / cheight; 1932 key = (*sysm_handler) (x, y, nbs, obs); 1933 if (key != 0) 1934 return key; 1935 } 1936 } 1937 return getch(); 1938 } 1939 1940 int 1941 do_getch() 1942 { 1943 if (is_xterm || !sysm_handler) 1944 return getch(); 1945 else 1946 return sysm_getch(); 1947 } 1948 1949 MySignalHandler 1950 sysmouse(SIGNAL_ARG) 1951 { 1952 struct mouse_info mi; 1953 1954 mi.operation = MOUSE_GETINFO; 1955 if (ioctl(tty, CONS_MOUSECTL, &mi) == -1) 1956 return; 1957 xpix = mi.u.data.x; 1958 ypix = mi.u.data.y; 1959 obs = nbs; 1960 nbs = mi.u.data.buttons & 0x7; 1961 /* for cosmetic bug in syscons.c on FreeBSD 3.[34] */ 1962 mi.operation = MOUSE_HIDE; 1963 ioctl(tty, CONS_MOUSECTL, &mi); 1964 mi.operation = MOUSE_SHOW; 1965 ioctl(tty, CONS_MOUSECTL, &mi); 1966 } 1967 #endif /* USE_SYSMOUSE */ 1968 #endif /* USE_MOUSE */ 1969 1970 void 1971 bell(void) 1972 { 1973 write1(7); 1974 } 1975 1976 void 1977 skip_escseq(void) 1978 { 1979 int c; 1980 1981 c = getch(); 1982 if (c == '[' || c == 'O') { 1983 c = getch(); 1984 #ifdef USE_MOUSE 1985 if (is_xterm && c == 'M') { 1986 getch(); 1987 getch(); 1988 getch(); 1989 } 1990 else 1991 #endif 1992 while (IS_DIGIT(c)) 1993 c = getch(); 1994 } 1995 } 1996 1997 int 1998 sleep_till_anykey(int sec, int purge) 1999 { 2000 fd_set rfd; 2001 struct timeval tim; 2002 int er, c, ret; 2003 TerminalMode ioval; 2004 2005 TerminalGet(tty, &ioval); 2006 term_raw(); 2007 2008 tim.tv_sec = sec; 2009 tim.tv_usec = 0; 2010 2011 FD_ZERO(&rfd); 2012 FD_SET(tty, &rfd); 2013 2014 ret = select(tty + 1, &rfd, 0, 0, &tim); 2015 if (ret > 0 && purge) { 2016 c = getch(); 2017 if (c == ESC_CODE) 2018 skip_escseq(); 2019 } 2020 er = TerminalSet(tty, &ioval); 2021 if (er == -1) { 2022 printf("Error occured: errno=%d\n", errno); 2023 reset_error_exit(SIGNAL_ARGLIST); 2024 } 2025 return ret; 2026 } 2027 2028 #ifdef USE_MOUSE 2029 2030 #define XTERM_ON {fputs("\033[?1001s\033[?1000h",ttyf); flush_tty();} 2031 #define XTERM_OFF {fputs("\033[?1000l\033[?1001r",ttyf); flush_tty();} 2032 #define CYGWIN_ON {fputs("\033[?1000h",ttyf); flush_tty();} 2033 #define CYGWIN_OFF {fputs("\033[?1000l",ttyf); flush_tty();} 2034 2035 #ifdef USE_GPM 2036 /* Linux console with GPM support */ 2037 2038 void 2039 mouse_init() 2040 { 2041 Gpm_Connect conn; 2042 extern int gpm_process_mouse(Gpm_Event *, void *); 2043 int r; 2044 2045 if (mouseActive) 2046 return; 2047 conn.eventMask = ~0; 2048 conn.defaultMask = 0; 2049 conn.maxMod = 0; 2050 conn.minMod = 0; 2051 2052 gpm_handler = NULL; 2053 r = Gpm_Open(&conn, 0); 2054 if (r == -2) { 2055 /* 2056 * If Gpm_Open() success, returns >= 0 2057 * Gpm_Open() returns -2 in case of xterm. 2058 * Gpm_Close() is necessary here. Otherwise, 2059 * xterm is being left in the mode where the mouse clicks are 2060 * passed through to the application. 2061 */ 2062 Gpm_Close(); 2063 is_xterm = (NEED_XTERM_ON | NEED_XTERM_OFF); 2064 } 2065 else if (r >= 0) { 2066 gpm_handler = gpm_process_mouse; 2067 is_xterm = 0; 2068 } 2069 if (is_xterm) { 2070 XTERM_ON; 2071 } 2072 mouseActive = 1; 2073 } 2074 2075 void 2076 mouse_end() 2077 { 2078 if (mouseActive == 0) 2079 return; 2080 if (is_xterm) { 2081 XTERM_OFF; 2082 } 2083 else 2084 Gpm_Close(); 2085 mouseActive = 0; 2086 } 2087 2088 #elif defined(USE_SYSMOUSE) 2089 /* *BSD console with sysmouse support */ 2090 void 2091 mouse_init() 2092 { 2093 mouse_info_t mi; 2094 extern int sysm_process_mouse(); 2095 2096 if (mouseActive) 2097 return; 2098 if (is_xterm) { 2099 XTERM_ON; 2100 } 2101 else { 2102 #if defined(FBIO_MODEINFO) || defined(CONS_MODEINFO) /* FreeBSD > 2.x */ 2103 #ifndef FBIO_GETMODE /* FreeBSD 3.x */ 2104 #define FBIO_GETMODE CONS_GET 2105 #define FBIO_MODEINFO CONS_MODEINFO 2106 #endif /* FBIO_GETMODE */ 2107 video_info_t vi; 2108 2109 if (ioctl(tty, FBIO_GETMODE, &vi.vi_mode) != -1 && 2110 ioctl(tty, FBIO_MODEINFO, &vi) != -1) { 2111 cwidth = vi.vi_cwidth; 2112 cheight = vi.vi_cheight; 2113 } 2114 #endif /* defined(FBIO_MODEINFO) || 2115 * defined(CONS_MODEINFO) */ 2116 mySignal(SIGUSR2, SIG_IGN); 2117 mi.operation = MOUSE_MODE; 2118 mi.u.mode.mode = 0; 2119 mi.u.mode.signal = SIGUSR2; 2120 sysm_handler = NULL; 2121 if (ioctl(tty, CONS_MOUSECTL, &mi) != -1) { 2122 mySignal(SIGUSR2, sysmouse); 2123 mi.operation = MOUSE_SHOW; 2124 ioctl(tty, CONS_MOUSECTL, &mi); 2125 sysm_handler = sysm_process_mouse; 2126 } 2127 } 2128 mouseActive = 1; 2129 } 2130 2131 void 2132 mouse_end() 2133 { 2134 if (mouseActive == 0) 2135 return; 2136 if (is_xterm) { 2137 XTERM_OFF; 2138 } 2139 else { 2140 mouse_info_t mi; 2141 mi.operation = MOUSE_MODE; 2142 mi.u.mode.mode = 0; 2143 mi.u.mode.signal = 0; 2144 ioctl(tty, CONS_MOUSECTL, &mi); 2145 } 2146 mouseActive = 0; 2147 } 2148 2149 #else 2150 /* not GPM nor SYSMOUSE, but use mouse with xterm */ 2151 2152 void 2153 mouse_init() 2154 { 2155 if (mouseActive) 2156 return; 2157 if (is_xterm & NEED_XTERM_ON) { 2158 XTERM_ON; 2159 } 2160 #ifdef __CYGWIN__ 2161 else if (is_xterm & NEED_CYGWIN_ON) { 2162 CYGWIN_ON; 2163 } 2164 #endif 2165 mouseActive = 1; 2166 } 2167 2168 void 2169 mouse_end() 2170 { 2171 if (mouseActive == 0) 2172 return; 2173 if (is_xterm & NEED_XTERM_OFF) { 2174 XTERM_OFF; 2175 } 2176 #ifdef __CYGWIN__ 2177 else if (is_xterm & NEED_CYGWIN_OFF) { 2178 CYGWIN_OFF; 2179 } 2180 #endif 2181 mouseActive = 0; 2182 } 2183 2184 #endif /* not USE_GPM nor USE_SYSMOUSE */ 2185 2186 2187 void 2188 mouse_active() 2189 { 2190 if (!mouseActive) 2191 mouse_init(); 2192 } 2193 2194 void 2195 mouse_inactive() 2196 { 2197 if (mouseActive && is_xterm) 2198 mouse_end(); 2199 } 2200 2201 #endif /* USE_MOUSE */ 2202 2203 void 2204 flush_tty() 2205 { 2206 if (ttyf) 2207 fflush(ttyf); 2208 } 2209 2210 #ifdef USE_IMAGE 2211 void 2212 touch_cursor() 2213 { 2214 #ifdef USE_M17N 2215 int i; 2216 #endif 2217 touch_line(); 2218 #ifdef USE_M17N 2219 for (i = CurColumn; i >= 0; i--) { 2220 touch_column(i); 2221 if (CHMODE(ScreenImage[CurLine]->lineprop[i]) != C_WCHAR2) 2222 break; 2223 } 2224 for (i = CurColumn + 1; i < COLS; i++) { 2225 if (CHMODE(ScreenImage[CurLine]->lineprop[i]) != C_WCHAR2) 2226 break; 2227 touch_column(i); 2228 } 2229 #else 2230 touch_column(CurColumn); 2231 #endif 2232 } 2233 #endif 2234 2235 #ifdef __MINGW32_VERSION 2236 2237 int tgetent(char *bp, char *name) 2238 { 2239 return 0; 2240 } 2241 2242 int tgetnum(char *id) 2243 { 2244 return -1; 2245 } 2246 2247 int tgetflag(char *id) 2248 { 2249 return 0; 2250 } 2251 2252 char *tgetstr(char *id, char **area) 2253 { 2254 id = ""; 2255 } 2256 2257 char *tgoto(char *cap, int col, int row) 2258 { 2259 } 2260 2261 int tputs(char *str, int affcnt, int (*putc)(char)) 2262 { 2263 } 2264 2265 char *ttyname(int tty) 2266 { 2267 return "CON"; 2268 } 2269 2270 #endif /* __MINGW32_VERSION */