4 * (C) 1992 Joseph H. Allen
5 * (C) 2001 Marek 'Marx' Grac
7 * This file is part of JOE (Joe's Own Editor)
12 __RCSID("$MirOS: contrib/code/jupp/help.c,v 1.11 2017/12/02 02:07:26 tg Exp $");
17 #ifdef HAVE_BSD_STRING_H
18 #include <bsd/string.h>
29 extern void outatr_help(SCRN *,int *,int *,int,int,int,int);
31 #define NOT_ENOUGH_MEMORY -11
33 struct help *help_actual = NULL; /* actual help screen */
37 * Returns 0 if the help file was succefully processed
38 * -1 if the help file couldn't be opened
39 * NOT_ENOUGH_MEMORY if there is not enough memory
42 int help_init(unsigned char *filename)
44 JFILE *fd; /* help file */
45 unsigned char buf[1024]; /* input buffer */
48 unsigned int bfl; /* buffer length */
49 unsigned int hlpsiz, hlpbsz; /* number of used/allocated bytes for tmp->text */
50 unsigned char *tempbuf;
52 if (!(fd = jfopen((char *)filename, "r"))) /* open the help file */
53 return -1; /* return if we couldn't open the file */
55 fprintf(stderr, "Processing '%s'...", filename);
58 while (jfgets((char *)buf, sizeof(buf), fd)) {
59 if (buf[0] == '{') { /* start of help screen */
60 if (!(tmp = (struct help *) joe_malloc(sizeof(struct help)))) {
61 return NOT_ENOUGH_MEMORY;
68 tmp->name = vsncpy(NULL, 0, sz(buf + 1) - 1);
70 while ((jfgets((char *)buf, sizeof(buf), fd)) && (buf[0] != '}')) {
71 bfl = strlen((char *)buf);
72 if (hlpsiz + bfl > hlpbsz) {
74 tempbuf = (unsigned char *) joe_realloc(tmp->text, hlpbsz + bfl + 1024);
78 return NOT_ENOUGH_MEMORY;
83 tmp->text = (unsigned char *) joe_malloc(bfl + 1024);
86 return NOT_ENOUGH_MEMORY;
93 strlcpy((char *)(tmp->text + hlpsiz), (char *)buf, 1024);
97 if (buf[0] == '}') { /* set new help screen as actual one */
98 tmp->prev = help_actual;
101 help_actual->next = tmp;
105 fprintf(stderr, "\nHelp file '%s' is not properly ended with } on new line.\n", filename);
106 fprintf(stderr, "Do you want to accept incomplete help screen (y/n)?");
108 if (fgets((char *)buf, 8, stdin) == NULL ||
109 (!((buf[0] == 'y') || (buf[0] == 'Y')))) {
114 tmp->prev = help_actual;
117 help_actual->next = tmp;
124 jfclose(fd); /* close help file */
126 fprintf(stderr, "done\n");
128 while (help_actual && help_actual->prev) { /* move to first help screen */
129 help_actual = help_actual->prev;
136 * Find context help - find help entry with the same name
139 struct help *find_context_help(const unsigned char *name)
141 struct help *tmp = help_actual;
143 while (tmp->prev != NULL) /* find the first help entry */
146 while (tmp != NULL && strcmp(tmp->name, name) != 0)
155 void help_display(SCREEN *t)
162 str = help_actual->text;
167 for (y = skiptop; y != t->wind; ++y) {
168 if (t->t->updtab[y]) {
169 unsigned char *start = str;
175 /* First pass: count no. springs \| and determine minimum width */
176 while(*str && *str!='\n')
204 /* Now calculate span width */
205 if (width >= t->w - 1 || nspans==0) {
209 spanwidth = ((t->w - 1) - width)/nspans;
210 spanextra = nspans - ((t->w - 1) - width - nspans*spanwidth);
212 /* Second pass: display text */
213 for (x = 0; x != t->w - 1; ++x) {
214 if (*str == '\n' || !*str) {
215 if (eraeol(t->t, x, y)) {
225 for (z=0;z!=spanwidth;++z)
226 outatr(locale_map,t->t,t->t->scrn+x+y*t->w+z,t->t->attr+x+y*t->w+z,x+z,y,' ',atr);
227 if (spancount++ >= spanextra) {
228 outatr(locale_map,t->t,t->t->scrn+x+y*t->w+z,t->t->attr+x+y*t->w+z,x+z,y,' ',atr);
269 t->t->scrn + x + y * t->w,
270 t->t->attr + x + y * t->w,
278 while (*str && *str != '\n')
288 int help_on(SCREEN *t)
291 t->wind = help_actual->lines + skiptop;
292 if ((t->h - t->wind) < FITHEIGHT) {
293 t->wind = t->h - FITHEIGHT;
300 msetI(t->t->updtab + skiptop, 1, t->wind);
310 void help_off(SCREEN *t)
317 * Show/hide current help screen
319 int u_help(BASE *base)
322 struct help *new_help;
324 if (w->huh && (new_help = find_context_help(w->huh)) != NULL) {
325 if (help_actual != new_help) {
326 if (w->t->wind != skiptop)
328 help_actual = new_help; /* prepare context help */
331 if (w->t->wind == skiptop) {
332 return help_on(w->t); /* help screen is hidden, so show the actual one */
334 help_off(w->t); /* hide actual help screen */
340 * Show next help screen (if it is possible)
342 int u_help_next(BASE *base)
346 if (help_actual && help_actual->next) { /* is there any next help screen? */
347 if (w->t->wind != skiptop) {
348 help_off(w->t); /* if help screen was visible, then hide it */
350 help_actual = help_actual->next; /* change to next help screen */
351 return help_on(w->t); /* show actual help screen */
358 * Show previous help screen (if it is possible)
360 int u_help_prev(BASE *base)
364 if (help_actual && help_actual->prev) { /* is there any previous help screen? */
365 if (w->t->wind != skiptop)
366 help_off(w->t); /* if help screen was visible, then hide it */
367 help_actual = help_actual->prev; /* change to previous help screen */
368 return help_on(w->t); /* show actual help screen */