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