¥»¤å²­z xcin ¿é¤Jªk module ªº¬[ºc¡A¥H¤Î·s¼W module ªº¤èªk¡C

----------------------------------------
A. ¤º³¡¬[ºc (include/module.h, include/imodule.h, include/cinput.h, module.c):

   module ªº³]­p¥Øªº¬O§Æ±æ programmer ¥i¥H«Ü®e©ö¦a¥[¤J·sªº¿é¤Jªk¤ä´©¡A¦]
   ¦¹§Ú¤wºÉ¶q±N¥¦©î¦¨¨â­Ó³¡¤À:

	1. programmer interface (module.h)
	2. internal implementation (imodule.h)

   Programmer ¥i¥H§¹¥þ¤£²z·| internal ªº²Ó¸`¡A¥L¥u»Ý­n±N module.h ùØÀY©w
   ¸qªº module_t ¸ê®Æµ²ºc¶ñ¦n§Y¥i¡C¦ý¥i¯à¦³¨Ç¤H¹ï©ó internal ²Ó¸`¦³¿³½ì¡A
   ¬G¥»¸`¹ï¦¹µy§@»¡©ú¡C

   ©Ò¿×¡umodule ¸ü¤J©Î³Q®M¥Î¡v¨ä¹ê¬O¨â­Ó¶¥¬q¡A¥Î¥H¤Uªº¨Ò¤l»¡©ú:

   ¨Ò¦p¬Y¦ì¨Ï¥ÎªÌ«ö¤U ctrl+alt+1 ±Ò°Ê cj(­Ü¾e) ¿é¤Jªk¡A«h xcin ·|¨ì¨ä¤º³¡
   cinput ¦Cªí¥h§ä¸Ó¿é¤Jªk¨Ã±Ò°Ê¥¦¡A¨ä©w¸q¦p¤U:

=========================================================================
typedef struct cinput_s {
    char *modname;
    char *objname;
    imodule_t *inpmod;
} cinput_t;

cinput_t cinput[MAX_INP_ENTRY];
=========================================================================

   °²³] xcin ¸ò¾Ú rcfile ªº³]©w¡A¨Ï¥ÎªÌ¦³µù¥U¨Ï¥Î cj ¿é¤Jªk¡A¥B¸Ó¿é¤JªkÀ³
   ®M¥Î gen_inp module, ¨ä setkey ¬O 1, ¦ý¸Ó¿é¤JªkÁÙ¨S³Q¸ü¤J¡A«h cinput ªº
   ¤º®e¦p¤U:

	cinput[1].modname = "gen_inp";
	cinput[1].objname = "cj";
	cinput[1].inpmod = NULL;

   ¨ä¤¤ inpmod ¬O¯u¥¿¤w¸ü¤J¥B¤w®M¥Î cj ³o­Ó¿é¤Jªkªº module, ­Y¨ä­È¤£¬O NULL, 
   ªí¥Ü¸Ó¿é¤Jªk¤w¸g¸ü¤J§¹²¦¥B¥i¥H¨Ï¥Î¡A«h xcin ·|°¨¤W¨Ï¥Î¥¦¡C¤Ï¤§¡A xcin ±N
   ¶i¦æ±µ¤U¨Óªº¸ü¤J¤u§@¡C

   ³o®É xcin ·|¨ì tmodule_t *mod_templet; ³o­Ó list ¤¤´M§ä¬Ý¦³¨S¦³ "gen_inp"
   ³o­Ó module ¡u®M¼Ò¡v¡C tmodule_t ¬O©w¸q¦b imodule.h ¤¤¡AÄÝ©ó internal
   ªº³¡¤À¡C¦pªG§ä¨ì¤F¡A«hª½±µ®M¥Î¡A³o®Éµ{¦¡·|®Ú¾Ú tmodule_t ªº¸ê°T¡A²£¥Í
   ¤@­Ó imodule_t (©w¸q¦b imodule.h) ªºµ²ºc¡A¥¦¦³ conf data structer,
   object name ¬° "cj", §Yª½±µ®M¥Î cj ¿é¤Jªk¡C¥B cinput[1].inpmod ¤]·|«ü
   ¦V³o­Ó·s²£¥Í¥X¨Óªº imodule_t µ²ºc¡C

   ¸U¤@¦b mod_templet ¤¤§ä¤£¨ì "gen_inp" ªº¸Ü¡A´N­n¥Î dlopen() ¦ÛµwºÐªº 
   gen_inp.so Àɸü¤J¤F¡C¸ü¤J«á¡A¥¦´N·|¥[¤J mod_templet list ùØÀY¡AµM«á¦A
   °µ¥X¤@­Ó cj ¿é¤Jªkªº imodule_t ¨Ó¨Ï¥Î¡C

   ³oùثܭ«­nªº¬O: ¤@­Ó module ¤£¬O¤@­Ó¹B§@¹êÅé (object), ¥¦¥u¬O­Ó®M¼Ò¡A¬O
   ·Ç³Æ³Q¬Y­Ó¿é¤Jªk®³¨Ó®M¥Îªº¡A¤@­Ó module ®M¼Ò¥i¥H³Q¦hºØ¤£¦Pªº¿é¤Jªk®M¥Î¡C
   ¦]¦¹¡A¦b module ©w¸q¤§ªì¡A¨ä¥»¨­ªº¸ê®Æµ²ºc¬O¤£¦s¦bªº¡A¦Ó¬O­nµ¥¥¦³Q¬Y­Ó¿é
   ¤Jªk®M¥Î (§Y²£¥Í imodule_t) ®É¡A¨t²Î¤~·| malloc() ¤@¶ôªÅ¶¡µ¹¥¦°µ¸ê®Æµ²ºc¡A
   ¨Ã¥Ñ rcfile Ū¨ú¨t²ÎŪ¤J³]©w­È (½Ð¨£¥H¤U»¡©ú)¡C



----------------------------------------
B. ¸ê®Æµ²ºc (include/module.h):

   ¥Ñ©ó include/module.h ©w¸q¤F xcin module ¤¶­±¡A¦Ó include/xcintool.h «Å
   §i¤F xcin ¬ÛÃöªº¤u¨ã¨ç¦¡¡A³o¨â­Ó .h Àɳ£¬O¦b¼¶¼g xcin module ®É©Ò¥²¶·ªº¡A
   ¬°¤F¹ªÀy¤j®a¬° xcin ¼g·s¼Ò²Õ¡A§Ú­Ì¯S§O¶}©ñ³o¨â­Ó .h Àɪºª©Åv: ¾¨ºÞ¾ã­Ó
   xcin ®M¥óÄÝ©ó GPL, ¦ý¥ô¦ó¤H­Y»Ý­n¬° xcin ¼g·s¼Ò²Õ®É¡A¥L­Ì¥i¥H¥H¥ô¦ó§Î¦¡
   ¤Þ¥Î³o¨â­ÓÀɪº¤º®e¡A¦Ó¤£·|¼vÅT¨ì¥L­Ì©Ò¼gªº¼Ò²Õªºª©Åvª¬ºA¡C¸Ô¨£ CopyRight 
   ªºÁn©ú¡C

   ­n¥[¤J·sªº¿é¤Jªk module, ±z¥u­n¶ñ¦n¦p¤Uªº¸ê®Æµ²ºc¨Ã¼g¦n¬ÛÃöªº¨ç¦¡§Y¥i:

=================================  module.h  ==============================
typedef struct module_s  module_t;
struct module_s {
    char *name;
    char *version;
    char *comments;
    char **valid_objname;
    enum mtype module_type;

    int conf_size;
    int (*init) (void *conf, char *objname, xcin_rc_t *xc);
        /* called when IM first loaded & initialized. */
    int (*xim_init) (void *conf, inpinfo_t *inpinfo);
        /* called when trigger key occures to switch IM. */
    unsigned (*xim_end) (void *conf, inpinfo_t *inpinfo);
        /* called just before xim_init() to leave IM, not necessary */
    unsigned (*keystroke) (void *conf, inpinfo_t *inpinfo, keyinfo_t *keyinfo);
        /* called to input key code, and output chinese char. */
    int (*show_keystroke) (void *conf, simdinfo_t *simdinfo);
        /* called to show the key stroke */
    int (*terminate) (void *conf);
	/* called when xcin is going to exit. */
};
=============================================================================

   ½Ðª`·N¡A¥Ñ©ó xcin ±Ä¥Îªº¬O module ³Q¿é¤Jªk®M¥Î¡A¥[¤W¨C¤@­Ó IC (Input 
   Context, ½Ð¨£ structer ¤@¤åªº»¡©ú) ªº¿é¤Jª¬ºA©¼¦¹¿W¥ßªº³]­p¡A¬G¿é¤J
   ªk¦b xcin ¤¤©Ò§êºtªº¨¤¦â´N¦n¹³¬O¤@­Ó server, ¥¦ÀRÀR¦aµ¥«Ý¨Ó¦Û xcin
   ªº½Ð¨D¡A¨Ã°µ¥X¦^À³¡C¦]¦¹¡A©Ò¦³ªº¿é¤Jªk module ªº¤º³¡¸ê®Æµ²ºcÀ³¤À¨â­Ó
   ³¡¤À: ¸Ó¿é¤Jªkªº¤½¥Î³]©w¡A¥Ñ void *conf ÅܼƶǤJ¤W­zªº module ¨ç¦¡¤¤¡F
   ¥t¤@­Ó¬O¨C­Ó IC ªº¿é¤Jª¬ºA¸ê®Æ¡A³oùاڭ̨èS¦³±N¾ã­Ó IC µ²ºc¶Ç¤J module
   ¨ç¦¡ùØ¡A¨º¬O¦]¬° IC µ²ºcÁÙ²o¯A¨ì«Ü¦h»P XIM ¬ÛÃöªº²Ó¸`¡A¦Ó§Ú§Æ±æ¨C­Ó¿é
   ¤Jªk module ¥i¥H»P³o¨Ç²Ó¸`§¹¥þµLÃö¡A¬G¦b¦¹¬O±N inpinfo_t *inpinfo ¶Ç¤J
   (¹ï©ó show_keystroke ¦Ó¨¥¶Ç¤Jªº¬O simdinfo_t *simdinfo), inpinfo ³o­Ó
   ¸ê®Æµ²ºc¥]§t¤F¥Ø«e xcin ªºª¬ºA»P¿é¤Jªkªº¬ÛÃö¸ê°T¡A¬O¤GªÌ¶¡ªº·¾³qºÞ¹D¡C


   1. ¸Ó¿é¤Jªkªº¤½¥Î³]©w:

      ³o¨Ç³]©w¥D­n¬O±q rcfile Ū¨ú¨t²Îªº¸ê®Æ©Ò³]©wªº¡A¦P®É¤]¥i¥H¥Î¨Ó«O¦s
      xim_init() ©I¥s®É¨Ó¦Û xcin_rc_t *xc (§Y xcin_rc) ©Ò»Ýªº¸ê®Æ¡CÁ|¤@­Ó
      ¨Ò¤l:

============================================================================
(define cj
        '((SETKEY         1)
          (AUTO_COMPOSE   YES)
          (AUTO_UPCHAR    YES)
          (AUTO_FULLUP    NO)
          (SPACE_AUTOUP   NO)
          (SELKEY_SHIFT   NO)
          (SPACE_IGNORE   NO)
          (SPACE_RESET    YES)
          (AUTO_RESET     NO)
          (END_KEY        NO)
          (WILD_ENABLE    NO)
          (AUTO_SELECT    NO)
          (SINMD_IN_LINE1 NO)
          (BEEP_WRONG     YES)
          (BEEP_DUPCHAR   YES)))
============================================================================

      ¤W­zªº³]©w¬O¦b±Ò°Ê xcin ¤§«á¡A¥ô¦ó³õ¦X¤U (©Î¦b¥ô¦ó IC ¤U) ³£¬Û¦Pªº¡C
      ¦ý¥Ñ©ó cj ³o­Ó¿é¤Jªk¥²¶·®M¥Î "gen_inp" module, ¥B "gen_inp" module
      ¤]¥i¥H³Q¨ä¥L¿é¤Jªk©Ò®M¥Î¡A¦ý§Oªº¿é¤Jªk¦b®M¥Î«á¡A¨ä¤W­zªº¤½¥Î³]©w­È¤£
      ¨£±o»P cj ¿é¤Jªk¤@¼Ë¡C´«¥y¸Ü»¡¡A¦³³\¦h¿é¤Jªk³£¥i¥H®M¥Î "gen_inp"
      module, ¨Ï¥Î¸Ó module ªº¨ç¦¡»P¥\¯à¡A¦ý¦U§O¿é¤Jªkªº¤½¥Î³]©w¸ê®Æµ²ºc¥²
      ¶·¤À¶}¡C

      ¦]¦¹¡A¦b¤WÀYªº module_t ¸ê®Æµ²ºc¤¤¡A¨S¦³¡u¤½¥Î³]©w°Ï¡vªºÄæ¦ì¡A¬Û¤Ïªº
      §Ú­Ì¦³¡u¤½¥Î³]©w°Ï¤j¤p¡vªºÄæ¦ì: int conf_size; ³o¬O programmer ¥²¶·
      «ü©wªº¡A¦]¬°¨C­Ó¤£¦Pªº¿é¤Jªk module ¨ä¤½¥Î³]©w°Ï¸ê®Æµ²ºc¥i¯à¤£¤@¼Ë¡C
      ¨t²Î·|ª½¨ì¸Ó module ¯u¥¿³Q¬Y­Ó¿é¤Jªk®M¥Î«á¡A¤~·|®Ú¾Ú conf_size ªº­È
      ¬°¦¹ module (¿é¤Jªk) ¤À°t¤@¶ô¿W¥ßªº¤½¥Î¸ê®Æµ²ºc°Ï°ì¡C

      ¦Ü©ó module ¤¤ªº¨ç¦¡­n¦p¦ó¨Ï¥Î¤½¥Î¸ê®Æµ²ºc©O? ¦U¦ì¥i¥H¬Ý¨ì¨C­Ó¨ç¦¡³£
      ¦³¤@­Ó void *conf Äæ¦ì¡A¤]´N¬O¸Ó¸ê®Æµ²ºc·|¸g¥Ñ¦¹Äæ¦ì¶Ç¤J¡Cºî¤W©Ò­z¡A
      ·í§Ú­Ì¦b¼gµ{¦¡®É¡A§Ú­Ì¥²¶·¿í¦u¥H¤Uªº½d¨Ò:

============================================================================
typedef struct {		/* ³o¬O¦¹ module ¦Û©wªº¤½¥Î¸ê®Æµ²ºc */
    char *inpname;
    int  setkey;
    ...........
} my_module_datastr_t;

int my_module_init(void *conf, char *objname, core_config_t *xc)
/* ³o¬O¦¹ module ªº init() ¨ç¦¡ */
{
    my_module_datastr_t *cf = (my_module_datastr_t *)conf;

    cf->inpname = .....;
    cf->setkey = .....;
}

.................

module_t module_ptr = {
    ......
    sizeof(my_module_datastr_t),	/* ³o¬O conf_size Äæ¦ì */
    ......
    my_module_init,			/* ³o¬O init Äæ¦ì */
};
============================================================================

      ½Ðª`·N¡A³Ì«áªº module_ptr ³o­Ó¦W¦r¬O¯S®íªº¡A¤@©w­n¥Î³o­Ó¦W¦r¡A³o¼Ë
      xcin ¦b¨Ï¥Î dlopen() ¸ü¤J¦¹ module ®É¡A¤~¯à§ä¨ì module_t ùØÀYªº¨C­Ó
      Äæ¦ì¡C


   2. ¨C­Ó IC ªº¿é¤Jª¬ºA¸ê®Æ:

      ¨C­Ó IC ªº¿é¤Jª¬ºA¸ê®Æ¬O¥Ñ¦U§O¿é¤Jªk module »P xcin ¨t²Î¦@¦PºûÅ@ªº¡C
      ·í¨C­Ó X window µøµ¡·Ç³Æ±µ¨ü xcin ¿é¤J®É¡A xcin ´N·|¬°¥¦²£¥Í¤@­Ó IC
      ¦P®É¤]·|¦³¤@­Ó inpinfo_t ¸ê®Æµ²ºc¨ÓÀx¦s IC ¿é¤Jª¬ºA¸ê®Æ:

=============================================================================
typedef struct inpinfo_s  inpinfo_t;
struct inpinfo_s {
    int imid;                           /* ID of current IM Context */
    void *iccf;                         /* Internal data of IM for each IC */

    char *inp_cname;                    /* IM Chinese name */
    char *inp_ename;                    /* IM English name */
    ubyte_t area3_len;                  /* Length of area 3 of window (n_char)*/
    ubyte_t zh_ascii;                   /* The zh_ascii mode */
    unsigned short xcin_wlen;           /* xcin window length */
    unsigned guimode;                   /* GUI mode flag */

    ubyte_t keystroke_len;              /* # chars of keystroke */
    wch_t *s_keystroke;                 /* keystroke printed in area 3 */
    wch_t *suggest_skeystroke;          /* keystroke printed in area 3 */

    ubyte_t n_selkey;                   /* # of selection keys */
    wch_t *s_selkey;                    /* the displayed select keys */
    unsigned short n_mcch;              /* # of chars with the same keystroke */
    wch_t *mcch;                        /* multi-char list */
    ubyte_t *mcch_grouping;             /* grouping of mcch list */
    byte_t mcch_pgstate;                /* page state of multi-char */

    unsigned short n_lcch;              /* # of composed cch list. */
    wch_t *lcch;                        /* composed cch list. */
    unsigned short edit_pos;            /* editing position in lcch list. */
    ubyte_t *lcch_grouping;             /* grouping of lcch list */

    wch_t cch_publish;                  /* A published cch. */
    char *cch;                          /* the string for commit. */
};
=============================================================================

      ¦Ó¦¹¸ê®Æµ²Á¿·|¶Ç¤J¬Y¨Ç¯S©wªº module ¨ç¦¡¤¤ (¦p keystroke() ¨ç¦¡)¡AÅý
      module °Ñ»P³B²z¡C¨ä¨C­ÓÄæ¦ìªº·N¸q¦p¤U:

      imid:  ¥Ø«e¨Ï¥Î¥»¿é¤Jªk module ªº IMC ªº½s¸¹¡C

      iccf:  ¦³®É­Ô·í¿é¤Jªk¼Ò²Õ»Ý­n¬°¨C¤@­Ó IC (¨Æ¹ê¤W¬O¨C¤@­Ó IMC¡A¨C­Ó
	  IC ¥i¥H¦³¦U¦Ûªº IMC, ¤]¥i¥H¦@¥Î¤@­Ó IMC¡C¨£ structer ¤@¤åªº»¡©ú)
	  ¦U§O²£¥Í¸ê®Æµ²ºc®É¡A«h¦³¨â­Ó°µªk: ¤@¬O¦Û¦æ¦b¸Ó¿é¤Jªkªº¤½¥Î³]©w
	  °Ï (¨£²Ä 1 ÂI) ¤¤¦Û¦æºûÅ@¤@­Ó IMC ¸ê®Æ¦ê¦C¡AµM«áÂÇ¥Ñ imid ¨Óµø
	  §O³o¨Ç¸ê®Æ¦ê¦C¬OÄÝ©ó¨º¨Ç IMC¡C¥t¤@­Ó¸û²³æªº°µªk¬O§Q¥Î iccf ³o
	  ­Ó«ü¼Ð¡AÅý¥¦«ü¨ì¥Ø«e IMC ©ÒÄݪº¸ê®Æµ²ºc¡A«h¨C·í¬Y­Ó IMC ³Q¨Ï¥Î
	  ®É¡Aiccf ´N¦ÛµM«ü¨ì¨ä©ÒÄݪº¸ê®Æµ²ºc¤F¡C

	  ½Ðª`·N¡A xcin ¤£·|´À±zºûÅ@¦¹«ü¼Ð©Ò«üªº¸ê®Æµ²ºc¡A¬G·í±z­n¥Î¦¹«ü
	  ¼Ð®É¡A¥²¶·¦Û¦æ½T©w¥¦½T¹ê«ü¨ì¯u¥¿ªº¸ê®Æµ²ºc¤W¡A¦Ó¥B¥Ñ©ó inpinfo
	  ¬O©Ò¦³¿é¤Jªk¦@¥Îªº¡A¬G±z¥²¶·½T©w¨C¦¸¦b¿é¤Jªk¤Á´«¤§»Ú¡A iccf ªº
	  «ü¦V¤´¬O¥¿½Tªº¡C¤@­Ó²³æªº°µªk¬O¦b xim_init() (¨£«á­z) ¤¤ malloc
	  ¤@­Ó°Ï°ìµ¹ iccf, ¦Ó¦b xim_end() (¨£«á­z) ¤¤±N¥¦ free ±¼¡C

      inp_cname:  ¦¹¿é¤Jªkªº¤¤¤å¦W¡C

      inp_ename:  ¦¹¿é¤Jªkªº­^¤å¦W¡C

      area3_len:  ²Õ¦r°Ï¤j¤p (³æ¦ì: ­^¤å¥À¦r­Ó¼Æ)

      zh_ascii:   ¥Ø«e xcin ¬O§_³B©ó¥þ§Î¿é¤J¼Ò¦¡¡H¬O«h¨ä­È¬° 1¡A§_«h¬° 0¡C

      xcin_wlen:  ³o¬O¥Ñ xcin ©Ò³]©wªº¡A¥Î¨Ó§i¶D¿é¤Jªk¼Ò²Õ¥Ø«e xcin µøµ¡ªº
		  ªø«×¡C

      guimode:  ¿é¤Jªk¼Ò²Õ¥i¥H¥Î³o­ÓÅܼƨӳ]©w GUI ¨t²Î¯S©wªºÅã¥Üª¬ºA:

	  GUIMOD_SELKEYSPOT:  ·í¥Ø«e¿é¤Jªk³B©ó¦h­«¦r¿ï¾Ü®É¡A¦¹³]©w¥i¥H³qª¾
		GUI ¨t²Î¬O§_±N¨C­Ó¿ï¾ÜÁä¥ÎÅã²´ªºÃC¦â (Spot light) ¨ÓÅã¥Ü¡C

	  GUIMOD_SINMDLINE1:  ¦¹³]©w¥i¥H³qª¾ GUI ¨t²Î¦b¦L¥X¡u¿é¤Jªk¦rÁä½X¡v
		®É¡A¬O¦b­ì¨Ó¦ì¸m¦L¥X¡AÁÙ¬O§ï¦b²Ä¤@¦æ¦L¥X¡C

	  GUIMOD_LISTCHAR:  ­Y¦¹³]©w¬° on, «h GUI ¨t²Î·|¦b xcin µøµ¡ªº²Ä¤@
		¦æ¦L¥X inpinfo->lcch ¦r¦êªº¤º®e¡A¨Ã®Ú¾Ú inpinfo->edit_pos
		µe¥X´å¼Ð¦ì¸m¡A³o¬O¥Î©ó bimsphone ¼Ò²Õ¡A·í¿é¤J¤¤¤å¦r®É¡A
		¤¤¤å¦r¨Ã¤£·|°¨¤W¶]¨ì client µøµ¡ùØ¡A¦Ó¬O¯d¦b xcin µøµ¡ªº
		²Ä¤@¦æ¡A¦Ó´å¼Ð«hÅã¥Ü¤F¥Ø«eªº¿é¤J¦ì¸m¡C­Y³]¬° off, «h xcin µø
		µ¡ªº²Ä¤@¦æ±N¥Î°µ¦h­«¦r (µü) ¿ï¾Üªº¦Cªí¡A§Y¦C¥X inpinfo->mcch
		ªº¤º®e (¦pªG¦³¤º®eªº¸Ü)¡C

      keystroke_len:  ¥Ø«e¤w¿é¤Jªº¦rÁä½Xªø«×¡C

      s_keystroke:  ¥Ø«e¤w¿é¤Jªº¦rÁä½X¡A§Y±NÅã¥Ü¦b xcin µøµ¡¤¤²Ä¤G¦æ²Ä¤G
	  °Ïªº¤º®e¡C½Ðª`·N xcin ¥»¨­¤£·|ºûÅ@¦¹½w½Ä°Ïªº¤º®e¡A¬G¦U¿é¤Jªk¥²
	  ¶·¦Û¦æºûÅ@¥¦¡A½Ð¨£«e­± iccf ªº»¡©ú¡C

      suggest_skeystroke:  ¦¹¿é¤Jªk¼Ò²Õ©Ò«ØÄ³ªº keystroke Åã¥Ü¦r¦ê¡C¿é¤J
	  ¼Ò²Õ¥i¥H¨M©w¬O§_­n´£¨Ñ¦¹¸ê®Æ¡C¨ä¥Îªk¬O: ·í¬Y¿é¤Jªk²Õ¦r§¹¦¨«á¡A
	  ¥¦¥i¥H±N¦¹¦r§¹¾ãªº keystroke ¶ñ¤J¦¹ buffer ¤¤¡C xcin ­Yµo²{¥Î
	  ¨ÓÅã¥Ü ksystroke ªº¨ç¦¡ (§Y show_keystroke()) ©ÒÄݪº¿é¤Jªk»P¥»
	  ¿é¤Jªk¬Û¦P®É¡A¥¦´N·|ª½±µ±Ä¥Î suggest_skeystroke ªº¤º®e¨ÓÅã¥Ü
	  xcin µøµ¡¤¤²Ä¤G¦æ²Ä¤T°Ïªº¸ê®Æ¡A¦Ó¤£·|¥h©I¥s¸Ó¿é¤Jªkªº 
	  show_keystroke() ¨ç¦¡¡C

	  ½Ðª`·N xcin ¥»¨­¤£·|ºûÅ@¦¹½w½Ä°Ïªº¤º®e¡A¬G¦U¿é¤Jªk¥²¶·¦Û¦æºûÅ@
	  ¥¦¡A½Ð¨£«e­± iccf ªº»¡©ú¡C

      n_selkey:  ¥»¿é¤Jªk¦h­«¦r¿ï¾ÜÁ䪺­Ó¼Æ¡C

      s_selkey:  ¥»¿é¤Jªk¦h­«¦r¿ï¾ÜÁä¦Cªí¡C½Ðª`·N xcin ¥»¨­¤£·|ºûÅ@¦¹½w½Ä
	  °Ïªº¤º®e¡A¬G¦U¿é¤Jªk¥²¶·¦Û¦æºûÅ@¥¦¡C

      n_mcch:  ¥Ø«eªº¦h­«¦rµü buffer mcch ªº¦r¼Æ¡C

      mcch:  ¥Ø«eªº¦h­«¦r¦Cªí¡A¦¹¦Cªíªº¤j¤p¤£À³¶W¹L n_selkey ªº­È¡C½Ðª`·N 
	  xcin ¥»¨­¤£·|ºûÅ@¦¹½w½Ä°Ïªº¤º®e¡A¬G¦U¿é¤Jªk¥²¶·¦Û¦æºûÅ@¥¦¡C

      mcch_grouping:  mcch ªº¸s¦Cªí¡C¦pªG mcch_grouping ¬° NULL ®É¡A«h¨C­Ó
	  mcch ¤¤ªº¦r§Y¬°¤@­Ó¿W¥ßªº¿ï¶µ¡A¥B n_mcch §Y¬° mcch ¤¤ªº¦r¼Æ¡C­Y
	  mcch_grouping ¤£¬° NULL ®É¡A«h²Ä¤@­Ó mcch_grouping ªº­È¥NªíÁ`¦@
	  ¦³´X­Ó¿ï¶µ¡A¦Ó¨ä«á¨C­Ó mcch_grouping ªº­È¥Nªí¸Ó¿ï¶µ¦b mcch ¤¤ªº
	  ¦r¼Æ¡C¨Ò¦p:

		n_mcch = 9;
		mcch_grouping[5] = {4, 2, 2, 1, 4}
		mcch = {¤µ¤é¤Ñ®ð¨Î­·©M¤éÄR}

	  ¨ä¤¤²Ä¤@­Ó 4 §Y¥NªíÁ`¦@¦³ 4 ­Ó¿ï¶µ¡C«h xcin ¦b¦h­«¦rµü¿ï¾Ü®É·|±N
	  ¥¦¸ÑÄÀ¬°

		1.¤µ¤é  2.¤Ñ®ð  3.¨Î  4.­·©M¤éÄR

	  ­Y mcch »P n_mcch ªº¤º®e¤£ÅÜ¡A¦ý mcch_grouping ¬° NULL, «h xcin 
	  ·|±N¥¦¸ÑÄÀ¬°

		1.¤µ  2.¤é  3.¤Ñ  4.®ð  5.¨Î  6.­·  7.©M  8.¤é  9.ÄR

	  ¦]¦¹¡A­Y¦b¤@¯ë¦h­«¦r¿ï¾Ü®É¡A±z¤£»Ý­n mcch_grouping, ¬G±N¥¦³]¬°
	  NULL §Y¥i¡C­Y­n¿ïµü®É¡A¥i¥H±Nµüªº¤º®e¥þ³¡¶ñ¤J mcch ¤¤¡A¨Ã¥H
	  mcch_grouping °µ¬°¦Uµü¤§¶¡ªº°Ï¹j¡C

      mcch_pgstate:  ªí¥Ü¥Ø«e¦h­«¦rªº¡u­¶¡vª¬ºA¡A¨ä¤¤¡u¤@­¶¡v¥Nªí xcin µø
	  µ¡²Ä¤@¦æ¥i¥HÅã¥Üªº¼e«×¡C¨ä­È¥i¥H¦p¤U:

	  MCCH_ONEPG:  ¦h­«¦rÁ`¼Æ¥i¥H¦b¤@­¶¤ºÅã¥ÜªÌ¡C

	  MCCH_BEGIN:  ¦h­«¦rÁ`¼Æ¶W¹L¤@­¶¥iÅã¥Ü¡A¦¹®É¥¿¦b²Ä¤@­¶¡C

	  MCCH_MIDDLE: ¦h­«¦rÁ`¼Æ¶W¹L¤@­¶¥iÅã¥Ü¡A¦¹®É¥¿¦b²Ä¤@­¶»P³Ì«á¤@­¶¤§¶¡¡C

	  MCCH_END:  ¦h­«¦rÁ`¼Æ¶W¹L¤@­¶¥iÅã¥Ü¡A¦¹®É¥¿¦b³Ì«á¤@­¶¡C

          ¦³Ãö xcin µøµ¡¤¤¦UÅã¥Ü°Ï¦ì¸m»P·N¸q¡A½Ð¨£ structer ¤@¤åªº»¡©ú¡C

      n_lcch:  lcch ½w½Ä°Ï¤º¤¤¤å¦r (¸s) ªº­Ó¼Æ¡C

      lcch:  bimsphone ¤Î¨ä¥L¨ãÃþ¦ü¡u¦ÛµM¡v¿é¤Jªk¥Î¨Ó¦C¥Ü¤w¿é¤Jªº¤¤¤å¦r¦ê
	  ªº½w½Ä°Ï¡A¨£«e­± guimode -> GUIMOD_LISTCHAR ªº»¡©ú¡C½Ðª`·N xcin
	  ¥»¨­¤£ºûÅ@¦¹½w½Ä°Ï¡A¬G¦U¿é¤Jªk¼Ò²Õ­Y­n¨Ï¥Î¥¦®É¡A¥²¶·¦Û¦æºûÅ@¥¦¡C
	  ½Ð¨£«e­± iccf ªº»¡©ú¡C

      edit_pos:  «ü¥Ü lcch ¤¤¤å¦r¦ê¦C¤¤¥Ø«eªº´å¼Ð¦ì¸m¡A½Ð¨£«e­±
	  guimode -> GUIMOD_LISTCHAR ªº»¡©ú¡C

      lcch_grouping:  lcch ªº¸s¦Cªí¡C¨ä»P lcch, n_lcch ªºÃö«Y»P mcch_grouping
	  mcch, n_mcch ¤§¶¡ªºÃö«Y¬O§¹¥þ¬ÛÃþ¤ñªº¡C¨ä§@¥Î¬O¦bÃþ¦ü bimsphone ©Î
	  ¡u¦ÛµM¡v¿é¤Jªk¤¤¡A¦b¤w¿é¤Jªº¤¤¤å¦r¦êªº½w½Ä°Ï¤U¼Ð¥Ü©³½u¡A¥H¥Nªí¤@­Ó
	  ­Ó¦³·N¸qªºµü¡C¨Ò¦p¦b½w½Ä°Ï¤¤¤w¿é¤J¤F:

		¤µ¤é¤Ñ®ð¨Î­·©M¤éÄR
		--- ---   -------
	  ­Y¦¹®É lcch_grouping ªº¤º®e¬° {4, 2, 2, 1, 4} ¥B n_lcch=9 ®É¡A«h 
	  xcin ·|¼Ð¥Ü¦p¤Wªº©³½u¡C­Y lcch_grouping ¬° NULL ®É¡A«h xcin ¥u·|µe
	  ¥X¨º¨Ç¦r¡A¦Ó¤£·|¼Ð¤W¥ô¦ó©³½u¡C

      cch_publish:  ªí¥Ü¥Ø«e¤w§¹¦¨²Õ¦r¥B¥i¥H¡u¤½§G¡vªº¤¤¤å¦r¡C¥¦±N³Q¥Î¨Ó°µ
	  ¡u¿é¤Jªk¦rÁäÅã¥Ü¡v¥Î¡A¨£«á­z¡C

      cch:  ¥Î¨Ó¦s©ñ¿é¤Jªk¼Ò²Õ·Ç³Æ commit µ¹ XIM client ªº¦r¦ê¡C½Ðª`·N xcin
	  ¥»¨­¤£ºûÅ@¦¹½w½Ä°Ï¡A¬G¦U¿é¤Jªk¼Ò²Õ­Y­n¨Ï¥Î¥¦®É¡A¥²¶·¦Û¦æºûÅ@¥¦¡C


