1 /* GNUPLOT - QtGnuplotEvent.cpp */
2 
3 /*[
4  * Copyright 2009   Jérôme Lodewyck
5  *
6  * Permission to use, copy, and distribute this software and its
7  * documentation for any purpose with or without fee is hereby granted,
8  * provided that the above copyright notice appear in all copies and
9  * that both that copyright notice and this permission notice appear
10  * in supporting documentation.
11  *
12  * Permission to modify the software is granted, but not the right to
13  * distribute the complete modified source code.  Modifications are to
14  * be distributed as patches to the released version.  Permission to
15  * distribute binaries produced by compiling modified sources is granted,
16  * provided you
17  *   1. distribute the corresponding source modifications from the
18  *    released version in the form of a patch file along with the binaries,
19  *   2. add special version identification to distinguish your version
20  *    in addition to the base release version number,
21  *   3. provide your name and address as the primary contact for the
22  *    support of your modified version, and
23  *   4. retain our contact information in regard to use of the base
24  *    software.
25  * Permission to distribute the released version of the source code along
26  * with corresponding source modifications in the form of a patch file is
27  * granted with same provisions 2 through 4 for binary distributions.
28  *
29  * This software is provided "as is" without express or implied warranty
30  * to the extent permitted by applicable law.
31  *
32  *
33  * Alternatively, the contents of this file may be used under the terms of the
34  * GNU General Public License Version 2 or later (the "GPL"), in which case the
35  * provisions of GPL are applicable instead of those above. If you wish to allow
36  * use of your version of this file only under the terms of the GPL and not
37  * to allow others to use your version of this file under the above gnuplot
38  * license, indicate your decision by deleting the provisions above and replace
39  * them with the notice and other provisions required by the GPL. If you do not
40  * delete the provisions above, a recipient may use your version of this file
41  * under either the GPL or the gnuplot license.
42 ]*/
43 
44 #include "QtGnuplotEvent.h"
45 #include "QtGnuplotWidget.h"
46 
47 extern "C" {
48 #include "../mousecmn.h"
49 }
50 
51 #include <QtNetwork>
52 
serverName()53 QString QtGnuplotEventReceiver::serverName()
54 {
55 	if (m_eventHandler)
56 		return m_eventHandler->serverName();
57 
58 	return QString();
59 }
60 
QtGnuplotEventHandler(QObject * parent,const QString & socket)61 QtGnuplotEventHandler::QtGnuplotEventHandler(QObject* parent, const QString& socket)
62 	: QObject(parent)
63 {
64 	m_blockSize = 0;
65 	m_socket = 0;
66 	m_server = new QLocalServer(this);
67 	if (!m_server->listen(socket))
68 		qDebug() << "QtGnuplotApplication error : cannot open server";
69 
70 	connect(m_server, SIGNAL(newConnection()), this, SLOT(newConnection()));
71 }
72 
serverName()73 QString QtGnuplotEventHandler::serverName()
74 {
75 	return m_server->serverName();
76 }
77 
newConnection()78 void QtGnuplotEventHandler::newConnection()
79 {
80 	m_socket = m_server->nextPendingConnection();
81 	connect(m_socket, SIGNAL(readyRead()), this, SLOT(readEvent()));
82 	connect(m_socket, SIGNAL(disconnected()), this, SLOT(connectionClosed()));
83 	emit(connected());
84 }
85 
connectionClosed()86 void QtGnuplotEventHandler::connectionClosed()
87 {
88 	emit(disconnected());
89 }
90 
readEvent()91 void QtGnuplotEventHandler::readEvent()
92 {
93 	QDataStream in(m_socket);
94 	in.setVersion(QDataStream::Qt_4_4);
95 
96 	QtGnuplotEventReceiver* receiver = dynamic_cast<QtGnuplotEventReceiver*>(parent());
97 	if (!receiver)
98 	{
99 		qDebug() << "QtGnuplotEventHandler::readEvent -- No receiver !";
100 		return;
101 	}
102 
103 	while(!in.atEnd())
104 	{
105 		// Extract the message length
106 		if (m_blockSize == 0)
107 		{
108 			if (m_socket->bytesAvailable() < (int)sizeof(qint32))
109 				return;
110 			in >> m_blockSize;
111 		}
112 
113 		// Break if the message is not entirely received yet
114 		if (m_socket->bytesAvailable() < m_blockSize)
115 			return;
116 
117 		// Process the message
118 		int remaining = m_socket->bytesAvailable() - m_blockSize;
119 		while (m_socket->bytesAvailable() > remaining)
120 		{
121 			int type;
122 			in >> type;
123 			if ((type < 1000) || (type > GEDone))
124 			{
125 			// FIXME EAM - At this point the program cannot recover and
126 			// if we try to continue it will eventually become a zombie.
127 			// Better to just exit explicitly right now.
128 				qDebug() << "qt_gnuplot exiting on read error";
129 				exit(0);
130 				// return;
131 			}
132 			receiver->processEvent(QtGnuplotEventType(type), in);
133 		}
134 		m_blockSize = 0;
135 	}
136 }
137 
postTermEvent(int type,int mx,int my,int par1,int par2,QtGnuplotWidget * widget)138 bool QtGnuplotEventHandler::postTermEvent(int type, int mx, int my, int par1, int par2, QtGnuplotWidget* widget)
139 {
140 	if ((m_socket == 0) || (m_socket->state() != QLocalSocket::ConnectedState))
141 		return false;
142 
143 	if (widget && !widget->isActive()) {
144 		if (type == GE_buttonrelease) {
145 			// qDebug() << "Rescued buttonrelease event with widget inactive";
146 		} else {
147 			// qDebug() << "Event lost because widget is not active";
148 			return false;
149 		}
150 	}
151 
152 	gp_event_t event;
153 	event.type = type;
154 	event.mx = mx;
155 	event.my = my;
156 	event.par1 = par1;
157 	event.par2 = par2;
158 	event.winid = 0; // We don't forward any window id to gnuplot
159 	m_socket->write((char*) &event, sizeof(gp_event_t));
160 
161 	return true;
162 }
163 
164 // Catch events for which the receiver is not active
swallowEvent(QtGnuplotEventType type,QDataStream & in)165 void QtGnuplotEventReceiver::swallowEvent(QtGnuplotEventType type, QDataStream& in)
166 {
167 	QPoint point;
168 	QString string;
169 	int i;
170 	bool b;
171 
172 	     if (type == GESetCurrentWindow) in >> i;        // 1000
173 	else if (type == GEInitWindow)       ;               // 1001
174 	else if (type == GECloseWindow)      in >> i;        // 1002
175 	else if (type == GEExit)             ;               // 1003
176 	else if (type == GEPersist)          ;               // 1004
177 	else if (type == GEStatusText)       in >> string;   // 1005
178 	else if (type == GETitle)            in >> string;   // 1006
179 	else if (type == GESetCtrl)          in >> b;        // 1007
180 	else if (type == GECursor)           in >> i;        // 1009
181 	else if (type == GEZoomStart)        in >> string;   // 1022
182 	else if (type == GEZoomStop)         in >> string;   // 1023
183 	else if (type == GERaise)            ;               // 1034
184 	else if (type == GEDesactivate)      ;               // 1038
185 	else if (type == GESetPosition)      in >> point;
186 	else qDebug() << "Event not swallowed !" << type;
187 }
188