<div dir="ltr"><div><div>Hello,<br><br></div>Just my 2 cents: I've test the patch and it works fine for me with pidgin-sipe. Thanks for you time and work !<br><br></div><div>The next step would be to have a more general dialpad that allows also to...dial phone mumber ?<br>
</div><div><br></div><div>Regards<br><br></div><div>  Patrice<br></div><br><div><div><br><div><div class="gmail_extra"><br><br><div class="gmail_quote">2013/10/14 David Woodhouse <span dir="ltr"><<a href="mailto:dwmw2@infradead.org" target="_blank">dwmw2@infradead.org</a>></span><br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">There are two open requests about DTMF support.<br>
<br>
 - <a href="https://developer.pidgin.im/ticket/12617" target="_blank">https://developer.pidgin.im/ticket/12617</a><br>
   (Patch to add out-of-band DTMF support)<br>
<br>
This adds a generic way for protocols to send DTMF out-of-band, and<br>
falls back to sending in-band in the media stream. And a second patch<br>
adds the required protocol-specific support for Jabber. The patches<br>
didn't even seem to build out-of-the-box, due to typos and mismatched<br>
function declarations, and the ticket has been open and mostly unloved<br>
for three years.<br>
<br>
 - <a href="https://developer.pidgin.im/ticket/15575" target="_blank">https://developer.pidgin.im/ticket/15575</a><br>
   (dialpad support)<br>
<br>
This is more recent, and actually adds a UI for users to dial DTMF tones<br>
whilst in an audio call. The patch here operates directly on a gstreamer<br>
pipeline to send dtmf-events, and looking at the code I'm not entirely<br>
sure the pipeline it selects will have *anything* to do with the media<br>
stream it was actually *asked* to send DTMF on.<br>
<br>
So I've generated a patch which combines the two — fixing up the generic<br>
part of the media_dtmf patch in ticket 12617, and combining it with the<br>
UI support added in ticket 15575. I am inclined to suggest we should<br>
leave ticket 12617 open for the Jabber support which I haven't updated<br>
and can't easily test, and handle the UI along with the generic part<br>
(i.e. my patch) in the new ticket 15575.<br>
<br>
I have some outstanding issues with my patch which I would appreciate<br>
some more clueful input on...<br>
<br>
Firstly, to make the generic DTMF support build cleanly I had to go<br>
through all the protocol plugins and add an explicit extra NULL to each<br>
PurplePluginProtocolInfo structure. Do we *really* still have to do it<br>
this way and use structure declarations from last century, or should I<br>
submit a separate patch which updates the code to use C99 structure<br>
initialisation? It's been 14 years now...<br>
<br>
Secondly, and more importantly, see the FIXME and the leak of the<br>
session-id string in the gtkmedia.c patch. I didn't bother to fix that<br>
because I'm assuming the session-id is going to be stored *somewhere* we<br>
can access it anyway, but I wasn't sure. Or perhaps we can even continue<br>
to use the one we were given, and its lifetime will exceed that of the<br>
UI? Suggestions welcome...<br>
<br>
Third: why wasn't pidgin_media_ready_cb() passing the sid to<br>
pidgin_media_add_audio_widget()? If you look carefully at the final hunk<br>
below, you'll see I 'fix' that too...<br>
<br>
This is just the patch of the patch which affects gtkmedia.c:<br>
<br>
diff --git a/pidgin/gtkmedia.c b/pidgin/gtkmedia.c<br>
index d91a951..9d5f4d8 100644<br>
--- a/pidgin/gtkmedia.c<br>
+++ b/pidgin/gtkmedia.c<br>
@@ -759,6 +759,150 @@ pidgin_media_add_audio_widget(PidginMedia *gtkmedia,<br>
 }<br>
<br>
 static void<br>
