ui_callbacks.c 31.8 KB
Newer Older
1 2 3 4
#if HAVE_CONFIG_H
# include "config.h"
#endif

Cedric Roux's avatar
 
Cedric Roux committed
5 6 7
#include <stdlib.h>
#include <stdint.h>

8 9
#define G_LOG_DOMAIN ("UI_CB")

Cedric Roux's avatar
 
Cedric Roux committed
10 11
#include <gtk/gtk.h>

12
#include "logs.h"
13
#include "rc.h"
Cedric Roux's avatar
 
Cedric Roux committed
14

Cedric Roux's avatar
Cedric Roux committed
15 16 17
#include "socket.h"

#include "ui_notif_dlg.h"
Cedric Roux's avatar
 
Cedric Roux committed
18
#include "ui_main_screen.h"
19
#include "ui_menu_bar.h"
Cedric Roux's avatar
 
Cedric Roux committed
20 21 22 23 24
#include "ui_callbacks.h"
#include "ui_interface.h"
#include "ui_notifications.h"
#include "ui_tree_view.h"
#include "ui_signal_dissect_view.h"
winckel's avatar
winckel committed
25
#include "ui_filters.h"
26
#include "ui_notebook.h"
Cedric Roux's avatar
 
Cedric Roux committed
27

Cedric Roux's avatar
Cedric Roux committed
28 29 30 31
#include "types.h"
#include "locate_root.h"
#include "xml_parse.h"

32 33 34
static gboolean refresh_message_list =  TRUE;
static gboolean filters_changed =       FALSE;
static gboolean operation_running =     FALSE;
35

winckel's avatar
winckel committed
36 37 38 39
static const char  *ui_ip;
static uint16_t     ui_port;
static GtkWidget   *dialogbox_connect;
static gboolean     ui_auto_reconnect;
40

41
gboolean ui_callback_on_open_messages(GtkWidget *widget, gpointer data)
Cedric Roux's avatar
 
Cedric Roux committed
42
{
winckel's avatar
winckel committed
43 44
    gboolean refresh = (data != NULL) ? TRUE : FALSE;

45
    g_message("Open messages event occurred %d", refresh);
winckel's avatar
winckel committed
46

47
    if (operation_running == FALSE)
winckel's avatar
winckel committed
48
    {
49 50 51
        operation_running = TRUE;
        if (refresh && (ui_main_data.messages_file_name != NULL))
        {
52
            ui_messages_read (ui_main_data.messages_file_name);
53 54 55
        }
        else
        {
56
            ui_messages_open_file_chooser ();
57 58
        }
        operation_running = FALSE;
winckel's avatar
winckel committed
59
    }
60 61 62 63

    return TRUE;
}

64
gboolean ui_callback_on_save_messages(GtkWidget *widget, gpointer data)
65
{
66 67 68
    gboolean filtered = (data != NULL) ? TRUE : FALSE;

    g_message("Save messages event occurred %d", filtered);
69

70 71 72
    if (operation_running == FALSE)
    {
        operation_running = TRUE;
73
        ui_messages_save_file_chooser(filtered);
74 75
        operation_running = FALSE;
    }
76

77 78 79
    return TRUE;
}

80
gboolean ui_callback_on_filters_enabled(GtkToolButton *button, gpointer data)
81 82 83 84
{
    gboolean enabled;
    gboolean changed;

85
    enabled = gtk_toggle_tool_button_get_active (GTK_TOGGLE_TOOL_BUTTON(button));
86

87
    g_info("Filters enabled event occurred %d", enabled);
88

89
    changed = ui_filters_enable (enabled);
90 91 92

    if (changed)
    {
93
        /* Set the tool tip text */
94 95
        if (enabled)
        {
96
            gtk_tool_item_set_tooltip_text (GTK_TOOL_ITEM(button), "Disable messages filtering");
97 98
        }
        else
99
        {
100
            gtk_tool_item_set_tooltip_text (GTK_TOOL_ITEM(button), "Enable messages filtering");
101
        }
102
        ui_tree_view_refilter ();
103 104 105 106 107
    }

    return TRUE;
}

108
gboolean ui_callback_on_open_filters(GtkWidget *widget, gpointer data)
109
{
110 111
    gboolean refresh = (data != NULL) ? TRUE : FALSE;

112
    g_message("Open filters event occurred");
113

114
    if (operation_running == FALSE)
115
    {
116 117 118
        operation_running = TRUE;
        if (refresh && (ui_main_data.filters_file_name != NULL))
        {
119
            ui_filters_read (ui_main_data.filters_file_name);
120 121 122
        }
        else
        {
123
            ui_filters_open_file_chooser ();
124 125
        }
        operation_running = FALSE;
126 127
    }

128 129 130
    return TRUE;
}

131
gboolean ui_callback_on_save_filters(GtkWidget *widget, gpointer data)
132
{
133 134 135 136
    if (operation_running == FALSE)
    {
        operation_running = TRUE;
        g_message("Save filters event occurred");
137
        ui_filters_save_file_chooser();
138 139 140
        operation_running = FALSE;
    }

Cedric Roux's avatar
 
Cedric Roux committed
141 142 143
    return TRUE;
}

