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(®, 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(®, 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(®, 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(®);
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