Added skinnable Gtk2 client.
git-svn-id: http://yate.null.ro/svn/yate/trunk@429 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
parent
80109fdfb4
commit
d1c8926c82
|
@ -20,7 +20,7 @@ MKDEPS := ./config.status
|
||||||
PROGS:= yate
|
PROGS:= yate
|
||||||
YLIB := libyate.so.@PACKAGE_VERSION@
|
YLIB := libyate.so.@PACKAGE_VERSION@
|
||||||
SLIBS:= $(YLIB) libyate.so
|
SLIBS:= $(YLIB) libyate.so
|
||||||
INCS := yateclass.h yatengine.h yatephone.h
|
INCS := yateclass.h yatengine.h yatephone.h yatecbase.h
|
||||||
GENS := yateversn.h
|
GENS := yateversn.h
|
||||||
LIBS :=
|
LIBS :=
|
||||||
MAN8 := yate.8 yate-config.8
|
MAN8 := yate.8 yate-config.8
|
||||||
|
@ -86,7 +86,9 @@ apidocs-build: check-topdir
|
||||||
|
|
||||||
apidocs: @srcdir@/docs/api/index.html
|
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
|
$(MAKE) apidocs-build
|
||||||
|
|
||||||
.PHONY: strip sex love war
|
.PHONY: strip sex love war
|
||||||
|
|
|
@ -29,6 +29,10 @@ ifneq (@HAVE_QT@,no)
|
||||||
PROGS := $(PROGS) yate-qt
|
PROGS := $(PROGS) yate-qt
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifneq (@HAVE_GTK2@,no)
|
||||||
|
PROGS := $(PROGS) yate-gtk2
|
||||||
|
endif
|
||||||
|
|
||||||
LOCALFLAGS =
|
LOCALFLAGS =
|
||||||
LOCALLIBS =
|
LOCALLIBS =
|
||||||
COMPILE = $(CXX) $(DEFS) $(DEBUG) $(INCLUDES) $(CFLAGS)
|
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: LOCALFLAGS = @GTK_INC@
|
||||||
yate-gtk: LOCALLIBS = @GTK_LIB@
|
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: ../contrib/qt/libqtclientform.a
|
||||||
yate-qt: LOCALFLAGS = -I@QT_INC@
|
yate-qt: LOCALFLAGS = -I@QT_INC@
|
||||||
yate-qt: LOCALLIBS = ../contrib/qt/libqtclientform.a -L@QT_DIR@/lib -lqt-mt
|
yate-qt: LOCALLIBS = ../contrib/qt/libqtclientform.a -L@QT_DIR@/lib -lqt-mt
|
||||||
|
|
||||||
../contrib/qt/libqtclientform.a:
|
../contrib/qt/libqtclientform.a:
|
||||||
$(MAKE) -C ../contrib/qt
|
$(MAKE) -C ../contrib/qt
|
||||||
|
|
||||||
|
../contrib/gtk2/libgtk2client.a:
|
||||||
|
$(MAKE) -C ../contrib/gtk2
|
||||||
|
|
|
@ -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: */
|
|
@ -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
|
59
configure.in
59
configure.in
|
@ -203,6 +203,21 @@ fi
|
||||||
AC_SUBST(HAVE_GSM)
|
AC_SUBST(HAVE_GSM)
|
||||||
AC_SUBST(GSM_INC)
|
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
|
HAVE_PWLIB=no
|
||||||
PWLIB_RTTI=none
|
PWLIB_RTTI=none
|
||||||
PWLIB_INC=""
|
PWLIB_INC=""
|
||||||
|
@ -465,6 +480,49 @@ AC_SUBST(HAVE_GTK)
|
||||||
AC_SUBST(GTK_INC)
|
AC_SUBST(GTK_INC)
|
||||||
AC_SUBST(GTK_LIB)
|
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
|
HAVE_QT=no
|
||||||
QT_DIR=""
|
QT_DIR=""
|
||||||
QT_INC=""
|
QT_INC=""
|
||||||
|
@ -552,6 +610,7 @@ AC_CONFIG_FILES([yate.spec
|
||||||
contrib/ysip/Makefile
|
contrib/ysip/Makefile
|
||||||
contrib/yrtp/Makefile
|
contrib/yrtp/Makefile
|
||||||
contrib/qt/Makefile
|
contrib/qt/Makefile
|
||||||
|
contrib/gtk2/Makefile
|
||||||
test/Makefile])
|
test/Makefile])
|
||||||
AC_CONFIG_FILES([yate-config],[chmod +x yate-config])
|
AC_CONFIG_FILES([yate-config],[chmod +x yate-config])
|
||||||
AC_CONFIG_FILES([run],[chmod +x run])
|
AC_CONFIG_FILES([run],[chmod +x run])
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
Makefile
|
||||||
|
core*
|
||||||
|
*.o
|
||||||
|
*.a
|
||||||
|
*.orig
|
||||||
|
*~
|
||||||
|
.*.swp
|
|
@ -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
|
File diff suppressed because it is too large
Load Diff
|
@ -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: */
|
|
@ -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: */
|
|
@ -18,14 +18,16 @@ MKDEPS := ../config.status
|
||||||
YLIB:= libyate.so.@PACKAGE_VERSION@
|
YLIB:= libyate.so.@PACKAGE_VERSION@
|
||||||
CINC := @top_srcdir@/yateclass.h
|
CINC := @top_srcdir@/yateclass.h
|
||||||
EINC := $(CINC) @top_srcdir@/yatengine.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 :=
|
LIBS :=
|
||||||
CLSOBJS := TelEngine.o ObjList.o String.o DataBlock.o NamedList.o YMD5.o \
|
CLSOBJS := TelEngine.o ObjList.o String.o DataBlock.o NamedList.o YMD5.o \
|
||||||
Mutex.o Thread.o Socket.o
|
Mutex.o Thread.o Socket.o
|
||||||
ENGOBJS := Configuration.o Message.o Plugin.o Engine.o
|
ENGOBJS := Configuration.o Message.o Plugin.o Engine.o
|
||||||
TELOBJS := DataFormat.o Channel.o
|
TELOBJS := DataFormat.o Channel.o
|
||||||
|
CLIOBJS := Client.o
|
||||||
|
|
||||||
LIBOBJS := $(CLSOBJS) $(ENGOBJS) $(TELOBJS)
|
LIBOBJS := $(CLSOBJS) $(ENGOBJS) $(TELOBJS) $(CLIOBJS)
|
||||||
CLEANS = $(LIBOBJS) core
|
CLEANS = $(LIBOBJS) core
|
||||||
COMPILE = $(CXX) $(DEFS) $(DEBUG) $(INCLUDES) $(CFLAGS)
|
COMPILE = $(CXX) $(DEFS) $(DEBUG) $(INCLUDES) $(CFLAGS)
|
||||||
LINK = $(CXX) $(LDFLAGS)
|
LINK = $(CXX) $(LDFLAGS)
|
||||||
|
@ -68,6 +70,9 @@ Mutex.o: @srcdir@/Mutex.cpp $(MKDEPS) $(CINC)
|
||||||
Thread.o: @srcdir@/Thread.cpp $(MKDEPS) $(CINC)
|
Thread.o: @srcdir@/Thread.cpp $(MKDEPS) $(CINC)
|
||||||
$(COMPILE) @THREAD_KILL@ -c $<
|
$(COMPILE) @THREAD_KILL@ -c $<
|
||||||
|
|
||||||
|
Client.o: @srcdir@/Client.cpp $(MKDEPS) $(CLINC)
|
||||||
|
$(COMPILE) -c $<
|
||||||
|
|
||||||
%.o: @srcdir@/%.cpp $(MKDEPS) $(EINC)
|
%.o: @srcdir@/%.cpp $(MKDEPS) $(EINC)
|
||||||
$(COMPILE) -c $<
|
$(COMPILE) -c $<
|
||||||
|
|
||||||
|
|
|
@ -120,6 +120,12 @@ GenObject* ObjList::operator[](int index) const
|
||||||
return obj ? obj->get() : 0;
|
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
|
ObjList* ObjList::find(const GenObject* obj) const
|
||||||
{
|
{
|
||||||
XDebug(DebugAll,"ObjList::find(%p) [%p]",obj,this);
|
XDebug(DebugAll,"ObjList::find(%p) [%p]",obj,this);
|
||||||
|
|
|
@ -17,7 +17,7 @@ MODFLAGS:= @MODULE_LDFLAGS@
|
||||||
MODSTRIP:= @MODULE_SYMBOLS@
|
MODSTRIP:= @MODULE_SYMBOLS@
|
||||||
INCFILES := @top_srcdir@/yatengine.h @top_srcdir@/yatephone.h ../yateversn.h
|
INCFILES := @top_srcdir@/yatengine.h @top_srcdir@/yatephone.h ../yateversn.h
|
||||||
|
|
||||||
SUBDIRS :=
|
SUBDIRS := gtk2
|
||||||
MKDEPS := ../config.status
|
MKDEPS := ../config.status
|
||||||
PROGS := cdrbuild.yate cdrfile.yate \
|
PROGS := cdrbuild.yate cdrfile.yate \
|
||||||
regexroute.yate regfile.yate accfile.yate \
|
regexroute.yate regfile.yate accfile.yate \
|
||||||
|
@ -55,6 +55,10 @@ ifneq (@HAVE_GSM@,no)
|
||||||
PROGS := $(PROGS) gsmcodec.yate
|
PROGS := $(PROGS) gsmcodec.yate
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq (@HAVE_GTK2@_@HAVE_GMOZ@,yes_yes)
|
||||||
|
PROGS := $(PROGS) gtk2/gtk2mozilla.yate
|
||||||
|
endif
|
||||||
|
|
||||||
LOCALFLAGS =
|
LOCALFLAGS =
|
||||||
LOCALLIBS =
|
LOCALLIBS =
|
||||||
COMPILE = $(CXX) $(DEFS) $(DEBUG) $(INCLUDES) $(CFLAGS)
|
COMPILE = $(CXX) $(DEFS) $(DEBUG) $(INCLUDES) $(CFLAGS)
|
||||||
|
@ -80,14 +84,21 @@ clean: do-clean
|
||||||
.PHONY: install
|
.PHONY: install
|
||||||
install: all do-install
|
install: all do-install
|
||||||
@mkdir -p "$(DESTDIR)$(moddir)/" && \
|
@mkdir -p "$(DESTDIR)$(moddir)/" && \
|
||||||
install $(PROGS) "$(DESTDIR)$(moddir)/"
|
for i in $(PROGS) ; do \
|
||||||
|
install -D "$$i" "$(DESTDIR)$(moddir)/$$i" ; \
|
||||||
|
done;
|
||||||
|
|
||||||
.PHONY: uninstall
|
.PHONY: uninstall
|
||||||
uninstall: do-uninstall
|
uninstall: do-uninstall
|
||||||
@-for i in $(PROGS) ; do \
|
@-for i in $(PROGS) ; do \
|
||||||
rm "$(DESTDIR)$(moddir)/$$i" ; \
|
rm "$(DESTDIR)$(moddir)/$$i" ; \
|
||||||
done; \
|
done; \
|
||||||
rmdir "$(DESTDIR)$(moddir)"
|
$(if $(SUBDIRS),\
|
||||||
|
for i in $(SUBDIRS) ; do \
|
||||||
|
rmdir "$(DESTDIR)$(moddir)/$$i" ; \
|
||||||
|
done; \
|
||||||
|
)
|
||||||
|
@-rmdir "$(DESTDIR)$(moddir)"
|
||||||
|
|
||||||
%.o: @srcdir@/%.cpp $(MKDEPS) $(INCFILES)
|
%.o: @srcdir@/%.cpp $(MKDEPS) $(INCFILES)
|
||||||
$(COMPILE) -c $<
|
$(COMPILE) -c $<
|
||||||
|
@ -142,6 +153,10 @@ yrtpchan.yate: ../contrib/yrtp/libyatertp.a
|
||||||
yrtpchan.yate: LOCALFLAGS = -I@top_srcdir@/contrib/yrtp
|
yrtpchan.yate: LOCALFLAGS = -I@top_srcdir@/contrib/yrtp
|
||||||
yrtpchan.yate: LOCALLIBS = ../contrib/yrtp/libyatertp.a
|
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:
|
../contrib/iax/libiax.a:
|
||||||
$(MAKE) -C ../contrib/iax
|
$(MAKE) -C ../contrib/iax
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
Makefile
|
||||||
|
core*
|
||||||
|
*.o
|
||||||
|
*.a
|
||||||
|
*.so
|
||||||
|
*.yate
|
||||||
|
*.orig
|
||||||
|
*~
|
||||||
|
.*.swp
|
|
@ -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: */
|
|
@ -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"
|
|
@ -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
|
|
@ -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: */
|
|
@ -779,6 +779,13 @@ public:
|
||||||
*/
|
*/
|
||||||
GenObject* operator[](int index) const;
|
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
|
* Get the item in the list that holds an object
|
||||||
* @param obj Pointer to the object to search for
|
* @param obj Pointer to the object to search for
|
||||||
|
|
Loading…
Reference in New Issue