144
gboolean ui_callback_on_enable_filters(GtkWidget *widget, gpointer data)
winckel's avatar
winckel committed
145 146 147
{
    gboolean enabled;

148 149
    enabled = gtk_toggle_tool_button_get_active (GTK_TOGGLE_TOOL_BUTTON(ui_main_data.filters_enabled));
    gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON(ui_main_data.filters_enabled), !enabled);
winckel's avatar
winckel committed
150 151 152 153

    return TRUE;
}

154
gboolean ui_callback_on_about(GtkWidget *widget, gpointer data)
Cedric Roux's avatar
 
Cedric Roux committed
155
{
156
#if defined(PACKAGE_STRING)
winckel's avatar
winckel committed
157
    ui_notification_dialog (GTK_MESSAGE_INFO, FALSE, "about", "Eurecom %s", PACKAGE_STRING);
158
#else
winckel's avatar
winckel committed
159
    ui_notification_dialog (GTK_MESSAGE_INFO, FALSE, "about", "Eurecom itti_analyzer");
160
#endif
Cedric Roux's avatar
 
Cedric Roux committed
161 162 163 164

    return TRUE;
}

165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187
gint ui_callback_check_string (const char *string, const gint lenght, const guint message_number)
{
    gint real_length;

    real_length = strnlen (string, lenght);
    if (lenght != real_length)
    {
        if (message_number)
        {
            g_warning("Bad string format for message %u, '\\0' found before end of string (%d/%d)\n", message_number, real_length, lenght);
        }
        else
        {
            g_warning("Bad string format, '\\0' found before end of string (%d/%d)\n", real_length, lenght);
        }
        return (real_length);
    }
    else
    {
        return (lenght);
    }
}

188 189
gboolean ui_callback_on_select_signal(GtkTreeSelection *selection, GtkTreeModel *model, GtkTreePath *path,
                                      gboolean path_currently_selected, gpointer user_data)
Cedric Roux's avatar
 
