1 /*
2  * Author:      William Chia-Wei Cheng (bill.cheng@acm.org)
3  *
4  * Copyright (C) 2001-2009, William Chia-Wei Cheng.
5  *
6  * This file may be distributed under the terms of the Q Public License
7  * as defined by Trolltech AS of Norway and appearing in the file
8  * LICENSE.QPL included in the packaging of this file.
9  *
10  * THIS FILE IS PROVIDED AS IS WITH NO WARRANTY OF ANY KIND, INCLUDING
11  * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
12  * PURPOSE.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
13  * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
14  * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
15  * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
16  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  *
18  * @(#)$Header: /mm2/home/cvs/bc-src/tgif/tgtwb5dl.c,v 1.15 2011/05/22 22:55:02 william Exp $
19  */
20 
21 #ifndef _NO_TGTWB5
22 
23 #define _INCLUDE_FROM_TGTWB5DL_C_
24 
25 #include "tgifdefs.h"
26 #include "patchlvl.h"
27 #include "tidget.h"
28 
29 #include "auxtext.e"
30 #include "cursor.e"
31 #include "dialog.e"
32 #include "file.e"
33 #include "font.e"
34 #include "mainloop.e"
35 #include "msg.e"
36 #include "raster.e"
37 #include "rect.e"
38 #include "scroll.e"
39 #include "setup.e"
40 #include "strtbl.e"
41 #include "tdgtbase.e"
42 #include "tdgtbmpl.e"
43 #include "tdgtbrow.e"
44 #include "tdgtbtn.e"
45 #include "tdgtdraw.e"
46 #include "tdgtsedt.e"
47 #include "tdgtlist.e"
48 #include "tdgtmsg.e"
49 #include "text.e"
50 #include "tidget.e"
51 #include "tgtwb5dl.e"
52 #include "tgtwb5xl.e"
53 #include "util.e"
54 #include "xbitmap.e"
55 
56 ZyfhInfo gZyfhInfo;
57 
58 typedef struct tagZyfhDlgInfo {
59    Window parent_win; /* should be the rootWindow */
60 
61    TdgtMsg *msg_ctl;
62    TdgtDraw *zyfh_ctl; /* the zhu-yin-fu-hao keypad */
63    TdgtDraw *zyfh_dpy_ctl; /* displays what has been entered */
64    TdgtSmplEdit *edit_ctl;
65    TdgtBmpList *bmp_list_ctl;
66    TdgtBtnRow *btn_row_ctl;
67 
68    int screen_w, screen_h;
69    int base_win_w, base_win_h;
70    int msg_x, msg_y, msg_w, msg_h;
71    int zyfh_dpy_x, zyfh_dpy_y, zyfh_dpy_w, zyfh_dpy_h;
72    int zyfh_x, zyfh_y, zyfh_w, zyfh_h;
73    int edit_x, edit_y, edit_w, edit_h;
74    int bmp_list_x, bmp_list_y, bmp_list_w, bmp_list_h;
75    int btn_row_x, btn_row_y, btn_row_w, btn_row_h;
76 
77    char **entries;
78    int num_entries;
79    int first_index;
80    int marked_index;
81    DspList *dsp_ptr;
82 
83    char *title_str, *formatted_title_str;
84    int def_btn_id, double_click_btn_id;
85 
86    Time last_click_time;
87    int last_selected;
88    int just_fetched;
89    int english_spelling; /* TRUE means pinyin, FALSE means zhu-yin-fu-hao */
90    int zyfh_spell_index;
91    int zyfh_spell_buf[MAXZYFH_CHARS+1]; /* each char is one of PH_* */
92 } ZyfhDlgInfo;
93 
94 /* --------------------- Utility Functions --------------------- */
95 
96 typedef struct tagZyfhDpyAppendInfo {
97    TdgtBase *base_ctl;
98    int row, col; /* position in zyfh_ctl */
99 } ZyfhDpyAppendInfo;
100 
101 #define TDGTARG_ZYFH_DPY_CLEAR 1 /* pv_cmd_userdata is NULL */
102 #define TDGTARG_ZYFH_DPY_APPEND 2 /* pv_cmd_userdata is (ZyfhDpyAppendInfo*) */
103 
104 static
ClearAllControls(pTdgtBase)105 void ClearAllControls(pTdgtBase)
106    TdgtBase *pTdgtBase;
107 {
108    ZyfhDlgInfo *pzdi=(ZyfhDlgInfo*)(pTdgtBase->pti->userdata);
109 
110    pzdi->last_selected = INVALID;
111    pzdi->just_fetched = FALSE;
112    pzdi->zyfh_spell_index = 0;
113    memset(pzdi->zyfh_spell_buf, 0, sizeof(pzdi->zyfh_spell_buf));
114 
115    TidgetSendCmd(pzdi->zyfh_dpy_ctl->pti, TDGTCMD_DRAW_USER,
116          TDGTARG_ZYFH_DPY_CLEAR, pTdgtBase);
117    TdgtSmplEditSetText(pzdi->edit_ctl, "");
118    TidgetSendCmd(pzdi->bmp_list_ctl->pti, TDGTCMD_LIST_RESETCONTENT, 0, NULL);
119 }
120 
121 static
SendSelectedCharToClient(pTdgtBase)122 int SendSelectedCharToClient(pTdgtBase)
123    TdgtBase *pTdgtBase;
124 {
125    ZyfhDlgInfo *pzdi=(ZyfhDlgInfo*)(pTdgtBase->pti->userdata);
126    int selected_index=INVALID;
127    BmpListItemInfo *pblii=NULL;
128 
129    TidgetSendCmd(pzdi->bmp_list_ctl->pti, TDGTCMD_LIST_GETCURSEL, 0,
130          &selected_index);
131    if (TidgetSendCmd(pzdi->bmp_list_ctl->pti, TDGTCMD_LIST_GETITEM,
132          selected_index, &pblii)) {
133       if (pblii != NULL) {
134          XKeyEvent key_ev;
135          int has_ch=2;
136          char buf[3];
137          XChar2b *pch16=(XChar2b*)(pblii->pv_userdata);
138 
139          memset(&key_ev, 0, sizeof(XKeyEvent));
140          buf[0] = pch16->byte1;
141          buf[1] = pch16->byte2;
142          buf[2] = '\0';
143          HandleTextFromBuffer(&key_ev, buf, (KeySym)0, has_ch);
144 
145          return TRUE;
146       }
147    }
148    return FALSE;
149 }
150 
151 static
SendCRToClient(pTdgtBase)152 int SendCRToClient(pTdgtBase)
153    TdgtBase *pTdgtBase;
154 {
155    XKeyEvent key_ev;
156    int has_ch=1;
157    char buf[2];
158 
159    memset(&key_ev, 0, sizeof(XKeyEvent));
160    buf[0] = '\n';
161    buf[1] = '\0';
162    HandleTextFromBuffer(&key_ev, buf, (KeySym)0, has_ch);
163 
164    return TRUE;
165 }
166 
167 static
InvalidSequence(pTdgtBase)168 int InvalidSequence(pTdgtBase)
169    TdgtBase *pTdgtBase;
170 {
171    ZyfhDlgInfo *pzdi=(ZyfhDlgInfo*)(pTdgtBase->pti->userdata);
172 
173    if (pzdi->zyfh_spell_index == 4 &&
174          (pzdi->zyfh_spell_buf[0] == PH_L || pzdi->zyfh_spell_buf[0] == PH_N) &&
175          pzdi->zyfh_spell_buf[1] == PH_Yu && pzdi->zyfh_spell_buf[3] < PH_Er &&
176          pzdi->zyfh_spell_buf[2] != PH_Eh) {
177       return TRUE;
178    }
179    return FALSE;
180 }
181 
182 static
Fill2ByteCharFromHexStringBuf(buf,pch16)183 int Fill2ByteCharFromHexStringBuf(buf, pch16)
184    char *buf;
185    XChar2b *pch16;
186 {
187    int hi_nibble=0, lo_nibble=0, hval=0;
188 
189    if (IsHex(buf[0], &hi_nibble) && IsHex(buf[1], &lo_nibble)) {
190       hval = (((hi_nibble&0x0ff)<<4)+(lo_nibble&0x0ff));
191       pch16->byte1 = hval;
192       if (IsHex(buf[2], &hi_nibble) && IsHex(buf[3], &lo_nibble)) {
193          hval = (((hi_nibble&0x0ff)<<4)+(lo_nibble&0x0ff));
194          pch16->byte2 = hval;
195       } else {
196          return FALSE;
197       }
198    } else {
199       return FALSE;
200    }
201    return TRUE;
202 }
203 
204 static
FreeBitmapItemCallback(pblii)205 void FreeBitmapItemCallback(pblii)
206    BmpListItemInfo *pblii;
207 {
208    if (pblii == NULL) return;
209 
210    if (pblii->pixmap != None) XFreePixmap(mainDisplay, pblii->pixmap);
211    if (pblii->pv_userdata != NULL) {
212       /* XChar2b */
213       free(pblii->pv_userdata);
214    }
215    free(pblii);
216 }
217 
218 #ifdef NOT_DEFINED /* debug, do not translate */
219 static
DebugCharBitmap(bitmap,w,h)220 void DebugCharBitmap(bitmap, w, h)
221    Pixmap bitmap;
222    int w, h;
223 {
224    static int n=0;
225    int r=0, c=0;
226    XImage *image=XGetImage(mainDisplay, bitmap, 0, 0, w,
227          h, 1, ZPixmap);
228 
229    fprintf(stdout, "Character %1d:\n", ++n);
230    for (r=0; r < h; r++) {
231       fprintf(stdout, "    ");
232       for (c=0; c < w; c++) {
233          if (XGetPixel(image, (int)c, (int)r) == 1) {
234             fprintf(stdout, "%1d", 1);
235          } else {
236             fprintf(stdout, "%1d", 0);
237          }
238       }
239       fprintf(stdout, "\n");
240    }
241    XDestroyImage(image);
242 }
243 
DrawAndDebugChar()244 void DrawAndDebugChar()
245 {
246    XChar2b str16;
247    XGCValues values;
248    GC tmp_gc;
249    Pixmap bitmap=XCreatePixmap(mainDisplay, mainWindow, gZyfhInfo.b5_font_w,
250          gZyfhInfo.b5_font_h, 1);
251 
252    values.foreground = 1;
253    values.background = 0;
254    values.fill_style = FillSolid;
255    values.function = GXcopy;
256    values.font = gZyfhInfo.xfs->fid;
257    tmp_gc = XCreateGC(mainDisplay, bitmap,
258          GCForeground | GCBackground | GCFillStyle | GCFunction | GCFont,
259          &values);
260 
261    XSetForeground(mainDisplay, tmp_gc, 0);
262    XFillRectangle(mainDisplay, bitmap, tmp_gc, 0, 0, gZyfhInfo.b5_font_w,
263          gZyfhInfo.b5_font_h);
264    XSetForeground(mainDisplay, tmp_gc, 1);
265 
266    switch (gZyfhInfo.b5_font_real_encoding) {
267    case GB_ENCODING:
268       str16.byte1 = 0xb9 & 0x7f;
269       str16.byte2 = 0xfa & 0x7f;
270       break;
271    case BIG5_ENCODING:
272       str16.byte1 = 0xa4;
273       str16.byte2 = 0xad;
274       break;
275    }
276    XDrawString16(mainDisplay, bitmap, tmp_gc, 0, gZyfhInfo.b5_font_asc,
277          &str16, 1);
278 
279    DebugCharBitmap(bitmap, gZyfhInfo.b5_font_w, gZyfhInfo.b5_font_h);
280 
281    XFreeGC(mainDisplay, tmp_gc);
282    XFreePixmap(mainDisplay, bitmap);
283 }
284 #endif /* NOT_DEFINED */
285 
286 static
DoLoadChars(pTdgtBase,buf,str16,num_char2bs)287 int DoLoadChars(pTdgtBase, buf, str16, num_char2bs)
288    TdgtBase *pTdgtBase;
289    char *buf;
290    XChar2b *str16;
291    int num_char2bs;
292 {
293    ZyfhDlgInfo *pzdi=(ZyfhDlgInfo*)(pTdgtBase->pti->userdata);
294    int i=0, redraw_disabled=FALSE;
295 
296    TidgetSendCmd(pzdi->bmp_list_ctl->pti, TDGTCMD_LIST_RESETCONTENT, 0, NULL);
297 
298    redraw_disabled = TidgetDisableRedraw(pzdi->bmp_list_ctl->pti, TRUE);
299    for (i=0; i < num_char2bs; i++) {
300       XGCValues values;
301       Pixmap bitmap=None;
302       BmpListItemInfo *pblii=NULL;
303       XChar2b *pch16=NULL;
304       XChar2b str16_buf;
305 
306       bitmap = XCreatePixmap(mainDisplay, mainWindow, gZyfhInfo.b5_font_w,
307             gZyfhInfo.b5_font_h, 1);
308       if (bitmap == None) {
309          FailAllocPixmapMessage(gZyfhInfo.b5_font_w, gZyfhInfo.b5_font_h);
310       }
311       XSetForeground(mainDisplay, rotateGC, 0);
312       XFillRectangle(mainDisplay, bitmap, rotateGC, 0, 0, gZyfhInfo.b5_font_w,
313             gZyfhInfo.b5_font_h);
314 
315       values.foreground = 1;
316       values.font = gZyfhInfo.xfs->fid;
317       XChangeGC(mainDisplay, rotateGC, GCForeground | GCFont, &values);
318 
319       if (gZyfhInfo.b5_font_mod_bytes) {
320          str16_buf.byte1 = str16[i].byte1 & 0x7f;
321          str16_buf.byte2 = str16[i].byte2 & 0x7f;
322       } else {
323          str16_buf.byte1 = str16[i].byte1;
324          str16_buf.byte2 = str16[i].byte2;
325       }
326       XDrawString16(mainDisplay, bitmap, rotateGC, 0, gZyfhInfo.b5_font_asc,
327             &str16_buf, 1);
328 
329 #ifdef NOT_DEFINED
330       DebugCharBitmap(bitmap, gZyfhInfo.b5_font_w, gZyfhInfo.b5_font_h);
331 #endif /* NOT_DEFINED */
332 
333       pch16 = (XChar2b*)malloc(sizeof(XChar2b));
334       if (pch16 == NULL) FailAllocMessage();
335       memset(pch16, 0, sizeof(XChar2b));
336       memcpy(pch16, &str16[i], sizeof(XChar2b));
337 
338       pblii = (BmpListItemInfo*)malloc(sizeof(BmpListItemInfo));
339       if (pblii == NULL) FailAllocMessage();
340       memset(pblii, 0, sizeof(BmpListItemInfo));
341 
342       pblii->pixmap = bitmap;
343       pblii->depth = 1;
344       pblii->width = gZyfhInfo.b5_font_w;
345       pblii->height = gZyfhInfo.b5_font_h;
346       pblii->pv_userdata = pch16;
347       pblii->pf_free_callback = FreeBitmapItemCallback;
348 
349       if (!TdgtBmpListAddItem(pzdi->bmp_list_ctl, pblii)) {
350       }
351    }
352    TidgetDisableRedraw(pzdi->bmp_list_ctl->pti, redraw_disabled);
353 
354    return TRUE;
355 }
356 
357 #define MAX_PINYIN_ET_BIG5_STR 628
358 #define MAX_BIG5_STR (MAX_PINYIN_ET_BIG5_STR>>2)
359 
360 static
LoadChars(pTdgtBase,buf)361 int LoadChars(pTdgtBase, buf)
362    TdgtBase *pTdgtBase;
363    char *buf;
364 {
365    ZyfhDlgInfo *pzdi=(ZyfhDlgInfo*)(pTdgtBase->pti->userdata);
366    int len=0, str16_index=0, ok=TRUE;
367    char *psz=NULL, **ppsz=NULL, *psz_found=NULL;
368    XChar2b str16[MAX_BIG5_STR+1];
369 
370    if (!pzdi->english_spelling && InvalidSequence(pTdgtBase)) {
371       sprintf(gszMsgBox, TgLoadString(STID_INVALID_PINYIN_SEQ), buf);
372       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
373       return FALSE;
374    }
375    switch (gZyfhInfo.b5_font_real_encoding) {
376    case GB_ENCODING:
377       for (ppsz=pinyin_gb2312; *ppsz!=NULL; ppsz++) {
378          if (strcmp(*ppsz, buf) == 0) {
379             psz_found = (*(++ppsz));
380             break;
381          }
382          ppsz++;
383       }
384       break;
385    case BIG5_ENCODING:
386       for (ppsz=pinyin_et_big5; *ppsz!=NULL; ppsz++) {
387          if (strcmp(*ppsz, buf) == 0) {
388             psz_found = (*(++ppsz));
389             break;
390          }
391          ppsz++;
392       }
393       break;
394    default: return FALSE;
395    }
396    if (psz_found == NULL) {
397       sprintf(gszMsgBox, TgLoadString(STID_INVALID_PINYIN_SEQ), buf);
398       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
399       return FALSE;
400    }
401    len = strlen(psz_found);
402 #ifdef _TGIF_DBG /* debug, do not translate */
403    if (len > MAX_PINYIN_ET_BIG5_STR) {
404       sprintf(gszMsgBox, "Fetched hexstring in LoadChars() is too long: %1d (limit is %1d).\n",
405             len, MAX_PINYIN_ET_BIG5_STR);
406       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
407       return FALSE;
408    }
409 #endif /* _TGIF_DBG */
410    for (psz=psz_found; ok && *psz != '\0'; psz=(&psz[4])) {
411       if (Fill2ByteCharFromHexStringBuf(psz, &str16[str16_index])) {
412          str16_index++;
413       } else {
414          ok = FALSE;
415       }
416    }
417    memset(&str16[str16_index], 0, sizeof(XChar2b));
418 
419 #ifdef _TGIF_DBG /* debug, do not translate */
420    if (!ok) {
421       switch (gZyfhInfo.b5_font_real_encoding) {
422       case GB_ENCODING:
423          sprintf(gszMsgBox, "The pinyin_gb2312[] table seems to be corrupted.\n");
424          break;
425       case BIG5_ENCODING:
426          sprintf(gszMsgBox, "The pinyin_et_big5[] table seems to be corrupted.\n");
427          break;
428       }
429       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
430       return FALSE;
431    }
432 #endif /* _TGIF_DBG */
433 
434    return DoLoadChars(pTdgtBase, buf, str16, str16_index);
435 }
436 
437 static
FetchChars(pTdgtBase)438 int FetchChars(pTdgtBase)
439    TdgtBase *pTdgtBase;
440 {
441    ZyfhDlgInfo *pzdi=(ZyfhDlgInfo*)(pTdgtBase->pti->userdata);
442    char *buf=UtilStrDup(TdgtSmplEditGetText(pzdi->edit_ctl));
443 
444    if (buf != NULL && *buf != '\0') {
445       char saved_ch='\0';
446       int ok=FALSE;
447 
448       if (buf[0] >= 'a' && buf[0] <= 'z') {
449          saved_ch = buf[0];
450          buf[0] = buf[0]-'a'+'A';
451       }
452       ok = LoadChars(pTdgtBase, buf);
453       if (saved_ch != '\0') buf[0] = saved_ch;
454    }
455    pzdi->just_fetched = TRUE;
456    pzdi->last_selected = INVALID;
457 
458    UtilFree(buf);
459 
460    return FALSE;
461 }
462 
463 static
ReverseZhuYenFuHao(index,pn_symbol_ltx,pn_symbol_lty)464 void ReverseZhuYenFuHao(index, pn_symbol_ltx, pn_symbol_lty)
465    int index, *pn_symbol_ltx, *pn_symbol_lty;
466    /*
467     * Given an index obtained from pzdi->zyfh_spell_buf[x], calculate
468     *         the ltx and lty of a bitmap from the zhfh_ctl.
469     */
470 {
471    if (pn_symbol_lty != NULL) {
472       *pn_symbol_lty = (index % (gZyfhInfo.zyfh_num_rows)) *
473             (gZyfhInfo.zyfh_image_wh);
474    }
475    if (pn_symbol_ltx != NULL) {
476       *pn_symbol_ltx = ((int)(index / gZyfhInfo.zyfh_num_rows)) *
477             (gZyfhInfo.zyfh_image_wh);
478    }
479 }
480 
481 static
ComposePinYin(pTdgtBase,buf,buf_sz)482 int ComposePinYin(pTdgtBase, buf, buf_sz)
483    TdgtBase *pTdgtBase;
484    char *buf;
485    int buf_sz;
486 {
487    ZyfhDlgInfo *pzdi=(ZyfhDlgInfo*)(pTdgtBase->pti->userdata);
488    int i=0;
489 
490    if (buf_sz < MAXZYFH_CHARS+1) return FALSE;
491 
492    *buf = '\0';
493    for (i=0; i < pzdi->zyfh_spell_index; i++) {
494       switch (i) {
495       case 0:
496          if (pzdi->zyfh_spell_index >= 2 && pzdi->zyfh_spell_buf[0] == PH_Yu &&
497                pzdi->zyfh_spell_buf[1] == PH_Eng) {
498             strcat (buf, "Yo");
499          } else {
500             strcpy(buf, firstLargeTransTbl[pzdi->zyfh_spell_buf[0]]);
501             if (pzdi->zyfh_spell_index == 2 &&
502                   pzdi->zyfh_spell_buf[1] < PH_Er) {
503                strcat(buf, singleExtention[pzdi->zyfh_spell_buf[0]]);
504             }
505          }
506          break;
507       case 1:
508          if (pzdi->zyfh_spell_index >= 3 && pzdi->zyfh_spell_buf[1] == PH_W &&
509                pzdi->zyfh_spell_buf[2] == PH_Eng) {
510             strcat(buf, "o");
511          } else if (pzdi->zyfh_spell_index >= 3 &&
512                pzdi->zyfh_spell_buf[1] == PH_Yu &&
513                pzdi->zyfh_spell_buf[2] == PH_Eng) {
514             strcat(buf, "io");
515          } else if (pzdi->zyfh_spell_index >= 2 &&
516                pzdi->zyfh_spell_buf[0] == PH_Yu &&
517                pzdi->zyfh_spell_buf[1] == PH_Eng) {
518             strcat(buf, "ng");
519          } else if (pzdi->zyfh_spell_index >= 2 &&
520                pzdi->zyfh_spell_buf[0] == PH_Y &&
521                pzdi->zyfh_spell_buf[1] == PH_En) {
522             strcat(buf, "in");
523          } else if (pzdi->zyfh_spell_index >= 2 &&
524                pzdi->zyfh_spell_buf[0] == PH_Y &&
525                pzdi->zyfh_spell_buf[1] == PH_Eng) {
526             strcat(buf, "ing");
527          } else {
528             strcat(buf, secondLargeTransTbl[pzdi->zyfh_spell_buf[i]]);
529          }
530          break;
531       case 2:
532          if (pzdi->zyfh_spell_index == 3 && pzdi->zyfh_spell_buf[2] < PH_Er &&
533                pzdi->zyfh_spell_buf[1] == PH_Yu &&
534                (pzdi->zyfh_spell_buf[0] == PH_L ||
535                pzdi->zyfh_spell_buf[0] == PH_N)) {
536             strcat(buf, ":");
537          }
538          strcat(buf, thirdLargeTransTbl[pzdi->zyfh_spell_buf[i]]);
539          break;
540       case 3:
541          if (pzdi->zyfh_spell_index == 4 && pzdi->zyfh_spell_buf[3] < PH_Er &&
542                pzdi->zyfh_spell_buf[2] == PH_Eh &&
543                pzdi->zyfh_spell_buf[1] == PH_Yu &&
544                (pzdi->zyfh_spell_buf[0] == PH_L ||
545                pzdi->zyfh_spell_buf[0] == PH_N)) {
546             strcat(buf, ":");
547          }
548          strcat(buf, fourthLargeTransTbl[pzdi->zyfh_spell_buf[i]]);
549          break;
550       }
551    }
552    return TRUE;
553 }
554 
555 static
UpdateSpellingAndDpyControls(pTdgtBase)556 void UpdateSpellingAndDpyControls(pTdgtBase)
557    TdgtBase *pTdgtBase;
558 {
559    ZyfhDlgInfo *pzdi=(ZyfhDlgInfo*)(pTdgtBase->pti->userdata);
560    char buf[MAXZYFH_CHARS+1];
561    int fetch_immediately=FALSE;
562 
563    if (ComposePinYin(pTdgtBase, buf, sizeof(buf))) {
564       int len=strlen(buf);
565 
566       TdgtSmplEditSetText(pzdi->edit_ctl, buf);
567       if (!pzdi->english_spelling && pzdi->zyfh_spell_index == 1 &&
568             (strcmp(buf, "Punctuations") == 0 || strcmp(buf, "Symbols") == 0)) {
569          fetch_immediately = TRUE;
570       } else if (len > 0 && buf[len-1] >= '1' && buf[len-1] <= '5') {
571          fetch_immediately = TRUE;
572       }
573    }
574    RedrawTidget(pzdi->zyfh_dpy_ctl->pti);
575 
576    if (fetch_immediately) {
577       FetchChars(pTdgtBase);
578    }
579 }
580 
581 static
HandleBackSpace(pTdgtBase)582 int HandleBackSpace(pTdgtBase)
583    TdgtBase *pTdgtBase;
584 {
585    ZyfhDlgInfo *pzdi=(ZyfhDlgInfo*)(pTdgtBase->pti->userdata);
586 
587    if (pzdi->english_spelling) {
588       if (TdgtSmplEditDelLastChar(pzdi->edit_ctl)) {
589          pzdi->just_fetched = FALSE;
590          pzdi->zyfh_spell_index--;
591          pzdi->last_selected = INVALID;
592          TidgetSendCmd(pzdi->bmp_list_ctl->pti, TDGTCMD_LIST_RESETCONTENT, 0,
593                NULL);
594       } else {
595          /* no change */
596       }
597    } else {
598       if (pzdi->zyfh_spell_index > 0) {
599          pzdi->just_fetched = FALSE;
600          pzdi->zyfh_spell_index--;
601          pzdi->last_selected = INVALID;
602          UpdateSpellingAndDpyControls(pTdgtBase);
603          TidgetSendCmd(pzdi->bmp_list_ctl->pti, TDGTCMD_LIST_RESETCONTENT, 0,
604                NULL);
605       } else {
606          /* no change */
607       }
608    }
609    return FALSE;
610 }
611 
612 /* --------------------- ZyfhRedrawCallback --------------------- */
613 
614 static
ZyfhRedrawCallback(pTdgtDraw)615 int ZyfhRedrawCallback(pTdgtDraw)
616    TdgtDraw *pTdgtDraw;
617 {
618    XGCValues values;
619 
620    if (pTdgtDraw == NULL) return FALSE;
621 
622    values.fill_style = FillOpaqueStippled;
623    values.ts_x_origin = pTdgtDraw->client_area.x;
624    values.ts_y_origin = pTdgtDraw->client_area.y;
625    values.stipple = gZyfhInfo.zyfh_bitmap;
626    XChangeGC(mainDisplay, gTidgetManager.gc,
627          GCFillStyle | GCTileStipXOrigin | GCTileStipYOrigin | GCStipple,
628          &values);
629 
630    XFillRectangle(mainDisplay, pTdgtDraw->pti->tci.win, gTidgetManager.gc,
631          pTdgtDraw->client_area.x, pTdgtDraw->client_area.y,
632          pTdgtDraw->client_area.w, pTdgtDraw->client_area.h);
633 
634    TidgetManagerResetGC();
635 
636    return TRUE;
637 }
638 
639 /* --------------------- ZyfhEvHandlerCallback() --------------------- */
640 
641 static
GetZhuYenFuHao(pTdgtDraw,button_x,button_y,pn_symbol_ltx,pn_symbol_lty)642 int GetZhuYenFuHao(pTdgtDraw, button_x, button_y, pn_symbol_ltx, pn_symbol_lty)
643    TdgtDraw *pTdgtDraw;
644    int button_x, button_y, *pn_symbol_ltx, *pn_symbol_lty;
645 {
646    struct BBRec bbox;
647    int x=0, y=0, row=0, col=0;
648 
649    bbox.ltx = pTdgtDraw->client_area.x;
650    bbox.lty = pTdgtDraw->client_area.y;
651    bbox.rbx = pTdgtDraw->client_area.x + pTdgtDraw->client_area.w;
652    bbox.rby = pTdgtDraw->client_area.y + pTdgtDraw->client_area.h;
653 
654    if (!PointInBBox(button_x, button_y, bbox)) return INVALID;
655 
656    x = button_x-pTdgtDraw->client_area.x;
657    y = button_y-pTdgtDraw->client_area.y;
658    row = (int)(y/gZyfhInfo.zyfh_image_wh);
659    col = (int)(x/gZyfhInfo.zyfh_image_wh);
660 
661    if (pn_symbol_ltx != NULL) {
662       *pn_symbol_ltx = col*gZyfhInfo.zyfh_image_wh + pTdgtDraw->client_area.x;
663    }
664    if (pn_symbol_lty != NULL) {
665       *pn_symbol_lty = row*gZyfhInfo.zyfh_image_wh + pTdgtDraw->client_area.y;
666    }
667    return ((col*gZyfhInfo.zyfh_num_rows)+row);
668 }
669 
670 static
ClickInZyfh(pTdgtDraw,button_ev)671 int ClickInZyfh(pTdgtDraw, button_ev)
672    TdgtDraw *pTdgtDraw;
673    XButtonEvent *button_ev;
674 {
675    TdgtBase *pTdgtBase=
676          (TdgtBase*)(pTdgtDraw->pti->tci.parent_tidgetinfo->tidget);
677    ZyfhDlgInfo *pzdi=(ZyfhDlgInfo*)(pTdgtBase->pti->userdata);
678    int down_ltx=0, down_lty=0, down_index=0, inside=TRUE, highlighted=TRUE;
679    char *psz=NULL;
680 
681    down_index = GetZhuYenFuHao(pTdgtDraw, button_ev->x, button_ev->y,
682          &down_ltx, &down_lty);
683    if (down_index == INVALID) return FALSE;
684 
685    switch (pzdi->zyfh_spell_index) {
686    case 0: psz=firstLargeTransTbl[down_index]; break;
687    case 1: psz=secondLargeTransTbl[down_index]; break;
688    case 2: psz=thirdLargeTransTbl[down_index]; break;
689    case 3: psz=fourthLargeTransTbl[down_index]; break;
690    }
691    if (*psz != '\0') {
692       /* clicked on a symbol */
693       XFillRectangle(mainDisplay, pTdgtDraw->pti->tci.win, revDefaultGC,
694             down_ltx, down_lty, gZyfhInfo.zyfh_image_wh,
695             gZyfhInfo.zyfh_image_wh);
696       if (!debugNoPointerGrab) {
697          XGrabPointer(mainDisplay, pTdgtDraw->pti->tci.win, FALSE,
698                PointerMotionMask | ButtonReleaseMask, GrabModeAsync,
699                GrabModeAsync, None, defaultCursor, CurrentTime);
700       }
701       while (TRUE) {
702          XEvent xev;
703 
704          XNextEvent(mainDisplay, &xev);
705          if (xev.type == Expose) {
706             ExposeEventHandler(&xev, FALSE);
707          } else if (xev.type == ButtonRelease) {
708             int up_index=0, up_ltx=0, up_lty=0;
709 
710             XUngrabPointer(mainDisplay, CurrentTime);
711             XSync(mainDisplay, False);
712             up_index = GetZhuYenFuHao(pTdgtDraw, xev.xbutton.x, xev.xbutton.y,
713                   &up_ltx, &up_lty);
714             if (up_index == down_index) {
715                if (highlighted) {
716                   XFillRectangle(mainDisplay, pTdgtDraw->pti->tci.win,
717                         revDefaultGC, down_ltx, down_lty,
718                         gZyfhInfo.zyfh_image_wh, gZyfhInfo.zyfh_image_wh);
719                   highlighted = FALSE;
720                }
721                pzdi->zyfh_spell_buf[pzdi->zyfh_spell_index++] = down_index;
722                UpdateSpellingAndDpyControls(pTdgtBase);
723             }
724             break;
725          } else if (xev.type == MotionNotify) {
726             int mouse_index=0, mouse_ltx=0, mouse_lty=0;
727             XEvent tmp_xev;
728 
729             while (XCheckMaskEvent(mainDisplay, PointerMotionMask, &tmp_xev)) ;
730 
731             mouse_index = GetZhuYenFuHao(pTdgtDraw, xev.xmotion.x,
732                   xev.xmotion.y, &mouse_ltx, &mouse_lty);
733             if (inside) {
734                if (mouse_index != down_index) {
735                   XFillRectangle(mainDisplay, pTdgtDraw->pti->tci.win,
736                         revDefaultGC, down_ltx, down_lty,
737                         gZyfhInfo.zyfh_image_wh, gZyfhInfo.zyfh_image_wh);
738                   highlighted = !highlighted;
739                   inside = FALSE;
740                }
741             } else {
742                if (mouse_index == down_index) {
743                   XFillRectangle(mainDisplay, pTdgtDraw->pti->tci.win,
744                         revDefaultGC, down_ltx, down_lty,
745                         gZyfhInfo.zyfh_image_wh, gZyfhInfo.zyfh_image_wh);
746                   highlighted = !highlighted;
747                   inside = TRUE;
748                }
749             }
750          }
751       }
752    }
753    return FALSE;
754 }
755 
756 static
ZyfhEvHandlerCallback(pTdgtDraw,pXEv)757 int ZyfhEvHandlerCallback(pTdgtDraw, pXEv)
758    TdgtDraw *pTdgtDraw;
759    XEvent *pXEv;
760 {
761    if (pXEv->xany.window == pTdgtDraw->pti->tci.win) {
762       static char ppsz_buf[MAX_STATUS_BTNS+1][MAXSTRING+1];
763       static int one_line_status=TRUE;
764 
765       if (pXEv->type == EnterNotify) {
766          SaveStatusStringsIntoBuf(ppsz_buf, &one_line_status);
767          SetMouseStatus(TgLoadString(STID_ADD_ZYFH),
768                TgLoadString(STID_FETCH_CHAR), TgLoadString(STID_BACKOUT_ZYFH));
769       } else if (pXEv->type == LeaveNotify) {
770          RestoreStatusStringsFromBuf(ppsz_buf, one_line_status);
771       } else if (pXEv->type == ButtonPress) {
772          XButtonEvent *button_ev=(&(pXEv->xbutton));
773          TdgtBase *pTdgtBase=
774                (TdgtBase*)(pTdgtDraw->pti->tci.parent_tidgetinfo->tidget);
775          ZyfhDlgInfo *pzdi=(ZyfhDlgInfo*)(pTdgtBase->pti->userdata);
776 
777          switch (button_ev->button) {
778          case Button1:
779             if (pzdi->english_spelling) {
780                pzdi->english_spelling = FALSE;
781                pzdi->zyfh_spell_index = 0;
782             }
783             if (pzdi->just_fetched) {
784                ClearAllControls(pTdgtBase);
785             }
786             if (pzdi->zyfh_spell_index >= MAXZYFH_CHARS) {
787                XBell(mainDisplay, 0);
788             } else {
789                return ClickInZyfh(pTdgtDraw, button_ev);
790             }
791             break;
792          case Button2:
793             if (pzdi->just_fetched) {
794                return SendSelectedCharToClient(pTdgtBase);
795             } else {
796                return FetchChars(pTdgtBase);
797             }
798             break;
799          case Button3:
800             return HandleBackSpace(pTdgtBase);
801          }
802       }
803    }
804    return FALSE;
805 }
806 
807 /* --------------------- ZyfhDpyRedrawCallback --------------------- */
808 
809 static
ZyfhDpyRedrawCallback(pTdgtDraw)810 int ZyfhDpyRedrawCallback(pTdgtDraw)
811    TdgtDraw *pTdgtDraw;
812    /* redraw the vertical display area on the left top area */
813 {
814    TdgtBase *pTdgtBase=
815          (TdgtBase*)(pTdgtDraw->pti->tci.parent_tidgetinfo->tidget);
816    ZyfhDlgInfo *pzdi=(ZyfhDlgInfo*)(pTdgtBase->pti->userdata);
817 
818    if (pTdgtDraw == NULL) return FALSE;
819 
820    if (pzdi->english_spelling) {
821       /* leave it blank if pinyin is used */
822    } else {
823       int i=0, x=pTdgtDraw->client_area.x, y=pTdgtDraw->client_area.y;
824 
825       if (pzdi->zyfh_spell_index == 0) return FALSE;
826 
827       for (i=0; i < pzdi->zyfh_spell_index; i++, y+=gZyfhInfo.zyfh_image_wh) {
828          int src_x=0, src_y=0;
829          XGCValues values;
830 
831          values.fill_style = FillSolid;
832          values.function = GXcopy;
833          XChangeGC(mainDisplay, gTidgetManager.gc, GCFillStyle | GCFunction,
834                &values);
835 
836          ReverseZhuYenFuHao(pzdi->zyfh_spell_buf[i], &src_x, &src_y);
837          XCopyArea(mainDisplay, gZyfhInfo.zyfh_bitmap, gZyfhInfo.symbol_bitmap,
838                xbmGC, src_x, src_y,
839                gZyfhInfo.zyfh_image_wh, gZyfhInfo.zyfh_image_wh, 0, 0);
840 
841          values.fill_style = FillStippled;
842          values.ts_x_origin = x;
843          values.ts_y_origin = y;
844          values.stipple = gZyfhInfo.symbol_bitmap;
845          XChangeGC (mainDisplay, gTidgetManager.gc,
846                GCFillStyle | GCTileStipXOrigin | GCTileStipYOrigin | GCStipple,
847                &values);
848 
849          XFillRectangle(mainDisplay, pTdgtDraw->pti->tci.win,
850                gTidgetManager.gc, x, y,
851                gZyfhInfo.zyfh_image_wh, gZyfhInfo.zyfh_image_wh);
852 
853          TidgetManagerResetGC();
854       }
855    }
856    return TRUE;
857 }
858 
859 /* --------------------- ZyfhDpySendCmdCallback --------------------- */
860 
861 static
ZyfhDpySendCmdCallback(pTdgtDraw,cmd_type,cmd_arg,pv_cmd_userdata)862 int ZyfhDpySendCmdCallback(pTdgtDraw, cmd_type, cmd_arg, pv_cmd_userdata)
863    TdgtDraw *pTdgtDraw;
864    int cmd_type, cmd_arg;
865    void *pv_cmd_userdata;
866 {
867    TdgtBase *pTdgtBase=NULL;
868    ZyfhDlgInfo *pzdi=NULL;
869 
870    switch (cmd_type) {
871    case TDGTCMD_DRAW_USER:
872       switch (cmd_arg) {
873       case TDGTARG_ZYFH_DPY_CLEAR:
874          pTdgtBase = (TdgtBase*)pv_cmd_userdata;
875          pzdi = (ZyfhDlgInfo*)(pTdgtBase->pti->userdata);
876          /* clear it */
877          RedrawTidget(pzdi->zyfh_dpy_ctl->pti);
878          break;
879       case TDGTARG_ZYFH_DPY_APPEND:
880          break;
881       }
882       break;
883    }
884    return FALSE;
885 }
886 
887 /* ------------------- Tdgtb5DlgKeyPressEvHandlerCallback ------------------- */
888 
889 static
HandleCursorKey(pTdgtBase,key_sym)890 int HandleCursorKey(pTdgtBase, key_sym)
891    TdgtBase *pTdgtBase;
892    KeySym key_sym;
893 {
894    ZyfhDlgInfo *pzdi=(ZyfhDlgInfo*)(pTdgtBase->pti->userdata);
895    int cmd_arg=0;
896 
897    switch (key_sym) {
898    case XK_Up: cmd_arg=TDGTARG_MOVE_UP; break;
899    case XK_KP_Up: cmd_arg=TDGTARG_MOVE_UP; break;
900    case XK_Down: cmd_arg=TDGTARG_MOVE_DOWN; break;
901    case XK_KP_Down: cmd_arg=TDGTARG_MOVE_DOWN; break;
902    case XK_Left: cmd_arg=TDGTARG_MOVE_LEFT; break;
903    case XK_KP_Left: cmd_arg=TDGTARG_MOVE_LEFT; break;
904    case XK_Right: cmd_arg=TDGTARG_MOVE_RIGHT; break;
905    case XK_KP_Right: cmd_arg=TDGTARG_MOVE_RIGHT; break;
906    default:
907       switch (key_sym & 0x0ff) {
908       case 'n': cmd_arg=TDGTARG_MOVE_RIGHT; break;
909       case 'N': cmd_arg=TDGTARG_MOVE_RIGHT; break;
910       case 'f': cmd_arg=TDGTARG_MOVE_RIGHT; break;
911       case 'F': cmd_arg=TDGTARG_MOVE_RIGHT; break;
912       case 'p': cmd_arg=TDGTARG_MOVE_LEFT; break;
913       case 'P': cmd_arg=TDGTARG_MOVE_LEFT; break;
914       case 'b': cmd_arg=TDGTARG_MOVE_LEFT; break;
915       case 'B': cmd_arg=TDGTARG_MOVE_LEFT; break;
916       default: return FALSE;
917       }
918       break;
919    }
920    TidgetSendCmd(pzdi->bmp_list_ctl->pti, TDGTCMD_LIST_SEL_NEXT, cmd_arg, NULL);
921 
922    return FALSE;
923 }
924 
925 static
HandleChar(pTdgtBase,key_sym,buf,has_ch)926 int HandleChar(pTdgtBase, key_sym, buf, has_ch)
927    TdgtBase *pTdgtBase;
928    KeySym key_sym;
929    char *buf;
930    int has_ch;
931 {
932    ZyfhDlgInfo *pzdi=(ZyfhDlgInfo*)(pTdgtBase->pti->userdata);
933 
934    if (!pzdi->english_spelling) {
935       pzdi->english_spelling = TRUE;
936       ClearAllControls((TdgtBase*)(gZyfhInfo.dialogbox_tidgetinfo->tidget));
937    }
938    if (pzdi->just_fetched) {
939       ClearAllControls((TdgtBase*)(gZyfhInfo.dialogbox_tidgetinfo->tidget));
940    }
941    TdgtSmplEditAppendStr(pzdi->edit_ctl, buf, 1);
942 
943    return FALSE;
944 }
945 
946 static XComposeStatus c_stat;
947 
948 static
Tdgtb5DlgKeyPressEvHandlerCallback(pTdgtBase,pXEv)949 int Tdgtb5DlgKeyPressEvHandlerCallback(pTdgtBase, pXEv)
950    TdgtBase *pTdgtBase;
951    XEvent *pXEv;
952 {
953    ZyfhDlgInfo *pzdi=(ZyfhDlgInfo*)(pTdgtBase->pti->userdata);
954    int has_ch=0;
955    char buf[80];
956    KeySym key_sym=(KeySym)0;
957    XKeyEvent *key_ev=NULL;
958 
959    if (pXEv->type != KeyPress) return FALSE;
960    if (pzdi == NULL) return FALSE;
961 
962    key_ev = (&(pXEv->xkey));
963    has_ch = XLookupString(key_ev, buf, sizeof(buf), &key_sym, &c_stat);
964    TranslateKeys(buf, &key_sym);
965 
966    if (CharIsESC(key_ev, buf, key_sym, &has_ch)) {
967       HideTdgtb5DialogBox();
968    } else if (CharIsCRorLF(key_ev, buf, key_sym, &has_ch)) {
969       if (pzdi->just_fetched) {
970          return SendSelectedCharToClient(pTdgtBase);
971       } else {
972          return FetchChars(pTdgtBase);
973       }
974    } else if (CharIsCntrlSpace(key_ev, buf, key_sym, &has_ch)) {
975       HideTdgtb5DialogBox();
976    } else if (CharIsBS(key_ev, buf, key_sym, &has_ch, FALSE)) {
977       return HandleBackSpace(pTdgtBase);
978    } else if (key_sym==XK_Up || key_sym==XK_KP_Up || key_sym==XK_Down ||
979          key_sym==XK_KP_Down || key_sym==XK_Left || key_sym==XK_KP_Left ||
980          key_sym==XK_Right || key_sym==XK_KP_Right ||
981          (key_sym>'\040' && key_sym<='\177' &&
982          (key_ev->state & ControlMask) == ControlMask)) {
983       return HandleCursorKey(pTdgtBase, key_sym);
984    } else if (key_sym>='\040' && key_sym<='\177') {
985       return HandleChar(pTdgtBase, key_sym, buf, has_ch);
986    }
987    return FALSE;
988 }
989 
990 /* --------------------- Tdgtb5DlgWmDeleteCallback --------------------- */
991 
992 static
Tdgtb5DlgWmDeleteCallback(pTdgtBase)993 void Tdgtb5DlgWmDeleteCallback(pTdgtBase)
994    TdgtBase *pTdgtBase;
995 {
996    ZyfhDlgInfo *pzdi=(ZyfhDlgInfo*)(pTdgtBase->pti->userdata);
997 
998    if (pzdi == NULL) return;
999 
1000    HideTdgtb5DialogBox();
1001 }
1002 
1003 /* --------------------- Tdgtb5DlgSetMsg --------------------- */
1004 
1005 static
Tdgtb5DlgSetMsg(pti,msg)1006 int Tdgtb5DlgSetMsg(pti, msg)
1007    TidgetInfo *pti;
1008    char *msg;
1009 {
1010    return TRUE;
1011 }
1012 
1013 /* --------------------- Tdgtb5DlgSetEntries --------------------- */
1014 
1015 static
Tdgtb5DlgSetEntries(pti,dsp_ptr,entries,num_entries,marked_index)1016 int Tdgtb5DlgSetEntries(pti, dsp_ptr, entries, num_entries, marked_index)
1017    TidgetInfo *pti;
1018    DspList *dsp_ptr;
1019    char **entries;
1020    int num_entries, marked_index;
1021 {
1022    return TRUE;
1023 }
1024 
1025 /* --------------------- InitTdgtb5DlgInfo --------------------- */
1026 
1027 static
InitTdgtb5DlgInfo(pti)1028 void InitTdgtb5DlgInfo(pti)
1029    TidgetInfo *pti;
1030 {
1031    ZyfhDlgInfo *pzdi=NULL;
1032 
1033    if (pti == NULL) return;
1034 
1035    pzdi = (ZyfhDlgInfo*)(pti->userdata);
1036    if (pzdi == NULL) return;
1037 
1038    pzdi->num_entries = INVALID;
1039    pzdi->first_index = INVALID;
1040    pzdi->marked_index = INVALID;
1041 
1042    pzdi->screen_w = DisplayWidth(mainDisplay, mainScreen);
1043    pzdi->screen_h = DisplayHeight(mainDisplay, mainScreen);
1044    Tdgtb5DlgSetMsg(pti, "");
1045 
1046    pzdi->def_btn_id = BUTTON_OK;
1047    pzdi->double_click_btn_id = BUTTON_OK;
1048 }
1049 
1050 /* --------------------- ShowTdgtb5DialogBox --------------------- */
1051 
ShowTdgtb5DialogBox()1052 void ShowTdgtb5DialogBox()
1053 {
1054    TidgetInfo *pti=gZyfhInfo.dialogbox_tidgetinfo;
1055    ZyfhDlgInfo *pzdi=(ZyfhDlgInfo*)(pti->userdata);
1056 
1057    TidgetManagerSetWantAllKeyPressEvents(pti, TRUE);
1058    gZyfhInfo.mapped = TRUE;
1059    MapTidget(pti);
1060 
1061    if (pzdi != NULL) {
1062       ClearAllControls((TdgtBase*)(pti->tidget));
1063       pzdi->english_spelling = FALSE;
1064    }
1065 }
1066 
1067 /* --------------------- HideTdgtb5DialogBox --------------------- */
1068 
HideTdgtb5DialogBox()1069 void HideTdgtb5DialogBox()
1070 {
1071    TidgetManagerSetWantAllKeyPressEvents(NULL, FALSE);
1072    gZyfhInfo.mapped = FALSE;
1073    XUnmapWindow(mainDisplay, gZyfhInfo.dialogbox_tidgetinfo->tci.win);
1074 
1075    if (warpToWinCenter) {
1076       XWarpPointer(mainDisplay, None, drawWindow, 0, 0, 0, 0,
1077             (int)(ZOOMED_SIZE(drawWinW)>>1), (int)(ZOOMED_SIZE(drawWinH)>>1));
1078    }
1079 }
1080 
1081 /* --------------------- CreateTdgtb5DialogBox --------------------- */
1082 
1083 typedef struct tagCreateBtnInfo {
1084    char *text;
1085    int ctl_id;
1086    int cstid;
1087    int msg_id;
1088 } CreateBtnInfo;
1089 
1090 #define NUM_ZHFH_BUTTONS 4
1091 
1092 static CreateBtnInfo cbi[NUM_ZHFH_BUTTONS]={
1093    { "Fetch", ID_ZYFH_BTN_FETCH, FALSE, STID_FETCH_CHARS_FROM_DB },
1094    { "Send",  ID_ZYFH_BTN_SEND,  FALSE, STID_SEND_SEL_CHAR_TO_DRAWING_AREA },
1095    { "<CR>",  ID_ZYFH_BTN_CR,    FALSE, STID_SEND_CR_TO_DRAWING_AREA },
1096    { "Close", ID_ZYFH_BTN_CLOSE, TRUE,  CSTID_CLOSE }
1097 };
1098 
1099 static
CreateTgtwb5Buttons(pTdgtBase)1100 int CreateTgtwb5Buttons(pTdgtBase)
1101    TdgtBase *pTdgtBase;
1102 {
1103    ZyfhDlgInfo *pzdi=(ZyfhDlgInfo*)(pTdgtBase->pti->userdata);
1104    TdgtBtnRow *pTdgtBtnRow=pzdi->btn_row_ctl;
1105    int i=0;
1106 
1107    for (i=0; i < NUM_ZHFH_BUTTONS; i++) {
1108       TdgtBtn *pTdgtBtn=NULL;
1109       MouseOverStatusInfo mosi;
1110       int btn_w=0, btn_h=0;
1111 
1112       memset(&mosi, 0, sizeof(MouseOverStatusInfo));
1113       mosi.one_line_status = TRUE;
1114       UtilStrCpyN(mosi.one_line_str, sizeof(mosi.one_line_str),
1115             cbi[i].cstid ? TgLoadCachedString(cbi[i].msg_id) :
1116             TgLoadString(cbi[i].msg_id));
1117 
1118       CalcTdgtBtnDim(cbi[i].text, 8, TDGTBTN_DEF_H_PAD, TDGTBTN_DEF_V_PAD,
1119             &btn_w, &btn_h);
1120       pTdgtBtn = CreateTdgtBtn(pTdgtBtnRow->pti->tci.win,
1121             pTdgtBtnRow->pti, cbi[i].ctl_id, 0, 0, btn_w, btn_h,
1122             TDGTBTN_DEF_H_PAD, TDGTBTN_DEF_V_PAD, TGMUTYPE_TEXT, TDGTBTN_CLICK,
1123             TGBS_NORMAL, STYLE_NR, cbi[i].text, &mosi);
1124       if (pTdgtBtn == NULL) {
1125          DestroyTidget(&pTdgtBase->pti);
1126          return FALSE;
1127       }
1128       if (!TdgtBtnRowAddBtn(pTdgtBtnRow, pTdgtBtn)) {
1129          DestroyTidget(&pTdgtBase->pti);
1130          return FALSE;
1131       }
1132    }
1133    return TRUE;
1134 }
1135 
1136 static
AdjustDialogBoxWidth(dpy,pTdgtBase)1137 void AdjustDialogBoxWidth(dpy, pTdgtBase)
1138    Display *dpy;
1139    TdgtBase *pTdgtBase;
1140 {
1141    ZyfhDlgInfo *pzdi=(ZyfhDlgInfo*)(pTdgtBase->pti->userdata);
1142    int max_w=0, bottom=0, h_pad=pTdgtBase->pti->tci.h_pad;
1143    int v_pad=pTdgtBase->pti->tci.v_pad;
1144    SimpleWinInfo *pswi=NULL;
1145 
1146    if (pzdi->msg_ctl != NULL) {
1147       pswi = (&(pzdi->msg_ctl->pti->tci.win_info));
1148       if (pswi->w > max_w) max_w = pswi->w;
1149    }
1150    pswi = (&(pzdi->zyfh_ctl->pti->tci.win_info));
1151    if (pswi->x+pswi->w > max_w) max_w = pswi->x+pswi->w;
1152 
1153    pswi = (&(pzdi->bmp_list_ctl->pti->tci.win_info));
1154    if (pswi->w > max_w) max_w = pswi->w;
1155 
1156    pswi = (&(pzdi->btn_row_ctl->pti->tci.win_info));
1157    if (pswi->w > max_w) max_w = pswi->w;
1158    bottom = pswi->y+pswi->h;
1159 
1160    if (pzdi->msg_ctl != NULL) {
1161       pswi = (&(pzdi->msg_ctl->pti->tci.win_info));
1162       pswi->x = ((max_w-pswi->w)>>1) + windowPadding + h_pad;
1163       TidgetMoveResize(pzdi->msg_ctl->pti, pswi->x, pswi->y, pswi->w, pswi->h);
1164    }
1165    pswi = (&(pzdi->edit_ctl->pti->tci.win_info));
1166    pswi->w = max_w;
1167    TidgetMoveResize(pzdi->edit_ctl->pti, pswi->x, pswi->y, pswi->w, pswi->h);
1168 
1169    pswi = (&(pzdi->bmp_list_ctl->pti->tci.win_info));
1170    pswi->w = max_w;
1171    TidgetMoveResize(pzdi->bmp_list_ctl->pti, pswi->x, pswi->y, pswi->w,
1172          pswi->h);
1173 
1174    pswi = (&(pzdi->btn_row_ctl->pti->tci.win_info));
1175    pswi->w = max_w;
1176    TidgetMoveResize(pzdi->btn_row_ctl->pti, pswi->x, pswi->y, pswi->w, pswi->h);
1177 
1178    pswi = (&(pTdgtBase->pti->tci.win_info));
1179    pswi->w = max_w+(windowPadding<<1)+(h_pad<<1);
1180    pswi->h = bottom+windowPadding+v_pad;
1181    TidgetMoveResize(pTdgtBase->pti, pswi->x, pswi->y, pswi->w, pswi->h);
1182 }
1183 
1184 static
AdjustDialogBoxSize(dpy,pTdgtBase)1185 void AdjustDialogBoxSize(dpy, pTdgtBase)
1186    Display *dpy;
1187    TdgtBase *pTdgtBase;
1188 {
1189    ZyfhDlgInfo *pzdi=(ZyfhDlgInfo*)(pTdgtBase->pti->userdata);
1190    int base_win_x=0, base_win_y=0, base_win_w=0, base_win_h=0;
1191    XWMHints wmhints;
1192    XSizeHints sizehints;
1193 
1194    if (pTdgtBase == NULL) return;
1195 
1196    AdjustDialogBoxWidth(dpy, pTdgtBase);
1197 
1198    base_win_w = pTdgtBase->pti->tci.win_info.w;
1199    base_win_h = pTdgtBase->pti->tci.win_info.h;
1200 
1201    memset(&wmhints, 0, sizeof(XWMHints));
1202    wmhints.flags = InputHint | StateHint;
1203    wmhints.input = True;
1204    wmhints.initial_state = NormalState;
1205    XSetWMHints(dpy, pTdgtBase->pti->tci.win, &wmhints);
1206 
1207    base_win_x = (base_win_w > pzdi->screen_w) ? 0 :
1208          ((pzdi->screen_w-base_win_w)>>1);
1209    base_win_y = (base_win_h > pzdi->screen_h) ? 0 :
1210          ((pzdi->screen_h-base_win_h)/3);
1211 
1212    XMoveResizeWindow(dpy, pTdgtBase->pti->tci.win, base_win_x,
1213          base_win_y, base_win_w, base_win_h);
1214 
1215    sizehints.flags = PPosition | PSize | USPosition | PMinSize | PMaxSize;
1216    sizehints.x = base_win_x;
1217    sizehints.y = base_win_y;
1218    sizehints.width = sizehints.min_width = sizehints.max_width = base_win_w;
1219    sizehints.height = sizehints.min_height = sizehints.max_height = base_win_h;
1220 #ifdef NOTR4MODE
1221    XSetNormalHints(dpy, pTdgtBase->pti->tci.win, &sizehints);
1222 #else
1223    XSetWMNormalHints(dpy, pTdgtBase->pti->tci.win, &sizehints);
1224 #endif
1225 
1226    XSetTransientForHint(dpy, pTdgtBase->pti->tci.win, mainWindow);
1227 }
1228 
CreateTdgtb5DialogBox(dpy,parent_win)1229 TidgetInfo *CreateTdgtb5DialogBox(dpy, parent_win)
1230    Display *dpy;
1231    Window parent_win; /* should be the rootWindow */
1232 {
1233    int orig_x=0, x=0, y=0, v_gap=20, num_bmp_cols=0, h_pad=0, v_pad=0;
1234    int max_w=((gZyfhInfo.b5_font_w<<4)+scrollBarW), vh_padding=0;
1235    int has_msg_ctl=FALSE;
1236    TdgtBase *pTdgtBase=NULL;
1237    ZyfhDlgInfo *pzdi=(ZyfhDlgInfo*)malloc(sizeof(ZyfhDlgInfo));
1238    char caption[MAXSTRING];
1239    MouseOverStatusInfo mosi;
1240 
1241    if (pzdi == NULL) FailAllocMessage();
1242    memset(pzdi, 0, sizeof(ZyfhDlgInfo));
1243 
1244    memset(&mosi, 0, sizeof(MouseOverStatusInfo));
1245    UtilStrCpyN(mosi.btn_str[0], sizeof(mosi.btn_str[0]),
1246          TgLoadString(STID_SELECT_A_CHAR));
1247    UtilStrCpyN(mosi.btn_str[1], sizeof(mosi.btn_str[1]),
1248          TgLoadString(STID_SEND_A_CHAR_TO_DRAWING_AREA));
1249    UtilStrCpyN(mosi.btn_str[2], sizeof(mosi.btn_str[2]),
1250          TgLoadCachedString(CSTID_PARANED_NONE));
1251 
1252    h_pad = TDGTBASE_DEF_H_PAD;
1253    v_pad = TDGTBASE_DEF_V_PAD;
1254    if (msgFontSet != NULL || msgFontPtr != NULL) {
1255       vh_padding = (msgFontWidth<<1);
1256    } else {
1257       vh_padding = (defaultFontWidth<<1);
1258    }
1259    h_pad = v_pad = vh_padding;
1260 
1261    orig_x = h_pad+windowPadding;
1262    x = h_pad+windowPadding;
1263    y = v_pad+windowPadding;
1264 
1265    switch (gZyfhInfo.b5_font_real_encoding) {
1266    case GB_ENCODING:
1267       sprintf(caption, TgLoadString(STID_TOOL_GB_CHINESE_KEYPAD), TOOL_NAME);
1268       break;
1269    case BIG5_ENCODING:
1270       sprintf(caption, TgLoadString(STID_TOOL_BIG5_CHINESE_KEYPAD), TOOL_NAME);
1271       break;
1272    default: return NULL;
1273    }
1274    pTdgtBase = CreateTdgtBase(parent_win, NULL, ID_ZYFH_DIALOG, 0, 0, 100, 100,
1275          h_pad, v_pad, (dialogboxUse3DBorder ? TGBS_RAISED : TGBS_NORMAL),
1276          caption);
1277    if (pTdgtBase == NULL) {
1278       free(pzdi);
1279       return NULL;
1280    }
1281    pTdgtBase->pti->userdata = pzdi;
1282    InitTdgtb5DlgInfo(pTdgtBase->pti);
1283 
1284    num_bmp_cols = (int)(((double)(pzdi->screen_w)) / ((double)3) /
1285          ((double)(gZyfhInfo.b5_font_w)));
1286 
1287    if (has_msg_ctl) {
1288       pzdi->msg_ctl = CreateTdgtMsg(pTdgtBase->pti->tci.win, pTdgtBase->pti,
1289             INVALID, x, y, TDGTMSG_DEF_H_PAD, TDGTMSG_DEF_V_PAD, TGBS_NORMAL,
1290             TgLoadString(STID_USE_ZYFH_KEYPAD_OR_PINYING), JUST_L);
1291       if (pzdi->msg_ctl == NULL) {
1292          DestroyTidget(&pTdgtBase->pti);
1293          return NULL;
1294       }
1295       y += pzdi->msg_ctl->pti->tci.win_info.h;
1296       y += v_gap;
1297    }
1298    pzdi->zyfh_dpy_ctl = CreateTdgtDraw(pTdgtBase->pti->tci.win, pTdgtBase->pti,
1299          ID_ZYFH_DPY, x, y, gZyfhInfo.zyfh_image_wh,
1300          ((gZyfhInfo.zyfh_image_wh)<<2), TDGTDRAW_DEF_H_PAD, TDGTDRAW_DEF_V_PAD,
1301          TGBS_LOWRED, NULL);
1302    if (pzdi->zyfh_dpy_ctl == NULL) {
1303       DestroyTidget(&pTdgtBase->pti);
1304       return NULL;
1305    }
1306    x += ((gZyfhInfo.zyfh_image_wh)<<2);
1307    pzdi->zyfh_ctl = CreateTdgtDraw(pTdgtBase->pti->tci.win, pTdgtBase->pti,
1308          ID_ZYFH_KEYPAD, x, y, gZyfhInfo.zyfh_bitmap_w, gZyfhInfo.zyfh_bitmap_h,
1309          TDGTDRAW_DEF_H_PAD, TDGTDRAW_DEF_V_PAD, TGBS_LOWRED, NULL);
1310    if (pzdi->zyfh_ctl == NULL) {
1311       DestroyTidget(&pTdgtBase->pti);
1312       return NULL;
1313    }
1314    TdgtDrawSetRedrawCallback(pzdi->zyfh_ctl, ZyfhRedrawCallback);
1315    TdgtDrawSetEvHandlerCallback(pzdi->zyfh_ctl, ZyfhEvHandlerCallback);
1316 
1317    TdgtDrawSetRedrawCallback(pzdi->zyfh_dpy_ctl, ZyfhDpyRedrawCallback);
1318    TdgtDrawSetSendCmdCallback(pzdi->zyfh_dpy_ctl, ZyfhDpySendCmdCallback);
1319 
1320    x = orig_x;
1321    y += pzdi->zyfh_ctl->pti->tci.win_info.h;
1322    y += v_gap;
1323    pzdi->edit_ctl = CreateTdgtSmplEdit(pTdgtBase->pti->tci.win, pTdgtBase->pti,
1324          ID_ZYFH_EDIT, x, y, max_w, TDGTSEDT_DEF_H_PAD, TDGTSEDT_DEF_V_PAD, "",
1325          STYLE_NR, INVALID);
1326    if (pzdi->edit_ctl == NULL) {
1327       DestroyTidget(&pTdgtBase->pti);
1328       return NULL;
1329    }
1330    y += pzdi->edit_ctl->pti->tci.win_info.h;
1331    y += v_gap;
1332    pzdi->bmp_list_ctl = CreateTdgtBmpList(pTdgtBase->pti->tci.win,
1333          pTdgtBase->pti, ID_ZYFH_BMPLIST, x, y, TDGTBMPL_DEF_H_PAD,
1334          TDGTBMPL_DEF_V_PAD, gZyfhInfo.b5_font_w, gZyfhInfo.b5_font_h,
1335          num_bmp_cols, 5, 0, (Button1Mask|Button2Mask), &mosi);
1336    if (pzdi->bmp_list_ctl == NULL) {
1337       DestroyTidget(&pTdgtBase->pti);
1338       return NULL;
1339    }
1340    y += pzdi->bmp_list_ctl->pti->tci.win_info.h;
1341    y += v_gap;
1342    pzdi->btn_row_ctl = CreateTdgtBtnRow(pTdgtBase->pti->tci.win, pTdgtBase->pti,
1343          INVALID, x, y, TDGTBROW_DEF_H_PAD, TDGTBROW_DEF_V_PAD, TGBS_NORMAL,
1344          defaultFontWidth, JUST_C);
1345    if (pzdi->btn_row_ctl == NULL) {
1346       DestroyTidget(&pTdgtBase->pti);
1347       return NULL;
1348    }
1349    if (!CreateTgtwb5Buttons(pTdgtBase)) {
1350       DestroyTidget(&pTdgtBase->pti);
1351       return NULL;
1352    }
1353    Tdgtb5DlgSetEntries(pTdgtBase->pti, NULL, NULL, 0, INVALID);
1354 
1355    /*
1356     * Specify that the base tidget will handle all the KeyPress events
1357     *         in all its children tidgets.
1358     */
1359    TdgtBaseWillHandleKeyPressEvents(pTdgtBase,
1360          Tdgtb5DlgKeyPressEvHandlerCallback);
1361    /*
1362     * Specify that the base tidget will handle all the KeyPress events
1363     *         in all its children tidgets.
1364     */
1365    TdgtBaseSetWmDeleteCallback(pTdgtBase, Tdgtb5DlgWmDeleteCallback);
1366 
1367    AdjustDialogBoxSize(dpy, pTdgtBase);
1368 
1369    return pTdgtBase->pti;
1370 }
1371 
1372 /* --------------------- DestroyTdgtb5DialogBox --------------------- */
1373 
DestroyTdgtb5DialogBox(dpy,pti)1374 void DestroyTdgtb5DialogBox(dpy, pti)
1375    Display *dpy;
1376    TidgetInfo *pti;
1377 {
1378    ZyfhDlgInfo *pzdi=NULL;
1379 
1380    if (pti == NULL) return;
1381 
1382    pzdi = (ZyfhDlgInfo*)(pti->userdata);
1383    if (pzdi != NULL) {
1384       free(pzdi);
1385    }
1386    DestroyTidget(&pti);
1387 }
1388 
1389 /* --------------------- Tdgtb5DlgLoop --------------------- */
1390 
1391 static
HandleTdgtNotifyEvent(pTdgtBase,pTdgtNtfy)1392 int HandleTdgtNotifyEvent(pTdgtBase, pTdgtNtfy)
1393    TdgtBase *pTdgtBase;
1394    TdgtNtfy *pTdgtNtfy;
1395 {
1396    switch (pTdgtNtfy->ctl_id) {
1397    case ID_ZYFH_BMPLIST:
1398       switch (pTdgtNtfy->nf_type) {
1399       case TDGTNF_LIST_CLICKED:
1400          if (pTdgtNtfy->nf_arg2 == Button2) {
1401             return SendSelectedCharToClient(pTdgtBase);
1402          }
1403          break;
1404       case TDGTNF_LIST_DBL_CLICKED:
1405          return SendSelectedCharToClient(pTdgtBase);
1406       }
1407       break;
1408    case ID_ZYFH_BTN_FETCH: FetchChars(pTdgtBase); break;
1409    case ID_ZYFH_BTN_SEND: SendSelectedCharToClient(pTdgtBase); break;
1410    case ID_ZYFH_BTN_CR: SendCRToClient(pTdgtBase); break;
1411    case ID_ZYFH_BTN_CLOSE: HideTdgtb5DialogBox(); break;
1412    }
1413    return FALSE;
1414 }
1415 
Tdgtb5DlgLoop(pti)1416 int Tdgtb5DlgLoop(pti)
1417    TidgetInfo *pti;
1418 {
1419    TdgtBase *pTdgtBase=(TdgtBase*)(pti->tidget);
1420    int which_btn_clicked=INVALID, first_time_config=TRUE;
1421 
1422    if (pTdgtBase == NULL) return which_btn_clicked;
1423 
1424    while (gZyfhInfo.mapped) {
1425       XEvent xev;
1426       TdgtNtfy tdgt_notify;
1427       TidgetInfo *handling_pti=NULL;
1428 
1429       XNextEvent(mainDisplay, &xev);
1430 
1431       if (xev.type == MotionNotify) {
1432          /* do nothing */
1433       } else if (xev.type == ConfigureNotify &&
1434             xev.xany.window == pti->tci.win) {
1435          if (first_time_config) {
1436             first_time_config = FALSE;
1437             if (warpToWinCenter) {
1438                /* does not work because the window has been moved */
1439                XWarpPointer(mainDisplay, None, pti->tci.win, 0, 0, 0, 0,
1440                      (pti->tci.win_info.w>>1), (pti->tci.win_info.h>>1));
1441             }
1442             SetStringStatus(TgLoadString(STID_CLICK_SEND_TO_SEND_CHAR));
1443          }
1444       } else if (xev.type == Expose) {
1445          ExposeEventHandler(&xev, FALSE);
1446       } else if (xev.type == ConfigureNotify &&
1447             xev.xany.window==mainWindow) {
1448          Reconfigure(FALSE);
1449       } else if (xev.type == KeyPress) {
1450          TidgetManagerHandleAllKeyPressEvent(&xev);
1451       } else if (IsTdgtNotifyEvent(pti, &xev, &tdgt_notify)) {
1452          HandleTdgtNotifyEvent(pTdgtBase, &tdgt_notify);
1453       } else if (IsTidgetEvent(pti, &xev, &handling_pti)) {
1454          TidgetEventHandler(pti, &xev, handling_pti);
1455       } else {
1456       }
1457    }
1458    return which_btn_clicked;
1459 }
1460 
1461 /* --------------------- Init & Clean Up --------------------- */
1462 
InitTdgtb5Dlg()1463 int InitTdgtb5Dlg()
1464 {
1465    return TRUE;
1466 }
1467 
CleanUpTdgtb5Dlg()1468 void CleanUpTdgtb5Dlg()
1469 {
1470 }
1471 
1472 #endif /* ~_NO_TGTWB5 */
1473