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