Add missing source files (genius here).
[monky] / src / imlib2.c
1 /* Conky, a system monitor, based on torsmo
2  *
3  * Please see COPYING for details
4  *
5  * Copyright (c) 2005-2009 Brenden Matthews, et. al.
6  * All rights reserved.
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 3 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  * You should have received a copy of the GNU General Public License
18  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19  *
20  */
21
22 #include "imlib2.h"
23 #include "config.h"
24 #include "logging.h"
25
26 #include <Imlib2.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30
31 struct image_list_s {
32         const char *name;
33         Imlib_Image image;
34         struct image_list_s *prev;
35         struct image_list_s *next;
36 };
37
38 struct image_list_s *image_list_start, *image_list_end;
39
40 /* areas to update */
41 Imlib_Updates updates, current_update;
42 /* our virtual framebuffer image we draw into */
43 Imlib_Image buffer, image;
44
45 #define DEFAULT_CACHE_SIZE 4096 * 1024 /* default cache size for loaded images */
46
47 void cimlib_set_cache_size(long size)
48 {
49         if (size > 0) {
50                 imlib_set_cache_size(size);
51         }
52 }
53
54 void cimlib_cleanup(void)
55 {
56         struct image_list_s *cur = image_list_start, *last = NULL;
57         while (cur) {
58                 last = cur;
59                 cur = last->next;
60                 free(last);
61         }
62         image_list_start = image_list_end = NULL;
63 }
64
65 void cimlib_init(Display *display, Window window, Visual *visual, Colormap colourmap)
66 {
67         image_list_start = image_list_end = NULL;
68         cimlib_set_cache_size(DEFAULT_CACHE_SIZE);
69         /* set the maximum number of colors to allocate for 8bpp and less to 256 */
70         imlib_set_color_usage(256);
71         /* dither for depths < 24bpp */
72         imlib_context_set_dither(1);
73         /* set the display , visual, colormap and drawable we are using */
74         imlib_context_set_display(display);
75         imlib_context_set_visual(visual);
76         imlib_context_set_colormap(colourmap);
77         imlib_context_set_drawable(window);
78 }
79
80 void cimlib_add_image(const char *name)
81 {
82         struct image_list_s *cur = NULL;
83         cur = malloc(sizeof(struct image_list_s));
84         memset(cur, 0, sizeof(struct image_list_s));
85         cur->name = name;
86         if (image_list_end) {
87                 image_list_end->next = cur;
88                 cur->prev = image_list_end;
89                 image_list_end = cur;
90         } else {
91                 image_list_start = image_list_end = cur;
92         }
93 }
94
95 static void cimlib_draw_image(struct image_list_s *cur)
96 {
97         image = imlib_load_image(cur->name);
98         if (image) {
99                 int w, h;
100                 DBGP("Drawing image '%s'", cur->name);
101                 imlib_context_set_image(image);
102                 w = imlib_image_get_width();
103                 h = imlib_image_get_height();
104                 imlib_context_set_image(buffer);
105                 imlib_blend_image_onto_image(image, 0, 0, 0, w, h,
106                                 0, 0, w, h);
107                 imlib_context_set_image(image);
108                 imlib_free_image();
109         } else {
110                 ERR("Unable to load image '%s'", cur->name);
111         }
112 }
113
114 void cimlib_event_start(void)
115 {
116         if (!image_list_start) return; /* are we actually drawing anything? */
117         /* init our updates to empty */
118         updates = imlib_updates_init();
119 }
120
121 static void cimlib_draw_all(void)
122 {
123         struct image_list_s *cur = image_list_start;
124         while (cur) {
125                 cimlib_draw_image(cur);
126                 cur = cur->next;
127         }
128 }
129
130 void cimlib_event_end(int x, int y, int width, int height)
131 {
132         if (!image_list_start) return; /* are we actually drawing anything? */
133         /* take all the little rectangles to redraw and merge them into
134          * something sane for rendering */
135         updates = imlib_updates_merge_for_rendering(updates, width, height);
136         for (current_update = updates; current_update; current_update = imlib_updates_get_next(current_update)) {
137                 int up_x, up_y, up_w, up_h;
138
139                 /* find out where the first update is */
140                 imlib_updates_get_coordinates(current_update, 
141                                 &up_x, &up_y, &up_w, &up_h);
142
143                 /* create our buffer image for rendering this update */
144                 buffer = imlib_create_image(up_w, up_h);
145
146                 /* we can blend stuff now */
147                 imlib_context_set_blend(1);
148
149                 cimlib_draw_all();
150
151                 /* set the buffer image as our current image */
152                 imlib_context_set_image(buffer);
153                 /* render the image at 0, 0 */
154                 imlib_render_image_on_drawable(up_x, up_y);
155                 /* don't need that temporary buffer image anymore */
156                 imlib_free_image();
157         }
158         /* if we had updates - free them */
159         if (updates) {
160                 imlib_updates_free(updates);
161         } else {
162                 /* was likely a timeout, redraw everything */
163
164                 /* create our buffer image for rendering this update */
165                 buffer = imlib_create_image(width, height);
166
167                 /* we can blend stuff now */
168                 imlib_context_set_blend(1);
169
170                 cimlib_draw_all();
171
172                 /* set the buffer image as our current image */
173                 imlib_context_set_image(buffer);
174                 /* render the image at 0, 0 */
175                 imlib_render_image_on_drawable(x, y);
176                 /* don't need that temporary buffer image anymore */
177                 imlib_free_image();
178         }
179 }
180
181 void cimlib_event_expose(XEvent *event)
182 {
183         if (!image_list_start) return; /* are we actually drawing anything? */
184         updates = imlib_update_append_rect(updates,
185                         event->xexpose.x, event->xexpose.y,
186                         event->xexpose.width, event->xexpose.height);
187 }
188