1
/* Copyright (C) 2004-2011 Edward Der-Hua Liu, Hsin-Chu, Taiwan
3
* This library is free software; you can redistribute it and/or
4
* modify it under the terms of the GNU Lesser General Public
5
* License as published by the Free Software Foundation; either
6
* version 2.1 of the License, or (at your option) any later version.
8
* This library is distributed in the hope that it will be useful,
9
* but WITHOUT ANY WARRANTY; without even the implied warranty of
10
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11
* Lesser General Public License for more details.
13
* You should have received a copy of the GNU Lesser General Public
14
* License along with this library; if not, write to the Free Software
15
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23
#include "hime-conf.h"
24
#include "hime-endian.h"
29
extern gboolean test_mode;
30
gboolean gtab_phrase_on();
31
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();
32
void init_seltab(char ***p);
34
extern gint64 key_press_time, key_press_time_ctrl;
36
extern GtkWidget *gwin_gtab;
37
void hide_gtab_pre_sel();
38
void gtab_scan_pre_select(gboolean);
40
extern GTAB_space_pressed_E _gtab_space_auto_first;
41
extern char *TableDir;
43
extern INMD *cur_inmd;
46
extern char str_key_codes[128];
47
void disp_pho_sel(char *s);
49
#define gtab_full_space_auto_first (_gtab_space_auto_first & (GTAB_space_auto_first_any|GTAB_space_auto_first_full))
50
#define AUTO_SELECT_BY_PHRASE (gtab_phrase_on())
52
gboolean use_tsin_sel_win()
54
return gtab_vertical_select_on() && gtab_phrase_pre_select;
58
static gboolean gtab_pre_select_or_partial_on()
60
return gtab_pre_select_on() || (cur_inmd->flag&FLAG_GTAB_DISP_PARTIAL_MATCH)!=0;
63
gboolean same_query_show_pho_win()
65
return poo.same_pho_query_state != SAME_PHO_QUERY_none;
68
gboolean hime_edit_display_ap_only();
69
gboolean gtab_has_input()
73
for(i=0; i < MAX_TAB_KEY_NUM64_6; i++)
77
if (same_query_show_pho_win())
80
if (ggg.gtab_buf_select)
83
if (ggg.gbufN && !hime_edit_display_ap_only())
89
#define tblch(i) tblch2(cur_inmd, i)
91
int load_phr_ch(INMD *inm, u_char *ch, char *tt)
93
int phrno =((int)(ch[0])<<16)|((int)ch[1]<<8)|ch[2];
94
int ofs = inm->phridx[phrno], ofs1 = inm->phridx[phrno+1];
96
// dbg("load_phr j:%d %d %d %d\n", j, phrno, ofs, ofs1);
99
if (len > MAX_CIN_PHR || len <= 0) {
100
dbg("phrae error %d\n", len);
105
memcpy(tt, inm->phrbuf + ofs, len);
110
static void load_phr(int j, char *tt)
112
u_char *ch = tblch(j);
114
load_phr_ch(cur_inmd, ch, tt);
117
static int qcmp_strlen(const void *aa, const void *bb)
119
char *a = *((char **)aa), *b = *((char **)bb);
121
return strlen(a) - strlen(b);
124
void set_key_codes_label(char *s, int better);
125
void set_page_label(char *s);
127
static void clear_page_label()
132
int gtab_key2name(INMD *tinmd, u_int64_t key, char *t, int *rtlen);
135
int ch_to_gtab_keys(INMD *tinmd, char *ch, u_int64_t keys[])
137
int n = utf8_str_N(ch);
138
gboolean phrase = n > 1 || !(ch[0] & 0x80);
140
for(i=0; i < tinmd->DefChars; i++) {
141
char *chi = (char *)tblch2(tinmd, i);
147
load_phr_ch(tinmd, (u_char *)chi, tstr);
148
if (strcmp(tstr, ch))
151
if (!(chi[0] & 0x80))
153
if (!utf8_eq(chi, ch))
157
u_int64_t key = CONVT2(tinmd, i);
163
void lookup_gtabn(char *ch, char *out)
168
INMD *tinmd = &inmd[default_input_method];
170
if (!tinmd->DefChars)
176
gboolean need_disp = FALSE;
188
int keysN = ch_to_gtab_keys(tinmd, ch, keys);
191
for(i=0; i < keysN; i++) {
193
char t[CH_SZ * 10 + 1];
195
klen = gtab_key2name(tinmd, keys[i], t, &tlen);
202
tbuf[tbufN] = strdup(t);
207
qsort(tbuf, tbufN, sizeof(char *), qcmp_strlen);
210
for(i=0; i < tbufN; i++) {
211
#define MAX_DISP_MATCH 40
212
if (strlen(out) < MAX_DISP_MATCH) {
213
strcat(out, tbuf[i]);
221
if (!out[0] || !need_disp)
225
set_key_codes_label(out, ggg.ci > min_klen);
226
void set_key_codes_label_pho(char *s);
227
set_key_codes_label_pho(out);
230
void lookup_gtab(char *ch)
234
lookup_gtabn(tt, NULL);
238
void lookup_gtab_out(char *ch, char *out)
242
lookup_gtabn(tt, out);
249
for(i=0; i < inmdN; i++) {
250
INMD *inp = &inmd[i];
251
free(inp->tbl); inp->tbl = NULL;
252
free(inp->tbl64); inp->tbl64 = NULL;
253
free(inp->phridx); inp->phridx = NULL;
254
free(inp->phrbuf); inp->phrbuf = NULL;
255
free(inp->keyname_lookup); inp->keyname_lookup = NULL;
262
char *b1_cat(char *s, char c)
272
char *bch_cat(char *s, char *ch)
275
int len = u8cpy(t, ch);
282
void minimize_win_gtab();
283
void disp_gtab_sel(char *s);
289
// hide_gtab_pre_sel();
293
void disp_gtab(char *);
294
void clear_gtab_input_error_color();
296
static void clr_seltab()
302
for(i=0; i < MAX_SELKEY; i++)
306
void clear_gtab_in_area(), hide_win_gtab();
309
bzero(ggg.inch,sizeof(ggg.inch));
311
ggg.total_matchN=ggg.pg_idx=ggg.more_pg=ggg.wild_mode=ggg.wild_page=ggg.last_idx=ggg.defselN=ggg.exa_match=
312
ggg.spc_pressed=ggg.ci=ggg.invalid_spc=0;
314
ggg.sel1st_i=MAX_SELKEY-1;
316
clear_gtab_in_area();
319
if (hime_pop_up_win && !gtab_has_input() && !tss.pre_selN)
322
clear_gtab_input_error_color();
324
// hide_gtab_pre_sel();
330
void close_gtab_pho_win()
334
if (same_query_show_pho_win()) {
335
poo.same_pho_query_state = SAME_PHO_QUERY_none;
337
if (hime_pop_up_win && (str_key_codes[0]!='\0'))
342
void gtab_disp_empty(char *tt, int N);
343
extern int win_gtab_max_key_press;
345
static void DispInArea()
349
// hide_gtab_pre_sel();
351
// dbg("sel1st:%d\n", ggg.sel1st_i);
352
if (hime_display_on_the_spot_key()) {
353
if (gwin_gtab && GTK_WIDGET_VISIBLE(gwin_gtab) && poo.same_pho_query_state == SAME_PHO_QUERY_none)
361
if (win_gtab_max_key_press < ggg.ci)
362
win_gtab_max_key_press = ggg.ci;
364
for(i=0;i<ggg.ci;i++) {
365
char *p=(char *)&cur_inmd->keyname[ggg.inch[i] * CH_SZ];
368
len=utf8cpy(tt+ttN, p);
379
gtab_disp_empty(tt, win_gtab_max_key_press - i);
385
int get_DispInArea_str(char *out)
388
for(i=0;i<ggg.ci;i++) {
389
char *p = (char *)&cur_inmd->keyname[ggg.inch[i] * CH_SZ];
391
outN+=u8cpy(out+outN, p);
394
memcpy(out+outN, p, len);
406
// dbg("get_DispInArea_str\n", out);
411
void set_gtab_input_method_name(char *s);
412
void case_inverse(KeySym *xkey, int shift_m);
414
extern unich_t *fullchar[];
416
void start_gtab_pho_query(char *utf8);
418
void clear_after_put()
424
void add_to_tsin_buf_str(char *str);
425
gboolean init_in_method(int in_no);
428
void hide_row2_if_necessary()
430
if ((!ggg.wild_mode && gtab_hide_row2) || !gtab_disp_key_codes) {
431
set_key_codes_label(NULL, 0);
435
static void putstr_inp(char *p)
439
// dbg("gtab_hide_row2 %d\n", gtab_hide_row2);
440
hide_row2_if_necessary();
444
int to_tsin = (cur_inmd->flag & FLAG_GTAB_SYM_KBM) && inmd[default_input_method].method_type==method_type_TSIN && tss.c_len;
446
if (utf8_str_N(p) > 1 || !(p[0]&128)) {
447
if ((gtab_disp_key_codes && !gtab_hide_row2) || ggg.wild_mode)
448
lookup_gtabn(p, NULL);
450
add_to_tsin_buf_str(p);
456
if (poo.same_pho_query_state == SAME_PHO_QUERY_gtab_input) {
457
poo.same_pho_query_state = SAME_PHO_QUERY_pho_select;
458
start_gtab_pho_query(p);
465
if ((gtab_disp_key_codes && !gtab_hide_row2) || ggg.wild_mode)
469
add_to_tsin_buf_str(p);
476
if ((cur_inmd->flag & FLAG_GTAB_SYM_KBM)) {
477
extern int win_kbm_inited, b_show_win_kbm;
478
init_in_method(default_input_method);
479
if (win_kbm_inited && !b_show_win_kbm)
485
#define swap(a,b) { tt=a; a=b; b=tt; }
487
static u_int vmask[]=
490
(0x3f<<24)|(0x3f<<18),
491
(0x3f<<24)|(0x3f<<18)|(0x3f<<12),
492
(0x3f<<24)|(0x3f<<18)|(0x3f<<12)|(0x3f<<6),
493
(0x3f<<24)|(0x3f<<18)|(0x3f<<12)|(0x3f<<6)|0x3f
497
static u_int vmask_7[]=
500
(0x7f<<21)|(0x7f<<14),
501
(0x7f<<21)|(0x7f<<14)|(0x7f<<7),
502
(0x7f<<21)|(0x7f<<14)|(0x7f<<7)|0x7f,
505
#define KKK ((u_int64_t)0x3f)
508
static u_int64_t vmask64[]=
512
(KKK<<54)|(KKK<<48)|(KKK<<42),
513
(KKK<<54)|(KKK<<48)|(KKK<<42)|(KKK<<36),
514
(KKK<<54)|(KKK<<48)|(KKK<<42)|(KKK<<36)|(KKK<<30),
515
(KKK<<54)|(KKK<<48)|(KKK<<42)|(KKK<<36)|(KKK<<30)|(KKK<<24),
516
(KKK<<54)|(KKK<<48)|(KKK<<42)|(KKK<<36)|(KKK<<30)|(KKK<<24)|(KKK<<18),
517
(KKK<<54)|(KKK<<48)|(KKK<<42)|(KKK<<36)|(KKK<<30)|(KKK<<24)|(KKK<<18)|(KKK<<12),
518
(KKK<<54)|(KKK<<48)|(KKK<<42)|(KKK<<36)|(KKK<<30)|(KKK<<24)|(KKK<<18)|(KKK<<12)|(KKK<<6),
519
(KKK<<54)|(KKK<<48)|(KKK<<42)|(KKK<<36)|(KKK<<30)|(KKK<<24)|(KKK<<18)|(KKK<<12)|(KKK<<6)|KKK
523
#define KKK7 ((u_int64_t)0x7f)
525
static u_int64_t vmask64_7[]=
528
(KKK7<<56)|(KKK7<<49),
529
(KKK7<<56)|(KKK7<<49)|(KKK7<<42),
530
(KKK7<<56)|(KKK7<<49)|(KKK7<<42)|(KKK7<<35),
531
(KKK7<<56)|(KKK7<<49)|(KKK7<<42)|(KKK7<<35)|(KKK7<<28),
532
(KKK7<<56)|(KKK7<<49)|(KKK7<<42)|(KKK7<<35)|(KKK7<<28)|(KKK7<<21),
533
(KKK7<<56)|(KKK7<<49)|(KKK7<<42)|(KKK7<<35)|(KKK7<<28)|(KKK7<<21)|(KKK7<<14),
534
(KKK7<<56)|(KKK7<<49)|(KKK7<<42)|(KKK7<<35)|(KKK7<<28)|(KKK7<<21)|(KKK7<<14)|(KKK7<<7),
535
(KKK7<<56)|(KKK7<<49)|(KKK7<<42)|(KKK7<<35)|(KKK7<<28)|(KKK7<<21)|(KKK7<<14)|(KKK7<<7)|KKK7,
539
#define KEY_N (cur_inmd->max_keyN)
541
static gboolean load_seltab(int tblidx, int seltabidx)
543
u_char *tbl_ch = tblch(tblidx);
544
if (tbl_ch[0] < 0x80) {
545
load_phr(tblidx, seltab[seltabidx]);
549
int len = u8cpy(seltab[seltabidx], (char *)tbl_ch);
550
seltab[seltabidx][len] = 0;
556
static char* load_tblidx(int tblidx)
558
char tt[MAX_CIN_PHR];
559
u_char *tbl_ch = tblch(tblidx);
560
if (tbl_ch[0] < 0x80) {
561
load_phr(tblidx, tt);
563
int len = u8cpy(tt, (char *)tbl_ch);
571
void set_gtab_input_error_color();
572
static void bell_err()
578
set_gtab_input_error_color();
581
gboolean cmp_inmd_idx(regex_t *reg, int idx)
583
u_int64_t kk=CONVT2(cur_inmd, idx);
590
for(i=0; i < KEY_N; i++) {
591
char c = (kk >> (LAST_K_bitN - i*cur_inmd->keybits)) & cur_inmd->kmask;
600
return regexec(reg, ts, 0, 0, 0);
605
return (_gtab_space_auto_first & GTAB_space_auto_first_any) ?
606
cur_inmd->M_DUP_SEL+1:cur_inmd->M_DUP_SEL;
609
static void page_no_str(char tstr[])
611
if (ggg.wild_mode || ggg.gtab_buf_select) {
612
int pgN = (ggg.total_matchN + cur_inmd->M_DUP_SEL - 1) / cur_inmd->M_DUP_SEL;
616
int pg = ggg.gtab_buf_select ? ggg.pg_idx : ggg.wild_page;
617
sprintf(tstr, "%d/%d", pg /cur_inmd->M_DUP_SEL + 1, pgN);
619
int pgN = (ggg.E1 - ggg.S1 + page_len() - 1) /page_len();
624
sprintf(tstr, "%d/%d", (ggg.pg_idx - ggg.S1)/page_len()+1, pgN);
628
char *htmlspecialchars(char *s, char out[])
633
} chs[]= {{'>',"gt"}, {'<',"lt"}, {'&',"amp"}
638
int chsN=sizeof(chs)/sizeof(chs[0]);
644
for(i=0; i<chsN; i++)
648
memcpy(&out[outn],s, sz);
654
int len=strlen(chs[i].str);
655
memcpy(&out[outn], chs[i].str, len);
667
void disp_selection0(gboolean phrase_selected, gboolean force_disp)
673
if (!gtab_vertical_select_on()) {
675
set_page_label(pgstr);
682
char uu[MAX_CIN_PHR];
685
if (!ggg.wild_mode && ggg.exa_match && (_gtab_space_auto_first & GTAB_space_auto_first_any)) {
686
strcat(tt, htmlspecialchars(seltab[0], uu));
687
if (gtab_vertical_select_on())
698
for(max_i = cur_inmd->M_DUP_SEL + ofs-1; max_i>=0; max_i--)
699
if (seltab[max_i][0])
702
for(i=ofs; i<= max_i; i++) {
704
char selback[MAX_CIN_PHR+16];
705
htmlspecialchars(seltab[i], selback);
707
utf8cpy(uu, &cur_inmd->selkey[i - ofs]);
710
sprintf(www, "<span foreground=\"%s\">%s</span>", hime_sel_key_color, htmlspecialchars(uu, vvv));
713
if (gtab_vertical_select_on())
716
if (phrase_selected && i==ggg.sel1st_i) {
717
strcat(tt, "<span foreground=\"red\">");
718
strcat(strcat(tt, selback), " ");
719
strcat(tt, "</span>");
721
char uu[MAX_CIN_PHR];
723
if (gtab_vertical_select_on()) {
724
utf8cpy_bytes(uu, selback, 120);
729
static char *skip[]={"http://", "ftp://", "https://", NULL};
732
for(j=0; skip[j]; j++)
733
if (!strncmp(seltab[i], skip[j], strlen(skip[j]))) {
738
utf8cpy_bytes(uu, p, 6 * 3);
739
strcat(strcat(tt, uu), " ");
743
if (gtab_vertical_select_on())
746
extern gboolean b_use_full_space;
748
if (!gtab_vertical_select_on() && gtab_disp_partial_match_on()) {
749
if (b_use_full_space)
758
if (gtab_vertical_select_on() && pgstr[0]) {
760
sprintf(tstr2, "(%s)", pgstr);
764
int len = strlen(tt);
765
if (len && tt[len-1] == '\n')
768
if (gtab_pre_select_or_partial_on() || ggg.wild_mode || ggg.spc_pressed || ggg.last_full || force_disp) {
774
void disp_selection(gboolean phrase_selected)
776
disp_selection0(phrase_selected, FALSE);
787
/* printf("wild %d %d %d %d\n", ggg.inch[0], ggg.inch[1], ggg.inch[2], ggg.inch[3]); */
792
regstr[regstrN++]=' ';
794
for(i=0; i < KEY_N; i++) {
797
if (ggg.inch[i] == cur_inmd->WILD_STAR) {
798
regstr[regstrN++]='.';
799
regstr[regstrN++]='*';
801
if (ggg.inch[i] == cur_inmd->WILD_QUES) {
802
regstr[regstrN++]='.';
804
char c = ggg.inch[i] + '0'; // start from '0'
805
if (strchr("*.\\()[]", c))
806
regstr[regstrN++] = '\\';
811
regstr[regstrN++]=' ';
814
// dbg("regstr %s\n", regstr);
816
if (regcomp(®, regstr, 0)) {
817
dbg("regcomp failed\n");
821
for(t=0; t< cur_inmd->DefChars && ggg.defselN < cur_inmd->M_DUP_SEL; t++) {
822
if (cmp_inmd_idx(®, t))
825
if (wild_ofs >= ggg.wild_page) {
826
load_seltab(t, ggg.defselN);
838
if (!ggg.wild_page) {
839
ggg.total_matchN = 0;
841
for(t=0; t< cur_inmd->DefChars; t++)
842
if (!cmp_inmd_idx(®, t))
847
if (ggg.total_matchN > cur_inmd->M_DUP_SEL)
851
disp_selection(FALSE);
854
static char *ptr_selkey(KeySym key)
856
if (key>= XK_KP_0 && key<= XK_KP_9)
858
return strchr(cur_inmd->selkey, key);
862
void init_gtab_pho_query_win();
863
int feedkey_pho(KeySym xkey, int state);
865
void set_gtab_target_displayed()
867
close_gtab_pho_win();
870
gboolean is_gtab_query_mode()
872
return poo.same_pho_query_state == SAME_PHO_QUERY_pho_select;
875
void reset_gtab_all()
885
static gboolean has_wild_card()
889
for(i=0; i < cur_inmd->MaxPress; i++)
890
if (ggg.inch[i]>= cur_inmd->WILD_QUES) {
897
static void proc_wild_disp()
905
gboolean full_char_proc(KeySym keysym);
906
void insert_gbuf_cursor_char(char ch);
907
gboolean gtab_pre_select_shift(KeySym key, int kbstate);
909
gboolean shift_char_proc(KeySym key, int kbstate)
915
if (kbstate & LockMask) {
916
if (key >= 'a' && key <= 'z')
919
if (key >= 'A' && key <= 'Z')
924
if (gtab_pre_select_shift(key, kbstate))
927
if (current_CS->b_half_full_char)
928
return full_char_proc(key);
931
insert_gbuf_cursor_char(key);
938
extern GtkWidget *gwin_pho;
939
gboolean feed_phrase(KeySym ksym, int state);
940
int gtab_buf_backspace();
941
gboolean output_gbuf();
942
int show_buf_select();
943
void gbuf_next_pg(), gbuf_prev_pg();
944
void show_win_gtab();
945
int gbuf_cursor_left();
946
int gbuf_cursor_right();
947
int gbuf_cursor_home();
948
int gbuf_cursor_end();
949
int gtab_buf_delete();
950
void set_gbuf_c_sel(int v);
951
void set_gtab_user_head();
952
KeySym keypad_proc(KeySym xkey);
953
void save_gtab_buf_phrase(KeySym key);
954
gboolean save_gtab_buf_shift_enter();
955
gboolean win_sym_page_up(), win_sym_page_down();
957
gboolean gtab_pre_select_idx(int c);
958
void save_CS_current_to_temp();
959
void tsin_set_eng_ch(int nmod);
961
gboolean feedkey_gtab(KeySym key, int kbstate)
966
gboolean phrase_selected = FALSE;
967
char seltab_phrase[MAX_SELKEY];
968
gboolean is_keypad = FALSE;
969
gboolean shift_m = (kbstate & ShiftMask) > 0;
970
// gboolean ctrl_m = (kbstate & ControlMask) > 0;
971
gboolean capslock_on = (kbstate & LockMask);
972
gboolean is_dayi = !strncmp(cur_inmd->filename, "dayi", 4);
974
bzero(seltab_phrase, sizeof(seltab_phrase));
976
// dbg("uuuuu %x %x shift,ctrl:%d,%d\n", key, kbstate, shift_m, ctrl_m);
981
if ((tsin_chinese_english_toggle_key == TSIN_CHINESE_ENGLISH_TOGGLE_KEY_CapsLock) &&
982
(key == XK_Caps_Lock)){
983
// The CapLock status may be incorrect when XK_Caps_Lock is pressed.
984
gboolean new_tsin_pho_mode = ! gdk_keymap_get_caps_lock_state(gdk_keymap_get_default());
985
if (current_CS->tsin_pho_mode != new_tsin_pho_mode) {
986
current_CS->tsin_pho_mode = new_tsin_pho_mode;
987
save_CS_current_to_temp();
988
tsin_set_eng_ch(new_tsin_pho_mode);
992
if ((kbstate & (Mod1Mask|Mod4Mask|Mod5Mask|ControlMask))==ControlMask
993
&& key>='1' && key<='9' && ggg.gbufN) {
994
save_gtab_buf_phrase(key);
998
if (ggg.gbufN && key==XK_Tab)
1001
if ((key==XK_Shift_L||key==XK_Shift_R) && !key_press_time) {
1002
key_press_time = current_time();
1003
key_press_time_ctrl = 0;
1005
if ((key==XK_Control_L||key==XK_Control_R) && !key_press_time_ctrl && tss.pre_selN) {
1006
key_press_time_ctrl = current_time();
1009
key_press_time_ctrl = 0;
1013
if (kbstate & (Mod1Mask|Mod4Mask|Mod5Mask|ControlMask)) {
1017
if (poo.same_pho_query_state == SAME_PHO_QUERY_pho_select)
1018
return feedkey_pho(key, 0);
1020
if (poo.same_pho_query_state == SAME_PHO_QUERY_none && gwin_pho &&
1021
GTK_WIDGET_VISIBLE(gwin_pho))
1024
if (!tsin_pho_mode()) {
1025
if (key < 0x20 || key>=0x7f)
1028
if (capslock_on && hime_capslock_lower)
1029
case_inverse((KeySym *)&key, shift_m);
1032
insert_gbuf_cursor_char(key);
1041
lcase = tolower(key);
1043
ucase = toupper(key);
1044
if (key < 127 && cur_inmd->keymap[key]) {
1045
if (key < 'A' || key > 'z' || (key > 'Z' && key < 'a') )
1047
if (cur_inmd->keymap[lcase] != cur_inmd->keymap[ucase])
1054
if (shift_m && !strchr(cur_inmd->selkey, key) && !ggg.more_pg && key>=' ' && key < 0x7e &&
1055
key!='*' && (key!='?' || (gtab_shift_phrase_key && !ggg.ci))) {
1056
if (gtab_shift_phrase_key) {
1057
if (tss.pre_selN && shift_char_proc(key, kbstate))
1059
if (feed_phrase(key, kbstate))
1062
if (!cur_inmd->keymap[key] || (lcase != ucase &&
1063
cur_inmd->keymap[lcase]==cur_inmd->keymap[ucase]))
1064
return shift_char_proc(key, kbstate);
1075
ggg.sel1st_i=MAX_SELKEY-1;
1076
clear_gtab_input_error_color();
1077
hide_gtab_pre_sel();
1080
if (AUTO_SELECT_BY_PHRASE)
1081
return gtab_buf_backspace();
1087
ggg.inch[--ggg.ci]=0;
1089
if (has_wild_card()) {
1096
ggg.invalid_spc = FALSE;
1097
if (ggg.ci==1 && cur_inmd->use_quick) {
1100
for(i=0;i<cur_inmd->M_DUP_SEL;i++)
1101
utf8cpy(seltab[i], (char *)cur_inmd->qkeys->quick1[ggg.inch[0]-1][i]);
1103
ggg.defselN=cur_inmd->M_DUP_SEL;
1107
if (ggg.ci==2 && cur_inmd->use_quick) {
1110
for(i=0;i<cur_inmd->M_DUP_SEL;i++)
1111
utf8cpy(seltab[i], (char *)cur_inmd->qkeys->quick2[ggg.inch[0]-1][ggg.inch[1]-1][i]);
1113
ggg.defselN=cur_inmd->M_DUP_SEL;
1121
if (AUTO_SELECT_BY_PHRASE) {
1122
hide_gtab_pre_sel();
1124
return save_gtab_buf_shift_enter();
1126
return output_gbuf();
1131
if (gtab_has_input())
1136
if (AUTO_SELECT_BY_PHRASE)
1137
return show_buf_select();
1141
hide_gtab_pre_sel();
1142
if (ggg.gtab_buf_select) {
1143
ggg.gtab_buf_select = 0;
1146
if (hime_pop_up_win && !gtab_has_input())
1151
close_gtab_pho_win();
1157
set_gtab_user_head();
1165
case XK_KP_Subtract:
1166
if (ggg.wild_mode) {
1167
if (ggg.wild_page >= cur_inmd->M_DUP_SEL) ggg.wild_page-=cur_inmd->M_DUP_SEL;
1172
if (ggg.gtab_buf_select) {
1177
ggg.pg_idx -= page_len();
1178
if (ggg.pg_idx < ggg.S1)
1179
ggg.pg_idx = ggg.S1;
1184
if (key==XK_KP_Subtract)
1187
return win_sym_page_up();
1192
if (ggg.gtab_buf_select) {
1197
// dbg("more...\n");
1198
ggg.pg_idx += page_len();
1199
if (ggg.pg_idx >=ggg.E1)
1200
ggg.pg_idx = ggg.S1;
1205
if (win_sym_page_down())
1207
if (!ggg.gtab_buf_select && ggg.gbufN && AUTO_SELECT_BY_PHRASE)
1208
return show_buf_select();
1212
hide_gtab_pre_sel();
1214
if (ggg.invalid_spc && gtab_invalid_key_in)
1217
if (!gtab_invalid_key_in && ggg.spc_pressed && ggg.invalid_spc) {
1222
has_wild = has_wild_card();
1224
// 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);
1226
if (ggg.wild_mode) {
1227
// request from tetralet
1228
if (!ggg.wild_page && ggg.total_matchN < cur_inmd->M_DUP_SEL) {
1233
ggg.wild_page += cur_inmd->M_DUP_SEL;
1234
if (ggg.wild_page >= ggg.total_matchN)
1238
ggg.spc_pressed = TRUE;
1241
if (ggg.more_pg && !(_gtab_space_auto_first & GTAB_space_auto_first_any)) {
1242
if (ggg.gtab_buf_select) {
1250
if (current_CS->b_half_full_char)
1251
return full_char_proc(key);
1259
// dbg("iii %d ggg.defselN:%d %d\n", ggg.sel1st_i, ggg.defselN, cur_inmd->M_DUP_SEL);
1260
if (_gtab_space_auto_first == GTAB_space_auto_first_any && seltab[0][0] &&
1261
ggg.sel1st_i==MAX_SELKEY-1) {
1265
if (_gtab_space_auto_first == GTAB_space_auto_first_nofull && ggg.exa_match > 1
1266
&& !AUTO_SELECT_BY_PHRASE && gtab_dup_select_bell)
1269
if (seltab[ggg.sel1st_i][0]) {
1270
// dbg("ggg.last_full %d %d\n", ggg.last_full,ggg.spc_pressed);
1271
if (gtab_full_space_auto_first || ggg.spc_pressed) {
1273
if (AUTO_SELECT_BY_PHRASE && poo.same_pho_query_state != SAME_PHO_QUERY_gtab_input) {
1274
// dbg("ins ggg.kval %x\n", ggg.kval);
1275
insert_gbuf_cursor1_cond(seltab[ggg.sel1st_i], ggg.kval, ggg.exa_match);
1278
putstr_inp(seltab[ggg.sel1st_i]); /* select 1st */
1286
// dbg("spc_pressed=1\n");
1297
if (!gtab_que_wild_card) {
1298
inkey=cur_inmd->keymap[key];
1299
if ((inkey && (inkey!=cur_inmd->WILD_QUES && inkey!=cur_inmd->WILD_STAR)) || ptr_selkey(key))
1301
if (AUTO_SELECT_BY_PHRASE && ggg.gbufN) {
1302
insert_gbuf_cursor_char(key);
1305
if (current_CS->b_half_full_char)
1306
return full_char_proc(key);
1312
if (tss.pre_selN && shift_char_proc(key, kbstate))
1315
if (current_CS->b_half_full_char)
1316
return full_char_proc(key);
1318
inkey=cur_inmd->keymap[key];
1319
if ((inkey && (inkey!=cur_inmd->WILD_STAR && inkey!=cur_inmd->WILD_QUES)) || ptr_selkey(key)) {
1320
// dbg("%d %d\n", inkey, cur_inmd->WILD_STAR);
1323
if (ggg.ci< cur_inmd->MaxPress) {
1324
ggg.inch[ggg.ci++]=inkey;
1327
if (hime_pop_up_win)
1330
ggg.total_matchN = 0;
1339
return gbuf_cursor_left();
1342
return gbuf_cursor_right();
1345
return gbuf_cursor_home();
1348
return gbuf_cursor_end();
1351
return gtab_buf_delete();
1361
if (!cur_inmd->keymap[key]) {
1362
poo.same_pho_query_state = SAME_PHO_QUERY_gtab_input;
1364
disp_gtab_sel(_("輸入要查的同音字,接著在注音視窗選字"));
1365
if (hime_pop_up_win)
1368
init_gtab_pho_query_win();
1375
inkey= cur_inmd->keymap[key];
1379
if (shift_m && !inkey && !tss.ctrl_pre_sel &&
1380
tss.pre_selN && shift_char_proc(key, kbstate))
1383
clear_gtab_input_error_color();
1385
if (ggg.invalid_spc && gtab_invalid_key_in) {
1388
if (key>=XK_KP_0 && key<=XK_KP_9) {
1391
insert_gbuf_cursor_char(key - XK_KP_0 + '0');
1397
key = key - XK_KP_0 + '0';
1404
keypad = keypad_proc(key);
1408
insert_gbuf_cursor_char(keypad);
1414
char *pendkey = strchr(cur_inmd->endkey, key);
1416
pselkey=ptr_selkey(key);
1418
if (!pselkey && (key < 32 || key > 0x7e) && (gtab_full_space_auto_first || ggg.spc_pressed)) {
1419
// dbg("%x %x ggg.sel1st_i:%d '%c'\n", pselkey, key, ggg.sel1st_i, seltab[ggg.sel1st_i][0]);
1420
if (seltab[ggg.sel1st_i][0]) {
1421
if (AUTO_SELECT_BY_PHRASE && poo.same_pho_query_state != SAME_PHO_QUERY_gtab_input)
1422
insert_gbuf_cursor1_cond(seltab[ggg.sel1st_i], ggg.kval, ggg.exa_match);
1424
putstr_inp(seltab[ggg.sel1st_i]); /* select 1st */
1432
// dbg("ggg.spc_pressed %d %d %d is_keypad:%d\n", ggg.spc_pressed, ggg.last_full, cur_inmd->MaxPress, is_keypad);
1434
#if 1 // for dayi, testcase : 6 space keypad6
1435
int vv = pselkey - cur_inmd->selkey;
1436
if (pselkey && tss.pre_selN && !ggg.gtab_buf_select && (tss.ctrl_pre_sel||
1437
((!inkey||ggg.spc_pressed||is_keypad)&&! gtab_disp_partial_match_on() && !gtab_pre_select_on()))) {
1438
if (gtab_pre_select_idx(vv))
1441
if (( (ggg.spc_pressed||ggg.last_full||is_keypad) ||(ggg.wild_mode && (!inkey ||pendkey)) || ggg.gtab_buf_select) && pselkey) {
1442
if ((_gtab_space_auto_first & GTAB_space_auto_first_any) && !ggg.wild_mode)
1448
if (seltab[vv][0]) {
1449
if (AUTO_SELECT_BY_PHRASE && !same_query_show_pho_win()) {
1450
if (ggg.gtab_buf_select && poo.same_pho_query_state != SAME_PHO_QUERY_gtab_input)
1453
insert_gbuf_cursor1_cond(seltab[vv], ggg.kval, ggg.exa_match);
1456
putstr_inp(seltab[vv]);
1459
if (hime_pop_up_win && !gtab_has_input())
1467
// dbg("iii %x sel1st_i:%d auto:%d\n", pselkey, ggg.sel1st_i, AUTO_SELECT_BY_PHRASE);
1468
if (seltab[ggg.sel1st_i][0] && !ggg.wild_mode &&
1469
(gtab_full_space_auto_first||ggg.spc_pressed||ggg.last_full) ) {
1470
if (AUTO_SELECT_BY_PHRASE && poo.same_pho_query_state != SAME_PHO_QUERY_gtab_input)
1471
insert_gbuf_cursor1_cond(seltab[ggg.sel1st_i], ggg.kval, ggg.exa_match);
1473
putstr_inp(seltab[ggg.sel1st_i]); /* select 1st */
1483
// for cj & boshiamy to input digits
1484
if (!ggg.ci && !inkey) {
1485
if (current_CS->b_half_full_char)
1486
return full_char_proc(key);
1488
if (ggg.gbufN && poo.same_pho_query_state != SAME_PHO_QUERY_gtab_input) {
1489
insert_gbuf_cursor_char(key);
1497
if (ggg.wild_mode && inkey>=1 && ggg.ci< cur_inmd->MaxPress) {
1498
ggg.inch[ggg.ci++]=inkey;
1499
if (hime_pop_up_win)
1505
if (inkey>=1 && ggg.ci< cur_inmd->MaxPress) {
1506
ggg.inch[ggg.ci++]=inkey;
1507
hide_gtab_pre_sel();
1509
if (hime_pop_up_win)
1513
if (cur_inmd->use_quick && !pendkey) {
1516
for(i=0;i < cur_inmd->M_DUP_SEL; i++) {
1517
utf8cpy(seltab[i], (char *)&cur_inmd->qkeys->quick1[inkey-1][i]);
1520
ggg.defselN=cur_inmd->M_DUP_SEL;
1524
if (ggg.ci==2 && !pselkey) {
1526
for(i=0;i < cur_inmd->M_DUP_SEL; i++) {
1527
utf8cpy(seltab[i], (char *)&cur_inmd->qkeys->quick2[ggg.inch[0]-1][inkey-1][i]);
1530
ggg.defselN=cur_inmd->M_DUP_SEL;
1536
if (ggg.ci == cur_inmd->MaxPress && !pselkey) {
1543
for(i=0; i < MAX_TAB_KEY_NUM64_6; i++)
1544
if (ggg.inch[i]>=cur_inmd->WILD_QUES) {
1546
if (ggg.ci==cur_inmd->MaxPress) {
1556
if (current_CS->b_half_full_char)
1557
return full_char_proc(key);
1559
if (key>=' ' && key<0x7f && AUTO_SELECT_BY_PHRASE && ggg.gbufN)
1560
insert_gbuf_cursor_char(key);
1579
ggg.invalid_spc = FALSE;
1580
char *pendkey = NULL;
1581
pendkey = strchr(cur_inmd->endkey, key);
1587
for(i=0; i < Max_tab_key_num; i++) {
1588
ggg.kval|= (u_int64_t)ggg.inch[i] << (KeyBits * (Max_tab_key_num - 1 - i));
1593
ggg.S1=ggg.last_idx;
1596
ggg.S1=cur_inmd->idx1[ggg.inch[0]];
1598
// dbg("--------- ch:%d %d val %llx ggg.S1:%d\n", ggg.inch[0], Max_tab_key_num, ggg.kval, ggg.S1);
1601
oE1=cur_inmd->idx1[ggg.inch[0]+1];
1602
if (cur_inmd->keybits==6)
1603
vmaskci = cur_inmd->key64 ? vmask64[ggg.ci]:vmask[ggg.ci];
1605
vmaskci = cur_inmd->key64 ? vmask64_7[ggg.ci]:vmask_7[ggg.ci];
1607
gtab_scan_pre_select(TRUE);
1609
while ((CONVT2(cur_inmd, ggg.S1) & vmaskci) != ggg.kval &&
1610
CONVT2(cur_inmd, ggg.S1) < ggg.kval && ggg.S1<oE1)
1613
ggg.pg_idx=ggg.last_idx=ggg.S1;
1617
dbg("MaxPress:%d vmaskci:%llx kval:%llx ggg.ci:%d !=%d S1:%d kval:%x\n", cur_inmd->MaxPress,
1618
vmaskci, ggg.kval, ggg.ci,
1619
((CONVT2(cur_inmd, ggg.S1) & vmaskci)!=ggg.kval), ggg.S1);
1622
if ((CONVT2(cur_inmd, ggg.S1) & vmaskci)!=ggg.kval || (ggg.wild_mode && ggg.defselN) ||
1623
((/* ggg.ci==cur_inmd->MaxPress|| */ ggg.spc_pressed) && ggg.defselN &&
1624
(pselkey && ( pendkey || ggg.spc_pressed)) ) ) {
1627
if ((pselkey || ggg.wild_mode) && ggg.defselN) {
1628
int vv = pselkey - cur_inmd->selkey;
1630
if ((_gtab_space_auto_first & GTAB_space_auto_first_any) && !ggg.wild_mode
1631
&& ggg.exa_match && (!cur_inmd->use_quick || ggg.ci!=2))
1637
if (seltab[vv][0]) {
1638
if (AUTO_SELECT_BY_PHRASE && poo.same_pho_query_state != SAME_PHO_QUERY_gtab_input)
1639
insert_gbuf_cursor1_cond(seltab[vv], ggg.kval, ggg.exa_match);
1641
putstr_inp(seltab[vv]);
1646
if (pselkey && !ggg.defselN)
1649
if (gtab_invalid_key_in) {
1650
if (ggg.spc_pressed) {
1652
ggg.invalid_spc = TRUE;
1653
// dbg("ggg.invalid_spc\n");
1659
if (gtab_dup_select_bell)
1663
ggg.inch[--ggg.ci]=0;
1674
while(CONVT2(cur_inmd, j)==ggg.kval && j<oE1)
1678
ggg.total_matchN = ggg.E1 - ggg.S1;
1679
ggg.pg_idx = ggg.S1;
1682
if (ggg.total_matchN > page_len()) {
1683
if ((_gtab_space_auto_first & GTAB_space_auto_first_any) || ggg.spc_pressed || pendkey ||
1684
(ggg.ci==cur_inmd->MaxPress && (_gtab_space_auto_first & GTAB_space_auto_first_full)))
1688
if (ggg.ci < cur_inmd->MaxPress && !ggg.spc_pressed && !pendkey && !ggg.more_pg) {
1694
while (CONVT2(cur_inmd, j)==ggg.kval && ggg.exa_match <= page_len()) {
1695
seltab_phrase[ggg.exa_match] = load_seltab(j, ggg.exa_match);
1701
ggg.defselN=ggg.exa_match;
1702
// dbg("--- ggg.exa_match %d\n", ggg.exa_match);
1704
if (ggg.defselN > page_len())
1707
int shiftb=(KEY_N - 1 -ggg.ci) * KeyBits;
1709
// if (gtab_disp_partial_match_on)
1710
while((CONVT2(cur_inmd, j) & vmaskci)==ggg.kval && j<oE1) {
1711
int fff=cur_inmd->keycol[(CONVT2(cur_inmd, j)>>shiftb) & cur_inmd->kmask];
1712
u_char *tbl_ch = tblch(j);
1714
if (gtab_disp_partial_match_on() && (!seltab[fff][0] || seltab_phrase[fff] ||
1715
(bchcmp(seltab[fff], tbl_ch)>0 && fff > ggg.exa_match))) {
1716
seltab_phrase[fff] = load_seltab(j, fff);
1722
dbg("jj %d", fff); utf8_putchar(seltab[fff]); dbg("\n");
1727
if (gtab_unique_auto_send_on()) {
1728
char *first_str=NULL;
1729
for(i=0; i < page_len(); i++) {
1733
first_str = seltab[i];
1736
if (match_cnt==1 && first_str) {
1737
if (AUTO_SELECT_BY_PHRASE && poo.same_pho_query_state != SAME_PHO_QUERY_gtab_input)
1738
insert_gbuf_nokey(first_str);
1740
putstr_inp(first_str);
1745
// dbg("more %d %d skip_end:%d\n", ggg.more_pg, ggg.total_matchN, cur_inmd->flag&FLAG_PHRASE_AUTO_SKIP_ENDKEY);
1749
if (pendkey && (!(cur_inmd->flag&FLAG_PHRASE_AUTO_SKIP_ENDKEY) || !AUTO_SELECT_BY_PHRASE || ggg.ci==1)) {
1750
// dbg("spc_pressed = 1\n");
1751
ggg.spc_pressed = 1;
1754
if (ggg.ci==cur_inmd->MaxPress)
1756
int full_send = gtab_press_full_auto_send_on() && ggg.last_full;
1758
// dbg("flag %d\n",!(pendkey && (cur_inmd->flag&FLAG_PHRASE_AUTO_SKIP_ENDKEY)));
1759
if (AUTO_SELECT_BY_PHRASE && !(pendkey && (cur_inmd->flag&FLAG_PHRASE_AUTO_SKIP_ENDKEY))
1760
&& poo.same_pho_query_state != SAME_PHO_QUERY_gtab_input &&
1761
(ggg.spc_pressed||full_send)) {
1766
// puts("kkkkkkkkkkk");
1767
while(j<ggg.E1 && CONVT2(cur_inmd, j)==ggg.kval && selN < 255) {
1768
sel = trealloc(sel, char *, selN+1);
1769
sel[selN++] = load_tblidx(j);
1772
insert_gbuf_cursor(sel, selN, ggg.kval, FALSE);
1773
gtab_scan_pre_select(FALSE);
1779
// dbg("jjjjjjjjjjjjjjjjjj");
1780
while(j<ggg.E1 && CONVT2(cur_inmd, j)==ggg.kval && ggg.defselN < page_len()) {
1781
load_seltab(j, ggg.defselN);
1785
if (ggg.ci == cur_inmd->MaxPress || ggg.spc_pressed) {
1787
// dbg("ggg.sel1st_i %d %d %d\n", ggg.ci, cur_inmd->MaxPress, ggg.spc_pressed);
1792
ggg.exa_match = ggg.defselN;
1793
// dbg("ggg.defselN %d\n", ggg.defselN);
1796
if (ggg.defselN==1 && !ggg.more_pg) {
1797
if (ggg.spc_pressed || full_send || gtab_unique_auto_send_on()) {
1798
if (AUTO_SELECT_BY_PHRASE && poo.same_pho_query_state != SAME_PHO_QUERY_gtab_input)
1799
insert_gbuf_cursor1_cond(seltab[0], ggg.kval, ggg.exa_match);
1801
putstr_inp(seltab[0]);
1807
// ggg.spc_pressed=0;
1808
// if (gtab_invalid_key_in)
1810
ggg.invalid_spc = TRUE;
1817
if (gtab_dup_select_bell && (gtab_disp_partial_match_on() || gtab_pre_select_or_partial_on())) {
1818
if (ggg.spc_pressed || gtab_full_space_auto_first || (ggg.last_full && gtab_press_full_auto_send_on()))
1825
if (gtab_disp_partial_match_on() || gtab_pre_select_or_partial_on() || ((ggg.exa_match > 1 || ggg.more_pg) &&
1826
(ggg.spc_pressed || gtab_press_full_auto_send_on() ||
1827
(ggg.ci==cur_inmd->MaxPress && (_gtab_space_auto_first & GTAB_space_auto_first_full))) ) ) {
1828
disp_selection(phrase_selected);