actions.c 35.8 KB
Newer Older
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
1
/*
2
 *  Copyright (C) 2007 - 2008 Savoir-Faire Linux inc.
3
 *  Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com>
4
 *  Author: Pierre-Luc Beaudoin <pierre-luc.beaudoin@savoirfairelinux.com>
Emmanuel Milou's avatar
Emmanuel Milou committed
5
 *
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
6
7
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
8
 *  the Free Software Foundation; either version 3 of the License, or
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
9
 *  (at your option) any later version.
Emmanuel Milou's avatar
Emmanuel Milou committed
10
 *
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
11
12
13
14
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
Emmanuel Milou's avatar
Emmanuel Milou committed
15
 *
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
16
17
18
19
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
20

Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
21
#include <actions.h>
22
#include <dbus/dbus.h>
23
#include <statusicon.h>
Julien Bonjean's avatar
Julien Bonjean committed
24
#include <contacts/searchbar.h>
25
26
27
#include <menus.h>
#include <toolbar.h>

28
29
30
31
#include <gtk/gtk.h>
#include <string.h>
#include <glib/gprintf.h>
#include <stdlib.h>
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
32
33
34
#include <sys/types.h>
#include <unistd.h>

35
guint voice_mails;
36
GHashTable * ip2ip_profile=NULL;
37

Emmanuel Milou's avatar
Emmanuel Milou committed
38
    void
39
sflphone_notify_voice_mail ( const gchar* accountID , guint count )
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
40
{
41
42
    gchar *id;
    gchar *current;
Emmanuel Milou's avatar
Emmanuel Milou committed
43

44
45
46
47
48
49
50
51
52
53
54
    // We want to notify only for the default current account; ie the first in the list
    id = g_strdup( accountID );
    current = account_list_get_current_id();
    if( strcmp( id, current ) != 0 )
        return;

    voice_mails = count ;

    if(count > 0)
    {
        gchar * message = g_new0(gchar, 50);
55
56
57
58
59
        g_sprintf(message, n_("%d voice mail", "%d voice mails", count), count);
//         if( count > 1)
//             g_sprintf(message, _("%d voice mails"), count);
//         else
//             g_sprintf(message, _("%d voice mail"), count);
60
61
62
        statusbar_push_message(message,  __MSG_VOICE_MAILS);
        g_free(message);
    }
Emmanuel Milou's avatar
Emmanuel Milou committed
63

64
65
66
67
    // TODO: add ifdef
    if( account_list_get_size() > 0 )
    {
        account_t* acc = account_list_get_by_id( id );
Emmanuel Milou's avatar
Emmanuel Milou committed
68
69
        if( acc != NULL )
            notify_voice_mails( count , acc );
70
    }
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
71
72
}

Emmanuel Milou's avatar
Emmanuel Milou committed
73
    void
74
status_bar_display_account ()
75
{
76
    gchar* msg;
77
    account_t* acc;
78
79
80
81
82

    statusbar_pop_message(__MSG_ACCOUNT_DEFAULT);

    acc = account_list_get_current ();
    if(acc){
83
84
        msg = g_markup_printf_escaped("%s %s (%s)" ,
                _("Using account"),
85
86
                (gchar*)g_hash_table_lookup( acc->properties , ACCOUNT_ALIAS),
                (gchar*)g_hash_table_lookup( acc->properties , ACCOUNT_TYPE));
Emmanuel Milou's avatar
Emmanuel Milou committed
87
    }
88
89
    else
    {
90
        msg = g_markup_printf_escaped(_("No registered accounts"));
91
92
93
    }
    statusbar_push_message( msg , __MSG_ACCOUNT_DEFAULT);
    g_free(msg);
94
95
}

Emmanuel Milou's avatar
Emmanuel Milou committed
96
97

    gboolean
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
98
99
sflphone_quit ()
{
Emmanuel Milou's avatar
Emmanuel Milou committed
100
    gboolean quit = FALSE;
Julien Bonjean's avatar
Julien Bonjean committed
101
    guint count = calllist_get_size(current_calls);
Emmanuel Milou's avatar
Emmanuel Milou committed
102
103
104
105
106
107
108
109
110
    if(count > 0){
        quit = main_window_ask_quit();
    }
    else{
        quit = TRUE;
    }

    if (quit)
    {
111
112
113
        // Save the history 
        sflphone_save_history ();

Emmanuel Milou's avatar
Emmanuel Milou committed
114
115
116
117
118
119
120
        dbus_unregister(getpid());
        dbus_clean ();
        //call_list_clean(); TODO
        //account_list_clean()
        gtk_main_quit ();
    }
    return quit;
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
121
122
}

Emmanuel Milou's avatar
Emmanuel Milou committed
123
    void
124
sflphone_hold (callable_obj_t * c )
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
125
{
126
    c->_state = CALL_STATE_HOLD;
127
    calltree_update_call(current_calls, c, NULL);
Emmanuel Milou's avatar
Emmanuel Milou committed
128
    update_menus();
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
129
130
}

Emmanuel Milou's avatar
Emmanuel Milou committed
131
    void
132
sflphone_ringing(callable_obj_t * c )
133
{
134
    c->_state = CALL_STATE_RINGING;
135
    calltree_update_call(current_calls, c, NULL);
Emmanuel Milou's avatar
Emmanuel Milou committed
136
    update_menus();
137
}
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
138

Emmanuel Milou's avatar
Emmanuel Milou committed
139
    void
140
sflphone_hung_up( callable_obj_t * c)
Emmanuel Milou's avatar
Emmanuel Milou committed
141
{
142
    calllist_remove( current_calls, c->_callID);
143
    calltree_remove_call(current_calls, c, NULL);
144
    c->_state = CALL_STATE_DIALING;
145
    call_remove_all_errors(c);
Emmanuel Milou's avatar
Emmanuel Milou committed
146
    update_menus();
147
#if GTK_CHECK_VERSION(2,10,0)
Emmanuel Milou's avatar
Emmanuel Milou committed
148
    status_tray_icon_blink( FALSE );
149
#endif
Emmanuel Milou's avatar
Emmanuel Milou committed
150
151
}

152
153
static hashtable_free(gpointer key, gpointer value, gpointer user_data)
{
154
    g_free(key);
155
156
157
    g_free(value);
}

Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
158
/** Internal to actions: Fill account list */
Emmanuel Milou's avatar
Emmanuel Milou committed
159
    void
