summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Larsson <alexl@redhat.com>2010-09-06 15:32:33 +0200
committerAlexander Larsson <alexl@redhat.com>2010-09-06 15:34:04 +0200
commit254c6fcfe01e0bfc4f0b4fba7f809bd053d8ce56 (patch)
tree31c0f3a061218dca9ba29abb1308ded002d94904
parent560234bc887441ed94c15a2314f3de12405c94b8 (diff)
Add app that can read log fileslog-drawing
-rw-r--r--log_reader.c184
1 files changed, 184 insertions, 0 deletions
diff --git a/log_reader.c b/log_reader.c
new file mode 100644
index 0000000..d9188dc
--- /dev/null
+++ b/log_reader.c
@@ -0,0 +1,184 @@
+/* Build with:
+ gcc `pkg-config --libs --cflags gtk+-2.0 pixman-1` log_reader.c -o log_reader -Wall -O2
+*/
+
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <pixman.h>
+#include <gdk/gdkkeysyms.h>
+
+#include <gtk/gtk.h>
+
+struct __attribute__ ((__packed__)) DrawLogEntry {
+ uint32_t text_length;
+ uint32_t surface_id;
+ uint32_t width;
+ uint32_t height;
+ uint32_t stride;
+ uint32_t format;
+ uint32_t box_x;
+ uint32_t box_y;
+ uint32_t box_w;
+ uint32_t box_h;
+ /* text */
+ /* canvas data */
+};
+
+int fd;
+GtkWidget *label, *image;
+off_t frame_pos[1024];
+int frame = 0;
+struct DrawLogEntry current_entry;
+int after = TRUE;
+char *current_text = NULL;
+GdkPixbuf *pixbuf1 = NULL, *pixbuf2 = NULL;
+
+static GdkPixbuf * get_pixbuf(struct DrawLogEntry *entry, const char *data)
+{
+ pixman_image_t *src, *dest;
+ GdkPixbuf *pixbuf;
+
+ src = pixman_image_create_bits (entry->format,
+ entry->width,
+ entry->height,
+ (guint32 *)data,
+ entry->stride);
+
+ pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, entry->width, entry->height);
+ dest = pixman_image_create_bits (PIXMAN_b8g8r8,
+ entry->width,
+ entry->height,
+ (guint32 *)gdk_pixbuf_get_pixels (pixbuf),
+ gdk_pixbuf_get_rowstride (pixbuf));
+
+ pixman_image_composite32 (PIXMAN_OP_SRC, src, NULL, dest,
+ 0, 0, 0,0, 0,0, entry->width, entry->height);
+
+ pixman_image_unref (src);
+ pixman_image_unref (dest);
+
+ return pixbuf;
+}
+
+static void update_text(void)
+{
+ char *l;
+ l = g_strdup_printf("%d %s: %d - %s", frame-1, after?"after":"before", current_entry.surface_id, current_text);
+ gtk_label_set_text (GTK_LABEL (label), l);
+ g_free(l);
+}
+
+static void update_image(void)
+{
+ if (after)
+ gtk_image_set_from_pixbuf (GTK_IMAGE (image), pixbuf2);
+ else
+ gtk_image_set_from_pixbuf (GTK_IMAGE (image), pixbuf1);
+}
+
+void read_next(void)
+{
+ char *data;
+ ssize_t n;
+
+ frame_pos[frame] = lseek(fd, 0, SEEK_CUR);
+
+ n = read(fd, &current_entry, sizeof(current_entry));
+ if (n == 0) {
+ return;
+ }
+ frame ++;
+
+ if (pixbuf1)
+ g_object_unref(pixbuf1);
+ if (pixbuf2)
+ g_object_unref(pixbuf2);
+
+ g_free(current_text);
+ current_text = g_malloc(current_entry.text_length + 1);
+ read(fd, current_text, current_entry.text_length);
+ current_text[current_entry.text_length] = 0;
+
+ data = g_malloc(current_entry.stride * current_entry.height);
+ read(fd, data, current_entry.stride * current_entry.height);
+
+ pixbuf1 = get_pixbuf(&current_entry, data);
+
+ data = g_malloc(current_entry.stride * current_entry.height);
+ read(fd, data, current_entry.stride * current_entry.height);
+
+ pixbuf2 = get_pixbuf(&current_entry, data);
+
+ update_text();
+ update_image();
+}
+
+void read_prev(void)
+{
+ if (frame < 2)
+ return; /* no earlier */
+
+ frame -= 2;
+ lseek(fd, frame_pos[frame], SEEK_SET);
+ read_next();
+}
+
+gboolean key_pressed (GtkWidget *widget,
+ GdkEventKey *event)
+{
+ if (event->keyval == GDK_Right) {
+ read_next();
+ } else if (event->keyval == GDK_Left) {
+ read_prev();
+ } else if (event->keyval == GDK_Up) {
+ after = TRUE;
+ update_text();
+ update_image();
+ } else if (event->keyval == GDK_Down) {
+ after = FALSE;
+ update_text();
+ update_image();
+ }
+ return TRUE;
+}
+
+int
+main(int argc, char *argv[])
+{
+ GtkWidget *window, *vbox;
+
+ gtk_init(&argc, &argv);
+
+ fd = open(argv[1], O_RDONLY);
+
+ if (fd == -1) {
+ printf ("Can't open %s\n", argv[1]);
+ }
+
+ window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
+ g_signal_connect (window, "key_press_event", G_CALLBACK (key_pressed), NULL);
+
+ vbox = gtk_vbox_new (FALSE, 4);
+ gtk_container_add (GTK_CONTAINER(window), vbox);
+ label = gtk_label_new ("Log entry");
+ gtk_label_set_justify (GTK_LABEL(label), GTK_JUSTIFY_LEFT);
+ gtk_misc_set_alignment (GTK_MISC(label), 0.0, 0.0);
+
+ gtk_box_pack_start (GTK_BOX (vbox),
+ label, FALSE, FALSE, 0);
+ image = gtk_image_new ();
+ gtk_box_pack_start (GTK_BOX (vbox),
+ image, FALSE, FALSE, 0);
+
+ gtk_widget_show_all (window);
+
+ read_next();
+
+ gtk_main();
+
+ return 0;
+}