aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDarren Hart <dvhltc@us.ibm.com>2010-01-04 20:24:41 -0500
committerSteven Rostedt <rostedt@goodmis.org>2010-01-04 23:40:02 -0500
commitbbb314602b12c2a2d9f859f75576c4f3aa58f306 (patch)
tree4d5713041061bef2c887fb8429ae06c2ace08495
parentf18df1531e4da5685dd7441811c57ba96af0c055 (diff)
trace-view: Provide GTK TreeModel trace-view-store available to python
Make the necessary trace-view-store methods non-static and place their declarations in the header file. Functions beginning with _ are considered private in python. The structs beginning with _ caused their accessor functions to be generated as private. Since they aren't used as structs anywhere in the C code, rename them to something more accessible to python. Signed-off-by: Darren Hart <dvhltc@us.ibm.com> LKML-Reference: <1262654682-20325-3-git-send-email-dvhltc@us.ibm.com> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
-rw-r--r--Makefile7
-rw-r--r--ctracecmdgui.i78
-rw-r--r--trace-view-store.c23
-rw-r--r--trace-view-store.h25
-rw-r--r--tracecmdgui.py239
5 files changed, 348 insertions, 24 deletions
diff --git a/Makefile b/Makefile
index dc8a2a0..3d17256 100644
--- a/Makefile
+++ b/Makefile
@@ -137,6 +137,13 @@ python: $(TCMD_LIB_OBJS)
137 $(CC) --shared $^ ctracecmd_wrap.o -o ctracecmd.so 137 $(CC) --shared $^ ctracecmd_wrap.o -o ctracecmd.so
138 #$(CC) --shared $^ ctracecmd_wrap.o -o _ctracecmd.so 138 #$(CC) --shared $^ ctracecmd_wrap.o -o _ctracecmd.so
139 139
140.PHONY: python-gui
141python-gui: $(TRACE_VIEW_OBJS)
142 swig -Wall -python -noproxy ctracecmdgui.i
143 # FIXME: where do we get the pygtk include from?
144 gcc -fpic -c `python-config --includes` $(CFLAGS) $(INCLUDES) -I/usr/include/pygtk-2.0/ ctracecmdgui_wrap.c
145 $(CC) --shared $^ $(LIBS) $(CONFIG_LIBS) ctracecmdgui_wrap.o -o ctracecmdgui.so
146
140 147
141.PHONY: force 148.PHONY: force
142force: 149force:
diff --git a/ctracecmdgui.i b/ctracecmdgui.i
new file mode 100644
index 0000000..1dcdab0
--- /dev/null
+++ b/ctracecmdgui.i
@@ -0,0 +1,78 @@
1// ctracecmdgui.i
2%module ctracecmdgui
3%include typemaps.i
4
5%{
6#include "trace-view-store.h"
7#include <pygobject.h>
8#include <pyglib.h>
9#include <Python.h>
10
11extern GtkTreeModel *trace_view_store_as_gtk_tree_model(struct trace_view_store *store);
12
13PyObject *
14pytype_from_gtype(GType gtype)
15{
16 PyTypeObject *pt = NULL;
17 switch (gtype) {
18 case G_TYPE_INT:
19 case G_TYPE_UINT:
20 pt = &PyLong_Type;
21 break;
22 case G_TYPE_STRING:
23 pt = &PyUnicode_Type;
24 break;
25 default:
26 return Py_None;
27 }
28 return (PyObject *)pt;
29}
30%}
31
32
33/* return python longs from unsigned long long functions */
34%typemap(out) unsigned long long {
35 $result = PyLong_FromUnsignedLongLong((unsigned long long) $1);
36}
37
38/* help swig cope with g* types */
39%typemap(in) gint {
40 $1 = PyInt_AsLong($input);
41}
42%typemap(out) gint {
43 $result = PyInt_FromLong($1);
44}
45%typemap(in) guint {
46 $1 = PyLong_AsUnsignedLong($input);
47}
48%typemap(out) guint {
49 $result = PyLong_FromUnsignedLong($1);
50}
51%typemap(in) guint64 {
52 $1 = PyLong_AsUnsignedLongLong($input);
53}
54%typemap(out) guint64 {
55 $result = PyLong_FromUnsignedLongLong($1);
56}
57%typemap(out) GType {
58 $result = pytype_from_gtype($1);
59}
60%typemap(out) GtkTreeModelFlags {
61 $result = PyLong_FromLong($1);
62}
63
64
65%inline %{
66GtkTreeModel *trace_view_store_as_gtk_tree_model(struct trace_view_store *store)
67{
68 return GTK_TREE_MODEL(store);
69}
70%}
71
72
73/* SWIG can't grok these, define them to nothing */
74#define __trace
75#define __attribute__(x)
76#define __thread
77
78%include "trace-view-store.h"
diff --git a/trace-view-store.c b/trace-view-store.c
index b167cc9..03664c8 100644
--- a/trace-view-store.c
+++ b/trace-view-store.c
@@ -13,25 +13,13 @@ static void trace_view_store_tree_model_init (GtkTreeModelIface *iface);
13 13
14static void trace_view_store_finalize (GObject *object); 14static void trace_view_store_finalize (GObject *object);
15 15
16static GtkTreeModelFlags trace_view_store_get_flags (GtkTreeModel *tree_model);
17
18static gint trace_view_store_get_n_columns (GtkTreeModel *tree_model);
19
20static GType trace_view_store_get_column_type (GtkTreeModel *tree_model,
21 gint index);
22
23static gboolean trace_view_store_get_iter (GtkTreeModel *tree_model, 16static gboolean trace_view_store_get_iter (GtkTreeModel *tree_model,
24 GtkTreeIter *iter, 17 GtkTreeIter *iter,
25 GtkTreePath *path); 18 GtkTreePath *path);
26 19
27static GtkTreePath *trace_view_store_get_path (GtkTreeModel *tree_model, 20static GtkTreePath *trace_view_store_get_path (GtkTreeModel *tree_model,
28 GtkTreeIter *iter); 21 GtkTreeIter *iter);
29 22
30static void trace_view_store_get_value (GtkTreeModel *tree_model,
31 GtkTreeIter *iter,
32 gint column,
33 GValue *value);
34
35static gboolean trace_view_store_iter_next (GtkTreeModel *tree_model, 23static gboolean trace_view_store_iter_next (GtkTreeModel *tree_model,
36 GtkTreeIter *iter); 24 GtkTreeIter *iter);
37 25
@@ -55,7 +43,6 @@ static gboolean trace_view_store_iter_parent (GtkTreeModel *tree_model,
55 GtkTreeIter *child); 43 GtkTreeIter *child);
56 44
57 45
58
59static GObjectClass *parent_class = NULL; /* GObject stuff - nothing to worry about */ 46static GObjectClass *parent_class = NULL; /* GObject stuff - nothing to worry about */
60 47
61 48
@@ -240,7 +227,7 @@ trace_view_store_finalize (GObject *object)
240 * 227 *
241 *****************************************************************************/ 228 *****************************************************************************/
242 229
243static GtkTreeModelFlags 230GtkTreeModelFlags
244trace_view_store_get_flags (GtkTreeModel *tree_model) 231trace_view_store_get_flags (GtkTreeModel *tree_model)
245{ 232{
246 g_return_val_if_fail (TRACE_VIEW_IS_LIST(tree_model), (GtkTreeModelFlags)0); 233 g_return_val_if_fail (TRACE_VIEW_IS_LIST(tree_model), (GtkTreeModelFlags)0);
@@ -256,7 +243,7 @@ trace_view_store_get_flags (GtkTreeModel *tree_model)
256 * 243 *
257 *****************************************************************************/ 244 *****************************************************************************/
258 245
259static gint 246gint
260trace_view_store_get_n_columns (GtkTreeModel *tree_model) 247trace_view_store_get_n_columns (GtkTreeModel *tree_model)
261{ 248{
262 g_return_val_if_fail (TRACE_VIEW_IS_LIST(tree_model), 0); 249 g_return_val_if_fail (TRACE_VIEW_IS_LIST(tree_model), 0);
@@ -299,7 +286,7 @@ static gint get_visible_column(TraceViewStore *trace_view, gint column)
299 * 286 *
300 *****************************************************************************/ 287 *****************************************************************************/
301 288
302static GType 289GType
303trace_view_store_get_column_type (GtkTreeModel *tree_model, 290trace_view_store_get_column_type (GtkTreeModel *tree_model,
304 gint index) 291 gint index)
305{ 292{
@@ -394,7 +381,7 @@ trace_view_store_get_path (GtkTreeModel *tree_model,
394 * 381 *
395 *****************************************************************************/ 382 *****************************************************************************/
396 383
397static void 384void
398trace_view_store_get_value (GtkTreeModel *tree_model, 385trace_view_store_get_value (GtkTreeModel *tree_model,
399 GtkTreeIter *iter, 386 GtkTreeIter *iter,
400 gint column, 387 gint column,
diff --git a/trace-view-store.h b/trace-view-store.h
index 53e0b37..bfa19d9 100644
--- a/trace-view-store.h
+++ b/trace-view-store.h
@@ -31,15 +31,15 @@ enum
31} ; 31} ;
32 32
33 33
34typedef struct _TraceViewRecord TraceViewRecord; 34typedef struct trace_view_record TraceViewRecord;
35typedef struct _TraceViewStore TraceViewStore; 35typedef struct trace_view_store TraceViewStore;
36typedef struct _TraceViewStoreClass TraceViewStoreClass; 36typedef struct trace_view_store_class TraceViewStoreClass;
37 37
38 38
39 39
40/* TraceViewRecord: this structure represents a row */ 40/* TraceViewRecord: this structure represents a row */
41 41
42struct _TraceViewRecord 42struct trace_view_record
43{ 43{
44 /* What we need from the record */ 44 /* What we need from the record */
45 guint64 timestamp; 45 guint64 timestamp;
@@ -60,7 +60,7 @@ struct _TraceViewRecord
60 * crucial that 'parent' is the first member of the 60 * crucial that 'parent' is the first member of the
61 * structure. */ 61 * structure. */
62 62
63struct _TraceViewStore 63struct trace_view_store
64{ 64{
65 GObject parent; /* this MUST be the first member */ 65 GObject parent; /* this MUST be the first member */
66 66
@@ -125,9 +125,22 @@ void trace_view_store_filter_tasks(TraceViewStore *store, struct filter_task *fi
125 125
126TraceViewRecord *trace_view_store_get_row(TraceViewStore *store, gint row); 126TraceViewRecord *trace_view_store_get_row(TraceViewStore *store, gint row);
127 127
128/* TraceViewStore methos */
129GtkTreeModelFlags trace_view_store_get_flags (GtkTreeModel *tree_model);
130
131gint trace_view_store_get_n_columns (GtkTreeModel *tree_model);
132
133GType trace_view_store_get_column_type (GtkTreeModel *tree_model,
134 gint index);
135
136void trace_view_store_get_value (GtkTreeModel *tree_model,
137 GtkTreeIter *iter,
138 gint column,
139 GValue *value);
140
128/* TraceViewStoreClass: more boilerplate GObject stuff */ 141/* TraceViewStoreClass: more boilerplate GObject stuff */
129 142
130struct _TraceViewStoreClass 143struct trace_view_store_class
131{ 144{
132 GObjectClass parent_class; 145 GObjectClass parent_class;
133}; 146};
diff --git a/tracecmdgui.py b/tracecmdgui.py
new file mode 100644
index 0000000..63400b0
--- /dev/null
+++ b/tracecmdgui.py
@@ -0,0 +1,239 @@
1#
2# Copyright (C) International Business Machines Corp., 2009
3#
4# This program is free software; you can redistribute it and/or modify
5# it under the terms of the GNU General Public License as published by
6# the Free Software Foundation; either version 2 of the License, or
7# (at your option) any later version.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License
15# along with this program; if not, write to the Free Software
16# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17#
18# 2009-Dec-31: Initial version by Darren Hart <dvhltc@us.ibm.com>
19#
20
21import gobject #delete me ?
22import time
23import sys
24import gtk
25from tracecmd import *
26from ctracecmdgui import *
27
28"""
29Python interface for tracecmd GTK widgets
30
31Python tracecmd applications should be written to this interface. It will be
32updated as the tracecmd gui C API changes and try to minimze the impact to
33python applications. The ctracecmdgui Python module is automatically generated
34using SWIG and it is recommended applications not use it directly.
35"""
36
37# In a "real" app these width should be determined at runtime testing max length
38# strings in the current font.
39TS_COL_W = 150
40CPU_COL_W = 35
41EVENT_COL_W = 150
42PID_COL_W = 75
43COMM_COL_W = 250
44
45
46def timing(func):
47 def wrapper(*arg):
48 start = time.time()
49 ret = func(*arg)
50 end = time.time()
51 print '@%s took %0.3f s' % (func.func_name, (end-start))
52 return ret
53 return wrapper
54
55
56class EventStore(gtk.GenericTreeModel):
57 # FIXME: get these from the C code: trace_view_store->column_types ...
58 @timing
59 def __init__(self, trace):
60 gtk.GenericTreeModel.__init__(self)
61 self.trace = trace
62 self.cstore = trace_view_store_new(trace.handle)
63 self.gtk_cstore = trace_view_store_as_gtk_tree_model(self.cstore)
64 num_rows = trace_view_store_num_rows_get(self.cstore)
65 print "Loaded %d events from trace" % (num_rows)
66
67 def on_get_flags(self):
68 return trace_view_store_get_flags(self.gtk_cstore)
69
70 def on_get_n_columns(self):
71 return trace_view_store_get_n_columns(self.gtk_cstore)
72
73 def on_get_column_type(self, col):
74 # I couldn't figure out how to convert the C GType into the python
75 # GType. The current typemap converts the C GType into the python type,
76 # which is what this function is supposed to return anyway.
77 pytype = trace_view_store_get_column_type(self.gtk_cstore, col)
78 return pytype
79
80 def on_get_iter(self, path):
81 if len(path) > 1 and path[1] != 1:
82 return None
83 n = path[0]
84 rec = trace_view_store_get_row(self.cstore, n)
85 return rec
86
87 def on_get_path(self, rec):
88 if not rec:
89 return None
90 start_row = trace_view_store_start_row_get(self.cstore)
91 return (trace_view_record_pos_get(rec) - start_row,)
92
93 def on_get_value(self, rec, col):
94 # FIXME: write SWIG wrapper to marshal the Gvalue and wrap the rec in an
95 # Iter
96 pass
97 #return trace_view_store_get_value_py(self.cstore, rec, col)
98
99 def on_iter_next(self, rec):
100 pos = trace_view_record_pos_get(rec)
101 start_row = trace_view_store_start_row_get(self.cstore)
102 return trace_view_store_get_row(self.cstore, pos - start_row + 1)
103
104 def on_iter_children(self, rec):
105 if rec:
106 return None
107 return trace_view_store_get_row(self.cstore, 0)
108
109 def on_iter_has_child(self, rec):
110 return False
111
112 def on_iter_n_children(self, rec):
113 if rec:
114 return 0
115 return trace_view_store_num_rows_get(self.cstore)
116
117 def on_iter_nth_child(self, rec, n):
118 if rec:
119 return None
120 return trace_view_store_get_row(self.cstore, n)
121
122 def on_iter_parent(self, child):
123 return None
124
125 def get_event(self, iter):
126 path = self.get_path(iter)
127 if not path:
128 return None
129 rec = trace_view_store_get_row(self.cstore, path[0])
130 if not rec:
131 return None
132 ev = self.trace.read_event_at(trace_view_record_offset_get(rec))
133 return ev
134
135
136class EventView(gtk.TreeView):
137 def __init__(self, model):
138 gtk.TreeView.__init__(self, model)
139 self.set_fixed_height_mode(True)
140
141 ts_col = gtk.TreeViewColumn("Time (s)")
142 ts_col.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
143 ts_col.set_fixed_width(TS_COL_W)
144 ts_cell = gtk.CellRendererText()
145 ts_col.pack_start(ts_cell, False)
146 ts_col.set_cell_data_func(ts_cell, self.data_func, "ts")
147 self.append_column(ts_col)
148
149 cpu_col = gtk.TreeViewColumn("CPU")
150 cpu_col.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
151 cpu_col.set_fixed_width(CPU_COL_W)
152 cpu_cell = gtk.CellRendererText()
153 cpu_col.pack_start(cpu_cell, False)
154 cpu_col.set_cell_data_func(cpu_cell, self.data_func, "cpu")
155 self.append_column(cpu_col)
156
157 event_col = gtk.TreeViewColumn("Event")
158 event_col.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
159 event_col.set_fixed_width(EVENT_COL_W)
160 event_cell = gtk.CellRendererText()
161 event_col.pack_start(event_cell, False)
162 event_col.set_cell_data_func(event_cell, self.data_func, "event")
163 self.append_column(event_col)
164
165 pid_col = gtk.TreeViewColumn("PID")
166 pid_col.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
167 pid_col.set_fixed_width(PID_COL_W)
168 pid_cell = gtk.CellRendererText()
169 pid_col.pack_start(pid_cell, False)
170 pid_col.set_cell_data_func(pid_cell, self.data_func, "pid")
171 self.append_column(pid_col)
172
173 comm_col = gtk.TreeViewColumn("Comm")
174 comm_col.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
175 comm_col.set_fixed_width(COMM_COL_W)
176 comm_cell = gtk.CellRendererText()
177 comm_col.pack_start(comm_cell, False)
178 comm_col.set_cell_data_func(comm_cell, self.data_func, "comm")
179 self.append_column(comm_col)
180
181 def data_func(self, col, cell, model, iter, data):
182 ev = model.get_event(iter)
183 #ev = model.get_value(iter, 0)
184 if not ev:
185 return False
186
187 if data == "ts":
188 cell.set_property("markup", "%d.%d" % (ev.ts/1000000000,
189 ev.ts%1000000000))
190 elif data == "cpu":
191 cell.set_property("markup", ev.cpu)
192 elif data == "event":
193 cell.set_property("markup", ev.name)
194 elif data == "pid":
195 cell.set_property("markup", ev.pid)
196 elif data == "comm":
197 cell.set_property("markup", ev.comm)
198 else:
199 print "Unknown Column:", data
200 return False
201
202 return True
203
204
205class EventViewerApp(gtk.Window):
206 def __init__(self, trace):
207 gtk.Window.__init__(self)
208
209 self.set_size_request(650, 400)
210 self.set_position(gtk.WIN_POS_CENTER)
211
212 self.connect("destroy", gtk.main_quit)
213 self.set_title("Event Viewer")
214
215 store = EventStore(trace)
216 view = EventView(store)
217
218 sw = gtk.ScrolledWindow()
219 sw.set_policy(gtk.POLICY_NEVER, gtk.POLICY_ALWAYS)
220 sw.add(view)
221
222 # track how often the treeview data_func is called
223 self.add(sw)
224 self.show_all()
225
226
227# Basic builtin test, execute module directly
228if __name__ == "__main__":
229 if len(sys.argv) >=2:
230 filename = sys.argv[1]
231 else:
232 filename = "trace.dat"
233
234 print "Initializing trace..."
235 trace = Trace(filename)
236 print "Initializing app..."
237 app = EventViewerApp(trace)
238 print "Go!"
239 gtk.main()