actions.c 19.2 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>
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
5
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
10
11
12
13
14
15
16
17
18
19
 *  (at your option) any later version.
 *                                                                                
 *  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.
 *                                                                              
 *  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
23
#include <calltree.h>
#include <dbus.h>
24
#include <mainwindow.h>
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
25
#include <menus.h>
26
#include <statusicon.h>
areversat's avatar
areversat committed
27
#include <calltab.h>
areversat's avatar
areversat committed
28
#include <historyfilter.h>
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
29

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

37
38
guint voice_mails;

areversat's avatar
areversat committed
39
void
40
sflphone_notify_voice_mail ( const gchar* accountID , guint count )
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
41
{
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
    gchar *id;
    gchar *current;
    
    // 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);
        if( count > 1)
            g_sprintf(message, _("%d voice mails"), count);
        else
            g_sprintf(message, _("%d voice mail"), count);	  
        statusbar_push_message(message,  __MSG_VOICE_MAILS);
        g_free(message);
    }
	
    // TODO: add ifdef
    if( account_list_get_size() > 0 )
    {
        account_t* acc = account_list_get_by_id( id );
	if( acc != NULL )
            notify_voice_mails( count , acc );	
    }
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
71
72
}

73
74
75
void
status_bar_display_account( call_t* c)
{
76
    gchar* msg;
77
    account_t* acc;
Emmanuel Milou's avatar
Emmanuel Milou committed
78
    if(c->accountID != NULL){
79
      acc = account_list_get_by_id(c->accountID);
Emmanuel Milou's avatar
Emmanuel Milou committed
80
      msg = g_markup_printf_escaped(_("%s account- %s") , 
81
82
				  (gchar*)g_hash_table_lookup( acc->properties , ACCOUNT_TYPE), 
				  (gchar*)g_hash_table_lookup( acc->properties , ACCOUNT_ALIAS));
83
      statusbar_push_message( msg , __MSG_ACCOUNT_DEFAULT);
Emmanuel Milou's avatar
Emmanuel Milou committed
84
85
      g_free(msg);
  }
86
87
88
}
  

areversat's avatar
areversat committed
89
gboolean
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
90
91
sflphone_quit ()
{
92
	gboolean quit = FALSE;
areversat's avatar
areversat committed
93
	guint count = call_list_get_size(current_calls);
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
	if(count > 0){
		quit = main_window_ask_quit();
	}
	else{
		quit = TRUE;
	}

	if (quit)
	{
		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
110
111
}

areversat's avatar
areversat committed
112
void 
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
113
114
sflphone_hold(call_t * c )
{
115
	c->state = CALL_STATE_HOLD;
areversat's avatar
areversat committed
116
	update_call_tree(current_calls,c);
117
	update_menus();
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
118
119
}

areversat's avatar
areversat committed
120
void 
121
122
sflphone_ringing(call_t * c )
{
123
	c->state = CALL_STATE_RINGING;
areversat's avatar
areversat committed
124
	update_call_tree(current_calls,c);
125
	update_menus();
126
}
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
127

areversat's avatar
areversat committed
128
void
Emmanuel Milou's avatar
Emmanuel Milou committed
129
130
sflphone_hung_up( call_t * c)
{
areversat's avatar
areversat committed
131
132
  call_list_remove( current_calls, c->callID);
  update_call_tree_remove(current_calls, c);
133
  c->state = CALL_STATE_DIALING;
Emmanuel Milou's avatar
Emmanuel Milou committed
134
  update_menus();
135
#if GTK_CHECK_VERSION(2,10,0)
136
  status_tray_icon_blink( FALSE );
137
#endif
Emmanuel Milou's avatar
Emmanuel Milou committed
138
139
}

Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
140
/** Internal to actions: Fill account list */
141
142
	void
sflphone_fill_account_list(gboolean toolbarInitialized)
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
143
{
144
145
146
147
148

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

149
150
	account_list_clear ( );

151
152
153
154
155
156
157
158
159
160
161
	array = (gchar **)dbus_account_list();
    if(array)
    {
	    for (accountID = array; *accountID; accountID++)
	    {
		    account_t * a = g_new0(account_t,1);
		    a->accountID = g_strdup(*accountID);
		    account_list_add(a);
	    }
	    g_strfreev (array);
    }
162
163
164
165
166

	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);
167
168
        if( details == NULL )
            break;
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
		a->properties = details;

		gchar * status = g_hash_table_lookup(details, "Status");
		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;
		}
