1 #include "gcin.h"
2 #include "pho.h"
3 #include "config.h"
4 #if GCIN_i18n_message
5 #include <libintl.h>
6 #endif
7 #include "lang.h"
8 #include "tsin.h"
9 #include "gtab.h"
10 #include <gdk/gdkkeysyms.h>
11 #if GTK_CHECK_VERSION(2,90,7)
12 #include <gdk/gdkkeysyms-compat.h>
13 #endif
14 
15 TSIN_HANDLE *ts;
16 gboolean b_contrib, b_contrib_en, b_en;
17 void load_tsin_contrib_tsin(), load_tsin_contrib_en();
18 
19 char private_file_src[128];
20 char contributed_file_src[128];
21 char downloaded_file_src[128];
22 
23 char txt[128];
24 
25 //extern char *current_tsin_fname;
26 typedef unsigned int u_int32_t;
27 
28 #define PAGE_LEN 20
29 
30 void init_TableDir();
31 void init_gtab(int inmdno);
32 gboolean init_tsin_table_fname(INMD *p, char *fname);
33 void load_tsin_db0(char *infname, gboolean is_gtab_i);
34 gboolean load_tsin_db_ex(TSIN_HANDLE *ptsin_hand, char *infname, gboolean read_only, gboolean use_idx);
35 
36 GtkWidget *vbox_top;
37 INMD *pinmd;
38 char gtab_tsin_fname[256];
39 char is_gtab;
40 
41 char *phokey2pinyin(phokey_t k);
42 gboolean b_pinyin;
43 GtkWidget *hbox_buttons;
44 char current_str[MAX_PHRASE_LEN*CH_SZ+1];
45 extern gboolean is_chs;
46 
47 GtkWidget *mainwin;
48 
49 static int *ts_idx;
50 int tsN;
51 int page_ofs;
52 GtkWidget *labels[PAGE_LEN];
53 GtkWidget *button_check[PAGE_LEN];
54 GtkWidget *last_row, *find_textentry;
55 GtkWidget *scroll_bar;
56 int del_ofs[1024];
57 int del_ofsN;
58 
get_tag()59 char *get_tag()
60 {
61   return b_en?TSIN_EN_FILE :tsin32_f;
62 }
63 
get_key_sz()64 int get_key_sz()
65 {
66 	return b_en?1:sizeof(phokey_t);
67 }
68 
cp_ph_key(void * in,int idx,void * dest)69 void cp_ph_key(void *in, int idx, void *dest)
70 {
71   if (ts->ph_key_sz==1) {
72     char *pharr = (char *)in;
73     in = &pharr[idx];
74   } else if (ts->ph_key_sz==2) {
75     phokey_t *pharr = (phokey_t *)in;
76     in = &pharr[idx];
77   } else
78   if (ts->ph_key_sz==4) {
79     u_int32_t *pharr4 = (u_int32_t *)in;
80     in = &pharr4[idx];
81   } else {
82     u_int64_t *pharr8 = (u_int64_t *)in;
83     in = &pharr8[idx];
84   }
85 
86   memcpy(dest, in, ts->ph_key_sz);
87 }
88 
get_ph_key_ptr(void * in,int idx)89 void *get_ph_key_ptr(void *in, int idx)
90 {
91   if (ts->ph_key_sz==1) {
92     char *pharr = (char *)in;
93     return &pharr[idx];
94   } else if (ts->ph_key_sz==2) {
95     phokey_t *pharr = (phokey_t *)in;
96     return &pharr[idx];
97   } else
98   if (ts->ph_key_sz==4) {
99     u_int32_t *pharr4 = (u_int32_t *)in;
100     return &pharr4[idx];
101   } else {
102     u_int64_t *pharr8 = (u_int64_t *)in;
103     return &pharr8[idx];
104   }
105 }
106 
lookup_gtab_key(char * ch,void * out)107 int lookup_gtab_key(char *ch, void *out)
108 {
109   int outN=0;
110   INMD *tinmd = &inmd[default_input_method];
111 
112   int i;
113   for(i=0; i < tinmd->DefChars; i++) {
114     char *chi = (char *)tblch2(tinmd, i);
115 
116     if (!(chi[0] & 0x80))
117       continue;
118     if (!utf8_eq(chi, ch))
119       continue;
120 
121     u_int64_t key = CONVT2(tinmd, i);
122     if (ts->ph_key_sz==4) {
123       u_int32_t key32 = (u_int32_t)key;
124       memcpy(get_ph_key_ptr(out, outN), &key32, ts->ph_key_sz);
125     } else
126       memcpy(get_ph_key_ptr(out, outN), &key, ts->ph_key_sz);
127     outN++;
128   }
129 
130   return outN;
131 }
132 
133 
qcmp_str(const void * aa,const void * bb)134 static int qcmp_str(const void *aa, const void *bb)
135 {
136   char *a = * (char **)aa, *b = * (char **)bb;
137 
138   return strcmp(a,b);
139 }
140 
141 extern FILE *fph;
142 
load_ts_phrase()143 void load_ts_phrase()
144 {
145   FILE *fp = ts->fph;
146 
147   int i;
148   dbg("load_ts_phrase fname %s\n", ts->tsin_fname);
149 
150   int ofs = (is_gtab || b_en) ? sizeof(TSIN_GTAB_HEAD):0;
151   fseek(fp, ofs, SEEK_SET);
152 
153   tsN=0;
154   free(ts_idx); ts_idx=NULL;
155 
156   while (!feof(fp)) {
157     ts_idx = trealloc(ts_idx, int, tsN);
158     ts_idx[tsN] = ftell(fp);
159     u_int64_t phbuf[MAX_PHRASE_LEN];
160     char chbuf[MAX_PHRASE_LEN * CH_SZ + 1];
161     char clen;
162     usecount_t usecount;
163     clen = 0;
164 
165 	int rn;
166     rn = fread(&clen,1,1,fp);
167 
168 	if (!clen)
169 	  break;
170 	gboolean en_str = FALSE;
171 
172 	if (clen < 0) {
173 	  clen = - clen;
174 	  en_str = TRUE;
175 	}
176 
177     if (clen > MAX_PHRASE_LEN * 2) {
178       box_warn("bad tsin db clen %d > MAX_PHRASE_LEN %d  ph_key_sz:%d\n", clen, MAX_PHRASE_LEN, ts->ph_key_sz);
179       break;
180     }
181 
182     rn = fread(&usecount,sizeof(usecount_t), 1, fp);
183     rn = fread(phbuf, ts->ph_key_sz, clen, fp);
184     int tlen = 0;
185 
186 
187     if (!b_en || en_str)
188     for(i=0; i < clen; i++) {
189       int n = fread(&chbuf[tlen], 1, 1, fp);
190       if (n<=0)
191         goto stop;
192       int len=utf8_sz(&chbuf[tlen]);
193       int rn = fread(&chbuf[tlen+1], 1, len-1, fp);
194       tlen+=len;
195     }
196 
197     if (clen < 2 || en_str)
198       continue;
199 
200     chbuf[tlen]=0;
201     tsN++;
202   }
203 
204   page_ofs = tsN - PAGE_LEN;
205   if (page_ofs < 0)
206     page_ofs = 0;
207 
208 stop:
209    dbg("load_ts_phrase\n");
210 //  fclose(fp);
211 
212 }
213 
214 int gtab_key2name(INMD *tinmd, u_int64_t key, char *t, int *rtlen);
get_key_str(void * key,int idx,char * out_str)215 void get_key_str(void *key, int idx, char *out_str)
216 {
217   char t[128];
218   char *phostr;
219 
220   if (b_en) {
221     int tofs = 0;
222     char *p = (char *)key;
223 	int c = 0;
224 	while (*p) {
225 	  if (c==idx) {
226 	    utf8cpy(t, p);
227 		break;
228 	  }
229 
230 	  int sz = utf8_sz(p);
231       tofs += sz;
232 	  c++;
233 	}
234 	phostr = t;
235   } else if (is_gtab) {
236      int tlen;
237      u_int64_t key64;
238      if (ts->ph_key_sz == 4) {
239        u_int32_t key32;
240        cp_ph_key(key, idx, &key32);
241        key64 = key32;
242      } else
243        cp_ph_key(key, idx, &key64);
244      gtab_key2name(pinmd, key64, t, &tlen);
245      phostr = t;
246    } else {
247      phokey_t k;
248      cp_ph_key(key, idx, &k);
249      phostr = b_pinyin?
250      phokey2pinyin(k):phokey_to_str(k);
251    }
252 
253  // dbg("phostr %s\n", phostr);
254    strcpy(out_str, phostr);
255 }
256 
257 
load_tsin_at_ts_idx(int ts_row,char * len,usecount_t * usecount,void * pho,u_char * ch)258 void load_tsin_at_ts_idx(int ts_row, char *len, usecount_t *usecount, void *pho, u_char *ch)
259 {
260     int ofs = ts_idx[ts_row];
261 #if MEM_TSIN
262 	load_tsin_entry0_ex(ts, ofs, len, usecount, pho, ch);
263 #else
264     fseek(ts->fph, ofs, SEEK_SET);
265     load_tsin_entry0_ex(ts, len, usecount, pho, ch);
266 #endif
267 	if (b_en) {
268 	  memcpy(ch, pho, *len);
269 	  ch[*len]=0;
270 	}
271 }
272 
disp_page()273 void disp_page()
274 {
275   dbg("tsN:%d\n", tsN);
276   if (!tsN)
277     return;
278 
279   int li;
280   for(li=0;li<PAGE_LEN;li++) {
281     char line[256];
282     line[0];
283     int ts_row = page_ofs + li;
284     if (ts_row >= tsN) {
285       gtk_label_set_text(GTK_LABEL(labels[li]), "-");
286       gtk_widget_hide(button_check[li]);
287       continue;
288     }
289 
290 
291     u_int64_t phbuf[MAX_PHRASE_LEN];
292     char chbuf[MAX_PHRASE_LEN * CH_SZ + 1];
293     char clen;
294     usecount_t usecount;
295     int i;
296 
297 	bzero(phbuf, sizeof(phbuf));
298     load_tsin_at_ts_idx(ts_row, &clen, &usecount, phbuf, (u_char *)chbuf);
299 
300     char *t;
301     strcpy(line, t=g_markup_escape_text(chbuf, -1));
302     g_free(t);
303     strcat(line, " <span foreground=\"blue\">");
304 
305 	char tt[512];
306 	if (!b_en) {
307     for(i=0; i < clen; i++) {
308       get_key_str(phbuf, i, tt);
309 //      dbg("tt %s\n", tt);
310       strcat(line, t=g_markup_escape_text(tt, -1));
311       g_free(t);
312       strcat(line, " ");
313     }
314 	}
315 
316     sprintf(tt, " %d", usecount);
317     strcat(line, tt);
318     strcat(line, "</span>");
319 
320 //    dbg("%s\n", line);
321     gtk_label_set_markup(GTK_LABEL(labels[li]), line);
322     gtk_widget_show(button_check[li]);
323   }
324 
325   gtk_range_set_value(GTK_RANGE(scroll_bar), page_ofs);
326 }
327 
328 
329 void write_tsin_src(FILE *fw, char len, phokey_t *pho, char *s);
330 
cb_button_delete(GtkButton * button,gpointer user_data)331 static void cb_button_delete(GtkButton *button, gpointer user_data)
332 {
333   int i;
334 if (b_contrib) {
335   FILE *fw;
336 
337   if ((fw=fopen(private_file_src, "a"))==NULL)
338     p_err("cannot write %s", private_file_src);
339 
340   for(i=0; i < PAGE_LEN; i++) {
341     if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button_check[i])))
342       continue;
343     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button_check[i]), FALSE);
344 
345     char len;
346     usecount_t usecount;
347     phokey_t pho[MAX_PHRASE_LEN];
348     unsigned char str[MAX_PHRASE_STR_LEN];
349     load_tsin_at_ts_idx(page_ofs+i, &len, &usecount, pho, str);
350 
351 	if (b_en)
352       write_tsin_src(fw, len, NULL, (char*)str);
353 	else
354       write_tsin_src(fw, len, pho, (char*)str);
355   }
356 
357   fclose(fw);
358   if (b_en)
359     load_tsin_contrib_en();
360   else
361 	load_tsin_contrib_tsin();
362   load_ts_phrase();
363 } else {
364   for(i=0; i < PAGE_LEN; i++) {
365     if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button_check[i])))
366       continue;
367     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button_check[i]), FALSE);
368 
369     del_ofs[del_ofsN++] = ts_idx[page_ofs+i];
370     ts_idx[page_ofs+i]=-1;
371   }
372 
373   int ntsN=0;
374 
375   for(i=0;i<tsN;i++)
376     if (ts_idx[i]>=0)
377       ts_idx[ntsN++]=ts_idx[i];
378   tsN = ntsN;
379 }
380   disp_page();
381 }
382 
cb_button_find_ok(GtkButton * button,gpointer user_data)383 static void cb_button_find_ok(GtkButton *button, gpointer user_data)
384 {
385   txt[0]=0;
386   strcpy(txt, gtk_entry_get_text(GTK_ENTRY(find_textentry)));
387 //  gtk_widget_destroy(last_row);
388 //  last_row = NULL;
389   if (!txt[0])
390     return;
391   int row;
392   for(row=page_ofs+1; row < tsN; row++) {
393     u_int64_t phbuf[MAX_PHRASE_LEN];
394     char chbuf[MAX_PHRASE_LEN * CH_SZ + 1];
395     char clen;
396     usecount_t usecount;
397 
398     load_tsin_at_ts_idx(row, &clen, &usecount, phbuf, (u_char *)chbuf);
399 
400     if (strstr(chbuf, txt))
401       break;
402   }
403 
404   if (row==tsN) {
405     GtkWidget *dia = gtk_message_dialog_new(NULL,GTK_DIALOG_MODAL,GTK_MESSAGE_INFO,GTK_BUTTONS_OK,"%s not found",
406       txt);
407     gtk_dialog_run (GTK_DIALOG (dia));
408     gtk_widget_destroy (dia);
409   } else {
410     page_ofs = row;
411     disp_page();
412   }
413 }
414 
cb_button_close(GtkButton * button,gpointer user_data)415 static void cb_button_close(GtkButton *button, gpointer user_data)
416 {
417   if (last_row)
418     gtk_widget_destroy(last_row);
419   last_row = NULL;
420   gtk_window_resize(GTK_WINDOW(mainwin), 1, 1);
421 }
422 
cb_button_find(GtkButton * button,gpointer user_data)423 static void cb_button_find(GtkButton *button, gpointer user_data)
424 {
425   if (last_row)
426     gtk_widget_destroy(last_row);
427 
428   last_row = gtk_hbox_new (FALSE, 0);
429   GtkWidget *lab = gtk_label_new("Find");
430   gtk_box_pack_start (GTK_BOX (last_row), lab, FALSE, FALSE, 0);
431   find_textentry = gtk_entry_new();
432   gtk_box_pack_start (GTK_BOX (last_row), find_textentry, FALSE, FALSE, 5);
433   GtkWidget *button_ok = gtk_button_new_from_stock (GTK_STOCK_OK);
434   g_signal_connect (G_OBJECT (button_ok), "clicked",
435      G_CALLBACK (cb_button_find_ok), NULL);
436   gtk_box_pack_start (GTK_BOX (last_row), button_ok, FALSE, FALSE, 5);
437 
438   GtkWidget *button_close = gtk_button_new_from_stock (GTK_STOCK_CLOSE);
439   g_signal_connect (G_OBJECT (button_close), "clicked",
440      G_CALLBACK (cb_button_close), NULL);
441   gtk_box_pack_start (GTK_BOX (last_row), button_close, FALSE, FALSE, 5);
442 
443 
444   gtk_box_pack_start (GTK_BOX (vbox_top), last_row, FALSE, FALSE, 0);
445 
446   gtk_entry_set_text(GTK_ENTRY(find_textentry), txt);
447 
448   gtk_widget_show_all(last_row);
449 }
450 
cb_button_edit(GtkButton * button,gpointer user_data)451 static void cb_button_edit(GtkButton *button, gpointer user_data)
452 {
453 }
454 
455 void ts_upload();
456 
cb_button_save(GtkButton * button,gpointer user_data)457 static void cb_button_save(GtkButton *button, gpointer user_data)
458 {
459 if (b_contrib) {
460   ts_upload();
461 } else {
462   int i;
463   for(i=0;i<del_ofsN;i++) {
464     fseek(ts->fph, del_ofs[i] + 1, SEEK_SET);
465     usecount_t usecount = -1;
466     fwrite(&usecount, sizeof(usecount), 1, ts->fph);
467   }
468   fflush(ts->fph);
469 
470 #if UNIX
471   unix_exec(GCIN_BIN_DIR"/tsd2a32 %s -o tsin.tmp", ts->tsin_fname);
472   unix_exec(GCIN_BIN_DIR"/tsa2d32 tsin.tmp %s", ts->tsin_fname);
473 #else
474   win32exec_va("tsd2a32", ts->tsin_fname, "-o", "tsin.tmp", NULL);
475   win32exec_va("tsa2d32", "tsin.tmp",  ts->tsin_fname, NULL);
476 #endif
477 }
478   exit(0);
479 }
480 
481 
482 Display *dpy;
483 
send_reload_tsin_db()484 void send_reload_tsin_db() {
485   send_gcin_message(
486 #if UNIX
487     dpy,
488 #endif
489      RELOAD_TSIN_DB);
490 }
491 
do_exit()492 void do_exit()
493 {
494   send_reload_tsin_db();
495   exit(0);
496 }
497 
498 void load_tsin_db();
499 void set_window_gcin_icon(GtkWidget *window);
500 #if WIN32
501 void init_gcin_program_files();
502 #pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"")
503 #endif
504 
page_up()505 void page_up()
506 {
507   page_ofs -= PAGE_LEN;
508   if (page_ofs < 0)
509     page_ofs = 0;
510 }
511 
page_down()512 void page_down()
513 {
514   page_ofs += PAGE_LEN;
515   if (page_ofs>= tsN)
516     page_ofs = tsN-1;
517 }
518 
scroll_event(GtkWidget * widget,GdkEventScroll * event,gpointer user_data)519 static gboolean  scroll_event(GtkWidget *widget,GdkEventScroll *event, gpointer user_data)
520 {
521   dbg("scroll_event\n");
522 
523   switch (event->direction) {
524     case GDK_SCROLL_UP:
525       page_up();
526       break;
527     case GDK_SCROLL_DOWN:
528       page_down();
529       break;
530     default:
531       break;
532   }
533 
534   return FALSE;
535 }
536 
key_press_event(GtkWidget * widget,GdkEventKey * event,gpointer user_data)537 gboolean key_press_event(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
538 {
539   if (last_row)
540     return FALSE;
541 //  dbg("key_press_event %x\n", event->keyval);
542   switch (event->keyval) {
543     case GDK_Up:
544     case GDK_KP_Up:
545       if (page_ofs>0)
546         page_ofs--;
547       break;
548     case GDK_Down:
549     case GDK_KP_Down:
550       if (page_ofs<tsN-1)
551         page_ofs++;
552       break;
553     case GDK_KP_Page_Up:
554     case GDK_Page_Up:
555       page_up();
556       break;
557     case GDK_KP_Page_Down:
558     case GDK_Page_Down:
559       page_down();
560       break;
561     case GDK_Home:
562     case GDK_KP_Home:
563       page_ofs = 0;
564       break;
565     case GDK_End:
566     case GDK_KP_End:
567       page_ofs = tsN - PAGE_LEN;
568       break;
569   }
570 
571   disp_page();
572 
573   return TRUE;
574 }
575 
576 gboolean is_pinyin_kbm();
577 
578 #if WIN32
579 #include <direct.h>
580 #endif
581 
cb_scroll_bar(GtkRange * range,GtkScrollType scroll,gdouble value,gpointer user_data)582 gboolean  cb_scroll_bar(GtkRange *range, GtkScrollType scroll,
583                         gdouble value, gpointer user_data)
584 {
585   page_ofs = (int)value;
586   if (page_ofs > tsN - PAGE_LEN)
587     page_ofs = tsN - PAGE_LEN;
588   if (page_ofs < 0)
589     page_ofs = 0;
590   disp_page();
591   return TRUE;
592 }
593 
gen_bin(char * name,char * full_src,char * minus)594 static void gen_bin(char *name, char *full_src, char *minus)
595 {
596   // doesn't have to use full path because chdir(gcin user dir)
597   minus[0]=0;
598   char src[128];
599   strcat(strcpy(src, name),".src");
600 
601   dbg("gen_bin %s %s\n", name, src);
602 
603   if (get_gcin_user_fname(src, full_src)) {
604     dbg("%s %s\n", name, full_src);
605 #if UNIX
606     putenv("GCIN_NO_RELOAD=");
607     unix_exec(GCIN_BIN_DIR"/tsa2d32 %s %s", src, name);
608 #else
609     _putenv("GCIN_NO_RELOAD=Y");
610     win32exec_va("tsa2d32", src, name, NULL);
611 #endif
612     sprintf(minus, " -minus %s", name);
613   } else
614     dbg("not exist %s\n", full_src);
615 }
616 
617 
618 void free_tsin();
619 #if WIN32
620 int win32exec_argv(char *s, int argc, char *argv[]);
621 #endif
622 
623 void free_en();
624 void load_en_db0(char *infname);
625 
load_tsin_contrib(gboolean is_en,char * private_phrases,char * contributed_phrases,char * downloaded_phrases)626 void load_tsin_contrib(gboolean is_en, char *private_phrases, char *contributed_phrases, char *downloaded_phrases)
627 {
628   char minus_priv[128];
629   gen_bin(private_phrases, private_file_src, minus_priv);
630   char minus_contributed[128];
631   gen_bin(contributed_phrases, contributed_file_src, minus_contributed);
632 
633   char minus_downloaded[128];
634   gen_bin(downloaded_phrases, downloaded_file_src, minus_downloaded);
635 
636   char sys_tsfname[128], contrib_temp[128];
637   get_sys_table_file_name(get_tag(), sys_tsfname);
638   get_gcin_user_fname("contrib-temp", contrib_temp);
639 
640   char ts_user_fname[128];
641   get_gcin_user_fname(get_tag(), ts_user_fname);
642 
643 #if UNIX
644   char *en_arg = is_en?"-e":"";
645   unix_exec(GCIN_BIN_DIR"/tsd2a32 %s -b -minus %s -o %s%s%s%s", ts_user_fname,
646     sys_tsfname, contrib_temp, minus_priv, minus_contributed, minus_downloaded);
647 #else
648   char *argv[32];
649   int argc=0;
650 
651   argv[argc++]=ts_user_fname;
652   argv[argc++]="-b";
653 
654   argv[argc++]="-o";
655   argv[argc++]=contrib_temp;
656 
657   argv[argc++]="-minus";
658   argv[argc++]=sys_tsfname;
659 
660   if (minus_priv[0]) {
661     argv[argc++]="-minus";
662     argv[argc++]=private_phrases;
663   }
664   if (minus_contributed[0]) {
665     argv[argc++]="-minus";
666     argv[argc++]=contributed_phrases;
667   }
668   if (minus_downloaded[0]) {
669     argv[argc++]="-minus";
670     argv[argc++]=downloaded_phrases;
671   }
672 
673   win32exec_argv("tsd2a32.exe", argc, argv);
674 #endif
675 
676   if (is_en) {
677     free_en();
678     load_en_db0(contrib_temp);
679   } else {
680     free_tsin();
681     load_tsin_db0(contrib_temp, FALSE);
682   }
683 }
684 
685 
686 void ts_download();
687 
cb_button_download(GtkButton * button,gpointer user_data)688 static void cb_button_download(GtkButton *button, gpointer user_data)
689 {
690   ts_download();
691   load_ts_phrase();
692   gtk_range_set_range(GTK_RANGE(scroll_bar), 0, tsN);
693   disp_page();
694   send_reload_tsin_db();
695 }
696 
697 #define DOWNLOADED_PHRASES "downloaded-phrases"
load_tsin_contrib_tsin()698 void load_tsin_contrib_tsin()
699 {
700   load_tsin_contrib(FALSE, "private-phrases", "contributed-phrases", DOWNLOADED_PHRASES);
701 }
702 
703 #define DOWNLOADED_PHRASES_EN "downloaded-phrases-en"
load_tsin_contrib_en()704 void load_tsin_contrib_en()
705 {
706   load_tsin_contrib(TRUE, "private-phrases-en", "contributed-phrases-en", DOWNLOADED_PHRASES_EN);
707 }
708 
709 
710 void load_en_db();
711 // will be dropped in gtk3.0 ?
712 GtkWidget *gtk_vscrollbar_new (GtkAdjustment *adjustment);
713 
main(int argc,char ** argv)714 int main(int argc, char **argv)
715 {
716 #if WIN32 && 0
717     WORD wVersionRequested;
718     WSADATA wsaData;
719     int err;
720     wVersionRequested = MAKEWORD(2, 2);
721     err = WSAStartup(wVersionRequested, &wsaData);
722 #endif
723 
724   dbg("%s\n", argv[0]);
725   b_contrib = strstr(argv[0], "ts-contribute")!=NULL;
726   b_contrib_en = strstr(argv[0], "ts-contribute-en")!=NULL;
727   b_en = strstr(argv[0], "ts-edit-en")!=NULL;
728 
729   if (b_contrib)
730     dbg("b_contrib\n");
731 
732   set_is_chs();
733   load_setttings();
734 
735   init_TableDir();
736   b_pinyin = is_pinyin_kbm();
737 
738   gtk_init (&argc, &argv);
739   load_gtab_list(TRUE);
740 
741   char gcin_dir[512];
742   get_gcin_dir(gcin_dir);
743 
744   if (argc < 2) {
745 	 int rval;
746 #if UNIX
747   rval = chdir(gcin_dir);
748 #else
749   _chdir(gcin_dir);
750 #endif
751   }
752 
753 #if GCIN_i18n_message
754   bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
755   textdomain(GETTEXT_PACKAGE);
756 #endif
757 
758 
759   get_gcin_user_fname(b_en?DOWNLOADED_PHRASES_EN:DOWNLOADED_PHRASES, downloaded_file_src);
760   strcat(downloaded_file_src, ".src");
761 
762   pinmd = &inmd[default_input_method];
763 
764   ts = &tsin_hand;
765 
766   if (b_contrib_en) {
767     dbg("b_contrib_en\n");
768     b_en = TRUE;
769     load_tsin_contrib_en();
770     ts = &en_hand;
771   } else
772   if (b_en) {
773     dbg("b_en\n");
774     if (argc > 1)
775       load_tsin_db_ex(&en_hand, argv[1], FALSE, FALSE);
776     else
777       load_en_db();
778     ts = &en_hand;
779   } else if (pinmd->method_type == method_type_TSIN) {
780     dbg("is tsin\n");
781     pho_load();
782     if (b_contrib) {
783       load_tsin_contrib_tsin();
784     } else {
785       dbg("edit\n");
786       if (argc > 1)
787         load_tsin_db_ex(&tsin_hand, argv[1], FALSE, FALSE);
788       else
789         load_tsin_db();
790     }
791 
792     ts->ph_key_sz = 2;
793   } else
794   if (pinmd->filename) {
795     if (b_contrib)
796       p_err("Currently %s only supports tsin", argv[0]);
797 
798     dbg("gtab filename %s\n", pinmd->filename);
799     init_gtab(default_input_method);
800     is_gtab = TRUE;
801     init_tsin_table_fname(pinmd, gtab_tsin_fname);
802     load_tsin_db0(gtab_tsin_fname, TRUE);
803   } else
804     p_err("Your default input method %s doesn't use phrase database",
805       pinmd->cname);
806 
807   dbg("ph_key_sz:%d  %s\n", ts->ph_key_sz, get_tag());
808 
809 #if UNIX
810   dpy = GDK_DISPLAY();
811 #endif
812 
813   load_ts_phrase();
814 
815   mainwin = gtk_window_new (GTK_WINDOW_TOPLEVEL);
816   gtk_window_set_position(GTK_WINDOW(mainwin), GTK_WIN_POS_CENTER);
817   g_signal_connect (G_OBJECT (mainwin), "key-press-event",  G_CALLBACK (key_press_event), NULL);
818 
819   gtk_window_set_has_resize_grip(GTK_WINDOW(mainwin), FALSE);
820 //  gtk_window_set_default_size(GTK_WINDOW (mainwin), 640, 520);
821   set_window_gcin_icon(mainwin);
822 
823   vbox_top = gtk_vbox_new (FALSE, 0);
824   gtk_container_add (GTK_CONTAINER(mainwin), vbox_top);
825 
826   GtkWidget *hbox_page = gtk_hbox_new (FALSE, 0);
827   gtk_box_pack_start (GTK_BOX (vbox_top), hbox_page, TRUE, FALSE, 0);
828 
829   GtkWidget *align_page = gtk_alignment_new(0, 0, 1.0, 1.0);
830   gtk_box_pack_start (GTK_BOX (hbox_page), align_page, TRUE, TRUE, 0);
831 
832   GtkWidget *vbox_page = gtk_vbox_new (TRUE, 0);
833   gtk_container_add (GTK_CONTAINER(align_page), vbox_page);
834 
835   scroll_bar = gtk_vscrollbar_new(
836   GTK_ADJUSTMENT(gtk_adjustment_new(tsN - PAGE_LEN,0, tsN, 1,PAGE_LEN,PAGE_LEN)));
837   gtk_box_pack_start (GTK_BOX (hbox_page), scroll_bar, FALSE, FALSE, 0);
838 
839   g_signal_connect(G_OBJECT(scroll_bar), "change-value", G_CALLBACK(cb_scroll_bar), NULL);
840 
841   int i;
842   for(i=0;i<PAGE_LEN;i++) {
843     GtkWidget *hbox;
844     hbox = gtk_hbox_new (FALSE, 0);
845     gtk_box_pack_start (GTK_BOX (vbox_page), hbox, TRUE, TRUE, 0);
846     button_check[i] = gtk_check_button_new();
847     gtk_box_pack_start (GTK_BOX (hbox), button_check[i], FALSE, FALSE, 0);
848 
849     labels[i]=gtk_label_new(NULL);
850 
851     GtkWidget *align = gtk_alignment_new (0, 0, 0, 0);
852     gtk_container_add(GTK_CONTAINER(align), labels[i]);
853     gtk_box_pack_start (GTK_BOX (hbox), align, FALSE, FALSE, 0);
854   }
855 
856 
857   hbox_buttons = gtk_hbox_new (FALSE, 0);
858   gtk_box_pack_start (GTK_BOX (vbox_top), hbox_buttons, FALSE, FALSE, 0);
859 
860   GtkWidget *button_delete = b_contrib ? gtk_button_new_with_label(_(_L("私密詞不上載"))):gtk_button_new_from_stock (GTK_STOCK_DELETE);
861   gtk_box_pack_start (GTK_BOX (hbox_buttons), button_delete, FALSE, FALSE, 0);
862   g_signal_connect (G_OBJECT (button_delete), "clicked",
863      G_CALLBACK (cb_button_delete), NULL);
864 
865   GtkWidget *button_find = gtk_button_new_from_stock (GTK_STOCK_FIND);
866   gtk_box_pack_start (GTK_BOX (hbox_buttons), button_find, FALSE, FALSE, 0);
867   g_signal_connect (G_OBJECT (button_find), "clicked",
868      G_CALLBACK (cb_button_find), NULL);
869 
870 #if 0
871   GtkWidget *button_edit = gtk_button_new_from_stock (GTK_STOCK_EDIT);
872   gtk_box_pack_start (GTK_BOX (hbox_buttons), button_edit, FALSE, FALSE, 0);
873   g_signal_connect (G_OBJECT (button_edit), "clicked",
874      G_CALLBACK (cb_button_edit), NULL);
875 #endif
876 
877   GtkWidget *button_save =  b_contrib ? gtk_button_new_with_label(_(_L("上載詞")))
878   :gtk_button_new_from_stock (GTK_STOCK_SAVE);
879 
880   gtk_box_pack_start (GTK_BOX (hbox_buttons), button_save, FALSE, FALSE, 0);
881   g_signal_connect (G_OBJECT (button_save), "clicked",
882      G_CALLBACK (cb_button_save), NULL);
883 
884 
885   GtkWidget *button_quit = gtk_button_new_from_stock (GTK_STOCK_QUIT);
886   gtk_box_pack_start (GTK_BOX (hbox_buttons), button_quit, FALSE, FALSE, 0);
887   g_signal_connect (G_OBJECT (button_quit), "clicked",
888      G_CALLBACK (do_exit), NULL);
889 
890   if (!b_contrib && !is_gtab) {
891     GtkWidget *button_download = gtk_button_new_with_label(_(_L("下載共享詞庫")));
892     gtk_box_pack_start (GTK_BOX (hbox_buttons), button_download, FALSE, FALSE, 0);
893     g_signal_connect (G_OBJECT (button_download), "clicked",
894        G_CALLBACK (cb_button_download), NULL);
895   }
896 
897   g_signal_connect (G_OBJECT (mainwin), "delete_event", G_CALLBACK (do_exit), NULL);
898 
899   gtk_widget_realize (mainwin);
900   gtk_widget_show_all(mainwin);
901 
902 //  load_ts_phrase();
903 
904   disp_page();
905 
906 #if 0
907   GdkWindow *gdkwin=gtk_widget_get_window(mainwin);
908   gdk_window_set_events(gdkwin, GDK_BUTTON_PRESS_MASK|GDK_SCROLL_MASK| gdk_window_get_events(gdkwin));
909 #endif
910 
911   gtk_main();
912   return 0;
913 }
914