Added inotify support for reloading Lua scripts automagically.
[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         char name[DEFAULT_TEXT_BUFFER_SIZE];
33         Imlib_Image image;
34         int x, y, w, h;
35         int wh_set;
36         struct image_list_s *next;
37 };
38
39 struct image_list_s *image_list_start, *image_list_end;
40
41 /* areas to update */
42 Imlib_Updates updates, current_update;
43 /* our virtual framebuffer image we draw into */
44 Imlib_Image buffer, image;
45
46 #define DEFAULT_CACHE_SIZE 4096 * 1024 /* default cache size for loaded images */
47
48 void cimlib_set_cache_size(long size)
49 {
50         imlib_set_cache_size(size);
51 }
52
53 void cimlib_cleanup(void)
54 {
55         struct image_list_s *cur = image_list_start, *last = NULL;
56         while (cur) {
57                 last = cur;
58                 cur = last->next;
59                 free(last);
60         }
61         image_list_start = image_list_end = NULL;
62 }
63
64 void cimlib_init(Display *display, Window drawable, Visual *visual, Colormap colourmap)
65 {
66         image_list_start = image_list_end = NULL;
67         cimlib_set_cache_size(DEFAULT_CACHE_SIZE);
68         /* set the maximum number of colors to allocate for 8bpp and less to 256 */
69         imlib_set_color_usage(256);
70         /* dither for depths < 24bpp */
71         imlib_context_set_dither(1);
72         /* set the display , visual, colormap and drawable we are using */
73         imlib_context_set_display(display);
74         imlib_context_set_visual(visual);
75         imlib_context_set_colormap(colourmap);
76         imlib_context_set_drawable(drawable);
77 }
78
79 void cimlib_add_image(const char *args)
80 {
81         struct image_list_s *cur = NULL;
82         char *tmp;
83
84         cur = malloc(sizeof(struct image_list_s));
85         memset(cur, 0, sizeof(struct image_list_s));
86
87         if (!sscanf(args, "%1024s", cur->name)) {
88                 ERR("Invalid args for $image.  Format is: '<path to image> (-p x,y) (-s WxH)' (got '%s')", args);
89         }
90         // now we check for optional args
91         tmp = strstr(args, "-p ");
92         if (tmp) {
93                 tmp += 3;
94                 sscanf(tmp, "%i,%i", &cur->x, &cur->y);
95         }
96         tmp = strstr(args, "-s ");
97         if (tmp) {
98                 tmp += 3;
99                 if (sscanf(tmp, "%ix%i", &cur->w, &cur->h)) {
100                         cur->wh_set = 1;
101                 }
102         }
103
104         if (image_list_end) {
105                 image_list_end->next = cur;
106                 image_list_end = cur;
107         } else {
108                 image_list_start = image_list_end = cur;
109         }
110 }
111
112 static void cimlib_draw_image(struct image_list_s *cur)
113 {
114         image = imlib_load_image(cur->name);
115         if (image) {
116                 int w, h;
117                 DBGP("Drawing image '%s' at (%i,%i) scaled to %ix%i", cur->name, cur->x, cur->y, cur->w, cur->h);
118                 imlib_context_set_image(image);
119                 w = imlib_image_get_width();
120                 h = imlib_image_get_height();
121                 imlib_context_set_image(buffer);
122                 imlib_blend_image_onto_image(image, 1, 0, 0, h, w,
123                                 cur->x, cur->y, cur->w, cur->h);
124                 imlib_context_set_image(image);
125                 imlib_free_image();
126         } else {
127                 ERR("Unable to load image '%s'", cur->name);
128         }
129 }
130
131 static void cimlib_draw_all(void)
132 {
133         struct image_list_s *cur = image_list_start;
134         while (cur) {
135                 cimlib_draw_image(cur);
136                 cur = cur->next;
137         }
138 }
139
140 void cimlib_render(int x, int y, int width, int height)
141 {
142         if (!image_list_start) return; /* are we actually drawing anything? */
143         /* take all the little rectangles to redraw and merge them into
144          * something sane for rendering */
145         buffer = imlib_create_image(width, height);
146         /* clear our buffer */
147         imlib_context_set_image(buffer);
148         imlib_image_clear();
149         /* we can blend stuff now */
150         imlib_context_set_blend(1);
151
152         cimlib_draw_all();
153
154         /* set the buffer image as our current image */
155         imlib_context_set_image(buffer);
156         /* render the image at 0, 0 */
157         imlib_render_image_on_drawable(x, y);
158         /* don't need that temporary buffer image anymore */
159         imlib_free_image();
160 }
161