Added skinnable Gtk2 client.

git-svn-id: http://voip.null.ro/svn/yate@429 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
paulc 2005-07-04 22:04:47 +00:00
parent 51b90b8a69
commit 42ce026bdb
19 changed files with 2518 additions and 7 deletions

View File

@ -20,7 +20,7 @@ MKDEPS := ./config.status
PROGS:= yate
YLIB := libyate.so.@PACKAGE_VERSION@
SLIBS:= $(YLIB) libyate.so
INCS := yateclass.h yatengine.h yatephone.h
INCS := yateclass.h yatengine.h yatephone.h yatecbase.h
GENS := yateversn.h
LIBS :=
MAN8 := yate.8 yate-config.8
@ -86,7 +86,9 @@ apidocs-build: check-topdir
apidocs: @srcdir@/docs/api/index.html
@srcdir@/docs/api/index.html: @srcdir@/yateclass.h @srcdir@/yatengine.h @srcdir@/yatephone.h @srcdir@/contrib/ysip/yatesip.h @srcdir@/contrib/yrtp/yatertp.h
@srcdir@/docs/api/index.html: @srcdir@/yateclass.h @srcdir@/yatengine.h \
@srcdir@/yatephone.h @srcdir@/yatecbase.h \
@srcdir@/contrib/ysip/yatesip.h @srcdir@/contrib/yrtp/yatertp.h
$(MAKE) apidocs-build
.PHONY: strip sex love war

View File

@ -29,6 +29,10 @@ ifneq (@HAVE_QT@,no)
PROGS := $(PROGS) yate-qt
endif
ifneq (@HAVE_GTK2@,no)
PROGS := $(PROGS) yate-gtk2
endif
LOCALFLAGS =
LOCALLIBS =
COMPILE = $(CXX) $(DEFS) $(DEBUG) $(INCLUDES) $(CFLAGS)
@ -86,9 +90,16 @@ yate-%: @srcdir@/main-%.cpp $(MKDEPS) ../libyate.so $(INCFILES)
yate-gtk: LOCALFLAGS = @GTK_INC@
yate-gtk: LOCALLIBS = @GTK_LIB@
yate-gtk2: ../contrib/gtk2/libgtk2client.a
yate-gtk2: LOCALFLAGS = @GTK2_INC@
yate-gtk2: LOCALLIBS = ../contrib/gtk2/libgtk2client.a @GTK2_LIB@
yate-qt: ../contrib/qt/libqtclientform.a
yate-qt: LOCALFLAGS = -I@QT_INC@
yate-qt: LOCALLIBS = ../contrib/qt/libqtclientform.a -L@QT_DIR@/lib -lqt-mt
../contrib/qt/libqtclientform.a:
$(MAKE) -C ../contrib/qt
../contrib/gtk2/libgtk2client.a:
$(MAKE) -C ../contrib/gtk2

43
clients/main-gtk2.cpp Normal file
View File

@ -0,0 +1,43 @@
/**
* main-gtk2.cpp
* This file is part of the YATE Project http://YATE.null.ro
*
* A Gtk-2 based universal telephony client
*
* Yet Another Telephony Engine - a fully featured software PBX and IVR
* Copyright (C) 2004, 2005 Null Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <yatephone.h>
#include <gtk/gtk.h>
#include "../contrib/gtk2/gtk2client.h"
using namespace TelEngine;
static GTKDriver gtkdriver;
extern "C" int main(int argc, const char** argv, const char** environ)
{
g_thread_init(NULL);
gdk_threads_init();
bool fail = !gtk_init_check(&argc,(char ***)&argv);
if (fail)
g_warning("Cannot open display: '%s'",gdk_get_display());
TelEngine::Engine::extraPath() = "gtk2";
return TelEngine::Engine::main(argc,argv,environ,TelEngine::Engine::Client,fail);
}
/* vi: set ts=8 sw=4 sts=4 noet: */

11
clients/run-gtk2 Executable file
View File

@ -0,0 +1,11 @@
#!/bin/sh
# Script to run the Gtk2 client from the build directory
if [ -x yate-gtk2 -a -x ../run ]; then
# Need to put the path to Mozilla libraries here
export LD_LIBRARY_PATH=/usr/lib/mozilla-1.6
cd ..; exec ./run --executable clients/yate-gtk2 "$@"
else
echo "Could not find client executable or run script" >&2
fi

View File

