delay a few things on startup, such as setting the visibility mode, which ensures...
[personal-kdebase.git] / apps / nsplugins / viewer / pluginhost_xt.cpp
bloba7dcf483c78ca0e7da26339116534203f58b0524
1 /*
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"
27 #include <QX11Info>
28 #include <QVBoxLayout>
29 #include <QLabel>
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);
65 Arg args[7];
66 Cardinal nargs = 0;
67 XtSetArg(args[nargs], XtNwidth, width); nargs++;
68 XtSetArg(args[nargs], XtNheight, height); nargs++;
69 XtSetArg(args[nargs], XtNborderWidth, 0); nargs++;
71 String n, c;
72 XtGetApplicationNameAndClass(QX11Info::display(), &n, &c);
73 _toplevel = XtAppCreateShell("drawingArea", c, applicationShellWidgetClass,
74 QX11Info::display(), args, nargs);
76 //if (embed)
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
89 #if 0
90 /* this little trick seems to finish initializing the widget */
91 #if XlibSpecificationRelease >= 6
92 XtRegisterDrawable(QX11Info::display(), embedderid, _toplevel);
93 #else
94 _XtRegisterWindow(embedderid, _toplevel);
95 #endif
96 #endif
97 XtRealizeWidget(_form);
98 XtManageChild(_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()
114 if (_form) {
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);
121 _form = 0;
122 _toplevel = 0;
124 delete _outside;
127 void PluginHostXt::forwarder(Widget w, XtPointer cl_data, XEvent * event, Boolean * cont)
129 Q_UNUSED(w);
130 PluginHostXt *inst = (PluginHostXt*)cl_data;
131 *cont = True;
132 if (inst->_form == 0 || event->xkey.window == XtWindow(inst->_form))
133 return;
134 *cont = False;
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);
149 XFree(children);
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);
159 Arg args[7];
160 Cardinal nargs = 0;
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;