Logo Search packages:      
Sourcecode: hanterm-classic version File versions  Download package

automata.c

/*
   Hangul Automata

   Written by Song Jaekyung
 */

#include "ptyx.h"
#include "data.h"
#include "hangul.h"

extern void HideCursor();

static int ascii(int, char *);

int hangul_state;
Char temp_hangul[8];
int (*converter) ();
static int f, m, l;

#define push(x)   ( stack[ sp++ ] = (x) )
#define pop()     ( stack[ --sp ] )

/* dvorak 자판 table */
static int table_dvorak_layout[] =
{
  '!',  'Q',  '#',  '$',  '%',  '&',    /* ! " # $ % & */
  'q',  '(',  ')',  '*',  '}',  'w',    /* ' ( ) * + , */
  '\'', 'e',  '[',  '0',  '1',  '2',    /* - . / 0 1 2 */
  '3',  '4',  '5',  '6',  '7',  '8',    /* 3 4 5 6 7 8 */
  '9',  'Z',  'z',  'W',  ']',  'E',    /* 9 : ; < = > */
  '{',  '@',  'A',  'N',  'I',  'H',    /* ? @ A B C D */
  'D',  'Y',  'U',  'J',  'G',  'C',    /* E F G H I J */
  'V',  'P',  'M',  'L',  'S',  'R',    /* K L M N O P */
  'X',  'O',  ':',  'K',  'F',  '>',    /* Q R S T U V */
  '<',  'B',  'T',  '?',  '-',  '\\',   /* W X Y Z [ \ */
  '=',  '^',  '"',  '`',  'a',  'n',    /* ] ^ _ ` a b */
  'i',  'h',  'd',  'y',  'u',  'j',    /* c d e f g h */
  'g',  'c',  'v',  'p',  'm',  'l',    /* i j k l m n */
  's',  'r',  'x',  'o',  ';',  'k',    /* o p q r s t */
  'f',  '.',  ',',  'b',  't',  '/',    /* u v w x y z */
  '_',  '|',  '+',  '~',                /* { | } ~ */
};

/* table_for_3 에서 사용될 flag: int type이 32bit 이상이어야 함 */
/* F_WC: wide character는 반드시 2바이트 조합형 코드(KSSM)로 표기해야 함 */
#define     F_F   0x010000                /* 초성 */
#define F_M 0x020000                /* 중성 */
#define F_L 0x040000                /* 종성 */
#define F_A 0x080000                /* ASCII */
#define F_WC    0x100000                /* wide(2 byte) character */

/* 세벌식 390자판 */
static unsigned int table_for_390_qwerty[] =
{
  24 | F_L, '"' | F_A, '#' | F_A, '$' | F_A, '%' | F_A, '&' | F_A,      /* ! " # $ % & */
  18 | F_F, '(' | F_A, ')' | F_A, '*' | F_A, '+' | F_A, ',' | F_A,      /* ' ( ) * + , */
  '-' | F_A, '.' | F_A, 13 | F_M, 17 | F_F, 29 | F_L, 22 | F_L,         /* - . / 0 1 2 */
  19 | F_L, 19 | F_M, 26 | F_M, 5 | F_M, 12 | F_M, 28 | F_M,            /* 3 4 5 6 7 8 */
  20 | F_M, ':' | F_A, 9 | F_F, '2' | F_A, '=' | F_A, '3' | F_A,  /* 9 : ; < = > */
  '?' | F_A, '@' | F_A, 8 | F_L, '!' | F_A, 11 | F_L, 10 | F_L,         /* ? @ A B C D */
  26 | F_L, 3 | F_L, '/' | F_A, 39 | F_A, '8' | F_A, '4' | F_A,         /* E F G H I J */
  '5' | F_A, '6' | F_A, '1' | F_A, '0' | F_A, '9' | F_A, '>' | F_A,     /* K L M N O P */
  28 | F_L, 6 | F_M, 7 | F_L, ';' | F_A, '7' | F_A, 16 | F_L,           /* Q R S T U V */
  27 | F_L, 20 | F_L, '<' | F_A, 25 | F_L, '[' | F_A, 92 | F_A,         /* W X Y Z [ \ */
  ']' | F_A, '^' | F_A, '_' | F_A, '`' | F_A, 23 | F_L, 20 | F_M, /* ] ^ _ ` a b */
  10 | F_M, 29 | F_M, 11 | F_M, 3 | F_M, 27 | F_M, 4 | F_F,       /* c d e f g h */
  8 | F_F, 13 | F_F, 2 | F_F, 14 | F_F, 20 | F_F, 11 | F_F,       /* i j k l m n */
  16 | F_F, 19 | F_F, 21 | F_L, 4 | F_M, 5 | F_L, 7 | F_M,        /* o p q r s t */
  5 | F_F, 13 | F_M, 9 | F_L, 2 | F_L, 7 | F_F, 17 | F_L,         /* u v w x y z */
  '{' | F_A, '|' | F_A, '}' | F_A, '~' | F_A,                     /* { | } ~ */
};

