ui_callbacks.c 31.9 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
            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;
            }

696
            dialogbox_connect = gtk_message_dialog_new (NULL, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_OTHER,
winckel's avatar
winckel committed
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
                                                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
            dialogbox_connect = NULL;
725
        }
Cedric Roux's avatar
Cedric Roux committed
726
    }
Cedric Roux's avatar
 
Cedric Roux committed
727 728 729 730

    return TRUE;
}

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

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

737 738 739 740 741 742 743 744 745
    if (dialogbox_connect != NULL)
    {
        gtk_dialog_response(GTK_DIALOG (dialogbox_connect), GTK_RESPONSE_CLOSE);
    }
    else
    {
        ui_enable_connect_button ();
        operation_running = FALSE;
    }
746

Cedric Roux's avatar
 
Cedric Roux committed
747 748 749
    return TRUE;
}

750
gboolean ui_callback_signal_go_to_first(GtkWidget *widget, gpointer data)
winckel's avatar
winckel committed
751
{
winckel's avatar
winckel committed
752
    gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON(ui_main_data.signals_go_to_last_button), FALSE);
753
    ui_tree_view_select_row (0);
winckel's avatar
winckel committed
754 755 756 757

    return TRUE;
}

758
gboolean ui_callback_signal_go_to(GtkWidget *widget, gpointer data)
759
{
760
    gtk_window_set_focus (GTK_WINDOW(ui_main_data.window), ui_main_data.signals_go_to_entry);
761 762 763
    return TRUE;
}

764
gboolean ui_callback_signal_go_to_entry(GtkWidget *widget, gpointer data)
765
{
winckel's avatar
winckel committed
766
    gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON(ui_main_data.signals_go_to_last_button), FALSE);
winckel's avatar
winckel committed
767
    // gtk_entry_buffer_set_text(GTK_ENTRY(ui_main_data.signals_go_to_entry), "");
768
    gtk_window_set_focus (GTK_WINDOW(ui_main_data.window), ui_main_data.messages_list);
769 770 771
    return TRUE;
}

772
gboolean ui_callback_signal_go_to_last(GtkWidget *widget, gpointer data)
773
{
winckel's avatar
winckel committed
774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795
    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
796 797 798

    return TRUE;
}
799

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

807
gboolean ui_callback_display_brace(GtkWidget *widget, gpointer data)
winckel's avatar
winckel committed
808 809 810
{
    ui_main_data.display_brace = !ui_main_data.display_brace;
    // TODO refresh textview.
811 812 813
    return TRUE;
}

814
gboolean ui_callback_signal_clear_list(GtkWidget *widget, gpointer data)
815 816
{
    /* Disable buttons to move in the list of signals */
817 818
    ui_set_sensitive_move_buttons (FALSE);
    ui_set_title ("");
819

820
    /* Clear list of signals */
821
    ui_tree_view_destroy_list (ui_main_data.messages_list);
winckel's avatar
winckel committed
822 823 824

    if (ui_main_data.text_view != NULL)
    {
825
        ui_signal_dissect_clear_view (ui_main_data.text_view);
winckel's avatar
winckel committed
826 827
    }

828 829
    ui_notebook_terminal_clear();

winckel's avatar
winckel committed
830 831 832
    return TRUE;
}

833
static void ui_callback_on_menu_items_selected(GtkWidget *widget, gpointer data)
winckel's avatar
winckel committed
834
{
835
    gboolean active = data != NULL;
winckel's avatar
winckel committed
836 837 838

    if (GTK_IS_CHECK_MENU_ITEM(widget))
    {
839
        gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM(widget), active);
winckel's avatar
winckel committed
840 841 842
    }
}

843
gboolean ui_callback_on_menu_none(GtkWidget *widget, gpointer data)
winckel's avatar
winckel committed
844 845 846
{
    GtkWidget *menu = (GtkWidget *) data;

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

849
    refresh_message_list = FALSE;
850
    gtk_container_foreach (GTK_CONTAINER(menu), ui_callback_on_menu_items_selected, (gpointer) FALSE);
851 852
    refresh_message_list = TRUE;

853
    if (filters_changed)
854
    {
855
        ui_tree_view_refilter ();
856 857
        filters_changed = FALSE;
    }
winckel's avatar
winckel committed
858 859 860 861

    return TRUE;
}

862
gboolean ui_callback_on_menu_all(GtkWidget *widget, gpointer data)
winckel's avatar
winckel committed
863 864 865
{
    GtkWidget *menu = (GtkWidget *) data;

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

868
    refresh_message_list = FALSE;
869
    gtk_container_foreach (GTK_CONTAINER(menu), ui_callback_on_menu_items_selected, (gpointer) TRUE);
870 871
    refresh_message_list = TRUE;

872
    if (filters_changed)
873
    {
874
        ui_tree_view_refilter ();
875 876
        filters_changed = FALSE;
    }
winckel's avatar
winckel committed
877

878 879 880
    return TRUE;
}

881
gboolean ui_callback_on_menu_item_selected(GtkWidget *widget, gpointer data)
882
{
winckel's avatar
winckel committed
883
    ui_filter_item_t *filter_entry = data;
winckel's avatar
winckel committed
884
    gboolean enabled;
winckel's avatar
winckel committed
885

886
    enabled = gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM(widget));
887 888 889
    if (filter_entry->enabled != enabled)
    {
        filter_entry->enabled = enabled;
890 891
        if (refresh_message_list)
        {
892
            ui_tree_view_refilter ();
893 894 895 896 897
        }
        else
        {
            filters_changed = TRUE;
        }
898
    }
899
    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
900

901 902 903
    return TRUE;
}

904
gboolean ui_callback_on_tree_column_header_click(GtkWidget *widget, gpointer data)
winckel's avatar
winckel committed
905
{
906
    col_type_t col = (col_type_t) data;
winckel's avatar
winckel committed
907

908
    g_info("ui_callback_on_tree_column_header_click %d", col);
winckel's avatar
winckel committed
909 910
    switch (col)
    {
911 912 913
        case COL_MESSAGE:
            ui_show_filter_menu (&ui_main_data.menu_filter_messages, &ui_filters.messages);
            break;
winckel's avatar
winckel committed
914

915 916 917
        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
918

919 920 921
        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
922

923 924 925
        case COL_INSTANCE:
            ui_show_filter_menu (&ui_main_data.menu_filter_instances, &ui_filters.instances);
            break;
winckel's avatar
winckel committed
926

927 928 929
        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
930 931
    }

932 933
    return TRUE;
}