f0d936c0 |
1 | |
fa2c4dbe |
2 | #include <gtk/gtk.h> |
3 | #include <glib.h> |
f0d936c0 |
4 | #include "Process_List.h" |
5 | |
fa2c4dbe |
6 | |
f0d936c0 |
7 | /***************************************************************************** |
8 | * Methods to synchronize process list * |
9 | *****************************************************************************/ |
10 | |
fa2c4dbe |
11 | typedef struct _ProcessInfo { |
12 | |
13 | guint pid; |
14 | LttTime birth; |
15 | |
16 | } ProcessInfo; |
17 | |
18 | |
19 | struct _ProcessList { |
f0d936c0 |
20 | |
21 | GtkWidget *Process_List_VC; |
22 | GtkListStore *Store_M; |
fa2c4dbe |
23 | |
24 | /* A hash table by PID to speed up process position find in the list */ |
25 | GHashTable *Process_Hash; |
f0d936c0 |
26 | |
27 | guint Number_Of_Process; |
28 | |
fa2c4dbe |
29 | }; |
f0d936c0 |
30 | |
31 | |
32 | /* Enumeration of the columns */ |
33 | enum |
34 | { |
35 | PROCESS_COLUMN, |
fa2c4dbe |
36 | PID_COLUMN, |
37 | BIRTH_S_COLUMN, |
38 | BIRTH_NS_COLUMN, |
f0d936c0 |
39 | N_COLUMNS |
40 | }; |
41 | |
42 | |
fa2c4dbe |
43 | gint process_sort_func ( GtkTreeModel *model, |
44 | GtkTreeIter *it_a, |
45 | GtkTreeIter *it_b, |
46 | gpointer user_data) |
47 | { |
48 | GValue a, b; |
49 | |
50 | memset(&a, 0, sizeof(GValue)); |
51 | memset(&b, 0, sizeof(GValue)); |
52 | |
53 | /* Order by PID */ |
54 | gtk_tree_model_get_value( model, |
55 | it_a, |
56 | PID_COLUMN, |
57 | &a); |
58 | |
59 | gtk_tree_model_get_value( model, |
60 | it_b, |
61 | PID_COLUMN, |
62 | &b); |
63 | |
64 | if(G_VALUE_TYPE(&a) == G_TYPE_UINT |
65 | && G_VALUE_TYPE(&b) == G_TYPE_UINT ) |
66 | { |
67 | if(g_value_get_uint(&a) > g_value_get_uint(&b)) |
68 | { |
69 | g_value_unset(&a); |
70 | g_value_unset(&b); |
71 | return 1; |
72 | } |
73 | if(g_value_get_uint(&a) < g_value_get_uint(&b)) |
74 | { |
75 | g_value_unset(&a); |
76 | g_value_unset(&b); |
77 | return 0; |
78 | } |
79 | } |
80 | |
81 | g_value_unset(&a); |
82 | g_value_unset(&b); |
83 | |
84 | |
85 | /* Order by birth second */ |
86 | gtk_tree_model_get_value( model, |
87 | it_a, |
88 | BIRTH_S_COLUMN, |
89 | &a); |
90 | |
91 | gtk_tree_model_get_value( model, |
92 | it_b, |
93 | BIRTH_S_COLUMN, |
94 | &b); |
95 | |
96 | |
97 | if(G_VALUE_TYPE(&a) == G_TYPE_ULONG |
98 | && G_VALUE_TYPE(&b) == G_TYPE_ULONG ) |
99 | { |
100 | if(g_value_get_ulong(&a) > g_value_get_ulong(&b)) |
101 | { |
102 | g_value_unset(&a); |
103 | g_value_unset(&b); |
104 | return 1; |
105 | } |
106 | if(g_value_get_ulong(&a) < g_value_get_ulong(&b)) |
107 | { |
108 | g_value_unset(&a); |
109 | g_value_unset(&b); |
110 | return 0; |
111 | } |
112 | |
113 | } |
114 | |
115 | g_value_unset(&a); |
116 | g_value_unset(&b); |
117 | |
118 | /* Order by birth nanosecond */ |
119 | gtk_tree_model_get_value( model, |
120 | it_a, |
121 | BIRTH_NS_COLUMN, |
122 | &a); |
123 | |
124 | gtk_tree_model_get_value( model, |
125 | it_b, |
126 | BIRTH_NS_COLUMN, |
127 | &b); |
128 | |
129 | |
130 | if(G_VALUE_TYPE(&a) == G_TYPE_ULONG |
131 | && G_VALUE_TYPE(&b) == G_TYPE_ULONG ) |
132 | { |
133 | if(g_value_get_ulong(&a) > g_value_get_ulong(&b)) |
134 | { |
135 | g_value_unset(&a); |
136 | g_value_unset(&b); |
137 | return 1; |
138 | } |
139 | // Final condition |
140 | //if(g_value_get_ulong(&a) < g_value_get_ulong(&b)) |
141 | //{ |
142 | // g_value_unset(&a); |
143 | // g_value_unset(&b); |
144 | // return 0; |
145 | //} |
146 | |
147 | } |
148 | |
149 | g_value_unset(&a); |
150 | g_value_unset(&b); |
151 | |
152 | return 0; |
153 | |
154 | } |
155 | |
156 | void send_test_data(ProcessList *Process_List) |
157 | { |
158 | guint height; |
159 | int i; |
160 | ProcessInfo Process_Info = {10000, 12000, 55600}; |
161 | //ProcessInfo Process_Info = {156, 14000, 55500}; |
162 | GtkTreeRowReference *got_RowRef; |
163 | |
164 | LttTime birth; |
165 | birth.tv_sec = 12000; |
166 | birth.tv_nsec = 55500; |
167 | |
168 | ProcessList_add(Process_List, |
169 | 1, |
170 | &birth, |
171 | &height); |
172 | |
173 | g_critical("height : %u", height); |
174 | |
175 | birth.tv_sec = 14000; |
176 | birth.tv_nsec = 55500; |
177 | |
178 | ProcessList_add(Process_List, |
179 | 156, |
180 | &birth, |
181 | &height); |
182 | |
183 | g_critical("height : %u", height); |
184 | |
185 | birth.tv_sec = 12000; |
186 | birth.tv_nsec = 55700; |
187 | |
188 | ProcessList_add(Process_List, |
189 | 10, |
190 | &birth, |
191 | &height); |
192 | |
193 | for(i=0; i<150; i++) |
194 | { |
195 | birth.tv_sec = i*12000; |
196 | birth.tv_nsec = i*55700; |
197 | |
198 | ProcessList_add(Process_List, |
199 | i, |
200 | &birth, |
201 | &height); |
202 | |
203 | } |
204 | g_critical("height : %u", height); |
205 | |
206 | birth.tv_sec = 12000; |
207 | birth.tv_nsec = 55600; |
208 | |
209 | ProcessList_add(Process_List, |
210 | 10, |
211 | &birth, |
212 | &height); |
213 | g_critical("height : %u", height); |
214 | |
215 | ProcessList_add(Process_List, |
216 | 10000, |
217 | &birth, |
218 | &height); |
219 | g_critical("height : %u", height); |
220 | |
221 | |
222 | ProcessList_remove( Process_List, |
223 | 10000, |
224 | &birth); |
225 | |
226 | if(got_RowRef = |
227 | (GtkTreeRowReference*)g_hash_table_lookup( |
228 | Process_List->Process_Hash, |
229 | &Process_Info)) |
230 | { |
231 | g_critical("key found"); |
232 | g_critical("position in the list : %s", |
233 | gtk_tree_path_to_string ( |
234 | gtk_tree_row_reference_get_path( |
235 | (GtkTreeRowReference*)got_RowRef) |
236 | )); |
237 | |
238 | } |
239 | |
240 | } |
241 | |
242 | |
243 | guint hash_fct(gconstpointer key) |
244 | { |
245 | return ((ProcessInfo*)key)->pid; |
246 | } |
247 | |
248 | gboolean equ_fct(gconstpointer a, gconstpointer b) |
249 | { |
250 | if(((ProcessInfo*)a)->pid != ((ProcessInfo*)b)->pid) |
251 | return 0; |
252 | g_critical("compare %u and %u",((ProcessInfo*)a)->pid,((ProcessInfo*)b)->pid); |
253 | if(((ProcessInfo*)a)->birth.tv_sec != ((ProcessInfo*)b)->birth.tv_sec) |
254 | return 0; |
255 | g_critical("compare %u and %u",((ProcessInfo*)a)->birth.tv_sec,((ProcessInfo*)b)->birth.tv_sec); |
256 | |
257 | if(((ProcessInfo*)a)->birth.tv_nsec != ((ProcessInfo*)b)->birth.tv_nsec) |
258 | return 0; |
259 | g_critical("compare %u and %u",((ProcessInfo*)a)->birth.tv_nsec,((ProcessInfo*)b)->birth.tv_nsec); |
260 | |
261 | return 1; |
262 | } |
263 | |
264 | void Destroy_hash_key(gpointer key); |
265 | |
266 | void Destroy_hash_data(gpointer data); |
267 | |
268 | |
269 | |
270 | |
558aa013 |
271 | ProcessList *ProcessList_construct(void) |
f0d936c0 |
272 | { |
273 | GtkTreeViewColumn *column; |
274 | GtkCellRenderer *renderer; |
275 | |
276 | ProcessList* Process_List = g_new(ProcessList,1); |
277 | |
fa2c4dbe |
278 | Process_List->Number_Of_Process = 0; |
279 | |
f0d936c0 |
280 | /* Create the Process list */ |
281 | Process_List->Store_M = gtk_list_store_new ( N_COLUMNS, |
fa2c4dbe |
282 | G_TYPE_STRING, |
283 | G_TYPE_UINT, |
284 | G_TYPE_ULONG, |
285 | G_TYPE_ULONG); |
f0d936c0 |
286 | |
287 | |
288 | Process_List->Process_List_VC = |
289 | gtk_tree_view_new_with_model |
290 | (GTK_TREE_MODEL (Process_List->Store_M)); |
291 | |
292 | g_object_unref (G_OBJECT (Process_List->Store_M)); |
293 | |
fa2c4dbe |
294 | gtk_tree_sortable_set_sort_func( |
295 | GTK_TREE_SORTABLE(Process_List->Store_M), |
296 | PID_COLUMN, |
297 | process_sort_func, |
298 | NULL, |
299 | NULL); |
300 | |
301 | gtk_tree_sortable_set_sort_column_id( |
302 | GTK_TREE_SORTABLE(Process_List->Store_M), |
303 | PID_COLUMN, |
304 | GTK_SORT_ASCENDING); |
305 | |
306 | Process_List->Process_Hash = g_hash_table_new_full( |
307 | hash_fct, equ_fct, |
308 | Destroy_hash_key, Destroy_hash_data |
309 | ); |
310 | |
311 | |
f0d936c0 |
312 | gtk_tree_view_set_headers_visible( |
313 | GTK_TREE_VIEW(Process_List->Process_List_VC), FALSE); |
314 | |
315 | /* Create a column, associating the "text" attribute of the |
316 | * cell_renderer to the first column of the model */ |
317 | /* Columns alignment : 0.0 : Left 0.5 : Center 1.0 : Right */ |
318 | renderer = gtk_cell_renderer_text_new (); |
319 | column = gtk_tree_view_column_new_with_attributes ( "Process", |
320 | renderer, |
321 | "text", |
322 | PROCESS_COLUMN, |
323 | NULL); |
324 | gtk_tree_view_column_set_alignment (column, 0.0); |
325 | gtk_tree_view_column_set_fixed_width (column, 45); |
326 | gtk_tree_view_append_column ( |
327 | GTK_TREE_VIEW (Process_List->Process_List_VC), column); |
fa2c4dbe |
328 | |
329 | column = gtk_tree_view_column_new_with_attributes ( "PID", |
330 | renderer, |
331 | "text", |
332 | PID_COLUMN, |
333 | NULL); |
334 | gtk_tree_view_append_column ( |
335 | GTK_TREE_VIEW (Process_List->Process_List_VC), column); |
336 | |
337 | |
338 | column = gtk_tree_view_column_new_with_attributes ( "Birth sec", |
339 | renderer, |
340 | "text", |
341 | BIRTH_S_COLUMN, |
342 | NULL); |
343 | gtk_tree_view_append_column ( |
344 | GTK_TREE_VIEW (Process_List->Process_List_VC), column); |
345 | |
346 | //gtk_tree_view_column_set_visible(column, 0); |
347 | // |
348 | column = gtk_tree_view_column_new_with_attributes ( "Birth nsec", |
349 | renderer, |
350 | "text", |
351 | BIRTH_NS_COLUMN, |
352 | NULL); |
353 | gtk_tree_view_append_column ( |
354 | GTK_TREE_VIEW (Process_List->Process_List_VC), column); |
355 | |
356 | //gtk_tree_view_column_set_visible(column, 0); |
f0d936c0 |
357 | |
358 | g_object_set_data_full( |
359 | G_OBJECT(Process_List->Process_List_VC), |
360 | "Process_List_Data", |
361 | Process_List, |
fa2c4dbe |
362 | (GDestroyNotify)ProcessList_destroy); |
f0d936c0 |
363 | |
fa2c4dbe |
364 | send_test_data(Process_List); |
365 | |
f0d936c0 |
366 | return Process_List; |
367 | } |
f0d936c0 |
368 | void ProcessList_destroy(ProcessList *Process_List) |
369 | { |
fa2c4dbe |
370 | g_hash_table_destroy(Process_List->Process_Hash); |
371 | Process_List->Process_Hash = NULL; |
f0d936c0 |
372 | |
373 | g_free(Process_List); |
374 | } |
375 | |
376 | GtkWidget *ProcessList_getWidget(ProcessList *Process_List) |
377 | { |
378 | return Process_List->Process_List_VC; |
379 | } |
380 | |
381 | |
382 | |
383 | gint get_cell_height(GtkTreeView *TreeView) |
384 | { |
fa2c4dbe |
385 | gint height; |
f0d936c0 |
386 | GtkTreeViewColumn *Column = gtk_tree_view_get_column(TreeView, 0); |
387 | GList *Render_List = gtk_tree_view_column_get_cell_renderers(Column); |
388 | GtkCellRenderer *Renderer = g_list_first(Render_List)->data; |
389 | |
390 | gtk_tree_view_column_cell_get_size(Column, NULL, NULL, NULL, NULL, &height); |
391 | g_critical("cell 0 height : %u",height); |
392 | |
393 | return height; |
394 | } |
395 | |
fa2c4dbe |
396 | void Destroy_hash_key(gpointer key) |
f0d936c0 |
397 | { |
fa2c4dbe |
398 | g_free(key); |
399 | } |
400 | |
401 | void Destroy_hash_data(gpointer data) |
402 | { |
403 | g_free(data); |
404 | } |
405 | |
406 | int ProcessList_add( ProcessList *Process_List, |
407 | guint pid, |
408 | LttTime *birth, |
409 | guint *height) |
410 | { |
411 | GtkTreeIter iter ; |
412 | ProcessInfo *Process_Info = g_new(ProcessInfo, 1); |
413 | GtkTreeRowReference *RowRef; |
414 | |
415 | Process_Info->pid = pid; |
416 | Process_Info->birth = *birth; |
417 | |
418 | /* Add a new row to the model */ |
419 | gtk_list_store_append ( Process_List->Store_M, &iter); |
420 | g_critical ( "iter before : %s", gtk_tree_path_to_string ( |
421 | gtk_tree_model_get_path ( |
422 | GTK_TREE_MODEL(Process_List->Store_M), |
423 | &iter))); |
424 | gtk_list_store_set ( Process_List->Store_M, &iter, |
425 | PROCESS_COLUMN, "name", |
426 | PID_COLUMN, pid, |
427 | BIRTH_S_COLUMN, birth->tv_sec, |
428 | BIRTH_NS_COLUMN, birth->tv_nsec, |
429 | -1); |
430 | RowRef = gtk_tree_row_reference_new ( |
431 | GTK_TREE_MODEL(Process_List->Store_M), |
432 | gtk_tree_model_get_path( |
433 | GTK_TREE_MODEL(Process_List->Store_M), |
434 | &iter)); |
435 | |
436 | g_hash_table_insert( Process_List->Process_Hash, |
437 | (gpointer)Process_Info, |
438 | (gpointer)RowRef); |
439 | |
440 | g_critical ( "iter after : %s", gtk_tree_path_to_string ( |
441 | gtk_tree_model_get_path ( |
442 | GTK_TREE_MODEL(Process_List->Store_M), |
443 | &iter))); |
444 | Process_List->Number_Of_Process++; |
f0d936c0 |
445 | |
fa2c4dbe |
446 | *height = get_cell_height(GTK_TREE_VIEW(Process_List->Process_List_VC)) |
f0d936c0 |
447 | * Process_List->Number_Of_Process ; |
448 | |
fa2c4dbe |
449 | |
f0d936c0 |
450 | return 0; |
451 | |
452 | } |
453 | |
fa2c4dbe |
454 | int ProcessList_remove( ProcessList *Process_List, |
455 | guint pid, |
456 | LttTime *birth) |
f0d936c0 |
457 | { |
fa2c4dbe |
458 | ProcessInfo Process_Info; |
459 | gint *path_indices; |
460 | GtkTreeRowReference *got_RowRef; |
461 | GtkTreeIter iter; |
f0d936c0 |
462 | |
fa2c4dbe |
463 | Process_Info.pid = pid; |
464 | Process_Info.birth = *birth; |
465 | |
466 | if(got_RowRef = |
467 | (GtkTreeRowReference*)g_hash_table_lookup( |
468 | Process_List->Process_Hash, |
469 | &Process_Info)) |
470 | { |
471 | gtk_tree_model_get_iter ( |
472 | GTK_TREE_MODEL(Process_List->Store_M), |
473 | &iter, |
474 | gtk_tree_row_reference_get_path( |
475 | (GtkTreeRowReference*)got_RowRef) |
476 | ); |
477 | |
478 | gtk_list_store_remove (Process_List->Store_M, &iter); |
479 | |
480 | g_hash_table_remove(Process_List->Process_Hash, |
481 | &Process_Info); |
482 | |
483 | Process_List->Number_Of_Process--; |
484 | |
485 | return 0; |
486 | } else { |
487 | return 1; |
488 | } |
489 | } |
490 | |
491 | |
492 | guint ProcessList_get_height(ProcessList *Process_List) |
493 | { |
494 | return get_cell_height(GTK_TREE_VIEW(Process_List->Process_List_VC)) |
f0d936c0 |
495 | * Process_List->Number_Of_Process ; |
f0d936c0 |
496 | } |
fa2c4dbe |
497 | |
498 | |
499 | gint ProcessList_get_process_pixels( ProcessList *Process_List, |
500 | guint pid, LttTime *birth, |
501 | guint *x, |
502 | guint *height) |
503 | { |
504 | ProcessInfo Process_Info; |
505 | gint *path_indices; |
506 | GtkTreeRowReference *got_RowRef; |
507 | |
508 | Process_Info.pid = pid; |
509 | Process_Info.birth = *birth; |
510 | |
511 | if(got_RowRef = |
512 | (GtkTreeRowReference*)g_hash_table_lookup( |
513 | Process_List->Process_Hash, |
514 | &Process_Info)) |
515 | { |
516 | path_indices = gtk_tree_path_get_indices ( |
517 | gtk_tree_row_reference_get_path( |
518 | (GtkTreeRowReference*)got_RowRef) |
519 | ); |
520 | |
521 | *height = get_cell_height( |
522 | GTK_TREE_VIEW(Process_List->Process_List_VC)); |
523 | *x = *height * path_indices[0]; |
524 | |
525 | return 0; |
526 | } else { |
527 | return 1; |
528 | } |
529 | |
530 | |
531 | |
532 | } |