¥»¤å°Q½×¿é¤Jªk¼Ò²Õªº GUI Request: ªº API ¤¶­±¡C¾\Ū¥»¤å®É¡A«ØÄ³±z¥i¥H¦P®É
°Ñ¦Ò: http://xcin.linux.org.tw/xcin-2.5/xcin_menu.png

¥i¥HÀ°§U±z²z¸Ñ :-))

-------------------------
1. ²¤¶:

¦Û xcin-2.5.2 °_¿é¤Jªk¼Ò²Õ¶}©l¤ä´© GUI Request ¥\¯à¡A¥¦¬O´£¨Ñ¿é¤Jªk¼Ò²Õ
¶}±Ò¨ä¥Lµøµ¡¥HÅã¥Ü¸ê®Æªº¤è¦¡¡C¥Ñ©ó xcin ¥Dµøµ¡ªºªÅ¶¡¦³­­¡A³o¹ï©ó»Ý­nÅã
¥Ü½ÆÂø¸ê°Tªº¿é¤Jªk¼Ò²Õ¦Ó¨¥¥i¯à¤£°÷¥Î¡A¦]¦Ó¦³³o¼Ëªº³]­p¡C

GUI Request ¬O»P winlist ¬[ºc¾ã¦X¦b¤@°_ªº¡A¥¦¥i¥H¬O¦UºØ§ÎºA©Î¥\¯àªºµøµ¡¡A
¤Z¬O¥i¨Ñ¿é¤Jªk¼Ò²Õ¥Î¨ÓÅã¥Ü¨ä¸ê°Tªº¡A§Ú³£ºÙ¬° GUI Request µøµ¡¡C¨ä¦b winlist
ªº©w¸q¤¤¡Awid ¬O³]¦¨ WTYPE_GUIREQ (¨£ include/gui.h)¡C

¦Ó¦b¥Ø«e¡A§Ú¥u³]­p¤F¤@­Ó GUI Request ªºµøµ¡¨Ñ¿é¤Jªk¼Ò²Õ¨Ï¥Î¡A§ÚºÙ¥¦¬°
Menu Selection window (²ºÙ menusel), ¥¦ªº¥\¯à´N¬OÅã¥Ü¥X¤@­Ó¿ï³æ¡A¨ä
source ´N¦b gui_menusel.c ¤¤¡C¥¼¨Ó­YÁÙ¦³»Ý­n¡A¥i¥H¦A¥[¤J¨ä¥Lªº GUI Request
µøµ¡¡C

¿é¤Jªk¼Ò²Õ¥i¥H³z¹L xcin ªº¨ç¦¡©I¥s¨Ó±Ò°Ê¡B¾Þ§@ GUI Request µøµ¡ (¨£«á­z)¡C
¥Ñ©ó GUI Request µ²ºcÄÝ©ó IMC ªº¤@³¡¤À (¸Ô¨£ structer ¤@¤åªº»¡©ú)¡A¦]¦¹¡A
­Y¦b XCIN_SINGLE_IMC OFF ªºª¬ºA¤U¡A¤£¦Pªº IMC ¥i¥H¤À§O¦³¥¦¦Û¤vªº¤@®M GUI
Request window ¸s¡C³o·N«ä¬O»¡¡A±z¥i¥H°µ¨ì¦b XIM client A ¶}±Ò¤@­Ó GUI Request
window¡A¦Ó¦b client B ¶}±Ò¥t¤@­Ó GUI Request window, ¤GªÌ¤¬¬Û¿W¥ß¡C·íµM¡A
¦pªG¦b XCIN_SINGLE_IMC ON ªºª¬ºA¤U¡A©Ò¦³ªº clients (©Î IC) ¤À¨É¦P¤@­Ó IMC¡A
«h¥¦©³¤Uªº GUI Request window ¤]¦P¼Ë³Q©Ò¦³ªº clients ¤À¨É¡C

¦b¦P¤@­Ó IMC ¤U¡A¿é¤Jªk¼Ò²Õ¥i¥H¶}±Ò¦h­Ó GUI Request window¡A¦Ó¥B¶}±ÒªººØÃþ
¨Ã¨S¦³­­¨î¡C·íµM¡A¥Ø«e¥u¦³¤@ºØ¡A§Y menusel, ¦]¦¹­Y±z°ª¿³ªº¸Ü¡A¤]¥i¥H¦P®É¶}
±Ò¨â¤T­Ó¿ï³æ¨Ó¥Î¡C¥Ø«e§Ú¬O³]©w¨C­Ó IMC ³Ì¦h¥u¯à¶}¥X¤­­Ó GUI Request window¡A
§Ú·Q³o¼Ë¦b«Ü¦h±¡ªpÀ³¸Ó¬O°÷¥Î¤F¡C


