Integrate adding files with the file manager
[anjuta-git-plugin.git] / plugins / debug-manager / plugin.c
blob0d4a1e3d81bc4578156369232b10b1b9a47292c2
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3 plugin.c
4 Copyright (C) 2004 Naba Kumar
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 later version.
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
21 #include <config.h>
23 /*#define DEBUG*/
25 #include "plugin.h"
27 #include "breakpoints.h"
28 #include "stack_trace.h"
29 #include "threads.h"
30 #include "info.h"
31 #include "memory.h"
32 #include "disassemble.h"
33 #include "signals.h"
34 #include "sharedlib.h"
35 #include "registers.h"
36 #include "utilities.h"
37 #include "start.h"
38 #include "queue.h"
39 #include "variable.h"
41 #include <libanjuta/anjuta-shell.h>
42 #include <libanjuta/anjuta-debug.h>
43 #include <libanjuta/anjuta-status.h>
44 #include <libanjuta/interfaces/ianjuta-file.h>
45 #include <libanjuta/interfaces/ianjuta-editor.h>
46 #include <libanjuta/interfaces/ianjuta-indicable.h>
47 #include <libanjuta/interfaces/ianjuta-markable.h>
48 #include <libanjuta/interfaces/ianjuta-debug-manager.h>
49 #include <libanjuta/interfaces/ianjuta-project-manager.h>
50 #include <libanjuta/interfaces/ianjuta-document-manager.h>
51 #include <libanjuta/interfaces/ianjuta-message-manager.h>
53 #include <libgnomevfs/gnome-vfs.h>
55 /* Contants defintion
56 *---------------------------------------------------------------------------*/
58 #define ICON_FILE "anjuta-debug-manager-plugin-48.png"
59 #define UI_FILE PACKAGE_DATA_DIR"/ui/anjuta-debug-manager.ui"
60 #define GLADE_FILE PACKAGE_DATA_DIR"/glade/anjuta-debug-manager.glade"
62 /* Plugin type
63 *---------------------------------------------------------------------------*/
65 struct _DebugManagerPlugin
67 AnjutaPlugin parent;
69 /* Debugger queue */
70 DmaDebuggerQueue *queue;
72 /* Menu item */
73 gint uiid;
74 GtkActionGroup *start_group;
75 GtkActionGroup *loaded_group;
76 GtkActionGroup *stopped_group;
77 GtkActionGroup *running_group;
79 /* Project */
80 gchar *project_root_uri;
81 guint project_watch_id;
83 /* Editor */
84 IAnjutaEditor *current_editor;
85 guint editor_watch_id;
86 IAnjutaEditor *pc_editor;
87 guint pc_line;
88 gulong pc_address;
89 gboolean busy;
91 /* Debugger components */
92 BreakpointsDBase *breakpoints;
93 DmaStart *start;
94 StackTrace *stack;
95 CpuRegisters *registers;
96 Sharedlibs *sharedlibs;
97 Signals *signals;
98 DmaMemory *memory;
99 DmaDisassemble *disassemble;
100 DmaThreads *thread;
101 DmaVariableDBase *variable;
104 /* Logging view */
105 IAnjutaMessageView* view;
108 struct _DebugManagerPluginClass
110 AnjutaPluginClass parent_class;
113 /* Private functions
114 *---------------------------------------------------------------------------*/
116 static void
117 register_stock_icons (AnjutaPlugin *plugin)
119 static gboolean registered = FALSE;
121 if (registered)
122 return;
123 registered = TRUE;
125 /* Register stock icons */
126 BEGIN_REGISTER_ICON (plugin)
127 REGISTER_ICON (ICON_FILE, "debugger-icon");
128 REGISTER_ICON ("stack.png", "gdb-stack-icon");
129 REGISTER_ICON ("locals.png", "gdb-locals-icon");
130 REGISTER_ICON_FULL ("anjuta-watch", "gdb-watch-icon");
131 REGISTER_ICON_FULL ("anjuta-breakpoint-toggle", ANJUTA_STOCK_BREAKPOINT_TOGGLE);
132 REGISTER_ICON_FULL ("anjuta-breakpoint-clear", ANJUTA_STOCK_BREAKPOINT_CLEAR);
133 /* We have no -24 version for the next two */
134 REGISTER_ICON ("anjuta-breakpoint-disabled-16.png", ANJUTA_STOCK_BREAKPOINT_DISABLED);
135 REGISTER_ICON ("anjuta-breakpoint-enabled-16.png", ANJUTA_STOCK_BREAKPOINT_ENABLED);
136 REGISTER_ICON_FULL ("anjuta-attach", "debugger-attach");
137 REGISTER_ICON_FULL ("anjuta-step-into", "debugger-step-into");
138 REGISTER_ICON_FULL ("anjuta-step-out", "debugger-step-out");
139 REGISTER_ICON_FULL ("anjuta-step-over", "debugger-step-over");
140 REGISTER_ICON_FULL ("anjuta-run-to-cursor", "debugger-run-to-cursor");
141 END_REGISTER_ICON
144 /* Program counter functions
145 *---------------------------------------------------------------------------*/
147 static void
148 show_program_counter_in_editor(DebugManagerPlugin *self)
150 IAnjutaEditor *editor = self->current_editor;
152 if ((editor != NULL) && (self->pc_editor == editor))
154 if (IANJUTA_IS_MARKABLE (editor))
156 ianjuta_markable_mark(IANJUTA_MARKABLE (editor), self->pc_line, IANJUTA_MARKABLE_PROGRAM_COUNTER, NULL);
158 if (IANJUTA_IS_INDICABLE(editor))
160 IAnjutaIterable *begin =
161 ianjuta_editor_get_line_begin_position(editor, self->pc_line, NULL);
162 IAnjutaIterable *end =
163 ianjuta_editor_get_line_end_position(editor, self->pc_line, NULL);
165 ianjuta_indicable_set(IANJUTA_INDICABLE(editor), begin, end,
166 IANJUTA_INDICABLE_IMPORTANT, NULL);
167 g_object_unref (begin);
168 g_object_unref (end);
173 static void
174 hide_program_counter_in_editor(DebugManagerPlugin *self)
176 IAnjutaEditor *editor = self->current_editor;
178 if ((editor != NULL) && (self->pc_editor == editor))
180 if (IANJUTA_IS_MARKABLE (editor))
182 ianjuta_markable_delete_all_markers (IANJUTA_MARKABLE (editor), IANJUTA_MARKABLE_PROGRAM_COUNTER, NULL);
184 if (IANJUTA_IS_INDICABLE(editor))
186 ianjuta_indicable_clear(IANJUTA_INDICABLE(editor), NULL);
191 static void
192 set_program_counter(DebugManagerPlugin *self, const gchar* filename, guint line, gulong address)
194 IAnjutaDocumentManager *docman = NULL;
195 GFile* file;
197 /* Remove previous marker */
198 hide_program_counter_in_editor (self);
199 if (self->pc_editor != NULL)
201 g_object_remove_weak_pointer (G_OBJECT (self->pc_editor), (gpointer *)(gpointer)&self->pc_editor);
202 self->pc_editor = NULL;
204 self->pc_address = address;
206 if (filename != NULL)
208 file = g_file_new_for_path (filename);
209 docman = anjuta_shell_get_interface (ANJUTA_PLUGIN (self)->shell, IAnjutaDocumentManager, NULL);
210 if (docman)
212 IAnjutaEditor* editor;
214 editor = ianjuta_document_manager_goto_file_line(docman, file, line, NULL);
216 if (editor != NULL)
218 self->pc_editor = editor;
219 g_object_add_weak_pointer (G_OBJECT (editor), (gpointer)(gpointer)&self->pc_editor);
220 self->pc_line = line;
221 show_program_counter_in_editor (self);
224 g_object_unref (file);
228 static void
229 value_added_project_root_uri (AnjutaPlugin *plugin, const gchar *name,
230 const GValue *value, gpointer user_data)
232 DebugManagerPlugin *dm_plugin;
233 const gchar *root_uri;
235 dm_plugin = ANJUTA_PLUGIN_DEBUG_MANAGER (plugin);
237 if (dm_plugin->project_root_uri)
238 g_free (dm_plugin->project_root_uri);
239 dm_plugin->project_root_uri = NULL;
241 root_uri = g_value_get_string (value);
242 if (root_uri)
244 dm_plugin->project_root_uri = g_strdup (root_uri);
248 static void
249 value_removed_project_root_uri (AnjutaPlugin *plugin, const gchar *name,
250 gpointer user_data)
252 DebugManagerPlugin *dm_plugin;
254 dm_plugin = ANJUTA_PLUGIN_DEBUG_MANAGER (plugin);
256 if (dm_plugin->project_root_uri)
257 g_free (dm_plugin->project_root_uri);
258 dm_plugin->project_root_uri = NULL;
261 static void
262 value_added_current_editor (AnjutaPlugin *plugin, const char *name,
263 const GValue *value, gpointer data)
265 GObject *editor;
266 DebugManagerPlugin *self;
268 self = ANJUTA_PLUGIN_DEBUG_MANAGER (plugin);
270 editor = g_value_get_object (value);
271 DEBUG_PRINT("add value current editor %p", editor);
273 if (!IANJUTA_IS_EDITOR(editor))
275 self->current_editor = NULL;
276 return;
279 self->current_editor = IANJUTA_EDITOR (editor);
280 g_object_add_weak_pointer (G_OBJECT (self->current_editor), (gpointer *)(gpointer)&self->current_editor);
282 /* Restore program counter marker */
283 show_program_counter_in_editor (self);
286 static void
287 value_removed_current_editor (AnjutaPlugin *plugin,
288 const char *name, gpointer data)
290 DebugManagerPlugin *self = ANJUTA_PLUGIN_DEBUG_MANAGER (plugin);
292 DEBUG_PRINT("remove value current editor %p", self->current_editor);
293 if (self->current_editor)
295 hide_program_counter_in_editor (self);
297 g_object_remove_weak_pointer (G_OBJECT (self->current_editor), (gpointer *)(gpointer)&self->current_editor);
299 self->current_editor = NULL;
302 static void
303 enable_log_view (DebugManagerPlugin *this, gboolean enable)
305 if (enable)
307 if (this->view == NULL)
309 IAnjutaMessageManager* man;
311 man = anjuta_shell_get_interface (ANJUTA_PLUGIN (this)->shell, IAnjutaMessageManager, NULL);
312 this->view = ianjuta_message_manager_add_view (man, _("Debugger Log"), ICON_FILE, NULL);
313 if (this->view != NULL)
315 /*g_signal_connect (G_OBJECT (this->view), "buffer_flushed", G_CALLBACK (on_message_buffer_flushed), this);*/
316 g_object_add_weak_pointer (G_OBJECT (this->view), (gpointer *)(gpointer)&this->view);
317 dma_queue_enable_log (this->queue, this->view);
320 else
322 ianjuta_message_view_clear (this->view, NULL);
325 else
327 if (this->view != NULL)
329 IAnjutaMessageManager* man;
331 man = anjuta_shell_get_interface (ANJUTA_PLUGIN (this)->shell, IAnjutaMessageManager, NULL);
332 ianjuta_message_manager_remove_view (man, this->view, NULL);
333 this->view = NULL;
335 if (this->queue != NULL)
337 dma_queue_disable_log (this->queue);
342 static void
343 on_session_save (AnjutaShell *shell, AnjutaSessionPhase phase,
344 AnjutaSession *session, DebugManagerPlugin *plugin)
346 if (phase == ANJUTA_SESSION_PHASE_FIRST)
347 enable_log_view (plugin, FALSE);
348 if (phase != ANJUTA_SESSION_PHASE_NORMAL)
349 return;
351 /* Close debugger when session changed */
352 if (plugin->queue)
354 dma_queue_abort (plugin->queue);
359 /* State functions
360 *---------------------------------------------------------------------------*/
362 /* Called when the debugger is started but no program is loaded */
364 static void
365 dma_plugin_debugger_started (DebugManagerPlugin *this)
367 AnjutaUI *ui;
368 GtkAction *action;
369 AnjutaStatus* status;
371 DEBUG_PRINT ("DMA: dma_plugin_debugger_started");
373 ui = anjuta_shell_get_ui (ANJUTA_PLUGIN (this)->shell, NULL);
375 /* Update ui */
376 action = gtk_action_group_get_action (this->start_group, "ActionDebuggerStop");
377 gtk_action_set_sensitive (action, TRUE);
378 gtk_action_group_set_visible (this->loaded_group, TRUE);
379 gtk_action_group_set_sensitive (this->loaded_group, FALSE);
380 gtk_action_group_set_visible (this->stopped_group, TRUE);
381 gtk_action_group_set_sensitive (this->stopped_group, FALSE);
382 gtk_action_group_set_visible (this->running_group, TRUE);
383 gtk_action_group_set_sensitive (this->running_group, FALSE);
385 status = anjuta_shell_get_status(ANJUTA_PLUGIN (this)->shell, NULL);
386 anjuta_status_set_default (status, _("Debugger"), _("Started"));
389 /* Called when a program is loaded */
391 static void
392 dma_plugin_program_loaded (DebugManagerPlugin *this)
394 AnjutaUI *ui;
395 AnjutaStatus* status;
397 DEBUG_PRINT ("DMA: dma_plugin_program_loaded");
399 if (this->sharedlibs == NULL)
401 this->sharedlibs = sharedlibs_new (this);
403 if (this->signals == NULL)
405 this->signals = signals_new (this);
408 /* Update ui */
409 ui = anjuta_shell_get_ui (ANJUTA_PLUGIN (this)->shell, NULL);
410 gtk_action_group_set_sensitive (this->loaded_group, TRUE);
411 gtk_action_group_set_sensitive (this->stopped_group, FALSE);
412 gtk_action_group_set_sensitive (this->running_group, FALSE);
414 status = anjuta_shell_get_status(ANJUTA_PLUGIN (this)->shell, NULL);
415 anjuta_status_set_default (status, _("Debugger"), _("Loaded"));
418 /* Called when the program is running */
420 static void
421 dma_plugin_program_running (DebugManagerPlugin *this)
423 AnjutaUI *ui;
424 AnjutaStatus* status;
426 DEBUG_PRINT ("DMA: dma_plugin_program_running");
428 /* Update ui */
429 ui = anjuta_shell_get_ui (ANJUTA_PLUGIN (this)->shell, NULL);
430 gtk_action_group_set_sensitive (this->loaded_group, TRUE);
431 gtk_action_group_set_sensitive (this->stopped_group, FALSE);
432 gtk_action_group_set_sensitive (this->running_group, TRUE);
434 status = anjuta_shell_get_status(ANJUTA_PLUGIN (this)->shell, NULL);
435 anjuta_status_set_default (status, _("Debugger"), _("Running..."));
437 set_program_counter(this, NULL, 0, 0);
440 /* Called when the program is stopped */
442 static void
443 dma_plugin_program_stopped (DebugManagerPlugin *this)
445 AnjutaUI *ui;
446 AnjutaStatus* status;
448 DEBUG_PRINT ("DMA: dma_plugin_program_broken");
450 /* Update ui */
451 ui = anjuta_shell_get_ui (ANJUTA_PLUGIN (this)->shell, NULL);
452 gtk_action_group_set_sensitive (this->loaded_group, TRUE);
453 gtk_action_group_set_sensitive (this->stopped_group, TRUE);
454 gtk_action_group_set_sensitive (this->running_group, FALSE);
456 status = anjuta_shell_get_status(ANJUTA_PLUGIN (this)->shell, NULL);
457 anjuta_status_set_default (status, _("Debugger"), _("Stopped"));
460 /* Called when the program postion change */
462 static void
463 dma_plugin_program_moved (DebugManagerPlugin *this, guint pid, guint tid, gulong address, const gchar* file, guint line)
465 DEBUG_PRINT ("DMA: dma_plugin_program_moved %s %d %lx", file, line, address);
467 set_program_counter (this, file, line, address);
470 /* Called when a program is unloaded */
471 static void
472 dma_plugin_program_unload (DebugManagerPlugin *this)
474 AnjutaUI *ui;
475 AnjutaStatus* status;
477 DEBUG_PRINT ("DMA: dma_plugin_program_unload");
479 if (this->sharedlibs != NULL)
481 sharedlibs_free (this->sharedlibs);
482 this->sharedlibs = NULL;
484 if (this->signals == NULL)
486 signals_free (this->signals);
487 this->signals = NULL;
490 /* Update ui */
491 ui = anjuta_shell_get_ui (ANJUTA_PLUGIN (this)->shell, NULL);
492 gtk_action_group_set_visible (this->start_group, TRUE);
493 gtk_action_group_set_sensitive (this->start_group, TRUE);
494 gtk_action_group_set_visible (this->loaded_group, TRUE);
495 gtk_action_group_set_sensitive (this->loaded_group, FALSE);
496 gtk_action_group_set_visible (this->stopped_group, TRUE);
497 gtk_action_group_set_sensitive (this->stopped_group, FALSE);
498 gtk_action_group_set_visible (this->running_group, TRUE);
499 gtk_action_group_set_sensitive (this->running_group, FALSE);
501 status = anjuta_shell_get_status(ANJUTA_PLUGIN (this)->shell, NULL);
502 anjuta_status_set_default (status, _("Debugger"), _("Unloaded"));
505 /* Called when the debugger is stopped */
507 static void
508 dma_plugin_debugger_stopped (DebugManagerPlugin *self, GError *err)
510 AnjutaUI *ui;
511 GtkAction *action;
512 AnjutaStatus* state;
514 DEBUG_PRINT ("DMA: dma_plugin_debugger_stopped");
516 dma_plugin_program_unload (self);
518 /* Update ui */
519 ui = anjuta_shell_get_ui (ANJUTA_PLUGIN (self)->shell, NULL);
520 gtk_action_group_set_visible (self->start_group, TRUE);
521 gtk_action_group_set_sensitive (self->start_group, TRUE);
522 action = gtk_action_group_get_action (self->start_group, "ActionDebuggerStop");
523 gtk_action_set_sensitive (action, FALSE);
524 gtk_action_group_set_visible (self->loaded_group, TRUE);
525 gtk_action_group_set_sensitive (self->loaded_group, FALSE);
526 gtk_action_group_set_visible (self->stopped_group, TRUE);
527 gtk_action_group_set_sensitive (self->stopped_group, FALSE);
528 gtk_action_group_set_visible (self->running_group, TRUE);
529 gtk_action_group_set_sensitive (self->running_group, FALSE);
531 /* clear indicator */
532 set_program_counter (self, NULL, 0, 0);
534 enable_log_view (self, FALSE);
536 state = anjuta_shell_get_status(ANJUTA_PLUGIN (self)->shell, NULL);
537 anjuta_status_set_default (state, _("Debugger"), NULL);
539 /* Display a warning if debugger stop unexpectedly */
540 if (err != NULL)
542 GtkWindow *parent = GTK_WINDOW (ANJUTA_PLUGIN(self)->shell);
543 anjuta_util_dialog_error (parent, _("Debugger terminated with error %d: %s\n"), err->code, err->message);
548 static void
549 dma_plugin_signal_received (DebugManagerPlugin *self, const gchar *name, const gchar *description)
551 GtkWindow *parent = GTK_WINDOW (ANJUTA_PLUGIN (self)->shell);
553 /* Skip SIGINT signal */
554 if (strcmp(name, "SIGINT") != 0)
556 anjuta_util_dialog_warning (parent, _("Program has received signal: %s\n"), description);
560 /* Called when the user want to go to another location */
562 static void
563 dma_plugin_location_changed (DebugManagerPlugin *self, gulong address, GFile* file, guint line)
565 /* Go to location in editor */
566 if (file != NULL)
568 IAnjutaDocumentManager *docman;
569 docman = anjuta_shell_get_interface (ANJUTA_PLUGIN(self)->shell, IAnjutaDocumentManager, NULL);
570 if (docman)
572 ianjuta_document_manager_goto_file_line (docman, file, line, NULL);
577 /* Start/Stop menu functions
578 *---------------------------------------------------------------------------*/
580 static void
581 on_start_debug_activate (GtkAction* action, DebugManagerPlugin* this)
583 enable_log_view (this, TRUE);
584 dma_run_target (this->start);
587 static void
588 on_attach_to_project_action_activate (GtkAction* action, DebugManagerPlugin* this)
590 enable_log_view (this, TRUE);
591 dma_attach_to_process (this->start);
594 static void
595 on_debugger_stop_activate (GtkAction* action, DebugManagerPlugin* plugin)
597 if (plugin->start)
599 dma_quit_debugger (plugin->start);
603 static void
604 on_add_source_activate (GtkAction* action, DebugManagerPlugin* this)
606 dma_add_source_path (this->start);
609 /* Execute call back
610 *---------------------------------------------------------------------------*/
612 static void
613 on_run_continue_action_activate (GtkAction* action, DebugManagerPlugin* plugin)
615 if (plugin->queue)
616 dma_queue_run (plugin->queue);
619 static void
620 on_step_in_action_activate (GtkAction* action, DebugManagerPlugin* plugin)
622 if (plugin->queue)
624 if ((plugin->disassemble != NULL) && (dma_disassemble_is_focus (plugin->disassemble)))
626 dma_queue_stepi_in (plugin->queue);
628 else
630 dma_queue_step_in (plugin->queue);
635 static void
636 on_step_over_action_activate (GtkAction* action, DebugManagerPlugin* plugin)
638 if (plugin->queue)
640 if ((plugin->disassemble != NULL) && (dma_disassemble_is_focus (plugin->disassemble)))
642 dma_queue_stepi_over (plugin->queue);
644 else
646 dma_queue_step_over (plugin->queue);
651 static void
652 on_step_out_action_activate (GtkAction* action, DebugManagerPlugin* plugin)
654 if (plugin->queue)
655 dma_queue_step_out (plugin->queue);
658 static void
659 on_run_to_cursor_action_activate (GtkAction* action, DebugManagerPlugin* plugin)
661 if (plugin->queue)
663 if ((plugin->disassemble != NULL) && (dma_disassemble_is_focus (plugin->disassemble)))
665 gulong address;
667 address = dma_disassemble_get_current_address (plugin->disassemble);
668 dma_queue_run_to_address (plugin->queue, address);
670 else
672 IAnjutaEditor *editor;
673 GFile* file;
674 gchar *filename;
675 gint line;
677 editor = dma_get_current_editor (ANJUTA_PLUGIN (plugin));
678 if (editor == NULL)
679 return;
680 file = ianjuta_file_get_file (IANJUTA_FILE (editor), NULL);
681 if (file == NULL)
682 return;
684 filename = g_file_get_path (file);
686 line = ianjuta_editor_get_lineno (editor, NULL);
687 dma_queue_run_to (plugin->queue, filename, line);
688 g_free (filename);
689 g_object_unref (file);
694 static void
695 on_debugger_interrupt_activate (GtkAction* action, DebugManagerPlugin* plugin)
697 if (plugin->queue)
698 dma_queue_interrupt (plugin->queue);
701 /* Custom command
702 *---------------------------------------------------------------------------*/
704 static void
705 on_debugger_command_entry_activate (GtkEntry *entry, DebugManagerPlugin *plugin)
707 const gchar *command;
709 command = gtk_entry_get_text (GTK_ENTRY (entry));
710 if (command && strlen (command))
711 dma_queue_send_command (plugin->queue, command);
712 gtk_entry_set_text (entry, "");
715 static void
716 on_debugger_custom_command_activate (GtkAction * action, DebugManagerPlugin *plugin)
718 GladeXML *gxml;
719 GtkWidget *win, *entry;
721 gxml = glade_xml_new (GLADE_FILE, "debugger_command_dialog", NULL);
722 win = glade_xml_get_widget (gxml, "debugger_command_dialog");
723 entry = glade_xml_get_widget (gxml, "debugger_command_entry");
725 gtk_window_set_transient_for (GTK_WINDOW (win),
726 GTK_WINDOW (ANJUTA_PLUGIN (plugin)->shell));
727 g_signal_connect_swapped (win, "response",
728 G_CALLBACK (gtk_widget_destroy),
729 win);
730 g_signal_connect (entry, "activate",
731 G_CALLBACK (on_debugger_command_entry_activate),
732 plugin);
733 g_object_unref (gxml);
736 /* Info callbacks
737 *---------------------------------------------------------------------------*/
739 static void
740 on_debugger_dialog_message (const gpointer data, gpointer user_data, GError* error)
742 const GList *cli_result = data;
743 GtkWindow *parent = GTK_WINDOW (user_data);
744 if (g_list_length ((GList*)cli_result) < 1)
745 return;
746 gdb_info_show_list (parent, (GList*)cli_result, 0, 0);
749 static void
750 on_info_targets_activate (GtkAction *action, DebugManagerPlugin *plugin)
752 dma_queue_info_target (plugin->queue, on_debugger_dialog_message, plugin);
755 static void
756 on_info_program_activate (GtkAction *action, DebugManagerPlugin *plugin)
758 dma_queue_info_program (plugin->queue, on_debugger_dialog_message, plugin);
761 static void
762 on_info_udot_activate (GtkAction *action, DebugManagerPlugin *plugin)
764 dma_queue_info_udot (plugin->queue, on_debugger_dialog_message, plugin);
767 static void
768 on_info_variables_activate (GtkAction *action, DebugManagerPlugin *plugin)
770 dma_queue_info_variables (plugin->queue, on_debugger_dialog_message, plugin);
773 static void
774 on_info_frame_activate (GtkAction *action, DebugManagerPlugin *plugin)
776 dma_queue_info_frame (plugin->queue, 0, on_debugger_dialog_message, plugin);
779 static void
780 on_info_args_activate (GtkAction *action, DebugManagerPlugin *plugin)
782 dma_queue_info_args (plugin->queue, on_debugger_dialog_message, plugin);
785 /* Other informations
786 *---------------------------------------------------------------------------*/
788 /*static void
789 on_info_memory_activate (GtkAction * action, DebugManagerPlugin *plugin)
791 GtkWidget *win_memory;
793 win_memory = memory_info_new (plugin->debugger,
794 GTK_WINDOW (ANJUTA_PLUGIN (plugin)->shell),
795 NULL);
796 gtk_widget_show(win_memory);
799 static void
800 on_debugger_sharedlibs_activate (GtkAction * action, DebugManagerPlugin *plugin)
802 sharedlibs_show (plugin->sharedlibs);
805 static void
806 on_debugger_signals_activate (GtkAction * action, DebugManagerPlugin *plugin)
808 signals_show (plugin->signals);
811 /* Actions table
812 *---------------------------------------------------------------------------*/
814 static GtkActionEntry actions_start[] =
817 "ActionMenuDebug", /* Action name */
818 NULL, /* Stock icon, if any */
819 N_("_Debug"), /* Display label */
820 NULL, /* short-cut */
821 NULL, /* Tooltip */
822 NULL /* action callback */
825 "ActionMenuStart",
826 "debugger-icon",
827 N_("_Start Debugger"),
828 NULL,
829 NULL,
830 NULL
833 "ActionDebuggerRunTarget",
834 NULL,
835 N_("_Debug Program"),
836 "<shift>F12",
837 N_("Start debugger and load the program"),
838 G_CALLBACK (on_start_debug_activate)
841 "ActionDebuggerAttachProcess",
842 "debugger-attach",
843 N_("_Debug Process..."),
844 NULL,
845 N_("Start debugger and attach to a running program"),
846 G_CALLBACK (on_attach_to_project_action_activate)
849 "ActionDebuggerStop",
850 GTK_STOCK_STOP,
851 N_("Stop Debugger"),
852 NULL,
853 N_("Say goodbye to the debugger"),
854 G_CALLBACK (on_debugger_stop_activate)
857 "ActionDebuggerAddSource",
858 NULL,
859 N_("Add source paths..."),
860 NULL,
861 N_("Add additional source paths"),
862 G_CALLBACK (on_add_source_activate)
866 static GtkActionEntry actions_loaded[] =
869 "ActionGdbCommand", /* Action name */
870 NULL, /* Stock icon, if any */
871 N_("Debugger Command..."), /* Display label */
872 NULL, /* short-cut */
873 N_("Custom debugger command"), /* Tooltip */
874 G_CALLBACK (on_debugger_custom_command_activate) /* action callback */
877 "ActionMenuGdbInformation",
878 NULL,
879 N_("_Info"),
880 NULL,
881 NULL,
882 NULL
885 "ActionGdbInfoTargetFiles",
886 NULL,
887 N_("Info _Target Files"),
888 NULL,
889 N_("Display information on the files the debugger is active with"),
890 G_CALLBACK (on_info_targets_activate)
893 "ActionGdbInfoProgram",
894 NULL,
895 N_("Info _Program"),
896 NULL,
897 N_("Display information on the execution status of the program"),
898 G_CALLBACK (on_info_program_activate)
901 "ActionGdbInfoKernelUserStruct",
902 NULL,
903 N_("Info _Kernel User Struct"),
904 NULL,
905 N_("Display the contents of kernel 'struct user' for current child"),
906 G_CALLBACK (on_info_udot_activate)
908 /* {
909 "ActionGdbExamineMemory",
910 NULL,
911 N_("Examine _Memory"),
912 NULL,
913 N_("Display accessible memory"),
914 G_CALLBACK (on_info_memory_activate)
915 },*/
917 "ActionGdbViewSharedlibs",
918 NULL,
919 N_("Shared Libraries"),
920 NULL,
921 N_("Show shared libraries mappings"),
922 G_CALLBACK (on_debugger_sharedlibs_activate)
925 "ActionGdbViewSignals",
926 NULL,
927 N_("Kernel Signals"),
928 NULL,
929 N_("Show kernel signals"),
930 G_CALLBACK (on_debugger_signals_activate)
934 static GtkActionEntry actions_stopped[] =
937 "ActionDebuggerRunContinue", /* Action name */
938 GTK_STOCK_EXECUTE, /* Stock icon, if any */
939 N_("Run/_Continue"), /* Display label */
940 "F4", /* short-cut */
941 N_("Continue the execution of the program"), /* Tooltip */
942 G_CALLBACK (on_run_continue_action_activate) /* action callback */
945 "ActionDebuggerStepIn",
946 "debugger-step-into",
947 N_("Step _In"),
948 "F5",
949 N_("Single step into function"),
950 G_CALLBACK (on_step_in_action_activate)
953 "ActionDebuggerStepOver",
954 "debugger-step-over",
955 N_("Step O_ver"),
956 "F6",
957 N_("Single step over function"),
958 G_CALLBACK (on_step_over_action_activate)
961 "ActionDebuggerStepOut",
962 "debugger-step-out",
963 N_("Step _Out"),
964 "F7",
965 N_("Single step out of the function"),
966 G_CALLBACK (on_step_out_action_activate)
969 "ActionDebuggerRunToPosition",
970 "debugger-run-to-cursor",
971 N_("_Run to Cursor"),
972 "F8",
973 N_("Run to the cursor"),
974 G_CALLBACK (on_run_to_cursor_action_activate)
977 "ActionGdbCommand",
978 NULL,
979 N_("Debugger Command..."),
980 NULL,
981 N_("Custom debugger command"),
982 G_CALLBACK (on_debugger_custom_command_activate)
985 "ActionMenuGdbInformation",
986 NULL,
987 N_("_Info"),
988 NULL,
989 NULL,
990 NULL
993 "ActionGdbInfoGlobalVariables",
994 NULL,
995 N_("Info _Global Variables"),
996 NULL,
997 N_("Display all global and static variables of the program"),
998 G_CALLBACK (on_info_variables_activate)
1001 "ActionGdbInfoCurrentFrame",
1002 NULL,
1003 N_("Info _Current Frame"),
1004 NULL,
1005 N_("Display information about the current frame of execution"),
1006 G_CALLBACK (on_info_frame_activate)
1009 "ActionGdbInfoFunctionArgs",
1010 NULL,
1011 N_("Info Function _Arguments"),
1012 NULL,
1013 N_("Display function arguments of the current frame"),
1014 G_CALLBACK (on_info_args_activate)
1017 "ActionGdbViewSharedlibs",
1018 NULL,
1019 N_("Shared Libraries"),
1020 NULL,
1021 N_("Show shared libraries mappings"),
1022 G_CALLBACK (on_debugger_sharedlibs_activate)
1025 "ActionGdbViewSignals",
1026 NULL,
1027 N_("Kernel Signals"),
1028 NULL,
1029 N_("Show kernel signals"),
1030 G_CALLBACK (on_debugger_signals_activate)
1034 static GtkActionEntry actions_running[] =
1037 "ActionGdbPauseProgram", /* Action name */
1038 GTK_STOCK_MEDIA_PAUSE, /* Stock icon, if any */
1039 N_("Pa_use Program"), /* Display label */
1040 NULL, /* short-cut */
1041 N_("Pauses the execution of the program"), /* Tooltip */
1042 G_CALLBACK (on_debugger_interrupt_activate) /* action callback */
1046 /* AnjutaPlugin functions
1047 *---------------------------------------------------------------------------*/
1049 static gboolean
1050 dma_plugin_activate (AnjutaPlugin* plugin)
1052 DebugManagerPlugin *this;
1053 static gboolean initialized = FALSE;
1054 AnjutaUI *ui;
1056 DEBUG_PRINT ("DebugManagerPlugin: Activating Debug Manager plugin...");
1057 this = ANJUTA_PLUGIN_DEBUG_MANAGER (plugin);
1059 if (!initialized)
1061 initialized = TRUE;
1062 register_stock_icons (ANJUTA_PLUGIN (plugin));
1065 /* Load debugger */
1066 this->queue = dma_debugger_queue_new (plugin);
1067 g_signal_connect (this, "debugger-started", G_CALLBACK (dma_plugin_debugger_started), this);
1068 g_signal_connect (this, "debugger-stopped", G_CALLBACK (dma_plugin_debugger_stopped), this);
1069 g_signal_connect (this, "program-loaded", G_CALLBACK (dma_plugin_program_loaded), this);
1070 g_signal_connect (this, "program-running", G_CALLBACK (dma_plugin_program_running), this);
1071 g_signal_connect (this, "program-stopped", G_CALLBACK (dma_plugin_program_stopped), this);
1072 g_signal_connect (this, "program-exited", G_CALLBACK (dma_plugin_program_loaded), this);
1073 g_signal_connect (this, "program-moved", G_CALLBACK (dma_plugin_program_moved), this);
1074 g_signal_connect (this, "signal-received", G_CALLBACK (dma_plugin_signal_received), this);
1075 g_signal_connect (this, "location-changed", G_CALLBACK (dma_plugin_location_changed), this);
1077 /* Add all our debug manager actions */
1078 ui = anjuta_shell_get_ui (ANJUTA_PLUGIN (plugin)->shell, NULL);
1079 this->start_group =
1080 anjuta_ui_add_action_group_entries (ui, "ActionGroupDebug",
1081 _("Debugger operations"),
1082 actions_start,
1083 G_N_ELEMENTS (actions_start),
1084 GETTEXT_PACKAGE, TRUE, this);
1085 this->loaded_group =
1086 anjuta_ui_add_action_group_entries (ui, "ActionGroupDebug",
1087 _("Debugger operations"),
1088 actions_loaded,
1089 G_N_ELEMENTS (actions_loaded),
1090 GETTEXT_PACKAGE, TRUE, this);
1091 this->stopped_group =
1092 anjuta_ui_add_action_group_entries (ui, "ActionGroupDebug",
1093 _("Debugger operations"),
1094 actions_stopped,
1095 G_N_ELEMENTS (actions_stopped),
1096 GETTEXT_PACKAGE, TRUE, this);
1097 this->running_group =
1098 anjuta_ui_add_action_group_entries (ui, "ActionGroupDebug",
1099 _("Debugger operations"),
1100 actions_running,
1101 G_N_ELEMENTS (actions_running),
1102 GETTEXT_PACKAGE, TRUE, this);
1103 this->uiid = anjuta_ui_merge (ui, UI_FILE);
1105 /* Variable */
1106 this->variable = dma_variable_dbase_new (this);
1108 /* Stack trace */
1109 this->stack = stack_trace_new (this);
1111 /* Thread list */
1112 this->thread = dma_threads_new (this);
1114 /* Create breakpoints list */
1115 this->breakpoints = breakpoints_dbase_new (this);
1117 /* Register list */
1118 this->registers = cpu_registers_new (this);
1120 /* Memory window */
1121 this->memory = dma_memory_new (this);
1123 /* Disassembly window */
1124 this->disassemble = dma_disassemble_new (this);
1126 /* Start debugger part */
1127 this->start = dma_start_new (this);
1129 dma_plugin_debugger_stopped (this, 0);
1131 /* Add watches */
1132 this->project_watch_id =
1133 anjuta_plugin_add_watch (plugin, IANJUTA_PROJECT_MANAGER_PROJECT_ROOT_URI,
1134 value_added_project_root_uri,
1135 value_removed_project_root_uri, NULL);
1136 this->editor_watch_id =
1137 anjuta_plugin_add_watch (plugin, IANJUTA_DOCUMENT_MANAGER_CURRENT_DOCUMENT,
1138 value_added_current_editor,
1139 value_removed_current_editor, NULL);
1141 /* Connect to save session */
1142 g_signal_connect (G_OBJECT (plugin->shell), "save_session",
1143 G_CALLBACK (on_session_save), plugin);
1145 return TRUE;
1148 static gboolean
1149 dma_plugin_deactivate (AnjutaPlugin* plugin)
1151 DebugManagerPlugin *this;
1152 AnjutaUI *ui;
1154 DEBUG_PRINT ("DebugManagerPlugin: Deactivating Debug Manager plugin...");
1156 this = ANJUTA_PLUGIN_DEBUG_MANAGER (plugin);
1158 /* Stop debugger */
1159 dma_plugin_debugger_stopped (this, 0);
1161 g_signal_handlers_disconnect_matched (plugin->shell, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, plugin);
1162 g_signal_handlers_disconnect_matched (plugin, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, plugin);
1164 anjuta_plugin_remove_watch (plugin, this->project_watch_id, FALSE);
1165 anjuta_plugin_remove_watch (plugin, this->editor_watch_id, FALSE);
1167 dma_debugger_queue_free (this->queue);
1168 this->queue = NULL;
1170 ui = anjuta_shell_get_ui (plugin->shell, NULL);
1171 anjuta_ui_unmerge (ui, this->uiid);
1173 dma_variable_dbase_free (this->variable);
1174 this->variable = NULL;
1176 breakpoints_dbase_destroy (this->breakpoints);
1177 this->breakpoints = NULL;
1179 stack_trace_free (this->stack);
1180 this->stack = NULL;
1182 cpu_registers_free (this->registers);
1183 this->registers = NULL;
1185 dma_memory_free (this->memory);
1186 this->memory = NULL;
1188 dma_disassemble_free (this->disassemble);
1189 this->disassemble = NULL;
1191 dma_threads_free (this->thread);
1192 this->thread = NULL;
1194 dma_start_free (this->start);
1195 this->start = NULL;
1197 ui = anjuta_shell_get_ui (ANJUTA_PLUGIN (this)->shell, NULL);
1198 anjuta_ui_remove_action_group (ui, this->start_group);
1199 anjuta_ui_remove_action_group (ui, this->loaded_group);
1200 anjuta_ui_remove_action_group (ui, this->stopped_group);
1201 anjuta_ui_remove_action_group (ui, this->running_group);
1203 if (this->view != NULL)
1205 g_object_remove_weak_pointer (G_OBJECT (this->view), (gpointer*)(gpointer)&this->view);
1206 this->view = NULL;
1209 return TRUE;
1212 /* Public functions
1213 *---------------------------------------------------------------------------*/
1215 DmaDebuggerQueue*
1216 dma_debug_manager_get_queue (DebugManagerPlugin *self)
1218 return self->queue;
1221 /* GObject functions
1222 *---------------------------------------------------------------------------*/
1224 /* Used in dispose and finalize */
1225 static gpointer parent_class;
1227 /* instance_init is the constructor. All functions should work after this
1228 * call. */
1230 static void
1231 dma_plugin_instance_init (GObject* obj)
1233 DebugManagerPlugin *plugin = ANJUTA_PLUGIN_DEBUG_MANAGER (obj);
1235 plugin->uiid = 0;
1237 plugin->project_root_uri = NULL;
1238 plugin->queue = NULL;
1239 plugin->current_editor = NULL;
1240 plugin->pc_editor = NULL;
1241 plugin->editor_watch_id = 0;
1242 plugin->project_watch_id = 0;
1243 plugin->breakpoints = NULL;
1244 plugin->registers = NULL;
1245 plugin->signals = NULL;
1246 plugin->sharedlibs = NULL;
1247 plugin->view = NULL;
1249 /* plugin->uri = NULL; */
1252 /* dispose is the first destruction step. It is used to unref object created
1253 * with instance_init in order to break reference counting cycles. This
1254 * function could be called several times. All function should still work
1255 * after this call. It has to called its parents.*/
1257 static void
1258 dma_plugin_dispose (GObject* obj)
1260 G_OBJECT_CLASS (parent_class)->dispose (obj);
1263 /* finalize is the last destruction step. It must free all memory allocated
1264 * with instance_init. It is called only one time just before releasing all
1265 * memory */
1267 static void
1268 dma_plugin_finalize (GObject* obj)
1270 DebugManagerPlugin *self = ANJUTA_PLUGIN_DEBUG_MANAGER (obj);
1272 if (self->pc_editor != NULL)
1274 g_object_remove_weak_pointer (G_OBJECT (self->pc_editor), (gpointer *)(gpointer)&self->pc_editor);
1276 if (self->current_editor != NULL)
1278 g_object_remove_weak_pointer (G_OBJECT (self->current_editor), (gpointer *)(gpointer)&self->current_editor);
1281 G_OBJECT_CLASS (parent_class)->finalize (obj);
1284 /* class_init intialize the class itself not the instance */
1286 static void
1287 dma_plugin_class_init (GObjectClass* klass)
1289 AnjutaPluginClass *plugin_class = ANJUTA_PLUGIN_CLASS (klass);
1291 parent_class = g_type_class_peek_parent (klass);
1293 plugin_class->activate = dma_plugin_activate;
1294 plugin_class->deactivate = dma_plugin_deactivate;
1295 klass->dispose = dma_plugin_dispose;
1296 klass->finalize = dma_plugin_finalize;
1299 /* Implementation of IAnjutaDebugManager interface
1300 *---------------------------------------------------------------------------*/
1302 static void
1303 idebug_manager_iface_init (IAnjutaDebugManagerIface *iface)
1307 ANJUTA_PLUGIN_BEGIN (DebugManagerPlugin, dma_plugin);
1308 ANJUTA_PLUGIN_ADD_INTERFACE(idebug_manager, IANJUTA_TYPE_DEBUG_MANAGER);
1309 ANJUTA_PLUGIN_END;
1311 ANJUTA_SIMPLE_PLUGIN (DebugManagerPlugin, dma_plugin);