1*58e6ee5fSAndroid Build Coastguard Worker# 2*58e6ee5fSAndroid Build Coastguard Worker# Copyright (C) International Business Machines Corp., 2009 3*58e6ee5fSAndroid Build Coastguard Worker# 4*58e6ee5fSAndroid Build Coastguard Worker# This program is free software; you can redistribute it and/or modify 5*58e6ee5fSAndroid Build Coastguard Worker# it under the terms of the GNU General Public License as published by 6*58e6ee5fSAndroid Build Coastguard Worker# the Free Software Foundation; either version 2 of the License, or 7*58e6ee5fSAndroid Build Coastguard Worker# (at your option) any later version. 8*58e6ee5fSAndroid Build Coastguard Worker# 9*58e6ee5fSAndroid Build Coastguard Worker# This program is distributed in the hope that it will be useful, 10*58e6ee5fSAndroid Build Coastguard Worker# but WITHOUT ANY WARRANTY; without even the implied warranty of 11*58e6ee5fSAndroid Build Coastguard Worker# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12*58e6ee5fSAndroid Build Coastguard Worker# GNU General Public License for more details. 13*58e6ee5fSAndroid Build Coastguard Worker# 14*58e6ee5fSAndroid Build Coastguard Worker# You should have received a copy of the GNU General Public License 15*58e6ee5fSAndroid Build Coastguard Worker# along with this program; if not, write to the Free Software 16*58e6ee5fSAndroid Build Coastguard Worker# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 17*58e6ee5fSAndroid Build Coastguard Worker# 18*58e6ee5fSAndroid Build Coastguard Worker# 2009-Dec-31: Initial version by Darren Hart <[email protected]> 19*58e6ee5fSAndroid Build Coastguard Worker# 20*58e6ee5fSAndroid Build Coastguard Worker 21*58e6ee5fSAndroid Build Coastguard Workerimport gobject #delete me ? 22*58e6ee5fSAndroid Build Coastguard Workerimport time 23*58e6ee5fSAndroid Build Coastguard Workerimport sys 24*58e6ee5fSAndroid Build Coastguard Workerimport gtk 25*58e6ee5fSAndroid Build Coastguard Workerfrom tracecmd import * 26*58e6ee5fSAndroid Build Coastguard Workerfrom ctracecmdgui import * 27*58e6ee5fSAndroid Build Coastguard Worker 28*58e6ee5fSAndroid Build Coastguard Worker""" 29*58e6ee5fSAndroid Build Coastguard WorkerPython interface for tracecmd GTK widgets 30*58e6ee5fSAndroid Build Coastguard Worker 31*58e6ee5fSAndroid Build Coastguard WorkerPython tracecmd applications should be written to this interface. It will be 32*58e6ee5fSAndroid Build Coastguard Workerupdated as the tracecmd gui C API changes and try to minimze the impact to 33*58e6ee5fSAndroid Build Coastguard Workerpython applications. The ctracecmdgui Python module is automatically generated 34*58e6ee5fSAndroid Build Coastguard Workerusing SWIG and it is recommended applications not use it directly. 35*58e6ee5fSAndroid Build Coastguard Worker""" 36*58e6ee5fSAndroid Build Coastguard Worker 37*58e6ee5fSAndroid Build Coastguard Worker# In a "real" app these width should be determined at runtime testing max length 38*58e6ee5fSAndroid Build Coastguard Worker# strings in the current font. 39*58e6ee5fSAndroid Build Coastguard WorkerTS_COL_W = 150 40*58e6ee5fSAndroid Build Coastguard WorkerCPU_COL_W = 35 41*58e6ee5fSAndroid Build Coastguard WorkerEVENT_COL_W = 150 42*58e6ee5fSAndroid Build Coastguard WorkerPID_COL_W = 75 43*58e6ee5fSAndroid Build Coastguard WorkerCOMM_COL_W = 250 44*58e6ee5fSAndroid Build Coastguard Worker 45*58e6ee5fSAndroid Build Coastguard Worker 46*58e6ee5fSAndroid Build Coastguard Workerdef timing(func): 47*58e6ee5fSAndroid Build Coastguard Worker def wrapper(*arg): 48*58e6ee5fSAndroid Build Coastguard Worker start = time.time() 49*58e6ee5fSAndroid Build Coastguard Worker ret = func(*arg) 50*58e6ee5fSAndroid Build Coastguard Worker end = time.time() 51*58e6ee5fSAndroid Build Coastguard Worker print('@%s took %0.3f s' % (func.func_name, (end-start))) 52*58e6ee5fSAndroid Build Coastguard Worker return ret 53*58e6ee5fSAndroid Build Coastguard Worker return wrapper 54*58e6ee5fSAndroid Build Coastguard Worker 55*58e6ee5fSAndroid Build Coastguard Worker 56*58e6ee5fSAndroid Build Coastguard Workerclass EventStore(gtk.GenericTreeModel): 57*58e6ee5fSAndroid Build Coastguard Worker # FIXME: get these from the C code: trace_view_store->column_types ... 58*58e6ee5fSAndroid Build Coastguard Worker @timing 59*58e6ee5fSAndroid Build Coastguard Worker def __init__(self, trace): 60*58e6ee5fSAndroid Build Coastguard Worker gtk.GenericTreeModel.__init__(self) 61*58e6ee5fSAndroid Build Coastguard Worker self.trace = trace 62*58e6ee5fSAndroid Build Coastguard Worker self.cstore = trace_view_store_new(trace.handle) 63*58e6ee5fSAndroid Build Coastguard Worker self.gtk_cstore = trace_view_store_as_gtk_tree_model(self.cstore) 64*58e6ee5fSAndroid Build Coastguard Worker num_rows = trace_view_store_num_rows_get(self.cstore) 65*58e6ee5fSAndroid Build Coastguard Worker print("Loaded %d events from trace" % (num_rows)) 66*58e6ee5fSAndroid Build Coastguard Worker 67*58e6ee5fSAndroid Build Coastguard Worker def on_get_flags(self): 68*58e6ee5fSAndroid Build Coastguard Worker return trace_view_store_get_flags(self.gtk_cstore) 69*58e6ee5fSAndroid Build Coastguard Worker 70*58e6ee5fSAndroid Build Coastguard Worker def on_get_n_columns(self): 71*58e6ee5fSAndroid Build Coastguard Worker return trace_view_store_get_n_columns(self.gtk_cstore) 72*58e6ee5fSAndroid Build Coastguard Worker 73*58e6ee5fSAndroid Build Coastguard Worker def on_get_column_type(self, col): 74*58e6ee5fSAndroid Build Coastguard Worker # I couldn't figure out how to convert the C GType into the python 75*58e6ee5fSAndroid Build Coastguard Worker # GType. The current typemap converts the C GType into the python type, 76*58e6ee5fSAndroid Build Coastguard Worker # which is what this function is supposed to return anyway. 77*58e6ee5fSAndroid Build Coastguard Worker pytype = trace_view_store_get_column_type(self.gtk_cstore, col) 78*58e6ee5fSAndroid Build Coastguard Worker return pytype 79*58e6ee5fSAndroid Build Coastguard Worker 80*58e6ee5fSAndroid Build Coastguard Worker def on_get_iter(self, path): 81*58e6ee5fSAndroid Build Coastguard Worker if len(path) > 1 and path[1] != 1: 82*58e6ee5fSAndroid Build Coastguard Worker return None 83*58e6ee5fSAndroid Build Coastguard Worker n = path[0] 84*58e6ee5fSAndroid Build Coastguard Worker rec = trace_view_store_get_row(self.cstore, n) 85*58e6ee5fSAndroid Build Coastguard Worker return rec 86*58e6ee5fSAndroid Build Coastguard Worker 87*58e6ee5fSAndroid Build Coastguard Worker def on_get_path(self, rec): 88*58e6ee5fSAndroid Build Coastguard Worker if not rec: 89*58e6ee5fSAndroid Build Coastguard Worker return None 90*58e6ee5fSAndroid Build Coastguard Worker start_row = trace_view_store_start_row_get(self.cstore) 91*58e6ee5fSAndroid Build Coastguard Worker return (trace_view_record_pos_get(rec) - start_row,) 92*58e6ee5fSAndroid Build Coastguard Worker 93*58e6ee5fSAndroid Build Coastguard Worker def on_get_value(self, rec, col): 94*58e6ee5fSAndroid Build Coastguard Worker # FIXME: write SWIG wrapper to marshal the Gvalue and wrap the rec in an 95*58e6ee5fSAndroid Build Coastguard Worker # Iter 96*58e6ee5fSAndroid Build Coastguard Worker pass 97*58e6ee5fSAndroid Build Coastguard Worker #return trace_view_store_get_value_py(self.cstore, rec, col) 98*58e6ee5fSAndroid Build Coastguard Worker 99*58e6ee5fSAndroid Build Coastguard Worker def on_iter_next(self, rec): 100*58e6ee5fSAndroid Build Coastguard Worker pos = trace_view_record_pos_get(rec) 101*58e6ee5fSAndroid Build Coastguard Worker start_row = trace_view_store_start_row_get(self.cstore) 102*58e6ee5fSAndroid Build Coastguard Worker return trace_view_store_get_row(self.cstore, pos - start_row + 1) 103*58e6ee5fSAndroid Build Coastguard Worker 104*58e6ee5fSAndroid Build Coastguard Worker def on_iter_children(self, rec): 105*58e6ee5fSAndroid Build Coastguard Worker if rec: 106*58e6ee5fSAndroid Build Coastguard Worker return None 107*58e6ee5fSAndroid Build Coastguard Worker return trace_view_store_get_row(self.cstore, 0) 108*58e6ee5fSAndroid Build Coastguard Worker 109*58e6ee5fSAndroid Build Coastguard Worker def on_iter_has_child(self, rec): 110*58e6ee5fSAndroid Build Coastguard Worker return False 111*58e6ee5fSAndroid Build Coastguard Worker 112*58e6ee5fSAndroid Build Coastguard Worker def on_iter_n_children(self, rec): 113*58e6ee5fSAndroid Build Coastguard Worker if rec: 114*58e6ee5fSAndroid Build Coastguard Worker return 0 115*58e6ee5fSAndroid Build Coastguard Worker return trace_view_store_num_rows_get(self.cstore) 116*58e6ee5fSAndroid Build Coastguard Worker 117*58e6ee5fSAndroid Build Coastguard Worker def on_iter_nth_child(self, rec, n): 118*58e6ee5fSAndroid Build Coastguard Worker if rec: 119*58e6ee5fSAndroid Build Coastguard Worker return None 120*58e6ee5fSAndroid Build Coastguard Worker return trace_view_store_get_row(self.cstore, n) 121*58e6ee5fSAndroid Build Coastguard Worker 122*58e6ee5fSAndroid Build Coastguard Worker def on_iter_parent(self, child): 123*58e6ee5fSAndroid Build Coastguard Worker return None 124*58e6ee5fSAndroid Build Coastguard Worker 125*58e6ee5fSAndroid Build Coastguard Worker def get_event(self, iter): 126*58e6ee5fSAndroid Build Coastguard Worker path = self.get_path(iter) 127*58e6ee5fSAndroid Build Coastguard Worker if not path: 128*58e6ee5fSAndroid Build Coastguard Worker return None 129*58e6ee5fSAndroid Build Coastguard Worker rec = trace_view_store_get_row(self.cstore, path[0]) 130*58e6ee5fSAndroid Build Coastguard Worker if not rec: 131*58e6ee5fSAndroid Build Coastguard Worker return None 132*58e6ee5fSAndroid Build Coastguard Worker ev = self.trace.read_event_at(trace_view_record_offset_get(rec)) 133*58e6ee5fSAndroid Build Coastguard Worker return ev 134*58e6ee5fSAndroid Build Coastguard Worker 135*58e6ee5fSAndroid Build Coastguard Worker 136*58e6ee5fSAndroid Build Coastguard Workerclass EventView(gtk.TreeView): 137*58e6ee5fSAndroid Build Coastguard Worker def __init__(self, model): 138*58e6ee5fSAndroid Build Coastguard Worker gtk.TreeView.__init__(self, model) 139*58e6ee5fSAndroid Build Coastguard Worker self.set_fixed_height_mode(True) 140*58e6ee5fSAndroid Build Coastguard Worker 141*58e6ee5fSAndroid Build Coastguard Worker ts_col = gtk.TreeViewColumn("Time (s)") 142*58e6ee5fSAndroid Build Coastguard Worker ts_col.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED) 143*58e6ee5fSAndroid Build Coastguard Worker ts_col.set_fixed_width(TS_COL_W) 144*58e6ee5fSAndroid Build Coastguard Worker ts_cell = gtk.CellRendererText() 145*58e6ee5fSAndroid Build Coastguard Worker ts_col.pack_start(ts_cell, False) 146*58e6ee5fSAndroid Build Coastguard Worker ts_col.set_cell_data_func(ts_cell, self.data_func, "ts") 147*58e6ee5fSAndroid Build Coastguard Worker self.append_column(ts_col) 148*58e6ee5fSAndroid Build Coastguard Worker 149*58e6ee5fSAndroid Build Coastguard Worker cpu_col = gtk.TreeViewColumn("CPU") 150*58e6ee5fSAndroid Build Coastguard Worker cpu_col.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED) 151*58e6ee5fSAndroid Build Coastguard Worker cpu_col.set_fixed_width(CPU_COL_W) 152*58e6ee5fSAndroid Build Coastguard Worker cpu_cell = gtk.CellRendererText() 153*58e6ee5fSAndroid Build Coastguard Worker cpu_col.pack_start(cpu_cell, False) 154*58e6ee5fSAndroid Build Coastguard Worker cpu_col.set_cell_data_func(cpu_cell, self.data_func, "cpu") 155*58e6ee5fSAndroid Build Coastguard Worker self.append_column(cpu_col) 156*58e6ee5fSAndroid Build Coastguard Worker 157*58e6ee5fSAndroid Build Coastguard Worker event_col = gtk.TreeViewColumn("Event") 158*58e6ee5fSAndroid Build Coastguard Worker event_col.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED) 159*58e6ee5fSAndroid Build Coastguard Worker event_col.set_fixed_width(EVENT_COL_W) 160*58e6ee5fSAndroid Build Coastguard Worker event_cell = gtk.CellRendererText() 161*58e6ee5fSAndroid Build Coastguard Worker event_col.pack_start(event_cell, False) 162*58e6ee5fSAndroid Build Coastguard Worker event_col.set_cell_data_func(event_cell, self.data_func, "event") 163*58e6ee5fSAndroid Build Coastguard Worker self.append_column(event_col) 164*58e6ee5fSAndroid Build Coastguard Worker 165*58e6ee5fSAndroid Build Coastguard Worker pid_col = gtk.TreeViewColumn("PID") 166*58e6ee5fSAndroid Build Coastguard Worker pid_col.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED) 167*58e6ee5fSAndroid Build Coastguard Worker pid_col.set_fixed_width(PID_COL_W) 168*58e6ee5fSAndroid Build Coastguard Worker pid_cell = gtk.CellRendererText() 169*58e6ee5fSAndroid Build Coastguard Worker pid_col.pack_start(pid_cell, False) 170*58e6ee5fSAndroid Build Coastguard Worker pid_col.set_cell_data_func(pid_cell, self.data_func, "pid") 171*58e6ee5fSAndroid Build Coastguard Worker self.append_column(pid_col) 172*58e6ee5fSAndroid Build Coastguard Worker 173*58e6ee5fSAndroid Build Coastguard Worker comm_col = gtk.TreeViewColumn("Comm") 174*58e6ee5fSAndroid Build Coastguard Worker comm_col.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED) 175*58e6ee5fSAndroid Build Coastguard Worker comm_col.set_fixed_width(COMM_COL_W) 176*58e6ee5fSAndroid Build Coastguard Worker comm_cell = gtk.CellRendererText() 177*58e6ee5fSAndroid Build Coastguard Worker comm_col.pack_start(comm_cell, False) 178*58e6ee5fSAndroid Build Coastguard Worker comm_col.set_cell_data_func(comm_cell, self.data_func, "comm") 179*58e6ee5fSAndroid Build Coastguard Worker self.append_column(comm_col) 180*58e6ee5fSAndroid Build Coastguard Worker 181*58e6ee5fSAndroid Build Coastguard Worker def data_func(self, col, cell, model, iter, data): 182*58e6ee5fSAndroid Build Coastguard Worker ev = model.get_event(iter) 183*58e6ee5fSAndroid Build Coastguard Worker #ev = model.get_value(iter, 0) 184*58e6ee5fSAndroid Build Coastguard Worker if not ev: 185*58e6ee5fSAndroid Build Coastguard Worker return False 186*58e6ee5fSAndroid Build Coastguard Worker 187*58e6ee5fSAndroid Build Coastguard Worker if data == "ts": 188*58e6ee5fSAndroid Build Coastguard Worker cell.set_property("markup", "%d.%d" % (ev.ts/1000000000, 189*58e6ee5fSAndroid Build Coastguard Worker ev.ts%1000000000)) 190*58e6ee5fSAndroid Build Coastguard Worker elif data == "cpu": 191*58e6ee5fSAndroid Build Coastguard Worker cell.set_property("markup", ev.cpu) 192*58e6ee5fSAndroid Build Coastguard Worker elif data == "event": 193*58e6ee5fSAndroid Build Coastguard Worker cell.set_property("markup", ev.name) 194*58e6ee5fSAndroid Build Coastguard Worker elif data == "pid": 195*58e6ee5fSAndroid Build Coastguard Worker cell.set_property("markup", ev.pid) 196*58e6ee5fSAndroid Build Coastguard Worker elif data == "comm": 197*58e6ee5fSAndroid Build Coastguard Worker cell.set_property("markup", ev.comm) 198*58e6ee5fSAndroid Build Coastguard Worker else: 199*58e6ee5fSAndroid Build Coastguard Worker print("Unknown Column:", data) 200*58e6ee5fSAndroid Build Coastguard Worker return False 201*58e6ee5fSAndroid Build Coastguard Worker 202*58e6ee5fSAndroid Build Coastguard Worker return True 203*58e6ee5fSAndroid Build Coastguard Worker 204*58e6ee5fSAndroid Build Coastguard Worker 205*58e6ee5fSAndroid Build Coastguard Workerclass EventViewerApp(gtk.Window): 206*58e6ee5fSAndroid Build Coastguard Worker def __init__(self, trace): 207*58e6ee5fSAndroid Build Coastguard Worker gtk.Window.__init__(self) 208*58e6ee5fSAndroid Build Coastguard Worker 209*58e6ee5fSAndroid Build Coastguard Worker self.set_size_request(650, 400) 210*58e6ee5fSAndroid Build Coastguard Worker self.set_position(gtk.WIN_POS_CENTER) 211*58e6ee5fSAndroid Build Coastguard Worker 212*58e6ee5fSAndroid Build Coastguard Worker self.connect("destroy", gtk.main_quit) 213*58e6ee5fSAndroid Build Coastguard Worker self.set_title("Event Viewer") 214*58e6ee5fSAndroid Build Coastguard Worker 215*58e6ee5fSAndroid Build Coastguard Worker store = EventStore(trace) 216*58e6ee5fSAndroid Build Coastguard Worker view = EventView(store) 217*58e6ee5fSAndroid Build Coastguard Worker 218*58e6ee5fSAndroid Build Coastguard Worker sw = gtk.ScrolledWindow() 219*58e6ee5fSAndroid Build Coastguard Worker sw.set_policy(gtk.POLICY_NEVER, gtk.POLICY_ALWAYS) 220*58e6ee5fSAndroid Build Coastguard Worker sw.add(view) 221*58e6ee5fSAndroid Build Coastguard Worker 222*58e6ee5fSAndroid Build Coastguard Worker # track how often the treeview data_func is called 223*58e6ee5fSAndroid Build Coastguard Worker self.add(sw) 224*58e6ee5fSAndroid Build Coastguard Worker self.show_all() 225*58e6ee5fSAndroid Build Coastguard Worker 226*58e6ee5fSAndroid Build Coastguard Worker 227*58e6ee5fSAndroid Build Coastguard Worker# Basic builtin test, execute module directly 228*58e6ee5fSAndroid Build Coastguard Workerif __name__ == "__main__": 229*58e6ee5fSAndroid Build Coastguard Worker if len(sys.argv) >=2: 230*58e6ee5fSAndroid Build Coastguard Worker filename = sys.argv[1] 231*58e6ee5fSAndroid Build Coastguard Worker else: 232*58e6ee5fSAndroid Build Coastguard Worker filename = "trace.dat" 233*58e6ee5fSAndroid Build Coastguard Worker 234*58e6ee5fSAndroid Build Coastguard Worker print("Initializing trace...") 235*58e6ee5fSAndroid Build Coastguard Worker trace = Trace(filename) 236*58e6ee5fSAndroid Build Coastguard Worker print("Initializing app...") 237*58e6ee5fSAndroid Build Coastguard Worker app = EventViewerApp(trace) 238*58e6ee5fSAndroid Build Coastguard Worker print("Go!") 239*58e6ee5fSAndroid Build Coastguard Worker gtk.main() 240