1 /* $Header: /home/yav/catty/fkiss/RCS/menu.c,v 1.28 2000/09/28 07:53:23 yav Exp $
2 * fkiss menu bar
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 char id_menu[] = "$Id: menu.c,v 1.28 2000/09/28 07:53:23 yav Exp $";
21
22 #include <X11/Xos.h>
23 #include <X11/Xlib.h>
24 #include <X11/Xutil.h>
25
26 #include <stdio.h>
27 #include "config.h"
28 #include "headers.h"
29 #include "fkiss.h"
30 #include "work.h"
31 #define PUBLIC_MENU_C
32 #include "extern.h"
33
34 #if USE_UNAME
35 #include <sys/utsname.h>
36 #endif
37
38 #define BASE_XMARGIN 3
39 #define BASE_YMARGIN 1
40
41 #define MNFNC_MAX 3
42
43 Window aboutwin;
44 Window aboutokwin;
45 static int aboutokw = 32;
46 static int aboutokh;
47 static int aboutokstat;
48 static char str_ok[] = "OK";
49 static char str_setbase[] = "Set";
50 static char str_palbase[] = "Col";
51 static MW *mwfnc;
52 static int fnccnt;
53 static MW *mwset;
54 static MW *mwpal;
55 static char *fncstr[MNFNC_MAX+1] = {"?", "Quit", "Doc", NULL};
56 static Window setbasewin;
57 static Window palbasewin;
58 #define DEFAULT_MNFNCW 48 /* function menu width default */
59 static int mnfnch; /* function menu height */
60 #define MNFNCBW 1 /* function menu border width */
61 static int mnbsetw0 = 32;
62 static int mnbsetw, mnbseth;
63 #define MNBSETBW 1 /* set menu base border width */
64 static int mnbpalw0 = 32;
65 static int mnbpalw, mnbpalh;
66 #define MNBPALBW 1 /* pal menu base border width */
67 static int mnsetw = 13; /* set menu width */
68 static int mnseth;
69 #define MNSETBW 0 /* set menu border width */
70 static int mnpalw = 13; /* pal menu width */
71 static int mnpalh;
72 #define MNPALBW 0 /* pal menu border width */
73 int infow, infoh;
74 #define INFOBW 0
75 static int about_mode = 0;
76
77 static char *font_defaults[] = {
78 "-adobe-new century schoolbook-medium-r-normal--*-140-*-*-p-*-iso8859-1",
79 "-adobe-times-medium-r-normal--*-140-*-*-p-*-iso8859-1",
80 "8x16",
81 "8x13",
82 NULL};
83 static char *font8_defaults[] = {
84 "rk16", /* 8x16 Alphabet and Kana */
85 "8x16", /* 8x16 Alphabet */
86 NULL};
87 static char *font16_defaults[] = {
88 "kanji16", /* 16x16 Kanji */
89 "neckg16", /* for NEC EWS4800 */
90 "k14", /* 14x14 Kanji */
91 NULL};
92
calc_text_size(str)93 int calc_text_size(str)
94 char *str;
95 {
96 XCharStruct overall;
97 int direction_hint;
98
99 XTextExtents(fsp, str, strlen(str), &direction_hint,
100 &font_ascent, &font_descent, &overall);
101 return overall.rbearing - overall.lbearing;
102 }
103
load_fs(name,list)104 XFontStruct *load_fs(name, list)
105 char **name;
106 char **list;
107 {
108 XFontStruct *p;
109
110 do {
111 if (*name != NULL) {
112 p = XLoadQueryFont(dsp, *name);
113 if (p != NULL)
114 return p;
115 msg("W font ``%s'' not found.\n", *name);
116 }
117 *name = *list++;
118 } while (*name != NULL);
119 return NULL;
120 }
121
load_font_sub(p,name,list,fromgc,ngc)122 void load_font_sub(p, name, list, fromgc, ngc)
123 XFontStruct **p;
124 char **name;
125 char **list;
126 int fromgc;
127 int ngc;
128 {
129 int i;
130
131 *p = load_fs(name, list);
132 if (*p == NULL) {
133 msg("W use CG default font.\n");
134 } else {
135 for (i = 0; i < ngc; i++)
136 XSetFont(dsp, sysgc[fromgc+i], (*p)->fid);
137 }
138 }
139
load_font()140 void load_font()
141 {
142 load_font_sub(&fsp, &str_font, font_defaults, 0, SGC_MAX);
143 if (fsp != NULL)
144 calc_text_size("Sample string");
145 mnh = font_ascent + font_descent + MNFNCBW*2 + 2 + BASE_YMARGIN*2;
146 load_font_sub(&fsp8, &str_font8, font8_defaults, SGC_T8, 1);
147 load_font_sub(&fsp16, &str_font16, font16_defaults, SGC_T16, 1);
148 }
149
change_menu_status(win,mode)150 void change_menu_status(win, mode)
151 Window win;
152 int mode;
153 {
154 XSetWindowBackground(dsp, win, (mode & 2) ? spx[SPX_FG] : spx[SPX_BT]);
155 XClearArea(dsp, win, 0, 0, 0, 0, True);
156 }
157
set_menu_window_attributes()158 void set_menu_window_attributes()
159 {
160 XSetWindowAttributes atr;
161
162 XSetWindowBorder(dsp, mnwin, spx[SPX_FG]);
163 XSetWindowBackground(dsp, mnwin, spx[SPX_MN]);
164 if (spx[SPX_MN] == spx[SPX_BG]) {
165 atr.background_pixmap =
166 XCreatePixmapFromBitmapData(dsp, topwin, (char *)hatch_ptrn, 8, 8,
167 spx[SPX_FG], spx[SPX_BG],
168 screen_depth);
169 XChangeWindowAttributes(dsp, mnwin, CWBackPixmap, &atr);
170 XFreePixmap(dsp, atr.background_pixmap);
171 }
172 XSetWindowBorder(dsp, aboutwin, spx[SPX_FG]);
173 if (iconp != None) {
174 atr.background_pixmap =
175 XCreatePixmap(dsp, aboutwin, iconw*2, iconh*2, screen_depth);
176 XFillRectangle(dsp, atr.background_pixmap, sysgc[SGC_IN1],
177 0, 0, iconw*2, iconh*2);
178 XCopyPlane(dsp, iconp, atr.background_pixmap, sysgc[SGC_IN0],
179 0, 0, iconw, iconh, 0, 0, 1);
180 XCopyPlane(dsp, iconp, atr.background_pixmap, sysgc[SGC_IN0],
181 0, 0, iconh, iconh, iconw, iconh, 1);
182 XChangeWindowAttributes(dsp, aboutwin, CWBackPixmap, &atr);
183 XFreePixmap(dsp, atr.background_pixmap);
184 }
185 }
186
create_menuwins(x,y,w,h,b,mask)187 Window create_menuwins(x, y, w, h, b, mask)
188 int x;
189 int y;
190 int w;
191 int h;
192 int b;
193 long mask;
194 {
195 Window win;
196
197 win = XCreateSimpleWindow(dsp, mnwin, x, y, w, h, b, spx[SPX_FG], spx[SPX_BT]);
198 XSelectInput(dsp, win, mask);
199 return win;
200 }
201
create_button_window(x,y,w,h,b)202 Window create_button_window(x, y, w, h, b)
203 int x;
204 int y;
205 int w;
206 int h;
207 int b;
208 {
209 return create_menuwins(x, y, w, h, b,
210 OwnerGrabButtonMask|
211 ExposureMask|ButtonPressMask|ButtonReleaseMask|
212 EnterWindowMask|LeaveWindowMask);
213 }
214
calc_menu_width(str)215 int calc_menu_width(str)
216 char *str;
217 {
218 int i;
219
220 i = calc_text_size(str);
221 return i + i/3 + 2;
222 }
223
calc_menu_geometry()224 void calc_menu_geometry()
225 {
226 int i, x;
227
228 mnfnch = mnh - MNFNCBW*2 - BASE_YMARGIN*2;
229 for (i = 0; i < fnccnt; i++) {
230 if (fsp != NULL)
231 (mwfnc+i)->w = calc_menu_width(fncstr[i]);
232 else
233 (mwfnc+i)->w = DEFAULT_MNFNCW;
234 if ((mwfnc+i)->w < mnfnch)
235 (mwfnc+i)->w = mnfnch;
236 }
237 if (fsp != NULL) {
238 aboutokw = calc_menu_width(str_ok);
239 mnbsetw0 = calc_menu_width(str_setbase);
240 mnbpalw0 = calc_menu_width(str_palbase);
241 }
242 mnbsetw = mnbsetw0 + (mnsetw + MNSETBW*2)*setcnt;
243 mnbseth = mnh - MNBSETBW*2 - BASE_YMARGIN*2;
244 mnbpalw = mnbpalw0 + (mnpalw + MNPALBW*2)*palcnt;
245 mnbpalh = mnh - MNBPALBW*2 - BASE_YMARGIN*2;
246 mnseth = mnbseth - MNSETBW*2;
247 mnpalh = mnbseth - MNPALBW*2;
248 infoh = mnh - INFOBW*2 - BASE_YMARGIN*2;
249 x = BASE_XMARGIN;
250 for (i = 0; i < fnccnt; i++)
251 x += (mwfnc+i)->w + MNFNCBW*2 + BASE_XMARGIN;
252 x += mnbsetw + MNBSETBW*2 + BASE_XMARGIN;
253 x += mnbpalw + MNBPALBW*2 + BASE_XMARGIN;
254 infow = mnw - (x + INFOBW*2 + BASE_XMARGIN);
255 if (infow < 1)
256 infow = 1;
257 }
258
menu_resize()259 void menu_resize()
260 {
261 calc_menu_geometry();
262 XResizeWindow(dsp, infowin, infow, infoh);
263 }
264
alloc_mw(n)265 MW *alloc_mw(n)
266 int n;
267 {
268 int i;
269 MW *p;
270
271 p = (MW *)ks_malloc(sizeof(MW)*(n+1));
272 bzero((char *)p, sizeof(MW)*(n+1));
273 for (i = 0; i < n; i++)
274 (p+i)->n = i;
275 (p+i)->n = -1; /* End mark */
276 return p;
277 }
278
create_set_menu()279 void create_set_menu()
280 {
281 int i, x, y;
282 XSetWindowAttributes atr;
283
284 for (fnccnt = 0; fncstr[fnccnt] != NULL; fnccnt++)
285 ;
286 mwfnc = alloc_mw(fnccnt);
287 calc_menu_geometry();
288 x = BASE_XMARGIN;
289 y = BASE_YMARGIN;
290 for (i = 0; i < fnccnt; i++) {
291 (mwfnc+i)->win = create_button_window(x, y, (mwfnc+i)->w, mnfnch, MNFNCBW);
292 x += (mwfnc+i)->w + MNFNCBW*2 + BASE_XMARGIN;
293 }
294 setbasewin = create_menuwins(x, y, mnbsetw, mnbseth, MNBSETBW, ExposureMask);
295 mwset = alloc_mw(setcnt);
296 for (i = 0; i < setcnt; i++)
297 if (active_set[i])
298 (mwset+i)->win =
299 create_button_window(x + MNBSETBW + mnbsetw0 + (mnsetw+MNSETBW*2)*i,
300 MNBSETBW + y,
301 mnsetw, mnseth, MNSETBW);
302 x += mnbsetw + MNBSETBW*2 + BASE_XMARGIN;
303 palbasewin = create_menuwins(x, y, mnbpalw, mnbpalh, MNBPALBW, ExposureMask);
304 mwpal = alloc_mw(palcnt);
305 for (i = 0; i < palcnt; i++)
306 (mwpal+i)->win =
307 create_button_window(x + MNBPALBW + mnbpalw0 + (mnpalw+MNPALBW*2)*i,
308 MNBPALBW + y,
309 mnpalw, mnpalh, MNPALBW);
310 x += mnbpalw + MNBPALBW*2 + BASE_XMARGIN;
311 XMapRaised(dsp, mnwin);
312 XMapSubwindows(dsp, mnwin);
313 infowin = XCreateSimpleWindow(dsp, mnwin, x, y,
314 infow, infoh, INFOBW,
315 spx[SPX_FG], spx[SPX_MN]);
316 XSelectInput(dsp, infowin, ExposureMask);
317 /* About ok menu open */
318 aboutokh = font_ascent + font_descent + 2;
319 aboutokstat = 0;
320 aboutokwin = XCreateSimpleWindow(dsp, aboutwin,
321 vieww-(aboutokw+MNFNCBW*2+1),
322 viewh-(aboutokh+MNFNCBW*2+1),
323 aboutokw, aboutokh, MNFNCBW,
324 spx[SPX_FG], spx[SPX_BT]);
325 XSelectInput(dsp, aboutokwin,
326 OwnerGrabButtonMask|
327 ExposureMask|ButtonPressMask|ButtonReleaseMask|
328 EnterWindowMask|LeaveWindowMask);
329 atr.win_gravity = SouthEastGravity;
330 XChangeWindowAttributes(dsp, aboutokwin, CWWinGravity, &atr);
331 XMapSubwindows(dsp, aboutwin);
332 }
333
which_winlist(win,p)334 int which_winlist(win, p)
335 Window win;
336 MW *p;
337 {
338 while (p->n >= 0) {
339 if (win == p->win)
340 break;
341 p++;
342 }
343 return p->n;
344 }
345
draw_menu_string(win,mode,w,h,leftm,topm,str)346 void draw_menu_string(win, mode, w, h, leftm, topm, str)
347 Window win;
348 int mode;
349 int w;
350 int h;
351 int leftm;
352 int topm;
353 char *str;
354 {
355 GC gc;
356
357 gc = ((mode & 2) ? sysgc[SGC_BT1] : sysgc[SGC_BT0]);
358 XDrawString(dsp, win, gc, leftm, topm + font_ascent, str, strlen(str));
359 if (mode & 1)
360 XDrawRectangle(dsp, win, gc, 0, 0, w-1, h-1);
361 }
362
draw_button(win,mode,w,h,str)363 void draw_button(win, mode, w, h, str)
364 Window win;
365 int mode;
366 int w;
367 int h;
368 char *str;
369 {
370 int strwidth;
371
372 strwidth = calc_text_size(str);
373 draw_menu_string(win, mode, w, h,
374 (w - strwidth)/2, (h - (font_ascent+font_descent))/2, str);
375 }
376
377 #define TAB_STOP_WIDTH 8
378
379 /* convert tab to spaces */
expand(dst,src,len)380 void expand(dst, src, len)
381 unsigned char *dst; /* destination buffer to store */
382 unsigned char *src; /* source string */
383 int len; /* dst size */
384 {
385 int i, pos;
386
387 pos = 0; /* initial column 0 */
388 while (*src) {
389 if (len <= 1)
390 break; /* no space to store, abort */
391 switch(*src) {
392 case '\t':
393 i = TAB_STOP_WIDTH - (pos % TAB_STOP_WIDTH);
394 while (i--) {
395 *dst++ = ' ';
396 pos++;
397 if (--len <= 1)
398 break; /* no space to store, abort */
399 }
400 break;
401 case '\033':
402 pos -= 3;
403 /* FALL THROUGH */
404 default:
405 *dst++ = *src;
406 pos++;
407 --len;
408 break;
409 }
410 src++;
411 }
412 *dst = '\0';
413 }
414
415 #define FONT8_WIDTH 8
416 #define FONT16_WIDTH 16
417
dup_char2b(dst,src,len)418 void dup_char2b(dst, src, len)
419 XChar2b *dst;
420 unsigned char *src;
421 int len;
422 {
423 while (len--) {
424 dst->byte1 = *src++;
425 dst->byte2 = *src++;
426 dst++;
427 }
428 }
429
430 #define DRAWSTR_MAX 1024
431
draw_str16(d,x,y,str,len,kanji)432 int draw_str16(d, x, y, str, len, kanji)
433 Drawable d; /* target window or pixmap (None:NOT draw) */
434 int x, y; /* position */
435 unsigned char *str; /* drawing string */
436 int len; /* byte count */
437 int kanji; /* kanji flag */
438 {
439 XChar2b buf[DRAWSTR_MAX];
440
441 if (kanji) {
442 len /= 2;
443 if (len > DRAWSTR_MAX)
444 len = DRAWSTR_MAX;
445 dup_char2b(buf, str, len);
446 if (d != None) {
447 if (spx[SPX_BG2] == spx[SPX_FG])
448 XDrawImageString16(dsp, d, sysgc[SGC_T16], x, y, buf, len);
449 else
450 XDrawString16(dsp, d, sysgc[SGC_T16], x, y, buf, len);
451 }
452 len *= FONT16_WIDTH;
453 } else {
454 if (d != None) {
455 if (spx[SPX_BG2] == spx[SPX_FG])
456 XDrawImageString(dsp, d, sysgc[SGC_T8], x, y, (char *)str, len);
457 else
458 XDrawString(dsp, d, sysgc[SGC_T8], x, y, (char *)str, len);
459 }
460 len *= FONT8_WIDTH;
461 }
462 return len; /* string width (pixel) */
463 }
464
465 /* draw ASCII English and Shift-JIS coed Japanese text
466 * output to specified drawable
467 * but, if None drawable is specified, strings is NOT draw.
468 */
draw_string(d,x,y,str)469 int draw_string(d, x, y, str)
470 Drawable d; /* target drawable (None: NOT draw) */
471 int x, y; /* position */
472 char *str; /* drawing string */
473 {
474 unsigned char c, c2;
475 unsigned short code;
476 Bool inkanji;
477 int buffered_count;
478 int i, w;
479 unsigned char *p;
480 unsigned char buf[DRAWSTR_MAX];
481 unsigned char buf2[DRAWSTR_MAX];
482
483 expand(buf, (unsigned char *)str, sizeof(buf));
484 buffered_count = w = 0;
485 inkanji = False;
486 p = buf;
487 while ((c = *p++) != '\0') {
488 c2 = *p;
489 if (is_sjis_1st(c) && is_sjis_2nd(c2)) {
490 if (!inkanji) {
491 /* flush ASCII text */
492 i = draw_str16(d, x, y, buf2, buffered_count, 0);
493 w += i;
494 x += i;
495 buffered_count = 0;
496 }
497 code = (c << 8) + c2;
498 code = ysjis2jis(code);
499 buf2[buffered_count++] = code >> 8;
500 buf2[buffered_count++] = code;
501 p++;
502 inkanji = True;
503 } else {
504 if (inkanji) {
505 /* flush Japanese KANJI text */
506 i = draw_str16(d, x, y, buf2, buffered_count, 1);
507 w += i;
508 x += i;
509 buffered_count = 0;
510 }
511 buf2[buffered_count++] = c;
512 inkanji = False;
513 }
514 }
515 if (buffered_count) {
516 i = draw_str16(d, x, y, buf2, buffered_count, inkanji);
517 w += i;
518 }
519 return w; /* string width (pixel) */
520 }
521
draw_data_comment()522 void draw_data_comment()
523 {
524 int i, y;
525
526 y = 0;
527 for (i = 0; i < cnf_comment_cnt; i++) {
528 y += 16; /* add font ascent */
529 draw_string(aboutwin, 0, y, *(cnf_comment+i));
530 y += 0; /* font descent + line margin */
531 }
532 }
533
534 #define ABOUT_LINE_MARGIN 2
535
draw_about_line(y,str)536 void draw_about_line(y, str)
537 int *y;
538 char *str;
539 {
540 int i, x;
541
542 x = (vieww - calc_text_size(str))/2;
543 i = strlen(str);
544 *y += font_ascent;
545 if (spx[SPX_BG2] == spx[SPX_FG])
546 XDrawImageString(dsp, aboutwin, sysgc[SGC_GEN], x, *y, str, i);
547 else
548 XDrawString(dsp, aboutwin, sysgc[SGC_GEN], x, *y, str, i);
549 *y += font_descent+ABOUT_LINE_MARGIN;
550 }
551
552 #if USE_UNAME
get_client_info()553 char *get_client_info()
554 {
555 char buf[1024];
556 static char *r = NULL;
557 struct utsname kernel_name;
558
559 if (r == NULL) {
560 uname(&kernel_name);
561 sprintf(buf, "Client: %s (%s %s %s)",
562 kernel_name.nodename,
563 kernel_name.sysname,
564 kernel_name.release,
565 kernel_name.machine);
566 r = ks_strdup(buf);
567 }
568 return r;
569 }
570 #else /* USE_UNAME */
pipe_exec(cmd,buf,len)571 char *pipe_exec(cmd, buf, len)
572 char *cmd;
573 char *buf;
574 int len;
575 {
576 char *p;
577 FILE *fp;
578
579 p = NULL;
580 fp = popen(cmd, "r");
581 if (fp != NULL) {
582 if (fgets(buf, len, fp) != NULL) {
583 cut_crlf(buf);
584 p = buf;
585 }
586 pclose(fp);
587 }
588 return p;
589 }
590
get_client_info()591 char *get_client_info()
592 {
593 char *p;
594 char *s;
595 char buf[1024];
596 char buf1[256];
597 char buf2[256];
598 static char *r = NULL;
599 static char unknown_name[] = "(unknown)";
600
601 if (r == NULL) {
602 p = pipe_exec("uname -n", buf1, sizeof(buf1));
603 if (p == NULL)
604 p = getenv("HOSTNAME");
605 if (p == NULL)
606 p = getenv("HOST");
607 if (p == NULL)
608 p = unknown_name;
609 s = pipe_exec("uname -smr", buf2, sizeof(buf2));
610 if (s == NULL)
611 s = getenv("HOSTTYPE");
612 if (s == NULL)
613 s = unknown_name;
614 sprintf(buf, "Client: %s (%s)", p, s);
615 r = ks_strdup(buf);
616 }
617 return r;
618 }
619 #endif /* USE_UNAME */
620
621 /* call after display connection is opened! */
get_server_info()622 char *get_server_info()
623 {
624 char buf[1024];
625 static char *r = NULL;
626
627 if (r == NULL) {
628 sprintf(buf, "Server: %s (%s)", DisplayString(dsp), ServerVendor(dsp));
629 r = ks_strdup(buf);
630 }
631 return r;
632 }
633
get_visual_info()634 char *get_visual_info()
635 {
636 int i;
637 char *p;
638 char buf[1024];
639 static char *r = NULL;
640 static struct {
641 int class;
642 char *name;
643 } vistbl[] = {
644 {StaticGray, "StaticGray"},
645 {GrayScale, "GrayScale"},
646 {StaticColor, "StaticColor"},
647 {PseudoColor, "PseudoColor"},
648 {TrueColor, "TrueColor"},
649 {DirectColor, "DirectColor"},
650 {-1, NULL}
651 };
652
653 if (r == NULL) {
654 p = "(unknown)";
655 for (i = 0; vistbl[i].name != NULL; i++) {
656 if (vis->class == vistbl[i].class) {
657 p = vistbl[i].name;
658 break;
659 }
660 }
661 if (vis->class == TrueColor || vis->class == DirectColor) {
662 sprintf(buf, "Visual: %s (depth %d, R:%08lx, G:%08lx, B:%08lx)",
663 p, screen_depth,
664 vis->red_mask, vis->green_mask, vis->blue_mask);
665 } else {
666 sprintf(buf, "Visual: %s (depth %d)", p, screen_depth);
667 }
668 r = ks_strdup(buf);
669 }
670 return r;
671 }
672
673 /* call after read_cells */
get_cell_info()674 char *get_cell_info()
675 {
676 char buf[1024];
677 static char *r = NULL;
678
679 if (r == NULL) {
680 sprintf(buf, "Total %d cells, %d objects, %d marks",
681 celcnt, objcnt2, objcnt);
682 r = ks_strdup(buf);
683 }
684 return r;
685 }
686
draw_aboutwin()687 void draw_aboutwin()
688 {
689 int i, y;
690 char buf[1024];
691
692 if (about_mode == 1) {
693 draw_data_comment();
694 return;
695 }
696 y = (viewh - ((font_ascent + font_descent + ABOUT_LINE_MARGIN) * (12+arcfilecnt)))/3;
697 draw_about_line(&y, str_fullname);
698 sprintf(buf, "Version %s", str_version);
699 draw_about_line(&y, buf);
700 sprintf(buf, "written by %s", str_author);
701 draw_about_line(&y, buf);
702 draw_about_line(&y, get_client_info());
703 draw_about_line(&y, get_server_info());
704 draw_about_line(&y, get_visual_info());
705 draw_about_line(&y, "");
706 for (i = 0; i < arcfilecnt; i++) {
707 sprintf(buf, "Archive %d: %s", i+1, *(arcfilelist+i));
708 draw_about_line(&y, buf);
709 }
710 sprintf(buf, "Configuration file: %s", conf_file);
711 draw_about_line(&y, buf);
712 sprintf(buf, "Size: %dx%d (%dx%d)", imgw, imgh, imgw0, imgh0);
713 draw_about_line(&y, buf);
714 sprintf(buf, "View port: %dx%d%+d%+d",
715 vieww, viewh, -imgx-imgbw, -imgy-imgbw);
716 draw_about_line(&y, buf);
717 draw_about_line(&y, get_cell_info());
718 sprintf(buf, "Motion compress: %d", motion_compress);
719 draw_about_line(&y, buf);
720 sprintf(buf, "%s%s", infostr0, infostr);
721 draw_about_line(&y, buf);
722 }
723
change_menu_func(i)724 void change_menu_func(i)
725 int i;
726 {
727 int s;
728
729 s = (mwfnc+i)->st;
730 switch(i) {
731 case 0: /* About */
732 if (++about_mode > 2)
733 about_mode = 0;
734 if (about_mode) {
735 XMapRaised(dsp, aboutwin);
736 XClearArea(dsp, aboutwin, 0, 0, 0, 0, True);
737 s |= 2;
738 } else {
739 XUnmapWindow(dsp, aboutwin);
740 s &= ~2;
741 }
742 break;
743 case 1: /* Quit */
744 s ^= 2;
745 quit_flag = !quit_flag;
746 break;
747 case 2: /* Doc */
748 /* Quick and darty hack! Not smart, Sorry */
749 s |= 2;
750 change_menu_status((mwfnc+i)->win, (mwfnc+i)->st = s);
751 browse_document();
752 s = 0;
753 break;
754 }
755 change_menu_status((mwfnc+i)->win, (mwfnc+i)->st = s);
756 }
757
expose_menu(p)758 void expose_menu(p)
759 XExposeEvent *p;
760 {
761 int i;
762 Window win;
763 char buf[16];
764
765 if (p->count)
766 return;
767 win = p->window;
768 if (win == aboutwin) {
769 draw_aboutwin();
770 } else if (win == aboutokwin) {
771 draw_button(win, aboutokstat, aboutokw, aboutokh, str_ok);
772 } else if (win == infowin) {
773 draw_button(win, 0, infow, infoh, infostr);
774 } else if (win == setbasewin) {
775 draw_button(win, 0, mnbsetw0, mnbseth, str_setbase);
776 } else if (win == palbasewin) {
777 draw_button(win, 0, mnbpalw0, mnbpalh, str_palbase);
778 } else {
779 i = which_winlist(win, mwfnc);
780 if (i >= 0)
781 draw_button((mwfnc+i)->win, (mwfnc+i)->st, (mwfnc+i)->w, mnfnch, fncstr[i]);
782 i = which_winlist(win, mwset);
783 if (i >= 0) {
784 sprintf(buf, "%d", i);
785 draw_button(win, (mwset+i)->st | (i == cset ? 2 : 0),
786 mnsetw, mnseth, buf);
787 }
788 i = which_winlist(win, mwpal);
789 if (i >= 0) {
790 sprintf(buf, "%d", i);
791 draw_button(win, (mwpal+i)->st | (i == cpal ? 2 : 0),
792 mnpalw, mnpalh, buf);
793 }
794 }
795 }
796
797 /* Press or Release mouse buttons */
press_menu(p)798 void press_menu(p)
799 XButtonEvent *p;
800 {
801 int i;
802 Window win;
803
804 win = p->window;
805 if (win == aboutokwin) {
806 if (p->type == ButtonRelease && (aboutokstat & 1)) {
807 change_menu_func(0);
808 }
809 }
810 i = which_winlist(win, mwfnc);
811 switch (i) {
812 case 0:
813 case 1:
814 if (p->type == ButtonRelease)
815 change_menu_func(i);
816 break;
817 case 2:
818 if (p->type == ButtonPress)
819 change_menu_func(i);
820 break;
821 }
822 if (p->type == ButtonRelease) {
823 i = which_winlist(win, mwset);
824 if (i >= 0)
825 change_setpal(i, -1);
826 i = which_winlist(win, mwpal);
827 if (i >= 0)
828 change_setpal(-1, i);
829 }
830 }
831
enter_mw(win,p)832 int enter_mw(win, p)
833 Window win;
834 MW *p;
835 {
836 int i;
837
838 i = which_winlist(win, p);
839 if (i >= 0)
840 change_menu_status(win, (p+i)->st |= 1);
841 return i;
842 }
843
enter_menu(p)844 void enter_menu(p)
845 XCrossingEvent *p;
846 {
847 Window win;
848
849 win = p->window;
850 if (win == aboutokwin)
851 change_menu_status(win, aboutokstat |= 1);
852 enter_mw(win, mwfnc);
853 enter_mw(win, mwset);
854 enter_mw(win, mwpal);
855 }
856
leave_mw(win,p)857 int leave_mw(win, p)
858 Window win;
859 MW *p;
860 {
861 int i;
862
863 i = which_winlist(win, p);
864 if (i >= 0)
865 change_menu_status(win, (p+i)->st &= ~1);
866 return i;
867 }
868
leave_menu(p)869 void leave_menu(p)
870 XCrossingEvent *p;
871 {
872 Window win;
873
874 win = p->window;
875 if (win == aboutokwin)
876 change_menu_status(win, aboutokstat &= ~1);
877 leave_mw(win, mwfnc);
878 leave_mw(win, mwset);
879 leave_mw(win, mwpal);
880 }
881
menu_setpal_change()882 void menu_setpal_change()
883 {
884 int i;
885
886 for (i = 0; i < setcnt; i++) {
887 if (active_set[i]) {
888 if (i == cset) {
889 change_menu_status((mwset+i)->win, (mwset+i)->st |= 2);
890 } else {
891 if ((mwset+i)->st & 2)
892 change_menu_status((mwset+i)->win, (mwset+i)->st &= ~2);
893 }
894 }
895 }
896 for (i = 0; i < palcnt; i++) {
897 if (i == cpal) {
898 change_menu_status((mwpal+i)->win, (mwpal+i)->st |= 2);
899 } else {
900 if ((mwpal+i)->st & 2)
901 change_menu_status((mwpal+i)->win, (mwpal+i)->st &= ~2);
902 }
903 }
904 }
905
906 /* End of file */
907