summaryrefslogtreecommitdiffstats
path: root/tqtinterface/qt4/src/kernel/tqinputcontext_x11.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tqtinterface/qt4/src/kernel/tqinputcontext_x11.cpp')
-rw-r--r--tqtinterface/qt4/src/kernel/tqinputcontext_x11.cpp504
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