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

📄 menu.c

📁 linux内核
💻 C
📖 第 1 页 / 共 2 页
字号:
    case KEY_ENTER:    case KEY_CTRL('J'):      return cmdline;    case KEY_ESC:    case KEY_CTRL('C'):      return NULL;    case KEY_BACKSPACE:    case KEY_DEL:      if ( cursor ) {	memmove(cmdline+cursor-1, cmdline+cursor, len-cursor+1);	len--;	cursor--;	redraw = 1;      }      break;    case KEY_CTRL('D'):	    case KEY_DELETE:      if ( cursor < len ) {	memmove(cmdline+cursor, cmdline+cursor+1, len-cursor);	len--;	redraw = 1;      }      break;    case KEY_CTRL('U'):      if ( len ) {	len = cursor = 0;	cmdline[len] = '\0';	redraw = 1;      }      break;    case KEY_CTRL('W'):      if ( cursor ) {	int prevcursor = cursor;	while ( cursor && (cmdline[cursor-1] <= ' ') )	  cursor--;	while ( cursor && (cmdline[cursor-1] > ' ') )	  cursor--;	memmove(cmdline+cursor, cmdline+prevcursor, len-prevcursor+1);	len -= (cursor-prevcursor);	redraw = 1;      }      break;    case KEY_LEFT:    case KEY_CTRL('B'):      if ( cursor ) {	cursor--;	redraw = 1;      }      break;    case KEY_RIGHT:    case KEY_CTRL('F'):      if ( cursor < len ) {	putchar(cmdline[cursor++]);      }      break;    case KEY_CTRL('K'):      if ( cursor < len ) {	cmdline[len = cursor] = '\0';	redraw = 1;      }      break;    case KEY_HOME:    case KEY_CTRL('A'):      if ( cursor ) {	cursor = 0;	redraw = 1;      }      break;    case KEY_END:    case KEY_CTRL('E'):      if ( cursor != len ) {	cursor = len;	redraw = 1;      }      break;    default:      if ( key >= ' ' && key <= 0xFF && len < MAX_CMDLINE_LEN-1 ) {	if ( cursor == len ) {	  cmdline[len] = key;	  cmdline[++len] = '\0';	  cursor++;	  putchar(key);	  prev_len++;	} else {	  memmove(cmdline+cursor+1, cmdline+cursor, len-cursor+1);	  cmdline[cursor++] = key;	  len++;	  redraw = 1;	}      }      break;    }  }}static voidclear_screen(void){  printf("\033e\033%%@\033)0\033(B%s\033[?25l\033[2J", menu_attrib->screen);}static const char *run_menu(void){  int key;  int done = 0;  volatile int entry = defentry, prev_entry = -1;  int top = 0, prev_top = -1;  int clear = 1, to_clear;  const char *cmdline = NULL;  volatile clock_t key_timeout, timeout_left, this_timeout;  /* Note: for both key_timeout and timeout == 0 means no limit */  timeout_left = key_timeout = timeout;  /* Handle both local and global timeout */  if ( setjmp(timeout_jump) ) {    entry = defentry;    if ( top < 0 || top < entry-MENU_ROWS+1 )      top = max(0, entry-MENU_ROWS+1);    else if ( top > entry || top > max(0,nentries-MENU_ROWS) )      top = min(entry, max(0,nentries-MENU_ROWS));    draw_menu(ontimeout ? -1 : entry, top, 1);    cmdline = ontimeout ? ontimeout : menu_entries[entry].cmdline;    done = 1;  }  while ( !done ) {    if ( entry < 0 )      entry = 0;    else if ( entry >= nentries )      entry = nentries-1;    if ( top < 0 || top < entry-MENU_ROWS+1 )      top = max(0, entry-MENU_ROWS+1);    else if ( top > entry || top > max(0,nentries-MENU_ROWS) )      top = min(entry, max(0,nentries-MENU_ROWS));    /* Start with a clear screen */    if ( clear ) {      /* Clear and redraw whole screen */      /* Enable ASCII on G0 and DEC VT on G1; do it in this order	 to avoid confusing the Linux console */      clear_screen();      clear = 0;      prev_entry = prev_top = -1;    }    if ( top != prev_top ) {      draw_menu(entry, top, 1);    } else if ( entry != prev_entry ) {      draw_row(prev_entry-top+4, entry, top, 0, 0);      draw_row(entry-top+4, entry, top, 0, 0);    }    prev_entry = entry;  prev_top = top;    /* Cursor movement cancels timeout */    if ( entry != defentry )      key_timeout = 0;    if ( key_timeout ) {      int tol = timeout_left/CLK_TCK;      int nc = snprintf(NULL, 0, " Automatic boot in %d seconds ", tol);      printf("\033[%d;%dH%s Automatic boot in %s%d%s seconds ",	     TIMEOUT_ROW, 1+((WIDTH-nc)>>1),	     menu_attrib->timeout_msg,	     menu_attrib->timeout, tol,	     menu_attrib->timeout_msg);      to_clear = 1;    } else {      to_clear = 0;    }    this_timeout = min(min(key_timeout, timeout_left), CLK_TCK);    key = mygetkey(this_timeout);    if ( key != KEY_NONE ) {      timeout_left = key_timeout;      if ( to_clear )	printf("\033[%d;1H%s\033[K", TIMEOUT_ROW, menu_attrib->screen);    }    switch ( key ) {    case KEY_NONE:		/* Timeout */      /* This is somewhat hacky, but this at least lets the user	 know what's going on, and still deals with "phantom inputs"	 e.g. on serial ports.	 Warning: a timeout will boot the default entry without any	 password! */      if ( key_timeout ) {	if ( timeout_left <= this_timeout )	  longjmp(timeout_jump, 1);		timeout_left -= this_timeout;      }      break;    case KEY_CTRL('L'):      clear = 1;      break;    case KEY_ENTER:    case KEY_CTRL('J'):      key_timeout = 0;		/* Cancels timeout */      if ( menu_entries[entry].passwd ) {	clear = 1;	done = ask_passwd(menu_entries[entry].passwd);      } else {	done = 1;      }      cmdline = menu_entries[entry].cmdline;      break;    case KEY_UP:    case KEY_CTRL('P'):      if ( entry > 0 ) {	entry--;	if ( entry < top )	  top -= MENU_ROWS;      }      break;    case KEY_DOWN:    case KEY_CTRL('N'):      if ( entry < nentries-1 ) {	entry++;	if ( entry >= top+MENU_ROWS )	  top += MENU_ROWS;      }      break;    case KEY_PGUP:    case KEY_LEFT:    case KEY_CTRL('B'):    case '<':      entry -= MENU_ROWS;      top   -= MENU_ROWS;      break;    case KEY_PGDN:    case KEY_RIGHT:    case KEY_CTRL('F'):    case '>':    case ' ':      entry += MENU_ROWS;      top   += MENU_ROWS;      break;    case '-':      entry--;      top--;      break;    case '+':      entry++;      top++;      break;    case KEY_CTRL('A'):    case KEY_HOME:      top = entry = 0;      break;    case KEY_CTRL('E'):    case KEY_END:      entry = nentries - 1;      top = max(0, nentries-MENU_ROWS);      break;    case KEY_TAB:      if ( allowedit ) {	int ok = 1;	key_timeout = 0;	/* Cancels timeout */	draw_row(entry-top+4, -1, top, 0, 0);	if ( menu_master_passwd ) {	  ok = ask_passwd(NULL);	  clear_screen();	  draw_menu(-1, top, 0);	} else {	  /* Erase [Tab] message */	  printf("\033[%d;1H%s\033[K", TABMSG_ROW, menu_attrib->screen);	}		if ( ok ) {	  cmdline = edit_cmdline(menu_entries[entry].cmdline, top);	  done = !!cmdline;	  clear = 1;		/* In case we hit [Esc] and done is null */	} else {	  draw_row(entry-top+4, entry, top, 0, 0);	}      }      break;    case KEY_CTRL('C'):		/* Ctrl-C */    case KEY_ESC:		/* Esc */      if ( allowedit ) {	done = 1;	clear = 1;	key_timeout = 0;		draw_row(entry-top+4, -1, top, 0, 0);	if ( menu_master_passwd )	  done = ask_passwd(NULL);      }      break;    default:      if ( key > 0 && key < 0xFF ) {	key &= ~0x20;		/* Upper case */	if ( menu_hotkeys[key] ) {	  key_timeout = 0;	  entry = menu_hotkeys[key] - menu_entries;	  /* Should we commit at this point? */	}      }      break;    }  }  printf("\033[?25h");		/* Show cursor */  /* Return the label name so localboot and ipappend work */  return cmdline;}static voidexecute(const char *cmdline){#ifdef __COM32__  com32sys_t ireg;  const char *p;  char *q = __com32.cs_bounce;  const char *kernel, *args;  memset(&ireg, 0, sizeof ireg);  kernel = q;  p = cmdline;  while ( *p && !isspace(*p) ) {    *q++ = *p++;  }  *q++ = '\0';    args = q;  while ( *p && isspace(*p) )    p++;    strcpy(q, p);  if ( !strcmp(kernel, ".localboot") ) {    ireg.eax.w[0] = 0x0014;	/* Local boot */    ireg.edx.w[0] = strtoul(args, NULL, 0);  } else {    ireg.eax.w[0] = 0x0016;	/* Run kernel image */    ireg.esi.w[0] = OFFS(kernel);    ireg.ds       = SEG(kernel);    ireg.ebx.w[0] = OFFS(args);    ireg.es       = SEG(args);    /* ireg.ecx.l    = 0; */		/* We do ipappend "manually" */    /* ireg.edx.l    = 0; */  }  __intcall(0x22, &ireg, NULL);  /* If this returns, something went bad; return to menu */#else  /* For testing... */  printf("\n\033[0m>>> %s\n", cmdline);  exit(0);#endif}int main(int argc, char *argv[]){  const char *cmdline;  (void)argc;  console_ansi_raw();  parse_config(argv[1]);  if ( !nentries ) {    fputs("No LABEL entries found in configuration file!\n", stdout);    return 1;			/* Error! */  }  for(;;) {    cmdline = run_menu();    printf("\033[?25h\033[%d;1H\033[0m", END_ROW);    if ( cmdline )      execute(cmdline);    else      return 0;			/* Exit */  }}

⌨️ 快捷键说明

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