1 /* $Header: /home/yav/xpx/RCS/main.c,v 1.62 1996/04/24 23:08:27 yav Exp $
2 * xpx main routine
3 * written by yav (UHD98984@pcvan.or.jp)
4 */
5
6 #include <X11/Xlib.h>
7 #include <X11/Xutil.h>
8 #include <X11/cursorfont.h>
9 #include <X11/keysym.h>
10
11 #include "headers.h"
12 #include "xpx.h"
13 #include "work.h"
14 #include "menudef.h"
15 #include "editdef.h"
16 #define PUBLIC_MAIN_C
17 #include "extern.h"
18
19 #define COLSETX (PALSETX+32)
20 #define COLSETY PALSETY
21
22 #define INTERNAL_ICONPIXMAP 1
23
24 /* #define DEFAULT_FONT "8x13" */
25 /* #define DEFAULT_BOLD_FONT "8x13bold" */
26 #define DEFAULT_FONT "-adobe-times-medium-r-normal--14-*"
27 #define DEFAULT_BOLD_FONT "-adobe-times-bold-r-normal--14-*"
28
29
30 char rcsid_main[] = "$Id: main.c,v 1.62 1996/04/24 23:08:27 yav Exp $";
31 char windowname[128];
32 static char *str_display = "";
33 static char *str_geometry = "";
34 static char *str_background = "Wheat";
35 static char *str_foreground = "Black";
36 static char *str_border = "Black";
37 static char *str_font = NULL;
38 static char *str_fontbold = NULL;
39 static int use_private_color = True;
40 static int use_private_cmap = False;
41 static char grid_dash_list[2] = {1,1};
42 static Pixmap xpxiconpixmap = None;
43 #ifdef INTERNAL_ICONPIXMAP
44 #include "icon.xbm"
45 #endif
46
47 #include "cursor0.xbm"
48 #include "cursor1.xbm"
49
usage()50 void usage()
51 {
52 fprintf(stderr, "* %s %s *\n", myname, xpx_version);
53 fprintf(stderr, "written by yav (UHD98984@pcvan.or.jp)\n");
54 fprintf(stderr, "usage : %s [options] col.kcf rei.cel\n", myname);
55 exit(1);
56 }
57
filename(name)58 char *filename(name)
59 char *name;
60 {
61 char *p;
62
63 if (name[0] == '\0')
64 return "*Noname*";
65 p = strrchr(name, '/');
66 if (p != NULL)
67 name = p+1;
68 return name;
69 }
70
basefilename(name)71 char *basefilename(name)
72 char *name;
73 {
74 char *p;
75
76 name = filename(name);
77 p = strrchr(name, '.');
78 if (p != NULL)
79 *p = '\0';
80 return name;
81 }
82
83
84 #define col8to32(x) (((x)<<24)|((x)<<16)|((x)<<8)|(x))
calcol(col,p)85 void calcol(col, p)
86 XColor *col;
87 COL *p;
88 {
89 col->red = col8to32(p->rgb.red);
90 col->green = col8to32(p->rgb.green);
91 col->blue = col8to32(p->rgb.blue);
92 col->flags = DoRed|DoGreen|DoBlue;
93 }
94
get_color_sub(i,p)95 int get_color_sub(i, p)
96 int i;
97 COL *p;
98 {
99 XColor col;
100 unsigned long plane_masks[1];
101 int r;
102
103 r = 0;
104 calcol(&col, p);
105 if (*(coltbl+i) & CM_PRIVATE) {
106 col.pixel = *(pixtbl+i);
107 XStoreColor(dsp, cmap, &col);
108 } else {
109 if (use_private_color &&
110 XAllocColorCells(dsp, cmap, False,
111 plane_masks, 0, &col.pixel, 1)) {
112 XStoreColor(dsp, cmap, &col);
113 *(coltbl+i) = CM_ALLOCED | CM_UPDATING | CM_PRIVATE;
114 alloced_private_color++;
115 alloced_color++;
116 } else if (XAllocColor(dsp, cmap, &col)) {
117 *(coltbl+i) = CM_ALLOCED | CM_UPDATING;
118 alloced_color++;
119 } else {
120 r = 1; /* alloc error! */
121 col.pixel = bg;
122 missed_color++;
123 }
124 *(pixtbl+i) = col.pixel;
125 }
126 return r;
127 }
128
get_color(p,n)129 int get_color(p, n)
130 COL *p;
131 int n;
132 {
133 int i;
134
135 for (i = 0; i < n; i++) {
136 if (get_color_sub(i, p))
137 message("!color %d %d %d cannot allocated!\n",
138 p->rgb.red, p->rgb.green, p->rgb.blue);
139 if (i < MAXCOLSET) {
140 XSetForeground(dsp, colgc[i], *(pixtbl+i));
141 update_colmenu(i);
142 }
143 p++;
144 }
145 return i;
146 }
147
148 /* return number of allocated color */
get_requested_colors()149 int get_requested_colors()
150 {
151 int i, r;
152
153 r = 0;
154 for (i = 0; i < MAXCOLSET*MAXPALSET; i++) {
155 if (*(coltbl+i) & CM_REQUEST) {
156 if (get_color_sub(i, color_buf+i) == 0)
157 r++;
158 *(coltbl+i) &= ~CM_REQUEST;
159 }
160 }
161 return r;
162 }
163
request_color(p)164 int request_color(p)
165 COL *p;
166 {
167 int i;
168
169 for (i = 0; i < MAXCOLSET*MAXPALSET; i++) {
170 if (!(*(coltbl+i) & (CM_ALLOCED|CM_REQUEST))) {
171 *(coltbl+i) = CM_REQUEST;
172 (color_buf+i)->rgb.red = p->rgb.red;
173 (color_buf+i)->rgb.green = p->rgb.green;
174 (color_buf+i)->rgb.blue = p->rgb.blue;
175 return i;
176 }
177 }
178 return -1;
179 }
180
request_color2(i,p)181 void request_color2(i, p)
182 int i;
183 COL *p;
184 {
185 *(coltbl+i) = CM_REQUEST;
186 (color_buf+i)->rgb.red = p->rgb.red;
187 (color_buf+i)->rgb.green = p->rgb.green;
188 (color_buf+i)->rgb.blue = p->rgb.blue;
189 }
190
init_color()191 void init_color()
192 {
193 alloced_color = alloced_private_color = missed_color = 0;
194 bzero(coltbl, MAXPALSET*MAXCOLSET);
195 bzero(colmask, MAXPALSET*MAXCOLSET);
196 }
197
198 /* free common color cells */
free_color()199 void free_color()
200 {
201 int i;
202
203 for (i = 0; i < MAXPALSET*MAXCOLSET; i++) {
204 if ((*(coltbl+i) & CM_ALLOCED)&&!(*(coltbl+i) & CM_PRIVATE)) {
205 XFreeColors(dsp, cmap, pixtbl+i, 1, 0);
206 --alloced_color;
207 *(coltbl+i) = 0;
208 }
209 }
210 }
211
212 /* free common and private color cells */
free_color_all()213 void free_color_all()
214 {
215 int i;
216
217 for (i = 0; i < MAXPALSET*MAXCOLSET; i++) {
218 if (*(coltbl+i) & CM_ALLOCED) {
219 XFreeColors(dsp, cmap, pixtbl+i, 1, 0);
220 --alloced_color;
221 if (*(coltbl+i) & CM_PRIVATE)
222 --alloced_private_color;
223 *(coltbl+i) = 0;
224 }
225 }
226 }
227
init_color_buf()228 void init_color_buf()
229 {
230 int i, j;
231 typedef struct {
232 unsigned char r;
233 unsigned char g;
234 unsigned char b;
235 } RGBDATA;
236 static RGBDATA initdata[16] = {
237 { 0, 0, 0},{ 0, 0,255},{255, 0, 0},{255, 0,255},
238 { 0,255, 0},{ 0,255,255},{255,255, 0},{127,127,127},
239 { 64, 64, 64},{127,127,255},{255,127,127},{255,127,255},
240 {127,255,127},{127,255,255},{255,255,127},{255,255,255}
241 };
242 #define GRAY(n) {n*17, n*17, n*17}
243 static RGBDATA initdata1[16] = {
244 GRAY(15), GRAY(0), GRAY(1), GRAY(2),
245 GRAY(3), GRAY(4), GRAY(5), GRAY(6),
246 GRAY(7), GRAY(8), GRAY(9), GRAY(10),
247 GRAY(11), GRAY(12), GRAY(13), GRAY(14)
248 };
249 static RGBDATA initdata2[16] = {
250 GRAY(0), GRAY(1), GRAY(2), GRAY(3),
251 GRAY(4), GRAY(5), GRAY(6), GRAY(7),
252 GRAY(8), GRAY(9), GRAY(10), GRAY(11),
253 GRAY(12), GRAY(13), GRAY(14), GRAY(15)
254 };
255
256 for (i = 0; i < MAXPALSET; i++) {
257 for (j = 0; j < MAXCOLSET; j++) {
258 (color_buf+MAXCOLSET*i+j)->rgb.padding = 0;
259 (color_buf+MAXCOLSET*i+j)->rgb.blue = initdata[j].b;
260 (color_buf+MAXCOLSET*i+j)->rgb.red = initdata[j].r;
261 (color_buf+MAXCOLSET*i+j)->rgb.green = initdata[j].g;
262 }
263 }
264 for (j = 0; j < MAXCOLSET; j++) {
265 (color_buf+MAXCOLSET+j)->rgb.padding = 0;
266 (color_buf+MAXCOLSET+j)->rgb.blue = initdata1[j].b;
267 (color_buf+MAXCOLSET+j)->rgb.red = initdata1[j].r;
268 (color_buf+MAXCOLSET+j)->rgb.green = initdata1[j].g;
269 }
270 for (j = 0; j < MAXCOLSET; j++) {
271 (color_buf+MAXCOLSET*2+j)->rgb.padding = 0;
272 (color_buf+MAXCOLSET*2+j)->rgb.blue = initdata2[j].b;
273 (color_buf+MAXCOLSET*2+j)->rgb.red = initdata2[j].r;
274 (color_buf+MAXCOLSET*2+j)->rgb.green = initdata2[j].g;
275 }
276 #undef GRAY
277 }
278
alloc_colorbuf()279 int alloc_colorbuf()
280 {
281 color_buf = (COL *)malloc(sizeof(COL)*MAXPALSET*MAXCOLSET);
282 pixtbl = (unsigned long *)malloc(sizeof(unsigned long)*MAXPALSET*MAXCOLSET);
283 coltbl = (char *)malloc(MAXPALSET*MAXCOLSET);
284 colmask = (char *)malloc(MAXPALSET*MAXCOLSET);
285 return (color_buf == NULL || pixtbl == NULL ||
286 coltbl == NULL || colmask == NULL);
287 }
288
key_event(ev)289 void key_event(ev)
290 XEvent *ev;
291 {
292 int i, c;
293 char buf[32];
294 KeySym key;
295 XComposeStatus cs;
296 static struct {KeySym sym; int func;} functbl[] = {
297 {XK_Left, '4'},
298 {XK_Right, '6'},
299 {XK_Up, '8'},
300 {XK_Down, '2'},
301 {XK_KP_Left, '4'},
302 {XK_KP_Right, '6'},
303 {XK_KP_Up, '8'},
304 {XK_KP_Down, '2'},
305 {0, 0}
306 };
307
308 i = XLookupString((XKeyEvent *)ev, buf, sizeof(buf)-1, &key, &cs);
309 buf[i] = '\0';
310 c = buf[0];
311 for (i = 0; functbl[i].func; i++) {
312 if (functbl[i].sym == key) {
313 c = functbl[i].func;
314 break;
315 }
316 }
317 switch(c) {
318 case 'q':
319 menu_stat_change(MENU_QUIT, 2);
320 break;
321 case 'f':
322 menu_stat_change(MENU_FILE, 2);
323 break;
324 case 'i':
325 menu_stat_change(MENU_INFO, 2);
326 break;
327 case 'e':
328 menu_stat_change(MENU_EDIT, 2);
329 break;
330 case 'L'-0x40:
331 redraw_window(imgwin);
332 break;
333 case '-':
334 zoom_out();
335 break;
336 case '+':
337 case '=':
338 zoom_in();
339 break;
340 case '2':
341 case 'j':
342 img_scroll(0, scroll_speed);
343 break;
344 case 'J':
345 img_scroll(0, 1);
346 break;
347 case '8':
348 case 'k':
349 img_scroll(0, -scroll_speed);
350 break;
351 case 'K':
352 img_scroll(0, -1);
353 break;
354 case '6':
355 case 'l':
356 img_scroll(scroll_speed, 0);
357 break;
358 case 'L':
359 img_scroll(1, 0);
360 break;
361 case '4':
362 case 'h':
363 img_scroll(-scroll_speed, 0);
364 break;
365 case 'H':
366 img_scroll(-1, 0);
367 break;
368 case '1':
369 img_scroll(-scroll_speed, scroll_speed);
370 break;
371 case '3':
372 img_scroll(scroll_speed, scroll_speed);
373 break;
374 case '7':
375 img_scroll(-scroll_speed, -scroll_speed);
376 break;
377 case '9':
378 img_scroll(scroll_speed, -scroll_speed);
379 break;
380 case 'o':
381 edit_mode_change(EDIT_PLOT);
382 break;
383 case 'p':
384 edit_mode_change(EDIT_PAINT);
385 break;
386 case 'c':
387 edit_mode_change(EDIT_COPY);
388 break;
389 case 'b':
390 edit_mode_change(EDIT_FILL);
391 break;
392 case 'n':
393 edit_mode_change(EDIT_LINE);
394 break;
395 case 'u':
396 edit_undo();
397 break;
398 case 'm':
399 color_mask_alt_all();
400 break;
401 case '!':
402 map_message_window();
403 break;
404 case '?':
405 message("imgchanged:%d colchanged:%d\n", imgchanged, colchanged);
406 break;
407 case 0x03: /* ^C */
408 edit_copy_hold();
409 break;
410 case 'V'-0x40: /* ^V */
411 edit_paste_hold();
412 break;
413 }
414 }
415
create_icon()416 int create_icon()
417 {
418 #ifdef INTERNAL_ICONPIXMAP
419 #if 1
420 xpxiconpixmap =
421 XCreateBitmapFromData(dsp, DefaultRootWindow(dsp),
422 icon_bits, icon_width, icon_height);
423 #else
424 xpxiconpixmap =
425 XCreatePixmapFromBitmapData(dsp, DefaultRootWindow(dsp),
426 icon_bits, icon_width, icon_height,
427 BlackPixel(dsp, scr), WhitePixel(dsp, scr),
428 DefaultDepth(dsp, scr));
429 #endif
430 if (xpxiconpixmap == None) {
431 error("icon pixmap create error!");
432 return 1;
433 }
434 #endif /* INTERNAL_ICONPIXMAP */
435 return create_icon_pixmap();
436 }
437
free_icon()438 void free_icon()
439 {
440 free_icon_pixmap();
441 if (xpxiconpixmap != None)
442 XFreePixmap(dsp, xpxiconpixmap);
443 }
444
parse_color(col,name)445 int parse_color(col, name)
446 XColor *col;
447 char *name;
448 {
449 if (!XParseColor(dsp, cmap, name, col)||
450 !XAllocColor(dsp, cmap, col))
451 return error("``%s'' color alloc error!", name);
452 return 0;
453 }
454
455
make_cursor()456 void make_cursor()
457 {
458 Pixmap src, mask;
459 XColor cfore, cback;
460
461 curs_watch = XCreateFontCursor(dsp, XC_watch);
462 XParseColor(dsp, cmap, "black", &cfore);
463 XParseColor(dsp, cmap, "white", &cback);
464 src = XCreateBitmapFromData(dsp, DefaultRootWindow(dsp),
465 cursor0_bits, cursor0_width, cursor0_height);
466 mask = XCreateBitmapFromData(dsp, DefaultRootWindow(dsp),
467 cursor1_bits, cursor1_width, cursor1_height);
468 curs_cross = XCreatePixmapCursor(dsp, src, mask, &cfore, &cback,
469 cursor0_x_hot, cursor0_y_hot);
470 }
471
initialize()472 void initialize()
473 {
474 int i;
475 XSizeHints hint;
476 XColor col;
477
478 dsp = XOpenDisplay(str_display);
479 if (!dsp) {
480 error("Cannot open display!");
481 exit(1);
482 }
483 scr = DefaultScreen(dsp);
484 cmap = DefaultColormap(dsp, scr);
485 bg = WhitePixel(dsp, scr);
486 border_color = fg = BlackPixel(dsp, scr);
487 if (parse_color(&col, str_background) == 0)
488 bg = col.pixel;
489 if (parse_color(&col, str_foreground) == 0)
490 fg = col.pixel;
491 if (parse_color(&col, str_border) == 0)
492 border_color = col.pixel;
493 create_icon();
494 hint.flags = 0;
495 i = XGeometry(dsp, scr, str_geometry, "428x368", border_width, 1, 1, 0, 0,
496 &(hint.x), &(hint.y), &(hint.width), &(hint.height));
497 if (i & (XValue|YValue))
498 hint.flags |= PPosition;
499 if (i & (WidthValue|HeightValue))
500 hint.flags |= PSize;
501 win = XCreateSimpleWindow(dsp, DefaultRootWindow(dsp),
502 hint.x, hint.y, hint.width, hint.height,
503 border_width, border_color, bg);
504 XSetStandardProperties(dsp, win, windowname, windowname, xpxiconpixmap,
505 oargv, oargc, &hint);
506 toplevelwin[toplevelwc++] = win;
507 if (use_private_cmap) {
508 cmap = XCopyColormapAndFree(dsp, cmap);
509 XSetWindowColormap(dsp, win, cmap);
510 }
511 make_cursor();
512 if (str_fontbold == NULL)
513 str_fontbold = str_font == NULL ? DEFAULT_BOLD_FONT : str_font;
514 if (str_font == NULL)
515 str_font = DEFAULT_FONT;
516
517 fs0 = XLoadQueryFont(dsp, str_fontbold);
518 fs1 = XLoadQueryFont(dsp, str_fontbold);
519
520 gc0 = XCreateGC(dsp, win, 0, 0);
521 XSetBackground(dsp, gc0, bg);
522 XSetForeground(dsp, gc0, fg);
523 XSetFont(dsp, gc0, fs0->fid);
524
525 gc1 = XCreateGC(dsp, win, 0, 0);
526 XSetBackground(dsp, gc1, fg);
527 XSetForeground(dsp, gc1, bg);
528 XSetFont(dsp, gc1, fs0->fid);
529
530 areagc = XCreateGC(dsp, win, 0, 0);
531 XSetBackground(dsp, areagc, bg);
532 XSetForeground(dsp, areagc, fg);
533
534 grid0gc = XCreateGC(dsp, win, 0, 0);
535 XSetBackground(dsp, grid0gc, bg);
536 XSetForeground(dsp, grid0gc, bg);
537
538 gridgc = XCreateGC(dsp, win, 0, 0);
539 XSetBackground(dsp, gridgc, bg);
540 XSetForeground(dsp, gridgc, bg);
541 XSetLineAttributes(dsp, gridgc, 0, LineOnOffDash, CapButt, JoinMiter);
542 XSetDashes(dsp, gridgc, 0, grid_dash_list, 2);
543
544 hatch_pixmap = XCreatePixmapFromBitmapData(dsp, win,
545 hatch_bits, 8, 8, fg, bg,
546 DefaultDepth(dsp, scr));
547
548 }
549
550 #ifdef __STDC__
551 typedef void *VOIDPTR;
552 #else
553 typedef char *VOIDPTR;
554 #endif
555
556 #define OPT_ABBREV_MASK 0x10
557 #define OPT_FUNC 1
558 #define OPT_SET_INT 2
559 #define OPT_GET_INT 3
560 #define OPT_GET_STR 4
561
562 typedef struct {
563 char *name;
564 VOIDPTR parm;
565 char type;
566 char setvalue; /* for OPT_SET_INT */
567 } OPTION;
568
569 #define OPTTBL(name,type,ptr,val) {name, (VOIDPTR)ptr, type, val}
570
571 static OPTION opttbl[] = {
572 OPTTBL("-?", OPT_FUNC, usage, 0),
573 OPTTBL("-h", OPT_FUNC, usage, 0),
574 OPTTBL("-V", OPT_FUNC, usage, 0),
575 OPTTBL("-help", OPT_FUNC, usage, 0),
576 OPTTBL("-debug", OPT_SET_INT, &debug_mode, True),
577 OPTTBL("-display", OPT_GET_STR, &str_display, 0),
578 OPTTBL("-geometry", OPT_GET_STR, &str_geometry, 0),
579 OPTTBL("-background", OPT_GET_STR, &str_background, 0),
580 OPTTBL("-bg", OPT_GET_STR, &str_background, 0),
581 OPTTBL("-foreground", OPT_GET_STR, &str_foreground, 0),
582 OPTTBL("-fg", OPT_GET_STR, &str_foreground, 0),
583 OPTTBL("-bordercolor",OPT_GET_STR, &str_border, 0),
584 OPTTBL("-bd", OPT_GET_STR, &str_border, 0),
585 OPTTBL("-font", OPT_GET_STR, &str_font, 0),
586 OPTTBL("-fn", OPT_GET_STR, &str_font, 0),
587 OPTTBL("-fb", OPT_GET_STR, &str_fontbold, 0),
588 OPTTBL("-borderwidth",OPT_GET_INT, &border_width, 0),
589 OPTTBL("-bw", OPT_GET_INT, &border_width, 0),
590 OPTTBL("-commoncolor",OPT_SET_INT, &use_private_color, False),
591 OPTTBL("-cmap", OPT_SET_INT, &use_private_cmap, True),
592 OPTTBL("-p", OPT_SET_INT, &use_private_cmap, True),
593 OPTTBL("-quickconvert",OPT_SET_INT, &quick_convert, True),
594 OPTTBL("-slowconvert",OPT_SET_INT, &quick_convert, False),
595 OPTTBL("-backingstore",OPT_GET_INT, &backingstoremode, 0),
596 OPTTBL("-menu", OPT_GET_INT, &menumode, 0),
597 OPTTBL("-menuspeed", OPT_GET_INT, &menu_speed, 0),
598 OPTTBL("-zoom", OPT_GET_INT, &zoomfactor, 0),
599 OPTTBL("-scrollbar", OPT_GET_INT, &scrollbarmode, 0),
600 OPTTBL("-maxw", OPT_GET_INT, &imgmaxw, 0),
601 OPTTBL("-maxh", OPT_GET_INT, &imgmaxh, 0),
602 OPTTBL("-maxz", OPT_GET_INT, &maxzoom, 0),
603 OPTTBL("-scrollspeed",OPT_GET_INT, &scroll_speed, 0),
604 OPTTBL("-ix", OPT_GET_INT, &imgwx, 0),
605 OPTTBL("-iy", OPT_GET_INT, &imgwy, 0),
606 OPTTBL(NULL, 0, NULL, 0)
607 };
608
parse_option(ac,av)609 int parse_option(ac, av)
610 int *ac;
611 char ***av;
612 {
613 OPTION *p;
614 int i;
615 typedef void (*VOIDFUNCPTR)();
616
617 for (p = opttbl; p->name != NULL; p++) {
618 if (strcmp(**av, p->name) == 0) {
619 --*ac;
620 ++*av;
621 switch(p->type & ~OPT_ABBREV_MASK) {
622 case OPT_FUNC:
623 ((VOIDFUNCPTR)(p->parm))();
624 break;
625 case OPT_SET_INT:
626 *((int *)(p->parm)) = p->setvalue;
627 break;
628 case OPT_GET_INT:
629 if (*ac) {
630 *((int *)(p->parm)) = strtol(**av, NULL, 0);
631 ++*av;
632 --*ac;
633 }
634 break;
635 case OPT_GET_STR:
636 if (*ac) {
637 *((char **)(p->parm)) = **av;
638 ++*av;
639 --*ac;
640 }
641 break;
642 }
643 return 0;
644 } else if (p->type & OPT_ABBREV_MASK &&
645 strncmp(**av, p->name, i = strlen(p->name)) == 0) {
646 switch(p->type & ~OPT_ABBREV_MASK) {
647 case OPT_GET_INT:
648 *((int *)(p->parm)) = strtol(**av+i, NULL, 0);
649 break;
650 case OPT_GET_STR:
651 *((char **)(p->parm)) = **av+i;
652 break;
653 }
654 ++*av;
655 --*ac;
656 return 0;
657 }
658 }
659 return 1;
660 }
661
662
main(argc,argv)663 void main(argc, argv)
664 int argc; char **argv;
665 {
666 XEvent ev;
667 int i;
668 Window double_click_win = 0;
669 Time l, double_click_time;
670 XEvent ahead;
671 Bool ignore_event;
672
673 oargc = argc;
674 oargv = argv;
675 errname = myname = filename(*argv);
676 strncpy(windowname, myname, sizeof(windowname));
677 strncat(windowname, " @ ", sizeof(windowname));
678 i = strlen(windowname);
679 gethostname(windowname+i, sizeof(windowname)-i);
680 windowname[sizeof(windowname)-1] = '\0';
681 if (read_config())
682 exit(1);
683 argv++;
684 argc--;
685 while (argc > 0) {
686 if (parse_option(&argc, &argv)) {
687 if (**argv == '-') {
688 error("unknown option ``%s''!", *argv);
689 usage();
690 }
691 break;
692 }
693 }
694 initialize();
695 if (alloc_colorbuf())
696 exit(1);
697 if (imgwx == -1 && imgwy == -1) {
698 if (!menumode) {
699 imgwx = imgwy = 0;
700 } else {
701 imgwx = 112; /* 124 */
702 imgwy = 52; /* 64 */
703 }
704 if (scrollbarmode & 1) {
705 imgwx += IMGSCRLW;
706 imgwy += IMGSCRLW;
707 }
708 }
709 create_img_window();
710 cursor_busy();
711
712 menuev_init();
713 create_message_window();
714 create_info_window();
715 create_scrlbar_window();
716 create_menu_window(win, MENUX, MENUY);
717 create_colset_window(win, COLSETX, COLSETY);
718 create_palset_window(win, PALSETX, PALSETY);
719 create_filename_window(win, PALSETX, PALSETY-24);
720 create_zoom_window(win, 256, 4);
721 create_grid_window(win, 340, 4);
722 create_cursor_window(win, 256, 30);
723 init_tilemask();
724 create_tile_window(win, 8, 364);
725 create_edit_window();
726 create_file_window();
727 if (image_alloc()||undo_init()) {
728 error("more core!");
729 exit(1);
730 }
731 init_color_buf();
732 init_color();
733 init_image();
734 image_update_all();
735 while (argc--)
736 read_data_file(*argv++);
737 XSelectInput(dsp, win, ExposureMask|StructureNotifyMask|
738 ButtonPressMask|KeyPressMask);
739 XMapRaised(dsp, win);
740 while (!sw_quit) {
741 if (XEventsQueued(dsp, QueuedAfterReading) == 0) {
742 XFlush(dsp);
743 cursor_free();
744 imgscrl_background();
745 file_background();
746 }
747 XNextEvent(dsp, &ev);
748 ignore_event = False;
749 switch(ev.type) {
750 case NoExpose:
751 if (ev.xnoexpose.drawable == imgwin)
752 imgwin_noexpose = True;
753 break;
754 case GraphicsExpose:
755 if (ev.xgraphicsexpose.drawable == imgwin) {
756 img_expose(ev.xgraphicsexpose.x, ev.xgraphicsexpose.y,
757 ev.xgraphicsexpose.width, ev.xgraphicsexpose.height);
758 if (ev.xgraphicsexpose.count == 0)
759 imgwin_noexpose = True;
760 }
761 break;
762 case Expose:
763 if (ev.xexpose.window == imgwin)
764 img_expose(ev.xexpose.x, ev.xexpose.y,
765 ev.xexpose.width, ev.xexpose.height);
766 else
767 info_expose(&ev);
768 break;
769 case MappingNotify:
770 XRefreshKeyboardMapping((XMappingEvent *)&ev);
771 break;
772 case KeyPress:
773 if (ev.xkey.window == win)
774 key_event(&ev);
775 break;
776 case ConfigureNotify:
777 if (ev.xconfigure.window == win)
778 resize_img_window();
779 break;
780 case ButtonPress:
781 if (ev.xbutton.window == double_click_win) {
782 l = ev.xbutton.time - double_click_time;
783 if (l & 0x80000000)
784 l = ~l + 1;
785 double_clicked = l < 500;
786 } else {
787 double_clicked = False;
788 }
789 double_click_win = ev.xbutton.window;
790 double_click_time = ev.xbutton.time;
791 info_press(&ev);
792 break;
793 case EnterNotify:
794 if (XEventsQueued(ev.xcrossing.display, QueuedAfterReading) > 0) {
795 XPeekEvent(ev.xcrossing.display, &ahead);
796 if (ahead.type == LeaveNotify &&
797 ahead.xcrossing.window == ev.xcrossing.window &&
798 ahead.xcrossing.mode == ev.xcrossing.mode &&
799 ahead.xcrossing.detail == ev.xcrossing.detail) {
800 XNextEvent(ev.xcrossing.display, &ev);
801 ignore_event = True;
802 }
803 }
804 case LeaveNotify:
805 double_click_win = 0;
806 break;
807 }
808 if (!ignore_event) {
809 edit_event(&ev);
810 if (ev.type == MotionNotify &&
811 XEventsQueued(ev.xmotion.display, QueuedAfterReading) > 0) {
812 XPeekEvent(ev.xmotion.display, &ahead);
813 if (ahead.type == MotionNotify &&
814 ahead.xmotion.window == ev.xmotion.window) {
815 XNextEvent(ev.xmotion.display, &ev);
816 }
817 }
818 menuev_event(&ev);
819 }
820 }
821 autosave();
822 update_config_file();
823 #if 1
824 menuev_destroy();
825 close_message_window();
826 close_edit_window();
827 close_info_window();
828 close_file_window();
829 XDestroyWindow(dsp, imgwin);
830 free_color_all();
831 free_icon();
832 XFree((char *)img);
833 XFreeGC(dsp, gc1);
834 XFreeGC(dsp, gc0);
835 XDestroyWindow(dsp, win);
836 #endif
837 XCloseDisplay(dsp);
838 exit(0);
839 }
840
841 /* End of file */
842