-------------------------
2. ±Ò°Ê GUI Request:

¦b module.h ªº©w¸q¤¤¡A¦³¤@­Ó greq_t ªº union¡A¥¦´N¬O¥Î¨Ó¾Þ§@ GUI Request ¥Î
ªº¡A¨ä©w¸q¦p¤U:

typedef union {
    int                 type;
    greq_menusel_t      menusel;
} greq_t;

¨ä¤¤ type ´N¬O¥Î¨Ó«ü©w±z­n±Ò°Ê¨º¤@ºØ GUI Request window, ¹ï©ó menusel ¦Ó
¨¥¡A±z­n¦b³oùس]¬° GREQ_MENUSEL¡A¦Ó¨ä©Ò¹ïÀ³ªº¸ê®Æµ²ºc§Y¬° 

	greq_menusel_t   menusel;

³q±`·í§Ú­Ì¦bµ{¦¡¤¤­n¨Ï¥Î¤@­Ó¥~¨Óªº greq_t ¸ê®Æ®É¡A¤]­n¥ý¬Ý¬Ý¨ä type ¬°¦ó¡A
µM«á¦A®Ú¾Ú³o­Ó type ¨Ó¦s¨ú¥¿½Tªº GUI Request ¸ê®Æµ²ºc¡C

·í¿é¤Jªk¼Ò²Õ­n¶}±Ò¤@­Ó GUI Request µøµ¡®É¡A­º¥ý¥²¶··Ç³Æ¦n¤@­Ó greq_t ªº¸ê
®Æ¡AµM«á³z¹L

int greq_register(int imid, greq_t *greq,
		int (*greq_callback)(int, int, inpinfo_t *, greq_cb_t *));

¨ç¦¡©I¥s±N¦¹ GUI Request µù¥Uµ¹ xcin¡C¨ä¦U¤Þ¼Æªº·N¸q¦p¤U:

   1. imid: §Y¥Ø«e inpinfo_t ªº imid ­È¡A¥Î¨Ó«ü¥Ü¦¹ GUI Request ¬OÄÝ©ó¨º
	    ¤@­Ó IMC¡C

   2. greq: §Y¿é¤Jªk¼Ò²Õ©Ò·Ç³Æ¦nªº greq_t ¸ê®Æ«ü¼Ð¡C

   3. greq_callback(): ³o­Ó¥i¦³¥iµL¡A­YµLªº¸Üª½±µ¶Ç¤J NULL §Y¥i¡C³o¬O¿é¤J
	    ªk¼Ò²Õ¬°¦¹ GUI Request ©Ò·Ç³Æªº callback ¨ç¦¡¡A¥Î¨Ó·í¦¹ GUI
	    Request µøµ¡¹J¨ì¤@¨Ç¯S®í¨Æ¥ó®É (¦pµøµ¡³Q·Æ¹«Ãö³¬ .... µ¥µ¥)¡A
	    xcin ¥i¥H³z¹L¦¹ callback ±N¦¹¨Æ¥ó¦^³øµ¹¿é¤Jªk¼Ò²Õ¡AÅý¿é¤Jªk¼Ò
	    ²Õ¥i¥H°µ«áÄòªº°Ê§@¡C¦¹ callback ¨ç¦¡ªº«Å§i¦p¤U:

	int (*greq_callback)(int cmd, int reqid,
			     inpinfo_t *inpinfo, greq_cb_t *greq_cb);

	    ¨ä¤¤ cmd ¬°¦¹¨Æ¥óªº¥N½X¡Areqid ¬°¨ü¦¹¨Æ¥ó¼vÅTªº GUI Request ªº
	    ½s¸¹ (¨£«á­z)¡Ainpinfo ¬°¦¹ GUI Request ©Ò³Bªº IMC ªº inpinfo
	    µ²ºc¡A¶Ç¦^µ¹¿é¤Jªk¼Ò²Õ¥H«K¨Ï¥Î¡A¦Ó greq_cb «h¬O¨ä¥LÃB¥~ªº¸ê®Æ
	    µ²ºc¡A¤£¦Pªº GUI Request ¥i¥Hµø»Ý­n¦Ó¥[¥H§Q¥Î¡C

	    ¦¹ callback ¦pªG°õ¦æ¦¨¥\®É¶Ç¦^ 0¡A§_«h¬°¨ä¥L­È¡Cµø¸Ó GUI Request
	    »P¿é¤Jªk¼Ò²Õªº³]­p¦Ó©w¡C

greq_register() ¦pªG°õ¦æ¦¨¥\¡A¥¦«K·|Âà¦^¸Ó GUI Request ¦b xcin ¤¤©Ò¥Nªíªº
½s¸¹ (¤j©ó©Îµ¥©ó 1)¡A¦¹½s¸¹§YºÙ¬° reqid¡C¥H«á­Y¿é¤Jªk¼Ò²Õ­n¾Þ§@¦¹ GUI Request,
°£¤F­n«ü©w¬O¨º¤@­Ó IMC ªº GUI Request ¥H¥~ (§Y inpinfo->imid)¡A¦P®ÉÁÙ­n«ü
©w¨ä reqid¡C³o¬O¥Ñ©ó¿é¤Jªk¼Ò²Õ¥i¥H¦b¦P¤@­Ó IMC ¤¤¶}±Ò¦h­Ó GUI Request window,
¦b³oùبC¤@­Ó³o¼Ëªº window ´N¬O¤@­Ó greq_t¡A¦Ó¤£¦Pªº window ´N¥H reqid ¨Ó°Ï¤À¡C

¿é¤Jªk¼Ò²Õ¥i¥H¦Û¥Ñ±±¨î greq_t ªº window ªº²£¥Í»PÃö³¬ (destroy)¡C­Y­n²£¥Í¥¦¡A
´N¥Î greq_register() ¨Óµù¥U¤@­Ó§Y¥i¡A­Y­nÃö³¬¥¦¡A«h­n³z¹L

	void greq_unregister(int imid, int reqid);

¨ç¦¡¨Ó°õ¦æ¡A³o¸Ì¥²¶·¶Ç¤J¦¹ GUI Request ©Ò¦bªº IMC ªº imid ¥H¤Î¨ä reqid¡C

°£¦¹¤§¥~¡A¿é¤Jªk¼Ò²Õ¤]¥i¥H¸g¥Ñ¦¹¨ç¦¡±oª¾¥Ø«eªº IMC Á`¦@¶}±Ò¤F¨º¨Ç GUI Request:

	void greq_query(int imid, int *n_greq, int **reqid_list_return);

