¥»¤å²­z xcin-2.5 ªº³]­p²z©À»P¾ã­Óµ{¦¡¬[ºc¡C

xcin-2.5 ªº³]­p²z©À¬°:

1. ¿é¤Jªk¦U¦Û¿W¥ß¥B¼Ò²Õ¤Æ¡C

2. ¨Ï¥ÎªÌ»P©¹±`¤@¼Ë¡A¥u­n·Ç³Æ¦n¤@­Ó .cin ÀÉ¡A¦b xcin ¤U´N¯à°¨¤W¨Ï¥Î¡A¦h¥b
   ¤£»Ý­n¬°¦¹¿é¤Jªk¦h¼g¤@­Ó¼Ò²Õ¡C

3. ¿é¤Jªk¥þµM§êºt¤@­ÓÃþ¦ü "server" ªº¨¤¦â¡A¤]´N¬O xcin ¦V¿é¤Jªk´£¥X½Ð¨D¡A
   ¦Ó¿é¤Jªk«h®Ú¾Ú½Ð¨D°µ¥X¦^À³¡C°£¦¹¤§¥~¡A¿é¤Jªk¤£°Ñ»P xcin ¨ä¥L³¡¤Àªº¬¡°Ê¡C

4. xcin §¹¥þ«ö·Ó locale, XIM ªº¬[ºc³]­p¡A¾¨¥i¯à´Â¼Ð·Ç¤Æªº¤è¦V¨«¡A§Æ±æ±q¦¹
   ¯à§¹¥þ¸Ñ¨M X window ¤Uªº¤¤¤å¿é¤J°ÝÃD¡C

°ò©ó³o¨Ç²z©À¡A¨Ï±o xcin-2.5 »Pª©ªº xcin ¤w§¹¥þ¤£¤@¼Ë¡A¨ä°ò¥»¬[ºc¦p¤U:

                       IC manager <------> IMC system
		           ||	             |
		           ||	             |
	               XIM system <----------+
		           ||	             |
		           ||	             |
	               GUI system          module <----- cinput
		  (winlist subsystem)        |
		           ||	             |
		           ||	             |
                         xccore   <------ xcintool
			   ||		     |
			   ||		     |
		         xcin_rc  <------  siod 

¥H¤U´N¤W¹Ïªº¦U³¡¤À°µÂ²³æªº»¡©ú¡C


--------------------------------------
A. xcintool: (include/xcintool.h, lib/xcintool/*.c)

   ³o¬O xcin ³Ì©³¼hªº¤u¨ã¨ç¦¡®w¡A¥¦¥u­t³d¤@¨Ç²³æ¦Ó°ò¥»ªº¾Þ§@¡C

--------------------------------------
B. siod & xcin_rc: (lib/siod/*, lib/xcintool/xcin_rc.c)

   ³o¬O xcin ªº rcfile Ū¨ú¨t²Î¡C¨ä¤½¥Î¨ç¦¡©I¥s¤¶­±»P xcintool ³sµ²¦b¤@°_¡A
   ¦Ó¨ä®Ö¤ß«h¬° siod lib ¡C siod ¬°¤@­Ó²V¦X lisp »P Scheme »y¨¥ªºª½Ä¶¾¹¡A³o
   ¨Ï±o rcfile ªº³]©w¤º®e¥i¥H±Ä¥ÎÄYºò¦Ó´I¼u©Êªº lisp / Scheme »y¨¥¡C

   xcin_rc ¨t²Î¥i¥H¦P®É´£¨Ñ xccore »P module Ū¨ú rcfile ¸ê®Æ¤§¥Î¡A¦P®É
   ¤]¥i¥H°µ¬° xcin ¨ä¥L¥~³¡µ{¦¡ (¦p cin2tab) ¦@³qªº rcfile Ū¨ú¤¶­±¡C¬G§Ú­Ì
   ¥u»Ý­n¤@­Ó rcfile §Y¥i°µ¦n©Ò¦³ªº xcin ¬ÛÃö³]©w¡C

   ©Ò¦³¸g¥Ñ siod »P rcfile Ū¨ú¨t²Î©ÒŪ¤Jªº¥þ°ì¸ê®ÆÅÜ¼Æ (¤£¥]¬A CINPUT ¤ºªº
   ²Ó³¡³]©w) ¥þ³¡Àx¦s¦b xcin_rc ¸ê®Æµ²ºc¤¤¡A·í xcin ¦³¥ô¦ó¤@­Ó module ±Ò°Ê
   ¨Ã¶}©lªì©l¤Æ®É¡A¦¹µ²ºc«K·|¶Ç¤J¸Ó module ªºªì©l¤Æ¨ç¦¡¤¤¡A«h¸Ó module «K¥i
   ¥H°Ñ¦Ò¸Óµ²ºc¤¤ªº¸ê®Æ°µ¥²­nªº³]©w°Ê§@¡C

--------------------------------------
C. xccore: (include/constant.h, include/xcin.h, xcin_main.c)

   ³o¬O xcin ¥Dµ{¦¡¸ê®Æµ²ºc¡A¥¦¬O¥Ñ¦­´Á clkao ¥S©Ò³W¹ºªº xcin_core module
   ÂàÅܹL¨Óªº¡C¥¦­t³d xcin ±Ò°Ê®É¤@¤Áªºªì©l¤Æ°Ê§@¡A¥]¬AŪ¤J©R¥O¦C¿ï¶µ¡B³]
   ©w locale ¡B°õ¦æ rcfile Ū¨ú¨t²ÎŪ¨ú rcfile ¡B¶i¦æ xcin ¨ä¥L³¡¤Àªºªì©l
   ¤Æ .... µ¥µ¥¡A¦P®É¥¦ªº¸ê®Æµ²ºcÁÙ«O¦³¥Ø«e xcin ©Ò¦³ªºª¬ºA¸ê°T¡A¥]¬A GUI¡B
   XIM¡B¥H¤Î¿é¤Jªkª¬ºAµ¥¡C¦¹¸ê®Æµ²ºc¬° xcin ¥Dµ{¦¡©Ò¨p¦³¡A¥Ñ xcin ®Ö¤ßª½±µ
   ±±¨î¡A¿é¤Jªk¼Ò²ÕµLªk°Ñ¦Ò¨ä¤º®e¡C

   ¦¹¸ê®Æµ²ºc¤¤¡A xccore.xcin_mode ¥Î¨Ó°O¿ý xcin ªºª¬ºA¡A¨ä§@¥Î¦³¤G: ¤@¬O°O
   ¿ý¨Ó¦Û rcfile (xcinrc) ªº³]©w²ÕºA¡A¥t¤@­Ó¬O°O¿ý xcin °õ¦æ®É´Áªºª¬ºA¡C


--------------------------------------
D. module: (include/module.h include/imodule.h include/cinput.h module.c)

   ³o¬O xcin ªº¿é¤Jªk¼Ò²Õ®Ö¤ß¡A©Ò¦³ªº¥i°ÊºA¸ü¤J¿é¤Jªk³£¬O¸g¥Ñ³oùضi¤J xcin
   ¨t²Î¡C¦¹®Ö¤ßºûÅ@µÛ©Ò¦³¿é¤Jªkªº¬ÛÃö¸ê®Æ¡AÅý IMC ¨t²Î¨ú¥Î¡C¦³Ãö¨ä¸Ô²Ó²Ó¸`
   ½Ð°Ñ¦Ò module ¤@¤å¡C


--------------------------------------
E. GUI system: (include/gui.h, gui.c)

   ³o¸Ì¬O GUI ¨t²Îªº®Ö¤ß³¡¤À¡A©Ò¦³ªº xcin µøµ¡Ã¸¹Ï»P¾Þ§@³£¬O¦b³oùا¹¦¨¡C
   ¦Ó¨ä gui_t ¸ê®Æµ²ºc¤¤Àx¦s¤F¾ã­Ó¨t²Îªº¥þ°ìÅܼơA¦p xcin µøµ¡·|¥Î¨ìªºÃC
   ¦â¡B¦r«¬¦WºÙ¡BX Server ªº¬ÛÃö¸ê°T .... µ¥µ¥¡C

   ¾ã­Ó GUI ¨t²Î©³¤UÁÙ¤À¦¨¨â­Ó¤l¨t²Î¡A¤@¬° FontSet ºÞ²z¨t²Î¡A¤G¬° winlist
   ºÞ²z¨t²Î¡A¥Ü·N¹Ï¦p¤U:

			GUI core
			   |
	      +------------+------------+
              |                         |
           FontSet sys		   winlist sys
					|
			     +----------+----------+-------------+
			     |          |          |             |
		       gui_main.c  gui_main2.c  gui_menusel.c  gui_overspot.c

   FontSet ªº³¡¤À¸û¬°³æ¯Â¡A¥¦­t³d²Î¤@ºûÅ@¾ã­Ó GUI ¨t²Î¤¤©Ò»Ýªº¦r«¬ªº¶}±Ò¡B
   Ãö³¬ .... µ¥¡AÁ×§K¦r«¬ªº­«½Æ¶}±Ò¡A©ÎªÌÃö³¬¤F¤£¸ÓÃöªº¦r«¬¡C

   ¦Ó winlist ¬[ºc«hªþ¤© xcin ¶}±Ò¦h­«µøµ¡ªº¯à¤O¡A¨ä¹ê¥¦¥i¥H³Qµø¬°¤@­Ó²³æ
   ªº widget set¡A¨ä¸ê®Æµ²ºc¦p¤U:

