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