actions.c 36.4 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
#include "icons/icon_factory.h"
26

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

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

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

43
44
45
46
47
48
49
50
51
52
    // 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)
    {
53
        gchar * message = g_strdup_printf(n_("%d voice mail", "%d voice mails", count), count);
54
55
56
        statusbar_push_message(message,  __MSG_VOICE_MAILS);
        g_free(message);
    }
Emmanuel Milou's avatar
Emmanuel Milou committed
57

58
59
60
61
    // 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
62
63
        if( acc != NULL )
            notify_voice_mails( count , acc );
64
    }
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
65
66
}

Emmanuel Milou's avatar
Emmanuel Milou committed
67
    void
68
status_bar_display_account ()
69
{
70
    gchar* msg;
71
    account_t* acc;
72
73
74
75
76

    statusbar_pop_message(__MSG_ACCOUNT_DEFAULT);

    acc = account_list_get_current ();
    if(acc){
77
78
        msg = g_markup_printf_escaped("%s %s (%s)" ,
                _("Using account"),
79
80
                (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
81
    }
82
83
    else
    {
84
        msg = g_markup_printf_escaped(_("No registered accounts"));
85
86
87
    }
    statusbar_push_message( msg , __MSG_ACCOUNT_DEFAULT);
    g_free(msg);
88
89
}

Emmanuel Milou's avatar
Emmanuel Milou committed
90
91

    gboolean
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
92
93
sflphone_quit ()
{
Emmanuel Milou's avatar
Emmanuel Milou committed
94
    gboolean quit = FALSE;
Julien Bonjean's avatar
Julien Bonjean committed
95
    guint count = calllist_get_size(current_calls);
Emmanuel Milou's avatar
Emmanuel Milou committed
96
97
98
99
100
101
102
103
104
    if(count > 0){
        quit = main_window_ask_quit();
    }
    else{
        quit = TRUE;
    }

    if (quit)
    {
105
106
107
        // Save the history 
        sflphone_save_history ();

Emmanuel Milou's avatar
Emmanuel Milou committed
108
109
110
111
112
113
114
        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
115
116
}

Emmanuel Milou's avatar
Emmanuel Milou committed
117
    void
118
sflphone_hold (callable_obj_t * c )
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
119
{
120
    c->_state = CALL_STATE_HOLD;
121
    calltree_update_call(current_calls, c, NULL);
122
    update_actions();
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
123
124
}

Emmanuel Milou's avatar
Emmanuel Milou committed
125
    void
126
sflphone_ringing(callable_obj_t * c )
127
{
128
    c->_state = CALL_STATE_RINGING;
129
    calltree_update_call(current_calls, c, NULL);
130
    update_actions();
131
}
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
132

Emmanuel Milou's avatar
Emmanuel Milou committed
133
    void
134
sflphone_hung_up( callable_obj_t * c)
Emmanuel Milou's avatar
Emmanuel Milou committed
135
{
136
    calllist_remove( current_calls, c->_callID);
137
    calltree_remove_call(current_calls, c, NULL);
138
    c->_state = CALL_STATE_DIALING;
139
    call_remove_all_errors(c);
140
    update_actions();
141
#if GTK_CHECK_VERSION(2,10,0)
Emmanuel Milou's avatar
Emmanuel Milou committed
142
    status_tray_icon_blink( FALSE );
143
#endif
Emmanuel Milou's avatar
Emmanuel Milou committed
144
145
}

146
147
static hashtable_free(gpointer key, gpointer value, gpointer user_data)
{
148
    g_free(key);
149
150
151
    g_free(value);
}

Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
152
/** Internal to actions: Fill account list */
Emmanuel Milou's avatar
Emmanuel Milou committed
153
    void
154
sflphone_fill_account_list(gboolean toolbarInitialized)
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
155
{
156
157
158
159
160

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

Emmanuel Milou's avatar
Emmanuel Milou committed
161
    account_list_clear ( );
162

Emmanuel Milou's avatar
Emmanuel Milou committed
163
    array = (gchar **)dbus_account_list();
164
165
    if(array)
    {
Emmanuel Milou's avatar
Emmanuel Milou committed
166
167
168
169
        for (accountID = array; *accountID; accountID++)
        {
            account_t * a = g_new0(account_t,1);
            a->accountID = g_strdup(*accountID);
170
            a->credential_information = NULL;
Emmanuel Milou's avatar
Emmanuel Milou committed
171
172
173
            account_list_add(a);
        }
        g_strfreev (array);
174
    }
175

Emmanuel Milou's avatar
Emmanuel Milou committed
176
177
178
179
    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);
180
181
        if( details == NULL )
            break;
Emmanuel Milou's avatar
Emmanuel Milou committed
182
        a->properties = details;
183
                        
184
185
186
        /* As this function might be called numberous time, we should free the 
         * previously allocated space to avoid memory leaks.
         */
187
188
189
190
191
192
193

        /* 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 {
194
195
196
            a->credential_information = NULL;
        }
        
197
        int credential_index;
198
199
        for(credential_index = 0; credential_index < number_of_credential; credential_index++) {
            GHashTable * credential_information = dbus_get_credential(a->accountID, credential_index);
200
            g_ptr_array_add(a->credential_information, credential_information);
201
        }
Emmanuel Milou's avatar
Emmanuel Milou committed
202

203
        gchar * status = g_hash_table_lookup(details, REGISTRATION_STATUS);
Emmanuel Milou's avatar
Emmanuel Milou committed
204
205
206
207
208
209
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
        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;
        }

245
246
247
248
249
250
251
        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
252
253
254
255
    }

    // Prevent update being called when toolbar is not yet initialized
    if(toolbarInitialized)
256
        update_actions ();
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
257
258
}

259
gboolean sflphone_init()
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
260
{
Emmanuel Milou's avatar
Emmanuel Milou committed
261
262
263
264
265
266
267
268
    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");
269

270
271
272
		// Init icons factory
		init_icon_factory ();

273
274
275
        current_calls = calltab_init(FALSE, CURRENT_CALLS);
        contacts = calltab_init(TRUE, CONTACTS);
        history = calltab_init(TRUE, HISTORY);
276

Emmanuel Milou's avatar
Emmanuel Milou committed
277
        account_list_init ();
278
        codec_list_init();
279
		conferencelist_init();
280

281
        // Fetch the configured accounts
Emmanuel Milou's avatar
Emmanuel Milou committed
282
        sflphone_fill_account_list(FALSE);
283

284
285
286
        // Fetch the ip2ip profile 
        sflphone_fill_ip2ip_profile();
        
287
        // Fetch the audio codecs
Emmanuel Milou's avatar
Emmanuel Milou committed
288
        sflphone_fill_codec_list();
289

290
		// Fetch the conference list
291
		// sflphone_fill_conference_list();
292

Emmanuel Milou's avatar
Emmanuel Milou committed
293
294
        return TRUE;
    }
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
295
296
}

297
298
299
300
301
void sflphone_fill_ip2ip_profile(void)
{
    ip2ip_profile = (GHashTable *) dbus_get_ip2_ip_details();
}

Emmanuel Milou's avatar
Emmanuel Milou committed
302
void sflphone_get_ip2ip_properties (GHashTable **properties)
303
{
Emmanuel Milou's avatar
Emmanuel Milou committed
304
	*properties	= ip2ip_profile;
305
306
}

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


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

Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
411
412
}

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

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

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

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


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

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

Emmanuel Milou's avatar
Emmanuel Milou committed
479
    void
480
sflphone_current( callable_obj_t * c )
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
481
{
482

483
484
    if( c->_state != CALL_STATE_HOLD )
        set_timestamp (&c->_time_start);
485
    c->_state = CALL_STATE_CURRENT;
486
    calltree_update_call(current_calls, c, NULL);
487
    update_actions();
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
488
489
}

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

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

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

526
    void
527
528
529
530
531
sflphone_display_transfer_status(const gchar* message)
{
    statusbar_push_message( message , __MSG_ACCOUNT_DEFAULT);
}

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

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

552
553
    DEBUG("process_dialing : keyval : %i",keyval);
    DEBUG("process_dialing : key : %s",key);
Emmanuel Milou's avatar
Emmanuel Milou committed
554
555
556
557
558
559
560
561
562
563
564
565

    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 */
566
567
                gchar * before = c->_peer_number;
                if(strlen(c->_peer_number) >= 1){
Emmanuel Milou's avatar
Emmanuel Milou committed
568

569
570
571
572
573
574
575
576
577
					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
578
                    }
579
					calltree_update_call(current_calls, c, NULL);
Julien Bonjean's avatar
Julien Bonjean committed
580
                }
581
                else if(strlen(c->_peer_number) == 0)
Emmanuel Milou's avatar
Emmanuel Milou committed
582
                {
583
                    if(c->_state != CALL_STATE_TRANSFERT)
Emmanuel Milou's avatar
Emmanuel Milou committed
584
585
586
587
588
589
590
591
592
593
594
595
596
                        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
597
            {
Emmanuel Milou's avatar
Emmanuel Milou committed
598

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

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

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

621
    callable_obj_t *
areversat's avatar
areversat committed
622
sflphone_new_call()
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
623
{
Julien Bonjean's avatar
Julien Bonjean committed
624

625
    callable_obj_t *c;
626
    callable_obj_t * current_selected_call;
627
    gchar *peer_name, *peer_number;
628

629
    DEBUG("sflphone_new_call");
630
631
632

    current_selected_call = calltab_get_selected_call(current_calls);

633
    if ((current_selected_call != NULL) && (current_selected_call->_confID == NULL))
634
	sflphone_on_hold();
635

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

640
641
642
    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
643

644
    calllist_add (current_calls,c);
645
    calltree_add_call (current_calls, c, NULL);
646
    update_actions();
647

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

areversat's avatar
areversat committed
651

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

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

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

/*
777
 * Place a call with the current account.
Emmanuel Milou's avatar
Emmanuel Milou committed
778
 * If there is no default account selected, place a call with the first
779
 * registered account of the account list
780
 * Else, check if it an IP call. if not, popup an error message
781
 */
782
783
784
785
786
787
788
789
 
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;
790
        }
791
792
        return 1;
    }
Emmanuel Milou's avatar
Emmanuel Milou committed
793

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

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

801
802
803
804
805
806
807
808
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
809

810
static int _place_registered_call(callable_obj_t * c) {
811

812
813
    account_t * current = NULL;
  
814
815
816
817
818
    if(c == NULL) {
        DEBUG("callable_obj_t is NULL in _place_registered_call");
        return -1;
    }
    
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
    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;
    }
    
839
840
841
842
843
    if(g_strcasecmp(c->_accountID, "") != 0) {
        current = account_list_get_by_id(c->_accountID);
    } else {
        current = account_list_get_current();
    }
844

845
    if(current == NULL) { 
846
        DEBUG("Unexpected condition: account_t is NULL in %s at %d for accountID %s", __FILE__, __LINE__, c->_accountID);
847
848
        return -1;
    }   
849
                        
850
851
852
853
854
855
856
857
858
859
    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 );
860
        c->_accountID = current->accountID;
861
862
863
864
865
866
867
868
        dbus_place_call(c);
        notify_current_account( current );
    }        

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

870
871
872
873
874
875
876
877
878
    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;
    }
