]> git.saurik.com Git - wxWidgets.git/blame_incremental - samples/ipc/server.cpp
Fix wrong configure test for abi::__forced_unwind in previous commit.
[wxWidgets.git] / samples / ipc / server.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: server.cpp
3// Purpose: IPC sample: server
4// Author: Julian Smart
5// Modified by: Jurgen Doornik
6// Created: 25/01/99
7// RCS-ID: $Id$
8// Copyright: (c) Julian Smart
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
20// For compilers that support precompilation, includes "wx.h".
21#include "wx/wxprec.h"
22
23#ifdef __BORLANDC__
24 #pragma hdrstop
25#endif
26
27#ifndef WX_PRECOMP
28 #include "wx/wx.h"
29#endif
30
31// Settings common to both executables: determines whether
32// we're using TCP/IP or real DDE.
33#include "ipcsetup.h"
34
35#ifndef wxHAS_IMAGES_IN_RESOURCES
36 #include "../sample.xpm"
37#endif
38
39#include "server.h"
40#include "wx/textdlg.h"
41#include "wx/datetime.h"
42
43// ----------------------------------------------------------------------------
44// wxWin macros
45// ----------------------------------------------------------------------------
46
47IMPLEMENT_APP(MyApp)
48
49BEGIN_EVENT_TABLE(MyFrame, wxFrame)
50 EVT_CLOSE( MyFrame::OnClose )
51
52 EVT_BUTTON( ID_START, MyFrame::OnStart )
53 EVT_CHOICE( ID_SERVERNAME, MyFrame::OnServerName )
54 EVT_BUTTON( ID_DISCONNECT, MyFrame::OnDisconnect )
55 EVT_BUTTON( ID_ADVISE, MyFrame::OnAdvise )
56END_EVENT_TABLE()
57
58
59// ============================================================================
60// implementation
61// ============================================================================
62
63// ----------------------------------------------------------------------------
64// MyApp
65// ----------------------------------------------------------------------------
66
67bool MyApp::OnInit()
68{
69 if ( !wxApp::OnInit() )
70 return false;
71
72 // Create the main frame window
73 m_frame = new MyFrame(NULL, "Server");
74 m_frame->Show(true);
75
76 return true;
77}
78
79// ----------------------------------------------------------------------------
80// MyFrame
81// ----------------------------------------------------------------------------
82
83// Define my frame constructor
84MyFrame::MyFrame(wxFrame *frame, const wxString& title)
85 : wxFrame(frame, wxID_ANY, title, wxDefaultPosition, wxSize(400, 300))
86{
87#if wxUSE_STATUSBAR
88 CreateStatusBar();
89#endif // wxUSE_STATUSBAR
90
91 SetIcon(wxICON(sample));
92
93 m_server = NULL;
94
95 wxPanel * const panel = new wxPanel(this);
96
97 wxBoxSizer * const sizerMain = new wxBoxSizer( wxVERTICAL );
98
99 wxFlexGridSizer * const sizerCmds = new wxFlexGridSizer( 2, 0, 0 );
100 sizerCmds->AddGrowableCol( 1 );
101
102 wxButton *btn;
103
104 btn = new wxButton(panel, ID_START, "&Start Server");
105 sizerCmds->Add(btn, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5);
106
107 const wxString choices[] = { IPC_SERVICE, "..." };
108 wxChoice * const choice = new wxChoice
109 (
110 panel,
111 ID_SERVERNAME,
112 wxDefaultPosition, wxSize(100, -1),
113 WXSIZEOF(choices), choices
114 );
115 sizerCmds->Add(choice, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5);
116
117 btn = new wxButton(panel, ID_DISCONNECT, "&Disconnect Client");
118 sizerCmds->Add(btn, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5);
119 sizerCmds->AddSpacer(20);
120
121 btn = new wxButton( panel, ID_ADVISE, "&Advise");
122 sizerCmds->Add(btn, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5);
123 sizerCmds->AddSpacer(20);
124
125 sizerMain->Add(sizerCmds, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5);
126
127 wxStaticBoxSizer * const
128 sizerLog = new wxStaticBoxSizer(wxVERTICAL, panel, "Server &log");
129
130 wxTextCtrl * const textLog = new wxTextCtrl
131 (
132 panel,
133 wxID_ANY,
134 "",
135 wxDefaultPosition, wxSize(500, 140),
136 wxTE_MULTILINE
137 );
138 sizerLog->Add(textLog, 1, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5);
139
140 sizerMain->Add(sizerLog, 1, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5);
141
142 panel->SetSizer(sizerMain);
143 sizerMain->SetSizeHints(panel);
144 SetClientSize(panel->GetSize());
145
146 GetServername()->SetSelection(0);
147 wxLogTextCtrl *logWindow = new wxLogTextCtrl(textLog);
148 delete wxLog::SetActiveTarget(logWindow);
149 wxLogMessage("Click on Start to start the server");
150 UpdateUI();
151}
152
153void MyFrame::UpdateUI()
154{
155 GetStart()->Enable(m_server == NULL);
156 GetServername()->Enable(m_server == NULL);
157 GetAdvise()->Enable(m_server && m_server->CanAdvise());
158 GetDisconnect()->Enable(m_server && m_server->IsConnected());
159}
160
161void MyFrame::OnClose(wxCloseEvent& event)
162{
163 wxDELETE(m_server);
164 event.Skip();
165}
166
167void MyFrame::OnStart(wxCommandEvent& WXUNUSED(event))
168{
169 // Create a new server
170 m_server = new MyServer;
171 wxString servername = GetServername()->GetStringSelection();
172 if (m_server->Create(servername))
173 {
174 wxLogMessage("Server %s started", servername);
175 #if wxUSE_DDE_FOR_IPC
176 wxLogMessage("Server uses DDE");
177 #else // !wxUSE_DDE_FOR_IPC
178 wxLogMessage("Server uses TCP");
179 #endif // wxUSE_DDE_FOR_IPC/!wxUSE_DDE_FOR_IPC
180 }
181 else
182 {
183 wxLogMessage("Server %s failed to start", servername);
184 wxDELETE(m_server);
185 }
186 UpdateUI();
187}
188
189void MyFrame::OnServerName( wxCommandEvent& WXUNUSED(event) )
190{
191 if ( GetServername()->GetStringSelection() == "..." )
192 {
193 wxString s = wxGetTextFromUser
194 (
195 "Specify the name of the server",
196 "Server Name",
197 "",
198 this
199 );
200
201 if ( !s.empty() && s != IPC_SERVICE )
202 {
203 GetServername()->Insert(s, 0);
204 GetServername()->SetSelection(0);
205 }
206 }
207}
208
209void MyFrame::Disconnect()
210{
211 m_server->Disconnect();
212 UpdateUI();
213}
214
215void MyFrame::OnDisconnect(wxCommandEvent& WXUNUSED(event))
216{
217 Disconnect();
218}
219
220void MyFrame::OnAdvise(wxCommandEvent& WXUNUSED(event))
221{
222 m_server->Advise();
223}
224
225// ----------------------------------------------------------------------------
226// MyServer
227// ----------------------------------------------------------------------------
228
229MyServer::MyServer() : wxServer()
230{
231 m_connection = NULL;
232}
233
234MyServer::~MyServer()
235{
236 Disconnect();
237}
238
239wxConnectionBase *MyServer::OnAcceptConnection(const wxString& topic)
240{
241 wxLogMessage("OnAcceptConnection(\"%s\")", topic);
242
243 if ( topic == IPC_TOPIC )
244 {
245 m_connection = new MyConnection();
246 wxGetApp().GetFrame()->UpdateUI();
247 wxLogMessage("Connection accepted");
248 return m_connection;
249 }
250 //else: unknown topic
251
252 wxLogMessage("Unknown topic, connection refused");
253 return NULL;
254}
255
256void MyServer::Disconnect()
257{
258 if ( m_connection )
259 {
260 wxDELETE(m_connection);
261 wxGetApp().GetFrame()->UpdateUI();
262 wxLogMessage("Disconnected client");
263 }
264}
265
266void MyServer::Advise()
267{
268 if ( CanAdvise() )
269 {
270 const wxDateTime now = wxDateTime::Now();
271
272 m_connection->Advise(m_connection->m_advise, now.Format());
273
274 const wxString s = now.FormatTime() + " " + now.FormatDate();
275 m_connection->Advise(m_connection->m_advise, s.mb_str(), wxNO_LEN);
276
277#if wxUSE_DDE_FOR_IPC
278 wxLogMessage("DDE Advise type argument cannot be wxIPC_PRIVATE. "
279 "The client will receive it as wxIPC_TEXT, "
280 " and receive the correct no of bytes, "
281 "but not print a correct log entry.");
282#endif
283 char bytes[3] = { '1', '2', '3' };
284 m_connection->Advise(m_connection->m_advise, bytes, 3, wxIPC_PRIVATE);
285 }
286}
287
288// ----------------------------------------------------------------------------
289// MyConnection
290// ----------------------------------------------------------------------------
291
292bool
293MyConnection::OnExecute(const wxString& topic,
294 const void *data,
295 size_t size,
296 wxIPCFormat format)
297{
298 Log("OnExecute", topic, "", data, size, format);
299 return true;
300}
301
302bool
303MyConnection::OnPoke(const wxString& topic,
304 const wxString& item,
305 const void *data,
306 size_t size,
307 wxIPCFormat format)
308{
309 Log("OnPoke", topic, item, data, size, format);
310 return wxConnection::OnPoke(topic, item, data, size, format);
311}
312
313const void *
314MyConnection::OnRequest(const wxString& topic,
315 const wxString& item,
316 size_t *size,
317 wxIPCFormat format)
318{
319 *size = 0;
320
321 wxString s,
322 afterDate;
323 if ( item.StartsWith("Date", &afterDate) )
324 {
325 const wxDateTime now = wxDateTime::Now();
326
327 if ( afterDate.empty() )
328 {
329 s = now.Format();
330 *size = wxNO_LEN;
331 }
332 else if ( afterDate == "+len" )
333 {
334 s = now.FormatTime() + " " + now.FormatDate();
335 *size = strlen(s.mb_str()) + 1;
336 }
337 }
338 else if ( item == "bytes[3]" )
339 {
340 s = "123";
341 *size = 3;
342 }
343
344 if ( !*size )
345 {
346 wxLogMessage("Unknown request for \"%s\"", item);
347 return NULL;
348 }
349
350 // store the data pointer to which we return in a member variable to ensure
351 // that the pointer remains valid even after we return
352 m_requestData = s.mb_str();
353 const void * const data = m_requestData;
354 Log("OnRequest", topic, item, data, *size, format);
355 return data;
356}
357
358bool MyConnection::OnStartAdvise(const wxString& topic, const wxString& item)
359{
360 wxLogMessage("OnStartAdvise(\"%s\", \"%s\")", topic, item);
361 wxLogMessage("Returning true");
362 m_advise = item;
363 wxGetApp().GetFrame()->UpdateUI();
364 return true;
365}
366
367bool MyConnection::OnStopAdvise(const wxString& topic, const wxString& item)
368{
369 wxLogMessage("OnStopAdvise(\"%s\",\"%s\")", topic, item);
370 wxLogMessage("Returning true");
371 m_advise.clear();
372 wxGetApp().GetFrame()->UpdateUI();
373 return true;
374}
375
376bool
377MyConnection::DoAdvise(const wxString& item,
378 const void *data,
379 size_t size,
380 wxIPCFormat format)
381{
382 Log("Advise", "", item, data, size, format);
383 return wxConnection::DoAdvise(item, data, size, format);
384}
385
386bool MyConnection::OnDisconnect()
387{
388 wxLogMessage("OnDisconnect()");
389 wxGetApp().GetFrame()->Disconnect();
390 return true;
391}