actions.c 20.7 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>
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.
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.
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 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>
29
#include <contactlist/eds.h>
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
30

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

38 39
guint voice_mails;

areversat's avatar
areversat committed
40
void
41
sflphone_notify_voice_mail ( const gchar* accountID , guint count )
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
42
{
43 44
    gchar *id;
    gchar *current;
45

46 47 48 49 50 51 52 53 54 55 56 57 58 59
    // 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
60
            g_sprintf(message, _("%d voice mail"), count);
61 62 63
        statusbar_push_message(message,  __MSG_VOICE_MAILS);
        g_free(message);
    }
64

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

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

89

areversat's avatar
areversat committed
90
gboolean
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
91 92
sflphone_quit ()
{
93
	gboolean quit = FALSE;
areversat's avatar
areversat committed
94
	guint count = call_list_get_size(current_calls);
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
	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
111 112
}

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

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

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

  statusbar_pop_message(__MSG_ACCOUNT_DEFAULT);
Emmanuel Milou's avatar
Emmanuel Milou committed
141 142
}

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

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

152 153
	account_list_clear ( );

154 155 156 157 158 159 160 161 162 163 164
	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);
    }
165 166 167 168 169

	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);
170 171
        if( details == NULL )
            break;
172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190
		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;
		}
191 192 193 194
		else if(strcmp( status , "ERROR_AUTH") == 0 )
		{
		  a->state = ACCOUNT_STATE_ERROR_AUTH;
		}
195 196 197 198
		else if(strcmp( status , "ERROR_NETWORK") == 0 )
		{
		  a->state = ACCOUNT_STATE_ERROR_NETWORK;
		}
199 200 201 202
		else if(strcmp( status , "ERROR_HOST") == 0 )
		{
		  a->state = ACCOUNT_STATE_ERROR_HOST;
		}
Yun Liu's avatar
Yun Liu committed
203 204 205 206 207 208 209
		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;
210
		}
211 212 213 214 215 216 217
		else
		{
			a->state = ACCOUNT_STATE_INVALID;
		}

	}

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

223
gboolean sflphone_init()
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
224
{
225
	if(!dbus_connect ()){
226

227
		main_window_error_message(_("Unable to connect to the SFLphone server.\nMake sure the daemon is running."));
228 229
		return FALSE;
	}
230
	else
231 232
	{
		dbus_register(getpid(), "Gtk+ Client");
233 234 235
        current_calls = calltab_init();
	    history = calltab_init();
	    contacts = calltab_init();
236
	  if(SHOW_SEARCHBAR)  histfilter = create_filter(GTK_TREE_MODEL(history->store));
237
	  init();
238 239
	  account_list_init ();
    codec_list_init();
240
		sflphone_fill_account_list(FALSE);
241
		sflphone_fill_codec_list();
242
		sflphone_set_current_account();
243 244
		return TRUE;
	}
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
245 246
}

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


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

333
void
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
334 335
sflphone_on_hold ()
{
areversat's avatar
areversat committed
336
	call_t * selectedCall = call_get_selected(current_calls);
337 338 339 340 341 342 343
	if(selectedCall)
	{
		switch(selectedCall->state)
		{
			case CALL_STATE_CURRENT:
				dbus_hold (selectedCall);
				break;
344 345 346
                        case CALL_STATE_RECORD:
                                dbus_hold (selectedCall);
                                break;
347

348 349 350 351 352
			default:
				g_warning("Should not happen in sflphone_on_hold!");
				break;
		}
	}
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
353 354
}

355
void
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
356 357
sflphone_off_hold ()
{
areversat's avatar
areversat committed
358
	call_t * selectedCall = call_get_selected(current_calls);
359 360 361 362 363 364 365 366 367 368 369 370
	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
371 372 373
}


374
void
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
375 376
sflphone_fail( call_t * c )
{
377
	c->state = CALL_STATE_FAILURE;
areversat's avatar
areversat committed
378
	update_call_tree(current_calls,c);
379
	update_menus();
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
380 381
}

382
void
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
383 384
sflphone_busy( call_t * c )
{
385
	c->state = CALL_STATE_BUSY;
areversat's avatar
areversat committed
386
	update_call_tree(current_calls, c);
387
	update_menus();
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
388 389
}

390
void
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
391 392
sflphone_current( call_t * c )
{
393
  if( c->state != CALL_STATE_HOLD )
Emmanuel Milou's avatar
Emmanuel Milou committed
394
	(void) time(&c->_start);
395 396 397
  c->state = CALL_STATE_CURRENT;
  update_call_tree(current_calls,c);
  update_menus();
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
398 399
}

alexandresavard's avatar
alexandresavard committed
400 401 402 403 404 405 406 407 408 409
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();
}