@ -203,6 +203,21 @@ fi
AC_SUBST(HAVE_GSM)
AC_SUBST(GSM_INC)
HAVE_ILBC=no
AC_ARG_ENABLE(ilbc,AC_HELP_STRING([--enable-ilbc],[Enable iLBC codec]),want_ilbc=$enableval,want_ilbc=yes)
if [[ "x$want_ilbc" = "xyes" ]]; then
HAVE_ILBC=yes
fi
AC_MSG_CHECKING([for iLBC in contrib])
inci10="contrib/ilbc"
if [[ -f "$basedir/$inci10/iLBC_encode.h" ]]; then
HAVE_ILBC=yes
ILBC_INC="-I$basedir/$inci2"
ILBC_DEP="../$inci2/libiax.a"
fi
AC_MSG_RESULT([$HAVE_ILBC])
AC_SUBST(HAVE_ILBC)
HAVE_PWLIB=no
PWLIB_RTTI=none
PWLIB_INC=""
@ -465,6 +480,49 @@ AC_SUBST(HAVE_GTK)
AC_SUBST(GTK_INC)
AC_SUBST(GTK_LIB)
HAVE_GTK2=no
GTK2_INC=""
GTK2_LIB=""
AC_ARG_WITH(libgtk2,AC_HELP_STRING([--with-libgtk2],[use Gtk for graphical clients (default)]),[ac_cv_use_libgtk2=$withval],[ac_cv_use_libgtk2=yes])
if [[ "x$ac_cv_use_libgtk2" = "xyes" ]]; then
AC_MSG_CHECKING([for Gtk2 using pkg-config])
vergt=`pkg-config --modversion gtk+-2.0 2>/dev/null`
incgt=`pkg-config --cflags gtk+-2.0 gthread-2.0 2>/dev/null`
libgt=`pkg-config --libs gtk+-2.0 gthread-2.0 2>/dev/null`
if [[ "x$incgt" != "x" -a "x$libgt" != "x" ]]; then
HAVE_GTK2=yes
GTK2_INC="$incgt"
GTK2_LIB="$libgt"
ac_cv_use_libgtk2="no"
fi
AC_MSG_RESULT([$vergt])
fi
AC_SUBST(HAVE_GTK2)
AC_SUBST(GTK2_INC)
AC_SUBST(GTK2_LIB)
HAVE_GMOZ=no
GMOZ_INC=""
GMOZ_LIB=""
AC_ARG_WITH(gtkmozilla,AC_HELP_STRING([--with-gtkmozilla],[use Mozilla embedded in Gtk clients (default)]),[ac_cv_use_gtkmozilla=$withval],[ac_cv_use_gtkmozilla=yes])
if [[ "x$ac_cv_use_gtkmozilla" = "xyes" ]]; then
AC_MSG_CHECKING([for Gtk Mozilla embedding using pkg-config])
vergmoz=`pkg-config --modversion mozilla-gtkmozembed 2>/dev/null`
incgmoz=`pkg-config --cflags mozilla-gtkmozembed 2>/dev/null`
libgmoz=`pkg-config --libs mozilla-gtkmozembed 2>/dev/null`
if [[ "x$incgmoz" != "x" -a "x$libgmoz" != "x" ]]; then
HAVE_GMOZ=yes
GMOZ_INC="$incgmoz"
GMOZ_LIB="$libgmoz"
ac_cv_use_gtkmozilla="no"
fi
AC_MSG_RESULT([$vergmoz])
fi
AC_SUBST(HAVE_GMOZ)
AC_SUBST(GMOZ_INC)
AC_SUBST(GMOZ_LIB)
HAVE_QT=no
QT_DIR=""
QT_INC=""
@ -552,6 +610,7 @@ AC_CONFIG_FILES([yate.spec
contrib/ysip/Makefile
contrib/yrtp/Makefile
contrib/qt/Makefile
contrib/gtk2/Makefile
test/Makefile])
AC_CONFIG_FILES([yate-config],[chmod +x yate-config])
AC_CONFIG_FILES([run],[chmod +x run])

7
contrib/gtk2/.cvsignore Normal file
View File

@ -0,0 +1,7 @@
Makefile
core*
*.o
*.a
*.orig
*~
.*.swp

38
contrib/gtk2/Makefile.in Normal file
View File

@ -0,0 +1,38 @@
# Makefile
# This file holds the make rules for the Gtk2 client support
CXX := @CXX@ -Wall
AR := ar
DEFS:=
INCLUDES:=-I. -I@srcdir@ -I@top_srcdir@ @GTK2_INC@
CXXFLAGS:=$(CXXFLAGS) @MODULE_CPPFLAGS@ @INLINE_FLAGS@
LDFLAGS:= -L../.. -lyate
INCFILES := @top_srcdir@/yateclass.h @top_srcdir@/yatecbase.h @srcdir@/gtk2client.h
MODFLAGS:= @MODULE_LDFLAGS@
MODSTRIP:= @MODULE_SYMBOLS@
PROJECT = libgtk2client.a
SOURCES = gtk2client.cpp
OBJECTS = $(SOURCES:.cpp=.o)
COMPILE = $(CXX) $(DEFS) $(INCLUDES) $(CXXFLAGS)
prefix = @prefix@
exec_prefix = @exec_prefix@
.PHONY: all clean
all: $(PROJECT)
clean:
@-$(RM) $(PROJECT) $(OBJECTS)
$(PROJECT): $(OBJECTS)
$(AR) rcs $@ $^
%.o: @srcdir@/%.cpp $(INCFILES)
$(COMPILE) -c $<
Makefile: @srcdir@/Makefile.in ../../config.status
cd ../.. && ./config.status

1000
contrib/gtk2/gtk2client.cpp Normal file

File diff suppressed because it is too large Load Diff

205
contrib/gtk2/gtk2client.h Normal file
View File

