1 #include <stdio.h>
2 #include <ctype.h>
3 #include <X11/Xlib.h>
4 #include <X11/Xutil.h>
5 
6 #include "ztypes.h"
7 #include "xio.h"
8 #include "arguments.h"
9 
10 #define DEFAULTGEOMETRY "500x600+100+100"
11 #define DEFAULTSTATGEOMETRY "80x24+100+50"
12 
13 static char *defaultfonts[NUMFONTS] = {
14     FND0, FND0,
15     FND1, FND1,
16     FND2, FND2,
17     FND3, FND3,
18     FND4, FND4,
19     FND5, FND5,
20     FND6, FND6,
21     FND7, FND7
22 };
23 
24 static char *attrnames[NUMFONTS] = {
25     "n",
26     "r",
27     "b",
28     "rb",
29     "i",
30     "ri",
31     "bi",
32     "rbi",
33     "f",
34     "rf",
35     "bf",
36     "rbf",
37     "if",
38     "rif",
39     "bif",
40     "rbif"
41 };
42 
43 #ifdef __STDC__
44 static char *findoption(int key);
45 static int str_to_attr(char *cx);
46 static int str_to_bool(char *cx);
47 #else
48 static char *findoption();
49 static int str_to_attr();
50 static int str_to_bool();
51 #endif
52 
53 #ifdef __STDC__
xinit_defaultprefs()54 void xinit_defaultprefs()
55 #else
56 void xinit_defaultprefs()
57 #endif
58 {
59     int ix;
60     strictz_report_mode = STRICTZ_DEFAULT_REPORT_MODE;
61     strictz_declare_spec = FALSE;
62     prefs.leading = 3;
63     prefs.marginx = 4;
64     prefs.marginy = 4;
65     prefs.inputattr = BOLD;
66     prefs.historylength = 20;
67     prefs.paging = FALSE;
68     prefs.fulljustify = TRUE;
69     prefs.buffersize = 4000;
70     prefs.bufferslack = 1000;
71     for (ix=0; ix<NUMFONTS; ix++)
72 	prefs.font[ix] = NULL;
73     prefs.statwid = 80;
74     prefs.stathgt = 24;
75     prefs.autoresize = TRUE;
76     prefs.resizeupward = FALSE;
77     prefs.autoclear = TRUE;
78     /* can't set up colors yet */
79 
80     xkey_init();
81 }
82 
83 /* set xiodpy, xioscn, xiodepth, fontstr[] */
84 #ifdef __STDC__
xinit_openconnection()85 void xinit_openconnection()
86 #else
87 void xinit_openconnection()
88 #endif
89 {
90     int ix;
91     int direction;
92     int ascent, descent;
93     XCharStruct overall;
94     XColor col, realcol;
95     Colormap colormap;
96     char *cx;
97 
98     xiodpy = XOpenDisplay(NULL);
99     if (!xiodpy) {
100 	fprintf(stderr, "%s: could not open display.\n", PROGRAMNAME);
101 	exit(-1);
102     }
103 
104     /* init all the X stuff */
105     xioscn = DefaultScreen(xiodpy);
106     xiodepth = DefaultDepth(xiodpy, xioscn);
107     if (DoesBackingStore(ScreenOfDisplay(xiodpy, xioscn)) == NotUseful)
108 	xiobackstore = FALSE;
109     else
110 	xiobackstore = TRUE;
111     colormap = DefaultColormap(xiodpy, xioscn);
112 
113     xinit_defaultprefs(); /* ### should be before argv[] parsing? */
114     prefs.forecolor = BlackPixel(xiodpy, xioscn);
115     prefs.backcolor = WhitePixel(xiodpy, xioscn);
116     for (ix=0; ix<NUMFONTS; ix++) {
117 	prefs.textcolor[ix] = prefs.forecolor;
118     }
119 
120     /* suck in the preferences */
121     cx = findoption(OPT_BINDINGS);
122     if (cx) {
123 	xkey_parse_bindings(cx);
124     }
125     cx = findoption(OPT_GEOMETRY);
126     if (!cx) {
127 	cx = DEFAULTGEOMETRY;
128     }
129     XGeometry(xiodpy, xioscn, cx, DEFAULTGEOMETRY, 1, 1, 1, 0, 0, &prefs.winx, &prefs.winy, &prefs.winw, &prefs.winh);
130     cx = findoption(OPT_STATGEOMETRY);
131     if (!cx) {
132 	cx = DEFAULTSTATGEOMETRY;
133     }
134     XGeometry(xiodpy, xioscn, cx, DEFAULTSTATGEOMETRY, 1, 1, 1, 0, 0, &prefs.statwinx, &prefs.statwiny, &prefs.statwid, &prefs.stathgt);
135     cx = findoption(OPT_STRICTZ);
136     if (cx) {
137         ix = atoi(cx);
138         if (ix >= STRICTZ_REPORT_NEVER && ix <= STRICTZ_REPORT_FATAL)
139 	    strictz_report_mode = ix;
140     }
141     cx = findoption(OPT_SPEC);
142     if (cx)
143 	strictz_declare_spec = str_to_bool(cx);
144     cx = findoption(OPT_INPUTSTYLE);
145     if (cx)
146 	prefs.inputattr = str_to_attr(cx);
147     cx = findoption(OPT_MARGINX);
148     if (cx)
149 	prefs.marginx = atoi(cx);
150     cx = findoption(OPT_LEADING);
151     if (cx)
152 	prefs.leading = atoi(cx);
153     cx = findoption(OPT_JUSTIFY);
154     if (cx)
155 	prefs.fulljustify = str_to_bool(cx);
156     cx = findoption(OPT_AUTORESIZE);
157     if (cx)
158 	prefs.autoresize = str_to_bool(cx);
159     cx = findoption(OPT_RESIZEUPWARD);
160     if (cx)
161 	prefs.resizeupward = str_to_bool(cx);
162     cx = findoption(OPT_AUTOCLEAR);
163     if (cx)
164 	prefs.autoclear = str_to_bool(cx);
165     cx = findoption(OPT_HISTORY);
166     if (cx)
167 	prefs.historylength = atoi(cx);
168     cx = findoption(OPT_BUFFER);
169     if (cx)
170 	prefs.buffersize = atol(cx);
171 
172     cx = findoption(OPT_BACKGROUND);
173     if (cx
174 	&& XAllocNamedColor(xiodpy, colormap, cx, &col, &realcol)) {
175 	prefs.backcolor = col.pixel;
176     }
177     cx = findoption(OPT_FOREGROUND);
178     if (cx
179 	&& XAllocNamedColor(xiodpy, colormap, cx, &col, &realcol)) {
180 	prefs.forecolor = col.pixel;
181 	for (ix=0; ix<NUMFONTS; ix++)
182 	    prefs.textcolor[ix] = col.pixel;
183     }
184     cx = findoption(OPT_GREYCOLOR);
185     if (!cx)
186 	cx = "grey60";
187     if (cx
188 	&& XAllocNamedColor(xiodpy, colormap, cx, &col, &realcol)) {
189 	prefs.greycolor = col.pixel;
190     }
191     else {
192 	prefs.greycolor = prefs.forecolor;
193     }
194     if (xiodepth > 1) {
195 	for (ix=0; ix<NUMFONTS; ix++) {
196 	    cx = findoption(OPT_STYLECOLOR+ix);
197 	    if (cx
198 		&& XAllocNamedColor(xiodpy, colormap, cx, &col, &realcol)) {
199 		prefs.textcolor[ix] = col.pixel;
200 	    }
201 	}
202     }
203     for (ix=0; ix<NUMFONTS; ix++) {
204 	cx = findoption(OPT_STYLEFONT+ix);
205 	if (cx) {
206 	    prefs.font[ix] = cx;
207 	}
208     }
209 
210     for (ix=0; ix<NUMFONTS; ix++) {
211 	if (!(ix & REVERSE)) {
212 	    fontstr[ix] = NULL;
213 	    if (prefs.font[ix])
214 		fontstr[ix] = XLoadQueryFont(xiodpy, prefs.font[ix]);
215 	    if (!fontstr[ix]) {
216 		if (prefs.font[ix]) {
217 		    fprintf(stderr, "%s: unable to load font <%s>, defaulting to <%s>...\n", PROGRAMNAME, prefs.font[ix], defaultfonts[ix]);
218 		}
219 		fontstr[ix] = XLoadQueryFont(xiodpy, defaultfonts[ix]);
220 		if (!fontstr[ix]) {
221 		    fprintf(stderr, "%s: fatal error: unable to load font <%s>\n", PROGRAMNAME, defaultfonts[ix]);
222 		    exit(1);
223 		}
224 	    }
225 	}
226 	else
227 	    fontstr[ix] = fontstr[ix & (~REVERSE)];
228     }
229 
230     /* figure out font foo */
231     for (ix=0; ix<NUMFONTS; ix++) {
232 	XTextExtents(fontstr[ix], " ", 1, &direction, &ascent, &descent, &overall);
233 	spacewidth[ix] = overall.width;
234 	if (fontstr[ix]->ascent + fontstr[ix]->descent > lineheight)
235 	    lineheight = fontstr[ix]->ascent + fontstr[ix]->descent;
236 	if (fontstr[ix]->ascent > lineheightoff)
237 	    lineheightoff = fontstr[ix]->ascent;
238     }
239     lineheight += prefs.leading;
240 
241     /* ensure all cut buffers exist */
242     for (ix=0; ix<8; ix++) {
243 	int size;
244 	char *cx = XFetchBuffer(xiodpy, &size, ix);
245 	if (!cx) {
246 	    XStoreBuffer(xiodpy, "#", sizeof(char), ix);
247 	}
248 	else {
249 	    free(cx);
250 	}
251     }
252 
253 }
254 
255 #ifdef __STDC__
findoption(int key)256 static char *findoption(int key)
257 #else
258 static char *findoption(key)
259 int key;
260 #endif
261 {
262     char *cx;
263     unixoption *opt;
264 
265     opt = (&unixoptionlist[key]);
266     if (!opt->name) {
267 	fprintf(stderr, "%s: internal option error on key %d\n", PROGRAMNAME, key);
268 	exit(1);
269     }
270 
271     if (opt->val)
272 	cx = opt->val;
273     else
274 	cx = XGetDefault(xiodpy, PROGRAMNAME, opt->name);
275 
276     return cx;
277 }
278 
279 #ifdef __STDC__
str_to_attr(char * cx)280 static int str_to_attr(char *cx)
281 #else
282 static int str_to_attr(cx)
283 char *cx;
284 #endif
285 {
286     int ix;
287     for (ix=0; ix<NUMFONTS; ix++) {
288 	if (!strcmp(attrnames[ix], cx))
289 	    return ix;
290     }
291     return 0;
292 }
293 
294 #ifdef __STDC__
str_to_bool(char * cx)295 static int str_to_bool(char *cx)
296 #else
297 static int str_to_bool(cx)
298 char *cx;
299 #endif
300 {
301     if (*cx=='y' || *cx=='Y' || *cx=='t' || *cx=='T')
302 	return TRUE;
303 
304     if (*cx=='o' || *cx=='O') {
305 	cx++;
306 	if (*cx=='n' || *cx=='N')
307 	    return TRUE;
308     }
309 
310     return FALSE;
311 }
312 
313