1 /*
2 * Copyright (C) 2020 The HIME team, Taiwan
3 * Copyright (C) 1994-2011 Edward Der-Hua Liu, Hsin-Chu, Taiwan
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation version 2.1
8 * of the License.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20 #include <stdlib.h>
21
22 #include <sys/stat.h>
23
24 #include "hime.h"
25
26 #include "gst.h"
27 #include "gtab.h"
28 #include "pho-status.h"
29 #include "pho.h"
30
31 extern PHO_ST poo;
32
33 extern PHO_ITEM *ch_pho;
34
35 extern PHOKBM phkbm;
36 gboolean b_hsu_kbm;
37 extern PIN_JUYIN *pin_juyin;
38
39 gboolean full_char_proc (KeySym keysym);
40 void hide_win_pho ();
41 void ClrSelArea ();
42
43 #define MAX_HASH_PHO 27
44 u_short hash_pho[MAX_HASH_PHO + 1];
45
46 static char typ_pho_len[] = {5, 2, 4, 3};
47
48 gboolean same_query_show_pho_win ();
49
typ_pho_empty()50 gboolean typ_pho_empty () {
51 return !poo.typ_pho[0] && !poo.typ_pho[1] && !poo.typ_pho[2] && !poo.typ_pho[3];
52 }
53
pho_has_input()54 gboolean pho_has_input () {
55 return !typ_pho_empty () || same_query_show_pho_win ();
56 }
57
pho2key(char typ_pho[])58 phokey_t pho2key (char typ_pho[]) {
59 phokey_t key = typ_pho[0];
60 int i;
61
62 if (key == BACK_QUOTE_NO)
63 return (BACK_QUOTE_NO << 9) | typ_pho[1];
64
65 for (i = 1; i < 4; i++) {
66 key = typ_pho[i] | (key << typ_pho_len[i]);
67 }
68
69 return key;
70 }
71
key_typ_pho(phokey_t phokey,u_char rtyp_pho[])72 void key_typ_pho (phokey_t phokey, u_char rtyp_pho[]) {
73 rtyp_pho[3] = phokey & 7;
74 phokey >>= 3;
75 rtyp_pho[2] = phokey & 0xf;
76 phokey >>= 4;
77 rtyp_pho[1] = phokey & 0x3;
78 phokey >>= 2;
79 rtyp_pho[0] = phokey;
80 }
81
mask_key_typ_pho(phokey_t * key)82 void mask_key_typ_pho (phokey_t *key) {
83 if (poo.typ_pho[0] == BACK_QUOTE_NO)
84 return;
85 if (!poo.typ_pho[0])
86 *key &= ~(31 << 9);
87 if (!poo.typ_pho[1])
88 *key &= ~(3 << 7);
89 if (!poo.typ_pho[2])
90 *key &= ~(15 << 3);
91 if (!poo.typ_pho[3])
92 *key &= ~(7);
93 }
94
95 #define TKBM 0
96 #define MIN_M_PHO 5
97
find_match_phos(u_char mtyp_pho[4],int * mcount,int newkey)98 static void find_match_phos (u_char mtyp_pho[4], int *mcount, int newkey) {
99 int vv;
100 phokey_t key = pho2key (poo.typ_pho);
101
102 mask_key_typ_pho (&key);
103 #if TKBM
104 dbg ("-------------------- %d --", poo.typ_pho[3]);
105 prph (key);
106 dbg ("\n");
107 #endif
108 for (vv = hash_pho[(int) poo.typ_pho[0]]; vv < hash_pho[(int) poo.typ_pho[0] + 1]; vv++) {
109 phokey_t ttt = idx_pho[vv].key;
110
111 if (newkey != ' ' && !poo.typ_pho[3])
112 mask_key_typ_pho (&ttt);
113
114 if (ttt > key)
115 break;
116
117 int count = 0;
118
119 int i;
120 for (i = idx_pho[vv].start; i < idx_pho[vv + 1].start; i++) {
121 if (utf8_sz (pho_idx_str (i)) > 1) {
122 #if 0
123 utf8_putchar(ch_pho[i].ch);
124 dbg(" ");
125 #endif
126 count++;
127 }
128 }
129
130 if (*mcount < count) {
131 *mcount = count;
132 memcpy (mtyp_pho, poo.typ_pho, sizeof (poo.typ_pho));
133 #if TKBM
134 dbg ("count %d\n", count);
135 #endif
136 if (*mcount > MIN_M_PHO)
137 break;
138 }
139 }
140 }
141
142 gboolean inph_typ_pho_pinyin (int newkey);
143
typ_pho_status()144 static int typ_pho_status () {
145 return poo.typ_pho[3] ? PHO_STATUS_OK_NEW : PHO_STATUS_OK;
146 }
147
inph_typ_pho(KeySym newkey)148 int inph_typ_pho (KeySym newkey) {
149 int i;
150 int insert = -1;
151
152 if (pin_juyin) {
153 return inph_typ_pho_pinyin (newkey);
154 }
155
156 if (poo.typ_pho[0] == BACK_QUOTE_NO) {
157 poo.typ_pho[1] = (char) newkey;
158 poo.inph[1] = newkey;
159 return PHO_STATUS_OK;
160 }
161
162 int max_in_idx;
163 for (max_in_idx = 3; max_in_idx >= 0 && !poo.typ_pho[max_in_idx]; max_in_idx--)
164 ;
165
166 // try insert mode first
167 if (insert < 0)
168 for (i = 0; i < 3; i++) {
169 char num = phkbm.phokbm[(int) newkey][i].num;
170 int typ = phkbm.phokbm[(int) newkey][i].typ;
171
172 if (num && !poo.inph[typ] && typ > max_in_idx) {
173 poo.inph[typ] = newkey;
174 poo.typ_pho[typ] = num;
175 #if TKBM
176 dbg ("insert typ %d\n", typ);
177 #endif
178 insert = typ;
179 break;
180 }
181 }
182
183 if (insert < 0) {
184 // then overwrite mode
185 for (i = 0; i < 3; i++) {
186 char num = phkbm.phokbm[newkey][i].num;
187 int typ = phkbm.phokbm[newkey][i].typ;
188
189 if (num) {
190 poo.inph[typ] = newkey;
191 poo.typ_pho[typ] = num;
192 insert = typ;
193 break;
194 }
195 }
196 }
197
198 // dbg("newkey %c\n", newkey);
199
200 int mcount = 0;
201 u_char mtyp_pho[4];
202
203 int a;
204
205 for (a = 0; a < 3; a++) {
206 char num = phkbm.phokbm[(int) poo.inph[0]][a].num;
207 char typ = phkbm.phokbm[(int) poo.inph[0]][a].typ;
208
209 if (typ == 3)
210 continue;
211
212 if (num) {
213 if (typ == 2 && poo.typ_pho[0] && !poo.typ_pho[2])
214 poo.typ_pho[0] = 0;
215 poo.typ_pho[(int) typ] = num;
216 #if TKBM
217 dbg ("%d num %d\n", a, num);
218 #endif
219 find_match_phos (mtyp_pho, &mcount, newkey);
220 }
221
222 for (i = 0; i < 3; i++) {
223 char num = phkbm.phokbm[(int) poo.inph[2]][i].num;
224 char typ = phkbm.phokbm[(int) poo.inph[2]][i].typ;
225
226 if (!num)
227 break;
228
229 if (typ != 2)
230 continue;
231
232 poo.typ_pho[(int) typ] = num;
233
234 find_match_phos (mtyp_pho, &mcount, newkey);
235
236 if (mcount > MIN_M_PHO) {
237 return typ_pho_status ();
238 }
239 }
240
241 find_match_phos (mtyp_pho, &mcount, newkey);
242
243 if (mcount > MIN_M_PHO) {
244 return typ_pho_status ();
245 }
246 }
247
248 if (mcount) {
249 memcpy (poo.typ_pho, mtyp_pho, sizeof (poo.typ_pho));
250 return typ_pho_status ();
251 }
252
253 return PHO_STATUS_REJECT;
254 }
255
clrin_pho()256 void clrin_pho () {
257 memset (poo.typ_pho, 0, sizeof (poo.typ_pho));
258 memset (poo.inph, 0, sizeof (poo.inph));
259 poo.maxi = poo.ityp3_pho = 0;
260 poo.cpg = 0;
261
262 if (hime_pop_up_win && !same_query_show_pho_win ())
263 hide_win_pho ();
264 }
265
266 void disp_pho (int index, char *phochar);
clr_in_area_pho()267 void clr_in_area_pho () {
268 int i;
269
270 clrin_pho ();
271 for (i = 0; i < text_pho_N; i++)
272 disp_pho (i, " ");
273 }
274
disp_in_area_pho()275 static void disp_in_area_pho () {
276 int i;
277
278 text_pho_N = pin_juyin ? 7 : 4;
279 if (pin_juyin) {
280 for (i = 0; i < text_pho_N; i++) {
281 disp_pho (i, &poo.inph[i]);
282 }
283 } else {
284 for (i = 0; i < 4; i++) {
285 if (i == 1 && poo.typ_pho[0] == BACK_QUOTE_NO) {
286 disp_pho (i, &poo.inph[1]);
287 } else
288 disp_pho (i, &pho_chars[i][poo.typ_pho[i] * 3]);
289 }
290 }
291 }
292
qcmp_count(const void * aa,const void * bb)293 static int qcmp_count (const void *aa, const void *bb) {
294 PHO_ITEM *a = (PHO_ITEM *) aa;
295 PHO_ITEM *b = (PHO_ITEM *) bb;
296
297 return b->count - a->count;
298 }
299
300 void disp_pho_sel (char *s);
301
ClrPhoSelArea()302 static void ClrPhoSelArea () {
303 disp_pho_sel ("");
304 }
305
306 extern char *TableDir;
307 extern char phofname[128];
308
get_start_stop_idx(phokey_t key,int * start_i,int * stop_i)309 gboolean get_start_stop_idx (phokey_t key, int *start_i, int *stop_i) {
310 int typ_pho0 = key >> 9;
311 int vv = hash_pho[typ_pho0];
312
313 while (vv < idxnum_pho) {
314 if (idx_pho[vv].key >= key)
315 break;
316 else
317 vv++;
318 }
319
320 if (vv >= idxnum_pho || idx_pho[vv].key != key)
321 return FALSE;
322
323 *start_i = idx_pho[vv].start;
324 *stop_i = idx_pho[vv + 1].start;
325
326 return TRUE;
327 }
328
329 // given the pho key & the utf8 char, return the idx in ch_pho
ch_key_to_ch_pho_idx(phokey_t phkey,char * utf8)330 int ch_key_to_ch_pho_idx (phokey_t phkey, char *utf8) {
331 int start_i, stop_i;
332
333 get_start_stop_idx (phkey, &start_i, &stop_i);
334
335 int i;
336 for (i = start_i; i < stop_i; i++) {
337 char *ch = pho_idx_str (i);
338 int u8len = utf8_sz (ch);
339 if (!memcmp (ch, utf8, u8len)) {
340 return i;
341 }
342 }
343
344 // prph(phkey);
345 // dbg("error found %c%c", *big5, *(big5+1));
346 return -1;
347 }
348
inc_pho_count(phokey_t key,int ch_idx)349 void inc_pho_count (phokey_t key, int ch_idx) {
350 int start_i, stop_i;
351
352 if (!phonetic_char_dynamic_sequence)
353 return;
354
355 get_start_stop_idx (key, &start_i, &stop_i);
356
357 // dbg("start_i %d %d %d %d\n", start_i, stop_i, poo.start_idx, poo.stop_idx);
358
359 ch_pho[ch_idx].count++;
360 // dbg("count %d\n", ch_pho[ch_idx].count);
361
362 qsort (&ch_pho[start_i], stop_i - start_i, sizeof (PHO_ITEM), qcmp_count);
363 #if 0
364 int i;
365 for(i=start_i; i < stop_i; i++) {
366 dbg("uuuu %c%c%c %d\n", ch_pho[i].ch[0], ch_pho[i].ch[1],
367 ch_pho[i].ch[2], ch_pho[i].count);
368 }
369 #endif
370
371 FILE *fw;
372
373 // dbg("phofname %s\n", phofname);
374 if ((fw = fopen (phofname, "rb+")) == NULL) {
375 p_err ("err %s\n", phofname);
376 }
377
378 if (fseek (fw, ch_pho_ofs + sizeof (PHO_ITEM) * start_i, SEEK_SET) < 0)
379 p_err ("fseek err");
380 #if 1
381 if (fwrite (&ch_pho[start_i], sizeof (PHO_ITEM), stop_i - start_i, fw) <= 0)
382 p_err ("fwrite err");
383 #endif
384 fclose (fw);
385 }
386
387 void lookup_gtab (char *ch);
388 gboolean is_gtab_query_mode ();
389 void set_gtab_target_displayed ();
390
391 #include "gtab-buf.h"
392
putkey_pho(u_short key,int idx)393 void putkey_pho (u_short key, int idx) {
394 char *pho_str = pho_idx_str (idx);
395
396 if (poo.same_pho_query_state == SAME_PHO_QUERY_pho_select && ggg.gbufN)
397 insert_gbuf_nokey (pho_str);
398 else
399 send_text (pho_str);
400
401 lookup_gtab (pho_str);
402
403 inc_pho_count (key, idx);
404
405 clr_in_area_pho ();
406 ClrSelArea ();
407
408 if (is_gtab_query_mode ())
409 set_gtab_target_displayed ();
410 }
411
412 void recreate_win1_if_nessary ();
413
load_tab_pho_file()414 void load_tab_pho_file () {
415 pho_load ();
416
417 memset (poo.typ_pho, 0, sizeof (poo.typ_pho));
418
419 u_int ttt = 0;
420 int i;
421 for (i = 0; i < MAX_HASH_PHO; i++) {
422 if (idx_pho[ttt].key >> 9 == i)
423 hash_pho[i] = ttt;
424 else {
425 continue;
426 }
427
428 while (ttt < idxnum_pho && idx_pho[ttt].key >> 9 == i)
429 ttt++;
430 }
431
432 for (i = MAX_HASH_PHO; !hash_pho[i]; i--)
433 hash_pho[i] = idxnum_pho;
434
435 char kbmfname[MAX_HIME_STR];
436 FILE *fr;
437
438 free (pin_juyin);
439 pin_juyin = NULL;
440
441 if (!strstr (pho_kbm_name, "pinyin")) {
442 text_pho_N = 4;
443 } else {
444 load_pin_juyin ();
445 }
446
447 if (strcmp (pho_kbm_name, "hsu"))
448 b_hsu_kbm = FALSE;
449 else
450 b_hsu_kbm = TRUE;
451
452 char pho_kbm_name_kbm[128];
453
454 strcat (strcpy (pho_kbm_name_kbm, pho_kbm_name), ".kbm");
455 dbg ("phokbm_name: %s\n", pho_kbm_name_kbm);
456
457 get_sys_table_file_name (pho_kbm_name_kbm, kbmfname);
458
459 if ((fr = fopen (kbmfname, "rb")) == NULL)
460 p_err ("Cannot open %s", kbmfname);
461
462 dbg ("kbmfname %s\n", kbmfname);
463
464 fread (&phkbm, sizeof (phkbm), 1, fr);
465 fclose (fr);
466 phkbm.selkeyN = strlen (pho_selkey);
467
468 dbg ("pho_selkey %s\n", pho_selkey);
469
470 recreate_win1_if_nessary ();
471 #if 0
472 for(i='A'; i <= 'z'; i++)
473 dbg("%c %d %d\n", i, phkbm.phokbm[i][0].num, phkbm.phokbm[i][0].typ);
474 #endif
475 }
476
477 void show_win_pho ();
478
init_tab_pho()479 void init_tab_pho () {
480 if (!ch_pho) {
481 load_tab_pho_file ();
482 }
483
484 show_win_pho ();
485 clr_in_area_pho ();
486 }
487
pho_idx_str_markup(int ii)488 static char *pho_idx_str_markup (int ii) {
489 char *pho_str = pho_idx_str (ii);
490 if (!strcmp (pho_str, "<"))
491 pho_str = "<";
492 else if (!strcmp (pho_str, ">"))
493 pho_str = ">";
494 return pho_str;
495 }
496
497 gboolean shift_char_proc (KeySym key, int kbstate);
498 gboolean pre_punctuation (KeySym xkey);
499 void pho_play (phokey_t key);
500 void close_gtab_pho_win ();
501 gboolean pre_punctuation_hsu (KeySym xkey);
502
feedkey_pho(KeySym xkey,int kbstate)503 int feedkey_pho (KeySym xkey, int kbstate) {
504 int ctyp = 0;
505 static unsigned int vv, ii;
506 static phokey_t key;
507 char *pp = NULL;
508 char kno;
509 int i, j, jj = 0, kk = 0;
510 char out_buffer[512];
511 int out_bufferN;
512 int shift_m = kbstate & ShiftMask;
513 int ctrl_m = kbstate & ControlMask;
514
515 if (ctrl_m)
516 return 0;
517
518 if (kbstate & LockMask) {
519 if (xkey >= 0x7e || xkey < ' ')
520 return FALSE;
521 if (hime_capslock_lower)
522 case_inverse (&xkey, shift_m);
523 send_ascii (xkey);
524 return 1;
525 }
526
527 if (xkey >= 'A' && xkey <= 'Z' && poo.typ_pho[0] != BACK_QUOTE_NO)
528 xkey += 0x20;
529
530 switch (xkey) {
531 case XK_Escape:
532 if (typ_pho_empty ())
533 return 0;
534 ClrPhoSelArea ();
535 clr_in_area_pho ();
536 if (is_gtab_query_mode ())
537 close_gtab_pho_win ();
538 return 1;
539 case XK_BackSpace:
540 poo.ityp3_pho = 0;
541 for (j = 3; j >= 0; j--)
542 if (poo.typ_pho[j]) {
543 poo.typ_pho[j] = 0;
544 if (typ_pho_empty ()) {
545 ClrSelArea ();
546 clr_in_area_pho ();
547 return 1;
548 }
549 break;
550 }
551
552 if (j < 0)
553 return 0;
554
555 goto llll3;
556 case '<':
557 if (!poo.ityp3_pho) {
558 return pre_punctuation (xkey);
559 }
560 if (poo.cpg >= phkbm.selkeyN)
561 poo.cpg -= phkbm.selkeyN;
562 goto proc_state;
563 case ' ':
564 if (!poo.typ_pho[0] && !poo.typ_pho[1] && !poo.typ_pho[2]) {
565 if (current_CS->b_half_full_char)
566 return full_char_proc (xkey);
567 return 0;
568 }
569
570 // dbg("poo.ityp3_pho %d\n", poo.ityp3_pho);
571 if (!poo.ityp3_pho) {
572 poo.ityp3_pho = TRUE;
573 goto lll1;
574 }
575
576 ii = poo.start_idx + poo.cpg + phkbm.selkeyN;
577
578 if (ii < poo.stop_idx) {
579 poo.cpg += phkbm.selkeyN;
580 dbg ("spc pool.cpg %d\n", poo.cpg);
581 } else {
582 if (poo.cpg) {
583 poo.cpg = 0;
584 ii = poo.start_idx;
585 } else {
586 putkey_pho (key, poo.start_idx);
587 return 1;
588 }
589 }
590
591 goto disp;
592 default:
593 if (xkey >= 127 || xkey < ' ')
594 return 0;
595
596 if (shift_m) {
597 // return shift_char_proc(xkey, kbstate);
598 if (pre_punctuation (xkey))
599 return 1;
600 return 0;
601 }
602
603 // dbg("poo.maxi:%d %d\n", poo.maxi, poo.cpg);
604
605 if ((pp = strchr (pho_selkey, xkey)) && poo.maxi && poo.ityp3_pho) {
606 int c = pp - pho_selkey;
607
608 if (c < poo.maxi) {
609 putkey_pho (key, poo.start_idx + poo.cpg + c);
610 }
611 return 1;
612 }
613
614 if (poo.ityp3_pho && !poo.cpg) {
615 // dbg("poo.start_idx: %d\n", poo.start_idx);
616 putkey_pho (key, poo.start_idx);
617 }
618
619 // poo.cpg=0;
620 }
621
622 lll1:
623 inph_typ_pho (xkey);
624 // dbg("typ_pho %x %x\n", poo.typ_pho[0], poo.typ_pho[1]);
625
626 if (hime_pop_up_win)
627 show_win_pho ();
628
629 if (poo.typ_pho[3])
630 ctyp = 3;
631
632 jj = 0;
633 kk = 1;
634 llll2:
635 if (ctyp == 3) {
636 poo.ityp3_pho = 1; /* last key is entered */
637 }
638 llll3:
639
640 key = pho2key (poo.typ_pho);
641
642 #if 0
643 dbg("poo.typ_pho %d %d %d %d\n", poo.typ_pho[0], poo.typ_pho[1], poo.typ_pho[2], poo.typ_pho[3]);
644 #endif
645 if (!key) {
646 return pre_punctuation_hsu (xkey);
647 }
648
649 pho_play (key);
650
651 vv = hash_pho[(int) poo.typ_pho[0]];
652 phokey_t ttt;
653 ttt = 0xffff;
654
655 while (vv < idxnum_pho) {
656 ttt = idx_pho[vv].key;
657 mask_key_typ_pho (&ttt);
658
659 if (ttt >= key)
660 break;
661 else
662 vv++;
663 }
664
665 // dbg("vv %d %d\n", vv, idxnum_pho);
666
667 if (ttt > key || (poo.ityp3_pho && idx_pho[vv].key != key)) {
668 // dbg("not found\n");
669 while (jj < 4) {
670 while (kk < 3)
671 if (phkbm.phokbm[(int) poo.inph[jj]][kk].num) {
672
673 if (kk) {
674 ctyp = phkbm.phokbm[(int) poo.inph[jj]][kk - 1].typ;
675 poo.typ_pho[ctyp] = 0;
676 }
677
678 kno = phkbm.phokbm[(int) poo.inph[jj]][kk].num;
679 ctyp = phkbm.phokbm[(int) poo.inph[jj]][kk].typ;
680 poo.typ_pho[ctyp] = kno;
681 kk++;
682 goto llll2;
683 } else
684 kk++;
685 jj++;
686 kk = 1;
687 }
688
689 bell ();
690 poo.ityp3_pho = poo.typ_pho[3] = 0;
691 disp_in_area_pho ();
692 return 1;
693 }
694
695 proc_state:
696 disp_in_area_pho ();
697 poo.start_idx = ii = idx_pho[vv].start;
698 poo.stop_idx = idx_pho[vv + 1].start;
699
700 // dbg("poo.start_idx: %d %d\n", poo.start_idx, poo.stop_idx);
701
702 if (poo.typ_pho[0] == L_BRACKET_NO || poo.typ_pho[0] == R_BRACKET_NO || (poo.typ_pho[0] == BACK_QUOTE_NO && poo.typ_pho[1]))
703 poo.ityp3_pho = 1;
704
705 ii += poo.cpg;
706
707 if (poo.ityp3_pho && poo.stop_idx - poo.start_idx == 1) {
708 putkey_pho (key, ii);
709 poo.maxi = poo.ityp3_pho = 0;
710 return 1;
711 }
712
713 disp:
714 i = 0;
715 out_bufferN = 0;
716 out_buffer[0] = 0;
717
718 if (poo.ityp3_pho) {
719 // dbg("poo.cpg %d\n", poo.cpg);
720
721 while (i < phkbm.selkeyN && ii < poo.stop_idx) {
722 char tt[512];
723 snprintf (tt, sizeof (tt), "<span foreground=\"%s\">%c</span>",
724 hime_sel_key_color, pho_selkey[i]);
725 int ttlen = strlen (tt);
726 memcpy (out_buffer + out_bufferN, tt, ttlen);
727 out_bufferN += ttlen;
728 // strcat(out_buffer, tt);
729 char *pho_str = pho_idx_str_markup (ii);
730 int len = strlen (pho_str);
731 memcpy (&out_buffer[out_bufferN], pho_str, len);
732 out_bufferN += len;
733 out_buffer[out_bufferN++] = ' ';
734
735 ii++;
736 i++;
737 }
738
739 char *tt = poo.cpg ? "<" : " ";
740 int ttlen = strlen (tt);
741 memcpy (out_buffer + out_bufferN, tt, ttlen);
742 out_bufferN += ttlen;
743
744 if (ii < poo.stop_idx) {
745 out_buffer[out_bufferN++] = poo.cpg ? '\\' : ' ';
746 tt = ">";
747 ttlen = strlen (tt);
748 memcpy (out_buffer + out_bufferN, tt, ttlen);
749 out_bufferN += strlen (tt);
750 }
751
752 poo.maxi = i;
753 } else {
754 while (i < phkbm.selkeyN && ii < poo.stop_idx) {
755 char *pho_str = pho_idx_str_markup (ii);
756 int len = strlen (pho_str);
757 memcpy (&out_buffer[out_bufferN], pho_str, len);
758 out_bufferN += len;
759
760 ii++;
761 i++;
762 }
763 poo.maxi = i;
764 }
765
766 out_buffer[out_bufferN] = 0;
767 disp_pho_sel (out_buffer);
768
769 return 1;
770 }
771
typ_pho_no_to_xkey(int typ,u_char num)772 static char typ_pho_no_to_xkey (int typ, u_char num) {
773 int i, j;
774
775 for (i = ' '; i < 127; i++)
776 for (j = 0; j < 3; j++)
777 if (phkbm.phokbm[i][j].typ == typ && phkbm.phokbm[i][j].num == num)
778 return i;
779
780 return 0;
781 }
782
start_gtab_pho_query(char * utf8)783 void start_gtab_pho_query (char *utf8) {
784 phokey_t phokeys[32];
785 int phokeysN, i;
786
787 phokeysN = utf8_pho_keys (utf8, phokeys);
788 if (phokeysN <= 0)
789 return;
790
791 u_char rtyp_pho[4];
792 memset (rtyp_pho, 0, sizeof (rtyp_pho));
793 key_typ_pho (phokeys[0], rtyp_pho);
794
795 char xkeys[4];
796 memset (xkeys, 0, sizeof (xkeys));
797
798 for (i = 0; i < 4; i++) {
799 if (!rtyp_pho[i])
800 continue;
801
802 xkeys[i] = typ_pho_no_to_xkey (i, rtyp_pho[i]);
803 }
804
805 if (!xkeys[3])
806 xkeys[3] = ' ';
807
808 for (i = 0; i < 4; i++) {
809 feedkey_pho (xkeys[i], 0);
810 }
811 }
812
pho_reset()813 void pho_reset () {
814 }
815
816 #include "im-client/hime-im-client-attr.h"
817 extern GtkWidget *gwin_pho;
818
pho_get_preedit(char * str,HIME_PREEDIT_ATTR attr[],int * cursor,int * sub_comp_len)819 int pho_get_preedit (char *str, HIME_PREEDIT_ATTR attr[], int *cursor, int *sub_comp_len) {
820 *sub_comp_len = !typ_pho_empty ();
821 ;
822 if (gwin_pho && gtk_widget_get_visible (gwin_pho))
823 *sub_comp_len |= 2;
824 *cursor = 0;
825 str[0] = 0;
826 return 0;
827 }
828
829 static PHO_ST temp_pho_st;
pho_save_gst()830 void pho_save_gst () {
831 temp_pho_st = poo;
832 }
833
pho_restore_gst()834 void pho_restore_gst () {
835 poo = temp_pho_st;
836 }
837