Cedric Roux committed
190
{
winckel's avatar
winckel committed
191
    static gpointer buffer_current;
192
    ui_text_view_t *text_view;
Cedric Roux's avatar
 
Cedric Roux committed
193 194
    GtkTreeIter iter;

195
    g_debug("Message selected %d %p %p %s", path_currently_selected, buffer_current, path, gtk_tree_path_to_string(path));
Cedric Roux's avatar
 
Cedric Roux committed
196

winckel's avatar
winckel committed
197 198 199
    if (!path_currently_selected)
    {
        text_view = (ui_text_view_t *) user_data;
Cedric Roux's avatar
Cedric Roux committed
200

winckel's avatar
winckel committed
201
        g_assert(text_view != NULL);
Cedric Roux's avatar
 
Cedric Roux committed
202

203
        if (gtk_tree_model_get_iter (model, &iter, path))
winckel's avatar
winckel committed
204 205
        {
            gpointer buffer;
Cedric Roux's avatar
Cedric Roux committed
206

winckel's avatar
winckel committed
207
            uint32_t message_number;
208 209 210
            uint32_t message_id;
            uint32_t origin_task_id;
            uint32_t destination_task_id;
winckel's avatar
winckel committed
211
            char *instance_name;
212 213
            uint32_t instance;
            char label[100];
Cedric Roux's avatar
Cedric Roux committed
214

winckel's avatar
winckel committed
215
            gtk_tree_model_get (model, &iter, COL_MSG_NUM, &message_number, COL_MESSAGE_ID, &message_id,
winckel's avatar
winckel committed
216 217
                                COL_FROM_TASK_ID, &origin_task_id, COL_TO_TASK_ID, &destination_task_id, COL_INSTANCE, &instance_name,
                                COL_INSTANCE_ID, &instance, COL_BUFFER, &buffer, -1);
Cedric Roux's avatar
Cedric Roux committed
218

winckel's avatar
winckel committed
219
            g_debug("  Get iter %p %p", buffer_current, buffer);
Cedric Roux's avatar
Cedric Roux committed
220

221 222
            if (ui_tree_view_last_event)
            {
223
                g_debug("last_event %p %d %d", ui_tree_view_last_event, ui_tree_view_last_event->type, ui_tree_view_last_event->button);
224 225 226 227

                if (ui_tree_view_last_event->type == GDK_BUTTON_PRESS)
                {
                    /* Callback is due to a button click */
winckel's avatar
winckel committed
228 229 230 231 232
                    if (ui_tree_view_last_event->button == 1)
                    {
                        /* It was a left mouse click */
                        gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON(ui_main_data.signals_go_to_last_button), FALSE);
                    }
233 234 235 236 237 238 239 240 241

                    if (ui_tree_view_last_event->button == 3)
                    {
                        /* It was a right mouse click */
                        int item;

                        /* Clear event */
                        ui_tree_view_last_event = NULL;

242 243
                        /* Create filter menus to refers its items in the pop-up menu */
                        ui_create_filter_menus ();
244

245
                        g_info("Message selected right click %d %d %d %d", message_id, origin_task_id, destination_task_id, instance);
246

247 248 249
                        /* Message Id menu */
                        {
                            /* Invalidate associated menu item to avoid issue with call back when updating the menu item check state */
250
                            ui_tree_view_menu_enable[MENU_MESSAGE].filter_item = NULL;
251
                            item = ui_filters_search_id (&ui_filters.messages, message_id);
252
                            /* Update the menu item check state based on message ID state */
253
                            gtk_check_menu_item_set_active (
254 255 256
                                    GTK_CHECK_MENU_ITEM(ui_tree_view_menu_enable[MENU_MESSAGE].menu_enable),
                                    ui_filters.messages.items[item].enabled);
                            /* Set menu item label */
257 258 259
                            sprintf (label, "Message:  %s", message_id_to_string (message_id));
                            gtk_menu_item_set_label (GTK_MENU_ITEM(ui_tree_view_menu_enable[MENU_MESSAGE].menu_enable),
                                                     label);
260
                            /* Save menu item associated to this row */
261
                            ui_tree_view_menu_enable[MENU_MESSAGE].filter_item = &ui_filters.messages.items[item];
262 263 264 265 266
                        }

                        /* Origin task id */
                        {
                            /* Invalidate associated menu item to avoid issue with call back when updating the menu item check state */
267
                            ui_tree_view_menu_enable[MENU_FROM_TASK].filter_item = NULL;
268
                            item = ui_filters_search_id (&ui_filters.origin_tasks, origin_task_id);
269
                            /* Update the menu item check state based on message ID state */
270
                            gtk_check_menu_item_set_active (
271 272 273
                                    GTK_CHECK_MENU_ITEM(ui_tree_view_menu_enable[MENU_FROM_TASK].menu_enable),
                                    ui_filters.origin_tasks.items[item].enabled);
                            /* Set menu item label */
274 275 276
                            sprintf (label, "From:  %s", task_id_to_string (origin_task_id, origin_task_id_type));
                            gtk_menu_item_set_label (
                                    GTK_MENU_ITEM(ui_tree_view_menu_enable[MENU_FROM_TASK].menu_enable), label);
277
                            /* Save menu item associated to this row */
278
                            ui_tree_view_menu_enable[MENU_FROM_TASK].filter_item = &ui_filters.origin_tasks.items[item];
279 280 281 282 283
                        }

                        /* Destination task id */
                        {
                            /* Invalidate associated menu item to avoid issue with call back when updating the menu item check state */
284
                            ui_tree_view_menu_enable[MENU_TO_TASK].filter_item = NULL;
285
                            item = ui_filters_search_id (&ui_filters.destination_tasks, destination_task_id);
286
                            /* Update the menu item check state based on message ID state */
287
                            gtk_check_menu_item_set_active (
288 289 290
                                    GTK_CHECK_MENU_ITEM(ui_tree_view_menu_enable[MENU_TO_TASK].menu_enable),
                                    ui_filters.destination_tasks.items[item].enabled);
                            /* Set menu item label */
291 292 293 294
                            sprintf (label, "To:  %s",
                                     task_id_to_string (destination_task_id, destination_task_id_type));
                            gtk_menu_item_set_label (GTK_MENU_ITEM(ui_tree_view_menu_enable[MENU_TO_TASK].menu_enable),
                                                     label);
295
                            /* Save menu item associated to this row */
296 297
                            ui_tree_view_menu_enable[MENU_TO_TASK].filter_item =
                                    &ui_filters.destination_tasks.items[item];
298 299 300 301 302
                        }

                        /* Instance */
                        {
                            /* Invalidate associated menu item to avoid issue with call back when updating the menu item check state */
303
                            ui_tree_view_menu_enable[MENU_INSTANCE].filter_item = NULL;
304
                            item = ui_filters_search_id (&ui_filters.instances, instance);
305
                            /* Update the menu item check state based on message ID state */
306
                            gtk_check_menu_item_set_active (
307 308 309
                                    GTK_CHECK_MENU_ITEM(ui_tree_view_menu_enable[MENU_INSTANCE].menu_enable),
                                    ui_filters.instances.items[item].enabled);
                            /* Set menu item label */
winckel's avatar
winckel committed
310
                            sprintf (label, "Instance:  %s", instance_name);
311 312
                            gtk_menu_item_set_label (GTK_MENU_ITEM(ui_tree_view_menu_enable[MENU_INSTANCE].menu_enable),
                                                     label);
313
                            /* Save menu item associated to this row */
314
                            ui_tree_view_menu_enable[MENU_INSTANCE].filter_item = &ui_filters.instances.items[item];
315 316
                        }

317 318
                        gtk_menu_popup (GTK_MENU (ui_tree_view_menu), NULL, NULL, NULL, NULL, 0,
                                        gtk_get_current_event_time ());
319 320 321 322 323 324 325
                    }
                }

                /* Clear event */
                ui_tree_view_last_event = NULL;
            }

winckel's avatar
winckel committed
326
            if (buffer_current != buffer)
327
            {
winckel's avatar
winckel committed
328 329 330 331 332 333 334 335 336 337
                buffer_current = buffer;

                /* Clear the view */
                CHECK_FCT_DO(ui_signal_dissect_clear_view(text_view), return FALSE);

                if (ui_main_data.display_message_header)
                {
                    CHECK_FCT_DO(dissect_signal_header((buffer_t*)buffer, ui_signal_set_text, text_view), return FALSE);
                }

338 339 340 341 342 343
                if ((strcmp (message_id_to_string (message_id), "ERROR_LOG") == 0)
                        || (strcmp (message_id_to_string (message_id), "WARNING_LOG") == 0)
                        || (strcmp (message_id_to_string (message_id), "NOTICE_LOG") == 0)
                        || (strcmp (message_id_to_string (message_id), "INFO_LOG") == 0)
                        || (strcmp (message_id_to_string (message_id), "DEBUG_LOG") == 0)
                        || (strcmp (message_id_to_string (message_id), "GENERIC_LOG") == 0))
winckel's avatar
winckel committed
344 345 346 347 348 349 350
                {
                    gchar *data;
                    gint data_size;
                    uint32_t message_header_type_size;

                    if (ui_main_data.display_message_header)
                    {
351
                        ui_signal_set_text (text_view, "\n", 1);
winckel's avatar
winckel committed
352 353
                    }

354 355 356
                    message_header_type_size = get_message_header_type_size ();
                    data = (gchar *) buffer_at_offset ((buffer_t*) buffer, message_header_type_size);
                    data_size = get_message_size ((buffer_t*) buffer);
357
                    data_size = ui_callback_check_string (data, data_size, message_number);
winckel's avatar
winckel committed
358

winckel's avatar
winckel committed
359 360
                    g_info("    dump message %d: header type size: %u, data size: %u, buffer %p, follow last %d",
                           message_number, message_header_type_size, data_size, buffer, ui_main_data.follow_last);
winckel's avatar
winckel committed
361

362
                    ui_signal_set_text (text_view, data, data_size);
363 364
                }
                else
winckel's avatar
winckel committed
365
                {
winckel's avatar
winckel committed
366
                    g_info("    dissect message %d: id %d, buffer %p, follow last %d", message_number, message_id, buffer, ui_main_data.follow_last);
winckel's avatar
winckel committed
367 368 369 370

                    /* Dissect the signal */
                    CHECK_FCT_DO(dissect_signal((buffer_t*)buffer, ui_signal_set_text, text_view), return FALSE);
                }
Cedric Roux's avatar
Cedric Roux committed
371
            }
372
        }
Cedric Roux's avatar
 
Cedric Roux committed
373 374 375 376
    }
    return TRUE;
}