===========================================================================
typedef struct winlist_s winlist_t;
struct winlist_s {
    Window window;		/* window of the winlist */
    xtype_t wtype;		/* winlist type */
    int imid;			/* IMC number */
    xmode_t winmode;		/* the current mode of the window */

    int pos_x, pos_y;
    unsigned int width, height, c_width, c_height;
    font_t *font;
    unsigned short n_gc;
    GC *wingc;

    void *data;			/* Data for window drawing */
    void (*win_draw_func)(gui_t *, winlist_t *);
				/* Function to draw the window */
    void (*win_attrib_func)(gui_t *, winlist_t *, XConfigureEvent *, int);
				/* Function when XConfigureEvent received */
    void (*win_destroy_func)(gui_t *, winlist_t *);
				/* Function to destroy window */
    winlist_t *next;
};
===========================================================================

   ¨ä¤¤ wtype ¥i¥H¦³¤TºØ winlist §Î§O:

	WTYPE_MAIN:	¦¹¬° xcin ¥Dµøµ¡¡A¦p gui_main, gui_main2¡C
	WTYPE_GUIREQ:   ¦¹¬° xcin GUI Request µøµ¡¡A¦p gui_menusel .... µ¥¡C
	WTYPE_OVERSPOT: ¦¹¬° xcin OverTheSpot µøµ¡¡C

   ¦Ó winmode «h¼Ð¥Ü¤F¥Ø«eµøµ¡ªºª¬ºA:

	WMODE_MAP:	ªí¥Ü¥Ø«eµøµ¡¬OÅã¥Ü¥X¨Ó©ÎÁôÂáC
	WMODE_EXIT:	ªí¥Ü¥Ø«eµøµ¡¬O§_¥¿·Ç³Æ­nÃö³¬ (destroy)¡C

   ¦Ó¥H¤U¤T­Ó¨ç¦¡ªº§@¥Î¤À§O¬O:

        win_draw_func:  ¥Î¨Óµeµøµ¡¥Îªº¡A¦pªGµ{¦¡¹B§@¤¤»Ý­nÅã¥Ü©ÎÁôÂõø
                        µ¡®É¡A½Ð¦b¦¹©I¥s gui_winmap_change¡C¦Ó¥Î¨Óµeµø
                        µ¡©Ò»Ýªº¸ê®Æ´N¦b data pointer ©Ò«ü¦ì¸m¡C
        win_attrib_func:  ·í¦¹µøµ¡±µ¨ì XConfigureEvent ®É (¦pµøµ¡³Q·Æ¹«
                        ©ì°Ê¡Aµøµ¡³Q©ñ¤jÁY¤p .... µ¥)¡A³o­Ó¨ç¦¡´N·|³Q©I
                        ¥s¡A³o®É§Ú­Ì´N¥i¥H¥Î¥¦¨Ó³]©wµøµ¡·sªº pos_x, pos_y,
                        width, height, etc.
        win_destroy_func:  ·í¦¹µøµ¡³Q destroy ®É·|³Q©I¥s¡A³o®É§Ú­Ì¥i¥H¥Î
                        ¥¦¨Ó°µ¤@¨Ç¦¬§Àªº°Ê§@ (¦pªG»Ý­nªº¸Ü)

   ¨ä¤¤ win_attrib_func »P win_destroy_func ¥i¥H³]¬° NULL, «h xcin ·|¥H¹w³]
   ªº¤è¦¡¨Ó³B²z¡C

   ¦Û xcin-2.5.2 ¶}©l¡A¨ä¥Dµøµ¡¦³¨âºØ¡A¹Ï¥Ü¦p¤U:

		+-------------------------------------------+
   ²Ä¤@¥Dµøµ¡:  |                     a                     |
		+---------+---------+--------------+--------+
		|    b    |    c    |      d       |   e    |
		+---------+---------+--------------+--------+

		+-------+-------+-------+
   ²Ä¤G¥Dµøµ¡:  |   b   |   d   |   e   |
		+-------+-------+-------+

   a. ¿é¤Jªk¦h­«¦rÅã¥Ü°Ï¡C

   b. ¿é¤Jªk¦W»Pª¬ºAÅã¥Ü°Ï (¦p [¤º½X][¥b§Î])¡C

   c. ¿é¤Jªk²Õ¦r°Ï¡C

   d. ¿é¤Jªk²Õ¦rÅã¥Ü°Ï¡A¥i¥Î°µ§¹¦¨²Õ¦r«á¡AÅã¥Ü¸Ó¦r§¹¾ãªº¦rÁä½X¡C

   e. ¿é¤Jªk­^¤å¦WÅã¥Ü°Ï (¦p zh_hex, phone µ¥)¡C

   ¹ï©ó²Ä¤@¥Dµøµ¡¦Ó¨¥¡A¥¦¥D­n¬O¥Î¦b Root input_style ¤Wªº¡A©Ò¦³ªº xcin ªº²Õ
   ¦r»Pª¬ºA¸ê°T³£Åã¥Ü¦b³o¸Ì¡C¦Ó¥B¡A·í rcfile ¤¤¬Y¿é¤Jªkªº SINMD_IN_LINE1 ³]
   ¬° "YES" ®É¡A«h­ì¥»¦b d ªº¿é¤Jªk²Õ¦rÅã¥Ü·|§ï¦b a °Ï¤¤Åã¥Ü¡C

   ¹ï©ó²Ä¤G¥Dµøµ¡¦Ó¨¥¡A¥¦¥D­n¬O¥Î¦b OverTheSpot input_style ¤Wªº¡A¥Ñ©ó©Ò¦³
   ªº²Õ¦r¸ê°T³£¤w²¾¦Ü OverTheSpot µøµ¡¡A¬G¦b³o¸Ì©Ò»ÝÅã¥Üªº¸ê°T´N´î¤Ö«Ü¦h¡A
   ¦]¦¹¦¹µøµ¡´N¥i¥H¤p«Ü¦h¡C

   GUI ¨t²Î¬O¦b¥H¤U¨âºØª¬ªp¤U¤~¶i¦æÃ¸¹Ïªº¡A¤@¬O±µ¨ì Expose event, ¥t¤@¬O
   ·í¥ô¦ó¿é¤Jªkª¬ºA§ïÅܮɡC©Ò¿×¿é¤Jªkª¬ºA§ïÅÜ¡A¥]¬A¤Á´«¿é¤Jªk¡BºV¤J¥ô¦ó
   ¦³·N¸qªº¦rÁäµ¥µ¥¡C³o®É GUI ¨t²Î·|¸ò¾Ú gui_t->winchange Åܼƪº­È¨Ó§P
   Â_¬O§_¦³¥ô¦ó¿é¤Jªkª¬ºAªº§ïÅÜ¡A¦]¦¹·í XIM ¨t²Î­Y¬dı¦³¿é¤Jªkª¬ºA§ïÅܮɡA
   ¥u­n§ïÅܳo­Ó­È¡A§Y¥i±Nµ²ªG¤ÏÀ³¦b xcin µøµ¡¤W¡C winchange ª¬ºA©w¸q¦p¤U:

   WIN_CHANGE_IM:  ·í¥¦¬° on ®É¡Aªí¥Ü¿é¤Jªkª¬ºA¤w§ïÅÜ¡C

   WIN_CHANGE_FOCUS:  ·í¥¦¬° on ®É¡Aªí¥Ü¥Ø«e¿é¤Jªº XIM clients µøµ¡¤w§ïÅÜ¡C

   WIN_CHANGE_REDRAW:  ·í¥¦¬° on ®É¡Aªí¥Ü xcin µøµ¡»Ý­n­«µe¡C³q±`¬O¤W­z¨â
		       ºØ±¡ªpµo¥Í®É¡A¤~»Ý­n­«µeµøµ¡¡C

   WIN_CHANGE_BELL:  ªí¥Ü»Ý­nµo¥X²Ä¤@ºØ¡u¹Í¡vÁn¡C

   WIN_CHANGE_BELL2:  ªí¥Ü»Ý­nµo¥X²Ä¤GºØ¡u¹Í¡vÁn¡C

   WIN_CHANGE_BELLALL:  ªí¥Ü»Ý­nµo¥X¡u¹Í¡vÁn¡A¤£½×¬O²Ä¤@ºØ©Î²Ä¤GºØ¡C

   ¥Ñ©ó GUI ¨t²Î¦bµe¹Ï®É¬O®Ú¾Ú xccore ¤¤ªº¿é¤Jªkª¬ºA¸ê®Æ¨Óµeªº¡A¦Ó³o
   ¨Çª¬ºA¸ê®Æ¬O¨Ó¦Û©ó xccore.ic µ²ºc¡A§Y¥Ø«e¤u§@¤¤ªº IC (½Ð¨£«áÀYªº»¡
   ©ú)¡C¦]¦¹¡A¤Z¬O¤ÏÀ³¦b xccore.ic ¤¤ªº§ïÅÜ¡A·|§Y®É¤ÏÀ³¦b GUI ¨t²Î¤W¡C

   °£¦¹¤§¥~¡A GUI ¨t²ÎªºÃ¸¹Ï¼Ò¦¡¦³«Ü¦h¥i¥HÂǥѿé¤Jªk»P XIM client ªº·¾
   ³q¤¶­±: IC ªº inpinfo (¨£«á­z»P module ¤@¤åªº»¡©ú) ²ÕºA¨Ó§ïÅÜ¡A¦p¦¹
   ¥i¥HÂÇ¥Ñ GUI ø¹Ïªº§ïÅÜ¡A¦Ó¥R¥÷¤ÏÀ³¥Ø«e¿é¤Jªk©Ò³Bªºª¬ºA¡C
   
   ·í xcin §¹¦¨©Ò¦³³¡¤Àªºªì©l¤Æ°Ê§@®É¡A¥¦´N·|¶i¤J GUI ¨t²Îªº gui_loop()
   ¨ç¦¡°j°é«ùÄò°õ¦æ¡Aª½¨ì xcin µ²§ô¬°¤î¡C¥¦ªº¤u§@¬Oµ¥«Ý¤U¤@­Ó X event
   (XNextEvent()), ¨Ã§â¸Ó X event ¥æµ¹ XFilterEvent() ¨Ó³B²z¡C¦pªG¥¦¬O
   ¨Ó¦Û©ó X apps ªº XIM event (§Y X apps ¶i¦æ¤¤¤å¿é¤Jµ¥°Ê§@) ®É¡A Xlib 
   ·|±N¦¹ event ¶Çµ¹ XIM ¨t²Î¨Ó³B²z (½Ð¨£«áÀYªº»¡©ú)¡C­Y¤£¬O³oÃþªº X 
   event, ¤~¥æ¥Ñ gui_loop() ¶i¦æ¨ä¥Lªº°Ê§@ (¦p­«µeµøµ¡) ¡AµM«á¶g¦Ó´_©l¡C


--------------------------------------
F. XIM system (include/xcin_core.h, xim.c, fkey.c, lib/IMdkit)

   ³o¬O³B²z XIM ¨ó©wªº®Ö¤ß¡A¤]¬O©Ò¦³¨Ó¦Û module ¨t²Îªº¿é¤Jªk»P X apps ªº
   ·¾³q¤¶­±¡C¨C¤@­Ó¨Ï¥Î XIM ¨ó©w¡B¥i±µ¨ü xcin ¿é¤Jªº X window µøµ¡¦b¶}±Ò
   «á¡A³£·|°e¤@­Ó°T¸¹¨ì³oùØ¡A¦Ó XIM ¨t²Î«K²£¥Í¤@­Ó IC (Input Context) µ¹
   ¥¦¡C IC °O¿ýµÛ¥Ø«e¿é¤Jªkªºª¬ºA»P¬ÛÃöªº XIM ¨ó©w¸ê®Æ¡C

   ¥»¨t²Î¨Ã¨S¦³ª½±µ»P Xlib ·¾³q¡A¦Ó¬O³z¹L IMdkit lib »P Xlib ·¾³q¡C IMdkit
   ¨Ã¤£¬O§Ú­Ì©Òµo®iªº¡A¥¦¬O yhsiao ¥S»P gamete ¥S¤¶²Ðµ¹§Ú­Ìªº¡A¥¦¥i¥H³B²z 
   Xlib ©³¼hªº½ÆÂø¸ê®Æµ²ºc»P¨ó©w¡AÅý§Ú­Ì¦b¨Ï¥Î XIM ¨ó©wªº¹Lµ{¥i¥H²¤Æ¡C¦b
   ªì©l¤Æ¹Lµ{¤¤¡A§Ú­Ì§Q¥Î¥¦ªº¨ç¦¡¦V Xlib µù¥U xcin ªº¬ÛÃö¸ê®Æ¡AÅý¤§«á±Ò°Ê
   ªº¨ä¥L X apps ª¾¹D¦³ xcin ³o¤@­Ó XIM server¡C©Òµù¥Uªº¸ê®Æ­«­nªº¦³:

   IMServerName:  §Ú­Ìªº XIM server ¦W¡C­Y¦b zh_TW.Big5 locale Àô¹Ò¤U±Ò°Ê
	xcin ªº¸Ü, «h IMServerName «K·|³]¬° "xcin", §_«hªº¸Ü·|³]¬° 
	"xcin-<locale name>"¡C

   IMLocale:  §Ú­Ì©Ò¨Ï¥Îªº LC_CTYPE locale¡C

   IMInputStyles:  xcin ¤ä´©ªº¿é¤J¼Ò¦¡¡C¥Ø«e xcin ¥u¤ä´© Root »P OverTheSpot
	³o¨âºØ¿é¤J¼Ò¦¡¡A¥¼¨Ó§Ú­Ì·|¦A¥[¤J¨ä¥L¤ä´©¡C

   IMProtocolHandler:  XIM event ³B²z¨ç¦¡¡A¦¹¬° XIM ³B²z¤¤¤ß¡C

   IMOnKeysList:  µù¥U trigger keys¡C xcin ±Ä¥Î XIM °ÊºA³s½uªº¼Ò¦¡¡A¤]´N¬O
	·í X apps ¦b°µ­^¤å / ¥b§Î¿é¤J®É¡A¨Ï¥ÎªÌºV¤Jªº¦rÁ䤣·|°e¤J xcin, ª½
	¨ì¥L«ö¤U trigger keys ¤Á´«¦¨¤¤¤å©Î¥þ§Î¿é¤J®É¡A Xlib ¤~·|±N¨Ï¥ÎªÌºV
	¤Jªº¦rÁä°eµ¹ xcin ³B²z¡C xcin µù¥Uªº trigger keys ­p¦³: 

	¤¤­^¤Á´«: ¹w³]¬° ctrl+space

	¥þ§Î¥b§Î¤Á´«: ¹w³]¬° shift+space

	¿é¤Jªk¤Á´«: ¹w³]¬° ctrl+shift, shift+ctrl, ¤Î ctrl+alt+[0123456789-=]

	§Ö³t¤ù»y¿é¤JÁä: ¹w³]¬° shift+alt+<ascii key>

	¤W­zªº trigger keys ³£¥i¥HÂÇ¥Ñ rcfile ªº³]©w¦Ó§ïÅÜ¡A¥B¥æ¥Ñ fkey.c
	ºûÅ@¡C¥¦·|§PÂ_¨Ï¥ÎªÌ³]©wªº trigger keys ¬O§_¦Xªk¡A¨ÃºÉ¶qÁ×§K½Ä¬ðªº
	µo¥Í¡C

   int im_protocol_handler(XIMS ims, IMProtocol *call_data) ¨ç¦¡¬O xcin µù
   ¥Uªº IMProtocolHandler ¡A©Ò¦³¨Ó¦Û Xlib (IMdkit) ªº XIM event ¥þ³¡³£·|°e
   ¨ì³o³B²z¡A¨ä¤¤ call_data ¬O³o¨Ç event ªº¤º®e¡C¦Ó³o¨Ç event ¨ä®É¬O¨Ó¦Û©ó 
   GUI ¨t²Î¤¤ gui_loop() ¨ç¦¡©Ò©I¥sªº XNextEvent(), ¸g¥Ñ XFilterEvent() ¹L
   Âo¡A¦pªGµo²{¬OÄÝ©ó XIM event, «hª½±µ¸g¥Ñ IMdkit °e¨ì³oùØ¡A¦Ó¤£¦A°e¦^µ¹ 
   gui_loop() ¨ç¦¡¡C XIM event ­p¦³:

   XIM_OPEN:  ·í¤@­Ó X app ­è±Ò°Ê¡A¨Ã¥B¨M©w¨Ï¥Î xcin °µ¬° XIM server ®É¡A
	¥¦´N·|°e³o­Ó event µ¹ xcin¡C

   XIM_CLOSE:  ·í¤@­Ó X app ­nµ²§ô«e¡A¥¦À³¸Ó­n°e³o­Ó event µ¹ xcin ³qª¾»¡
	­n°µ¤@¨Ç²M²zªº°Ê§@¡C

   XIM_CREATE_IC:  ·í¤@­Ó X app ±Ò°Ê«á¡A¥¦¨C¶}¤@­Ó¨Ï¥Î XIM ªºµøµ¡¡A´N·|°e³o
	­Ó event ¹L¨Ó¡C³o®É­Ô xcin ¥²¶·¬°¥¦²£¥Í¤@­Ó IC ¥HÀx¦s¬ÛÃö¸ê®Æ¡C

   XIM_DESTROY_IC:  ·í X app ¬Y­Ó¨Ï¥Î XIM µøµ¡­nÃö³¬«e¡A¥¦À³¸Ó­n°e³o­Ó 
	event µ¹ xcin ¥H³qª¾ xcin °µ¤@¨Çµ«á¤u§@¡C³o®É xcin ¥i¥H±NÄÝ©ó
	¦¹µøµ¡ªº IC ²M²z±¼¡C

   XIM_SET_IC_FOCUS:  ·í·Æ¹«ÂI¿ï¬Y­Ó¨Ï¥Î XIM ªº X app µøµ¡®É¡A¸Óµøµ¡´N·|°e
	³o­Ó event µ¹ xcin¡C³o®É xcin ´N¥²¶·¶i¦æ¤Á´« IC ªº¤u§@¡C

   XIM_UNSET_IC_FOCUS:  ·í·Æ¹«ÂI¿ï¨ä¥Lªº X µøµ¡®É¡A­ì¥ý¥¿¤u§@¤¤ªº¨Ï¥Î XIM 
	µøµ¡´N·|°e³o­Ó event µ¹ xcin, µM«á¤~Â÷¶} focus¡C

   XIM_TRIGGER_NOTIFY:  ·í­ì¥»ªº X app ¤u§@µøµ¡¨S¦³»P xcin ³s½u (§Y³B©ó­^
	¼Æ / ¥b§Î¿é¤J) ®É¡A¦pªG­n¶i¦æ¤¤¤å / ¥þ§Î¿é¤J¡A«h·í¨Ï¥ÎªÌ«ö¤U
	trigger key, IMdkit «K·|°e³o­Ó°T¸¹µ¹ xcin ¡C³o®É xcin ¥²¶·¶i¦æ¬°
	¦¹ IC ¶i¦æªì©l¤Æªº°Ê§@¡C

   XIM_FORWARD_EVENT:  ·í¨Ï¥ÎªÌ«ö¤U trigger key «á¡A¥L©¹«á¦b¦¹µøµ¡¤¤ºV¤J
	ªº¨C¤@­Ó¦r¡A xcin ³£·|±µ¨ì³o­Ó event, ¦P®É xcin ¤]·|±q call_data
	ªº¨ä¥L¤º®e¤¤ª¾¹D¥L«ö¤F¨º¨Ç«öÁä¡A³o®É xcin ·|®Ú¾Ú³o¨Ç«öÁä¶i¦æ¥H¤U
	ªº³B²z:

	1. ¬O¤£¬O trigger keys? ¨Ï¥ÎªÌ¥i¯à¦b¿é¤J¤¤³~¤Á´«¿é¤Jªk¡A©Î«ì´_­^
	   ¤å¿é¤Jµ¥¡C¦pªG¬O trigger key, «h xcin ·|¶i¦æ¿é¤Jªk¤Á´«°Ê§@¡C

	2. ­Y¤£¬O trigger keys, «h xcin ·|±N¦rÁä¶Çµ¹¥Ø«e¿é¤Jªkªº keystroke()
	   ¨ç¦¡¤¤¡A¦P®É¤]±N¥Ø«eªº¿é¤Jªkª¬ºA¸ê®Æ inpinfo_t *inpinfo ¶Ç°eµ¹
	   ¥¦¡AÅý¥¦¶i¦æ§PÂ_»P²Õ¦r¤u§@¡CµM«á xcin ·|®Ú¾Ú¥¦ªº¶Ç¦^­È¨M©w¤U¤@
	   ¨Bªº¦æ°Ê¡C

	3. ­Y¿é¤Jªkªº keystroke ¨ç¦¡¹ï©ó³o­ÓÁä¨S¦³¿³½ì¡A¦ý¥Ø«e¬O³B©ó¥þ§Î
	   ¿é¤Jª¬ºA¡A©ÎªÌ»¡ keystroke ¨ç¦¡§Æ±æ¥þ§Î¿é¤Jªk¨Ó³B²z³o­Ó¦rÁä¡A
	   «h xcin ·|±N³o­Ó¦rÁä¶Çµ¹¥þ§Î¿é¤Jªk¼Ò²Õ³B²z¡C

	4. ­Y¿é¤Jªkªº keystroke() ¨ç¦¡©Î¥þ§Î¿é¤Jªk¼Ò²Õ§¹¦¨²Õ¦r¡A¨Ã§Æ±æ²Õ
	   ¥Xªº¦r¦^¶Çµ¹ X app ®É¡A xcin ·|±N³o­Ó¦r¦^¶Çµ¹ X app¡C

	5. ­Y¿é¤Jªkªº keystroke() ¨ç¦¡©Î¥þ§Î¿é¤Jªk¼Ò²Õªí¥Ü³o­Ó¦rÁä¹ï¥¦­Ì
	   ¦Ó¨¥³£¨S¦³·N¸q¡A«h xcin ·|±N³o­Ó¦rÁäÁÙµ¹ Xlib, Xlib ¦A±N¦rÁäÁÙ
	   µ¹ X app¡C

   XIM ¨t²Îªº¬ÛÃö¸ê®Æµ²ºc¤¤¡A³Ì­«­nªº¬O xccore.ic, ¥¦¬O¤@­Ó«ü¦V¥Ø«e¤u§@
   ¤¤ªº IC ªº¦ì§}¡C


--------------------------------------
G. IC manager (include/IC.h, xim_IC.c)

   ³o­Ó³¡¤À¹ê»Ú¤W»P XIM ¨t²Î¬O¤@Å骺¡A¥¦­t³dºûÅ@©Ò¦³²£¥Íªº IC ¦ê¦C¡C IC
   ¬O¤@­Ó«Ü½ÆÂøªº¸ê®Æµ²ºc¡A¥¦°O¿ý¤F¥Ø«e³o­Ó¤u§@µøµ¡ªº¿é¤Jªkª¬ºA¡C¨ä©w¸q
   ¦p¤U (³¡¤À)

===========================================================================
typedef struct _IC IC; /* forward declaration */
    CARD16              id;             /* ic id */
    CARD16              connect_id;     /* id of connected client */
    time_t              exec_time;      /* recent excution time */
    xmode_t             ic_state;       /* status of the IC */
    ic_rec_t            ic_rec;         /* the IC resource setting by client */
    IM_Context_t       *imc;            /* the IM Context */
    IC                 *next;
};
===========================================================================

   ¥H¤Wªº¦UÄæ¦ì·N¸q¬°:

   id:  ¦¹ IC ªº½s¸¹¡C

   connect_id:  ¨Ï¥Î¦¹ IC ªº X app ½s¸¹¡C

   exec_time:  ¦¹ IC ³Ìªñªº¨Ï¥Î»P°õ¦æ®É¶¡¡C³o¬O¥Î©ó garbage collection ¥Î¡C
	¸Ô¨£¥H¤Uªº»¡©ú¡C

   ic_state:  ¦¹ IC ªº¥Ø«eª¬ºA¡A­p¦³:
	IC_NEWIC:	¥Nªí¦¹ IC ¬°·s²£¥Íªº IC¡C
	IC_CONNECT:	¦¹ IC ¥¿³B©ó¤¤¤å¿é¤J¼Ò¦¡¡A§Y client ¥¿»P xcin ³s½u¡C
	IC_FOCUS:	¦¹ IC ¬°¥Ø«e¤u§@¤¤ªº IC¡C

   ic_rec:  ¦¹ IC ¤¤©Ò¦³¨Ó¦Û XIM client ªº¸ê®Æ¡A¨ä¤¤­«­nªº¥]¬A:
	ic_value_set:	  ¥Nªí¦³¨º¨Ç IC ªºÅܼƭȦ³³Q XIM client ³]©w¡C
	ic_value_update:  ¥Nªí¦³¨º¨Ç IC ªºÅܼƭȳQ XIM client §ó·s¹L¤F¡C
	input_style:	  ¦¹ IC ªº XIM ¿é¤J¼Ò¦¡¡C
	client_win, focus_win:  XIM client ªº window¡C
	pre_attr:	  ¦¹ IC ªº²Õ¦rÅÜ¼Æ­È (¥i³Q XIM client ³]©w)¡C

   imc:  «ü¦V IMC ¦ê¦Cªº«ü¼Ð (¨£«á­z)¡C

   ¥Ñ©ó IC ¬O­t³d¦U XIM clients »P xcin ¤§¶¡ªº·¾³q¤¶­±¡A¨C¤@­Ó XIM client µø
   µ¡¦b xcin ³oÃä³£·|«ü©w¤@­Ó IC ¨Ó´£¨ÑªA°È¡A¬G¥¦­ÌÀH®É´x´¤µÛ¦U XIM clients
   ªº°ÊºA¡A«O«ù¥¦­Ìªº¸ê®Æ¨Ñ xcin ÀH®É¨ú¥Î¡CµM¦Ó¡A¥¦­Ì¤£­t³d¿é¤Jªkªº³¡¤À¡C¦]
   ¬°¦U IC ¥i¯à¿é¤Jªk©¼¦¹¦U¦Û¿W¥ß¡A¤]¥i¯à¦@¥Î¦P¤@­Ó¿é¤Jªkµ²ºc¡Aµø¨ä©Ò¨Ï¥Îªº
   IMC ¬°¦ó¦Ó¨M©w (¨£«á­z)¡C


   IC garbage collection:

   ¥Ñ©ó¨Ã«D©Ò¦³ªº XIM client ¦bµ²§ô®É³£·|°e XIM_CLOSE ©Î XIM_DESTROY_IC
   µ¹ xcin, ³o·|³y¦¨ xcin ©Ò¶}±Ò¨Ï¥Îªº IC ·|³vº¥²Ö¿n¡A¶V¨Ó¶V¦h¡C¦A°õ¦æ®Ä
   ²v»Pµ{¦¡½ÆÂø«×ªº¦Ò¶q¤U¡A¦P®É¤]¦Ò¼{¤F racing condition¡A ¬G xcin ¥Ø«e
   ±Ä¥Î¥H¤U²³æªº garbage collection ¾÷¨î:

   xcin ¤j¦Ü¤W¨C¹j 5 ¤ÀÄÁ°µÀˬd¤@¦¸©Ò¦³ªº IC, ¥H½T©w¨ä©ÒÄݪº client ÁÙ¬¡
   µÛ¡C¤§©Ò¥H¥Î¡u¤j¦Ü¤W¡v³o­Ó¦r²´¡A¬O¦]¬°§Ú¨S¦³¥Î multi-thread ©Î fork 
   ¥t¤@­Ó process ¨Óºë·Ç±±¨î®É¶¡¡A¦Ó¬Oª½±µ±NÀˬd¨ç¦¡´¡¤J 
   im_protocol_handler() ¤¤, ³o­Ó¨ç¦¡¬O³Ì±`³Q©I¥sªº¡A½Ñ¦p¦b client «ö¥ô
   ¤@Áä¡B©Î¬Æ¦Ü¥Î·Æ¹«ÂI¿ï client, ³£¦³¥i¯à·|©I¥s¨ì³o­Ó¨ç¦¡¡C¦]¦¹¡A¥u­n§Ú
   ­Ì«ùÄò¨Ï¥Î¥ô¦ó¤@­Ó client, ´N·|¤£°±¦a¶i¤J im_protocol_handler()¡A¬G
   ¦b¦¹ª½±µ¦w´¡Àˬd¨ç¦¡¡AÀ³¸Ó¬O³Ì²³æ¤]³Ì¦³®Äªº¿ìªk¡C

   ¬°¤FÅU¤Î racing condition, §Ú¦b IC µ²ºc¤¤¦h¥[¤F time_t exec_time ³o
   ­Ó variable, ¨C·í³o­Ó IC ³Q¨Ï¥Î®É¡A exec_time ´N·|³Q³]¤J¥Ø«eªº®É¶¡¡A
   ¦ÓÀˬd¨ç¦¡³Ì«á¥u·|¬D¶W¹L 10 ¤ÀÄÁ¥H¤W idle ªº IC ¶i¦æÀˬd¡A¦pªGµo²{¸Ó
   IC ©ÒÄݪº window ¤£¦b¤F¡A´N±N¦¹ IC °µ¸ê·½¦^¦¬¡C


---------------------------------
H. IM Context (IMC) System

   IMC ¬O«ü Input Method Context, ¥¦´N¬O¿é¤Jªkªº¹ê»Ú¸ê®Æµ²ºc¡C¦b xcin-2.5.1
   ¤Î¥H«eªºª©¥»¤¤¡AIMC ªº³¡¤À¬Oª½±µ¼g¦b IC ùØÀYªº¡A¦p¦¹·í±z¦b¥Î·Æ¹«¤Á´«
   XIM client µøµ¡®É¡Axcin µøµ¡¤º®e (¤]´N¬O¦U IC ªº¿é¤Jªk¥Ø«eª¬ºA) ¤]¸ò
   µÛÅÜ¡C

   µM¦Ó¡A¦b¬Y¨Ç±¡ªp¤U¡A§Ú­Ì¤£§Æ±æ³o¼Ë¡A¯S§O¬O¦b bimsphone ¿é¤Jªk¤W¡A§Ú
   ­Ì©¹©¹§Æ±æ¦b¤Á´« clients ®É¡A¿é¤Jªkªºª¬ºA¤£­n§ïÅÜ¡A¤×¨ä¬O­è­è¤w¿é¤J
   ¨ì xcin buffer ùØÀYªº¨º¹ï¦r¡C¬°¤F¹F¨ì¦¹­n¨D¡A¤~±N IMC ³¡¤À¦Û IC ¤¤¤À
   Â÷¡C

   ²{¦b xcin ¦³¨âºØ mode: XCIN_SINGLE_IMC ON ¤Î XCIN_SINGLE_IMC OFF¡C¦b
   XCIN_SINGLE_IMC OFF ®É¡A¨C­Ó IC ³£¦U¦Û·|¦³¤@­Ó IMC, ©ó¬O¦U client ¶¡
   ªº¿é¤Jªkª¬ºA´N§¹¥þ¿W¥ß¡C­Y XCIN_SINGLE_IMC ON ®É¡A©Ò¦³ªº IC ³£·|¤À¨É
   ¦P¤@­Ó IMC, ©ó¬O¦U client ¶¡ªº¿é¤Jªkª¬ºA´N§¹¥þ¤@­P¡C

   IC ¦³¥¦ªº¥Í©R¶g´Á¡A³o»P client ªº Input Context ¶g´Á¬O¤@¼Ëªº¡C·í¤@­Ó
   ·sªº client Input Context ²£¥Í®É¡A xcin ³oÃä´N²£¥Í¤@­Ó·sªº IC, ¦Ó·í
   client ªº Input Context µ²§ô«á¡A xcin ³oÃ䪺 IC ¤]µ²§ô¤F¡C

   IMC ¤]¦³¥¦ªº¥Í©R¶g´Á¡A¦ýµø xcin ©Ò³Bªº mode ¦Ó©w¡C¦pªG¬O XCIN_SINGLE_IMC
   ON ®É¡A¥¦ªº¥Í©R¶g´Á´N»P xcin ¥Dµ{¦¡¤@¼Ëªø¡C¦pªG¬O XCIN_SINGLE_IMC OFF
   ®É¡A¥¦ªº¥Í©R¶g´Á´N»P IC ¤@¼Ëªø¡C

   IMC ªº¸ê®Æµ²ºc¦p¤U:

==============================================================================
typedef struct _IMC IM_Context_t;
struct _IMC {
    unsigned short      id;             /* id of this IMC */
    unsigned int        icid;           /* id of the current attached IC */
    ic_rec_t           *ic_rec;         /* point to the current IC resource */

    inp_state_t         inp_state;      /* ic cinput state */
    inp_state_t         inp_num;        /* ic cinput num */
    inp_state_t         sinp_num;       /* ic cinput num (sinmd) */
    imodule_t          *imodp;          /* current binding cinput module */
    imodule_t          *s_imodp;        /* show keystroke cinput module */
    inpinfo_t           inpinfo;        /* inp info referenced by gui */
    unsigned int        skey_size;      /* sinmd_keystroke buf size. */
    wch_t              *sinmd_keystroke;/* for keystroke of a published cch. */
    unsigned int        cch_size;       /* cch buf size. */
    char               *cch;            /* composed char for commit. */

    int                 n_gwin;         /* IM GUI request window recorder. */
    greq_win_t          gwin[MAX_GREQ_CNT];
    Window              overspot_win;   /* OverTheSpot candidate window. */

    IM_Context_t       *next;
    IM_Context_t       *prev;
};
==============================================================================

   ¨ä¤¤ id ´N¬O§Ú­Ì¦b¨ä¥L¦a¤è©Ò¨£¨ìªº imid¡C¦pªG SINGLE_IM_CONTEXT ¥´¶}®É¡A
   «h¥u¦³¤@­Ó IMC¡A¨ä imid ¬° 1¡F¦pªG¨S¦³¥´¶}¡A«h¨ä imid «K·|»P icid ¤@¼Ë¡C

   §Ú­Ì¥i¥H¨£¨ì¡A³o­Óµ²ºc¤¤¥]§t¤F©Ò¦³ªº¿é¤Jªk¸ê®Æ¡A¥]¬A¨Ï¥Î¨º¤@­Ó¿é¤Jªk¼Ò²Õ
   (imodp »P s_imodp)¡B¿é¤Jªkªºª¬ºA (inp_state, inp_num »P sinp_num)¡B»P¦U
   ¿é¤Jªk¼Ò²Õªº·¾³q¤¶­± (inpinfo)¡B¥H¤Î OverTheSpot µøµ¡©M GUI Request µøµ¡
   µ¥µ¥¡C¦Ü©ó ic_rec «h¬O«ü¦V IC µ²ºcªº ic_rec¡A¦p¦¹¿é¤Jªk¨t²Î»P GUI ¨t²Î«K
   ¥iÀH®ÉŪ¨ú XIM client ªº°ÊºA¡C¥i¥H»¡¦¹µ²ºc¬O¿é¤Jªk¼Ò²Õ»P XIM ¨t²Î¤§¶¡ªº
   ¾ô¼Ù¡C

   ³oùØÁÙ­n´£¤@¤U IMC ªºª¬ºA:

        IM_CINPUT ON:   ¦¹ IMC ¶i¤J¤¤¤å¿é¤J¼Ò¦¡
        IM_CINPUT OFF:  ¦¹ IMC ³B©ó­^¤å¿é¤J¼Ò¦¡
        IM_2BYTES ON:   ¦¹ IMC ¶i¤J¥þ§Î¿é¤J¼Ò¦¡
        IM_2BYTES OFF:  ¦¹ IMC ³B©ó¥b§Î¿é¤J¼Ò¦¡
        IM_XIMFOCUS ON: ¦¹ IMC ¶i¤J¤¤¤å focus ª¬ºA
        IM_XIMFOCUS OFF:¦¹ IMC Â÷¶}¤¤¤å focus ª¬ºA
	IM_2BFOCUS ON:  ¦¹ IMC ¶i¤J¥þ§Î focus ª¬ºA
	IM_2BFOCUS OFF: ¦¹ IMC Â÷¶}¥þ§Î focus ª¬ºA

   ³oùذQ½× IM_CINPUT »P IM_XIMFOCUS ´N¦n¡AIM_2BYTES ­ì²z»P IM_CINPUT Ãþ
   ¦ü¡C©Ò¿× IMC ¶i¤J¤¤¤å focus ª¬ºA¡A¬O«ü¸Ó IMC ¤w¤Á´«¨ì¤¤¤å¿é¤J¼Ò¦¡¡A¥B
   ¨ä©Ò¹ïÀ³ªº XIM client µøµ¡³Q·Æ¹«ÂI¿ï¡A¦¨¬°«e´ºµøµ¡¡A±µ¤U¨ÓÁä½L¥´¦r´N·|
   ª½±µ§@¥Î¦b¸Ó client µøµ¡¤W¡C



T.H.Hsieh