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