HRESULT CTextService::_HandleKey(TfEditCookie ec, ITfContext *pContext, WPARAM wParam) { /* * FIXME: the following keys are not handled: * shift left VK_LSHIFT * shift right VK_RSHIFT * caps lock VK_CAPITAL * page up VK_PRIOR * page down VK_NEXT * ctrl num * shift space * numlock num VK_NUMLOCK */ if (('A' <= wParam && wParam <= 'Z')) { chewing_handle_Default(mChewingContext, wParam - 'A' + 'a'); } else if ('0' <= wParam && wParam <= '9') { chewing_handle_Default(mChewingContext, wParam); } else { switch(wParam) { case VK_OEM_COMMA: chewing_handle_Default(mChewingContext, ','); break; case VK_OEM_MINUS: chewing_handle_Default(mChewingContext, '-'); break; case VK_OEM_PERIOD: chewing_handle_Default(mChewingContext, '.'); break; case VK_OEM_1: chewing_handle_Default(mChewingContext, ';'); break; case VK_OEM_2: chewing_handle_Default(mChewingContext, '/'); break; case VK_OEM_3: chewing_handle_Default(mChewingContext, '`'); break; case VK_SPACE: chewing_handle_Space(mChewingContext); break; case VK_ESCAPE: chewing_handle_Esc(mChewingContext); break; case VK_RETURN: chewing_handle_Enter(mChewingContext); break; case VK_DELETE: chewing_handle_Del(mChewingContext); break; case VK_BACK: chewing_handle_Backspace(mChewingContext); break; case VK_UP: chewing_handle_Up(mChewingContext); break; case VK_DOWN: chewing_handle_Down(mChewingContext); case VK_LEFT: chewing_handle_Left(mChewingContext); break; case VK_RIGHT: chewing_handle_Right(mChewingContext); break; case VK_HOME: chewing_handle_Home(mChewingContext); break; case VK_END: chewing_handle_End(mChewingContext); break; default: return S_OK; } } // Remove old candidate list. We will create a new one if necessary. _pCandidateList->_EndCandidateList(); ChewingCandidates candidate(mChewingContext); if (!candidate.IsEmpty()) { _SetCompositionDisplayAttributes(ec, pContext, _gaDisplayAttributeConverted); // // The document manager object is not cached. Get it from pContext. // ITfDocumentMgr *pDocumentMgr; if (pContext->GetDocumentMgr(&pDocumentMgr) == S_OK) { // // get the composition range. // ITfRange *pRange; if (_pComposition->GetRange(&pRange) == S_OK) { _pCandidateList->_StartCandidateList(_tfClientId, pDocumentMgr, pContext, ec, pRange, candidate); pRange->Release(); } pDocumentMgr->Release(); } return S_OK; } ChewingString commit(mChewingContext, CHEWING_STRING_COMMIT); if (!commit.IsEmpty()) { // FIXME: Need a better way to submit a string if (!_IsComposing()) _StartComposition(pContext); ULONG cFetched; BOOL fCovered; TF_SELECTION tfSelection; // FIXME: Why we need this here? // first, test where a keystroke would go in the document if an insert is done if (pContext->GetSelection(ec, TF_DEFAULT_SELECTION, 1, &tfSelection, &cFetched) != S_OK || cFetched != 1) return S_FALSE; // FIXME: Why we need this here? // is the insertion point covered by a composition? ITfRange *pRangeComposition; if (_pComposition->GetRange(&pRangeComposition) == S_OK) { fCovered = IsRangeCovered(ec, tfSelection.range, pRangeComposition); pRangeComposition->Release(); if (!fCovered) { goto End3; } } if (tfSelection.range->SetText(ec, 0, commit.GetString(), commit.GetLength()) != S_OK) goto End3; _TerminateComposition(ec, pContext); End3: // FIXME: RAII? tfSelection.range->Release(); } /* * Composition is mapped to preedit buffer + zuin buffer */ ChewingString preedit_zuin(mChewingContext, CHEWING_STRING_PREEDIT_ZUIN); if (preedit_zuin.IsEmpty()) { // Remove composition if (_IsComposing()) { ULONG cFetched; BOOL fCovered; TF_SELECTION tfSelection; // FIXME: Why we need this here? // first, test where a keystroke would go in the document if an insert is done if (pContext->GetSelection(ec, TF_DEFAULT_SELECTION, 1, &tfSelection, &cFetched) != S_OK || cFetched != 1) return S_FALSE; // FIXME: Why we need this here? // is the insertion point covered by a composition? ITfRange *pRangeComposition; if (_pComposition->GetRange(&pRangeComposition) == S_OK) { fCovered = IsRangeCovered(ec, tfSelection.range, pRangeComposition); pRangeComposition->Release(); if (!fCovered) { goto End; } } // Empties the composition tfSelection.range->SetText(ec, 0, L"", 0); _TerminateComposition(ec, pContext); End: // FIXME: RAII? tfSelection.range->Release(); } } else { if (!_IsComposing()) _StartComposition(pContext); ULONG cFetched; BOOL fCovered; TF_SELECTION tfSelection; // FIXME: Why we need this here? // first, test where a keystroke would go in the document if an insert is done if (pContext->GetSelection(ec, TF_DEFAULT_SELECTION, 1, &tfSelection, &cFetched) != S_OK || cFetched != 1) return S_FALSE; // FIXME: Why we need this here? // is the insertion point covered by a composition? ITfRange *pRangeComposition; if (_pComposition->GetRange(&pRangeComposition) == S_OK) { fCovered = IsRangeCovered(ec, tfSelection.range, pRangeComposition); pRangeComposition->Release(); if (!fCovered) { goto End2; } } if (tfSelection.range->SetText(ec, 0, preedit_zuin.GetString(), preedit_zuin.GetLength()) != S_OK) goto End2; _SetCompositionDisplayAttributes(ec, pContext, _gaDisplayAttributeInput); End2: // FIXME: RAII? tfSelection.range->Release(); } return S_OK; }
int main( int argc, char *argv[] ) #endif { ChewingContext *ctx; char *prefix = CHEWING_DATA_PREFIX; int i; int ctrl_shifted; /* Initialize libchewing */ /* for the sake of testing, we should not change existing hash data */ chewing_Init( prefix, TEST_HASH_DIR ); /* Request handle to ChewingContext */ ctx = chewing_new(); /* Set keyboard type */ chewing_set_KBType( ctx, chewing_KBStr2Num( "KB_DEFAULT" ) ); chewing_set_candPerPage( ctx, 9 ); chewing_set_maxChiSymbolLen( ctx, 16 ); chewing_set_addPhraseDirection( ctx, 1 ); chewing_set_selKey( ctx, selKey_define, 10 ); chewing_set_spaceAsSelection( ctx, 1 ); while ( 1 ) { i = get_keystroke(); switch ( i ) { case KEY_LEFT: chewing_handle_Left( ctx ); break; case KEY_SLEFT: chewing_handle_ShiftLeft( ctx ); break; case KEY_RIGHT: chewing_handle_Right( ctx ); break; case KEY_SRIGHT: chewing_handle_ShiftRight( ctx ); break; case KEY_UP: chewing_handle_Up( ctx ); break; case KEY_DOWN: chewing_handle_Down( ctx ); break; case KEY_SPACE: chewing_handle_Space( ctx ); break; case KEY_ENTER: chewing_handle_Enter( ctx ); break; case KEY_BACKSPACE: chewing_handle_Backspace( ctx ); break; case KEY_ESC: chewing_handle_Esc( ctx ); break; case KEY_DELETE: chewing_handle_Del( ctx ); break; case KEY_HOME: chewing_handle_Home( ctx ); break; case KEY_END: chewing_handle_End( ctx ); break; case KEY_TAB: chewing_handle_Tab( ctx ); break; case KEY_CAPSLOCK: chewing_handle_Capslock( ctx ); break; case END: goto end; default: ctrl_shifted = ( i - KEY_CTRL_BASE ); if ( ( ctrl_shifted >= '0' ) && ( ctrl_shifted <= '9' ) ) { chewing_handle_CtrlNum( ctx, ctrl_shifted ); } else { chewing_handle_Default( ctx, (char) i ); } break; } commit_string( ctx ); #ifdef USED_IN_SIMULATION if ( i == KEY_ENTER ) compare_per_run(); #endif } end: /* Free Chewing IM handle */ chewing_delete( ctx ); /* Termate Chewing services */ chewing_Terminate(); #ifndef USED_IN_SIMULATION printf( "\n" ); #endif return 0; }
gboolean ibus_chewing_engine_process_key_event(IBusEngine *engine, guint keysym, guint keycode, guint modifiers){ gboolean result=TRUE; if (modifiers & IBUS_RELEASE_MASK){ /* Skip release event */ return TRUE; } IBusChewingEngine *self=IBUS_CHEWING_ENGINE(engine); guint kSym=ibus_chewing_engine_keycode_to_keysym(self,keysym, keycode, modifiers); G_DEBUG_MSG(2,"***[I2] process_key_event(-, %x(%s), %x, %x) orig keysym=%x... proceed.",kSym, keyName_get(kSym), keycode, modifiers,keysym); guint state= modifiers & (IBUS_SHIFT_MASK | IBUS_CONTROL_MASK | IBUS_MOD1_MASK); self->_priv->key_last=kSym; if (state==0){ guint kSym_tmp=keysym_KP_to_normal(kSym); if (kSym_tmp){ G_DEBUG_MSG(3,"***[I3] process_key_event(): %x is from keypad.", kSym_tmp); /* Is keypad key */ if ((self->chewingFlags & CHEWING_FLAG_NUMPAD_ALWAYS_NUMBER) && chewing_get_ChiEngMode(self->context)){ chewing_set_ChiEngMode(self->context, 0); self_handle_Default(self,kSym_tmp,FALSE); chewing_set_ChiEngMode(self->context,CHINESE_MODE); }else{ /* Convert kp numbers to normal */ self_handle_Default(self,kSym_tmp,FALSE); } }else{ switch (kSym){ case IBUS_Return: case IBUS_KP_Enter: chewing_handle_Enter(self->context); break; case IBUS_Escape: if (self->inputMode==CHEWING_INPUT_MODE_BYPASS) return FALSE; chewing_handle_Esc(self->context); break; case IBUS_BackSpace: if (self->inputMode==CHEWING_INPUT_MODE_BYPASS) return FALSE; chewing_handle_Backspace(self->context); break; case IBUS_Delete: case IBUS_KP_Delete: if (self->inputMode==CHEWING_INPUT_MODE_BYPASS) return FALSE; chewing_handle_Del(self->context); break; case IBUS_space: case IBUS_KP_Space: if (self->chewingFlags & CHEWING_FLAG_PLAIN_ZHUYIN) { if (chewing_cand_TotalChoice(self->context) == 0) { chewing_handle_Space(self->context); } } else { /** * Fix for space in Temporary English mode. */ chewing_handle_Space(self->context); } if (self->inputMode==CHEWING_INPUT_MODE_SELECTION_DONE || self->inputMode==CHEWING_INPUT_MODE_BYPASS ) ibus_chewing_engine_set_status_flag(self,ENGINE_STATUS_NEED_COMMIT); break; case IBUS_Page_Up: case IBUS_KP_Page_Up: if (self->inputMode==CHEWING_INPUT_MODE_BYPASS) return FALSE; IBUS_ENGINE_GET_CLASS(engine)->page_up(engine); break; case IBUS_Page_Down: case IBUS_KP_Page_Down: if (self->inputMode==CHEWING_INPUT_MODE_BYPASS) return FALSE; IBUS_ENGINE_GET_CLASS(engine)->page_down(engine); break; case IBUS_Up: case IBUS_KP_Up: if (self->inputMode==CHEWING_INPUT_MODE_BYPASS) return FALSE; IBUS_ENGINE_GET_CLASS(engine)->cursor_up(engine); break; case IBUS_Down: case IBUS_KP_Down: if (self->inputMode==CHEWING_INPUT_MODE_BYPASS) return FALSE; IBUS_ENGINE_GET_CLASS(engine)->cursor_down(engine); break; case IBUS_Left: case IBUS_KP_Left: if (self->inputMode==CHEWING_INPUT_MODE_BYPASS) return FALSE; chewing_handle_Left(self->context); break; case IBUS_Right: case IBUS_KP_Right: if (self->inputMode==CHEWING_INPUT_MODE_BYPASS) return FALSE; chewing_handle_Right(self->context); break; case IBUS_Home: case IBUS_KP_Home: if (self->inputMode==CHEWING_INPUT_MODE_BYPASS) return FALSE; chewing_handle_Home(self->context); break; case IBUS_End: case IBUS_KP_End: if (self->inputMode==CHEWING_INPUT_MODE_BYPASS) return FALSE; chewing_handle_End(self->context); break; case IBUS_Tab: if (self->inputMode==CHEWING_INPUT_MODE_BYPASS) return FALSE; chewing_handle_Tab(self->context); break; case IBUS_Caps_Lock: /* When Chi->Eng with incomplete character */ if (chewing_get_ChiEngMode(self->context) && !chewing_zuin_Check(self->context)){ /* chewing_zuin_Check==0 means incomplete character */ /* Send a space to finish the character */ chewing_handle_Space(self->context); } chewing_handle_Capslock(self->context); self_refresh_property(self,"chewing_chieng_prop"); break; case IBUS_Shift_L: case IBUS_Shift_R: /* Some QT application will sneak these through */ return FALSE; case IBUS_Alt_L: case IBUS_Alt_R: /* Some QT application will sneak these through */ return FALSE; case IBUS_Control_L: case IBUS_Control_R: /* Some QT application will sneak these through */ return FALSE; default: self_handle_Default(self,kSym,FALSE); break; } } }else if (state==IBUS_SHIFT_MASK){ switch(kSym){ case IBUS_Left: if (self->inputMode==CHEWING_INPUT_MODE_BYPASS) return FALSE; chewing_handle_ShiftLeft(self->context); break; case IBUS_Right: if (self->inputMode==CHEWING_INPUT_MODE_BYPASS) return FALSE; chewing_handle_ShiftRight(self->context); break; case IBUS_Up: case IBUS_KP_Up: case IBUS_Down: case IBUS_KP_Down: case IBUS_Page_Up: case IBUS_KP_Page_Up: case IBUS_Page_Down: case IBUS_KP_Page_Down: case IBUS_Home: case IBUS_End: if (self->_priv->statusFlags & ENGINE_STATUS_NEED_COMMIT) self_force_commit(self); return FALSE; case IBUS_space: case IBUS_KP_Space: chewing_handle_ShiftSpace(self->context); chewing_set_ShapeMode(self->context, !chewing_get_ShapeMode(self->context)); self_refresh_property(self,"chewing_alnumSize_prop"); break; default: if (kSym>127 || kSym<0){ /* Special keys, must let it through */ return FALSE; } self_handle_Default(self,kSym,TRUE); break; } }else if (state==IBUS_CONTROL_MASK){ if (kSym>=IBUS_0 && kSym<=IBUS_9){ chewing_handle_CtrlNum(self->context,kSym); // }else if (kSym==IBUS_v || kSym==IBUS_V){ // chewing_handle_Right(self->context); }else{ result=FALSE; } }else{ result=FALSE; } if (!result){ return FALSE; } return self_update(self); }
int main( int argc, char *argv[] ) { ChewingContext *ctx; FILE *fout; FILE *fout2; char *prefix = CHEWING_DATA_PREFIX; char *out_file = "tmp.txt"; char *out_file2 = "tmp_out.txt"; int ch; int width, height; int add_phrase_length; /*if ( argc < 2 ) { fprintf( stderr, "usage: genkeystroke filename\n" ); exit( 1 ); } else { fout = fopen( argv[ 1 ], "w" );*/ fout = fopen( out_file, "w" ); if ( ! fout ) { fprintf( stderr, "Error: failed to open %s\n", out_file ); exit( 1 ); } fout2 = fopen( out_file2, "w" ); if ( ! fout2 ) { fprintf( stderr, "Error: failed to open %s\n", out_file2 ); exit( 1 ); } /*}*/ /* Initialize curses library */ setlocale(LC_CTYPE, ""); initscr(); if ( has_colors() == TRUE ) { start_color(); init_pair( 1, COLOR_WHITE, COLOR_BLUE ); init_pair( 2, COLOR_RED, COLOR_YELLOW ); init_pair( 3, COLOR_WHITE, COLOR_RED ); hasColor = 1; } cbreak(); noecho(); keypad( stdscr, 1 ); getmaxyx( stdscr, height, width ); start_color(); clear(); refresh(); /* Initialize libchewing */ /* for the sake of testing, we should not change existing hash data */ chewing_Init( prefix, TEST_HASH_DIR ); /* Request handle to ChewingContext */ ctx = chewing_new(); /* Set keyboard type */ chewing_set_KBType( ctx, chewing_KBStr2Num( "KB_DEFAULT" ) ); /* Fill configuration values */ chewing_set_candPerPage( ctx, 9 ); chewing_set_maxChiSymbolLen( ctx, 16 ); chewing_set_addPhraseDirection( ctx, 1 ); chewing_set_selKey( ctx, selKey_define, 10 ); chewing_set_spaceAsSelection( ctx, 1 ); chewing_set_autoShiftCur( ctx, 1 ); chewing_set_phraseChoiceRearward( ctx, 1 ); clear(); mvaddstr( 0, 0, "Any key to start testing..." ); while ( TRUE ) { ch = getch(); switch ( ch ) { case KEY_LEFT: chewing_handle_Left( ctx ); fprintf( fout, "<L>" ); break; case KEY_SLEFT: chewing_handle_ShiftLeft( ctx ); fprintf( fout, "<SL>" ); break; case KEY_RIGHT: chewing_handle_Right( ctx ); fprintf( fout, "<R>" ); break; case KEY_SRIGHT: chewing_handle_ShiftRight( ctx ); fprintf( fout, "<SR>" ); break; case KEY_UP: chewing_handle_Up( ctx ); fprintf( fout, "<U>" ); break; case KEY_DOWN: chewing_handle_Down( ctx ); fprintf( fout, "<D>" ); break; case KEY_SPACE: chewing_handle_Space( ctx ); fprintf( fout, " " ); break; case KEY_ENTER: chewing_handle_Enter( ctx ); fprintf( fout, "<E>" ); break; case KEY_BACKSPACE: chewing_handle_Backspace( ctx ); fprintf( fout, "<B>" ); break; case KEY_ESC: chewing_handle_Esc( ctx ); fprintf( fout, "<EE>" ); break; case KEY_DC: chewing_handle_Del( ctx ); fprintf( fout, "<DC>" ); break; case KEY_HOME: chewing_handle_Home( ctx ); fprintf( fout, "<H>" ); break; case KEY_END: chewing_handle_End( ctx ); fprintf( fout, "<EN>" ); break; case KEY_TAB: chewing_handle_Tab( ctx ); fprintf( fout, "<T>" ); break; case CTRL_0: case CTRL_1: case CTRL_2: case CTRL_3: case CTRL_4: case CTRL_5: case CTRL_6: case CTRL_7: case CTRL_8: case CTRL_9: add_phrase_length = ( ch - CTRL_0 + '0' ); chewing_handle_CtrlNum( ctx, add_phrase_length ); fprintf( fout, "<C%c>", add_phrase_length ); break; case KEY_CTRL_('B'): /* emulate CapsLock */ chewing_handle_Capslock( ctx ); fprintf( fout, "<CB>"); break; case KEY_CTRL_('D'): case EOF: goto end; case KEY_CTRL_('H'): /* emulate Shift */ if ( chewing_get_ShapeMode( ctx ) == FULLSHAPE_MODE ) chewing_set_ShapeMode( ctx, HALFSHAPE_MODE ); else chewing_set_ShapeMode( ctx, FULLSHAPE_MODE ); break; default: chewing_handle_Default( ctx, (char) ch ); fprintf( fout, "%c", (char) ch ); break; } drawline( 0, 0 ); drawline( 2, 0 ); show_interval_buffer( 3, 0, ctx ); drawline( 4, 0 ); show_choose_buffer( 5, 0, ctx ); drawline( 6, 0 ); show_zuin_buffer( 7, 0, ctx ); show_full_shape( 7, 5, ctx ); drawline( 8, 0 ); mvaddstr( 9, 0, "Ctrl + d : leave" ); mvaddstr( 9, 20, "Ctrl + b : toggle Eng/Chi mode" ); mvaddstr( 10, 0, "F1, F2, F3, ..., F9 : Add user defined phrase"); mvaddstr( 11, 0, "Crtl + h : toggle Full/Half shape mode" ); show_commit_string( ctx ); store_commit_string( ctx, fout2 ); show_userphrase( 7, 12, ctx ); show_edit_buffer( 1, 0, ctx ); } end: endwin(); /* Release Chewing context */ chewing_delete( ctx ); /* Termate Chewing services */ chewing_Terminate(); fprintf( fout, "\n" ); fprintf( fout2, "\n" ); fclose( fout ); fclose( fout2 ); return 0; }
int Chewing::End() { return chewing_handle_End(ctx);}
void type_single_keystroke( ChewingContext *ctx, int ch ) { switch ( ch ) { case KEY_LEFT: chewing_handle_Left( ctx ); break; case KEY_SLEFT: chewing_handle_ShiftLeft( ctx ); break; case KEY_RIGHT: chewing_handle_Right( ctx ); break; case KEY_SRIGHT: chewing_handle_ShiftRight( ctx ); break; case KEY_UP: chewing_handle_Up( ctx ); break; case KEY_DOWN: chewing_handle_Down( ctx ); break; case KEY_SPACE: chewing_handle_Space( ctx ); break; case KEY_ENTER: chewing_handle_Enter( ctx ); break; case KEY_BACKSPACE: chewing_handle_Backspace( ctx ); break; case KEY_ESC: chewing_handle_Esc( ctx ); break; case KEY_DELETE: chewing_handle_Del( ctx ); break; case KEY_HOME: chewing_handle_Home( ctx ); break; case KEY_END: chewing_handle_End( ctx ); break; case KEY_TAB: chewing_handle_Tab( ctx ); break; case KEY_CAPSLOCK: chewing_handle_Capslock( ctx ); break; case KEY_NPAGE: chewing_handle_PageDown( ctx ); break; case KEY_PPAGE: chewing_handle_PageUp( ctx ); break; case KEY_SSPACE: chewing_handle_ShiftSpace( ctx ); break; case KEY_DBLTAB: chewing_handle_DblTab( ctx ); break; default: if ( KEY_CTRL_BASE <= ch && ch < KEY_NUMPAD_BASE) chewing_handle_CtrlNum( ctx, ch - KEY_CTRL_BASE ); else if ( KEY_NUMPAD_BASE <= ch ) chewing_handle_Numlock( ctx, ch - KEY_NUMPAD_BASE ); else chewing_handle_Default( ctx, (char) ch ); break; } }