~ubuntu-branches/ubuntu/trusty/isdnutils/trusty

« back to all changes in this revision

Viewing changes to ant-phone/src/controlpad.c

  • Committer: Package Import Robot
  • Author(s): Steve Langasek
  • Date: 2013-11-15 00:02:58 UTC
  • mfrom: (1.1.8) (31.1.1 trusty-proposed)
  • Revision ID: package-import@ubuntu.com-20131115000258-tt9v3gasgrdml07k
Tags: 1:3.25+dfsg1-3.3ubuntu1
* Merge from Debian unstable:
  - resolves licensing issues with package contents.  LP: #511988.
  - includes proper upstream fix for ipppd on ARM.  LP: #453159.
  - resolves isdnutils-base removal failures.  LP: #813771.
  - fixes capiutils init script to not try to mount obsolete capifs.
    LP: #1064347.
* Remaining changes:
  - Switch libreadline5-dev to libreadline-gplv2-dev since this package
    appears to be GPLv2
  - debian/patches/no-imake.patch: Don't build xisdnload/xmonisdn using
    xmkmf/imake.  This patch was dropped in Debian without explanation;
    it still applies and seems to still be a good idea for eventual
    upstreaming, since imake is quite obsolete.
  - capi.conf: Fix typo for fcdsl2 firmware. LP: #189132.
  - Remove dependencies on /etc/inittab.
    - Disable the installation code to modify /etc/inittab.
    - isdnutils-base: Add ttyI0 example script, which needs to be installed
      in /etc/event.d/ttyI0.
    - isdnvboxserver: Add ttyI1 example script, which needs to be installed
      in /etc/event.d/ttyI1.
    - The two upstart scripts need to be edited.
    - Further improvements and documentation welcome.
* Changes included in Debian:
  - replace calls to ./MAKEDEV with /sbin/MAKEDEV
  - Build-depend on ppp-dev.
  - Switch to newer tcl -dev.
  - update to newer automake
  - debian/rules: use autoreconf to update the autotools in the capi20
    directory
  - debian/{compat,rules,*.files,.dirs}: Convert to Multi-arch.
  - debian/libcapi20-dev.install: Remove .la files (no builds use them).
* Changes included upstream:
  - fix for ARM FTBFS.
  - fix bashisms in vboxplay.
  - debian/patches/{config_libdir,toplevel-make}.patch: add CONFIG_LIBDIR
    override to upstream build system to support Multi-arch.
* Dropped changes:
  - kick dpatch to the curb.
* Handle migrating the blacklist file from
  /etc/modprobe.d/blacklist-capiutils.conf to the path used in Debian,
  /etc/modprobe.d/capiutils.conf.
* Handle rename of /etc/ppp/ip-down.d/99-ipppd and /etc/ppp/ip-up.d/00-ipppd
  to /etc/ppp/ip-down.d/ipppd and /etc/ppp/ip-up.d/ipppd
* Handle rename of /etc/init.d/isdnutils to /etc/init.d/isdnutils-base
* Restore standard.tcl to /usr/share/isdnvboxserver/default; maintainer
  scripts must not depend on contents of /usr/share/doc.
* Apply patches that were preserved in the 3.0 (quilt) migration, but
  were inadvertently not applied:
  - debian/patches/capifax.additional_error_codes.patch
  - debian/patches/capifax.3_1kHz_audio.patch
* Drop debian/isdnutils-base.cron.d, which isn't a cronjob example at all
  but an inittab example gone astray.
* debian/dotconfig*: don't use embedded quotes for paths; this confuses
  vbox's Makefiles something fierce, and causes files to be missed from
  debian/tmp'/usr/share/man/' at install time.
* Fix isdnlog and ipppd to not ship files used in the postinst under
  /usr/share/doc.
* Modernize the upstart examples.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * The key pad
3
 
 *
4
 
 * This file is part of ANT (Ant is Not a Telephone)
5
 
 *
6
 
 * Copyright 2002, 2003 Roland Stigge
7
 
 *
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.
12
 
 *
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.
17
 
 *
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
21
 
 *
22
 
 */
23
 
 
24
 
/* regular GNU system includes */
25
 