160
sflphone_fill_account_list(gboolean toolbarInitialized)
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
161
{
162
163
164
165
166

    gchar** array;
    gchar** accountID;
    unsigned int i;

Emmanuel Milou's avatar
Emmanuel Milou committed
167
    account_list_clear ( );
168

Emmanuel Milou's avatar
Emmanuel Milou committed
169
    array = (gchar **)dbus_account_list();
170
171
    if(array)
    {
Emmanuel Milou's avatar
Emmanuel Milou committed
172
173
174
175
        for (accountID = array; *accountID; accountID++)
        {
            account_t * a = g_new0(account_t,1);
            a->accountID = g_strdup(*accountID);
176
            a->credential_information = NULL;
Emmanuel Milou's avatar
Emmanuel Milou committed
177
178
179
            account_list_add(a);
        }
        g_strfreev (array);
180
    }
181

Emmanuel Milou's avatar
Emmanuel Milou committed
182
183
184
185
    for( i = 0; i < account_list_get_size(); i++)
    {
        account_t  * a = account_list_get_nth (i);
        GHashTable * details = (GHashTable *) dbus_account_details(a->accountID);
186
187
        if( details == NULL )
            break;
Emmanuel Milou's avatar
Emmanuel Milou committed
188
        a->properties = details;
189
                        
190
191
192
        /* As this function might be called numberous time, we should free the 
         * previously allocated space to avoid memory leaks.
         */
193
194
195
196
197
198
199

        /* Fill the actual array of credentials */

        int number_of_credential = dbus_get_number_of_credential(a->accountID);
        if(number_of_credential) {
            a->credential_information = g_ptr_array_new();
        } else {
200
201
202
            a->credential_information = NULL;
        }
        
203
        int credential_index;
204
205
        for(credential_index = 0; credential_index < number_of_credential; credential_index++) {
            GHashTable * credential_information = dbus_get_credential(a->accountID, credential_index);
206
            g_ptr_array_add(a->credential_information, credential_information);
207
        }
Emmanuel Milou's avatar
Emmanuel Milou committed
208

209
        gchar * status = g_hash_table_lookup(details, REGISTRATION_STATUS);
Emmanuel Milou's avatar
Emmanuel Milou committed
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
        if(strcmp(status, "REGISTERED") == 0)
        {
            a->state = ACCOUNT_STATE_REGISTERED;
        }
        else if(strcmp(status, "UNREGISTERED") == 0)
        {
            a->state = ACCOUNT_STATE_UNREGISTERED;
        }
        else if(strcmp(status, "TRYING") == 0)
        {
            a->state = ACCOUNT_STATE_TRYING;
        }
        else if(strcmp(status, "ERROR") == 0)
        {
            a->state = ACCOUNT_STATE_ERROR;
        }
        else if(strcmp( status , "ERROR_AUTH") == 0 )
        {
            a->state = ACCOUNT_STATE_ERROR_AUTH;
        }
        else if(strcmp( status , "ERROR_NETWORK") == 0 )
        {
            a->state = ACCOUNT_STATE_ERROR_NETWORK;
        }
        else if(strcmp( status , "ERROR_HOST") == 0 )
        {
            a->state = ACCOUNT_STATE_ERROR_HOST;
        }
        else if(strcmp( status , "ERROR_CONF_STUN") == 0 )
        {
            a->state = ACCOUNT_STATE_ERROR_CONF_STUN;
        }
        else if(strcmp( status , "ERROR_EXIST_STUN") == 0 )
        {
            a->state = ACCOUNT_STATE_ERROR_EXIST_STUN;
        }
        else
        {
            a->state = ACCOUNT_STATE_INVALID;
        }

251
252
253
254
255
256
257
        gchar * code = NULL;
        code = g_hash_table_lookup(details, REGISTRATION_STATE_CODE);
        if (code != NULL) {
            a->protocol_state_code = atoi(code);
        }
        g_free(a->protocol_state_description);
        a->protocol_state_description = g_hash_table_lookup(details, REGISTRATION_STATE_DESCRIPTION);
Emmanuel Milou's avatar
Emmanuel Milou committed
258
259
260
261
262
    }

    // Prevent update being called when toolbar is not yet initialized
    if(toolbarInitialized)
        toolbar_update_buttons();
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
263
264
}

