static char * grub_getline (void) { int i; char *line; char *tmp; char c; i = 0; line = grub_malloc (1 + i + sizeof('\0')); if (! line) return NULL; while (1) { c = grub_getkey (); if ((c == '\n') || (c == '\r')) break; line[i] = c; if (grub_isprint (c)) grub_putchar (c); i++; tmp = grub_realloc (line, 1 + i + sizeof('\0')); if (! tmp) { grub_free (line); return NULL; } line = tmp; } line[i] = '\0'; return line; }
/* Wait until the user pushes any key so that the user can see what happened. */ void grub_wait_after_message (void) { grub_putchar ('\n'); grub_printf_ (N_("Press any key to continue...")); (void) grub_getkey (); grub_putchar ('\n'); }
static grub_err_t grub_cmd_cat (grub_extcmd_context_t ctxt, int argc, char **args) { struct grub_arg_list *state = ctxt->state; int dos = 0; grub_file_t file; char buf[GRUB_DISK_SECTOR_SIZE]; grub_ssize_t size; int key = 0; if (state[0].set) dos = 1; if (argc != 1) return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required"); file = grub_file_open (args[0]); if (! file) return grub_errno; while ((size = grub_file_read (file, buf, sizeof (buf))) > 0 && key != GRUB_TERM_ESC) { int i; for (i = 0; i < size; i++) { unsigned char c = buf[i]; if ((grub_isprint (c) || grub_isspace (c)) && c != '\r') grub_printf ("%c", c); else if (dos && c == '\r' && i + 1 < size && buf[i + 1] == '\n') { grub_printf ("\n"); i++; } else { grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT); grub_printf ("<%x>", (int) c); grub_setcolorstate (GRUB_TERM_COLOR_STANDARD); } } while (grub_checkkey () >= 0 && (key = grub_getkey ()) != GRUB_TERM_ESC) ; } grub_xputs ("\n"); grub_refresh (); grub_file_close (file); return 0; }
/* Based on grub_millisleep() from kern/generic/millisleep.c. */ static int grub_interruptible_millisleep (grub_uint32_t ms) { grub_uint64_t start; start = grub_get_time_ms (); while (grub_get_time_ms () - start < ms) if (grub_checkkey () >= 0 && grub_getkey () == GRUB_TERM_ESC) return 1; return 0; }
static int grub_check_keyboard (void) { int mods = grub_getkeystatus (); if (mods >= 0 && (mods & GRUB_TERM_STATUS_SHIFT) != 0) return 1; if (grub_checkkey () >= 0 && GRUB_TERM_ASCII_CHAR (grub_getkey ()) == GRUB_TERM_ESC) return 1; return 0; }
/* Prompt to input a command and read the line. */ static grub_err_t grub_rescue_read_line (char **line, int cont) { int c; int pos = 0; char str[4]; grub_printf ((cont) ? "> " : "grub rescue> "); grub_memset (linebuf, 0, GRUB_RESCUE_BUF_SIZE); while ((c = grub_getkey ()) != '\n' && c != '\r') { if (grub_isprint (c)) { if (pos < GRUB_RESCUE_BUF_SIZE - 1) { str[0] = c; str[1] = 0; linebuf[pos++] = c; grub_xputs (str); } } else if (c == '\b') { if (pos > 0) { str[0] = c; str[1] = ' '; str[2] = c; str[3] = 0; linebuf[--pos] = 0; grub_xputs (str); } } grub_refresh (); } grub_xputs ("\n"); grub_refresh (); *line = grub_strdup (linebuf); return 0; }
/* Wait until the user pushes any key so that the user can see what happened. */ void grub_wait_after_message (void) { grub_uint64_t endtime; grub_xputs ("\n"); grub_printf_ (N_("Press any key to continue...")); grub_refresh (); endtime = grub_get_time_ms () + 10000; while (grub_get_time_ms () < endtime) if (grub_checkkey () >= 0) { grub_getkey (); break; } grub_xputs ("\n"); }
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream) { ssize_t read_return; grub_errno = GRUB_ERR_NONE; if (stream == stdout || stream == stderr) { grub_printf("Internal error: Python attempted to fread from stdout or stderr.\n"); return 0; } if (stream == stdin) { size_t i, j; unsigned char *bytes = ptr; for (i = 0; i < nmemb; i++) for (j = 0; j < size; j++) *bytes++ = grub_getkey(); return nmemb; } read_return = grub_file_read(stream, ptr, size * nmemb); if (read_return <= 0) return 0; return read_return / size; }
static PyObject *bits_get_key(PyObject *self, PyObject *args) { return Py_BuildValue("i", grub_getkey()); }
/* Show the menu and handle menu entry selection. Returns the menu entry index that should be executed or -1 if no entry should be executed (e.g., Esc pressed to exit a sub-menu or switching menu viewers). If the return value is not -1, then *AUTO_BOOT is nonzero iff the menu entry to be executed is a result of an automatic default selection because of the timeout. */ static int run_menu (grub_menu_t menu, int nested, int *auto_boot) { grub_uint64_t saved_time; int default_entry, current_entry; int timeout; default_entry = get_entry_number (menu, "default"); /* If DEFAULT_ENTRY is not within the menu entries, fall back to the first entry. */ if (default_entry < 0 || default_entry >= menu->size) default_entry = 0; /* If timeout is 0, drawing is pointless (and ugly). */ if (grub_menu_get_timeout () == 0) { *auto_boot = 1; return default_entry; } current_entry = default_entry; /* Initialize the time. */ saved_time = grub_get_time_ms (); refresh: menu_init (current_entry, menu, nested); timeout = grub_menu_get_timeout (); if (timeout > 0) menu_print_timeout (timeout); else clear_timeout (); while (1) { int c; timeout = grub_menu_get_timeout (); if (grub_normal_exit_level) return -1; if (timeout > 0) { grub_uint64_t current_time; current_time = grub_get_time_ms (); if (current_time - saved_time >= 1000) { timeout--; grub_menu_set_timeout (timeout); saved_time = current_time; menu_print_timeout (timeout); } } if (timeout == 0) { grub_env_unset ("timeout"); *auto_boot = 1; menu_fini (); return default_entry; } if (grub_checkkey () >= 0 || timeout < 0) { c = grub_getkey (); if (timeout >= 0) { grub_env_unset ("timeout"); grub_env_unset ("fallback"); clear_timeout (); } switch (c) { case GRUB_TERM_KEY_HOME: case GRUB_TERM_CTRL | 'a': current_entry = 0; menu_set_chosen_entry (current_entry); break; case GRUB_TERM_KEY_END: case GRUB_TERM_CTRL | 'e': current_entry = menu->size - 1; menu_set_chosen_entry (current_entry); break; case GRUB_TERM_KEY_UP: case GRUB_TERM_CTRL | 'p': case '^': if (current_entry > 0) current_entry--; menu_set_chosen_entry (current_entry); break; case GRUB_TERM_CTRL | 'n': case GRUB_TERM_KEY_DOWN: case 'v': if (current_entry < menu->size - 1) current_entry++; menu_set_chosen_entry (current_entry); break; case GRUB_TERM_CTRL | 'g': case GRUB_TERM_KEY_PPAGE: if (current_entry < GRUB_MENU_PAGE_SIZE) current_entry = 0; else current_entry -= GRUB_MENU_PAGE_SIZE; menu_set_chosen_entry (current_entry); break; case GRUB_TERM_CTRL | 'c': case GRUB_TERM_KEY_NPAGE: if (current_entry + GRUB_MENU_PAGE_SIZE < menu->size) current_entry += GRUB_MENU_PAGE_SIZE; else current_entry = menu->size - 1; menu_set_chosen_entry (current_entry); break; case '\n': case '\r': case GRUB_TERM_KEY_RIGHT: case GRUB_TERM_CTRL | 'f': menu_fini (); *auto_boot = 0; return current_entry; case '\e': if (nested) { menu_fini (); return -1; } break; case 'c': menu_fini (); grub_cmdline_run (1); goto refresh; case 'e': menu_fini (); { grub_menu_entry_t e = grub_menu_get_entry (menu, current_entry); if (e) grub_menu_entry_run (e); } goto refresh; default: { grub_menu_entry_t entry; int i; for (i = 0, entry = menu->entry_list; i < menu->size; i++, entry = entry->next) if (entry->hotkey == c) { menu_fini (); *auto_boot = 0; return i; } } break; } } }
static grub_err_t grub_cmd_videotest (grub_command_t cmd __attribute__ ((unused)), int argc, char **args) { grub_err_t err; grub_video_color_t color; unsigned int x; unsigned int y; unsigned int width; unsigned int height; int i; struct grub_video_render_target *text_layer; grub_video_color_t palette[16]; const char *mode = NULL; #ifdef GRUB_MACHINE_PCBIOS if (grub_strcmp (cmd->name, "vbetest") == 0) grub_dl_load ("vbe"); #endif mode = grub_env_get ("gfxmode"); if (argc) mode = args[0]; if (!mode) mode = "auto"; err = grub_video_set_mode (mode, GRUB_VIDEO_MODE_TYPE_PURE_TEXT, 0); if (err) return err; grub_video_get_viewport (&x, &y, &width, &height); { const char *str; int texty; grub_font_t sansbig; grub_font_t sans; grub_font_t sanssmall; grub_font_t fixed; struct grub_font_glyph *glyph; grub_video_create_render_target (&text_layer, width, height, GRUB_VIDEO_MODE_TYPE_RGB | GRUB_VIDEO_MODE_TYPE_ALPHA); grub_video_set_active_render_target (text_layer); color = grub_video_map_rgb (0, 255, 255); sansbig = grub_font_get ("Unknown Regular 16"); sans = grub_font_get ("Unknown Regular 16"); sanssmall = grub_font_get ("Unknown Regular 16"); fixed = grub_font_get ("Fixed 20"); if (! sansbig || ! sans || ! sanssmall || ! fixed) return grub_error (GRUB_ERR_BAD_FONT, "no font loaded"); glyph = grub_font_get_glyph (fixed, '*'); grub_font_draw_glyph (glyph, color, 200 ,0); color = grub_video_map_rgb (255, 255, 255); texty = 32; grub_font_draw_string ("The quick brown fox jumped over the lazy dog.", sans, color, 16, texty); texty += grub_font_get_descent (sans) + grub_font_get_leading (sans); texty += grub_font_get_ascent (fixed); grub_font_draw_string ("The quick brown fox jumped over the lazy dog.", fixed, color, 16, texty); texty += grub_font_get_descent (fixed) + grub_font_get_leading (fixed); /* To convert Unicode characters into UTF-8 for this test, the following command is useful: echo -ne '\x00\x00\x26\x3A' | iconv -f UTF-32BE -t UTF-8 | od -t x1 This converts the Unicode character U+263A to UTF-8. */ /* Characters used: Code point Description UTF-8 encoding ----------- ------------------------------ -------------- U+263A unfilled smiley face E2 98 BA U+00A1 inverted exclamation point C2 A1 U+00A3 British pound currency symbol C2 A3 U+03C4 Greek tau CF 84 U+00E4 lowercase letter a with umlaut C3 A4 U+2124 set 'Z' symbol (integers) E2 84 A4 U+2287 subset symbol E2 8A 87 U+211D set 'R' symbol (real numbers) E2 84 9D */ str = "Unicode test: happy\xE2\x98\xBA \xC2\xA3 5.00" " \xC2\xA1\xCF\x84\xC3\xA4u! " " \xE2\x84\xA4\xE2\x8A\x87\xE2\x84\x9D"; color = grub_video_map_rgb (128, 128, 255); /* All characters in the string exist in the 'Fixed 20' (10x20) font. */ texty += grub_font_get_ascent(fixed); grub_font_draw_string (str, fixed, color, 16, texty); texty += grub_font_get_descent (fixed) + grub_font_get_leading (fixed); texty += grub_font_get_ascent(sansbig); grub_font_draw_string (str, sansbig, color, 16, texty); texty += grub_font_get_descent (sansbig) + grub_font_get_leading (sansbig); texty += grub_font_get_ascent(sans); grub_font_draw_string (str, sans, color, 16, texty); texty += grub_font_get_descent (sans) + grub_font_get_leading (sans); texty += grub_font_get_ascent(sanssmall); grub_font_draw_string (str, sanssmall, color, 16, texty); texty += (grub_font_get_descent (sanssmall) + grub_font_get_leading (sanssmall)); glyph = grub_font_get_glyph (fixed, '*'); for (i = 0; i < 16; i++) { color = grub_video_map_color (i); palette[i] = color; grub_font_draw_glyph (glyph, color, 16 + i * 16, 220); } } grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY); for (i = 0; i < 2; i++) { color = grub_video_map_rgb (0, 0, 0); grub_video_fill_rect (color, 0, 0, width, height); color = grub_video_map_rgb (255, 0, 0); grub_video_fill_rect (color, 0, 0, 100, 100); color = grub_video_map_rgb (0, 255, 255); grub_video_fill_rect (color, 100, 100, 100, 100); grub_video_set_viewport (x + 150, y + 150, width - 150 * 2, height - 150 * 2); color = grub_video_map_rgb (77, 33, 77); grub_video_fill_rect (color, 0, 0, width, height); grub_video_swap_buffers (); } for (i = 0; i < 5; i++) { color = grub_video_map_rgb (i, 33, 77); grub_video_fill_rect (color, 0, 0, width, height); grub_video_blit_render_target (text_layer, GRUB_VIDEO_BLIT_BLEND, 0, 0, 0, 0, width, height); grub_video_swap_buffers (); } grub_getkey (); grub_video_delete_render_target (text_layer); grub_video_restore (); for (i = 0; i < 16; i++) grub_printf("color %d: %08x\n", i, palette[i]); grub_errno = GRUB_ERR_NONE; return grub_errno; }