1 /* wmDrawer (c) 2002-2004 Valery Febvre <vfebvre@easter-eggs.com>
2 *
3 * wmDrawer is a dock application (dockapp) which provides a
4 * drawer (button bar) to launch applications from.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20
21 #include "types_defs.h"
22 #include "images.h"
23
24 #ifdef USE_GDKPIXBUF
25 #include <gdk-pixbuf/gdk-pixbuf-xlib.h>
26 #endif
27
28 #ifdef USE_GDKPIXBUF2
29 #include <gdk-pixbuf-xlib/gdk-pixbuf-xlib.h>
30 #endif
31
32 #ifdef USE_IMLIB
33 #include <Imlib.h>
34 ImlibData *id;
35 #endif
36
37 unsigned int imageLibIsInit = 0;
38 extern Display *display;
39 extern drawerConfig config;
40 extern int nbImagesPaths;
41
initImgLib(void)42 static int initImgLib (void) {
43 if (imageLibIsInit == 0) {
44 #ifdef USE_GDKPIXBUF
45 gdk_pixbuf_xlib_init (display, DefaultScreen (display));
46 imageLibIsInit = 1;
47 #endif
48 #ifdef USE_GDKPIXBUF2
49 g_type_init ();
50 gdk_pixbuf_xlib_init (display, DefaultScreen (display));
51 imageLibIsInit = 1;
52 #endif
53 #ifdef USE_IMLIB
54 id = Imlib_init (display);
55 imageLibIsInit = 1;
56 #endif
57 }
58 return imageLibIsInit;
59 }
60
loadImageFromFile(char * file)61 static char *loadImageFromFile (char *file) {
62 #ifdef USE_GDKPIXBUF
63 return (char *)gdk_pixbuf_new_from_file (file);
64 #endif
65 #ifdef USE_GDKPIXBUF2
66 GError *error = NULL;
67 return (char *)gdk_pixbuf_new_from_file (file, &error);
68 #endif
69 #ifdef USE_IMLIB
70 return (char *)Imlib_load_image (id, file);
71 #endif
72 }
73
loadImageFromXpmData(const char ** data)74 static char *loadImageFromXpmData (const char **data) {
75 #ifdef USE_GDKPIXBUF
76 return (char *)gdk_pixbuf_new_from_xpm_data (data);
77 #endif
78 #ifdef USE_GDKPIXBUF2
79 return (char *)gdk_pixbuf_new_from_xpm_data (data);
80 #endif
81 #ifdef USE_IMLIB
82 return (char *)Imlib_create_image_from_xpm_data(id, (char **)data);
83 #endif
84 }
85
getImageWidth(char * img)86 static int getImageWidth (char *img) {
87 #ifdef USE_GDKPIXBUF
88 return gdk_pixbuf_get_width ((GdkPixbuf *)img);
89 #endif
90 #ifdef USE_GDKPIXBUF2
91 return gdk_pixbuf_get_width ((GdkPixbuf *)img);
92 #endif
93 #ifdef USE_IMLIB
94 return ((ImlibImage *)img)->rgb_width;
95 #endif
96 }
97
getImageHeight(char * img)98 static int getImageHeight (char *img) {
99 #ifdef USE_GDKPIXBUF
100 return gdk_pixbuf_get_height ((GdkPixbuf *)img);
101 #endif
102 #ifdef USE_GDKPIXBUF2
103 return gdk_pixbuf_get_height ((GdkPixbuf *)img);
104 #endif
105 #ifdef USE_IMLIB
106 return ((ImlibImage *)img)->rgb_height;
107 #endif
108 }
109
scaleImage(char * img,int w,int h)110 static char *scaleImage (char *img, int w, int h) {
111 #ifdef USE_GDKPIXBUF
112 return (char *)gdk_pixbuf_scale_simple ((GdkPixbuf *)img,
113 w, h, GDK_INTERP_HYPER);
114 #endif
115 #ifdef USE_GDKPIXBUF2
116 return (char *)gdk_pixbuf_scale_simple ((GdkPixbuf *)img,
117 w, h, GDK_INTERP_HYPER);
118 #endif
119 #ifdef USE_IMLIB
120 return (char *)Imlib_clone_scaled_image (id, (ImlibImage *)img, w, h);
121 #endif
122 }
123
unrefImage(char * img)124 static void unrefImage (char *img) {
125 #ifdef USE_GDKPIXBUF
126 gdk_pixbuf_unref ((GdkPixbuf *)img);
127 #endif
128 #ifdef USE_GDKPIXBUF2
129 g_object_unref ((GdkPixbuf *)img);
130 #endif
131 #ifdef USE_IMLIB
132 Imlib_kill_image (id, (ImlibImage *)img);
133 #endif
134 }
135
createPixmapAndMask(char * img,Pixmap * pixmap,Pixmap * mask)136 static void createPixmapAndMask (char *img, Pixmap *pixmap, Pixmap *mask) {
137 #ifdef USE_GDKPIXBUF
138 gdk_pixbuf_xlib_render_pixmap_and_mask ((GdkPixbuf *)img, pixmap, mask, 128);
139 #endif
140 #ifdef USE_GDKPIXBUF2
141 gdk_pixbuf_xlib_render_pixmap_and_mask ((GdkPixbuf *)img, pixmap, mask, 128);
142 #endif
143 #ifdef USE_IMLIB
144 Imlib_render (id, (ImlibImage *)img, ((ImlibImage *)img)->rgb_width,
145 ((ImlibImage *)img)->rgb_height);
146 *pixmap = Imlib_move_image (id, (ImlibImage *)img);
147 *mask = Imlib_move_mask (id, (ImlibImage *)img);
148 #endif
149 }
150
151 /*
152 Create pixmap from image data and resize it to fit (dimW x dimH)
153 img : image data
154 imgPix : pixmap result
155 imgMask : mask result
156 w : pixmap width result
157 h : pixmap height result
158 dimW : max width allows
159 dimH : max height allows
160 resizeMask : resize mask
161 */
createAndResizePixmap(char * img,Pixmap * imgPix,Pixmap * imgMask,int * w,int * h,int dimW,int dimH,unsigned long resizeMask)162 void createAndResizePixmap (char *img, Pixmap *imgPix, Pixmap *imgMask,
163 int *w, int *h, int dimW, int dimH,
164 unsigned long resizeMask) {
165 char *imgScaled = NULL;
166
167 *w = getImageWidth (img);
168 *h = getImageHeight (img);
169
170 if (resizeMask > 0) {
171 /* resize smaller ? */
172 if ((*w > dimW || *h > dimH) && ((resizeMask >> (RESIZE_SMALLER-1)) % 2)) {
173 if ((float) *w / (float) dimW > (float) *h / (float) dimH) {
174 *h = (int) ((*h * dimW) / *w);
175 *w = dimW;
176 }
177 else {
178 *w = (int) ((*w * dimH) / *h);
179 *h = dimH;
180 }
181 }
182 /* resize greater ? */
183 if ((*w < dimW && *h < dimH) && ((resizeMask >> (RESIZE_GREATER-1)) % 2)) {
184 if (*w >= *h) {
185 *h = (int) ((*h * dimW) / *w);
186 *w = dimW;
187 }
188 else {
189 *w = (int) ((*w * dimH) / *h);
190 *h = dimH;
191 }
192 }
193 /* ready for resizing */
194 imgScaled = scaleImage (img, *w, *h);
195 unrefImage (img);
196 img = imgScaled;
197 }
198 createPixmapAndMask (img, imgPix, imgMask);
199 unrefImage (img);
200 }
201
createPixmapFromFile(char * file,Pixmap * imgPix,Pixmap * imgMask,int * w,int * h,int dimW,int dimH,unsigned long resizeMask)202 int createPixmapFromFile (char *file, Pixmap *imgPix, Pixmap *imgMask,
203 int *w, int *h, int dimW, int dimH,
204 unsigned long resizeMask) {
205 int i;
206 char *img;
207 char path[FILENAME_MAX];
208
209 if (initImgLib() == 0) {
210 printf ("%s warning: can't init image library.\n", PACKAGE);
211 return 0;
212 }
213 if (file == NULL) {
214 printf ("%s warning: a file path is (null)!\n", PACKAGE);
215 return 0;
216 }
217
218 /* quick test for absolute path */
219 img = loadImageFromFile (file);
220 if (file[0] != '/' || img == NULL) {
221 /* else try all paths */
222 for (i=0; i<nbImagesPaths; i++) {
223 sprintf(path, "%s/%s", config.imagesPaths[i], file);
224 img = loadImageFromFile (path);
225 if (img != NULL) break;
226 }
227 }
228 if (img == NULL) {
229 printf ("%s warning: can't load image %s\n", PACKAGE, file);
230 return 0;
231 }
232
233 createAndResizePixmap (img, imgPix, imgMask, w, h, dimW, dimH, resizeMask);
234 return 1;
235 }
236
createPixmapFromData(const char ** data,Pixmap * imgPix,Pixmap * imgMask,int * w,int * h,int dimW,int dimH,unsigned long resizeMask)237 void createPixmapFromData (const char **data, Pixmap *imgPix, Pixmap *imgMask,
238 int *w, int *h, int dimW, int dimH,
239 unsigned long resizeMask) {
240 char *img;
241
242 initImgLib();
243 img = loadImageFromXpmData (data);
244 createAndResizePixmap (img, imgPix, imgMask, w, h, dimW, dimH, resizeMask);
245 }
246