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