diff --git a/ChangeLog b/ChangeLog index e7af2d3e..985b3c76 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +Mon Nov 7 23:42:26 2005 Soeren Sandmann + + * sysprof.c: Add beginning of a screenshot + window. + + * sysprof.glade: Add screenshot window plus menu items. + + * stackstash.c: Remove unused function stack_node_list_leaves() + + * xmlstore.c: Various crack + Sun Nov 6 23:03:49 2005 Soeren Sandmann * profile.c (add_trace_to_tree): Test for !prev instead of !next. diff --git a/profile.c b/profile.c index 7beded27..935c7cd8 100644 --- a/profile.c +++ b/profile.c @@ -484,7 +484,8 @@ profile_get_objects (Profile *profile) { GList *objects = NULL; - stack_stash_foreach_by_address (profile->stash, build_object_list, &objects); + stack_stash_foreach_by_address ( + profile->stash, build_object_list, &objects); /* FIXME: everybody still assumes that they don't have to free the * objects in the list, but these days they do, and so we are leaking. diff --git a/stackstash.c b/stackstash.c index 3a285bc4..cee0d2ba 100644 --- a/stackstash.c +++ b/stackstash.c @@ -138,6 +138,7 @@ do_callback (StackNode *node, if (trace) trace->prev = &link; + link.next = trace; link.data = node->address; link.prev = NULL; @@ -204,19 +205,6 @@ stack_stash_find_node (StackStash *stash, return g_hash_table_lookup (stash->nodes_by_data, data); } -void -stack_node_list_leaves (StackNode *node, - GList **leaves) -{ - StackNode *n; - - if (node->size > 0) - *leaves = g_list_prepend (*leaves, node); - - for (n = node->children; n != NULL; n = n->siblings) - stack_node_list_leaves (n, leaves); -} - typedef struct { StackNodeFunc func; diff --git a/stackstash.h b/stackstash.h index 0be55c23..1faa5f93 100644 --- a/stackstash.h +++ b/stackstash.h @@ -23,7 +23,6 @@ #include typedef struct StackStash StackStash; - typedef struct StackNode StackNode; struct StackNode @@ -45,6 +44,9 @@ typedef void (* StackFunction) (GList *trace, gint size, gpointer data); +typedef void (* StackNodeFunc) (StackNode *node, + gpointer data); + /* Stach */ StackStash *stack_stash_new (void); void stack_stash_add_trace (StackStash *stash, @@ -59,11 +61,6 @@ void stack_node_foreach_trace (StackNode *node, gpointer data); StackNode *stack_stash_find_node (StackStash *stash, gpointer address); -/* FIXME: should probably return a list */ -void stack_node_list_leaves (StackNode *node, - GList **leaves); -typedef void (* StackNodeFunc) (StackNode *node, - gpointer data); void stack_stash_foreach_by_address (StackStash *stash, StackNodeFunc func, gpointer data); diff --git a/sysprof.c b/sysprof.c index 3fd7cab7..27e57de6 100644 --- a/sysprof.c +++ b/sysprof.c @@ -66,8 +66,14 @@ struct Application GtkWidget * reset_item; GtkWidget * save_as_item; GtkWidget * open_item; + GtkWidget * screenshot_item; GtkWidget * samples_label; + + gboolean screenshot_window_visible; + GtkWidget * screenshot_textview; + GtkWidget * screenshot_close_button; + GtkWidget * screenshot_window; Profile * profile; ProfileDescendant * descendants; @@ -227,6 +233,14 @@ update_sensitivity (Application *app) gtk_widget_set_sensitive (GTK_WIDGET (app->descendants_view), sensitive_tree_views); gtk_widget_set_sensitive (GTK_WIDGET (app->samples_label), sensitive_samples_label); + if (app->screenshot_window_visible) + gtk_widget_show (app->screenshot_window); + else + gtk_widget_hide (app->screenshot_window); + + gtk_check_menu_item_set_active ( + GTK_CHECK_MENU_ITEM (app->screenshot_item), app->screenshot_window_visible); + queue_show_samples (app); } @@ -1106,6 +1120,34 @@ on_callers_row_activated (GtkTreeView *tree_view, gtk_widget_grab_focus (GTK_WIDGET (app->callers_view)); } +static void +on_screenshot_activated (GtkCheckMenuItem *menu_item, + Application *app) +{ + app->screenshot_window_visible = gtk_check_menu_item_get_active (menu_item); + + update_sensitivity (app); +} + +static void +on_screenshot_window_delete (GtkWidget *window, + GdkEvent *event, + Application *app) +{ + app->screenshot_window_visible = FALSE; + + update_sensitivity (app); +} + +static void +on_screenshot_close_button_clicked (GtkWidget *widget, + Application *app) +{ + app->screenshot_window_visible = FALSE; + + update_sensitivity (app); +} + static void set_sizes (GtkWindow *window, GtkWidget *hpaned, @@ -1219,6 +1261,7 @@ build_gui (Application *app) app->reset_item = glade_xml_get_widget (xml, "reset_item"); app->open_item = glade_xml_get_widget (xml, "open_item"); app->save_as_item = glade_xml_get_widget (xml, "save_as_item"); + app->screenshot_item = glade_xml_get_widget (xml, "screenshot_item"); g_assert (app->start_item); g_assert (app->profile_item); @@ -1240,6 +1283,9 @@ build_gui (Application *app) g_signal_connect (G_OBJECT (app->save_as_item), "activate", G_CALLBACK (on_save_as_clicked), app); + g_signal_connect (G_OBJECT (app->screenshot_item), "activate", + G_CALLBACK (on_screenshot_activated), app); + g_signal_connect (G_OBJECT (glade_xml_get_widget (xml, "quit")), "activate", G_CALLBACK (on_delete), NULL); @@ -1277,10 +1323,24 @@ build_gui (Application *app) g_signal_connect (app->descendants_view, "row-activated", G_CALLBACK (on_descendants_row_activated), app); gtk_tree_view_column_set_expand (col, TRUE); - + gtk_widget_grab_focus (GTK_WIDGET (app->object_view)); + + /* Screenshot window */ + app->screenshot_window = glade_xml_get_widget (xml, "screenshot_window"); + app->screenshot_textview = glade_xml_get_widget (xml, "screenshot_textview"); + app->screenshot_close_button = glade_xml_get_widget (xml, "screenshot_close_button"); + + g_signal_connect (app->screenshot_window, "delete_event", + G_CALLBACK (on_screenshot_window_delete), app); + + g_signal_connect (app->screenshot_close_button, "clicked", + G_CALLBACK (on_screenshot_close_button_clicked), app); + + /* hide/show widgets */ gtk_widget_show_all (app->main_window); gtk_widget_hide (app->dummy_button); + gtk_widget_hide (app->screenshot_window); queue_show_samples (app); diff --git a/sysprof.glade b/sysprof.glade index 724e5b81..9251e616 100644 --- a/sysprof.glade +++ b/sysprof.glade @@ -46,7 +46,7 @@ - + True gtk-media-play 1 @@ -67,7 +67,7 @@ - + True gtk-justify-left 1 @@ -88,7 +88,7 @@ - + True gtk-clear 1 @@ -116,7 +116,7 @@ - + True gtk-open 1 @@ -138,7 +138,7 @@ - + True gtk-save-as 1 @@ -166,7 +166,7 @@ - + True gtk-quit 1 @@ -183,6 +183,30 @@ + + + True + _View + True + + + + + + + + True + _Screenshot Window + True + False + + + + + + + + True @@ -200,7 +224,7 @@ - + True gtk-about 1 @@ -555,4 +579,136 @@ + + Screenshot + GTK_WINDOW_TOPLEVEL + GTK_WIN_POS_NONE + False + True + False + True + False + False + GDK_WINDOW_TYPE_HINT_UTILITY + GDK_GRAVITY_NORTH_WEST + True + + + + 12 + True + False + 6 + + + + True + 0 + 0.5 + GTK_SHADOW_NONE + + + + True + 0.5 + 0.5 + 1 + 1 + 3 + 0 + 12 + 0 + + + + True + True + GTK_POLICY_AUTOMATIC + GTK_POLICY_NEVER + GTK_SHADOW_IN + GTK_CORNER_TOP_LEFT + + + + True + True + False + False + True + GTK_JUSTIFY_LEFT + GTK_WRAP_NONE + False + 0 + 0 + 0 + 0 + 0 + 0 + + + + + + + + + + + True + <b>Screenshot</b> + False + True + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + label_item + + + + + 0 + True + True + + + + + + True + GTK_BUTTONBOX_END + 0 + + + + True + True + True + True + gtk-close + True + GTK_RELIEF_NORMAL + True + + + + + 0 + False + True + + + + + + diff --git a/xmlstore.c b/xmlstore.c index 202b6dc1..71aaa164 100644 --- a/xmlstore.c +++ b/xmlstore.c @@ -1,5 +1,62 @@ typedef struct ParsedItem ParsedItem; +struct XmlItem +{ + gboolean is_element; + + union + { + struct + { + const char *name; + guint sibling_index; + } element; + + char text[1]; + } u; +}; + +struct XmlStore +{ + GHashTable *names; + GArray *items; + + GList *stack; + guint last_index; +}; + +static guint +add_item (GArray *array, + const XmlItem *item) +{ + +} + +XmlStore * +xml_store_new (void) +{ + XmlStore *store = g_new (XmlStore, 1); + store->names = g_hash_table_new (g_str_hash, g_str_equal); + store->stack = NULL; + store->items = g_array_new (TRUE, TRUE, sizeof (XmlItem)); +} + +void +xml_store_append_begin (XmlStore *store, + const char *element) +{ + XmlItem item; + + item.is_element = TRUE; + item.element.name = canonical_name (store, element); + item.element.sibling = NULL; + + if (store->last) + store->last->u.element.sibling = &result; + +} + + typedef enum { BEGIN, @@ -16,14 +73,14 @@ struct XmlItem struct XmlStore { XmlItem * items; - + GHashTable *user_data_map; }; struct ParsedItem { XmlItemType type; - + union { struct @@ -32,12 +89,12 @@ struct ParsedItem int n_attrs; char **attr; } begin_item; - + struct { char *text; } text_item; - + struct { char *element; @@ -77,18 +134,18 @@ parsed_item_new (XmlItem *item) parsed_item->type = BEGIN; parse_begin_item (item, parsed_item); break; - + case END: parsed_item->type = END; parse_end_item (item, parsed_item); break; - + case TEXT: parsed_item->type = TEXT; parse_text_item (item, parsed_item); break; } - + return parsed_item; }