1 /*
2 
3 Copyright 1989, 1998  The Open Group
4 
5 Permission to use, copy, modify, distribute, and sell this software and its
6 documentation for any purpose is hereby granted without fee, provided that
7 the above copyright notice appear in all copies and that both that
8 copyright notice and this permission notice appear in supporting
9 documentation.
10 
11 The above copyright notice and this permission notice shall be included
12 in all copies or substantial portions of the Software.
13 
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17 IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 OTHER DEALINGS IN THE SOFTWARE.
21 
22 Except as contained in this notice, the name of The Open Group shall
23 not be used in advertising or otherwise to promote the sale, use or
24 other dealings in this Software without prior written authorization
25 from The Open Group.
26 
27 */
28 
29 /*
30  * Author:  Davor Matic, MIT X Consortium
31  */
32 
33 
34 
35 
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <X11/Intrinsic.h>
39 #include <X11/StringDefs.h>
40 #include <X11/Xaw/Paned.h>
41 #include <X11/Xaw/Form.h>
42 #include <X11/Xaw/Box.h>
43 #include <X11/Xaw/Command.h>
44 #include <X11/Xaw/Toggle.h>
45 #include <X11/Xaw/MenuButton.h>
46 #include <X11/Xaw/SimpleMenu.h>
47 #include <X11/Xaw/SmeLine.h>
48 #include <X11/Xaw/SmeBSB.h>
49 #include "Bitmap.h"
50 
51 #include <X11/bitmaps/xlogo16>
52 
53 static const char *usage = "[-options ...] filename\n\
54 \n\
55 where options include all standard toolkit options plus:\n\
56      -size WIDTHxHEIGHT\n\
57      -sw dimension\n\
58      -sh dimension\n\
59      -gt dimension\n\
60      -grid, +grid\n\
61      -axes, +axes\n\
62      -dashed, +dashed\n\
63      -stippled, +stippled\n\
64      -proportional, +proportional\n\
65      -basename basename\n\
66      -dashes filename\n\
67      -stipple filename\n\
68      -hl color\n\
69      -fr color\n\
70 \n\
71 The default WIDTHxHEIGHT is 16x16.\n";
72 
73 static XrmOptionDescRec options[] = {
74   { "-axes",	    "*bitmap.axes",	    XrmoptionNoArg,	"True"},
75   { "+axes",	    "*bitmap.axes",	    XrmoptionNoArg,	"False"},
76   { "-basename",    "*bitmap.basename",	    XrmoptionSepArg,	NULL},
77   { "-dashed",	    "*bitmap.dashed",	    XrmoptionNoArg,	"True"},
78   { "+dashed",	    "*bitmap.dashed",	    XrmoptionNoArg,	"False"},
79   { "-dashes",	    "*bitmap.dashes",	    XrmoptionSepArg,	NULL},
80   { "-fr",	    "*bitmap.frame",	    XrmoptionSepArg,	NULL},
81   { "-gt",	    "*bitmap.gridTolerance",XrmoptionSepArg,	NULL},
82   { "-grid",	    "*bitmap.grid",	    XrmoptionNoArg,	"True"},
83   { "+grid",	    "*bitmap.grid",	    XrmoptionNoArg,	"False"},
84   { "-hl",	    "*bitmap.highlight",    XrmoptionSepArg,	NULL},
85   { "-proportional","*bitmap.proportional", XrmoptionNoArg,	"True"},
86   { "+proportional","*bitmap.proportional", XrmoptionNoArg,	"False"},
87   { "-size",	    "*bitmap.size",	    XrmoptionSepArg,	NULL},
88   { "-sh",	    "*bitmap.squareHeight", XrmoptionSepArg,	NULL},
89   { "-sw",	    "*bitmap.squareWidth",  XrmoptionSepArg,	NULL},
90   { "-stipple",	    "*bitmap.stipple",	    XrmoptionSepArg,	NULL},
91   { "-stippled",    "*bitmap.stippled",	    XrmoptionNoArg,	"True"},
92   { "+stippled",    "*bitmap.stippled",	    XrmoptionNoArg,	"False"},
93 };
94 
95 typedef struct {
96   int             id;
97   String          name;
98   Boolean         trap;
99   Widget          widget;
100   } ButtonRec;
101 
102 static ButtonRec file_menu[] = {
103 #define New 101
104   {New, "new", True},
105 #define Load 102
106   {Load, "load", True},
107 #define Insert 103
108   {Insert, "insert", True},
109 #define Save 104
110   {Save, "save", True},
111 #define SaveAs 105
112   {SaveAs, "saveAs", True},
113 #define Resize 106
114   {Resize, "resize", True},
115 #define Rescale 107
116   {Rescale, "rescale", True},
117 #define Filename 108
118   {Filename, "filename", True},
119 #define Basename 109
120   {Basename, "basename", True},
121 #define Dummy -1
122   {Dummy, "line", False},
123 #define Quit 110
124   {Quit, "quit", True},
125 };
126 
127 static ButtonRec edit_menu[] = {
128 #define Image 201
129   {Image, "image", True},
130 #define Grid 203
131   {Grid, "grid", True},
132 #define Dashed 204
133   {Dashed, "dashed", True},
134 #define Axes 205
135   {Axes, "axes", True},
136 #define Stippled 206
137   {Stippled, "stippled", True},
138 #define Proportional 207
139   {Proportional, "proportional", True},
140 #define Zoom 208
141   {Zoom, "zoom", True},
142 /* Dummy */
143   {Dummy, "line", False},
144 #define Cut 209
145   {Cut, "cut", True},
146 #define Copy 210
147   {Copy, "copy", True},
148 #define Paste 211
149   {Paste, "paste", True},
150 };
151 
152 static ButtonRec buttons[] = {
153 /*#define Clear 1*/
154   {Clear, "clear", False},
155 /*#define Set 2*/
156   {Set, "set", False},
157 /*#define Invert 3*/
158   {Invert, "invert", False},
159 #define Mark 26
160   {Mark, "mark", True},
161 #define Unmark 27
162   {Unmark, "unmark", False},
163 #define CopyImm 4
164   {CopyImm, "copy", True},
165 #define MoveImm 5
166   {MoveImm, "move", True},
167 #define FlipHoriz 6
168   {FlipHoriz, "flipHoriz", False},
169 #define Up 7
170   {Up, "up", False},
171 #define FlipVert 8
172   {FlipVert, "flipVert", False},
173 #define Left 9
174   {Left, "left", False},
175 #define Fold 10
176   {Fold, "fold", False},
177 #define Right 11
178   {Right, "right", False},
179 #define RotateLeft 12
180   {RotateLeft, "rotateLeft", False},
181 #define Down 13
182   {Down, "down", False},
183 #define RotateRight 14
184   {RotateRight, "rotateRight", False},
185 #define Point 15
186   {Point, "point", True},
187 #define Curve 16
188   {Curve, "curve", True},
189 #define Line 17
190   {Line, "line", True},
191 #define Rectangle 18
192   {Rectangle, "rectangle", True},
193 #define FilledRectangle 19
194   {FilledRectangle, "filledRectangle", True},
195 #define Circle 20
196   {Circle, "circle", True},
197 #define FilledCircle 21
198   {FilledCircle, "filledCircle", True},
199 #define FloodFill 22
200   {FloodFill, "floodFill", True},
201 #define SetHotSpot 23
202   {SetHotSpot, "setHotSpot", True},
203 #define ClearHotSpot 24
204   {ClearHotSpot, "clearHotSpot", False},
205 #define Undo 25
206   {Undo, "undo", False},
207 };
208 
209 #include "Dialog.h"
210 
211 static Widget
212     top_widget,
213     parent_widget,
214     formy_widget,
215     fileMenu_widget,
216     editMenu_widget,
217     status_widget,
218     pane_widget,
219     form_widget,
220     bitmap_widget,
221     image_shell,
222     box_widget,
223     normal_image_widget,
224     inverted_image_widget;
225 static Boolean image_visible = False;
226 static Pixmap check_mark;
227 static Dialog input_dialog, error_dialog, qsave_dialog;
228 static Time btime;
229 static String filename = NULL, base_name = NULL, format;
230 static char message[80];
231 
232 
233 void FixMenu ( Widget w, XEvent *event, String *params, Cardinal *num_params );
234 void SwitchImage ( void );
235 void SwitchGrid( void );
236 void SwitchDashed( void );
237 void SwitchAxes( void );
238 void SwitchStippled( void );
239 void SwitchProportional( void );
240 void SwitchZoom( void );
241 void DoCut( void );
242 void DoCopy( void );
243 void DoPaste( void );
244 void DoNew( void );
245 void DoLoad( void );
246 void DoInsert( void );
247 void DoSave( void );
248 void DoSaveAs( void );
249 void DoResize( void );
250 void DoRescale( void );
251 void DoFilename( void );
252 void DoBasename( void );
253 void DoQuit ( Widget w, XEvent *event, String *params, Cardinal *num_params );
254 
255 static XtActionsRec actions_table[] = {
256   {"fix-menu", FixMenu},
257   {"switch-image", (XtActionProc)SwitchImage},
258   {"switch-grid", (XtActionProc)SwitchGrid},
259   {"switch-dashed", (XtActionProc)SwitchDashed},
260   {"switch-axes", (XtActionProc)SwitchAxes},
261   {"switch-stippled", (XtActionProc)SwitchStippled},
262   {"switch-proportional", (XtActionProc)SwitchProportional},
263   {"switch-zoom", (XtActionProc)SwitchZoom},
264   {"do-cut", (XtActionProc)DoCut},
265   {"do-copy", (XtActionProc)DoCopy},
266   {"do-paste", (XtActionProc)DoPaste},
267   {"do-new", (XtActionProc)DoNew},
268   {"do-load", (XtActionProc)DoLoad},
269   {"do-insert", (XtActionProc)DoInsert},
270   {"do-save", (XtActionProc)DoSave},
271   {"do-save-as", (XtActionProc)DoSaveAs},
272   {"do-resize", (XtActionProc)DoResize},
273   {"do-rescale", (XtActionProc)DoRescale},
274   {"do-filename", (XtActionProc)DoFilename},
275   {"do-basename", (XtActionProc)DoBasename},
276   {"do-quit", DoQuit}
277 };
278 
279 static Atom wm_delete_window;
280 
281 static void
FixImage(void)282 FixImage(void)
283 {
284     Pixmap old_image, image;
285     int n;
286     Arg wargs[2];
287 
288     if (!image_visible) return;
289 
290     n=0;
291     XtSetArg(wargs[n], XtNbitmap, &old_image); n++;
292     XtGetValues(normal_image_widget, wargs, n);
293 
294 
295     image = BWGetUnzoomedPixmap(bitmap_widget);
296 
297     n=0;
298     XtSetArg(wargs[n], XtNbitmap, image); n++;
299     XtSetValues(normal_image_widget, wargs, n);
300     XtSetValues(inverted_image_widget, wargs, n);
301 
302     if (old_image != XtUnspecifiedPixmap)
303 	XFreePixmap(XtDisplay(bitmap_widget), old_image);
304 }
305 
306 static void
FixStatus(void)307 FixStatus(void)
308 {
309     int n;
310     Arg wargs[2];
311     String str, label;
312 
313     str = BWUnparseStatus(bitmap_widget);
314 
315     n=0;
316     XtSetArg(wargs[n], XtNlabel, &label); n++;
317     XtGetValues(status_widget, wargs, n);
318 
319     if (strcmp(str, label)) {
320       n = 0;
321       XtSetArg(wargs[n], XtNlabel, str); n++;
322       XtSetValues(status_widget, wargs, n);
323     }
324 
325     /*XtFree(str); */
326 }
327 
328 static void
FixUp(void)329 FixUp(void)
330 {
331   FixImage();
332   FixStatus();
333 }
334 
335 static void
FixEntry(Widget w,int * id)336 FixEntry(Widget w, int *id)
337 {
338     int n;
339     Arg wargs[2];
340     Time dummy = 0;
341 
342     n = 0;
343 
344     switch (*id) {
345 
346     case Image:
347 	XtSetArg(wargs[n], XtNleftBitmap,
348 		 image_visible ? check_mark : None); n++;
349 	break;
350 
351     case Grid:
352 	XtSetArg(wargs[n], XtNleftBitmap,
353 		 BWQueryGrid(bitmap_widget) ? check_mark : None); n++;
354 	break;
355 
356     case Dashed:
357 	XtSetArg(wargs[n], XtNleftBitmap,
358 		 BWQueryDashed(bitmap_widget) ? check_mark : None); n++;
359 	break;
360 
361     case Axes:
362 	XtSetArg(wargs[n], XtNleftBitmap,
363 		 BWQueryAxes(bitmap_widget) ? check_mark : None); n++;
364 	break;
365 
366     case Stippled:
367 	XtSetArg(wargs[n], XtNleftBitmap,
368 		 BWQueryStippled(bitmap_widget) ? check_mark : None); n++;
369 	break;
370 
371     case Proportional:
372 	XtSetArg(wargs[n], XtNleftBitmap,
373 		 BWQueryProportional(bitmap_widget) ? check_mark : None); n++;
374 	break;
375 
376     case Zoom:
377 	XtSetArg(wargs[n], XtNleftBitmap,
378 		 BWQueryZooming(bitmap_widget) ? check_mark : None); n++;
379 	break;
380 
381     case Copy:
382     case Cut:
383 	XtSetArg(wargs[n], XtNsensitive, BWQueryMarked(bitmap_widget)); n++;
384 	break;
385 
386     case Paste:
387 	XtSetArg(wargs[n], XtNsensitive,
388 		 BWQuerySelection(bitmap_widget, dummy)); n++;
389 	break;
390 
391     default:
392 	return;
393     }
394 
395     XtSetValues(w, wargs, n);
396 }
397 
398 /* ARGSUSED */
FixMenu(Widget w,XEvent * event,String * params,Cardinal * num_params)399 void FixMenu(Widget w,
400 	     XEvent *event,
401 	     String *params,
402 	     Cardinal *num_params)
403 {
404     int i;
405 
406     btime = event->xbutton.time;
407 
408     for (i = 0; i < XtNumber(edit_menu); i++)
409 	FixEntry(edit_menu[i].widget, &edit_menu[i].id);
410 }
411 
412 static int zero = 0;
413 #define Plain  (char *)&zero,sizeof(int)
414 /* ARGSUSED */
415 static void
TheCallback(Widget w,XtPointer clientData,XtPointer callData)416 TheCallback(Widget w,	/* not used */
417 	    XtPointer clientData,
418 	    XtPointer callData)
419 {
420     int *id = (int *)clientData;
421     switch (*id) {
422 
423     case New:
424       DoNew();
425       break;
426 
427     case Load:
428       DoLoad();
429       break;
430 
431     case Insert:
432       DoInsert();
433       break;
434 
435     case Save:
436       DoSave();
437       break;
438 
439     case SaveAs:
440       DoSaveAs();
441       break;
442 
443     case Resize:
444       DoResize();
445       break;
446 
447     case Rescale:
448       DoRescale();
449       break;
450 
451     case Filename:
452       DoFilename();
453       break;
454 
455     case Basename:
456       DoBasename();
457       break;
458 
459     case Image:
460       SwitchImage();
461       break;
462 
463     case Grid:
464       SwitchGrid();
465       break;
466 
467     case Dashed:
468       SwitchDashed();
469       break;
470 
471     case Axes:
472       SwitchAxes();
473       break;
474 
475     case Stippled:
476       SwitchStippled();
477       break;
478 
479     case Proportional:
480       SwitchProportional();
481       break;
482 
483     case Zoom:
484       SwitchZoom();
485       break;
486 
487     case Cut:
488       DoCut();
489       break;
490 
491     case Copy:
492       DoCopy();
493       break;
494 
495     case Paste:
496       DoPaste();
497       break;
498 
499     case Clear:
500 	BWStoreToBuffer(bitmap_widget);
501 	BWClear(bitmap_widget);
502 	BWChangeNotify(bitmap_widget);
503 	BWSetChanged(bitmap_widget);
504 	break;
505 
506     case Set:
507 	BWStoreToBuffer(bitmap_widget);
508 	BWSet(bitmap_widget);
509 	BWChangeNotify(bitmap_widget);
510 	BWSetChanged(bitmap_widget);
511 break;
512 
513     case Invert:
514 	BWStoreToBuffer(bitmap_widget);
515 	BWInvert(bitmap_widget);
516 	BWChangeNotify(bitmap_widget);
517 	BWSetChanged(bitmap_widget);
518 	break;
519 
520     case Mark:
521         BWRemoveAllRequests(bitmap_widget);
522         BWEngageRequest(bitmap_widget, MarkRequest, True, Plain);
523         break;
524 
525     case Unmark:
526         BWUnmark(bitmap_widget);
527         break;
528 
529     case CopyImm:
530 	BWRemoveAllRequests(bitmap_widget);
531 	if (BWQueryMarked(bitmap_widget)) {
532 	    BWAddRequest(bitmap_widget, MarkRequest, False, Plain);
533 	    BWEngageRequest(bitmap_widget, CopyRequest, True, Plain);
534 	}
535 	else {
536 	    BWEngageRequest(bitmap_widget, MarkRequest, False, Plain);
537 	    BWAddRequest(bitmap_widget, CopyRequest, True, Plain);
538 	}
539 	break;
540 
541     case MoveImm:
542 	BWRemoveAllRequests(bitmap_widget);
543 	if (BWQueryMarked(bitmap_widget)) {
544 	    BWAddRequest(bitmap_widget, MarkRequest, False, Plain);
545 	    BWEngageRequest(bitmap_widget, MoveRequest, True, Plain);
546 	}
547 	else {
548 	    BWEngageRequest(bitmap_widget, MarkRequest, False, Plain);
549 	    BWAddRequest(bitmap_widget, MoveRequest, True, Plain);
550 	}
551 	break;
552 
553     case Up:
554 	BWStoreToBuffer(bitmap_widget);
555 	BWUp(bitmap_widget);
556 	BWChangeNotify(bitmap_widget);
557 	BWSetChanged(bitmap_widget);
558 	break;
559 
560     case Down:
561 	BWStoreToBuffer(bitmap_widget);
562 	BWDown(bitmap_widget);
563 	BWChangeNotify(bitmap_widget);
564 	BWSetChanged(bitmap_widget);
565 	break;
566 
567     case Left:
568 	BWStoreToBuffer(bitmap_widget);
569 	BWLeft(bitmap_widget);
570 	BWChangeNotify(bitmap_widget);
571 	BWSetChanged(bitmap_widget);
572 	break;
573 
574     case Right:
575 	BWStoreToBuffer(bitmap_widget);
576 	BWRight(bitmap_widget);
577 	BWChangeNotify(bitmap_widget);
578 	BWSetChanged(bitmap_widget);
579 	break;
580 
581     case Fold:
582 	BWStoreToBuffer(bitmap_widget);
583 	BWFold(bitmap_widget);
584 	BWChangeNotify(bitmap_widget);
585 	BWSetChanged(bitmap_widget);
586 	break;
587 
588     case FlipHoriz:
589 	BWStoreToBuffer(bitmap_widget);
590 	BWFlipHoriz(bitmap_widget);
591 	BWChangeNotify(bitmap_widget);
592 	BWSetChanged(bitmap_widget);
593 	break;
594 
595     case FlipVert:
596 	BWStoreToBuffer(bitmap_widget);
597 	BWFlipVert(bitmap_widget);
598 	BWChangeNotify(bitmap_widget);
599 	BWSetChanged(bitmap_widget);
600 	break;
601 
602     case RotateRight:
603 	BWStoreToBuffer(bitmap_widget);
604 	BWRotateRight(bitmap_widget);
605 	BWChangeNotify(bitmap_widget);
606 	BWSetChanged(bitmap_widget);
607 	break;
608 
609     case RotateLeft:
610 	BWStoreToBuffer(bitmap_widget);
611 	BWRotateLeft(bitmap_widget);
612 	BWChangeNotify(bitmap_widget);
613 	BWSetChanged(bitmap_widget);
614 	break;
615 
616     case Point:
617 	BWRemoveAllRequests(bitmap_widget);
618 	BWEngageRequest(bitmap_widget, PointRequest, True, Plain);
619 	break;
620 
621     case Curve:
622 	BWRemoveAllRequests(bitmap_widget);
623 	BWEngageRequest(bitmap_widget, CurveRequest, True, Plain);
624 	break;
625 
626     case Line:
627 	BWRemoveAllRequests(bitmap_widget);
628 	BWEngageRequest(bitmap_widget, LineRequest, True, Plain);
629 	break;
630 
631     case Rectangle:
632 	BWRemoveAllRequests(bitmap_widget);
633 	BWEngageRequest(bitmap_widget, RectangleRequest, True, Plain);
634 	break;
635 
636     case FilledRectangle:
637 	BWRemoveAllRequests(bitmap_widget);
638 	BWEngageRequest(bitmap_widget, FilledRectangleRequest, True, Plain);
639 	break;
640 
641     case Circle:
642 	BWRemoveAllRequests(bitmap_widget);
643 	BWEngageRequest(bitmap_widget, CircleRequest, True, Plain);
644 	break;
645 
646     case FilledCircle:
647 	BWRemoveAllRequests(bitmap_widget);
648 	BWEngageRequest(bitmap_widget, FilledCircleRequest, True, Plain);
649 	break;
650 
651     case FloodFill:
652 	BWRemoveAllRequests(bitmap_widget);
653 	BWEngageRequest(bitmap_widget, FloodFillRequest, True, Plain);
654 	break;
655 
656     case SetHotSpot:
657 	BWRemoveAllRequests(bitmap_widget);
658 	BWEngageRequest(bitmap_widget, HotSpotRequest, True, Plain);
659 	break;
660 
661     case ClearHotSpot:
662 	BWStoreToBuffer(bitmap_widget);
663 	BWClearHotSpot(bitmap_widget);
664 	BWChangeNotify(bitmap_widget);
665 	BWSetChanged(bitmap_widget);
666 	break;
667 
668     case Undo:
669 	BWUndo(bitmap_widget);
670 	BWChangeNotify(bitmap_widget);
671 	BWSetChanged(bitmap_widget);
672 	break;
673 
674     case Quit:
675       DoQuit(bitmap_widget, NULL, NULL, NULL);
676       break;
677     } /* don't add anything below this line */
678 }
679 
680 /* ARGSUSED */
681 
SwitchImage(void)682 void SwitchImage(void)
683 {
684   if (image_visible) {
685     XtPopdown(image_shell);
686     image_visible = False;
687   }
688   else {
689     Position image_x, image_y;
690     int n;
691     Arg wargs[3];
692 
693     XtTranslateCoords(bitmap_widget,
694 		      10, 10, &image_x, &image_y);
695 
696     n = 0;
697     XtSetArg(wargs[n], XtNx, image_x); n++;
698     XtSetArg(wargs[n], XtNy, image_y); n++;
699     XtSetValues(image_shell, wargs, n);
700 
701     image_visible = True;
702 
703     FixImage();
704     XtPopup(image_shell, XtGrabNone);
705     FixImage();
706   }
707 }
708 
SwitchGrid(void)709 void SwitchGrid(void)
710 {
711   BWSwitchGrid(bitmap_widget);
712 }
713 
SwitchDashed(void)714 void SwitchDashed(void)
715 {
716   BWSwitchDashed(bitmap_widget);
717 }
718 
SwitchAxes(void)719 void SwitchAxes(void)
720 {
721   BWSwitchAxes(bitmap_widget);
722 }
723 
SwitchStippled(void)724 void SwitchStippled(void)
725 {
726   BWSwitchStippled(bitmap_widget);
727 }
728 
SwitchProportional(void)729 void SwitchProportional(void)
730 {
731   BWSwitchProportional(bitmap_widget);
732 }
733 
SwitchZoom(void)734 void SwitchZoom(void)
735 {
736   if (BWQueryZooming(bitmap_widget)) {
737     BWZoomOut(bitmap_widget);
738     BWChangeNotify(bitmap_widget);
739   }
740   else {
741     if (BWQueryMarked(bitmap_widget)) {
742       BWStoreToBuffer(bitmap_widget);
743       BWZoomMarked(bitmap_widget);
744       BWChangeNotify(bitmap_widget);
745     }
746     else {
747       BWEngageRequest(bitmap_widget, ZoomInRequest, False, Plain);
748     }
749   }
750 }
751 
DoCut(void)752 void DoCut(void)
753 {
754   BWStore(bitmap_widget);
755   BWStoreToBuffer(bitmap_widget);
756   BWClearMarked(bitmap_widget);
757   BWUnmark(bitmap_widget);
758   BWChangeNotify(bitmap_widget);
759   BWSetChanged(bitmap_widget);
760 }
761 
DoCopy(void)762 void DoCopy(void)
763 {
764   BWStore(bitmap_widget);
765   BWUnmark(bitmap_widget);
766 }
767 
DoPaste(void)768 void DoPaste(void)
769 {
770   BWRequestSelection(bitmap_widget, btime, TRUE);
771   BWEngageRequest(bitmap_widget, RestoreRequest, False, Plain);
772 }
773 
DoNew(void)774 void DoNew(void)
775 {
776   BWGetFilename(bitmap_widget, &filename);
777   if (PopupDialog(input_dialog, "New file:",
778 		  filename, &filename, XtGrabExclusive) == Okay) {
779     BWChangeFilename(bitmap_widget, filename);
780     BWChangeBasename(bitmap_widget, filename);
781     BWStoreToBuffer(bitmap_widget);
782     BWClear(bitmap_widget);
783     BWClearHotSpot(bitmap_widget);
784     BWChangeNotify(bitmap_widget);
785     BWClearChanged(bitmap_widget);
786     BWUnmark(bitmap_widget);
787     FixStatus();
788   }
789 }
790 
DoLoad(void)791 void DoLoad(void)
792 {
793   if (BWQueryChanged(bitmap_widget)) {
794     BWGetFilename(bitmap_widget, &filename);
795   RetryLoadSave:
796     switch (PopupDialog(qsave_dialog, "Save file before loading?",
797 			filename, &filename, XtGrabExclusive)) {
798     case Yes:
799       if (BWWriteFile(bitmap_widget, filename, NULL)
800 	  != BitmapSuccess) {
801 	snprintf(message, sizeof(message), "Can't write file: %s", filename);
802 	if (PopupDialog(error_dialog, message,
803 			NULL, NULL, XtGrabExclusive) == Retry)
804 	  goto RetryLoadSave;
805       }
806       break;
807 
808     case Cancel:
809       return;
810     }
811   }
812   BWGetFilepath(bitmap_widget, &filename);
813  RetryLoad:
814   if (PopupDialog(input_dialog, "Load file:",
815 		  filename, &filename, XtGrabExclusive) == Okay) {
816     if (BWReadFile(bitmap_widget, filename, NULL) != BitmapSuccess) {
817       snprintf(message, sizeof(message), "Can't read file: %s", filename);
818       if (PopupDialog(error_dialog, message,
819 		      NULL, NULL, XtGrabExclusive) == Retry)
820 	goto RetryLoad;
821     }
822     else {
823       BWChangeNotify(bitmap_widget);
824       BWClearChanged(bitmap_widget);
825       FixStatus();
826     }
827   }
828 }
829 
DoInsert(void)830 void DoInsert(void)
831 {
832   BWGetFilepath(bitmap_widget, &filename);
833  RetryInsert:
834   if (PopupDialog(input_dialog, "Insert file:",
835 		  filename, &filename, XtGrabExclusive) == Okay) {
836     if (BWStoreFile(bitmap_widget, filename, NULL) != BitmapSuccess) {
837       snprintf(message, sizeof(message), "Can't read file: %s", filename);
838       if (PopupDialog(error_dialog, message,
839 		      NULL, NULL, XtGrabExclusive) == Retry)
840 	goto RetryInsert;
841     }
842     else {
843       BWEngageRequest(bitmap_widget, RestoreRequest, False, Plain);
844     }
845   }
846 }
847 
DoSave(void)848 void DoSave(void)
849 {
850   BWGetFilename(bitmap_widget, &filename);
851   if (!strcmp(filename, ""))
852     DoSaveAs();
853   else if (BWWriteFile(bitmap_widget, NULL, NULL) != BitmapSuccess) {
854     snprintf(message, sizeof(message), "Can't write file: %s", filename);
855     if (PopupDialog(error_dialog, message,
856 		    NULL, NULL, XtGrabExclusive) == Retry)
857       DoSaveAs();
858   }
859   else {
860     BWClearChanged(bitmap_widget);
861   }
862 }
863 
DoSaveAs(void)864 void DoSaveAs(void)
865 {
866   BWGetFilename(bitmap_widget, &filename);
867  RetrySave:
868   if (PopupDialog(input_dialog, "Save file:",
869 		  filename, &filename, XtGrabExclusive) == Okay) {
870     if (BWWriteFile(bitmap_widget, filename, NULL) != BitmapSuccess) {
871       snprintf(message, sizeof(message), "Can't write file: %s", filename);
872       if (PopupDialog(error_dialog, message,
873 		      NULL, NULL, XtGrabExclusive) == Retry)
874 	goto RetrySave;
875     }
876     else {
877       BWClearChanged(bitmap_widget);
878       FixStatus();
879     }
880   }
881 }
882 
DoResize(void)883 void DoResize(void)
884 {
885   Dimension width, height;
886   format = "";
887  RetryResize:
888   if (PopupDialog(input_dialog, "Resize to WIDTHxHEIGHT:",
889 		  format, &format, XtGrabExclusive) == Okay) {
890     if (BWParseSize(format, &width, &height)) {
891       BWResize(bitmap_widget, width, height);
892       BWChangeNotify(bitmap_widget);
893       BWSetChanged(bitmap_widget);
894       FixStatus();
895     }
896     else {
897       snprintf(message, sizeof(message), "Wrong format: %s", format);
898       if (PopupDialog(error_dialog, message,
899 		      NULL, NULL, XtGrabExclusive) == Retry)
900 	goto RetryResize;
901     }
902   }
903 }
904 
DoRescale(void)905 void DoRescale(void)
906 {
907   Dimension width, height;
908 
909   format = "";
910  RetryRescale:
911   if (PopupDialog(input_dialog, "Rescale to WIDTHxHEIGHT:",
912 		  format, &format, XtGrabExclusive) == Okay) {
913     if (BWParseSize(format, &width, &height)) {
914       BWRescale(bitmap_widget, width, height);
915       BWChangeNotify(bitmap_widget);
916       BWSetChanged(bitmap_widget);
917       FixStatus();
918     }
919     else {
920       snprintf(message, sizeof(message), "Wrong format: %s", format);
921       if (PopupDialog(error_dialog, message,
922 		      NULL, NULL, XtGrabExclusive) == Retry)
923 	goto RetryRescale;
924     }
925   }
926 }
927 
DoFilename(void)928 void DoFilename(void)
929 {
930   BWGetFilename(bitmap_widget, &filename);
931   if (PopupDialog(input_dialog, "Change filename:",
932 		  filename, &filename, XtGrabExclusive) == Okay) {
933     BWChangeFilename(bitmap_widget, filename);
934     FixStatus();
935   }
936 }
937 
DoBasename(void)938 void DoBasename(void)
939 {
940   BWGetBasename(bitmap_widget, &base_name);
941   if (PopupDialog(input_dialog, "Change basename:",
942 		  base_name, &base_name, XtGrabExclusive) == Okay) {
943     BWChangeBasename(bitmap_widget, base_name);
944     FixStatus();
945   }
946 }
947 
DoQuit(Widget w,XEvent * event,String * params,Cardinal * num_params)948 void DoQuit(Widget w, XEvent *event, String *params, Cardinal *num_params)
949 {
950   if (BWQueryChanged(bitmap_widget)) {
951     BWGetFilename(bitmap_widget, &filename);
952   RetryQuit:
953     switch (PopupDialog(qsave_dialog, "Save file before quitting?",
954 			filename, &filename, XtGrabExclusive)) {
955     case Yes:
956       if (BWWriteFile(bitmap_widget, filename, NULL)
957 	  != BitmapSuccess) {
958 	snprintf(message, sizeof(message), "Can't write file: %s", filename);
959 	if (PopupDialog(error_dialog, message,
960 			NULL, NULL, XtGrabExclusive) == Retry)
961 	  goto RetryQuit;
962 	else return;
963       }
964       break;
965 
966     case Cancel:
967       return;
968     }
969   }
970   exit(0);
971 }
972 
main(int argc,char * argv[])973 int main(int argc, char *argv[])
974 {
975     int i, n;
976     Arg wargs[2];
977     Widget w;
978     Widget radio_group = NULL;
979     XtPointer radio_data = NULL;
980 
981     top_widget = XtInitialize(NULL, "Bitmap",
982 			      options, XtNumber(options), &argc, argv);
983 
984     if (argc > 2) {
985 	fputs(usage, stderr);
986 	exit (0);
987     }
988 
989     check_mark = XCreateBitmapFromData(XtDisplay(top_widget),
990 				      RootWindowOfScreen(XtScreen(top_widget)),
991 				      (char *) xlogo16_bits,
992 				      xlogo16_width,
993 				      xlogo16_height);
994 
995     XtAddActions(actions_table, XtNumber(actions_table));
996     XtOverrideTranslations
997       (top_widget,
998        XtParseTranslationTable("<Message>WM_PROTOCOLS: do-quit()"));
999 
1000     parent_widget = XtCreateManagedWidget("parent", panedWidgetClass,
1001 					 top_widget, NULL, 0);
1002 
1003     formy_widget = XtCreateManagedWidget("formy", formWidgetClass,
1004 				       parent_widget, NULL, 0);
1005 
1006     fileMenu_widget = XtCreatePopupShell("fileMenu",
1007 					 simpleMenuWidgetClass,
1008 					 formy_widget, NULL, 0);
1009 
1010     (void) XtCreateManagedWidget("fileButton",
1011 				 menuButtonWidgetClass,
1012 				 formy_widget, NULL, 0);
1013 
1014     for (i = 0; i < XtNumber(file_menu); i++) {
1015 	w = XtCreateManagedWidget(file_menu[i].name,
1016 				  (file_menu[i].trap ?
1017 				   smeBSBObjectClass : smeLineObjectClass),
1018 				  fileMenu_widget, NULL, 0),
1019 	XtAddCallback(w,
1020 		      XtNcallback,
1021 		      TheCallback,
1022 		      (XtPointer)&file_menu[i].id);
1023 
1024 	file_menu[i].widget = w;
1025     }
1026 
1027     editMenu_widget = XtCreatePopupShell("editMenu",
1028 					 simpleMenuWidgetClass,
1029 					 formy_widget, NULL, 0);
1030 
1031     (void) XtCreateManagedWidget("editButton",
1032 				 menuButtonWidgetClass,
1033 				 formy_widget, NULL, 0);
1034 
1035     for (i = 0; i < XtNumber(edit_menu); i++) {
1036 	w = XtCreateManagedWidget(edit_menu[i].name,
1037 				  (edit_menu[i].trap ?
1038 				   smeBSBObjectClass : smeLineObjectClass),
1039 				  editMenu_widget, NULL, 0),
1040 	XtAddCallback(w,
1041 		      XtNcallback,
1042 		      TheCallback,
1043 		      (XtPointer)&edit_menu[i].id);
1044 
1045 	edit_menu[i].widget = w;
1046     }
1047 
1048     status_widget = XtCreateManagedWidget("status", labelWidgetClass,
1049 					  formy_widget, NULL, 0);
1050 
1051     pane_widget = XtCreateManagedWidget("pane", panedWidgetClass,
1052 					parent_widget, NULL, 0);
1053 
1054     form_widget = XtCreateManagedWidget("form", formWidgetClass,
1055 					pane_widget, NULL, 0);
1056 
1057     for (i = 0; i < XtNumber(buttons); i++) {
1058 	w = XtCreateManagedWidget(buttons[i].name,
1059 				  (buttons[i].trap ?
1060 				   toggleWidgetClass : commandWidgetClass),
1061 				  form_widget, NULL, 0);
1062 
1063 	XtAddCallback(w,
1064 		      XtNcallback,
1065 		      TheCallback,
1066 		      (XtPointer)&buttons[i].id);
1067 
1068 	buttons[i].widget = w;
1069 
1070 	if (buttons[i].id == Point) {
1071 	    radio_group = buttons[i].widget;
1072 	    radio_data  = buttons[i].name;
1073 	}
1074     }
1075     bitmap_widget = XtCreateManagedWidget("bitmap", bitmapWidgetClass,
1076 					  pane_widget, NULL, 0);
1077     XtRealizeWidget(top_widget);
1078     if (argc > 1)
1079       if (BWReadFile(bitmap_widget, argv[1], NULL))
1080 
1081     wm_delete_window = XInternAtom(XtDisplay(top_widget), "WM_DELETE_WINDOW",
1082 				   False);
1083     (void) XSetWMProtocols (XtDisplay(top_widget), XtWindow(top_widget),
1084                             &wm_delete_window, 1);
1085 
1086 
1087     image_shell = XtCreatePopupShell("image", transientShellWidgetClass,
1088 				     top_widget, NULL, 0);
1089 
1090     box_widget = XtCreateManagedWidget("box", boxWidgetClass,
1091 				       image_shell, NULL, 0);
1092 
1093     normal_image_widget = XtCreateManagedWidget("normalImage",
1094 						labelWidgetClass,
1095 						box_widget, NULL, 0);
1096 
1097     inverted_image_widget = XtCreateManagedWidget("invertedImage",
1098 						  labelWidgetClass,
1099 						  box_widget, NULL, 0);
1100 
1101     n=0;
1102     XtSetArg(wargs[n], XtNbitmap, BWGetUnzoomedPixmap(bitmap_widget)); n++;
1103     XtSetValues(normal_image_widget, wargs, n);
1104     XtSetValues(inverted_image_widget, wargs, n);
1105 
1106     XtRealizeWidget(image_shell);
1107 
1108     BWNotify(bitmap_widget, (XtActionProc)FixUp);
1109 
1110     FixStatus();
1111 
1112     input_dialog = CreateDialog(top_widget, "input", Okay | Cancel);
1113     error_dialog = CreateDialog(top_widget, "error", Abort | Retry);
1114     qsave_dialog = CreateDialog(top_widget, "qsave", Yes | No | Cancel);
1115 
1116     XawToggleSetCurrent(radio_group, radio_data);
1117     BWEngageRequest(bitmap_widget, PointRequest, True, Plain);
1118 
1119     XtMainLoop();
1120     exit(0);
1121 }
1122