265
gboolean sflphone_init()
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
266
{
Emmanuel Milou's avatar
Emmanuel Milou committed
267
268
269
270
271
272
273
274
    if(!dbus_connect ()){

        main_window_error_message(_("Unable to connect to the SFLphone server.\nMake sure the daemon is running."));
        return FALSE;
    }
    else
    {
        dbus_register(getpid(), "Gtk+ Client");
275

276
277
278
        current_calls = calltab_init(FALSE, CURRENT_CALLS);
        contacts = calltab_init(TRUE, CONTACTS);
        history = calltab_init(TRUE, HISTORY);
279

Emmanuel Milou's avatar
Emmanuel Milou committed
280
        account_list_init ();
281
        codec_list_init();
282
	conferencelist_init();
283

284
        // Fetch the configured accounts
Emmanuel Milou's avatar
Emmanuel Milou committed
285
        sflphone_fill_account_list(FALSE);
286

287
288
289
        // Fetch the ip2ip profile 
        sflphone_fill_ip2ip_profile();
        
290
        // Fetch the audio codecs
Emmanuel Milou's avatar
Emmanuel Milou committed
291
        sflphone_fill_codec_list();
292

293
294
295
	// Fetch the conference list
	sflphone_fill_conference_list();

Emmanuel Milou's avatar
Emmanuel Milou committed
296
297
        return TRUE;
    }
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
298
299
}

300
301
302
303
304
305
306
307
308
309
void sflphone_fill_ip2ip_profile(void)
{
    ip2ip_profile = (GHashTable *) dbus_get_ip2_ip_details();
}

GHashTable * sflphone_get_ip2ip_properties(void) 
{
    return ip2ip_profile;
}

Emmanuel Milou's avatar
Emmanuel Milou committed
310
    void
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
311
sflphone_hang_up()
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
312
{
313
    callable_obj_t * selectedCall = calltab_get_selected_call(current_calls);
Emmanuel Milou's avatar
Emmanuel Milou committed
314
315
    if(selectedCall)
    {
316
        switch(selectedCall->_state)
Emmanuel Milou's avatar
Emmanuel Milou committed
317
318
319
320
321
322
        {
            case CALL_STATE_DIALING:
                dbus_hang_up (selectedCall);
                break;
            case CALL_STATE_RINGING:
                dbus_hang_up (selectedCall);
323
                call_remove_all_errors(selectedCall);
324
325
                selectedCall->_state = CALL_STATE_DIALING;
                //selectedCall->_stop = 0;
Emmanuel Milou's avatar
Emmanuel Milou committed
326
327
328
329
                break;
            case CALL_STATE_CURRENT:
            case CALL_STATE_HOLD:
            case CALL_STATE_BUSY:
330
            case CALL_STATE_RECORD:
Emmanuel Milou's avatar
Emmanuel Milou committed
331
                dbus_hang_up (selectedCall);
332
                call_remove_all_errors(selectedCall);
333
                selectedCall->_state = CALL_STATE_DIALING;
334
                set_timestamp (&selectedCall->_time_stop);
Emmanuel Milou's avatar
Emmanuel Milou committed
335
336
337
                break;
            case CALL_STATE_FAILURE:
                dbus_hang_up (selectedCall);
338
                call_remove_all_errors(selectedCall);
339
                selectedCall->_state = CALL_STATE_DIALING;
Emmanuel Milou's avatar
Emmanuel Milou committed
340
341
342
                break;
            case CALL_STATE_INCOMING:
                dbus_refuse (selectedCall);
343
                call_remove_all_errors(selectedCall);
344
                selectedCall->_state = CALL_STATE_DIALING;
345
                DEBUG("from sflphone_hang_up : "); stop_notification();
Emmanuel Milou's avatar
Emmanuel Milou committed
346
347
348
                break;
            case CALL_STATE_TRANSFERT:
                dbus_hang_up (selectedCall);
349
                call_remove_all_errors(selectedCall);
350
                set_timestamp (&selectedCall->_time_stop);
Emmanuel Milou's avatar
Emmanuel Milou committed
351
352
                break;
            default:
353
                WARN("Should not happen in sflphone_hang_up()!");
Emmanuel Milou's avatar
Emmanuel Milou committed
354
355
356
                break;
        }
    }
357
    calltree_update_call(history, selectedCall, NULL);
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
358
359
360
}


Alexandre Savard's avatar
Alexandre Savard committed
361
362
363
364
365
366
367
368
369
370
void
sflphone_conference_hang_up()
{
    conference_obj_t * selectedConf = calltab_get_selected_conf();

    if(selectedConf)
	dbus_hang_up_conference(selectedConf);
}