¨ä¤¤ imid ¬°¦¹ IMC ªº½s¸¹¡A¦Ó¨ç¦¡³Ì«á·|¶Ç¦^ *n_greq, ¬°¥Ø«e GUI Request ªº­Ó
¼Æ¡A¥H¤Î©Ò¦³ GUI Request ªº reqid °}¦C: *reqid_list_return¡C½Ðª`·N¿é¤Jªk¼Ò²Õ
¤£¯à¥ô·N±N¦¹°}¦C free ±¼¡C

½Ðª`·N¡A¦b¦³¨Ç±¡ªp¤U xcin ·|¥D°ÊÃö±¼¥Ø«e¥¿¹B§@¤¤ªº GUI Request window, ¨Ò¦p:

	1. ¨Ï¥ÎªÌ¥Î·Æ¹«ÂI¤Fµøµ¡¤Wªº«ö¶s±N¥¦Ãö±¼®É¡C
	2. ¨Ï¥ÎªÌ¬ðµM«ö ctrl+alt+... ¤Á´«¨ì§Oªº¿é¤Jªk®É¡C

³o®É­Ô¡A¦pªG¸Ó GUI Request ¦³µù¥U¤@­Ó greq_callback() ¨ç¦¡®É¡Axcin ³q±`·|³z
¹L¦¹¨ç¦¡³qª¾¿é¤Jªk¼Ò²Õ¡AÅý¿é¤Jªk¼Ò²Õ¶i¦æ«áÄò³B²z¡AµM«á¤~±N¸Óµøµ¡Ãö±¼¡C

¦Ü©ó¬O§_¥i¥H¼È®ÉÁôÂáBÅã¥Ü GUI Request window (§Y Map, Unmap), «hµø¸Ó GUI
Request window ªº©w¸q¦Ó©w¡A¨Ã«D©Ò¦³ªº window ³£»Ý­n¦¹¥\¯à¡C

©³¤U²¤¶¦U GUI Request ªº¾Þ§@¤è¦¡»P¬ÛÃö¸ê®Æµ²ºc¡C


-------------------------
3. Menu Selection Window:

¦¹ GUI Request ²ºÙ menusel¡A¥i¥H¥Î¨Ó¶}¤@­Ó¿ï³æµøµ¡¡A¨Ñ¨Ï¥ÎªÌ¨Ó°µ¶µ¥Ø¿ï¾Ü¡C
menusel ©Ò»Ýªº¸ê®Æµ²ºc¦p¤U:

typedef struct {
    int type;				/* GUI Request type. */
    unsigned short n_item;              /* number of item lists. */
    unsigned short head_item;           /* head index of the item lists. */
    unsigned short n_sel;               /* number of selection keys. */
    char *selkeys;                      /* the selection keys. */
    unsigned short focus_item;          /* index of the focused item. */
    unsigned short focus_elem;          /* index of the focused element. */
    ubyte_t enable_focus_elem;          /* use focus element facility or not. */
    menu_item_t *item;                  /* the item lists. */
} greq_menusel_t;

Menusel µøµ¡¤À¨â³¡¤À¡A¥ª¥bÃäºÙ¬° item head, ¥k¥bÃäºÙ¬° item list, ¦p¤U¹Ï:

	head1  |  item1-1  item1-2  item1-3 ....
	head2  |  item2-1  item2-2  item2-3 ....
	.....  |  .......  .......  .......

¸Óµøµ¡ªº¤j¤p¬O©T©wªº¡Aªø«×µ¥©ó xcin ²Ä¤@¥Dµøµ¡ªºªø«×¡A°ª«×³Ì¦h¬O¤­¦C¡A¦pªG
n_item ªº¼Æ¥Ø¤p©ó¤­ªº¸Ü¡A«h¦C¼Æ´N·|µ¥©ó n_item ªº­È¡C n_item ¥i¥H¶W¹L 5,
¦Óµøµ¡Åã¥Ü®É¬O±q head_item ¶}©l§@²Ä¤@¦CÅã¥Ü¡C¨Ò¦p¡A±z¦³¤@µ§¸ê®ÆÁ`¦@¦³ 8
­Ó item list, ¦ý head_item ¬O³]¦¨ 2, «hÅã¥Ü¦p¤U:

   (item head)   (item elements)
	head2  |  item2-1  item2-2  item2-3 ....
	head3  |  item3-1  item3-2  item3-3 ....
	head4  |  item4-1  item4-2  item4-3 ....
	head5  |  item5-1  item5-2  item5-3 ....
	head6  |  item6-1  item6-2  item6-3 ....

