| /* -*- c -*- ------------------------------------------------------------- * |
| * |
| * Copyright 2004-2005 Murali Krishnan Ganapathy - All Rights Reserved |
| * |
| * This program is free software; you can redistribute it and/or modify |
| * it under the terms of the GNU General Public License as published by |
| * the Free Software Foundation, Inc., 53 Temple Place Ste 330, |
| * Boston MA 02111-1307, USA; either version 2 of the License, or |
| * (at your option) any later version; incorporated herein by reference. |
| * |
| * ----------------------------------------------------------------------- */ |
| |
| #include "help.h" |
| #include <stdio.h> |
| #include "string.h" |
| #include "com32io.h" |
| #include <syslinux/loadfile.h> // to read entire file into memory |
| |
| int nc, nr; // Number of columns/rows of the screen |
| char helpbasedir[HELPDIRLEN]; // name of help directory limited to HELPDIRLEN |
| |
| // Find the occurence of the count'th \n in buffer (or NULL) if not found |
| static char *findline(char *buffer, int count) |
| { |
| int ctr; |
| char *p = buffer - 1; |
| |
| if (count < 1) |
| return buffer; |
| for (ctr = 0; ctr < count; ctr++) { |
| p = strchr(p + 1, '\n'); |
| if (p == NULL) |
| return NULL; |
| } |
| return p; |
| } |
| |
| // return the number of lines in buffer |
| static int countlines(char *buffer) |
| { |
| int ans; |
| const char *p; |
| |
| p = buffer - 1; |
| ans = 1; |
| while (p) { |
| p = strchr(p + 1, '\n'); |
| ans++; |
| } |
| return ans; |
| } |
| |
| // Print numlines of text starting from buf |
| static void printtext(char *buf, int from) |
| { |
| char *f, *t; |
| int nlines, i; |
| |
| // clear window to print |
| nlines = nr - HELP_BODY_ROW - HELP_BOTTOM_MARGIN - 1; |
| |
| f = findline(buf, from); |
| if (!f) |
| return; // nothing to print |
| if (*f == '\n') |
| f++; // start of from+1st line |
| t = f; |
| |
| for (i = 0; i < nlines; i++) { |
| gotoxy(HELP_BODY_ROW + i, HELP_LEFT_MARGIN); |
| clear_end_of_line(); |
| putchar(SO); |
| gotoxy(HELP_BODY_ROW + i, nc - 1); |
| putch(LEFT_BORDER, 0x07); |
| putchar(SI); |
| |
| gotoxy(HELP_BODY_ROW + i, HELP_LEFT_MARGIN); |
| while (*t != '\n') { |
| if (*t == '\0') |
| return; |
| putchar(*t); |
| t++; |
| } |
| putchar('\n'); |
| t++; |
| } |
| } |
| |
| void showhelp(const char *filename) |
| { |
| char ph; |
| char *title, *text; |
| union { |
| char *buffer; |
| void *vbuf; |
| } buf; // This is to avoild type-punning issues |
| |
| char line[512]; |
| size_t size; |
| int scan; |
| int rv, numlines, curr_line; |
| |
| if (getscreensize(1, &nr, &nc)) { |
| /* Unknown screen size? */ |
| nc = 80; |
| nr = 24; |
| } |
| ph = nr - HELP_BODY_ROW; |
| cls(); |
| |
| /* Turn autowrap off, to avoid scrolling the menu */ |
| printf(CSI "?7l"); |
| |
| if (filename == NULL) { // print file contents |
| strcpy(line, "Filename not given"); |
| goto puke; |
| } |
| |
| rv = loadfile(filename, (void **)&buf.vbuf, &size); // load entire file into memory |
| if (rv < 0) { // Error reading file or no such file |
| sprintf(line, "Error reading file or file not found\n file=%s", filename); |
| goto puke; |
| } |
| |
| title = buf.buffer; |
| text = findline(title, 1); // end of first line |
| *text++ = '\0'; // end the title string and increment text |
| |
| // Now we have a file just print it. |
| numlines = countlines(text); |
| curr_line = 0; |
| scan = KEY_ESC + 1; // anything except ESCAPE |
| |
| /* top, left, bottom, right, attr */ |
| drawbox(0, 0, nr - 1, nc - 1, 0x07); |
| while (scan != KEY_ESC) { |
| /* Title */ |
| gotoxy(1, (nc - strlen(title)) / 2); |
| fputs(title, stdout); |
| drawhorizline(2, HELP_LEFT_MARGIN - 1, nc - HELP_RIGHT_MARGIN, 0x07, 0); // dumb==0 |
| /* Text */ |
| printtext(text, curr_line); |
| gotoxy(HELP_BODY_ROW - 1, nc - HELP_RIGHT_MARGIN); |
| if (curr_line > 0) |
| putchar(HELP_MORE_ABOVE); |
| else |
| putchar(' '); |
| gotoxy(nr - HELP_BOTTOM_MARGIN - 1, nc - HELP_RIGHT_MARGIN); |
| if (curr_line < numlines - ph) |
| putchar(HELP_MORE_BELOW); |
| else |
| putchar(' '); |
| |
| scan = get_key(stdout, 0); // wait for user keypress |
| |
| switch (scan) { |
| case KEY_HOME: |
| curr_line = 0; |
| break; |
| case KEY_END: |
| curr_line = numlines; |
| break; |
| case KEY_UP: |
| curr_line--; |
| break; |
| case KEY_DOWN: |
| curr_line++; |
| break; |
| case KEY_PGUP: |
| curr_line -= ph; |
| break; |
| case KEY_PGDN: |
| curr_line += ph; |
| break; |
| default: |
| break; |
| } |
| if (curr_line > numlines - ph) |
| curr_line = numlines - ph; |
| if (curr_line < 0) |
| curr_line = 0; |
| } |
| out: |
| cls(); |
| return; |
| |
| puke: |
| gotoxy(HELP_BODY_ROW, HELP_LEFT_MARGIN); |
| fputs(line, stdout); |
| while (1) { |
| scan = get_key(stdin, 0); |
| if (scan == KEY_ESC) |
| break; |
| } |
| goto out; |
| } |
| |
| void runhelp(const char *filename) |
| { |
| char fullname[HELPDIRLEN + 16]; |
| |
| cls(); |
| cursoroff(); |
| if (helpbasedir[0] != 0) { |
| strcpy(fullname, helpbasedir); |
| strcat(fullname, "/"); |
| strcat(fullname, filename); |
| showhelp(fullname); |
| } else |
| showhelp(filename); // Assume filename is absolute |
| } |
| |
| void runhelpsystem(unsigned int helpid) |
| { |
| char filename[15]; |
| |
| sprintf(filename, "hlp%05d.txt", helpid); |
| runhelp(filename); |
| } |
| |
| void init_help(const char *helpdir) |
| { |
| if (helpdir != NULL) |
| strcpy(helpbasedir, helpdir); |
| else |
| helpbasedir[0] = 0; |
| } |
| |
| void close_help(void) |
| { |
| } |