#include <stdio.h>
26
 
#include <stdlib.h>
27
 
#include <string.h>
28
 
 
29
 
/* GTK */
30
 
#include <gtk/gtk.h>
31
 
 
32
 
/* own header files */
33
 
#include "globals.h"
34
 
#include "session.h"
35
 
#include "isdn.h"
36
 
#include "util.h"
37
 
#include "callerid.h"
38
 
 
39
 
/* graphical symbols */
40
 
#include "backspace.xpm"
41
 
#include "redial.xpm"
42
 
#include "mute.xpm"
43
 
 
44
 
 
45
 
/*
46
 
 * called on preset edit confirmation (OK button)
47
 
 * -> sets new preset values (name, number) and destroys window
48
 
 *
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
55
 
 *        data = the session
56
 
 */
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),
60
 
                                                      "entry_name");
61
 
  GtkWidget *entry_number = gtk_object_get_data(GTK_OBJECT(widget),
62
 
                                                        "entry_number");
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"));
65
 
 
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)));
73
 
 
74
 
  gtk_widget_destroy(gtk_object_get_data(GTK_OBJECT(widget), "window"));
75
 
}
76
 
 
77
 
/*
78
 
 * called on right-click on preset button to configure
79
 
 *
80
 
 * input: widget = the preset button
81
 
 *        event = the event (we determine the clicked mouse button from it)
82
 
 *        data = the session
83
 
 */
84
 
static gint controlpad_preset_edit_cb(GtkWidget *widget, GdkEventButton *event,
85
 
                                      gpointer data) {
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);
90
 
    GtkWidget *window;
91
 
    GtkWidget *button_box;
92
 
    GtkWidget *button;
93
 
    GtkWidget *label;
94
 
    GtkWidget *table;
95
 
    GtkWidget *entry_name;
96
 
    GtkWidget *entry_number;
97
 
    char *title;
98
 
    char *labeltext;
99
 
  
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);
104
 
 
105
 
    /* vbox area */
106
 
    gtk_container_set_border_width(GTK_CONTAINER(GTK_DIALOG(window)->vbox), 0);
107
 
    asprintf(&labeltext,
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,
111
 
                     TRUE, FALSE, 0);
112
 
    gtk_misc_set_padding(GTK_MISC(label), 10, 10);
113
 
    gtk_widget_show(label);
114
 
 
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,
118
 
                       TRUE, FALSE, 0);
119
 
    gtk_widget_show(table);
120
 
 
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);
127
 
   
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);
136
 
 
137
 
    /* action area */
138
 
    button_box = gtk_hbutton_box_new();
139
 
    gtk_container_add(GTK_CONTAINER(GTK_DIALOG(window)->action_area),
140
 
                      button_box);
141
 
    gtk_widget_show(button_box);
142
 
 
143
 
    /* OK button */
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),
153
 
                       session);
154
 
    gtk_widget_show(button);
155
 
 
156
 
    /* cancel 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),
161
 
                              GTK_OBJECT(window));
162
 
    gtk_widget_show(button);
163
 
    gtk_widget_show(window);
164
 
 
165
 
    free(labeltext);
166
 
    free(title);
167
 
    return TRUE; /* event handled */
168
 
  } else {
169
 
    return FALSE;
170
 
  }
171
 
}
172
 
 
173
 
/*
174
 
 * called when button in key pad clicked (except mute)
175
 
 */
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");
179
 
  char *temp;
180
 
 
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)
185
 
                                      ->entry), c);
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)
195
 
                                     ->entry), temp);
196
 
      }
197
 
      free(temp);
198
 
    } else if (*c == 'C') { /* clear entry */
199
 
      gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(session->dial_number_box)
200
 
                                   ->entry), "");
201
 
    } else if (*c == 'R') { /* Redial from history */
202
 
      do {
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)
206
 
                                     ->entry), temp);
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);
214
 
    }
215
 
    gtk_widget_grab_focus(GTK_WIDGET(GTK_COMBO(session->dial_number_box)
216
 
                                     ->entry));
217
 
    gtk_entry_set_position(GTK_ENTRY(GTK_COMBO(session->dial_number_box)
218
 
                                          ->entry), -1);