Emmanuel Milou's avatar
Emmanuel Milou committed
371
    void
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
372
373
sflphone_pick_up()
{
Alexandre Savard's avatar
Alexandre Savard committed
374
    DEBUG("sflphone_pick_up\n");
375
376
377
    callable_obj_t * selectedCall = NULL;
    selectedCall = calltab_get_selected_call(active_calltree);
    
Emmanuel Milou's avatar
Emmanuel Milou committed
378
379
    if(selectedCall)
    {
380
        switch(selectedCall->_state)
Emmanuel Milou's avatar
Emmanuel Milou committed
381
382
383
384
385
        {
            case CALL_STATE_DIALING:
                sflphone_place_call (selectedCall);
                break;
            case CALL_STATE_INCOMING:
386
                selectedCall->_history_state = INCOMING;
387
                calltree_update_call( history, selectedCall, NULL);
Emmanuel Milou's avatar
Emmanuel Milou committed
388
                dbus_accept (selectedCall);
389
                DEBUG("from sflphone_pick_up : "); stop_notification();
Emmanuel Milou's avatar
Emmanuel Milou committed
390
391
392
393
394
395
                break;
            case CALL_STATE_HOLD:
                sflphone_new_call();
                break;
            case CALL_STATE_TRANSFERT:
                dbus_transfert (selectedCall);
396
                set_timestamp (&selectedCall->_time_stop);
Emmanuel Milou's avatar
Emmanuel Milou committed
397
398
399
400
401
402
403
404
405
                break;
            case CALL_STATE_CURRENT:
            case CALL_STATE_RECORD:
                sflphone_new_call();
                break;
            case CALL_STATE_RINGING:
                sflphone_new_call();
                break;
            default:
406
                WARN("Should not happen in sflphone_pick_up()!");
Emmanuel Milou's avatar
Emmanuel Milou committed
407
408
409
                break;
        }
    }
410
411
412
    else {
        sflphone_new_call();
    }
413

Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
414
415
}

Emmanuel Milou's avatar
Emmanuel Milou committed
416
    void
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
417
418
sflphone_on_hold ()
{
419
    callable_obj_t * selectedCall = calltab_get_selected_call(current_calls);
Emmanuel Milou's avatar
Emmanuel Milou committed
420
421
    if(selectedCall)
    {
422
        switch(selectedCall->_state)
Emmanuel Milou's avatar
Emmanuel Milou committed
423
424
425
426
427
428
429
430
431
        {
            case CALL_STATE_CURRENT:
                dbus_hold (selectedCall);
                break;
            case CALL_STATE_RECORD:
                dbus_hold (selectedCall);
                break;

            default:
432
                WARN("Should not happen in sflphone_on_hold!");
Emmanuel Milou's avatar
Emmanuel Milou committed
433
434
435
                break;
        }
    }
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
436
437
}

Emmanuel Milou's avatar
Emmanuel Milou committed
438
    void
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
439
440
sflphone_off_hold ()
{
441
    callable_obj_t * selectedCall = calltab_get_selected_call(current_calls);
Emmanuel Milou's avatar
Emmanuel Milou committed
442
443
    if(selectedCall)
    {
444
        switch(selectedCall->_state)
Emmanuel Milou's avatar
Emmanuel Milou committed
445
446
447
448
449
        {
            case CALL_STATE_HOLD:
                dbus_unhold (selectedCall);
                break;
            default:
450
                WARN("Should not happen in sflphone_off_hold ()!");
Emmanuel Milou's avatar
Emmanuel Milou committed
451
452
453
                break;
        }
    }
Julien Bonjean's avatar
Julien Bonjean committed
454

455
    if(dbus_get_is_recording(selectedCall))
456
    {
457
        DEBUG("Currently recording!");
458
    }
459
    else
460
    {
461
        DEBUG("Not recording currently");
462
    }
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
463
464
465
}


Emmanuel Milou's avatar
Emmanuel Milou committed
466
    void
467
sflphone_fail( callable_obj_t * c )
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
468
{
469
    c->_state = CALL_STATE_FAILURE;
470
    calltree_update_call(current_calls, c, NULL);
Emmanuel Milou's avatar
Emmanuel Milou committed
471
    update_menus();
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
472
473
}

Emmanuel Milou's avatar
Emmanuel Milou committed
474
    void
475
sflphone_busy( callable_obj_t * c )
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
476
{
477
    c->_state = CALL_STATE_BUSY;
478
    calltree_update_call(current_calls, c, NULL);
Emmanuel Milou's avatar
Emmanuel Milou committed
479
    update_menus();
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
480
481
}

Emmanuel Milou's avatar
Emmanuel Milou committed
482
    void
483
sflphone_current( callable_obj_t * c )
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
484
{
485
486
    if( c->_state != CALL_STATE_HOLD )
        set_timestamp (&c->_time_start);
487
    c->_state = CALL_STATE_CURRENT;
488
    calltree_update_call(current_calls, c, NULL);
Emmanuel Milou's avatar
Emmanuel Milou committed
489
    update_menus();
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
490
491
}

Emmanuel Milou's avatar
Emmanuel Milou committed
492
    void
