Add support for loadable vkeyboard layouts
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@9347 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
0fec4711d5
commit
75c3d0b9f1
13 changed files with 644 additions and 196 deletions
|
@ -41,6 +41,9 @@
|
|||
#include "dircache.h"
|
||||
#include "splash.h"
|
||||
#include "yesno.h"
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
#include "keyboard.h"
|
||||
#endif
|
||||
|
||||
#ifndef SIMULATOR
|
||||
static int boot_size = 0;
|
||||
|
@ -462,6 +465,12 @@ int ft_enter(struct tree_context* c)
|
|||
font_load(buf);
|
||||
set_file(buf, (char *)global_settings.font_file, MAX_FILENAME);
|
||||
break;
|
||||
|
||||
case TREE_ATTR_KBD:
|
||||
if (!load_kbd(buf))
|
||||
gui_syncsplash(HZ, true, str(LANG_KEYBOARD_LOADED));
|
||||
set_file(buf, (char *)global_settings.kbd_file, MAX_FILENAME);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifndef SIMULATOR
|
||||
|
|
|
@ -21,4 +21,8 @@
|
|||
|
||||
int kbd_input(char* buffer, int buflen);
|
||||
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
int load_kbd(unsigned char* filename);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -3887,3 +3887,14 @@ eng: "Precut"
|
|||
voice: "Pre-cut"
|
||||
new:
|
||||
|
||||
id: LANG_KEYBOARD_LOADED
|
||||
desc: shown when a keyboard has been loaded from the dir browser
|
||||
eng: "New Keyboard"
|
||||
voice: ""
|
||||
new:
|
||||
|
||||
id: VOICE_EXT_KBD
|
||||
desc: spoken only, for file extension
|
||||
eng: ""
|
||||
voice: "keyboard"
|
||||
new:
|
||||
|
|
|
@ -49,6 +49,7 @@ const unsigned char bitmap_icons_6x8[][6] =
|
|||
{ 0xff, 0x81, 0xaf, 0xaa, 0x8c, 0xf8 }, /* Bookmark file */
|
||||
{ 0x77, 0x55, 0x55, 0x55, 0x55, 0x77 }, /* Queued Item */
|
||||
{ 0x3e, 0x41, 0x3e, 0x1c, 0x1c, 0x08 }, /* Moving Item */
|
||||
{ 0x7f, 0x7f, 0x1c, 0x3e, 0x77, 0x63 }, /* Keyboard file */
|
||||
};
|
||||
|
||||
const unsigned char bitmap_icons_7x8[][7] =
|
||||
|
|
|
@ -56,6 +56,7 @@ enum icons_6x8 {
|
|||
Icon_Bookmark,
|
||||
Icon_Queued,
|
||||
Icon_Moving,
|
||||
Icon_Keyboard,
|
||||
Icon6x8Last
|
||||
};
|
||||
|
||||
|
|
|
@ -33,19 +33,28 @@
|
|||
#include "rbunicode.h"
|
||||
#include "buttonbar.h"
|
||||
#include "logf.h"
|
||||
#include "icons.h"
|
||||
#include "file.h"
|
||||
#include "hangul.h"
|
||||
|
||||
#define KEYBOARD_MARGIN 3
|
||||
|
||||
#if (LCD_WIDTH >= 160) && (LCD_HEIGHT >= 96)
|
||||
#define KEYBOARD_LINES 8
|
||||
#define KEYBOARD_PAGES 1
|
||||
|
||||
#else
|
||||
#define KEYBOARD_LINES 4
|
||||
#define KEYBOARD_PAGES 3
|
||||
|
||||
#ifndef O_BINARY
|
||||
#define O_BINARY 0
|
||||
#endif
|
||||
|
||||
#if CONFIG_KEYPAD == RECORDER_PAD
|
||||
#define BUTTONBAR_HEIGHT 8
|
||||
#else
|
||||
#define BUTTONBAR_HEIGHT 0
|
||||
#endif
|
||||
|
||||
#if (LCD_WIDTH >= 160) && (LCD_HEIGHT >= 96)
|
||||
#define DEFAULT_LINES 8
|
||||
#else
|
||||
#define DEFAULT_LINES 4
|
||||
#endif
|
||||
|
||||
#define DEFAULT_MARGIN 6
|
||||
#define KBD_BUF_SIZE 500
|
||||
|
||||
#if (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
|
||||
(CONFIG_KEYPAD == IRIVER_H300_PAD)
|
||||
|
@ -61,7 +70,7 @@
|
|||
#define KBD_RIGHT BUTTON_RIGHT
|
||||
#define KBD_UP BUTTON_UP
|
||||
#define KBD_DOWN BUTTON_DOWN
|
||||
#define HAVE_MORSE_INPUT
|
||||
#define KBD_MORSE_INPUT (BUTTON_ON | BUTTON_MODE)
|
||||
|
||||
#elif CONFIG_KEYPAD == RECORDER_PAD
|
||||
#define KBD_CURSOR_RIGHT (BUTTON_ON | BUTTON_RIGHT)
|
||||
|
@ -172,39 +181,39 @@
|
|||
|
||||
#endif
|
||||
|
||||
#if KEYBOARD_PAGES == 1
|
||||
static const char * const kbdpages[KEYBOARD_PAGES][KEYBOARD_LINES] = {
|
||||
{ "ABCDEFG abcdefg !?\" @#$%+'",
|
||||
"HIJKLMN hijklmn 789 &_()-`",
|
||||
"OPQRSTU opqrstu 456 §|{}/<",
|
||||
"VWXYZ., vwxyz.,0123 ~=[]*>",
|
||||
"ÀÁÂÃÄÅÆ ÌÍÎÏ ÈÉÊË ¢£¤¥¦§©®",
|
||||
"àáâãäåæ ìíîï èéêë «»°ºª¹²³",
|
||||
"ÓÒÔÕÖØ ÇÐÞÝß ÙÚÛÜ ¯±×÷¡¿µ·",
|
||||
"òóôõöø çðþýÿ ùúûü ¼½¾¬¶¨ " },
|
||||
};
|
||||
|
||||
#if (LCD_WIDTH >= 160) && (LCD_HEIGHT >= 96)
|
||||
static const unsigned char * default_kbd =
|
||||
"ABCDEFG abcdefg !?\" @#$%+'\n"
|
||||
"HIJKLMN hijklmn 789 &_()-`\n"
|
||||
"OPQRSTU opqrstu 456 §|{}/<\n"
|
||||
"VWXYZ., vwxyz.,0123 ~=[]*>\n"
|
||||
"ÀÁÂÃÄÅÆ ÌÍÎÏ ÈÉÊË ¢£¤¥¦§©®\n"
|
||||
"àáâãäåæ ìíîï èéêë «»°ºª¹²³\n"
|
||||
"ÓÒÔÕÖØ ÇÐÞÝß ÙÚÛÜ ¯±×÷¡¿µ·\n"
|
||||
"òóôõöø çðþýÿ ùúûü ¼½¾¬¶¨";
|
||||
#else
|
||||
static const char * const kbdpages[KEYBOARD_PAGES][KEYBOARD_LINES] = {
|
||||
{ "ABCDEFG !?\" @#$%+'",
|
||||
"HIJKLMN 789 &_()-`",
|
||||
"OPQRSTU 456 §|{}/<",
|
||||
"VWXYZ.,0123 ~=[]*>" },
|
||||
static const unsigned char * default_kbd =
|
||||
"ABCDEFG !?\" @#$%+'\n"
|
||||
"HIJKLMN 789 &_()-`\n"
|
||||
"OPQRSTU 456 §|{}/<\n"
|
||||
"VWXYZ.,0123 ~=[]*>\n"
|
||||
|
||||
{ "abcdefg ¢£¤¥¦§©®¬",
|
||||
"hijklmn «»°ºª¹²³¶",
|
||||
"opqrstu ¯±×÷¡¿µ·¨",
|
||||
"vwxyz., ¼½¾ " },
|
||||
|
||||
{ "ÀÁÂÃÄÅÆ ÌÍÎÏ ÈÉÊË",
|
||||
"àáâãäåæ ìíîï èéêë",
|
||||
"ÓÒÔÕÖØ ÇÐÞÝß ÙÚÛÜ",
|
||||
"òóôõöø çðþýÿ ùúûü" },
|
||||
};
|
||||
"abcdefg ¢£¤¥¦§©®¬\n"
|
||||
"hijklmn «»°ºª¹²³¶\n"
|
||||
"opqrstu ¯±×÷¡¿µ·¨\n"
|
||||
"vwxyz., ¼½¾ \n"
|
||||
|
||||
"ÀÁÂÃÄÅÆ ÌÍÎÏ ÈÉÊË\n"
|
||||
"àáâãäåæ ìíîï èéêë\n"
|
||||
"ÓÒÔÕÖØ ÇÐÞÝß ÙÚÛÜ\n"
|
||||
"òóôõöø çðþýÿ ùúûü";
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_MORSE_INPUT
|
||||
static unsigned short kbd_buf[KBD_BUF_SIZE];
|
||||
static bool kbd_loaded = false;
|
||||
static int nchars = 0;
|
||||
|
||||
#ifdef KBD_MORSE_INPUT
|
||||
/* FIXME: We should put this to a configuration file. */
|
||||
static const char *morse_alphabets =
|
||||
"abcdefghijklmnopqrstuvwxyz1234567890,.?-@ ";
|
||||
|
@ -217,37 +226,139 @@ static const unsigned char morse_codes[] = {
|
|||
static bool morse_mode = false;
|
||||
#endif
|
||||
|
||||
/* Loads a custom keyboard into memory
|
||||
call with NULL to reset keyboard */
|
||||
int load_kbd(unsigned char* filename)
|
||||
{
|
||||
int fd, count;
|
||||
int i = 0;
|
||||
unsigned char buf[4];
|
||||
|
||||
if (filename == NULL) {
|
||||
kbd_loaded = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
fd = open(filename, O_RDONLY|O_BINARY);
|
||||
if (fd < 0)
|
||||
return 1;
|
||||
|
||||
while (read(fd, buf, 1) == 1 && i < KBD_BUF_SIZE) {
|
||||
/* check how many bytes to read */
|
||||
if (buf[0] < 0x80) {
|
||||
count = 0;
|
||||
} else if (buf[0] < 0xe0) {
|
||||
count = 1;
|
||||
} else if (buf[0] < 0xf0) {
|
||||
count = 2;
|
||||
} else if (buf[0] < 0xf5) {
|
||||
count = 3;
|
||||
} else {
|
||||
/* Invalid size. */
|
||||
continue;
|
||||
}
|
||||
|
||||
if (read(fd, &buf[1], count) != count) {
|
||||
close(fd);
|
||||
kbd_loaded = false;
|
||||
return 1;
|
||||
}
|
||||
|
||||
utf8decode(buf, &kbd_buf[i]);
|
||||
if (kbd_buf[i] != 0xFEFF && kbd_buf[i] != '\n' &&
|
||||
kbd_buf[i] != '\r') /*skip BOM & newlines */
|
||||
i++;
|
||||
}
|
||||
|
||||
close(fd);
|
||||
kbd_loaded = true;
|
||||
nchars = i;
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
/* helper function to spell a char if voice UI is enabled */
|
||||
static void kbd_spellchar(char c)
|
||||
static void kbd_spellchar(unsigned short c)
|
||||
{
|
||||
static char spell_char[2] = "\0\0"; /* store char to pass to talk_spell */
|
||||
|
||||
if (global_settings.talk_menu) /* voice UI? */
|
||||
if (global_settings.talk_menu && c < 128) /* voice UI? */
|
||||
{
|
||||
spell_char[0] = c;
|
||||
spell_char[0] = (char)c;
|
||||
talk_spell(spell_char, false);
|
||||
}
|
||||
}
|
||||
|
||||
void kbd_inschar(unsigned char* text, int buflen, int* editpos, unsigned short ch)
|
||||
{
|
||||
int i, j, k, len;
|
||||
unsigned char tmp[4];
|
||||
unsigned char* utf8;
|
||||
|
||||
len = strlen(text);
|
||||
k = utf8length(text);
|
||||
utf8 = utf8encode(ch, tmp);
|
||||
j = (long)utf8 - (long)tmp;
|
||||
|
||||
if (len + j < buflen)
|
||||
{
|
||||
for (i = len+j; k >= *editpos; i--) {
|
||||
text[i] = text[i-j];
|
||||
if ((text[i] & MASK) != COMP)
|
||||
k--;
|
||||
}
|
||||
while (j--)
|
||||
text[i--] = tmp[j];
|
||||
(*editpos)++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void kbd_delchar(unsigned char* text, int* editpos)
|
||||
{
|
||||
int i = 0;
|
||||
unsigned char* utf8;
|
||||
|
||||
if (*editpos > 0)
|
||||
{
|
||||
utf8 = text + utf8seek(text, *editpos);
|
||||
do {
|
||||
i++;
|
||||
utf8--;
|
||||
} while ((*utf8 & MASK) == COMP);
|
||||
while (utf8[i]) {
|
||||
*utf8 = utf8[i];
|
||||
utf8++;
|
||||
}
|
||||
*utf8 = 0;
|
||||
(*editpos)--;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int kbd_input(char* text, int buflen)
|
||||
{
|
||||
bool done = false;
|
||||
#if defined(KBD_PAGE_FLIP) || (KEYBOARD_PAGES > 1)
|
||||
int page = 0;
|
||||
#endif
|
||||
int font_w = 0, font_h = 0, i, j;
|
||||
int font_w = 0, font_h = 0, text_w = 0;
|
||||
int i = 0, j, k, w;
|
||||
int x = 0, y = 0;
|
||||
int main_x, main_y, max_chars;
|
||||
int status_y1, status_y2;
|
||||
int len, len_utf8, c = 0;
|
||||
int main_x, main_y, max_chars, max_chars_text;
|
||||
int len_utf8, c = 0;
|
||||
int editpos, curpos, leftpos;
|
||||
int lines, pages, keyboard_margin;
|
||||
int curfont;
|
||||
int statusbar_size = global_settings.statusbar ? STATUSBAR_HEIGHT : 0;
|
||||
unsigned short ch, tmp, hlead = 0, hvowel = 0, htail = 0;
|
||||
bool hangul = false;
|
||||
bool redraw = true;
|
||||
unsigned char *utf8;
|
||||
const char * const *line;
|
||||
#ifdef HAVE_MORSE_INPUT
|
||||
const unsigned char *p;
|
||||
#ifdef KBD_MORSE_INPUT
|
||||
bool morse_reading = false;
|
||||
unsigned char morse_code = 0;
|
||||
int morse_tick = 0, morse_len;
|
||||
int morse_tick = 0, morse_len, old_main_y;
|
||||
char buf[2];
|
||||
#endif
|
||||
#ifdef KBD_MODES
|
||||
|
@ -255,7 +366,7 @@ int kbd_input(char* text, int buflen)
|
|||
#endif
|
||||
|
||||
char outline[256];
|
||||
struct font* font = font_get(FONT_SYSFIXED);
|
||||
struct font* font;
|
||||
int button, lastbutton = 0;
|
||||
#ifdef HAS_BUTTONBAR
|
||||
struct gui_buttonbar buttonbar;
|
||||
|
@ -264,44 +375,103 @@ int kbd_input(char* text, int buflen)
|
|||
gui_buttonbar_init(&buttonbar);
|
||||
gui_buttonbar_set_display(&buttonbar, &(screens[SCREEN_MAIN]) );
|
||||
#endif
|
||||
lcd_setfont(FONT_SYSFIXED);
|
||||
font_w = font->maxwidth;
|
||||
|
||||
if (!kbd_loaded) {
|
||||
curfont = FONT_SYSFIXED;
|
||||
p = default_kbd;
|
||||
while (*p != 0) {
|
||||
p = utf8decode(p, &kbd_buf[i]);
|
||||
if (kbd_buf[i] == '\n')
|
||||
while (i % (LCD_WIDTH/6))
|
||||
kbd_buf[i++] = ' ';
|
||||
else
|
||||
i++;
|
||||
}
|
||||
nchars = i;
|
||||
}
|
||||
else
|
||||
curfont = FONT_UI;
|
||||
|
||||
font = font_get(curfont);
|
||||
font_h = font->height;
|
||||
|
||||
#ifdef HAVE_MORSE_INPUT
|
||||
/* check if FONT_UI fits the screen */
|
||||
if (2*font_h+3+statusbar_size + BUTTONBAR_HEIGHT > LCD_HEIGHT) {
|
||||
font = font_get(FONT_SYSFIXED);
|
||||
font_h = font->height;
|
||||
curfont = FONT_SYSFIXED;
|
||||
}
|
||||
|
||||
lcd_setfont(curfont);
|
||||
|
||||
/* find max width of keyboard glyphs */
|
||||
for (i=0; i<nchars; i++) {
|
||||
w = font_get_width(font, kbd_buf[i]);
|
||||
if (w > font_w)
|
||||
font_w = w;
|
||||
}
|
||||
|
||||
/* find max width for text string */
|
||||
utf8 = text;
|
||||
text_w = font_w;
|
||||
while (*utf8) {
|
||||
utf8 = (unsigned char*)utf8decode(utf8, &ch);
|
||||
w = font_get_width(font, ch);
|
||||
if (w > text_w)
|
||||
text_w = w;
|
||||
}
|
||||
max_chars_text = LCD_WIDTH / text_w - 2;
|
||||
|
||||
/* calculate keyboard grid size */
|
||||
max_chars = LCD_WIDTH / font_w;
|
||||
if (!kbd_loaded) {
|
||||
lines = DEFAULT_LINES;
|
||||
keyboard_margin = DEFAULT_MARGIN;
|
||||
} else {
|
||||
lines = (LCD_HEIGHT - BUTTONBAR_HEIGHT - statusbar_size) / font_h - 1;
|
||||
keyboard_margin = LCD_HEIGHT - BUTTONBAR_HEIGHT - statusbar_size - (lines+1)*font_h;
|
||||
if (keyboard_margin < 3) {
|
||||
lines--;
|
||||
keyboard_margin += font_h;
|
||||
}
|
||||
if (keyboard_margin > 6)
|
||||
keyboard_margin = 6;
|
||||
}
|
||||
|
||||
pages = (nchars + (lines*max_chars-1))/(lines*max_chars);
|
||||
if (pages == 1 && kbd_loaded)
|
||||
lines = (nchars + max_chars - 1) / max_chars;
|
||||
|
||||
main_y = font_h*lines + keyboard_margin + statusbar_size;
|
||||
main_x = 0;
|
||||
keyboard_margin -= keyboard_margin/2;
|
||||
|
||||
#ifdef KBD_MORSE_INPUT
|
||||
old_main_y = main_y;
|
||||
if (morse_mode)
|
||||
main_y = LCD_HEIGHT - font_h;
|
||||
else
|
||||
#endif
|
||||
main_y = (KEYBOARD_LINES + 1) * font_h + (2*KEYBOARD_MARGIN);
|
||||
main_x = 0;
|
||||
status_y1 = LCD_HEIGHT - font_h;
|
||||
status_y2 = LCD_HEIGHT;
|
||||
|
||||
editpos = utf8length(text);
|
||||
|
||||
max_chars = LCD_WIDTH / font_w - 2; /* leave room for < and > */
|
||||
line = kbdpages[0];
|
||||
|
||||
if (global_settings.talk_menu) /* voice UI? */
|
||||
talk_spell(text, true); /* spell initial text */
|
||||
|
||||
while(!done)
|
||||
{
|
||||
len = strlen(text);
|
||||
len_utf8 = utf8length(text);
|
||||
|
||||
if(redraw)
|
||||
{
|
||||
lcd_clear_display();
|
||||
|
||||
lcd_setfont(FONT_SYSFIXED);
|
||||
|
||||
#ifdef HAVE_MORSE_INPUT
|
||||
#ifdef KBD_MORSE_INPUT
|
||||
if (morse_mode)
|
||||
{
|
||||
lcd_setfont(FONT_SYSFIXED); /* Draw morse code screen with sysfont */
|
||||
w = 6; /* sysfixed font width */
|
||||
x = 0;
|
||||
y = font_h;
|
||||
y = statusbar_size;
|
||||
buf[1] = '\0';
|
||||
/* Draw morse code table with code descriptions. */
|
||||
for (i = 0; morse_alphabets[i] != '\0'; i++)
|
||||
|
@ -312,7 +482,7 @@ int kbd_input(char* text, int buflen)
|
|||
for (j = 0; (morse_codes[i] >> j) > 0x01; j++) ;
|
||||
morse_len = j;
|
||||
|
||||
x += font_w + 3;
|
||||
x += w + 3;
|
||||
for (j = 0; j < morse_len; j++)
|
||||
{
|
||||
if ((morse_codes[i] >> (morse_len-j-1)) & 0x01)
|
||||
|
@ -321,11 +491,11 @@ int kbd_input(char* text, int buflen)
|
|||
lcd_fillrect(x + j*4, y + 3, 1, 2);
|
||||
}
|
||||
|
||||
x += font_w * 5 - 3;
|
||||
if (x >= LCD_WIDTH - (font_w*6))
|
||||
x += w * 5 - 3;
|
||||
if (x >= LCD_WIDTH - (w*6))
|
||||
{
|
||||
x = 0;
|
||||
y += font_h;
|
||||
y += 8; /* sysfixed font height */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -333,50 +503,67 @@ int kbd_input(char* text, int buflen)
|
|||
#endif
|
||||
{
|
||||
/* draw page */
|
||||
for (i=0; i < KEYBOARD_LINES; i++)
|
||||
lcd_putsxy(0, 8+i * font_h, line[i]);
|
||||
|
||||
lcd_setfont(curfont);
|
||||
k = page*max_chars*lines;
|
||||
for (i=j=0; j < lines && k < nchars; k++) {
|
||||
utf8 = utf8encode(kbd_buf[k], outline);
|
||||
*utf8 = 0;
|
||||
lcd_getstringsize(outline, &w, NULL);
|
||||
lcd_putsxy(i*font_w + (font_w-w)/2, j*font_h + statusbar_size, outline);
|
||||
if (++i == max_chars) {
|
||||
i = 0;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* separator */
|
||||
lcd_hline(0, LCD_WIDTH - 1, main_y - KEYBOARD_MARGIN);
|
||||
lcd_hline(0, LCD_WIDTH - 1, main_y - keyboard_margin);
|
||||
|
||||
/* write out the text */
|
||||
curpos = MIN(editpos, max_chars - MIN(len_utf8 - editpos, 2));
|
||||
lcd_setfont(curfont);
|
||||
i=j=0;
|
||||
curpos = MIN(editpos, max_chars_text - MIN(len_utf8 - editpos, 2));
|
||||
leftpos = editpos - curpos;
|
||||
utf8 = text + utf8seek(text, leftpos);
|
||||
i=j=0;
|
||||
while (*utf8 && i < max_chars) {
|
||||
outline[j++] = *utf8++;
|
||||
if ((*utf8 & MASK) != COMP)
|
||||
i++;
|
||||
}
|
||||
outline[j] = 0;
|
||||
|
||||
lcd_putsxy(font_w, main_y, outline);
|
||||
|
||||
if (leftpos)
|
||||
lcd_putsxy(0, main_y, "<");
|
||||
if (len_utf8 - leftpos > max_chars)
|
||||
lcd_putsxy(LCD_WIDTH - font_w, main_y, ">");
|
||||
|
||||
while (*utf8 && i < max_chars_text) {
|
||||
outline[j++] = *utf8++;
|
||||
if ((*utf8 & MASK) != COMP) {
|
||||
outline[j] = 0;
|
||||
j=0;
|
||||
i++;
|
||||
lcd_getstringsize(outline, &w, NULL);
|
||||
lcd_putsxy(i*text_w + (text_w-w)/2, main_y, outline);
|
||||
}
|
||||
}
|
||||
|
||||
if (leftpos) {
|
||||
lcd_getstringsize("<", &w, NULL);
|
||||
lcd_putsxy(text_w - w, main_y, "<");
|
||||
}
|
||||
if (len_utf8 - leftpos > max_chars_text)
|
||||
lcd_putsxy(LCD_WIDTH - text_w, main_y, ">");
|
||||
|
||||
/* cursor */
|
||||
i = (curpos + 1) * font_w;
|
||||
i = (curpos + 1) * text_w;
|
||||
lcd_vline(i, main_y, main_y + font_h);
|
||||
|
||||
if (hangul) /* draw underbar */
|
||||
lcd_hline(curpos*text_w, (curpos+1)*text_w, main_y+font_h-1);
|
||||
|
||||
#ifdef HAS_BUTTONBAR
|
||||
/* draw the status bar */
|
||||
gui_buttonbar_set(&buttonbar, "Shift", "OK", "Del");
|
||||
gui_buttonbar_draw(&buttonbar);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef KBD_MODES
|
||||
if (!line_edit)
|
||||
#endif
|
||||
{
|
||||
/* highlight the key that has focus */
|
||||
lcd_set_drawmode(DRMODE_COMPLEMENT);
|
||||
lcd_fillrect(font_w * x, 8 + font_h * y, font_w, font_h);
|
||||
lcd_fillrect(font_w * x, statusbar_size + font_h * y, font_w, font_h);
|
||||
lcd_set_drawmode(DRMODE_SOLID);
|
||||
}
|
||||
|
||||
|
@ -388,7 +575,7 @@ int kbd_input(char* text, int buflen)
|
|||
redraw = true;
|
||||
|
||||
button = button_get_w_tmo(HZ/2);
|
||||
#ifdef HAVE_MORSE_INPUT
|
||||
#ifdef KBD_MORSE_INPUT
|
||||
if (morse_mode)
|
||||
{
|
||||
/* Remap some buttons for morse mode. */
|
||||
|
@ -411,40 +598,43 @@ int kbd_input(char* text, int buflen)
|
|||
|
||||
#if defined(KBD_PAGE_FLIP)
|
||||
case KBD_PAGE_FLIP:
|
||||
#ifdef HAVE_MORSE_INPUT
|
||||
#ifdef KBD_MORSE_INPUT
|
||||
if (morse_mode)
|
||||
{
|
||||
main_y = (KEYBOARD_LINES + 1) * font_h + (2*KEYBOARD_MARGIN);
|
||||
morse_mode = false;
|
||||
x = y = 0;
|
||||
}
|
||||
else
|
||||
break;
|
||||
#endif
|
||||
if (++page == KEYBOARD_PAGES)
|
||||
{
|
||||
if (++page == pages)
|
||||
page = 0;
|
||||
#ifdef HAVE_MORSE_INPUT
|
||||
main_y = LCD_HEIGHT - font_h;
|
||||
morse_mode = true;
|
||||
/* FIXME: We should talk something like Morse mode.. */
|
||||
break ;
|
||||
#endif
|
||||
}
|
||||
line = kbdpages[page];
|
||||
c = utf8seek(line[y], x);
|
||||
kbd_spellchar(line[y][c]);
|
||||
k = (page*lines + y)*max_chars + x;
|
||||
kbd_spellchar(kbd_buf[k]);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef KBD_MORSE_INPUT
|
||||
case KBD_MORSE_INPUT:
|
||||
morse_mode = !morse_mode;
|
||||
x = y = page = 0;
|
||||
if (morse_mode) {
|
||||
old_main_y = main_y;
|
||||
main_y = LCD_HEIGHT - font_h;
|
||||
} else
|
||||
main_y = old_main_y;
|
||||
/* FIXME: We should talk something like Morse mode.. */
|
||||
break;
|
||||
#endif
|
||||
case KBD_RIGHT:
|
||||
case KBD_RIGHT | BUTTON_REPEAT:
|
||||
#ifdef HAVE_MORSE_INPUT
|
||||
#ifdef KBD_MORSE_INPUT
|
||||
if (morse_mode)
|
||||
break;
|
||||
#endif
|
||||
#ifdef KBD_MODES
|
||||
if (line_edit) /* right doubles as cursor_right in line_edit */
|
||||
{
|
||||
if (hangul) {
|
||||
hangul = false;
|
||||
hlead=hvowel=htail=0;
|
||||
break;
|
||||
}
|
||||
if (editpos < len_utf8)
|
||||
{
|
||||
editpos++;
|
||||
|
@ -455,32 +645,33 @@ int kbd_input(char* text, int buflen)
|
|||
else
|
||||
#endif
|
||||
{
|
||||
if (x < (int)utf8length(line[y]) - 1)
|
||||
x++;
|
||||
else
|
||||
{
|
||||
if (++x == max_chars) {
|
||||
x = 0;
|
||||
#if !defined(KBD_PAGE_FLIP) && KEYBOARD_PAGES > 1
|
||||
#if !defined(KBD_PAGE_FLIP)
|
||||
/* no dedicated flip key - flip page on wrap */
|
||||
if (++page == KEYBOARD_PAGES)
|
||||
if (++page == pages)
|
||||
page = 0;
|
||||
line = kbdpages[page];
|
||||
#endif
|
||||
}
|
||||
c = utf8seek(line[y], x);
|
||||
kbd_spellchar(line[y][c]);
|
||||
k = (page*lines + y)*max_chars + x;
|
||||
kbd_spellchar(kbd_buf[k]);
|
||||
}
|
||||
break;
|
||||
|
||||
case KBD_LEFT:
|
||||
case KBD_LEFT | BUTTON_REPEAT:
|
||||
#ifdef HAVE_MORSE_INPUT
|
||||
#ifdef KBD_MORSE_INPUT
|
||||
if (morse_mode)
|
||||
break;
|
||||
#endif
|
||||
#ifdef KBD_MODES
|
||||
if (line_edit) /* left doubles as cursor_left in line_edit */
|
||||
{
|
||||
if (hangul) {
|
||||
hangul = false;
|
||||
hlead=hvowel=htail=0;
|
||||
break;
|
||||
}
|
||||
if (editpos)
|
||||
{
|
||||
editpos--;
|
||||
|
@ -490,27 +681,26 @@ int kbd_input(char* text, int buflen)
|
|||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
{
|
||||
if (x)
|
||||
x--;
|
||||
else
|
||||
{
|
||||
#if !defined(KBD_PAGE_FLIP) && KEYBOARD_PAGES > 1
|
||||
#if !defined(KBD_PAGE_FLIP)
|
||||
/* no dedicated flip key - flip page on wrap */
|
||||
if (--page < 0)
|
||||
page = (KEYBOARD_PAGES-1);
|
||||
line = kbdpages[page];
|
||||
page = (pages-1);
|
||||
#endif
|
||||
x = utf8length(line[y]) - 1;
|
||||
x = max_chars - 1;
|
||||
}
|
||||
c = utf8seek(line[y], x);
|
||||
kbd_spellchar(line[y][c]);
|
||||
k = (page*lines + y)*max_chars + x;
|
||||
kbd_spellchar(kbd_buf[k]);
|
||||
}
|
||||
break;
|
||||
|
||||
case KBD_DOWN:
|
||||
case KBD_DOWN | BUTTON_REPEAT:
|
||||
#ifdef HAVE_MORSE_INPUT
|
||||
#ifdef KBD_MORSE_INPUT
|
||||
if (morse_mode)
|
||||
break;
|
||||
#endif
|
||||
|
@ -523,7 +713,7 @@ int kbd_input(char* text, int buflen)
|
|||
else
|
||||
{
|
||||
#endif
|
||||
if (y < KEYBOARD_LINES - 1)
|
||||
if (y < lines - 1)
|
||||
y++;
|
||||
else
|
||||
#ifndef KBD_MODES
|
||||
|
@ -533,20 +723,22 @@ int kbd_input(char* text, int buflen)
|
|||
}
|
||||
if (!line_edit)
|
||||
#endif
|
||||
c = utf8seek(line[y], x);
|
||||
kbd_spellchar(line[y][c]);
|
||||
{
|
||||
k = (page*lines + y)*max_chars + x;
|
||||
kbd_spellchar(kbd_buf[k]);
|
||||
}
|
||||
break;
|
||||
|
||||
case KBD_UP:
|
||||
case KBD_UP | BUTTON_REPEAT:
|
||||
#ifdef HAVE_MORSE_INPUT
|
||||
#ifdef KBD_MORSE_INPUT
|
||||
if (morse_mode)
|
||||
break;
|
||||
#endif
|
||||
#ifdef KBD_MODES
|
||||
if (line_edit)
|
||||
{
|
||||
y = KEYBOARD_LINES - 1;
|
||||
y = lines - 1;
|
||||
line_edit = false;
|
||||
}
|
||||
else
|
||||
|
@ -556,14 +748,16 @@ int kbd_input(char* text, int buflen)
|
|||
y--;
|
||||
else
|
||||
#ifndef KBD_MODES
|
||||
y = KEYBOARD_LINES - 1;
|
||||
y = lines - 1;
|
||||
#else
|
||||
line_edit = true;
|
||||
}
|
||||
if (!line_edit)
|
||||
#endif
|
||||
c = utf8seek(line[y], x);
|
||||
kbd_spellchar(line[y][c]);
|
||||
{
|
||||
k = (page*lines + y)*max_chars + x;
|
||||
kbd_spellchar(kbd_buf[k]);
|
||||
}
|
||||
break;
|
||||
|
||||
case KBD_DONE:
|
||||
|
@ -575,7 +769,7 @@ int kbd_input(char* text, int buflen)
|
|||
done = true;
|
||||
break;
|
||||
|
||||
#ifdef HAVE_MORSE_INPUT
|
||||
#ifdef KBD_MORSE_INPUT
|
||||
case KBD_SELECT | BUTTON_REL:
|
||||
if (morse_mode && morse_reading)
|
||||
{
|
||||
|
@ -588,7 +782,7 @@ int kbd_input(char* text, int buflen)
|
|||
#endif
|
||||
|
||||
case KBD_SELECT:
|
||||
#ifdef HAVE_MORSE_INPUT
|
||||
#ifdef KBD_MORSE_INPUT
|
||||
if (morse_mode)
|
||||
{
|
||||
morse_tick = current_tick;
|
||||
|
@ -607,44 +801,94 @@ int kbd_input(char* text, int buflen)
|
|||
break;
|
||||
#endif
|
||||
#ifdef KBD_MODES
|
||||
if (line_edit) /* select doubles as backspace in line_edit */
|
||||
{
|
||||
if (editpos > 0)
|
||||
{
|
||||
utf8 = text + utf8seek(text, editpos);
|
||||
i = 0;
|
||||
do {
|
||||
i++;
|
||||
utf8--;
|
||||
} while ((*utf8 & MASK) == COMP);
|
||||
while (utf8[i]) {
|
||||
*utf8 = utf8[i];
|
||||
utf8++;
|
||||
if (line_edit) { /* select doubles as backspace in line_edit */
|
||||
if (hangul) {
|
||||
if (htail != 0)
|
||||
htail = 0;
|
||||
else if (hvowel != 0)
|
||||
hvowel = 0;
|
||||
else {
|
||||
hlead = 0;
|
||||
hangul = false;
|
||||
}
|
||||
*utf8 = 0;
|
||||
editpos--;
|
||||
}
|
||||
kbd_delchar(text, &editpos);
|
||||
if (hangul) {
|
||||
if (hvowel != 0)
|
||||
ch = hangul_join(hlead, hvowel, htail);
|
||||
else
|
||||
ch = hlead;
|
||||
kbd_inschar(text, buflen, &editpos, ch);
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
const unsigned char *inschar = line[y] + utf8seek(line[y], x);
|
||||
j = 0;
|
||||
do {
|
||||
j++;
|
||||
} while ((inschar[j] & MASK) == COMP);
|
||||
if (len + j < buflen)
|
||||
{
|
||||
int k = len_utf8;
|
||||
for (i = len+j; k >= editpos; i--) {
|
||||
text[i] = text[i-j];
|
||||
if ((text[i] & MASK) != COMP)
|
||||
k--;
|
||||
/* find input char */
|
||||
k = (page*lines + y)*max_chars + x;
|
||||
if (k < nchars)
|
||||
ch = kbd_buf[k];
|
||||
else
|
||||
ch = ' ';
|
||||
|
||||
/* check for hangul input */
|
||||
if (ch >= 0x3131 && ch <= 0x3163) {
|
||||
if (hangul) {
|
||||
if ((hvowel == 0) && (jamo_table[ch-0x3131][1] != 0)) {
|
||||
hvowel = ch;
|
||||
ch = hangul_join(hlead, hvowel, htail);
|
||||
kbd_delchar(text, &editpos);
|
||||
}
|
||||
else if ((htail == 0) && (hvowel != 0) && (jamo_table[ch-0x3131][2] != 0)) {
|
||||
htail = ch;
|
||||
/* combine into hangul */
|
||||
ch = hangul_join(hlead, hvowel, htail);
|
||||
kbd_delchar(text, &editpos);
|
||||
}
|
||||
else { /* invalid following char or hangul complete */
|
||||
/* check whether tail is actually lead of next char */
|
||||
if (htail != 0 && (jamo_table[htail-0x3131][0] != 0)
|
||||
&& (jamo_table[ch-0x3131][1] != 0)) {
|
||||
tmp = hangul_join(hlead, hvowel, 0);
|
||||
kbd_delchar(text, &editpos);
|
||||
kbd_inschar(text, buflen, &editpos, tmp);
|
||||
hlead = htail;
|
||||
hvowel = ch;
|
||||
htail = 0;
|
||||
ch = hangul_join(hlead, hvowel, htail);
|
||||
}
|
||||
else if (hlead != 0 && hvowel != 0) {
|
||||
/* finish previous hangul */
|
||||
tmp = hangul_join(hlead, hvowel, htail);
|
||||
kbd_delchar(text, &editpos);
|
||||
kbd_inschar(text, buflen, &editpos, tmp);
|
||||
hlead=hvowel=htail=0;
|
||||
/* start of new hangul? */
|
||||
if (jamo_table[ch-0x3131][0] != 0) {
|
||||
hlead = ch;
|
||||
}
|
||||
else
|
||||
hangul = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (jamo_table[ch-0x3131][0] != 0) {
|
||||
hlead = ch;
|
||||
hangul = true;
|
||||
}
|
||||
while (j--)
|
||||
text[i--] = inschar[j];
|
||||
editpos++;
|
||||
}
|
||||
else if (hangul) {
|
||||
/* finish previous hangul */
|
||||
if (hlead != 0 && hvowel != 0) {
|
||||
tmp = hangul_join(hlead, hvowel, htail);
|
||||
kbd_delchar(text, &editpos);
|
||||
kbd_inschar(text, buflen, &editpos, tmp);
|
||||
}
|
||||
hangul = false;
|
||||
hlead=hvowel=htail=0;
|
||||
}
|
||||
/* insert char */
|
||||
kbd_inschar(text, buflen, &editpos, ch);
|
||||
}
|
||||
if (global_settings.talk_menu) /* voice UI? */
|
||||
talk_spell(text, false); /* speak revised text */
|
||||
|
@ -653,20 +897,23 @@ int kbd_input(char* text, int buflen)
|
|||
#ifndef KBD_MODES
|
||||
case KBD_BACKSPACE:
|
||||
case KBD_BACKSPACE | BUTTON_REPEAT:
|
||||
if (editpos > 0)
|
||||
{
|
||||
utf8 = text + utf8seek(text, editpos);
|
||||
i = 0;
|
||||
do {
|
||||
i++;
|
||||
utf8--;
|
||||
} while ((*utf8 & MASK) == COMP);
|
||||
while (utf8[i]) {
|
||||
*utf8 = utf8[i];
|
||||
utf8++;
|
||||
if (hangul) {
|
||||
if (htail != 0)
|
||||
htail = 0;
|
||||
else if (hvowel != 0)
|
||||
hvowel = 0;
|
||||
else {
|
||||
hlead = 0;
|
||||
hangul = false;
|
||||
}
|
||||
*utf8 = 0;
|
||||
editpos--;
|
||||
}
|
||||
kbd_delchar(text, &editpos);
|
||||
if (hangul) {
|
||||
if (hvowel != 0)
|
||||
ch = hangul_join(hlead, hvowel, htail);
|
||||
else
|
||||
ch = hlead;
|
||||
kbd_inschar(text, buflen, &editpos, ch);
|
||||
}
|
||||
if (global_settings.talk_menu) /* voice UI? */
|
||||
talk_spell(text, false); /* speak revised text */
|
||||
|
@ -674,6 +921,11 @@ int kbd_input(char* text, int buflen)
|
|||
|
||||
case KBD_CURSOR_RIGHT:
|
||||
case KBD_CURSOR_RIGHT | BUTTON_REPEAT:
|
||||
if (hangul) {
|
||||
hangul = false;
|
||||
hlead=hvowel=htail=0;
|
||||
break;
|
||||
}
|
||||
if (editpos < len_utf8)
|
||||
{
|
||||
editpos++;
|
||||
|
@ -684,6 +936,11 @@ int kbd_input(char* text, int buflen)
|
|||
|
||||
case KBD_CURSOR_LEFT:
|
||||
case KBD_CURSOR_LEFT | BUTTON_REPEAT:
|
||||
if (hangul) {
|
||||
hangul = false;
|
||||
hlead=hvowel=htail=0;
|
||||
break;
|
||||
}
|
||||
if (editpos)
|
||||
{
|
||||
editpos--;
|
||||
|
@ -696,7 +953,7 @@ int kbd_input(char* text, int buflen)
|
|||
case BUTTON_NONE:
|
||||
gui_syncstatusbar_draw(&statusbars, false);
|
||||
redraw = false;
|
||||
#ifdef HAVE_MORSE_INPUT
|
||||
#ifdef KBD_MORSE_INPUT
|
||||
if (morse_reading)
|
||||
{
|
||||
logf("Morse: 0x%02x", morse_code);
|
||||
|
@ -713,15 +970,15 @@ int kbd_input(char* text, int buflen)
|
|||
logf("Morse code not found");
|
||||
break ;
|
||||
}
|
||||
|
||||
if (len + 1 < buflen)
|
||||
{
|
||||
for (i = len ; i > editpos; i--)
|
||||
text[i] = text[i-1];
|
||||
text[len+1] = 0;
|
||||
text[editpos] = morse_alphabets[j];
|
||||
editpos++;
|
||||
|
||||
/* finish hangul char if necessary */
|
||||
if (hangul) {
|
||||
hangul = false;
|
||||
hlead=hvowel=htail=0;
|
||||
}
|
||||
|
||||
kbd_inschar(text, buflen, &editpos, morse_alphabets[j]);
|
||||
|
||||
if (global_settings.talk_menu) /* voice UI? */
|
||||
talk_spell(text, false); /* speak revised text */
|
||||
redraw = true;
|
||||
|
|
|
@ -916,6 +916,11 @@ int settings_save( void )
|
|||
MAX_FILENAME);
|
||||
i+= MAX_FILENAME;
|
||||
#endif
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
strncpy((char *)&config_block[i], (char *)global_settings.kbd_file,
|
||||
MAX_FILENAME);
|
||||
i+= MAX_FILENAME;
|
||||
#endif
|
||||
|
||||
if(save_config_buffer())
|
||||
{
|
||||
|
@ -1108,6 +1113,15 @@ void settings_apply(void)
|
|||
else
|
||||
font_reset();
|
||||
|
||||
if ( global_settings.kbd_file[0] &&
|
||||
global_settings.kbd_file[0] != 0xff ) {
|
||||
snprintf(buf, sizeof buf, ROCKBOX_DIR "/%s.kbd",
|
||||
global_settings.kbd_file);
|
||||
load_kbd(buf);
|
||||
}
|
||||
else
|
||||
load_kbd(NULL);
|
||||
|
||||
lcd_scroll_step(global_settings.scroll_step);
|
||||
gui_list_screen_scroll_step(global_settings.screen_scroll_step);
|
||||
gui_list_screen_scroll_out_of_view(global_settings.offset_out_of_view);
|
||||
|
@ -1252,6 +1266,11 @@ void settings_load(int which)
|
|||
strncpy((char *)global_settings.backdrop_file, (char *)&config_block[i],
|
||||
MAX_FILENAME);
|
||||
i+= MAX_FILENAME;
|
||||
#endif
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
strncpy((char *)global_settings.kbd_file, (char *)&config_block[i],
|
||||
MAX_FILENAME);
|
||||
i+= MAX_FILENAME;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -1425,6 +1444,12 @@ bool settings_load_config(const char* file)
|
|||
set_file(value, (char *)global_settings.backdrop_file, MAX_FILENAME);
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
else if (!strcasecmp(name, "keyboard")) {
|
||||
if (!load_kbd(value))
|
||||
set_file(value, (char *)global_settings.kbd_file, MAX_FILENAME);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* check for scalar values, using the two tables */
|
||||
|
@ -1583,6 +1608,12 @@ bool settings_save_config(void)
|
|||
global_settings.backdrop_file);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
if (global_settings.kbd_file[0] != 0)
|
||||
fdprintf(fd, "keyboard: %s/%s.kbd\r\n", ROCKBOX_DIR,
|
||||
global_settings.kbd_file);
|
||||
#endif
|
||||
|
||||
/* here's the action: write values to file, specified via table */
|
||||
save_cfg_table(rtc_bits, sizeof(rtc_bits)/sizeof(rtc_bits[0]), fd);
|
||||
save_cfg_table(hd_bits, sizeof(hd_bits)/sizeof(hd_bits[0]), fd);
|
||||
|
@ -1666,6 +1697,9 @@ void settings_reset(void) {
|
|||
global_settings.fg_color = LCD_DEFAULT_FG;
|
||||
global_settings.bg_color = LCD_DEFAULT_BG;
|
||||
#endif
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
global_settings.kbd_file[0] = '\0';
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -481,6 +481,10 @@ struct user_settings
|
|||
bool remote_bl_filter_first_keypress; /* filter first remote keypress when remote dark? */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
unsigned char kbd_file[MAX_FILENAME+1]; /* last keyboard */
|
||||
#endif
|
||||
};
|
||||
|
||||
enum optiontype { INT, BOOL };
|
||||
|
|
|
@ -110,6 +110,7 @@ const struct filetype filetypes[] = {
|
|||
{ "rock",TREE_ATTR_ROCK,Icon_Plugin, VOICE_EXT_ROCK },
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
{ "fnt", TREE_ATTR_FONT,Icon_Font, VOICE_EXT_FONT },
|
||||
{ "kbd", TREE_ATTR_KBD, Icon_Keyboard, VOICE_EXT_KBD },
|
||||
#endif
|
||||
{ "bmark",TREE_ATTR_BMARK, Icon_Bookmark, VOICE_EXT_BMARK },
|
||||
#ifdef BOOTFILE_EXT
|
||||
|
|
|
@ -241,6 +241,7 @@ struct tree_context {
|
|||
#define TREE_ATTR_MOD 0x0900 /* firmware file */
|
||||
#define TREE_ATTR_RWPS 0x1000 /* remote-wps config file */
|
||||
#define TREE_ATTR_BMP 0x1100 /* backdrop bmp file */
|
||||
#define TREE_ATTR_KBD 0x1200 /* keyboard file */
|
||||
#define TREE_ATTR_MASK 0xFF00 /* which bits tree.c uses for file types */
|
||||
|
||||
void tree_get_filetypes(const struct filetype**, int*);
|
||||
|
|
|
@ -63,6 +63,7 @@ drivers/lcd-player.c
|
|||
#ifdef HAVE_LCD_BITMAP
|
||||
arabjoin.c
|
||||
bidi.c
|
||||
hangul.c
|
||||
#if LCD_DEPTH == 1
|
||||
drivers/lcd-recorder.c
|
||||
#elif LCD_DEPTH == 2
|
||||
|
|
23
firmware/export/hangul.h
Normal file
23
firmware/export/hangul.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
*
|
||||
*
|
||||
* Copyright (C) 2006 by Frank Dischner
|
||||
*
|
||||
* All files in this archive are subject to the GNU General Public License.
|
||||
* See the file COPYING in the source tree root for full license agreement.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
extern const char jamo_table[51][3];
|
||||
|
||||
unsigned short hangul_join(unsigned short lead, unsigned short vowel,
|
||||
unsigned short tail);
|
101
firmware/hangul.c
Normal file
101
firmware/hangul.c
Normal file
|
@ -0,0 +1,101 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
*
|
||||
*
|
||||
* Copyright (C) 2006 by Frank Dischner
|
||||
*
|
||||
* All files in this archive are subject to the GNU General Public License.
|
||||
* See the file COPYING in the source tree root for full license agreement.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
#include "hangul.h"
|
||||
|
||||
const char jamo_table[51][3] = {
|
||||
{ 1, 0, 1},
|
||||
{ 2, 0, 2},
|
||||
{ 0, 0, 3},
|
||||
{ 3, 0, 4},
|
||||
{ 0, 0, 5},
|
||||
{ 0, 0, 6},
|
||||
{ 4, 0, 7},
|
||||
{ 5, 0, 0},
|
||||
{ 6, 0, 8},
|
||||
{ 0, 0, 9},
|
||||
{ 0, 0, 10},
|
||||
{ 0, 0, 11},
|
||||
{ 0, 0, 12},
|
||||
{ 0, 0, 13},
|
||||
{ 0, 0, 14},
|
||||
{ 0, 0, 15},
|
||||
{ 7, 0, 16},
|
||||
{ 8, 0, 17},
|
||||
{ 9, 0, 0},
|
||||
{ 0, 0, 18},
|
||||
{10, 0, 19},
|
||||
{11, 0, 20},
|
||||
{12, 0, 21},
|
||||
{13, 0, 22},
|
||||
{14, 0, 0},
|
||||
{15, 0, 23},
|
||||
{16, 0, 24},
|
||||
{17, 0, 25},
|
||||
{18, 0, 26},
|
||||
{19, 0, 27},
|
||||
{ 0, 1, 0},
|
||||
{ 0, 2, 0},
|
||||
{ 0, 3, 0},
|
||||
{ 0, 4, 0},
|
||||
{ 0, 5, 0},
|
||||
{ 0, 6, 0},
|
||||
{ 0, 7, 0},
|
||||
{ 0, 8, 0},
|
||||
{ 0, 9, 0},
|
||||
{ 0, 10, 0},
|
||||
{ 0, 11, 0},
|
||||
{ 0, 12, 0},
|
||||
{ 0, 13, 0},
|
||||
{ 0, 14, 0},
|
||||
{ 0, 15, 0},
|
||||
{ 0, 16, 0},
|
||||
{ 0, 17, 0},
|
||||
{ 0, 18, 0},
|
||||
{ 0, 19, 0},
|
||||
{ 0, 20, 0},
|
||||
{ 0, 21, 0},
|
||||
};
|
||||
|
||||
/* takes three jamo chars and joins them into one hangul */
|
||||
unsigned short hangul_join(unsigned short lead, unsigned short vowel,
|
||||
unsigned short tail)
|
||||
{
|
||||
unsigned short ch = 0xfffd;
|
||||
|
||||
if (lead < 0x3131 || lead > 0x3163)
|
||||
return ch;
|
||||
lead = jamo_table[lead-0x3131][0];
|
||||
|
||||
if (vowel < 0x3131 || vowel > 0x3163)
|
||||
return ch;
|
||||
vowel = jamo_table[vowel-0x3131][1];
|
||||
|
||||
if (tail) {
|
||||
if (tail < 0x3131 || tail > 0x3163)
|
||||
return ch;
|
||||
tail = jamo_table[tail-0x3131][2];
|
||||
if (!tail)
|
||||
return ch;
|
||||
}
|
||||
|
||||
if (lead && vowel)
|
||||
ch = tail + (vowel - 1)*28 + (lead - 1)*588 + 44032;
|
||||
|
||||
return ch;
|
||||
}
|
Loading…
Reference in a new issue