X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=gfio.c;h=4bee83be388b128f849cc669fc07e7d8e1207195;hp=5413da29d7fd153f82f054e91725e9b16c9d067c;hb=41666588eed4ed830b1fabd0458eb2b0a93f0147;hpb=6a4cf74fc2521b601cb1cc9478526cc441830a5c diff --git a/gfio.c b/gfio.c index 5413da29..4bee83be 100644 --- a/gfio.c +++ b/gfio.c @@ -33,6 +33,7 @@ #include "gfio.h" #include "ghelpers.h" #include "goptions.h" +#include "gerror.h" #include "graph.h" static int gfio_server_running; @@ -75,8 +76,7 @@ static struct button_spec { }; static void gfio_update_thread_status(struct gui_entry *ge, char *status_message, double perc); -static void gfio_update_thread_status_all(char *status_message, double perc); -static void report_error(GError *error); +static void gfio_update_thread_status_all(struct gui *ui, char *status_message, double perc); static struct graph *setup_iops_graph(void) { @@ -347,6 +347,7 @@ static struct graph *setup_clat_graph(char *title, unsigned int *ovals, g = graph_new(xdim, ydim, gfio_graph_font); graph_title(g, title); graph_x_title(g, "Percentile"); + graph_y_title(g, "Time"); for (i = 0; i < len; i++) { char fbuf[8]; @@ -657,6 +658,7 @@ static struct graph *setup_lat_bucket_graph(const char *title, double *lat, g = graph_new(xdim, ydim, gfio_graph_font); graph_title(g, title); graph_x_title(g, "Buckets"); + graph_y_title(g, "Percent"); for (i = 0; i < len; i++) { graph_add_label(g, labels[i]); @@ -872,13 +874,13 @@ static void gfio_add_total_depths_tree(GtkListStore *model, static void gfio_show_io_depths(GtkWidget *vbox, struct thread_stat *ts) { - GtkWidget *frame, *box, *tree_view; + GtkWidget *frame, *box, *tree_view = NULL; GtkTreeSelection *selection; GtkListStore *model; GType types[FIO_IO_U_MAP_NR + 1]; int i; -#define NR_LABELS 10 - const char *labels[NR_LABELS] = { "Depth", "0", "1", "2", "4", "8", "16", "32", "64", ">= 64" }; + const char *labels[] = { "Depth", "0", "1", "2", "4", "8", "16", "32", "64", ">= 64" }; + const int nr_labels = ARRAYSIZE(labels); frame = gtk_frame_new("IO depths"); gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 5); @@ -886,10 +888,10 @@ static void gfio_show_io_depths(GtkWidget *vbox, struct thread_stat *ts) box = gtk_hbox_new(FALSE, 3); gtk_container_add(GTK_CONTAINER(frame), box); - for (i = 0; i < NR_LABELS; i++) + for (i = 0; i < nr_labels; i++) types[i] = G_TYPE_STRING; - model = gtk_list_store_newv(NR_LABELS, types); + model = gtk_list_store_newv(nr_labels, types); tree_view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(model)); gtk_widget_set_can_focus(tree_view, FALSE); @@ -900,12 +902,12 @@ static void gfio_show_io_depths(GtkWidget *vbox, struct thread_stat *ts) selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view)); gtk_tree_selection_set_mode(GTK_TREE_SELECTION(selection), GTK_SELECTION_BROWSE); - for (i = 0; i < NR_LABELS; i++) + for (i = 0; i < nr_labels; i++) tree_view_column(tree_view, i, labels[i], ALIGN_RIGHT | UNSORTABLE); - gfio_add_total_depths_tree(model, ts, NR_LABELS); - gfio_add_sc_depths_tree(model, ts, NR_LABELS, 1); - gfio_add_sc_depths_tree(model, ts, NR_LABELS, 0); + gfio_add_total_depths_tree(model, ts, nr_labels); + gfio_add_sc_depths_tree(model, ts, nr_labels, 1); + gfio_add_sc_depths_tree(model, ts, nr_labels, 0); gtk_box_pack_start(GTK_BOX(box), tree_view, TRUE, FALSE, 3); } @@ -1024,7 +1026,7 @@ static GtkWidget *gfio_disk_util_get_vbox(struct gui_entry *ge) scroll = get_scrolled_window(5); vbox = gtk_vbox_new(FALSE, 3); box = gtk_hbox_new(FALSE, 0); - gtk_box_pack_start(GTK_BOX(vbox), box, TRUE, FALSE, 5); + gtk_box_pack_start(GTK_BOX(vbox), box, FALSE, FALSE, 5); gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scroll), vbox); res_notebook = get_results_window(ge); @@ -1217,7 +1219,9 @@ static void gfio_display_ts(struct fio_client *client, struct thread_stat *ts, static void gfio_text_op(struct fio_client *client, struct fio_net_cmd *cmd) { struct cmd_text_pdu *p = (struct cmd_text_pdu *) cmd->payload; - struct gui *ui = &main_ui; + struct gfio_client *gc = client->client_data; + struct gui_entry *ge = gc->ge; + struct gui *ui = ge->ui; GtkTreeIter iter; struct tm *tm; time_t sec; @@ -1532,7 +1536,7 @@ static void gfio_update_all_eta(struct jobs_eta *je) sprintf(dst, " - %s", eta_str); } - gfio_update_thread_status_all(output, perc); + gfio_update_thread_status_all(ui, output, perc); gdk_threads_leave(); } @@ -1577,12 +1581,12 @@ static void gfio_update_thread_status(struct gui_entry *ge, strncpy(message, status_message, sizeof(message) - 1); gtk_progress_bar_set_text(GTK_PROGRESS_BAR(ge->thread_status_pb), m); gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(ge->thread_status_pb), perc / 100.0); - gtk_widget_queue_draw(main_ui.window); + gtk_widget_queue_draw(ge->ui->window); } -static void gfio_update_thread_status_all(char *status_message, double perc) +static void gfio_update_thread_status_all(struct gui *ui, char *status_message, + double perc) { - struct gui *ui = &main_ui; static char message[100]; const char *m = message; @@ -1704,6 +1708,15 @@ static void gfio_client_iolog(struct fio_client *client, struct cmd_iolog_pdu *p free(pdu); } +static void gfio_client_removed(struct fio_client *client) +{ + struct gfio_client *gc = client->client_data; + + assert(gc->client == client); + fio_put_client(gc->client); + gc->client = NULL; +} + struct client_ops gfio_client_ops = { .text = gfio_text_op, .disk_util = gfio_disk_util_op, @@ -1719,6 +1732,7 @@ struct client_ops gfio_client_ops = { .start = gfio_client_start, .job_start = gfio_client_job_start, .iolog = gfio_client_iolog, + .removed = gfio_client_removed, .eta_msec = FIO_CLIENT_DEF_ETA_MSEC, .stay_connected = 1, .client_type = FIO_CLIENT_TYPE_GUI, @@ -1738,12 +1752,17 @@ static void ge_destroy(struct gui_entry *ge) fio_put_client(gc->client); } + free(ge->job_file); + free(ge->host); flist_del(&ge->list); free(ge); } static void ge_widget_destroy(GtkWidget *w, gpointer data) { + struct gui_entry *ge = (struct gui_entry *) data; + + ge_destroy(ge); } static void gfio_quit(struct gui *ui) @@ -1761,7 +1780,9 @@ static void gfio_quit(struct gui *ui) static void quit_clicked(__attribute__((unused)) GtkWidget *widget, __attribute__((unused)) gpointer data) { - gfio_quit(data); + struct gui *ui = (struct gui *) data; + + gfio_quit(ui); } static void *job_thread(void *arg) @@ -1774,36 +1795,17 @@ static void *job_thread(void *arg) return NULL; } -static int send_job_files(struct gui_entry *ge) +static int send_job_file(struct gui_entry *ge) { struct gfio_client *gc = ge->client; - int i, ret = 0; - - for (i = 0; i < ge->nr_job_files; i++) { - ret = fio_client_send_ini(gc->client, ge->job_files[i]); - if (ret < 0) { - GError *error; + int ret = 0; - error = g_error_new(g_quark_from_string("fio"), 1, "Failed to send file %s: %s\n", ge->job_files[i], strerror(-ret)); - report_error(error); - g_error_free(error); - break; - } else if (ret) - break; + ret = fio_client_send_ini(gc->client, ge->job_file); + if (!ret) + return 0; - free(ge->job_files[i]); - ge->job_files[i] = NULL; - } - while (i < ge->nr_job_files) { - free(ge->job_files[i]); - ge->job_files[i] = NULL; - i++; - } - - free(ge->job_files); - ge->job_files = NULL; - ge->nr_job_files = 0; - return ret; + gfio_report_error(ge, "Failed to send file %s: %s\n", ge->job_file, strerror(-ret)); + return 1; } static void *server_thread(void *arg) @@ -1815,10 +1817,8 @@ static void *server_thread(void *arg) return NULL; } -static void gfio_start_server(void) +static void gfio_start_server(struct gui *ui) { - struct gui *ui = &main_ui; - if (!gfio_server_running) { gfio_server_running = 1; pthread_create(&ui->server_t, NULL, server_thread, NULL); @@ -1838,93 +1838,6 @@ static void start_job_clicked(__attribute__((unused)) GtkWidget *widget, static void file_open(GtkWidget *w, gpointer data); -static void connect_clicked(GtkWidget *widget, gpointer data) -{ - struct gui_entry *ge = data; - struct gfio_client *gc = ge->client; - - if (ge->state == GE_STATE_NEW) { - int ret; - - if (!ge->nr_job_files) - file_open(widget, ge->ui); - if (!ge->nr_job_files) - return; - - gc = ge->client; - - gtk_progress_bar_set_text(GTK_PROGRESS_BAR(ge->thread_status_pb), "No jobs running"); - gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(ge->thread_status_pb), 0.0); - ret = fio_client_connect(gc->client); - if (!ret) { - if (!ge->ui->handler_running) - pthread_create(&ge->ui->t, NULL, job_thread, ge->ui); - gfio_set_state(ge, GE_STATE_CONNECTED); - } else { - GError *error; - - error = g_error_new(g_quark_from_string("fio"), 1, "Failed to connect to %s: %s\n", ge->client->client->hostname, strerror(-ret)); - report_error(error); - g_error_free(error); - } - } else { - fio_client_terminate(gc->client); - gfio_set_state(ge, GE_STATE_NEW); - clear_ge_ui_info(ge); - } -} - -static void send_clicked(GtkWidget *widget, gpointer data) -{ - struct gui_entry *ge = data; - - if (send_job_files(ge)) { - GError *error; - - error = g_error_new(g_quark_from_string("fio"), 1, "Failed to send one or more job files for client %s", ge->client->client->hostname); - report_error(error); - g_error_free(error); - - gtk_widget_set_sensitive(ge->button[GFIO_BUTTON_START], 1); - } -} - -static void on_info_bar_response(GtkWidget *widget, gint response, - gpointer data) -{ - struct gui *ui = &main_ui; - - if (response == GTK_RESPONSE_OK) { - gtk_widget_destroy(widget); - ui->error_info_bar = NULL; - } -} - -static void report_error(GError *error) -{ - struct gui *ui = &main_ui; - - if (ui->error_info_bar == NULL) { - ui->error_info_bar = gtk_info_bar_new_with_buttons(GTK_STOCK_OK, - GTK_RESPONSE_OK, - NULL); - g_signal_connect(ui->error_info_bar, "response", G_CALLBACK(on_info_bar_response), NULL); - gtk_info_bar_set_message_type(GTK_INFO_BAR(ui->error_info_bar), - GTK_MESSAGE_ERROR); - - ui->error_label = gtk_label_new(error->message); - GtkWidget *container = gtk_info_bar_get_content_area(GTK_INFO_BAR(ui->error_info_bar)); - gtk_container_add(GTK_CONTAINER(container), ui->error_label); - - gtk_box_pack_start(GTK_BOX(ui->vbox), ui->error_info_bar, FALSE, FALSE, 0); - gtk_widget_show_all(ui->vbox); - } else { - char buffer[256]; - snprintf(buffer, sizeof(buffer), "Failed to open file."); - gtk_label_set(GTK_LABEL(ui->error_label), buffer); - } -} - struct connection_widgets { GtkWidget *hentry; @@ -1966,15 +1879,18 @@ static void hostname_cb(GtkEntry *entry, gpointer data) } } -static int get_connection_details(char **host, int *port, int *type, - int *server_start) +static int get_connection_details(struct gui_entry *ge) { GtkWidget *dialog, *box, *vbox, *hbox, *frame, *pentry; struct connection_widgets cw; + struct gui *ui = ge->ui; char *typeentry; + if (ge->host) + return 0; + dialog = gtk_dialog_new_with_buttons("Connection details", - GTK_WINDOW(main_ui.window), + GTK_WINDOW(ui->window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, NULL); @@ -2044,36 +1960,98 @@ static int get_connection_details(char **host, int *port, int *type, return 1; } - *host = strdup(gtk_entry_get_text(GTK_ENTRY(cw.hentry))); - *port = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(pentry)); + ge->host = strdup(gtk_entry_get_text(GTK_ENTRY(cw.hentry))); + ge->port = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(pentry)); typeentry = gtk_combo_box_get_active_text(GTK_COMBO_BOX(cw.combo)); if (!typeentry || !strncmp(typeentry, "IPv4", 4)) - *type = Fio_client_ipv4; + ge->type = Fio_client_ipv4; else if (!strncmp(typeentry, "IPv6", 4)) - *type = Fio_client_ipv6; + ge->type = Fio_client_ipv6; else - *type = Fio_client_socket; + ge->type = Fio_client_socket; g_free(typeentry); - *server_start = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(cw.button)); + ge->server_start = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(cw.button)); gtk_widget_destroy(dialog); return 0; } +static void gfio_set_client(struct gfio_client *gc, struct fio_client *client) +{ + gc->client = fio_get_client(client); + client->client_data = gc; +} + static void gfio_client_added(struct gui_entry *ge, struct fio_client *client) { struct gfio_client *gc; gc = malloc(sizeof(*gc)); memset(gc, 0, sizeof(*gc)); + options_default_fill(&gc->o); gc->ge = ge; - gc->client = fio_get_client(client); - ge->client = gc; + gfio_set_client(gc, client); +} - client->client_data = gc; +static void connect_clicked(GtkWidget *widget, gpointer data) +{ + struct gui_entry *ge = data; + struct gfio_client *gc = ge->client; + + if (ge->state == GE_STATE_NEW) { + int ret; + + if (!ge->job_file) + file_open(widget, ge->ui); + if (!ge->job_file) + return; + + gc = ge->client; + + if (!gc->client) { + struct fio_client *client; + + if (get_connection_details(ge)) { + gfio_report_error(ge, "Failed to get connection details\n"); + return; + } + + client = fio_client_add_explicit(&gfio_client_ops, ge->host, ge->type, ge->port); + if (!client) { + gfio_report_error(ge, "Failed to add client %s\n", ge->host); + free(ge->host); + ge->host = NULL; + return; + } + gfio_set_client(gc, client); + } + + gtk_progress_bar_set_text(GTK_PROGRESS_BAR(ge->thread_status_pb), "No jobs running"); + gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(ge->thread_status_pb), 0.0); + ret = fio_client_connect(gc->client); + if (!ret) { + if (!ge->ui->handler_running) + pthread_create(&ge->ui->t, NULL, job_thread, ge->ui); + gfio_set_state(ge, GE_STATE_CONNECTED); + } else { + gfio_report_error(ge, "Failed to connect to %s: %s\n", ge->client->client->hostname, strerror(-ret)); + } + } else { + fio_client_terminate(gc->client); + gfio_set_state(ge, GE_STATE_NEW); + clear_ge_ui_info(ge); + } +} + +static void send_clicked(GtkWidget *widget, gpointer data) +{ + struct gui_entry *ge = data; + + if (send_job_file(ge)) + gtk_widget_set_sensitive(ge->button[GFIO_BUTTON_START], 1); } static GtkWidget *new_client_page(struct gui_entry *ge); @@ -2091,19 +2069,19 @@ static struct gui_entry *alloc_new_gui_entry(struct gui *ui) return ge; } -static struct gui_entry *get_new_ge_with_tab(const char *name) +static struct gui_entry *get_new_ge_with_tab(struct gui *ui, const char *name) { struct gui_entry *ge; - ge = alloc_new_gui_entry(&main_ui); + ge = alloc_new_gui_entry(ui); ge->vbox = new_client_page(ge); g_signal_connect(ge->vbox, "destroy", G_CALLBACK(ge_widget_destroy), ge); ge->page_label = gtk_label_new(name); - ge->page_num = gtk_notebook_append_page(GTK_NOTEBOOK(main_ui.notebook), ge->vbox, ge->page_label); + ge->page_num = gtk_notebook_append_page(GTK_NOTEBOOK(ui->notebook), ge->vbox, ge->page_label); - gtk_widget_show_all(main_ui.window); + gtk_widget_show_all(ui->window); return ge; } @@ -2112,7 +2090,7 @@ static void file_new(GtkWidget *w, gpointer data) struct gui *ui = (struct gui *) data; struct gui_entry *ge; - ge = get_new_ge_with_tab("Untitled"); + ge = get_new_ge_with_tab(ui, "Untitled"); gtk_notebook_set_current_page(GTK_NOTEBOOK(ui->notebook), ge->page_num); } @@ -2120,7 +2098,8 @@ static void file_new(GtkWidget *w, gpointer data) * Return the 'ge' corresponding to the tab. If the active tab is the * main tab, open a new tab. */ -static struct gui_entry *get_ge_from_page(gint cur_page, int *created) +static struct gui_entry *get_ge_from_page(struct gui *ui, gint cur_page, + int *created) { struct flist_head *entry; struct gui_entry *ge; @@ -2128,13 +2107,13 @@ static struct gui_entry *get_ge_from_page(gint cur_page, int *created) if (!cur_page) { if (created) *created = 1; - return get_new_ge_with_tab("Untitled"); + return get_new_ge_with_tab(ui, "Untitled"); } if (created) *created = 0; - flist_for_each(entry, &main_ui.list) { + flist_for_each(entry, &ui->list) { ge = flist_entry(entry, struct gui_entry, list); if (ge->page_num == cur_page) return ge; @@ -2153,7 +2132,7 @@ static struct gui_entry *get_ge_from_cur_tab(struct gui *ui) */ cur_page = gtk_notebook_get_current_page(GTK_NOTEBOOK(ui->notebook)); if (cur_page) - return get_ge_from_page(cur_page, NULL); + return get_ge_from_page(ui, cur_page, NULL); return NULL; } @@ -2202,40 +2181,31 @@ static gchar *get_filename_from_uri(const gchar *uri) return strdup(uri + 7); } -static int do_file_open(struct gui_entry *ge, const gchar *uri, char *host, - int type, int port) +static int do_file_open(struct gui_entry *ge, const gchar *uri) { struct fio_client *client; - gchar *filename; - - filename = get_filename_from_uri(uri); - ge->job_files = realloc(ge->job_files, (ge->nr_job_files + 1) * sizeof(char *)); - ge->job_files[ge->nr_job_files] = strdup(filename); - ge->nr_job_files++; + assert(!ge->job_file); - client = fio_client_add_explicit(&gfio_client_ops, host, type, port); - if (!client) { - GError *error; + ge->job_file = get_filename_from_uri(uri); - error = g_error_new(g_quark_from_string("fio"), 1, - "Failed to add client %s", host); - report_error(error); - g_error_free(error); - return 1; + client = fio_client_add_explicit(&gfio_client_ops, ge->host, ge->type, ge->port); + if (client) { + gfio_client_added(ge, client); + file_add_recent(ge->ui, uri); + return 0; } - gfio_client_added(ge, client); - file_add_recent(ge->ui, uri); - return 0; + gfio_report_error(ge, "Failed to add client %s\n", ge->host); + free(ge->host); + ge->host = NULL; + return 1; } static int do_file_open_with_tab(struct gui *ui, const gchar *uri) { - int port, type, server_start; struct gui_entry *ge; gint cur_page; - char *host; int ret, ge_is_new = 0; /* @@ -2243,28 +2213,26 @@ static int do_file_open_with_tab(struct gui *ui, const gchar *uri) * current tab already has a client. */ cur_page = gtk_notebook_get_current_page(GTK_NOTEBOOK(ui->notebook)); - ge = get_ge_from_page(cur_page, &ge_is_new); + ge = get_ge_from_page(ui, cur_page, &ge_is_new); if (ge->client) { - ge = get_new_ge_with_tab("Untitled"); + ge = get_new_ge_with_tab(ui, "Untitled"); ge_is_new = 1; } gtk_notebook_set_current_page(GTK_NOTEBOOK(ui->notebook), ge->page_num); - if (get_connection_details(&host, &port, &type, &server_start)) { + if (get_connection_details(ge)) { if (ge_is_new) gtk_widget_destroy(ge->vbox); return 1; } - ret = do_file_open(ge, uri, host, type, port); - - free(host); + ret = do_file_open(ge, uri); if (!ret) { - if (server_start) - gfio_start_server(); + if (ge->server_start) + gfio_start_server(ui); } else { if (ge_is_new) gtk_widget_destroy(ge->vbox); @@ -2289,8 +2257,8 @@ static void file_open(GtkWidget *w, gpointer data) { struct gui *ui = data; GtkWidget *dialog; - GSList *filenames, *fn_glist; GtkFileFilter *filter; + gchar *filename; dialog = gtk_file_chooser_dialog_new("Open File", GTK_WINDOW(ui->window), @@ -2298,7 +2266,7 @@ static void file_open(GtkWidget *w, gpointer data) GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL); - gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), TRUE); + gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), FALSE); filter = gtk_file_filter_new(); gtk_file_filter_add_pattern(filter, "*.fio"); @@ -2313,18 +2281,12 @@ static void file_open(GtkWidget *w, gpointer data) return; } - fn_glist = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(dialog)); + filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); gtk_widget_destroy(dialog); - filenames = fn_glist; - while (filenames != NULL) { - if (do_file_open_with_tab(ui, filenames->data)) - break; - filenames = g_slist_next(filenames); - } - - g_slist_free(fn_glist); + do_file_open_with_tab(ui, filename); + g_free(filename); } static void file_save(GtkWidget *w, gpointer data) @@ -2416,8 +2378,11 @@ static void send_job_entry(GtkWidget *w, gpointer data) static void edit_job_entry(GtkWidget *w, gpointer data) { struct gui *ui = (struct gui *) data; + struct gui_entry *ge; - gopt_get_options_window(ui->window); + ge = get_ge_from_cur_tab(ui); + if (ge && ge->client) + gopt_get_options_window(ui->window, &ge->client->o); } static void start_job_entry(GtkWidget *w, gpointer data) @@ -2471,10 +2436,11 @@ static void preferences(GtkWidget *w, gpointer data) { GtkWidget *dialog, *frame, *box, **buttons, *vbox, *font; GtkWidget *hbox, *spin, *entry, *spin_int; + struct gui *ui = (struct gui *) data; int i; dialog = gtk_dialog_new_with_buttons("Preferences", - GTK_WINDOW(main_ui.window), + GTK_WINDOW(ui->window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, @@ -2900,7 +2866,7 @@ static gboolean notebook_switch_page(GtkNotebook *notebook, GtkWidget *widget, } set_job_menu_visible(ui, 1); - ge = get_ge_from_page(page, NULL); + ge = get_ge_from_page(ui, page, NULL); if (ge) update_button_states(ui, ge); @@ -2986,13 +2952,12 @@ static void add_recent_file_items(struct gui *ui) } static void drag_and_drop_received(GtkWidget *widget, GdkDragContext *ctx, - gint x, gint y, GtkSelectionData *data, - guint info, guint time) + gint x, gint y, GtkSelectionData *seldata, + guint info, guint time, gpointer *data) { - struct gui *ui = &main_ui; + struct gui *ui = (struct gui *) data; gchar **uris; GtkWidget *source; - int i; source = gtk_drag_get_source_widget(ctx); if (source && widget == gtk_widget_get_toplevel(source)) { @@ -3000,18 +2965,14 @@ static void drag_and_drop_received(GtkWidget *widget, GdkDragContext *ctx, return; } - uris = gtk_selection_data_get_uris(data); + uris = gtk_selection_data_get_uris(seldata); if (!uris) { gtk_drag_finish(ctx, FALSE, FALSE, time); return; } - i = 0; - while (uris[i]) { - if (do_file_open_with_tab(ui, uris[i])) - break; - i++; - } + if (uris[0]) + do_file_open_with_tab(ui, uris[0]); gtk_drag_finish(ctx, TRUE, FALSE, time); g_strfreev(uris); @@ -3040,8 +3001,8 @@ static void init_ui(int *argc, char **argv[], struct gui *ui) gtk_window_set_title(GTK_WINDOW(ui->window), "fio"); gtk_window_set_default_size(GTK_WINDOW(ui->window), 1024, 768); - g_signal_connect(ui->window, "delete-event", G_CALLBACK(quit_clicked), NULL); - g_signal_connect(ui->window, "destroy", G_CALLBACK(quit_clicked), NULL); + g_signal_connect(ui->window, "delete-event", G_CALLBACK(quit_clicked), ui); + g_signal_connect(ui->window, "destroy", G_CALLBACK(quit_clicked), ui); ui->vbox = gtk_vbox_new(FALSE, 0); gtk_container_add(GTK_CONTAINER(ui->window), ui->vbox); @@ -3060,7 +3021,7 @@ static void init_ui(int *argc, char **argv[], struct gui *ui) gtk_container_add(GTK_CONTAINER(ui->vbox), ui->notebook); vbox = new_main_page(ui); - gtk_drag_dest_set(GTK_WIDGET(ui->window), GTK_DEST_DEFAULT_ALL, NULL, 0, GDK_ACTION_COPY); + gtk_drag_dest_set(GTK_WIDGET(ui->window), GTK_DEST_DEFAULT_ALL, NULL, 1, GDK_ACTION_COPY); gtk_drag_dest_add_uri_targets(GTK_WIDGET(ui->window)); g_signal_connect(ui->window, "drag-data-received", G_CALLBACK(drag_and_drop_received), ui);