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
19 int nc, nr; // Number of columns/rows of the screen
20 char 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
findline(char * buffer,int count)23 static 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
countlines(char * buffer)39 static 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
printtext(char * buf,int from)54 static 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
showhelp(const char * filename)89 void 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 }
183 out:
184 cls();
185 return;
186
187 puke:
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
runhelp(const char * filename)198 void 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
runhelpsystem(unsigned int helpid)213 void runhelpsystem(unsigned int helpid)
214 {
215 char filename[15];
216
217 sprintf(filename, "hlp%05d.txt", helpid);
218 runhelp(filename);
219 }
220
init_help(const char * helpdir)221 void init_help(const char *helpdir)
222 {
223 if (helpdir != NULL)
224 strcpy(helpbasedir, helpdir);
225 else
226 helpbasedir[0] = 0;
227 }
228
close_help(void)229 void close_help(void)
230 {
231 }
232