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