Home | History | Annotate | Download | only in libmenu
      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