update pid for all tracefiles of a trace
[lttv.git] / ltt / branches / poly / lttv / modules / guiControlFlow / Draw_Item.c
CommitLineData
cf6cb7e0 1/******************************************************************************
2 * Draw_Item.c
3 *
4 * This file contains methods responsible for drawing a generic type of data
5 * in a drawable. Doing this generically will permit user defined drawing
6 * behavior in a later time.
7 *
b782dd11 8 * This file provides an API which is meant to be reusable for all viewers that
9 * need to show information in line, icon, text, background or point form in
10 * a drawable area having time for x axis. The y axis, in the control flow
11 * viewer case, is corresponding to the different processes, but it can be
12 * reused integrally for cpu, and eventually locks, buffers, network
13 * interfaces... What will differ between the viewers is the precise
14 * information which interests us. We may think that the most useful
15 * information for control flow are some specific events, like schedule
16 * change, and processes'states. It may differ for a cpu viewer : the
17 * interesting information could be more the execution mode of each cpu.
18 * This API in meant to make viewer's writers life easier : it will become
19 * a simple choice of icons and line types for the precise information
20 * the viewer has to provide (agremented with keeping supplementary records
21 * and modifying slightly the DrawContext to suit the needs.)
22 *
f0728492 23 * We keep each data type in attributes, keys to specific information
24 * being formed from the GQuark corresponding to the information received.
25 * (facilities / facility_name / events / eventname.)
26 * (cpus/cpu_name, process_states/ps_name,
27 * execution_modes/em_name, execution_submodes/es_name).
cf6cb7e0 28 * The goal is then to provide a generic way to print information on the
29 * screen for all this different information.
30 *
31 * Information can be printed as
32 *
33 * - text (text + color + size + position (over or under line)
34 * - icon (icon filename, corresponding to a loaded icon, accessible through
35 * a GQuark. Icons are loaded statically at the guiControlFlow level during
36 * module initialization and can be added on the fly if not present in the
37 * GQuark.) The habitual place for xpm icons is in
38 * ${prefix}/share/LinuxTraceToolkit.) + position (over or under line)
39 * - line (color, width, style)
189a5d08 40 * - Arc (big points) (color, size)
cf6cb7e0 41 * - background color (color)
42 *
189a5d08 43 * An item is a leaf of the attributes tree. It is, in that case, including
44 * all kind of events categories we can have. It then associates each category
45 * with one or more actions (drawing something) or nothing.
46 *
7d5ffafa 47 * Each item has an array of hooks (hook list). Each hook represents an
48 * operation to perform. We seek the array each time we want to
a2e850ff 49 * draw an item. We execute each operation in order. An operation type
50 * is associated with each hook to permit user listing and modification
51 * of these operations. The operation type is also used to find the
52 * corresponding priority for the sorting. Operation type and priorities
53 * are enum and a static int table.
cf6cb7e0 54 *
55 * The array has to be sorted by priority each time we add a task in it.
a2e850ff 56 * A priority is associated with each operation type. It permits
cf6cb7e0 57 * to perform background color selection before line or text drawing. We also
58 * draw lines before text, so the text appears over the lines.
59 *
60 * Executing all the arrays of operations for a specific event (which
61 * implies information for state, event, cpu, execution mode and submode)
62 * has to be done in a same DrawContext. The goal there is to keep the offset
63 * of the text and icons over and under the middle line, so a specific
64 * event could be printed as ( R Si 0 for running, scheduled in, cpu 0 ),
7d5ffafa 65 * text being easy to replace with icons. The DrawContext is passed as
66 * call_data for the operation hooks.
cf6cb7e0 67 *
b782dd11 68 * We use the lttv global attributes to keep track of the loaded icons.
69 * If we need an icon, we look for it in the icons / icon name pathname.
70 * If found, we use the pointer to it. If not, we load the pixmap in
71 * memory and set the pointer to the GdkPixmap in the attributes.
72 *
cf6cb7e0 73 * Author : Mathieu Desnoyers, October 2003
74 */
7d5ffafa 75
76#include <glib.h>
09e2606f 77#include <gtk/gtk.h>
78#include <gdk/gdk.h>
7d5ffafa 79#include <lttv/hook.h>
f0728492 80#include <lttv/attribute.h>
81#include <lttv/iattribute.h>
7d5ffafa 82
b782dd11 83#include <lttv/processTrace.h>
84#include <lttv/state.h>
85
09e2606f 86#include "Draw_Item.h"
87
b782dd11 88/* The DrawContext keeps information about the current drawing position and
89 * the previous one, so we can use both to draw lines.
90 *
91 * over : position for drawing over the middle line.
92 * middle : middle line position.
93 * under : position for drawing under the middle line.
09e2606f 94 *
95 * the modify_* are used to take into account that we should go forward
96 * when we draw a text, an arc or an icon, while it's unneeded when we
97 * draw a line or background.
b782dd11 98 */
99struct _DrawContext {
100 GdkDrawable *drawable;
101 GdkGC *gc;
102
103 DrawInfo *Current;
104 DrawInfo *Previous;
105};
106
107struct _DrawInfo {
108 ItemInfo *over;
109 ItemInfo *middle;
110 ItemInfo *under;
09e2606f 111
112 ItemInfo *modify_over;
113 ItemInfo *modify_middle;
114 ItemInfo *modify_under;
b782dd11 115};
116
117/* LttvExecutionState is accessible through the LttvTracefileState. Is has
118 * a pointer to the LttvProcessState which points to the top of stack
119 * execution state : LttvExecutionState *state.
120 *
121 * LttvExecutionState contains (useful here):
122 * LttvExecutionMode t,
123 * LttvExecutionSubmode n,
124 * LttvProcessStatus s
125 *
126 *
127 * LttvTraceState will be used in the case we need the string of the
128 * different processes, eventtype_names, syscall_names, trap_names, irq_names.
129 *
130 * LttvTracefileState also gives the cpu_name and, as it herits from
131 * LttvTracefileContext, it gives the LttEvent structure, which is needed
132 * to get facility name and event name.
133 */
134struct _ItemInfo {
135 gint x, y;
136 LttvTraceState *ts;
137 LttvTracefileState *tfs;
138};
139
140
141/*
142 * The Item element is only used so the DrawOperation is modifiable by users.
143 * During drawing, only the Hook is needed.
144 */
145struct _DrawOperation {
146 DrawableItems Item;
147 LttvHooks *Hook;
148};
149
150/*
151 * We define here each items that can be drawn, together with their
152 * associated priority. Many item types can have the same priority,
153 * it's only used for quicksorting the operations when we add a new one
154 * to the array of operations to perform. Lower priorities are executed
155 * first. So, for example, we may want to give background color a value
156 * of 10 while a line would have 20, so the background color, which
157 * is in fact a rectangle, does not hide the line.
158 */
159
09e2606f 160static int Items_Priorities[] = {
b782dd11 161 50, /* ITEM_TEXT */
162 40, /* ITEM_ICON */
163 20, /* ITEM_LINE */
164 30, /* ITEM_POINT */
165 10 /* ITEM_BACKGROUND */
166};
167
b782dd11 168/*
169 * Here are the different structures describing each item type that can be
170 * drawn. They contain the information necessary to draw the item : not the
171 * position (this is provided by the DrawContext), but the text, icon name,
172 * line width, color; all the properties of the specific items.
173 */
174
175struct _PropertiesText {
176 GdkColor *foreground;
177 GdkColor *background;
178 gint size;
179 gchar *Text;
180 RelPos position;
181};
182
183
184struct _PropertiesIcon {
185 gchar *icon_name;
186 gint width;
187 gint height;
188 RelPos position;
189};
190
191struct _PropertiesLine {
192 GdkColor *color;
193 gint line_width;
194 GdkLineStyle style;
195 RelPos position;
196};
197
198struct _PropertiesArc {
199 GdkColor *color;
200 gint size; /* We force circle by width = height */
201 gboolean filled;
202 RelPos position;
203};
204
205struct _PropertiesBG {
206 GdkColor *color;
207};
208
209
b782dd11 210/* Drawing hook functions */
4c69e0cc 211gboolean draw_text( void *hook_data, void *call_data)
b782dd11 212{
213 PropertiesText *Properties = (PropertiesText*)hook_data;
214 DrawContext *Draw_Context = (DrawContext*)call_data;
09e2606f 215
216 PangoContext *context;
217 PangoLayout *layout;
218 PangoFontDescription *FontDesc;// = pango_font_description_new();
219 gint Font_Size;
220 PangoRectangle ink_rect;
221
222 gdk_gc_set_foreground(Draw_Context->gc, Properties->foreground);
223 gdk_gc_set_background(Draw_Context->gc, Properties->background);
224
225 layout = gtk_widget_create_pango_layout(GTK_WIDGET(Draw_Context->drawable), NULL);
226 context = pango_layout_get_context(layout);
227 FontDesc = pango_context_get_font_description(context);
228 Font_Size = pango_font_description_get_size(FontDesc);
229 pango_font_description_set_size(FontDesc, Properties->size*PANGO_SCALE);
230
231
232 pango_layout_set_text(layout, Properties->Text, -1);
233 pango_layout_get_pixel_extents(layout, &ink_rect, NULL);
234 switch(Properties->position) {
235 case OVER:
236 gdk_draw_layout(Draw_Context->drawable, Draw_Context->gc,
237 Draw_Context->Current->modify_over->x,
238 Draw_Context->Current->modify_over->y,
239 layout);
240 Draw_Context->Current->modify_over->x += ink_rect.width;
241
242 break;
243 case MIDDLE:
244 gdk_draw_layout(Draw_Context->drawable, Draw_Context->gc,
245 Draw_Context->Current->modify_middle->x,
246 Draw_Context->Current->modify_middle->y,
247 layout);
248 Draw_Context->Current->modify_middle->x += ink_rect.width;
249 break;
250 case UNDER:
251 gdk_draw_layout(Draw_Context->drawable, Draw_Context->gc,
252 Draw_Context->Current->modify_under->x,
253 Draw_Context->Current->modify_under->y,
254 layout);
255 Draw_Context->Current->modify_under->x += ink_rect.width;
256 break;
257 }
258
259
260 pango_font_description_set_size(FontDesc, Font_Size);
261 g_free(layout);
262
263 return 0;
b782dd11 264}
265
4c69e0cc 266gboolean draw_icon( void *hook_data, void *call_data)
b782dd11 267{
268 PropertiesIcon *Properties = (PropertiesIcon*)hook_data;
269 DrawContext *Draw_Context = (DrawContext*)call_data;
270
09e2606f 271 GdkBitmap *mask = g_new(GdkBitmap, 1);
272 GdkPixmap *icon_pixmap = g_new(GdkPixmap, 1);
273 GdkGC *gc = gdk_gc_new(Draw_Context->drawable);
274 gdk_gc_copy(gc, Draw_Context->gc);
275
276 icon_pixmap = gdk_pixmap_create_from_xpm(Draw_Context->drawable, &mask, NULL,
277 Properties->icon_name);
278
279 gdk_gc_set_clip_mask(gc, mask);
280
281 switch(Properties->position) {
282 case OVER:
283 gdk_draw_drawable(Draw_Context->drawable,
284 gc,
285 icon_pixmap,
286 0, 0,
287 Draw_Context->Current->modify_over->x,
288 Draw_Context->Current->modify_over->y,
289 Properties->width, Properties->height);
290
291 Draw_Context->Current->modify_over->x += Properties->width;
292
293 break;
294 case MIDDLE:
295 gdk_draw_drawable(Draw_Context->drawable,
296 gc,
297 icon_pixmap,
298 0, 0,
299 Draw_Context->Current->modify_middle->x,
300 Draw_Context->Current->modify_middle->y,
301 Properties->width, Properties->height);
302
303
304 Draw_Context->Current->modify_middle->x += Properties->width;
305 break;
306 case UNDER:
307 gdk_draw_drawable(Draw_Context->drawable,
308 gc,
309 icon_pixmap,
310 0, 0,
311 Draw_Context->Current->modify_under->x,
312 Draw_Context->Current->modify_under->y,
313 Properties->width, Properties->height);
314
315 Draw_Context->Current->modify_under->x += Properties->width;
316 break;
317 }
318
319 g_free(gc);
320
321 return 0;
b782dd11 322}
323
4c69e0cc 324gboolean draw_line( void *hook_data, void *call_data)
b782dd11 325{
326 PropertiesLine *Properties = (PropertiesLine*)hook_data;
327 DrawContext *Draw_Context = (DrawContext*)call_data;
328
09e2606f 329 gdk_gc_set_foreground(Draw_Context->gc, Properties->color);
330 gdk_gc_set_line_attributes( Draw_Context->gc,
331 Properties->line_width,
332 Properties->style,
333 GDK_CAP_BUTT,
334 GDK_JOIN_MITER);
335
336 switch(Properties->position) {
337 case OVER:
338 drawing_draw_line(
339 NULL, Draw_Context->drawable,
340 Draw_Context->Previous->over->x,
341 Draw_Context->Previous->over->y,
342 Draw_Context->Current->over->x,
343 Draw_Context->Current->over->y,
344 Draw_Context->gc);
345 break;
346 case MIDDLE:
347 drawing_draw_line(
348 NULL, Draw_Context->drawable,
349 Draw_Context->Previous->middle->x,
350 Draw_Context->Previous->middle->y,
351 Draw_Context->Current->middle->x,
352 Draw_Context->Current->middle->y,
353 Draw_Context->gc);
354 break;
355 case UNDER:
356 drawing_draw_line(
357 NULL, Draw_Context->drawable,
358 Draw_Context->Previous->under->x,
359 Draw_Context->Previous->under->y,
360 Draw_Context->Current->under->x,
361 Draw_Context->Current->under->y,
362 Draw_Context->gc);
363
364 break;
365 }
366
367 return 0;
b782dd11 368}
369
4c69e0cc 370gboolean draw_arc( void *hook_data, void *call_data)
b782dd11 371{
372 PropertiesArc *Properties = (PropertiesArc*)hook_data;
373 DrawContext *Draw_Context = (DrawContext*)call_data;
374
09e2606f 375 gdk_gc_set_foreground(Draw_Context->gc, Properties->color);
376
377 switch(Properties->position) {
378 case OVER:
379 gdk_draw_arc(Draw_Context->drawable, Draw_Context->gc,
380 Properties->filled,
381 Draw_Context->Current->modify_over->x,
382 Draw_Context->Current->modify_over->y,
383 Properties->size, Properties->size, 0, 360*64);
384 Draw_Context->Current->modify_over->x += Properties->size;
385
386 break;
387 case MIDDLE:
388 gdk_draw_arc(Draw_Context->drawable, Draw_Context->gc,
389 Properties->filled,
390 Draw_Context->Current->modify_middle->x,
391 Draw_Context->Current->modify_middle->y,
392 Properties->size, Properties->size, 0, 360*64);
393 Draw_Context->Current->modify_middle->x += Properties->size;
394
395 break;
396 case UNDER:
397 gdk_draw_arc(Draw_Context->drawable, Draw_Context->gc,
398 Properties->filled,
399 Draw_Context->Current->modify_under->x,
400 Draw_Context->Current->modify_under->y,
401 Properties->size, Properties->size, 0, 360*64);
402 Draw_Context->Current->modify_under->x += Properties->size;
403
404 break;
405 }
406
407
408 return 0;
b782dd11 409}
410
4c69e0cc 411gboolean draw_bg( void *hook_data, void *call_data)
b782dd11 412{
413 PropertiesBG *Properties = (PropertiesBG*)hook_data;
414 DrawContext *Draw_Context = (DrawContext*)call_data;
415
09e2606f 416 gdk_gc_set_foreground(Draw_Context->gc, Properties->color);
417
418
419 gdk_draw_rectangle(Draw_Context->drawable, Draw_Context->gc,
420 TRUE,
421 Draw_Context->Previous->over->x,
422 Draw_Context->Previous->over->y,
423 Draw_Context->Current->over->x - Draw_Context->Previous->over->x,
424 Draw_Context->Previous->under->y);
425
426 return 0;
b782dd11 427}
428
429
This page took 0.055037 seconds and 4 git commands to generate.