µøµ¡¥»¨­¤£·|¥hÄd±¶³B²z¥ô¦ó¿é¤J¦rÁä¡A¦]¦¹¡A¦pªG±z­n¹ê§@ menu ¤W¤U±²­¶ªº¥\
¯à¡A±z¥i¥H¦b module function keystroke() ±µ¨ì¤WÁä®É¡A±N head_item ´î 1,
±µ¨ì¤UÁä®É±N¥¦¥[ 1 §Y¥i¡C

n_sel ¬O«ü¦b¤@­Ó item list ¤¤³Ì¦h¦³´X­Ó¿ï¾Ü¶µ¡A¦ý¥¦¥u¦³¦b selkeys ¦³³]©w
®É¤~¦³¥Î¡A selkeys ¬O³]©wÅã¥Ü¥Xªº¿ï¾ÜÁä¡A¦Ó n_sel ´N¬O selkeys ªº¼Æ¥Ø¡C
¨Ò¦p¡A§Ú¥i¥H³]©w:

	greq_menusel->selkeys = "asdfghjkl;";
	greq_menusel->n_sel = strlen(selkeys);

¦p¦¹Åã¥Ü¥X¨Óªº item list ´N¬O:

	headN  |  a itemN-a  s itemN-s  d itemN-d  ....