219
 
    break;
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';
228
 
    }
229
 
    break;
230
 
  default: /* other states */
231
 
    ;
232
 
  }
233
 
}
234
 
 
235
 
/*
236
 
 * called when mute button in key pad toggled
237
 
 */
238
 
static void controlpad_mute_cb(GtkWidget *button, gpointer data) {
239
 
  session_t *session = (session_t *) data;
240
 
 
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);
247
 
  }
248
 
}
249
 
 
250
 
/*
251
 
 * called when record / local / remote checkbutton has been toggled
252
 
 */
253
 
static void controlpad_record_cb(GtkWidget *button, gpointer data) {
254
 
  session_t *session = (session_t *) data;
255
 
  char *digits = NULL;
256
 
 
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))
264
 
        {
265
 
          fprintf(stderr, "Error opening audio file.\n");
266
 
          gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(
267
 
                                       session->record_checkbutton), FALSE);
268
 
          return;
269
 
        }
270
 
        free(digits);
271
 
        cid_row_mark_record(session, session->cid_num - 1);
272
 
      }
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;
283
 
      }
284
 
    }
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;
295
 
    }
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;
302
 
    }
303
 
  }
304
 
}
305
 
 
306
 
/*
307
 
 * The key pad etc.
308
 
 */
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]}};
314
 
  char *tips[4][5] = {
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"};
320
 
  
321
 
  GtkWidget *frame;
322
 
  GtkWidget *hbox;
323
 
  GtkWidget *table;
324
 
  GtkWidget *button;
325
 
 
326
 
  GtkWidget *recordframe;
327
 
  GtkWidget *recordbox;
328
 
  GtkWidget *record_checkbutton;
329
 
  GtkWidget *record_checkbutton_local;
330
 
  GtkWidget *record_checkbutton_remote;
331
 
 
332
 
  GdkPixmap *pixmap;
333
 
  GdkBitmap *mask;
334
 
  GtkStyle *style;
335
 
  GtkWidget *pixmapwid;
336
 
 
337
 
  GtkTooltips *tooltips;
338
 
 
339
 
  int i, j;
340
 
 
341
 
  tooltips = gtk_tooltips_new();
342
 
  /* tooltips are often grey by default and have to be set up with a gtkrc
343
 
     file:
344
 
 
345
 
     style "gtk-tooltips-style" {
346
 
             bg[NORMAL] = "#ffffc0"
347
 
     }
348
 
     widget "gtk-tooltips" style "gtk-tooltips-style"
349
 
   */
350
 
 
351
 
  frame = gtk_frame_new(_("Control"));
352
 
  gtk_container_set_border_width(GTK_CONTAINER(frame), 8);
353
 
 
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);
358
 
 
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);
363
 
 
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,
370
 
                                              &mask,
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,
386
 
                                                &mask,
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,
396
 
                                                &mask,
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),
406
 
                             session);
407
 
        }
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);
413
 
      }
414
 
      if (*tips[j][i])
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);
419
 
    }
420
 
    gtk_table_set_col_spacing(GTK_TABLE(table), i, i < 2 ? 5 : 15);
421
 
  }
422
 
 
423
 
  recordframe = gtk_frame_new(_("Recording"));
424
 
  gtk_box_pack_start(GTK_BOX(hbox), recordframe, TRUE, FALSE, 5);
425
 
  gtk_widget_show(recordframe);
426
 
 
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);
432
 
 
433
 
  record_checkbutton =
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;
443
 
 
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;
454
 
 
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;
465
 
 
466
 
  if (!session->option_record) {
467
 
    gtk_widget_set_sensitive(record_checkbutton_local, FALSE);
468
 
    gtk_widget_set_sensitive(record_checkbutton_remote, FALSE);
469
 
  }
470
 
 
471
 
  return frame;
472
 
}
473
 
 
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;
478
 
 
479
 
  if (GTK_CHECK_MENU_ITEM (session->controlpad_check_menu_item)->active) {
480
 
    gtk_widget_show(session->controlpad);
481
 
    session->option_show_controlpad = 1;
482
 
  } else {
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);
488
 
  }
489
 
}
490