gtk-viewer.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475
  1. /*
  2. * StarPU
  3. * Copyright (C) INRIA 2008-2009 (see AUTHORS file)
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU Lesser General Public License as published by
  7. * the Free Software Foundation; either version 2.1 of the License, or (at
  8. * your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful, but
  11. * WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  13. *
  14. * See the GNU Lesser General Public License in COPYING.LGPL for more details.
  15. */
  16. /* example-start scrolledwin scrolledwin.c */
  17. #include <stdio.h>
  18. #include <gtk/gtk.h>
  19. #include <stdlib.h>
  20. #include "fxt-tool.h"
  21. #include <assert.h>
  22. #define GTK_WIDTH 800
  23. #define GTK_THICKNESS 30
  24. #define GTK_GAP 10
  25. #define GTK_BORDERX 100
  26. #define GTK_BORDERY 100
  27. /* Backing pixmap for drawing area */
  28. static GdkPixmap *pixmap = NULL;
  29. static GdkGC *gc = NULL;
  30. static GtkWidget *scrolled_window;
  31. static GtkWidget *window;
  32. static GdkColor blue;
  33. static GdkColor red;
  34. static GdkColor green;
  35. static GdkColor white;
  36. static GdkColor grey;
  37. static GdkColor black;
  38. static unsigned zoom = 1;
  39. GtkWidget *drawing_area;
  40. /* the actual trace data ... */
  41. static event_list_t *events;
  42. static workq_list_t taskq;
  43. static char **worker_name;
  44. static unsigned nworkers;
  45. static unsigned maxq_size;
  46. static uint64_t start_time;
  47. static uint64_t end_time;
  48. void trace_gantt(void);
  49. static void init_colors(GtkWidget *area)
  50. {
  51. GdkColormap *colormap;
  52. colormap = gtk_widget_get_colormap(area);
  53. if (!colormap)
  54. exit(1);
  55. green.red = 0;
  56. green.green = 0xff * 0x100;
  57. green.blue = 0;
  58. gdk_colormap_alloc_color(colormap, &green, FALSE, TRUE);
  59. blue.red = 0;
  60. blue.green = 0;
  61. blue.blue = 0xff * 0x100;
  62. gdk_colormap_alloc_color(colormap, &blue, FALSE, TRUE);
  63. red.red = 0xff * 0x100;
  64. red.green = 0;
  65. red.blue = 0;
  66. gdk_colormap_alloc_color(colormap, &red, FALSE, TRUE);
  67. white.red = 0xff * 0x100;
  68. white.green = 0xff * 0x100;
  69. white.blue = 0xff * 0x100;
  70. gdk_colormap_alloc_color(colormap, &white, FALSE, TRUE);
  71. grey.red = 112 * 0x100;
  72. grey.green = 128 * 0x100;
  73. grey.blue = 144 * 0x100;
  74. gdk_colormap_alloc_color(colormap, &grey, FALSE, TRUE);
  75. black.red = 0;
  76. black.green = 0;
  77. black.blue = 0;
  78. gdk_colormap_alloc_color(colormap, &white, FALSE, TRUE);
  79. }
  80. /* Create a new backing pixmap of the appropriate size */
  81. static gint configure_event( GtkWidget *widget,
  82. GdkEventConfigure *event __attribute__ ((unused)))
  83. {
  84. if (pixmap)
  85. gdk_pixmap_unref(pixmap);
  86. pixmap = gdk_pixmap_new(widget->window,
  87. widget->allocation.width,
  88. widget->allocation.height,
  89. -1);
  90. gdk_draw_rectangle (pixmap,
  91. widget->style->white_gc,
  92. TRUE,
  93. 0, 0,
  94. widget->allocation.width,
  95. widget->allocation.height);
  96. trace_gantt();
  97. return TRUE;
  98. }
  99. static gint expose_event( GtkWidget *widget,
  100. GdkEventExpose *event )
  101. {
  102. gdk_draw_pixmap(widget->window,
  103. widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
  104. pixmap,
  105. event->area.x, event->area.y,
  106. event->area.x, event->area.y,
  107. event->area.width, event->area.height);
  108. return FALSE;
  109. }
  110. /* Draw a rectangle on the screen */
  111. static void draw_brush( GtkWidget *widget,
  112. gdouble x,
  113. gdouble y)
  114. {
  115. GdkRectangle update_rect;
  116. update_rect.x = x - 5;
  117. update_rect.y = y - 5;
  118. update_rect.width = 10;
  119. update_rect.height = 10;
  120. gdk_draw_rectangle (pixmap,
  121. widget->style->black_gc,
  122. TRUE,
  123. update_rect.x, update_rect.y,
  124. update_rect.width, update_rect.height);
  125. gtk_widget_draw (widget, &update_rect);
  126. }
  127. static gint button_press_event( GtkWidget *widget __attribute__ ((unused)),
  128. GdkEventButton *event __attribute__((unused)))
  129. {
  130. // if (event->button == 1 && pixmap != NULL)
  131. // draw_brush (widget, event->x, event->y);
  132. //
  133. return TRUE;
  134. }
  135. static gint motion_notify_event( GtkWidget *widget,
  136. GdkEventMotion *event )
  137. {
  138. int x, y;
  139. GdkModifierType state;
  140. if (event->is_hint)
  141. gdk_window_get_pointer (event->window, &x, &y, &state);
  142. else
  143. {
  144. x = event->x;
  145. y = event->y;
  146. state = event->state;
  147. }
  148. if (state & GDK_BUTTON1_MASK && pixmap != NULL)
  149. draw_brush (widget, x, y);
  150. return TRUE;
  151. }
  152. void destroy( GtkWidget *widget __attribute__ ((unused)),
  153. gpointer data __attribute__ ((unused)))
  154. {
  155. gtk_main_quit();
  156. }
  157. static void gtk_add_region(worker_mode color, uint64_t start, uint64_t end, unsigned worker)
  158. {
  159. unsigned long starty, endy, startx, endx;
  160. starty = GTK_BORDERY + (GTK_THICKNESS + GTK_GAP)*worker;
  161. endy = starty + GTK_THICKNESS;
  162. double ratio_start, ratio_end;
  163. ratio_start = (double)(start - start_time) / (double)(end_time - start_time);
  164. ratio_end = (double)(end - start_time) / (double)(end_time - start_time);
  165. startx = (unsigned long)(GTK_BORDERX + zoom*ratio_start*(GTK_WIDTH - 2*GTK_BORDERX));
  166. endx = (unsigned long)(GTK_BORDERX + zoom*ratio_end*(GTK_WIDTH - 2*GTK_BORDERX));
  167. GdkRectangle update_rect;
  168. update_rect.x = startx;
  169. update_rect.y = starty;
  170. update_rect.width = endx - startx;
  171. update_rect.height = endy - starty;
  172. gc = gdk_gc_new(drawing_area->window);
  173. assert(gc);
  174. switch (color) {
  175. case WORKING:
  176. gdk_gc_set_foreground (gc, &green);
  177. break;
  178. case FETCHING:
  179. gdk_gc_set_foreground (gc, &blue);
  180. break;
  181. case PUSHING:
  182. gdk_gc_set_foreground (gc, &grey);
  183. break;
  184. case IDLE:
  185. default:
  186. gdk_gc_set_foreground (gc, &red);
  187. break;
  188. }
  189. gdk_draw_rectangle (pixmap,
  190. gc,
  191. TRUE,
  192. update_rect.x, update_rect.y,
  193. update_rect.width, update_rect.height);
  194. gtk_widget_draw (drawing_area, &update_rect);
  195. }
  196. static void gtk_display_worker(event_list_t worker_events, unsigned worker,
  197. char *worker_name __attribute__ ((unused)))
  198. {
  199. uint64_t prev = start_time;
  200. worker_mode prev_state = IDLE;
  201. event_itor_t i;
  202. for (i = event_list_begin(worker_events);
  203. i != event_list_end(worker_events);
  204. i = event_list_next(i))
  205. {
  206. gtk_add_region(prev_state, prev, i->time, worker);
  207. prev = i->time;
  208. prev_state = i->mode;
  209. }
  210. }
  211. void trace_gantt(void)
  212. {
  213. // GdkRectangle update_rect;
  214. //
  215. // update_rect.x = 100 - 25;
  216. // update_rect.y = 100 - 25;
  217. // update_rect.width = zoom*GTK_WIDTH;
  218. // update_rect.height = zoom*GTK_WIDTH;
  219. //
  220. // gc = gdk_gc_new(drawing_area->window);
  221. // assert(gc);
  222. // gdk_gc_set_foreground (gc, &green);
  223. //
  224. // gdk_draw_rectangle (pixmap,
  225. // gc,
  226. // TRUE,
  227. // update_rect.x, update_rect.y,
  228. // update_rect.width, update_rect.height);
  229. // gtk_widget_draw (drawing_area, &update_rect);
  230. unsigned worker;
  231. for (worker = 0; worker < nworkers; worker++)
  232. {
  233. gtk_display_worker(events[worker], worker, worker_name[worker]);
  234. }
  235. }
  236. void refresh(void)
  237. {
  238. unsigned drawing_area_height =
  239. nworkers*GTK_THICKNESS + (nworkers-1)*GTK_GAP+2*GTK_BORDERY;
  240. unsigned drawing_area_width =
  241. 2*GTK_BORDERX + (GTK_WIDTH-2*GTK_BORDERX)*zoom;
  242. gtk_drawing_area_size (GTK_DRAWING_AREA (drawing_area),
  243. drawing_area_width , drawing_area_height);
  244. gdk_window_clear_area(drawing_area->window, 0, 0,
  245. drawing_area->allocation.width,
  246. drawing_area->allocation.height);
  247. gdk_draw_rectangle (pixmap,
  248. drawing_area->style->white_gc,
  249. TRUE, 0, 0,
  250. drawing_area->allocation.width,
  251. drawing_area->allocation.height);
  252. gdk_draw_pixmap(drawing_area->window,
  253. drawing_area->style->fg_gc[GTK_WIDGET_STATE (drawing_area)],
  254. pixmap,
  255. drawing_area->allocation.x, drawing_area->allocation.x,
  256. drawing_area->allocation.y, drawing_area->allocation.y,
  257. drawing_area->allocation.width,
  258. drawing_area->allocation.height);
  259. trace_gantt();
  260. }
  261. void zoom_in_func( GtkWidget *widget __attribute__ ((unused)),
  262. gpointer data __attribute__ ((unused)))
  263. {
  264. GtkAdjustment *hadjustment;
  265. refresh();
  266. hadjustment = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW (scrolled_window));
  267. float ratio = (hadjustment->value - GTK_BORDERX)/(GTK_BORDERX + zoom*(GTK_WIDTH - 2*GTK_BORDERX));
  268. zoom*=2;
  269. gtk_adjustment_set_value (hadjustment, GTK_BORDERX + ratio*zoom*(GTK_WIDTH - 2*GTK_BORDERX));
  270. refresh();
  271. }
  272. void zoom_out_func( GtkWidget *widget __attribute__ ((unused)) , gpointer data __attribute__ ((unused)) )
  273. {
  274. GtkAdjustment *hadjustment;
  275. hadjustment = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW (scrolled_window));
  276. float ratio = (hadjustment->value - GTK_BORDERX)/(GTK_BORDERX + zoom*(GTK_WIDTH - 2*GTK_BORDERX));
  277. if (zoom > 1)
  278. zoom/=2;
  279. gtk_adjustment_set_value (hadjustment, GTK_BORDERX + ratio*zoom*(GTK_WIDTH - 2*GTK_BORDERX));
  280. refresh();
  281. }
  282. int gtk_viewer_apps( int argc, char *argv[], event_list_t *_events,
  283. workq_list_t _taskq, char **_worker_name,
  284. unsigned _nworkers, unsigned _maxq_size,
  285. uint64_t _start_time, uint64_t _end_time)
  286. {
  287. /* save the arguments */
  288. events = _events;
  289. taskq = _taskq;
  290. worker_name = _worker_name;
  291. nworkers = _nworkers;
  292. maxq_size = _maxq_size;
  293. start_time = _start_time;
  294. end_time = _end_time;
  295. GtkWidget *close_button, *zoom_in_button, *zoom_out_button;
  296. gtk_init (&argc, &argv);
  297. /* Create a new dialog window for the scrolled window to be
  298. * packed into. */
  299. window = gtk_dialog_new ();
  300. gtk_signal_connect (GTK_OBJECT (window), "destroy",
  301. (GtkSignalFunc) destroy, NULL);
  302. gtk_window_set_title (GTK_WINDOW (window), "GtkScrolledWindow example");
  303. gtk_container_set_border_width (GTK_CONTAINER (window), 0);
  304. gtk_widget_set_usize(window, STARPU_MIN(800, GTK_WIDTH), STARPU_MIN(600, nworkers*GTK_THICKNESS + (nworkers-1)*GTK_GAP+2*GTK_BORDERY+100));
  305. /* create a new scrolled window. */
  306. scrolled_window = gtk_scrolled_window_new (NULL, NULL);
  307. gtk_container_set_border_width (GTK_CONTAINER (scrolled_window), 10);
  308. /* the policy is one of GTK_POLICY AUTOMATIC, or GTK_POLICY_ALWAYS.
  309. * GTK_POLICY_AUTOMATIC will automatically decide whether you need
  310. * scrollbars, whereas GTK_POLICY_ALWAYS will always leave the scrollbars
  311. * there. The first one is the horizontal scrollbar, the second,
  312. * the vertical. */
  313. gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
  314. GTK_POLICY_ALWAYS, GTK_POLICY_NEVER);
  315. /* The dialog window is created with a vbox packed into it. */
  316. gtk_box_pack_start (GTK_BOX (GTK_DIALOG(window)->vbox), scrolled_window,
  317. TRUE, TRUE, 0);
  318. gtk_widget_show (scrolled_window);
  319. /* the drawing box ... */
  320. drawing_area = gtk_drawing_area_new ();
  321. gtk_drawing_area_size (GTK_DRAWING_AREA (drawing_area), GTK_WIDTH , nworkers*GTK_THICKNESS + (nworkers-1)*GTK_GAP+2*GTK_BORDERY);
  322. gtk_scrolled_window_add_with_viewport (
  323. GTK_SCROLLED_WINDOW (scrolled_window), drawing_area);
  324. init_colors(drawing_area);
  325. gtk_widget_show (drawing_area);
  326. /* Signals used to handle backing pixmap */
  327. gtk_signal_connect (GTK_OBJECT (drawing_area), "expose_event",
  328. (GtkSignalFunc) expose_event, NULL);
  329. gtk_signal_connect (GTK_OBJECT(drawing_area),"configure_event",
  330. (GtkSignalFunc) configure_event, NULL);
  331. /* Event signals */
  332. gtk_signal_connect (GTK_OBJECT (drawing_area), "motion_notify_event",
  333. (GtkSignalFunc) motion_notify_event, NULL);
  334. gtk_signal_connect (GTK_OBJECT (drawing_area), "button_press_event",
  335. (GtkSignalFunc) button_press_event, NULL);
  336. gtk_widget_set_events (drawing_area, GDK_EXPOSURE_MASK
  337. | GDK_LEAVE_NOTIFY_MASK
  338. | GDK_BUTTON_PRESS_MASK
  339. | GDK_POINTER_MOTION_MASK
  340. | GDK_POINTER_MOTION_HINT_MASK);
  341. /* Add a "close" button to the bottom of the dialog */
  342. close_button = gtk_button_new_with_label ("close");
  343. gtk_signal_connect_object (GTK_OBJECT (close_button), "clicked",
  344. (GtkSignalFunc) gtk_widget_destroy,
  345. GTK_OBJECT (window));
  346. /* this makes it so the button is the default. */
  347. GTK_WIDGET_SET_FLAGS (close_button, GTK_CAN_DEFAULT);
  348. gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), close_button, TRUE, TRUE, 0);
  349. /* This grabs this button to be the default button. Simply hitting
  350. * the "Enter" key will cause this button to activate. */
  351. gtk_widget_grab_default (close_button);
  352. gtk_widget_show (close_button);
  353. zoom_in_button = gtk_button_new_with_label ("zoom in");
  354. gtk_signal_connect_object (GTK_OBJECT (zoom_in_button), "clicked",
  355. (GtkSignalFunc) zoom_in_func,
  356. GTK_OBJECT (drawing_area));
  357. zoom_out_button = gtk_button_new_with_label ("zoom out");
  358. gtk_signal_connect_object (GTK_OBJECT (zoom_out_button), "clicked",
  359. (GtkSignalFunc) zoom_out_func,
  360. GTK_OBJECT (drawing_area));
  361. gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), zoom_in_button, TRUE, TRUE, 0);
  362. gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), zoom_out_button, TRUE, TRUE, 0);
  363. gtk_widget_show (zoom_in_button);
  364. gtk_widget_show (zoom_out_button);
  365. gtk_widget_show (window);
  366. gtk_main();
  367. return(0);
  368. }
  369. /* example-end */