188
189
190
191
		else if(strcmp( status , "ERROR_AUTH") == 0 )
		{
		  a->state = ACCOUNT_STATE_ERROR_AUTH;
		}
192
193
194
195
		else if(strcmp( status , "ERROR_NETWORK") == 0 )
		{
		  a->state = ACCOUNT_STATE_ERROR_NETWORK;
		}
196
197
198
199
		else if(strcmp( status , "ERROR_HOST") == 0 )
		{
		  a->state = ACCOUNT_STATE_ERROR_HOST;
		}
Yun Liu's avatar
Yun Liu committed
200
201
202
203
204
205
206
207
		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;
		}	
208
209
210
211
212
213
214
		else
		{
			a->state = ACCOUNT_STATE_INVALID;
		}

	}

215
216
217
	// Prevent update being called when toolbar is not yet initialized
	if(toolbarInitialized)
		toolbar_update_buttons();
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
218
219
}

220
gboolean sflphone_init()
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
221
{
222
223
	if(!dbus_connect ()){
	
224
		main_window_error_message(_("Unable to connect to the SFLphone server.\nMake sure the daemon is running."));
225
226
227
228
229
		return FALSE;
	}
	else 
	{
		dbus_register(getpid(), "Gtk+ Client");
230
231
232
233
234
        current_calls = calltab_init();
	    history = calltab_init();
	    if(SHOW_SEARCHBAR)  histfilter = create_filter(GTK_TREE_MODEL(history->store));
	    account_list_init ();
        codec_list_init();
235
		sflphone_fill_account_list(FALSE);
236
		sflphone_fill_codec_list();
237
		sflphone_set_current_account();
238
239
		return TRUE;
	}
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
240
241
}

areversat's avatar
areversat committed
242
void 
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
243
sflphone_hang_up()
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
244
{
areversat's avatar
areversat committed
245
	call_t * selectedCall = call_get_selected(current_calls);
246
247
248
249
	if(selectedCall)
	{
		switch(selectedCall->state)
		{
areversat's avatar
areversat committed
250
251
252
			case CALL_STATE_DIALING:
				dbus_hang_up (selectedCall);
				break;
Emmanuel Milou's avatar
Emmanuel Milou committed
253
254
255
256
257
			case CALL_STATE_RINGING:
				dbus_hang_up (selectedCall);
				selectedCall->state = CALL_STATE_DIALING;
				selectedCall->_stop = 0;
				break;
258
259
260
261
			case CALL_STATE_CURRENT:
			case CALL_STATE_HOLD:
			case CALL_STATE_BUSY:
			case CALL_STATE_FAILURE:
262
                        case CALL_STATE_RECORD:
263
				dbus_hang_up (selectedCall);
areversat's avatar
areversat committed
264
				selectedCall->state = CALL_STATE_DIALING;
265
				(void) time(&selectedCall->_stop);
266
267
268
				break;
			case CALL_STATE_INCOMING:  
				dbus_refuse (selectedCall);
areversat's avatar
areversat committed
269
				selectedCall->state = CALL_STATE_DIALING;
270
				selectedCall->_stop = 0;
271
				g_print("from sflphone_hang_up : "); stop_notification();
272
273
274
				break;
			case CALL_STATE_TRANSFERT:  
				dbus_hang_up (selectedCall);
275
				(void) time(&selectedCall->_stop);
276
277
278
279
280
281
				break;
			default:
				g_warning("Should not happen in sflphone_hang_up()!");
				break;
		}
	}
Emmanuel Milou's avatar
Emmanuel Milou committed
282
	update_call_tree( history , selectedCall );
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
283
284
285
}


