added icons and xml to livewp directory in debian rules
[shermanaquarium] / sherman-aquarium / shermans / aquarium.c
1 /* 
2  * Sherman's aquarium - Applet v3.0.1
3  *
4  * (Formely known as aquarium applet.)
5  *
6  * Copyright (C) 2002-2003 Jonas Aaberg <cja@gmx.net>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You did not receive a copy of the GNU General Public License along with
19  * this program; chances are, you already have at least 10 copies of this
20  * license somewhere on your system.  If you still want it, write to the
21  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
22  * MA 02111-1307, USA.
23  *
24  * This applet was once based upon timecop's <timecop@japan.co.jp> fishmon, 
25  * but not much is now left of his code. (draw.c is mainly his code)
26  *
27  *
28  */
29
30
31 #include <stdio.h>
32 #include <sys/types.h>
33 #include <sys/stat.h>
34 #include <time.h>
35 #include <math.h>
36 #include <unistd.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <gai/gai.h>
40
41
42 #define GAI_APPLET_DEFINES
43 #include "../config.h"
44 #include "aquarium.h"
45 #include "draw.h"
46 #include "settings.h"
47
48 /* Features */
49 #include "clock.h"
50 #include "date.h"
51 #include "bubble.h"
52 #include "over.h"
53 #include "leds.h"
54 #include "thermometer.h"
55 #include "fish.h"
56 #include "background.h"
57 #ifdef XMMS
58 #include "xmms_sn.h"
59 #endif
60 #include "soundeffects.h"
61 #include "status.h"
62 #include "bottom.h"
63 #include "pref.h"
64
65
66 /* keeps track of mouse focus */
67 static int over_ruled;
68 static AquariumData ad;
69 static General_settings general_settings;
70
71 /* Only there for screensaver compability */
72 int fullscreen = 0, window_id = -1;
73
74
75 static void aquarium_enter(gpointer d)
76 {
77     ad.proximity = 1;
78     fish_enter();
79 }
80
81 static void aquarium_keypress(int key, gpointer d)
82 {
83     if(ad.proximity)
84         over_keypress(key);
85 }
86
87 static void aquarium_joystick(GaiFlagsJoystick flags, gpointer d)
88 {
89     if(ad.proximity)
90         over_joystick(flags);
91 }
92
93 static void aquarium_leave(gpointer d)
94 {
95     ad.proximity = 0;
96     fish_leave();
97 }
98
99 static void mouse_action(int flag, char *option)
100 {
101     if(flag == MOUSE_OFF)
102         return;
103
104     if(flag == MOUSE_RUN){
105         gai_exec(option);
106         return;
107     }
108 }
109
110 static void aquarium_mouseclick_left(int x, int y, gpointer d)
111 {
112     mouse_action(general_settings.mouse_left, general_settings.mouse_left_option);
113 }
114
115 static void aquarium_mouseclick_middle(int x, int y, gpointer d)
116 {
117     mouse_action(general_settings.mouse_middle, general_settings.mouse_middle_option);
118 }
119
120 static void aquarium_mouseclick_updown(int dir, gpointer d)
121 {
122     if(dir == GDK_SCROLL_UP)
123         mouse_action(general_settings.mouse_up, general_settings.mouse_up_option);
124     if(dir == GDK_SCROLL_DOWN)
125         mouse_action(general_settings.mouse_down, general_settings.mouse_down_option);
126 }
127
128
129
130 void aquarium_change(int orient, int new_w, int new_h, gpointer d)
131 {
132     static int old_xmax = -1, old_ymax = -1;
133     ad.dont_update = 1;
134
135     ad.ymin = gai_scale(YMIN);
136     ad.xmin = gai_scale(XMIN);
137     
138     if(gai_applet_mode() == GAI_DOCKAPP){
139         if(general_settings.ratio_width > general_settings.ratio_height){
140             ad.xmax = gai_get_size()*general_settings.ratio_width/general_settings.ratio_height - 2*ad.xmin;
141             ad.ymax = gai_get_size() - 2*ad.ymin;
142         } else {
143             ad.xmax = gai_get_size() - 2*ad.xmin;
144             ad.ymax = gai_get_size()*general_settings.ratio_height/general_settings.ratio_width - 2*ad.ymin;
145         }
146         if(old_ymax != ad.ymax || old_xmax != ad.xmax)
147             gai_background_set(ad.xmax+2*ad.xmin, ad.ymax+2*ad.ymin, GAI_BACKGROUND_MAX_SIZE_NONE, TRUE);
148     } else {
149         if(orient == GAI_HORIZONTAL){
150             if(general_settings.ratio_width > general_settings.ratio_height){
151                 ad.xmax = gai_get_size()*general_settings.ratio_width/general_settings.ratio_height - 2*ad.xmin;
152                 ad.ymax = gai_get_size() - 2*ad.ymin;
153             } else {
154                 ad.ymax = gai_get_size() - 2*ad.ymin;
155                 ad.xmax = gai_get_size()*general_settings.ratio_height/general_settings.ratio_width - 2*ad.xmin;
156             }
157             if(old_ymax != ad.ymax || old_xmax != ad.xmax)
158                 gai_background_set(ad.xmax+2*ad.xmin, ad.ymax+2*ad.ymin, GAI_BACKGROUND_MAX_SIZE_NONE, TRUE);
159         } else {
160             /* Vertical */
161             if(general_settings.ratio_width > general_settings.ratio_height){
162                 ad.ymax = gai_get_size() * general_settings.ratio_width/general_settings.ratio_height - 2*ad.ymin;
163                 ad.xmax = gai_get_size() - 2*ad.xmin;
164             } else {
165                 ad.xmax = gai_get_size() - 2*ad.xmin;
166                 ad.ymax = gai_get_size()*general_settings.ratio_height/general_settings.ratio_width - 2*ad.ymin;
167             }
168             if(old_ymax != ad.ymax || old_xmax != ad.xmax)
169                 gai_background_set(ad.ymax+2*ad.ymin,ad.xmax+2*ad.xmin, GAI_BACKGROUND_MAX_SIZE_NONE, TRUE);
170         }
171     
172 }
173     old_ymax = ad.ymax;
174     old_xmax = ad.xmax;
175
176     ad.virtual_aquarium_x = ad.xmax + 2 * VIRTUAL_AQUARIUM_DX;
177     ad.virtual_aquarium_y = ad.ymax + 2 * VIRTUAL_AQUARIUM_DX;
178
179     g_free(ad.rgb);
180     g_free(ad.bgr);
181
182     ad.rgb = g_malloc0((ad.xmax + 2) * (ad.ymax + 2) * 3);
183     ad.bgr = g_malloc0((ad.xmax + 2) * (ad.ymax + 2) * 3);
184
185     background_init();
186     bottom_init();
187
188     ad.dont_update = 0;
189
190 }
191
192
193
194 void prepare_graphics(void)
195 {
196
197     clock_init();
198     date_init();
199
200     bubble_init();
201
202     thermometer_init();
203
204     leds_init();
205 #ifdef XMMS
206     xmms_sn_init();
207 #endif
208     fish_init();
209
210     background_init();
211     bottom_init();
212
213     status_init();
214     over_init();
215
216 }
217
218
219 void aquarium_update(gpointer d)
220 {
221     static gboolean inited = 0;
222   /* If this function is called during reload of images,
223        just quit and wait until that is done. */
224
225     if(ad.dont_update)
226         return;
227
228     if(!inited){
229         inited = TRUE;
230         if(gai_applet_mode() == GAI_DOCKAPP){
231             if(ad.xmax < ad.ymax){
232                 aquarium_change(gai_get_orient(), 
233                                 gai_get_size(),
234                                 gai_get_size()*general_settings.ratio_height/general_settings.ratio_width,
235                                 NULL);
236             } else {
237                 aquarium_change(gai_get_orient(), 
238                                 gai_get_size()*general_settings.ratio_width/general_settings.ratio_height,
239                                 gai_get_size(),
240                                 NULL);
241             }
242         } else {
243             if(gai_get_orient() == GAI_HORIZONTAL){
244                 aquarium_change(gai_get_orient(), 
245                                 gai_get_size(),
246                                 gai_get_size()*general_settings.ratio_height/general_settings.ratio_width,
247                                 NULL);
248
249             }
250             else {
251                 aquarium_change(gai_get_orient(), 
252                                 gai_get_size()*general_settings.ratio_width/general_settings.ratio_height,
253                                 gai_get_size(),
254                                 NULL);
255             }
256         }
257     }
258
259     if(ad.drawingarea == NULL)
260         ad.drawingarea = gai_get_drawingarea();
261     
262     memcpy(ad.rgb, ad.bgr, ad.ymax * ad.xmax * 3);
263
264     /* If the mouse over function is completly domiating,
265        then, only call the mouse over function */
266
267     if(!over_ruled) {
268         leds_update(DRAW_BEFORE);
269         thermometer_update(DRAW_BEFORE);
270         clock_update(DRAW_BEFORE);
271 #ifdef XMMS
272         xmms_sn_update(DRAW_BEFORE);
273 #endif
274         date_update(DRAW_BEFORE);
275         
276
277         fish_update();
278         bubble_update();
279
280
281         thermometer_update(DRAW_AFTER);
282         clock_update(DRAW_AFTER);
283 #ifdef XMMS
284         xmms_sn_update(DRAW_AFTER);
285 #endif
286         date_update(DRAW_AFTER);
287         leds_update(DRAW_AFTER); 
288     }
289
290     over_ruled = over_update(ad.proximity);
291
292     ad.gc = gai_get_gc();
293
294     /* Draw it, not using gai */
295     gdk_draw_rgb_image(ad.drawingarea->window,  ad.gc, ad.xmin, ad.ymin, ad.xmax, ad.ymax,
296                        GDK_RGB_DITHER_NONE,ad.rgb, ad.xmax*3);
297     gdk_flush();
298 }
299   
300
301
302 void aquarium_free_all()
303 {
304
305     background_exit();
306     clock_exit();
307     date_exit();
308     over_exit();
309 #ifdef XMMS
310     xmms_sn_exit();
311 #endif
312     thermometer_exit();
313     status_exit();
314     bubble_exit();
315     fish_exit();
316     bottom_exit();
317
318     over_exit();
319     
320 }
321
322 void aquarium_reload_all()
323 {
324     background_init();
325     clock_init();
326     date_init();
327     status_init();
328 #ifdef XMMS
329     xmms_sn_init();
330 #endif
331     thermometer_init();
332     bubble_init();
333     /* We are loading fishes before aquarium_change gets activated, since it needs to call bottom and bg */
334     //    printf("fish init\n");
335     //fish_init();
336     bottom_init();              /* Must be after fish, because it draw bottom creatures. */
337     over_init();
338
339 }
340
341 /* This function (re)sets all the global variables to their default */
342 /* Some globals, don't have a default, those are not set ofcourse */
343
344 void init(void)
345 {
346
347     memset(&ad, 0, sizeof(AquariumData));
348
349     ad.rnd = g_rand_new();
350
351     clock_load_settings();
352     date_load_settings();
353 #ifdef XMMS
354     xmms_sn_load_settings();
355 #endif
356
357     bubble_load_settings();
358
359     thermometer_load_settings();
360     over_load_settings();
361     leds_load_settings();
362     
363
364     background_load_settings();
365     bottom_load_settings();
366
367     fish_load_settings();
368     general_load_settings();
369     sound_load_settings();
370     tetris_load_settings();
371
372     /* Default at start up is horizontal gnome-panel */
373     ad.ymax = YMAX;
374     ad.xmax = XMAX;
375
376     if(general_settings.ratio_width > general_settings.ratio_height){
377         ad.xmax = (XMAX+2*XMIN)*general_settings.ratio_width/general_settings.ratio_height - 2*XMIN;
378     } else {
379         ad.ymax = (YMAX+2*YMIN)*general_settings.ratio_height/general_settings.ratio_width - 2*YMIN;
380     }
381
382     ad.ymin = YMIN;
383     ad.xmin = XMIN;
384
385     ad.virtual_aquarium_x = XMAX + 2 * VIRTUAL_AQUARIUM_DX;
386     ad.virtual_aquarium_y = YMAX + 2 * VIRTUAL_AQUARIUM_DY;
387     ad.viewpoint_start_x = VIEWPOINT_START_X;
388     ad.viewpoint_start_y = VIEWPOINT_START_Y;
389
390     ad.proximity = 0;
391     over_ruled = 0;
392
393     ad.posx=ad.posy=-1;
394
395     ad.gc = NULL;
396     ad.drawingarea = NULL;
397
398     ad.special_action = 0;
399 }
400
401
402
403
404 int main(int argc, char **argv)
405 {
406
407     gai_init2(&applet_defines ,&argc, &argv);
408
409
410     /* Load saved settings and reset others */
411     init();
412
413     ad.rgb = g_malloc0((ad.xmax + 2) * (ad.ymax + 2) * 3);
414     ad.bgr = g_malloc0((ad.xmax + 2) * (ad.ymax + 2) * 3);
415
416     prepare_graphics();
417
418     pref_init();
419
420     gai_background_set(ad.xmax+2*ad.xmin, ad.ymax+2*ad.ymin, GAI_BACKGROUND_MAX_SIZE_NONE, TRUE);
421
422     gai_preferences2("Sherman's aquarium - Preferences", 
423                     shermans_pref, 
424                     "You cannot do anything dangerous with this applet,\n"
425                      "so just play around and look at what the applet does.\n"
426                      "If you still have some questions, feel free to mail me, cja@gmx.net.\n\n"
427                      "Thanks for trying Sherman's aquarium!\n\n"
428                      "http://aquariumapplet.sourceforge.net",
429                     (GaiCallback0 *)pref_restart, NULL);
430
431     /* 20 frames per second */
432     gai_signal_on_update((GaiCallback0 *)aquarium_update, 1000/50, NULL);
433     gai_signal_on_enter((GaiCallback0 *)aquarium_enter, NULL);
434     gai_signal_on_leave((GaiCallback0 *)aquarium_leave, NULL);
435     gai_signal_on_change((GaiCallback3 *)aquarium_change, NULL);
436     gai_signal_on_keypress((GaiCallback1 *)aquarium_keypress, NULL);
437     gai_signal_on_joystick((GaiCallback1 *)aquarium_joystick, NULL);
438
439     gai_signal_on_mouse_button_click((GaiCallback2 *)aquarium_mouseclick_left, GAI_MOUSE_BUTTON_1, NULL);
440     gai_signal_on_mouse_button_click((GaiCallback2 *)aquarium_mouseclick_middle, GAI_MOUSE_BUTTON_2, NULL);
441     gai_signal_on_scroll_buttons((GaiCallback1 *)aquarium_mouseclick_updown, NULL);
442
443
444     gai_start();
445     return 0;
446 }
447
448
449 AquariumData *aquarium_get_settings_ptr(void)
450 {
451     return &ad;
452 }
453
454 unsigned char *aquarium_install_path(void)
455 {
456     return applet_defines.image_path;
457 }
458
459 General_settings *general_get_settings_ptr(void)
460 {
461     return &general_settings;
462 }
463
464
465 void aquarium_draw_image(int x, int y, int idx, int rev, SA_Image *image)
466 {
467     draw_image(x, y, idx, rev, image);
468 }
469
470 void aquarium_draw_pic_alpha(SA_Image *image, int w, int h, int x, int y, int idx, int alpha)
471 {
472     draw_pic_alpha(image->image, w, h, x, y, idx, alpha);
473
474
475
476 void aquarium_clean_image(int x, int y, int w, int h)
477 {
478
479 }
480
481 /* This is just to keep background.c happy */
482 void grab_screen_image (Screen *s, Window w)
483 {
484
485 }