/* * VAS_EBOOT -- GRand Unified Bootloader * Copyright (C) 2002,2003,2005,2007,2008,2009,2010 Free Software Foundation, Inc. * * VAS_EBOOT 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, either version 3 of the License, or * (at your option) any later version. * * VAS_EBOOT is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with VAS_EBOOT. If not, see . */ #ifndef VAS_EBOOT_TERM_HEADER #define VAS_EBOOT_TERM_HEADER 1 #define VAS_EBOOT_TERM_NO_KEY 0 /* Internal codes used by VAS_EBOOT to represent terminal input. */ /* Only for keys otherwise not having shifted modification. */ #define VAS_EBOOT_TERM_SHIFT 0x01000000 #define VAS_EBOOT_TERM_CTRL 0x02000000 #define VAS_EBOOT_TERM_ALT 0x04000000 /* Keys without associated character. */ #define VAS_EBOOT_TERM_EXTENDED 0x00800000 #define VAS_EBOOT_TERM_KEY_MASK 0x00ffffff #define VAS_EBOOT_TERM_KEY_LEFT (VAS_EBOOT_TERM_EXTENDED | 0x4b) #define VAS_EBOOT_TERM_KEY_RIGHT (VAS_EBOOT_TERM_EXTENDED | 0x4d) #define VAS_EBOOT_TERM_KEY_UP (VAS_EBOOT_TERM_EXTENDED | 0x48) #define VAS_EBOOT_TERM_KEY_DOWN (VAS_EBOOT_TERM_EXTENDED | 0x50) #define VAS_EBOOT_TERM_KEY_HOME (VAS_EBOOT_TERM_EXTENDED | 0x47) #define VAS_EBOOT_TERM_KEY_END (VAS_EBOOT_TERM_EXTENDED | 0x4f) #define VAS_EBOOT_TERM_KEY_DC (VAS_EBOOT_TERM_EXTENDED | 0x53) #define VAS_EBOOT_TERM_KEY_PPAGE (VAS_EBOOT_TERM_EXTENDED | 0x49) #define VAS_EBOOT_TERM_KEY_NPAGE (VAS_EBOOT_TERM_EXTENDED | 0x51) #define VAS_EBOOT_TERM_KEY_F1 (VAS_EBOOT_TERM_EXTENDED | 0x3b) #define VAS_EBOOT_TERM_KEY_F2 (VAS_EBOOT_TERM_EXTENDED | 0x3c) #define VAS_EBOOT_TERM_KEY_F3 (VAS_EBOOT_TERM_EXTENDED | 0x3d) #define VAS_EBOOT_TERM_KEY_F4 (VAS_EBOOT_TERM_EXTENDED | 0x3e) #define VAS_EBOOT_TERM_KEY_F5 (VAS_EBOOT_TERM_EXTENDED | 0x3f) #define VAS_EBOOT_TERM_KEY_F6 (VAS_EBOOT_TERM_EXTENDED | 0x40) #define VAS_EBOOT_TERM_KEY_F7 (VAS_EBOOT_TERM_EXTENDED | 0x41) #define VAS_EBOOT_TERM_KEY_F8 (VAS_EBOOT_TERM_EXTENDED | 0x42) #define VAS_EBOOT_TERM_KEY_F9 (VAS_EBOOT_TERM_EXTENDED | 0x43) #define VAS_EBOOT_TERM_KEY_F10 (VAS_EBOOT_TERM_EXTENDED | 0x44) #define VAS_EBOOT_TERM_KEY_F11 (VAS_EBOOT_TERM_EXTENDED | 0x57) #define VAS_EBOOT_TERM_KEY_F12 (VAS_EBOOT_TERM_EXTENDED | 0x58) #define VAS_EBOOT_TERM_KEY_INSERT (VAS_EBOOT_TERM_EXTENDED | 0x52) #define VAS_EBOOT_TERM_KEY_CENTER (VAS_EBOOT_TERM_EXTENDED | 0x4c) /* Hex value is used for ESC, since '\e' is nonstandard */ #define VAS_EBOOT_TERM_ESC 0x1b #define VAS_EBOOT_TERM_TAB '\t' #define VAS_EBOOT_TERM_BACKSPACE '\b' #define VAS_EBOOT_PROGRESS_NO_UPDATE -1 #define VAS_EBOOT_PROGRESS_FAST 0 #define VAS_EBOOT_PROGRESS_SLOW 2 #ifndef ASM_FILE #include #include #include #include #include /* These are used to represent the various color states we use. */ typedef enum { /* Used for uninitialized VasEBoot_term_color_state variables */ VAS_EBOOT_TERM_COLOR_UNDEFINED = -1, /* The color used to display all text that does not use the user defined colors below. */ VAS_EBOOT_TERM_COLOR_STANDARD = 0, /* The user defined colors for normal text. */ VAS_EBOOT_TERM_COLOR_NORMAL, /* The user defined colors for highlighted text. */ VAS_EBOOT_TERM_COLOR_HIGHLIGHT } VasEBoot_term_color_state; /* Flags for representing the capabilities of a terminal. */ /* Some notes about the flags: - These flags are used by higher-level functions but not terminals themselves. - If a terminal is dumb, you may assume that only putchar, getkey and checkkey are called. - Some fancy features (setcolorstate, setcolor and setcursor) can be set to NULL. */ /* Set when input characters shouldn't be echoed back. */ #define VAS_EBOOT_TERM_NO_ECHO (1 << 0) /* Set when the editing feature should be disabled. */ #define VAS_EBOOT_TERM_NO_EDIT (1 << 1) /* Set when the terminal cannot do fancy things. */ #define VAS_EBOOT_TERM_DUMB (1 << 2) /* Which encoding does terminal expect stream to be. */ #define VAS_EBOOT_TERM_CODE_TYPE_SHIFT 3 #define VAS_EBOOT_TERM_CODE_TYPE_MASK (7 << VAS_EBOOT_TERM_CODE_TYPE_SHIFT) /* Only ASCII characters accepted. */ #define VAS_EBOOT_TERM_CODE_TYPE_ASCII (0 << VAS_EBOOT_TERM_CODE_TYPE_SHIFT) /* Expects CP-437 characters (ASCII + pseudographics). */ #define VAS_EBOOT_TERM_CODE_TYPE_CP437 (1 << VAS_EBOOT_TERM_CODE_TYPE_SHIFT) /* UTF-8 stream in logical order. Usually used for terminals which just forward the stream to another computer. */ #define VAS_EBOOT_TERM_CODE_TYPE_UTF8_LOGICAL (2 << VAS_EBOOT_TERM_CODE_TYPE_SHIFT) /* UTF-8 in visual order. Like UTF-8 logical but for buggy endpoints. */ #define VAS_EBOOT_TERM_CODE_TYPE_UTF8_VISUAL (3 << VAS_EBOOT_TERM_CODE_TYPE_SHIFT) /* Glyph description in visual order. */ #define VAS_EBOOT_TERM_CODE_TYPE_VISUAL_GLYPHS (4 << VAS_EBOOT_TERM_CODE_TYPE_SHIFT) /* Bitmasks for modifier keys returned by VasEBoot_getkeystatus. */ #define VAS_EBOOT_TERM_STATUS_RSHIFT (1 << 0) #define VAS_EBOOT_TERM_STATUS_LSHIFT (1 << 1) #define VAS_EBOOT_TERM_STATUS_RCTRL (1 << 2) #define VAS_EBOOT_TERM_STATUS_RALT (1 << 3) #define VAS_EBOOT_TERM_STATUS_SCROLL (1 << 4) #define VAS_EBOOT_TERM_STATUS_NUM (1 << 5) #define VAS_EBOOT_TERM_STATUS_CAPS (1 << 6) #define VAS_EBOOT_TERM_STATUS_LCTRL (1 << 8) #define VAS_EBOOT_TERM_STATUS_LALT (1 << 9) /* Menu-related geometrical constants. */ /* The number of columns/lines between messages/borders/etc. */ #define VAS_EBOOT_TERM_MARGIN 1 /* The number of columns of scroll information. */ #define VAS_EBOOT_TERM_SCROLL_WIDTH 1 struct VasEBoot_term_input { /* The next terminal. */ struct VasEBoot_term_input *next; struct VasEBoot_term_input **prev; /* The terminal name. */ const char *name; /* Initialize the terminal. */ VasEBoot_err_t (*init) (struct VasEBoot_term_input *term); /* Clean up the terminal. */ VasEBoot_err_t (*fini) (struct VasEBoot_term_input *term); /* Get a character if any input character is available. Otherwise return -1 */ int (*getkey) (struct VasEBoot_term_input *term); /* Get keyboard modifier status. */ int (*getkeystatus) (struct VasEBoot_term_input *term); void *data; }; typedef struct VasEBoot_term_input *VasEBoot_term_input_t; /* Made in a way to fit into uint32_t and so be passed in a register. */ struct VasEBoot_term_coordinate { VasEBoot_uint16_t x; VasEBoot_uint16_t y; }; struct VasEBoot_term_output { /* The next terminal. */ struct VasEBoot_term_output *next; struct VasEBoot_term_output **prev; /* The terminal name. */ const char *name; /* Initialize the terminal. */ VasEBoot_err_t (*init) (struct VasEBoot_term_output *term); /* Clean up the terminal. */ VasEBoot_err_t (*fini) (struct VasEBoot_term_output *term); /* Put a character. C is encoded in Unicode. */ void (*putchar) (struct VasEBoot_term_output *term, const struct VasEBoot_unicode_glyph *c); /* Get the number of columns occupied by a given character C. C is encoded in Unicode. */ VasEBoot_size_t (*getcharwidth) (struct VasEBoot_term_output *term, const struct VasEBoot_unicode_glyph *c); /* Get the screen size. */ struct VasEBoot_term_coordinate (*getwh) (struct VasEBoot_term_output *term); /* Get the cursor position. The return value is ((X << 8) | Y). */ struct VasEBoot_term_coordinate (*getxy) (struct VasEBoot_term_output *term); /* Go to the position (X, Y). */ void (*gotoxy) (struct VasEBoot_term_output *term, struct VasEBoot_term_coordinate pos); /* Clear the screen. */ void (*cls) (struct VasEBoot_term_output *term); /* Set the current color to be used */ void (*setcolorstate) (struct VasEBoot_term_output *term, VasEBoot_term_color_state state); /* Turn on/off the cursor. */ void (*setcursor) (struct VasEBoot_term_output *term, int on); /* Update the screen. */ void (*refresh) (struct VasEBoot_term_output *term); /* gfxterm only: put in fullscreen mode. */ VasEBoot_err_t (*fullscreen) (void); /* The feature flags defined above. */ VasEBoot_uint32_t flags; /* Progress data. */ VasEBoot_uint32_t progress_update_divisor; VasEBoot_uint32_t progress_update_counter; void *data; }; typedef struct VasEBoot_term_output *VasEBoot_term_output_t; #define VAS_EBOOT_TERM_DEFAULT_NORMAL_COLOR 0x07 #define VAS_EBOOT_TERM_DEFAULT_HIGHLIGHT_COLOR 0x70 #define VAS_EBOOT_TERM_DEFAULT_STANDARD_COLOR 0x07 /* Current color state. */ extern VasEBoot_uint8_t EXPORT_VAR(VasEBoot_term_normal_color); extern VasEBoot_uint8_t EXPORT_VAR(VasEBoot_term_highlight_color); extern struct VasEBoot_term_output *EXPORT_VAR(VasEBoot_term_outputs_disabled); extern struct VasEBoot_term_input *EXPORT_VAR(VasEBoot_term_inputs_disabled); extern struct VasEBoot_term_output *EXPORT_VAR(VasEBoot_term_outputs); extern struct VasEBoot_term_input *EXPORT_VAR(VasEBoot_term_inputs); static inline void VasEBoot_term_register_input (const char *name __attribute__ ((unused)), VasEBoot_term_input_t term) { if (VasEBoot_term_inputs) VasEBoot_list_push (VAS_EBOOT_AS_LIST_P (&VasEBoot_term_inputs_disabled), VAS_EBOOT_AS_LIST (term)); else { /* If this is the first terminal, enable automatically. */ if (! term->init || term->init (term) == VAS_EBOOT_ERR_NONE) VasEBoot_list_push (VAS_EBOOT_AS_LIST_P (&VasEBoot_term_inputs), VAS_EBOOT_AS_LIST (term)); } } static inline void VasEBoot_term_register_input_inactive (const char *name __attribute__ ((unused)), VasEBoot_term_input_t term) { VasEBoot_list_push (VAS_EBOOT_AS_LIST_P (&VasEBoot_term_inputs_disabled), VAS_EBOOT_AS_LIST (term)); } static inline void VasEBoot_term_register_input_active (const char *name __attribute__ ((unused)), VasEBoot_term_input_t term) { if (! term->init || term->init (term) == VAS_EBOOT_ERR_NONE) VasEBoot_list_push (VAS_EBOOT_AS_LIST_P (&VasEBoot_term_inputs), VAS_EBOOT_AS_LIST (term)); } static inline void VasEBoot_term_register_output (const char *name __attribute__ ((unused)), VasEBoot_term_output_t term) { if (VasEBoot_term_outputs) VasEBoot_list_push (VAS_EBOOT_AS_LIST_P (&VasEBoot_term_outputs_disabled), VAS_EBOOT_AS_LIST (term)); else { /* If this is the first terminal, enable automatically. */ if (! term->init || term->init (term) == VAS_EBOOT_ERR_NONE) VasEBoot_list_push (VAS_EBOOT_AS_LIST_P (&VasEBoot_term_outputs), VAS_EBOOT_AS_LIST (term)); } } static inline void VasEBoot_term_register_output_inactive (const char *name __attribute__ ((unused)), VasEBoot_term_output_t term) { VasEBoot_list_push (VAS_EBOOT_AS_LIST_P (&VasEBoot_term_outputs_disabled), VAS_EBOOT_AS_LIST (term)); } static inline void VasEBoot_term_register_output_active (const char *name __attribute__ ((unused)), VasEBoot_term_output_t term) { if (! term->init || term->init (term) == VAS_EBOOT_ERR_NONE) VasEBoot_list_push (VAS_EBOOT_AS_LIST_P (&VasEBoot_term_outputs), VAS_EBOOT_AS_LIST (term)); } static inline void VasEBoot_term_unregister_input (VasEBoot_term_input_t term) { VasEBoot_list_remove (VAS_EBOOT_AS_LIST (term)); VasEBoot_list_remove (VAS_EBOOT_AS_LIST (term)); } static inline void VasEBoot_term_unregister_output (VasEBoot_term_output_t term) { VasEBoot_list_remove (VAS_EBOOT_AS_LIST (term)); VasEBoot_list_remove (VAS_EBOOT_AS_LIST (term)); } #define FOR_ACTIVE_TERM_INPUTS(var) FOR_LIST_ELEMENTS((var), (VasEBoot_term_inputs)) #define FOR_DISABLED_TERM_INPUTS(var) FOR_LIST_ELEMENTS((var), (VasEBoot_term_inputs_disabled)) #define FOR_ACTIVE_TERM_OUTPUTS(var) FOR_LIST_ELEMENTS((var), (VasEBoot_term_outputs)) #define FOR_DISABLED_TERM_OUTPUTS(var) FOR_LIST_ELEMENTS((var), (VasEBoot_term_outputs_disabled)) void VasEBoot_putcode (VasEBoot_uint32_t code, struct VasEBoot_term_output *term); int EXPORT_FUNC(VasEBoot_getkey) (void); int EXPORT_FUNC(VasEBoot_getkey_noblock) (void); int EXPORT_FUNC(VasEBoot_getkeystatus) (void); int EXPORT_FUNC(VasEBoot_key_is_interrupt) (int key); void VasEBoot_cls (void); void EXPORT_FUNC(VasEBoot_refresh) (void); void VasEBoot_puts_terminal (const char *str, struct VasEBoot_term_output *term); struct VasEBoot_term_coordinate *VasEBoot_term_save_pos (void); void VasEBoot_term_restore_pos (struct VasEBoot_term_coordinate *pos); static inline unsigned VasEBoot_term_width (struct VasEBoot_term_output *term) { return term->getwh(term).x ? : 80; } static inline unsigned VasEBoot_term_height (struct VasEBoot_term_output *term) { return term->getwh(term).y ? : 24; } static inline struct VasEBoot_term_coordinate VasEBoot_term_getxy (struct VasEBoot_term_output *term) { return term->getxy (term); } static inline void VasEBoot_term_refresh (struct VasEBoot_term_output *term) { if (term->refresh) term->refresh (term); } static inline void VasEBoot_term_gotoxy (struct VasEBoot_term_output *term, struct VasEBoot_term_coordinate pos) { term->gotoxy (term, pos); } static inline void VasEBoot_term_setcolorstate (struct VasEBoot_term_output *term, VasEBoot_term_color_state state) { if (term->setcolorstate) term->setcolorstate (term, state); } static inline void VasEBoot_setcolorstate (VasEBoot_term_color_state state) { struct VasEBoot_term_output *term; FOR_ACTIVE_TERM_OUTPUTS(term) VasEBoot_term_setcolorstate (term, state); } /* Turn on/off the cursor. */ static inline void VasEBoot_term_setcursor (struct VasEBoot_term_output *term, int on) { if (term->setcursor) term->setcursor (term, on); } static inline void VasEBoot_term_cls (struct VasEBoot_term_output *term) { if (term->cls) (term->cls) (term); else { VasEBoot_putcode ('\n', term); VasEBoot_term_refresh (term); } } #if HAVE_FONT_SOURCE VasEBoot_size_t VasEBoot_unicode_estimate_width (const struct VasEBoot_unicode_glyph *c); #else static inline VasEBoot_size_t VasEBoot_unicode_estimate_width (const struct VasEBoot_unicode_glyph *c __attribute__ ((unused))) { if (VasEBoot_unicode_get_comb_type (c->base)) return 0; return 1; } #endif #define VAS_EBOOT_TERM_TAB_WIDTH 8 static inline VasEBoot_size_t VasEBoot_term_getcharwidth (struct VasEBoot_term_output *term, const struct VasEBoot_unicode_glyph *c) { if (c->base == '\t') return VAS_EBOOT_TERM_TAB_WIDTH; if (term->getcharwidth) return term->getcharwidth (term, c); else if (((term->flags & VAS_EBOOT_TERM_CODE_TYPE_MASK) == VAS_EBOOT_TERM_CODE_TYPE_UTF8_LOGICAL) || ((term->flags & VAS_EBOOT_TERM_CODE_TYPE_MASK) == VAS_EBOOT_TERM_CODE_TYPE_UTF8_VISUAL) || ((term->flags & VAS_EBOOT_TERM_CODE_TYPE_MASK) == VAS_EBOOT_TERM_CODE_TYPE_VISUAL_GLYPHS)) return VasEBoot_unicode_estimate_width (c); else return 1; } struct VasEBoot_term_autoload { struct VasEBoot_term_autoload *next; char *name; char *modname; }; extern struct VasEBoot_term_autoload *VasEBoot_term_input_autoload; extern struct VasEBoot_term_autoload *VasEBoot_term_output_autoload; static inline void VasEBoot_print_spaces (struct VasEBoot_term_output *term, int number_spaces) { while (--number_spaces >= 0) VasEBoot_putcode (' ', term); } extern void (*EXPORT_VAR (VasEBoot_term_poll_usb)) (int wait_for_completion); #define VAS_EBOOT_TERM_REPEAT_PRE_INTERVAL 400 #define VAS_EBOOT_TERM_REPEAT_INTERVAL 50 #endif /* ! ASM_FILE */ #endif /* ! VAS_EBOOT_TERM_HEADER */