]> git.saurik.com Git - wxWidgets.git/blame - samples/ipc/baseserver.cpp
forwarding mouse moved events to the view under the mouse, not the firstResponder
[wxWidgets.git] / samples / ipc / baseserver.cpp
CommitLineData
ebe887ed
VZ
1///////////////////////////////////////////////////////////////////////////////
2// Name: samples/ipc/baseserver.cpp
3// Purpose: IPC sample: console server
4// Author: Anders Larsen
5// Most of the code was stolen from: samples/ipc/server.cpp
6// (c) Julian Smart, Jurgen Doornik
7// Created: 2007-11-08
8// RCS-ID: $Id$
9// Copyright: (c) 2007 Anders Larsen
526954c5 10// Licence: wxWindows licence
ebe887ed
VZ
11///////////////////////////////////////////////////////////////////////////////
12
13// ============================================================================
14// declarations
15// ============================================================================
16
17// ----------------------------------------------------------------------------
18// headers
19// ----------------------------------------------------------------------------
20
21// For compilers that support precompilation, includes "wx.h".
22#include "wx/wxprec.h"
23
24#ifdef __BORLANDC__
25 #pragma hdrstop
26#endif
27
28#ifndef WX_PRECOMP
29 #include "wx/wx.h"
30#endif
31
32// Settings common to both executables: determines whether
33// we're using TCP/IP or real DDE.
34#include "ipcsetup.h"
35
521d3436
VZ
36#include "connection.h"
37
ebe887ed
VZ
38#include "wx/timer.h"
39#include "wx/datetime.h"
40
41// ----------------------------------------------------------------------------
65669e31 42// local classes
ebe887ed
VZ
43// ----------------------------------------------------------------------------
44
65669e31 45// a simple connection class testing and logging various operations
521d3436 46class MyConnection : public MyConnectionBase, public wxTimer
ebe887ed
VZ
47{
48public:
ebe887ed 49 virtual bool Disconnect() { return wxConnection::Disconnect(); }
65669e31
VZ
50 virtual bool OnExecute(const wxString& topic,
51 const void *data,
52 size_t size,
53 wxIPCFormat format);
54 virtual const void *OnRequest(const wxString& topic,
55 const wxString& item,
56 size_t *size,
57 wxIPCFormat format);
58 virtual bool OnPoke(const wxString& topic,
59 const wxString& item,
60 const void *data,
61 size_t size,
62 wxIPCFormat format);
ebe887ed
VZ
63 virtual bool OnStartAdvise(const wxString& topic, const wxString& item);
64 virtual bool OnStopAdvise(const wxString& topic, const wxString& item);
65669e31
VZ
65 virtual bool DoAdvise(const wxString& item,
66 const void *data,
67 size_t size,
68 wxIPCFormat format);
ebe887ed
VZ
69 virtual bool OnDisconnect();
70 virtual void Notify();
71
ea84f255 72private:
ebe887ed
VZ
73 wxString m_sAdvise;
74
ebe887ed
VZ
75 wxString m_sRequestDate;
76 char m_achRequestBytes[3];
77};
78
65669e31
VZ
79// a connection used for benchmarking some IPC operations by
80// tests/benchmarks/ipcclient.cpp
81class BenchConnection : public wxConnection
82{
83public:
84 BenchConnection() { m_advise = false; }
85
86 virtual bool OnPoke(const wxString& topic,
87 const wxString& item,
88 const void *data,
89 size_t size,
90 wxIPCFormat format);
91 virtual bool OnStartAdvise(const wxString& topic, const wxString& item);
92 virtual bool OnStopAdvise(const wxString& topic, const wxString& item);
93
94private:
95 // return true if this is the supported topic+item combination, log an
96 // error message otherwise
97 bool IsSupportedTopicAndItem(const wxString& operation,
98 const wxString& topic,
99 const wxString& item) const;
100
101 // the item which can be manipulated by the client via Poke() calls
102 wxString m_item;
103
104 // should we notify the client about changes to m_item?
105 bool m_advise;
106
c0c133e1 107 wxDECLARE_NO_COPY_CLASS(BenchConnection);
65669e31
VZ
108};
109
110// a simple server accepting connections to IPC_TOPIC and IPC_BENCHMARK_TOPIC
ea84f255 111class MyServer : public wxServer
ebe887ed
VZ
112{
113public:
114 MyServer();
115 virtual ~MyServer();
116 void Disconnect();
117 bool IsConnected() { return m_connection != NULL; };
ea84f255
VZ
118
119 virtual wxConnectionBase *OnAcceptConnection(const wxString& topic);
120
121private:
122 wxConnection *m_connection;
123};
124
125// Define a new application
126class MyApp : public wxApp
127{
128public:
129 virtual bool OnInit();
ebe887ed
VZ
130
131protected:
ea84f255 132 MyServer m_server;
ebe887ed
VZ
133};
134
ea84f255
VZ
135DECLARE_APP(MyApp)
136
ebe887ed
VZ
137// ============================================================================
138// implementation
139// ============================================================================
140
2e334012 141IMPLEMENT_APP_CONSOLE(MyApp)
ebe887ed
VZ
142
143// ----------------------------------------------------------------------------
144// MyApp
145// ----------------------------------------------------------------------------
146
147bool MyApp::OnInit()
148{
149 if ( !wxApp::OnInit() )
150 return false;
151
152 delete wxLog::SetActiveTarget(new wxLogStderr);
153
ea84f255 154 const char * const kind =
ebe887ed 155#if wxUSE_DDE_FOR_IPC
ea84f255
VZ
156 "DDE"
157#else
158 "TCP"
159#endif
160 ;
161
162 // Create a new server
163 if ( !m_server.Create(IPC_SERVICE) )
ebe887ed 164 {
ea84f255 165 wxLogMessage("%s server failed to start on %s", kind, IPC_SERVICE);
ebe887ed
VZ
166 return false;
167 }
ebe887ed 168
ea84f255
VZ
169 wxLogMessage("%s server started on %s", kind, IPC_SERVICE);
170 return true;
ebe887ed
VZ
171}
172
173// ----------------------------------------------------------------------------
174// MyServer
175// ----------------------------------------------------------------------------
176
177MyServer::MyServer()
178{
179 m_connection = NULL;
180}
181
182MyServer::~MyServer()
183{
184 Disconnect();
185}
186
187wxConnectionBase *MyServer::OnAcceptConnection(const wxString& topic)
188{
65669e31 189 wxLogMessage("OnAcceptConnection(\"%s\")", topic);
ebe887ed
VZ
190
191 if ( topic == IPC_TOPIC )
192 {
193 m_connection = new MyConnection;
65669e31
VZ
194 }
195 else if ( topic == IPC_BENCHMARK_TOPIC )
196 {
197 m_connection = new BenchConnection;
198 }
199 else // unknown topic
200 {
201 wxLogMessage("Unknown topic");
202 return NULL;
ebe887ed 203 }
ea84f255 204
65669e31
VZ
205 wxLogMessage("Connection accepted");
206 return m_connection;
ebe887ed
VZ
207}
208
209void MyServer::Disconnect()
210{
65669e31 211 if ( m_connection )
ebe887ed
VZ
212 {
213 m_connection->Disconnect();
5276b0a5 214 wxDELETE(m_connection);
ea84f255 215 wxLogMessage("Disconnected client");
ebe887ed
VZ
216 }
217}
218
219// ----------------------------------------------------------------------------
220// MyConnection
221// ----------------------------------------------------------------------------
222
ea84f255
VZ
223bool
224MyConnection::OnExecute(const wxString& topic,
225 const void *data,
226 size_t size,
227 wxIPCFormat format)
ebe887ed 228{
ea84f255 229 Log("OnExecute", topic, "", data, size, format);
ebe887ed
VZ
230 return true;
231}
232
ea84f255
VZ
233bool
234MyConnection::OnPoke(const wxString& topic,
235 const wxString& item,
236 const void *data,
237 size_t size,
238 wxIPCFormat format)
ebe887ed 239{
ea84f255 240 Log("OnPoke", topic, item, data, size, format);
ebe887ed
VZ
241 return wxConnection::OnPoke(topic, item, data, size, format);
242}
243
ea84f255
VZ
244const void *
245MyConnection::OnRequest(const wxString& topic,
246 const wxString& item,
247 size_t *size,
248 wxIPCFormat format)
ebe887ed
VZ
249{
250 const void *data;
ea84f255 251 if (item == "Date")
ebe887ed
VZ
252 {
253 m_sRequestDate = wxDateTime::Now().Format();
254 data = m_sRequestDate.c_str();
255 *size = wxNO_LEN;
256 }
ea84f255 257 else if (item == "Date+len")
ebe887ed 258 {
65669e31
VZ
259 m_sRequestDate = wxDateTime::Now().FormatTime() +
260 " " + wxDateTime::Now().FormatDate();
ebe887ed
VZ
261 data = m_sRequestDate.c_str();
262 *size = m_sRequestDate.Length() + 1;
263 }
ea84f255 264 else if (item == "bytes[3]")
ebe887ed
VZ
265 {
266 data = m_achRequestBytes;
65669e31
VZ
267 m_achRequestBytes[0] = '1';
268 m_achRequestBytes[1] = '2';
269 m_achRequestBytes[2] = '3';
ebe887ed
VZ
270 *size = 3;
271 }
272 else
273 {
274 data = NULL;
275 *size = 0;
276 }
ea84f255 277 Log("OnRequest", topic, item, data, *size, format);
ebe887ed
VZ
278 return data;
279}
280
ea84f255 281bool MyConnection::OnStartAdvise(const wxString& topic, const wxString& item)
ebe887ed 282{
65669e31 283 wxLogMessage("OnStartAdvise(\"%s\",\"%s\")", topic, item);
ea84f255 284 wxLogMessage("Returning true");
ebe887ed 285 m_sAdvise = item;
ea84f255 286 Start(3000); // schedule our Notify() to be called in 3 seconds
ebe887ed
VZ
287 return true;
288}
289
ea84f255 290bool MyConnection::OnStopAdvise(const wxString& topic, const wxString& item)
ebe887ed 291{
65669e31 292 wxLogMessage("OnStopAdvise(\"%s\",\"%s\")", topic, item);
ea84f255
VZ
293 wxLogMessage("Returning true");
294 m_sAdvise.clear();
ebe887ed
VZ
295 Stop();
296 return true;
297}
298
299void MyConnection::Notify()
300{
ea84f255 301 if (!m_sAdvise.empty())
ebe887ed
VZ
302 {
303 wxString s = wxDateTime::Now().Format();
304 Advise(m_sAdvise, s);
65669e31
VZ
305 s = wxDateTime::Now().FormatTime() + " "
306 + wxDateTime::Now().FormatDate();
ea84f255 307 Advise(m_sAdvise, s.mb_str(), s.length() + 1);
ebe887ed
VZ
308
309#if wxUSE_DDE_FOR_IPC
ea84f255
VZ
310 wxLogMessage("DDE Advise type argument cannot be wxIPC_PRIVATE. "
311 "The client will receive it as wxIPC_TEXT, "
312 "and receive the correct no of bytes, "
313 "but not print a correct log entry.");
314#endif // DDE
315
ebe887ed
VZ
316 char bytes[3];
317 bytes[0] = '1'; bytes[1] = '2'; bytes[2] = '3';
318 Advise(m_sAdvise, bytes, 3, wxIPC_PRIVATE);
319 // this works, but the log treats it as a string now
320// m_connection->Advise(m_connection->m_sAdvise, bytes, 3, wxIPC_TEXT );
321 }
322}
323
65669e31
VZ
324bool MyConnection::DoAdvise(const wxString& item,
325 const void *data,
326 size_t size,
327 wxIPCFormat format)
ebe887ed 328{
ea84f255 329 Log("Advise", "", item, data, size, format);
ebe887ed
VZ
330 return wxConnection::DoAdvise(item, data, size, format);
331}
332
333bool MyConnection::OnDisconnect()
334{
ea84f255 335 wxLogMessage("OnDisconnect()");
ebe887ed
VZ
336 return true;
337}
65669e31
VZ
338
339// ----------------------------------------------------------------------------
340// BenchConnection
341// ----------------------------------------------------------------------------
342
343bool BenchConnection::IsSupportedTopicAndItem(const wxString& operation,
344 const wxString& topic,
345 const wxString& item) const
346{
347 if ( topic != IPC_BENCHMARK_TOPIC ||
348 item != IPC_BENCHMARK_ITEM )
349 {
350 wxLogMessage("Unexpected %s(\"%s\", \"%s\") call.",
351 operation, topic, item);
352 return false;
353 }
354
355 return true;
356}
357
358bool BenchConnection::OnPoke(const wxString& topic,
359 const wxString& item,
360 const void *data,
361 size_t size,
362 wxIPCFormat format)
363{
364 if ( !IsSupportedTopicAndItem("OnPoke", topic, item) )
365 return false;
366
367 if ( !IsTextFormat(format) )
368 {
369 wxLogMessage("Unexpected format %d in OnPoke().", format);
370 return false;
371 }
372
373 m_item = GetTextFromData(data, size, format);
374
375 if ( m_advise )
376 {
377 if ( !Advise(item, m_item) )
43b2d5e7 378 {
65669e31 379 wxLogMessage("Failed to advise client about the change.");
43b2d5e7 380 }
65669e31
VZ
381 }
382
383 return true;
384}
385
386bool BenchConnection::OnStartAdvise(const wxString& topic, const wxString& item)
387{
388 if ( !IsSupportedTopicAndItem("OnStartAdvise", topic, item) )
389 return false;
390
391 m_advise = true;
392
393 return true;
394}
395
396bool BenchConnection::OnStopAdvise(const wxString& topic, const wxString& item)
397{
398 if ( !IsSupportedTopicAndItem("OnStopAdvise", topic, item) )
399 return false;
400
401 m_advise = false;
402
403 return true;
404}
405