summaryrefslogtreecommitdiffstats
path: root/contrib/syslinux-4.02/com32/cmenu/libmenu/help.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/syslinux-4.02/com32/cmenu/libmenu/help.c')
-rw-r--r--contrib/syslinux-4.02/com32/cmenu/libmenu/help.c232
1 files changed, 232 insertions, 0 deletions
diff --git a/contrib/syslinux-4.02/com32/cmenu/libmenu/help.c b/contrib/syslinux-4.02/com32/cmenu/libmenu/help.c
new file mode 100644
index 0000000..0df1e10
--- /dev/null
+++ b/contrib/syslinux-4.02/com32/cmenu/libmenu/help.c
@@ -0,0 +1,232 @@
+/* -*- 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 right, nlines, i;
+
+ // clear window to print
+ right = nc - HELP_RIGHT_MARGIN;
+ 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;
+ while (i < nlines) {
+ 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++;
+ i++;
+ }
+}
+
+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)
+{
+}