actions.c 11.6 KB
Newer Older
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
1
2
/*
 *  Copyright (C) 2007 Savoir-Faire Linux inc.
3
 *  Author: Pierre-Luc Beaudoin <pierre-luc@squidy.info>
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 *                                                                              
 *  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
 *  the Free Software Foundation; either version 2 of the License, or
 *  (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.
 */
19

20
#include <accountlist.h>
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
27
#include <screen.h>
#include <statusicon.h>
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
28

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

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

Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
void
sflphone_notify_voice_mail (guint count)
{
  if(count > 0)
  {
    gchar * message = g_new0(gchar, 50);
    g_sprintf(message, "%d new voice mail%s", count, (count > 1? "s" : "")); 
    status_bar_message(message);
    g_free(message);
  }
  else
  {
    status_bar_message("");
  }
}

Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
53
54
55
56
57
58
59
60
61
62
63
64
65
66
gboolean
sflphone_quit ()
{
  gboolean quit = FALSE;
  guint count = call_list_get_size();
  if(count > 0){
    quit = main_window_ask_quit();
  }
  else{
    quit = TRUE;
  }
  
  if (quit)
  {
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
67
    dbus_unregister(getpid());
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
68
69
    dbus_clean ();
    //call_list_clean(); TODO
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
70
    //account_list_clean()
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
71
72
73
74
75
76
77
78
79
    gtk_main_quit ();
  }
  return quit;
}

void 
sflphone_hold(call_t * c )
{
  c->state = CALL_STATE_HOLD;
80
  update_call_tree(c);
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
81
  update_menus();
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
82
83
84
  screen_clear();
}

85
86
87
88
89
void 
sflphone_ringing(call_t * c )
{
  c->state = CALL_STATE_RINGING;
  update_call_tree(c);
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
90
  update_menus();
91
}
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
92

Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
93
/** Internal to actions: Fill account list */
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
94
95
96
void
sflphone_fill_account_list()
{
97
98
  account_list_clear ( );
  
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
  gchar ** array = (gchar **)dbus_account_list();
  gchar ** accountID;
  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);
  
  int i;
  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);
    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;
    }
125
126
127
128
    else if(strcmp(status, "TRYING") == 0)
    {
      a->state = ACCOUNT_STATE_TRYING;
    }
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
129
130
131
132
    else if(strcmp(status, "ERROR") == 0)
    {
      a->state = ACCOUNT_STATE_ERROR;
    }
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
133
134
135
136
137
138
139
    else
    {
      a->state = ACCOUNT_STATE_INVALID;
    }
    
  }
  
140
	toolbar_update_buttons();
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
141
142
143
144
145
146
147
148
149
}

gboolean
sflphone_init()
{
  call_list_init ();
  account_list_init ();
  if(!dbus_connect ())
  {
150
    main_window_error_message("Unable to connect to the SFLphone server.\nMake sure the daemon is running.");
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
151
152
153
154
    return FALSE;
  }
  else 
  {
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
155
    dbus_register(getpid(), "Gtk+ Client");
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
156
    sflphone_fill_account_list();
Emmanuel Milou's avatar
Emmanuel Milou committed
157
    sflphone_set_default_account();
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
158
159
160
161
162
    return TRUE;
  }
}

void 
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
163
sflphone_hang_up()
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
164
{
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
  call_t * selectedCall = call_get_selected();
  if(selectedCall)
  {
    switch(selectedCall->state)
    {
      case CALL_STATE_CURRENT:
      case CALL_STATE_HOLD:
      case CALL_STATE_DIALING:
      case CALL_STATE_RINGING:
      case CALL_STATE_BUSY:
      case CALL_STATE_FAILURE:
        dbus_hang_up (selectedCall);
        break;
      case CALL_STATE_INCOMING:  
        dbus_refuse (selectedCall);
        break;
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
181
182
183
      case CALL_STATE_TRANSFERT:  
        dbus_hang_up (selectedCall);
        break;
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
184
      default:
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
185
        g_warning("Should not happen in sflphone_hang_up()!");
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
        break;
    }
  }
}


