#include <lttv/tracecontext.h>
#include <lttvwindow/lttvwindowtraces.h>
#include <lttvwindow/lttvwindow.h> // for CHUNK_NUM_EVENTS
+#include <lttvwindow/mainwindow-private.h> /* for main window structure */
+extern GSList * g_main_window_list;
typedef struct _BackgroundRequest {
LttvAttributeName module_name; /* Hook path in global attributes,
where all standard hooks under computation/.
i.e. modulename */
LttvTrace *trace; /* trace concerned */
+ GtkWidget *dialog; /* Dialog linked with the request, may be NULL */
+ GtkWidget *parent_window; /* Parent window the dialog must be transient for */
} BackgroundRequest;
typedef struct _BackgroundNotify {
LttvAttributeType type;
LttvAttributeName name;
LttvAttributeValue value;
+ gboolean is_named;
g_assert(attribute =
LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
LTTV_TRACES)));
- type = lttv_iattribute_get(LTTV_IATTRIBUTE(attribute), num, &name, &value);
+ type = lttv_iattribute_get(LTTV_IATTRIBUTE(attribute), num, &name, &value,
+ &is_named);
if(type == LTTV_POINTER) {
return (LttvTrace *)*(value.v_pointer);
}
}
+static void destroy_dialog(BackgroundRequest *bg_req)
+{
+ gtk_widget_destroy(bg_req->dialog);
+ bg_req->dialog = NULL;
+}
+
/**
* Function to request data from a specific trace
*
* The memory allocated for the request will be managed by the API.
*
+ * @param widget the current Window
* @param trace the trace to compute
* @param module_name the name of the module which registered global computation
* hooks.
*/
void lttvwindowtraces_background_request_queue
- (LttvTrace *trace, gchar *module_name)
+ (GtkWidget *widget, LttvTrace *trace, gchar *module_name)
{
BackgroundRequest *bg_req;
LttvAttribute *attribute = lttv_trace_attribute(trace);
trace,
NULL);
/* FIXME : show message in status bar, need context and message id */
- g_info("Background computation started for trace %p", trace);
+ g_info("Background computation for %s started for trace %p", module_name,
+ trace);
+ GtkWidget *dialog =
+ gtk_message_dialog_new(
+ GTK_WINDOW(widget),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_INFO, GTK_BUTTONS_OK,
+ "Background computation for %s started for trace %s",
+ module_name,
+ g_quark_to_string(ltt_trace_name(lttv_trace(trace))));
+ gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(widget));
+ g_signal_connect_swapped (dialog, "response",
+ G_CALLBACK (destroy_dialog),
+ bg_req);
+ bg_req->dialog = dialog;
+ /* the parent window might vanish : only use this pointer for a
+ * comparison with existing windows */
+ bg_req->parent_window = gtk_widget_get_toplevel(widget);
+ gtk_widget_show(dialog);
}
/**
}
}
+/**
+ * Find a background request in a trace
+ *
+ */
+
+gboolean lttvwindowtraces_background_request_find
+ (LttvTrace *trace, gchar *module_name)
+{
+ LttvAttribute *attribute = lttv_trace_attribute(trace);
+ LttvAttributeValue value;
+ GSList *iter = NULL;
+ GSList **slist;
+
+ g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
+ LTTV_REQUESTS_QUEUE,
+ LTTV_POINTER,
+ &value));
+ slist = (GSList**)(value.v_pointer);
+
+ for(iter=*slist;iter!=NULL;) {
+ BackgroundRequest *bg_req =
+ (BackgroundRequest *)iter->data;
+
+ if(bg_req->module_name == g_quark_from_string(module_name)) {
+ return TRUE;
+ } else {
+ iter=g_slist_next(iter);
+ }
+ }
+ return FALSE;
+}
/**
* Register a callback to be called when requested data is passed in the next
&value));
slist = (GSList**)(value.v_pointer);
+ g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
+ LTTV_COMPUTATION_TRACESET_CONTEXT,
+ LTTV_POINTER,
+ &value));
+ LttvTracesetContext *tsc = (LttvTracesetContext*)(value.v_pointer);
bg_notify = g_new(BackgroundNotify,1);
bg_notify->trace = trace;
bg_notify->notify_time = notify_time;
if(notify_position != NULL) {
- bg_notify->notify_position = lttv_traceset_context_position_new();
+ bg_notify->notify_position = lttv_traceset_context_position_new(tsc);
lttv_traceset_context_position_copy(bg_notify->notify_position,
notify_position);
} else {
&value));
slist = (GSList**)(value.v_pointer);
+ g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
+ LTTV_COMPUTATION_TRACESET_CONTEXT,
+ LTTV_POINTER,
+ &value));
+ LttvTracesetContext *tsc = (LttvTracesetContext*)(value.v_pointer);
+
+
bg_notify = g_new(BackgroundNotify,1);
bg_notify->owner = owner;
bg_notify->trace = trace;
bg_notify->notify_time = notify_time;
if(notify_position!= NULL) {
- bg_notify->notify_position = lttv_traceset_context_position_new();
+ bg_notify->notify_position = lttv_traceset_context_position_new(tsc);
lttv_traceset_context_position_copy(bg_notify->notify_position,
notify_position);
} else {
return TRUE;
}
+static gint find_window_widget(MainWindow *a, GtkWidget *b)
+{
+ if(a->mwindow == b) return 0;
+ else return -1;
+}
+
/* lttvwindowtraces_process_pending_requests
*
if(trace == NULL)
return FALSE;
+
+ if(lttvwindow_preempt_count > 0) return TRUE;
attribute = lttv_trace_attribute(trace);
LttvHooks *after_request = (LttvHooks*)*(value.v_pointer);
if(after_request != NULL) lttv_hooks_call(after_request, tsc);
+
+ if(bg_req->dialog != NULL)
+ gtk_widget_destroy(bg_req->dialog);
+ GtkWidget *parent_window;
+ if(g_slist_find_custom(g_main_window_list,
+ bg_req->parent_window,
+ (GCompareFunc)find_window_widget))
+ parent_window = GTK_WIDGET(bg_req->parent_window);
+ else
+ parent_window = NULL;
+
+ GtkWidget *dialog =
+ gtk_message_dialog_new(GTK_WINDOW(parent_window),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_INFO, GTK_BUTTONS_OK,
+ "Background computation %s finished for trace %s",
+ g_quark_to_string(bg_req->module_name),
+ g_quark_to_string(ltt_trace_name(lttv_trace(bg_req->trace))));
+ if(parent_window != NULL)
+ gtk_window_set_transient_for(GTK_WINDOW(dialog),
+ GTK_WINDOW(parent_window));
+ g_signal_connect_swapped (dialog, "response",
+ G_CALLBACK (gtk_widget_destroy),
+ dialog);
+ gtk_widget_show(dialog);
+
/* - remove request */
remove = TRUE;
free_data = TRUE;
g_debug("Background computation scheduler stopped");
g_info("Background computation finished for trace %p", trace);
/* FIXME : remove status bar info, need context id and message id */
+
ret_val = FALSE;
} else {
ret_val = TRUE;