493
sflphone_record( callable_obj_t * c )
alexandresavard's avatar
alexandresavard committed
494
{
495
496
    if( c->_state != CALL_STATE_HOLD )
        set_timestamp (&c->_time_start);
497
    c->_state = CALL_STATE_RECORD;
498
    calltree_update_call(current_calls, c, NULL);
Emmanuel Milou's avatar
Emmanuel Milou committed
499
    update_menus();
alexandresavard's avatar
alexandresavard committed
500
501
}

Emmanuel Milou's avatar
Emmanuel Milou committed
502
    void
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
503
sflphone_set_transfert()
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
504
{
505
    callable_obj_t * c = calltab_get_selected_call(current_calls);
Emmanuel Milou's avatar
Emmanuel Milou committed
506
507
    if(c)
    {
508
        c->_state = CALL_STATE_TRANSFERT;
509
        c->_trsft_to = g_strdup("");
510
        calltree_update_call(current_calls, c, NULL);
Emmanuel Milou's avatar
Emmanuel Milou committed
511
512
513
        update_menus();
    }
    toolbar_update_buttons();
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
514
515
}

Emmanuel Milou's avatar
Emmanuel Milou committed
516
    void
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
517
518
sflphone_unset_transfert()
{
519
    callable_obj_t * c = calltab_get_selected_call(current_calls);
Emmanuel Milou's avatar
Emmanuel Milou committed
520
521
    if(c)
    {
522
        c->_state = CALL_STATE_CURRENT;
523
        c->_trsft_to = g_strdup("");
524
        calltree_update_call(current_calls, c, NULL);
Emmanuel Milou's avatar
Emmanuel Milou committed
525
526
527
        update_menus();
    }
    toolbar_update_buttons();
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
528
}
Emmanuel Milou's avatar
Emmanuel Milou committed
529

530
    void
531
532
533
534
535
sflphone_display_transfer_status(const gchar* message)
{
    statusbar_push_message( message , __MSG_ACCOUNT_DEFAULT);
}

Emmanuel Milou's avatar
Emmanuel Milou committed
536
    void
537
sflphone_incoming_call (callable_obj_t * c)
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
538
{
539
    c->_history_state = MISSED;
Julien Bonjean's avatar
Julien Bonjean committed
540
541
    calllist_add ( current_calls, c );
    calllist_add( history, c );
542
    calltree_add_call( current_calls, c, NULL);
Emmanuel Milou's avatar
Emmanuel Milou committed
543
    update_menus();
Julien Bonjean's avatar
Julien Bonjean committed
544
    calltree_display (current_calls);
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
545
}
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
546

Emmanuel Milou's avatar
Emmanuel Milou committed
547
    void
548
process_dialing(callable_obj_t * c, guint keyval, gchar * key)
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
549
{
Emmanuel Milou's avatar
Emmanuel Milou committed
550
    // We stop the tone
551
    if(strlen(c->_peer_number) == 0 && c->_state != CALL_STATE_TRANSFERT){
Emmanuel Milou's avatar
Emmanuel Milou committed
552
553
554
        dbus_start_tone( FALSE , 0 );
        //dbus_play_dtmf( key );
    }
555

556
557
    DEBUG("process_dialing : keyval : %i",keyval);
    DEBUG("process_dialing : key : %s",key);
Emmanuel Milou's avatar
Emmanuel Milou committed
558
559
560
561
562
563
564
565
566
567
568
569

    switch (keyval)
    {
        case 65293: /* ENTER */
        case 65421: /* ENTER numpad */
            sflphone_place_call(c);
            break;
        case 65307: /* ESCAPE */
            sflphone_hang_up(c);
            break;
        case 65288: /* BACKSPACE */
            {  /* Brackets mandatory because of local vars */
570
571
                gchar * before = c->_peer_number;
                if(strlen(c->_peer_number) >= 1){
Emmanuel Milou's avatar
Emmanuel Milou committed
572

573
574
575
576
577
578
579
580
581
					if (c->_state == CALL_STATE_TRANSFERT)
					{
						c->_trsft_to = g_strndup (c->_trsft_to, strlen(c->_trsft_to) - 1);
					}
					else
					{
						c->_peer_number = g_strndup(c->_peer_number, strlen(c->_peer_number) -1);
						g_free(before);
						DEBUG("TO: backspace %s", c->_peer_number);
Emmanuel Milou's avatar
Emmanuel Milou committed
582
                    }
583
					calltree_update_call(current_calls, c, NULL);
Julien Bonjean's avatar
Julien Bonjean committed
584
                }
585
                else if(strlen(c->_peer_number) == 0)
Emmanuel Milou's avatar
Emmanuel Milou committed
586
                {
587
                    if(c->_state != CALL_STATE_TRANSFERT)
Emmanuel Milou's avatar
Emmanuel Milou committed
588
589
590
591
592
593
594
595
596
597
598
599
600
                        dbus_hang_up(c);
                }
            }
            break;
        case 65289: /* TAB */
        case 65513: /* ALT */
        case 65507: /* CTRL */
        case 65515: /* SUPER */
        case 65509: /* CAPS */
            break;
        default:
            // if (keyval < 255 || (keyval >65453 && keyval < 65466))
            if (keyval < 127 || (keyval > 65400 && keyval < 65466))
Julien Bonjean's avatar
Julien Bonjean committed
601
            {
Emmanuel Milou's avatar
Emmanuel Milou committed
602

603
604
605
606
607
608
                if (c->_state == CALL_STATE_TRANSFERT)
                {
                    c->_trsft_to = g_strconcat(c->_trsft_to, key, NULL);
                }
                else
                {
Emmanuel Milou's avatar
Emmanuel Milou committed
609
                    dbus_play_dtmf( key );
610
611
                    c->_peer_number = g_strconcat(c->_peer_number, key, NULL);
                }
Emmanuel Milou's avatar
Emmanuel Milou committed
612

613
                if(c->_state == CALL_STATE_DIALING)
Emmanuel Milou's avatar
Emmanuel Milou committed
614
                {
615
616
                    //g_free(c->_peer_name);
                    //c->_peer_name = g_strconcat("\"\" <", c->_peer_number, ">", NULL);
Emmanuel Milou's avatar
Emmanuel Milou committed
617
                }
618
                calltree_update_call(current_calls, c, NULL);
Emmanuel Milou's avatar
Emmanuel Milou committed
619
620
621
            }
            break;
    }
622
623
}

Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
624

