²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 XGw@ˡA򥻬[cpU:

	                 xim_IC  <-------+
		           ||	         |
		           ||	         |
	                xim_conf <-------+
		           ||	         |
		           ||	         |
	                gui_conf      module <----- cinput
		           ||	         |
		           ||	         |
                       xcin_conf <--- xcintool
				      xcin_rc (siod)

HUNWϪU²檺C


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

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


B. xcin_conf: (include/constant.h, include/xcin_core.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 Bi xcin Ll .... APɥ
   Ƶc٫OҦ rcfile ŪJƪl (]A CINPUT 
   ]w) AHΤ@ǥܼơAoǥiH@ xcin LlƮɪѦ
   ơC

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

   XCIN_MODE_HIDE:  pG rcfile ]w XCIN_HIDE YES ho bit |] onC

   XCIN_SHOW_CINPUT:  pG rcfile ]w DEFAULT_IM_SINMD Ȭ "DEFAULT",
	hܨϥΪ̧ƱbJkɡAJkrܤ]ۤAho
	bit |] onCpGϥΪ̫F ctrl+alt+i JkrܮɡA
	ho bit |۰ʳ] offC

   XCIN_XKILL_OFF:  pG rcfile  XKILL_DISABLE  YES ɫh onC

   XCIN_IM_FOCUS:  pG rcfile  IM_FOCUS_ON  YES ɫh onC

   XCIN_MODE_WORKING:  oOb XCIN_MODE_HIDE ] on ɤ~|@ΡCoɦp
	G xcin X{ɡA bit |] on, Yîɷ|] offC

   XCIN_RUN_IM_FOCUS:  Oثe xcin O_Bb IM Focus A (IM Focus 
	䬰 ctrl+alt+f)C


