[rkward-cvs] SF.net SVN: rkward-code:[4682] branches/development_branches/ rkward_graphpics_device/rkward

tfry at users.sf.net tfry at users.sf.net
Wed Apr 10 12:00:54 UTC 2013


Revision: 4682
          http://sourceforge.net/p/rkward/code/4682
Author:   tfry
Date:     2013-04-10 12:00:54 +0000 (Wed, 10 Apr 2013)
Log Message:
-----------
Wrap RK device into the existing plot device wrapper window, and a few fixes.

Modified Paths:
--------------
    branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice.cpp
    branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice.h
    branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice_frontendtransmitter.cpp
    branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice_protocol_shared.h
    branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice_setup.cpp
    branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice_stubs.cpp
    branches/development_branches/rkward_graphpics_device/rkward/windows/rkwindowcatcher.cpp
    branches/development_branches/rkward_graphpics_device/rkward/windows/rkwindowcatcher.h
    branches/development_branches/rkward_graphpics_device/rkward/windows/rkworkplace.cpp
    branches/development_branches/rkward_graphpics_device/rkward/windows/rkworkplace.h

Modified: branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice.cpp
===================================================================
--- branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice.cpp	2013-04-07 22:39:28 UTC (rev 4681)
+++ branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice.cpp	2013-04-10 12:00:54 UTC (rev 4682)
@@ -43,6 +43,7 @@
 	if (antialias) painter.setRenderHints (QPainter::Antialiasing | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform);
 	view = new QLabel ();
 	view->installEventFilter (this);
+	connect (view, SIGNAL (destroyed(QObject*)), this, SLOT (viewKilled()));
 	connect (&updatetimer, SIGNAL (timeout ()), this, SLOT (updateNow ()));
 	updatetimer.setSingleShot (true);
 	clear ();
@@ -56,6 +57,12 @@
 	delete view;
 }
 
+void RKGraphicsDevice::viewKilled () {
+	RK_TRACE (GRAPHICS_DEVICE);
+	view = 0;
+	closeDevice (devices.key (this));
+}
+
 void RKGraphicsDevice::triggerUpdate () {
 	updatetimer.start (UPDATE_INTERVAL);
 }
@@ -102,7 +109,7 @@
 	RK_TRACE (GRAPHICS_DEVICE);
 
 	if (!painter.isActive ()) painter.begin (&area);
-	painter.setClipRect (new_clip);
+//	painter.setClipRect (new_clip);
 }
 
 void RKGraphicsDevice::circle (double x, double y, double r, const QPen& pen, const QBrush& brush) {
@@ -280,8 +287,10 @@
 		dialog->deleteLater ();
 		dialog = 0;
 	}
-	view->setCursor (Qt::ArrowCursor);
-	view->setToolTip (QString ());
+	if (view) {	// might already be destroyed
+		view->setCursor (Qt::ArrowCursor);
+		view->setToolTip (QString ());
+	}
 	interaction_opcode = -1;
 }
 

Modified: branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice.h
===================================================================
--- branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice.h	2013-04-07 22:39:28 UTC (rev 4681)
+++ branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice.h	2013-04-10 12:00:54 UTC (rev 4682)
@@ -54,6 +54,8 @@
 	void triggerUpdate ();
 	void locator ();
 	void confirmNewPage ();
+
+ 	QWidget* viewPort () const { return view; };
 public slots:
 	void stopInteraction ();
 signals:
@@ -63,6 +65,7 @@
 private slots:
 	void updateNow ();
 	void newPageDialogDone (int result);
+	void viewKilled ();
 private:
 	bool eventFilter (QObject *watched, QEvent *event);
 

Modified: branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice_frontendtransmitter.cpp
===================================================================
--- branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice_frontendtransmitter.cpp	2013-04-07 22:39:28 UTC (rev 4681)
+++ branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice_frontendtransmitter.cpp	2013-04-10 12:00:54 UTC (rev 4682)
@@ -28,6 +28,7 @@
 // *IF* the RKWard Graphics Device works out as hoped, the single process variant can finally be ditched for good.
 #define RKWARD_SPLIT_PROCESS 1
 #include "../rkfrontendtransmitter.h"
