openenvutils/commandshell/shell/src/modules/terminfo.c
changeset 0 2e3d3ce01487
child 4 0fdb7f6b0309
equal deleted inserted replaced
-1:000000000000 0:2e3d3ce01487
       
     1 // terminfo.c - parameter interface to terminfo via curses
       
     2 //
       
     3 // © Portions Copyright (c) Symbian Software Ltd 2007. All rights reserved.
       
     4 //
       
     5 /*
       
     6  * This file is part of zsh, the Z shell.
       
     7  *
       
     8  * Copyright (c) 2000 Sven Wishnowsky, Clint Adams
       
     9  * All rights reserved.
       
    10  *
       
    11  * Permission is hereby granted, without written agreement and without
       
    12  * license or royalty fees, to use, copy, modify, and distribute this
       
    13  * software and to distribute modified versions of this software for any
       
    14  * purpose, provided that the above copyright notice and the following
       
    15  * two paragraphs appear in all copies of this software.
       
    16  *
       
    17  * In no event shall Sven Wishnowsky, Clint Adams or the Zsh Development Group
       
    18  * be liable to any party for direct, indirect, special, incidental, or
       
    19  * consequential damages arising out of the use of this software and its
       
    20  * documentation, even if Sven Wishnowsky, Clint Adams and the Zsh
       
    21  * Development Group have been advised of the possibility of such damage.
       
    22  *
       
    23  * Sven Wishnowsky, Clint Adams and the Zsh Development Group specifically
       
    24  * disclaim any warranties, including, but not limited to, the implied
       
    25  * warranties of merchantability and fitness for a particular purpose.
       
    26  * The software provided hereunder is on an "as is" basis, and Sven
       
    27  * Wishnowsky, Clint Adams and the Zsh Development Group have no obligation
       
    28  * to provide maintenance, support, updates, enhancements, or modifications.
       
    29  *
       
    30  */
       
    31 #define USES_TERM_H 1
       
    32 #include "terminfo.mdh"
       
    33 
       
    34 #ifdef __SYMBIAN32__
       
    35 #ifdef __WINSCW__
       
    36 #pragma warn_unusedarg off
       
    37 #endif//__WINSCW__
       
    38 #endif//__SYMBIAN32__
       
    39 
       
    40 #ifdef __SYMBIAN32__
       
    41 #include "dummy.h"
       
    42 #endif //__SYMBIAN32__
       
    43 
       
    44 #if defined(HAVE_TIGETFLAG) && defined(HAVE_CURSES_H)
       
    45 # define USE_TERMINFO_MODULE 1
       
    46 #else
       
    47 # undef USE_TERMINFO_MODULE
       
    48 #endif
       
    49 
       
    50 #include "terminfo.pro"
       
    51 static char terminfo_nam[] = "terminfo";
       
    52 
       
    53 /**/
       
    54 #ifdef USE_TERMINFO_MODULE
       
    55 
       
    56 /* The following two undefs are needed for Solaris 2.6 */
       
    57 # ifdef VINTR
       
    58 #  undef VINTR
       
    59 # endif
       
    60 # ifdef offsetof
       
    61 #  undef offsetof
       
    62 # endif
       
    63 #ifndef __SYMBIAN32__
       
    64 # include <curses.h> 
       
    65 #endif//__SYMBIAN32__
       
    66 # ifdef HAVE_TERM_H
       
    67 #ifndef __SYMBIAN32__
       
    68 #  include <term.h> //is mandatory as it defines 'boolnames', 'numnames', 'strnames'.
       
    69 #endif //__SYMBIAN32__
       
    70 # endif
       
    71 
       
    72 static Param terminfo_pm;
       
    73 
       
    74 /* echoti: output a terminfo capability */
       
    75 
       
    76 /**/
       
    77 static int
       
    78 bin_echoti(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
       
    79 {
       
    80     char *s, *t, **u;
       
    81     int arg, num, strarg = 0;
       
    82     long pars[] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
       
    83     char *strcap[] = { "pfkey", "pfloc", "pfx", "pln", "pfxl", NULL };
       
    84 
       
    85     s = *argv++;
       
    86     /* This depends on the termcap stuff in init.c */
       
    87     if (termflags & TERM_BAD)
       
    88 	return 1;
       
    89     if ((termflags & TERM_UNKNOWN) && (isset(INTERACTIVE) || !init_term()))
       
    90 	return 1;
       
    91     /* if the specified capability has a numeric value, display it */
       
    92     if (((num = tigetnum(s)) != -1) && (num != -2)) {
       
    93 	printf("%d\n", num);
       
    94 	return 0;
       
    95     }
       
    96 
       
    97     switch (tigetflag(s)) {
       
    98     case -1:
       
    99 	break;
       
   100     case 0:
       
   101 	puts("no");
       
   102 	return 0;
       
   103     default:
       
   104 	puts("yes");
       
   105 	return 0;
       
   106     }
       
   107 
       
   108 /* get a string-type capability */
       
   109     t = (char *)tigetstr(s);
       
   110     if (!t || t == (char *)-1 || !*t) {
       
   111 	/* capability doesn't exist, or (if boolean) is off */
       
   112 	zwarnnam(name, "no such terminfo capability: %s", s, 0);
       
   113 	return 1;
       
   114     }
       
   115     /* check that the number of arguments provided is not too high */
       
   116     if (arrlen(argv) > 9) {
       
   117         zwarnnam(name, "too many arguments", NULL, 0);
       
   118         return 1;
       
   119     }
       
   120 
       
   121     /* check if we have a capability taking non-integers for parameters */
       
   122     for (u = strcap; *u && !strarg; u++)
       
   123       strarg = !strcmp(s, *u);
       
   124 
       
   125     /* get the arguments */
       
   126     for (arg=0; argv[arg]; arg++) {
       
   127 	if (strarg && arg > 0)
       
   128             pars[arg] = (long) argv[arg];
       
   129 	else
       
   130             pars[arg] = atoi(argv[arg]);
       
   131     }
       
   132 
       
   133     /* output string, through the proper termcap functions */
       
   134     if (!arg)
       
   135         putp(t);
       
   136     else {
       
   137         putp(tparm(t, pars[0], pars[1], pars[2], pars[3], pars[4],
       
   138 	              pars[5], pars[6], pars[7], pars[8]));
       
   139     }
       
   140     return 0;
       
   141 }
       
   142 
       
   143 /**/
       
   144 #else /* !USE_TERMINFO_MODULE */
       
   145 
       
   146 #define bin_echoti bin_notavail
       
   147 
       
   148 /**/
       
   149 #endif /* !USE_TERMINFO_MODULE */
       
   150 
       
   151 static struct builtin bintab[] = {
       
   152     BUILTIN("echoti", 0, bin_echoti, 1, -1, 0, NULL, NULL),
       
   153 };
       
   154 
       
   155 /**/
       
   156 #ifdef USE_TERMINFO_MODULE
       
   157 
       
   158 /* Empty dummy function for special hash parameters. */
       
   159 
       
   160 /**/
       
   161 static void
       
   162 shempty(void)
       
   163 {
       
   164 }
       
   165 
       
   166 /* Create a simple special hash parameter. */
       
   167 
       
   168 /**/
       
   169 static Param
       
   170 createtihash()
       
   171 {
       
   172     Param pm;
       
   173     HashTable ht;
       
   174 
       
   175     unsetparam(terminfo_nam);
       
   176 
       
   177     if (!(pm = createparam(terminfo_nam, PM_SPECIAL|PM_HIDE|PM_HIDEVAL|
       
   178 			   PM_REMOVABLE|PM_HASHED)))
       
   179 	return NULL;
       
   180 
       
   181     pm->level = pm->old ? locallevel : 0;
       
   182     pm->gsu.h = &stdhash_gsu;
       
   183     pm->u.hash = ht = newhashtable(7, terminfo_nam, NULL);
       
   184 
       
   185     ht->hash        = hasher;
       
   186     ht->emptytable  = (TableFunc) shempty;
       
   187     ht->filltable   = NULL;
       
   188     ht->addnode     = (AddNodeFunc) shempty;
       
   189     ht->getnode     = ht->getnode2 = getterminfo;
       
   190     ht->removenode  = (RemoveNodeFunc) shempty;
       
   191     ht->disablenode = NULL;
       
   192     ht->enablenode  = NULL;
       
   193     ht->freenode    = (FreeNodeFunc) shempty;
       
   194     ht->printnode   = printparamnode;
       
   195     ht->scantab     = scanterminfo;
       
   196 
       
   197     return (terminfo_pm = pm);
       
   198 }
       
   199 
       
   200 /**/
       
   201 static HashNode
       
   202 getterminfo(UNUSED(HashTable ht), char *name)
       
   203 {
       
   204     int len, num;
       
   205     char *tistr;
       
   206     Param pm = NULL;
       
   207 
       
   208     /* This depends on the termcap stuff in init.c */
       
   209     if (termflags & TERM_BAD)
       
   210 	return NULL;
       
   211     if ((termflags & TERM_UNKNOWN) && (isset(INTERACTIVE) || !init_term()))
       
   212 	return NULL;
       
   213 
       
   214     unmetafy(name, &len);
       
   215 
       
   216     pm = (Param) hcalloc(sizeof(struct param));
       
   217     pm->nam = dupstring(name);
       
   218     pm->flags = PM_READONLY;
       
   219 
       
   220     if (((num = tigetnum(name)) != -1) && (num != -2)) {
       
   221 	pm->u.val = num;
       
   222 	pm->flags |= PM_INTEGER;
       
   223 	pm->gsu.i = &nullsetinteger_gsu;
       
   224     }
       
   225     else if ((num = tigetflag(name)) != -1) {
       
   226 	pm->u.str = num ? dupstring("yes") : dupstring("no");
       
   227 	pm->flags |= PM_SCALAR;
       
   228 	pm->gsu.s = &nullsetscalar_gsu;
       
   229     }
       
   230     else if ((tistr = (char *)tigetstr(name)) != NULL && tistr != (char *)-1)
       
   231     {
       
   232 	pm->u.str = dupstring(tistr);
       
   233 	pm->flags |= PM_SCALAR;
       
   234 	pm->gsu.s = &nullsetscalar_gsu;
       
   235     }
       
   236     else
       
   237     {
       
   238 	/* zwarn("no such capability: %s", name, 0); */
       
   239 	pm->u.str = dupstring("");
       
   240 	pm->flags |= PM_UNSET;
       
   241 	pm->gsu.s = &nullsetscalar_gsu;
       
   242     }
       
   243     return (HashNode) pm;
       
   244 }
       
   245 
       
   246 /**/
       
   247 static void
       
   248 scanterminfo(UNUSED(HashTable ht), ScanFunc func, int flags)
       
   249 {
       
   250     Param pm = NULL;
       
   251     int num;
       
   252     char **capname, *tistr;
       
   253 
       
   254 #ifndef HAVE_BOOLNAMES
       
   255     static char *boolnames[] = {
       
   256 	"bw", "am", "bce", "ccc", "xhp", "xhpa", "cpix", "crxm", "xt", "xenl",
       
   257 	"eo", "gn", "hc", "chts", "km", "daisy", "hs", "hls", "in", "lpix",
       
   258 	"da", "db", "mir", "msgr", "nxon", "xsb", "npc", "ndscr", "nrrmc",
       
   259 	"os", "mc5i", "xvpa", "sam", "eslok", "hz", "ul", "xon", NULL};
       
   260 #endif
       
   261     
       
   262 #ifndef HAVE_NUMNAMES
       
   263     static char *numnames[] = {
       
   264 	"cols", "it", "lh", "lw", "lines", "lm", "xmc", "ma", "colors",
       
   265 	"pairs", "wnum", "ncv", "nlab", "pb", "vt", "wsl", "bitwin",
       
   266 	"bitype", "bufsz", "btns", "spinh", "spinv", "maddr", "mjump",
       
   267 	"mcs", "mls", "npins", "orc", "orhi", "orl", "orvi", "cps", "widcs",
       
   268 	NULL};
       
   269 #endif
       
   270 
       
   271 #ifndef HAVE_STRNAMES
       
   272     static char *strnames[] = {
       
   273 	"acsc", "cbt", "bel", "cr", "cpi", "lpi", "chr", "cvr", "csr", "rmp",
       
   274 	"tbc", "mgc", "clear", "el1", "el", "ed", "hpa", "cmdch", "cwin",
       
   275 	"cup", "cud1", "home", "civis", "cub1", "mrcup", "cnorm", "cuf1",
       
   276 	"ll", "cuu1", "cvvis", "defc", "dch1", "dl1", "dial", "dsl", "dclk",
       
   277 	"hd", "enacs", "smacs", "smam", "blink", "bold", "smcup", "smdc",
       
   278 	"dim", "swidm", "sdrfq", "smir", "sitm", "slm", "smicm", "snlq",
       
   279 	"snrmq", "prot", "rev", "invis", "sshm", "smso", "ssubm", "ssupm",
       
   280 	"smul", "sum", "smxon", "ech", "rmacs", "rmam", "sgr0", "rmcup",
       
   281 	"rmdc", "rwidm", "rmir", "ritm", "rlm", "rmicm", "rshm", "rmso",
       
   282 	"rsubm", "rsupm", "rmul", "rum", "rmxon", "pause", "hook", "flash",
       
   283 	"ff", "fsl", "wingo", "hup", "is1", "is2", "is3", "if", "iprog",
       
   284 	"initc", "initp", "ich1", "il1", "ip", "ka1", "ka3", "kb2", "kbs",
       
   285 	"kbeg", "kcbt", "kc1", "kc3", "kcan", "ktbc", "kclr", "kclo", "kcmd",
       
   286 	"kcpy", "kcrt", "kctab", "kdch1", "kdl1", "kcud1", "krmir", "kend",
       
   287 	"kent", "kel", "ked", "kext", "kf0", "kf1", "kf10", "kf11", "kf12",
       
   288 	"kf13", "kf14", "kf15", "kf16", "kf17", "kf18", "kf19", "kf2",
       
   289 	"kf20", "kf21", "kf22", "kf23", "kf24", "kf25", "kf26", "kf27",
       
   290 	"kf28", "kf29", "kf3", "kf30", "kf31", "kf32", "kf33", "kf34",
       
   291 	"kf35", "kf36", "kf37", "kf38", "kf39", "kf4", "kf40", "kf41",
       
   292 	"kf42", "kf43", "kf44", "kf45", "kf46", "kf47", "kf48", "kf49",
       
   293 	"kf5", "kf50", "kf51", "kf52", "kf53", "kf54", "kf55", "kf56",
       
   294 	"kf57", "kf58", "kf59", "kf6", "kf60", "kf61", "kf62", "kf63",
       
   295 	"kf7", "kf8", "kf9", "kfnd", "khlp", "khome", "kich1", "kil1",
       
   296 	"kcub1", "kll", "kmrk", "kmsg", "kmov", "knxt", "knp", "kopn",
       
   297 	"kopt", "kpp", "kprv", "kprt", "krdo", "kref", "krfr", "krpl",
       
   298 	"krst", "kres", "kcuf1", "ksav", "kBEG", "kCAN", "kCMD", "kCPY",
       
   299 	"kCRT", "kDC", "kDL", "kslt", "kEND", "kEOL", "kEXT", "kind",
       
   300 	"kFND", "kHLP", "kHOM", "kIC", "kLFT", "kMSG", "kMOV", "kNXT",
       
   301 	"kOPT", "kPRV", "kPRT", "kri", "kRDO", "kRPL", "kRIT", "kRES",
       
   302 	"kSAV", "kSPD", "khts", "kUND", "kspd", "kund", "kcuu1", "rmkx",
       
   303 	"smkx", "lf0", "lf1", "lf10", "lf2", "lf3", "lf4", "lf5", "lf6",
       
   304 	"lf7", "lf8", "lf9", "fln", "rmln", "smln", "rmm", "smm", "mhpa",
       
   305 	"mcud1", "mcub1", "mcuf1", "mvpa", "mcuu1", "nel", "porder", "oc",
       
   306 	"op", "pad", "dch", "dl", "cud", "mcud", "ich", "indn", "il", "cub",
       
   307 	"mcub", "cuf", "mcuf", "rin", "cuu", "mcuu", "pfkey", "pfloc",
       
   308 	"pfx", "pln", "mc0", "mc5p", "mc4", "mc5", "pulse", "qdial",
       
   309 	"rmclk", "rep", "rfi", "rs1", "rs2", "rs3", "rf", "rc", "vpa",
       
   310 	"sc", "ind", "ri", "scs", "sgr", "setb", "smgb", "smgbp", "sclk",
       
   311 	"scp", "setf", "smgl", "smglp", "smgr", "smgrp", "hts", "smgt",
       
   312 	"smgtp", "wind", "sbim", "scsd", "rbim", "rcsd", "subcs",
       
   313 	"supcs", "ht", "docr", "tsl", "tone", "uc", "hu", "u0", "u1",
       
   314 	"u2", "u3", "u4", "u5", "u6", "u7", "u8", "u9", "wait", "xoffc",
       
   315 	"xonc", "zerom", "scesa", "bicr", "binel", "birep", "csnm",
       
   316 	"csin", "colornm", "defbi", "devt", "dispc", "endbi", "smpch",
       
   317 	"smsc", "rmpch", "rmsc", "getm", "kmous", "minfo", "pctrm",
       
   318 	"pfxl", "reqmp", "scesc", "s0ds", "s1ds", "s2ds", "s3ds",
       
   319 	"setab", "setaf", "setcolor", "smglr", "slines", "smgtb",
       
   320 	"ehhlm", "elhlm", "elohlm", "erhlm", "ethlm", "evhlm", "sgr1",
       
   321 	"slength", NULL};
       
   322 #endif
       
   323 
       
   324     pm = (Param) hcalloc(sizeof(struct param));
       
   325 
       
   326     pm->flags = PM_READONLY | PM_SCALAR;
       
   327     pm->gsu.s = &nullsetscalar_gsu;
       
   328 
       
   329     for (capname = (char **)boolnames; *capname; capname++) {
       
   330 	if ((num = tigetflag(*capname)) != -1) {
       
   331 	    pm->u.str = num ? dupstring("yes") : dupstring("no");
       
   332 	    pm->nam = dupstring(*capname);
       
   333 	    func((HashNode) pm, flags);
       
   334 	}
       
   335     }
       
   336 
       
   337     pm->flags = PM_READONLY | PM_INTEGER;
       
   338     pm->gsu.i = &nullsetinteger_gsu;
       
   339 
       
   340     for (capname = (char **)numnames; *capname; capname++) {
       
   341 	if (((num = tigetnum(*capname)) != -1) && (num != -2)) {
       
   342 	    pm->u.val = num;
       
   343 	    pm->nam = dupstring(*capname);
       
   344 	    func((HashNode) pm, flags);
       
   345 	}
       
   346     }
       
   347 
       
   348     pm->flags = PM_READONLY | PM_SCALAR;
       
   349     pm->gsu.s = &nullsetscalar_gsu;
       
   350 
       
   351     for (capname = (char **)strnames; *capname; capname++) {
       
   352 	if ((tistr = (char *)tigetstr(*capname)) != NULL &&
       
   353 	    tistr != (char *)-1) {
       
   354 	    pm->u.str = dupstring(tistr);
       
   355 	    pm->nam = dupstring(*capname);
       
   356 	    func((HashNode) pm, flags);
       
   357 	}
       
   358     }
       
   359 }
       
   360 
       
   361 /**/
       
   362 #endif /* USE_TERMINFO_MODULE */
       
   363 
       
   364 /**/
       
   365 int
       
   366 setup_(UNUSED(Module m))
       
   367 {
       
   368     return 0;
       
   369 }
       
   370 
       
   371 /**/
       
   372 int
       
   373 boot_(Module m)
       
   374 {
       
   375 #ifdef USE_TERMINFO_MODULE
       
   376 # ifdef HAVE_SETUPTERM
       
   377     int errret;
       
   378 
       
   379     if (setupterm((char *)0, 1, &errret) == ERR)
       
   380 	return 1;
       
   381 # endif
       
   382 
       
   383     if (!createtihash())
       
   384     	return 1;
       
   385 #else
       
   386     unsetparam(terminfo_nam);
       
   387 #endif
       
   388     return  !addbuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab));
       
   389 }
       
   390 
       
   391 /**/
       
   392 int
       
   393 cleanup_(Module m)
       
   394 {
       
   395 #ifdef USE_TERMINFO_MODULE
       
   396     Param pm;
       
   397 
       
   398     if ((pm = (Param) paramtab->getnode(paramtab, terminfo_nam)) &&
       
   399 	pm == terminfo_pm) {
       
   400 	pm->flags &= ~PM_READONLY;
       
   401 	unsetparam_pm(pm, 0, 1);
       
   402     }
       
   403 #endif
       
   404     deletebuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab));
       
   405     return 0;
       
   406 }
       
   407 
       
   408 /**/
       
   409 int
       
   410 finish_(UNUSED(Module m))
       
   411 {
       
   412     return 0;
       
   413 }