curses.c

Go to the documentation of this file.
00001 /* curses.c */
00002 
00003 /* Author:
00004  *      Steve Kirkendall
00005  *      14407 SW Teal Blvd. #C
00006  *      Beaverton, OR 97005
00007  *      kirkenda@cs.pdx.edu
00008  */
00009 
00010 
00011 /* This file contains the functions & variables needed for a tiny subset of
00012  * curses.  The principle advantage of this version of curses is its
00013  * extreme speed.  Disadvantages are potentially larger code, few supported
00014  * functions, limited compatibility with full curses, and only stdscr.
00015  */
00016 
00017 #include "config.h"
00018 #include "vi.h"
00019 
00020 #if ANY_UNIX
00021 /* The termios/termio/sgtty #ifdefs were a mess, so I removed all but termios.
00022  * (KJB)
00023  */
00024 # include       <termios.h>
00025 # if MINIX
00026 #  include      <sys/ioctl.h>
00027 # endif
00028 #endif
00029 
00030 #if TOS
00031 # include       <osbind.h>
00032 #endif
00033 
00034 #if OSK
00035 # include       <sgstat.h>
00036 #endif
00037 
00038 #if VMS
00039 extern int VMS_read_raw;  /* Set in initscr() */
00040 #endif
00041 
00042 
00043 extern char     *getenv();
00044 static void      starttcap();
00045 
00046 /* variables, publicly available & used in the macros */
00047 char    *termtype;      /* name of terminal entry */
00048 short   ospeed;         /* speed of the tty, eg B2400 */
00049 #if OSK
00050 char    PC_;    /* Pad char */
00051 char    *BC;    /* backspace character string */
00052 #else
00053 char    PC;             /* Pad char */
00054 #endif
00055 WINDOW  *stdscr;        /* pointer into kbuf[] */
00056 WINDOW  kbuf[KBSIZ];    /* a very large output buffer */
00057 int     LINES;          /* :li#: number of rows */
00058 int     COLS;           /* :co#: number of columns */
00059 int     AM;             /* :am:  boolean: auto margins? */
00060 int     PT;             /* :pt:  boolean: physical tabs? */
00061 char    *VB;            /* :vb=: visible bell */
00062 char    *UP;            /* :up=: move cursor up */
00063 char    *SO = "";       /* :so=: standout start */
00064 char    *SE = "";       /* :se=: standout end */
00065 char    *US = "";       /* :us=: underline start */
00066 char    *UE = "";       /* :ue=: underline end */
00067 char    *MD = "";       /* :md=: bold start */
00068 char    *ME = "";       /* :me=: bold end */
00069 char    *AS = "";       /* :as=: alternate (italic) start */
00070 char    *AE = "";       /* :ae=: alternate (italic) end */
00071 #ifndef NO_VISIBLE
00072 char    *MV;            /* :mv=: "visible" selection start */
00073 #endif
00074 char    *CM;            /* :cm=: cursor movement */
00075 char    *CE;            /* :ce=: clear to end of line */
00076 char    *CD;            /* :cd=: clear to end of screen */
00077 char    *AL;            /* :al=: add a line */
00078 char    *DL;            /* :dl=: delete a line */
00079 #if OSK
00080 char    *SR_;           /* :sr=: scroll reverse */
00081 #else
00082 char    *SR;            /* :sr=: scroll reverse */
00083 #endif
00084 char    *KS = "";       /* :ks=: init string for cursor */
00085 char    *KE = "";       /* :ke=: restore string for cursor */
00086 char    *KU;            /* :ku=: key sequence sent by up arrow */
00087 char    *KD;            /* :kd=: key sequence sent by down arrow */
00088 char    *KL;            /* :kl=: key sequence sent by left arrow */
00089 char    *KR;            /* :kr=: key sequence sent by right arrow */
00090 char    *HM;            /* :HM=: key sequence sent by the <Home> key */
00091 char    *EN;            /* :EN=: key sequence sent by the <End> key */
00092 char    *PU;            /* :PU=: key sequence sent by the <PgUp> key */
00093 char    *PD;            /* :PD=: key sequence sent by the <PgDn> key */
00094 char    *KI;            /* :kI=: key sequence sent by the <Insert> key */
00095 #ifndef NO_FKEY
00096 char    *FKEY[NFKEYS];  /* :k0=: ... :k9=: sequences sent by function keys */
00097 #endif
00098 char    *IM = "";       /* :im=: insert mode start */
00099 char    *IC = "";       /* :ic=: insert the following character */
00100 char    *EI = "";       /* :ei=: insert mode end */
00101 char    *DC;            /* :dc=: delete a character */
00102 char    *TI = "";       /* :ti=: terminal init */       /* GB */
00103 char    *TE = "";       /* :te=: terminal exit */       /* GB */
00104 #ifndef NO_CURSORSHAPE
00105 #if 1
00106 char    *CQ = (char *)0;/* :cQ=: normal cursor */
00107 char    *CX = (char *)1;/* :cX=: cursor used for EX command/entry */
00108 char    *CV = (char *)2;/* :cV=: cursor used for VI command mode */
00109 char    *CI = (char *)3;/* :cI=: cursor used for VI input mode */
00110 char    *CR = (char *)4;/* :cR=: cursor used for VI replace mode */
00111 #else
00112 char    *CQ = "";       /* :cQ=: normal cursor */
00113 char    *CX = "";       /* :cX=: cursor used for EX command/entry */
00114 char    *CV = "";       /* :cV=: cursor used for VI command mode */
00115 char    *CI = "";       /* :cI=: cursor used for VI input mode */
00116 char    *CR = "";       /* :cR=: cursor used for VI replace mode */
00117 #endif
00118 #endif
00119 char    *aend = "";     /* end an attribute -- either UE or ME */
00120 char    ERASEKEY;       /* backspace key taken from ioctl structure */
00121 #ifndef NO_COLOR
00122 char    normalcolor[16];
00123 char    SOcolor[16];
00124 char    SEcolor[16];
00125 char    UScolor[16];
00126 char    UEcolor[16];
00127 char    MDcolor[16];
00128 char    MEcolor[16];
00129 char    AScolor[16];
00130 char    AEcolor[16];
00131 # ifndef NO_POPUP
00132 char    POPUPcolor[16];
00133 # endif
00134 # ifndef NO_VISIBLE
00135 char    VISIBLEcolor[16];
00136 # endif
00137 #endif
00138 
00139 #if ANY_UNIX
00140 static struct termios   oldtermio;      /* original tty mode */
00141 static struct termios   newtermio;      /* cbreak/noecho tty mode */
00142 #endif
00143 
00144 #if OSK
00145 static struct sgbuf     oldsgttyb;      /* orginal tty mode */
00146 static struct sgbuf     newsgttyb;      /* noecho tty mode */
00147 #endif
00148 
00149 static char     *capbuf;        /* capability string buffer */
00150 
00151 
00152 /* Initialize the Curses package. */
00153 void initscr()
00154 {
00155         /* make sure TERM variable is set */
00156         termtype = getenv("TERM");
00157 
00158 #if VMS
00159         /* VMS getenv() handles TERM as a environment setting.  Foreign 
00160          * terminal support can be implemented by setting the ELVIS_TERM
00161          * logical or symbol to match a tinytcap entry.
00162          */
00163         if (!strcmp(termtype,"unknown"))
00164                 termtype = getenv("ELVIS_TERM");
00165 #endif
00166 #if MSDOS
00167         /* For MS-DOS, if TERM is unset we can default to "pcbios", or
00168          * maybe "rainbow".
00169          */
00170         if (!termtype)
00171         {
00172 #ifdef RAINBOW
00173                 if (*(unsigned char far*)(0xffff000eL) == 6   /* Rainbow 100a */
00174                  || *(unsigned char far*)(0xffff000eL) == 148)/* Rainbow 100b */
00175                 {
00176                         termtype = "rainbow";
00177                 }
00178                 else
00179 #endif
00180                         termtype = "pcbios";
00181         }
00182         if (!strcmp(termtype, "pcbios"))
00183 #else
00184         if (!termtype)
00185 #endif
00186         {
00187 #if ANY_UNIX
00188                 write(2, "Environment variable TERM must be set\n", (unsigned)38);
00189                 exit(1);
00190 #endif
00191 #if OSK
00192                 writeln(2, "Environment variable TERM must be set\n", (unsigned)38);
00193                 exit(1);
00194 #endif
00195 #if AMIGA
00196                 termtype = TERMTYPE;
00197                 starttcap(termtype);
00198 #endif
00199 #if MSDOS
00200                 starttcap("pcbios");
00201 #endif
00202 #if TOS
00203                 termtype = "vt52";
00204                 starttcap(termtype);
00205 #endif
00206 #if VMS
00207                 write(2, "UNKNOWN terminal: define ELVIS_TERM\n", (unsigned)36);
00208                 exit(1);
00209 #endif
00210         }
00211         else
00212         {
00213 #if MSDOS
00214                 *o_pcbios = 0;
00215 #endif
00216                 /* start termcap stuff */
00217                 starttcap(termtype);
00218         }
00219 
00220         /* create stdscr and curscr */
00221         stdscr = kbuf;
00222 
00223         /* change the terminal mode to cbreak/noecho */
00224 #if ANY_UNIX
00225         tcgetattr(2, &oldtermio);
00226 #endif
00227 
00228 #if OSK
00229         _gs_opt(0, &oldsgttyb);
00230 #endif
00231 
00232 #if VMS
00233         VMS_read_raw = 1;   /* cbreak/noecho */
00234         vms_open_tty();
00235 #endif
00236         resume_curses(TRUE);
00237 }
00238 
00239 /* Shut down the Curses package. */
00240 void endwin()
00241 {
00242         /* change the terminal mode back the way it was */
00243         suspend_curses();
00244 #if AMIGA
00245         amiclosewin();
00246 #endif
00247 }
00248 
00249 
00250 static int curses_active = FALSE;
00251 
00252 /* Send any required termination strings.  Turn off "raw" mode. */
00253 void suspend_curses()
00254 {
00255 #ifndef NO_CURSORSHAPE
00256         if (has_CQ)
00257         {
00258                 do_CQ();
00259         }
00260 #endif
00261         if (has_TE)                                     /* GB */
00262         {
00263                 do_TE();
00264         }
00265         if (has_KE)
00266         {
00267                 do_KE();
00268         }
00269 #ifndef NO_COLOR
00270         quitcolor();
00271 #endif
00272         refresh();
00273 
00274         /* change the terminal mode back the way it was */
00275 #if ANY_UNIX
00276         tcsetattr(2, TCSADRAIN, &oldtermio);
00277 #endif
00278 #if OSK
00279         _ss_opt(0, &oldsgttyb);
00280 #endif
00281 #if AMIGA
00282         ttyshutdown();
00283 #endif
00284 #if MSDOS
00285         raw_set_stdio(FALSE);
00286 #endif
00287 
00288 #if VMS
00289         VMS_read_raw = 0;
00290 #endif
00291         curses_active = FALSE;
00292 }
00293 
00294 
00295 /* put the terminal in RAW mode.  If "quietly" is FALSE, then ask the user
00296  * to hit a key, and wait for keystroke before returning.
00297  */
00298 void resume_curses(quietly)
00299         int     quietly;
00300 {
00301         if (!curses_active)
00302         {
00303                 /* change the terminal mode to cbreak/noecho */
00304 #if ANY_UNIX
00305                 ospeed = cfgetospeed(&oldtermio);
00306                 ERASEKEY = oldtermio.c_cc[VERASE];
00307                 newtermio = oldtermio;
00308                 newtermio.c_iflag &= (IXON|IXOFF|IXANY|ISTRIP|IGNBRK);
00309                 newtermio.c_oflag &= ~OPOST;
00310                 newtermio.c_lflag &= ISIG;
00311                 newtermio.c_cc[VINTR] = ctrl('C'); /* always use ^C for interrupts */
00312                 newtermio.c_cc[VMIN] = 1;
00313                 newtermio.c_cc[VTIME] = 0;
00314                 newtermio.c_cc[VSUSP] = 0;
00315                 tcsetattr(2, TCSADRAIN, &newtermio);
00316 #endif
00317 #if OSK
00318                 newsgttyb = oldsgttyb;
00319                 newsgttyb.sg_echo = 0;
00320                 newsgttyb.sg_eofch = 0;
00321                 newsgttyb.sg_kbach = 0;
00322                 newsgttyb.sg_kbich = ctrl('C');
00323                 _ss_opt(0, &newsgttyb);
00324                 ospeed = oldsgttyb.sg_baud;
00325                 ERASEKEY = oldsgttyb.sg_bspch;
00326 #endif
00327 #if AMIGA
00328                 /* turn on window resize and RAW */
00329                 ttysetup();
00330 #endif
00331 #if MSDOS
00332                 raw_set_stdio(TRUE);
00333 #endif
00334 
00335 #if VMS
00336                 VMS_read_raw = 1;
00337                 { int c;
00338                         read(0,&c,0);   /* Flush the tty buffer. */
00339                 }
00340                 ERASEKEY = '\177';  /* Accept <DEL> as <^H> for VMS */
00341 #endif
00342 
00343                 if (has_TI)                                     /* GB */
00344                 {
00345                         do_TI();
00346                 }
00347                 if (has_KS)
00348                 {
00349                         do_KS();
00350                 }
00351 
00352                 curses_active = TRUE;
00353         }
00354 
00355         /* If we're supposed to quit quietly, then we're done */
00356         if (quietly)
00357         {
00358                 return;
00359         }
00360 
00361         signal(SIGINT, SIG_IGN);
00362 
00363         move(LINES - 1, 0);
00364         do_SO();
00365 #if VMS
00366         qaddstr("\n[Press <RETURN> to continue]");
00367 #else
00368         qaddstr("[Press <RETURN> to continue]");
00369 #endif
00370         do_SE();
00371         refresh();
00372         ttyread(kbuf, 20, 0); /* in RAW mode, so <20 is very likely */
00373         if (kbuf[0] == ':')
00374         {
00375                 mode = MODE_COLON;
00376                 addch('\n');
00377                 refresh();
00378         }
00379         else
00380         {
00381                 mode = MODE_VI;
00382                 redraw(MARK_UNSET, FALSE);
00383         }       
00384         exwrote = FALSE;
00385 
00386 #if TURBOC || __GNUC__ || _ANSI
00387         signal(SIGINT, (void(*)()) trapint);
00388 #else
00389         signal(SIGINT, trapint);
00390 #endif
00391 }
00392 
00393 /* This function fetches an optional string from termcap */
00394 static void mayhave(T, s)
00395         char    **T;    /* where to store the returned pointer */
00396         char    *s;     /* name of the capability */
00397 {
00398         char    *val;
00399 
00400         val = tgetstr(s, &capbuf);
00401         if (val)
00402         {
00403                 *T = val;
00404         }
00405 }
00406 
00407 
00408 /* This function fetches a required string from termcap */
00409 static void musthave(T, s)
00410         char    **T;    /* where to store the returned pointer */
00411         char    *s;     /* name of the capability */
00412 {
00413         mayhave(T, s);
00414         if (!*T)
00415         {
00416                 write(2, "This termcap entry lacks the :", (unsigned)30);
00417                 write(2, s, (unsigned)2);
00418                 write(2, "=: capability\n", (unsigned)14);
00419 #if OSK
00420                 write(2, "\l", 1);
00421 #endif
00422                 exit(1);
00423         }
00424 }
00425 
00426 
00427 /* This function fetches a pair of strings from termcap.  If one of them is
00428  * missing, then the other one is ignored.
00429  */
00430 static void pair(T, U, sT, sU)
00431         char    **T;    /* where to store the first pointer */
00432         char    **U;    /* where to store the second pointer */
00433         char    *sT;    /* name of the first capability */
00434         char    *sU;    /* name of the second capability */
00435 {
00436         mayhave(T, sT);
00437         mayhave(U, sU);
00438         if (!**T || !**U)
00439         {
00440                 *T = *U = "";
00441         }
00442 }
00443 
00444 
00445 
00446 /* Read everything from termcap */
00447 static void starttcap(term)
00448         char    *term;
00449 {
00450         static char     cbmem[800];
00451 
00452         /* allocate memory for capbuf */
00453         capbuf = cbmem;
00454 
00455         /* get the termcap entry */
00456         switch (tgetent(kbuf, term))
00457         {
00458           case -1:
00459                 write(2, "Can't read /etc/termcap\n", (unsigned)24);
00460 #if OSK
00461                 write(2, "\l", 1);
00462 #endif
00463                 exit(2);
00464 
00465           case 0:
00466                 write(2, "Unrecognized TERM type\n", (unsigned)23);
00467 #if OSK
00468                 write(2, "\l", 1);
00469 #endif
00470                 exit(3);
00471         }
00472 
00473         /* get strings */
00474         musthave(&UP, "up");
00475         mayhave(&VB, "vb");
00476         musthave(&CM, "cm");
00477         pair(&SO, &SE, "so", "se");
00478         mayhave(&TI, "ti");
00479         mayhave(&TE, "te");
00480         if (tgetnum("ug") <= 0)
00481         {
00482                 pair(&US, &UE, "us", "ue");
00483                 pair(&MD, &ME, "md", "me");
00484 
00485                 /* get italics, or have it default to underline */
00486                 pair(&AS, &AE, "as", "ae");
00487                 if (!*AS)
00488                 {
00489                         AS = US;
00490                         AE = UE;
00491                 }
00492         }
00493 #ifndef NO_VISIBLE
00494         MV = SO; /* by default */
00495         mayhave(&MV, "mv");
00496 #endif
00497         mayhave(&AL, "al");
00498         mayhave(&DL, "dl");
00499         musthave(&CE, "ce");
00500         mayhave(&CD, "cd");
00501 #if OSK
00502         mayhave(&SR_, "sr");
00503 #else   
00504         mayhave(&SR, "sr");
00505 #endif
00506         pair(&IM, &EI, "im", "ei");
00507         mayhave(&IC, "ic");
00508         mayhave(&DC, "dc");
00509 
00510         /* other termcap stuff */
00511         AM = (tgetflag("am") && !tgetflag("xn"));
00512         PT = tgetflag("pt");
00513 #if AMIGA
00514         amiopenwin(termtype);   /* Must run this before ttysetup(); */
00515         ttysetup();     /* Must run this before getsize(0); */
00516 #endif
00517         getsize(0);
00518 
00519         /* Key sequences */
00520         pair(&KS, &KE, "ks", "ke");
00521         mayhave(&KU, "ku");             /* up */
00522         mayhave(&KD, "kd");             /* down */
00523         mayhave(&KL, "kl");             /* left */
00524         mayhave(&KR, "kr");             /* right */
00525         mayhave(&PU, "kP");             /* PgUp */
00526         mayhave(&PD, "kN");             /* PgDn */
00527         mayhave(&HM, "kh");             /* Home */
00528         mayhave(&EN, "kH");             /* End */
00529         mayhave(&KI, "kI");             /* Insert */
00530 #ifndef CRUNCH
00531         if (!PU) mayhave(&PU, "K2");    /* "3x3 pad" names for PgUp, etc. */
00532         if (!PD) mayhave(&PD, "K5");
00533         if (!HM) mayhave(&HM, "K1");
00534         if (!EN) mayhave(&EN, "K4");
00535 
00536         mayhave(&PU, "PU");             /* old XENIX names for PgUp, etc. */
00537         mayhave(&PD, "PD");             /* (overrides others, if used.) */
00538         mayhave(&HM, "HM");
00539         mayhave(&EN, "EN");
00540 #endif
00541 #ifndef NO_FKEY
00542         mayhave(&FKEY[0], "k0");                /* function key codes */
00543         mayhave(&FKEY[1], "k1");
00544         mayhave(&FKEY[2], "k2");
00545         mayhave(&FKEY[3], "k3");
00546         mayhave(&FKEY[4], "k4");
00547         mayhave(&FKEY[5], "k5");
00548         mayhave(&FKEY[6], "k6");
00549         mayhave(&FKEY[7], "k7");
00550         mayhave(&FKEY[8], "k8");
00551         mayhave(&FKEY[9], "k9");
00552 # ifndef NO_SHIFT_FKEY
00553         mayhave(&FKEY[10], "s0");               /* shift function key codes */
00554         mayhave(&FKEY[11], "s1");
00555         mayhave(&FKEY[12], "s2");
00556         mayhave(&FKEY[13], "s3");
00557         mayhave(&FKEY[14], "s4");
00558         mayhave(&FKEY[15], "s5");
00559         mayhave(&FKEY[16], "s6");
00560         mayhave(&FKEY[17], "s7");
00561         mayhave(&FKEY[18], "s8");
00562         mayhave(&FKEY[19], "s9");
00563 #  ifndef NO_CTRL_FKEY
00564         mayhave(&FKEY[20], "c0");               /* control function key codes */
00565         mayhave(&FKEY[21], "c1");
00566         mayhave(&FKEY[22], "c2");
00567         mayhave(&FKEY[23], "c3");
00568         mayhave(&FKEY[24], "c4");
00569         mayhave(&FKEY[25], "c5");
00570         mayhave(&FKEY[26], "c6");
00571         mayhave(&FKEY[27], "c7");
00572         mayhave(&FKEY[28], "c8");
00573         mayhave(&FKEY[29], "c9");
00574 #   ifndef NO_ALT_FKEY
00575         mayhave(&FKEY[30], "a0");               /* alt function key codes */
00576         mayhave(&FKEY[31], "a1");
00577         mayhave(&FKEY[32], "a2");
00578         mayhave(&FKEY[33], "a3");
00579         mayhave(&FKEY[34], "a4");
00580         mayhave(&FKEY[35], "a5");
00581         mayhave(&FKEY[36], "a6");
00582         mayhave(&FKEY[37], "a7");
00583         mayhave(&FKEY[38], "a8");
00584         mayhave(&FKEY[39], "a9");
00585 #   endif
00586 #  endif
00587 # endif
00588 #endif
00589 
00590 #ifndef NO_CURSORSHAPE
00591         /* cursor shapes */
00592         CQ = tgetstr("cQ", &capbuf);
00593         if (has_CQ)
00594         {
00595                 CX = tgetstr("cX", &capbuf);
00596                 if (!CX) CX = CQ;
00597                 CV = tgetstr("cV", &capbuf);
00598                 if (!CV) CV = CQ;
00599                 CI = tgetstr("cI", &capbuf);
00600                 if (!CI) CI = CQ;
00601                 CR = tgetstr("cR", &capbuf);
00602                 if (!CR) CR = CQ;
00603         }
00604 # ifndef CRUNCH
00605         else
00606         {
00607                 CQ = CV = "";
00608                 pair(&CQ, &CV, "ve", "vs");
00609                 CX = CI = CR = CQ;
00610         }
00611 # endif /* !CRUNCH */
00612 #endif /* !NO_CURSORSHAPE */
00613 
00614 #ifndef NO_COLOR
00615         strcpy(SOcolor, SO);
00616         strcpy(SEcolor, SE);
00617         strcpy(AScolor, AS);
00618         strcpy(AEcolor, AE);
00619         strcpy(MDcolor, MD);
00620         strcpy(MEcolor, ME);
00621         strcpy(UScolor, US);
00622         strcpy(UEcolor, UE);
00623 # ifndef NO_POPUP
00624         strcpy(POPUPcolor, SO);
00625 # endif
00626 # ifndef NO_VISIBLE
00627         strcpy(VISIBLEcolor, MV);
00628 # endif
00629 #endif
00630 
00631 }
00632 
00633 
00634 /* This function gets the window size.  It uses the TIOCGWINSZ ioctl call if
00635  * your system has it, or tgetnum("li") and tgetnum("co") if it doesn't.
00636  * This function is called once during initialization, and thereafter it is
00637  * called whenever the SIGWINCH signal is sent to this process.
00638  */
00639 int getsize(signo)
00640         int     signo;
00641 {
00642         int     lines;
00643         int     cols;
00644 #ifdef TIOCGWINSZ
00645         struct winsize size;
00646 #endif
00647 
00648 #ifdef SIGWINCH
00649         /* reset the signal vector */
00650         signal(SIGWINCH, getsize);
00651 #endif
00652 
00653         /* get the window size, one way or another. */
00654         lines = cols = 0;
00655 #ifdef TIOCGWINSZ
00656         if (ioctl(2, TIOCGWINSZ, &size) >= 0)
00657         {
00658                 lines = size.ws_row;
00659                 cols = size.ws_col;
00660         }
00661 #endif
00662 #if AMIGA
00663         /* Amiga gets window size by asking the console.device */
00664         if (!strcmp(TERMTYPE, termtype))
00665         {
00666             auto long len;
00667             auto char buf[30];
00668             
00669             Write(Output(), "\2330 q", 4); /* Ask the console.device */
00670             len = Read(Input(), buf, 29);
00671             buf[len] = '\000';
00672             sscanf(&buf[5], "%d;%d", &lines, &cols);
00673         }
00674 #endif
00675         if ((lines == 0 || cols == 0) && signo == 0)
00676         {
00677                 LINES = tgetnum("li");
00678                 COLS = tgetnum("co");
00679         }
00680 #if MSDOS
00681 # ifdef RAINBOW
00682         if (!strcmp(termtype, "rainbow"))
00683         {
00684                 /* Determine whether Rainbow is in 80-column or 132-column mode */
00685                 cols = *(unsigned char far *)0xee000f57L;
00686         }
00687         else
00688 # endif
00689         {
00690                 lines = v_rows();
00691                 cols = v_cols();
00692         }
00693 #endif
00694         if (lines >= 2)
00695         {
00696                 LINES = lines;
00697         }
00698 
00699         if (cols >= 30)
00700         {
00701                 COLS = cols;
00702         }
00703 
00704         /* Make sure we got values that we can live with */
00705         if (LINES < 2 || COLS < 30)
00706         {
00707                 write(2, "Screen too small\n", (unsigned)17);
00708 #if OSK
00709                 write(2, "\l", 1);
00710 #endif
00711                 endwin();
00712                 exit(2);
00713         }
00714 
00715 #if AMIGA
00716         if (*o_lines != LINES || *o_columns != COLS)
00717         {
00718                 *o_lines = LINES;
00719                 *o_columns = COLS;
00720         }
00721 #endif
00722 
00723         return 0;
00724 }
00725 
00726 
00727 /* This is a function version of addch() -- it is used by tputs() */
00728 int faddch(ch)
00729         int     ch;
00730 {
00731         addch(ch);
00732 
00733         return 0;
00734 }
00735 
00736 /* This function quickly adds a string to the output queue.  It does *NOT*
00737  * convert \n into <CR><LF>.
00738  */
00739 void qaddstr(str)
00740         char    *str;
00741 {
00742         REG char *s_, *d_;
00743 
00744 #if MSDOS
00745         if (o_pcbios[0])
00746         {
00747                 while (*str)
00748                         qaddch(*str++);
00749                 return;
00750         }
00751 #endif
00752         for (s_=(str), d_=stdscr; *d_++ = *s_++; )
00753         {
00754         }
00755         stdscr = d_ - 1;
00756 }
00757 
00758 /* Output the ESC sequence needed to go into any video mode, if supported */
00759 void attrset(a)
00760         int     a;
00761 {
00762         do_aend();
00763         if (a == A_BOLD)
00764         {
00765                 do_MD();
00766                 aend = ME;
00767         }
00768         else if (a == A_UNDERLINE)
00769         {
00770                 do_US();
00771                 aend = UE;
00772         }
00773         else if (a == A_ALTCHARSET)
00774         {
00775                 do_AS();
00776                 aend = AE;
00777         }
00778         else
00779         {
00780                 aend = "";
00781         }
00782 }
00783 
00784 
00785 /* Insert a single character into the display */
00786 void insch(ch)
00787         int     ch;
00788 {
00789         if (has_IM)
00790                 do_IM();
00791         do_IC();
00792         qaddch(ch);
00793         if (has_EI)
00794                 do_EI();
00795 }
00796 
00797 void wrefresh()
00798 {
00799         if (stdscr != kbuf)
00800         {
00801                 VOIDBIOS(;,ttywrite(kbuf, (unsigned)(stdscr - kbuf)));
00802                 stdscr = kbuf;
00803         }
00804 }
00805 
00806 void wqrefresh()
00807 {
00808         if (stdscr - kbuf > 2000)
00809         {
00810                 VOIDBIOS(stdscr = kbuf,
00811                 {
00812                         ttywrite(kbuf, (unsigned)(stdscr - kbuf)); 
00813                         stdscr = kbuf;
00814                 });
00815         }
00816 }
00817 
00818 #ifndef NO_COLOR
00819 /* This function is called during termination.  It resets color modes */
00820 int ansiquit()
00821 {
00822         /* if ANSI color terminal, then reset the colors */
00823         if (!strcmp(UP, "\033[A"))
00824         {
00825                 tputs("\033[37;40m\033[m", 1, faddch);
00826                 clrtoeol();
00827                 return 1;
00828         }
00829         return 0;
00830 }
00831 
00832 /* This sets the color strings that work for ANSI terminals.  If the TERMCAP
00833  * doesn't look like an ANSI terminal, then it returns FALSE.  If the colors
00834  * aren't understood, it also returns FALSE.  If all goes well, it returns TRUE
00835  */
00836 int ansicolor(cmode, attrbyte)
00837         int     cmode;          /* mode to set, e.g. A_NORMAL */
00838         int     attrbyte;       /* IBM PC attribute byte */
00839 {
00840         char    temp[16];       /* hold the new mode string */
00841 
00842         /* if not ANSI-ish, then fail */
00843         if (strcmp(UP, "\033[A") && strcmp(UP, "\033OA"))
00844         {
00845                 msg("Don't know how to set colors for this terminal");
00846                 return 0;
00847         }
00848 
00849         /* construct the color string */
00850         sprintf(temp, "\033[m\033[3%c;4%c%s%sm",
00851                 "04261537"[attrbyte & 0x07],
00852                 "04261537"[(attrbyte >> 4) & 0x07],
00853                 (attrbyte & 0x08) ? ";1" : "",
00854                 (attrbyte & 0x80) ? ";5" : "");
00855 
00856         /* stick it in the right place */
00857         switch (cmode)
00858         {
00859           case A_NORMAL:
00860                 if (!strcmp(MEcolor, normalcolor))
00861                         strcpy(MEcolor, temp);
00862                 if (!strcmp(UEcolor, normalcolor))
00863                         strcpy(UEcolor, temp);
00864                 if (!strcmp(AEcolor, normalcolor))
00865                         strcpy(AEcolor, temp);
00866                 if (!strcmp(SEcolor, normalcolor))
00867                         strcpy(SEcolor, temp);
00868 
00869                 strcpy(normalcolor, temp);
00870                 tputs(normalcolor, 1, faddch);
00871                 break;
00872 
00873           case A_BOLD:
00874                 strcpy(MDcolor, temp);
00875                 strcpy(MEcolor, normalcolor);
00876                 break;
00877 
00878           case A_UNDERLINE:
00879                 strcpy(UScolor, temp);
00880                 strcpy(UEcolor, normalcolor);
00881                 break;
00882 
00883           case A_ALTCHARSET:
00884                 strcpy(AScolor, temp);
00885                 strcpy(AEcolor, normalcolor);
00886                 break;
00887 
00888           case A_STANDOUT:
00889                 strcpy(SOcolor, temp);
00890                 strcpy(SEcolor, normalcolor);
00891                 break;
00892 
00893 #ifndef NO_POPUP
00894           case A_POPUP:
00895                 strcpy(POPUPcolor, temp);
00896                 break;
00897 #endif
00898 
00899 #ifndef NO_VISIBLE
00900           case A_VISIBLE:
00901                 strcpy(VISIBLEcolor, temp);
00902                 break;
00903 #endif
00904         }
00905 
00906         return 1;
00907 }
00908 
00909 
00910 /* This function outputs the ESC sequence needed to switch the screen back
00911  * to "normal" mode.  On color terminals which haven't had their color set
00912  * yet, this is one of the termcap strings; for color terminals that really
00913  * have had colors defined, we just the "normal color" escape sequence.
00914  */
00915 endcolor()
00916 {
00917         if (aend == ME)
00918                 tputs(MEcolor, 1, faddch);
00919         else if (aend == UE)
00920                 tputs(UEcolor, 1, faddch);
00921         else if (aend == AE)
00922                 tputs(AEcolor, 1, faddch);
00923         else if (aend == SE)
00924                 tputs(SEcolor, 1, faddch);
00925         aend = "";
00926         return 0;
00927 }
00928 
00929 
00930 #endif /* !NO_COLOR */

Generated on Fri Apr 14 22:56:52 2006 for minix by  doxygen 1.4.6