void 
sflphone_pick_up()
{
  call_t * selectedCall = call_get_selected();
  if(selectedCall)
  {
    switch(selectedCall->state)
    {
      case CALL_STATE_DIALING:
        sflphone_place_call (selectedCall);
        break;
      case CALL_STATE_INCOMING:
        dbus_accept (selectedCall);
        break;
      case CALL_STATE_HOLD:
        dbus_unhold (selectedCall);
        break;
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
209
210
211
      case CALL_STATE_TRANSFERT:
        dbus_transfert (selectedCall);
        break;
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
212
      default:
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
213
        g_warning("Should not happen in sflphone_pick_up()!");
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
214
215
216
        break;
    }
  }
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
217
218
}

Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
219
220
221
222
223
224
225
226
227
228
229
230
void 
sflphone_on_hold ()
{
  call_t * selectedCall = call_get_selected();
  if(selectedCall)
  {
    switch(selectedCall->state)
    {
      case CALL_STATE_CURRENT:
        dbus_hold (selectedCall);
        break;
      default:
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
231
        g_warning("Should not happen in sflphone_on_hold!");
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
        break;
    }
  }
}

void 
sflphone_off_hold ()
{
  call_t * selectedCall = call_get_selected();
  if(selectedCall)
  {
    switch(selectedCall->state)
    {
      case CALL_STATE_HOLD:
        dbus_unhold (selectedCall);
        break;
      default:
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
249
        g_warning("Should not happen in sflphone_off_hold ()!");
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
250
251
252
253
254
255
        break;
      }
  }
}


Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
256
257
258
259
260
void 
sflphone_fail( call_t * c )
{
  c->state = CALL_STATE_FAILURE;
  update_call_tree(c);
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
261
  update_menus();
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
262
263
264
265
266
267
268
269
  screen_set_call(c);
}

void 
sflphone_busy( call_t * c )
{
  c->state = CALL_STATE_BUSY;
  update_call_tree(c);
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
270
  update_menus();
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
271
272
273
  screen_set_call(c);
}

Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
274
275
276
277
void 
sflphone_current( call_t * c )
{
  c->state = CALL_STATE_CURRENT;
278
  update_call_tree(c);
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
279
  update_menus();
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
280
281
282
283
  screen_set_call(c);
}

void 
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
284
sflphone_set_transfert()
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
285
{
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
286
287
288
289
290
291
292
293
294
  call_t * c = call_get_selected();
  if(c)
  {
    c->state = CALL_STATE_TRANSFERT;
    c->to = g_strdup("");
    screen_set_call(c);
    update_call_tree(c);
    update_menus();
  }
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
295
  toolbar_update_buttons();
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
296
297
}

Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
298
299
300
301
302
303
304
305
306
307
308
309
310
311
void 
sflphone_unset_transfert()
{
  call_t * c = call_get_selected();
  if(c)
  {
    c->state = CALL_STATE_CURRENT;
    c->to = g_strdup("");
    screen_set_call(c);
    update_call_tree(c);
    update_menus();
  }
  toolbar_update_buttons();
}
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
312
313
314
315
void
sflphone_incoming_call (call_t * c) 
{
  call_list_add ( c );
316
  status_icon_unminimize();
317
  update_call_tree_add(c);
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
318
  update_menus();
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
319
}
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
320

Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
321
322
323
324
void 
sflphone_hung_up (call_t * c )
{
  call_list_remove(c->callID);
325
  update_call_tree_remove(c);
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
326
  update_menus();
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
327
328
329
  screen_clear();
}

330
void process_dialing(call_t * c, guint keyval, gchar * key)
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
331
{
332
  switch (keyval)
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
333
  {
334
335
336
337
338
339
340
341
342
343
344
345
  case 65293: /* ENTER */
  case 65421: /* ENTER numpad */
    sflphone_place_call(c);
    break;
  case 65307: /* ESCAPE */
    dbus_hang_up(c);
    break;
  case 65288: /* BACKSPACE */
    {  /* Brackets mandatory because of local vars */
      gchar * before = c->to;
      if(strlen(c->to) > 1){
        c->to = g_strndup(c->to, strlen(c->to) -1);
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
346
347
        g_free(before);
        g_print("TO: %s\n", c->to);
348
      
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
349
350
351
352
353
        if(c->state == CALL_STATE_DIALING)
        {
          g_free(c->from);
          c->from = g_strconcat("\"\" <", c->to, ">", NULL);
        }
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
354
        screen_set_call(c);
355
        update_call_tree(c);
356
357
358
359
      } 
      else if(strlen(c->to) == 1)
      {
        dbus_hang_up(c);
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
360
361
      }
    }
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
    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))
    { 
      gchar * before = c->to;
      c->to = g_strconcat(c->to, key, NULL);
      g_free(before);
      g_print("TO: %s\n", c->to);
      
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
377
378
379
380
381
      if(c->state == CALL_STATE_DIALING)
      {
        g_free(c->from);
        c->from = g_strconcat("\"\" <", c->to, ">", NULL);
      }
382
383
384
385
      screen_set_call(c);
      update_call_tree(c);
    }
    break;
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
386
  }
