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.
27 #include <cairo-xlib.h>
32 #define STRNCMP_LITERAL(var, literal) \
33 strncmp ((var), (literal), sizeof (literal) - 1)
36 load_fips_data (const char *filename)
40 acre_data_t *frame_time;
41 char *line = NULL, *s;
45 file = fopen (filename, "r");
47 fprintf (stderr, "Failed to open %s: %s\n",
48 filename, strerror (errno));
52 acre = acre_create ();
54 acre_set_title (acre, filename);
55 acre_set_x_axis_label (acre, "Frame #");
56 acre_set_y_axis_label (acre, "Frame time (ms)");
58 frame_time = acre_data_create ();
59 acre_data_set_style (frame_time, ACRE_STYLE_BARS_OR_LINE);
64 bytes = getline (&line, &line_size, file);
70 if (STRNCMP_LITERAL (s, "frame-time: ") == 0) {
72 int64_t frame_time_ns;
74 s += strlen("frame-time: ");
76 scanned = sscanf (s, "%d %" SCNu64,
77 &frame, &frame_time_ns);
79 fprintf (stderr, "Warning: Failed to parse line: %s\n", line);
83 acre_data_add_point_2d (frame_time, frame,
86 /* Ignoring all other lines. */
92 acre_add_data (acre, frame_time);
98 draw (Display *dpy, Window window, Visual *visual, acre_t *acre,
99 int width, int height, double x_min, double x_max)
102 cairo_surface_t *surface;
104 surface = cairo_xlib_surface_create (dpy, window, visual,
106 cr = cairo_create (surface);
109 cairo_set_source_rgb (cr, 1, 1, 1);
112 acre_set_x_axis_range (acre, x_min, x_max);
113 acre_draw (acre, cr, width, height);
117 cairo_surface_destroy (surface);
122 handle_events(Display *dpy, Window window, Visual *visual,
123 acre_t *acre, int width, int height)
126 KeyCode quit_code = XKeysymToKeycode (dpy, XStringToKeysym("Q"));
127 KeyCode escape_code = XKeysymToKeycode (dpy, XStringToKeysym("Escape"));
128 KeyCode left_code = XKeysymToKeycode (dpy, XStringToKeysym("Left"));
129 KeyCode right_code = XKeysymToKeycode (dpy, XStringToKeysym("Right"));
130 KeyCode plus_code = XKeysymToKeycode (dpy, XStringToKeysym("plus"));
131 KeyCode equal_code = XKeysymToKeycode (dpy, XStringToKeysym("equal"));
132 KeyCode minus_code = XKeysymToKeycode (dpy, XStringToKeysym("minus"));
133 KeyCode home_code = XKeysymToKeycode (dpy, XStringToKeysym("Home"));
135 bool need_redraw = false;
136 double x_min, x_max, shift;
138 acre_get_x_axis_data_range (acre, &x_min, &x_max);
141 if (! XPending (dpy) && need_redraw)
142 draw (dpy, window, visual, acre,
143 width, height, x_min, x_max);
147 XNextEvent (dpy, &xev);
151 keycode = xev.xkey.keycode;
152 if (keycode == quit_code ||
153 keycode == escape_code)
157 else if (keycode == left_code)
159 shift = PAN * (x_max - x_min);
163 else if (keycode == right_code)
165 shift = PAN * (x_max - x_min);
169 else if (keycode == plus_code ||
170 keycode == equal_code)
172 shift = ZOOM * (x_max - x_min);
176 else if (keycode == minus_code)
178 shift = (ZOOM/(1 - 2 * ZOOM)) * (x_max - x_min);
182 else if (keycode == home_code)
184 acre_get_x_axis_data_range (acre, &x_min, &x_max);
191 case ConfigureNotify:
192 width = xev.xconfigure.width;
193 height = xev.xconfigure.height;
196 if (xev.xexpose.count == 0)
204 main (int argc, char *argv[])
210 XSetWindowAttributes window_attr;
212 unsigned long window_mask, event_mask;
219 fprintf (stderr, "Usage: acre-x data-file\n");
220 fprintf (stderr, "Where the data file is the output from fips (with frame-timing feature.\n");
224 acre = load_fips_data (argv[1]);
229 dpy = XOpenDisplay (NULL);
232 fprintf(stderr, "Failed to open display %s\n",
237 root = DefaultRootWindow (dpy);
238 white = WhitePixel (dpy, DefaultScreen (dpy));
239 visual = DefaultVisual (dpy, DefaultScreen (dpy));
240 colormap = XCreateColormap (dpy, root, visual, AllocNone);
241 event_mask = KeyPressMask | StructureNotifyMask | ExposureMask;
244 window_mask |= CWBackPixel; window_attr.background_pixel = white;
245 window_mask |= CWBorderPixel; window_attr.border_pixel = white;
246 window_mask |= CWColormap; window_attr.colormap = colormap;
247 window_mask |= CWEventMask; window_attr.event_mask = event_mask;
249 window = XCreateWindow(dpy, root, 0, 0, width, height, 0,
250 DefaultDepth (dpy, DefaultScreen (dpy)),
252 window_mask, &window_attr);
254 XMapWindow (dpy, window);
256 handle_events (dpy, window, visual, acre, width, height);
260 XDestroyWindow (dpy, window);