377
gboolean ui_callback_on_menu_enable(GtkWidget *widget, gpointer data)
378 379 380
{
    ui_tree_view_menu_enable_t *menu_enable = data;

381
    if (menu_enable->filter_item != NULL)
382
    {
383 384
        gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM(menu_enable->filter_item->menu_item),
                                        gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM(menu_enable->menu_enable)));
385
        menu_enable->filter_item = NULL;
386 387 388 389 390
    }

    return TRUE;
}

391
gboolean ui_callback_on_menu_color(GtkWidget *widget, gpointer data)
392
{
393
    ui_tree_view_menu_color_t *menu_color = data;
394

395 396 397 398
    GdkRGBA color;
    GtkWidget *color_chooser;
    gint response;

399 400 401
    color_chooser = gtk_color_chooser_dialog_new ("Select message background color", GTK_WINDOW(ui_main_data.window));
    gtk_color_chooser_set_use_alpha (GTK_COLOR_CHOOSER(color_chooser), FALSE);
    response = gtk_dialog_run (GTK_DIALOG (color_chooser));
402 403 404

    if (response == GTK_RESPONSE_OK)
    {
405
        int red, green, blue;
406 407 408 409 410 411
        char *color_string;

        color_string =
                menu_color->foreground ?
                        menu_color->menu_enable->filter_item->foreground :
                        menu_color->menu_enable->filter_item->background;
412

413
        gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER(color_chooser), &color);
414

415 416 417 418
        red = (int) (color.red * 255);
        green = (int) (color.green * 255);
        blue = (int) (color.blue * 255);

419 420 421
        snprintf (color_string, COLOR_SIZE, "#%02x%02x%02x", red, green, blue);
        ui_tree_view_refilter ();

422
        g_info("Selected color for %s %f->%02x %f->%02x %f->%02x %s",
423
                  menu_color->menu_enable->filter_item->name, color.red, red, color.green, green, color.blue, blue, color_string);
424
    }
425
    gtk_widget_destroy (color_chooser);
426 427 428 429

    return TRUE;
}

