X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/39d580f7dcc48a85d092f6088f8c978a18db5a97..fcd209b6a20b41e7ddf9acf837311ac6779ea41f:/samples/ipc/server.cpp?ds=sidebyside diff --git a/samples/ipc/server.cpp b/samples/ipc/server.cpp index f278b704e8..4bd26352a2 100644 --- a/samples/ipc/server.cpp +++ b/samples/ipc/server.cpp @@ -2,7 +2,7 @@ // Name: server.cpp // Purpose: IPC sample: server // Author: Julian Smart -// Modified by: +// Modified by: Jurgen Doornik // Created: 25/01/99 // RCS-ID: $Id$ // Copyright: (c) Julian Smart @@ -30,13 +30,15 @@ // Settings common to both executables: determines whether // we're using TCP/IP or real DDE. -#include "ddesetup.h" +#include "ipcsetup.h" -#if defined(__WXGTK__) || defined(__WXX11__) || defined(__WXMOTIF__) || defined(__WXMAC__) - #include "mondrian.xpm" +#if !defined(__WXMSW__) && !defined(__WXPM__) + #include "../sample.xpm" #endif #include "server.h" +#include "wx/textdlg.h" +#include "wx/datetime.h" // ---------------------------------------------------------------------------- // wxWin macros @@ -45,20 +47,14 @@ IMPLEMENT_APP(MyApp) BEGIN_EVENT_TABLE(MyFrame, wxFrame) - EVT_MENU (SERVER_EXIT, MyFrame::OnExit) - EVT_LISTBOX(SERVER_LISTBOX, MyFrame::OnListBoxClick) -END_EVENT_TABLE() + EVT_CLOSE( MyFrame::OnClose ) -BEGIN_EVENT_TABLE(IPCDialogBox, wxDialog) - EVT_BUTTON(SERVER_QUIT_BUTTON, IPCDialogBox::OnQuit) + EVT_BUTTON( ID_START, MyFrame::OnStart ) + EVT_CHOICE( ID_SERVERNAME, MyFrame::OnServerName ) + EVT_BUTTON( ID_DISCONNECT, MyFrame::OnDisconnect ) + EVT_BUTTON( ID_ADVISE, MyFrame::OnAdvise ) END_EVENT_TABLE() -// ---------------------------------------------------------------------------- -// global variables -// ---------------------------------------------------------------------------- - -char ipc_buffer[4000]; -MyConnection *the_connection = NULL; // ============================================================================ // implementation @@ -70,27 +66,14 @@ MyConnection *the_connection = NULL; bool MyApp::OnInit() { - // Create the main frame window - (new MyFrame(NULL, "Server"))->Show(TRUE); - - // service name (DDE classes) or port number (TCP/IP based classes) - wxString service = "4242"; - - if (argc > 1) - service = argv[1]; - - // Create a new server - m_server = new MyServer; - m_server->Create(service); - - return TRUE; -} + if ( !wxApp::OnInit() ) + return false; -int MyApp::OnExit() -{ - delete m_server; + // Create the main frame window + m_frame = new MyFrame(NULL, "Server"); + m_frame->Show(true); - return 0; + return true; } // ---------------------------------------------------------------------------- @@ -99,138 +82,316 @@ int MyApp::OnExit() // Define my frame constructor MyFrame::MyFrame(wxFrame *frame, const wxString& title) - : wxFrame(frame, -1, title, wxDefaultPosition, wxSize(350, 250)) + : wxFrame(frame, wxID_ANY, title, wxDefaultPosition, wxSize(400, 300)) { +#if wxUSE_STATUSBAR CreateStatusBar(); +#endif // wxUSE_STATUSBAR + + SetIcon(wxICON(sample)); + + m_server = NULL; + + wxPanel * const panel = new wxPanel(this); + + wxBoxSizer * const sizerMain = new wxBoxSizer( wxVERTICAL ); + + wxFlexGridSizer * const sizerCmds = new wxFlexGridSizer( 2, 0, 0 ); + sizerCmds->AddGrowableCol( 1 ); + + wxButton *btn; + + btn = new wxButton(panel, ID_START, "&Start Server"); + sizerCmds->Add(btn, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5); + + const wxString choices[] = { IPC_SERVICE, "..." }; + wxChoice * const choice = new wxChoice + ( + panel, + ID_SERVERNAME, + wxDefaultPosition, wxSize(100, -1), + WXSIZEOF(choices), choices + ); + sizerCmds->Add(choice, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5); - // Give it an icon - SetIcon(wxICON(mondrian)); + btn = new wxButton(panel, ID_DISCONNECT, "&Disconnect Client"); + sizerCmds->Add(btn, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5); + sizerCmds->AddSpacer(20); - // Make a menubar - wxMenu *file_menu = new wxMenu; + btn = new wxButton( panel, ID_ADVISE, "&Advise"); + sizerCmds->Add(btn, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5); + sizerCmds->AddSpacer(20); - file_menu->Append(SERVER_EXIT, "&Quit\tCtrl-Q"); + sizerMain->Add(sizerCmds, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5); - wxMenuBar *menu_bar = new wxMenuBar; + wxStaticBoxSizer * const + sizerLog = new wxStaticBoxSizer(wxVERTICAL, panel, "Server &log"); - menu_bar->Append(file_menu, "&File"); + wxTextCtrl * const textLog = new wxTextCtrl + ( + panel, + wxID_ANY, + "", + wxDefaultPosition, wxSize(500, 140), + wxTE_MULTILINE + ); + sizerLog->Add(textLog, 1, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5); - // Associate the menu bar with the frame - SetMenuBar(menu_bar); + sizerMain->Add(sizerLog, 1, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5); - // Make a listbox - wxListBox *list = new wxListBox(this, SERVER_LISTBOX, wxPoint(5, 5)); - list->Append("Apple"); - list->Append("Pear"); - list->Append("Orange"); - list->Append("Banana"); - list->Append("Fruit"); + panel->SetSizer(sizerMain); + sizerMain->SetSizeHints(panel); + SetClientSize(panel->GetSize()); + + GetServername()->SetSelection(0); + wxLogTextCtrl *logWindow = new wxLogTextCtrl(textLog); + delete wxLog::SetActiveTarget(logWindow); + wxLogMessage("Click on Start to start the server"); + UpdateUI(); +} + +void MyFrame::UpdateUI() +{ + GetStart()->Enable(m_server == NULL); + GetServername()->Enable(m_server == NULL); + GetAdvise()->Enable(m_server && m_server->CanAdvise()); + GetDisconnect()->Enable(m_server && m_server->IsConnected()); +} + +void MyFrame::OnClose(wxCloseEvent& event) +{ + if (m_server) + { + delete m_server; + m_server = NULL; + } + event.Skip(); +} + +void MyFrame::OnStart(wxCommandEvent& WXUNUSED(event)) +{ + // Create a new server + m_server = new MyServer; + wxString servername = GetServername()->GetStringSelection(); + if (m_server->Create(servername)) + { + wxLogMessage("Server %s started", servername); + #if wxUSE_DDE_FOR_IPC + wxLogMessage("Server uses DDE"); + #else // !wxUSE_DDE_FOR_IPC + wxLogMessage("Server uses TCP"); + #endif // wxUSE_DDE_FOR_IPC/!wxUSE_DDE_FOR_IPC + } + else + { + wxLogMessage("Server %s failed to start", servername); + delete m_server; + m_server = NULL; + } + UpdateUI(); } -// Set the client process's listbox to this item -void MyFrame::OnListBoxClick(wxCommandEvent& WXUNUSED(event)) +void MyFrame::OnServerName( wxCommandEvent& WXUNUSED(event) ) { - wxListBox* listBox = (wxListBox*) FindWindow(SERVER_LISTBOX); - if (listBox) + if ( GetServername()->GetStringSelection() == "..." ) { - wxString value = listBox->GetStringSelection(); - if (the_connection) + wxString s = wxGetTextFromUser + ( + "Specify the name of the server", + "Server Name", + "", + this + ); + + if ( !s.empty() && s != IPC_SERVICE ) { - the_connection->Advise("Item", (wxChar *)value.c_str()); + GetServername()->Insert(s, 0); + GetServername()->SetSelection(0); } } } -void MyFrame::OnExit(wxCommandEvent& WXUNUSED(event)) +void MyFrame::Disconnect() { - Close(TRUE); + m_server->Disconnect(); + UpdateUI(); } -// ---------------------------------------------------------------------------- -// IPCDialogBox -// ---------------------------------------------------------------------------- - -IPCDialogBox::IPCDialogBox(wxWindow *parent, const wxString& title, - const wxPoint& pos, const wxSize& size, - MyConnection *connection) - : wxDialog(parent, -1, title, pos, size) +void MyFrame::OnDisconnect(wxCommandEvent& WXUNUSED(event)) { - m_connection = connection; - (void)new wxButton(this, SERVER_QUIT_BUTTON, "Quit this connection", - wxPoint(5, 5)); - Fit(); + Disconnect(); } -void IPCDialogBox::OnQuit(wxCommandEvent& event) +void MyFrame::OnAdvise(wxCommandEvent& WXUNUSED(event)) { - m_connection->Disconnect(); - delete m_connection; + m_server->Advise(); } // ---------------------------------------------------------------------------- // MyServer // ---------------------------------------------------------------------------- +MyServer::MyServer() : wxServer() +{ + m_connection = NULL; +} + +MyServer::~MyServer() +{ + Disconnect(); +} + wxConnectionBase *MyServer::OnAcceptConnection(const wxString& topic) { - if (strcmp(topic, "STDIO") != 0 && strcmp(topic, "IPC TEST") == 0) - return new MyConnection(ipc_buffer, WXSIZEOF(ipc_buffer)); - else - return NULL; + wxLogMessage("OnAcceptConnection(\"%s\")", topic); + + if ( topic == IPC_TOPIC ) + { + m_connection = new MyConnection(); + wxGetApp().GetFrame()->UpdateUI(); + wxLogMessage("Connection accepted"); + return m_connection; + } + //else: unknown topic + + wxLogMessage("Unknown topic, connection refused"); + return NULL; +} + +void MyServer::Disconnect() +{ + if ( m_connection ) + { + delete m_connection; + m_connection = NULL; + wxGetApp().GetFrame()->UpdateUI(); + wxLogMessage("Disconnected client"); + } +} + +void MyServer::Advise() +{ + if ( CanAdvise() ) + { + const wxDateTime now = wxDateTime::Now(); + + m_connection->Advise(m_connection->m_advise, now.Format()); + + const wxString s = now.FormatTime() + " " + now.FormatDate(); + m_connection->Advise(m_connection->m_advise, s.mb_str(), wxNO_LEN); + +#if wxUSE_DDE_FOR_IPC + wxLogMessage("DDE Advise type argument cannot be wxIPC_PRIVATE. " + "The client will receive it as wxIPC_TEXT, " + " and receive the correct no of bytes, " + "but not print a correct log entry."); +#endif + char bytes[3] = { '1', '2', '3' }; + m_connection->Advise(m_connection->m_advise, bytes, 3, wxIPC_PRIVATE); + } } // ---------------------------------------------------------------------------- // MyConnection // ---------------------------------------------------------------------------- -MyConnection::MyConnection(char *buf, int size) - : wxConnection(buf, size) +bool +MyConnection::OnExecute(const wxString& topic, + const void *data, + size_t size, + wxIPCFormat format) { - dialog = new IPCDialogBox(wxTheApp->GetTopWindow(), "Connection", - wxPoint(100, 100), wxSize(500, 500), this); - dialog->Show(TRUE); - the_connection = this; + Log("OnExecute", topic, "", data, size, format); + return true; } -MyConnection::~MyConnection() +bool +MyConnection::OnPoke(const wxString& topic, + const wxString& item, + const void *data, + size_t size, + wxIPCFormat format) { - if (the_connection) + Log("OnPoke", topic, item, data, size, format); + return wxConnection::OnPoke(topic, item, data, size, format); +} + +const void * +MyConnection::OnRequest(const wxString& topic, + const wxString& item, + size_t *size, + wxIPCFormat format) +{ + *size = 0; + + wxString s, + afterDate; + if ( item.StartsWith("Date", &afterDate) ) { - dialog->Destroy(); - the_connection = NULL; + const wxDateTime now = wxDateTime::Now(); + + if ( afterDate.empty() ) + { + s = now.Format(); + *size = wxNO_LEN; + } + else if ( afterDate == "+len" ) + { + s = now.FormatTime() + " " + now.FormatDate(); + *size = strlen(s.mb_str()) + 1; + } + } + else if ( item == "bytes[3]" ) + { + s = "123"; + *size = 3; + } + + if ( !*size ) + { + wxLogMessage("Unknown request for \"%s\"", item); + return NULL; } + + // store the data pointer to which we return in a member variable to ensure + // that the pointer remains valid even after we return + m_requestData = s.mb_str(); + const void * const data = m_requestData; + Log("OnRequest", topic, item, data, *size, format); + return data; } -bool MyConnection::OnExecute(const wxString& WXUNUSED(topic), - char *data, - int WXUNUSED(size), - wxIPCFormat WXUNUSED(format)) +bool MyConnection::OnStartAdvise(const wxString& topic, const wxString& item) { - wxLogStatus("Execute command: %s", data); - return TRUE; + wxLogMessage("OnStartAdvise(\"%s\", \"%s\")", topic, item); + wxLogMessage("Returning true"); + m_advise = item; + wxGetApp().GetFrame()->UpdateUI(); + return true; } -bool MyConnection::OnPoke(const wxString& WXUNUSED(topic), - const wxString& item, - char *data, - int WXUNUSED(size), - wxIPCFormat WXUNUSED(format)) +bool MyConnection::OnStopAdvise(const wxString& topic, const wxString& item) { - wxLogStatus("Poke command: %s = %s", item.c_str(), data); - return TRUE; + wxLogMessage("OnStopAdvise(\"%s\",\"%s\")", topic, item); + wxLogMessage("Returning true"); + m_advise.clear(); + wxGetApp().GetFrame()->UpdateUI(); + return true; } -char *MyConnection::OnRequest(const wxString& WXUNUSED(topic), - const wxString& WXUNUSED(item), - int * WXUNUSED(size), - wxIPCFormat WXUNUSED(format)) +bool +MyConnection::DoAdvise(const wxString& item, + const void *data, + size_t size, + wxIPCFormat format) { - return "Here, have your data, client!"; + Log("Advise", "", item, data, size, format); + return wxConnection::DoAdvise(item, data, size, format); } -bool MyConnection::OnStartAdvise(const wxString& WXUNUSED(topic), - const wxString& WXUNUSED(item)) +bool MyConnection::OnDisconnect() { - return TRUE; + wxLogMessage("OnDisconnect()"); + wxGetApp().GetFrame()->Disconnect(); + return true; } -