2 * GRUB -- GRand Unified Bootloader
3 * Copyright (C) 2002,2003,2005,2007,2008,2009,2010 Free Software Foundation, Inc.
5 * GRUB is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * GRUB is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
19 #ifndef GRUB_TERM_HEADER
20 #define GRUB_TERM_HEADER 1
22 #define GRUB_TERM_NO_KEY 0
24 /* Internal codes used by GRUB to represent terminal input. */
25 /* Only for keys otherwise not having shifted modification. */
26 #define GRUB_TERM_SHIFT 0x01000000
27 #define GRUB_TERM_CTRL 0x02000000
28 #define GRUB_TERM_ALT 0x04000000
30 /* Keys without associated character. */
31 #define GRUB_TERM_EXTENDED 0x00800000
32 #define GRUB_TERM_KEY_MASK 0x00ffffff
34 #define GRUB_TERM_KEY_LEFT (GRUB_TERM_EXTENDED | 0x4b)
35 #define GRUB_TERM_KEY_RIGHT (GRUB_TERM_EXTENDED | 0x4d)
36 #define GRUB_TERM_KEY_UP (GRUB_TERM_EXTENDED | 0x48)
37 #define GRUB_TERM_KEY_DOWN (GRUB_TERM_EXTENDED | 0x50)
38 #define GRUB_TERM_KEY_HOME (GRUB_TERM_EXTENDED | 0x47)
39 #define GRUB_TERM_KEY_END (GRUB_TERM_EXTENDED | 0x4f)
40 #define GRUB_TERM_KEY_DC (GRUB_TERM_EXTENDED | 0x53)
41 #define GRUB_TERM_KEY_PPAGE (GRUB_TERM_EXTENDED | 0x49)
42 #define GRUB_TERM_KEY_NPAGE (GRUB_TERM_EXTENDED | 0x51)
43 #define GRUB_TERM_KEY_F1 (GRUB_TERM_EXTENDED | 0x3b)
44 #define GRUB_TERM_KEY_F2 (GRUB_TERM_EXTENDED | 0x3c)
45 #define GRUB_TERM_KEY_F3 (GRUB_TERM_EXTENDED | 0x3d)
46 #define GRUB_TERM_KEY_F4 (GRUB_TERM_EXTENDED | 0x3e)
47 #define GRUB_TERM_KEY_F5 (GRUB_TERM_EXTENDED | 0x3f)
48 #define GRUB_TERM_KEY_F6 (GRUB_TERM_EXTENDED | 0x40)
49 #define GRUB_TERM_KEY_F7 (GRUB_TERM_EXTENDED | 0x41)
50 #define GRUB_TERM_KEY_F8 (GRUB_TERM_EXTENDED | 0x42)
51 #define GRUB_TERM_KEY_F9 (GRUB_TERM_EXTENDED | 0x43)
52 #define GRUB_TERM_KEY_F10 (GRUB_TERM_EXTENDED | 0x44)
53 #define GRUB_TERM_KEY_F11 (GRUB_TERM_EXTENDED | 0x57)
54 #define GRUB_TERM_KEY_F12 (GRUB_TERM_EXTENDED | 0x58)
55 #define GRUB_TERM_KEY_INSERT (GRUB_TERM_EXTENDED | 0x52)
56 #define GRUB_TERM_KEY_CENTER (GRUB_TERM_EXTENDED | 0x4c)
58 #define GRUB_TERM_ESC '\e'
59 #define GRUB_TERM_TAB '\t'
60 #define GRUB_TERM_BACKSPACE '\b'
62 #define GRUB_PROGRESS_NO_UPDATE -1
63 #define GRUB_PROGRESS_FAST 0
64 #define GRUB_PROGRESS_SLOW 2
69 #include <grub/symbol.h>
70 #include <grub/types.h>
71 #include <grub/unicode.h>
72 #include <grub/list.h>
74 /* These are used to represent the various color states we use. */
77 /* The color used to display all text that does not use the
78 user defined colors below. */
79 GRUB_TERM_COLOR_STANDARD
,
80 /* The user defined colors for normal text. */
81 GRUB_TERM_COLOR_NORMAL
,
82 /* The user defined colors for highlighted text. */
83 GRUB_TERM_COLOR_HIGHLIGHT
85 grub_term_color_state
;
87 /* Flags for representing the capabilities of a terminal. */
88 /* Some notes about the flags:
89 - These flags are used by higher-level functions but not terminals
91 - If a terminal is dumb, you may assume that only putchar, getkey and
93 - Some fancy features (setcolorstate, setcolor and setcursor) can be set
96 /* Set when input characters shouldn't be echoed back. */
97 #define GRUB_TERM_NO_ECHO (1 << 0)
98 /* Set when the editing feature should be disabled. */
99 #define GRUB_TERM_NO_EDIT (1 << 1)
100 /* Set when the terminal cannot do fancy things. */
101 #define GRUB_TERM_DUMB (1 << 2)
102 /* Which encoding does terminal expect stream to be. */
103 #define GRUB_TERM_CODE_TYPE_SHIFT 3
104 #define GRUB_TERM_CODE_TYPE_MASK (7 << GRUB_TERM_CODE_TYPE_SHIFT)
105 /* Only ASCII characters accepted. */
106 #define GRUB_TERM_CODE_TYPE_ASCII (0 << GRUB_TERM_CODE_TYPE_SHIFT)
107 /* Expects CP-437 characters (ASCII + pseudographics). */
108 #define GRUB_TERM_CODE_TYPE_CP437 (1 << GRUB_TERM_CODE_TYPE_SHIFT)
109 /* UTF-8 stream in logical order. Usually used for terminals
110 which just forward the stream to another computer. */
111 #define GRUB_TERM_CODE_TYPE_UTF8_LOGICAL (2 << GRUB_TERM_CODE_TYPE_SHIFT)
112 /* UTF-8 in visual order. Like UTF-8 logical but for buggy endpoints. */
113 #define GRUB_TERM_CODE_TYPE_UTF8_VISUAL (3 << GRUB_TERM_CODE_TYPE_SHIFT)
114 /* Glyph description in visual order. */
115 #define GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS (4 << GRUB_TERM_CODE_TYPE_SHIFT)
118 /* Bitmasks for modifier keys returned by grub_getkeystatus. */
119 #define GRUB_TERM_STATUS_RSHIFT (1 << 0)
120 #define GRUB_TERM_STATUS_LSHIFT (1 << 1)
121 #define GRUB_TERM_STATUS_RCTRL (1 << 2)
122 #define GRUB_TERM_STATUS_RALT (1 << 3)
123 #define GRUB_TERM_STATUS_SCROLL (1 << 4)
124 #define GRUB_TERM_STATUS_NUM (1 << 5)
125 #define GRUB_TERM_STATUS_CAPS (1 << 6)
126 #define GRUB_TERM_STATUS_LCTRL (1 << 8)
127 #define GRUB_TERM_STATUS_LALT (1 << 9)
129 /* Menu-related geometrical constants. */
131 /* The number of columns/lines between messages/borders/etc. */
132 #define GRUB_TERM_MARGIN 1
134 /* The number of columns of scroll information. */
135 #define GRUB_TERM_SCROLL_WIDTH 1
137 struct grub_term_input
139 /* The next terminal. */
140 struct grub_term_input
*next
;
141 struct grub_term_input
**prev
;
143 /* The terminal name. */
146 /* Initialize the terminal. */
147 grub_err_t (*init
) (struct grub_term_input
*term
);
149 /* Clean up the terminal. */
150 grub_err_t (*fini
) (struct grub_term_input
*term
);
152 /* Get a character if any input character is available. Otherwise return -1 */
153 int (*getkey
) (struct grub_term_input
*term
);
155 /* Get keyboard modifier status. */
156 int (*getkeystatus
) (struct grub_term_input
*term
);
160 typedef struct grub_term_input
*grub_term_input_t
;
162 /* Made in a way to fit into uint32_t and so be passed in a register. */
163 struct grub_term_coordinate
169 struct grub_term_output
171 /* The next terminal. */
172 struct grub_term_output
*next
;
173 struct grub_term_output
**prev
;
175 /* The terminal name. */
178 /* Initialize the terminal. */
179 grub_err_t (*init
) (struct grub_term_output
*term
);
181 /* Clean up the terminal. */
182 grub_err_t (*fini
) (struct grub_term_output
*term
);
184 /* Put a character. C is encoded in Unicode. */
185 void (*putchar
) (struct grub_term_output
*term
,
186 const struct grub_unicode_glyph
*c
);
188 /* Get the number of columns occupied by a given character C. C is
189 encoded in Unicode. */
190 grub_size_t (*getcharwidth
) (struct grub_term_output
*term
,
191 const struct grub_unicode_glyph
*c
);
193 /* Get the screen size. */
194 struct grub_term_coordinate (*getwh
) (struct grub_term_output
*term
);
196 /* Get the cursor position. The return value is ((X << 8) | Y). */
197 struct grub_term_coordinate (*getxy
) (struct grub_term_output
*term
);
199 /* Go to the position (X, Y). */
200 void (*gotoxy
) (struct grub_term_output
*term
,
201 struct grub_term_coordinate pos
);
203 /* Clear the screen. */
204 void (*cls
) (struct grub_term_output
*term
);
206 /* Set the current color to be used */
207 void (*setcolorstate
) (struct grub_term_output
*term
,
208 grub_term_color_state state
);
210 /* Turn on/off the cursor. */
211 void (*setcursor
) (struct grub_term_output
*term
, int on
);
213 /* Update the screen. */
214 void (*refresh
) (struct grub_term_output
*term
);
216 /* gfxterm only: put in fullscreen mode. */
217 grub_err_t (*fullscreen
) (void);
219 /* The feature flags defined above. */
223 grub_uint32_t progress_update_divisor
;
224 grub_uint32_t progress_update_counter
;
228 typedef struct grub_term_output
*grub_term_output_t
;
230 #define GRUB_TERM_DEFAULT_NORMAL_COLOR 0x07
231 #define GRUB_TERM_DEFAULT_HIGHLIGHT_COLOR 0x70
232 #define GRUB_TERM_DEFAULT_STANDARD_COLOR 0x07
234 /* Current color state. */
235 extern grub_uint8_t
EXPORT_VAR(grub_term_normal_color
);
236 extern grub_uint8_t
EXPORT_VAR(grub_term_highlight_color
);
238 extern struct grub_term_output
*EXPORT_VAR(grub_term_outputs_disabled
);
239 extern struct grub_term_input
*EXPORT_VAR(grub_term_inputs_disabled
);
240 extern struct grub_term_output
*EXPORT_VAR(grub_term_outputs
);
241 extern struct grub_term_input
*EXPORT_VAR(grub_term_inputs
);
244 grub_term_register_input (const char *name
__attribute__ ((unused
)),
245 grub_term_input_t term
)
247 if (grub_term_inputs
)
248 grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs_disabled
),
249 GRUB_AS_LIST (term
));
252 /* If this is the first terminal, enable automatically. */
253 if (! term
->init
|| term
->init (term
) == GRUB_ERR_NONE
)
254 grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs
), GRUB_AS_LIST (term
));
259 grub_term_register_input_inactive (const char *name
__attribute__ ((unused
)),
260 grub_term_input_t term
)
262 grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs_disabled
),
263 GRUB_AS_LIST (term
));
267 grub_term_register_input_active (const char *name
__attribute__ ((unused
)),
268 grub_term_input_t term
)
270 if (! term
->init
|| term
->init (term
) == GRUB_ERR_NONE
)
271 grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs
), GRUB_AS_LIST (term
));
275 grub_term_register_output (const char *name
__attribute__ ((unused
)),
276 grub_term_output_t term
)
278 if (grub_term_outputs
)
279 grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs_disabled
),
280 GRUB_AS_LIST (term
));
283 /* If this is the first terminal, enable automatically. */
284 if (! term
->init
|| term
->init (term
) == GRUB_ERR_NONE
)
285 grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs
),
286 GRUB_AS_LIST (term
));
291 grub_term_register_output_inactive (const char *name
__attribute__ ((unused
)),
292 grub_term_output_t term
)
294 grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs_disabled
),
295 GRUB_AS_LIST (term
));
299 grub_term_register_output_active (const char *name
__attribute__ ((unused
)),
300 grub_term_output_t term
)
302 if (! term
->init
|| term
->init (term
) == GRUB_ERR_NONE
)
303 grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs
),
304 GRUB_AS_LIST (term
));
308 grub_term_unregister_input (grub_term_input_t term
)
310 grub_list_remove (GRUB_AS_LIST (term
));
311 grub_list_remove (GRUB_AS_LIST (term
));
315 grub_term_unregister_output (grub_term_output_t term
)
317 grub_list_remove (GRUB_AS_LIST (term
));
318 grub_list_remove (GRUB_AS_LIST (term
));
321 #define FOR_ACTIVE_TERM_INPUTS(var) FOR_LIST_ELEMENTS((var), (grub_term_inputs))
322 #define FOR_DISABLED_TERM_INPUTS(var) FOR_LIST_ELEMENTS((var), (grub_term_inputs_disabled))
323 #define FOR_ACTIVE_TERM_OUTPUTS(var) FOR_LIST_ELEMENTS((var), (grub_term_outputs))
324 #define FOR_DISABLED_TERM_OUTPUTS(var) FOR_LIST_ELEMENTS((var), (grub_term_outputs_disabled))
326 void grub_putcode (grub_uint32_t code
, struct grub_term_output
*term
);
327 int EXPORT_FUNC(grub_getkey
) (void);
328 int EXPORT_FUNC(grub_getkey_noblock
) (void);
329 void grub_cls (void);
330 void EXPORT_FUNC(grub_refresh
) (void);
331 void grub_puts_terminal (const char *str
, struct grub_term_output
*term
);
332 struct grub_term_coordinate
*grub_term_save_pos (void);
333 void grub_term_restore_pos (struct grub_term_coordinate
*pos
);
335 static inline unsigned grub_term_width (struct grub_term_output
*term
)
337 return term
->getwh(term
).x
? : 80;
340 static inline unsigned grub_term_height (struct grub_term_output
*term
)
342 return term
->getwh(term
).y
? : 24;
345 static inline struct grub_term_coordinate
346 grub_term_getxy (struct grub_term_output
*term
)
348 return term
->getxy (term
);
352 grub_term_refresh (struct grub_term_output
*term
)
355 term
->refresh (term
);
359 grub_term_gotoxy (struct grub_term_output
*term
, struct grub_term_coordinate pos
)
361 term
->gotoxy (term
, pos
);
365 grub_term_setcolorstate (struct grub_term_output
*term
,
366 grub_term_color_state state
)
368 if (term
->setcolorstate
)
369 term
->setcolorstate (term
, state
);
373 grub_setcolorstate (grub_term_color_state state
)
375 struct grub_term_output
*term
;
377 FOR_ACTIVE_TERM_OUTPUTS(term
)
378 grub_term_setcolorstate (term
, state
);
381 /* Turn on/off the cursor. */
383 grub_term_setcursor (struct grub_term_output
*term
, int on
)
386 term
->setcursor (term
, on
);
390 grub_term_cls (struct grub_term_output
*term
)
396 grub_putcode ('\n', term
);
397 grub_term_refresh (term
);
404 grub_unicode_estimate_width (const struct grub_unicode_glyph
*c
);
408 static inline grub_size_t
409 grub_unicode_estimate_width (const struct grub_unicode_glyph
*c
__attribute__ ((unused
)))
411 if (grub_unicode_get_comb_type (c
->base
))
418 #define GRUB_TERM_TAB_WIDTH 8
420 static inline grub_size_t
421 grub_term_getcharwidth (struct grub_term_output
*term
,
422 const struct grub_unicode_glyph
*c
)
425 return GRUB_TERM_TAB_WIDTH
;
427 if (term
->getcharwidth
)
428 return term
->getcharwidth (term
, c
);
429 else if (((term
->flags
& GRUB_TERM_CODE_TYPE_MASK
)
430 == GRUB_TERM_CODE_TYPE_UTF8_LOGICAL
)
431 || ((term
->flags
& GRUB_TERM_CODE_TYPE_MASK
)
432 == GRUB_TERM_CODE_TYPE_UTF8_VISUAL
)
433 || ((term
->flags
& GRUB_TERM_CODE_TYPE_MASK
)
434 == GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS
))
435 return grub_unicode_estimate_width (c
);
440 struct grub_term_autoload
442 struct grub_term_autoload
*next
;
447 extern struct grub_term_autoload
*grub_term_input_autoload
;
448 extern struct grub_term_autoload
*grub_term_output_autoload
;
451 grub_print_spaces (struct grub_term_output
*term
, int number_spaces
)
453 while (--number_spaces
>= 0)
454 grub_putcode (' ', term
);
457 extern void (*EXPORT_VAR (grub_term_poll_usb
)) (int wait_for_completion
);
459 #define GRUB_TERM_REPEAT_PRE_INTERVAL 400
460 #define GRUB_TERM_REPEAT_INTERVAL 50
462 #endif /* ! ASM_FILE */
464 #endif /* ! GRUB_TERM_HEADER */