----------------------------------------
C. module_t ªºÄæ¦ì»¡©ú:

   ¥H¤U¦UÄæ¦ì­Y¨ä«á¦³¼Ð¥Ü (*) ªÌªí¥Ü¥²¶·­n¦³¡A§_«h¬°¥i¦³¥iµL (§Y¥i³]¬° 0 ©Î
   NULL)¡C

   1. name (*):  ¼Ò²Õ¦WºÙ¡C

   2. version (*):  

      ¼Ò²Õªºª©¥»¡C½Ðª`·N¨t²Îªº¼Ò²Õª©¥»¬O±Ä¥Î¤é´Á¦r¦ê¡A¦p "19990217"¡C·í¨t²Î
      ¸ü¤J¦¹¼Ò²Õ®É¡A¥¦·|Àˬd¦¹¼Ò²Õªºª©¥»¬O¤£¬O»P¨t²Îª©¥»¤£¤@¼Ë¡A¬Oªº¸Ü«h¤£
      ¸ü¤J (­ì¦]¬O¨t²Îªº¼Ò²Õ¬[ºc¥i¯à¤w§ïÅÜ) ¡C¦]¦¹¡A·í±z­n¬° xcin ¥[¤J·s¼Ò
      ²Õ®É¡A½Ðª`·N­n°w¹ï¥Ø«e xcin ªº¼Ò²Õ©w¸q»Pª©¥»¨Ó¼g¡C

   3. comments:

      ¥»¼Ò²ÕªºÂ²µu»¡©ú¡C¥i¥HÂÇ¥Ñ xcin -m <module name> ¨Ó¦L¥X¡A¸Ô¨£ Usage
      ¤@¤åªº»¡©ú¡C


   4. valid_objname:

      «ü©w¥i¥Î¨Ó®M¥Î¦¹ module ªº¿é¤Jªk¦W¦ê¦C¡C¦¹¦ê¦C³Ì«á¥²¶·¥H¤@­Ó NULL item
      µ²§ô¡C­Y¤£«ü©w¡A«h¨t²Î°²³]¦¹ module ¥u¯à³Q¦WºÙ¬° name ªº¿é¤Jªk (»P¦¹
      ¼Ò²Õ¦P¦W) ©Ò®M¥Î¡C¦ê¦C¦WºÙ¥i¥H¥Î * ©Î ? µ¥¸U¥Î¦r¤¸¡A¨Ò¦p:

	{"my_inp", "my_inp_ext_*", "my_inp_ver??", NULL}

      «h¤Z¬O¿é¤Jªk¦WºÙ¬° "my_inp", "my_inp_ext_style1", "my_inp_ext_power",
      "my_inp_ver99" .... µ¥µ¥¡A³£¥i¥H®M¥Î¦¹¼Ò²Õ¡C

   5. module_type (*):

      ¥Ø«e xcin ¥u©w¸q¤@ºØ module_type, ¦b¦¹½Ð³]¬° MOD_CINPUT¡C

   6. conf_size (*):  ¥»¼Ò²Õªº¤½¥Î³]©w¸ê®Æµ²ºc¤j¤p¡C

   7. int (*init) (void *conf, char *objname, xcin_rc_t *xc) (*):

      ¥»¼Ò²Õªºªì©l¤Æ¨ç¦¡¡A¬O¥Î©ó¸Ó¼Ò²Õ²Ä¤@¦¸³Q¸ü¤J¤Î³Q¬Y¿é¤Jªk®M¥Î®É¤~©I¥s¡C
      ¥¦ªº¥ô°È¬O°µ¦n©Ò¦³ªºªì©l¤Æ°Ê§@¡A¦P®É­n±N rcfile ¤¤©Ò»Ýªº¸ê®ÆÅª¶i¨Ó¡C
      ¨ä¦U°Ñ¼Æ·N¸q¦p¤U:

      conf:  ¥»¼Ò²Õªº¤½¥Î³]©w¸ê®Æµ²ºc«ü¼Ð¡C

      objname:  ®M¥Î¦¹¼Ò²Õªº¿é¤Jªk­^¤å¦WºÙ¡C

      xc:  «ü¦V xcin_rc_t (xcin ¥þ°ì³]©w¸ê®Æµ²ºc) ªº«ü¼Ð¡A¦¹¤@«ü¼Ð¦³§U©ó
           ¦¹ module Àò¨ú xcin ªº¤º³¡¸ê°T (¦p locale ªº³]©w)¡C¦¹µ²ºcªº©w
	   ¸q¦p¤U:

	typedef struct {
	    char *lc_ctype;		/* LC_CTYPE locale category name */
	    char *lc_messages;		/* LC_MESSAGES locale category name */
	    char *encoding;		/* encoding name */
	} locale_t;

	typedef struct {
	    char *rcfile;               /* rcfile name. */
	    char *default_dir;          /* Default module directory. */
	    char *user_dir;             /* User data directory. */
	    locale_t locale;            /* Locale name. */
	} xcin_rc_t;

      ¥»¨ç¦¡­Y¦¨¥\¶Ç¦^ True, ¥¢±Ñ¶Ç¦^ False¡C


   8. int (*xim_init) (void *conf, inpinfo_t *inpinfo) (*)

      ¥»¨ç¦¡¦b¤@­Ó·sªº IC (·sªº window ·Ç³Æ±µ¨ü xcin ¿é¤J) ²£¥Í®É¡A©Î¬Y­Ó
      IC ¤£¦Pªº¿é¤Jªk¤Á´«®É³Q©I¥s¡C³o®É¥¦¥²¶·°µ¦n¥²­nªº°Ê§@¬°¦¹ IC ªì©l¤Æ¡A
      ¦P®É¤]­nªì©l¤Æ¦¹ IC ªº¿é¤Jª¬ºA (§Y³]©w inpinfo)¡C

      ½Ðª`·N¡A¥Ñ©ó inpinfo ¬OÄÝ©ó IC ¸ê®Æµ²ºc¤§¤@¡A¨Ã¤£ÄÝ©ó¦U module, ¦U 
      module ¥u¬O¥Î¥¦¨Ó»P xcin °µ·¾³q¦Ó¤w¡C´«¥y¸Ü»¡¡A inpinfo ¬O©Ò¦³¿é¤Jªk 
      module ¦@¥Îªº¡C¦]¦¹¡A·í¬Y­Ó¿é¤Jªk·Ç³Æ³Q¬Y­Ó IC ¨Ï¥Î®É¡A¸Ó IC «K·|©I¥s 
      ¥»¨ç¦¡¡A«h¥»¨ç¦¡¥²¶·¬° inpinfo ¤¤¨C­ÓÄæ¦ì³]©wªì­È (¦]¬°¥¦­Ì¥Ø«eªº­È¥i
      ¯à¬O¤W­Ó¨Ï¥Î¥¦ªº¿é¤Jªk¼Ò²Õ©Ò³]ªº¡A¤£¾A¥Î©ó¥Ø«eªº¿é¤Jªk¼Ò²Õ)¡A¨Ã¥Bµø»Ý
      ­n malloc ½w½Ä°Ïµ¹ inpinfo->iccf, inpinfo->s_keystroke, inpinfo->lcch,
      »P inpinfo->cch ¨Ï¥Î¡C

      ¥»¨ç¦¡­Y¦¨¥\¶Ç¦^ True, ¥¢±Ñ¶Ç¦^ False¡C


   9. unsigned int (*xim_end) (void *conf, inpinfo_t *inpinfo) (*)

      ¨C·í¬Y­Ó IC µ²§ô®É¡A©Î¤£¦Pªº¿é¤Jªk¤Á´«®É¡A xcin ¦b©I¥s¥t¤@­Ó¿é¤Jªkªº 
      xim_init() ¤§«e·|¥ý©I¥s¥Ø«e³o­Ó¿é¤Jªkªº xim_end()¡C§Ú­Ì¥i¥H¦b¦¹°µ¤@¨Ç
      µ²§ô«eªº¤u§@¡A¨Ò¦pµø»Ý­n²M°£©Î free  inpinfo->iccf, inpinfo->s_keystroke, 
      inpinfo->lcch, »P inpinfo->cch ½w½Ä°Ï .... µ¥¡C

      ¥»¨ç¦¡ªº¶Ç¦^­È¥i¥H»P keystroke() ªº¶Ç¦^­È¤@¼Ë¡A¬G¥i¥Î©ó commit ¦r¦ê¡A
      ¨£«á­z¡C


  10. unsigned int (*keystroke) (void *conf, 
		inpinfo_t *inpinfo, keyinfo_t *keyinfo) (*)

      ¦¹¨ç¦¡©w¸q¥»¿é¤Jªk module ªº¦rÁä³B²z¤è¦¡¡C¨C·í¨Ï¥ÎªÌºV¤J¤@­Ó«öÁä¡A
      xcin «K·|©I¥s¦¹¨ç¦¡¡C³o®É¥»¨ç¦¡¥²¶·¸ÑÄÀ¦¹¦rÁ䪺·N¸q¡Aµø»Ý­n§ïÅÜ xcin 
      µøµ¡ªºª¬ºA¡A¦P®É±Nµ²ªG¶Ç¦^µ¹ xcin ¶i¦æ«áÄò³B²z°Ê§@¡C¨ä¤¤ conf »P 
      inpinfo_t Äæ¦ì¦p«e©Ò­z¡A¦Ó keyinfo_t µ²ºcªº©w¸q¦p¤U:

typedef struct {
    KeySym keysym;                      /* X11 key code. */
    unsigned int keystate;              /* X11 key state/modifiers */
    char keystr[16];                    /* X11 key name (in ascii) */
    int keystr_len;                     /* key name length */
} keyinfo_t;


      ¥»¨ç¦¡ªº¶Ç¦^­È¥i¥H¬O¦p¤U¥ô·Nªº | (bitwise OR) ²Õ¦X:

      IMKEY_ABSORB:  ªí¥Ü¥»¿é¤Jªk±N³o­Ó¦rÁäÀRÀRªº§l¦¬¤F¡A xcin ¤£»Ý­n°µ¨ä
		¥L«áÄò°Ê§@¡C¦¹¥Îªk¦h¥b¥Î©ó²Õ¦rªº¤¤³~¡C

      IMKEY_COMMIT:  ªí¥Ü¥»¿é¤Jªk¤w§¹¦¨²Õ¦r¡A³o®É xcin ·|±N inpinfo->cch
		³o­Ó¤¤¤å¦r¶Çµ¹¥Ø«eªº X app, ¦Ó X app ·|±N³o­Ó¦rÅã¥Ü¦b¨äµø
		µ¡¤W¡C

      IMKEY_IGNORE:  ªí¥Ü³o­Ó¦rÁä¹ï¥»¿é¤Jªk¦Ó¨¥¬O§¹¥þ¨S¦³·N¸qªº¡A¥»¿é¤Jªk
		¤£³B²z³o­Ó¦rÁä¡A½Ð xcin ±N¦¹¦rÁ䥿¥Ñ¨ä¥L³¡¤À³B²z¡C

      IMKEY_BELL:  ªí¥Ü¥»¿é¤Jªk­n¨D xcin µo¥X¡u¹Í¡v¤@Án¡C

      IMKEY_BELL2: ªí¥Ü¥»¿é¤Jªk­n¨D xcin µo¥X¥t¤@ºØ¡u¹Í¡v¤@Án¡C²{¦b xcin
		¤ä´©¨âºØ¡u¹Í¡vÁn¡A³q±`¥Î¥H¥Nªí¥Ø«e¦³¦h­«¦r¥i¥H¿ï¾Ü¡A©ÎªÌ
		¨Ï¥ÎªÌ¿é¤J¿ù»~¡C¿é¤Jªk¼Ò²Õ¥i¥Hµø»Ý­n¤ä´©¥¦©Î¥u¥Î IMKEY_BELL
		¥ç¥i¡C

      IMKEY_SHIFTESC:  ªí¥Ü¥Ø«e¨Ï¥ÎªÌ¦P®ÉÁÙ«ö¤U¤F shift Áä»P¨ä¥L¦rÁä¡A¦Ó¥B¥»
		¿é¤Jªk±N¤£³B²z³o­Ó¦rÁä¡A¦Ó½Ð xcin ±N¦¹¦rÁäÂà¥æ¥þ§Î/¥b§Î¿é¤J
		¼Ò²Õ³B²z¡C

      IMKEY_SHIFTPHR:  ªí¥Ü¥Ø«e¨Ï¥ÎªÌ¦P®ÉÁÙ«ö¤U¤F shift Áä»P¨ä¥L¦rÁä¡A¦ý»P
		IMKEY_SHIFTESC ¤£¦Pªº¬O¡A³o¦^«o¬O¥æµ¹ qphrase ¨Ó³B²z¡A¤]´N¬O
		§Ö³t¤ù»y¿é¤J¥\¯à¡C¿é¤Jªk¼Ò²Õ¥i¥Hµø»Ý­n¤ä´©¦¹¥\¯à¡C

      IMKEY_CTRLPHR:  ªí¥Ü¥Ø«e¨Ï¥ÎªÌ¦P®ÉÁÙ«ö¤U¤F ctrl Áä»P¨ä¥L¦rÁä¡A¥Î¨Ó°µ§Ö
		³t¤ù»y¿é¤J (qphrase)¡A¨ä§@¥Î»P IMKEY_SHIFTPHR ¬Û¦P¡C

      IMKEY_ALTPHR:  ªí¥Ü¥Ø«e¨Ï¥ÎªÌ¦P®ÉÁÙ«ö¤U¤F alt Áä»P¨ä¥L¦rÁä¡A¥Î¨Ó°µ§Ö³t
		¤ù»y¿é¤J (qphrase)¡A¨ä§@¥Î»P IMKEY_SHIFTPHR ¬Û¦P¡C

      IMKEY_FALLBACKPHR:  ªí¥Ü¥Ø«e¨Ï¥ÎªÌ«ö¤U¤F¬Y¦rÁä¡A¦ý¸Ó¦rÁ䥻¿é¤Jªk¤£°µ³B
		²z¡A¬G¥i¥H¥æµ¹§Ö³t¤ù»y¿é¤J (qphrase)¡A¨ä§@¥Î»P IMKEY_SHIFTPHR
		¬Û¦P¡C

  11. int (*show_keystroke) (void *conf, simdinfo_t *simdinfo);

      ¥»¨ç¦¡¥Î¨ÓÅã¥Ü¬Y­Ó¯S©w¤¤¤å¦rªº¦rÁä½X¡C xcin ·|µø»Ý­n©I¥s¦¹¨ç¦¡¡A¨Ã
      ±N¦¹¨ç¦¡©Ò»Ýªº¸ê®Æ¸g¥Ñ simdinfo µ²ºc¶Ç¤J¡A¥Hµ²ºc©w¸q¦p¤U:

