1 /* $Header: /home/yav/xpx/RCS/file.c,v 1.62 1996/04/23 10:58:05 yav Exp $
2 * xpx file menu
3 * written by yav (UHD98984@pcvan.or.jp)
4 */
5
6 #include <X11/Xlib.h>
7 #include <X11/Xutil.h>
8 #include <X11/keysym.h>
9
10 #include "headers.h"
11 #include "xpx.h"
12 #include "work.h"
13 #include "icondef.h"
14 #include "infodef.h"
15 #define PUBLIC_FILE_C
16 #include "extern.h"
17
18 # ifdef HAVE_SYS_WAIT_H
19 # include <sys/wait.h>
20 # endif
21
22 #define FILEWINWIDTH 320
23 #define FILEWINHEIGHT 320
24
25 #define MAXFILE 1024
26 #define MAXFILENAME 64
27
28 #define PATHX 8
29 #define PATHY 8
30 #define PATHW 300
31 #define PATHH 24
32
33 #define NAMEX 160
34 #define NAMEY 100
35 #define NAMEW 140
36 #define NAMEH PATHH
37
38 #define DIRSLOTMAX 12
39 #define FILESLOTMAX 14 /* >= DIRSLOTMAX+1 */
40
41 #define SCROLLX (8-BDW)
42 #define SCROLLY 40
43 #define SCROLLW 128
44 #define SCROLLH 20
45 #define DIRSLOTX (SCROLLX+BDW)
46 #define DIRSLOTY (SCROLLY+SCROLLH+BDW*2)
47 #define DIRSLOTW SCROLLW
48 #define DIRSLOTH 18
49
50 #define FILEMENUX 196
51 #define FILEMENUY 160
52 #define FILEMENUW 64
53 #define FILEMENUH 20
54
55 #define SLIDERW 16
56 #define SLIDERH (DIRSLOTH*DIRSLOTMAX)
57
58 #define COLNMX 0
59 #define COLNMY 0
60 #define COLNMW 112
61 #define COLNMH 16
62 #define IMGNMX COLNMX+COLNMW+8
63 #define IMGNMY COLNMY
64 #define IMGNMW COLNMW
65 #define IMGNMH COLNMH
66
67 char rcsid_file[] = "$Id: file.c,v 1.62 1996/04/23 10:58:05 yav Exp $";
68
69 static Window file2win;
70 static int select_slot;
71 static char *filenamebuf;
72 static char current_path[MAXPATH];
73 static char current_name[MAXFILENAME];
74 static int files_count;
75 static int scroll_range;
76 static int scroll_pos;
77 static int slotindex[FILESLOTMAX];
78 static int file_scroll_speed;
79 static char *rcfile = ".xpxrc";
80
81 #define F_IMG (1<<0)
82 #define F_COL (1<<1)
83 #define F_ALL (F_IMG|F_COL)
84
85 typedef struct {
86 char suffix[8];
87 int mode;
88 int (*readroutine)();
89 int (*writeroutine)();
90 char *decoder;
91 char *encoder;
92 } FTYPE;
93
94 #define FTYPEMAX 32
95 static FTYPE *file_type_tbl = NULL;
96 static FTYPE default_file_type[] = {
97 {".cbb", F_IMG, rd_cbb, wr_cbb, NULL, NULL},
98 {".csb", F_IMG, rd_csb, NULL, NULL, NULL},
99 {".ccb", F_COL, rd_ccb, wr_ccb, NULL, NULL},
100 {".cxb", F_COL, rd_cxb, wr_cxb, NULL, NULL},
101 {".kcf", F_COL, rd_kcf, wr_kcf, NULL, NULL},
102 {".cel", F_IMG, rd_cel, wr_cel, NULL, NULL},
103 {".pbm", F_ALL, rd_pnm, NULL, NULL, NULL},
104 {".pgm", F_ALL, rd_pnm, NULL, NULL, NULL},
105 {".ppm", F_ALL, rd_pnm, wr_ppm, NULL, NULL},
106 {".mag", F_ALL, rd_mag, wr_mag, NULL, NULL},
107 {".xbm", F_IMG, rd_xbm, wr_xbm, NULL, NULL},
108 {".gif", F_ALL, rd_pnm, wr_ppm, "giftoppm", "ppmtogif"},
109 {".tim", F_ALL, rd_tim, wr_tim, NULL, NULL},
110 {".nbn", F_ALL, rd_nbn, NULL, NULL, NULL},
111 {".cls", F_COL, rd_cls, NULL, NULL, NULL},
112 {"", 0, NULL, NULL, NULL, NULL}
113 };
114
115 #define FILE_PATH 0
116 #define FILE_NAME 1
117 #define FILE_OPEN 2
118 #define FILE_SAVE 3
119 #define FILE_MASK 4
120 #define FILE_REMOVE 5
121 #define FILE_DUMMY2 6
122 #define FILE_OK 7
123 #define FILE_SLIDER 8
124
125 int fileev();
126 int slotev();
127 int slotev2();
128 void scroll_down();
129 void scroll_up();
130
131 #define IMASK (ExposureMask|EnterWindowMask|LeaveWindowMask|\
132 ButtonPressMask|ButtonReleaseMask)
133 static MENU filemenu[] = {
134 {
135 FILE_PATH, MenuModeMaskBorder,
136 PATHX, PATHY, PATHW, PATHH,
137 0, ExposureMask|EnterWindowMask|LeaveWindowMask|KeyPressMask, 0,
138 fileev, NULL, 0, MAXPATH, NULL},
139 {
140 FILE_NAME, MenuModeMaskBorder,
141 NAMEX, NAMEY, NAMEW, NAMEH,
142 0, ExposureMask|EnterWindowMask|LeaveWindowMask|KeyPressMask, 0,
143 fileev, NULL, 0, 64, NULL},
144 {
145 FILE_OPEN, MenuModeMaskBorder,
146 FILEMENUX, FILEMENUY+(FILEMENUH+BDW)*0, FILEMENUW, FILEMENUH,
147 0, IMASK, 0,
148 fileev, NULL, 0, 0, "Open"},
149 {
150 FILE_SAVE, MenuModeMaskBorder,
151 FILEMENUX, FILEMENUY+(FILEMENUH+BDW)*1, FILEMENUW, FILEMENUH,
152 0, IMASK, 0,
153 fileev, NULL, 0, 0, "Save"},
154 {
155 FILE_MASK, MenuModeMaskBorder|MenuModeMaskOn,
156 FILEMENUX, FILEMENUY+(FILEMENUH+BDW)*2, FILEMENUW, FILEMENUH,
157 0, ExposureMask|EnterWindowMask|LeaveWindowMask|ButtonPressMask, 0,
158 fileev, NULL, 0, 0, "Mask"},
159 {
160 FILE_REMOVE, MenuModeMaskBorder,
161 FILEMENUX, FILEMENUY+(FILEMENUH+BDW)*3, FILEMENUW, FILEMENUH,
162 0, IMASK, 0,
163 fileev, NULL, 0, 0, "Remove"},
164 {
165 FILE_DUMMY2, MenuModeMaskBorder,
166 FILEMENUX, FILEMENUY+(FILEMENUH+BDW)*4, FILEMENUW, FILEMENUH,
167 0, ExposureMask, 0,
168 NULL, NULL, 0, 0, "----"},
169 {
170 FILE_OK, MenuModeMaskBorder,
171 FILEMENUX, FILEMENUY+(FILEMENUH+BDW)*5, FILEMENUW, FILEMENUH,
172 0, IMASK, 0,
173 fileev, NULL, 0, 0, "OK"},
174 {
175 FILE_SLIDER, MenuModeMaskBorder,
176 DIRSLOTX+DIRSLOTW+BDW*2, DIRSLOTY, SLIDERW, SLIDERH,
177 0, ExposureMask|ButtonPressMask, 0,
178 NULL, NULL, 0, 0, NULL},
179 {
180 -1, 0,
181 0, 0, 0, 0,
182 0, 0, 0,
183 NULL, NULL, 0, 0, NULL}};
184 #undef IMASK
185
186 static MENU *fileslot;
187
188 #define DIRSLOT_UP 0
189 #define DIRSLOT_DOWN 1
190 #define IMASK (ExposureMask|EnterWindowMask|LeaveWindowMask|\
191 ButtonPressMask|ButtonReleaseMask)
192 static MENU slotwin[] = {
193 {
194 DIRSLOT_UP, MenuModeMaskBorder,
195 SCROLLX, SCROLLY, SCROLLW, SCROLLH,
196 0, IMASK, 0,
197 slotev2, NULL, 0, 0, NULL},
198 {
199 DIRSLOT_DOWN, MenuModeMaskBorder,
200 SCROLLX, SCROLLY+SCROLLH+BDW*4+DIRSLOTH*DIRSLOTMAX, SCROLLW, SCROLLH,
201 0, IMASK, 0,
202 slotev2, NULL, 0, 0, NULL},
203 {
204 -1, 0,
205 0, 0, 0, 0,
206 0, 0, 0,
207 NULL, NULL, 0, 0, NULL}};
208 #undef IMASK
209
210 #define NAMEMENU_IMAGE 0
211 #define NAMEMENU_COLOR 1
212
213 char *namemenu_str();
214
215 static MENU namemenu[] = {
216 {
217 NAMEMENU_IMAGE, MenuModeMaskBorder,
218 IMGNMX, IMGNMY, IMGNMW, IMGNMH,
219 0, ExposureMask, 0,
220 NULL, namemenu_str, 0, 0, NULL},
221 {
222 NAMEMENU_COLOR, MenuModeMaskBorder,
223 COLNMX, COLNMY, COLNMW, COLNMH,
224 0, ExposureMask, 0,
225 NULL, namemenu_str, 0, 0, NULL},
226 {
227 -1, 0,
228 0, 0, 0, 0,
229 0, 0, 0,
230 NULL, NULL, 0, 0, NULL}};
231
namemenu_str(p)232 char *namemenu_str(p)
233 MENU *p;
234 {
235 switch(p->n) {
236 case NAMEMENU_IMAGE:
237 return filename(imgfilename);
238 case NAMEMENU_COLOR:
239 return filename(colfilename);
240 }
241 /* NOT REACHED */
242 return NULL;
243 }
244
sliderev(p,ev)245 int sliderev(p, ev)
246 MENU *p;
247 XEvent *ev;
248 {
249 int i, rx, ry, cx, cy;
250 unsigned int key;
251 Window rw, cw;
252 static int dy, sy;
253
254 switch(ev->type) {
255 case ButtonPress:
256 dy = p->y + ev->xbutton.y;
257 dy = ev->xbutton.y_root;
258 sy = scroll_pos;
259 return 1;
260 break;
261 case ButtonRelease:
262 return 1;
263 break;
264 case MotionNotify:
265 XQueryPointer(dsp, ev->xmotion.window, &rw, &cw, &rx, &ry, &cx, &cy, &key);
266 i = ((ry - dy)*scroll_range)/(SLIDERH-p->h) + sy;
267 if (i > scroll_pos)
268 scroll_up(i - scroll_pos);
269 else if (i < scroll_pos)
270 scroll_down(scroll_pos - i);
271 break;
272 }
273 return 0;
274 }
275
276 #define IMASK (ExposureMask|ButtonPressMask|ButtonReleaseMask|\
277 PointerMotionHintMask|ButtonMotionMask)
278
279 static MENU slidermenu[] = {
280 {
281 0, MenuModeMaskBorder,
282 0, 0, SLIDERW-BDW*2, 1,
283 0, IMASK, 0,
284 sliderev, NULL, 0, 0, NULL},
285 {
286 -1, 0,
287 0, 0, 0, 0,
288 0, 0, 0,
289 NULL, NULL, 0, 0, NULL}};
290 #undef IMASK
291
resize_slider()292 void resize_slider()
293 {
294 int movearea, fcnt;
295 MENU *p;
296
297 fcnt = files_count < DIRSLOTMAX ? DIRSLOTMAX : files_count;
298 p = slidermenu+0;
299 p->h = ((SLIDERH-BDW*2)*DIRSLOTMAX)/fcnt;
300 if (p->h < p->w)
301 p->h = p->w;
302 movearea = (SLIDERH-BDW*2) - p->h;
303 p->y = 0;
304 fcnt -= DIRSLOTMAX;
305 if (fcnt > 0)
306 p->y = (movearea*scroll_pos)/fcnt/DIRSLOTH;
307 XMoveResizeWindow(dsp, p->win, p->x, p->y, p->w, p->h);
308 }
309
get_filetype_max(void)310 int get_filetype_max(
311 #if NeedFunctionPrototypes
312 void
313 #endif
314 )
315 {
316 int i;
317
318 for (i = 0; i < FTYPEMAX; i++) {
319 if (file_type_tbl[i].suffix[0] == '\0')
320 break;
321 }
322 return i;
323 }
324
is_supported_suffix(char * name)325 int is_supported_suffix(
326 #if NeedFunctionPrototypes
327 char *name)
328 #else
329 name)
330 char *name;
331 #endif
332 {
333 int i;
334 int len, suflen;
335
336 len = strlen(name);
337 i = get_filetype_max();
338 while (--i >= 0) {
339 suflen = strlen(file_type_tbl[i].suffix);
340 if ((len - suflen >= 0) &&
341 (strncmp(name+len-suflen, file_type_tbl[i].suffix, suflen) == 0))
342 return 1;
343 }
344 return 0;
345 }
346
select_suffix(char * buf,int len,int n)347 int select_suffix(
348 #if NeedFunctionPrototypes
349 char *buf, int len, int n)
350 #else
351 buf, len, n)
352 char *buf;
353 int len;
354 int n;
355 #endif
356 {
357 int i, j, r;
358 char *p, *p2;
359
360 p = buf;
361 r = 0;
362 for (i = 0; i < n && *p; i++) {
363 j = strlen(p);
364 if ((j && *(p+j-1) == '/')||
365 is_supported_suffix(p))
366 r++;
367 else
368 *p = '\0';
369 p += len;
370 }
371 p = p2 = buf;
372 for (i = 0; i < n; i++) {
373 if (*p) {
374 if (p != p2)
375 memcpy(p2, p, len);
376 p2 += len;
377 }
378 p += len;
379 }
380 while (p2 != p) {
381 *p2 = '\0';
382 p2 += len;
383 }
384 return r;
385 }
386
387 /*
388 * return number of file (0 is error!)
389 */
get_filenames()390 int get_filenames()
391 {
392 int i, n;
393
394 n = get_dir(current_path, filenamebuf, MAXFILENAME, MAXFILE);
395 for (i = n; i < MAXFILE; i++)
396 *(filenamebuf+i*MAXFILENAME) = '\0';
397 if (filemenu[FILE_MASK].mode & MenuModeMaskOn)
398 n = select_suffix(filenamebuf, MAXFILENAME, n);
399 redraw_window(filemenu[FILE_PATH].win);
400 files_count = n;
401 scroll_range = (n-DIRSLOTMAX)*DIRSLOTH;
402 if (scroll_range < 0)
403 scroll_range = 0;
404 return n;
405 }
406
slotwin_strfunc(p)407 char *slotwin_strfunc(p)
408 MENU *p;
409 {
410 return filenamebuf+slotindex[p->n]*MAXFILENAME;
411 }
412
redraw_fileslot()413 void redraw_fileslot()
414 {
415 int i;
416 MENU *p;
417
418 p = fileslot;
419 for (i = 0; i < FILESLOTMAX; i++) {
420 XMoveWindow(dsp, p->win, p->x, p->y);
421 redraw_window(p->win);
422 p++;
423 }
424 }
425
set_slotmode(n)426 void set_slotmode(n)
427 int n;
428 {
429 if (slotindex[n] == select_slot)
430 (fileslot+n)->mode |= MenuModeMaskOn;
431 else
432 (fileslot+n)->mode &= ~MenuModeMaskOn;
433 }
434
init_fileslot_pos()435 void init_fileslot_pos()
436 {
437 int i, y;
438 int startindex;
439 MENU *p;
440
441 p = fileslot;
442 startindex = scroll_pos / DIRSLOTH;
443 y = - (scroll_pos % DIRSLOTH);
444 for (i = 0; i < FILESLOTMAX; i++) {
445 slotindex[i] = startindex+i;
446 p->x = 0;
447 p->y = y;
448 y += DIRSLOTH;
449 set_slotmode(i);
450 p++;
451 }
452 }
453
454
create_file_window()455 int create_file_window()
456 {
457 int i;
458 MENU *p;
459 XSetWindowAttributes attr;
460
461 filenamebuf = malloc(MAXFILE*MAXFILENAME);
462 create_toplevel_window(&filewin, "file", str_file_geom,
463 FILEWINWIDTH, FILEWINHEIGHT);
464 menuwin_create(filemenu, filewin, 0, 0);
465 file2win = XCreateSimpleWindow(dsp, filewin, DIRSLOTX, DIRSLOTY,
466 DIRSLOTW, DIRSLOTH*DIRSLOTMAX,
467 BDW, border_color, bg);
468 XMapRaised(dsp, file2win);
469 fileslot = (MENU *)malloc(sizeof(MENU)*(FILESLOTMAX+1));
470 p = fileslot;
471 for (i = 0; i < FILESLOTMAX; i++) {
472 bzero(p, sizeof(*p));
473 p->n = i;
474 p->w = DIRSLOTW;
475 p->h = DIRSLOTH;
476 p->mode = MenuModeMaskLeft;
477 p->im = ExposureMask|EnterWindowMask|LeaveWindowMask|ButtonPressMask;
478 p->event = slotev;
479 p->strfunc = slotwin_strfunc;
480 p++;
481 }
482 p->n = -1;
483 select_slot = 0;
484 scroll_pos = 0;
485 init_fileslot_pos();
486 menuwin_create(fileslot, file2win, 0, 0);
487 menuwin_create(slotwin, filewin, BDW, 0);
488 attr.background_pixmap = hatch_pixmap;
489 XChangeWindowAttributes(dsp, filemenu[FILE_SLIDER].win, CWBackPixmap, &attr);
490 menuwin_create(slidermenu, filemenu[FILE_SLIDER].win, 0, 0);
491
492 change_directory(""); /* get current */
493 return 0;
494 }
495
map_file_window()496 void map_file_window()
497 {
498 XMapRaised(dsp, filewin);
499 }
500
unmap_file_window()501 void unmap_file_window()
502 {
503 XUnmapWindow(dsp, filewin);
504 }
505
close_file_window()506 void close_file_window()
507 {
508 XDestroyWindow(dsp, filewin);
509 free(filenamebuf);
510 }
511
get_parent_pathname(path)512 char *get_parent_pathname(path)
513 char *path;
514 {
515 char *p;
516
517 p = strrchr(path, '/');
518 if (p != NULL) {
519 if (p == path)
520 p++;
521 *p = '\0';
522 }
523 return path;
524 }
525
set_current_name(name)526 void set_current_name(name)
527 char *name;
528 {
529 strcpy(current_name, name);
530 strcpy(filemenu[FILE_NAME].str, name);
531 filemenu[FILE_NAME].cursor = strlen(current_name);
532 redraw_window(filemenu[FILE_NAME].win);
533 }
534
set_select_slot_name(void)535 void set_select_slot_name(
536 #if NeedFunctionPrototypes
537 void
538 #endif
539 )
540 {
541 set_current_name(filenamebuf+(select_slot)*MAXFILENAME);
542 }
543
rescan_disp_fileslot(void)544 void rescan_disp_fileslot(
545 #if NeedFunctionPrototypes
546 void
547 #endif
548 )
549 {
550 int i;
551
552 cursor_busy();
553 i = get_filenames();
554 if (select_slot >= i)
555 select_slot = i-1;
556 scroll_pos = select_slot*DIRSLOTH - (DIRSLOTMAX*DIRSLOTH)/2;
557 if (scroll_pos < 0)
558 scroll_pos = 0;
559 else if (scroll_pos >= scroll_range)
560 scroll_pos = scroll_range;
561 init_fileslot_pos();
562 resize_slider();
563 redraw_fileslot();
564 }
565
change_directory(dir)566 int change_directory(dir)
567 char *dir;
568 {
569 int i;
570 char buf[MAXPATH];
571 char buf2[MAXPATH];
572
573 switch(*dir) {
574 case '\0':
575 /* current working directory pathname */
576 get_current_dir(buf);
577 break;
578 case '/':
579 /* absolute pathname */
580 strcpy(buf, dir);
581 break;
582 default:
583 /* relative pathname */
584 strcpy(buf, current_path);
585 strcpy(buf2, dir);
586 i = strlen(buf2);
587 if (i && buf2[i-1] == '/')
588 buf2[i-1] = '\0';
589 if (strcmp(buf2, "..") == 0) {
590 get_parent_pathname(buf);
591 } else if (strcmp(buf2, ".") != 0) {
592 i = strlen(buf);
593 if (i && buf[i-1] != '/')
594 strcat(buf, "/");
595 strcat(buf, buf2);
596 }
597 }
598 if (get_dir(buf, buf2, sizeof(buf2), 1)) {
599 strcpy(current_path, buf);
600 strcpy(filemenu[FILE_PATH].str, buf);
601 filemenu[FILE_PATH].cursor = strlen(filemenu[FILE_PATH].str);
602 redraw_window(filemenu[FILE_PATH].win);
603 select_slot = 0;
604 scroll_pos = 0;
605 rescan_disp_fileslot();
606 set_select_slot_name();
607 return 0;
608 }
609 return 1;
610 }
611
set_imgfilename(name)612 void set_imgfilename(name)
613 char *name;
614 {
615 strcpy(imgfilename, name);
616 redraw_window(namemenu[NAMEMENU_IMAGE].win);
617 redraw_window(infomenu[INFOMENU_IMGFILE].win);
618 }
619
set_colfilename(name)620 void set_colfilename(name)
621 char *name;
622 {
623 strcpy(colfilename, name);
624 redraw_window(namemenu[NAMEMENU_COLOR].win);
625 redraw_window(infomenu[INFOMENU_COLFILE].win);
626 redraw_window(infomenu[INFOMENU_COLCOUNT].win);
627 }
628
create_filename_window(win,x,y)629 void create_filename_window(win, x, y)
630 Window win;
631 int x;
632 int y;
633 {
634 topmenuwin_create(namemenu, x, y);
635 }
636
skip_space(p)637 char *skip_space(p)
638 char *p;
639 {
640 while (*p && (*p == ' ' || *p == '\t' || *p == '\n'))
641 p++;
642 return p;
643 }
644
645 /* Search matching string in structures
646 * structure first member must be (char *).
647 * if not found matching string, return NULL
648 */
match_struct(tbl,len,p)649 char *match_struct(tbl, len, p)
650 char *tbl; /* structure list pointer */
651 int len; /* size of a structure */
652 char *p; /* string */
653 {
654 char *s;
655
656 while ((s = *((char **)tbl)) != NULL) {
657 if (strncmp(p, s, strlen(s)) == 0)
658 return tbl;
659 tbl += len; /* get next structure address */
660 }
661 return NULL; /* not found */
662 }
663
664 /* if not found matching string, return -1 */
match_string(tbl,p)665 int match_string(tbl, p)
666 char *tbl[];
667 char *p;
668 {
669 int i;
670
671 for (i = 0; tbl[i] != NULL; i++) {
672 if (strncmp(p, tbl[i], strlen(tbl[i])) == 0)
673 return i;
674 }
675 return -1; /* not found */
676 }
677
get_string(char str[],char * p,int n)678 char *get_string(
679 #if NeedFunctionProtorypes
680 char str[], char *p, int n)
681 #else
682 str, p, n)
683 char str[];
684 char *p;
685 int n;
686 #endif
687 {
688 int i;
689 int quote;
690
691 p = skip_space(p);
692 quote = i = 0;
693 if (*p == '"' || *p == '\'')
694 quote = *p++;
695 while (i < n-1 && *p) {
696 if (*p == quote) {
697 p++;
698 break;
699 }
700 if (!quote && (*p == ' ' || *p == '\t'))
701 break;
702 str[i++] = *p++;
703 }
704 str[i] = '\0';
705 return p;
706 }
707
708 /* Parse string in structure
709 * structure first member must be (char *).
710 * if not found matching string, return NULL
711 */
712 #if NeedFunctionPrototypes
parse_str2(void * tbl,int len,char ** p)713 void *parse_str2(void *tbl, int len, char **p)
714 #else
715 char *parse_str2(
716 tbl, len, p)
717 char *tbl; /* structure list pointer */
718 int len; /* size of one structure */
719 char **p; /* string */
720 #endif
721 {
722 char *r;
723 char buf[256];
724
725 *p = get_string(buf, *p, sizeof(buf));
726 if (strcmp(buf, "None") == 0 || strcmp(buf, "-") == 0)
727 return NULL;
728 r = match_struct(tbl, len, buf);
729 if (r == NULL) {
730 error("parse ``%s'' unknown!", buf);
731 *p += strlen(*p);
732 }
733 return r;
734 }
735
736 /* type */
737 typedef struct _MODETBL {
738 char *symbol;
739 int mode;
740 } MODETBL;
741
742 static MODETBL modetbll[] = {
743 {"color", F_COL},
744 {"image", F_IMG},
745 {"all", F_ALL},
746 {NULL, 0}
747 };
748
749 typedef struct _FUNCTBL {
750 char *symbol;
751 int (*func)();
752 } FUNCTBL;
753
754 /* read routine */
755 static FUNCTBL rdfunc[] = {
756 {"ccb", rd_ccb},
757 {"cbb", rd_cbb},
758 {"csb", rd_csb},
759 {"cxb", rd_cxb},
760 {"kcf", rd_kcf},
761 {"cel", rd_cel},
762 {"pnm", rd_pnm},
763 {"ppm", rd_pnm},
764 {"xbm", rd_xbm},
765 {"mag", rd_mag},
766 {"tim", rd_tim},
767 {"nbn", rd_nbn},
768 {"cls", rd_cls},
769 {NULL, NULL}
770 };
771
772 /* write routine */
773 static FUNCTBL wrfunc[] = {
774 {"ccb", wr_ccb},
775 {"cbb", wr_cbb},
776 {"cxb", wr_cxb},
777 {"kcf", wr_kcf},
778 {"cel", wr_cel},
779 {"ppm", wr_ppm},
780 {"xbm", wr_xbm},
781 {"mag", wr_mag},
782 {"tim", wr_tim},
783 {NULL, NULL}
784 };
785
parse_ftype(char * p)786 int parse_ftype(
787 #if NeedFunctionPrototypes
788 char *p)
789 #else
790 p)
791 char *p;
792 #endif
793 {
794 int i;
795 FTYPE *pp;
796 FUNCTBL *funcp;
797 MODETBL *modep;
798 char buf[256];
799
800 i = get_filetype_max();
801 pp = file_type_tbl + i;
802 p = get_string(pp->suffix, p, sizeof(pp->suffix));
803 if (!*p)
804 return 1;
805 modep = parse_str2(modetbll, sizeof(*modetbll), &p);
806 pp->mode = (modep != NULL) ? modep->mode : 0;
807 funcp = parse_str2(rdfunc, sizeof(*rdfunc), &p);
808 pp->readroutine = (funcp != NULL) ? funcp->func : NULL;
809 funcp = parse_str2(wrfunc, sizeof(*wrfunc), &p);
810 pp->writeroutine = (funcp != NULL) ? funcp->func : NULL;
811 pp->decoder = NULL;
812 p = get_string(buf, p, sizeof(buf));
813 if (buf[0]) {
814 pp->decoder = (char *)malloc(strlen(buf)+1);
815 strcpy(pp->decoder, buf);
816 }
817 pp->encoder = NULL;
818 p = get_string(buf, p, sizeof(buf));
819 if (buf[0]) {
820 pp->encoder = (char *)malloc(strlen(buf)+1);
821 strcpy(pp->encoder, buf);
822 }
823 return 0;
824 }
825
parse_option_configuration(char * p)826 int parse_option_configuration(
827 #if NeedFunctionProtorypes
828 char *p)
829 #else
830 p)
831 char *p;
832 #endif
833 {
834 int i;
835 char *bufp;
836 char **argv;
837 char buf[1024];
838 char *av[64];
839
840 i = 0;
841 bufp = buf;
842 while (i < 64-1) {
843 p = get_string(bufp, p, sizeof(buf)-(bufp-buf));
844 if (!*bufp)
845 break;
846 av[i++] = bufp;
847 bufp += strlen(bufp) + 1;
848 if (bufp >= buf+sizeof(buf))
849 break;
850 }
851 av[i] = NULL;
852 argv = av;
853 return parse_option(&i, &argv);
854 }
855
856 static char *section_name[] = {"*end", "*file", "*window", "*option", NULL};
857
858 typedef struct _WINGEOMTBL {
859 char *symbol;
860 char *geom;
861 Window *win;
862 } WINGEOMTBL;
863
864 static WINGEOMTBL wintbl[] = {
865 {"file", str_file_geom, &filewin},
866 {"info", str_info_geom, &infowin},
867 {"edit", str_edit_geom, &editwin},
868 {NULL, NULL, NULL}
869 };
870
871
parse_window_configuration(char * p)872 int parse_window_configuration(
873 #if NeedFunctionProtorypes
874 char *p)
875 #else
876 p)
877 char *p;
878 #endif
879 {
880 WINGEOMTBL *wp;
881 char buf[256];
882
883 wp = parse_str2(wintbl, sizeof(*wintbl), &p);
884 if (wp == NULL)
885 return -1;
886 get_string(buf, p, sizeof(buf));
887 strncpy(wp->geom, buf, 32);
888 return 0;
889 }
890
891
read_config_file(char * name)892 int read_config_file(
893 #if NeedFunctionPrototypes
894 char *name)
895 #else
896 name)
897 char *name;
898 #endif
899 {
900 int i;
901 int section; /* 0:None 1:file 2:window 3:option */
902 FILE *fp;
903 char buf[1024];
904
905 fp = fopen(name, "r");
906 if (fp == NULL)
907 return 1;
908 section = 0;
909 while (fgets(buf, sizeof(buf), fp) != NULL) {
910 i = strlen(buf);
911 if (i && buf[i-1] == '\n')
912 buf[i-1] = '\0';
913 if (buf[0] == '#' || buf[0] == '\0')
914 continue;
915 if (buf[0] == '*') {
916 i = match_string(section_name, buf);
917 if (i < 0)
918 i = 0;
919 section = i;
920 continue;
921 }
922 switch(section) {
923 case 1:
924 if (parse_ftype(buf))
925 error("file type parse error ``%s''", buf);
926 break;
927 case 2:
928 parse_window_configuration(buf);
929 break;
930 case 3:
931 parse_option_configuration(buf);
932 break;
933 }
934 }
935 fclose(fp);
936 return 0;
937 }
938
939 /*
940 * return 0: no error!
941 * Caution! This routine is called before XOpenDisplay.
942 */
read_config(void)943 int read_config(
944 #if NeedFunctionPrototypes
945 void
946 #endif
947 )
948 {
949 int i;
950 char *p;
951 char buf[MAXPATH];
952
953 file_type_tbl = (FTYPE *)malloc(sizeof(FTYPE)*FTYPEMAX);
954 if (file_type_tbl == NULL) {
955 error("more core!");
956 return 1;
957 }
958 bzero(file_type_tbl, sizeof(FTYPE)*FTYPEMAX);
959 for (i = 0; default_file_type[i].suffix[0]; i++)
960 file_type_tbl[i] = default_file_type[i];
961 p = getenv("HOME");
962 if (p != NULL) {
963 sprintf(buf, "%s/%s", p, rcfile);
964 read_config_file(buf);
965 }
966 read_config_file(rcfile);
967 return 0;
968 }
969
gen_geometry_string(char * buf,Window win)970 void gen_geometry_string(
971 #if NeedFunctionProtorypes
972 char *buf, Window win)
973 #else
974 buf, win)
975 char *buf;
976 Window win;
977 #endif
978 {
979 int x0, y0;
980 unsigned int width0, height0;
981 int x, y;
982 unsigned int width, height, border, depth;
983 Window root, parent;
984 Window *children;
985 unsigned int nchildren;
986
987 width0 = height0 = x0 = y0 = 0;
988 while (XQueryTree(dsp, win, &root, &parent, &children, &nchildren)) {
989 XFree((char *)children);
990 XGetGeometry(dsp, win, &root, &x, &y, &width, &height, &border, &depth);
991 if (!width0) {
992 width0 = width;
993 height0 = height;
994 }
995 x0 = x;
996 y0 = y;
997 win = parent;
998 if (win == DefaultRootWindow(dsp))
999 break;
1000 }
1001 sprintf(buf, "%dx%d+%d+%d", width0, height0, x0, y0);
1002 }
1003
1004 /* return 0: no error */
write_window_geometry(FILE * fp)1005 int write_window_geometry(
1006 #if NeedFunctionProtorypes
1007 FILE *fp)
1008 #else
1009 fp)
1010 FILE *fp;
1011 #endif
1012 {
1013 WINGEOMTBL *wp;
1014 char buf[1024];
1015
1016 fprintf(fp, "%s\n", section_name[2]);
1017 for (wp = wintbl; wp->symbol != NULL; wp++) {
1018 gen_geometry_string(buf, *(wp->win));
1019 fprintf(fp, "%s\t%s\n", wp->symbol, buf);
1020 }
1021 return ferror(fp);
1022 }
1023
1024 /* update configuration file
1025 *
1026 * return
1027 * 0 no error
1028 * other error
1029 */
update_config_file(void)1030 int update_config_file(
1031 #if NeedFunctionProtorypes
1032 void
1033 #endif
1034 )
1035 {
1036 FILE *fp, *ofp;
1037 char *p;
1038 Bool f;
1039 int r, i, section;
1040 char orgfile[MAXPATH];
1041 char buf[MAXPATH];
1042
1043 strcpy(orgfile, rcfile);
1044 fp = fopen(orgfile, "r+"); /* "r+" for writable check */
1045 if (fp == NULL) {
1046 p = (char *)getenv("HOME");
1047 if (p != NULL) {
1048 sprintf(orgfile, "%s/%s", p, rcfile);
1049 fp = fopen(orgfile, "r+");
1050 }
1051 }
1052 if (fp == NULL)
1053 return 1;
1054 strcpy(buf, orgfile);
1055 strcat(buf, ".new");
1056 ofp = fopen(buf, "w");
1057 if (ofp == NULL)
1058 return 1;
1059 r = section = 0;
1060 while (fgets(buf, sizeof(buf), fp) != NULL) {
1061 f = True;
1062 if (buf[0] == '*') {
1063 i = match_string(section_name, buf);
1064 if (i < 0)
1065 i = 0;
1066 section = i;
1067 }
1068 if (section == 2)
1069 f = False;
1070 if (f && fputs(buf, ofp) == EOF)
1071 r = 1;
1072 if (r)
1073 break;
1074 }
1075 r |= write_window_geometry(ofp);
1076 fclose(ofp);
1077 fclose(fp);
1078 /* rename file, if no error */
1079 if (!r) {
1080 strcpy(buf, orgfile);
1081 strcat(buf, ".new");
1082 r = rename(buf, orgfile);
1083 }
1084 return r;
1085 }
1086
split_command(str,filename)1087 char **split_command(str, filename)
1088 char *str;
1089 char *filename;
1090 {
1091 char *p;
1092 int i;
1093 char form[1024];
1094 static char *args[128];
1095 static char buf[1024];
1096
1097 strcpy(form, str);
1098 strcat(form, " %s"); /* for decoder string without filename %s */
1099 sprintf(buf, form, filename, "");
1100 p = buf;
1101 for (i = 0; i < 128-1; i++) {
1102 p = skip_space(p);
1103 if (*p == '\0' || *p == '\n')
1104 break;
1105 args[i] = p;
1106 while (*p > ' ')
1107 p++;
1108 while (*p == ' '|| *p == '\t' || *p == '\n')
1109 *p++ = '\0';
1110 }
1111 args[i] = NULL;
1112 return args;
1113 }
1114
autosavecol()1115 int autosavecol()
1116 {
1117 FILE *fp;
1118 char *p;
1119 char name[MAXPATH];
1120
1121 reset_color_pushed(-1);
1122 p = (char *)getenv("HOME");
1123 if (p == NULL)
1124 p = ".";
1125 strcpy(name, p);
1126 strcat(name, "/#xpxsave.kcf");
1127 fp = fopen(name, "w");
1128 if (fp == NULL)
1129 return 1;
1130 wr_kcf(fp);
1131 return fclose(fp);
1132 }
1133
autosaveimg()1134 int autosaveimg()
1135 {
1136 FILE *fp;
1137 char *p;
1138 char name[MAXPATH];
1139
1140 p = (char *)getenv("HOME");
1141 if (p == NULL)
1142 p = ".";
1143 strcpy(name, p);
1144 strcat(name, "/#xpxsave.cel");
1145 fp = fopen(name, "w");
1146 if (fp == NULL)
1147 return 1;
1148 wr_cel(fp);
1149 return fclose(fp);
1150 }
1151
autosave()1152 int autosave()
1153 {
1154 int r;
1155
1156 r = 0;
1157 if (colchanged)
1158 r |= autosavecol();
1159 if (imgchanged)
1160 r |= autosaveimg();
1161 return r;
1162 }
1163
read_any_file(p,name)1164 int read_any_file(p, name)
1165 FTYPE *p;
1166 char *name;
1167 {
1168 FILE *fp;
1169 int i, r, fd[2];
1170
1171 cursor_busy();
1172 autosave();
1173 undo_clear();
1174 message("``%s'' reading...", name);
1175 if (p->decoder != NULL) {
1176 pipe(fd);
1177 if (vfork() == 0) {
1178 char **av;
1179 close(1);
1180 dup(fd[1]);
1181 close(fd[1]);
1182 close(fd[0]);
1183 av = split_command(p->decoder, name);
1184 execvp(*av, av);
1185 _exit(1);
1186 }
1187 fp = fdopen(fd[0], "r");
1188 close(fd[1]);
1189 } else {
1190 fp = fopen(name, "r");
1191 if (fp == NULL) {
1192 message("!open error!\n");
1193 return 1;
1194 }
1195 }
1196 if (p->mode & F_COL) {
1197 set_colfilename(name);
1198 colchanged = missed_color = 0;
1199 colposx = colposy = 0;
1200 }
1201 if (p->mode & F_IMG) {
1202 set_imgfilename(name);
1203 imgchanged = 0;
1204 hotspotx = hotspoty = -1;
1205 imgposx = imgposy = imgfiledepth = 0;
1206 }
1207 r = 1;
1208 if (p->readroutine != NULL)
1209 r = p->readroutine(fp);
1210 fclose(fp);
1211 if (p->decoder != NULL)
1212 wait(&i);
1213 if (r) {
1214 if (p->mode & F_COL)
1215 set_colfilename("");
1216 if (p->mode & F_IMG)
1217 set_imgfilename("");
1218 message("!read error!\n");
1219 return r;
1220 }
1221 img_scroll_posreset();
1222 message("done.\n");
1223 info_imgsize_set(); /* update info numbers */
1224 return 0;
1225 }
1226
1227
write_any_file(p,name)1228 int write_any_file(p, name)
1229 FTYPE *p;
1230 char *name;
1231 {
1232 FILE *fp;
1233 int r, i, fd[2];
1234
1235 cursor_busy();
1236 autosave();
1237 undo_clear();
1238 message("``%s'' writing...", name);
1239 if (p->writeroutine == NULL) {
1240 message("!\nNot supported format!\nAbort.\n");
1241 return 1;
1242 }
1243 fp = fopen(name, "w");
1244 if (fp == NULL) {
1245 message("!open error!\n");
1246 return 1;
1247 }
1248 if (p->encoder != NULL) {
1249 char **av;
1250
1251 pipe(fd);
1252 if (vfork() == 0) {
1253 close(0);
1254 dup(fd[0]);
1255 close(1);
1256 dup(fileno(fp));
1257 close(fd[1]);
1258 close(fd[0]);
1259 av = split_command(p->encoder, "");
1260 execvp(*av, av);
1261 _exit(1);
1262 }
1263 fp = fdopen(fd[1], "w");
1264 close(fd[0]);
1265 }
1266 r = p->writeroutine(fp, name);
1267 fclose(fp);
1268 if (p->encoder != NULL)
1269 wait(&i);
1270 if (r) {
1271 message("!write error!\n");
1272 return r;
1273 }
1274 if (p->mode & F_COL) {
1275 colchanged = 0;
1276 set_colfilename(name);
1277 }
1278 if (p->mode & F_IMG) {
1279 imgchanged = 0;
1280 set_imgfilename(name);
1281 }
1282 message("done.\n");
1283 return 0;
1284 }
1285
get_filetype(name)1286 int get_filetype(name)
1287 char *name;
1288 {
1289 int i, n;
1290
1291 n = get_filetype_max();
1292 while (--n >= 0) {
1293 i = strlen(name) - strlen(file_type_tbl[n].suffix);
1294 if (i >= 0 && strcmp(name+i, file_type_tbl[n].suffix) == 0)
1295 break;
1296 }
1297 return n;
1298 }
1299
read_data_file(name)1300 int read_data_file(name)
1301 char *name;
1302 {
1303 int i;
1304
1305 i = get_filetype(name);
1306 if (i < 0)
1307 return 1;
1308 return read_any_file(file_type_tbl+i, name);
1309 }
1310
file_open()1311 int file_open()
1312 {
1313 int i;
1314 char buf[MAXPATH];
1315
1316 i = strlen(current_name);
1317 if (i && current_name[i-1] == '/') {
1318 strcpy(buf, current_name);
1319 buf[i-1] = '\0';
1320 change_directory(buf);
1321 set_current_name("");
1322 }
1323 if (current_name[0] == '\0')
1324 return 1;
1325 sprintf(buf, "%s/%s", current_path, current_name);
1326 return read_data_file(buf);
1327 }
1328
change_select_slot(char * name)1329 int change_select_slot(
1330 #if NeedFunctionProtorypes
1331 char *name)
1332 #else
1333 name)
1334 char *name;
1335 #endif
1336 {
1337 int i;
1338
1339 for (i = 0; i < files_count; i++) {
1340 if (strcmp(filenamebuf+i*MAXFILENAME, name) == 0)
1341 return select_slot = i;
1342 }
1343 return -1;
1344 }
1345
file_save()1346 int file_save()
1347 {
1348 int i, r;
1349 char buf[MAXPATH];
1350
1351 i = strlen(current_name);
1352 if (!i || current_name[i-1] == '/')
1353 return 1;
1354 sprintf(buf, "%s/%s", current_path, current_name);
1355 i = get_filetype(buf);
1356 if (i < 0)
1357 return 1;
1358 r = write_any_file(file_type_tbl+i, buf);
1359 if (r == 0) {
1360 rescan_disp_fileslot();
1361 change_select_slot(current_name);
1362 rescan_disp_fileslot();
1363 }
1364 return r;
1365 }
1366
file_remove()1367 int file_remove()
1368 {
1369 int i;
1370 char buf[MAXPATH];
1371
1372 i = strlen(current_name);
1373 if (!i || current_name[i-1] == '/')
1374 return 1;
1375 sprintf(buf, "%s/%s", current_path, current_name);
1376 if (unlink(buf) == 0) {
1377 rescan_disp_fileslot();
1378 set_select_slot_name();
1379 }
1380 return 0;
1381 }
1382
max_sloty()1383 MENU *max_sloty()
1384 {
1385 int i;
1386 MENU *p, *rp;
1387
1388 rp = p = fileslot;
1389 for (i = 0; i < FILESLOTMAX; i++) {
1390 if (rp->y < p->y)
1391 rp = p;
1392 p++;
1393 }
1394 return rp;
1395 }
1396
min_sloty()1397 MENU *min_sloty()
1398 {
1399 int i;
1400 MENU *p, *rp;
1401
1402 rp = p = fileslot;
1403 for (i = 0; i < FILESLOTMAX; i++) {
1404 if (rp->y > p->y)
1405 rp = p;
1406 p++;
1407 }
1408 return rp;
1409 }
1410
1411 typedef struct {
1412 int n;
1413 MENU m;
1414 } SMENU;
1415
cmp_slot(p1,p2)1416 int cmp_slot(p1, p2)
1417 SMENU *p1;
1418 SMENU *p2;
1419 {
1420 return p1->m.y - p2->m.y;
1421 }
1422
sort_slot()1423 void sort_slot()
1424 {
1425 int i;
1426 SMENU buf[FILESLOTMAX];
1427
1428 for (i = 0; i < FILESLOTMAX; i++) {
1429 buf[i].n = slotindex[i];
1430 buf[i].m = *(fileslot+i);
1431 }
1432 qsort(buf, FILESLOTMAX, sizeof(*buf), cmp_slot);
1433 for (i = 0; i < FILESLOTMAX; i++) {
1434 slotindex[i] = buf[i].n;
1435 *(fileslot+i) = buf[i].m;
1436 (fileslot+i)->n = i;
1437 }
1438 }
1439
scroll_up(n)1440 void scroll_up(n)
1441 int n;
1442 {
1443 int i;
1444 MENU *p, *mx;
1445
1446 if (scroll_pos + n > scroll_range)
1447 n = scroll_range - scroll_pos;
1448 scroll_pos += n;
1449 for (i = 0; i < FILESLOTMAX; i++)
1450 (fileslot+i)->y -= n;
1451 while (p = min_sloty(), p->y + p->h <= 0) {
1452 mx = max_sloty();
1453 p->y = mx->y + mx->h;
1454 slotindex[p-fileslot] += FILESLOTMAX;
1455 set_slotmode(p-fileslot);
1456 redraw_window(p->win);
1457 }
1458 sort_slot();
1459 p = fileslot;
1460 for (i = 0; i < FILESLOTMAX; i++) {
1461 XMoveWindow(dsp, p->win, p->x, p->y);
1462 p++;
1463 }
1464 resize_slider();
1465 }
1466
scroll_down(n)1467 void scroll_down(n)
1468 int n;
1469 {
1470 int i;
1471 MENU *p, *mn;
1472
1473 if (scroll_pos - n < 0)
1474 n = scroll_pos;
1475 scroll_pos -= n;
1476 for (i = 0; i < FILESLOTMAX; i++)
1477 (fileslot+i)->y += n;
1478 while (p = max_sloty(), p->y >= DIRSLOTH*DIRSLOTMAX) {
1479 mn = min_sloty();
1480 p->y = mn->y - p->h;
1481 slotindex[p-fileslot] -= FILESLOTMAX;
1482 set_slotmode(p-fileslot);
1483 redraw_window(p->win);
1484 }
1485 sort_slot();
1486 for (i = FILESLOTMAX-1; i >= 0; --i) {
1487 p = fileslot+i;
1488 XMoveWindow(dsp, p->win, p->x, p->y);
1489 }
1490 resize_slider();
1491 }
1492
slotev(p,ev)1493 int slotev(p, ev)
1494 MENU *p;
1495 XEvent *ev;
1496 {
1497 int i, oldsel;
1498
1499 switch(ev->type) {
1500 case ButtonPress:
1501 oldsel = select_slot;
1502 select_slot = slotindex[p->n];
1503 set_current_name(filenamebuf+select_slot*MAXFILENAME);
1504 for (i = 0; i < FILESLOTMAX; i++) {
1505 if (slotindex[i] == oldsel) {
1506 (fileslot+i)->mode &= ~MenuModeMaskOn;
1507 redraw_window((fileslot+i)->win);
1508 }
1509 }
1510 for (i = 0; i < FILESLOTMAX; i++) {
1511 if (slotindex[i] == select_slot) {
1512 (fileslot+i)->mode |= MenuModeMaskOn;
1513 redraw_window((fileslot+i)->win);
1514 }
1515 }
1516 if (double_clicked)
1517 file_open();
1518 return 1;
1519 }
1520 return 0;
1521 }
1522
slotev2(p,ev)1523 int slotev2(p, ev)
1524 MENU *p;
1525 XEvent *ev;
1526 {
1527 switch(ev->type) {
1528 case Expose:
1529 switch(p->n) {
1530 case DIRSLOT_UP:
1531 menu_icon_center(p, ICON_up);
1532 break;
1533 case DIRSLOT_DOWN:
1534 menu_icon_center(p, ICON_down);
1535 break;
1536 }
1537 return 1;
1538 case ButtonPress:
1539 if (ev->xbutton.button == Button1)
1540 file_scroll_speed = menu_speed;
1541 else
1542 file_scroll_speed = DIRSLOTH*DIRSLOTMAX/2;
1543 }
1544 return 0;
1545 }
1546
fileev(p,ev)1547 int fileev(p, ev)
1548 MENU *p;
1549 XEvent *ev;
1550 {
1551 switch(ev->type) {
1552 case ButtonPress:
1553 switch(p->n) {
1554 case FILE_MASK:
1555 p->mode ^= MenuModeMaskOn;
1556 rescan_disp_fileslot();
1557 p->mode ^= MenuModeMaskOn;
1558 break;
1559 }
1560 break;
1561 case ButtonRelease:
1562 if (p->mode & MenuModeMaskEnter && p->mode & MenuModeMaskOn) {
1563 switch(p->n) {
1564 case FILE_OPEN:
1565 file_open();
1566 break;
1567 case FILE_SAVE:
1568 file_save();
1569 break;
1570 case FILE_REMOVE:
1571 file_remove();
1572 break;
1573 case FILE_DUMMY2:
1574 break;
1575 case FILE_OK:
1576 menu_stat_change(1, 0);
1577 break;
1578 }
1579 }
1580 break;
1581 case KeyPress:
1582 switch(p->n) {
1583 case FILE_PATH:
1584 {
1585 int i;
1586 KeySym key;
1587 char buf[16];
1588 i = XLookupString((XKeyEvent *)ev, buf, sizeof(buf)-1, &key, NULL);
1589 buf[i] -= '\0';
1590 switch(key) {
1591 case XK_KP_Enter:
1592 case XK_Return:
1593 change_directory(p->str);
1594 return 1;
1595 }
1596 }
1597 break;
1598 }
1599 break;
1600 case EnterNotify:
1601 switch(p->n) {
1602 case FILE_PATH:
1603 break;
1604 case FILE_NAME:
1605 strcpy(p->str, current_name);
1606 break;
1607 }
1608 break;
1609 case LeaveNotify:
1610 switch(p->n) {
1611 case FILE_PATH:
1612 break;
1613 case FILE_NAME:
1614 strcpy(current_name, p->str);
1615 break;
1616 }
1617 break;
1618 }
1619 return 0;
1620 }
1621
file_background()1622 void file_background()
1623 {
1624 if (slotwin[DIRSLOT_UP].mode & MenuModeMaskOn)
1625 scroll_down(file_scroll_speed);
1626 if (slotwin[DIRSLOT_DOWN].mode & MenuModeMaskOn)
1627 scroll_up(file_scroll_speed);
1628 }
1629
1630 /* End of file */
1631