[rkward-cvs] SF.net SVN: rkward-code:[4687] trunk/rkward

tfry at users.sf.net tfry at users.sf.net
Thu Apr 11 11:57:26 UTC 2013


Revision: 4687
          http://sourceforge.net/p/rkward/code/4687
Author:   tfry
Date:     2013-04-11 11:57:23 +0000 (Thu, 11 Apr 2013)
Log Message:
-----------
Merge rkward_graphics_device-branch into trunk

Modified Paths:
--------------
    trunk/rkward/rkward/debug.h
    trunk/rkward/rkward/main.cpp
    trunk/rkward/rkward/rbackend/CMakeLists.txt
    trunk/rkward/rkward/rbackend/FindR.cmake
    trunk/rkward/rkward/rbackend/rkbackendtransmitter.h
    trunk/rkward/rkward/rbackend/rkfrontendtransmitter.cpp
    trunk/rkward/rkward/rbackend/rkfrontendtransmitter.h
    trunk/rkward/rkward/rbackend/rkrbackend.cpp
    trunk/rkward/rkward/rbackend/rkrbackendprotocol_backend.cpp
    trunk/rkward/rkward/rbackend/rkrbackendprotocol_backend.h
    trunk/rkward/rkward/rbackend/rktransmitter.h
    trunk/rkward/rkward/rbackend/rpackages/rkward/NAMESPACE
    trunk/rkward/rkward/rbackend/rpackages/rkward/R/internal_graphics.R
    trunk/rkward/rkward/rbackend/rpackages/rkward/R/public_graphics.R
    trunk/rkward/rkward/settings/rksettingsmoduledebug.cpp
    trunk/rkward/rkward/windows/rkwindowcatcher.cpp
    trunk/rkward/rkward/windows/rkwindowcatcher.h
    trunk/rkward/rkward/windows/rkworkplace.cpp
    trunk/rkward/rkward/windows/rkworkplace.h

Added Paths:
-----------
    trunk/rkward/rkward/rbackend/rkwarddevice/
    trunk/rkward/rkward/rbackend/rpackages/rkward/man/RKdevice.Rd

Property Changed:
----------------
    trunk/rkward/

Index: trunk/rkward
===================================================================
--- trunk/rkward	2013-04-11 11:41:17 UTC (rev 4686)
+++ trunk/rkward	2013-04-11 11:57:23 UTC (rev 4687)

Property changes on: trunk/rkward
___________________________________________________________________
Modified: svn:mergeinfo
## -1,4 +1,5 ##
 /branches/2010_10_18_backend_restructuring_branch:3130-3196
+/branches/development_branches/rkward_graphpics_device:4612-4686
 /branches/release_branch_0.5.4:3098-3102,3127
 /branches/release_branch_0.5.7:3913,3979-3980,3998
 /branches/release_branches/rkward_0.6.1:4649-4650
\ No newline at end of property
Modified: trunk/rkward/rkward/debug.h
===================================================================
--- trunk/rkward/rkward/debug.h	2013-04-11 11:41:17 UTC (rev 4686)
+++ trunk/rkward/rkward/debug.h	2013-04-11 11:57:23 UTC (rev 4687)
@@ -32,24 +32,25 @@
 
 // Debug components
 #define APP 1
-#define PLUGIN 2
-#define OBJECTS 4
-#define EDITOR 8
-#define SETTINGS 16
-#define PHP 64
-#define RBACKEND 128
-#define COMMANDEDITOR 256
-#define MISC 512
-#define DIALOGS 1024
-#define OUTPUT 2048
-#define XML 4096
-#define ALL (APP | PLUGIN | PHP | OBJECTS | EDITOR | RBACKEND | COMMANDEDITOR | MISC | DIALOGS | OUTPUT | XML)
+#define PLUGIN 1 << 1
+#define OBJECTS 1 << 2
+#define EDITOR 1 << 3
+#define SETTINGS 1 << 4
+#define PHP 1 << 5
+#define RBACKEND 1 << 6
+#define COMMANDEDITOR 1 << 7
+#define MISC 1 << 8
+#define DIALOGS 1 << 9
+#define OUTPUT 1 << 10
+#define XML 1 << 11
+#define GRAPHICS_DEVICE 1 << 12
+#define DEBUG_ALL (APP | PLUGIN | PHP | OBJECTS | EDITOR | RBACKEND | COMMANDEDITOR | MISC | DIALOGS | OUTPUT | XML | GRAPHICS_DEVICE)
 
 #ifdef RKWARD_DEBUG
 // Debug functions 
 #	define RK_DO(expr,flags,level) if ((flags & RK_Debug_Flags) && (level >= RK_Debug_Level)) { expr; }
 #	define RK_DEBUG(flags,level,...) { if ((flags & RK_Debug_Flags) && (level >= RK_Debug_Level)) RKDebug (flags,level,__VA_ARGS__); }
