1 /*
2 	Copyright (C) 2004-2008	Edward Der-Hua Liu, Hsin-Chu, Taiwan
3 */
4 
5 #include <sys/stat.h>
6 #include <regex.h>
7 #include "gcin.h"
8 #include "gtab.h"
9 #include "pho.h"
10 #include "gcin-conf.h"
11 #include "gcin-endian.h"
12 #include "gtab-buf.h"
13 #include "tsin.h"
14 #include "gst.h"
15 
16 
17 extern gboolean test_mode;
18 gboolean gtab_phrase_on();
19 gboolean gtab_disp_partial_match_on(), gtab_vertical_select_on(), gtab_pre_select_on(), gtab_unique_auto_send_on(), gtab_press_full_auto_send_on();
20 void init_seltab(char ***p);
21 void disp_gbuf();
22 
23 extern gint64 key_press_time, key_press_time_ctrl;
24 
25 extern GtkWidget *gwin_gtab;
26 void hide_gtab_pre_sel();
27 void gtab_scan_pre_select(gboolean);
28 gboolean output_gbuf();
29 
30 extern GTAB_space_pressed_E _gtab_space_auto_first;
31 extern char *TableDir;
32 
33 extern INMD *cur_inmd;
34 extern char **seltab;
35 
36 #define gtab_full_space_auto_first (_gtab_space_auto_first & (GTAB_space_auto_first_any|GTAB_space_auto_first_full))
37 #define AUTO_SELECT_BY_PHRASE (gtab_phrase_on())
38 
use_tsin_sel_win()39 gboolean use_tsin_sel_win()
40 {
41   return  gtab_vertical_select_on() && gtab_phrase_pre_select;
42 }
43 
44 
gtab_pre_select_or_partial_on()45 static gboolean gtab_pre_select_or_partial_on()
46 {
47  return gtab_pre_select_on() || (cur_inmd->flag&FLAG_GTAB_DISP_PARTIAL_MATCH)!=0;
48 }
49 
same_query_show_pho_win()50 gboolean same_query_show_pho_win()
51 {
52   return poo.same_pho_query_state != SAME_PHO_QUERY_none;
53 }
54 
55 gboolean gcin_edit_display_ap_only();
gtab_has_input()56 gboolean gtab_has_input()
57 {
58   int i;
59 
60   for(i=0; i < MAX_TAB_KEY_NUM64_6; i++)
61     if (ggg.inch[i])
62       return TRUE;
63 
64   if (same_query_show_pho_win())
65     return TRUE;
66 
67   if (ggg.gtab_buf_select)
68     return TRUE;
69 
70 #if 1
71   if (ggg.gbufN && !gcin_edit_display_ap_only())
72 #else
73   if (ggg.gbufN)
74 #endif
75     return TRUE;
76 
77   return FALSE;
78 }
79 
80 #define tblch(i) tblch2(cur_inmd, i)
81 
load_phr_ch(INMD * inm,u_char * ch,char * tt)82 int load_phr_ch(INMD *inm, u_char *ch, char *tt)
83 {
84   int phrno =((int)(ch[0])<<16)|((int)ch[1]<<8)|ch[2];
85   int ofs = inm->phridx[phrno], ofs1 = inm->phridx[phrno+1];
86 
87 //  dbg("load_phr   j:%d %d %d %d\n", j, phrno, ofs, ofs1);
88   int len = ofs1 - ofs;
89 
90   if (len > MAX_CIN_PHR || len <= 0) {
91     dbg("phrae error %d\n", len);
92     strcpy(tt,"err");
93     return 0;
94   }
95 
96   memcpy(tt, inm->phrbuf + ofs, len);
97   tt[len]=0;
98   return len;
99 }
100 
load_phr(int j,char * tt)101 static void load_phr(int j, char *tt)
102 {
103   u_char *ch = tblch(j);
104 
105   load_phr_ch(cur_inmd, ch, tt);
106 }
107 
qcmp_strlen(const void * aa,const void * bb)108 static int qcmp_strlen(const void *aa, const void *bb)
109 {
110   char *a = *((char **)aa), *b = *((char **)bb);
111 
112   return strlen(a) - strlen(b);
113 }
114 
115 void set_key_codes_label(char *s, int better);
116 void set_page_label(char *s);
117 
clear_page_label()118 static void clear_page_label()
119 {
120   set_page_label("");
121 }
122 
123 int gtab_key2name(INMD *tinmd, u_int64_t key, char *t, int *rtlen);
124 
125 
ch_to_gtab_keys(INMD * tinmd,char * ch,u_int64_t keys[])126 int ch_to_gtab_keys(INMD *tinmd, char *ch, u_int64_t keys[])
127 {
128   if (tinmd->DefChars < 1000)
129     return 0;
130 
131   int n = utf8_str_N(ch);
132   gboolean phrase = n > 1 || !(ch[0] & 0x80);
133   int i, keysN=0;
134   for(i=0; i < tinmd->DefChars; i++) {
135     char *chi = (char *)tblch2(tinmd, i);
136 
137     if (phrase) {
138       if ((chi[0] & 0x80))
139         continue;
140       char tstr[512];
141       load_phr_ch(tinmd, (u_char *)chi, tstr);
142       if (strcmp(tstr, ch))
143         continue;
144     } else {
145       if (!(chi[0] & 0x80))
146         continue;
147       if (!utf8_eq(chi, ch))
148         continue;
149     }
150 
151     u_int64_t key = CONVT2(tinmd, i);
152     keys[keysN++] = key;
153   }
154   return keysN;
155 }
156 
lookup_gtabn(char * ch,char * out)157 void lookup_gtabn(char *ch, char *out)
158 {
159   char outbuf[512];
160   char *tbuf[128];
161   int tbufN=0;
162   INMD *tinmd = &inmd[default_input_method];
163 
164   if (!tinmd->DefChars)
165     tinmd = cur_inmd;
166 
167   if (!tinmd)
168     return;
169 
170   gboolean need_disp = FALSE;
171 
172   if (!out) {
173     out = outbuf;
174     need_disp = TRUE;
175   }
176 
177   out[0]=0;
178 
179 
180   int min_klen = 100;
181   u_int64_t keys[64];
182   int keysN = ch_to_gtab_keys(tinmd, ch, keys);
183 
184   int i;
185   for(i=0; i < keysN; i++) {
186     int tlen, klen;
187     char t[CH_SZ * 10 + 1];
188 
189     klen = gtab_key2name(tinmd, keys[i], t, &tlen);
190 
191     if (klen < min_klen)
192       min_klen = klen;
193 
194     t[tlen]=0;
195 
196     tbuf[tbufN] = strdup(t);
197     tbufN++;
198   }
199 
200 
201   qsort(tbuf, tbufN, sizeof(char *), qcmp_strlen);
202   out[0]=0;
203 
204   for(i=0; i < tbufN; i++) {
205 #define MAX_DISP_MATCH 40
206     if (strlen(out) < MAX_DISP_MATCH) {
207       strcat(out, tbuf[i]);
208       if (i < tbufN-1)
209         strcat(out, " |");
210     }
211 
212     free(tbuf[i]);
213   }
214 
215   if (!out[0] || !need_disp)
216     return;
217 
218 
219   set_key_codes_label(out, ggg.ci > min_klen);
220   void set_key_codes_label_pho(char *s);
221   set_key_codes_label_pho(out);
222 }
223 
lookup_gtab(char * ch)224 void lookup_gtab(char *ch)
225 {
226   char tt[CH_SZ+1];
227   utf8cpy(tt, ch);
228   lookup_gtabn(tt, NULL);
229 }
230 
231 
lookup_gtab_out(char * ch,char * out)232 void lookup_gtab_out(char *ch, char *out)
233 {
234   char tt[CH_SZ+1];
235   utf8cpy(tt, ch);
236   lookup_gtabn(tt, out);
237 }
238 
239 
b1_cat(char * s,char c)240 char *b1_cat(char *s, char c)
241 {
242   char t[2];
243   t[0]=c;
244   t[1]=0;
245 
246   return strcat(s, t);
247 }
248 
249 
bch_cat(char * s,char * ch)250 char *bch_cat(char *s, char *ch)
251 {
252   char t[CH_SZ + 1];
253   int len = u8cpy(t, ch);
254   t[len]=0;
255 
256   return strcat(s, t);
257 }
258 
259 
260 void minimize_win_gtab();
261 void disp_gtab_sel(char *s);
262 
ClrSelArea()263 void ClrSelArea()
264 {
265 #if WIN32
266   if (test_mode)
267     return;
268 #endif
269   disp_gtab_sel("");
270   minimize_win_gtab();
271 //  hide_gtab_pre_sel();
272 }
273 
274 
275 void disp_gtab(char *);
276 void clear_gtab_input_error_color();
277 
clr_seltab()278 static void clr_seltab()
279 {
280   int i;
281   if (!seltab)
282     return;
283 
284   for(i=0; i < MAX_SELKEY; i++)
285      seltab[i][0]=0;
286 }
287 
288 void clear_gtab_in_area(), hide_win_gtab();
ClrIn()289 void ClrIn()
290 {
291 #if WIN32
292   if (test_mode)
293     return;
294 #endif
295 
296   bzero(ggg.inch,sizeof(ggg.inch));
297   clr_seltab();
298   ggg.total_matchN=ggg.pg_idx=ggg.more_pg=ggg.wild_mode=ggg.wild_page=ggg.last_idx=ggg.defselN=ggg.exa_match=
299   ggg.spc_pressed=ggg.ci=ggg.invalid_spc=0;
300 
301   ggg.sel1st_i=MAX_SELKEY-1;
302 
303   clear_gtab_in_area();
304   ggg.last_idx = 0;
305 
306   if (gcin_pop_up_win && !gtab_has_input() && !tss.pre_selN)
307     hide_win_gtab();
308 
309   clear_gtab_input_error_color();
310   clear_page_label();
311 //  hide_gtab_pre_sel();
312 }
313 
314 
315 void hide_win_pho();
316 
close_gtab_pho_win()317 void close_gtab_pho_win()
318 {
319   if (test_mode)
320     return;
321   if (poo.same_pho_query_state != SAME_PHO_QUERY_none) {
322     poo.same_pho_query_state = SAME_PHO_QUERY_none;
323     hide_win_pho();
324   }
325 }
326 
327 void gtab_disp_empty(char *tt, int N);
328 extern int win_gtab_max_key_press;
329 
DispInArea()330 static void DispInArea()
331 {
332   int i;
333 #if WIN32
334   if (test_mode)
335     return;
336 #endif
337 
338 //  hide_gtab_pre_sel();
339 
340 //  dbg("sel1st:%d\n", ggg.sel1st_i);
341   if (gcin_display_on_the_spot_key()) {
342     if (gwin_gtab && GTK_WIDGET_VISIBLE(gwin_gtab) && poo.same_pho_query_state == SAME_PHO_QUERY_none)
343       hide_win_gtab();
344     return;
345   }
346 
347   char tt[128];
348   int ttN=0;
349 
350   if (win_gtab_max_key_press < ggg.ci)
351     win_gtab_max_key_press = ggg.ci;
352 
353   for(i=0;i<ggg.ci;i++) {
354     char *p=(char *)&cur_inmd->keyname[ggg.inch[i] * CH_SZ];
355     int len;
356     if (*p & 0x80)
357       len=utf8cpy(tt+ttN, p);
358     else {
359       len = strlen(p);
360       strcpy(tt+ttN, p);
361     }
362 
363     ttN+=len;
364   }
365 
366   tt[ttN]=0;
367 
368   gtab_disp_empty(tt, win_gtab_max_key_press - i);
369 
370   disp_gtab(tt);
371   minimize_win_gtab();
372 }
373 
get_DispInArea_str(char * out)374 int get_DispInArea_str(char *out)
375 {
376   int outN=0, i;
377   for(i=0;i<ggg.ci;i++) {
378     char *p = (char *)&cur_inmd->keyname[ggg.inch[i] * CH_SZ];
379     if (*p & 0x80)
380       outN+=u8cpy(out+outN, p);
381     else {
382       int len = strlen(p);
383       memcpy(out+outN, p, len);
384       outN+=len;
385     }
386   }
387 
388 #if 0
389   if (outN) {
390     hide_gtab_pre_sel();
391   }
392 #endif
393 
394   out[outN]=0;
395 //  dbg("get_DispInArea_str\n", out);
396   return outN;
397 }
398 
399 
400 void set_gtab_input_method_name(char *s);
401 void case_inverse(KeySym *xkey, int shift_m);
402 
403 extern char *fullchar[];
404 
405 void start_gtab_pho_query(char *utf8);
406 
clear_after_put()407 void clear_after_put()
408 {
409   ClrIn();
410   ClrSelArea();
411 }
412 
413 void add_to_tsin_buf_str(char *str);
414 gboolean init_in_method(int in_no);
415 void hide_win_kbm();
416 
hide_row2_if_necessary()417 void hide_row2_if_necessary()
418 {
419   if (!ggg.wild_mode && gtab_hide_row2 || !gtab_disp_key_codes) {
420     set_key_codes_label(NULL, 0);
421   }
422 }
423 
424 void set_wselkey();
425 
putstr_inp(char * p)426 static void putstr_inp(char *p)
427 {
428 #if WIN32
429   if (test_mode)
430     return;
431 #endif
432 
433   clear_page_label();
434 
435 //  dbg("gtab_hide_row2 %d\n", gtab_hide_row2);
436   hide_row2_if_necessary();
437 
438   char_play(p);
439 
440   int to_tsin = (cur_inmd->flag & FLAG_GTAB_SYM_KBM) && inmd[default_input_method].method_type==method_type_TSIN && tss.c_len;
441 
442   if (utf8_str_N(p) > 1  || !(p[0]&128)) {
443     if (gtab_disp_key_codes && !gtab_hide_row2 || ggg.wild_mode)
444       lookup_gtabn(p, NULL);
445 #if USE_TSIN
446     if (to_tsin) {
447       add_to_tsin_buf_str(p);
448     }
449     else
450 #endif
451       send_text(p);
452   }
453   else {
454     if (poo.same_pho_query_state == SAME_PHO_QUERY_gtab_input) {
455       poo.same_pho_query_state = SAME_PHO_QUERY_pho_select;
456       start_gtab_pho_query(p);
457 
458       ClrIn();
459       ClrSelArea();
460       return;
461     }
462 
463     if (gtab_disp_key_codes && !gtab_hide_row2 || ggg.wild_mode)
464       lookup_gtab(p);
465 
466     if (to_tsin)
467       add_to_tsin_buf_str(p);
468     else
469       send_utf8_ch(p);
470   }
471 
472   clear_after_put();
473 
474   if ((cur_inmd->flag & FLAG_GTAB_SYM_KBM)) {
475     extern int win_kbm_inited, b_show_win_kbm;
476     init_in_method(default_input_method);
477     if (win_kbm_inited && !b_show_win_kbm)
478       hide_win_kbm();
479   }
480 }
481 
482 
483 #define swap(a,b) { tt=a; a=b; b=tt; }
484 
485 static u_int vmask[]=
486 { 0,
487  (0x3f<<24),
488  (0x3f<<24)|(0x3f<<18),
489  (0x3f<<24)|(0x3f<<18)|(0x3f<<12),
490  (0x3f<<24)|(0x3f<<18)|(0x3f<<12)|(0x3f<<6),
491  (0x3f<<24)|(0x3f<<18)|(0x3f<<12)|(0x3f<<6)|0x3f
492 };
493 
494 
495 static u_int vmask_7[]=
496 { 0,
497  (0x7f<<21),
498  (0x7f<<21)|(0x7f<<14),
499  (0x7f<<21)|(0x7f<<14)|(0x7f<<7),
500  (0x7f<<21)|(0x7f<<14)|(0x7f<<7)|0x7f,
501 };
502 
503 #define KKK ((u_int64_t)0x3f)
504 
505 
506 static u_int64_t vmask64[]=
507 { 0,
508   (KKK<<54),
509   (KKK<<54)|(KKK<<48),
510   (KKK<<54)|(KKK<<48)|(KKK<<42),
511   (KKK<<54)|(KKK<<48)|(KKK<<42)|(KKK<<36),
512   (KKK<<54)|(KKK<<48)|(KKK<<42)|(KKK<<36)|(KKK<<30),
513   (KKK<<54)|(KKK<<48)|(KKK<<42)|(KKK<<36)|(KKK<<30)|(KKK<<24),
514   (KKK<<54)|(KKK<<48)|(KKK<<42)|(KKK<<36)|(KKK<<30)|(KKK<<24)|(KKK<<18),
515   (KKK<<54)|(KKK<<48)|(KKK<<42)|(KKK<<36)|(KKK<<30)|(KKK<<24)|(KKK<<18)|(KKK<<12),
516   (KKK<<54)|(KKK<<48)|(KKK<<42)|(KKK<<36)|(KKK<<30)|(KKK<<24)|(KKK<<18)|(KKK<<12)|(KKK<<6),
517   (KKK<<54)|(KKK<<48)|(KKK<<42)|(KKK<<36)|(KKK<<30)|(KKK<<24)|(KKK<<18)|(KKK<<12)|(KKK<<6)|KKK
518 };
519 
520 
521 #define KKK7 ((u_int64_t)0x7f)
522 
523 static u_int64_t vmask64_7[]=
524 { 0,
525  (KKK7<<56),
526  (KKK7<<56)|(KKK7<<49),
527  (KKK7<<56)|(KKK7<<49)|(KKK7<<42),
528  (KKK7<<56)|(KKK7<<49)|(KKK7<<42)|(KKK7<<35),
529  (KKK7<<56)|(KKK7<<49)|(KKK7<<42)|(KKK7<<35)|(KKK7<<28),
530  (KKK7<<56)|(KKK7<<49)|(KKK7<<42)|(KKK7<<35)|(KKK7<<28)|(KKK7<<21),
531  (KKK7<<56)|(KKK7<<49)|(KKK7<<42)|(KKK7<<35)|(KKK7<<28)|(KKK7<<21)|(KKK7<<14),
532  (KKK7<<56)|(KKK7<<49)|(KKK7<<42)|(KKK7<<35)|(KKK7<<28)|(KKK7<<21)|(KKK7<<14)|(KKK7<<7),
533  (KKK7<<56)|(KKK7<<49)|(KKK7<<42)|(KKK7<<35)|(KKK7<<28)|(KKK7<<21)|(KKK7<<14)|(KKK7<<7)|KKK7,
534 };
535 
536 
537 #define KEY_N (cur_inmd->max_keyN)
538 
539 
tblidx_to_str(int tblidx,char out[])540 static gboolean tblidx_to_str(int tblidx, char out[])
541 {
542   u_char *tbl_ch = tblch(tblidx);
543   if (tbl_ch[0] < 0x80) {
544     load_phr(tblidx, out);
545     return TRUE;
546   }
547 
548   int len = u8cpy(out, (char *)tbl_ch);
549   out[len] = 0;
550 
551   return FALSE;
552 }
553 
554 
load_seltab(int tblidx,int seltabidx)555 static gboolean load_seltab(int tblidx, int seltabidx)
556 {
557   return tblidx_to_str(tblidx, seltab[seltabidx]);
558 }
559 
560 
load_tblidx(int tblidx)561 static char* load_tblidx(int tblidx)
562 {
563   char tt[MAX_CIN_PHR];
564   u_char *tbl_ch = tblch(tblidx);
565   if (tbl_ch[0] < 0x80) {
566     load_phr(tblidx, tt);
567   } else {
568     int len = u8cpy(tt, (char *)tbl_ch);
569     tt[len] = 0;
570   }
571 
572   return strdup(tt);
573 }
574 
575 
576 void set_gtab_input_error_color();
bell_err()577 static void bell_err()
578 {
579 #if WIN32
580   if (test_mode)
581     return;
582 #endif
583   bell();
584   set_gtab_input_error_color();
585 }
586 
cmp_inmd_idx(regex_t * reg,int idx)587 gboolean cmp_inmd_idx(regex_t *reg, int idx)
588 {
589   u_int64_t kk=CONVT2(cur_inmd, idx);
590   char ts[32];
591   int tsN=0;
592 
593   ts[tsN++]= ' ';
594 
595   int i;
596   for(i=0; i < KEY_N; i++) {
597     char c = (kk >> (LAST_K_bitN - i*cur_inmd->keybits)) & cur_inmd->kmask;
598     if (!c)
599       break;
600     ts[tsN++] = c + '0';
601   }
602 
603   ts[tsN++]= ' ';
604   ts[tsN]=0;
605 
606   return regexec(reg, ts, 0, 0, 0);
607 }
608 
page_len()609 int page_len()
610 {
611   return (_gtab_space_auto_first & GTAB_space_auto_first_any) ?
612   cur_inmd->M_DUP_SEL+1:cur_inmd->M_DUP_SEL;
613 }
614 
page_no_str(char tstr[])615 static void page_no_str(char tstr[])
616 {
617   if (ggg.wild_mode || ggg.gtab_buf_select) {
618     int pgN = (ggg.total_matchN + cur_inmd->M_DUP_SEL - 1) / cur_inmd->M_DUP_SEL;
619     if (pgN < 2)
620       return;
621 
622     int pg = ggg.gtab_buf_select ? ggg.pg_idx : ggg.wild_page;
623     sprintf(tstr, "%d/%d", pg /cur_inmd->M_DUP_SEL + 1, pgN);
624   } else {
625     int pgN = (ggg.E1 - ggg.S1 + page_len() - 1) /page_len();
626 
627     if (pgN < 2)
628       return;
629 
630     sprintf(tstr, "%d/%d", (ggg.pg_idx - ggg.S1)/page_len()+1, pgN);
631   }
632 }
633 
htmlspecialchars(char * s,char out[])634 char *htmlspecialchars(char *s, char out[])
635 {
636   char *tstr=g_markup_escape_text(s, -1);
637   strcpy(out, tstr);
638   g_free(tstr);
639   return out;
640 }
641 
642 
disp_selection0(gboolean phrase_selected,gboolean force_disp)643 void disp_selection0(gboolean phrase_selected, gboolean force_disp)
644 {
645 #if WIN32
646   if (test_mode)
647     return;
648 #endif
649 
650   char pgstr[32];
651   pgstr[0]=0;
652   page_no_str(pgstr);
653 
654   if (!gtab_vertical_select_on()) {
655     if (ggg.more_pg)
656       set_page_label(pgstr);
657     else
658       clear_page_label();
659   }
660 
661   char tt[4096];
662   tt[0]=0;
663   char uu[MAX_CIN_PHR];
664 
665   dbg("wild %d %d\n", ggg.wild_mode, ggg.wild_mode);
666 
667   int ofs;
668   if (!ggg.wild_mode && ggg.exa_match && (_gtab_space_auto_first & GTAB_space_auto_first_any)) {
669     strcat(tt, htmlspecialchars(seltab[0], uu));
670     if (gtab_vertical_select_on())
671       strcat(tt, "\n");
672     else
673       strcat(tt, " ");
674     ofs = 1;
675   } else {
676     ofs = 0;
677   }
678 
679 
680   int i,max_i;
681   for(max_i = cur_inmd->M_DUP_SEL + ofs-1; max_i>=0; max_i--)
682     if (seltab[max_i][0])
683       break;
684 
685   for(i=ofs; i<= max_i; i++) {
686     if (seltab[i][0]) {
687       char selback[MAX_CIN_PHR+16];
688       htmlspecialchars(seltab[i], selback);
689 
690       utf8cpy(uu, &cur_inmd->selkey[i - ofs]);
691       char vvv[16];
692       char www[1024];
693       sprintf(www, "<span foreground=\"%s\">%s</span>", gcin_sel_key_color, htmlspecialchars(uu, vvv));
694       strcat(tt, www);
695 
696       if (gtab_vertical_select_on())
697         strcat(tt, " ");
698 
699       if (phrase_selected && i==ggg.sel1st_i) {
700         strcat(tt, "<span foreground=\"red\">");
701         strcat(strcat(tt, selback), " ");
702         strcat(tt, "</span>");
703       } else {
704         char uu[MAX_CIN_PHR];
705 
706         if (gtab_vertical_select_on()) {
707           utf8cpy_bytes(uu, selback, 120);
708           strcat(tt, uu);
709         } else {
710           strcat(strcat(tt, selback), " ");
711         }
712       }
713 
714       if (gtab_vertical_select_on())
715         strcat(tt, "\n");
716     } else {
717       extern gboolean b_use_full_space;
718 
719       if (!gtab_vertical_select_on() && gtab_disp_partial_match_on()) {
720          if (b_use_full_space)
721            strcat(tt, _(_L("   ")));
722          else {
723            strcat(tt, "   ");
724          }
725       }
726     }
727   }
728 
729   if (gtab_vertical_select_on() && pgstr[0]) {
730     char tstr2[16];
731     sprintf(tstr2, "(%s)", pgstr);
732     strcat(tt, tstr2);
733   }
734 
735   int len = strlen(tt);
736   if (len && tt[len-1] == '\n')
737     tt[len-1] = 0;
738 
739   if (gtab_pre_select_or_partial_on() || ggg.wild_mode || ggg.spc_pressed || ggg.last_full || force_disp) {
740     disp_gtab_sel(tt);
741   }
742 }
743 
744 
disp_selection(gboolean phrase_selected)745 void disp_selection(gboolean phrase_selected)
746 {
747   disp_selection0(phrase_selected, FALSE);
748 }
749 
wildcard()750 void wildcard()
751 {
752 #if WIN32
753   if (test_mode)
754 	  return;
755 #endif
756   int i,t, wild_ofs=0;
757   int found=0;
758   regex_t reg;
759 
760   ClrSelArea();
761   clr_seltab();
762   /* printf("wild %d %d %d %d\n", ggg.inch[0], ggg.inch[1], ggg.inch[2], ggg.inch[3]); */
763   ggg.defselN=0;
764   char regstr[32];
765   int regstrN=0;
766 
767   regstr[regstrN++]=' ';
768 
769   for(i=0; i < KEY_N; i++) {
770     if (!ggg.inch[i])
771       break;
772     if (ggg.inch[i] == cur_inmd->WILD_STAR) {
773       regstr[regstrN++]='.';
774       regstr[regstrN++]='*';
775     } else
776     if (ggg.inch[i] == cur_inmd->WILD_QUES) {
777       regstr[regstrN++]='.';
778     } else {
779       char c = ggg.inch[i] + '0';         // start from '0'
780       if (strchr("*.\\()[]", c))
781       regstr[regstrN++] = '\\';
782       regstr[regstrN++]=c;
783     }
784   }
785 
786   regstr[regstrN++]=' ';
787   regstr[regstrN]=0;
788 
789 //  dbg("regstr %s\n", regstr);
790 
791   if (regcomp(&reg, regstr, 0)) {
792     dbg("regcomp failed\n");
793     return;
794   }
795 
796   for(t=0; t< cur_inmd->DefChars && ggg.defselN < cur_inmd->M_DUP_SEL; t++) {
797     if (cmp_inmd_idx(&reg, t))
798       continue;
799 
800     if (wild_ofs >= ggg.wild_page) {
801       load_seltab(t, ggg.defselN);
802       ggg.defselN++;
803     } else
804       wild_ofs++;
805 
806     found=1;
807   } /* for t */
808 
809 
810   if (!found) {
811     bell_err();
812   } else
813   if (!ggg.wild_page) {
814     ggg.total_matchN = 0;
815 
816     for(t=0; t< cur_inmd->DefChars; t++)
817       if (!cmp_inmd_idx(&reg, t))
818         ggg.total_matchN++;
819 
820   }
821 
822   if (ggg.total_matchN > cur_inmd->M_DUP_SEL)
823     ggg.more_pg = 1;
824 
825   regfree(&reg);
826   disp_selection(FALSE);
827 }
828 
ptr_selkey(KeySym key)829 static char *ptr_selkey(KeySym key)
830 {
831   if (key>= XK_KP_0 && key<= XK_KP_9)
832     key-= XK_KP_0 - '0';
833   return strchr(cur_inmd->selkey, key);
834 }
835 
836 
837 void init_gtab_pho_query_win();
838 int feedkey_pho(KeySym xkey, int state);
839 
set_gtab_target_displayed()840 void set_gtab_target_displayed()
841 {
842   close_gtab_pho_win();
843 }
844 
is_gtab_query_mode()845 gboolean is_gtab_query_mode()
846 {
847   return poo.same_pho_query_state == SAME_PHO_QUERY_pho_select;
848 }
849 
reset_gtab_all()850 void reset_gtab_all()
851 {
852   if (!cur_inmd)
853     return;
854 
855   ClrIn();
856   ClrSelArea();
857   if (gcin_pop_up_win)
858     hide_win_gtab();
859 }
860 
861 
has_wild_card()862 static gboolean has_wild_card()
863 {
864   int i;
865 
866   for(i=0; i < cur_inmd->MaxPress; i++)
867     if (ggg.inch[i]>= cur_inmd->WILD_QUES) {
868       return TRUE;
869     }
870 
871   return FALSE;
872 }
873 
proc_wild_disp()874 static void proc_wild_disp()
875 {
876 #if WIN32
877    if (test_mode)
878 	   return;
879 #endif
880    DispInArea();
881    ggg.wild_page = 0;
882    wildcard();
883    disp_selection(0);
884 }
885 
886 gboolean full_char_proc(KeySym keysym);
887 void insert_gbuf_cursor_char(char ch);
888 gboolean gtab_pre_select_shift(KeySym key, int kbstate);
889 
shift_char_proc(KeySym key,int kbstate)890 gboolean shift_char_proc(KeySym key, int kbstate)
891 {
892     if (key >= 127)
893       return FALSE;
894 
895 #if 0
896     if (kbstate & LockMask) {
897       if (key >= 'a' && key <= 'z')
898         key-=0x20;
899     } else {
900       if (key >= 'A' && key <= 'Z')
901         key+=0x20;
902     }
903 #endif
904 
905     if (gtab_pre_select_shift(key, kbstate))
906       return TRUE;
907 
908     if (current_CS->b_half_full_char)
909       return full_char_proc(key);
910 
911     if (ggg.gbufN)  {
912 	  if (strchr("<>?':_+$^&(){}|!@$*#%\"~",  key)  != NULL)  {
913 		  output_gbuf();
914 	     send_ascii(key);
915       } else
916          insert_gbuf_cursor_char(key);
917     } else
918       send_ascii(key);
919 
920     return TRUE;
921 }
922 
923 extern GtkWidget *gwin_pho;
924 gboolean feed_phrase(KeySym ksym, int state);
925 int gtab_buf_backspace();
926 int show_buf_select();
927 void gbuf_next_pg(), gbuf_prev_pg();
928 void show_win_gtab();
929 int gbuf_cursor_left();
930 int gbuf_cursor_right();
931 int gbuf_cursor_home();
932 int gbuf_cursor_end();
933 int gtab_buf_delete();
934 void set_gbuf_c_sel(int v);
935 void set_gtab_user_head();
936 KeySym keypad_proc(KeySym xkey);
937 void save_gtab_buf_phrase(KeySym key);
938 gboolean save_gtab_buf_shift_enter();
939 gboolean win_sym_page_up(), win_sym_page_down();
940 u_int64_t vmaskci;
941 gboolean gtab_pre_select_idx(int c);
942 void save_CS_current_to_temp();
943 void disp_tray_icon();
944 void gtab_reset();
945 
946 static int handle_timeout_auto_space;
947 void send_fake_key_eve(KeySym key);
cb_timeout_auto_space(gpointer data)948 static gboolean cb_timeout_auto_space(gpointer data)
949 {
950 	handle_timeout_auto_space = 0;
951 	if (ggg.ci)
952 	  send_fake_key_eve(' ');
953 
954 	return FALSE;
955 }
956 
clear_handle_timeout_auto_space()957 void clear_handle_timeout_auto_space() {
958 	if (!handle_timeout_auto_space)
959 		return;
960 	g_source_remove(handle_timeout_auto_space);
961 	handle_timeout_auto_space = 0;
962 }
963 
add_timeout_auto_space()964 static void add_timeout_auto_space()
965 {
966 	clear_handle_timeout_auto_space();
967 	handle_timeout_auto_space = g_timeout_add(gtab_auto_space, cb_timeout_auto_space, NULL);
968 }
969 
970 void gtab_en_scan_pre_select();
971 extern char *wselkey;
972 extern gboolean capslock_on;
973 void clear_gbuf_sel();
974 gboolean gtab_phrase_on_();
975 gboolean output_gbuf_();
976 
flush_en()977 void flush_en() {
978 	if (!gtab_phrase_on_() && ggg.gbufN) // may true if en_pre_select is on
979 		output_gbuf_();
980 }
981 
gen_kval()982 void gen_kval() {
983     ggg.kval=0;
984     int i;
985     for(i=0; i < Max_tab_key_num; i++) {
986       ggg.kval|= (u_int64_t)ggg.inch[i] << (KeyBits * (Max_tab_key_num - 1 - i));
987     }
988 
989     if (cur_inmd->keybits==6)
990       vmaskci = cur_inmd->key64 ? vmask64[ggg.ci]:vmask[ggg.ci];
991     else
992       vmaskci = cur_inmd->key64 ? vmask64_7[ggg.ci]:vmask_7[ggg.ci];
993 }
994 
invalid_key_in()995 static void invalid_key_in() {
996 	dbg("invalid_key_in\n");
997     if (gtab_invalid_key_in) {
998       if (ggg.spc_pressed) {
999         bell_err();
1000         ggg.invalid_spc = TRUE;
1001 //        dbg("ggg.invalid_spc\n");
1002       } else {
1003         seltab[0][0]=0;
1004         ClrSelArea();
1005       }
1006     } else {
1007       if (gtab_dup_select_bell)
1008         bell();
1009 
1010       if (ggg.ci>0)
1011         ggg.inch[--ggg.ci]=0;
1012     }
1013 
1014     ggg.last_idx=0;
1015     DispInArea();
1016 }
1017 
feedkey_gtab(KeySym key,int kbstate)1018 gboolean feedkey_gtab(KeySym key, int kbstate)
1019 {
1020   int i,j=0;
1021   int inkey=0;
1022   char *pselkey= NULL;
1023   gboolean phrase_selected = FALSE;
1024   char seltab_phrase[MAX_SELKEY];
1025   gboolean is_keypad = FALSE;
1026   gboolean shift_m = (kbstate & ShiftMask) > 0;
1027   gboolean ctrl_m = (kbstate & ControlMask) > 0;
1028   int caps_eng_tog = tsin_chinese_english_toggle_key == TSIN_CHINESE_ENGLISH_TOGGLE_KEY_CapsLock;
1029   gboolean is_dayi = !strncmp(cur_inmd->filename, "dayi", 4);
1030 
1031   bzero(seltab_phrase, sizeof(seltab_phrase));
1032 
1033   dbg("feedkey_gtab %c key:%x %x   shift,ctrl:%d,%d\n", key, key, kbstate, shift_m, ctrl_m);
1034 
1035   if (!cur_inmd)
1036     return 0;
1037 
1038   if (!current_CS) {
1039     dbg("current_CS is null\n");
1040     return 0;
1041   }
1042 
1043   if (caps_eng_tog) {
1044     gboolean new_tsin_pho_mode =!capslock_on;
1045     if (current_CS->tsin_pho_mode != new_tsin_pho_mode) {
1046       current_CS->tsin_pho_mode = new_tsin_pho_mode;
1047       save_CS_current_to_temp();
1048       disp_tray_icon();
1049     }
1050   }
1051 
1052   if (cur_inmd && (cur_inmd->flag & FLAG_GTAB_SYM_KBM))
1053     current_CS->tsin_pho_mode = TRUE;
1054 
1055   if ((kbstate & (Mod1Mask|Mod4Mask|Mod5Mask|ControlMask))==ControlMask
1056      && key>='1' && key<='9' && ggg.gbufN) {
1057     save_gtab_buf_phrase(key);
1058     return 1;
1059   }
1060 
1061   if (ggg.gbufN && key==XK_Tab)
1062     return 1;
1063 
1064    if ((key==XK_Shift_L||key==XK_Shift_R) && !key_press_time) {
1065      key_press_time = current_time();
1066      key_press_time_ctrl = 0;
1067    } else
1068   if ((key==XK_Control_L||key==XK_Control_R) && !key_press_time_ctrl && tss.pre_selN) {
1069     key_press_time_ctrl = current_time();
1070     return TRUE;
1071   } else {
1072     key_press_time_ctrl = 0;
1073     key_press_time = 0;
1074   }
1075 
1076   if (kbstate & (Mod1Mask|Mod4Mask|Mod5Mask|ControlMask)) {
1077     return 0;
1078   }
1079 
1080   if (poo.same_pho_query_state == SAME_PHO_QUERY_pho_select)
1081     return feedkey_pho(key, 0);
1082 
1083   if (poo.same_pho_query_state == SAME_PHO_QUERY_none && gwin_pho &&
1084     GTK_WIDGET_VISIBLE(gwin_pho))
1085      hide_win_pho();
1086 
1087   if (!tsin_pho_mode()) {
1088     if (key < 0x20 || key>=0x7f)
1089       goto shift_proc;
1090 
1091     if (capslock_on && gcin_capslock_lower)
1092       case_inverse((KeySym *)&key, shift_m);
1093 
1094     dbg("aa\n");
1095 
1096     if (current_CS->b_half_full_char)
1097       return full_char_proc(key);
1098 en_char:
1099     if (AUTO_SELECT_BY_PHRASE && (ggg.gbufN || en_pre_select)) {
1100 	  char *p;
1101 	  if (tss.pre_selN && (p=strchr(wselkey, key))) {
1102 		int vv = p - wselkey;
1103 		dbg("wselkey '%s'", wselkey);
1104 		gtab_pre_select_idx(vv);
1105         return TRUE;
1106       } else {
1107 		dbg("bb ggg.gbuf_cursor %d %d\n", ggg.gbuf_cursor, ggg.gbufN);
1108         insert_gbuf_cursor_char(key);
1109 
1110 		if (ggg.gbuf_cursor==ggg.gbufN && (strchr("<>,./;-=?':[]_0123456789+$^&(){}|\\!@*#%\"`~", key) != NULL || (key==' ' && !en_pre_select) )) {
1111 		  dbg("output\n");
1112 		  output_gbuf();
1113           return 1;
1114 	    }
1115 
1116         show_win_gtab();
1117         disp_gbuf();
1118         if (en_pre_select)
1119           gtab_en_scan_pre_select();
1120       }
1121     } else
1122       send_ascii(key);
1123 
1124     dbg("ret\n");
1125     return 1;
1126   }
1127 
1128   int lcase;
1129   lcase = tolower(key);
1130   int ucase;
1131   ucase = toupper(key);
1132   if (!strchr(cur_inmd->selkey, key) && key < 127 && cur_inmd && cur_inmd->keymap && cur_inmd->keymap[key]) {
1133      if (key < 'A' || key > 'z' || key > 'Z'  && key < 'a' ) {
1134        goto shift_proc;
1135 	 }
1136      if (cur_inmd->keymap[lcase] != cur_inmd->keymap[ucase]) {
1137        goto next;
1138 	 }
1139   }
1140 
1141 shift_proc:
1142   if (shift_m && !strchr(cur_inmd->selkey, key) && !ggg.more_pg && key>=' ' && key < 0x7e &&
1143        key!='*' && (key!='?' || gtab_shift_phrase_key && !ggg.ci)) {
1144 
1145     if (gtab_shift_phrase_key) {
1146       if (tss.pre_selN && shift_char_proc(key, kbstate))
1147         return TRUE;
1148       if (feed_phrase(key, kbstate))
1149         return TRUE;
1150     } else {
1151       if (!cur_inmd->keymap[key] || (lcase != ucase &&
1152            cur_inmd->keymap[lcase]==cur_inmd->keymap[ucase]))
1153         return shift_char_proc(key, kbstate);
1154     }
1155   }
1156 
1157   gboolean has_wild;
1158   has_wild = FALSE;
1159 
1160   switch (key) {
1161     case XK_BackSpace:
1162       ggg.last_idx=0;
1163       ggg.spc_pressed=0;
1164       ggg.sel1st_i=MAX_SELKEY-1;
1165       clear_gtab_input_error_color();
1166       hide_gtab_pre_sel();
1167 
1168       if (ggg.ci==0) {
1169         if (AUTO_SELECT_BY_PHRASE)
1170           return gtab_buf_backspace();
1171         else
1172           return 0;
1173       }
1174 
1175       if (ggg.ci>0)
1176         ggg.inch[--ggg.ci]=0;
1177 
1178       if (has_wild_card()) {
1179         proc_wild_disp();
1180         return 1;
1181       }
1182 
1183 
1184       ggg.wild_mode=0;
1185       ggg.invalid_spc = FALSE;
1186       if (ggg.ci==1 && cur_inmd->use_quick) {
1187         int i;
1188         clr_seltab();
1189 
1190         if (ggg.inch[0]-1 <MAX_GTAB_QUICK_KEYS)
1191         for(i=0;i<cur_inmd->M_DUP_SEL;i++)
1192           utf8cpy(seltab[i], (char *)cur_inmd->qkeys->quick1[ggg.inch[0]-1][i]);
1193 
1194         ggg.defselN=cur_inmd->M_DUP_SEL;
1195         DispInArea();
1196         gtab_scan_pre_select(TRUE);
1197         goto Disp_opt;
1198       } else
1199       if (ggg.ci==2 && cur_inmd->use_quick) {
1200         int i;
1201         clr_seltab();
1202 
1203         if (ggg.inch[0]-1 <MAX_GTAB_QUICK_KEYS && ggg.inch[1]-1<MAX_GTAB_QUICK_KEYS)
1204         for(i=0;i<cur_inmd->M_DUP_SEL;i++)
1205           utf8cpy(seltab[i], (char *)cur_inmd->qkeys->quick2[ggg.inch[0]-1][ggg.inch[1]-1][i]);
1206 
1207         ggg.defselN=cur_inmd->M_DUP_SEL;
1208         DispInArea();
1209         gtab_scan_pre_select(TRUE);
1210         goto Disp_opt;
1211       }
1212 
1213       break;
1214     case XK_KP_Enter:
1215     case XK_Return:
1216       if (AUTO_SELECT_BY_PHRASE) {
1217         hide_gtab_pre_sel();
1218         if (shift_m) {
1219           return save_gtab_buf_shift_enter();
1220         } else
1221           return output_gbuf();
1222       }
1223       else {
1224 		if (gtab_has_input())
1225 			return 1;
1226         return 0;
1227 	  }
1228     case XK_Up:
1229       if (gtab_has_input())
1230         return TRUE;
1231       return FALSE;
1232     case XK_Down:
1233 #if UNIX
1234     case XK_KP_Down:
1235 #endif
1236 
1237       if (AUTO_SELECT_BY_PHRASE)
1238         return show_buf_select();
1239       else
1240         return 0;
1241     case XK_Escape:
1242       hide_gtab_pre_sel();
1243       if (ggg.gtab_buf_select) {
1244 		dbg("gtab_buf_select\n");
1245         ggg.gtab_buf_select = 0;
1246 #if 0
1247         reset_gtab_all();
1248 #else
1249 		ClrIn();
1250 		ClrSelArea();
1251 #endif
1252         if (gcin_pop_up_win && !gtab_has_input())
1253           hide_win_gtab();
1254         return 1;
1255       }
1256 
1257       close_gtab_pho_win();
1258       if (ggg.ci) {
1259 #if 0
1260         reset_gtab_all();
1261 #else
1262 		ClrIn();
1263 #endif
1264         return 1;
1265       } else {
1266         if (ggg.gbufN) {
1267 
1268 		  if (ggg.gtab_buf_select) {
1269 			  clear_gbuf_sel();
1270 			  return TRUE;
1271 		  }
1272           if (gcin_escape_clear_edit_buffer) {
1273 			gtab_reset();
1274 			return 1;
1275 		  }
1276           set_gtab_user_head();
1277           return 1;
1278         }
1279         ClrIn();
1280         return 0;
1281       }
1282     case XK_Prior:
1283 #if UNIX
1284     case XK_KP_Prior:
1285 #endif
1286     case XK_KP_Subtract:
1287       if (ggg.wild_mode) {
1288         if (ggg.wild_page >= cur_inmd->M_DUP_SEL) ggg.wild_page-=cur_inmd->M_DUP_SEL;
1289         wildcard();
1290         return 1;
1291       } else
1292       if (ggg.more_pg) {
1293         if (ggg.gtab_buf_select) {
1294           gbuf_prev_pg();
1295           return 1;
1296         }
1297 
1298         ggg.pg_idx -= page_len();
1299         if (ggg.pg_idx < ggg.S1)
1300           ggg.pg_idx = ggg.S1;
1301 
1302         goto next_pg;
1303       }
1304 
1305       if (key==XK_KP_Subtract)
1306         goto keypad_proc;
1307 
1308       return win_sym_page_up();
1309     case XK_Next:
1310 #if UNIX
1311     case XK_KP_Next:
1312 #endif
1313     case XK_KP_Add:
1314       if (ggg.more_pg) {
1315         if (ggg.gtab_buf_select) {
1316           gbuf_next_pg();
1317           return 1;
1318         }
1319 next_page:
1320         dbg("more...pg_idx:%d page_len:%d\n", ggg.pg_idx, page_len());
1321         ggg.pg_idx += page_len();
1322         if (ggg.pg_idx >=ggg.E1)
1323           ggg.pg_idx = ggg.S1;
1324         goto next_pg;
1325       } else {
1326         if (key==XK_KP_Add)
1327           goto keypad_proc;
1328         if (win_sym_page_down())
1329           return TRUE;
1330         if (!ggg.gtab_buf_select && ggg.gbufN && AUTO_SELECT_BY_PHRASE)
1331           return show_buf_select();
1332         return FALSE;
1333       }
1334     case ' ':
1335 	  if (!ggg.more_pg)
1336 		hide_gtab_pre_sel();
1337 
1338       if (ggg.invalid_spc && gtab_invalid_key_in)
1339         ClrIn();
1340 
1341       if (!gtab_invalid_key_in && ggg.spc_pressed && ggg.invalid_spc) {
1342         ClrIn();
1343         return 1;
1344       }
1345 
1346       has_wild = has_wild_card();
1347 
1348       dbg("ggg.wild_mode:%d ggg.more_pg:%d ggg.ci:%d  has_wild:%d\n", ggg.wild_mode, ggg.more_pg, ggg.ci, has_wild);
1349 
1350       if (ggg.wild_mode) {
1351         // request from tetralet
1352         if (!ggg.wild_page && ggg.total_matchN < cur_inmd->M_DUP_SEL) {
1353           ggg.sel1st_i = 0;
1354           goto direct_select;
1355         }
1356 
1357         ggg.wild_page += cur_inmd->M_DUP_SEL;
1358         if (ggg.wild_page >= ggg.total_matchN)
1359           ggg.wild_page=0;
1360 
1361         wildcard();
1362         ggg.spc_pressed = TRUE;
1363         return 1;
1364       } else
1365       if (ggg.more_pg && !(_gtab_space_auto_first & GTAB_space_auto_first_any)) {
1366         if (ggg.gtab_buf_select) {
1367           gbuf_next_pg();
1368           return 1;
1369         }
1370         else
1371           goto next_page;
1372       } else
1373       if (ggg.ci==0) {
1374         if (ggg.gbufN) {
1375 		  if (tsin_space_opt & (TSIN_SPACE_OPT_INPUT|TSIN_SPACE_OPT_FLUSH_EDIT)) {
1376 			dbg("output_gbuf\n");
1377 			output_gbuf();
1378 			if (tsin_space_opt == TSIN_SPACE_OPT_INPUT) {
1379               if (current_CS->b_half_full_char)
1380 			    return full_char_proc(key);
1381 			  send_ascii(' ');
1382 		    }
1383 
1384 		    return TRUE;
1385 		  } else
1386 		    return show_buf_select();
1387         }
1388 
1389         if (current_CS->b_half_full_char)
1390           return full_char_proc(key);
1391         return 0;
1392       } else
1393       if (!has_wild) {
1394         dbg("iii %d  ggg.defselN:%d   %d\n", ggg.sel1st_i, ggg.defselN, cur_inmd->M_DUP_SEL);
1395         if (_gtab_space_auto_first == GTAB_space_auto_first_any && seltab[0][0] &&
1396             ggg.sel1st_i==MAX_SELKEY-1) {
1397 		  dbg("yy\n");
1398           ggg.sel1st_i = 0;
1399         }
1400 
1401         if (_gtab_space_auto_first == GTAB_space_auto_first_nofull && ggg.exa_match > 1
1402             && !gtab_phrase_on_() && gtab_dup_select_bell)
1403           bell();
1404         dbg("bbbb\n");
1405         if (seltab[ggg.sel1st_i][0]) {
1406           dbg("ggg.last_full %d %d\n", ggg.last_full,ggg.spc_pressed);
1407           if (gtab_full_space_auto_first || ggg.spc_pressed) {
1408 direct_select:
1409             if (gtab_phrase_on_() && poo.same_pho_query_state != SAME_PHO_QUERY_gtab_input) {
1410               dbg("ins ggg.kval %x\n", ggg.kval);
1411               insert_gbuf_cursor1_cond(seltab[ggg.sel1st_i], ggg.kval, ggg.exa_match);
1412             }
1413             else {
1414 			  flush_en();
1415               putstr_inp(seltab[ggg.sel1st_i]);  /* select 1st */
1416             }
1417             return 1;
1418           }
1419         }
1420       }
1421 
1422       ggg.last_full=0;
1423       ggg.spc_pressed=1;
1424       dbg("spc_pressed=1\n");
1425 
1426       if (has_wild) {
1427         ggg.wild_page=0;
1428         ggg.wild_mode=1;
1429         wildcard();
1430         return 1;
1431       }
1432 
1433       break;
1434     case '?':
1435       if (!gtab_que_wild_card) {
1436         inkey=cur_inmd->keymap[key];
1437         if ((inkey && (inkey!=cur_inmd->WILD_QUES && inkey!=cur_inmd->WILD_STAR)) || ptr_selkey(key))
1438           goto next;
1439         if (gtab_phrase_on_() && ggg.gbufN) {
1440           insert_gbuf_cursor_char(key);
1441           return 1;
1442         } else {
1443           if (current_CS->b_half_full_char)
1444             return full_char_proc(key);
1445 		  else
1446             return 0;
1447 		}
1448       }
1449     case '*':
1450       if (tss.pre_selN && shift_char_proc(key, kbstate))
1451         return TRUE;
1452 
1453       if (current_CS->b_half_full_char)
1454         return full_char_proc(key);
1455 
1456       inkey=cur_inmd->keymap[key];
1457       if ((inkey && (inkey!=cur_inmd->WILD_STAR && inkey!=cur_inmd->WILD_QUES)) || ptr_selkey(key)) {
1458 //        dbg("%d %d\n", inkey, cur_inmd->WILD_STAR);
1459         goto next;
1460       }
1461 
1462 	  if (!gtab_star_wild_card) {
1463 		  insert_gbuf_cursor_char('*');
1464 		  output_gbuf();
1465 		  return TRUE;
1466 	  }
1467       if (ggg.ci< cur_inmd->MaxPress) {
1468 #if WIN32
1469 		  if (test_mode)
1470 			  return 1;
1471 #endif
1472         ggg.inch[ggg.ci++]=inkey;
1473         DispInArea();
1474 
1475         if (gcin_pop_up_win)
1476           show_win_gtab();
1477 
1478         ggg.total_matchN = 0;
1479         ggg.wild_page=0;
1480         ggg.wild_mode=1;
1481         wildcard();
1482         return 1;
1483       }
1484       return 0;
1485     case XK_Left:
1486 #if UNIX
1487     case XK_KP_Left:
1488 #endif
1489       return gbuf_cursor_left();
1490     case XK_Right:
1491 #if UNIX
1492     case XK_KP_Right:
1493 #endif
1494       return gbuf_cursor_right();
1495     case XK_Home:
1496 #if UNIX
1497     case XK_KP_Home:
1498 #endif
1499       return gbuf_cursor_home();
1500     case XK_End:
1501 #if UNIX
1502     case XK_KP_End:
1503 #endif
1504       return gbuf_cursor_end();
1505     case XK_Delete:
1506 #if UNIX
1507     case XK_KP_Delete:
1508 #endif
1509       return gtab_buf_delete();
1510     case XK_Shift_L:
1511     case XK_Shift_R:
1512     case XK_Control_R:
1513     case XK_Control_L:
1514     case XK_Alt_L:
1515     case XK_Alt_R:
1516     case XK_Caps_Lock:
1517       return 0;
1518     case '`':
1519       if (!cur_inmd->keymap[key]) {
1520 #if WIN32
1521 		if (!test_mode)
1522 #endif
1523 		{
1524 			poo.same_pho_query_state = SAME_PHO_QUERY_gtab_input;
1525 			disp_gtab_sel("輸入要查的同音字,接著在注音視窗選字");
1526 			if (gcin_pop_up_win)
1527 			show_win_gtab();
1528 			init_gtab_pho_query_win();
1529 		}
1530         return 1;
1531       }
1532     default:
1533 next:
1534 	  dbg("next:\n");
1535 
1536       if (key < 0x7f)
1537         inkey= cur_inmd->keymap[key];
1538       else
1539         inkey = 0;
1540 
1541       if (shift_m && !inkey && !tss.ctrl_pre_sel && tss.pre_selN && shift_char_proc(key, kbstate))
1542         return TRUE;
1543 
1544       clear_gtab_input_error_color();
1545 
1546       if (ggg.invalid_spc && gtab_invalid_key_in) {
1547         ClrIn();
1548       }
1549       if (key>=XK_KP_0 && key<=XK_KP_9) {
1550         if (cur_inmd->flag & FLAG_GTAB_KEYPAD_INPUT_KEY) {
1551           key = key - XK_KP_0 + '0';
1552           inkey= cur_inmd->keymap[key];
1553         } else {
1554           if (!ggg.ci) {
1555             if (ggg.gbufN) {
1556 #if WIN32
1557 			  if (!test_mode)
1558 #endif
1559 				insert_gbuf_cursor_char(key - XK_KP_0 + '0');
1560               return 1;
1561             } else
1562               return 0;
1563           }
1564           if (is_dayi) {
1565             key = key - XK_KP_0 + '0';
1566             is_keypad = TRUE;
1567           }
1568         }
1569       }
1570 
1571       int keypad;
1572 keypad_proc:
1573       keypad = keypad_proc(key);
1574       if (keypad) {
1575         if (!ggg.ci) {
1576           if (ggg.gbufN) {
1577 #if WIN32
1578 			if (!test_mode)
1579 #endif
1580 				insert_gbuf_cursor_char(keypad);
1581             return 1;
1582           } else
1583             return 0;
1584         }
1585       }
1586       char *pendkey = strchr(cur_inmd->endkey, key);
1587 
1588       pselkey=ptr_selkey(key);
1589 
1590 	  dbg("pselkey %p %c:%x\n", pselkey, key, key);
1591 
1592       if (!pselkey && (key < 32 || key > 0x7e) && (gtab_full_space_auto_first || ggg.spc_pressed)) {
1593 //        dbg("%x %x ggg.sel1st_i:%d  '%c'\n", pselkey, key, ggg.sel1st_i, seltab[ggg.sel1st_i][0]);
1594 #if WIN32
1595 		  if (test_mode)
1596 			  return 0;
1597 #endif
1598         if (seltab[ggg.sel1st_i][0]) {
1599           if (gtab_phrase_on_() && poo.same_pho_query_state != SAME_PHO_QUERY_gtab_input)
1600             insert_gbuf_cursor1_cond(seltab[ggg.sel1st_i], ggg.kval, ggg.exa_match);
1601           else {
1602             flush_en();
1603             putstr_inp(seltab[ggg.sel1st_i]);  /* select 1st */
1604           }
1605         }
1606 
1607         return 0;
1608       }
1609 
1610         dbg("ggg.spc_pressed %d %d %d is_keypad:%d\n", ggg.spc_pressed, ggg.last_full, cur_inmd->MaxPress, is_keypad);
1611 
1612 #if 1 // for dayi, testcase :  6 space keypad6
1613       int vv = pselkey - cur_inmd->selkey;
1614       if (pselkey && tss.pre_selN && !ggg.gtab_buf_select && (tss.ctrl_pre_sel|| en_pre_select ||
1615           ((!inkey||ggg.spc_pressed||is_keypad)&&! gtab_disp_partial_match_on() && !gtab_pre_select_on()))) {
1616 	    dbg("jjjjj\n");
1617         if (gtab_pre_select_idx(vv)) {
1618 		  dbg("TRUE");
1619           return TRUE;
1620 		}
1621       } else
1622       if (( (ggg.spc_pressed||ggg.last_full||is_keypad) ||(ggg.wild_mode && (!inkey ||pendkey)) || ggg.gtab_buf_select) && pselkey) {
1623         if ((_gtab_space_auto_first & GTAB_space_auto_first_any) && !ggg.wild_mode)
1624           vv++;
1625 
1626         if (vv<0)
1627           vv=9;
1628 
1629         if (seltab[vv][0]) {
1630 #if WIN32
1631 		  if (!test_mode)
1632 #endif
1633 		  {
1634 			  if (gtab_phrase_on_() && !same_query_show_pho_win()) {
1635 				if (ggg.gtab_buf_select && poo.same_pho_query_state != SAME_PHO_QUERY_gtab_input)
1636 				  set_gbuf_c_sel(vv);
1637 				else
1638 				  insert_gbuf_cursor1_cond(seltab[vv], ggg.kval, ggg.exa_match);
1639 			  }
1640 			  else {
1641 				flush_en();
1642 				putstr_inp(seltab[vv]);
1643 			  }
1644 
1645 			  if (gcin_pop_up_win && !gtab_has_input())
1646 				hide_win_gtab();
1647 		  }
1648           return TRUE;
1649         }
1650       }
1651 #endif
1652 
1653       dbg("iii %x sel1st_i:%d auto:%d\n", pselkey, ggg.sel1st_i, AUTO_SELECT_BY_PHRASE);
1654       if (seltab[ggg.sel1st_i][0] && !ggg.wild_mode &&
1655            (gtab_full_space_auto_first||ggg.spc_pressed||ggg.last_full) ) {
1656         if (gtab_phrase_on_() && poo.same_pho_query_state != SAME_PHO_QUERY_gtab_input)
1657           insert_gbuf_cursor1_cond(seltab[ggg.sel1st_i], ggg.kval, ggg.exa_match);
1658         else {
1659 		  flush_en();
1660           putstr_inp(seltab[ggg.sel1st_i]);  /* select 1st */
1661         }
1662       }
1663 #if 0
1664       if (key > 0x7f) {
1665         return 0;
1666       }
1667 #endif
1668 
1669       ggg.spc_pressed=0;
1670 
1671       // for cj & boshiamy to input digits
1672       if (!ggg.ci && !inkey) {
1673         if (current_CS->b_half_full_char)
1674           return full_char_proc(key);
1675         else {
1676           if (ggg.gbufN && poo.same_pho_query_state != SAME_PHO_QUERY_gtab_input) {
1677 #if 1
1678 			output_gbuf();
1679 			send_ascii(key);
1680 #else
1681             insert_gbuf_cursor_char(key);
1682 #endif
1683             return 1;
1684           }
1685           else
1686             return 0;
1687         }
1688       }
1689 
1690       if (ggg.wild_mode && inkey>=1 && ggg.ci< cur_inmd->MaxPress) {
1691         ggg.inch[ggg.ci++]=inkey;
1692         if (gcin_pop_up_win)
1693           show_win_gtab();
1694         proc_wild_disp();
1695         return 1;
1696       }
1697 
1698       if (inkey>=1 && ggg.ci< cur_inmd->MaxPress) {
1699         ggg.inch[ggg.ci++]=inkey;
1700         hide_gtab_pre_sel();
1701 
1702         gen_kval();
1703         if (gcin_pop_up_win)
1704           show_win_gtab();
1705         ggg.last_full=0;
1706 
1707         if (cur_inmd->use_quick && !pendkey) {
1708           if (ggg.ci==1) {
1709             int i;
1710 
1711             if (inkey-1<MAX_GTAB_QUICK_KEYS) {
1712 #if WIN32
1713               if (test_mode)
1714 				return 1;
1715 #endif
1716               for(i=0;i < cur_inmd->M_DUP_SEL; i++) {
1717                 utf8cpy(seltab[i], (char *)&cur_inmd->qkeys->quick1[inkey-1][i]);
1718               }
1719               ggg.defselN=cur_inmd->M_DUP_SEL;
1720               DispInArea();
1721               gtab_scan_pre_select(TRUE);
1722               goto Disp_opt;
1723             }
1724           } else
1725           if (ggg.ci==2 && !pselkey) {
1726             if (ggg.inch[0]-1 <MAX_GTAB_QUICK_KEYS && inkey-1<MAX_GTAB_QUICK_KEYS) {
1727 #if WIN32
1728               if (test_mode)
1729 				return 1;
1730 #endif
1731               int i;
1732               for(i=0;i < cur_inmd->M_DUP_SEL; i++) {
1733                 utf8cpy(seltab[i], (char *)&cur_inmd->qkeys->quick2[ggg.inch[0]-1][inkey-1][i]);
1734               }
1735               ggg.defselN=cur_inmd->M_DUP_SEL;
1736               DispInArea();
1737 			  gtab_scan_pre_select(TRUE);
1738               goto Disp_opt;
1739             }
1740           }
1741         }
1742       } else
1743       if (ggg.ci == cur_inmd->MaxPress && !pselkey) {
1744         bell();
1745         return 1;
1746       }
1747 
1748 
1749       if (inkey) {
1750         for(i=0; i < MAX_TAB_KEY_NUM64_6; i++)
1751           if (ggg.inch[i]>=cur_inmd->WILD_QUES) {
1752 #if WIN32
1753 			if (test_mode)
1754 				return 1;
1755 #endif
1756             DispInArea();
1757             if (ggg.ci==cur_inmd->MaxPress) {
1758               ggg.wild_mode=1;
1759               ggg.wild_page=0;
1760               wildcard();
1761             }
1762 
1763             return 1;
1764           }
1765       } else {
1766         if (!pselkey) {
1767           if (current_CS->b_half_full_char)
1768             return full_char_proc(key);
1769           else {
1770             if (key>=' ' && key<0x7f && AUTO_SELECT_BY_PHRASE && ggg.gbufN)
1771               insert_gbuf_cursor_char(key);
1772             else
1773               return 0;
1774           }
1775         }
1776 
1777         if (ggg.defselN) {
1778           goto YYYY;
1779         }
1780      }
1781   } /* switch */
1782 
1783 
1784   if (ggg.ci==0) {
1785     ClrSelArea();
1786     ClrIn();
1787     return 1;
1788   }
1789 
1790   ggg.invalid_spc = FALSE;
1791   char *pendkey = NULL;
1792   pendkey = strchr(cur_inmd->endkey, key);
1793 
1794   DispInArea();
1795 
1796 #if 0
1797   ggg.kval=0;
1798   for(i=0; i < Max_tab_key_num; i++) {
1799     ggg.kval|= (u_int64_t)ggg.inch[i] << (KeyBits * (Max_tab_key_num - 1 - i));
1800   }
1801 #endif
1802   gen_kval();
1803 
1804 #if 1
1805   if (ggg.last_idx)
1806     ggg.S1=ggg.last_idx;
1807   else
1808 #endif
1809     ggg.S1=cur_inmd->idx1[ggg.inch[0]];
1810 
1811 //  dbg("--------- ch:%d %d val %llx  ggg.S1:%d\n", ggg.inch[0], Max_tab_key_num, ggg.kval, ggg.S1);
1812 
1813 
1814   int oE1;
1815   oE1=cur_inmd->idx1[ggg.inch[0]+1];
1816 
1817   int b0=ggg.S1;
1818   int b1=oE1;
1819   int mid;
1820   do {
1821 	 mid = (b0+b1)/2;
1822 	 u_int64_t v = CONVT2(cur_inmd, mid);
1823 	 if (v < ggg.kval)
1824 		 b0 = mid+1;
1825 	 else
1826 	 if (v > ggg.kval)
1827 		 b1 = mid-1;
1828 	 else
1829 		 break;
1830   } while (b0 < b1);
1831 
1832   i = mid;
1833   while (i > ggg.S1) {
1834 	u_int64_t v = CONVT2(cur_inmd, i);
1835 	if (v < ggg.kval)
1836 		break;
1837 	i--;
1838   }
1839   ggg.S1 = i;
1840 
1841 
1842 #if 0
1843   if (cur_inmd->keybits==6)
1844     vmaskci = cur_inmd->key64 ? vmask64[ggg.ci]:vmask[ggg.ci];
1845   else
1846     vmaskci = cur_inmd->key64 ? vmask64_7[ggg.ci]:vmask_7[ggg.ci];
1847 #endif
1848   if (gtab_phrase_on_())
1849 	gtab_scan_pre_select(TRUE);
1850 
1851   while ((CONVT2(cur_inmd, ggg.S1) & vmaskci) != ggg.kval &&
1852           CONVT2(cur_inmd, ggg.S1) < ggg.kval &&  ggg.S1<oE1)
1853     ggg.S1++;
1854 
1855   ggg.pg_idx=ggg.last_idx=ggg.S1;
1856 
1857 
1858 #if 0
1859   dbg("MaxPress:%d vmaskci:%llx kval:%llx ggg.ci:%d  !=%d  S1:%d  CONV:%lx\n", cur_inmd->MaxPress,
1860   vmaskci, ggg.kval, ggg.ci, ((CONVT2(cur_inmd, ggg.S1) & vmaskci)!=ggg.kval), ggg.S1, CONVT2(cur_inmd, ggg.S1));
1861 #endif
1862 
1863   if ((CONVT2(cur_inmd, ggg.S1) & vmaskci)!=ggg.kval || (ggg.wild_mode && ggg.defselN) ||
1864                     (ggg.spc_pressed && ggg.defselN && (pselkey && (pendkey || ggg.spc_pressed)) ) ) {
1865 YYYY:
1866 
1867     if ((pselkey || ggg.wild_mode) && ggg.defselN) {
1868       int vv = pselkey - cur_inmd->selkey;
1869 
1870       if ((_gtab_space_auto_first & GTAB_space_auto_first_any) && !ggg.wild_mode
1871           && ggg.exa_match && (!cur_inmd->use_quick || ggg.ci!=2))
1872         vv++;
1873 
1874       if (vv<0)
1875         vv=9;
1876 
1877       if (seltab[vv][0]) {
1878         if (gtab_phrase_on_() && poo.same_pho_query_state != SAME_PHO_QUERY_gtab_input)
1879           insert_gbuf_cursor1_cond(seltab[vv], ggg.kval, ggg.exa_match);
1880         else {
1881 		  flush_en();
1882           putstr_inp(seltab[vv]);
1883         }
1884         return 1;
1885       }
1886     }
1887 
1888     if (pselkey && !ggg.defselN)
1889       return 0;
1890 
1891 #if WIN32
1892   if (test_mode)
1893     return 1;
1894 #endif
1895 
1896 	invalid_key_in();
1897     return 1;
1898   }
1899 
1900 refill:
1901 
1902 #if WIN32
1903   if (test_mode)
1904     return 1;
1905 #endif
1906 
1907   j=ggg.S1;
1908   while(CONVT2(cur_inmd, j)==ggg.kval && j<oE1)
1909     j++;
1910 
1911   ggg.E1 = j;
1912   ggg.total_matchN = ggg.E1 - ggg.S1;
1913   ggg.pg_idx = ggg.S1;
1914 
1915   ggg.more_pg = 0;
1916   if (ggg.total_matchN > page_len()) {
1917     if ((_gtab_space_auto_first & GTAB_space_auto_first_any) || ggg.spc_pressed || pendkey ||
1918       ggg.ci==cur_inmd->MaxPress && (_gtab_space_auto_first & GTAB_space_auto_first_full))
1919       ggg.more_pg = 1;
1920   }
1921 
1922   if (ggg.ci < cur_inmd->MaxPress && !ggg.spc_pressed && !pendkey && !ggg.more_pg) {
1923     j = ggg.S1;
1924     ggg.exa_match=0;
1925     clr_seltab();
1926     int match_cnt=0;
1927 
1928     while (CONVT2(cur_inmd, j)==ggg.kval && ggg.exa_match <= page_len()) {
1929       seltab_phrase[ggg.exa_match] = load_seltab(j, ggg.exa_match);
1930       match_cnt++;
1931       ggg.exa_match++;
1932       j++;
1933     }
1934 
1935     ggg.defselN=ggg.exa_match;
1936     dbg("--- ggg.exa_match %d\n", ggg.exa_match);
1937 
1938     if (ggg.defselN > page_len())
1939       ggg.defselN--;
1940 
1941     int shiftb=(KEY_N - 1 -ggg.ci) * KeyBits;
1942 
1943 //    if (gtab_disp_partial_match_on)
1944     while((CONVT2(cur_inmd, j) & vmaskci)==ggg.kval && j<oE1) {
1945       int fff=cur_inmd->keycol[(CONVT2(cur_inmd, j)>>shiftb) & cur_inmd->kmask];
1946       u_char *tbl_ch = tblch(j);
1947 
1948       if (gtab_disp_partial_match_on() && (!seltab[fff][0] || seltab_phrase[fff] ||
1949            (bchcmp(seltab[fff], tbl_ch)>0 && fff > ggg.exa_match))) {
1950 
1951         seltab_phrase[fff] = load_seltab(j, fff);
1952         ggg.defselN++;
1953       }
1954 
1955       match_cnt++;
1956 #if 0
1957       dbg("jj %d", fff); utf8_putchar(seltab[fff]); dbg("\n");
1958 #endif
1959       j++;
1960     }
1961 
1962 #if 1
1963 	j=ggg.S1;
1964 	if (gtab_disp_partial_match_on())
1965     while((CONVT2(cur_inmd, j) & vmaskci)==ggg.kval && j<oE1) {
1966 	  char jstr[512];
1967 	  tblidx_to_str(j, jstr);
1968 
1969 	  int fff;
1970 	  for(fff=0;fff<page_len();fff++)
1971 		 if (!strcmp(seltab[fff], jstr))
1972 			goto nextj;
1973 
1974 	  for(fff=0;fff<page_len();fff++) {
1975          if (!seltab[fff][0]) {
1976            seltab_phrase[fff] = load_seltab(j, fff);
1977            ggg.defselN++;
1978            break;
1979 		 }
1980 	  }
1981 
1982       match_cnt++;
1983 #if 0
1984       dbg("jj %d", fff); utf8_putchar(seltab[fff]); dbg("\n");
1985 #endif
1986 nextj:
1987       j++;
1988     }
1989 #endif
1990 
1991 	dbg("gtab_unique_auto_send_on %d\n", gtab_unique_auto_send_on());
1992 
1993     if (gtab_unique_auto_send_on()) {
1994       char *first_str=NULL;
1995       for(i=0; i < page_len(); i++) {
1996         if (!seltab[i][0])
1997           continue;
1998         if (!first_str)
1999           first_str = seltab[i];
2000       }
2001 
2002 	  dbg("match_cnt %d\n", match_cnt);
2003 
2004       if (match_cnt==1 && first_str) {
2005         if (gtab_phrase_on_() && poo.same_pho_query_state != SAME_PHO_QUERY_gtab_input)
2006           insert_gbuf_nokey(first_str);
2007         else {
2008 		  flush_en();
2009           putstr_inp(first_str);
2010         }
2011         return 1;
2012       }
2013     }
2014   } else {
2015     dbg("more %d %d  skip_end:%d\n", ggg.more_pg,  ggg.total_matchN, cur_inmd->flag&FLAG_PHRASE_AUTO_SKIP_ENDKEY);
2016 next_pg:
2017     ggg.defselN=0;
2018     clr_seltab();
2019     if (pendkey && (!(cur_inmd->flag&FLAG_PHRASE_AUTO_SKIP_ENDKEY) || !gtab_phrase_on_() || ggg.ci==1)) {
2020 //      dbg("spc_pressed = 1\n");
2021       ggg.spc_pressed = 1;
2022     }
2023 
2024     if (ggg.ci==cur_inmd->MaxPress)
2025       ggg.last_full=1;
2026     int full_send = gtab_press_full_auto_send_on() && ggg.last_full;
2027 
2028 //    dbg("flag %d\n",!(pendkey && (cur_inmd->flag&FLAG_PHRASE_AUTO_SKIP_ENDKEY)));
2029     if (gtab_phrase_on_() && !(pendkey && (cur_inmd->flag&FLAG_PHRASE_AUTO_SKIP_ENDKEY))
2030         && poo.same_pho_query_state != SAME_PHO_QUERY_gtab_input &&
2031         (ggg.spc_pressed||full_send)) {
2032       j = ggg.S1;
2033       int selN=0;
2034       char **sel = NULL;
2035 
2036 //     dbg("kkkkkkkkkkk");
2037       while(j<ggg.E1 && CONVT2(cur_inmd, j)==ggg.kval && selN < 255) {
2038         sel = trealloc(sel, char *, selN+1);
2039         sel[selN++] = load_tblidx(j);
2040         j++;
2041       }
2042       if (!selN) {
2043 		  invalid_key_in();
2044 		  return 1;
2045 	  }
2046       insert_gbuf_cursor(sel, selN, ggg.kval, FALSE);
2047       gtab_scan_pre_select(FALSE);
2048       clear_after_put();
2049       return 1;
2050     } else {
2051       j = ggg.pg_idx;
2052 
2053 //      dbg("jjjjjjjjjjjjjjjjjj\n");
2054       while(j<ggg.E1 && CONVT2(cur_inmd, j)==ggg.kval && ggg.defselN < page_len()) {
2055         load_seltab(j, ggg.defselN);
2056 
2057         j++; ggg.defselN++;
2058 
2059         if (ggg.ci == cur_inmd->MaxPress || ggg.spc_pressed) {
2060           ggg.sel1st_i=0;
2061 //          dbg("ggg.sel1st_i %d %d %d\n", ggg.ci, cur_inmd->MaxPress, ggg.spc_pressed);
2062         }
2063       }
2064     }
2065 
2066     ggg.exa_match = ggg.defselN;
2067 //    dbg("ggg.defselN %d\n", ggg.defselN);
2068 
2069 
2070     if (ggg.defselN==1 && !ggg.more_pg) {
2071       if (ggg.spc_pressed || full_send || gtab_unique_auto_send_on()) {
2072         if (gtab_phrase_on_() && poo.same_pho_query_state != SAME_PHO_QUERY_gtab_input)
2073           insert_gbuf_cursor1_cond(seltab[0], ggg.kval, ggg.exa_match);
2074         else {
2075 		  flush_en();
2076           putstr_inp(seltab[0]);
2077         }
2078         return 1;
2079       }
2080     } else
2081     if (!ggg.defselN) {
2082       bell_err();
2083 //      ggg.spc_pressed=0;
2084 //      if (gtab_invalid_key_in)
2085       {
2086         ggg.invalid_spc = TRUE;
2087 //        return TRUE;
2088       }
2089       return TRUE;
2090     } else
2091     if (!ggg.more_pg) {
2092       if (gtab_dup_select_bell && (gtab_disp_partial_match_on() || gtab_pre_select_or_partial_on())) {
2093         if (ggg.spc_pressed || gtab_full_space_auto_first || ggg.last_full && gtab_press_full_auto_send_on())
2094           bell();
2095       }
2096     }
2097   }
2098 
2099 Disp_opt:
2100 #if WIN32
2101   if (test_mode)
2102     return 1;
2103 #endif
2104   if (gtab_disp_partial_match_on() || gtab_pre_select_or_partial_on() || ((ggg.exa_match > 1 || ggg.more_pg) &&
2105     (ggg.spc_pressed || gtab_press_full_auto_send_on() ||
2106     (ggg.ci==cur_inmd->MaxPress && (_gtab_space_auto_first & GTAB_space_auto_first_full))) ) ) {
2107        disp_selection(phrase_selected);
2108   }
2109 
2110   if (gtab_auto_space) {
2111 	  if (ggg.ci && seltab[0][0])
2112 		add_timeout_auto_space();
2113 	  else
2114 		clear_handle_timeout_auto_space();
2115   }
2116 
2117   return 1;
2118 }
2119 
2120 #if WIN32
2121 static GTAB_ST temp_st;
2122 void pho_save_gst(), pho_restore_gst();
2123 // static GEDIT *gbuf_save;
2124 static char **seltab_save;
2125 
gtab_save_gst()2126 void gtab_save_gst()
2127 {
2128   if (seltab) {
2129 	init_seltab(&seltab_save);
2130 	for(int i=0; i < MAX_SELKEY; i++)
2131 		strcpy(seltab_save[i], seltab[i]);
2132   }
2133 
2134   pho_save_gst();
2135   temp_st = ggg;
2136 }
2137 
gtab_restore_gst()2138 void gtab_restore_gst()
2139 {
2140   if (seltab) {
2141 	for(int i=0; i < MAX_SELKEY; i++)
2142 	    strcpy(seltab[i], seltab_save[i]);
2143   }
2144 
2145   pho_restore_gst();
2146   ggg = temp_st;
2147 }
2148 #endif
2149