3 Xt plugin embedding support
5 Copyright (c) 2000 Matthias Hoelzer-Kluepfel <hoelzer@kde.org>
6 Stefan Schimanski <1Stein@gmx.de>
7 2003-2005 George Staikos <staikos@kde.org>
8 2007 Maksim orlovich <maksim@kde.org>
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26 #include "pluginhost_xt.h"
28 #include <QVBoxLayout>
31 // BEGIN Workaround for QX11EmbedWidget silliness --- it maps widgets by default
32 // Most of the code is from Qt 4.3.3, Copyright (C) 1992-2007 Trolltech ASA
33 static unsigned int XEMBED_VERSION
= 0;
34 static Atom _XEMBED_INFO
= None
;
35 static void initXEmbedAtoms(Display
*d
)
37 if (_XEMBED_INFO
== None
)
38 _XEMBED_INFO
= XInternAtom(d
, "_XEMBED_INFO", false);
41 static void doNotAskForXEmbedMapping(QX11EmbedWidget
* widget
)
43 initXEmbedAtoms(widget
->x11Info().display());
44 unsigned int data
[] = {XEMBED_VERSION
, 0 /* e.g. not XEMBED_MAPPED*/};
45 XChangeProperty(widget
->x11Info().display(), widget
->winId(), _XEMBED_INFO
,
46 _XEMBED_INFO
, 32, PropModeReplace
,
47 (unsigned char*) data
, 2);
50 // END Workaround for QX11EmbedWidget silliness.
53 PluginHostXt::PluginHostXt(NSPluginInstance
* plugin
):
54 _plugin(plugin
), _outside(0), _toplevel(0), _form(0)
59 void PluginHostXt::setupWindow(int winId
, int width
, int height
)
61 _outside
= new QX11EmbedWidget();
62 doNotAskForXEmbedMapping(_outside
);
63 _outside
->embedInto(winId
);
67 XtSetArg(args
[nargs
], XtNwidth
, width
); nargs
++;
68 XtSetArg(args
[nargs
], XtNheight
, height
); nargs
++;
69 XtSetArg(args
[nargs
], XtNborderWidth
, 0); nargs
++;
72 XtGetApplicationNameAndClass(QX11Info::display(), &n
, &c
);
73 _toplevel
= XtAppCreateShell("drawingArea", c
, applicationShellWidgetClass
,
74 QX11Info::display(), args
, nargs
);
77 XtSetMappedWhenManaged(_toplevel
, False
);
78 XtRealizeWidget(_toplevel
);
80 // Create form window that is searched for by flash plugin
81 _form
= XtVaCreateWidget("form", compositeWidgetClass
, _toplevel
, NULL
);
82 XtSetArg(args
[nargs
], XtNvisual
, QX11Info::appVisual()); nargs
++;
83 XtSetArg(args
[nargs
], XtNdepth
, QX11Info::appDepth()); nargs
++;
84 XtSetArg(args
[nargs
], XtNcolormap
, QX11Info::appColormap()); nargs
++;
85 XtSetValues(_form
, args
, nargs
);
86 XSync(QX11Info::display(), false);
88 // From mozilla - not sure if it's needed yet, nor what to use for embedder
90 /* this little trick seems to finish initializing the widget */
91 #if XlibSpecificationRelease >= 6
92 XtRegisterDrawable(QX11Info::display(), embedderid
, _toplevel
);
94 _XtRegisterWindow(embedderid
, _toplevel
);
97 XtRealizeWidget(_form
);
100 // Register forwarder
101 XtAddEventHandler(_toplevel
, (KeyPressMask
|KeyReleaseMask
),
102 False
, forwarder
, (XtPointer
)this );
103 XtAddEventHandler(_form
, (KeyPressMask
|KeyReleaseMask
),
104 False
, forwarder
, (XtPointer
)this );
106 // Embed the Xt widget into the Qt widget
107 XReparentWindow(QX11Info::display(), XtWindow(_toplevel
), _outside
->winId(), 0, 0);
108 XtMapWidget(_toplevel
);
109 setupPluginWindow(_plugin
, (void*) XtWindow(_form
), width
, height
);
112 PluginHostXt::~PluginHostXt()
115 XtRemoveEventHandler(_form
, (KeyPressMask
|KeyReleaseMask
),
116 False
, forwarder
, (XtPointer
)this);
117 XtRemoveEventHandler(_toplevel
, (KeyPressMask
|KeyReleaseMask
),
118 False
, forwarder
, (XtPointer
)this);
119 XtDestroyWidget(_form
);
120 XtDestroyWidget(_toplevel
);
127 void PluginHostXt::forwarder(Widget w
, XtPointer cl_data
, XEvent
* event
, Boolean
* cont
)
130 PluginHostXt
*inst
= (PluginHostXt
*)cl_data
;
132 if (inst
->_form
== 0 || event
->xkey
.window
== XtWindow(inst
->_form
))
135 event
->xkey
.window
= XtWindow(inst
->_form
);
136 event
->xkey
.subwindow
= None
;
137 XtDispatchEvent(event
);
141 static void resizeWidgets(Window w
, int width
, int height
) {
142 Window rroot
, parent
, *children
;
143 unsigned int nchildren
= 0;
145 if (XQueryTree(QX11Info::display(), w
, &rroot
, &parent
, &children
, &nchildren
)) {
146 for (unsigned int i
= 0; i
< nchildren
; i
++) {
147 XResizeWindow(QX11Info::display(), children
[i
], width
, height
);
153 void PluginHostXt::resizePlugin(int /*pluginWinId*/, int w
, int h
)
155 kDebug(1431) << w
<< h
;
156 XResizeWindow(QX11Info::display(), XtWindow(_form
), w
, h
);
157 XResizeWindow(QX11Info::display(), XtWindow(_toplevel
), w
, h
);
161 XtSetArg(args
[nargs
], XtNwidth
, w
); nargs
++;
162 XtSetArg(args
[nargs
], XtNheight
, h
); nargs
++;
163 XtSetArg(args
[nargs
], XtNvisual
, QX11Info::appVisual()); nargs
++;
164 XtSetArg(args
[nargs
], XtNdepth
, QX11Info::appDepth()); nargs
++;
165 XtSetArg(args
[nargs
], XtNcolormap
, QX11Info::appColormap()); nargs
++;
166 XtSetArg(args
[nargs
], XtNborderWidth
, 0); nargs
++;
168 XtSetValues(_form
, args
, nargs
);
170 resizeWidgets(XtWindow(_form
), w
, h
);
173 // kate: indent-width 4; replace-tabs on; tab-width 4; space-indent on;