+#include "../../windows/rkworkplace.h"
 #include "rkgraphicsdevice.h"
 #include "../../version.h"
 
@@ -179,6 +180,7 @@
 			bool antialias;
 			streamer.instream >> width >> height >> title >> antialias;
 			device = RKGraphicsDevice::newDevice (devnum, width, height, title, antialias);
+			RKWorkplace::mainWorkplace ()->newRKWardGraphisWindow (device, devnum+1);
 			connect (device, SIGNAL (locatorDone(bool,double,double)), this, SLOT (locatorDone(bool,double,double)));
 			connect (device, SIGNAL (newPageConfirmDone(bool)), this, SLOT (newPageConfirmDone(bool)));
 			connect (this, SIGNAL (stopInteraction()), device, SLOT (stopInteraction()));

Modified: branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice_protocol_shared.h
===================================================================
--- branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice_protocol_shared.h	2013-04-07 22:39:28 UTC (rev 4681)
+++ branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice_protocol_shared.h	2013-04-10 12:00:54 UTC (rev 4682)
@@ -128,7 +128,7 @@
  * processing from instream. */
 	bool readInBuffer () {
 		if (!expected_read_size) {
-			if (device->bytesAvailable () < sizeof (quint32)) {
+			if (device->bytesAvailable () < (unsigned int) sizeof (quint32)) {
 				return false;
 			} else {
 				auxbuffer = device->read (sizeof (quint32));

Modified: branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice_setup.cpp
===================================================================
--- branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice_setup.cpp	2013-04-07 22:39:28 UTC (rev 4681)
+++ branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice_setup.cpp	2013-04-10 12:00:54 UTC (rev 4682)
@@ -144,11 +144,13 @@
 	dev->wantSymbolUTF8 = TRUE;
 	dev->useRotatedTextInContour = TRUE;
 
+#if R_VERSION >= R_Version (2, 14, 0)
 	dev->haveTransparency = 2;
 	dev->haveTransparentBg = 2; // FIXME. Do we really? Check.
 	dev->haveRaster = 2;
 	dev->haveCapture = 2;
 	dev->haveLocator = 2;
+#endif
 
 	/*
 	* Mouse events

Modified: branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice_stubs.cpp
===================================================================
--- branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice_stubs.cpp	2013-04-07 22:39:28 UTC (rev 4681)
+++ branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice_stubs.cpp	2013-04-10 12:00:54 UTC (rev 4682)
@@ -30,7 +30,15 @@
 #define RKD_IN_STREAM RKGraphicsDeviceBackendTransmitter::streamer.instream
 #define RKD_OUT_STREAM RKGraphicsDeviceBackendTransmitter::streamer.outstream
 
-/** This class is essentially like QMutexLocker. In addition, the constructor waits until the next chunk of the transmission is ready (and does event processing) */
+/** This class is essentially like QMutexLocker. In addition, the constructor waits until the next chunk of the transmission is ready (and does event processing).
+ *
+ * @note: Never ever call Rf_error(), or any R function that might fail during the lifetime of an RKGraphicsDataStreamReadGuard or
+ * RKGraphicsDataStreamWriteGuard. If R decides to long-jump out, the d'tor will not be called, the mutex will be left locked, and
+ * the next graphics operation will hang, with no way to interrupt.
+ * 
+ * At the same time, note that the RKGraphicsDataStreamReadGuard c'tor @em may cause R to long-jump (safely) in case of a user interrupt,
+ * or if the connection was killed. Don't rely on the code following the creation of an RKGraphicsDataStreamReadGuard to be called.
+ */
 class RKGraphicsDataStreamReadGuard {
 public:
 	RKGraphicsDataStreamReadGuard () {
@@ -290,13 +298,14 @@
 	RKGraphicsDataStreamWriteGuard wguard;
 	WRITE_HEADER (RKDRaster, dev);
 
+	int *_raster = reinterpret_cast<int*> (raster);	// shut up warning in WRITE_COLOR_BYTES. It's just four separete bytes, anyway
 	quint32 _w = qMin (w, 1 << 15);	// skip stuff exceeding reasonable limits to keep protocol simple
 	RKD_OUT_STREAM << _w;
 	quint32 _h = qMin (h, 1 << 15);
 	RKD_OUT_STREAM << _h;
 	for (quint32 col = 0; col < _h; ++col) {
 		for (quint32 row = 0; row < _w; ++row) {
-			WRITE_COLOR_BYTES (raster[(col*_w) + row]);
+			WRITE_COLOR_BYTES (_raster[(col*_w) + row]);
 		}
 	}
 	RKD_OUT_STREAM << QRectF (x, y, width, height) << rot << (bool) interpolate;
@@ -316,7 +325,7 @@
 		quint8 r, g, b, a;
 		RKD_IN_STREAM >> w >> h;
 		size = w*h;
- 		buffer = new int[size];// Although unlikely, allocVector below could fail. We don't want to be left with a locked mutex (from the rguard) in this case. (Being left with a dead pointer looks bening in comparison)
+ 		buffer = new int[size];// Although unlikely, allocVector below could fail. We don't want to be left with a locked mutex (from the rguard) in this case. (Being left with a dead pointer looks benign in comparison; Note that the vector may easily be too large for allocation on the stack)
 		quint32 i = 0;
 		for (quint32 col = 0; col < h; ++col) {
 			for (quint32 row = 0; row < w; ++row) {

Modified: branches/development_branches/rkward_graphpics_device/rkward/windows/rkwindowcatcher.cpp
===================================================================
--- branches/development_branches/rkward_graphpics_device/rkward/windows/rkwindowcatcher.cpp	2013-04-07 22:39:28 UTC (rev 4681)
+++ branches/development_branches/rkward_graphpics_device/rkward/windows/rkwindowcatcher.cpp	2013-04-10 12:00:54 UTC (rev 4682)
@@ -131,6 +131,7 @@
 
 #include "../rkglobals.h"
 #include "../rbackend/rinterface.h"
+#include "../rbackend/rkwarddevice/rkgraphicsdevice.h"
 #include "../core/robject.h"
 #include "../misc/rkprogresscontrol.h"
 #include "../misc/rksaveobjectchooser.h"
@@ -142,34 +143,9 @@
 RKCaughtX11Window::RKCaughtX11Window (WId window_to_embed, int device_number) : RKMDIWindow (0, X11Window), RCommandReceiver () {
 	RK_TRACE (MISC);
 
-	capture = 0;
-	killed_in_r = false;
 	embedded = window_to_embed;
-	RKCaughtX11Window::device_number = device_number;
-	RK_ASSERT (!device_windows.contains (device_number));
-	device_windows.insert (device_number, this);
+	commonInit (device_number);
 
-	error_dialog = new RKProgressControl (0, i18n ("An error occurred"), i18n ("An error occurred"), RKProgressControl::DetailedError);
-	setPart (new RKCaughtX11WindowPart (this));
-	setMetaInfo (i18n ("Graphics Device Window"), "rkward://page/rkward_plot_history", RKSettings::PageX11);
-	initializeActivationSignals ();
-	setFocusPolicy (Qt::ClickFocus);
-	updateHistoryActions (0, 0, QStringList ());
-
-	status_popup = new KPassivePopup (this);
-	status_popup->setTimeout (0);
-	disconnect (status_popup, SIGNAL (clicked()), status_popup, SLOT (hide()));	// no auto-hiding, please
-
-	QVBoxLayout *layout = new QVBoxLayout (this);
-	layout->setContentsMargins (0, 0, 0, 0);
-	box_widget = new KVBox (this);
-	layout->addWidget (box_widget);
-	scroll_widget = new QScrollArea (this);
-	scroll_widget->hide ();
-	layout->addWidget (scroll_widget);
-
-	xembed_container = new KVBox (box_widget);	// QX11EmbedContainer can not be reparented (between the box_widget, and the scroll_widget) directly. Therefore we place it into a container, and reparent that instead
-
 #ifdef Q_WS_WIN
 	// unfortunately, trying to get KWindowInfo as below hangs on windows (KDElibs 4.2.3)
 	WINDOWINFO wininfo;
@@ -192,14 +168,55 @@
 	setGeometry (wininfo.geometry ());	// it's important to set a size, even while not visible. Else DetachedWindowContainer will assign a default size of 640*480, and then size upwards, if necessary.
 	setCaption (wininfo.name ());
 #endif
-	dynamic_size = false;
-	dynamic_size_action->setChecked (false);
 
 	// somehow in Qt 4.4.3, when the RKCaughtWindow is reparented the first time, the QX11EmbedContainer may kill its client. Hence we delay the actual embedding until after the window was shown.
 	// In some previous version of Qt, this was not an issue, but I did not track the versions.
 	QTimer::singleShot (0, this, SLOT (doEmbed()));
 }
 
+RKCaughtX11Window::RKCaughtX11Window (RKGraphicsDevice* rkward_device, int device_number) : RKMDIWindow (0, X11Window) {
+	RK_TRACE (MISC);
+
+	commonInit (device_number);
+	rk_native_device_view = rkward_device->viewPort ();
+	rk_native_device_view->setParent (xembed_container);
+}
+
+void RKCaughtX11Window::commonInit (int device_number) {
+	RK_TRACE (MISC);
+
+	capture = 0;
+	killed_in_r = false;
+	RKCaughtX11Window::device_number = device_number;
+	RK_ASSERT (!device_windows.contains (device_number));
+	device_windows.insert (device_number, this);
+
+	error_dialog = new RKProgressControl (0, i18n ("An error occurred"), i18n ("An error occurred"), RKProgressControl::DetailedError);
+	setPart (new RKCaughtX11WindowPart (this));
+	setMetaInfo (i18n ("Graphics Device Window"), "rkward://page/rkward_plot_history", RKSettings::PageX11);
+	initializeActivationSignals ();
+	setFocusPolicy (Qt::ClickFocus);
+	updateHistoryActions (0, 0, QStringList ());
+
+	status_popup = new KPassivePopup (this);
+	status_popup->setTimeout (0);
+	disconnect (status_popup, SIGNAL (clicked()), status_popup, SLOT (hide()));	// no auto-hiding, please
+
+	QVBoxLayout *layout = new QVBoxLayout (this);
+	layout->setContentsMargins (0, 0, 0, 0);
+	box_widget = new KVBox (this);
+	layout->addWidget (box_widget);
+	scroll_widget = new QScrollArea (this);
+	scroll_widget->hide ();
+	layout->addWidget (scroll_widget);
+
+	xembed_container = new KVBox (box_widget);	// QX11EmbedContainer can not be reparented (between the box_widget, and the scroll_widget) directly. Therefore we place it into a container, and reparent that instead.
+	// Also, this makes it easier to handle the various different devices
+
+	dynamic_size = false;
+	dynamic_size_action->setChecked (false);
+}
+
 void RKCaughtX11Window::doEmbed () {
 	RK_TRACE (MISC);
 

Modified: branches/development_branches/rkward_graphpics_device/rkward/windows/rkwindowcatcher.h
===================================================================
--- branches/development_branches/rkward_graphpics_device/rkward/windows/rkwindowcatcher.h	2013-04-07 22:39:28 UTC (rev 4681)
+++ branches/development_branches/rkward_graphpics_device/rkward/windows/rkwindowcatcher.h	2013-04-10 12:00:54 UTC (rev 4682)
@@ -2,7 +2,7 @@
                           rwindowcatcher.h  -  description
                              -------------------
     begin                : Wed May 4 2005
-    copyright            : (C) 2005, 2006, 2009, 2010, 2011, 2012 by Thomas Friedrichsmeier
+    copyright            : (C) 2005-2013 by Thomas Friedrichsmeier
     email                : tfry at users.sourceforge.net
  ***************************************************************************/
 
@@ -95,8 +95,10 @@
 class QX11EmbedContainer;
 class QWinHost;
 class KPassivePopup;
+class RKGraphicsDevice;
 
-/** An R X11 device window managed by rkward. */
+/** An R onscreen graphics device window managed by rkward. Currently, this can be X11 devices (on X11), Windows devices (on Windows), and
+ RK devices (anywhere). */
 class RKCaughtX11Window : public RKMDIWindow, public RCommandReceiver {
 	Q_OBJECT
 public:
@@ -104,6 +106,7 @@
 @param window_to_embed the Window id of the R X11 device window to embed
 @param device_number the device number corresponding to that window */
 	RKCaughtX11Window (WId window_to_embed, int device_number);
+	RKCaughtX11Window (RKGraphicsDevice *rkward_device, int device_number);
 /** dtor */
 	~RKCaughtX11Window ();
 /** TODO? */
@@ -158,6 +161,7 @@
 private slots:
 	void doEmbed ();
 private:
+	void commonInit (int device_number);
 	void reEmbed ();
 	void rCommandDone (RCommand *command);
 	friend class RKCaughtX11WindowPart;	// needs access to the actions
@@ -178,6 +182,7 @@
 	// a dummy to make things compile for now
 	QWidget *capture;
 #endif
+	QWidget *rk_native_device_view;
 
 	bool dynamic_size;
 	KToggleAction *dynamic_size_action;

Modified: branches/development_branches/rkward_graphpics_device/rkward/windows/rkworkplace.cpp
===================================================================
--- branches/development_branches/rkward_graphpics_device/rkward/windows/rkworkplace.cpp	2013-04-07 22:39:28 UTC (rev 4681)
+++ branches/development_branches/rkward_graphpics_device/rkward/windows/rkworkplace.cpp	2013-04-10 12:00:54 UTC (rev 4682)
@@ -352,6 +352,14 @@
 	addWindow (window, false);
 }
 
+void RKWorkplace::newRKWardGraphisWindow (RKGraphicsDevice* dev, int device_number) {
+	RK_TRACE (APP);
+
+	RKCaughtX11Window *window = new RKCaughtX11Window (dev, device_number);
+	window->state = RKMDIWindow::Detached;
+	addWindow (window, false);
+}
+
 void RKWorkplace::newObjectViewer (RObject *object) {
 	RK_TRACE (APP);
 	RK_ASSERT (object);

Modified: branches/development_branches/rkward_graphpics_device/rkward/windows/rkworkplace.h
===================================================================
--- branches/development_branches/rkward_graphpics_device/rkward/windows/rkworkplace.h	2013-04-07 22:39:28 UTC (rev 4681)
+++ branches/development_branches/rkward_graphpics_device/rkward/windows/rkworkplace.h	2013-04-10 12:00:54 UTC (rev 4682)
@@ -2,7 +2,7 @@
                           rkworkplace  -  description
                              -------------------
     begin                : Thu Sep 21 2006
-    copyright            : (C) 2006, 2007, 2009, 2010, 2011, 2012 by Thomas Friedrichsmeier
+    copyright            : (C) 2006-2013 by Thomas Friedrichsmeier
     email                : tfry at users.sourceforge.net
  ***************************************************************************/
 
@@ -36,6 +36,7 @@
 class KAction;
 class RKToolWindowBar;
 class RKMDIWindowHistoryWidget;
+class RKGraphicsDevice;
 
 #define TOOL_WINDOW_BAR_COUNT 4
 
@@ -111,6 +112,7 @@
 	RKMDIWindow* openOutputWindow (const KUrl &url=KUrl ());
 
 	void newX11Window (WId window_to_embed, int device_number);
+	void newRKWardGraphisWindow (RKGraphicsDevice *dev, int device_number);
 	void newObjectViewer (RObject *object);
 
 /** @returns true if there is a known editor for this type of object, false otherwise */





More information about the rkward-tracker mailing list