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 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 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 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 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 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 213 void runhelpsystem(unsigned int helpid) 214 { 215 char filename[15]; 216 217 sprintf(filename, "hlp%05d.txt", helpid); 218 runhelp(filename); 219 } 220 221 void init_help(const char *helpdir) 222 { 223 if (helpdir != NULL) 224 strcpy(helpbasedir, helpdir); 225 else 226 helpbasedir[0] = 0; 227 } 228 229 void close_help(void) 230 { 231 } 232