-#	define RK_ASSERT(x) if (!(x)) RK_DEBUG (ALL, DL_FATAL, "Assert '%s' failed at %s - function %s line %d", #x, __FILE__, __FUNCTION__, __LINE__);
+#	define RK_ASSERT(x) if (!(x)) RK_DEBUG (DEBUG_ALL, DL_FATAL, "Assert '%s' failed at %s - function %s line %d", #x, __FILE__, __FUNCTION__, __LINE__);
 #	ifndef RKWARD_NO_TRACE
 #		define RK_TRACE(flags) RK_DEBUG (flags, DL_TRACE, "Trace: %s - function %s line %d", __FILE__, __FUNCTION__, __LINE__);
 #	else

Modified: trunk/rkward/rkward/main.cpp
===================================================================
--- trunk/rkward/rkward/main.cpp	2013-04-11 11:41:17 UTC (rev 4686)
+++ trunk/rkward/rkward/main.cpp	2013-04-11 11:57:23 UTC (rev 4687)
@@ -79,7 +79,7 @@
 #include "version.h"
 
 int RK_Debug_Level = 0;
-int RK_Debug_Flags = ALL;
+int RK_Debug_Flags = DEBUG_ALL;
 int RK_Debug_CommandStep = 0;
 QMutex RK_Debug_Mutex;
 
@@ -114,7 +114,7 @@
 int main(int argc, char *argv[]) {
 	options.add ("evaluate <Rcode>", ki18n ("After starting (and after loading the specified workspace, if applicable), evaluate the given R code."), 0);
 	options.add ("debug-level <level>", ki18n ("Verbosity of debug messages (0-5)"), "2");
-	options.add ("debug-flags <flags>", ki18n ("Mask for components to debug (see debug.h)"), "8191");
+	options.add ("debug-flags <flags>", ki18n ("Mask for components to debug (see debug.h)"), QString::number (DEBUG_ALL).toLocal8Bit ());
 	options.add ("debugger <command>", ki18n ("Debugger (enclose any debugger arguments in single quotes ('') together with the command)"), "");
 	options.add ("backend-debugger <command>", ki18n ("Debugger for the backend. (Enclose any debugger arguments in single quotes ('') together with the command. Make sure to re-direct stdout!)"), "");
 	options.add ("+[File]", ki18n ("R workspace file to open"), 0);
@@ -155,7 +155,7 @@
 	RK_Debug_Level = DL_FATAL - QString (args->getOption ("debug-level")).toInt ();
 	RK_Debug_Flags = QString (args->getOption ("debug-flags")).toInt ();
 	if (!args->getOption ("debugger").isEmpty ()) {
-		RK_DEBUG (ALL, DL_ERROR, "--debugger option should have been handled by wrapper script. Ignoring.");
+		RK_DEBUG (DEBUG_ALL, DL_ERROR, "--debugger option should have been handled by wrapper script. Ignoring.");
 	}
 
 	if (args->count ()) {

Modified: trunk/rkward/rkward/rbackend/CMakeLists.txt
===================================================================
--- trunk/rkward/rkward/rbackend/CMakeLists.txt	2013-04-11 11:41:17 UTC (rev 4686)
+++ trunk/rkward/rkward/rbackend/CMakeLists.txt	2013-04-11 11:57:23 UTC (rev 4687)
@@ -5,6 +5,7 @@
 ENDIF(NOT WIN32)
 
 ADD_SUBDIRECTORY( rpackages )
+ADD_SUBDIRECTORY( rkwarddevice )
 
 INCLUDE_DIRECTORIES( ${R_INCLUDEDIR} ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} ${KDE4_INCLUDE_DIR} ${QT_INCLUDES}  )
 
@@ -46,7 +47,7 @@
 	)
 	QT4_AUTOMOC(${rbackend_FRONTEND_SRCS})
 	ADD_LIBRARY(rbackend STATIC ${rbackend_FRONTEND_SRCS})