/* 세벌식 최종(391)자판: qwerty */
static unsigned int table_for_3final_qwerty[] =
{
  3 | F_L, 0xD934 | F_WC, 24 | F_L, 15 | F_L, 14 | F_L, 0xD940 | F_WC, /* ! " # $ % & */
  18 | F_F, '\'' | F_A, '~' | F_A, 0xD941 | F_WC, '+' | F_A, ',' | F_A, /* ' ( ) * + , */
  ')' | F_A, '.' | F_A, 13 | F_M, 17 | F_F, 29 | F_L, 22 | F_L,         /* - . / 0 1 2 */
  19 | F_L, 19 | F_M, 26 | F_M, 5 | F_M, 12 | F_M, 28 | F_M,            /* 3 4 5 6 7 8 */
  20 | F_M, '4' | F_A, 9 | F_F, ',' | F_A, '>' | F_A, '.' | F_A,  /* 9 : ; < = > */
  '!' | F_A, 10 | F_L, 8 | F_L, '?' | F_A, 26 | F_L, 12 | F_L,          /* ? @ A B C D */
  6 | F_L, 11 | F_L, 6 | F_M, '0' | F_A, '7' | F_A, '1' | F_A,          /* E F G H I J */
  '2' | F_A, '3' | F_A, '"' | F_A, '-' | F_A, '8' | F_A, '9' | F_A,     /* K L M N O P */
  28 | F_L, 16 | F_L, 7 | F_L, 13 | F_L, '6' | F_A, 4 | F_L,            /* Q R S T U V */
  27 | F_L, 20 | F_L, '5' | F_A, 25 | F_L, '(' | F_A, ':' | F_A,  /* W X Y Z [ \ */
  '<' | F_A, '=' | F_A, ';' | F_A, '*' | F_A, 23 | F_L, 20 | F_M, /* ] ^ _ ` a b */
  10 | F_M, 29 | F_M, 11 | F_M, 3 | F_M, 27 | F_M, 4 | F_F,       /* c d e f g h */
  8 | F_F, 13 | F_F, 2 | F_F, 14 | F_F, 20 | F_F, 11 | F_F,       /* i j k l m n */
  16 | F_F, 19 | F_F, 21 | F_L, 4 | F_M, 5 | F_L, 7 | F_M,        /* o p q r s t */
  5 | F_F, 13 | F_M, 9 | F_L, 2 | F_L, 7 | F_F, 17 | F_L,         /* u v w x y z */
  '%' | F_A, '\\' | F_A, '/' | F_A, 0xD968 | F_WC,                       /* { | } ~ */
};

/* table_for_2 에서 사용될 flag */
#define     F_C_F 0x010000U         /* 자음 - 초성전용 */
#define F_C_L     0x020000U         /* 자음 - 종성: 종성전용 자음은 없음 */
#define F_C_C     0x030000U         /* 자음 - 초, 종성 겸용 */
#define F_V 0x040000U         /* 모음 */
/* ASCII문자는 공통으로 쓰임 */

