[geany/geany-plugins] 093fdc: Merge pull request #18 from cesspit/master
Frank Lanitz
git-noreply at xxxxx
Wed Mar 14 20:00:10 UTC 2012
Branch: refs/heads/master
Author: Frank Lanitz <frank at frank.uvena.de>
Committer: Frank Lanitz <frank at frank.uvena.de>
Date: Wed, 14 Mar 2012 20:00:10
Commit: 093fdc6260681ea6baa5657bb1d8ca2ef9f9ced8
https://github.com/geany/geany-plugins/commit/093fdc6260681ea6baa5657bb1d8ca2ef9f9ced8
Log Message:
-----------
Merge pull request #18 from cesspit/master
switching between frames by clicking a frame arrow in the stack window
Modified Paths:
--------------
debugger/ChangeLog
debugger/TODO
debugger/src/Makefile.am
debugger/src/breakpoints.h
debugger/src/callbacks.c
debugger/src/cell_renderers/cellrendererbreakicon.c
debugger/src/cell_renderers/cellrendererbreakicon.h
debugger/src/cell_renderers/cellrendererframeicon.c
debugger/src/cell_renderers/cellrendererframeicon.h
debugger/src/dbm_gdb.c
debugger/src/debug.c
debugger/src/debug.h
debugger/src/debug_module.h
debugger/src/pixbuf.h
debugger/src/stree.c
debugger/src/stree.h
debugger/src/utils.h
Modified: debugger/ChangeLog
4 files changed, 4 insertions(+), 0 deletions(-)
===================================================================
@@ -1,3 +1,7 @@
+10-03-2012 Alexander Petukhov <devel at apetukhov.ru>
+
+ * switching between frames by clicking a frame arrow in the stack window
+
18-02-2012 Alexander Petukhov <devel at apetukhov.ru>
* threads info added to the stack window
Modified: debugger/TODO
4 files changed, 3 insertions(+), 1 deletions(-)
===================================================================
@@ -2,12 +2,13 @@ BUGS:
- terminal stops to produce any output after some debug seesions
- tooltip appears even if a pointer in no longer inside editor window
- check possible memory leaks on a)gtk_tree_row_reference_get_path b)missing unrefs on tree/list stores
+- cell_renderer_toogle SIGSEGV in cell_renderer_toggle_activate when activating a cell using a keyboard (event->button == NULL)
+- debug geany with debugger project. switch frames then step over -> continue instead, then close geany being debugged -> dbm_gdb.c:502 (no step reason, probably the record from the previos step command???)
FEATURES:
- custom tooltip with sticking facilities
- don't hide a tooltip until run hasn't happent, move it if document is being scrolled
- use lexer to lookup for a symbol under cursor when presenting a tooltip
-- jump to a frame (change frame that affects locals, watch etc., caused by clicking a frame in the stack trace tab/margin stack marker)
- geany menu integration
- toolbar buttons
- margin context menu
@@ -22,3 +23,4 @@ FEATURES:
- interrupt thread using stack window
- custom tooltip on breaks and stack trace windows with code snippet around break or frame
- font from the geany settings for a message window
+- a button in the upper right path of a right notebook for a hiding/showing button panel
Modified: debugger/src/Makefile.am
2 files changed, 2 insertions(+), 0 deletions(-)
===================================================================
@@ -62,6 +62,8 @@ debugger_la_SOURCES = \
wtree.h \
cell_renderers/cellrendererbreakicon.c \
cell_renderers/cellrendererbreakicon.h \
+ cell_renderers/cellrendererframeicon.c \
+ cell_renderers/cellrendererframeicon.h \
cell_renderers/cellrenderertoggle.c \
cell_renderers/cellrenderertoggle.h
Modified: debugger/src/breakpoints.h
3 files changed, 2 insertions(+), 1 deletions(-)
===================================================================
@@ -27,7 +27,8 @@
BS_DISABLED
} break_state;
-typedef void (*move_to_line_cb)(char* file, int line);
+typedef void (*move_to_line_cb)(const char* file, int line);
+typedef void (*select_frame_cb)(int frame_number);
gboolean breaks_init(move_to_line_cb callback);
void breaks_destroy();
Modified: debugger/src/callbacks.c
26 files changed, 14 insertions(+), 12 deletions(-)
===================================================================
@@ -67,24 +67,26 @@ void set_markers_for_file(const gchar* file)
/* set frames markers if exists */
if (DBS_STOPPED == debug_get_state())
{
+ int active_frame_index = debug_get_active_frame();
+
GList *iter = debug_get_stack();
- if (iter)
+ int frame_index = 0;
+ for (; iter; iter = iter->next, frame_index++)
{
- frame *f = (frame*)iter->data;
- if (f->have_source && !strcmp(f->file, file))
- {
- markers_add_current_instruction(f->file, f->line);
- }
-
- iter = iter->next;
- while (iter)
+ if (iter)
{
- f = (frame*)iter->data;
+ frame *f = (frame*)iter->data;
if (f->have_source && !strcmp(f->file, file))
{
- markers_add_frame(f->file, f->line);
+ if (active_frame_index == frame_index)
+ {
+ markers_add_current_instruction(f->file, f->line);
+ }
+ else
+ {
+ markers_add_frame(f->file, f->line);
+ }
}
- iter = iter->next;
}
}
}
Modified: debugger/src/cell_renderers/cellrendererbreakicon.c
2 files changed, 1 insertions(+), 1 deletions(-)
===================================================================
@@ -205,7 +205,7 @@ static void cell_renderer_break_icon_render(GtkCellRenderer *cell, GdkDrawable *
{
CellRendererBreakIcon *cellbreakpoint = (CellRendererBreakIcon*) cell;
- GdkPixbuf *pixbuf;
+ GdkPixbuf *pixbuf = NULL;
GdkRectangle pix_rect;
GdkRectangle draw_rect;
Modified: debugger/src/cell_renderers/cellrendererbreakicon.h
2 files changed, 1 insertions(+), 1 deletions(-)
===================================================================
@@ -54,7 +54,7 @@ struct _CellRendererBreakIconClass
{
GtkCellRendererClass parent_class;
- void (*clicked)(GtkCellRendererToggle *cell_renderer_toggle, const gchar *path);
+ void (*clicked)(CellRendererBreakIcon *cell_renderer_toggle, const gchar *path);
};
GType cell_renderer_break_icon_get_type(void);
Modified: debugger/src/cell_renderers/cellrendererframeicon.c
343 files changed, 343 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1,343 @@
+/*
+ * cellrendererframeicon.c
+ *
+ * Copyright 2012 Alexander Petukhov <devel(at)apetukhov.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+/*
+ * cell renderer class that renders frame icon, that in turn depends on whether a
+ * row is the first vhildren (uppermost frame) and whether a renderer is under the cursor
+ */
+
+#include <string.h>
+#include <geanyplugin.h>
+
+#include "cellrendererframeicon.h"
+
+enum {
+ PROP_0,
+ PROP_PIXBUF_ACTIVE,
+ PROP_PIXBUF_HIGHLIGHTED,
+ PROP_ACTIVE_FRAME,
+};
+
+static gpointer parent_class;
+static guint clicked_signal;
+
+/*
+ * activate callback
+ */
+static gint cell_renderer_frame_icon_activate(GtkCellRenderer *cell, GdkEvent *event, GtkWidget *widget, const gchar *path,
+ GdkRectangle *background_area, GdkRectangle *cell_area, GtkCellRendererState flags)
+{
+ if (event->button.x >= cell_area->x &&
+ event->button.x < (cell_area->x + cell_area->width))
+ {
+ g_signal_emit (cell, clicked_signal, 0, path);
+ }
+ return TRUE;
+}
+
+/*
+ * property getter
+ */
+static void cell_renderer_frame_icon_get_property(GObject *object, guint param_id, GValue *value, GParamSpec *pspec)
+{
+ CellRendererFrameIcon *cellframe = CELL_RENDERER_FRAME_ICON(object);
+ switch (param_id)
+ {
+ case PROP_PIXBUF_ACTIVE:
+ g_value_set_object (value, cellframe->pixbuf_active);
+ break;
+ case PROP_PIXBUF_HIGHLIGHTED:
+ g_value_set_object (value, cellframe->pixbuf_highlighted);
+ break;
+ case PROP_ACTIVE_FRAME:
+ g_value_set_boolean(value, cellframe->active_frame);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+ break;
+ }
+}
+
+/*
+ * property setter
+ */
+static void cell_renderer_frame_icon_set_property (GObject *object, guint param_id, const GValue *value, GParamSpec *pspec)
+{
+ CellRendererFrameIcon *cellframe = CELL_RENDERER_FRAME_ICON(object);
+ switch (param_id)
+ {
+ case PROP_PIXBUF_ACTIVE:
+ if (cellframe->pixbuf_active)
+ {
+ g_object_unref(cellframe->pixbuf_active);
+ }
+ cellframe->pixbuf_active = (GdkPixbuf*)g_value_dup_object(value);
+ break;
+ case PROP_PIXBUF_HIGHLIGHTED:
+ if (cellframe->pixbuf_highlighted)
+ {
+ g_object_unref(cellframe->pixbuf_highlighted);
+ }
+ cellframe->pixbuf_highlighted = (GdkPixbuf*)g_value_dup_object(value);
+ break;
+ case PROP_ACTIVE_FRAME:
+ {
+ cellframe->active_frame = g_value_get_boolean(value);
+ break;
+ }
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+ break;
+ }
+}
+
+/*
+ * get size of a cell
+ */
+static void cell_renderer_frame_icon_get_size(GtkCellRenderer *cell, GtkWidget *widget, GdkRectangle *cell_area,
+ gint *x_offset, gint *y_offset, gint *width, gint *height)
+{
+ CellRendererFrameIcon *cellframe = (CellRendererFrameIcon *) cell;
+ gint pixbuf_width = 0;
+ gint pixbuf_height = 0;
+ gint calc_width;
+ gint calc_height;
+
+ if (cellframe->pixbuf_active)
+ {
+ pixbuf_width = gdk_pixbuf_get_width (cellframe->pixbuf_active);
+ pixbuf_height = gdk_pixbuf_get_height (cellframe->pixbuf_active);
+ }
+ if (cellframe->pixbuf_highlighted)
+ {
+ pixbuf_width = MAX (pixbuf_width, gdk_pixbuf_get_width (cellframe->pixbuf_highlighted));
+ pixbuf_height = MAX (pixbuf_height, gdk_pixbuf_get_height (cellframe->pixbuf_highlighted));
+ }
+
+ calc_width = (gint) cell->xpad * 2 + pixbuf_width;
+ calc_height = (gint) cell->ypad * 2 + pixbuf_height;
+
+ if (cell_area && pixbuf_width > 0 && pixbuf_height > 0)
+ {
+ if (x_offset)
+ {
+ *x_offset = (((gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) ?
+ (1.0 - cell->xalign) : cell->xalign) *
+ (cell_area->width - calc_width));
+ *x_offset = MAX (*x_offset, 0);
+ }
+ if (y_offset)
+ {
+ *y_offset = (cell->yalign * (cell_area->height - calc_height));
+ *y_offset = MAX (*y_offset, 0);
+ }
+ }
+ else
+ {
+ if (x_offset) *x_offset = 0;
+ if (y_offset) *y_offset = 0;
+ }
+
+ if (width)
+ *width = calc_width;
+
+ if (height)
+ *height = calc_height;
+}
+
+/*
+ * render a cell
+ */
+static void cell_renderer_frame_icon_render(GtkCellRenderer *cell, GdkDrawable *window, GtkWidget *widget,
+ GdkRectangle *background_area, GdkRectangle *cell_area, GdkRectangle *expose_area, GtkCellRendererState flags)
+{
+ CellRendererFrameIcon *cellframe = (CellRendererFrameIcon*) cell;
+
+ GdkPixbuf *pixbuf = NULL;
+
+ GdkRectangle pix_rect;
+ GdkRectangle draw_rect;
+ cairo_t *cr;
+
+ cell_renderer_frame_icon_get_size (cell, widget, cell_area,
+ &pix_rect.x,
+ &pix_rect.y,
+ &pix_rect.width,
+ &pix_rect.height);
+
+ pix_rect.x += cell_area->x + cell->xpad;
+ pix_rect.y += cell_area->y + cell->ypad;
+ pix_rect.width -= cell->xpad * 2;
+ pix_rect.height -= cell->ypad * 2;
+
+ if (!gdk_rectangle_intersect (cell_area, &pix_rect, &draw_rect) ||
+ !gdk_rectangle_intersect (expose_area, &draw_rect, &draw_rect))
+ return;
+
+ if (cellframe->active_frame)
+ {
+ pixbuf = cellframe->pixbuf_active;
+ }
+ else if (flags & GTK_CELL_RENDERER_PRELIT)
+ {
+ pixbuf = cellframe->pixbuf_highlighted;
+ }
+
+ if (!pixbuf)
+ return;
+
+ cr = gdk_cairo_create (window);
+
+ gdk_cairo_set_source_pixbuf (cr, pixbuf, pix_rect.x, pix_rect.y);
+ gdk_cairo_rectangle (cr, &draw_rect);
+ cairo_fill (cr);
+
+ cairo_destroy (cr);
+}
+
+/*
+ * init instance
+ */
+static void cell_renderer_frame_icon_init (CellRendererFrameIcon *cell)
+{
+ cell->active_frame = FALSE;
+
+ GtkCellRenderer *cell_renderer = (GtkCellRenderer*)cell;
+
+ cell_renderer->mode = GTK_CELL_RENDERER_MODE_ACTIVATABLE;
+
+ cell->pixbuf_active = cell->pixbuf_highlighted = 0;
+}
+
+/*
+ * finalizes an instance (frees pixbuffers)
+ */
+static void cell_renderer_frame_icon_finalize (GObject *object)
+{
+ CellRendererFrameIcon *cell = (CellRendererFrameIcon*)object;
+
+ GdkPixbuf *pixbufs[] = { cell->pixbuf_active, cell->pixbuf_highlighted };
+ int i;
+ for(i = 0; i < 2; i++)
+ {
+ if (pixbufs[i])
+ {
+ g_object_unref(pixbufs[i]);
+ }
+ }
+
+ (*G_OBJECT_CLASS (parent_class)->finalize) (object);
+}
+
+/*
+ * init class
+ */
+static void cell_renderer_frame_icon_class_init (CellRendererFrameIconClass *class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS(class);
+ GtkCellRendererClass *cell_class = GTK_CELL_RENDERER_CLASS(class);
+
+ parent_class = g_type_class_peek_parent(class);
+
+ object_class->get_property = cell_renderer_frame_icon_get_property;
+ object_class->set_property = cell_renderer_frame_icon_set_property;
+
+ object_class->finalize = cell_renderer_frame_icon_finalize;
+
+ cell_class->get_size = cell_renderer_frame_icon_get_size;
+ cell_class->render = cell_renderer_frame_icon_render;
+
+ cell_class->activate = cell_renderer_frame_icon_activate;
+
+ g_object_class_install_property (object_class,
+ PROP_PIXBUF_ACTIVE,
+ g_param_spec_object (
+ "pixbuf_active",
+ "Pixbuf Object",
+ "Active frame image",
+ GDK_TYPE_PIXBUF,
+ G_PARAM_READWRITE)
+ );
+
+ g_object_class_install_property (object_class,
+ PROP_PIXBUF_HIGHLIGHTED,
+ g_param_spec_object (
+ "pixbuf_highlighted",
+ "Pixbuf Object",
+ "Highlighted frame image",
+ GDK_TYPE_PIXBUF,
+ G_PARAM_READWRITE)
+ );
+
+ g_object_class_install_property (object_class,
+ PROP_ACTIVE_FRAME,
+ g_param_spec_boolean ("active_frame", "Activeness", "Is a frame active", FALSE, G_PARAM_READWRITE)
+ );
+
+ clicked_signal = g_signal_new ("clicked",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CellRendererFrameIconClass, clicked),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE, 1,
+ G_TYPE_STRING);
+}
+
+/*
+ * registers a type
+ */
+GType cell_renderer_frame_icon_get_type(void)
+{
+ static GType cell_frame_icon_type = 0;
+
+ if(0 == cell_frame_icon_type)
+ {
+ static const GTypeInfo cell_frame_icon_info =
+ {
+ sizeof (CellRendererFrameIconClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) cell_renderer_frame_icon_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (CellRendererFrameIcon),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) cell_renderer_frame_icon_init,
+ };
+
+ /* Derive from GtkCellRenderer */
+ cell_frame_icon_type = g_type_register_static (GTK_TYPE_CELL_RENDERER,
+ "CellRendererFrameIcon",
+ &cell_frame_icon_info,
+ 0);
+ }
+
+ return cell_frame_icon_type;
+}
+
+/*
+ * creates new renderer
+ */
+GtkCellRenderer* cell_renderer_frame_icon_new()
+{
+ return g_object_new(TYPE_CELL_RENDERER_FRAME_ICON, NULL);
+}
Modified: debugger/src/cell_renderers/cellrendererframeicon.h
61 files changed, 61 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1,61 @@
+/*
+ * cellrendererframeicon.h
+ *
+ * Copyright 2012 Alexander Petukhov <devel(at)apetukhov.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#ifndef __CELL_RENDERER_FRAME_ICON_H__
+#define __CELL_RENDERER_FRAME_ICON_H__
+
+#include <gtk/gtkcellrenderer.h>
+
+G_BEGIN_DECLS
+
+#define TYPE_CELL_RENDERER_FRAME_ICON (cell_renderer_frame_icon_get_type ())
+#define CELL_RENDERER_FRAME_ICON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_CELL_RENDERER_FRAME_ICON, CellRendererFrameIcon))
+#define CELL_RENDERER_FRAME_ICON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_CELL_RENDERER_FRAME_ICON, CellRendererFrameIconClass))
+#define IS_CELL_RENDERER_FRAME_ICON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_CELL_RENDERER_FRAME_ICON))
+#define IS_CELL_RENDERER_FRAME_ICON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_CELL_RENDERER_FRAME_ICON))
+#define CELL_RENDERER_FRAME_ICON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_CELL_RENDERER_FRAME_ICON, CellRendererFrameIconClass))
+
+typedef struct _CellRendererFrameIcon CellRendererFrameIcon;
+typedef struct _CellRendererFrameIconClass CellRendererFrameIconClass;
+
+struct _CellRendererFrameIcon
+{
+ GtkCellRenderer parent;
+
+ guint GSEAL (active_frame);
+
+ GdkPixbuf *GSEAL (pixbuf_active);
+ GdkPixbuf *GSEAL (pixbuf_highlighted);
+};
+
+struct _CellRendererFrameIconClass
+{
+ GtkCellRendererClass parent_class;
+
+ void (*clicked)(CellRendererFrameIcon *cell_renderer_toggle, const gchar *path);
+};
+
+GType cell_renderer_frame_icon_get_type(void);
+GtkCellRenderer* cell_renderer_frame_icon_new (void);
+
+G_END_DECLS
+
+#endif /* __CELL_RENDERER_FRAME_ICON_H__ */
Modified: debugger/src/dbm_gdb.c
31 files changed, 30 insertions(+), 1 deletions(-)
===================================================================
@@ -117,6 +117,9 @@ enum sr {
and it's nessesary to refresh files list */
static gboolean file_refresh_needed = FALSE;
+/* current frame number */
+static int active_frame = 0;
+
/* forward declarations */
void stop();
variable* add_watch(gchar* expression);
@@ -499,6 +502,8 @@ static gboolean on_read_from_gdb(GIOChannel * src, GIOCondition cond, gpointer d
gchar *thread_id = strstr(reason + strlen(reason) + 1,"thread-id=\"") + strlen("thread-id=\"");
*(strchr(thread_id, '\"')) = '\0';
+ active_frame = 0;
+
if (SR_BREAKPOINT_HIT == stop_reason || SR_END_STEPPING_RANGE == stop_reason)
{
/* update autos */
@@ -1029,6 +1034,29 @@ gboolean remove_break(breakpoint* bp)
}
/*
+ * get active frame
+ */
+int get_active_frame()
+{
+ return active_frame;
+}
+
+/*
+ * select frame
+ */
+void set_active_frame(int frame_number)
+{
+ gchar *command = g_strdup_printf("-stack-select-frame %i", frame_number);
+ if (RC_DONE == exec_sync_command(command, TRUE, NULL))
+ {
+ active_frame = frame_number;
+ update_autos();
+ update_watches();
+ }
+ g_free(command);
+}
+
+/*
* gets stack
*/
GList* get_stack()
@@ -1452,7 +1480,7 @@ void update_autos()
/* add current autos to the list */
GList *unevaluated = NULL;
- const char *gdb_commands[] = { "-stack-list-arguments 0 0 0", "-stack-list-locals 0" };
+ const char *gdb_commands[] = { g_strdup_printf("-stack-list-arguments 0 %i %i", active_frame, active_frame), "-stack-list-locals 0" };
int i, size = sizeof (gdb_commands) / sizeof(char*);
for (i = 0; i < size; i++)
{
@@ -1498,6 +1526,7 @@ void update_autos()
}
g_free(record);
}
+ g_free((void*)gdb_commands[0]);
/* get values for the autos (without incorrect variables) */
get_variables(autos);
Modified: debugger/src/debug.c
105 files changed, 77 insertions(+), 28 deletions(-)
===================================================================
@@ -151,46 +151,60 @@
static GHashTable *calltips = NULL;
/*
- * removes stack margin markers
+ * remove stack margin markers
*/
void remove_stack_markers()
{
- frame *current = (frame*)stack->data;
- if (current->have_source)
- {
- markers_remove_current_instruction(current->file, current->line);
- }
- GList *iter = stack->next;
- while (iter)
+ int active_frame_index = active_module->get_active_frame();
+
+ GList *iter;
+ int frame_index;
+ for (iter = stack, frame_index = 0; iter; iter = iter->next, frame_index++)
{
- frame *next = (frame*)iter->data;
- if (next->have_source)
+ if (iter)
{
- markers_remove_frame(next->file, next->line);
+ frame *f = (frame*)iter->data;
+ if (f->have_source)
+ {
+ if (active_frame_index == frame_index)
+ {
+ markers_remove_current_instruction(f->file, f->line);
+ }
+ else
+ {
+ markers_remove_frame(f->file, f->line);
+ }
+ }
}
- iter = iter->next;
}
}
/*
- * removes stack margin markers
+ * add stack margin markers
*/
- void add_stack_markers()
+static void add_stack_markers()
{
- frame *current = (frame*)stack->data;
- if (current->have_source)
- {
- markers_add_current_instruction(current->file, current->line);
- }
- GList *iter = stack->next;
- while (iter)
+ int active_frame_index = active_module->get_active_frame();
+
+ GList *iter;
+ int frame_index;
+ for (iter = stack, frame_index = 0; iter; iter = iter->next, frame_index++)
{
- frame *next = (frame*)iter->data;
- if (next->have_source)
+ if (iter)
{
- markers_add_frame(next->file, next->line);
+ frame *f = (frame*)iter->data;
+ if (f->have_source)
+ {
+ if (active_frame_index == frame_index)
+ {
+ markers_add_current_instruction(f->file, f->line);
+ }
+ else
+ {
+ markers_add_frame(f->file, f->line);
+ }
+ }
}
- iter = iter->next;
}
}
@@ -643,7 +657,7 @@ static void on_debugger_stopped (int thread_id)
}
/* clear stack tree view */
- stree_set_current_thread_id(thread_id);
+ stree_set_active_thread_id(thread_id);
/* get current stack trace and put in the tree view */
stack = active_module->get_stack();
@@ -806,7 +820,7 @@ static void on_debugger_exited (int code)
/*
* called from debugger module to show a message in debugger messages pane
*/
-static void on_debugger_message (const gchar* message, const gchar *color)
+void on_debugger_message (const gchar* message, const gchar *color)
{
gchar *msg = g_strdup_printf("%s\n", message);
@@ -873,6 +887,33 @@ static void on_thread_added (int thread_id)
* Interface functions
*/
+/*
+ * called when a frame in the stack tree has been selected
+ */
+static void on_select_frame(int frame_number)
+{
+ frame *f = (frame*)g_list_nth(stack, active_module->get_active_frame())->data;
+ markers_remove_current_instruction(f->file, f->line);
+ markers_add_frame(f->file, f->line);
+
+ active_module->set_active_frame(frame_number);
+
+ /* clear calltips cache */
+ g_hash_table_remove_all(calltips);
+
+ /* autos */
+ GList *autos = active_module->get_autos();
+ update_variables(GTK_TREE_VIEW(atree), NULL, autos);
+
+ /* watches */
+ GList *watches = active_module->get_watches();
+ update_variables(GTK_TREE_VIEW(wtree), NULL, watches);
+
+ f = (frame*)g_list_nth(stack, frame_number)->data;
+ markers_remove_frame(f->file, f->line);
+ markers_add_current_instruction(f->file, f->line);
+}
+
/*
* init debug related GUI (watch tree view)
* arguments:
@@ -909,7 +950,7 @@ void debug_init()
gtk_container_add(GTK_CONTAINER(tab_autos), atree);
/* create stack trace page */
- stree = stree_init(editor_open_position);
+ stree = stree_init(editor_open_position, on_select_frame);
tab_call_stack = gtk_scrolled_window_new(
gtk_tree_view_get_hadjustment(GTK_TREE_VIEW(stree )),
gtk_tree_view_get_vadjustment(GTK_TREE_VIEW(stree ))
@@ -1314,3 +1355,11 @@ void debug_on_file_open(GeanyDocument *doc)
if (g_list_find_custom(read_only_pages, (gpointer)file, (GCompareFunc)g_strcmp0))
scintilla_send_message(doc->editor->sci, SCI_SETREADONLY, 1, 0);
}
+
+/*
+ * get active frame index
+ */
+int debug_get_active_frame()
+{
+ return active_module->get_active_frame();
+}
Modified: debugger/src/debug.h
1 files changed, 1 insertions(+), 0 deletions(-)
===================================================================
@@ -48,4 +48,5 @@
gchar* debug_get_calltip_for_expression(gchar* expression);
GList* debug_get_stack();
void debug_restart();
+int debug_get_active_frame();
Modified: debugger/src/debug_module.h
8 files changed, 7 insertions(+), 1 deletions(-)
===================================================================
@@ -108,8 +108,12 @@ enum dbs {
gboolean (*set_break) (breakpoint* bp, break_set_activity bsa);
gboolean (*remove_break) (breakpoint* bp);
+
GList* (*get_stack) ();
-
+
+ void (*set_active_frame)(int frame_number);
+ int (*get_active_frame)();
+
GList* (*get_autos) ();
GList* (*get_watches) ();
@@ -141,6 +145,8 @@ enum dbs {
set_break, \
remove_break, \
get_stack, \
+ set_active_frame, \
+ get_active_frame, \
get_autos, \
get_watches, \
get_files, \
Modified: debugger/src/pixbuf.h
1 files changed, 1 insertions(+), 0 deletions(-)
===================================================================
@@ -27,6 +27,7 @@
extern GdkPixbuf *local_pixbuf;
extern GdkPixbuf *watch_pixbuf;
+extern GdkPixbuf *frame_pixbuf;
extern GdkPixbuf *frame_current_pixbuf;
void pixbufs_init();
Modified: debugger/src/stree.c
172 files changed, 112 insertions(+), 60 deletions(-)
===================================================================
@@ -36,6 +36,8 @@
#include "debug_module.h"
#include "pixbuf.h"
+#include "cell_renderers/cellrendererframeicon.h"
+
/* Tree view columns */
enum
{
@@ -46,25 +48,57 @@ enum
S_LAST_VISIBLE,
S_HAVE_SOURCE,
S_THREAD_ID,
+ S_ACTIVE,
S_N_COLUMNS
};
/* hash table to keep thread nodes in the tree */
static GHashTable *threads;
-/* current_thread_id */
-static glong current_thread_id = 0;
+/* active thread and frame */
+static glong active_thread_id = 0;
+static int active_frame_index = 0;
-/* double click callback pointer */
-static move_to_line_cb callback = NULL;
+/* callbacks */
+static select_frame_cb select_frame = NULL;
+static move_to_line_cb move_to_line = NULL;
/* tree view, model and store handles */
-static GtkWidget* tree = NULL;
-static GtkTreeModel* model = NULL;
-static GtkTreeStore* store = NULL;
+static GtkWidget *tree = NULL;
+static GtkTreeModel *model = NULL;
+static GtkTreeStore *store = NULL;
-/* selection callback id */
-static gulong selection_callback = 0;
+/* cell renderer for a frame arrow */
+static GtkCellRenderer *renderer_arrow = NULL;
+
+/*
+ * frame arrow clicked callback
+ */
+static void on_frame_arrow_clicked(CellRendererFrameIcon *cell_renderer, gchar *path, gpointer user_data)
+{
+ GtkTreePath *new_active_frame = gtk_tree_path_new_from_string (path);
+ if (gtk_tree_path_get_indices(new_active_frame)[1] != active_frame_index)
+ {
+ GtkTreeIter iter;
+
+ GtkTreeRowReference *reference = (GtkTreeRowReference*)g_hash_table_lookup(threads, (gpointer)active_thread_id);
+ GtkTreePath *old_active_frame = gtk_tree_row_reference_get_path(reference);
+ gtk_tree_path_append_index(old_active_frame, active_frame_index);
+
+ gtk_tree_model_get_iter(model, &iter, old_active_frame);
+ gtk_tree_store_set (store, &iter, S_ACTIVE, FALSE, -1);
+
+ active_frame_index = gtk_tree_path_get_indices(new_active_frame)[1];
+ select_frame(active_frame_index);
+
+ gtk_tree_model_get_iter(model, &iter, new_active_frame);
+ gtk_tree_store_set (store, &iter, S_ACTIVE, TRUE, -1);
+
+ gtk_tree_path_free(old_active_frame);
+ }
+
+ gtk_tree_path_free(new_active_frame);
+}
/*
* shows a tooltip for a file name
@@ -79,21 +113,33 @@ static gboolean on_query_tooltip(GtkWidget *widget, gint x, gint y, gboolean key
GtkTreeViewColumn *column = NULL;
if (gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(widget), bx, by, &tpath, &column, NULL, NULL))
{
- if (2 == gtk_tree_path_get_depth(tpath) && column == gtk_tree_view_get_column(GTK_TREE_VIEW(widget), S_FILEPATH))
+ if (2 == gtk_tree_path_get_depth(tpath))
{
- GtkTreeIter iter;
- gtk_tree_model_get_iter(model, &iter, tpath);
-
- gchar *path = NULL;
- gtk_tree_model_get(model, &iter, S_FILEPATH, &path, -1);
-
- gtk_tooltip_set_text(tooltip, path);
-
- gtk_tree_view_set_tooltip_row(GTK_TREE_VIEW(widget), tooltip, tpath);
-
- show = TRUE;
+ gint start_pos, width;
+ gtk_tree_view_column_cell_get_position(column, renderer_arrow, &start_pos, &width);
+
+ if (column == gtk_tree_view_get_column(GTK_TREE_VIEW(widget), S_FILEPATH))
+ {
+ GtkTreeIter iter;
+ gtk_tree_model_get_iter(model, &iter, tpath);
+
+ gchar *path = NULL;
+ gtk_tree_model_get(model, &iter, S_FILEPATH, &path, -1);
+
+ gtk_tooltip_set_text(tooltip, path);
+
+ gtk_tree_view_set_tooltip_row(GTK_TREE_VIEW(widget), tooltip, tpath);
+
+ show = TRUE;
- g_free(path);
+ g_free(path);
+ }
+ else if (column == gtk_tree_view_get_column(GTK_TREE_VIEW(widget), S_ADRESS && bx >= start_pos && bx < start_pos + width))
+ {
+ gtk_tooltip_set_text(tooltip, gtk_tree_path_get_indices(tpath)[1] == active_frame_index ? _("Active frame") : _("Switch to a frame"));
+ gtk_tree_view_set_tooltip_row(GTK_TREE_VIEW(widget), tooltip, tpath);
+ show = TRUE;
+ }
}
gtk_tree_path_free(tpath);
}
@@ -102,17 +148,13 @@ static gboolean on_query_tooltip(GtkWidget *widget, gint x, gint y, gboolean key
}
/*
- * shows arrow icon for the current frame, hides renderer for a thread row
+ * shows arrow icon for the frame rows, hides renderer for a thread ones
*/
-static void on_render_icon(GtkTreeViewColumn *tree_column, GtkCellRenderer *cell, GtkTreeModel *tree_model,
+static void on_render_arrow(GtkTreeViewColumn *tree_column, GtkCellRenderer *cell, GtkTreeModel *tree_model,
GtkTreeIter *iter, gpointer data)
{
GtkTreePath *tpath = gtk_tree_model_get_path(model, iter);
- gboolean frame_row = 1 != gtk_tree_path_get_depth(tpath);
-
- g_object_set(cell, "visible", frame_row, NULL);
- g_object_set(cell, "pixbuf", (frame_row && 0 == gtk_tree_path_get_indices(tpath)[1]) ? (gpointer)frame_current_pixbuf : NULL, NULL);
-
+ g_object_set(cell, "visible", 1 != gtk_tree_path_get_depth(tpath), NULL);
gtk_tree_path_free(tpath);
}
@@ -123,7 +165,7 @@ static void on_render_line(GtkTreeViewColumn *tree_column, GtkCellRenderer *cell
GtkTreeIter *iter, gpointer data)
{
GtkTreePath *tpath = gtk_tree_model_get_path(model, iter);
-
+
if (1 == gtk_tree_path_get_depth(tpath))
{
g_object_set(cell, "text", "", NULL);
@@ -169,7 +211,8 @@ static gboolean on_msgwin_button_press(GtkWidget *widget, GdkEventButton *event,
if (event->type == GDK_BUTTON_PRESS)
{
GtkTreePath *pressed_path = NULL;
- if (gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(tree), (int)event->x, (int)event->y, &pressed_path, NULL, NULL, NULL))
+ GtkTreeViewColumn *column = NULL;
+ if (gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(tree), (int)event->x, (int)event->y, &pressed_path, &column, NULL, NULL))
{
if (2 == gtk_tree_path_get_depth(pressed_path))
{
@@ -203,7 +246,7 @@ static gboolean on_msgwin_button_press(GtkWidget *widget, GdkEventButton *event,
S_FILEPATH, &file,
S_LINE, &line,
-1);
- callback(file, line);
+ move_to_line(file, line);
g_free(file);
}
@@ -223,8 +266,13 @@ static gboolean on_msgwin_button_press(GtkWidget *widget, GdkEventButton *event,
/*
* Tree view selection changed callback
*/
-void on_selection_changed(GtkTreeSelection *treeselection, gpointer user_data)
+static void on_selection_changed(GtkTreeSelection *treeselection, gpointer user_data)
{
+ if (!gtk_tree_selection_count_selected_rows(treeselection))
+ {
+ return;
+ }
+
GList *rows = gtk_tree_selection_get_selected_rows(treeselection, &model);
GtkTreePath *path = (GtkTreePath*)rows->data;
@@ -232,7 +280,7 @@ void on_selection_changed(GtkTreeSelection *treeselection, gpointer user_data)
{
GtkTreeIter iter;
gtk_tree_model_get_iter (
- gtk_tree_view_get_model(GTK_TREE_VIEW(tree)),
+ model,
&iter,
path);
gboolean have_source;
@@ -253,8 +301,8 @@ void on_selection_changed(GtkTreeSelection *treeselection, gpointer user_data)
S_FILEPATH, &file,
S_LINE, &line,
-1);
- callback(file, line);
-
+
+ move_to_line(file, line);
g_free(file);
}
}
@@ -266,9 +314,10 @@ void on_selection_changed(GtkTreeSelection *treeselection, gpointer user_data)
/*
* inits stack trace tree
*/
-GtkWidget* stree_init(move_to_line_cb cb)
+GtkWidget* stree_init(move_to_line_cb ml, select_frame_cb sf)
{
- callback = cb;
+ move_to_line = ml;
+ select_frame = sf;
/* create tree view */
store = gtk_tree_store_new (
@@ -279,6 +328,7 @@ void on_selection_changed(GtkTreeSelection *treeselection, gpointer user_data)
G_TYPE_INT,
G_TYPE_STRING,
G_TYPE_INT,
+ G_TYPE_INT,
G_TYPE_INT);
model = GTK_TREE_MODEL(store);
@@ -290,12 +340,11 @@ void on_selection_changed(GtkTreeSelection *treeselection, gpointer user_data)
gtk_tree_view_set_show_expanders(GTK_TREE_VIEW(tree), FALSE);
/* connect signals */
-
- selection_callback = g_signal_connect(G_OBJECT(gtk_tree_view_get_selection(GTK_TREE_VIEW(tree))), "changed", G_CALLBACK (on_selection_changed), NULL);
+ g_signal_connect(G_OBJECT(gtk_tree_view_get_selection(GTK_TREE_VIEW(tree))), "changed", G_CALLBACK (on_selection_changed), NULL);
/* for clicking on already selected frame */
g_signal_connect(G_OBJECT(tree), "button-press-event", G_CALLBACK(on_msgwin_button_press), NULL);
-
+
g_signal_connect(G_OBJECT(tree), "query-tooltip", G_CALLBACK (on_query_tooltip), NULL);
/* creating columns */
@@ -305,15 +354,18 @@ void on_selection_changed(GtkTreeSelection *treeselection, gpointer user_data)
column = gtk_tree_view_column_new();
gtk_tree_view_column_set_title(column, _("Address"));
- GtkCellRenderer *renderer_arrow = gtk_cell_renderer_pixbuf_new ();
+ renderer_arrow = cell_renderer_frame_icon_new ();
+ g_object_set(renderer_arrow, "pixbuf_active", (gpointer)frame_current_pixbuf, NULL);
+ g_object_set(renderer_arrow, "pixbuf_highlighted", (gpointer)frame_pixbuf, NULL);
gtk_tree_view_column_pack_start(column, renderer_arrow, TRUE);
- gtk_tree_view_column_set_cell_data_func(column, renderer_arrow, on_render_icon, NULL, NULL);
+ gtk_tree_view_column_set_attributes(column, renderer_arrow, "active_frame", S_ACTIVE, NULL);
+ gtk_tree_view_column_set_cell_data_func(column, renderer_arrow, on_render_arrow, NULL, NULL);
+ g_signal_connect (G_OBJECT(renderer_arrow), "clicked", G_CALLBACK(on_frame_arrow_clicked), NULL);
GtkCellRenderer *renderer_address = gtk_cell_renderer_text_new ();
gtk_tree_view_column_pack_start(column, renderer_address, TRUE);
gtk_tree_view_column_set_attributes(column, renderer_address, "text", S_ADRESS, NULL);
- gtk_tree_view_column_set_resizable (column, TRUE);
gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
/* function */
@@ -357,7 +409,7 @@ void on_selection_changed(GtkTreeSelection *treeselection, gpointer user_data)
*/
void stree_add(frame *f)
{
- GtkTreeRowReference *reference = (GtkTreeRowReference*)g_hash_table_lookup(threads, (gpointer)current_thread_id);
+ GtkTreeRowReference *reference = (GtkTreeRowReference*)g_hash_table_lookup(threads, (gpointer)active_thread_id);
GtkTreeIter thread_iter;
gtk_tree_model_get_iter(model, &thread_iter, gtk_tree_row_reference_get_path(reference));
@@ -378,12 +430,8 @@ void stree_add(frame *f)
*/
void stree_clear()
{
- g_signal_handler_disconnect(G_OBJECT(gtk_tree_view_get_selection(GTK_TREE_VIEW(tree))), selection_callback);
-
gtk_tree_store_clear(store);
g_hash_table_remove_all(threads);
-
- selection_callback = g_signal_connect(G_OBJECT(gtk_tree_view_get_selection(GTK_TREE_VIEW(tree))), "changed", G_CALLBACK (on_selection_changed), NULL);
}
/*
@@ -393,18 +441,22 @@ void stree_select_first_frame()
{
gtk_tree_view_expand_all(GTK_TREE_VIEW(tree));
- GtkTreeRowReference *reference = (GtkTreeRowReference*)g_hash_table_lookup(threads, (gpointer)current_thread_id);
+ GtkTreeRowReference *reference = (GtkTreeRowReference*)g_hash_table_lookup(threads, (gpointer)active_thread_id);
GtkTreeIter thread_iter, frame_iter;
gtk_tree_model_get_iter(model, &thread_iter, gtk_tree_row_reference_get_path(reference));
if(gtk_tree_model_iter_children(model, &frame_iter, &thread_iter))
{
+ gtk_tree_store_set (store, &frame_iter, S_ACTIVE, TRUE, -1);
+
GtkTreePath* path = gtk_tree_model_get_path(model, &frame_iter);
gtk_tree_selection_select_path (
gtk_tree_view_get_selection(GTK_TREE_VIEW(tree)),
path);
-
+
gtk_tree_path_free(path);
+
+ active_frame_index = 0;
}
}
@@ -413,8 +465,11 @@ void stree_select_first_frame()
*/
void stree_destroy()
{
- g_hash_table_destroy(threads);
- threads = NULL;
+ if (threads)
+ {
+ g_hash_table_destroy(threads);
+ threads = NULL;
+ }
}
/*
@@ -477,6 +532,7 @@ void stree_remove_thread(int thread_id)
gtk_tree_model_get_iter(model, &iter, tpath);
gtk_tree_store_remove(store, &iter);
+
g_hash_table_remove(threads, (gpointer)(glong)thread_id);
}
@@ -485,26 +541,22 @@ void stree_remove_thread(int thread_id)
*/
void stree_remove_frames()
{
- GtkTreeRowReference *reference = (GtkTreeRowReference*)g_hash_table_lookup(threads, (gpointer)current_thread_id);
+ GtkTreeRowReference *reference = (GtkTreeRowReference*)g_hash_table_lookup(threads, (gpointer)active_thread_id);
GtkTreeIter thread_iter;
gtk_tree_model_get_iter(model, &thread_iter, gtk_tree_row_reference_get_path(reference));
- g_signal_handler_disconnect(G_OBJECT(gtk_tree_view_get_selection(GTK_TREE_VIEW(tree))), selection_callback);
-
GtkTreeIter child;
if (gtk_tree_model_iter_children(model, &child, &thread_iter))
{
while(gtk_tree_store_remove(GTK_TREE_STORE(model), &child))
;
}
-
- selection_callback = g_signal_connect(G_OBJECT(gtk_tree_view_get_selection(GTK_TREE_VIEW(tree))), "changed", G_CALLBACK (on_selection_changed), NULL);
}
/*
* set current thread id
*/
-void stree_set_current_thread_id(int thread_id)
+void stree_set_active_thread_id(int thread_id)
{
- current_thread_id = thread_id;
+ active_thread_id = thread_id;
}
Modified: debugger/src/stree.h
4 files changed, 2 insertions(+), 2 deletions(-)
===================================================================
@@ -19,7 +19,7 @@
* MA 02110-1301, USA.
*/
-GtkWidget* stree_init(move_to_line_cb cb);
+GtkWidget* stree_init(move_to_line_cb ml, select_frame_cb sf);
void stree_destroy();
void stree_add(frame *f);
@@ -31,4 +31,4 @@
void stree_select_first_frame();
void stree_remove_frames();
-void stree_set_current_thread_id(int thread_id);
+void stree_set_active_thread_id(int thread_id);
Modified: debugger/src/utils.h
2 files changed, 1 insertions(+), 1 deletions(-)
===================================================================
@@ -19,5 +19,5 @@
* MA 02110-1301, USA.
*/
-void editor_open_position(char* file, int line);
+void editor_open_position(const char* file, int line);
GString* get_word_at_position(ScintillaObject *sci, int position);
--------------
This E-Mail was brought to you by github_commit_mail.py (Source: TBD).
More information about the Plugins-Commits
mailing list