00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <qapplication.h>
00023 #include <qptrlist.h>
00024 #include <qptrdict.h>
00025 #include <qguardedptr.h>
00026 #include <qwhatsthis.h>
00027 #include <qfocusdata.h>
00028 #ifdef Q_WS_X11
00029 #include <X11/X.h>
00030 #include <X11/Xlib.h>
00031 #include <X11/Xutil.h>
00032 #include <X11/Xatom.h>
00033 #define XK_MISCELLANY
00034 #define XK_LATIN1
00035 #include <X11/keysymdef.h>
00036 #include <kdebug.h>
00037
00038
00039 #include <config.h>
00040
00041 #ifdef HAVE_UNISTD_H
00042 #include <unistd.h>
00043 #ifdef HAVE_USLEEP
00044 #define USLEEP(x) usleep(x)
00045 #else
00046 #define USLEEP(x) sleep(0)
00047 #endif // HAVE_USLEEP
00048 #else
00049 #define USLEEP(x) sleep(0)
00050 #endif // HAVE_UNISTD_H
00051
00052 #include "qxembed.h"
00053
00054 #ifndef XK_ISO_Left_Tab
00055 #define XK_ISO_Left_Tab 0xFE20
00056 #endif
00057 const int XFocusOut = FocusOut;
00058 const int XFocusIn = FocusIn;
00059 const int XKeyPress = KeyPress;
00060 const int XKeyRelease = KeyRelease;
00061 #undef KeyRelease
00062 #undef KeyPress
00063 #undef FocusOut
00064 #undef FocusIn
00065
00066
00067 extern Atom qt_wm_protocols;
00068 extern Atom qt_wm_delete_window;
00069 extern Atom qt_wm_take_focus;
00070 extern Time qt_x_time;
00071 extern Atom qt_wm_state;
00072
00073 static Atom xembed = 0;
00074 static Atom context_help = 0;
00075
00076
00077 #define XEMBED_EMBEDDED_NOTIFY 0
00078 #define XEMBED_WINDOW_ACTIVATE 1
00079 #define XEMBED_WINDOW_DEACTIVATE 2
00080 #define XEMBED_REQUEST_FOCUS 3
00081 #define XEMBED_FOCUS_IN 4
00082 #define XEMBED_FOCUS_OUT 5
00083 #define XEMBED_FOCUS_NEXT 6
00084 #define XEMBED_FOCUS_PREV 7
00085
00086
00087
00088
00089 #define XEMBED_FOCUS_CURRENT 0
00090 #define XEMBED_FOCUS_FIRST 1
00091 #define XEMBED_FOCUS_LAST 2
00092
00093
00094
00095 class QXEmbedData
00096 {
00097 public:
00098 QXEmbedData(){
00099 autoDelete = TRUE;
00100 lastPos = QPoint(0,0);
00101 }
00102 ~QXEmbedData(){};
00103
00104
00105 bool autoDelete;
00106 QWidget* focusProxy;
00107 QPoint lastPos;
00108
00109 };
00110
00111 class QXEmbedAppFilter : public QObject
00112 {
00113 public:
00114 QXEmbedAppFilter(){ qApp->installEventFilter( this ); }
00115 ~QXEmbedAppFilter(){};
00116 bool eventFilter( QObject *, QEvent * );
00117 };
00118
00119
00120 static QXEmbedAppFilter* filter = 0;
00121 static QPtrDict<QGuardedPtr<QWidget> > *focusMap = 0;
00122
00123 static XKeyEvent last_key_event;
00124 static bool tabForward = TRUE;
00125
00126
00127 class QPublicWidget : public QWidget
00128 {
00129 public:
00130 QTLWExtra* topData() { return QWidget::topData(); };
00131 QFocusData *focusData(){ return QWidget::focusData(); };
00132 };
00133
00134 typedef int (*QX11EventFilter) (XEvent*);
00135 extern QX11EventFilter qt_set_x11_event_filter (QX11EventFilter filter);
00136 static QX11EventFilter oldFilter = 0;
00137
00138
00139 static void send_xembed_message( WId window, long message, long detail = 0,
00140 long data1 = 0, long data2 = 0)
00141 {
00142 XEvent ev;
00143 memset(&ev, 0, sizeof(ev));
00144 ev.xclient.type = ClientMessage;
00145 ev.xclient.window = window;
00146 ev.xclient.message_type = xembed;
00147 ev.xclient.format = 32;
00148 ev.xclient.data.l[0] = qt_x_time;
00149 ev.xclient.data.l[1] = message;
00150 ev.xclient.data.l[2] = detail;
00151 ev.xclient.data.l[3] = data1;
00152 ev.xclient.data.l[4] = data2;
00153 XSendEvent(qt_xdisplay(), window, FALSE, NoEventMask, &ev);
00154 }
00155
00156 static void sendClientMessage(Window window, Atom a, long x){
00157 XEvent ev;
00158 memset(&ev, 0, sizeof(ev));
00159 ev.xclient.type = ClientMessage;
00160 ev.xclient.window = window;
00161 ev.xclient.message_type = a;
00162 ev.xclient.format = 32;
00163 ev.xclient.data.l[0] = x;
00164 ev.xclient.data.l[1] = qt_x_time;
00165 XSendEvent(qt_xdisplay(), window, FALSE, NoEventMask, &ev);
00166 }
00167
00168
00169 bool QXEmbedAppFilter::eventFilter( QObject *o, QEvent * e)
00170 {
00171 static bool obeyFocus = FALSE;
00172 switch ( e->type() ) {
00173 case QEvent::MouseButtonPress:
00174 if ( !((QWidget*)o)->isActiveWindow() )
00175 obeyFocus = TRUE;
00176 break;
00177 case QEvent::FocusIn:
00178 if ( qApp->focusWidget() == o &&
00179 ((QPublicWidget*)qApp->focusWidget()->topLevelWidget())->topData()->embedded ) {
00180 QFocusEvent* fe = (QFocusEvent*) e;
00181
00182 if ( obeyFocus || fe->reason() == QFocusEvent::Mouse ||
00183 fe->reason() == QFocusEvent::Shortcut ) {
00184 WId window = ((QPublicWidget*)qApp->focusWidget()->topLevelWidget())->topData()->parentWinId;
00185 focusMap->remove( qApp->focusWidget()->topLevelWidget() );
00186 send_xembed_message( window, XEMBED_REQUEST_FOCUS );
00187 } else if ( fe->reason() == QFocusEvent::ActiveWindow ) {
00188 focusMap->remove( qApp->focusWidget()->topLevelWidget() );
00189 focusMap->insert( qApp->focusWidget()->topLevelWidget(),
00190 new QGuardedPtr<QWidget>(qApp->focusWidget()->topLevelWidget()->focusWidget() ) );
00191 qApp->focusWidget()->clearFocus();
00192 }
00193 obeyFocus = FALSE;
00194 }
00195 break;
00196 default:
00197 break;
00198 }
00199 return FALSE;
00200 }
00201
00202
00203 static int qxembed_x11_event_filter( XEvent* e)
00204 {
00205
00206
00207 switch ( e->type ) {
00208 case XKeyPress: {
00209 int kc = XKeycodeToKeysym(qt_xdisplay(), e->xkey.keycode, 0);
00210 if ( kc == XK_Tab || kc == XK_ISO_Left_Tab ) {
00211 tabForward = (e->xkey.state & ShiftMask) == 0;
00212 QWidget* w = QWidget::find( e->xkey.window );
00213 if ( w && w->isActiveWindow() && qApp->focusWidget() &&
00214 qApp->focusWidget()->topLevelWidget() == w->topLevelWidget() &&
00215 ((QPublicWidget*)w->topLevelWidget())->topData()->embedded ) {
00216 WId window = ((QPublicWidget*)w->topLevelWidget())->topData()->parentWinId;
00217 QFocusData *fd = ((QPublicWidget*)w)->focusData();
00218 while ( fd->next() != w->topLevelWidget() )
00219 ;
00220 QWidget* first = fd->next();
00221 QWidget* last = fd->prev(); last = fd->prev();
00222 if ( !tabForward && fd->focusWidget() == first ) {
00223 send_xembed_message( window, XEMBED_FOCUS_PREV );
00224 return TRUE;
00225 } else if ( tabForward && fd->focusWidget() == last ) {
00226 send_xembed_message( window, XEMBED_FOCUS_NEXT );
00227 return TRUE;
00228 }
00229 }
00230 } else
00231 last_key_event = e->xkey;
00232 }
00233
00234 case XKeyRelease: {
00235 last_key_event = e->xkey;
00236 break;
00237 }
00238 case ClientMessage:
00239 if ( e->xclient.message_type == xembed ) {
00240 Time msgtime = (Time) e->xclient.data.l[0];
00241 long message = e->xclient.data.l[1];
00242 long detail = e->xclient.data.l[2];
00243 if ( msgtime > qt_x_time )
00244 qt_x_time = msgtime;
00245 QWidget* w = QWidget::find( e->xclient.window );
00246 if ( !w )
00247 break;
00248 switch ( message) {
00249 case XEMBED_EMBEDDED_NOTIFY:
00250 ((QPublicWidget*)w->topLevelWidget())->topData()->embedded = 1;
00251 w->topLevelWidget()->show();
00252 break;
00253 case XEMBED_WINDOW_ACTIVATE: {
00254
00255 XEvent ev;
00256 memset(&ev, 0, sizeof(ev));
00257 ev.xfocus.display = qt_xdisplay();
00258 ev.xfocus.type = XFocusIn;
00259 ev.xfocus.window = w->topLevelWidget()->winId();
00260 ev.xfocus.mode = NotifyNormal;
00261 ev.xfocus.detail = NotifyAncestor;
00262 qApp->x11ProcessEvent( &ev );
00263 }
00264 break;
00265 case XEMBED_WINDOW_DEACTIVATE: {
00266
00267 XEvent ev;
00268 memset(&ev, 0, sizeof(ev));
00269 ev.xfocus.display = qt_xdisplay();
00270 ev.xfocus.type = XFocusOut;
00271 ev.xfocus.window = w->topLevelWidget()->winId();
00272 ev.xfocus.mode = NotifyNormal;
00273 ev.xfocus.detail = NotifyAncestor;
00274 qApp->x11ProcessEvent( &ev );
00275 }
00276 break;
00277 case XEMBED_FOCUS_IN:
00278 {
00279 QWidget* focusCurrent = 0;
00280 QGuardedPtr<QWidget>* fw = focusMap->find( w->topLevelWidget() );
00281 if ( fw ) {
00282 focusCurrent = *fw;
00283 focusMap->remove( w->topLevelWidget() );
00284 }
00285 switch ( detail ) {
00286 case XEMBED_FOCUS_CURRENT:
00287 if ( focusCurrent )
00288 focusCurrent->setFocus();
00289 else if ( !w->topLevelWidget()->focusWidget() )
00290 w->topLevelWidget()->setFocus();
00291 break;
00292 case XEMBED_FOCUS_FIRST:
00293 {
00294 QFocusData *fd = ((QPublicWidget*)w)->focusData();
00295 while ( fd->next() != w->topLevelWidget() )
00296 ;
00297 QWidget* fw = fd->next();
00298 QFocusEvent::setReason( QFocusEvent::Tab );
00299 if ( w )
00300 fw->setFocus();
00301 else
00302 w->topLevelWidget()->setFocus();
00303 QFocusEvent::resetReason();
00304 }
00305 break;
00306 case XEMBED_FOCUS_LAST:
00307 {
00308 QFocusData *fd = ((QPublicWidget*)w)->focusData();
00309 while ( fd->next() != w->topLevelWidget() )
00310 ;
00311 QWidget* fw = fd->prev();
00312 QFocusEvent::setReason( QFocusEvent::Tab );
00313 if ( w )
00314 fw->setFocus();
00315 else
00316 w->topLevelWidget()->setFocus();
00317 QFocusEvent::resetReason();
00318 }
00319 break;
00320 default:
00321 break;
00322 }
00323 }
00324 break;
00325 case XEMBED_FOCUS_OUT:
00326 if ( w->topLevelWidget()->focusWidget() ) {
00327 focusMap->insert( w->topLevelWidget(),
00328 new QGuardedPtr<QWidget>(w->topLevelWidget()->focusWidget() ) );
00329 w->topLevelWidget()->focusWidget()->clearFocus();
00330 }
00331 break;
00332 default:
00333 break;
00334 }
00335 } else if ( e->xclient.format == 32 && e->xclient.message_type ) {
00336 if ( e->xclient.message_type == qt_wm_protocols ) {
00337 QWidget* w = QWidget::find( e->xclient.window );
00338 if ( !w )
00339 break;
00340 Atom a = e->xclient.data.l[0];
00341 if ( a == qt_wm_take_focus ) {
00342 if ( (ulong) e->xclient.data.l[1] > qt_x_time )
00343 qt_x_time = e->xclient.data.l[1];
00344 if ( w->isActiveWindow() ) {
00345
00346
00347
00348 QEvent e( QEvent::WindowActivate );
00349 QApplication::sendEvent( w, &e );
00350 }
00351 }
00352 }
00353 }
00354 break;
00355 default:
00356 break;
00357 }
00358
00359 if ( oldFilter )
00360 return oldFilter( e );
00361 return FALSE;
00362 }
00363
00372 void QXEmbed::initialize()
00373 {
00374 static bool is_initialized = FALSE;
00375 if ( is_initialized )
00376 return;
00377 xembed = XInternAtom( qt_xdisplay(), "_XEMBED", FALSE );
00378 oldFilter = qt_set_x11_event_filter( qxembed_x11_event_filter );
00379
00380 focusMap = new QPtrDict<QGuardedPtr<QWidget> >;
00381 focusMap->setAutoDelete( TRUE );
00382
00383 filter = new QXEmbedAppFilter;
00384
00385 is_initialized = TRUE;
00386 }
00387
00388
00427 QXEmbed::QXEmbed(QWidget *parent, const char *name, WFlags f)
00428 : QWidget(parent, name, f)
00429 {
00430 d = new QXEmbedData;
00431 d->focusProxy = new QWidget( this, "xembed_focus" );
00432 d->focusProxy->setGeometry( -1, -1, 1, 1 );
00433 initialize();
00434 window = 0;
00435 setFocusPolicy(StrongFocus);
00436 setKeyCompression( FALSE );
00437
00438
00439 (void) topData();
00440
00441
00442 XSelectInput(qt_xdisplay(), winId(),
00443 KeyPressMask | KeyReleaseMask |
00444 ButtonPressMask | ButtonReleaseMask |
00445 KeymapStateMask |
00446 ButtonMotionMask |
00447 PointerMotionMask |
00448 EnterWindowMask | LeaveWindowMask |
00449 FocusChangeMask |
00450 ExposureMask |
00451 StructureNotifyMask |
00452 SubstructureRedirectMask |
00453 SubstructureNotifyMask
00454 );
00455
00456 topLevelWidget()->installEventFilter( this );
00457 qApp->installEventFilter( this );
00458
00459 setAcceptDrops( TRUE );
00460 }
00461
00465 QXEmbed::~QXEmbed()
00466 {
00467
00468 if ( window != 0 ) {
00469 if ( autoDelete() )
00470 XUnmapWindow( qt_xdisplay(), window );
00471
00472 XReparentWindow(qt_xdisplay(), window, qt_xrootwin(), 0, 0);
00473 XSync(qt_xdisplay(), FALSE);
00474
00475 if ( autoDelete() ) {
00476 XEvent ev;
00477 memset(&ev, 0, sizeof(ev));
00478 ev.xclient.type = ClientMessage;
00479 ev.xclient.window = window;
00480 ev.xclient.message_type = qt_wm_protocols;
00481 ev.xclient.format = 32;
00482 ev.xclient.data.s[0] = qt_wm_delete_window;
00483 XSendEvent(qt_xdisplay(), window, FALSE, NoEventMask, &ev);
00484 }
00485 XFlush( qt_xdisplay() );
00486 }
00487 window = 0;
00488
00489 delete d;
00490 }
00491
00492
00495 void QXEmbed::resizeEvent(QResizeEvent*)
00496 {
00497 if (window != 0)
00498 XResizeWindow(qt_xdisplay(), window, width(), height());
00499 }
00500
00503 void QXEmbed::showEvent(QShowEvent*)
00504 {
00505 if (window != 0)
00506 XMapRaised(qt_xdisplay(), window);
00507
00508 }
00509
00510
00513 bool QXEmbed::eventFilter( QObject *o, QEvent * e)
00514 {
00515
00516 switch ( e->type() ) {
00517 case QEvent::WindowActivate:
00518 if ( o == topLevelWidget() ) {
00519 if ( !((QPublicWidget*) topLevelWidget())->topData()->embedded )
00520 XSetInputFocus( qt_xdisplay(), d->focusProxy->winId(), RevertToParent, qt_x_time );
00521 send_xembed_message( window, XEMBED_WINDOW_ACTIVATE );
00522 }
00523 break;
00524 case QEvent::WindowDeactivate:
00525 if ( o == topLevelWidget() )
00526 send_xembed_message( window, XEMBED_WINDOW_DEACTIVATE );
00527 break;
00528 case QEvent::Move:
00529 {
00530 QPoint globalPos = mapToGlobal(QPoint(0,0));
00531 if (globalPos != d->lastPos) {
00532 d->lastPos = globalPos;
00533 sendSyntheticConfigureNotifyEvent();
00534 }
00535 }
00536 break;
00537 default:
00538 break;
00539 }
00540 return FALSE;
00541 }
00542
00543
00544 bool QXEmbed::event( QEvent * e)
00545 {
00546 return QWidget::event( e );
00547 }
00548
00551 void QXEmbed::keyPressEvent( QKeyEvent *)
00552 {
00553 if (!window)
00554 return;
00555 last_key_event.window = window;
00556 XSendEvent(qt_xdisplay(), window, FALSE, NoEventMask, (XEvent*)&last_key_event);
00557
00558 }
00559
00562 void QXEmbed::keyReleaseEvent( QKeyEvent *)
00563 {
00564 if (!window)
00565 return;
00566 last_key_event.window = window;
00567 XSendEvent(qt_xdisplay(), window, FALSE, NoEventMask, (XEvent*)&last_key_event);
00568 }
00569
00572 void QXEmbed::focusInEvent( QFocusEvent * e ){
00573 if (!window)
00574 return;
00575 int detail = XEMBED_FOCUS_CURRENT;
00576 if ( e->reason() == QFocusEvent::Tab )
00577 detail = tabForward?XEMBED_FOCUS_FIRST:XEMBED_FOCUS_LAST;
00578 send_xembed_message( window, XEMBED_FOCUS_IN, detail);
00579 }
00580
00583 void QXEmbed::focusOutEvent( QFocusEvent * ){
00584 if (!window)
00585 return;
00586 send_xembed_message( window, XEMBED_FOCUS_OUT );
00587 }
00588
00589
00590
00591 static bool wstate_withdrawn( WId winid )
00592 {
00593 Atom type;
00594 int format;
00595 unsigned long length, after;
00596 unsigned char *data;
00597 int r = XGetWindowProperty( qt_xdisplay(), winid, qt_wm_state, 0, 2,
00598 FALSE, AnyPropertyType, &type, &format,
00599 &length, &after, &data );
00600 bool withdrawn = TRUE;
00601 if ( r == Success && data && format == 32 ) {
00602 Q_UINT32 *wstate = (Q_UINT32*)data;
00603 withdrawn = (*wstate == WithdrawnState );
00604 XFree( (char *)data );
00605 }
00606 return withdrawn;
00607 }
00608
00609 static int get_parent(WId winid, Window *out_parent)
00610 {
00611 Window root, *children=0;
00612 unsigned int nchildren;
00613 int st = XQueryTree(qt_xdisplay(), winid, &root, out_parent, &children, &nchildren);
00614 if (st) {
00615 if (children) {
00616 XFree(children);
00617 }
00618 return st;
00619 } else {
00620
00621 }
00622 return st;
00623 }
00624 #include <unistd.h>
00637 void QXEmbed::embed(WId w)
00638 {
00639 kdDebug() << "************************** Embed "<< QString("0x%1").arg(w, 0, 16) << " into " << QString("0x%1").arg(winId(), 0, 16) << " window=" << QString("0x%1").arg(window, 0, 16) << " **********" << endl;
00640 if (!w)
00641 return;
00642 XAddToSaveSet( qt_xdisplay(), w );
00643 bool has_window = w == window;
00644 window = w;
00645 if ( !has_window ) {
00646 if ( !wstate_withdrawn(window) ) {
00647 XWithdrawWindow(qt_xdisplay(), window, qt_xscreen());
00648 QApplication::flushX();
00649 while (!wstate_withdrawn(window))
00650 ;
00651 }
00652 Window parent;
00653 get_parent(w, &parent);
00654 kdDebug() << QString(">>> before reparent: parent=0x%1").arg(parent, 0, 16) << endl;
00655 for (int i = 0; i < 50; i++) {
00656 Window parent = 0;
00657 XReparentWindow(qt_xdisplay(), w, winId(), 0, 0);
00658 if (get_parent(w, &parent) && parent == winId()) {
00659 kdDebug() << QString(">>> Loop %1: reparent of 0x%2 into 0x%3 successful").arg(i).arg(w, 0, 16).arg(winId(), 0, 16) << endl;
00660 break;
00661 }
00662 kdDebug() << QString(">>> Loop %1: reparent of 0x%2 into 0x%3 failed").arg(i).arg(w, 0, 16).arg(winId(), 0, 16) << endl;
00663 USLEEP(1000);
00664 }
00665 QApplication::syncX();
00666 }
00667
00668 XResizeWindow(qt_xdisplay(), w, width(), height());
00669 XMapRaised(qt_xdisplay(), window);
00670 sendSyntheticConfigureNotifyEvent();
00671 extraData()->xDndProxy = w;
00672
00673 if ( parent() ) {
00674 QEvent * layoutHint = new QEvent( QEvent::LayoutHint );
00675 QApplication::postEvent( parent(), layoutHint );
00676 }
00677 windowChanged( window );
00678 send_xembed_message( window, XEMBED_EMBEDDED_NOTIFY, 0, (long) winId() );
00679 send_xembed_message( window, isActiveWindow() ? XEMBED_WINDOW_ACTIVATE : XEMBED_WINDOW_DEACTIVATE );
00680 if ( hasFocus() )
00681 send_xembed_message( window, XEMBED_FOCUS_IN );
00682 }
00683
00684
00689 WId QXEmbed::embeddedWinId() const
00690 {
00691 return window;
00692 }
00693
00694
00697 bool QXEmbed::focusNextPrevChild( bool next )
00698 {
00699 if ( window )
00700 return FALSE;
00701 else
00702 return QWidget::focusNextPrevChild( next );
00703 }
00704
00705
00708 bool QXEmbed::x11Event( XEvent* e)
00709 {
00710
00711 switch ( e->type ) {
00712 case DestroyNotify:
00713 if ( e->xdestroywindow.window == window ) {
00714 window = 0;
00715 windowChanged( window );
00716 emit embeddedWindowDestroyed();
00717 }
00718 break;
00719 case ReparentNotify:
00720 if ( e->xreparent.window == d->focusProxy->winId() )
00721 break;
00722 if ( window && e->xreparent.window == window &&
00723 e->xreparent.parent != winId() ) {
00724
00725 window = 0;
00726 windowChanged( window );
00727 } else if ( e->xreparent.parent == winId() ){
00728
00729 window = e->xreparent.window;
00730 embed( window );
00731 }
00732 break;
00733 case MapRequest:
00734 if ( window && e->xmaprequest.window == window )
00735 XMapRaised(qt_xdisplay(), window );
00736 break;
00737 case ClientMessage:
00738 if ( e->xclient.format == 32 && e->xclient.message_type == xembed ) {
00739 long message = e->xclient.data.l[1];
00740
00741 switch ( message ) {
00742 case XEMBED_FOCUS_NEXT:
00743 QWidget::focusNextPrevChild( TRUE );
00744 break;
00745 case XEMBED_FOCUS_PREV:
00746 QWidget::focusNextPrevChild( FALSE );
00747 break;
00748 case XEMBED_REQUEST_FOCUS:
00749 QFocusEvent::setReason( QFocusEvent::Mouse );
00750 setFocus();
00751 QFocusEvent::resetReason();
00752 break;
00753 default:
00754 break;
00755 }
00756 }
00757 break;
00758
00759 case ConfigureRequest:
00760 if (e->xconfigurerequest.window == window)
00761 {
00762 sendSyntheticConfigureNotifyEvent();
00763 }
00764 break;
00765 case MotionNotify:
00766
00767 case EnterNotify:
00768 if ( QWhatsThis::inWhatsThisMode() )
00769 enterWhatsThisMode();
00770 break;
00771 default:
00772 break;
00773 }
00774 return FALSE;
00775 }
00776
00777
00778 void QXEmbed::enterWhatsThisMode()
00779 {
00780 QWhatsThis::leaveWhatsThisMode();
00781 if ( !context_help )
00782 context_help = XInternAtom( x11Display(), "_NET_WM_CONTEXT_HELP", FALSE );
00783 sendClientMessage(window , qt_wm_protocols, context_help );
00784 }
00785
00786
00792 void QXEmbed::windowChanged( WId )
00793 {
00794 }
00795
00796
00807 bool QXEmbed::processClientCmdline( QWidget* client, int& argc, char ** argv )
00808 {
00809 int myargc = argc;
00810 WId window = 0;
00811 int i, j;
00812
00813 j = 1;
00814 for ( i=1; i<myargc; i++ ) {
00815 if ( argv[i] && *argv[i] != '-' ) {
00816 argv[j++] = argv[i];
00817 continue;
00818 }
00819 QCString arg = argv[i];
00820 if ( strcmp(arg,"-embed") == 0 && i < myargc-1 ) {
00821 QCString s = argv[++i];
00822 window = s.toInt();
00823 } else
00824 argv[j++] = argv[i];
00825 }
00826 argc = j;
00827
00828 if ( window != 0 ) {
00829 embedClientIntoWindow( client, window );
00830 return TRUE;
00831 }
00832
00833 return FALSE;
00834 }
00835
00836
00845 void QXEmbed::embedClientIntoWindow(QWidget* client, WId window)
00846 {
00847 initialize();
00848 XReparentWindow(qt_xdisplay(), client->winId(), window, 0, 0);
00849 ((QXEmbed*)client)->topData()->embedded = TRUE;
00850 ((QXEmbed*)client)->topData()->parentWinId = window;
00851 client->show();
00852 }
00853
00854
00855
00861 QSizePolicy QXEmbed::sizePolicy() const
00862 {
00863 return QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );
00864 }
00865
00866
00870 QSize QXEmbed::sizeHint() const
00871 {
00872 return minimumSizeHint();
00873 }
00874
00887 QSize QXEmbed::minimumSizeHint() const
00888 {
00889 int minw = 0;
00890 int minh = 0;
00891 if ( window ) {
00892 XSizeHints size;
00893 long msize;
00894 if (XGetWMNormalHints(qt_xdisplay(), window, &size, &msize)
00895 && ( size.flags & PMinSize) ) {
00896 minw = size.min_width;
00897 minh = size.min_height;
00898 }
00899 }
00900
00901 return QSize( minw, minh );
00902 }
00903
00904 void QXEmbed::setAutoDelete( bool b)
00905 {
00906 d->autoDelete = b;
00907 }
00908
00909 bool QXEmbed::autoDelete() const
00910 {
00911 return d->autoDelete;
00912 }
00913
00916 bool QXEmbed::customWhatsThis() const
00917 {
00918 return TRUE;
00919 }
00920
00921 void QXEmbed::sendSyntheticConfigureNotifyEvent() {
00922 QPoint globalPos = mapToGlobal(QPoint(0,0));
00923 if (window) {
00924
00925 XConfigureEvent c;
00926 memset(&c, 0, sizeof(c));
00927 c.type = ConfigureNotify;
00928 c.display = qt_xdisplay();
00929 c.send_event = True;
00930 c.event = window;
00931 c.window = winId();
00932 c.x = globalPos.x();
00933 c.y = globalPos.y();
00934 c.width = width();
00935 c.height = height();
00936 c.border_width = 0;
00937 c.above = None;
00938 c.override_redirect = 0;
00939 XSendEvent( qt_xdisplay(), c.event, TRUE, StructureNotifyMask, (XEvent*)&c );
00940
00941 }
00942 }
00943
00944
00945 #include "qxembed.moc"
00946 #endif