@ -0,0 +1,205 @@
/**
* gtk2client.h
* This file is part of the YATE Project http://YATE.null.ro
*
* A Gtk based universal telephony client
*
* Yet Another Telephony Engine - a fully featured software PBX and IVR
* Copyright (C) 2004, 2005 Null Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <yatecbase.h>
#ifdef _WINDOWS
#ifdef LIBYGTK2_EXPORTS
#define YGTK2_API __declspec(dllexport)
#else
#ifndef LIBYGTK2_STATIC
#define YGTK2_API __declspec(dllimport)
#endif
#endif
#endif /* _WINDOWS */
#ifndef YGTK2_API
#define YGTK2_API
#endif
#include <string.h>
#include <stdio.h>
#include <malloc.h>
#include <gtk/gtk.h>
namespace TelEngine {
class YGTK2_API GTKClient : public Client
{
friend class GTKWindow;
public:
GTKClient();
virtual ~GTKClient();
virtual void main();
virtual void lock();
virtual void unlock();
virtual void allHidden();
virtual bool createWindow(const String& name);
protected:
virtual void loadWindows();
};
class YGTK2_API GTKDriver : public ClientDriver
{
public:
GTKDriver();
virtual ~GTKDriver();
virtual void initialize();
virtual bool factory(UIFactory* factory, const char* type = 0);
};
class YGTK2_API Widget
{
public:
Widget();
virtual ~Widget();
inline GtkWidget* widget() const
{ return m_widget; }
virtual bool setText(const String& text);
virtual bool setCheck(bool checked);
virtual bool setSelect(const String& item);
virtual bool addOption(const String& item, bool atStart = false);
virtual bool delOption(const String& item);
virtual bool getText(String& text);
virtual bool getCheck(bool& checked);
protected:
void widget(GtkWidget* wid);
private:
GtkWidget* m_widget;
void destroyed();
static void destroyCb(GtkObject* obj, gpointer dat);
};
class YGTK2_API GTKWindow : public Window
{
friend class GTKClient;
public:
enum Layout {
Unknown = 0,
Fixed,
Table,
Infinite,
HBox,
VBox,
Boxed,
Tabbed,
Framed,
};
GTKWindow(const char* id = 0, Layout layout = Unknown);
virtual ~GTKWindow();
virtual bool setActive(const String& name, bool active);
virtual bool setShow(const String& name, bool visible);
virtual bool setText(const String& name, const String& text);
virtual bool setCheck(const String& name, bool checked);
virtual bool setSelect(const String& name, const String& item);
virtual bool addOption(const String& name, const String& item, bool atStart = false);
virtual bool delOption(const String& name, const String& item);
virtual bool getText(const String& name, String& text);
virtual bool getCheck(const String& name, bool& checked);
virtual void populate();
virtual void init();
virtual void show();
virtual void hide();
virtual void size(int width, int height);
virtual void move(int x, int y);
virtual void moveRel(int dx, int dy);
virtual void geometry(int x, int y, int w, int h);
virtual GtkWidget* filler();
virtual GtkWidget* container(Layout layout) const;
virtual GtkWidget* container(const String& layout) const;
virtual GtkWidget* build(const String& type, const String& text);
GtkWidget* find(const String& name) const;
virtual void insert(GtkWidget* wid, int x = 0, int y = 0, int w = -1, int h = -1);
virtual bool action(GtkWidget* wid);
virtual bool toggle(GtkToggleButton* btn, gboolean active);
virtual bool select(GtkOptionMenu* opt, gint selected);
virtual void menu(int x, int y);
inline GtkWidget* widget() const
{ return m_widget; }
inline int state() const
{ return m_state; }
inline void state(int gdkState)
{ m_state = gdkState; }
bool prepare();
bool restore();
static bool setText(GtkWidget* wid, const String& text);
static bool setCheck(GtkWidget* wid, bool checked);
static bool setSelect(GtkWidget* wid, const String& item);
static bool addOption(GtkWidget* wid, const String& item, bool atStart = false);
static bool delOption(GtkWidget* wid, const String& item);
static bool getText(GtkWidget* wid, String& text);
static bool getCheck(GtkWidget* wid, bool& checked);
protected:
GtkWidget* m_widget;
GtkWidget* m_filler;
int m_layout;
int m_state;
gint m_posX;
gint m_posY;
gint m_sizeW;
gint m_sizeH;
};
/**
* Each instance of WindowFactory creates special windows by name
* @short A static window creator
*/
class YGTK2_API WindowFactory : public UIFactory
{
YCLASS(WindowFactory,UIFactory)
public:
WindowFactory(const char* type, const char* name);
virtual Window* build() const = 0;
};
#define WINDOW_FACTORY(type,name,cls) \
class cls##__Factory : public WindowFactory \
{ public: cls##__Factory() : WindowFactory(type,name) {} \
Window* build() const { return new cls(name); } }; \
cls##__Factory cls##__FactoryInstance;
/**
* Each instance of WidgetFactory creates special widgets by name
* @short A static widget creator
*/
class YGTK2_API WidgetFactory : public UIFactory
{
YCLASS(WidgetFactory,UIFactory)
public:
WidgetFactory(const char* type, const char* name);
virtual Widget* build(const String& text) const = 0;
};
#define WIDGET_FACTORY(type,name,cls) \
class cls##__Factory : public WidgetFactory \
{ public: cls##__Factory() : WidgetFactory(type,name) {} \
Widget* build(const String& text) const { return new cls(text); } }; \
cls##__Factory cls##__FactoryInstance;
}; // namespace TelEngine
/* vi: set ts=8 sw=4 sts=4 noet: */

681
engine/Client.cpp Normal file
View File

