1706f2543Smrg/*
2706f2543Smrg * Copyright 2002 Red Hat Inc., Durham, North Carolina.
3706f2543Smrg *
4706f2543Smrg * All Rights Reserved.
5706f2543Smrg *
6706f2543Smrg * Permission is hereby granted, free of charge, to any person obtaining
7706f2543Smrg * a copy of this software and associated documentation files (the
8706f2543Smrg * "Software"), to deal in the Software without restriction, including
9706f2543Smrg * without limitation on the rights to use, copy, modify, merge,
10706f2543Smrg * publish, distribute, sublicense, and/or sell copies of the Software,
11706f2543Smrg * and to permit persons to whom the Software is furnished to do so,
12706f2543Smrg * subject to the following conditions:
13706f2543Smrg *
14706f2543Smrg * The above copyright notice and this permission notice (including the
15706f2543Smrg * next paragraph) shall be included in all copies or substantial
16706f2543Smrg * portions of the Software.
17706f2543Smrg *
18706f2543Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19706f2543Smrg * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20706f2543Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21706f2543Smrg * NON-INFRINGEMENT.  IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS
22706f2543Smrg * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
23706f2543Smrg * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24706f2543Smrg * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25706f2543Smrg * SOFTWARE.
26706f2543Smrg */
27706f2543Smrg
28706f2543Smrg/*
29706f2543Smrg * Authors:
30706f2543Smrg *   Rickard E. (Rik) Faith <faith@redhat.com>
31706f2543Smrg *
32706f2543Smrg */
33706f2543Smrg
34706f2543Smrg#ifdef HAVE_DMX_CONFIG_H
35706f2543Smrg#include <dmx-config.h>
36706f2543Smrg#endif
37706f2543Smrg
38706f2543Smrg#include <stdio.h>
39706f2543Smrg#include <stdlib.h>
40706f2543Smrg#include <X11/Intrinsic.h>
41706f2543Smrg#include <X11/StringDefs.h>
42706f2543Smrg#include <X11/Xaw/Form.h>
43706f2543Smrg#include <X11/Xaw/Box.h>
44706f2543Smrg/* #include <X11/Xaw/Paned.h> */
45706f2543Smrg#include <X11/Xaw/Command.h>
46706f2543Smrg#include <X11/Xaw/SimpleMenu.h>
47706f2543Smrg#include <X11/Xaw/SmeBSB.h>
48706f2543Smrg#include <X11/Xaw/MenuButton.h>
49706f2543Smrg#include <X11/Xaw/Viewport.h>
50706f2543Smrg#include <X11/Xaw/Dialog.h>
51706f2543Smrg#include <X11/keysym.h>
52706f2543Smrg#include <X11/Xmu/SysUtil.h>
53706f2543Smrg#include "Canvas.h"
54706f2543Smrg
55706f2543Smrg#include "dmxparse.h"
56706f2543Smrg#include "dmxprint.h"
57706f2543Smrg#include "dmxlog.h"
58706f2543Smrg
59706f2543Smrgextern int                 yyparse(void);
60706f2543Smrgextern FILE                *yyin;
61706f2543Smrg
62706f2543Smrg#define DMX_INFO "xdmxconfig v0.9\nCopyright 2002 Red Hat Inc.\n"
63706f2543Smrg
64706f2543Smrg#define DMX_MAIN_WIDTH    800
65706f2543Smrg#define DMX_MAIN_HEIGHT   600
66706f2543Smrg#define DMX_DATA_WIDTH    200
67706f2543Smrg#define DMX_DATA_HEIGHT   200
68706f2543Smrg#define DMX_CANVAS_WIDTH  400
69706f2543Smrg#define DMX_CANVAS_HEIGHT 500
70706f2543Smrg
71706f2543SmrgDMXConfigEntryPtr          dmxConfigEntry;
72706f2543Smrgstatic DMXConfigVirtualPtr dmxConfigCurrent, dmxConfigNewVirtual;
73706f2543Smrgstatic DMXConfigDisplayPtr dmxConfigCurrentDisplay, dmxConfigNewDisplay;
74706f2543Smrgstatic int                 dmxConfigGrabbed, dmxConfigGrabbedFine;
75706f2543Smrgstatic int                 dmxConfigGrabbedX, dmxConfigGrabbedY;
76706f2543Smrgstatic char                *dmxConfigFilename;
77706f2543Smrgstatic GC                  dmxConfigGC, dmxConfigGCRev, dmxConfigGCHL;
78706f2543Smrgstatic int                 dmxConfigGCInit = 0;
79706f2543Smrgstatic Dimension           dmxConfigWidgetWidth, dmxConfigWidgetHeight;
80706f2543Smrgstatic Dimension           dmxConfigWallWidth, dmxConfigWallHeight;
81706f2543Smrgstatic double              dmxConfigScaleX, dmxConfigScaleY;
82706f2543Smrgstatic int                 dmxConfigNotSaved;
83706f2543Smrgstatic enum {
84706f2543Smrg    dmxConfigStateOpen,
85706f2543Smrg    dmxConfigStateSave
86706f2543Smrg}                          dmxConfigState;
87706f2543Smrg
88706f2543Smrg/* Global widgets */
89706f2543Smrgstatic Widget              canvas;
90706f2543Smrgstatic Widget              cnamebox, cdimbox;
91706f2543Smrgstatic Widget              openpopup, opendialog;
92706f2543Smrgstatic Widget              namebox, dimbox, rtbox, origbox;
93706f2543Smrgstatic Widget              okbutton, buttonpopup;
94706f2543Smrgstatic Widget              ecbutton, dcbutton;
95706f2543Smrgstatic Widget              ndbutton0, ndbutton1, edbutton, ddbutton;
96706f2543Smrgstatic Widget              ecpopup, ecdialog0, ecdialog1;
97706f2543Smrgstatic Widget              edpopup, eddialog0, eddialog1, eddialog2;
98706f2543Smrgstatic Widget              aboutpopup, quitpopup;
99706f2543Smrg
100706f2543Smrgstatic void dmxConfigCanvasGCs(void)
101706f2543Smrg{
102706f2543Smrg    Display       *dpy = XtDisplay(canvas);
103706f2543Smrg    Window        win  = XtWindow(canvas);
104706f2543Smrg    XGCValues     gcvals;
105706f2543Smrg    unsigned long mask;
106706f2543Smrg    Colormap      colormap;
107706f2543Smrg    XColor        fg, bg, hl, tmp;
108706f2543Smrg
109706f2543Smrg    if (dmxConfigGCInit++) return;
110706f2543Smrg
111706f2543Smrg    XtVaGetValues(canvas, XtNcolormap, &colormap, NULL);
112706f2543Smrg    XAllocNamedColor(XtDisplay(canvas), colormap, "black", &bg, &tmp);
113706f2543Smrg    XAllocNamedColor(XtDisplay(canvas), colormap, "white", &fg, &tmp);
114706f2543Smrg    XAllocNamedColor(XtDisplay(canvas), colormap, "red",   &hl, &tmp);
115706f2543Smrg
116706f2543Smrg    mask = (GCFunction | GCPlaneMask | GCClipMask | GCForeground |
117706f2543Smrg            GCBackground | GCLineWidth | GCLineStyle | GCCapStyle |
118706f2543Smrg            GCFillStyle);
119706f2543Smrg
120706f2543Smrg                                /* FIXME: copy this from widget */
121706f2543Smrg    gcvals.function   = GXcopy;
122706f2543Smrg    gcvals.plane_mask = AllPlanes;
123706f2543Smrg    gcvals.clip_mask  = None;
124706f2543Smrg    gcvals.foreground = fg.pixel;
125706f2543Smrg    gcvals.background = bg.pixel;
126706f2543Smrg    gcvals.line_width = 0;
127706f2543Smrg    gcvals.line_style = LineSolid;
128706f2543Smrg    gcvals.cap_style  = CapNotLast;
129706f2543Smrg    gcvals.fill_style = FillSolid;
130706f2543Smrg
131706f2543Smrg    dmxConfigGC       = XCreateGC(dpy, win, mask, &gcvals);
132706f2543Smrg    gcvals.foreground = hl.pixel;
133706f2543Smrg    dmxConfigGCHL     = XCreateGC(dpy, win, mask, &gcvals);
134706f2543Smrg    gcvals.foreground = bg.pixel;
135706f2543Smrg    gcvals.background = fg.pixel;
136706f2543Smrg    dmxConfigGCRev    = XCreateGC(dpy, win, mask, &gcvals);
137706f2543Smrg}
138706f2543Smrg
139706f2543Smrgstatic void dmxConfigGetDims(int *maxWidth, int *maxHeight)
140706f2543Smrg{
141706f2543Smrg    DMXConfigSubPtr   pt;
142706f2543Smrg    DMXConfigEntryPtr e;
143706f2543Smrg
144706f2543Smrg    *maxWidth = dmxConfigWallWidth  = 0;
145706f2543Smrg    *maxHeight = dmxConfigWallHeight = 0;
146706f2543Smrg    if (!dmxConfigCurrent) return;
147706f2543Smrg
148706f2543Smrg    dmxConfigWallWidth  = dmxConfigCurrent->width;
149706f2543Smrg    dmxConfigWallHeight = dmxConfigCurrent->height;
150706f2543Smrg    if (!dmxConfigWallWidth || !dmxConfigWallHeight) {
151706f2543Smrg        for (pt = dmxConfigCurrent->subentry; pt; pt = pt->next) {
152706f2543Smrg            if (pt->type == dmxConfigDisplay) {
153706f2543Smrg                int x = pt->display->scrnWidth  + pt->display->rootXOrigin;
154706f2543Smrg                int y = pt->display->scrnHeight + pt->display->rootYOrigin;
155706f2543Smrg                if (x > dmxConfigWallWidth)  dmxConfigWallWidth  = x;
156706f2543Smrg                if (y > dmxConfigWallHeight) dmxConfigWallHeight = y;
157706f2543Smrg            }
158706f2543Smrg        }
159706f2543Smrg    }
160706f2543Smrg                                /* Compute maximums */
161706f2543Smrg    *maxWidth = *maxHeight = 0;
162706f2543Smrg    for (e = dmxConfigEntry; e; e = e->next) {
163706f2543Smrg        if (e->type != dmxConfigVirtual) continue;
164706f2543Smrg        for (pt = e->virtual->subentry; pt; pt = pt->next) {
165706f2543Smrg            if (pt->type == dmxConfigDisplay) {
166706f2543Smrg                int x = pt->display->scrnWidth  + pt->display->rootXOrigin;
167706f2543Smrg                int y = pt->display->scrnHeight + pt->display->rootYOrigin;
168706f2543Smrg                if (x > *maxWidth)  *maxWidth  = x;
169706f2543Smrg                if (y > *maxHeight) *maxHeight = y;
170706f2543Smrg            }
171706f2543Smrg        }
172706f2543Smrg    }
173706f2543Smrg    if (dmxConfigWallWidth  > *maxWidth)  *maxWidth  = dmxConfigWallWidth;
174706f2543Smrg    if (dmxConfigWallHeight > *maxHeight) *maxHeight = dmxConfigWallHeight;
175706f2543Smrg}
176706f2543Smrg
177706f2543Smrgstatic int scalex(int x)   { return (int)((x * dmxConfigScaleX) + .5); }
178706f2543Smrgstatic int scaley(int y)   { return (int)((y * dmxConfigScaleY) + .5); }
179706f2543Smrgstatic int unscalex(int x) { return (int)((x / dmxConfigScaleX) + .5); }
180706f2543Smrgstatic int unscaley(int y) { return (int)((y / dmxConfigScaleY) + .5); }
181706f2543Smrg
182706f2543Smrgstatic void dmxConfigDataUpdate(void)
183706f2543Smrg{
184706f2543Smrg                                /* FIXME: could result in buffer overflows */
185706f2543Smrg    char       cnambuf[512];
186706f2543Smrg    char       cdimbuf[128];
187706f2543Smrg    char       nambuf[512];
188706f2543Smrg    char       dimbuf[128];
189706f2543Smrg    char       rtbuf[128];
190706f2543Smrg    char       offbuf[128];
191706f2543Smrg    const char *name;
192706f2543Smrg
193706f2543Smrg    if (!dmxConfigCurrent) {
194706f2543Smrg        XtVaSetValues(cnamebox,   XtNlabel, "", XtNsensitive, False, NULL);
195706f2543Smrg        XtVaSetValues(cdimbox,    XtNlabel, "", XtNsensitive, False, NULL);
196706f2543Smrg        XtVaSetValues(ecbutton,                 XtNsensitive, False, NULL);
197706f2543Smrg        XtVaSetValues(dcbutton,                 XtNsensitive, False, NULL);
198706f2543Smrg        XtVaSetValues(ndbutton0,                XtNsensitive, False, NULL);
199706f2543Smrg        XtVaSetValues(ndbutton1,                XtNsensitive, False, NULL);
200706f2543Smrg    } else {
201706f2543Smrg        name = dmxConfigCurrent->name;
202706f2543Smrg        XmuSnprintf(cnambuf, sizeof(cnambuf), "%s", name ? name : "");
203706f2543Smrg	XmuSnprintf(cdimbuf, sizeof(cdimbuf), "%dx%d",
204706f2543Smrg                    dmxConfigWallWidth, dmxConfigWallHeight);
205706f2543Smrg        XtVaSetValues(cnamebox,   XtNlabel, cnambuf, XtNsensitive, True, NULL);
206706f2543Smrg        XtVaSetValues(cdimbox,    XtNlabel, cdimbuf, XtNsensitive, True, NULL);
207706f2543Smrg        XtVaSetValues(ecbutton,                      XtNsensitive, True, NULL);
208706f2543Smrg        XtVaSetValues(dcbutton,                      XtNsensitive, True, NULL);
209706f2543Smrg        XtVaSetValues(ndbutton0,                     XtNsensitive, True, NULL);
210706f2543Smrg        XtVaSetValues(ndbutton1,                     XtNsensitive, True, NULL);
211706f2543Smrg    }
212706f2543Smrg
213706f2543Smrg    if (!dmxConfigCurrentDisplay) {
214706f2543Smrg        XtVaSetValues(namebox, XtNlabel, "", XtNsensitive, False, NULL);
215706f2543Smrg        XtVaSetValues(dimbox,  XtNlabel, "", XtNsensitive, False, NULL);
216706f2543Smrg        XtVaSetValues(rtbox,   XtNlabel, "", XtNsensitive, False, NULL);
217706f2543Smrg        XtVaSetValues(origbox, XtNlabel, "", XtNsensitive, False, NULL);
218706f2543Smrg        XtVaSetValues(edbutton,              XtNsensitive, False, NULL);
219706f2543Smrg        XtVaSetValues(ddbutton,              XtNsensitive, False, NULL);
220706f2543Smrg    } else {
221706f2543Smrg        name = dmxConfigCurrentDisplay->name;
222706f2543Smrg        XmuSnprintf(nambuf, sizeof(nambuf), "%s", name ? name : "");
223706f2543Smrg        XmuSnprintf(dimbuf, sizeof(dimbuf), "%dx%d%c%d%c%d",
224706f2543Smrg                    dmxConfigCurrentDisplay->scrnWidth,
225706f2543Smrg                    dmxConfigCurrentDisplay->scrnHeight,
226706f2543Smrg                    dmxConfigCurrentDisplay->scrnXSign < 0 ? '-' : '+',
227706f2543Smrg                    dmxConfigCurrentDisplay->scrnX,
228706f2543Smrg                    dmxConfigCurrentDisplay->scrnYSign < 0 ? '-' : '+',
229706f2543Smrg                    dmxConfigCurrentDisplay->scrnY);
230706f2543Smrg        XmuSnprintf(rtbuf, sizeof(dimbuf), "%dx%d%c%d%c%d",
231706f2543Smrg                    dmxConfigCurrentDisplay->rootWidth,
232706f2543Smrg                    dmxConfigCurrentDisplay->rootHeight,
233706f2543Smrg                    dmxConfigCurrentDisplay->rootXSign < 0 ? '-' : '+',
234706f2543Smrg                    dmxConfigCurrentDisplay->rootX,
235706f2543Smrg                    dmxConfigCurrentDisplay->rootYSign < 0 ? '-' : '+',
236706f2543Smrg                    dmxConfigCurrentDisplay->rootY);
237706f2543Smrg        XmuSnprintf(offbuf, sizeof(offbuf), "@%dx%d",
238706f2543Smrg                    dmxConfigCurrentDisplay->rootXOrigin,
239706f2543Smrg                    dmxConfigCurrentDisplay->rootYOrigin);
240706f2543Smrg        XtVaSetValues(namebox, XtNlabel, nambuf, XtNsensitive, True, NULL);
241706f2543Smrg        XtVaSetValues(dimbox,  XtNlabel, dimbuf, XtNsensitive, True, NULL);
242706f2543Smrg        XtVaSetValues(rtbox,   XtNlabel, rtbuf,  XtNsensitive, True, NULL);
243706f2543Smrg        XtVaSetValues(origbox, XtNlabel, offbuf, XtNsensitive, True, NULL);
244706f2543Smrg        XtVaSetValues(edbutton,                  XtNsensitive, True, NULL);
245706f2543Smrg        XtVaSetValues(ddbutton,                  XtNsensitive, True, NULL);
246706f2543Smrg    }
247706f2543Smrg}
248706f2543Smrg
249706f2543Smrgstatic void dmxConfigCanvasUpdate(void)
250706f2543Smrg{
251706f2543Smrg    DMXConfigSubPtr pt;
252706f2543Smrg    Display         *dpy     = XtDisplay(canvas);
253706f2543Smrg    Window          win      = XtWindow(canvas);
254706f2543Smrg    GContext        gcontext = XGContextFromGC(dmxConfigGC);
255706f2543Smrg    XFontStruct     *fs;
256706f2543Smrg    int             w, h;
257706f2543Smrg
258706f2543Smrg    XFillRectangle(dpy, win, dmxConfigGCRev,
259706f2543Smrg                   0, 0, dmxConfigWidgetWidth, dmxConfigWidgetHeight);
260706f2543Smrg    dmxConfigDataUpdate();
261706f2543Smrg    if (!dmxConfigCurrent) return;
262706f2543Smrg
263706f2543Smrg    w = scalex(dmxConfigWallWidth);
264706f2543Smrg    h = scaley(dmxConfigWallHeight);
265706f2543Smrg    if (w > dmxConfigWidgetWidth - 1)  w = dmxConfigWidgetWidth - 1;
266706f2543Smrg    if (h > dmxConfigWidgetHeight - 1) h = dmxConfigWidgetHeight - 1;
267706f2543Smrg    XDrawRectangle(dpy, win, dmxConfigGC, 0, 0, w, h);
268706f2543Smrg    fs = XQueryFont(dpy, gcontext);
269706f2543Smrg    for (pt = dmxConfigCurrent->subentry; pt; pt = pt->next) {
270706f2543Smrg        int x, y, len;
271706f2543Smrg        int xo = 3, yo = fs->ascent + fs->descent + 2;
272706f2543Smrg        GC  gc;
273706f2543Smrg
274706f2543Smrg        if (pt->type != dmxConfigDisplay) continue;
275706f2543Smrg        gc  = (pt->display == dmxConfigCurrentDisplay
276706f2543Smrg               ? dmxConfigGCHL
277706f2543Smrg               : dmxConfigGC);
278706f2543Smrg        x   = scalex(pt->display->rootXOrigin);
279706f2543Smrg        y   = scaley(pt->display->rootYOrigin);
280706f2543Smrg        w   = scalex(pt->display->scrnWidth);
281706f2543Smrg        h   = scaley(pt->display->scrnHeight);
282706f2543Smrg        len = pt->display->name ? strlen(pt->display->name) : 0;
283706f2543Smrg        if (x > dmxConfigWidgetWidth - 1)  x = dmxConfigWidgetWidth - 1;
284706f2543Smrg        if (y > dmxConfigWidgetHeight - 1) y = dmxConfigWidgetHeight - 1;
285706f2543Smrg        XDrawRectangle(dpy, win, gc, x, y, w, h);
286706f2543Smrg        if (fs && len) {
287706f2543Smrg            while (len && XTextWidth(fs, pt->display->name, len) >= w - 2 * xo)
288706f2543Smrg                --len;
289706f2543Smrg            if (len)
290706f2543Smrg                XDrawString(dpy, win, gc, x+xo, y+yo, pt->display->name, len);
291706f2543Smrg        }
292706f2543Smrg    }
293706f2543Smrg    if (fs) XFreeFontInfo(NULL, fs, 0);
294706f2543Smrg}
295706f2543Smrg
296706f2543Smrgstatic void dmxConfigCanvasDraw(Region region)
297706f2543Smrg{
298706f2543Smrg    Display *dpy = XtDisplay(canvas);
299706f2543Smrg    int     maxWidth, maxHeight;
300706f2543Smrg
301706f2543Smrg    dmxConfigCanvasGCs();
302706f2543Smrg    if (region) {
303706f2543Smrg        XSetRegion(dpy, dmxConfigGC,    region);
304706f2543Smrg        XSetRegion(dpy, dmxConfigGCRev, region);
305706f2543Smrg        XSetRegion(dpy, dmxConfigGCHL,  region);
306706f2543Smrg    }
307706f2543Smrg    XtVaGetValues(canvas,
308706f2543Smrg                  XtNwidth, &dmxConfigWidgetWidth,
309706f2543Smrg                  XtNheight, &dmxConfigWidgetHeight,
310706f2543Smrg                  NULL);
311706f2543Smrg    dmxConfigGetDims(&maxWidth, &maxHeight);
312706f2543Smrg    dmxConfigScaleX = (double)dmxConfigWidgetWidth  / maxWidth;
313706f2543Smrg    dmxConfigScaleY = (double)dmxConfigWidgetHeight / maxHeight;
314706f2543Smrg    if (dmxConfigScaleX > dmxConfigScaleY) dmxConfigScaleX = dmxConfigScaleY;
315706f2543Smrg    if (dmxConfigScaleY > dmxConfigScaleX) dmxConfigScaleY = dmxConfigScaleX;
316706f2543Smrg    dmxConfigCanvasUpdate();
317706f2543Smrg    if (region) {
318706f2543Smrg        XSetClipMask(dpy, dmxConfigGC,    None);
319706f2543Smrg        XSetClipMask(dpy, dmxConfigGCRev, None);
320706f2543Smrg        XSetClipMask(dpy, dmxConfigGCHL,  None);
321706f2543Smrg    }
322706f2543Smrg}
323706f2543Smrg
324706f2543Smrgstatic void dmxConfigSelectCallback(Widget w, XtPointer closure,
325706f2543Smrg                                    XtPointer callData)
326706f2543Smrg{
327706f2543Smrg    dmxConfigCurrent = closure;
328706f2543Smrg    dmxConfigVirtualPrint(stdout, dmxConfigCurrent);
329706f2543Smrg    dmxConfigCanvasDraw(NULL);
330706f2543Smrg}
331706f2543Smrg
332706f2543Smrgstatic void dmxConfigCopystrings(void)
333706f2543Smrg{
334706f2543Smrg    DMXConfigEntryPtr pt;
335706f2543Smrg    DMXConfigSubPtr   sub;
336706f2543Smrg
337706f2543Smrg    if (!dmxConfigCurrent) return;
338706f2543Smrg
339706f2543Smrg                                /* FIXME: this is all a per-config file
340706f2543Smrg                                 * memory leak */
341706f2543Smrg    for (pt = dmxConfigEntry; pt; pt = pt->next) {
342706f2543Smrg        if (pt->type == dmxConfigVirtual) {
343706f2543Smrg            pt->virtual->name = XtNewString(pt->virtual->name
344706f2543Smrg                                            ? pt->virtual->name
345706f2543Smrg                                            : "");
346706f2543Smrg
347706f2543Smrg            for (sub = pt->virtual->subentry; sub; sub = sub->next) {
348706f2543Smrg                if (sub->type != dmxConfigDisplay) continue;
349706f2543Smrg                sub->display->name = XtNewString(sub->display->name
350706f2543Smrg                                                 ? sub->display->name
351706f2543Smrg                                                 : "");
352706f2543Smrg            }
353706f2543Smrg        }
354706f2543Smrg    }
355706f2543Smrg}
356706f2543Smrg
357706f2543Smrgstatic void dmxConfigGetValueString(char **d, Widget w)
358706f2543Smrg{
359706f2543Smrg    const char *tmp = XawDialogGetValueString(w);
360706f2543Smrg    if (*d) XtFree(*d);
361706f2543Smrg    *d = XtNewString(tmp);
362706f2543Smrg}
363706f2543Smrg
364706f2543Smrgstatic void dmxConfigSetupCnamemenu(void)
365706f2543Smrg{
366706f2543Smrg    static Widget     cnamemenu = NULL;
367706f2543Smrg    Widget            w;
368706f2543Smrg    DMXConfigEntryPtr pt;
369706f2543Smrg
370706f2543Smrg    if (cnamemenu) XtDestroyWidget(cnamemenu);
371706f2543Smrg    cnamemenu = NULL;
372706f2543Smrg
373706f2543Smrg    if (!dmxConfigCurrent) return;
374706f2543Smrg    cnamemenu = XtVaCreatePopupShell("cnamemenu", simpleMenuWidgetClass,
375706f2543Smrg                                     cnamebox,
376706f2543Smrg                                     NULL);
377706f2543Smrg
378706f2543Smrg    for (pt = dmxConfigEntry; pt; pt = pt->next) {
379706f2543Smrg        if (pt->type == dmxConfigVirtual) {
380706f2543Smrg            w = XtVaCreateManagedWidget(pt->virtual->name
381706f2543Smrg                                        ? pt->virtual->name
382706f2543Smrg                                        : "",
383706f2543Smrg                                        smeBSBObjectClass, cnamemenu,
384706f2543Smrg                                        NULL);
385706f2543Smrg            XtAddCallback(w, XtNcallback,
386706f2543Smrg                          dmxConfigSelectCallback, pt->virtual);
387706f2543Smrg        }
388706f2543Smrg    }
389706f2543Smrg}
390706f2543Smrg
391706f2543Smrgstatic void dmxConfigReadFile(void)
392706f2543Smrg{
393706f2543Smrg    FILE              *str;
394706f2543Smrg    DMXConfigEntryPtr pt;
395706f2543Smrg
396706f2543Smrg    if (!(str = fopen(dmxConfigFilename, "r"))) {
397706f2543Smrg        dmxLog(dmxWarning, "Unable to read configuration file %s\n",
398706f2543Smrg               dmxConfigFilename);
399706f2543Smrg        return;
400706f2543Smrg    }
401706f2543Smrg    yyin    = str;
402706f2543Smrg    yydebug = 0;
403706f2543Smrg    yyparse();
404706f2543Smrg    fclose(str);
405706f2543Smrg    dmxLog(dmxInfo, "Read configuration file %s\n", dmxConfigFilename);
406706f2543Smrg
407706f2543Smrg    for (pt = dmxConfigEntry; pt; pt = pt->next) {
408706f2543Smrg        if (pt->type == dmxConfigVirtual) {
409706f2543Smrg            dmxConfigCurrent = pt->virtual;
410706f2543Smrg            break;
411706f2543Smrg        }
412706f2543Smrg    }
413706f2543Smrg
414706f2543Smrg
415706f2543Smrg
416706f2543Smrg    if (XtIsRealized(canvas)) {
417706f2543Smrg        dmxConfigCopystrings();
418706f2543Smrg        dmxConfigSetupCnamemenu();
419706f2543Smrg        dmxConfigCanvasDraw(NULL);
420706f2543Smrg    }
421706f2543Smrg    dmxConfigVirtualPrint(stdout, dmxConfigCurrent);
422706f2543Smrg}
423706f2543Smrg
424706f2543Smrgstatic void dmxConfigWriteFile(void)
425706f2543Smrg{
426706f2543Smrg    FILE              *str;
427706f2543Smrg
428706f2543Smrg    if (!(str = fopen(dmxConfigFilename, "w"))) {
429706f2543Smrg        dmxLog(dmxWarning, "Unable to write configuration file %s\n",
430706f2543Smrg               dmxConfigFilename);
431706f2543Smrg        return;
432706f2543Smrg    }
433706f2543Smrg    dmxConfigPrint(str, dmxConfigEntry);
434706f2543Smrg    fclose(str);
435706f2543Smrg}
436706f2543Smrg
437706f2543Smrgstatic DMXConfigDisplayPtr dmxConfigFindDisplay(int x, int y)
438706f2543Smrg{
439706f2543Smrg    DMXConfigSubPtr pt;
440706f2543Smrg
441706f2543Smrg    if (!dmxConfigCurrent) return NULL;
442706f2543Smrg    for (pt = dmxConfigCurrent->subentry; pt; pt = pt->next) {
443706f2543Smrg        DMXConfigDisplayPtr d = pt->display;
444706f2543Smrg        if (pt->type != dmxConfigDisplay) continue;
445706f2543Smrg        if (x >= scalex(d->rootXOrigin)
446706f2543Smrg            && x <= scalex(d->rootXOrigin + d->scrnWidth)
447706f2543Smrg            && y >= scaley(d->rootYOrigin)
448706f2543Smrg            && y <= scaley(d->rootYOrigin + d->scrnHeight)) return d;
449706f2543Smrg    }
450706f2543Smrg    return NULL;
451706f2543Smrg}
452706f2543Smrg
453706f2543Smrgstatic void dmxConfigSetPopupPosition(Widget popup)
454706f2543Smrg{
455706f2543Smrg    Position     x, y;
456706f2543Smrg    Window       t1, t2;
457706f2543Smrg    int          root_x, root_y;
458706f2543Smrg    int          temp_x, temp_y;
459706f2543Smrg    unsigned int temp;
460706f2543Smrg
461706f2543Smrg
462706f2543Smrg    XtRealizeWidget(popup);
463706f2543Smrg    if (!XQueryPointer(XtDisplay(popup), XtWindow(popup), &t1, &t2,
464706f2543Smrg                       &root_x, &root_y, &temp_x, &temp_y, &temp))
465706f2543Smrg        root_x = root_y = 0;
466706f2543Smrg
467706f2543Smrg    x = root_x - 5;
468706f2543Smrg    y = root_y - 5;
469706f2543Smrg    XtVaSetValues(popup, XtNx, x, XtNy, y, NULL);
470706f2543Smrg}
471706f2543Smrg
472706f2543Smrgstatic void dmxConfigPlaceMenu(Widget w, XEvent *event,
473706f2543Smrg                               String *params, Cardinal *num_params)
474706f2543Smrg{
475706f2543Smrg    dmxConfigSetPopupPosition(buttonpopup);
476706f2543Smrg}
477706f2543Smrg
478706f2543Smrgstatic void dmxConfigMove(int deltaX, int deltaY)
479706f2543Smrg{
480706f2543Smrg    dmxConfigCurrentDisplay->rootXOrigin += deltaX;
481706f2543Smrg    dmxConfigCurrentDisplay->rootYOrigin += deltaY;
482706f2543Smrg    if (dmxConfigCurrentDisplay->rootXOrigin < 0)
483706f2543Smrg        dmxConfigCurrentDisplay->rootXOrigin = 0;
484706f2543Smrg    if (dmxConfigCurrentDisplay->rootYOrigin < 0)
485706f2543Smrg        dmxConfigCurrentDisplay->rootYOrigin = 0;
486706f2543Smrg    if (dmxConfigWallWidth && dmxConfigWallHeight) {
487706f2543Smrg        if (dmxConfigCurrentDisplay->rootXOrigin >= dmxConfigWallWidth)
488706f2543Smrg            dmxConfigCurrentDisplay->rootXOrigin = dmxConfigWallWidth - 1;
489706f2543Smrg        if (dmxConfigCurrentDisplay->rootYOrigin >= dmxConfigWallHeight)
490706f2543Smrg            dmxConfigCurrentDisplay->rootYOrigin = dmxConfigWallHeight - 1;
491706f2543Smrg    }
492706f2543Smrg    dmxConfigCanvasUpdate();
493706f2543Smrg    dmxConfigNotSaved = 1;
494706f2543Smrg}
495706f2543Smrg
496706f2543Smrgstatic void dmxConfigCanvasInput(Widget w, XtPointer closure,
497706f2543Smrg                                 XtPointer callData)
498706f2543Smrg{
499706f2543Smrg    XEvent              *e      = (XEvent *)callData;
500706f2543Smrg    DMXConfigDisplayPtr display = NULL;
501706f2543Smrg
502706f2543Smrg    switch (e->type) {
503706f2543Smrg    case ButtonPress:
504706f2543Smrg        if (e->xbutton.button == Button1) {
505706f2543Smrg            dmxConfigGrabbed     = 1;
506706f2543Smrg            dmxConfigGrabbedFine = 0;
507706f2543Smrg            dmxConfigGrabbedX    = e->xbutton.x;
508706f2543Smrg            dmxConfigGrabbedY    = e->xbutton.y;
509706f2543Smrg        }
510706f2543Smrg        if (e->xbutton.button == Button2) {
511706f2543Smrg            dmxConfigGrabbed     = 1;
512706f2543Smrg            dmxConfigGrabbedFine = 1;
513706f2543Smrg            dmxConfigGrabbedX    = e->xbutton.x;
514706f2543Smrg            dmxConfigGrabbedY    = e->xbutton.y;
515706f2543Smrg        }
516706f2543Smrg        break;
517706f2543Smrg    case ButtonRelease:
518706f2543Smrg        if (e->xbutton.button == Button1) dmxConfigGrabbed = 0;
519706f2543Smrg        if (e->xbutton.button == Button2) dmxConfigGrabbed = 0;
520706f2543Smrg        break;
521706f2543Smrg    case MotionNotify:
522706f2543Smrg        if (dmxConfigGrabbed && dmxConfigCurrentDisplay) {
523706f2543Smrg            int deltaX = e->xmotion.x - dmxConfigGrabbedX;
524706f2543Smrg            int deltaY = e->xmotion.y - dmxConfigGrabbedY;
525706f2543Smrg            dmxConfigMove(dmxConfigGrabbedFine ? deltaX : unscalex(deltaX),
526706f2543Smrg                          dmxConfigGrabbedFine ? deltaY : unscaley(deltaY));
527706f2543Smrg            dmxConfigGrabbedX = e->xmotion.x;
528706f2543Smrg            dmxConfigGrabbedY = e->xmotion.y;
529706f2543Smrg        } else {
530706f2543Smrg            display = dmxConfigFindDisplay(e->xmotion.x, e->xmotion.y);
531706f2543Smrg            if (display != dmxConfigCurrentDisplay) {
532706f2543Smrg                dmxConfigCurrentDisplay = display;
533706f2543Smrg                dmxConfigCanvasUpdate();
534706f2543Smrg            }
535706f2543Smrg        }
536706f2543Smrg        break;
537706f2543Smrg    case KeyPress:
538706f2543Smrg        switch (XLookupKeysym(&e->xkey, 0)) {
539706f2543Smrg        case XK_Right: dmxConfigMove(1,0);  break;
540706f2543Smrg        case XK_Left:  dmxConfigMove(-1,0); break;
541706f2543Smrg        case XK_Down:  dmxConfigMove(0,1);  break;
542706f2543Smrg        case XK_Up:    dmxConfigMove(0,-1); break;
543706f2543Smrg        }
544706f2543Smrg        break;
545706f2543Smrg    }
546706f2543Smrg}
547706f2543Smrg
548706f2543Smrgstatic void dmxConfigCanvasResize(Widget w, XtPointer closure,
549706f2543Smrg                                  XtPointer callData)
550706f2543Smrg{
551706f2543Smrg    dmxConfigCanvasDraw(NULL);
552706f2543Smrg}
553706f2543Smrg
554706f2543Smrgstatic void dmxConfigCanvasExpose(Widget w, XtPointer closure,
555706f2543Smrg                                  XtPointer callData)
556706f2543Smrg{
557706f2543Smrg    CanvasExposeDataPtr data = (CanvasExposeDataPtr)callData;
558706f2543Smrg
559706f2543Smrg    dmxConfigCanvasDraw(data->region);
560706f2543Smrg}
561706f2543Smrg
562706f2543Smrgstatic void dmxConfigOpenCallback(Widget w, XtPointer closure,
563706f2543Smrg                                  XtPointer callData)
564706f2543Smrg{
565706f2543Smrg    dmxConfigState = dmxConfigStateOpen;
566706f2543Smrg    XtVaSetValues(okbutton, XtNlabel, "Open", NULL);
567706f2543Smrg    dmxConfigSetPopupPosition(openpopup);
568706f2543Smrg    XtPopup(openpopup, XtGrabExclusive);
569706f2543Smrg}
570706f2543Smrg
571706f2543Smrgstatic void dmxConfigSaveCallback(Widget w, XtPointer closure,
572706f2543Smrg                                  XtPointer callData)
573706f2543Smrg{
574706f2543Smrg    dmxConfigState = dmxConfigStateSave;
575706f2543Smrg    XtVaSetValues(okbutton, XtNlabel, "Save", NULL);
576706f2543Smrg    dmxConfigSetPopupPosition(openpopup);
577706f2543Smrg    XtPopup(openpopup, XtGrabExclusive);
578706f2543Smrg}
579706f2543Smrg
580706f2543Smrgstatic void dmxConfigOkCallback(Widget w, XtPointer closure,
581706f2543Smrg                                XtPointer callData)
582706f2543Smrg{
583706f2543Smrg    dmxConfigGetValueString(&dmxConfigFilename, opendialog);
584706f2543Smrg    XtPopdown(openpopup);
585706f2543Smrg    if (dmxConfigState == dmxConfigStateOpen) dmxConfigReadFile();
586706f2543Smrg    else                                      dmxConfigWriteFile();
587706f2543Smrg    dmxConfigNotSaved = 0;
588706f2543Smrg}
589706f2543Smrg
590706f2543Smrgstatic void dmxConfigCanCallback(Widget w, XtPointer closure,
591706f2543Smrg                                 XtPointer callData)
592706f2543Smrg{
593706f2543Smrg    XtPopdown(openpopup);
594706f2543Smrg}
595706f2543Smrg
596706f2543Smrgstatic void dmxConfigECCallback(Widget w, XtPointer closure,
597706f2543Smrg                                XtPointer callData)
598706f2543Smrg{
599706f2543Smrg    char buf[256];              /* RATS: Only used in XmuSnprintf */
600706f2543Smrg
601706f2543Smrg    if (!dmxConfigCurrent) return;
602706f2543Smrg    dmxConfigSetPopupPosition(ecpopup);
603706f2543Smrg    XtVaSetValues(ecdialog0, XtNvalue,
604706f2543Smrg                  dmxConfigCurrent->name ? dmxConfigCurrent->name : "",
605706f2543Smrg                  NULL);
606706f2543Smrg    XmuSnprintf(buf, sizeof(buf), "%dx%d",
607706f2543Smrg                dmxConfigCurrent->width, dmxConfigCurrent->height);
608706f2543Smrg    XtVaSetValues(ecdialog1, XtNvalue, buf, NULL);
609706f2543Smrg    XtPopup(ecpopup, XtGrabExclusive);
610706f2543Smrg}
611706f2543Smrg
612706f2543Smrgstatic void dmxConfigNCCallback(Widget w, XtPointer closure,
613706f2543Smrg                                XtPointer callData)
614706f2543Smrg{
615706f2543Smrg    int width = 1280*2, height = 1024*2;
616706f2543Smrg
617706f2543Smrg    if (dmxConfigCurrent) {
618706f2543Smrg        width  = dmxConfigCurrent->width;
619706f2543Smrg        height = dmxConfigCurrent->height;
620706f2543Smrg    }
621706f2543Smrg
622706f2543Smrg    dmxConfigCurrent         = dmxConfigCreateVirtual(NULL, NULL, NULL,
623706f2543Smrg                                                      NULL, NULL, NULL);
624706f2543Smrg    dmxConfigNewVirtual      = dmxConfigCurrent;
625706f2543Smrg    dmxConfigCurrent->width  = width;
626706f2543Smrg    dmxConfigCurrent->height = height;
627706f2543Smrg    dmxConfigEntry = dmxConfigAddEntry(dmxConfigEntry, dmxConfigVirtual, NULL,
628706f2543Smrg                                       dmxConfigCurrent);
629706f2543Smrg    dmxConfigECCallback(w, closure, callData);
630706f2543Smrg}
631706f2543Smrg
632706f2543Smrgstatic void dmxConfigDCCallback(Widget w, XtPointer closure,
633706f2543Smrg                                XtPointer callData)
634706f2543Smrg{
635706f2543Smrg    DMXConfigEntryPtr pt;
636706f2543Smrg
637706f2543Smrg    if (!dmxConfigEntry) return;
638706f2543Smrg    if (dmxConfigEntry
639706f2543Smrg        && dmxConfigEntry->type == dmxConfigVirtual
640706f2543Smrg        && dmxConfigEntry->virtual == dmxConfigCurrent) {
641706f2543Smrg        dmxConfigEntry = dmxConfigEntry->next;
642706f2543Smrg    } else {
643706f2543Smrg        for (pt = dmxConfigEntry; pt && pt->next; pt = pt->next)
644706f2543Smrg            if (pt->next->type == dmxConfigVirtual
645706f2543Smrg                && pt->next->virtual == dmxConfigCurrent) {
646706f2543Smrg                pt->next = pt->next->next;
647706f2543Smrg                break;
648706f2543Smrg            }
649706f2543Smrg    }
650706f2543Smrg    dmxConfigFreeVirtual(dmxConfigCurrent);
651706f2543Smrg    dmxConfigCurrent        = NULL;
652706f2543Smrg    dmxConfigCurrentDisplay = NULL;
653706f2543Smrg
654706f2543Smrg                                /* Make the first entry current */
655706f2543Smrg    for (pt = dmxConfigEntry; pt; pt = pt->next) {
656706f2543Smrg        if (pt->type == dmxConfigVirtual) {
657706f2543Smrg            dmxConfigCurrent = pt->virtual;
658706f2543Smrg            break;
659706f2543Smrg        }
660706f2543Smrg    }
661706f2543Smrg
662706f2543Smrg    dmxConfigSetupCnamemenu();
663706f2543Smrg    dmxConfigCanvasDraw(NULL);
664706f2543Smrg}
665706f2543Smrg
666706f2543Smrgstatic void dmxConfigECOkCallback(Widget w, XtPointer closure,
667706f2543Smrg                                  XtPointer callData)
668706f2543Smrg{
669706f2543Smrg    const char *value;
670706f2543Smrg    char       *endpt;
671706f2543Smrg
672706f2543Smrg    dmxConfigGetValueString((char **)&dmxConfigCurrent->name, ecdialog0);
673706f2543Smrg    value                    = XawDialogGetValueString(ecdialog1);
674706f2543Smrg    dmxConfigCurrent->width  = strtol(value, &endpt, 10);
675706f2543Smrg    dmxConfigCurrent->height = strtol(endpt+1, NULL, 10);
676706f2543Smrg    XtPopdown(ecpopup);
677706f2543Smrg    dmxConfigCurrentDisplay = NULL;
678706f2543Smrg    dmxConfigNewVirtual     = NULL;
679706f2543Smrg    dmxConfigSetupCnamemenu();
680706f2543Smrg    dmxConfigCanvasDraw(NULL);
681706f2543Smrg    dmxConfigNotSaved = 1;
682706f2543Smrg}
683706f2543Smrg
684706f2543Smrgstatic void dmxConfigECCanCallback(Widget w, XtPointer closure,
685706f2543Smrg                                   XtPointer callData)
686706f2543Smrg{
687706f2543Smrg    if (dmxConfigNewVirtual) dmxConfigDCCallback(w, closure, callData);
688706f2543Smrg    dmxConfigNewVirtual     = NULL;
689706f2543Smrg    XtPopdown(ecpopup);
690706f2543Smrg}
691706f2543Smrg
692706f2543Smrgstatic void dmxConfigEDCallback(Widget w, XtPointer closure,
693706f2543Smrg                                XtPointer callData)
694706f2543Smrg{
695706f2543Smrg    char buf[256];              /* RATS: Only used in XmuSnprintf */
696706f2543Smrg
697706f2543Smrg    if (!dmxConfigCurrent || !dmxConfigCurrentDisplay) return;
698706f2543Smrg    dmxConfigSetPopupPosition(edpopup);
699706f2543Smrg    XtVaSetValues(eddialog0, XtNvalue,
700706f2543Smrg                  dmxConfigCurrentDisplay->name
701706f2543Smrg                  ? dmxConfigCurrentDisplay->name
702706f2543Smrg                  : "",
703706f2543Smrg                  NULL);
704706f2543Smrg    XmuSnprintf(buf, sizeof(buf), "%dx%d%c%d%c%d",
705706f2543Smrg                dmxConfigCurrentDisplay->scrnWidth,
706706f2543Smrg                dmxConfigCurrentDisplay->scrnHeight,
707706f2543Smrg                dmxConfigCurrentDisplay->scrnXSign < 0 ? '-' : '+',
708706f2543Smrg                dmxConfigCurrentDisplay->scrnY,
709706f2543Smrg                dmxConfigCurrentDisplay->scrnYSign < 0 ? '-' : '+',
710706f2543Smrg                dmxConfigCurrentDisplay->scrnY);
711706f2543Smrg    XtVaSetValues(eddialog1, XtNvalue, buf, NULL);
712706f2543Smrg    XmuSnprintf(buf, sizeof(buf), "@%dx%d",
713706f2543Smrg                dmxConfigCurrentDisplay->rootXOrigin,
714706f2543Smrg                dmxConfigCurrentDisplay->rootYOrigin);
715706f2543Smrg    XtVaSetValues(eddialog2, XtNvalue, buf, NULL);
716706f2543Smrg    XtPopup(edpopup, XtGrabExclusive);
717706f2543Smrg}
718706f2543Smrg
719706f2543Smrgstatic void dmxConfigNDCallback(Widget w, XtPointer closure,
720706f2543Smrg                                XtPointer callData)
721706f2543Smrg{
722706f2543Smrg    int width = 1280, height = 1024;
723706f2543Smrg
724706f2543Smrg    if (!dmxConfigCurrent) return;
725706f2543Smrg    if (dmxConfigCurrentDisplay) {
726706f2543Smrg        width  = dmxConfigCurrentDisplay->scrnWidth;
727706f2543Smrg        height = dmxConfigCurrentDisplay->scrnHeight;
728706f2543Smrg    }
729706f2543Smrg    dmxConfigCurrentDisplay = dmxConfigCreateDisplay(NULL, NULL, NULL,
730706f2543Smrg                                                     NULL, NULL);
731706f2543Smrg    dmxConfigNewDisplay     = dmxConfigCurrentDisplay;
732706f2543Smrg    dmxConfigCurrentDisplay->scrnWidth  = width;
733706f2543Smrg    dmxConfigCurrentDisplay->scrnHeight = height;
734706f2543Smrg
735706f2543Smrg    dmxConfigCurrent->subentry
736706f2543Smrg        = dmxConfigAddSub(dmxConfigCurrent->subentry,
737706f2543Smrg                          dmxConfigSubDisplay(dmxConfigCurrentDisplay));
738706f2543Smrg    dmxConfigEDCallback(w, closure, callData);
739706f2543Smrg}
740706f2543Smrg
741706f2543Smrgstatic void dmxConfigDDCallback(Widget w, XtPointer closure,
742706f2543Smrg                                XtPointer callData)
743706f2543Smrg{
744706f2543Smrg    DMXConfigSubPtr pt;
745706f2543Smrg
746706f2543Smrg    if (!dmxConfigCurrent || !dmxConfigCurrentDisplay) return;
747706f2543Smrg                                /* First */
748706f2543Smrg    if (dmxConfigCurrent->subentry
749706f2543Smrg        && dmxConfigCurrent->subentry->type == dmxConfigDisplay
750706f2543Smrg        && dmxConfigCurrent->subentry->display == dmxConfigCurrentDisplay) {
751706f2543Smrg        dmxConfigCurrent->subentry = dmxConfigCurrent->subentry->next;
752706f2543Smrg    } else {
753706f2543Smrg        for (pt = dmxConfigCurrent->subentry; pt && pt->next; pt = pt->next)
754706f2543Smrg            if (pt->next->type == dmxConfigDisplay
755706f2543Smrg                && pt->next->display == dmxConfigCurrentDisplay) {
756706f2543Smrg                pt->next = pt->next->next;
757706f2543Smrg                break;
758706f2543Smrg            }
759706f2543Smrg    }
760706f2543Smrg    dmxConfigFreeDisplay(dmxConfigCurrentDisplay);
761706f2543Smrg    dmxConfigCurrentDisplay = NULL;
762706f2543Smrg    dmxConfigSetupCnamemenu();
763706f2543Smrg    dmxConfigCanvasDraw(NULL);
764706f2543Smrg}
765706f2543Smrg
766706f2543Smrgstatic void dmxConfigAboutCallback(Widget w, XtPointer closure,
767706f2543Smrg                                   XtPointer callData)
768706f2543Smrg{
769706f2543Smrg    dmxConfigSetPopupPosition(aboutpopup);
770706f2543Smrg    XtPopup(aboutpopup, XtGrabExclusive);
771706f2543Smrg}
772706f2543Smrg
773706f2543Smrgstatic void dmxConfigAboutOkCallback(Widget w, XtPointer closure,
774706f2543Smrg                                     XtPointer CallData)
775706f2543Smrg{
776706f2543Smrg    XtPopdown(aboutpopup);
777706f2543Smrg}
778706f2543Smrg
779706f2543Smrgstatic void dmxConfigQuitCallback(Widget w, XtPointer closure,
780706f2543Smrg                                  XtPointer callData)
781706f2543Smrg{
782706f2543Smrg    if (dmxConfigNotSaved) {
783706f2543Smrg        dmxConfigSetPopupPosition(quitpopup);
784706f2543Smrg        XtPopup(quitpopup, XtGrabExclusive);
785706f2543Smrg        return;
786706f2543Smrg    }
787706f2543Smrg    exit(0);
788706f2543Smrg}
789706f2543Smrg
790706f2543Smrgstatic void dmxConfigQuitOkCallback(Widget w, XtPointer closure,
791706f2543Smrg                                    XtPointer callData)
792706f2543Smrg{
793706f2543Smrg    XtPopdown(quitpopup);
794706f2543Smrg    exit(0);
795706f2543Smrg}
796706f2543Smrg
797706f2543Smrgstatic void dmxConfigQuitCanCallback(Widget w, XtPointer closure,
798706f2543Smrg                                     XtPointer callData)
799706f2543Smrg{
800706f2543Smrg    XtPopdown(quitpopup);
801706f2543Smrg}
802706f2543Smrg
803706f2543Smrgstatic void dmxConfigEDOkCallback(Widget w, XtPointer closure,
804706f2543Smrg                                  XtPointer callData)
805706f2543Smrg{
806706f2543Smrg    char *value;
807706f2543Smrg    char *endpt;
808706f2543Smrg
809706f2543Smrg    dmxConfigNewDisplay = NULL;
810706f2543Smrg    dmxConfigGetValueString((char **)&dmxConfigCurrentDisplay->name,
811706f2543Smrg                            eddialog0);
812706f2543Smrg    value                           = XawDialogGetValueString(eddialog1);
813706f2543Smrg    if (*value == '-' || *value == '+') {
814706f2543Smrg        dmxConfigCurrentDisplay->scrnWidth  = 0;
815706f2543Smrg        dmxConfigCurrentDisplay->scrnHeight = 0;
816706f2543Smrg        endpt                               = value;
817706f2543Smrg    } else {
818706f2543Smrg        dmxConfigCurrentDisplay->scrnWidth  = strtol(value, &endpt, 10);
819706f2543Smrg        dmxConfigCurrentDisplay->scrnHeight = strtol(endpt+1, &endpt, 10);
820706f2543Smrg    }
821706f2543Smrg    if (*endpt) {
822706f2543Smrg        dmxConfigCurrentDisplay->scrnXSign  = (*endpt == '-') ? -1 : 1;
823706f2543Smrg        dmxConfigCurrentDisplay->scrnX      = strtol(endpt+1, &endpt, 10);
824706f2543Smrg        dmxConfigCurrentDisplay->scrnYSign  = (*endpt == '-') ? -1 : 1;
825706f2543Smrg        dmxConfigCurrentDisplay->scrnY      = strtol(endpt+1, NULL, 10);
826706f2543Smrg    }
827706f2543Smrg    if (dmxConfigCurrentDisplay->scrnX < 0)
828706f2543Smrg        dmxConfigCurrentDisplay->scrnX = -dmxConfigCurrentDisplay->scrnX;
829706f2543Smrg    if (dmxConfigCurrentDisplay->scrnY < 0)
830706f2543Smrg        dmxConfigCurrentDisplay->scrnY = -dmxConfigCurrentDisplay->scrnY;
831706f2543Smrg    value                                 = XawDialogGetValueString(eddialog2);
832706f2543Smrg    dmxConfigCurrentDisplay->rootXOrigin  = strtol(value+1, &endpt, 10);
833706f2543Smrg    dmxConfigCurrentDisplay->rootYOrigin  = strtol(endpt+1, NULL, 10);
834706f2543Smrg    XtPopdown(edpopup);
835706f2543Smrg    dmxConfigSetupCnamemenu();
836706f2543Smrg    dmxConfigCanvasDraw(NULL);
837706f2543Smrg    dmxConfigNotSaved = 1;
838706f2543Smrg}
839706f2543Smrg
840706f2543Smrgstatic void dmxConfigEDCanCallback(Widget w, XtPointer closure,
841706f2543Smrg                                   XtPointer callData)
842706f2543Smrg{
843706f2543Smrg    if (dmxConfigNewDisplay) dmxConfigDDCallback(w, closure, callData);
844706f2543Smrg    dmxConfigNewDisplay = NULL;
845706f2543Smrg    XtPopdown(edpopup);
846706f2543Smrg}
847706f2543Smrg
848706f2543Smrgstatic void dmxConfigOkAction(Widget w, XEvent *event,
849706f2543Smrg                              String *params, Cardinal *num_params)
850706f2543Smrg{
851706f2543Smrg    Widget p = XtParent(w);
852706f2543Smrg    Widget t;
853706f2543Smrg
854706f2543Smrg    if (p == opendialog) dmxConfigOkCallback(w, NULL, NULL);
855706f2543Smrg
856706f2543Smrg    if (p == ecdialog0) {
857706f2543Smrg        t = XtNameToWidget(ecdialog1, "value");
858706f2543Smrg        XWarpPointer(XtDisplay(t), None, XtWindow(t), 0, 0, 0, 0, 0, 10);
859706f2543Smrg    }
860706f2543Smrg    if (p == ecdialog1) dmxConfigECOkCallback(w, NULL, NULL);
861706f2543Smrg
862706f2543Smrg    if (p == eddialog0) {
863706f2543Smrg        t = XtNameToWidget(eddialog1, "value");
864706f2543Smrg        XWarpPointer(XtDisplay(t), None, XtWindow(t), 0, 0, 0, 0, 0, 10);
865706f2543Smrg    }
866706f2543Smrg    if (p == eddialog1) {
867706f2543Smrg        t = XtNameToWidget(eddialog2, "value");
868706f2543Smrg        XWarpPointer(XtDisplay(t), None, XtWindow(t), 0, 0, 0, 0, 0, 10);
869706f2543Smrg    }
870706f2543Smrg    if (p == eddialog2) dmxConfigEDOkCallback(w, NULL, NULL);
871706f2543Smrg}
872706f2543Smrg
873706f2543Smrgint main(int argc, char **argv)
874706f2543Smrg{
875706f2543Smrg    XtAppContext   appContext;
876706f2543Smrg    Widget         toplevel;
877706f2543Smrg    Widget         parent, menubox, bottombox, databox, canvasbox;
878706f2543Smrg    Widget         filebutton, helpbutton;
879706f2543Smrg    Widget         filemenu, openbutton, savebutton, quitbutton;
880706f2543Smrg    Widget         helpmenu, aboutbutton, aboutbox, abouttext, aboutok;
881706f2543Smrg    Widget         quitbox, quittext, quitok, quitcan;
882706f2543Smrg    Widget         ncbutton;
883706f2543Smrg    Widget         canbutton;
884706f2543Smrg    Widget         ecbox, ecokbutton, eccanbutton;
885706f2543Smrg    Widget         edbox, edokbutton;
886706f2543Smrg    Widget         edcanbutton;
887706f2543Smrg                                /* FIXME: add meta-i, ctrl,meta-z,v? */
888706f2543Smrg    const char     *opentrans = "<Key>Return: openOk()\n\
889706f2543Smrg                                 <Key>Linefeed: openOk()\n\
890706f2543Smrg                                 Ctrl<Key>M: openOk()\n\
891706f2543Smrg                                 Ctrl<Key>J: openOk()\n\
892706f2543Smrg                                 Ctrl<Key>O: noop()\n\
893706f2543Smrg                                 Ctrl<Key>N: noop()\n\
894706f2543Smrg                                 Ctrl<Key>P: noop()";
895706f2543Smrg    const char     *canvastrans =
896706f2543Smrg        "<Btn3Down>: placeMenu() XtMenuPopup(buttonpopup)";
897706f2543Smrg    XtActionsRec   actiontable[] = {
898706f2543Smrg        { "openOk",        dmxConfigOkAction },
899706f2543Smrg        { "placeMenu",     dmxConfigPlaceMenu },
900706f2543Smrg        { "noop",          NULL }
901706f2543Smrg    };
902706f2543Smrg
903706f2543Smrg    dmxConfigFilename = XtNewString((argc >= 2) ? argv[1] : "");
904706f2543Smrg
905706f2543Smrg    toplevel    = XtVaAppInitialize(&appContext, "XDmxconfig",
906706f2543Smrg                                    NULL, 0,
907706f2543Smrg                                    &argc, argv,
908706f2543Smrg                                    NULL,
909706f2543Smrg                                    NULL);
910706f2543Smrg
911706f2543Smrg                                /* Main boxes */
912706f2543Smrg    parent      = XtVaCreateManagedWidget("parent", formWidgetClass, toplevel,
913706f2543Smrg                                          XtNorientation, XtorientVertical,
914706f2543Smrg                                          XtNwidth, DMX_MAIN_WIDTH,
915706f2543Smrg                                          XtNheight, DMX_MAIN_HEIGHT,
916706f2543Smrg                                          NULL);
917706f2543Smrg    menubox     = XtVaCreateManagedWidget("menubox", boxWidgetClass, parent,
918706f2543Smrg                                          XtNborderWidth, 0,
919706f2543Smrg                                          XtNorientation, XtorientHorizontal,
920706f2543Smrg                                          XtNtop, XtChainTop,
921706f2543Smrg                                          NULL);
922706f2543Smrg    bottombox   = XtVaCreateManagedWidget("bottombox", formWidgetClass, parent,
923706f2543Smrg                                          XtNborderWidth, 0,
924706f2543Smrg                                          XtNfromVert, menubox,
925706f2543Smrg                                          XtNorientation, XtorientHorizontal,
926706f2543Smrg                                          NULL);
927706f2543Smrg    databox     = XtVaCreateManagedWidget("databox", formWidgetClass,
928706f2543Smrg                                          bottombox,
929706f2543Smrg                                          XtNborderWidth, 0,
930706f2543Smrg                                          XtNhorizDistance, 0,
931706f2543Smrg                                          XtNwidth, DMX_DATA_WIDTH,
932706f2543Smrg                                          XtNheight, DMX_DATA_HEIGHT,
933706f2543Smrg                                          XtNleft, XtChainLeft,
934706f2543Smrg                                          XtNorientation, XtorientVertical,
935706f2543Smrg                                          NULL);
936706f2543Smrg
937706f2543Smrg                                /* Data */
938706f2543Smrg    cnamebox    = XtVaCreateManagedWidget("cnamebox", menuButtonWidgetClass,
939706f2543Smrg                                          databox,
940706f2543Smrg                                          XtNtop, XtChainTop,
941706f2543Smrg                                          XtNjustify, XtJustifyLeft,
942706f2543Smrg                                          XtNwidth, DMX_DATA_WIDTH,
943706f2543Smrg                                          XtNlabel, "",
944706f2543Smrg                                          XtNmenuName, "cnamemenu",
945706f2543Smrg                                          NULL);
946706f2543Smrg    cdimbox     = XtVaCreateManagedWidget("cdimbox", labelWidgetClass,
947706f2543Smrg                                          databox,
948706f2543Smrg                                          XtNfromVert, cnamebox,
949706f2543Smrg                                          XtNjustify, XtJustifyLeft,
950706f2543Smrg                                          XtNwidth, DMX_DATA_WIDTH,
951706f2543Smrg                                          XtNlabel, "",
952706f2543Smrg                                          NULL);
953706f2543Smrg    namebox     = XtVaCreateManagedWidget("namebox", labelWidgetClass, databox,
954706f2543Smrg                                          XtNfromVert, cdimbox,
955706f2543Smrg                                          XtNjustify, XtJustifyLeft,
956706f2543Smrg                                          XtNwidth, DMX_DATA_WIDTH,
957706f2543Smrg                                          XtNlabel, "",
958706f2543Smrg                                          NULL);
959706f2543Smrg    dimbox      = XtVaCreateManagedWidget("dimbox", labelWidgetClass,
960706f2543Smrg                                          databox,
961706f2543Smrg                                          XtNfromVert, namebox,
962706f2543Smrg                                          XtNjustify, XtJustifyLeft,
963706f2543Smrg                                          XtNwidth, DMX_DATA_WIDTH,
964706f2543Smrg                                          XtNlabel, "",
965706f2543Smrg                                          NULL);
966706f2543Smrg    rtbox       = XtVaCreateManagedWidget("rtbox", labelWidgetClass,
967706f2543Smrg                                          databox,
968706f2543Smrg                                          XtNfromVert, dimbox,
969706f2543Smrg                                          XtNjustify, XtJustifyLeft,
970706f2543Smrg                                          XtNwidth, DMX_DATA_WIDTH,
971706f2543Smrg                                          XtNlabel, "",
972706f2543Smrg                                          NULL);
973706f2543Smrg    origbox     = XtVaCreateManagedWidget("origbox", labelWidgetClass,
974706f2543Smrg                                          databox,
975706f2543Smrg                                          XtNfromVert, rtbox,
976706f2543Smrg                                          XtNjustify, XtJustifyLeft,
977706f2543Smrg                                          XtNwidth, DMX_DATA_WIDTH,
978706f2543Smrg                                          XtNlabel, "",
979706f2543Smrg                                          NULL);
980706f2543Smrg
981706f2543Smrg                                /* Canvas */
982706f2543Smrg    canvasbox   = XtVaCreateManagedWidget("canvasbox", boxWidgetClass,
983706f2543Smrg                                          bottombox,
984706f2543Smrg                                          XtNborderWidth, 0,
985706f2543Smrg                                          XtNwidth, DMX_CANVAS_WIDTH,
986706f2543Smrg                                          XtNheight, DMX_CANVAS_HEIGHT,
987706f2543Smrg                                          XtNfromHoriz, databox,
988706f2543Smrg                                          NULL);
989706f2543Smrg
990706f2543Smrg    canvas      = XtVaCreateManagedWidget("canvas", canvasWidgetClass,
991706f2543Smrg                                          canvasbox,
992706f2543Smrg                                          XtNwidth, DMX_CANVAS_WIDTH,
993706f2543Smrg                                          XtNheight, DMX_CANVAS_HEIGHT,
994706f2543Smrg                                          NULL);
995706f2543Smrg
996706f2543Smrg
997706f2543Smrg                                /* Main menu buttons */
998706f2543Smrg    filebutton  = XtVaCreateManagedWidget("File", menuButtonWidgetClass,
999706f2543Smrg                                          menubox,
1000706f2543Smrg                                          XtNmenuName, "filemenu",
1001706f2543Smrg                                          NULL);
1002706f2543Smrg    helpbutton  = XtVaCreateManagedWidget("Help", menuButtonWidgetClass,
1003706f2543Smrg                                          menubox,
1004706f2543Smrg                                          XtNmenuName, "helpmenu",
1005706f2543Smrg                                          NULL);
1006706f2543Smrg
1007706f2543Smrg
1008706f2543Smrg                                /* File submenu buttons */
1009706f2543Smrg    filemenu     = XtVaCreatePopupShell("filemenu", simpleMenuWidgetClass,
1010706f2543Smrg                                        filebutton, NULL);
1011706f2543Smrg    openbutton   = XtVaCreateManagedWidget("Open File", smeBSBObjectClass,
1012706f2543Smrg                                           filemenu, NULL);
1013706f2543Smrg    savebutton   = XtVaCreateManagedWidget("Save File", smeBSBObjectClass,
1014706f2543Smrg                                           filemenu,
1015706f2543Smrg                                           NULL);
1016706f2543Smrg    ncbutton     = XtVaCreateManagedWidget("New Global", smeBSBObjectClass,
1017706f2543Smrg                                           filemenu, NULL);
1018706f2543Smrg    ecbutton     = XtVaCreateManagedWidget("Edit Global", smeBSBObjectClass,
1019706f2543Smrg                                           filemenu,
1020706f2543Smrg                                           NULL);
1021706f2543Smrg    dcbutton     = XtVaCreateManagedWidget("Delete Global", smeBSBObjectClass,
1022706f2543Smrg                                           filemenu,
1023706f2543Smrg                                           NULL);
1024706f2543Smrg    ndbutton0    = XtVaCreateManagedWidget("New Display", smeBSBObjectClass,
1025706f2543Smrg                                           filemenu,
1026706f2543Smrg                                           NULL);
1027706f2543Smrg    quitbutton   = XtVaCreateManagedWidget("Quit", smeBSBObjectClass,
1028706f2543Smrg                                           filemenu, NULL);
1029706f2543Smrg
1030706f2543Smrg                                /* Help submenu button */
1031706f2543Smrg    helpmenu     = XtVaCreatePopupShell("helpmenu", simpleMenuWidgetClass,
1032706f2543Smrg                                        helpbutton, NULL);
1033706f2543Smrg    aboutbutton  = XtVaCreateManagedWidget("About", smeBSBObjectClass,
1034706f2543Smrg                                           helpmenu, NULL);
1035706f2543Smrg
1036706f2543Smrg                                /* Open popup */
1037706f2543Smrg    openpopup    = XtVaCreatePopupShell("openpopup", transientShellWidgetClass,
1038706f2543Smrg                                        toplevel, NULL);
1039706f2543Smrg    opendialog   = XtVaCreateManagedWidget("opendialog", dialogWidgetClass,
1040706f2543Smrg                                           openpopup,
1041706f2543Smrg                                           XtNlabel, "Filename: ",
1042706f2543Smrg                                           XtNvalue, dmxConfigFilename,
1043706f2543Smrg                                           NULL);
1044706f2543Smrg    okbutton     = XtVaCreateManagedWidget("Open", commandWidgetClass,
1045706f2543Smrg                                           opendialog, NULL);
1046706f2543Smrg    canbutton    = XtVaCreateManagedWidget("Cancel", commandWidgetClass,
1047706f2543Smrg                                           opendialog, NULL);
1048706f2543Smrg
1049706f2543Smrg                                /* EC popup */
1050706f2543Smrg    ecpopup      = XtVaCreatePopupShell("ecpopup", transientShellWidgetClass,
1051706f2543Smrg                                        toplevel, NULL);
1052706f2543Smrg    ecbox        = XtVaCreateManagedWidget("ecbox", boxWidgetClass,
1053706f2543Smrg                                           ecpopup, NULL);
1054706f2543Smrg    ecdialog0    = XtVaCreateManagedWidget("ecdialog0", dialogWidgetClass,
1055706f2543Smrg                                           ecbox,
1056706f2543Smrg                                           XtNlabel, "Name:              ",
1057706f2543Smrg                                           XtNvalue, "",
1058706f2543Smrg                                           NULL);
1059706f2543Smrg    ecdialog1    = XtVaCreateManagedWidget("ecdialog1", dialogWidgetClass,
1060706f2543Smrg                                           ecbox,
1061706f2543Smrg                                           XtNlabel, "Dimension:         ",
1062706f2543Smrg                                           XtNvalue, "",
1063706f2543Smrg                                           NULL);
1064706f2543Smrg    ecokbutton   = XtVaCreateManagedWidget("OK", commandWidgetClass,
1065706f2543Smrg                                           ecbox, NULL);
1066706f2543Smrg    eccanbutton  = XtVaCreateManagedWidget("Cancel", commandWidgetClass,
1067706f2543Smrg                                           ecbox, NULL);
1068706f2543Smrg
1069706f2543Smrg                                /* ED popup */
1070706f2543Smrg    edpopup      = XtVaCreatePopupShell("edpopup", transientShellWidgetClass,
1071706f2543Smrg                                        toplevel, NULL);
1072706f2543Smrg    edbox        = XtVaCreateManagedWidget("edbox", boxWidgetClass,
1073706f2543Smrg                                           edpopup, NULL);
1074706f2543Smrg    eddialog0    = XtVaCreateManagedWidget("eddialog0", dialogWidgetClass,
1075706f2543Smrg                                           edbox,
1076706f2543Smrg                                           XtNlabel, "Display Name:      ",
1077706f2543Smrg                                           XtNvalue, "",
1078706f2543Smrg                                           NULL);
1079706f2543Smrg    eddialog1    = XtVaCreateManagedWidget("eddialog1", dialogWidgetClass,
1080706f2543Smrg                                           edbox,
1081706f2543Smrg                                           XtNlabel, "Geometry:          ",
1082706f2543Smrg                                           XtNvalue, "",
1083706f2543Smrg                                           NULL);
1084706f2543Smrg    eddialog2    = XtVaCreateManagedWidget("eddialog2", dialogWidgetClass,
1085706f2543Smrg                                           edbox,
1086706f2543Smrg                                           XtNlabel, "Offset:            ",
1087706f2543Smrg                                           XtNvalue, "",
1088706f2543Smrg                                           NULL);
1089706f2543Smrg    edokbutton   = XtVaCreateManagedWidget("OK", commandWidgetClass,
1090706f2543Smrg                                           edbox, NULL);
1091706f2543Smrg    edcanbutton  = XtVaCreateManagedWidget("Cancel", commandWidgetClass,
1092706f2543Smrg                                           edbox, NULL);
1093706f2543Smrg
1094706f2543Smrg                                /* About popup */
1095706f2543Smrg    aboutpopup   = XtVaCreatePopupShell("aboutpopup",transientShellWidgetClass,
1096706f2543Smrg                                        toplevel, NULL);
1097706f2543Smrg    aboutbox     = XtVaCreateManagedWidget("aboutbox", boxWidgetClass,
1098706f2543Smrg                                           aboutpopup, NULL);
1099706f2543Smrg    abouttext    = XtVaCreateManagedWidget("abouttext", labelWidgetClass,
1100706f2543Smrg                                           aboutbox,
1101706f2543Smrg                                           XtNlabel, DMX_INFO,
1102706f2543Smrg                                           NULL);
1103706f2543Smrg    aboutok      = XtVaCreateManagedWidget("OK", commandWidgetClass,
1104706f2543Smrg                                           aboutbox, NULL);
1105706f2543Smrg
1106706f2543Smrg                                /* Quit popup */
1107706f2543Smrg    quitpopup    = XtVaCreatePopupShell("quitpopup",transientShellWidgetClass,
1108706f2543Smrg                                        toplevel, NULL);
1109706f2543Smrg    quitbox      = XtVaCreateManagedWidget("quitbox", boxWidgetClass,
1110706f2543Smrg                                           quitpopup, NULL);
1111706f2543Smrg    quittext     = XtVaCreateManagedWidget("quittext", labelWidgetClass,
1112706f2543Smrg                                           quitbox,
1113706f2543Smrg                                           XtNlabel,
1114706f2543Smrg                                           "Changes to the configuration\n"
1115706f2543Smrg                                           "been made that have not yet\n"
1116706f2543Smrg                                           "been saved.  Do you want to\n"
1117706f2543Smrg                                           "quit without saving?",
1118706f2543Smrg                                           NULL);
1119706f2543Smrg    quitok       = XtVaCreateManagedWidget("Quit WITHOUT Saving",
1120706f2543Smrg                                           commandWidgetClass,
1121706f2543Smrg                                           quitbox, NULL);
1122706f2543Smrg    quitcan      = XtVaCreateManagedWidget("Continue Editing",
1123706f2543Smrg                                           commandWidgetClass,
1124706f2543Smrg                                           quitbox, NULL);
1125706f2543Smrg
1126706f2543Smrg                                /* Button popup */
1127706f2543Smrg    buttonpopup  = XtVaCreatePopupShell("buttonpopup", simpleMenuWidgetClass,
1128706f2543Smrg                                        toplevel, NULL);
1129706f2543Smrg    ndbutton1    = XtVaCreateManagedWidget("New Display", smeBSBObjectClass,
1130706f2543Smrg                                           buttonpopup,
1131706f2543Smrg                                           NULL);
1132706f2543Smrg    edbutton     = XtVaCreateManagedWidget("Edit Display", smeBSBObjectClass,
1133706f2543Smrg                                           buttonpopup,
1134706f2543Smrg                                           NULL);
1135706f2543Smrg    ddbutton     = XtVaCreateManagedWidget("Delete Display", smeBSBObjectClass,
1136706f2543Smrg                                           buttonpopup,
1137706f2543Smrg                                           NULL);
1138706f2543Smrg
1139706f2543Smrg                                /* Callbacks */
1140706f2543Smrg    XtAddCallback(openbutton,  XtNcallback, dmxConfigOpenCallback,       NULL);
1141706f2543Smrg    XtAddCallback(savebutton,  XtNcallback, dmxConfigSaveCallback,       NULL);
1142706f2543Smrg    XtAddCallback(okbutton,    XtNcallback, dmxConfigOkCallback,         NULL);
1143706f2543Smrg    XtAddCallback(canbutton,   XtNcallback, dmxConfigCanCallback,        NULL);
1144706f2543Smrg
1145706f2543Smrg    XtAppAddActions(appContext, actiontable, XtNumber(actiontable));
1146706f2543Smrg    XtOverrideTranslations(canvas, XtParseTranslationTable(canvastrans));
1147706f2543Smrg    XtOverrideTranslations(XtNameToWidget(opendialog, "value"),
1148706f2543Smrg                                          XtParseTranslationTable(opentrans));
1149706f2543Smrg    XtOverrideTranslations(XtNameToWidget(ecdialog0, "value"),
1150706f2543Smrg                                          XtParseTranslationTable(opentrans));
1151706f2543Smrg    XtOverrideTranslations(XtNameToWidget(ecdialog1, "value"),
1152706f2543Smrg                                          XtParseTranslationTable(opentrans));
1153706f2543Smrg    XtOverrideTranslations(XtNameToWidget(eddialog0, "value"),
1154706f2543Smrg                                          XtParseTranslationTable(opentrans));
1155706f2543Smrg    XtOverrideTranslations(XtNameToWidget(eddialog1, "value"),
1156706f2543Smrg                                          XtParseTranslationTable(opentrans));
1157706f2543Smrg    XtOverrideTranslations(XtNameToWidget(eddialog2, "value"),
1158706f2543Smrg                                          XtParseTranslationTable(opentrans));
1159706f2543Smrg
1160706f2543Smrg    XtAddCallback(ncbutton,    XtNcallback, dmxConfigNCCallback,         NULL);
1161706f2543Smrg    XtAddCallback(ecbutton,    XtNcallback, dmxConfigECCallback,         NULL);
1162706f2543Smrg    XtAddCallback(ecokbutton,  XtNcallback, dmxConfigECOkCallback,       NULL);
1163706f2543Smrg    XtAddCallback(eccanbutton, XtNcallback, dmxConfigECCanCallback,      NULL);
1164706f2543Smrg    XtAddCallback(dcbutton,    XtNcallback, dmxConfigDCCallback,         NULL);
1165706f2543Smrg
1166706f2543Smrg    XtAddCallback(ndbutton0,   XtNcallback, dmxConfigNDCallback,         NULL);
1167706f2543Smrg    XtAddCallback(ndbutton1,   XtNcallback, dmxConfigNDCallback,         NULL);
1168706f2543Smrg    XtAddCallback(edbutton,    XtNcallback, dmxConfigEDCallback,         NULL);
1169706f2543Smrg    XtAddCallback(ddbutton,    XtNcallback, dmxConfigDDCallback,         NULL);
1170706f2543Smrg    XtAddCallback(edokbutton,  XtNcallback, dmxConfigEDOkCallback,       NULL);
1171706f2543Smrg    XtAddCallback(edcanbutton, XtNcallback, dmxConfigEDCanCallback,      NULL);
1172706f2543Smrg
1173706f2543Smrg    XtAddCallback(aboutbutton, XtNcallback, dmxConfigAboutCallback,      NULL);
1174706f2543Smrg    XtAddCallback(aboutok,     XtNcallback, dmxConfigAboutOkCallback,    NULL);
1175706f2543Smrg    XtAddCallback(quitok,      XtNcallback, dmxConfigQuitOkCallback,     NULL);
1176706f2543Smrg    XtAddCallback(quitcan,     XtNcallback, dmxConfigQuitCanCallback,    NULL);
1177706f2543Smrg
1178706f2543Smrg    XtAddCallback(quitbutton,  XtNcallback, dmxConfigQuitCallback,       NULL);
1179706f2543Smrg
1180706f2543Smrg    XtAddCallback(canvas, XtNcallback,             dmxConfigCanvasInput, NULL);
1181706f2543Smrg    XtAddCallback(canvas, XtNcanvasExposeCallback, dmxConfigCanvasExpose,NULL);
1182706f2543Smrg    XtAddCallback(canvas, XtNcanvasResizeCallback, dmxConfigCanvasResize,NULL);
1183706f2543Smrg
1184706f2543Smrg    if (dmxConfigFilename) dmxConfigReadFile();
1185706f2543Smrg
1186706f2543Smrg    XtRealizeWidget(toplevel);
1187706f2543Smrg    dmxConfigCopystrings();
1188706f2543Smrg    dmxConfigSetupCnamemenu();
1189706f2543Smrg    XtAppMainLoop(appContext);
1190706f2543Smrg    return 0;
1191706f2543Smrg}
1192