Updated Spanish translation
[anjuta-git-plugin.git] / plugins / debug-manager / plugin.c
blob7befd2e0147ba722c83dc5846d8ed9b641d4a5c9
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include <config.h>
23 /*#define DEBUG*/
25 #include "plugin.h"
27 #include "breakpoints.h"
28 #include "watch.h"
29 #include "locals.h"
30 #include "stack_trace.h"
31 #include "threads.h"
32 #include "info.h"
33 #include "memory.h"
34 #include "disassemble.h"
35 #include "signals.h"
36 #include "sharedlib.h"
37 #include "registers.h"
38 #include "utilities.h"
39 #include "start.h"
40 #include "debugger.h"
42 #include <libanjuta/anjuta-shell.h>
43 #include <libanjuta/anjuta-debug.h>
44 #include <libanjuta/anjuta-status.h>
45 #include <libanjuta/interfaces/ianjuta-file.h>
46 #include <libanjuta/interfaces/ianjuta-editor.h>
47 #include <libanjuta/interfaces/ianjuta-indicable.h>
48 #include <libanjuta/interfaces/ianjuta-markable.h>
49 #include <libanjuta/interfaces/ianjuta-debug-manager.h>
50 #include <libanjuta/interfaces/ianjuta-project-manager.h>
51 #include <libanjuta/interfaces/ianjuta-document-manager.h>
52 #include <libanjuta/interfaces/ianjuta-message-manager.h>
54 #include <libgnomevfs/gnome-vfs.h>
56 /* Contants defintion
57 *---------------------------------------------------------------------------*/
59 #define ICON_FILE "anjuta-debug-manager.plugin.png"
60 #define UI_FILE PACKAGE_DATA_DIR"/ui/anjuta-debug-manager.ui"
61 #define GLADE_FILE PACKAGE_DATA_DIR"/glade/anjuta-debug-manager.glade"
63 /* Plugin type
64 *---------------------------------------------------------------------------*/
66 struct _DebugManagerPlugin
68 AnjutaPlugin parent;
70 /* Debugger queue */
71 DmaDebuggerQueue *queue;
72 IAnjutaDebugger *debugger;
74 /* Menu item */
75 gint uiid;
76 GtkActionGroup *start_group;
77 GtkActionGroup *loaded_group;
78 GtkActionGroup *stopped_group;
79 GtkActionGroup *running_group;
81 /* Project */
82 gchar *project_root_uri;
83 guint project_watch_id;
85 /* Editor */
86 IAnjutaEditor *current_editor;
87 guint editor_watch_id;
88 IAnjutaEditor *pc_editor;
89 guint pc_line;
90 guint pc_address;
91 gboolean busy;
93 /* Debugger components */
94 Locals *locals;
95 ExprWatch *watch;
96 BreakpointsDBase *breakpoints;
97 DmaStart *start;
98 StackTrace *stack;
99 CpuRegisters *registers;
100 Sharedlibs *sharedlibs;
101 Signals *signals;
102 DmaMemory *memory;
103 DmaDisassemble *disassemble;
104 DmaThreads *thread;
107 /* Logging view */
108 IAnjutaMessageView* view;
111 struct _DebugManagerPluginClass
113 AnjutaPluginClass parent_class;
116 /* Private functions
117 *---------------------------------------------------------------------------*/
119 #define REGISTER_ICON(icon, stock_id) \
120 pixbuf = gdk_pixbuf_new_from_file (PACKAGE_PIXMAPS_DIR"/"icon, NULL); \
121 icon_set = gtk_icon_set_new_from_pixbuf (pixbuf); \
122 gtk_icon_factory_add (icon_factory, stock_id, icon_set); \
123 g_object_unref (pixbuf);
125 static void
126 register_stock_icons (AnjutaPlugin *plugin)
128 AnjutaUI *ui;
129 GtkIconFactory *icon_factory;
130 GtkIconSet *icon_set;
131 GdkPixbuf *pixbuf;
132 static gboolean registered = FALSE;
134 if (registered)
135 return;
136 registered = TRUE;
138 /* Register stock icons */
139 ui = anjuta_shell_get_ui (plugin->shell, NULL);
140 icon_factory = anjuta_ui_get_icon_factory (ui);
141 REGISTER_ICON (ICON_FILE, "debugger-icon");
142 REGISTER_ICON ("stack.png", "gdb-stack-icon");
143 REGISTER_ICON ("locals.png", "gdb-locals-icon");
144 REGISTER_ICON ("watch.png", "gdb-watch-icon");
145 REGISTER_ICON ("breakpoint.png", "gdb-breakpoint-toggle");
146 REGISTER_ICON ("detach.png", "debugger-detach");
147 REGISTER_ICON ("step-into.png", "debugger-step-into");
148 REGISTER_ICON ("step-out.png", "debugger-step-out");
149 REGISTER_ICON ("step-over.png", "debugger-step-over");
150 REGISTER_ICON ("run-to-cursor.png", "debugger-run-to-cursor");
153 /* Program counter functions
154 *---------------------------------------------------------------------------*/
156 static void
157 show_program_counter_in_editor(DebugManagerPlugin *self)
159 IAnjutaEditor *editor = self->current_editor;
161 if ((editor != NULL) && (self->pc_editor == editor))
163 if (IANJUTA_IS_MARKABLE (editor))
165 ianjuta_markable_mark(IANJUTA_MARKABLE (editor), self->pc_line, IANJUTA_MARKABLE_PROGRAM_COUNTER, NULL);
167 if (IANJUTA_IS_INDICABLE(editor))
169 gint begin = ianjuta_editor_get_line_begin_position(editor, self->pc_line, NULL);
170 gint end = ianjuta_editor_get_line_end_position(editor, self->pc_line, NULL);
172 ianjuta_indicable_set(IANJUTA_INDICABLE(editor), begin, end, IANJUTA_INDICABLE_IMPORTANT,
173 NULL);
178 static void
179 show_program_counter_in_disassembler(DebugManagerPlugin *self)
181 dma_disassemble_mark (self->disassemble, self->pc_address, IANJUTA_MARKABLE_PROGRAM_COUNTER);
182 dma_disassemble_goto_address (self->disassemble, self->pc_address);
185 static void
186 hide_program_counter_in_editor(DebugManagerPlugin *self)
188 IAnjutaEditor *editor = self->current_editor;
190 if ((editor != NULL) && (self->pc_editor == editor))
192 if (IANJUTA_IS_MARKABLE (editor))
194 ianjuta_markable_delete_all_markers (IANJUTA_MARKABLE (editor), IANJUTA_MARKABLE_PROGRAM_COUNTER, NULL);
196 if (IANJUTA_IS_INDICABLE(editor))
198 ianjuta_indicable_clear(IANJUTA_INDICABLE(editor), NULL);
203 static void
204 hide_program_counter_in_disassembler(DebugManagerPlugin *self)
206 dma_disassemble_clear_all_mark (self->disassemble, IANJUTA_MARKABLE_PROGRAM_COUNTER);
209 static void
210 set_program_counter(DebugManagerPlugin *self, const gchar* file, guint line, guint address)
212 IAnjutaDocumentManager *docman = NULL;
213 gchar *file_uri;
215 /* Remove previous marker */
216 hide_program_counter_in_editor (self);
217 hide_program_counter_in_disassembler (self);
218 if (self->pc_editor != NULL)
220 g_object_remove_weak_pointer (G_OBJECT (self->pc_editor), (gpointer *)&self->pc_editor);
221 self->pc_editor = NULL;
223 self->pc_address = address;
225 if (address != 0)
226 show_program_counter_in_disassembler (self);
228 if (file != NULL)
230 docman = anjuta_shell_get_interface (ANJUTA_PLUGIN (self)->shell, IAnjutaDocumentManager, NULL);
231 file_uri = g_strconcat ("file://", file, NULL);
232 if (docman)
234 IAnjutaEditor* editor;
236 editor = ianjuta_document_manager_goto_file_line(docman, file_uri, line, NULL);
238 if (editor != NULL)
240 self->pc_editor = editor;
241 g_object_add_weak_pointer (G_OBJECT (editor), (gpointer)&self->pc_editor);
242 self->pc_line = line;
243 show_program_counter_in_editor (self);
246 g_free (file_uri);
250 static void
251 value_added_project_root_uri (AnjutaPlugin *plugin, const gchar *name,
252 const GValue *value, gpointer user_data)
254 DebugManagerPlugin *dm_plugin;
255 const gchar *root_uri;
257 dm_plugin = ANJUTA_PLUGIN_DEBUG_MANAGER (plugin);
259 if (dm_plugin->project_root_uri)
260 g_free (dm_plugin->project_root_uri);
261 dm_plugin->project_root_uri = NULL;
263 root_uri = g_value_get_string (value);
264 if (root_uri)
266 dm_plugin->project_root_uri = g_strdup (root_uri);
270 static void
271 value_removed_project_root_uri (AnjutaPlugin *plugin, const gchar *name,
272 gpointer user_data)
274 DebugManagerPlugin *dm_plugin;
276 dm_plugin = ANJUTA_PLUGIN_DEBUG_MANAGER (plugin);
278 if (dm_plugin->project_root_uri)
279 g_free (dm_plugin->project_root_uri);
280 dm_plugin->project_root_uri = NULL;
283 static void
284 value_added_current_editor (AnjutaPlugin *plugin, const char *name,
285 const GValue *value, gpointer data)
287 IAnjutaEditor *editor;
288 DebugManagerPlugin *self;
290 editor = IANJUTA_EDITOR (g_value_get_object (value));
291 self = ANJUTA_PLUGIN_DEBUG_MANAGER (plugin);
292 self->current_editor = editor;
293 g_object_add_weak_pointer (G_OBJECT (self->current_editor), (gpointer *)&self->current_editor);
295 /* Restore breakpoints */
296 breakpoints_dbase_set_all_in_editor (self->breakpoints, editor);
298 /* Restore program counter marker */
299 show_program_counter_in_editor (self);
302 static void
303 value_removed_current_editor (AnjutaPlugin *plugin,
304 const char *name, gpointer data)
306 DebugManagerPlugin *self = ANJUTA_PLUGIN_DEBUG_MANAGER (plugin);
308 if (self->current_editor)
310 breakpoints_dbase_clear_all_in_editor (self->breakpoints,
311 self->current_editor);
313 hide_program_counter_in_editor (self);
315 g_object_remove_weak_pointer (G_OBJECT (self->current_editor), (gpointer *)&self->current_editor);
316 self->current_editor = NULL;
320 static void
321 enable_log_view (DebugManagerPlugin *this, gboolean enable)
323 if (enable)
325 if (this->view == NULL)
327 IAnjutaMessageManager* man;
329 man = anjuta_shell_get_interface (ANJUTA_PLUGIN (this)->shell, IAnjutaMessageManager, NULL);
330 this->view = ianjuta_message_manager_add_view (man, _("Debugger Log"), ICON_FILE, NULL);
331 if (this->view != NULL)
333 //g_signal_connect (G_OBJECT (this->view), "buffer_flushed", G_CALLBACK (on_message_buffer_flushed), this);
334 g_object_add_weak_pointer (G_OBJECT (this->view), (gpointer *)&this->view);
335 ianjuta_debugger_enable_log (this->debugger, this->view, NULL);
338 else
340 ianjuta_message_view_clear (this->view, NULL);
343 else
345 if (this->view != NULL)
347 IAnjutaMessageManager* man;
349 man = anjuta_shell_get_interface (ANJUTA_PLUGIN (this)->shell, IAnjutaMessageManager, NULL);
350 ianjuta_message_manager_remove_view (man, this->view, NULL);
351 this->view = NULL;
353 ianjuta_debugger_disable_log (this->debugger, NULL);
357 static void
358 on_session_save (AnjutaShell *shell, AnjutaSessionPhase phase,
359 AnjutaSession *session, DebugManagerPlugin *plugin)
361 if (phase == ANJUTA_SESSION_PHASE_FIRST)
362 enable_log_view (plugin, FALSE);
363 if (phase != ANJUTA_SESSION_PHASE_NORMAL)
364 return;
366 /* Close debugger when session changed */
367 if (plugin->debugger)
369 ianjuta_debugger_abort (plugin->debugger, NULL);
374 /* State functions
375 *---------------------------------------------------------------------------*/
377 static void
378 dma_plugin_debugger_ready (DebugManagerPlugin *self, IAnjutaDebuggerStatus stat)
380 AnjutaStatus* status;
382 if ((stat == IANJUTA_DEBUGGER_BUSY) != self->busy)
384 status = anjuta_shell_get_status(ANJUTA_PLUGIN (self)->shell, NULL);
385 if (!self->busy)
387 anjuta_status_busy_push (status);
388 self->busy = TRUE;
390 else
392 anjuta_status_busy_pop (status);
393 self->busy = FALSE;
398 /* Called when the debugger is started but no program is loaded */
400 static void
401 dma_plugin_debugger_started (DebugManagerPlugin *this)
403 AnjutaUI *ui;
404 GtkAction *action;
405 AnjutaStatus* status;
407 DEBUG_PRINT ("DMA: dma_plugin_debugger_started");
409 ui = anjuta_shell_get_ui (ANJUTA_PLUGIN (this)->shell, NULL);
411 /* Update ui */
412 action = gtk_action_group_get_action (this->start_group, "ActionDebuggerStop");
413 gtk_action_set_sensitive (action, TRUE);
414 gtk_action_group_set_visible (this->loaded_group, TRUE);
415 gtk_action_group_set_sensitive (this->loaded_group, FALSE);
416 gtk_action_group_set_visible (this->stopped_group, TRUE);
417 gtk_action_group_set_sensitive (this->stopped_group, FALSE);
418 gtk_action_group_set_visible (this->running_group, TRUE);
419 gtk_action_group_set_sensitive (this->running_group, FALSE);
421 status = anjuta_shell_get_status(ANJUTA_PLUGIN (this)->shell, NULL);
422 anjuta_status_set_default (status, _("Debugger"), _("Started"));
424 dma_plugin_debugger_ready (this, IANJUTA_DEBUGGER_STARTED);
427 /* Called when a program is loaded */
429 static void
430 dma_plugin_program_loaded (DebugManagerPlugin *this)
432 AnjutaUI *ui;
433 AnjutaStatus* status;
435 DEBUG_PRINT ("DMA: dma_plugin_program_loaded");
437 if (this->sharedlibs == NULL)
439 this->sharedlibs = sharedlibs_new (this->debugger);
441 if (this->signals == NULL)
443 this->signals = signals_new (this->debugger);
446 /* Connect components */
447 breakpoints_dbase_connect (this->breakpoints, this->debugger);
448 expr_watch_connect (this->watch, this->debugger);
449 // locals_connect (this->locals, this->debugger);
450 // stack_trace_connect (this->stack, this->debugger);
451 // cpu_registers_connect (this->registers, this->debugger);
453 /* Update ui */
454 ui = anjuta_shell_get_ui (ANJUTA_PLUGIN (this)->shell, NULL);
455 gtk_action_group_set_sensitive (this->loaded_group, TRUE);
456 gtk_action_group_set_sensitive (this->stopped_group, FALSE);
457 gtk_action_group_set_sensitive (this->running_group, FALSE);
459 status = anjuta_shell_get_status(ANJUTA_PLUGIN (this)->shell, NULL);
460 anjuta_status_set_default (status, _("Debugger"), _("Loaded"));
463 /* Called when the program is running */
465 static void
466 dma_plugin_program_running (DebugManagerPlugin *this)
468 AnjutaUI *ui;
469 AnjutaStatus* status;
471 DEBUG_PRINT ("DMA: dma_plugin_program_running");
473 /* Update ui */
474 ui = anjuta_shell_get_ui (ANJUTA_PLUGIN (this)->shell, NULL);
475 gtk_action_group_set_sensitive (this->loaded_group, TRUE);
476 gtk_action_group_set_sensitive (this->stopped_group, FALSE);
477 gtk_action_group_set_sensitive (this->running_group, TRUE);
479 status = anjuta_shell_get_status(ANJUTA_PLUGIN (this)->shell, NULL);
480 anjuta_status_set_default (status, _("Debugger"), _("Running..."));
482 set_program_counter(this, NULL, 0, 0);
485 /* Called when the program is stopped */
487 static void
488 dma_plugin_program_stopped (DebugManagerPlugin *this)
490 AnjutaUI *ui;
491 AnjutaStatus* status;
493 DEBUG_PRINT ("DMA: dma_plugin_program_broken");
495 expr_watch_cmd_queqe (this->watch);
496 // locals_update (this->locals);
497 // stack_trace_update (this->stack);
498 // cpu_registers_update (this->registers);
500 /* Update ui */
501 ui = anjuta_shell_get_ui (ANJUTA_PLUGIN (this)->shell, NULL);
502 gtk_action_group_set_sensitive (this->loaded_group, TRUE);
503 gtk_action_group_set_sensitive (this->stopped_group, TRUE);
504 gtk_action_group_set_sensitive (this->running_group, FALSE);
506 status = anjuta_shell_get_status(ANJUTA_PLUGIN (this)->shell, NULL);
507 anjuta_status_set_default (status, _("Debugger"), _("Stopped"));
510 /* Called when the program postion change */
512 static void
513 dma_plugin_location_changed (DebugManagerPlugin *this, const gchar* file, guint line, guint address)
515 gchar *msg;
517 DEBUG_PRINT ("DMA: dma_plugin_location_changed %s %d %x", file, line, address);
519 msg = g_strdup_printf (_("Location: %s, line %d\n"), file, line);
520 dma_debugger_message (this->queue, msg);
521 g_free (msg);
523 set_program_counter (this, file, line, address);
526 /* Called when a program is unloaded */
527 static void
528 dma_plugin_program_unload (DebugManagerPlugin *this)
530 AnjutaUI *ui;
531 AnjutaStatus* status;
533 DEBUG_PRINT ("DMA: dma_plugin_program_unload");
535 if (this->sharedlibs != NULL)
537 sharedlibs_free (this->sharedlibs);
538 this->sharedlibs = NULL;
540 if (this->signals == NULL)
542 signals_free (this->signals);
543 this->signals = NULL;
546 /* Disconnect components */
547 breakpoints_dbase_disconnect (this->breakpoints);
549 /* Update ui */
550 ui = anjuta_shell_get_ui (ANJUTA_PLUGIN (this)->shell, NULL);
551 gtk_action_group_set_visible (this->start_group, TRUE);
552 gtk_action_group_set_sensitive (this->start_group, TRUE);
553 gtk_action_group_set_visible (this->loaded_group, TRUE);
554 gtk_action_group_set_sensitive (this->loaded_group, FALSE);
555 gtk_action_group_set_visible (this->stopped_group, TRUE);
556 gtk_action_group_set_sensitive (this->stopped_group, FALSE);
557 gtk_action_group_set_visible (this->running_group, TRUE);
558 gtk_action_group_set_sensitive (this->running_group, FALSE);
560 status = anjuta_shell_get_status(ANJUTA_PLUGIN (this)->shell, NULL);
561 anjuta_status_set_default (status, _("Debugger"), _("Unloaded"));
564 /* Called when the debugger is stopped */
566 static void
567 dma_plugin_debugger_stopped (DebugManagerPlugin *self, gint status)
569 AnjutaUI *ui;
570 GtkAction *action;
571 AnjutaStatus* state;
573 DEBUG_PRINT ("DMA: dma_plugin_debugger_stopped");
575 dma_plugin_program_unload (self);
577 /* Update ui */
578 ui = anjuta_shell_get_ui (ANJUTA_PLUGIN (self)->shell, NULL);
579 gtk_action_group_set_visible (self->start_group, TRUE);
580 gtk_action_group_set_sensitive (self->start_group, TRUE);
581 action = gtk_action_group_get_action (self->start_group, "ActionDebuggerStop");
582 gtk_action_set_sensitive (action, FALSE);
583 gtk_action_group_set_visible (self->loaded_group, TRUE);
584 gtk_action_group_set_sensitive (self->loaded_group, FALSE);
585 gtk_action_group_set_visible (self->stopped_group, TRUE);
586 gtk_action_group_set_sensitive (self->stopped_group, FALSE);
587 gtk_action_group_set_visible (self->running_group, TRUE);
588 gtk_action_group_set_sensitive (self->running_group, FALSE);
590 /* clear indicator */
591 set_program_counter (self, NULL, 0, 0);
593 enable_log_view (self, FALSE);
595 state = anjuta_shell_get_status(ANJUTA_PLUGIN (self)->shell, NULL);
596 anjuta_status_set_default (state, _("Debugger"), NULL);
598 dma_plugin_debugger_ready (self, IANJUTA_DEBUGGER_STOPPED);
600 /* Display a warning if debugger stop unexpectedly */
601 if (status != 0)
603 GtkWindow *parent = GTK_WINDOW (ANJUTA_PLUGIN(self)->shell);
604 anjuta_util_dialog_error (parent, _("gdb terminated unexpectedly with status %d\n"), status);
609 static void
610 dma_plugin_signal_received (DebugManagerPlugin *self, const gchar *name, const gchar *description)
612 GtkWindow *parent = GTK_WINDOW (ANJUTA_PLUGIN (self)->shell);
614 /* Skip SIGINT signal */
615 if (strcmp(name, "SIGINT") != 0)
617 anjuta_util_dialog_warning (parent, _("Program has received signal: %s\n"), description);
621 /* Start/Stop menu functions
622 *---------------------------------------------------------------------------*/
624 static void
625 on_start_debug_activate (GtkAction* action, DebugManagerPlugin* this)
627 enable_log_view (this, TRUE);
628 if (dma_run_target (this->start))
630 GtkAction *action;
631 action = gtk_action_group_get_action (this->start_group, "ActionDebuggerRestartTarget");
632 gtk_action_set_sensitive (action, TRUE);
637 static void
638 on_restart_debug_activate (GtkAction* action, DebugManagerPlugin* this)
640 enable_log_view (this, TRUE);
641 dma_rerun_target (this->start);
644 static void
645 on_attach_to_project_action_activate (GtkAction* action, DebugManagerPlugin* this)
647 enable_log_view (this, TRUE);
648 dma_attach_to_process (this->start);
651 static void
652 on_debugger_stop_activate (GtkAction* action, DebugManagerPlugin* plugin)
654 if (plugin->debugger)
656 ianjuta_debugger_interrupt (plugin->debugger, NULL);
657 ianjuta_debugger_quit (plugin->debugger, NULL);
661 /* Execute call back
662 *---------------------------------------------------------------------------*/
664 static void
665 on_run_continue_action_activate (GtkAction* action, DebugManagerPlugin* plugin)
667 if (plugin->debugger)
668 ianjuta_debugger_run (plugin->debugger, NULL /* TODO */);
671 static void
672 on_step_in_action_activate (GtkAction* action, DebugManagerPlugin* plugin)
674 if (plugin->debugger)
675 ianjuta_debugger_step_in (plugin->debugger, NULL /* TODO */);
678 static void
679 on_step_over_action_activate (GtkAction* action, DebugManagerPlugin* plugin)
681 if (plugin->debugger)
682 ianjuta_debugger_step_over (plugin->debugger, NULL /* TODO */);
685 static void
686 on_step_out_action_activate (GtkAction* action, DebugManagerPlugin* plugin)
688 if (plugin->debugger)
689 ianjuta_debugger_step_out (plugin->debugger, NULL /* TODO */);
692 static void
693 on_run_to_cursor_action_activate (GtkAction* action, DebugManagerPlugin* plugin)
695 IAnjutaDocumentManager *docman;
696 IAnjutaEditor *editor;
697 const gchar *uri;
698 gchar *file;
699 gint line;
701 if (plugin->debugger == NULL)
702 return;
704 docman = IANJUTA_DOCUMENT_MANAGER (anjuta_shell_get_object (ANJUTA_PLUGIN (plugin)->shell, "IAnjutaDocumentManager", NULL));
705 if (docman == NULL)
706 return;
708 editor = ianjuta_document_manager_get_current_editor (docman, NULL);
709 if (editor == NULL)
710 return;
712 uri = ianjuta_file_get_uri (IANJUTA_FILE (editor), NULL);
713 if (uri == NULL)
714 return;
716 file = gnome_vfs_get_local_path_from_uri (uri);
718 line = ianjuta_editor_get_lineno (editor, NULL);
719 ianjuta_debugger_run_to (plugin->debugger, file, line,
720 NULL /* TODO */);
721 g_free (file);
725 static void
726 on_debugger_interrupt_activate (GtkAction* action, DebugManagerPlugin* plugin)
728 if (plugin->debugger)
729 ianjuta_debugger_interrupt (plugin->debugger, NULL);
732 /* Custom command
733 *---------------------------------------------------------------------------*/
735 static void
736 on_debugger_command_entry_activate (GtkEntry *entry, DebugManagerPlugin *plugin)
738 const gchar *command;
740 command = gtk_entry_get_text (GTK_ENTRY (entry));
741 if (command && strlen (command))
742 ianjuta_debugger_send_command (plugin->debugger, command, NULL);
743 gtk_entry_set_text (entry, "");
746 static void
747 on_debugger_custom_command_activate (GtkAction * action, DebugManagerPlugin *plugin)
749 GladeXML *gxml;
750 GtkWidget *win, *entry;
752 gxml = glade_xml_new (GLADE_FILE, "debugger_command_dialog", NULL);
753 win = glade_xml_get_widget (gxml, "debugger_command_dialog");
754 entry = glade_xml_get_widget (gxml, "debugger_command_entry");
756 gtk_window_set_transient_for (GTK_WINDOW (win),
757 GTK_WINDOW (ANJUTA_PLUGIN (plugin)->shell));
758 g_signal_connect_swapped (win, "response",
759 G_CALLBACK (gtk_widget_destroy),
760 win);
761 g_signal_connect (entry, "activate",
762 G_CALLBACK (on_debugger_command_entry_activate),
763 plugin);
764 g_object_unref (gxml);
767 /* Info callbacks
768 *---------------------------------------------------------------------------*/
770 static void
771 on_debugger_dialog_message (const gpointer data, gpointer user_data, GError* error)
773 const GList *cli_result = data;
774 GtkWindow *parent = GTK_WINDOW (user_data);
775 if (g_list_length ((GList*)cli_result) < 1)
776 return;
777 gdb_info_show_list (parent, (GList*)cli_result, 0, 0);
780 static void
781 on_info_targets_activate (GtkAction *action, DebugManagerPlugin *plugin)
783 ianjuta_debugger_info_target (plugin->debugger, on_debugger_dialog_message, plugin, NULL);
786 static void
787 on_info_program_activate (GtkAction *action, DebugManagerPlugin *plugin)
789 ianjuta_debugger_info_program (plugin->debugger, on_debugger_dialog_message, plugin, NULL);
792 static void
793 on_info_udot_activate (GtkAction *action, DebugManagerPlugin *plugin)
795 ianjuta_debugger_info_udot (plugin->debugger, on_debugger_dialog_message, plugin, NULL);
798 static void
799 on_info_variables_activate (GtkAction *action, DebugManagerPlugin *plugin)
801 ianjuta_debugger_info_variables (plugin->debugger, on_debugger_dialog_message, plugin, NULL);
804 static void
805 on_info_frame_activate (GtkAction *action, DebugManagerPlugin *plugin)
807 ianjuta_debugger_info_frame (plugin->debugger, 0, on_debugger_dialog_message, plugin, NULL);
810 static void
811 on_info_args_activate (GtkAction *action, DebugManagerPlugin *plugin)
813 ianjuta_debugger_info_args (plugin->debugger, on_debugger_dialog_message, plugin, NULL);
816 /* Other informations
817 *---------------------------------------------------------------------------*/
819 /*static void
820 on_info_memory_activate (GtkAction * action, DebugManagerPlugin *plugin)
822 GtkWidget *win_memory;
824 win_memory = memory_info_new (plugin->debugger,
825 GTK_WINDOW (ANJUTA_PLUGIN (plugin)->shell),
826 NULL);
827 gtk_widget_show(win_memory);
830 static void
831 on_debugger_sharedlibs_activate (GtkAction * action, DebugManagerPlugin *plugin)
833 sharedlibs_show (plugin->sharedlibs);
836 static void
837 on_debugger_signals_activate (GtkAction * action, DebugManagerPlugin *plugin)
839 signals_show (plugin->signals);
842 static void
843 on_debugger_ready_signal (IAnjutaDebugger* dbg, IAnjutaDebuggerStatus stat, DebugManagerPlugin *plugin)
845 dma_plugin_debugger_ready (plugin, stat);
848 /* Actions table
849 *---------------------------------------------------------------------------*/
851 static GtkActionEntry actions_start[] =
854 "ActionMenuDebug", /* Action name */
855 NULL, /* Stock icon, if any */
856 N_("_Debug"), /* Display label */
857 NULL, /* short-cut */
858 NULL, /* Tooltip */
859 NULL /* action callback */
862 "ActionMenuStart",
863 "debugger-icon",
864 N_("_Start Debugger"),
865 NULL,
866 NULL,
867 NULL
870 "ActionDebuggerRunTarget",
871 NULL,
872 N_("Run Target..."),
873 "<shift>F12",
874 N_("load and start the target for debugging"),
875 G_CALLBACK (on_start_debug_activate)
878 "ActionDebuggerRestartTarget",
879 NULL,
880 N_("Restart Target"),
881 NULL,
882 N_("restart the same target for debugging"),
883 G_CALLBACK (on_restart_debug_activate)
886 "ActionDebuggerAttachProcess",
887 "debugger-detach",
888 N_("_Attach to Process..."),
889 NULL,
890 N_("Attach to a running program"),
891 G_CALLBACK (on_attach_to_project_action_activate)
894 "ActionDebuggerStop",
895 GTK_STOCK_STOP,
896 N_("Stop Debugger"),
897 NULL,
898 N_("Say goodbye to the debugger"),
899 G_CALLBACK (on_debugger_stop_activate)
903 static GtkActionEntry actions_loaded[] =
906 "ActionGdbCommand", /* Action name */
907 NULL, /* Stock icon, if any */
908 N_("Debugger Command..."), /* Display label */
909 NULL, /* short-cut */
910 N_("Custom debugger command"), /* Tooltip */
911 G_CALLBACK (on_debugger_custom_command_activate) /* action callback */
914 "ActionMenuGdbInformation",
915 NULL,
916 N_("_Info"),
917 NULL,
918 NULL,
919 NULL
922 "ActionGdbInfoTargetFiles",
923 NULL,
924 N_("Info _Target Files"),
925 NULL,
926 N_("Display information on the files the debugger is active with"),
927 G_CALLBACK (on_info_targets_activate)
930 "ActionGdbInfoProgram",
931 NULL,
932 N_("Info _Program"),
933 NULL,
934 N_("Display information on the execution status of the program"),
935 G_CALLBACK (on_info_program_activate)
938 "ActionGdbInfoKernelUserStruct",
939 NULL,
940 N_("Info _Kernel User Struct"),
941 NULL,
942 N_("Display the contents of kernel 'struct user' for current child"),
943 G_CALLBACK (on_info_udot_activate)
945 /* {
946 "ActionGdbExamineMemory",
947 NULL,
948 N_("Examine _Memory"),
949 NULL,
950 N_("Display accessible memory"),
951 G_CALLBACK (on_info_memory_activate)
952 },*/
954 "ActionGdbViewSharedlibs",
955 NULL,
956 N_("Shared Libraries"),
957 NULL,
958 N_("Show shared libraries mappings"),
959 G_CALLBACK (on_debugger_sharedlibs_activate)
962 "ActionGdbViewSignals",
963 NULL,
964 N_("Kernel Signals"),
965 NULL,
966 N_("Show kernel signals"),
967 G_CALLBACK (on_debugger_signals_activate)
971 static GtkActionEntry actions_stopped[] =
974 "ActionDebuggerRunContinue", /* Action name */
975 GTK_STOCK_EXECUTE, /* Stock icon, if any */
976 N_("Run/_Continue"), /* Display label */
977 "F4", /* short-cut */
978 N_("Continue the execution of the program"), /* Tooltip */
979 G_CALLBACK (on_run_continue_action_activate) /* action callback */
982 "ActionDebuggerStepIn",
983 "debugger-step-into",
984 N_("Step _In"),
985 "F5",
986 N_("Single step into function"),
987 G_CALLBACK (on_step_in_action_activate)
990 "ActionDebuggerStepOver",
991 "debugger-step-over",
992 N_("Step O_ver"),
993 "F6",
994 N_("Single step over function"),
995 G_CALLBACK (on_step_over_action_activate)
998 "ActionDebuggerStepOut",
999 "debugger-step-out",
1000 N_("Step _Out"),
1001 "F7",
1002 N_("Single step out of the function"),
1003 G_CALLBACK (on_step_out_action_activate)
1006 "ActionDebuggerRunToPosition",
1007 "debugger-run-to-cursor",
1008 N_("_Run to Cursor"),
1009 "F8",
1010 N_("Run to the cursor"),
1011 G_CALLBACK (on_run_to_cursor_action_activate)
1014 "ActionGdbCommand",
1015 NULL,
1016 N_("Debugger Command..."),
1017 NULL,
1018 N_("Custom debugger command"),
1019 G_CALLBACK (on_debugger_custom_command_activate)
1022 "ActionMenuGdbInformation",
1023 NULL,
1024 N_("_Info"),
1025 NULL,
1026 NULL,
1027 NULL
1030 "ActionGdbInfoGlobalVariables",
1031 NULL,
1032 N_("Info _Global Variables"),
1033 NULL,
1034 N_("Display all global and static variables of the program"),
1035 G_CALLBACK (on_info_variables_activate)
1038 "ActionGdbInfoCurrentFrame",
1039 NULL,
1040 N_("Info _Current Frame"),
1041 NULL,
1042 N_("Display information about the current frame of execution"),
1043 G_CALLBACK (on_info_frame_activate)
1046 "ActionGdbInfoFunctionArgs",
1047 NULL,
1048 N_("Info Function _Arguments"),
1049 NULL,
1050 N_("Display function arguments of the current frame"),
1051 G_CALLBACK (on_info_args_activate)
1054 "ActionGdbViewSharedlibs",
1055 NULL,
1056 N_("Shared Libraries"),
1057 NULL,
1058 N_("Show shared libraries mappings"),
1059 G_CALLBACK (on_debugger_sharedlibs_activate)
1062 "ActionGdbViewSignals",
1063 NULL,
1064 N_("Kernel Signals"),
1065 NULL,
1066 N_("Show kernel signals"),
1067 G_CALLBACK (on_debugger_signals_activate)
1071 static GtkActionEntry actions_running[] =
1074 "ActionGdbPauseProgram", /* Action name */
1075 GTK_STOCK_MEDIA_PAUSE, /* Stock icon, if any */
1076 N_("Pa_use Program"), /* Display label */
1077 NULL, /* short-cut */
1078 N_("Pauses the execution of the program"), /* Tooltip */
1079 G_CALLBACK (on_debugger_interrupt_activate) /* action callback */
1083 /* AnjutaPlugin functions
1084 *---------------------------------------------------------------------------*/
1086 static gboolean
1087 dma_plugin_activate (AnjutaPlugin* plugin)
1089 DebugManagerPlugin *this;
1090 static gboolean initialized = FALSE;
1091 AnjutaUI *ui;
1092 GtkAction *action;
1094 DEBUG_PRINT ("DebugManagerPlugin: Activating Debug Manager plugin...");
1095 this = ANJUTA_PLUGIN_DEBUG_MANAGER (plugin);
1097 if (!initialized)
1099 initialized = TRUE;
1100 register_stock_icons (ANJUTA_PLUGIN (plugin));
1103 /* Load debugger */
1104 this->queue = dma_debugger_queue_new (plugin);
1105 this->debugger = IANJUTA_DEBUGGER (this->queue);
1106 g_signal_connect_swapped (this->debugger, "debugger-started", G_CALLBACK (dma_plugin_debugger_started), this);
1107 g_signal_connect_swapped (this->debugger, "debugger-stopped", G_CALLBACK (dma_plugin_debugger_stopped), this);
1108 g_signal_connect_swapped (this->debugger, "program-loaded", G_CALLBACK (dma_plugin_program_loaded), this);
1109 g_signal_connect_swapped (this->debugger, "program-running", G_CALLBACK (dma_plugin_program_running), this);
1110 g_signal_connect_swapped (this->debugger, "program-stopped", G_CALLBACK (dma_plugin_program_stopped), this);
1111 g_signal_connect_swapped (this->debugger, "program-exited", G_CALLBACK (dma_plugin_program_loaded), this);
1112 g_signal_connect_swapped (this->debugger, "location-changed", G_CALLBACK (dma_plugin_location_changed), this);
1113 g_signal_connect_swapped (this->debugger, "signal-received", G_CALLBACK (dma_plugin_signal_received), this);
1114 g_signal_connect (this->debugger, "debugger-ready", G_CALLBACK (on_debugger_ready_signal), this);
1116 /* Add all our debug manager actions */
1117 ui = anjuta_shell_get_ui (ANJUTA_PLUGIN (plugin)->shell, NULL);
1118 this->start_group =
1119 anjuta_ui_add_action_group_entries (ui, "ActionGroupDebug",
1120 _("Debugger operations"),
1121 actions_start,
1122 G_N_ELEMENTS (actions_start),
1123 GETTEXT_PACKAGE, TRUE, this);
1124 this->loaded_group =
1125 anjuta_ui_add_action_group_entries (ui, "ActionGroupDebug",
1126 _("Debugger operations"),
1127 actions_loaded,
1128 G_N_ELEMENTS (actions_loaded),
1129 GETTEXT_PACKAGE, TRUE, this);
1130 this->stopped_group =
1131 anjuta_ui_add_action_group_entries (ui, "ActionGroupDebug",
1132 _("Debugger operations"),
1133 actions_stopped,
1134 G_N_ELEMENTS (actions_stopped),
1135 GETTEXT_PACKAGE, TRUE, this);
1136 this->running_group =
1137 anjuta_ui_add_action_group_entries (ui, "ActionGroupDebug",
1138 _("Debugger operations"),
1139 actions_running,
1140 G_N_ELEMENTS (actions_running),
1141 GETTEXT_PACKAGE, TRUE, this);
1142 this->uiid = anjuta_ui_merge (ui, UI_FILE);
1145 /* Watch expression */
1146 this->watch = expr_watch_new (ANJUTA_PLUGIN (plugin), this->debugger);
1148 /* Local window */
1149 this->locals = locals_new (ANJUTA_PLUGIN (plugin), this->debugger);
1151 /* Stack trace */
1152 this->stack = stack_trace_new (this->debugger, this);
1154 /* Thread list */
1155 this->thread = dma_threads_new (this->debugger, this);
1157 /* Create breakpoints list */
1158 this->breakpoints = breakpoints_dbase_new (this);
1160 /* Register list */
1161 this->registers = cpu_registers_new (plugin, this->debugger);
1163 /* Memory window */
1164 this->memory = dma_memory_new (plugin, this->debugger);
1166 /* Disassembly window */
1167 this->disassemble = dma_disassemble_new (plugin, this->debugger);
1169 /* Start debugger part */
1170 this->start = dma_start_new (plugin, this->debugger);
1173 dma_plugin_debugger_stopped (this, 0);
1174 action = gtk_action_group_get_action (this->start_group, "ActionDebuggerRestartTarget");
1175 gtk_action_set_sensitive (action, FALSE);
1177 /* Add watches */
1178 this->project_watch_id =
1179 anjuta_plugin_add_watch (plugin, "project_root_uri",
1180 value_added_project_root_uri,
1181 value_removed_project_root_uri, NULL);
1182 this->editor_watch_id =
1183 anjuta_plugin_add_watch (plugin, "document_manager_current_editor",
1184 value_added_current_editor,
1185 value_removed_current_editor, NULL);
1187 /* Connect to save session */
1188 g_signal_connect (G_OBJECT (plugin->shell), "save_session",
1189 G_CALLBACK (on_session_save), plugin);
1191 return TRUE;
1194 static gboolean
1195 dma_plugin_deactivate (AnjutaPlugin* plugin)
1197 DebugManagerPlugin *this;
1198 AnjutaUI *ui;
1200 DEBUG_PRINT ("DebugManagerPlugin: Deactivating Debug Manager plugin...");
1202 this = ANJUTA_PLUGIN_DEBUG_MANAGER (plugin);
1204 /* Stop debugger */
1205 dma_plugin_debugger_stopped (this, 0);
1207 g_signal_handlers_disconnect_by_func (this->queue, G_CALLBACK (dma_plugin_debugger_started), this);
1208 g_signal_handlers_disconnect_by_func (this->queue, G_CALLBACK (dma_plugin_debugger_stopped), this);
1209 g_signal_handlers_disconnect_by_func (this->queue, G_CALLBACK (dma_plugin_program_loaded), this);
1210 g_signal_handlers_disconnect_by_func (this->queue, G_CALLBACK (dma_plugin_program_running), this);
1211 g_signal_handlers_disconnect_by_func (this->queue, G_CALLBACK (dma_plugin_program_stopped), this);
1212 g_signal_handlers_disconnect_by_func (this->queue, G_CALLBACK (dma_plugin_location_changed), this);
1213 g_signal_handlers_disconnect_by_func (this->queue, G_CALLBACK (on_debugger_ready_signal), this);
1214 dma_debugger_queue_free (this->queue);
1215 this->queue = NULL;
1217 ui = anjuta_shell_get_ui (plugin->shell, NULL);
1218 anjuta_ui_unmerge (ui, this->uiid);
1220 expr_watch_destroy (this->watch);
1221 this->watch = NULL;
1223 breakpoints_dbase_destroy (this->breakpoints);
1224 this->breakpoints = NULL;
1226 locals_free (this->locals);
1227 this->locals = NULL;
1229 stack_trace_free (this->stack);
1230 this->stack = NULL;
1232 cpu_registers_free (this->registers);
1233 this->registers = NULL;
1235 dma_memory_free (this->memory);
1236 this->memory = NULL;
1238 dma_disassemble_free (this->disassemble);
1239 this->disassemble = NULL;
1241 dma_threads_free (this->thread);
1242 this->thread = NULL;
1244 dma_start_free (this->start);
1245 this->start = NULL;
1247 ui = anjuta_shell_get_ui (ANJUTA_PLUGIN (this)->shell, NULL);
1248 anjuta_ui_remove_action_group (ui, this->start_group);
1249 anjuta_ui_remove_action_group (ui, this->loaded_group);
1250 anjuta_ui_remove_action_group (ui, this->stopped_group);
1251 anjuta_ui_remove_action_group (ui, this->running_group);
1253 if (this->view != NULL)
1255 g_object_remove_weak_pointer (G_OBJECT (this->view), (gpointer*)&this->view);
1256 this->view = NULL;
1259 return TRUE;
1262 /* Public functions
1263 *---------------------------------------------------------------------------*/
1265 void
1266 dma_debug_manager_goto_code (DebugManagerPlugin *self, const gchar *uri, guint line, guint address)
1268 /* Go to address in disassembly view */
1269 if (address != 0)
1271 dma_disassemble_goto_address (self->disassemble, address);
1274 /* Go to location in editor */
1275 if (uri != NULL)
1277 goto_location_in_editor (ANJUTA_PLUGIN (self), uri, line);
1282 /* GObject functions
1283 *---------------------------------------------------------------------------*/
1285 /* Used in dispose and finalize */
1286 static gpointer parent_class;
1288 /* instance_init is the constructor. All functions should work after this
1289 * call. */
1291 static void
1292 dma_plugin_instance_init (GObject* obj)
1294 DebugManagerPlugin *plugin = ANJUTA_PLUGIN_DEBUG_MANAGER (obj);
1296 plugin->uiid = 0;
1298 plugin->project_root_uri = NULL;
1299 plugin->debugger = NULL;
1300 plugin->current_editor = NULL;
1301 plugin->pc_editor = NULL;
1302 plugin->editor_watch_id = 0;
1303 plugin->project_watch_id = 0;
1304 plugin->breakpoints = NULL;
1305 plugin->watch = NULL;
1306 plugin->locals = NULL;
1307 plugin->registers = NULL;
1308 plugin->signals = NULL;
1309 plugin->sharedlibs = NULL;
1310 plugin->view = NULL;
1312 /* plugin->uri = NULL; */
1315 /* dispose is the first destruction step. It is used to unref object created
1316 * with instance_init in order to break reference counting cycles. This
1317 * function could be called several times. All function should still work
1318 * after this call. It has to called its parents.*/
1320 static void
1321 dma_plugin_dispose (GObject* obj)
1323 GNOME_CALL_PARENT (G_OBJECT_CLASS, dispose, (G_OBJECT (obj)));
1326 /* finalize is the last destruction step. It must free all memory allocated
1327 * with instance_init. It is called only one time just before releasing all
1328 * memory */
1330 static void
1331 dma_plugin_finalize (GObject* obj)
1333 DebugManagerPlugin *self = ANJUTA_PLUGIN_DEBUG_MANAGER (obj);
1335 if (self->pc_editor != NULL)
1337 g_object_remove_weak_pointer (G_OBJECT (self->pc_editor), (gpointer *)&self->pc_editor);
1339 if (self->current_editor != NULL)
1341 g_object_remove_weak_pointer (G_OBJECT (self->current_editor), (gpointer *)&self->current_editor);
1344 GNOME_CALL_PARENT (G_OBJECT_CLASS, finalize, (G_OBJECT (obj)));
1347 /* class_init intialize the class itself not the instance */
1349 static void
1350 dma_plugin_class_init (GObjectClass* klass)
1352 AnjutaPluginClass *plugin_class = ANJUTA_PLUGIN_CLASS (klass);
1354 parent_class = g_type_class_peek_parent (klass);
1356 plugin_class->activate = dma_plugin_activate;
1357 plugin_class->deactivate = dma_plugin_deactivate;
1358 klass->dispose = dma_plugin_dispose;
1359 klass->finalize = dma_plugin_finalize;
1362 /* Implementation of IAnjutaDebugManager interface
1363 *---------------------------------------------------------------------------*/
1365 static void
1366 idebug_manager_iface_init (IAnjutaDebugManagerIface *iface)
1370 ANJUTA_PLUGIN_BEGIN (DebugManagerPlugin, dma_plugin);
1371 ANJUTA_PLUGIN_ADD_INTERFACE(idebug_manager, IANJUTA_TYPE_DEBUG_MANAGER);
1372 ANJUTA_PLUGIN_END;
1374 ANJUTA_SIMPLE_PLUGIN (DebugManagerPlugin, dma_plugin);