@ -0,0 +1,681 @@
/**
* Client.cpp
* This file is part of the YATE Project http://YATE.null.ro
*
* Yet Another Telephony Engine - a fully featured software PBX and IVR
* Copyright (C) 2004, 2005 Null Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "yatecbase.h"
using namespace TelEngine;
class UIHandler : public MessageHandler
{
public:
UIHandler()
: MessageHandler("ui.action",150)
{ }
virtual bool received(Message &msg);
};
Window::Window(const char* id)
: m_id(id), m_visible(false), m_master(false)
{
}
Window::~Window()
{
if (Client::self())
Client::self()->m_windows.remove(this,false);
}
const String& Window::toString() const
{
return m_id;
}
bool Window::related(const Window* wnd) const
{
if ((wnd == this) || !wnd || wnd->master())
return false;
return true;
}
UIFactory::UIFactory(const char* type, const char* name)
: String(name)
{
if (ClientDriver::self() && ClientDriver::self()->factory(this,type))
return;
Debug(ClientDriver::self(),DebugGoOn,"Could not register '%s' factory type '%s'",
name,type);
}
UIFactory::~UIFactory()
{
if (ClientDriver::self())
ClientDriver::self()->factory(this,0);
}
Client* Client::s_client = 0;
int Client::s_changing = 0;
Client::Client(const char *name)
: Thread(name), m_line(0)
{
s_client = this;
Engine::install(new UIHandler);
}
Client::~Client()
{
m_windows.clear();
s_client = 0;
Engine::halt(0);
}
void Client::run()
{
loadWindows();
Message msg("ui.event");
msg.setParam("event","load");
Engine::dispatch(msg);
initWindows();
setStatus("");
msg.setParam("event","init");
Engine::dispatch(msg);
main();
}
Window* Client::getWindow(const String& name)
{
if (!s_client)
return 0;
ObjList* l = s_client->m_windows.find(name);
return static_cast<Window*>(l ? l->get() : 0);
}
bool Client::setVisible(const String& name, bool show)
{
Window* w = getWindow(name);
if (!w)
return false;
w->visible(show);
return true;
}
bool Client::getVisible(const String& name)
{
Window* w = getWindow(name);
return w && w->visible();
}
void Client::initWindows()
{
ObjList* l = &m_windows;
for (; l; l = l->next()) {
Window* w = static_cast<Window*>(l->get());
if (w)
w->init();
}
}
void Client::moveRelated(const Window* wnd, int dx, int dy)
{
if (!wnd)
return;
ObjList* l = &m_windows;
for (; l; l = l->next()) {
Window* w = static_cast<Window*>(l->get());
if (w && (w != wnd) && wnd->related(w))
w->moveRel(dx,dy);
}
}
bool Client::setShow(const String& name, bool visible, Window* wnd, Window* skip)
{
if (wnd)
return wnd->setShow(name,visible);
++s_changing;
bool ok = false;
ObjList* l = &m_windows;
for (; l; l = l->next()) {
wnd = static_cast<Window*>(l->get());
if (wnd && (wnd != skip))
ok = wnd->setShow(name,visible) || ok;
}
--s_changing;
return ok;
}
bool Client::setActive(const String& name, bool active, Window* wnd, Window* skip)
{
if (wnd)
return wnd->setActive(name,active);
++s_changing;
bool ok = false;
ObjList* l = &m_windows;
for (; l; l = l->next()) {
wnd = static_cast<Window*>(l->get());
if (wnd && (wnd != skip))
ok = wnd->setActive(name,active) || ok;
}
--s_changing;
return ok;
}
bool Client::setText(const String& name, const String& text, Window* wnd, Window* skip)
{
if (wnd)
return wnd->setText(name,text);
++s_changing;
bool ok = false;
ObjList* l = &m_windows;
for (; l; l = l->next()) {
wnd = static_cast<Window*>(l->get());
if (wnd && (wnd != skip))
ok = wnd->setText(name,text) || ok;
}
--s_changing;
return ok;
}
bool Client::setCheck(const String& name, bool checked, Window* wnd, Window* skip)
{
if (wnd)
return wnd->setCheck(name,checked);
++s_changing;
bool ok = false;
ObjList* l = &m_windows;
for (; l; l = l->next()) {
wnd = static_cast<Window*>(l->get());
if (wnd && (wnd != skip))
ok = wnd->setCheck(name,checked) || ok;
}
--s_changing;
return ok;
}
bool Client::setSelect(const String& name, const String& item, Window* wnd, Window* skip)
{
if (wnd)
return wnd->setSelect(name,item);
++s_changing;
bool ok = false;
ObjList* l = &m_windows;
for (; l; l = l->next()) {
wnd = static_cast<Window*>(l->get());
if (wnd && (wnd != skip))
ok = wnd->setSelect(name,item) || ok;
}
--s_changing;
return ok;
}
bool Client::addOption(const String& name, const String& item, bool atStart, Window* wnd, Window* skip)
{
if (wnd)
return wnd->addOption(name,item,atStart);
++s_changing;
bool ok = false;
ObjList* l = &m_windows;
for (; l; l = l->next()) {
wnd = static_cast<Window*>(l->get());
if (wnd && (wnd != skip))
ok = wnd->addOption(name,item,atStart) || ok;
}
--s_changing;
return ok;
}
bool Client::delOption(const String& name, const String& item, Window* wnd, Window* skip)
{
if (wnd)
return wnd->delOption(name,item);
++s_changing;
bool ok = false;
ObjList* l = &m_windows;
for (; l; l = l->next()) {
wnd = static_cast<Window*>(l->get());
if (wnd && (wnd != skip))
ok = wnd->delOption(name,item) || ok;
}
--s_changing;
return ok;
}
bool Client::getText(const String& name, String& text, Window* wnd, Window* skip)
{
if (wnd)
return wnd->getText(name,text);
ObjList* l = &m_windows;
for (; l; l = l->next()) {
wnd = static_cast<Window*>(l->get());
if (wnd && (wnd != skip) && wnd->getText(name,text))
return true;
}
return false;
}
bool Client::getCheck(const String& name, bool& checked, Window* wnd, Window* skip)
{
if (wnd)
return wnd->getCheck(name,checked);
ObjList* l = &m_windows;
for (; l; l = l->next()) {
wnd = static_cast<Window*>(l->get());
if (wnd && (wnd != skip) && wnd->getCheck(name,checked))
return true;
}
return false;
}
bool Client::getSelect(const String& name, String& item, Window* wnd, Window* skip)
{
return getText(name,item,wnd,skip);
}
bool Client::setStatus(const String& text, Window* wnd)
{
Debug(ClientDriver::self(),DebugInfo,"Status '%s' in window %p",text.c_str(),wnd);
return setText("status",text,wnd);
}
bool Client::setStatusLocked(const String& text, Window* wnd)
{
lock();
bool ok = setStatus(text,wnd);
unlock();
return ok;
}
bool Client::action(Window* wnd, const String& name)
{
DDebug(ClientDriver::self(),DebugInfo,"Action '%s' in %p",name.c_str(),wnd);
if (name == "call" || name == "callto") {
String target;
getText("callto",target,wnd);
String line;
getText("line",line,wnd);
String proto;
getText("proto",proto,wnd);
return callStart(target,line,proto);
}
else if (name.startsWith("callto:"))
return callStart(name.substr(7));
else if (name == "accept") {
callAccept(m_incoming);
return true;
}
else if (name.startsWith("accept:")) {
callAccept(name.substr(7));
return true;
}
else if (name == "reject") {
callReject(m_incoming);
return true;
}
else if (name.startsWith("reject:")) {
callReject(name.substr(7));
return true;
}
else if (name == "hangup") {
callHangup(m_incoming);
return true;
}
else if (name.startsWith("hangup:")) {
callHangup(name.substr(7));
return true;
}
else if (name.startsWith("digit:")) {
emitDigit(name.at(6));
return true;
}
else if (name.startsWith("line:")) {
int l = name.substr(5).toInteger(-1);
if (l >= 0) {
line(l);
return true;
}
}
Message* m = new Message("ui.event");
m->addParam("event","action");
m->addParam("name",name);
Engine::enqueue(m);
return false;
}
bool Client::toggle(Window* wnd, const String& name, bool active)
{
DDebug(ClientDriver::self(),DebugInfo,"Toggle '%s' %s in %p",
name.c_str(),String::boolText(active),wnd);
if (setVisible(name,active))
return true;
setCheck(name,active,0,wnd);
Message* m = new Message("ui.event");
m->addParam("event","toggle");
m->addParam("name",name);
m->addParam("active",String::boolText(active));
Engine::enqueue(m);
return false;
}
bool Client::select(Window* wnd, const String& name, const String& item)
{
DDebug(ClientDriver::self(),DebugInfo,"Select '%s' '%s' in %p",
name.c_str(),item.c_str(),wnd);
setSelect(name,item,0,wnd);
Message* m = new Message("ui.event");
m->addParam("event","select");
m->addParam("name",name);
m->addParam("item",item);
Engine::enqueue(m);
return false;
}
void Client::line(int newLine)
{
Debug(ClientDriver::self(),DebugInfo,"line(%d)",newLine);
m_line = newLine;
}
void Client::callAccept(const char* callId)
{
Debug(ClientDriver::self(),DebugInfo,"callAccept('%s')",callId);
ClientChannel* cc = static_cast<ClientChannel*>(ClientDriver::self()->find(callId));
if (cc) {
cc->openMedia();
Engine::enqueue(cc->message("call.answered",false,true));
}
}
void Client::callReject(const char* callId)
{
Debug(ClientDriver::self(),DebugInfo,"callReject('%s')",callId);
if (!ClientDriver::self())
return;
Message* m = new Message("call.drop");
m->addParam("id",callId ? callId : ClientDriver::self()->name().c_str());
m->addParam("error","rejected");
m->addParam("reason","Refused");
Engine::enqueue(m);
}
void Client::callHangup(const char* callId)
{
Debug(ClientDriver::self(),DebugInfo,"callHangup('%s')",callId);
if (!ClientDriver::self())
return;
Message* m = new Message("call.drop");
m->addParam("id",callId ? callId : ClientDriver::self()->name().c_str());
m->addParam("reason","User hangup");
Engine::enqueue(m);
}
bool Client::callStart(const String& target, const String& line, const String& proto)
{
Debug(ClientDriver::self(),DebugInfo,"callStart('%s','%s','%s')",
target.c_str(),line.c_str(),proto.c_str());
if (target.null())
return false;
ClientChannel* cc = new ClientChannel();
Message* m = cc->message("call.route");
Regexp r("^[a-z]\\+/");
if (r.matches(target.safe()))
m->setParam("callto",target);
else
m->setParam("called",target);
if (line)
m->setParam("line",line);
if (proto)
m->setParam("protocol",proto);
return cc->startRouter(m);
}
bool Client::emitDigit(char digit)
{
Debug(ClientDriver::self(),DebugInfo,"emitDigit('%c')",digit);
return false;
}
bool Client::callIncoming(const String& caller, const String& dest, Message* msg)
{
Debug(ClientDriver::self(),DebugAll,"callIncoming [%p]",this);
if (msg && msg->userData()) {
CallEndpoint* ch = static_cast<CallEndpoint*>(msg->userData());
ClientChannel* cc = new ClientChannel(ch->id());
if (cc->connect(ch)) {
m_incoming = cc->id();
msg->setParam("peerid",m_incoming);
msg->setParam("targetid",m_incoming);
Engine::enqueue(cc->message("call.ringing",false,true));
cc->deref();
// notify the UI about the call
String tmp("Call from:");
tmp << " " << caller;
lock();
setStatus(tmp);
setText("incoming",tmp);
setVisible("incoming");
unlock();
return true;
}
}
return false;
}
void Client::clearIncoming(const String& id)
{
if (id == m_incoming)
m_incoming.clear();
}
bool UIHandler::received(Message &msg)
{
if (!Client::self())
return false;
String action(msg.getValue("action"));
if (action.null())
return false;
Window* wnd = Client::getWindow(msg.getValue("window"));
if (action == "set_status")
return Client::self()->setStatusLocked(msg.getValue("status"),wnd);
String name(msg.getValue("name"));
if (name.null())
return false;
DDebug(ClientDriver::self(),DebugAll,"UI action '%s' on '%s' in %p",
action.c_str(),name.c_str(),wnd);
bool ok = false;
Client::self()->lock();
if (action == "set_text")
ok = Client::self()->setText(name,msg.getValue("text"),wnd);
else if (action == "set_toggle")
ok = Client::self()->setCheck(name,msg.getBoolValue("active"),wnd);
else if (action == "set_select")
ok = Client::self()->setSelect(name,msg.getValue("item"),wnd);
else if (action == "set_active")
ok = Client::self()->setActive(name,msg.getBoolValue("active"),wnd);
else if (action == "set_visible")
ok = Client::self()->setShow(name,msg.getBoolValue("visible"),wnd);
else if (action == "add_option")
ok = Client::self()->addOption(name,msg.getValue("item"),msg.getBoolValue("insert"),wnd);
else if (action == "del_option")
ok = Client::self()->delOption(name,msg.getValue("item"),wnd);
else if (action == "get_text") {
String text;
ok = Client::self()->getText(name,text,wnd);
if (ok)
msg.retValue() = text;
}
else if (action == "get_toggle") {
bool check;
ok = Client::self()->getCheck(name,check,wnd);
if (ok)
msg.retValue() = check;
}
else if (action == "get_select") {
String item;
ok = Client::self()->getSelect(name,item,wnd);
if (ok)
msg.retValue() = item;
}
else if (action == "window_show")
ok = Client::setVisible(name,true);
else if (action == "window_hide")
ok = Client::setVisible(name,false);
Client::self()->unlock();
return ok;
}
// IMPORTANT: having a target means "from inside Yate to the user"
// An user initiated call must be incoming (no target)
ClientChannel::ClientChannel(const char* target)
: Channel(ClientDriver::self(),0,target), m_line(0)
{
m_targetid = target;
Engine::enqueue(message("chan.startup"));
}
ClientChannel::~ClientChannel()
{
closeMedia();
String tmp("Hung up:");
tmp << " " << (address() ? address() : id());
if (Client::self()) {
Client::self()->clearIncoming(id());
Client::self()->setStatusLocked(tmp);
}
Engine::enqueue(message("chan.hangup"));
}
bool ClientChannel::openMedia()
{
String dev = ClientDriver::device();
if (dev.null())
return false;
Message m("chan.attach");
complete(m,true);
m.setParam("source",dev);
m.setParam("consumer",dev);
m.userData(this);
return Engine::dispatch(m);
}
void ClientChannel::closeMedia()
{
setSource();
setConsumer();
}
void ClientChannel::line(int newLine)
{
m_line = newLine;
m_address.clear();
if (m_line > 0)
m_address << "line/" << m_line;
}
bool ClientChannel::callRouted(Message& msg)
{
String tmp("Calling:");
tmp << " " << msg.retValue();
Client::self()->setStatusLocked(tmp);
return true;
}
void ClientChannel::callAccept(Message& msg)
{
Debug(ClientDriver::self(),DebugAll,"ClientChannel::callAccept() [%p]",this);
Client::self()->setStatusLocked("Call connected");
Channel::callAccept(msg);
}
void ClientChannel::callReject(const char* error, const char* reason)
{
Debug(ClientDriver::self(),DebugAll,"ClientChannel::callReject('%s','%s') [%p]",
error,reason,this);
if (!reason)
reason = error;
if (!reason)
reason = "Unknown reason";
String tmp("Call failed:");
tmp << " " << reason;
if (Client::self())
Client::self()->setStatusLocked(tmp);
Channel::callReject(error,reason);
}
bool ClientChannel::msgRinging(Message& msg)
{
Debug(ClientDriver::self(),DebugAll,"ClientChannel::msgRinging() [%p]",this);
Client::self()->setStatusLocked("Call ringing");
return Channel::msgRinging(msg);
}
bool ClientChannel::msgAnswered(Message& msg)
{
Debug(ClientDriver::self(),DebugAll,"ClientChannel::msgAnswered() [%p]",this);
Client::self()->setStatusLocked("Call answered");
openMedia();
return Channel::msgAnswered(msg);
}
ClientDriver* ClientDriver::s_driver = 0;
String ClientDriver::s_device;
ClientDriver::ClientDriver()
: Driver("client","misc")
{
s_driver = this;
}
ClientDriver::~ClientDriver()
{
s_driver = 0;
}
bool ClientDriver::factory(UIFactory* factory, const char* type)
{
return false;
}
bool ClientDriver::msgExecute(Message& msg, String& dest)
{
Debug(this,DebugInfo,"msgExecute() '%s'",dest.c_str());
return (Client::self()) && (Client::self()->callIncoming(msg.getValue("caller"),dest,&msg));
}
ClientChannel* ClientDriver::findLine(int line)
{
if (line < 1)
return 0;
Lock mylock(this);
ObjList* l = &channels();
for (; l; l = l->next()) {
ClientChannel* cc = static_cast<ClientChannel*>(l->get());
if (cc && (cc->line() == line))
return cc;
}
return 0;
}
/* vi: set ts=8 sw=4 sts=4 noet: */

