diff options
author | Alexander Larsson <alexl@redhat.com> | 2010-09-06 15:32:33 +0200 |
---|---|---|
committer | Alexander Larsson <alexl@redhat.com> | 2010-09-06 15:34:04 +0200 |
commit | 254c6fcfe01e0bfc4f0b4fba7f809bd053d8ce56 (patch) | |
tree | 31c0f3a061218dca9ba29abb1308ded002d94904 | |
parent | 560234bc887441ed94c15a2314f3de12405c94b8 (diff) |
Add app that can read log fileslog-drawing
-rw-r--r-- | log_reader.c | 184 |
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, ¤t_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(¤t_entry, data); + + data = g_malloc(current_entry.stride * current_entry.height); + read(fd, data, current_entry.stride * current_entry.height); + + pixbuf2 = get_pixbuf(¤t_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; +} |