C. xcin_rc: (lib/xcintool/xcin_rc.c lib/siod/*)

   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ɴ xcin_conf P module Ū rcfile ƤΡAP
   ]iH xcin L~{ (p cin2tab) @q rcfile ŪCGڭ
   uݭn@ rcfile YinҦ xcin ]wC


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 xim_conf tΨΡCԲ
   Ӹ`аѦ module @C


E. gui_conf: (include/gui.h, gui.c)

   oO xcin  GUI tΪ֤ߡApGJkҲըSnDۦb xcin ø
   ϪܡAҦ xcin øϻPާ@OboاC xcin Wewq
   pU:

		+-------------------------------------------+
		|                     a                     |
		+---------+---------+--------------+--------+
		|    b    |    c    |      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

    rcfile YJk SINMD_IN_LINE1 ] "YES" ɡAh쥻b d J
   kզrܷ|b a ϤܡC

   GUI tΦblƮɡAO xcin_conf o rcfile ơAӨøϻP
   ާ@禡DnT:

   void win_draw(void):
	øϡCӨøϪe (]AWz 5 Ӱܤr) 
	 gui_conf ƵcoC

   void win_map_change(int state):
	ΩܻPäCoO rcfile ]w xcin îɤ~|Q
	IsC

   void win_draw_map(void):
	禡ΨӦPɩIs win_draw() P win_map_change() Ө禡CӥB
	|ھ xcin_conf.xcin_mode ΨLAӧP_O_Is
	win_map_change()  /  xcin C@Өڭ̳O
	Φ禡Ӱ xcin øϤu@AӤϥΤWYӨ禡C

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

   WIN_CHANGE_IM_CONTENT:  o bit  on ɡAܿJkAupŧ
	ܡAҦpϥΪ̺VJ@ӦNqrC

   WIN_RAISE:  o bit  on ɡA win_draw_map() |bøϫAN
	xcin ܬĤ@ӵC

   WIN_CHANGE_IM:   on ɡANWzҦ bits Ҭ on, NOJ
	kAwjŧܡAq`ObJkpUoͪC

   ѩ GUI tΦbeϮɬOھ gui_conf JkAƨӵeAƹ
   WoǪAƬOӦ۩ xim_conf.ic cAYثeu@ IC (ШY
   )A gui_conf oƥuO@ǫV xim_conf.ic ƪ
   ЦӤwC]AZOb xim_conf.ic ܡA|Yɤb GUI t
   ΤWCpGuOpܡAY WIN_CHANGE_IM_CONTENT  on ɡA GUI tδN
   ھڧܨøϡCpGOJkAܴu@ IC ɡANn
   s]w gui_conf лPơAHVT IC mCӳoӤu@
   O static void inpstate_content(inp_state_t inp_state) 禡ӹF
   AO win_draw() 禡өIsC win_draw() o{ WIN_CHANGE_IM
    on ɡA~|Is inpstate_content() ӭ]ơC

   ~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_conf tΨӳBz (ШY)CYOo
    X event, ~ gui_loop() iLʧ@ (pe) AMg
   _lC

   F{²_Aڥثeu}@ Window, Y xcin DAèS
   A}L WindowC


F. xim_conf (include/xim.h, xim.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 WCثeb{oiqAڭ̼Ȯɳ]
	"sampleIM" ( Setup @妳 xedit b $HOME/.Xresources ]w)A
	ӧڭ̷|Nאּ "xcin"C

   IMLocale:  ڭ̩ҨϥΪ LC_CTYPE localeC

   IMInputStyles:  xcin 䴩JҦCثe xcin u䴩
	XIMPreeditNothing|XIMStatusNothing oؿJҦANOJkզr
	ϻPJkAϳb xcin  (Y input_style  "Root")C
	ڭ̷|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: ctrl+space,
	ctrl+alt+[0123456789-=], shift+space, ctrl+shift, shift+ctrlC


   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_conf ƵcA̭nO xim_conf.ic, O@ӫVثeu@
   IC }C


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

   oӳڤWOP xim_conf @骺Atd@Ҧͪ IC CC IC
   O@ӫܽƵcAOFثeoӤu@JkACwq
   pU ()

===========================================================================
typedef struct _IC IC; /* forward declaration */
struct _IC {
    CARD16              id;             /* ic id */
    CARD16              connect_id;     /* id of connected client */
    time_t              exec_time;      /* recent excution time. */
    struct _IC         *next;
    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. */

/*
 *  Set from: XICAttribute *ic_attr, *pre_attr, *sts_attr;  
 *  ic_set_value_by_name();
 */
    INT32               input_style;    /* input style */
    Window              client_win;     /* client window */
    Window              focus_win;      /* focus window */
    char               *resource_name;  /* resource name */
    char               *resource_class; /* resource class */
    PreeditAttributes   pre_attr;       /* preedit attributes */
    StatusAttributes    sts_attr;       /* status attributes */
};
===========================================================================

   ثeѩ xcin u䴩 XIMPreeditNothing|XIMStatusNothing oؿJҦAG
   INT32  input_style HUثeS@ΡCӥHWUNq:

   id:   IC sC

   connect_id:  ϥΦ IC  X app sC

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

   inp_state:   IC JkAAȥiHO:
	IC_CINPUT:   Y on ܤJA_h^ƿJC
	IC_2BYTES:   Y on ܥοJA_hbοJC
	IC_XIMINIT:  Y on ܦ IC wL modules->xim_init() 禡FC
		     PɥiΩP_O_ modules->xim_end() 禡C
	IC_XIMFOCUS: Y on ܦ IC wL modules->switch_in() 禡FC
		     PɥiΩP_O_ modules->switch_out() 禡C
	IC_NEWIC:    Y on ܦ IC OsͪAǦiΨӧPOöii@
		     B XIM ʧ@C 

   inp_num:   IC ثeϥΪJksAYJk setkey (Jk setkey
	MwFs)C

   sinp_num:  ثeΨܿJkrXsC

   imodp:  VثeϥΤJkҲաC

   s_imodp:  VثeϥΤuJkrXܡvҲաC

   inpinfo:  ثeJkAơCԨ module @媺C

   skey_size:  sinmd_keystroke wİϪjpC

   sinmd_keystroke:  ΨӦsuJkrXܡvwİϡCwİϪjp
	 xcin ݭnۦվAUJkҲդݭnӶ˸C

   cch_size:  cch wİϪjpC

   cch:  ΨӦs commit  XIM client rCwİϪjp xcin 
	nۦվAUJkҲդݭnӶ˸C

   ~A xcin [JLJҦɡA xim_IC Ntdi
   IC ]wC


   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



T.H.Hsieh