430
void ui_signal_add_to_list(gpointer data, gpointer user_data)
Cedric Roux's avatar
Cedric Roux committed
431
{
winckel's avatar
winckel committed
432
    gboolean goto_last = user_data ? TRUE : FALSE;
Cedric Roux's avatar
Cedric Roux committed
433
    buffer_t *signal_buffer;
434 435
    GtkTreePath *path;
    GtkTreeViewColumn *focus_column;
436 437
    uint32_t lte_frame;
    uint32_t lte_slot;
438 439
    uint32_t origin_task_id;
    uint32_t destination_task_id;
winckel's avatar
winckel committed
440
    uint32_t instance;
441 442
    char lte_time[15];

443 444 445 446
    g_assert(data != NULL);
    g_assert(origin_task_id_type != NULL);
    g_assert(destination_task_id_type != NULL);

447
    gtk_tree_view_get_cursor (GTK_TREE_VIEW(ui_main_data.messages_list), &path, &focus_column);
Cedric Roux's avatar
Cedric Roux committed
448

449
    signal_buffer = (buffer_t *) data;
Cedric Roux's avatar
Cedric Roux committed
450

451 452 453
    lte_frame = get_lte_frame (signal_buffer);
    lte_slot = get_lte_slot (signal_buffer);
    sprintf (lte_time, "%d.%02d", lte_frame, lte_slot);
454

455 456 457 458
    get_message_id (root, signal_buffer, &signal_buffer->message_id);
    origin_task_id = get_task_id (signal_buffer, origin_task_id_type);
    destination_task_id = get_task_id (signal_buffer, destination_task_id_type);
    instance = get_instance (signal_buffer);
459

460 461 462 463
    ui_tree_view_new_signal_ind (signal_buffer->message_number, lte_time, signal_buffer->message_id,
                                 message_id_to_string (signal_buffer->message_id), origin_task_id,
                                 task_id_to_string (origin_task_id, origin_task_id_type), destination_task_id,
                                 task_id_to_string (destination_task_id, destination_task_id_type), instance, data);
464

465 466 467 468 469 470 471 472 473 474 475 476 477 478
    if ((strcmp (message_id_to_string (signal_buffer->message_id), "ERROR_LOG") == 0)
            || (strcmp (message_id_to_string (signal_buffer->message_id), "WARNING_LOG") == 0)
            || (strcmp (message_id_to_string (signal_buffer->message_id), "NOTICE_LOG") == 0)
            || (strcmp (message_id_to_string (signal_buffer->message_id), "INFO_LOG") == 0)
            || (strcmp (message_id_to_string (signal_buffer->message_id), "DEBUG_LOG") == 0)
            || (strcmp (message_id_to_string (signal_buffer->message_id), "GENERIC_LOG") == 0))
    {
        gchar *string_terminal;
        gint string_terminal_size;
        uint32_t message_header_type_size;

        message_header_type_size = get_message_header_type_size ();
        string_terminal = (gchar *) buffer_at_offset ((buffer_t*) signal_buffer, message_header_type_size);
        string_terminal_size = get_message_size ((buffer_t*) signal_buffer);
479
        string_terminal_size = ui_callback_check_string (string_terminal, string_terminal_size, signal_buffer->message_number);
480 481 482
        ui_notebook_terminal_append_data(string_terminal, string_terminal_size);
    }

483 484
    /* Increment number of messages */
    ui_main_data.nb_message_received++;
485

winckel's avatar
winckel committed
486
    if ((ui_main_data.follow_last) && (goto_last))
487 488
    {
        /* Advance to the new last signal */
489
        ui_tree_view_select_row (ui_tree_view_get_filtered_number () - 1);
490
    }
Cedric Roux's avatar
Cedric Roux committed
491 492
}

493
static gboolean ui_handle_update_signal_list(gint fd, void *data, size_t data_length)
Cedric Roux's avatar
Cedric Roux committed
494 495 496
{
    pipe_new_signals_list_message_t *signal_list_message;

497
    /* Enable buttons to move in the list of signals */
498
    ui_set_sensitive_move_buttons (TRUE);
499

500
    signal_list_message = (pipe_new_signals_list_message_t *) data;
Cedric Roux's avatar
Cedric Roux committed
501 502 503 504

    g_assert(signal_list_message != NULL);
    g_assert(signal_list_message->signal_list != NULL);

505
    g_list_foreach (signal_list_message->signal_list, ui_signal_add_to_list, (gpointer) TRUE);
Cedric Roux's avatar
Cedric Roux committed
506

507
    /* Free the list but not user data associated with each element */
508
    g_list_free (signal_list_message->signal_list);
509
    /* Free the message */
510
    free (signal_list_message);
Cedric Roux's avatar
Cedric Roux committed
511

512
    ui_gtk_flush_events ();
513

Cedric Roux's avatar
Cedric Roux committed
514 515 516
    return TRUE;
}

517
static gboolean ui_handle_socket_connection_failed(gint fd)
Cedric Roux's avatar
Cedric Roux committed
518
{
winckel's avatar
winckel committed
519
    gtk_dialog_response(GTK_DIALOG (dialogbox_connect), GTK_RESPONSE_REJECT);
Cedric Roux's avatar
Cedric Roux committed
520 521 522 523

    return TRUE;
}

524
static gboolean ui_handle_socket_connection_lost(gint fd)
Cedric Roux's avatar
Cedric Roux committed
525
{
winckel's avatar
winckel committed
526 527 528 529 530 531 532 533 534 535 536 537 538
    if (operation_running)
    {
        operation_running = FALSE;
        if (ui_auto_reconnect)
        {
            ui_callback_on_connect (NULL, (gpointer) FALSE);
        }
        else
        {
            ui_enable_connect_button();
            ui_set_sensitive_save_message_buttons (TRUE);
        }
    }
539

Cedric Roux's avatar
Cedric Roux committed
540 541 542
    return TRUE;
}

543
static gboolean ui_handle_socket_xml_definition(gint fd, void *data, size_t data_length)
Cedric Roux's avatar
Cedric Roux committed
544 545 546
{
    pipe_xml_definition_message_t *xml_definition_message;

547
    xml_definition_message = (pipe_xml_definition_message_t *) data;
Cedric Roux's avatar
Cedric Roux committed
548 549 550
    g_assert(xml_definition_message != NULL);
    g_assert(data_length == sizeof(pipe_xml_definition_message_t));

551
    xml_parse_buffer (xml_definition_message->xml_definition, xml_definition_message->xml_definition_length);
Cedric Roux's avatar
Cedric Roux committed
552 553 554 555

    return TRUE;
}