View File

@ -18,14 +18,16 @@ MKDEPS := ../config.status
YLIB:= libyate.so.@PACKAGE_VERSION@
CINC := @top_srcdir@/yateclass.h
EINC := $(CINC) @top_srcdir@/yatengine.h
PINC := $(PINC) @top_srcdir@/yatephone.h
PINC := $(EINC) @top_srcdir@/yatephone.h
CLINC:= $(PINC) @top_srcdir@/yatecbase.h
LIBS :=
CLSOBJS := TelEngine.o ObjList.o String.o DataBlock.o NamedList.o YMD5.o \
Mutex.o Thread.o Socket.o
ENGOBJS := Configuration.o Message.o Plugin.o Engine.o
TELOBJS := DataFormat.o Channel.o
CLIOBJS := Client.o
LIBOBJS := $(CLSOBJS) $(ENGOBJS) $(TELOBJS)
LIBOBJS := $(CLSOBJS) $(ENGOBJS) $(TELOBJS) $(CLIOBJS)
CLEANS = $(LIBOBJS) core
COMPILE = $(CXX) $(DEFS) $(DEBUG) $(INCLUDES) $(CFLAGS)
LINK = $(CXX) $(LDFLAGS)
@ -68,6 +70,9 @@ Mutex.o: @srcdir@/Mutex.cpp $(MKDEPS) $(CINC)
Thread.o: @srcdir@/Thread.cpp $(MKDEPS) $(CINC)
$(COMPILE) @THREAD_KILL@ -c $<
Client.o: @srcdir@/Client.cpp $(MKDEPS) $(CLINC)
$(COMPILE) -c $<
%.o: @srcdir@/%.cpp $(MKDEPS) $(EINC)
$(COMPILE) -c $<

