1 /* $Header: /home/yav/catty/fkiss/RCS/selcnf.c,v 1.26 2000/09/28 07:53:44 yav Exp $
2  * fkiss config selecter
3  * written by yav <yav@bigfoot.com>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */
19 
20 #include <X11/Xos.h>
21 #include <X11/Xlib.h>
22 #include <X11/Xutil.h>
23 #include <stdio.h>
24 #include "config.h"
25 #include "headers.h"
26 #include "fkiss.h"
27 #include "work.h"
28 #define PUBLIC_SELCNF_C
29 #include "extern.h"
30 
31 #if HAVE_SYS_STAT_H
32 # include <sys/stat.h>
33 #else
34 # if HAVE_STAT_H
35 #  include <stat.h>
36 # endif
37 #endif
38 
39 #define BASE_MARGIN 2
40 #define BASE_TOP_MARGIN		BASE_MARGIN
41 #define BASE_BOTTOM_MARGIN	BASE_MARGIN
42 #define BASE_LEFT_MARGIN	BASE_MARGIN
43 #define BASE_RIGHT_MARGIN	BASE_MARGIN
44 
45 #define MENU_TOP_MARGIN		2
46 #define MENU_BOTTOM_MARGIN	3
47 #define MENU_LEFT_MARGIN	4
48 #define MENU_RIGHT_MARGIN	4
49 
50 char id_selcnf[] = "$Id: selcnf.c,v 1.26 2000/09/28 07:53:44 yav Exp $";
51 static Window selwin;
52 static int menuw = 128;
53 static int menuh = MENU_TOP_MARGIN+11+2+MENU_BOTTOM_MARGIN;
54 static char **conflist = NULL;
55 static char *str_cancel = "(Cancel)";
56 static MW *mwsel;
57 static char default_cnf_suffix[] = ".cnf";
58 static char current_dir[] = ".";
59 
is_regular_file(str)60 int is_regular_file(str)
61      char *str;
62 {
63   struct stat st;
64 
65   return stat(str, &st) == 0 && (st.st_mode & S_IFMT) == S_IFREG;
66 }
67 
match_cnf(char * p)68 int match_cnf(char *p)
69 {
70   return is_suffix(p, default_cnf_suffix);
71 }
72 
find_cnf_file(path)73 char **find_cnf_file(path)
74      char *path;
75 {
76   debug_printf("find_cnf_file ``%s''\n", path);
77   return dir_ls(path, match_cnf);
78 }
79 
set_menu_font(list)80 void set_menu_font(list)
81      char **list;		/* menu string list */
82 {
83   int i, maxwidth;
84 
85   if (fsp == NULL)
86     return;
87   maxwidth = calc_text_size(str_cancel);
88   for (; *list != NULL; list++) {
89     i = calc_text_size(*list);
90     if (i > maxwidth)
91       maxwidth = i;
92   }
93   menuh = MENU_TOP_MARGIN + font_ascent + font_descent + MENU_BOTTOM_MARGIN;
94   menuw = MENU_LEFT_MARGIN + maxwidth + MENU_RIGHT_MARGIN;
95   debug_printf("font: %s\nfont ascent %d, descent %d\n",
96 	       str_font, font_ascent, font_descent);
97 }
98 
which_menuwin(win)99 int which_menuwin(win)
100      Window win;
101 {
102   return which_winlist(win, mwsel);
103 }
104 
set_menu_status(n,mode)105 void set_menu_status(n, mode)
106      int n;
107      int mode;
108 {
109   change_menu_status((mwsel+n)->win, (mwsel+n)->st = mode);
110 }
111 
select_menu(title,geomstr,mlist)112 int select_menu(title, geomstr, mlist)
113      char *title;		/* window title */
114      char *geomstr;		/* window geometry string */
115      char **mlist;		/* menu string list */
116 {
117   int i, r;
118   int menucnt;
119   int x, y, w, h, f;
120   XSizeHints hint;
121   XEvent ev;
122   Bool fin;
123   unsigned long atrmask;
124   XSetWindowAttributes atr;
125 
126   set_menu_font(mlist);
127   for (menucnt = 0; *(mlist+menucnt) != NULL; menucnt++)
128     ;
129   menucnt++;				/* append "Cancel" menu */
130   hint.flags = PSize;
131   x = y = 0;
132   atr.save_under = True;
133   atrmask = CWSaveUnder;
134   if (geomstr != NULL && geomstr[0]) {
135     /* window geometry is specified */
136     f = XGeometry(dsp, scr, geomstr, "", 1, 1, 1, 0, 0, &x, &y, &w, &h);
137     if (f & XValue)
138       hint.flags |= USPosition;
139     if (f & YValue)
140       hint.flags |= USPosition;
141     atr.override_redirect = True;
142     atrmask |= CWOverrideRedirect;
143   }
144 
145   w = menuw+BASE_LEFT_MARGIN+BASE_RIGHT_MARGIN;
146   h = menuh*menucnt+BASE_TOP_MARGIN+BASE_BOTTOM_MARGIN;
147   hint.x = x;
148   hint.y = y;
149   hint.width = w;
150   hint.height = h;
151   selwin = XCreateSimpleWindow(dsp, rootwin, x, y, w, h,
152 			       1, spx[SPX_FG], spx[SPX_BG]);
153   XSetStandardProperties(dsp, selwin, title, title, 0,
154 			 oargv, oargc, &hint);
155   XSelectInput(dsp, selwin, ExposureMask);
156   XChangeWindowAttributes(dsp, selwin, atrmask, &atr);
157 
158   mwsel = alloc_mw(menucnt);
159   for (i = 0; i < menucnt; i++) {
160     (mwsel+i)->win =
161       XCreateSimpleWindow(dsp, selwin,
162 			  BASE_LEFT_MARGIN, BASE_TOP_MARGIN+i*menuh,
163 			  menuw, menuh,
164 			  0, spx[SPX_FG], spx[SPX_BT]);
165     XSelectInput(dsp, (mwsel+i)->win, ExposureMask|
166 		 ButtonPressMask|ButtonReleaseMask|OwnerGrabButtonMask|
167 		 EnterWindowMask|LeaveWindowMask);
168   }
169   cursor_set(selwin, 3);	/* 3: CUR_ARROW */
170   XMapRaised(dsp, selwin);
171   XMapSubwindows(dsp, selwin);
172   r = -1;
173   fin = False;
174   while (!fin) {
175     XNextEvent(dsp, &ev);
176     switch(ev.type) {
177     case Expose:
178       if (!ev.xexpose.count) {
179 	i = which_menuwin(ev.xexpose.window);
180 	if (i >= 0) {
181 	  draw_menu_string((mwsel+i)->win, (mwsel+i)->st, menuw, menuh,
182 			   MENU_LEFT_MARGIN, MENU_TOP_MARGIN,
183 			   (i == menucnt-1)?str_cancel:*(mlist+i));
184 #if 0
185 	  if ((mwsel+i)->st & 2)
186 	    fin = True;
187 #endif
188 	}
189       }
190       break;
191     case EnterNotify:
192     case LeaveNotify:
193       i = which_menuwin(ev.xcrossing.window);
194       if (i >= 0)
195 	set_menu_status(i, (ev.type == EnterNotify));
196       break;
197       /* case ButtonPress: */
198     case ButtonRelease:
199       i = (ev.xbutton.button == Button1) ?
200 	which_menuwin(ev.xbutton.window) : menucnt-1;
201       if (i >= 0) {
202 	r = (i == menucnt-1) ? -1 : i; /* -1 for Cancel */
203 	set_menu_status(i, 2);
204 	fin = True;
205       }
206       break;
207     }
208   }
209   XDestroyWindow(dsp, selwin);
210   XFlush(dsp);
211   free(mwsel);
212   return r;
213 }
214 
cnf_exist_check(name)215 int cnf_exist_check(name)
216      char *name;
217 {
218   int i;
219 
220   conf_file = ks_strdup(name);
221   i = is_regular_file(conf_file);
222   if (!i && extract_dir != NULL) {
223     conf_file = ks_realloc(strlen(extract_dir) + 1 + strlen(name) + 1);
224     sprintf(conf_file, "%s/%s", extract_dir, name);
225     i = is_regular_file(conf_file);
226   }
227   return i;
228 }
229 
230 /*
231  * input:
232  *	name		config file
233  *	extract_dir	LHa extracted directory
234  * output:
235  *	conf_dir[]	cell and kcf file base directory
236  *	conf_file[]	configuration file
237  */
select_cnf(name)238 int select_cnf(name)
239      char *name;
240 {
241   int i, r;
242   char *p;
243   LSTR buf;
244 
245   conf_dir = NULL;
246   conf_file = NULL;
247   lstr_init(&buf);
248   if (name != NULL) {
249     i = cnf_exist_check(name);
250     if (!i) {
251       lstr_cat(&buf, name);
252       lstr_cat(&buf, default_cnf_suffix);
253       i = cnf_exist_check(buf.buf);
254     }
255     if (i) {
256       conf_dir = get_directory(conf_file);
257       if (!*conf_dir) {
258 	free(conf_dir);
259 	conf_dir = ks_strdup(current_dir);
260       }
261       return 0;
262     }
263     /* name will be directory */
264     conf_dir = ks_strdup(name);
265   }
266   if (extract_dir != NULL) {
267     if (conf_dir != NULL)
268       free(conf_dir);
269     conf_dir = ks_strdup(extract_dir);
270   }
271   if (conf_dir == NULL || !conf_dir[0]) {
272     if (conf_dir != NULL)
273       free(conf_dir);
274     conf_dir = ks_strdup(current_dir);
275   }
276   conflist = find_cnf_file(conf_dir);
277   if (conflist == NULL) {
278     msg("W ``%s'' open error!\n", conf_dir);
279     r = -2;
280   } else if (*conflist == NULL) {
281     r = -2;			/* No *.cnf */
282   } else if (*(conflist+1) == NULL) {
283     r = 0;			/* One *.cnf */
284   } else {
285     r = select_menu("fkiss sel", str_geometry, conflist);
286   }
287   if (r >= 0) {
288     if (conf_file != NULL)
289       free(conf_file);
290     conf_file = ks_malloc(strlen(conf_dir) + 1 + strlen(*(conflist+r)) + 1);
291     sprintf(conf_file, "%s/%s", conf_dir, *(conflist+r));
292 
293     free(conf_dir);
294     conf_dir = ks_strdup(conf_file);
295     p = rindex(conf_dir, '/');
296     if (p)
297       *p = '\0';
298 
299   }
300   if (conflist != NULL)
301     dir_free(conflist);
302   debug_printf("selconf conf_dir [%s]\n", conf_dir);
303   return r;
304 }
305 
306 /* End of file */
307