aboutsummaryrefslogtreecommitdiff
path: root/src/conversation/gnunet-conversation-gtk.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/conversation/gnunet-conversation-gtk.c')
-rw-r--r--src/conversation/gnunet-conversation-gtk.c1480
1 files changed, 1480 insertions, 0 deletions
diff --git a/src/conversation/gnunet-conversation-gtk.c b/src/conversation/gnunet-conversation-gtk.c
new file mode 100644
index 00000000..1ded8a4c
--- /dev/null
+++ b/src/conversation/gnunet-conversation-gtk.c
@@ -0,0 +1,1480 @@
1/*
2 This file is part of GNUnet.
3 (C) 2010-2013 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21/**
22 * @file src/conversation/gnunet-conversation-gtk.c
23 * @brief Main function of gnunet-conversation-gtk
24 * @author hark and yids
25 */
26#include "gnunet_gtk.h"
27#include "gtk/gtk.h"
28#include "gnunet-conversation-gtk.h"
29#include "gnunet/gnunet_gnsrecord_lib.h"
30#include "gnunet/gnunet_conversation_service.h"
31#include "gnunet/gnunet_identity_service.h"
32#include "gnunet/gnunet_namestore_service.h"
33#include "gnunet/gnunet_speaker_lib.h"
34#include "gnunet/gnunet_microphone_lib.h"
35#include "gnunet/gnunet_namestore_service.h"
36#include "gnunet/gnunet_gnsrecord_lib.h"
37#include <time.h>
38
39
40
41/*
42 * macro's
43 */
44
45#define UPDATE_STATUS(format, ...) update_status(g_strdup_printf (format, ## __VA_ARGS__))
46
47#define UPDATE_INFOBAR(format, ...) set_infobar_text(g_strdup_printf (format, ## __VA_ARGS__))
48
49#define LOG(format, ...) log_message(g_strdup_printf (format, ## __VA_ARGS__))
50
51/**
52 * Get an object from the main window.
53 *
54 * @param name name of the object
55 * @return NULL on error
56 */
57static GObject *
58get_object (const char *name)
59{
60 return GNUNET_GTK_main_loop_get_object (ml, name);
61}
62
63/*
64 * log a message to gtk thing
65 */
66
67void
68log_message (const char *message)
69{
70 //
71 // log
72 //
73 GtkTextBuffer *logbuff;
74 GtkTextView *log_view;
75 GtkTextIter iter;
76 gchar *fmsg;
77
78// update_status(message);
79 //UPDATE_STATUS("status update testje: %s", message);
80 //FPRINTF(stderr,"now logging: %s",message);
81
82 log_view = get_object ("GNUNET_GTK_conversation_log");
83
84 logbuff = gtk_text_view_get_buffer (log_view);
85
86 fmsg = g_strdup_printf (" %s \n", message);
87
88 gtk_text_buffer_get_start_iter (logbuff, &iter);
89
90 gtk_text_buffer_insert (logbuff, &iter, fmsg, -1);
91 g_free (fmsg);
92
93
94}
95
96void
97update_state ()
98{
99// LOG('update_state called',NULL);
100}
101
102void
103update_status (const gchar * message)
104{
105
106 GtkStatusbar *status_bar;
107 guint status_bar_context;
108
109 //static int count = 1;
110 gchar *buff;
111
112 status_bar = get_object ("GNUNET_GTK_conversation_statusbar");
113 status_bar_context = gtk_statusbar_get_context_id (status_bar, "blaat");
114
115
116 buff = g_strdup_printf ("%s", message);
117
118 gtk_statusbar_push (GTK_STATUSBAR (status_bar),
119 GPOINTER_TO_INT (status_bar_context), buff);
120 g_free (buff);
121
122
123}
124
125/*
126* adds a item to the call history
127 types:
128 1: accepted
129 2: rejected
130*/
131
132void
133history_add (int type, char *contactName)
134{
135 GtkTreeIter iter;
136 time_t t;
137
138 time (&t);
139 gtk_list_store_append (history_liststore, &iter);
140 gtk_list_store_set (history_liststore, &iter, 1, type, 0, ctime (&t), 2,
141 contactName, -1);
142}
143
144void
145set_button_text (const char *button_name, const char *label)
146{
147 //GtkButton *button;
148 GtkWidget *button;
149
150 button = get_object (button_name);
151 gtk_widget_hide (button);
152}
153
154void
155set_infobar_text (const gchar * text)
156{
157 GtkLabel *infolabel;
158
159 infolabel = get_object ("GNUNET_GTK_new_call_label");
160 log_message ("setting infobar text");
161 gtk_label_set_text (infolabel, text);
162}
163
164
165
166void
167disable_button (const char *button_name)
168{
169 //GtkButton *button;
170 GtkWidget *button;
171
172 button = get_object (button_name);
173 gtk_widget_hide (button);
174}
175
176void
177enable_button (const char *button_name)
178{
179 //GtkButton *button;
180 GtkWidget *button;
181
182 button = get_object (button_name);
183 gtk_widget_show (button);
184}
185
186void
187show_infobar ()
188{
189// GtkInfoBar *infobar;
190 GtkWidget *infobar;
191
192 infobar = get_object ("GNUNET_GTK_conversation_infobar");
193
194 gtk_widget_show (infobar);
195}
196
197void
198hide_infobar ()
199{
200 //GtkInfoBar *infobar;
201 GtkWidget *infobar;
202
203 infobar = get_object ("GNUNET_GTK_conversation_infobar");
204
205 gtk_widget_hide (infobar);
206}
207
208
209
210/**
211 * Function called with an event emitted by a phone.
212 *
213 * @param cls closure
214 * @param code type of the event
215 * @param caller handle for the caller
216 * @param caller_id name of the caller in GNS
217 */
218static void
219phone_event_handler (void *cls, enum GNUNET_CONVERSATION_PhoneEventCode code,
220 struct GNUNET_CONVERSATION_Caller *caller,
221 const char *caller_id)
222{
223 struct CallList *cl;
224
225 switch (code)
226 {
227 case GNUNET_CONVERSATION_EC_PHONE_RING:
228
229 LOG (_("A Incoming call from `%s' on line %u\n"), caller_id,
230 caller_num_gen);
231
232
233 UPDATE_INFOBAR (_("Incoming call from `%s' on line %u\n"), caller_id,
234 caller_num_gen);
235
236 show_infobar ();
237 // TODO: make sound
238
239 cl = GNUNET_new (struct CallList);
240
241 cl->caller = caller;
242 cl->caller_id = GNUNET_strdup (caller_id);
243 cl->caller_num = caller_num_gen++;
244 GNUNET_CONTAINER_DLL_insert (cl_head, cl_tail, cl);
245 strncpy (&callerName, &caller_id, 50);
246 callerName[52] = '\0';
247 quick_message ("der is een beller", caller_id);
248
249 break;
250
251 case GNUNET_CONVERSATION_EC_PHONE_HUNG_UP:
252 for (cl = cl_head; NULL != cl; cl = cl->next)
253 if (caller == cl->caller)
254 break;
255 if (NULL == cl)
256 {
257 GNUNET_break (0);
258 return;
259 }
260 LOG (_("Call from `%s' terminated\n"), cl->caller_id);
261
262 GNUNET_CONTAINER_DLL_remove (cl_head, cl_tail, cl);
263 GNUNET_free (cl->caller_id);
264 if (cl == cl_active)
265 {
266 cl_active = NULL;
267 phone_state = PS_LISTEN;
268 }
269 GNUNET_free (cl);
270 gtk_widget_destroy (dialog);
271 break;
272
273 }
274}
275
276
277/**
278 * Function called with an event emitted by a caller.
279 *
280 * @param cls closure with the `struct CallList` of the caller
281 * @param code type of the event issued by the caller
282 */
283static void
284caller_event_handler (void *cls, enum GNUNET_CONVERSATION_CallerEventCode code)
285{
286 struct CallList *cl = cls;
287
288 switch (code)
289 {
290 case GNUNET_CONVERSATION_EC_CALLER_SUSPEND:
291 update_state ();
292 LOG (_("Call from `%s' suspended by other user\n"), cl->caller_id);
293 break;
294 case GNUNET_CONVERSATION_EC_CALLER_RESUME:
295 update_state ();
296 LOG (_("Call from `%s' resumed by other user\n"), cl->caller_id);
297 break;
298 }
299}
300
301
302/**
303 * Start our phone.
304 */
305static void
306start_phone ()
307{
308 struct GNUNET_GNSRECORD_Data rd;
309
310 LOG ("start_phone\n");
311
312 if (NULL == caller_id)
313 {
314 LOG (_("Ego `%s' no longer available, phone is now down.\n"), ego_name);
315 phone_state = PS_LOOKUP_EGO;
316 return;
317 }
318 //GNUNET_assert (NULL == phone);
319 phone =
320 GNUNET_CONVERSATION_phone_create (cfg, caller_id, &phone_event_handler,
321 NULL);
322 /* FIXME: get record and print full GNS record info later here... */
323 if (NULL == phone)
324 {
325 LOG ("%s", _("Failed to setup phone (internal error)\n"));
326 phone_state = PS_ERROR;
327 }
328 else
329 {
330 GNUNET_CONVERSATION_phone_get_record (phone, &rd);
331 GNUNET_free_non_null (address);
332 address =
333 GNUNET_GNSRECORD_value_to_string (rd.record_type, rd.data,
334 rd.data_size);
335
336 LOG (_("address: `%s' \n"), address);
337
338 if (verbose)
339 LOG (_("Phone active on line %u\n"), (unsigned int) line);
340 phone_state = PS_LISTEN;
341 }
342}
343
344
345/**
346 * Function called with an event emitted by a call.
347 *
348 * @param cls closure, NULL
349 * @param code type of the event on the call
350 */
351static void
352call_event_handler (void *cls, enum GNUNET_CONVERSATION_CallEventCode code)
353{
354 switch (code)
355 {
356 case GNUNET_CONVERSATION_EC_CALL_RINGING:
357 GNUNET_break (CS_RESOLVING == call_state);
358 LOG (_("Resolved address of `%s'. Now ringing other party."), peer_name);
359 call_state = CS_RINGING;
360 break;
361 case GNUNET_CONVERSATION_EC_CALL_PICKED_UP:
362 GNUNET_break (CS_RINGING == call_state);
363 LOG (_("Connection established to `%s'"), peer_name);
364 call_state = CS_CONNECTED;
365 break;
366 case GNUNET_CONVERSATION_EC_CALL_GNS_FAIL:
367 GNUNET_break (CS_RESOLVING == call_state);
368 LOG (_("Failed to resolve %s in ego `%s'"), peer_name, ego_name);
369 call = NULL;
370 break;
371 case GNUNET_CONVERSATION_EC_CALL_HUNG_UP:
372 LOG ("%s", _("Call terminated"));
373 call = NULL;
374 break;
375 case GNUNET_CONVERSATION_EC_CALL_SUSPENDED:
376 GNUNET_break (CS_CONNECTED == call_state);
377 LOG (_("Connection to `%s' suspended (by other user)\n"), peer_name);
378 break;
379 case GNUNET_CONVERSATION_EC_CALL_RESUMED:
380 GNUNET_break (CS_CONNECTED == call_state);
381 LOG (_("Connection to `%s' resumed (by other user)\n"), peer_name);
382 break;
383 }
384}
385
386
387
388/**
389 * Initiating a new call
390 *
391 * @param arg arguments given to the command
392 */
393static void
394do_call (const char *arg)
395{
396 if (NULL == caller_id)
397 {
398 LOG (_("Ego `%s' not available\n"), ego_name);
399 return;
400 }
401 if (NULL != call)
402 {
403 LOG (_("You are calling someone else already, hang up first!\n"));
404 return;
405 }
406 switch (phone_state)
407 {
408 case PS_LOOKUP_EGO:
409 LOG (_("Ego `%s' not available\n"), ego_name);
410 return;
411 case PS_LISTEN:
412 /* ok to call! */
413 break;
414 case PS_ACCEPTED:
415 LOG (_
416 ("You are answering call from `%s', hang up or suspend that call first!\n"),
417 peer_name);
418 return;
419 case PS_ERROR:
420 /* ok to call */
421 break;
422 }
423 GNUNET_free_non_null (peer_name);
424 peer_name = GNUNET_strdup (arg);
425 LOG (_("now calling: %s"), peer_name);
426 call_state = CS_RESOLVING;
427 GNUNET_assert (NULL == call);
428 call =
429 GNUNET_CONVERSATION_call_start (cfg, caller_id, arg, speaker, mic,
430 &call_event_handler, NULL);
431}
432
433
434/**
435 * Accepting an incoming call
436 *
437 * @param args arguments given to the command
438 */
439static void
440do_accept (const char *args)
441{
442 FPRINTF (stderr, "do_accept run");
443 struct CallList *cl;
444 char buf[32];
445
446
447 if ((NULL != call) && (CS_SUSPENDED != call_state))
448 {
449 LOG (_("You are calling someone else already, hang up first!\n"));
450 return;
451 }
452 switch (phone_state)
453 {
454 case PS_LOOKUP_EGO:
455 GNUNET_break (0);
456 break;
457 case PS_LISTEN:
458 /* this is the expected state */
459 break;
460 case PS_ACCEPTED:
461 LOG (_
462 ("You are answering call from `%s', hang up or suspend that call first!\n"),
463 peer_name);
464 return;
465 case PS_ERROR:
466 GNUNET_break (0);
467 break;
468 }
469 cl = cl_head;
470 if (NULL == cl)
471 {
472 LOG (_("There is no incoming call to accept here!\n"));
473 return;
474 }
475 if ((NULL != cl->next) || (NULL != args))
476 {
477 for (cl = cl_head; NULL != cl; cl = cl->next)
478 {
479 GNUNET_snprintf (buf, sizeof (buf), "%u", cl->caller_num);
480 if (0 == strcmp (buf, args))
481 break;
482 }
483 }
484 if (NULL == cl)
485 {
486 LOG (_("There is no incoming call `%s' to accept right now!\n"), args);
487 return;
488 }
489 cl_active = cl;
490 GNUNET_free_non_null (peer_name);
491 peer_name = GNUNET_strdup (cl->caller_id);
492 phone_state = PS_ACCEPTED;
493 GNUNET_CONVERSATION_caller_pick_up (cl->caller, &caller_event_handler, cl,
494 speaker, mic);
495 history_add ("1", peer_name);
496
497}
498
499
500
501
502
503
504
505/**
506 * update statusbar
507 *
508 * @param args arguments given to the command
509 */
510static void
511do_status (const char *args)
512{
513 struct CallList *cl;
514
515 switch (phone_state)
516 {
517 case PS_LOOKUP_EGO:
518 UPDATE_STATUS (_
519 ("We are currently trying to locate the private key for the ego `%s'.\n"),
520 ego_name);
521
522 break;
523 case PS_LISTEN:
524 UPDATE_STATUS (_
525 ("We are listening for incoming calls for ego `%s' on line %u.\n"),
526 ego_name, line);
527 break;
528 case PS_ACCEPTED:
529 UPDATE_STATUS (_("You are having a conversation with `%s'.\n"), peer_name);
530 break;
531 case PS_ERROR:
532 UPDATE_STATUS (_
533 ("We had an internal error setting up our phone line. You can still make calls.\n"));
534 break;
535 }
536 if (NULL != call)
537 {
538 switch (call_state)
539 {
540 case CS_RESOLVING:
541 UPDATE_STATUS (_
542 ("We are trying to find the network address to call `%s'.\n"),
543 peer_name);
544 break;
545 case CS_RINGING:
546 UPDATE_STATUS (_("We are calling `%s', his phone should be ringing.\n"),
547 peer_name);
548 break;
549 case CS_CONNECTED:
550 UPDATE_STATUS (_("You are having a conversation with `%s'.\n"),
551 peer_name);
552 break;
553 case CS_SUSPENDED:
554 /* ok to accept incoming call right now */
555 break;
556 }
557 }
558 if ((NULL != cl_head) && ((cl_head != cl_active) || (cl_head != cl_tail)))
559 {
560 LOG ("%s", _("Calls waiting:"));
561 for (cl = cl_head; NULL != cl; cl = cl->next)
562 {
563 if (cl == cl_active)
564 continue;
565 UPDATE_STATUS (_("#%u: `%s'"), cl->caller_num, cl->caller_id);
566 }
567 }
568}
569
570
571/**
572 * Suspending a call
573 *
574 * @param args arguments given to the command
575 */
576
577static void
578do_suspend (const char *args)
579{
580 if (NULL != call)
581 {
582 switch (call_state)
583 {
584 case CS_RESOLVING:
585 case CS_RINGING:
586 case CS_SUSPENDED:
587 LOG ("%s", _("There is no call that could be suspended right now."));
588 return;
589 case CS_CONNECTED:
590 call_state = CS_SUSPENDED;
591 GNUNET_CONVERSATION_call_suspend (call);
592 return;
593 }
594 }
595 switch (phone_state)
596 {
597 case PS_LOOKUP_EGO:
598 case PS_LISTEN:
599 case PS_ERROR:
600 LOG ("%s", _("There is no call that could be suspended right now."));
601 return;
602 case PS_ACCEPTED:
603 /* expected state, do rejection logic */
604 break;
605 }
606 GNUNET_assert (NULL != cl_active);
607 GNUNET_CONVERSATION_caller_suspend (cl_active->caller);
608 cl_active = NULL;
609 phone_state = PS_LISTEN;
610}
611
612
613/**
614 * Resuming a call
615 *
616 * @param args arguments given to the command
617 */
618static void
619do_resume (const char *args)
620{
621 struct CallList *cl;
622 char buf[32];
623
624 if (NULL != call)
625 {
626 switch (call_state)
627 {
628 case CS_RESOLVING:
629 case CS_RINGING:
630 case CS_CONNECTED:
631 LOG ("%s", _("There is no call that could be resumed right now."));
632 return;
633 case CS_SUSPENDED:
634 call_state = CS_CONNECTED;
635 GNUNET_CONVERSATION_call_resume (call, speaker, mic);
636 return;
637 }
638 }
639 switch (phone_state)
640 {
641 case PS_LOOKUP_EGO:
642 case PS_ERROR:
643 LOG ("%s", _("There is no call that could be resumed right now."));
644 return;
645 case PS_LISTEN:
646 /* expected state, do resume logic */
647 break;
648 case PS_ACCEPTED:
649 LOG (_("Already talking with `%s', cannot resume a call right now."),
650 peer_name);
651 return;
652 }
653 GNUNET_assert (NULL == cl_active);
654 cl = cl_head;
655 if (NULL == cl)
656 {
657 LOG (_("There is no incoming call to resume here!"));
658 return;
659 }
660 if ((NULL != cl->next) || (NULL != args))
661 {
662 for (cl = cl_head; NULL != cl; cl = cl->next)
663 {
664 GNUNET_snprintf (buf, sizeof (buf), "%u", cl->caller_num);
665 if (0 == strcmp (buf, args))
666 break;
667 }
668 }
669 if (NULL == cl)
670 {
671 LOG (_("There is no incoming call `%s' to resume right now!"), args);
672 return;
673 }
674 cl_active = cl;
675 GNUNET_CONVERSATION_caller_resume (cl_active->caller, speaker, mic);
676 phone_state = PS_ACCEPTED;
677}
678
679
680/**
681 / Rejecting a call
682 *
683 * @param args arguments given to the command
684 */
685static void
686do_reject (const char *args)
687{
688 FPRINTF (stderr, "doing reject");
689 struct CallList *cl;
690 char buf[32];
691
692 if (NULL != call)
693 {
694 GNUNET_CONVERSATION_call_stop (call);
695 call = NULL;
696 return;
697 }
698 switch (phone_state)
699 {
700 case PS_LOOKUP_EGO:
701 case PS_ERROR:
702 LOG ("%s", _("There is no call that could be cancelled right now.\n"));
703 return;
704 case PS_LISTEN:
705 /* look for active incoming calls to refuse */
706 cl = cl_head;
707 if (NULL == cl)
708 {
709 LOG (_("There is no incoming call to refuse here!\n"));
710 return;
711 }
712 if ((NULL != cl->next) || (NULL != args))
713 {
714 for (cl = cl_head; NULL != cl; cl = cl->next)
715 {
716 GNUNET_snprintf (buf, sizeof (buf), "%u", cl->caller_num);
717 if (0 == strcmp (buf, args))
718 break;
719 }
720 }
721 if (NULL == cl)
722 {
723 LOG (_("There is no incoming call `%s' to refuse right now!\n"), args);
724 return;
725 }
726 GNUNET_CONVERSATION_caller_hang_up (cl->caller);
727 GNUNET_CONTAINER_DLL_remove (cl_head, cl_tail, cl);
728 peer_name = GNUNET_strdup (cl->caller_id);
729 GNUNET_free (cl->caller_id);
730 GNUNET_free (cl);
731 break;
732 case PS_ACCEPTED:
733 /* expected state, do rejection logic */
734 GNUNET_assert (NULL != cl_active);
735 GNUNET_CONVERSATION_caller_hang_up (cl_active->caller);
736 cl_active = NULL;
737 phone_state = PS_LISTEN;
738 break;
739 }
740 //FPRINTF(stderr,"blaalalal %s",peer_name);
741 history_add ("2", peer_name);
742
743}
744
745
746
747
748
749
750////////////////////////////
751
752
753static void
754display_record (void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key,
755 const char *rname, unsigned int rd_len,
756 const struct GNUNET_GNSRECORD_Data *rd)
757{
758 const char *typestring;
759 char *s, *type;
760 unsigned int i;
761 const char *ets;
762 struct GNUNET_TIME_Absolute at;
763 struct GNUNET_TIME_Relative rt;
764 GtkTreeIter iter;
765
766 if (NULL == rname)
767 {
768 list_it = NULL;
769 //test_finished ();
770 return;
771 }
772 if ((NULL != name) && (0 != strcmp (name, rname)))
773 {
774 GNUNET_NAMESTORE_zone_iterator_next (list_it);
775 return;
776 }
777 //FPRINTF (stdout,
778// "%s:\n",
779// rname);
780 for (i = 0; i < rd_len; i++)
781 {
782
783 if ((GNUNET_GNSRECORD_TYPE_NICK == rd[i].record_type) &&
784 (0 != strcmp (rname, "+")))
785 continue;
786 typestring = GNUNET_GNSRECORD_number_to_typename (rd[i].record_type);
787 s = GNUNET_GNSRECORD_value_to_string (rd[i].record_type, rd[i].data,
788 rd[i].data_size);
789 if (NULL == s)
790 {
791 FPRINTF (stdout, _("\tCorrupt or unsupported record of type %u\n"),
792 (unsigned int) rd[i].record_type);
793 continue;
794 }
795 if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION))
796 {
797 rt.rel_value_us = rd[i].expiration_time;
798 ets = GNUNET_STRINGS_relative_time_to_string (rt, GNUNET_YES);
799 }
800 else
801 {
802 at.abs_value_us = rd[i].expiration_time;
803 ets = GNUNET_STRINGS_absolute_time_to_string (at);
804 }
805 if (rd[i].record_type == 65536)
806 {
807 type = "PKEY";
808 } // if pubkey record
809 if (rd[i].record_type == 65542)
810 {
811 type = "PHONE";
812 }
813 FPRINTF (stdout, "%s", rname);
814 gtk_list_store_append (contacts_liststore, &iter);
815 gtk_list_store_set (contacts_liststore, &iter, 1, type, 0, rname, -1);
816
817/* FPRINTF (stdout,
818 "\t%s: %s (%s)\t%s\t%s\t%s\n",
819 typestring,
820 s,
821 ets,
822 (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_PRIVATE)) ? "PRIVATE" : "PUBLIC",
823 (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_SHADOW_RECORD)) ? "SHADOW" : "",
824 (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_PENDING)) ? "PENDING" : "");
825*/
826 //gtk_widget_show(contacts_liststore);
827 GNUNET_free (s);
828 }
829 FPRINTF (stdout, "%s", "\n");
830 GNUNET_NAMESTORE_zone_iterator_next (list_it);
831}
832
833/**
834 * Continuation called to notify client about result of the
835 * operation.
836 *
837 * @param cls closure, location of the QueueEntry pointer to NULL out
838 * @param success #GNUNET_SYSERR on failure (including timeout/queue drop/failure to validate)
839 * #GNUNET_NO if content was already there
840 * #GNUNET_YES (or other positive value) on success
841 * @param emsg NULL on success, otherwise an error message
842 */
843static void
844add_continuation (void *cls, int32_t success, const char *emsg)
845{
846 struct GNUNET_NAMESTORE_QueueEntry **qe = cls;
847
848 *qe = NULL;
849 if (GNUNET_YES != success)
850 {
851 fprintf (stderr, _("Adding record failed: %s\n"),
852 (GNUNET_NO == success) ? "record exists" : emsg);
853 if (GNUNET_NO != success)
854 ret = 1;
855 }
856 ret = 0;
857 //test_finished ();
858}
859
860/**
861 * Function called by identity service with information about egos.
862 *
863 * @param cls NULL
864 * @param ego ego handle
865 * @param ctx unused
866 * @param name name of the ego
867 */
868static void
869identity_cb (void *cls, struct GNUNET_IDENTITY_Ego *ego, void **ctx,
870 const char *name)
871{
872
873 FPRINTF (stderr, _("identity_cb name: `%s' caller_id: `%s' \n"), name,
874 caller_id);
875
876 if (NULL == name)
877 return;
878 if (ego == caller_id)
879 {
880 if (verbose)
881 LOG (_("Name of our ego changed to `%s'\n"), name);
882 GNUNET_free (ego_name);
883 ego_name = GNUNET_strdup (name);
884 return;
885 }
886 if (0 != strcmp (name, ego_name))
887 return;
888 if (NULL == ego)
889 {
890 if (verbose)
891 LOG (_("Our ego `%s' was deleted!\n"), ego_name);
892 caller_id = NULL;
893 return;
894 }
895 caller_id = ego;
896 GNUNET_CONFIGURATION_set_value_number (cfg, "CONVERSATION", "LINE", line);
897 zone_pkey = *GNUNET_IDENTITY_ego_get_private_key (caller_id);
898 ns = GNUNET_NAMESTORE_connect (cfg);
899
900 list_it =
901 GNUNET_NAMESTORE_zone_iteration_start (ns, &zone_pkey, &display_record,
902 NULL);
903
904
905 start_phone ();
906
907}
908
909/**
910 * Get our configuration.
911 *
912 * @return configuration handle
913 */
914const struct GNUNET_CONFIGURATION_Handle *
915GIG_get_configuration ()
916{
917 return GNUNET_GTK_main_loop_get_configuration (ml);
918}
919
920
921
922
923/**
924 * Task run on shutdown.
925 *
926 * @param cls unused
927 * @param tc scheduler context, unused
928 */
929static void
930shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
931{
932 struct OperationContext *oc;
933
934/*
935 GIG_advertise_shutdown_ ();
936 while (NULL != (oc = oc_head))
937 {
938 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
939 _("Operation not completed due to shutdown\n"));
940 GNUNET_IDENTITY_cancel (oc->op);
941 GNUNET_CONTAINER_DLL_remove (oc_head,
942 oc_tail,
943 oc);
944 GNUNET_free (oc);
945 }
946 if (NULL != identity)
947 {
948 GNUNET_IDENTITY_disconnect (identity);
949 identity = NULL;
950 }
951 */
952 GNUNET_GTK_tray_icon_destroy ();
953 GNUNET_GTK_main_loop_quit (ml);
954 ml = NULL;
955}
956
957
958
959
960/**
961 * Callback invoked if the application is supposed to exit.
962 *
963 * @param object
964 * @param user_data unused
965 */
966void
967GNUNET_GTK_conversation_quit_cb (GObject * object, gpointer user_data)
968{
969 if (NULL != call)
970 {
971 GNUNET_CONVERSATION_call_stop (call);
972 call = NULL;
973 }
974 if (NULL != phone)
975 {
976 GNUNET_CONVERSATION_phone_destroy (phone);
977 phone = NULL;
978 }
979 if (NULL != id)
980 {
981 GNUNET_IDENTITY_disconnect (id);
982 id = NULL;
983 }
984 if (NULL != ns)
985 {
986 GNUNET_IDENTITY_disconnect (ns);
987 ns = NULL;
988 }
989
990 GNUNET_SPEAKER_destroy (speaker);
991 speaker = NULL;
992 GNUNET_MICROPHONE_destroy (mic);
993 mic = NULL;
994 GNUNET_free (ego_name);
995 ego_name = NULL;
996 GNUNET_free_non_null (peer_name);
997 phone_state = PS_ERROR;
998
999 GNUNET_SCHEDULER_shutdown ();
1000
1001
1002 GNUNET_CRYPTO_ecdsa_key_clear (&zone_pkey);
1003 return 0;
1004
1005}
1006
1007
1008/**
1009 * Actual main function run right after GNUnet's scheduler
1010 * is initialized. Initializes up GTK and Glade.
1011 *
1012 * @param cls NULL
1013 * @param tc schedule context
1014 */
1015static void
1016run (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1017{
1018 GtkTreeIter iter;
1019 GtkWidget *main_window;
1020
1021 //line = 0;
1022
1023 ml = cls;
1024 if (GNUNET_OK != GNUNET_GTK_main_loop_build_window (ml, NULL))
1025 return;
1026 GNUNET_GTK_set_icon_search_path ();
1027 GNUNET_GTK_setup_nls ();
1028 /* setup main window */
1029 main_window = GTK_WIDGET (get_object ("GNUNET_GTK_conversation_window"));
1030 main_window =
1031 GNUNET_GTK_plug_me ("GNUNET_CONVERSATION_GTK_PLUG", main_window);
1032 gtk_window_set_default_size (main_window, 300, 700);
1033 contacts_liststore =
1034 GTK_LIST_STORE (get_object
1035 ("gnunet_conversation_gtk_contacts_liststore"));
1036 contacts_treeview =
1037 GTK_TREE_VIEW (get_object ("gnunet_conversation_gtk_treeview"));
1038 contacts_treestore =
1039 GTK_TREE_STORE (get_object
1040 ("gnunet_conversation_gtk_contacts_treestore"));
1041 contacts_treemodel = GTK_TREE_MODEL (contacts_treestore);
1042
1043 history_liststore =
1044 GTK_LIST_STORE (get_object ("gnunet_conversation_gtk_history_liststore"));
1045 history_treeview =
1046 GTK_TREE_VIEW (get_object ("gnunet_conversation_gtk_history_treeview"));
1047 history_treestore =
1048 GTK_TREE_STORE (get_object ("gnunet_conversation_gtk_history_treestore"));
1049 history_treemodel = GTK_TREE_MODEL (history_treestore);
1050
1051 //gtk_tree_view_set_activate_on_single_click(contacts_treeview, TRUE);
1052
1053 GNUNET_assert (NULL != contacts_liststore);
1054
1055 // gtk_window_maximize (GTK_WINDOW (main_window));
1056
1057 if (NULL == getenv ("GNUNET_CONVERSATION_GTK_PLUG"))
1058 GNUNET_GTK_tray_icon_create (ml, GTK_WINDOW (main_window),
1059 "gnunet-gtk" /* FIXME: different icon? */ ,
1060 "gnunet-conversation-gtk");
1061
1062 /* make GUI visible */
1063 if (!tray_only)
1064 {
1065 gtk_widget_show (main_window);
1066 gtk_window_present (GTK_WINDOW (main_window));
1067 }
1068
1069 /* get gui objects */
1070
1071
1072
1073 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task,
1074 NULL);
1075
1076 cfg = GIG_get_configuration ();
1077//cfg = GNUNET_CONFIGURATION_dup (c);
1078
1079 speaker = GNUNET_SPEAKER_create_from_hardware (cfg);
1080 mic = GNUNET_MICROPHONE_create_from_hardware (cfg);
1081
1082// ego_name = "phone_ego";
1083 if (NULL == ego_name)
1084 {
1085 ego_name = "phone-ego";
1086 LOG ("%s", _("No ego given, using default \"phone-ego\" \n"));
1087 return;
1088 }
1089
1090
1091 id = GNUNET_IDENTITY_connect (cfg, &identity_cb, NULL);
1092
1093// zone_pkey = *GNUNET_IDENTITY_ego_get_private_key (caller_id);
1094
1095}
1096
1097
1098/**
1099 * Main function of gnunet-conversation-gtk.
1100 *
1101 * @param argc number of arguments
1102 * @param argv arguments
1103 * @return 0 on success
1104 */
1105int
1106main (int argc, char *const *argv)
1107{
1108 static struct GNUNET_GETOPT_CommandLineOption options[] = {
1109 {'p', "phone", "LINE",
1110 gettext_noop ("sets the LINE to use for the phone"),
1111 1, &GNUNET_GETOPT_set_uint, &line},
1112
1113 {'e', "ego", "ego",
1114 gettext_noop ("select ego to use"), 1,
1115 &GNUNET_GETOPT_set_string, &ego_name},
1116
1117 {'t', "tray", NULL,
1118 gettext_noop ("start in tray mode"), 0,
1119 &GNUNET_GETOPT_set_one, &tray_only},
1120 GNUNET_GETOPT_OPTION_END
1121 };
1122 if (GNUNET_OK !=
1123 GNUNET_GTK_main_loop_start ("gnunet-conversation-gtk",
1124 "GTK GUI for conversation", argc, argv,
1125 options,
1126 "gnunet_conversation_gtk_main_window.glade",
1127 &run))
1128 return 1;
1129 return 0;
1130 FPRINTF (stderr, "line %i", line);
1131}
1132
1133/* gui stuff start */
1134
1135
1136
1137
1138/**
1139 * call clicked
1140 */
1141void
1142GNUNET_CONVERSATION_GTK_on_call_clicked ()
1143{
1144 char *to_addr;
1145
1146 // /og_message ("call clicked");
1147 //update_status();
1148 //address dingetje
1149
1150 GtkEntry *address_entry;
1151
1152 address_entry = GTK_ENTRY ((get_object ("GNUNET_GTK_conversation_address")));
1153 to_addr = gtk_entry_get_text (address_entry);
1154
1155// FPRINTF (stderr, _("calling: %s \n"), to_addr );
1156
1157 do_call (to_addr);
1158 disable_button ("GNUNET_GTK_conversation_accept_button");
1159 do_status ("");
1160}
1161
1162/**
1163 * clicked
1164 */
1165void
1166GNUNET_CONVERSATION_GTK_on_hangup_clicked ()
1167{
1168 //update_status()disable_button("GNUNET_CONVERSATION_GTK_call_button");
1169
1170 enable_button ("GNUNET_GTK_conversation_call_button");
1171
1172
1173 //FPRINTF (stderr, "hangup clicked \n");
1174 do_reject ("");
1175 do_status ("");
1176}
1177
1178/**
1179 * clicked
1180 */
1181void
1182GNUNET_CONVERSATION_GTK_on_accept_clicked ()
1183{
1184 FPRINTF (stderr, "accept clicked \n");
1185 do_accept (0);
1186 hide_infobar ();
1187}
1188
1189
1190/**
1191 * clicked
1192 */
1193void
1194GNUNET_CONVERSATION_GTK_on_reject_clicked ()
1195{
1196 LOG ("reject clicked \n");
1197 do_reject ("0");
1198}
1199
1200/**
1201 * clicked
1202 */
1203void
1204GNUNET_CONVERSATION_GTK_on_pause_clicked ()
1205{
1206// GtkEntry *entry;
1207
1208 //FPRINTF (stderr, "pause clicked \n");
1209 //do_pause("");
1210 // entry = GTK_ENTRY((get_object ("GNUNET_GTK_conversation_address")));
1211 //FPRINTF (stderr, gtk_entry_get_text (entry));
1212// gtk_entry_set_text (entry, "testtextje");
1213 show_infobar ();
1214}
1215
1216/**
1217 * clicked
1218 */
1219void
1220GNUNET_CONVERSATION_GTK_on_resume_clicked ()
1221{
1222 //FPRINTF (stderr, "reject clicked \n");
1223 do_resume ("");
1224}
1225
1226/**
1227 * clicked
1228 */
1229void
1230GNUNET_CONVERSATION_GTK_on_status_clicked ()
1231{
1232
1233 FPRINTF (stderr, "status clicked \n");
1234
1235// do_accept("0");
1236 do_status (" ");
1237 //quick_message('hee blaaat you have a call from blaat');
1238}
1239
1240
1241void
1242use_current_incoming_address ()
1243{
1244 FPRINTF (stderr, "use cur addr");
1245}
1246
1247
1248/*
1249void
1250test_function (gint response_id)
1251{
1252 FPRINTF (stderr, "teest %u", response_id);
1253}
1254*/
1255
1256
1257/*
1258 * add a new contact
1259 * @param name
1260 * @param address
1261 */
1262void add_contact(char *name, char *address)
1263{
1264// memmove(&address+1,&address+51,1);
1265 GtkTreeIter iter;
1266 struct GNUNET_GNSRECORD_Data rd;
1267
1268 zone_pkey = *GNUNET_IDENTITY_ego_get_private_key (caller_id);
1269 rd.data = address;
1270 rd.data_size = sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey);
1271 rd.record_type = GNUNET_GNSRECORD_TYPE_PKEY;
1272 rd.flags |= GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION; // always set to relative for testing purposes
1273 FPRINTF (stderr, "adding\n");
1274 FPRINTF (stderr, "name: %s\n", name);
1275 FPRINTF (stderr, "address: %s\n", address);
1276 add_qe =
1277 GNUNET_NAMESTORE_records_store (ns, &zone_pkey, name, 1, &rd, NULL,
1278 add_qe);
1279 gtk_list_store_append (contacts_liststore, &iter);
1280 gtk_list_store_set (contacts_liststore, &iter, 1, "PKEY", 0, name, -1);
1281
1282}
1283
1284/*
1285 * executed when clicked on add contact
1286 * @param button
1287 * @param user_data
1288 */
1289
1290void
1291GNUNET_CONVERSATION_GTK_on_add_clicked (GtkButton * button,
1292 gpointer * user_data)
1293{
1294 gint response_id;
1295
1296 FPRINTF (stderr, "add clicked \n");
1297 GtkWidget *caller_name, *notification, *content_area, *currentCheckButton,
1298 *nameEntry, *addressEntry, *anotherArea, *labelName, *labelAddres;
1299 GtkDialog *dialog;
1300 GtkWindow *main_window;
1301
1302 currentCheckButton =
1303 gtk_button_new_with_label ("use currently incoming addres");
1304
1305 nameEntry = gtk_entry_new ();
1306 gtk_entry_set_text (nameEntry, "Name of contact");
1307 addressEntry = gtk_entry_new ();
1308 gtk_entry_set_text (addressEntry, "Address of contact");
1309
1310 main_window = get_object ("GNUNET_GTK_conversation_window");
1311
1312 dialog =
1313 gtk_dialog_new_with_buttons ("Adding contact", main_window,
1314 GTK_DIALOG_DESTROY_WITH_PARENT,
1315 _("Add contact"), GTK_RESPONSE_ACCEPT,
1316 _("Cancel"), GTK_RESPONSE_CANCEL, NULL);
1317 gtk_dialog_add_action_widget (dialog, currentCheckButton, GTK_RESPONSE_OK);
1318 FPRINTF (stderr, "response id : %u", response_id);
1319 g_signal_connect (GTK_BUTTON (currentCheckButton), "clicked",
1320 G_CALLBACK (use_current_incoming_address), NULL);
1321
1322
1323 gtk_dialog_add_action_widget (dialog, nameEntry, 2);
1324 gtk_dialog_add_action_widget (dialog, addressEntry, 3);
1325
1326 content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
1327
1328
1329 notification = gtk_label_new ("Adding contact");
1330// caller_name = gtk_label_new (caller_id);
1331
1332 // Add the labels, and show everything we've added to the dialog
1333 gtk_container_add (GTK_CONTAINER (content_area), notification);
1334// gtk_container_add (GTK_CONTAINER (content_area), caller_name);
1335 gtk_widget_show_all (dialog);
1336
1337 switch (gtk_dialog_run (dialog))
1338 {
1339 case GTK_RESPONSE_ACCEPT:
1340 FPRINTF (stderr, "accept clicked");
1341 do_status ("");
1342 add_contact (gtk_entry_get_text (nameEntry),
1343 gtk_entry_get_text (addressEntry));
1344 gtk_widget_destroy (dialog);
1345 break;
1346 case GTK_RESPONSE_CANCEL:
1347 FPRINTF (stderr, "cancel clicked");
1348 do_status ("");
1349 gtk_widget_destroy (dialog);
1350 break;
1351 case GTK_RESPONSE_OK:
1352 //use_current_incoming_address();
1353 gtk_entry_set_text (addressEntry, callerName);
1354 add_contact (gtk_entry_get_text (nameEntry), callerName);
1355// add_contact(gtk_entry_get_text(nameEntry),memmove(&callerName,&callerName+52,1));
1356 gtk_widget_destroy (dialog);
1357
1358// memmove(&address+1,&address+51,1);
1359 break;
1360 }
1361
1362
1363}
1364
1365void
1366GNUNET_CONVERSATION_GTK_on_remove_clicked (GtkButton * button,
1367 gpointer * user_data)
1368{
1369 FPRINTF (stderr, "remove clicked \n");
1370
1371}
1372
1373
1374/*
1375 * Function to open a dialog box displaying the message provided.
1376 *
1377 * @param message message in the dialogbox
1378 * @param caller_id
1379 */
1380
1381void
1382quick_message (gchar * message, const char *caller_id)
1383{
1384 GtkWidget *caller_name, *notification, *content_area;
1385 GtkDialog *dialog;
1386 GtkWindow *main_window;
1387 main_window = get_object("GNUNET_GTK_conversation_window");
1388 // Create the widgets
1389
1390
1391 dialog = gtk_dialog_new_with_buttons ("Incoming call!",
1392 main_window,
1393 GTK_DIALOG_DESTROY_WITH_PARENT,
1394 _("Accept call"),
1395 GTK_RESPONSE_ACCEPT,
1396 _("Reject call"),
1397 GTK_RESPONSE_REJECT,
1398 _("Decide later"),
1399 GTK_RESPONSE_CANCEL,
1400
1401 NULL);
1402 content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
1403
1404
1405 notification = gtk_label_new ("Incoming call from:");
1406 caller_name = gtk_label_new (caller_id);
1407
1408 // Add the labels, and show everything we've added to the dialog
1409 gtk_container_add (GTK_CONTAINER (content_area), notification);
1410 gtk_container_add (GTK_CONTAINER (content_area), caller_name);
1411 gtk_widget_show_all (dialog);
1412
1413 switch(gtk_dialog_run(dialog)){
1414 case GTK_RESPONSE_ACCEPT :
1415 do_status("");
1416 gtk_widget_destroy(dialog);
1417 do_accept("0");
1418 break;
1419 case GTK_RESPONSE_REJECT :
1420 do_reject(NULL);
1421 do_status("");
1422 gtk_widget_destroy(dialog);
1423 break;
1424 case GTK_RESPONSE_CANCEL :
1425 do_status("");
1426 gtk_widget_destroy(dialog);
1427 break;
1428 }
1429
1430
1431}
1432
1433/*
1434 * row activated
1435 * @return void
1436 */
1437
1438void
1439GNUNET_CONVERSATION_GTK_row_activated ()
1440{
1441 char *callAddress;
1442 char *type;
1443
1444 FPRINTF (stderr, "row activated \n");
1445
1446 GtkTreeSelection *selection;
1447
1448 GtkTreeIter iterA;
1449
1450
1451 selection = gtk_tree_view_get_selection (contacts_treeview);
1452
1453 gtk_tree_selection_get_selected (selection, &contacts_treemodel, &iterA);
1454 gtk_tree_model_get (contacts_treemodel, &iterA, 0, &name, 1, &type, -1);
1455 g_print ("ego name %s\n", ego_name);
1456 g_print ("selected row is: %s\n", name);
1457 g_print ("selected rowtype is: %s\n", type);
1458
1459
1460 g_print ("type @row active%s", type);
1461 if (strcmp (type, "PKEY") == 0)
1462 {
1463 GNUNET_asprintf (&callAddress, "call\.%s\.gnu", name);
1464 }
1465 if (strcmp (type, "PHONE") == 0)
1466 {
1467 GNUNET_asprintf (&callAddress, "%s\.gnu", name);
1468 }
1469// else { GNUNET_asprintf(&callAddress, "%s", peer_id);}
1470
1471 g_print ("ego name %s\n", callAddress);
1472 GtkEntry *address_entry;
1473
1474 address_entry = GTK_ENTRY ((get_object ("GNUNET_GTK_conversation_address")));
1475 gtk_entry_set_text (address_entry, callAddress);
1476
1477}
1478
1479/* end of gnunet-conversation-gtk.c */
1480