diff --git a/autogen.sh b/autogen.sh
old mode 100755
new mode 100644
diff --git a/ekiga.schemas.in.in b/ekiga.schemas.in.in
index 822270f..4eb5b28 100644
@@ -991,5 +991,38 @@
<long>Automatically reject or forward incoming calls if no answer is given after the specified amount of time (in seconds)</long>
</locale>
</schema>
+ <schema>
+ <key>/schemas/apps/@PACKAGE_NAME@/protocols/t140/enable_realtime</key>
+ <applyto>/apps/@PACKAGE_NAME@/protocols/t140/enable_realtime</applyto>
+ <owner>Ekiga</owner>
+ <type>bool</type>
+ <default>true</default>
+ <locale name="C">
+ <short>Enable Realtime</short>
+ <long>Enable Realtime</long>
+ </locale>
+ </schema>
+ <schema>
+ <key>/schemas/apps/@PACKAGE_NAME@/protocols/t140/buffer_time</key>
+ <applyto>/apps/@PACKAGE_NAME@/protocols/t140/buffer_time</applyto>
+ <owner>Ekiga</owner>
+ <type>int</type>
+ <default>300</default>
+ <locale name="C">
+ <short>Buffer time</short>
+ <long>Buffer time (in ms)</long>
+ </locale>
+ </schema>
+ <schema>
+ <key>/schemas/apps/@PACKAGE_NAME@/protocols/t140/character_per_second</key>
+ <applyto>/apps/@PACKAGE_NAME@/protocols/t140/character_per_second</applyto>
+ <owner>Ekiga</owner>
+ <type>int</type>
+ <default>30</default>
+ <locale name="C">
+ <short>Character per Second</short>
+ <long>Character per Second</long>
+ </locale>
+ </schema>
</schemalist>
</gconfschemafile>
diff --git a/help/sv/sv.po b/help/sv/sv.po
old mode 100755
new mode 100644
diff --git a/lib/engine/chat/chat.h b/lib/engine/chat/chat.h
index 94e8de8..5fd2aae 100644
@@ -58,7 +58,8 @@ namespace Ekiga
*
*/
virtual void message (const std::string to,
- const std::string msg) = 0;
+ const std::string msg,
+ bool flag) = 0;
/** Tell the observer about a new service message, like :
* observer.notice ("Snark just disconnected");
@@ -109,6 +110,8 @@ namespace Ekiga
* @return True if it was valid to send a message
*/
virtual bool send_message (const std::string msg) = 0;
+
+ virtual void display_message (const std::string msg) = 0;
/** This signal is emitted when the Chat has been updated.
*/
@@ -130,6 +133,12 @@ namespace Ekiga
/** This chain allows the Chat to present forms to the user.
*/
ChainOfResponsibility<FormRequest*> questions;
+
+ /** True if the chat is enabled real-time text.
+ */
+ virtual bool is_real_time_text_enabled () = 0;
+
+ virtual int real_time_buffering_time () { return 300; }
};
};
diff --git a/lib/engine/components/echo/echo-simple.cpp b/lib/engine/components/echo/echo-simple.cpp
index 6e3789b..1b41dc3 100644
@@ -83,11 +83,20 @@ Echo::SimpleChat::send_message (const std::string msg)
for (std::list<gmref_ptr<Ekiga::ChatObserver> >::iterator iter = observers.begin ();
iter != observers.end ();
++iter)
- (*iter)->message ("Echo", msg);
+ (*iter)->message ("Echo", msg, false);
return true;
}
+void
+Echo::SimpleChat::display_message (const std::string msg)
+{
+ for (std::list<gmref_ptr<Ekiga::ChatObserver> >::iterator iter = observers.begin ();
+ iter != observers.end ();
+ ++iter)
+ (*iter)->message ("Echo", msg, false);
+}
+
const std::string
Echo::SimpleChat::get_title() const
{
index 1c6a307..4c94946 100644
@@ -56,11 +56,15 @@ namespace Echo
void disconnect (gmref_ptr<Ekiga::ChatObserver> observer);
bool send_message (const std::string msg);
+
+ void display_message (const std::string msg);
Ekiga::PresentityPtr get_presentity () const;
bool populate_menu (Ekiga::MenuBuilder &builder);
+ bool is_real_time_text_enabled () { return false; }
+
private:
std::list<gmref_ptr<Ekiga::ChatObserver> > observers;
diff --git a/lib/engine/components/opal/opal-call-manager.cpp b/lib/engine/components/opal/opal-call-manager.cpp
index 2961d8a..0771175 100644
@@ -141,6 +141,13 @@ CallManager::CallManager (Ekiga::ServiceCore & _core)
queue = g_async_queue_new ();
PInterfaceMonitor::GetInstance().SetRefreshInterval (15000);
+
+ // IM media format
+ using_im = false;
+ using_im_media_format = OpalT140;
+ im_media_format = OpalMediaFormat();
+ t140_buffer_time = 300;
+ t140_cps = 30;
}
@@ -156,7 +163,7 @@ void CallManager::set_display_name (const std::string & name)
{
display_name = name;
- SetDefaultDisplayName (display_name);
+ SetDefaultDisplayName ("");
}
@@ -357,7 +364,8 @@ void CallManager::set_codecs (Ekiga::CodecList & _codecs)
}
codecs = _codecs;
-
+ // T140 is the first order and not in the mask, otherwise setup t140 session will fail.
+ order += OpalT140;
//
// Update OPAL
//
@@ -496,6 +504,28 @@ bool CallManager::dial (const std::string & uri)
return false;
}
+bool
+CallManager::make_im_connection (const std::string & uri)
+{
+ std::stringstream ustr;
+
+
+ if (uri.find (":") == string::npos)
+ ustr << "sip:" << uri;
+ else
+ ustr << uri;
+
+ PSafePtr<OpalCall> call = FindCallWithLock(tokens[uri]);
+ if (call) {
+ OpalConnection::StringOptions * options = new OpalConnection::StringOptions();
+ //options->SetAt(OPAL_OPT_AUTO_START, get_im_media_format().GetMediaType() + ":exclusive");
+ options->SetAt(OPAL_OPT_AUTO_START, get_im_media_format().GetMediaType());
+ }
+ }
+ return false;
+}
void CallManager::set_video_options (const CallManager::VideoOptions & options)
{
@@ -616,6 +646,45 @@ void CallManager::get_video_options (CallManager::VideoOptions & options) const
}
}
+bool CallManager::is_using_im (void)
+{
+ return using_im;
+}
+
+const OpalMediaFormat &CallManager::get_using_im_media_format (void)
+{
+ return using_im_media_format;
+}
+
+void CallManager::set_im_media_format (OpalMediaFormat media_format)
+{
+ im_media_format = media_format;
+}
+
+OpalMediaFormat &CallManager::get_im_media_format (void)
+{
+ return im_media_format;
+}
+
+void CallManager::set_t140_buffer_time (int buffer_time)
+{
+ t140_buffer_time = buffer_time;
+}
+
+int CallManager::get_t140_buffer_time () const
+{
+ return t140_buffer_time;
+}
+
+void CallManager::set_t140_cps (int cps)
+{
+ t140_cps = cps;
+}
+
+int CallManager::get_t140_cps () const
+{
+ return t140_cps;
+}
OpalCall *CallManager::CreateCall (void *uri)
{
@@ -644,11 +713,16 @@ CallManager::DestroyCall (OpalCall *_call)
void
CallManager::OnClosedMediaStream (const OpalMediaStream & stream)
{
+ if (stream.GetMediaFormat() == OpalT140) {
+ using_im = false;
+ }
+
OpalMediaFormatList list = pcssEP->GetMediaFormats ();
OpalManager::OnClosedMediaStream (stream);
dynamic_cast <Opal::Call &> (stream.GetConnection ().GetCall ()).OnClosedMediaStream ((OpalMediaStream &) stream);
+
}
@@ -658,14 +732,50 @@ CallManager::OnOpenMediaStream (OpalConnection & connection,
{
OpalMediaFormatList list = pcssEP->GetMediaFormats ();
if (!OpalManager::OnOpenMediaStream (connection, stream))
- return FALSE;
+ return false;
dynamic_cast <Opal::Call &> (connection.GetCall ()).OnOpenMediaStream (stream);
- return TRUE;
+ if (stream.GetMediaFormat() == OpalT140) {
+ // Do not enable T140
+ if (im_media_format != OpalT140) {
+ PTRACE(1, "CallManager\tOnOpenMediaStream disable t140.");
+ return false;
+ }
+ PTRACE(1, "CallManager\tOnOpenMediaStream enable t140.");
+ using_im = true;
+ using_im_media_format = OpalT140;
+// stream.GetMediaFormat().PrintOptions(cout);
+// cout << endl;
+// stream.GetMediaFormat().SetOptionInteger("cps", get_t140_cps());
+// stream.GetMediaFormat().PrintOptions(cout);
+// cout << endl;
+ }
+
+ return true;
+}
+
+
+void CallManager::OnEstablished(OpalConnection &connection)
+{
+ std::string disp_name = (const char *) connection.GetRemotePartyName ();
+ std::string uri = (const char *) "sip:" + disp_name;
+ // For T.140
+ tokens[uri] = connection.GetCall().GetToken();
+
+ OpalManager::OnEstablished(connection);
}
+void CallManager::OnReleased(OpalConnection &connection)
+{
+ std::string disp_name = (const char *) connection.GetRemotePartyName ();
+ std::string uri = (const char *) "sip:" + disp_name;
+ tokens.erase (uri);
+
+ using_im = false;
+ OpalManager::OnReleased(connection);
+}
void CallManager::GetAllowedFormats (OpalMediaFormatList & full_list)
{
@@ -755,3 +865,4 @@ CallManager::ReportSTUNError (const std::string error)
10);
}
}
+
diff --git a/lib/engine/components/opal/opal-call-manager.h b/lib/engine/components/opal/opal-call-manager.h
index 421502e..75fa340 100644
@@ -88,6 +88,8 @@ public:
/** Call Manager **/
bool dial (const std::string & uri);
+ bool make_im_connection (const std::string & uri);
+
void set_display_name (const std::string & name);
const std::string & get_display_name () const;
@@ -151,6 +153,21 @@ public:
void set_video_options (const VideoOptions & options);
void get_video_options (VideoOptions & options) const;
+ /* T140 */
+ bool is_using_im (void);
+ const OpalMediaFormat &get_using_im_media_format (void);
+
+ void set_im_media_format (OpalMediaFormat im_media_format);
+ OpalMediaFormat &get_im_media_format (void);
+
+ void set_t140_buffer_time (int buffer_time);
+ int get_t140_buffer_time () const;
+
+ void set_t140_cps (int cps);
+ int get_t140_cps () const;
+
+ PString &find_token_with_uri (const PString &uri) { return tokens[uri]; }
+
private:
OpalCall *CreateCall (void *uri);
void DestroyCall (OpalCall *);
@@ -160,6 +177,10 @@ private:
void OnClosedMediaStream (const OpalMediaStream &);
+ void OnEstablished (OpalConnection &connection);
+
+ void OnReleased (OpalConnection &connection);
+
void GetAllowedFormats (OpalMediaFormatList & full_list);
void HandleSTUNResult ();
@@ -187,6 +208,15 @@ private:
bool unconditional_forward;
bool forward_on_no_answer;
bool stun_enabled;
+
+ std::map<std::string, PString> tokens; // <uri, token>
+
+ /* which im format to use */
+ bool using_im;
+ OpalMediaFormat using_im_media_format;
+ OpalMediaFormat im_media_format;
+ int t140_buffer_time;
+ int t140_cps;
};
};
#endif
diff --git a/lib/engine/components/opal/opal-gmconf-bridge.cpp b/lib/engine/components/opal/opal-gmconf-bridge.cpp
index baf5d8b..aef24a7 100644
@@ -60,6 +60,7 @@
#define SIP_KEY "/apps/" PACKAGE_NAME "/protocols/sip/"
#define PORTS_KEY "/apps/" PACKAGE_NAME "/protocols/ports/"
#define CALL_FORWARDING_KEY "/apps/" PACKAGE_NAME "/protocols/call_forwarding/"
+#define TEXT_KEY "/apps/" PACKAGE_NAME "/protocols/t140/"
#define AUDIO_CODECS_KEY "/apps/" PACKAGE_NAME "/codecs/audio/"
#define VIDEO_CODECS_KEY "/apps/" PACKAGE_NAME "/codecs/video/"
@@ -78,6 +79,10 @@ ConfBridge::ConfBridge (Ekiga::Service & _service)
keys.push_back (AUDIO_CODECS_KEY "enable_silence_detection");
keys.push_back (AUDIO_CODECS_KEY "enable_echo_cancelation");
+ keys.push_back (TEXT_KEY "enable_realtime");
+ keys.push_back (TEXT_KEY "buffer_time");
+ keys.push_back (TEXT_KEY "character_per_second");
+
keys.push_back (AUDIO_CODECS_KEY "media_list");
keys.push_back (VIDEO_CODECS_KEY "media_list");
@@ -289,6 +294,31 @@ void ConfBridge::on_property_changed (std::string key, GmConfEntry *entry)
}
//
+ // TEXT related keys
+ //
+ else if (key.find (TEXT_KEY) != string::npos) {
+
+ if (key == TEXT_KEY "buffer_time") {
+
+ manager.set_t140_buffer_time (gm_conf_entry_get_int (entry));
+ }
+ else if (key == TEXT_KEY "character_per_second") {
+
+ manager.set_t140_cps (gm_conf_entry_get_int (entry));
+ }
+ else if (key == TEXT_KEY "enable_realtime") {
+ if (gm_conf_entry_get_bool (entry)) {
+
+ PTRACE(1, "opal-gmconf-bridge\tEnable t140.");
+ manager.set_im_media_format(OpalT140);
+ } else {
+ PTRACE(1, "opal-gmconf-bridge\tDisable t140.");
+ manager.set_im_media_format(OpalMediaFormat ());
+ }
+ }
+ }
+
+ //
// H.323 keys
//
#ifdef HAVE_H323
diff --git a/lib/engine/components/opal/pcss-endpoint.cpp b/lib/engine/components/opal/pcss-endpoint.cpp
index 8727fb1..68099b2 100644
@@ -40,10 +40,10 @@
#include "pcss-endpoint.h"
#include "opal-call-manager.h"
+#include "sip-endpoint.h"
#include "call.h"
-
GMPCSSEndpoint::GMPCSSEndpoint (Opal::CallManager & ep,
Ekiga::ServiceCore & _core)
: OpalPCSSEndPoint (ep),
@@ -54,16 +54,32 @@ GMPCSSEndpoint::GMPCSSEndpoint (Opal::CallManager & ep,
#else
SetSoundChannelBufferDepth (5);
#endif
+
}
-bool GMPCSSEndpoint::OnShowIncoming (const OpalPCSSConnection & /*connection*/)
+bool GMPCSSEndpoint::OnShowIncoming (const OpalPCSSConnection & connection)
{
+ ((OpalConnection &)connection).AddIMListener(PCREATE_NOTIFIER(OnReceiveIM));
return true;
}
-bool GMPCSSEndpoint::OnShowOutgoing (const OpalPCSSConnection & /*connection*/)
+bool GMPCSSEndpoint::OnShowOutgoing (const OpalPCSSConnection & connection)
{
+ ((OpalConnection &)connection).AddIMListener(PCREATE_NOTIFIER(OnReceiveIM));
return true;
}
+
+void GMPCSSEndpoint::OnReceiveIM(OpalConnection::IMInfo & im, INT conn)
+{
+ OpalConnection *connection = (OpalConnection *) conn;
+
+ std::string display_name = (const char *) connection->GetRemotePartyName ();
+ std::string message_uri = (const char *) "sip:" + display_name;
+ std::string message = (const char *)im.body.GetPointer();
+
+ OpalEndPoint *sip = GetManager().FindEndPoint ("sip");
+ dynamic_cast<Opal::Sip::EndPoint*>(sip)->OnReceivedIM(message_uri, display_name, message, (void *)conn);
+}
+
diff --git a/lib/engine/components/opal/pcss-endpoint.h b/lib/engine/components/opal/pcss-endpoint.h
index 4ee2ea3..300c381 100644
@@ -45,6 +45,8 @@
#include <opal/opal.h>
#include <opal/pcss.h>
+#include "chat-core.h"
+
namespace Opal {
class CallManager;
}
@@ -60,7 +62,10 @@ public:
bool OnShowOutgoing (const OpalPCSSConnection &connection);
+ PDECLARE_NOTIFIER(OpalConnection::IMInfo, GMPCSSEndpoint, OnReceiveIM);
+
private:
+
Ekiga::ServiceCore & core;
};
diff --git a/lib/engine/components/opal/sip-chat-simple.cpp b/lib/engine/components/opal/sip-chat-simple.cpp
index aa23eff..d99a6aa 100644
@@ -47,6 +47,7 @@ SIP::SimpleChat::SimpleChat (Ekiga::ServiceCore& core_,
{
presentity = gmref_ptr<Ekiga::URIPresentity> (new Ekiga::URIPresentity (core, name, uri,
std::set<std::string>()));
+ call_manager = core.get ("opal-component");
}
SIP::SimpleChat::~SimpleChat ()
@@ -85,13 +86,20 @@ bool
SIP::SimpleChat::send_message (const std::string msg)
{
bool result;
- gmref_ptr<Ekiga::PersonalDetails> personal = core.get ("personal-details");
+ //gmref_ptr<Ekiga::PersonalDetails> personal = core.get ("personal-details");
result = sender (msg);
+
+ return result;
+}
+
+void
+SIP::SimpleChat::display_message (const std::string msg)
+{
+ gmref_ptr<Ekiga::PersonalDetails> personal = core.get ("personal-details");
for (std::list<gmref_ptr<Ekiga::ChatObserver> >::iterator iter = observers.begin ();
iter != observers.end ();
++iter)
- (*iter)->message (personal->get_display_name (), msg);
- return result;
+ (*iter)->message (personal->get_display_name (), msg, false);
}
void
@@ -100,7 +108,7 @@ SIP::SimpleChat::receive_message (const std::string msg)
for (std::list<gmref_ptr<Ekiga::ChatObserver> >::iterator iter = observers.begin ();
iter != observers.end ();
++iter)
- (*iter)->message (presentity->get_name (), msg);
+ (*iter)->message (presentity->get_name (), msg, true);
}
void
@@ -123,3 +131,15 @@ SIP::SimpleChat::populate_menu (Ekiga::MenuBuilder& /*builder*/)
{
return false;
}
+
+bool
+SIP::SimpleChat::is_real_time_text_enabled ()
+{
+ return call_manager->is_using_im();
+}
+
+int
+SIP::SimpleChat::real_time_buffering_time ()
+{
+ return call_manager->get_t140_buffer_time();
+}
diff --git a/lib/engine/components/opal/sip-chat-simple.h b/lib/engine/components/opal/sip-chat-simple.h
index 7a3de61..5e15814 100644
@@ -40,6 +40,7 @@
#include "chat-simple.h"
#include "services.h"
+#include "opal-call-manager.h"
namespace SIP
{
@@ -63,6 +64,8 @@ namespace SIP
bool send_message (const std::string msg);
+ void display_message (const std::string msg);
+
void receive_message (const std::string msg);
void receive_notice (const std::string msg);
@@ -71,6 +74,10 @@ namespace SIP
bool populate_menu (Ekiga::MenuBuilder& builder);
+ bool is_real_time_text_enabled ();
+
+ int real_time_buffering_time ();
+
private:
Ekiga::ServiceCore& core;
@@ -78,6 +85,7 @@ namespace SIP
std::list<gmref_ptr<Ekiga::ChatObserver> > observers;
Ekiga::PresentityPtr presentity;
std::string uri;
+ gmref_ptr<Opal::CallManager> call_manager;
};
typedef gmref_ptr<SimpleChat> SimpleChatPtr;
diff --git a/lib/engine/components/opal/sip-endpoint.cpp b/lib/engine/components/opal/sip-endpoint.cpp
index ece5f98..85d1171 100644
@@ -352,15 +352,24 @@ Opal::Sip::EndPoint::send_message (const std::string & _uri,
{
if (!_uri.empty () && (_uri.find ("sip:") == 0 || _uri.find (':') == string::npos) && !_message.empty ()) {
- SIPEndPoint::Message (_uri, _message);
-
+ if (manager.is_using_im()) {
+ PSafePtr<OpalCall> call = manager.FindCallWithLock(manager.find_token_with_uri(_uri));
+
+ if (call != NULL) {
+ PSafePtr<OpalPCSSConnection> conn = call->GetConnectionAs<OpalPCSSConnection>();
+ if (conn != NULL) {
+ conn->SendIM(manager.get_using_im_media_format(), T140String(_message));
+ }
+ }
+ } else {
+ SIPEndPoint::Message (_uri, _message);
+ }
return true;
}
return false;
}
-
bool
Opal::Sip::EndPoint::dial (const std::string & uri)
{
@@ -373,8 +382,14 @@ Opal::Sip::EndPoint::dial (const std::string & uri)
else
ustr << uri;
- PString token;
+ OpalConnection::StringOptions *options = NULL;
+
+ if (manager.get_im_media_format() == OpalT140) {
+ options = new OpalConnection::StringOptions();
+ options->SetAt(OPAL_OPT_AUTO_START, manager.get_im_media_format().GetMediaType());
+ }
+
+ manager.SetUpCall("pc:*", ustr.str(), manager.find_token_with_uri(uri), (void*) ustr.str().c_str(), 0, options);
return true;
}
@@ -382,7 +397,6 @@ Opal::Sip::EndPoint::dial (const std::string & uri)
return false;
}
-
const std::string&
Opal::Sip::EndPoint::get_protocol_name () const
{
@@ -890,6 +904,7 @@ Opal::Sip::EndPoint::OnIncomingConnection (OpalConnection &connection,
else {
Opal::Call *call = dynamic_cast<Opal::Call *> (&connection.GetCall ());
+
if (call) {
if (!forward_uri.empty () && manager.get_forward_on_no_answer ())
@@ -911,7 +926,6 @@ Opal::Sip::EndPoint::OnReceivedMESSAGE (OpalTransport & transport,
{
PString *last = NULL;
PString *val = NULL;
-
PString from = pdu.GetMIME().GetFrom();
PINDEX j = from.Find (';');
if (j != P_MAX_INDEX)
@@ -939,6 +953,14 @@ Opal::Sip::EndPoint::OnReceivedMESSAGE (OpalTransport & transport,
return SIPEndPoint::OnReceivedMESSAGE (transport, pdu);
}
+void
+Opal::Sip::EndPoint::OnReceivedIM (std::string &uri,
+ std::string &display_name,
+ std::string &message,
+ void *conn)
+{
+ Ekiga::Runtime::run_in_main (sigc::bind (sigc::mem_fun (this, &Opal::Sip::EndPoint::push_message_in_main), uri, display_name, message));
+}
void
Opal::Sip::EndPoint::OnMessageFailed (const SIPURL & messageUrl,
@@ -954,7 +976,6 @@ Opal::Sip::EndPoint::OnMessageFailed (const SIPURL & messageUrl,
_("Could not send message")));
}
-
SIPURL
Opal::Sip::EndPoint::GetRegisteredPartyName (const SIPURL & aor,
const OpalTransport & transport)
index 7fbd6b2..5c6598c 100644
@@ -114,7 +114,6 @@ namespace Opal {
bool send_message (const std::string & uri,
const std::string & message);
-
/* CallProtocolManager */
bool dial (const std::string & uri);
@@ -180,13 +179,17 @@ namespace Opal {
bool OnReceivedMESSAGE (OpalTransport & transport,
SIP_PDU & pdu);
+ void OnReceivedIM (std::string &uri,
+ std::string &display_name,
+ std::string &message,
+ void *conn);
+
void OnMessageFailed (const SIPURL & messageUrl,
SIP_PDU::StatusCodes reason);
SIPURL GetRegisteredPartyName (const SIPURL & host,
const OpalTransport & transport);
-
/* Callbacks */
private:
void on_dial (std::string uri);
index 663ee68..14ea57a 100644
@@ -55,6 +55,12 @@
class ChatAreaHelper;
+struct _HistoryMessage
+{
+ gint number;
+ GSList* next;
+};
+
struct _ChatAreaPrivate
{
Ekiga::Chat* chat;
@@ -67,6 +73,15 @@ struct _ChatAreaPrivate
GtkWidget* scrolled_text_window;
GtkWidget* text_view;
GtkWidget* message;
+ GTimeVal buffering_timer_stop_time;
+ guint buffering_timer_id;
+ gint buffering_time;
+ gint bp;
+ gint cp_min;
+ gint line_number;
+ GHashTable* hash;
+ GSList* list;
+ gchar* local_name;
};
enum {
@@ -84,13 +99,23 @@ static GObjectClass* parent_class = NULL;
/* declaration of internal api */
+static gboolean message_send_after_buffering (gpointer data);
+
+static void start_buffering_timer (ChatArea* self);
+
+static gboolean buffering_timer_is_started (ChatArea* self);
+
static void chat_area_add_notice (ChatArea* self,
const gchar* txt);
-static void chat_area_add_message (ChatArea* self,
+static void chat_area_add_local_message (ChatArea* self,
const gchar* from,
const gchar* txt);
+static void chat_area_add_remote_message (ChatArea* self,
+ const gchar* from,
+ const gchar* txt);
+
/* declaration of the helping observer */
class ChatAreaHelper: public Ekiga::ChatObserver
{
@@ -102,8 +127,15 @@ public:
{}
void message (const std::string from,
- const std::string msg)
- { chat_area_add_message (area, from.c_str (), msg.c_str ()); }
+ const std::string msg,
+ bool flag)
+ {
+ if (flag) {
+ chat_area_add_remote_message (area, from.c_str (), msg.c_str ());
+ } else {
+ chat_area_add_local_message (area, from.c_str (), msg.c_str ());
+ }
+ }
void notice (const std::string msg)
{ chat_area_add_notice (area, msg.c_str ()); }
@@ -154,6 +186,12 @@ static gboolean message_activated_cb (GtkWidget *w,
GdkEventKey *key,
gpointer data);
+static void message_changed_cb (GtkTextBuffer *textbuffer,
+ gpointer user_data);
+
+static void backspace_activated_cb (GtkTextView *textview,
+ gpointer user_data);
+
static void on_chat_removed (ChatArea* self);
static void on_chat_area_grab_focus (GtkWidget*,
@@ -210,6 +248,90 @@ gm_chat_area_define_simple_text_tag (GtkTextBuffer* buffer,
* owned by the buffer's tag table */
}
+static gboolean
+message_send_after_buffering (gpointer data)
+{
+ ChatArea *self = CHAT_AREA (data);
+ GtkTextIter cp_min_iter, end_iter;
+ GtkTextBuffer *buffer = NULL;
+ gchar* body = NULL;
+ gint cp = 0; // cursor point
+
+ g_return_val_if_fail (data != NULL, FALSE);
+
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (self->priv->message));
+ gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER (buffer), &end_iter);
+ cp = gtk_text_iter_get_offset(&end_iter);
+
+ if (self->priv->cp_min != self->priv->bp || self->priv->bp != cp) {
+
+ if (self->priv->buffering_timer_id > 0) {
+ send_immediately:
+ gchar *backspace_str = NULL;
+ gchar *message = NULL;
+
+ gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER (buffer), &cp_min_iter, self->priv->cp_min);
+
+ body = gtk_text_buffer_get_text (GTK_TEXT_BUFFER (buffer), &cp_min_iter, &end_iter, TRUE);
+
+ if (self->priv->cp_min < self->priv->bp) {
+ backspace_str = g_strnfill(self->priv->bp - self->priv->cp_min, '\b');
+ message = g_strconcat (backspace_str, body, NULL);
+ g_free(body);
+ g_free(backspace_str);
+ } else {
+ message = body;
+ }
+
+ if (self->priv->chat->send_message (message)) {
+ self->priv->bp = cp;
+ self->priv->cp_min = cp;
+ }
+
+ g_free(message);
+
+ } else {
+ GTimeVal now;
+ GTimeVal last = self->priv->buffering_timer_stop_time;
+ /* Detect if it is after an idle period time (a buffering time) */
+ g_get_current_time(&now);
+ g_time_val_add(&last, self->priv->buffering_time);
+ // Start buffer timer anyway
+ start_buffering_timer(self);
+ if (now.tv_sec > last.tv_sec
+ // Send at once
+ goto send_immediately;
+ // } else {
+ // postpone to the next buffering time
+ }
+ }
+ } else {
+ // No changes
+ /* Update timer stop time */
+ g_get_current_time(&self->priv->buffering_timer_stop_time);
+ self->priv->buffering_timer_id = 0;
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static void
+start_buffering_timer (ChatArea* self)
+{
+ if (self->priv->buffering_timer_id == 0) {
+ self->priv->buffering_timer_id = g_timeout_add (self->priv->buffering_time,
+ (GSourceFunc)message_send_after_buffering,
+ self);
+ }
+}
+
+static gboolean
+buffering_timer_is_started (ChatArea* self)
+{
+ return self->priv->buffering_timer_id != 0;
+}
static void
chat_area_add_notice (ChatArea* self,
@@ -235,25 +357,188 @@ chat_area_add_notice (ChatArea* self,
}
static void
-chat_area_add_message (ChatArea* self,
- const gchar* from,
- const gchar* txt)
+chat_area_add_local_message (ChatArea* self,
+ const gchar* from,
+ const gchar* txt)
{
gchar* str = NULL;
GtkTextMark *mark = NULL;
GtkTextBuffer* buffer = NULL;
GtkTextIter iter;
- str = g_strdup_printf ("<b><i>%s %s</i></b>\n%s\n", from, _("says:"), txt);
+ str = g_strdup_printf ("<b><i>%s %s</i></b>\n%s", from, _("says:"), txt);
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (self->priv->text_view));
gtk_text_buffer_get_end_iter (buffer, &iter);
- gm_text_buffer_enhancer_insert_text (self->priv->enhancer, &iter,
- str, -1);
+
+ if (self->priv->chat->is_real_time_text_enabled()) {
+ gtk_text_iter_set_line (&iter, self->priv->line_number);
+ gm_text_buffer_enhancer_insert_text (self->priv->enhancer, &iter,
+ str, -1);
+
+ self->priv->line_number = gtk_text_iter_get_line (&iter);
+ g_free (self->priv->local_name);
+ self->priv->local_name = g_strdup (from);
+
+ _HistoryMessage* history_message = g_new (_HistoryMessage, 1);
+ history_message->number = self->priv->line_number;
+ history_message->next = (GSList*)g_hash_table_lookup (self->priv->hash, from);
+
+ self->priv->list = g_slist_prepend (self->priv->list, history_message);
+
+ g_hash_table_insert (self->priv->hash, (gpointer)g_strdup(from), (gpointer)(self->priv->list));
+
+ } else {
+ gm_text_buffer_enhancer_insert_text (self->priv->enhancer, &iter,
+ str, -1);
+
+ }
+
g_free (str);
mark = gtk_text_buffer_get_mark (buffer, "current-position");
gtk_text_view_scroll_to_mark (GTK_TEXT_VIEW (self->priv->text_view), mark,
- 0.0, FALSE, 0,0);
+ 0.0, FALSE, 0,0);
+
+ g_signal_emit (self, signals[MESSAGE_NOTICE_EVENT], 0);
+
+}
+
+static void
+chat_area_add_remote_message (ChatArea* self,
+ const gchar* from,
+ const gchar* txt)
+{
+#define ZERO_WIDTH_NO_BREAK 0xfeff
+ GtkTextMark *mark = NULL;
+ GtkTextBuffer* buffer = NULL;
+ GtkTextIter start_iter, end_iter;
+ gchar* str = NULL;
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (self->priv->text_view));
+ gtk_text_buffer_get_end_iter (buffer, &end_iter);
+
+ if (self->priv->chat->is_real_time_text_enabled()) {
+
+ g_return_if_fail(g_utf8_validate(txt, -1, NULL));
+ gchar *iter = (gchar *)txt;
+ glong len = g_utf8_strlen(txt, -1);
+ glong i = 0;
+ gunichar uc;
+
+ while(i < len) {
+ uc = g_utf8_get_char(iter);
+ g_message("Get unichar 0x%x", uc);
+
+ if (uc == '\n') {
+ gboolean flag;
+ gchar *body = NULL;
+
+ gtk_text_buffer_get_end_iter (buffer, &start_iter);
+ gtk_text_iter_set_line (&start_iter, -1);
+
+ body = gtk_text_buffer_get_text (GTK_TEXT_BUFFER (buffer), &start_iter, &end_iter, TRUE);
+ flag = gtk_text_iter_backward_line(&start_iter);
+
+ gtk_text_buffer_delete (GTK_TEXT_BUFFER (buffer), &start_iter, &end_iter);
+ str = g_strdup_printf ("<b><i>%s %s</i></b>\n%s\n", from, _("says:"), body);
+ gm_text_buffer_enhancer_insert_text (self->priv->enhancer, &end_iter,
+ str, -1);
+
+ gtk_text_buffer_get_end_iter (buffer, &end_iter);
+ self->priv->line_number = gtk_text_iter_get_line (&end_iter);
+
+ _HistoryMessage* history_message = g_new (_HistoryMessage, 1);
+ history_message->number = self->priv->line_number;
+ history_message->next = (GSList*)g_hash_table_lookup (self->priv->hash, from);
+
+ self->priv->list = g_slist_prepend (self->priv->list, history_message);
+
+ g_hash_table_insert(self->priv->hash, (gpointer)g_strdup(from), (gpointer)(self->priv->list));
+
+ g_free (body);
+
+ } else if(uc == '\b') {
+
+ GSList* lookup_ptr = (GSList*)g_hash_table_lookup (self->priv->hash, from);
+
+ if (0 == gtk_text_iter_get_line_offset (&end_iter) && (lookup_ptr != NULL)) {
+
+ _HistoryMessage* _historymessage = (_HistoryMessage*)(lookup_ptr->data);
+ gint from_number = (_historymessage)->number;
+ gboolean flag;
+ gchar* body = NULL;
+ GSList* ptr = NULL;
+
+ gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (buffer), &start_iter);
+ gtk_text_iter_set_line (&start_iter, from_number-1);
+
+ gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER (buffer), &end_iter);
+ gtk_text_iter_set_line (&end_iter, from_number-1);
+ gtk_text_iter_forward_to_line_end (&end_iter);
+
+ body = gtk_text_buffer_get_text (GTK_TEXT_BUFFER (buffer), &start_iter, &end_iter, TRUE);
+ flag = gtk_text_iter_backward_line (&start_iter);
+ flag = gtk_text_iter_forward_char (&end_iter);
+ gtk_text_buffer_delete (GTK_TEXT_BUFFER (buffer), &start_iter, &end_iter);
+
+ for (ptr = self->priv->list;
+ ptr!= lookup_ptr;
+ ptr = g_slist_next (ptr)) {
+ ((_HistoryMessage*)(ptr->data))->number -= 2;
+ }
+
+ gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER (buffer), &end_iter);
+ str = g_strdup_printf ("<b>%s %s</b>\n%s", from, _("is typing:"), body);
+ gm_text_buffer_enhancer_insert_text (self->priv->enhancer, &end_iter,
+ str, -1);
+ g_free (body);
+
+ self->priv->line_number -= 2;
+
+ g_hash_table_insert (self->priv->hash, (gpointer)g_strdup (from), (gpointer)(_historymessage->next));
+ g_free (_historymessage);
+ self->priv->list = g_slist_delete_link (self->priv->list, lookup_ptr);
+
+ } else {
+ gtk_text_buffer_get_end_iter (buffer, &start_iter);
+ gtk_text_iter_backward_char (&start_iter);
+ gtk_text_buffer_delete (GTK_TEXT_BUFFER (buffer), &start_iter, &end_iter);
+
+ if (0 == gtk_text_iter_get_line_offset (&end_iter)){
+ gtk_text_iter_backward_line (&start_iter);
+ gtk_text_buffer_delete (GTK_TEXT_BUFFER (buffer), &start_iter, &end_iter);
+ }
+ }
+ } else if (uc == ZERO_WIDTH_NO_BREAK) {
+ ; // Ignore
+ } else {
+ gchar out[7];
+
+ out[g_unichar_to_utf8(uc, out)] = '\0';
+ gtk_text_buffer_get_start_iter (buffer, &start_iter);
+
+ if (self->priv->line_number == gtk_text_iter_get_line (&end_iter)) {
+ str = g_strdup_printf ("<b>%s %s</b>\n%s", from, _("is typing:"), out);
+ } else {
+ str = g_strdup(out);
+ }
+
+ gm_text_buffer_enhancer_insert_text (self->priv->enhancer, &end_iter,
+ str, -1);
+ }
+
+ iter = g_utf8_next_char(iter);
+ i++;
+ }
+ } else {
+ str = g_strdup_printf ("<b><i>%s %s</i></b>\n%s", from, _("says:"), txt);
+ gm_text_buffer_enhancer_insert_text (self->priv->enhancer, &end_iter,
+ str, -1);
+ }
+ g_free (str);
+
+ mark = gtk_text_buffer_get_mark (buffer, "current-position");
+ gtk_text_view_scroll_to_mark (GTK_TEXT_VIEW (self->priv->text_view), mark,
+ 0.0, FALSE, 0,0);
g_signal_emit (self, signals[MESSAGE_NOTICE_EVENT], 0);
}
@@ -547,32 +832,150 @@ message_activated_cb (G_GNUC_UNUSED GtkWidget *w,
gpointer data)
{
ChatArea *self = CHAT_AREA (data);
- GtkTextIter start_iter, end_iter;
+ GtkTextIter end_iter;
GtkTextBuffer *buffer = NULL;
- gchar *body = NULL;
- std::string message;
g_return_val_if_fail (data != NULL, false);
- if (key->keyval == GDK_Return) {
-
+ if (self->priv->chat->is_real_time_text_enabled()) {
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (self->priv->message));
- gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (buffer), &start_iter);
gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER (buffer), &end_iter);
+ gtk_text_buffer_place_cursor (GTK_TEXT_BUFFER (buffer), &end_iter);
+ }
+
+ return false;
+}
+
+static void
+message_changed_cb (GtkTextBuffer *buffer, gpointer data)
+{
+ ChatArea *self = CHAT_AREA (data);
+ GtkTextIter start_iter, end_iter, last_iter;
+ gchar* body = NULL;
+ gunichar keyval;
+ gboolean realtime_im = self->priv->chat->is_real_time_text_enabled();
+
+ g_return_if_fail (data != NULL);
+
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (self->priv->message));
+ gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER (buffer), &end_iter);
+ last_iter = end_iter;
+ gint offset = gtk_text_iter_get_offset(&end_iter);
+
+ if (gtk_text_iter_backward_char(&last_iter)) {
+ keyval = gtk_text_iter_get_char (&last_iter);
+
+ if (keyval == '\n') {
+
+ gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (buffer), &start_iter);
+
+ if (offset == 1) {
+ // Only a Return
+ gtk_text_buffer_delete (GTK_TEXT_BUFFER (buffer), &start_iter, &end_iter);
+ return;
+ }
- /* if nothing to send - send nothing ;-) */
- if (gtk_text_iter_get_offset (&end_iter) == 0)
- return TRUE;
+ body = gtk_text_buffer_get_text (GTK_TEXT_BUFFER (buffer), &start_iter, &end_iter, TRUE);
+
+ self->priv->chat->display_message (body);
- body = gtk_text_buffer_get_text (GTK_TEXT_BUFFER (buffer), &start_iter, &end_iter, TRUE);
+ if (!realtime_im) {
+ self->priv->chat->send_message (body);
+ } else {
+ // Start buffer timer anyway, so we can make sure message must
+ // be sent.
+ start_buffering_timer(self);
+ message_send_after_buffering(data);
+
+ // Reset pointer since we are clean the input buffer.
+ self->priv->bp = 0;
+ self->priv->cp_min = 0;
+ }
- if (self->priv->chat->send_message (body))
gtk_text_buffer_delete (GTK_TEXT_BUFFER (buffer), &start_iter, &end_iter);
- return true;
+ g_free (body);
+
+ return;
+ }
}
- return false;
+ if (realtime_im) {
+ if (self->priv->cp_min > offset) {
+ self->priv->cp_min = offset;
+ }
+
+ gtk_text_buffer_place_cursor(buffer, &end_iter);
+
+ if (!buffering_timer_is_started(self)) {
+ message_send_after_buffering(data);
+ }
+ }
+}
+
+static void
+backspace_activated_cb (GtkTextView *textview, gpointer data)
+{
+ ChatArea *self = CHAT_AREA (data);
+ GtkTextIter start_iter, end_iter, last_iter;
+ gchar* body = NULL;
+ g_return_if_fail (data != NULL);
+
+ GtkTextBuffer* buffer = gtk_text_view_get_buffer (textview);
+ gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER (buffer), &end_iter);
+ last_iter = end_iter;
+ gint offset = gtk_text_iter_get_offset (&end_iter);
+
+ if (self->priv->chat->is_real_time_text_enabled()) {
+ GSList* lookup_ptr = (GSList*)g_hash_table_lookup (self->priv->hash, self->priv->local_name);
+
+ if ((offset == 0) && (lookup_ptr != NULL)) {
+
+ _HistoryMessage* _historymessage = (_HistoryMessage*)(lookup_ptr->data);
+ gint from_number = _historymessage->number;
+ gboolean flag;
+ GSList* ptr = NULL;
+ glong len = 0;
+
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (self->priv->text_view));
+ gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (buffer), &start_iter);
+ gtk_text_iter_set_line (&start_iter, from_number-1);
+
+ gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER (buffer), &end_iter);
+ gtk_text_iter_set_line (&end_iter, from_number-1);
+ gtk_text_iter_forward_to_line_end (&end_iter);
+
+ body = gtk_text_buffer_get_text (GTK_TEXT_BUFFER (buffer), &start_iter, &end_iter, TRUE);
+ // len does not contain "\n"
+ len = g_utf8_strlen (body, -1);
+
+ flag = gtk_text_iter_forward_char (&end_iter);
+ flag = gtk_text_iter_backward_line (&start_iter);
+ gtk_text_buffer_delete (GTK_TEXT_BUFFER (buffer), &start_iter, &end_iter);
+
+ for(ptr = self->priv->list;
+ ptr!= lookup_ptr;
+ ptr = g_slist_next (ptr)) {
+ ((_HistoryMessage*)(ptr->data))->number -= 2;
+ }
+
+ self->priv->line_number -= 2;
+
+ g_hash_table_insert(self->priv->hash, (gpointer)g_strdup (self->priv->local_name), (gpointer)(_historymessage->next));
+
+ g_free (_historymessage);
+ self->priv->list = g_slist_delete_link (self->priv->list, lookup_ptr);
+
+ self->priv->cp_min = len;
+ self->priv->bp += len + 1;
+
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (self->priv->message));
+ gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (buffer), &start_iter);
+ gtk_text_buffer_insert (buffer, &start_iter, body, -1);
+
+ g_free (body);
+ }
+ }
}
static void
@@ -637,6 +1040,10 @@ chat_area_finalize (GObject* obj)
self = (ChatArea*)obj;
+ if (self->priv->buffering_timer_id > 0) {
+ g_source_remove (self->priv->buffering_timer_id);
+ }
+
if (self->priv->chat) {
self->priv->connection.disconnect ();
@@ -647,6 +1054,11 @@ chat_area_finalize (GObject* obj)
self->priv->chat = NULL;
}
+ g_free (self->priv->local_name);
+ g_slist_foreach (self->priv->list, (GFunc) g_free, NULL);
+ g_slist_free (self->priv->list);
+ g_hash_table_destroy(self->priv->hash);
+
parent_class->finalize (obj);
}
@@ -691,6 +1103,7 @@ chat_area_set_property (GObject* obj,
self->priv->connection = self->priv->chat->removed.connect (sigc::bind (sigc::ptr_fun (on_chat_removed), self));
self->priv->helper = gmref_ptr<ChatAreaHelper>(new ChatAreaHelper (self));
self->priv->chat->connect (self->priv->helper);
+ self->priv->buffering_time = self->priv->chat->real_time_buffering_time();
break;
default:
@@ -757,6 +1170,15 @@ chat_area_init (GTypeInstance* instance,
TYPE_CHAT_AREA,
ChatAreaPrivate);
self->priv->chat = NULL;
+ self->priv->buffering_timer_id = 0;
+ self->priv->buffering_time = 300;
+ self->priv->local_name = g_strdup ("");
+ self->priv->bp = 0;
+ self->priv->cp_min = 0;
+ self->priv->line_number = 0;
+ self->priv->hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+ self->priv->list = NULL;
+
/* first the area has a text view to display
the GtkScrolledWindow is there to make
@@ -778,7 +1200,7 @@ chat_area_init (GTypeInstance* instance,
gtk_text_view_set_justification (GTK_TEXT_VIEW (self->priv->text_view),
GTK_JUSTIFY_LEFT);
gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (self->priv->text_view),
- GTK_WRAP_WORD);
+ GTK_WRAP_WORD_CHAR);
gtk_text_view_set_left_margin (GTK_TEXT_VIEW (self->priv->text_view),
2);
gtk_text_view_set_right_margin (GTK_TEXT_VIEW (self->priv->text_view),
@@ -959,11 +1381,22 @@ chat_area_init (GTypeInstance* instance,
gtk_box_pack_start (GTK_BOX (vbox), sep, FALSE, FALSE, 0);
self->priv->message = gtk_text_view_new ();
+
gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (self->priv->message),
GTK_WRAP_WORD_CHAR);
- gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (self->priv->message), true);
+ gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (self->priv->message), TRUE);
+
g_signal_connect (GTK_OBJECT (self->priv->message), "key-press-event",
G_CALLBACK (message_activated_cb), self);
+
+ g_signal_connect (gtk_text_view_get_buffer (GTK_TEXT_VIEW (self->priv->message)),
+ "changed",
+ G_CALLBACK (message_changed_cb), self);
+
+ g_signal_connect (GTK_TEXT_VIEW (self->priv->message),
+ "backspace",
+ G_CALLBACK (backspace_activated_cb), self);
+
gtk_box_pack_start (GTK_BOX (vbox), self->priv->message,
TRUE, TRUE, 2);
diff --git a/lib/pixops/convert b/lib/pixops/convert
old mode 100755
new mode 100644
old mode 100755
new mode 100644
old mode 100755
new mode 100644
old mode 100755
new mode 100644
old mode 100755
new mode 100644
old mode 100755
new mode 100644
old mode 100755
new mode 100644
old mode 100755
new mode 100644
old mode 100755
new mode 100644
old mode 100755
new mode 100644
old mode 100755
new mode 100644
diff --git a/pixmaps/conv-icon.pl b/pixmaps/conv-icon.pl
old mode 100755
new mode 100644
old mode 100755
new mode 100644
diff --git a/src/common.h b/src/common.h
index 5c3183a..b9407a8 100644
--- a/src/common.h
+++ b/src/common.h
@@ -69,6 +69,7 @@
#define PORTS_KEY "/apps/" PACKAGE_NAME "/protocols/ports/"
#define CALL_FORWARDING_KEY "/apps/" PACKAGE_NAME "/protocols/call_forwarding/"
#define LDAP_KEY "/apps/" PACKAGE_NAME "/protocols/ldap/"
+#define TEXT_KEY "/apps/" PACKAGE_NAME "/protocols/t140/"
#define CODECS_KEY "/apps/" PACKAGE_NAME "/codecs/"
#define AUDIO_CODECS_KEY "/apps/" PACKAGE_NAME "/codecs/audio/"
#define VIDEO_CODECS_KEY "/apps/" PACKAGE_NAME "/codecs/video/"
index f0f680f..10eae4e 100755
@@ -1,4 +1,4 @@
-#!/usr/bin/awk -f
+#!/usr/bin/gawk -f
# Usage: ekiga-debug-analyser <ekigaDebugOutput
# where the output comes from ekiga -d 4 (or 5).
index 595359c..b715a3c 100644
@@ -204,7 +204,8 @@ static void gm_pw_init_audio_codecs_page (GtkWidget *prefs_window,
GtkWidget *container);
static void gm_pw_init_video_codecs_page (GtkWidget *prefs_window,
GtkWidget *container);
-
+static void gm_pw_init_text_parameter_page (GtkWidget *prefs_window,
+ GtkWidget *container);
/* GTK Callbacks */
@@ -945,6 +946,29 @@ gm_pw_init_video_devices_page (GtkWidget *prefs_window,
}
+static void
+gm_pw_init_text_parameter_page (GtkWidget *prefs_window,
+ GtkWidget *container)
+{
+ GtkWidget *subsection = NULL;
+ GmPreferencesWindow *pw = NULL;
+
+ pw = gm_pw_get_pw (prefs_window);
+
+ /* Here we add text parameter options */
+ subsection =
+ gnome_prefs_subsection_new (prefs_window, container,
+ _("Real time"), 3, 1);
+
+ /* Translators: the full sentence is Automatically adjust jitter buffer
+ between X and Y ms */
+ gnome_prefs_toggle_new (subsection, _("Enable Realtime"), TEXT_KEY "enable_realtime", _("If enabled, use realtime preview with the chat."), 1);
+
+ gnome_prefs_spin_new (subsection, _("Buffer time (ms):"), TEXT_KEY "buffer_time", _("The buffer size for text reception (in ms)."), 0.0, 2000.0, 1.0, 2, NULL, true);
+
+ // gnome_prefs_spin_new (subsection, _("Max incoming CPS :"), TEXT_KEY "character_per_second", _("The maximum incoming speed for text reception."), 0.0, 2000.0, 1.0, 3, NULL, true);
+
+}
static void
gm_pw_init_audio_codecs_page (GtkWidget *prefs_window,
@@ -1397,6 +1421,11 @@ gm_prefs_window_new (Ekiga::ServiceCore *core)
gm_pw_init_video_codecs_page (window, container);
gtk_widget_show_all (GTK_WIDGET (container));
+ gnome_prefs_window_section_new (window, _("Text"));
+ container = gnome_prefs_window_subsection_new (window, _("Text settings"));
+ gm_pw_init_text_parameter_page (window, container);
+ gtk_widget_show_all (GTK_WIDGET (container));
+
/* That's an usual GtkWindow, connect it to the signals */
g_signal_connect_swapped (GTK_OBJECT (window),