1 // Baseresource.cc from fluxter - tools to display resources in X11.
2 //
3 //  Copyright (c) 2008 Mark Willson, mark@hydrus.org.uk
4 //  Copyright (c) 2002 Steve Cooper, stevencooper@isomedia.com
5 //  Copyright (c) 1998-2000 John Kennis, jkennis@chello.nl
6 //
7 //  This program is free software; you can redistribute it and/or modify
8 //  it under the terms of the GNU General Public License as published by
9 //  the Free Software Foundation; either version 2 of the License, or
10 //  (at your option) any later version.
11 //
12 //  This program is distributed in the hope that it will be useful,
13 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
14 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 //  GNU General Public License for more details.
16 //
17 //  You should have received a copy of the GNU General Public License
18 //  along with this program; if not, write to the Free Software
19 //  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 //
21 // (See the included file COPYING / GPL-2.0)
22 //
23 
24 #include <stdlib.h>
25 #include "fluxter.hh"
26 #include "Baseresource.hh"
27 #include "wmstyle.hh"
28 
BaseResource(ToolWindow * toolwindow)29 BaseResource::BaseResource(ToolWindow *toolwindow) {
30   XrmValue value;
31   char *value_type;
32 
33   bbtool=toolwindow;
34   style.style_filename=NULL;
35   style.conf_filename=NULL;
36 
37   if (bbtool->nobb_config) {
38       ReadBBtoolResource();
39       ResourceType=FLUXTERG;
40   } else {
41     char *homedir = getenv("HOME");
42     bbtool->config_filename = new char[strlen(homedir) + 32];
43     sprintf(bbtool->config_filename, "%s/.fluxbox/init", homedir);
44     if ((resource_db = XrmGetFileDatabase(bbtool->config_filename))!=NULL) {
45       ReadWMResource();
46       ResourceType=FLUXBOX;
47     }
48     else {
49       ReadBBtoolResource();
50       ResourceType=FLUXTERG;
51     }
52   }
53 
54   if (XrmGetResource(resource_db, "session.colorsPerChannel",
55                      "Session.ColorsPerChannel", &value_type, &value)) {
56     if (sscanf(value.addr, "%d", &bbtool->colors_per_channel) != 1) {
57       bbtool->colors_per_channel = 4;
58     } else {
59       if (bbtool->colors_per_channel < 2) bbtool->colors_per_channel = 2;
60       if (bbtool->colors_per_channel > 6) bbtool->colors_per_channel = 6;
61     }
62   } else
63     bbtool->colors_per_channel = 4;
64 
65 
66   if (XrmGetResource(resource_db, "session.imageDither",
67                      "Session.ImageDither", &value_type, &value)) {
68     if (! strncasecmp("true", value.addr, value.size))
69       bbtool->image_dither = True;
70     else
71       bbtool->image_dither = False;
72   } else
73     bbtool->image_dither = True;
74 
75  if (bbtool->image_dither &&
76      bbtool->getCurrentScreenInfo()->getVisual()->c_class == TrueColor
77      && bbtool->getCurrentScreenInfo()->getDepth() >= 24)
78     bbtool->image_dither = False;
79 
80 	/* Need to do this here */
81 	bbtool->setupImageControl();
82 
83   if (XrmGetResource(resource_db, "fluxter.autoConfig",
84                      "Fluxter.Autoconfig", &value_type, &value)) {
85     if (! strncasecmp("true", value.addr, value.size)) {
86       auto_config = True;
87     } else
88       auto_config = False;
89   } else
90     auto_config = False;
91 
92   if (bbtool->withdrawn) auto_config=False;
93 
94   if (XrmGetResource(resource_db, "fluxter.autoConfig.checkTimeout",
95                      "Fluxter.Autoconfig.CheckTimeout", &value_type, &value)) {
96     if (sscanf(value.addr, "%u", &check_timeout) != 1)
97       check_timeout = 10;
98   }
99   else
100     check_timeout = 10;
101 
102   if ((bbtool->config_filename!=NULL)&(auto_config)) {
103     if (stat(bbtool->config_filename,&file_status)!=0) {
104       fprintf(stderr,"Can't use autoconfig");
105       auto_config=false;
106       mtime=0;
107     } else {
108       mtime=file_status.st_mtime;
109 
110       timer=new BTimer(toolwindow->getCurrentScreenInfo()->getBaseDisplay(),
111                         this);
112       timer->setTimeout(1000*check_timeout);
113       timer->start();
114     }
115   }
116 
117 }
118 
Load()119 void BaseResource::Load() {
120 
121   LoadBBToolResource();
122   XrmDestroyDatabase(resource_db);
123 }
124 
~BaseResource()125 BaseResource::~BaseResource() {
126   delete [] style.style_filename;
127   delete [] style.conf_filename;
128 
129   style.style_filename=NULL;
130   style.conf_filename=NULL;
131 }
132 
timeout()133 void BaseResource::timeout() {
134   if (stat(bbtool->config_filename,&file_status)!=0) {
135     fprintf(stderr,"Autoconfig error: Cannot get status of:%s\n",
136             bbtool->config_filename);
137     style.mtime=0;
138   } else {
139     if (mtime!=file_status.st_mtime) {
140       bbtool->reconfigure();
141       mtime=file_status.st_mtime;
142     }
143   }
144 }
145 
CopyColor(BColor * Color1,BColor * Color2)146 void BaseResource::CopyColor(BColor *Color1,BColor *Color2) {
147   Color2->setPixel(Color1->getPixel());
148   Color2->setRGB(Color1->getRed(),Color1->getGreen(),Color1->getBlue());
149 }
150 
CopyTexture(BTexture Texture1,BTexture * Texture2)151 void BaseResource::CopyTexture(BTexture Texture1,BTexture *Texture2) {
152   CopyColor(Texture1.getColor(),Texture2->getColor());
153   CopyColor(Texture1.getColorTo(),Texture2->getColorTo());
154   CopyColor(Texture1.getHiColor(),Texture2->getHiColor());
155   CopyColor(Texture1.getLoColor(),Texture2->getLoColor());
156   Texture2->setTexture(Texture1.getTexture());
157 }
158 
Reload()159 void BaseResource::Reload() {
160   struct stat file_status;
161 
162   switch (ResourceType) {
163     case FLUXTERG:
164       {
165         ReadBBtoolResource();
166       }
167       break;
168     case FLUXBOX:
169       {
170         if ((resource_db = XrmGetFileDatabase(bbtool->config_filename))!=NULL)
171           ReadWMResource();
172       }
173       break;
174   }
175   LoadBBToolResource();
176 
177   if ((bbtool->config_file!=NULL)&(style.auto_config)) {
178     if (stat(bbtool->config_filename,&file_status)!=0) {
179       fprintf(stderr,"Can't use autoconfig");
180       style.auto_config=false;
181       mtime=0;
182     } else
183         mtime=file_status.st_mtime;
184   }
185 
186   XrmDestroyDatabase(resource_db);
187 }
188 
ReadResourceFromFilename(const char * rname,const char * rclass)189 bool BaseResource::ReadResourceFromFilename(const char *rname,
190                                             const char *rclass) {
191   struct stat file_status;
192   char *filename=NULL;
193   XrmValue value;
194   char *value_type;
195 
196   if (XrmGetResource(resource_db,rname,rclass, &value_type, &value)) {
197     int len = strlen(value.addr);
198     delete [] filename;
199     filename = new char[len + 1];
200     memset(filename, 0, len + 1);
201     strncpy(filename, value.addr, len);
202     if (stat(filename,&file_status)!=0) {
203       db=NULL;
204       delete [] filename;
205       return(False);
206     }
207     db = XrmGetFileDatabase(filename);
208     delete [] filename;
209     return(True);
210   }
211   db=NULL;
212   delete [] filename;
213   return(False);
214 }
215 
ReadBBtoolResource()216 void BaseResource::ReadBBtoolResource() {
217 
218   if (bbtool->config_file) {
219     if ((resource_db = XrmGetFileDatabase(bbtool->config_file))==NULL) {
220       fprintf(stderr,"Could not open config file: %s\n",
221                 bbtool->config_file);
222       fprintf(stderr,"Using internal defaults.\n");
223     }
224     else
225       bbtool->config_filename=bbtool->config_file;
226   }
227   else {
228     delete [] style.conf_filename;
229     char *homedir = getenv("HOME");
230     int len=strlen(homedir) + strlen(FLUXTER_LOCAL);
231 
232     style.conf_filename = new char[len+2];
233     memset(style.conf_filename, 0, len + 2);
234     sprintf(style.conf_filename, "%s/%s", homedir,FLUXTER_LOCAL);
235     printf("Local fluxter config file: \"%s\"\n", style.conf_filename);
236     if ((resource_db = XrmGetFileDatabase(style.conf_filename))==NULL) {
237       delete [] style.conf_filename;
238       int len=strlen(FLUXTER_GLOBAL);
239       style.conf_filename = new char[len + 1];
240       memset(style.conf_filename, 0, len + 1);
241       strncpy(style.conf_filename,FLUXTER_GLOBAL, len);
242       printf("Global fluxter config file: \"%s\"\n", style.conf_filename);
243       if ((resource_db = XrmGetFileDatabase(style.conf_filename))==NULL) {
244         fprintf(stderr,"Could not open default config file: %s\n",
245                 style.conf_filename);
246         fprintf(stderr,"Using internal defaults.\n");
247       }
248       else
249         bbtool->config_filename=bbtool->config_file;
250     }
251     else
252       bbtool->config_filename=bbtool->config_file;
253   }
254 
255 }
256 
ReadWMResource()257 void BaseResource::ReadWMResource() {
258 
259   if (!ReadResourceFromFilename("session.styleFile","Session.StyleFile")) {
260     fprintf(stderr,"Could not open fluxbox style file\n");
261   } else
262     XrmCombineDatabase(db,&resource_db,False);
263 
264   if (bbtool->config_file!=NULL) {
265 printf("Config file: \"%s\"\n", bbtool->config_file);
266     if ((db = XrmGetFileDatabase(bbtool->config_file))==NULL) {
267       fprintf(stderr,"Could not open config file: %s\n",
268               bbtool->config_file);
269       return;
270     } else {
271       XrmCombineDatabase(db,&resource_db,True);
272     }
273   } else {
274     delete [] style.conf_filename;
275     char *homedir = getenv("HOME");
276     int len=strlen(homedir) + strlen(FLUXBOX_LOCAL);
277     style.conf_filename = new char[len+2];
278     memset(style.conf_filename, 0, len + 2);
279     sprintf(style.conf_filename, "%s/%s", homedir,FLUXBOX_LOCAL);
280 printf("Local fluxbox config file: \"%s\"\n", style.conf_filename);
281     if ((db = XrmGetFileDatabase(style.conf_filename))==NULL) {
282       delete [] style.conf_filename;
283       int len=strlen(FLUXBOX_GLOBAL);
284       style.conf_filename = new char[len + 1];
285       memset(style.conf_filename, 0, len + 1);
286       strncpy(style.conf_filename, FLUXBOX_GLOBAL, len);
287 printf("Default fluxbox config file: \"%s\"\n", style.conf_filename);
288       if ((db = XrmGetFileDatabase(style.conf_filename))==NULL) {
289         fprintf(stderr,"Could not open default config file: %s\n",
290                 style.conf_filename);
291         fprintf(stderr,"Using internal defaults.\n");
292         return;
293       }
294       else XrmCombineDatabase(db,&resource_db,True);
295     }
296     else XrmCombineDatabase(db,&resource_db,True);
297   }
298 }
299 
readTexture(const char * rname,const char * rclass,const char * bbname,const char * bbclass,const char * dcolor,const char * dcolorTo,const char * dtexture,BTexture * texture)300 void BaseResource::readTexture(const char *rname,const char *rclass,
301                                const char *bbname,
302                                const char *bbclass,const char *dcolor,
303                                const char *dcolorTo,
304                                const char *dtexture,BTexture *texture) {
305   readDatabaseTexture(rname,rclass,texture);
306   if (!texture->getTexture()) {
307     readDatabaseTexture(bbname,bbclass,texture);
308     if (!texture->getTexture()) {
309       bbtool->getImageControl()->parseTexture(texture, dtexture);
310       bbtool->getImageControl()->parseColor(texture->getColor(), dcolor);
311       bbtool->getImageControl()->parseColor(texture->getColorTo(), dcolorTo);
312     }
313   }
314 }
315 
readColor(const char * rname,const char * rclass,const char * bbname,const char * bbclass,const char * dcolor,BColor * color)316 void BaseResource::readColor(const char *rname,const char *rclass,
317                              const char *bbname,
318                              const char *bbclass,const char *dcolor,
319                              BColor *color) {
320   readDatabaseColor(rname,rclass,color);
321   if (!color->isAllocated()) {
322     readDatabaseColor(bbname,bbclass,color);
323     if (!color->isAllocated())
324       bbtool->getImageControl()->parseColor(color,dcolor);
325   }
326 }
327 
readDatabaseTexture(const char * rname,const char * rclass,BTexture * texture)328 void BaseResource::readDatabaseTexture(const char *rname, const char *rclass,
329 				  BTexture *texture) {
330   XrmValue value;
331   char *value_type;
332 
333   texture->setTexture(0);
334 
335   if (XrmGetResource(resource_db, rname, rclass, &value_type,
336 		     &value))
337     bbtool->getImageControl()->parseTexture(texture, value.addr);
338 
339   if (texture->getTexture() & BImage_Solid) {
340     int clen = strlen(rclass) + 8, nlen = strlen(rname) + 8;
341     char *colorclass = new char[clen], *colorname = new char[nlen];
342 
343     sprintf(colorclass, "%s.Color", rclass);
344     sprintf(colorname,  "%s.color", rname);
345 
346     readDatabaseColor(colorname, colorclass, texture->getColor());
347 
348     delete [] colorclass;
349     delete [] colorname;
350 
351     if ((! texture->getColor()->isAllocated()) ||
352 	(texture->getTexture() & BImage_Flat))
353       return;
354 
355     XColor xcol;
356 
357     xcol.red = (unsigned int) (texture->getColor()->getRed() +
358 			       (texture->getColor()->getRed() >> 1));
359     if (xcol.red >= 0xff) xcol.red = 0xffff;
360     else xcol.red *= 0xff;
361     xcol.green = (unsigned int) (texture->getColor()->getGreen() +
362 				 (texture->getColor()->getGreen() >> 1));
363     if (xcol.green >= 0xff) xcol.green = 0xffff;
364     else xcol.green *= 0xff;
365     xcol.blue = (unsigned int) (texture->getColor()->getBlue() +
366 				(texture->getColor()->getBlue() >> 1));
367     if (xcol.blue >= 0xff) xcol.blue = 0xffff;
368     else xcol.blue *= 0xff;
369 
370     if (! XAllocColor(bbtool->getXDisplay(), bbtool->getImageControl()->getColormap(),
371                       &xcol))
372       xcol.pixel = 0;
373 
374     texture->getHiColor()->setPixel(xcol.pixel);
375 
376     xcol.red =
377       (unsigned int) ((texture->getColor()->getRed() >> 2) +
378 		      (texture->getColor()->getRed() >> 1)) * 0xff;
379     xcol.green =
380       (unsigned int) ((texture->getColor()->getGreen() >> 2) +
381 		      (texture->getColor()->getGreen() >> 1)) * 0xff;
382     xcol.blue =
383       (unsigned int) ((texture->getColor()->getBlue() >> 2) +
384 		      (texture->getColor()->getBlue() >> 1)) * 0xff;
385 
386     if (! XAllocColor(bbtool->getXDisplay(), bbtool->getImageControl()->getColormap(),
387                       &xcol))
388       xcol.pixel = 0;
389 
390     texture->getLoColor()->setPixel(xcol.pixel);
391   } else if (texture->getTexture() & BImage_Gradient) {
392     int clen = strlen(rclass) + 10, nlen = strlen(rname) + 10;
393     char *colorclass = new char[clen], *colorname = new char[nlen],
394       *colortoclass = new char[clen], *colortoname = new char[nlen];
395 
396     sprintf(colorclass, "%s.Color", rclass);
397     sprintf(colorname,  "%s.color", rname);
398 
399     sprintf(colortoclass, "%s.ColorTo", rclass);
400     sprintf(colortoname,  "%s.colorTo", rname);
401 
402     readDatabaseColor(colorname, colorclass, texture->getColor());
403     readDatabaseColor(colortoname, colortoclass, texture->getColorTo());
404 
405     delete [] colorclass;
406     delete [] colorname;
407     delete [] colortoclass;
408     delete [] colortoname;
409   }
410 }
411 
readDatabaseColor(const char * rname,const char * rclass,BColor * color)412 void BaseResource::readDatabaseColor(const char *rname,
413                                      const char *rclass, BColor *color) {
414   XrmValue value;
415   char *value_type;
416   if (XrmGetResource(resource_db, rname, rclass, &value_type,
417 		     &value))
418     bbtool->getImageControl()->parseColor(color, value.addr);
419   else
420     // parsing with no color string just deallocates the color, if it has
421     // been previously allocated
422     bbtool->getImageControl()->parseColor(color);
423 }
424