1 /* acre - A cairo-based library for creating plots and charts.
3 * Copyright © 2009 Carl Worth <cworth@cworth.org>
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of the
8 * License, or (at your option) any later version.
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. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
28 #include <cairo-svg.h>
29 #include <cairo-xlib.h>
34 #define STRNCMP_LITERAL(var, literal) \
35 strncmp ((var), (literal), sizeof (literal) - 1)
38 load_fips_data (const char *filename)
42 acre_data_t *frame_time;
43 char *line = NULL, *s;
47 file = fopen (filename, "r");
49 fprintf (stderr, "Failed to open %s: %s\n",
50 filename, strerror (errno));
54 acre = acre_create ();
56 acre_set_title (acre, filename);
57 acre_set_x_axis_label (acre, "Frame #");
58 acre_set_y_axis_label (acre, "Frame time (ms)");
60 frame_time = acre_data_create ();
61 acre_data_set_style (frame_time, ACRE_STYLE_BARS_OR_LINE);
66 bytes = getline (&line, &line_size, file);
72 if (STRNCMP_LITERAL (s, "frame-time: ") == 0) {
74 int64_t frame_time_ns;
76 s += strlen("frame-time: ");
78 scanned = sscanf (s, "%d %" SCNu64,
79 &frame, &frame_time_ns);
81 fprintf (stderr, "Warning: Failed to parse line: %s\n", line);
85 acre_data_add_point_2d (frame_time, frame,
88 /* Ignoring all other lines. */
94 acre_add_data (acre, frame_time);
100 draw (Display *dpy, Window window, Visual *visual, acre_t *acre,
101 int width, int height, double x_min, double x_max)
104 cairo_surface_t *surface;
106 surface = cairo_xlib_surface_create (dpy, window, visual,
108 cr = cairo_create (surface);
111 cairo_set_source_rgb (cr, 1, 1, 1);
114 acre_set_x_axis_range (acre, x_min, x_max);
115 acre_draw (acre, cr, width, height);
119 cairo_surface_destroy (surface);
123 draw_svg (acre_t *acre, int width, int height, double x_min, double x_max)
126 cairo_surface_t *surface;
128 surface = cairo_svg_surface_create ("acre-fips.svg", width, height);
130 cr = cairo_create (surface);
132 acre_set_x_axis_range (acre, x_min, x_max);
133 acre_draw (acre, cr, width, height);
137 cairo_surface_destroy (surface);
142 handle_events(Display *dpy, Window window, Visual *visual,
143 acre_t *acre, int width, int height)
146 KeyCode quit_code = XKeysymToKeycode (dpy, XStringToKeysym("Q"));
147 KeyCode escape_code = XKeysymToKeycode (dpy, XStringToKeysym("Escape"));
148 KeyCode left_code = XKeysymToKeycode (dpy, XStringToKeysym("Left"));
149 KeyCode right_code = XKeysymToKeycode (dpy, XStringToKeysym("Right"));
150 KeyCode plus_code = XKeysymToKeycode (dpy, XStringToKeysym("plus"));
151 KeyCode equal_code = XKeysymToKeycode (dpy, XStringToKeysym("equal"));
152 KeyCode minus_code = XKeysymToKeycode (dpy, XStringToKeysym("minus"));
153 KeyCode home_code = XKeysymToKeycode (dpy, XStringToKeysym("Home"));
154 KeyCode svg_code = XKeysymToKeycode (dpy, XStringToKeysym("S"));
156 bool need_redraw = false;
157 double x_min, x_max, shift;
159 acre_get_x_axis_data_range (acre, &x_min, &x_max);
162 if (! XPending (dpy) && need_redraw)
163 draw (dpy, window, visual, acre,
164 width, height, x_min, x_max);
168 XNextEvent (dpy, &xev);
172 keycode = xev.xkey.keycode;
173 if (keycode == quit_code ||
174 keycode == escape_code)
178 else if (keycode == left_code)
180 shift = PAN * (x_max - x_min);
184 else if (keycode == right_code)
186 shift = PAN * (x_max - x_min);
190 else if (keycode == plus_code ||
191 keycode == equal_code)
193 shift = ZOOM * (x_max - x_min);
197 else if (keycode == minus_code)
199 shift = (ZOOM/(1 - 2 * ZOOM)) * (x_max - x_min);
203 else if (keycode == home_code)
205 acre_get_x_axis_data_range (acre, &x_min, &x_max);
207 else if (keycode == svg_code)
210 draw_svg (acre, width, height, x_min, x_max);
217 case ConfigureNotify:
218 width = xev.xconfigure.width;
219 height = xev.xconfigure.height;
222 if (xev.xexpose.count == 0)
230 main (int argc, char *argv[])
236 XSetWindowAttributes window_attr;
238 unsigned long window_mask, event_mask;
245 fprintf (stderr, "Usage: acre-x data-file\n");
246 fprintf (stderr, "Where the data file is the output from fips (with frame-timing feature.\n");
250 acre = load_fips_data (argv[1]);
255 dpy = XOpenDisplay (NULL);
258 fprintf(stderr, "Failed to open display %s\n",
263 root = DefaultRootWindow (dpy);
264 white = WhitePixel (dpy, DefaultScreen (dpy));
265 visual = DefaultVisual (dpy, DefaultScreen (dpy));
266 colormap = XCreateColormap (dpy, root, visual, AllocNone);
267 event_mask = KeyPressMask | StructureNotifyMask | ExposureMask;
270 window_mask |= CWBackPixel; window_attr.background_pixel = white;
271 window_mask |= CWBorderPixel; window_attr.border_pixel = white;
272 window_mask |= CWColormap; window_attr.colormap = colormap;
273 window_mask |= CWEventMask; window_attr.event_mask = event_mask;
275 window = XCreateWindow(dpy, root, 0, 0, width, height, 0,
276 DefaultDepth (dpy, DefaultScreen (dpy)),
278 window_mask, &window_attr);
280 XMapWindow (dpy, window);
282 handle_events (dpy, window, visual, acre, width, height);
286 XDestroyWindow (dpy, window);