387
388
389
  
}

Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407

call_t * sflphone_new_call()
{
  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("");
  
  call_list_add(c);
  screen_set_call(c);
  update_call_tree_add(c);  
  update_menus();
  
  return c;
408
409
410
411
412
413
414
}

void 
sflphone_keypad( guint keyval, gchar * key)
{
  call_t * c = call_get_selected();
  if(c)
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
415
  {
416
  
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
417
    switch(c->state) 
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
418
    {
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
419
      case CALL_STATE_DIALING: // Currently dialing => edit number
420
        process_dialing(c, keyval, key);
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
421
        break;
422
      case CALL_STATE_CURRENT:
423
424
425
426
427
        switch (keyval)
        {
        case 65307: /* ESCAPE */
          dbus_hang_up(c);
          break;
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
428
        default:  // TODO should this be here?
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
429
          dbus_play_dtmf(key);
430
431
432
433
434
435
436
437
438
439
440
          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);
            screen_set_call(c);
            update_call_tree(c);
          }
          break;
441
        }
442
443
444
445
446
447
448
449
450
451
452
        break;
      case CALL_STATE_INCOMING:
        switch (keyval)
        {
        case 65293: /* ENTER */
        case 65421: /* ENTER numpad */
          dbus_accept(c);
          break;
        case 65307: /* ESCAPE */
          dbus_refuse(c);
          break;
453
        }
454
        break;
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
455
456
457
458
459
460
461
462
      case CALL_STATE_TRANSFERT:
        switch (keyval)
        {
        case 65293: /* ENTER */
        case 65421: /* ENTER numpad */
          dbus_transfert(c);
          break;
        case 65307: /* ESCAPE */
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
463
          sflphone_hang_up(c); 
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
464
465
466
467
468
469
          break;
        default: // When a call is on transfert, typing new numbers will add it to c->to
          process_dialing(c, keyval, key);
          break;
        }
        break;
470
471
472
473
474
475
476
477
478
479
480
      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
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
481
          process_dialing(sflphone_new_call(), keyval, key);
482
483
484
          break;
        }
        break;
485
      case CALL_STATE_RINGING:
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
486
487
      case CALL_STATE_BUSY:
      case CALL_STATE_FAILURE:
488
489
490
491
492
493
494
        switch (keyval)
        {
        case 65307: /* ESCAPE */
          dbus_hang_up(c);
          break;
        }
        break;
495
496
497
498
499
500
      default:
        break;
     } 
  }
  else 
  { // Not in a call, not dialing, create a new call 
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
501
502
503
504
505
506
507
508
509
510
511
512
    switch (keyval)
    {
    case 65293: /* ENTER */
    case 65421: /* ENTER numpad */
    case 65307: /* ESCAPE */
      break;
    default:
      process_dialing(sflphone_new_call(), keyval, key);
      break;
    }
        
     
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
513
514
515
  }
} 

516

Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
void 
sflphone_place_call ( call_t * c )
{
  if(c->state == CALL_STATE_DIALING)
  {
    account_t * a = account_list_get_by_state (ACCOUNT_STATE_REGISTERED);
    if(a)
    {
      c->accountID = a->accountID;
      dbus_place_call(c);
    }
    else
    {
      main_window_error_message("There are no registered accounts to make this call with.");
    }
    
  }
}

Emmanuel Milou's avatar
Emmanuel Milou committed
536
537
538
539
540
541
542
543
/* Internal to action - set the DEFAULT_ACCOUNT variable */
void
sflphone_set_default_account( )
{
	gchar* default_id = strdup(dbus_get_default_account());
	g_print("Default Account = %s\n", default_id);
	account_list_set_default(default_id);	
}
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
544