556
gboolean ui_pipe_callback(gint source, gpointer user_data)
Cedric Roux's avatar
Cedric Roux committed
557
{
558 559 560
    void *input_data = NULL;
    size_t input_data_length = 0;
    pipe_input_header_t input_header;
Cedric Roux's avatar
Cedric Roux committed
561 562

    /* Read the header */
563
    if (read (source, &input_header, sizeof(input_header)) < 0)
564
    {
Cedric Roux's avatar
Cedric Roux committed
565 566 567 568 569 570 571
        g_warning("Failed to read from pipe %d: %s", source, g_strerror(errno));
        return FALSE;
    }

    input_data_length = input_header.message_size - sizeof(input_header);

    /* Checking for non-header part */
572 573
    if (input_data_length > 0)
    {
574
        input_data = malloc (input_data_length);
Cedric Roux's avatar
Cedric Roux committed
575

576
        if (read (source, input_data, input_data_length) < 0)
577
        {
Cedric Roux's avatar
Cedric Roux committed
578 579 580 581 582
            g_warning("Failed to read from pipe %d: %s", source, g_strerror(errno));
            return FALSE;
        }
    }

583 584
    switch (input_header.message_type)
    {
585 586
        case UI_PIPE_CONNECTION_FAILED:
            return ui_handle_socket_connection_failed (source);
winckel's avatar
winckel committed
587

588 589
        case UI_PIPE_CONNECTION_LOST:
            return ui_handle_socket_connection_lost (source);
winckel's avatar
winckel committed
590 591

        case UI_PIPE_XML_DEFINITION:
winckel's avatar
winckel committed
592
            gtk_dialog_response(GTK_DIALOG (dialogbox_connect), GTK_RESPONSE_OK);
winckel's avatar
winckel committed
593 594
            return ui_handle_socket_xml_definition (source, input_data, input_data_length);

595 596
        case UI_PIPE_UPDATE_SIGNAL_LIST:
            return ui_handle_update_signal_list (source, input_data, input_data_length);
winckel's avatar
winckel committed
597

598 599 600
        default:
            g_warning("[gui] Unhandled message type %u", input_header.message_type);
            g_assert_not_reached();
Cedric Roux's avatar
Cedric Roux committed
601 602 603 604
    }
    return FALSE;
}

winckel's avatar
winckel committed
605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639
gboolean ui_callback_on_auto_reconnect(GtkWidget *widget, gpointer data)
{
    gboolean enabled;
    gboolean changed = TRUE;

    gboolean toggle = (data != NULL) ? TRUE : FALSE;

    enabled = gtk_toggle_tool_button_get_active (GTK_TOGGLE_TOOL_BUTTON(ui_main_data.auto_reconnect));

    if (toggle)
    {
        gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON(ui_main_data.auto_reconnect), !enabled);
        return TRUE;
    }

    g_info("Auto reconnect event occurred %d %d ", toggle, enabled);

    ui_auto_reconnect = enabled;

    if (changed)
    {
        /* Set the tool tip text */
        if (enabled)
        {
            gtk_tool_item_set_tooltip_text (GTK_TOOL_ITEM(ui_main_data.auto_reconnect), "Disable automatic reconnection");
        }
        else
        {
            gtk_tool_item_set_tooltip_text (GTK_TOOL_ITEM(ui_main_data.auto_reconnect), "Enable automatic reconnection");
        }
    }

    return TRUE;
}

640
gboolean ui_callback_on_connect(GtkWidget *widget, gpointer data)
Cedric Roux's avatar
 
