1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
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
26 #include "debug_tree.h"
31 #include <libanjuta/anjuta-debug.h>
34 typedef struct _DmaThreadLocal
41 typedef struct _DmaThreadAndFrame
50 DmaDebuggerQueue
*debugger
;
53 DebugTree
*debug_tree
;
55 DmaThreadLocal
* current
;
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
);
70 if (g_list_length ((GList
*)list
) < 1)
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
);
79 *---------------------------------------------------------------------------*/
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 */
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
),
97 GTK_POLICY_AUTOMATIC
);
98 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (main_w
),
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
,
106 /* This is the list of local variables. */
107 "AnjutaDebuggerLocals", _("Locals"),
108 "gdb-locals-icon", ANJUTA_SHELL_PLACEMENT_BOTTOM
,
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
));
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
));
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
;
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
)
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
;
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
;
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
);
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
);
208 /* Find frame already read */
209 self
->current
= local
;
210 debug_tree_set_model (self
->debug_tree
, self
->current
->model
);
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
);
221 on_program_moved (Locals
*self
, guint pid
, gint thread
)
223 locals_update (self
, thread
);
227 on_frame_changed (Locals
*self
, guint frame
, gint thread
)
229 /* Change thread and frame*/
230 locals_change_frame (self
, frame
, thread
);
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
);
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
);
259 *---------------------------------------------------------------------------*/
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 *---------------------------------------------------------------------------*/
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
);
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
);
293 destroy_locals_gui (self
);