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 ();
63 bytes = getline (&line, &line_size, file);
69 if (STRNCMP_LITERAL (s, "frame-time: ") == 0) {
71 int64_t frame_time_ns;
73 s += strlen("frame-time: ");
75 scanned = sscanf (s, "%d %" SCNu64,
76 &frame, &frame_time_ns);
78 fprintf (stderr, "Warning: Failed to parse line: %s\n", line);
82 acre_data_add_point_2d (frame_time, frame,
85 /* Ignoring all other lines. */
91 acre_add_data (acre, frame_time);
97 draw (Display *dpy, Window window, Visual *visual, acre_t *acre,
98 int width, int height, double x_min, double x_max)
101 cairo_surface_t *surface;
103 surface = cairo_xlib_surface_create (dpy, window, visual,
105 cr = cairo_create (surface);
108 cairo_set_source_rgb (cr, 1, 1, 1);
111 acre_set_x_axis_range (acre, x_min, x_max);
112 acre_draw (acre, cr, width, height);
116 cairo_surface_destroy (surface);
121 handle_events(Display *dpy, Window window, Visual *visual,
122 acre_t *acre, int width, int height)
125 KeyCode quit_code = XKeysymToKeycode (dpy, XStringToKeysym("Q"));
126 KeyCode escape_code = XKeysymToKeycode (dpy, XStringToKeysym("Escape"));
127 KeyCode left_code = XKeysymToKeycode (dpy, XStringToKeysym("Left"));
128 KeyCode right_code = XKeysymToKeycode (dpy, XStringToKeysym("Right"));
129 KeyCode plus_code = XKeysymToKeycode (dpy, XStringToKeysym("plus"));
130 KeyCode equal_code = XKeysymToKeycode (dpy, XStringToKeysym("equal"));
131 KeyCode minus_code = XKeysymToKeycode (dpy, XStringToKeysym("minus"));
132 KeyCode home_code = XKeysymToKeycode (dpy, XStringToKeysym("Home"));
134 bool need_redraw = false;
135 double x_min, x_max, shift;
137 acre_get_x_axis_data_range (acre, &x_min, &x_max);
140 if (! XPending (dpy) && need_redraw)
141 draw (dpy, window, visual, acre,
142 width, height, x_min, x_max);
146 XNextEvent (dpy, &xev);
150 keycode = xev.xkey.keycode;
151 if (keycode == quit_code ||
152 keycode == escape_code)
156 else if (keycode == left_code)
158 shift = PAN * (x_max - x_min);
162 else if (keycode == right_code)
164 shift = PAN * (x_max - x_min);
168 else if (keycode == plus_code ||
169 keycode == equal_code)
171 shift = ZOOM * (x_max - x_min);
175 else if (keycode == minus_code)
177 shift = (ZOOM/(1 - 2 * ZOOM)) * (x_max - x_min);
181 else if (keycode == home_code)
183 acre_get_x_axis_data_range (acre, &x_min, &x_max);
190 case ConfigureNotify:
191 width = xev.xconfigure.width;
192 height = xev.xconfigure.height;
195 if (xev.xexpose.count == 0)
203 main (int argc, char *argv[])
209 XSetWindowAttributes window_attr;
211 unsigned long window_mask, event_mask;
218 fprintf (stderr, "Usage: acre-x data-file\n");
219 fprintf (stderr, "Where the data file is the output from fips (with frame-timing feature.\n");
223 acre = load_fips_data (argv[1]);
228 dpy = XOpenDisplay (NULL);
231 fprintf(stderr, "Failed to open display %s\n",
236 root = DefaultRootWindow (dpy);
237 white = WhitePixel (dpy, DefaultScreen (dpy));
238 visual = DefaultVisual (dpy, DefaultScreen (dpy));
239 colormap = XCreateColormap (dpy, root, visual, AllocNone);
240 event_mask = KeyPressMask | StructureNotifyMask | ExposureMask;
243 window_mask |= CWBackPixel; window_attr.background_pixel = white;
244 window_mask |= CWBorderPixel; window_attr.border_pixel = white;
245 window_mask |= CWColormap; window_attr.colormap = colormap;
246 window_mask |= CWEventMask; window_attr.event_mask = event_mask;
248 window = XCreateWindow(dpy, root, 0, 0, width, height, 0,
249 DefaultDepth (dpy, DefaultScreen (dpy)),
251 window_mask, &window_attr);
253 XMapWindow (dpy, window);
255 handle_events (dpy, window, visual, acre, width, height);
259 XDestroyWindow (dpy, window);