[gnome-builder/wip/chergert/bug1: 36/101] perspective port wip
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder/wip/chergert/bug1: 36/101] perspective port wip
- Date: Sat, 2 Sep 2017 01:33:24 +0000 (UTC)
commit 7eb05216b6a8d9c8346dae90bd5e3a7a053665a4
Author: Christian Hergert <chergert redhat com>
Date: Fri Aug 25 01:33:49 2017 -0700
perspective port wip
data/gtk/menus.ui | 18 +
data/icons/hicolor/icons.gresource.xml | 1 +
.../scalable/actions/builder-debugger-symbolic.svg | 27 ++
libide/debugger/debugger.plugin | 10 +
libide/debugger/ide-debug-manager.c | 100 +++++-
libide/debugger/ide-debug-manager.h | 11 +-
libide/debugger/ide-debugger-breakpoints-view.ui | 121 +++++++
libide/debugger/ide-debugger-breakpoints.c | 189 ++++++++++
libide/debugger/ide-debugger-breakpoints.h | 37 ++
libide/debugger/ide-debugger-controls.c | 40 ++
libide/debugger/ide-debugger-controls.h | 40 ++
libide/debugger/ide-debugger-controls.ui | 92 +++++
libide/debugger/ide-debugger-gutter-renderer.c | 288 +++++++++++++++
libide/debugger/ide-debugger-gutter-renderer.h | 37 ++
libide/debugger/ide-debugger-libraries-view.ui | 44 +++
libide/debugger/ide-debugger-locals-view.ui | 61 ++++
libide/debugger/ide-debugger-perspective.c | 376 ++++++++++++++++++++
libide/debugger/ide-debugger-perspective.h | 35 ++
libide/debugger/ide-debugger-perspective.ui | 108 ++++++
libide/debugger/ide-debugger-plugin.c | 40 ++
libide/debugger/ide-debugger-private.h | 142 ++++----
libide/debugger/ide-debugger-registers-view.ui | 52 +++
libide/debugger/ide-debugger-threads-view.ui | 140 ++++++++
libide/debugger/ide-debugger-types.c | 1 +
libide/debugger/ide-debugger-types.h | 2 +
libide/debugger/ide-debugger-view.c | 155 ++++++++
libide/debugger/ide-debugger-view.h | 36 ++
libide/debugger/ide-debugger-view.ui | 20 +
libide/debugger/ide-debugger-workbench-addin.c | 260 ++++++++++++++
libide/debugger/ide-debugger-workbench-addin.h | 29 ++
libide/ide-context.h | 1 +
libide/ide-types.h | 8 +
libide/libide.gresource.xml | 12 +
libide/meson.build | 13 +
34 files changed, 2467 insertions(+), 79 deletions(-)
---
diff --git a/data/gtk/menus.ui b/data/gtk/menus.ui
index e849629..355c5f9 100644
--- a/data/gtk/menus.ui
+++ b/data/gtk/menus.ui
@@ -51,6 +51,16 @@
<attribute name="target">editor</attribute>
<attribute name="verb-icon-name">builder-editor-symbolic</attribute>
</item>
+ <item>
+ <attribute name="accel"><alt>2</attribute>
+ <attribute name="action">win.perspective</attribute>
+ <attribute name="after">perspective-menu-editor</attribute>
+ <attribute name="id">perspective-menu-debugger</attribute>
+ <attribute name="label" translatable="yes">Debugger</attribute>
+ <attribute name="role">normal</attribute>
+ <attribute name="target">debugger</attribute>
+ <attribute name="verb-icon-name">builder-debugger-symbolic</attribute>
+ </item>
</section>
<section id="perspectives-menu-prefs-section">
<item>
@@ -332,6 +342,14 @@
<attribute name="verb-icon-name">media-playback-start-symbolic</attribute>
<attribute name="accel"><Control>F5</attribute>
</item>
+ <item>
+ <attribute name="id">debugger-run-handler</attribute>
+ <attribute name="action">run-manager.run-with-handler</attribute>
+ <attribute name="target">debugger</attribute>
+ <attribute name="label" translatable="yes">Run with Debugger</attribute>
+ <attribute name="verb-icon-name">builder-debugger-symbolic</attribute>
+ <attribute name="accel">F5</attribute>
+ </item>
</section>
</menu>
</interface>
diff --git a/data/icons/hicolor/icons.gresource.xml b/data/icons/hicolor/icons.gresource.xml
index d078183..f89cd16 100644
--- a/data/icons/hicolor/icons.gresource.xml
+++ b/data/icons/hicolor/icons.gresource.xml
@@ -12,6 +12,7 @@
<file compressed="true">scalable/actions/builder-view-bottom-pane-symbolic.svg</file>
<file compressed="true">scalable/actions/builder-view-left-pane-symbolic.svg</file>
<file compressed="true">scalable/actions/builder-view-right-pane-symbolic.svg</file>
+ <file compressed="true">scalable/actions/builder-debugger-symbolic.svg</file>
<file compressed="true">scalable/actions/debug-continue-symbolic.svg</file>
<file compressed="true">scalable/actions/debug-execute-from-cursor-symbolic.svg</file>
<file compressed="true">scalable/actions/debug-execute-to-cursor-symbolic.svg</file>
diff --git a/data/icons/hicolor/scalable/actions/builder-debugger-symbolic.svg
b/data/icons/hicolor/scalable/actions/builder-debugger-symbolic.svg
new file mode 100644
index 0000000..8aac791
--- /dev/null
+++ b/data/icons/hicolor/scalable/actions/builder-debugger-symbolic.svg
@@ -0,0 +1,27 @@
+<?xml version='1.0' encoding='UTF-8' standalone='no'?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg xmlns:cc='http://creativecommons.org/ns#' xmlns:dc='http://purl.org/dc/elements/1.1/'
sodipodi:docname='nemiver-symbolic.svg' height='16' id='svg7384'
xmlns:inkscape='http://www.inkscape.org/namespaces/inkscape'
xmlns:osb='http://www.openswatchbook.org/uri/2009/osb'
xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'
xmlns:sodipodi='http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd' xmlns:svg='http://www.w3.org/2000/svg'
version='1.1' inkscape:version='0.91 r13725' width='16' xmlns='http://www.w3.org/2000/svg'>
+ <metadata id='metadata90'>
+ <rdf:RDF>
+ <cc:Work rdf:about=''>
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type rdf:resource='http://purl.org/dc/dcmitype/StillImage'/>
+ <dc:title>Gnome Symbolic Icon Theme</dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <sodipodi:namedview inkscape:bbox-paths='true' bordercolor='#666666' borderopacity='1'
inkscape:current-layer='layer9' inkscape:cx='5.1146516' inkscape:cy='-47.54864' gridtolerance='10'
inkscape:guide-bbox='true' guidetolerance='10' id='namedview88' inkscape:object-nodes='false'
inkscape:object-paths='false' objecttolerance='10' pagecolor='#555753' inkscape:pageopacity='1'
inkscape:pageshadow='2' showborder='false' showgrid='false' showguides='true' inkscape:snap-bbox='true'
inkscape:snap-bbox-midpoints='false' inkscape:snap-global='true' inkscape:snap-grids='true'
inkscape:snap-nodes='true' inkscape:snap-others='false' inkscape:snap-to-guides='true'
inkscape:window-height='1376' inkscape:window-maximized='1' inkscape:window-width='2560'
inkscape:window-x='0' inkscape:window-y='27' inkscape:zoom='4'>
+ <inkscape:grid empspacing='2' enabled='true' id='grid4866' originx='-162' originy='-382'
snapvisiblegridlinesonly='true' spacingx='1px' spacingy='1px' type='xygrid' visible='true'/>
+ </sodipodi:namedview>
+ <title id='title9167'>Gnome Symbolic Icon Theme</title>
+ <defs id='defs7386'>
+ <linearGradient id='linearGradient7212' osb:paint='solid'>
+ <stop id='stop7214' offset='0' style='stop-color:#000000;stop-opacity:1;'/>
+ </linearGradient>
+ </defs>
+ <g inkscape:groupmode='layer' id='layer9' inkscape:label='apps' style='display:inline'
transform='translate(-403.0002,165)'>
+
+ <path inkscape:connector-curvature='0' d='m 409.46895,-165 c -0.25969,0 -0.46875,0.20906
-0.46875,0.46875 l 0,1.875 c -1.03854,0.49004 -1.79689,1.48201 -1.96875,2.65625 l 6.9375,0 c
-0.17186,-1.17424 -0.93021,-2.16621 -1.96875,-2.65625 l 0,-1.875 c 0,-0.25969 -0.20906,-0.46875
-0.46875,-0.46875 z m 0.0312,1 c 0.27614,0 0.5,0.22386 0.5,0.5 0,0.27614 -0.22386,0.5 -0.5,0.5 -0.27614,0
-0.5,-0.22386 -0.5,-0.5 0,-0.27614 0.22386,-0.5 0.5,-0.5 z m -2.5,5 0,1 4.5,0 c 0.26179,3e-5 0.49997,0.23821
0.5,0.5 l 0,6 c -3e-5,0.26179 -0.23821,0.49997 -0.5,0.5 l -4.5,0 0,0.96875 c 0,0.57402 0.45723,1.03125
1.03125,1.03125 l 4.9375,0 c 0.57402,0 1.03125,-0.45723 1.03125,-1.03125 l 0,-8.96875 z m 0,2 0,5 4,0 0,-5 z'
id='rect7914' sodipodi:nodetypes='ssccccsssssssscccccccssssccccccc'
style='fill:#bebebe;fill-opacity:1;stroke:none'/>
+ </g>
+</svg>
diff --git a/libide/debugger/debugger.plugin b/libide/debugger/debugger.plugin
new file mode 100644
index 0000000..8ef8a11
--- /dev/null
+++ b/libide/debugger/debugger.plugin
@@ -0,0 +1,10 @@
+[Plugin]
+Module=debugger
+Name=Debugger
+Description=Debugger integration for Builder
+Authors=Christian Hergert <chergert redhat com>
+Copyright=Copyright © 2017 Christian Hergert
+Depends=editor
+Builtin=true
+Hidden=true
+Embedded=ide_debugger_register_types
diff --git a/libide/debugger/ide-debug-manager.c b/libide/debugger/ide-debug-manager.c
index ee7f6a9..82cf14b 100644
--- a/libide/debugger/ide-debug-manager.c
+++ b/libide/debugger/ide-debug-manager.c
@@ -25,6 +25,7 @@
#include "debugger/ide-debug-manager.h"
#include "debugger/ide-debugger.h"
+#include "debugger/ide-debugger-private.h"
#include "plugins/ide-extension-util.h"
#include "runner/ide-runner.h"
@@ -32,6 +33,7 @@ struct _IdeDebugManager
{
IdeObject parent_instance;
+ GHashTable *breakpoints;
IdeDebugger *debugger;
DzlBindingGroup *debugger_bindings;
DzlSignalGroup *debugger_signals;
@@ -125,6 +127,63 @@ ide_debug_manager_debugger_stopped (IdeDebugManager *self,
}
static void
+ide_debug_manager_breakpoint_added (IdeDebugManager *self,
+ IdeDebuggerBreakpoint *breakpoint,
+ IdeDebugger *debugger)
+{
+ IdeDebuggerBreakpoints *breakpoints;
+ IdeDebuggerBreakMode mode;
+ g_autoptr(GFile) file = NULL;
+ const gchar *path;
+ guint line;
+
+ g_assert (IDE_IS_DEBUG_MANAGER (self));
+ g_assert (IDE_IS_DEBUGGER_BREAKPOINT (breakpoint));
+ g_assert (IDE_IS_DEBUGGER (debugger));
+
+ path = ide_debugger_breakpoint_get_file (breakpoint);
+ file = g_file_new_for_path (path);
+
+ breakpoints = g_hash_table_lookup (self->breakpoints, file);
+
+ if (breakpoints == NULL)
+ {
+ breakpoints = g_object_new (IDE_TYPE_DEBUGGER_BREAKPOINTS,
+ "file", file,
+ NULL);
+ g_hash_table_insert (self->breakpoints, g_steal_pointer (&file), breakpoints);
+ }
+
+ mode = ide_debugger_breakpoint_get_mode (breakpoint);
+ line = ide_debugger_breakpoint_get_line (breakpoint);
+
+ ide_debugger_breakpoints_set_line (breakpoints, line, mode);
+}
+
+static void
+ide_debug_manager_breakpoint_removed (IdeDebugManager *self,
+ IdeDebuggerBreakpoint *breakpoint,
+ IdeDebugger *debugger)
+{
+ IdeDebuggerBreakpoints *breakpoints;
+ g_autoptr(GFile) file = NULL;
+ const gchar *path;
+ guint line;
+
+ g_assert (IDE_IS_DEBUG_MANAGER (self));
+ g_assert (IDE_IS_DEBUGGER_BREAKPOINT (breakpoint));
+ g_assert (IDE_IS_DEBUGGER (debugger));
+
+ line = ide_debugger_breakpoint_get_line (breakpoint);
+ path = ide_debugger_breakpoint_get_file (breakpoint);
+ file = g_file_new_for_path (path);
+
+ breakpoints = g_hash_table_lookup (self->breakpoints, file);
+ if (breakpoints != NULL)
+ ide_debugger_breakpoints_set_line (breakpoints, line, IDE_DEBUGGER_BREAK_NONE);
+}
+
+static void
ide_debug_manager_finalize (GObject *object)
{
IdeDebugManager *self = (IdeDebugManager *)object;
@@ -133,6 +192,7 @@ ide_debug_manager_finalize (GObject *object)
g_clear_object (&self->debugger_bindings);
g_clear_object (&self->debugger_signals);
g_clear_object (&self->runner);
+ g_clear_pointer (&self->breakpoints, g_hash_table_unref);
G_OBJECT_CLASS (ide_debug_manager_parent_class)->finalize (object);
}
@@ -217,13 +277,27 @@ ide_debug_manager_class_init (IdeDebugManagerClass *klass)
static void
ide_debug_manager_init (IdeDebugManager *self)
{
+ self->breakpoints = g_hash_table_new_full ((GHashFunc)g_file_hash,
+ (GEqualFunc)g_file_equal,
+ g_object_unref,
+ g_object_unref);
+
self->debugger_signals = dzl_signal_group_new (IDE_TYPE_DEBUGGER);
- dzl_signal_group_connect_object (self->debugger_signals,
- "stopped",
- G_CALLBACK (ide_debug_manager_debugger_stopped),
- self,
- G_CONNECT_SWAPPED);
+ dzl_signal_group_connect_swapped (self->debugger_signals,
+ "stopped",
+ G_CALLBACK (ide_debug_manager_debugger_stopped),
+ self);
+
+ dzl_signal_group_connect_swapped (self->debugger_signals,
+ "breakpoint-added",
+ G_CALLBACK (ide_debug_manager_breakpoint_added),
+ self);
+
+ dzl_signal_group_connect_swapped (self->debugger_signals,
+ "breakpoint-removed",
+ G_CALLBACK (ide_debug_manager_breakpoint_removed),
+ self);
}
static void
@@ -387,3 +461,19 @@ ide_debug_manager_get_active (IdeDebugManager *self)
return self->active;
}
+
+/**
+ * ide_debug_manager_get_debugger:
+ * @self: a #IdeDebugManager
+ *
+ * Gets the debugger instance, if it is loaded.
+ *
+ * Returns: (transfer none) (nullable): An #IdeDebugger or %NULL
+ */
+IdeDebugger *
+ide_debug_manager_get_debugger (IdeDebugManager *self)
+{
+ g_return_val_if_fail (IDE_IS_DEBUG_MANAGER (self), NULL);
+
+ return self->debugger;
+}
diff --git a/libide/debugger/ide-debug-manager.h b/libide/debugger/ide-debug-manager.h
index e0bdbf7..fa2a18b 100644
--- a/libide/debugger/ide-debug-manager.h
+++ b/libide/debugger/ide-debug-manager.h
@@ -26,10 +26,11 @@ G_BEGIN_DECLS
G_DECLARE_FINAL_TYPE (IdeDebugManager, ide_debug_manager, IDE, DEBUG_MANAGER, IdeObject)
-gboolean ide_debug_manager_get_active (IdeDebugManager *self);
-gboolean ide_debug_manager_start (IdeDebugManager *self,
- IdeRunner *runner,
- GError **error);
-void ide_debug_manager_stop (IdeDebugManager *self);
+IdeDebugger *ide_debug_manager_get_debugger (IdeDebugManager *self);
+gboolean ide_debug_manager_get_active (IdeDebugManager *self);
+gboolean ide_debug_manager_start (IdeDebugManager *self,
+ IdeRunner *runner,
+ GError **error);
+void ide_debug_manager_stop (IdeDebugManager *self);
G_END_DECLS
diff --git a/libide/debugger/ide-debugger-breakpoints-view.ui
b/libide/debugger/ide-debugger-breakpoints-view.ui
new file mode 100644
index 0000000..0a184de
--- /dev/null
+++ b/libide/debugger/ide-debugger-breakpoints-view.ui
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <template class="IdeDebuggerBreakpointsView" parent="GtkBin">
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">true</property>
+ <child>
+ <object class="GtkTreeView" id="tree_view">
+ <property name="model">list_store</property>
+ <property name="visible">true</property>
+ <child>
+ <object class="GtkTreeViewColumn" id="enabled_column">
+ <child>
+ <object class="GtkCellRendererToggle" id="enabled_cell">
+ <property name="xalign">0.5</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="id_column">
+ <property name="title" translatable="yes">ID</property>
+ <child>
+ <object class="GtkCellRendererText" id="id_cell">
+ <property name="xalign">0.0</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="file_column">
+ <property name="expand">true</property>
+ <property name="resizable">true</property>
+ <property name="title" translatable="yes">File</property>
+ <child>
+ <object class="GtkCellRendererText" id="file_cell">
+ <property name="ellipsize">start</property>
+ <property name="xalign">0.0</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="line_column">
+ <property name="resizable">true</property>
+ <property name="title" translatable="yes">Line</property>
+ <child>
+ <object class="GtkCellRendererText" id="line_cell">
+ <property name="xalign">0.0</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="function_column">
+ <property name="expand">true</property>
+ <property name="resizable">true</property>
+ <property name="title" translatable="yes">Function</property>
+ <child>
+ <object class="GtkCellRendererText" id="function_cell">
+ <property name="ellipsize">middle</property>
+ <property name="xalign">0.0</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="address_column">
+ <property name="resizable">true</property>
+ <property name="title" translatable="yes">Address</property>
+ <child>
+ <object class="GtkCellRendererText" id="address_cell">
+ <property name="xalign">0.0</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="type_column">
+ <property name="resizable">true</property>
+ <property name="title" translatable="yes">Type</property>
+ <child>
+ <object class="GtkCellRendererText" id="type_cell">
+ <property name="xalign">0.0</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="hits_column">
+ <property name="title" translatable="yes">Hits</property>
+ <child>
+ <object class="GtkCellRendererText" id="hits_cell">
+ <property name="xalign">0.0</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="spec_column">
+ <property name="resizable">true</property>
+ <property name="title" translatable="yes">Expression</property>
+ <child>
+ <object class="GtkCellRendererText" id="spec_cell">
+ <property name="ellipsize">end</property>
+ <property name="xalign">0.0</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </template>
+ <object class="GtkListStore" id="list_store">
+ <columns>
+ <column type="IdeDebuggerBreakpoint"/>
+ </columns>
+ </object>
+</interface>
diff --git a/libide/debugger/ide-debugger-breakpoints.c b/libide/debugger/ide-debugger-breakpoints.c
new file mode 100644
index 0000000..d65567c
--- /dev/null
+++ b/libide/debugger/ide-debugger-breakpoints.c
@@ -0,0 +1,189 @@
+/* ide-debugger-breakpoints.c
+ *
+ * Copyright (C) 2017 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define G_LOG_DOMAIN "ide-debugger-breakpoints"
+
+#include <stdlib.h>
+
+#include "ide-debug.h"
+
+#include "debugger/ide-debugger-breakpoints.h"
+
+typedef struct
+{
+ guint line;
+ IdeDebuggerBreakMode mode;
+} LineInfo;
+
+struct _IdeDebuggerBreakpoints
+{
+ GObject parent_instance;
+ GArray *lines;
+ GFile *file;
+};
+
+enum {
+ PROP_0,
+ PROP_FILE,
+ N_PROPS
+};
+
+G_DEFINE_TYPE (IdeDebuggerBreakpoints, ide_debugger_breakpoints, G_TYPE_OBJECT)
+
+static GParamSpec *properties [N_PROPS];
+
+static gint
+line_info_compare (gconstpointer a,
+ gconstpointer b)
+{
+ const LineInfo *lia = a;
+ const LineInfo *lib = b;
+
+ return (gint)lia->line - (gint)lib->line;
+}
+
+static void
+ide_debugger_breakpoints_finalize (GObject *object)
+{
+ IdeDebuggerBreakpoints *self = (IdeDebuggerBreakpoints *)object;
+
+ g_clear_object (&self->file);
+ g_clear_pointer (&self->lines, g_array_unref);
+
+ G_OBJECT_CLASS (ide_debugger_breakpoints_parent_class)->finalize (object);
+}
+
+static void
+ide_debugger_breakpoints_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ IdeDebuggerBreakpoints *self = IDE_DEBUGGER_BREAKPOINTS (object);
+
+ switch (prop_id)
+ {
+ case PROP_FILE:
+ g_value_set_object (value, self->file);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+ide_debugger_breakpoints_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ IdeDebuggerBreakpoints *self = IDE_DEBUGGER_BREAKPOINTS (object);
+
+ switch (prop_id)
+ {
+ case PROP_FILE:
+ self->file = g_value_dup_object (value);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+ide_debugger_breakpoints_class_init (IdeDebuggerBreakpointsClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = ide_debugger_breakpoints_finalize;
+ object_class->get_property = ide_debugger_breakpoints_get_property;
+ object_class->set_property = ide_debugger_breakpoints_set_property;
+
+ properties [PROP_FILE] =
+ g_param_spec_object ("file",
+ "File",
+ "The file for the breakpoints",
+ G_TYPE_FILE,
+ (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_properties (object_class, N_PROPS, properties);
+}
+
+static void
+ide_debugger_breakpoints_init (IdeDebuggerBreakpoints *self)
+{
+}
+
+IdeDebuggerBreakMode
+ide_debugger_breakpoints_get_line (IdeDebuggerBreakpoints *self,
+ guint line)
+{
+ g_return_val_if_fail (IDE_IS_DEBUGGER_BREAKPOINTS (self), 0);
+
+ if (self->lines != NULL)
+ {
+ LineInfo info = { line, 0 };
+ LineInfo *ret;
+
+ ret = bsearch (&info, (gpointer)self->lines->data,
+ self->lines->len, sizeof (LineInfo),
+ line_info_compare);
+
+ if (ret)
+ return ret->mode;
+ }
+
+ return 0;
+}
+
+void
+ide_debugger_breakpoints_set_line (IdeDebuggerBreakpoints *self,
+ guint line,
+ IdeDebuggerBreakMode mode)
+{
+ LineInfo info;
+
+ g_return_if_fail (IDE_IS_DEBUGGER_BREAKPOINTS (self));
+
+ if (self->lines != NULL)
+ {
+ for (guint i = 0; i < self->lines->len; i++)
+ {
+ LineInfo *ele = &g_array_index (self->lines, LineInfo, i);
+
+ if (ele->line == line)
+ {
+ g_array_remove_index_fast (self->lines, i);
+ break;
+ }
+ }
+ }
+
+ if (mode == IDE_DEBUGGER_BREAK_NONE)
+ return;
+
+ if (self->lines == NULL)
+ self->lines = g_array_new (FALSE, FALSE, sizeof (LineInfo));
+
+ info.line = line;
+ info.mode = mode;
+
+ g_array_append_val (self->lines, info);
+ g_array_sort (self->lines, line_info_compare);
+}
diff --git a/libide/debugger/ide-debugger-breakpoints.h b/libide/debugger/ide-debugger-breakpoints.h
new file mode 100644
index 0000000..1db82c4
--- /dev/null
+++ b/libide/debugger/ide-debugger-breakpoints.h
@@ -0,0 +1,37 @@
+/* ide-debugger-breakpoints.h
+ *
+ * Copyright (C) 2017 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include <glib-object.h>
+
+#include "ide-debugger-types.h"
+
+G_BEGIN_DECLS
+
+#define IDE_TYPE_DEBUGGER_BREAKPOINTS (ide_debugger_breakpoints_get_type())
+
+G_DECLARE_FINAL_TYPE (IdeDebuggerBreakpoints, ide_debugger_breakpoints, IDE, DEBUGGER_BREAKPOINTS, GObject)
+
+IdeDebuggerBreakMode ide_debugger_breakpoints_get_line (IdeDebuggerBreakpoints *self,
+ guint line);
+void ide_debugger_breakpoints_set_line (IdeDebuggerBreakpoints *self,
+ guint line,
+ IdeDebuggerBreakMode mode);
+
+G_END_DECLS
diff --git a/libide/debugger/ide-debugger-controls.c b/libide/debugger/ide-debugger-controls.c
new file mode 100644
index 0000000..71295b0
--- /dev/null
+++ b/libide/debugger/ide-debugger-controls.c
@@ -0,0 +1,40 @@
+/* ide-debugger-controls.c
+ *
+ * Copyright (C) 2017 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "ide-debugger-controls.h"
+
+struct _IdeDebuggerControls
+{
+ GtkBin parent_instance;
+};
+
+G_DEFINE_TYPE (IdeDebuggerControls, ide_debugger_controls, GTK_TYPE_REVEALER)
+
+static void
+ide_debugger_controls_class_init (IdeDebuggerControlsClass *klass)
+{
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ gtk_widget_class_set_template_from_resource (widget_class,
"/org/gnome/builder/ui/ide-debugger-controls.ui");
+}
+
+static void
+ide_debugger_controls_init (IdeDebuggerControls *self)
+{
+ gtk_widget_init_template (GTK_WIDGET (self));
+}
diff --git a/libide/debugger/ide-debugger-controls.h b/libide/debugger/ide-debugger-controls.h
new file mode 100644
index 0000000..3e7bd2d
--- /dev/null
+++ b/libide/debugger/ide-debugger-controls.h
@@ -0,0 +1,40 @@
+/* ide-debugger-controls.h
+ *
+ * Copyright (C) 2017 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef IDE_DEBUGGER_CONTROLS_H
+#define IDE_DEBUGGER_CONTROLS_H
+
+#include <gtk/gtk.h>
+
+#include "ide-types.h"
+
+#include "debugger/ide-debugger.h"
+
+G_BEGIN_DECLS
+
+#define IDE_TYPE_DEBUGGER_CONTROLS (ide_debugger_controls_get_type())
+
+G_DECLARE_FINAL_TYPE (IdeDebuggerControls, ide_debugger_controls, IDE, DEBUGGER_CONTROLS, GtkRevealer)
+
+IdeDebugger *ide_debugger_controls_get_debugger (IdeDebuggerControls *self);
+void ide_debugger_controls_set_debugger (IdeDebuggerControls *self,
+ IdeDebugger *debugger);
+
+G_END_DECLS
+
+#endif /* IDE_DEBUGGER_CONTROLS_H */
diff --git a/libide/debugger/ide-debugger-controls.ui b/libide/debugger/ide-debugger-controls.ui
new file mode 100644
index 0000000..33a6cd9
--- /dev/null
+++ b/libide/debugger/ide-debugger-controls.ui
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <template class="IdeDebuggerControls" parent="GtkRevealer">
+ <child>
+ <object class="GtkBox">
+ <property name="orientation">horizontal</property>
+ <property name="visible">true</property>
+ <style>
+ <class name="linked"/>
+ </style>
+ <child>
+ <object class="GtkButton" id="continue_button">
+ <property name="action-name">debug-manager.continue</property>
+ <property name="tooltip-text" translatable="yes">Continue running the program</property>
+ <property name="visible">true</property>
+ <child>
+ <object class="GtkImage">
+ <property name="icon-name">debug-continue-symbolic</property>
+ <property name="visible">true</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkButton" id="execute_from_cursor_button">
+ <property name="action-name">debug-manager.execute-from-cursor</property>
+ <property name="tooltip-text" translatable="yes">Execute from the current cursor
position</property>
+ <property name="visible">true</property>
+ <child>
+ <object class="GtkImage">
+ <property name="icon-name">debug-execute-from-cursor-symbolic</property>
+ <property name="visible">true</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkButton" id="execute_to_cursor_button">
+ <property name="action-name">debug-manager.execute-to-cursor</property>
+ <property name="tooltip-text" translatable="yes">Execute until reaching the current cursor
position</property>
+ <property name="visible">true</property>
+ <child>
+ <object class="GtkImage">
+ <property name="icon-name">debug-execute-to-cursor-symbolic</property>
+ <property name="visible">true</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkButton" id="step_in_button">
+ <property name="action-name">debug-manager.step-in</property>
+ <property name="tooltip-text" translatable="yes">Execute the current line, stepping into any
function calls</property>
+ <property name="visible">true</property>
+ <child>
+ <object class="GtkImage">
+ <property name="icon-name">debug-step-in-symbolic</property>
+ <property name="visible">true</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkButton" id="step_over_button">
+ <property name="action-name">debug-manager.step-over</property>
+ <property name="tooltip-text" translatable="yes">Execute the current line, stepping over any
function calls</property>
+ <property name="visible">true</property>
+ <child>
+ <object class="GtkImage">
+ <property name="icon-name">debug-step-over-symbolic</property>
+ <property name="visible">true</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkButton" id="finish_button">
+ <property name="action-name">debug-manager.finish</property>
+ <property name="tooltip-text" translatable="yes">Run until the end of the function</property>
+ <property name="visible">true</property>
+ <child>
+ <object class="GtkImage">
+ <property name="icon-name">debug-step-out-symbolic</property>
+ <property name="visible">true</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </template>
+</interface>
diff --git a/libide/debugger/ide-debugger-gutter-renderer.c b/libide/debugger/ide-debugger-gutter-renderer.c
new file mode 100644
index 0000000..89d3aac
--- /dev/null
+++ b/libide/debugger/ide-debugger-gutter-renderer.c
@@ -0,0 +1,288 @@
+/* ide-debugger-gutter-renderer.c
+ *
+ * Copyright (C) 2017 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define G_LOG_DOMAIN "ide-debugger-gutter-renderer"
+
+#include <glib/gi18n.h>
+
+#include "ide-debug.h"
+
+#include "debugger/ide-debugger-gutter-renderer.h"
+#include "debugger/ide-debugger-breakpoints.h"
+
+struct _IdeDebuggerGutterRenderer
+{
+ GtkSourceGutterRendererPixbuf parent_instance;
+ IdeDebuggerBreakpoints *breakpoints;
+ gulong breakpoints_changed_handler;
+};
+
+G_DEFINE_TYPE (IdeDebuggerGutterRenderer, ide_debugger_gutter_renderer,
GTK_SOURCE_TYPE_GUTTER_RENDERER_PIXBUF)
+
+enum {
+ PROP_0,
+ PROP_BREAKPOINTS,
+ N_PROPS
+};
+
+static GParamSpec *properties [N_PROPS];
+
+static void
+ide_debugger_gutter_renderer_activate (IdeDebuggerGutterRenderer *self,
+ const GtkTextIter *iter,
+ GdkRectangle *area,
+ GdkEvent *event)
+{
+ IdeDebuggerBreakMode break_type;
+ guint line;
+
+ IDE_ENTRY;
+
+ g_assert (IDE_IS_DEBUGGER_GUTTER_RENDERER (self));
+ g_assert (iter != NULL);
+ g_assert (area != NULL);
+ g_assert (event != NULL);
+
+ line = gtk_text_iter_get_line (iter) + 1;
+
+ IDE_TRACE_MSG ("Toggle breakpoint on line %u", line);
+
+ break_type = ide_debugger_breakpoints_get_line (self->breakpoints, line);
+
+ switch (break_type)
+ {
+ case IDE_DEBUGGER_BREAK_NONE:
+ /* TOOD: Register with real debug manager */
+ ide_debugger_breakpoints_set_line (self->breakpoints, line, IDE_DEBUGGER_BREAK_BREAKPOINT);
+ break;
+
+ case IDE_DEBUGGER_BREAK_BREAKPOINT:
+ case IDE_DEBUGGER_BREAK_COUNTPOINT:
+ case IDE_DEBUGGER_BREAK_WATCHPOINT:
+ /* TOOD: Register with real debug manager */
+ ide_debugger_breakpoints_set_line (self->breakpoints, line, 0);
+ break;
+
+ default:
+ break;
+ }
+
+ IDE_EXIT;
+}
+
+static gboolean
+ide_debugger_gutter_renderer_query_activatable (IdeDebuggerGutterRenderer *self,
+ const GtkTextIter *begin,
+ const GdkRectangle *area,
+ GdkEvent *event)
+{
+ g_assert (IDE_IS_DEBUGGER_GUTTER_RENDERER (self));
+ g_assert (begin != NULL);
+ g_assert (area != NULL);
+ g_assert (event != NULL);
+
+ return TRUE;
+}
+
+static void
+ide_debugger_gutter_renderer_query_data (IdeDebuggerGutterRenderer *self,
+ const GtkTextIter *begin,
+ const GtkTextIter *end,
+ GtkSourceGutterRendererState state)
+{
+ IdeDebuggerBreakMode break_type;
+ guint line;
+
+ g_assert (IDE_IS_DEBUGGER_GUTTER_RENDERER (self));
+ g_assert (begin != NULL);
+ g_assert (end != NULL);
+
+ if (self->breakpoints == NULL)
+ return;
+
+ line = gtk_text_iter_get_line (begin) + 1;
+ break_type = ide_debugger_breakpoints_get_line (self->breakpoints, line);
+
+ /*
+ * These are very much a miss-appropriation of the icon, but it works
+ * well enough for now until we get real symbolic icons for these.
+ */
+#define BREAKPOINT_ICON_NAME "edit-clear-symbolic-rtl"
+#define COUNTPOINT_ICON_NAME "edit-clear-symbolic-rtl"
+#define WATCHPOINT_ICON_NAME "edit-clear-symbolic-rtl"
+
+ switch (break_type)
+ {
+ case IDE_DEBUGGER_BREAK_BREAKPOINT:
+ gtk_source_gutter_renderer_pixbuf_set_icon_name (GTK_SOURCE_GUTTER_RENDERER_PIXBUF (self),
BREAKPOINT_ICON_NAME);
+ break;
+
+ case IDE_DEBUGGER_BREAK_COUNTPOINT:
+ gtk_source_gutter_renderer_pixbuf_set_icon_name (GTK_SOURCE_GUTTER_RENDERER_PIXBUF (self),
COUNTPOINT_ICON_NAME);
+ break;
+
+ case IDE_DEBUGGER_BREAK_WATCHPOINT:
+ gtk_source_gutter_renderer_pixbuf_set_icon_name (GTK_SOURCE_GUTTER_RENDERER_PIXBUF (self),
WATCHPOINT_ICON_NAME);
+ break;
+
+ case IDE_DEBUGGER_BREAK_NONE:
+ default:
+ /* Setting pixbuf to NULL via g_object_set() seems to be
+ * the only way to clear this without g_warning()s.
+ */
+ g_object_set (self, "pixbuf", NULL, NULL);
+ break;
+ }
+
+#undef BREAKPOINT_ICON_NAME
+#undef COUNTPOINT_ICON_NAME
+#undef WATCHPOINT_ICON_NAME
+}
+
+static void
+ide_debugger_gutter_renderer_breakpoints_changed (IdeDebuggerGutterRenderer *self,
+ IdeDebuggerBreakpoints *breakpoints)
+{
+ g_assert (IDE_IS_DEBUGGER_GUTTER_RENDERER (self));
+ g_assert (IDE_IS_DEBUGGER_BREAKPOINTS (breakpoints));
+
+ gtk_source_gutter_renderer_queue_draw (GTK_SOURCE_GUTTER_RENDERER (self));
+}
+
+void
+ide_debugger_gutter_renderer_set_breakpoints (IdeDebuggerGutterRenderer *self,
+ IdeDebuggerBreakpoints *breakpoints)
+{
+ g_return_if_fail (IDE_IS_DEBUGGER_GUTTER_RENDERER (self));
+ g_return_if_fail (!breakpoints || IDE_IS_DEBUGGER_BREAKPOINTS (breakpoints));
+
+ if (self->breakpoints != breakpoints)
+ {
+ if (self->breakpoints != NULL)
+ {
+ g_signal_handler_disconnect (self->breakpoints, self->breakpoints_changed_handler);
+ self->breakpoints_changed_handler = 0;
+ g_clear_object (&self->breakpoints);
+ }
+
+ if (breakpoints != NULL)
+ {
+ self->breakpoints = g_object_ref (breakpoints);
+ self->breakpoints_changed_handler =
+ g_signal_connect_object (breakpoints,
+ "changed",
+ G_CALLBACK (ide_debugger_gutter_renderer_breakpoints_changed),
+ self,
+ G_CONNECT_SWAPPED);
+ }
+
+ g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_BREAKPOINTS]);
+ }
+}
+
+static void
+ide_debugger_gutter_renderer_finalize (GObject *object)
+{
+ IdeDebuggerGutterRenderer *self = (IdeDebuggerGutterRenderer *)object;
+
+ g_clear_object (&self->breakpoints);
+
+ G_OBJECT_CLASS (ide_debugger_gutter_renderer_parent_class)->finalize (object);
+}
+
+static void
+ide_debugger_gutter_renderer_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ IdeDebuggerGutterRenderer *self = IDE_DEBUGGER_GUTTER_RENDERER (object);
+
+ switch (prop_id)
+ {
+ case PROP_BREAKPOINTS:
+ g_value_set_object (value, self->breakpoints);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+ide_debugger_gutter_renderer_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ IdeDebuggerGutterRenderer *self = IDE_DEBUGGER_GUTTER_RENDERER (object);
+
+ switch (prop_id)
+ {
+ case PROP_BREAKPOINTS:
+ ide_debugger_gutter_renderer_set_breakpoints (self, g_value_get_object (value));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+ide_debugger_gutter_renderer_class_init (IdeDebuggerGutterRendererClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = ide_debugger_gutter_renderer_finalize;
+ object_class->get_property = ide_debugger_gutter_renderer_get_property;
+ object_class->set_property = ide_debugger_gutter_renderer_set_property;
+
+ properties [PROP_BREAKPOINTS] =
+ g_param_spec_object ("breakpoints",
+ "Breakpoints",
+ "Breakpoints",
+ IDE_TYPE_DEBUGGER_BREAKPOINTS,
+ (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_properties (object_class, N_PROPS, properties);
+}
+
+static void
+ide_debugger_gutter_renderer_init (IdeDebuggerGutterRenderer *self)
+{
+ g_signal_connect (self,
+ "activate",
+ G_CALLBACK (ide_debugger_gutter_renderer_activate),
+ NULL);
+
+ g_signal_connect (self,
+ "query-activatable",
+ G_CALLBACK (ide_debugger_gutter_renderer_query_activatable),
+ NULL);
+
+ g_signal_connect (self,
+ "query-data",
+ G_CALLBACK (ide_debugger_gutter_renderer_query_data),
+ NULL);
+}
+
+GtkSourceGutterRenderer *
+ide_debugger_gutter_renderer_new (void)
+{
+ return g_object_new (IDE_TYPE_DEBUGGER_GUTTER_RENDERER, NULL);
+}
diff --git a/libide/debugger/ide-debugger-gutter-renderer.h b/libide/debugger/ide-debugger-gutter-renderer.h
new file mode 100644
index 0000000..dd11d35
--- /dev/null
+++ b/libide/debugger/ide-debugger-gutter-renderer.h
@@ -0,0 +1,37 @@
+/* ide-debugger-gutter-renderer.h
+ *
+ * Copyright (C) 2017 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include <gtksourceview/gtksource.h>
+
+#include "ide-types.h"
+
+#include "debugger/ide-debugger-breakpoints.h"
+
+G_BEGIN_DECLS
+
+#define IDE_TYPE_DEBUGGER_GUTTER_RENDERER (ide_debugger_gutter_renderer_get_type())
+
+G_DECLARE_FINAL_TYPE (IdeDebuggerGutterRenderer, ide_debugger_gutter_renderer, IDE,
DEBUGGER_GUTTER_RENDERER, GtkSourceGutterRendererPixbuf)
+
+GtkSourceGutterRenderer *ide_debugger_gutter_renderer_new (void);
+void ide_debugger_gutter_renderer_set_breakpoints (IdeDebuggerGutterRenderer *self,
+ IdeDebuggerBreakpoints
*breakpoints);
+
+G_END_DECLS
diff --git a/libide/debugger/ide-debugger-libraries-view.ui b/libide/debugger/ide-debugger-libraries-view.ui
new file mode 100644
index 0000000..e8dd3fb
--- /dev/null
+++ b/libide/debugger/ide-debugger-libraries-view.ui
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <template class="IdeDebuggerLibrariesView" parent="GtkBin">
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">true</property>
+ <child>
+ <object class="GtkTreeView" id="tree_view">
+ <property name="model">list_store</property>
+ <property name="sensitive">false</property>
+ <property name="visible">true</property>
+ <child>
+ <object class="GtkTreeViewColumn" id="target_column">
+ <property name="title" translatable="yes">Library</property>
+ <property name="expand">true</property>
+ <child>
+ <object class="GtkCellRendererText" id="target_cell">
+ <property name="ellipsize">start</property>
+ <property name="xalign">0.0</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="range_column">
+ <property name="title" translatable="yes">Address Range</property>
+ <child>
+ <object class="GtkCellRendererText" id="range_cell">
+ <property name="xalign">0.0</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </template>
+ <object class="GtkListStore" id="list_store">
+ <columns>
+ <column type="IdeDebuggerLibrary"/>
+ </columns>
+ </object>
+</interface>
diff --git a/libide/debugger/ide-debugger-locals-view.ui b/libide/debugger/ide-debugger-locals-view.ui
new file mode 100644
index 0000000..2c85151
--- /dev/null
+++ b/libide/debugger/ide-debugger-locals-view.ui
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <template class="IdeDebuggerLocalsView" parent="GtkBin">
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="min-content-width">300</property>
+ <property name="visible">true</property>
+ <child>
+ <object class="GtkTreeView" id="tree_view">
+ <property name="model">tree_store</property>
+ <property name="visible">true</property>
+ <child>
+ <object class="GtkTreeViewColumn" id="variable_column">
+ <property name="expand">true</property>
+ <property name="resizable">true</property>
+ <property name="title" translatable="yes">Variable</property>
+ <child>
+ <object class="GtkCellRendererText" id="variable_cell">
+ <property name="xalign">0.0</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="type_column">
+ <property name="expand">true</property>
+ <property name="resizable">true</property>
+ <property name="title" translatable="yes">Type</property>
+ <child>
+ <object class="GtkCellRendererText" id="type_cell">
+ <property name="ellipsize">end</property>
+ <property name="xalign">0.0</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="value_column">
+ <property name="expand">true</property>
+ <property name="resizable">true</property>
+ <property name="title" translatable="yes">Value</property>
+ <child>
+ <object class="GtkCellRendererText" id="value_cell">
+ <property name="ellipsize">end</property>
+ <property name="xalign">0.0</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </template>
+ <object class="GtkTreeStore" id="tree_store">
+ <columns>
+ <column type="GObject"/>
+ <column type="gchararray"/>
+ </columns>
+ </object>
+</interface>
diff --git a/libide/debugger/ide-debugger-perspective.c b/libide/debugger/ide-debugger-perspective.c
new file mode 100644
index 0000000..e9376c6
--- /dev/null
+++ b/libide/debugger/ide-debugger-perspective.c
@@ -0,0 +1,376 @@
+/* ide-debugger-perspective.c
+ *
+ * Copyright (C) 2017 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define G_LOG_DOMAIN "ide-debugger-perspective"
+
+#include <dazzle.h>
+#include <glib/gi18n.h>
+
+#include "ide-debug.h"
+
+#include "buffers/ide-buffer.h"
+#include "debugger/ide-debugger.h"
+#include "debugger/ide-debugger-breakpoints-view.h"
+#include "debugger/ide-debugger-locals-view.h"
+#include "debugger/ide-debugger-perspective.h"
+#include "debugger/ide-debugger-registers-view.h"
+#include "debugger/ide-debugger-threads-view.h"
+#include "debugger/ide-debugger-view.h"
+#include "layout/ide-layout-grid.h"
+#include "workbench/ide-perspective.h"
+
+struct _IdeDebuggerPerspective
+{
+ IdeLayout parent_instance;
+
+ /* Owned references */
+ IdeDebugger *debugger;
+ DzlSignalGroup *debugger_signals;
+ GSettings *terminal_settings;
+ GtkCssProvider *log_css;
+
+ /* Template references */
+ GtkTextBuffer *log_buffer;
+ GtkTextView *log_text_view;
+ IdeLayoutGrid *layout_grid;
+};
+
+enum {
+ PROP_0,
+ PROP_DEBUGGER,
+ N_PROPS
+};
+
+static gchar *
+ide_debugger_perspective_get_title (IdePerspective *perspective)
+{
+ return g_strdup (_("Debugger"));
+}
+
+static gchar *
+ide_debugger_perspective_get_id (IdePerspective *perspective)
+{
+ return g_strdup ("debugger");
+}
+
+static gchar *
+ide_debugger_perspective_get_icon_name (IdePerspective *perspective)
+{
+ return g_strdup ("builder-debugger-symbolic");
+}
+
+static gchar *
+ide_debugger_perspective_get_accelerator (IdePerspective *perspective)
+{
+ return g_strdup ("<Alt>2");
+}
+
+static void
+perspective_iface_init (IdePerspectiveInterface *iface)
+{
+ iface->get_accelerator = ide_debugger_perspective_get_accelerator;
+ iface->get_icon_name = ide_debugger_perspective_get_icon_name;
+ iface->get_id = ide_debugger_perspective_get_id;
+ iface->get_title = ide_debugger_perspective_get_title;
+}
+
+G_DEFINE_TYPE_WITH_CODE (IdeDebuggerPerspective, ide_debugger_perspective, IDE_TYPE_LAYOUT,
+ G_IMPLEMENT_INTERFACE (IDE_TYPE_PERSPECTIVE, perspective_iface_init))
+
+static GParamSpec *properties [N_PROPS];
+
+static void
+on_debugger_log (IdeDebuggerPerspective *self,
+ IdeDebuggerStream stream,
+ GBytes *content,
+ IdeDebugger *debugger)
+{
+ g_assert (IDE_IS_DEBUGGER_PERSPECTIVE (self));
+ g_assert (IDE_IS_DEBUGGER_STREAM (stream));
+ g_assert (IDE_IS_DEBUGGER (debugger));
+
+ if (stream == IDE_DEBUGGER_CONSOLE)
+ {
+ const gchar *str;
+ GtkTextIter iter;
+ gsize len;
+
+ str = (gchar *)g_bytes_get_data (content, &len);
+
+ gtk_text_buffer_get_end_iter (self->log_buffer, &iter);
+ gtk_text_buffer_insert (self->log_buffer, &iter, str, len);
+ gtk_text_buffer_select_range (self->log_buffer, &iter, &iter);
+ gtk_text_view_scroll_to_iter (self->log_text_view, &iter, 0.0, FALSE, 1.0, 1.0);
+ }
+}
+
+void
+ide_debugger_perspective_set_debugger (IdeDebuggerPerspective *self,
+ IdeDebugger *debugger)
+{
+ IDE_ENTRY;
+
+ g_return_if_fail (IDE_IS_DEBUGGER_PERSPECTIVE (self));
+ g_return_if_fail (!debugger || IDE_IS_DEBUGGER (debugger));
+
+ if (g_set_object (&self->debugger, debugger))
+ {
+ dzl_signal_group_set_target (self->debugger_signals, debugger);
+ gtk_text_buffer_set_text (self->log_buffer, "", 0);
+ g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_DEBUGGER]);
+ }
+
+ IDE_EXIT;
+}
+
+static void
+log_panel_changed_font_name (IdeDebuggerPerspective *self,
+ const gchar *key,
+ GSettings *settings)
+{
+ gchar *font_name;
+ PangoFontDescription *font_desc;
+
+ g_assert (IDE_IS_DEBUGGER_PERSPECTIVE (self));
+ g_assert (g_strcmp0 (key, "font-name") == 0);
+ g_assert (G_IS_SETTINGS (settings));
+
+ font_name = g_settings_get_string (settings, key);
+ font_desc = pango_font_description_from_string (font_name);
+
+ if (font_desc != NULL)
+ {
+ gchar *fragment;
+ gchar *css;
+
+ fragment = dzl_pango_font_description_to_css (font_desc);
+ css = g_strdup_printf ("textview { %s }", fragment);
+
+ gtk_css_provider_load_from_data (self->log_css, css, -1, NULL);
+
+ pango_font_description_free (font_desc);
+ g_free (fragment);
+ g_free (css);
+ }
+
+ g_free (font_name);
+}
+
+static void
+on_debugger_stopped (IdeDebuggerPerspective *self,
+ IdeDebuggerStopReason reason,
+ IdeDebuggerBreakpoint *breakpoint,
+ IdeDebugger *debugger)
+{
+ IDE_ENTRY;
+
+ g_assert (IDE_IS_DEBUGGER_PERSPECTIVE (self));
+ g_assert (!breakpoint || IDE_IS_DEBUGGER_BREAKPOINT (breakpoint));
+ g_assert (IDE_IS_DEBUGGER (debugger));
+
+ if (breakpoint != NULL)
+ ide_debugger_perspective_navigate_to_breakpoint (self, breakpoint);
+
+ IDE_EXIT;
+}
+
+static void
+ide_debugger_perspective_finalize (GObject *object)
+{
+ IdeDebuggerPerspective *self = (IdeDebuggerPerspective *)object;
+
+ g_clear_object (&self->debugger);
+ g_clear_object (&self->debugger_signals);
+ g_clear_object (&self->terminal_settings);
+ g_clear_object (&self->log_css);
+
+ G_OBJECT_CLASS (ide_debugger_perspective_parent_class)->finalize (object);
+}
+
+static void
+ide_debugger_perspective_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ IdeDebuggerPerspective *self = IDE_DEBUGGER_PERSPECTIVE (object);
+
+ switch (prop_id)
+ {
+ case PROP_DEBUGGER:
+ g_value_set_object (value, self->debugger);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+ide_debugger_perspective_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ IdeDebuggerPerspective *self = IDE_DEBUGGER_PERSPECTIVE (object);
+
+ switch (prop_id)
+ {
+ case PROP_DEBUGGER:
+ ide_debugger_perspective_set_debugger (self, g_value_get_object (value));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+ide_debugger_perspective_class_init (IdeDebuggerPerspectiveClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ object_class->finalize = ide_debugger_perspective_finalize;
+ object_class->get_property = ide_debugger_perspective_get_property;
+ object_class->set_property = ide_debugger_perspective_set_property;
+
+ properties [PROP_DEBUGGER] =
+ g_param_spec_object ("debugger",
+ "Debugger",
+ "The current debugger instance",
+ IDE_TYPE_DEBUGGER,
+ (G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_properties (object_class, N_PROPS, properties);
+
+ gtk_widget_class_set_template_from_resource (widget_class,
"/org/gnome/builder/ui/ide-debugger-perspective.ui");
+ gtk_widget_class_bind_template_child (widget_class, IdeDebuggerPerspective, layout_grid);
+ gtk_widget_class_bind_template_child (widget_class, IdeDebuggerPerspective, log_text_view);
+ gtk_widget_class_bind_template_child (widget_class, IdeDebuggerPerspective, log_buffer);
+
+ g_type_ensure (IDE_TYPE_DEBUGGER_BREAKPOINTS_VIEW);
+ g_type_ensure (IDE_TYPE_DEBUGGER_LOCALS_VIEW);
+ g_type_ensure (IDE_TYPE_DEBUGGER_REGISTERS_VIEW);
+ g_type_ensure (IDE_TYPE_DEBUGGER_THREADS_VIEW);
+}
+
+static void
+ide_debugger_perspective_init (IdeDebuggerPerspective *self)
+{
+ GtkStyleContext *context;
+
+ gtk_widget_init_template (GTK_WIDGET (self));
+
+ self->debugger_signals = dzl_signal_group_new (IDE_TYPE_DEBUGGER);
+
+ dzl_signal_group_connect_object (self->debugger_signals,
+ "log",
+ G_CALLBACK (on_debugger_log),
+ self,
+ G_CONNECT_SWAPPED);
+
+ dzl_signal_group_connect_object (self->debugger_signals,
+ "stopped",
+ G_CALLBACK (on_debugger_stopped),
+ self,
+ G_CONNECT_SWAPPED);
+
+ self->log_css = gtk_css_provider_new ();
+ context = gtk_widget_get_style_context (GTK_WIDGET (self->log_text_view));
+ gtk_style_context_add_provider (context,
+ GTK_STYLE_PROVIDER (self->log_css),
+ GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
+
+ self->terminal_settings = g_settings_new ("org.gnome.builder.terminal");
+ g_signal_connect_object (self->terminal_settings,
+ "changed::font-name",
+ G_CALLBACK (log_panel_changed_font_name),
+ self,
+ G_CONNECT_SWAPPED);
+ log_panel_changed_font_name (self, "font-name", self->terminal_settings);
+}
+
+static void
+ide_debugger_perspective_locate_by_file (GtkWidget *widget,
+ gpointer user_data)
+{
+ struct {
+ const gchar *file;
+ IdeDebuggerView *view;
+ } *lookup = user_data;
+
+ if (lookup->view != NULL)
+ return;
+
+ if (IDE_IS_DEBUGGER_VIEW (widget))
+ {
+ }
+}
+
+void
+ide_debugger_perspective_navigate_to_breakpoint (IdeDebuggerPerspective *self,
+ IdeDebuggerBreakpoint *breakpoint)
+{
+ struct {
+ const gchar *file;
+ IdeDebuggerView *view;
+ } lookup = { 0 };
+
+ IDE_ENTRY;
+
+ g_return_if_fail (IDE_IS_DEBUGGER_PERSPECTIVE (self));
+ g_return_if_fail (IDE_IS_DEBUGGER_BREAKPOINT (breakpoint));
+ g_return_if_fail (IDE_IS_DEBUGGER (self->debugger));
+
+ /*
+ * To display the source for the breakpoint, first we need to discover what
+ * file contains the source. If there is no file, then we need to ask the
+ * IdeDebugger to retrieve the disassembly for us so that we can show
+ * something "useful" to the developer.
+ *
+ * If we also fail to get the disassembly for the current breakpoint, we
+ * need to load some dummy text into a buffer to denote to the developer
+ * that technically they can click forward, but the behavior is rather
+ * undefined.
+ *
+ * If the file on disk is out of date (due to changes behind the scenes) we
+ * will likely catch that with a CRC check. We will show the file, but the
+ * user will have an infobar displayed that denotes that the file is not
+ * longer in sync with the debugged executable.
+ */
+
+ lookup.file = ide_debugger_breakpoint_get_file (breakpoint);
+ g_return_if_fail (lookup.file != NULL);
+
+ ide_layout_grid_foreach_view (self->layout_grid,
+ ide_debugger_perspective_locate_by_file,
+ &lookup);
+
+ if (lookup.view != NULL)
+ {
+ //ide_debugger_view_scroll_to_line (lookup.view,
+ //ide_debugger_breakpoint_get_line (breakpoint));
+ gtk_widget_grab_focus (GTK_WIDGET (lookup.view));
+ return;
+ }
+
+ g_print ("Need to load source\n");
+
+ IDE_EXIT;
+}
diff --git a/libide/debugger/ide-debugger-perspective.h b/libide/debugger/ide-debugger-perspective.h
new file mode 100644
index 0000000..d83075e
--- /dev/null
+++ b/libide/debugger/ide-debugger-perspective.h
@@ -0,0 +1,35 @@
+/* ide-debugger-perspective.h
+ *
+ * Copyright (C) 2017 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include "debugger/ide-debugger-breakpoint.h"
+#include "layout/ide-layout.h"
+
+G_BEGIN_DECLS
+
+#define IDE_TYPE_DEBUGGER_PERSPECTIVE (ide_debugger_perspective_get_type())
+
+G_DECLARE_FINAL_TYPE (IdeDebuggerPerspective, ide_debugger_perspective, IDE, DEBUGGER_PERSPECTIVE, IdeLayout)
+
+void ide_debugger_perspective_set_debugger (IdeDebuggerPerspective *self,
+ IdeDebugger *debugger);
+void ide_debugger_perspective_navigate_to_breakpoint (IdeDebuggerPerspective *self,
+ IdeDebuggerBreakpoint *breakpoint);
+
+G_END_DECLS
diff --git a/libide/debugger/ide-debugger-perspective.ui b/libide/debugger/ide-debugger-perspective.ui
new file mode 100644
index 0000000..67f676a
--- /dev/null
+++ b/libide/debugger/ide-debugger-perspective.ui
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <template class="IdeDebuggerPerspective" parent="IdeLayout">
+ <child>
+ <object class="IdeLayoutGrid" id="layout_grid">
+ <property name="visible">true</property>
+ </object>
+ </child>
+ <child internal-child="bottom">
+ <object class="DzlDockBinEdge">
+ <property name="reveal-child">true</property>
+ </object>
+ </child>
+ <child type="bottom">
+ <object class="DzlDockStack">
+ <property name="hexpand">true</property>
+ <property name="visible">true</property>
+ <child>
+ <object class="DzlDockWidget">
+ <property name="title" translatable="yes">Application Output</property>
+ <property name="expand">true</property>
+ <property name="visible">true</property>
+ </object>
+ </child>
+ <child>
+ <object class="DzlDockWidget">
+ <property name="title" translatable="yes">Breakpoints</property>
+ <property name="expand">true</property>
+ <property name="visible">true</property>
+ <child>
+ <object class="IdeDebuggerBreakpointsView" id="breakpoints_view">
+ <property name="visible">true</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="DzlDockWidget">
+ <property name="title" translatable="yes">Threads</property>
+ <property name="expand">true</property>
+ <property name="visible">true</property>
+ <child>
+ <object class="DzlMultiPaned">
+ <property name="orientation">horizontal</property>
+ <property name="visible">true</property>
+ <child>
+ <object class="IdeDebuggerThreadsView" id="threads_view">
+ <property name="hexpand">true</property>
+ <property name="visible">true</property>
+ </object>
+ </child>
+ <child>
+ <object class="IdeDebuggerLocalsView" id="locals_view">
+ <property name="hexpand">true</property>
+ <property name="visible">true</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="DzlDockWidget">
+ <property name="title" translatable="yes">Registers</property>
+ <property name="expand">true</property>
+ <property name="visible">true</property>
+ <child>
+ <object class="IdeDebuggerRegistersView" id="registers_view">
+ <property name="visible">true</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="DzlDockWidget">
+ <property name="title" translatable="yes">Libraries</property>
+ <property name="expand">true</property>
+ <property name="visible">true</property>
+ <child>
+ <object class="IdeDebuggerLibrariesView" id="libraries_view">
+ <property name="visible">true</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="DzlDockWidget">
+ <property name="title" translatable="yes">Log</property>
+ <property name="expand">true</property>
+ <property name="visible">true</property>
+ <child>
+ <object class="GtkScrolledWindow">
+ <child>
+ <object class="GtkTextView" id="log_text_view">
+ <property name="buffer">log_buffer</property>
+ <property name="visible">true</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </template>
+ <object class="GtkTextBuffer" id="log_buffer">
+ </object>
+</interface>
diff --git a/libide/debugger/ide-debugger-plugin.c b/libide/debugger/ide-debugger-plugin.c
new file mode 100644
index 0000000..e45cc7f
--- /dev/null
+++ b/libide/debugger/ide-debugger-plugin.c
@@ -0,0 +1,40 @@
+/* ide-debugger-plugin.c
+ *
+ * Copyright (C) 2017 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <libpeas/peas.h>
+
+#if 0
+#include "debugger/ide-debugger-editor-view-addin.h"
+#endif
+#include "debugger/ide-debugger-workbench-addin.h"
+#include "editor/ide-editor-view-addin.h"
+#include "workbench/ide-workbench-addin.h"
+
+void
+ide_debugger_register_types (PeasObjectModule *module)
+{
+#if 0
+ peas_object_module_register_extension_type (module,
+ IDE_TYPE_EDITOR_VIEW_ADDIN,
+ IDE_TYPE_DEBUGGER_EDITOR_VIEW_ADDIN);
+#endif
+
+ peas_object_module_register_extension_type (module,
+ IDE_TYPE_WORKBENCH_ADDIN,
+ IDE_TYPE_DEBUGGER_WORKBENCH_ADDIN);
+}
diff --git a/libide/debugger/ide-debugger-private.h b/libide/debugger/ide-debugger-private.h
index 3641bf3..fd20f5b 100644
--- a/libide/debugger/ide-debugger-private.h
+++ b/libide/debugger/ide-debugger-private.h
@@ -18,78 +18,82 @@
#pragma once
+#include "ide-debug-manager.h"
#include "ide-debugger.h"
+#include "ide-debugger-breakpoints.h"
G_BEGIN_DECLS
-void _ide_debugger_class_init_actions (GActionGroupInterface *iface);
-void _ide_debugger_update_actions (IdeDebugger *self);
-gboolean _ide_debugger_get_has_started (IdeDebugger *self);
-void _ide_debugger_real_list_frames_async (IdeDebugger *self,
- IdeDebuggerThread *thread,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-GPtrArray *_ide_debugger_real_list_frames_finish (IdeDebugger *self,
- GAsyncResult *result,
- GError **error);
-void _ide_debugger_real_interrupt_async (IdeDebugger *self,
- IdeDebuggerThreadGroup *thread_group,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-gboolean _ide_debugger_real_interrupt_finish (IdeDebugger *self,
- GAsyncResult *result,
- GError **error);
-void _ide_debugger_real_send_signal_async (IdeDebugger *self,
- gint signum,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-gboolean _ide_debugger_real_send_signal_finish (IdeDebugger *self,
- GAsyncResult *result,
- GError **error);
-void _ide_debugger_real_modify_breakpoint_async (IdeDebugger *self,
- IdeDebuggerBreakpointChange change,
- IdeDebuggerBreakpoint *breakpoint,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-gboolean _ide_debugger_real_modify_breakpoint_finish (IdeDebugger *self,
- GAsyncResult *result,
- GError **error);
-void _ide_debugger_real_list_params_async (IdeDebugger *self,
- IdeDebuggerThread *thread,
- IdeDebuggerFrame *frame,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-GPtrArray *_ide_debugger_real_list_params_finish (IdeDebugger *self,
- GAsyncResult *result,
- GError **error);
-void _ide_debugger_real_list_locals_async (IdeDebugger *self,
- IdeDebuggerThread *thread,
- IdeDebuggerFrame *frame,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-GPtrArray *_ide_debugger_real_list_locals_finish (IdeDebugger *self,
- GAsyncResult *result,
- GError **error);
-void _ide_debugger_real_list_registers_async (IdeDebugger *self,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-GPtrArray *_ide_debugger_real_list_registers_finish (IdeDebugger *self,
- GAsyncResult *result,
- GError **error);
-void _ide_debugger_real_disassemble_async (IdeDebugger *self,
- const IdeDebuggerAddressRange *range,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-GPtrArray *_ide_debugger_real_disassemble_finish (IdeDebugger *self,
- GAsyncResult *result,
- GError **error);
+IdeDebuggerBreakpoints *_ide_debug_manager_get_breakpoints (IdeDebugManager *self,
+ GFile *file);
+void _ide_debugger_class_init_actions (GActionGroupInterface *iface);
+void _ide_debugger_update_actions (IdeDebugger *self);
+gboolean _ide_debugger_get_has_started (IdeDebugger *self);
+void _ide_debugger_real_list_frames_async (IdeDebugger *self,
+ IdeDebuggerThread *thread,
+ GCancellable
*cancellable,
+ GAsyncReadyCallback
callback,
+ gpointer
user_data);
+GPtrArray *_ide_debugger_real_list_frames_finish (IdeDebugger *self,
+ GAsyncResult *result,
+ GError **error);
+void _ide_debugger_real_interrupt_async (IdeDebugger *self,
+ IdeDebuggerThreadGroup
*thread_group,
+ GCancellable
*cancellable,
+ GAsyncReadyCallback
callback,
+ gpointer
user_data);
+gboolean _ide_debugger_real_interrupt_finish (IdeDebugger *self,
+ GAsyncResult *result,
+ GError **error);
+void _ide_debugger_real_send_signal_async (IdeDebugger *self,
+ gint signum,
+ GCancellable
*cancellable,
+ GAsyncReadyCallback
callback,
+ gpointer
user_data);
+gboolean _ide_debugger_real_send_signal_finish (IdeDebugger *self,
+ GAsyncResult *result,
+ GError **error);
+void _ide_debugger_real_modify_breakpoint_async (IdeDebugger *self,
+ IdeDebuggerBreakpointChange change,
+ IdeDebuggerBreakpoint
*breakpoint,
+ GCancellable
*cancellable,
+ GAsyncReadyCallback
callback,
+ gpointer
user_data);
+gboolean _ide_debugger_real_modify_breakpoint_finish (IdeDebugger *self,
+ GAsyncResult *result,
+ GError **error);
+void _ide_debugger_real_list_params_async (IdeDebugger *self,
+ IdeDebuggerThread *thread,
+ IdeDebuggerFrame *frame,
+ GCancellable
*cancellable,
+ GAsyncReadyCallback
callback,
+ gpointer
user_data);
+GPtrArray *_ide_debugger_real_list_params_finish (IdeDebugger *self,
+ GAsyncResult *result,
+ GError **error);
+void _ide_debugger_real_list_locals_async (IdeDebugger *self,
+ IdeDebuggerThread *thread,
+ IdeDebuggerFrame *frame,
+ GCancellable
*cancellable,
+ GAsyncReadyCallback
callback,
+ gpointer
user_data);
+GPtrArray *_ide_debugger_real_list_locals_finish (IdeDebugger *self,
+ GAsyncResult *result,
+ GError **error);
+void _ide_debugger_real_list_registers_async (IdeDebugger *self,
+ GCancellable
*cancellable,
+ GAsyncReadyCallback
callback,
+ gpointer
user_data);
+GPtrArray *_ide_debugger_real_list_registers_finish (IdeDebugger *self,
+ GAsyncResult *result,
+ GError **error);
+void _ide_debugger_real_disassemble_async (IdeDebugger *self,
+ const IdeDebuggerAddressRange *range,
+ GCancellable
*cancellable,
+ GAsyncReadyCallback
callback,
+ gpointer
user_data);
+GPtrArray *_ide_debugger_real_disassemble_finish (IdeDebugger *self,
+ GAsyncResult *result,
+ GError **error);
G_END_DECLS
diff --git a/libide/debugger/ide-debugger-registers-view.ui b/libide/debugger/ide-debugger-registers-view.ui
new file mode 100644
index 0000000..eab4a2b
--- /dev/null
+++ b/libide/debugger/ide-debugger-registers-view.ui
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <template class="IdeDebuggerRegistersView" parent="GtkBin">
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">true</property>
+ <child>
+ <object class="GtkTreeView" id="tree_view">
+ <property name="model">list_store</property>
+ <property name="visible">true</property>
+ <child>
+ <object class="GtkTreeViewColumn" id="id_column">
+ <property name="title" translatable="yes">ID</property>
+ <child>
+ <object class="GtkCellRendererText" id="id_cell">
+ <property name="xalign">0.0</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="name_column">
+ <property name="title" translatable="yes">Register</property>
+ <child>
+ <object class="GtkCellRendererText" id="name_cell">
+ <property name="xalign">0.0</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="value_column">
+ <property name="expand">true</property>
+ <property name="title" translatable="yes">Value</property>
+ <child>
+ <object class="GtkCellRendererText" id="value_cell">
+ <property name="xalign">0.0</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </template>
+ <object class="GtkListStore" id="list_store">
+ <columns>
+ <column type="IdeDebuggerRegister"/>
+ </columns>
+ </object>
+</interface>
diff --git a/libide/debugger/ide-debugger-threads-view.ui b/libide/debugger/ide-debugger-threads-view.ui
new file mode 100644
index 0000000..b81c8b4
--- /dev/null
+++ b/libide/debugger/ide-debugger-threads-view.ui
@@ -0,0 +1,140 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <template class="IdeDebuggerThreadsView" parent="GtkBin">
+ <child>
+ <object class="DzlMultiPaned">
+ <property name="orientation">horizontal</property>
+ <property name="visible">true</property>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">true</property>
+ <child>
+ <object class="GtkTreeView" id="thread_groups_tree_view">
+ <property name="activate-on-single-click">true</property>
+ <property name="model">thread_groups_store</property>
+ <property name="visible">true</property>
+ <child>
+ <object class="GtkTreeViewColumn" id="group_column">
+ <property name="title" translatable="yes">Group</property>
+ <child>
+ <object class="GtkCellRendererText" id="group_cell">
+ <property name="xalign">0.0</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">true</property>
+ <child>
+ <object class="GtkTreeView" id="threads_tree_view">
+ <property name="activate-on-single-click">true</property>
+ <property name="model">threads_store</property>
+ <property name="visible">true</property>
+ <child>
+ <object class="GtkTreeViewColumn" id="thread_column">
+ <property name="title" translatable="yes">Thread</property>
+ <child>
+ <object class="GtkCellRendererText" id="thread_cell">
+ <property name="xalign">0.0</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">true</property>
+ <child>
+ <object class="GtkTreeView" id="frames_tree_view">
+ <property name="activate-on-single-click">true</property>
+ <property name="model">frames_store</property>
+ <property name="visible">true</property>
+ <child>
+ <object class="GtkTreeViewColumn" id="depth_column">
+ <property name="title" translatable="yes">Frame</property>
+ <child>
+ <object class="GtkCellRendererText" id="depth_cell">
+ <property name="xalign">0.0</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="function_column">
+ <property name="expand">true</property>
+ <property name="resizable">true</property>
+ <property name="title" translatable="yes">Function</property>
+ <child>
+ <object class="GtkCellRendererText" id="function_cell">
+ <property name="ellipsize">middle</property>
+ <property name="xalign">0.0</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="args_column">
+ <property name="resizable">true</property>
+ <property name="title" translatable="yes">Arguments</property>
+ <child>
+ <object class="GtkCellRendererText" id="args_cell">
+ <property name="ellipsize">middle</property>
+ <property name="xalign">0.0</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="location_column">
+ <property name="expand">true</property>
+ <property name="resizable">true</property>
+ <property name="title" translatable="yes">Location</property>
+ <child>
+ <object class="GtkCellRendererText" id="location_cell">
+ <property name="ellipsize">start</property>
+ <property name="xalign">0.0</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="binary_column">
+ <property name="title" translatable="yes">Binary</property>
+ <child>
+ <object class="GtkCellRendererText" id="binary_cell">
+ <property name="xalign">0.0</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </template>
+ <object class="GtkListStore" id="thread_groups_store">
+ <columns>
+ <column type="IdeDebuggerThreadGroup"/>
+ </columns>
+ </object>
+ <object class="GtkListStore" id="threads_store">
+ <columns>
+ <column type="IdeDebuggerThread"/>
+ </columns>
+ </object>
+ <object class="GtkListStore" id="frames_store">
+ <columns>
+ <column type="IdeDebuggerFrame"/>
+ </columns>
+ </object>
+</interface>
diff --git a/libide/debugger/ide-debugger-types.c b/libide/debugger/ide-debugger-types.c
index 80cd7c5..47b92c1 100644
--- a/libide/debugger/ide-debugger-types.c
+++ b/libide/debugger/ide-debugger-types.c
@@ -102,6 +102,7 @@ ide_debugger_break_mode_get_type (void)
{
GType _type_id;
static const GEnumValue values[] = {
+ { IDE_DEBUGGER_BREAK_NONE, "IDE_DEBUGGER_BREAK_NONE", "none" },
{ IDE_DEBUGGER_BREAK_BREAKPOINT, "IDE_DEBUGGER_BREAK_BREAKPOINT", "breakpoint" },
{ IDE_DEBUGGER_BREAK_COUNTPOINT, "IDE_DEBUGGER_BREAK_COUNTPOINT", "countpoint" },
{ IDE_DEBUGGER_BREAK_WATCHPOINT, "IDE_DEBUGGER_BREAK_WATCHPOINT", "watchpoint" },
diff --git a/libide/debugger/ide-debugger-types.h b/libide/debugger/ide-debugger-types.h
index a2a1353..96435c1 100644
--- a/libide/debugger/ide-debugger-types.h
+++ b/libide/debugger/ide-debugger-types.h
@@ -104,6 +104,7 @@ typedef enum
/**
* IdeDebuggerBreakMode:
+ * @IDE_DEBUGGER_BREAK_NONE: No breakpoint is set
* @IDE_DEBUGGER_BREAK_BREAKPOINT: A simple breakpoint that stops the debugger
* when reaching a given location.
* @IDE_DEBUGGER_BREAK_COUNTPOINT: A counter that is incremented when the
@@ -115,6 +116,7 @@ typedef enum
*/
typedef enum
{
+ IDE_DEBUGGER_BREAK_NONE = 0,
IDE_DEBUGGER_BREAK_BREAKPOINT,
IDE_DEBUGGER_BREAK_COUNTPOINT,
IDE_DEBUGGER_BREAK_WATCHPOINT,
diff --git a/libide/debugger/ide-debugger-view.c b/libide/debugger/ide-debugger-view.c
new file mode 100644
index 0000000..69149cc
--- /dev/null
+++ b/libide/debugger/ide-debugger-view.c
@@ -0,0 +1,155 @@
+/* ide-debugger-view.c
+ *
+ * Copyright (C) 2017 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define G_LOG_DOMAIN "ide-debugger-view"
+
+#include <gtksourceview/gtksource.h>
+
+#include "ide-debug.h"
+
+#include "buffers/ide-buffer.h"
+#include "debugger/ide-debugger-gutter-renderer.h"
+#include "debugger/ide-debugger-view.h"
+
+struct _IdeDebuggerView
+{
+ IdeLayoutView parent_instance;
+
+ GtkSourceView *source_view;
+ IdeDebuggerGutterRenderer *breakpoints_gutter;
+};
+
+enum {
+ PROP_0,
+ PROP_BUFFER,
+ N_PROPS
+};
+
+G_DEFINE_TYPE (IdeDebuggerView, ide_debugger_view, IDE_TYPE_LAYOUT_VIEW)
+
+static GParamSpec *properties [N_PROPS];
+
+static void
+ide_debugger_view_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ IdeDebuggerView *self = IDE_DEBUGGER_VIEW (object);
+
+ switch (prop_id)
+ {
+ case PROP_BUFFER:
+ g_value_set_object (value, ide_debugger_view_get_buffer (self));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+ide_debugger_view_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ IdeDebuggerView *self = IDE_DEBUGGER_VIEW (object);
+
+ switch (prop_id)
+ {
+ case PROP_BUFFER:
+ ide_debugger_view_set_buffer (self, g_value_get_object (value));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+ide_debugger_view_class_init (IdeDebuggerViewClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ object_class->get_property = ide_debugger_view_get_property;
+ object_class->set_property = ide_debugger_view_set_property;
+
+ properties [PROP_BUFFER] =
+ g_param_spec_object ("buffer",
+ "Buffer",
+ "The buffer for the view",
+ GTK_SOURCE_TYPE_BUFFER,
+ (G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_properties (object_class, N_PROPS, properties);
+
+ gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/builder/ui/ide-debugger-view.ui");
+ gtk_widget_class_bind_template_child (widget_class, IdeDebuggerView, source_view);
+}
+
+static void
+ide_debugger_view_init (IdeDebuggerView *self)
+{
+ GtkSourceGutter *gutter;
+
+ gtk_widget_init_template (GTK_WIDGET (self));
+
+ gutter = gtk_source_view_get_gutter (GTK_SOURCE_VIEW (self->source_view), GTK_TEXT_WINDOW_LEFT);
+ self->breakpoints_gutter = g_object_new (IDE_TYPE_DEBUGGER_GUTTER_RENDERER,
+ "visible", TRUE,
+ NULL);
+ gtk_source_gutter_insert (gutter, GTK_SOURCE_GUTTER_RENDERER (self->breakpoints_gutter), -100);
+}
+
+GtkWidget *
+ide_debugger_view_new (void)
+{
+ return g_object_new (IDE_TYPE_DEBUGGER_VIEW, NULL);
+}
+
+/**
+ * ide_debugger_view_get_buffer:
+ * @self: a #IdeDebuggerView
+ *
+ * Gets the buffer for the view.
+ *
+ * Returns: (transfer none): A #GtkSourceBuffer
+ */
+GtkSourceBuffer *
+ide_debugger_view_get_buffer (IdeDebuggerView *self)
+{
+ g_return_val_if_fail (IDE_IS_DEBUGGER_VIEW (self), NULL);
+
+ return GTK_SOURCE_BUFFER (gtk_text_view_get_buffer (GTK_TEXT_VIEW (self->source_view)));
+}
+
+void
+ide_debugger_view_set_buffer (IdeDebuggerView *self,
+ GtkSourceBuffer *buffer)
+{
+ g_return_if_fail (IDE_IS_DEBUGGER_VIEW (self));
+ g_return_if_fail (GTK_SOURCE_IS_BUFFER (buffer));
+
+ if (buffer != ide_debugger_view_get_buffer (self))
+ {
+ gtk_text_view_set_buffer (GTK_TEXT_VIEW (self->source_view), GTK_TEXT_BUFFER (buffer));
+ g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_BUFFER]);
+ }
+}
diff --git a/libide/debugger/ide-debugger-view.h b/libide/debugger/ide-debugger-view.h
new file mode 100644
index 0000000..5151c04
--- /dev/null
+++ b/libide/debugger/ide-debugger-view.h
@@ -0,0 +1,36 @@
+/* ide-debugger-view.h
+ *
+ * Copyright (C) 2017 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include <gtksourceview/gtksource.h>
+
+#include "layout/ide-layout-view.h"
+
+G_BEGIN_DECLS
+
+#define IDE_TYPE_DEBUGGER_VIEW (ide_debugger_view_get_type())
+
+G_DECLARE_FINAL_TYPE (IdeDebuggerView, ide_debugger_view, IDE, DEBUGGER_VIEW, IdeLayoutView)
+
+GtkWidget *ide_debugger_view_new (void);
+GtkSourceBuffer *ide_debugger_view_get_buffer (IdeDebuggerView *self);
+void ide_debugger_view_set_buffer (IdeDebuggerView *self,
+ GtkSourceBuffer *buffer);
+
+G_END_DECLS
diff --git a/libide/debugger/ide-debugger-view.ui b/libide/debugger/ide-debugger-view.ui
new file mode 100644
index 0000000..42c911e
--- /dev/null
+++ b/libide/debugger/ide-debugger-view.ui
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<interface>
+ <template class="IdeDebuggerView" parent="IdeLayoutView">
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="expand">true</property>
+ <property name="visible">true</property>
+ <child>
+ <object class="GtkSourceView" id="source_view">
+ <property name="highlight-current-line">true</property>
+ <property name="show-line-numbers">true</property>
+ <property name="monospace">true</property>
+ <property name="editable">false</property>
+ <property name="visible">true</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </template>
+</interface>
diff --git a/libide/debugger/ide-debugger-workbench-addin.c b/libide/debugger/ide-debugger-workbench-addin.c
new file mode 100644
index 0000000..e6f5161
--- /dev/null
+++ b/libide/debugger/ide-debugger-workbench-addin.c
@@ -0,0 +1,260 @@
+/* ide-debugger-workbench-addin.c
+ *
+ * Copyright (C) 2017 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define G_LOG_DOMAIN "ide-debugger-workbench-addin"
+
+#include <dazzle.h>
+#include <glib/gi18n.h>
+#include <gtksourceview/gtksource.h>
+
+#include "ide-context.h"
+#include "ide-debug.h"
+
+#include "debugger/ide-debug-manager.h"
+#include "debugger/ide-debugger-controls.h"
+#include "debugger/ide-debugger-perspective.h"
+#include "debugger/ide-debugger-workbench-addin.h"
+#include "runner/ide-run-manager.h"
+#include "workbench/ide-workbench-addin.h"
+#include "workbench/ide-workbench-message.h"
+
+struct _IdeDebuggerWorkbenchAddin
+{
+ GObject parent_instance;
+ IdeWorkbench *workbench;
+ IdeDebuggerControls *controls;
+ IdeWorkbenchMessage *message;
+ IdeDebuggerPerspective *perspective;
+ DzlSignalGroup *debug_manager_signals;
+};
+
+static void
+debugger_run_handler (IdeRunManager *run_manager,
+ IdeRunner *runner,
+ gpointer user_data)
+{
+ IdeDebuggerWorkbenchAddin *self = user_data;
+ IdeDebugManager *debug_manager;
+ IdeContext *context;
+ g_autoptr(GError) error = NULL;
+
+ IDE_ENTRY;
+
+ g_assert (IDE_IS_RUN_MANAGER (run_manager));
+ g_assert (IDE_IS_RUNNER (runner));
+ g_assert (IDE_IS_DEBUGGER_WORKBENCH_ADDIN (self));
+
+ ide_workbench_set_visible_perspective_name (self->workbench, "debugger");
+
+ /*
+ * Get the currently configured debugger and attach it to our runner.
+ * It might need to prepend arguments like `gdb', `pdb', `mdb', etc.
+ */
+ context = ide_object_get_context (IDE_OBJECT (run_manager));
+ debug_manager = ide_context_get_debug_manager (context);
+
+ if (!ide_debug_manager_start (debug_manager, runner, &error))
+ {
+ ide_workbench_message_set_subtitle (self->message, error->message);
+ gtk_widget_show (GTK_WIDGET (self->message));
+ }
+
+ IDE_EXIT;
+}
+
+static void
+debug_manager_notify_debugger (IdeDebuggerWorkbenchAddin *self,
+ GParamSpec *pspec,
+ IdeDebugManager *debug_manager)
+{
+ IdeDebugger *debugger;
+
+ g_assert (IDE_IS_DEBUGGER_WORKBENCH_ADDIN (self));
+ g_assert (IDE_IS_DEBUG_MANAGER (debug_manager));
+
+ debugger = ide_debug_manager_get_debugger (debug_manager);
+
+ gtk_widget_insert_action_group (GTK_WIDGET (self->workbench),
+ "debugger",
+ G_ACTION_GROUP (debugger));
+}
+
+static void
+debug_manager_notify_active (IdeDebuggerWorkbenchAddin *self,
+ GParamSpec *pspec,
+ IdeDebugManager *debug_manager)
+{
+ g_assert (IDE_IS_DEBUGGER_WORKBENCH_ADDIN (self));
+ g_assert (IDE_IS_DEBUG_MANAGER (debug_manager));
+
+ /*
+ * Instead of using a property binding, we use this signal callback so
+ * that we can adjust the reveal-child and visible. Otherwise the widgets
+ * will take up space+padding when reveal-child is FALSE.
+ */
+
+ if (ide_debug_manager_get_active (debug_manager))
+ {
+ gtk_widget_show (GTK_WIDGET (self->controls));
+ gtk_revealer_set_reveal_child (GTK_REVEALER (self->controls), TRUE);
+ }
+ else
+ {
+ gtk_revealer_set_reveal_child (GTK_REVEALER (self->controls), FALSE);
+ }
+}
+
+static void
+controls_notify_child_revealed (IdeDebuggerWorkbenchAddin *self,
+ GParamSpec *pspec,
+ IdeDebuggerControls *controls)
+{
+ g_assert (IDE_IS_DEBUGGER_WORKBENCH_ADDIN (self));
+ g_assert (IDE_IS_DEBUGGER_CONTROLS (controls));
+
+ if (!gtk_revealer_get_child_revealed (GTK_REVEALER (controls)))
+ gtk_widget_hide (GTK_WIDGET (controls));
+}
+
+static void
+ide_debugger_workbench_addin_load (IdeWorkbenchAddin *addin,
+ IdeWorkbench *workbench)
+{
+ IdeDebuggerWorkbenchAddin *self = (IdeDebuggerWorkbenchAddin *)addin;
+ IdeWorkbenchHeaderBar *headerbar;
+ IdeDebugManager *debug_manager;
+ IdeRunManager *run_manager;
+ IdeContext *context;
+
+ g_assert (IDE_IS_WORKBENCH_ADDIN (addin));
+ g_assert (IDE_IS_WORKBENCH (workbench));
+
+ self->workbench = workbench;
+
+ context = ide_workbench_get_context (workbench);
+ debug_manager = ide_context_get_debug_manager (context);
+ run_manager = ide_context_get_run_manager (context);
+
+ headerbar = ide_workbench_get_headerbar (workbench);
+
+ self->debug_manager_signals = dzl_signal_group_new (IDE_TYPE_DEBUG_MANAGER);
+
+ dzl_signal_group_connect_swapped (self->debug_manager_signals,
+ "notify::active",
+ G_CALLBACK (debug_manager_notify_active),
+ self);
+
+ dzl_signal_group_connect_swapped (self->debug_manager_signals,
+ "notify::debugger",
+ G_CALLBACK (debug_manager_notify_debugger),
+ self);
+
+ dzl_signal_group_set_target (self->debug_manager_signals, debug_manager);
+
+ self->controls = g_object_new (IDE_TYPE_DEBUGGER_CONTROLS,
+ "transition-duration", 500,
+ "transition-type", GTK_REVEALER_TRANSITION_TYPE_SLIDE_RIGHT,
+ "reveal-child", FALSE,
+ "visible", FALSE,
+ NULL);
+ g_signal_connect_object (self->controls,
+ "notify::child-revealed",
+ G_CALLBACK (controls_notify_child_revealed),
+ self,
+ G_CONNECT_SWAPPED);
+ ide_workbench_header_bar_insert_left (headerbar,
+ GTK_WIDGET (self->controls),
+ GTK_PACK_START,
+ 100);
+
+ ide_run_manager_add_handler (run_manager,
+ "debugger",
+ _("Run with Debugger"),
+ "builder-debugger-symbolic",
+ "F5",
+ debugger_run_handler,
+ g_object_ref (self),
+ g_object_unref);
+
+ self->perspective = g_object_new (IDE_TYPE_DEBUGGER_PERSPECTIVE,
+ "visible", TRUE,
+ NULL);
+ g_object_bind_property (debug_manager, "debugger",
+ self->perspective, "debugger",
+ G_BINDING_SYNC_CREATE);
+ ide_workbench_add_perspective (workbench, IDE_PERSPECTIVE (self->perspective));
+
+ self->message = g_object_new (IDE_TYPE_WORKBENCH_MESSAGE,
+ "id", "org.gnome.builder.debugger.failure",
+ "show-close-button", TRUE,
+ "title", _("Failed to initialize the debugger"),
+ NULL);
+ ide_workbench_push_message (workbench, self->message);
+}
+
+static void
+ide_debugger_workbench_addin_unload (IdeWorkbenchAddin *addin,
+ IdeWorkbench *workbench)
+{
+ IdeDebuggerWorkbenchAddin *self = (IdeDebuggerWorkbenchAddin *)addin;
+ IdeRunManager *run_manager;
+ IdeContext *context;
+
+ g_assert (IDE_IS_WORKBENCH_ADDIN (addin));
+ g_assert (IDE_IS_WORKBENCH (workbench));
+
+ context = ide_workbench_get_context (workbench);
+ run_manager = ide_context_get_run_manager (context);
+
+ g_clear_object (&self->debug_manager_signals);
+
+ /* Remove the handler to initiate the debugger */
+ ide_run_manager_remove_handler (run_manager, "debugger");
+
+ /* Remove our debugger control widgets */
+ g_clear_pointer (&self->controls, gtk_widget_destroy);
+
+ /* Remove actions from activation */
+ gtk_widget_insert_action_group (GTK_WIDGET (workbench), "debugger", NULL);
+
+ /* Remove the debugging perspective from the UI */
+ ide_workbench_remove_perspective (workbench, IDE_PERSPECTIVE (self->perspective));
+ self->perspective = NULL;
+
+ self->workbench = NULL;
+}
+
+static void
+workbench_addin_iface_init (IdeWorkbenchAddinInterface *iface)
+{
+ iface->load = ide_debugger_workbench_addin_load;
+ iface->unload = ide_debugger_workbench_addin_unload;
+}
+
+G_DEFINE_TYPE_WITH_CODE (IdeDebuggerWorkbenchAddin, ide_debugger_workbench_addin, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (IDE_TYPE_WORKBENCH_ADDIN, workbench_addin_iface_init))
+
+static void
+ide_debugger_workbench_addin_class_init (IdeDebuggerWorkbenchAddinClass *klass)
+{
+}
+
+static void
+ide_debugger_workbench_addin_init (IdeDebuggerWorkbenchAddin *self)
+{
+}
diff --git a/libide/debugger/ide-debugger-workbench-addin.h b/libide/debugger/ide-debugger-workbench-addin.h
new file mode 100644
index 0000000..df10b61
--- /dev/null
+++ b/libide/debugger/ide-debugger-workbench-addin.h
@@ -0,0 +1,29 @@
+/* ide-debugger-workbench-addin.h
+ *
+ * Copyright (C) 2017 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define IDE_TYPE_DEBUGGER_WORKBENCH_ADDIN (ide_debugger_workbench_addin_get_type())
+
+G_DECLARE_FINAL_TYPE (IdeDebuggerWorkbenchAddin, ide_debugger_workbench_addin, IDE,
DEBUGGER_WORKBENCH_ADDIN, GObject)
+
+G_END_DECLS
diff --git a/libide/ide-context.h b/libide/ide-context.h
index 7c6c50f..55a06ae 100644
--- a/libide/ide-context.h
+++ b/libide/ide-context.h
@@ -36,6 +36,7 @@ IdeBufferManager *ide_context_get_buffer_manager (IdeContext
IdeBuildManager *ide_context_get_build_manager (IdeContext *self);
IdeBuildSystem *ide_context_get_build_system (IdeContext *self);
IdeConfigurationManager *ide_context_get_configuration_manager (IdeContext *self);
+IdeDebugManager *ide_context_get_debug_manager (IdeContext *self);
IdeDiagnosticsManager *ide_context_get_diagnostics_manager (IdeContext *self);
IdeDeviceManager *ide_context_get_device_manager (IdeContext *self);
IdeDocumentation *ide_context_get_documentation (IdeContext *self);
diff --git a/libide/ide-types.h b/libide/ide-types.h
index 9a02b4a..0661c15 100644
--- a/libide/ide-types.h
+++ b/libide/ide-types.h
@@ -47,6 +47,14 @@ typedef struct _IdeConfigurationManager IdeConfigurationManager;
typedef struct _IdeContext IdeContext;
+typedef struct _IdeDebugManager IdeDebugManager;
+typedef struct _IdeDebugger IdeDebugger;
+typedef struct _IdeDebuggerBreakpoint IdeDebuggerBreakpoint;
+typedef struct _IdeDebuggerFrame IdeDebuggerFrame;
+typedef struct _IdeDebuggerInstruction IdeDebuggerInstruction;
+typedef struct _IdeDebuggerRegister IdeDebuggerRegister;
+typedef struct _IdeDebuggerVariable IdeDebuggerVariable;
+
typedef struct _IdeDevice IdeDevice;
typedef struct _IdeDeviceManager IdeDeviceManager;
typedef struct _IdeDeviceProvider IdeDeviceProvider;
diff --git a/libide/libide.gresource.xml b/libide/libide.gresource.xml
index f3d97a5..0a4a9b9 100644
--- a/libide/libide.gresource.xml
+++ b/libide/libide.gresource.xml
@@ -55,6 +55,14 @@
</gresource>
<gresource prefix="/org/gnome/builder/ui">
+ <file compressed="true" preprocess="xml-stripblanks"
alias="ide-debugger-breakpoints-view.ui">debugger/ide-debugger-breakpoints-view.ui</file>
+ <file compressed="true" preprocess="xml-stripblanks"
alias="ide-debugger-controls.ui">debugger/ide-debugger-controls.ui</file>
+ <file compressed="true" preprocess="xml-stripblanks"
alias="ide-debugger-libraries-view.ui">debugger/ide-debugger-libraries-view.ui</file>
+ <file compressed="true" preprocess="xml-stripblanks"
alias="ide-debugger-locals-view.ui">debugger/ide-debugger-locals-view.ui</file>
+ <file compressed="true" preprocess="xml-stripblanks"
alias="ide-debugger-perspective.ui">debugger/ide-debugger-perspective.ui</file>
+ <file compressed="true" preprocess="xml-stripblanks"
alias="ide-debugger-registers-view.ui">debugger/ide-debugger-registers-view.ui</file>
+ <file compressed="true" preprocess="xml-stripblanks"
alias="ide-debugger-threads-view.ui">debugger/ide-debugger-threads-view.ui</file>
+ <file compressed="true" preprocess="xml-stripblanks"
alias="ide-debugger-view.ui">debugger/ide-debugger-view.ui</file>
<file compressed="true" preprocess="xml-stripblanks"
alias="ide-layout-pane.ui">layout/ide-layout-pane.ui</file>
<file compressed="true" preprocess="xml-stripblanks"
alias="ide-layout-stack-header.ui">layout/ide-layout-stack-header.ui</file>
<file compressed="true" preprocess="xml-stripblanks"
alias="ide-layout-stack.ui">layout/ide-layout-stack.ui</file>
@@ -83,6 +91,10 @@
<file alias="buildconfig.plugin">buildconfig/buildconfig.plugin</file>
</gresource>
+ <gresource prefix="/org/gnome/builder/plugins/debugger">
+ <file alias="debugger.plugin">debugger/debugger.plugin</file>
+ </gresource>
+
<gresource prefix="/org/gnome/builder/plugins/editor">
<file alias="editor.plugin">editor/editor.plugin</file>
</gresource>
diff --git a/libide/meson.build b/libide/meson.build
index 7809d5d..260ec67 100644
--- a/libide/meson.build
+++ b/libide/meson.build
@@ -90,6 +90,7 @@ libide_public_headers = [
'debugger/ide-debugger-frame.h',
'debugger/ide-debugger-instruction.h',
'debugger/ide-debugger-library.h',
+ 'debugger/ide-debugger-perspective.h',
'debugger/ide-debugger-register.h',
'debugger/ide-debugger-thread-group.h',
'debugger/ide-debugger-thread.h',
@@ -306,6 +307,7 @@ libide_public_sources = [
'debugger/ide-debugger-frame.c',
'debugger/ide-debugger-instruction.c',
'debugger/ide-debugger-library.c',
+ 'debugger/ide-debugger-perspective.c',
'debugger/ide-debugger-register.c',
'debugger/ide-debugger-thread-group.c',
'debugger/ide-debugger-thread.c',
@@ -515,16 +517,27 @@ libide_sources = libide_generated_headers + libide_public_sources + [
'debugger/ide-debugger-address-map.h',
'debugger/ide-debugger-breakpoints-view.c',
'debugger/ide-debugger-breakpoints-view.h',
+ 'debugger/ide-debugger-controls.c',
+ 'debugger/ide-debugger-controls.h',
'debugger/ide-debugger-fallbacks.c',
+ 'debugger/ide-debugger-breakpoints.c',
+ 'debugger/ide-debugger-breakpoints.h',
+ 'debugger/ide-debugger-gutter-renderer.c',
+ 'debugger/ide-debugger-gutter-renderer.h',
'debugger/ide-debugger-libraries-view.c',
'debugger/ide-debugger-libraries-view.h',
'debugger/ide-debugger-locals-view.c',
'debugger/ide-debugger-locals-view.h',
+ 'debugger/ide-debugger-plugin.c',
'debugger/ide-debugger-private.h',
'debugger/ide-debugger-registers-view.c',
'debugger/ide-debugger-registers-view.h',
'debugger/ide-debugger-threads-view.c',
'debugger/ide-debugger-threads-view.h',
+ 'debugger/ide-debugger-view.c',
+ 'debugger/ide-debugger-view.h',
+ 'debugger/ide-debugger-workbench-addin.c',
+ 'debugger/ide-debugger-workbench-addin.h',
'editor/ide-editor-layout-stack-addin.c',
'editor/ide-editor-layout-stack-addin.h',
'editor/ide-editor-layout-stack-controls.c',
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]