¥»¤å²z xcin-2.5 ªº³]p²z©À»P¾ãÓµ{¦¡¬[ºc¡C
xcin-2.5 ªº³]p²z©À¬°:
1. ¿é¤Jªk¦U¦Û¿W¥ß¥B¼Ò²Õ¤Æ¡C
2. ¨Ï¥ÎªÌ»P©¹±`¤@¼Ë¡A¥un·Ç³Æ¦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¥¦¥ut³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¥¦¥Dn¬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¥¦¥Dn¬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
¥un§ïÅܳ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¤Wz¨â
ºØ±¡ª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ªº»¡©ú)¡CY¤£¬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¡CY¦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>
¤Wzªº 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ªGn¶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¡Ap¦³:
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 ¬Ot³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¥un§Ú
Ì«ùÄò¨Ï¥Î¥ô¦ó¤@Ó 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¥ß¡CY 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