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