1 /*
2  *  This program is free software; you can redistribute it and/or modify
3  *  it under the terms of the GNU General Public License as published by
4  *  the Free Software Foundation; either version 2 of the License, or
5  *  (at your option) any later version.
6  *
7  *  This program is distributed in the hope that it will be useful,
8  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
9  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  *  GNU Library General Public License for more details.
11  *
12  *  You should have received a copy of the GNU General Public License
13  *  along with this program; if not, write to the Free Software
14  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
15  */
16 
17 /*----------------------------------------------------------------------*
18  * Originally written:
19  *    2002      Alexis <materm@tele2.fr>
20  *
21  *----------------------------------------------------------------------*/
22 
23 /* Resource management
24  *
25  * $Id: xresources.c,v 1.9 2004/08/15 16:20:38 alexis Exp $
26  */
27 
28 #include "../config.h"
29 #include "rxvt.h"		/* NECESSARY */
30 #include "xresources.h"
31 
32 #ifdef DEBUG
33 #define DEBUG_XRSCR_ALEXIS 1
34 #else
35 #define DEBUG_XRSCR_ALEXIS 0
36 #endif
37 
38 #if DEBUG_XRSCR_ALEXIS
39 #define DXR_ALEXIS(d,x) if(d <= DEBUG_XRSCR_ALEXIS) fprintf x
40 #else
41 #define DXR_ALEXIS(d,x)
42 #endif
43 
44 /* local variables */
45 static const char *rs_loginShell = NULL;
46 static const char *rs_utmpInhibit = NULL;
47 static const char *rs_scrollBar = NULL;
48 static const char *rs_scrollBar_right = NULL;
49 static const char *rs_scrollBar_floating = NULL;
50 static const char *rs_scrollTtyOutputInh = NULL;
51 static const char *rs_scrollKeypress = NULL;
52 
53 #ifdef TRANSPARENT
54 static const char *rs_transparent = NULL;
55 static const char *rs_transparent_sb = NULL;
56 #endif
57 
58 #ifdef DONT_TILE_PIXMAP_OPTION
59 static const char *rs_dontTilePixmap = NULL;
60 static const char *rs_dontTilePixmapH = NULL;
61 static const char *rs_dontTilePixmapV = NULL;
62 #endif
63 
64 #if defined (HOTKEY_CTRL) || defined (HOTKEY_META)
65 static const char *rs_bigfont_key = NULL;
66 static const char *rs_smallfont_key = NULL;
67 #endif
68 
69 #ifndef NO_MAPALERT
70 # ifdef MAPALERT_OPTION
71 static const char *rs_mapAlert = NULL;
72 # endif
73 #endif
74 static const char *rs_visualBell = NULL;
75 static const char *rs_reverseVideo = NULL;
76 
77 #ifdef META8_OPTION
78 static const char *rs_meta8 = NULL;
79 #endif
80 #ifdef MULTICHAR_SET
81 static const char *rs_multichar_encoding = NULL;
82 #endif
83 #ifdef GREEK_SUPPORT
84 static const char *rs_greek_keyboard = NULL;
85 #endif
86 
87 /* monolithic option/resource structure: */
88 /*
89  * `string' options MUST have a usage argument
90  * `switch' and `boolean' options have no argument
91  *
92  * if there's no desc(ription), it won't appear in usage()
93  */
94 static const struct
95 {
96 	unsigned long flag;
97 	const char **dp;	/* data pointer */
98 	const char *const kw;	/* keyword */
99 	const char *const opt;	/* option */
100 	const char *const arg;	/* argument */
101 	const char *const desc;	/* description */
102 }
103 optList[] =
104 {
105 
106 /*
107  * INFO() - descriptive information only
108  * STRG() - command-line option, with/without resource
109  * RSTRG() - resource/long-option
110  * BOOL() - regular boolean `-/+' flag
111  * SWCH() - `-' flag
112  */
113 #define INFO(opt, arg, desc)         {0, NULL, NULL, opt, arg, desc}
114 #define STRG(p, kw, opt, arg, desc)	 {0, &p, kw, opt, arg, desc}
115 #define RSTRG(p, kw, arg)	           {0, &p, kw, NULL, arg, NULL}
116 #define BOOL(p, kw, opt, flag, desc) {(Opt_Boolean|flag), &p, kw, opt, NULL, desc}
117 #define SWCH(opt, flag, desc)	       {(flag), NULL, NULL, opt, NULL, desc}
118 
119 /* convenient macros */
120 #define optList_strlen(i)	(optList[i].flag ? 0 : (optList[i].arg ? strlen (optList[i].arg) : 1))
121 #define optList_isBool(i)	(optList[i].flag & Opt_Boolean)
122 #define optList_size()		(sizeof(optList) / sizeof(optList[0]))
123 
124   STRG (display_name, NULL, "display", "string", "X server to contact"),
125   STRG (rs_term_name, "termName", "tn", "string", "value of the TERM environment variable"),
126   STRG (rs_geometry, "geometry", "geometry", "geometry", "size (in characters) and position"),
127   STRG (display_name, NULL, "d", NULL, NULL),	/* short form */
128   STRG (rs_geometry, NULL, "g", NULL, NULL),	/* short form */
129   BOOL (rs_reverseVideo, "reverseVideo", "rv", Opt_reverseVideo,"reverse video"),
130 #ifdef _MYSTYLE_
131   STRG (rs_mystyle, "MyStyle", "mst", "name", "MyStyle"),
132 #endif
133   STRG (rs_color[Color_bg], "background", "bg", "color","background color"),
134 //  STRG (rs_tab_title, "tab_title", "tt", "string","tab titles"),
135   STRG (rs_term_num, "tab_num", "nt", "number","numbers of tab at startup"),
136   STRG (rs_color[Color_fg], "foreground", "fg", "color","foreground color"),
137   /* colors: command-line long-option = resource name */
138   RSTRG (rs_color[minCOLOR + 0], "color0", "color"),
139   RSTRG (rs_color[minCOLOR + 1], "color1", "color"),
140   RSTRG (rs_color[minCOLOR + 2], "color2", "color"),
141   RSTRG (rs_color[minCOLOR + 3], "color3", "color"),
142   RSTRG (rs_color[minCOLOR + 4], "color4", "color"),
143   RSTRG (rs_color[minCOLOR + 5], "color5", "color"),
144   RSTRG (rs_color[minCOLOR + 6], "color6", "color"),
145   RSTRG (rs_color[minCOLOR + 7], "color7", "color"),
146 #ifndef NO_BRIGHTCOLOR
147   RSTRG (rs_color[minBrightCOLOR + 0], "color8", "color"),
148   RSTRG (rs_color[minBrightCOLOR + 1], "color9", "color"),
149   RSTRG (rs_color[minBrightCOLOR + 2], "color10", "color"),
150   RSTRG (rs_color[minBrightCOLOR + 3], "color11", "color"),
151   RSTRG (rs_color[minBrightCOLOR + 4], "color12", "color"),
152   RSTRG (rs_color[minBrightCOLOR + 5], "color13", "color"),
153   RSTRG (rs_color[minBrightCOLOR + 6], "color14", "color"),
154   RSTRG (rs_color[minBrightCOLOR + 7], "color15", "color"),
155 #endif /* NO_BRIGHTCOLOR */
156 #ifndef NO_BOLDUNDERLINE
157   RSTRG (rs_color[Color_BD], "colorBD", "color"),
158   RSTRG (rs_color[Color_UL], "colorUL", "color"),
159 #endif /* NO_BOLDUNDERLINE */
160 #ifdef KEEP_SCROLLCOLOR
161   RSTRG (rs_color[Color_scroll], "scrollColor", "color"),
162   RSTRG (rs_color[Color_trough], "troughColor", "color"),
163 #endif /* KEEP_SCROLLCOLOR */
164 #if defined (BACKGROUND_IMAGE) || (MENUBAR_MAX)
165   RSTRG (rs_path, "path", "search path"),
166 #endif /* defined (BACKGROUND_IMAGE) || (MENUBAR_MAX) */
167 #ifdef BACKGROUND_IMAGE
168   STRG (rs_backgroundPixmap,"backgroundPixmap","pixmap", "file[;geom]", "background pixmap"),
169 #endif /* BACKGROUND_IMAGE */
170 #if defined(BACKGROUND_IMAGE) || defined(TRANSPARENT)
171   STRG (rs_backgroundType,"backgroundType","bgtype", BGT_ALL,
172     "type of the background pixmap transformation"),
173   STRG (rs_tintType, "tintingType", "tinttype", TINT_TYPE_ALL,
174     "defines function to be used for background tinting"),
175   STRG (rs_shade, "shading", "sh", "%",
176     "make transparent background x% darker"),
177   STRG (rs_color[Color_tint], "tinting", "tint", "color",
178     "tinted transparency color"),
179 #endif
180   STRG (rs_textType,"textType","txttype", GC_TYPE_ALL,
181     "defines function to be used for text drawing"),
182 #ifdef OFF_FOCUS_FADING
183   STRG (rs_fade,"fading","fade", "%",
184     "make colors x% darker when aterm is loosing focus."),
185 #endif
186 #ifdef BOOL
187 #ifdef TRANSPARENT
188   BOOL (rs_transparent, "transparent", "tr", Opt_transparent,
189     "transparent background"),
190   BOOL (rs_transparent_sb, "transpscrollbar", "trsb",
191     Opt_transparent_sb, "transparent scrollbar"),
192 #endif
193 #endif
194 #if (MENUBAR_MAX)
195   RSTRG (rs_menu, "menu", "name[;tag]"),
196 #endif
197 #ifndef NO_BOLDFONT
198     STRG (rs_boldFont, "boldFont", "fb", "fontname","bold text font"),
199 #endif
200   STRG (rs_font[0], "font", "fn", "fontname","normal text font"),
201 /* fonts: command-line option = resource name */
202 #if NFONTS > 1
203   RSTRG (rs_font[1], "font1", "fontname"),
204 #endif
205 #if NFONTS > 2
206   RSTRG (rs_font[2], "font2", "fontname"),
207 #endif
208 #if NFONTS > 3
209   RSTRG (rs_font[3], "font3", "fontname"),
210 #endif
211 #if NFONTS > 4
212   RSTRG (rs_font[4], "font4", "fontname"),
213 #endif
214 #if NFONTS > 5
215   RSTRG (rs_font[5], "font5", "fontname"),
216 #endif
217 #if NFONTS > 6
218   RSTRG (rs_font[6], "font6", "fontname"),
219 #endif
220 #if NFONTS > 7
221   RSTRG (rs_font[7], "font7", "fontname"),
222 #endif
223 #ifdef MULTICHAR_SET
224   STRG (rs_mfont[0], "mfont", "fm", "fontname","multichar font"),
225 /* fonts: command-line option = resource name */
226 # if NFONTS > 1
227   RSTRG (rs_mfont[1], "mfont1", "fontname"),
228 # endif
229 # if NFONTS > 2
230   RSTRG (rs_mfont[2], "mfont2", "fontname"),
231 # endif
232 # if NFONTS > 3
233   RSTRG (rs_mfont[3], "mfont3", "fontname"),
234 # endif
235 # if NFONTS > 4
236   RSTRG (rs_mfont[4], "mfont4", "fontname"),
237 # endif
238 # if NFONTS > 5
239   RSTRG (rs_mfont[5], "mfont5", "fontname"),
240 # endif
241 # if NFONTS > 6
242   RSTRG (rs_mfont[6], "mfont6", "fontname"),
243 # endif
244 # if NFONTS > 7
245   RSTRG (rs_mfont[7], "mfont7", "fontname"),
246 # endif
247 #endif /* MULTICHAR_SET */
248 #ifdef MULTICHAR_SET
249   STRG (rs_multichar_encoding, "multichar_encoding", "km","mode",
250     "multiple-character font encoding; mode = eucj | sjis | big5"),
251 #endif /* MULTICHAR_SET */
252 #ifdef GREEK_SUPPORT
253   STRG (rs_greek_keyboard, "greek_keyboard", "grk", "mode",
254     "greek keyboard mapping; mode = iso | ibm"),
255 #endif
256   SWCH ("iconic", Opt_iconic, "start iconic"), SWCH ("ic", Opt_iconic, NULL),	/* short form */
257   STRG (rs_name, NULL, "name", "string", "client instance, icon, and title strings"),
258   STRG (rs_title, "title", "title", "string", "title name for window"),
259   STRG (rs_title, NULL, "T", NULL, NULL),	/* short form */
260   STRG (rs_iconName, "iconName", "n", "string","icon name for window"),
261 #ifndef NO_CURSORCOLOR
262   STRG (rs_color[Color_cursor], "cursorColor", "cr", "color","cursor color"),
263 /* command-line option = resource name */
264   RSTRG (rs_color[Color_cursor2], "cursorColor2", "color"),
265 #endif /* NO_CURSORCOLOR */
266   STRG (rs_color[Color_pointer], "pointerColor", "pr", "color","pointer color"),
267   STRG (rs_borderWidth, "borderWidth", "bw", "number","width of border"),
268 //  STRG (rs_configFile, "configFile", "cf", "file","configuration file"),
269   STRG (rs_color[Color_border], "borderColor", "bd", "color","border color"),
270   BOOL (rs_loginShell, "loginShell", "ls", Opt_loginShell,"login shell"),
271   BOOL (rs_scrollBar, "scrollBar", "sb",Opt_scrollBar, "scrollbar"),
272   BOOL (rs_scrollBar_right, "scrollBar_right", "sr",Opt_scrollBar_right, "scrollbar right"),
273   BOOL (rs_scrollBar_floating, "scrollBar_floating", "st",Opt_scrollBar_floating,
274     "scrollbar without a trough"),
275   BOOL (rs_scrollTtyOutputInh, "scrollTtyOutput", "si",Opt_scrollTtyOutputInh,
276     "scroll-on-tty-output inhibit"),
277   BOOL (rs_scrollKeypress, "scrollTtyKeypress", "sk",Opt_scrollKeypress, "scroll-on-keypress"),
278   STRG (rs_minBufferWidth, "minBufferWidth", "mbw", "number",
279     "minimum number of columns stored in buffer"),
280   STRG (rs_saveLines, "saveLines", "sl", "number","number of scrolled lines to save"),
281   BOOL (rs_utmpInhibit, "utmpInhibit", "ut", Opt_utmpInhibit,"utmp inhibit"),
282   BOOL (rs_visualBell, "visualBell","vb", Opt_visualBell,"visual bell"),
283 #ifndef NO_MAPALERT
284 # ifdef MAPALERT_OPTION
285   BOOL (rs_mapAlert, "mapAlert", NULL, Opt_mapAlert, NULL),
286 # endif
287 #endif
288 #ifdef META8_OPTION
289   BOOL (rs_meta8, "meta8", NULL, Opt_meta8, NULL),
290   RSTRG (rs_modifier, "modifier", "string"),
291 #endif
292 #ifndef NO_BACKSPACE_KEY
293   RSTRG (rs_backspace_key, "backspacekey", "string"),
294 #endif
295 #ifndef NO_DELETE_KEY
296   RSTRG (rs_delete_key, "deletekey", "string"),
297 #endif
298 #ifdef PRINTPIPE
299   RSTRG (rs_print_pipe, "print-pipe", "string"),
300 #endif
301 #if defined (HOTKEY_CTRL) || defined (HOTKEY_META)
302   RSTRG (rs_bigfont_key, "bigfont_key", "keysym"),
303   RSTRG (rs_smallfont_key, "smallfont_key", "keysym"),
304 #endif
305 #ifdef CUTCHAR_RESOURCE
306   RSTRG (rs_cutchars, "cutchars", "string"),
307 #endif /* CUTCHAR_RESOURCE */
308   SWCH ("C", Opt_console, "intercept console messages"),
309   INFO ("e", "command arg ...", "command to execute"),
310 //  STRG (rs_shading,".VT.Shading","sh2", "%","Shading percentage")
311 };
312 
313 #undef INFO
314 #undef STRG
315 #undef RSTRG
316 #undef SWCH
317 #undef BOOL
318 
319 #if defined(BACKGROUND_IMAGE) || defined(TRANSPARENT)
320 static const char *transparencies[MAX_PAGES];
321 static const char *shadings[MAX_PAGES];
322 static char *tintings[MAX_PAGES];
323 static char *pixmaps[MAX_PAGES];
324 static char *bg_types[MAX_PAGES];
325 static char *tint_types[MAX_PAGES];
326 #endif
327 
328 static char *save_lines[MAX_PAGES];
329 static char *titles[MAX_PAGES];
330 static char *rs_console;
331 
332 /* Brand new resources management,
333  * experimental !
334  */
335 struct s_resources_list {
336   const int multiple;    /* indicate if there's more than 1 resource for that class */
337   const char *resource;  /* resource name */
338   const char *class;     /* resource class */
339   const char *kw;        /* type of resource : string, color, ... */
340   const char *option;    /* command line option */
341   int flag;              /* flag for switch option */
342   const char **data_ptr; /* data pointer : could be scalar or table */
343   const char *help;      /* help message for lost soul */
344 } resources_list [] = {
345   {0,NULL,NULL,"string","display",0,&display_name,"X server to contact"},
346   {0,NULL,NULL,"string","d",0,&display_name,"X server to contact"},
347 #ifdef TRANSPARENT
348   {0,APL_NAME".vt%d.transparent",APL_CLASS".Vt.Transparent",NULL,"tr",Opt_transparent,&rs_transparent,"transparent background"},
349   {0,APL_NAME".transpscrollbar",APL_CLASS".Transpscrollbar",NULL,"trsb",Opt_transparent_sb,&rs_transparent_sb,"transparent scrollbar"},
350 #endif
351 #if defined(BACKGROUND_IMAGE) || defined(TRANSPARENT)
352   {1,APL_NAME".vt%d.tinting",APL_CLASS".Vt.Tinting","color","tint",0,tintings,"tinted transparency color"},
353   {1,APL_NAME".vt%d.shading",APL_CLASS".Vt.Shading","number","sh",0,shadings,"make transparent background x% darker"},
354   {1,APL_NAME".vt%d.bgType",APL_CLASS".Vt.BgType","bgtype","bgtype",0,bg_types,"transformation type for background pixmap"},
355   //{1,APL_NAME".vt%d.tintingType",APL_CLASS".Vt.TintingType","tinttype",0,tint_types,"function applied for background tinting"},
356   {0,APL_NAME".vt%d.tintingType",APL_CLASS".Vt.TintingType","toto","tinttype",0,&rs_tintType,"function applied for background tinting"},
357 #endif
358   {0,APL_NAME".textType",APL_CLASS".TextType","toto","txttype",0,&rs_textType,"function applied for text drawing"},
359 #ifdef BACKGROUND_IMAGE
360   {1,APL_NAME".vt%d.pixmap",APL_CLASS".Vt.Pixmap","file[;geometry]","pixmap",0,pixmaps,"pixmap background"},
361 #endif
362   {0,APL_NAME".name",APL_CLASS".Name","string","name",0,&rs_name,"client instance, icon, and title strings"},
363   {0,APL_NAME".iconName",APL_CLASS".IconName","string","n",0,&rs_iconName,"icon name for window"},
364   {0,NULL,NULL,NULL,"iconic",Opt_iconic,&rs_iconic,"start iconic"},
365   {1,APL_NAME".vt%d.title",APL_CLASS".Vt.Title","string",NULL,0,titles,"title name for notebooks"},
366   {1,APL_NAME".vt%d.saveLines",APL_CLASS".Vt.SaveLines","number","sl",0,save_lines,"number of scrolled lines to save"},
367   {0,APL_NAME".termName",APL_CLASS".TermName","string","tn",0,&rs_term_name,"value of the TERM environment variable"},
368   {0,APL_NAME".geometry",APL_CLASS".Geometry","geometry","geometry",0,&rs_geometry,"size (in characters) and position"},
369   {0,NULL,NULL,"geometry","g",0,&rs_geometry,"size (in characters) and position"},
370   {0,APL_NAME".reverseVideo",APL_CLASS".ReverseVideo",NULL,"rv",Opt_reverseVideo,&rs_reverseVideo,"reverse video"},
371   {0,APL_NAME".foreground",APL_CLASS".Foreground","color","fg",0,&rs_color[Color_fg],"foreground color"},
372   {0,APL_NAME".background",APL_CLASS".Background","color","bg",0,&rs_color[Color_bg],"background color"},
373   {0,APL_NAME".loginShell",APL_CLASS".LoginShell",NULL,"ls",Opt_loginShell,&rs_loginShell,"login shell"},
374   {0,APL_NAME".borderWidth",APL_CLASS".BorderWidth","number","bw",0,&rs_borderWidth,"border width"},
375   {0,APL_NAME".scrollbar",APL_CLASS".Scrollbar",NULL,"sb",Opt_scrollBar,&rs_scrollBar,"scroll bar"},
376   {0,APL_NAME".scrollbarRight",APL_CLASS".ScrollbarRight",NULL,"sr",Opt_scrollBar_right,&rs_scrollBar_right,"scrollbar on right"},
377   {0,APL_NAME".scrollbarFloating",APL_CLASS".ScrollbarFloating",NULL,"st",Opt_scrollBar_floating,&rs_scrollBar_floating,"scrollbar without a trough"},
378   {0,APL_NAME".scrollbarTtyOutput",APL_CLASS".ScrollbarTtyOutput",NULL,"si",Opt_scrollTtyOutputInh,&rs_scrollTtyOutputInh,"scroll-on-tty-output inhibit"},
379   {0,APL_NAME".scrollbarTtyKeypress",APL_CLASS".ScrollbarTtyKeypress",NULL,"sk",Opt_scrollKeypress,&rs_scrollKeypress,"scroll-on-keypress"},
380   {0,APL_NAME".minBufferWidth",APL_CLASS".MinBufferWidth","number","mbw",0,&rs_minBufferWidth,"minimum number of columns stored in buffer"},
381   {0,APL_NAME".utmpInhibit",APL_CLASS".UtmpInhibit",NULL,"ut",Opt_utmpInhibit,&rs_utmpInhibit,"utmp inhibit"},
382   {0,APL_NAME".visualBell",APL_CLASS".VisualBell",NULL,"vb",Opt_visualBell,&rs_visualBell,"visual bell"},
383   {0,APL_NAME".borderColor",APL_CLASS".BorderColor","color","bd",0,&rs_color[Color_border],"border color"},
384   {0,APL_NAME".nbTerm",APL_CLASS".NbTerm","number","nt",0,&rs_term_num,"numbers of tab at startup"},
385 #ifdef OFF_FOCUS_FADING
386   {0,APL_NAME".fading",APL_CLASS".Fading","number","fade",0,&rs_fade,"make colors x% darker when aterm is loosing focus"},
387 #endif
388   {0,APL_NAME".color0",APL_CLASS".Color0","color",NULL,0,&rs_color[minCOLOR + 0],NULL},
389   {0,APL_NAME".color1",APL_CLASS".Color1","color",NULL,0,&rs_color[minCOLOR + 1],NULL},
390   {0,APL_NAME".color2",APL_CLASS".Color2","color",NULL,0,&rs_color[minCOLOR + 2],NULL},
391   {0,APL_NAME".color3",APL_CLASS".Color3","color",NULL,0,&rs_color[minCOLOR + 3],NULL},
392   {0,APL_NAME".color4",APL_CLASS".Color4","color",NULL,0,&rs_color[minCOLOR + 4],NULL},
393   {0,APL_NAME".color5",APL_CLASS".Color5","color",NULL,0,&rs_color[minCOLOR + 5],NULL},
394   {0,APL_NAME".color6",APL_CLASS".Color6","color",NULL,0,&rs_color[minCOLOR + 6],NULL},
395   {0,APL_NAME".color7",APL_CLASS".Color7","color",NULL,0,&rs_color[minCOLOR + 7],NULL},
396 #ifndef NO_BRIGHTCOLOR
397   {0,APL_NAME".color8",APL_CLASS".Color8","color",NULL,0,&rs_color[minBrightCOLOR + 0],NULL},
398   {0,APL_NAME".color9",APL_CLASS".Color9","color",NULL,0,&rs_color[minBrightCOLOR + 1],NULL},
399   {0,APL_NAME".color10",APL_CLASS".Color10","color",NULL,0,&rs_color[minBrightCOLOR + 2],NULL},
400   {0,APL_NAME".color11",APL_CLASS".Color11","color",NULL,0,&rs_color[minBrightCOLOR + 3],NULL},
401   {0,APL_NAME".color12",APL_CLASS".Color12","color",NULL,0,&rs_color[minBrightCOLOR + 4],NULL},
402   {0,APL_NAME".color13",APL_CLASS".Color13","color",NULL,0,&rs_color[minBrightCOLOR + 5],NULL},
403   {0,APL_NAME".color14",APL_CLASS".Color14","color",NULL,0,&rs_color[minBrightCOLOR + 6],NULL},
404   {0,APL_NAME".color15",APL_CLASS".Color15","color",NULL,0,&rs_color[minBrightCOLOR + 7],NULL},
405 #endif /* NO_BRIGHTCOLOR */
406 #ifndef NO_BOLDUNDERLINE
407   {0,APL_NAME".colorBD",APL_CLASS".ColorBD","color",NULL,0,&rs_color[Color_BD],NULL},
408   {0,APL_NAME".colorUL",APL_CLASS".ColorUL","color",NULL,0,&rs_color[Color_UL],NULL},
409 #endif /* NO_BOLDUNDERLINE */
410 #ifdef KEEP_SCROLLCOLOR
411   {0,APL_NAME".scrollcolor",APL_CLASS".ScrollColor","color",NULL,0,&rs_color[Color_scroll],NULL},
412   {0,APL_NAME".troughcolor",APL_CLASS".TroughColor","color",NULL,0,&rs_color[Color_trough],NULL},
413 #endif /* KEEP_SCROLLCOLOR */
414 #if defined (BACKGROUND_IMAGE) || (MENUBAR_MAX)
415   {0,APL_NAME".path",APL_CLASS".Path","directory",NULL,0,&rs_path,"search path for pixmaps"},
416 #endif /* defined (BACKGROUND_IMAGE) || (MENUBAR_MAX) */
417   {0,APL_NAME".fontName",APL_CLASS".FontName","font","font",0,&rs_font[0],"normal text font"},
418 #ifndef NO_BOLDFONT
419   {0,APL_NAME".boldFont",APL_CLASS".BoldFont","font","fb",0,&rs_boldFont,"bold text font"},
420 #endif
421 #if NFONTS > 1
422   {0,APL_NAME".font1",APL_CLASS".Font1","font",NULL,0,&rs_font[1],NULL},
423 #endif
424 #if NFONTS > 2
425   {0,APL_NAME".font2",APL_CLASS".Font2","font",NULL,0,&rs_font[2],NULL},
426 #endif
427 #if NFONTS > 3
428   {0,APL_NAME".font3",APL_CLASS".Font3","font",NULL,0,&rs_font[3],NULL},
429 #endif
430 #if NFONTS > 4
431   {0,APL_NAME".font4",APL_CLASS".Font4","font",NULL,0,&rs_font[4],NULL},
432 #endif
433 #if NFONTS > 5
434   {0,APL_NAME".font5",APL_CLASS".Font5","font",NULL,0,&rs_font[5],NULL},
435 #endif
436 #if NFONTS > 6
437   {0,APL_NAME".font6",APL_CLASS".Font6","font",NULL,0,&rs_font[6],NULL},
438 #endif
439 #if NFONTS > 7
440   {0,APL_NAME".font7",APL_CLASS".Font7","font",NULL,0,&rs_font[7],NULL},
441 #endif
442 #ifdef MULTICHAR_SET
443   {0,APL_NAME".mfont",APL_CLASS".MFont","font",NULL,0,&rs_mfont[0],NULL},
444 # if NFONTS > 1
445   {0,APL_NAME".mfont1",APL_CLASS".MFont1","font",NULL,0,&rs_mfont[1],NULL},
446 # endif
447 # if NFONTS > 2
448   {0,APL_NAME".mfont2",APL_CLASS".MFont2","font",NULL,0,&rs_mfont[2],NULL},
449 # endif
450 # if NFONTS > 3
451   {0,APL_NAME".mfont3",APL_CLASS".MFont3","font",NULL,0,&rs_mfont[3],NULL},
452 # endif
453 # if NFONTS > 4
454   {0,APL_NAME".mfont4",APL_CLASS".MFont4","font",NULL,0,&rs_mfont[4],NULL},
455 # endif
456 # if NFONTS > 5
457   {0,APL_NAME".mfont5",APL_CLASS".MFont5","font",NULL,0,&rs_mfont[5],NULL},
458 # endif
459 # if NFONTS > 6
460   {0,APL_NAME".mfont6",APL_CLASS".MFont6","font",NULL,0,&rs_mfont[6],NULL},
461 # endif
462 # if NFONTS > 7
463   {0,APL_NAME".mfont7",APL_CLASS".MFont7","font",NULL,0,&rs_mfont[7],NULL},
464 # endif
465 #endif /* MULTICHAR_SET */
466   {0,APL_NAME".pointerColor",APL_CLASS".PointerColor",NULL,NULL,0,&rs_color[Color_pointer],NULL},
467 #ifndef NO_CURSORCOLOR
468   {0,APL_NAME".cursorColor",APL_CLASS".CursorColor","color",NULL,0,&rs_color[Color_cursor],NULL},
469   {0,APL_NAME".cursorColor2",APL_CLASS".CursorColor2","color",NULL,0,&rs_color[Color_cursor2],NULL},
470 #endif /* NO_CURSORCOLOR */
471 #if defined (HOTKEY_CTRL) || defined (HOTKEY_META)
472   {0,APL_NAME".bigfont_key",APL_CLASS".Bigfont_key","font",NULL,0,&rs_bigfont_key,NULL},
473   {0,APL_NAME".smallfont_key",APL_CLASS".Smallfont_key","font",NULL,0,&rs_smallfont_key,NULL},
474 #endif
475 #ifdef CUTCHAR_RESOURCE
476   {0,APL_NAME".cutchars",APL_CLASS".Cutchars","string",NULL,0,&rs_cutchars,NULL},
477 #endif /* CUTCHAR_RESOURCE */
478 #ifdef META8_OPTION
479   {0,APL_NAME".meta8",APL_CLASS".Meta8",NULL,NULL,0,&rs_meta8,NULL},
480   {0,APL_NAME".modifier",APL_CLASS".Modifier",NULL,NULL,0,&rs_modifier,NULL},
481 #endif
482 #ifndef NO_BACKSPACE_KEY
483   {0,APL_NAME".backspacekey",APL_CLASS".Backspacekey",NULL,NULL,0,&rs_backspace_key,NULL},
484 #endif
485 #ifndef NO_DELETE_KEY
486   {0,APL_NAME".deletekey",APL_CLASS".Deletekey",NULL,NULL,0,&rs_delete_key,NULL},
487 #endif
488 #ifndef NO_MAPALERT
489 # ifdef MAPALERT_OPTION
490   {0,APL_NAME".mapAlert",APL_CLASS".MapAlert",NULL,NULL,Opt_mapAlert,&rs_mapAlert,NULL},
491 # endif
492 #endif
493 #ifdef MULTICHAR_SET
494   {0,APL_NAME".multichar_encoding",APL_CLASS".Multichar_encoding","eucj|sjis|big5","km",0,&rs_multichar_encoding,NULL},
495 #endif /* MULTICHAR_SET */
496 #ifdef GREEK_SUPPORT
497   {0,APL_NAME".greek_keyboard",APL_CLASS".Greek_keyboard","iso | ibm","grk",0,&rs_greek_keyboard,NULL},
498 #endif
499 #ifdef PRINTPIPE
500   {0,APL_NAME".Print-pipe",APL_CLASS".print-pipe",NULL,"string",0,&rs_print_pipe,NULL},
501 #endif
502   {0,NULL,NULL,"file","cf",0,&rs_config_file,"resource configuration file"},
503   {0,NULL,NULL,NULL,"C",Opt_console,&rs_console,"intercept console messages"}
504 };
505 
506 /* for debug purpose only !
507  */
508 #if DEBUG_XRSCR_ALEXIS
509 
display_options()510 void display_options() {
511   int i,l;
512 
513   fprintf(stderr,"Display option:\n");
514   l = sizeof(resources_list) / sizeof(struct s_resources_list);
515   for(i=0; i < l; i++) {
516     if( resources_list[i].option ) {
517       printf("%s",resources_list[i].option);
518       if( resources_list[i].multiple ) {
519         printf(": %s",resources_list[i].data_ptr ? resources_list[i].data_ptr[0] : "");
520       } else {
521         printf(": %s",resources_list[i].data_ptr ? *(resources_list[i].data_ptr) : "");
522       }
523       printf("\n");
524     }
525   }
526 }
527 
528 #endif
529 
530 /* my usage function
531  */
howto_use(int type)532 static void howto_use(int type) {
533   int i,l;
534 
535 	fprintf (stderr, "\nUsage v%s :", VERSION);
536 	list_options ();
537 	fprintf (stderr, "\n%s", APL_NAME);
538 
539   l = sizeof(resources_list) / sizeof(struct s_resources_list);
540   switch (type) {
541     case 0 : /* brief listing */
542       for(i=0; i < l; i++) {
543         if( resources_list[i].option ) {
544           fprintf(stderr," [-");
545           if( resources_list[i].flag) {
546             fprintf(stderr,"/+");
547           }
548           fprintf(stderr,"%s]",resources_list[i].option);
549         }
550       }
551       fprintf(stderr,"\n");
552       break;
553     case 1 : /* long listening */
554       fprintf(stderr," [options]\nwhere options might be :\n");
555       for(i=0; i < l; i++) {
556         int t,u;
557         if( resources_list[i].option ) {
558           t = strlen(resources_list[i].option);
559           fprintf(stderr,"-");
560           if( resources_list[i].flag) {
561             fprintf(stderr,"/+");
562           }
563           fprintf(stderr,"%s",resources_list[i].option);
564           u=1;
565           if( resources_list[i].kw ) {
566             fprintf(stderr," %s",resources_list[i].kw);
567             u=strlen(resources_list[i].kw);
568 
569           }
570           fprintf(stderr,"%-*s",25-u-t," ");
571           if( resources_list[i].help ) {
572             fprintf(stderr," %s",resources_list[i].help);
573           }
574           fprintf(stderr,"\n");
575         }
576       }
577       break;
578     case 2 : /* resources listening */
579       fprintf(stderr,"\nwhere resources might be :\n");
580       for(i=0; i < l; i++) {
581         if( resources_list[i].class ) {
582           fprintf(stderr,"%-30s",resources_list[i].class);
583           if( resources_list[i].help ) {
584             fprintf(stderr," %50s",resources_list[i].help);
585           }
586           fprintf(stderr,"\n");
587         }
588       }
589       break;
590   }
591   fprintf(stderr,"\n");
592   exit(EXIT_FAILURE);
593 }
594 
595 
display_resources()596 void display_resources() {
597 
598 }
599 
XrmValueToString(XrmValue * value,char ** string)600 void XrmValueToString(XrmValue *value,char **string) {
601   *string = (char *) malloc(sizeof(char)*(value->size+1));
602   memcpy(*string,value->addr,value->size + 1);
603   (*string)[value->size] = 0;
604 }
605 
load_resources_from_db(XrmDatabase db)606 void load_resources_from_db(XrmDatabase db) {
607   XrmValue value;
608   char resource[100];
609   char *type,*val;
610   int i,j,l;
611 
612   l = sizeof(resources_list) / sizeof(struct s_resources_list);
613   for(i=0; i < l; i++) {
614     if( resources_list[i].multiple ) {
615       for(j=0; j < MAX_PAGES; j++) {
616         if( resources_list[i].resource && !resources_list[i].data_ptr[j]) {
617           sprintf(resource,resources_list[i].resource,j);
618           if( XrmGetResource(db,resource,resources_list[i].class,&type,&value) ) {
619             XrmValueToString(&value,&val);
620             resources_list[i].data_ptr[j] = val;
621           }
622         }
623       }
624     } else {
625       if( resources_list[i].resource && !*(resources_list[i].data_ptr) && XrmGetResource(db,resources_list[i].resource,resources_list[i].class,&type,&value) ) {
626         XrmValueToString(&value,&val);
627 //        printf("%s : %s\n",resource,val);
628         *(resources_list[i].data_ptr) = val;
629         if( resources_list[i].flag ) {
630           if( ! strcasecmp(*(resources_list[i].data_ptr),"True") ) {
631             Options |= resources_list[i].flag;
632           } else {
633             Options &= ~(resources_list[i].flag);
634           }
635         }
636       }
637     }
638   }
639 
640 }
641 
642 
get_resources()643 void get_resources() {
644   XrmDatabase db=NULL,tmp_db;
645   char *home;
646   char *home_Xdefaults=NULL;
647   char *home_Xresources=NULL;
648 
649   /* init files */
650   if ((home = getenv ("HOME")) != NULL) {
651 
652     int len_home = strlen(home);
653     home_Xdefaults = malloc(sizeof(char)*(len_home+12)); /* 12 = strlen("/.Xdefaults")+1 */
654     home_Xresources = malloc(sizeof(char)*(len_home+13)); /* 13 = strlen("/.Xresources")+1 */
655 
656     strcpy(home_Xdefaults,home);
657     strncpy(home_Xdefaults+len_home,"/.Xdefaults",11);
658     home_Xdefaults[len_home+11] = 0;
659 
660     strcpy(home_Xresources,home);
661     strncpy(home_Xresources+len_home,"/.Xresources",12);
662     home_Xresources[len_home+12] = 0;
663 
664   }
665 
666   XrmInitialize();
667   if( rs_config_file ) {
668     db = XrmGetFileDatabase(rs_config_file);
669     if( ! db ) {
670       print_error("Cannot open %s",rs_config_file);
671     }
672   }
673   tmp_db = XrmGetFileDatabase(home_Xdefaults);
674   if( !tmp_db ) {
675     /* cannot read ~/.Xdefaults
676      * so try ~/.Xresources
677      */
678     tmp_db = XrmGetFileDatabase(home_Xresources);
679   }
680   free(home_Xdefaults);
681   free(home_Xresources);
682 
683   if( tmp_db ) {
684     XrmCombineDatabase(tmp_db,&db,False);
685     //XrmDestroyDatabase(tmp_db);
686   }
687 #ifdef XAPPLOADDIR
688   tmp_db = XrmGetFileDatabase(XAPPLOADDIR "/" APL_CLASS);
689   if( tmp_db) {
690     XrmCombineDatabase(tmp_db,&db,False);
691     //XrmDestroyDatabase(tmp_db);
692   }
693 #endif
694   if( !db ) {
695     /* we'll use defaults values since no resource
696      * file were found
697      */
698     return;
699   }
700 
701   /* start of resources reading */
702   load_resources_from_db(db);
703   //XrmDestroyDatabase(db);
704 
705 /*
706  * even without resources, at least do this setup for command-line
707  * options and command-line long options
708  */
709 #ifdef MULTICHAR_SET
710 	set_multichar_encoding (rs_multichar_encoding);
711 #endif
712 #ifdef GREEK_SUPPORT
713 /* this could be a function in grkelot.c */
714 /* void set_greek_keyboard (const char * str); */
715 	if (rs_greek_keyboard)
716 	{
717 		if (!strcmp (rs_greek_keyboard, "iso"))
718 			greek_setmode (GREEK_ELOT928);	/* former -grk9 */
719 		else if (!strcmp (rs_greek_keyboard, "ibm"))
720 			greek_setmode (GREEK_IBM437);	/* former -grk4 */
721 	}
722 #endif /* GREEK_SUPPORT */
723 
724 #define to_keysym(pks,str) do { KeySym sym;\
725 if (str && ((sym = XStringToKeysym(str)) != 0)) *pks = sym; } while (0)
726 
727 #if defined (HOTKEY_CTRL) || defined (HOTKEY_META)
728 	to_keysym (&ks_bigfont, rs_bigfont_key);
729 	to_keysym (&ks_smallfont, rs_smallfont_key);
730 #endif
731 #undef to_keysym
732 }
733 
734 
735 /* load resources from XRM, .Xdefaults and .Xresources
736  *
737  */
load_resources()738 void load_resources() {
739 }
740 
put_resources()741 void put_resources() {
742 }
743 
744 /* my parse command-line function
745  */
parse_command_line(int argc,char * argv[])746 void parse_command_line(int argc, char *argv[]) {
747   int i,j,k;
748   int l;
749 
750   l = sizeof(resources_list) / sizeof(struct s_resources_list);
751   DXR_ALEXIS(2,(stderr,"Command line options :\n"));
752   for(i=1; i < argc; i++) {
753     char *opt=argv[i];
754     int long_opt=0;
755     int opt_on=1;
756 
757     DXR_ALEXIS(2,(stderr,"option: %s\n",argv[i]));
758     if( *opt == '-') {
759       if(*++opt == '-') {
760         long_opt=1;
761         opt++;
762       }
763     } else if( *opt++ == '+' ) {
764       opt_on=0;
765     } else {
766       print_error("Bad option %s\n",argv[i]);
767       howto_use(0);
768     }
769     if( ! strcmp(opt,"help") ) {
770       howto_use (long_opt ? 2 : 1);
771     }
772     if( ! strcmp(opt,"h") ) {
773       howto_use(0);
774     }
775     if( ! strcmp(opt,"version") ) {
776       version (long_opt ? 2 : 1);
777     }
778     if( ! strcmp(opt,"V") ) {
779       version(0);
780     }
781 
782     for(j=0; j < l; j++) {
783       if( resources_list[j].option && !strcmp(opt,resources_list[j].option) ) {
784         break;
785       }
786     }
787     if( j < l) {
788       DXR_ALEXIS(2,(stderr,"opt : %s",opt));
789       if( resources_list[j].flag ) {
790 
791         /* this is a flag */
792         DXR_ALEXIS(2,(stderr,"(switch) "));
793         if( resources_list[j].multiple ) {
794           for(k=0; k < MAX_PAGES; k++) {
795             resources_list[j].data_ptr[k] = malloc(sizeof(char)*2);
796             sprintf(resources_list[j].data_ptr[k],"%c",(opt_on ? 1 : 0));
797           }
798         } else {
799           if( opt_on ) {
800             Options |= resources_list[j].flag;
801             *(resources_list[j].data_ptr) = "True";
802 
803           } else {
804             Options &= ~(resources_list[j].flag);
805             *(resources_list[j].data_ptr) = "False";
806           }
807         }
808 
809       } else {
810         /* argv[i+1] should be an option */
811         if( i+1 < argc) {
812           if( ! resources_list[j].multiple ) {
813             *(resources_list[j].data_ptr) = strdup(argv[++i]);
814             DXR_ALEXIS(2,(stderr,": %s",*(resources_list[j].data_ptr)));
815           } else {
816             for(k=0; k < MAX_PAGES; k++) {
817               resources_list[j].data_ptr[k] = strdup(argv[i+1]); /* points to argv -> do not free it */
818             }
819             i++;
820           }
821         } else {
822           print_error("Missing argument for %s\n",opt);
823           usage(0);
824         }
825       }
826       DXR_ALEXIS(2,(stderr,"\n"));
827     }
828 #ifdef KEYSYM_RESOURCE
829 		else if (Str_match (opt, "keysym.")) {
830 			char *str = argv[++i];
831 
832 			/*
833 			 * '7' is strlen("keysym.")
834 			 */
835 			if (str != NULL)
836 				parse_keysym (opt + 7, str);
837 		}
838 #endif
839     else {
840       print_error("Unknown option %s\n",opt);
841       howto_use(0);
842     }
843   }
844 //  display_options();
845 }
846 
set_vt_resources()847 void set_vt_resources() {
848   int i;
849 
850   for(i=0; i < MAX_PAGES; i++) {
851     if( titles[i] ) {
852       TermWin.vts[i].tab_title = titles[i];
853     } else {
854       TermWin.vts[i].tab_title = strdup(rs_default_tab_title); /* this is the default value */
855     }
856     if( save_lines[i] ) {
857       TermWin.vts[i].saveLines = atoi(save_lines[i]);
858       free(save_lines[i]);
859     } else {
860       TermWin.vts[i].saveLines = SAVELINES; /* this is the default value */
861     }
862     TermWin.vts[i].min_bcol = 1;  /* this is the default value */
863   }
864 }
865 
866 #if defined(BACKGROUND_IMAGE) || defined(TRANSPARENT)
set_background()867 void set_background() {
868   int i;
869 
870   for(i=0; i < MAX_PAGES; i++) {
871     if( shadings[i] ) {
872       TermWin.vts[i].bg.Shading.shading = atoi(shadings[i]);
873       free(shadings[i]);
874     }
875     if( tintings[i] ) {
876       TermWin.vts[i].bg.color = tintings[i];
877     }
878     if( transparencies[i] ) {
879       TermWin.vts[i].bg.transparent =
880         (transparencies[i][0] == '1' || !strcasecmp("true",transparencies[i]) )? Opt_transparent : ~Opt_transparent;
881     }
882     if( tint_types[i] ) {
883       // to do ...
884       //TermWin.vts[i].bg.trgType = ParseGCType(tint_types[i],GXand);
885     }
886 
887     TermWin.vts[i].bg.trgType = BGT_Tile;
888 
889 #ifdef TRANSPARENT
890       if ((Options & Opt_transparent) && (!bg_types[i] || !strcasecmp("None",bg_types[i])) ) {
891   //if( (Options & TermWin.vts[0].bg.transparent) && !type) {
892         if (TermWin.vts[i].bg.Shading.shading != 100) {
893           TermWin.vts[i].bg.trgType = BGT_Cut;
894         }	else {
895           TermWin.vts[i].bg.trgType = BGT_None;
896         }
897       }
898 #endif
899     if( bg_types[i] ) {
900       if (strcmp(bg_types[i], BGT_CENTER) == 0)
901         TermWin.vts[i].bg.trgType = BGT_Center;
902       else if (strcmp(bg_types[i], BGT_SCALE) == 0)
903         TermWin.vts[i].bg.trgType = BGT_Scale;
904       else if (strcmp(bg_types[i], BGT_SCALEH) == 0)
905         TermWin.vts[i].bg.trgType = BGT_ScaleH;
906       else if (strcmp(bg_types[i], BGT_SCALEV) == 0)
907         TermWin.vts[i].bg.trgType = BGT_ScaleV;
908       else if (strcmp(bg_types[i], BGT_NO_TILE) == 0)
909         TermWin.vts[i].bg.trgType = BGT_NoTile;
910       else if (strcmp(bg_types[i], BGT_NO_TILE_H) == 0)
911         TermWin.vts[i].bg.trgType = BGT_NoTileH;
912       else if (strcmp(bg_types[i], BGT_NO_TILE_V) == 0)
913         TermWin.vts[i].bg.trgType = BGT_NoTileV;
914       else if (strcmp(bg_types[i], BGT_CUT) == 0)
915         TermWin.vts[i].bg.trgType = BGT_Cut;
916     }
917     if( pixmaps[i] ) {
918       TermWin.vts[i].bg.pixmap_file = pixmaps[i];
919     }
920   }
921 }
922 #endif
923 
924 extern const char *def_colorName[];
925 
926 /* list_options
927  */
list_options()928 void list_options ()
929 {
930 #define INDENT 30
931 	fprintf (stderr, "(");
932 #ifdef BACKGROUND_IMAGE
933 	fprintf (stderr, "background image,");
934 #endif
935 #ifdef HAVE_LIBXPM
936 	fprintf (stderr, "XPM,");
937 #endif
938 #ifdef USE_LIBASIMAGE
939 #ifdef JPEG
940 	fprintf (stderr, "JPEG,");
941 #endif
942 #ifdef PNG
943 	fprintf (stderr, "PNG,");
944 #endif
945 	fprintf (stderr, "AfterStep integration,");
946 #ifdef _MYSTYLE_
947 	fprintf (stderr, "AfterStep MyStyles,");
948 #else
949 	fprintf (stderr, "no AfterStep MyStyles,");
950 #endif
951 #endif
952 #ifdef UTMP_SUPPORT
953 	fprintf (stderr, "utmp,");
954 #endif
955 #ifdef MENUBAR
956 	fprintf (stderr, "menubar,");
957 #endif
958 #ifdef KANJI
959 	fprintf (stderr, "Kanji,");
960 #endif
961 #ifdef ZH
962 	fprintf (stderr, "Chinese,");
963 #endif
964 #ifdef THAI
965 	fprintf (stderr, "Thai,");
966 #endif
967 #ifdef XTERM_SCROLLBAR
968 	fprintf (stderr, "XTerm-scrollbar,");
969 #endif
970 #ifdef GREEK_SUPPORT
971 	fprintf (stderr, "Greek,");
972 #endif
973 #ifdef NO_BACKSPACE_KEY
974 	fprintf (stderr, "no backspace,");
975 #endif
976 #ifdef NO_DELETE_KEY
977 	fprintf (stderr, "no delete,");
978 #endif
979 #ifdef TRANSPARENT
980 	fprintf (stderr, "transparency,");
981 #else
982 	fprintf (stderr, "no transparency,");
983 # endif
984 #ifdef OFF_FOCUS_FADING
985 	fprintf (stderr, "fading,");
986 #else
987 	fprintf (stderr, "no fading,");
988 # endif
989 #ifdef NEXT_SCROLLBAR
990 	fprintf (stderr, "NeXT scrollbar,");
991 # endif
992 #ifdef NO_RESOURCES
993 	fprintf (stderr, "NoResources");
994 #else
995 # ifdef USE_XGETDEFAULT
996 	fprintf (stderr, "XGetDefaults");
997 # else
998 	fprintf (stderr, ".Xdefaults");
999 # endif
1000 #endif
1001 
1002 	fprintf (stderr, ")");
1003 
1004 }
1005 
1006 /* version
1007  */
version(int type)1008 void version (int type) {
1009 	switch (type)
1010 	{
1011 	case 0:		/* brief listing */
1012 		fprintf (stderr, "%s version %s\n", APL_NAME, VERSION);
1013 		break;
1014 	case 1:		/* full command-line listing */
1015 		fprintf (stderr, "%s version %s from %s\n", APL_NAME, VERSION,DATE);
1016 		list_options ();
1017 		fprintf (stderr, "\n");
1018 		break;
1019 	case 2:		/* full resource listing */
1020 		fprintf (stderr, "%s\n", VERSION);
1021 		break;
1022 	}
1023 	exit (EXIT_FAILURE);
1024 }
1025 
1026 /* usage
1027  */
usage(int type)1028 void usage (int type) {
1029 	int i, col;
1030 
1031 	fprintf (stderr, "\nUsage v%s :", VERSION);
1032 	list_options ();
1033 	fprintf (stderr, "\n%s", APL_NAME);
1034 
1035 	switch (type)
1036 	{
1037 	case 0:		/* brief listing */
1038 		fprintf (stderr, " [-help][-V]\n");
1039 		col = 3;
1040 		for (i = 0; i < optList_size (); i++)
1041 		{
1042 			if (optList[i].desc != NULL)
1043 			{
1044 				int len = 2;
1045 
1046 				if (!optList_isBool (i))
1047 				{
1048 					len = optList_strlen (i);
1049 					if (len > 0)
1050 						len++;	/* account for space */
1051 				}
1052 
1053 				len += 4 + strlen (optList[i].opt);
1054 
1055 				col += len;
1056 				if (col > 79)
1057 				{	/* assume regular width */
1058 					fprintf (stderr, "\n");
1059 					col = 3 + len;
1060 				}
1061 				fprintf (stderr, " [-");
1062 				if (optList_isBool (i))
1063 					fprintf (stderr, "/+");
1064 
1065 				fprintf (stderr, "%s", optList[i].opt);
1066 				if (optList_strlen (i))
1067 					fprintf (stderr, " %s]",
1068 						 optList[i].arg);
1069 				else
1070 					fprintf (stderr, "]");
1071 			}
1072 		}
1073 		fprintf (stderr, "\n\n");
1074 		break;
1075 
1076 	case 1:		/* full command-line listing */
1077 		fprintf (stderr,
1078 			 " [options] [-e command args]\n\n"
1079 			 "where options include:\n");
1080 
1081 		for (i = 0; i < optList_size (); i++)
1082 		{
1083 			if (optList[i].desc != NULL)
1084 				fprintf (stderr, "    %s%s %-*s%s%s\n",
1085 					 (optList_isBool (i) ? "-/+" : "-"),
1086 					 optList[i].opt,
1087 					 (INDENT - strlen (optList[i].opt) + (optList_isBool (i) ? 0 : 2)),
1088 					 (optList[i].arg ? optList[i].arg : ""),
1089 					 (optList_isBool (i) ? "turn on/off " : ""), optList[i].desc);
1090 		}
1091 		fprintf (stderr,
1092 			 "\n    --help to list long-options\n    --version for the version information\n\n");
1093 		break;
1094 
1095 	case 2:		/* full resource listing */
1096 		fprintf (stderr,
1097 			 " [options] [-e command args]\n\n"
1098 			 "where resources (long-options) include:\n");
1099 
1100 		for (i = 0; i < optList_size (); i++)
1101 			if (optList[i].kw != NULL)
1102 				fprintf (stderr, "    %s: %*s\n",
1103 					 optList[i].kw,
1104 					 (INDENT - strlen (optList[i].kw)),
1105 					 (optList_isBool (i) ? "boolean" :
1106 					  optList[i].arg));
1107 
1108 #ifdef KEYSYM_RESOURCE
1109 		fprintf (stderr, "    " "keysym.sym" ": %*s\n",
1110 			 (INDENT - strlen ("keysym.sym")), "keysym");
1111 #endif
1112 		fprintf (stderr,
1113 			 "\n    -help to list options\n    -version for the version information with options list\n\n");
1114 		break;
1115 	}
1116 	exit (EXIT_FAILURE);
1117 }
1118 
1119 
1120 /* get command-line options before getting resources
1121  */
get_options(int argc,char * argv[])1122 void get_options (int argc, char *argv[]) {
1123 	int i, bad_option = 0;
1124 	static const char *const On = "ON";
1125 	static const char *const Off = "OFF";
1126 
1127 	for (i = 1; i < argc; i++)
1128 	{
1129 		int entry, longopt = 0;
1130 		const char *flag;
1131 		char *opt = argv[i];
1132 
1133 #ifdef DEBUG_RESOURCES
1134 		fprintf (stderr, "argv[%d] = %s: ", i, argv[i]);
1135 #endif
1136 		if (*opt == '-')
1137 		{
1138 			flag = On;
1139 			if (*++opt == '-')
1140 				longopt = *opt++;	/* long option */
1141 		}
1142 		else if (*opt == '+')
1143 		{
1144 			flag = Off;
1145 			if (*++opt == '+')
1146 				longopt = *opt++;	/* long option */
1147 		}
1148 		else
1149 		{
1150 			bad_option = 1;
1151 			print_error ("bad option \"%s\"", opt);
1152 			continue;
1153 		}
1154 
1155 		if (!strcmp (opt, "help"))
1156 			usage (longopt ? 2 : 1);
1157 		if (!strcmp (opt, "h"))
1158 			usage (0);
1159 		if (!strcmp (opt, "version"))
1160 			version (longopt ? 2 : 1);
1161 		if (!strcmp (opt, "V"))
1162 			version (0);
1163 
1164 		/* feature: always try to match long-options */
1165 		for (entry = 0; entry < optList_size (); entry++)
1166 		{
1167 			if ( (optList[entry].kw && !strcmp (opt, optList[entry].kw)) ||
1168         (!longopt && optList[entry].opt && !strcmp(opt,optList[entry].opt)) )
1169 				break;
1170 		}
1171 
1172 		if (entry < optList_size ())
1173 		{
1174 			if (optList_strlen (entry))
1175 			{	/* string value */
1176 				char *str = argv[++i];
1177 
1178 #ifdef DEBUG_RESOURCES
1179 				fprintf (stderr, "string (%s,%s) = ",
1180 					 optList[entry].opt ? optList[entry].opt : "nil",
1181 					 optList[entry].kw ? optList[entry].kw : "nil");
1182 #endif
1183 				if (flag == On && str && optList[entry].dp)
1184 				{
1185 #ifdef DEBUG_RESOURCES
1186 					fprintf (stderr, "\"%s\"\n", str);
1187 #endif
1188 					*(optList[entry].dp) = str;
1189 
1190 					/* special cases are handled in main.c:main() to allow
1191 					 * X resources to set these values before we settle for
1192 					 * default values
1193 					 */
1194 				}
1195 #ifdef DEBUG_RESOURCES
1196 				else
1197 					fprintf (stderr, "???\n");
1198 #endif
1199 			}
1200 			else
1201 			{	/* boolean value */
1202 #ifdef DEBUG_RESOURCES
1203 				fprintf (stderr, "boolean (%s,%s) = %s\n",
1204 					 optList[entry].opt,
1205 					 optList[entry].kw, flag);
1206 #endif
1207 				if (flag == On)
1208 					Options |= (optList[entry].flag);
1209 				else
1210 					Options &= ~(optList[entry].flag);
1211 
1212 				if (optList[entry].dp)
1213 					*(optList[entry].dp) = flag;
1214 			}
1215 		}
1216 		else
1217 #ifdef KEYSYM_RESOURCE
1218 			/* if (!strncmp (opt, "keysym.", strlen ("keysym."))) */
1219 		if (Str_match (opt, "keysym."))
1220 		{
1221 			char *str = argv[++i];
1222 
1223 			/*
1224 			 * '7' is strlen("keysym.")
1225 			 */
1226 			if (str != NULL)
1227 				parse_keysym (opt + 7, str);
1228 		}
1229 		else
1230 #endif
1231 		{
1232 			/* various old-style options, just ignore
1233 			 * Obsolete since about Jan 96,
1234 			 * so they can probably eventually be removed
1235 			 */
1236 			const char *msg = "bad";
1237 
1238 			if (longopt)
1239 			{
1240 				opt--;
1241 				bad_option = 1;
1242 			}
1243 			else if (!strcmp (opt, "7") || !strcmp (opt, "8")
1244 #ifdef GREEK_SUPPORT
1245 				 /* obsolete 12 May 1996 (v2.17) */
1246 				 || !Str_match (opt, "grk")
1247 #endif
1248 				)
1249 				msg = "obsolete";
1250 			else
1251 				bad_option = 1;
1252 
1253 			print_error ("%s option \"%s\"", msg, --opt);
1254 		}
1255 	}
1256 
1257 	if (bad_option)
1258 		usage (0);
1259 }
1260 
1261 
1262 
1263 #ifndef NO_RESOURCES
1264 /*
1265  * a replacement for strcasecmp() to avoid linking an entire library
1266  */
my_strcasecmp(const char * s1,const char * s2)1267 int my_strcasecmp (const char *s1, const char *s2) {
1268 	for ( /*nil */ ; (*s1 && *s2); s1++, s2++)
1269 	{
1270 		register int c1 = toupper (*s1);
1271 		register int c2 = toupper (*s2);
1272 
1273 		if (c1 != c2)
1274 			return (c1 - c2);
1275 	}
1276 	return (int) (*s1 - *s2);
1277 }
1278 
1279 # ifdef KEYSYM_RESOURCE
1280 
1281 /*
1282  * Define key from XrmEnumerateDatabase.
1283  *   quarks will be something like
1284  *      "rxvt" "keysym" "0xFF01"
1285  *   value will be a string
1286  */
define_key(XrmDatabase * database,XrmBindingList bindings,XrmQuarkList quarks,XrmRepresentation * type,XrmValue * value,XPointer closure)1287 Bool define_key (XrmDatabase * database, XrmBindingList bindings,
1288   XrmQuarkList quarks, XrmRepresentation * type, XrmValue * value, XPointer closure) {
1289 	int last;
1290 
1291 	for (last = 0; quarks[last] != NULLQUARK; last++)	/* look for last quark in list */
1292 		;
1293 	last--;
1294 	parse_keysym (XrmQuarkToString (quarks[last]), (char *) value->addr);
1295 	return False;
1296 }
1297 
1298 /*
1299  * look for something like this (XK_Delete)
1300  * rxvt*keysym.0xFFFF: "\177"
1301  *
1302  * arg will be
1303  *      NULL for ~/.Xdefaults and
1304  *      non-NULL for command-line options (need to allocate)
1305  */
parse_keysym(char * str,char * arg)1306 int parse_keysym (char *str, char *arg) {
1307 	char *key_string;
1308 	int n, sym;
1309 
1310 	if (arg == NULL)
1311 	{
1312 		if ((n = Str_match (str, "keysym.")) == 0)
1313 			return 0;
1314 		str += n;	/* skip `keysym.' */
1315 	}
1316 /* some scanf() have trouble with a 0x prefix */
1317 	if (isdigit (str[0]))
1318 	{
1319 		if (str[0] == '0' && toupper (str[1]) == 'X')
1320 			str += 2;
1321 		if (arg)
1322 		{
1323 			if (sscanf(str, (strchr (str, ':') ? "%x:" : "%x"),&sym) != 1)
1324 				return -1;
1325 		}
1326 		else
1327 		{
1328 			if (sscanf (str, "%x:", &sym) != 1)
1329 				return -1;
1330 
1331 			/* cue to ':', it's there since sscanf() worked */
1332 			str = strchr (str, ':');
1333 			str++;
1334 			arg = Str_trim (str);
1335 			if (arg == NULL)
1336 				return -1;
1337 		}
1338 	}
1339 	else
1340 	{
1341 		/*
1342 		 * convert keysym name to keysym number
1343 		 */
1344 		if (arg == NULL)
1345 		{
1346 			arg = str;
1347 
1348 			arg = strchr (str, ':');
1349 			if (arg == NULL)
1350 				return -1;
1351 
1352 			*arg++ = '\0';
1353 			arg = Str_trim (arg);
1354 			if (arg == NULL)
1355 				return -1;
1356 		}
1357 		sym = XStringToKeysym (str);
1358 
1359 		if (sym == None)
1360 			return -1;
1361 	}
1362 
1363 	if (sym < 0xFF00 || sym > 0xFFFF)	/* we only do extended keys */
1364 		return -1;
1365 	sym -= 0xFF00;
1366 
1367 	if (KeySym_map[sym] != NULL)	/* already set ? */
1368 		return -1;
1369 
1370 	if ((n = strlen (arg)) == 0)
1371 		return -1;
1372 
1373 	key_string = MALLOC ((n + 2) * sizeof (char));
1374 
1375 	STRCPY (key_string + 1, arg);
1376 
1377 	n = Str_escaped (key_string + 1);
1378 	if (n)
1379 	{
1380 		key_string[0] = min (n, 255);
1381 		KeySym_map[sym] = (unsigned char *) key_string;
1382 	}
1383 	else
1384 	{
1385 		FREE (key_string);
1386 		return -1;
1387 	}
1388 
1389 	return 1;
1390 }
1391 # endif	/* KEYSYM_RESOURCE */
1392 
1393 # ifndef USE_XGETDEFAULT
1394 /* get_xdefaults()
1395  *
1396  * the matching algorithm used for memory-save fake resources
1397  */
1398 
1399 void
get_xdefaults(FILE * stream,const char * name)1400 get_xdefaults (FILE * stream, const char *name)
1401 {
1402 	unsigned int len;
1403 	char *str, buffer[256];
1404 
1405 	if (stream == NULL)
1406 		return;
1407 	len = strlen (name);
1408 	while ((str = fgets (buffer, sizeof (buffer), stream)) != NULL)
1409 	{
1410 		unsigned int entry, n;
1411 
1412 		while (*str && isspace (*str))
1413 			str++;	/* leading whitespace */
1414 
1415 		if ((str[len] != '*' && str[len] != '.') || (len && strncmp (str, name, len)))
1416 			continue;
1417 		str += (len + 1);	/* skip `name*' or `name.' */
1418 
1419 # ifdef KEYSYM_RESOURCE
1420 		if (!parse_keysym (str, NULL))
1421 # endif	/* KEYSYM_RESOURCE */
1422 			for (entry = 0; entry < optList_size (); entry++)
1423 			{
1424 				const char *const kw = optList[entry].kw;
1425 
1426 				if (kw == NULL)
1427 					continue;
1428 				n = strlen (kw);
1429 				if (str[n] == ':' && Str_match (str, kw))
1430 				{
1431 					/* skip `keyword:' */
1432 					str += (n + 1);
1433 					str = Str_skip_space (str);
1434 					str = Str_trim (str);
1435 					n = (str ? strlen (str) : 0);
1436 					if (n && *(optList[entry].dp) == NULL)
1437 					{
1438 						/* not already set */
1439 						char *p =	MALLOC ((n +1) *sizeof(char));
1440 						STRCPY (p, str);
1441 						*(optList[entry].dp) = p;
1442 						if (optList_isBool (entry))
1443 						{
1444 							if (!my_strcasecmp(str, "TRUE"))
1445                 Options |= (optList[entry].flag);
1446 							else
1447 								Options &= ~(optList[entry].flag);
1448 						}
1449 					}
1450 					break;
1451 				}
1452 			}
1453 	}
1454 	rewind (stream);
1455 }
1456 
1457 
1458 # endif	/* ! USE_XGETDEFAULT */
1459 
1460 #endif /* NO_RESOURCES */
1461 
1462 /* read the resources files */
1463 /*
1464  * using XGetDefault() or the hand-rolled replacement
1465  */
extract_resources(Display * display,const char * name)1466 void extract_resources (Display * display, const char *name) {
1467 #ifndef NO_RESOURCES
1468 # ifdef USE_XGETDEFAULT
1469 /*
1470  * get resources using the X library function
1471  */
1472 	int entry;
1473 
1474 #ifdef XrmEnumOneLevel
1475 	XrmName name_prefix[3];
1476 	XrmClass class_prefix[3];
1477 	char *displayResource;
1478 	XrmDatabase database;
1479 	char *screenResource;
1480 	XrmDatabase screenDatabase;
1481 
1482 /*
1483  * Get screen-specific resources (X11R5) and merge into common resources.
1484  */
1485 //	DXR_ALEXIS (1, (stderr, "extract_resources\n"));
1486 	database = NULL;
1487 	screenDatabase = NULL;
1488 	displayResource = XResourceManagerString (display);
1489 	if (displayResource != NULL)
1490 		database = XrmGetStringDatabase (displayResource);
1491 	screenResource = XScreenResourceString (DefaultScreenOfDisplay (display));
1492 
1493 	if (screenResource != NULL)
1494 		screenDatabase = XrmGetStringDatabase (screenResource);
1495 
1496 	XrmMergeDatabases (screenDatabase, &database);
1497 	XrmSetDatabase (display, database);
1498 #endif
1499 
1500 	for (entry = 0; entry < optList_size (); entry++)
1501 	{
1502 		char *p;
1503 		const char *kw = optList[entry].kw;
1504 
1505 		if (kw == NULL || *(optList[entry].dp) != NULL)
1506 			continue;	/* previously set */
1507 		if ((p = XGetDefault (display, name, kw)) != NULL ||
1508 		    (p = XGetDefault (display, APL_SUBCLASS, kw)) != NULL ||
1509 		    (p = XGetDefault (display, APL_CLASS, kw)) != NULL)
1510 		{
1511 			*optList[entry].dp = p;
1512 
1513 			if (optList_isBool (entry))
1514 			{
1515 				if (!my_strcasecmp (p, "TRUE"))
1516 					Options |= (optList[entry].flag);
1517 				else
1518 					Options &= ~(optList[entry].flag);
1519 			}
1520 		}
1521 	}
1522 
1523 /*
1524  * [R5 or later]: enumerate the resource database
1525  */
1526 #ifdef XrmEnumOneLevel
1527 #ifdef KEYSYM_RESOURCE
1528 	name_prefix[0] = XrmStringToName (name);
1529 	name_prefix[1] = XrmStringToName ("keysym");
1530 	name_prefix[2] = NULLQUARK;
1531 	class_prefix[0] = XrmStringToName (APL_SUBCLASS);
1532 	class_prefix[1] = XrmStringToName ("Keysym");
1533 	class_prefix[2] = NULLQUARK;
1534 	XrmEnumerateDatabase (XrmGetDatabase (display),
1535     name_prefix,
1536     class_prefix, XrmEnumOneLevel, define_key,
1537     NULL);
1538 	name_prefix[0] = XrmStringToName (APL_CLASS);
1539 	name_prefix[1] = XrmStringToName ("keysym");
1540 	class_prefix[0] = XrmStringToName (APL_CLASS);
1541 	class_prefix[1] = XrmStringToName ("Keysym");
1542 	XrmEnumerateDatabase (XrmGetDatabase (display),
1543 			      name_prefix,
1544 			      class_prefix, XrmEnumOneLevel, define_key,
1545 			      NULL);
1546 #   endif
1547 #  endif
1548 
1549 # else /* USE_XGETDEFAULT */
1550 /* get resources the hard way, but save lots of memory */
1551 	const char *fname[] = { rs_configFile,".Xdefaults", ".Xresources" };
1552 	FILE *fd = NULL;
1553 	char *home;
1554 
1555 	if ((home = getenv ("HOME")) != NULL)
1556 	{
1557 		int i, len = strlen (home) + 2;
1558 		char *f = NULL;
1559 
1560 		for (i = 0; i < (sizeof (fname) / sizeof (fname[0])); i++)
1561 		{
1562       if( !fname[i][0] )
1563         break;
1564 
1565       f = REALLOC (f,(len + strlen (fname[i])) * sizeof (char));
1566 
1567       sprintf (f, "%s/%s", home, fname[i]);
1568 
1569       if ((fd = fopen (f, "r")) != NULL)
1570         break;
1571 		}
1572 		FREE (f);
1573 	}
1574 /*
1575  * The normal order to match resources is the following:
1576  * @ global resources (partial match, ~/.Xdefaults)
1577  * @ application file resources (XAPPLOADDIR/Rxvt)
1578  * @ class resources (~/.Xdefaults)
1579  * @ private resources (~/.Xdefaults)
1580  *
1581  * However, for the hand-rolled resources, the matching algorithm
1582  * checks if a resource string value has already been allocated
1583  * and won't overwrite it with (in this case) a less specific
1584  * resource value.
1585  *
1586  * This avoids multiple allocation.  Also, when we've called this
1587  * routine command-line string options have already been applied so we
1588  * needn't to allocate for those resources.
1589  *
1590  * So, search in resources from most to least specific.
1591  *
1592  * Also, use a special sub-class so that we can use either or both of
1593  * "XTerm" and "Rxvt" as class names.
1594  */
1595 
1596 	get_xdefaults (fd, name);
1597 	get_xdefaults (fd, APL_SUBCLASS);
1598 
1599 #  ifdef XAPPLOADDIR
1600 	{
1601 		FILE *ad = fopen (XAPPLOADDIR "/" APL_SUBCLASS, "r");
1602 
1603 		if (ad != NULL)
1604 		{
1605 			get_xdefaults (ad, "");
1606 			fclose (ad);
1607 		}
1608 	}
1609 #  endif /* XAPPLOADDIR */
1610 
1611 	get_xdefaults (fd, APL_CLASS);
1612 	get_xdefaults (fd, "");	/* partial match */
1613 	if (fd != NULL)
1614 		fclose (fd);
1615 
1616 # endif	/* USE_XGETDEFAULT */
1617 #endif /* NO_RESOURCES */
1618 
1619 /*
1620  * even without resources, at least do this setup for command-line
1621  * options and command-line long options
1622  */
1623 #ifdef MULTICHAR_SET
1624 	set_multichar_encoding (rs_multichar_encoding);
1625 #endif
1626 #ifdef GREEK_SUPPORT
1627 /* this could be a function in grkelot.c */
1628 /* void set_greek_keyboard (const char * str); */
1629 	if (rs_greek_keyboard)
1630 	{
1631 		if (!strcmp (rs_greek_keyboard, "iso"))
1632 			greek_setmode (GREEK_ELOT928);	/* former -grk9 */
1633 		else if (!strcmp (rs_greek_keyboard, "ibm"))
1634 			greek_setmode (GREEK_IBM437);	/* former -grk4 */
1635 	}
1636 #endif /* GREEK_SUPPORT */
1637 
1638 #define to_keysym(pks,str) do { KeySym sym;\
1639 if (str && ((sym = XStringToKeysym(str)) != 0)) *pks = sym; } while (0)
1640 
1641 #if defined (HOTKEY_CTRL) || defined (HOTKEY_META)
1642 	to_keysym (&ks_bigfont, rs_bigfont_key);
1643 	to_keysym (&ks_smallfont, rs_smallfont_key);
1644 #endif
1645 #undef to_keysym
1646 }
1647