Dear R developers,
I've been experimenting with embedding R X11 windows into another
application
using KDE's QXEmbed on linux. Attempting to do so will crash R (with R
2.4.0,
trunk, and I know the bug has been around in prior versions). I used to think
this was related to bug #848, but I'm not sure, if / how the solution
suggested there still applies to current versions of R.
After debugging, I came up with the following patch (in src/modules/X11):
Index: devX11.c
==================================================================--- devX11.c
(revision 39818)
+++ devX11.c (working copy)
@@ -586,8 +586,8 @@
if (event.xany.type == Expose) {
while(XCheckTypedEvent(display, Expose, &event))
;
- XFindContext(display, event.xexpose.window,
- devPtrContext, &temp);
+ if (XFindContext(display, event.xexpose.window,
+ devPtrContext, &temp)) return;
dd = (NewDevDesc *) temp;
if (event.xexpose.count == 0)
do_update = 1;
@@ -595,8 +595,8 @@
else if (event.type == ConfigureNotify) {
while(XCheckTypedEvent(display, ConfigureNotify, &event))
;
- XFindContext(display, event.xconfigure.window,
- devPtrContext, &temp);
+ if (XFindContext(display, event.xconfigure.window,
+ devPtrContext, &temp)) return;
dd = (NewDevDesc *) temp;
xd = (newX11Desc *) dd->deviceSpecific;
if (xd->windowWidth != event.xconfigure.width ||
@@ -614,8 +614,8 @@
else if ((event.type == ClientMessage) &&
(event.xclient.message_type == _XA_WM_PROTOCOLS))
if (!inclose && event.xclient.data.l[0] == protocol) {
- XFindContext(display, event.xclient.window,
- devPtrContext, &temp);
+ if (XFindContext(display, event.xclient.window,
+ devPtrContext, &temp)) return;
dd = (NewDevDesc *) temp;
KillDevice((DevDesc*) GetDevice(devNumber((DevDesc*) dd)));
}
I'll have to admit, that I'm mostly clueless as far as X11-programming
is
concerned, so the patch may not be entirely correct. It does fix the crash,
however, and should be along the right lines. The rationale is, that
apparently calls to XFindContext() may fail in the context of embedding the
X11 window. The patch simply checks the return value of XFindContext() for a
non-zero (i.e. error) value, and in that case drops out of the function.
Does this seem like a valid fix? Should I provide more info?
Regards
Thomas Friedrichsmeier
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
Url :
https://stat.ethz.ch/pipermail/r-devel/attachments/20061107/acb0b680/attachment.bin
Dear R developers, On Tuesday 07 November 2006 15:26, Thomas Friedrichsmeier wrote:> Does this seem like a valid fix? Should I provide more info?I'll take no answer to mean "We'd like to see a test case". You'll find one attached. Instructions on compilation / usage are given at the top of the source file. Embedding an R X11 window will crash the corresponding R process (tested with R 2.4.0, and R devel), while other applications can be embedded just fine, this way. Refer to my last mail for a patch and explanation. In case the attachment does not get through (I hope I've chosen a good MIME-type this time, though), it is also available at: http://rkward.sourceforge.net/temp/embed.cpp Regards Thomas Friedrichsmeier -------------- next part -------------- /*************************************************************************** embed.cpp - description ------------------- Simple test case to embed the first X 11 Window found with a title starting with the given string using QXEmbed under KDE. Compilation: Here these lines will compile the test case: # moc embed.cpp > embed.moc # gcc -I /usr/include/qt3/ -I /usr/include/kde/ -lqt-mt -lkdeui embed.cpp -o embed Obviously, you may have to adjust the paths Usage: 1) In an R console, create an X11 device 2) Run this program, click "Capture" ***************************************************************************/ #include <kapplication.h> #include <kcmdlineargs.h> #include <kaboutdata.h> #include <kmainwindow.h> #include <qxembed.h> #include <qstring.h> #include <qdialog.h> #include <qpushbutton.h> #include <qlineedit.h> #include <qlayout.h> #include <qlabel.h> #include <X11/X.h> #include <X11/Xlib.h> // function below is a slightly adapted copy from http://lists.trolltech.com/qt-interest/1999-10/msg00224.html // this could be tweaked a little more, since for instance we know we're only looking for toplevel windows Window Window_With_Name (Display *dp, Window top, const QString &name) { Window *children, dummy; unsigned int nchildren; int i; Window w=0; char *window_name; if (XFetchName (dp, top, &window_name)) { if (QString (window_name).startsWith (name)) return (top); } if (!XQueryTree (dp, top, &dummy, &dummy, &children, &nchildren)) return (0); for (i=0; i<nchildren; i++) { w = Window_With_Name (dp, children[i], name); if (w) break; } if (children) XFree ((char *) children); return (w); } class EmbedDialog : public KMainWindow { Q_OBJECT public: EmbedDialog () : KMainWindow (0) { // create the window QVBoxLayout *layout = new QVBoxLayout (this); QLabel *label = new QLabel ("Enter start of title of window to capture:", this); layout->addWidget (label); caption_edit = new QLineEdit (this); caption_edit->setText ("R Graphics"); layout->addWidget (caption_edit); QPushButton *button = new QPushButton ("Capture", this); connect (button, SIGNAL (clicked ()), this, SLOT (embedRGraphics ())); layout->addWidget (button); show (); }; public slots: void embedRGraphics () { Window w = Window_With_Name (qt_xdisplay (), qApp->desktop ()->winId (), caption_edit->text ()); if (!w) { qDebug ("No such window found"); return; } else { qDebug ("embedding window id %p", w); } // capture QXEmbed *capture = new QXEmbed (0, 0, Qt::WDestructiveClose); capture->setProtocol (QXEmbed::XPLAIN); capture->embed (w); capture->show (); qDebug ("done embedding", w); }; private: QLineEdit *caption_edit; }; static KCmdLineOptions options[] = { { 0, 0, 0 } }; int main (int argc, char *argv[]) { KAboutData aboutdata ("embedtest", "embedtest", "0.1", "a test case", KAboutData::License_GPL, "(c) 2006", 0); KCmdLineArgs::init (argc, argv, &aboutdata); KApplication app; new EmbedDialog (); return app.exec (); } #include "embed.moc" -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: not available Url : https://stat.ethz.ch/pipermail/r-devel/attachments/20061121/497d459a/attachment.bin
Dear R developers, On Tuesday 07 November 2006 15:26, Thomas Friedrichsmeier wrote:> I've been experimenting with embedding R X11 windows into another > application using KDE's QXEmbed on linux. Attempting to do so will crash R > (with R 2.4.0, trunk, and I know the bug has been around in prior > versions). I used to think this was related to bug #848, but I'm not sure, > if / how the solution suggested there still applies to current versions of > R. > > After debugging, I came up with the following patch (in src/modules/X11):shame on me. After further investigation, I found out, that indeed QXEmbed is to blame, not R (see http://lists.kde.org/?l=kde-devel&m=116448102901184&w=2). The fact that all other applications, I had tried to embed, did not crash, led me to believe otherwise for a long time. The patch, I suggested, probably would not do any harm, either way, but should not be strictly needed. Sorry about the noise. Regards Thomas Friedrichsmeier -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: not available Url : https://stat.ethz.ch/pipermail/r-devel/attachments/20061129/f8891348/attachment.bin