|
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 } |