From abf6a2a1bb53cf4e01d91fcb64a68f6929e3ca24 Mon Sep 17 00:00:00 2001 From: William Kendrick Date: Sun, 8 Jul 2007 07:27:12 +0000 Subject: [PATCH] Attempting to add Thai input method. --- Makefile-i18n | 5 ++ docs/CHANGES.txt | 23 +++--- im/th.im | 96 ++++++++++++++++++++++++ src/im.c | 191 ++++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 304 insertions(+), 11 deletions(-) create mode 100644 im/th.im diff --git a/Makefile-i18n b/Makefile-i18n index 573cdc144..70e72e5c6 100644 --- a/Makefile-i18n +++ b/Makefile-i18n @@ -95,6 +95,7 @@ uninstall-i18n: -rm $(LOCALE_PREFIX)/zh_TW/LC_MESSAGES/tuxpaint.mo -rm $(IM_PREFIX)/ja.im -rm $(IM_PREFIX)/ko.im + -rm $(IM_PREFIX)/th.im # Install the translated text: @@ -475,6 +476,10 @@ install-im: @echo " ko ...Korean..." @cp im/ko.im $(IM_PREFIX)/ko.im @chmod 644 $(IM_PREFIX)/ko.im + @# + @echo " ko ...Thai..." + @cp im/th.im $(IM_PREFIX)/th.im + @chmod 644 $(IM_PREFIX)/th.im else install-im: @echo diff --git a/docs/CHANGES.txt b/docs/CHANGES.txt index c975fe481..e169d7336 100644 --- a/docs/CHANGES.txt +++ b/docs/CHANGES.txt @@ -9,7 +9,7 @@ http://www.tuxpaint.org/ $Id$ -2007.July.5 (0.9.18) +2007.July.8 (0.9.18) * System-Related Improvements: ---------------------------- * Added an API for developing Magic tools as plug-ins. @@ -50,23 +50,26 @@ $Id$ ----------- * Sparkles (based on old Magic Tool) - * New Translations: - ----------------- - * Wolof + * New Localizations: + ------------------ + * Thai input method + Ed Montgomery + + * Wolof translation Haby Diallo - * Translation Updates: - -------------------- - * British English + * Localization Updates: + --------------------- + * British English translation Caroline Ford - * Dutch + * Dutch translation Freek de Kruijf - * Italian + * Italian translation Flavio "Iron Bishop" Pastore - * South African English + * South African English translation Caroline Ford diff --git a/im/th.im b/im/th.im new file mode 100644 index 000000000..b24224b10 --- /dev/null +++ b/im/th.im @@ -0,0 +1,96 @@ +############################################################################## +# Thai IM Character Map +# Preliminary test version +# $Id$ + +# Thai script +section + +0E01 d - +0E02 - - +0E03 \ - +0E04 8 - +0E05 | - +0E06 S - +0E07 ' - +0E08 0 - +#0E09 . - +0E0A = - +0E0B : - +0E0C G - +0E0D P - +0E0E E - +0E0F D - +0E10 { - +0E11 R - +0E12 < - +0E13 I - +0E14 f - +0E15 9 - +0E16 5 - +0E17 m - +0E18 T - +0E19 o - +0E1A [ - +0E1B x - +0E1C z - +0E1D / - +0E1E r - +0E1F a - +0E20 4 - +0E21 , - +0E22 p - +#0E23 . - +0E24 A - +0E25 ] - +0E26 ? - +0E27 ; - +0E28 L - +0E29 K - +0E2A l - +0E2B s - +0E2C > - +#0E2D . - +0E2E V - +0E2F O - +0E30 t - +0E31 y - +0E32 k - +0E33 e - +0E34 b - +0E35 u - +0E36 7 - +0E37 n - +0E38 6 - +#0E39 . - +0E3A B - +0E3F & - +0E40 g - +0E41 c - +0E42 F - +0E43 . - +0E44 w - +0E45 1 - +0E46 q - +0E47 H - +0E48 j - +0E49 h - +0E4A U - +0E4B J - +#0E4C . - +#0E4D . - +#0E4E . - +#0E4F . - +0E50 Q - +0E51 @ - +0E52 # - +0E53 $ - +0E54 % - +0E55 * - +0E56 ( - +0E57 ) - +0E58 _ - +0E59 + - +#0E5A . - +#0E5B . - +# vim:ts=12 diff --git a/src/im.c b/src/im.c index ad18d39c8..ed95eb583 100644 --- a/src/im.c +++ b/src/im.c @@ -60,6 +60,7 @@ enum { IM_TIP_HIRAGANA, IM_TIP_KATAKANA, IM_TIP_HANGUL, + IM_TIP_THAI, NUM_IM_TIPS }; @@ -70,7 +71,8 @@ static const char* const im_tip_text[NUM_IM_TIPS] = gettext_noop("English"), gettext_noop("Hiragana"), gettext_noop("Katakana"), - gettext_noop("Hangul") + gettext_noop("Hangul"), + gettext_noop("Thai") }; @@ -693,6 +695,192 @@ static int im_event_c(IM_DATA* im, SDL_keysym ks) } +/** +* Thai IM. +* +* @see im_read +*/ +static int im_event_th(IM_DATA* im, SDL_keysym ks) +{ + static const char* lang_file = IMDIR "th.im"; + enum { SEC_ENGLISH, SEC_THAI, SEC_TOTAL }; + + static CHARMAP cm; + + + /* Handle event requests */ + switch(im->request) { + case 0: break; + + case IM_REQ_FREE: /* Free allocated resources */ + charmap_free(&cm); + /* go onto full reset */ + + case IM_REQ_RESET_FULL: /* Full reset */ + cm.section = SEC_ENGLISH; + im->tip_text = im_tip_text[IM_TIP_ENGLISH]; + /* go onto soft reset */ + + case IM_REQ_RESET_SOFT: /* Soft reset */ + im->s[0] = L'\0'; + im->buf[0] = L'\0'; + im->redraw = 0; + cm.match_count = 0; + cm.match_is_final = 0; + cm.match_state = &cm.sections[cm.section]; + cm.match_state_prev = &cm.sections[cm.section]; + break; + + case IM_REQ_INIT: /* Initialization */ + charmap_init(&cm); + + if(charmap_load(&cm, lang_file)) { + fprintf(stderr, "Unable to load %s, defaulting to im_event_c\n", lang_file); + im->lang = LANG_DEFAULT; + return im_event_c(im, ks); + } + + im_fullreset(im); + + #ifdef DEBUG + printf("IM: Loaded '%s'\n", lang_file); + #endif + break; + } + if(im->request != IM_REQ_TRANSLATE) return 0; + + + /* Discard redraw characters, so they can be redrawn */ + if((int)wcslen(im->s) < im->redraw) im->redraw = wcslen(im->s); + wcs_lshift(im->s, (wcslen(im->s) - im->redraw) ); + + + /* Handle keys */ + switch(ks.sym) { + /* Keys to ignore */ + case SDLK_NUMLOCK: case SDLK_CAPSLOCK: case SDLK_SCROLLOCK: + case SDLK_LSHIFT: case SDLK_RSHIFT: + case SDLK_LCTRL: case SDLK_RCTRL: + case SDLK_LALT: + case SDLK_LMETA: case SDLK_RMETA: + case SDLK_LSUPER: case SDLK_RSUPER: + case SDLK_MODE: case SDLK_COMPOSE: + break; + + /* Right-Alt mapped to mode-switch */ + case SDLK_RALT: + cm.section = (++cm.section % SEC_TOTAL); /* Change section */ + im_softreset(im); /* Soft reset */ + + /* Set tip text */ + switch(cm.section) { + case SEC_ENGLISH: im->tip_text = im_tip_text[IM_TIP_ENGLISH]; break; + case SEC_THAI: im->tip_text = im_tip_text[IM_TIP_THAI]; break; + } + break; + + /* Enter finalizes previous redraw */ + case SDLK_RETURN: + if(im->redraw <= 0) { + im->s[0] = L'\r'; + im->s[1] = L'\0'; + } + im->buf[0] = L'\0'; + im->redraw = 0; + break; + + /* Actual character processing */ + default: + /* English mode */ + if(cm.section == SEC_ENGLISH) { + im->s[0] = ks.unicode; + im->s[1] = L'\0'; + im->buf[0] = L'\0'; + } + /* Thai mode */ + else { + wchar_t u = ks.unicode; + + im->s[0] = L'\0'; /* Zero-out output string */ + wcsncat(im->buf, &u, 1); /* Copy new character */ + + /* Translate the characters */ + im->redraw = 0; + while(1) { + const wchar_t* us = charmap_search(&cm, im->buf); + #ifdef IM_DEBUG + wprintf(L" [%8ls] [%8ls] %2d %2d\n", im->s, im->buf, wcslen(im->s), wcslen(im->buf)); + #endif + + /* Match was found? */ + if(us && wcslen(us)) { + #ifdef IM_DEBUG + wprintf(L" 1\n"); + #endif + + wcscat(im->s, us); + + /* Final match */ + if(cm.match_is_final) { + wcs_lshift(im->buf, cm.match_count); + cm.match_count = 0; + cm.match_is_final = 0; + } + /* May need to be overwritten next time */ + else { + im->redraw += wcslen(us); + break; + } + } + /* No match, but more data is in the buffer */ + else if(wcslen(im->buf) > 0) { + /* If the input character has no state, it's its own state */ + if(cm.match_count == 0) { + #ifdef IM_DEBUG + wprintf(L" 2a\n"); + #endif + wcsncat(im->s, im->buf, 1); + wcs_lshift(im->buf, 1); + cm.match_is_final = 0; + } + /* If the matched characters didn't consume all, it's own state */ + else if((size_t)cm.match_count != wcslen(im->buf)) { + #ifdef IM_DEBUG + wprintf(L" 2b (%2d)\n", cm.match_count); + #endif + wcsncat(im->s, im->buf, 1); + wcs_lshift(im->buf, 1); + cm.match_is_final = 0; + } + /* Otherwise it's just a part of a future input */ + else { + #ifdef IM_DEBUG + wprintf(L" 2c (%2d)\n", cm.match_count); + #endif + wcscat(im->s, im->buf); + cm.match_is_final = 0; + im->redraw += wcslen(im->buf); + break; + } + } + /* No match and no more data in the buffer */ + else { + #ifdef IM_DEBUG + wprintf(L" 3\n"); + #endif + break; + } + + /* Is this the end? */ + if(cm.match_is_final) break; + } + } + } + + return im->redraw; +} + + /** * Japanese IM. * @@ -1193,6 +1381,7 @@ void im_init(IM_DATA* im, int lang) /* ADD NEW LANGUAGE SUPPORT HERE */ im_event_fns[LANG_JA] = &im_event_ja; im_event_fns[LANG_KO] = &im_event_ko; + im_event_fns[LANG_TH] = &im_event_th; im_initialized = 1; }