00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 #include <tqapplication.h>
00050 #include <tqptrlist.h>
00051 #include <tqptrdict.h>
00052 #include <tqguardedptr.h>
00053 #include <tqwhatsthis.h>
00054 #include <tqfocusdata.h>
00055
00056
00057 #ifdef Q_WS_X11
00058
00059 # include <X11/X.h>
00060 # include <X11/Xlib.h>
00061 # include <X11/Xutil.h>
00062 # include <X11/Xatom.h>
00063 # define XK_MISCELLANY
00064 # define XK_LATIN1
00065 # include <X11/keysymdef.h>
00066 # include <kdebug.h>
00067 # include <kxerrorhandler.h>
00068
00069
00070 # include <config.h>
00071 # ifdef HAVE_UNISTD_H
00072 # include <unistd.h>
00073 # ifdef HAVE_USLEEP
00074 # define USLEEP(x) usleep(x)
00075 # else
00076 # define USLEEP(x) sleep(0)
00077 # endif
00078 # else
00079 # define USLEEP(x) sleep(0)
00080 # endif
00081
00082 # include "qxembed.h"
00083
00084
00085 # ifndef XK_ISO_Left_Tab
00086 # define XK_ISO_Left_Tab 0xFE20
00087 # endif
00088
00089
00090 const int XFocusOut = FocusOut;
00091 const int XFocusIn = FocusIn;
00092 const int XKeyPress = KeyPress;
00093 const int XKeyRelease = KeyRelease;
00094 # undef KeyRelease
00095 # undef KeyPress
00096 # undef FocusOut
00097 # undef FocusIn
00098
00099
00100 extern Atom tqt_wm_protocols;
00101 extern Atom tqt_wm_delete_window;
00102 extern Atom tqt_wm_take_focus;
00103 extern Atom tqt_wm_state;
00104
00105
00106 static Atom xembed = 0;
00107 static Atom context_help = 0;
00108
00109
00110 #define XEMBED_EMBEDDED_NOTIFY 0
00111 #define XEMBED_WINDOW_ACTIVATE 1
00112 #define XEMBED_WINDOW_DEACTIVATE 2
00113 #define XEMBED_REQUEST_FOCUS 3
00114 #define XEMBED_FOCUS_IN 4
00115 #define XEMBED_FOCUS_OUT 5
00116 #define XEMBED_FOCUS_NEXT 6
00117 #define XEMBED_FOCUS_PREV 7
00118
00119
00120
00121 #define XEMBED_FOCUS_CURRENT 0
00122 #define XEMBED_FOCUS_FIRST 1
00123 #define XEMBED_FOCUS_LAST 2
00124
00125
00126
00127
00128 class QXEmbedData
00129 {
00130 public:
00131 QXEmbedData(){
00132 autoDelete = true;
00133 xplain = false;
00134 xgrab = false;
00135 mapAfterRelease = false;
00136 lastPos = TQPoint(0,0);
00137 }
00138 ~QXEmbedData(){}
00139
00140 bool autoDelete;
00141 bool xplain;
00142 bool xgrab;
00143 bool mapAfterRelease;
00144 TQWidget* focusProxy;
00145 TQPoint lastPos;
00146 };
00147
00148 namespace
00149 {
00150
00151
00152 class QXEmbedAppFilter : public TQObject
00153 {
00154 public:
00155 QXEmbedAppFilter() { tqApp->installEventFilter( this ); }
00156 ~QXEmbedAppFilter() { }
00157 bool eventFilter( TQObject *, TQEvent * );
00158 };
00159 }
00160
00161
00162 static QXEmbedAppFilter* filter = 0;
00163
00164 static TQPtrDict<TQGuardedPtr<TQWidget> > *focusMap = 0;
00165
00166 static XKeyEvent last_key_event;
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176 class QPublicWidget : public TQWidget
00177 {
00178 public:
00179 TQTLWExtra* topData() { return TQWidget::topData(); }
00180 TQFocusData *focusData(){ return TQWidget::focusData(); }
00181 bool focusNextPrev(bool b) { return focusNextPrevChild(b); }
00182 };
00183
00184
00185
00186 typedef int (*QX11EventFilter) (XEvent*);
00187 extern QX11EventFilter tqt_set_x11_event_filter (QX11EventFilter filter);
00188 static QX11EventFilter oldFilter = 0;
00189
00190
00191
00192 static void sendXEmbedMessage( WId window, long message, long detail = 0,
00193 long data1 = 0, long data2 = 0)
00194 {
00195 if (!window) return;
00196 XEvent ev;
00197 memset(&ev, 0, sizeof(ev));
00198 ev.xclient.type = ClientMessage;
00199 ev.xclient.window = window;
00200 ev.xclient.message_type = xembed;
00201 ev.xclient.format = 32;
00202 ev.xclient.data.l[0] = GET_QT_X_TIME();
00203 ev.xclient.data.l[1] = message;
00204 ev.xclient.data.l[2] = detail;
00205 ev.xclient.data.l[3] = data1;
00206 ev.xclient.data.l[4] = data2;
00207 XSendEvent(tqt_xdisplay(), window, false, NoEventMask, &ev);
00208 }
00209
00210
00211
00212 static void sendClientMessage(Window window, Atom a, long x)
00213 {
00214 if (!window) return;
00215 XEvent ev;
00216 memset(&ev, 0, sizeof(ev));
00217 ev.xclient.type = ClientMessage;
00218 ev.xclient.window = window;
00219 ev.xclient.message_type = a;
00220 ev.xclient.format = 32;
00221 ev.xclient.data.l[0] = x;
00222 ev.xclient.data.l[1] = GET_QT_X_TIME();
00223 XSendEvent(tqt_xdisplay(), window, false, NoEventMask, &ev);
00224 }
00225
00226
00227
00228 static void sendFocusMessage(Window window, int type, int mode, int detail)
00229 {
00230 if (!window) return;
00231 XEvent ev;
00232 memset(&ev, 0, sizeof(ev));
00233 ev.xfocus.type = type;
00234 ev.xfocus.window = window;
00235 ev.xfocus.mode = mode;
00236 ev.xfocus.detail = detail;
00237 XSendEvent(tqt_xdisplay(), window, false, FocusChangeMask, &ev);
00238 }
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299 bool QXEmbedAppFilter::eventFilter( TQObject *o, TQEvent * e)
00300 {
00301 static bool obeyFocus = false;
00302 switch ( e->type() ) {
00303 case TQEvent::MouseButtonPress:
00304
00305 if ( !((TQWidget*)o)->isActiveWindow() )
00306 obeyFocus = true;
00307 break;
00308 case TQEvent::FocusIn:
00309
00310
00311
00312
00313 if ( TQT_BASE_OBJECT(tqApp->focusWidget()) == TQT_BASE_OBJECT(o) &&
00314 ((QPublicWidget*)tqApp->focusWidget()->topLevelWidget())->topData()->embedded ) {
00315 TQFocusEvent* fe = (TQFocusEvent*) e;
00316 if ( obeyFocus || fe->reason() != TQFocusEvent::ActiveWindow
00317 ) {
00318
00319
00320
00321
00322 #ifdef USE_QT4
00323 WId window = ((QPublicWidget*)tqApp->focusWidget()->topLevelWidget())->effectiveWinId();
00324 #else // USE_QT4
00325 WId window = ((QPublicWidget*)tqApp->focusWidget()->topLevelWidget())->topData()->parentWinId;
00326 #endif // USE_QT4
00327 focusMap->remove( tqApp->focusWidget()->topLevelWidget() );
00328 sendXEmbedMessage( window, XEMBED_REQUEST_FOCUS );
00329 } else if ( fe->reason() == TQFocusEvent::ActiveWindow ) {
00330
00331
00332
00333
00334
00335 focusMap->remove( tqApp->focusWidget()->topLevelWidget() );
00336 focusMap->insert( tqApp->focusWidget()->topLevelWidget(),
00337 new TQGuardedPtr<TQWidget>(tqApp->focusWidget()->topLevelWidget()->focusWidget() ) );
00338
00339
00340 tqApp->focusWidget()->clearFocus();
00341
00342 }
00343 obeyFocus = false;
00344 }
00345 break;
00346 case TQEvent::KeyPress:
00347 if (TQT_BASE_OBJECT(tqApp->focusWidget()) == TQT_BASE_OBJECT(o) &&
00348 ((QPublicWidget*)tqApp->focusWidget()->topLevelWidget())->topData()->embedded ) {
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361 TQKeyEvent *k = (TQKeyEvent *)e;
00362 TQWidget *w = tqApp->focusWidget();
00363
00364 bool res = false;
00365 bool tabForward = true;
00366 if ( !(k->state() & ControlButton || k->state() & AltButton) ) {
00367 if ( k->key() == Key_Backtab || (k->key() == Key_Tab && (k->state() & ShiftButton)) ) {
00368 #ifdef USE_QT4
00369 res = ((QPublicWidget*)w)->focusNextPrev( tabForward = false );
00370 #else // USE_QT4
00371 TQFocusEvent::setReason( TQFocusEvent::Backtab );
00372 res = ((QPublicWidget*)w)->focusNextPrev( tabForward = false );
00373 TQFocusEvent::resetReason();
00374 #endif // USE_QT4
00375 } else if ( k->key() == Key_Tab ) {
00376 #ifdef USE_QT4
00377 res = ((QPublicWidget*)w)->focusNextPrev( tabForward = true );
00378 #else // USE_QT4
00379 TQFocusEvent::setReason( TQFocusEvent::Tab );
00380 res = ((QPublicWidget*)w)->focusNextPrev( tabForward = true );
00381 TQFocusEvent::resetReason();
00382 #endif // USE_QT4
00383 }
00384 }
00385 if (res) {
00386
00387
00388 TQFocusData *fd = ((QPublicWidget*)w)->focusData();
00389 #ifdef USE_QT4
00390 WId window = ((QPublicWidget*)w->topLevelWidget())->effectiveWinId();
00391 #else // USE_QT4
00392 WId window = ((QPublicWidget*)w->topLevelWidget())->topData()->parentWinId;
00393 #endif // USE_QT4
00394 TQWidget *cw = 0;
00395 TQWidget *fw = fd->home();
00396 if (tabForward && window) {
00397 while (cw != w && cw != fw && cw != w->topLevelWidget())
00398 cw = fd->prev();
00399 if (cw != w)
00400 sendXEmbedMessage( window, XEMBED_FOCUS_NEXT );
00401 } else if (window) {
00402 while (cw != w && cw != fw && cw != w->topLevelWidget())
00403 cw = fd->next();
00404 if (cw != w)
00405 sendXEmbedMessage( window, XEMBED_FOCUS_PREV );
00406 }
00407
00408 return true;
00409 }
00410 }
00411 break;
00412 default:
00413 break;
00414 }
00415
00416 return false;
00417 }
00418
00419
00420
00421 static int qxembed_x11_event_filter( XEvent* e)
00422 {
00423 switch ( e->type ) {
00424 case XKeyPress:
00425 case XKeyRelease: {
00426
00427 last_key_event = e->xkey;
00428 break;
00429 }
00430 case ClientMessage:
00431 if ( e->xclient.message_type == xembed ) {
00432
00433
00434 Time msgtime = (Time) e->xclient.data.l[0];
00435 long message = e->xclient.data.l[1];
00436 long detail = e->xclient.data.l[2];
00437
00438 if ( msgtime > GET_QT_X_TIME() )
00439 SET_QT_X_TIME(msgtime);
00440 TQWidget* w = TQT_TQWIDGET(TQWidget::find( e->xclient.window ));
00441 if ( !w )
00442 break;
00443 switch ( message) {
00444 case XEMBED_EMBEDDED_NOTIFY: {
00445
00446 TQTLWExtra *extra = ((QPublicWidget*)w->topLevelWidget())->topData();
00447 extra->embedded = 1;
00448 #ifdef USE_QT4
00449
00450 printf("[FIXME] WId not set in tdelibs/tdeui/qxembed.cpp\n");
00451 #else // USE_QT4
00452 extra->parentWinId = e->xclient.data.l[3];
00453 #endif // USE_QT4
00454 w->topLevelWidget()->show();
00455 break;
00456 }
00457 case XEMBED_WINDOW_ACTIVATE: {
00458
00459
00460
00461
00462
00463 XEvent ev;
00464 memset(&ev, 0, sizeof(ev));
00465 ev.xfocus.display = tqt_xdisplay();
00466 ev.xfocus.type = XFocusIn;
00467 ev.xfocus.window = w->topLevelWidget()->winId();
00468 ev.xfocus.mode = NotifyNormal;
00469 ev.xfocus.detail = NotifyAncestor;
00470 tqApp->x11ProcessEvent( &ev );
00471 }
00472 break;
00473 case XEMBED_WINDOW_DEACTIVATE: {
00474
00475
00476
00477 XEvent ev;
00478 memset(&ev, 0, sizeof(ev));
00479 ev.xfocus.display = tqt_xdisplay();
00480 ev.xfocus.type = XFocusOut;
00481 ev.xfocus.window = w->topLevelWidget()->winId();
00482 ev.xfocus.mode = NotifyNormal;
00483 ev.xfocus.detail = NotifyAncestor;
00484 tqApp->x11ProcessEvent( &ev );
00485 }
00486 break;
00487 case XEMBED_FOCUS_IN:
00488
00489 {
00490
00491 TQWidget* focusCurrent = 0;
00492 TQGuardedPtr<TQWidget>* fw = focusMap->find( w->topLevelWidget() );
00493 if ( fw ) {
00494 focusCurrent = *fw;
00495
00496 focusMap->remove( w->topLevelWidget() );
00497 }
00498 switch ( detail ) {
00499 case XEMBED_FOCUS_CURRENT:
00500
00501 if ( focusCurrent ) {
00502 focusCurrent->setFocus();
00503 if( QXEmbed* emb = tqt_dynamic_cast< QXEmbed* >( focusCurrent ))
00504 emb->updateEmbeddedFocus( true );
00505 }
00506 else if ( !w->topLevelWidget()->focusWidget() )
00507 w->topLevelWidget()->setFocus();
00508 break;
00509 case XEMBED_FOCUS_FIRST:
00510 {
00511
00512 #ifdef USE_QT4
00513 w->topLevelWidget()->setFocus();
00514 ((QPublicWidget*)w->topLevelWidget())->focusNextPrev(true);
00515 #else // USE_QT4
00516 TQFocusEvent::setReason( TQFocusEvent::Tab );
00517 w->topLevelWidget()->setFocus();
00518 ((QPublicWidget*)w->topLevelWidget())->focusNextPrev(true);
00519 TQFocusEvent::resetReason();
00520 #endif // USE_QT4
00521 }
00522 break;
00523 case XEMBED_FOCUS_LAST:
00524 {
00525
00526 #ifdef USE_QT4
00527 w->topLevelWidget()->setFocus();
00528 ((QPublicWidget*)w->topLevelWidget())->focusNextPrev(false);
00529 #else // USE_QT4
00530 TQFocusEvent::setReason( TQFocusEvent::Backtab );
00531 w->topLevelWidget()->setFocus();
00532 ((QPublicWidget*)w->topLevelWidget())->focusNextPrev(false);
00533 TQFocusEvent::resetReason();
00534 #endif // USE_QT4
00535 }
00536 break;
00537 default:
00538 break;
00539 }
00540 }
00541 break;
00542 case XEMBED_FOCUS_OUT:
00543
00544
00545
00546 if ( w->topLevelWidget()->focusWidget() ) {
00547 if( QXEmbed* emb = tqt_dynamic_cast< QXEmbed* >( w->topLevelWidget()->focusWidget()))
00548 emb->updateEmbeddedFocus( false );
00549 focusMap->insert( w->topLevelWidget(),
00550 new TQGuardedPtr<TQWidget>(w->topLevelWidget()->focusWidget() ) );
00551 w->topLevelWidget()->focusWidget()->clearFocus();
00552 }
00553 break;
00554 default:
00555 break;
00556 }
00557 } else if ( e->xclient.format == 32 && e->xclient.message_type ) {
00558 if ( e->xclient.message_type == tqt_wm_protocols ) {
00559 TQWidget* w = TQT_TQWIDGET(TQWidget::find( e->xclient.window ));
00560 if ( !w )
00561 break;
00562
00563
00564
00565
00566
00567
00568
00569 Atom a = e->xclient.data.l[0];
00570 if ( a == tqt_wm_take_focus ) {
00571
00572 if ( (ulong) e->xclient.data.l[1] > GET_QT_X_TIME() )
00573 SET_QT_X_TIME(e->xclient.data.l[1]);
00574
00575
00576
00577
00578 if ( w->isActiveWindow() ) {
00579 TQEvent e( TQEvent::WindowActivate );
00580 TQApplication::sendEvent( w, &e );
00581 }
00582 }
00583 }
00584 }
00585 break;
00586 default:
00587 break;
00588 }
00589
00590 if ( oldFilter )
00591 return oldFilter( e );
00592
00593 return false;
00594 }
00595
00596
00597
00598
00599
00600
00601
00602
00603 void QXEmbed::initialize()
00604 {
00605 static bool is_initialized = false;
00606 if ( is_initialized )
00607 return;
00608
00609
00610 xembed = XInternAtom( tqt_xdisplay(), "_XEMBED", false );
00611
00612 oldFilter = tqt_set_x11_event_filter( qxembed_x11_event_filter );
00613
00614 focusMap = new TQPtrDict<TQGuardedPtr<TQWidget> >;
00615 focusMap->setAutoDelete( true );
00616
00617 filter = new QXEmbedAppFilter;
00618
00619 is_initialized = true;
00620 }
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643 QXEmbed::QXEmbed(TQWidget *parent, const char *name, WFlags f)
00644 : TQWidget(parent, name, f)
00645 {
00646
00647 d = new QXEmbedData;
00648
00649
00650
00651
00652
00653
00654 d->focusProxy = new TQWidget( topLevelWidget(), "xembed_focus" );
00655 d->focusProxy->setGeometry( -1, -1, 1, 1 );
00656 d->focusProxy->show();
00657
00658 TQApplication::sendPostedEvents( d->focusProxy, 0 );
00659
00660
00661
00662 initialize();
00663 window = 0;
00664 setFocusPolicy(TQ_StrongFocus);
00665 setKeyCompression( false );
00666
00667
00668 (void) topData();
00669
00670
00671
00672
00673 XSelectInput(tqt_xdisplay(), winId(),
00674 KeyPressMask | KeyReleaseMask |
00675 ButtonPressMask | ButtonReleaseMask |
00676 KeymapStateMask |
00677 ButtonMotionMask |
00678 PointerMotionMask |
00679 EnterWindowMask | LeaveWindowMask |
00680 FocusChangeMask |
00681 ExposureMask |
00682 StructureNotifyMask |
00683 SubstructureRedirectMask |
00684 SubstructureNotifyMask
00685 );
00686
00687
00688
00689 topLevelWidget()->installEventFilter( this );
00690 tqApp->installEventFilter( this );
00691
00692
00693
00694 if ( tqApp->activeWindow() == topLevelWidget() )
00695 if ( !((QPublicWidget*) topLevelWidget())->topData()->embedded )
00696 XSetInputFocus( tqt_xdisplay(), d->focusProxy->winId(),
00697 RevertToParent, GET_QT_X_TIME() );
00698
00699 setAcceptDrops( true );
00700 }
00701
00702
00703 QXEmbed::~QXEmbed()
00704 {
00705
00706 if ( d && d->xgrab)
00707 XUngrabButton( tqt_xdisplay(), AnyButton, AnyModifier, winId() );
00708 if ( window && ( autoDelete() || !d->xplain ))
00709 {
00710
00711
00712
00713 #if 0
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724 #else
00725 if( autoDelete())
00726 XUnmapWindow( tqt_xdisplay(), window );
00727 #endif
00728 XReparentWindow(tqt_xdisplay(), window, tqt_xrootwin(), 0, 0);
00729 if( !d->xplain )
00730 XRemoveFromSaveSet( tqt_xdisplay(), window );
00731 if( d->mapAfterRelease )
00732 XMapWindow( tqt_xdisplay(), window );
00733 XSync(tqt_xdisplay(), false);
00734
00735 if( autoDelete() )
00736
00737
00738
00739
00740 sendDelete();
00741 }
00742 window = 0;
00743
00744
00745 Window focus;
00746 int revert;
00747 XGetInputFocus( tqt_xdisplay(), &focus, &revert );
00748 if( focus == d->focusProxy->winId())
00749 XSetInputFocus( tqt_xdisplay(), topLevelWidget()->winId(), RevertToParent, GET_QT_X_TIME() );
00750
00751 delete d;
00752 }
00753
00754
00755
00756
00757
00758 void QXEmbed::sendDelete( void )
00759 {
00760 if (window)
00761 {
00762 sendClientMessage(window, tqt_wm_protocols, tqt_wm_delete_window);
00763 XFlush( tqt_xdisplay() );
00764 }
00765 }
00766
00767
00768
00769
00770
00771
00772
00773
00774 void QXEmbed::setProtocol( Protocol proto )
00775 {
00776 if (!window) {
00777 d->xplain = false;
00778 if (proto == XPLAIN)
00779 d->xplain = true;
00780 }
00781 }
00782
00783
00784 QXEmbed::Protocol QXEmbed::protocol()
00785 {
00786 if (d->xplain)
00787 return XPLAIN;
00788 return XEMBED;
00789 }
00790
00791
00792
00793 void QXEmbed::resizeEvent(TQResizeEvent*)
00794 {
00795 if (window)
00796 XResizeWindow(tqt_xdisplay(), window, width(), height());
00797 }
00798
00799
00800 void QXEmbed::showEvent(TQShowEvent*)
00801 {
00802 if (window)
00803 XMapRaised(tqt_xdisplay(), window);
00804 }
00805
00806
00807
00808 bool QXEmbed::eventFilter( TQObject *o, TQEvent * e)
00809 {
00810
00811 switch ( e->type() ) {
00812 case TQEvent::WindowActivate:
00813 if ( TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(topLevelWidget()) ) {
00814
00815
00816 if ( !((QPublicWidget*) topLevelWidget())->topData()->embedded )
00817 if (! hasFocus() )
00818 XSetInputFocus( tqt_xdisplay(), d->focusProxy->winId(),
00819 RevertToParent, GET_QT_X_TIME() );
00820 if (d->xplain)
00821
00822 checkGrab();
00823 else
00824
00825 sendXEmbedMessage( window, XEMBED_WINDOW_ACTIVATE );
00826 }
00827 break;
00828 case TQEvent::WindowDeactivate:
00829 if ( TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(topLevelWidget()) ) {
00830 if (d->xplain)
00831
00832 checkGrab();
00833 else
00834
00835 sendXEmbedMessage( window, XEMBED_WINDOW_DEACTIVATE );
00836 }
00837 break;
00838 case TQEvent::Move:
00839 {
00840 TQWidget* pos = this;
00841 while( TQT_BASE_OBJECT(pos) != TQT_BASE_OBJECT(o) && TQT_BASE_OBJECT(pos) != TQT_BASE_OBJECT(topLevelWidget()))
00842 pos = pos->parentWidget();
00843 if( TQT_BASE_OBJECT(pos) == TQT_BASE_OBJECT(o) ) {
00844
00845
00846 TQPoint globalPos = mapToGlobal(TQPoint(0,0));
00847 if (globalPos != d->lastPos) {
00848 d->lastPos = globalPos;
00849 sendSyntheticConfigureNotifyEvent();
00850 }
00851 }
00852 }
00853 break;
00854 default:
00855 break;
00856 }
00857 return false;
00858 }
00859
00860
00861 bool QXEmbed::event( TQEvent * e)
00862 {
00863 return TQWidget::event( e );
00864 }
00865
00866
00867
00868
00869
00870
00871
00872 void QXEmbed::keyPressEvent( TQKeyEvent *)
00873 {
00874 if (!window)
00875 return;
00876 last_key_event.window = window;
00877 XSendEvent(tqt_xdisplay(), window, false, KeyPressMask, (XEvent*)&last_key_event);
00878
00879 }
00880
00881
00882
00883 void QXEmbed::keyReleaseEvent( TQKeyEvent *)
00884 {
00885 if (!window)
00886 return;
00887 last_key_event.window = window;
00888 XSendEvent(tqt_xdisplay(), window, false, KeyReleaseMask, (XEvent*)&last_key_event);
00889 }
00890
00891
00892 void QXEmbed::focusInEvent( TQFocusEvent * e ){
00893 if (!window)
00894 return;
00895
00896
00897 if ( !((QPublicWidget*) topLevelWidget())->topData()->embedded )
00898 if ( tqApp->activeWindow() == topLevelWidget() )
00899
00900
00901
00902 XSetInputFocus( tqt_xdisplay(), d->focusProxy->winId(),
00903 RevertToParent, GET_QT_X_TIME() );
00904 if (d->xplain) {
00905
00906 checkGrab();
00907
00908
00909
00910 sendFocusMessage(window, XFocusIn, NotifyNormal, NotifyPointer );
00911 } else {
00912
00913
00914 int detail = XEMBED_FOCUS_CURRENT;
00915
00916
00917
00918 if ( e->reason() == TQFocusEvent::Tab )
00919 detail = XEMBED_FOCUS_FIRST;
00920 else if ( e->reason() == TQFocusEvent::Backtab )
00921 detail = XEMBED_FOCUS_LAST;
00922 sendXEmbedMessage( window, XEMBED_FOCUS_IN, detail);
00923 }
00924 }
00925
00926
00927 void QXEmbed::focusOutEvent( TQFocusEvent * ){
00928 if (!window)
00929 return;
00930 if (d->xplain) {
00931
00932 checkGrab();
00933
00934 sendFocusMessage(window, XFocusOut, NotifyNormal, NotifyPointer );
00935 } else {
00936
00937 sendXEmbedMessage( window, XEMBED_FOCUS_OUT );
00938 }
00939
00940
00941
00942
00943
00944
00945
00946 if ( !((QPublicWidget*) topLevelWidget())->topData()->embedded )
00947 if ( tqApp->activeWindow() == topLevelWidget() )
00948
00949
00950
00951
00952 XSetInputFocus( tqt_xdisplay(), d->focusProxy->winId(),
00953 RevertToParent, GET_QT_X_TIME() );
00954 }
00955
00956
00957
00958
00959 void QXEmbed::updateEmbeddedFocus( bool hasfocus ){
00960 if (!window || d->xplain)
00961 return;
00962 if( hasfocus )
00963 sendXEmbedMessage( window, XEMBED_FOCUS_IN, XEMBED_FOCUS_CURRENT);
00964 else
00965 sendXEmbedMessage( window, XEMBED_FOCUS_OUT);
00966 }
00967
00968
00969
00970 static bool wstate_withdrawn( WId winid )
00971 {
00972 Atom type;
00973 int format;
00974 unsigned long length, after;
00975 unsigned char *data;
00976 int r = XGetWindowProperty( tqt_xdisplay(), winid, tqt_wm_state, 0, 2,
00977 false, AnyPropertyType, &type, &format,
00978 &length, &after, &data );
00979 bool withdrawn = true;
00980
00981
00982 if ( r == Success && data && format == 32 ) {
00983 TQ_UINT32 *wstate = (TQ_UINT32*)data;
00984 withdrawn = (*wstate == WithdrawnState );
00985 XFree( (char *)data );
00986 }
00987 return withdrawn;
00988 }
00989
00990
00991
00992 static int get_parent(WId winid, Window *out_parent)
00993 {
00994 Window root, *children=0;
00995 unsigned int nchildren;
00996 int st = XQueryTree(tqt_xdisplay(), winid, &root, out_parent, &children, &nchildren);
00997 if (st && children)
00998 XFree(children);
00999 return st;
01000 }
01001
01002
01003
01004 void QXEmbed::embed(WId w)
01005 {
01006 kdDebug() << "*** Embed " << w << " into " << winId() << ". window=" << window << endl;
01007 if (!w)
01008 return;
01009
01010
01011 bool has_window = (w == window);
01012 window = w;
01013 if ( !has_window ) {
01014 KXErrorHandler errhandler;
01015
01016
01017
01018 if ( !wstate_withdrawn(window) ) {
01019 XWithdrawWindow(tqt_xdisplay(), window, tqt_xscreen());
01020 TQApplication::flushX();
01021
01022 for (int i=0; i < 10000; ++i) {
01023 if (wstate_withdrawn(window)) {
01024 Window parent = 0;
01025 get_parent(w, &parent);
01026 if (parent == tqt_xrootwin()) break;
01027 }
01028 USLEEP(1000);
01029 }
01030 }
01031
01032
01033
01034
01035 Window parent = 0;
01036 get_parent(w, &parent);
01037 kdDebug() << TQString(TQString("> before reparent: parent=0x%1").arg(parent,0,16)) << endl;
01038 for (int i = 0; i < 50; i++) {
01039
01040
01041 if( !d->xplain )
01042 XAddToSaveSet( tqt_xdisplay(), w );
01043 XReparentWindow(tqt_xdisplay(), w, winId(), 0, 0);
01044 if (get_parent(w, &parent) && parent == winId()) {
01045 kdDebug() << TQString(TQString("> Loop %1: ").arg(i))
01046 << TQString(TQString("> reparent of 0x%1").arg(w,0,16))
01047 << TQString(TQString(" into 0x%1").arg(winId(),0,16))
01048 << TQString(" successful") << endl;
01049 break;
01050 }
01051 kdDebug() << TQString(TQString("> Loop %1: ").arg(i))
01052 << TQString(TQString("> reparent of 0x%1").arg(w,0,16))
01053 << TQString(TQString(" into 0x%1").arg(winId(),0,16))
01054 << TQString(" failed") << endl;
01055 USLEEP(1000);
01056 }
01057 if( parent != winId())
01058 window = 0;
01059 }
01060 }
01061
01062
01063
01064 void QXEmbed::handleEmbed()
01065 {
01066
01067
01068 if( !d->xplain )
01069 XAddToSaveSet( tqt_xdisplay(), window );
01070 XResizeWindow(tqt_xdisplay(), window, width(), height());
01071 XMapRaised(tqt_xdisplay(), window);
01072
01073 sendSyntheticConfigureNotifyEvent();
01074
01075 extraData()->xDndProxy = window;
01076 if ( parent() ) {
01077
01078
01079 TQEvent * layoutHint = new TQEvent( TQEvent::LayoutHint );
01080 TQApplication::postEvent( parent(), layoutHint );
01081 }
01082 windowChanged( window );
01083 if (d->xplain) {
01084
01085 checkGrab();
01086 if ( hasFocus() )
01087
01088 sendFocusMessage(window, XFocusIn, NotifyNormal, NotifyPointer );
01089 } else {
01090
01091 sendXEmbedMessage( window, XEMBED_EMBEDDED_NOTIFY, 0, (long) winId() );
01092 if (isActiveWindow())
01093 sendXEmbedMessage( window, XEMBED_WINDOW_ACTIVATE);
01094 else
01095 sendXEmbedMessage( window, XEMBED_WINDOW_DEACTIVATE);
01096 if ( hasFocus() )
01097 sendXEmbedMessage( window, XEMBED_FOCUS_IN, XEMBED_FOCUS_CURRENT );
01098 }
01099 }
01100
01101
01102 WId QXEmbed::embeddedWinId() const
01103 {
01104 return window;
01105 }
01106
01107
01108
01109
01110 bool QXEmbed::focusNextPrevChild( bool next )
01111 {
01112 if ( window )
01113
01114
01115
01116
01117
01118
01119 return false;
01120 else
01121
01122 return TQWidget::focusNextPrevChild( next );
01123 }
01124
01125
01126
01127 bool QXEmbed::x11Event( XEvent* e)
01128 {
01129 switch ( e->type ) {
01130 case DestroyNotify:
01131 if ( e->xdestroywindow.window == window ) {
01132
01133 window = 0;
01134 windowChanged( window );
01135 emit embeddedWindowDestroyed();
01136 }
01137 break;
01138 case CreateNotify:
01139
01140 if( window == 0 ) {
01141 window = e->xcreatewindow.window;
01142 handleEmbed();
01143 }
01144 break;
01145 case ReparentNotify:
01146 if ( e->xreparent.window == d->focusProxy->winId() )
01147 break;
01148 if ( window && e->xreparent.window == window &&
01149 e->xreparent.parent != winId() ) {
01150
01151 window = 0;
01152 windowChanged( window );
01153 emit embeddedWindowDestroyed();
01154
01155
01156
01157 if( !d->xplain )
01158 XRemoveFromSaveSet( tqt_xdisplay(), window );
01159 } else if ( e->xreparent.parent == winId()){
01160 if( window == 0 )
01161 window = e->xreparent.window;
01162
01163 if( e->xreparent.window == window )
01164 handleEmbed();
01165 }
01166 break;
01167 case ButtonPress:
01168 if (d->xplain && d->xgrab) {
01169
01170
01171 #ifdef USE_QT4
01172 setFocus();
01173 #else // USE_QT4
01174 TQFocusEvent::setReason( TQFocusEvent::Mouse );
01175 setFocus();
01176 TQFocusEvent::resetReason();
01177 #endif // USE_QT4
01178
01179 XAllowEvents(tqt_xdisplay(), ReplayPointer, CurrentTime);
01180
01181 return true;
01182 }
01183 break;
01184 case ButtonRelease:
01185 if (d->xplain && d->xgrab) {
01186
01187 XAllowEvents(tqt_xdisplay(), SyncPointer, CurrentTime);
01188 return true;
01189 }
01190 break;
01191 case MapRequest:
01192
01193 if ( window && e->xmaprequest.window == window )
01194 XMapRaised(tqt_xdisplay(), window );
01195 break;
01196 case ClientMessage:
01197
01198
01199 if ( e->xclient.format == 32 && e->xclient.message_type == xembed ) {
01200 long message = e->xclient.data.l[1];
01201 switch ( message ) {
01202
01203
01204
01205 case XEMBED_FOCUS_NEXT:
01206 TQWidget::focusNextPrevChild( true );
01207 break;
01208 case XEMBED_FOCUS_PREV:
01209 TQWidget::focusNextPrevChild( false );
01210 break;
01211
01212 case XEMBED_REQUEST_FOCUS:
01213 if( ((QPublicWidget*)topLevelWidget())->topData()->embedded ) {
01214 focusMap->remove( topLevelWidget() );
01215 focusMap->insert( topLevelWidget(), new TQGuardedPtr<TQWidget>( this ));
01216 #ifdef USE_QT4
01217 WId window = ((QPublicWidget*)topLevelWidget())->effectiveWinId();
01218 #else // USE_QT4
01219 WId window = ((QPublicWidget*)topLevelWidget())->topData()->parentWinId;
01220 #endif // USE_QT4
01221 sendXEmbedMessage( window, XEMBED_REQUEST_FOCUS );
01222 } else {
01223 #ifdef USE_QT4
01224 setFocus();
01225 #else // USE_QT4
01226 TQFocusEvent::setReason( TQFocusEvent::Mouse );
01227 setFocus();
01228 TQFocusEvent::resetReason();
01229 #endif // USE_QT4
01230 }
01231 break;
01232 default:
01233 break;
01234 }
01235 }
01236 break;
01237
01238 case ConfigureRequest:
01239
01240
01241 if (e->xconfigurerequest.window == window)
01242 {
01243 sendSyntheticConfigureNotifyEvent();
01244 }
01245 break;
01246 case MotionNotify:
01247
01248 case EnterNotify:
01249
01250 if ( TQWhatsThis::inWhatsThisMode() )
01251 enterWhatsThisMode();
01252 break;
01253 default:
01254 break;
01255 }
01256 return false;
01257 }
01258
01259
01260
01261
01262 void QXEmbed::enterWhatsThisMode()
01263 {
01264
01265
01266
01267
01268 TQWhatsThis::leaveWhatsThisMode();
01269 if ( !context_help )
01270 context_help = XInternAtom( x11Display(), "_NET_WM_CONTEXT_HELP", false );
01271 sendClientMessage(window , tqt_wm_protocols, context_help );
01272 }
01273
01274
01275
01276 void QXEmbed::windowChanged( WId )
01277 {
01278 }
01279
01280
01281
01282
01283 bool QXEmbed::processClientCmdline( TQWidget* client, int& argc, char ** argv )
01284 {
01285 int myargc = argc;
01286 WId window = 0;
01287 int i, j;
01288
01289 j = 1;
01290 for ( i=1; i<myargc; i++ ) {
01291 if ( argv[i] && *argv[i] != '-' ) {
01292 argv[j++] = argv[i];
01293 continue;
01294 }
01295 TQCString arg = argv[i];
01296 if ( !strcmp(arg,"-embed") && i < myargc-1 ) {
01297 TQCString s = argv[++i];
01298 window = s.toInt();
01299 } else
01300 argv[j++] = argv[i];
01301 }
01302 argc = j;
01303
01304 if ( window ) {
01305 embedClientIntoWindow( client, window );
01306 return true;
01307 }
01308
01309 return false;
01310 }
01311
01312
01313
01314
01315 void QXEmbed::embedClientIntoWindow(TQWidget* client, WId window)
01316 {
01317 initialize();
01318 XReparentWindow(tqt_xdisplay(), client->winId(), window, 0, 0);
01319
01320 ((QXEmbed*)client)->topData()->embedded = true;
01321 #ifdef USE_QT4
01322
01323 printf("[FIXME] WId not set in tdelibs/tdeui/qxembed.cpp\n");
01324 #else // USE_QT4
01325 ((QXEmbed*)client)->topData()->parentWinId = window;
01326 #endif // USE_QT4
01327
01328
01329 client->show();
01330 }
01331
01332
01333
01334
01335
01336 TQSizePolicy QXEmbed::sizePolicy() const
01337 {
01338 return TQSizePolicy( TQSizePolicy::Expanding, TQSizePolicy::Expanding );
01339 }
01340
01341
01342
01343 TQSize QXEmbed::sizeHint() const
01344 {
01345 return minimumSizeHint();
01346 }
01347
01348
01349 TQSize QXEmbed::minimumSizeHint() const
01350 {
01351 int minw = 0;
01352 int minh = 0;
01353 if ( window ) {
01354 XSizeHints size;
01355 long msize;
01356 if (XGetWMNormalHints(tqt_xdisplay(), window, &size, &msize)
01357 && ( size.flags & PMinSize) ) {
01358 minw = size.min_width;
01359 minh = size.min_height;
01360 }
01361 }
01362
01363 return TQSize( minw, minh );
01364 }
01365
01366
01367
01368 void QXEmbed::setAutoDelete( bool b)
01369 {
01370 d->autoDelete = b;
01371 }
01372
01373
01374 bool QXEmbed::autoDelete() const
01375 {
01376 return d->autoDelete;
01377 }
01378
01379
01380 bool QXEmbed::customWhatsThis() const
01381 {
01382 return true;
01383 }
01384
01385
01386
01387
01388
01389
01390 void QXEmbed::checkGrab()
01391 {
01392 if (d->xplain && isActiveWindow() && !hasFocus()) {
01393 if (! d->xgrab)
01394 XGrabButton(tqt_xdisplay(), AnyButton, AnyModifier, winId(),
01395 false, ButtonPressMask, GrabModeSync, GrabModeAsync,
01396 None, None );
01397 d->xgrab = true;
01398 } else {
01399 if (d->xgrab)
01400 XUngrabButton( tqt_xdisplay(), AnyButton, AnyModifier, winId() );
01401 d->xgrab = false;
01402 }
01403 }
01404
01405
01406
01407 void QXEmbed::sendSyntheticConfigureNotifyEvent()
01408 {
01409
01410
01411
01412 TQPoint globalPos = mapToGlobal(TQPoint(0,0));
01413 if (window) {
01414 #if 0
01415 XConfigureEvent c;
01416 memset(&c, 0, sizeof(c));
01417 c.type = ConfigureNotify;
01418 c.display = tqt_xdisplay();
01419 c.send_event = True;
01420 c.event = window;
01421 c.window = window;
01422 c.x = globalPos.x();
01423 c.y = globalPos.y();
01424 c.width = width();
01425 c.height = height();
01426 c.border_width = 0;
01427 c.above = None;
01428 c.override_redirect = 0;
01429 XSendEvent( tqt_xdisplay(), c.event, true, StructureNotifyMask, (XEvent*)&c );
01430 #endif
01431
01432 XSetWindowBorderWidth( tqt_xdisplay(), window, 1 );
01433 XSetWindowBorderWidth( tqt_xdisplay(), window, 0 );
01434 }
01435 }
01436
01437
01438 void QXEmbed::reparent( TQWidget * parent, WFlags f, const TQPoint & p, bool showIt )
01439 {
01440
01441
01442
01443
01444 Q_ASSERT( !window );
01445 TQWidget::reparent( parent, f, p, showIt );
01446 }
01447
01448
01449 #include "qxembed.moc"
01450 #endif // Q_WS_X11