1 /*
2 **
3 ** scale.c
4 **
5 ** Copyright (C) 1997 Johannes Plass
6 ** Copyright (C) 2004 Jose E. Marchesi
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 **
18 ** You should have received a copy of the GNU General Public License
19 ** along with GNU gv; see the file COPYING.  If not, write to
20 ** the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 ** Boston, MA 02111-1307, USA.
22 **
23 ** Author:   Johannes Plass (plass@thep.physik.uni-mainz.de)
24 **           Department of Physics
25 **           Johannes Gutenberg-University
26 **           Mainz, Germany
27 **
28 **           Jose E. Marchesi (jemarch@gnu.org)
29 **           GNU Project
30 **
31 */
32 
33 #include "ac_config.h"
34 /*
35 #define MESSAGES
36 */
37 #include "message.h"
38 
39 #include <stdio.h>
40 #include <math.h>
41 #include <stdlib.h>
42 
43 #include "paths.h"
44 #include INC_X11(Intrinsic.h)
45 #include INC_XMU(SysUtil.h)
46 
47 #include "types.h"
48 #include "config.h"
49 #include "types.h"
50 #include "options.h"
51 #include "resource.h"
52 #include "scale.h"
53 
54 #include <string.h>
55 
56 
57 /*##################################################
58   scale_freeScales
59 ##################################################*/
60 
scale_freeScales(scales)61 void scale_freeScales(scales)
62   Scale *scales;
63 {
64   int i=0;
65   BEGINMESSAGE(scale_freeScales)
66   while (scales[i]) {
67     XtFree(scales[i]->name);
68     XtFree((XtPointer)scales[i]);
69     i++;
70   }
71   XtFree((XtPointer)scales);
72   ENDMESSAGE(scale_freeScales)
73 }
74 
75 /*##################################################
76   scale_parseScales
77 ##################################################*/
78 
scale_mallocScale(void)79 static Scale scale_mallocScale(void)
80 {
81   Scale scale;
82   scale = (Scale) XtMalloc(sizeof(ScaleStruct));
83   memset((void*)scale ,0,sizeof(ScaleStruct));
84   return scale;
85 }
86 
scale_parseScales(s)87 Scale *scale_parseScales(s)
88   char *s;
89 {
90   char *c,*nl;
91   Scale *scales,*mscales;
92   Scale scale;
93   int i,n,have_base=0,have_center=0;
94   char name[50],kind[50];
95   float f;
96 
97   BEGINMESSAGE(scale_parseScales)
98   if (!s) s = "";
99   s =options_squeezeMultiline(s);
100   for (n=1,c=s; (c = strchr(c,'\n')); n++, c++);
101   INFIMESSAGE(number of scales,n)
102   mscales = scales = (Scale*) XtMalloc((n+3)*sizeof(Scale));
103   c=s;
104   if (*s) while (n>0) {
105     nl = strchr(c,'\n');
106     if (nl) *nl='\0';
107     name[0]=kind[0]='\0';
108     f=-10.0;
109     if (*c=='#' || *c=='!') i=0;
110     else i=sscanf(c," %[^,] , %f , %[^,] ",name,&f,kind);
111     if (i>=2 && f>=-3.1) {
112       scale = scale_mallocScale();
113       scale->name = XtNewString(name);
114       if (f>0)
115          scale->scale = sqrt(f);
116       else
117          scale->scale = f;
118       if (i==3) {
119         if (!strcasecmp(kind,"screen")) { scale->is_base = SCALE_IS_REAL_BASED; have_base=1;}
120         else if (!strcasecmp(kind,"pixel")) { scale->is_base = SCALE_IS_PIXEL_BASED; have_base=1;}
121       }
122       if (!scale->is_base && f==1.0) { scale->is_center=1; have_center=1; }
123       INFSMESSAGE(found scale,scale->name);
124       FMESSAGE(scale->scale)
125       IMESSAGE(scale->is_base)
126       *scales++ = scale;
127     }
128     n--;
129     if (!nl) break;
130     c=++nl;
131   }
132   if (!have_center) {
133     scale = scale_mallocScale();
134     scale->name = XtNewString("1.000");
135     scale->scale = 1.0;
136     scale->is_center=1;
137     *scales++ = scale;
138   }
139   if (!have_base) {
140     scale = scale_mallocScale();
141     scale->name = XtNewString("Natural size");
142     scale->scale = 1.0;
143     scale->is_base=SCALE_IS_REAL_BASED;
144     *scales++ = scale;
145   }
146   *scales = (Scale) NULL;
147 
148   /* sort the scales: first the scale bases, then the relative ones. */
149   /* Also sort relative scales according to their scale value. */
150   scales=mscales;
151   n=0;
152   while (scales[n]) {
153     if (n>0 &&
154        ((scales[n]->is_base && !(scales[n-1]->is_base)) ||
155         (!(scales[n]->is_base) && !(scales[n-1]->is_base) &&
156 	 scales[n-1]->scale > scales[n]->scale))) {
157       scale=scales[n];
158       scales[n]=scales[n-1];
159       scales[n-1]=scale;
160       n=0;
161     }
162     else n++;
163   }
164   XtFree(s);
165   ENDMESSAGE(scale_parseScales)
166   return(mscales);
167 }
168 
169 /*##################################################################*/
170 /* scale_numOfScale */
171 /*##################################################################*/
172 
scale_checkScaleNum(scales,s)173 int scale_checkScaleNum(scales,s)
174   Scale *scales;
175   int s;
176 {
177   int j,n=-1;
178   int m;
179 
180   m = s & (~SCALE_VAL);
181   s = s & SCALE_VAL; if (m&SCALE_MIN) s = -s;
182   BEGINMESSAGE(scale_checkScaleNum)
183   if (m&SCALE_REL) {
184     for (j=0; scales[j] && !scales[j]->is_center; j++);
185     if (scales[j]) {
186       n = j;
187       j += s; if (j<0) j = 0;
188       while (n>j) if (scales[n-1]->is_base) break; else n--;
189       while (n<j) if (!scales[n+1]) break; else n++;
190     }
191   } else {
192     n = s;
193     for (j=0; scales[j] && (n != j); j++); if (!scales[j]) n=-1;
194   }
195   if (n>=0) {
196     if (m&SCALE_BAS) { if (!(scales[n]->is_base)) n=-1; }
197     else if (scales[n]->is_base) n = -1;
198   }
199   if (n>=0) {
200     if (m&SCALE_BAS) n = n|SCALE_BAS;
201     else             n = n|SCALE_ABS;
202   }
203   ENDMESSAGE(scale_checkScaleNum)
204   return n;
205 }
206 
207 /*##################################################################*/
208 /* scale_getScreenSize */
209 /*##################################################################*/
210 
scale_getScreenSize(display,screen,db,app_class,app_name,widthP,heightP)211 void scale_getScreenSize(display,screen,db,app_class,app_name,widthP,heightP)
212   Display *display;
213   Screen *screen;
214   XrmDatabase db;
215   char *app_class;
216   char *app_name;
217   int *widthP;
218   int *heightP;
219 {
220   int hmm=0,wmm=0;
221   char v[255];
222   char *s;
223   XrmDatabase sdb=NULL;
224 
225   BEGINMESSAGE(scale_getScreenSize)
226   s=XScreenResourceString(screen);
227   if (s) {
228     sdb=XrmGetStringDatabase(s);
229     s=resource_getResource(sdb,app_class,app_name,"screenSize",NULL);
230     INFSMESSAGE(found in SCREEN_RESOURCES,s)
231   }
232   if (!s) {
233     scale_getScreenResourceName(display,v);
234     s=resource_getResource(db,app_class,app_name,v,NULL);
235     INFSMESSAGE(found in screen specific resource,s)
236   }
237   if (!s) {
238     s=resource_getResource(db,app_class,app_name,"screenSize",NULL);
239     INFSMESSAGE(found,s)
240   }
241   if (s) strcpy(v,s); else v[0]='\0';
242   if (v[0]) sscanf(v," %d x %d ",&wmm,&hmm);
243   if (hmm > 0 && wmm > 0) {
244      *widthP=wmm;
245      *heightP=hmm;
246   } else {
247     *widthP=WidthMMOfScreen(screen);
248     *heightP=HeightMMOfScreen(screen);
249   }
250   if (sdb) XrmDestroyDatabase(sdb);
251   IIMESSAGE(*widthP,*heightP)
252   ENDMESSAGE(scale_getScreenSize)
253 }
254 
255 /*##################################################
256   scale_getScreenResourceName
257 ##################################################*/
258 
scale_getScreenResourceName(display,name)259 void scale_getScreenResourceName(display,name)
260   Display *display;
261   char *name;
262 {
263   char server[255],*s;
264   int disp=0,scr=0;
265 
266   BEGINMESSAGE(scale_getScreenResourceName)
267   server[0]='\0';
268   s=XDisplayName(XDisplayString(display));
269   if (s) {
270     strcpy(server,s);
271     s=strrchr(server,':');
272     if (s) {
273       *s++ = '\0';
274       if (*s == ':') s++;
275       if (*s=='.') sscanf(++s, "%d", &scr);
276       else         sscanf(s, "%d.%d", &disp,&scr);
277     }
278   }
279   if (!*server || !strcmp(server, "unix") || !strcmp(server, "localhost"))
280   {
281     char* ssh;
282     ssh = getenv("SSH_CLIENT");
283     if (ssh)
284     {
285        strcpy(server, ssh);
286        s=strrchr(server,' ');
287        if (s) *s='\0';
288        s = server;
289        while (*s)
290        {
291           if (*s == '.')  *s = '-';
292 	  s++;
293        }
294     }
295   }
296   if (!*server || !strcmp(server, "unix") || !strcmp(server, "localhost") || !strcmp(server, "127-0-0-1"))
297     XmuGetHostname(server, 255);
298   s=strrchr(server,'.');
299   if (s) *s='\0';
300   SMESSAGE(server)
301   if (server[0]) sprintf(name, "screenSize_%s_%d_%d",server,disp,scr);
302   else *name='\0';
303   SMESSAGE(name)
304   ENDMESSAGE(scale_getScreenResourceName)
305 }
306