1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
4 Copyright (C) 2005 Sébastien Granjoux
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
22 * Keep all debugger commands in a queue and send them one by one to the
23 * debugger (implementing IAnjutaDebugger).
24 *---------------------------------------------------------------------------*/
31 #include <libanjuta/anjuta-debug.h>
32 #include <libanjuta/interfaces/ianjuta-message-manager.h>
33 #include <libanjuta/interfaces/ianjuta-cpu-debugger.h>
34 #include <libanjuta/interfaces/ianjuta-debugger-breakpoint.h>
35 #include <libanjuta/interfaces/ianjuta-debugger-variable.h>
41 *---------------------------------------------------------------------------*/
43 #define ICON_FILE "anjuta-debug-manager.plugin.png"
46 *---------------------------------------------------------------------------*/
48 struct _DmaDebuggerQueue
{
52 IAnjutaDebugger
* debugger
;
57 DmaQueueCommand
*last
;
60 IAnjutaDebuggerState debugger_state
;
61 IAnjutaDebuggerState queue_state
;
62 gboolean stop_on_sharedlib
;
64 /* View for debugger messages */
65 IAnjutaMessageView
* log
;
70 struct _DmaDebuggerQueueClass
{
75 *---------------------------------------------------------------------------*/
78 *---------------------------------------------------------------------------*/
81 dma_queue_cancel (DmaDebuggerQueue
*self
, DmaCommandFlag flag
)
83 GList
* node
= g_queue_peek_head_link(self
->queue
);
85 /* Cancel all commands in queue with the flag */
88 GList
* next
= g_list_next (node
);
89 DmaQueueCommand
* cmd
= (DmaQueueCommand
*)node
->data
;
91 if (dma_command_has_flag (cmd
, flag
))
93 dma_command_cancel (cmd
);
94 g_queue_delete_link (self
->queue
, node
);
100 /* Cancel all commands those cannot handle this unexpected state
101 * Return TRUE if the state of the queue need to be changed too
105 dma_queue_cancel_unexpected (DmaDebuggerQueue
*self
, IAnjutaDebuggerState state
)
107 GList
* node
= g_queue_peek_head_link(self
->queue
);
109 /* IANJUTA_DEBUGGER_BUSY is used as a do nothing marker*/
110 if (state
== IANJUTA_DEBUGGER_BUSY
) return FALSE
;
112 /* Cancel all commands in queue with the flag */
115 GList
* next
= g_list_next (node
);
116 DmaQueueCommand
* cmd
= (DmaQueueCommand
*)node
->data
;
118 if (!dma_command_is_valid_in_state(cmd
, state
))
120 /* Command is not allowed in this state, cancel it */
121 dma_command_cancel (cmd
);
122 g_queue_delete_link (self
->queue
, node
);
124 else if (dma_command_is_going_to_state (cmd
) != IANJUTA_DEBUGGER_BUSY
)
126 /* A command setting the state is kept,
127 debugger state is known again afterward, queue state is kept too */
133 /* End in this unexpected state */
134 self
->queue_state
= state
;
140 dma_debugger_queue_clear (DmaDebuggerQueue
*self
)
142 g_queue_foreach (self
->queue
, (GFunc
)dma_command_free
, NULL
);
143 /* Do not use g_queue_clear yet as it is defined only in GLib 2.14 */
144 while (g_queue_pop_head(self
->queue
) != NULL
);
145 if (self
->last
!= NULL
)
147 DEBUG_PRINT("clear command %x", dma_command_get_type (self
->last
));
148 dma_command_free (self
->last
);
152 /* Queue is empty so has the same state than debugger */
153 self
->queue_state
= self
->debugger_state
;
155 self
->prepend_command
= 0;
159 dma_queue_emit_debugger_state (DmaDebuggerQueue
*self
, IAnjutaDebuggerState state
, GError
* err
)
164 DEBUGGER_STOPPED_SIGNAL
,
165 DEBUGGER_STARTED_SIGNAL
,
166 PROGRAM_LOADED_SIGNAL
,
167 PROGRAM_UNLOADED_SIGNAL
,
168 PROGRAM_STARTED_SIGNAL
,
169 PROGRAM_EXITED_SIGNAL
,
170 PROGRAM_RUNNING_SIGNAL
,
171 PROGRAM_STOPPED_SIGNAL
172 } signal
= NO_SIGNAL
;
173 gboolean emit_program_started
= FALSE
;
175 DEBUG_PRINT("update debugger state new %d old %d", state
, self
->debugger_state
);
177 /* Add missing state if useful */
180 case IANJUTA_DEBUGGER_STOPPED
:
181 if ((self
->debugger_state
== IANJUTA_DEBUGGER_PROGRAM_RUNNING
) ||
182 (self
->debugger_state
== IANJUTA_DEBUGGER_PROGRAM_STOPPED
))
184 dma_queue_emit_debugger_state (self
, IANJUTA_DEBUGGER_PROGRAM_LOADED
, NULL
);
186 else if (self
->debugger_state
== IANJUTA_DEBUGGER_PROGRAM_LOADED
)
188 dma_queue_emit_debugger_state (self
, IANJUTA_DEBUGGER_STARTED
, NULL
);
191 case IANJUTA_DEBUGGER_STARTED
:
192 if ((self
->debugger_state
== IANJUTA_DEBUGGER_PROGRAM_RUNNING
) ||
193 (self
->debugger_state
== IANJUTA_DEBUGGER_PROGRAM_STOPPED
))
195 dma_queue_emit_debugger_state (self
, IANJUTA_DEBUGGER_PROGRAM_LOADED
, NULL
);
198 case IANJUTA_DEBUGGER_PROGRAM_LOADED
:
199 if (self
->debugger_state
== IANJUTA_DEBUGGER_STOPPED
)
201 dma_queue_emit_debugger_state (self
, IANJUTA_DEBUGGER_STARTED
, NULL
);
204 case IANJUTA_DEBUGGER_PROGRAM_STOPPED
:
205 if (self
->debugger_state
== IANJUTA_DEBUGGER_STOPPED
)
207 dma_queue_emit_debugger_state (self
, IANJUTA_DEBUGGER_STARTED
, NULL
);
209 else if (self
->debugger_state
== IANJUTA_DEBUGGER_STARTED
)
211 dma_queue_emit_debugger_state (self
, IANJUTA_DEBUGGER_PROGRAM_LOADED
, NULL
);
214 case IANJUTA_DEBUGGER_PROGRAM_RUNNING
:
215 if (self
->debugger_state
== IANJUTA_DEBUGGER_STOPPED
)
217 dma_queue_emit_debugger_state (self
, IANJUTA_DEBUGGER_STARTED
, NULL
);
219 else if (self
->debugger_state
== IANJUTA_DEBUGGER_STARTED
)
221 dma_queue_emit_debugger_state (self
, IANJUTA_DEBUGGER_PROGRAM_LOADED
, NULL
);
224 case IANJUTA_DEBUGGER_BUSY
:
228 if (self
->debugger_state
!= state
)
232 case IANJUTA_DEBUGGER_BUSY
:
233 /* Debugger is busy, nothing to do */
235 case IANJUTA_DEBUGGER_STOPPED
:
236 self
->stop_on_sharedlib
= FALSE
;
237 signal
= DEBUGGER_STOPPED_SIGNAL
;
238 self
->debugger_state
= state
;
240 case IANJUTA_DEBUGGER_STARTED
:
241 self
->stop_on_sharedlib
= FALSE
;
242 signal
= self
->debugger_state
< IANJUTA_DEBUGGER_STARTED
? DEBUGGER_STARTED_SIGNAL
: PROGRAM_UNLOADED_SIGNAL
;
243 self
->debugger_state
= state
;
245 case IANJUTA_DEBUGGER_PROGRAM_LOADED
:
246 self
->stop_on_sharedlib
= FALSE
;
247 signal
= self
->debugger_state
< IANJUTA_DEBUGGER_PROGRAM_LOADED
? PROGRAM_LOADED_SIGNAL
: PROGRAM_EXITED_SIGNAL
;
248 self
->debugger_state
= state
;
250 case IANJUTA_DEBUGGER_PROGRAM_STOPPED
:
251 if (!self
->stop_on_sharedlib
)
253 emit_program_started
= self
->debugger_state
< IANJUTA_DEBUGGER_PROGRAM_STOPPED
;
254 signal
= PROGRAM_STOPPED_SIGNAL
;
256 else if (self
->debugger_state
< IANJUTA_DEBUGGER_PROGRAM_STOPPED
)
258 signal
= PROGRAM_STARTED_SIGNAL
;
260 self
->debugger_state
= state
;
262 case IANJUTA_DEBUGGER_PROGRAM_RUNNING
:
263 emit_program_started
= self
->debugger_state
< IANJUTA_DEBUGGER_PROGRAM_STOPPED
;
264 self
->stop_on_sharedlib
= FALSE
;
265 signal
= PROGRAM_RUNNING_SIGNAL
;
266 self
->debugger_state
= state
;
271 self
->prepend_command
++;
278 case DEBUGGER_STOPPED_SIGNAL
:
279 DEBUG_PRINT("** emit debugger-stopped **");
280 g_signal_emit_by_name (self
->plugin
, "debugger-stopped", err
);
282 case DEBUGGER_STARTED_SIGNAL
:
283 DEBUG_PRINT("** emit debugger-started **");
284 g_signal_emit_by_name (self
->plugin
, "debugger-started");
286 case PROGRAM_LOADED_SIGNAL
:
287 DEBUG_PRINT("** emit program-loaded **");
288 g_signal_emit_by_name (self
->plugin
, "program-loaded");
290 case PROGRAM_UNLOADED_SIGNAL
:
291 DEBUG_PRINT("** emit program-unloaded **");
292 g_signal_emit_by_name (self
->plugin
, "program-unloaded");
294 case PROGRAM_STARTED_SIGNAL
:
295 DEBUG_PRINT("** emit program-started **");
296 g_signal_emit_by_name (self
->plugin
, "program-started");
298 case PROGRAM_EXITED_SIGNAL
:
299 DEBUG_PRINT("** emit program-exited **");
300 g_signal_emit_by_name (self
->plugin
, "program-exited");
302 case PROGRAM_STOPPED_SIGNAL
:
303 DEBUG_PRINT("** emit program-exited **");
304 if (emit_program_started
)
306 DEBUG_PRINT("** emit program-started **");
307 g_signal_emit_by_name (self
->plugin
, "program-started");
309 DEBUG_PRINT("** emit program-stopped **");
310 g_signal_emit_by_name (self
->plugin
, "program-stopped");
312 case PROGRAM_RUNNING_SIGNAL
:
313 if (emit_program_started
)
315 DEBUG_PRINT("** emit program-started **");
316 g_signal_emit_by_name (self
->plugin
, "program-started");
318 DEBUG_PRINT("** emit program-running **");
319 g_signal_emit_by_name (self
->plugin
, "program-running");
322 self
->prepend_command
--;
326 dma_queue_emit_debugger_ready (DmaDebuggerQueue
*self
)
330 if (g_queue_is_empty(self
->queue
) && (self
->last
== NULL
))
339 if (busy
!= self
->busy
)
341 AnjutaStatus
* status
;
343 status
= anjuta_shell_get_status(ANJUTA_PLUGIN (self
->plugin
)->shell
, NULL
);
346 anjuta_status_busy_push (status
);
351 anjuta_status_busy_pop (status
);
357 static void dma_debugger_queue_execute (DmaDebuggerQueue
*self
);
359 /* Call when debugger has completed the current command */
362 dma_debugger_queue_complete (DmaDebuggerQueue
*self
, IAnjutaDebuggerState state
)
364 DEBUG_PRINT("debugger_queue_complete %d", state
);
366 if (state
!= IANJUTA_DEBUGGER_BUSY
)
368 if (self
->last
!= NULL
)
370 if (dma_command_is_going_to_state (self
->last
) != state
)
372 /* Command end in an unexpected state,
373 * Remove invalid following command */
374 dma_queue_cancel_unexpected (self
, state
);
377 /* Remove current command */
378 DEBUG_PRINT("end command %x", dma_command_get_type (self
->last
));
379 dma_command_free (self
->last
);
384 /* Emit new state if necessary */
385 dma_queue_emit_debugger_state (self
, state
, NULL
);
387 /* Send next command */
388 dma_debugger_queue_execute (self
);
392 /* Call to send next command */
395 dma_debugger_queue_execute (DmaDebuggerQueue
*self
)
397 DEBUG_PRINT("debugger_queue_execute");
399 /* Check if debugger is connected to a debugger backend */
400 g_return_if_fail (self
->debugger
!= NULL
);
402 /* Check if there debugger is busy */
403 if (self
->last
!= NULL
)
405 IAnjutaDebuggerState state
;
406 /* Recheck state in case of desynchronization */
407 state
= ianjuta_debugger_get_state (self
->debugger
, NULL
);
408 dma_debugger_queue_complete (self
, state
);
411 /* Check if there is something to execute */
412 while (!g_queue_is_empty(self
->queue
) && (self
->last
== NULL
))
414 DmaQueueCommand
*cmd
;
418 cmd
= (DmaQueueCommand
*)g_queue_pop_head(self
->queue
);
422 DEBUG_PRINT("run command %x", dma_command_get_type (cmd
));
423 ok
= dma_command_run (cmd
, self
->debugger
, self
, &err
);
425 if (!ok
|| (err
!= NULL
))
428 if (dma_command_is_going_to_state (self
->last
) != IANJUTA_DEBUGGER_BUSY
)
430 /* Command has been canceled in an unexpected state,
431 * Remove invalid following command */
432 dma_queue_cancel_unexpected (self
, self
->debugger_state
);
435 /* Remove current command */
436 DEBUG_PRINT("cancel command %x", dma_command_get_type (self
->last
));
437 dma_command_free (self
->last
);
440 /* Display error message to user */
443 if (err
->message
!= NULL
)
445 anjuta_util_dialog_error (GTK_WINDOW (ANJUTA_PLUGIN (self
->plugin
)->shell
), err
->message
);
453 dma_queue_emit_debugger_ready (self
);
457 dma_queue_check_state (DmaDebuggerQueue
*self
, DmaQueueCommand
* cmd
)
461 for (recheck
= FALSE
; recheck
!= TRUE
; recheck
= TRUE
)
463 IAnjutaDebuggerState state
;
465 if (self
->prepend_command
)
467 /* Prepend command use debugger state or current command state */
468 if (self
->last
!= NULL
)
470 state
= dma_command_is_going_to_state (self
->last
);
471 if (state
== IANJUTA_DEBUGGER_BUSY
)
473 state
= self
->debugger_state
;
478 state
= self
->debugger_state
;
483 /* Append command use queue state */
484 state
= self
->queue_state
;
487 /* Only the debugger can be busy */
488 g_return_val_if_fail (state
!= IANJUTA_DEBUGGER_BUSY
, FALSE
);
490 if (dma_command_is_valid_in_state (cmd
, state
))
496 g_warning ("Cancel command %x, debugger in state %d", dma_command_get_type (cmd
), state
);
498 /* Check if synchronization is still ok */
499 state
= ianjuta_debugger_get_state (self
->debugger
, NULL
);
500 dma_debugger_queue_complete (self
, state
);
509 dma_debugger_activate_plugin (DmaDebuggerQueue
* self
, const gchar
*mime_type
)
511 AnjutaPluginManager
*plugin_manager
;
512 AnjutaPluginDescription
*plugin
;
516 /* Get list of debugger plugins */
517 plugin_manager
= anjuta_shell_get_plugin_manager (ANJUTA_PLUGIN(self
->plugin
)->shell
, NULL
);
518 if (mime_type
== NULL
)
520 /* User has to select the right debugger */
521 descs
= anjuta_plugin_manager_query (plugin_manager
,
522 "Anjuta Plugin","Interfaces", "IAnjutaDebugger", NULL
);
526 /* Propose only debugger supporting correct mime type */
527 descs
= anjuta_plugin_manager_query (plugin_manager
,
528 "Anjuta Plugin","Interfaces", "IAnjutaDebugger",
529 "File Loader", "SupportedMimeTypes", mime_type
,
535 /* No plugin found */
536 anjuta_util_dialog_error (GTK_WINDOW (ANJUTA_PLUGIN (self
->plugin
)->shell
),
537 _("Unable to find one debugger plugin acception %s mime type"), mime_type
);
541 else if (g_list_length (descs
) == 1)
543 /* Only one plugin found, use it */
544 plugin
= (AnjutaPluginDescription
*)descs
->data
;
548 /* Ask the user to select one plugin */
549 plugin
= anjuta_plugin_manager_select (plugin_manager
,
550 _("Select a plugin"),
551 _("Please select a plugin to activate"),
557 /* Get debugger location */
559 anjuta_plugin_description_get_string (plugin
, "Anjuta Plugin", "Location", &value
);
560 g_return_val_if_fail (value
!= NULL
, FALSE
);
562 /* Get debugger interface */
563 self
->debugger
= (IAnjutaDebugger
*)anjuta_plugin_manager_get_plugin_by_id (plugin_manager
, value
);
566 /* Check if cpu interface is available */
567 self
->support
|= IANJUTA_IS_CPU_DEBUGGER(self
->debugger
) ? HAS_CPU
: 0;
568 /* Check if breakpoint interface is available */
569 self
->support
|= IANJUTA_IS_DEBUGGER_BREAKPOINT(self
->debugger
) ? HAS_BREAKPOINT
: 0;
570 if (IANJUTA_IS_DEBUGGER_BREAKPOINT (self
->debugger
))
572 self
->support
|= ianjuta_debugger_breakpoint_implement (IANJUTA_DEBUGGER_BREAKPOINT (self
->debugger
), NULL
) * HAS_BREAKPOINT
* 2;
574 /* Check if variable interface is available */
575 self
->support
|= IANJUTA_IS_DEBUGGER_VARIABLE(self
->debugger
) ? HAS_VARIABLE
: 0;
583 /* No plugin selected */
589 /* IAnjutaDebugger callback
590 *---------------------------------------------------------------------------*/
593 on_dma_debugger_ready (DmaDebuggerQueue
*self
, IAnjutaDebuggerState state
)
595 DEBUG_PRINT ("From debugger: receive debugger ready %d", state
);
597 dma_debugger_queue_complete (self
, state
);
601 on_dma_debugger_started (DmaDebuggerQueue
*self
)
603 DEBUG_PRINT ("From debugger: receive debugger started");
604 dma_queue_emit_debugger_state (self
, IANJUTA_DEBUGGER_STARTED
, NULL
);
608 on_dma_debugger_stopped (DmaDebuggerQueue
*self
, GError
*err
)
610 IAnjutaDebuggerState state
;
612 DEBUG_PRINT ("From debugger: receive debugger stopped with error %p", err
);
613 dma_queue_emit_debugger_state (self
, IANJUTA_DEBUGGER_STOPPED
, err
);
615 /* Reread debugger state, could have changed while emitting signal */
616 state
= ianjuta_debugger_get_state (self
->debugger
, NULL
);
617 dma_debugger_queue_complete (self
, state
);
621 on_dma_program_loaded (DmaDebuggerQueue
*self
)
623 DEBUG_PRINT ("From debugger: receive program loaded");
624 dma_queue_emit_debugger_state (self
, IANJUTA_DEBUGGER_PROGRAM_LOADED
, NULL
);
628 on_dma_program_running (DmaDebuggerQueue
*self
)
630 DEBUG_PRINT ("From debugger: debugger_program_running");
631 dma_queue_emit_debugger_state (self
, IANJUTA_DEBUGGER_PROGRAM_RUNNING
, NULL
);
635 on_dma_program_stopped (DmaDebuggerQueue
*self
)
637 DEBUG_PRINT ("From debugger: receive program stopped");
638 dma_queue_emit_debugger_state (self
, IANJUTA_DEBUGGER_PROGRAM_STOPPED
, NULL
);
642 on_dma_program_exited (DmaDebuggerQueue
*self
)
644 DEBUG_PRINT ("From debugger: receive program exited");
645 dma_queue_emit_debugger_state (self
, IANJUTA_DEBUGGER_PROGRAM_LOADED
, NULL
);
649 on_dma_program_moved (DmaDebuggerQueue
*self
, guint pid
, gint tid
, guint address
, const gchar
* src_path
, guint line
)
651 DEBUG_PRINT ("From debugger: program moved");
652 self
->prepend_command
++;
653 g_signal_emit_by_name (self
->plugin
, "program-moved", pid
, tid
, address
, src_path
, line
);
654 self
->prepend_command
--;
658 on_dma_frame_changed (DmaDebuggerQueue
*self
, guint frame
, gint thread
)
660 DEBUG_PRINT ("From debugger: frame changed");
661 self
->prepend_command
++;
662 g_signal_emit_by_name (self
->plugin
, "frame-changed", frame
, thread
);
663 self
->prepend_command
--;
667 on_dma_signal_received (DmaDebuggerQueue
*self
, const gchar
* name
, const gchar
* description
)
669 DEBUG_PRINT ("From debugger: signal received");
670 self
->prepend_command
++;
671 g_signal_emit_by_name (self
->plugin
, "signal-received", name
, description
);
672 self
->prepend_command
--;
676 on_dma_sharedlib_event (DmaDebuggerQueue
*self
)
678 DEBUG_PRINT ("From debugger: shared lib event");
679 self
->stop_on_sharedlib
= TRUE
;
680 dma_debugger_queue_complete (self
, IANJUTA_DEBUGGER_PROGRAM_STOPPED
);
681 self
->prepend_command
++;
682 g_signal_emit_by_name (self
->plugin
, "sharedlib-event");
683 self
->prepend_command
--;
684 dma_queue_run (self
);
688 *---------------------------------------------------------------------------*/
690 /* Command callback will add their commands at the beginning of the queue */
692 dma_debugger_queue_command_callback (const gpointer data
, gpointer user_data
, GError
* err
)
694 DmaDebuggerQueue
*self
= (DmaDebuggerQueue
*)user_data
;
696 g_return_if_fail (self
->last
!= NULL
);
698 self
->prepend_command
++;
699 dma_command_callback (self
->last
, data
, err
);
700 self
->prepend_command
--;
704 dma_debugger_queue_append (DmaDebuggerQueue
*self
, DmaQueueCommand
*cmd
)
706 DEBUG_PRINT("append cmd %x prepend %d", dma_command_get_type (cmd
), self
->prepend_command
);
707 DEBUG_PRINT("current %x", self
->last
== NULL
? 0 : dma_command_get_type (self
->last
));
708 DEBUG_PRINT("queue %x", self
->queue
->head
== NULL
? 0 : dma_command_get_type (self
->queue
->head
->data
));
710 if ((self
->debugger
!= NULL
) && dma_queue_check_state(self
, cmd
))
712 /* If command is asynchronous stop current command */
713 if (dma_command_has_flag (cmd
, ASYNCHRONOUS
))
715 IAnjutaDebuggerState state
;
717 state
= dma_command_is_going_to_state (cmd
);
718 if (state
!= IANJUTA_DEBUGGER_BUSY
)
720 /* Command is changing debugger state */
721 dma_queue_cancel_unexpected (self
, state
);
724 /* Append command at the beginning */
725 g_queue_push_head (self
->queue
, cmd
);
727 dma_debugger_queue_complete (self
, self
->debugger_state
);
729 else if (self
->prepend_command
== 0)
731 /* Append command at the end (in the queue) */
732 IAnjutaDebuggerState state
;
734 g_queue_push_tail (self
->queue
, cmd
);
736 state
= dma_command_is_going_to_state (cmd
);
737 if (state
!= IANJUTA_DEBUGGER_BUSY
)
739 self
->queue_state
= state
;
744 /* Prepend command at the beginning */
745 g_queue_push_head (self
->queue
, cmd
);
748 dma_debugger_queue_execute(self
);
754 dma_command_free (cmd
);
761 dma_debugger_queue_stop (DmaDebuggerQueue
*self
)
763 /* Disconnect signal */
766 g_signal_handlers_disconnect_by_func (self
->debugger
, G_CALLBACK (on_dma_debugger_ready
), self
);
767 g_signal_handlers_disconnect_by_func (self
->debugger
, G_CALLBACK (on_dma_debugger_started
), self
);
768 g_signal_handlers_disconnect_by_func (self
->debugger
, G_CALLBACK (on_dma_debugger_stopped
), self
);
769 g_signal_handlers_disconnect_by_func (self
->debugger
, G_CALLBACK (on_dma_program_loaded
), self
);
770 g_signal_handlers_disconnect_by_func (self
->debugger
, G_CALLBACK (on_dma_program_running
), self
);
771 g_signal_handlers_disconnect_by_func (self
->debugger
, G_CALLBACK (on_dma_program_stopped
), self
);
772 g_signal_handlers_disconnect_by_func (self
->debugger
, G_CALLBACK (on_dma_program_exited
), self
);
773 g_signal_handlers_disconnect_by_func (self
->debugger
, G_CALLBACK (on_dma_program_moved
), self
);
774 g_signal_handlers_disconnect_by_func (self
->debugger
, G_CALLBACK (on_dma_signal_received
), self
);
775 g_signal_handlers_disconnect_by_func (self
->debugger
, G_CALLBACK (on_dma_frame_changed
), self
);
776 g_signal_handlers_disconnect_by_func (self
->debugger
, G_CALLBACK (on_dma_sharedlib_event
), self
);
777 self
->debugger
= NULL
;
783 dma_debugger_queue_start (DmaDebuggerQueue
*self
, const gchar
*mime_type
)
785 dma_debugger_queue_stop (self
);
787 /* Look for a debugger supporting mime_type */
788 if (!dma_debugger_activate_plugin (self
, mime_type
))
796 g_signal_connect_swapped (self
->debugger
, "debugger-ready", G_CALLBACK (on_dma_debugger_ready
), self
);
797 g_signal_connect_swapped (self
->debugger
, "debugger-started", G_CALLBACK (on_dma_debugger_started
), self
);
798 g_signal_connect_swapped (self
->debugger
, "debugger-stopped", G_CALLBACK (on_dma_debugger_stopped
), self
);
799 g_signal_connect_swapped (self
->debugger
, "program-loaded", G_CALLBACK (on_dma_program_loaded
), self
);
800 g_signal_connect_swapped (self
->debugger
, "program-running", G_CALLBACK (on_dma_program_running
), self
);
801 g_signal_connect_swapped (self
->debugger
, "program-stopped", G_CALLBACK (on_dma_program_stopped
), self
);
802 g_signal_connect_swapped (self
->debugger
, "program-exited", G_CALLBACK (on_dma_program_exited
), self
);
803 g_signal_connect_swapped (self
->debugger
, "program-moved", G_CALLBACK (on_dma_program_moved
), self
);
804 g_signal_connect_swapped (self
->debugger
, "signal-received", G_CALLBACK (on_dma_signal_received
), self
);
805 g_signal_connect_swapped (self
->debugger
, "frame-changed", G_CALLBACK (on_dma_frame_changed
), self
);
806 g_signal_connect_swapped (self
->debugger
, "sharedlib-event", G_CALLBACK (on_dma_sharedlib_event
), self
);
808 if (self
->log
== NULL
)
810 dma_queue_disable_log (self
);
814 dma_queue_enable_log (self
, self
->log
);
818 return self
->debugger
!= NULL
;
822 dma_queue_enable_log (DmaDebuggerQueue
*self
, IAnjutaMessageView
*log
)
825 if (self
->debugger
!= NULL
)
827 ianjuta_debugger_enable_log (self
->debugger
, self
->log
, NULL
);
832 dma_queue_disable_log (DmaDebuggerQueue
*self
)
835 if (self
->debugger
!= NULL
)
837 ianjuta_debugger_disable_log (self
->debugger
, NULL
);
842 dma_debugger_queue_get_state (DmaDebuggerQueue
*self
)
844 return self
->queue_state
;
848 dma_debugger_queue_is_supported (DmaDebuggerQueue
*self
, DmaDebuggerCapability capability
)
850 return self
->support
& capability
? TRUE
: FALSE
;
854 *---------------------------------------------------------------------------*/
856 /* Used in dispose and finalize */
857 static gpointer parent_class
;
859 /* dispose is the first destruction step. It is used to unref object created
860 * with instance_init in order to break reference counting cycles. This
861 * function could be called several times. All function should still work
862 * after this call. It has to called its parents.*/
865 dma_debugger_queue_dispose (GObject
*obj
)
867 DmaDebuggerQueue
*self
= DMA_DEBUGGER_QUEUE (obj
);
869 dma_debugger_queue_clear (self
);
871 GNOME_CALL_PARENT (G_OBJECT_CLASS
, dispose
, (obj
));
874 /* finalize is the last destruction step. It must free all memory allocated
875 * with instance_init. It is called only one time just before releasing all
879 dma_debugger_queue_finalize (GObject
*obj
)
881 /*DmaDebuggerQueue *self = DMA_DEBUGGER_QUEUE (obj);*/
883 GNOME_CALL_PARENT (G_OBJECT_CLASS
, finalize
, (obj
));
886 /* instance_init is the constructor. All functions should work after this
890 dma_debugger_queue_instance_init (DmaDebuggerQueue
*self
)
893 self
->debugger
= NULL
;
895 self
->queue
= g_queue_new ();
898 self
->prepend_command
= 0;
899 self
->debugger_state
= IANJUTA_DEBUGGER_STOPPED
;
900 self
->queue_state
= IANJUTA_DEBUGGER_STOPPED
;
904 /* class_init intialize the class itself not the instance */
907 dma_debugger_queue_class_init (DmaDebuggerQueueClass
* klass
)
909 GObjectClass
*object_class
;
911 g_return_if_fail (klass
!= NULL
);
912 object_class
= G_OBJECT_CLASS (klass
);
914 parent_class
= g_type_class_peek_parent (klass
);
916 object_class
->dispose
= dma_debugger_queue_dispose
;
917 object_class
->finalize
= dma_debugger_queue_finalize
;
921 dma_debugger_queue_get_type (void)
923 static GType type
= 0;
927 static const GTypeInfo type_info
=
929 sizeof (DmaDebuggerQueueClass
),
930 (GBaseInitFunc
) NULL
,
931 (GBaseFinalizeFunc
) NULL
,
932 (GClassInitFunc
) dma_debugger_queue_class_init
,
933 (GClassFinalizeFunc
) NULL
,
934 NULL
, /* class_data */
935 sizeof (DmaDebuggerQueue
),
937 (GInstanceInitFunc
) dma_debugger_queue_instance_init
,
938 NULL
/* value_table */
941 type
= g_type_register_static (G_TYPE_OBJECT
,
942 "DmaDebuggerQueue", &type_info
, 0);
948 /* Creation and Destruction
949 *---------------------------------------------------------------------------*/
952 dma_debugger_queue_new (AnjutaPlugin
*plugin
)
954 DmaDebuggerQueue
*self
;
956 self
= g_object_new (DMA_DEBUGGER_QUEUE_TYPE
, NULL
);
957 self
->plugin
= plugin
;
963 dma_debugger_queue_free (DmaDebuggerQueue
*self
)
965 dma_debugger_queue_stop (self
);
966 g_object_unref (self
);