410
void
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
411
sflphone_set_transfert()
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
412
{
areversat's avatar
areversat committed
413
	call_t * c = call_get_selected(current_calls);
414 415 416 417
	if(c)
	{
		c->state = CALL_STATE_TRANSFERT;
		c->to = g_strdup("");
areversat's avatar
areversat committed
418
		update_call_tree(current_calls,c);
419 420 421
		update_menus();
	}
	toolbar_update_buttons();
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
422 423
}

424
void
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
425 426
sflphone_unset_transfert()
{
areversat's avatar
areversat committed
427
	call_t * c = call_get_selected(current_calls);
428 429 430 431
	if(c)
	{
		c->state = CALL_STATE_CURRENT;
		c->to = g_strdup("");
areversat's avatar
areversat committed
432
		update_call_tree(current_calls,c);
433 434 435
		update_menus();
	}
	toolbar_update_buttons();
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
436
}
Emmanuel Milou's avatar
Emmanuel Milou committed
437

areversat's avatar
areversat committed
438
void
439
sflphone_incoming_call (call_t * c)
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
440
{
441
	c->history_state = MISSED;
442 443 444
	call_list_add ( current_calls, c );
	call_list_add( history, c );
	update_call_tree_add( current_calls , c );
445
	update_menus();
446
	switch_tab(current_calls);
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
447
}
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
448

areversat's avatar
areversat committed
449 450
void
process_dialing(call_t * c, guint keyval, gchar * key)
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
451
{
452
	// We stop the tone
Emmanuel Milou's avatar
Emmanuel Milou committed
453
	if(strlen(c->to) == 0 && c->state != CALL_STATE_TRANSFERT){
454
	  dbus_start_tone( FALSE , 0 );
Emmanuel Milou's avatar
Emmanuel Milou committed
455
	  //dbus_play_dtmf( key );
456
	}
457 458 459 460

        g_print("process_dialing : keyval : %i \n",keyval);
        g_print("process_dialing : key : %s \n",key);

461 462 463 464 465 466 467
	switch (keyval)
	{
		case 65293: /* ENTER */
		case 65421: /* ENTER numpad */
			sflphone_place_call(c);
			break;
		case 65307: /* ESCAPE */
Emmanuel Milou's avatar
Emmanuel Milou committed
468
			sflphone_hang_up(c);
469 470 471 472
			break;
		case 65288: /* BACKSPACE */
			{  /* Brackets mandatory because of local vars */
				gchar * before = c->to;
473
				if(strlen(c->to) >= 1){
474

475 476
					c->to = g_strndup(c->to, strlen(c->to) -1);
					g_free(before);
477
					g_print("TO: backspace %s\n", c->to);
478 479 480 481 482 483

					if(c->state == CALL_STATE_DIALING)
					{
						g_free(c->from);
						c->from = g_strconcat("\"\" <", c->to, ">", NULL);
					}
areversat's avatar
areversat committed
484
					update_call_tree(current_calls,c);
485
				}
486
				else if(strlen(c->to) == 0)
487
				{
488
				  if(c->state != CALL_STATE_TRANSFERT)
489 490 491 492 493 494 495 496 497 498 499
					dbus_hang_up(c);
				}
			}
			break;
		case 65289: /* TAB */
		case 65513: /* ALT */
		case 65507: /* CTRL */
		case 65515: /* SUPER */
		case 65509: /* CAPS */
			break;
		default:
500 501
                  // if (keyval < 255 || (keyval >65453 && keyval < 65466))
                        if (keyval < 127)
502 503
			{

504
                                if(c->state != CALL_STATE_TRANSFERT)
Emmanuel Milou's avatar
Emmanuel Milou committed
505
				  dbus_play_dtmf( key );
506 507 508
				  gchar * before = c->to;
				  c->to = g_strconcat(c->to, key, NULL);
				  g_free(before);
509
				  g_print("TO:default %s\n", c->to);
510 511 512 513 514 515

				if(c->state == CALL_STATE_DIALING)
				{
					g_free(c->from);
					c->from = g_strconcat("\"\" <", c->to, ">", NULL);
				}
areversat's avatar
areversat committed
516
				update_call_tree(current_calls,c);
517 518 519 520
			}
			break;
	}

521 522
}

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

