1/* -*- c -*- ------------------------------------------------------------- *
2 *
3 *   Copyright 2004-2005 Murali Krishnan Ganapathy - All Rights Reserved
4 *
5 *   This program is free software; you can redistribute it and/or modify
6 *   it under the terms of the GNU General Public License as published by
7 *   the Free Software Foundation, Inc., 53 Temple Place Ste 330,
8 *   Boston MA 02111-1307, USA; either version 2 of the License, or
9 *   (at your option) any later version; incorporated herein by reference.
10 *
11 * ----------------------------------------------------------------------- */
12
13#include "help.h"
14#include <stdio.h>
15#include "string.h"
16#include "com32io.h"
17#include <syslinux/loadfile.h>	// to read entire file into memory
18
19int nc, nr; // Number of columns/rows of the screen
20char helpbasedir[HELPDIRLEN];	// name of help directory limited to HELPDIRLEN
21
22// Find the occurence of the count'th \n in buffer (or NULL) if not found
23static char *findline(char *buffer, int count)
24{
25    int ctr;
26    char *p = buffer - 1;
27
28    if (count < 1)
29	return buffer;
30    for (ctr = 0; ctr < count; ctr++) {
31	p = strchr(p + 1, '\n');
32	if (p == NULL)
33	    return NULL;
34    }
35    return p;
36}
37
38// return the number of lines in buffer
39static int countlines(char *buffer)
40{
41    int ans;
42    const char *p;
43
44    p = buffer - 1;
45    ans = 1;
46    while (p) {
47	p = strchr(p + 1, '\n');
48	ans++;
49    }
50    return ans;
51}
52
53// Print numlines of text starting from buf
54static void printtext(char *buf, int from)
55{
56    char *f, *t;
57    int nlines, i;
58
59    // clear window to print
60    nlines = nr - HELP_BODY_ROW - HELP_BOTTOM_MARGIN - 1;
61
62    f = findline(buf, from);
63    if (!f)
64	return;			// nothing to print
65    if (*f == '\n')
66	f++;			// start of from+1st line
67    t = f;
68
69    for (i = 0; i < nlines; i++) {
70        gotoxy(HELP_BODY_ROW + i, HELP_LEFT_MARGIN);
71        clear_end_of_line();
72        putchar(SO);
73        gotoxy(HELP_BODY_ROW + i, nc - 1);
74        putch(LEFT_BORDER, 0x07);
75        putchar(SI);
76
77        gotoxy(HELP_BODY_ROW + i, HELP_LEFT_MARGIN);
78        while (*t != '\n') {
79            if (*t == '\0')
80                return;
81            putchar(*t);
82            t++;
83        }
84        putchar('\n');
85        t++;
86    }
87}
88
89void showhelp(const char *filename)
90{
91    char ph;
92    char *title, *text;
93    union {
94	char *buffer;
95	void *vbuf;
96    } buf;			// This is to avoild type-punning issues
97
98    char line[512];
99    size_t size;
100    int scan;
101    int rv, numlines, curr_line;
102
103    if (getscreensize(1, &nr, &nc)) {
104        /* Unknown screen size? */
105        nc = 80;
106        nr = 24;
107    }
108    ph = nr - HELP_BODY_ROW;
109    cls();
110
111    /* Turn autowrap off, to avoid scrolling the menu */
112    printf(CSI "?7l");
113
114    if (filename == NULL) {	// print file contents
115        strcpy(line, "Filename not given");
116        goto puke;
117    }
118
119    rv = loadfile(filename, (void **)&buf.vbuf, &size);	// load entire file into memory
120    if (rv < 0) {		// Error reading file or no such file
121        sprintf(line, "Error reading file or file not found\n file=%s", filename);
122        goto puke;
123    }
124
125    title = buf.buffer;
126    text = findline(title, 1);	// end of first line
127    *text++ = '\0';		// end the title string and increment text
128
129    // Now we have a file just print it.
130    numlines = countlines(text);
131    curr_line = 0;
132    scan = KEY_ESC + 1;		// anything except ESCAPE
133
134    /* top, left, bottom, right, attr */
135    drawbox(0, 0, nr - 1, nc - 1, 0x07);
136    while (scan != KEY_ESC) {
137    /* Title */
138    gotoxy(1, (nc - strlen(title)) / 2);
139    fputs(title, stdout);
140    drawhorizline(2, HELP_LEFT_MARGIN - 1, nc - HELP_RIGHT_MARGIN, 0x07, 0);	// dumb==0
141    /* Text */
142	printtext(text, curr_line);
143    gotoxy(HELP_BODY_ROW - 1, nc - HELP_RIGHT_MARGIN);
144	if (curr_line > 0)
145	    putchar(HELP_MORE_ABOVE);
146	else
147	    putchar(' ');
148	gotoxy(nr - HELP_BOTTOM_MARGIN - 1, nc - HELP_RIGHT_MARGIN);
149	if (curr_line < numlines - ph)
150	    putchar(HELP_MORE_BELOW);
151	else
152	    putchar(' ');
153
154    scan = get_key(stdout, 0); // wait for user keypress
155
156	switch (scan) {
157	case KEY_HOME:
158	    curr_line = 0;
159	    break;
160	case KEY_END:
161	    curr_line = numlines;
162	    break;
163	case KEY_UP:
164	    curr_line--;
165	    break;
166	case KEY_DOWN:
167	    curr_line++;
168	    break;
169	case KEY_PGUP:
170	    curr_line -= ph;
171	    break;
172	case KEY_PGDN:
173	    curr_line += ph;
174	    break;
175	default:
176	    break;
177	}
178	if (curr_line > numlines - ph)
179	    curr_line = numlines - ph;
180	if (curr_line < 0)
181	    curr_line = 0;
182    }
183out:
184    cls();
185    return;
186
187puke:
188    gotoxy(HELP_BODY_ROW, HELP_LEFT_MARGIN);
189    fputs(line, stdout);
190    while (1) {
191        scan = get_key(stdin, 0);
192        if (scan == KEY_ESC)
193            break;
194    }
195    goto out;
196}
197
198void runhelp(const char *filename)
199{
200    char fullname[HELPDIRLEN + 16];
201
202	cls();
203    cursoroff();
204    if (helpbasedir[0] != 0) {
205	strcpy(fullname, helpbasedir);
206	strcat(fullname, "/");
207	strcat(fullname, filename);
208	showhelp(fullname);
209    } else
210	showhelp(filename);	// Assume filename is absolute
211}
212
213void runhelpsystem(unsigned int helpid)
214{
215    char filename[15];
216
217    sprintf(filename, "hlp%05d.txt", helpid);
218    runhelp(filename);
219}
220
221void init_help(const char *helpdir)
222{
223    if (helpdir != NULL)
224	strcpy(helpbasedir, helpdir);
225    else
226	helpbasedir[0] = 0;
227}
228
229void close_help(void)
230{
231}
232