areversat's avatar
areversat committed
286
void 
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
287
288
sflphone_pick_up()
{
areversat's avatar
areversat committed
289
	call_t * selectedCall = call_get_selected(active_calltree);
290
291
292
293
294
295
296
297
	if(selectedCall)
	{
		switch(selectedCall->state)
		{
			case CALL_STATE_DIALING:
				sflphone_place_call (selectedCall);
				break;
			case CALL_STATE_INCOMING:
298
299
				selectedCall->history_state = INCOMING;
				update_call_tree( history , selectedCall );
300
				dbus_accept (selectedCall);
301
				g_print("from sflphone_pick_up : "); stop_notification();
302
303
				break;
			case CALL_STATE_HOLD:
304
				sflphone_new_call();
305
306
307
				break;
			case CALL_STATE_TRANSFERT:
				dbus_transfert (selectedCall);
308
				(void) time(&selectedCall->_stop);
309
				break;
310
311
312
			case CALL_STATE_CURRENT:
				sflphone_new_call();
				break;
313
314
315
			case CALL_STATE_RINGING:
				sflphone_new_call();
				break;
316
317
318
319
320
			default:
				g_warning("Should not happen in sflphone_pick_up()!");
				break;
		}
	}
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
321
322
}

areversat's avatar
areversat committed
323
void 
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
324
325
sflphone_on_hold ()
{
areversat's avatar
areversat committed
326
	call_t * selectedCall = call_get_selected(current_calls);
327
328
329
330
331
332
333
	if(selectedCall)
	{
		switch(selectedCall->state)
		{
			case CALL_STATE_CURRENT:
				dbus_hold (selectedCall);
				break;
334
335
336
337
                        case CALL_STATE_RECORD:
                                dbus_hold (selectedCall);
                                break;
                                
338
339
340
341
342
			default:
				g_warning("Should not happen in sflphone_on_hold!");
				break;
		}
	}
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
343
344
}

areversat's avatar
areversat committed
345
void 
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
346
347
sflphone_off_hold ()
{
areversat's avatar
areversat committed
348
	call_t * selectedCall = call_get_selected(current_calls);
349
350
351
352
353
354
355
356
357
358
359
360
	if(selectedCall)
	{
		switch(selectedCall->state)
		{
			case CALL_STATE_HOLD:
				dbus_unhold (selectedCall);
				break;
			default:
				g_warning("Should not happen in sflphone_off_hold ()!");
				break;
		}
	}
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
361
362
363
}


areversat's avatar
areversat committed
364
void 
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
365
366
sflphone_fail( call_t * c )
{
367
	c->state = CALL_STATE_FAILURE;
areversat's avatar
areversat committed
368
	update_call_tree(current_calls,c);
369
	update_menus();
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
370
371
}

areversat's avatar
areversat committed
372
void 
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
373
374
sflphone_busy( call_t * c )
{
375
	c->state = CALL_STATE_BUSY;
areversat's avatar
areversat committed
376
	update_call_tree(current_calls, c);
377
	update_menus();
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
378
379
}

areversat's avatar
areversat committed
380
void 
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
381
382
sflphone_current( call_t * c )
{
383
  if( c->state != CALL_STATE_HOLD )
Emmanuel Milou's avatar
Emmanuel Milou committed
384
	(void) time(&c->_start);
385
386
387
  c->state = CALL_STATE_CURRENT;
  update_call_tree(current_calls,c);
  update_menus();
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
388
389
}

alexandresavard's avatar
alexandresavard committed
390
391
392
393
394
395
396
397
398
399
void
sflphone_record( call_t * c )
{
  if( c->state != CALL_STATE_HOLD )
	(void) time(&c->_start);
  c->state = CALL_STATE_RECORD;
  update_call_tree(current_calls,c);
  update_menus();
}

areversat's avatar
areversat committed
400
void 
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
401
sflphone_set_transfert()
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
402
{
areversat's avatar
areversat committed
403
	call_t * c = call_get_selected(current_calls);
404
405
406
407
	if(c)
	{
		c->state = CALL_STATE_TRANSFERT;
		c->to = g_strdup("");
areversat's avatar
areversat committed
408
		update_call_tree(current_calls,c);
409
410
411
		update_menus();
	}
	toolbar_update_buttons();
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
412
413
}

areversat's avatar
areversat committed
414
void 
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
415
416
sflphone_unset_transfert()
{
areversat's avatar
areversat committed
417
	call_t * c = call_get_selected(current_calls);
418
419
420
421
	if(c)
	{
		c->state = CALL_STATE_CURRENT;
		c->to = g_strdup("");
areversat's avatar
areversat committed
422
		update_call_tree(current_calls,c);
423
424
425
		update_menus();
	}
	toolbar_update_buttons();
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
426
}
Emmanuel Milou's avatar
Emmanuel Milou committed
427