524
call_t *
areversat's avatar
areversat committed
525
sflphone_new_call()
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
526
{
527 528 529

        sflphone_on_hold();

Emmanuel Milou's avatar
Emmanuel Milou committed
530
	// Play a tone when creating a new call
areversat's avatar
areversat committed
531
	if( call_list_get_size(current_calls) == 0 )
532
	  dbus_start_tone( TRUE , ( voice_mails > 0 )? TONE_WITH_MESSAGE : TONE_WITHOUT_MESSAGE) ;
Emmanuel Milou's avatar
Emmanuel Milou committed
533

534 535 536 537 538
	call_t * c = g_new0 (call_t, 1);
	c->state = CALL_STATE_DIALING;
	c->from = g_strconcat("\"\" <>", NULL);

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

	c->to = g_strdup("");

Emmanuel Milou's avatar
Emmanuel Milou committed
543 544 545
	c->_start = 0;
	c->_stop = 0;

areversat's avatar
areversat committed
546
	call_list_add(current_calls,c);
547
	update_call_tree_add(current_calls,c);
548 549 550
	update_menus();

	return c;
551 552
}

areversat's avatar
areversat committed
553

554
void
areversat's avatar
areversat committed
555 556
sflphone_keypad( guint keyval, gchar * key)
{
areversat's avatar
areversat committed
557
	call_t * c = call_get_selected(current_calls);
558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575

	if((active_calltree != current_calls) || (active_calltree == current_calls && !c))
  {
    // Not in a call, not dialing, create a new call
    //dbus_play_dtmf(key);
    switch (keyval)
    {
      case 65293: /* ENTER */
      case 65421: /* ENTER numpad */
      case 65307: /* ESCAPE */
        break;
      default:
        switch_tab(current_calls);
        process_dialing(sflphone_new_call(), keyval, key);
        break;
    }
  }
  else if(c)
576
	{
577
	  printf("call\n");
578
		switch(c->state)
579 580 581 582
		{
			case CALL_STATE_DIALING: // Currently dialing => edit number
				process_dialing(c, keyval, key);
				break;
583
                case CALL_STATE_RECORD:
584 585 586 587
			case CALL_STATE_CURRENT:
				switch (keyval)
				{
					case 65307: /* ESCAPE */
588
						dbus_hang_up(c);
Emmanuel Milou's avatar
Emmanuel Milou committed
589 590
						(void) time(&c->_stop);
						update_call_tree( history , c );
591
						break;
592
					default:
Emmanuel Milou's avatar
Emmanuel Milou committed
593
						// To play the dtmf when calling mail box for instance
594 595
						dbus_play_dtmf(key);
						if (keyval < 255 || (keyval >65453 && keyval < 65466))
596
						{
597 598 599 600 601
							//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
602
							//update_call_tree(current_calls,c);
603 604 605 606 607 608 609 610 611
						}
						break;
				}
				break;
			case CALL_STATE_INCOMING:
				switch (keyval)
				{
					case 65293: /* ENTER */
					case 65421: /* ENTER numpad */
612 613
						c->history_state = INCOMING;
						update_call_tree( history , c );
614
						dbus_accept(c);
615
						g_print("from sflphone_keypad ( enter ) : "); stop_notification();
616 617 618
						break;
					case 65307: /* ESCAPE */
						dbus_refuse(c);
619
						g_print("from sflphone_keypad ( escape ) : "); stop_notification();
620 621 622 623 624 625 626 627 628
						break;
				}
				break;
			case CALL_STATE_TRANSFERT:
				switch (keyval)
				{
					case 65293: /* ENTER */
					case 65421: /* ENTER numpad */
						dbus_transfert(c);
629
						(void) time(&c->_stop);
630 631
						break;
					case 65307: /* ESCAPE */
632
						sflphone_unset_transfert(c);
633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656
						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:
657
				c->_stop = 0;
658 659 660
				switch (keyval)
				{
					case 65307: /* ESCAPE */
Emmanuel Milou's avatar
Emmanuel Milou committed
661 662 663 664
					  dbus_hang_up(c);
					  c->_stop = 0;
					  update_call_tree( history , c );
					  break;
665 666 667 668
				}
				break;
			default:
				break;
669
		}
670
	}
671
 }
672 673

/*
674
 * Place a call with the current account.
675
 * If there is no default account selected, place a call with the first
676 677 678
 * registered account of the account list
 * Else, popup an error message
 */
679
void
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
680 681
sflphone_place_call ( call_t * c )
{
682 683

    if(c->state == CALL_STATE_DIALING && strcmp(c->to, "") != 0)
Emmanuel Milou's avatar
Emmanuel Milou committed
684
    {
685 686 687 688 689
        if( account_list_get_size() == 0 )
        {
            notify_no_accounts();
            sflphone_fail(c);
        }
690

691 692 693 694 695
        else if( account_list_get_by_state( ACCOUNT_STATE_REGISTERED ) == NULL )
        {
            notify_no_registered_accounts();
            sflphone_fail(c);
        }
696

697 698
        else
        {
699 700 701 702 703 704 705 706 707 708 709
            account_t * current;

            if(c->accountID != 0)
                current = account_list_get_by_id(c->accountID);
            else
                current = account_list_get_current();

            // printf("sflphone_place_call :: c->accountID : %i \n",c->accountID);

            // account_t * current = c->accountID;

710 711 712
            if( current )
            {
	            if(g_strcasecmp(g_hash_table_lookup( current->properties, "Status"),"REGISTERED")==0)
713
	            {
714 715 716 717 718 719 720
	                // 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
	            {
721
	                // Current account is not registered
722 723 724 725 726 727 728 729 730 731 732 733
	                // 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
            {
734
	            // No current accounts have been setup.
735 736 737 738 739 740 741 742 743 744 745 746
	            // 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;
747
	    c->from;
748
	    call_list_add(history, c);
Emmanuel Milou's avatar
Emmanuel Milou committed
749
    }
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
750 751
}

alexandresavard's avatar
alexandresavard committed
752

753
void
Alexandre Savard's avatar
Alexandre Savard committed
754 755 756 757 758 759 760
sflphone_display_selected_codec (const gchar* codecName)
{
    call_t * selectedCall = call_get_selected(current_calls);
    gchar* msg;
    account_t* acc;
    if(selectedCall->accountID != NULL){
      acc = account_list_get_by_id(selectedCall->accountID);
761 762
      msg = g_markup_printf_escaped(_("%s account- %s             %s") ,
		 (gchar*)g_hash_table_lookup( acc->properties , ACCOUNT_TYPE),
Alexandre Savard's avatar
Alexandre Savard committed
763 764 765 766 767 768 769 770 771 772 773 774 775 776 777
                 (gchar*)g_hash_table_lookup( acc->properties , ACCOUNT_ALIAS),
                 codecName);
      statusbar_push_message( msg , __MSG_ACCOUNT_DEFAULT);
      g_free(msg);
  }

}

gchar*
sflphone_get_current_codec_name()
{
    call_t * selectedCall = call_get_selected(current_calls);
    return dbus_get_current_codec_name(selectedCall);
}

alexandresavard's avatar
alexandresavard committed
778 779 780
void
sflphone_rec_call()
{
alexandresavard's avatar
alexandresavard committed
781 782
  call_t * selectedCall = call_get_selected(current_calls);
  dbus_set_record(selectedCall);
783

784 785 786 787 788

  switch(selectedCall->state)
  {
      case CALL_STATE_CURRENT:
            selectedCall->state = CALL_STATE_RECORD;
789
            break;
790 791 792
      case CALL_STATE_RECORD:
            selectedCall->state = CALL_STATE_CURRENT;
            break;
793
      default:
794
            g_warning("Should not happen in sflphone_off_hold ()!");
795 796
        break;
  }
797 798
  update_call_tree(current_calls,selectedCall);
  update_menus();
Alexandre Savard's avatar
Alexandre Savard committed
799 800 801

  // gchar* codname = sflphone_get_current_codec_name();
  // printf("sflphone_get_current_codec_name: %s \n",codname);
alexandresavard's avatar
alexandresavard committed
802 803
}

Emmanuel Milou's avatar
Emmanuel Milou committed
804
/* Internal to action - set the __CURRENT_ACCOUNT variable */
areversat's avatar
areversat committed
805
void
Emmanuel Milou's avatar
Emmanuel Milou committed
806
sflphone_set_current_account()
Emmanuel Milou's avatar
Emmanuel Milou committed
807
{
Emmanuel Milou's avatar
Emmanuel Milou committed
808
  if( account_list_get_size() > 0 )
809
    account_list_set_current_pos( 0 );
810 811
}

812 813

/* Internal to action - get the codec list */
814
void
815
sflphone_fill_codec_list()
816
{
817 818

  codec_list_clear();
819

820
  gchar** codecs = (gchar**)dbus_codec_list();
821
  gchar** order = (gchar**)dbus_get_active_codec_list();
822 823
  gchar** details;
  gchar** pl;
Emmanuel Milou's avatar
nothing  
Emmanuel Milou committed
824

825
  for(pl=order; *order; order++)
826 827
  {
    codec_t * c = g_new0(codec_t, 1);
828
    c->_payload = atoi(*order);
829
    details = (gchar **)dbus_codec_details(c->_payload);
830
    //printf("Codec details: %s / %s / %s / %s\n",details[0],details[1],details[2],details[3]);
831
    c->name = details[0];
832
    c->is_active = TRUE;
833
    c->sample_rate = atoi(details[1]);
Emmanuel Milou's avatar
Emmanuel Milou committed
834 835 836
    c->_bitrate = atof(details[2]);
    c->_bandwidth = atof(details[3]);
    codec_list_add(c);
837
  }
838

839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855
  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);
    }
  }
856
  if( codec_list_get_size() == 0) {
857

858 859
    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 );
860 861 862
    dbus_unregister(getpid());
    exit(0);
  }
863
}
Alexandre Savard's avatar
Alexandre Savard committed
864