typedef struct {
    int imid;                           /* ID of current Input Context */
    unsigned short xcin_wlen;           /* xcin window length */
    unsigned short guimode;             /* GUI mode flag */
    wch_t cch_publish;                  /* A published cch. */
    wch_t *s_keystroke;                 /* keystroke of cch_publish returned */
} simdinfo_t;

      ¨ä¤¤ cch_publish §Y¬° xcin §Æ±æ¦¹¨ç¦¡Åã¥Ü¦rÁä½Xªº¤¤¤å¦r¡A¦Ó©Ò±oªº
      ¦rÁä½X«h¸g¥Ñ s_keystroke ¶Ç¦^µ¹ xcin ¡C

      ½Ðª`·N¡A xcin ¨Ã¤£ºûÅ@ s_keystroke ½w½Ä°Ï¡A¬G¥»¨ç¦¡¥²¶·¦Û¦æºûÅ@¥¦¡C
      ¤@­Ó²³æªº°µªk¬O¥»¨ç¦¡¦Û¦æ«Å§i¤@­Ó static ªº½w½Ä°Ï¡AµM«á±N s_keystroke
      «ü¦V¥¦¡A¨Ò¦p:

	  static wch_t my_keystroke[BUF_SIZE];
	  simdinfo->s_keystroke = my_keystroke;
	  .........

  12. int (*terminate) (void *conf);

      ·í xcin ±N­n¥Ã¤[°±¥Î¬Y­Ó¿é¤Jªk®É (¨Ò¦p xcin ±Nµ²§ô¹B§@®É)¡A¦pªG¦¹¨ç¦¡
      ¦³©w¸q®É¡A´N·|©I¥s¦¹¨ç¦¡Åý¦¹¿é¤Jªk (¼Ò²Õ) ¶i¦æµ²§ô«eªº¤u§@¡A¦pÃö³¬¸ê
      ®ÆÀÉ .... µ¥¡C


----------------------------------------
D. ¼Ò²Õªºªì©l¤Æ¤u§@:

¼Ò²Õªºªì©l¤Æ¤u§@¤À¬°¨â­Ó¼h­±¡A¨ä¤@¬O¿é¤Jªk²Ä¤@¦¸³Q¸ü¤J¨Ï¥Î®É¡A¥²¶·±N¨ä¸ê®Æ
µ²ºc¥þ³¡°µªì©l¤Æ¡F¨ä¤G¬O¨C¦¸¨Ï¥ÎªÌ¤Á´«¨ì¦¹¿é¤Jªk®Éªº inpinfo_t µ²ºcªºªì©l
¤Æ¤u§@¡C³o¨â­Ó¤u§@¤À§O¥Ñ¿é¤Jªk¼Ò²Õªº int (*init)() »P int (*xim_init)() ¨â
­Ó¨ç¦¡¨Ó§¹¦¨¡C

¥ý¨Ó¬Ý«áªÌªº³¡¤À¡C¥Ñ©ó¿é¤Jªk¼Ò²Õ»P xcin ¤§¶¡ªº³sôºÞ¹D¬O³z¹L inpinfo_t µ²
ºc¨Ó¹F¦¨¡AµM¦Ó inpinfo_t ¨Ã¤£¬OÄÝ©ó¼Ò²Õ¥»¨­ªº¸ê®Æµ²ºc¡A¥¦¬OÄÝ©ó IMC ªº¤@³¡
¤À¡C¤]´N¬O»¡¡A¨C·í IMC ÅÜ´«¿é¤Jªk (¤]´N¬O¨Ï¥ÎªÌ¤Á´«¨ì¨ä¥Lªº¿é¤Jªk) ®É¡A¨ä
inpinfo_t µ²ºc´N·|³Q·sªº¿é¤Jªk®³¨Ó¨Ï¥Î¡C¦]¦¹¡A¨C­Ó¿é¤Jªk¦b¨C¦¸³Q¤Á¤J¨Ï¥Î®É¡A
¥¦³£¥²¶·­n­«³]¤@¦¸ inpinfo_t ªº¤º®e¡C

¦Ü©ó«eªÌªº³¡¤À¡A·í¤@­Ó¿é¤Jªk²Ä¤@¦¸³Q¸ü¤J¨Ï¥Î®É¡A¥¦¥²¶·°µ¦n¤@¤Áªºªì©l¤Æ¤u§@¡A
¨ä¤¤¥]¬A¤F¡G

1. ¨M©w¿é¤Jªk¦WºÙ¡G

   ¥Ñ©ó¦Û xcin-2.5.2 ¶}©l¡Axcinrc ªº³]©wÀɤw¤ä´© <IM_name>@<encoding> ªº®æ
   ¦¡¡A¨Ò¦p cj@big5 ¥Nªíªº§Y¬O Big5 ½s½Xªº­Ü¾e¿é¤Jªk¡C¦]¦¹

	int (*init) (void *conf, char *objname, xcin_rc_t *xc);

   ¨ç¦¡©Ò¶Ç¤Jªº objname ©¹©¹©M xcinrc ¤¤©Ò³]©wªº¿é¤Jªk¦WºÙ¤£¤@¼Ë¡C¦]¦¹¥²¶·
   ¥ý¨M©w xcinrc ¤¤¯u¥¿ªº¿é¤Jªk¦WºÙ¡C¨ä¤è¦¡¬°©I¥s xcin ªº¨ç¦¡:

	int get_objenc(char *objname, objenc_t *objenc);

   ¨ä¤¤ objname §Y¬° (*init)() ©Ò¶Ç¤Jªº objname¡C¦Ó¦¹¨ç¦¡©Ò¶Ç¦^ªº objenc_t
   ªºµ²ºc¦p¤U:

typedef struct {
    char objname[50];		/* ¿é¤Jªk¦WºÙ */
    char encoding[50];		/* ¤º½X¦WºÙ */
    char objloadname[100];	/* xcinrc Àɤ¤©Ò³]©wªº¿é¤Jªk¦W
				   (§Y®æ¦¡ <IM_name>@<encoding> */
} objenc_t;


2. Ū¨ú xcinrc ªº³]©w:

   xcinrc ªº³]©wŪ¨ú¬O¸g¥Ñ

	int get_resource(char **cmd_list, char *value, int v_size, 
        	         int n_cmd_list)

   ªº©I¥s¡C¨ä¤¤ cmd_list ¥Î¨Ó¼Ð¥Ü xcinrc Àɤ¤¬Y­Ó¤p¸`ªº¬Y­Ó¶µ¥Ø¡C­nª`·Nªº¬O¡A
   ³q±`¿é¤Jªk³]©w³£¬O¶°¤¤¦b¸Ó¿é¤Jªkªº¤p¸`¤¤¡A¤]´N¬O cmd_list[0] ¥²¶·«ü©ú¬°¸Ó
   ¿é¤Jªkªº¦WºÙ¡C¨Ò¦p¡A·í§Ú­Ì­nŪ¨ú­Ü¾e¿é¤Jªkªº AUTO_COMPOSE ¿ï¶µªº­È®É¡A¨ä
   ¦b xcinrc Àɪº³]©w¬°:

	(define cj
		'((AUTO_COMPOSE  1)
		  .................))

   «h get_resource() ªº©I¥s¤è¦¡«h¬°:

	char *cmd[2], value[256];
	cmd[0] = "cj";
	cmd[1] = "AUTO_COMPOSE";
	if (get_resource(cmd, value, sizeof(value), 2)) {
	    /* we have read the value of AUTO_COMPOSE */
	}
	
   µM¦Ó¡A¹ï©ó¤@­Ó¿é¤Jªk¼Ò²Õ¦Ó¨¥¡A¥Ñ©ó¥i¥H³Q¦hºØ¿é¤Jªk®M¥Î¡A¬G¿é¤Jªk¦WºÙ¬OµL
   ªk¨Æ¥ýª¾¹Dªº¡A¬G¤£¯à¦p¤W¨Ò¨º¼Ë¨Ï¥Î "cj" ¦r¦ê¡C¦ý³o¸Ì¤]¤£¯àª½±µ¥Î¤W­zªº
   objname ¨Ó¥N¤J¡A¦]¬° xcinrc Àɪº³]©w¤]¥i¯à¬O³o¼Ë:

	(define cj@big5
		'((AUTO_COMPOSE  1)
		  .................))

   ¦]¦¹¥¿½Tªº¼gªk¬O¥Î¥ý«e©I¥sªº get_objenc() ªº¶Ç¦^­È¨Ó¥N¤J:

	objenc_t objenc;
	........ .......

	if (get_objenc(objname, &objenc) == -1)
	    return False;
	cmd[0] = objenc.objloadname;
	............................

   ¨ä¾l©M¤W¨Ò¤@¼Ë¡A¦p¦¹«K¥i¥¿½T¦aŪ¨ú xcinrc ªº³]©w¤F¡C



T.H.Hsieh