1 | /*code snippet, not to be compiled separately*/ |
---|
2 | static int goat_pages=0; |
---|
3 | static int goat_frame=0; |
---|
4 | static GdkPixmap *goat_pix[2] = {NULL,NULL}; |
---|
5 | static GdkPixmap *goat_pix_rev[2] = {NULL,NULL}; |
---|
6 | static GtkWidget *goat_darea = NULL; |
---|
7 | static char *goat_filename = NULL; |
---|
8 | static int goat_width = 0,goat_height = 0; |
---|
9 | static int goat_timeout = 0; |
---|
10 | static int goat_x = -1, goat_y = -1; |
---|
11 | static int goat_accx = -1, goat_accy = -1; |
---|
12 | |
---|
13 | static void |
---|
14 | destroy_egg(GtkWidget *widget, gpointer data) |
---|
15 | { |
---|
16 | goat_pages = 0; |
---|
17 | if(goat_timeout) { |
---|
18 | gtk_timeout_remove(goat_timeout); |
---|
19 | goat_timeout = 0; |
---|
20 | } |
---|
21 | goat_x = goat_y = -1; |
---|
22 | } |
---|
23 | |
---|
24 | static int |
---|
25 | goat_timeout_func(gpointer data) |
---|
26 | { |
---|
27 | int real_goat_frame; |
---|
28 | |
---|
29 | if(!GTK_WIDGET_REALIZED(goat_darea) || |
---|
30 | !GTK_WIDGET_DRAWABLE(goat_darea) || |
---|
31 | !goat_pix[0]) |
---|
32 | return TRUE; |
---|
33 | |
---|
34 | if(goat_x == -1) { |
---|
35 | goat_x = 6; |
---|
36 | goat_y = 6; |
---|
37 | gdk_draw_rectangle(goat_darea->window, |
---|
38 | goat_darea->style->white_gc, |
---|
39 | TRUE, 0,0,-1,-1); |
---|
40 | goat_accx = rand()%4 +3; |
---|
41 | goat_accy = rand()%4 +3; |
---|
42 | } |
---|
43 | |
---|
44 | goat_x += goat_accx; |
---|
45 | goat_y += goat_accy; |
---|
46 | |
---|
47 | if(goat_x>goat_darea->allocation.width-6-goat_width) { |
---|
48 | goat_accx = -(rand()%4 +3); |
---|
49 | goat_x = goat_darea->allocation.width-6-goat_width; |
---|
50 | if(goat_filename) |
---|
51 | gnome_sound_play (goat_filename); |
---|
52 | } else if(goat_x<6) { |
---|
53 | goat_accx = rand()%4 +3; |
---|
54 | goat_x = 6; |
---|
55 | if(goat_filename) |
---|
56 | gnome_sound_play (goat_filename); |
---|
57 | } |
---|
58 | if(goat_y>goat_darea->allocation.height-6-goat_height) { |
---|
59 | goat_accy = -(rand()%4 +3); |
---|
60 | goat_y = goat_darea->allocation.height-6-goat_height; |
---|
61 | if(goat_filename) |
---|
62 | gnome_sound_play (goat_filename); |
---|
63 | } else if(goat_y<6) { |
---|
64 | goat_accy = rand()%4 +3; |
---|
65 | goat_y = 6; |
---|
66 | if(goat_filename) |
---|
67 | gnome_sound_play (goat_filename); |
---|
68 | } |
---|
69 | |
---|
70 | real_goat_frame = goat_frame/2; |
---|
71 | |
---|
72 | gdk_draw_pixmap(goat_darea->window, |
---|
73 | goat_darea->style->white_gc, |
---|
74 | goat_accx>0?goat_pix_rev[real_goat_frame]: |
---|
75 | goat_pix[real_goat_frame], |
---|
76 | 0,0,goat_x,goat_y, |
---|
77 | goat_width,goat_height); |
---|
78 | |
---|
79 | if(++goat_frame == 4) |
---|
80 | goat_frame = 0; |
---|
81 | |
---|
82 | return TRUE; |
---|
83 | } |
---|
84 | |
---|
85 | static int |
---|
86 | goat_expose(GtkWidget *widget, GdkEventExpose *event) |
---|
87 | { |
---|
88 | if(!GTK_WIDGET_DRAWABLE(widget)) |
---|
89 | return FALSE; |
---|
90 | |
---|
91 | gdk_draw_rectangle(goat_darea->window, |
---|
92 | goat_darea->style->white_gc, |
---|
93 | TRUE, event->area.x, event->area.y, |
---|
94 | event->area.width,event->area.height); |
---|
95 | return FALSE; |
---|
96 | } |
---|
97 | |
---|
98 | static void |
---|
99 | goat_realize(GtkWidget *widget) |
---|
100 | { |
---|
101 | int frame; |
---|
102 | char *files[] = { |
---|
103 | "gnome-gegl2.png", |
---|
104 | "gnome-gegl2-2.png" |
---|
105 | }; |
---|
106 | if(goat_pix[0]) |
---|
107 | return; |
---|
108 | for(frame=0;frame<2;frame++) { |
---|
109 | GdkPixbuf *pb; |
---|
110 | guchar *rgb; |
---|
111 | GdkGC *gc; |
---|
112 | int i,j; |
---|
113 | gdouble affine[6]; |
---|
114 | char *file; |
---|
115 | |
---|
116 | file = gnome_pixmap_file(files[frame]); |
---|
117 | if(!file || |
---|
118 | !(pb=gdk_pixbuf_new_from_file (file))) { |
---|
119 | g_warning("Goat is not available!"); |
---|
120 | return; |
---|
121 | } |
---|
122 | g_free(file); |
---|
123 | |
---|
124 | goat_width = gdk_pixbuf_get_width(pb)+12; |
---|
125 | goat_height = gdk_pixbuf_get_height(pb)+12; |
---|
126 | rgb = g_new(guchar,goat_width*goat_height*3); |
---|
127 | for(i=0;i<goat_width*goat_height*3;i++) |
---|
128 | rgb[i] = 0xFF; |
---|
129 | |
---|
130 | art_affine_translate(affine,6,6); |
---|
131 | transform_pixbuf(rgb, |
---|
132 | 0,0,goat_width,goat_height,goat_width*3, |
---|
133 | pb,affine,ART_FILTER_NEAREST,NULL); |
---|
134 | gdk_pixbuf_unref(pb); |
---|
135 | |
---|
136 | goat_pix[frame] = gdk_pixmap_new(widget->window, |
---|
137 | goat_width,goat_height, |
---|
138 | gtk_widget_get_visual(GTK_WIDGET(widget))->depth); |
---|
139 | gc = gdk_gc_new(goat_pix[frame]); |
---|
140 | gdk_draw_rgb_image(goat_pix[frame],gc,0,0, |
---|
141 | goat_width,goat_height, |
---|
142 | GDK_RGB_DITHER_NORMAL, |
---|
143 | rgb, goat_width*3); |
---|
144 | gdk_gc_destroy(gc); |
---|
145 | |
---|
146 | #define GUCHARSWAP(x,y) { guchar tmp=(x); (x)=(y); (y)=tmp; } |
---|
147 | for(i=0;i<goat_width/2;i++) |
---|
148 | for(j=0;j<goat_height;j++) { |
---|
149 | GUCHARSWAP(*(rgb+(j*goat_width*3)+(i*3)), |
---|
150 | *(rgb+(j*goat_width*3)+((goat_width-i-1)*3))) |
---|
151 | GUCHARSWAP(*(rgb+(j*goat_width*3)+(i*3)+1), |
---|
152 | *(rgb+(j*goat_width*3)+((goat_width-i-1)*3)+1)) |
---|
153 | GUCHARSWAP(*(rgb+(j*goat_width*3)+(i*3)+2), |
---|
154 | *(rgb+(j*goat_width*3)+((goat_width-i-1)*3)+2)) |
---|
155 | } |
---|
156 | #undef GUCHARSWAP |
---|
157 | |
---|
158 | goat_pix_rev[frame] = gdk_pixmap_new(widget->window, |
---|
159 | goat_width,goat_height, |
---|
160 | gtk_widget_get_visual(GTK_WIDGET(widget))->depth); |
---|
161 | gc = gdk_gc_new(goat_pix_rev[frame]); |
---|
162 | gdk_draw_rgb_image(goat_pix_rev[frame],gc,0,0, |
---|
163 | goat_width,goat_height, |
---|
164 | GDK_RGB_DITHER_NORMAL, |
---|
165 | rgb, goat_width*3); |
---|
166 | |
---|
167 | gdk_gc_destroy(gc); |
---|
168 | g_free(rgb); |
---|
169 | } |
---|
170 | } |
---|
171 | |
---|
172 | /*thy evil easter egg*/ |
---|
173 | static int |
---|
174 | config_event(GtkWidget *widget,GdkEvent *event,GtkNotebook *nbook) |
---|
175 | { |
---|
176 | static int clicks=0; |
---|
177 | GdkEventButton *bevent; |
---|
178 | |
---|
179 | if(event->type != GDK_BUTTON_PRESS) |
---|
180 | return FALSE; |
---|
181 | |
---|
182 | bevent = (GdkEventButton *)event; |
---|
183 | if(bevent->button != 3) |
---|
184 | clicks = 0; |
---|
185 | else |
---|
186 | clicks++; |
---|
187 | |
---|
188 | if(clicks<3) |
---|
189 | return FALSE; |
---|
190 | clicks = 0; |
---|
191 | |
---|
192 | if(goat_pages==0) { |
---|
193 | if(!goat_filename) |
---|
194 | goat_filename = |
---|
195 | gnome_sound_file ("ricochet.wav"); |
---|
196 | |
---|
197 | gtk_widget_push_visual (gdk_rgb_get_visual ()); |
---|
198 | gtk_widget_push_colormap (gdk_rgb_get_cmap ()); |
---|
199 | |
---|
200 | goat_darea = gtk_drawing_area_new(); |
---|
201 | |
---|
202 | gtk_widget_pop_colormap (); |
---|
203 | gtk_widget_pop_visual (); |
---|
204 | |
---|
205 | gtk_signal_connect_after(GTK_OBJECT(goat_darea),"realize", |
---|
206 | GTK_SIGNAL_FUNC(goat_realize),NULL); |
---|
207 | |
---|
208 | gtk_widget_show(goat_darea); |
---|
209 | goat_timeout = gtk_timeout_add(60,goat_timeout_func,NULL); |
---|
210 | /*the GEGL shall not be translated*/ |
---|
211 | gtk_notebook_append_page (nbook, goat_darea, |
---|
212 | gtk_label_new ("GEGL")); |
---|
213 | gtk_notebook_set_page(nbook,-1); |
---|
214 | goat_pages = 1; |
---|
215 | gtk_signal_connect(GTK_OBJECT(goat_darea),"destroy", |
---|
216 | GTK_SIGNAL_FUNC(destroy_egg),NULL); |
---|
217 | gtk_signal_connect(GTK_OBJECT(goat_darea),"expose_event", |
---|
218 | GTK_SIGNAL_FUNC(goat_expose),NULL); |
---|
219 | } else { |
---|
220 | gtk_notebook_set_page(nbook,-1); |
---|
221 | } |
---|
222 | return FALSE; |
---|
223 | } |
---|