1 /*
2  * mod_aux.c
3  *
4  * Copyright (c) 2005, 2006, 2008, 2009, 2012-2014
5  *      libchewing Core Team. See ChangeLog for details.
6  *
7  * See the file "COPYING" for information on usage and redistribution
8  * of this file.
9  */
10 
11 /**
12  * @file mod_aux.c
13  * @brief Auxiliary module
14  */
15 
16 #include <string.h>
17 #include <stdlib.h>
18 
19 #include "global.h"
20 #include "chewing-private.h"
21 #include "bopomofo-private.h"
22 #include "chewingio.h"
23 #include "chewing-utf8-util.h"
24 #include "private.h"
25 
26 /**
27  * @param ctx handle to Chewing IM context
28  * @retval TRUE if it currnet input state is at the "end-of-a-char"
29  */
chewing_commit_Check(const ChewingContext * ctx)30 CHEWING_API int chewing_commit_Check(const ChewingContext *ctx)
31 {
32     const ChewingData *pgdata;
33 
34     if (!ctx) {
35         return -1;
36     }
37     pgdata = ctx->data;
38 
39     LOG_API("");
40 
41     return ! !(ctx->output->keystrokeRtn & KEYSTROKE_COMMIT);
42 }
43 
44 /**
45  * @param ctx handle to Chewing IM context
46  *
47  * retrun current commit string, regardless current input state.
48  * Always returns a char pointer, caller must free it.
49  */
chewing_commit_String(const ChewingContext * ctx)50 CHEWING_API char *chewing_commit_String(const ChewingContext *ctx)
51 {
52     const ChewingData *pgdata;
53 
54     if (!ctx) {
55         return strdup("");
56     }
57     pgdata = ctx->data;
58 
59     LOG_API("");
60 
61     return strdup(ctx->output->commitBuf);
62 }
63 
64 /**
65  * @param ctx handle to Chewing IM context
66  * retrun current commit string, regardless current input state.
67  * Always returns a const char pointer, you have to clone them immediately,
68  * if you need.
69  */
chewing_commit_String_static(const ChewingContext * ctx)70 CHEWING_API const char *chewing_commit_String_static(const ChewingContext *ctx)
71 {
72     const ChewingData *pgdata;
73 
74     if (!ctx) {
75         return "";
76     }
77     pgdata = ctx->data;
78 
79     LOG_API("");
80 
81     return ctx->output->commitBuf;
82 }
83 
chewing_buffer_Check(const ChewingContext * ctx)84 CHEWING_API int chewing_buffer_Check(const ChewingContext *ctx)
85 {
86     const ChewingData *pgdata;
87 
88     if (!ctx) {
89         return -1;
90     }
91     pgdata = ctx->data;
92 
93     LOG_API("");
94 
95     return (ctx->output->chiSymbolBufLen != 0);
96 }
97 
chewing_buffer_Len(const ChewingContext * ctx)98 CHEWING_API int chewing_buffer_Len(const ChewingContext *ctx)
99 {
100     const ChewingData *pgdata;
101 
102     if (!ctx) {
103         return -1;
104     }
105     pgdata = ctx->data;
106 
107     LOG_API("");
108 
109     return ctx->output->chiSymbolBufLen;
110 }
111 
chewing_buffer_String(const ChewingContext * ctx)112 CHEWING_API char *chewing_buffer_String(const ChewingContext *ctx)
113 {
114     const ChewingData *pgdata;
115 
116     if (!ctx) {
117         return strdup("");
118     }
119     pgdata = ctx->data;
120 
121     LOG_API("");
122 
123     return strdup(ctx->output->preeditBuf);
124 }
125 
chewing_buffer_String_static(const ChewingContext * ctx)126 CHEWING_API const char *chewing_buffer_String_static(const ChewingContext *ctx)
127 {
128     const ChewingData *pgdata;
129 
130     if (!ctx) {
131         return "";
132     }
133     pgdata = ctx->data;
134 
135     LOG_API("");
136 
137     return ctx->output->preeditBuf;
138 }
139 
140 /**
141  * @param ctx handle to Chewing IM context
142  *
143  * Always returns a const char pointer, you have to clone them immediately,
144  * if you need.
145  */
chewing_bopomofo_String_static(const ChewingContext * ctx)146 CHEWING_API const char *chewing_bopomofo_String_static(const ChewingContext *ctx)
147 {
148     const ChewingData *pgdata;
149 
150     if (!ctx) {
151         return "";
152     }
153     pgdata = ctx->data;
154 
155     LOG_API("");
156 
157     return ctx->output->bopomofoBuf;
158 }
159 
chewing_bopomofo_Check(const ChewingContext * ctx)160 CHEWING_API int chewing_bopomofo_Check(const ChewingContext *ctx)
161 {
162     const ChewingData *pgdata;
163 
164     if (!ctx) {
165         return -1;
166     }
167     pgdata = ctx->data;
168 
169     LOG_API("");
170 
171     return ctx->output->bopomofoBuf[0] != 0;
172 }
173 
chewing_cursor_Current(const ChewingContext * ctx)174 CHEWING_API int chewing_cursor_Current(const ChewingContext *ctx)
175 {
176     const ChewingData *pgdata;
177 
178     if (!ctx) {
179         return -1;
180     }
181     pgdata = ctx->data;
182 
183     LOG_API("");
184 
185     return (ctx->output->chiSymbolCursor);
186 }
187 
chewing_cand_CheckDone(const ChewingContext * ctx)188 CHEWING_API int chewing_cand_CheckDone(const ChewingContext *ctx)
189 {
190     const ChewingData *pgdata;
191 
192     if (!ctx) {
193         return -1;
194     }
195     pgdata = ctx->data;
196 
197     LOG_API("");
198 
199     return (!ctx->output->pci);
200 }
201 
chewing_cand_TotalPage(const ChewingContext * ctx)202 CHEWING_API int chewing_cand_TotalPage(const ChewingContext *ctx)
203 {
204     const ChewingData *pgdata;
205 
206     if (!ctx) {
207         return -1;
208     }
209     pgdata = ctx->data;
210 
211     LOG_API("");
212 
213     return (ctx->output->pci ? ctx->output->pci->nPage : 0);
214 }
215 
chewing_cand_ChoicePerPage(const ChewingContext * ctx)216 CHEWING_API int chewing_cand_ChoicePerPage(const ChewingContext *ctx)
217 {
218     const ChewingData *pgdata;
219 
220     if (!ctx) {
221         return -1;
222     }
223     pgdata = ctx->data;
224 
225     LOG_API("");
226 
227     return (ctx->output->pci ? ctx->output->pci->nChoicePerPage : 0);
228 }
229 
chewing_cand_TotalChoice(const ChewingContext * ctx)230 CHEWING_API int chewing_cand_TotalChoice(const ChewingContext *ctx)
231 {
232     const ChewingData *pgdata;
233 
234     if (!ctx) {
235         return -1;
236     }
237     pgdata = ctx->data;
238 
239     LOG_API("");
240 
241     return (ctx->output->pci ? ctx->output->pci->nTotalChoice : 0);
242 }
243 
chewing_cand_CurrentPage(const ChewingContext * ctx)244 CHEWING_API int chewing_cand_CurrentPage(const ChewingContext *ctx)
245 {
246     const ChewingData *pgdata;
247 
248     if (!ctx) {
249         return -1;
250     }
251     pgdata = ctx->data;
252 
253     LOG_API("");
254 
255     return (ctx->output->pci ? ctx->output->pci->pageNo : -1);
256 }
257 
chewing_cand_Enumerate(ChewingContext * ctx)258 CHEWING_API void chewing_cand_Enumerate(ChewingContext *ctx)
259 {
260     ChewingData *pgdata;
261 
262     if (!ctx) {
263         return;
264     }
265     pgdata = ctx->data;
266 
267     LOG_API("");
268 
269     ctx->cand_no = ctx->output->pci->pageNo * ctx->output->pci->nChoicePerPage;
270 }
271 
chewing_cand_hasNext(ChewingContext * ctx)272 CHEWING_API int chewing_cand_hasNext(ChewingContext *ctx)
273 {
274     ChewingData *pgdata;
275 
276     if (!ctx) {
277         return -1;
278     }
279     pgdata = ctx->data;
280 
281     LOG_API("");
282 
283     return (ctx->cand_no < ctx->output->pci->nTotalChoice);
284 }
285 
chewing_cand_String_static(ChewingContext * ctx)286 CHEWING_API const char *chewing_cand_String_static(ChewingContext *ctx)
287 {
288     ChewingData *pgdata;
289     const char *s = "";
290 
291     if (!ctx) {
292         return s;
293     }
294     pgdata = ctx->data;
295 
296     LOG_API("");
297 
298     if (chewing_cand_hasNext(ctx)) {
299         s = ctx->output->pci->totalChoiceStr[ctx->cand_no];
300         ctx->cand_no++;
301     }
302 
303     return s;
304 }
305 
chewing_cand_String(ChewingContext * ctx)306 CHEWING_API char *chewing_cand_String(ChewingContext *ctx)
307 {
308     return strdup(chewing_cand_String_static(ctx));
309 }
310 
chewing_interval_Enumerate(ChewingContext * ctx)311 CHEWING_API void chewing_interval_Enumerate(ChewingContext *ctx)
312 {
313     ChewingData *pgdata;
314 
315     if (!ctx) {
316         return;
317     }
318     pgdata = ctx->data;
319 
320     LOG_API("");
321 
322     ctx->it_no = 0;
323 }
324 
chewing_interval_hasNext(ChewingContext * ctx)325 CHEWING_API int chewing_interval_hasNext(ChewingContext *ctx)
326 {
327     ChewingData *pgdata;
328 
329     if (!ctx) {
330         return -1;
331     }
332     pgdata = ctx->data;
333 
334     LOG_API("");
335 
336     return (ctx->it_no < ctx->output->nDispInterval);
337 }
338 
chewing_interval_Get(ChewingContext * ctx,IntervalType * it)339 CHEWING_API void chewing_interval_Get(ChewingContext *ctx, IntervalType * it)
340 {
341     ChewingData *pgdata;
342 
343     if (!ctx) {
344         return;
345     }
346     pgdata = ctx->data;
347 
348     LOG_API("");
349 
350     if (chewing_interval_hasNext(ctx)) {
351         if (it) {
352             it->from = ctx->output->dispInterval[ctx->it_no].from;
353             it->to = ctx->output->dispInterval[ctx->it_no].to;
354         }
355         ctx->it_no++;
356     }
357 }
358 
chewing_aux_Check(const ChewingContext * ctx)359 CHEWING_API int chewing_aux_Check(const ChewingContext *ctx)
360 {
361     const ChewingData *pgdata;
362 
363     if (!ctx) {
364         return -1;
365     }
366     pgdata = ctx->data;
367 
368     LOG_API("");
369 
370     return (ctx->data->bShowMsg);
371 }
372 
chewing_aux_Length(const ChewingContext * ctx)373 CHEWING_API int chewing_aux_Length(const ChewingContext *ctx)
374 {
375     const ChewingData *pgdata;
376 
377     if (!ctx) {
378         return -1;
379     }
380     pgdata = ctx->data;
381 
382     LOG_API("");
383 
384     return (ctx->data->bShowMsg ? ctx->data->showMsgLen : 0);
385 }
386 
chewing_aux_String_static(const ChewingContext * ctx)387 CHEWING_API const char *chewing_aux_String_static(const ChewingContext *ctx)
388 {
389     const ChewingData *pgdata;
390 
391     if (!ctx) {
392         return "";
393     }
394     pgdata = ctx->data;
395 
396     LOG_API("");
397 
398     return ctx->data->showMsg;
399 }
400 
chewing_aux_String(const ChewingContext * ctx)401 CHEWING_API char *chewing_aux_String(const ChewingContext *ctx)
402 {
403     const ChewingData *pgdata;
404 
405     if (!ctx) {
406         return strdup("");
407     }
408     pgdata = ctx->data;
409 
410     LOG_API("");
411 
412     return strdup(chewing_aux_String_static(ctx));
413 }
414 
chewing_keystroke_CheckIgnore(const ChewingContext * ctx)415 CHEWING_API int chewing_keystroke_CheckIgnore(const ChewingContext *ctx)
416 {
417     const ChewingData *pgdata;
418 
419     if (!ctx) {
420         return -1;
421     }
422     pgdata = ctx->data;
423 
424     LOG_API("");
425 
426     return ! !(ctx->output->keystrokeRtn & KEYSTROKE_IGNORE);
427 }
428 
chewing_keystroke_CheckAbsorb(const ChewingContext * ctx)429 CHEWING_API int chewing_keystroke_CheckAbsorb(const ChewingContext *ctx)
430 {
431     const ChewingData *pgdata;
432 
433     if (!ctx) {
434         return -1;
435     }
436     pgdata = ctx->data;
437 
438     LOG_API("");
439 
440     return ! !(ctx->output->keystrokeRtn & KEYSTROKE_ABSORB);
441 }
442 
chewing_kbtype_Total(const ChewingContext * ctx UNUSED)443 CHEWING_API int chewing_kbtype_Total(const ChewingContext *ctx UNUSED)
444 {
445     return KB_TYPE_NUM;
446 }
447 
chewing_kbtype_Enumerate(ChewingContext * ctx)448 CHEWING_API void chewing_kbtype_Enumerate(ChewingContext *ctx)
449 {
450     ChewingData *pgdata;
451 
452     if (!ctx) {
453         return;
454     }
455     pgdata = ctx->data;
456 
457     LOG_API("");
458 
459     ctx->kb_no = 0;
460 }
461 
chewing_kbtype_hasNext(ChewingContext * ctx)462 CHEWING_API int chewing_kbtype_hasNext(ChewingContext *ctx)
463 {
464     ChewingData *pgdata;
465 
466     if (!ctx) {
467         return -1;
468     }
469     pgdata = ctx->data;
470 
471     LOG_API("");
472 
473     return ctx->kb_no < KB_TYPE_NUM;
474 }
475 
476 extern const char *const kb_type_str[];
477 
chewing_kbtype_String_static(ChewingContext * ctx)478 CHEWING_API const char *chewing_kbtype_String_static(ChewingContext *ctx)
479 {
480     ChewingData *pgdata;
481     const char *s = "";
482 
483     if (!ctx) {
484         return s;
485     }
486     pgdata = ctx->data;
487 
488     LOG_API("");
489 
490     if (chewing_kbtype_hasNext(ctx)) {
491         s = kb_type_str[ctx->kb_no];
492         ctx->kb_no++;
493     }
494 
495     return s;
496 }
497 
chewing_kbtype_String(ChewingContext * ctx)498 CHEWING_API char *chewing_kbtype_String(ChewingContext *ctx)
499 {
500     ChewingData *pgdata;
501 
502     if (!ctx) {
503         return strdup("");
504     }
505     pgdata = ctx->data;
506 
507     LOG_API("");
508 
509     return strdup(chewing_kbtype_String_static(ctx));
510 }
511