dbus function is done
[shermanaquarium] / sherman-aquarium / shermans / background.c
1
2 #include <X11/Xlib.h>
3 #include <stdlib.h>
4
5 #ifdef GAI
6 #include <gai/gai.h>
7 #else
8
9 #include <gdk-pixbuf/gdk-pixbuf.h>
10
11 typedef struct {
12     unsigned char r,g,b,alpha;
13 } GaiColor;
14
15 void gai_display_error_continue(const char *);
16 GdkPixbuf *gai_load_image(const char *);
17
18 #endif
19
20 #include "aquarium.h"
21 #include "draw.h"
22 #include "grabscreen.h"
23 #include "background.h"
24
25
26 static Background_settings background_settings;
27 static AquariumData *ad;
28
29 Background_settings *background_get_settings_ptr(void)
30 {
31     return &background_settings;
32 }
33
34 static void background_prepare_solid(unsigned char r, unsigned char g, unsigned b)
35 {
36     int i,j,t;
37
38     for (i = 0; i < ad->ymax; i++) {
39         for (j = 0; j < ad->xmax; j++) {
40             t = (i * ad->xmax * 3) + j * 3;
41             ad->bgr[t + 0] = r;
42             ad->bgr[t + 1] = g;
43             ad->bgr[t + 2] = b;
44         }
45     }
46
47 }
48
49 static void background_prepare_shaded(unsigned char r1, unsigned char g1, unsigned b1,
50                                       unsigned char r2, unsigned char g2, unsigned b2)
51 {
52     int i,j,t;
53     float d1,d2,d3;
54
55     d1 = ((float)r2 - (float)r1) / (float) ad->ymax;
56     d2 = ((float)g2 - (float)g1) / (float) ad->ymax;
57     d3 = ((float)b2 - (float)b1) / (float) ad->ymax;
58
59     for (i = 0; i < ad->ymax; i++) {
60         for (j = 0; j < ad->xmax; j++) {
61             t = (i * ad->xmax * 3) + j * 3;
62             ad->bgr[t + 0] = (unsigned char)((float)r1 + ((float) i * d1));
63             ad->bgr[t + 1] = (unsigned char)((float)g1 + ((float) i * d2));
64             ad->bgr[t + 2] = (unsigned char)((float)b1 + ((float) i * d3));
65         }
66     }
67
68 }
69
70
71 static void background_prepare_image(char *image_file, int user_choise)
72 {
73     GdkPixbuf *water=NULL, *water2=NULL;
74     GError *imerr=NULL;
75     unsigned char *buff;
76     int i, j, k=0, y, rowstride, alpha;
77
78     if(user_choise){
79         water = gdk_pixbuf_new_from_file(image_file, &imerr);
80         if (water==NULL){
81             gai_display_error_continue("Can't load image!\nChanging to default water image background.");
82             water = gai_load_image("water.png");
83         }
84     } else {
85         water = gai_load_image("water.png");
86     }
87     
88     water2 = gdk_pixbuf_scale_simple(water, ad->xmax, ad->ymax,
89                                      GDK_INTERP_BILINEAR);
90     buff = gdk_pixbuf_get_pixels(water2);
91
92     rowstride = gdk_pixbuf_get_rowstride(water2);
93     alpha = (int)gdk_pixbuf_get_has_alpha(water2);
94     
95     for (i = 0; i < ad->ymax; i++) {
96         y = i * rowstride;
97         for (j = 0; j < ((ad->xmax * (3+alpha))); j += (3+alpha)) {
98             ad->bgr[k + 0] = buff[y + j + 0];
99             ad->bgr[k + 1] = buff[y + j + 1];
100             ad->bgr[k + 2] = buff[y + j + 2];
101             k += 3;
102         }
103     }
104
105     g_object_unref(water);
106     g_object_unref(water2);
107
108 }
109
110 static void background_prepare_desktop(void)
111 {
112     int rowstride, alpha, i, j, k=0, y;
113     unsigned char *buff, *str;
114     GdkPixbuf *desktop, *tmp_desktop;
115     GdkWindow *win;
116     Display *display;
117     Window xwin;
118
119     win = gdk_get_default_root_window();
120     str = getenv("SDL_WINDOWID");
121
122     if(str == NULL){
123         xwin = GDK_WINDOW_XWINDOW(win);
124     }
125     else{
126         xwin = (Window)atoi(str);
127         display = XOpenDisplay(NULL);
128         grab_screen_image(ScreenOfDisplay(display, DefaultScreen(display)), xwin);
129     }
130
131
132     desktop = gdk_pixbuf_get_from_drawable(NULL, 
133                                       GDK_DRAWABLE(win), 
134                                       NULL, 0,0,0,0,
135                                       gdk_screen_width(), gdk_screen_height());
136
137     if(gdk_screen_width() != ad->xmax || gdk_screen_height() != ad->ymax){
138         tmp_desktop = gdk_pixbuf_scale_simple(desktop, ad->xmax, ad->ymax,
139                                               GDK_INTERP_BILINEAR);
140         g_object_unref(desktop);
141         desktop = tmp_desktop;
142     }
143
144     buff = gdk_pixbuf_get_pixels(desktop);
145
146     rowstride = gdk_pixbuf_get_rowstride(desktop);
147     alpha = (int)gdk_pixbuf_get_has_alpha(desktop);
148     
149     for (i = 0; i < ad->ymax; i++) {
150         y = i * rowstride;
151         for (j = 0; j < ((ad->xmax * (3+alpha))); j += (3+alpha)) {
152             ad->bgr[k + 0] = buff[y + j + 0];
153             ad->bgr[k + 1] = buff[y + j + 1];
154             ad->bgr[k + 2] = buff[y + j + 2];
155             k += 3;
156         }
157     }
158
159     g_object_unref(desktop);
160 }
161
162 void background_exit(void)
163 {
164
165 }
166
167 void background_init(void)
168 {
169     ad = aquarium_get_settings_ptr();
170
171     
172     if(background_settings.desktop){
173         background_prepare_desktop();
174         return;
175     }
176
177
178     if(background_settings.type == BG_SOLID)
179         background_prepare_solid(background_settings.solid_c.r,
180                                  background_settings.solid_c.g,
181                                  background_settings.solid_c.b);
182
183     if(background_settings.type == BG_SHADED)
184         background_prepare_shaded(background_settings.shaded_top_c.r,
185                                   background_settings.shaded_top_c.g,
186                                   background_settings.shaded_top_c.b,
187                                   background_settings.shaded_bot_c.r,
188                                   background_settings.shaded_bot_c.g,
189                                   background_settings.shaded_bot_c.b);
190
191     if(background_settings.type == BG_IMAGE)
192         background_prepare_image(background_settings.imagename, 1);
193
194     if(background_settings.type == BG_WATER)
195         background_prepare_image(NULL,0);
196
197
198 }