/* 2벌식 자판 변환: 종성은 lcon()에서 다시 처리함 */
static unsigned int table_for_2_qwerty[] =
{
/* !          "          #          $          %          & */
  '!' | F_A, '"' | F_A, '#' | F_A, '$' | F_A, '%' | F_A, '&' | F_A,
/* '          (          )          *          +          , */
  '\'' | F_A, '(' | F_A, ')' | F_A, '*' | F_A, '+' | F_A, ',' | F_A, 
/* -          .          /          0          1          2 */
  '-' | F_A, '.' | F_A, '[' | F_A, '0' | F_A, '1' | F_A, '2' | F_A, 
/* 3          4          5          6          7          8 */
  '3' | F_A, '4' | F_A, '5' | F_A, '6' | F_A, '7' | F_A, '8' | F_A,
/* 9          :          ;          <          =          > */
  '9' | F_A, ':' | F_A, ';' | F_A, '<' | F_A, '=' | F_A, '>' | F_A,
/* ?          @          A          B          C          D */
  '?' | F_A, '@' | F_A, 'A' | F_A, 'B' | F_A, 'C' | F_A, 'D' | F_A,
/* E          F          G          H          I          J */
  6 | F_C_F, 'F' | F_A, 'G' | F_A, 'H' | F_A, 'I' | F_A, 'J' | F_A,
/* K          L          M          N          O          P */
  'K' | F_A, 'L' | F_A, 'M' | F_A, 'N' | F_A, 6 | F_V, 12 | F_V,
/* Q          R          S          T          U          V */
  10 | F_C_F, 3 | F_C_C, 'S' | F_A, 12 | F_C_C, 'U' | F_A, 'V' | F_A,
/* W          X          Y          Z          [          \ */
  15 | F_C_F, 'X' | F_A, 'Y' | F_A, 'Z' | F_A, '[' | F_A, '\\' | F_A,
/* ]          ^          _          `          a          b */
  ']' | F_A, '^' | F_A, '_' | F_A, '`' | F_A, 8 | F_C_C, 26 | F_V,
/* c          d          e          f          g          h */
  16 | F_C_C, 13 | F_C_C, 5 | F_C_C, 7 | F_C_C, 20 | F_C_C, 13 | F_V,
/* i          j          k          l          m          n */
  5 | F_V, 7 | F_V, 3 | F_V, 29 | F_V, 27 | F_V, 20 | F_V,
/* o          p          q          r          s          t */
  4 | F_V, 10 | F_V, 9 | F_C_C, 2 | F_C_C, 4 | F_C_C, 11 | F_C_C,
/* u          v          w          x          y          z */
  11 | F_V, 19 | F_C_C, 14 | F_C_C, 18 | F_C_C, 19 | F_V, 17 | F_C_C,
/* {          |          }          ~ */
  '{' | F_A, '|' | F_A, '}' | F_A, '~' | F_A,
};

/* 3 벌식에서 영문자 -> 초성 변환
   결과: 초성이 아니면 0
 */
static int
fcon3 (c)
     int c;
{
  if (c >= '!' && c <= '~')
    {
      if (term->screen.keyboard == 391)
        {
          if (table_for_3final_qwerty[c - '!'] & F_F)
            return table_for_3final_qwerty[c - '!'] & 0xff;
        }
      else
        {
          if (table_for_390_qwerty[c - '!'] & F_F)
            return table_for_390_qwerty[c - '!'] & 0xff;
        }
    }
  return 0;
}

/* 3 벌식에서 영문자 -> 중성 변환
   결과: 중성이 아니면 0
 */
static int
vow3 (c)
     int c;
{
  if (c >= '!' && c <= '~')
    {
      if (term->screen.keyboard == 391)
        {
          if (table_for_3final_qwerty[c - '!'] & F_M)
            return table_for_3final_qwerty[c - '!'] & 0xff;
        }
      else
        {
          if (table_for_390_qwerty[c - '!'] & F_M)
            return table_for_390_qwerty[c - '!'] & 0xff;
        }
    }
  return 0;
}

