1 /* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 3 * 4 * Copyright (c) 2007 Sun Microsystems, Inc. All Rights Reserved. 5 * 6 * The contents of this file are subject to the terms of either the GNU Lesser 7 * General Public License Version 2.1 only ("LGPL") or the Common Development and 8 * Distribution License ("CDDL")(collectively, the "License"). You may not use this 9 * file except in compliance with the License. You can obtain a copy of the CDDL at 10 * http://www.opensource.org/licenses/cddl1.php and a copy of the LGPLv2.1 at 11 * http://www.opensource.org/licenses/lgpl-license.php. See the License for the 12 * specific language governing permissions and limitations under the License. When 13 * distributing the software, include this License Header Notice in each file and 14 * include the full text of the License in the License file as well as the 15 * following notice: 16 * 17 * NOTICE PURSUANT TO SECTION 9 OF THE COMMON DEVELOPMENT AND DISTRIBUTION LICENSE 18 * (CDDL) 19 * For Covered Software in this distribution, this License shall be governed by the 20 * laws of the State of California (excluding conflict-of-law provisions). 21 * Any litigation relating to this License shall be subject to the jurisdiction of 22 * the Federal Courts of the Northern District of California and the state courts 23 * of the State of California, with venue lying in Santa Clara County, California. 24 * 25 * Contributor(s): 26 * 27 * If you wish your version of this file to be governed by only the CDDL or only 28 * the LGPL Version 2.1, indicate your decision by adding "[Contributor]" elects to 29 * include this software in this distribution under the [CDDL or LGPL Version 2.1] 30 * license." If you don't indicate a single choice of license, a recipient has the 31 * option to distribute your version of this file under either the CDDL or the LGPL 32 * Version 2.1, or to extend the choice of license to its licensees as provided 33 * above. However, if you add LGPL Version 2.1 code and therefore, elected the LGPL 34 * Version 2 license, then the option applies only if the new code is made subject 35 * to such option by the copyright holder. 36 */ 37 38 #ifdef HAVE_CONFIG_H 39 #include <config.h> 40 #endif 41 42 #include "imi_clewin.h" 43 #include "imi_uiobjects.h" 44 45 ImmServices CCLEWinHandler::sm_imm_srvs = NULL; 46 47 CCLEWinHandler::CCLEWinHandler() : CIMIWinHandler() 48 { 49 memset(&mp_mainwin, 0, sizeof(mp_mainwin)); 50 m_iconv = iconv_open("UTF-8", TWCHAR_ICONV_NAME); 51 } 52 53 CCLEWinHandler::~CCLEWinHandler() 54 { 55 iconv_close(m_iconv); 56 } 57 58 void 59 CCLEWinHandler::throwBackKey(unsigned keycode, unsigned keyvalue, unsigned modifier) 60 { 61 // do nothing, iiim/cle would throw it back 62 } 63 64 void 65 CCLEWinHandler::commit(const TWCHAR* wstr) 66 { 67 ImeInputContext ic = (ImeInputContext)mp_mainwin; 68 69 #ifdef DEBUG 70 printf("NEWCLEWin Commit["); 71 #endif 72 73 TIConvSrcPtr src = (TIConvSrcPtr)(wstr); 74 size_t srclen = (WCSLEN(wstr)+1)*sizeof(TWCHAR); 75 char * dst = m_buf; 76 size_t dstlen = sizeof(m_buf); 77 iconv(m_iconv, &src, &srclen, &dst, &dstlen); 78 dstlen = sizeof(m_buf) - dstlen; 79 80 #ifdef DEBUG 81 printf("%s", m_buf); 82 #endif 83 84 sm_imm_srvs->ImmCommit(ic, (unsigned char*)m_buf); 85 86 #ifdef DEBUG 87 printf("]done\n"); 88 fflush(stdout); 89 #endif 90 } 91 92 void 93 CCLEWinHandler::updatePreedit(const IPreeditString* ppd) 94 { 95 ImeInputContext ic = (ImeInputContext)mp_mainwin; 96 ImePreeditRec prec; 97 ImeTextRec& trec = prec.preedit; 98 99 prec.caret = ppd->caret(); 100 prec.cl_start = ppd->candi_start(); 101 trec.count_feedbacks = 0; 102 trec.feedbacks = NULL; 103 trec.text = (unsigned char*)m_buf; 104 105 #ifdef DEBUG 106 printf("CLEWin Preedit change to ["); 107 #endif 108 109 TIConvSrcPtr src = (TIConvSrcPtr)(ppd->string()); 110 size_t srclen = (ppd->size()+1)*sizeof(TWCHAR); 111 char * dst = (char *)m_buf; 112 size_t dstlen = sizeof(m_buf); 113 iconv(m_iconv, &src, &srclen, &dst, &dstlen); 114 115 #ifdef DEBUG 116 printf("%s", m_buf); 117 #endif 118 119 std::vector<ImeFeedbackRec> decos; 120 for (int i=0, sz = ppd->charTypeSize(); i < sz; ) { 121 int ct = ppd->charTypeAt(i); 122 123 if (ct & IPreeditString::ILLEGAL) { 124 ImeFeedbackRec fb = {ImeFeedbackForegroundRGB, IME_RGB_COLOR(192, 0, 0), i, 1}; 125 for (++i; (i<sz) && (ppd->charTypeAt(i) & IPreeditString::ILLEGAL); ++i) 126 ; 127 fb.length = i - fb.start; 128 decos.push_back(fb); 129 130 } else if (ct & IPreeditString::NORMAL_CHAR) { 131 if (ct & IPreeditString::USER_CHOICE) { 132 ImeFeedbackRec fb = {ImeFeedbackForegroundRGB, IME_RGB_COLOR(0, 0, 192), i, 1}; 133 for (++i; (i < sz) && (ppd->charTypeAt(i) & IPreeditString::USER_CHOICE); ++i) 134 ; 135 fb.length = i - fb.start; 136 decos.push_back(fb); 137 } else { 138 ++i; 139 } 140 141 } else 142 ++i; 143 } 144 145 if ((trec.count_feedbacks = decos.size()) > 0) 146 trec.feedbacks = &decos[0]; 147 148 sm_imm_srvs->ImmShowPreedit(ic); 149 sm_imm_srvs->ImmUpdatePreedit(ic, &prec); 150 151 #ifdef DEBUG 152 printf("]done\n"); 153 fflush(stdout); 154 #endif 155 } 156 157 static unsigned char sclnumber[] = "1234567890"; 158 static unsigned char s_title[]="SUN"; 159 160 static ImeFeedbackRec s_fb[] = { 161 {ImeFeedbackForegroundRGB, IME_RGB_COLOR(0, 128, 0), 0, 0}, 162 {ImeFeedbackForegroundRGB, IME_RGB_COLOR(0, 0, 192), 0, 0} 163 }; 164 165 void 166 CCLEWinHandler::updateCandidates(const ICandidateList* pcl) 167 { 168 ImeTextRec scltext[16]; 169 170 #ifdef DEBUG 171 printf("CLEWin update Candidates["); 172 #endif 173 174 ImeInputContext ic = (ImeInputContext)mp_mainwin; 175 176 int sz = pcl->size(); 177 if (sz > 16) sz = 16; 178 179 if (sz <= 0) { 180 sm_imm_srvs->ImmHideCandidates(ic); 181 return; 182 } 183 184 sm_imm_srvs->ImmShowCandidates(ic); 185 186 for (int i=0; i < sz; ++i) { 187 scltext[i].count_feedbacks = 0; 188 scltext[i].feedbacks = NULL; 189 scltext[i].text = sclbuf[i]; 190 191 const TWCHAR* pcand = pcl->candiString(i); 192 int len = pcl->candiSize(i); 193 194 195 TIConvSrcPtr src = (TIConvSrcPtr)(pcand); 196 size_t srclen = (len+1)*sizeof(TWCHAR); 197 char * dst = (char*)sclbuf[i]; 198 size_t dstlen = 512 - 1; 199 iconv(m_iconv, &src, &srclen, &dst, &dstlen); 200 dstlen = 512 - 1 - dstlen; 201 202 if (pcl->candiType(i) == ICandidateList::BEST_TAIL) { 203 s_fb[0].length = pcl->candiSize(i); 204 scltext[i].count_feedbacks = 1; 205 scltext[i].feedbacks = s_fb; 206 } else if (pcl->candiType(i) == ICandidateList::BEST_WORD) { 207 s_fb[1].length = pcl->candiSize(i); 208 scltext[i].count_feedbacks = 1; 209 scltext[i].feedbacks = s_fb+1; 210 } else { 211 scltext[i].count_feedbacks = 0; 212 scltext[i].feedbacks = NULL; 213 } 214 } 215 CSunpinyinOptions *ppref = dynamic_cast<CSunpinyinOptions*>(m_pPrefLink); 216 ImeCandidatesRec cl; 217 218 cl.focus = 0; 219 cl.page_state = 0; 220 if (pcl->first() <= 0) cl.page_state |= 1; 221 cl.count = sz; 222 if (pcl->first() + cl.count >= pcl->total()) cl.page_state |= 2; 223 cl.title = s_title; 224 cl.candidates = scltext; 225 cl.numbers = sclnumber; 226 cl.horizental = ((ppref && ppref->m_LayoutVeritcal)?0:1); 227 sm_imm_srvs->ImmUpdateCandidates(ic, &cl); 228 229 #ifdef DEBUG 230 printf("%d]done\n", sz); 231 fflush(stdout); 232 #endif 233 } 234 235 void 236 CCLEWinHandler::updateStatus(int key, int value) 237 { 238 //need to do nothing, because CLE taking care of it. 239 } 240 241