625
    callable_obj_t *
areversat's avatar
areversat committed
626
sflphone_new_call()
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
627
{
Julien Bonjean's avatar
Julien Bonjean committed
628

629
630
    callable_obj_t *c;
    gchar *peer_name, *peer_number;
631

632
    DEBUG("sflphone_new_call");
Emmanuel Milou's avatar
Emmanuel Milou committed
633
    sflphone_on_hold();
634

Emmanuel Milou's avatar
Emmanuel Milou committed
635
    // Play a tone when creating a new call
Julien Bonjean's avatar
Julien Bonjean committed
636
    if( calllist_get_size(current_calls) == 0 )
Emmanuel Milou's avatar
Emmanuel Milou committed
637
        dbus_start_tone( TRUE , ( voice_mails > 0 )? TONE_WITH_MESSAGE : TONE_WITHOUT_MESSAGE) ;
Emmanuel Milou's avatar
Emmanuel Milou committed
638

639
640
641
    peer_number = g_strdup("");
    peer_name = g_strdup ("");
    create_new_call (CALL, CALL_STATE_DIALING, "", "", peer_name, peer_number, &c);
Emmanuel Milou's avatar
Emmanuel Milou committed
642

643
    calllist_add (current_calls,c);
644
    calltree_add_call (current_calls, c, NULL);
Emmanuel Milou's avatar
Emmanuel Milou committed
645
    update_menus();
646

Emmanuel Milou's avatar
Emmanuel Milou committed
647
    return c;
648
649
}

areversat's avatar
areversat committed
650

Emmanuel Milou's avatar
Emmanuel Milou committed
651
    void
