📄 qximinputcontext_x11.cpp
字号:
xim_style = XIMPreeditNothing | XIMStatusNothing; break; } } // ... and failing that, None. for (i = 0; !xim_style && i < styles->count_styles; i++) { if (styles->supported_styles[i] == (XIMPreeditNone | XIMStatusNone)) { xim_style = XIMPreeditNone | XIMStatusNone; break; } } // qDebug("QApplication: using im style %lx", xim_style); XFree((char *)styles); } if (xim_style) {#ifdef USE_X11R6_XIM XUnregisterIMInstantiateCallback(X11->display, 0, 0, 0, (XIMProc) xim_create_callback, reinterpret_cast<char *>(this));#endif // USE_X11R6_XIM // following code fragment is not required for immodule // version of XIM#if 0 QWidgetList list = qApp->topLevelWidgets(); for (int i = 0; i < list.size(); ++i) { QWidget *w = list.at(i); w->d->createTLSysExtra(); }#endif } else { // Give up qWarning("No supported input style found." " See InputMethod documentation."); close_xim(); } }#endif // QT_NO_XIM}/*!\internal Closes the application input method.*/void QXIMInputContext::close_xim(){ QString errMsg(QLatin1String("QXIMInputContext::close_xim() has been called")); // ###clean up ximData! ximData.clear(); // ############## check this! // Calling XCloseIM gives a Purify FMR error // XCloseIM(xim); // We prefer a less serious memory leak xim = 0; if ( --fontsetRefCount == 0 ) { Display *dpy = X11->display; for ( int i = 0; i < 8; i++ ) { if ( fontsetCache[i] && fontsetCache[i] != (XFontSet)-1 ) { XFreeFontSet(dpy, fontsetCache[i]); fontsetCache[i] = 0; } } }}QXIMInputContext::~QXIMInputContext(){ close_xim();}QString QXIMInputContext::identifierName(){ // the name should be "xim" rather than "XIM" to be consistent // with corresponding immodule of GTK+ return QLatin1String("xim");}QString QXIMInputContext::language(){ QString language; if (xim) { QByteArray locale(XLocaleOfIM(xim)); if (locale.startsWith("zh")) { // Chinese language should be formed as "zh_CN", "zh_TW", "zh_HK" language = QLatin1String(locale.left(5)); } else { // other languages should be two-letter ISO 639 language code language = QLatin1String(locale.left(2)); } } return language;}void QXIMInputContext::reset(){ QWidget *w = focusWidget(); if (!w) return; ICData *data = ximData.value(w); if (!data) return; if (data->ic) { char *mb = XmbResetIC(data->ic); if (mb) { QInputMethodEvent e; e.setCommitString(QString::fromLocal8Bit(mb)); sendEvent(e); XFree(mb); } } data->clear();}void QXIMInputContext::widgetDestroyed(QWidget *w){ QInputContext::widgetDestroyed(w); ICData *data = ximData.take(w); if (!data) return; data->clear(); if (data->ic) XDestroyIC(data->ic); delete data;}void QXIMInputContext::mouseHandler(int pos, QMouseEvent *e){ if(e->type() != QEvent::MouseButtonPress) return; XIM_DEBUG("QXIMInputContext::mouseHandler pos=%d", pos); ICData *data = ximData.value(focusWidget()); if (!data) return; if (pos < 0 || pos > data->text.length()) reset(); // ##### handle mouse position}bool QXIMInputContext::isComposing() const{ QWidget *w = focusWidget(); if (!w) return false; ICData *data = ximData.value(w); if (!data) return false; return data->composing;}void QXIMInputContext::setFocusWidget(QWidget *w){ if (!xim) return; QWidget *oldFocus = focusWidget(); if (oldFocus == w) return; if (language() != QLatin1String("ja")) reset(); if (oldFocus) { ICData *data = ximData.value(oldFocus); if (data && data->ic) XUnsetICFocus(data->ic); } QInputContext::setFocusWidget(w); if (!w) return; ICData *data = ximData.value(w); if (!data) data = createICData(w); if (data->ic) XSetICFocus(data->ic); update();}bool QXIMInputContext::x11FilterEvent(QWidget *keywidget, XEvent *event){ int xkey_keycode = event->xkey.keycode; if (!keywidget->testAttribute(Qt::WA_WState_Created)) return false; if (XFilterEvent(event, keywidget->winId())) { qt_ximComposingKeycode = xkey_keycode; // ### not documented in xlib return true; } if (event->type != XKeyPress || event->xkey.keycode != 0) return false; QWidget *w = focusWidget(); if (keywidget != w) return false; ICData *data = ximData.value(w); if (!data) return false; // input method has sent us a commit string QByteArray string; string.resize(513); KeySym key; // unused Status status; // unused QString text; int count = XmbLookupString(data->ic, &event->xkey, string.data(), string.size(), &key, &status); if (status == XBufferOverflow) { string.resize(count + 1); count = XmbLookupString(data->ic, &event->xkey, string.data(), string.size(), &key, &status); } if (count > 0) { // XmbLookupString() gave us some text, convert it to unicode text = qt_input_mapper->toUnicode(string.constData() , count); if (text.isEmpty()) { // codec couldn't convert to unicode? this can happen when running in the // C locale (or with no LANG set). try converting from latin-1 text = QString::fromLatin1(string.constData(), count); } }#if 0 if (!(xim_style & XIMPreeditCallbacks) || !isComposing()) { // ############### send a regular key event here! ; }#endif QInputMethodEvent e; e.setCommitString(text); sendEvent(e); data->clear(); return true;}QXIMInputContext::ICData *QXIMInputContext::createICData(QWidget *w){ ICData *data = new ICData; data->widget = w; XVaNestedList preedit_attr = 0; XIMCallback startcallback, drawcallback, donecallback; QFont font = w->font(); data->fontset = getFontSet(font); if (xim_style & XIMPreeditArea) { XRectangle rect; rect.x = 0; rect.y = 0; rect.width = w->width(); rect.height = w->height(); preedit_attr = XVaCreateNestedList(0, XNArea, &rect, XNFontSet, data->fontset, (char *) 0); } else if (xim_style & XIMPreeditPosition) { XPoint spot; spot.x = 1; spot.y = 1; preedit_attr = XVaCreateNestedList(0, XNSpotLocation, &spot, XNFontSet, data->fontset, (char *) 0); } else if (xim_style & XIMPreeditCallbacks) { startcallback.client_data = (XPointer) this; startcallback.callback = (XIMProc) xic_start_callback; drawcallback.client_data = (XPointer) this; drawcallback.callback = (XIMProc)xic_draw_callback; donecallback.client_data = (XPointer) this; donecallback.callback = (XIMProc) xic_done_callback; preedit_attr = XVaCreateNestedList(0, XNPreeditStartCallback, &startcallback, XNPreeditDrawCallback, &drawcallback, XNPreeditDoneCallback, &donecallback, (char *) 0); } if (preedit_attr) { data->ic = XCreateIC(xim, XNInputStyle, xim_style, XNClientWindow, w->winId(), XNPreeditAttributes, preedit_attr, (char *) 0); XFree(preedit_attr); } else { data->ic = XCreateIC(xim, XNInputStyle, xim_style, XNClientWindow, w->winId(), (char *) 0); } if (data->ic) { // when resetting the input context, preserve the input state (void) XSetICValues(data->ic, XNResetState, XIMPreserveState, (char *) 0); } else { qWarning("Failed to create XIC"); } ximData[w] = data; return data;}void QXIMInputContext::update(){ QWidget *w = focusWidget(); if (!w) return; ICData *data = ximData.value(w); if (!data || !data->ic) return; QRect r = w->inputMethodQuery(Qt::ImMicroFocus).toRect(); QPoint p = QPoint((r.left() + r.right() + 1)/2, r.bottom()); XPoint spot; spot.x = p.x(); spot.y = p.y(); r = w->rect(); XRectangle area; area.x = r.x(); area.y = r.y(); area.width = r.width(); area.height = r.height(); XFontSet fontset = getFontSet(qvariant_cast<QFont>(w->inputMethodQuery(Qt::ImFont))); if (data->fontset == fontset) fontset = 0; else data->fontset = fontset; XVaNestedList preedit_attr; if (fontset) preedit_attr = XVaCreateNestedList(0, XNSpotLocation, &spot, XNArea, &area, XNFontSet, fontset, (char *) 0); else preedit_attr = XVaCreateNestedList(0, XNSpotLocation, &spot, XNArea, &area, (char *) 0); XSetICValues(data->ic, XNPreeditAttributes, preedit_attr, (char *) 0); XFree(preedit_attr);}#else/* When QT_NO_XIM is defined, we provide a dummy implementation for this class. The reason for this is that the header file is moc'ed regardless of QT_NO_XIM. The best would be to remove the file completely from the pri file is QT_NO_XIM was defined, or for moc to understand this preprocessor directive. Since the header does not declare this class when QT_NO_XIM is defined, this is dead code.*/bool QXIMInputContext::isComposing() const { return false; }QString QXIMInputContext::identifierName() { return QString(); }void QXIMInputContext::mouseHandler(int, QMouseEvent *) {}void QXIMInputContext::setFocusWidget(QWidget *) {}void QXIMInputContext::reset() {}void QXIMInputContext::update() {}QXIMInputContext::~QXIMInputContext() {}void QXIMInputContext::widgetDestroyed(QWidget *) {}QString QXIMInputContext::language() { return QString(); }bool QXIMInputContext::x11FilterEvent(QWidget *, XEvent *) { return true; }#endif //QT_NO_XIM#endif //QT_NO_IM
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -