1 /*
2 Copyright (C) 1994-2008 Edward Der-Hua Liu, Hsin-Chu, Taiwan
3 */
4
5 #include <stdio.h>
6 #if UNIX
7 #include <X11/Xlib.h>
8 #include <X11/keysym.h>
9 #endif
10 #include "gcin.h"
11 #include "gtab.h"
12 #include "gtab-buf.h"
13 #include "pho.h"
14 #include "gst.h"
15
16 struct keystruc {
17 char *kname;
18 KeySym ksym;
19 char *str;
20 char *str_caps;
21 };
22
23 struct keystruc tran[]={
24 {"`", '~'},
25 {"0", ')'}, {"1", '!'}, {"2", '@'}, {"3", '#'}, {"4", '$'}, {"5", '%'},
26 {"6", '^'}, {"7", '&'}, {"8", '*'}, {"9", '('},
27 {"a", 'a'}, {"b", 'b'}, {"c", 'c'}, {"d", 'd'}, {"e", 'e'}, {"f", 'f'},
28 {"g", 'g'}, {"h", 'h'}, {"i", 'i'}, {"j", 'j'}, {"k", 'k'}, {"l", 'l'},
29 {"m", 'm'}, {"n", 'n'}, {"o", 'o'}, {"p", 'p'}, {"q", 'q'}, {"r", 'r'},
30 {"s", 's'}, {"t", 't'}, {"u", 'u'}, {"v", 'v'}, {"w", 'w'}, {"x", 'x'},
31 {"y", 'y'}, {"z", 'z'},
32 {",", '<'}, {".", '>'}, {";", ':'}, {"'", '"'}, {"/", '?'},
33 {"[", '{'}, {"]", '}'}, {"\\", '|'},
34 {"-", '_'}, {"=", '+'},
35 {"f1",XK_F1},{"f2",XK_F2},{"f3",XK_F3},{"f4",XK_F4},{"f5",XK_F5},{"f6",XK_F6},
36 {"f7",XK_F7},{"f8",XK_F8},{"f9",XK_F9},{"f10",XK_F10},{"f11",XK_F11},
37 {"f12",XK_F12},
38 {"left", XK_Left}, {"right", XK_Right}, {"down", XK_Down}, {"up", XK_Up},
39 {"k_ins", XK_KP_Insert}, {"k_del", XK_KP_Delete}, {"k_end", XK_KP_End},
40 {"k_down",XK_KP_Down}, {"k_pgup",XK_KP_Prior},
41 {"k_up",XK_KP_Up},
42 {"k_pgdn",XK_KP_Next}, {"k_left",XK_KP_Left},
43 {"k_5", XK_KP_Begin}, {"k_right", XK_KP_Right}, {"k_home",XK_KP_Home},
44 {"k_up",XK_Up}, {"k_pgup",XK_Prior},
45 {"kp0", XK_KP_0}, {"kp.", XK_KP_Decimal},
46 {"kp1", XK_KP_1}, {"kp2", XK_KP_2}, {"kp3", XK_KP_3},
47 {"kp4", XK_KP_4}, {"kp5", XK_KP_5}, {"kp6", XK_KP_6},
48 {"kp7", XK_KP_7}, {"kp8", XK_KP_8}, {"kp9", XK_KP_9},
49 {"kp/",XK_KP_Divide}, {"kp*", XK_KP_Multiply}, {"kp-", XK_KP_Subtract},
50 {"kp+",XK_KP_Add}, {"kpenter",XK_KP_Enter}
51 };
52
53
54 struct keystruc tran_ctrl[]={
55 {",", ','}, {".", '.'}, {";", ';'}, {"'", '\''}, {"/", '/'}, {"?",'?'},
56 {"[", '['}, {"]", ']'},
57 {":",':'}, {"{",'{'}, {"}",'}'}, {"<",'<'}, {">",'>'}, {"\"",'"'},
58 };
59
60
61 int tranN=sizeof(tran)/sizeof(tran[0]);
62 int tran_ctrlN=sizeof(tran_ctrl)/sizeof(tran_ctrl[0]);
63 extern char *TableDir;
64
65 FILE *watch_fopen(char *filename, time_t *pfile_modify_time);
66 gboolean output_gbuf();
67 gboolean gtab_cursor_end();
68 gboolean gtab_phrase_on(), tsin_cursor_end();
69 void flush_tsin_buffer();
70 void add_to_tsin_buf_str(char *str);
71
72 static time_t file_modify_time;
73 static time_t ctrl_file_modify_time;
74
load_phrase(char * fname,time_t * modtime,struct keystruc * tr,int trN)75 void load_phrase(char *fname, time_t *modtime, struct keystruc *tr, int trN)
76 {
77 FILE *fp;
78 char kname[32];
79 char ttt[512];
80
81 // dbg("load_phrase %s\n", fname);
82 if ((fp=watch_fopen(fname, modtime)) == NULL) {
83 return;
84 }
85
86 // dbg("load succcc %s\n", fname);
87 skip_utf8_sigature(fp);
88
89 while (!feof(fp)) {
90 int i,j;
91 char str[512];
92
93 kname[0]=str[0]=0;
94 myfgets(ttt, sizeof(ttt), fp);
95 if (ttt[0]=='#')
96 continue;
97 for(i=0; ttt[i]!=' ' && ttt[i]!=9 && ttt[i]; i++)
98 kname[i]=ttt[i];
99
100 kname[i]=0;
101 gboolean is_upper = FALSE;
102
103 if (!(kname[0]&0x80) && isupper(kname[0])) {
104 is_upper = TRUE;
105 kname[0] = tolower(kname[0]);
106 }
107
108 while((ttt[i]==' ' || ttt[i]==9) && ttt[i])
109 i++;
110
111 for(j=0; ttt[i]!='\n' && ttt[i]; i++,j++)
112 str[j]=ttt[i];
113
114 if (!str[0] || !kname[0])
115 continue;
116
117 str[j]=0;
118
119
120 for(i=0; i < trN; i++)
121 if (!strcmp(kname, tr[i].kname))
122 break;
123 if (i==trN) {
124 dbg("unknown key: %s\n", kname);
125 continue;
126 }
127
128 if (is_upper)
129 tr[i].str_caps = strdup(str);
130 else
131 tr[i].str = strdup(str);
132 }
133
134 fclose(fp);
135 }
136
137
free_phrase()138 void free_phrase()
139 {
140 int i;
141
142 for(i=0; i < tranN; i++) {
143 free(tran[i].str);
144 free(tran[i].str_caps);
145 }
146 }
147
148 #if WIN32
149 extern char shift_sele[], noshi_sele[];
150 #endif
151
152 gboolean gtab_phrase_on_();
153
feed_phrase(KeySym ksym,int state)154 gboolean feed_phrase(KeySym ksym, int state)
155 {
156 int i;
157
158 // dbg("ksym:%x %c\n", ksym, ksym);
159 load_phrase("phrase.table", &file_modify_time, tran, tranN);
160 load_phrase("phrase-ctrl.table", &ctrl_file_modify_time, tran_ctrl, tran_ctrlN);
161
162 #if WIN32
163 if (state & ShiftMask) {
164 char *p = strchr(noshi_sele, ksym);
165 if (p) {
166 int idx = p - noshi_sele;
167 ksym = shift_sele[idx];
168 }
169 }
170 #endif
171
172 if (ksym < 0x7f && isupper(ksym))
173 ksym = tolower(ksym);
174
175 struct keystruc *tr;
176 int trN;
177
178 if (state & ControlMask) {
179 tr = tran_ctrl;
180 trN = tran_ctrlN;
181 } else {
182 tr = tran;
183 trN = tranN;
184 }
185
186 char *str;
187
188 for(i=0; i < trN; i++) {
189 if (tr[i].ksym!= ksym)
190 continue;
191
192 str = ((state & LockMask) && tr[i].str_caps) ? tr[i].str_caps : tr[i].str;
193
194 if (str) {
195 #if USE_TSIN
196 if (current_method_type() == method_type_TSIN && current_CS->im_state == GCIN_STATE_CHINESE) {
197 add_to_tsin_buf_str(str);
198 if (gcin_punc_auto_send && tsin_cursor_end())
199 flush_tsin_buffer();
200 }
201 else
202 #endif
203 if (gtab_phrase_on_() && ggg.gbufN) {
204 insert_gbuf_nokey(str);
205 if (gcin_punc_auto_send && gtab_cursor_end())
206 output_gbuf();
207 } else
208 send_text(str);
209 return TRUE;
210 }
211 }
212
213 #if 0
214 char tt[2];
215 if ((state&(ControlMask|ShiftMask|Mod1Mask|Mod4Mask|Mod5Mask))==ShiftMask && ksym>=' ' && ksym < 0x7e) {
216 str = tt;
217 tt[0]=ksym;
218 tt[1]=0;
219 goto send_it;
220 }
221 #endif
222
223 return FALSE;
224 }
225