1 #define Uses_SCIM_IMENGINE
2 #define Uses_SCIM_ICONV
3 #define Uses_SCIM_CONFIG_BASE
4 #define Uses_SCIM_CONFIG_PATH
5 #include <cstring>
6 #include <ctype.h>
7 #include <cstring>
8 
9 #include <scim.h>
10 #include "scim_fcitx_imengine.h"
11 using namespace scim;
12 
13 #include "xim.h"
14 #include "ime.h"
15 #include "punc.h"
16 #include "table.h"
17 #include "py.h"
18 #include "tools.h"
19 #include "sp.h"
20 #include "qw.h"
21 
22 
23 int             iCursorPos;
24 IM             *im = NULL;
25 INT8            iIMCount = 0;
26 
27 int             iMaxCandWord = 8;
28 int             iCandPageCount;
29 int             iCurrentCandPage;
30 int             iCandWordCount;
31 
32 int             iLegendCandWordCount;
33 int             iLegendCandPageCount;
34 int             iCurrentLegendCandPage;
35 
36 int             iCodeInputCount;
37 
38 // *************************************************************
39 char            strCodeInput[MAX_USER_INPUT + 1];
40 char            strStringGet[MAX_USER_INPUT + 1];	//�������뷨���ص���Ҫ�͵��ͻ������е��ִ�
41 unsigned int    messageColor[MESSAGE_TYPE_COUNT] = {
42     SCIM_RGB_COLOR(255, 0, 0),
43     SCIM_RGB_COLOR(0, 0, 255),
44     SCIM_RGB_COLOR(200, 0, 0),
45     SCIM_RGB_COLOR(0, 150, 100),
46     SCIM_RGB_COLOR(0, 0, 255),
47     SCIM_RGB_COLOR(100, 100, 255),
48     SCIM_RGB_COLOR(0, 0, 0)
49 };
50 unsigned int    cursorColor = SCIM_RGB_COLOR(92, 210, 131);
51 // *************************************************************
52 
53 ENTER_TO_DO     enterToDo = K_ENTER_SEND;
54 
55 Bool            bCorner = False;	//ȫ����л�
56 Bool            bChnPunc = True;	//��Ӣ�ı���л�
57 Bool            bUseGBK = False;	//�Ƿ�֧��GBK
58 Bool            bIsDoInputOnly = False;	//�����Ƿ�ֻ�����뷨���������
59 Bool            bLastIsNumber = False;	//��һ�������Dz��ǰ���������
60 Bool            bInCap = False;	//�Dz��Ǵ��ڴ�д���Ӣ��״̬
61 Bool            bAutoHideInputWindow = True;	//�Ƿ��Զ�����������
62 Bool            bEngPuncAfterNumber = True;	//���ֺ��������Ƿ���(ֻ��'.'/','��Ч)
63 Bool            bPhraseTips = False;
64 INT8            lastIsSingleHZ = 0;
65 
66 Bool            bEngAfterSemicolon = True;
67 Bool            bEngAfterCap = True;
68 Bool            bDisablePagingInLegend = True;
69 
70 KeyEvent             i2ndSelectKey = KeyEvent("Control+Control_L");	//�ڶ�����ѡ��ѡ�����Ϊɨ����
71 KeyEvent             i2ndSelectKeyPress = KeyEvent("Control_L");	//�ڶ�����ѡ��ѡ�����Ϊɨ����
72 KeyEvent             i3rdSelectKey = KeyEvent("Control+Control_R");	//��������ѡ��ѡ�����Ϊɨ����
73 KeyEvent             i3rdSelectKeyPress = KeyEvent("Control_R");	//��������ѡ��ѡ�����Ϊɨ����
74 
75 
76 KEY_RELEASED    keyReleased = KR_OTHER;
77 Bool		bDoubleSwitchKey = False;
78 KeyEvent         switchKey = KeyEvent("Shift+Shift_L");
79 KeyEvent         switchKeyPress = KeyEvent("Shift_L");
80 
81 //�ȼ�����
82 
83 KeyEvent         hkGBK[HOT_KEY_COUNT] = { KeyEvent("Alt+m"), KeyEvent()  };
84 KeyEvent         hkLegend[HOT_KEY_COUNT] = { KeyEvent("Alt+l"), KeyEvent() };
85 KeyEvent         hkCorner[HOT_KEY_COUNT] = { KeyEvent("Shift+space"), KeyEvent() };	//ȫ����л�
86 KeyEvent         hkPunc[HOT_KEY_COUNT] = { KeyEvent("Alt+space"), KeyEvent() };	//���ı��
87 KeyEvent         hkNextPage[HOT_KEY_COUNT] = { KeyEvent("period"),KeyEvent() };
88 KeyEvent         hkPrevPage[HOT_KEY_COUNT] = { KeyEvent("comma"), KeyEvent() };
89 
90 
91 Bool            bUseLegend = False;
92 Bool            bIsInLegend = False;
93 
94 INT8            iIMIndex = 0;
95 Bool            bUsePinyin = True;
96 Bool            bUseSP = False;
97 Bool            bUseQW = False;
98 Bool            bUseTable = True;
99 
100 
101 MESSAGE         messageUp[32];
102 uint            uMessageUp = 0;
103 MESSAGE         messageDown[32];
104 uint            uMessageDown = 0;
105 
106 Bool            bShowPrev = False;
107 Bool            bShowNext = False;
108 Bool		bShowCursor = False;
109 Bool		bLocked = True;
110 
111 //++++++++++++++++++++++++++++++++++++++++
112 /*
113 INT8		iKeyPressed = 0;
114 Bool		bRelease = True;
115 */
116 
117 
ResetInput(void)118 void ResetInput (void)
119 {
120     iCandPageCount = 0;
121     iCurrentCandPage = 0;
122     iCandWordCount = 0;
123     iLegendCandWordCount = 0;
124     iCurrentLegendCandPage = 0;
125     iLegendCandPageCount = 0;
126     iCursorPos = 0;
127 
128     strCodeInput[0] = '\0';
129     iCodeInputCount = 0;
130 
131     bIsDoInputOnly = False;
132 
133     bShowPrev = False;
134     bShowNext = False;
135 
136     bIsInLegend = False;
137     bInCap = False;
138 
139     if (IsIM (NAME_OF_PINYIN))
140 	bSingleHZMode = False;
141     else
142 	bShowCursor = False;
143 
144     if (im[iIMIndex].ResetIM)
145 	im[iIMIndex].ResetIM ();
146 }
147 
148 
149 //FILE           *fd;
ProcessKey(FcitxInstance & fInst,const KeyEvent & key)150 bool ProcessKey (FcitxInstance& fInst, const KeyEvent& key)
151 {
152 
153     int 	    iLen;
154 
155     int             count; //��ԭ�ȵ�fcitx�У�count��ʾkeyboard buffer���ж����ַ���
156     int             iKey=key.get_ascii_code();
157     char           *pstr;
158     KeyEvent key2=KeyEvent(key.code, key.mask&~SCIM_KEY_ReleaseMask, key.layout);
159     int             keyCount;
160     INPUT_RETURN_VALUE retVal;
161 
162 
163     if (key2.empty())
164 	return false;
165 
166     retVal = IRV_TO_PROCESS;
167 
168     if (key.is_key_release()) {
169 
170 	if ((!bIsDoInputOnly)) {
171 	    if (!bLocked && key2==KeyEvent("Shift+Alt+Shift_L")) {
172 
173 		if (fInst.imeState == IS_CHN) {
174 		    SwitchIM (-1);
175 		    fInst.refresh_status_property();
176 		}
177 	    }
178 	    else if (key2 == switchKey && keyReleased == KR_CTRL && !bDoubleSwitchKey) {
179 	        fInst.ChangeIMState();
180 		retVal = IRV_DO_NOTHING;
181 	    }
182 	    else if (key2 == i2ndSelectKey && keyReleased == KR_2ND_SELECTKEY) {
183 		if (!bIsInLegend) {
184 		    pstr = im[iIMIndex].GetCandWord (1);
185 		    if (pstr) {
186 			strcpy (strStringGet, pstr);
187 			if (bIsInLegend)
188 			    retVal = IRV_GET_LEGEND;
189 			else
190 			    retVal = IRV_GET_CANDWORDS;
191 		    }
192 		    else if (iCandWordCount)
193 			retVal = IRV_DISPLAY_CANDWORDS;
194 		    else
195 			retVal = IRV_TO_PROCESS;
196 		}
197 		else {
198 			strcpy(strStringGet, " ");
199 			uMessageDown = 0;
200 			retVal = IRV_GET_CANDWORDS;
201 		}
202 	    }
203 	    else if (key2 == i3rdSelectKey && keyReleased == KR_3RD_SELECTKEY) {
204 		if (!bIsInLegend) {
205 		    pstr = im[iIMIndex].GetCandWord (2);
206 		    if (pstr) {
207 			strcpy (strStringGet, pstr);
208 			if (bIsInLegend)
209 			    retVal = IRV_GET_LEGEND;
210 			else
211 			    retVal = IRV_GET_CANDWORDS;
212 		    }
213 		    else if (iCandWordCount)
214 			retVal = IRV_DISPLAY_CANDWORDS;
215 		}
216 		else {
217 			strcpy(strStringGet, "��");
218 			uMessageDown = 0;
219 			retVal = IRV_GET_CANDWORDS;
220 		}
221 	    }
222 	}
223     }
224 
225     if (retVal == IRV_TO_PROCESS) {
226 	if (key.is_key_press()) {
227 
228 	    if (!(key2 == switchKeyPress) )
229 		keyReleased = KR_OTHER;
230 
231 	    if (key2 == switchKeyPress) {
232 		keyReleased = KR_CTRL;
233 		//retVal = (bDoubleSwitchKey)? IRV_CLEAN:IRV_DO_NOTHING;
234 		retVal = IRV_DO_NOTHING;
235 	    }
236 	}
237 	if (retVal == IRV_TO_PROCESS && fInst.imeState == IS_CHN) {
238 	    if (key.is_key_press()) {
239 
240 		if (!key2.mask) {
241 		    if (key2 == i2ndSelectKeyPress)
242 			keyReleased = KR_2ND_SELECTKEY;
243 		    else if (key2 == i3rdSelectKeyPress)
244 			keyReleased = KR_3RD_SELECTKEY;
245 		}
246 
247 		if (key2 == KeyEvent() ) {
248 		    if (bLocked)
249 			retVal = IRV_TO_PROCESS;
250 		}
251 		else {
252 		    if (!bInCap && !bCorner) {
253 			retVal = im[iIMIndex].DoInput (key);
254 			if (!IsIM (NAME_OF_PINYIN) && !IsIM (NAME_OF_SHUANGPIN))
255 			    iCursorPos = iCodeInputCount;
256 		    }
257 
258 		    if (!bIsDoInputOnly && retVal == IRV_TO_PROCESS) {
259 			if (bCorner && (iKey >= 32 && iKey <= 126)&& !key2.mask) {
260 			    //���˱� �ո� ��ȫ�Dz��ԣ���ȷ����0xa1 0xa1
261 			    //��������ȴ˵ȫ�Ƿ���������0xa3��ʼ��
262 			    //����0xa3 0xa0���ܻ���ʾ���룬��˲���0xa1 0xa1�ķ�ʽ
263 			    if (iKey == ' ')
264 				sprintf (strStringGet, "%c%c", 0xa1, 0xa1);
265 			    else
266 				sprintf (strStringGet, "%c%c", 0xa3, 0xa0 + iKey - 32);
267 			    retVal = IRV_GET_CANDWORDS;
268 			}
269 			else if ((iKey >= 'A' && iKey <= 'Z') &&
270 				 bEngAfterCap &&
271 				 !(key2.mask&~SCIM_KEY_ShiftMask&~SCIM_KEY_CapsLockMask)) {
272 			    bInCap = True;
273 			    FCIM_DEUBG();
274 			    if (!bIsInLegend && iCandWordCount) {
275 				pstr = im[iIMIndex].GetCandWord (0);
276 				iCandWordCount = 0;
277 				if (pstr) {
278 				    strcpy (strStringGet, pstr);
279 				    SendHZtoClient (fInst, strStringGet);
280 				    iCodeInputCount = 0;
281 				}
282 			    }
283 			}
284 			else if (!key2.mask && iKey == ';' && bEngAfterSemicolon && !iCodeInputCount)
285 			    bInCap = True;
286 			else if (IsHotKey (key2, hkCorner))
287 			    retVal = ChangeCorner (fInst);
288 			else if (IsHotKey (key2, hkPunc))
289 			    retVal = ChangePunc (fInst);
290 			else if (IsHotKey (key2, hkGBK))
291 			    retVal = ChangeGBK (fInst);
292 			else if (IsHotKey (key2, hkPrevPage))
293 			    retVal = im[iIMIndex].GetCandWords (SM_PREV);
294 			else if (IsHotKey (key2, hkNextPage))
295 			    retVal = im[iIMIndex].GetCandWords (SM_NEXT);
296 			else if (IsHotKey (key2, hkLegend))
297 			    retVal = ChangeLegend (fInst);
298 
299 			if (retVal == IRV_TO_PROCESS) {
300 			    if (bInCap) {
301 				if (iKey == ' ' && !key2.mask && iCodeInputCount==0) {
302 
303 					strcpy (strStringGet, "��");
304 					retVal = IRV_ENG;
305 					bInCap = False;
306 
307 				}
308 				else if (isprint (iKey) && iKey < 128 && !(key2.mask&~SCIM_KEY_CapsLockMask&~SCIM_KEY_ShiftMask)) {
309 				    if (iCodeInputCount == MAX_USER_INPUT)
310 					retVal = IRV_DO_NOTHING;
311 				    else {
312 					if (!bEngAfterSemicolon || !(bEngAfterSemicolon && (iCodeInputCount == 0 && iKey == ';'))) {
313 					    strCodeInput[iCodeInputCount++] = iKey;
314 					    strCodeInput[iCodeInputCount] = '\0';
315 					    bShowCursor = True;
316 					    iCursorPos = iCodeInputCount;
317 					}
318 					retVal = IRV_DISPLAY_MESSAGE;
319 				    }
320 				}
321 				else if (key2 == KeyEvent(SCIM_KEY_BackSpace) && iCodeInputCount) {
322 				    iCodeInputCount--;
323 				    iCursorPos--;
324 				    strCodeInput[iCodeInputCount] = '\0';
325 				    retVal = IRV_DISPLAY_MESSAGE;
326 				    if (!iCodeInputCount)
327 					retVal = IRV_CLEAN;
328 				}
329 				uMessageUp = 1;
330 				uMessageDown = 1;
331 				if (bEngAfterSemicolon && !iCodeInputCount) {
332 				    iCursorPos=100;
333 				    strcpy (messageUp[0].strMsg, "����Ӣ������״̬");
334 				    strcpy (messageDown[0].strMsg, "�ո����룻Enter����;");
335 				}
336 				else {
337 				    strcpy (messageUp[0].strMsg, strCodeInput);
338 				    strcpy (messageDown[0].strMsg, "�� Enter����Ӣ��");
339 				}
340 				messageUp[0].type = MSG_INPUT;
341 				messageDown[0].type = MSG_TIPS;
342 			    }
343 			    else if ((bLastIsNumber && bEngPuncAfterNumber)
344 				     && (iKey == '.' || iKey == ',')
345 				     && !iCandWordCount) {
346 				retVal = IRV_TO_PROCESS;
347 				bLastIsNumber = False;
348 			    }
349 			    else {
350 				if (bChnPunc) {
351 				    int             iPunc;
352 
353 				    pstr = NULL;
354 				    iPunc = IsPunc (iKey);
355 				    if (iPunc != -1) {
356 					strStringGet[0] = '\0';
357 					if (!bIsInLegend)
358 					    pstr = im[iIMIndex].GetCandWord (0);
359 					if (pstr)
360 					    strcpy (strStringGet, pstr);
361 					strcat (strStringGet, chnPunc[iPunc].strChnPunc[chnPunc[iPunc].iWhich]);
362 
363 					uMessageUp = 1;
364 					messageUp[0].strMsg[0] = iKey;
365 					messageUp[0].strMsg[1] = '\0';
366 					messageUp[0].type = MSG_INPUT;
367 
368 					uMessageDown = 1;
369 					strcpy (messageDown[0].strMsg, chnPunc[iPunc].strChnPunc[chnPunc[iPunc].iWhich]);
370 					messageDown[0].type = MSG_OTHER;
371 
372 					chnPunc[iPunc].iWhich++;
373 					if (chnPunc[iPunc].iWhich >= chnPunc[iPunc].iCount)
374 					    chnPunc[iPunc].iWhich = 0;
375 
376 					retVal = IRV_PUNC;
377 				    }
378 				    else if (isprint (iKey) && iKey < 128 && !key2.mask) {
379 					if (iKey >= '0' && iKey <= '9')
380 					    bLastIsNumber = True;
381 					else {
382 					    bLastIsNumber = False;
383 					    if (iKey == ' ')
384 						retVal = IRV_DONOT_PROCESS_CLEAN;	//Ϊ����mozilla����
385 					    else {
386 						strStringGet[0] = '\0';
387 						if (!bIsInLegend)
388 						    pstr = im[iIMIndex].GetCandWord (0);
389 						if (pstr)
390 						    strcpy (strStringGet, pstr);
391 						iLen = strlen (strStringGet);
392 						uMessageDown = uMessageUp = 0;
393 						strStringGet[iLen] = iKey;
394 						strStringGet[iLen + 1] = '\0';
395 						retVal = IRV_ENG;
396 					    }
397 					}
398 				    }
399 				}
400 			    }
401 			}
402 		    }
403 
404 		    if (retVal == IRV_TO_PROCESS) {
405 			if (key2==KeyEvent(SCIM_KEY_Escape)) {
406 			    if (iCodeInputCount || bInCap || bIsInLegend)
407 				retVal = IRV_CLEAN;
408 			    else
409 				retVal = IRV_DONOT_PROCESS;
410 			}
411 			else if (key2==KeyEvent("Control+5")) {
412 			    SetIM ();
413 			    fInst.refresh_status_property();
414 			    LoadConfig (False);
415 
416 
417 			    retVal = IRV_DO_NOTHING;
418 			}
419 			else if (key2.code==SCIM_KEY_Return && (key2.mask&~(SCIM_KEY_ShiftMask|SCIM_KEY_CapsLockMask))==0) {
420 			    if (bInCap) {
421 				if (bEngAfterSemicolon && !iCodeInputCount)
422 				    strcpy (strStringGet, ";");
423 				else
424 				    strcpy (strStringGet, strCodeInput);
425 				retVal = IRV_ENG;
426 				uMessageUp = uMessageDown = 0;
427 				bInCap = False;
428 			    }
429 			    else if (!iCodeInputCount)
430 				retVal = IRV_DONOT_PROCESS;
431 			    else {
432 				switch (enterToDo) {
433 				case K_ENTER_NOTHING:
434 				    retVal = IRV_DO_NOTHING;
435 				    break;
436 				case K_ENTER_CLEAN:
437 				    retVal = IRV_CLEAN;
438 				    break;
439 				case K_ENTER_SEND:
440 				    uMessageDown = 1;
441 				    strcpy (messageDown[0].strMsg, strCodeInput);
442 				    strcpy (strStringGet, strCodeInput);
443 				    retVal = IRV_ENG;
444 				    break;
445 				}
446 			    }
447 			}
448 			else if (isprint (iKey) && iKey < 128 && !key2.mask)
449 			    retVal = IRV_DONOT_PROCESS_CLEAN;
450 			else
451 			    retVal = IRV_DONOT_PROCESS;
452 		    }
453 		}
454 	    }
455 	    else if (key.is_key_press())
456 		retVal = IRV_DONOT_PROCESS;
457 	}
458     }
459 
460     switch (retVal) {
461     case IRV_DO_NOTHING:
462 	return true;
463 
464     case IRV_TO_PROCESS:
465     case IRV_DONOT_PROCESS:
466 	return false;
467 
468     case IRV_DONOT_PROCESS_CLEAN:
469 	ResetInput();
470 	fInst.ResetInputWindow();
471 	return false;
472     case IRV_CLEAN:
473 	ResetInput ();
474 	fInst.ResetInputWindow ();
475 	return true;
476 
477     case IRV_DISPLAY_CANDWORDS:
478 	bShowNext = bShowPrev = False;
479 	if (bIsInLegend) {
480 	    if (iCurrentLegendCandPage > 0)
481 		bShowPrev = True;
482 	    if (iCurrentLegendCandPage < iLegendCandPageCount)
483 		bShowNext = True;
484 	}
485 	else {
486 	    if (iCurrentCandPage > 0)
487 		bShowPrev = True;
488 	    if (iCurrentCandPage < iCandPageCount)
489 		bShowNext = True;
490 	}
491 
492 	fInst.DisplayInputWindow ();
493 	return true;
494 
495     case IRV_DISPLAY_LAST:
496 	bShowNext = bShowPrev = False;
497 	uMessageUp = 1;
498 	messageUp[0].strMsg[0] = strCodeInput[0];
499 	messageUp[0].strMsg[1] = '\0';
500 	messageUp[0].type = MSG_INPUT;
501 	uMessageDown = 1;
502 	strcpy (messageDown[0].strMsg, strStringGet);
503 	messageDown[0].type = MSG_TIPS;
504 	fInst.DisplayInputWindow ();
505 	return true;
506 
507     case IRV_DISPLAY_MESSAGE:
508 	bShowNext = False;
509 	bShowPrev = False;
510 	fInst.DisplayInputWindow ();
511 	return true;
512 
513     case IRV_GET_LEGEND:
514 	SendHZtoClient (fInst, strStringGet);
515 	if (iLegendCandWordCount) {
516 	    bShowNext = bShowPrev = False;
517 	    if (iCurrentLegendCandPage > 0)
518 		bShowPrev = True;
519 	    if (iCurrentLegendCandPage < iLegendCandPageCount)
520 		bShowNext = True;
521 	    bLastIsNumber = False;
522 	    iCodeInputCount = 0;
523 	    fInst.DisplayInputWindow ();
524 	}
525 	else {
526 	    ResetInput ();
527 	    uMessageDown=uMessageUp=0;
528 
529 		fInst.DisplayInputWindow ();
530 	}
531 
532 	return true;
533     case IRV_GET_CANDWORDS:
534 	if (bPhraseTips && im[iIMIndex].PhraseTips)
535 	    DoPhraseTips ();
536     case IRV_ENG:
537     case IRV_PUNC:
538 	ResetInput ();
539 	if (!(uMessageDown && retVal == IRV_GET_CANDWORDS)
540 	    && bAutoHideInputWindow && (retVal == IRV_PUNC || (!bPhraseTips || (bPhraseTips && !lastIsSingleHZ))))
541 	    fInst.ResetInputWindow();
542 	    else
543 	    fInst.DisplayInputWindow ();
544 
545 
546     case IRV_GET_CANDWORDS_NEXT:
547 	if (retVal == IRV_GET_CANDWORDS_NEXT || lastIsSingleHZ == -1)
548 	    fInst.DisplayInputWindow ();
549 	SendHZtoClient (fInst, strStringGet);
550 	bLastIsNumber = False;
551 	lastIsSingleHZ = 0;
552 
553 	return true;
554 
555     default:
556 	;
557     }
558     return true;
559 
560 }
561 
IsHotKey(const KeyEvent & iKey,KeyEvent * hotkey)562 Bool IsHotKey (const KeyEvent& iKey, KeyEvent * hotkey)
563 {
564     if (iKey.empty()) return False;
565     if (iKey == hotkey[0] || iKey == hotkey[1])
566         return True;
567     return False;
568 
569 }
570 
ChangeCorner(FcitxInstance & fInst)571 INPUT_RETURN_VALUE ChangeCorner (FcitxInstance& fInst)
572 {
573     ResetInput ();
574     fInst.ResetInputWindow ();
575     bCorner = !bCorner;
576     fInst.refresh_letter_property();
577 
578     SaveProfile ();
579 
580     return IRV_DO_NOTHING;
581 }
582 
ChangePunc(FcitxInstance & fInst)583 INPUT_RETURN_VALUE ChangePunc (FcitxInstance& fInst)
584 {
585     bChnPunc = !bChnPunc;
586     fInst.refresh_punct_property();
587     SaveProfile ();
588 
589     return IRV_DO_NOTHING;
590 }
591 
ChangeGBK(FcitxInstance & fInst)592 INPUT_RETURN_VALUE ChangeGBK (FcitxInstance& fInst)
593 {
594     bUseGBK = !bUseGBK;
595     fInst.refresh_gbk_property();
596     ResetInput ();
597     fInst.ResetInputWindow ();
598 
599 
600     SaveProfile ();
601 
602     return IRV_CLEAN;
603 }
604 
ChangeLegend(FcitxInstance & fInst)605 INPUT_RETURN_VALUE ChangeLegend (FcitxInstance& fInst)
606 {
607     bUseLegend = !bUseLegend;
608     ResetInput ();
609     fInst.ResetInputWindow ();
610     fInst.refresh_legend_property();
611 
612     //DisplayMainWindow ();
613     //XUnmapWindow (dpy, inputWindow);
614 
615     SaveProfile ();
616 
617     return IRV_CLEAN;
618 }
619 
SwitchIM(INT8 index)620 void SwitchIM (INT8 index)
621 {
622     INT8            iLastIM;
623 
624     iLastIM = (iIMIndex >= iIMCount) ? (iIMCount - 1) : iIMIndex;
625 
626     if (index == (INT8) - 1) {
627 	if (iIMIndex == (iIMCount - 1))
628 	    iIMIndex = 0;
629 	else
630 	    iIMIndex++;
631     }
632     else {
633 	if (index >= iIMCount)
634 	    iIMIndex = iIMCount - 1;
635     }
636 
637 
638     if (iIMCount == 1)
639 	return;
640 
641     if (im[iLastIM].Destroy != NULL)
642 	im[iLastIM].Destroy ();
643 
644     ResetInput ();
645 
646 
647     SaveProfile ();
648 
649     if (im[iIMIndex].Init)
650 	im[iIMIndex].Init ();
651 }
652 
DoPhraseTips(void)653 void DoPhraseTips (void)
654 {
655     if (!bPhraseTips)
656 	return;
657 
658     if (im[iIMIndex].PhraseTips ())
659 	lastIsSingleHZ = (unsigned char)-1;
660     else
661 	lastIsSingleHZ = 0;
662 }
663 
664 /*
665 #define _DEBUG
666 */
RegisterNewIM(char * strName,void (* ResetIM)(void),INPUT_RETURN_VALUE (* DoInput)(const KeyEvent &),INPUT_RETURN_VALUE (* GetCandWords)(SEARCH_MODE),char * (* GetCandWord)(int),char * (* GetLegendCandWord)(int),Bool (* PhraseTips)(void),void (* Init)(void),void (* Destroy)(void))667 void RegisterNewIM (char *strName,
668 		    void (*ResetIM) (void),
669 		    INPUT_RETURN_VALUE (*DoInput) (const KeyEvent&),
670 		    INPUT_RETURN_VALUE (*GetCandWords) (SEARCH_MODE),
671 		    char *(*GetCandWord) (int),
672 		    char *(*GetLegendCandWord) (int),
673 		    Bool (*PhraseTips) (void),
674 		    void (*Init) (void),
675 		    void (*Destroy) (void))
676 {
677 #ifdef _DEBUG
678     printf ("REGISTER %s\n", strName);
679 #endif
680     strcpy (im[iIMCount].strName, strName);
681     im[iIMCount].ResetIM = ResetIM;
682     im[iIMCount].DoInput = DoInput;
683     im[iIMCount].GetCandWords = GetCandWords;
684     im[iIMCount].GetCandWord = GetCandWord;
685     im[iIMCount].GetLegendCandWord = GetLegendCandWord;
686     im[iIMCount].PhraseTips = PhraseTips;
687     im[iIMCount].Init = Init;
688     im[iIMCount].Destroy = Destroy;
689 
690     iIMCount++;
691 }
692 
IsIM(char * strName)693 Bool IsIM (char *strName)
694 {
695     if (strstr (im[iIMIndex].strName, strName))
696 	return True;
697 
698     return False;
699 }
700 
SaveIM(void)701 void SaveIM (void)
702 {
703     if (iTableChanged || iTableOrderChanged)
704 	SaveTableDict ();
705     if (iNewPYPhraseCount)
706 	SavePYUserPhrase ();
707     if (iOrderCount)
708 	SavePYIndex ();
709     if (iNewFreqCount)
710 	SavePYFreq ();
711 }
712 
SetIM(void)713 void SetIM (void)
714 {
715     INT8            i;
716 
717     if (im)
718 	free (im);
719 
720     if (bUseTable)
721 	LoadTableInfo ();
722 
723     iIMCount = iTableCount;
724     if (bUsePinyin)
725 	iIMCount++;
726     if (bUseSP)
727 	iIMCount++;
728     if (bUseQW)
729 	iIMCount++;
730 
731     im = (IM *) malloc (sizeof (IM) * iIMCount);
732     iIMCount = 0;
733 
734     /* �������뷨 */
735     if (bUsePinyin || (!bUseSP && (!bUseTable || !iTableCount)))	//����Ӧ����һ�����뷨
736 	RegisterNewIM (NAME_OF_PINYIN, ResetPYStatus, DoPYInput, PYGetCandWords, PYGetCandWord, PYGetLegendCandWord, NULL, PYInit, NULL);
737     if (bUseSP)
738 	RegisterNewIM (NAME_OF_SHUANGPIN, ResetPYStatus, DoPYInput, PYGetCandWords, PYGetCandWord, PYGetLegendCandWord, NULL, SPInit, NULL);
739     if (bUseQW)
740 	RegisterNewIM (NAME_OF_QUWEI, NULL, DoQWInput, QWGetCandWords, QWGetCandWord, NULL, NULL, NULL, NULL);
741     if (bUseTable) {
742 	for (i = 0; i < iTableCount; i++) {
743 	    RegisterNewIM (table[i].strName, TableResetStatus, DoTableInput, TableGetCandWords, TableGetCandWord, TableGetLegendCandWord, TablePhraseTips, TableInit, FreeTableIM);
744 	    table[i].iIMIndex = iIMCount - 1;
745 	}
746     }
747 
748     SwitchIM (iIMIndex);
749 }
750 
751