ui_callbacks.c 10.1 KB
Newer Older
Cedric Roux's avatar
 
Cedric Roux committed
1 2 3 4 5
#include <stdlib.h>
#include <stdint.h>

#include <gtk/gtk.h>

6
#include "rc.h"
Cedric Roux's avatar
 
Cedric Roux committed
7

Cedric Roux's avatar
Cedric Roux committed
8 9 10
#include "socket.h"

#include "ui_notif_dlg.h"
Cedric Roux's avatar
 
Cedric Roux committed
11
#include "ui_main_screen.h"
12
#include "ui_menu_bar.h"
Cedric Roux's avatar
 
Cedric Roux committed
13 14 15 16 17
#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
18
#include "ui_filters.h"
Cedric Roux's avatar
 
Cedric Roux committed
19

Cedric Roux's avatar
Cedric Roux committed
20 21 22 23
#include "types.h"
#include "locate_root.h"
#include "xml_parse.h"

24
gboolean ui_callback_on_open_messages(GtkWidget *widget, GdkEvent *event, gpointer data)
Cedric Roux's avatar
 
Cedric Roux committed
25
{
26
    g_debug("Open messages event occurred");
27 28 29 30 31 32 33
    CHECK_FCT(ui_messages_open_file_chooser());

    return TRUE;
}

gboolean ui_callback_on_save_messages(GtkWidget *widget, GdkEvent *event, gpointer data)
{
34
    g_debug("Save messages event occurred");
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
    // CHECK_FCT(ui_file_chooser());
    return TRUE;
}

gboolean ui_callback_on_open_filters(GtkWidget *widget, GdkEvent *event, gpointer data)
{
    g_debug("Open filters event occurred");
    CHECK_FCT(ui_filters_open_file_chooser());
    return TRUE;
}

gboolean ui_callback_on_save_filters(GtkWidget *widget, GdkEvent *event, gpointer data)
{
    g_debug("Save filters event occurred");
    CHECK_FCT(ui_filters_save_file_chooser());
Cedric Roux's avatar
 
Cedric Roux committed
50 51 52
    return TRUE;
}

53
gboolean ui_callback_on_about(GtkWidget *widget, GdkEvent *event, gpointer data)
Cedric Roux's avatar
 
Cedric Roux committed
54 55 56 57 58
{

    return TRUE;
}

