1 /*! \defgroup guiEvents libguiControlFlow: The GUI ControlFlow display plugin */
4 /*! \file guiControlFlow.c
5 * \brief Graphical plugin for showing control flow of a trace.
7 * This plugin adds a Control Flow Viewer functionnality to Linux TraceToolkit
8 * GUI when this plugin is loaded. The init and destroy functions add the
9 * viewer's insertion menu item and toolbar icon by calling gtkTraceSet's
10 * API functions. Then, when a viewer's object is created, the constructor
11 * creates ans register through API functions what is needed to interact
12 * with the TraceSet window.
14 * This plugin uses the gdk library to draw the events and gtk to interact
17 * Author : Mathieu Desnoyers, June 2003
25 #include <lttv/hook.h>
26 #include <lttv/module.h>
28 //#include "guiControlFlow.h"
29 #include "icons/hGuiControlFlowInsert.xpm"
31 #include "gtktreeprivate.h"
33 //FIXME by including ltt.h
35 typedef time_t ltt_time
;
37 typedef struct _DrawingAreaInfo
{
43 typedef struct _ControlFlowData
{
45 GtkWidget
*Drawing_Area_V
;
46 GtkWidget
*Drawing_Scrolled_Window_VC
;
47 GtkAdjustment
*VAdjust_Draw_C
;
49 GtkWidget
*Process_List_VC
;
50 GtkWidget
*Process_Scrolled_Window_VC
;
52 /* Model containing list data */
53 GtkListStore
*Store_M
;
57 GtkAdjustment
*VAdjust_C
;
59 guint First_Event
, Last_Event
;
60 ltt_time Begin_time
, End_Time
;
62 /* Drawing Area Info */
63 DrawingAreaInfo Drawing_Area_Info
;
65 /* TEST DATA, TO BE READ FROM THE TRACE */
66 gint Number_Of_Events
;
67 guint Currently_Selected_Event
;
68 gboolean Selected_Event
;
69 guint Number_Of_Process
;
74 /** Array containing instanced objects. Used when module is unloaded */
75 static GSList
*sControl_Flow_Data_List
= NULL
;
78 //! Control Flow Viewer's constructor hook
79 GtkWidget
*hGuiControlFlow(GtkWidget
*pmParentWindow
);
80 //! Control Flow Viewer's constructor
81 ControlFlowData
*GuiControlFlow(void);
82 //! Control Flow Viewer's destructor
83 void GuiControlFlow_Destructor(ControlFlowData
*Control_Flow_Data
);
86 static int Event_Selected_Hook(void *hook_data
, void *call_data
);
88 //void Tree_V_set_cursor(ControlFlowData *Control_Flow_Data);
89 //void Tree_V_get_cursor(ControlFlowData *Control_Flow_Data);
91 /* Prototype for selection handler callback */
92 //static void tree_selection_changed_cb (GtkTreeSelection *selection, gpointer data);
93 static void v_scroll_cb (GtkAdjustment
*adjustment
, gpointer data
);
94 //static void Tree_V_size_allocate_cb (GtkWidget *widget, GtkAllocation *alloc, gpointer data);
95 //static void Tree_V_size_request_cb (GtkWidget *widget, GtkRequisition *requisition, gpointer data);
96 //static void Tree_V_cursor_changed_cb (GtkWidget *widget, gpointer data);
97 //static void Tree_V_move_cursor_cb (GtkWidget *widget, GtkMovementStep arg1, gint arg2, gpointer data);
99 static void expose_event_cb (GtkWidget
*widget
, GdkEventExpose
*expose
, gpointer data
);
101 void add_test_process(ControlFlowData
*Control_Flow_Data
);
103 static void get_test_data(guint Event_Number
, guint List_Height
,
104 ControlFlowData
*Control_Flow_Data
);
106 void add_test_data(ControlFlowData
*Control_Flow_Data
);
107 void test_draw(ControlFlowData
*Control_Flow_Data
);
109 void Drawing_Area_Init(ControlFlowData
*Control_Flow_Data
);
115 * plugin's init function
117 * This function initializes the Control Flow Viewer functionnality through the
120 G_MODULE_EXPORT
void init() {
121 g_critical("GUI ControlFlow Viewer init()");
123 /* Register the toolbar insert button */
124 //ToolbarItemReg(guiEventsInsert_xpm, "Insert Control Flow Viewer", guiEvent);
126 /* Register the menu item insert entry */
127 //MenuItemReg("/", "Insert Control Flow Viewer", guiEvent);
131 void destroy_walk(gpointer data
, gpointer user_data
)
133 GuiControlFlow_Destructor((ControlFlowData
*)data
);
139 * plugin's destroy function
141 * This function releases the memory reserved by the module and unregisters
142 * everything that has been registered in the gtkTraceSet API.
144 G_MODULE_EXPORT
void destroy() {
145 g_critical("GUI Control Flow Viewer destroy()");
148 ControlFlowData
*Control_Flow_Data
;
150 g_critical("GUI Event Viewer destroy()");
152 g_slist_foreach(sControl_Flow_Data_List
, destroy_walk
, NULL
);
154 /* Unregister the toolbar insert button */
155 //ToolbarItemUnreg(hGuiEvents);
157 /* Unregister the menu item insert entry */
158 //MenuItemUnreg(hGuiEvents);
162 * Event Viewer's constructor hook
164 * This constructor is given as a parameter to the menuitem and toolbar button
165 * registration. It creates the list.
166 * @param pmParentWindow A pointer to the parent window.
167 * @return The widget created.
170 hGuiControlFlow(GtkWidget
*pmParentWindow
)
172 ControlFlowData
* Control_Flow_Data
= GuiControlFlow() ;
174 return Control_Flow_Data
->HBox_V
;
180 /* Enumeration of the columns */
190 * Control Flow Viewer's constructor
192 * This constructor is given as a parameter to the menuitem and toolbar button
193 * registration. It creates the drawing widget.
194 * @param ParentWindow A pointer to the parent window.
195 * @return The widget created.
201 GtkTreeViewColumn
*column
;
202 GtkCellRenderer
*renderer
;
204 ControlFlowData
* Control_Flow_Data
= g_new(ControlFlowData
,1) ;
205 Control_Flow_Data
->Drawing_Area_V
= gtk_drawing_area_new ();
207 /* TEST DATA, TO BE READ FROM THE TRACE */
208 Control_Flow_Data
->Number_Of_Events
= 1000 ;
209 Control_Flow_Data
->Currently_Selected_Event
= FALSE
;
210 Control_Flow_Data
->Selected_Event
= 0;
211 Control_Flow_Data
->Number_Of_Process
= 10;
213 /* FIXME register Event_Selected_Hook */
217 /* Create the Process list */
218 Control_Flow_Data
->Store_M
= gtk_list_store_new ( N_COLUMNS
,
222 Control_Flow_Data
->Process_List_VC
= gtk_tree_view_new_with_model (GTK_TREE_MODEL (Control_Flow_Data
->Store_M
));
224 g_object_unref (G_OBJECT (Control_Flow_Data
->Store_M
));
226 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(Control_Flow_Data
->Process_List_VC
), FALSE
);
228 /* Create a column, associating the "text" attribute of the
229 * cell_renderer to the first column of the model */
230 /* Columns alignment : 0.0 : Left 0.5 : Center 1.0 : Right */
231 renderer
= gtk_cell_renderer_text_new ();
232 column
= gtk_tree_view_column_new_with_attributes ("Process",
234 "text", PROCESS_COLUMN
,
236 gtk_tree_view_column_set_alignment (column
, 0.0);
237 gtk_tree_view_column_set_fixed_width (column
, 45);
238 gtk_tree_view_append_column (GTK_TREE_VIEW (Control_Flow_Data
->Process_List_VC
), column
);
242 /* Create the two scrolled windows with the same adjustment */
243 Control_Flow_Data
->Process_Scrolled_Window_VC
= gtk_scrolled_window_new(NULL
, NULL
);
245 Control_Flow_Data
->VAdjust_C
= gtk_scrolled_window_get_vadjustment(
246 GTK_SCROLLED_WINDOW(Control_Flow_Data
->Process_Scrolled_Window_VC
));
248 gtk_scrolled_window_set_policy(
249 GTK_SCROLLED_WINDOW(Control_Flow_Data
->Process_Scrolled_Window_VC
),
251 // GTK_POLICY_NEVER);
252 GTK_POLICY_AUTOMATIC
);
256 Control_Flow_Data
->Drawing_Scrolled_Window_VC
= gtk_scrolled_window_new(NULL
,Control_Flow_Data
->VAdjust_C
);
257 //Control_Flow_Data->Drawing_Scrolled_Window_VC = gtk_scrolled_window_new(NULL,NULL);
258 gtk_scrolled_window_set_policy(
259 GTK_SCROLLED_WINDOW(Control_Flow_Data
->Drawing_Scrolled_Window_VC
),
261 // GTK_POLICY_NEVER);
262 GTK_POLICY_AUTOMATIC
);
264 Control_Flow_Data
->VAdjust_Draw_C
= gtk_scrolled_window_get_vadjustment(
265 GTK_SCROLLED_WINDOW(Control_Flow_Data
->Drawing_Scrolled_Window_VC
));
267 gtk_container_add(GTK_CONTAINER(Control_Flow_Data
->Process_Scrolled_Window_VC
),
268 Control_Flow_Data
->Process_List_VC
);
271 gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(Control_Flow_Data
->Drawing_Scrolled_Window_VC
),
272 Control_Flow_Data
->Drawing_Area_V
);
275 Control_Flow_Data
->HBox_V
= gtk_hbox_new(0, 0);
280 /* Pack the list and the drawing area in the hbox */
282 gtk_box_pack_start(GTK_BOX(Control_Flow_Data
->HBox_V
), Control_Flow_Data
->Process_Scrolled_Window_VC
, TRUE
, TRUE
, 0);
283 gtk_box_pack_start(GTK_BOX(Control_Flow_Data
->HBox_V
), Control_Flow_Data
->Drawing_Scrolled_Window_VC
, TRUE
, TRUE
, 0);
286 g_signal_connect (G_OBJECT (Control_Flow_Data
->Drawing_Area_V
), "expose_event",
287 G_CALLBACK (expose_event_cb
), Control_Flow_Data
);
292 g_signal_connect (G_OBJECT (drawing_area
), "expose_event",
293 G_CALLBACK (expose_event_callback
), Control_Flow_Data
);
297 Control_Flow_Data
->VAdjust_C
= gtk_range_get_adjustment(GTK_RANGE(Control_Flow_Data
->VScroll_VC
));
299 g_signal_connect (G_OBJECT (Control_Flow_Data
->VAdjust_C
), "value-changed",
300 G_CALLBACK (v_scroll_cb
),
302 /* Set the upper bound to the last event number */
303 Control_Flow_Data
->VAdjust_C
->lower
= 0;
304 Control_Flow_Data
->VAdjust_C
->upper
= Control_Flow_Data
->Number_Of_Events
;
305 Control_Flow_Data
->VAdjust_C
->value
= 0;
306 Control_Flow_Data
->VAdjust_C
->step_increment
= 1;
307 Control_Flow_Data
->VAdjust_C
->page_increment
=
308 Control_Flow_Data
->VTree_Adjust_C
->upper
;
309 Control_Flow_Data
->VAdjust_C
->page_size
=
310 Control_Flow_Data
->VTree_Adjust_C
->upper
;
311 g_critical("value : %u",Control_Flow_Data
->VTree_Adjust_C
->upper
);
316 /* Add the object's information to the module's array */
317 g_slist_append(sControl_Flow_Data_List
, Control_Flow_Data
);
319 Control_Flow_Data
->First_Event
= -1 ;
320 Control_Flow_Data
->Last_Event
= 0 ;
322 Control_Flow_Data
->Num_Visible_Events
= 1;
325 get_test_data((int)Control_Flow_Data
->VAdjust_C
->value
,
326 Control_Flow_Data
->Num_Visible_Events
,
329 /* Set the Selected Event */
330 //Tree_V_set_cursor(Control_Flow_Data);
334 g_signal_connect (G_OBJECT (Control_Flow_Data
->VAdjust_C
), "value-changed",
335 G_CALLBACK (v_scroll_cb
),
337 g_signal_connect (G_OBJECT (Control_Flow_Data
->VAdjust_Draw_C
), "value-changed",
338 G_CALLBACK (v_scroll_cb
),
344 add_test_process(Control_Flow_Data
);
348 /* Set the size of the drawing area */
349 Drawing_Area_Init(Control_Flow_Data
);
354 gtk_widget_show(Control_Flow_Data
->Drawing_Area_V
);
355 gtk_widget_show(Control_Flow_Data
->Process_List_VC
);
356 gtk_widget_show(Control_Flow_Data
->Process_Scrolled_Window_VC
);
357 gtk_widget_show(Control_Flow_Data
->Drawing_Scrolled_Window_VC
);
358 gtk_widget_show(Control_Flow_Data
->HBox_V
);
361 test_draw(Control_Flow_Data
);
363 return Control_Flow_Data
;
367 gint
get_cell_height(GtkTreeView
*TreeView
)
370 GtkTreeViewColumn
*Column
= gtk_tree_view_get_column(TreeView
, 0);
371 GList
*Render_List
= gtk_tree_view_column_get_cell_renderers(Column
);
372 GtkCellRenderer
*Renderer
= g_list_first(Render_List
)->data
;
374 gtk_tree_view_column_cell_get_size(Column
, NULL
, NULL
, NULL
, NULL
, &height
);
375 g_critical("cell 0 height : %u",height
);
381 void Drawing_Area_Init(ControlFlowData
*Control_Flow_Data
)
383 DrawingAreaInfo
*Drawing_Area_Info
= &Control_Flow_Data
->Drawing_Area_Info
;
385 //GdkWindow *Tree_View_Window = gtk_tree_view_get_bin_window(
386 // GTK_TREE_VIEW(Control_Flow_Data->Process_List_VC));
387 //GdkRectangle visible_rect ;
391 //gdk_drawable_get_size(Tree_View_Window, NULL, &h);
392 //gdk_drawable_get_size(GTK_TREE_VIEW(Control_Flow_Data->Process_List_VC)->priv->bin_window, NULL, &h);
393 //gtk_widget_get_size_request(GTK_WIDGET(Control_Flow_Data->Process_Scrolled_Window_VC), NULL, &h);
394 //gdk_window_get_geometry(Tree_View_Window, NULL, NULL, &w, &h, NULL);
395 //gtk_tree_view_get_visible_rect(GTK_TREE_VIEW(Control_Flow_Data->Process_List_VC), &visible_rect);
396 //h = visible_rect.height;
397 /* 4 is probably the 2 pixels that the outside cells does not have */
398 Drawing_Area_Info
->height
=
399 get_cell_height(GTK_TREE_VIEW(Control_Flow_Data
->Process_List_VC
))
400 * Control_Flow_Data
->Number_Of_Process
- 4 ;
402 gtk_widget_set_size_request (Control_Flow_Data
->Drawing_Area_V
,
404 Drawing_Area_Info
->height
);
410 void expose_event_cb (GtkWidget
*widget
, GdkEventExpose
*expose
, gpointer data
)
412 ControlFlowData
*Control_Flow_Data
= (ControlFlowData
*)data
;
414 g_critical("expose");
416 /* When redrawing, use widget->allocation.width to get the width of
418 Control_Flow_Data
->Drawing_Area_Info
.width
= widget
->allocation
.width
;
420 test_draw(Control_Flow_Data
);
422 //gdk_draw_arc (widget->window,
423 // widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
425 // //0, 0, widget->allocation.width, widget->allocation.height,
426 // 0, 0, widget->allocation.width,
427 // Control_Flow_Data->Drawing_Area_Info.height,
431 //Drawing_Area_Init(Control_Flow_Data);
437 void v_scroll_cb (GtkAdjustment
*adjustment
, gpointer data
)
439 ControlFlowData
*Control_Flow_Data
= (ControlFlowData
*)data
;
440 GtkTreePath
*Tree_Path
;
442 g_critical("DEBUG : scroll signal, value : %f", adjustment
->value
);
444 //get_test_data((int)adjustment->value, Control_Flow_Data->Num_Visible_Events,
445 // Control_Flow_Data);
455 void add_test_process(ControlFlowData
*Control_Flow_Data
)
459 gchar
*process
[] = { "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten" };
461 for(i
=0; i
<Control_Flow_Data
->Number_Of_Process
; i
++)
463 /* Add a new row to the model */
464 gtk_list_store_append (Control_Flow_Data
->Store_M
, &iter
);
465 gtk_list_store_set (Control_Flow_Data
->Store_M
, &iter
,
466 PROCESS_COLUMN
, process
[i
],
474 void test_draw(ControlFlowData
*Control_Flow_Data
)
476 /* Draw event states using available height, Number of process, cell height
477 * (don't forget to remove two pixels at beginning and end).
478 * For horizontal : use width, Time_Begin, Time_End.
479 * This function calls the reading library to get the draw_hook called
480 * for the desired period of time. */
482 DrawingAreaInfo
*Drawing_Area_Info
= &Control_Flow_Data
->Drawing_Area_Info
;
488 /*void Tree_V_set_cursor(ControlFlowData *Control_Flow_Data)
492 if(Control_Flow_Data->Selected_Event && Control_Flow_Data->First_Event != -1)
494 gtk_adjustment_set_value(Control_Flow_Data->VAdjust_C,
495 Control_Flow_Data->Currently_Selected_Event);
497 path = gtk_tree_path_new_from_indices(
498 Control_Flow_Data->Currently_Selected_Event-
499 Control_Flow_Data->First_Event,
502 gtk_tree_view_set_cursor(GTK_TREE_VIEW(Control_Flow_Data->Tree_V), path, NULL, FALSE);
503 gtk_tree_path_free(path);
507 void Tree_V_get_cursor(ControlFlowData *Control_Flow_Data)
512 gtk_tree_view_get_cursor(GTK_TREE_VIEW(Control_Flow_Data->Tree_V), &path, NULL);
513 indices = gtk_tree_path_get_indices(path);
517 Control_Flow_Data->Selected_Event = TRUE;
518 Control_Flow_Data->Currently_Selected_Event =
519 Control_Flow_Data->First_Event + indices[0];
522 Control_Flow_Data->Selected_Event = FALSE;
523 Control_Flow_Data->Currently_Selected_Event = 0;
525 g_critical("DEBUG : Event Selected : %i , num: %u", Control_Flow_Data->Selected_Event, Control_Flow_Data->Currently_Selected_Event) ;
527 gtk_tree_path_free(path);
533 void Tree_V_move_cursor_cb (GtkWidget
*widget
, GtkMovementStep arg1
, gint arg2
, gpointer data
)
535 GtkTreePath
*path
; // = gtk_tree_path_new();
538 ControlFlowData
*Control_Flow_Data
= (ControlFlowData
*)data
;
540 gtk_tree_view_get_cursor(GTK_TREE_VIEW(Control_Flow_Data
->Tree_V
), &path
, NULL
);
543 /* No prior cursor, put it at beginning of page and let the execution do */
544 path
= gtk_tree_path_new_from_indices(0, -1);
545 gtk_tree_view_set_cursor(GTK_TREE_VIEW(Control_Flow_Data
->Tree_V
), path
, NULL
, FALSE
);
548 indices
= gtk_tree_path_get_indices(path
);
550 g_critical("DEBUG : move cursor step : %u , int : %i , indice : %i", (guint
)arg1
, arg2
, indices
[0]) ;
552 value
= gtk_adjustment_get_value(Control_Flow_Data
->VAdjust_C
);
554 if(arg1
== GTK_MOVEMENT_DISPLAY_LINES
)
559 /* move one line down */
560 if(indices
[0] == Control_Flow_Data
->Num_Visible_Events
- 1)
562 if(value
+ Control_Flow_Data
->Num_Visible_Events
<=
563 Control_Flow_Data
->Number_Of_Events
-1)
565 g_critical("need 1 event down") ;
566 Control_Flow_Data
->Currently_Selected_Event
+= 1;
567 gtk_adjustment_set_value(Control_Flow_Data
->VAdjust_C
, value
+1);
568 //gtk_tree_path_free(path);
569 //path = gtk_tree_path_new_from_indices(Control_Flow_Data->Num_Visible_Events-1, -1);
570 //gtk_tree_view_set_cursor(GTK_TREE_VIEW(Control_Flow_Data->Tree_V), path, NULL, FALSE);
571 g_signal_stop_emission_by_name(G_OBJECT(widget
), "move-cursor");
575 /* Move one line up */
580 g_critical("need 1 event up") ;
581 Control_Flow_Data
->Currently_Selected_Event
-= 1;
582 gtk_adjustment_set_value(Control_Flow_Data
->VAdjust_C
, value
-1);
583 //gtk_tree_path_free(path);
584 //path = gtk_tree_path_new_from_indices(0, -1);
585 //gtk_tree_view_set_cursor(GTK_TREE_VIEW(Control_Flow_Data->Tree_V), path, NULL, FALSE);
586 g_signal_stop_emission_by_name(G_OBJECT(widget
), "move-cursor");
594 if(arg1
== GTK_MOVEMENT_PAGES
)
599 if(Control_Flow_Data
->Num_Visible_Events
== 1)
601 /* move one page down */
602 if(value
+ Control_Flow_Data
->Num_Visible_Events
-1 <=
603 Control_Flow_Data
->Number_Of_Events
)
605 g_critical("need 1 page down") ;
607 Control_Flow_Data
->Currently_Selected_Event
+= Control_Flow_Data
->Num_Visible_Events
-1;
608 gtk_adjustment_set_value(Control_Flow_Data
->VAdjust_C
,
609 value
+(Control_Flow_Data
->Num_Visible_Events
-1));
610 //gtk_tree_path_free(path);
611 //path = gtk_tree_path_new_from_indices(0, -1);
612 //gtk_tree_view_set_cursor(GTK_TREE_VIEW(Control_Flow_Data->Tree_V), path, NULL, FALSE);
613 g_signal_stop_emission_by_name(G_OBJECT(widget
), "move-cursor");
616 /* Move one page up */
617 if(Control_Flow_Data
->Num_Visible_Events
== 1)
620 if(indices
[0] < Control_Flow_Data
->Num_Visible_Events
- 2 )
622 if(value
- (Control_Flow_Data
->Num_Visible_Events
-1) >= 0)
624 g_critical("need 1 page up") ;
626 Control_Flow_Data
->Currently_Selected_Event
-= Control_Flow_Data
->Num_Visible_Events
-1;
628 gtk_adjustment_set_value(Control_Flow_Data
->VAdjust_C
,
629 value
-(Control_Flow_Data
->Num_Visible_Events
-1));
630 //gtk_tree_path_free(path);
631 //path = gtk_tree_path_new_from_indices(0, -1);
632 //gtk_tree_view_set_cursor(GTK_TREE_VIEW(Control_Flow_Data->Tree_V), path, NULL, FALSE);
633 g_signal_stop_emission_by_name(G_OBJECT(widget
), "move-cursor");
636 /* Go to first Event */
637 g_critical("need 1 page up") ;
639 Control_Flow_Data
->Currently_Selected_Event
== 0 ;
640 gtk_adjustment_set_value(Control_Flow_Data
->VAdjust_C
,
642 //gtk_tree_path_free(path);
643 //path = gtk_tree_path_new_from_indices(0, -1);
644 //gtk_tree_view_set_cursor(GTK_TREE_VIEW(Control_Flow_Data->Tree_V), path, NULL, FALSE);
645 g_signal_stop_emission_by_name(G_OBJECT(widget
), "move-cursor");
654 if(arg1
== GTK_MOVEMENT_BUFFER_ENDS
)
656 /* Move to the ends of the buffer */
659 /* move end of buffer */
660 g_critical("End of buffer") ;
661 Control_Flow_Data
->Currently_Selected_Event
= Control_Flow_Data
->Number_Of_Events
-1 ;
662 gtk_adjustment_set_value(Control_Flow_Data
->VAdjust_C
,
663 Control_Flow_Data
->Number_Of_Events
-
664 Control_Flow_Data
->Num_Visible_Events
);
665 //gtk_tree_path_free(path);
666 //path = gtk_tree_path_new_from_indices(Control_Flow_Data->Num_Visible_Events-1, -1);
667 //gtk_tree_view_set_cursor(GTK_TREE_VIEW(Control_Flow_Data->Tree_V), path, NULL, FALSE);
668 g_signal_stop_emission_by_name(G_OBJECT(widget
), "move-cursor");
670 /* Move beginning of buffer */
671 g_critical("Beginning of buffer") ;
672 Control_Flow_Data
->Currently_Selected_Event
= 0 ;
673 gtk_adjustment_set_value(Control_Flow_Data
->VAdjust_C
, 0);
674 //gtk_tree_path_free(path);
675 //path = gtk_tree_path_new_from_indices(0, -1);
676 //gtk_tree_view_set_cursor(GTK_TREE_VIEW(Control_Flow_Data->Tree_V), path, NULL, FALSE);
677 g_signal_stop_emission_by_name(G_OBJECT(widget
), "move-cursor");
683 gtk_tree_path_free(path
);
686 void Tree_V_cursor_changed_cb (GtkWidget
*widget
, gpointer data
)
688 ControlFlowData
*Control_Flow_Data
= (ControlFlowData
*) data
;
690 g_critical("DEBUG : cursor change");
691 /* On cursor change, modify the currently selected event by calling
692 * the right API function */
693 Tree_V_get_cursor(Control_Flow_Data
);
697 void v_scroll_cb (GtkAdjustment
*adjustment
, gpointer data
)
699 ControlFlowData
*Control_Flow_Data
= (ControlFlowData
*)data
;
700 GtkTreePath
*Tree_Path
;
702 g_critical("DEBUG : scroll signal, value : %f", adjustment
->value
);
704 get_test_data((int)adjustment
->value
, Control_Flow_Data
->Num_Visible_Events
,
708 if(Control_Flow_Data
->Currently_Selected_Event
709 >= Control_Flow_Data
->First_Event
711 Control_Flow_Data
->Currently_Selected_Event
712 <= Control_Flow_Data
->Last_Event
714 Control_Flow_Data
->Selected_Event
)
717 Tree_Path
= gtk_tree_path_new_from_indices(
718 Control_Flow_Data
->Currently_Selected_Event
-
719 Control_Flow_Data
->First_Event
,
722 gtk_tree_view_set_cursor(GTK_TREE_VIEW(Control_Flow_Data
->Tree_V
), Tree_Path
,
724 gtk_tree_path_free(Tree_Path
);
730 gint
get_cell_height(GtkTreeView
*TreeView
)
733 GtkTreeViewColumn
*Column
= gtk_tree_view_get_column(TreeView
, 0);
734 GList
*Render_List
= gtk_tree_view_column_get_cell_renderers(Column
);
735 GtkCellRenderer
*Renderer
= g_list_first(Render_List
)->data
;
737 gtk_tree_view_column_cell_get_size(Column
, NULL
, NULL
, NULL
, NULL
, &height
);
738 g_critical("cell 0 height : %u",height
);
743 void Tree_V_size_allocate_cb (GtkWidget
*widget
, GtkAllocation
*alloc
, gpointer data
)
745 ControlFlowData
*Control_Flow_Data
= (ControlFlowData
*)data
;
746 gint Cell_Height
= get_cell_height(GTK_TREE_VIEW(Control_Flow_Data
->Tree_V
));
747 gint Last_Num_Visible_Events
= Control_Flow_Data
->Num_Visible_Events
;
748 gdouble Exact_Num_Visible
;
750 g_critical("size-allocate");
752 Exact_Num_Visible
= ( alloc
->height
-
753 TREE_VIEW_HEADER_HEIGHT (GTK_TREE_VIEW(Control_Flow_Data
->Tree_V
)) )
754 / (double)Cell_Height
;
756 Control_Flow_Data
->Num_Visible_Events
= ceil(Exact_Num_Visible
) ;
758 g_critical("number of events shown : %u",Control_Flow_Data
->Num_Visible_Events
);
759 g_critical("ex number of events shown : %f",Exact_Num_Visible
);
761 Control_Flow_Data
->VAdjust_C
->page_increment
=
762 floor(Exact_Num_Visible
);
763 Control_Flow_Data
->VAdjust_C
->page_size
=
764 floor(Exact_Num_Visible
);
766 if(Control_Flow_Data
->Num_Visible_Events
!= Last_Num_Visible_Events
)
768 get_test_data((int)Control_Flow_Data
->VAdjust_C
->value
,
769 Control_Flow_Data
->Num_Visible_Events
,
776 void Tree_V_size_request_cb (GtkWidget
*widget
, GtkRequisition
*requisition
, gpointer data
)
779 ControlFlowData
*Control_Flow_Data
= (ControlFlowData
*)data
;
780 gint Cell_Height
= get_cell_height(GTK_TREE_VIEW(Control_Flow_Data
->Tree_V
));
782 g_critical("size-request");
784 h
= Cell_Height
+ TREE_VIEW_HEADER_HEIGHT
785 (GTK_TREE_VIEW(Control_Flow_Data
->Tree_V
));
786 requisition
->height
= h
;
792 void get_test_data(guint Event_Number
, guint List_Height
,
793 ControlFlowData
*Control_Flow_Data
)
797 //GtkTreeModel *model = GTK_TREE_MODEL(Control_Flow_Data->Store_M);
798 //GtkTreePath *Tree_Path;
801 // if(Event_Number > Control_Flow_Data->Last_Event ||
802 // Event_Number + List_Height-1 < Control_Flow_Data->First_Event ||
803 // Control_Flow_Data->First_Event == -1)
805 /* no event can be reused, clear and start from nothing */
806 //gtk_list_store_clear(Control_Flow_Data->Store_M);
807 for(i
=Event_Number
; i
<Event_Number
+List_Height
; i
++)
809 if(i
>=Control_Flow_Data
->Number_Of_Events
) break;
810 /* Add a new row to the model */
811 // gtk_list_store_append (Control_Flow_Data->Store_M, &iter);
812 // gtk_list_store_set (Control_Flow_Data->Store_M, &iter,
814 // EVENT_COLUMN, "event irq",
817 // ENTRY_LEN_COLUMN, 17,
818 // EVENT_DESCR_COLUMN, "Detailed information",
822 #ifdef DEBUG //do not use this, it's slower and broken
824 /* Some events will be reused */
825 if(Event_Number
< Control_Flow_Data
->First_Event
)
827 /* scrolling up, prepend events */
828 Tree_Path
= gtk_tree_path_new_from_indices
829 (Event_Number
+List_Height
-1 -
830 Control_Flow_Data
->First_Event
+ 1,
832 for(i
=0; i
<Control_Flow_Data
->Last_Event
-(Event_Number
+List_Height
-1);
835 /* Remove the last events from the list */
836 if(gtk_tree_model_get_iter(model
, &iter
, Tree_Path
))
837 gtk_list_store_remove(Control_Flow_Data
->Store_M
, &iter
);
840 for(i
=Control_Flow_Data
->First_Event
-1; i
>=Event_Number
; i
--)
842 if(i
>=Control_Flow_Data
->Number_Of_Events
) break;
843 /* Prepend new events */
844 gtk_list_store_prepend (Control_Flow_Data
->Store_M
, &iter
);
845 gtk_list_store_set (Control_Flow_Data
->Store_M
, &iter
,
847 EVENT_COLUMN
, "event irq",
850 ENTRY_LEN_COLUMN
, 17,
851 EVENT_DESCR_COLUMN
, "Detailed information",
855 /* Scrolling down, append events */
856 for(i
=Control_Flow_Data
->First_Event
; i
<Event_Number
; i
++)
858 /* Remove these events from the list */
859 gtk_tree_model_get_iter_first(model
, &iter
);
860 gtk_list_store_remove(Control_Flow_Data
->Store_M
, &iter
);
862 for(i
=Control_Flow_Data
->Last_Event
+1; i
<Event_Number
+List_Height
; i
++)
864 if(i
>=Control_Flow_Data
->Number_Of_Events
) break;
865 /* Append new events */
866 gtk_list_store_append (Control_Flow_Data
->Store_M
, &iter
);
867 gtk_list_store_set (Control_Flow_Data
->Store_M
, &iter
,
869 EVENT_COLUMN
, "event irq",
872 ENTRY_LEN_COLUMN
, 17,
873 EVENT_DESCR_COLUMN
, "Detailed information",
880 Control_Flow_Data
->First_Event
= Event_Number
;
881 Control_Flow_Data
->Last_Event
= Event_Number
+List_Height
-1 ;
888 void add_test_data(ControlFlowData
*Control_Flow_Data
)
895 /* Add a new row to the model */
896 gtk_list_store_append (Control_Flow_Data
->Store_M
, &iter
);
897 gtk_list_store_set (Control_Flow_Data
->Store_M
, &iter
,
899 EVENT_COLUMN
, "event irq",
902 ENTRY_LEN_COLUMN
, 17,
903 EVENT_DESCR_COLUMN
, "Detailed information",
911 GuiControlFlow_Destructor(ControlFlowData
*Control_Flow_Data
)
915 /* May already been done by GTK window closing */
916 if(GTK_IS_WIDGET(Control_Flow_Data
->HBox_V
))
917 gtk_widget_destroy(Control_Flow_Data
->HBox_V
);
919 /* Destroy the Tree View */
920 //gtk_widget_destroy(Control_Flow_Data->Tree_V);
922 /* Clear raw event list */
923 //gtk_list_store_clear(Control_Flow_Data->Store_M);
924 //gtk_widget_destroy(GTK_WIDGET(Control_Flow_Data->Store_M));
926 g_slist_remove(sControl_Flow_Data_List
,Control_Flow_Data
);
929 //FIXME : call hGuiEvents_Destructor for corresponding data upon widget destroy
933 tree_selection_changed_cb (GtkTreeSelection
*selection
, gpointer data
)
935 ControlFlowData
*Control_Flow_Data
= (ControlFlowData
*)data
;
937 GtkTreeModel
*model
= GTK_TREE_MODEL(Control_Flow_Data
->Store_M
);
940 if (gtk_tree_selection_get_selected (selection
, &model
, &iter
))
942 gtk_tree_model_get (model
, &iter
, EVENT_COLUMN
, &Event
, -1);
944 g_print ("Event selected : %s\n", Event
);
952 int Event_Selected_Hook(void *hook_data
, void *call_data
)
954 ControlFlowData
*Control_Flow_Data
= (ControlFlowData
*) hook_data
;
955 guint
*Event_Number
= (guint
*) call_data
;
957 g_critical("DEBUG : event selected by main window : %u", *Event_Number
);
959 // Control_Flow_Data->Currently_Selected_Event = *Event_Number;
960 // Control_Flow_Data->Selected_Event = TRUE ;
962 // Tree_V_set_cursor(Control_Flow_Data);
968 static void destroy_cb( GtkWidget
*widget
,
976 int main(int argc
, char **argv
)
979 GtkWidget
*CF_Viewer
;
981 GtkWidget
*HScroll_VC
;
982 ControlFlowData
*Control_Flow_Data
;
984 /* Horizontal scrollbar and it's adjustment */
985 GtkWidget
*VScroll_VC
;
986 GtkAdjustment
*VAdjust_C
;
988 /* Initialize i18n support */
991 /* Initialize the widget set */
992 gtk_init (&argc
, &argv
);
996 Window
= gtk_window_new (GTK_WINDOW_TOPLEVEL
);
997 gtk_window_set_title (GTK_WINDOW (Window
), ("Test Window"));
999 g_signal_connect (G_OBJECT (Window
), "destroy",
1000 G_CALLBACK (destroy_cb
), NULL
);
1003 VBox_V
= gtk_vbox_new(0, 0);
1004 gtk_container_add (GTK_CONTAINER (Window
), VBox_V
);
1006 //ListViewer = hGuiEvents(Window);
1007 //gtk_box_pack_start(GTK_BOX(VBox_V), ListViewer, TRUE, TRUE, 0);
1009 //ListViewer = hGuiEvents(Window);
1010 //gtk_box_pack_start(GTK_BOX(VBox_V), ListViewer, FALSE, TRUE, 0);
1012 Control_Flow_Data
= GuiControlFlow();
1013 CF_Viewer
= Control_Flow_Data
->HBox_V
;
1014 gtk_box_pack_start(GTK_BOX(VBox_V
), CF_Viewer
, TRUE
, TRUE
, 0);
1016 /* Create horizontal scrollbar and pack it */
1017 HScroll_VC
= gtk_hscrollbar_new(NULL
);
1018 gtk_box_pack_start(GTK_BOX(VBox_V
), HScroll_VC
, FALSE
, TRUE
, 0);
1021 gtk_widget_show (HScroll_VC
);
1022 gtk_widget_show (VBox_V
);
1023 gtk_widget_show (Window
);
1025 //Event_Selected_Hook(Control_Flow_Data, &ev_sel);
1029 g_critical("main loop finished");
1031 //hGuiEvents_Destructor(ListViewer);
1033 //g_critical("GuiEvents Destructor finished");