+phone_dtmf_pressed_cb(GtkButton *button, gpointer user_data)<br>
+{<br>
+       PidginMedia *gtkmedia = user_data;<br>
+       gint num;<br>
+       gchar *sid;<br>
+<br>
+       num = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(button), "dtmf-digit"));<br>
+       sid = g_object_get_data(G_OBJECT(button), "session-id");<br>
+<br>
+       purple_media_send_dtmf(gtkmedia->priv->media, sid, num, 25, 50);<br>
+}<br>
+<br>
+static inline GtkWidget *<br>
+phone_create_button(const gchar *text_hi, const gchar *text_lo)<br>
+{<br>
+       GtkWidget *button;<br>
+       GtkWidget *label_hi;<br>
+       GtkWidget *label_lo;<br>
+       GtkWidget *grid;<br>
+<br>
+       grid = gtk_vbox_new(TRUE, 0);<br>
+<br>
+       button = gtk_button_new();<br>
+       label_hi = gtk_label_new(text_hi);<br>
+       gtk_misc_set_alignment(GTK_MISC(label_hi), 0.5, 0.5);<br>
+       gtk_box_pack_end(GTK_BOX(grid), label_hi, FALSE, TRUE, 0);<br>
+       label_lo = gtk_label_new(text_lo);<br>
+       gtk_misc_set_alignment(GTK_MISC(label_lo), 0.5, 0.5);<br>
+       gtk_label_set_use_markup(GTK_LABEL(label_lo), TRUE);<br>
+       gtk_box_pack_end(GTK_BOX(grid), label_lo, FALSE, TRUE, 0);<br>
+       gtk_container_add(GTK_CONTAINER(button), grid);<br>
+<br>
+       return button;<br>
+}<br>
+<br>
+static GtkWidget *<br>
+pidgin_media_add_dtmf_widget(PidginMedia *gtkmedia,<br>
+               PurpleMediaSessionType type, const gchar *_sid)<br>
+{<br>
+       GtkWidget *grid = gtk_table_new(4, 3, TRUE);<br>
+       GtkWidget *button1;<br>
+       GtkWidget *button2;<br>
+       GtkWidget *button3;<br>
+       GtkWidget *button4;<br>
+       GtkWidget *button5;<br>
+       GtkWidget *button6;<br>
+       GtkWidget *button7;<br>
+       GtkWidget *button8;<br>
+       GtkWidget *button9;<br>
+       GtkWidget *button_asterisk;<br>
+       GtkWidget *button0;<br>
+       GtkWidget *button_pound;<br>
+       gchar *sid = g_strdup(_sid); /* FIXME: This leaks. */<br>
+<br>
+       /* Button 1 */<br>
+       button1 = phone_create_button("o_o", "<b>1</b>");<br>
+       g_signal_connect(button1, "pressed", G_CALLBACK(phone_dtmf_pressed_cb), gtkmedia);<br>
+       g_object_set_data(G_OBJECT(button1), "dtmf-digit", GINT_TO_POINTER('1'));<br>
+       g_object_set_data(G_OBJECT(button1), "session-id", sid);<br>
+       gtk_table_attach(GTK_TABLE(grid), button1, 0, 1, 0, 1, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND, 2, 2);<br>
+<br>
+       /* Button 2 */<br>
+       button2 = phone_create_button("ABC", "<b>2</b>");<br>
+       g_signal_connect(button2, "pressed", G_CALLBACK(phone_dtmf_pressed_cb), gtkmedia);<br>
+       g_object_set_data(G_OBJECT(button2), "dtmf-digit", GINT_TO_POINTER('2'));<br>
+       g_object_set_data(G_OBJECT(button2), "session-id", sid);<br>
+       gtk_table_attach(GTK_TABLE(grid), button2, 1, 2, 0, 1, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND, 2, 2);<br>
+<br>
+       /* Button 3 */<br>
+       button3 = phone_create_button("DEF", "<b>3</b>");<br>
+       g_signal_connect(button3, "pressed", G_CALLBACK(phone_dtmf_pressed_cb), gtkmedia);<br>
+       g_object_set_data(G_OBJECT(button3), "dtmf-digit", GINT_TO_POINTER('3'));<br>
+       g_object_set_data(G_OBJECT(button3), "session-id", sid);<br>
+       gtk_table_attach(GTK_TABLE(grid), button3, 2, 3, 0, 1, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND, 2, 2);<br>
+<br>
+       /* Button 4 */<br>
+       button4 = phone_create_button("GHI", "<b>4</b>");<br>
+       g_signal_connect(button4, "pressed", G_CALLBACK(phone_dtmf_pressed_cb), gtkmedia);<br>
+       g_object_set_data(G_OBJECT(button4), "dtmf-digit", GINT_TO_POINTER('4'));<br>
+       g_object_set_data(G_OBJECT(button4), "session-id", sid);<br>
+       gtk_table_attach(GTK_TABLE(grid), button4, 0, 1, 1, 2, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND, 2, 2);<br>
+<br>
+       /* Button 5 */<br>
+       button5 = phone_create_button("JKL", "<b>5</b>");<br>
+       g_signal_connect(button5, "pressed", G_CALLBACK(phone_dtmf_pressed_cb), gtkmedia);<br>
+       g_object_set_data(G_OBJECT(button5), "dtmf-digit", GINT_TO_POINTER('5'));<br>
+       g_object_set_data(G_OBJECT(button5), "session-id", sid);<br>
+       gtk_table_attach(GTK_TABLE(grid), button5, 1, 2, 1, 2, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND, 2, 2);<br>
+<br>
+       /* Button 6 */<br>
+       button6 = phone_create_button("MNO", "<b>6</b>");<br>
+       g_signal_connect(button6, "pressed", G_CALLBACK(phone_dtmf_pressed_cb), gtkmedia);<br>
+       g_object_set_data(G_OBJECT(button6), "dtmf-digit", GINT_TO_POINTER('6'));<br>
+       g_object_set_data(G_OBJECT(button6), "session-id", sid);<br>
+       gtk_table_attach(GTK_TABLE(grid), button6, 2, 3, 1, 2, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND, 2, 2);<br>
+<br>
+       /* Button 7 */<br>
+       button7 = phone_create_button("PQRS", "<b>7</b>");<br>
+       g_signal_connect(button7, "pressed", G_CALLBACK(phone_dtmf_pressed_cb), gtkmedia);<br>
+       g_object_set_data(G_OBJECT(button7), "dtmf-digit", GINT_TO_POINTER('7'));<br>
+       g_object_set_data(G_OBJECT(button7), "session-id", sid);<br>
+       gtk_table_attach(GTK_TABLE(grid), button7, 0, 1, 2, 3, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND, 2, 2);<br>
+<br>
+       /* Button 8 */<br>
+       button8 = phone_create_button("TUV", "<b>8</b>");<br>
+       g_signal_connect(button8, "pressed", G_CALLBACK(phone_dtmf_pressed_cb), gtkmedia);<br>
+       g_object_set_data(G_OBJECT(button8), "dtmf-digit", GINT_TO_POINTER('8'));<br>
+       g_object_set_data(G_OBJECT(button8), "session-id", sid);<br>
+       gtk_table_attach(GTK_TABLE(grid), button8, 1, 2, 2, 3, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND, 2, 2);<br>
+<br>
+       /* Button 9 */<br>
+       button9 = phone_create_button("WXYZ", "<b>9</b>");<br>
+       g_signal_connect(button9, "pressed", G_CALLBACK(phone_dtmf_pressed_cb), gtkmedia);<br>
+       g_object_set_data(G_OBJECT(button9), "dtmf-digit", GINT_TO_POINTER('9'));<br>
+       g_object_set_data(G_OBJECT(button9), "session-id", sid);<br>
+       gtk_table_attach(GTK_TABLE(grid), button9, 2, 3, 2, 3, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND, 2, 2);<br>
+<br>
+       /* Button Asterisk */<br>
+       button_asterisk = phone_create_button(_("DEL"), "<b>*</b>");<br>
+       g_signal_connect(button_asterisk, "pressed", G_CALLBACK(phone_dtmf_pressed_cb), gtkmedia);<br>
+       g_object_set_data(G_OBJECT(button_asterisk), "dtmf-digit", GINT_TO_POINTER('*'));<br>
+       g_object_set_data(G_OBJECT(button_asterisk), "session-id", sid);<br>
+       gtk_table_attach(GTK_TABLE(grid), button_asterisk, 0, 1, 3, 4, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND, 2, 2);<br>
+<br>
+       /* Button 0 */<br>
+       button0 = phone_create_button("", "<b>0</b>");<br>
+       g_signal_connect(button0, "pressed", G_CALLBACK(phone_dtmf_pressed_cb), gtkmedia);<br>
+       g_object_set_data(G_OBJECT(button0), "dtmf-digit", GINT_TO_POINTER('0'));<br>
+       g_object_set_data(G_OBJECT(button0), "session-id", sid);<br>
+       gtk_table_attach(GTK_TABLE(grid), button0, 1, 2, 3, 4, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND, 2, 2);<br>
+<br>
+       /* Button Pound */<br>
+       button_pound = phone_create_button(_("RETURN"), "<b>#</b>");<br>
+       g_signal_connect(button_pound, "pressed", G_CALLBACK(phone_dtmf_pressed_cb), gtkmedia);<br>
+       g_object_set_data(G_OBJECT(button_pound), "dtmf-digit", GINT_TO_POINTER('#'));<br>
+       g_object_set_data(G_OBJECT(button_pound), "session-id", sid);<br>
+       gtk_table_attach(GTK_TABLE(grid), button_pound, 2, 3, 3, 4, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND, 2, 2);<br>
+<br>
+       gtk_widget_show_all(grid);<br>
+<br>
+       return grid;<br>
+}<br>
+<br>
+static void<br>
 pidgin_media_ready_cb(PurpleMedia *media, PidginMedia *gtkmedia, const gchar *sid)<br>
 {<br>
        GtkWidget *send_widget = NULL, *recv_widget = NULL, *button_widget = NULL;<br>
@@ -888,7 +1032,11 @@ pidgin_media_ready_cb(PurpleMedia *media, PidginMedia *gtkmedia, const gchar *si<br>
<br>
                gtk_box_pack_end(GTK_BOX(recv_widget),<br>
                                pidgin_media_add_audio_widget(gtkmedia,<br>
-                               PURPLE_MEDIA_SEND_AUDIO, NULL), FALSE, FALSE, 0);<br>
+                               PURPLE_MEDIA_SEND_AUDIO, sid), FALSE, FALSE, 0);<br>
+<br>
+               gtk_box_pack_end(GTK_BOX(recv_widget),<br>
+                               pidgin_media_add_dtmf_widget(gtkmedia,<br>
+                               PURPLE_MEDIA_SEND_AUDIO, sid), FALSE, FALSE, 0);<br>
        }<br>
<br>
        if (type & PURPLE_MEDIA_AUDIO &&<br>
<span class=""><font color="#888888"><br>
<br>
<br>
--<br>
David Woodhouse                            Open Source Technology Centre<br>
<a href="mailto:David.Woodhouse@intel.com">David.Woodhouse@intel.com</a>                              Intel Corporation<br>
</font></span><br>_______________________________________________<br>
Devel mailing list<br>
<a href="mailto:Devel@pidgin.im">Devel@pidgin.im</a><br>
<a href="http://pidgin.im/cgi-bin/mailman/listinfo/devel" target="_blank">http://pidgin.im/cgi-bin/mailman/listinfo/devel</a><br></blockquote></div><br></div></div></div></div></div>