²z xcin-2.5 ]pzPӵ{[cC

xcin-2.5 ]pz:

1. JkUۿWߥBҲդơC

2. ϥΪ̻P`@ˡAunǳƦn@ .cin ɡAb xcin UNనWϥΡAhb
   ݭnJkhg@ӼҲաC

3. JkMt@ "server" A]NO xcin VJkXШDA
   ӿJkhھڽШDX^C~AJkѻP xcin LʡC

4. xcin  locale, XIM [c]pAi¼зǤƪVAƱq
   ৹ѨM X window UJDC

oǲzAϱo xcin-2.5 Pª xcin w@ˡA򥻬[cpU:

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

HUNWϪU²檺C


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

   oO xcin ̩hu禡wAutd@²Ӱ򥻪ާ@C

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

   oO xcin  rcfile ŪtΡC䤽Ψ禡IsP xcintool sb@_A
   Ө֤߫h siod lib C siod @ӲVX lisp P Scheme yĶAo
   ϱo rcfile ]weiHĥYӴIuʪ lisp / Scheme yC

   xcin_rc tΥiHPɴ xccore P module Ū rcfile ƤΡAP
   ]iH xcin L~{ (p cin2tab) @q rcfile ŪCGڭ
   uݭn@ rcfile YinҦ xcin ]wC

   Ҧg siod P rcfile ŪtΩŪJܼ (]A CINPUT 
   ӳ]w) xsb xcin_rc ƵcA xcin @ module Ұ
   ö}llƮɡAcK|ǤJ module lƨ禡Ah module Ki
   HѦҸӵcưn]wʧ@C

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

   oO xcin D{ƵcAOѦ clkao SҳW xcin_core module
   ܹLӪCtd xcin Ұʮɤ@lưʧ@A]AŪJROCﶵB]
   w locale B rcfile ŪtŪ rcfile Bi xcin Ll
    .... APɥƵc٫Oثe xcin ҦATA]A GUIB
   XIMBHοJkACƵc xcin D{ҨpA xcin ֤ߪ
   AJkҲյLkѦҨ䤺eC

   ƵcA xccore.xcin_mode ΨӰO xcin AA@ΦG: @OO
   Ӧ rcfile (xcinrc) ]wպAAt@ӬOO xcin ɴAC


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

   oO xcin JkҲծ֤ߡAҦiʺAJJkOgѳoضiJ xcin
   tΡC֤ߺ@۩ҦJkơA IMC tΨΡCԲӲӸ`
   аѦ module @C


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

   o̬O GUI tΪ֤߳AҦ xcin øϻPާ@OboاC
   Ө gui_t ƵcxsFӨtΪܼơAp xcin |Ψ쪺C
   BrW١BX Server T .... C

    GUI tΩU٤ӤltΡA@ FontSet ޲ztΡAG winlist
   ޲ztΡAܷNϦpU:

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

   FontSet ¡AtdΤ@@ GUI tΤһݪr}ҡB
    .... AקKrƶ}ҡAΪFrC

    winlist [ch xcin }ҦhOAꥦiHQ@²
    widget setAƵcpU:

