diff options
Diffstat (limited to 'tqtinterface/qt4/src/kernel/tqinputcontext_x11.cpp')
-rw-r--r-- | tqtinterface/qt4/src/kernel/tqinputcontext_x11.cpp | 504 |
1 files changed, 19 insertions, 485 deletions
diff --git a/tqtinterface/qt4/src/kernel/tqinputcontext_x11.cpp b/tqtinterface/qt4/src/kernel/tqinputcontext_x11.cpp index 758b56d..e96c75c 100644 --- a/tqtinterface/qt4/src/kernel/tqinputcontext_x11.cpp +++ b/tqtinterface/qt4/src/kernel/tqinputcontext_x11.cpp @@ -36,500 +36,34 @@ ** **********************************************************************/ +#include "tqinputcontext.h" + +#ifndef TQT_NO_IM + #include "tqplatformdefs.h" #include "tqapplication.h" #include "tqwidget.h" -#include "tqinputcontext_p.h" - -#include <stdlib.h> -#include <limits.h> +#include "tqt_x11_p.h" -bool qt_compose_emptied = FALSE; +/*! + This function may be overridden only if input method is depending + on X11 and you need raw XEvent. Otherwise, this function must not. -#if !defined(TQT_NO_XIM) + This function is designed to filter raw key events for XIM, but + other input methods may use this to implement some special + features such as distinguishing Shift_L and Shift_R. -#define XK_MISCELLANY -#define XK_LATIN1 -#include <X11/keysymdef.h> + Return TRUE if the \a event has been consumed. Otherwise, the + unfiltered \a event will be translated into TQEvent and forwarded + to filterEvent(). Filtering at both x11FilterEvent() and + filterEvent() in single input method is allowed. -// #define TQT_XIM_DEBUG + \a keywidget is a client widget into which a text is inputted. \a + event is inputted XEvent. -// from qapplication_x11.cpp -extern XIM qt_xim; -extern XIMStyle qt_xim_style; - -/* The cache here is needed, as X11 leaks a few kb for every - XFreeFontSet call, so we avoid creating and deletion of fontsets as - much as possible + \sa filterEvent() */ -static XFontSet fontsetCache[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; -static int fontsetRefCount = 0; - -static const char * const fontsetnames[] = { - "-*-fixed-medium-r-*-*-16-*,-*-*-medium-r-*-*-16-*", - "-*-fixed-medium-i-*-*-16-*,-*-*-medium-i-*-*-16-*", - "-*-fixed-bold-r-*-*-16-*,-*-*-bold-r-*-*-16-*", - "-*-fixed-bold-i-*-*-16-*,-*-*-bold-i-*-*-16-*", - "-*-fixed-medium-r-*-*-24-*,-*-*-medium-r-*-*-24-*", - "-*-fixed-medium-i-*-*-24-*,-*-*-medium-i-*-*-24-*", - "-*-fixed-bold-r-*-*-24-*,-*-*-bold-r-*-*-24-*", - "-*-fixed-bold-i-*-*-24-*,-*-*-bold-i-*-*-24-*" -}; - -static XFontSet getFontSet( const TQFont &f ) -{ - int i = 0; - if (f.italic()) - i |= 1; - if (f.bold()) - i |= 2; - - if ( f.pointSize() > 20 ) - i += 4; - - if ( !fontsetCache[i] ) { - Display* dpy = TQPaintDevice::x11AppDisplay(); - int missCount; - char** missList; - fontsetCache[i] = XCreateFontSet(dpy, fontsetnames[i], &missList, &missCount, 0); - if(missCount > 0) - XFreeStringList(missList); - if ( !fontsetCache[i] ) { - fontsetCache[i] = XCreateFontSet(dpy, "-*-fixed-*-*-*-*-16-*", &missList, &missCount, 0); - if(missCount > 0) - XFreeStringList(missList); - if ( !fontsetCache[i] ) - fontsetCache[i] = (XFontSet)-1; - } - } - return (fontsetCache[i] == (XFontSet)-1) ? 0 : fontsetCache[i]; -} - - -#ifdef TQ_C_CALLBACKS -extern "C" { -#endif // TQ_C_CALLBACKS - - static int xic_start_callback(XIC, XPointer client_data, XPointer) { - TQInputContext *qic = (TQInputContext *) client_data; - if (! qic) { -#ifdef TQT_XIM_DEBUG - qDebug("compose start: no qic"); -#endif // TQT_XIM_DEBUG - - return 0; - } - - qic->composing = TRUE; - qic->text = TQString::null; - qic->tqfocusWidget = 0; - - if ( qic->selectedChars.size() < 128 ) - qic->selectedChars.resize( 128 ); - qic->selectedChars.fill( 0 ); - -#ifdef TQT_XIM_DEBUG - qDebug("compose start"); -#endif // TQT_XIM_DEBUG - - return 0; - } - - static int xic_draw_callback(XIC, XPointer client_data, XPointer call_data) { - TQInputContext *qic = (TQInputContext *) client_data; - if (! qic) { -#ifdef TQT_XIM_DEBUG - qDebug("compose event: invalid compose event %p", qic); -#endif // TQT_XIM_DEBUG - - return 0; - } - - bool send_imstart = FALSE; - if (tqApp->tqfocusWidget() != qic->tqfocusWidget && qic->text.isEmpty()) { - if (qic->tqfocusWidget) { -#ifdef TQT_XIM_DEBUG - qDebug( "sending IMEnd (empty) to %p", qic->tqfocusWidget ); -#endif // TQT_XIM_DEBUG - - TQIMEvent endevent(TQEvent::IMEnd, TQString::null, -1); - TQApplication::sendEvent(qic->tqfocusWidget, &endevent); - } - - qic->text = TQString::null; - qic->tqfocusWidget = tqApp->tqfocusWidget(); - qic->composing = FALSE; - - if ( qic->selectedChars.size() < 128 ) - qic->selectedChars.resize( 128 ); - qic->selectedChars.fill( 0 ); - - if (qic->tqfocusWidget) { - qic->composing = TRUE; - send_imstart = TRUE; - } - } - - if (! qic->composing || ! qic->tqfocusWidget) { -#ifdef TQT_XIM_DEBUG - qDebug("compose event: invalid compose event %d %p", - qic->composing, qic->tqfocusWidget); -#endif // TQT_XIM_DEBUG - - return 0; - } - - if ( send_imstart ) { -#ifdef TQT_XIM_DEBUG - qDebug( "sending IMStart to %p", qic->tqfocusWidget ); -#endif // TQT_XIM_DEBUG - - qt_compose_emptied = FALSE; - TQIMEvent startevent(TQEvent::IMStart, TQString::null, -1); - TQApplication::sendEvent(qic->tqfocusWidget, &startevent); - } - - XIMPreeditDrawCallbackStruct *drawstruct = - (XIMPreeditDrawCallbackStruct *) call_data; - XIMText *text = (XIMText *) drawstruct->text; - int cursor = drawstruct->caret, sellen = 0; - - if ( ! drawstruct->caret && ! drawstruct->chg_first && - ! drawstruct->chg_length && ! text ) { - // nothing to do - return 0; - } - - if (text) { - char *str = 0; - if (text->encoding_is_wchar) { - int l = wcstombs(NULL, text->string.wide_char, text->length); - if (l != -1) { - str = new char[l + 1]; - wcstombs(str, text->string.wide_char, l); - str[l] = 0; - } - } else - str = text->string.multi_byte; - - if (! str) - return 0; - - TQString s = TQString::fromLocal8Bit(str); - - if (text->encoding_is_wchar) - delete [] str; - - if (drawstruct->chg_length < 0) - qic->text.tqreplace(drawstruct->chg_first, UINT_MAX, s); - else - qic->text.tqreplace(drawstruct->chg_first, drawstruct->chg_length, s); - - if ( qic->selectedChars.size() < qic->text.length() ) { - // expand the selectedChars array if the compose string is longer - uint from = qic->selectedChars.size(); - qic->selectedChars.resize( qic->text.length() ); - for ( uint x = from; from < qic->selectedChars.size(); ++x ) - qic->selectedChars[x] = 0; - } - - uint x; - bool *p = qic->selectedChars.data() + drawstruct->chg_first; - // determine if the changed chars are selected based on text->feedback - for ( x = 0; x < s.length(); ++x ) - *p++ = ( text->feedback ? ( text->feedback[x] & XIMReverse ) : 0 ); - - // figure out where the selection starts, and how long it is - p = qic->selectedChars.data(); - bool started = FALSE; - for ( x = 0; x < TQMIN(qic->text.length(), qic->selectedChars.size()); ++x ) { - if ( started ) { - if ( *p ) ++sellen; - else break; - } else { - if ( *p ) { - cursor = x; - started = TRUE; - sellen = 1; - } - } - ++p; - } - } else { - if (drawstruct->chg_length == 0) - drawstruct->chg_length = -1; - - qic->text.remove(drawstruct->chg_first, drawstruct->chg_length); - qt_compose_emptied = qic->text.isEmpty(); - if ( qt_compose_emptied ) { -#ifdef TQT_XIM_DEBUG - qDebug( "compose emptied" ); -#endif // TQT_XIM_DEBUG - - // don't send an empty compose, since we will send an IMEnd with - // either the correct compose text (or null text if the user has - // cancelled the compose or deleted all chars). - return 0; - } - } - -#ifdef TQT_XIM_DEBUG - qDebug( "sending IMCompose to %p with %d chars", - qic->tqfocusWidget, qic->text.length() ); -#endif // TQT_XIM_DEBUG - - TQIMComposeEvent event( TQEvent::IMCompose, qic->text, cursor, sellen ); - TQApplication::sendEvent(qic->tqfocusWidget, &event); - return 0; - } - - static int xic_done_callback(XIC, XPointer client_data, XPointer) { - TQInputContext *qic = (TQInputContext *) client_data; - if (! qic) - return 0; - - if (qic->composing && qic->tqfocusWidget) { -#ifdef TQT_XIM_DEBUG - qDebug( "sending IMEnd (empty) to %p", qic->tqfocusWidget ); -#endif // TQT_XIM_DEBUG - - TQIMEvent event(TQEvent::IMEnd, TQString::null, -1); - TQApplication::sendEvent(qic->tqfocusWidget, &event); - } - - qic->composing = FALSE; - qic->tqfocusWidget = 0; - - if ( qic->selectedChars.size() < 128 ) - qic->selectedChars.resize( 128 ); - qic->selectedChars.fill( 0 ); - - return 0; - } - -#ifdef TQ_C_CALLBACKS -} -#endif // TQ_C_CALLBACKS - -#endif // !TQT_NO_XIM - - - -TQInputContext::TQInputContext(TQWidget *widget) - : ic(0), tqfocusWidget(0), composing(FALSE), fontset(0) -{ -#if !defined(TQT_NO_XIM) - fontsetRefCount++; - if (! qt_xim) { - qWarning("TQInputContext: no input method context available"); - return; - } - - if (! widget->isTopLevel()) { - qWarning("TQInputContext: cannot create input context for non-toplevel widgets"); - return; - } - - XPoint spot; - XRectangle rect; - XVaNestedList preedit_attr = 0; - XIMCallback startcallback, drawcallback, donecallback; - - font = widget->font(); - fontset = getFontSet( font ); - - if (qt_xim_style & XIMPreeditArea) { - rect.x = 0; - rect.y = 0; - rect.width = widget->width(); - rect.height = widget->height(); - - preedit_attr = XVaCreateNestedList(0, - XNArea, &rect, - XNFontSet, fontset, - (char *) 0); - } else if (qt_xim_style & XIMPreeditPosition) { - spot.x = 1; - spot.y = 1; - - preedit_attr = XVaCreateNestedList(0, - XNSpotLocation, &spot, - XNFontSet, fontset, - (char *) 0); - } else if (qt_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) { - ic = XCreateIC(qt_xim, - XNInputStyle, qt_xim_style, - XNClientWindow, widget->winId(), - XNPreeditAttributes, preedit_attr, - (char *) 0); - XFree(preedit_attr); - } else - ic = XCreateIC(qt_xim, - XNInputStyle, qt_xim_style, - XNClientWindow, widget->winId(), - (char *) 0); - - if (! ic) - qFatal("Failed to create XIM input context!"); - - // when resetting the input context, preserve the input state - (void) XSetICValues((XIC) ic, XNResetState, XIMPreserveState, (char *) 0); -#endif // !TQT_NO_XIM -} - - -TQInputContext::~TQInputContext() -{ - -#if !defined(TQT_NO_XIM) - if (ic) - XDestroyIC((XIC) ic); - - if ( --fontsetRefCount == 0 ) { - Display *dpy = TQPaintDevice::x11AppDisplay(); - for ( int i = 0; i < 8; i++ ) { - if ( fontsetCache[i] && fontsetCache[i] != (XFontSet)-1 ) { - XFreeFontSet(dpy, fontsetCache[i]); - fontsetCache[i] = 0; - } - } - } - -#endif // !TQT_NO_XIM - - ic = 0; - tqfocusWidget = 0; - composing = FALSE; -} - - -void TQInputContext::reset() -{ -#if !defined(TQT_NO_XIM) - if (tqfocusWidget && composing && ! text.isNull()) { -#ifdef TQT_XIM_DEBUG - qDebug("TQInputContext::reset: composing - sending IMEnd (empty) to %p", - tqfocusWidget); -#endif // TQT_XIM_DEBUG - - TQIMEvent endevent(TQEvent::IMEnd, TQString::null, -1); - TQApplication::sendEvent(tqfocusWidget, &endevent); - tqfocusWidget = 0; - text = TQString::null; - if ( selectedChars.size() < 128 ) - selectedChars.resize( 128 ); - selectedChars.fill( 0 ); - - char *mb = XmbResetIC((XIC) ic); - if (mb) - XFree(mb); - } -#endif // !TQT_NO_XIM -} - - -void TQInputContext::setComposePosition(int x, int y) -{ -#if !defined(TQT_NO_XIM) - if (qt_xim && ic) { - XPoint point; - point.x = x; - point.y = y; - - XVaNestedList preedit_attr = - XVaCreateNestedList(0, - XNSpotLocation, &point, - - (char *) 0); - XSetICValues((XIC) ic, XNPreeditAttributes, preedit_attr, (char *) 0); - XFree(preedit_attr); - } -#endif // !TQT_NO_XIM -} - - -void TQInputContext::setComposeArea(int x, int y, int w, int h) -{ -#if !defined(TQT_NO_XIM) - if (qt_xim && ic) { - XRectangle rect; - rect.x = x; - rect.y = y; - rect.width = w; - rect.height = h; - - XVaNestedList preedit_attr = XVaCreateNestedList(0, - XNArea, &rect, - - (char *) 0); - XSetICValues((XIC) ic, XNPreeditAttributes, preedit_attr, (char *) 0); - XFree(preedit_attr); - } -#endif -} - - -int TQInputContext::lookupString(XKeyEvent *event, TQCString &chars, - KeySym *key, Status *status) const -{ - int count = 0; - -#if !defined(TQT_NO_XIM) - if (qt_xim && ic) { - count = XmbLookupString((XIC) ic, event, chars.data(), - chars.size(), key, status); - - if ((*status) == XBufferOverflow ) { - chars.resize(count + 1); - count = XmbLookupString((XIC) ic, event, chars.data(), - chars.size(), key, status); - } - } - -#endif // TQT_NO_XIM - - return count; -} - -void TQInputContext::setFocus() -{ -#if !defined(TQT_NO_XIM) - if (qt_xim && ic) - XSetICFocus((XIC) ic); -#endif // !TQT_NO_XIM -} - -void TQInputContext::setXFontSet(const TQFont &f) -{ -#if !defined(TQT_NO_XIM) - if (font == f) return; // nothing to do - font = f; - - XFontSet fs = getFontSet(font); - if (fontset == fs) return; // nothing to do - fontset = fs; - XVaNestedList preedit_attr = XVaCreateNestedList(0, XNFontSet, fontset, (char *) 0); - XSetICValues((XIC) ic, XNPreeditAttributes, preedit_attr, (char *) 0); - XFree(preedit_attr); -#else - TQ_UNUSED( f ); -#endif -} +#endif //TQ_NO_IM
\ No newline at end of file |