/* 3 벌식에서 영문자 -> 받침 변환
   결과: 받침이 아니면 0
 */
static int
lcon3 (c)
     int c;
{
  if (c >= '!' && c <= '~')
    {
      if (term->screen.keyboard == 391)
        {
          if (table_for_3final_qwerty[c - '!'] & F_L)
            return table_for_3final_qwerty[c - '!'] & 0xff;
        }
      else
        {
          if (table_for_390_qwerty[c - '!'] & F_L)
            return table_for_390_qwerty[c - '!'] & 0xff;
        }
    }
  return 0;
}

/* 3 벌식에서 (현재초성, 입력영문) -> 복합초성 처리 */
static int
comfcon3_qwerty (v, c)
     int v, c;
{
#ifdef DELETED
  switch (v)
    {
    case 2:             /* ㄱ */
      switch (c)
      {
      case 'k':         /* ㄱ */
        return 3;       /* ㄲ */
      }
      break;
    case 5:             /* ㄷ */
      switch (c)
      {
      case 'u':
        return 6;       /* ㄸ */
      }
      break;
    case 9:             /* ㅂ */
      switch (c)
      {
      case ';':
        return 10;
      }
      break;
    case 11:                  /* ㅅ */
      switch (c)
      {
      case 'n':
        return 12;
      }
      break;
    case 14:                  /* ㅈ */
      switch (c)
      {
      case 'l':
        return 15;
      }
    }
#else
  if (v == 2 && c == 'k') return 3;
  if (v == 5 && c == 'u') return 6;
  if (v == 9 && c == ';') return 10;
  if (v == 11 && c == 'n') return 12;
  if (v == 14 && c == 'l') return 15;
#endif
  return 0;
}

/* 3 벌식에서 (현재모음, 입력 영문) -> 복합 모음 처리 */
static int
comvow3_qwerty (v, c)
     int v, c;
{
  switch (v)
    {
    case 13:                  /* ㅗ */
      switch (c)
      {
      case 'f':         /* ㅗㅏ */
        return 14;
      case 'r':         /* ㅗㅐ */
        return 15;
      case 'd':         /* ㅗㅣ */
        return 18;
      }
      break;
    case 20:                  /* ㅜ */
      switch (c)
      {
      case 't':         /* ㅜㅓ */
        return 21;
      case 'c':         /* ㅜㅔ */
        return 22;
      case 'd':         /* ㅜㅣ */
        return 23;
      }
      break;

      /* 3 벌식 자판은 ㅡㅣ 가 있으므로 ... */
    }
  return 0;
}

/* 3 벌식에서 (현재 받침, 영문자 입력) -> 받침 */
static int
comcon3_qwerty (k, c)
     int k;
     int c;
{
  switch (k)
    {
    case 2:             /* ㄱ */
      switch (c)
      {
      case 'x':
        return 3;       /* ㄱㄱ */
      case 'q':
        return 4;       /* ㄱㅅ */
      }
      break;
    case 5:             /* ㄴ */
      if (term->screen.keyboard == 391)
        {
          switch (c)
          {
            case '#':         /* ㄴㅈ */
              return 6;
            case '1':
              return 7; /* ㄴㅎ */
          }
        }
      else
        {
          switch (c)
          {
            case '!':         /* ㄴㅈ */
              return 6;
            case '1':
              return 7; /* ㄴㅎ */
          }
        }
      break;
    case 9:             /* ㄹ */
      switch (c)
      {
      case 'x':         /* ㄹㄱ */
        return 10;
      case 'z':         /* ㄹㅁ */
        return 11;
      case '3':         /* ㄹㅂ */
        return 12;
      case 'q':         /* ㄹㅅ */
        return 13;
      case 'W':         /* ㄹㅌ */
        return 14;
      case 'Q':         /* ㄹㅍ */
        return 15;
      case '1':         /* ㄹㅎ */
        return 16;
      }
      break;
    case 19:
      switch (c)
      {
      case 'q':         /* ㅂㅅ */
        return 20;
      }
      break;
    }
  return 0;
}

/* 3 벌식에서 영문자 처리 */
static int
ascii3 (c, buf)
     int c;
     char *buf;
{
  if (c >= '!' && c <= '~')
    {
      if (term->screen.keyboard == 391)
        {
          if (table_for_3final_qwerty[c - '!'] & F_A)
            c = table_for_3final_qwerty[c - '!'] & 0xffff;
          else if (table_for_3final_qwerty[c - '!'] & F_WC)
            c = table_for_3final_qwerty[c - '!'] & 0xffffffff;
        }
      else
        {
          if (table_for_390_qwerty[c - '!'] & F_A)
            c = table_for_390_qwerty[c - '!'] & 0xffff;
          else if (table_for_390_qwerty[c - '!'] & F_WC)
            c = table_for_390_qwerty[c - '!'] & 0xffffffff;
        }
    }
  return ascii (c, buf);
}

/* 2 벌식에서 영문자 -> 조합형 초성 변환
   결과: 초성이 아니면 0
 */
static int
fcon (c)
     int c;
{
  /* 초성의 범위 검색 */
  if (c < '"' || c > 'z')
    return 0;

  if (table_for_2_qwerty[c - '!'] & F_C_F)
    return table_for_2_qwerty[c - '!'] & 0xff;

  return 0;
}

/* 2 벌식에서 영문자 -> 중성 변환
   결과: 중성이 아니면 0
 */
static int
vow (c)
     int c;
{
  /* 모음의 범위 검색 */
  if (c < 'L' || c > 'y')
    return 0;

  if (table_for_2_qwerty[c - '!'] & F_V)
    return table_for_2_qwerty[c - '!'] & 0xff;

  return 0;
}

/* 2벌식에서 영문자 -> 받침 변환
   결과: 받침이 아니면 0
 */
static int
lcon (c)
     int c;
{
  static unsigned int table_qwerty[] =
  {
    /* !   "   #   $   %   &   '   (   )   *   +   ,   -   .   / */
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    /* 0   1   2   3   4   5   6   7   8   9   :   ;   <   =   > */
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    /* ?   @   A   B   C   D   E   F   G   H   I   J   K   L   M */
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    /* N   O   P   Q   R   S   T   U   V   W   X   Y   Z   [   \ */
       0,  0,  0,  0,  3,  0,  22, 0,  0,  0,  0,  0,  0,  0,  0,
    /* ]   ^   _   `   a   b   c   d   e   f   g   h   i   j   k */
       0,  0,  0,  0,  17, 0,  25, 23, 8,  9,  29, 0,  0,  0,  0,
    /* l   m   n   o   p   q   r   s   t   u   v   w   x   y   z */
       0,  0,  0,  0,  0,  19, 2,  5,  21, 0,  28, 24, 27, 0,  26
  };

  /* 종성의 범위 검색 */
  if (c < 'R' || c > 'z')
    return 0;

  if (table_for_2_qwerty[c - '!'] & F_C_L)
    return table_qwerty[c - '!'];

  return 0;
}

/* 2 벌식에서 (현재 받침, 영문자 입력) -> 받침 변환 */
static int
comcon_qwerty (k, c)
     int k;
     int c;
{
  switch (k)
    {
    case 2:             /* ㄱ */
      switch (c)
      {
      case 't':
        return 4;       /* ㄱㅅ */
      }
      break;
    case 5:             /* ㄴ */
      switch (c)
      {
      case 'w':         /* ㄴㅈ */
        return 6;
      case 'g':         /* ㄴㅎ */
        return 7;
      }
      break;
    case 9:             /* ㄹ */
      switch (c)
      {
      case 'r':         /* ㄹㄱ */
        return 10;
      case 'a':         /* ㄹㅁ */
        return 11;
      case 'q':         /* ㄹㅂ */
        return 12;
      case 't':         /* ㄹㅅ */
        return 13;
      case 'x':         /* ㄹㅌ */
        return 14;
      case 'v':         /* ㄹㅍ */
        return 15;
      case 'g':         /* ㄹㅎ */
        return 16;
      }
      break;
    case 19:                  /* ㅂ */
      switch (c)
      {
      case 't':         /* ㅂㅅ */
        return 20;
      }
      break;
    }
  return 0;
}

