If picture does no exist, warn and exit
[cascardo/movie.git] / gdk.c
1 /*
2  *  Copyright (C) 2008  Thadeu Lima de Souza Cascardo <cascardo@holoscopio.com>
3  *
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 2 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License along
15  *  with this program; if not, write to the Free Software Foundation, Inc.,
16  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  */
18
19
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <gtk/gtk.h>
23 #include <gdk-pixbuf/gdk-pixbuf.h>
24 #include "point.h"
25
26 struct ctx
27 {
28   GtkWidget *draw;
29   GdkPixbuf *picture;
30   GArray *points;
31   int i;
32   gboolean move;
33   GdkGC *gc;
34   GdkGC *gc2;
35   PangoAttrList *list;
36 };
37
38 #define WIDTH 800
39 #define HEIGHT 600
40
41 gboolean
42 queue (gpointer data)
43 {
44   struct ctx *ctx;
45   ctx = (struct ctx *) data;
46   gtk_widget_queue_draw (GTK_WIDGET (ctx->draw));
47   ctx->move = TRUE;
48   return FALSE;
49 }
50
51 gboolean
52 expose (GtkWidget *widget, GdkEventExpose *event, gpointer data)
53 {
54   GdkPixbuf *screen;
55   struct ctx *ctx;
56   Point point;
57   int w, h;
58   ctx = (struct ctx *) data;
59   gdk_drawable_get_size (GDK_DRAWABLE (event->window), &w, &h);
60   if (ctx->move)
61     ctx->i = (ctx->i >= ctx->points->len) ? 0 : ctx->i + 1;
62   point = g_array_index (ctx->points, Point, ctx->i);
63   screen = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8,
64                            event->area.width, event->area.height);
65   gdk_pixbuf_scale (ctx->picture, screen, 0, 0,
66                     event->area.width, event->area.height,
67                     -point.x + w/2 - event->area.x,
68                     -point.y + h/2 - event->area.y,
69                     point.rx, point.ry, GDK_INTERP_BILINEAR);
70   gdk_draw_pixbuf (widget->window, NULL, screen, 0, 0,
71                    event->area.x, event->area.y,
72                    event->area.width, event->area.height,
73                    GDK_RGB_DITHER_NONE, 0, 0);
74   gdk_pixbuf_unref (screen);
75   if (point.name)
76     {
77       PangoLayout *layout;
78       int pw, ph;
79       layout = gtk_widget_create_pango_layout (ctx->draw, point.name);
80       pango_layout_set_attributes (layout, ctx->list);
81       pango_layout_get_pixel_size (layout, &pw, &ph);
82       gdk_draw_rectangle (widget->window, ctx->gc2, TRUE,
83                           (WIDTH - pw - 8) / 2, HEIGHT - ph - 20, pw + 8, ph);
84       gdk_draw_layout (widget->window, ctx->gc, (WIDTH - pw) / 2,
85                        HEIGHT - ph - 20, layout);
86       g_object_unref (layout);
87       if (ctx->move)
88         g_timeout_add (3000, queue, ctx);
89     }
90   else
91     {
92       if (ctx->move)
93         g_timeout_add (10, queue, ctx);
94     }
95   ctx->move = FALSE;
96   return FALSE;
97 }
98
99 #define FPF 40
100
101 void
102 usage ()
103 {
104   fprintf (stderr, "movie picture dotsfile\n");
105   exit (0);
106 }
107
108 int
109 main (int argc, char **argv)
110 {
111   char *filename;
112   char *dotsfile;
113   GdkColorspace colorspace;
114   gboolean has_alpha;
115   int bits_per_sample;
116   int width, height;
117   GtkWidget *window;
118   struct ctx ctx;
119   GdkColor Yellow;
120   GdkColor Black;
121   PangoAttribute *attr;
122   GError *error;
123   gtk_init (&argc, &argv);
124   if (argc < 3)
125     {
126       usage ();
127     }
128   else
129     {
130       filename = argv[1];
131       dotsfile = argv[2];
132     }
133   ctx.points = ReadPoints (dotsfile);
134   ctx.points = drop_dup_frames (ctx.points, FPF);
135   rescale_points (ctx.points, get_scales (FPF));
136   error = NULL;
137   ctx.picture = gdk_pixbuf_new_from_file (filename, &error);
138   if (ctx.picture == NULL)
139     {
140       fprintf (stderr, "Could not open picture %s: %s\n", filename,
141                error->message);
142       g_error_free (error);
143       exit (1);
144     }
145   ctx.i = ctx.points->len;
146   colorspace = gdk_pixbuf_get_colorspace (ctx.picture);
147   has_alpha = gdk_pixbuf_get_has_alpha (ctx.picture);
148   bits_per_sample = gdk_pixbuf_get_bits_per_sample (ctx.picture);
149   width = WIDTH;
150   height = HEIGHT;
151   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
152   g_signal_connect (G_OBJECT (window), "destroy",
153                     G_CALLBACK (gtk_main_quit), NULL);
154   ctx.draw = gtk_drawing_area_new ();
155   gtk_widget_set_size_request (ctx.draw, width, height);
156   gtk_container_add (GTK_CONTAINER (window), ctx.draw);
157   gtk_widget_show_all (window);
158   g_signal_connect (G_OBJECT (ctx.draw), "expose_event",
159                     G_CALLBACK (expose), &ctx);
160   Yellow.red = 0xFFFF;
161   Yellow.green = 0xFFFF;
162   Yellow.blue = 0;
163   Black.red = 0;
164   Black.green = 0;
165   Black.blue = 0;
166   ctx.gc = gdk_gc_new (ctx.draw->window);
167   gdk_gc_set_rgb_fg_color (ctx.gc, &Yellow);
168   ctx.gc2 = gdk_gc_new (ctx.draw->window);
169   gdk_gc_set_rgb_fg_color (ctx.gc2, &Black);
170   ctx.list = pango_attr_list_new ();
171   attr = pango_attr_size_new (32 * PANGO_SCALE);
172   pango_attr_list_insert (ctx.list, attr);
173   attr = pango_attr_weight_new (PANGO_WEIGHT_SEMIBOLD);
174   pango_attr_list_insert (ctx.list, attr);
175   g_timeout_add (10, queue, &ctx);
176   gtk_main ();
177   gdk_pixbuf_unref (ctx.picture);
178   return 0;
179 }