-	TARGET_LINK_LIBRARIES(rbackend ${CMAKE_THREAD_LIBS_INIT})
+	TARGET_LINK_LIBRARIES(rbackend rkgraphicsdevice.frontend ${CMAKE_THREAD_LIBS_INIT})
 
 	SET (
 		rbackend_BACKEND_SRCS
@@ -60,7 +61,7 @@
 	LINK_DIRECTORIES(${R_SHAREDLIBDIR})
 	ADD_EXECUTABLE(rkward.rbackend ${rbackend_BACKEND_SRCS})
 	FIND_PACKAGE(Gettext REQUIRED)
-	TARGET_LINK_LIBRARIES(rkward.rbackend ${R_USED_LIBS} ${CMAKE_THREAD_LIBS_INIT} ${QT_QTNETWORK_LIBRARY} ${QT_QTCORE_LIBRARY} ${GETTEXT_LIBRARIES})
+	TARGET_LINK_LIBRARIES(rkward.rbackend rkgraphicsdevice.backend ${R_USED_LIBS} ${CMAKE_THREAD_LIBS_INIT} ${QT_QTNETWORK_LIBRARY} ${QT_QTCORE_LIBRARY} ${GETTEXT_LIBRARIES})
 
 	IF(WIN32)
 		# on Widows, we install to the rbackend subdirectory, because 1) LIBEXEC_INSTALL_DIR == BIN_INSTALL_DIR and 2) we don't want the backend to pick up
@@ -80,5 +81,5 @@
 	QT4_AUTOMOC(${rbackend_ALL_SRCS})
 	LINK_DIRECTORIES(${R_SHAREDLIBDIR})
 	ADD_LIBRARY(rbackend STATIC ${rbackend_ALL_SRCS})
-	TARGET_LINK_LIBRARIES(rbackend ${R_USED_LIBS} ${CMAKE_THREAD_LIBS_INIT})
+	TARGET_LINK_LIBRARIES(rbackend rkgraphicsdevice.backend rkgraphicsdevice.frontend ${R_USED_LIBS} ${CMAKE_THREAD_LIBS_INIT})
 ENDIF(RBACKEND_SPLIT)

Modified: trunk/rkward/rkward/rbackend/FindR.cmake
===================================================================
--- trunk/rkward/rkward/rbackend/FindR.cmake	2013-04-11 11:41:17 UTC (rev 4686)
+++ trunk/rkward/rkward/rbackend/FindR.cmake	2013-04-11 11:57:23 UTC (rev 4687)
@@ -18,6 +18,20 @@
 	OUTPUT_VARIABLE R_ARCH)
 MESSAGE (STATUS "R architecture is ${R_ARCH}")
 
+# check R version. Currently min R 2.12.0.
+SET (R_MIN_VERSION "2.12.0")
+MESSAGE (STATUS "Checking R version")
+EXECUTE_PROCESS(
+	COMMAND ${R_EXECUTABLE} "--slave" "--no-save" "-e" "cat (paste(R.version$major, R.version$minor, sep='.'))"
+	OUTPUT_VARIABLE R_VERSION)
+MESSAGE (STATUS "R version is ${R_VERSION}")
+EXECUTE_PROCESS(
+	COMMAND ${R_EXECUTABLE} "--slave" "--no-save" "-e" "min_ver <- '${R_MIN_VERSION}'; if (compareVersion ('${R_VERSION}', min_ver) < 0) cat ('At least R version', min_ver, 'is required')"
+	OUTPUT_VARIABLE R_VERSION_STATUS)
+IF (R_VERSION_STATUS)
+	MESSAGE (FATAL_ERROR ${R_VERSION_STATUS})
+ENDIF (R_VERSION_STATUS)
+
 # find R_HOME
 
 MESSAGE(STATUS "Looking for R_HOME")

Modified: trunk/rkward/rkward/rbackend/rkbackendtransmitter.h
===================================================================
--- trunk/rkward/rkward/rbackend/rkbackendtransmitter.h	2013-04-11 11:41:17 UTC (rev 4686)
+++ trunk/rkward/rkward/rbackend/rkbackendtransmitter.h	2013-04-11 11:57:23 UTC (rev 4687)
@@ -40,7 +40,6 @@
 	void flushOutput (bool force);
 	QList<RBackendRequest*> current_sync_requests;	// pointers to the request that we expect a reply for. Yes, internally, this can be several requests.
 	QString servername;
-	QString token;
 };
 
 #endif

Modified: trunk/rkward/rkward/rbackend/rkfrontendtransmitter.cpp
===================================================================
--- trunk/rkward/rkward/rbackend/rkfrontendtransmitter.cpp	2013-04-11 11:41:17 UTC (rev 4686)
+++ trunk/rkward/rkward/rbackend/rkfrontendtransmitter.cpp	2013-04-11 11:57:23 UTC (rev 4687)
@@ -18,6 +18,7 @@
 #include "rkfrontendtransmitter.h"
 
 #include "rkrbackendprotocol_frontend.h"
+#include "rkwarddevice/rkgraphicsdevice_frontendtransmitter.h"
 #include "../misc/rkcommonfunctions.h"
 #include "../settings/rksettingsmodulegeneral.h"
 #include "../rkglobals.h"
@@ -37,12 +38,14 @@
 RKFrontendTransmitter::RKFrontendTransmitter () : RKAbstractTransmitter () {
 	RK_TRACE (RBACKEND);
 
+	rkd_transmitter = new RKGraphicsDeviceFrontendTransmitter ();
 	start ();
 }
 
 RKFrontendTransmitter::~RKFrontendTransmitter () {
 	RK_TRACE (RBACKEND);
 
+	delete rkd_transmitter;
 	RK_ASSERT (!server->isListening ());
 }
 
@@ -69,6 +72,7 @@
 	QStringList args;
 	args.append ("--debug-level=" + QString::number (RK_Debug_Level));
 	args.append ("--server-name=" + server->fullServerName ());
+	args.append ("--rkd-server-name=" + rkd_transmitter->serverName ());
 	args.append ("--data-dir=" + RKSettingsModuleGeneral::filesPath ());
 	args.append ("--locale-dir=" + KGlobal::dirs()->findResourceDir ("locale", KGlobal::locale ()->language () + "/LC_MESSAGES/rkward.mo"));
 	connect (backend, SIGNAL (finished (int, QProcess::ExitStatus)), this, SLOT (backendExit (int)));