View File

@ -120,6 +120,12 @@ GenObject* ObjList::operator[](int index) const
return obj ? obj->get() : 0;
}
GenObject* ObjList::operator[](const String& str) const
{
ObjList *obj = find(str);
return obj ? obj->get() : 0;
}
ObjList* ObjList::find(const GenObject* obj) const
{
XDebug(DebugAll,"ObjList::find(%p) [%p]",obj,this);

View File

@ -17,7 +17,7 @@ MODFLAGS:= @MODULE_LDFLAGS@
MODSTRIP:= @MODULE_SYMBOLS@
INCFILES := @top_srcdir@/yatengine.h @top_srcdir@/yatephone.h ../yateversn.h
SUBDIRS :=
SUBDIRS := gtk2
MKDEPS := ../config.status
PROGS := cdrbuild.yate cdrfile.yate \
regexroute.yate regfile.yate accfile.yate \
@ -55,6 +55,10 @@ ifneq (@HAVE_GSM@,no)
PROGS := $(PROGS) gsmcodec.yate
endif
ifeq (@HAVE_GTK2@_@HAVE_GMOZ@,yes_yes)
PROGS := $(PROGS) gtk2/gtk2mozilla.yate
endif
LOCALFLAGS =
LOCALLIBS =
COMPILE = $(CXX) $(DEFS) $(DEBUG) $(INCLUDES) $(CFLAGS)
@ -80,14 +84,21 @@ clean: do-clean
.PHONY: install
install: all do-install
@mkdir -p "$(DESTDIR)$(moddir)/" && \
install $(PROGS) "$(DESTDIR)$(moddir)/"
for i in $(PROGS) ; do \
install -D "$$i" "$(DESTDIR)$(moddir)/$$i" ; \
done;
.PHONY: uninstall
uninstall: do-uninstall
@-for i in $(PROGS) ; do \
rm "$(DESTDIR)$(moddir)/$$i" ; \
done; \
rmdir "$(DESTDIR)$(moddir)"
$(if $(SUBDIRS),\
for i in $(SUBDIRS) ; do \
rmdir "$(DESTDIR)$(moddir)/$$i" ; \
done; \
)
@-rmdir "$(DESTDIR)$(moddir)"
%.o: @srcdir@/%.cpp $(MKDEPS) $(INCFILES)
$(COMPILE) -c $<
@ -142,6 +153,10 @@ yrtpchan.yate: ../contrib/yrtp/libyatertp.a
yrtpchan.yate: LOCALFLAGS = -I@top_srcdir@/contrib/yrtp
yrtpchan.yate: LOCALLIBS = ../contrib/yrtp/libyatertp.a
gtk2/gtk2mozilla.yate: @top_srcdir@/contrib/gtk2/gtk2client.h
gtk2/gtk2mozilla.yate: LOCALFLAGS = @GTK2_INC@ @GMOZ_INC@ -I@top_srcdir@/contrib/gtk2
gtk2/gtk2mozilla.yate: LOCALLIBS = @GMOZ_LIB@
../contrib/iax/libiax.a:
$(MAKE) -C ../contrib/iax

9
modules/gtk2/.cvsignore Normal file
View File

@ -0,0 +1,9 @@
Makefile
core*
*.o
*.a
*.so
*.yate
*.orig
*~
.*.swp

View File

@ -0,0 +1,101 @@
/**
* gtk2mozilla.cpp
* This file is part of the YATE Project http://YATE.null.ro
*
* Mozilla embedded widget for the Gtk2 based universal telephony client
*
* Yet Another Telephony Engine - a fully featured software PBX and IVR
* Copyright (C) 2004, 2005 Null Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "gtk2client.h"
#include <gtkmozembed.h>
using namespace TelEngine;
// Embedded Mozilla widget
class MozWidget : public Widget
{
public:
MozWidget(const String& text);
virtual ~MozWidget();
virtual bool setText(const String& text);
virtual bool getText(String& text);
void setTextAsync();
protected:
String m_url;
};
WIDGET_FACTORY("gtk2","mozilla",MozWidget)
static Mutex s_mutex;
static gboolean mozIntervalCb(gpointer dat)
{
if (dat)
static_cast<MozWidget*>(dat)->setTextAsync();
return false;
}
MozWidget::MozWidget(const String& text)
{
DDebug(ClientDriver::self(),DebugAll,"MozWidget::MozWidget()");
widget(gtk_moz_embed_new());
setText(text);
}
MozWidget::~MozWidget()
{
DDebug(ClientDriver::self(),DebugAll,"MozWidget::~MozWidget()");
}
bool MozWidget::setText(const String& text)
{
if (widget() && text) {
s_mutex.lock();
m_url = text;
gtk_timeout_add(1,mozIntervalCb,this);
s_mutex.unlock();
return true;
}
return false;
}
bool MozWidget::getText(String& text)
{
if (widget()) {
char* url = gtk_moz_embed_get_location(GTK_MOZ_EMBED(widget()));
text = url;
delete url;
return true;
}
return false;
}
void MozWidget::setTextAsync()
{
s_mutex.lock();
if (widget() && m_url) {
Debug(ClientDriver::self(),DebugAll,"MozWidget async url='%s'",m_url.c_str());
gtk_moz_embed_load_url(GTK_MOZ_EMBED(widget()),m_url.c_str());
m_url.clear();
}
s_mutex.unlock();
}
/* vi: set ts=8 sw=4 sts=4 noet: */

View File

@ -0,0 +1,37 @@
pixmap_path "/usr/src/yate09-gtk2/clients"
style "tux" {
bg_pixmap[NORMAL] = "tux.xpm"
}
style "brown" {
bg[NORMAL] = { 0.80, 0.75, 0.25 }
}
style "red" {
bg[NORMAL] = { 1.0, 0.5, 0.5 }
}
style "green" {
bg[NORMAL] = { 0.5, 1.0, 0.5 }
}
style "blue" {
bg[NORMAL] = { 0.5, 0.5, 1.0 }
GtkButton::default_border = { 5, 0, 5, 0 }
}
style "sky" {
bg[NORMAL] = { 0.85, 0.85, 1.0 }
}
widget_class "default" style "tux"
#class "GtkWindow" style "brown"
#widget "default" style "brown"
widget "browser" style "sky"
widget "*.call" style "green"
widget "*.accept" style "green"
widget "*.reject" style "red"
widget "*.hangup" style "red"
widget "*.caption" style "sky"
widget "*.decoration" style "blue"

View File

@ -0,0 +1,72 @@
[default]
enabled=on
title=Yate VoIP Client
master=yes
layout=fixed
width=220
height=130
label=10,5,100,20,Yate
label=10,30,150,20,Call address or number
combo=10,50,150,22,callto,
label=170,30,40,20,Line
option=170,48,40,30,line,l 1,l 2,l 3
button=10,80,100,28,call,Call
button=110,80,100,28,hangup,Hangup
label=10,110,200,20,status,Initializing...
check=75,5,20,20,ctest,Test
toggle=135,5,20,20,browser,
toggle=155,5,20,20,tools,
button_icon=175,5,20,20,decoration,
button_hide=195,5,20,20,decoration,
x=489
y=368
[tools]
enabled=off
title=Tools
label=Tools Window
check=160,5,20,20,ctest,Test
button_hide=0,0,20,20,decoration,
x=608
y=314
[browser]
enabled=on
title=Browser
master=yes
layout=framed
vbox=>
hbox=,,0,-1
label=1,1,,,Browser window
button_icon=,,20,20,decoration,
button_max=,,20,20,decoration,
button_hide=,,20,20,decoration,
leave=<
mozilla=1,1,300,400,browser,file:///usr/share/gtk-doc/html/gtk/GtkWidget.html#gtk-widget-set-size-request
editor=,1,200,22,callto,
hbox=,,0,-1
button=1,,100,30,call,Call
button=1,,100,30,hangup,Hangup
button=1,,100,30,mumu,Mumu
leave=<
label=,,,,status,Initializing...
leave=<
x=688
y=40
[incoming]
enabled=on
title=Incoming Call
layout=framed
vbox=>
boxed=0,0,-1,-1,caption,>
hbox=,,0,-1
label=1,1,,,Incoming call
button_hide=,,20,20,decoration,
leave=<
leave=<
label=,,,,incoming,No call
hbox=
button=1,,75,30,accept,Accept
button=1,,75,30,reject,Reject
leave=<
leave=<
x=688
y=536

202
yatecbase.h Normal file
View File

@ -0,0 +1,202 @@
/**
* yatecbase.h
* This file is part of the YATE Project http://YATE.null.ro
*
* Common base classes for all telephony clients
*
* Yet Another Telephony Engine - a fully featured software PBX and IVR
* Copyright (C) 2004, 2005 Null Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __YATECBASE_H
#define __YATECBASE_H
#ifndef __cplusplus
#error C++ is required
#endif
#include <yatephone.h>
/**
* Holds all Telephony Engine related classes.
*/
namespace TelEngine {
/**
* A window is the basic user interface element.
* Everything inside is implementation specific functionality.
* @short An abstract user interface window
*/
class YATE_API Window : public GenObject
{
friend class Client;
public:
Window(const char* id = 0);
virtual ~Window();
virtual const String& toString() const;
virtual bool setActive(const String& name, bool active) = 0;
virtual bool setShow(const String& name, bool visible) = 0;
virtual bool setText(const String& name, const String& text) = 0;
virtual bool setCheck(const String& name, bool checked) = 0;
virtual bool setSelect(const String& name, const String& item) = 0;
virtual bool addOption(const String& name, const String& item, bool atStart = false) = 0;
virtual bool delOption(const String& name, const String& item) = 0;
virtual bool getText(const String& name, String& text) = 0;
virtual bool getCheck(const String& name, bool& checked) = 0;
virtual void populate() = 0;
virtual void init() = 0;
virtual void show() = 0;
virtual void hide() = 0;
virtual void size(int width, int height) = 0;
virtual void move(int x, int y) = 0;
virtual void moveRel(int dx, int dy) = 0;
virtual bool related(const Window* wnd) const;
virtual void menu(int x, int y) = 0;
inline const String& id() const
{ return m_id; }
inline bool visible() const
{ return m_visible; }
inline void visible(bool yes)
{ if (yes) show(); else hide(); }
inline bool master() const
{ return m_master; }
protected:
String m_id;
bool m_visible;
bool m_master;
};
/**
* Each instance of UIFactory creates special user interface elements by name
* @short A static user interface creator
*/
class YATE_API UIFactory : public String
{
public:
UIFactory(const char* type, const char* name);
virtual ~UIFactory();
};
/**
* Singleton class that holds the User Interface's main thread and methods
* @short Thread that runs the User Interface
*/
class YATE_API Client : public Thread
{
friend class Window;
public:
Client(const char *name = 0);
virtual ~Client();
virtual void run();
virtual void main() = 0;
virtual void lock() = 0;
virtual void unlock() = 0;
virtual void allHidden() = 0;
virtual bool createWindow(const String& name) = 0;
virtual bool setStatus(const String& text, Window* wnd = 0);
bool setStatusLocked(const String& text, Window* wnd = 0);
virtual bool action(Window* wnd, const String& name);
virtual bool toggle(Window* wnd, const String& name, bool active);
virtual bool select(Window* wnd, const String& name, const String& item);
virtual bool callIncoming(const String& caller, const String& dest = String::empty(), Message* msg = 0);
void clearIncoming(const String& id);
void callAccept(const char* callId = 0);
void callReject(const char* callId = 0);
void callHangup(const char* callId = 0);
bool callStart(const String& target, const String& line = String::empty(), const String& proto = String::empty());
bool emitDigit(char digit);
inline int line() const
{ return m_line; }
void line(int newLine);
bool setActive(const String& name, bool active, Window* wnd = 0, Window* skip = 0);
bool setShow(const String& name, bool visible, Window* wnd = 0, Window* skip = 0);
bool setText(const String& name, const String& text, Window* wnd = 0, Window* skip = 0);
bool setCheck(const String& name, bool checked, Window* wnd = 0, Window* skip = 0);
bool setSelect(const String& name, const String& item, Window* wnd = 0, Window* skip = 0);
bool addOption(const String& name, const String& item, bool atStart, Window* wnd = 0, Window* skip = 0);
bool delOption(const String& name, const String& item, Window* wnd = 0, Window* skip = 0);
bool getText(const String& name, String& text, Window* wnd = 0, Window* skip = 0);
bool getCheck(const String& name, bool& checked, Window* wnd = 0, Window* skip = 0);
bool getSelect(const String& name, String& item, Window* wnd = 0, Window* skip = 0);
void moveRelated(const Window* wnd, int dx, int dy);
inline static Client* self()
{ return s_client; }
inline static bool changing()
{ return (s_changing > 0); }
static Window* getWindow(const String& name);
static bool setVisible(const String& name, bool show = true);
static bool getVisible(const String& name);
protected:
virtual void loadWindows() = 0;
virtual void initWindows();
ObjList m_windows;
String m_incoming;
int m_line;
static Client* s_client;
static int s_changing;
};
/**
* This class implements a Channel used by client programs
* @short Channel used by client programs
*/
class YATE_API ClientChannel : public Channel
{
public:
ClientChannel(const char* target = 0);
virtual ~ClientChannel();
virtual bool msgRinging(Message& msg);
virtual bool msgAnswered(Message& msg);
virtual bool callRouted(Message& msg);
virtual void callAccept(Message& msg);
virtual void callReject(const char* error, const char* reason);
bool openMedia();
void closeMedia();
inline int line() const
{ return m_line; }
void line(int newLine);
protected:
int m_line;
};
/**
* Abstract client Driver that implements some of the specific functionality
* @short Base Driver with client specific functions
*/
class YATE_API ClientDriver : public Driver
{
public:
ClientDriver();
virtual ~ClientDriver();
virtual void initialize() = 0;
virtual bool factory(UIFactory* factory, const char* type);
virtual bool msgExecute(Message& msg, String& dest);
ClientChannel* findLine(int line);
inline static ClientDriver* self()
{ return s_driver; }
inline static const String& device()
{ return s_device; }
protected:
static ClientDriver* s_driver;
static String s_device;
};
}; // namespace TelEngine
#endif /* __YATECBASE_H */
/* vi: set ts=8 sw=4 sts=4 noet: */

View File

@ -779,6 +779,13 @@ public:
*/
GenObject* operator[](int index) const;
/**
* Array-like indexing operator
* @param str String value of the object to locate
* @return Pointer to the object or NULL
*/
GenObject* operator[](const String& str) const;
/**
* Get the item in the list that holds an object
* @param obj Pointer to the object to search for