Cedric Roux committed
641
{
642
    /* We have to retrieve the ip address and ui_port of remote host */
winckel's avatar
winckel committed
643
    gboolean start = (data != NULL) ? TRUE : FALSE;
644
    int pipe_fd[2];
Cedric Roux's avatar
 
Cedric Roux committed
645

winckel's avatar
winckel committed
646
    if (start)
647
    {
winckel's avatar
winckel committed
648 649
        ui_port = atoi (gtk_entry_get_text (GTK_ENTRY(ui_main_data.port_entry)));
        ui_ip = gtk_entry_get_text (GTK_ENTRY(ui_main_data.ip_entry));
650 651
    }

winckel's avatar
winckel committed
652 653 654
    g_message("Connect event occurred to %s:%d %s", ui_ip, ui_port, start ? "START" : "RETRY");

    if (start)
655
    {
winckel's avatar
winckel committed
656 657 658 659 660 661 662 663 664 665 666
        if (strlen (ui_ip) == 0)
        {
            ui_notification_dialog (GTK_MESSAGE_ERROR, FALSE, "Connect", "Empty host ip address");
            return FALSE;
        }

        if (ui_port == 0)
        {
            ui_notification_dialog (GTK_MESSAGE_ERROR, FALSE, "Connect", "Invalid host ui_port value");
            return FALSE;
        }
Cedric Roux's avatar
Cedric Roux committed
667 668
    }

669 670 671 672 673
    if (operation_running == FALSE)
    {
        operation_running = TRUE;

        ui_pipe_new (pipe_fd, ui_pipe_callback, NULL);
Cedric Roux's avatar
Cedric Roux committed
674

675
        memcpy (ui_main_data.pipe_fd, pipe_fd, sizeof(int) * 2);
Cedric Roux's avatar
Cedric Roux committed
676

677 678
        /* Disable the connect button */
        ui_disable_connect_button ();
679

680
        ui_set_title ("connecting to %s:%d ...", ui_ip, ui_port);
681
        {
winckel's avatar
winckel committed
682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723
            const static char *message_formats[] =
            {
                "Connecting to %s:%d ...",
                "Connection lost!\n\n" "Trying to reconnect to %s:%d ..."
            };
            gint response;

            if (socket_connect_to_remote_host (ui_ip, ui_port, pipe_fd[1]) != 0)
            {
                ui_enable_connect_button ();
                operation_running = FALSE;
                return FALSE;
            }

            dialogbox_connect = gtk_message_dialog_new (GTK_WINDOW(ui_main_data.window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_OTHER,
                                                GTK_BUTTONS_CANCEL, message_formats[start ? 0 : 1], ui_ip, ui_port);
            gtk_window_set_title (GTK_WINDOW(dialogbox_connect), "Connect");

            response = gtk_dialog_run (GTK_DIALOG (dialogbox_connect));
            g_message("Connect dialog response %s (%d)", gtk_get_respose_string(response), response);

            if (response == GTK_RESPONSE_OK)
            {
                /* Connection is established */
                ui_set_sensitive_save_message_buttons (FALSE);
                ui_callback_signal_clear_list (NULL, NULL);
                ui_set_title ("%s:%d", ui_ip, ui_port);
            }
            else
            {
                /* Connection can not be established */
                if (response == GTK_RESPONSE_REJECT)
                {
                    /* Connection retry time-out */
                    ui_notification_dialog (GTK_MESSAGE_WARNING, FALSE, "Connect", "Failed to connect to provided host/ip address");
                }

                /* Re-enable connect button */
                ui_enable_connect_button();
                operation_running = FALSE;
            }
            gtk_widget_destroy (dialogbox_connect);
724
        }
Cedric Roux's avatar
Cedric Roux committed
725
    }
Cedric Roux's avatar
 
Cedric Roux committed
726 727 728 729

    return TRUE;
}

730
gboolean ui_callback_on_disconnect(GtkWidget *widget, gpointer data)
Cedric Roux's avatar
 
Cedric Roux committed
731
{
732
    g_message("Disconnect event occurred");
Cedric Roux's avatar
Cedric Roux committed
733

734
    ui_pipe_write_message (ui_main_data.pipe_fd[0], UI_PIPE_DISCONNECT_EVT, NULL, 0);
Cedric Roux's avatar
Cedric Roux committed
735

736
    ui_enable_connect_button ();
737 738
    operation_running = FALSE;

Cedric Roux's avatar
 
Cedric Roux committed
739 740 741
    return TRUE;
}

742
gboolean ui_callback_signal_go_to_first(GtkWidget *widget, gpointer data)
winckel's avatar
winckel committed
743
{
winckel's avatar
winckel committed
744
    gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON(ui_main_data.signals_go_to_last_button), FALSE);
745
    ui_tree_view_select_row (0);
winckel's avatar
winckel committed
746 747 748 749

    return TRUE;
}

750
gboolean ui_callback_signal_go_to(GtkWidget *widget, gpointer data)
751
{
752
    gtk_window_set_focus (GTK_WINDOW(ui_main_data.window), ui_main_data.signals_go_to_entry);
753 754 755
    return TRUE;
}

756
gboolean ui_callback_signal_go_to_entry(GtkWidget *widget, gpointer data)
757
{
winckel's avatar
winckel committed
758
    gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON(ui_main_data.signals_go_to_last_button), FALSE);
winckel's avatar
winckel committed
759
    // gtk_entry_buffer_set_text(GTK_ENTRY(ui_main_data.signals_go_to_entry), "");
760
    gtk_window_set_focus (GTK_WINDOW(ui_main_data.window), ui_main_data.messages_list);
761 762 763
    return TRUE;
}

764
gboolean ui_callback_signal_go_to_last(GtkWidget *widget, gpointer data)
765
{
winckel's avatar
winckel committed
766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787
    gboolean enable = (data != NULL) ? TRUE : FALSE;
    gboolean enabled;

    if (enable)
    {
        gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON(ui_main_data.signals_go_to_last_button), TRUE);
        return TRUE;
    }

    enabled = gtk_toggle_tool_button_get_active (GTK_TOGGLE_TOOL_BUTTON(ui_main_data.signals_go_to_last_button));

    g_info("Button signal go to last event occurred %d %d", enable, enabled);

    if (enabled)
    {
        ui_main_data.follow_last = TRUE;
        ui_tree_view_select_row (ui_tree_view_get_filtered_number () - 1);
    }
    else
    {
        ui_main_data.follow_last = FALSE;
    }
winckel's avatar
winckel committed
788 789 790

    return TRUE;
}
791

792
gboolean ui_callback_display_message_header(GtkWidget *widget, gpointer data)
winckel's avatar
winckel committed
793 794 795 796 797
{
    ui_main_data.display_message_header = !ui_main_data.display_message_header;
    // TODO refresh textview.
    return TRUE;
}
798