areversat's avatar
areversat committed
428
void
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
429
430
sflphone_incoming_call (call_t * c) 
{
431
	c->history_state = MISSED;
432
433
434
	call_list_add ( current_calls, c );
	call_list_add( history, c );
	update_call_tree_add( current_calls , c );
435
	update_menus();
436
	if( active_calltree == history )  switch_tab();
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
437
}
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
438

areversat's avatar
areversat committed
439
440
void
process_dialing(call_t * c, guint keyval, gchar * key)
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
441
{
442
	// We stop the tone
Emmanuel Milou's avatar
Emmanuel Milou committed
443
	if(strlen(c->to) == 0 && c->state != CALL_STATE_TRANSFERT){
444
	  dbus_start_tone( FALSE , 0 );
Emmanuel Milou's avatar
Emmanuel Milou committed
445
	  //dbus_play_dtmf( key );
446
	}
447
448
449
450
451
452
453
	switch (keyval)
	{
		case 65293: /* ENTER */
		case 65421: /* ENTER numpad */
			sflphone_place_call(c);
			break;
		case 65307: /* ESCAPE */
Emmanuel Milou's avatar
Emmanuel Milou committed
454
			sflphone_hang_up(c);
455
456
457
458
			break;
		case 65288: /* BACKSPACE */
			{  /* Brackets mandatory because of local vars */
				gchar * before = c->to;
459
				if(strlen(c->to) >= 1){
460
461
462
463
464
465
466
467
468
					c->to = g_strndup(c->to, strlen(c->to) -1);
					g_free(before);
					g_print("TO: %s\n", c->to);

					if(c->state == CALL_STATE_DIALING)
					{
						g_free(c->from);
						c->from = g_strconcat("\"\" <", c->to, ">", NULL);
					}
areversat's avatar
areversat committed
469
					update_call_tree(current_calls,c);
470
				} 
471
				else if(strlen(c->to) == 0)
472
				{
473
				  if(c->state != CALL_STATE_TRANSFERT)
474
475
476
477
478
479
480
481
482
483
484
485
486
					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))
			{ 
Emmanuel Milou's avatar
Emmanuel Milou committed
487
488
				if(c->state != CALL_STATE_TRANSFERT)
				  dbus_play_dtmf( key );
489
490
491
492
				  gchar * before = c->to;
				  c->to = g_strconcat(c->to, key, NULL);
				  g_free(before);
				  g_print("TO: %s\n", c->to);
493
494
495
496
497
498

				if(c->state == CALL_STATE_DIALING)
				{
					g_free(c->from);
					c->from = g_strconcat("\"\" <", c->to, ">", NULL);
				}
areversat's avatar
areversat committed
499
				update_call_tree(current_calls,c);
500
501
502
503
			}
			break;
	}

504
505
}

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

areversat's avatar
areversat committed
507
508
call_t * 
sflphone_new_call()
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
509
{
Emmanuel Milou's avatar
Emmanuel Milou committed
510
	// Play a tone when creating a new call
areversat's avatar
areversat committed
511
	if( call_list_get_size(current_calls) == 0 )
512
	  dbus_start_tone( TRUE , ( voice_mails > 0 )? TONE_WITH_MESSAGE : TONE_WITHOUT_MESSAGE) ;
Emmanuel Milou's avatar
Emmanuel Milou committed
513

514
515
516
517
518
519
520
521
522
	call_t * c = g_new0 (call_t, 1);
	c->state = CALL_STATE_DIALING;
	c->from = g_strconcat("\"\" <>", NULL);

	c->callID = g_new0(gchar, 30);
	g_sprintf(c->callID, "%d", rand()); 

	c->to = g_strdup("");

Emmanuel Milou's avatar
Emmanuel Milou committed
523
524
525
	c->_start = 0;
	c->_stop = 0;

areversat's avatar
areversat committed
526
527
	call_list_add(current_calls,c);
	update_call_tree_add(current_calls,c);  
528
529
530
	update_menus();

	return c;
531
532
}

areversat's avatar
areversat committed
533
534

