Bidi and diacritics support.

* Makefile.in (widthspec.bin): New target.
	(widthspec.h): Likewise.
	(TARGET_CFLAGS): Add -DHAVE_UNIFONT_WIDTHSPEC=1 if font was available.
	* autogen.sh: Generate unidata.c.
	* commands/cat.c (grub_cmd_cat): Don't use grub_putchar.
	* commands/ls.c (grub_ls_list_devices): Likewise.
	(grub_ls_list_files): Likewise.
	* commands/minicmd.c (grub_mini_cmd_cat): Likewise.
	(grub_mini_cmd_lsmod): Likewise.
	* commands/read.c: Likewise.
	* kern/corecmd.c (grub_core_cmd_ls): Likewise.
	* kern/rescue_reader.c (grub_rescue_read_line): Likewise.
	* lib/arg.c (grub_arg_show_help): Likewise.
	* lib/crypto.c (grub_password_get): Likewise.
	* normal/auth.c (grub_username_get): Likewise.
	* normal/misc.c (grub_normal_print_device_info): Likewise.
	* commands/help.c (grub_cmd_help): Use grub_unicode_aglomerate_comb.
	* conf/common.rmk (grub_mkfont_SOURCES): Add unidata.c.
	(gfxmenu_mod_SOURCES): Add gfxmenu/font.c.
	(normal/charset.c_DEPENDENCIES): New variable.
	(normal_mod_SOURCES): Add normal/charset.c and unidata.c.
	(pkglib_MODULES): Remove charset.mod.
	(charset_mod_SOURCES): Removed.
	(charset_mod_CFLAGS): Likewise.
	(charset_mod_LDFLAGS): Likewise.
	(pkglib_MODULES) [ieee1275]: Remove terminfo.mod.
	* conf/powerpc-ieee1275.rmk (kernel_img_SOURCES): Add term/terminfo.c
	and term/tparm.c.
	* conf/sparc64-ieee1275.rmk (kernel_img_SOURCES): Likewise.
	* conf/i386-ieee1275.rmk (kernel_img_SOURCES): Likewise.
	(kernel_img_HEADERS): Add terminfo.h.
	* font/font.c (ascii_glyph_lookup): Return NULL on failure.
	Fill ->font. Reverse ascii bitmaps.
	(grub_font_get_xheight): New function.
	* font/font.c (grub_font_get_string_width): Moved from here ...
	* gfxmenu/font.c (grub_font_get_string_width): ... here.
	* font/font.c (grub_font_draw_string): Moved from here ...
	* gfxmenu/font.c (grub_font_draw_string): ... here.
	* font/font.c (grub_font_dup_glyph): New function.
	(grub_font_blit_glyph): Likewise.
	(grub_font_blit_glyph_mirror): Likewise.
	(blit_comb): Likewise.
	(grub_font_construct_dry_run): Likewise.
	(grub_font_get_constructed_device_width): Likewise.
	(grub_font_construct_glyph): Likewise.
	* include/grub/charset.h (grub_ucs4_to_utf8): New proto.
	* include/grub/misc.h (grub_utf8_to_ucs4): Moved from here ...
	* include/grub/charset.h (grub_utf8_to_ucs4): ... here.
	* include/grub/font.h (GRUB_FONT_CODE_CHAR_MASK): New constant.
	(GRUB_FONT_CODE_RIGHT_JOINED): Likewise.
	(GRUB_FONT_CODE_LEFT_JOINED): Likewise.
	(grub_font_get_xheight): New proto.
	(grub_font_get_constructed_device_width): Likewise.
	(grub_font_construct_glyph): Likewise.
	* include/grub/font.h (grub_font_get_string_width): Moved from here ...
	* include/grub/gfxmenu_view.h (grub_font_get_string_width): ... here.
	* include/grub/font.h (grub_font_draw_string): Moved from here ...
	* include/grub/gfxmenu_view.h (grub_font_draw_string): ... here.
	* include/grub/i386/vga_common.h (grub_console_putchar): Moved from here..
	* include/grub/i386/pc/console.h (grub_console_putchar): ... here.
	* include/grub/i386/vga_common.h (grub_console_real_putchar): Removed.
	(grub_console_getcharwidth): Likewise.
	* include/grub/misc.h (grub_xputs): New proto.
	(grub_puts): Inlined.
	* include/grub/normal.h (grub_print_ucs4): Add margin specification.
	(grub_normal_get_line_counter): Removed.
	(grub_install_newline_hook): Likewise.
	(grub_normal_get_char_counter): New proto.
	(grub_normal_reset_more): Likewise.
	(grub_xputs_normal): Likewise.
	* include/grub/powerpc/ieee1275/console.h: Removed.
	* include/grub/sparc64/ieee1275/console.h: Likewise.
	* include/grub/term.h (GRUB_TERM_CODE_TYPE_MASK): New definition.
	(GRUB_TERM_CODE_TYPE_ASCII): Likewise.
	(GRUB_TERM_CODE_TYPE_CP437): Likewise.
	(GRUB_TERM_CODE_TYPE_UTF8_LOGICAL): Likewise.
	(GRUB_TERM_CODE_TYPE_UTF8_VISUAL): Likewise.
	(GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS): Likewise.
	(grub_term_input): Pass reference to self. All users updated.
	(grub_term_output): Pass grub_unicode_glyph to putchar and getcharwidth.
	Pass reference to self. New fields normal_color, highlight_color and
	data. All users updated.
	(grub_putchar): Removed.
	(grub_putcode): Remove EXPORT_FUNC since it's not in kernel anymore.
	(grub_unicode_estimate_width): New function.
	(grub_term_getcharwidth): Add defaults.
	(GRUB_TERM_DEFAULT_NORMAL_COLOR): New definition.
	(GRUB_TERM_DEFAULT_HIGHLIGHT_COLOR): Likewise.
	(GRUB_TERM_DEFAULT_STANDARD_COLOR): Likewise.
	(grub_cls): Remove EXPORT_FUNC.
	(grub_setcolorstate): Inline.
	(grub_newline_hook): Removed.
	* include/grub/terminfo.h: Rewritten. All users updated.
	* include/grub/unicode.h: New file.
	* include/grub/video.h (grub_video_signed_rect): New type.
	* kern/emu/console.c (grub_console_highlight_color): Removed.
	(grub_console_normal_color): Likewise.
	(grub_console_standard_color): Made static.
	(grub_ncurses_putchar): Remove mapping.
	(grub_ncurses_getcharwidth): Removed.
	(grub_ncurses_term_output): Declare as GRUB_TERM_CODE_TYPE_ASCII.
	(grub_ncurses_setcolor): Removed.
	(grub_ncurses_getcolor): Likewise.
	* kern/i386/pc/startup.S (grub_console_real_putchar): Renamed to ...
	(grub_console_putchar): ... this.
	(grub_console_putchar): Handle argument difference.
	* kern/ieee1275/init.c (grub_machine_init): Split console_init into
	console_init_early and console_init_lately.
	* kern/sparc64/ieee1275/init.c (grub_machine_init): Likewise.
	* kern/misc.c (grub_puts): Removed.
	(grub_vprintf): Store UTF-8 string instead of outputting it directly.
	(grub_vsnprintf_real): Remove str = NULL support.
	* kern/misc.c (grub_utf8_to_ucs4): Move from here ...
	* normal/charset.c (grub_utf8_to_ucs4): ... here.
	* kern/term.c (grub_putcode): Renamed to ...
	(grub_putcode_dumb): ... this. Pass grub_unicode_glyph instead of code.
	(grub_putchar): Removed.
	(grub_xputs_dumb): New function.
	(grub_xputs): New variable.
	* lib/charset.c: Move from here ...
	* normal/charset.c: ... to here.
	(grub_ucs4_to_utf8): New function.
	(grub_ucs4_to_utf8_alloc): Use grub_ucs4_to_utf8.
	(join_types): New variable.
	(unpack_join): New function.
	(bidi_types): New variable.
	(unpack_bidi): New function.
	(get_bidi_type): Likewise.
	(get_join_type): Likewise.
	(is_mirrored): Likewise.
	(grub_unicode_get_comb_type): Likewise.
	(grub_unicode_estimate_width) [HAVE_UNIFONT_WIDTHSPEC]: Likewise.
	(is_type_after): Likewise.
	(grub_unicode_aglomerate_comb): Likewise.
	(bidi_line_wrap): Likewise.
	(grub_bidi_line_logical_to_visual): Likewise.
	(grub_bidi_logical_to_visual): Likewise.
	(grub_unicode_mirror_code): Likewise.
	(grub_unicode_shape_code): Likewise.
	* normal/cmdline.c (grub_cmdline_get): Reset more counter.
	Don't use grub_putchar.
	* normal/main.c (grub_normal_init_page): Use grub_putcode.
	(grub_normal_reader_init): Likewise.
	(grub_xputs_saved): New variable.
	(GRUB_MOD_INIT): Set grub_xputs.
	(GRUB_MOD_FINI): Restore grub_xputs.
	* normal/menu.c (grub_wait_after_message): Don't use grub_putchar.
	(menu_init): Avoid printing gfxmenu error.
	(show_menu): Use grub_normal_get_char_counter.
	* normal/menu_entry.c (update_screen): Fix out-of-array.
	(complete): Avoid NULL dereferencing.
	* grub_menu_entry_run (grub_menu_entry_run): Don't use putchar.
	* normal/menu_text.c (print_spaces): Removed.
	(grub_print_ucs4): Likewise.
	(grub_print_message_indented): Use grub_print_ucs4.
	(print_message): Use grub_putcode.
	(print_entry): Hanlde diacritics.
	* normal/term.c (term_state): New type.
	(grub_more_lines): Removed.
	(term_states): New variable.
	(grub_normal_line_counter): Renamed to ..
	(grub_normal_char_counter): ...this. All users updated.
	(grub_normal_get_line_counter): Renamed to ...
	(grub_normal_get_char_counter): ... this.
	(grub_normal_reset_more): New function.
	(process_newline): Removed.
	(print_more): New function.
	(grub_install_newline_hook): Removed.
	(map_code): New function.
	(grub_puts_terminal): Use grub_print_ucs4.
	(putglyph): New function.
	(putcode_real): Likewise.
	(grub_putcode): Use putcode_real.
	(get_maxwidth): New function.
	(get_startwidth): Likewise.
	(print_ucs4_terminal): Likewise.
	(find_term_state): Likewise.
	(put_glyphs_terminal): Likewise.
	(print_backlog): Likewise.
	(print_ucs4_real): Likewise.
	(grub_print_ucs4): Likewise.
	(grub_xputs_normal): Likewise.
	* term/efi/console.c (grub_console_putchar): Output diacritics.
	(grub_console_getcharwidth): Removed.
	(grub_console_term_output): Declare as GRUB_TERM_CODE_TYPE_UCS4_VISUAL.
	* term/gfxterm.c (clear_char): Free chars.
	(scroll_up): Avoid leaking memory.
	(grub_gfxterm_putchar): Support diacritics.
	(grub_video_term): Declare as GRUB_TERM_CODE_TYPE_UCS4_VISUAL.
	* term/i386/pc/console.c (grub_console_term_output): Declare as
	GRUB_TERM_CODE_TYPE_VGA.
	* term/i386/pc/vga.c (grub_vga_term): Declare as
	GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS.
	* term/i386/pc/vga_text.c (grub_vga_text_term): Declare as
	GRUB_TERM_CODE_TYPE_VGA.
	* term/i386/vga_common.c (map_char): Removed.
	(grub_console_putchar): Likewise.
	(grub_console_getcharwidth): Likewise.
	* term/ieee1275/ofconsole.c: Simplify using terminfo.
	(colors): Reordered to match terminfo.
	(grub_ofconsole_normal_color): Removed.
	(grub_ofconsole_writeesc): Likewise.
	(grub_ofconsole_highlight_color): Likewise.
	(grub_ofconsole_getcharwidth): Likewise.
	(grub_ofconsole_setcolorstate): Likewise.
	(grub_ofconsole_setcolor): Likewise.
	(grub_ofconsole_getcolor): Likewise.
	(grub_ofconsole_readkey): Renamed to ...
	(readkey): ... this. Remove escape sequence handling. Return -1 on no
	key.
	(grub_ofconsole_checkkey): Removed.
	(grub_ofconsole_getkey): Likewise.
	(grub_ofconsole_getxy): Likewise.
	(grub_ofconsole_gotoxy): Likewise.
	(grub_ofconsole_cls): Likewise.
	(grub_ofconsole_refresh): Likewise.
	(grub_ofconsole_terminfo_input): New struct.
	(grub_ofconsole_terminfo_output): Likewise.
	(grub_ofconsole_term_input): Use terminfo.
	(grub_ofconsole_term_output): Likewise.
	(grub_console_init): Split into ...
	(grub_console_init_early): ...this and ...
	(grub_console_init_lately): ...this. Use terminfo.
	(grub_ofconsole_putchar): Renamed to ...
	(put): ... this. Remove mapping.
	(grub_ofconsole_term_output): Declare as GRUB_TERM_CODE_TYPE_ASCII.
	* term/serial.c: Simplify using terminfo.
	(xpos): Removed.
	(ypos): Likewise.
	(keep_track): Likewise.
	(registered): Likewise.
	(input_buf): Likewise.
	(npending): Likewise.
	(serial_translate_key_sequence): Likewise.
	(fill_input_buf): Likewise.
	(grub_serial_checkkey): Likewise.
	(grub_serial_getkey): Likewise.
	(grub_serial_getxy): Likewise.
	(grub_serial_gotoxy): Likewise.
	(grub_serial_putchar): Likewise.
	(grub_serial_cls): Likewise.
	(grub_serial_setcolorstate): Likewise.
	(grub_serial_setcursor): Likewise.
	(serial_hw_init): Use serial_hw_fetch.
	(grub_serial_terminfo_input): New variable.
	(grub_serial_terminfo_output): Likewise.
	(grub_serial_term_input): Use terminfo.
	(grub_serial_term_output): Likewise.
	* term/terminfo.c (putstr): Use put.
	(grub_terminfo_all_free): New function
	(grub_terminfo_set_current): New types vt100-color, ieee1275 and dumb.
	(grub_terminfo_output_register): New function.
	(grub_terminfo_output_unregister): Likewise.
	(grub_terminfo_getxy): Likewise.
	(grub_terminfo_readkey): Likewise.
	(grub_terminfo_checkkey): Likewise.
	(grub_terminfo_getkey): Likewise.
	(grub_terminfo_input_init): Likewise.
	(print_terminfo): Likewise.
	(grub_cmd_terminfo): Handle encoding.
	(grub_terminfo_gotoxy): Track position.
	(grub_terminfo_cls): Likewise.
	(grub_terminfo_putchar): Likewise.
	(grub_terminfo_setcolorstate): Handle colors
	(grub_terminfo_cursor_on): This ...
	(grub_terminfo_cursor_off): ... and this merged into ...
	(grub_terminfo_setcursor): ... this.
	* term/tparm.c (grub_terminfo_tparm): Avoid NULL dereferencing.
	* unicode/ArabicShaping.txt: New file (imported from Unicode).
	* unicode/BidiMirroring.txt: Likewise.
	* unicode/UnicodeData.txt: Likewise.
	* unicode/COPYING: Likewise.
	* util/grub-editenv.c (grub_putchar): Removed.
	(grub_xputs_real): New function.
	(grub_xputs): New variable.
	* util/grub-fstest.c (grub_putchar): Removed.
	(grub_xputs_real): New function.
	(grub_xputs): New variable.
	* util/grub-mkdevicemap.c (grub_putchar): Removed.
	(grub_xputs_real): New function.
	(grub_xputs): New variable.
	* util/grub-probe.c (grub_putchar): Removed.
	(grub_xputs_real): New function.
	(grub_xputs): New variable.
	* util/grub-script-check.c (grub_putchar): Removed.
	(grub_xputs_real): New function.
	(grub_xputs): New variable.
	* util/i386/pc/grub-setup.c (grub_putchar): Removed.
	(grub_xputs_real): New function.
	(grub_xputs): New variable.
	* util/import_unicode.py: New file.
	* util/grub-mkfont.c (ft_errmsgs): New array.
	(grub_glyph_info): Make bitmap a pointer.
	(file_formats): New type WIDTH_SPEC.
	(grub_font_info): New members glyphs_unsorted, glyphs_sorted, num_glyphs.
	(options): Add width-spec.
	(help): Likewise.
	(add_char): Renamed to ...
	(add_glyph): ... this.
	(add_glyph): Use index. Show freetype errors. Cut blank space at borders.
	(glyph_replace): New type.
	(subst_rightjoin), (subst_leftjoin), (subst_medijoin): New variables.
	(add_char): New function.
	(add_subst): Likewise.
	(process_cursive): Likewise.
	(add_font): Handle GSUB.
	(write_font_width_spec): New function.
	(main): Sort glyphs.
	* commands/minicmd.c (grub_mini_cmd_clear): Moved from here ...
	* normal/main.c (grub_mini_cmd_clear): ..here. All users updated.
	* kern/term.c (grub_cls): Moved from here...
	* normal/term.c (grub_cls): ... here.
This commit is contained in:
Vladimir 'phcoder' Serbinenko 2010-07-02 22:16:35 +02:00
commit df3eb88f04
76 changed files with 28013 additions and 2141 deletions

View File

@ -76,3 +76,4 @@ stamp-h.in
symlist.c
trigtables.c
update-grub_lib
unidata.c

317
ChangeLog
View File

@ -1,3 +1,320 @@
2010-07-02 Vladimir Serbinenko <phcoder@gmail.com>
Bidi and diacritics support.
* Makefile.in (widthspec.bin): New target.
(widthspec.h): Likewise.
(TARGET_CFLAGS): Add -DHAVE_UNIFONT_WIDTHSPEC=1 if font was available.
* autogen.sh: Generate unidata.c.
* commands/cat.c (grub_cmd_cat): Don't use grub_putchar.
* commands/ls.c (grub_ls_list_devices): Likewise.
(grub_ls_list_files): Likewise.
* commands/minicmd.c (grub_mini_cmd_cat): Likewise.
(grub_mini_cmd_lsmod): Likewise.
* commands/read.c: Likewise.
* kern/corecmd.c (grub_core_cmd_ls): Likewise.
* kern/rescue_reader.c (grub_rescue_read_line): Likewise.
* lib/arg.c (grub_arg_show_help): Likewise.
* lib/crypto.c (grub_password_get): Likewise.
* normal/auth.c (grub_username_get): Likewise.
* normal/misc.c (grub_normal_print_device_info): Likewise.
* commands/help.c (grub_cmd_help): Use grub_unicode_aglomerate_comb.
* conf/common.rmk (grub_mkfont_SOURCES): Add unidata.c.
(gfxmenu_mod_SOURCES): Add gfxmenu/font.c.
(normal/charset.c_DEPENDENCIES): New variable.
(normal_mod_SOURCES): Add normal/charset.c and unidata.c.
(pkglib_MODULES): Remove charset.mod.
(charset_mod_SOURCES): Removed.
(charset_mod_CFLAGS): Likewise.
(charset_mod_LDFLAGS): Likewise.
(pkglib_MODULES) [ieee1275]: Remove terminfo.mod.
* conf/powerpc-ieee1275.rmk (kernel_img_SOURCES): Add term/terminfo.c
and term/tparm.c.
* conf/sparc64-ieee1275.rmk (kernel_img_SOURCES): Likewise.
* conf/i386-ieee1275.rmk (kernel_img_SOURCES): Likewise.
(kernel_img_HEADERS): Add terminfo.h.
* font/font.c (ascii_glyph_lookup): Return NULL on failure.
Fill ->font. Reverse ascii bitmaps.
(grub_font_get_xheight): New function.
* font/font.c (grub_font_get_string_width): Moved from here ...
* gfxmenu/font.c (grub_font_get_string_width): ... here.
* font/font.c (grub_font_draw_string): Moved from here ...
* gfxmenu/font.c (grub_font_draw_string): ... here.
* font/font.c (grub_font_dup_glyph): New function.
(grub_font_blit_glyph): Likewise.
(grub_font_blit_glyph_mirror): Likewise.
(blit_comb): Likewise.
(grub_font_construct_dry_run): Likewise.
(grub_font_get_constructed_device_width): Likewise.
(grub_font_construct_glyph): Likewise.
* include/grub/charset.h (grub_ucs4_to_utf8): New proto.
* include/grub/misc.h (grub_utf8_to_ucs4): Moved from here ...
* include/grub/charset.h (grub_utf8_to_ucs4): ... here.
* include/grub/font.h (GRUB_FONT_CODE_CHAR_MASK): New constant.
(GRUB_FONT_CODE_RIGHT_JOINED): Likewise.
(GRUB_FONT_CODE_LEFT_JOINED): Likewise.
(grub_font_get_xheight): New proto.
(grub_font_get_constructed_device_width): Likewise.
(grub_font_construct_glyph): Likewise.
* include/grub/font.h (grub_font_get_string_width): Moved from here ...
* include/grub/gfxmenu_view.h (grub_font_get_string_width): ... here.
* include/grub/font.h (grub_font_draw_string): Moved from here ...
* include/grub/gfxmenu_view.h (grub_font_draw_string): ... here.
* include/grub/i386/vga_common.h (grub_console_putchar): Moved from here..
* include/grub/i386/pc/console.h (grub_console_putchar): ... here.
* include/grub/i386/vga_common.h (grub_console_real_putchar): Removed.
(grub_console_getcharwidth): Likewise.
* include/grub/misc.h (grub_xputs): New proto.
(grub_puts): Inlined.
* include/grub/normal.h (grub_print_ucs4): Add margin specification.
(grub_normal_get_line_counter): Removed.
(grub_install_newline_hook): Likewise.
(grub_normal_get_char_counter): New proto.
(grub_normal_reset_more): Likewise.
(grub_xputs_normal): Likewise.
* include/grub/powerpc/ieee1275/console.h: Removed.
* include/grub/sparc64/ieee1275/console.h: Likewise.
* include/grub/term.h (GRUB_TERM_CODE_TYPE_MASK): New definition.
(GRUB_TERM_CODE_TYPE_ASCII): Likewise.
(GRUB_TERM_CODE_TYPE_CP437): Likewise.
(GRUB_TERM_CODE_TYPE_UTF8_LOGICAL): Likewise.
(GRUB_TERM_CODE_TYPE_UTF8_VISUAL): Likewise.
(GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS): Likewise.
(grub_term_input): Pass reference to self. All users updated.
(grub_term_output): Pass grub_unicode_glyph to putchar and getcharwidth.
Pass reference to self. New fields normal_color, highlight_color and
data. All users updated.
(grub_putchar): Removed.
(grub_putcode): Remove EXPORT_FUNC since it's not in kernel anymore.
(grub_unicode_estimate_width): New function.
(grub_term_getcharwidth): Add defaults.
(GRUB_TERM_DEFAULT_NORMAL_COLOR): New definition.
(GRUB_TERM_DEFAULT_HIGHLIGHT_COLOR): Likewise.
(GRUB_TERM_DEFAULT_STANDARD_COLOR): Likewise.
(grub_cls): Remove EXPORT_FUNC.
(grub_setcolorstate): Inline.
(grub_newline_hook): Removed.
* include/grub/terminfo.h: Rewritten. All users updated.
* include/grub/unicode.h: New file.
* include/grub/video.h (grub_video_signed_rect): New type.
* kern/emu/console.c (grub_console_highlight_color): Removed.
(grub_console_normal_color): Likewise.
(grub_console_standard_color): Made static.
(grub_ncurses_putchar): Remove mapping.
(grub_ncurses_getcharwidth): Removed.
(grub_ncurses_term_output): Declare as GRUB_TERM_CODE_TYPE_ASCII.
(grub_ncurses_setcolor): Removed.
(grub_ncurses_getcolor): Likewise.
* kern/i386/pc/startup.S (grub_console_real_putchar): Renamed to ...
(grub_console_putchar): ... this.
(grub_console_putchar): Handle argument difference.
* kern/ieee1275/init.c (grub_machine_init): Split console_init into
console_init_early and console_init_lately.
* kern/sparc64/ieee1275/init.c (grub_machine_init): Likewise.
* kern/misc.c (grub_puts): Removed.
(grub_vprintf): Store UTF-8 string instead of outputting it directly.
(grub_vsnprintf_real): Remove str = NULL support.
* kern/misc.c (grub_utf8_to_ucs4): Move from here ...
* normal/charset.c (grub_utf8_to_ucs4): ... here.
* kern/term.c (grub_putcode): Renamed to ...
(grub_putcode_dumb): ... this. Pass grub_unicode_glyph instead of code.
(grub_putchar): Removed.
(grub_xputs_dumb): New function.
(grub_xputs): New variable.
* lib/charset.c: Move from here ...
* normal/charset.c: ... to here.
(grub_ucs4_to_utf8): New function.
(grub_ucs4_to_utf8_alloc): Use grub_ucs4_to_utf8.
(join_types): New variable.
(unpack_join): New function.
(bidi_types): New variable.
(unpack_bidi): New function.
(get_bidi_type): Likewise.
(get_join_type): Likewise.
(is_mirrored): Likewise.
(grub_unicode_get_comb_type): Likewise.
(grub_unicode_estimate_width) [HAVE_UNIFONT_WIDTHSPEC]: Likewise.
(is_type_after): Likewise.
(grub_unicode_aglomerate_comb): Likewise.
(bidi_line_wrap): Likewise.
(grub_bidi_line_logical_to_visual): Likewise.
(grub_bidi_logical_to_visual): Likewise.
(grub_unicode_mirror_code): Likewise.
(grub_unicode_shape_code): Likewise.
* normal/cmdline.c (grub_cmdline_get): Reset more counter.
Don't use grub_putchar.
* normal/main.c (grub_normal_init_page): Use grub_putcode.
(grub_normal_reader_init): Likewise.
(grub_xputs_saved): New variable.
(GRUB_MOD_INIT): Set grub_xputs.
(GRUB_MOD_FINI): Restore grub_xputs.
* normal/menu.c (grub_wait_after_message): Don't use grub_putchar.
(menu_init): Avoid printing gfxmenu error.
(show_menu): Use grub_normal_get_char_counter.
* normal/menu_entry.c (update_screen): Fix out-of-array.
(complete): Avoid NULL dereferencing.
* grub_menu_entry_run (grub_menu_entry_run): Don't use putchar.
* normal/menu_text.c (print_spaces): Removed.
(grub_print_ucs4): Likewise.
(grub_print_message_indented): Use grub_print_ucs4.
(print_message): Use grub_putcode.
(print_entry): Hanlde diacritics.
* normal/term.c (term_state): New type.
(grub_more_lines): Removed.
(term_states): New variable.
(grub_normal_line_counter): Renamed to ..
(grub_normal_char_counter): ...this. All users updated.
(grub_normal_get_line_counter): Renamed to ...
(grub_normal_get_char_counter): ... this.
(grub_normal_reset_more): New function.
(process_newline): Removed.
(print_more): New function.
(grub_install_newline_hook): Removed.
(map_code): New function.
(grub_puts_terminal): Use grub_print_ucs4.
(putglyph): New function.
(putcode_real): Likewise.
(grub_putcode): Use putcode_real.
(get_maxwidth): New function.
(get_startwidth): Likewise.
(print_ucs4_terminal): Likewise.
(find_term_state): Likewise.
(put_glyphs_terminal): Likewise.
(print_backlog): Likewise.
(print_ucs4_real): Likewise.
(grub_print_ucs4): Likewise.
(grub_xputs_normal): Likewise.
* term/efi/console.c (grub_console_putchar): Output diacritics.
(grub_console_getcharwidth): Removed.
(grub_console_term_output): Declare as GRUB_TERM_CODE_TYPE_UCS4_VISUAL.
* term/gfxterm.c (clear_char): Free chars.
(scroll_up): Avoid leaking memory.
(grub_gfxterm_putchar): Support diacritics.
(grub_video_term): Declare as GRUB_TERM_CODE_TYPE_UCS4_VISUAL.
* term/i386/pc/console.c (grub_console_term_output): Declare as
GRUB_TERM_CODE_TYPE_VGA.
* term/i386/pc/vga.c (grub_vga_term): Declare as
GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS.
* term/i386/pc/vga_text.c (grub_vga_text_term): Declare as
GRUB_TERM_CODE_TYPE_VGA.
* term/i386/vga_common.c (map_char): Removed.
(grub_console_putchar): Likewise.
(grub_console_getcharwidth): Likewise.
* term/ieee1275/ofconsole.c: Simplify using terminfo.
(colors): Reordered to match terminfo.
(grub_ofconsole_normal_color): Removed.
(grub_ofconsole_writeesc): Likewise.
(grub_ofconsole_highlight_color): Likewise.
(grub_ofconsole_getcharwidth): Likewise.
(grub_ofconsole_setcolorstate): Likewise.
(grub_ofconsole_setcolor): Likewise.
(grub_ofconsole_getcolor): Likewise.
(grub_ofconsole_readkey): Renamed to ...
(readkey): ... this. Remove escape sequence handling. Return -1 on no
key.
(grub_ofconsole_checkkey): Removed.
(grub_ofconsole_getkey): Likewise.
(grub_ofconsole_getxy): Likewise.
(grub_ofconsole_gotoxy): Likewise.
(grub_ofconsole_cls): Likewise.
(grub_ofconsole_refresh): Likewise.
(grub_ofconsole_terminfo_input): New struct.
(grub_ofconsole_terminfo_output): Likewise.
(grub_ofconsole_term_input): Use terminfo.
(grub_ofconsole_term_output): Likewise.
(grub_console_init): Split into ...
(grub_console_init_early): ...this and ...
(grub_console_init_lately): ...this. Use terminfo.
(grub_ofconsole_putchar): Renamed to ...
(put): ... this. Remove mapping.
(grub_ofconsole_term_output): Declare as GRUB_TERM_CODE_TYPE_ASCII.
* term/serial.c: Simplify using terminfo.
(xpos): Removed.
(ypos): Likewise.
(keep_track): Likewise.
(registered): Likewise.
(input_buf): Likewise.
(npending): Likewise.
(serial_translate_key_sequence): Likewise.
(fill_input_buf): Likewise.
(grub_serial_checkkey): Likewise.
(grub_serial_getkey): Likewise.
(grub_serial_getxy): Likewise.
(grub_serial_gotoxy): Likewise.
(grub_serial_putchar): Likewise.
(grub_serial_cls): Likewise.
(grub_serial_setcolorstate): Likewise.
(grub_serial_setcursor): Likewise.
(serial_hw_init): Use serial_hw_fetch.
(grub_serial_terminfo_input): New variable.
(grub_serial_terminfo_output): Likewise.
(grub_serial_term_input): Use terminfo.
(grub_serial_term_output): Likewise.
* term/terminfo.c (putstr): Use put.
(grub_terminfo_all_free): New function
(grub_terminfo_set_current): New types vt100-color, ieee1275 and dumb.
(grub_terminfo_output_register): New function.
(grub_terminfo_output_unregister): Likewise.
(grub_terminfo_getxy): Likewise.
(grub_terminfo_readkey): Likewise.
(grub_terminfo_checkkey): Likewise.
(grub_terminfo_getkey): Likewise.
(grub_terminfo_input_init): Likewise.
(print_terminfo): Likewise.
(grub_cmd_terminfo): Handle encoding.
(grub_terminfo_gotoxy): Track position.
(grub_terminfo_cls): Likewise.
(grub_terminfo_putchar): Likewise.
(grub_terminfo_setcolorstate): Handle colors
(grub_terminfo_cursor_on): This ...
(grub_terminfo_cursor_off): ... and this merged into ...
(grub_terminfo_setcursor): ... this.
* term/tparm.c (grub_terminfo_tparm): Avoid NULL dereferencing.
* unicode/ArabicShaping.txt: New file (imported from Unicode).
* unicode/BidiMirroring.txt: Likewise.
* unicode/UnicodeData.txt: Likewise.
* unicode/COPYING: Likewise.
* util/grub-editenv.c (grub_putchar): Removed.
(grub_xputs_real): New function.
(grub_xputs): New variable.
* util/grub-fstest.c (grub_putchar): Removed.
(grub_xputs_real): New function.
(grub_xputs): New variable.
* util/grub-mkdevicemap.c (grub_putchar): Removed.
(grub_xputs_real): New function.
(grub_xputs): New variable.
* util/grub-probe.c (grub_putchar): Removed.
(grub_xputs_real): New function.
(grub_xputs): New variable.
* util/grub-script-check.c (grub_putchar): Removed.
(grub_xputs_real): New function.
(grub_xputs): New variable.
* util/i386/pc/grub-setup.c (grub_putchar): Removed.
(grub_xputs_real): New function.
(grub_xputs): New variable.
* util/import_unicode.py: New file.
* util/grub-mkfont.c (ft_errmsgs): New array.
(grub_glyph_info): Make bitmap a pointer.
(file_formats): New type WIDTH_SPEC.
(grub_font_info): New members glyphs_unsorted, glyphs_sorted, num_glyphs.
(options): Add width-spec.
(help): Likewise.
(add_char): Renamed to ...
(add_glyph): ... this.
(add_glyph): Use index. Show freetype errors. Cut blank space at borders.
(glyph_replace): New type.
(subst_rightjoin), (subst_leftjoin), (subst_medijoin): New variables.
(add_char): New function.
(add_subst): Likewise.
(process_cursive): Likewise.
(add_font): Handle GSUB.
(write_font_width_spec): New function.
(main): Sort glyphs.
* commands/minicmd.c (grub_mini_cmd_clear): Moved from here ...
* normal/main.c (grub_mini_cmd_clear): ..here. All users updated.
* kern/term.c (grub_cls): Moved from here...
* normal/term.c (grub_cls): ... here.
2010-07-02 Colin Watson <cjwatson@ubuntu.com>
* include/grub/types.h: Define the C99-style PRIxGRUB_SIZE macro,

View File

@ -275,7 +275,13 @@ ascii.bitmaps: $(FONT_SOURCE) grub-mkfont
ascii.h: ascii.bitmaps grub-bin2h
$(builddir)/grub-bin2h ascii_bitmaps < $< > $@
TARGET_CFLAGS += -DUSE_ASCII_FAILBACK=1
widthspec.bin: $(FONT_SOURCE) grub-mkfont
$(builddir)/grub-mkfont --width-spec -o $@ $(FONT_SOURCE)
widthspec.h: widthspec.bin grub-bin2h
$(builddir)/grub-bin2h widthspec < $< > $@
TARGET_CFLAGS += -DUSE_ASCII_FAILBACK=1 -DHAVE_UNIFONT_WIDTHSPEC=1
endif
endif

View File

@ -13,6 +13,8 @@ echo timestamp > stamp-h.in
python util/import_gcry.py lib/libgcrypt/ .
python util/import_unicode.py unicode/UnicodeData.txt unicode/BidiMirroring.txt unicode/ArabicShaping.txt unidata.c
for rmk in conf/*.rmk ${GRUB_CONTRIB}/*/conf/*.rmk; do
if test -e $rmk ; then
ruby genmk.rb < $rmk > `echo $rmk | sed 's/\.rmk$/.mk/'`

View File

@ -62,10 +62,10 @@ grub_cmd_cat (grub_extcmd_t cmd, int argc, char **args)
unsigned char c = buf[i];
if ((grub_isprint (c) || grub_isspace (c)) && c != '\r')
grub_putchar (c);
grub_printf ("%c", c);
else if (dos && c == '\r' && i + 1 < size && buf[i + 1] == '\n')
{
grub_putchar ('\n');
grub_printf ("\n");
i++;
}
else
@ -81,7 +81,7 @@ grub_cmd_cat (grub_extcmd_t cmd, int argc, char **args)
;
}
grub_putchar ('\n');
grub_xputs ("\n");
grub_refresh ();
grub_file_close (file);

View File

@ -66,18 +66,24 @@ grub_cmd_help (grub_extcmd_t ext __attribute__ ((unused)), int argc,
while (unicode_last_screen_position < unicode_last_position &&
stringwidth < ((grub_term_width (term) / 2) - 2))
{
struct grub_unicode_glyph glyph;
unicode_last_screen_position
+= grub_unicode_aglomerate_comb (unicode_last_screen_position,
unicode_last_position
- unicode_last_screen_position,
&glyph);
stringwidth
+= grub_term_getcharwidth (term,
*unicode_last_screen_position);
unicode_last_screen_position++;
+= grub_term_getcharwidth (term, &glyph);
}
grub_print_ucs4 (unicode_command_help,
unicode_last_screen_position, term);
unicode_last_screen_position, 0, 0, term);
if (!(cnt % 2))
grub_print_spaces (term, grub_term_width (term) / 2
- stringwidth);
}
if (cnt % 2)
grub_printf ("\n");
cnt++;

View File

@ -57,7 +57,7 @@ grub_ls_list_devices (int longlist)
}
grub_device_iterate (grub_ls_print_devices);
grub_putchar ('\n');
grub_xputs ("\n");
grub_refresh ();
return 0;
@ -233,7 +233,7 @@ grub_ls_list_files (char *dirname, int longlist, int all, int human)
}
if (grub_errno == GRUB_ERR_NONE)
grub_putchar ('\n');
grub_xputs ("\n");
grub_refresh ();
}

View File

@ -54,7 +54,7 @@ grub_mini_cmd_cat (struct grub_command *cmd __attribute__ ((unused)),
unsigned char c = buf[i];
if ((grub_isprint (c) || grub_isspace (c)) && c != '\r')
grub_putchar (c);
grub_printf ("%c", c);
else
{
grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT);
@ -64,7 +64,7 @@ grub_mini_cmd_cat (struct grub_command *cmd __attribute__ ((unused)),
}
}
grub_putchar ('\n');
grub_xputs ("\n");
grub_refresh ();
grub_file_close (file);
@ -312,11 +312,11 @@ grub_mini_cmd_lsmod (struct grub_command *cmd __attribute__ ((unused)),
for (dep = mod->dep; dep; dep = dep->next)
{
if (dep != mod->dep)
grub_putchar (',');
grub_xputs (",");
grub_printf ("%s", dep->mod->name);
}
grub_putchar ('\n');
grub_xputs ("\n");
}
return 0;
@ -332,19 +332,8 @@ grub_mini_cmd_exit (struct grub_command *cmd __attribute__ ((unused)),
return 0;
}
/* clear */
static grub_err_t
grub_mini_cmd_clear (struct grub_command *cmd __attribute__ ((unused)),
int argc __attribute__ ((unused)),
char *argv[] __attribute__ ((unused)))
{
grub_cls ();
return 0;
}
static grub_command_t cmd_cat, cmd_help, cmd_root;
static grub_command_t cmd_dump, cmd_rmmod, cmd_lsmod, cmd_exit;
static grub_command_t cmd_clear;
GRUB_MOD_INIT(minicmd)
{
@ -369,9 +358,6 @@ GRUB_MOD_INIT(minicmd)
cmd_exit =
grub_register_command ("exit", grub_mini_cmd_exit,
0, N_("Exit from GRUB."));
cmd_clear =
grub_register_command ("clear", grub_mini_cmd_clear,
0, N_("Clear the screen."));
}
GRUB_MOD_FINI(minicmd)
@ -383,5 +369,4 @@ GRUB_MOD_FINI(minicmd)
grub_unregister_command (cmd_rmmod);
grub_unregister_command (cmd_lsmod);
grub_unregister_command (cmd_exit);
grub_unregister_command (cmd_clear);
}

View File

@ -47,7 +47,7 @@ grub_getline (void)
line[i] = c;
if (grub_isprint (c))
grub_putchar (c);
grub_printf ("%c", c);
i++;
tmp = grub_realloc (line, 1 + i + sizeof('\0'));
if (! tmp)

View File

@ -30,8 +30,8 @@ struct abstract_terminal
{
struct abstract_terminal *next;
const char *name;
grub_err_t (*init) (void);
grub_err_t (*fini) (void);
grub_err_t (*init) (struct abstract_terminal *term);
grub_err_t (*fini) (struct abstract_terminal *term);
};
static grub_err_t
@ -123,7 +123,7 @@ handle_command (int argc, char **args, struct abstract_terminal **enabled,
break;
if (term)
{
if (term->init && term->init () != GRUB_ERR_NONE)
if (term->init && term->init (term) != GRUB_ERR_NONE)
return grub_errno;
grub_list_remove (GRUB_AS_LIST_P (disabled), GRUB_AS_LIST (term));
@ -147,7 +147,7 @@ handle_command (int argc, char **args, struct abstract_terminal **enabled,
"can't remove the last terminal");
grub_list_remove (GRUB_AS_LIST_P (enabled), GRUB_AS_LIST (term));
if (term->fini)
term->fini ();
term->fini (term);
grub_list_push (GRUB_AS_LIST_P (disabled), GRUB_AS_LIST (term));
}
}
@ -160,7 +160,7 @@ handle_command (int argc, char **args, struct abstract_terminal **enabled,
break;
if (term)
{
if (term->init && term->init () != GRUB_ERR_NONE)
if (term->init && term->init (term) != GRUB_ERR_NONE)
return grub_errno;
grub_list_remove (GRUB_AS_LIST_P (disabled), GRUB_AS_LIST (term));
@ -183,7 +183,7 @@ handle_command (int argc, char **args, struct abstract_terminal **enabled,
"can't remove the last terminal");
grub_list_remove (GRUB_AS_LIST_P (enabled), GRUB_AS_LIST (term));
if (term->fini)
term->fini ();
term->fini (term);
grub_list_push (GRUB_AS_LIST_P (disabled), GRUB_AS_LIST (term));
}
}

View File

@ -25,6 +25,7 @@
#include <grub/term.h>
#include <grub/command.h>
#include <grub/i18n.h>
#include <grub/gfxmenu_view.h>
static grub_err_t
grub_cmd_videotest (grub_command_t cmd __attribute__ ((unused)),

View File

@ -69,7 +69,8 @@ grub_fstest_SOURCES = gnulib/progname.c util/grub-fstest.c kern/emu/hostfs.c \
# For grub-mkfont.
ifeq ($(enable_grub_mkfont), yes)
bin_UTILITIES += grub-mkfont
grub_mkfont_SOURCES = gnulib/progname.c util/grub-mkfont.c util/misc.c kern/emu/misc.c
grub_mkfont_SOURCES = gnulib/progname.c util/grub-mkfont.c util/misc.c \
unidata.c kern/emu/misc.c
grub_mkfont_CFLAGS = $(freetype_cflags)
grub_mkfont_LDFLAGS = $(freetype_libs)
endif
@ -441,7 +442,7 @@ scsi_mod_LDFLAGS = $(COMMON_LDFLAGS)
pkglib_MODULES += minicmd.mod extcmd.mod hello.mod \
ls.mod cmp.mod cat.mod help.mod search.mod loopback.mod \
configfile.mod echo.mod \
terminfo.mod test.mod blocklist.mod hexdump.mod \
test.mod blocklist.mod hexdump.mod \
read.mod sleep.mod loadenv.mod crc.mod parttool.mod \
msdospart.mod memrw.mod normal.mod \
gptsync.mod true.mod probe.mod password.mod \
@ -490,7 +491,8 @@ gfxmenu_mod_SOURCES = \
gfxmenu/gui_progress_bar.c \
gfxmenu/gui_util.c \
gfxmenu/gui_string_util.c \
gfxmenu/named_colors.c
gfxmenu/named_colors.c \
gfxmenu/font.c
gfxmenu_mod_CFLAGS = $(COMMON_CFLAGS)
gfxmenu_mod_LDFLAGS = $(COMMON_LDFLAGS)
@ -566,10 +568,13 @@ configfile_mod_SOURCES = commands/configfile.c
configfile_mod_CFLAGS = $(COMMON_CFLAGS)
configfile_mod_LDFLAGS = $(COMMON_LDFLAGS)
ifneq ($(platform), ieee1275)
# For terminfo.mod.
pkglib_MODULES += terminfo.mod
terminfo_mod_SOURCES = term/terminfo.c term/tparm.c
terminfo_mod_CFLAGS = $(COMMON_CFLAGS)
terminfo_mod_LDFLAGS = $(COMMON_LDFLAGS)
endif
# For blocklist.mod.
blocklist_mod_SOURCES = commands/blocklist.c
@ -622,12 +627,15 @@ keystatus_mod_CFLAGS = $(COMMON_CFLAGS)
keystatus_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For normal.mod.
ifneq (, $(FONT_SOURCE))
normal/charset.c_DEPENDENCIES = widthspec.h
endif
normal_mod_SOURCES = normal/main.c normal/cmdline.c normal/dyncmd.c \
normal/auth.c normal/autofs.c \
normal/color.c normal/completion.c normal/datetime.c normal/menu.c \
normal/menu_entry.c normal/menu_text.c \
normal/menu_entry.c normal/menu_text.c normal/charset.c \
normal/misc.c normal/crypto.c normal/term.c normal/context.c \
script/main.c script/script.c script/execute.c \
script/main.c script/script.c script/execute.c unidata.c \
script/function.c script/lexer.c grub_script.tab.c grub_script.yy.c
normal_mod_CFLAGS = $(COMMON_CFLAGS) $(POSIX_CFLAGS) -Wno-error
normal_mod_LDFLAGS = $(COMMON_LDFLAGS)
@ -701,7 +709,6 @@ png_mod_SOURCES = video/readers/png.c
png_mod_CFLAGS = $(COMMON_CFLAGS)
png_mod_LDFLAGS = $(COMMON_LDFLAGS)
# Misc.
pkglib_MODULES += gzio.mod elf.mod
@ -755,11 +762,6 @@ setjmp_mod_SOURCES = lib/$(target_cpu)/setjmp.S
setjmp_mod_ASFLAGS = $(COMMON_ASFLAGS)
setjmp_mod_LDFLAGS = $(COMMON_LDFLAGS)
pkglib_MODULES += charset.mod
charset_mod_SOURCES = lib/charset.c
charset_mod_CFLAGS = $(COMMON_CFLAGS)
charset_mod_LDFLAGS = $(COMMON_LDFLAGS)
pkglib_MODULES += regexp.mod
regexp_mod_SOURCES = gnulib/regex.c commands/regexp.c
regexp_mod_CFLAGS = $(COMMON_CFLAGS) $(GNULIB_CFLAGS)

View File

@ -22,9 +22,10 @@ kernel_img_SOURCES = kern/i386/ieee1275/startup.S \
kern/generic/millisleep.c \
kern/ieee1275/ieee1275.c \
term/ieee1275/ofconsole.c \
term/terminfo.c term/tparm.c \
disk/ieee1275/ofdisk.c \
symlist.c
kernel_img_HEADERS += ieee1275/ieee1275.h
kernel_img_HEADERS += ieee1275/ieee1275.h terminfo.h
kernel_img_CFLAGS = $(COMMON_CFLAGS)
kernel_img_ASFLAGS = $(COMMON_ASFLAGS)
kernel_img_LDFLAGS += $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,0x10000,-Bstatic

View File

@ -16,7 +16,7 @@ kernel_img_SOURCES = kern/powerpc/ieee1275/startup.S kern/ieee1275/cmain.c \
kern/list.c kern/command.c kern/corecmd.c \
kern/ieee1275/init.c \
kern/ieee1275/mmap.c \
term/ieee1275/ofconsole.c \
term/ieee1275/ofconsole.c term/terminfo.c term/tparm.c \
kern/ieee1275/openfw.c disk/ieee1275/ofdisk.c \
kern/parser.c kern/partition.c kern/env.c kern/$(target_cpu)/dl.c \
kern/generic/millisleep.c kern/time.c \

View File

@ -31,7 +31,8 @@ kernel_img_SOURCES = kern/sparc64/ieee1275/crt0.S kern/ieee1275/cmain.c \
kern/sparc64/ieee1275/init.c \
kern/ieee1275/mmap.c \
term/ieee1275/ofconsole.c \
kern/ieee1275/openfw.c disk/ieee1275/ofdisk.c \
kern/ieee1275/openfw.c term/terminfo.c term/tparm.c \
disk/ieee1275/ofdisk.c \
kern/parser.c kern/partition.c kern/env.c kern/$(target_cpu)/dl.c \
kern/generic/millisleep.c kern/time.c \
symlist.c kern/$(target_cpu)/cache.S

View File

@ -26,6 +26,8 @@
#include <grub/types.h>
#include <grub/video.h>
#include <grub/bitmap.h>
#include <grub/charset.h>
#include <grub/unicode.h>
#include <grub/fontformat.h>
#ifdef USE_ASCII_FAILBACK
@ -92,7 +94,7 @@ struct font_file_section
/* Replace unknown glyphs with a rounded question mark. */
static grub_uint8_t unknown_glyph_bitmap[] = {
/* 76543210 */
/* 76543210 */
0x7C, /* ooooo */
0x82, /* o o */
0xBA, /* o ooo o */
@ -133,7 +135,7 @@ ascii_glyph_lookup (grub_uint32_t code)
static int ascii_failback_initialized = 0;
if (code >= 0x80)
return unknown_glyph;
return NULL;
if (ascii_failback_initialized == 0)
{
@ -148,9 +150,10 @@ ascii_glyph_lookup (grub_uint32_t code)
ascii_font_glyph[current]->offset_x = 0;
ascii_font_glyph[current]->offset_y = -2;
ascii_font_glyph[current]->device_width = 8;
ascii_font_glyph[current]->font = NULL;
grub_memcpy (ascii_font_glyph[current]->bitmap,
&ascii_bitmaps[(0x7f - current) * ASCII_BITMAP_SIZE],
&ascii_bitmaps[current * ASCII_BITMAP_SIZE],
ASCII_BITMAP_SIZE);
}
@ -160,7 +163,7 @@ ascii_glyph_lookup (grub_uint32_t code)
return ascii_font_glyph[code];
#else
(void) code;
return unknown_glyph;
return NULL;
#endif
}
@ -900,6 +903,13 @@ grub_font_get_descent (grub_font_t font)
return font->descent;
}
/* FIXME: not correct for all fonts. */
int
grub_font_get_xheight (grub_font_t font)
{
return font->ascent / 2;
}
/* Get the *standard leading* of the font in pixel, which is the spacing
between two lines of text. Specifically, it is the space between the
descent of one line and the ascent of the next line. This is included
@ -917,27 +927,6 @@ grub_font_get_height (grub_font_t font)
return font->ascent + font->descent + font->leading;
}
/* Get the width in pixels of the specified UTF-8 string, when rendered in
in the specified font (but falling back on other fonts for glyphs that
are missing). */
int
grub_font_get_string_width (grub_font_t font, const char *str)
{
int width;
struct grub_font_glyph *glyph;
grub_uint32_t code;
const grub_uint8_t *ptr;
for (ptr = (const grub_uint8_t *) str, width = 0;
grub_utf8_to_ucs4 (&code, 1, ptr, -1, &ptr) > 0;)
{
glyph = grub_font_get_glyph_with_fallback (font, code);
width += glyph->device_width;
}
return width;
}
/* Get the glyph for FONT corresponding to the Unicode code point CODE.
Returns the ASCII glyph for the code if no other fonts are available.
The glyphs are cached once loaded. */
@ -1044,13 +1033,457 @@ grub_font_get_glyph_with_fallback (grub_font_t font, grub_uint32_t code)
}
}
if (best_glyph)
return best_glyph;
else
/* Glyph not available in any font. Return ASCII failback. */
return ascii_glyph_lookup (code);
return best_glyph;
}
static struct grub_font_glyph *
grub_font_dup_glyph (struct grub_font_glyph *glyph)
{
static struct grub_font_glyph *ret;
ret = grub_malloc (sizeof (*ret) + (glyph->width * glyph->height + 7) / 8);
if (!ret)
return NULL;
grub_memcpy (ret, glyph, sizeof (*ret)
+ (glyph->width * glyph->height + 7) / 8);
return ret;
}
/* FIXME: suboptimal. */
static void
grub_font_blit_glyph (struct grub_font_glyph *target,
struct grub_font_glyph *src, unsigned dx, unsigned dy)
{
unsigned src_bit, tgt_bit, src_byte, tgt_byte;
unsigned i, j;
for (i = 0; i < src->height; i++)
{
src_bit = (src->width * i) % 8;
src_byte = (src->width * i) / 8;
tgt_bit = (target->width * (dy + i) + dx) % 8;
tgt_byte = (target->width * (dy + i) + dx) / 8;
for (j = 0; j < src->width; j++)
{
target->bitmap[tgt_byte] |= ((src->bitmap[src_byte] << src_bit)
& 0x80) >> tgt_bit;
src_bit++;
tgt_bit++;
if (src_bit == 8)
{
src_byte++;
src_bit = 0;
}
if (tgt_bit == 8)
{
tgt_byte++;
tgt_bit = 0;
}
}
}
}
static void
grub_font_blit_glyph_mirror (struct grub_font_glyph *target,
struct grub_font_glyph *src,
unsigned dx, unsigned dy)
{
unsigned tgt_bit, src_byte, tgt_byte;
signed src_bit;
unsigned i, j;
for (i = 0; i < src->height; i++)
{
src_bit = (src->width * i + src->width - 1) % 8;
src_byte = (src->width * i + src->width - 1) / 8;
tgt_bit = (target->width * (dy + i) + dx) % 8;
tgt_byte = (target->width * (dy + i) + dx) / 8;
for (j = 0; j < src->width; j++)
{
target->bitmap[tgt_byte] |= ((src->bitmap[src_byte] << src_bit)
& 0x80) >> tgt_bit;
src_bit--;
tgt_bit++;
if (src_bit == -1)
{
src_byte--;
src_bit = 7;
}
if (tgt_bit == 8)
{
tgt_byte++;
tgt_bit = 0;
}
}
}
}
static void
blit_comb (const struct grub_unicode_glyph *glyph_id,
struct grub_font_glyph *glyph,
struct grub_video_signed_rect *bounds_out,
struct grub_font_glyph *main_glyph,
struct grub_font_glyph **combining_glyphs, int *device_width)
{
struct grub_video_signed_rect bounds;
unsigned i;
signed above_rightx, above_righty;
signed above_leftx, above_lefty;
signed below_rightx, below_righty;
signed min_devwidth = 0;
auto void NESTED_FUNC_ATTR do_blit (struct grub_font_glyph *src,
signed dx, signed dy);
void NESTED_FUNC_ATTR do_blit (struct grub_font_glyph *src,
signed dx, signed dy)
{
if (glyph)
grub_font_blit_glyph (glyph, src, dx - glyph->offset_x,
(glyph->height + glyph->offset_y) + dy);
if (dx < bounds.x)
{
bounds.width += bounds.x - dx;
bounds.x = dx;
}
if (bounds.y > -src->height - dy)
{
bounds.height += bounds.y - (-src->height - dy);
bounds.y = (-src->height - dy);
}
if (dx + src->width - bounds.x >= (signed) bounds.width)
bounds.width = dx + src->width - bounds.x + 1;
if ((signed) bounds.height < src->height + (-src->height - dy) - bounds.y)
bounds.height = src->height + (-src->height - dy) - bounds.y;
}
auto void add_device_width (int val);
void add_device_width (int val)
{
if (glyph)
glyph->device_width += val;
if (device_width)
*device_width += val;
}
if (glyph)
glyph->device_width = main_glyph->device_width;
if (device_width)
*device_width = main_glyph->device_width;
bounds.x = main_glyph->offset_x;
bounds.y = main_glyph->offset_y;
bounds.width = main_glyph->width;
bounds.height = main_glyph->height;
above_rightx = main_glyph->offset_x + main_glyph->width;
above_righty = bounds.y + bounds.height;
above_leftx = main_glyph->offset_x;
above_lefty = bounds.y + bounds.height;
below_rightx = bounds.x + bounds.width;
below_righty = bounds.y;
for (i = 0; i < glyph_id->ncomb; i++)
{
grub_int16_t space = 0;
/* Center by default. */
grub_int16_t targetx;
if (!combining_glyphs[i])
continue;
targetx = (bounds.width - combining_glyphs[i]->width) / 2 + bounds.x;
/* CGJ is to avoid diacritics reordering. */
if (glyph_id->combining[i].code
== GRUB_UNICODE_COMBINING_GRAPHEME_JOINER)
continue;
switch (glyph_id->combining[i].type)
{
case GRUB_UNICODE_COMB_OVERLAY:
do_blit (combining_glyphs[i],
targetx,
(bounds.height - combining_glyphs[i]->height) / 2
- (bounds.height + bounds.y));
if (min_devwidth < combining_glyphs[i]->width)
min_devwidth = combining_glyphs[i]->width;
break;
case GRUB_UNICODE_COMB_ATTACHED_ABOVE_RIGHT:
do_blit (combining_glyphs[i], above_rightx, -above_righty);
above_rightx += combining_glyphs[i]->width;
break;
case GRUB_UNICODE_COMB_ABOVE_RIGHT:
do_blit (combining_glyphs[i], above_rightx,
-(above_righty + combining_glyphs[i]->height));
above_rightx += combining_glyphs[i]->width;
break;
case GRUB_UNICODE_COMB_ABOVE_LEFT:
above_leftx -= combining_glyphs[i]->width;
do_blit (combining_glyphs[i], above_leftx,
-(above_lefty + combining_glyphs[i]->height));
break;
case GRUB_UNICODE_COMB_BELOW_RIGHT:
do_blit (combining_glyphs[i], below_rightx, below_righty);
below_rightx += combining_glyphs[i]->width;
break;
case GRUB_UNICODE_COMB_HEBREW_HOLAM:
if (glyph_id->base != GRUB_UNICODE_HEBREW_WAW)
targetx =
main_glyph->offset_x - combining_glyphs[i]->width -
(combining_glyphs[i]->width + 3) / 4;
goto above_on_main;
case GRUB_UNICODE_COMB_HEBREW_SIN_DOT:
targetx = main_glyph->offset_x + combining_glyphs[i]->width / 4;
goto above_on_main;
case GRUB_UNICODE_COMB_HEBREW_SHIN_DOT:
targetx =
main_glyph->width + main_glyph->offset_x -
combining_glyphs[i]->width;
above_on_main:
space = combining_glyphs[i]->offset_y
- grub_font_get_xheight (combining_glyphs[i]->font) - 1;
if (space <= 0)
space = 1 + (grub_font_get_xheight (main_glyph->font)) / 8;
do_blit (combining_glyphs[i], targetx,
-(main_glyph->height + main_glyph->offset_y + space
+ combining_glyphs[i]->height));
if (min_devwidth < combining_glyphs[i]->width)
min_devwidth = combining_glyphs[i]->width;
break;
/* TODO: Put dammah, fathah and alif nearer to shadda. */
case GRUB_UNICODE_COMB_SYRIAC_SUPERSCRIPT_ALAPH:
case GRUB_UNICODE_COMB_ARABIC_DAMMAH:
case GRUB_UNICODE_COMB_ARABIC_DAMMATAN:
case GRUB_UNICODE_COMB_ARABIC_FATHATAN:
case GRUB_UNICODE_COMB_ARABIC_FATHAH:
case GRUB_UNICODE_COMB_ARABIC_SUPERSCRIPT_ALIF:
case GRUB_UNICODE_COMB_ARABIC_SUKUN:
case GRUB_UNICODE_COMB_ARABIC_SHADDA:
case GRUB_UNICODE_COMB_HEBREW_RAFE:
case GRUB_UNICODE_STACK_ABOVE:
stacked_above:
space = combining_glyphs[i]->offset_y
- grub_font_get_xheight (combining_glyphs[i]->font) - 1;
if (space <= 0)
space = 1 + (grub_font_get_xheight (main_glyph->font)) / 8;
case GRUB_UNICODE_STACK_ATTACHED_ABOVE:
do_blit (combining_glyphs[i], targetx,
-(bounds.height + bounds.y + space
+ combining_glyphs[i]->height));
if (min_devwidth < combining_glyphs[i]->width)
min_devwidth = combining_glyphs[i]->width;
break;
case GRUB_UNICODE_COMB_HEBREW_SHEVA:
case GRUB_UNICODE_COMB_HEBREW_HIRIQ:
case GRUB_UNICODE_COMB_HEBREW_QAMATS:
case GRUB_UNICODE_COMB_HEBREW_TSERE:
case GRUB_UNICODE_COMB_HEBREW_SEGOL:
/* TODO: placement in final kaf and under reish. */
case GRUB_UNICODE_COMB_HEBREW_HATAF_SEGOL:
case GRUB_UNICODE_COMB_HEBREW_HATAF_PATAH:
case GRUB_UNICODE_COMB_HEBREW_HATAF_QAMATS:
case GRUB_UNICODE_COMB_HEBREW_PATAH:
case GRUB_UNICODE_COMB_HEBREW_QUBUTS:
case GRUB_UNICODE_COMB_HEBREW_METEG:
/* TODO: Put kasra and kasratan under shadda. */
case GRUB_UNICODE_COMB_ARABIC_KASRA:
case GRUB_UNICODE_COMB_ARABIC_KASRATAN:
/* I don't know how ypogegrammeni differs from subscript. */
case GRUB_UNICODE_COMB_YPOGEGRAMMENI:
case GRUB_UNICODE_STACK_BELOW:
stacked_below:
space = -(combining_glyphs[i]->offset_y
+ combining_glyphs[i]->height);
if (space <= 0)
space = 1 + (grub_font_get_xheight (main_glyph->font)) / 8;
case GRUB_UNICODE_STACK_ATTACHED_BELOW:
do_blit (combining_glyphs[i], targetx, -(bounds.y - space));
if (min_devwidth < combining_glyphs[i]->width)
min_devwidth = combining_glyphs[i]->width;
break;
case GRUB_UNICODE_COMB_MN:
switch (glyph_id->combining[i].code)
{
case GRUB_UNICODE_THAANA_ABAFILI:
case GRUB_UNICODE_THAANA_AABAAFILI:
case GRUB_UNICODE_THAANA_UBUFILI:
case GRUB_UNICODE_THAANA_OOBOOFILI:
case GRUB_UNICODE_THAANA_EBEFILI:
case GRUB_UNICODE_THAANA_EYBEYFILI:
case GRUB_UNICODE_THAANA_OBOFILI:
case GRUB_UNICODE_THAANA_OABOAFILI:
case GRUB_UNICODE_THAANA_SUKUN:
goto stacked_above;
case GRUB_UNICODE_THAANA_IBIFILI:
case GRUB_UNICODE_THAANA_EEBEEFILI:
goto stacked_below;
}
/* Fall through. */
default:
{
/* Default handling. Just draw combining character on top
of base character.
FIXME: support more unicode types correctly.
*/
do_blit (combining_glyphs[i],
main_glyph->device_width
+ combining_glyphs[i]->offset_x,
-(combining_glyphs[i]->height
+ combining_glyphs[i]->offset_y));
add_device_width (combining_glyphs[i]->device_width);
}
}
}
add_device_width ((above_rightx >
below_rightx ? above_rightx : below_rightx) -
(main_glyph->offset_x + main_glyph->width));
add_device_width (above_leftx - main_glyph->offset_x);
if (glyph && glyph->device_width < min_devwidth)
glyph->device_width = min_devwidth;
if (device_width && *device_width < min_devwidth)
*device_width = min_devwidth;
if (bounds_out)
*bounds_out = bounds;
}
static struct grub_font_glyph *
grub_font_construct_dry_run (grub_font_t hinted_font,
const struct grub_unicode_glyph *glyph_id,
struct grub_video_signed_rect *bounds,
struct grub_font_glyph ***combining_glyphs_out,
int *device_width)
{
struct grub_font_glyph *main_glyph = NULL;
struct grub_font_glyph **combining_glyphs;
grub_uint32_t desired_attributes = 0;
if (combining_glyphs_out)
*combining_glyphs_out = NULL;
if (glyph_id->attributes & GRUB_UNICODE_GLYPH_ATTRIBUTE_RIGHT_JOINED)
desired_attributes |= GRUB_FONT_CODE_RIGHT_JOINED;
if (glyph_id->attributes & GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED)
desired_attributes |= GRUB_FONT_CODE_LEFT_JOINED;
main_glyph = grub_font_get_glyph_with_fallback (hinted_font, glyph_id->base
| desired_attributes);
if (!main_glyph)
main_glyph = grub_font_get_glyph_with_fallback (hinted_font,
glyph_id->base);
/* Glyph not available in any font. Use ASCII fallback. */
if (!main_glyph)
main_glyph = ascii_glyph_lookup (glyph_id->base);
/* Glyph not available in any font. Return unknown glyph. */
if (!main_glyph)
return NULL;
if (device_width)
*device_width = main_glyph->device_width;
if (!glyph_id->ncomb && !glyph_id->attributes)
return main_glyph;
combining_glyphs = grub_malloc (sizeof (combining_glyphs[0])
* glyph_id->ncomb);
if (glyph_id->ncomb && !combining_glyphs)
{
grub_errno = GRUB_ERR_NONE;
return main_glyph;
}
{
unsigned i;
for (i = 0; i < glyph_id->ncomb; i++)
combining_glyphs[i]
= grub_font_get_glyph_with_fallback (main_glyph->font,
glyph_id->combining[i].code);
}
blit_comb (glyph_id, NULL, bounds, main_glyph, combining_glyphs,
device_width);
if (combining_glyphs_out)
*combining_glyphs_out = combining_glyphs;
else
grub_free (combining_glyphs);
return main_glyph;
}
int
grub_font_get_constructed_device_width (grub_font_t hinted_font,
const struct grub_unicode_glyph
*glyph_id)
{
int ret;
struct grub_font_glyph *main_glyph;
main_glyph = grub_font_construct_dry_run (hinted_font, glyph_id, NULL,
NULL, &ret);
if (!main_glyph)
return unknown_glyph->device_width;
return ret;
}
struct grub_font_glyph *
grub_font_construct_glyph (grub_font_t hinted_font,
const struct grub_unicode_glyph *glyph_id)
{
struct grub_font_glyph *main_glyph;
struct grub_video_signed_rect bounds;
struct grub_font_glyph *glyph;
struct grub_font_glyph **combining_glyphs;
main_glyph = grub_font_construct_dry_run (hinted_font, glyph_id,
&bounds, &combining_glyphs, NULL);
if (!main_glyph)
return grub_font_dup_glyph (unknown_glyph);
if (!combining_glyphs)
return grub_font_dup_glyph (main_glyph);
glyph =
grub_zalloc (sizeof (*glyph) + (bounds.width * bounds.height + 7) / 8);
if (!glyph)
{
grub_errno = GRUB_ERR_NONE;
return grub_font_dup_glyph (main_glyph);
}
glyph->font = main_glyph->font;
glyph->width = bounds.width;
glyph->height = bounds.height;
glyph->offset_x = bounds.x;
glyph->offset_y = bounds.y;
if (glyph_id->attributes & GRUB_UNICODE_GLYPH_ATTRIBUTE_MIRROR)
grub_font_blit_glyph_mirror (glyph, main_glyph,
main_glyph->offset_x - glyph->offset_x,
(glyph->height + glyph->offset_y)
- (main_glyph->height +
main_glyph->offset_y));
else
grub_font_blit_glyph (glyph, main_glyph,
main_glyph->offset_x - glyph->offset_x,
(glyph->height + glyph->offset_y)
- (main_glyph->height + main_glyph->offset_y));
blit_comb (glyph_id, glyph, NULL, main_glyph, combining_glyphs, NULL);
return glyph;
}
/* Draw the specified glyph at (x, y). The y coordinate designates the
baseline of the character, while the x coordinate designates the left
@ -1067,8 +1500,8 @@ grub_font_draw_glyph (struct grub_font_glyph * glyph,
glyph_bitmap.mode_info.width = glyph->width;
glyph_bitmap.mode_info.height = glyph->height;
glyph_bitmap.mode_info.mode_type =
(1 << GRUB_VIDEO_MODE_TYPE_DEPTH_POS) | GRUB_VIDEO_MODE_TYPE_1BIT_BITMAP;
glyph_bitmap.mode_info.mode_type
= (1 << GRUB_VIDEO_MODE_TYPE_DEPTH_POS) | GRUB_VIDEO_MODE_TYPE_1BIT_BITMAP;
glyph_bitmap.mode_info.blit_format = GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED;
glyph_bitmap.mode_info.bpp = 1;
@ -1098,29 +1531,3 @@ grub_font_draw_glyph (struct grub_font_glyph * glyph,
bitmap_left, bitmap_top,
0, 0, glyph->width, glyph->height);
}
/* Draw a UTF-8 string of text on the current video render target.
The x coordinate specifies the starting x position for the first character,
while the y coordinate specifies the baseline position.
If the string contains a character that FONT does not contain, then
a glyph from another loaded font may be used instead. */
grub_err_t
grub_font_draw_string (const char *str, grub_font_t font,
grub_video_color_t color, int left_x, int baseline_y)
{
int x;
struct grub_font_glyph *glyph;
grub_uint32_t code;
const grub_uint8_t *ptr;
for (ptr = (const grub_uint8_t *) str, x = left_x;
grub_utf8_to_ucs4 (&code, 1, ptr, -1, &ptr) > 0;)
{
glyph = grub_font_get_glyph_with_fallback (font, code);
if (grub_font_draw_glyph (glyph, color, x, baseline_y) != GRUB_ERR_NONE)
return grub_errno;
x += glyph->device_width;
}
return GRUB_ERR_NONE;
}

109
gfxmenu/font.c Normal file
View File

@ -0,0 +1,109 @@
/* font.c - Font API and font file loader. */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2003,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc.
*
* GRUB 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.
*
* GRUB 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 GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <grub/bufio.h>
#include <grub/dl.h>
#include <grub/file.h>
#include <grub/font.h>
#include <grub/misc.h>
#include <grub/mm.h>
#include <grub/types.h>
#include <grub/video.h>
#include <grub/bitmap.h>
#include <grub/charset.h>
#include <grub/unicode.h>
#include <grub/fontformat.h>
#include <grub/gfxmenu_view.h>
/* Draw a UTF-8 string of text on the current video render target.
The x coordinate specifies the starting x position for the first character,
while the y coordinate specifies the baseline position.
If the string contains a character that FONT does not contain, then
a glyph from another loaded font may be used instead. */
grub_err_t
grub_font_draw_string (const char *str, grub_font_t font,
grub_video_color_t color,
int left_x, int baseline_y)
{
int x;
struct grub_font_glyph *glyph;
grub_uint32_t *logical;
grub_ssize_t logical_len, visual_len;
struct grub_unicode_glyph *visual, *ptr;
logical_len = grub_utf8_to_ucs4_alloc (str, &logical, 0);
if (logical_len < 0)
return grub_errno;
visual_len = grub_bidi_logical_to_visual (logical, logical_len, &visual,
0, 0, 0);
grub_free (logical);
if (visual_len < 0)
return grub_errno;
for (ptr = visual, x = left_x; ptr < visual + visual_len; ptr++)
{
grub_err_t err;
glyph = grub_font_construct_glyph (font, ptr);
if (!glyph)
return grub_errno;
err = grub_font_draw_glyph (glyph, color, x, baseline_y);
x += glyph->device_width;
grub_free (glyph);
if (err)
return err;
}
grub_free (visual);
return GRUB_ERR_NONE;
}
/* Get the width in pixels of the specified UTF-8 string, when rendered in
in the specified font (but falling back on other fonts for glyphs that
are missing). */
int
grub_font_get_string_width (grub_font_t font, const char *str)
{
int width = 0;
grub_uint32_t *ptr;
grub_ssize_t logical_len;
grub_uint32_t *logical;
logical_len = grub_utf8_to_ucs4_alloc (str, &logical, 0);
if (logical_len < 0)
{
grub_errno = GRUB_ERR_NONE;
return 0;
}
for (ptr = logical; ptr < logical + logical_len;)
{
struct grub_unicode_glyph glyph;
ptr += grub_unicode_aglomerate_comb (ptr,
logical_len - (ptr - logical),
&glyph);
width += grub_font_get_constructed_device_width (font, &glyph);
grub_free (glyph.combining);
}
return width;
}

View File

@ -117,5 +117,11 @@ grub_is_valid_utf8 (const grub_uint8_t *src, grub_size_t srcsize);
int grub_utf8_to_ucs4_alloc (const char *msg, grub_uint32_t **unicode_msg,
grub_uint32_t **last_position);
void
grub_ucs4_to_utf8 (grub_uint32_t *src, grub_size_t size,
grub_uint8_t *dest, grub_size_t destsize);
grub_size_t grub_utf8_to_ucs4 (grub_uint32_t *dest, grub_size_t destsize,
const grub_uint8_t *src, grub_size_t srcsize,
const grub_uint8_t **srcend);
#endif

View File

@ -22,6 +22,7 @@
#include <grub/types.h>
#include <grub/video.h>
#include <grub/file.h>
#include <grub/unicode.h>
/* Forward declaration of opaque structure grub_font.
Users only pass struct grub_font pointers to the font module functions,
@ -69,6 +70,11 @@ struct grub_font_glyph
grub_uint8_t bitmap[0];
};
/* Part of code field which is really used as such. */
#define GRUB_FONT_CODE_CHAR_MASK 0x001fffff
#define GRUB_FONT_CODE_RIGHT_JOINED 0x80000000
#define GRUB_FONT_CODE_LEFT_JOINED 0x40000000
/* Initialize the font loader.
Must be called before any fonts are loaded or used. */
void grub_font_loader_init (void);
@ -97,8 +103,7 @@ int EXPORT_FUNC (grub_font_get_leading) (grub_font_t font);
int EXPORT_FUNC (grub_font_get_height) (grub_font_t font);
int EXPORT_FUNC (grub_font_get_string_width) (grub_font_t font,
const char *str);
int EXPORT_FUNC (grub_font_get_xheight) (grub_font_t font);
struct grub_font_glyph *EXPORT_FUNC (grub_font_get_glyph) (grub_font_t font,
grub_uint32_t code);
@ -110,9 +115,11 @@ grub_err_t EXPORT_FUNC (grub_font_draw_glyph) (struct grub_font_glyph *glyph,
grub_video_color_t color,
int left_x, int baseline_y);
grub_err_t EXPORT_FUNC (grub_font_draw_string) (const char *str,
grub_font_t font,
grub_video_color_t color,
int left_x, int baseline_y);
int
EXPORT_FUNC (grub_font_get_constructed_device_width) (grub_font_t hinted_font,
const struct grub_unicode_glyph *glyph_id);
struct grub_font_glyph *
EXPORT_FUNC (grub_font_construct_glyph) (grub_font_t hinted_font,
const struct grub_unicode_glyph *glyph_id);
#endif /* ! GRUB_FONT_HEADER */

View File

@ -62,6 +62,14 @@ grub_gfxmenu_print_timeout (int timeout, void *data);
void
grub_gfxmenu_set_chosen_entry (int entry, void *data);
grub_err_t grub_font_draw_string (const char *str,
grub_font_t font,
grub_video_color_t color,
int left_x, int baseline_y);
int grub_font_get_string_width (grub_font_t font,
const char *str);
/* Implementation details -- this should not be used outside of the
view itself. */

View File

@ -40,12 +40,15 @@
#include <grub/i386/vga_common.h>
/* These are global to share code between C and asm. */
int grub_console_checkkey (void);
int grub_console_getkey (void);
grub_uint16_t grub_console_getxy (void);
void grub_console_gotoxy (grub_uint8_t x, grub_uint8_t y);
void grub_console_cls (void);
void grub_console_setcursor (int on);
int grub_console_checkkey (struct grub_term_input *term);
int grub_console_getkey (struct grub_term_input *term);
grub_uint16_t grub_console_getxy (struct grub_term_output *term);
void grub_console_gotoxy (struct grub_term_output *term,
grub_uint8_t x, grub_uint8_t y);
void grub_console_cls (struct grub_term_output *term);
void grub_console_setcursor (struct grub_term_output *term, int on);
void grub_console_putchar (struct grub_term_output *term,
const struct grub_unicode_glyph *c);
/* Initialize the console system. */
void grub_console_init (void);

View File

@ -25,16 +25,8 @@
extern grub_uint8_t grub_console_cur_color;
void grub_console_putchar (grub_uint32_t c);
grub_ssize_t grub_console_getcharwidth (grub_uint32_t c);
grub_uint16_t grub_console_getwh (void);
void grub_console_setcolorstate (grub_term_color_state state);
void grub_console_setcolor (grub_uint8_t normal_color, grub_uint8_t highlight_color);
void grub_console_getcolor (grub_uint8_t *normal_color, grub_uint8_t *highlight_color);
/* Implemented in both kern/i386/pc/startup.S and vga_text.c; this symbol
is not exported, so there's no collision, but vga_common.c expects this
prototype to be the same. */
void grub_console_real_putchar (int c);
grub_uint16_t grub_console_getwh (struct grub_term_output *term);
void grub_console_setcolorstate (struct grub_term_output *term,
grub_term_color_state state);
#endif /* ! GRUB_VGA_COMMON_CPU_HEADER */

View File

@ -22,7 +22,8 @@
#include <grub/symbol.h>
/* Initialize the console system. */
void grub_console_init (void);
void grub_console_init_early (void);
void grub_console_init_lately (void);
/* Finish the console system. */
void grub_console_fini (void);

View File

@ -237,7 +237,19 @@ void *EXPORT_FUNC(grub_memset) (void *s, int c, grub_size_t n);
grub_size_t EXPORT_FUNC(grub_strlen) (const char *s);
int EXPORT_FUNC(grub_printf) (const char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
int EXPORT_FUNC(grub_printf_) (const char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
int EXPORT_FUNC(grub_puts) (const char *s);
extern void (*EXPORT_VAR (grub_xputs)) (const char *str);
static inline int
grub_puts (const char *s)
{
const char nl[2] = "\n";
grub_xputs (s);
grub_xputs (nl);
return 1; /* Cannot fail. */
}
int EXPORT_FUNC(grub_puts_) (const char *s);
void EXPORT_FUNC(grub_real_dprintf) (const char *file,
const int line,
@ -253,11 +265,6 @@ char *EXPORT_FUNC(grub_xasprintf) (const char *fmt, ...)
char *EXPORT_FUNC(grub_xvasprintf) (const char *fmt, va_list args);
void EXPORT_FUNC(grub_exit) (void) __attribute__ ((noreturn));
void EXPORT_FUNC(grub_abort) (void) __attribute__ ((noreturn));
grub_size_t EXPORT_FUNC(grub_utf8_to_ucs4) (grub_uint32_t *dest,
grub_size_t destsize,
const grub_uint8_t *src,
grub_size_t srcsize,
const grub_uint8_t **srcend);
grub_uint64_t EXPORT_FUNC(grub_divmod64) (grub_uint64_t n,
grub_uint32_t d, grub_uint32_t *r);

View File

@ -77,9 +77,11 @@ void grub_parse_color_name_pair (grub_uint8_t *ret, const char *name);
/* Defined in `menu_text.c'. */
void grub_wait_after_message (void);
void grub_print_ucs4 (const grub_uint32_t * str,
const grub_uint32_t * last_position,
struct grub_term_output *term);
void
grub_print_ucs4 (const grub_uint32_t * str,
const grub_uint32_t * last_position,
int margin_left, int margin_right,
struct grub_term_output *term);
grub_ssize_t grub_getstringwidth (grub_uint32_t * str,
const grub_uint32_t * last_position,
struct grub_term_output *term);
@ -110,7 +112,9 @@ void read_terminal_list (const char *prefix);
void grub_set_more (int onoff);
int grub_normal_get_line_counter (void);
void grub_install_newline_hook (void);
int grub_normal_get_char_counter (void);
void grub_normal_reset_more (void);
void grub_xputs_normal (const char *str);
#endif /* ! GRUB_NORMAL_HEADER */

View File

@ -1,28 +0,0 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2002,2004,2005,2007 Free Software Foundation, Inc.
*
* GRUB 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.
*
* GRUB 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 GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef GRUB_CONSOLE_MACHINE_HEADER
#define GRUB_CONSOLE_MACHINE_HEADER 1
/* Initialize the console system. */
void grub_console_init (void);
/* Finish the console system. */
void grub_console_fini (void);
#endif /* ! GRUB_CONSOLE_MACHINE_HEADER */

View File

@ -1,28 +0,0 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2002,2004,2005,2007 Free Software Foundation, Inc.
*
* GRUB 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.
*
* GRUB 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 GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef GRUB_CONSOLE_MACHINE_HEADER
#define GRUB_CONSOLE_MACHINE_HEADER 1
/* Initialize the console system. */
void grub_console_init (void);
/* Finish the console system. */
void grub_console_fini (void);
#endif /* ! GRUB_CONSOLE_MACHINE_HEADER */

View File

@ -38,6 +38,7 @@
#include <grub/err.h>
#include <grub/symbol.h>
#include <grub/types.h>
#include <grub/unicode.h>
#include <grub/list.h>
/* These are used to represent the various color states we use. */
@ -63,11 +64,25 @@ grub_term_color_state;
to NULL. */
/* Set when input characters shouldn't be echoed back. */
#define GRUB_TERM_NO_ECHO (1 << 0)
#define GRUB_TERM_NO_ECHO (1 << 0)
/* Set when the editing feature should be disabled. */
#define GRUB_TERM_NO_EDIT (1 << 1)
#define GRUB_TERM_NO_EDIT (1 << 1)
/* Set when the terminal cannot do fancy things. */
#define GRUB_TERM_DUMB (1 << 2)
#define GRUB_TERM_DUMB (1 << 2)
/* Which encoding does terminal expect stream to be. */
#define GRUB_TERM_CODE_TYPE_SHIFT 3
#define GRUB_TERM_CODE_TYPE_MASK (7 << GRUB_TERM_CODE_TYPE_SHIFT)
/* Only ASCII characters accepted. */
#define GRUB_TERM_CODE_TYPE_ASCII (0 << GRUB_TERM_CODE_TYPE_SHIFT)
/* Expects CP-437 characters (ASCII + pseudographics). */
#define GRUB_TERM_CODE_TYPE_CP437 (1 << GRUB_TERM_CODE_TYPE_SHIFT)
/* UTF-8 stream in logical order. Usually used for terminals
which just forward the stream to another computer. */
#define GRUB_TERM_CODE_TYPE_UTF8_LOGICAL (2 << GRUB_TERM_CODE_TYPE_SHIFT)
/* UTF-8 in visual order. Like UTF-8 logical but for buggy endpoints. */
#define GRUB_TERM_CODE_TYPE_UTF8_VISUAL (3 << GRUB_TERM_CODE_TYPE_SHIFT)
/* Glyph description in visual order. */
#define GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS (4 << GRUB_TERM_CODE_TYPE_SHIFT)
/* Bitmasks for modifier keys returned by grub_getkeystatus. */
@ -75,20 +90,6 @@ grub_term_color_state;
#define GRUB_TERM_STATUS_CTRL (1 << 1)
#define GRUB_TERM_STATUS_ALT (1 << 2)
/* Unicode characters for fancy graphics. */
#define GRUB_TERM_DISP_LEFT 0x2190
#define GRUB_TERM_DISP_UP 0x2191
#define GRUB_TERM_DISP_RIGHT 0x2192
#define GRUB_TERM_DISP_DOWN 0x2193
#define GRUB_TERM_DISP_HLINE 0x2501
#define GRUB_TERM_DISP_VLINE 0x2503
#define GRUB_TERM_DISP_UL 0x250F
#define GRUB_TERM_DISP_UR 0x2513
#define GRUB_TERM_DISP_LL 0x2517
#define GRUB_TERM_DISP_LR 0x251B
/* Menu-related geometrical constants. */
/* The number of lines of "GRUB version..." at the top. */
@ -122,19 +123,21 @@ struct grub_term_input
const char *name;
/* Initialize the terminal. */
grub_err_t (*init) (void);
grub_err_t (*init) (struct grub_term_input *term);
/* Clean up the terminal. */
grub_err_t (*fini) (void);
grub_err_t (*fini) (struct grub_term_input *term);
/* Check if any input character is available. */
int (*checkkey) (void);
int (*checkkey) (struct grub_term_input *term);
/* Get a character. */
int (*getkey) (void);
int (*getkey) (struct grub_term_input *term);
/* Get keyboard modifier status. */
int (*getkeystatus) (void);
int (*getkeystatus) (struct grub_term_input *term);
void *data;
};
typedef struct grub_term_input *grub_term_input_t;
@ -147,52 +150,58 @@ struct grub_term_output
const char *name;
/* Initialize the terminal. */
grub_err_t (*init) (void);
grub_err_t (*init) (struct grub_term_output *term);
/* Clean up the terminal. */
grub_err_t (*fini) (void);
grub_err_t (*fini) (struct grub_term_output *term);
/* Put a character. C is encoded in Unicode. */
void (*putchar) (grub_uint32_t c);
void (*putchar) (struct grub_term_output *term,
const struct grub_unicode_glyph *c);
/* Get the number of columns occupied by a given character C. C is
encoded in Unicode. */
grub_ssize_t (*getcharwidth) (grub_uint32_t c);
grub_ssize_t (*getcharwidth) (struct grub_term_output *term,
const struct grub_unicode_glyph *c);
/* Get the screen size. The return value is ((Width << 8) | Height). */
grub_uint16_t (*getwh) (void);
grub_uint16_t (*getwh) (struct grub_term_output *term);
/* Get the cursor position. The return value is ((X << 8) | Y). */
grub_uint16_t (*getxy) (void);
grub_uint16_t (*getxy) (struct grub_term_output *term);
/* Go to the position (X, Y). */
void (*gotoxy) (grub_uint8_t x, grub_uint8_t y);
void (*gotoxy) (struct grub_term_output *term,
grub_uint8_t x, grub_uint8_t y);
/* Clear the screen. */
void (*cls) (void);
void (*cls) (struct grub_term_output *term);
/* Set the current color to be used */
void (*setcolorstate) (grub_term_color_state state);
/* Set the normal color and the highlight color. The format of each
color is VGA's. */
void (*setcolor) (grub_uint8_t normal_color, grub_uint8_t highlight_color);
/* Get the normal color and the highlight color. The format of each
color is VGA's. */
void (*getcolor) (grub_uint8_t *normal_color, grub_uint8_t *highlight_color);
void (*setcolorstate) (struct grub_term_output *term,
grub_term_color_state state);
/* Turn on/off the cursor. */
void (*setcursor) (int on);
void (*setcursor) (struct grub_term_output *term, int on);
/* Update the screen. */
void (*refresh) (void);
void (*refresh) (struct grub_term_output *term);
/* The feature flags defined above. */
grub_uint32_t flags;
/* Current color state. */
grub_uint8_t normal_color;
grub_uint8_t highlight_color;
void *data;
};
typedef struct grub_term_output *grub_term_output_t;
#define GRUB_TERM_DEFAULT_NORMAL_COLOR 0x07
#define GRUB_TERM_DEFAULT_HIGHLIGHT_COLOR 0x70
#define GRUB_TERM_DEFAULT_STANDARD_COLOR 0x07
extern struct grub_term_output *EXPORT_VAR(grub_term_outputs_disabled);
extern struct grub_term_input *EXPORT_VAR(grub_term_inputs_disabled);
extern struct grub_term_output *EXPORT_VAR(grub_term_outputs);
@ -208,7 +217,7 @@ grub_term_register_input (const char *name __attribute__ ((unused)),
else
{
/* If this is the first terminal, enable automatically. */
if (! term->init || term->init () == GRUB_ERR_NONE)
if (! term->init || term->init (term) == GRUB_ERR_NONE)
grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs), GRUB_AS_LIST (term));
}
}
@ -217,7 +226,7 @@ static inline void
grub_term_register_input_active (const char *name __attribute__ ((unused)),
grub_term_input_t term)
{
if (! term->init || term->init () == GRUB_ERR_NONE)
if (! term->init || term->init (term) == GRUB_ERR_NONE)
grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs), GRUB_AS_LIST (term));
}
@ -231,7 +240,7 @@ grub_term_register_output (const char *name __attribute__ ((unused)),
else
{
/* If this is the first terminal, enable automatically. */
if (! term->init || term->init () == GRUB_ERR_NONE)
if (! term->init || term->init (term) == GRUB_ERR_NONE)
grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs),
GRUB_AS_LIST (term));
}
@ -241,7 +250,7 @@ static inline void
grub_term_register_output_active (const char *name __attribute__ ((unused)),
grub_term_output_t term)
{
if (! term->init || term->init () == GRUB_ERR_NONE)
if (! term->init || term->init (term) == GRUB_ERR_NONE)
grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs),
GRUB_AS_LIST (term));
}
@ -267,14 +276,11 @@ grub_term_unregister_output (grub_term_output_t term)
#define FOR_ACTIVE_TERM_OUTPUTS(var) FOR_LIST_ELEMENTS((var), (grub_term_outputs))
#define FOR_DISABLED_TERM_OUTPUTS(var) FOR_LIST_ELEMENTS((var), (grub_term_outputs_disabled))
void EXPORT_FUNC(grub_putchar) (int c);
void EXPORT_FUNC(grub_putcode) (grub_uint32_t code,
struct grub_term_output *term);
void grub_putcode (grub_uint32_t code, struct grub_term_output *term);
int EXPORT_FUNC(grub_getkey) (void);
int EXPORT_FUNC(grub_checkkey) (void);
int EXPORT_FUNC(grub_getkeystatus) (void);
void EXPORT_FUNC(grub_cls) (void);
void EXPORT_FUNC(grub_setcolorstate) (grub_term_color_state state);
void grub_cls (void);
void EXPORT_FUNC(grub_refresh) (void);
void grub_puts_terminal (const char *str, struct grub_term_output *term);
grub_uint16_t *grub_term_save_pos (void);
@ -282,12 +288,12 @@ void grub_term_restore_pos (grub_uint16_t *pos);
static inline unsigned grub_term_width (struct grub_term_output *term)
{
return ((term->getwh()&0xFF00)>>8);
return ((term->getwh(term)&0xFF00)>>8);
}
static inline unsigned grub_term_height (struct grub_term_output *term)
{
return (term->getwh()&0xFF);
return (term->getwh(term)&0xFF);
}
/* The width of the border. */
@ -331,20 +337,20 @@ grub_term_cursor_x (struct grub_term_output *term)
static inline grub_uint16_t
grub_term_getxy (struct grub_term_output *term)
{
return term->getxy ();
return term->getxy (term);
}
static inline void
grub_term_refresh (struct grub_term_output *term)
{
if (term->refresh)
term->refresh ();
term->refresh (term);
}
static inline void
grub_term_gotoxy (struct grub_term_output *term, grub_uint8_t x, grub_uint8_t y)
{
term->gotoxy (x, y);
term->gotoxy (term, x, y);
}
static inline void
@ -352,17 +358,26 @@ grub_term_setcolorstate (struct grub_term_output *term,
grub_term_color_state state)
{
if (term->setcolorstate)
term->setcolorstate (state);
term->setcolorstate (term, state);
}
/* Set the normal color and the highlight color. The format of each
color is VGA's. */
static inline void
grub_setcolorstate (grub_term_color_state state)
{
struct grub_term_output *term;
FOR_ACTIVE_TERM_OUTPUTS(term)
grub_term_setcolorstate (term, state);
}
/* Set the normal color and the highlight color. The format of each
color is VGA's. */
static inline void
grub_term_setcolor (struct grub_term_output *term,
grub_uint8_t normal_color, grub_uint8_t highlight_color)
{
if (term->setcolor)
term->setcolor (normal_color, highlight_color);
term->normal_color = normal_color;
term->highlight_color = highlight_color;
}
/* Turn on/off the cursor. */
@ -370,14 +385,14 @@ static inline void
grub_term_setcursor (struct grub_term_output *term, int on)
{
if (term->setcursor)
term->setcursor (on);
term->setcursor (term, on);
}
static inline void
grub_term_cls (struct grub_term_output *term)
{
if (term->cls)
(term->cls) ();
(term->cls) (term);
else
{
grub_putcode ('\n', term);
@ -385,11 +400,36 @@ grub_term_cls (struct grub_term_output *term)
}
}
#ifdef HAVE_UNIFONT_WIDTHSPEC
grub_ssize_t
grub_unicode_estimate_width (const struct grub_unicode_glyph *c);
#else
static inline grub_ssize_t
grub_unicode_estimate_width (const struct grub_unicode_glyph *c __attribute__ ((unused)))
{
if (grub_unicode_get_comb_type (c->base))
return 0;
return 1;
}
#endif
static inline grub_ssize_t
grub_term_getcharwidth (struct grub_term_output *term, grub_uint32_t c)
grub_term_getcharwidth (struct grub_term_output *term,
const struct grub_unicode_glyph *c)
{
if (term->getcharwidth)
return term->getcharwidth (c);
return term->getcharwidth (term, c);
else if (((term->flags & GRUB_TERM_CODE_TYPE_MASK)
== GRUB_TERM_CODE_TYPE_UTF8_LOGICAL)
|| ((term->flags & GRUB_TERM_CODE_TYPE_MASK)
== GRUB_TERM_CODE_TYPE_UTF8_VISUAL)
|| ((term->flags & GRUB_TERM_CODE_TYPE_MASK)
== GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS))
return grub_unicode_estimate_width (c);
else
return 1;
}
@ -398,17 +438,10 @@ static inline void
grub_term_getcolor (struct grub_term_output *term,
grub_uint8_t *normal_color, grub_uint8_t *highlight_color)
{
if (term->getcolor)
term->getcolor (normal_color, highlight_color);
else
{
*normal_color = 0x07;
*highlight_color = 0x07;
}
*normal_color = term->normal_color;
*highlight_color = term->highlight_color;
}
extern void (*EXPORT_VAR (grub_newline_hook)) (void);
struct grub_term_autoload
{
struct grub_term_autoload *next;

View File

@ -23,15 +23,55 @@
#include <grub/types.h>
#include <grub/term.h>
char *grub_terminfo_get_current (void);
grub_err_t grub_terminfo_set_current (const char *);
char *EXPORT_FUNC(grub_terminfo_get_current) (struct grub_term_output *term);
grub_err_t EXPORT_FUNC(grub_terminfo_set_current) (struct grub_term_output *term,
const char *);
void grub_terminfo_gotoxy (grub_uint8_t x, grub_uint8_t y,
grub_term_output_t oterm);
void grub_terminfo_cls (grub_term_output_t oterm);
void grub_terminfo_reverse_video_on (grub_term_output_t oterm);
void grub_terminfo_reverse_video_off (grub_term_output_t oterm);
void grub_terminfo_cursor_on (grub_term_output_t oterm);
void grub_terminfo_cursor_off (grub_term_output_t oterm);
#define GRUB_TERMINFO_READKEY_MAX_LEN 4
struct grub_terminfo_input_state
{
int input_buf[GRUB_TERMINFO_READKEY_MAX_LEN];
int npending;
int (*readkey) (void);
};
struct grub_terminfo_output_state
{
struct grub_term_output *next;
char *name;
char *gotoxy;
char *cls;
char *reverse_video_on;
char *reverse_video_off;
char *cursor_on;
char *cursor_off;
char *setcolor;
unsigned int xpos, ypos;
void (*put) (const int c);
};
void EXPORT_FUNC(grub_terminfo_gotoxy) (grub_term_output_t term,
grub_uint8_t x, grub_uint8_t y);
void EXPORT_FUNC(grub_terminfo_cls) (grub_term_output_t term);
grub_uint16_t EXPORT_FUNC (grub_terminfo_getxy) (struct grub_term_output *term);
void EXPORT_FUNC (grub_terminfo_setcursor) (struct grub_term_output *term,
const int on);
void EXPORT_FUNC (grub_terminfo_setcolorstate) (struct grub_term_output *term,
const grub_term_color_state state);
int EXPORT_FUNC (grub_terminfo_checkkey) (struct grub_term_input *term);
grub_err_t EXPORT_FUNC (grub_terminfo_input_init) (struct grub_term_input *term);
int EXPORT_FUNC (grub_terminfo_getkey) (struct grub_term_input *term);
void EXPORT_FUNC (grub_terminfo_putchar) (struct grub_term_output *term,
const struct grub_unicode_glyph *c);
grub_err_t EXPORT_FUNC (grub_terminfo_output_register) (struct grub_term_output *term,
const char *type);
grub_err_t EXPORT_FUNC (grub_terminfo_output_unregister) (struct grub_term_output *term);
#endif /* ! GRUB_TERMINFO_HEADER */

272
include/grub/unicode.h Normal file
View File

@ -0,0 +1,272 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2010 Free Software Foundation, Inc.
*
* GRUB 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.
*
* GRUB 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 GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef GRUB_BIDI_HEADER
#define GRUB_BIDI_HEADER 1
#include <grub/types.h>
#include <grub/mm.h>
#include <grub/misc.h>
struct grub_unicode_bidi_pair
{
grub_uint32_t key;
grub_uint32_t replace;
};
struct grub_unicode_compact_range
{
grub_uint32_t start:21;
grub_uint32_t end:21;
grub_uint8_t bidi_type:5;
grub_uint8_t comb_type;
grub_uint8_t bidi_mirror:1;
grub_uint8_t join_type:3;
} __attribute__ ((packed));
/* Old-style Arabic shaping. Used for "visual UTF-8" and
in grub-mkfont to find variant glyphs in absence of GPOS tables. */
struct grub_unicode_arabic_shape
{
grub_uint32_t code;
grub_uint32_t isolated;
grub_uint32_t right_linked;
grub_uint32_t both_linked;
grub_uint32_t left_linked;
};
extern struct grub_unicode_arabic_shape grub_unicode_arabic_shapes[];
enum grub_bidi_type
{
GRUB_BIDI_TYPE_L = 0,
GRUB_BIDI_TYPE_LRE,
GRUB_BIDI_TYPE_LRO,
GRUB_BIDI_TYPE_R,
GRUB_BIDI_TYPE_AL,
GRUB_BIDI_TYPE_RLE,
GRUB_BIDI_TYPE_RLO,
GRUB_BIDI_TYPE_PDF,
GRUB_BIDI_TYPE_EN,
GRUB_BIDI_TYPE_ES,
GRUB_BIDI_TYPE_ET,
GRUB_BIDI_TYPE_AN,
GRUB_BIDI_TYPE_CS,
GRUB_BIDI_TYPE_NSM,
GRUB_BIDI_TYPE_BN,
GRUB_BIDI_TYPE_B,
GRUB_BIDI_TYPE_S,
GRUB_BIDI_TYPE_WS,
GRUB_BIDI_TYPE_ON
};
enum grub_join_type
{
GRUB_JOIN_TYPE_NONJOINING = 0,
GRUB_JOIN_TYPE_LEFT = 1,
GRUB_JOIN_TYPE_RIGHT = 2,
GRUB_JOIN_TYPE_DUAL = 3,
GRUB_JOIN_TYPE_CAUSING = 4,
GRUB_JOIN_TYPE_TRANSPARENT = 5
};
enum grub_comb_type
{
GRUB_UNICODE_COMB_NONE = 0,
GRUB_UNICODE_COMB_OVERLAY = 1,
GRUB_UNICODE_COMB_HEBREW_SHEVA = 10,
GRUB_UNICODE_COMB_HEBREW_HATAF_SEGOL = 11,
GRUB_UNICODE_COMB_HEBREW_HATAF_PATAH = 12,
GRUB_UNICODE_COMB_HEBREW_HATAF_QAMATS = 13,
GRUB_UNICODE_COMB_HEBREW_HIRIQ = 14,
GRUB_UNICODE_COMB_HEBREW_TSERE = 15,
GRUB_UNICODE_COMB_HEBREW_SEGOL = 16,
GRUB_UNICODE_COMB_HEBREW_PATAH = 17,
GRUB_UNICODE_COMB_HEBREW_QAMATS = 18,
GRUB_UNICODE_COMB_HEBREW_HOLAM = 19,
GRUB_UNICODE_COMB_HEBREW_QUBUTS = 20,
GRUB_UNICODE_COMB_HEBREW_DAGESH = 21,
GRUB_UNICODE_COMB_HEBREW_METEG = 22,
GRUB_UNICODE_COMB_HEBREW_RAFE = 23,
GRUB_UNICODE_COMB_HEBREW_SHIN_DOT = 24,
GRUB_UNICODE_COMB_HEBREW_SIN_DOT = 25,
GRUB_UNICODE_COMB_HEBREW_VARIKA = 26,
GRUB_UNICODE_COMB_ARABIC_FATHATAN = 27,
GRUB_UNICODE_COMB_ARABIC_DAMMATAN = 28,
GRUB_UNICODE_COMB_ARABIC_KASRATAN = 29,
GRUB_UNICODE_COMB_ARABIC_FATHAH = 30,
GRUB_UNICODE_COMB_ARABIC_DAMMAH = 31,
GRUB_UNICODE_COMB_ARABIC_KASRA = 32,
GRUB_UNICODE_COMB_ARABIC_SHADDA = 33,
GRUB_UNICODE_COMB_ARABIC_SUKUN = 34,
GRUB_UNICODE_COMB_ARABIC_SUPERSCRIPT_ALIF = 35,
GRUB_UNICODE_COMB_SYRIAC_SUPERSCRIPT_ALAPH = 36,
GRUB_UNICODE_STACK_ATTACHED_BELOW = 202,
GRUB_UNICODE_STACK_ATTACHED_ABOVE = 214,
GRUB_UNICODE_COMB_ATTACHED_ABOVE_RIGHT = 216,
GRUB_UNICODE_STACK_BELOW = 220,
GRUB_UNICODE_COMB_BELOW_RIGHT = 222,
GRUB_UNICODE_COMB_ABOVE_LEFT = 228,
GRUB_UNICODE_STACK_ABOVE = 230,
GRUB_UNICODE_COMB_ABOVE_RIGHT = 232,
GRUB_UNICODE_COMB_YPOGEGRAMMENI = 240,
/* If combining nature is indicated only by class and
not "combining type". */
GRUB_UNICODE_COMB_ME = 253,
GRUB_UNICODE_COMB_MC = 254,
GRUB_UNICODE_COMB_MN = 255,
};
/* This structure describes a glyph as opposed to character. */
struct grub_unicode_glyph
{
grub_uint32_t base;
grub_uint16_t variant:9;
grub_uint8_t attributes:5;
grub_size_t ncomb;
struct grub_unicode_combining {
grub_uint32_t code;
enum grub_comb_type type;
} *combining;
/* Hint by unicode subsystem how wide this character usually is.
Real width is determined by font. Set only in UTF-8 stream. */
int estimated_width;
};
#define GRUB_UNICODE_GLYPH_ATTRIBUTE_MIRROR 0x1
#define GRUB_UNICODE_GLYPH_ATTRIBUTES_JOIN_LEFT_TO_RIGHT_SHIFT 1
#define GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED 0x2
#define GRUB_UNICODE_GLYPH_ATTRIBUTE_RIGHT_JOINED \
(GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED \
<< GRUB_UNICODE_GLYPH_ATTRIBUTES_JOIN_LEFT_TO_RIGHT_SHIFT)
/* Set iff the corresponding joining flags come from ZWJ or ZWNJ. */
#define GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED_EXPLICIT 0x8
#define GRUB_UNICODE_GLYPH_ATTRIBUTE_RIGHT_JOINED_EXPLICIT \
(GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED_EXPLICIT \
<< GRUB_UNICODE_GLYPH_ATTRIBUTES_JOIN_LEFT_TO_RIGHT_SHIFT)
#define GRUB_UNICODE_GLYPH_ATTRIBUTES_JOIN \
(GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED \
| GRUB_UNICODE_GLYPH_ATTRIBUTE_RIGHT_JOINED \
| GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED_EXPLICIT \
| GRUB_UNICODE_GLYPH_ATTRIBUTE_RIGHT_JOINED_EXPLICIT)
enum
{
GRUB_UNICODE_COMBINING_GRAPHEME_JOINER = 0x034f,
GRUB_UNICODE_HEBREW_WAW = 0x05d5,
GRUB_UNICODE_ARABIC_START = 0x0600,
GRUB_UNICODE_ARABIC_END = 0x0700,
GRUB_UNICODE_THAANA_ABAFILI = 0x07a6,
GRUB_UNICODE_THAANA_AABAAFILI = 0x07a7,
GRUB_UNICODE_THAANA_IBIFILI = 0x07a8,
GRUB_UNICODE_THAANA_EEBEEFILI = 0x07a9,
GRUB_UNICODE_THAANA_UBUFILI = 0x07aa,
GRUB_UNICODE_THAANA_OOBOOFILI = 0x07ab,
GRUB_UNICODE_THAANA_EBEFILI = 0x07ac,
GRUB_UNICODE_THAANA_EYBEYFILI = 0x07ad,
GRUB_UNICODE_THAANA_OBOFILI = 0x07ae,
GRUB_UNICODE_THAANA_OABOAFILI = 0x07af,
GRUB_UNICODE_THAANA_SUKUN = 0x07b0,
GRUB_UNICODE_ZWNJ = 0x200c,
GRUB_UNICODE_ZWJ = 0x200d,
GRUB_UNICODE_LEFTARROW = 0x2190,
GRUB_UNICODE_UPARROW = 0x2191,
GRUB_UNICODE_RIGHTARROW = 0x2192,
GRUB_UNICODE_DOWNARROW = 0x2193,
GRUB_UNICODE_LIGHT_HLINE = 0x2500,
GRUB_UNICODE_HLINE = 0x2501,
GRUB_UNICODE_LIGHT_VLINE = 0x2502,
GRUB_UNICODE_VLINE = 0x2503,
GRUB_UNICODE_LIGHT_CORNER_UL = 0x250c,
GRUB_UNICODE_CORNER_UL = 0x250f,
GRUB_UNICODE_LIGHT_CORNER_UR = 0x2510,
GRUB_UNICODE_CORNER_UR = 0x2513,
GRUB_UNICODE_LIGHT_CORNER_LL = 0x2514,
GRUB_UNICODE_CORNER_LL = 0x2517,
GRUB_UNICODE_LIGHT_CORNER_LR = 0x2518,
GRUB_UNICODE_CORNER_LR = 0x251b,
GRUB_UNICODE_BLACK_UP_TRIANGLE = 0x25b2,
GRUB_UNICODE_BLACK_RIGHT_TRIANGLE = 0x25ba,
GRUB_UNICODE_BLACK_DOWN_TRIANGLE = 0x25bc,
GRUB_UNICODE_BLACK_LEFT_TRIANGLE = 0x25c4,
GRUB_UNICODE_VARIATION_SELECTOR_1 = 0xfe00,
GRUB_UNICODE_VARIATION_SELECTOR_16 = 0xfe0f,
GRUB_UNICODE_VARIATION_SELECTOR_17 = 0xe0100,
GRUB_UNICODE_VARIATION_SELECTOR_256 = 0xe01ef
};
extern struct grub_unicode_compact_range grub_unicode_compact[];
extern struct grub_unicode_bidi_pair grub_unicode_bidi_pairs[];
#define GRUB_UNICODE_MAX_CACHED_CHAR 0x20000
/* Unicode mandates an arbitrary limit. */
#define GRUB_BIDI_MAX_EXPLICIT_LEVEL 61
grub_ssize_t
grub_bidi_logical_to_visual (const grub_uint32_t *logical,
grub_size_t logical_len,
struct grub_unicode_glyph **visual_out,
grub_ssize_t (*getcharwidth) (const struct grub_unicode_glyph *visual),
grub_size_t max_width,
grub_size_t start_width);
enum grub_comb_type
grub_unicode_get_comb_type (grub_uint32_t c);
grub_size_t
grub_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen,
struct grub_unicode_glyph *out);
static inline struct grub_unicode_glyph *
grub_unicode_glyph_dup (const struct grub_unicode_glyph *in)
{
struct grub_unicode_glyph *out = grub_malloc (sizeof (*out));
if (!out)
return NULL;
grub_memcpy (out, in, sizeof (*in));
if (in->combining)
{
out->combining = grub_malloc (in->ncomb * sizeof (*in));
if (!out->combining)
{
grub_free (out);
return NULL;
}
grub_memcpy (out->combining, in->combining, in->ncomb * sizeof (*in));
}
return out;
}
static inline struct grub_unicode_glyph *
grub_unicode_glyph_from_code (grub_uint32_t code)
{
struct grub_unicode_glyph *ret;
ret = grub_zalloc (sizeof (*ret));
if (!ret)
return NULL;
ret->base = code;
return ret;
}
grub_uint32_t
grub_unicode_mirror_code (grub_uint32_t in);
grub_uint32_t
grub_unicode_shape_code (grub_uint32_t in, grub_uint8_t attr);
#endif

View File

@ -168,6 +168,15 @@ struct grub_video_rect
};
typedef struct grub_video_rect grub_video_rect_t;
struct grub_video_signed_rect
{
signed x;
signed y;
unsigned width;
unsigned height;
};
typedef struct grub_video_signed_rect grub_video_signed_rect_t;
struct grub_video_palette_data
{
grub_uint8_t r; /* Red color value (0-255). */

View File

@ -122,7 +122,7 @@ grub_core_cmd_ls (struct grub_command *cmd __attribute__ ((unused)),
if (argc < 1)
{
grub_device_iterate (grub_mini_print_devices);
grub_putchar ('\n');
grub_xputs ("\n");
grub_refresh ();
}
else
@ -161,7 +161,7 @@ grub_core_cmd_ls (struct grub_command *cmd __attribute__ ((unused)),
else if (fs)
{
(fs->dir) (dev, path, grub_mini_print_files);
grub_putchar ('\n');
grub_xputs ("\n");
grub_refresh ();
}

View File

@ -43,9 +43,7 @@ static int grub_console_attr = A_NORMAL;
grub_uint8_t grub_console_cur_color = 7;
static grub_uint8_t grub_console_standard_color = 0x7;
static grub_uint8_t grub_console_normal_color = 0x7;
static grub_uint8_t grub_console_highlight_color = 0x70;
static const grub_uint8_t grub_console_standard_color = 0x7;
#define NUM_COLORS 8
@ -64,60 +62,15 @@ static grub_uint8_t color_map[NUM_COLORS] =
static int use_color;
static void
grub_ncurses_putchar (grub_uint32_t c)
grub_ncurses_putchar (struct grub_term_output *term __attribute__ ((unused)),
const struct grub_unicode_glyph *c)
{
/* Better than nothing. */
switch (c)
{
case GRUB_TERM_DISP_LEFT:
c = '<';
break;
case GRUB_TERM_DISP_UP:
c = '^';
break;
case GRUB_TERM_DISP_RIGHT:
c = '>';
break;
case GRUB_TERM_DISP_DOWN:
c = 'v';
break;
case GRUB_TERM_DISP_HLINE:
c = '-';
break;
case GRUB_TERM_DISP_VLINE:
c = '|';
break;
case GRUB_TERM_DISP_UL:
case GRUB_TERM_DISP_UR:
case GRUB_TERM_DISP_LL:
case GRUB_TERM_DISP_LR:
c = '+';
break;
default:
/* ncurses does not support Unicode. */
if (c > 0x7f)
c = '?';
break;
}
addch (c | grub_console_attr);
}
static grub_ssize_t
grub_ncurses_getcharwidth (grub_uint32_t code __attribute__ ((unused)))
{
return 1;
addch (c->base | grub_console_attr);
}
static void
grub_ncurses_setcolorstate (grub_term_color_state state)
grub_ncurses_setcolorstate (struct grub_term_output *term,
grub_term_color_state state)
{
switch (state)
{
@ -126,11 +79,11 @@ grub_ncurses_setcolorstate (grub_term_color_state state)
grub_console_attr = A_NORMAL;
break;
case GRUB_TERM_COLOR_NORMAL:
grub_console_cur_color = grub_console_normal_color;
grub_console_cur_color = term->normal_color;
grub_console_attr = A_NORMAL;
break;
case GRUB_TERM_COLOR_HIGHLIGHT:
grub_console_cur_color = grub_console_highlight_color;
grub_console_cur_color = term->highlight_color;
grub_console_attr = A_STANDOUT;
break;
default:
@ -149,25 +102,10 @@ grub_ncurses_setcolorstate (grub_term_color_state state)
}
}
/* XXX: This function is never called. */
static void
grub_ncurses_setcolor (grub_uint8_t normal_color, grub_uint8_t highlight_color)
{
grub_console_normal_color = normal_color;
grub_console_highlight_color = highlight_color;
}
static void
grub_ncurses_getcolor (grub_uint8_t *normal_color, grub_uint8_t *highlight_color)
{
*normal_color = grub_console_normal_color;
*highlight_color = grub_console_highlight_color;
}
static int saved_char = ERR;
static int
grub_ncurses_checkkey (void)
grub_ncurses_checkkey (struct grub_term_input *term __attribute__ ((unused)))
{
int c;
@ -189,7 +127,7 @@ grub_ncurses_checkkey (void)
}
static int
grub_ncurses_getkey (void)
grub_ncurses_getkey (struct grub_term_input *term __attribute__ ((unused)))
{
int c;
@ -208,19 +146,19 @@ grub_ncurses_getkey (void)
switch (c)
{
case KEY_LEFT:
c = 2;
c = GRUB_TERM_LEFT;
break;
case KEY_RIGHT:
c = 6;
c = GRUB_TERM_RIGHT;
break;
case KEY_UP:
c = 16;
c = GRUB_TERM_UP;
break;
case KEY_DOWN:
c = 14;
c = GRUB_TERM_DOWN;
break;
case KEY_IC:
@ -228,30 +166,30 @@ grub_ncurses_getkey (void)
break;
case KEY_DC:
c = 4;
c = GRUB_TERM_DC;
break;
case KEY_BACKSPACE:
/* XXX: For some reason ncurses on xterm does not return
KEY_BACKSPACE. */
case 127:
c = 8;
c = GRUB_TERM_BACKSPACE;
break;
case KEY_HOME:
c = 1;
c = GRUB_TERM_HOME;
break;
case KEY_END:
c = 5;
c = GRUB_TERM_END;
break;
case KEY_NPAGE:
c = 3;
c = GRUB_TERM_NPAGE;
break;
case KEY_PPAGE:
c = 7;
c = GRUB_TERM_PPAGE;
break;
}
@ -259,7 +197,7 @@ grub_ncurses_getkey (void)
}
static grub_uint16_t
grub_ncurses_getxy (void)
grub_ncurses_getxy (struct grub_term_output *term __attribute__ ((unused)))
{
int x;
int y;
@ -270,7 +208,7 @@ grub_ncurses_getxy (void)
}
static grub_uint16_t
grub_ncurses_getwh (void)
grub_ncurses_getwh (struct grub_term_output *term __attribute__ ((unused)))
{
int x;
int y;
@ -281,32 +219,34 @@ grub_ncurses_getwh (void)
}
static void
grub_ncurses_gotoxy (grub_uint8_t x, grub_uint8_t y)
grub_ncurses_gotoxy (struct grub_term_output *term __attribute__ ((unused)),
grub_uint8_t x, grub_uint8_t y)
{
move (y, x);
}
static void
grub_ncurses_cls (void)
grub_ncurses_cls (struct grub_term_output *term __attribute__ ((unused)))
{
clear ();
refresh ();
}
static void
grub_ncurses_setcursor (int on)
grub_ncurses_setcursor (struct grub_term_output *term __attribute__ ((unused)),
int on)
{
curs_set (on ? 1 : 0);
}
static void
grub_ncurses_refresh (void)
grub_ncurses_refresh (struct grub_term_output *term __attribute__ ((unused)))
{
refresh ();
}
static grub_err_t
grub_ncurses_init (void)
grub_ncurses_init (struct grub_term_output *term __attribute__ ((unused)))
{
initscr ();
raw ();
@ -338,7 +278,7 @@ grub_ncurses_init (void)
}
static grub_err_t
grub_ncurses_fini (void)
grub_ncurses_fini (struct grub_term_output *term __attribute__ ((unused)))
{
endwin ();
return 0;
@ -358,16 +298,14 @@ static struct grub_term_output grub_ncurses_term_output =
.init = grub_ncurses_init,
.fini = grub_ncurses_fini,
.putchar = grub_ncurses_putchar,
.getcharwidth = grub_ncurses_getcharwidth,
.getxy = grub_ncurses_getxy,
.getwh = grub_ncurses_getwh,
.gotoxy = grub_ncurses_gotoxy,
.cls = grub_ncurses_cls,
.setcolorstate = grub_ncurses_setcolorstate,
.setcolor = grub_ncurses_setcolor,
.getcolor = grub_ncurses_getcolor,
.setcursor = grub_ncurses_setcursor,
.refresh = grub_ncurses_refresh
.refresh = grub_ncurses_refresh,
.flags = GRUB_TERM_CODE_TYPE_ASCII
};
void
@ -380,5 +318,5 @@ grub_console_init (void)
void
grub_console_fini (void)
{
grub_ncurses_fini ();
grub_ncurses_fini (&grub_ncurses_term_output);
}

View File

@ -1063,7 +1063,7 @@ xsmap:
/*
* void grub_console_real_putchar (int c)
* void grub_console_putchar (const struct grub_unicode_glyph *c)
*
* Put the character C on the console. Because GRUB wants to write a
* character with an attribute, this implementation is a bit tricky.
@ -1076,8 +1076,9 @@ xsmap:
* get the height of the screen, and the TELETYPE OUTPUT BIOS call doesn't
* support setting a background attribute.
*/
FUNCTION(grub_console_real_putchar)
movl %eax, %edx
FUNCTION(grub_console_putchar)
/* Retrieve the base character. */
movl 0(%edx), %edx
pusha
movb EXT_C(grub_console_cur_color), %bl
@ -1328,8 +1329,8 @@ FUNCTION(grub_console_gotoxy)
pushl %ebp
pushl %ebx /* save EBX */
movb %dl, %dh /* %dh = y */
movb %al, %dl /* %dl = x */
movb %cl, %dh /* %dh = y */
/* %dl = x */
call prot_to_real
.code16
@ -1405,7 +1406,7 @@ FUNCTION(grub_console_setcursor)
pushl %ebx
/* push ON */
pushl %eax
pushl %edx
/* check if the standard cursor shape has already been saved */
movw console_cursor_shape, %ax

View File

@ -61,7 +61,7 @@ load_font (void)
grub_vga_gr_write (0xff, GRUB_VGA_GR_BITMASK);
for (i = 0; i < 128; i++)
grub_memcpy ((void *) (0xa0000 + 32 * i), ascii_bitmaps + 16 * (0x7f - i), 16);
grub_memcpy ((void *) (0xa0000 + 32 * i), ascii_bitmaps + 16 * i, 16);
}
static void

View File

@ -28,7 +28,7 @@
#include <grub/env.h>
#include <grub/misc.h>
#include <grub/time.h>
#include <grub/machine/console.h>
#include <grub/ieee1275/console.h>
#include <grub/ieee1275/ofdisk.h>
#include <grub/ieee1275/ieee1275.h>
#include <grub/offsets.h>
@ -224,11 +224,12 @@ grub_machine_init (void)
grub_ieee1275_init ();
grub_console_init ();
grub_console_init_early ();
#ifdef __i386__
grub_get_extended_memory ();
#endif
grub_claim_heap ();
grub_console_init_lately ();
grub_ofdisk_init ();
/* Process commandline. */

View File

@ -142,19 +142,6 @@ grub_printf_ (const char *fmt, ...)
return ret;
}
int
grub_puts (const char *s)
{
while (*s)
{
grub_putchar (*s);
s++;
}
grub_putchar ('\n');
return 1; /* Cannot fail. */
}
int
grub_puts_ (const char *s)
{
@ -200,13 +187,37 @@ grub_real_dprintf (const char *file, const int line, const char *condition,
}
}
#define PREALLOC_SIZE 255
int
grub_vprintf (const char *fmt, va_list args)
{
int ret;
grub_size_t s;
static char buf[PREALLOC_SIZE + 1];
char *curbuf = buf;
ret = grub_vsnprintf_real (0, 0, fmt, args);
return ret;
s = grub_vsnprintf_real (buf, PREALLOC_SIZE, fmt, args);
if (s > PREALLOC_SIZE)
{
curbuf = grub_malloc (s + 1);
if (!curbuf)
{
grub_errno = GRUB_ERR_NONE;
buf[PREALLOC_SIZE - 3] = '.';
buf[PREALLOC_SIZE - 2] = '.';
buf[PREALLOC_SIZE - 1] = '.';
buf[PREALLOC_SIZE] = 0;
}
else
s = grub_vsnprintf_real (curbuf, s, fmt, args);
}
grub_xputs (curbuf);
if (curbuf != buf)
grub_free (curbuf);
return s;
}
int
@ -649,13 +660,8 @@ grub_vsnprintf_real (char *str, grub_size_t max_len, const char *fmt, va_list ar
void write_char (unsigned char ch)
{
if (str)
{
if (count < max_len)
*str++ = ch;
}
else
grub_putchar (ch);
if (count < max_len)
*str++ = ch;
count++;
}
@ -872,8 +878,7 @@ grub_vsnprintf_real (char *str, grub_size_t max_len, const char *fmt, va_list ar
}
}
if (str)
*str = '\0';
*str = '\0';
return count;
}
@ -906,8 +911,6 @@ grub_snprintf (char *str, grub_size_t n, const char *fmt, ...)
return ret;
}
#define PREALLOC_SIZE 255
char *
grub_xvasprintf (const char *fmt, va_list ap)
{
@ -942,100 +945,6 @@ grub_xasprintf (const char *fmt, ...)
return ret;
}
/* Convert a (possibly null-terminated) UTF-8 string of at most SRCSIZE
bytes (if SRCSIZE is -1, it is ignored) in length to a UCS-4 string.
Return the number of characters converted. DEST must be able to hold
at least DESTSIZE characters.
If SRCEND is not NULL, then *SRCEND is set to the next byte after the
last byte used in SRC. */
grub_size_t
grub_utf8_to_ucs4 (grub_uint32_t *dest, grub_size_t destsize,
const grub_uint8_t *src, grub_size_t srcsize,
const grub_uint8_t **srcend)
{
grub_uint32_t *p = dest;
int count = 0;
grub_uint32_t code = 0;
if (srcend)
*srcend = src;
while (srcsize && destsize)
{
grub_uint32_t c = *src++;
if (srcsize != (grub_size_t)-1)
srcsize--;
if (count)
{
if ((c & 0xc0) != 0x80)
{
/* invalid */
code = '?';
/* Character c may be valid, don't eat it. */
src--;
if (srcsize != (grub_size_t)-1)
srcsize++;
count = 0;
}
else
{
code <<= 6;
code |= (c & 0x3f);
count--;
}
}
else
{
if (c == 0)
break;
if ((c & 0x80) == 0x00)
code = c;
else if ((c & 0xe0) == 0xc0)
{
count = 1;
code = c & 0x1f;
}
else if ((c & 0xf0) == 0xe0)
{
count = 2;
code = c & 0x0f;
}
else if ((c & 0xf8) == 0xf0)
{
count = 3;
code = c & 0x07;
}
else if ((c & 0xfc) == 0xf8)
{
count = 4;
code = c & 0x03;
}
else if ((c & 0xfe) == 0xfc)
{
count = 5;
code = c & 0x01;
}
else
{
/* invalid */
code = '?';
count = 0;
}
}
if (count == 0)
{
*p++ = code;
destsize--;
}
}
if (srcend)
*srcend = src;
return p - dest;
}
/* Abort GRUB. This function does not return. */
void
grub_abort (void)

View File

@ -34,6 +34,7 @@ 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);
@ -44,24 +45,28 @@ grub_rescue_read_line (char **line, int cont)
{
if (pos < GRUB_RESCUE_BUF_SIZE - 1)
{
str[0] = c;
str[1] = 0;
linebuf[pos++] = c;
grub_putchar (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_putchar (c);
grub_putchar (' ');
grub_putchar (c);
grub_xputs (str);
}
}
grub_refresh ();
}
grub_putchar ('\n');
grub_xputs ("\n");
grub_refresh ();
*line = grub_strdup (linebuf);

View File

@ -24,7 +24,7 @@
#include <grub/misc.h>
#include <grub/time.h>
#include <grub/machine/boot.h>
#include <grub/machine/console.h>
#include <grub/ieee1275/console.h>
#include <grub/machine/kernel.h>
#include <grub/machine/time.h>
#include <grub/ieee1275/ofdisk.h>
@ -155,8 +155,9 @@ void
grub_machine_init (void)
{
grub_ieee1275_init ();
grub_console_init ();
grub_console_init_early ();
grub_heap_init ();
grub_console_init_lately ();
grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_NO_PARTITION_0);
grub_ofdisk_init ();

View File

@ -28,53 +28,54 @@ struct grub_term_input *grub_term_inputs_disabled;
struct grub_term_output *grub_term_outputs;
struct grub_term_input *grub_term_inputs;
void (*grub_newline_hook) (void) = NULL;
/* Put a Unicode character. */
void
grub_putcode (grub_uint32_t code, struct grub_term_output *term)
static void
grub_putcode_dumb (grub_uint32_t code,
struct grub_term_output *term)
{
struct grub_unicode_glyph c =
{
.base = code,
.variant = 0,
.attributes = 0,
.ncomb = 0,
.combining = 0,
.estimated_width = 1
};
if (code == '\t' && term->getxy)
{
int n;
n = 8 - ((term->getxy () >> 8) & 7);
n = 8 - ((term->getxy (term) >> 8) & 7);
while (n--)
grub_putcode (' ', term);
grub_putcode_dumb (' ', term);
return;
}
(term->putchar) (code);
(term->putchar) (term, &c);
if (code == '\n')
(term->putchar) ('\r');
grub_putcode_dumb ('\r', term);
}
/* Put a character. C is one byte of a UTF-8 stream.
This function gathers bytes until a valid Unicode character is found. */
void
grub_putchar (int c)
static void
grub_xputs_dumb (const char *str)
{
static grub_size_t size = 0;
static grub_uint8_t buf[6];
grub_uint8_t *rest;
grub_uint32_t code;
buf[size++] = c;
while (grub_utf8_to_ucs4 (&code, 1, buf, size, (const grub_uint8_t **) &rest)
!= 0)
for (; *str; str++)
{
struct grub_term_output *term;
size -= rest - buf;
grub_memmove (buf, rest, size);
grub_term_output_t term;
grub_uint32_t code = *str;
if (code > 0x7f)
code = '?';
FOR_ACTIVE_TERM_OUTPUTS(term)
grub_putcode (code, term);
if (code == '\n' && grub_newline_hook)
grub_newline_hook ();
grub_putcode_dumb (code, term);
}
}
void (*grub_xputs) (const char *str) = grub_xputs_dumb;
int
grub_getkey (void)
{
@ -86,9 +87,9 @@ grub_getkey (void)
{
FOR_ACTIVE_TERM_INPUTS(term)
{
int key = term->checkkey ();
int key = term->checkkey (term);
if (key != -1)
return term->getkey ();
return term->getkey (term);
}
grub_cpu_idle ();
@ -102,7 +103,7 @@ grub_checkkey (void)
FOR_ACTIVE_TERM_INPUTS(term)
{
int key = term->checkkey ();
int key = term->checkkey (term);
if (key != -1)
return key;
}
@ -119,38 +120,12 @@ grub_getkeystatus (void)
FOR_ACTIVE_TERM_INPUTS(term)
{
if (term->getkeystatus)
status |= term->getkeystatus ();
status |= term->getkeystatus (term);
}
return status;
}
void
grub_cls (void)
{
struct grub_term_output *term;
FOR_ACTIVE_TERM_OUTPUTS(term)
{
if ((term->flags & GRUB_TERM_DUMB) || (grub_env_get ("debug")))
{
grub_putcode ('\n', term);
grub_term_refresh (term);
}
else
(term->cls) ();
}
}
void
grub_setcolorstate (grub_term_color_state state)
{
struct grub_term_output *term;
FOR_ACTIVE_TERM_OUTPUTS(term)
grub_term_setcolorstate (term, state);
}
void
grub_refresh (void)
{

View File

@ -144,21 +144,8 @@ grub_arg_show_help (grub_extcmd_t cmd)
}
}
const char *doc = _(opt->doc);
for (;;)
{
while (spacing-- > 0)
grub_putchar (' ');
while (*doc && *doc != '\n')
grub_putchar (*doc++);
grub_putchar ('\n');
if (! *doc)
break;
doc++;
spacing = 4 + 20;
}
/* FIXME: add spacing back. */
grub_xputs (_(opt->doc));
switch (opt->shortarg)
{

View File

@ -1,269 +0,0 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009 Free Software Foundation, Inc.
*
* GRUB 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.
*
* GRUB 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 GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
/* Convert a (possibly null-terminated) UTF-8 string of at most SRCSIZE
bytes (if SRCSIZE is -1, it is ignored) in length to a UTF-16 string.
Return the number of characters converted. DEST must be able to hold
at least DESTSIZE characters. If an invalid sequence is found, return -1.
If SRCEND is not NULL, then *SRCEND is set to the next byte after the
last byte used in SRC. */
#include <grub/charset.h>
#include <grub/mm.h>
#include <grub/misc.h>
grub_ssize_t
grub_utf8_to_utf16 (grub_uint16_t *dest, grub_size_t destsize,
const grub_uint8_t *src, grub_size_t srcsize,
const grub_uint8_t **srcend)
{
grub_uint16_t *p = dest;
int count = 0;
grub_uint32_t code = 0;
if (srcend)
*srcend = src;
while (srcsize && destsize)
{
grub_uint32_t c = *src++;
if (srcsize != (grub_size_t)-1)
srcsize--;
if (count)
{
if ((c & GRUB_UINT8_2_LEADINGBITS) != GRUB_UINT8_1_LEADINGBIT)
{
/* invalid */
return -1;
}
else
{
code <<= 6;
code |= (c & GRUB_UINT8_6_TRAILINGBITS);
count--;
}
}
else
{
if (c == 0)
break;
if ((c & GRUB_UINT8_1_LEADINGBIT) == 0)
code = c;
else if ((c & GRUB_UINT8_3_LEADINGBITS) == GRUB_UINT8_2_LEADINGBITS)
{
count = 1;
code = c & GRUB_UINT8_5_TRAILINGBITS;
}
else if ((c & GRUB_UINT8_4_LEADINGBITS) == GRUB_UINT8_3_LEADINGBITS)
{
count = 2;
code = c & GRUB_UINT8_4_TRAILINGBITS;
}
else if ((c & GRUB_UINT8_5_LEADINGBITS) == GRUB_UINT8_4_LEADINGBITS)
{
count = 3;
code = c & GRUB_UINT8_3_TRAILINGBITS;
}
else if ((c & GRUB_UINT8_6_LEADINGBITS) == GRUB_UINT8_5_LEADINGBITS)
{
count = 4;
code = c & GRUB_UINT8_2_TRAILINGBITS;
}
else if ((c & GRUB_UINT8_7_LEADINGBITS) == GRUB_UINT8_6_LEADINGBITS)
{
count = 5;
code = c & GRUB_UINT8_1_TRAILINGBIT;
}
else
return -1;
}
if (count == 0)
{
if (destsize < 2 && code >= GRUB_UCS2_LIMIT)
break;
if (code >= GRUB_UCS2_LIMIT)
{
*p++ = GRUB_UTF16_UPPER_SURROGATE (code);
*p++ = GRUB_UTF16_LOWER_SURROGATE (code);
destsize -= 2;
}
else
{
*p++ = code;
destsize--;
}
}
}
if (srcend)
*srcend = src;
return p - dest;
}
/* Convert UCS-4 to UTF-8. */
char *
grub_ucs4_to_utf8_alloc (grub_uint32_t *src, grub_size_t size)
{
grub_size_t remaining;
grub_uint32_t *ptr;
grub_size_t cnt = 0;
grub_uint8_t *ret, *dest;
remaining = size;
ptr = src;
while (remaining--)
{
grub_uint32_t code = *ptr++;
if (code <= 0x007F)
cnt++;
else if (code <= 0x07FF)
cnt += 2;
else if ((code >= 0xDC00 && code <= 0xDFFF)
|| (code >= 0xD800 && code <= 0xDBFF))
/* No surrogates in UCS-4... */
cnt++;
else
cnt += 3;
}
cnt++;
ret = grub_malloc (cnt);
if (!ret)
return 0;
dest = ret;
remaining = size;
ptr = src;
while (remaining--)
{
grub_uint32_t code = *ptr++;
if (code <= 0x007F)
*dest++ = code;
else if (code <= 0x07FF)
{
*dest++ = (code >> 6) | 0xC0;
*dest++ = (code & 0x3F) | 0x80;
}
else if ((code >= 0xDC00 && code <= 0xDFFF)
|| (code >= 0xD800 && code <= 0xDBFF))
{
/* No surrogates in UCS-4... */
*dest++ = '?';
}
else
{
*dest++ = (code >> 12) | 0xE0;
*dest++ = ((code >> 6) & 0x3F) | 0x80;
*dest++ = (code & 0x3F) | 0x80;
}
}
*dest = 0;
return (char *) ret;
}
int
grub_is_valid_utf8 (const grub_uint8_t *src, grub_size_t srcsize)
{
grub_uint32_t code = 0;
int count = 0;
while (srcsize)
{
grub_uint32_t c = *src++;
if (srcsize != (grub_size_t)-1)
srcsize--;
if (count)
{
if ((c & 0xc0) != 0x80)
{
/* invalid */
return 0;
}
else
{
code <<= 6;
code |= (c & 0x3f);
count--;
}
}
else
{
if (c == 0)
break;
if ((c & 0x80) == 0x00)
code = c;
else if ((c & 0xe0) == 0xc0)
{
count = 1;
code = c & 0x1f;
}
else if ((c & 0xf0) == 0xe0)
{
count = 2;
code = c & 0x0f;
}
else if ((c & 0xf8) == 0xf0)
{
count = 3;
code = c & 0x07;
}
else if ((c & 0xfc) == 0xf8)
{
count = 4;
code = c & 0x03;
}
else if ((c & 0xfe) == 0xfc)
{
count = 5;
code = c & 0x01;
}
else
return 0;
}
}
return 1;
}
int
grub_utf8_to_ucs4_alloc (const char *msg, grub_uint32_t **unicode_msg,
grub_uint32_t **last_position)
{
grub_size_t msg_len = grub_strlen (msg);
*unicode_msg = grub_malloc (grub_strlen (msg) * sizeof (grub_uint32_t));
if (!*unicode_msg)
{
grub_printf ("utf8_to_ucs4 ERROR1: %s", msg);
return -1;
}
msg_len = grub_utf8_to_ucs4 (*unicode_msg, msg_len,
(grub_uint8_t *) msg, -1, 0);
*last_position = *unicode_msg + msg_len;
return msg_len;
}

View File

@ -445,7 +445,7 @@ grub_password_get (char buf[], unsigned buf_size)
grub_memset (buf + cur_len, 0, buf_size - cur_len);
grub_putchar ('\n');
grub_xputs ("\n");
grub_refresh ();
return (key != '\e');

View File

@ -184,13 +184,13 @@ grub_username_get (char buf[], unsigned buf_size)
if (cur_len + 2 < buf_size)
{
buf[cur_len++] = key;
grub_putchar (key);
grub_printf ("%c", key);
}
}
grub_memset (buf + cur_len, 0, buf_size - cur_len);
grub_putchar ('\n');
grub_xputs ("\n");
grub_refresh ();
return (key != '\e');

1294
normal/charset.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -362,6 +362,7 @@ grub_cmdline_get (const char *prompt)
grub_putcode ('\n', term);
}
grub_printf ("%s ", prompt_translated);
grub_normal_reset_more ();
{
struct cmdline_term *cl_term_cur;
@ -440,6 +441,8 @@ grub_cmdline_get (const char *prompt)
print_completion);
grub_free (bufu8);
grub_normal_reset_more ();
if (restore)
{
/* Restore the prompt. */
@ -614,7 +617,7 @@ grub_cmdline_get (const char *prompt)
grub_refresh ();
}
grub_putchar ('\n');
grub_xputs ("\n");
grub_refresh ();
/* Remove leading spaces. */

View File

@ -436,8 +436,9 @@ grub_normal_init_page (struct grub_term_output *term)
posx = (grub_term_width (term) - posx) / 2;
grub_term_gotoxy (term, posx, 1);
grub_print_ucs4 (unicode_msg, last_position, term);
grub_printf("\n\n");
grub_print_ucs4 (unicode_msg, last_position, 0, 0, term);
grub_putcode ('\n', term);
grub_putcode ('\n', term);
grub_free (unicode_msg);
}
@ -567,9 +568,10 @@ grub_normal_reader_init (int nested)
{
grub_normal_init_page (term);
grub_term_setcursor (term, 1);
grub_print_message_indented (msg_formatted, 3, STANDARD_MARGIN, term);
grub_puts ("\n");
grub_putcode ('\n', term);
grub_putcode ('\n', term);
}
grub_free (msg_formatted);
@ -656,17 +658,37 @@ grub_env_write_pager (struct grub_env_var *var __attribute__ ((unused)),
return grub_strdup (val);
}
/* clear */
static grub_err_t
grub_mini_cmd_clear (struct grub_command *cmd __attribute__ ((unused)),
int argc __attribute__ ((unused)),
char *argv[] __attribute__ ((unused)))
{
grub_cls ();
return 0;
}
static grub_command_t cmd_clear;
static void (*grub_xputs_saved) (const char *str);
GRUB_MOD_INIT(normal)
{
grub_context_init ();
grub_xputs_saved = grub_xputs;
grub_xputs = grub_xputs_normal;
/* Normal mode shouldn't be unloaded. */
if (mod)
grub_dl_ref (mod);
cmd_clear =
grub_register_command ("clear", grub_mini_cmd_clear,
0, N_("Clear the screen."));
grub_set_history (GRUB_DEFAULT_HISTORY_SIZE);
grub_install_newline_hook ();
grub_register_variable_hook ("pager", 0, grub_env_write_pager);
/* Register a command "normal" for the rescue mode. */
@ -688,7 +710,10 @@ GRUB_MOD_FINI(normal)
{
grub_context_fini ();
grub_xputs = grub_xputs_saved;
grub_set_history (0);
grub_register_variable_hook ("pager", 0, 0);
grub_fs_autoload_hook = 0;
grub_unregister_command (cmd_clear);
}

View File

@ -43,10 +43,10 @@ grub_err_t (*grub_gfxmenu_try_hook) (int entry, grub_menu_t menu,
void
grub_wait_after_message (void)
{
grub_putchar ('\n');
grub_xputs ("\n");
grub_printf_ (N_("Press any key to continue..."));
(void) grub_getkey ();
grub_putchar ('\n');
grub_xputs ("\n");
}
/* Get a menu entry by its index in the entry list. */
@ -285,7 +285,6 @@ menu_init (int entry, grub_menu_t menu, int nested)
err = grub_gfxmenu_try_hook (entry, menu, nested);
if(!err)
continue;
grub_print_error ();
grub_errno = GRUB_ERR_NONE;
}
@ -610,13 +609,13 @@ show_menu (grub_menu_t menu, int nested)
}
else
{
int lines_before = grub_normal_get_line_counter ();
int chars_before = grub_normal_get_char_counter ();
grub_errno = GRUB_ERR_NONE;
grub_menu_execute_entry (e);
grub_print_error ();
grub_errno = GRUB_ERR_NONE;
if (lines_before != grub_normal_get_line_counter ())
if (chars_before != grub_normal_get_char_counter ())
grub_wait_after_message ();
}
}

View File

@ -26,6 +26,7 @@
#include <grub/script_sh.h>
#include <grub/auth.h>
#include <grub/i18n.h>
#include <grub/charset.h>
enum update_mode
{
@ -173,7 +174,7 @@ print_up (int flag, struct per_term_screen *term_screen)
GRUB_TERM_FIRST_ENTRY_Y);
if (flag)
grub_putcode (GRUB_TERM_DISP_UP, term_screen->term);
grub_putcode (GRUB_UNICODE_UPARROW, term_screen->term);
else
grub_putcode (' ', term_screen->term);
}
@ -188,7 +189,7 @@ print_down (int flag, struct per_term_screen *term_screen)
+ grub_term_num_entries (term_screen->term));
if (flag)
grub_putcode (GRUB_TERM_DISP_DOWN, term_screen->term);
grub_putcode (GRUB_UNICODE_DOWNARROW, term_screen->term);
else
grub_putcode (' ', term_screen->term);
}
@ -243,6 +244,9 @@ update_screen (struct screen *screen, struct per_term_screen *term_screen,
{
int column;
if (linep >= screen->lines + screen->num_lines)
break;
for (column = 0;
column <= linep->len
&& y < grub_term_num_entries (term_screen->term);
@ -337,7 +341,7 @@ insert_string (struct screen *screen, char *s, int update)
screen->num_lines++;
screen->lines = grub_realloc (screen->lines,
screen->num_lines
* sizeof (struct line));
* sizeof (screen->lines[0]));
if (! screen->lines)
return 0;
@ -1020,87 +1024,92 @@ complete (struct screen *screen, int continuous, int update)
insert = grub_normal_do_completion (linep->buf, &restore, store_completion);
linep->buf[screen->column] = saved_char;
buflen = grub_strlen (completion_buffer.buf);
ucs4 = grub_malloc (sizeof (grub_uint32_t) * (buflen + 1));
if (!ucs4)
if (completion_buffer.buf)
{
grub_print_error ();
grub_errno = GRUB_ERR_NONE;
return 1;
}
buflen = grub_strlen (completion_buffer.buf);
ucs4 = grub_malloc (sizeof (grub_uint32_t) * (buflen + 1));
if (!ucs4)
{
grub_print_error ();
grub_errno = GRUB_ERR_NONE;
return 1;
}
ucs4len = grub_utf8_to_ucs4 (ucs4, buflen,
(grub_uint8_t *) completion_buffer.buf,
buflen, 0);
ucs4[ucs4len] = 0;
ucs4len = grub_utf8_to_ucs4 (ucs4, buflen,
(grub_uint8_t *) completion_buffer.buf,
buflen, 0);
ucs4[ucs4len] = 0;
if (restore)
for (i = 0; i < screen->nterms; i++)
{
int num_sections = ((completion_buffer.len
+ grub_term_width (screen->terms[i].term) - 8 - 1)
/ (grub_term_width (screen->terms[i].term) - 8));
grub_uint32_t *endp;
grub_uint16_t pos;
grub_uint32_t *p = ucs4;
pos = grub_term_getxy (screen->terms[i].term);
grub_term_gotoxy (screen->terms[i].term, 0,
grub_term_height (screen->terms[i].term) - 3);
screen->completion_shown = 1;
grub_term_gotoxy (screen->terms[i].term, 0,
grub_term_height (screen->terms[i].term) - 3);
grub_puts_terminal (" ", screen->terms[i].term);
switch (completion_type)
if (restore)
for (i = 0; i < screen->nterms; i++)
{
case GRUB_COMPLETION_TYPE_COMMAND:
grub_puts_terminal (_("Possible commands are:"),
screen->terms[i].term);
break;
case GRUB_COMPLETION_TYPE_DEVICE:
grub_puts_terminal (_("Possible devices are:"),
screen->terms[i].term);
break;
case GRUB_COMPLETION_TYPE_FILE:
grub_puts_terminal (_("Possible files are:"),
screen->terms[i].term);
break;
case GRUB_COMPLETION_TYPE_PARTITION:
grub_puts_terminal (_("Possible partitions are:"),
screen->terms[i].term);
break;
case GRUB_COMPLETION_TYPE_ARGUMENT:
grub_puts_terminal (_("Possible arguments are:"),
screen->terms[i].term);
break;
default:
grub_puts_terminal (_("Possible things are:"),
screen->terms[i].term);
break;
int num_sections = ((completion_buffer.len
+ grub_term_width (screen->terms[i].term)
- 8 - 1)
/ (grub_term_width (screen->terms[i].term)
- 8));
grub_uint32_t *endp;
grub_uint16_t pos;
grub_uint32_t *p = ucs4;
pos = grub_term_getxy (screen->terms[i].term);
grub_term_gotoxy (screen->terms[i].term, 0,
grub_term_height (screen->terms[i].term) - 3);
screen->completion_shown = 1;
grub_term_gotoxy (screen->terms[i].term, 0,
grub_term_height (screen->terms[i].term) - 3);
grub_puts_terminal (" ", screen->terms[i].term);
switch (completion_type)
{
case GRUB_COMPLETION_TYPE_COMMAND:
grub_puts_terminal (_("Possible commands are:"),
screen->terms[i].term);
break;
case GRUB_COMPLETION_TYPE_DEVICE:
grub_puts_terminal (_("Possible devices are:"),
screen->terms[i].term);
break;
case GRUB_COMPLETION_TYPE_FILE:
grub_puts_terminal (_("Possible files are:"),
screen->terms[i].term);
break;
case GRUB_COMPLETION_TYPE_PARTITION:
grub_puts_terminal (_("Possible partitions are:"),
screen->terms[i].term);
break;
case GRUB_COMPLETION_TYPE_ARGUMENT:
grub_puts_terminal (_("Possible arguments are:"),
screen->terms[i].term);
break;
default:
grub_puts_terminal (_("Possible things are:"),
screen->terms[i].term);
break;
}
grub_puts_terminal ("\n ", screen->terms[i].term);
p += (count % num_sections)
* (grub_term_width (screen->terms[i].term) - 8);
endp = p + (grub_term_width (screen->terms[i].term) - 8);
if (p != ucs4)
grub_putcode (GRUB_UNICODE_LEFTARROW, screen->terms[i].term);
else
grub_putcode (' ', screen->terms[i].term);
grub_print_ucs4 (p, ucs4 + ucs4len < endp ? ucs4 + ucs4len : endp,
0, 0, screen->terms[i].term);
if (ucs4 + ucs4len > endp)
grub_putcode (GRUB_UNICODE_RIGHTARROW, screen->terms[i].term);
grub_term_gotoxy (screen->terms[i].term, pos >> 8, pos & 0xFF);
}
grub_puts_terminal ("\n ", screen->terms[i].term);
p += (count % num_sections)
* (grub_term_width (screen->terms[i].term) - 8);
endp = p + (grub_term_width (screen->terms[i].term) - 8);
if (p != ucs4)
grub_putcode (GRUB_TERM_DISP_LEFT, screen->terms[i].term);
else
grub_putcode (' ', screen->terms[i].term);
while (*p && p < endp)
grub_putcode (*p++, screen->terms[i].term);
if (*p)
grub_putcode (GRUB_TERM_DISP_RIGHT, screen->terms[i].term);
grub_term_gotoxy (screen->terms[i].term, pos >> 8, pos & 0xFF);
}
}
if (insert)
{
@ -1362,8 +1371,13 @@ grub_menu_entry_run (grub_menu_entry_t entry)
goto refresh;
case 24: /* C-x */
if (! run (screen))
goto fail;
{
int chars_before = grub_normal_get_char_counter ();
run (screen);
if (chars_before != grub_normal_get_char_counter ())
grub_wait_after_message ();
}
goto refresh;
case 18: /* C-r */
@ -1394,7 +1408,7 @@ grub_menu_entry_run (grub_menu_entry_t entry)
grub_cls ();
grub_print_error ();
grub_errno = GRUB_ERR_NONE;
grub_putchar ('\n');
grub_xputs ("\n");
grub_printf_ (N_("Press any key to continue..."));
(void) grub_getkey ();
}

View File

@ -38,26 +38,6 @@ struct menu_viewer_data
struct grub_term_output *term;
};
static void
print_spaces (int number_spaces, struct grub_term_output *term)
{
int i;
for (i = 0; i < number_spaces; i++)
grub_putcode (' ', term);
}
void
grub_print_ucs4 (const grub_uint32_t * str,
const grub_uint32_t * last_position,
struct grub_term_output *term)
{
while (str < last_position)
{
grub_putcode (*str, term);
str++;
}
}
grub_ssize_t
grub_getstringwidth (grub_uint32_t * str, const grub_uint32_t * last_position,
struct grub_term_output *term)
@ -66,8 +46,9 @@ grub_getstringwidth (grub_uint32_t * str, const grub_uint32_t * last_position,
while (str < last_position)
{
width += grub_term_getcharwidth (term, *str);
str++;
struct grub_unicode_glyph glyph;
str += grub_unicode_aglomerate_comb (str, last_position - str, &glyph);
width += grub_term_getcharwidth (term, &glyph);
}
return width;
}
@ -76,16 +57,11 @@ void
grub_print_message_indented (const char *msg, int margin_left, int margin_right,
struct grub_term_output *term)
{
int line_len;
grub_uint32_t *unicode_msg;
grub_uint32_t *last_position;
int msg_len;
line_len = grub_term_width (term) - grub_term_getcharwidth (term, 'm') *
(margin_left + margin_right);
msg_len = grub_utf8_to_ucs4_alloc (msg, &unicode_msg, &last_position);
if (msg_len < 0)
@ -93,40 +69,8 @@ grub_print_message_indented (const char *msg, int margin_left, int margin_right,
return;
}
grub_uint32_t *current_position = unicode_msg;
grub_print_ucs4 (unicode_msg, last_position, margin_left, margin_right, term);
grub_uint32_t *next_new_line = unicode_msg;
int first_loop = 1;
while (current_position < last_position)
{
if (! first_loop)
grub_putcode ('\n', term);
next_new_line = (grub_uint32_t *) last_position;
while (grub_getstringwidth (current_position, next_new_line,term)
> line_len
|| (next_new_line != last_position && *next_new_line != ' '
&& next_new_line > current_position))
{
next_new_line--;
}
if (next_new_line == current_position)
{
next_new_line = (next_new_line + line_len > last_position) ?
(grub_uint32_t *) last_position : next_new_line + line_len;
}
print_spaces (margin_left, term);
grub_print_ucs4 (current_position, next_new_line, term);
next_new_line++;
current_position = next_new_line;
first_loop = 0;
}
grub_free (unicode_msg);
}
@ -139,27 +83,27 @@ draw_border (struct grub_term_output *term)
grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL);
grub_term_gotoxy (term, GRUB_TERM_MARGIN, GRUB_TERM_TOP_BORDER_Y);
grub_putcode (GRUB_TERM_DISP_UL, term);
grub_putcode (GRUB_UNICODE_CORNER_UL, term);
for (i = 0; i < (unsigned) grub_term_border_width (term) - 2; i++)
grub_putcode (GRUB_TERM_DISP_HLINE, term);
grub_putcode (GRUB_TERM_DISP_UR, term);
grub_putcode (GRUB_UNICODE_HLINE, term);
grub_putcode (GRUB_UNICODE_CORNER_UR, term);
for (i = 0; i < (unsigned) grub_term_num_entries (term); i++)
{
grub_term_gotoxy (term, GRUB_TERM_MARGIN, GRUB_TERM_TOP_BORDER_Y + i + 1);
grub_putcode (GRUB_TERM_DISP_VLINE, term);
grub_putcode (GRUB_UNICODE_VLINE, term);
grub_term_gotoxy (term, GRUB_TERM_MARGIN + grub_term_border_width (term)
- 1,
GRUB_TERM_TOP_BORDER_Y + i + 1);
grub_putcode (GRUB_TERM_DISP_VLINE, term);
grub_putcode (GRUB_UNICODE_VLINE, term);
}
grub_term_gotoxy (term, GRUB_TERM_MARGIN,
GRUB_TERM_TOP_BORDER_Y + grub_term_num_entries (term) + 1);
grub_putcode (GRUB_TERM_DISP_LL, term);
grub_putcode (GRUB_UNICODE_CORNER_LL, term);
for (i = 0; i < (unsigned) grub_term_border_width (term) - 2; i++)
grub_putcode (GRUB_TERM_DISP_HLINE, term);
grub_putcode (GRUB_TERM_DISP_LR, term);
grub_putcode (GRUB_UNICODE_HLINE, term);
grub_putcode (GRUB_UNICODE_CORNER_LR, term);
grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL);
@ -194,11 +138,11 @@ command-line or ESC to discard edits and return to the GRUB menu."),
"entry is highlighted.\n");
char *msg_translated;
msg_translated = grub_xasprintf (msg, (grub_uint32_t) GRUB_TERM_DISP_UP,
(grub_uint32_t) GRUB_TERM_DISP_DOWN);
msg_translated = grub_xasprintf (msg, GRUB_UNICODE_UPARROW,
GRUB_UNICODE_DOWNARROW);
if (!msg_translated)
return;
grub_putchar ('\n');
grub_putcode ('\n', term);
grub_print_message_indented (msg_translated, STANDARD_MARGIN,
STANDARD_MARGIN, term);
@ -259,34 +203,55 @@ print_entry (int y, int highlight, grub_menu_entry_t entry,
grub_term_gotoxy (term, GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN, y);
int last_printed = 0;
for (x = GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN + 1, i = 0;
x < (int) (GRUB_TERM_LEFT_BORDER_X + grub_term_border_width (term)
- GRUB_TERM_MARGIN);
i++)
- GRUB_TERM_MARGIN);)
{
if (i < len
&& x <= (int) (GRUB_TERM_LEFT_BORDER_X + grub_term_border_width (term)
- GRUB_TERM_MARGIN - 1))
{
grub_ssize_t width;
struct grub_unicode_glyph glyph;
width = grub_term_getcharwidth (term, unicode_title[i]);
i += grub_unicode_aglomerate_comb (unicode_title + i,
len - i, &glyph);
if (x + width > (int) (GRUB_TERM_LEFT_BORDER_X
width = grub_term_getcharwidth (term, &glyph);
grub_free (glyph.combining);
if (x + width <= (int) (GRUB_TERM_LEFT_BORDER_X
+ grub_term_border_width (term)
- GRUB_TERM_MARGIN - 1))
grub_putcode (GRUB_TERM_DISP_RIGHT, term);
else
grub_putcode (unicode_title[i], term);
last_printed = i;
x += width;
}
else
{
grub_putcode (' ', term);
x++;
}
break;
}
grub_print_ucs4 (unicode_title,
unicode_title + last_printed, 0, 0, term);
if (last_printed != len)
{
grub_putcode (GRUB_UNICODE_RIGHTARROW, term);
struct grub_unicode_glyph pseudo_glyph = {
.base = GRUB_UNICODE_RIGHTARROW,
.variant = 0,
.attributes = 0,
.ncomb = 0,
.combining = 0,
.estimated_width = 1
};
x += grub_term_getcharwidth (term, &pseudo_glyph);
}
for (; x < (int) (GRUB_TERM_LEFT_BORDER_X + grub_term_border_width (term)
- GRUB_TERM_MARGIN); x++)
grub_putcode (' ', term);
grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL);
grub_putcode (' ', term);
@ -309,7 +274,7 @@ print_entries (grub_menu_t menu, int first, int offset,
GRUB_TERM_FIRST_ENTRY_Y);
if (first)
grub_putcode (GRUB_TERM_DISP_UP, term);
grub_putcode (GRUB_UNICODE_UPARROW, term);
else
grub_putcode (' ', term);
@ -327,7 +292,7 @@ print_entries (grub_menu_t menu, int first, int offset,
GRUB_TERM_TOP_BORDER_Y + grub_term_num_entries (term));
if (e)
grub_putcode (GRUB_TERM_DISP_DOWN, term);
grub_putcode (GRUB_UNICODE_DOWNARROW, term);
else
grub_putcode (' ', term);
@ -385,7 +350,7 @@ menu_text_print_timeout (int timeout, void *dataptr)
grub_print_message_indented (msg_translated, 3, 0, data->term);
posx = grub_term_getxy (data->term) >> 8;
print_spaces (grub_term_width (data->term) - posx - 1, data->term);
grub_print_spaces (data->term, grub_term_width (data->term) - posx - 1);
grub_term_gotoxy (data->term,
grub_term_cursor_x (data->term),
@ -443,7 +408,7 @@ menu_text_clear_timeout (void *dataptr)
struct menu_viewer_data *data = dataptr;
grub_term_gotoxy (data->term, 0, grub_term_height (data->term) - 3);
print_spaces (grub_term_width (data->term) - 1, data->term);
grub_print_spaces (data->term, grub_term_width (data->term) - 1);
grub_term_gotoxy (data->term, grub_term_cursor_x (data->term),
GRUB_TERM_FIRST_ENTRY_Y + data->offset);
grub_term_refresh (data->term);

View File

@ -37,14 +37,14 @@ grub_normal_print_device_info (const char *name)
p = grub_strchr (name, ',');
if (p)
{
grub_putchar ('\t');
grub_xputs ("\t");
grub_printf_ (N_("Partition %s:"), name);
grub_putchar (' ');
grub_xputs (" ");
}
else
{
grub_printf_ (N_("Device %s:"), name);
grub_putchar (' ');
grub_xputs (" ");
}
dev = grub_device_open (name);
@ -69,7 +69,7 @@ grub_normal_print_device_info (const char *name)
{
if (label && grub_strlen (label))
{
grub_putchar (' ');
grub_xputs (" ");
grub_printf_ (N_("- Label \"%s\""), label);
}
grub_free (label);
@ -84,7 +84,7 @@ grub_normal_print_device_info (const char *name)
if (grub_errno == GRUB_ERR_NONE)
{
grub_unixtime2datetime (tm, &datetime);
grub_putchar (' ');
grub_xputs (" ");
grub_printf_ (N_("- Last modification time %d-%02d-%02d "
"%02d:%02d:%02d %s"),
datetime.year, datetime.month, datetime.day,
@ -115,6 +115,6 @@ grub_normal_print_device_info (const char *name)
grub_device_close (dev);
}
grub_putchar ('\n');
grub_xputs ("\n");
return grub_errno;
}

View File

@ -23,57 +23,87 @@
#include <grub/dl.h>
#include <grub/env.h>
#include <grub/normal.h>
#include <grub/charset.h>
/* The amount of lines counted by the pager. */
static unsigned grub_more_lines;
struct term_state
{
struct term_state *next;
const struct grub_unicode_glyph *backlog_glyphs;
const grub_uint32_t *backlog_ucs4;
grub_size_t backlog_len;
void *free;
int num_lines;
char *term_name;
};
static struct term_state *term_states = NULL;
/* If the more pager is active. */
static int grub_more;
static int grub_normal_line_counter = 0;
static int grub_normal_char_counter = 0;
int
grub_normal_get_line_counter (void)
grub_normal_get_char_counter (void)
{
return grub_normal_line_counter;
return grub_normal_char_counter;
}
void
grub_normal_reset_more (void)
{
static struct term_state *state;
for (state = term_states; state; state = state->next)
state->num_lines = 0;
}
static void
process_newline (void)
print_more (void)
{
struct grub_term_output *cur;
unsigned height = -1;
char key;
grub_uint16_t *pos;
grub_term_output_t term;
grub_uint32_t *unicode_str, *unicode_last_position;
FOR_ACTIVE_TERM_OUTPUTS(cur)
if (grub_term_height (cur) < height)
height = grub_term_height (cur);
grub_more_lines++;
pos = grub_term_save_pos ();
grub_normal_line_counter++;
grub_utf8_to_ucs4_alloc ("--MORE--", &unicode_str,
&unicode_last_position);
if (grub_more && grub_more_lines >= height - 1)
if (!unicode_str)
{
char key;
grub_uint16_t *pos;
grub_errno = GRUB_ERR_NONE;
return;
}
pos = grub_term_save_pos ();
grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT);
grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT);
grub_printf ("--MORE--");
grub_setcolorstate (GRUB_TERM_COLOR_STANDARD);
FOR_ACTIVE_TERM_OUTPUTS(term)
{
grub_print_ucs4 (unicode_str, unicode_last_position, 0, 0, term);
}
grub_setcolorstate (GRUB_TERM_COLOR_STANDARD);
key = grub_getkey ();
grub_free (unicode_str);
key = grub_getkey ();
/* Remove the message. */
grub_term_restore_pos (pos);
grub_printf (" ");
grub_term_restore_pos (pos);
/* Remove the message. */
grub_term_restore_pos (pos);
FOR_ACTIVE_TERM_OUTPUTS(term)
grub_print_spaces (term, 8);
grub_term_restore_pos (pos);
/* Scroll one lines or an entire page, depending on the key. */
if (key == '\r' || key =='\n')
grub_more_lines = height - 2;
else
grub_more_lines = 0;
/* Scroll one lines or an entire page, depending on the key. */
if (key == '\r' || key =='\n')
grub_normal_reset_more ();
else
{
static struct term_state *state;
for (state = term_states; state; state = state->next)
state->num_lines -= 2;
}
}
@ -84,30 +114,99 @@ grub_set_more (int onoff)
grub_more++;
else
grub_more--;
grub_more_lines = 0;
grub_normal_reset_more ();
}
void
grub_install_newline_hook (void)
enum
{
GRUB_CP437_UPARROW = 0x18,
GRUB_CP437_DOWNARROW = 0x19,
GRUB_CP437_RIGHTARROW = 0x1a,
GRUB_CP437_LEFTARROW = 0x1b,
GRUB_CP437_VLINE = 0xb3,
GRUB_CP437_CORNER_UR = 0xbf,
GRUB_CP437_CORNER_LL = 0xc0,
GRUB_CP437_HLINE = 0xc4,
GRUB_CP437_CORNER_LR = 0xd9,
GRUB_CP437_CORNER_UL = 0xda,
};
static grub_uint32_t
map_code (grub_uint32_t in, struct grub_term_output *term)
{
grub_newline_hook = process_newline;
if (in <= 0x7f)
return in;
switch (term->flags & GRUB_TERM_CODE_TYPE_MASK)
{
case GRUB_TERM_CODE_TYPE_CP437:
switch (in)
{
case GRUB_UNICODE_LEFTARROW:
return GRUB_CP437_LEFTARROW;
case GRUB_UNICODE_UPARROW:
return GRUB_CP437_UPARROW;
case GRUB_UNICODE_RIGHTARROW:
return GRUB_CP437_RIGHTARROW;
case GRUB_UNICODE_DOWNARROW:
return GRUB_CP437_DOWNARROW;
case GRUB_UNICODE_HLINE:
return GRUB_CP437_HLINE;
case GRUB_UNICODE_VLINE:
return GRUB_CP437_VLINE;
case GRUB_UNICODE_CORNER_UL:
return GRUB_CP437_CORNER_UL;
case GRUB_UNICODE_CORNER_UR:
return GRUB_CP437_CORNER_UR;
case GRUB_UNICODE_CORNER_LL:
return GRUB_CP437_CORNER_LL;
case GRUB_UNICODE_CORNER_LR:
return GRUB_CP437_CORNER_LR;
}
return '?';
case GRUB_TERM_CODE_TYPE_ASCII:
/* Better than nothing. */
switch (in)
{
case GRUB_UNICODE_LEFTARROW:
return '<';
case GRUB_UNICODE_UPARROW:
return '^';
case GRUB_UNICODE_RIGHTARROW:
return '>';
case GRUB_UNICODE_DOWNARROW:
return 'v';
case GRUB_UNICODE_HLINE:
return '-';
case GRUB_UNICODE_VLINE:
return '|';
case GRUB_UNICODE_CORNER_UL:
case GRUB_UNICODE_CORNER_UR:
case GRUB_UNICODE_CORNER_LL:
case GRUB_UNICODE_CORNER_LR:
return '+';
}
return '?';
}
return in;
}
void
grub_puts_terminal (const char *str, struct grub_term_output *term)
{
grub_uint32_t code;
grub_ssize_t ret;
const grub_uint8_t *ptr = (const grub_uint8_t *) str;
const grub_uint8_t *end;
end = (const grub_uint8_t *) (str + grub_strlen (str));
grub_uint32_t *unicode_str, *unicode_last_position;
grub_utf8_to_ucs4_alloc (str, &unicode_str,
&unicode_last_position);
while (*ptr)
{
ret = grub_utf8_to_ucs4 (&code, 1, ptr, end - ptr, &ptr);
grub_putcode (code, term);
}
grub_print_ucs4 (unicode_str, unicode_last_position, 0, 0, term);
grub_free (unicode_str);
}
grub_uint16_t *
@ -262,3 +361,433 @@ read_terminal_list (const char *prefix)
grub_errno = GRUB_ERR_NONE;
}
static void
putglyph (const struct grub_unicode_glyph *c, struct grub_term_output *term)
{
struct grub_unicode_glyph c2 =
{
.variant = 0,
.attributes = 0,
.ncomb = 0,
.combining = 0,
.estimated_width = 1
};
grub_normal_char_counter++;
if (c->base == '\t' && term->getxy)
{
int n;
n = 8 - ((term->getxy (term) >> 8) & 7);
c2.base = ' ';
while (n--)
(term->putchar) (term, &c2);
return;
}
if ((term->flags & GRUB_TERM_CODE_TYPE_MASK)
== GRUB_TERM_CODE_TYPE_UTF8_LOGICAL
|| (term->flags & GRUB_TERM_CODE_TYPE_MASK)
== GRUB_TERM_CODE_TYPE_UTF8_VISUAL)
{
int i;
c2.estimated_width = grub_term_getcharwidth (term, c);
for (i = -1; i < (int) c->ncomb; i++)
{
grub_uint8_t u8[20], *ptr;
grub_uint32_t code;
if (i == -1)
{
code = c->base;
if ((term->flags & GRUB_TERM_CODE_TYPE_MASK)
== GRUB_TERM_CODE_TYPE_UTF8_VISUAL)
{
if ((c->attributes & GRUB_UNICODE_GLYPH_ATTRIBUTE_MIRROR))
code = grub_unicode_mirror_code (code);
code = grub_unicode_shape_code (code, c->attributes);
}
}
else
code = c->combining[i].code;
grub_ucs4_to_utf8 (&code, 1, u8, sizeof (u8));
for (ptr = u8; *ptr; ptr++)
{
c2.base = *ptr;
(term->putchar) (term, &c2);
c2.estimated_width = 0;
}
}
c2.estimated_width = 1;
}
else
(term->putchar) (term, c);
if (c->base == '\n')
{
c2.base = '\r';
(term->putchar) (term, &c2);
}
}
static void
putcode_real (grub_uint32_t code, struct grub_term_output *term)
{
struct grub_unicode_glyph c =
{
.variant = 0,
.attributes = 0,
.ncomb = 0,
.combining = 0,
.estimated_width = 1
};
c.base = map_code (code, term);
putglyph (&c, term);
}
/* Put a Unicode character. */
void
grub_putcode (grub_uint32_t code, struct grub_term_output *term)
{
/* Combining character by itself? */
if (grub_unicode_get_comb_type (code) != GRUB_UNICODE_COMB_NONE)
return;
putcode_real (code, term);
}
static grub_ssize_t
get_maxwidth (struct grub_term_output *term,
int margin_left, int margin_right)
{
struct grub_unicode_glyph space_glyph = {
.base = ' ',
.variant = 0,
.attributes = 0,
.ncomb = 0,
.combining = 0
};
return (grub_term_width (term)
- grub_term_getcharwidth (term, &space_glyph)
* (margin_left + margin_right) - 1);
}
static grub_ssize_t
get_startwidth (struct grub_term_output *term,
int margin_left)
{
return ((term->getxy (term) >> 8) & 0xff) - margin_left;
}
static int
print_ucs4_terminal (const grub_uint32_t * str,
const grub_uint32_t * last_position,
int margin_left, int margin_right,
struct grub_term_output *term,
struct term_state *state)
{
const grub_uint32_t *ptr;
grub_ssize_t startwidth = get_startwidth (term, margin_left);
grub_ssize_t line_width = startwidth;
grub_ssize_t lastspacewidth = 0;
grub_ssize_t max_width = get_maxwidth (term, margin_left, margin_right);
const grub_uint32_t *line_start = str, *last_space = str - 1;
for (ptr = str; ptr < last_position; ptr++)
{
grub_ssize_t last_width = 0;
if (grub_unicode_get_comb_type (*ptr) == GRUB_UNICODE_COMB_NONE)
{
struct grub_unicode_glyph c = {
.variant = 0,
.attributes = 0,
.ncomb = 0,
.combining = 0
};
c.base = *ptr;
line_width += last_width = grub_term_getcharwidth (term, &c);
}
if (*ptr == ' ')
{
lastspacewidth = line_width;
last_space = ptr;
}
if (line_width > max_width || *ptr == '\n')
{
const grub_uint32_t *ptr2;
if (line_width > max_width && last_space > line_start)
ptr = last_space;
else if (line_width > max_width
&& line_start == str && startwidth != 0)
{
ptr = str;
lastspacewidth = startwidth;
}
else
lastspacewidth = line_width - last_width;
for (ptr2 = line_start; ptr2 < ptr; ptr2++)
{
/* Skip combining characters on non-UTF8 terminals. */
if ((term->flags & GRUB_TERM_CODE_TYPE_MASK)
!= GRUB_TERM_CODE_TYPE_UTF8_LOGICAL
&& grub_unicode_get_comb_type (*ptr2)
!= GRUB_UNICODE_COMB_NONE)
continue;
putcode_real (*ptr2, term);
}
grub_print_spaces (term, margin_right);
grub_putcode ('\n', term);
if (state && ++state->num_lines
>= (grub_ssize_t) grub_term_height (term) - 2)
{
state->backlog_ucs4 = (ptr == last_space || *ptr == '\n')
? ptr + 1 : ptr;
state->backlog_len = last_position - state->backlog_ucs4;
return 1;
}
line_width -= lastspacewidth;
grub_print_spaces (term, margin_left);
if (ptr == last_space || *ptr == '\n')
ptr++;
line_start = ptr;
}
}
{
const grub_uint32_t *ptr2;
for (ptr2 = line_start; ptr2 < last_position; ptr2++)
{
/* Skip combining characters on non-UTF8 terminals. */
if ((term->flags & GRUB_TERM_CODE_TYPE_MASK)
!= GRUB_TERM_CODE_TYPE_UTF8_LOGICAL
&& grub_unicode_get_comb_type (*ptr2)
!= GRUB_UNICODE_COMB_NONE)
continue;
putcode_real (*ptr2, term);
}
}
return 0;
}
static struct term_state *
find_term_state (struct grub_term_output *term)
{
struct term_state *state;
for (state = term_states; state; state = state->next)
if (grub_strcmp (state->term_name, term->name) == 0)
return state;
state = grub_zalloc (sizeof (*state));
if (!state)
{
grub_errno = GRUB_ERR_NONE;
return NULL;
}
state->term_name = grub_strdup (term->name);
state->next = term_states;
term_states = state;
return state;
}
static int
put_glyphs_terminal (const struct grub_unicode_glyph *visual,
grub_ssize_t visual_len,
int margin_left, int margin_right,
struct grub_term_output *term,
struct term_state *state)
{
const struct grub_unicode_glyph *visual_ptr;
for (visual_ptr = visual; visual_ptr < visual + visual_len; visual_ptr++)
{
if (visual_ptr->base == '\n')
grub_print_spaces (term, margin_right);
putglyph (visual_ptr, term);
if (state && ++state->num_lines
>= (grub_ssize_t) grub_term_height (term) - 2)
{
state->backlog_glyphs = visual_ptr + 1;
state->backlog_len = visual_len - (visual - visual_ptr) - 1;
return 1;
}
if (visual_ptr->base == '\n')
grub_print_spaces (term, margin_left);
grub_free (visual_ptr->combining);
}
return 0;
}
static int
print_backlog (struct grub_term_output *term,
int margin_left, int margin_right)
{
struct term_state *state = find_term_state (term);
if (!state)
return 0;
if (state->backlog_ucs4)
{
int ret;
ret = print_ucs4_terminal (state->backlog_ucs4,
state->backlog_ucs4 + state->backlog_len,
margin_left, margin_right, term, state);
if (!ret)
{
grub_free (state->free);
state->free = NULL;
state->backlog_len = 0;
}
return ret;
}
if (state->backlog_glyphs)
{
int ret;
ret = put_glyphs_terminal (state->backlog_glyphs,
state->backlog_len,
margin_left, margin_right, term, state);
if (!ret)
{
grub_free (state->free);
state->free = NULL;
state->backlog_len = 0;
}
return ret;
}
return 0;
}
static int
print_ucs4_real (const grub_uint32_t * str,
const grub_uint32_t * last_position,
int margin_left, int margin_right,
struct grub_term_output *term, int backlog)
{
struct term_state *state = NULL;
if (backlog)
state = find_term_state (term);
if (((term->getxy (term) >> 8) & 0xff) < margin_left)
grub_print_spaces (term, margin_left - ((term->getxy (term) >> 8) & 0xff));
if ((term->flags & GRUB_TERM_CODE_TYPE_MASK)
== GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS
|| (term->flags & GRUB_TERM_CODE_TYPE_MASK)
== GRUB_TERM_CODE_TYPE_UTF8_VISUAL)
{
grub_ssize_t visual_len;
struct grub_unicode_glyph *visual;
int ret;
auto grub_ssize_t getcharwidth (const struct grub_unicode_glyph *c);
grub_ssize_t getcharwidth (const struct grub_unicode_glyph *c)
{
return grub_term_getcharwidth (term, c);
}
visual_len = grub_bidi_logical_to_visual (str, last_position - str,
&visual, getcharwidth,
get_maxwidth (term,
margin_left,
margin_right),
get_startwidth (term,
margin_left));
if (visual_len < 0)
{
grub_print_error ();
return 0;
}
ret = put_glyphs_terminal (visual, visual_len, margin_left, margin_right,
term, state);
if (!ret)
grub_free (visual);
else
state->free = visual;
return ret;
}
return print_ucs4_terminal (str, last_position, margin_left, margin_right,
term, state);
}
void
grub_print_ucs4 (const grub_uint32_t * str,
const grub_uint32_t * last_position,
int margin_left, int margin_right,
struct grub_term_output *term)
{
print_ucs4_real (str, last_position, margin_left, margin_right,
term, 0);
}
void
grub_xputs_normal (const char *str)
{
grub_term_output_t term;
grub_uint32_t *unicode_str, *unicode_last_position;
int backlog = 0;
grub_utf8_to_ucs4_alloc (str, &unicode_str,
&unicode_last_position);
if (!unicode_str)
{
grub_errno = GRUB_ERR_NONE;
return;
}
FOR_ACTIVE_TERM_OUTPUTS(term)
{
int cur;
cur = print_ucs4_real (unicode_str, unicode_last_position, 0, 0,
term, grub_more);
if (cur)
backlog = 1;
}
while (backlog)
{
print_more ();
backlog = 0;
FOR_ACTIVE_TERM_OUTPUTS(term)
{
int cur;
cur = print_backlog (term, 0, 0);
if (cur)
backlog = 1;
}
}
grub_free (unicode_str);
}
void
grub_cls (void)
{
struct grub_term_output *term;
FOR_ACTIVE_TERM_OUTPUTS(term)
{
if ((term->flags & GRUB_TERM_DUMB) || (grub_env_get ("debug")))
{
grub_putcode ('\n', term);
grub_term_refresh (term);
}
else
(term->cls) (term);
}
}

View File

@ -236,7 +236,7 @@ grub_at_keyboard_getkey_noblock (void)
}
static int
grub_at_keyboard_checkkey (void)
grub_at_keyboard_checkkey (struct grub_term_input *term __attribute__ ((unused)))
{
if (pending_key != -1)
return 1;
@ -250,7 +250,7 @@ grub_at_keyboard_checkkey (void)
}
static int
grub_at_keyboard_getkey (void)
grub_at_keyboard_getkey (struct grub_term_input *term __attribute__ ((unused)))
{
int key;
if (pending_key != -1)
@ -267,7 +267,7 @@ grub_at_keyboard_getkey (void)
}
static grub_err_t
grub_keyboard_controller_init (void)
grub_keyboard_controller_init (struct grub_term_input *term __attribute__ ((unused)))
{
pending_key = -1;
at_keyboard_status = 0;
@ -277,7 +277,7 @@ grub_keyboard_controller_init (void)
}
static grub_err_t
grub_keyboard_controller_fini (void)
grub_keyboard_controller_fini (struct grub_term_input *term __attribute__ ((unused)))
{
grub_keyboard_controller_write (grub_keyboard_controller_orig);
return GRUB_ERR_NONE;

View File

@ -24,97 +24,84 @@
#include <grub/efi/api.h>
#include <grub/efi/console.h>
static grub_uint8_t
static const grub_uint8_t
grub_console_standard_color = GRUB_EFI_TEXT_ATTR (GRUB_EFI_YELLOW,
GRUB_EFI_BACKGROUND_BLACK);
static grub_uint8_t
grub_console_normal_color = GRUB_EFI_TEXT_ATTR (GRUB_EFI_LIGHTGRAY,
GRUB_EFI_BACKGROUND_BLACK);
static grub_uint8_t
grub_console_highlight_color = GRUB_EFI_TEXT_ATTR (GRUB_EFI_BLACK,
GRUB_EFI_BACKGROUND_LIGHTGRAY);
static int read_key = -1;
static grub_uint32_t
map_char (grub_uint32_t c)
{
if (c > 0x7f)
/* Map some unicode characters to the EFI character. */
switch (c)
{
/* Map some unicode characters to the EFI character. */
switch (c)
{
case 0x2190: /* left arrow */
c = 0x25c4;
break;
case 0x2191: /* up arrow */
c = 0x25b2;
break;
case 0x2192: /* right arrow */
c = 0x25ba;
break;
case 0x2193: /* down arrow */
c = 0x25bc;
break;
case 0x2501: /* horizontal line */
c = 0x2500;
break;
case 0x2503: /* vertical line */
c = 0x2502;
break;
case 0x250F: /* upper-left corner */
c = 0x250c;
break;
case 0x2513: /* upper-right corner */
c = 0x2510;
break;
case 0x2517: /* lower-left corner */
c = 0x2514;
break;
case 0x251B: /* lower-right corner */
c = 0x2518;
break;
default:
c = '?';
break;
}
case GRUB_UNICODE_LEFTARROW:
c = GRUB_UNICODE_BLACK_LEFT_TRIANGLE;
break;
case GRUB_UNICODE_UPARROW:
c = GRUB_UNICODE_BLACK_UP_TRIANGLE;
break;
case GRUB_UNICODE_RIGHTARROW:
c = GRUB_UNICODE_BLACK_RIGHT_TRIANGLE;
break;
case GRUB_UNICODE_DOWNARROW:
c = GRUB_UNICODE_BLACK_DOWN_TRIANGLE;
break;
case GRUB_UNICODE_HLINE:
c = GRUB_UNICODE_LIGHT_HLINE;
break;
case GRUB_UNICODE_VLINE:
c = GRUB_UNICODE_LIGHT_VLINE;
break;
case GRUB_UNICODE_CORNER_UL:
c = GRUB_UNICODE_LIGHT_CORNER_UL;
break;
case GRUB_UNICODE_CORNER_UR:
c = GRUB_UNICODE_LIGHT_CORNER_UR;
break;
case GRUB_UNICODE_CORNER_LL:
c = GRUB_UNICODE_LIGHT_CORNER_LL;
break;
case GRUB_UNICODE_CORNER_LR:
c = GRUB_UNICODE_LIGHT_CORNER_LR;
break;
}
return c;
}
static void
grub_console_putchar (grub_uint32_t c)
grub_console_putchar (struct grub_term_output *term __attribute__ ((unused)),
const struct grub_unicode_glyph *c)
{
grub_efi_char16_t str[2];
grub_efi_char16_t str[2 + c->ncomb];
grub_efi_simple_text_output_interface_t *o;
unsigned i, j;
o = grub_efi_system_table->con_out;
/* For now, do not try to use a surrogate pair. */
if (c > 0xffff)
c = '?';
str[0] = (grub_efi_char16_t) map_char (c & 0xffff);
str[1] = 0;
if (c->base > 0xffff)
str[0] = '?';
else
str[0] = (grub_efi_char16_t) map_char (c->base & 0xffff);
j = 1;
for (i = 0; i < c->ncomb; i++)
if (c->base < 0xffff)
str[j++] = c->combining[i].code;
str[j] = 0;
/* Should this test be cached? */
if (c > 0x7f && efi_call_2 (o->test_string, o, str) != GRUB_EFI_SUCCESS)
if ((c->base > 0x7f || c->ncomb)
&& efi_call_2 (o->test_string, o, str) != GRUB_EFI_SUCCESS)
return;
efi_call_2 (o->output_string, o, str);
}
static grub_ssize_t
grub_console_getcharwidth (grub_uint32_t c __attribute__ ((unused)))
{
/* For now, every printable character has the width 1. */
return 1;
}
static int
grub_console_checkkey (void)
grub_console_checkkey (struct grub_term_input *term __attribute__ ((unused)))
{
grub_efi_simple_input_interface_t *i;
grub_efi_input_key_t key;
@ -209,7 +196,7 @@ grub_console_checkkey (void)
}
static int
grub_console_getkey (void)
grub_console_getkey (struct grub_term_input *term)
{
grub_efi_simple_input_interface_t *i;
grub_efi_boot_services_t *b;
@ -233,7 +220,7 @@ grub_console_getkey (void)
if (status != GRUB_EFI_SUCCESS)
return -1;
grub_console_checkkey ();
grub_console_checkkey (term);
}
while (read_key < 0);
@ -243,7 +230,7 @@ grub_console_getkey (void)
}
static grub_uint16_t
grub_console_getwh (void)
grub_console_getwh (struct grub_term_output *term __attribute__ ((unused)))
{
grub_efi_simple_text_output_interface_t *o;
grub_efi_uintn_t columns, rows;
@ -260,7 +247,7 @@ grub_console_getwh (void)
}
static grub_uint16_t
grub_console_getxy (void)
grub_console_getxy (struct grub_term_output *term __attribute__ ((unused)))
{
grub_efi_simple_text_output_interface_t *o;
@ -269,7 +256,8 @@ grub_console_getxy (void)
}
static void
grub_console_gotoxy (grub_uint8_t x, grub_uint8_t y)
grub_console_gotoxy (struct grub_term_output *term __attribute__ ((unused)),
grub_uint8_t x, grub_uint8_t y)
{
grub_efi_simple_text_output_interface_t *o;
@ -278,7 +266,7 @@ grub_console_gotoxy (grub_uint8_t x, grub_uint8_t y)
}
static void
grub_console_cls (void)
grub_console_cls (struct grub_term_output *term __attribute__ ((unused)))
{
grub_efi_simple_text_output_interface_t *o;
grub_efi_int32_t orig_attr;
@ -291,7 +279,8 @@ grub_console_cls (void)
}
static void
grub_console_setcolorstate (grub_term_color_state state)
grub_console_setcolorstate (struct grub_term_output *term,
grub_term_color_state state)
{
grub_efi_simple_text_output_interface_t *o;
@ -302,10 +291,10 @@ grub_console_setcolorstate (grub_term_color_state state)
efi_call_2 (o->set_attributes, o, grub_console_standard_color);
break;
case GRUB_TERM_COLOR_NORMAL:
efi_call_2 (o->set_attributes, o, grub_console_normal_color);
efi_call_2 (o->set_attributes, o, term->normal_color);
break;
case GRUB_TERM_COLOR_HIGHLIGHT:
efi_call_2 (o->set_attributes, o, grub_console_highlight_color);
efi_call_2 (o->set_attributes, o, term->highlight_color);
break;
default:
break;
@ -313,21 +302,8 @@ grub_console_setcolorstate (grub_term_color_state state)
}
static void
grub_console_setcolor (grub_uint8_t normal_color, grub_uint8_t highlight_color)
{
grub_console_normal_color = normal_color;
grub_console_highlight_color = highlight_color;
}
static void
grub_console_getcolor (grub_uint8_t *normal_color, grub_uint8_t *highlight_color)
{
*normal_color = grub_console_normal_color;
*highlight_color = grub_console_highlight_color;
}
static void
grub_console_setcursor (int on)
grub_console_setcursor (struct grub_term_output *term __attribute__ ((unused)),
int on)
{
grub_efi_simple_text_output_interface_t *o;
@ -346,15 +322,17 @@ static struct grub_term_output grub_console_term_output =
{
.name = "console",
.putchar = grub_console_putchar,
.getcharwidth = grub_console_getcharwidth,
.getwh = grub_console_getwh,
.getxy = grub_console_getxy,
.gotoxy = grub_console_gotoxy,
.cls = grub_console_cls,
.setcolorstate = grub_console_setcolorstate,
.setcolor = grub_console_setcolor,
.getcolor = grub_console_getcolor,
.setcursor = grub_console_setcursor
.setcursor = grub_console_setcursor,
.normal_color = GRUB_EFI_TEXT_ATTR (GRUB_EFI_LIGHTGRAY,
GRUB_EFI_BACKGROUND_BLACK),
.highlight_color = GRUB_EFI_TEXT_ATTR (GRUB_EFI_BLACK,
GRUB_EFI_BACKGROUND_LIGHTGRAY),
.flags = GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS
};
void

View File

@ -35,8 +35,6 @@
#define DEFAULT_BORDER_WIDTH 10
#define DEFAULT_STANDARD_COLOR 0x07
#define DEFAULT_NORMAL_COLOR 0x07
#define DEFAULT_HIGHLIGHT_COLOR 0x70
struct grub_dirty_region
{
@ -49,7 +47,7 @@ struct grub_dirty_region
struct grub_colored_char
{
/* An Unicode codepoint. */
grub_uint32_t code;
struct grub_unicode_glyph *code;
/* Color values. */
grub_video_color_t fg_color;
@ -92,8 +90,6 @@ struct grub_virtual_screen
/* Terminal color settings. */
grub_uint8_t standard_color_setting;
grub_uint8_t normal_color_setting;
grub_uint8_t highlight_color_setting;
grub_uint8_t term_color;
/* Color settings. */
@ -146,7 +142,11 @@ static unsigned int calculate_normal_character_width (grub_font_t font);
static unsigned char calculate_character_width (struct grub_font_glyph *glyph);
static void grub_gfxterm_refresh (void);
static void grub_gfxterm_refresh (struct grub_term_output *term __attribute__ ((unused)));
static grub_ssize_t
grub_gfxterm_getcharwidth (struct grub_term_output *term __attribute__ ((unused)),
const struct grub_unicode_glyph *c);
static void
set_term_color (grub_uint8_t term_color)
@ -177,7 +177,10 @@ set_term_color (grub_uint8_t term_color)
static void
clear_char (struct grub_colored_char *c)
{
c->code = ' ';
grub_free (c->code);
c->code = grub_unicode_glyph_from_code (' ');
if (!c->code)
grub_errno = GRUB_ERR_NONE;
c->fg_color = virtual_screen.fg_color;
c->bg_color = virtual_screen.bg_color;
c->width = 0;
@ -253,10 +256,8 @@ grub_virtual_screen_setup (unsigned int x, unsigned int y,
grub_video_set_active_render_target (text_layer);
virtual_screen.standard_color_setting = DEFAULT_STANDARD_COLOR;
virtual_screen.normal_color_setting = DEFAULT_NORMAL_COLOR;
virtual_screen.highlight_color_setting = DEFAULT_HIGHLIGHT_COLOR;
virtual_screen.term_color = virtual_screen.normal_color_setting;
virtual_screen.term_color = GRUB_TERM_DEFAULT_NORMAL_COLOR;
set_term_color (virtual_screen.term_color);
@ -266,7 +267,10 @@ grub_virtual_screen_setup (unsigned int x, unsigned int y,
/* Clear out text buffer. */
for (i = 0; i < virtual_screen.columns * virtual_screen.rows; i++)
clear_char (&(virtual_screen.text_buffer[i]));
{
virtual_screen.text_buffer[i].code = 0;
clear_char (&(virtual_screen.text_buffer[i]));
}
return grub_errno;
}
@ -355,7 +359,7 @@ grub_gfxterm_fullscreen (void)
}
static grub_err_t
grub_gfxterm_term_init (void)
grub_gfxterm_term_init (struct grub_term_output *term __attribute__ ((unused)))
{
char *tmp;
grub_err_t err;
@ -399,7 +403,7 @@ destroy_window (void)
}
static grub_err_t
grub_gfxterm_term_fini (void)
grub_gfxterm_term_fini (struct grub_term_output *term __attribute__ ((unused)))
{
destroy_window ();
grub_video_restore ();
@ -611,7 +615,12 @@ paint_char (unsigned cx, unsigned cy)
p -= p->index;
/* Get glyph for character. */
glyph = grub_font_get_glyph (virtual_screen.font, p->code);
glyph = grub_font_construct_glyph (virtual_screen.font, p->code);
if (!glyph)
{
grub_errno = GRUB_ERR_NONE;
return;
}
ascent = grub_font_get_ascent (virtual_screen.font);
width = virtual_screen.normal_char_width * calculate_character_width(glyph);
@ -632,6 +641,7 @@ paint_char (unsigned cx, unsigned cy)
/* Mark character to be drawn. */
dirty_region_add (virtual_screen.offset_x + x, virtual_screen.offset_y + y,
width, height);
grub_free (glyph);
}
static inline void
@ -782,6 +792,15 @@ scroll_up (void)
{
unsigned int i;
/* Clear first line in text buffer. */
for (i = 0;
i < virtual_screen.columns;
i++)
{
virtual_screen.text_buffer[i].code = 0;
clear_char (&(virtual_screen.text_buffer[i]));
}
/* Scroll text buffer with one line to up. */
grub_memmove (virtual_screen.text_buffer,
virtual_screen.text_buffer + virtual_screen.columns,
@ -793,15 +812,19 @@ scroll_up (void)
for (i = virtual_screen.columns * (virtual_screen.rows - 1);
i < virtual_screen.columns * virtual_screen.rows;
i++)
clear_char (&(virtual_screen.text_buffer[i]));
{
virtual_screen.text_buffer[i].code = 0;
clear_char (&(virtual_screen.text_buffer[i]));
}
virtual_screen.total_scroll++;
}
static void
grub_gfxterm_putchar (grub_uint32_t c)
grub_gfxterm_putchar (struct grub_term_output *term,
const struct grub_unicode_glyph *c)
{
if (c == '\a')
if (c->base == '\a')
/* FIXME */
return;
@ -809,9 +832,9 @@ grub_gfxterm_putchar (grub_uint32_t c)
if (virtual_screen.cursor_state)
draw_cursor (0);
if (c == '\b' || c == '\n' || c == '\r')
if (c->base == '\b' || c->base == '\n' || c->base == '\r')
{
switch (c)
switch (c->base)
{
case '\b':
if (virtual_screen.cursor_x > 0)
@ -832,26 +855,30 @@ grub_gfxterm_putchar (grub_uint32_t c)
}
else
{
struct grub_font_glyph *glyph;
struct grub_colored_char *p;
unsigned char char_width;
/* Get properties of the character. */
glyph = grub_font_get_glyph (virtual_screen.font, c);
/* Calculate actual character width for glyph. This is number of
times of normal_font_width. */
char_width = calculate_character_width(glyph);
char_width = grub_gfxterm_getcharwidth (term, c);
/* If we are about to exceed line length, wrap to next line. */
if (virtual_screen.cursor_x + char_width > virtual_screen.columns)
grub_putchar ('\n');
{
if (virtual_screen.cursor_y >= virtual_screen.rows - 1)
scroll_up ();
else
virtual_screen.cursor_y++;
}
/* Find position on virtual screen, and fill information. */
p = (virtual_screen.text_buffer +
virtual_screen.cursor_x +
virtual_screen.cursor_y * virtual_screen.columns);
p->code = c;
grub_free (p->code);
p->code = grub_unicode_glyph_dup (c);
if (!p->code)
grub_errno = GRUB_ERR_NONE;
p->fg_color = virtual_screen.fg_color;
p->bg_color = virtual_screen.bg_color;
p->width = char_width - 1;
@ -864,7 +891,10 @@ grub_gfxterm_putchar (grub_uint32_t c)
for (i = 1; i < char_width; i++)
{
p[i].code = ' ';
grub_free (p[i].code);
p[i].code = grub_unicode_glyph_from_code (' ');
if (!p[i].code)
grub_errno = GRUB_ERR_NONE;
p[i].width = char_width - 1;
p[i].index = i;
}
@ -929,34 +959,34 @@ calculate_character_width (struct grub_font_glyph *glyph)
}
static grub_ssize_t
grub_gfxterm_getcharwidth (grub_uint32_t c)
grub_gfxterm_getcharwidth (struct grub_term_output *term __attribute__ ((unused)),
const struct grub_unicode_glyph *c)
{
struct grub_font_glyph *glyph;
unsigned char char_width;
int dev_width;
dev_width = grub_font_get_constructed_device_width (virtual_screen.font, c);
/* Get properties of the character. */
glyph = grub_font_get_glyph (virtual_screen.font, c);
if (dev_width == 0)
return 1;
/* Calculate actual character width for glyph. */
char_width = calculate_character_width (glyph);
return char_width;
return (dev_width + (virtual_screen.normal_char_width - 1))
/ virtual_screen.normal_char_width;
}
static grub_uint16_t
grub_virtual_screen_getwh (void)
grub_virtual_screen_getwh (struct grub_term_output *term __attribute__ ((unused)))
{
return (virtual_screen.columns << 8) | virtual_screen.rows;
}
static grub_uint16_t
grub_virtual_screen_getxy (void)
grub_virtual_screen_getxy (struct grub_term_output *term __attribute__ ((unused)))
{
return ((virtual_screen.cursor_x << 8) | virtual_screen.cursor_y);
}
static void
grub_gfxterm_gotoxy (grub_uint8_t x, grub_uint8_t y)
grub_gfxterm_gotoxy (struct grub_term_output *term __attribute__ ((unused)),
grub_uint8_t x, grub_uint8_t y)
{
if (x >= virtual_screen.columns)
x = virtual_screen.columns - 1;
@ -977,7 +1007,7 @@ grub_gfxterm_gotoxy (grub_uint8_t x, grub_uint8_t y)
}
static void
grub_virtual_screen_cls (void)
grub_virtual_screen_cls (struct grub_term_output *term __attribute__ ((unused)))
{
grub_uint32_t i;
@ -988,12 +1018,12 @@ grub_virtual_screen_cls (void)
}
static void
grub_gfxterm_cls (void)
grub_gfxterm_cls (struct grub_term_output *term)
{
grub_video_color_t color;
/* Clear virtual screen. */
grub_virtual_screen_cls ();
grub_virtual_screen_cls (term);
/* Clear text layer. */
grub_video_set_active_render_target (text_layer);
@ -1005,11 +1035,12 @@ grub_gfxterm_cls (void)
/* Mark virtual screen to be redrawn. */
dirty_region_add_virtualscreen ();
grub_gfxterm_refresh ();
grub_gfxterm_refresh (term);
}
static void
grub_virtual_screen_setcolorstate (grub_term_color_state state)
grub_virtual_screen_setcolorstate (struct grub_term_output *term,
grub_term_color_state state)
{
switch (state)
{
@ -1018,11 +1049,11 @@ grub_virtual_screen_setcolorstate (grub_term_color_state state)
break;
case GRUB_TERM_COLOR_NORMAL:
virtual_screen.term_color = virtual_screen.normal_color_setting;
virtual_screen.term_color = term->normal_color;
break;
case GRUB_TERM_COLOR_HIGHLIGHT:
virtual_screen.term_color = virtual_screen.highlight_color_setting;
virtual_screen.term_color = term->highlight_color;
break;
default:
@ -1034,23 +1065,8 @@ grub_virtual_screen_setcolorstate (grub_term_color_state state)
}
static void
grub_virtual_screen_setcolor (grub_uint8_t normal_color,
grub_uint8_t highlight_color)
{
virtual_screen.normal_color_setting = normal_color;
virtual_screen.highlight_color_setting = highlight_color;
}
static void
grub_virtual_screen_getcolor (grub_uint8_t *normal_color,
grub_uint8_t *highlight_color)
{
*normal_color = virtual_screen.normal_color_setting;
*highlight_color = virtual_screen.highlight_color_setting;
}
static void
grub_gfxterm_setcursor (int on)
grub_gfxterm_setcursor (struct grub_term_output *term __attribute__ ((unused)),
int on)
{
if (virtual_screen.cursor_state != on)
{
@ -1064,7 +1080,7 @@ grub_gfxterm_setcursor (int on)
}
static void
grub_gfxterm_refresh (void)
grub_gfxterm_refresh (struct grub_term_output *term __attribute__ ((unused)))
{
real_scroll ();
@ -1175,11 +1191,11 @@ static struct grub_term_output grub_video_term =
.gotoxy = grub_gfxterm_gotoxy,
.cls = grub_gfxterm_cls,
.setcolorstate = grub_virtual_screen_setcolorstate,
.setcolor = grub_virtual_screen_setcolor,
.getcolor = grub_virtual_screen_getcolor,
.setcursor = grub_gfxterm_setcursor,
.refresh = grub_gfxterm_refresh,
.flags = 0,
.flags = GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS,
.normal_color = GRUB_TERM_DEFAULT_NORMAL_COLOR,
.highlight_color = GRUB_TERM_DEFAULT_HIGHLIGHT_COLOR,
.next = 0
};

View File

@ -30,7 +30,7 @@ static const struct grub_machine_bios_data_area *bios_data_area =
#define KEYBOARD_ALT (1 << 3)
static int
grub_console_getkeystatus (void)
grub_console_getkeystatus (struct grub_term_input *term __attribute__ ((unused)))
{
grub_uint8_t status = bios_data_area->keyboard_flag_lower;
int mods = 0;
@ -57,15 +57,15 @@ static struct grub_term_output grub_console_term_output =
{
.name = "console",
.putchar = grub_console_putchar,
.getcharwidth = grub_console_getcharwidth,
.getwh = grub_console_getwh,
.getxy = grub_console_getxy,
.gotoxy = grub_console_gotoxy,
.cls = grub_console_cls,
.setcolorstate = grub_console_setcolorstate,
.setcolor = grub_console_setcolor,
.getcolor = grub_console_getcolor,
.setcursor = grub_console_setcursor
.setcursor = grub_console_setcursor,
.flags = GRUB_TERM_CODE_TYPE_CP437,
.normal_color = GRUB_TERM_DEFAULT_NORMAL_COLOR,
.highlight_color = GRUB_TERM_DEFAULT_HIGHLIGHT_COLOR,
};
void

View File

@ -75,10 +75,11 @@ inc_x (void)
grub_curr_x++;
}
void
grub_console_real_putchar (int c)
static void
grub_vga_text_putchar (struct grub_term_output *term __attribute__ ((unused)),
const struct grub_unicode_glyph *c)
{
switch (c)
switch (c->base)
{
case '\b':
if (grub_curr_x != 0)
@ -91,8 +92,8 @@ grub_console_real_putchar (int c)
grub_curr_x = 0;
break;
default:
screen_write_char (grub_curr_x,
grub_curr_y, c | (grub_console_cur_color << 8));
screen_write_char (grub_curr_x, grub_curr_y,
c->base | (grub_console_cur_color << 8));
inc_x ();
}
@ -100,13 +101,14 @@ grub_console_real_putchar (int c)
}
static grub_uint16_t
grub_vga_text_getxy (void)
grub_vga_text_getxy (struct grub_term_output *term __attribute__ ((unused)))
{
return (grub_curr_x << 8) | grub_curr_y;
}
static void
grub_vga_text_gotoxy (grub_uint8_t x, grub_uint8_t y)
grub_vga_text_gotoxy (struct grub_term_output *term __attribute__ ((unused)),
grub_uint8_t x, grub_uint8_t y)
{
grub_curr_x = x;
grub_curr_y = y;
@ -114,16 +116,17 @@ grub_vga_text_gotoxy (grub_uint8_t x, grub_uint8_t y)
}
static void
grub_vga_text_cls (void)
grub_vga_text_cls (struct grub_term_output *term)
{
int i;
for (i = 0; i < ROWS * COLS; i++)
((short *) VGA_TEXT_SCREEN)[i] = ' ' | (grub_console_cur_color << 8);
grub_vga_text_gotoxy (0, 0);
grub_vga_text_gotoxy (term, 0, 0);
}
static void
grub_vga_text_setcursor (int on)
grub_vga_text_setcursor (struct grub_term_output *term __attribute__ ((unused)),
int on)
{
grub_uint8_t old;
old = grub_vga_cr_read (GRUB_VGA_CR_CURSOR_START);
@ -136,9 +139,9 @@ grub_vga_text_setcursor (int on)
}
static grub_err_t
grub_vga_text_init_fini (void)
grub_vga_text_init_fini (struct grub_term_output *term)
{
grub_vga_text_cls ();
grub_vga_text_cls (term);
return 0;
}
@ -147,16 +150,16 @@ static struct grub_term_output grub_vga_text_term =
.name = "vga_text",
.init = grub_vga_text_init_fini,
.fini = grub_vga_text_init_fini,
.putchar = grub_console_putchar,
.getcharwidth = grub_console_getcharwidth,
.putchar = grub_vga_text_putchar,
.getwh = grub_console_getwh,
.getxy = grub_vga_text_getxy,
.gotoxy = grub_vga_text_gotoxy,
.cls = grub_vga_text_cls,
.setcolorstate = grub_console_setcolorstate,
.setcolor = grub_console_setcolor,
.getcolor = grub_console_getcolor,
.setcursor = grub_vga_text_setcursor,
.flags = GRUB_TERM_CODE_TYPE_CP437,
.normal_color = GRUB_TERM_DEFAULT_NORMAL_COLOR,
.highlight_color = GRUB_TERM_DEFAULT_HIGHLIGHT_COLOR,
};
GRUB_MOD_INIT(vga_text)

View File

@ -21,105 +21,28 @@
#include <grub/types.h>
grub_uint8_t grub_console_cur_color = 0x7;
static grub_uint8_t grub_console_standard_color = 0x7;
static grub_uint8_t grub_console_normal_color = 0x7;
static grub_uint8_t grub_console_highlight_color = 0x70;
static grub_uint32_t
map_char (grub_uint32_t c)
{
if (c > 0x7f)
{
/* Map some unicode characters to the VGA font, if possible. */
switch (c)
{
case 0x2190: /* left arrow */
c = 0x1b;
break;
case 0x2191: /* up arrow */
c = 0x18;
break;
case 0x2192: /* right arrow */
c = 0x1a;
break;
case 0x2193: /* down arrow */
c = 0x19;
break;
case 0x2501: /* horizontal line */
c = 0xc4;
break;
case 0x2503: /* vertical line */
c = 0xb3;
break;
case 0x250F: /* upper-left corner */
c = 0xda;
break;
case 0x2513: /* upper-right corner */
c = 0xbf;
break;
case 0x2517: /* lower-left corner */
c = 0xc0;
break;
case 0x251B: /* lower-right corner */
c = 0xd9;
break;
default:
c = '?';
break;
}
}
return c;
}
void
grub_console_putchar (grub_uint32_t c)
{
grub_console_real_putchar (map_char (c));
}
grub_ssize_t
grub_console_getcharwidth (grub_uint32_t c __attribute__ ((unused)))
{
/* For now, every printable character has the width 1. */
return 1;
}
grub_uint16_t
grub_console_getwh (void)
grub_console_getwh (struct grub_term_output *term __attribute__ ((unused)))
{
return (80 << 8) | 25;
}
void
grub_console_setcolorstate (grub_term_color_state state)
grub_console_setcolorstate (struct grub_term_output *term,
grub_term_color_state state)
{
switch (state) {
case GRUB_TERM_COLOR_STANDARD:
grub_console_cur_color = grub_console_standard_color;
grub_console_cur_color = GRUB_TERM_DEFAULT_STANDARD_COLOR;
break;
case GRUB_TERM_COLOR_NORMAL:
grub_console_cur_color = grub_console_normal_color;
grub_console_cur_color = term->normal_color;
break;
case GRUB_TERM_COLOR_HIGHLIGHT:
grub_console_cur_color = grub_console_highlight_color;
grub_console_cur_color = term->highlight_color;
break;
default:
break;
}
}
void
grub_console_setcolor (grub_uint8_t normal_color, grub_uint8_t highlight_color)
{
grub_console_normal_color = normal_color;
grub_console_highlight_color = highlight_color;
}
void
grub_console_getcolor (grub_uint8_t *normal_color, grub_uint8_t *highlight_color)
{
*normal_color = grub_console_normal_color;
*highlight_color = grub_console_highlight_color;
}

View File

@ -22,7 +22,8 @@
#include <grub/misc.h>
#include <grub/mm.h>
#include <grub/time.h>
#include <grub/machine/console.h>
#include <grub/terminfo.h>
#include <grub/ieee1275/console.h>
#include <grub/ieee1275/ieee1275.h>
static grub_ieee1275_ihandle_t stdout_ihandle;
@ -31,12 +32,6 @@ static grub_ieee1275_ihandle_t stdin_ihandle;
static grub_uint8_t grub_ofconsole_width;
static grub_uint8_t grub_ofconsole_height;
static int grub_curr_x;
static int grub_curr_y;
static int grub_keybuf;
static int grub_buflen;
struct color
{
int red;
@ -44,292 +39,41 @@ struct color
int blue;
};
/* Use serial colors as they are default on most firmwares and some firmwares
ignore set-color!. Additionally output may be redirected to serial. */
static struct color colors[] =
{
// {R, G, B}
{0x00, 0x00, 0x00},
{0x00, 0x00, 0xA8}, // 1 = blue
{0x00, 0x00, 0x00}, // 0 = black
{0xA8, 0x00, 0x00}, // 1 = red
{0x00, 0xA8, 0x00}, // 2 = green
{0x00, 0xA8, 0xA8}, // 3 = cyan
{0xA8, 0x00, 0x00}, // 4 = red
{0xFE, 0xFE, 0x54}, // 3 = yellow
{0x00, 0x00, 0xA8}, // 4 = blue
{0xA8, 0x00, 0xA8}, // 5 = magenta
{0xFE, 0xFE, 0x54}, // 6 = yellow
{0x00, 0xA8, 0xA8}, // 6 = cyan
{0xFE, 0xFE, 0xFE} // 7 = white
};
static grub_uint8_t grub_ofconsole_normal_color = 0x7;
static grub_uint8_t grub_ofconsole_highlight_color = 0x70;
/* Write control characters to the console. */
static void
grub_ofconsole_writeesc (const char *str)
put (const int c)
{
if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_ANSI))
return;
char chr = c;
while (*str)
{
char chr = *(str++);
grub_ieee1275_write (stdout_ihandle, &chr, 1, 0);
}
}
static void
grub_ofconsole_putchar (grub_uint32_t c)
{
char chr;
if (c > 0x7F)
{
/* Better than nothing. */
switch (c)
{
case GRUB_TERM_DISP_LEFT:
c = '<';
break;
case GRUB_TERM_DISP_UP:
c = '^';
break;
case GRUB_TERM_DISP_RIGHT:
c = '>';
break;
case GRUB_TERM_DISP_DOWN:
c = 'v';
break;
case GRUB_TERM_DISP_HLINE:
c = '-';
break;
case GRUB_TERM_DISP_VLINE:
c = '|';
break;
case GRUB_TERM_DISP_UL:
case GRUB_TERM_DISP_UR:
case GRUB_TERM_DISP_LL:
case GRUB_TERM_DISP_LR:
c = '+';
break;
default:
c = '?';
break;
}
}
chr = c;
if (c == '\n')
{
grub_curr_y++;
grub_curr_x = 0;
}
else if (c == '\r')
{
grub_curr_x = 0;
}
else
{
grub_curr_x++;
if (grub_curr_x >= grub_ofconsole_width)
{
grub_ofconsole_putchar ('\n');
grub_ofconsole_putchar ('\r');
grub_curr_x++;
}
}
grub_ieee1275_write (stdout_ihandle, &chr, 1, 0);
}
static grub_ssize_t
grub_ofconsole_getcharwidth (grub_uint32_t c __attribute__((unused)))
{
return 1;
}
static void
grub_ofconsole_setcolorstate (grub_term_color_state state)
{
char setcol[256];
int fg;
int bg;
switch (state)
{
case GRUB_TERM_COLOR_STANDARD:
case GRUB_TERM_COLOR_NORMAL:
fg = grub_ofconsole_normal_color & 0x0f;
bg = grub_ofconsole_normal_color >> 4;
break;
case GRUB_TERM_COLOR_HIGHLIGHT:
fg = grub_ofconsole_highlight_color & 0x0f;
bg = grub_ofconsole_highlight_color >> 4;
break;
default:
return;
}
grub_snprintf (setcol, sizeof (setcol), "\e[3%dm\e[4%dm", fg, bg);
grub_ofconsole_writeesc (setcol);
}
static void
grub_ofconsole_setcolor (grub_uint8_t normal_color,
grub_uint8_t highlight_color)
{
/* Discard bright bit. */
grub_ofconsole_normal_color = normal_color & 0x77;
grub_ofconsole_highlight_color = highlight_color & 0x77;
}
static void
grub_ofconsole_getcolor (grub_uint8_t *normal_color, grub_uint8_t *highlight_color)
{
*normal_color = grub_ofconsole_normal_color;
*highlight_color = grub_ofconsole_highlight_color;
}
#define ANSI_C0 0x9b
static int
grub_ofconsole_readkey (int *key)
readkey (void)
{
grub_uint8_t c;
grub_ssize_t actual = 0;
grub_ieee1275_read (stdin_ihandle, &c, 1, &actual);
if (actual > 0)
switch(c)
{
case 0x7f:
/* Backspace: Ctrl-h. */
c = '\b';
break;
case ANSI_C0:
case '\e':
{
grub_uint64_t start;
if (c == '\e')
{
grub_ieee1275_read (stdin_ihandle, &c, 1, &actual);
/* On 9600 we have to wait up to 12 milliseconds. */
start = grub_get_time_ms ();
while (actual <= 0 && grub_get_time_ms () - start < 12)
grub_ieee1275_read (stdin_ihandle, &c, 1, &actual);
if (actual <= 0)
{
*key = '\e';
return 1;
}
if (c != '[')
return 0;
}
grub_ieee1275_read (stdin_ihandle, &c, 1, &actual);
/* On 9600 we have to wait up to 12 milliseconds. */
start = grub_get_time_ms ();
while (actual <= 0 && grub_get_time_ms () - start < 12)
grub_ieee1275_read (stdin_ihandle, &c, 1, &actual);
if (actual <= 0)
return 0;
switch (c)
{
case 'A':
/* Up: Ctrl-p. */
c = GRUB_TERM_UP;
break;
case 'B':
/* Down: Ctrl-n. */
c = GRUB_TERM_DOWN;
break;
case 'C':
/* Right: Ctrl-f. */
c = GRUB_TERM_RIGHT;
break;
case 'D':
/* Left: Ctrl-b. */
c = GRUB_TERM_LEFT;
break;
case '3':
{
grub_ieee1275_read (stdin_ihandle, &c, 1, &actual);
/* On 9600 we have to wait up to 12 milliseconds. */
start = grub_get_time_ms ();
while (actual <= 0 && grub_get_time_ms () - start < 12)
grub_ieee1275_read (stdin_ihandle, &c, 1, &actual);
if (actual <= 0)
return 0;
/* Delete: Ctrl-d. */
if (c == '~')
c = GRUB_TERM_DC;
else
return 0;
break;
}
break;
}
}
}
*key = c;
return actual > 0;
}
static int
grub_ofconsole_checkkey (void)
{
int key;
int read;
if (grub_buflen)
return 1;
read = grub_ofconsole_readkey (&key);
if (read)
{
grub_keybuf = key;
grub_buflen = 1;
return 1;
}
return c;
return -1;
}
static int
grub_ofconsole_getkey (void)
{
int key;
if (grub_buflen)
{
grub_buflen =0;
return grub_keybuf;
}
while (! grub_ofconsole_readkey (&key));
return key;
}
static grub_uint16_t
grub_ofconsole_getxy (void)
{
return (grub_curr_x << 8) | grub_curr_y;
}
static void
grub_ofconsole_dimensions (void)
{
@ -367,50 +111,14 @@ grub_ofconsole_dimensions (void)
}
static grub_uint16_t
grub_ofconsole_getwh (void)
grub_ofconsole_getwh (struct grub_term_output *term __attribute__ ((unused)))
{
return (grub_ofconsole_width << 8) | grub_ofconsole_height;
}
static void
grub_ofconsole_gotoxy (grub_uint8_t x, grub_uint8_t y)
{
if (! grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_ANSI))
{
char s[256];
grub_curr_x = x;
grub_curr_y = y;
grub_snprintf (s, sizeof (s), "\e[%d;%dH", y + 1, x + 1);
grub_ofconsole_writeesc (s);
}
else
{
if ((y == grub_curr_y) && (x == grub_curr_x - 1))
{
char chr;
chr = '\b';
grub_ieee1275_write (stdout_ihandle, &chr, 1, 0);
}
grub_curr_x = x;
grub_curr_y = y;
}
}
static void
grub_ofconsole_cls (void)
{
/* Clear the screen. Using serial console, screen(1) only recognizes the
* ANSI escape sequence. Using video console, Apple Open Firmware (version
* 3.1.1) only recognizes the literal ^L. So use both. */
grub_ofconsole_writeesc (" \e[2J");
grub_ofconsole_gotoxy (0, 0);
}
static void
grub_ofconsole_setcursor (int on)
grub_ofconsole_setcursor (struct grub_term_output *term __attribute__ ((unused)),
int on)
{
/* Understood by the Open Firmware flavour in OLPC. */
if (on)
@ -419,14 +127,8 @@ grub_ofconsole_setcursor (int on)
grub_ieee1275_interpret ("cursor-off", 0);
}
static void
grub_ofconsole_refresh (void)
{
/* Do nothing, the current console state is ok. */
}
static grub_err_t
grub_ofconsole_init_input (void)
grub_ofconsole_init_input (struct grub_term_input *term)
{
grub_ssize_t actual;
@ -435,11 +137,11 @@ grub_ofconsole_init_input (void)
|| actual != sizeof stdin_ihandle)
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "cannot find stdin");
return 0;
return grub_terminfo_input_init (term);
}
static grub_err_t
grub_ofconsole_init_output (void)
grub_ofconsole_init_output (struct grub_term_output *term)
{
grub_ssize_t actual;
@ -462,8 +164,8 @@ grub_ofconsole_init_output (void)
grub_ieee1275_set_color (stdout_ihandle, col, colors[col].red,
colors[col].green, colors[col].blue);
/* Set the right fg and bg colors. */
grub_ofconsole_setcolorstate (GRUB_TERM_COLOR_NORMAL);
/* Set the right fg and bg colors. */
grub_terminfo_setcolorstate (term, GRUB_TERM_COLOR_NORMAL);
}
grub_ofconsole_dimensions ();
@ -471,51 +173,74 @@ grub_ofconsole_init_output (void)
return 0;
}
static grub_err_t
grub_ofconsole_fini (void)
{
return 0;
}
struct grub_terminfo_input_state grub_ofconsole_terminfo_input =
{
.readkey = readkey
};
struct grub_terminfo_output_state grub_ofconsole_terminfo_output =
{
.put = put
};
static struct grub_term_input grub_ofconsole_term_input =
{
.name = "ofconsole",
.init = grub_ofconsole_init_input,
.fini = grub_ofconsole_fini,
.checkkey = grub_ofconsole_checkkey,
.getkey = grub_ofconsole_getkey,
.checkkey = grub_terminfo_checkkey,
.getkey = grub_terminfo_getkey,
.data = &grub_ofconsole_terminfo_input
};
static struct grub_term_output grub_ofconsole_term_output =
{
.name = "ofconsole",
.init = grub_ofconsole_init_output,
.fini = grub_ofconsole_fini,
.putchar = grub_ofconsole_putchar,
.getcharwidth = grub_ofconsole_getcharwidth,
.getxy = grub_ofconsole_getxy,
.putchar = grub_terminfo_putchar,
.getxy = grub_terminfo_getxy,
.getwh = grub_ofconsole_getwh,
.gotoxy = grub_ofconsole_gotoxy,
.cls = grub_ofconsole_cls,
.setcolorstate = grub_ofconsole_setcolorstate,
.setcolor = grub_ofconsole_setcolor,
.getcolor = grub_ofconsole_getcolor,
.gotoxy = grub_terminfo_gotoxy,
.cls = grub_terminfo_cls,
.setcolorstate = grub_terminfo_setcolorstate,
.setcursor = grub_ofconsole_setcursor,
.refresh = grub_ofconsole_refresh
.flags = GRUB_TERM_CODE_TYPE_ASCII,
.data = &grub_ofconsole_terminfo_output,
.normal_color = GRUB_TERM_DEFAULT_NORMAL_COLOR,
.highlight_color = GRUB_TERM_DEFAULT_HIGHLIGHT_COLOR,
};
void grub_terminfo_fini (void);
void grub_terminfo_init (void);
void
grub_console_init (void)
grub_console_init_early (void)
{
grub_term_register_input ("ofconsole", &grub_ofconsole_term_input);
grub_term_register_output ("ofconsole", &grub_ofconsole_term_output);
}
void
grub_console_init_lately (void)
{
const char *type;
if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_ANSI))
type = "dumb";
else
type = "ieee1275";
grub_terminfo_init ();
grub_terminfo_output_register (&grub_ofconsole_term_output, type);
}
void
grub_console_fini (void)
{
grub_term_unregister_input (&grub_ofconsole_term_input);
grub_term_unregister_output (&grub_ofconsole_term_output);
grub_terminfo_output_unregister (&grub_ofconsole_term_output);
grub_terminfo_fini ();
}

View File

@ -27,19 +27,8 @@
#include <grub/extcmd.h>
#include <grub/i18n.h>
#define TEXT_WIDTH 80
#define TEXT_HEIGHT 24
static unsigned int xpos, ypos;
static unsigned int keep_track = 1;
static unsigned int registered = 0;
/* An input buffer. */
static char input_buf[8];
static unsigned int npending = 0;
static struct grub_term_output grub_serial_term_output;
/* Argument options. */
static const struct grub_arg_option options[] =
{
@ -111,98 +100,6 @@ serial_hw_put (const int c)
grub_outb (c, serial_settings.port + UART_TX);
}
static void
serial_translate_key_sequence (void)
{
unsigned int i;
static struct
{
char key;
char ascii;
}
three_code_table[] =
{
{'A', 16},
{'B', 14},
{'C', 6},
{'D', 2},
{'F', 5},
{'H', 1},
{'4', 4}
};
static struct
{
short key;
char ascii;
}
four_code_table[] =
{
{('1' | ('~' << 8)), 1},
{('3' | ('~' << 8)), 4},
{('5' | ('~' << 8)), 7},
{('6' | ('~' << 8)), 3}
};
if (npending < 3)
return;
/* The buffer must start with "ESC [". */
if (input_buf[0] != '\e' || input_buf[1] != '[')
return;
for (i = 0; i < ARRAY_SIZE (three_code_table); i++)
if (three_code_table[i].key == input_buf[2])
{
input_buf[0] = three_code_table[i].ascii;
npending -= 2;
grub_memmove (input_buf + 1, input_buf + 3, npending - 1);
return;
}
if (npending >= 4)
{
short key = input_buf[3] | (input_buf[4] << 8);
for (i = 0; i < ARRAY_SIZE (four_code_table); i++)
if (four_code_table[i].key == key)
{
input_buf[0] = four_code_table[i].ascii;
npending -= 3;
grub_memmove (input_buf + 1, input_buf + 4, npending - 1);
return;
}
}
}
static int
fill_input_buf (const int nowait)
{
int i;
for (i = 0; i < 10000 && npending < sizeof (input_buf); i++)
{
int c;
c = serial_hw_fetch ();
if (c >= 0)
{
input_buf[npending++] = c;
/* Reset the counter to zero, to wait for the same interval. */
i = 0;
}
if (nowait)
break;
}
/* Translate some key sequences. */
serial_translate_key_sequence ();
return npending;
}
/* Convert speed to divisor. */
static unsigned short
serial_get_divisor (unsigned int speed)
@ -241,34 +138,6 @@ serial_get_divisor (unsigned int speed)
return 0;
}
/* The serial version of checkkey. */
static int
grub_serial_checkkey (void)
{
if (fill_input_buf (1))
return input_buf[0];
else
return -1;
}
/* The serial version of getkey. */
static int
grub_serial_getkey (void)
{
int c;
while (! fill_input_buf (0))
;
c = input_buf[0];
if (c == 0x7f)
c = GRUB_TERM_BACKSPACE;
grub_memmove (input_buf, input_buf + 1, --npending);
return c;
}
/* Initialize a serial device. PORT is the port number for a serial device.
SPEED is a DTE-DTE speed which must be one of these: 2400, 4800, 9600,
19200, 38400, 57600 and 115200. WORD_LEN is the word length to be used
@ -314,191 +183,54 @@ serial_hw_init (void)
#endif
/* Drain the input buffer. */
while (grub_serial_checkkey () != -1)
(void) grub_serial_getkey ();
while (serial_hw_fetch () != -1);
/* FIXME: should check if the serial terminal was found. */
return GRUB_ERR_NONE;
}
/* The serial version of putchar. */
static void
grub_serial_putchar (grub_uint32_t c)
{
/* Keep track of the cursor. */
if (keep_track)
{
/* The serial terminal does not have VGA fonts. */
if (c > 0x7F)
{
/* Better than nothing. */
switch (c)
{
case GRUB_TERM_DISP_LEFT:
c = '<';
break;
case GRUB_TERM_DISP_UP:
c = '^';
break;
case GRUB_TERM_DISP_RIGHT:
c = '>';
break;
case GRUB_TERM_DISP_DOWN:
c = 'v';
break;
case GRUB_TERM_DISP_HLINE:
c = '-';
break;
case GRUB_TERM_DISP_VLINE:
c = '|';
break;
case GRUB_TERM_DISP_UL:
case GRUB_TERM_DISP_UR:
case GRUB_TERM_DISP_LL:
case GRUB_TERM_DISP_LR:
c = '+';
break;
default:
c = '?';
break;
}
}
switch (c)
{
case '\a':
break;
case '\b':
case 127:
if (xpos > 0)
xpos--;
break;
case '\n':
if (ypos < TEXT_HEIGHT - 1)
ypos++;
break;
case '\r':
xpos = 0;
break;
default:
if (xpos >= TEXT_WIDTH)
{
grub_putchar ('\r');
grub_putchar ('\n');
}
xpos++;
break;
}
}
serial_hw_put (c);
}
static grub_ssize_t
grub_serial_getcharwidth (grub_uint32_t c __attribute__ ((unused)))
{
return 1;
}
static grub_uint16_t
grub_serial_getwh (void)
grub_serial_getwh (struct grub_term_output *term __attribute__ ((unused)))
{
const grub_uint8_t TEXT_WIDTH = 80;
const grub_uint8_t TEXT_HEIGHT = 24;
return (TEXT_WIDTH << 8) | TEXT_HEIGHT;
}
static grub_uint16_t
grub_serial_getxy (void)
{
return ((xpos << 8) | ypos);
}
struct grub_terminfo_input_state grub_serial_terminfo_input =
{
.readkey = serial_hw_fetch
};
static void
grub_serial_gotoxy (grub_uint8_t x, grub_uint8_t y)
{
if (x > TEXT_WIDTH || y > TEXT_HEIGHT)
{
grub_error (GRUB_ERR_OUT_OF_RANGE, "invalid point (%u,%u)", x, y);
}
else
{
keep_track = 0;
grub_terminfo_gotoxy (x, y, &grub_serial_term_output);
keep_track = 1;
xpos = x;
ypos = y;
}
}
static void
grub_serial_cls (void)
{
keep_track = 0;
grub_terminfo_cls (&grub_serial_term_output);
keep_track = 1;
xpos = ypos = 0;
}
static void
grub_serial_setcolorstate (const grub_term_color_state state)
{
keep_track = 0;
switch (state)
{
case GRUB_TERM_COLOR_STANDARD:
case GRUB_TERM_COLOR_NORMAL:
grub_terminfo_reverse_video_off (&grub_serial_term_output);
break;
case GRUB_TERM_COLOR_HIGHLIGHT:
grub_terminfo_reverse_video_on (&grub_serial_term_output);
break;
default:
break;
}
keep_track = 1;
}
static void
grub_serial_setcursor (const int on)
{
if (on)
grub_terminfo_cursor_on (&grub_serial_term_output);
else
grub_terminfo_cursor_off (&grub_serial_term_output);
}
struct grub_terminfo_output_state grub_serial_terminfo_output =
{
.put = serial_hw_put
};
static struct grub_term_input grub_serial_term_input =
{
.name = "serial",
.checkkey = grub_serial_checkkey,
.getkey = grub_serial_getkey,
.init = grub_terminfo_input_init,
.checkkey = grub_terminfo_checkkey,
.getkey = grub_terminfo_getkey,
.data = &grub_serial_terminfo_input
};
static struct grub_term_output grub_serial_term_output =
{
.name = "serial",
.putchar = grub_serial_putchar,
.getcharwidth = grub_serial_getcharwidth,
.putchar = grub_terminfo_putchar,
.getwh = grub_serial_getwh,
.getxy = grub_serial_getxy,
.gotoxy = grub_serial_gotoxy,
.cls = grub_serial_cls,
.setcolorstate = grub_serial_setcolorstate,
.setcursor = grub_serial_setcursor,
.flags = 0,
.getxy = grub_terminfo_getxy,
.gotoxy = grub_terminfo_gotoxy,
.cls = grub_terminfo_cls,
.setcolorstate = grub_terminfo_setcolorstate,
.setcursor = grub_terminfo_setcursor,
.flags = GRUB_TERM_CODE_TYPE_ASCII,
.data = &grub_serial_terminfo_output,
.normal_color = GRUB_TERM_DEFAULT_NORMAL_COLOR,
.highlight_color = GRUB_TERM_DEFAULT_HIGHLIGHT_COLOR,
};
@ -593,6 +325,7 @@ grub_cmd_serial (grub_extcmd_t cmd,
{
grub_term_register_input ("serial", &grub_serial_term_input);
grub_term_register_output ("serial", &grub_serial_term_output);
grub_terminfo_output_register (&grub_serial_term_output, "vt100");
registered = 1;
}
}
@ -609,6 +342,7 @@ grub_cmd_serial (grub_extcmd_t cmd,
/* If unable to restore settings, unregister terminal. */
grub_term_unregister_input (&grub_serial_term_input);
grub_term_unregister_output (&grub_serial_term_output);
grub_terminfo_output_unregister (&grub_serial_term_output);
registered = 0;
}
}
@ -660,5 +394,6 @@ GRUB_MOD_FINI(serial)
{
grub_term_unregister_input (&grub_serial_term_input);
grub_term_unregister_output (&grub_serial_term_output);
grub_terminfo_output_unregister (&grub_serial_term_output);
}
}

View File

@ -32,26 +32,17 @@
#include <grub/tparm.h>
#include <grub/command.h>
#include <grub/i18n.h>
#include <grub/time.h>
struct terminfo
{
char *name;
char *gotoxy;
char *cls;
char *reverse_video_on;
char *reverse_video_off;
char *cursor_on;
char *cursor_off;
};
static struct terminfo term;
static struct grub_term_output *terminfo_outputs;
/* Get current terminfo name. */
char *
grub_terminfo_get_current (void)
grub_terminfo_get_current (struct grub_term_output *term)
{
return term.name;
struct grub_terminfo_output_state *data
= (struct grub_terminfo_output_state *) term->data;
return data->name;
}
/* Free *PTR and set *PTR to NULL, to prevent double-free. */
@ -62,10 +53,29 @@ grub_terminfo_free (char **ptr)
*ptr = 0;
}
static void
grub_terminfo_all_free (struct grub_term_output *term)
{
struct grub_terminfo_output_state *data
= (struct grub_terminfo_output_state *) term->data;
/* Free previously allocated memory. */
grub_terminfo_free (&data->name);
grub_terminfo_free (&data->gotoxy);
grub_terminfo_free (&data->cls);
grub_terminfo_free (&data->reverse_video_on);
grub_terminfo_free (&data->reverse_video_off);
grub_terminfo_free (&data->cursor_on);
grub_terminfo_free (&data->cursor_off);
}
/* Set current terminfo type. */
grub_err_t
grub_terminfo_set_current (const char *str)
grub_terminfo_set_current (struct grub_term_output *term,
const char *str)
{
struct grub_terminfo_output_state *data
= (struct grub_terminfo_output_state *) term->data;
/* TODO
* Lookup user specified terminfo type. If found, set term variables
* as appropriate. Otherwise return an error.
@ -83,95 +93,518 @@ grub_terminfo_set_current (const char *str)
* d. Your idea here.
*/
/* Free previously allocated memory. */
grub_terminfo_free (&term.name);
grub_terminfo_free (&term.gotoxy);
grub_terminfo_free (&term.cls);
grub_terminfo_free (&term.reverse_video_on);
grub_terminfo_free (&term.reverse_video_off);
grub_terminfo_free (&term.cursor_on);
grub_terminfo_free (&term.cursor_off);
grub_terminfo_all_free (term);
if (grub_strcmp ("vt100", str) == 0)
{
term.name = grub_strdup ("vt100");
term.gotoxy = grub_strdup ("\e[%i%p1%d;%p2%dH");
term.cls = grub_strdup ("\e[H\e[J");
term.reverse_video_on = grub_strdup ("\e[7m");
term.reverse_video_off = grub_strdup ("\e[m");
term.cursor_on = grub_strdup ("\e[?25h");
term.cursor_off = grub_strdup ("\e[?25l");
data->name = grub_strdup ("vt100");
data->gotoxy = grub_strdup ("\e[%i%p1%d;%p2%dH");
data->cls = grub_strdup ("\e[H\e[J");
data->reverse_video_on = grub_strdup ("\e[7m");
data->reverse_video_off = grub_strdup ("\e[m");
data->cursor_on = grub_strdup ("\e[?25h");
data->cursor_off = grub_strdup ("\e[?25l");
data->setcolor = NULL;
return grub_errno;
}
if (grub_strcmp ("vt100-color", str) == 0)
{
data->name = grub_strdup ("vt100-color");
data->gotoxy = grub_strdup ("\e[%i%p1%d;%p2%dH");
data->cls = grub_strdup ("\e[H\e[J");
data->reverse_video_on = grub_strdup ("\e[7m");
data->reverse_video_off = grub_strdup ("\e[m");
data->cursor_on = grub_strdup ("\e[?25h");
data->cursor_off = grub_strdup ("\e[?25l");
data->setcolor = grub_strdup ("\e[3%p1%dm\e[4%p2%dm");
return grub_errno;
}
if (grub_strcmp ("ieee1275", str) == 0)
{
data->name = grub_strdup ("ieee1275");
data->gotoxy = grub_strdup ("\e[%i%p1%d;%p2%dH");
/* Clear the screen. Using serial console, screen(1) only recognizes the
* ANSI escape sequence. Using video console, Apple Open Firmware
* (version 3.1.1) only recognizes the literal ^L. So use both. */
data->cls = grub_strdup (" \e[2J");
data->reverse_video_on = grub_strdup ("\e[7m");
data->reverse_video_off = grub_strdup ("\e[m");
data->cursor_on = grub_strdup ("\e[?25h");
data->cursor_off = grub_strdup ("\e[?25l");
data->setcolor = grub_strdup ("\e[3%p1%dm\e[4%p2%dm");
return grub_errno;
}
if (grub_strcmp ("dumb", str) == 0)
{
data->name = grub_strdup ("dumb");
data->gotoxy = NULL;
data->cls = NULL;
data->reverse_video_on = NULL;
data->reverse_video_off = NULL;
data->cursor_on = NULL;
data->cursor_off = NULL;
data->setcolor = NULL;
return grub_errno;
}
return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminfo type");
}
/* Wrapper for grub_putchar to write strings. */
static void
putstr (const char *str, grub_term_output_t oterm)
grub_err_t
grub_terminfo_output_register (struct grub_term_output *term,
const char *type)
{
while (*str)
grub_putcode (*str++, oterm);
grub_err_t err;
struct grub_terminfo_output_state *data;
err = grub_terminfo_set_current (term, type);
if (err)
return err;
data = (struct grub_terminfo_output_state *) term->data;
data->next = terminfo_outputs;
terminfo_outputs = term;
return GRUB_ERR_NONE;
}
/* Move the cursor to the given position starting with "0". */
void
grub_terminfo_gotoxy (grub_uint8_t x, grub_uint8_t y, grub_term_output_t oterm)
grub_err_t
grub_terminfo_output_unregister (struct grub_term_output *term)
{
putstr (grub_terminfo_tparm (term.gotoxy, y, x), oterm);
struct grub_term_output **ptr;
for (ptr = &terminfo_outputs; *ptr;
ptr = &((struct grub_terminfo_output_state *) (*ptr)->data)->next)
if (*ptr == term)
{
grub_terminfo_all_free (term);
*ptr = ((struct grub_terminfo_output_state *) (*ptr)->data)->next;
return GRUB_ERR_NONE;
}
return grub_error (GRUB_ERR_BAD_ARGUMENT, "terminal not found");
}
/* Wrapper for grub_putchar to write strings. */
static void
putstr (struct grub_term_output *term, const char *str)
{
struct grub_terminfo_output_state *data
= (struct grub_terminfo_output_state *) term->data;
while (*str)
data->put (*str++);
}
grub_uint16_t
grub_terminfo_getxy (struct grub_term_output *term)
{
struct grub_terminfo_output_state *data
= (struct grub_terminfo_output_state *) term->data;
return ((data->xpos << 8) | data->ypos);
}
void
grub_terminfo_gotoxy (struct grub_term_output *term,
grub_uint8_t x, grub_uint8_t y)
{
struct grub_terminfo_output_state *data
= (struct grub_terminfo_output_state *) term->data;
if (x > grub_term_width (term) || y > grub_term_height (term))
{
grub_error (GRUB_ERR_OUT_OF_RANGE, "invalid point (%u,%u)", x, y);
return;
}
if (data->gotoxy)
putstr (term, grub_terminfo_tparm (data->gotoxy, y, x));
else
{
if ((y == data->ypos) && (x == data->xpos - 1))
data->put ('\b');
}
data->xpos = x;
data->ypos = y;
}
/* Clear the screen. */
void
grub_terminfo_cls (grub_term_output_t oterm)
grub_terminfo_cls (struct grub_term_output *term)
{
putstr (grub_terminfo_tparm (term.cls), oterm);
struct grub_terminfo_output_state *data
= (struct grub_terminfo_output_state *) term->data;
putstr (term, grub_terminfo_tparm (data->cls));
data->xpos = data->ypos = 0;
}
/* Set reverse video mode on. */
void
grub_terminfo_reverse_video_on (grub_term_output_t oterm)
grub_terminfo_setcolorstate (struct grub_term_output *term,
const grub_term_color_state state)
{
putstr (grub_terminfo_tparm (term.reverse_video_on), oterm);
struct grub_terminfo_output_state *data
= (struct grub_terminfo_output_state *) term->data;
if (data->setcolor)
{
int fg;
int bg;
/* Map from VGA to terminal colors. */
const int colormap[8]
= { 0, /* Black. */
4, /* Blue. */
2, /* Green. */
6, /* Cyan. */
1, /* Red. */
5, /* Magenta. */
3, /* Yellow. */
7, /* White. */
};
switch (state)
{
case GRUB_TERM_COLOR_STANDARD:
case GRUB_TERM_COLOR_NORMAL:
fg = term->normal_color & 0x0f;
bg = term->normal_color >> 4;
break;
case GRUB_TERM_COLOR_HIGHLIGHT:
fg = term->highlight_color & 0x0f;
bg = term->highlight_color >> 4;
break;
default:
return;
}
putstr (term, grub_terminfo_tparm (data->setcolor, colormap[fg & 7],
colormap[bg & 7]));
return;
}
switch (state)
{
case GRUB_TERM_COLOR_STANDARD:
case GRUB_TERM_COLOR_NORMAL:
putstr (term, grub_terminfo_tparm (data->reverse_video_off));
break;
case GRUB_TERM_COLOR_HIGHLIGHT:
putstr (term, grub_terminfo_tparm (data->reverse_video_on));
break;
default:
break;
}
}
/* Set reverse video mode off. */
void
grub_terminfo_reverse_video_off (grub_term_output_t oterm)
grub_terminfo_setcursor (struct grub_term_output *term, const int on)
{
putstr (grub_terminfo_tparm (term.reverse_video_off), oterm);
struct grub_terminfo_output_state *data
= (struct grub_terminfo_output_state *) term->data;
if (on)
putstr (term, grub_terminfo_tparm (data->cursor_on));
else
putstr (term, grub_terminfo_tparm (data->cursor_off));
}
/* Show cursor. */
/* The terminfo version of putchar. */
void
grub_terminfo_cursor_on (grub_term_output_t oterm)
grub_terminfo_putchar (struct grub_term_output *term,
const struct grub_unicode_glyph *c)
{
putstr (grub_terminfo_tparm (term.cursor_on), oterm);
struct grub_terminfo_output_state *data
= (struct grub_terminfo_output_state *) term->data;
/* Keep track of the cursor. */
switch (c->base)
{
case '\a':
break;
case '\b':
case 127:
if (data->xpos > 0)
data->xpos--;
break;
case '\n':
if (data->ypos < grub_term_height (term) - 1)
data->ypos++;
break;
case '\r':
data->xpos = 0;
break;
default:
if (data->xpos + c->estimated_width >= grub_term_width (term) + 1)
{
data->xpos = 0;
if (data->ypos < grub_term_height (term) - 1)
data->ypos++;
data->put ('\r');
data->put ('\n');
}
data->xpos += c->estimated_width;
break;
}
data->put (c->base);
}
/* Hide cursor. */
void
grub_terminfo_cursor_off (grub_term_output_t oterm)
#define ANSI_C0 0x9b
static void
grub_terminfo_readkey (int *keys, int *len, int (*readkey) (void))
{
putstr (grub_terminfo_tparm (term.cursor_off), oterm);
int c;
#define CONTINUE_READ \
{ \
grub_uint64_t start; \
/* On 9600 we have to wait up to 12 milliseconds. */ \
start = grub_get_time_ms (); \
do \
c = readkey (); \
while (c == -1 && grub_get_time_ms () - start < 12); \
if (c == -1) \
return; \
\
keys[*len] = c; \
(*len)++; \
}
c = readkey ();
if (c < 0)
{
*len = 0;
return;
}
*len = 1;
keys[0] = c;
if (c != ANSI_C0 && c != '\e')
{
/* Backspace: Ctrl-h. */
if (c == 0x7f)
c = '\b';
*len = 1;
keys[0] = c;
return;
}
{
static struct
{
char key;
char ascii;
}
three_code_table[] =
{
{'4', GRUB_TERM_DC},
{'A', GRUB_TERM_UP},
{'B', GRUB_TERM_DOWN},
{'C', GRUB_TERM_RIGHT},
{'D', GRUB_TERM_LEFT},
{'F', GRUB_TERM_END},
{'H', GRUB_TERM_HOME},
{'K', GRUB_TERM_END},
{'P', GRUB_TERM_DC},
{'?', GRUB_TERM_PPAGE},
{'/', GRUB_TERM_NPAGE}
};
static struct
{
char key;
char ascii;
}
four_code_table[] =
{
{'1', GRUB_TERM_HOME},
{'3', GRUB_TERM_DC},
{'5', GRUB_TERM_PPAGE},
{'6', GRUB_TERM_NPAGE}
};
unsigned i;
if (c == '\e')
{
CONTINUE_READ;
if (c != '[')
return;
}
CONTINUE_READ;
for (i = 0; i < ARRAY_SIZE (three_code_table); i++)
if (three_code_table[i].key == c)
{
keys[0] = three_code_table[i].ascii;
*len = 1;
return;
}
for (i = 0; i < ARRAY_SIZE (four_code_table); i++)
if (four_code_table[i].key == c)
{
CONTINUE_READ;
if (c != '~')
return;
keys[0] = three_code_table[i].ascii;
*len = 1;
return;
}
return;
}
#undef CONTINUE_READ
}
/* The terminfo version of checkkey. */
int
grub_terminfo_checkkey (struct grub_term_input *termi)
{
struct grub_terminfo_input_state *data
= (struct grub_terminfo_input_state *) (termi->data);
if (data->npending)
return data->input_buf[0];
grub_terminfo_readkey (data->input_buf, &data->npending, data->readkey);
if (data->npending)
return data->input_buf[0];
return -1;
}
/* The terminfo version of getkey. */
int
grub_terminfo_getkey (struct grub_term_input *termi)
{
struct grub_terminfo_input_state *data
= (struct grub_terminfo_input_state *) (termi->data);
int ret;
while (! data->npending)
grub_terminfo_readkey (data->input_buf, &data->npending, data->readkey);
ret = data->input_buf[0];
data->npending--;
grub_memmove (data->input_buf, data->input_buf + 1, data->npending);
return ret;
}
grub_err_t
grub_terminfo_input_init (struct grub_term_input *termi)
{
struct grub_terminfo_input_state *data
= (struct grub_terminfo_input_state *) (termi->data);
data->npending = 0;
return GRUB_ERR_NONE;
}
/* GRUB Command. */
static grub_err_t
print_terminfo (void)
{
const char *encoding_names[(GRUB_TERM_CODE_TYPE_MASK
>> GRUB_TERM_CODE_TYPE_SHIFT) + 1]
= {
/* VGA and glyph descriptor types are just for completeness,
they are not used on terminfo terminals.
*/
[GRUB_TERM_CODE_TYPE_ASCII >> GRUB_TERM_CODE_TYPE_SHIFT] = _("ASCII"),
[GRUB_TERM_CODE_TYPE_CP437 >> GRUB_TERM_CODE_TYPE_SHIFT] = "CP-437",
[GRUB_TERM_CODE_TYPE_UTF8_LOGICAL >> GRUB_TERM_CODE_TYPE_SHIFT]
= _("UTF-8"),
[GRUB_TERM_CODE_TYPE_UTF8_VISUAL >> GRUB_TERM_CODE_TYPE_SHIFT]
= _("UTF-8 visual"),
[GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS >> GRUB_TERM_CODE_TYPE_SHIFT]
= "Glyph descriptors",
_("Unknown"), _("Unknown"), _("Unknown")
};
struct grub_term_output *cur;
grub_printf ("Current terminfo types: \n");
for (cur = terminfo_outputs; cur;
cur = ((struct grub_terminfo_output_state *) cur->data)->next)
grub_printf ("%s: %s\t%s\n", cur->name,
grub_terminfo_get_current(cur),
encoding_names[(cur->flags & GRUB_TERM_CODE_TYPE_MASK)
>> GRUB_TERM_CODE_TYPE_SHIFT]);
return GRUB_ERR_NONE;
}
static grub_err_t
grub_cmd_terminfo (grub_command_t cmd __attribute__ ((unused)),
int argc, char **args)
{
struct grub_term_output *cur;
int encoding = GRUB_TERM_CODE_TYPE_ASCII;
int i;
char *name = NULL, *type = NULL;
if (argc == 0)
{
grub_printf ("Current terminfo type: %s\n", grub_terminfo_get_current());
return GRUB_ERR_NONE;
}
else if (argc != 1)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "too many parameters");
else
return grub_terminfo_set_current (args[0]);
return print_terminfo ();
for (i = 0; i < argc; i++)
{
if (grub_strcmp (args[i], "-a") == 0
|| grub_strcmp (args[i], "--ascii") == 0)
{
encoding = GRUB_TERM_CODE_TYPE_ASCII;
continue;
}
if (grub_strcmp (args[i], "-u") == 0
|| grub_strcmp (args[i], "--utf8") == 0)
{
encoding = GRUB_TERM_CODE_TYPE_UTF8_LOGICAL;
continue;
}
if (grub_strcmp (args[i], "-v") == 0
|| grub_strcmp (args[i], "--visual-utf8") == 0)
{
encoding = GRUB_TERM_CODE_TYPE_UTF8_VISUAL;
continue;
}
if (!name)
{
name = args[i];
continue;
}
if (!type)
{
type = args[i];
continue;
}
return grub_error (GRUB_ERR_BAD_ARGUMENT, "too many parameters");
}
if (name == NULL)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "too few parameters");
for (cur = terminfo_outputs; cur;
cur = ((struct grub_terminfo_output_state *) cur->data)->next)
if (grub_strcmp (name, cur->name) == 0)
{
cur->flags = (cur->flags & ~GRUB_TERM_CODE_TYPE_MASK) | encoding;
if (!type)
return GRUB_ERR_NONE;
return grub_terminfo_set_current (cur, type);
}
return grub_error (GRUB_ERR_BAD_ARGUMENT,
"no terminal %s found or it's not handled by terminfo",
name);
}
static grub_command_t cmd;
@ -179,8 +612,13 @@ static grub_command_t cmd;
GRUB_MOD_INIT(terminfo)
{
cmd = grub_register_command ("terminfo", grub_cmd_terminfo,
N_("[TERM]"), N_("Set terminfo type."));
grub_terminfo_set_current ("vt100");
N_("[[-a|-u|-v] TERM [TYPE]]"),
N_("Set terminfo type of TERM to TYPE.\n"
"-a, --ascii Terminal is ASCII-only [default].\n"
"-u, --utf8 Terminal is logical-ordered UTF-8.\n"
"-v, --visual-utf8 Terminal is visually-ordered UTF-8.")
);
}
GRUB_MOD_FINI(terminfo)

View File

@ -751,6 +751,9 @@ grub_terminfo_tparm (const char *string, ...)
va_list ap;
char *result;
if (!string)
return "";
va_start (ap, string);
result = tparam_internal (string, ap);
va_end (ap);

View File

@ -119,7 +119,7 @@ grub_usb_keyboard_getreport (grub_usb_device_t dev, grub_uint8_t *report)
static int
grub_usb_keyboard_checkkey (void)
grub_usb_keyboard_checkkey (struct grub_term_input *term __attribute__ ((unused)))
{
grub_uint8_t data[8];
int key;
@ -188,7 +188,7 @@ typedef enum
} grub_usb_keyboard_repeat_t;
static int
grub_usb_keyboard_getkey (void)
grub_usb_keyboard_getkey (struct grub_term_input *term)
{
int key;
grub_err_t err;
@ -201,7 +201,7 @@ grub_usb_keyboard_getkey (void)
do
{
key = grub_usb_keyboard_checkkey ();
key = grub_usb_keyboard_checkkey (term);
} while (key == -1);
data[2] = !0; /* Or whatever. */
@ -253,7 +253,7 @@ grub_usb_keyboard_getkey (void)
}
static int
grub_usb_keyboard_getkeystatus (void)
grub_usb_keyboard_getkeystatus (struct grub_term_input *term __attribute__ ((unused)))
{
grub_uint8_t data[8];
int mods = 0;

373
unicode/ArabicShaping.txt Normal file
View File

@ -0,0 +1,373 @@
# ArabicShaping-5.2.0.txt
# Date: 2009-08-17, 11:11:00 PDT [KW]
#
# This file is a normative contributory data file in the
# Unicode Character Database.
#
# Copyright (c) 1991-2009 Unicode, Inc.
# For terms of use, see http://www.unicode.org/terms_of_use.html
#
# This file defines the shaping classes for Arabic, Syriac, and N'Ko
# positional shaping, repeating in machine readable form the
# information exemplified in Tables 8-3, 8-7, 8-8, 8-11, 8-12,
# 8-13, and 13-5 of The Unicode Standard, Version 5.2.
#
# See sections 8.2, 8.3, and 13.5 of The Unicode Standard, Version 5.2
# for more information.
#
# Each line contains four fields, separated by a semicolon.
#
# Field 0: the code point, in 4-digit hexadecimal
# form, of an Arabic, Syriac, or N'Ko character.
#
# Field 1: gives a short schematic name for that character,
# abbreviated from the normative Unicode character name.
#
# Field 2: defines the joining type (property name: Joining_Type)
# R Right_Joining
# L Left_Joining
# D Dual_Joining
# C Join_Causing
# U Non_Joining
# T Transparent
# See Section 8.2, Arabic for more information on these types.
#
# Field 3: defines the joining group (property name: Joining_Group)
#
# The values of the joining group are based schematically on character
# names. Where a schematic character name consists of two or more parts separated
# by spaces, the formal Joining_Group property value, as specified in
# PropertyValueAliases.txt, consists of the same name parts joined by
# underscores. Hence, the entry:
#
# 0629; TEH MARBUTA; R; TEH MARBUTA
#
# corresponds to [Joining_Group = Teh_Marbuta].
#
# Note: For historical reasons, the property value [Joining_Group = Hamza_On_Heh_Goal]
# is anachronistically named. It used to apply to both of the following characters
# in earlier versions of the standard:
#
# U+06C2 ARABIC LETTER HEH GOAL WITH HAMZA ABOVE
# U+06C3 ARABIC LETTER TEH MARBUTA GOAL
#
# However, it currently applies only to U+06C3, and *not* to U+06C2.
# To avoid destabilizing existing Joining_Group property aliases, the
# value Hamza_On_Heh_Goal has not been changed, despite the fact that it
# no longer applies to Hamza On Heh Goal, but only to Teh Marbuta Goal.
#
# When other cursive scripts are added to the Unicode Standard in
# the future, the joining group value of all its letters will default
# to jg=No_Joining_Group in this data file. Other, more specific
# joining group values will be defined only if an explicit proposal
# to define those values exactly has been approved by the UTC. This
# is the convention exemplified by the N'Ko script. Only the Arabic
# and Syriac scripts currently have explicit joining group values defined.
#
# Note: Code points that are not explicitly listed in this file are
# either of joining type T or U:
#
# - Those that not explicitly listed that are of General Category Mn, Me, or Cf
# have joining type T.
# - All others not explicitly listed have joining type U.
#
# For an explicit listing of characters of joining type T, see
# the derived property file DerivedJoiningType.txt.
#
# There are currently no characters of joining type L defined in Unicode.
#
# #############################################################
# Unicode; Schematic Name; Joining Type; Joining Group
# Arabic characters
0600; ARABIC NUMBER SIGN; U; No_Joining_Group
0601; ARABIC SIGN SANAH; U; No_Joining_Group
0602; ARABIC FOOTNOTE MARKER; U; No_Joining_Group
0603; ARABIC SIGN SAFHA; U; No_Joining_Group
0608; ARABIC RAY; U; No_Joining_Group
060B; AFGHANI SIGN; U; No_Joining_Group
0621; HAMZA; U; No_Joining_Group
0622; MADDA ON ALEF; R; ALEF
0623; HAMZA ON ALEF; R; ALEF
0624; HAMZA ON WAW; R; WAW
0625; HAMZA UNDER ALEF; R; ALEF
0626; HAMZA ON YEH; D; YEH
0627; ALEF; R; ALEF
0628; BEH; D; BEH
0629; TEH MARBUTA; R; TEH MARBUTA
062A; TEH; D; BEH
062B; THEH; D; BEH
062C; JEEM; D; HAH
062D; HAH; D; HAH
062E; KHAH; D; HAH
062F; DAL; R; DAL
0630; THAL; R; DAL
0631; REH; R; REH
0632; ZAIN; R; REH
0633; SEEN; D; SEEN
0634; SHEEN; D; SEEN
0635; SAD; D; SAD
0636; DAD; D; SAD
0637; TAH; D; TAH
0638; ZAH; D; TAH
0639; AIN; D; AIN
063A; GHAIN; D; AIN
063B; KEHEH WITH 2 DOTS ABOVE; D; GAF
063C; KEHEH WITH 3 DOTS BELOW; D; GAF
063D; FARSI YEH WITH INVERTED V; D; FARSI YEH
063E; FARSI YEH WITH 2 DOTS ABOVE; D; FARSI YEH
063F; FARSI YEH WITH 3 DOTS ABOVE; D; FARSI YEH
0640; TATWEEL; C; No_Joining_Group
0641; FEH; D; FEH
0642; QAF; D; QAF
0643; KAF; D; KAF
0644; LAM; D; LAM
0645; MEEM; D; MEEM
0646; NOON; D; NOON
0647; HEH; D; HEH
0648; WAW; R; WAW
0649; ALEF MAKSURA; D; YEH
064A; YEH; D; YEH
066E; DOTLESS BEH; D; BEH
066F; DOTLESS QAF; D; QAF
0671; HAMZAT WASL ON ALEF; R; ALEF
0672; WAVY HAMZA ON ALEF; R; ALEF
0673; WAVY HAMZA UNDER ALEF; R; ALEF
0674; HIGH HAMZA; U; No_Joining_Group
0675; HIGH HAMZA ALEF; R; ALEF
0676; HIGH HAMZA WAW; R; WAW
0677; HIGH HAMZA WAW WITH DAMMA; R; WAW
0678; HIGH HAMZA YEH; D; YEH
0679; TEH WITH SMALL TAH; D; BEH
067A; TEH WITH 2 DOTS VERTICAL ABOVE; D; BEH
067B; BEH WITH 2 DOTS VERTICAL BELOW; D; BEH
067C; TEH WITH RING; D; BEH
067D; TEH WITH 3 DOTS ABOVE DOWNWARD; D; BEH
067E; TEH WITH 3 DOTS BELOW; D; BEH
067F; TEH WITH 4 DOTS ABOVE; D; BEH
0680; BEH WITH 4 DOTS BELOW; D; BEH
0681; HAMZA ON HAH; D; HAH
0682; HAH WITH 2 DOTS VERTICAL ABOVE; D; HAH
0683; HAH WITH MIDDLE 2 DOTS; D; HAH
0684; HAH WITH MIDDLE 2 DOTS VERTICAL; D; HAH
0685; HAH WITH 3 DOTS ABOVE; D; HAH
0686; HAH WITH MIDDLE 3 DOTS DOWNWARD; D; HAH
0687; HAH WITH MIDDLE 4 DOTS; D; HAH
0688; DAL WITH SMALL TAH; R; DAL
0689; DAL WITH RING; R; DAL
068A; DAL WITH DOT BELOW; R; DAL
068B; DAL WITH DOT BELOW AND SMALL TAH; R; DAL
068C; DAL WITH 2 DOTS ABOVE; R; DAL
068D; DAL WITH 2 DOTS BELOW; R; DAL
068E; DAL WITH 3 DOTS ABOVE; R; DAL
068F; DAL WITH 3 DOTS ABOVE DOWNWARD; R; DAL
0690; DAL WITH 4 DOTS ABOVE; R; DAL
0691; REH WITH SMALL TAH; R; REH
0692; REH WITH SMALL V; R; REH
0693; REH WITH RING; R; REH
0694; REH WITH DOT BELOW; R; REH
0695; REH WITH SMALL V BELOW; R; REH
0696; REH WITH DOT BELOW AND DOT ABOVE; R; REH
0697; REH WITH 2 DOTS ABOVE; R; REH
0698; REH WITH 3 DOTS ABOVE; R; REH
0699; REH WITH 4 DOTS ABOVE; R; REH
069A; SEEN WITH DOT BELOW AND DOT ABOVE; D; SEEN
069B; SEEN WITH 3 DOTS BELOW; D; SEEN
069C; SEEN WITH 3 DOTS BELOW AND 3 DOTS ABOVE; D; SEEN
069D; SAD WITH 2 DOTS BELOW; D; SAD
069E; SAD WITH 3 DOTS ABOVE; D; SAD
069F; TAH WITH 3 DOTS ABOVE; D; TAH
06A0; AIN WITH 3 DOTS ABOVE; D; AIN
06A1; DOTLESS FEH; D; FEH
06A2; FEH WITH DOT MOVED BELOW; D; FEH
06A3; FEH WITH DOT BELOW; D; FEH
06A4; FEH WITH 3 DOTS ABOVE; D; FEH
06A5; FEH WITH 3 DOTS BELOW; D; FEH
06A6; FEH WITH 4 DOTS ABOVE; D; FEH
06A7; QAF WITH DOT ABOVE; D; QAF
06A8; QAF WITH 3 DOTS ABOVE; D; QAF
06A9; KEHEH; D; GAF
06AA; SWASH KAF; D; SWASH KAF
06AB; KAF WITH RING; D; GAF
06AC; KAF WITH DOT ABOVE; D; KAF
06AD; KAF WITH 3 DOTS ABOVE; D; KAF
06AE; KAF WITH 3 DOTS BELOW; D; KAF
06AF; GAF; D; GAF
06B0; GAF WITH RING; D; GAF
06B1; GAF WITH 2 DOTS ABOVE; D; GAF
06B2; GAF WITH 2 DOTS BELOW; D; GAF
06B3; GAF WITH 2 DOTS VERTICAL BELOW; D; GAF
06B4; GAF WITH 3 DOTS ABOVE; D; GAF
06B5; LAM WITH SMALL V; D; LAM
06B6; LAM WITH DOT ABOVE; D; LAM
06B7; LAM WITH 3 DOTS ABOVE; D; LAM
06B8; LAM WITH 3 DOTS BELOW; D; LAM
06B9; NOON WITH DOT BELOW; D; NOON
06BA; DOTLESS NOON; D; NOON
06BB; DOTLESS NOON WITH SMALL TAH; D; NOON
06BC; NOON WITH RING; D; NOON
06BD; NYA; D; NYA
06BE; KNOTTED HEH; D; KNOTTED HEH
06BF; HAH WITH MIDDLE 3 DOTS DOWNWARD AND DOT ABOVE; D; HAH
06C0; HAMZA ON HEH; R; TEH MARBUTA
06C1; HEH GOAL; D; HEH GOAL
06C2; HAMZA ON HEH GOAL; D; HEH GOAL
06C3; TEH MARBUTA GOAL; R; HAMZA ON HEH GOAL
06C4; WAW WITH RING; R; WAW
06C5; WAW WITH BAR; R; WAW
06C6; WAW WITH SMALL V; R; WAW
06C7; WAW WITH DAMMA; R; WAW
06C8; WAW WITH ALEF ABOVE; R; WAW
06C9; WAW WITH INVERTED SMALL V; R; WAW
06CA; WAW WITH 2 DOTS ABOVE; R; WAW
06CB; WAW WITH 3 DOTS ABOVE; R; WAW
06CC; FARSI YEH; D; FARSI YEH
06CD; YEH WITH TAIL; R; YEH WITH TAIL
06CE; FARSI YEH WITH SMALL V; D; FARSI YEH
06CF; WAW WITH DOT ABOVE; R; WAW
06D0; YEH WITH 2 DOTS VERTICAL BELOW; D; YEH
06D1; YEH WITH 3 DOTS BELOW; D; YEH
06D2; YEH BARREE; R; YEH BARREE
06D3; HAMZA ON YEH BARREE; R; YEH BARREE
06D5; AE; R; TEH MARBUTA
06DD; ARABIC END OF AYAH; U; No_Joining_Group
06EE; DAL WITH INVERTED V; R; DAL
06EF; REH WITH INVERTED V; R; REH
06FA; SEEN WITH DOT BELOW AND 3 DOTS ABOVE; D; SEEN
06FB; DAD WITH DOT BELOW; D; SAD
06FC; GHAIN WITH DOT BELOW; D; AIN
06FF; HEH WITH INVERTED V; D; KNOTTED HEH
# Syriac characters
0710; ALAPH; R; ALAPH
0712; BETH; D; BETH
0713; GAMAL; D; GAMAL
0714; GAMAL GARSHUNI; D; GAMAL
0715; DALATH; R; DALATH RISH
0716; DOTLESS DALATH RISH; R; DALATH RISH
0717; HE; R; HE
0718; WAW; R; SYRIAC WAW
0719; ZAIN; R; ZAIN
071A; HETH; D; HETH
071B; TETH; D; TETH
071C; TETH GARSHUNI; D; TETH
071D; YUDH; D; YUDH
071E; YUDH HE; R; YUDH HE
071F; KAPH; D; KAPH
0720; LAMADH; D; LAMADH
0721; MIM; D; MIM
0722; NUN; D; NUN
0723; SEMKATH; D; SEMKATH
0724; FINAL SEMKATH; D; FINAL SEMKATH
0725; E; D; E
0726; PE; D; PE
0727; REVERSED PE; D; REVERSED PE
0728; SADHE; R; SADHE
0729; QAPH; D; QAPH
072A; RISH; R; DALATH RISH
072B; SHIN; D; SHIN
072C; TAW; R; TAW
072D; PERSIAN BHETH; D; BETH
072E; PERSIAN GHAMAL; D; GAMAL
072F; PERSIAN DHALATH; R; DALATH RISH
074D; SOGDIAN ZHAIN; R; ZHAIN
074E; SOGDIAN KHAPH; D; KHAPH
074F; SOGDIAN FE; D; FE
# Arabic supplement characters
0750; BEH WITH 3 DOTS HORIZONTALLY BELOW; D; BEH
0751; BEH WITH DOT BELOW AND 3 DOTS ABOVE; D; BEH
0752; BEH WITH 3 DOTS POINTING UPWARDS BELOW; D; BEH
0753; BEH WITH 3 DOTS POINTING UPWARDS BELOW AND 2 DOTS ABOVE; D; BEH
0754; BEH WITH 2 DOTS BELOW AND DOT ABOVE; D; BEH
0755; BEH WITH INVERTED SMALL V BELOW; D; BEH
0756; BEH WITH SMALL V; D; BEH
0757; HAH WITH 2 DOTS ABOVE; D; HAH
0758; HAH WITH 3 DOTS POINTING UPWARDS BELOW; D; HAH
0759; DAL WITH 2 DOTS VERTICALLY BELOW AND SMALL TAH; R; DAL
075A; DAL WITH INVERTED SMALL V BELOW; R; DAL
075B; REH WITH STROKE; R; REH
075C; SEEN WITH 4 DOTS ABOVE; D; SEEN
075D; AIN WITH 2 DOTS ABOVE; D; AIN
075E; AIN WITH 3 DOTS POINTING DOWNWARDS ABOVE; D; AIN
075F; AIN WITH 2 DOTS VERTICALLY ABOVE; D; AIN
0760; FEH WITH 2 DOTS BELOW; D; FEH
0761; FEH WITH 3 DOTS POINTING UPWARDS BELOW; D; FEH
0762; KEHEH WITH DOT ABOVE; D; GAF
0763; KEHEH WITH 3 DOTS ABOVE; D; GAF
0764; KEHEH WITH 3 DOTS POINTING UPWARDS BELOW; D; GAF
0765; MEEM WITH DOT ABOVE; D; MEEM
0766; MEEM WITH DOT BELOW; D; MEEM
0767; NOON WITH 2 DOTS BELOW; D; NOON
0768; NOON WITH SMALL TAH; D; NOON
0769; NOON WITH SMALL V; D; NOON
076A; LAM WITH BAR; D; LAM
076B; REH WITH 2 DOTS VERTICALLY ABOVE; R; REH
076C; REH WITH HAMZA ABOVE; R; REH
076D; SEEN WITH 2 DOTS VERTICALLY ABOVE; D; SEEN
076E; HAH WITH SMALL TAH BELOW; D; HAH
076F; HAH WITH SMALL TAH AND 2 DOTS; D; HAH
0770; SEEN WITH SMALL TAH AND 2 DOTS; D; SEEN
0771; REH WITH SMALL TAH AND 2 DOTS; R; REH
0772; HAH WITH SMALL TAH ABOVE; D; HAH
0773; ALEF WITH DIGIT TWO ABOVE; R; ALEF
0774; ALEF WITH DIGIT THREE ABOVE; R; ALEF
0775; FARSI YEH WITH DIGIT TWO ABOVE; D; FARSI YEH
0776; FARSI YEH WITH DIGIT THREE ABOVE; D; FARSI YEH
0777; YEH WITH DIGIT FOUR BELOW; D; YEH
0778; WAW WITH DIGIT TWO ABOVE; R; WAW
0779; WAW WITH DIGIT THREE ABOVE; R; WAW
077A; YEH BARREE WITH DIGIT TWO ABOVE; D; BURUSHASKI YEH BARREE
077B; YEH BARREE WITH DIGIT THREE ABOVE; D; BURUSHASKI YEH BARREE
077C; HAH WITH DIGIT FOUR BELOW; D; HAH
077D; SEEN WITH DIGIT FOUR ABOVE; D; SEEN
077E; SEEN WITH INVERTED V; D; SEEN
077F; KAF WITH 2 DOTS ABOVE; D; KAF
# N'Ko Characters
07CA; NKO A; D; No_Joining_Group
07CB; NKO EE; D; No_Joining_Group
07CC; NKO I; D; No_Joining_Group
07CD; NKO E; D; No_Joining_Group
07CE; NKO U; D; No_Joining_Group
07CF; NKO OO; D; No_Joining_Group
07D0; NKO O; D; No_Joining_Group
07D1; NKO DAGBASINNA; D; No_Joining_Group
07D2; NKO N; D; No_Joining_Group
07D3; NKO BA; D; No_Joining_Group
07D4; NKO PA; D; No_Joining_Group
07D5; NKO TA; D; No_Joining_Group
07D6; NKO JA; D; No_Joining_Group
07D7; NKO CHA; D; No_Joining_Group
07D8; NKO DA; D; No_Joining_Group
07D9; NKO RA; D; No_Joining_Group
07DA; NKO RRA; D; No_Joining_Group
07DB; NKO SA; D; No_Joining_Group
07DC; NKO GBA; D; No_Joining_Group
07DD; NKO FA; D; No_Joining_Group
07DE; NKO KA; D; No_Joining_Group
07DF; NKO LA; D; No_Joining_Group
07E0; NKO NA WOLOSO; D; No_Joining_Group
07E1; NKO MA; D; No_Joining_Group
07E2; NKO NYA; D; No_Joining_Group
07E3; NKO NA; D; No_Joining_Group
07E4; NKO HA; D; No_Joining_Group
07E5; NKO WA; D; No_Joining_Group
07E6; NKO YA; D; No_Joining_Group
07E7; NKO NYA WOLOSO; D; No_Joining_Group
07E8; NKO JONA JA; D; No_Joining_Group
07E9; NKO JONA CHA; D; No_Joining_Group
07EA; NKO JONA RA; D; No_Joining_Group
07FA; NKO LAJANYALAN; C; No_Joining_Group
# Other
200C; ZERO WIDTH NON-JOINER; U; No_Joining_Group
200D; ZERO WIDTH JOINER; C; No_Joining_Group
# EOF

588
unicode/BidiMirroring.txt Normal file
View File

@ -0,0 +1,588 @@
# BidiMirroring-5.2.0.txt
# Date: 2009-05-22, 12:44:00 PDT [KW]
#
# Bidi_Mirroring_Glyph Property
#
# This file is an informative contributory data file in the
# Unicode Character Database.
#
# Copyright (c) 1991-2009 Unicode, Inc.
# For terms of use, see http://www.unicode.org/terms_of_use.html
#
# This data file lists characters that have the mirrored property
# where there is another Unicode character that typically has a glyph
# that is the mirror image of the original character's glyph.
# The repertoire covered by the file is Unicode 5.2.0.
#
# The file contains a list of lines with mappings from one code point
# to another one for character-based mirroring.
# Note that for "real" mirroring, a rendering engine needs to select
# appropriate alternative glyphs, and that many Unicode characters do not
# have a mirror-image Unicode character.
#
# Each mapping line contains two fields, separated by a semicolon (';').
# Each of the two fields contains a code point represented as a
# variable-length hexadecimal value with 4 to 6 digits.
# A comment indicates where the characters are "BEST FIT" mirroring.
#
# Code points with the "mirrored" property but no appropriate mirrors are
# listed as comments at the end of the file.
#
# For information on bidi mirroring, see UAX #9: Bidirectional Algorithm,
# at http://www.unicode.org/unicode/reports/tr9/
#
# This file was originally created by Markus Scherer.
# Extended for Unicode 3.2, 4.0, 4.1, 5.0, 5.1, and 5.2 by Ken Whistler.
#
# ############################################################
0028; 0029 # LEFT PARENTHESIS
0029; 0028 # RIGHT PARENTHESIS
003C; 003E # LESS-THAN SIGN
003E; 003C # GREATER-THAN SIGN
005B; 005D # LEFT SQUARE BRACKET
005D; 005B # RIGHT SQUARE BRACKET
007B; 007D # LEFT CURLY BRACKET
007D; 007B # RIGHT CURLY BRACKET
00AB; 00BB # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
00BB; 00AB # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
0F3A; 0F3B # TIBETAN MARK GUG RTAGS GYON
0F3B; 0F3A # TIBETAN MARK GUG RTAGS GYAS
0F3C; 0F3D # TIBETAN MARK ANG KHANG GYON
0F3D; 0F3C # TIBETAN MARK ANG KHANG GYAS
169B; 169C # OGHAM FEATHER MARK
169C; 169B # OGHAM REVERSED FEATHER MARK
2039; 203A # SINGLE LEFT-POINTING ANGLE QUOTATION MARK
203A; 2039 # SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
2045; 2046 # LEFT SQUARE BRACKET WITH QUILL
2046; 2045 # RIGHT SQUARE BRACKET WITH QUILL
207D; 207E # SUPERSCRIPT LEFT PARENTHESIS
207E; 207D # SUPERSCRIPT RIGHT PARENTHESIS
208D; 208E # SUBSCRIPT LEFT PARENTHESIS
208E; 208D # SUBSCRIPT RIGHT PARENTHESIS
2208; 220B # ELEMENT OF
2209; 220C # NOT AN ELEMENT OF
220A; 220D # SMALL ELEMENT OF
220B; 2208 # CONTAINS AS MEMBER
220C; 2209 # DOES NOT CONTAIN AS MEMBER
220D; 220A # SMALL CONTAINS AS MEMBER
2215; 29F5 # DIVISION SLASH
223C; 223D # TILDE OPERATOR
223D; 223C # REVERSED TILDE
2243; 22CD # ASYMPTOTICALLY EQUAL TO
2252; 2253 # APPROXIMATELY EQUAL TO OR THE IMAGE OF
2253; 2252 # IMAGE OF OR APPROXIMATELY EQUAL TO
2254; 2255 # COLON EQUALS
2255; 2254 # EQUALS COLON
2264; 2265 # LESS-THAN OR EQUAL TO
2265; 2264 # GREATER-THAN OR EQUAL TO
2266; 2267 # LESS-THAN OVER EQUAL TO
2267; 2266 # GREATER-THAN OVER EQUAL TO
2268; 2269 # [BEST FIT] LESS-THAN BUT NOT EQUAL TO
2269; 2268 # [BEST FIT] GREATER-THAN BUT NOT EQUAL TO
226A; 226B # MUCH LESS-THAN
226B; 226A # MUCH GREATER-THAN
226E; 226F # [BEST FIT] NOT LESS-THAN
226F; 226E # [BEST FIT] NOT GREATER-THAN
2270; 2271 # [BEST FIT] NEITHER LESS-THAN NOR EQUAL TO
2271; 2270 # [BEST FIT] NEITHER GREATER-THAN NOR EQUAL TO
2272; 2273 # [BEST FIT] LESS-THAN OR EQUIVALENT TO
2273; 2272 # [BEST FIT] GREATER-THAN OR EQUIVALENT TO
2274; 2275 # [BEST FIT] NEITHER LESS-THAN NOR EQUIVALENT TO
2275; 2274 # [BEST FIT] NEITHER GREATER-THAN NOR EQUIVALENT TO
2276; 2277 # LESS-THAN OR GREATER-THAN
2277; 2276 # GREATER-THAN OR LESS-THAN
2278; 2279 # [BEST FIT] NEITHER LESS-THAN NOR GREATER-THAN
2279; 2278 # [BEST FIT] NEITHER GREATER-THAN NOR LESS-THAN
227A; 227B # PRECEDES
227B; 227A # SUCCEEDS
227C; 227D # PRECEDES OR EQUAL TO
227D; 227C # SUCCEEDS OR EQUAL TO
227E; 227F # [BEST FIT] PRECEDES OR EQUIVALENT TO
227F; 227E # [BEST FIT] SUCCEEDS OR EQUIVALENT TO
2280; 2281 # [BEST FIT] DOES NOT PRECEDE
2281; 2280 # [BEST FIT] DOES NOT SUCCEED
2282; 2283 # SUBSET OF
2283; 2282 # SUPERSET OF
2284; 2285 # [BEST FIT] NOT A SUBSET OF
2285; 2284 # [BEST FIT] NOT A SUPERSET OF
2286; 2287 # SUBSET OF OR EQUAL TO
2287; 2286 # SUPERSET OF OR EQUAL TO
2288; 2289 # [BEST FIT] NEITHER A SUBSET OF NOR EQUAL TO
2289; 2288 # [BEST FIT] NEITHER A SUPERSET OF NOR EQUAL TO
228A; 228B # [BEST FIT] SUBSET OF WITH NOT EQUAL TO
228B; 228A # [BEST FIT] SUPERSET OF WITH NOT EQUAL TO
228F; 2290 # SQUARE IMAGE OF
2290; 228F # SQUARE ORIGINAL OF
2291; 2292 # SQUARE IMAGE OF OR EQUAL TO
2292; 2291 # SQUARE ORIGINAL OF OR EQUAL TO
2298; 29B8 # CIRCLED DIVISION SLASH
22A2; 22A3 # RIGHT TACK
22A3; 22A2 # LEFT TACK
22A6; 2ADE # ASSERTION
22A8; 2AE4 # TRUE
22A9; 2AE3 # FORCES
22AB; 2AE5 # DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE
22B0; 22B1 # PRECEDES UNDER RELATION
22B1; 22B0 # SUCCEEDS UNDER RELATION
22B2; 22B3 # NORMAL SUBGROUP OF
22B3; 22B2 # CONTAINS AS NORMAL SUBGROUP
22B4; 22B5 # NORMAL SUBGROUP OF OR EQUAL TO
22B5; 22B4 # CONTAINS AS NORMAL SUBGROUP OR EQUAL TO
22B6; 22B7 # ORIGINAL OF
22B7; 22B6 # IMAGE OF
22C9; 22CA # LEFT NORMAL FACTOR SEMIDIRECT PRODUCT
22CA; 22C9 # RIGHT NORMAL FACTOR SEMIDIRECT PRODUCT
22CB; 22CC # LEFT SEMIDIRECT PRODUCT
22CC; 22CB # RIGHT SEMIDIRECT PRODUCT
22CD; 2243 # REVERSED TILDE EQUALS
22D0; 22D1 # DOUBLE SUBSET
22D1; 22D0 # DOUBLE SUPERSET
22D6; 22D7 # LESS-THAN WITH DOT
22D7; 22D6 # GREATER-THAN WITH DOT
22D8; 22D9 # VERY MUCH LESS-THAN
22D9; 22D8 # VERY MUCH GREATER-THAN
22DA; 22DB # LESS-THAN EQUAL TO OR GREATER-THAN
22DB; 22DA # GREATER-THAN EQUAL TO OR LESS-THAN
22DC; 22DD # EQUAL TO OR LESS-THAN
22DD; 22DC # EQUAL TO OR GREATER-THAN
22DE; 22DF # EQUAL TO OR PRECEDES
22DF; 22DE # EQUAL TO OR SUCCEEDS
22E0; 22E1 # [BEST FIT] DOES NOT PRECEDE OR EQUAL
22E1; 22E0 # [BEST FIT] DOES NOT SUCCEED OR EQUAL
22E2; 22E3 # [BEST FIT] NOT SQUARE IMAGE OF OR EQUAL TO
22E3; 22E2 # [BEST FIT] NOT SQUARE ORIGINAL OF OR EQUAL TO
22E4; 22E5 # [BEST FIT] SQUARE IMAGE OF OR NOT EQUAL TO
22E5; 22E4 # [BEST FIT] SQUARE ORIGINAL OF OR NOT EQUAL TO
22E6; 22E7 # [BEST FIT] LESS-THAN BUT NOT EQUIVALENT TO
22E7; 22E6 # [BEST FIT] GREATER-THAN BUT NOT EQUIVALENT TO
22E8; 22E9 # [BEST FIT] PRECEDES BUT NOT EQUIVALENT TO
22E9; 22E8 # [BEST FIT] SUCCEEDS BUT NOT EQUIVALENT TO
22EA; 22EB # [BEST FIT] NOT NORMAL SUBGROUP OF
22EB; 22EA # [BEST FIT] DOES NOT CONTAIN AS NORMAL SUBGROUP
22EC; 22ED # [BEST FIT] NOT NORMAL SUBGROUP OF OR EQUAL TO
22ED; 22EC # [BEST FIT] DOES NOT CONTAIN AS NORMAL SUBGROUP OR EQUAL
22F0; 22F1 # UP RIGHT DIAGONAL ELLIPSIS
22F1; 22F0 # DOWN RIGHT DIAGONAL ELLIPSIS
22F2; 22FA # ELEMENT OF WITH LONG HORIZONTAL STROKE
22F3; 22FB # ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE
22F4; 22FC # SMALL ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE
22F6; 22FD # ELEMENT OF WITH OVERBAR
22F7; 22FE # SMALL ELEMENT OF WITH OVERBAR
22FA; 22F2 # CONTAINS WITH LONG HORIZONTAL STROKE
22FB; 22F3 # CONTAINS WITH VERTICAL BAR AT END OF HORIZONTAL STROKE
22FC; 22F4 # SMALL CONTAINS WITH VERTICAL BAR AT END OF HORIZONTAL STROKE
22FD; 22F6 # CONTAINS WITH OVERBAR
22FE; 22F7 # SMALL CONTAINS WITH OVERBAR
2308; 2309 # LEFT CEILING
2309; 2308 # RIGHT CEILING
230A; 230B # LEFT FLOOR
230B; 230A # RIGHT FLOOR
2329; 232A # LEFT-POINTING ANGLE BRACKET
232A; 2329 # RIGHT-POINTING ANGLE BRACKET
2768; 2769 # MEDIUM LEFT PARENTHESIS ORNAMENT
2769; 2768 # MEDIUM RIGHT PARENTHESIS ORNAMENT
276A; 276B # MEDIUM FLATTENED LEFT PARENTHESIS ORNAMENT
276B; 276A # MEDIUM FLATTENED RIGHT PARENTHESIS ORNAMENT
276C; 276D # MEDIUM LEFT-POINTING ANGLE BRACKET ORNAMENT
276D; 276C # MEDIUM RIGHT-POINTING ANGLE BRACKET ORNAMENT
276E; 276F # HEAVY LEFT-POINTING ANGLE QUOTATION MARK ORNAMENT
276F; 276E # HEAVY RIGHT-POINTING ANGLE QUOTATION MARK ORNAMENT
2770; 2771 # HEAVY LEFT-POINTING ANGLE BRACKET ORNAMENT
2771; 2770 # HEAVY RIGHT-POINTING ANGLE BRACKET ORNAMENT
2772; 2773 # LIGHT LEFT TORTOISE SHELL BRACKET
2773; 2772 # LIGHT RIGHT TORTOISE SHELL BRACKET
2774; 2775 # MEDIUM LEFT CURLY BRACKET ORNAMENT
2775; 2774 # MEDIUM RIGHT CURLY BRACKET ORNAMENT
27C3; 27C4 # OPEN SUBSET
27C4; 27C3 # OPEN SUPERSET
27C5; 27C6 # LEFT S-SHAPED BAG DELIMITER
27C6; 27C5 # RIGHT S-SHAPED BAG DELIMITER
27C8; 27C9 # REVERSE SOLIDUS PRECEDING SUBSET
27C9; 27C8 # SUPERSET PRECEDING SOLIDUS
27D5; 27D6 # LEFT OUTER JOIN
27D6; 27D5 # RIGHT OUTER JOIN
27DD; 27DE # LONG RIGHT TACK
27DE; 27DD # LONG LEFT TACK
27E2; 27E3 # WHITE CONCAVE-SIDED DIAMOND WITH LEFTWARDS TICK
27E3; 27E2 # WHITE CONCAVE-SIDED DIAMOND WITH RIGHTWARDS TICK
27E4; 27E5 # WHITE SQUARE WITH LEFTWARDS TICK
27E5; 27E4 # WHITE SQUARE WITH RIGHTWARDS TICK
27E6; 27E7 # MATHEMATICAL LEFT WHITE SQUARE BRACKET
27E7; 27E6 # MATHEMATICAL RIGHT WHITE SQUARE BRACKET
27E8; 27E9 # MATHEMATICAL LEFT ANGLE BRACKET
27E9; 27E8 # MATHEMATICAL RIGHT ANGLE BRACKET
27EA; 27EB # MATHEMATICAL LEFT DOUBLE ANGLE BRACKET
27EB; 27EA # MATHEMATICAL RIGHT DOUBLE ANGLE BRACKET
27EC; 27ED # MATHEMATICAL LEFT WHITE TORTOISE SHELL BRACKET
27ED; 27EC # MATHEMATICAL RIGHT WHITE TORTOISE SHELL BRACKET
27EE; 27EF # MATHEMATICAL LEFT FLATTENED PARENTHESIS
27EF; 27EE # MATHEMATICAL RIGHT FLATTENED PARENTHESIS
2983; 2984 # LEFT WHITE CURLY BRACKET
2984; 2983 # RIGHT WHITE CURLY BRACKET
2985; 2986 # LEFT WHITE PARENTHESIS
2986; 2985 # RIGHT WHITE PARENTHESIS
2987; 2988 # Z NOTATION LEFT IMAGE BRACKET
2988; 2987 # Z NOTATION RIGHT IMAGE BRACKET
2989; 298A # Z NOTATION LEFT BINDING BRACKET
298A; 2989 # Z NOTATION RIGHT BINDING BRACKET
298B; 298C # LEFT SQUARE BRACKET WITH UNDERBAR
298C; 298B # RIGHT SQUARE BRACKET WITH UNDERBAR
298D; 2990 # LEFT SQUARE BRACKET WITH TICK IN TOP CORNER
298E; 298F # RIGHT SQUARE BRACKET WITH TICK IN BOTTOM CORNER
298F; 298E # LEFT SQUARE BRACKET WITH TICK IN BOTTOM CORNER
2990; 298D # RIGHT SQUARE BRACKET WITH TICK IN TOP CORNER
2991; 2992 # LEFT ANGLE BRACKET WITH DOT
2992; 2991 # RIGHT ANGLE BRACKET WITH DOT
2993; 2994 # LEFT ARC LESS-THAN BRACKET
2994; 2993 # RIGHT ARC GREATER-THAN BRACKET
2995; 2996 # DOUBLE LEFT ARC GREATER-THAN BRACKET
2996; 2995 # DOUBLE RIGHT ARC LESS-THAN BRACKET
2997; 2998 # LEFT BLACK TORTOISE SHELL BRACKET
2998; 2997 # RIGHT BLACK TORTOISE SHELL BRACKET
29B8; 2298 # CIRCLED REVERSE SOLIDUS
29C0; 29C1 # CIRCLED LESS-THAN
29C1; 29C0 # CIRCLED GREATER-THAN
29C4; 29C5 # SQUARED RISING DIAGONAL SLASH
29C5; 29C4 # SQUARED FALLING DIAGONAL SLASH
29CF; 29D0 # LEFT TRIANGLE BESIDE VERTICAL BAR
29D0; 29CF # VERTICAL BAR BESIDE RIGHT TRIANGLE
29D1; 29D2 # BOWTIE WITH LEFT HALF BLACK
29D2; 29D1 # BOWTIE WITH RIGHT HALF BLACK
29D4; 29D5 # TIMES WITH LEFT HALF BLACK
29D5; 29D4 # TIMES WITH RIGHT HALF BLACK
29D8; 29D9 # LEFT WIGGLY FENCE
29D9; 29D8 # RIGHT WIGGLY FENCE
29DA; 29DB # LEFT DOUBLE WIGGLY FENCE
29DB; 29DA # RIGHT DOUBLE WIGGLY FENCE
29F5; 2215 # REVERSE SOLIDUS OPERATOR
29F8; 29F9 # BIG SOLIDUS
29F9; 29F8 # BIG REVERSE SOLIDUS
29FC; 29FD # LEFT-POINTING CURVED ANGLE BRACKET
29FD; 29FC # RIGHT-POINTING CURVED ANGLE BRACKET
2A2B; 2A2C # MINUS SIGN WITH FALLING DOTS
2A2C; 2A2B # MINUS SIGN WITH RISING DOTS
2A2D; 2A2E # PLUS SIGN IN LEFT HALF CIRCLE
2A2E; 2A2D # PLUS SIGN IN RIGHT HALF CIRCLE
2A34; 2A35 # MULTIPLICATION SIGN IN LEFT HALF CIRCLE
2A35; 2A34 # MULTIPLICATION SIGN IN RIGHT HALF CIRCLE
2A3C; 2A3D # INTERIOR PRODUCT
2A3D; 2A3C # RIGHTHAND INTERIOR PRODUCT
2A64; 2A65 # Z NOTATION DOMAIN ANTIRESTRICTION
2A65; 2A64 # Z NOTATION RANGE ANTIRESTRICTION
2A79; 2A7A # LESS-THAN WITH CIRCLE INSIDE
2A7A; 2A79 # GREATER-THAN WITH CIRCLE INSIDE
2A7D; 2A7E # LESS-THAN OR SLANTED EQUAL TO
2A7E; 2A7D # GREATER-THAN OR SLANTED EQUAL TO
2A7F; 2A80 # LESS-THAN OR SLANTED EQUAL TO WITH DOT INSIDE
2A80; 2A7F # GREATER-THAN OR SLANTED EQUAL TO WITH DOT INSIDE
2A81; 2A82 # LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE
2A82; 2A81 # GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE
2A83; 2A84 # LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE RIGHT
2A84; 2A83 # GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE LEFT
2A8B; 2A8C # LESS-THAN ABOVE DOUBLE-LINE EQUAL ABOVE GREATER-THAN
2A8C; 2A8B # GREATER-THAN ABOVE DOUBLE-LINE EQUAL ABOVE LESS-THAN
2A91; 2A92 # LESS-THAN ABOVE GREATER-THAN ABOVE DOUBLE-LINE EQUAL
2A92; 2A91 # GREATER-THAN ABOVE LESS-THAN ABOVE DOUBLE-LINE EQUAL
2A93; 2A94 # LESS-THAN ABOVE SLANTED EQUAL ABOVE GREATER-THAN ABOVE SLANTED EQUAL
2A94; 2A93 # GREATER-THAN ABOVE SLANTED EQUAL ABOVE LESS-THAN ABOVE SLANTED EQUAL
2A95; 2A96 # SLANTED EQUAL TO OR LESS-THAN
2A96; 2A95 # SLANTED EQUAL TO OR GREATER-THAN
2A97; 2A98 # SLANTED EQUAL TO OR LESS-THAN WITH DOT INSIDE
2A98; 2A97 # SLANTED EQUAL TO OR GREATER-THAN WITH DOT INSIDE
2A99; 2A9A # DOUBLE-LINE EQUAL TO OR LESS-THAN
2A9A; 2A99 # DOUBLE-LINE EQUAL TO OR GREATER-THAN
2A9B; 2A9C # DOUBLE-LINE SLANTED EQUAL TO OR LESS-THAN
2A9C; 2A9B # DOUBLE-LINE SLANTED EQUAL TO OR GREATER-THAN
2AA1; 2AA2 # DOUBLE NESTED LESS-THAN
2AA2; 2AA1 # DOUBLE NESTED GREATER-THAN
2AA6; 2AA7 # LESS-THAN CLOSED BY CURVE
2AA7; 2AA6 # GREATER-THAN CLOSED BY CURVE
2AA8; 2AA9 # LESS-THAN CLOSED BY CURVE ABOVE SLANTED EQUAL
2AA9; 2AA8 # GREATER-THAN CLOSED BY CURVE ABOVE SLANTED EQUAL
2AAA; 2AAB # SMALLER THAN
2AAB; 2AAA # LARGER THAN
2AAC; 2AAD # SMALLER THAN OR EQUAL TO
2AAD; 2AAC # LARGER THAN OR EQUAL TO
2AAF; 2AB0 # PRECEDES ABOVE SINGLE-LINE EQUALS SIGN
2AB0; 2AAF # SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN
2AB3; 2AB4 # PRECEDES ABOVE EQUALS SIGN
2AB4; 2AB3 # SUCCEEDS ABOVE EQUALS SIGN
2ABB; 2ABC # DOUBLE PRECEDES
2ABC; 2ABB # DOUBLE SUCCEEDS
2ABD; 2ABE # SUBSET WITH DOT
2ABE; 2ABD # SUPERSET WITH DOT
2ABF; 2AC0 # SUBSET WITH PLUS SIGN BELOW
2AC0; 2ABF # SUPERSET WITH PLUS SIGN BELOW
2AC1; 2AC2 # SUBSET WITH MULTIPLICATION SIGN BELOW
2AC2; 2AC1 # SUPERSET WITH MULTIPLICATION SIGN BELOW
2AC3; 2AC4 # SUBSET OF OR EQUAL TO WITH DOT ABOVE
2AC4; 2AC3 # SUPERSET OF OR EQUAL TO WITH DOT ABOVE
2AC5; 2AC6 # SUBSET OF ABOVE EQUALS SIGN
2AC6; 2AC5 # SUPERSET OF ABOVE EQUALS SIGN
2ACD; 2ACE # SQUARE LEFT OPEN BOX OPERATOR
2ACE; 2ACD # SQUARE RIGHT OPEN BOX OPERATOR
2ACF; 2AD0 # CLOSED SUBSET
2AD0; 2ACF # CLOSED SUPERSET
2AD1; 2AD2 # CLOSED SUBSET OR EQUAL TO
2AD2; 2AD1 # CLOSED SUPERSET OR EQUAL TO
2AD3; 2AD4 # SUBSET ABOVE SUPERSET
2AD4; 2AD3 # SUPERSET ABOVE SUBSET
2AD5; 2AD6 # SUBSET ABOVE SUBSET
2AD6; 2AD5 # SUPERSET ABOVE SUPERSET
2ADE; 22A6 # SHORT LEFT TACK
2AE3; 22A9 # DOUBLE VERTICAL BAR LEFT TURNSTILE
2AE4; 22A8 # VERTICAL BAR DOUBLE LEFT TURNSTILE
2AE5; 22AB # DOUBLE VERTICAL BAR DOUBLE LEFT TURNSTILE
2AEC; 2AED # DOUBLE STROKE NOT SIGN
2AED; 2AEC # REVERSED DOUBLE STROKE NOT SIGN
2AF7; 2AF8 # TRIPLE NESTED LESS-THAN
2AF8; 2AF7 # TRIPLE NESTED GREATER-THAN
2AF9; 2AFA # DOUBLE-LINE SLANTED LESS-THAN OR EQUAL TO
2AFA; 2AF9 # DOUBLE-LINE SLANTED GREATER-THAN OR EQUAL TO
2E02; 2E03 # LEFT SUBSTITUTION BRACKET
2E03; 2E02 # RIGHT SUBSTITUTION BRACKET
2E04; 2E05 # LEFT DOTTED SUBSTITUTION BRACKET
2E05; 2E04 # RIGHT DOTTED SUBSTITUTION BRACKET
2E09; 2E0A # LEFT TRANSPOSITION BRACKET
2E0A; 2E09 # RIGHT TRANSPOSITION BRACKET
2E0C; 2E0D # LEFT RAISED OMISSION BRACKET
2E0D; 2E0C # RIGHT RAISED OMISSION BRACKET
2E1C; 2E1D # LEFT LOW PARAPHRASE BRACKET
2E1D; 2E1C # RIGHT LOW PARAPHRASE BRACKET
2E20; 2E21 # LEFT VERTICAL BAR WITH QUILL
2E21; 2E20 # RIGHT VERTICAL BAR WITH QUILL
2E22; 2E23 # TOP LEFT HALF BRACKET
2E23; 2E22 # TOP RIGHT HALF BRACKET
2E24; 2E25 # BOTTOM LEFT HALF BRACKET
2E25; 2E24 # BOTTOM RIGHT HALF BRACKET
2E26; 2E27 # LEFT SIDEWAYS U BRACKET
2E27; 2E26 # RIGHT SIDEWAYS U BRACKET
2E28; 2E29 # LEFT DOUBLE PARENTHESIS
2E29; 2E28 # RIGHT DOUBLE PARENTHESIS
3008; 3009 # LEFT ANGLE BRACKET
3009; 3008 # RIGHT ANGLE BRACKET
300A; 300B # LEFT DOUBLE ANGLE BRACKET
300B; 300A # RIGHT DOUBLE ANGLE BRACKET
300C; 300D # [BEST FIT] LEFT CORNER BRACKET
300D; 300C # [BEST FIT] RIGHT CORNER BRACKET
300E; 300F # [BEST FIT] LEFT WHITE CORNER BRACKET
300F; 300E # [BEST FIT] RIGHT WHITE CORNER BRACKET
3010; 3011 # LEFT BLACK LENTICULAR BRACKET
3011; 3010 # RIGHT BLACK LENTICULAR BRACKET
3014; 3015 # LEFT TORTOISE SHELL BRACKET
3015; 3014 # RIGHT TORTOISE SHELL BRACKET
3016; 3017 # LEFT WHITE LENTICULAR BRACKET
3017; 3016 # RIGHT WHITE LENTICULAR BRACKET
3018; 3019 # LEFT WHITE TORTOISE SHELL BRACKET
3019; 3018 # RIGHT WHITE TORTOISE SHELL BRACKET
301A; 301B # LEFT WHITE SQUARE BRACKET
301B; 301A # RIGHT WHITE SQUARE BRACKET
FE59; FE5A # SMALL LEFT PARENTHESIS
FE5A; FE59 # SMALL RIGHT PARENTHESIS
FE5B; FE5C # SMALL LEFT CURLY BRACKET
FE5C; FE5B # SMALL RIGHT CURLY BRACKET
FE5D; FE5E # SMALL LEFT TORTOISE SHELL BRACKET
FE5E; FE5D # SMALL RIGHT TORTOISE SHELL BRACKET
FE64; FE65 # SMALL LESS-THAN SIGN
FE65; FE64 # SMALL GREATER-THAN SIGN
FF08; FF09 # FULLWIDTH LEFT PARENTHESIS
FF09; FF08 # FULLWIDTH RIGHT PARENTHESIS
FF1C; FF1E # FULLWIDTH LESS-THAN SIGN
FF1E; FF1C # FULLWIDTH GREATER-THAN SIGN
FF3B; FF3D # FULLWIDTH LEFT SQUARE BRACKET
FF3D; FF3B # FULLWIDTH RIGHT SQUARE BRACKET
FF5B; FF5D # FULLWIDTH LEFT CURLY BRACKET
FF5D; FF5B # FULLWIDTH RIGHT CURLY BRACKET
FF5F; FF60 # FULLWIDTH LEFT WHITE PARENTHESIS
FF60; FF5F # FULLWIDTH RIGHT WHITE PARENTHESIS
FF62; FF63 # [BEST FIT] HALFWIDTH LEFT CORNER BRACKET
FF63; FF62 # [BEST FIT] HALFWIDTH RIGHT CORNER BRACKET
# The following characters have no appropriate mirroring character.
# For these characters it is up to the rendering system
# to provide mirrored glyphs.
# 2140; DOUBLE-STRUCK N-ARY SUMMATION
# 2201; COMPLEMENT
# 2202; PARTIAL DIFFERENTIAL
# 2203; THERE EXISTS
# 2204; THERE DOES NOT EXIST
# 2211; N-ARY SUMMATION
# 2216; SET MINUS
# 221A; SQUARE ROOT
# 221B; CUBE ROOT
# 221C; FOURTH ROOT
# 221D; PROPORTIONAL TO
# 221F; RIGHT ANGLE
# 2220; ANGLE
# 2221; MEASURED ANGLE
# 2222; SPHERICAL ANGLE
# 2224; DOES NOT DIVIDE
# 2226; NOT PARALLEL TO
# 222B; INTEGRAL
# 222C; DOUBLE INTEGRAL
# 222D; TRIPLE INTEGRAL
# 222E; CONTOUR INTEGRAL
# 222F; SURFACE INTEGRAL
# 2230; VOLUME INTEGRAL
# 2231; CLOCKWISE INTEGRAL
# 2232; CLOCKWISE CONTOUR INTEGRAL
# 2233; ANTICLOCKWISE CONTOUR INTEGRAL
# 2239; EXCESS
# 223B; HOMOTHETIC
# 223E; INVERTED LAZY S
# 223F; SINE WAVE
# 2240; WREATH PRODUCT
# 2241; NOT TILDE
# 2242; MINUS TILDE
# 2244; NOT ASYMPTOTICALLY EQUAL TO
# 2245; APPROXIMATELY EQUAL TO
# 2246; APPROXIMATELY BUT NOT ACTUALLY EQUAL TO
# 2247; NEITHER APPROXIMATELY NOR ACTUALLY EQUAL TO
# 2248; ALMOST EQUAL TO
# 2249; NOT ALMOST EQUAL TO
# 224A; ALMOST EQUAL OR EQUAL TO
# 224B; TRIPLE TILDE
# 224C; ALL EQUAL TO
# 225F; QUESTIONED EQUAL TO
# 2260; NOT EQUAL TO
# 2262; NOT IDENTICAL TO
# 228C; MULTISET
# 22A7; MODELS
# 22AA; TRIPLE VERTICAL BAR RIGHT TURNSTILE
# 22AC; DOES NOT PROVE
# 22AD; NOT TRUE
# 22AE; DOES NOT FORCE
# 22AF; NEGATED DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE
# 22B8; MULTIMAP
# 22BE; RIGHT ANGLE WITH ARC
# 22BF; RIGHT TRIANGLE
# 22F5; ELEMENT OF WITH DOT ABOVE
# 22F8; ELEMENT OF WITH UNDERBAR
# 22F9; ELEMENT OF WITH TWO HORIZONTAL STROKES
# 22FF; Z NOTATION BAG MEMBERSHIP
# 2320; TOP HALF INTEGRAL
# 2321; BOTTOM HALF INTEGRAL
# 27CC; LONG DIVISION
# 27C0; THREE DIMENSIONAL ANGLE
# 27D3; LOWER RIGHT CORNER WITH DOT
# 27D4; UPPER LEFT CORNER WITH DOT
# 27DC; LEFT MULTIMAP
# 299B; MEASURED ANGLE OPENING LEFT
# 299C; RIGHT ANGLE VARIANT WITH SQUARE
# 299D; MEASURED RIGHT ANGLE WITH DOT
# 299E; ANGLE WITH S INSIDE
# 299F; ACUTE ANGLE
# 29A0; SPHERICAL ANGLE OPENING LEFT
# 29A1; SPHERICAL ANGLE OPENING UP
# 29A2; TURNED ANGLE
# 29A3; REVERSED ANGLE
# 29A4; ANGLE WITH UNDERBAR
# 29A5; REVERSED ANGLE WITH UNDERBAR
# 29A6; OBLIQUE ANGLE OPENING UP
# 29A7; OBLIQUE ANGLE OPENING DOWN
# 29A8; MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING UP AND RIGHT
# 29A9; MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING UP AND LEFT
# 29AA; MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING DOWN AND RIGHT
# 29AB; MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING DOWN AND LEFT
# 29AC; MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING RIGHT AND UP
# 29AD; MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING LEFT AND UP
# 29AE; MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING RIGHT AND DOWN
# 29AF; MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING LEFT AND DOWN
# 29C2; CIRCLE WITH SMALL CIRCLE TO THE RIGHT
# 29C3; CIRCLE WITH TWO HORIZONTAL STROKES TO THE RIGHT
# 29C9; TWO JOINED SQUARES
# 29CE; RIGHT TRIANGLE ABOVE LEFT TRIANGLE
# 29DC; INCOMPLETE INFINITY
# 29E1; INCREASES AS
# 29E3; EQUALS SIGN AND SLANTED PARALLEL
# 29E4; EQUALS SIGN AND SLANTED PARALLEL WITH TILDE ABOVE
# 29E5; IDENTICAL TO AND SLANTED PARALLEL
# 29E8; DOWN-POINTING TRIANGLE WITH LEFT HALF BLACK
# 29E9; DOWN-POINTING TRIANGLE WITH RIGHT HALF BLACK
# 29F4; RULE-DELAYED
# 29F6; SOLIDUS WITH OVERBAR
# 29F7; REVERSE SOLIDUS WITH HORIZONTAL STROKE
# 2A0A; MODULO TWO SUM
# 2A0B; SUMMATION WITH INTEGRAL
# 2A0C; QUADRUPLE INTEGRAL OPERATOR
# 2A0D; FINITE PART INTEGRAL
# 2A0E; INTEGRAL WITH DOUBLE STROKE
# 2A0F; INTEGRAL AVERAGE WITH SLASH
# 2A10; CIRCULATION FUNCTION
# 2A11; ANTICLOCKWISE INTEGRATION
# 2A12; LINE INTEGRATION WITH RECTANGULAR PATH AROUND POLE
# 2A13; LINE INTEGRATION WITH SEMICIRCULAR PATH AROUND POLE
# 2A14; LINE INTEGRATION NOT INCLUDING THE POLE
# 2A15; INTEGRAL AROUND A POINT OPERATOR
# 2A16; QUATERNION INTEGRAL OPERATOR
# 2A17; INTEGRAL WITH LEFTWARDS ARROW WITH HOOK
# 2A18; INTEGRAL WITH TIMES SIGN
# 2A19; INTEGRAL WITH INTERSECTION
# 2A1A; INTEGRAL WITH UNION
# 2A1B; INTEGRAL WITH OVERBAR
# 2A1C; INTEGRAL WITH UNDERBAR
# 2A1E; LARGE LEFT TRIANGLE OPERATOR
# 2A1F; Z NOTATION SCHEMA COMPOSITION
# 2A20; Z NOTATION SCHEMA PIPING
# 2A21; Z NOTATION SCHEMA PROJECTION
# 2A24; PLUS SIGN WITH TILDE ABOVE
# 2A26; PLUS SIGN WITH TILDE BELOW
# 2A29; MINUS SIGN WITH COMMA ABOVE
# 2A3E; Z NOTATION RELATIONAL COMPOSITION
# 2A57; SLOPING LARGE OR
# 2A58; SLOPING LARGE AND
# 2A6A; TILDE OPERATOR WITH DOT ABOVE
# 2A6B; TILDE OPERATOR WITH RISING DOTS
# 2A6C; SIMILAR MINUS SIMILAR
# 2A6D; CONGRUENT WITH DOT ABOVE
# 2A6F; ALMOST EQUAL TO WITH CIRCUMFLEX ACCENT
# 2A70; APPROXIMATELY EQUAL OR EQUAL TO
# 2A73; EQUALS SIGN ABOVE TILDE OPERATOR
# 2A74; DOUBLE COLON EQUAL
# 2A7B; LESS-THAN WITH QUESTION MARK ABOVE
# 2A7C; GREATER-THAN WITH QUESTION MARK ABOVE
# 2A85; LESS-THAN OR APPROXIMATE
# 2A86; GREATER-THAN OR APPROXIMATE
# 2A87; LESS-THAN AND SINGLE-LINE NOT EQUAL TO
# 2A88; GREATER-THAN AND SINGLE-LINE NOT EQUAL TO
# 2A89; LESS-THAN AND NOT APPROXIMATE
# 2A8A; GREATER-THAN AND NOT APPROXIMATE
# 2A8D; LESS-THAN ABOVE SIMILAR OR EQUAL
# 2A8E; GREATER-THAN ABOVE SIMILAR OR EQUAL
# 2A8F; LESS-THAN ABOVE SIMILAR ABOVE GREATER-THAN
# 2A90; GREATER-THAN ABOVE SIMILAR ABOVE LESS-THAN
# 2A9D; SIMILAR OR LESS-THAN
# 2A9E; SIMILAR OR GREATER-THAN
# 2A9F; SIMILAR ABOVE LESS-THAN ABOVE EQUALS SIGN
# 2AA0; SIMILAR ABOVE GREATER-THAN ABOVE EQUALS SIGN
# 2AA3; DOUBLE NESTED LESS-THAN WITH UNDERBAR
# 2AB1; PRECEDES ABOVE SINGLE-LINE NOT EQUAL TO
# 2AB2; SUCCEEDS ABOVE SINGLE-LINE NOT EQUAL TO
# 2AB5; PRECEDES ABOVE NOT EQUAL TO
# 2AB6; SUCCEEDS ABOVE NOT EQUAL TO
# 2AB7; PRECEDES ABOVE ALMOST EQUAL TO
# 2AB8; SUCCEEDS ABOVE ALMOST EQUAL TO
# 2AB9; PRECEDES ABOVE NOT ALMOST EQUAL TO
# 2ABA; SUCCEEDS ABOVE NOT ALMOST EQUAL TO
# 2AC7; SUBSET OF ABOVE TILDE OPERATOR
# 2AC8; SUPERSET OF ABOVE TILDE OPERATOR
# 2AC9; SUBSET OF ABOVE ALMOST EQUAL TO
# 2ACA; SUPERSET OF ABOVE ALMOST EQUAL TO
# 2ACB; SUBSET OF ABOVE NOT EQUAL TO
# 2ACC; SUPERSET OF ABOVE NOT EQUAL TO
# 2ADC; FORKING
# 2AE2; VERTICAL BAR TRIPLE RIGHT TURNSTILE
# 2AE6; LONG DASH FROM LEFT MEMBER OF DOUBLE VERTICAL
# 2AEE; DOES NOT DIVIDE WITH REVERSED NEGATION SLASH
# 2AF3; PARALLEL WITH TILDE OPERATOR
# 2AFB; TRIPLE SOLIDUS BINARY RELATION
# 2AFD; DOUBLE SOLIDUS OPERATOR
# 1D6DB; MATHEMATICAL BOLD PARTIAL DIFFERENTIAL
# 1D715; MATHEMATICAL ITALIC PARTIAL DIFFERENTIAL
# 1D74F; MATHEMATICAL BOLD ITALIC PARTIAL DIFFERENTIAL
# 1D789; MATHEMATICAL SANS-SERIF BOLD PARTIAL DIFFERENTIAL
# 1D7C3; MATHEMATICAL SANS-SERIF BOLD ITALIC PARTIAL DIFFERENTIAL
# EOF

9
unicode/COPYING Normal file
View File

@ -0,0 +1,9 @@
COPYRIGHT AND PERMISSION NOTICE
Copyright © 1991-2009 Unicode, Inc. All rights reserved. Distributed under the Terms of Use in http://www.unicode.org/copyright.html.
Permission is hereby granted, free of charge, to any person obtaining a copy of the Unicode data files and any associated documentation (the "Data Files") or Unicode software and any associated documentation (the "Software") to deal in the Data Files or Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, and/or sell copies of the Data Files or Software, and to permit persons to whom the Data Files or Software are furnished to do so, provided that (a) the above copyright notice(s) and this permission notice appear with all copies of the Data Files or Software, (b) both the above copyright notice(s) and this permission notice appear in associated documentation, and (c) there is clear notice in each modified Data File or in the Software as well as in the documentation associated with the Data File(s) or Software that the data or software has been modified.
THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES OR SOFTWARE.
Except as contained in this notice, the name of a copyright holder shall not be used in advertising or otherwise to promote the sale, use or other dealings in these Data Files or Software without prior written authorization of the copyright holder.

21829
unicode/UnicodeData.txt Normal file

File diff suppressed because it is too large Load Diff

View File

@ -33,12 +33,6 @@
#define DEFAULT_ENVBLK_SIZE 1024
void
grub_putchar (int c)
{
putchar (c);
}
void
grub_refresh (void)
{
@ -51,6 +45,14 @@ grub_getkey (void)
return 0;
}
void
grub_xputs_real (const char *str)
{
fputs (str, stdout);
}
void (*grub_xputs) (const char *str) = grub_xputs_real;
char *
grub_env_get (const char *name __attribute__ ((unused)))
{

View File

@ -43,12 +43,14 @@
#include "progname.h"
void
grub_putchar (int c)
void
grub_xputs_real (const char *str)
{
putchar (c);
fputs (str, stdout);
}
void (*grub_xputs) (const char *str) = grub_xputs_real;
int
grub_getkey (void)
{

View File

@ -39,12 +39,14 @@
#include "progname.h"
void
grub_putchar (int c)
void
grub_xputs_real (const char *str)
{
putchar (c);
fputs (str, stdout);
}
void (*grub_xputs) (const char *str) = grub_xputs_real;
int
grub_getkey (void)
{

View File

@ -19,8 +19,11 @@
#include <config.h>
#include <grub/types.h>
#include <grub/util/misc.h>
#include <grub/misc.h>
#include <grub/i18n.h>
#include <grub/fontformat.h>
#include <grub/font.h>
#include <grub/unicode.h>
#include <stdio.h>
#include <stdlib.h>
@ -29,8 +32,16 @@
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_TRUETYPE_TAGS_H
#include FT_TRUETYPE_TABLES_H
#include <freetype/ftsynth.h>
#undef __FTERRORS_H__
#define FT_ERROR_START_LIST const char *ft_errmsgs[] = {
#define FT_ERRORDEF(e, v, s) [e] = s,
#define FT_ERROR_END_LIST };
#include FT_ERRORS_H
#include "progname.h"
#define GRUB_FONT_DEFAULT_SIZE 16
@ -47,13 +58,14 @@ struct grub_glyph_info
int y_ofs;
int device_width;
int bitmap_size;
grub_uint8_t bitmap[0];
grub_uint8_t *bitmap;
};
enum file_formats
{
PF2,
ASCII_BITMAPS
ASCII_BITMAPS,
WIDTH_SPEC
};
#define GRUB_FONT_FLAG_BOLD 1
@ -75,7 +87,9 @@ struct grub_font_info
int flags;
int num_range;
grub_uint32_t *ranges;
struct grub_glyph_info *glyph;
struct grub_glyph_info *glyphs_unsorted;
struct grub_glyph_info *glyphs_sorted;
int num_glyphs;
};
static struct option options[] =
@ -95,6 +109,7 @@ static struct option options[] =
{"version", no_argument, 0, 'V'},
{"verbose", no_argument, 0, 'v'},
{"ascii-bitmaps", no_argument, 0, 0x102},
{"width-spec", no_argument, 0, 0x103},
{0, 0, 0, 0}
};
@ -111,6 +126,7 @@ Usage: %s [OPTIONS] FONT_FILES\n\
\nOptions:\n\
-o, --output=FILE_NAME set output file name\n\
--ascii-bitmaps save only the ASCII bitmaps\n\
--width-spec create width summary file\n\
-i, --index=N set face index\n\
-r, --range=A-B[,C-D] set font range\n\
-n, --name=S set font family name\n\
@ -146,16 +162,18 @@ add_pixel (grub_uint8_t **data, int *mask, int not_blank)
*mask >>= 1;
}
void
add_char (struct grub_font_info *font_info, FT_Face face,
grub_uint32_t char_code)
static void
add_glyph (struct grub_font_info *font_info, FT_UInt glyph_idx, FT_Face face,
grub_uint32_t char_code, int nocut)
{
struct grub_glyph_info *glyph_info, **p_glyph;
struct grub_glyph_info *glyph_info;
int width, height;
int cuttop, cutbottom, cutleft, cutright;
grub_uint8_t *data;
int mask, i, j, bitmap_size;
FT_GlyphSlot glyph;
int flag = FT_LOAD_RENDER | FT_LOAD_MONOCHROME;
FT_Error err;
if (font_info->flags & GRUB_FONT_FLAG_NOBITMAP)
flag |= FT_LOAD_NO_BITMAP;
@ -165,39 +183,99 @@ add_char (struct grub_font_info *font_info, FT_Face face,
else if (font_info->flags & GRUB_FONT_FLAG_FORCEHINT)
flag |= FT_LOAD_FORCE_AUTOHINT;
if (FT_Load_Char (face, char_code, flag))
return;
err = FT_Load_Glyph (face, glyph_idx, flag);
if (err)
{
printf ("Freetype Error %d loading glyph 0x%x for U+0x%x%s",
err, glyph_idx, char_code & GRUB_FONT_CODE_CHAR_MASK,
char_code & GRUB_FONT_CODE_RIGHT_JOINED
? ((char_code & GRUB_FONT_CODE_LEFT_JOINED) ? " (medial)":
" (leftmost)")
: ((char_code & GRUB_FONT_CODE_LEFT_JOINED) ? " (rightmost)":
""));
if (err > 0 && err < (signed) ARRAY_SIZE (ft_errmsgs))
printf (": %s\n", ft_errmsgs[err]);
else
printf ("\n");
return;
}
glyph = face->glyph;
if (font_info->flags & GRUB_FONT_FLAG_BOLD)
FT_GlyphSlot_Embolden (glyph);
p_glyph = &font_info->glyph;
while ((*p_glyph) && ((*p_glyph)->char_code > char_code))
if (glyph->next)
printf ("%x\n", char_code);
if (nocut)
cuttop = cutbottom = cutleft = cutright = 0;
else
{
p_glyph = &(*p_glyph)->next;
for (cuttop = 0; cuttop < glyph->bitmap.rows; cuttop++)
{
for (j = 0; j < glyph->bitmap.width; j++)
if (glyph->bitmap.buffer[j / 8 + cuttop * glyph->bitmap.pitch]
& (1 << (7 - (j & 7))))
break;
if (j != glyph->bitmap.width)
break;
}
for (cutbottom = glyph->bitmap.rows - 1; cutbottom >= 0; cutbottom--)
{
for (j = 0; j < glyph->bitmap.width; j++)
if (glyph->bitmap.buffer[j / 8 + cutbottom * glyph->bitmap.pitch]
& (1 << (7 - (j & 7))))
break;
if (j != glyph->bitmap.width)
break;
}
cutbottom = glyph->bitmap.rows - 1 - cutbottom;
if (cutbottom + cuttop >= glyph->bitmap.rows)
cutbottom = 0;
for (cutleft = 0; cutleft < glyph->bitmap.width; cutleft++)
{
for (j = 0; j < glyph->bitmap.rows; j++)
if (glyph->bitmap.buffer[cutleft / 8 + j * glyph->bitmap.pitch]
& (1 << (7 - (cutleft & 7))))
break;
if (j != glyph->bitmap.rows)
break;
}
for (cutright = glyph->bitmap.width - 1; cutright >= 0; cutright--)
{
for (j = 0; j < glyph->bitmap.rows; j++)
if (glyph->bitmap.buffer[cutright / 8 + j * glyph->bitmap.pitch]
& (1 << (7 - (cutright & 7))))
break;
if (j != glyph->bitmap.rows)
break;
}
cutright = glyph->bitmap.width - 1 - cutright;
if (cutright + cutleft >= glyph->bitmap.width)
cutright = 0;
}
/* Ignore duplicated glyph. */
if ((*p_glyph) && ((*p_glyph)->char_code == char_code))
return;
width = glyph->bitmap.width;
height = glyph->bitmap.rows;
width = glyph->bitmap.width - cutleft - cutright;
height = glyph->bitmap.rows - cutbottom - cuttop;
bitmap_size = ((width * height + 7) / 8);
glyph_info = xmalloc (sizeof (struct grub_glyph_info) + bitmap_size);
glyph_info = xmalloc (sizeof (struct grub_glyph_info));
glyph_info->bitmap = xmalloc (bitmap_size);
glyph_info->bitmap_size = bitmap_size;
glyph_info->next = *p_glyph;
*p_glyph = glyph_info;
glyph_info->next = font_info->glyphs_unsorted;
font_info->glyphs_unsorted = glyph_info;
font_info->num_glyphs++;
glyph_info->char_code = char_code;
glyph_info->width = width;
glyph_info->height = height;
glyph_info->x_ofs = glyph->bitmap_left;
glyph_info->y_ofs = glyph->bitmap_top - height;
glyph_info->x_ofs = glyph->bitmap_left + cutleft;
glyph_info->y_ofs = glyph->bitmap_top - height - cuttop;
glyph_info->device_width = glyph->metrics.horiAdvance / 64;
if (width > font_info->max_width)
@ -214,16 +292,388 @@ add_char (struct grub_font_info *font_info, FT_Face face,
mask = 0;
data = &glyph_info->bitmap[0] - 1;
for (j = 0; j < height; j++)
for (i = 0; i < width; i++)
for (j = cuttop; j < height + cuttop; j++)
for (i = cutleft; i < width + cutleft; i++)
add_pixel (&data, &mask,
glyph->bitmap.buffer[i / 8 + j * glyph->bitmap.pitch] &
(1 << (7 - (i & 7))));
}
void
add_font (struct grub_font_info *font_info, FT_Face face)
struct glyph_replace *subst_rightjoin, *subst_leftjoin, *subst_medijoin;
struct glyph_replace
{
struct glyph_replace *next;
grub_uint32_t from, to;
};
/* TODO: sort glyph_replace and use binary search if necessary. */
static void
add_char (struct grub_font_info *font_info, FT_Face face,
grub_uint32_t char_code, int nocut)
{
FT_UInt glyph_idx;
struct glyph_replace *cur;
glyph_idx = FT_Get_Char_Index (face, char_code);
if (!glyph_idx)
return;
add_glyph (font_info, glyph_idx, face, char_code, nocut);
for (cur = subst_rightjoin; cur; cur = cur->next)
if (cur->from == glyph_idx)
{
add_glyph (font_info, cur->to, face,
char_code | GRUB_FONT_CODE_RIGHT_JOINED, nocut);
break;
}
if (!cur && char_code >= GRUB_UNICODE_ARABIC_START
&& char_code < GRUB_UNICODE_ARABIC_END)
{
int i;
for (i = 0; grub_unicode_arabic_shapes[i].code; i++)
if (grub_unicode_arabic_shapes[i].code == char_code
&& grub_unicode_arabic_shapes[i].right_linked)
{
FT_UInt idx2;
idx2 = FT_Get_Char_Index (face, grub_unicode_arabic_shapes[i]
.right_linked);
if (idx2)
add_glyph (font_info, idx2, face,
char_code | GRUB_FONT_CODE_RIGHT_JOINED, nocut);
break;
}
}
for (cur = subst_leftjoin; cur; cur = cur->next)
if (cur->from == glyph_idx)
{
add_glyph (font_info, cur->to, face,
char_code | GRUB_FONT_CODE_LEFT_JOINED, nocut);
break;
}
if (!cur && char_code >= GRUB_UNICODE_ARABIC_START
&& char_code < GRUB_UNICODE_ARABIC_END)
{
int i;
for (i = 0; grub_unicode_arabic_shapes[i].code; i++)
if (grub_unicode_arabic_shapes[i].code == char_code
&& grub_unicode_arabic_shapes[i].left_linked)
{
FT_UInt idx2;
idx2 = FT_Get_Char_Index (face, grub_unicode_arabic_shapes[i]
.left_linked);
if (idx2)
add_glyph (font_info, idx2, face,
char_code | GRUB_FONT_CODE_LEFT_JOINED, nocut);
break;
}
}
for (cur = subst_medijoin; cur; cur = cur->next)
if (cur->from == glyph_idx)
{
add_glyph (font_info, cur->to, face,
char_code | GRUB_FONT_CODE_LEFT_JOINED
| GRUB_FONT_CODE_RIGHT_JOINED, nocut);
break;
}
if (!cur && char_code >= GRUB_UNICODE_ARABIC_START
&& char_code < GRUB_UNICODE_ARABIC_END)
{
int i;
for (i = 0; grub_unicode_arabic_shapes[i].code; i++)
if (grub_unicode_arabic_shapes[i].code == char_code
&& grub_unicode_arabic_shapes[i].both_linked)
{
FT_UInt idx2;
idx2 = FT_Get_Char_Index (face, grub_unicode_arabic_shapes[i]
.both_linked);
if (idx2)
add_glyph (font_info, idx2, face,
char_code | GRUB_FONT_CODE_LEFT_JOINED
| GRUB_FONT_CODE_RIGHT_JOINED, nocut);
break;
}
}
}
struct gsub_header
{
grub_uint32_t version;
grub_uint16_t scripts_off;
grub_uint16_t features_off;
grub_uint16_t lookups_off;
} __attribute__ ((packed));
struct gsub_features
{
grub_uint16_t count;
struct
{
#define FEATURE_FINA 0x66696e61
#define FEATURE_INIT 0x696e6974
#define FEATURE_MEDI 0x6d656469
#define FEATURE_AALT 0x61616c74
#define FEATURE_LIGA 0x6c696761
#define FEATURE_RLIG 0x726c6967
grub_uint32_t feature_tag;
grub_uint16_t offset;
} __attribute__ ((packed)) features[0];
} __attribute__ ((packed));
struct gsub_feature
{
grub_uint16_t params;
grub_uint16_t lookupcount;
grub_uint16_t lookupindices[0];
} __attribute__ ((packed));
struct gsub_lookup_list
{
grub_uint16_t count;
grub_uint16_t offsets[0];
} __attribute__ ((packed));
struct gsub_lookup
{
grub_uint16_t type;
grub_uint16_t flag;
grub_uint16_t subtablecount;
grub_uint16_t subtables[0];
} __attribute__ ((packed));
struct gsub_substitution
{
grub_uint16_t type;
grub_uint16_t coverage_off;
union
{
grub_int16_t delta;
struct
{
grub_int16_t count;
grub_uint16_t repl[0];
};
};
} __attribute__ ((packed));
struct gsub_coverage_list
{
grub_uint16_t type;
grub_uint16_t count;
grub_uint16_t glyphs[0];
} __attribute__ ((packed));
struct gsub_coverage_ranges
{
grub_uint16_t type;
grub_uint16_t count;
struct
{
grub_uint16_t start;
grub_uint16_t end;
grub_uint16_t start_index;
} __attribute__ ((packed)) ranges[0];
} __attribute__ ((packed));
#define GSUB_SINGLE_SUBSTITUTION 1
#define GSUB_SUBSTITUTION_DELTA 1
#define GSUB_SUBSTITUTION_MAP 2
#define GSUB_COVERAGE_LIST 1
#define GSUB_COVERAGE_RANGE 2
#define GSUB_RTL_CHAR 1
static void
add_subst (grub_uint32_t from, grub_uint32_t to, struct glyph_replace **target)
{
struct glyph_replace *new = xmalloc (sizeof (*new));
new->next = *target;
new->from = from;
new->to = to;
*target = new;
}
static void
process_cursive (struct gsub_feature *feature,
struct gsub_lookup_list *lookups,
grub_uint32_t feattag)
{
int j, k;
int i;
struct glyph_replace **target;
struct gsub_substitution *sub;
auto inline void subst (grub_uint32_t glyph);
void subst (grub_uint32_t glyph)
{
grub_uint16_t substtype;
substtype = grub_be_to_cpu16 (sub->type);
if (substtype == GSUB_SUBSTITUTION_DELTA)
add_subst (glyph, glyph + grub_be_to_cpu16 (sub->delta), target);
else if (i >= grub_be_to_cpu16 (sub->count))
printf ("Out of range substitution (%d, %d)\n", i,
grub_be_to_cpu16 (sub->count));
else
add_subst (glyph, grub_be_to_cpu16 (sub->repl[i++]), target);
}
for (j = 0; j < grub_be_to_cpu16 (feature->lookupcount); j++)
{
int lookup_index = grub_be_to_cpu16 (feature->lookupindices[j]);
struct gsub_lookup *lookup;
if (lookup_index >= grub_be_to_cpu16 (lookups->count))
{
printf ("Out of range lookup: %d\n", lookup_index);
continue;
}
lookup = (struct gsub_lookup *)
((grub_uint8_t *) lookups
+ grub_be_to_cpu16 (lookups->offsets[lookup_index]));
if (grub_be_to_cpu16 (lookup->type) != GSUB_SINGLE_SUBSTITUTION)
{
printf ("Unsupported substitution type: %d\n",
grub_be_to_cpu16 (lookup->type));
continue;
}
if (grub_be_to_cpu16 (lookup->flag) & ~GSUB_RTL_CHAR)
{
printf ("Unsupported substitution flag: 0x%x\n",
grub_be_to_cpu16 (lookup->flag));
}
switch (feattag)
{
case FEATURE_INIT:
if (grub_be_to_cpu16 (lookup->flag) & GSUB_RTL_CHAR)
target = &subst_leftjoin;
else
target = &subst_rightjoin;
break;
case FEATURE_FINA:
if (grub_be_to_cpu16 (lookup->flag) & GSUB_RTL_CHAR)
target = &subst_rightjoin;
else
target = &subst_leftjoin;
break;
case FEATURE_MEDI:
target = &subst_medijoin;
break;
}
for (k = 0; k < grub_be_to_cpu16 (lookup->subtablecount); k++)
{
sub = (struct gsub_substitution *)
((grub_uint8_t *) lookup + grub_be_to_cpu16 (lookup->subtables[k]));
grub_uint16_t substtype;
substtype = grub_be_to_cpu16 (sub->type);
if (substtype != GSUB_SUBSTITUTION_MAP
&& substtype != GSUB_SUBSTITUTION_DELTA)
{
printf ("Unsupported substitution specification: %d\n",
substtype);
continue;
}
void *coverage = (grub_uint8_t *) sub
+ grub_be_to_cpu16 (sub->coverage_off);
grub_uint32_t covertype;
covertype = grub_be_to_cpu16 (*(grub_uint16_t * __attribute__ ((packed))) coverage);
i = 0;
if (covertype == GSUB_COVERAGE_LIST)
{
struct gsub_coverage_list *cover = coverage;
int l;
for (l = 0; l < grub_be_to_cpu16 (cover->count); l++)
subst (grub_be_to_cpu16 (cover->glyphs[l]));
}
else if (covertype == GSUB_COVERAGE_RANGE)
{
struct gsub_coverage_ranges *cover = coverage;
int l, m;
for (l = 0; l < grub_be_to_cpu16 (cover->count); l++)
for (m = grub_be_to_cpu16 (cover->ranges[l].start);
m <= grub_be_to_cpu16 (cover->ranges[l].end); m++)
subst (m);
}
else
printf ("Unsupported coverage specification: %d\n", covertype);
}
}
}
void
add_font (struct grub_font_info *font_info, FT_Face face, int nocut)
{
struct gsub_header *gsub = NULL;
FT_ULong gsub_len = 0;
if (!FT_Load_Sfnt_Table (face, TTAG_GSUB, 0, NULL, &gsub_len))
{
gsub = xmalloc (gsub_len);
if (FT_Load_Sfnt_Table (face, TTAG_GSUB, 0, (void *) gsub, &gsub_len))
{
free (gsub);
gsub = NULL;
gsub_len = 0;
}
}
if (gsub)
{
struct gsub_features *features
= (struct gsub_features *) (((grub_uint8_t *) gsub)
+ grub_be_to_cpu16 (gsub->features_off));
struct gsub_lookup_list *lookups
= (struct gsub_lookup_list *) (((grub_uint8_t *) gsub)
+ grub_be_to_cpu16 (gsub->lookups_off));
int i;
int nfeatures = grub_be_to_cpu16 (features->count);
for (i = 0; i < nfeatures; i++)
{
struct gsub_feature *feature = (struct gsub_feature *)
((grub_uint8_t *) features
+ grub_be_to_cpu16 (features->features[i].offset));
grub_uint32_t feattag
= grub_be_to_cpu32 (features->features[i].feature_tag);
if (feature->params)
printf ("WARNING: unsupported feature parameters: %x\n",
grub_be_to_cpu16 (feature->params));
switch (feattag)
{
/* Used for retrieving all possible variants. Useless in grub. */
case FEATURE_AALT:
break;
/* FIXME: Add ligature support. */
case FEATURE_LIGA:
case FEATURE_RLIG:
break;
/* Cursive form variants. */
case FEATURE_FINA:
case FEATURE_INIT:
case FEATURE_MEDI:
process_cursive (feature, lookups, feattag);
break;
default:
{
char str[5];
int j;
memcpy (str, &features->features[i].feature_tag,
sizeof (features->features[i].feature_tag));
str[4] = 0;
for (j = 0; j < 4; j++)
if (!grub_isgraph (str[j]))
str[j] = '?';
printf ("Unknown gsub feature 0x%x (%s)\n", feattag, str);
}
}
}
}
if (font_info->num_range)
{
int i;
@ -232,7 +682,7 @@ add_font (struct grub_font_info *font_info, FT_Face face)
for (i = 0; i < font_info->num_range; i++)
for (j = font_info->ranges[i * 2]; j <= font_info->ranges[i * 2 + 1];
j++)
add_char (font_info, face, j);
add_char (font_info, face, j, nocut);
}
else
{
@ -241,7 +691,7 @@ add_font (struct grub_font_info *font_info, FT_Face face)
for (char_code = FT_Get_First_Char (face, &glyph_index);
glyph_index;
char_code = FT_Get_Next_Char (face, char_code, &glyph_index))
add_char (font_info, face, char_code);
add_char (font_info, face, char_code, nocut);
}
}
@ -281,7 +731,8 @@ print_glyphs (struct grub_font_info *font_info)
struct grub_glyph_info *glyph;
char line[512];
for (glyph = font_info->glyph, num = 0; glyph; glyph = glyph->next, num++)
for (glyph = font_info->glyphs_sorted, num = 0; num < font_info->num_glyphs;
glyph++, num++)
{
int x, y, xmax, xmin, ymax, ymin;
grub_uint8_t *bitmap, mask;
@ -357,7 +808,8 @@ write_font_ascii_bitmap (struct grub_font_info *font_info, char *output_file)
grub_util_error ("Can\'t write to file %s.", output_file);
int correct_size;
for (glyph = font_info->glyph, num = 0; glyph; glyph = glyph->next, num++)
for (glyph = font_info->glyphs_sorted, num = 0; num < font_info->num_glyphs;
glyph++, num++)
{
correct_size = 1;
if (glyph->width != 8 || glyph->height != 16)
@ -377,14 +829,38 @@ write_font_ascii_bitmap (struct grub_font_info *font_info, char *output_file)
fclose (file);
}
void
write_font_width_spec (struct grub_font_info *font_info, char *output_file)
{
FILE *file;
struct grub_glyph_info *glyph;
grub_uint8_t *out;
out = xmalloc (8192);
memset (out, 0, 8192);
file = fopen (output_file, "wb");
if (! file)
grub_util_error ("Can\'t write to file %s.", output_file);
for (glyph = font_info->glyphs_sorted;
glyph < font_info->glyphs_sorted + font_info->num_glyphs; glyph++)
if (glyph->width > 12)
out[glyph->char_code >> 3] |= (1 << (glyph->char_code & 7));
fwrite (out, 8192, 1, file);
fclose (file);
free (out);
}
void
write_font_pf2 (struct grub_font_info *font_info, char *output_file)
{
FILE *file;
grub_uint32_t leng, data;
char style_name[20], *font_name;
struct grub_glyph_info *cur, *pre;
int num, offset;
int offset;
struct grub_glyph_info *cur;
file = fopen (output_file, "wb");
if (! file)
@ -468,33 +944,18 @@ write_font_pf2 (struct grub_font_info *font_info, char *output_file)
printf ("Font descent: %d\n", font_info->desc);
}
num = 0;
pre = 0;
cur = font_info->glyph;
while (cur)
{
struct grub_glyph_info *nxt;
nxt = cur->next;
cur->next = pre;
pre = cur;
cur = nxt;
num++;
}
font_info->glyph = pre;
if (font_verbosity > 0)
printf ("Number of glyph: %d\n", num);
printf ("Number of glyph: %d\n", font_info->num_glyphs);
leng = grub_cpu_to_be32 (num * 9);
leng = grub_cpu_to_be32 (font_info->num_glyphs * 9);
grub_util_write_image (FONT_FORMAT_SECTION_NAMES_CHAR_INDEX,
sizeof(FONT_FORMAT_SECTION_NAMES_CHAR_INDEX) - 1,
file);
grub_util_write_image ((char *) &leng, 4, file);
offset += 8 + num * 9 + 8;
offset += 8 + font_info->num_glyphs * 9 + 8;
for (cur = font_info->glyph; cur; cur = cur->next)
for (cur = font_info->glyphs_sorted;
cur < font_info->glyphs_sorted + font_info->num_glyphs; cur++)
{
data = grub_cpu_to_be32 (cur->char_code);
grub_util_write_image ((char *) &data, 4, file);
@ -510,7 +971,8 @@ write_font_pf2 (struct grub_font_info *font_info, char *output_file)
sizeof(FONT_FORMAT_SECTION_NAMES_DATA) - 1, file);
grub_util_write_image ((char *) &leng, 4, file);
for (cur = font_info->glyph; cur; cur = cur->next)
for (cur = font_info->glyphs_sorted;
cur < font_info->glyphs_sorted + font_info->num_glyphs; cur++)
{
data = grub_cpu_to_be16 (cur->width);
grub_util_write_image ((char *) &data, 2, file);
@ -645,6 +1107,10 @@ main (int argc, char *argv[])
file_format = ASCII_BITMAPS;
break;
case 0x103:
file_format = WIDTH_SPEC;
break;
default:
usage (1);
break;
@ -703,16 +1169,56 @@ main (int argc, char *argv[])
font_info.size = size;
FT_Set_Pixel_Sizes (ft_face, size, size);
add_font (&font_info, ft_face);
add_font (&font_info, ft_face, file_format != PF2);
FT_Done_Face (ft_face);
}
FT_Done_FreeType (ft_lib);
if (file_format == PF2)
write_font_pf2 (&font_info, output_file);
else if (file_format == ASCII_BITMAPS)
write_font_ascii_bitmap (&font_info, output_file);
{
int counter[65537];
struct grub_glyph_info *tmp, *cur;
int i;
memset (counter, 0, sizeof (counter));
for (cur = font_info.glyphs_unsorted; cur; cur = cur->next)
counter[(cur->char_code & 0xffff) + 1]++;
for (i = 0; i < 0x10000; i++)
counter[i+1] += counter[i];
tmp = xmalloc (font_info.num_glyphs
* sizeof (tmp[0]));
for (cur = font_info.glyphs_unsorted; cur; cur = cur->next)
tmp[counter[(cur->char_code & 0xffff)]++] = *cur;
memset (counter, 0, sizeof (counter));
for (cur = tmp; cur < tmp + font_info.num_glyphs; cur++)
counter[((cur->char_code & 0xffff0000) >> 16) + 1]++;
for (i = 0; i < 0x10000; i++)
counter[i+1] += counter[i];
font_info.glyphs_sorted = xmalloc (font_info.num_glyphs
* sizeof (font_info.glyphs_sorted[0]));
for (cur = tmp; cur < tmp + font_info.num_glyphs; cur++)
font_info.glyphs_sorted[counter[(cur->char_code & 0xffff0000) >> 16]++]
= *cur;
free (tmp);
}
switch (file_format)
{
case PF2:
write_font_pf2 (&font_info, output_file);
break;
case ASCII_BITMAPS:
write_font_ascii_bitmap (&font_info, output_file);
break;
case WIDTH_SPEC:
write_font_width_spec (&font_info, output_file);
break;
}
if (font_verbosity > 1)
print_glyphs (&font_info);

View File

@ -59,12 +59,14 @@ enum {
int print = PRINT_FS;
static unsigned int argument_is_device = 0;
void
grub_putchar (int c)
void
grub_xputs_real (const char *str)
{
putchar (c);
fputs (str, stdout);
}
void (*grub_xputs) (const char *str) = grub_xputs_real;
int
grub_getkey (void)
{

View File

@ -37,12 +37,14 @@
#include "progname.h"
void
grub_putchar (int c)
void
grub_xputs_real (const char *str)
{
putchar (c);
fputs (str, stdout);
}
void (*grub_xputs) (const char *str) = grub_xputs_real;
int
grub_getkey (void)
{

View File

@ -64,12 +64,14 @@ static const grub_gpt_part_type_t grub_gpt_partition_type_bios_boot = GRUB_GPT_P
#define grub_host_to_target32(x) grub_cpu_to_le32(x)
#define grub_host_to_target64(x) grub_cpu_to_le64(x)
void
grub_putchar (int c)
void
grub_xputs_real (const char *str)
{
putchar (c);
fputs (str, stdout);
}
void (*grub_xputs) (const char *str) = grub_xputs_real;
int
grub_getkey (void)
{

191
util/import_unicode.py Normal file
View File

@ -0,0 +1,191 @@
#*
#* GRUB -- GRand Unified Bootloader
#* Copyright (C) 2010 Free Software Foundation, Inc.
#*
#* GRUB 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.
#*
#* GRUB 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 GRUB. If not, see <http://www.gnu.org/licenses/>.
#*
import re
import sys
import os
import datetime
if len (sys.argv) < 3:
print ("Usage: %s SOURCE DESTINATION" % sys.argv[0])
exit (0)
infile = open (sys.argv[3], "r")
joining = {}
for line in infile:
line = re.sub ("#.*$", "", line)
line = line.replace ("\n", "")
line = line.replace (" ", "")
if len (line) == 0 or line[0] == '\n':
continue
sp = line.split (";")
curcode = int (sp[0], 16)
if sp[2] == "U":
joining[curcode] = "NONJOINING"
elif sp[2] == "L":
joining[curcode] = "LEFT"
elif sp[2] == "R":
joining[curcode] = "RIGHT"
elif sp[2] == "D":
joining[curcode] = "DUAL"
elif sp[2] == "C":
joining[curcode] = "CAUSING"
else:
print ("Unknown joining type '%s'" % sp[2])
exit (1)
infile.close ()
infile = open (sys.argv[1], "r")
outfile = open (sys.argv[4], "w")
outfile.write ("#include <grub/unicode.h>\n")
outfile.write ("\n")
outfile.write ("struct grub_unicode_compact_range grub_unicode_compact[] = {\n")
begincode = -2
lastcode = -2
lastbiditype = "X"
lastmirrortype = False
lastcombtype = -1
arabicsubst = {}
for line in infile:
sp = line.split (";")
curcode = int (sp[0], 16)
curcombtype = int (sp[3], 10)
curbiditype = sp[4]
curmirrortype = (sp[9] == "Y")
if curcombtype <= 255 and curcombtype >= 253:
print ("UnicodeData.txt uses combination type %d. Conflict." \
% curcombtype)
raise
if sp[2] != "Lu" and sp[2] != "Ll" and sp[2] != "Lt" and sp[2] != "Lm" \
and sp[2] != "Lo"\
and sp[2] != "Me" and sp[2] != "Mc" and sp[2] != "Mn" \
and sp[2] != "Nd" and sp[2] != "Nl" and sp[2] != "No" \
and sp[2] != "Pc" and sp[2] != "Pd" and sp[2] != "Ps" \
and sp[2] != "Pe" and sp[2] != "Pi" and sp[2] != "Pf" \
and sp[2] != "Po" \
and sp[2] != "Sm" and sp[2] != "Sc" and sp[2] != "Sk" \
and sp[2] != "So"\
and sp[2] != "Zs" and sp[2] != "Zl" and sp[2] != "Zp" \
and sp[2] != "Cc" and sp[2] != "Cf" and sp[2] != "Cs" \
and sp[2] != "Co":
print ("WARNING: Unknown type %s" % sp[2])
if curcombtype == 0 and sp[2] == "Me":
curcombtype = 253
if curcombtype == 0 and sp[2] == "Mc":
curcombtype = 254
if curcombtype == 0 and sp[2] == "Mn":
curcombtype = 255
if (curcombtype >= 2 and curcombtype <= 6) \
or (curcombtype >= 37 and curcombtype != 84 and curcombtype != 91 and curcombtype != 103 and curcombtype != 107 and curcombtype != 118 and curcombtype != 122 and curcombtype != 129 and curcombtype != 130 and curcombtype != 132 and curcombtype != 202 and \
curcombtype != 214 and curcombtype != 216 and \
curcombtype != 218 and curcombtype != 220 and \
curcombtype != 222 and curcombtype != 224 and curcombtype != 226 and curcombtype != 228 and \
curcombtype != 230 and curcombtype != 232 and curcombtype != 233 and \
curcombtype != 234 and \
curcombtype != 240 and curcombtype != 253 and \
curcombtype != 254 and curcombtype != 255):
print ("WARNING: Unknown combining type %d" % curcombtype)
if curcode in joining:
curjoin = joining[curcode]
elif sp[2] == "Me" or sp[2] == "Mn" or sp[2] == "Cf":
curjoin = "TRANSPARENT"
else:
curjoin = "NONJOINING"
if sp[1].startswith ("ARABIC LETTER "):
arabname = sp[1][len ("ARABIC LETTER "):]
form = 0
if arabname.endswith (" ISOLATED FORM"):
arabname = arabname[0:len (arabname) - len (" ISOLATED FORM")]
form = 1
if arabname.endswith (" FINAL FORM"):
arabname = arabname[0:len (arabname) - len (" FINAL FORM")]
form = 2
if arabname.endswith (" MEDIAL FORM"):
arabname = arabname[0:len (arabname) - len (" MEDIAL FORM")]
form = 3
if arabname.endswith (" INITIAL FORM"):
arabname = arabname[0:len (arabname) - len (" INITIAL FORM")]
form = 4
if arabname not in arabicsubst:
arabicsubst[arabname]={}
arabicsubst[arabname][form] = curcode;
if form == 0:
arabicsubst[arabname]['join'] = curjoin
if lastcode + 1 != curcode or curbiditype != lastbiditype \
or curcombtype != lastcombtype or curmirrortype != lastmirrortype \
or curjoin != lastjoin:
if begincode != -2 and (lastbiditype != "L" or lastcombtype != 0 or \
lastmirrortype):
outfile.write (("{0x%x, 0x%x, GRUB_BIDI_TYPE_%s, %d, %d, GRUB_JOIN_TYPE_%s},\n" \
% (begincode, lastcode, lastbiditype, \
lastcombtype, lastmirrortype, \
lastjoin)))
begincode = curcode
lastcode = curcode
lastjoin = curjoin
lastbiditype = curbiditype
lastcombtype = curcombtype
lastmirrortype = curmirrortype
if lastbiditype != "L" or lastcombtype != 0 or lastmirrortype:
outfile.write (("{0x%x, 0x%x, GRUB_BIDI_TYPE_%s, %d, %d, GRUB_JOIN_TYPE_%s},\n" \
% (begincode, lastcode, lastbiditype, lastcombtype, \
lastmirrortype, lastjoin)))
outfile.write ("{0, 0, 0, 0, 0, 0},\n")
outfile.write ("};\n")
infile.close ()
infile = open (sys.argv[2], "r")
outfile.write ("struct grub_unicode_bidi_pair grub_unicode_bidi_pairs[] = {\n")
for line in infile:
line = re.sub ("#.*$", "", line)
line = line.replace ("\n", "")
line = line.replace (" ", "")
if len (line) == 0 or line[0] == '\n':
continue
sp = line.split (";")
code1 = int (sp[0], 16)
code2 = int (sp[1], 16)
outfile.write ("{0x%x, 0x%x},\n" % (code1, code2))
outfile.write ("{0, 0},\n")
outfile.write ("};\n")
infile.close ()
outfile.write ("struct grub_unicode_arabic_shape grub_unicode_arabic_shapes[] = {\n ")
for x in arabicsubst:
try:
if arabicsubst[x]['join'] == "DUAL":
outfile.write ("{0x%x, 0x%x, 0x%x, 0x%x, 0x%x},\n " % (arabicsubst[x][0], arabicsubst[x][1], arabicsubst[x][2], arabicsubst[x][3], arabicsubst[x][4]))
elif arabicsubst[x]['join'] == "RIGHT":
outfile.write ("{0x%x, 0x%x, 0x%x, 0x%x, 0x%x},\n " % (arabicsubst[x][0], arabicsubst[x][1], arabicsubst[x][2], 0, 0))
elif arabicsubst[x]['join'] == "LEFT":
outfile.write ("{0x%x, 0x%x, 0x%x, 0x%x, 0x%x},\n " % (arabicsubst[x][0], arabicsubst[x][1], 0, 0, arabicsubst[x][4]))
except:
pass
outfile.write ("{0, 0, 0, 0, 0},\n")
outfile.write ("};\n")
outfile.close ()

View File

@ -90,12 +90,14 @@ struct boot_blocklist
grub_uint32_t len;
} __attribute__ ((packed));
void
grub_putchar (int c)
void
grub_xputs_real (const char *str)
{
putchar (c);
fputs (str, stdout);
}
void (*grub_xputs) (const char *str) = grub_xputs_real;
int
grub_getkey (void)
{