Modified: trunk/rkward/rkward/rbackend/rkfrontendtransmitter.h
===================================================================
--- trunk/rkward/rkward/rbackend/rkfrontendtransmitter.h	2013-04-11 11:41:17 UTC (rev 4686)
+++ trunk/rkward/rkward/rbackend/rkfrontendtransmitter.h	2013-04-11 11:57:23 UTC (rev 4687)
@@ -22,6 +22,7 @@
 
 class QProcess;
 class QLocalServer;
+class RKGraphicsDeviceFrontendTransmitter;
 
 class RKFrontendTransmitter : public RKAbstractTransmitter, public RKROutputBuffer {
 Q_OBJECT
@@ -46,7 +47,7 @@
 	int current_request_length;
 	QProcess* backend;
 	QLocalServer* server;
-	QString token;
+	RKGraphicsDeviceFrontendTransmitter* rkd_transmitter;
 };
 
 #endif

Modified: trunk/rkward/rkward/rbackend/rkrbackend.cpp
===================================================================
--- trunk/rkward/rkward/rbackend/rkrbackend.cpp	2013-04-11 11:41:17 UTC (rev 4686)
+++ trunk/rkward/rkward/rbackend/rkrbackend.cpp	2013-04-11 11:57:23 UTC (rev 4687)
@@ -884,7 +884,7 @@
 SEXP doError (SEXP call) {
 	RK_TRACE (RBACKEND);
 
-	if ((RKRBackend::repl_status.eval_depth == 0) && (!RKRBackend::repl_status.browser_context) && (!RKRBackend::this_pointer->isKilled ()) && (RKRBackend::repl_status.user_command_status != RKRBackend::RKReplStatus::ReplIterationKilled)) {
+	if ((RKRBackend::repl_status.eval_depth == 0) && (!RKRBackend::repl_status.browser_context) && (!RKRBackend::this_pointer->isKilled ()) && (RKRBackend::repl_status.user_command_status != RKRBackend::RKReplStatus::ReplIterationKilled) && (!RKRBackend::repl_status.user_command_status == RKRBackend::RKReplStatus::NoUserCommand)) {
 		RKRBackend::repl_status.user_command_status = RKRBackend::RKReplStatus::UserCommandFailed;
 	}
 	if (RKRBackend::repl_status.interrupted) {
@@ -997,6 +997,8 @@
 	return (R_NilValue);
 }
 
+SEXP RKStartGraphicsDevice (SEXP width, SEXP height, SEXP pointsize, SEXP family, SEXP bg, SEXP title, SEXP antialias);
+
 bool RKRBackend::startR () {
 	RK_TRACE (RBACKEND);
 
@@ -1082,6 +1084,7 @@
 		{ "rk.dialog", (DL_FUNC) &doDialog, 6 },
 		{ "rk.update.locale", (DL_FUNC) &doUpdateLocale, 0 },
 		{ "rk.locale.name", (DL_FUNC) &doLocaleName, 0 },
+		{ "rk.graphics.device", (DL_FUNC) &RKStartGraphicsDevice, 7},
 		{ 0, 0, 0 }
 	};
 	R_registerRoutines (R_getEmbeddingDllInfo(), NULL, callMethods, NULL, NULL);

Modified: trunk/rkward/rkward/rbackend/rkrbackendprotocol_backend.cpp
===================================================================
--- trunk/rkward/rkward/rbackend/rkrbackendprotocol_backend.cpp	2013-04-11 11:41:17 UTC (rev 4686)
+++ trunk/rkward/rkward/rbackend/rkrbackendprotocol_backend.cpp	2013-04-11 11:57:23 UTC (rev 4687)
@@ -2,7 +2,7 @@
                           rkrbackendprotocol  -  description
                              -------------------
     begin                : Thu Nov 04 2010
-    copyright            : (C) 2010 by Thomas Friedrichsmeier
+    copyright            : (C) 2010, 2013 by Thomas Friedrichsmeier
     email                : tfry at users.sourceforge.net
  ***************************************************************************/
 
@@ -85,7 +85,7 @@
 
 	extern "C" void RK_setupGettext (const char*);
 	int RK_Debug_Level = 2;
-	int RK_Debug_Flags = ALL;
+	int RK_Debug_Flags = DEBUG_ALL;
 	QMutex RK_Debug_Mutex;
 	QTemporaryFile* RK_Debug_File;
 
@@ -125,7 +125,7 @@
 		RK_Debug_File->setAutoRemove (false);
 		if (RK_Debug_File->open ()) qInstallMsgHandler (RKDebugMessageOutput);
 
-		QString servername;
+		QString servername, rkd_server_name;
 		QString data_dir, locale_dir;
 		QStringList args = app.arguments ();
 		for (int i = 1; i < args.count (); ++i) {
@@ -138,6 +138,8 @@
 				data_dir = args[i].section ('=', 1);
 			} else if (args[i].startsWith ("--locale-dir")) {
 				locale_dir = args[i].section ('=', 1);
+			} else if (args[i].startsWith ("--rkd-server-name")) {
+				rkd_server_name = args[i].section ('=', 1);
 			} else {
 				printf ("unkown argument %s", qPrintable (args[i]));
 			}
@@ -154,7 +156,7 @@
 		fflush (stdout);
 
 		RKRBackendTransmitter transmitter (servername, token);
-		RKRBackendProtocolBackend backend (data_dir);
+		RKRBackendProtocolBackend backend (data_dir, rkd_server_name);
 		transmitter.start ();
 		RKRBackend::this_pointer->run (locale_dir);
 		transmitter.quit ();
@@ -165,7 +167,7 @@
 #endif
 
 RKRBackendProtocolBackend* RKRBackendProtocolBackend::_instance = 0;
-RKRBackendProtocolBackend::RKRBackendProtocolBackend (const QString &storage_dir) {
+RKRBackendProtocolBackend::RKRBackendProtocolBackend (const QString &storage_dir, const QString &_rkd_server_name) {
 	RK_TRACE (RBACKEND);
 
 	_instance = this;
@@ -181,6 +183,7 @@
 #	endif
 #endif
 	data_dir = storage_dir;
+	rkd_server_name = _rkd_server_name;
 }
 
 RKRBackendProtocolBackend::~RKRBackendProtocolBackend () {

Modified: trunk/rkward/rkward/rbackend/rkrbackendprotocol_backend.h
===================================================================
--- trunk/rkward/rkward/rbackend/rkrbackendprotocol_backend.h	2013-04-11 11:41:17 UTC (rev 4686)
+++ trunk/rkward/rkward/rbackend/rkrbackendprotocol_backend.h	2013-04-11 11:57:23 UTC (rev 4687)
@@ -2,7 +2,7 @@
                           rkrbackendprotocol  -  description
                              -------------------
     begin                : Thu Nov 04 2010
-    copyright            : (C) 2010, 2011 by Thomas Friedrichsmeier
+    copyright            : (C) 2010, 2011, 2013 by Thomas Friedrichsmeier
     email                : tfry at users.sourceforge.net
  ***************************************************************************/
 
@@ -26,9 +26,10 @@
 public:
 	static bool inRThread ();
 	static QString dataDir () { return _instance->data_dir; };
+	static QString rkdServerName () { return _instance->rkd_server_name; };
 	static QString backendDebugFile ();
 
-	RKRBackendProtocolBackend (const QString &data_dir);
+	RKRBackendProtocolBackend (const QString &data_dir, const QString &rkd_server_name);
 	~RKRBackendProtocolBackend ();
 protected:
 friend class RKRBackendProtocolFrontend;
@@ -40,6 +41,7 @@
 	static RKRBackendProtocolBackend* instance () { return _instance; };
 	QString data_dir;
 private:
+	QString rkd_server_name;
 	static RKRBackendProtocolBackend* _instance;
 	QThread *r_thread;
 #ifndef Q_WS_WIN

Modified: trunk/rkward/rkward/rbackend/rktransmitter.h
===================================================================
--- trunk/rkward/rkward/rbackend/rktransmitter.h	2013-04-11 11:41:17 UTC (rev 4686)
+++ trunk/rkward/rkward/rbackend/rktransmitter.h	2013-04-11 11:57:23 UTC (rev 4687)
@@ -2,7 +2,7 @@
                           rktransmitter  -  description
                              -------------------
     begin                : Thu Nov 18 2010
-    copyright            : (C) 2010 by Thomas Friedrichsmeier
+    copyright            : (C) 2010, 2013 by Thomas Friedrichsmeier
     email                : tfry at users.sourceforge.net
  ***************************************************************************/
 
@@ -50,6 +50,9 @@
 public:
 	static RKAbstractTransmitter* instance () { return _instance; };
 	virtual ~RKAbstractTransmitter ();
+
+/** returns the magic token negotiated between frontend and backend (for validating incoming connections) */
+	QString connectionToken () { return token; };
 protected:
 	RKAbstractTransmitter ();
 
@@ -61,6 +64,7 @@
 	void customEvent (QEvent *e);
 	void setConnection (QLocalSocket *connection);
 	QLocalSocket *connection;
+	QString token;
 private slots:
 	/** Note: this blocks until a compelete request has been received. Connected to the "readyRead"-signal of the connection. Calls requestReceived() once the request has been read. */
 	void fetchTransmission ();

Modified: trunk/rkward/rkward/rbackend/rpackages/rkward/NAMESPACE
===================================================================
--- trunk/rkward/rkward/rbackend/rpackages/rkward/NAMESPACE	2013-04-11 11:41:17 UTC (rev 4686)
+++ trunk/rkward/rkward/rbackend/rpackages/rkward/NAMESPACE	2013-04-11 11:57:23 UTC (rev 4687)
@@ -3,6 +3,7 @@
 export(q)
 export(quit)
 export(require)
+export(RK)
 export(.rk.app.version)
 export(.rk.backups)
 export(.rk.cached.available.packages)
@@ -105,6 +106,7 @@
 export(.rk.watched.symbols)
 export(.rk.watch.globalenv)
 export(.rk.watch.symbol)
+export(rk.without.plot.history)
 export(setwd)
 export(Sys.setlocale)
 export(x11)

Modified: trunk/rkward/rkward/rbackend/rpackages/rkward/R/internal_graphics.R
===================================================================
--- trunk/rkward/rkward/rbackend/rpackages/rkward/R/internal_graphics.R	2013-04-11 11:41:17 UTC (rev 4686)
+++ trunk/rkward/rkward/rbackend/rpackages/rkward/R/internal_graphics.R	2013-04-11 11:57:23 UTC (rev 4687)
@@ -3,11 +3,9 @@
 
 # overriding x11 to get informed, when a new x11 window is opened
 #' @export
-"rk.screen.device" <- function (..., is.being.duplicated = FALSE, is.preview.device = FALSE) {
+"rk.screen.device" <- function (...) {
 	.rk.do.call ("startOpenX11", as.character (dev.cur ()));
 
-	old_dev <- dev.cur ()
-
 	args <- list (...)
 	if (!exists (".rk.default.device")) {
 		if (base::.Platform$OS.type == "unix") {
@@ -29,8 +27,7 @@
 
 	.rk.do.call ("endOpenX11", as.character (dev.cur ()));
 
-	if (getOption ("rk.enable.graphics.history"))
-		rk.record.plot$onAddDevice (old_dev, dev.cur (), is.being.duplicated, is.preview.device)
+	rk.record.plot$onAddDevice ()
 
 	invisible (x)
 }
@@ -56,7 +53,7 @@
 	a <- .rk.variables$.rk.preview.devices[[x]]
 	if (is.null (a)) {
 		devnum <- dev.cur ()
-		x11 (is.preview.device = TRUE)
+		rk.without.plot.history (rk.screen.device ())
 		if (devnum != dev.cur ()) {
 			.rk.variables$.rk.preview.devices[[x]] <- list (devnum=dev.cur(), par=par (no.readonly=TRUE))
 		} else {
@@ -147,12 +144,9 @@
 				plot_hist_enabled <- getOption ("rk.enable.graphics.history")
 				if (plot_hist_enabled) {
 					rk.record.plot$record (nextplot.pkg = "lattice")
-					on.exit (options (rk.enable.graphics.history=TRUE))
-					options (rk.enable.graphics.history=FALSE)	# avoid duplicate trigger inside plot(), below
 				}
-				plot (x, ...)
+				rk.without.plot.history (plot (x, ...))
 				if (plot_hist_enabled) {
-					options (rk.enable.graphics.history=TRUE)
 					rk.record.plot$.save.tlo.in.hP ()
 				}
 				invisible ()

Modified: trunk/rkward/rkward/rbackend/rpackages/rkward/R/public_graphics.R
===================================================================
--- trunk/rkward/rkward/rbackend/rpackages/rkward/R/public_graphics.R	2013-04-11 11:41:17 UTC (rev 4686)
+++ trunk/rkward/rkward/rbackend/rpackages/rkward/R/public_graphics.R	2013-04-11 11:57:23 UTC (rev 4687)
@@ -85,6 +85,34 @@
 	invisible (ret)
 }
 
+#' Plot graphics to RKWard native device
+#'
+#' \code{RK()} creates an R on-screen device that will be rendered in the RKWard frontend. 
+#' The default settings for \code{width}, and \code{height} can be modified from Settings -> Configure RKWard -> Onscreen Graphics.
+#'
+#' @param width Width of the device in inches. The default is to use the heigth configured in Settings -> Configure RKWard -> Onscreen Graphics.
+#' @param height Height of the device in inchesgraphics in pixels. The default is to use the heigth configured in Settings -> Configure RKWard -> Onscreen Graphics.
+#' @param pointsize Default pointsize
+#' @param family Default font family. This can be a character vector of length 1 or 2. The second value is used for
+#'               plotting symbols. Effectively the default is c("Helvetica", "Symbol"). A wide variety of sepcification is supported,
+#'               including the device independent fonts names "sans", "serif", and "mono"
+#' @param bg Background color.
+#' @param title Window title.
+#' @param antialias Antialiasing. Can be turned off for somewhat faster drawing.
+#'
+#' @keywords devices
+#'
+#' @export
+#' @aliases RK
+#' @rdname RKdevice
+"RK" <- function (width=getOption("rk.screendevice.width"), height=getOption("rk.screendevice.height"), pointsize=12, family=NULL, bg="white", title="", antialias=TRUE) {
+	if (is.null (width)) width <- 7
+	if (is.null (height)) height <- 7
+	ret <- .Call ("rk.graphics.device", as.integer (width), as.integer (height), as.integer (pointsize), family, bg, title, isTRUE (antialias), PACKAGE="(embedding)")
+	rk.record.plot$onAddDevice (dev.cur ())
+	invisible (ret)	# Current always NULL
+}
+
 #' \code{rk.graph.off()} closes the device that was opened by \code{rk.graph.on}. 
 #'
 #' @rdname rk.graph.on
@@ -135,8 +163,10 @@
 #' @export
 "rk.duplicate.device" <- function (devId = dev.cur ())
 {
+	rk.record.plot$duplicating.from.device <- devId
+	on.exit (rk.record.plot$duplicating.from.device <- 1)	# NULL device
 	dev.set (devId)
-	dev.copy (device = x11, is.being.duplicated = TRUE)
+	dev.copy (device = rk.screen.device)
 }
 
 # A global history of various graphics calls;
@@ -208,16 +238,15 @@
 	}
 	
 	## Device specific functions:
-	onAddDevice <- function (devId.from = 1, devId = dev.cur (), 
-		is.being.duplicated = FALSE, is.preview.device = FALSE)
+	onAddDevice <- function (devId = dev.cur ())
 	{
-		if (is.preview.device) return (invisible ())
+		if (!isTRUE (getOption ("rk.enable.graphics.history"))) return (invisible ())
 		
-		devId.from <- as.character (devId.from)
+		devId.from <- as.character (env$duplicating.from.device)
 		devId <- as.character (devId)
 		
 		histPositions [[devId]] <<- .hP.template
-		if (is.being.duplicated && !histPositions [[devId.from]]$is.this.dev.new) {
+		if ((env$duplicating.from.device > 1) && !histPositions [[devId.from]]$is.this.dev.new) {
 			# devId.from > 1
 			## TODO: see if so many "[[" calls can be reduced?
 			histPositions [[devId]]$is.this.plot.new <<- TRUE
@@ -596,9 +625,9 @@
 			# access it
 			if (cur.devId != as.numeric (devId))
 				tlo.ls <- get ("lattice.status", envir = lattice:::.LatticeEnv)
-			options (rk.enable.graphics.history=FALSE); on.exit (options (rk.enable.graphics.history=TRUE))
-			plot (savedPlots [[st]]$plot, save.object = (cur.devId == as.numeric (devId)))
-			options (rk.enable.graphics.history=TRUE)
+			rk.without.plot.history ({
+				plot (savedPlots [[st]]$plot, save.object = (cur.devId == as.numeric (devId)))
+			})
 			if (cur.devId != as.numeric (devId))
 				assign ("lattice.status", tlo.ls, envir = lattice:::.LatticeEnv)
 		}
@@ -843,6 +872,7 @@
 		# Existing plots are not checked for their sizes, only the new ones are.
 	}
 
+	env$duplicating.from.device <- 1 # NULL device
 	env
 }
 rk.record.plot <- rk.record.plot ()
@@ -931,3 +961,15 @@
 			NULL)
 	ret
 }
+#' Run a (plotting) action, without recording anything in the plot history.
+#' Internally, the plot history option is turned off for the duration of the action.
+#' 
+#' @export
+"rk.without.plot.history" <- function (expr)
+{
+	if (getOption ("rk.enable.graphics.history")) {
+		on.exit (options ("rk.enable.graphics.history" = TRUE))
+	}
+	options ("rk.enable.graphics.history" = FALSE)
+	eval.parent(expr)
+}

Copied: trunk/rkward/rkward/rbackend/rpackages/rkward/man/RKdevice.Rd (from rev 4686, branches/development_branches/rkward_graphpics_device/rkward/rbackend/rpackages/rkward/man/RKdevice.Rd)
===================================================================
--- trunk/rkward/rkward/rbackend/rpackages/rkward/man/RKdevice.Rd	                        (rev 0)
+++ trunk/rkward/rkward/rbackend/rpackages/rkward/man/RKdevice.Rd	2013-04-11 11:57:23 UTC (rev 4687)
@@ -0,0 +1,42 @@
+\name{RK}
+\alias{RK}
+\title{Plot graphics to RKWard native device}
+\usage{
+  RK(width = getOption("rk.screendevice.width"),
+    height = getOption("rk.screendevice.height"),
+    pointsize = 12, family = NULL, bg = "white",
+    title = "", antialias = TRUE)
+}
+\arguments{
+  \item{width}{Width of the device in inches. The default
+  is to use the heigth configured in Settings -> Configure
+  RKWard -> Onscreen Graphics.}
+
+  \item{height}{Height of the device in inchesgraphics in
+  pixels. The default is to use the heigth configured in
+  Settings -> Configure RKWard -> Onscreen Graphics.}
+
+  \item{pointsize}{Default pointsize}
+
+  \item{family}{Default font family. This can be a
+  character vector of length 1 or 2. The second value is
+  used for plotting symbols. Effectively the default is
+  c("Helvetica", "Symbol"). A wide variety of sepcification
+  is supported, including the device independent fonts
+  names "sans", "serif", and "mono"}
+
+  \item{bg}{Background color.}
+
+  \item{title}{Window title.}
+
+  \item{antialias}{Antialiasing. Can be turned off for
+  somewhat faster drawing.}
+}
+\description{
+  \code{RK()} creates an R on-screen device that will be
+  rendered in the RKWard frontend. The default settings for
+  \code{width}, and \code{height} can be modified from
+  Settings -> Configure RKWard -> Onscreen Graphics.
+}
+\keyword{devices}
+

Modified: trunk/rkward/rkward/settings/rksettingsmoduledebug.cpp
===================================================================
--- trunk/rkward/rkward/settings/rksettingsmoduledebug.cpp	2013-04-11 11:41:17 UTC (rev 4686)
+++ trunk/rkward/rkward/settings/rksettingsmoduledebug.cpp	2013-04-11 11:57:23 UTC (rev 4687)
@@ -70,6 +70,7 @@
 	debug_flags_group->addButton (new QCheckBox ("DIALOGS", group), DIALOGS);
 	debug_flags_group->addButton (new QCheckBox ("OUTPUT", group), OUTPUT);
 	debug_flags_group->addButton (new QCheckBox ("XML", group), XML);
+	debug_flags_group->addButton (new QCheckBox ("GRAPHICS_DEVICE", group), GRAPHICS_DEVICE);
 
 	QList<QAbstractButton*> buttons = debug_flags_group->buttons ();
 	for (QList<QAbstractButton*>::const_iterator it = buttons.constBegin (); it != buttons.constEnd (); ++it) {

Modified: trunk/rkward/rkward/windows/rkwindowcatcher.cpp
===================================================================
--- trunk/rkward/rkward/windows/rkwindowcatcher.cpp	2013-04-11 11:41:17 UTC (rev 4686)
+++ trunk/rkward/rkward/windows/rkwindowcatcher.cpp	2013-04-11 11:57:23 UTC (rev 4687)
@@ -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 = close_attempted = false;
+	commonInit (device_number);
 	embedded = window_to_embed;
-	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
-
 #ifdef Q_WS_WIN
 	// unfortunately, trying to get KWindowInfo as below hangs on windows (KDElibs 4.2.3)
 	WINDOWINFO wininfo;
@@ -192,14 +168,61 @@
 	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 = rkward_device;
+	xembed_container->setFixedSize (rk_native_device->viewPort ()->size ());
+	rk_native_device->viewPort ()->setParent (xembed_container);
+
+// adjust to size
+//	dynamic_size_action->setChecked (true);
+	fixedSizeToggled ();
+}
+
+void RKCaughtX11Window::commonInit (int device_number) {
+	RK_TRACE (MISC);
+
+	capture = 0;
+	rk_native_device = 0;
+	killed_in_r = close_attempted = 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);
 
@@ -264,6 +287,8 @@
 		return RKMDIWindow::close (also_delete);
 	}
 
+	if (rk_native_device) rk_native_device->stopInteraction ();
+
 	QString status = i18n ("Closing device (saving history)");
 	if (!close_attempted) {
 		RCommand* c = new RCommand ("dev.off (" + QString::number (device_number) + ')', RCommand::App, i18n ("Shutting down device number %1", device_number));

Modified: trunk/rkward/rkward/windows/rkwindowcatcher.h
===================================================================
--- trunk/rkward/rkward/windows/rkwindowcatcher.h	2013-04-11 11:41:17 UTC (rev 4686)
+++ trunk/rkward/rkward/windows/rkwindowcatcher.h	2013-04-11 11:57:23 UTC (rev 4687)
@@ -2,7 +2,7 @@
                           rwindowcatcher.h  -  description
                              -------------------
     begin                : Wed May 4 2005
-    copyright            : (C) 2005 - 2013 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,7 +161,11 @@
 private slots:
 	void doEmbed ();
 private:
+<<<<<<< .working
 	void forceClose ();
+=======
+	void commonInit (int device_number);
+>>>>>>> .merge-right.r4686
 	void reEmbed ();
 	void rCommandDone (RCommand *command);
 	friend class RKCaughtX11WindowPart;	// needs access to the actions
@@ -180,6 +187,7 @@
 	// a dummy to make things compile for now
 	QWidget *capture;
 #endif
+	RKGraphicsDevice *rk_native_device;
 
 	bool dynamic_size;
 	KToggleAction *dynamic_size_action;

Modified: trunk/rkward/rkward/windows/rkworkplace.cpp
===================================================================
--- trunk/rkward/rkward/windows/rkworkplace.cpp	2013-04-11 11:41:17 UTC (rev 4686)
+++ trunk/rkward/rkward/windows/rkworkplace.cpp	2013-04-11 11:57:23 UTC (rev 4687)
@@ -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: trunk/rkward/rkward/windows/rkworkplace.h
===================================================================
--- trunk/rkward/rkward/windows/rkworkplace.h	2013-04-11 11:41:17 UTC (rev 4686)
+++ trunk/rkward/rkward/windows/rkworkplace.h	2013-04-11 11:57:23 UTC (rev 4687)
@@ -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