===========================================================================
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 iHT winlist ΧO:

	WTYPE_MAIN:	 xcin DAp gui_main, gui_main2C
	WTYPE_GUIREQ:    xcin GUI Request Ap gui_menusel .... C
	WTYPE_OVERSPOT:  xcin OverTheSpot C

    winmode hХܤFثeA:

	WMODE_MAP:	ܥثeOܥXөáC
	WMODE_EXIT:	ܥثeO_ǳƭn (destroy)C

   ӥHUTӨ禡@ΤOO:

        win_draw_func:  ΨӵeΪApG{B@ݭnܩõ
                        ɡAЦbIs gui_winmap_changeCӥΨӵe
                        һݪƴNb data pointer ҫmC
        win_attrib_func:   XConfigureEvent  (pQƹ
                        ʡAQjYp .... )AoӨ禡N|QI
                        sAoɧڭ̴NiHΥӳ]ws pos_x, pos_y,
                        width, height, etc.
        win_destroy_func:  Q destroy ɷ|QIsAoɧڭ̥iH
                        Ӱ@Ǧʧ@ (pGݭn)

   䤤 win_attrib_func P win_destroy_func iH] NULL, h xcin |Hw]
   覡ӳBzC

    xcin-2.5.2 }lADءAϥܦpU:

		+-------------------------------------------+
   Ĥ@D:  |                     a                     |
		+---------+---------+--------------+--------+
		|    b    |    c    |      d       |   e    |
		+---------+---------+--------------+--------+

		+-------+-------+-------+
   ĤGD:  |   b   |   d   |   e   |
		+-------+-------+-------+

   a. JkhrܰϡC

   b. JkWPAܰ (p [X][b])C

   c. JkզrϡC

   d. JkզrܰϡAiΰզrAܸӦr㪺rXC

   e. Jk^Wܰ (p zh_hex, phone )C

   Ĥ@DӨADnOΦb Root input_style WAҦ xcin 
   rPATܦbo̡CӥBA rcfile YJk SINMD_IN_LINE1 ]
    "YES" ɡAh쥻b d Jkզrܷ|b a ϤܡC

   ĤGDӨADnOΦb OverTheSpot input_style WAѩҦ
   զrTw OverTheSpot AGbo̩һܪTN֫ܦhA
   ]NiHpܦhC

   GUI tάObHUتpU~iøϪA@O Expose event, t@O
   JkAܮɡCҿ׿JkAܡA]AJkBVJ
   Nqr䵥Co GUI tη| gui_t->winchange ܼƪȨӧP
   _O_JkAܡA] XIM tέYdıJkAܮɡA
   unܳoӭȡAYiNGb xcin WC winchange AwqpU:

   WIN_CHANGE_IM:   on ɡAܿJkAwܡC

   WIN_CHANGE_FOCUS:   on ɡAܥثeJ XIM clients wܡC

   WIN_CHANGE_REDRAW:   on ɡA xcin ݭneCq`OWz
		       رpoͮɡA~ݭneC

   WIN_CHANGE_BELL:  ܻݭnoXĤ@ءu͡vnC

   WIN_CHANGE_BELL2:  ܻݭnoXĤGءu͡vnC

   WIN_CHANGE_BELLALL:  ܻݭnoXu͡vnA׬OĤ@ةβĤGءC

   ѩ GUI tΦbeϮɬOھ xccore JkAƨӵeAӳo
   ǪAƬOӦ۩ xccore.ic cAYثeu@ IC (ШY
   )C]AZOb xccore.ic ܡA|Yɤb GUI tΤWC

   ~A GUI tΪøϼҦܦhiHǥѿJkP XIM client 
   q: IC  inpinfo (zP module @媺) պAӧܡAp
   iHǥ GUI øϪܡAӥRثeJkҳBAC
   
    xcin Ҧlưʧ@ɡAN|iJ GUI tΪ gui_loop()
   禡jA xcin Cu@OݤU@ X event
   (XNextEvent()), ç X event 浹 XFilterEvent() ӳBzCpGO
   Ӧ۩ X apps  XIM event (Y X apps i椤Jʧ@) ɡA Xlib 
   |N event ǵ XIM tΨӳBz (ШY)CYOo X 
   event, ~ gui_loop() iLʧ@ (pe) AMgӴ_lC


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

   oOBz XIM w֤ߡA]OҦӦ module tΪJkP X apps 
   qCC@Өϥ XIM wBi xcin J X window b}
   A|e@ӰToءA XIM tΫKͤ@ IC (Input Context) 
   C IC OۥثeJkAP XIM wơC

   tΨèSP Xlib qAӬOzL IMdkit lib P Xlib qC IMdkit
   äOڭ̩ҵoiAO yhsiao SP gamete Sеڭ̪AiHBz 
   Xlib hƵcPwAڭ̦bϥ XIM wL{iH²ơCb
   lƹL{Aڭ̧QΥ禡V Xlib U xcin ơAҰ
   L X apps D xcin o@ XIM serverCҵUƭn:

   IMServerName:  ڭ̪ XIM server WCYb zh_TW.Big5 locale ҤUҰ
	xcin , h IMServerName K|] "xcin", _hܷ|] 
	"xcin-<locale name>"C

   IMLocale:  ڭ̩ҨϥΪ LC_CTYPE localeC

   IMInputStyles:  xcin 䴩JҦCثe xcin u䴩 Root P OverTheSpot
	oؿJҦAӧڭ̷|A[JL䴩C

   IMProtocolHandler:  XIM event Bz禡A XIM BzߡC

   IMOnKeysList:  U trigger keysC xcin ĥ XIM ʺAsuҦA]NO
	 X apps b^ / bοJɡAϥΪ̺VJr䤣|eJ xcin, 
	LU trigger keys ΥοJɡA Xlib ~|NϥΪ̺V
	Jre xcin BzC xcin U trigger keys p: 

	^: w] ctrl+space

	ΥbΤ: w] shift+space

	Jk: w] ctrl+shift, shift+ctrl,  ctrl+alt+[0123456789-=]

	ֳtyJ: w] shift+alt+<ascii key>

	Wz trigger keys iHǥ rcfile ]wӧܡAB fkey.c
	@C|P_ϥΪ̳]w trigger keys O_XkAúɶqקKĬ
	o͡C

   int im_protocol_handler(XIMS ims, IMProtocol *call_data) 禡O xcin 
   U IMProtocolHandler AҦӦ Xlib (IMdkit)  XIM event |e
   oBzA䤤 call_data Oo event eCӳo event ɬOӦ۩ 
   GUI tΤ gui_loop() 禡ҩIs XNextEvent(), g XFilterEvent() L
   oApGo{Oݩ XIM event, hg IMdkit eoءAӤAe^ 
   gui_loop() 禡C XIM event p:

   XIM_OPEN:  @ X app ҰʡAåBMwϥ xcin  XIM server ɡA
	N|eo event  xcinC

   XIM_CLOSE:  @ X app neAӭneo event  xcin q
	n@ǲMzʧ@C

   XIM_CREATE_IC:  @ X app ҰʫAC}@Өϥ XIM AN|eo
	 event LӡCoɭ xcin ͤ@ IC HxsơC

   XIM_DESTROY_IC:   X app YӨϥ XIM neAӭneo 
	event  xcin Hq xcin @µu@Co xcin iHNݩ
	 IC MzC

   XIM_SET_IC_FOCUS:  ƹIYӨϥ XIM  X app ɡAӵN|e
	o event  xcinCo xcin Ni IC u@C

   XIM_UNSET_IC_FOCUS:  ƹIL X ɡAu@ϥ XIM 
	N|eo event  xcin, M~} focusC

   XIM_TRIGGER_NOTIFY:  쥻 X app u@SP xcin su (YB^
	 / bοJ) ɡApGni椤 / οJAhϥΪ̫U
	trigger key, IMdkit K|eoӰT xcin Co xcin i欰
	 IC ilƪʧ@C

   XIM_FORWARD_EVENT:  ϥΪ̫U trigger key ALbVJ
	C@ӦrA xcin |o event, P xcin ]|q call_data
	LeDLFǫAo xcin |ھڳoǫiHU
	Bz:

	1. OO trigger keys? ϥΪ̥ibJ~JkAΫ_^
	   JCpGO trigger key, h xcin |iJkʧ@C

	2. YO trigger keys, h xcin |NrǵثeJk keystroke()
	   禡APɤ]NثeJkA inpinfo_t *inpinfo ǰe
	   AiP_Pզru@CM xcin |ھڥǦ^ȨMwU@
	   BʡC

	3. YJk keystroke 禡oSAثeOB
	   JAAΪ̻ keystroke 禡ƱοJkӳBzoӦrA
	   h xcin |NoӦrǵοJkҲճBzC

	4. YJk keystroke() 禡ΥοJkҲէզrAçƱ
	   Xr^ǵ X app ɡA xcin |NoӦr^ǵ X appC

	5. YJk keystroke() 禡ΥοJkҲժܳoӦr復
	   ӨSNqAh xcin |NoӦrٵ Xlib, Xlib ANr
	    X appC

   XIM tΪƵcA̭nO xccore.ic, O@ӫVثeu@
    IC }C


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

   oӳڤWP XIM tάO@骺Atd@Ҧͪ IC CC IC
   O@ӫܽƵcAOFثeoӤu@JkACwq
   pU ()

===========================================================================
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;
};
===========================================================================

   HWUNq:

   id:   IC sC

   connect_id:  ϥΦ IC  X app sC

   exec_time:   IC ̪񪺨ϥλPɶCoOΩ garbage collection ΡC
	ԨHUC

   ic_state:   IC ثeAAp:
	IC_NEWIC:	N IC sͪ ICC
	IC_CONNECT:	 IC B󤤤JҦAY client P xcin suC
	IC_FOCUS:	 IC ثeu@ ICC

   ic_rec:   IC ҦӦ XIM client ơA䤤n]A:
	ic_value_set:	  N IC ܼƭȦQ XIM client ]wC
	ic_value_update:  N IC ܼƭȳQ XIM client sLFC
	input_style:	   IC  XIM JҦC
	client_win, focus_win:  XIM client  windowC
	pre_attr:	   IC զrܼƭ (iQ XIM client ]w)C

   imc:  V IMC C (z)C

   ѩ IC OtdU XIM clients P xcin qAC@ XIM client 
   b xcin o䳣|w@ IC ӴѪAȡAGHɴxۦU XIM clients
   ʺAAO̪ƨ xcin HɨΡCMӡA̤tdJkC]
   U IC iJkUۿWߡA]i@ΦP@ӿJkcAҨϥΪ
   IMC ӨMw (z)C


   IC garbage collection:

   ѩëDҦ XIM client bɳ|e XIM_CLOSE  XIM_DESTROY_IC
    xcin, o|y xcin Ҷ}ҨϥΪ IC |vֿnAVӶVhCA
   vP{תҶqUAPɤ]Ҽ{F racing conditionA G xcin ثe
   ĥΥHU²檺 garbage collection :

   xcin jܤWCj 5 ˬd@Ҧ IC, HTwݪ client ٬
   ۡCҥHΡujܤWvoӦrAO]ڨS multi-thread  fork 
   t@ process ӺǱɶAӬONˬd禡J 
   im_protocol_handler() , oӨ禡O̱`QIsAѦpb client 
   @BάƦܥηƹI client, i|IsoӨ禡C]Aun
   ̫ϥΥ@ client, N|aiJ im_protocol_handler()AG
   bwˬd禡AӬO²]̦ĪkC

   FU racing condition, ڦb IC ch[F time_t exec_time o
    variable, Co IC QϥήɡA exec_time N|Q]JثeɶA
   ˬd禡̫u|DWL 10 HW idle  IC iˬdApGo{
   IC ݪ window bFANN IC 귽^C


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

   IMC O Input Method Context, NOJkڸƵcCb xcin-2.5.1
   ΥHeAIMC Ogb IC YApzbηƹ
   XIM client ɡAxcin e (]NOU IC JkثeA) ]
   ܡC

   MӡAbYǱpUAڭ̤ƱoˡASOOb bimsphone JkWA
   ̩Ʊb clients ɡAJkAnܡAרOwJ
    xcin buffer YrCFF즹nDA~N IMC  IC 
   C

   {b xcin  mode: XCIN_SINGLE_IMC ON  XCIN_SINGLE_IMC OFFCb
   XCIN_SINGLE_IMC OFF ɡAC IC U۷|@ IMC, OU client 
   JkANWߡCY XCIN_SINGLE_IMC ON ɡAҦ IC |
   P@ IMC, OU client JkAN@PC

   IC ͩRgAoP client  Input Context gO@˪C@
   s client Input Context ͮɡA xcin oNͤ@ӷs IC, ӷ
   client  Input Context A xcin o䪺 IC ]FC

   IMC ]ͩRgA xcin ҳB mode өwCpGO XCIN_SINGLE_IMC
   ON ɡAͩRgNP xcin D{@˪CpGO XCIN_SINGLE_IMC OFF
   ɡAͩRgNP IC @˪C

   IMC ƵcpU:

==============================================================================
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 NOڭ̦bLaҨ쪺 imidCpG SINGLE_IM_CONTEXT }ɡA
   hu@ IMCA imid  1FpGS}Ah imid K|P icid @ˡC

   ڭ̥iHAoӵc]tFҦJkơA]AϥΨ@ӿJkҲ
   (imodp P s_imodp)BJkA (inp_state, inp_num P sinp_num)BPU
   JkҲժq (inpinfo)BH OverTheSpot M GUI Request 
   Cܩ ic_rec hOV IC c ic_recApJktλP GUI tΫK
   iHŪ XIM client ʺACiHcOJkҲջP XIM tΤ
   ١C

   o٭n@U IMC A:

        IM_CINPUT ON:    IMC iJJҦ
        IM_CINPUT OFF:   IMC B^JҦ
        IM_2BYTES ON:    IMC iJοJҦ
        IM_2BYTES OFF:   IMC BbοJҦ
        IM_XIMFOCUS ON:  IMC iJ focus A
        IM_XIMFOCUS OFF: IMC } focus A
	IM_2BFOCUS ON:   IMC iJ focus A
	IM_2BFOCUS OFF:  IMC } focus A

   oذQ IM_CINPUT P IM_XIMFOCUS NnAIM_2BYTES zP IM_CINPUT 
   Cҿ IMC iJ focus AAO IMC w줤JҦAB
   ҹ XIM client QƹIAeAULrN|
   @Φb client WC



T.H.Hsieh