59 60
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
61
{
62
    ui_text_view_t *text_view;
Cedric Roux's avatar
 
Cedric Roux committed
63 64
    GtkTreeIter iter;

65
    text_view = (ui_text_view_t *) user_data;
66 67 68

    g_assert(text_view != NULL);

69
    if (gtk_tree_model_get_iter (model, &iter, path))
Cedric Roux's avatar
 
Cedric Roux committed
70
    {
Cedric Roux's avatar
Cedric Roux committed
71 72 73
        GValue buffer_store = G_VALUE_INIT;
        gpointer buffer;

74
        gtk_tree_model_get_value (model, &iter, COL_BUFFER, &buffer_store);
Cedric Roux's avatar
Cedric Roux committed
75

76
        buffer = g_value_get_pointer (&buffer_store);
Cedric Roux's avatar
 
Cedric Roux committed
77 78 79

        if (!path_currently_selected)
        {
Cedric Roux's avatar
Cedric Roux committed
80
            /* Clear the view */
81
            CHECK_FCT_DO(ui_signal_dissect_clear_view(text_view), return FALSE);
Cedric Roux's avatar
 
Cedric Roux committed
82

83 84 85
            /* 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
86 87 88 89
    }
    return TRUE;
}

Cedric Roux's avatar
Cedric Roux committed
90 91 92
void ui_signal_add_to_list(gpointer data, gpointer user_data)
{
    buffer_t *signal_buffer;
93 94
    GtkTreePath *path;
    GtkTreeViewColumn *focus_column;
Cedric Roux's avatar
Cedric Roux committed
95

96
    gtk_tree_view_get_cursor (GTK_TREE_VIEW(ui_main_data.signalslist), &path, &focus_column);
Cedric Roux's avatar
Cedric Roux committed
97

98
    signal_buffer = (buffer_t *) data;
Cedric Roux's avatar
Cedric Roux committed
99

100 101 102 103
    get_message_id (root, signal_buffer, &signal_buffer->message_id);

    ui_tree_view_new_signal_ind (signal_buffer->message_number, message_id_to_string (signal_buffer->message_id),
                                 get_origin_task_id (signal_buffer), get_destination_task_id (signal_buffer), data);
104 105 106

    /* Increment number of messages */
    ui_main_data.nb_message_received++;
107 108 109 110 111 112 113

    /* Check if no signal was selected in the list or if it was the last signal */
    if ((ui_main_data.path_last == NULL) || (gtk_tree_path_compare(ui_main_data.path_last, path) == 0))
    {
        /* Advance to the new last signal */
        ui_callback_signal_go_to_last (NULL, NULL, NULL);
    }
Cedric Roux's avatar
Cedric Roux committed
114 115
}

116
static gboolean ui_handle_update_signal_list(gint fd, void *data, size_t data_length)
Cedric Roux's avatar
Cedric Roux committed
117 118 119
{
    pipe_new_signals_list_message_t *signal_list_message;

120
    /* Enable buttons to move in the list of signals */
121
    ui_set_sensitive_move_buttons (TRUE);
122

123
    signal_list_message = (pipe_new_signals_list_message_t *) data;
Cedric Roux's avatar
Cedric Roux committed
124 125 126 127

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

128
    g_list_foreach (signal_list_message->signal_list, ui_signal_add_to_list, NULL);
Cedric Roux's avatar
Cedric Roux committed
129

130
    /* Free the list but not user data associated with each element */
131
    g_list_free (signal_list_message->signal_list);
132
    /* Free the message */
133
    free (signal_list_message);
Cedric Roux's avatar
Cedric Roux committed
134 135 136 137 138 139 140 141

    return TRUE;
}

static gboolean ui_handle_socket_connection_failed(gint fd)
{
    GtkWidget *dialogbox;

142 143 144
    dialogbox = gtk_message_dialog_new (GTK_WINDOW(ui_main_data.window), GTK_DIALOG_DESTROY_WITH_PARENT,
                                        GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE,
                                        "Failed to connect to provided host/ip address");
Cedric Roux's avatar
Cedric Roux committed
145

146 147
    gtk_dialog_run (GTK_DIALOG(dialogbox));
    gtk_widget_destroy (dialogbox);
Cedric Roux's avatar
Cedric Roux committed
148 149

    /* Re-enable connect button */
150
    ui_enable_connect_button ();
Cedric Roux's avatar
Cedric Roux committed
151 152 153 154 155 156 157
    return TRUE;
}

static gboolean ui_handle_socket_connection_lost(gint fd)
{
    GtkWidget *dialogbox;

158 159 160
    dialogbox = gtk_message_dialog_new (GTK_WINDOW(ui_main_data.window), GTK_DIALOG_DESTROY_WITH_PARENT,
                                        GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE,
                                        "Connection with remote host has been lost");
Cedric Roux's avatar
Cedric Roux committed
161

162 163
    gtk_dialog_run (GTK_DIALOG(dialogbox));
    gtk_widget_destroy (dialogbox);
Cedric Roux's avatar
Cedric Roux committed
164 165

    /* Re-enable connect button */
166
    ui_enable_connect_button ();
Cedric Roux's avatar
Cedric Roux committed
167 168 169
    return TRUE;
}

170
static gboolean ui_handle_socket_xml_definition(gint fd, void *data, size_t data_length)
Cedric Roux's avatar
Cedric Roux committed
171 172 173
{
    pipe_xml_definition_message_t *xml_definition_message;

174
    xml_definition_message = (pipe_xml_definition_message_t *) data;
Cedric Roux's avatar
Cedric Roux committed
175 176 177
    g_assert(xml_definition_message != NULL);
    g_assert(data_length == sizeof(pipe_xml_definition_message_t));

178
    xml_parse_buffer (xml_definition_message->xml_definition, xml_definition_message->xml_definition_length);
Cedric Roux's avatar
Cedric Roux committed
179

180
    free (data);
Cedric Roux's avatar
Cedric Roux committed
181 182 183 184 185 186

    return TRUE;
}

gboolean ui_pipe_callback(gint source, gpointer user_data)
{
187 188 189
    void *input_data = NULL;
    size_t input_data_length = 0;
    pipe_input_header_t input_header;
Cedric Roux's avatar
Cedric Roux committed
190 191

    /* Read the header */
192 193
    if (read (source, &input_header, sizeof(input_header)) < 0)
    {
Cedric Roux's avatar
Cedric Roux committed
194 195 196 197 198 199 200
        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 */
201 202 203
    if (input_data_length > 0)
    {
        input_data = malloc (input_data_length);
Cedric Roux's avatar
Cedric Roux committed
204

205 206
        if (read (source, input_data, input_data_length) < 0)
        {
Cedric Roux's avatar
Cedric Roux committed
207 208 209 210 211
            g_warning("Failed to read from pipe %d: %s", source, g_strerror(errno));
            return FALSE;
        }
    }

212 213
    switch (input_header.message_type)
    {
Cedric Roux's avatar
Cedric Roux committed
214
        case UI_PIPE_CONNECTION_FAILED:
215
            return ui_handle_socket_connection_failed (source);
Cedric Roux's avatar
Cedric Roux committed
216
        case UI_PIPE_XML_DEFINITION:
217
            return ui_handle_socket_xml_definition (source, input_data, input_data_length);
Cedric Roux's avatar
Cedric Roux committed
218
        case UI_PIPE_CONNECTION_LOST:
219
            return ui_handle_socket_connection_lost (source);
Cedric Roux's avatar
Cedric Roux committed
220
        case UI_PIPE_UPDATE_SIGNAL_LIST:
221
            return ui_handle_update_signal_list (source, input_data, input_data_length);
Cedric Roux's avatar
Cedric Roux committed
222
        default:
223
            g_warning("[gui] Unhandled message type %u", input_header.message_type);
Cedric Roux's avatar
Cedric Roux committed
224 225 226 227 228
            g_assert_not_reached();
    }
    return FALSE;
}

229
gboolean ui_callback_on_connect(GtkWidget *widget, GdkEvent *event, gpointer data)
Cedric Roux's avatar
 
Cedric Roux committed
230 231 232
{
    /* We have to retrieve the ip address and port of remote host */
    const char *ip;
233 234
    uint16_t port;
    int pipe_fd[2];
Cedric Roux's avatar
 
Cedric Roux committed
235

236
    g_debug("Connect event occurred");
Cedric Roux's avatar
 
Cedric Roux committed
237

winckel's avatar
winckel committed
238 239
    port = atoi (gtk_entry_get_text (GTK_ENTRY(ui_main_data.port_entry)));
    ip = gtk_entry_get_text (GTK_ENTRY(ui_main_data.ip_entry));
Cedric Roux's avatar
 
Cedric Roux committed
240

241 242
    if ((ip == NULL) || (port == 0))
    {
Cedric Roux's avatar
Cedric Roux committed
243 244 245 246 247
        g_warning("NULL parameter given for ip address or port = 0");
        /* TODO: add dialog box here */
        return FALSE;
    }

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

250
    memcpy (ui_main_data.pipe_fd, pipe_fd, sizeof(int) * 2);
Cedric Roux's avatar
Cedric Roux committed
251 252

    /* Disable the connect button */
253
    ui_disable_connect_button ();
Cedric Roux's avatar
Cedric Roux committed
254

255 256 257 258 259
    ui_callback_signal_clear_list (widget, event, data);

    if (socket_connect_to_remote_host (ip, port, pipe_fd[1]) != 0)
    {
        ui_enable_connect_button ();
Cedric Roux's avatar
Cedric Roux committed
260 261
        return FALSE;
    }
Cedric Roux's avatar
 
Cedric Roux committed
262 263 264 265

    return TRUE;
}

266
gboolean ui_callback_on_disconnect(GtkWidget *widget, GdkEvent *event, gpointer data)
Cedric Roux's avatar
 
Cedric Roux committed
267 268 269
{
    /* We have to retrieve the ip address and port of remote host */

270
    g_debug("Disconnect event occurred");
Cedric Roux's avatar
Cedric Roux committed
271

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

274
    ui_enable_connect_button ();
Cedric Roux's avatar
 
Cedric Roux committed
275 276 277
    return TRUE;
}

278
gboolean ui_callback_signal_go_to(GtkWidget *widget, GdkEvent *event, gpointer data)
279
{
280
    ui_tree_view_select_row (ui_main_data.nb_message_received / 2, NULL);
281 282 283
    return TRUE;
}

284
gboolean ui_callback_signal_go_to_first(GtkWidget *widget, GdkEvent *event, gpointer data)
285
{
286
    ui_tree_view_select_row (0, NULL);
287 288 289
    return TRUE;
}

290
gboolean ui_callback_signal_go_to_last(GtkWidget *widget, GdkEvent *event, gpointer data)
291
{
292 293 294 295 296
    GtkTreePath *path;

    ui_tree_view_select_row (ui_main_data.nb_message_received - 1, &path);
    ui_main_data.path_last = path;

297 298 299
    return TRUE;
}

300
gboolean ui_callback_signal_clear_list(GtkWidget *widget, GdkEvent *event, gpointer data)
301 302
{
    /* Disable buttons to move in the list of signals */
303
    ui_set_sensitive_move_buttons (FALSE);
304

305 306
    /* Clear list of signals */
    ui_tree_view_destroy_list (ui_main_data.signalslist);
307 308 309
    return TRUE;
}

310
gboolean ui_callback_on_menu_item_selected(GtkWidget *widget, gpointer data)
311
{
winckel's avatar
winckel committed
312
    ui_filter_item_t *filter_entry = data;
winckel's avatar
winckel committed
313
    gboolean enabled;
winckel's avatar
winckel committed
314

winckel's avatar
winckel committed
315 316
    enabled = gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM(widget));
    filter_entry->enabled = enabled;
winckel's avatar
winckel committed
317
    // g_debug("ui_callback_on_menu_item_selected occurred %x %x %s %d", (int) widget, (int) data, filter_entry->name, enabled);
winckel's avatar
winckel committed
318

319 320 321
    return TRUE;
}

winckel's avatar
winckel committed
322 323 324 325
gboolean ui_callback_on_tree_column_header_click(GtkWidget *widget, gpointer data)
{
    col_type_e col = (col_type_e) data;

326
    // g_debug("ui_callback_on_tree_column_header_click %x", col);
winckel's avatar
winckel committed
327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345
    switch (col)
    {
        case COL_SIGNAL:
            ui_show_filter_menu (&ui_main_data.menu_filter_messages, &ui_filters.messages);
            break;

        case COL_FROM_TASK:
            ui_show_filter_menu (&ui_main_data.menu_filter_origin_tasks, &ui_filters.origin_tasks);
            break;

        case COL_TO_TASK:
            ui_show_filter_menu (&ui_main_data.menu_filter_destination_tasks, &ui_filters.destination_tasks);
            break;

        default:
            g_warning("Unknown column filter %d in call to ui_callback_on_tree_column_header_click", col);
            return FALSE;
    }

346 347
    return TRUE;
}