[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