* src/hildon.h * src/hildon-remote-texture.c * src/hildon-remote-texture.h * src...
[hildon] / examples / hildon-remote-texture-example.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <glib.h>
4 #include <gtk/gtk.h>
5 #include <sys/types.h>
6 #include <sys/shm.h>
7 #include <string.h>
8 #include <math.h>
9 #include "hildon.h"
10
11 #define W 800
12 #define H 480
13
14 /* Press and drag to pan around, or tap to move between zoom levels.
15  * A file must be specified on the command-line, and it must be > 640x480.
16  *
17  * This file will be loaded and placed into a shared memory area, which will
18  * be read by hildon-desktop.
19  * An area 640x480 in the top-left corner will be updated with an animation
20  * to show how to modify the area. */
21
22 #define ANIM_X 0
23 #define ANIM_Y 0
24 #define ANIM_WIDTH 640
25 #define ANIM_HEIGHT 480
26 #define ANIM_FRAMES 64
27
28 static key_t shm_key = 0xCAFEBEEF;
29 static gint  bpp, width, height;
30 static guchar *shm = 0; /* shared mem */
31 static int anim_frame = 0;
32
33 static double scale = 1;
34 static double scale_smooth = 1;
35 static double x = 0;
36 static double y = 0;
37 static double x_inc = 0;
38 static double y_inc = 0;
39 static double cursor_move = 0;
40
41 static int last_x, last_y, pressed = 0;
42
43 static void timeout_cb (void *obj)
44 {
45     HildonRemoteTexture *actor = HILDON_REMOTE_TEXTURE (obj);
46
47     if (shm) {
48       gint x,y;
49
50       for (y=0;y<ANIM_HEIGHT;y++)
51         {
52           guchar *anim = &shm[(width*(y+ANIM_Y) + ANIM_X)*bpp];
53           for (x=0;x<ANIM_WIDTH;x++)
54             {
55               *anim = ((x+anim_frame)&(ANIM_FRAMES-1)) * 256 / ANIM_FRAMES;
56               anim += bpp;
57             }
58         }
59
60       hildon_remote_texture_update_area(actor,
61           ANIM_X, ANIM_Y, ANIM_WIDTH, ANIM_HEIGHT);
62       anim_frame++;
63     }
64
65     if (!pressed)
66       {
67         x += x_inc;
68         y += y_inc;
69         x_inc = x_inc * 0.8;
70         y_inc = y_inc * 0.8;
71         hildon_remote_texture_set_position (actor, x, y);
72
73         scale_smooth = scale_smooth*0.9 + scale*0.1;
74         hildon_remote_texture_set_scale (actor, scale_smooth, scale_smooth);
75       }
76
77 }
78
79 static void press_cb (GtkWidget *widget,
80                GdkEventButton *event, gpointer data)
81 {
82   pressed = TRUE;
83   last_x = event->x;
84   last_y = event->y;
85   cursor_move = 0;
86 }
87
88 static void release_cb (GtkWidget *widget,
89                GdkEventButton *event, gpointer obj)
90 {
91   pressed = FALSE;
92   last_x = event->x;
93   last_y = event->y;
94
95   if (cursor_move < 40)
96     {
97       scale = scale * 1.5;
98       if (scale>8) scale=0.125;
99       /* scale smooth will actually do the update */
100     }
101 }
102
103 static void motion_cb (GtkWidget *widget,
104                 GdkEventMotion *event, gpointer data)
105 {
106   HildonRemoteTexture *actor = HILDON_REMOTE_TEXTURE(data);
107
108   if (pressed)
109     {
110       x_inc = event->x - last_x;
111       y_inc = event->y - last_y;
112       cursor_move += fabs(x_inc) + fabs(y_inc);
113
114       x_inc /= scale;
115       y_inc /= scale;
116
117       x += x_inc;
118       y += y_inc;
119       hildon_remote_texture_set_position (actor, x, y);
120     }
121
122   last_x = event->x;
123   last_y = event->y;
124 }
125
126 int
127 main (int argc, char **argv)
128 {
129     gtk_init (&argc, &argv);
130
131     GdkPixbuf        *pixbuf;
132     GError           *error = 0;
133     guchar           *gpixels;
134
135     if (argc!=2)
136       {
137         printf("USAGE: hildon-remote-texture-example image.png\n");
138         printf("NB. Image should be 640x480 in size or greater\n");
139         return EXIT_FAILURE;
140       }
141
142     g_debug("Loading Image %s...", argv[1]);
143     pixbuf          = gdk_pixbuf_new_from_file (argv[1], &error);
144     width           = gdk_pixbuf_get_width (pixbuf);
145     height          = gdk_pixbuf_get_height (pixbuf);
146     bpp             = gdk_pixbuf_get_n_channels (pixbuf); /* assume 8 bit */
147     gpixels         = gdk_pixbuf_get_pixels (pixbuf);
148     g_debug("Creating Shared Memory");
149
150
151     size_t shm_size = width*height*bpp;
152     int shmid;
153
154     /*
155      * Create the segment, attach it to our data space, and copy in the
156      * texture we loaded
157      */
158     if ((shmid = shmget(shm_key, shm_size, IPC_CREAT | 0666)) < 0) {
159         perror("shmget");
160         exit(1);
161     }
162
163     if ((shm = shmat(shmid, NULL, 0)) == (guchar *) -1) {
164         perror("shmat");
165         exit(1);
166     }
167
168     memcpy(shm, gpixels, shm_size);
169
170     g_debug("Done.");
171
172
173
174     HildonProgram *program = hildon_program_get_instance ();
175
176     HildonWindow *window = HILDON_WINDOW(
177         hildon_window_new());
178     hildon_program_add_window (program, window);
179     gtk_window_set_decorated (GTK_WINDOW (window), FALSE);
180     gtk_widget_show (GTK_WIDGET(window));
181
182     HildonRemoteTexture *actor = HILDON_REMOTE_TEXTURE
183         (hildon_remote_texture_new ());
184     gtk_window_resize(GTK_WINDOW(actor), W, H);
185
186     g_set_application_name ("Animation");
187
188     g_signal_connect (G_OBJECT (actor),
189                       "delete_event",
190                       G_CALLBACK (gtk_main_quit), NULL);
191     g_signal_connect (G_OBJECT (actor),
192                               "button-press-event",
193                               G_CALLBACK (press_cb),
194                               actor);
195     g_signal_connect (G_OBJECT (actor),
196                                   "button-release-event",
197                                   G_CALLBACK (release_cb),
198                                   actor);
199     g_signal_connect (G_OBJECT (actor),
200                       "motion-notify-event",
201                       G_CALLBACK (motion_cb),
202                       actor);
203     gtk_widget_add_events (GTK_WIDGET(actor),
204                            GDK_BUTTON_PRESS_MASK|
205                            GDK_BUTTON_MOTION_MASK|
206                            GDK_BUTTON_RELEASE_MASK);
207
208
209     gtk_widget_show_all (GTK_WIDGET (actor));
210     gdk_flush ();
211
212     hildon_remote_texture_set_parent(actor, GTK_WINDOW(window));
213     hildon_remote_texture_set_image(actor, shm_key, width, height, bpp);
214     hildon_remote_texture_set_position (actor, x, y);
215     hildon_remote_texture_set_show (actor, 1);
216
217     g_timeout_add (25, (GSourceFunc)timeout_cb, actor);
218
219     printf ("going to gtk_main ()\n");
220     gtk_main ();
221     return 0;
222 }