ª`·N¨C­Ó item «e­±³£·|¦ñÀH¤@­Ó selkey, ´N¬O±z¦b greq_menusel->selkeys ¤¤
©Ò³]ªº¤º®e¡C·íµM±z¦b³oùØ¥i¥H³]¦¨ NULL, «h¹w³]´Nª½±µ¥H "1234567890" ¨Ó®M¥Î¡C

focus_item ¬O«ü¨º¤@­Ó item ­n¯S§O¥H¤Ï¥Õ¼Ð¥Ü¡A´N¦n¹³´å¼Ð°±¦b¨º¤@­Ó¶µ¥Ø¤W¤@
¼Ë¡C¦b³oùؤϥշ|¼Ð¥Ü¦b¸Ó item list ªº head ¤W¡A¹Ï¥Ü¦p¤U (¼Ð¥Ü¦b²Ä¤G­Ó item):

	head1  |  item1-1  item1-2  item1-3  ....
       <head2> |  item2-1  item2-2  item2-3  ....
	.....  |  .......  .......  .......

¦pªG±N enable_focus_elem ³]¬° 1 ®É¡A«h¤Ï¥Õ¼Ð¥Ü¤]¥i¥H¼Ð¥Ü¦b¤@­Ó item list ¤¤
ªº¬Y­Ó element ¤W (¥Ñ focus_elem ¨Ó«ü©w)¡A¨Ò¦p (¼Ð¥Ü¦b²Ä¤G­Ó item ªº²Ä¤T­Ó 
element):

	head1  |  item1-1  item1-2  item1-3  ....
       <head2> |  item2-1  item2-2 <item2-3> ....
	.....  |  .......  .......  .......

­Y±N enable_focus_elem ³]¬° 0, «h item list ¤¤¤£·|¦³ element ªº¤Ï¥Õ¼Ð¥Ü¡A¥B
focus_elem ¤]¤£·|¦³§@¥Î¡C

³Ì«áªº menu_item_t *item ¬O«ü¦V¨C¤@­Ó item list ªº°}¦C¡A¦p:

	item[0].title     ==> head1
	       .elements  ==> item1-1 item1-2 item1-3 ....
	       .........
	item[1].title     ==> head2
	       .elements  ==> item2-1 item2-2 item2-3 ....
	       .........

¨ä¤¤¨C­Ó item list ªº²Ó³¡©w¸q¦p¤U:

typedef struct {
    wch_t *title;                       /* title of the item list. */
    wch_t *elements;                    /* elements of the item list. */
    ubyte_t *elem_group;                /* grouping info. of the elements. */
    unsigned short n_elem;              /* size of "elements" array. */
    unsigned short head_idx;            /* head index of the item list. */
    unsigned short n_sel_return;        /* num of selection returned by xcin. */
} menu_item_t;

¨ä¤¤ title ´N¬O¤W­±¨º´X­Ó¹Ï¤¤¬Y¤@ item ªº head, ¦Ó¥¦ªº element list «h¬O
³]¦b wch_t *elements ¤¤¡A n_elem ¬O elements °}¦Cªº­Ó¼Æ¡C¦pªG elem_group
¬O NULL, «h¨C­Ó elements ªº°}¦C­ì¯À´N¬O¤@­Ó¿ï¶µ¡A¦pªG elem_group ¤£¬O NULL,
«h¥i¥H¥Î¥¦¨Ó«ü©w¦h­Ó elements °}¦C­ì¯À¦X¦¨¤@­Ó¿ï¶µ¡A¨Ò¦p:

	elem_group = NULL		/* ¨C­Ó element ­ì¯À³£¬O¦U§O¿ï¶µ */
	title = head1
	elements = {A}, {B}, {C}, {D}
	-------------------------------------------------------------------
	head1  |  1.{A}  2.{B}  3.{C}  4.{D}

	elem_group = ....		/* ¥i¥H«ü©w­Y¤z element ­ì¯À¦X¦¨¤@ */
	title = head2			/* ­Ó¿ï¶µ			   */
	elements = {A}, {B}, {C}, {D}
	-------------------------------------------------------------------
	head2  |  1.{AB}  2.{C}  3.{D}

¦Ü©ó elem_group ªº¥Îªk¡A»P inpinfo ¤¤ lcch_grouping »P mcch_grouping ªº¥Î
ªk¤@¼Ò¤@¼Ë¡A±z¥i¥H°Ñ¦Ò xcin-2.5/doc/internal/module ªº»¡©ú¡A§Y¥i¤F¸Ñ¡C

¦Ü©ó head_idx ¥¦ªº§@¥Î»P¥ý«e´£ªº gui_menusel_t->head_item ¤@¼Ë¡A¤]¬O§i¶D
xcin »¡¦¹ item list ­n±q¨º¤@­Ó element ¶}©lµe°_¡C

¥Ñ©ó menusel ªº¼e«×¤£¨£±o¨¬¥H®e¯Ç©Ò¦³ªº item element, ¦pµøµ¡µe¤£¤U®É¡Axcin
·|³z¹L n_sel_return ¦^³ø»¡¹ê»Ú¤W¥uµe¤F´X­Ó element¡A¬G¿é¤Jªk¼Ò²Õ¥i¥HÂǦ¹°µ
¥X¥²­nªº½Õ¾ã¡C

³Ì«á´£¤@ÂI: ¤W­z©Ò´£ªº©Ò¦³ªº index, ¦p head_item, focus_item, focus_elem,
head_idx µ¥¡A¥þ³¡³£¬O¥Ñ 1 ¶}©l­p¼Æ¡A¦Ó¤£¬O±q 0 ¶}©l¡A½Ð¤£­n§Ë¿ù¤F¡C




T.H.Hsieh