* plugins/debug-manager/debug_tree.c,
[anjuta-git-plugin.git] / plugins / debug-manager / queue.c
blobe308f9e0dbd82e8b652f7fe03fcf0962cba860d9
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3 queue.c
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 *---------------------------------------------------------------------------*/
26 #include <config.h>
28 #include "queue.h"
30 /*#define DEBUG*/
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>
38 #include <stdarg.h>
40 /* Contants defintion
41 *---------------------------------------------------------------------------*/
43 #define ICON_FILE "anjuta-debug-manager.plugin.png"
45 /* Private type
46 *---------------------------------------------------------------------------*/
48 struct _DmaDebuggerQueue {
49 GObject parent;
51 AnjutaPlugin* plugin;
52 IAnjutaDebugger* debugger;
53 guint support;
55 /* Command queue */
56 GQueue *queue;
57 DmaQueueCommand *last;
58 gint prepend_command;
60 IAnjutaDebuggerState debugger_state;
61 IAnjutaDebuggerState queue_state;
62 gboolean stop_on_sharedlib;
64 /* View for debugger messages */
65 IAnjutaMessageView* log;
67 gboolean busy;
70 struct _DmaDebuggerQueueClass {
71 GObjectClass parent;
74 /* Call backs
75 *---------------------------------------------------------------------------*/
77 /* Queue function
78 *---------------------------------------------------------------------------*/
80 static void
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 */
86 while (node != NULL)
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);
96 node = next;
100 /* Cancel all commands those cannot handle this unexpected state
101 * Return TRUE if the state of the queue need to be changed too
104 static gboolean
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 */
113 while (node != NULL)
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 */
129 return FALSE;
131 node = next;
133 /* End in this unexpected state */
134 self->queue_state = state;
136 return TRUE;
139 static void
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);
149 self->last = NULL;
152 /* Queue is empty so has the same state than debugger */
153 self->queue_state = self->debugger_state;
155 self->prepend_command = 0;
158 static void
159 dma_queue_emit_debugger_state (DmaDebuggerQueue *self, IAnjutaDebuggerState state, GError* err)
161 enum
163 NO_SIGNAL,
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 */
178 switch (state)
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);
190 break;
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);
197 break;
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);
203 break;
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);
213 break;
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);
223 break;
224 case IANJUTA_DEBUGGER_BUSY:
225 break;
228 if (self->debugger_state != state)
230 switch (state)
232 case IANJUTA_DEBUGGER_BUSY:
233 /* Debugger is busy, nothing to do */
234 return;
235 case IANJUTA_DEBUGGER_STOPPED:
236 self->stop_on_sharedlib = FALSE;
237 signal = DEBUGGER_STOPPED_SIGNAL;
238 self->debugger_state = state;
239 break;
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;
244 break;
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;
249 break;
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;
261 break;
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;
267 break;
271 self->prepend_command++;
272 /* Emit signal */
273 switch (signal)
275 case NO_SIGNAL:
276 /* Do nothing */
277 break;
278 case DEBUGGER_STOPPED_SIGNAL:
279 DEBUG_PRINT("** emit debugger-stopped **");
280 g_signal_emit_by_name (self->plugin, "debugger-stopped", err);
281 break;
282 case DEBUGGER_STARTED_SIGNAL:
283 DEBUG_PRINT("** emit debugger-started **");
284 g_signal_emit_by_name (self->plugin, "debugger-started");
285 break;
286 case PROGRAM_LOADED_SIGNAL:
287 DEBUG_PRINT("** emit program-loaded **");
288 g_signal_emit_by_name (self->plugin, "program-loaded");
289 break;
290 case PROGRAM_UNLOADED_SIGNAL:
291 DEBUG_PRINT("** emit program-unloaded **");
292 g_signal_emit_by_name (self->plugin, "program-unloaded");
293 break;
294 case PROGRAM_STARTED_SIGNAL:
295 DEBUG_PRINT("** emit program-started **");
296 g_signal_emit_by_name (self->plugin, "program-started");
297 break;
298 case PROGRAM_EXITED_SIGNAL:
299 DEBUG_PRINT("** emit program-exited **");
300 g_signal_emit_by_name (self->plugin, "program-exited");
301 break;
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");
311 break;
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");
320 break;
322 self->prepend_command--;
325 static void
326 dma_queue_emit_debugger_ready (DmaDebuggerQueue *self)
328 gboolean busy;
330 if (g_queue_is_empty(self->queue) && (self->last == NULL))
332 busy = FALSE;
334 else
336 busy = TRUE;
339 if (busy != self->busy)
341 AnjutaStatus* status;
343 status = anjuta_shell_get_status(ANJUTA_PLUGIN (self->plugin)->shell, NULL);
344 if (busy)
346 anjuta_status_busy_push (status);
347 self->busy = TRUE;
349 else
351 anjuta_status_busy_pop (status);
352 self->busy = FALSE;
357 static void dma_debugger_queue_execute (DmaDebuggerQueue *self);
359 /* Call when debugger has completed the current command */
361 static void
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);
380 self->last = NULL;
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 */
394 static void
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;
415 GError *err = NULL;
416 gboolean ok;
418 cmd = (DmaQueueCommand *)g_queue_pop_head(self->queue);
420 /* Start command */
421 self->last = cmd;
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))
427 /* Something fail */
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);
438 self->last = NULL;
440 /* Display error message to user */
441 if (err != NULL)
443 if (err->message != NULL)
445 anjuta_util_dialog_error (GTK_WINDOW (ANJUTA_PLUGIN (self->plugin)->shell), err->message);
448 g_error_free (err);
453 dma_queue_emit_debugger_ready (self);
456 static gboolean
457 dma_queue_check_state (DmaDebuggerQueue *self, DmaQueueCommand* cmd)
459 gboolean recheck;
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;
476 else
478 state = self->debugger_state;
481 else
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))
492 /* State is right */
493 return TRUE;
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);
502 /* Check again */
505 return FALSE;
508 static gboolean
509 dma_debugger_activate_plugin (DmaDebuggerQueue* self, const gchar *mime_type)
511 AnjutaPluginManager *plugin_manager;
512 AnjutaPluginDescription *plugin;
513 GList *descs = NULL;
514 gchar *value;
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);
524 else
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,
530 NULL);
533 if (descs == NULL)
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);
539 return FALSE;
541 else if (g_list_length (descs) == 1)
543 /* Only one plugin found, use it */
544 plugin = (AnjutaPluginDescription *)descs->data;
546 else
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"),
552 descs);
555 if (plugin != NULL)
557 /* Get debugger location */
558 value = NULL;
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);
565 self->support = 0;
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;
577 g_free (value);
579 return TRUE;
581 else
583 /* No plugin selected */
585 return FALSE;
589 /* IAnjutaDebugger callback
590 *---------------------------------------------------------------------------*/
592 static void
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);
600 static void
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);
607 static void
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);
620 static void
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);
627 static void
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);
634 static void
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);
641 static void
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);
648 static void
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--;
657 static void
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--;
666 static void
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--;
675 static void
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);
687 /* Public function
688 *---------------------------------------------------------------------------*/
690 /* Command callback will add their commands at the beginning of the queue */
691 void
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--;
703 gboolean
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;
742 else
744 /* Prepend command at the beginning */
745 g_queue_push_head (self->queue, cmd);
748 dma_debugger_queue_execute(self);
750 return TRUE;
752 else
754 dma_command_free (cmd);
756 return FALSE;
760 void
761 dma_debugger_queue_stop (DmaDebuggerQueue *self)
763 /* Disconnect signal */
764 if (self->debugger)
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;
778 self->support = 0;
782 gboolean
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))
790 return FALSE;
793 if (self->debugger)
795 /* Connect signal */
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);
812 else
814 dma_queue_enable_log (self, self->log);
818 return self->debugger != NULL;
821 void
822 dma_queue_enable_log (DmaDebuggerQueue *self, IAnjutaMessageView *log)
824 self->log = log;
825 if (self->debugger != NULL)
827 ianjuta_debugger_enable_log (self->debugger, self->log, NULL);
831 void
832 dma_queue_disable_log (DmaDebuggerQueue *self)
834 self->log = NULL;
835 if (self->debugger != NULL)
837 ianjuta_debugger_disable_log (self->debugger, NULL);
841 IAnjutaDebuggerState
842 dma_debugger_queue_get_state (DmaDebuggerQueue *self)
844 return self->queue_state;
847 gboolean
848 dma_debugger_queue_is_supported (DmaDebuggerQueue *self, DmaDebuggerCapability capability)
850 return self->support & capability ? TRUE : FALSE;
853 /* GObject functions
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.*/
864 static void
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
876 * memory */
878 static void
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
887 * call. */
889 static void
890 dma_debugger_queue_instance_init (DmaDebuggerQueue *self)
892 self->plugin = NULL;
893 self->debugger = NULL;
894 self->support = 0;
895 self->queue = g_queue_new ();
896 self->last = NULL;
897 self->busy = FALSE;
898 self->prepend_command = 0;
899 self->debugger_state = IANJUTA_DEBUGGER_STOPPED;
900 self->queue_state = IANJUTA_DEBUGGER_STOPPED;
901 self->log = NULL;
904 /* class_init intialize the class itself not the instance */
906 static void
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;
920 GType
921 dma_debugger_queue_get_type (void)
923 static GType type = 0;
925 if (!type)
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),
936 0, /* n_preallocs */
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);
945 return type;
948 /* Creation and Destruction
949 *---------------------------------------------------------------------------*/
951 DmaDebuggerQueue*
952 dma_debugger_queue_new (AnjutaPlugin *plugin)
954 DmaDebuggerQueue *self;
956 self = g_object_new (DMA_DEBUGGER_QUEUE_TYPE, NULL);
957 self->plugin = plugin;
959 return self;
962 void
963 dma_debugger_queue_free (DmaDebuggerQueue *self)
965 dma_debugger_queue_stop (self);
966 g_object_unref (self);