799
gboolean ui_callback_display_brace(GtkWidget *widget, gpointer data)
winckel's avatar
winckel committed
800 801 802
{
    ui_main_data.display_brace = !ui_main_data.display_brace;
    // TODO refresh textview.
803 804 805
    return TRUE;
}

806
gboolean ui_callback_signal_clear_list(GtkWidget *widget, gpointer data)
807 808
{
    /* Disable buttons to move in the list of signals */
809 810
    ui_set_sensitive_move_buttons (FALSE);
    ui_set_title ("");
811

812
    /* Clear list of signals */
813
    ui_tree_view_destroy_list (ui_main_data.messages_list);
winckel's avatar
winckel committed
814 815 816

    if (ui_main_data.text_view != NULL)
    {
817
        ui_signal_dissect_clear_view (ui_main_data.text_view);
winckel's avatar
winckel committed
818 819
    }

820 821
    ui_notebook_terminal_clear();

winckel's avatar
winckel committed
822 823 824
    return TRUE;
}

825
static void ui_callback_on_menu_items_selected(GtkWidget *widget, gpointer data)
winckel's avatar
winckel committed
826
{
827
    gboolean active = data != NULL;
winckel's avatar
winckel committed
828 829 830

    if (GTK_IS_CHECK_MENU_ITEM(widget))
    {
831
        gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM(widget), active);
winckel's avatar
winckel committed
832 833 834
    }
}

835
gboolean ui_callback_on_menu_none(GtkWidget *widget, gpointer data)
winckel's avatar
winckel committed
836 837 838
{
    GtkWidget *menu = (GtkWidget *) data;

839
    g_info("ui_callback_on_menu_none occurred %lx %lx)", (long) widget, (long) data);
winckel's avatar
winckel committed
840

841
    refresh_message_list = FALSE;
842
    gtk_container_foreach (GTK_CONTAINER(menu), ui_callback_on_menu_items_selected, (gpointer) FALSE);
843 844
    refresh_message_list = TRUE;

845
    if (filters_changed)
846
    {
847
        ui_tree_view_refilter ();
848 849
        filters_changed = FALSE;
    }
winckel's avatar
winckel committed
850 851 852 853

    return TRUE;
}

854
gboolean ui_callback_on_menu_all(GtkWidget *widget, gpointer data)
winckel's avatar
winckel committed
855 856 857
{
    GtkWidget *menu = (GtkWidget *) data;

858
    g_info("ui_callback_on_menu_all occurred %lx %lx)", (long) widget, (long) data);
winckel's avatar
winckel committed
859

860
    refresh_message_list = FALSE;
861
    gtk_container_foreach (GTK_CONTAINER(menu), ui_callback_on_menu_items_selected, (gpointer) TRUE);
862 863
    refresh_message_list = TRUE;

864
    if (filters_changed)
865
    {
866
        ui_tree_view_refilter ();
867 868
        filters_changed = FALSE;
    }
winckel's avatar
winckel committed
869

870 871 872
    return TRUE;
}

873
gboolean ui_callback_on_menu_item_selected(GtkWidget *widget, gpointer data)
874
{
winckel's avatar
winckel committed
875
    ui_filter_item_t *filter_entry = data;
winckel's avatar
winckel committed
876
    gboolean enabled;
winckel's avatar
winckel committed
877

878
    enabled = gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM(widget));
879 880 881
    if (filter_entry->enabled != enabled)
    {
        filter_entry->enabled = enabled;
882 883
        if (refresh_message_list)
        {
884
            ui_tree_view_refilter ();
885 886 887 888 889
        }
        else
        {
            filters_changed = TRUE;
        }
890
    }
891
    g_info("ui_callback_on_menu_item_selected occurred %p %p %s %d (%d messages to display)", widget, data, filter_entry->name, enabled, ui_tree_view_get_filtered_number());
winckel's avatar
winckel committed
892

893 894 895
    return TRUE;
}

896
gboolean ui_callback_on_tree_column_header_click(GtkWidget *widget, gpointer data)
winckel's avatar
winckel committed
897
{
898
    col_type_t col = (col_type_t) data;
winckel's avatar
winckel committed
899

900
    g_info("ui_callback_on_tree_column_header_click %d", col);
winckel's avatar
winckel committed
901 902
    switch (col)
    {
903 904 905
        case COL_MESSAGE:
            ui_show_filter_menu (&ui_main_data.menu_filter_messages, &ui_filters.messages);
            break;
winckel's avatar
winckel committed
906

907 908 909
        case COL_FROM_TASK:
            ui_show_filter_menu (&ui_main_data.menu_filter_origin_tasks, &ui_filters.origin_tasks);
            break;
winckel's avatar
winckel committed
910

911 912 913
        case COL_TO_TASK:
            ui_show_filter_menu (&ui_main_data.menu_filter_destination_tasks, &ui_filters.destination_tasks);
            break;
winckel's avatar
winckel committed
914

915 916 917
        case COL_INSTANCE:
            ui_show_filter_menu (&ui_main_data.menu_filter_instances, &ui_filters.instances);
            break;
winckel's avatar
winckel committed
918

919 920 921
        default:
            g_warning("Unknown column filter %d in call to ui_callback_on_tree_column_header_click", col);
            return FALSE;
winckel's avatar
winckel committed
922 923
    }

924 925
    return TRUE;
}