areversat's avatar
areversat committed
652
653
sflphone_keypad( guint keyval, gchar * key)
{
654
    callable_obj_t * c = calltab_get_selected_call(current_calls);
Emmanuel Milou's avatar
Emmanuel Milou committed
655
656
657

    if((active_calltree != current_calls) || (active_calltree == current_calls && !c))
    {
658
        DEBUG("Not in a call, not dialing, create a new call");
Emmanuel Milou's avatar
Emmanuel Milou committed
659
660
661
662
663
664
665
666
        //dbus_play_dtmf(key);
        switch (keyval)
        {
            case 65293: /* ENTER */
            case 65421: /* ENTER numpad */
            case 65307: /* ESCAPE */
                break;
            default:
Julien Bonjean's avatar
Julien Bonjean committed
667
                calltree_display (current_calls);
Emmanuel Milou's avatar
Emmanuel Milou committed
668
669
670
671
672
673
                process_dialing(sflphone_new_call(), keyval, key);
                break;
        }
    }
    else if(c)
    {
674
        DEBUG("Call is non-zero");
675
        switch(c->_state)
Emmanuel Milou's avatar
Emmanuel Milou committed
676
677
        {
            case CALL_STATE_DIALING: // Currently dialing => edit number
678
                DEBUG("Writing a number");
Emmanuel Milou's avatar
Emmanuel Milou committed
679
680
681
682
683
684
685
686
                process_dialing(c, keyval, key);
                break;
            case CALL_STATE_RECORD:
            case CALL_STATE_CURRENT:
                switch (keyval)
                {
                    case 65307: /* ESCAPE */
                        dbus_hang_up(c);
687
                        set_timestamp (&c->_time_stop);
688
                        calltree_update_call(history, c, NULL);
Emmanuel Milou's avatar
Emmanuel Milou committed
689
690
691
692
693
694
695
696
697
698
699
                        break;
                    default:
                        // To play the dtmf when calling mail box for instance
                        dbus_play_dtmf(key);
                        if (keyval < 255 || (keyval >65453 && keyval < 65466))
                        {
                            //gchar * temp = g_strconcat(call_get_number(c), key, NULL);
                            //gchar * before = c->from;
                            //c->from = g_strconcat("\"",call_get_name(c) ,"\" <", temp, ">", NULL);
                            //g_free(before);
                            //g_free(temp);
700
                            //update_callable_obj_tree(current_calls,c);
Emmanuel Milou's avatar
Emmanuel Milou committed
701
702
703
704
705
706
707
708
709
                        }
                        break;
                }
                break;
            case CALL_STATE_INCOMING:
                switch (keyval)
                {
                    case 65293: /* ENTER */
                    case 65421: /* ENTER numpad */
710
                        c->_history_state = INCOMING;
711
                        calltree_update_call(history, c, NULL);
Emmanuel Milou's avatar
Emmanuel Milou committed
712
                        dbus_accept(c);
713
                        DEBUG("from sflphone_keypad ( enter ) : "); stop_notification();
Emmanuel Milou's avatar
Emmanuel Milou committed
714
715
716
                        break;
                    case 65307: /* ESCAPE */
                        dbus_refuse(c);
717
                        DEBUG("from sflphone_keypad ( escape ) : "); stop_notification();
Emmanuel Milou's avatar
Emmanuel Milou committed
718
719
720
721
722
723
724
725
726
                        break;
                }
                break;
            case CALL_STATE_TRANSFERT:
                switch (keyval)
                {
                    case 65293: /* ENTER */
                    case 65421: /* ENTER numpad */
                        dbus_transfert(c);
727
                        set_timestamp (&c->_time_stop);
Emmanuel Milou's avatar
Emmanuel Milou committed
728
729
730
731
                        break;
                    case 65307: /* ESCAPE */
                        sflphone_unset_transfert(c);
                        break;
732
                    default: // When a call is on transfert, typing new numbers will add it to c->_peer_number
Emmanuel Milou's avatar
Emmanuel Milou committed
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
                        process_dialing(c, keyval, key);
                        break;
                }
                break;
            case CALL_STATE_HOLD:
                switch (keyval)
                {
                    case 65293: /* ENTER */
                    case 65421: /* ENTER numpad */
                        dbus_unhold(c);
                        break;
                    case 65307: /* ESCAPE */
                        dbus_hang_up(c);
                        break;
                    default: // When a call is on hold, typing new numbers will create a new call
                        process_dialing(sflphone_new_call(), keyval, key);
                        break;
                }
                break;
            case CALL_STATE_RINGING:
            case CALL_STATE_BUSY:
            case CALL_STATE_FAILURE:
755
                //c->_stop = 0;
Emmanuel Milou's avatar
Emmanuel Milou committed
756
757
758
759
                switch (keyval)
                {
                    case 65307: /* ESCAPE */
                        dbus_hang_up(c);
760
                        //c->_stop = 0;
761
                        calltree_update_call(history, c, NULL);
Emmanuel Milou's avatar
Emmanuel Milou committed
762
763
764
765
766
767
                        break;
                }
                break;
            default:
                break;
        }
768

Alexandre Savard's avatar
Alexandre Savard committed
769
770
    }
    else {
771
        sflphone_new_call();
Emmanuel Milou's avatar
Emmanuel Milou committed
772
773
    }
}
774
775

/*
776
 * Place a call with the current account.
Emmanuel Milou's avatar
Emmanuel Milou committed
777
 * If there is no default account selected, place a call with the first
778
 * registered account of the account list
779
 * Else, check if it an IP call. if not, popup an error message
780
 */
781
782
783
784
785
786
787
788
 
static gboolean _is_direct_call(callable_obj_t * c) {

    if(g_strcasecmp(c->_accountID, EMPTY_ENTRY) == 0) {
        if(!g_str_has_prefix (c->_peer_number, "sip:")) {
            gchar * new_number = g_strconcat("sip:", c->_peer_number, NULL);
            g_free(c->_peer_number);
            c->_peer_number = new_number;
789
        }
790
791
        return 1;
    }
Emmanuel Milou's avatar
Emmanuel Milou committed
792

793
794
795
    if(g_str_has_prefix (c->_peer_number, "sip:")) {
        return 1;
    }
Julien Bonjean's avatar
Julien Bonjean committed
796

797
798
    return 0;
}
Julien Bonjean's avatar
Julien Bonjean committed
799

800
801
802
803
804
805
806
807
static int _place_direct_call(const callable_obj_t * c) {
    if (c->_state == CALL_STATE_DIALING) {
        dbus_place_call (c);
    } else {
        return -1;
    }
    return 0;
}
Julien Bonjean's avatar
Julien Bonjean committed
808

