From 9f1d654e67d3bb903c132424debe6420f9826b7c Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 20 Jun 2012 22:19:26 +0200 Subject: [PATCH] * include/grub/ieee1275/ieee1275.h (grub_ieee1275_flag): New enum value GRUB_IEEE1275_FLAG_BROKEN_REPEAT. * grub-core/kern/ieee1275/cmain.c (grub_ieee1275_find_options): Set GRUB_IEEE1275_FLAG_BROKEN_REPEAT on PowerBook3,3. * include/grub/terminfo.h (grub_terminfo_input_state) [__powerpc__]: New fields last_key and last_key_time. * grub-core/term/terminfo.c (grub_terminfo_getkey): Transform extended key-esc into extended key-extended key. --- ChangeLog | 11 +++++++++++ grub-core/kern/ieee1275/cmain.c | 11 +++++++++++ grub-core/term/terminfo.c | 22 ++++++++++++++++++++++ include/grub/ieee1275/ieee1275.h | 4 +++- include/grub/terminfo.h | 4 ++++ 5 files changed, 51 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 35ad54e0c..38408b8e5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2012-06-20 Vladimir Serbinenko + + * include/grub/ieee1275/ieee1275.h (grub_ieee1275_flag): New enum value + GRUB_IEEE1275_FLAG_BROKEN_REPEAT. + * grub-core/kern/ieee1275/cmain.c (grub_ieee1275_find_options): Set + GRUB_IEEE1275_FLAG_BROKEN_REPEAT on PowerBook3,3. + * include/grub/terminfo.h (grub_terminfo_input_state) [__powerpc__]: + New fields last_key and last_key_time. + * grub-core/term/terminfo.c (grub_terminfo_getkey): Transform + extended key-esc into extended key-extended key. + 2012-06-19 Vladimir Serbinenko Avoid unnecessary memcpy of whole video buffer. diff --git a/grub-core/kern/ieee1275/cmain.c b/grub-core/kern/ieee1275/cmain.c index 763f83394..dd04d3976 100644 --- a/grub-core/kern/ieee1275/cmain.c +++ b/grub-core/kern/ieee1275/cmain.c @@ -92,6 +92,17 @@ grub_ieee1275_find_options (void) if (rc >= 0 && grub_strncmp (tmp, "IBM", 3) == 0) grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_NO_TREE_SCANNING_FOR_DISKS); + /* Old Macs have no key repeat, newer ones have fully working one. + The ones inbetween when repeated key generates an escaoe sequence + only the escape is repeated. With this workaround however a fast + e.g. down arrow-ESC is perceived as down arrow-down arrow which is + also annoying but is less so than the original bug of exiting from + the current window on arrow repeat. To avoid unaffected users suffering + from this workaround match only exact models known to have this bug. + */ + if (rc >= 0 && grub_strcmp (tmp, "PowerBook3,3") == 0) + grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_BROKEN_REPEAT); + rc = grub_ieee1275_get_property (root, "compatible", tmp, sizeof (tmp), &actual); if (rc >= 0) diff --git a/grub-core/term/terminfo.c b/grub-core/term/terminfo.c index b09953c2b..d241c84fb 100644 --- a/grub-core/term/terminfo.c +++ b/grub-core/term/terminfo.c @@ -33,6 +33,9 @@ #include #include #include +#ifdef __powerpc__ +#include +#endif GRUB_MOD_LICENSE ("GPLv3+"); @@ -560,11 +563,30 @@ grub_terminfo_getkey (struct grub_term_input *termi) grub_terminfo_readkey (termi, data->input_buf, &data->npending, data->readkey); +#ifdef __powerpc__ + if (data->npending == 1 && data->input_buf[0] == '\e' + && grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_BROKEN_REPEAT) + && grub_get_time_ms () - data->last_key_time < 1000 + && (data->last_key & GRUB_TERM_EXTENDED)) + { + data->npending = 0; + data->last_key_time = grub_get_time_ms (); + return data->last_key; + } +#endif + if (data->npending) { int ret; data->npending--; ret = data->input_buf[0]; +#ifdef __powerpc__ + if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_BROKEN_REPEAT)) + { + data->last_key = ret; + data->last_key_time = grub_get_time_ms (); + } +#endif grub_memmove (data->input_buf, data->input_buf + 1, data->npending * sizeof (data->input_buf[0])); return ret; diff --git a/include/grub/ieee1275/ieee1275.h b/include/grub/ieee1275/ieee1275.h index 451ea44ae..38a75fdf7 100644 --- a/include/grub/ieee1275/ieee1275.h +++ b/include/grub/ieee1275/ieee1275.h @@ -121,7 +121,9 @@ enum grub_ieee1275_flag GRUB_IEEE1275_FLAG_NO_OFNET_SUFFIX, - GRUB_IEEE1275_FLAG_VIRT_TO_REAL_BROKEN + GRUB_IEEE1275_FLAG_VIRT_TO_REAL_BROKEN, + + GRUB_IEEE1275_FLAG_BROKEN_REPEAT }; extern int EXPORT_FUNC(grub_ieee1275_test_flag) (enum grub_ieee1275_flag flag); diff --git a/include/grub/terminfo.h b/include/grub/terminfo.h index 317b18e68..c081a92e1 100644 --- a/include/grub/terminfo.h +++ b/include/grub/terminfo.h @@ -32,6 +32,10 @@ struct grub_terminfo_input_state { int input_buf[GRUB_TERMINFO_READKEY_MAX_LEN]; int npending; +#ifdef __powerpc__ + int last_key; + grub_uint64_t last_key_time; +#endif int (*readkey) (struct grub_term_input *term); };