/* 2벌식에서 (현재 중성, 영문 입력) -> 중성 변환 */
static int
comvow_qwerty (v, c)
     int v;
     int c;
{
  switch (v)
    {
    case 13:                  /* ㅗ */
      switch (c)
      {
      case 'k':         /* ㅗㅏ */
        return 14;
      case 'o':         /* ㅗㅐ */
        return 15;
      case 'l':         /* ㅗㅣ */
        return 18;
      }
      break;
    case 20:                  /* ㅜ */
      switch (c)
      {
      case 'j':         /* ㅜㅓ */
        return 21;
      case 'p':         /* ㅜㅔ */
        return 22;
      case 'l':         /* ㅜㅣ */
        return 23;
      }
      break;
    case 27:                  /* ㅡ */
      switch (c)
      {
      case 'l':         /* ㅡㅣ */
        return 28;
      }
      break;
    }
  return 0;
}

/* 세벌식에서 영문 처리: 세벌식은 ascii3를 거쳐서 옴 */
static int
ascii (c, buf)
     int c;
     char *buf;
{
  static int f, m, l;

  if (c == -1)
    {
      if (hangul_state)
      hangul_state = 0;
      else
      {
        hangul_state = 1;
        f = 1;
        m = 2;
        l = 1;
      }
      show_status (&term->screen, 0, 0);
      return 0;
    }
  else if (c == -2)
    {                   /* flush output */
      f = 1;
      m = 2;
      l = 1;
      return 0;
    }
  else if (hangul_state && c == 27)      /* escape key */
    {
      hangul_state = 0;
      show_status (&term->screen, 0, 0);
      buf[0] = c;
      return 1;
    }
#ifdef USE_WON
  else if (hangul_state && c == '\\')
    {
      buf[0] = 0xa3;
      buf[1] = 0xdc;
      return 2;
    }
#endif
  else if (c & F_WC)              /* wide character */
    {
      buf[0] = (c & 0xFF00) >> 8; /* first byte */
      buf[1] = (c & 0xFF);        /* second byte */
      /* 모든 코드를 지원하기 위해서 
       * 3바이트 코드(내부기본형)으로 바꾼후 다시 출력할 코드로 바꾼다. */
      convert_johab_to_3((unsigned char *)buf, &f, &m, &l);
      (*converter) (f, m, l, buf);
      return 2;
    }
  else
    {
      buf[0] = c;
      return 1;
    }
}

/* (영문 입력) -> 완성형 코드 문자열
   c : 영문 ASCII
   -1 : 한영 toggle
   -2 : 현재 구성중인 한글을 돌려 준다. flush.
   buf : 완성된 글자의 KS C 5601 - 1992 코드
   결과: buf 에 몇 바이트나 들어 갔는가
   외부 참조: display_temp() : 현재 구성중인 한글을 화면에 그려 준다.
   term->screen.keyboard : 자판 결정. 2 = 2벌식, 3 = 3벌식
   term->screen.use_dvorak_layout : 영문자판배열. False = qwerty, True = dvorak
   convert_3_to_ks() : 조합->완성 변환. 변환된 후 문자열 길이를
   돌려 줘야 한다. 2 또는 8
   show_status() : 한글 상태 인지 영문 상태인지 표시한다.
 */
