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

📄 menu.c

📁 linux内核
💻 C
📖 第 1 页 / 共 3 页
字号:
/* -*- 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 "menu.h"#include <stdlib.h>// Local Variablesstatic pt_menusystem ms; // Pointer to the menusystemchar TITLESTR[] = "COMBOOT Menu System for SYSLINUX developed by Murali Krishnan Ganapathy";char TITLELONG[] = " TITLE too long ";char ITEMLONG[] = " ITEM too long ";char ACTIONLONG[] = " ACTION too long ";char STATUSLONG[] = " STATUS too long ";char EMPTYSTR[] = "";/* Forward declarations */int calc_visible(pt_menu menu,int first);int next_visible(pt_menu menu,int index); int prev_visible(pt_menu menu,int index); int next_visible_sep(pt_menu menu,int index); int prev_visible_sep(pt_menu menu,int index); int calc_first_early(pt_menu menu,int curr);int calc_first_late(pt_menu menu,int curr);int isvisible(pt_menu menu,int first, int curr);/* 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,uchar* attr){    uchar page = getdisppage();    uchar 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++;    }}int find_shortcut(pt_menu menu,uchar 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}// print the menu starting from FIRST// will print a maximum of menu->menuheight itemsvoid printmenu(pt_menu menu, int curr, uchar top, uchar left, uchar first){  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  uchar *attr;  // attribute attr  char sep[MENULEN];// and inbetween the item or a seperator is printed  pt_menuitem ci;    numitems = calc_visible(menu,first);  if (numitems > menu->menuheight) numitems = menu->menuheight;  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->menupage,ms->normalattr[NOHLITE],ms->menubt);  memset(sep,ms->box_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=first; x < menu->numitems; x++)    {      ci = menu->items[x];      if (ci->action == OPT_INVISIBLE) continue;      row++;      if (row >= numitems) break; // Already have enough number of items      // 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] = ms->box_ltrt; fchar[2] = ms->box_horiz; fchar[3] = ms->box_horiz; fchar[4] = 0;	  lchar[0] = ms->box_horiz; lchar[1] = ms->box_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    }  // Check if we need to MOREABOVE and MOREBELOW to be added  // reuse x   row = 0;  x = next_visible_sep(menu,0); // First item  if (! isvisible(menu,first,x)) // There is more above  {     row = 1;     gotoxy(top,left+menuwidth,ms->menupage);     cprint(MOREABOVE,ms->normalattr[NOHLITE],1,ms->menupage);  }  x = prev_visible_sep(menu,menu->numitems); // last item  if (! isvisible(menu,first,x)) // There is more above  {     row = 1;     gotoxy(top+numitems-1,left+menuwidth,ms->menupage);     cprint(MOREBELOW,ms->normalattr[NOHLITE],1,ms->menupage);  }  // Add a scroll box  x = ((numitems-1)*curr)/(menu->numitems);  if ((x>0) && (row==1)) {  gotoxy(top+x,left+menuwidth,ms->menupage);  cprint(SCROLLBOX,ms->normalattr[NOHLITE],1,ms->menupage);  }  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, uchar top, uchar left, int first){  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  uchar *attr;  // all in the attribute attr  char sep[MENULEN];// and inbetween the item or a seperator is printed  pt_menuitem ci;    numitems = calc_visible(menu,first);  if (numitems > menu->menuheight) numitems = menu->menuheight;  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->menupage,ms->normalattr[NOHLITE],ms->menubt);  memset(sep,ms->box_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=first; x < menu->numitems; x++)    {      ci = menu->items[x];      if (ci->action == OPT_INVISIBLE) continue;      row++;      if (row > numitems) break;      // 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] = ms->box_ltrt; fchar[2] = ms->box_horiz; fchar[3] = ms->box_horiz; fchar[4] = 0;	  lchar[0] = ms->box_horiz; lchar[1] = ms->box_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    }  // Check if we need to MOREABOVE and MOREBELOW to be added  // reuse x   row = 0;  x = next_visible_sep(menu,0); // First item  if (! isvisible(menu,first,x)) // There is more above  {     row = 1;     gotoxy(top,left+menuwidth,ms->menupage);     cprint(MOREABOVE,ms->normalattr[NOHLITE],1,ms->menupage);  }  x = prev_visible_sep(menu,menu->numitems); // last item  if (! isvisible(menu,first,x)) // There is more above  {     row = 1;     gotoxy(top+numitems-1,left+menuwidth,ms->menupage);     cprint(MOREBELOW,ms->normalattr[NOHLITE],1,ms->menupage);  }  // Add a scroll box  x = ((numitems-1)*curr)/(menu->numitems);  if ((x > 0) && (row == 1))  {     gotoxy(top+x,left+menuwidth,ms->menupage);     cprint(SCROLLBOX,ms->normalattr[NOHLITE],1,ms->menupage);  }  if (ms->handler) ms->handler(ms,menu->items[curr]);}void cleanupmenu(pt_menu menu, uchar top,uchar left,int numitems){  if (numitems > menu->menuheight) numitems = menu->menuheight;  clearwindow(top,left-2, top+numitems+1, left+menu->menuwidth+4,	      ms->menupage, ms->fillchar, ms->fillattr); // Clear the shadow  clearwindow(top-1, left-3, top+numitems, left+menu->menuwidth+3,	      ms->menupage, ms->fillchar, ms->fillattr); // main window}/* Handle a radio menu */pt_menuitem getradiooption(pt_menu menu, uchar top, uchar left, uchar startopt)     // Return item chosen or NULL if ESC was hit.{  int curr,i,first,tmp;  uchar asc,scan;  uchar numitems;  pt_menuitem ci; // Current item      numitems = calc_visible(menu,0);  // 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);  first = calc_first_early(menu,curr);  while (1) // Forever    {      printradiomenu(menu,curr,top,left,first);      ci = menu->items[curr];            asc = getch(&scan);      switch (scan)        {	case HOMEKEY:	  curr = next_visible(menu,0);          first = calc_first_early(menu,curr);	  break;	case ENDKEY:	  curr = prev_visible(menu,numitems-1);          first = calc_first_late(menu,curr);

⌨️ 快捷键说明

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