diff options
-rw-r--r-- | src/conversation/gnunet-conversation-gtk_contacts.c | 1 | ||||
-rw-r--r-- | src/conversation/gnunet-conversation-gtk_phone.c | 1571 |
2 files changed, 695 insertions, 877 deletions
diff --git a/src/conversation/gnunet-conversation-gtk_contacts.c b/src/conversation/gnunet-conversation-gtk_contacts.c index 000801e0..057ed40d 100644 --- a/src/conversation/gnunet-conversation-gtk_contacts.c +++ b/src/conversation/gnunet-conversation-gtk_contacts.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include "gnunet-conversation-gtk.h" | 29 | #include "gnunet-conversation-gtk.h" |
30 | #include "gnunet-conversation-gtk_contacts.h" | 30 | #include "gnunet-conversation-gtk_contacts.h" |
31 | #include "gnunet-conversation-gtk_egos.h" | 31 | #include "gnunet-conversation-gtk_egos.h" |
32 | #include "gnunet-conversation-gtk_phone.h" | ||
32 | 33 | ||
33 | 34 | ||
34 | /** | 35 | /** |
diff --git a/src/conversation/gnunet-conversation-gtk_phone.c b/src/conversation/gnunet-conversation-gtk_phone.c index 05be2bfa..bbd1cb53 100644 --- a/src/conversation/gnunet-conversation-gtk_phone.c +++ b/src/conversation/gnunet-conversation-gtk_phone.c | |||
@@ -33,42 +33,67 @@ | |||
33 | 33 | ||
34 | 34 | ||
35 | /** | 35 | /** |
36 | * active calls treeview columns | 36 | * Active calls treeview columns |
37 | */ | 37 | */ |
38 | enum ActiveCallsTreeViewColumns | 38 | enum ActiveCallsTreeViewColumns |
39 | { | 39 | { |
40 | AL_caller_id, //*gchar | 40 | /** |
41 | AL_caller, //* | 41 | * A `gchar *` |
42 | AL_caller_num, //gint | 42 | */ |
43 | AL_type, //gint | 43 | GCG_PHONE_LS_CALLER_ID, |
44 | AL_caller_state, //gint | ||
45 | AL_call, //* | ||
46 | AL_call_state, //gint | ||
47 | AL_call_num //gint | ||
48 | }; | ||
49 | 44 | ||
45 | /** | ||
46 | * A `struct IncomingCall *` | ||
47 | */ | ||
48 | GCG_PHONE_LS_CALLER, | ||
49 | |||
50 | /** | ||
51 | * A `gint`. | ||
52 | */ | ||
53 | GCG_PHONE_LS_CALLER_NUM, | ||
54 | |||
55 | /** | ||
56 | * A `gint` for a `enum TypeOfConversation` (FIXME: remove?) | ||
57 | */ | ||
58 | GCG_PHONE_LS_TYPE, | ||
59 | |||
60 | /** | ||
61 | * A `gint` for a `enum InCallState` (FIXME: replace with char *!) | ||
62 | */ | ||
63 | GCG_PHONE_LS_CALLER_STATE, | ||
64 | |||
65 | /** | ||
66 | * A `struct OutgoingCall *`. | ||
67 | */ | ||
68 | GCG_PHONE_LS_CALL, | ||
69 | |||
70 | /** | ||
71 | * A `gint` for a `enum OutCallState` (FIXME: replace with char *, | ||
72 | * combine with #GCG_PHONE_LS_CALLER_STATE). | ||
73 | */ | ||
74 | GCG_PHONE_LS_CALL_STATE, | ||
75 | |||
76 | /** | ||
77 | * A `gint`. FIXME: combine with #GCG_PHONE_LS_CALLER_NUM! | ||
78 | */ | ||
79 | GCG_PHONE_LS_CALL_NUM | ||
50 | 80 | ||
51 | /** | ||
52 | * callerstate (state of incoming call) | ||
53 | */ | ||
54 | enum CallerState | ||
55 | { | ||
56 | CT_active, | ||
57 | CT_suspended, | ||
58 | CT_ringing, | ||
59 | CT_dead, | ||
60 | CT_hangup, | ||
61 | CT_rejected, | ||
62 | CT_other | ||
63 | }; | 81 | }; |
64 | 82 | ||
65 | 83 | ||
66 | /** | 84 | /** |
67 | * type of call | 85 | * Types of conversations |
68 | */ | 86 | */ |
69 | enum TypeOfCall | 87 | enum TypeOfConversation |
70 | { | 88 | { |
89 | /** | ||
90 | * Incoming phone call. | ||
91 | */ | ||
71 | CALL_IN, | 92 | CALL_IN, |
93 | |||
94 | /** | ||
95 | * Outgoing call. | ||
96 | */ | ||
72 | CALL_OUT | 97 | CALL_OUT |
73 | }; | 98 | }; |
74 | 99 | ||
@@ -79,7 +104,7 @@ enum TypeOfCall | |||
79 | enum PhoneState | 104 | enum PhoneState |
80 | { | 105 | { |
81 | /** | 106 | /** |
82 | * We're waiting for our own idenitty. | 107 | * We're waiting for the user to select a caller ID. |
83 | */ | 108 | */ |
84 | PS_LOOKUP_EGO, | 109 | PS_LOOKUP_EGO, |
85 | 110 | ||
@@ -101,58 +126,75 @@ enum PhoneState | |||
101 | 126 | ||
102 | 127 | ||
103 | /** | 128 | /** |
104 | * States for current outgoing call. | 129 | * States for current incoming call. |
105 | */ | 130 | */ |
106 | enum CallState | 131 | enum InCallState |
107 | { | 132 | { |
108 | /** | 133 | /** |
109 | * We are looking up some other participant. | 134 | * No incoming call. |
110 | */ | 135 | */ |
111 | CS_RESOLVING, | 136 | IN_STATE_NONE, |
112 | 137 | ||
113 | /** | 138 | /** |
114 | * We are now ringing the other participant. | 139 | * Our phone is ringing. |
115 | */ | 140 | */ |
116 | CS_RINGING, | 141 | IN_STATE_RINGING, |
117 | 142 | ||
118 | /** | 143 | /** |
119 | * The other party accepted our call and we are now connected. | 144 | * The other party accepted our call and we are now connected. |
120 | */ | 145 | */ |
121 | CS_CONNECTED, | 146 | IN_STATE_CONNECTED, |
122 | 147 | ||
123 | /** | 148 | /** |
124 | * The call is currently suspended (by us). | 149 | * The call is currently suspended (by us). |
125 | */ | 150 | */ |
126 | CS_SUSPENDED | 151 | IN_STATE_SUSPENDED |
127 | }; | 152 | }; |
128 | 153 | ||
129 | 154 | ||
130 | |||
131 | /** | 155 | /** |
132 | * List of incoming calls | 156 | * Possible states of outgoing phone calls. |
133 | */ | 157 | */ |
134 | struct CallList | 158 | enum OutCallState |
135 | { | 159 | { |
160 | /** | ||
161 | * Phone state we use if this is not an outgoing call. | ||
162 | */ | ||
163 | OUT_STATE_NONE, | ||
136 | 164 | ||
137 | /** | 165 | /** |
138 | * A DLL. | 166 | * This phone call is currently resolving. |
139 | */ | 167 | */ |
140 | struct CallList *prev; | 168 | OUT_STATE_RESOLVING, |
141 | 169 | ||
142 | /** | 170 | /** |
143 | * A DLL. | 171 | * This phone call is currently ringing. |
144 | */ | 172 | */ |
145 | struct CallList *next; | 173 | OUT_STATE_RINGING, |
146 | 174 | ||
147 | /** | 175 | /** |
148 | * Handle to hang up or activate. | 176 | * This phone call is currently active. |
149 | */ | 177 | */ |
150 | struct GNUNET_CONVERSATION_Caller *caller; | 178 | OUT_STATE_ACTIVE, |
151 | 179 | ||
152 | /** | 180 | /** |
153 | * Handle to call currently selected in list | 181 | * This phone call is currently suspended. |
154 | */ | 182 | */ |
155 | struct GNUNET_CONVERSATION_Caller *caller_selected; | 183 | OUT_STATE_SUSPENDED |
184 | |||
185 | }; | ||
186 | |||
187 | |||
188 | /** | ||
189 | * List of incoming calls | ||
190 | */ | ||
191 | struct IncomingCall | ||
192 | { | ||
193 | |||
194 | /** | ||
195 | * Handle to hang up or activate. | ||
196 | */ | ||
197 | struct GNUNET_CONVERSATION_Caller *caller; | ||
156 | 198 | ||
157 | /** | 199 | /** |
158 | * String identifying the caller. | 200 | * String identifying the caller. |
@@ -160,22 +202,55 @@ struct CallList | |||
160 | char *caller_id; | 202 | char *caller_id; |
161 | 203 | ||
162 | /** | 204 | /** |
205 | * Location of this call in the list. | ||
206 | */ | ||
207 | GtkTreeRowReference *rr; | ||
208 | |||
209 | /** | ||
163 | * Unique number of the caller. | 210 | * Unique number of the caller. |
164 | */ | 211 | */ |
165 | unsigned int caller_num; | 212 | unsigned int caller_num; |
166 | 213 | ||
214 | /** | ||
215 | * State for this call. | ||
216 | */ | ||
217 | enum InCallState state; | ||
218 | |||
167 | }; | 219 | }; |
168 | 220 | ||
169 | 221 | ||
170 | /** | 222 | /** |
171 | * | 223 | * Information we keep for an outgoing call. |
172 | */ | 224 | */ |
173 | static struct GNUNET_CONVERSATION_Caller *caller_selected; | 225 | struct OutgoingCall |
226 | { | ||
174 | 227 | ||
175 | /** | 228 | /** |
176 | * | 229 | * Associated conversation handle. |
177 | */ | 230 | */ |
178 | static struct GNUNET_CONVERSATION_Call *call_selected; | 231 | struct GNUNET_CONVERSATION_Call *call; |
232 | |||
233 | /** | ||
234 | * Name of conversation partner. | ||
235 | */ | ||
236 | char *peer_name; | ||
237 | |||
238 | /** | ||
239 | * Location of this call in the list. | ||
240 | */ | ||
241 | GtkTreeRowReference *rr; | ||
242 | |||
243 | /** | ||
244 | * Unique number of the caller. | ||
245 | */ | ||
246 | unsigned int caller_num; | ||
247 | |||
248 | /** | ||
249 | * State for this call. | ||
250 | */ | ||
251 | enum OutCallState state; | ||
252 | |||
253 | }; | ||
179 | 254 | ||
180 | 255 | ||
181 | /** | 256 | /** |
@@ -189,84 +264,91 @@ static GtkListStore *active_liststore; | |||
189 | static GtkTreeView *active_treeview; | 264 | static GtkTreeView *active_treeview; |
190 | 265 | ||
191 | /** | 266 | /** |
192 | * Unique number of call (outgoing) | ||
193 | */ | ||
194 | static unsigned int call_counter; | ||
195 | |||
196 | /** | ||
197 | * Counts the number of incoming calls we have had so far. | ||
198 | */ | ||
199 | static unsigned int caller_num_gen; | ||
200 | |||
201 | /** | ||
202 | * Phone handle | 267 | * Phone handle |
203 | */ | 268 | */ |
204 | static struct GNUNET_CONVERSATION_Phone *phone; | 269 | static struct GNUNET_CONVERSATION_Phone *phone; |
205 | 270 | ||
206 | /** | 271 | /** |
207 | * Call handle (for active outgoing call). | 272 | * Our speaker. |
208 | */ | 273 | */ |
209 | static struct GNUNET_CONVERSATION_Call *call; | 274 | static struct GNUNET_SPEAKER_Handle *speaker; |
210 | 275 | ||
211 | /** | 276 | /** |
212 | * Caller handle (for active incoming call). | 277 | * Our microphone. |
213 | */ | 278 | */ |
214 | static struct CallList *cl_active; | 279 | static struct GNUNET_MICROPHONE_Handle *mic; |
215 | 280 | ||
216 | /** | 281 | /** |
217 | * Head of calls waiting to be accepted. | 282 | * Our phone's current state. |
218 | */ | 283 | */ |
219 | static struct CallList *cl_head; | 284 | static enum PhoneState phone_state; |
220 | 285 | ||
221 | /** | ||
222 | * Tail of calls waiting to be accepted. | ||
223 | */ | ||
224 | static struct CallList *cl_tail; | ||
225 | 286 | ||
226 | /** | 287 | /** |
227 | * Our speaker. | 288 | * Counts the number of incoming calls we have had so far. |
228 | */ | 289 | */ |
229 | static struct GNUNET_SPEAKER_Handle *speaker; | 290 | static unsigned int caller_num_gen; |
230 | 291 | ||
231 | /** | 292 | /** |
232 | * Our microphone. | 293 | * Unique number of call (outgoing) |
233 | */ | 294 | */ |
234 | static struct GNUNET_MICROPHONE_Handle *mic; | 295 | static unsigned int call_counter; |
235 | 296 | ||
236 | /** | 297 | /** |
237 | * Our phone's current state. | 298 | * Number of incoming calls that are currently ringing. |
238 | */ | 299 | */ |
239 | static enum PhoneState phone_state; | 300 | static unsigned int in_ring_counter; |
240 | 301 | ||
241 | /** | 302 | /** |
242 | * Our call's current state. | 303 | * Caller handle (for active incoming call, or NULL). |
243 | */ | 304 | */ |
244 | static enum CallState call_state; | 305 | static struct IncomingCall *active_in; |
245 | 306 | ||
246 | /** | 307 | /** |
247 | * Name of conversation partner (if any). | 308 | * Call handle (of the active outgoing call, or NULL). |
248 | */ | 309 | */ |
249 | static char *peer_name; | 310 | static struct OutgoingCall *active_out; |
311 | |||
250 | 312 | ||
251 | /** | 313 | /** |
252 | * GNS address for this phone. | 314 | * The "add contact" (or "> contact") button. |
253 | */ | 315 | */ |
254 | static char *address; | ||
255 | |||
256 | static GtkWidget *b_add_contact; | 316 | static GtkWidget *b_add_contact; |
257 | 317 | ||
318 | /** | ||
319 | * The "accept" button. | ||
320 | */ | ||
258 | static GtkWidget *b_accept; | 321 | static GtkWidget *b_accept; |
259 | 322 | ||
323 | /** | ||
324 | * The "refuse" button. | ||
325 | */ | ||
260 | static GtkWidget *b_refuse; | 326 | static GtkWidget *b_refuse; |
261 | 327 | ||
262 | static GtkWidget *b_suspend; // pause | 328 | /** |
329 | * The "pause" button. | ||
330 | */ | ||
331 | static GtkWidget *b_suspend; | ||
263 | 332 | ||
333 | /** | ||
334 | * The "resume" button. | ||
335 | */ | ||
264 | static GtkWidget *b_resume; | 336 | static GtkWidget *b_resume; |
265 | 337 | ||
266 | static GtkWidget *b_call; // connect | 338 | /** |
339 | * The "connect" button. | ||
340 | */ | ||
341 | static GtkWidget *b_call; | ||
267 | 342 | ||
268 | static GtkWidget *b_hangup; // disconnect up | 343 | /** |
344 | * The "disconnect" button. | ||
345 | */ | ||
346 | static GtkWidget *b_hangup; | ||
269 | 347 | ||
348 | /** | ||
349 | * Our address entry. | ||
350 | */ | ||
351 | static GtkEntry *address_entry; | ||
270 | 352 | ||
271 | 353 | ||
272 | /** | 354 | /** |
@@ -277,249 +359,41 @@ static GtkWidget *b_hangup; // disconnect up | |||
277 | static void | 359 | static void |
278 | do_status () | 360 | do_status () |
279 | { | 361 | { |
280 | switch (phone_state) | 362 | if ( (NULL == active_in) && |
363 | (NULL == active_out) && | ||
364 | (0 != in_ring_counter) ) | ||
281 | { | 365 | { |
282 | case PS_LOOKUP_EGO: | 366 | GCG_update_status_bar (_("The phone is ringing (%u calls waiting)"), |
283 | GCG_update_status_bar ("%s", | 367 | in_ring_counter); |
284 | _("Phone inactive: no ego selected for the caller ID.")); | 368 | GCG_set_status_icon ("gnunet-conversation-gtk-tray-call-incoming"); |
285 | GCG_set_status_icon ("gnunet-conversation-gtk-tray-pending"); | 369 | return; |
286 | break; | ||
287 | case PS_LISTEN: | ||
288 | GCG_update_status_bar ("%s", | ||
289 | _("We are listening for incoming calls")); | ||
290 | GCG_set_status_icon ("gnunet-conversation-gtk-tray-available"); | ||
291 | break; | ||
292 | case PS_ACCEPTED: | ||
293 | GCG_update_status_bar (_("You are having a conversation with `%s'.\n"), | ||
294 | peer_name); | ||
295 | GCG_set_status_icon ("gnunet-conversation-call-active"); | ||
296 | break; | ||
297 | case PS_ERROR: | ||
298 | GCG_update_status_bar (_("We had an internal error setting up our phone line. You can still make calls.")); | ||
299 | GCG_set_status_icon ("gnunet-conversation-offline"); | ||
300 | break; | ||
301 | } | 370 | } |
302 | if (NULL != call) | 371 | if ( (NULL == active_in) && |
372 | (NULL == active_out) && | ||
373 | (PS_LISTEN == phone_state) ) | ||
303 | { | 374 | { |
304 | switch (call_state) | 375 | GCG_update_status_bar ("%s", |
305 | { | 376 | _("We are listening for incoming calls")); |
306 | case CS_RESOLVING: | 377 | GCG_set_status_icon ("gnunet-conversation-gtk-tray-available"); |
307 | GCG_update_status_bar (_("We are trying to find the network address to call `%s'."), | ||
308 | peer_name); | ||
309 | GCG_set_status_icon ("gnunet-conversation-gtk-tray-call-pending"); | ||
310 | break; | ||
311 | case CS_RINGING: | ||
312 | GCG_update_status_bar (_("We are calling `%s', his phone should be ringing."), | ||
313 | peer_name); | ||
314 | GCG_set_status_icon ("gnunet-conversation-gtk-tray-call-ringing"); | ||
315 | break; | ||
316 | case CS_CONNECTED: | ||
317 | GCG_update_status_bar (_("You are having a conversation with `%s'."), | ||
318 | peer_name); | ||
319 | GCG_set_status_icon ("gnunet-conversation-gtk-tray-call-active"); | ||
320 | break; | ||
321 | case CS_SUSPENDED: | ||
322 | GCG_update_status_bar (_("Conversation suspended, you can accept or initiate another call now."), | ||
323 | peer_name); | ||
324 | GCG_set_status_icon ("gnunet-conversation-gtk-tray-call-suspended"); | ||
325 | break; | ||
326 | } | ||
327 | } | 378 | } |
328 | if ( ( (NULL == call) || | ||
329 | (CS_SUSPENDED == call_state) ) && | ||
330 | (NULL != cl_head) && | ||
331 | ( (cl_head != cl_active) || | ||
332 | (cl_head != cl_tail) ) ) | ||
333 | GCG_set_status_icon ("gnunet-conversation-gtk-tray-call-incoming"); | ||
334 | } | 379 | } |
335 | 380 | ||
336 | 381 | ||
337 | |||
338 | /** | 382 | /** |
339 | * @brief print info for currently selected call | 383 | * Check if the conditions are met for the "call" button to |
384 | * be sensitive again. Those conditions are that we must | ||
385 | * have a phone that is ready to "listen" (no error or active | ||
386 | * call), and that some address text is in the address entry. | ||
340 | */ | 387 | */ |
341 | static void | 388 | static void |
342 | print_call_info () | 389 | check_call_sensitivity () |
343 | { | 390 | { |
344 | GtkTreeIter gtkiter; | 391 | gboolean sens; |
345 | gboolean valid; | ||
346 | gint row_count = 0; | ||
347 | 392 | ||
348 | valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (active_liststore), | 393 | sens = (PS_LISTEN == phone_state); |
349 | >kiter); | 394 | if (0 == strlen (gtk_entry_get_text (address_entry))) |
350 | if (! valid) | 395 | sens = FALSE; |
351 | GNUNET_break(0); | 396 | gtk_widget_set_sensitive (b_call, sens); |
352 | |||
353 | while (valid) | ||
354 | { | ||
355 | gchar *str_data; | ||
356 | gint int_data; | ||
357 | gpointer cl_caller; | ||
358 | gpointer cl_call; | ||
359 | |||
360 | gtk_tree_model_get (GTK_TREE_MODEL (active_liststore), | ||
361 | >kiter, | ||
362 | AL_caller, &cl_caller, | ||
363 | AL_caller_id, &str_data, | ||
364 | AL_caller_num, &int_data, | ||
365 | AL_call, &cl_call, | ||
366 | -1); | ||
367 | if (call_selected == cl_call) | ||
368 | { | ||
369 | GCG_log (_("info for active outgoing call:%s number: %u row: %u"), | ||
370 | str_data, | ||
371 | int_data, | ||
372 | row_count); | ||
373 | break; | ||
374 | } | ||
375 | g_free (str_data); | ||
376 | row_count++; | ||
377 | valid = gtk_tree_model_iter_next (GTK_TREE_MODEL(active_liststore), >kiter); | ||
378 | } | ||
379 | } | ||
380 | |||
381 | |||
382 | /** | ||
383 | * @brief sets caller_selected, and enables or disables the active call list buttons | ||
384 | */ | ||
385 | static void | ||
386 | update_active_call_list_buttons () | ||
387 | { | ||
388 | gchar *caller_id; | ||
389 | gpointer cl_caller; | ||
390 | gpointer cl_call; | ||
391 | gint cl_caller_state; | ||
392 | gint cl_type; | ||
393 | //gint cl_caller_type; | ||
394 | GtkTreeSelection *active_selection; | ||
395 | GtkTreeIter gcl_selected; | ||
396 | // active_liststore_selection = GCG_get_main_window_object(ml,"GNUNET_CONVERSATION_GTK_active_calls_selection"); | ||
397 | |||
398 | // reset references to selected call/caller | ||
399 | //caller_selected = NULL; | ||
400 | //call_selected = NULL; | ||
401 | GCG_log("reset caller selected"); | ||
402 | active_selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (active_treeview)); | ||
403 | if (gtk_tree_selection_get_selected (active_selection, | ||
404 | NULL, | ||
405 | &gcl_selected)) | ||
406 | { | ||
407 | // get selected call | ||
408 | gtk_tree_model_get (GTK_TREE_MODEL(active_liststore), &gcl_selected, | ||
409 | AL_caller, &cl_caller, // reference to incoming call | ||
410 | AL_caller_id, &caller_id, | ||
411 | AL_caller_state, &cl_caller_state, | ||
412 | AL_type, &cl_type, | ||
413 | AL_call, &cl_call, // reference to outgoing call | ||
414 | -1); | ||
415 | // check if selected call is a incoming or outgoing call | ||
416 | switch (cl_type) | ||
417 | { | ||
418 | case CALL_IN: | ||
419 | call_selected = NULL; | ||
420 | caller_selected = cl_caller; | ||
421 | GNUNET_break (NULL != caller_selected); | ||
422 | break; | ||
423 | case CALL_OUT: | ||
424 | caller_selected = NULL; | ||
425 | call_selected = cl_call; | ||
426 | GCG_log("outgoing selected"); | ||
427 | GNUNET_break (NULL != call_selected); | ||
428 | break; | ||
429 | default: | ||
430 | GNUNET_break(0); | ||
431 | break; | ||
432 | } | ||
433 | gtk_widget_show(GTK_WIDGET(GCG_get_main_window_object("GNUNET_GTK_conversation_active_call_list_buttons"))); | ||
434 | GCG_log("caller state: %u phone_state: %u", | ||
435 | cl_caller_state, | ||
436 | phone_state); | ||
437 | switch (cl_caller_state) | ||
438 | { | ||
439 | /* buttons: | ||
440 | * contact | ||
441 | * accept | ||
442 | * hangup | ||
443 | * suspend | ||
444 | * resume | ||
445 | * | ||
446 | * TODO: check if there is incoming or outgoing call, | ||
447 | * disable resume and accept buttons. | ||
448 | * or suspend that other call | ||
449 | */ | ||
450 | case CT_active: | ||
451 | // hangup, pause | ||
452 | //GCG_log("CT_active state: %u ",cl_caller_state); | ||
453 | gtk_widget_set_sensitive (b_add_contact, TRUE); | ||
454 | gtk_widget_set_sensitive (b_accept, FALSE); | ||
455 | gtk_widget_set_sensitive (b_hangup, TRUE); | ||
456 | gtk_widget_set_sensitive (b_suspend, TRUE); | ||
457 | gtk_widget_set_sensitive (b_resume, FALSE); | ||
458 | break; | ||
459 | case CT_ringing: | ||
460 | // pickup, phonebook | ||
461 | //GCG_log("CT_ring show button"); | ||
462 | gtk_widget_set_sensitive (b_add_contact, TRUE); | ||
463 | if (phone_state == PS_LISTEN) | ||
464 | { | ||
465 | gtk_widget_set_sensitive (b_accept, TRUE); | ||
466 | } | ||
467 | else | ||
468 | { | ||
469 | gtk_widget_set_sensitive (b_accept, FALSE); | ||
470 | } | ||
471 | gtk_widget_set_sensitive (b_hangup, FALSE); | ||
472 | gtk_widget_set_sensitive (b_suspend, FALSE); | ||
473 | gtk_widget_set_sensitive (b_resume, FALSE); | ||
474 | break; | ||
475 | case CT_rejected: | ||
476 | //add to phonebook | ||
477 | //GCG_log("CT_rejected "); | ||
478 | gtk_widget_set_sensitive (b_add_contact, TRUE); | ||
479 | gtk_widget_set_sensitive (b_accept, FALSE); | ||
480 | gtk_widget_set_sensitive (b_hangup, FALSE); | ||
481 | gtk_widget_set_sensitive (b_suspend, FALSE); | ||
482 | gtk_widget_set_sensitive (b_resume, FALSE); | ||
483 | break; | ||
484 | case CT_suspended: | ||
485 | // resume, hangup | ||
486 | //GCG_log("CT_suspended "); | ||
487 | gtk_widget_set_sensitive (b_add_contact, TRUE); | ||
488 | gtk_widget_set_sensitive (b_accept, FALSE); | ||
489 | gtk_widget_set_sensitive (b_hangup, TRUE); | ||
490 | gtk_widget_set_sensitive (b_suspend, FALSE); | ||
491 | if (phone_state == PS_LISTEN) | ||
492 | { | ||
493 | GCG_log("enable resume button"); | ||
494 | gtk_widget_set_sensitive (b_resume, TRUE); | ||
495 | } | ||
496 | else | ||
497 | { | ||
498 | GCG_log("do not disable resume button (for test)"); | ||
499 | gtk_widget_set_sensitive (b_resume, TRUE); | ||
500 | } | ||
501 | break; | ||
502 | case CT_other: | ||
503 | //add to phonebook | ||
504 | //GCG_log("CT_rejected "); | ||
505 | gtk_widget_set_sensitive (b_add_contact, TRUE); | ||
506 | gtk_widget_set_sensitive (b_accept, TRUE); | ||
507 | gtk_widget_set_sensitive (b_hangup, TRUE); | ||
508 | gtk_widget_set_sensitive (b_suspend, TRUE); | ||
509 | gtk_widget_set_sensitive (b_resume, TRUE); | ||
510 | break; | ||
511 | |||
512 | default: | ||
513 | GNUNET_break(0); | ||
514 | break; | ||
515 | } | ||
516 | print_call_info(); | ||
517 | } | ||
518 | else | ||
519 | { | ||
520 | GCG_log("nothing selected"); | ||
521 | //gtk_widget_hide(GTK_WIDGET(GCG_get_main_window_object("GNUNET_GTK_conversation_active_call_list_buttons" ))); | ||
522 | } | ||
523 | } | 397 | } |
524 | 398 | ||
525 | 399 | ||
@@ -529,200 +403,85 @@ update_active_call_list_buttons () | |||
529 | void | 403 | void |
530 | gnunet_conversation_gtk_active_calls_treeview_selection_changed_cb () | 404 | gnunet_conversation_gtk_active_calls_treeview_selection_changed_cb () |
531 | { | 405 | { |
532 | update_active_call_list_buttons(); | 406 | // FIXME |
533 | } | ||
534 | |||
535 | |||
536 | static void | ||
537 | disable_list_buttons () | ||
538 | { | ||
539 | gtk_widget_set_sensitive (b_add_contact, FALSE); | ||
540 | gtk_widget_set_sensitive (b_accept, FALSE); | ||
541 | gtk_widget_set_sensitive (b_hangup, FALSE); | ||
542 | gtk_widget_set_sensitive (b_suspend, FALSE); | ||
543 | gtk_widget_set_sensitive (b_resume, FALSE); | ||
544 | } | 407 | } |
545 | 408 | ||
546 | 409 | ||
547 | /** | 410 | /** |
548 | * set state of outgoing call | 411 | * Set state of outgoing call. |
412 | * | ||
413 | * @param oc outgoing call to change state of | ||
414 | * @param state new state of the call | ||
549 | */ | 415 | */ |
550 | static void | 416 | static void |
551 | set_outgoing_call_state (struct GNUNET_CONVERSATION_Call *call, | 417 | set_outgoing_call_state (struct OutgoingCall *oc, |
552 | int state) | 418 | enum OutCallState state) |
553 | { | 419 | { |
554 | GtkTreeIter gtkiter; | 420 | GtkTreePath *path; |
555 | gint valid = 0; | 421 | GtkTreeIter iter; |
556 | gint cl_type; | 422 | |
557 | 423 | path = gtk_tree_row_reference_get_path (oc->rr); | |
558 | valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (active_liststore), | 424 | GNUNET_assert (gtk_tree_model_get_iter (GTK_TREE_MODEL (active_liststore), |
559 | >kiter); | 425 | &iter, |
560 | if (!valid) | 426 | path)); |
561 | GNUNET_break(0); | 427 | gtk_tree_path_free (path); |
562 | while (valid) | 428 | switch (state) |
563 | { | 429 | { |
564 | gchar *cl_caller_id; | 430 | case OUT_STATE_NONE: |
565 | gint cl_caller_num; | 431 | gtk_list_store_remove (active_liststore, |
566 | gpointer cl_call; | 432 | &iter); |
567 | 433 | return; | |
568 | gtk_tree_model_get ( GTK_TREE_MODEL( active_liststore ), >kiter, | 434 | case OUT_STATE_RESOLVING: |
569 | AL_call, &cl_call, | 435 | break; |
570 | AL_caller_id,&cl_caller_id, | 436 | case OUT_STATE_RINGING: |
571 | AL_caller_num,&cl_caller_num, | 437 | break; |
572 | AL_type, &cl_type, | 438 | case OUT_STATE_ACTIVE: |
573 | -1); | 439 | break; |
574 | if (cl_type == CALL_OUT) | 440 | case OUT_STATE_SUSPENDED: |
575 | { | 441 | break; |
576 | if (call == NULL) // function called by phone event handler | ||
577 | { | ||
578 | GCG_log("event handler"); | ||
579 | gtk_list_store_set(active_liststore, >kiter, | ||
580 | AL_call_state, state, | ||
581 | -1); | ||
582 | switch (state) | ||
583 | { | ||
584 | /** | ||
585 | * We are the caller and are now ringing the other party (GNS lookup | ||
586 | * succeeded). | ||
587 | */ | ||
588 | case GNUNET_CONVERSATION_EC_CALL_RINGING: | ||
589 | break; | ||
590 | /** | ||
591 | * We are the caller and are now ready to talk as the callee picked up. | ||
592 | */ | ||
593 | case GNUNET_CONVERSATION_EC_CALL_PICKED_UP: | ||
594 | break; | ||
595 | /** | ||
596 | * We are the caller and failed to locate a phone record in GNS. | ||
597 | * After this invocation, the respective call handle will be | ||
598 | * automatically destroyed and the client must no longer call | ||
599 | * #GNUNET_CONVERSATION_call_stop or any other function on the | ||
600 | * call object. | ||
601 | */ | ||
602 | case GNUNET_CONVERSATION_EC_CALL_GNS_FAIL: | ||
603 | gtk_list_store_remove(active_liststore,>kiter); | ||
604 | disable_list_buttons(); | ||
605 | break; | ||
606 | /** | ||
607 | * We are the caller and the callee called | ||
608 | * #GNUNET_CONVERSATION_caller_hang_up. After this invocation, the | ||
609 | * respective call handle will be automatically destroyed and the | ||
610 | * client must no longer call #GNUNET_CONVERSATION_call_stop. | ||
611 | */ | ||
612 | case GNUNET_CONVERSATION_EC_CALL_HUNG_UP: | ||
613 | gtk_list_store_remove(active_liststore,>kiter); | ||
614 | disable_list_buttons(); | ||
615 | break; | ||
616 | /** | ||
617 | * We are the caller and the callee suspended the call. Note that | ||
618 | * both sides can independently suspend and resume calls; a call is | ||
619 | * only "working" of both sides are active. | ||
620 | */ | ||
621 | case GNUNET_CONVERSATION_EC_CALL_SUSPENDED: | ||
622 | break; | ||
623 | /** | ||
624 | * We are the caller and the callee suspended the call. Note that | ||
625 | * both sides can independently suspend and resume calls; a call is | ||
626 | * only "working" of both sides are active. | ||
627 | */ | ||
628 | case GNUNET_CONVERSATION_EC_CALL_RESUMED: | ||
629 | break; | ||
630 | /** | ||
631 | * We had an error handing the call, and are now restarting it | ||
632 | * (back to lookup). This happens, for example, if the peer | ||
633 | * is restarted during a call. | ||
634 | */ | ||
635 | case GNUNET_CONVERSATION_EC_CALL_ERROR: | ||
636 | break; | ||
637 | default: | ||
638 | break; | ||
639 | } | ||
640 | } | ||
641 | else if (call == cl_call) // function called for specific call | ||
642 | { | ||
643 | //GCG_log (_("setting state for call:%u row: %u state: %u"),cl_caller_num,row_count,state); | ||
644 | |||
645 | switch (state) | ||
646 | { | ||
647 | case CT_hangup: | ||
648 | //GCG_log("remove line cause hangup"); | ||
649 | gtk_list_store_remove(active_liststore,>kiter); | ||
650 | disable_list_buttons(); | ||
651 | break; | ||
652 | case CT_rejected: | ||
653 | //GCG_log("remove line cause rejected"); | ||
654 | gtk_list_store_remove(active_liststore,>kiter); | ||
655 | disable_list_buttons(); | ||
656 | break; | ||
657 | default: | ||
658 | gtk_list_store_set(active_liststore, >kiter, | ||
659 | AL_caller_state, state, | ||
660 | -1); | ||
661 | break; | ||
662 | } | ||
663 | } | ||
664 | } | ||
665 | g_free (cl_caller_id); | ||
666 | valid = gtk_tree_model_iter_next (GTK_TREE_MODEL(active_liststore), >kiter); | ||
667 | } | 442 | } |
668 | GCG_update_status_bar (""); | 443 | gtk_list_store_set (active_liststore, |
444 | &iter, | ||
445 | GCG_PHONE_LS_CALL_STATE, state, | ||
446 | -1); | ||
669 | } | 447 | } |
670 | 448 | ||
671 | 449 | ||
672 | /** | 450 | /** |
673 | * set call state of a incoming call | 451 | * Set call state of a incoming call |
452 | * | ||
453 | * @param ic incoming call to change state of | ||
454 | * @param state new state of the call | ||
674 | */ | 455 | */ |
675 | static void | 456 | static void |
676 | set_incoming_call_state (struct GNUNET_CONVERSATION_Caller *caller, | 457 | set_incoming_call_state (struct IncomingCall *ic, |
677 | int state) | 458 | enum InCallState state) |
678 | { | 459 | { |
679 | GtkTreeIter gtkiter; | 460 | GtkTreePath *path; |
680 | gint valid = 0; | 461 | GtkTreeIter iter; |
681 | 462 | ||
682 | valid = gtk_tree_model_get_iter_first( GTK_TREE_MODEL( active_liststore ), >kiter ); | 463 | path = gtk_tree_row_reference_get_path (ic->rr); |
683 | if (!valid) | 464 | GNUNET_assert (gtk_tree_model_get_iter (GTK_TREE_MODEL (active_liststore), |
684 | GNUNET_break(0); | 465 | &iter, |
685 | while (valid) | 466 | path)); |
467 | gtk_tree_path_free (path); | ||
468 | switch (state) | ||
686 | { | 469 | { |
687 | gchar *cl_caller_id; | 470 | case IN_STATE_NONE: |
688 | gint cl_caller_num; | 471 | gtk_list_store_remove (active_liststore, |
689 | gpointer cl_caller; | 472 | &iter); |
690 | 473 | return; | |
691 | gtk_tree_model_get (GTK_TREE_MODEL (active_liststore ), | 474 | case IN_STATE_RINGING: |
692 | >kiter, | 475 | break; |
693 | AL_caller, &cl_caller, | 476 | case IN_STATE_CONNECTED: |
694 | AL_caller_id, &cl_caller_id, | 477 | break; |
695 | AL_caller_num, &cl_caller_num, | 478 | case IN_STATE_SUSPENDED: |
696 | -1); | 479 | break; |
697 | if (caller == cl_caller) | ||
698 | { | ||
699 | switch (state) | ||
700 | { | ||
701 | case CT_hangup: | ||
702 | //GCG_log("remove line cause hangup"); | ||
703 | gtk_list_store_remove (active_liststore, | ||
704 | >kiter); | ||
705 | disable_list_buttons (); | ||
706 | break; | ||
707 | case CT_rejected: | ||
708 | //GCG_log("remove line cause rejected"); | ||
709 | gtk_list_store_remove (active_liststore, | ||
710 | >kiter); | ||
711 | disable_list_buttons (); | ||
712 | break; | ||
713 | default: | ||
714 | gtk_list_store_set (active_liststore, | ||
715 | >kiter, | ||
716 | AL_caller_state, state, | ||
717 | -1); | ||
718 | break; | ||
719 | } | ||
720 | } | ||
721 | g_free (cl_caller_id); | ||
722 | valid = gtk_tree_model_iter_next (GTK_TREE_MODEL(active_liststore), | ||
723 | >kiter); | ||
724 | } | 480 | } |
725 | GCG_update_status_bar(""); | 481 | gtk_list_store_set (active_liststore, |
482 | &iter, | ||
483 | GCG_PHONE_LS_CALLER_STATE, state, | ||
484 | -1); | ||
726 | } | 485 | } |
727 | 486 | ||
728 | 487 | ||
@@ -740,61 +499,59 @@ phone_event_handler (void *cls, | |||
740 | struct GNUNET_CONVERSATION_Caller *caller, | 499 | struct GNUNET_CONVERSATION_Caller *caller, |
741 | const char *caller_id) | 500 | const char *caller_id) |
742 | { | 501 | { |
743 | GtkTreeIter gtkiter; | 502 | GtkTreeIter iter; |
744 | GtkTreeIter gtkiter1; | ||
745 | gboolean valid; | 503 | gboolean valid; |
746 | struct CallList *cl; | 504 | struct IncomingCall *ic; |
747 | 505 | ||
748 | switch (code) | 506 | switch (code) |
749 | { | 507 | { |
750 | case GNUNET_CONVERSATION_EC_PHONE_RING: | 508 | case GNUNET_CONVERSATION_EC_PHONE_RING: |
751 | caller_num_gen++; | 509 | ic = GNUNET_new (struct IncomingCall); |
510 | ic->caller = caller; | ||
511 | ic->caller_id = GNUNET_strdup (caller_id); | ||
512 | ic->caller_num = caller_num_gen++; | ||
513 | gtk_list_store_insert_with_values (active_liststore, | ||
514 | &iter, | ||
515 | -1, | ||
516 | GCG_PHONE_LS_CALLER_ID, caller_id, | ||
517 | GCG_PHONE_LS_CALLER, ic, | ||
518 | GCG_PHONE_LS_CALLER_NUM, caller_num_gen, | ||
519 | GCG_PHONE_LS_CALLER_STATE, IN_STATE_RINGING, | ||
520 | GCG_PHONE_LS_TYPE, CALL_IN, | ||
521 | -1); | ||
522 | // FIXME: initialize ic->rr | ||
752 | GCG_log (_("A Incoming call from `%s' with number %u\n"), | 523 | GCG_log (_("A Incoming call from `%s' with number %u\n"), |
753 | caller_id, | 524 | caller_id, |
754 | caller_num_gen); | 525 | caller_num_gen); |
755 | cl = GNUNET_new (struct CallList); | ||
756 | cl->caller = caller; | ||
757 | cl->caller_id = GNUNET_strdup (caller_id); | ||
758 | cl->caller_num = caller_num_gen; | ||
759 | GNUNET_CONTAINER_DLL_insert (cl_head, cl_tail, cl); | ||
760 | gtk_list_store_append (active_liststore, | ||
761 | >kiter); | ||
762 | gtk_list_store_set (active_liststore, | ||
763 | >kiter, | ||
764 | AL_caller_id, caller_id, | ||
765 | AL_caller, caller, | ||
766 | AL_caller_num, caller_num_gen, | ||
767 | AL_caller_state, CT_ringing, | ||
768 | AL_type, CALL_IN, | ||
769 | -1); | ||
770 | break; | 526 | break; |
771 | case GNUNET_CONVERSATION_EC_PHONE_HUNG_UP: | 527 | case GNUNET_CONVERSATION_EC_PHONE_HUNG_UP: |
772 | valid = gtk_tree_model_get_iter_first( GTK_TREE_MODEL( active_liststore ), >kiter1 ); | 528 | valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (active_liststore), |
773 | if (!valid) | 529 | &iter); |
774 | GNUNET_break(0); | 530 | GNUNET_break (valid); |
775 | while (valid) | 531 | while (valid) |
776 | { | 532 | { |
777 | gchar *str_data; | 533 | gchar *str_data; |
778 | gint int_data; | 534 | gint int_data; |
779 | gpointer cl_caller; | 535 | struct IncomingCall *ic; |
780 | 536 | ||
781 | gtk_tree_model_get (GTK_TREE_MODEL(active_liststore), | 537 | gtk_tree_model_get (GTK_TREE_MODEL (active_liststore), |
782 | >kiter1, | 538 | &iter, |
783 | AL_caller, &cl_caller, | 539 | GCG_PHONE_LS_CALLER, &ic, |
784 | AL_caller_id, &str_data, | 540 | GCG_PHONE_LS_CALLER_ID, &str_data, |
785 | AL_caller_num, &int_data, | 541 | GCG_PHONE_LS_CALLER_NUM, &int_data, |
786 | -1); | 542 | -1); |
787 | if (caller == cl_caller) | 543 | if (caller == ic->caller) |
788 | { | 544 | { |
789 | GCG_log (_("phone hung up:%s number: %u "), | 545 | GCG_log (_("phone hung up:%s number: %u "), |
790 | str_data, | 546 | str_data, |
791 | int_data); | 547 | int_data); |
792 | set_incoming_call_state (caller, | 548 | set_incoming_call_state (ic, |
793 | CT_rejected); | 549 | IN_STATE_NONE); |
794 | break; | 550 | break; |
795 | } | 551 | } |
796 | g_free (str_data); | 552 | g_free (str_data); |
797 | valid = gtk_tree_model_iter_next (GTK_TREE_MODEL(active_liststore), >kiter1); | 553 | valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (active_liststore), |
554 | &iter); | ||
798 | } | 555 | } |
799 | phone_state = PS_LISTEN; | 556 | phone_state = PS_LISTEN; |
800 | break; | 557 | break; |
@@ -813,7 +570,7 @@ static void | |||
813 | caller_event_handler (void *cls, | 570 | caller_event_handler (void *cls, |
814 | enum GNUNET_CONVERSATION_CallerEventCode code) | 571 | enum GNUNET_CONVERSATION_CallerEventCode code) |
815 | { | 572 | { |
816 | struct CallList *cl = cls; | 573 | struct IncomingCall *cl = cls; |
817 | 574 | ||
818 | if (NULL == cl) | 575 | if (NULL == cl) |
819 | { | 576 | { |
@@ -824,12 +581,16 @@ caller_event_handler (void *cls, | |||
824 | { | 581 | { |
825 | case GNUNET_CONVERSATION_EC_CALLER_SUSPEND: | 582 | case GNUNET_CONVERSATION_EC_CALLER_SUSPEND: |
826 | //TODO: should this be cls? not cl->caller | 583 | //TODO: should this be cls? not cl->caller |
827 | set_incoming_call_state(cl->caller,CT_suspended); | 584 | set_incoming_call_state (cl, |
828 | GCG_log (_("Call from `%s' suspended by other user\n"), cl->caller_id); | 585 | IN_STATE_SUSPENDED); |
586 | GCG_log (_("Call from `%s' suspended by other user\n"), | ||
587 | cl->caller_id); | ||
829 | break; | 588 | break; |
830 | case GNUNET_CONVERSATION_EC_CALLER_RESUME: | 589 | case GNUNET_CONVERSATION_EC_CALLER_RESUME: |
831 | set_incoming_call_state(cl->caller,CT_active); | 590 | set_incoming_call_state(cl, |
832 | GCG_log (_("Call from `%s' resumed by other user\n"), cl->caller_id); | 591 | IN_STATE_CONNECTED); |
592 | GCG_log (_("Call from `%s' resumed by other user\n"), | ||
593 | cl->caller_id); | ||
833 | break; | 594 | break; |
834 | } | 595 | } |
835 | do_status(); | 596 | do_status(); |
@@ -837,264 +598,125 @@ caller_event_handler (void *cls, | |||
837 | 598 | ||
838 | 599 | ||
839 | /** | 600 | /** |
840 | * Start our phone. | 601 | * The "accept" button was clicked. Accept selected incoming call. |
602 | * | ||
603 | * @param button the button | ||
604 | * @param user_data builder (unused) | ||
841 | */ | 605 | */ |
842 | static void | 606 | void |
843 | start_phone () | 607 | GNUNET_CONVERSATION_GTK_on_accept_clicked (GtkButton *button, |
608 | gpointer user_data) | ||
844 | { | 609 | { |
845 | struct GNUNET_GNSRECORD_Data rd; | 610 | struct IncomingCall *ic; |
846 | struct GNUNET_IDENTITY_Ego *caller_id; | ||
847 | 611 | ||
848 | caller_id = GCG_EGOS_get_selected_ego (); | 612 | if ( (NULL != active_in) || |
849 | if (NULL == caller_id) | 613 | (NULL != active_out) || |
614 | (PS_LISTEN != phone_state) ) | ||
850 | { | 615 | { |
851 | GCG_log ("%s\n", | 616 | /* accept button should not have been sensitive! */ |
852 | _("No ego selected, phone is now down.")); | 617 | GNUNET_break (0); |
853 | phone_state = PS_LOOKUP_EGO; | ||
854 | do_status(); | ||
855 | return; | ||
856 | } | ||
857 | phone = | ||
858 | GNUNET_CONVERSATION_phone_create (GCG_get_configuration (), | ||
859 | caller_id, | ||
860 | &phone_event_handler, | ||
861 | NULL); | ||
862 | if (NULL == phone) | ||
863 | { | ||
864 | GCG_log ("%s", | ||
865 | _("Failed to setup phone (internal error)\n")); | ||
866 | phone_state = PS_ERROR; | ||
867 | do_status(); | ||
868 | return; | 618 | return; |
869 | } | 619 | } |
870 | GNUNET_CONVERSATION_phone_get_record (phone, | 620 | phone_state = PS_ACCEPTED; |
871 | &rd); | 621 | ic = NULL; // FIXME: get 'ic' from selection! |
872 | /* FIXME: publish record to GNS! */ | 622 | set_incoming_call_state (ic, |
873 | GCG_log ("%s\n", | 623 | IN_STATE_CONNECTED); |
874 | _("Phone active")); | 624 | GCG_update_status_bar (_("Started a conversation with `%s'.\n"), |
875 | phone_state = PS_LISTEN; | 625 | ic->caller_id); |
876 | do_status(); | 626 | GCG_set_status_icon ("gnunet-conversation-call-active"); |
627 | GNUNET_CONVERSATION_caller_pick_up (ic->caller, | ||
628 | &caller_event_handler, ic, | ||
629 | speaker, mic); | ||
630 | GCG_HISTORY_add (GCG_HISTORY_TYPE_ACCEPTED, | ||
631 | ic->caller_id); | ||
632 | // FIXME: update visibility properly... | ||
633 | do_status (); | ||
877 | } | 634 | } |
878 | 635 | ||
879 | 636 | ||
880 | /** | 637 | /** |
881 | * Function called with an event emitted by a call. | 638 | * The "reject" button was clicked. Reject incoming call. |
882 | * | 639 | * |
883 | * @param cls closure, NULL | 640 | * @param button the button |
884 | * @param code type of the event on the call | 641 | * @param user_data builder (unused) |
885 | */ | 642 | */ |
886 | static void | 643 | void |
887 | call_event_handler (void *cls, | 644 | GNUNET_CONVERSATION_GTK_on_reject_clicked (GtkButton *button, |
888 | enum GNUNET_CONVERSATION_CallEventCode code) | 645 | gpointer user_data) |
889 | { | 646 | { |
890 | //struct OutgoingCallClosure *cl = cls; | 647 | // do_reject (); // FIXME! |
891 | 648 | do_status (); | |
892 | set_outgoing_call_state (NULL, code); | ||
893 | switch (code) | ||
894 | { | ||
895 | case GNUNET_CONVERSATION_EC_CALL_RINGING: | ||
896 | GNUNET_break (CS_RESOLVING == call_state); | ||
897 | GCG_log (_("Resolved address of `%s'. Now ringing other party."), | ||
898 | peer_name); | ||
899 | // set_outgoing_call_state(cls, CT_ringing); | ||
900 | call_state = CS_RINGING; | ||
901 | break; | ||
902 | case GNUNET_CONVERSATION_EC_CALL_PICKED_UP: | ||
903 | GNUNET_break (CS_RINGING == call_state); | ||
904 | GCG_log (_("Connection established to `%s'."), | ||
905 | peer_name); | ||
906 | call_state = CS_CONNECTED; | ||
907 | break; | ||
908 | case GNUNET_CONVERSATION_EC_CALL_GNS_FAIL: | ||
909 | GNUNET_break (CS_RESOLVING == call_state); | ||
910 | GCG_log (_("Failed to resolve %s in current zone."), | ||
911 | peer_name); | ||
912 | call = NULL; | ||
913 | break; | ||
914 | case GNUNET_CONVERSATION_EC_CALL_HUNG_UP: | ||
915 | GCG_log ("%s", _("Call terminated")); | ||
916 | call = NULL; | ||
917 | break; | ||
918 | case GNUNET_CONVERSATION_EC_CALL_SUSPENDED: | ||
919 | GNUNET_break (CS_CONNECTED == call_state); | ||
920 | GCG_log (_("Connection to `%s' suspended (by other user)\n"), | ||
921 | peer_name); | ||
922 | break; | ||
923 | case GNUNET_CONVERSATION_EC_CALL_RESUMED: | ||
924 | GNUNET_break (CS_CONNECTED == call_state); | ||
925 | GCG_log (_("Connection to `%s' resumed (by other user)\n"), | ||
926 | peer_name); | ||
927 | break; | ||
928 | case GNUNET_CONVERSATION_EC_CALL_ERROR: | ||
929 | GCG_log ("GNUNET_CONVERSATION_EC_CALL_ERROR %s", | ||
930 | peer_name); | ||
931 | } | ||
932 | } | 649 | } |
933 | 650 | ||
934 | 651 | ||
935 | /** | 652 | /** |
936 | * Initiating a new call | 653 | * User clicked the '> contact' button to move the selected |
654 | * caller's information into our address book. | ||
937 | * | 655 | * |
938 | * @param arg arguments given to the command | 656 | * @param button the button |
657 | * @param user_data builder (unused) | ||
939 | */ | 658 | */ |
940 | void | 659 | void |
941 | GSC_PHONE_make_call (const char *arg) | 660 | GNUNET_CONVERSATION_GTK_use_current_button_clicked (GtkButton *button, |
661 | gpointer *user_data) | ||
942 | { | 662 | { |
943 | GtkEntry *address_entry; | 663 | // FIXME: implement, use "GSC_add_contact" |
944 | struct GNUNET_IDENTITY_Ego *caller_id; | 664 | #if 0 |
945 | GtkTreeIter gtkiter; | 665 | const gchar *target; |
946 | 666 | ||
947 | address_entry = GTK_ENTRY (GCG_get_main_window_object ("GNUNET_GTK_conversation_address")); | 667 | target = gtk_entry_get_text (address_entry); |
948 | gtk_entry_set_text (address_entry, | 668 | gtk_entry_set_text (address_entry, |
949 | address); | 669 | "FIXME"); |
950 | caller_id = GCG_EGOS_get_selected_ego (); | 670 | #endif |
951 | if (NULL == caller_id) | ||
952 | { | ||
953 | // should not be possible! | ||
954 | GCG_log ("%s\n", | ||
955 | _("Caller ID unavailable, cannot initiate call.")); | ||
956 | return; | ||
957 | } | ||
958 | if (NULL != call) | ||
959 | { | ||
960 | GCG_log (_("You are calling someone else already, hang up first!\n")); | ||
961 | return; | ||
962 | } | ||
963 | switch (phone_state) | ||
964 | { | ||
965 | case PS_LOOKUP_EGO: | ||
966 | GCG_log ("%s\n", | ||
967 | _("Caller ID unavailable, cannot initiate call.")); | ||
968 | // should not be possible! | ||
969 | return; | ||
970 | case PS_LISTEN: | ||
971 | /* ok to call! */ | ||
972 | break; | ||
973 | case PS_ACCEPTED: | ||
974 | GCG_log (_ | ||
975 | ("You are answering call from `%s', hang up or suspend that call first!\n"), | ||
976 | peer_name); | ||
977 | GNUNET_break(0); | ||
978 | return; | ||
979 | case PS_ERROR: | ||
980 | /* ok to call */ | ||
981 | break; | ||
982 | } | ||
983 | //GNUNET_free_non_null (peer_name); | ||
984 | peer_name = GNUNET_strdup (arg); | ||
985 | GCG_log (_("now calling: %s"), peer_name); | ||
986 | call_state = CS_RESOLVING; | ||
987 | GNUNET_assert (NULL == call); | ||
988 | |||
989 | call_counter++; | ||
990 | call = | ||
991 | GNUNET_CONVERSATION_call_start (GCG_get_configuration (), | ||
992 | caller_id, | ||
993 | arg, | ||
994 | speaker, mic, | ||
995 | &call_event_handler, NULL); | ||
996 | //call = newcall; | ||
997 | |||
998 | // add call to active call list | ||
999 | |||
1000 | gtk_list_store_append (active_liststore, | ||
1001 | >kiter); | ||
1002 | gtk_list_store_set (active_liststore, >kiter, | ||
1003 | AL_caller_id, peer_name, | ||
1004 | AL_caller, NULL, | ||
1005 | AL_caller_num, NULL, | ||
1006 | AL_caller_state, CT_other, | ||
1007 | AL_type, CALL_OUT, | ||
1008 | AL_call, call, | ||
1009 | AL_call_num, call_counter, | ||
1010 | AL_call_state, CS_RESOLVING, | ||
1011 | -1 ); | ||
1012 | GCG_update_status_bar (_("We are calling `%s', his phone should be ringing."), | ||
1013 | peer_name); | ||
1014 | GCG_HISTORY_add (GCG_HISTORY_TYPE_OUTGOING, | ||
1015 | peer_name); | ||
1016 | } | 671 | } |
1017 | 672 | ||
1018 | 673 | ||
1019 | /** | 674 | /** |
1020 | * Accepting an incoming call | 675 | * The "resume" button was clicked. Resume a call! |
1021 | * | 676 | * |
1022 | * @param args arguments given to the command | 677 | * @param button the button |
678 | * @param user_data builder (unused) | ||
1023 | */ | 679 | */ |
1024 | static void | 680 | void |
1025 | do_accept (struct GNUNET_CONVERSATION_Caller *sel_caller) | 681 | GNUNET_CONVERSATION_GTK_on_resume_clicked (GtkButton *button, |
682 | gpointer user_data) | ||
1026 | { | 683 | { |
1027 | struct CallList *cl; | 684 | enum TypeOfConversation toc; |
1028 | 685 | struct IncomingCall *ic; | |
1029 | if ( (NULL != call) && | 686 | struct OutgoingCall *oc; |
1030 | (CS_SUSPENDED != call_state) ) | 687 | |
688 | if ( (NULL != active_in) || | ||
689 | (NULL != active_out) || | ||
690 | (! (PS_LISTEN == phone_state) || | ||
691 | (PS_ERROR == phone_state) ) ) | ||
1031 | { | 692 | { |
1032 | GCG_log (_("You are calling someone else already, hang up first!\n")); | 693 | /* resume button should have been inactive */ |
1033 | GNUNET_break(0); | 694 | GNUNET_break(0); |
1034 | return; | 695 | return; |
1035 | } | 696 | } |
1036 | switch (phone_state) | 697 | toc = 42; // FIXME: get from selection! |
1037 | { | ||
1038 | case PS_LOOKUP_EGO: | ||
1039 | GNUNET_break (0); | ||
1040 | break; | ||
1041 | case PS_LISTEN: | ||
1042 | /* this is the expected state */ | ||
1043 | break; | ||
1044 | case PS_ACCEPTED: | ||
1045 | GCG_log (_ | ||
1046 | ("You are answering call from `%s', hang up or suspend that call first!\n"), | ||
1047 | peer_name); | ||
1048 | GNUNET_break(0); | ||
1049 | return; | ||
1050 | case PS_ERROR: | ||
1051 | GNUNET_break (0); | ||
1052 | break; | ||
1053 | } | ||
1054 | |||
1055 | phone_state = PS_ACCEPTED; | ||
1056 | set_incoming_call_state(sel_caller,CT_active); | ||
1057 | 698 | ||
1058 | for (cl = cl_head; cl; cl = cl->next) | 699 | switch (toc) |
1059 | { | 700 | { |
1060 | /* FIXME: this may not be unique enough to identify the right item! | 701 | case CALL_IN: |
1061 | * Why not store CallList items in treeview instead of just callers? | 702 | ic = NULL; // FIXME: get from selection |
1062 | */ | 703 | GNUNET_CONVERSATION_caller_resume (ic->caller, speaker, mic); |
1063 | if (cl->caller == sel_caller) | 704 | set_incoming_call_state (ic, IN_STATE_CONNECTED); |
1064 | break; | 705 | phone_state = PS_ACCEPTED; |
1065 | } | 706 | GCG_update_status_bar (_("Resumed a conversation with `%s'.\n"), |
1066 | GNUNET_CONVERSATION_caller_pick_up (sel_caller, | 707 | ic->caller_id); |
1067 | &caller_event_handler, cl, | 708 | GCG_set_status_icon ("gnunet-conversation-call-active"); |
1068 | speaker, mic); | 709 | // FIXME: update visibility/sensitivity |
1069 | GCG_HISTORY_add (GCG_HISTORY_TYPE_ACCEPTED, peer_name); | 710 | do_status (); |
1070 | } | ||
1071 | |||
1072 | |||
1073 | /** | ||
1074 | * Suspending a call | ||
1075 | */ | ||
1076 | static void | ||
1077 | do_suspend () | ||
1078 | { | ||
1079 | if ( (NULL != call_selected) && | ||
1080 | (NULL != caller_selected) ) | ||
1081 | { | ||
1082 | GNUNET_break(0); | ||
1083 | return; | ||
1084 | } | ||
1085 | if (NULL != call_selected) | ||
1086 | { | ||
1087 | /* outgoing */ | ||
1088 | GNUNET_CONVERSATION_call_suspend (call_selected); | ||
1089 | set_outgoing_call_state(call_selected,CT_suspended); | ||
1090 | return; | 711 | return; |
1091 | } | 712 | case CALL_OUT: |
1092 | if (NULL != caller_selected) | 713 | oc = NULL; // FIXME: get from selection |
1093 | { | 714 | GNUNET_CONVERSATION_call_resume (oc->call, |
1094 | /* incoming */ | 715 | speaker, mic); |
1095 | GNUNET_CONVERSATION_caller_suspend (caller_selected); | 716 | set_outgoing_call_state (oc, |
1096 | set_incoming_call_state(caller_selected,CT_suspended); | 717 | OUT_STATE_ACTIVE); |
1097 | phone_state = PS_LISTEN; | 718 | // FIXME: update visibility/sensitivity |
719 | do_status (); | ||
1098 | return; | 720 | return; |
1099 | } | 721 | } |
1100 | GNUNET_break (0); | 722 | GNUNET_break (0); |
@@ -1102,82 +724,101 @@ do_suspend () | |||
1102 | 724 | ||
1103 | 725 | ||
1104 | /** | 726 | /** |
1105 | * Resuming a call | 727 | * The "suspend" button was clicked. Pause a call. |
1106 | * | 728 | * |
1107 | * @param args arguments given to the command | 729 | * @param button the button |
730 | * @param user_data builder (unused) | ||
1108 | */ | 731 | */ |
1109 | static void | 732 | void |
1110 | do_resume () | 733 | GNUNET_CONVERSATION_GTK_on_pause_clicked (GtkButton *button, |
734 | gpointer user_data) | ||
1111 | { | 735 | { |
1112 | switch (phone_state) | 736 | if ( (NULL != active_in) && |
1113 | { | 737 | (NULL != active_out) ) |
1114 | case PS_LOOKUP_EGO: | ||
1115 | case PS_ERROR: | ||
1116 | GCG_log ("%s", | ||
1117 | _("There is no call that could be resumed right now.(PS_ERROR)")); | ||
1118 | return; | ||
1119 | case PS_LISTEN: | ||
1120 | break; | ||
1121 | case PS_ACCEPTED: | ||
1122 | GCG_log (_("Already talking with `%s', cannot resume a call right now."), | ||
1123 | peer_name); | ||
1124 | return; | ||
1125 | } | ||
1126 | if ( (NULL != call_selected) && | ||
1127 | (NULL != caller_selected) ) | ||
1128 | { | 738 | { |
1129 | GNUNET_break(0); | 739 | GNUNET_break(0); |
1130 | return; | 740 | return; |
1131 | } | 741 | } |
1132 | if (NULL != call_selected) | 742 | if (NULL != active_out) |
1133 | { | 743 | { |
1134 | /* outgoing */ | 744 | /* outgoing */ |
1135 | GNUNET_CONVERSATION_call_resume (call_selected, speaker, mic); | 745 | GNUNET_CONVERSATION_call_suspend (active_out->call); |
1136 | set_outgoing_call_state(call_selected,CT_active); | 746 | set_outgoing_call_state (active_out, |
747 | OUT_STATE_SUSPENDED); | ||
748 | active_out = NULL; | ||
749 | gtk_widget_hide (b_suspend); | ||
750 | gtk_widget_hide (b_hangup); | ||
751 | gtk_widget_show (b_call); | ||
752 | gtk_widget_set_sensitive (b_hangup, FALSE); | ||
753 | gtk_widget_set_sensitive (b_suspend, FALSE); | ||
754 | gtk_widget_set_sensitive (GTK_WIDGET (address_entry), TRUE); | ||
755 | check_call_sensitivity (); | ||
756 | do_status (); | ||
757 | // FIXME: logging | ||
1137 | return; | 758 | return; |
1138 | } | 759 | } |
1139 | if (NULL != caller_selected) | 760 | if (NULL != active_in) |
1140 | { | 761 | { |
1141 | /* incoming */ | 762 | /* incoming */ |
1142 | GNUNET_CONVERSATION_caller_resume (caller_selected, speaker, mic); | 763 | GNUNET_CONVERSATION_caller_suspend (active_in->caller); |
1143 | set_incoming_call_state(caller_selected,CT_active); | 764 | set_incoming_call_state (active_in, |
1144 | phone_state = PS_ACCEPTED; | 765 | IN_STATE_SUSPENDED); |
766 | active_in = NULL; | ||
767 | phone_state = PS_LISTEN; | ||
768 | // FIXME: visibility | ||
769 | // FIXME: logging | ||
1145 | return; | 770 | return; |
1146 | } | 771 | } |
1147 | GNUNET_break(0); | 772 | GNUNET_break (0); |
1148 | } | 773 | } |
1149 | 774 | ||
1150 | 775 | ||
1151 | /** | 776 | /** |
1152 | / Rejecting a call | 777 | * The "hangup" button was clicked. Hang up. |
1153 | * | 778 | * |
1154 | * @param args arguments given to the command | 779 | * @param button the button |
780 | * @param user_data builder (unused) | ||
1155 | */ | 781 | */ |
1156 | static void | 782 | void |
1157 | do_reject () | 783 | GNUNET_CONVERSATION_GTK_on_hangup_clicked (GtkButton *button, |
784 | gpointer user_data) | ||
1158 | { | 785 | { |
1159 | if ( (NULL == call_selected) && | 786 | if ( (NULL == active_in) && |
1160 | (NULL == caller_selected) ) | 787 | (NULL == active_out) ) |
1161 | { | 788 | { |
1162 | GNUNET_break(0); | 789 | GNUNET_break(0); |
1163 | return; | 790 | return; |
1164 | } | 791 | } |
1165 | if (NULL != call_selected) | 792 | if (NULL != active_out) |
1166 | { | 793 | { |
1167 | /* if selected call is outgoing, stop it */ | 794 | /* if current call is outgoing, stop it */ |
1168 | set_outgoing_call_state (call_selected, CT_hangup); | 795 | set_outgoing_call_state (active_out, |
1169 | GNUNET_CONVERSATION_call_stop (call); | 796 | OUT_STATE_NONE); |
1170 | call = NULL; | 797 | // FIXME: rather: remove call state! |
1171 | call_selected = NULL; | 798 | GNUNET_CONVERSATION_call_stop (active_out->call); |
799 | active_out = NULL; | ||
800 | // FIXME: logging | ||
801 | gtk_widget_hide (b_suspend); | ||
802 | gtk_widget_hide (b_hangup); | ||
803 | gtk_widget_show (b_call); | ||
804 | gtk_widget_set_sensitive (b_hangup, FALSE); | ||
805 | gtk_widget_set_sensitive (b_suspend, FALSE); | ||
806 | gtk_widget_set_sensitive (GTK_WIDGET (address_entry), TRUE); | ||
807 | check_call_sensitivity (); | ||
808 | do_status (); | ||
1172 | return; | 809 | return; |
1173 | } | 810 | } |
1174 | if (NULL != caller_selected) | 811 | if (NULL != active_in) |
1175 | { | 812 | { |
1176 | /* if selected call is incoming, hang it up */ | 813 | /* if selected call is incoming, hang it up */ |
1177 | set_incoming_call_state (caller_selected,CT_hangup); | 814 | set_incoming_call_state (active_in, |
1178 | GNUNET_CONVERSATION_caller_hang_up (caller_selected); | 815 | IN_STATE_NONE); |
816 | // FIXME: rather: remove call state! | ||
817 | GNUNET_CONVERSATION_caller_hang_up (active_in->caller); | ||
1179 | phone_state = PS_LISTEN; | 818 | phone_state = PS_LISTEN; |
1180 | caller_selected = NULL; | 819 | active_in = NULL; |
820 | // FIXME: logging | ||
821 | // FIXME: visibility | ||
1181 | return; | 822 | return; |
1182 | } | 823 | } |
1183 | GNUNET_break (0); | 824 | GNUNET_break (0); |
@@ -1185,98 +826,240 @@ do_reject () | |||
1185 | 826 | ||
1186 | 827 | ||
1187 | /** | 828 | /** |
1188 | * hangup clicked | 829 | * Function called with an event emitted by a call. |
830 | * | ||
831 | * @param cls our `struct OutgoingCall` | ||
832 | * @param code type of the event on the call | ||
1189 | */ | 833 | */ |
1190 | void | 834 | static void |
1191 | GNUNET_CONVERSATION_GTK_on_hangup_clicked () | 835 | call_event_handler (void *cls, |
836 | enum GNUNET_CONVERSATION_CallEventCode code) | ||
1192 | { | 837 | { |
1193 | do_reject (); | 838 | struct OutgoingCall *oc = cls; |
1194 | do_status (); | ||
1195 | } | ||
1196 | |||
1197 | 839 | ||
1198 | /** | 840 | set_outgoing_call_state (oc, code); |
1199 | * accept clicked | 841 | switch (code) |
1200 | */ | ||
1201 | void | ||
1202 | GNUNET_CONVERSATION_GTK_on_accept_clicked () | ||
1203 | { | ||
1204 | if (NULL != caller_selected) | ||
1205 | { | ||
1206 | do_accept (caller_selected); | ||
1207 | } | ||
1208 | else | ||
1209 | { | 842 | { |
1210 | GNUNET_break(0); | 843 | case GNUNET_CONVERSATION_EC_CALL_RINGING: |
844 | GNUNET_break (OUT_STATE_RESOLVING == oc->state); | ||
845 | GCG_log (_("Resolved address of `%s'. Now ringing other party."), | ||
846 | oc->peer_name); | ||
847 | // FIXME: use oc->rr here! | ||
848 | set_outgoing_call_state (oc, OUT_STATE_RINGING); | ||
849 | GCG_log (_("Ringing `%s'.\n"), | ||
850 | oc->peer_name); | ||
851 | GCG_update_status_bar (_("Ringing `%s'."), | ||
852 | oc->peer_name); | ||
853 | GCG_set_status_icon ("gnunet-conversation-gtk-tray-call-ringing"); | ||
854 | break; | ||
855 | case GNUNET_CONVERSATION_EC_CALL_PICKED_UP: | ||
856 | GNUNET_break (OUT_STATE_RINGING == oc->state); | ||
857 | set_outgoing_call_state (oc, OUT_STATE_ACTIVE); | ||
858 | gtk_widget_set_sensitive (b_suspend, TRUE); | ||
859 | GCG_log (_("Connection established to `%s'."), | ||
860 | oc->peer_name); | ||
861 | GCG_update_status_bar (_("Talking to `%s'."), | ||
862 | oc->peer_name); | ||
863 | GCG_set_status_icon ("gnunet-conversation-gtk-tray-call-active"); | ||
864 | break; | ||
865 | case GNUNET_CONVERSATION_EC_CALL_GNS_FAIL: | ||
866 | GNUNET_break (OUT_STATE_RESOLVING == oc->state); | ||
867 | set_outgoing_call_state (oc, OUT_STATE_NONE); | ||
868 | // FIXME: rather: remove from list! | ||
869 | GCG_log (_("Failed to resolve %s in current zone."), | ||
870 | oc->peer_name); | ||
871 | GNUNET_free (oc); | ||
872 | active_out = NULL; | ||
873 | gtk_widget_hide (b_suspend); | ||
874 | gtk_widget_hide (b_hangup); | ||
875 | gtk_widget_show (b_call); | ||
876 | gtk_widget_set_sensitive (b_hangup, FALSE); | ||
877 | gtk_widget_set_sensitive (GTK_WIDGET (address_entry), TRUE); | ||
878 | check_call_sensitivity (); | ||
879 | do_status (); | ||
880 | break; | ||
881 | case GNUNET_CONVERSATION_EC_CALL_HUNG_UP: | ||
882 | GCG_log ("%s", _("Call terminated")); | ||
883 | set_outgoing_call_state (oc, OUT_STATE_NONE); | ||
884 | // FIXME: rather: remove from list! | ||
885 | GNUNET_free (oc); | ||
886 | active_out = NULL; | ||
887 | gtk_widget_hide (b_suspend); | ||
888 | gtk_widget_hide (b_hangup); | ||
889 | gtk_widget_show (b_call); | ||
890 | gtk_widget_set_sensitive (b_hangup, FALSE); | ||
891 | gtk_widget_set_sensitive (b_suspend, FALSE); | ||
892 | gtk_widget_set_sensitive (GTK_WIDGET (address_entry), TRUE); | ||
893 | check_call_sensitivity (); | ||
894 | do_status (); | ||
895 | break; | ||
896 | case GNUNET_CONVERSATION_EC_CALL_SUSPENDED: | ||
897 | GNUNET_break (OUT_STATE_ACTIVE == oc->state); | ||
898 | set_outgoing_call_state (oc, OUT_STATE_SUSPENDED); | ||
899 | GCG_log (_("Connection to `%s' suspended (by other user)\n"), | ||
900 | oc->peer_name); | ||
901 | active_out = NULL; | ||
902 | gtk_widget_hide (b_suspend); | ||
903 | gtk_widget_hide (b_hangup); | ||
904 | gtk_widget_show (b_call); | ||
905 | gtk_widget_set_sensitive (b_hangup, FALSE); | ||
906 | gtk_widget_set_sensitive (b_suspend, FALSE); | ||
907 | gtk_widget_set_sensitive (GTK_WIDGET (address_entry), TRUE); | ||
908 | check_call_sensitivity (); | ||
909 | do_status (); | ||
910 | break; | ||
911 | case GNUNET_CONVERSATION_EC_CALL_RESUMED: | ||
912 | GNUNET_break (OUT_STATE_ACTIVE == oc->state); | ||
913 | GCG_log (_("Connection to `%s' resumed\n"), | ||
914 | oc->peer_name); | ||
915 | GCG_update_status_bar (_("Talking to `%s'."), | ||
916 | oc->peer_name); | ||
917 | GCG_set_status_icon ("gnunet-conversation-gtk-tray-call-active"); | ||
918 | active_out = oc; | ||
919 | set_outgoing_call_state (oc, OUT_STATE_ACTIVE); | ||
920 | gtk_widget_show (b_suspend); | ||
921 | gtk_widget_show (b_hangup); | ||
922 | gtk_widget_hide (b_call); | ||
923 | gtk_widget_set_sensitive (b_hangup, TRUE); | ||
924 | gtk_widget_set_sensitive (b_suspend, TRUE); | ||
925 | gtk_widget_set_sensitive (GTK_WIDGET (address_entry), FALSE); | ||
926 | break; | ||
927 | case GNUNET_CONVERSATION_EC_CALL_ERROR: | ||
928 | GCG_log ("GNUNET_CONVERSATION_EC_CALL_ERROR %s", | ||
929 | oc->peer_name); | ||
930 | set_outgoing_call_state (oc, OUT_STATE_NONE); | ||
931 | // FIXME: rather: remove from list! | ||
932 | active_out = NULL; | ||
933 | gtk_widget_hide (b_suspend); | ||
934 | gtk_widget_hide (b_hangup); | ||
935 | gtk_widget_show (b_call); | ||
936 | gtk_widget_set_sensitive (b_hangup, FALSE); | ||
937 | gtk_widget_set_sensitive (b_suspend, FALSE); | ||
938 | gtk_widget_set_sensitive (GTK_WIDGET (address_entry), TRUE); | ||
939 | check_call_sensitivity (); | ||
940 | do_status (); | ||
941 | break; | ||
1211 | } | 942 | } |
1212 | do_status (); | ||
1213 | } | 943 | } |
1214 | 944 | ||
1215 | 945 | ||
1216 | /** | 946 | /** |
1217 | * reject clicked | 947 | * Initiate a new call. |
1218 | */ | 948 | * |
1219 | void | 949 | * @param arg address of the user to call |
1220 | GNUNET_CONVERSATION_GTK_on_reject_clicked () | ||
1221 | { | ||
1222 | do_reject (); | ||
1223 | do_status (); | ||
1224 | } | ||
1225 | |||
1226 | |||
1227 | /** | ||
1228 | * User clicked the '> contact' button to move the selected | ||
1229 | * caller's information into our address book. | ||
1230 | */ | 950 | */ |
1231 | void | 951 | void |
1232 | GNUNET_CONVERSATION_GTK_use_current_button_clicked (GtkButton *button, | 952 | GSC_PHONE_make_call (const char *arg) |
1233 | gpointer *user_data) | ||
1234 | { | 953 | { |
1235 | // FIXME: implement, use "GSC_add_contact" | 954 | struct GNUNET_IDENTITY_Ego *caller_id; |
1236 | #if 0 | 955 | GtkTreeIter gtkiter; |
1237 | GtkEntry *addressEntry; | 956 | struct OutgoingCall *oc; |
1238 | 957 | ||
1239 | addressEntry = GTK_ENTRY (GCG_get_main_window_object ("GNUNET_GTK_conversation_addressAdd")); | 958 | gtk_entry_set_text (address_entry, |
1240 | gtk_entry_set_text (addressEntry, | 959 | arg); |
1241 | "FIXME"); | 960 | caller_id = GCG_EGOS_get_selected_ego (); |
1242 | #endif | 961 | if (NULL == caller_id) |
962 | { | ||
963 | /* can happen if user activated address in phone book | ||
964 | while our phone was still down (no ego selected) */ | ||
965 | GCG_log (_("Caller ID unavailable, cannot initiate call to `%s'.\n"), | ||
966 | arg); | ||
967 | return; | ||
968 | } | ||
969 | if (NULL != active_out) | ||
970 | { | ||
971 | if (0 == strcmp (active_out->peer_name, | ||
972 | arg)) | ||
973 | return; /* user likely simply clicked a bit too often, ignore */ | ||
974 | GCG_log (_("You are on the phone with `%s', suspend or hang up before trying to call `%s'!\n"), | ||
975 | active_out->peer_name, | ||
976 | arg); | ||
977 | return; | ||
978 | } | ||
979 | switch (phone_state) | ||
980 | { | ||
981 | case PS_LOOKUP_EGO: | ||
982 | GCG_log ("%s\n", | ||
983 | _("Caller ID unavailable, cannot initiate call.")); | ||
984 | return; | ||
985 | case PS_LISTEN: | ||
986 | /* ok to call! */ | ||
987 | break; | ||
988 | case PS_ACCEPTED: | ||
989 | /* `call` should be non-NULL */ | ||
990 | GNUNET_break (0); | ||
991 | return; | ||
992 | case PS_ERROR: | ||
993 | /* ok to call, we got an ego just could not init the phone */ | ||
994 | break; | ||
995 | } | ||
996 | call_counter++; | ||
997 | oc = GNUNET_new (struct OutgoingCall); | ||
998 | oc->peer_name = GNUNET_strdup (arg); | ||
999 | oc->state = OUT_STATE_RESOLVING; | ||
1000 | oc->call = | ||
1001 | GNUNET_CONVERSATION_call_start (GCG_get_configuration (), | ||
1002 | caller_id, | ||
1003 | arg, | ||
1004 | speaker, mic, | ||
1005 | &call_event_handler, oc); | ||
1006 | gtk_list_store_insert_with_values (active_liststore, | ||
1007 | >kiter, | ||
1008 | -1, | ||
1009 | GCG_PHONE_LS_CALLER_ID, oc->peer_name, | ||
1010 | GCG_PHONE_LS_CALLER, NULL, | ||
1011 | GCG_PHONE_LS_CALLER_NUM, 0, | ||
1012 | GCG_PHONE_LS_CALLER_STATE, IN_STATE_NONE, | ||
1013 | GCG_PHONE_LS_TYPE, CALL_OUT, | ||
1014 | GCG_PHONE_LS_CALL, oc, | ||
1015 | GCG_PHONE_LS_CALL_NUM, call_counter, | ||
1016 | GCG_PHONE_LS_CALL_STATE, OUT_STATE_RESOLVING, | ||
1017 | -1); | ||
1018 | /* log event */ | ||
1019 | GCG_log (_("Resolving `%s'.\n"), | ||
1020 | oc->peer_name); | ||
1021 | GCG_update_status_bar (_("Resolving `%s'."), | ||
1022 | oc->peer_name); | ||
1023 | GCG_set_status_icon ("gnunet-conversation-gtk-tray-call-pending"); | ||
1024 | GCG_HISTORY_add (GCG_HISTORY_TYPE_OUTGOING, | ||
1025 | oc->peer_name); | ||
1026 | /* hide "call" button, make address entry insensitive; | ||
1027 | show suspend button (but not sensitive), | ||
1028 | show hangup button (and make sensitive) */ | ||
1029 | gtk_widget_hide (b_call); | ||
1030 | gtk_widget_set_sensitive (GTK_WIDGET (address_entry), FALSE); | ||
1031 | gtk_widget_show (b_suspend); | ||
1032 | gtk_widget_show (b_hangup); | ||
1033 | gtk_widget_set_sensitive (b_hangup, TRUE); | ||
1243 | } | 1034 | } |
1244 | 1035 | ||
1245 | 1036 | ||
1246 | /** | 1037 | /** |
1247 | * pause clicked | 1038 | * The "connect" button was clicked. Initiate a call! |
1248 | */ | 1039 | * |
1249 | void | 1040 | * @param button the button |
1250 | GNUNET_CONVERSATION_GTK_on_pause_clicked () | 1041 | * @param user_data builder (unused) |
1251 | { | ||
1252 | do_suspend (); | ||
1253 | do_status (); | ||
1254 | } | ||
1255 | |||
1256 | /** | ||
1257 | * resume clicked | ||
1258 | */ | 1042 | */ |
1259 | void | 1043 | void |
1260 | GNUNET_CONVERSATION_GTK_on_resume_clicked () | 1044 | gnunet_conversation_gtk_call_button_clicked_cb (GtkButton *button, |
1045 | gpointer user_data) | ||
1261 | { | 1046 | { |
1262 | do_resume (); | 1047 | GSC_PHONE_make_call (gtk_entry_get_text (address_entry)); |
1263 | do_status (); | ||
1264 | } | 1048 | } |
1265 | 1049 | ||
1266 | 1050 | ||
1267 | /** | 1051 | /** |
1268 | * call clicked | 1052 | * The user has changed the address entry. Consider activating the |
1053 | * "call" button. | ||
1054 | * | ||
1055 | * @param editable entry that was changed | ||
1056 | * @param user_data builder (unused) | ||
1269 | */ | 1057 | */ |
1270 | void | 1058 | void |
1271 | GNUNET_CONVERSATION_GTK_on_call_clicked () | 1059 | gnunet_conversation_gtk_address_entry_changed_cb (GtkEditable *editable, |
1060 | gpointer user_data) | ||
1272 | { | 1061 | { |
1273 | GtkEntry *address_entry; | 1062 | check_call_sensitivity (); |
1274 | |||
1275 | address_entry = GTK_ENTRY (GCG_get_main_window_object | ||
1276 | ("GNUNET_GTK_conversation_address")); | ||
1277 | |||
1278 | GSC_PHONE_make_call (gtk_entry_get_text (address_entry)); | ||
1279 | do_status (); | ||
1280 | } | 1063 | } |
1281 | 1064 | ||
1282 | 1065 | ||
@@ -1290,12 +1073,50 @@ void | |||
1290 | gnunet_conversation_gtk_ego_combobox_changed_cb (GtkComboBox *widget, | 1073 | gnunet_conversation_gtk_ego_combobox_changed_cb (GtkComboBox *widget, |
1291 | gpointer user_data) | 1074 | gpointer user_data) |
1292 | { | 1075 | { |
1076 | struct GNUNET_GNSRECORD_Data rd; | ||
1077 | struct GNUNET_IDENTITY_Ego *caller_id; | ||
1078 | |||
1293 | if (NULL != phone) | 1079 | if (NULL != phone) |
1294 | { | 1080 | { |
1295 | GNUNET_CONVERSATION_phone_destroy (phone); | 1081 | GNUNET_CONVERSATION_phone_destroy (phone); |
1296 | phone = NULL; | 1082 | phone = NULL; |
1297 | } | 1083 | } |
1298 | start_phone(); | 1084 | caller_id = GCG_EGOS_get_selected_ego (); |
1085 | if (NULL == caller_id) | ||
1086 | { | ||
1087 | GCG_update_status_bar ("%s", | ||
1088 | _("No ego selected, phone is now down.")); | ||
1089 | GCG_log ("%s\n", | ||
1090 | _("No ego selected, phone is now down.")); | ||
1091 | GCG_set_status_icon ("gnunet-conversation-gtk-tray-pending"); | ||
1092 | phone_state = PS_LOOKUP_EGO; | ||
1093 | check_call_sensitivity (); | ||
1094 | return; | ||
1095 | } | ||
1096 | phone = | ||
1097 | GNUNET_CONVERSATION_phone_create (GCG_get_configuration (), | ||
1098 | caller_id, | ||
1099 | &phone_event_handler, | ||
1100 | NULL); | ||
1101 | if (NULL == phone) | ||
1102 | { | ||
1103 | GCG_update_status_bar ("%s", | ||
1104 | _("Failed to setup phone (internal error)\n")); | ||
1105 | GCG_log ("%s", | ||
1106 | _("Failed to setup phone (internal error)\n")); | ||
1107 | GCG_set_status_icon ("gnunet-conversation-offline"); | ||
1108 | phone_state = PS_ERROR; | ||
1109 | check_call_sensitivity (); | ||
1110 | return; | ||
1111 | } | ||
1112 | GNUNET_CONVERSATION_phone_get_record (phone, | ||
1113 | &rd); | ||
1114 | /* FIXME: publish record to GNS! */ | ||
1115 | GCG_log ("%s\n", | ||
1116 | _("Phone active")); | ||
1117 | phone_state = PS_LISTEN; | ||
1118 | check_call_sensitivity (); | ||
1119 | do_status(); | ||
1299 | } | 1120 | } |
1300 | 1121 | ||
1301 | 1122 | ||
@@ -1310,7 +1131,7 @@ GCG_PHONE_init () | |||
1310 | cfg = GCG_get_configuration (); | 1131 | cfg = GCG_get_configuration (); |
1311 | speaker = GNUNET_SPEAKER_create_from_hardware (cfg); | 1132 | speaker = GNUNET_SPEAKER_create_from_hardware (cfg); |
1312 | mic = GNUNET_MICROPHONE_create_from_hardware (cfg); | 1133 | mic = GNUNET_MICROPHONE_create_from_hardware (cfg); |
1313 | /* get gui objects */ | 1134 | |
1314 | b_add_contact = GTK_WIDGET (GCG_get_main_window_object | 1135 | b_add_contact = GTK_WIDGET (GCG_get_main_window_object |
1315 | ("gnunet_conversation_gtk_add_contact_button")); | 1136 | ("gnunet_conversation_gtk_add_contact_button")); |
1316 | b_accept = GTK_WIDGET (GCG_get_main_window_object | 1137 | b_accept = GTK_WIDGET (GCG_get_main_window_object |
@@ -1325,7 +1146,8 @@ GCG_PHONE_init () | |||
1325 | ("gnunet_conversation_gtk_call_button")); | 1146 | ("gnunet_conversation_gtk_call_button")); |
1326 | b_hangup = GTK_WIDGET (GCG_get_main_window_object | 1147 | b_hangup = GTK_WIDGET (GCG_get_main_window_object |
1327 | ("gnunet_conversation_gtk_hangup_button")); | 1148 | ("gnunet_conversation_gtk_hangup_button")); |
1328 | 1149 | address_entry = GTK_ENTRY (GCG_get_main_window_object | |
1150 | ("gnunet_conversation_gtk_address_entry")); | ||
1329 | active_liststore = | 1151 | active_liststore = |
1330 | GTK_LIST_STORE (GCG_get_main_window_object | 1152 | GTK_LIST_STORE (GCG_get_main_window_object |
1331 | ("gnunet_conversation_gtk_active_calls_liststore")); | 1153 | ("gnunet_conversation_gtk_active_calls_liststore")); |
@@ -1341,22 +1163,19 @@ GCG_PHONE_init () | |||
1341 | void | 1163 | void |
1342 | GCG_PHONE_shutdown () | 1164 | GCG_PHONE_shutdown () |
1343 | { | 1165 | { |
1344 | struct CallList *cl; | 1166 | if (NULL != active_in) |
1345 | |||
1346 | while (NULL != (cl = cl_head)) | ||
1347 | { | 1167 | { |
1348 | GNUNET_CONVERSATION_caller_hang_up (cl->caller); | 1168 | GNUNET_CONVERSATION_caller_hang_up (active_in->caller); |
1349 | GNUNET_CONTAINER_DLL_remove (cl_head, | 1169 | // FIXME: memory leak |
1350 | cl_tail, | 1170 | active_in = NULL; |
1351 | cl); | ||
1352 | // FIXME: release other memory? | ||
1353 | GNUNET_free (cl); | ||
1354 | } | 1171 | } |
1355 | if (NULL != call) | 1172 | if (NULL != active_out) |
1356 | { | 1173 | { |
1357 | GNUNET_CONVERSATION_call_stop (call); | 1174 | GNUNET_CONVERSATION_call_stop (active_out->call); |
1358 | call = NULL; | 1175 | // FIXME: memory leak |
1176 | active_out = NULL; | ||
1359 | } | 1177 | } |
1178 | // FIXME: clean up tree view! | ||
1360 | if (NULL != phone) | 1179 | if (NULL != phone) |
1361 | { | 1180 | { |
1362 | GNUNET_CONVERSATION_phone_destroy (phone); | 1181 | GNUNET_CONVERSATION_phone_destroy (phone); |
@@ -1366,8 +1185,6 @@ GCG_PHONE_shutdown () | |||
1366 | speaker = NULL; | 1185 | speaker = NULL; |
1367 | GNUNET_MICROPHONE_destroy (mic); | 1186 | GNUNET_MICROPHONE_destroy (mic); |
1368 | mic = NULL; | 1187 | mic = NULL; |
1369 | GNUNET_free_non_null (peer_name); | ||
1370 | peer_name = NULL; | ||
1371 | phone_state = PS_ERROR; | 1188 | phone_state = PS_ERROR; |
1372 | } | 1189 | } |
1373 | 1190 | ||