int
hangul_automata (c, buf)
     int c;             /* input character */
     char *buf;
{
  static int sp, pc, stack[10];
  int t, t2, rs;

  extern int font_ks_mode;
  int ks_only;

  /* function pointer for english keyboard layout */
  static int (*comfcon3)();
  static int (*comvow3)();
  static int (*comcon3)();
  static int (*comcon)();
  static int (*comvow)();

  ks_only = font_ks_mode != -1 || term->screen.code == C_WANSUNG;

  if (hangul_state == 0)      /* 영문 상태 */
    return ascii (c, buf);

  /* dvorak 배열을 qwerty자판처럼 바꾸어 줌 */
  if (term->screen.use_dvorak_layout && c >= '!' && c <= '~')
    {
      c = table_dvorak_layout[c - '!']; 
    }

  /* set function pointer: 3.1.5rc1에서 임시로 썼음. 곧 복구 예정 */
  comcon = comcon_qwerty;
  comvow = comvow_qwerty;
  comfcon3 = comfcon3_qwerty;
  comvow3 = comvow3_qwerty;
  comcon3 = comcon3_qwerty;

  if (term->screen.keyboard == 2)
    {                   /* 2 벌식 */
      switch (hangul_state)
      {
      case 1:           /* 초성을 기다림 */
        sp = 0;
        if (t = fcon (c))
          {
            display_temp (t, 2, 1);
            f = t;
            hangul_state = 2;
            return 0;
          }
        else if (t = vow (c))
          {
            display_temp (1, t, 1);
            f = 1;
            m = t;
            push (2);
            hangul_state = 3;
            return 0;
          }
        else
          {
            f = 1;
            m = 2;
            l = 1;
            display_temp (-1, -1, -1);
            return ascii (c, buf);
          }
        break;
      case 2:           /* 중성 기다림 */
        if (t = vow (c))
          {
            if (in_ks(f, t, 1))
            {
              display_temp (f, t, 1);
              push (2);
              m = t;
              hangul_state = 3;
              return 0;
            }
            else
            {
              rs = (*converter) (f, 2, 1, buf);
              display_temp (f = 1, m = t, 1);
              sp = 0;
              push(2);
              hangul_state = 3;
              return rs;
            }
          }
        else if (t = fcon (c))
          {
            rs = (*converter) (f, 2, 1, buf);
            display_temp (t, 2, 1);
            sp = 0;
            f = t;
            hangul_state = 2;
            return rs;
          }
        else if (c == '\b')
          {
            display_temp (-1, -1, -1);
            hangul_state = 1;
            return 0;
          }
        else
          {
            rs = (*converter) (f, 2, 1, buf);
            display_temp (-1, -1, -1);
            hangul_state = 1;
            return ascii (c, buf + rs) + rs;
          }
        break;
      case 3:           /* 종성 기다림 */
        if ((t = lcon (c)) && (!ks_only || in_ks(f, m, t)))
          {
            display_temp (f, m, t);
            push (1);
            l = t;
            pc = c;
            hangul_state = 4;
            return 0;
          }
        else if ((t = comvow (m, c)) && (!ks_only || in_ks(f, t, 1)))
          {
            display_temp (f, t, 1);
            push (m);
            m = t;
            return 0;
          }
        else if (t = fcon (c))
          {
            rs = (*converter) (f, m, 1, buf);
            display_temp (t, 2, 1);
            f = t;
            sp = 0;
            hangul_state = 2;
            return rs;
          }
        else if (t = vow (c))
          {
            rs = (*converter) (f, m, 1, buf);
            f = 1;
            m = t;
            l = 1;
            display_temp (f, m, l);
            sp = 0;
            push (2);
            return rs;
          }
        else if (c == '\b')
          {             /* back space */
            m = pop ();
            if (m == 2)
            {           /* we extracted all */
              if (f == 1)
                {
                  hangul_state = 1;
                  f = -1;
                }
              else
                {
                  hangul_state = 2;
                }
            }
            display_temp (f, m, 1);
            return 0;
          }
        else
          {
            rs = (*converter) (f, m, 1, buf);
            display_temp (-1, -1, -1);
            sp = 0;
            hangul_state = 1;
            return ascii (c, buf + rs) + rs;
          }
        break;
      case 4:           /* 복합 받침 기다림 */
        if( (t = comcon(l, c)) && (!ks_only || in_ks(f, m, t)))
          {
            display_temp (f, m, t);
            push (l);
            l = t;
            pc = c;
            return 0;
          }
        else if (t = vow (c))
          {
            if (!ks_only || in_ks(fcon(pc), t, 1))
            {
              rs = (*converter) (f, m, pop (), buf);
              display_temp (f = fcon (pc), m = t, 1);
              sp = 0;
              push (2);
              hangul_state = 3;
              return rs;
            }
            else
            {
              rs = (*converter) (f, m, l, buf);
              display_temp (f = 1, m = t, 1);
              sp = 0;
              push(2);
              hangul_state = 3;
              return rs;
            }
          }
        else if (t = fcon (c))
          {
            rs = (*converter) (f, m, l, buf);
            display_temp (t, 2, 1);
            f = t;
            sp = 0;
            hangul_state = 2;
            return rs;
          }
        else if (c == '\b')
          {             /* back space */
            display_temp (f, m, l = pop ());
            if (l == 1)
            hangul_state = 3;
            return 0;
          }
        else
          {
            rs = (*converter) (f, m, l, buf);
            display_temp (-1, -1, -1);
            sp = 0;
            hangul_state = 1;
            return ascii (c, buf + rs) + rs;
          }
        break;
      }
    }
  else if (term->screen.keyboard == 390 || term->screen.keyboard == 391)
    {                   /* 3 벌식 */
      if (t = fcon3 (c))
      {
        t2 = 0;
        if (f > 1 && !(t2 = comfcon3 (f, c)) || m > 2 || l > 1)
          {             /* 중성이 있거나 받침이 있음 */
            rs = (*converter) (f, m, l, buf);
            sp = 0;
            m = 2;
            l = 1;
          }
        else
          {
            if (t2)
            {
              t = t2;
            }
            rs = 0;
          }
        f = t;
        display_temp (f, m, l);
        push ((f << 10) | (m << 5) | l);
        return rs;
      }
      else if (t = vow3 (c))
      {
        t2 = 0;
        if (m > 2 && !(t2 = comvow3 (m, c)) || l > 1)
          {             /* 받침이 있음 */
            rs = (*converter) (f, m, l, buf);
            sp = 0;
            f = 1;
            l = 1;
          }
        else
          {
            if (t2)
            {
              t = t2;
            }
            rs = 0;
          }
        m = t;
        display_temp (f, m, l);
        push ((f << 10) | (m << 5) | l);
        return rs;
      }
      else if (t = lcon3 (c))
      {
        t2 = 0;
        if (f > 1 && m < 3 || l > 1 && !(t2 = comcon3 (l, c)))
          {             /* 초성은 있고 중성이 없음 */
            rs = (*converter) (f, m, l, buf);
            sp = 0;
            f = 1;
            m = 2;
          }
        else
          {
            if (t2)
            {
              t = t2;
            }
            rs = 0;
          }
        l = t;
        display_temp (f, m, l);
        push ((f << 10) | (m << 5) | l);
        return rs;
      }
      else if (c == '\b')
      {
        if (sp > 0)
          {
            pop ();           /* 맨위의 글자는 버린다 */
            if (sp > 0)
            {
              t = stack[sp - 1];
              f = t >> 10;
              m = (t >> 5) & 0x1f;
              l = t & 0x1f;
              display_temp (f, m, l);
              return 0;
            }
            f = 1;
            m = 2;
            l = 1;
            display_temp (-1, -1, -1);
            return 0;
          }
        else
          {
            display_temp (-1, -1, -1);
            return ascii3 (c, buf);
          }
      }
      else
      {
        if (f > 1 || m > 2 || l > 1)
          {
            rs = (*converter) (f, m, l, buf);
            sp = 0;
            f = 1;
            m = 2;
            l = 1;
            display_temp (-1, -1, -1);
          }
        else
          {
            rs = 0;
          }
        return rs + ascii3 (c, buf + rs);
      }
    }
}

display_temp (f, m, l)
     int f, m, l;
{
  if (f < 0)
    {
      HideCursor ();
      temp_hangul[0] = 0;
    }
  else
    convert_3_to_johab (f, m, l, temp_hangul);
  ShowCursor ();
}

in_ks (f, m, t)
     int f, m, t;
{
  char buf[8];

  return convert_3_to_ks (f, m, t, buf) == 2;
}

Generated by  Doxygen 1.6.0   Back to index