Added the keepalive loop.
LFLAGS=`wx-config --libs`
daphne: main.o citclient.o userlogin.o testwindow.o who.o \
- utils.o tcp_sockets.o
+ utils.o tcp_sockets.o express_message.o
c++ main.o citclient.o userlogin.o testwindow.o who.o \
- utils.o tcp_sockets.o \
+ utils.o tcp_sockets.o express_message.o \
$(LFLAGS) -o daphne
main.o: main.cpp
tcp_sockets.o: tcp_sockets.cpp tcp_sockets.hpp
c++ -c $(CFLAGS) tcp_sockets.cpp
+
+express_message.o: express_message.cpp express_message.hpp
+ c++ -c $(CFLAGS) express_message.cpp
#include <wx/wx.h>
#include "citclient.hpp"
+#include "express_message.hpp"
+#include "utils.h"
//
}
-// constructur
+// constructor
CitClient::CitClient(void) {
+ (void)new keepalive(this);
}
// destructor
CitClient::~CitClient(void) {
-
// Be nice and log out from the server if it's still connected
sock.detach();
}
serv_puts("000");
}
-
if (express_messages_waiting) {
- // FIX do something here
+ download_express_messages();
}
return first_digit;
}
}
}
+
+
+
+void CitClient::download_express_messages(void) {
+ wxString sendcmd, recvcmd, x_user, x_sys;
+ wxStringList xferbuf;
+
+ sendcmd = "GEXP";
+ while (serv_trans(sendcmd, recvcmd, xferbuf) == 1) {
+ extract(x_user, recvcmd, 3);
+ extract(x_sys, recvcmd, 4);
+ (void)new express_message(this, x_user, x_sys, xferbuf);
+ }
+}
+
+
+
+// This is a simple timer that periodically wakes up and sends a NOOP to the
+// server. This accomplishes two things: it keeps the server connection
+// alive by trickling some data through when it's otherwise idle, and it allows
+// the "check for express messages" loop to activate if it has to.
+
+keepalive::keepalive(CitClient *sock)
+ : wxTimer() {
+
+ which_sock = sock; // Know which instance to refresh
+ Start(15000, FALSE); // Call every 15 seconds
+}
+
+
+void keepalive::Notify(void) {
+ if (which_sock->IsConnected()) {
+ which_sock->serv_trans("NOOP");
+ }
+}
+
+
+
+
+
+
private:
void serv_gets(wxString& buf);
void serv_puts(wxString buf);
+ void download_express_messages(void);
TCPsocket sock;
void CitClient::initialize_session(void);
};
+
+
+// This is a timer that does keepalives...
+class keepalive : public wxTimer {
+public:
+ keepalive(CitClient *sock);
+private:
+ CitClient *which_sock;
+ void Notify(void);
+};
+
+
+
--- /dev/null
+// ============================================================================
+// declarations
+// ============================================================================
+
+
+#include <wx/wx.h>
+#include <wx/listctrl.h>
+#include "citclient.hpp"
+#include "express_message.hpp"
+#include "utils.h"
+
+// ----------------------------------------------------------------------------
+// private classes
+// ----------------------------------------------------------------------------
+
+// ----------------------------------------------------------------------------
+// constants
+// ----------------------------------------------------------------------------
+
+// IDs for the controls and the menu commands
+enum
+{
+ BUTTON_OK,
+ BUTTON_REPLY
+};
+
+// ----------------------------------------------------------------------------
+// event tables and other macros for wxWindows
+// ----------------------------------------------------------------------------
+
+// the event tables connect the wxWindows events with the functions (event
+// handlers) which process them. It can be also done at run-time, but for the
+// simple menu events like this the static method is much simpler.
+BEGIN_EVENT_TABLE( express_message, wxFrame)
+ EVT_BUTTON( BUTTON_OK, express_message::OnButtonPressed)
+END_EVENT_TABLE()
+
+// ============================================================================
+// implementation
+// ============================================================================
+
+
+// ----------------------------------------------------------------------------
+// the application class
+// ----------------------------------------------------------------------------
+
+// frame constructor
+express_message::express_message(
+ CitClient *sock,
+ wxString sender,
+ wxString sendsys,
+ wxStringList msg)
+ : wxFrame(
+ NULL, //parent
+ -1, //window id
+ "Express message",
+ wxDefaultPosition,
+ wxSize(500, 200),
+ wxDEFAULT_FRAME_STYLE,
+ "express_message"
+ ) {
+
+ wxString more_informative_title;
+ wxString stringized_message;
+
+ citsock = sock;
+
+ ListToMultiline(stringized_message, msg);
+
+ // set the frame icon
+ /* SetIcon(wxICON(mondrian)); */
+
+ more_informative_title =
+ "Express message from " + sender + " @ " + sendsys + "..." ;
+
+ SetTitle(more_informative_title);
+
+ wxButton *ok_button = new wxButton(
+ this,
+ BUTTON_OK,
+ " OK ",
+ wxPoint(100,100),
+ wxSize(100,30),
+ 0L,
+ wxDefaultValidator,
+ "ok_button"
+ );
+
+ wxButton *reply_button = new wxButton(
+ this,
+ BUTTON_REPLY,
+ " Reply ",
+ wxPoint(100,100),
+ wxSize(100,30),
+ 0L,
+ wxDefaultValidator,
+ "reply_button"
+ );
+
+ wxTextCtrl *msgbox = new wxTextCtrl(
+ this,
+ -1,
+ stringized_message,
+ wxDefaultPosition,
+ wxDefaultSize,
+ wxTE_MULTILINE | wxTE_READONLY,
+ wxDefaultValidator,
+ "msgbox"
+ );
+
+ wxLayoutConstraints *c0 = new wxLayoutConstraints;
+ c0->bottom.SameAs(this, wxBottom, 10);
+ c0->left.SameAs(this, wxLeft, 10);
+ c0->height.AsIs(); c0->width.AsIs();
+ ok_button->SetConstraints(c0);
+
+ wxLayoutConstraints *c1 = new wxLayoutConstraints;
+ c1->bottom.SameAs(this, wxBottom, 10);
+ c1->right.SameAs(this, wxRight, 10);
+ c1->height.AsIs(); c1->width.AsIs();
+ reply_button->SetConstraints(c1);
+
+ wxLayoutConstraints *c2 = new wxLayoutConstraints;
+ c2->top.SameAs(this, wxTop, 10);
+ c2->left.SameAs(this, wxLeft, 10);
+ c2->right.SameAs(this, wxRight, 10);
+ c2->bottom.Above(ok_button, -10);
+ msgbox->SetConstraints(c2);
+
+ SetAutoLayout(TRUE);
+ Show(TRUE);
+
+}
+
+
+void express_message::OnButtonPressed(wxCommandEvent& whichbutton) {
+ if (whichbutton.GetId() == BUTTON_OK) {
+ delete this;
+ }
+}
--- /dev/null
+class express_message : public wxFrame {
+public:
+ express_message(CitClient *sock, wxString sender,
+ wxString sendsys, wxStringList msg);
+private:
+ void OnButtonPressed(wxCommandEvent& whichbutton);
+ CitClient *citsock;
+ DECLARE_EVENT_TABLE()
+};
menuFile->AppendSeparator();
menuFile->Append(IG_Quit, "E&xit");
+ wxMenu *menuEdit = new wxMenu;
+
wxMenu *menuWindow = new wxMenu;
menuWindow->Append(WMENU_CASCADE, "&Cascade");
menuWindow->Append(WMENU_TILE, "&Tile");
// now append the freshly created menu to the menu bar...
wxMenuBar *menuBar = new wxMenuBar;
menuBar->Append(menuFile, "&File");
+ menuBar->Append(menuEdit, "&Edit");
menuBar->Append(menuWindow, "&Window");
menuBar->Append(menuHelp, "&Help");