/**************************************************************************** Implementation of QXEmbed class Copyright (C) 1999-2000 Troll Tech AS This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *****************************************************************************/ #include "javaembed.h" #include #include #include #include struct KJavaEmbedPrivate { }; QString getQtEventName( QEvent* e ) { QString s; switch( e->type() ) { case QEvent::None: s = "None"; break; case QEvent::Timer: s = "Timer"; break; case QEvent::MouseButtonPress: s = "MouseButtonPress"; break; case QEvent::MouseButtonRelease: s = "MouseButtonRelease"; break; case QEvent::MouseButtonDblClick: s = "MouseButtonClick"; break; case QEvent::MouseMove: s = "MouseMove"; break; case QEvent::KeyPress: s = "KeyPress"; break; case QEvent::KeyRelease: s = "KeyRelease"; break; case QEvent::FocusIn: s = "FocusIn"; break; case QEvent::FocusOut: s = "FocusOut"; break; case QEvent::Enter: s = "Enter"; break; case QEvent::Leave: s = "Leave"; break; case QEvent::Paint: s = "Paint"; break; case QEvent::Move: s = "Move"; break; case QEvent::Resize: s = "Resize"; break; case QEvent::Create: s = "Create"; break; case QEvent::Destroy: s = "Destroy"; break; case QEvent::Show: s = "Show"; break; case QEvent::Hide: s = "Hide"; break; case QEvent::Close: s = "Close"; break; case QEvent::Quit: s = "Quit"; break; case QEvent::Reparent: s = "Reparent"; break; case QEvent::ShowMinimized: s = "ShowMinimized"; break; case QEvent::ShowNormal: s = "ShowNormal"; break; case QEvent::WindowActivate: s = "WindowActivate"; break; case QEvent::WindowDeactivate: s = "WindowDeactivate"; break; case QEvent::ShowToParent: s = "ShowToParent"; break; case QEvent::HideToParent: s = "HideToParent"; break; case QEvent::ShowMaximized: s = "ShowMaximized"; break; case QEvent::Accel: s = "Accel"; break; case QEvent::Wheel: s = "Wheel"; break; case QEvent::AccelAvailable: s = "AccelAvailable"; break; case QEvent::CaptionChange: s = "CaptionChange"; break; case QEvent::IconChange: s = "IconChange"; break; case QEvent::ParentFontChange: s = "ParentFontChange"; break; case QEvent::ApplicationFontChange: s = "ApplicationFontChange"; break; case QEvent::ParentPaletteChange: s = "ParentPaletteChange"; break; case QEvent::ApplicationPaletteChange: s = "ApplicationPaletteChange"; break; case QEvent::Clipboard: s = "Clipboard"; break; case QEvent::Speech: s = "Speech"; break; case QEvent::SockAct: s = "SockAct"; break; case QEvent::AccelOverride: s = "AccelOverride"; break; case QEvent::DragEnter: s = "DragEnter"; break; case QEvent::DragMove: s = "DragMove"; break; case QEvent::DragLeave: s = "DragLeave"; break; case QEvent::Drop: s = "Drop"; break; case QEvent::DragResponse: s = "DragResponse"; break; case QEvent::ChildInserted: s = "ChildInserted"; break; case QEvent::ChildRemoved: s = "ChildRemoved"; break; case QEvent::LayoutHint: s = "LayoutHint"; break; case QEvent::ShowWindowRequest: s = "ShowWindowRequest"; break; case QEvent::ActivateControl: s = "ActivateControl"; break; case QEvent::DeactivateControl: s = "DeactivateControl"; break; case QEvent::User: s = "User Event"; break; default: s = "Undefined Event, value = " + QString::number( e->type() ); break; } return s; } /*!\reimp */ bool KJavaEmbed::eventFilter( QObject* o, QEvent* e) { QEvent::Type t = e->type(); if( t != QEvent::MouseMove && t != QEvent::Timer && t <= QEvent::User ) { kdDebug(6100) << "KJavaEmbed::eventFilter, event = " << getQtEventName( e ) << endl; if( o == this ) kdDebug(6100) << "event is for me:)" << endl; switch ( e->type() ) { case QEvent::FocusIn: break; case QEvent::FocusOut: break; case QEvent::Leave: /* check to see if we are entering the applet somehow... */ break; case QEvent::Enter: break; case QEvent::WindowActivate: break; case QEvent::WindowDeactivate: break; default: break; } } return FALSE; } #include #include #include #include QString getX11EventName( XEvent* e ) { QString s; switch( e->type ) { case KeyPress: s = "KeyPress"; break; case KeyRelease: s = "KeyRelease"; break; case ButtonPress: s = "ButtonPress"; break; case ButtonRelease: s = "ButtonRelease"; break; case MotionNotify: s = "MotionNotify"; break; case EnterNotify: s = "EnterNotify"; break; case LeaveNotify: s = "LeaveNotify"; break; case FocusIn: s = "FocusIn"; break; case FocusOut: s = "FocusOut"; break; case KeymapNotify: s = "KeymapNotify"; break; case Expose: s = "Expose"; break; case GraphicsExpose: s = "GraphicsExpose"; break; case NoExpose: s = "NoExpose"; break; case VisibilityNotify: s = "VisibilityNotify"; break; case CreateNotify: s = "CreateNotify"; break; case DestroyNotify: s = "DestroyNotify"; break; case UnmapNotify: s = "UnmapNotify"; break; case MapNotify: s = "MapNotify"; break; case MapRequest: s = "MapRequest"; break; case ReparentNotify: s = "ReparentNotify"; break; case ConfigureNotify: s = "ConfigureNotify"; break; case ConfigureRequest: s = "ConfigureRequest"; break; case GravityNotify: s = "GravityNotify"; break; case ResizeRequest: s = "ResizeRequest"; break; case CirculateNotify: s = "CirculateNofify"; break; case CirculateRequest: s = "CirculateRequest"; break; case PropertyNotify: s = "PropertyNotify"; break; case SelectionClear: s = "SelectionClear"; break; case SelectionRequest: s = "SelectionRequest"; break; case SelectionNotify: s = "SelectionNotify"; break; case ColormapNotify: s = "ColormapNotify"; break; case ClientMessage: s = "ClientMessage"; break; case MappingNotify: s = "MappingNotify"; break; case LASTEvent: s = "LASTEvent"; break; default: s = "Undefined"; break; } return s; } /*! Constructs a xembed widget. The \e parent, \e name and \e f arguments are passed to the QFrame constructor. */ KJavaEmbed::KJavaEmbed( QWidget *parent, const char *name, WFlags f ) : QWidget( parent, name, f ) { d = new KJavaEmbedPrivate; setFocusPolicy( StrongFocus ); setKeyCompression( FALSE ); setAcceptDrops( TRUE ); window = 0; } /*! Destructor. Cleans up the focus if necessary. */ KJavaEmbed::~KJavaEmbed() { if ( window != 0 ) { XUnmapWindow( qt_xdisplay(), window ); QApplication::flushX(); } delete d; } /*!\reimp */ void KJavaEmbed::resizeEvent( QResizeEvent* e ) { // kdDebug(6100) << "KJavaEmbed::resizeEvent" << endl; QWidget::resizeEvent( e ); if ( window != 0 ) XResizeWindow( qt_xdisplay(), window, e->size().width(), e->size().height() ); } bool KJavaEmbed::event( QEvent* e) { // kdDebug(6100) << "KJavaEmbed::event, event type = " << getQtEventName( e ) << endl; switch( e->type() ) { case QEvent::ShowWindowRequest: XMapRaised( qt_xdisplay(), window ); break; default: break; } return QWidget::event( e ); } /*!\reimp */ void KJavaEmbed::focusInEvent( QFocusEvent* ) { // kdDebug(6100) << "KJavaEmbed::focusInEvent" << endl; if ( !window ) return; XEvent ev; memset( &ev, 0, sizeof( ev ) ); ev.xfocus.type = FocusIn; ev.xfocus.window = window; XSendEvent( qt_xdisplay(), window, true, NoEventMask, &ev ); } /*!\reimp */ void KJavaEmbed::focusOutEvent( QFocusEvent* ) { // kdDebug(6100) << "KJavaEmbed::focusOutEvent" << endl; if ( !window ) return; XEvent ev; memset( &ev, 0, sizeof( ev ) ); ev.xfocus.type = FocusOut; ev.xfocus.window = window; XSendEvent( qt_xdisplay(), window, true, NoEventMask, &ev ); } /*! Embeds the window with the identifier \a w into this xembed widget. This function is useful if the server knows about the client window that should be embedded. Often it is vice versa: the client knows about its target embedder. In that case, it is not necessary to call embed(). Instead, the client will call the static function embedClientIntoWindow(). \sa embeddedWinId() */ void KJavaEmbed::embed( WId w ) { // kdDebug(6100) << "KJavaEmbed::embed" << endl; if ( w == 0 ) return; window = w; //first withdraw the window XWithdrawWindow( qt_xdisplay(), window, qt_xscreen() ); QApplication::flushX(); //make sure we will receive destroy notifications for the embedded window. XWindowAttributes xwattr; XGetWindowAttributes(qt_xdisplay(), winId(), &xwattr); XSelectInput(qt_xdisplay(), winId(), SubstructureNotifyMask | xwattr.your_event_mask); //now reparent the window to be swallowed by the KJavaEmbed widget XReparentWindow( qt_xdisplay(), window, winId(), 0, 0 ); //and add it to the save set in case this window gets destroyed before XAddToSaveSet(qt_xdisplay(), window); QApplication::syncX(); //now resize it XResizeWindow( qt_xdisplay(), window, width(), height() ); XMapRaised( qt_xdisplay(), window ); setFocus(); } /*!\reimp */ bool KJavaEmbed::focusNextPrevChild( bool next ) { if ( window ) return FALSE; else return QWidget::focusNextPrevChild( next ); } /*!\reimp */ bool KJavaEmbed::x11Event( XEvent* e) { // kdDebug(6100) << "KJavaEmbed::x11Event, event = " << getX11EventName( e ) // << ", window = " << e->xany.window << endl; switch ( e->type ) { case DestroyNotify: if ( e->xdestroywindow.window == window ) { window = 0; } break; case LeaveNotify: break; case FocusOut: break; case EnterNotify: break; case FocusIn: break; default: break; } return false; } /*! Specifies that this widget can use additional space, and that it can survive on less than sizeHint(). */ QSizePolicy KJavaEmbed::sizePolicy() const { return QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ); } /*! Returns a size sufficient for the embedded window */ QSize KJavaEmbed::sizeHint() const { return minimumSizeHint(); } /*! Returns the minimum size specified by the embedded window. */ QSize KJavaEmbed::minimumSizeHint() const { int minw = 0; int minh = 0; if ( window ) { kdDebug(6100) << "KJavaEmbed::minimumSizeHint, getting hints from window" << endl; XSizeHints size; long msize; if( XGetWMNormalHints( qt_xdisplay(), window, &size, &msize ) && ( size.flags & PMinSize) ) { minw = size.min_width; minh = size.min_height; kdDebug(6100) << "XGetWMNormalHints succeeded, minw = " << minw << ", minh = " << minh << endl; } } return QSize( minw, minh ); } // for KDE #include "javaembed.moc"