mirror of
https://github.com/tromey/gdb-gui.git
synced 2025-12-16 07:10:04 +01:00
move to pygobject and glade
This ports the code to PyGObject, and also changes it to use Glade to edit the user interface elements.
This commit is contained in:
10
README
10
README
@@ -15,14 +15,14 @@ GUIs in a few ways:
|
||||
|
||||
|
||||
To get started, install the prerequisites. You'll need a
|
||||
Python-enabled gdb, PyGtk, and PyGktSourceView. (And maybe more -- if
|
||||
you trip across something, let me know.) You'll need the Python
|
||||
Python-enabled gdb, PyGObject, and PyGktSourceView. (And maybe more
|
||||
-- if you trip across something, let me know.) You'll need the Python
|
||||
development package to compile the small C module that is included
|
||||
here.
|
||||
|
||||
On Fedora I think this suffices:
|
||||
|
||||
sudo yum install gdb python-devel pygtksourceview pygtk2
|
||||
sudo yum install gdb python-devel gtksourceview3 pygobject3
|
||||
|
||||
After you install this, type "make". Now, start gdb and source the
|
||||
"SourceMe.py" file. This sets everything up.
|
||||
@@ -31,3 +31,7 @@ This adds a new "gui" command to gdb. Currently the only subcommand
|
||||
is "gui source", which pops up a source window. The source window
|
||||
will automatically track your progress when debugging. You can make
|
||||
multiple source windows; they will be reused in an LRU fashion.
|
||||
|
||||
If you want to hack on this, you will need Glade to edit the UI
|
||||
elements. For Fedora 18, you'll need a special hack to make the
|
||||
gtksourceview widget visible to Glade.
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
# Copyright (C) 2013 Tom Tromey <tom@tromey.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/>.
|
||||
|
||||
import os.path
|
||||
|
||||
self_dir = os.path.abspath(os.path.dirname(__file__))
|
||||
|
||||
1
gui/icons/README
Normal file
1
gui/icons/README
Normal file
@@ -0,0 +1 @@
|
||||
These icons were shamelessly taken from nemiver.
|
||||
BIN
gui/icons/breakpoint-disabled-marker.png
Normal file
BIN
gui/icons/breakpoint-disabled-marker.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 586 B |
BIN
gui/icons/breakpoint-marker.png
Normal file
BIN
gui/icons/breakpoint-marker.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 710 B |
BIN
gui/icons/countpoint-marker.png
Normal file
BIN
gui/icons/countpoint-marker.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 241 B |
BIN
gui/icons/line-pointer.png
Normal file
BIN
gui/icons/line-pointer.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 601 B |
40
gui/icons/run-to-cursor.xpm
Normal file
40
gui/icons/run-to-cursor.xpm
Normal file
@@ -0,0 +1,40 @@
|
||||
/* XPM */
|
||||
static char * run_to_cursor_xpm[] = {
|
||||
"22 22 15 1",
|
||||
" c None",
|
||||
". c #4A4A4A",
|
||||
"+ c #BABABA",
|
||||
"@ c #C0C0C0",
|
||||
"# c #9C9C9C",
|
||||
"$ c #000000",
|
||||
"% c #CCCCCC",
|
||||
"& c #D4D4D4",
|
||||
"* c #D7D7D8",
|
||||
"= c #DCDCDC",
|
||||
"- c #E3E3E3",
|
||||
"; c #EBEBEB",
|
||||
"> c #F4F3F3",
|
||||
", c #FEFEFE",
|
||||
"' c #B72618",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ........... ",
|
||||
" .++++++++@.# ",
|
||||
" .+++++@@@@.## ",
|
||||
" .++@@$$@%%.... ",
|
||||
" .@@@%$$%&&*==. ",
|
||||
" .%%%%$$&*==--. ",
|
||||
" .%&&*$$=---;;. ",
|
||||
" .&*==$$;;;;>;. ",
|
||||
" .=-$$$$$$>>,,. ",
|
||||
" .;;;$$$$>,,,,. ",
|
||||
" .;;>>$$,,,,,,. ",
|
||||
" .>'''''''''',. ",
|
||||
" .,'''''''''',. ",
|
||||
" .,,,,,,,,,,,,. ",
|
||||
" .,,,,,,,,,,,,. ",
|
||||
" .............. ",
|
||||
" ",
|
||||
" ",
|
||||
" "};
|
||||
52
gui/icons/set-breakpoint.xpm
Normal file
52
gui/icons/set-breakpoint.xpm
Normal file
@@ -0,0 +1,52 @@
|
||||
/* XPM */
|
||||
static char * breakpoint_xpm[] = {
|
||||
"22 22 27 1",
|
||||
" c None",
|
||||
". c #394248",
|
||||
"+ c #B1B5B8",
|
||||
"@ c #B6B9BC",
|
||||
"# c #B8BBBE",
|
||||
"$ c #C0C0C0",
|
||||
"% c #C6C9CB",
|
||||
"& c #CBCED0",
|
||||
"* c #D1D3D5",
|
||||
"= c #BBBEC1",
|
||||
"- c #BDC1C3",
|
||||
"; c #C3C7C8",
|
||||
"> c #C9CBCD",
|
||||
", c #D4D6D8",
|
||||
"' c #D6D8DA",
|
||||
") c #0C1115",
|
||||
"! c #DADCDD",
|
||||
"~ c #DEE0E1",
|
||||
"{ c #E2E3E5",
|
||||
"] c #E6E7E8",
|
||||
"^ c #E7E8E9",
|
||||
"/ c #EBECED",
|
||||
"( c #FF0000",
|
||||
"_ c #000000",
|
||||
": c #F3F4F4",
|
||||
"< c #F7F8F9",
|
||||
"[ c #FDFDFD",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ................ ",
|
||||
" .++++++@#$$%%&*. ",
|
||||
" .++++@#=-;%>&,'. ",
|
||||
" .++))))))))))'!. ",
|
||||
" .+@#=-;>&*,'!~{. ",
|
||||
" .#=))))&,,!~{]^. ",
|
||||
" .-;;;,,/////^//. ",
|
||||
" .;(((((/)))__::. ",
|
||||
" .>(((((/////:<[. ",
|
||||
" .*(((((/))))<[[. ",
|
||||
" .'(((((/:<<[[[[. ",
|
||||
" .!(((((:_____[[. ",
|
||||
" .{]/:::<[[[[[[[. ",
|
||||
" .//))))))[[[[[[. ",
|
||||
" .::<<[[[[[[[[[[. ",
|
||||
" ................ ",
|
||||
" ",
|
||||
" ",
|
||||
" "};
|
||||
28
gui/icons/step-into.xpm
Normal file
28
gui/icons/step-into.xpm
Normal file
@@ -0,0 +1,28 @@
|
||||
/* XPM */
|
||||
static char * step_in_xpm[] = {
|
||||
"22 22 3 1",
|
||||
" c None",
|
||||
". c #FF0000",
|
||||
"+ c #000000",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ......... ",
|
||||
" ......... ",
|
||||
" .. ",
|
||||
" ++ .. ++ ",
|
||||
" ++......++ ",
|
||||
" ++ .... ++ ",
|
||||
" ++ .. ++ ",
|
||||
" ++ ++ ",
|
||||
" ++ ++ ",
|
||||
" ++ ++ ",
|
||||
" ++ ++ ",
|
||||
" ++ ++ ",
|
||||
" ++ ++ ",
|
||||
" ++ ++ ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" "};
|
||||
28
gui/icons/step-out.xpm
Normal file
28
gui/icons/step-out.xpm
Normal file
@@ -0,0 +1,28 @@
|
||||
/* XPM */
|
||||
static char * step_out_xpm[] = {
|
||||
"22 22 3 1",
|
||||
" c None",
|
||||
". c #FF0000",
|
||||
"+ c #000000",
|
||||
" ",
|
||||
" ",
|
||||
" . ",
|
||||
" .. ",
|
||||
" ......... ",
|
||||
" ......... ",
|
||||
" .. .. ",
|
||||
" ++ .. ++ . ",
|
||||
" ++ .. ++ ",
|
||||
" ++ .. ++ ",
|
||||
" ++ .. ++ ",
|
||||
" ++ ++ ",
|
||||
" ++ ++ ",
|
||||
" ++ ++ ",
|
||||
" ++ ++ ",
|
||||
" ++ ++ ",
|
||||
" ++ ++ ",
|
||||
" ++ ++ ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" "};
|
||||
28
gui/icons/step-over.xpm
Normal file
28
gui/icons/step-over.xpm
Normal file
@@ -0,0 +1,28 @@
|
||||
/* XPM */
|
||||
static char * step_over_xpm[] = {
|
||||
"22 22 3 1",
|
||||
" c None",
|
||||
". c #FF0000",
|
||||
"+ c #000000",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" . ",
|
||||
" .. ",
|
||||
" ................ ",
|
||||
" ................ ",
|
||||
" .. ",
|
||||
" ++ ++ . ",
|
||||
" ++ ++ ",
|
||||
" ++ ++ ",
|
||||
" ++ ++ ",
|
||||
" ++ ++ ",
|
||||
" ++ ++ ",
|
||||
" ++ ++ ",
|
||||
" ++ ++ ",
|
||||
" ++ ++ ",
|
||||
" ++ ++ ",
|
||||
" ++ ++ ",
|
||||
" ",
|
||||
" ",
|
||||
" "};
|
||||
BIN
gui/icons/throbber.gif
Normal file
BIN
gui/icons/throbber.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.5 KiB |
31
gui/invoker.py
Normal file
31
gui/invoker.py
Normal file
@@ -0,0 +1,31 @@
|
||||
# Copyright (C) 2013 Tom Tromey <tom@tromey.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/>.
|
||||
|
||||
import gdb
|
||||
|
||||
class Invoker(object):
|
||||
"""A simple class that can invoke a gdb command.
|
||||
This is suitable for use as an event handler in Gtk."""
|
||||
|
||||
def __init__(self, cmd):
|
||||
self.cmd = cmd
|
||||
|
||||
# This is invoked in the gdb thread to run the command.
|
||||
def do_call(self):
|
||||
gdb.execute(self.cmd, from_tty = True, to_string = True)
|
||||
|
||||
# The object itself is the Gtk event handler.
|
||||
def __call__(self, *args):
|
||||
gdb.post_event(self.do_call)
|
||||
@@ -16,9 +16,11 @@
|
||||
# Source view.
|
||||
|
||||
import gdb
|
||||
from gui.invoker import Invoker
|
||||
import gui.startup
|
||||
import gtksourceview2 as gtksourceview
|
||||
import gtk
|
||||
import os.path
|
||||
|
||||
from gi.repository import Gtk, GtkSource, GObject
|
||||
|
||||
class BufferManager:
|
||||
def __init__(self):
|
||||
@@ -32,7 +34,7 @@ class BufferManager:
|
||||
if filename in self.buffers:
|
||||
return self.buffers[filename]
|
||||
|
||||
buff = gtksourceview.Buffer()
|
||||
buff = GtkSource.Buffer()
|
||||
buff.begin_not_undoable_action()
|
||||
try:
|
||||
contents = open(filename).read()
|
||||
@@ -142,30 +144,25 @@ class SourceWindow:
|
||||
def __init__(self):
|
||||
self.frame = None
|
||||
|
||||
# FIXME: set the size
|
||||
# stuff in margins
|
||||
self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
|
||||
self.window.set_border_width(0)
|
||||
self.window.set_title('GDB Source')
|
||||
self.window.set_size_request(600, 400)
|
||||
self.do_step = Invoker("step")
|
||||
self.do_next = Invoker("next")
|
||||
self.do_continue = Invoker("continue")
|
||||
|
||||
vbox = gtk.VBox(0, False)
|
||||
swin = gtk.ScrolledWindow()
|
||||
self.view = gtksourceview.View()
|
||||
self.view.set_editable(False)
|
||||
self.view.set_cursor_visible(False)
|
||||
self.view.set_highlight_current_line(True)
|
||||
self.window.add(vbox)
|
||||
vbox.pack_start(swin, True, True, 0)
|
||||
swin.add(self.view)
|
||||
builder = Gtk.Builder()
|
||||
builder.add_from_file(os.path.join(gui.self_dir, 'sourcewindow.xml'))
|
||||
|
||||
vbox.show_all()
|
||||
builder.connect_signals(self)
|
||||
self.window = builder.get_object("sourcewindow")
|
||||
self.view = builder.get_object("view")
|
||||
|
||||
self.window.connect("delete-event", self.deleted)
|
||||
lru_handler.add(self)
|
||||
|
||||
self.window.show()
|
||||
|
||||
def do_stop(self, *args):
|
||||
# FIXME.
|
||||
pass
|
||||
|
||||
def deleted(self, widget, event):
|
||||
lru_handler.remove(self)
|
||||
|
||||
@@ -180,5 +177,5 @@ class SourceWindow:
|
||||
old_buffer = self.view.get_buffer()
|
||||
self.view.set_buffer(buff)
|
||||
buffer_manager.release_buffer(old_buffer)
|
||||
gtk.idle_add(self._do_scroll, buff, srcline - 1)
|
||||
GObject.idle_add(self._do_scroll, buff, srcline - 1)
|
||||
# self.view.scroll_to_iter(buff.get_iter_at_line(srcline), 0.0)
|
||||
|
||||
135
gui/sourcewindow.xml
Normal file
135
gui/sourcewindow.xml
Normal file
@@ -0,0 +1,135 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<!-- interface-requires gtk+ 3.0 -->
|
||||
<!-- interface-requires gtksourceview 3.0 -->
|
||||
<object class="GtkImage" id="image1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="pixbuf">icons/run-to-cursor.xpm</property>
|
||||
</object>
|
||||
<object class="GtkImage" id="image2">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="pixbuf">icons/step-over.xpm</property>
|
||||
</object>
|
||||
<object class="GtkImage" id="image3">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="pixbuf">icons/step-into.xpm</property>
|
||||
</object>
|
||||
<object class="GtkWindow" id="sourcewindow">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="title" translatable="yes">Source</property>
|
||||
<property name="default_width">600</property>
|
||||
<property name="default_height">400</property>
|
||||
<signal name="delete-event" handler="deleted" swapped="no"/>
|
||||
<child>
|
||||
<object class="GtkBox" id="box1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkToolbar" id="toolbar1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkToolButton" id="continue">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="tooltip_text" translatable="yes">Continue execution</property>
|
||||
<property name="label" translatable="yes">Continue</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="icon_widget">image1</property>
|
||||
<accelerator key="c" signal="clicked"/>
|
||||
<signal name="clicked" handler="do_continue" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToolButton" id="next">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="tooltip_text" translatable="yes">Execute one line, stepping over function calls</property>
|
||||
<property name="label" translatable="yes">Next</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="icon_widget">image2</property>
|
||||
<accelerator key="n" signal="clicked"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToolButton" id="step">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="tooltip_text" translatable="yes">Execute one line, stepping into function calls</property>
|
||||
<property name="label" translatable="yes">Step</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="icon_widget">image3</property>
|
||||
<accelerator key="s" signal="clicked"/>
|
||||
<signal name="clicked" handler="do_step" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToolButton" id="stop">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="tooltip_text" translatable="yes">Interrupt the program</property>
|
||||
<property name="label" translatable="yes">Stop</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="stock_id">gtk-stop</property>
|
||||
<accelerator key="c" signal="clicked" modifiers="GDK_CONTROL_MASK"/>
|
||||
<signal name="clicked" handler="do_stop" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="scrolledwindow2">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<child>
|
||||
<object class="GtkSourceView" id="view">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="has_tooltip">True</property>
|
||||
<property name="editable">False</property>
|
||||
<property name="left_margin">2</property>
|
||||
<property name="right_margin">2</property>
|
||||
<property name="cursor_visible">False</property>
|
||||
<property name="tab_width">4</property>
|
||||
<property name="auto_indent">True</property>
|
||||
<property name="highlight_current_line">True</property>
|
||||
<property name="indent_on_tab">False</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
||||
@@ -20,8 +20,8 @@ import Queue
|
||||
import fix_signals
|
||||
fix_signals.save()
|
||||
|
||||
import gtk
|
||||
import glib
|
||||
from gi.repository import Gtk, Gdk, GObject, GtkSource
|
||||
|
||||
import os
|
||||
|
||||
(read_pipe, write_pipe) = os.pipe()
|
||||
@@ -43,15 +43,17 @@ class _GtkThread(threading.Thread):
|
||||
|
||||
def run(self):
|
||||
global read_pipe
|
||||
glib.io_add_watch(read_pipe, glib.IO_IN, self.handle_queue)
|
||||
gtk.main()
|
||||
GObject.io_add_watch(read_pipe, GObject.IO_IN, self.handle_queue)
|
||||
GObject.type_register(GtkSource.View)
|
||||
Gtk.main()
|
||||
|
||||
_t = None
|
||||
|
||||
def start_gtk():
|
||||
global _t
|
||||
if _t is None:
|
||||
gtk.gdk.threads_init()
|
||||
GObject.threads_init()
|
||||
Gdk.threads_init()
|
||||
_t = _GtkThread()
|
||||
_t.setDaemon(True)
|
||||
_t.start()
|
||||
|
||||
Reference in New Issue
Block a user