4
* This file is part of ANT (Ant is Not a Telephone)
6
* Copyright 2002, 2003 Roland Stigge
8
* ANT is free software; you can redistribute it and/or modify
9
* it under the terms of the GNU General Public License as published by
10
* the Free Software Foundation; either version 2 of the License, or
11
* (at your option) any later version.
13
* ANT is distributed in the hope that it will be useful,
14
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
* GNU General Public License for more details.
18
* You should have received a copy of the GNU General Public License
19
* along with ANT; if not, write to the Free Software
20
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24
/* regular GNU system includes */
32
/* own header files */
39
/* graphical symbols */
40
#include "backspace.xpm"
46
* called on preset edit confirmation (OK button)
47
* -> sets new preset values (name, number) and destroys window
49
* input: widget = the OK button, set data:
50
* "entry_name" - the entry with the new preset name
51
* "entry_number" - the entry with the new preset number
52
* "button" - the preset button
53
* "number" - the preset button number
54
* "window" - the window to destroy after setting values
57
static void controlpad_preset_edit_ok(GtkWidget *widget, gpointer *data) {
58
session_t *session = (session_t *) data;
59
GtkWidget *entry_name = gtk_object_get_data(GTK_OBJECT(widget),
61
GtkWidget *entry_number = gtk_object_get_data(GTK_OBJECT(widget),
63
GtkWidget *button = gtk_object_get_data(GTK_OBJECT(widget), "button");
64
int n = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(widget), "number"));
66
free(session->preset_names[n]);
67
session->preset_names[n] = strdup(gtk_entry_get_text(GTK_ENTRY(entry_name)));
68
free(session->preset_numbers[n]);
69
session->preset_numbers[n] = strdup(
70
gtk_entry_get_text(GTK_ENTRY(entry_number)));
71
gtk_label_set_text(GTK_LABEL(GTK_BIN(button)->child),
72
gtk_entry_get_text(GTK_ENTRY(entry_name)));
74
gtk_widget_destroy(gtk_object_get_data(GTK_OBJECT(widget), "window"));
78
* called on right-click on preset button to configure
80
* input: widget = the preset button
81
* event = the event (we determine the clicked mouse button from it)
84
static gint controlpad_preset_edit_cb(GtkWidget *widget, GdkEventButton *event,
86
if (event->button == 3) {
87
session_t *session = (session_t *) data;
88
char *buttoncode = (char *)gtk_object_get_data(GTK_OBJECT(widget), "desc");
89
int n = strtol(&buttoncode[1], NULL, 0);
91
GtkWidget *button_box;
95
GtkWidget *entry_name;
96
GtkWidget *entry_number;
100
window = gtk_dialog_new();
101
asprintf(&title, _("Preset %c"), buttoncode[1] + 1);
102
gtk_window_set_title(GTK_WINDOW(window), title);
103
gtk_window_set_modal(GTK_WINDOW(window), TRUE);
106
gtk_container_set_border_width(GTK_CONTAINER(GTK_DIALOG(window)->vbox), 0);
108
_("Please input new preset data for button %c:"), buttoncode[1] + 1);
109
label = gtk_label_new(labeltext);
110
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(window)->vbox), label,
112
gtk_misc_set_padding(GTK_MISC(label), 10, 10);
113
gtk_widget_show(label);
115
table = gtk_table_new(2, 2, FALSE);
116
gtk_container_set_border_width(GTK_CONTAINER(table), 10);
117
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(window)->vbox), table,
119
gtk_widget_show(table);
121
label = gtk_label_new(_("Name:"));
122
gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 0, 1);
123
gtk_widget_show(label);
124
label = gtk_label_new(_("Number:"));
125
gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 1, 2);
126
gtk_widget_show(label);
128
entry_name = gtk_entry_new();
129
gtk_entry_set_text(GTK_ENTRY(entry_name), session->preset_names[n]);
130
gtk_table_attach_defaults(GTK_TABLE(table), entry_name, 1, 2, 0, 1);
131
gtk_widget_show(entry_name);
132
entry_number = gtk_entry_new();
133
gtk_entry_set_text(GTK_ENTRY(entry_number), session->preset_numbers[n]);
134
gtk_table_attach_defaults(GTK_TABLE(table), entry_number, 1, 2, 1, 2);
135
gtk_widget_show(entry_number);
138
button_box = gtk_hbutton_box_new();
139
gtk_container_add(GTK_CONTAINER(GTK_DIALOG(window)->action_area),
141
gtk_widget_show(button_box);
144
button = gtk_button_new_with_label(_("OK"));
145
gtk_box_pack_start_defaults(GTK_BOX(button_box), button);
146
gtk_object_set_data(GTK_OBJECT(button), "entry_name", entry_name);
147
gtk_object_set_data(GTK_OBJECT(button), "entry_number", entry_number);
148
gtk_object_set_data(GTK_OBJECT(button), "button", widget);
149
gtk_object_set_data(GTK_OBJECT(button), "number", GINT_TO_POINTER(n));
150
gtk_object_set_data(GTK_OBJECT(button), "window", window);
151
gtk_signal_connect(GTK_OBJECT(button), "clicked",
152
GTK_SIGNAL_FUNC(controlpad_preset_edit_ok),
154
gtk_widget_show(button);
157
button = gtk_button_new_with_label(_("Cancel"));
158
gtk_box_pack_start_defaults(GTK_BOX(button_box), button);
159
gtk_signal_connect_object(GTK_OBJECT(button), "clicked",
160
GTK_SIGNAL_FUNC(gtk_widget_destroy),
162
gtk_widget_show(button);
163
gtk_widget_show(window);
167
return TRUE; /* event handled */
174
* called when button in key pad clicked (except mute)
176
static void controlpad_button_cb(GtkWidget *button, gpointer data) {
177
session_t *session = (session_t *) data;
178
char *c = (char *) gtk_object_get_data(GTK_OBJECT(button), "desc");
181
switch (session->state) {
182
case STATE_READY: /* manipulate dial box */
183
if ((*c >= '0' && *c <= '9') || *c == '*' || *c == '#') { /* new char */
184
gtk_entry_append_text(GTK_ENTRY(GTK_COMBO(session->dial_number_box)
186
} else if (*c == 'P') { /* preset button */
187
gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(session->dial_number_box)->entry),
188
session->preset_numbers[strtol(&c[1], NULL, 0)]);
189
} else if (*c == 'B') { /* clear one byte (Backspace) */
190
temp = strdup(gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(
191
session->dial_number_box)->entry)));
192
if (strlen(temp) > 0) {
193
temp[strlen(temp) - 1] = 0;
194
gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(session->dial_number_box)
198
} else if (*c == 'C') { /* clear entry */
199
gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(session->dial_number_box)
201
} else if (*c == 'R') { /* Redial from history */
203
temp = g_list_nth_data(session->dial_number_history,
204
session->dial_number_history_pointer);
205
gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(session->dial_number_box)
207
if (session->dial_number_history_pointer <
208
session->dial_number_history_maxlen)
209
session->dial_number_history_pointer++;
210
if (session->dial_number_history_pointer ==
211
session->dial_number_history_maxlen)
212
session->dial_number_history_pointer = 0;
213
} while (*temp == '\0' && session->dial_number_history_pointer != 0);
215
gtk_widget_grab_focus(GTK_WIDGET(GTK_COMBO(session->dial_number_box)
217
gtk_entry_set_position(GTK_ENTRY(GTK_COMBO(session->dial_number_box)
220
case STATE_CONVERSATION: /* touchtones */
221
if ((*c >= '0' && *c <= '9') || *c == '*' || *c == '#') { /* new tt */
222
#define TOUCHTONE_LENGTH 0.1
223
session->touchtone_countdown_isdn = TOUCHTONE_LENGTH * ISDN_SPEED;
224
session->touchtone_countdown_audio =
225
TOUCHTONE_LENGTH * session->audio_speed_out;
226
session->touchtone_index =
227
*c == '*' ? 9 : *c == '0' ? 10 : *c == '#' ? 11 : *c - '1';
230
default: /* other states */
236
* called when mute button in key pad toggled
238
static void controlpad_mute_cb(GtkWidget *button, gpointer data) {
239
session_t *session = (session_t *) data;
241
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button))) { /* muted */
242
session->option_muted = 1;
243
gtk_widget_show(session->muted_warning);
244
} else { /* unmuted */
245
session->option_muted = 0;
246
gtk_widget_hide(session->muted_warning);
251
* called when record / local / remote checkbutton has been toggled
253
static void controlpad_record_cb(GtkWidget *button, gpointer data) {
254
session_t *session = (session_t *) data;
257
if (button == session->record_checkbutton) {
258
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button))) { /* record! */
259
session->option_record = 1;
260
if (session->state == STATE_CONVERSATION) {
261
if (recording_open(session->recorder,
262
digits = util_digitstime(&session->vcon_time),
263
session->option_recording_format))
265
fprintf(stderr, "Error opening audio file.\n");
266
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(
267
session->record_checkbutton), FALSE);
271
cid_row_mark_record(session, session->cid_num - 1);
273
} else { /* don't record! */
274
session->option_record = 0;
275
if (session->state == STATE_CONVERSATION) {
276
recording_write(session->recorder, session->rec_buf_local,
277
session->rec_buf_local_index, RECORDING_LOCAL);
278
recording_write(session->recorder, session->rec_buf_remote,
279
session->rec_buf_remote_index, RECORDING_REMOTE);
280
recording_close(session->recorder);
281
session->rec_buf_local_index = 0;
282
session->rec_buf_remote_index = 0;
285
gtk_widget_set_sensitive(session->record_checkbutton_local,
286
session->option_record);
287
gtk_widget_set_sensitive(session->record_checkbutton_remote,
288
session->option_record);
289
} else if (button == session->record_checkbutton_local) {
290
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button))) {
291
/* record local channel (if recording is selected at all)! */
292
session->option_record_local = 1;
293
} else { /* don't record local channel! */
294
session->option_record_local = 0;
296
} else { /* button == session->record_checkbutton_remote */
297
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button))) {
298
/* record remote channel (if recording is selected at all)! */
299
session->option_record_remote = 1;
300
} else { /* don't record remote channel! */
301
session->option_record_remote = 0;
309
GtkWidget *controlpad_new(session_t *session) {
310
char *labels[4][5] = {{"1", "2", "3", "B", session->preset_names[0]},
311
{"4", "5", "6", "C", session->preset_names[1]},
312
{"7", "8", "9", "R", session->preset_names[2]},
313
{"*", "0", "#", "M", session->preset_names[3]}};
315
{",-./", "abc", "def", N_("Backspace"), N_("Preset 1")},
316
{"ghi", "jkl", "mno", N_("Clear Number"), N_("Preset 2")},
317
{"pqrs", "tuv", "wxyz", N_("Redial"), N_("Preset 3")},
318
{"", "0...9", "", N_("Mute Microphone"), N_("Preset 4")}};
319
char *presetcodes[4] = {"P0", "P1", "P2", "P3"};
326
GtkWidget *recordframe;
327
GtkWidget *recordbox;
328
GtkWidget *record_checkbutton;
329
GtkWidget *record_checkbutton_local;
330
GtkWidget *record_checkbutton_remote;
335
GtkWidget *pixmapwid;
337
GtkTooltips *tooltips;
341
tooltips = gtk_tooltips_new();
342
/* tooltips are often grey by default and have to be set up with a gtkrc
345
style "gtk-tooltips-style" {
346
bg[NORMAL] = "#ffffc0"
348
widget "gtk-tooltips" style "gtk-tooltips-style"
351
frame = gtk_frame_new(_("Control"));
352
gtk_container_set_border_width(GTK_CONTAINER(frame), 8);
354
hbox = gtk_hbox_new(FALSE, 15);
355
gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
356
gtk_container_add(GTK_CONTAINER(frame), hbox);
357
gtk_widget_show(hbox);
359
table = gtk_table_new(4, 3, FALSE);
360
gtk_table_set_row_spacings(GTK_TABLE(table), 5);
361
gtk_box_pack_start(GTK_BOX(hbox), table, TRUE, FALSE, 5);
362
gtk_widget_show(table);
364
for (i = 0; i < 5; i++) { /* columns */
365
for (j = 0; j < 4; j++) { /* rows */
366
if (i == 3 && j == 3) { /* mute */
367
button = gtk_toggle_button_new();
368
style = gtk_widget_get_style(session->main_window);
369
pixmap = gdk_pixmap_create_from_xpm_d(session->main_window->window,
371
&style->bg[GTK_STATE_NORMAL],
372
(gchar **) mute_xpm);
373
pixmapwid = gtk_pixmap_new(pixmap, mask);
374
gtk_container_add(GTK_CONTAINER(button), pixmapwid);
375
gtk_widget_show(pixmapwid);
376
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button),
377
session->option_muted);
378
session->mute_button = button;
379
gtk_signal_connect(GTK_OBJECT(button), "toggled",
380
GTK_SIGNAL_FUNC(controlpad_mute_cb), session);
381
} else { /* everything else (except mute) */
382
if (i == 3 && j == 0) { /* backspace icon */
383
button = gtk_button_new();
384
style = gtk_widget_get_style(session->main_window);
385
pixmap = gdk_pixmap_create_from_xpm_d(session->main_window->window,
387
&style->bg[GTK_STATE_NORMAL],
388
(gchar **) backspace_xpm);
389
pixmapwid = gtk_pixmap_new(pixmap, mask);
390
gtk_container_add(GTK_CONTAINER(button), pixmapwid);
391
gtk_widget_show(pixmapwid);
392
} else if (i == 3 && j == 2) { /* redial icon */
393
button = gtk_button_new();
394
style = gtk_widget_get_style(session->main_window);
395
pixmap = gdk_pixmap_create_from_xpm_d(session->main_window->window,
397
&style->bg[GTK_STATE_NORMAL],
398
(gchar **) redial_xpm);
399
pixmapwid = gtk_pixmap_new(pixmap, mask);
400
gtk_container_add(GTK_CONTAINER(button), pixmapwid);
401
gtk_widget_show(pixmapwid);
402
} else { /* icon with letter (or description) */
403
button = gtk_button_new_with_label(labels[j][i]);
404
gtk_signal_connect(GTK_OBJECT(button), "button-press-event",
405
GTK_SIGNAL_FUNC(controlpad_preset_edit_cb),
408
/* connect callback to widget */
409
gtk_object_set_data(GTK_OBJECT(button), "desc",
410
i < 4 ? labels[j][i] : presetcodes[j]);
411
gtk_signal_connect(GTK_OBJECT(button), "pressed",
412
GTK_SIGNAL_FUNC(controlpad_button_cb), session);
415
gtk_tooltips_set_tip(tooltips, button, _(tips[j][i]), NULL);
416
gtk_table_attach_defaults(GTK_TABLE(table), button, i, i + 1, j, j + 1);
417
gtk_widget_set_size_request(button, i < 3 ? 30 : i == 3 ? 20 : 100, -1);
418
gtk_widget_show(button);
420
gtk_table_set_col_spacing(GTK_TABLE(table), i, i < 2 ? 5 : 15);
423
recordframe = gtk_frame_new(_("Recording"));
424
gtk_box_pack_start(GTK_BOX(hbox), recordframe, TRUE, FALSE, 5);
425
gtk_widget_show(recordframe);
427
recordbox = gtk_table_new(2, 3, FALSE);
428
gtk_table_set_row_spacings(GTK_TABLE(recordbox), 0);
429
gtk_table_set_col_spacings(GTK_TABLE(recordbox), 20);
430
gtk_container_add(GTK_CONTAINER(recordframe), recordbox);
431
gtk_widget_show(recordbox);
434
gtk_check_button_new_with_label(_("Record to file"));
435
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(record_checkbutton),
436
session->option_record);
437
gtk_table_attach(GTK_TABLE(recordbox), record_checkbutton,
438
0, 2, 0, 1, GTK_FILL | GTK_EXPAND, 0, 0, 0);
439
gtk_widget_show(record_checkbutton);
440
gtk_signal_connect(GTK_OBJECT(record_checkbutton), "toggled",
441
GTK_SIGNAL_FUNC(controlpad_record_cb), session);
442
session->record_checkbutton = record_checkbutton;
444
record_checkbutton_local =
445
gtk_check_button_new_with_label(_("Record local channel"));
446
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(record_checkbutton_local),
447
session->option_record_local);
448
gtk_table_attach(GTK_TABLE(recordbox), record_checkbutton_local,
449
1, 2, 1, 2, GTK_FILL | GTK_EXPAND, 0, 0, 0);
450
gtk_widget_show(record_checkbutton_local);
451
gtk_signal_connect(GTK_OBJECT(record_checkbutton_local), "toggled",
452
GTK_SIGNAL_FUNC(controlpad_record_cb), session);
453
session->record_checkbutton_local = record_checkbutton_local;
455
record_checkbutton_remote =
456
gtk_check_button_new_with_label(_("Record remote channel"));
457
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(record_checkbutton_remote),
458
session->option_record_remote);
459
gtk_table_attach(GTK_TABLE(recordbox), record_checkbutton_remote,
460
1, 2, 2, 3, GTK_FILL | GTK_EXPAND, 0, 0, 0);
461
gtk_widget_show(record_checkbutton_remote);
462
gtk_signal_connect(GTK_OBJECT(record_checkbutton_remote), "toggled",
463
GTK_SIGNAL_FUNC(controlpad_record_cb), session);
464
session->record_checkbutton_remote = record_checkbutton_remote;
466
if (!session->option_record) {
467
gtk_widget_set_sensitive(record_checkbutton_local, FALSE);
468
gtk_widget_set_sensitive(record_checkbutton_remote, FALSE);
474
/* called when control pad state check button is toggled */
475
void controlpad_toggle_cb(GtkWidget *widget _U_,
476
gpointer data, guint action _U_) {
477
session_t *session = (session_t *) data;
479
if (GTK_CHECK_MENU_ITEM (session->controlpad_check_menu_item)->active) {
480
gtk_widget_show(session->controlpad);
481
session->option_show_controlpad = 1;
483
gtk_widget_hide(session->controlpad);
484
session->option_show_controlpad = 0;
485
/* shrink if no growing callerid monitor present */
486
if (!session->option_show_callerid)
487
gtk_window_resize(GTK_WINDOW(session->main_window), 1, 1);