|
From: <st...@us...> - 2003-06-17 22:53:31
|
Update of /cvsroot/iaxclient/iaxclient/simpleclient/wx
In directory sc8-pr-cvs1:/tmp/cvs-serv6863/simpleclient/wx
Modified Files:
wx.cc
Log Message:
Another big commit:
1) Replace the "RadioBox" control with a ListCntrl control, for the call
list. This has expandable columns, and displays each data type in it's
own column.
2) Some locking for the library: try to prevent us from doing the
processing loop while moving the calls around from the front-end.
3) REGISTRATION, and better incoming call support.
Incoming calls now are not auto-answered, but are answered when you
select them.
You can register with an IAX server (tested for IAX1 only so far).
Index: wx.cc
===================================================================
RCS file: /cvsroot/iaxclient/iaxclient/simpleclient/wx/wx.cc,v
retrieving revision 1.30
retrieving revision 1.31
diff -u -d -r1.30 -r1.31
--- wx.cc 17 Jun 2003 02:08:57 -0000 1.30
+++ wx.cc 17 Jun 2003 22:53:28 -0000 1.31
@@ -6,6 +6,8 @@
#endif
#include "wx/cmdline.h"
+#include "wx/listctrl.h"
+#include "wx/tokenzr.h"
#include "iaxclient.h"
@@ -72,8 +74,9 @@
ID_PTT = 300,
ID_MUTE,
ID_SILENCE,
+ ID_REGISTER,
- ID_CALLBOX = 400,
+ ID_CALLS = 400,
CALLBACK_STATUS = 1000,
CALLBACK_LEVELS,
@@ -93,6 +96,115 @@
};
+class IAXCalls : public wxListCtrl
+{
+ public:
+ IAXCalls(wxWindow *parent, int nCalls);
+ void IAXCalls::OnSelect(wxListEvent &evt);
+ int IAXCalls::OnStateCallback(struct iaxc_ev_call_state c);
+ inline void IAXCalls::AutoSize() {
+ for(int i=0;i<nCalls;i++)
+ SetColumnWidth(i,wxLIST_AUTOSIZE);
+ }
+
+ int nCalls;
+
+protected:
+ DECLARE_EVENT_TABLE()
+};
+
+BEGIN_EVENT_TABLE(IAXCalls, wxListCtrl)
+ EVT_LIST_ITEM_SELECTED(ID_CALLS, IAXCalls::OnSelect)
+END_EVENT_TABLE()
+
+IAXCalls::IAXCalls(wxWindow *parent, int inCalls)
+ : nCalls(inCalls),
+ wxListCtrl(parent, ID_CALLS,
+ wxDefaultPosition, wxDefaultSize, wxLC_REPORT|wxLC_SINGLE_SEL,
+ wxDefaultValidator, _T("calls"))
+{
+ // initialze IAXCalls control
+ long i;
+
+ wxListItem item;
+ item.m_mask = wxLIST_MASK_TEXT | wxLIST_MASK_IMAGE;
+ item.m_image = -1;
+ item.m_text = _T("Call");
+ InsertColumn(0, item);
+ item.m_text = _T("State");
+ InsertColumn(1, item);
+ item.m_text = _T("Remote");
+ InsertColumn(2, item);
+
+ Hide();
+ for(i=0;i<nCalls;i++) {
+ long tmp = InsertItem(i,wxString::Format("%d", i+1), 0);
+ // XXX ??? SetItemData(tmp,i);
+ SetItem(i, 2, _T("No call"));
+ }
+ Show();
+ AutoSize();
+}
+
+int IAXCalls::OnStateCallback(struct iaxc_ev_call_state c)
+{
+ if (!wxThread::IsMain()) wxMutexGuiEnter();
+
+ fprintf(stderr, "Updating state for item %d state=%x\n", c.callNo, c.state);
+
+
+ // first, handle inactive calls
+ if(!(c.state & IAXC_CALL_STATE_ACTIVE)) {
+ fprintf(stderr, "state for item %d is free\n", c.callNo);
+ SetItem(c.callNo, 2, _T("No call") );
+ SetItem(c.callNo, 1, _T("") );
+ } else {
+ // set remote
+ SetItem(c.callNo, 2, c.remote );
+
+ bool outgoing = c.state & IAXC_CALL_STATE_OUTGOING;
+ bool ringing = c.state & IAXC_CALL_STATE_RINGING;
+ bool complete = c.state & IAXC_CALL_STATE_COMPLETE;
+
+ if(outgoing) {
+ if(ringing)
+ SetItem(c.callNo, 1, _T("r") );
+ else if(complete)
+ SetItem(c.callNo, 1, _T("o") );
+ else // not accepted yet..
+ SetItem(c.callNo, 1, _T("c") );
+ } else {
+ if(ringing)
+ SetItem(c.callNo, 1, _T("R") );
+ else if(complete)
+ SetItem(c.callNo, 1, _T("I") );
+ else // not accepted yet.. shouldn't happen!
+ SetItem(c.callNo, 1, _T("C") );
+ }
+ // XXX do something more noticable if it's incoming, ringing!
+ }
+
+
+ // select if necessary
+ if((c.state & IAXC_CALL_STATE_SELECTED) &&
+ !(GetItemState(c.callNo,wxLIST_STATE_SELECTED|wxLIST_STATE_SELECTED)))
+ {
+ fprintf(stderr, "setting call %d to selected\n", c.callNo);
+ SetItemState(c.callNo,wxLIST_STATE_SELECTED,wxLIST_STATE_SELECTED);
+ }
+ AutoSize();
+ if (!wxThread::IsMain()) wxMutexGuiLeave();
+
+ return 0;
+}
+
+void IAXCalls::OnSelect(wxListEvent &evt) {
+ int selected = evt.m_itemIndex; //GetSelection();
+ fprintf(stderr, "User Selected item %d\n", selected);
+ iaxc_select_call(selected);
+}
+
+
class IAXFrame : public wxFrame
{
public:
@@ -106,8 +218,8 @@
void IAXFrame::OnQuit(wxEvent &evt);
void IAXFrame::OnPTTChange(wxCommandEvent &evt);
void IAXFrame::OnSilenceChange(wxCommandEvent &evt);
- void IAXFrame::OnCallBoxSelect(wxCommandEvent &evt);
void IAXFrame::OnNotify(void);
+ void IAXFrame::OnRegisterMenu(wxCommandEvent &evt);
bool IAXFrame::GetPTTState();
@@ -120,7 +232,7 @@
wxTextCtrl *iaxDest;
wxStaticText *muteState;
- wxRadioBox *callBox;
+ IAXCalls *calls;
bool pttMode; // are we in PTT mode?
bool pttState; // is the PTT button pressed?
@@ -202,9 +314,18 @@
/* NOTE: Mac doesn't use a File/Exit item, and Application/Quit is
automatically added for us */
-#ifndef __WXMAC__
wxMenu *fileMenu = new wxMenu();
+ fileMenu->Append(ID_REGISTER, _T("&Register\tCtrl-R"));
+
+// Mac: no quit item (it goes in app menu)
+// Win: "exit" item.
+// Linux and others: Quit.
+#if !defined(__WXMAC__)
+#if defined(__WXMSW__)
fileMenu->Append(ID_QUIT, _T("E&xit\tCtrl-X"));
+#else
+ fileMenu->Append(ID_QUIT, _T("&Quit\tCtrl-Q"));
+#endif
#endif
wxMenu *optionsMenu = new wxMenu();
@@ -256,22 +377,12 @@
// Add call appearances
if(wxGetApp().optNumCalls > 1) {
- int i;
int nCalls = wxGetApp().optNumCalls;
- wxString *labels = new wxString[nCalls];
- for(i=0;i<nCalls;i++)
- labels[i] = wxString::Format("%d: No Call", i);
-
- callBox = new wxRadioBox(aPanel, ID_CALLBOX, _T("Calls"),
- wxDefaultPosition, wxDefaultSize,
- nCalls, labels,
- 1, wxRA_SPECIFY_COLS);
-
- topsizer->Add(callBox, 0, wxEXPAND);
-
+ topsizer->Add(calls = new IAXCalls(this, nCalls), 1, wxEXPAND);
}
+
/* Destination */
topsizer->Add(iaxDest = new wxTextCtrl(aPanel, -1, _T("guest@ast1/8068"),
wxDefaultPosition, wxDefaultSize),0,wxEXPAND);
@@ -383,6 +494,34 @@
exit(0);
}
+void IAXFrame::OnRegisterMenu(wxCommandEvent &evt) {
+ wxTextEntryDialog dialog(this,
+ _T("Register with a remote asterisk server"),
+ _T("Format is user:password@hostname"),
+ _T("iaxuser:iaxpass@ast1"),
+ wxOK | wxCANCEL);
+
+ if(dialog.ShowModal() == wxID_OK)
+ {
+ wxString value = dialog.GetValue();
+ wxStringTokenizer tok(value, _T(":@"));
+ char user[256], pass[256], host[256];
+
+ if(tok.CountTokens() != 3) {
+ theFrame->SetStatusText("error in registration format");
+ return;
+ }
+
+ strncpy( user , tok.GetNextToken().c_str(), 256);
+ strncpy( pass , tok.GetNextToken().c_str(), 256);
+ strncpy( host , tok.GetNextToken().c_str(), 256);
+
+ fprintf(stderr, "Registering user %s pass %s host %s\n",
+ user, pass, host);
+ iaxc_register(user, pass, host);
+ }
+}
+
void IAXFrame::OnPTTChange(wxCommandEvent &evt)
{
pttMode = evt.IsChecked();
@@ -415,10 +554,6 @@
}
}
-void IAXFrame::OnCallBoxSelect(wxCommandEvent &evt) {
- int selected = evt.GetSelection();
- iaxc_select_call(selected);
-}
BEGIN_EVENT_TABLE(IAXFrame, wxFrame)
@@ -440,8 +575,8 @@
EVT_MENU(ID_QUIT,IAXFrame::OnQuit)
EVT_MENU(ID_PTT,IAXFrame::OnPTTChange)
EVT_MENU(ID_SILENCE,IAXFrame::OnSilenceChange)
+ EVT_MENU(ID_REGISTER,IAXFrame::OnRegisterMenu)
- EVT_RADIOBOX(ID_CALLBOX, IAXFrame::OnCallBoxSelect)
END_EVENT_TABLE()
@@ -588,47 +723,6 @@
return 1;
}
- int state_callback(struct iaxc_ev_call_state c)
- {
- wxString label;
-
- label += wxString::Format("%d: ", c.callNo);
-
- if(!(c.state & IAXC_CALL_STATE_ACTIVE)) {
- label += _T("No Call");
- } else {
- if(c.state & IAXC_CALL_STATE_COMPLETE)
- if(c.state & IAXC_CALL_STATE_OUTGOING)
- label += _T("O");
- else
- label += _T("I");
- else
- if(c.state & IAXC_CALL_STATE_OUTGOING)
- label += _T("o");
- else
- label += _T("i");
-
- label += wxString::Format(" %s", c.remote);
- }
-
- if (!wxThread::IsMain()) wxMutexGuiEnter();
-#if 0
-#ifdef __WXMSW__
- // XXX figure out why MSW has this problem figuring out which method
- // to call...
- theFrame->callBox->wxRadioBoxBase::SetLabel(c.callNo, label);
-#else
- theFrame->callBox->SetLabel(c.callNo, label);
-#endif
-#endif
- theFrame->callBox->SetString(c.callNo, label);
- if((c.state & IAXC_CALL_STATE_SELECTED) &&
- (theFrame->callBox->GetSelection() != c.callNo))
- theFrame->callBox->SetSelection(c.callNo);
- if (!wxThread::IsMain()) wxMutexGuiLeave();
-
- return 0;
- }
int iaxc_callback(iaxc_event e)
{
@@ -638,7 +732,7 @@
case IAXC_EVENT_TEXT:
return status_callback(e.ev.text.message);
case IAXC_EVENT_STATE:
- return state_callback(e.ev.call);
+ return theFrame->calls->OnStateCallback(e.ev.call);
default:
return 0; // not handled
}
|