⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 menu.c

📁 Windows上的精简Linux系统
💻 C
📖 第 1 页 / 共 2 页
字号:
/* -*- 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"#include "heap.h"// Local Variablesstatic pt_menusystem ms; // Pointer to the menusystemstatic char TITLESTR[] = "COMBOOT Menu System for SYSLINUX developed by Murali Krishnan Ganapathy";static char TITLELONG[] = " TITLE too long ";static char ITEMLONG[] = " ITEM too long ";static char ACTIONLONG[] = " ACTION too long ";static char STATUSLONG[] = " STATUS too long ";static char EMPTYSTR[] = "";/* Basic Menu routines */// This is same as inputc except it honors the ontimeout handler// and calls it when needed. For the callee, there is no difference// as this will not return unless a key has been pressed.char getch(char *scan){  unsigned long i;  TIMEOUTCODE c;  // Wait until keypress if no handler specified  if (ms->ontimeout==NULL) return inputc(scan);  while (1) // Forever do    {      for (i=0; i < ms->tm_numsteps; i++)	{	  if (checkkbdbuf()) return inputc(scan);	  sleep(ms->tm_stepsize);	}      c = ms->ontimeout();      switch(c)	{	case CODE_ENTER: // Pretend user hit enter	  *scan = ENTERA;	  return '\015'; // \015 octal = 13	case CODE_ESCAPE: // Pretend user hit escape	  *scan = ESCAPE;	  return '\033'; // \033 octal = 27	default:	  break;	}    }  return 0;}/* Print a menu item *//* attr[0] is non-hilite attr, attr[1] is highlight attr */void printmenuitem(const char *str,char* attr){    char page = getdisppage();    char row,col;    int hlite=NOHLITE; // Initially no highlighting    getpos(&row,&col,page);    while ( *str ) {      switch (*str) 	{	case '\b':	  --col;	  break;	case '\n':	  ++row;	  break;	case '\r':	  col=0;	  break;	case BELL: // No Bell Char	  break;	case ENABLEHLITE: // Switch on highlighting	  hlite = HLITE;	  break;	case DISABLEHLITE: // Turn off highlighting	  hlite = NOHLITE;	  break;	default:	  putch(*str, attr[hlite], page);	  ++col;	}      if (col > getnumcols())	{	  ++row;	  col=0;	}      if (row > getnumrows())	{	  scrollup();	  row= getnumrows();	}      gotoxy(row,col,page);      str++;    }}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);    }}int next_visible(pt_menu menu, int index) // Return index of next visible{  int ans;  if (index < 0) ans = 0 ;  else if (index >= menu->numitems) ans = menu->numitems-1;  else ans = index;  while ((ans < menu->numitems-1) && 	 ((menu->items[ans]->action == OPT_INVISIBLE) || 	  (menu->items[ans]->action == OPT_SEP)))     ans++;  return ans;}int prev_visible(pt_menu menu, int index) // Return index of next visible{  int ans;  if (index < 0) ans = 0;  else if (index >= menu->numitems) ans = menu->numitems-1;  else ans = index;  while ((ans > 0) && 	 ((menu->items[ans]->action == OPT_INVISIBLE) ||	  (menu->items[ans]->action == OPT_SEP)))     ans--;  return ans;}int find_shortcut(pt_menu menu,char shortcut, int index) // Find the next index with specified shortcut key{  int ans;  pt_menuitem mi;  // Garbage in garbage out  if ((index <0) || (index >= menu->numitems)) return index;   ans = index+1;  // Go till end of menu  while (ans < menu->numitems)	     {      mi = menu->items[ans];      if ((mi->action == OPT_INVISIBLE) || (mi->action == OPT_SEP)	  || (mi->shortcut != shortcut))	ans ++;      else return ans;    }  // Start at the beginning and try again  ans = 0;  while (ans < index)    {      mi = menu->items[ans];      if ((mi->action == OPT_INVISIBLE) || (mi->action == OPT_SEP)	  || (mi->shortcut != shortcut))	ans ++;      else return ans;    }  return index; // Sorry not found}void printmenu(pt_menu menu, int curr, char top, char left){  int x,row; // x = index, row = position from top  int numitems,menuwidth;  char fchar[5],lchar[5]; // The first and last char in for each entry  const char *str;  // and inbetween the item or a seperator is printed  char *attr;  // attribute attr  char sep[MENULEN];// and inbetween the item or a seperator is printed  pt_menuitem ci;    calc_visible(menu);  numitems = menu->numvisible;  menuwidth = menu->menuwidth+3;  clearwindow(top,left-2, top+numitems+1, left+menuwidth+1,	      ms->menupage, ms->fillchar, ms->shadowattr);  drawbox(top-1, left-3, top+numitems, left+menuwidth, 	  ms->normalattr[NOHLITE], ms->menupage);  memset(sep,HORIZ,menuwidth); // String containing the seperator string  sep[menuwidth-1] = 0;   // Menu title  x = (menuwidth - strlen(menu->title) - 1) >> 1;  gotoxy(top-1,left+x,ms->menupage);  printmenuitem(menu->title,ms->normalattr);  row = -1; // 1 less than inital value of x  for (x=0; x < menu->numitems; x++)    {      ci = menu->items[x];      if (ci->action == OPT_INVISIBLE) continue;      row++;      // Setup the defaults now      lchar[0] = fchar[0] = ' ';       lchar[1] = fchar[1] = '\0'; // fchar and lchar are just spaces      str = ci->item; // Pointer to item string      attr = (x==curr ? ms->reverseattr : ms->normalattr); // Normal attributes      switch (ci->action) // set up attr,str,fchar,lchar for everything        {	case OPT_INACTIVE:	  attr = (x==curr? ms->revinactattr : ms->inactattr);	  break;	case OPT_SUBMENU:	  lchar[0] = SUBMENUCHAR; lchar[1] = 0;	  break;	case OPT_RADIOMENU:	  lchar[0] = RADIOMENUCHAR; lchar[1] = 0;	  break;	case OPT_CHECKBOX:	  lchar[0] = (ci->itemdata.checked ? CHECKED : UNCHECKED);	  lchar[1] = 0;	  break;	case OPT_SEP:	  fchar[0] = '\b'; fchar[1] = LTRT; fchar[2] = HORIZ; fchar[3] = HORIZ; fchar[4] = 0;	  lchar[0] = HORIZ; lchar[1] = RTLT; lchar[2] = 0;	  str = sep;	  break;	case OPT_EXITMENU:	  fchar[0] = EXITMENUCHAR; fchar[1] = 0;	  break;	default: // Just to keep the compiler happy	  break;        }      gotoxy(top+row,left-2,ms->menupage);      cprint(ms->spacechar,attr[NOHLITE],menuwidth+2,ms->menupage); // Wipe area with spaces      gotoxy(top+row,left-2,ms->menupage);      csprint(fchar,attr[NOHLITE]); // Print first part      gotoxy(top+row,left,ms->menupage);      printmenuitem(str,attr); // Print main part      gotoxy(top+row,left+menuwidth-1,ms->menupage); // Last char if any      csprint(lchar,attr[NOHLITE]); // Print last part    }  if (ms->handler) ms->handler(ms,menu->items[curr]);}// Difference between this and regular menu, is that only // OPT_INVISIBLE, OPT_SEP are honoured void printradiomenu(pt_menu menu, int curr, char top, char left){  int x,row; // x = index, row = position from top  int numitems,menuwidth;  char fchar[5],lchar[5]; // The first and last char in for each entry  const char *str;  // and inbetween the item or a seperator is printed  char *attr;  // all in the attribute attr  char sep[MENULEN];// and inbetween the item or a seperator is printed  pt_menuitem ci;    calc_visible(menu);  numitems = menu->numvisible;  menuwidth = menu->menuwidth+3;  clearwindow(top,left-2, top+numitems+1, left+menuwidth+1,	      ms->menupage, ms->fillchar, ms->shadowattr);  drawbox(top-1, left-3, top+numitems, left+menuwidth, 	  ms->normalattr[NOHLITE], ms->menupage);  memset(sep,HORIZ,menuwidth); // String containing the seperator string  sep[menuwidth-1] = 0;   // Menu title  x = (menuwidth - strlen(menu->title) - 1) >> 1;  gotoxy(top-1,left+x,ms->menupage);  printmenuitem(menu->title,ms->normalattr);  row = -1; // 1 less than inital value of x  for (x=0; x < menu->numitems; x++)    {      ci = menu->items[x];      if (ci->action == OPT_INVISIBLE) continue;      row++;      // Setup the defaults now      fchar[0] = RADIOUNSEL; fchar[1]='\0'; // Unselected ( )      lchar[0] = '\0'; // Nothing special after       str = ci->item; // Pointer to item string      attr = ms->normalattr; // Always same attribute      fchar[0] = (x==curr ? RADIOSEL : RADIOUNSEL);       switch (ci->action) // set up attr,str,fchar,lchar for everything        {	case OPT_INACTIVE:	  attr = ms->inactattr;	  break;	case OPT_SEP:	  fchar[0] = '\b'; fchar[1] = LTRT; fchar[2] = HORIZ; fchar[3] = HORIZ; fchar[4] = 0;	  lchar[0] = HORIZ; lchar[1] = RTLT; lchar[3] = 0;	  str = sep;	  break;	default: // To keep the compiler happy	  break;        }      gotoxy(top+row,left-2,ms->menupage);      cprint(ms->spacechar,attr[NOHLITE],menuwidth+2,ms->menupage); // Wipe area with spaces      gotoxy(top+row,left-2,ms->menupage);      csprint(fchar,attr[NOHLITE]); // Print first part      gotoxy(top+row,left,ms->menupage);      printmenuitem(str,attr); // Print main part      gotoxy(top+row,left+menuwidth-1,ms->menupage); // Last char if any      csprint(lchar,attr[NOHLITE]); // Print last part    }  if (ms->handler) ms->handler(ms,menu->items[curr]);}void cleanupmenu(pt_menu menu, char top,char left){  clearwindow(top,left-2, top+menu->numvisible+1, left+menu->menuwidth+4,	      ms->menupage, ms->fillchar, ms->fillattr); // Clear the shadow  clearwindow(top-1, left-3, top+menu->numvisible, left+menu->menuwidth+3,	      ms->menupage, ms->fillchar, ms->fillattr); // main window}/* Handle a radio menu */pt_menuitem getradiooption(pt_menu menu, char top, char left, char startopt)     // Return item chosen or NULL if ESC was hit.{  int curr,i;  char asc,scan;  char numitems;  pt_menuitem ci; // Current item      calc_visible(menu);  numitems = menu->numvisible;  // Setup status line  gotoxy(ms->minrow+ms->statline,ms->mincol,ms->menupage);  cprint(ms->spacechar,ms->statusattr[NOHLITE],ms->numcols,ms->menupage);  // Initialise current menu item  curr = next_visible(menu,startopt);  gotoxy(ms->minrow+ms->statline,ms->mincol,ms->menupage);  cprint(ms->spacechar,ms->statusattr[NOHLITE],ms->numcols,1);  gotoxy(ms->minrow+ms->statline,ms->mincol,ms->menupage);  printmenuitem(menu->items[curr]->status,ms->statusattr);  while (1) // Forever    {      printradiomenu(menu,curr,top,left);      ci = menu->items[curr];            asc = getch(&scan);      switch (scan)        {	case HOMEKEY:	  curr = next_visible(menu,0);	  break;	case ENDKEY:	  curr = prev_visible(menu,numitems-1);	  break;	case PAGEDN:	  for (i=0; i < 5; i++) curr = next_visible(menu,curr+1);	  break;	case PAGEUP:	  for (i=0; i < 5; i++) curr = prev_visible(menu,curr-1);	  break;	case UPARROW:	  curr = prev_visible(menu,curr-1);	  break;	case DNARROW:	  curr = next_visible(menu,curr+1);	  break;	case LTARROW:	case ESCAPE:	  return NULL;	  break;	case RTARROW:	case ENTERA:	case ENTERB:	  if (ci->action == OPT_INACTIVE) break;	  if (ci->action == OPT_SEP) break;	  return ci;	  break;	default:	  // Check if this is a shortcut key	  if (((asc >= 'A') && (asc <= 'Z')) ||	      ((asc >= 'a') && (asc <= 'z')) ||	      ((asc >= '0') && (asc <= '9')))	    curr = find_shortcut(menu,asc,curr);	  break;        }      // Update status line      gotoxy(ms->minrow+ms->statline,ms->mincol,ms->menupage);      cprint(ms->spacechar,ms->statusattr[NOHLITE],ms->numcols,ms->menupage);      printmenuitem(menu->items[curr]->status,ms->statusattr);    }  return NULL; // Should never come here}/* Handle one menu */pt_menuitem getmenuoption( pt_menu menu, char top, char left, char startopt)     // Return item chosen or NULL if ESC was hit.{  int curr,i;  char asc,scan;  char numitems;  pt_menuitem ci; // Current item      calc_visible(menu);  numitems = menu->numvisible;  // Setup status line  gotoxy(ms->minrow+ms->statline,ms->mincol,ms->menupage);  cprint(ms->spacechar,ms->statusattr[NOHLITE],ms->numcols,ms->menupage);  // Initialise current menu item      curr = next_visible(menu,startopt);  gotoxy(ms->minrow+ms->statline,ms->mincol,ms->menupage);  cprint(ms->spacechar,ms->statusattr[NOHLITE],ms->numcols,1);  gotoxy(ms->minrow+ms->statline,ms->mincol,ms->menupage);  printmenuitem(menu->items[curr]->status,ms->statusattr);  while (1) // Forever    {      printmenu(menu,curr,top,left);      ci = menu->items[curr];      asc = getch(&scan);      switch (scan)        {	case HOMEKEY:	  curr = next_visible(menu,0);	  break;	case ENDKEY:	  curr = prev_visible(menu,numitems-1);	  break;	case PAGEDN:	  for (i=0; i < 5; i++) curr = next_visible(menu,curr+1);	  break;	case PAGEUP:	  for (i=0; i < 5; i++) curr = prev_visible(menu,curr-1);	  break;	case UPARROW:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -