summaryrefslogtreecommitdiff
path: root/menu
diff options
context:
space:
mode:
authorhpa <hpa>2004-02-04 23:36:07 +0000
committerhpa <hpa>2004-02-04 23:36:07 +0000
commit3f1dc4d44e2edd814eb98b229683ef12c59a0589 (patch)
tree09810eb02cf530f2a6287cdbd693f2e722af214a /menu
parent00e7167012ca033be039c9ea6d9d880f833d6fed (diff)
downloadsyslinux-3f1dc4d44e2edd814eb98b229683ef12c59a0589.tar.gz
Patch from Murali for windowing support and a much cleaner interface;
some minor formatting cleanups on my part
Diffstat (limited to 'menu')
-rw-r--r--menu/biosio.c150
-rw-r--r--menu/biosio.h22
-rw-r--r--menu/complex.c8
-rw-r--r--menu/menu.c608
-rw-r--r--menu/menu.h46
-rw-r--r--menu/simple.c4
6 files changed, 448 insertions, 390 deletions
diff --git a/menu/biosio.c b/menu/biosio.c
index d27f4f14..6c573fa6 100644
--- a/menu/biosio.c
+++ b/menu/biosio.c
@@ -18,8 +18,8 @@
/* Print character and attribute at cursor */
static inline void asm_cprint(char chr, char attr, int times, char disppage)
{
- asm volatile("movb $0x09,%%ah ; int $0x10"
- : "+a" (chr) : "b" (attr + (disppage << 8)), "c" (times));
+ asm volatile("movb $0x09,%%ah ; int $0x10"
+ : "+a" (chr) : "b" (attr + (disppage << 8)), "c" (times));
}
void cprint(char chr,char attr,int times,char disppage)
@@ -29,8 +29,8 @@ void cprint(char chr,char attr,int times,char disppage)
static inline void asm_setdisppage(char num)
{
- asm volatile("movb $0x05,%%ah ; int $0x10"
- : "+a" (num));
+ asm volatile("movb $0x05,%%ah ; int $0x10"
+ : "+a" (num));
}
void setdisppage(char num) // Set the display page to specified number
@@ -41,12 +41,12 @@ void setdisppage(char num) // Set the display page to specified number
static inline char asm_getdisppage(void)
{
- char page;
-
- asm("movb $0x0f,%%ah ; "
- "int $0x10 ; "
- "movb %%bh,%0" : "=rm" (page) : : "eax", "ebp");
- return page;
+ char page;
+
+ asm("movb $0x0f,%%ah ; "
+ "int $0x10 ; "
+ "movb %%bh,%0" : "=rm" (page) : : "eax", "ebp");
+ return page;
}
char getdisppage() // Get current display page
@@ -66,7 +66,7 @@ static inline void asm_putchar(char x, char page)
void csprint(const char *str)
{
char page = asm_getdisppage();
-
+
while ( *str ) {
asm_putchar(*str, page);
str++;
@@ -85,18 +85,19 @@ void clearwindow(char top, char left, char bot, char right, char page, char fill
void cls(void)
{
- asm_cprint(' ',0x07,25*80,getdisppage());
+ gotoxy(0,0,getdisppage());
+ asm_cprint(' ',0x07,getnumrows()*getnumcols(),getdisppage());
}
static inline void asm_gotoxy(char row,char col, char page)
{
- asm volatile("movb %1,%%bh ; "
- "movb $0x02,%%ah ; "
- "int $0x10"
- : : "d" ((row << 8) + col), "g" (page)
- : "eax", "ebx");
+ asm volatile("movb %1,%%bh ; "
+ "movb $0x02,%%ah ; "
+ "int $0x10"
+ : : "d" ((row << 8) + col), "g" (page)
+ : "eax", "ebx");
}
-
+
void gotoxy(char row,char col, char page)
{
asm_gotoxy(row,col,page);
@@ -104,16 +105,16 @@ void gotoxy(char row,char col, char page)
static inline void asm_getpos(char *row, char *col, char page)
{
- asm("movb %2,%%bh ; "
- "movb $0x03,%%ah ; "
- "int $0x10 ; "
- "movb %%dh,%0 ; "
- "movb %%dl,%1"
- : "=m" (*row), "=m" (*col)
- : "g" (page)
- : "eax", "ebx", "ecx", "edx");
+ asm("movb %2,%%bh ; "
+ "movb $0x03,%%ah ; "
+ "int $0x10 ; "
+ "movb %%dh,%0 ; "
+ "movb %%dl,%1"
+ : "=m" (*row), "=m" (*col)
+ : "g" (page)
+ : "eax", "ebx", "ecx", "edx");
}
-
+
void getpos(char * row, char * col, char page)
{
asm_getpos(row,col,page);
@@ -128,8 +129,8 @@ char asm_inputc(char *scancode)
: "=a" (ax));
if (scancode)
- *scancode = (ax >> 8);
-
+ *scancode = (ax >> 8);
+
return (char)ax;
}
@@ -140,8 +141,8 @@ char inputc(char * scancode)
static inline void asm_cursorshape(char start, char end)
{
- asm volatile("movb $0x01,%%ah ; int $0x10"
- : : "c" ((start << 8) + end) : "eax");
+ asm volatile("movb $0x01,%%ah ; int $0x10"
+ : : "c" ((start << 8) + end) : "eax");
}
void cursoroff(void)
@@ -159,46 +160,59 @@ char eolstr[] = "\n$";
static inline char asm_getchar(void)
{
- char v;
-
- /* Get key without echo */
- asm("movb $0x08,%%ah ; int $0x21" : "=a" (v));
-
- return v;
+ char v;
+
+ /* Get key without echo */
+ asm("movb $0x08,%%ah ; int $0x21" : "=a" (v));
+
+ return v;
}
-void getstring(char *str, unsigned int size)
// Reads a line of input from stdin. Replace CR with NUL byte
+void getstring(char *str, unsigned int size)
{
- char c;
- char *p = str;
- char page = asm_getdisppage();
-
- while ( (c = asm_getchar()) != '\r' ) {
- switch (c) {
- case '\0': /* Extended char prefix */
- asm_getchar(); /* Drop */
- break;
- case '\b':
- if ( p > str ) {
- p--;
- csprint("\b \b");
- }
- break;
- case '\x15': /* Ctrl-U: kill input */
- while ( p > str ) {
- p--;
- csprint("\b \b");
- }
- break;
- default:
- if ( c >= ' ' && (unsigned int)(p-str) < size-1 ) {
- *p++ = c;
- asm_putchar(c, page);
- }
- break;
+ char c;
+ char *p = str;
+ char page = asm_getdisppage();
+
+ while ( (c = asm_getchar()) != '\r' ) {
+ switch (c) {
+ case '\0': /* Extended char prefix */
+ asm_getchar(); /* Drop */
+ break;
+ case '\b':
+ if ( p > str ) {
+ p--;
+ csprint("\b \b");
+ }
+ break;
+ case '\x15': /* Ctrl-U: kill input */
+ while ( p > str ) {
+ p--;
+ csprint("\b \b");
+ }
+ break;
+ default:
+ if ( c >= ' ' && (unsigned int)(p-str) < size-1 ) {
+ *p++ = c;
+ asm_putchar(c, page);
+ }
+ break;
+ }
}
- }
- *p = '\0';
- csprint("\r\n");
+ *p = '\0';
+ csprint("\r\n");
+}
+
+static inline void asm_setvideomode(char mode)
+{
+ /* This BIOS function is notoriously register-dirty,
+ so push/pop around it */
+ asm volatile("pushal ; xorb %%ah,%%ah ; int $0x10 ; popal"
+ : : "a" (mode) );
+}
+
+void setvideomode(char mode)
+{
+ asm_setvideomode(mode);
}
diff --git a/menu/biosio.h b/menu/biosio.h
index 719a8e15..c4ba0c6a 100644
--- a/menu/biosio.h
+++ b/menu/biosio.h
@@ -49,4 +49,26 @@ void cursoron(void); /* Turns off cursor */
void getstring(char *str, unsigned int size);
+static inline unsigned char readbiosb(unsigned short addr)
+{
+ unsigned char v;
+
+ asm("movw %2,%%fs ; "
+ "movb %%fs:%1,%0"
+ : "=r" (v)
+ : "m" (*(unsigned char *)(unsigned int)addr),
+ "r" ((unsigned short)0));
+ return v;
+}
+static inline char getnumrows()
+{
+ return readbiosb(0x484);
+}
+static inline char getnumcols(void)
+{
+ return readbiosb(0x44a);
+}
+
+void setvideomode(char mode); // Set the video mode.
+
#endif
diff --git a/menu/complex.c b/menu/complex.c
index 47cf3734..8498618d 100644
--- a/menu/complex.c
+++ b/menu/complex.c
@@ -46,7 +46,7 @@ void msys_handler(t_menusystem *ms, t_menuitem *mi)
return;
}
strcpy (infoline," ");
- if (flags.baseurl) strcat(infoline,"baseurl=http://128.135.11.139/gui ");
+ if (flags.baseurl) strcat(infoline,"baseurl=http://192.168.11.12/gui ");
if (flags.mountcd) strcat(infoline,"mountcd=yes ");
if (!flags.network)
strcat(infoline,"network=no ");
@@ -118,8 +118,12 @@ int menumain(char *cmdline)
(void)cmdline; /* Not used */
+ // Switch video mode here
+ // setvideomode(0x18); // or whatever mode you want
+
// Choose the default title and setup default values for all attributes....
init_menusystem(NULL);
+ set_window_size(1,1,23,79); // Leave one row/col all around
// Choose the default values for all attributes and char's
// -1 means choose defaults (Actually the next 4 lines are not needed)
@@ -182,7 +186,7 @@ int menumain(char *cmdline)
{
csprint("Enter IP address (last two octets only): ");
getstring(ip, sizeof ip);
- strcat(cmd,"ipaddr=128.135.");
+ strcat(cmd,"ipaddr=192.168.");
strcat(cmd,ip);
}
}
diff --git a/menu/menu.c b/menu/menu.c
index e786b924..5a865a2a 100644
--- a/menu/menu.c
+++ b/menu/menu.c
@@ -1,272 +1,272 @@
- /* -*- c -*- ------------------------------------------------------------- *
- *
- * Copyright 2004 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,
- * Bostom MA 02111-1307, USA; either version 2 of the License, or
- * (at your option) any later version; incorporated herein by reference.
- *
- * ----------------------------------------------------------------------- */
-
- #include "biosio.h"
- #include "string.h"
- #include "menu.h"
-
- // Structures
-
- // Declare a menusystem here
- static t_menusystem menusystem;
-
- /* Basic Menu routines */
-
- void drawbox(char top, char left, char bot, char right,char attr, char page)
- {
- char x;
-
- // Top border
- gotoxy(top,left,page);
- cprint(TOPLEFT,attr,1,page);
- gotoxy(top,left+1,page);
- cprint(TOP,attr,right-left,page);
- gotoxy(top,right,page);
- cprint(TOPRIGHT,attr,1,page);
- // Bottom border
- gotoxy(bot,left,page);
- cprint(BOTLEFT,attr,1,page);
- gotoxy(bot,left+1,page);
- cprint(BOT,attr,right-left,page);
- gotoxy(bot,right,page);
- cprint(BOTRIGHT,attr,1,page);
- // Left & right borders
- for (x=top+1; x < bot; x++)
- {
- gotoxy(x,left,page);
- cprint(LEFT,attr,1,page);
- gotoxy(x,right,page);
- cprint(RIGHT,attr,1,page);
- }
- }
-
- void printmenu(t_menu * menu, int curr, char top, char left)
- {
- int x;
- int numitems,menuwidth;
- t_menusystem *ms;
- char attr;
-
- ms = & menusystem;
- numitems = menu->numitems;
- menuwidth = menu->menuwidth+2;
- clearwindow(top,left-1,top+numitems+1,left+menuwidth+1,ms->menupage,ms->fillchar,ms->shadowattr);
- drawbox(top-1,left-2,top+numitems,left+menuwidth,ms->normalattr,ms->menupage);
- // Menu title
- x = (menuwidth - strlen(menu->title) - 1) >> 1;
- gotoxy(top-1,left+x,ms->menupage);
- csprint(menu->title);
- for (x=0; x < numitems; x++)
- {
- gotoxy(top+x,left-1,ms->menupage);
- if (menu->items[x].action == OPT_INACTIVE)
- {
- attr = (x==curr? ms->revinactattr : ms->inactattr);
- } else {
- attr = (x==curr ? ms->reverseattr : ms->normalattr);
- }
- cprint(ms->spacechar,attr,menuwidth+1,ms->menupage);
- gotoxy(top+x,left,ms->menupage);
- csprint(menu->items[x].item);
- gotoxy(top+x,left+menuwidth-1,ms->menupage); // Last char if any
- switch (menu->items[x].action)
- {
- case OPT_SUBMENU:
- cprint(SUBMENUCHAR,attr,1,ms->menupage);
- break;
- case OPT_CHECKBOX:
- cprint( (menu->items[x].itemdata.checked ? CHECKED : UNCHECKED),attr,1,ms->menupage);
- break;
- }
- }
- if (menusystem.handler) menusystem.handler(&menusystem,menu->items+curr);
- }
-
- void cleanupmenu(t_menu *menu, char top,char left)
- {
- t_menusystem *ms = &menusystem;
- clearwindow(top,left-1,top+menu->numitems+1,left+menu->menuwidth+3,ms->menupage,ms->fillchar,ms->fillattr); // Clear the shadow
- clearwindow(top-1,left-2,top+menu->numitems,left+menu->menuwidth+2,ms->menupage,ms->fillchar,ms->fillattr); // clear the main window
- }
-
- /* Handle one menu */
- t_menuitem * getmenuoption( t_menu *menu, char top, char left, char startopt)
- // Return item chosen or NULL if ESC was hit.
- {
- int curr;
- char asc,scan;
- char numitems;
- t_menusystem *ms;
- t_menuitem *ci; // Current item
-
- ms = & menusystem;
- numitems = menu->numitems;
- // Setup status line
- gotoxy(ms->statline,0,ms->menupage);
- cprint(ms->spacechar,ms->reverseattr,80,ms->menupage);
-
- // Initialise current menu item
- curr = startopt;
- gotoxy(ms->statline,0,ms->menupage);
- cprint(ms->spacechar,ms->statusattr,80,1);
- gotoxy(ms->statline,0,ms->menupage);
- csprint(menu->items[curr].status);
- while (1) // Forever
- {
- printmenu(menu,curr,top,left);
- ci = &(menu->items[curr]);
- asc = inputc(&scan);
- switch (scan)
- {
- case HOMEKEY:
- curr = 0;
- break;
- case ENDKEY:
- curr = numitems -1;
- break;
- case PAGEDN:
- curr += 5;
- break;
- case PAGEUP:
- curr -= 5;
- break;
- case UPARROW:
- curr --;
- break;
- case DNARROW:
- curr++;
- break;
- case LTARROW:
- case ESCAPE:
- return NULL;
- break;
- case ENTERA:
- case RTARROW:
- case ENTERB:
- if (ci->action == OPT_INACTIVE) break;
- if (ci->action == OPT_CHECKBOX) break;
- if (ci->action == OPT_EXITMENU) return NULL; // As if we hit Esc
- return ci;
- break;
- case SPACEKEY:
- if (ci->action != OPT_CHECKBOX) break;
- ci->itemdata.checked = !ci->itemdata.checked;
- // Call handler to see it anything needs to be done
- if (ci->handler != NULL) ci->handler(&menusystem,ci);
- break;
- }
- // Adjust within range
- if (curr < 0) curr=0;
- if (curr >= numitems) curr = numitems -1;
- // Update status line
- gotoxy(ms->statline,0,ms->menupage);
- cprint(ms->spacechar,ms->statusattr,80,ms->menupage);
- csprint(menu->items[curr].status);
- }
- return NULL; // Should never come here
- }
-
- /* Handle the entire system of menu's. */
- t_menuitem * runmenusystem(char top, char left, int currmenu)
- /*
- * currmenu
- * Which menu should be currently displayed
- * top,left
- * What is the position of the top,left corner of the menu
- *
- * Return Value:
- * Returns a pointer to the final item chosen, or NULL if nothing chosen.
- */
- {
- t_menu *cmenu;
- t_menusystem *ms = &menusystem;
- t_menuitem *opt,*choice;
- int numitems;
- char startopt;
-
- startopt = 0;
- startover:
- cmenu = (menusystem.menus+currmenu);
- numitems = menusystem.menus[currmenu].numitems;
- opt = getmenuoption(cmenu,top,left,startopt);
- if (opt == NULL)
- {
- // User hit Esc
- cleanupmenu(cmenu,top,left);
- return NULL;
- }
- if (opt->action != OPT_SUBMENU) // We are done with the menu system
- {
- cleanupmenu(cmenu,top,left);
- return opt; // parent cleanup other menus
- }
- if (opt->itemdata.submenunum >= menusystem.nummenus) // This is Bad....
- {
- gotoxy(12,12,ms->menupage); // Middle of screen
- csprint("Invalid submenu requested. Ask administrator to correct this.");
- cleanupmenu(cmenu,top,left);
- return NULL; // Pretend user hit esc
- }
- // Call recursively for submenu
- // Position the submenu below the current item,
- // covering half the current window (horizontally)
- choice = runmenusystem(top+opt->index+2, left+3+(cmenu->menuwidth >> 1), opt->itemdata.submenunum);
- if (choice==NULL) // User hit Esc in submenu
- {
- // Startover
- startopt = opt->index;
- goto startover;
- }
- else
- {
- cleanupmenu(cmenu,top,left);
- return choice;
- }
- }
-
- /* User Callable functions */
-
- t_menuitem * showmenus(char startmenu)
- {
- t_menuitem *rv;
- t_menusystem *ms;
- char oldpage, tpos;
- char oldrow, oldcol;
-
- ms = & menusystem;
- // Setup screen for menusystem
- oldpage = getdisppage();
- getpos(&oldrow, &oldcol, oldpage);
- setdisppage(ms->menupage);
- clearwindow(0,0,24,79,ms->menupage,ms->fillchar,ms->fillattr);
- tpos = (80 - strlen(menusystem.title) - 1) >> 1; // To center it on line
- gotoxy(0,0,ms->menupage);
- cprint(ms->tfillchar,ms->titleattr,80,ms->menupage);
- gotoxy(0,tpos,ms->menupage);
- csprint(menusystem.title);
-
- cursoroff(); // Doesn't seem to work?
-
- // Go
- rv = runmenusystem(MENUROW, MENUCOL, startmenu);
-
- // Hide the garbage we left on the screen
- cursoron();
- if (oldpage == ms->menupage) {
- cls();
- } else {
- setdisppage(oldpage);
- gotoxy(oldrow, oldcol, oldpage);
+/* -*- c -*- ------------------------------------------------------------- *
+ *
+ * Copyright 2004 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,
+ * Bostom MA 02111-1307, USA; either version 2 of the License, or
+ * (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+/* This program can be compiled for DOS with the OpenWatcom compiler
+ * (http://www.openwatcom.org/):
+ *
+ * wcl -3 -osx -mt getargs.c
+ */
+
+#include "biosio.h"
+#include "string.h"
+#include "menu.h"
+
+// Structures
+
+// Declare a menusystem here
+static t_menusystem menusystem;
+
+/* Basic Menu routines */
+
+void drawbox(char top, char left, char bot, char right,char attr, char page)
+{
+ char x;
+
+ // Top border
+ gotoxy(top,left,page);
+ cprint(TOPLEFT,attr,1,page);
+ gotoxy(top,left+1,page);
+ cprint(TOP,attr,right-left,page);
+ gotoxy(top,right,page);
+ cprint(TOPRIGHT,attr,1,page);
+ // Bottom border
+ gotoxy(bot,left,page);
+ cprint(BOTLEFT,attr,1,page);
+ gotoxy(bot,left+1,page);
+ cprint(BOT,attr,right-left,page);
+ gotoxy(bot,right,page);
+ cprint(BOTRIGHT,attr,1,page);
+ // Left & right borders
+ for (x=top+1; x < bot; x++)
+ {
+ gotoxy(x,left,page);
+ cprint(LEFT,attr,1,page);
+ gotoxy(x,right,page);
+ cprint(RIGHT,attr,1,page);
+ }
+}
+
+void printmenu(t_menu * menu, int curr, char top, char left)
+{
+ int x;
+ int numitems,menuwidth;
+ t_menusystem *ms;
+ char attr;
+
+ ms = & menusystem;
+ numitems = menu->numitems;
+ menuwidth = menu->menuwidth+2;
+ clearwindow(top,left-1,top+numitems+1,left+menuwidth+1,ms->menupage,ms->fillchar,ms->shadowattr);
+ drawbox(top-1,left-2,top+numitems,left+menuwidth,ms->normalattr,ms->menupage);
+ // Menu title
+ x = (menuwidth - strlen(menu->title) - 1) >> 1;
+ gotoxy(top-1,left+x,ms->menupage);
+ csprint(menu->title);
+ for (x=0; x < numitems; x++)
+ {
+ gotoxy(top+x,left-1,ms->menupage);
+ if (menu->items[x].action == OPT_INACTIVE)
+ {
+ attr = (x==curr? ms->revinactattr : ms->inactattr);
+ } else {
+ attr = (x==curr ? ms->reverseattr : ms->normalattr);
+ }
+ cprint(ms->spacechar,attr,menuwidth+1,ms->menupage);
+ gotoxy(top+x,left,ms->menupage);
+ csprint(menu->items[x].item);
+ gotoxy(top+x,left+menuwidth-1,ms->menupage); // Last char if any
+ switch (menu->items[x].action)
+ {
+ case OPT_SUBMENU:
+ cprint(SUBMENUCHAR,attr,1,ms->menupage);
+ break;
+ case OPT_CHECKBOX:
+ cprint( (menu->items[x].itemdata.checked ? CHECKED : UNCHECKED),attr,1,ms->menupage);
+ break;
+ }
+ }
+ if (menusystem.handler) menusystem.handler(&menusystem,menu->items+curr);
+}
+
+void cleanupmenu(t_menu *menu, char top,char left)
+{
+ t_menusystem *ms = &menusystem;
+ clearwindow(top,left-1,top+menu->numitems+1,left+menu->menuwidth+3,ms->menupage,ms->fillchar,ms->fillattr); // Clear the shadow
+ clearwindow(top-1,left-2,top+menu->numitems,left+menu->menuwidth+2,ms->menupage,ms->fillchar,ms->fillattr); // clear the main window
+}
+
+/* Handle one menu */
+t_menuitem * getmenuoption( t_menu *menu, char top, char left, char startopt)
+// Return item chosen or NULL if ESC was hit.
+{
+ int curr;
+ char asc,scan;
+ char numitems;
+ t_menusystem *ms;
+ t_menuitem *ci; // Current item
+
+ ms = & menusystem;
+ numitems = menu->numitems;
+ // Setup status line
+ gotoxy(ms->minrow+ms->statline,ms->mincol,ms->menupage);
+ cprint(ms->spacechar,ms->reverseattr,ms->numcols,ms->menupage);
+
+ // Initialise current menu item
+ curr = startopt;
+ gotoxy(ms->minrow+ms->statline,ms->mincol,ms->menupage);
+ cprint(ms->spacechar,ms->statusattr,ms->numcols,1);
+ gotoxy(ms->minrow+ms->statline,ms->mincol,ms->menupage);
+ csprint(menu->items[curr].status);
+ while (1) // Forever
+ {
+ printmenu(menu,curr,top,left);
+ ci = &(menu->items[curr]);
+ asc = inputc(&scan);
+ switch (scan)
+ {
+ case HOMEKEY:
+ curr = 0;
+ break;
+ case ENDKEY:
+ curr = numitems -1;
+ break;
+ case PAGEDN:
+ curr += 5;
+ break;
+ case PAGEUP:
+ curr -= 5;
+ break;
+ case UPARROW:
+ curr --;
+ break;
+ case DNARROW:
+ curr++;
+ break;
+ case LTARROW:
+ case ESCAPE:
+ return NULL;
+ break;
+ case ENTERA:
+ case RTARROW:
+ case ENTERB:
+ if (ci->action == OPT_INACTIVE) break;
+ if (ci->action == OPT_CHECKBOX) break;
+ if (ci->action == OPT_EXITMENU) return NULL; // As if we hit Esc
+ return ci;
+ break;
+ case SPACEKEY:
+ if (ci->action != OPT_CHECKBOX) break;
+ ci->itemdata.checked = !ci->itemdata.checked;
+ // Call handler to see it anything needs to be done
+ if (ci->handler != NULL) ci->handler(&menusystem,ci);
+ break;
+ }
+ // Adjust within range
+ if (curr < 0) curr=0;
+ if (curr >= numitems) curr = numitems -1;
+ // Update status line
+ gotoxy(ms->minrow+ms->statline,ms->mincol,ms->menupage);
+ cprint(ms->spacechar,ms->statusattr,ms->numcols,ms->menupage);
+ csprint(menu->items[curr].status);
+ }
+ return NULL; // Should never come here
+}
+
+/* Handle the entire system of menu's. */
+t_menuitem * runmenusystem(char top, char left, int currmenu)
+/*
+ * currmenu
+ * Which menu should be currently displayed
+ * top,left
+ * What is the position of the top,left corner of the menu
+ *
+ * Return Value:
+ * Returns a pointer to the final item chosen, or NULL if nothing chosen.
+ */
+{
+ t_menu *cmenu;
+ t_menusystem *ms = &menusystem;
+ t_menuitem *opt,*choice;
+ int numitems;
+ char startopt;
+
+ startopt = 0;
+startover:
+ cmenu = (menusystem.menus+currmenu);
+ numitems = menusystem.menus[currmenu].numitems;
+ opt = getmenuoption(cmenu,top,left,startopt);
+ if (opt == NULL)
+ {
+ // User hit Esc
+ cleanupmenu(cmenu,top,left);
+ return NULL;
+ }
+ if (opt->action != OPT_SUBMENU) // We are done with the menu system
+ {
+ cleanupmenu(cmenu,top,left);
+ return opt; // parent cleanup other menus
}
+ if (opt->itemdata.submenunum >= menusystem.nummenus) // This is Bad....
+ {
+ gotoxy(12,12,ms->menupage); // Middle of screen
+ csprint("Invalid submenu requested. Ask administrator to correct this.");
+ cleanupmenu(cmenu,top,left);
+ return NULL; // Pretend user hit esc
+ }
+ // Call recursively for submenu
+ // Position the submenu below the current item,
+ // covering half the current window (horizontally)
+ choice = runmenusystem(top+opt->index+2, left+3+(cmenu->menuwidth >> 1), opt->itemdata.submenunum);
+ if (choice==NULL) // User hit Esc in submenu
+ {
+ // Startover
+ startopt = opt->index;
+ goto startover;
+ }
+ else
+ {
+ cleanupmenu(cmenu,top,left);
+ return choice;
+ }
+}
+
+/* User Callable functions */
+
+t_menuitem * showmenus(char startmenu)
+{
+ t_menuitem *rv;
+ t_menusystem *ms;
+ char oldpage,tpos;
+
+ ms = & menusystem;
+ // Setup screen for menusystem
+ oldpage = getdisppage();
+ setdisppage(ms->menupage);
+ cls();
+ clearwindow(ms->minrow,ms->mincol,ms->maxrow,ms->maxcol,ms->menupage,ms->fillchar,ms->fillattr);
+ tpos = (ms->numcols - strlen(menusystem.title) - 1) >> 1; // To center it on line
+ gotoxy(ms->minrow,ms->mincol,ms->menupage);
+ cprint(ms->tfillchar,ms->titleattr,ms->numcols,ms->menupage);
+ gotoxy(ms->minrow,ms->mincol+tpos,ms->menupage);
+ csprint(menusystem.title);
+
+ cursoroff(); // Doesn't seem to work?
+
+ // Go
+ rv = runmenusystem(ms->minrow+MENUROW, ms->mincol+MENUCOL, startmenu);
+
+ // Hide the garbage we left on the screen
+ cursoron();
+ if (oldpage == ms->menupage) cls(); else setdisppage(oldpage);
// Return user choice
return rv;
@@ -296,6 +296,14 @@ void init_menusystem(const char *title)
menusystem.menupage = MENUPAGE; // Usually no need to change this at all
menusystem.handler = NULL; // No handler function
+
+ // Figure out the size of the screen we are in now.
+ // By default we use the whole screen for our menu
+ menusystem.minrow = menusystem.mincol = 0;
+ menusystem.numcols = getnumcols();
+ menusystem.numrows = getnumrows();
+ menusystem.maxcol = menusystem.numcols - 1;
+ menusystem.maxrow = menusystem.numrows - 1;
}
void set_normal_attr(char normal, char selected, char inactivenormal, char inactiveselected)
@@ -309,7 +317,9 @@ void set_normal_attr(char normal, char selected, char inactivenormal, char inact
void set_status_info(char statusattr, char statline)
{
if (statusattr != 0xFF) menusystem.statusattr = statusattr;
- if (statline != 0xFF) menusystem.statline = statline;
+ // statline is relative to minrow
+ if (statline >= menusystem.numrows) statline = menusystem.numrows - 1;
+ menusystem.statline = statline; // relative to ms->minrow, 0 based
}
void set_title_info(char tfillchar, char titleattr)
@@ -326,6 +336,26 @@ void set_misc_info(char fillchar, char fillattr,char spacechar, char shadowattr)
if (shadowattr!= 0xFF) menusystem.shadowattr= shadowattr;
}
+void set_window_size(char top, char left, char bot, char right) // Set the window which menusystem should use
+{
+ t_menusystem *ms;
+
+ char nr,nc;
+ if ((top > bot) || (left > right)) return; // Sorry no change will happen here
+ nr = getnumrows();
+ nc = getnumcols();
+ if (bot >= nr) bot = nr-1;
+ if (right >= nc) right = nc-1;
+ ms = &menusystem;
+ ms->minrow = top;
+ ms->mincol = left;
+ ms->maxrow = bot;
+ ms->maxcol = right;
+ ms->numcols = right - left + 1;
+ ms->numrows = bot - top + 1;
+ if (ms->statline >= ms->numrows) ms->statline = ms->numrows - 1; // Clip statline if need be
+}
+
void reg_handler( t_menusystem_handler handler)
{
menusystem.handler = handler;
@@ -338,36 +368,32 @@ void unreg_handler()
int add_menu(const char *title) // Create a new menu and return its position
{
- t_menu *m;
-
- if (menusystem.nummenus >= MAXMENUS)
- return -1;
-
- m = &menusystem.menus[(unsigned int)menusystem.nummenus];
-
- m->numitems = 0;
- if (title) {
- if (strlen(title) > MENULEN - 2) {
- strcpy(m->title," TITLE TOO LONG ");
- } else {
- strcpy(m->title,title);
- }
- } else {
- strcpy(m->title,"");
- }
-
- m->menuwidth = strlen(m->title);
-
- return menusystem.nummenus++;
+ char num = menusystem.nummenus;
+ t_menu *m;
+
+ if (num >= MAXMENUS) return -1;
+ m = &(menusystem.menus[(int)num]);
+ m->numitems = 0;
+ if (title)
+ {
+ if (strlen(title) > MENULEN - 2)
+ strcpy(m->title," TITLE TOO LONG ");
+ else strcpy(m->title,title);
+ }
+ else strcpy(m->title,"");
+ m ->menuwidth = strlen(m->title);
+ menusystem.nummenus += 1;
+ return menusystem.nummenus - 1;
}
+
t_menuitem * add_item(const char *item, const char *status, t_action action, const char *data, char itemdata) // Add item to the "current" menu
{
t_menuitem *mi;
t_menu *m;
m = &(menusystem.menus[menusystem.nummenus-1]);
- mi = &(m->items[m->numitems]);
+ mi = &(m->items[(int)m->numitems]);
mi->handler = NULL; // No handler
if (item) {
if (strlen(item) > MENULEN - 2) {
diff --git a/menu/menu.h b/menu/menu.h
index cf41173a..1de36ec8 100644
--- a/menu/menu.h
+++ b/menu/menu.h
@@ -10,6 +10,12 @@
*
* ----------------------------------------------------------------------- */
+/* This program can be compiled for DOS with the OpenWatcom compiler
+ * (http://www.openwatcom.org/):
+ *
+ * wcl -3 -osx -mt <filename>.c
+ */
+
#ifndef __MENU_H__
#define __MENU_H__
@@ -32,25 +38,6 @@
#define SPACEKEY 57 // Scan code for SPACE
// Attributes
-#if 0
-/* Original black/white with blink */
-
-#define NORMALATTR 0x70
-#define REVERSEATTR 0x87
-#define INACTATTR 0x74
-#define REVINACTATTR 0x87
-#define STATUSATTR 0xF0
-#define FILLCHAR 178
-#define FILLATTR 0x07
-#define SHADOWATTR 0x08
-#define SPACECHAR ' '
-
-#define TFILLCHAR ' '
-#define TITLEATTR 0x70
-
-#else
-/* Alternate color scheme */
-
#define NORMALATTR 0x17
#define REVERSEATTR 0x70
#define INACTATTR 0x18
@@ -64,8 +51,6 @@
#define TFILLCHAR ' '
#define TITLEATTR 0x70
-#endif
-
#define TITLESTR "COMBOOT Menu System for SYSLINUX developed by Murali Krishnan Ganapathy"
// Single line Box drawing Chars
@@ -79,7 +64,6 @@
#define LEFT 179
#define RIGHT 179
-
// Double line Box Drawing Chars
/*
#define TOPLEFT 201
@@ -103,11 +87,11 @@
#define MENUROW 3 // Row where menu is displayed
#define MENUCOL 4 // Col where menu is displayed
#define MENUPAGE 1 // show in display page 1
-#define STATLINE 24 // Line number where status line starts
+#define STATLINE 23 // Line number where status line starts
// Other Chars
#define SUBMENUCHAR 175 // This is >> symbol, << is 174
-#define CHECKED 251 // Checkmark
+#define CHECKED 251 // Check mark
#define UNCHECKED 250 // Light bullet
typedef enum {OPT_INACTIVE, OPT_SUBMENU, OPT_RUN, OPT_EXITMENU, OPT_CHECKBOX, OPT_RADIOBTN, OPT_EXIT} t_action;
@@ -128,21 +112,21 @@ typedef void (*t_menusystem_handler)(struct s_menusystem *, struct s_menuitem *)
typedef struct s_menuitem {
char item[MENULEN+2];
char status[STATLEN+2];
+ char data[ACTIONLEN+2];
+ void * extra_data; // Any other data user can point to
+ t_item_handler handler; // Pointer to function of type menufn
char active; // Is this item active or not
t_action action;
- char data[ACTIONLEN+2];
t_itemdata itemdata; // Data depends on action value
char index; // Index within the menu array
char parindex; // Index of the menu in which this item appears.
- void * extra_data; // Any other data user can point to
- t_item_handler handler; // Pointer to function of type menufn
} t_menuitem;
typedef struct s_menu {
+ t_menuitem items[MAXMENUSIZE];
+ char title[MENULEN+2];
char numitems;
char menuwidth;
- char title[MENULEN+2];
- t_menuitem items[MAXMENUSIZE];
} t_menu;
typedef struct s_menusystem {
@@ -163,6 +147,8 @@ typedef struct s_menusystem {
char shadowattr;
char statline;
char menupage;
+ char maxrow,minrow,numrows; // Number of rows in the current text mode
+ char maxcol,mincol,numcols; // Number of columns in the current text mode
} t_menusystem;
// User callable Functions
@@ -179,6 +165,8 @@ void set_title_info(char tfillchar, char titleattr);
void set_misc_info(char fillchar, char fillattr,char spacechar, char shadowattr);
+void set_window_size(char top, char left, char bot, char right); // Set the window which menusystem should use
+
void reg_handler( t_menusystem_handler handler); // Register handler
void unreg_handler();
diff --git a/menu/simple.c b/menu/simple.c
index 2d26af86..aeaa6b73 100644
--- a/menu/simple.c
+++ b/menu/simple.c
@@ -26,8 +26,12 @@ int menumain(char *cmdline)
char TESTING,RESCUE,MAIN; /* The menus we're going to declare */
(void)cmdline; /* Not used */
+ // Change the video mode here
+ // setvideomode(0)
+
// Choose the default title and setup default values for all attributes....
init_menusystem(NULL);
+ set_window_size(1,1,23,78); // Leave one row/col border all around
// Choose the default values for all attributes and char's
// -1 means choose defaults (Actually the next 4 lines are not needed)