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