809
static int _place_registered_call(callable_obj_t * c) {
810

811
812
    account_t * current = NULL;
  
813
814
815
816
817
    if(c == NULL) {
        DEBUG("callable_obj_t is NULL in _place_registered_call");
        return -1;
    }
    
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
    if (c->_state != CALL_STATE_DIALING) {
        return -1;
    }
  
    if(g_strcasecmp(c->_peer_number, "") == 0) {
        return -1;
    }
    
    if( account_list_get_size() == 0 ) {
        notify_no_accounts();
        sflphone_fail(c);
        return -1;
    } 
    
    if( account_list_get_by_state( ACCOUNT_STATE_REGISTERED ) == NULL ) {
        notify_no_registered_accounts();
        sflphone_fail(c);
        return -1;
    }
    
838
839
840
841
842
    if(g_strcasecmp(c->_accountID, "") != 0) {
        current = account_list_get_by_id(c->_accountID);
    } else {
        current = account_list_get_current();
    }
843

844
    if(current == NULL) { 
845
        DEBUG("Unexpected condition: account_t is NULL in %s at %d for accountID %s", __FILE__, __LINE__, c->_accountID);
846
847
        return -1;
    }   
848
                        
849
850
851
852
853
854
855
856
857
858
    if(g_strcasecmp(g_hash_table_lookup( current->properties, "Status"),"REGISTERED")==0) {
        /* The call is made with the current account */
        c->_accountID = current->accountID;
        dbus_place_call(c);
    } else {
       /* Place the call with the first registered account
        * and switch the current account.
        * If we are here, we can be sure that there is at least one. 
        */
        current = account_list_get_by_state( ACCOUNT_STATE_REGISTERED );
859
        c->_accountID = current->accountID;
860
861
862
863
864
865
866
867
        dbus_place_call(c);
        notify_current_account( current );
    }        

    c->_history_state = OUTGOING;
    calllist_add(history, c);                
    return 0;
}
868

869
870
871
872
873
874
875
876
877
    void
sflphone_place_call ( callable_obj_t * c )
{
    DEBUG("Placing call with %s @ %s and accountid %s", c->_peer_name, c->_peer_number, c->_accountID);
    
    if(c == NULL) {
        DEBUG("Unexpected condition: callable_obj_t is null in %s at %d", __FILE__, __LINE__);
        return;
    }
878

879
880
881
882
883
884
885
886
887
    if(_is_direct_call(c)) {
        if(_place_direct_call(c) < 0) {
            DEBUG("An error occured while placing direct call in %s at %d", __FILE__, __LINE__);
            return;
        }
    } else {
        if(_place_registered_call(c) < 0) {
            DEBUG("An error occured while placing registered call in %s at %d", __FILE__, __LINE__);
            return;
888
        }
Emmanuel Milou's avatar
Emmanuel Milou committed
889
    }
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
890
891
}

Emmanuel Milou's avatar
Emmanuel Milou committed
892
    void
Alexandre Savard's avatar
Alexandre Savard committed
893
894
sflphone_display_selected_codec (const gchar* codecName)
{
Julien Bonjean's avatar
Julien Bonjean committed
895

896
    callable_obj_t * selectedCall;
Alexandre Savard's avatar
Alexandre Savard committed
897
898
899
    gchar* msg;
    account_t* acc;

Emmanuel Milou's avatar
Emmanuel Milou committed
900
901
    selectedCall =  calltab_get_selected_call(current_calls);
    if (selectedCall) {
902
        if(selectedCall->_accountID != NULL){
903
            statusbar_pop_message(__MSG_ACCOUNT_DEFAULT);
904
            acc = account_list_get_by_id(selectedCall->_accountID);
Emmanuel Milou's avatar
Emmanuel Milou committed
905
906
907
908
            if (!acc) {
                msg = g_markup_printf_escaped (_("IP call - %s"), codecName);
            }
            else {
909
910
                msg = g_markup_printf_escaped("%s %s (%s) - %s %s" ,
                        _("Using account"),
911
912
                        (gchar*)g_hash_table_lookup( acc->properties , ACCOUNT_ALIAS),
                        (gchar*)g_hash_table_lookup( acc->properties , ACCOUNT_TYPE),
913
                        _("Codec"),
914
                        codecName);
Emmanuel Milou's avatar
Emmanuel Milou committed
915
916
917
            }
            statusbar_push_message( msg , __MSG_ACCOUNT_DEFAULT);
            g_free(msg);
918
        }
Emmanuel Milou's avatar
Emmanuel Milou committed
919
    }
Alexandre Savard's avatar
Alexandre Savard committed
920
921
}

Emmanuel Milou's avatar
Emmanuel Milou committed
922
    gchar*
Alexandre Savard's avatar
Alexandre Savard committed
923
924
sflphone_get_current_codec_name()
{
925
    callable_obj_t * selectedCall = calltab_get_selected_call(current_calls);
Alexandre Savard's avatar
Alexandre Savard committed
926
927
928
    return dbus_get_current_codec_name(selectedCall);
}

929
    void
930
sflphone_detach_participant(const gchar* callID)
931
{
932
    DEBUG("sflphone detach participant from conference");
933

934
935
    

936
937
    if(callID == NULL) {
        callable_obj_t * selectedCall = calltab_get_selected_call(current_calls);
938
939
940
941
	DEBUG("    sflphone_detach_participant %s\n", selectedCall->_callID);

	calltree_remove_call(current_calls, selectedCall, NULL);
	calltree_add_call(current_calls, selectedCall, NULL);
942
943
944
        dbus_detach_participant(selectedCall->_callID);
    }
    else {
945
946
947
948
949
	callable_obj_t * selectedCall = calllist_get(current_calls, callID);
	DEBUG("    sflphone_detach_participant %s\n", callID);

	calltree_remove_call(current_calls, selectedCall, NULL);
	calltree_add_call(current_calls, selectedCall, NULL);
</