Codebase list fcitx-cloudpinyin / 9f4e530
Imported Upstream version 0.1.2 Aron Xu 12 years ago
5 changed file(s) with 194 addition(s) and 26 deletion(s). Raw diff Collapse all Expand all
11 cmake_minimum_required(VERSION 2.6)
22
33 set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
4 find_package(Fcitx 4.1.1 REQUIRED)
4 find_package(Fcitx 4.1.2 REQUIRED)
55 find_package(PkgConfig REQUIRED)
66 find_package(Gettext REQUIRED)
77 find_package(Libintl REQUIRED)
8 find_package(Libiconv REQUIRED)
89
910 # uninstall target
1011 configure_file(
0 # Try to find Libiconv functionality
1 # Once done this will define
2 #
3 # LIBICONV_FOUND - system has Libiconv
4 # LIBICONV_INCLUDE_DIR - Libiconv include directory
5 # LIBICONV_LIBRARIES - Libraries needed to use Libiconv
6 #
7 # TODO: This will enable translations only if Gettext functionality is
8 # present in libc. Must have more robust system for release, where Gettext
9 # functionality can also reside in standalone Gettext library, or the one
10 # embedded within kdelibs (cf. gettext.m4 from Gettext source).
11
12 # Copyright (c) 2006, Chusslove Illich, <caslav.ilic@gmx.net>
13 # Copyright (c) 2007, Alexander Neundorf, <neundorf@kde.org>
14 #
15 # Redistribution and use is allowed according to the terms of the BSD license.
16 # For details see the accompanying COPYING-CMAKE-SCRIPTS file.
17
18 if(LIBICONV_INCLUDE_DIR AND LIBICONV_LIB_FOUND)
19 set(Libiconv_FIND_QUIETLY TRUE)
20 endif(LIBICONV_INCLUDE_DIR AND LIBICONV_LIB_FOUND)
21
22 find_path(LIBICONV_INCLUDE_DIR iconv.h)
23
24 set(LIBICONV_LIB_FOUND FALSE)
25
26 if(LIBICONV_INCLUDE_DIR)
27 include(CheckFunctionExists)
28 check_function_exists(iconv_open LIBICONV_LIBC_HAS_ICONV_OPEN)
29
30 if (LIBICONV_LIBC_HAS_ICONV_OPEN)
31 set(LIBICONV_LIBRARIES)
32 set(LIBICONV_LIB_FOUND TRUE)
33 else (LIBICONV_LIBC_HAS_ICONV_OPEN)
34 find_library(LIBICONV_LIBRARIES NAMES iconv)
35 if(LIBICONV_LIBRARIES)
36 set(LIBICONV_LIB_FOUND TRUE)
37 endif(LIBICONV_LIBRARIES)
38 endif (LIBICONV_LIBC_HAS_ICONV_OPEN)
39
40 endif(LIBICONV_INCLUDE_DIR)
41
42 include(FindPackageHandleStandardArgs)
43 find_package_handle_standard_args(Libiconv DEFAULT_MSG LIBICONV_INCLUDE_DIR LIBICONV_LIB_FOUND)
44
45 mark_as_advanced(LIBICONV_INCLUDE_DIR LIBICONV_LIBRARIES LIBICONV_LIBC_HAS_ICONV_OPEN LIBICONV_LIB_FOUND)
2828 #include <fcitx-config/xdg.h>
2929 #include <fcitx/module/pinyin/pydef.h>
3030 #include <errno.h>
31
32 #define CHECK_VALID_IM (strcmp(im->strIconName, "pinyin") == 0 || \
33 strcmp(im->strIconName, "googlepinyin") == 0 || \
34 strcmp(im->strIconName, "sunpinyin") == 0 || \
35 strcmp(im->strIconName, "shuangpin") == 0)
31 #include <iconv.h>
32
33 #define CHECK_VALID_IM (im && \
34 (strcmp(im->uniqueName, "pinyin") == 0 || \
35 strcmp(im->uniqueName, "googlepinyin") == 0 || \
36 strcmp(im->uniqueName, "sunpinyin") == 0 || \
37 strcmp(im->uniqueName, "shuangpin") == 0))
3638
3739 #define LOGLEVEL DEBUG
3840
6668 static void SaveCloudPinyinConfig(FcitxCloudPinyinConfig* fs);
6769 static char *GetCurrentString(FcitxCloudPinyin* cloudpinyin);
6870 static char* SplitHZAndPY(char* string);
69 void CloudPinyinOnTriggerOn(void* arg);
71 void CloudPinyinHookForNewRequest(void* arg);
7072
7173 void SogouParseKey(FcitxCloudPinyin* cloudpinyin, CurlQueue* queue);
7274 char* SogouParsePinyin(FcitxCloudPinyin* cloudpinyin, CurlQueue* queue);
7375 void QQParseKey(FcitxCloudPinyin* cloudpinyin, CurlQueue* queue);
7476 char* QQParsePinyin(FcitxCloudPinyin* cloudpinyin, CurlQueue* queue);
7577 char* GoogleParsePinyin(FcitxCloudPinyin* cloudpinyin, CurlQueue* queue);
76
77 CloudPinyinEngine engine[3] =
78 char* BaiduParsePinyin(FcitxCloudPinyin* cloudpinyin, CurlQueue* queue);
79
80 CloudPinyinEngine engine[4] =
7881 {
7982 {
8083 "http://web.pinyin.sogou.com/web_ime/patch.php",
9396 "http://www.google.com/inputtools/request?ime=pinyin&text=%s",
9497 NULL,
9598 GoogleParsePinyin
99 },
100 {
101 NULL,
102 "http://olime.baidu.com/py?py=%s&rn=0&pn=1&ol=1",
103 NULL,
104 BaiduParsePinyin
96105 }
97106 };
98107
108117 CloudPinyinReloadConfig
109118 };
110119
120 FCITX_EXPORT_API
121 int ABI_VERSION = FCITX_ABI_VERSION;
122
123 static inline boolean ishex(char ch)
124 {
125 if ((ch >= '0' && ch <= '9') || (ch >='a' && ch <='f') || (ch >='A' && ch <='F'))
126 return true;
127 return false;
128 }
129
130 static inline unsigned char tohex(char ch)
131 {
132 if (ch >= '0' && ch <= '9')
133 return ch - '0';
134 if (ch >='a' && ch <='f')
135 return ch - 'a' + 10;
136 if (ch >='A' && ch <='F')
137 return ch - 'A' + 10;
138 return 0;
139 }
140
111141 void* CloudPinyinCreate(FcitxInstance* instance)
112142 {
113143 FcitxCloudPinyin* cloudpinyin = fcitx_malloc0(sizeof(FcitxCloudPinyin));
138168 RegisterUpdateCandidateWordHook(instance, hook);
139169
140170 hook.arg = cloudpinyin;
141 hook.func = CloudPinyinOnTriggerOn;
142
171 hook.func = CloudPinyinHookForNewRequest;
172
173 RegisterResetInputHook(instance, hook);
174 RegisterInputFocusHook(instance, hook);
175 RegisterInputUnFocusHook(instance, hook);
143176 RegisterTriggerOnHook(instance, hook);
144177
145178 CloudPinyinRequestKey(cloudpinyin);
151184 {
152185 FcitxCloudPinyin* cloudpinyin = (FcitxCloudPinyin*) arg;
153186 FcitxIM* im = GetCurrentIM(cloudpinyin->owner);
154 FcitxInputState* input = &cloudpinyin->owner->input;
187 FcitxInputState* input = FcitxInstanceGetInputState(cloudpinyin->owner);
155188
156189 if (cloudpinyin->initialized == false)
157190 return;
160193 if (CHECK_VALID_IM)
161194 {
162195 /* there is something pending input */
163 if (strlen(input->strCodeInput) >= cloudpinyin->config.iMinimumPinyinLength)
196 if (FcitxInputStateGetRawInputBufferSize(input) >= cloudpinyin->config.iMinimumPinyinLength)
164197 {
165198 char* strToFree = NULL, *inputString;
166199 strToFree = GetCurrentString(cloudpinyin);
233266 FcitxCloudPinyin* cloudpinyin = (FcitxCloudPinyin*) arg;
234267 FcitxInstance* instance = cloudpinyin->owner;
235268 int maxfd = 0;
236 curl_multi_fdset(cloudpinyin->curlm, &instance->rfds, &instance->wfds, &instance->efds, &maxfd);
237 if (maxfd > instance->maxfd)
238 instance->maxfd = maxfd;
269 curl_multi_fdset(cloudpinyin->curlm,
270 FcitxInstanceGetReadFDSet(instance),
271 FcitxInstanceGetWriteFDSet(instance),
272 FcitxInstanceGetExceptFDSet(instance),
273 &maxfd);
274 if (maxfd > FcitxInstanceGetMaxFD(instance))
275 FcitxInstanceSetMaxFD(instance, maxfd);
239276 }
240277
241278 void CloudPinyinProcessEvent(void* arg)
463500 void _CloudPinyinAddCandidateWord(FcitxCloudPinyin* cloudpinyin, const char* pinyin)
464501 {
465502 CloudPinyinCache* cacheEntry = CloudPinyinCacheLookup(cloudpinyin, pinyin);
503 FcitxInputState* input = FcitxInstanceGetInputState(cloudpinyin->owner);
466504
467505 CandidateWord candWord;
468506 CloudCandWord* cloudCand = fcitx_malloc0(sizeof(CloudCandWord));
489527 if (order < 0)
490528 order = 0;
491529
492 CandidateWordInsert(cloudpinyin->owner->input.candList, &candWord, order);
530 CandidateWordInsert(FcitxInputStateGetCandidateList(input), &candWord, order);
493531 }
494532
495533 void CloudPinyinFillCandidateWord(FcitxCloudPinyin* cloudpinyin, const char* pinyin)
496534 {
497535 CloudPinyinCache* cacheEntry = CloudPinyinCacheLookup(cloudpinyin, pinyin);
498 FcitxInputState* input = &cloudpinyin->owner->input;
536 FcitxInputState* input = FcitxInstanceGetInputState(cloudpinyin->owner);
499537 if (cacheEntry)
500538 {
501539 CandidateWord* candWord;
502 for (candWord = CandidateWordGetFirst(input->candList);
540 for (candWord = CandidateWordGetFirst(FcitxInputStateGetCandidateList(input));
503541 candWord != NULL;
504 candWord = CandidateWordGetNext(input->candList, candWord))
542 candWord = CandidateWordGetNext(FcitxInputStateGetCandidateList(input), candWord))
505543 {
506544 if (candWord->owner == cloudpinyin)
507545 break;
525563 {
526564 FcitxCloudPinyin* cloudpinyin = (FcitxCloudPinyin*) arg;
527565 CloudCandWord* cloudCand = candWord->priv;
566 FcitxInputState* input = FcitxInstanceGetInputState(cloudpinyin->owner);
528567 if (cloudCand->filled)
529568 {
530569 char* string = GetCurrentString(cloudpinyin);
533572 {
534573 *py = 0;
535574
536 snprintf(GetOutputString(&cloudpinyin->owner->input), MAX_USER_INPUT, "%s%s", string, candWord->strWord);
575 snprintf(GetOutputString(input), MAX_USER_INPUT, "%s%s", string, candWord->strWord);
576
577 FcitxIM* im = GetCurrentIM(cloudpinyin->owner);
578 FcitxModuleFunctionArg args;
579 args.args[0] = GetOutputString(input);
580 if (im)
581 {
582 if (strcmp(im->strIconName, "sunpinyin") == 0)
583 {
584 //InvokeModuleFunctionWithName(cloudpinyin->owner, "fcitx-sunpinyin", 1, args);
585 }
586 else if (strcmp(im->strIconName, "shuangpin") == 0 || strcmp(im->strIconName, "pinyin") == 0)
587 {
588 InvokeModuleFunctionWithName(cloudpinyin->owner, "fcitx-pinyin", 7, args);
589 }
590 }
537591 }
538592 if (string)
539593 free(string);
589643 char *GetCurrentString(FcitxCloudPinyin* cloudpinyin)
590644 {
591645 FcitxIM* im = GetCurrentIM(cloudpinyin->owner);
592 char* string = MessagesToCString(cloudpinyin->owner->input.msgPreedit);
646 if (!im)
647 return NULL;
648 FcitxInputState* input = FcitxInstanceGetInputState(cloudpinyin->owner);
649 char* string = MessagesToCString(FcitxInputStateGetPreedit(input));
593650 char p[MAX_USER_INPUT + 1], *pinyin, *lastpos;
594651 pinyin = SplitHZAndPY(string);
595652 lastpos = pinyin;
776833 return NULL;
777834 }
778835
779
780 void CloudPinyinOnTriggerOn(void* arg)
836 char* BaiduParsePinyin(FcitxCloudPinyin* cloudpinyin, CurlQueue* queue)
837 {
838 char *start = NULL, *end = NULL;
839 static iconv_t conv = 0;
840 if (conv == 0)
841 conv = iconv_open("utf-8", "utf-16be");
842
843 if (conv == (iconv_t)(-1))
844 return NULL;
845 if ((start = strstr(queue->str, "[[[\"")) != NULL)
846 {
847 start += strlen( "[[[\"");
848 if ((end = strstr(start, "\",")) != NULL)
849 {
850 size_t length = end - start;
851 if (length % 6 != 0 || length == 0)
852 return NULL;
853
854 size_t i = 0, j = 0;
855 char* buf = fcitx_malloc0((length / 6 + 1) * 2);
856 while (i < length)
857 {
858 if (start[i] == '\\' && start[i+1] == 'u')
859 {
860 if (ishex(start[i+2]) && ishex(start[i+3]) && ishex(start[i+4]) && ishex(start[i+5]))
861 {
862 buf[j++] = (tohex(start[i+2]) << 4) | tohex(start[i+3]);
863 buf[j++] = (tohex(start[i+4]) << 4) | tohex(start[i+5]);
864 }
865 else
866 break;
867 }
868
869 i += 6;
870 }
871
872 if (i != length)
873 {
874 free(buf);
875 return NULL;
876 }
877 buf[j++] = 0;
878 buf[j++] = 0;
879 size_t len = UTF8_MAX_LENGTH * (length / 6) * sizeof(char);
880 char* realstring = fcitx_malloc0(UTF8_MAX_LENGTH * (length / 6) * sizeof(char));
881 char* p = buf, *pp = realstring;
882 iconv(conv, &p, &j, &pp, &len);
883
884 free(buf);
885 if (utf8_check_string(realstring))
886 return realstring;
887 else
888 {
889 free(realstring);
890 return NULL;
891 }
892 }
893 }
894 return NULL;
895 }
896
897
898
899 void CloudPinyinHookForNewRequest(void* arg)
781900 {
782901 FcitxCloudPinyin* cloudpinyin = (FcitxCloudPinyin*) arg;
783902 if (!cloudpinyin->initialized && !cloudpinyin->isrequestkey)
3636 {
3737 CloudPinyin_Sogou = 0,
3838 CloudPinyin_QQ = 1,
39 CloudPinyin_Google = 2
39 CloudPinyin_Google = 2,
40 CloudPinyin_Baidu = 3
4041 } CloudPinyinSource;
4142
4243 typedef enum _CloudPinyinRequestType
1616 Type=Enum
1717 DefaultValue=Sogou
1818 Description=Cloud Pinyin Source
19 EnumCount=3
19 EnumCount=4
2020 Enum0=Sogou
2121 Enum1=QQ
2222 Enum2=Google
23 Enum3=Baidu
2324
2425 [DescriptionFile]
2526 LocaleDomain=fcitx-cloudpinyin