void 
areversat's avatar
areversat committed
535
536
sflphone_keypad( guint keyval, gchar * key)
{
537

areversat's avatar
areversat committed
538
	call_t * c = call_get_selected(current_calls);
539
540
541
542
543
544
545
546
547
548
549
	if(c)
	{
		switch(c->state) 
		{
			case CALL_STATE_DIALING: // Currently dialing => edit number
				process_dialing(c, keyval, key);
				break;
			case CALL_STATE_CURRENT:
				switch (keyval)
				{
					case 65307: /* ESCAPE */
550
						dbus_hang_up(c);
Emmanuel Milou's avatar
Emmanuel Milou committed
551
552
						(void) time(&c->_stop);
						update_call_tree( history , c );
553
						break;
554
					default:  
Emmanuel Milou's avatar
Emmanuel Milou committed
555
						// To play the dtmf when calling mail box for instance
556
557
558
						dbus_play_dtmf(key);
						if (keyval < 255 || (keyval >65453 && keyval < 65466))
						{ 
559
560
561
562
563
							//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);
areversat's avatar
areversat committed
564
							//update_call_tree(current_calls,c);
565
566
567
568
569
570
571
572
573
						}
						break;
				}
				break;
			case CALL_STATE_INCOMING:
				switch (keyval)
				{
					case 65293: /* ENTER */
					case 65421: /* ENTER numpad */
574
575
						c->history_state = INCOMING;
						update_call_tree( history , c );
576
						dbus_accept(c);
577
						g_print("from sflphone_keypad ( enter ) : "); stop_notification();
578
579
580
						break;
					case 65307: /* ESCAPE */
						dbus_refuse(c);
581
						g_print("from sflphone_keypad ( escape ) : "); stop_notification();
582
583
584
585
586
587
588
589
590
						break;
				}
				break;
			case CALL_STATE_TRANSFERT:
				switch (keyval)
				{
					case 65293: /* ENTER */
					case 65421: /* ENTER numpad */
						dbus_transfert(c);
591
						(void) time(&c->_stop);
592
593
						break;
					case 65307: /* ESCAPE */
594
						sflphone_unset_transfert(c); 
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
						break;
					default: // When a call is on transfert, typing new numbers will add it to c->to
						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:
				switch (keyval)
				{
					case 65307: /* ESCAPE */
Emmanuel Milou's avatar
Emmanuel Milou committed
622
623
624
625
					  dbus_hang_up(c);
					  c->_stop = 0;
					  update_call_tree( history , c );
					  break;
626
627
628
629
630
631
632
633
				}
				break;
			default:
				break;
		} 
	}
	else 
	{ // Not in a call, not dialing, create a new call 
Emmanuel Milou's avatar
Emmanuel Milou committed
634
		//dbus_play_dtmf(key);
635
636
637
638
639
640
641
		switch (keyval)
		{
			case 65293: /* ENTER */
			case 65421: /* ENTER numpad */
			case 65307: /* ESCAPE */
				break;
			default:
642
643
				if( active_calltree == history )
				  switch_tab();
644
645
646
				process_dialing(sflphone_new_call(), keyval, key);
				break;
		}
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
647

648

649
	}
areversat's avatar
areversat committed
650
 } 
651
652

/*
653
 * Place a call with the current account.
654
655
656
657
 * If there is no default account selected, place a call with the first 
 * registered account of the account list
 * Else, popup an error message
 */
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
658
659
660
void 
sflphone_place_call ( call_t * c )
{
661
662

    if(c->state == CALL_STATE_DIALING && strcmp(c->to, "") != 0)
Emmanuel Milou's avatar
Emmanuel Milou committed
663
    {
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
        if( account_list_get_size() == 0 )
        {
            notify_no_accounts();
            sflphone_fail(c);
        }
        
        else if( account_list_get_by_state( ACCOUNT_STATE_REGISTERED ) == NULL )
        {
            notify_no_registered_accounts();
            sflphone_fail(c);
        }
    
        else
        {
            account_t * current = account_list_get_current();
            if( current )
            {
	            if(g_strcasecmp(g_hash_table_lookup( current->properties, "Status"),"REGISTERED")==0)
	            { 
	                // OK, everything alright - the call is made with the current account
	                c -> accountID = current -> accountID;
	                status_bar_display_account(c);
	                dbus_place_call(c);
	            }
	            else
	            {
	                // Current account is not registered 
	                // So we place a call with the first registered account
	                // And we switch the current account
	                current = account_list_get_by_state( ACCOUNT_STATE_REGISTERED );
	                c -> accountID = current -> accountID;
	                dbus_place_call(c);
	                notify_current_account( current );
	                status_bar_display_account(c);
	                account_list_set_current_id( c-> accountID );
	            }
            }
            else
            {
	            // No current accounts have been setup. 
	            // So we place a call with the first registered account
	            // and we change the current account
	            current = account_list_get_by_state( ACCOUNT_STATE_REGISTERED );
	            c -> accountID = current -> accountID;
	            dbus_place_call(c);
	            notify_current_account( current );
	            status_bar_display_account(c);
	            account_list_set_current_id( c-> accountID );
            }
        }
	    // Update history
	    c->history_state = OUTGOING;
	    call_list_add(history, c);
Emmanuel Milou's avatar
Emmanuel Milou committed
717
    }
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
718
719
}

alexandresavard's avatar
alexandresavard committed
720
721
722
723

void
sflphone_rec_call()
{
alexandresavard's avatar
alexandresavard committed
724
725
  call_t * selectedCall = call_get_selected(current_calls);
  dbus_set_record(selectedCall);
726
727
728
729
730
731
732
733
734
735
736
  

  switch(selectedCall->state)
  {
      case CALL_STATE_CURRENT:
            selectedCall->state = CALL_STATE_RECORD;
            break; 
      case CALL_STATE_RECORD:
            selectedCall->state = CALL_STATE_CURRENT;
            break;
      default: 
737
            g_warning("Should not happen in sflphone_off_hold ()!");
738
739
        break;
  }
740
741
  update_call_tree(current_calls,selectedCall);
  update_menus();
alexandresavard's avatar
alexandresavard committed
742
743
}

Emmanuel Milou's avatar
Emmanuel Milou committed
744
/* Internal to action - set the __CURRENT_ACCOUNT variable */
areversat's avatar
areversat committed
745
void
Emmanuel Milou's avatar
Emmanuel Milou committed
746
sflphone_set_current_account()
Emmanuel Milou's avatar
Emmanuel Milou committed
747
{
Emmanuel Milou's avatar
Emmanuel Milou committed
748
  if( account_list_get_size() > 0 )
Emmanuel Milou's avatar
Emmanuel Milou committed
749
    account_list_set_current_pos( 0 );	
750
751
}

752
753

/* Internal to action - get the codec list */
754
755
void	
sflphone_fill_codec_list()
756
{
757
758
759

  codec_list_clear();
    
760
  gchar** codecs = (gchar**)dbus_codec_list();
761
  gchar** order = (gchar**)dbus_get_active_codec_list();
762
763
  gchar** details;
  gchar** pl;
Emmanuel Milou's avatar
nothing    
Emmanuel Milou committed
764

765
  for(pl=order; *order; order++)
766
767
  {
    codec_t * c = g_new0(codec_t, 1);
768
    c->_payload = atoi(*order);
769
    details = (gchar **)dbus_codec_details(c->_payload);
770
    //printf("Codec details: %s / %s / %s / %s\n",details[0],details[1],details[2],details[3]);
771
    c->name = details[0];
772
    c->is_active = TRUE;
773
    c->sample_rate = atoi(details[1]);
Emmanuel Milou's avatar
Emmanuel Milou committed
774
775
776
    c->_bitrate = atof(details[2]);
    c->_bandwidth = atof(details[3]);
    codec_list_add(c);
777
  }
778

779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
  for(pl=codecs; *codecs; codecs++)
  {
    details = (gchar **)dbus_codec_details(atoi(*codecs));
    if(codec_list_get(details[0])!=NULL){
      // does nothing - the codec is already in the list, so is active.
    }
    else{
      codec_t* c = g_new0(codec_t, 1);
      c->_payload = atoi(*codecs);
      c->name = details[0];
      c->is_active = FALSE;
      c->sample_rate = atoi(details[1]);
      c->_bitrate = atof(details[2]);
      c->_bandwidth = atof(details[3]);
      codec_list_add(c);
    }
  }
796
  if( codec_list_get_size() == 0) {
797
798
799
    
    gchar* markup = g_markup_printf_escaped(_("<b>Error: No audio codecs found.\n\n</b> SFL audio codecs have to be placed in <i>%s</i> or in the <b>.sflphone</b> directory in your home( <i>%s</i> )") , CODECS_DIR , g_get_home_dir());
    main_window_error_message( markup );
800
801
802
    dbus_unregister(getpid());
    exit(0);
  }
803
}