2 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
3 * Sadrul Habib Chowdhury (sadrul@users.sourceforge.net)
4 * Copyright (c) 2008, 2009
5 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
6 * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
7 * Micah Cowan (micah@cowan.name)
8 * Sadrul Habib Chowdhury (sadrul@users.sourceforge.net)
9 * Copyright (c) 1993-2002, 2003, 2005, 2006, 2007
10 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
11 * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
12 * Copyright (c) 1987 Oliver Laumann
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 3, or (at your option)
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program (see the file COPYING); if not, see
26 * https://www.gnu.org/licenses/, or contact Free Software Foundation, Inc.,
27 * 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
29 ****************************************************************
38 #include <sys/types.h>
43 #include "list_generic.h"
46 char version
[60]; /* initialised by main() */
48 static void PadStr(char *, int, int, int);
51 ** Here come the help page routines
54 static void HelpProcess(char **, size_t *);
55 static void HelpAbort(void);
56 static void HelpRedisplayLine(int, int, int, int);
57 static void add_key_to_buf(char *, int);
58 static void AddAction(struct action
*, int, int);
59 static int helppage(void);
64 int maxrow
, grow
, numcols
, numrows
, num_names
;
65 int numskip
, numpages
;
66 int command_search
, command_bindings
;
67 int refgrow
, refcommand_search
;
68 int inter
, mcom
, mkey
;
69 int nact
[RC_LAST
+ 1];
74 static const struct LayFuncs HelpLf
= {
84 void display_help(char *class, struct action
*ktabp
)
86 int i
, n
, key
, mcom
, mkey
, l
;
87 struct helpdata
*helpdata
;
88 int used
[RC_LAST
+ 1];
90 if (flayer
->l_height
< 6) {
91 LMsg(0, "Window height too small for help page");
94 if (InitOverlayPage(sizeof(struct helpdata
), &HelpLf
, 0))
97 helpdata
= (struct helpdata
*)flayer
->l_data
;
98 helpdata
->class = class;
99 helpdata
->ktabp
= ktabp
;
100 helpdata
->num_names
= helpdata
->command_bindings
= 0;
101 helpdata
->command_search
= 0;
102 for (n
= 0; n
<= RC_LAST
; n
++)
106 for (key
= 0; key
< 256 + KMAP_KEYS
; key
++) {
110 if (ktabp
[key
].args
== noargs
) {
111 used
[n
] += (key
<= ' ' || key
== 0x7f) ? 3 : (key
> 0x7f) ? 5 : 2;
113 helpdata
->command_bindings
++;
115 for (n
= i
= 0; n
<= RC_LAST
; n
++)
117 l
= strlen(comms
[n
].name
);
122 helpdata
->nact
[i
++] = n
;
124 helpdata
->num_names
= i
;
128 helpdata
->numcols
= flayer
->l_width
/ (mcom
+ mkey
+ 1);
129 if (helpdata
->numcols
== 0) {
131 LMsg(0, "Width too small");
134 helpdata
->inter
= (flayer
->l_width
- (mcom
+ mkey
) * helpdata
->numcols
) / (helpdata
->numcols
+ 1);
135 if (helpdata
->inter
<= 0)
137 helpdata
->mcom
= mcom
;
138 helpdata
->mkey
= mkey
;
139 helpdata
->numrows
= (helpdata
->num_names
+ helpdata
->numcols
- 1) / helpdata
->numcols
;
140 helpdata
->numskip
= flayer
->l_height
- 5 - (2 + helpdata
->numrows
);
141 while (helpdata
->numskip
< 0)
142 helpdata
->numskip
+= flayer
->l_height
- 5;
143 helpdata
->numskip
%= flayer
->l_height
- 5;
144 if (helpdata
->numskip
> flayer
->l_height
/ 3 || helpdata
->numskip
> helpdata
->command_bindings
)
145 helpdata
->numskip
= 1;
146 helpdata
->maxrow
= 2 + helpdata
->numrows
+ helpdata
->numskip
+ helpdata
->command_bindings
;
149 helpdata
->numpages
= (helpdata
->maxrow
+ flayer
->l_height
- 6) / (flayer
->l_height
- 5);
151 flayer
->l_y
= flayer
->l_height
- 1;
155 static void HelpProcess(char **ppbuf
, size_t *plen
)
159 while (!done
&& *plen
> 0) {
179 static void HelpAbort(void)
181 LAY_CALL_UP(LRefreshAll(flayer
, 0));
185 static int helppage(void)
187 struct helpdata
*helpdata
;
188 int col
, crow
, n
, key
, x
;
189 char buf
[MAXKLEN
], Esc_buf
[5], cbuf
[512];
190 struct action
*ktabp
;
192 helpdata
= (struct helpdata
*)flayer
->l_data
;
194 ktabp
= helpdata
->ktabp
;
195 if (helpdata
->grow
>= helpdata
->maxrow
)
197 helpdata
->refgrow
= helpdata
->grow
;
198 helpdata
->refcommand_search
= helpdata
->command_search
;
200 /* Clear the help screen */
201 LClearAll(flayer
, 0);
203 sprintf(cbuf
, "Screen key bindings, page %d of %d.", helpdata
->grow
/ (flayer
->l_height
- 5) + 1,
210 /* XXX fix escape character */
211 if (flayer
->l_cvlist
&& flayer
->l_cvlist
->c_display
) {
212 add_key_to_buf(buf
, flayer
->l_cvlist
->c_display
->d_user
->u_MetaEsc
);
213 add_key_to_buf(Esc_buf
, flayer
->l_cvlist
->c_display
->d_user
->u_Esc
);
215 strncpy(Esc_buf
, "??", 5);
216 strncpy(buf
, "??", 256);
219 for (; crow
< flayer
->l_height
- 3; crow
++) {
220 if (helpdata
->grow
< 1) {
222 sprintf(cbuf
, "Command key: %s Literal %s: %s", Esc_buf
, Esc_buf
, buf
);
224 sprintf(cbuf
, "Command class: '%.80s'", helpdata
->class);
225 centerline(cbuf
, crow
);
227 } else if (helpdata
->grow
>= 2 && helpdata
->grow
- 2 < helpdata
->numrows
) {
230 col
< helpdata
->numcols
231 && (n
= helpdata
->numrows
* col
+ (helpdata
->grow
- 2)) < helpdata
->num_names
; col
++) {
232 x
+= helpdata
->inter
- !col
;
233 n
= helpdata
->nact
[n
];
235 for (key
= 0; key
< 256 + KMAP_KEYS
; key
++)
236 if (ktabp
[key
].nr
== n
&& ktabp
[key
].args
== noargs
237 && strlen(buf
) < ARRAY_SIZE(buf
) - 7) {
239 add_key_to_buf(buf
, key
);
241 PadStr(comms
[n
].name
, helpdata
->mcom
, x
, crow
);
243 PadStr(buf
, helpdata
->mkey
, x
, crow
);
247 } else if (helpdata
->grow
- 2 - helpdata
->numrows
>= helpdata
->numskip
248 && helpdata
->grow
- 2 - helpdata
->numrows
- helpdata
->numskip
< helpdata
->command_bindings
) {
249 while ((n
= ktabp
[helpdata
->command_search
].nr
) == RC_ILLEGAL
250 || ktabp
[helpdata
->command_search
].args
== noargs
) {
251 if (++helpdata
->command_search
>= 256 + KMAP_KEYS
)
255 add_key_to_buf(buf
, helpdata
->command_search
);
256 PadStr(buf
, 5, 0, crow
);
257 AddAction(&ktabp
[helpdata
->command_search
++], 5, crow
);
262 sprintf(cbuf
, "[Press Space %s Return to end.]", helpdata
->grow
< helpdata
->maxrow
? "for next page;" : "or");
263 centerline(cbuf
, flayer
->l_height
- 2);
268 static void AddAction(struct action
*act
, int x
, int y
)
275 struct mchar mchar_dol
;
277 mchar_dol
= mchar_blank
;
278 mchar_dol
.image
= '$';
280 fr
= flayer
->l_width
- 1 - x
;
283 l
= strlen(comms
[act
->nr
].name
);
287 PadStr(comms
[act
->nr
].name
, l
, x
, y
);
290 LPutChar(flayer
, fr
? &mchar_blank
: &mchar_dol
, x
++, y
);
294 while (pp
&& (cp
= *pp
) != NULL
) {
298 if (!ll
|| (strchr(cp
, ' ') != NULL
)) {
299 if (strchr(cp
, '\'') != NULL
)
304 while (ll
-- && bp
< buf
+ 250)
305 bp
+= AddXChar(bp
, *(unsigned char *)cp
++);
309 if ((fr
-= (bp
- buf
) + 1) < 0) {
312 PadStr(buf
, fr
, x
, y
);
314 LPutChar(flayer
, &mchar_dol
, x
, y
);
317 PadStr(buf
, strlen(buf
), x
, y
);
321 LPutChar(flayer
, fr
? &mchar_blank
: &mchar_dol
, x
++, y
);
325 static void add_key_to_buf(char *buf
, int key
)
329 strncpy(buf
, "unset", 6);
331 strncpy(buf
, "sp", 3);
332 else if (key
>= 256) {
333 key
= key
- 256 + T_CAPS
;
335 buf
[1] = term
[key
].tcname
[0];
336 buf
[2] = term
[key
].tcname
[1];
340 buf
[AddXChar(buf
, key
)] = 0;
343 static void HelpRedisplayLine(int y
, int xs
, int xe
, int isblank
)
346 struct helpdata
*helpdata
;
348 helpdata
= (struct helpdata
*)flayer
->l_data
;
349 helpdata
->grow
= helpdata
->refgrow
;
350 helpdata
->command_search
= helpdata
->refcommand_search
;
354 if (y
!= 0 && y
!= flayer
->l_height
- 1)
357 LClearArea(flayer
, xs
, y
, xe
, y
, 0, 0);
362 ** The bindkey help page
366 static void BindkeyProcess(char **, size_t *);
367 static void BindkeyAbort(void);
368 static void BindkeyRedisplayLine(int, int, int, int);
369 static void bindkeypage(void);
380 static const struct LayFuncs BindkeyLf
= {
383 BindkeyRedisplayLine
,
390 void display_bindkey(char *title
, struct action
*tab
)
392 struct bindkeydata
*bindkeydata
;
395 if (flayer
->l_height
< 6) {
396 LMsg(0, "Window height too small for bindkey page");
399 if (InitOverlayPage(sizeof(struct bindkeydata
), &BindkeyLf
, 0))
402 bindkeydata
= (struct bindkeydata
*)flayer
->l_data
;
403 bindkeydata
->title
= title
;
404 bindkeydata
->tab
= tab
;
407 for (i
= 0; i
< KMAP_KEYS
+ KMAP_AKEYS
+ kmap_extn
; i
++) {
408 if (tab
[i
].nr
!= RC_ILLEGAL
)
411 bindkeydata
->pos
= 0;
412 bindkeydata
->page
= 1;
413 bindkeydata
->pages
= (n
+ flayer
->l_height
- 6) / (flayer
->l_height
- 5);
414 if (bindkeydata
->pages
== 0)
415 bindkeydata
->pages
= 1;
417 flayer
->l_y
= flayer
->l_height
- 1;
421 static void BindkeyAbort(void)
423 LAY_CALL_UP(LRefreshAll(flayer
, 0));
427 static void bindkeypage(void)
429 struct bindkeydata
*bindkeydata
;
430 struct kmap_ext
*kme
;
436 bindkeydata
= (struct bindkeydata
*)flayer
->l_data
;
438 LClearAll(flayer
, 0);
440 sprintf(tbuf
, "%s key bindings, page %d of %d.", bindkeydata
->title
, bindkeydata
->page
, bindkeydata
->pages
);
443 for (i
= bindkeydata
->pos
; i
< KMAP_KEYS
+ KMAP_AKEYS
+ kmap_extn
&& y
< flayer
->l_height
- 3; i
++) {
447 act
= &bindkeydata
->tab
[i
];
448 if (act
->nr
== RC_ILLEGAL
)
451 s
= term
[i
+ T_CAPS
].tcname
;
452 sl
= s
? strlen(s
) : 0;
453 } else if (i
< KMAP_KEYS
+ KMAP_AKEYS
) {
454 act
= &bindkeydata
->tab
[i
];
455 if (act
->nr
== RC_ILLEGAL
)
458 s
= term
[i
+ (T_CAPS
- T_OCAPS
+ T_CURSOR
)].tcname
;
459 sl
= s
? strlen(s
) : 0;
462 kme
= kmap_exts
+ (i
- (KMAP_KEYS
+ KMAP_AKEYS
));
465 sl
= kme
->fl
& ~KMAP_NOTIMEOUT
;
466 if ((kme
->fl
& KMAP_NOTIMEOUT
) != 0)
468 act
= bindkeydata
->tab
== dmtab
? &kme
->dm
: bindkeydata
->tab
== mmtab
? &kme
->mm
: &kme
->um
;
469 if (act
->nr
== RC_ILLEGAL
)
473 p
+= AddXChar(p
, *(unsigned char *)s
++);
477 while (p
< tbuf
+ 15)
479 sprintf(p
, "%s -> ", xch
);
481 if (p
- tbuf
> flayer
->l_width
- 1) {
482 tbuf
[flayer
->l_width
- 2] = '$';
483 tbuf
[flayer
->l_width
- 1] = 0;
485 PadStr(tbuf
, strlen(tbuf
), 0, y
);
486 AddAction(act
, strlen(tbuf
), y
);
490 bindkeydata
->last
= i
;
491 sprintf(tbuf
, "[Press Space %s Return to end.]",
492 bindkeydata
->page
< bindkeydata
->pages
? "for next page;" : "or");
493 centerline(tbuf
, flayer
->l_height
- 2);
497 static void BindkeyProcess(char **ppbuf
, size_t *plen
)
500 struct bindkeydata
*bindkeydata
;
502 bindkeydata
= (struct bindkeydata
*)flayer
->l_data
;
503 while (!done
&& *plen
> 0) {
506 if (bindkeydata
->page
< bindkeydata
->pages
) {
507 bindkeydata
->pos
= bindkeydata
->last
;
527 static void BindkeyRedisplayLine(int y
, int xs
, int xe
, int isblank
)
533 if (y
!= 0 && y
!= flayer
->l_height
- 1)
536 LClearArea(flayer
, xs
, y
, xe
, y
, 0, 0);
541 ** The zmodem active page
545 static void ZmodemRedisplayLine(int, int, int, int);
546 static int ZmodemResize(int, int);
548 static const struct LayFuncs ZmodemLf
= {
558 static int ZmodemResize(int wi
, int he
)
560 flayer
->l_width
= wi
;
561 flayer
->l_height
= he
;
562 flayer
->l_x
= flayer
->l_width
> 32 ? 32 : 0;
566 static void ZmodemRedisplayLine(int y
, int xs
, int xe
, int isblank
)
568 DefRedisplayLine(y
, xs
, xe
, isblank
);
569 if (y
== 0 && xs
== 0)
570 LPutStr(flayer
, "Zmodem active on another display", flayer
->l_width
> 32 ? 32 : flayer
->l_width
,
574 void ZmodemPage(void)
576 if (InitOverlayPage(1, &ZmodemLf
, 1))
578 LRefreshAll(flayer
, 0);
579 flayer
->l_x
= flayer
->l_width
> 32 ? 32 : 0;
583 static void PadStr(char *str
, int n
, int x
, int y
)
590 LPutStr(flayer
, str
, l
, &mchar_blank
, x
, y
);
592 LPutStr(flayer
, (char *)blank
, n
- l
, &mchar_blank
, x
+ l
, y
);