879

880
881
882
883
884
885
886
887
888
    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;
889
        }
Emmanuel Milou's avatar
Emmanuel Milou committed
890
    }
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
891
892
}

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

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

Emmanuel Milou's avatar
Emmanuel Milou committed
901
902
    selectedCall =  calltab_get_selected_call(current_calls);
    if (selectedCall) {
903
        if(selectedCall->_accountID != NULL){
904
            statusbar_pop_message(__MSG_ACCOUNT_DEFAULT);
905
            acc = account_list_get_by_id(selectedCall->_accountID);
Emmanuel Milou's avatar
Emmanuel Milou committed
906
907
908
909
            if (!acc) {
                msg = g_markup_printf_escaped (_("IP call - %s"), codecName);
            }
            else {
910
911
912

		if (strcmp(codecName, "") != 0) {
                    msg = g_markup_printf_escaped("%s %s (%s) - %s %s" ,
913
                        _("Using account"),
914
915
                        (gchar*)g_hash_table_lookup( acc->properties , ACCOUNT_ALIAS),
                        (gchar*)g_hash_table_lookup( acc->properties , ACCOUNT_TYPE),
916
                        _("Codec"),
917
                        codecName);
918
919
920
921
922
923
		} else {
		    msg = g_markup_printf_escaped("%s %s (%s)" ,
                        _("Using account"),
                        (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
924
925
926
            }
            statusbar_push_message( msg , __MSG_ACCOUNT_DEFAULT);
            g_free(msg);
927
        }
Emmanuel Milou's avatar
Emmanuel Milou committed
928
    }
Alexandre Savard's avatar
Alexandre Savard committed
929
930
}