* plugins/debug-manager/command.c:
[anjuta-git-plugin.git] / plugins / debug-manager / locals.c
blob29f71069765fa74a6f4886b9ad3d13af59de5916
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3 locals.c
4 Copyright (C) 2000 Kh. Naba Kumar Singh
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any laterdversion.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 #ifdef HAVE_CONFIG_H
21 # include <config.h>
22 #endif
24 #include "locals.h"
26 #include "debug_tree.h"
28 #include "queue.h"
30 /*#define DEBUG*/
31 #include <libanjuta/anjuta-debug.h>
34 typedef struct _DmaThreadLocal
36 GtkTreeModel *model;
37 gint thread;
38 guint frame;
39 } DmaThreadLocal;
41 typedef struct _DmaThreadAndFrame
43 gint thread;
44 guint frame;
45 } DmaThreadAndFrame;
47 struct _Locals
49 AnjutaPlugin *plugin;
50 DmaDebuggerQueue *debugger;
52 GtkWidget *main_w;
53 DebugTree *debug_tree;
55 DmaThreadLocal* current;
56 GList *list;
59 static void
60 locals_updated (const gpointer data, gpointer user_data, GError *error)
62 const GList *list = (const GList *)data;
63 Locals *self = (Locals*) user_data;
65 g_return_if_fail (self != NULL);
67 if (error != NULL)
68 return;
70 if (g_list_length ((GList*)list) < 1)
71 return;
73 debug_tree_update_all(self->debug_tree);
74 debug_tree_replace_list (self->debug_tree, list);
75 debug_tree_update_all(self->debug_tree);
78 /* Private functions
79 *---------------------------------------------------------------------------*/
81 static void
82 create_locals_gui (Locals *self)
84 g_return_if_fail (self->debug_tree == NULL);
85 g_return_if_fail (self->main_w == NULL);
87 self->debug_tree = debug_tree_new (self->plugin);
88 debug_tree_connect (self->debug_tree, self->debugger);
90 /* Create local window */
91 GtkWidget *main_w;
93 main_w = gtk_scrolled_window_new (NULL, NULL);
94 gtk_widget_show (main_w);
95 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (main_w),
96 GTK_POLICY_AUTOMATIC,
97 GTK_POLICY_AUTOMATIC);
98 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (main_w),
99 GTK_SHADOW_IN);
100 gtk_container_add (GTK_CONTAINER (main_w), debug_tree_get_tree_widget (self->debug_tree));
101 gtk_widget_show_all (main_w);
102 self->main_w = main_w;
104 anjuta_shell_add_widget (self->plugin->shell,
105 self->main_w,
106 /* This is the list of local variables. */
107 "AnjutaDebuggerLocals", _("Locals"),
108 "gdb-locals-icon", ANJUTA_SHELL_PLACEMENT_BOTTOM,
109 NULL);
112 static void
113 destroy_locals_gui (Locals *self)
115 if (self->debug_tree != NULL)
117 debug_tree_free (self->debug_tree);
118 self->debug_tree = NULL;
121 if (self->main_w != NULL)
123 gtk_widget_destroy (GTK_WIDGET (self->main_w));
124 self->main_w = NULL;
128 static void
129 on_clear_locals (gpointer data, gpointer user_data)
131 DmaThreadLocal *frame = (DmaThreadLocal *) data;
132 Locals *self = (Locals *)user_data;
134 debug_tree_remove_model (self->debug_tree, frame->model);
135 g_object_unref (G_OBJECT (frame->model));
136 g_free (frame);
139 static void
140 dma_thread_clear_all_locals (Locals *self)
142 /* Clear all GtkListStore */
143 g_list_foreach (self->list, (GFunc)on_clear_locals, self);
144 g_list_free (self->list);
146 self->current = NULL;
147 self->list = NULL;
150 static gboolean
151 on_find_local (gconstpointer a, gconstpointer b)
153 const DmaThreadLocal *frame = (const DmaThreadLocal *)a;
154 const DmaThreadAndFrame *comp = (const DmaThreadAndFrame *)b;
156 return !((frame->thread == comp->thread) && (frame->frame == comp->frame));
159 static DmaThreadLocal *
160 dma_thread_find_local (Locals *self, gint thread, guint frame)
162 GList *list;
163 DmaThreadAndFrame comp = {thread, frame};
165 list = g_list_find_custom (self->list, (gconstpointer) &comp, on_find_local);
167 return list == NULL ? NULL : (DmaThreadLocal *)list->data;
170 static void
171 dma_thread_add_local (Locals *self, GtkTreeModel *model, gint thread, guint frame)
173 DmaThreadLocal *local;
175 local = g_new (DmaThreadLocal, 1);
176 local->thread = thread;
177 local->frame = frame;
178 local->model = model;
179 g_object_ref (G_OBJECT (model));
181 self->list = g_list_append (self->list, local);
182 self->current = local;
185 /* Private functions
186 *---------------------------------------------------------------------------*/
188 static void locals_update (Locals *self, gint thread)
190 dma_thread_clear_all_locals (self);
192 dma_thread_add_local (self, debug_tree_get_model (self->debug_tree), thread, 0);
194 dma_queue_list_local (self->debugger, locals_updated, self);
197 static void
198 locals_change_frame (Locals *self, guint frame, gint thread)
200 DmaThreadLocal *local;
202 /* Check if we really need a change */
203 if ((self->current != NULL) && (self->current->thread == thread) && (self->current->frame == frame)) return;
205 local = dma_thread_find_local (self, thread, frame);
206 if (local != NULL)
208 /* Find frame already read */
209 self->current = local;
210 debug_tree_set_model (self->debug_tree, self->current->model);
212 return;
215 debug_tree_new_model (self->debug_tree);
216 dma_thread_add_local (self, debug_tree_get_model (self->debug_tree), thread, frame);
217 dma_queue_list_local (self->debugger, locals_updated, self);
220 static void
221 on_program_moved (Locals *self, guint pid, gint thread)
223 locals_update (self, thread);
226 static void
227 on_frame_changed (Locals *self, guint frame, gint thread)
229 /* Change thread and frame*/
230 locals_change_frame (self, frame, thread);
233 static void
234 on_program_exited (Locals *self)
236 /* Disconnect signals */
237 g_signal_handlers_disconnect_by_func (self->plugin, on_program_exited, self);
238 g_signal_handlers_disconnect_by_func (self->plugin, on_program_moved, self);
239 g_signal_handlers_disconnect_by_func (self->plugin, on_frame_changed, self);
241 dma_thread_clear_all_locals (self);
243 destroy_locals_gui (self);
246 static void
247 on_program_started (Locals *self)
249 if (!dma_debugger_queue_is_supported (self->debugger, HAS_VARIABLE)) return;
251 create_locals_gui (self);
253 g_signal_connect_swapped (self->plugin, "program-exited", G_CALLBACK (on_program_exited), self);
254 g_signal_connect_swapped (self->plugin, "program-moved", G_CALLBACK (on_program_moved), self);
255 g_signal_connect_swapped (self->plugin, "frame-changed", G_CALLBACK (on_frame_changed), self);
258 /* Public function
259 *---------------------------------------------------------------------------*/
261 gchar*
262 locals_find_variable_value (Locals *l, const gchar *name)
264 return debug_tree_find_variable_value (l->debug_tree, name);
267 /* Constructor & Destructor
268 *---------------------------------------------------------------------------*/
270 Locals *
271 locals_new (DebugManagerPlugin *plugin)
273 Locals *self = g_new0 (Locals, 1);
275 self->plugin = ANJUTA_PLUGIN (plugin);
276 self->debugger = dma_debug_manager_get_queue (plugin);
278 g_signal_connect_swapped (self->plugin, "program-started", G_CALLBACK (on_program_started), self);
280 return self;
283 void
284 locals_free (Locals *self)
286 g_return_if_fail (self != NULL);
288 g_signal_handlers_disconnect_matched (self->plugin, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, self);
290 dma_thread_clear_all_locals (self);
292 /* Destroy gui */
293 destroy_locals_gui (self);
295 g_free (self);