예제 #1
0
/**
* IM-process a character.  This function simply looks up the language from
* IM and calls the appropriate im_event_<lang>() language-specific IM event
* handler.  im_event_c() is called by default if no language-specific
* function is specified for the specified language.
*
* @param im  IM-processed data to return to the caller function.
* @param ks  SDL_keysym typed on the keyboard.
*
* @return    The number of characters in im->s that should not be committed.
*            In other words, the returned number of characters at the end of
*            im->s should be overwritten the next time im_read is called.
*
* @see im_event_c()
* @see im_event_fns
*/
int im_read(IM_DATA* im, SDL_keysym ks)
{
//  im_event_fp = NULL;
  int redraw = 0;

  /* Sanity check */
  if(im->lang < 0 || im->lang >= NUM_LANGS) {
    fprintf(stderr, "im->lang out of range (%d), using default\n", im->lang);
    im->lang = LANG_DEFAULT;
  }

  /* Function pointer to the language-specific im_event_* function */
  im_event_fp = im_event_fns[im->lang];

  /* Run the language-specific IM or run the default C IM */
  if(im_event_fp)
    redraw = (*im_event_fp)(im, ks);
  else
    redraw = im_event_c(im, ks);

  #ifdef IM_DEBUG
  wprintf(L"* [%8ls] [%8ls] %2d %2d (%2d)\n", im->s, im->buf, wcslen(im->s), wcslen(im->buf), im->redraw);
  #endif

  return redraw;
}
예제 #2
0
파일: im.c 프로젝트: Daksh/tuxpaint-0.9.21
/**
* 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;
}
예제 #3
0
파일: im.c 프로젝트: Daksh/tuxpaint-0.9.21
/**
* Korean IM.
*
* @see im_read
*/
static int im_event_ko(IM_DATA* im, SDL_keysym ks)
{
  static const char* lang_file = IMDIR "ko.im";
  enum { SEC_ENGLISH, SEC_HANGUL, 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_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_LALT: 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_HANGUL:  im->tip_text = im_tip_text[IM_TIP_HANGUL]; break;
      }
      break;

    /* Backspace removes only a single buffered character */
    case SDLK_BACKSPACE:
      /* Delete one buffered character */
      if(wcslen(im->buf) > 0) {
        wcs_pull(im->buf, 1);
        if(im->redraw > 0) im->redraw--;
        ks.unicode = L'\0';
      }
      /* continue processing: */

    /* 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';
      }
      /* Hangul mode */
      else {
        wchar_t u = ks.unicode;
        wchar_t* bp = im->buf;

        im->s[0] = L'\0';                     /* Zero-out output string */
        wcsncat(bp, &u, 1);                   /* Copy new character */

        /* Translate the characters */
        im->redraw = 0;
        while(1) {
          const wchar_t* us = charmap_search(&cm, bp);
          #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)) {
            /* Final match */
            if(cm.match_is_final) {
              /* Batchim may carry over to the next character */
              if(cm.match_state->flag == 'b') {
                wchar_t next_char = bp[cm.match_count];

                /* If there is no more buffer, output it */
                if(cm.match_stats & MATCH_STAT_NOMOBUF) {
                  #ifdef IM_DEBUG
                  wprintf(L"    1a\n");
                  #endif

                  wcscat(im->s, us);          /* Output */
                  im->redraw += wcslen(us);  /* May need to re-eval next time */
                  bp += cm.match_count;       /* Keep buffer data for re-eval*/
                  cm.match_count = 0;
                  cm.match_is_final = 0;
                }
                /* If there is buffer data but it's not vowel, finalize it */
                else if(!im_event_ko_isvowel(&cm, next_char)) {
                  #ifdef IM_DEBUG
                  wprintf(L"    1b\n");
                  #endif

                  wcscat(im->s, us);     /* Output */
                  wcs_lshift(bp, cm.match_count);
                  cm.match_count = 0;
                  cm.match_is_final = 0;
                }
                /* If there is buffer and it's vowel, re-eval */
                else {
                  #ifdef IM_DEBUG
                  wprintf(L"    1c\n");
                  #endif

                  us = cm.match_state_prev->output;
                  wcscat(im->s, us);      /* Output */
                  cm.match_count--;       /* Matched all but one */
                  cm.match_is_final = 0;
                  wcs_lshift(bp, cm.match_count);
                }
              }
              /* No batchim - this is final */
              else {
                #ifdef IM_DEBUG
                wprintf(L"    1d\n");
                #endif

                wcscat(im->s, us);
                wcs_lshift(bp, cm.match_count);
                cm.match_count = 0;
                cm.match_is_final = 0;
              }
            }
            /* May need to be overwritten next time */
            else {
              #ifdef IM_DEBUG
              wprintf(L"    1e\n");
              #endif

              wcscat(im->s, us);
              im->redraw += wcslen(us);
              break;
            }
          }
          /* No match, but more data is in the buffer */
          else if(wcslen(bp) > 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, bp, 1);
              wcs_lshift(bp, 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(bp)) {
              #ifdef IM_DEBUG
              wprintf(L"    2b (%2d)\n", cm.match_count);
              #endif
              wcsncat(im->s, bp, 1);
              wcs_lshift(bp, 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, bp);
              cm.match_is_final = 0;
              im->redraw += wcslen(bp);
              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;
}