diff options
Diffstat (limited to 'grub-core/term/morse.c')
-rw-r--r-- | grub-core/term/morse.c | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/grub-core/term/morse.c b/grub-core/term/morse.c new file mode 100644 index 0000000..13b8e86 --- /dev/null +++ b/grub-core/term/morse.c @@ -0,0 +1,133 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2011,2012,2013 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/term.h> +#include <grub/misc.h> +#include <grub/types.h> +#include <grub/err.h> +#include <grub/dl.h> +#include <grub/time.h> +#include <grub/speaker.h> + +GRUB_MOD_LICENSE ("GPLv3+"); + +#define BASE_TIME 250 +#define DIH 1 +#define DAH 3 +#define END 0 + +static const char codes[0x80][6] = + { + ['0'] = { DAH, DAH, DAH, DAH, DAH, END }, + ['1'] = { DIH, DAH, DAH, DAH, DAH, END }, + ['2'] = { DIH, DIH, DAH, DAH, DAH, END }, + ['3'] = { DIH, DIH, DIH, DAH, DAH, END }, + ['4'] = { DIH, DIH, DIH, DIH, DAH, END }, + ['5'] = { DIH, DIH, DIH, DIH, DIH, END }, + ['6'] = { DAH, DIH, DIH, DIH, DIH, END }, + ['7'] = { DAH, DAH, DIH, DIH, DIH, END }, + ['8'] = { DAH, DAH, DAH, DIH, DIH, END }, + ['9'] = { DAH, DAH, DAH, DAH, DIH, END }, + ['a'] = { DIH, DAH, END }, + ['b'] = { DAH, DIH, DIH, DIH, END }, + ['c'] = { DAH, DIH, DAH, DIH, END }, + ['d'] = { DAH, DIH, DIH, END }, + ['e'] = { DIH, END }, + ['f'] = { DIH, DIH, DAH, DIH, END }, + ['g'] = { DAH, DAH, DIH, END }, + ['h'] = { DIH, DIH, DIH, DIH, END }, + ['i'] = { DIH, DIH, END }, + ['j'] = { DIH, DAH, DAH, DAH, END }, + ['k'] = { DAH, DIH, DAH, END }, + ['l'] = { DIH, DAH, DIH, DIH, END }, + ['m'] = { DAH, DAH, END }, + ['n'] = { DAH, DIH, END }, + ['o'] = { DAH, DAH, DAH, END }, + ['p'] = { DIH, DAH, DAH, DIH, END }, + ['q'] = { DAH, DAH, DIH, DAH, END }, + ['r'] = { DIH, DAH, DIH, END }, + ['s'] = { DIH, DIH, DIH, END }, + ['t'] = { DAH, END }, + ['u'] = { DIH, DIH, DAH, END }, + ['v'] = { DIH, DIH, DIH, DAH, END }, + ['w'] = { DIH, DAH, DAH, END }, + ['x'] = { DAH, DIH, DIH, DAH, END }, + ['y'] = { DAH, DIH, DAH, DAH, END }, + ['z'] = { DAH, DAH, DIH, DIH, END } + }; + +static void +grub_audio_tone (int length) +{ + grub_speaker_beep_on (1000); + grub_millisleep (length); + grub_speaker_beep_off (); +} + +static void +grub_audio_putchar (struct grub_term_output *term __attribute__ ((unused)), + const struct grub_unicode_glyph *c_in) +{ + grub_uint8_t c; + int i; + + /* For now, do not try to use a surrogate pair. */ + if (c_in->base > 0x7f) + c = '?'; + else + c = grub_tolower (c_in->base); + for (i = 0; codes[c][i]; i++) + { + grub_audio_tone (codes[c][i] * BASE_TIME); + grub_millisleep (BASE_TIME); + } + grub_millisleep (2 * BASE_TIME); +} + + +static int +dummy (void) +{ + return 0; +} + +static struct grub_term_output grub_audio_term_output = + { + .name = "morse", + .init = (void *) dummy, + .fini = (void *) dummy, + .putchar = grub_audio_putchar, + .getwh = (void *) dummy, + .getxy = (void *) dummy, + .gotoxy = (void *) dummy, + .cls = (void *) dummy, + .setcolorstate = (void *) dummy, + .setcursor = (void *) dummy, + .flags = GRUB_TERM_CODE_TYPE_ASCII | GRUB_TERM_DUMB, + .progress_update_divisor = GRUB_PROGRESS_NO_UPDATE + }; + +GRUB_MOD_INIT (morse) +{ + grub_term_register_output ("audio", &grub_audio_term_output); +} + +GRUB_MOD_FINI (morse) +{ + grub_term_unregister_output (&grub_audio_term_output); +} |