2 * Copyright 2002 Red Hat Inc., Durham, North Carolina.
6 * Permission is hereby granted, free of charge, to any person obtaining
7 * a copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation on the rights to use, copy, modify, merge,
10 * publish, distribute, sublicense, and/or sell copies of the Software,
11 * and to permit persons to whom the Software is furnished to do so,
12 * subject to the following conditions:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial
16 * portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS
22 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
23 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 * Rickard E. (Rik) Faith <faith@redhat.com>
37 #include <X11/Intrinsic.h>
38 #include <X11/StringDefs.h>
39 #include <X11/Xaw/Form.h>
40 #include <X11/Xaw/Box.h>
41 /* #include <X11/Xaw/Paned.h> */
42 #include <X11/Xaw/Command.h>
43 #include <X11/Xaw/SimpleMenu.h>
44 #include <X11/Xaw/SmeBSB.h>
45 #include <X11/Xaw/MenuButton.h>
46 #include <X11/Xaw/Viewport.h>
47 #include <X11/Xaw/Dialog.h>
48 #include <X11/keysym.h>
55 extern int yyparse(void);
58 #define DMX_INFO "xdmxconfig v0.9\nCopyright 2002 Red Hat Inc.\n"
60 #define DMX_MAIN_WIDTH 800
61 #define DMX_MAIN_HEIGHT 600
62 #define DMX_DATA_WIDTH 200
63 #define DMX_DATA_HEIGHT 200
64 #define DMX_CANVAS_WIDTH 400
65 #define DMX_CANVAS_HEIGHT 500
67 DMXConfigEntryPtr dmxConfigEntry
;
68 static DMXConfigVirtualPtr dmxConfigCurrent
, dmxConfigNewVirtual
;
69 static DMXConfigDisplayPtr dmxConfigCurrentDisplay
, dmxConfigNewDisplay
;
70 static int dmxConfigGrabbed
, dmxConfigGrabbedFine
;
71 static int dmxConfigGrabbedX
, dmxConfigGrabbedY
;
72 static char *dmxConfigFilename
;
73 static GC dmxConfigGC
, dmxConfigGCRev
, dmxConfigGCHL
;
74 static int dmxConfigGCInit
= 0;
75 static Dimension dmxConfigWidgetWidth
, dmxConfigWidgetHeight
;
76 static Dimension dmxConfigWallWidth
, dmxConfigWallHeight
;
77 static double dmxConfigScaleX
, dmxConfigScaleY
;
78 static int dmxConfigNotSaved
;
86 static Widget cnamebox
, cdimbox
;
87 static Widget openpopup
, opendialog
;
88 static Widget namebox
, dimbox
, rtbox
, origbox
;
89 static Widget okbutton
, buttonpopup
;
90 static Widget ecbutton
, dcbutton
;
91 static Widget ndbutton0
, ndbutton1
, edbutton
, ddbutton
;
92 static Widget ecpopup
, ecdialog0
, ecdialog1
;
93 static Widget edpopup
, eddialog0
, eddialog1
, eddialog2
;
94 static Widget aboutpopup
, quitpopup
;
97 dmxConfigCanvasGCs(void)
99 Display
*dpy
= XtDisplay(canvas
);
100 Window win
= XtWindow(canvas
);
104 XColor fg
, bg
, hl
, tmp
;
106 if (dmxConfigGCInit
++)
109 XtVaGetValues(canvas
, XtNcolormap
, &colormap
, NULL
);
110 XAllocNamedColor(XtDisplay(canvas
), colormap
, "black", &bg
, &tmp
);
111 XAllocNamedColor(XtDisplay(canvas
), colormap
, "white", &fg
, &tmp
);
112 XAllocNamedColor(XtDisplay(canvas
), colormap
, "red", &hl
, &tmp
);
114 mask
= (GCFunction
| GCPlaneMask
| GCClipMask
| GCForeground
|
115 GCBackground
| GCLineWidth
| GCLineStyle
| GCCapStyle
|
118 /* FIXME: copy this from widget */
119 gcvals
.function
= GXcopy
;
120 gcvals
.plane_mask
= AllPlanes
;
121 gcvals
.clip_mask
= None
;
122 gcvals
.foreground
= fg
.pixel
;
123 gcvals
.background
= bg
.pixel
;
124 gcvals
.line_width
= 0;
125 gcvals
.line_style
= LineSolid
;
126 gcvals
.cap_style
= CapNotLast
;
127 gcvals
.fill_style
= FillSolid
;
129 dmxConfigGC
= XCreateGC(dpy
, win
, mask
, &gcvals
);
130 gcvals
.foreground
= hl
.pixel
;
131 dmxConfigGCHL
= XCreateGC(dpy
, win
, mask
, &gcvals
);
132 gcvals
.foreground
= bg
.pixel
;
133 gcvals
.background
= fg
.pixel
;
134 dmxConfigGCRev
= XCreateGC(dpy
, win
, mask
, &gcvals
);
138 dmxConfigGetDims(int *maxWidth
, int *maxHeight
)
143 *maxWidth
= dmxConfigWallWidth
= 0;
144 *maxHeight
= dmxConfigWallHeight
= 0;
145 if (!dmxConfigCurrent
)
148 dmxConfigWallWidth
= dmxConfigCurrent
->width
;
149 dmxConfigWallHeight
= dmxConfigCurrent
->height
;
150 if (!dmxConfigWallWidth
|| !dmxConfigWallHeight
) {
151 for (pt
= dmxConfigCurrent
->subentry
; pt
; pt
= pt
->next
) {
152 if (pt
->type
== dmxConfigDisplay
) {
153 int x
= pt
->display
->scrnWidth
+ pt
->display
->rootXOrigin
;
154 int y
= pt
->display
->scrnHeight
+ pt
->display
->rootYOrigin
;
156 if (x
> dmxConfigWallWidth
)
157 dmxConfigWallWidth
= x
;
158 if (y
> dmxConfigWallHeight
)
159 dmxConfigWallHeight
= y
;
163 /* Compute maximums */
164 *maxWidth
= *maxHeight
= 0;
165 for (e
= dmxConfigEntry
; e
; e
= e
->next
) {
166 if (e
->type
!= dmxConfigVirtual
)
168 for (pt
= e
->virtual->subentry
; pt
; pt
= pt
->next
) {
169 if (pt
->type
== dmxConfigDisplay
) {
170 int x
= pt
->display
->scrnWidth
+ pt
->display
->rootXOrigin
;
171 int y
= pt
->display
->scrnHeight
+ pt
->display
->rootYOrigin
;
180 if (dmxConfigWallWidth
> *maxWidth
)
181 *maxWidth
= dmxConfigWallWidth
;
182 if (dmxConfigWallHeight
> *maxHeight
)
183 *maxHeight
= dmxConfigWallHeight
;
189 return (int) ((x
* dmxConfigScaleX
) + .5);
195 return (int) ((y
* dmxConfigScaleY
) + .5);
201 return (int) ((x
/ dmxConfigScaleX
) + .5);
207 return (int) ((y
/ dmxConfigScaleY
) + .5);
211 dmxConfigDataUpdate(void)
213 /* FIXME: could result in buffer overflows */
222 if (!dmxConfigCurrent
) {
223 XtVaSetValues(cnamebox
, XtNlabel
, "", XtNsensitive
, False
, NULL
);
224 XtVaSetValues(cdimbox
, XtNlabel
, "", XtNsensitive
, False
, NULL
);
225 XtVaSetValues(ecbutton
, XtNsensitive
, False
, NULL
);
226 XtVaSetValues(dcbutton
, XtNsensitive
, False
, NULL
);
227 XtVaSetValues(ndbutton0
, XtNsensitive
, False
, NULL
);
228 XtVaSetValues(ndbutton1
, XtNsensitive
, False
, NULL
);
231 name
= dmxConfigCurrent
->name
;
232 snprintf(cnambuf
, sizeof(cnambuf
), "%s", name
? name
: "");
233 snprintf(cdimbuf
, sizeof(cdimbuf
), "%dx%d",
234 dmxConfigWallWidth
, dmxConfigWallHeight
);
235 XtVaSetValues(cnamebox
, XtNlabel
, cnambuf
, XtNsensitive
, True
, NULL
);
236 XtVaSetValues(cdimbox
, XtNlabel
, cdimbuf
, XtNsensitive
, True
, NULL
);
237 XtVaSetValues(ecbutton
, XtNsensitive
, True
, NULL
);
238 XtVaSetValues(dcbutton
, XtNsensitive
, True
, NULL
);
239 XtVaSetValues(ndbutton0
, XtNsensitive
, True
, NULL
);
240 XtVaSetValues(ndbutton1
, XtNsensitive
, True
, NULL
);
243 if (!dmxConfigCurrentDisplay
) {
244 XtVaSetValues(namebox
, XtNlabel
, "", XtNsensitive
, False
, NULL
);
245 XtVaSetValues(dimbox
, XtNlabel
, "", XtNsensitive
, False
, NULL
);
246 XtVaSetValues(rtbox
, XtNlabel
, "", XtNsensitive
, False
, NULL
);
247 XtVaSetValues(origbox
, XtNlabel
, "", XtNsensitive
, False
, NULL
);
248 XtVaSetValues(edbutton
, XtNsensitive
, False
, NULL
);
249 XtVaSetValues(ddbutton
, XtNsensitive
, False
, NULL
);
252 name
= dmxConfigCurrentDisplay
->name
;
253 snprintf(nambuf
, sizeof(nambuf
), "%s", name
? name
: "");
254 snprintf(dimbuf
, sizeof(dimbuf
), "%dx%d%c%d%c%d",
255 dmxConfigCurrentDisplay
->scrnWidth
,
256 dmxConfigCurrentDisplay
->scrnHeight
,
257 dmxConfigCurrentDisplay
->scrnXSign
< 0 ? '-' : '+',
258 dmxConfigCurrentDisplay
->scrnX
,
259 dmxConfigCurrentDisplay
->scrnYSign
< 0 ? '-' : '+',
260 dmxConfigCurrentDisplay
->scrnY
);
261 snprintf(rtbuf
, sizeof(dimbuf
), "%dx%d%c%d%c%d",
262 dmxConfigCurrentDisplay
->rootWidth
,
263 dmxConfigCurrentDisplay
->rootHeight
,
264 dmxConfigCurrentDisplay
->rootXSign
< 0 ? '-' : '+',
265 dmxConfigCurrentDisplay
->rootX
,
266 dmxConfigCurrentDisplay
->rootYSign
< 0 ? '-' : '+',
267 dmxConfigCurrentDisplay
->rootY
);
268 snprintf(offbuf
, sizeof(offbuf
), "@%dx%d",
269 dmxConfigCurrentDisplay
->rootXOrigin
,
270 dmxConfigCurrentDisplay
->rootYOrigin
);
271 XtVaSetValues(namebox
, XtNlabel
, nambuf
, XtNsensitive
, True
, NULL
);
272 XtVaSetValues(dimbox
, XtNlabel
, dimbuf
, XtNsensitive
, True
, NULL
);
273 XtVaSetValues(rtbox
, XtNlabel
, rtbuf
, XtNsensitive
, True
, NULL
);
274 XtVaSetValues(origbox
, XtNlabel
, offbuf
, XtNsensitive
, True
, NULL
);
275 XtVaSetValues(edbutton
, XtNsensitive
, True
, NULL
);
276 XtVaSetValues(ddbutton
, XtNsensitive
, True
, NULL
);
281 dmxConfigCanvasUpdate(void)
284 Display
*dpy
= XtDisplay(canvas
);
285 Window win
= XtWindow(canvas
);
286 GContext gcontext
= XGContextFromGC(dmxConfigGC
);
290 XFillRectangle(dpy
, win
, dmxConfigGCRev
,
291 0, 0, dmxConfigWidgetWidth
, dmxConfigWidgetHeight
);
292 dmxConfigDataUpdate();
293 if (!dmxConfigCurrent
)
296 w
= scalex(dmxConfigWallWidth
);
297 h
= scaley(dmxConfigWallHeight
);
298 if (w
> dmxConfigWidgetWidth
- 1)
299 w
= dmxConfigWidgetWidth
- 1;
300 if (h
> dmxConfigWidgetHeight
- 1)
301 h
= dmxConfigWidgetHeight
- 1;
302 XDrawRectangle(dpy
, win
, dmxConfigGC
, 0, 0, w
, h
);
303 fs
= XQueryFont(dpy
, gcontext
);
304 for (pt
= dmxConfigCurrent
->subentry
; pt
; pt
= pt
->next
) {
306 int xo
= 3, yo
= fs
->ascent
+ fs
->descent
+ 2;
309 if (pt
->type
!= dmxConfigDisplay
)
311 gc
= (pt
->display
== dmxConfigCurrentDisplay
312 ? dmxConfigGCHL
: dmxConfigGC
);
313 x
= scalex(pt
->display
->rootXOrigin
);
314 y
= scaley(pt
->display
->rootYOrigin
);
315 w
= scalex(pt
->display
->scrnWidth
);
316 h
= scaley(pt
->display
->scrnHeight
);
317 len
= pt
->display
->name
? strlen(pt
->display
->name
) : 0;
318 if (x
> dmxConfigWidgetWidth
- 1)
319 x
= dmxConfigWidgetWidth
- 1;
320 if (y
> dmxConfigWidgetHeight
- 1)
321 y
= dmxConfigWidgetHeight
- 1;
322 XDrawRectangle(dpy
, win
, gc
, x
, y
, w
, h
);
324 while (len
&& XTextWidth(fs
, pt
->display
->name
, len
) >= w
- 2 * xo
)
327 XDrawString(dpy
, win
, gc
, x
+ xo
, y
+ yo
, pt
->display
->name
,
332 XFreeFontInfo(NULL
, fs
, 0);
336 dmxConfigCanvasDraw(Region region
)
338 Display
*dpy
= XtDisplay(canvas
);
339 int maxWidth
, maxHeight
;
341 dmxConfigCanvasGCs();
343 XSetRegion(dpy
, dmxConfigGC
, region
);
344 XSetRegion(dpy
, dmxConfigGCRev
, region
);
345 XSetRegion(dpy
, dmxConfigGCHL
, region
);
347 XtVaGetValues(canvas
,
348 XtNwidth
, &dmxConfigWidgetWidth
,
349 XtNheight
, &dmxConfigWidgetHeight
, NULL
);
350 dmxConfigGetDims(&maxWidth
, &maxHeight
);
351 dmxConfigScaleX
= (double) dmxConfigWidgetWidth
/ maxWidth
;
352 dmxConfigScaleY
= (double) dmxConfigWidgetHeight
/ maxHeight
;
353 if (dmxConfigScaleX
> dmxConfigScaleY
)
354 dmxConfigScaleX
= dmxConfigScaleY
;
355 if (dmxConfigScaleY
> dmxConfigScaleX
)
356 dmxConfigScaleY
= dmxConfigScaleX
;
357 dmxConfigCanvasUpdate();
359 XSetClipMask(dpy
, dmxConfigGC
, None
);
360 XSetClipMask(dpy
, dmxConfigGCRev
, None
);
361 XSetClipMask(dpy
, dmxConfigGCHL
, None
);
366 dmxConfigSelectCallback(Widget w
, XtPointer closure
, XtPointer callData
)
368 dmxConfigCurrent
= closure
;
369 dmxConfigVirtualPrint(stdout
, dmxConfigCurrent
);
370 dmxConfigCanvasDraw(NULL
);
374 dmxConfigCopystrings(void)
376 DMXConfigEntryPtr pt
;
379 if (!dmxConfigCurrent
)
382 /* FIXME: this is all a per-config file
384 for (pt
= dmxConfigEntry
; pt
; pt
= pt
->next
) {
385 if (pt
->type
== dmxConfigVirtual
) {
386 pt
->virtual->name
= XtNewString(pt
->virtual->name
387 ? pt
->virtual->name
: "");
389 for (sub
= pt
->virtual->subentry
; sub
; sub
= sub
->next
) {
390 if (sub
->type
!= dmxConfigDisplay
)
392 sub
->display
->name
= XtNewString(sub
->display
->name
393 ? sub
->display
->name
: "");
400 dmxConfigGetValueString(char **d
, Widget w
)
402 const char *tmp
= XawDialogGetValueString(w
);
406 *d
= XtNewString(tmp
);
410 dmxConfigSetupCnamemenu(void)
412 static Widget cnamemenu
= NULL
;
414 DMXConfigEntryPtr pt
;
417 XtDestroyWidget(cnamemenu
);
420 if (!dmxConfigCurrent
)
422 cnamemenu
= XtVaCreatePopupShell("cnamemenu", simpleMenuWidgetClass
,
425 for (pt
= dmxConfigEntry
; pt
; pt
= pt
->next
) {
426 if (pt
->type
== dmxConfigVirtual
) {
427 w
= XtVaCreateManagedWidget(pt
->virtual->name
430 smeBSBObjectClass
, cnamemenu
, NULL
);
431 XtAddCallback(w
, XtNcallback
, dmxConfigSelectCallback
, pt
->virtual);
437 dmxConfigReadFile(void)
440 DMXConfigEntryPtr pt
;
442 if (!(str
= fopen(dmxConfigFilename
, "r"))) {
443 dmxLog(dmxWarning
, "Unable to read configuration file %s\n",
451 dmxLog(dmxInfo
, "Read configuration file %s\n", dmxConfigFilename
);
453 for (pt
= dmxConfigEntry
; pt
; pt
= pt
->next
) {
454 if (pt
->type
== dmxConfigVirtual
) {
455 dmxConfigCurrent
= pt
->virtual;
460 if (XtIsRealized(canvas
)) {
461 dmxConfigCopystrings();
462 dmxConfigSetupCnamemenu();
463 dmxConfigCanvasDraw(NULL
);
465 dmxConfigVirtualPrint(stdout
, dmxConfigCurrent
);
469 dmxConfigWriteFile(void)
473 if (!(str
= fopen(dmxConfigFilename
, "w"))) {
474 dmxLog(dmxWarning
, "Unable to write configuration file %s\n",
478 dmxConfigPrint(str
, dmxConfigEntry
);
482 static DMXConfigDisplayPtr
483 dmxConfigFindDisplay(int x
, int y
)
487 if (!dmxConfigCurrent
)
489 for (pt
= dmxConfigCurrent
->subentry
; pt
; pt
= pt
->next
) {
490 DMXConfigDisplayPtr d
= pt
->display
;
492 if (pt
->type
!= dmxConfigDisplay
)
494 if (x
>= scalex(d
->rootXOrigin
)
495 && x
<= scalex(d
->rootXOrigin
+ d
->scrnWidth
)
496 && y
>= scaley(d
->rootYOrigin
)
497 && y
<= scaley(d
->rootYOrigin
+ d
->scrnHeight
))
504 dmxConfigSetPopupPosition(Widget popup
)
512 XtRealizeWidget(popup
);
513 if (!XQueryPointer(XtDisplay(popup
), XtWindow(popup
), &t1
, &t2
,
514 &root_x
, &root_y
, &temp_x
, &temp_y
, &temp
))
519 XtVaSetValues(popup
, XtNx
, x
, XtNy
, y
, NULL
);
523 dmxConfigPlaceMenu(Widget w
, XEvent
* event
,
524 String
* params
, Cardinal
* num_params
)
526 dmxConfigSetPopupPosition(buttonpopup
);
530 dmxConfigMove(int deltaX
, int deltaY
)
532 dmxConfigCurrentDisplay
->rootXOrigin
+= deltaX
;
533 dmxConfigCurrentDisplay
->rootYOrigin
+= deltaY
;
534 if (dmxConfigCurrentDisplay
->rootXOrigin
< 0)
535 dmxConfigCurrentDisplay
->rootXOrigin
= 0;
536 if (dmxConfigCurrentDisplay
->rootYOrigin
< 0)
537 dmxConfigCurrentDisplay
->rootYOrigin
= 0;
538 if (dmxConfigWallWidth
&& dmxConfigWallHeight
) {
539 if (dmxConfigCurrentDisplay
->rootXOrigin
>= dmxConfigWallWidth
)
540 dmxConfigCurrentDisplay
->rootXOrigin
= dmxConfigWallWidth
- 1;
541 if (dmxConfigCurrentDisplay
->rootYOrigin
>= dmxConfigWallHeight
)
542 dmxConfigCurrentDisplay
->rootYOrigin
= dmxConfigWallHeight
- 1;
544 dmxConfigCanvasUpdate();
545 dmxConfigNotSaved
= 1;
549 dmxConfigCanvasInput(Widget w
, XtPointer closure
, XtPointer callData
)
551 XEvent
*e
= (XEvent
*) callData
;
552 DMXConfigDisplayPtr display
= NULL
;
556 if (e
->xbutton
.button
== Button1
) {
557 dmxConfigGrabbed
= 1;
558 dmxConfigGrabbedFine
= 0;
559 dmxConfigGrabbedX
= e
->xbutton
.x
;
560 dmxConfigGrabbedY
= e
->xbutton
.y
;
562 if (e
->xbutton
.button
== Button2
) {
563 dmxConfigGrabbed
= 1;
564 dmxConfigGrabbedFine
= 1;
565 dmxConfigGrabbedX
= e
->xbutton
.x
;
566 dmxConfigGrabbedY
= e
->xbutton
.y
;
570 if (e
->xbutton
.button
== Button1
)
571 dmxConfigGrabbed
= 0;
572 if (e
->xbutton
.button
== Button2
)
573 dmxConfigGrabbed
= 0;
576 if (dmxConfigGrabbed
&& dmxConfigCurrentDisplay
) {
577 int deltaX
= e
->xmotion
.x
- dmxConfigGrabbedX
;
578 int deltaY
= e
->xmotion
.y
- dmxConfigGrabbedY
;
580 dmxConfigMove(dmxConfigGrabbedFine
? deltaX
: unscalex(deltaX
),
581 dmxConfigGrabbedFine
? deltaY
: unscaley(deltaY
));
582 dmxConfigGrabbedX
= e
->xmotion
.x
;
583 dmxConfigGrabbedY
= e
->xmotion
.y
;
586 display
= dmxConfigFindDisplay(e
->xmotion
.x
, e
->xmotion
.y
);
587 if (display
!= dmxConfigCurrentDisplay
) {
588 dmxConfigCurrentDisplay
= display
;
589 dmxConfigCanvasUpdate();
594 switch (XLookupKeysym(&e
->xkey
, 0)) {
599 dmxConfigMove(-1, 0);
605 dmxConfigMove(0, -1);
613 dmxConfigCanvasResize(Widget w
, XtPointer closure
, XtPointer callData
)
615 dmxConfigCanvasDraw(NULL
);
619 dmxConfigCanvasExpose(Widget w
, XtPointer closure
, XtPointer callData
)
621 CanvasExposeDataPtr data
= (CanvasExposeDataPtr
) callData
;
623 dmxConfigCanvasDraw(data
->region
);
627 dmxConfigOpenCallback(Widget w
, XtPointer closure
, XtPointer callData
)
629 dmxConfigState
= dmxConfigStateOpen
;
630 XtVaSetValues(okbutton
, XtNlabel
, "Open", NULL
);
631 dmxConfigSetPopupPosition(openpopup
);
632 XtPopup(openpopup
, XtGrabExclusive
);
636 dmxConfigSaveCallback(Widget w
, XtPointer closure
, XtPointer callData
)
638 dmxConfigState
= dmxConfigStateSave
;
639 XtVaSetValues(okbutton
, XtNlabel
, "Save", NULL
);
640 dmxConfigSetPopupPosition(openpopup
);
641 XtPopup(openpopup
, XtGrabExclusive
);
645 dmxConfigOkCallback(Widget w
, XtPointer closure
, XtPointer callData
)
647 dmxConfigGetValueString(&dmxConfigFilename
, opendialog
);
648 XtPopdown(openpopup
);
649 if (dmxConfigState
== dmxConfigStateOpen
)
652 dmxConfigWriteFile();
653 dmxConfigNotSaved
= 0;
657 dmxConfigCanCallback(Widget w
, XtPointer closure
, XtPointer callData
)
659 XtPopdown(openpopup
);
663 dmxConfigECCallback(Widget w
, XtPointer closure
, XtPointer callData
)
665 char buf
[256]; /* RATS: Only used in snprintf */
667 if (!dmxConfigCurrent
)
669 dmxConfigSetPopupPosition(ecpopup
);
670 XtVaSetValues(ecdialog0
, XtNvalue
,
671 dmxConfigCurrent
->name
? dmxConfigCurrent
->name
: "", NULL
);
672 snprintf(buf
, sizeof(buf
), "%dx%d",
673 dmxConfigCurrent
->width
, dmxConfigCurrent
->height
);
674 XtVaSetValues(ecdialog1
, XtNvalue
, buf
, NULL
);
675 XtPopup(ecpopup
, XtGrabExclusive
);
679 dmxConfigNCCallback(Widget w
, XtPointer closure
, XtPointer callData
)
681 int width
= 1280 * 2, height
= 1024 * 2;
683 if (dmxConfigCurrent
) {
684 width
= dmxConfigCurrent
->width
;
685 height
= dmxConfigCurrent
->height
;
688 dmxConfigCurrent
= dmxConfigCreateVirtual(NULL
, NULL
, NULL
,
690 dmxConfigNewVirtual
= dmxConfigCurrent
;
691 dmxConfigCurrent
->width
= width
;
692 dmxConfigCurrent
->height
= height
;
693 dmxConfigEntry
= dmxConfigAddEntry(dmxConfigEntry
, dmxConfigVirtual
, NULL
,
695 dmxConfigECCallback(w
, closure
, callData
);
699 dmxConfigDCCallback(Widget w
, XtPointer closure
, XtPointer callData
)
701 DMXConfigEntryPtr pt
;
706 && dmxConfigEntry
->type
== dmxConfigVirtual
707 && dmxConfigEntry
->virtual == dmxConfigCurrent
) {
708 dmxConfigEntry
= dmxConfigEntry
->next
;
711 for (pt
= dmxConfigEntry
; pt
&& pt
->next
; pt
= pt
->next
)
712 if (pt
->next
->type
== dmxConfigVirtual
713 && pt
->next
->virtual == dmxConfigCurrent
) {
714 pt
->next
= pt
->next
->next
;
718 dmxConfigFreeVirtual(dmxConfigCurrent
);
719 dmxConfigCurrent
= NULL
;
720 dmxConfigCurrentDisplay
= NULL
;
722 /* Make the first entry current */
723 for (pt
= dmxConfigEntry
; pt
; pt
= pt
->next
) {
724 if (pt
->type
== dmxConfigVirtual
) {
725 dmxConfigCurrent
= pt
->virtual;
730 dmxConfigSetupCnamemenu();
731 dmxConfigCanvasDraw(NULL
);
735 dmxConfigECOkCallback(Widget w
, XtPointer closure
, XtPointer callData
)
740 dmxConfigGetValueString((char **) &dmxConfigCurrent
->name
, ecdialog0
);
741 value
= XawDialogGetValueString(ecdialog1
);
742 dmxConfigCurrent
->width
= strtol(value
, &endpt
, 10);
743 dmxConfigCurrent
->height
= strtol(endpt
+ 1, NULL
, 10);
745 dmxConfigCurrentDisplay
= NULL
;
746 dmxConfigNewVirtual
= NULL
;
747 dmxConfigSetupCnamemenu();
748 dmxConfigCanvasDraw(NULL
);
749 dmxConfigNotSaved
= 1;
753 dmxConfigECCanCallback(Widget w
, XtPointer closure
, XtPointer callData
)
755 if (dmxConfigNewVirtual
)
756 dmxConfigDCCallback(w
, closure
, callData
);
757 dmxConfigNewVirtual
= NULL
;
762 dmxConfigEDCallback(Widget w
, XtPointer closure
, XtPointer callData
)
764 char buf
[256]; /* RATS: Only used in snprintf */
766 if (!dmxConfigCurrent
|| !dmxConfigCurrentDisplay
)
768 dmxConfigSetPopupPosition(edpopup
);
769 XtVaSetValues(eddialog0
, XtNvalue
,
770 dmxConfigCurrentDisplay
->name
771 ? dmxConfigCurrentDisplay
->name
: "", NULL
);
772 snprintf(buf
, sizeof(buf
), "%dx%d%c%d%c%d",
773 dmxConfigCurrentDisplay
->scrnWidth
,
774 dmxConfigCurrentDisplay
->scrnHeight
,
775 dmxConfigCurrentDisplay
->scrnXSign
< 0 ? '-' : '+',
776 dmxConfigCurrentDisplay
->scrnY
,
777 dmxConfigCurrentDisplay
->scrnYSign
< 0 ? '-' : '+',
778 dmxConfigCurrentDisplay
->scrnY
);
779 XtVaSetValues(eddialog1
, XtNvalue
, buf
, NULL
);
780 snprintf(buf
, sizeof(buf
), "@%dx%d",
781 dmxConfigCurrentDisplay
->rootXOrigin
,
782 dmxConfigCurrentDisplay
->rootYOrigin
);
783 XtVaSetValues(eddialog2
, XtNvalue
, buf
, NULL
);
784 XtPopup(edpopup
, XtGrabExclusive
);
788 dmxConfigNDCallback(Widget w
, XtPointer closure
, XtPointer callData
)
790 int width
= 1280, height
= 1024;
792 if (!dmxConfigCurrent
)
794 if (dmxConfigCurrentDisplay
) {
795 width
= dmxConfigCurrentDisplay
->scrnWidth
;
796 height
= dmxConfigCurrentDisplay
->scrnHeight
;
798 dmxConfigCurrentDisplay
= dmxConfigCreateDisplay(NULL
, NULL
, NULL
,
800 dmxConfigNewDisplay
= dmxConfigCurrentDisplay
;
801 dmxConfigCurrentDisplay
->scrnWidth
= width
;
802 dmxConfigCurrentDisplay
->scrnHeight
= height
;
804 dmxConfigCurrent
->subentry
805 = dmxConfigAddSub(dmxConfigCurrent
->subentry
,
806 dmxConfigSubDisplay(dmxConfigCurrentDisplay
));
807 dmxConfigEDCallback(w
, closure
, callData
);
811 dmxConfigDDCallback(Widget w
, XtPointer closure
, XtPointer callData
)
815 if (!dmxConfigCurrent
|| !dmxConfigCurrentDisplay
)
818 if (dmxConfigCurrent
->subentry
819 && dmxConfigCurrent
->subentry
->type
== dmxConfigDisplay
820 && dmxConfigCurrent
->subentry
->display
== dmxConfigCurrentDisplay
) {
821 dmxConfigCurrent
->subentry
= dmxConfigCurrent
->subentry
->next
;
824 for (pt
= dmxConfigCurrent
->subentry
; pt
&& pt
->next
; pt
= pt
->next
)
825 if (pt
->next
->type
== dmxConfigDisplay
826 && pt
->next
->display
== dmxConfigCurrentDisplay
) {
827 pt
->next
= pt
->next
->next
;
831 dmxConfigFreeDisplay(dmxConfigCurrentDisplay
);
832 dmxConfigCurrentDisplay
= NULL
;
833 dmxConfigSetupCnamemenu();
834 dmxConfigCanvasDraw(NULL
);
838 dmxConfigAboutCallback(Widget w
, XtPointer closure
, XtPointer callData
)
840 dmxConfigSetPopupPosition(aboutpopup
);
841 XtPopup(aboutpopup
, XtGrabExclusive
);
845 dmxConfigAboutOkCallback(Widget w
, XtPointer closure
, XtPointer CallData
)
847 XtPopdown(aboutpopup
);
851 dmxConfigQuitCallback(Widget w
, XtPointer closure
, XtPointer callData
)
853 if (dmxConfigNotSaved
) {
854 dmxConfigSetPopupPosition(quitpopup
);
855 XtPopup(quitpopup
, XtGrabExclusive
);
862 dmxConfigQuitOkCallback(Widget w
, XtPointer closure
, XtPointer callData
)
864 XtPopdown(quitpopup
);
869 dmxConfigQuitCanCallback(Widget w
, XtPointer closure
, XtPointer callData
)
871 XtPopdown(quitpopup
);
875 dmxConfigEDOkCallback(Widget w
, XtPointer closure
, XtPointer callData
)
880 dmxConfigNewDisplay
= NULL
;
881 dmxConfigGetValueString((char **) &dmxConfigCurrentDisplay
->name
,
883 value
= XawDialogGetValueString(eddialog1
);
884 if (*value
== '-' || *value
== '+') {
885 dmxConfigCurrentDisplay
->scrnWidth
= 0;
886 dmxConfigCurrentDisplay
->scrnHeight
= 0;
890 dmxConfigCurrentDisplay
->scrnWidth
= strtol(value
, &endpt
, 10);
891 dmxConfigCurrentDisplay
->scrnHeight
= strtol(endpt
+ 1, &endpt
, 10);
894 dmxConfigCurrentDisplay
->scrnXSign
= (*endpt
== '-') ? -1 : 1;
895 dmxConfigCurrentDisplay
->scrnX
= strtol(endpt
+ 1, &endpt
, 10);
896 dmxConfigCurrentDisplay
->scrnYSign
= (*endpt
== '-') ? -1 : 1;
897 dmxConfigCurrentDisplay
->scrnY
= strtol(endpt
+ 1, NULL
, 10);
899 if (dmxConfigCurrentDisplay
->scrnX
< 0)
900 dmxConfigCurrentDisplay
->scrnX
= -dmxConfigCurrentDisplay
->scrnX
;
901 if (dmxConfigCurrentDisplay
->scrnY
< 0)
902 dmxConfigCurrentDisplay
->scrnY
= -dmxConfigCurrentDisplay
->scrnY
;
903 value
= XawDialogGetValueString(eddialog2
);
904 dmxConfigCurrentDisplay
->rootXOrigin
= strtol(value
+ 1, &endpt
, 10);
905 dmxConfigCurrentDisplay
->rootYOrigin
= strtol(endpt
+ 1, NULL
, 10);
907 dmxConfigSetupCnamemenu();
908 dmxConfigCanvasDraw(NULL
);
909 dmxConfigNotSaved
= 1;
913 dmxConfigEDCanCallback(Widget w
, XtPointer closure
, XtPointer callData
)
915 if (dmxConfigNewDisplay
)
916 dmxConfigDDCallback(w
, closure
, callData
);
917 dmxConfigNewDisplay
= NULL
;
922 dmxConfigOkAction(Widget w
, XEvent
* event
,
923 String
* params
, Cardinal
* num_params
)
925 Widget p
= XtParent(w
);
929 dmxConfigOkCallback(w
, NULL
, NULL
);
931 if (p
== ecdialog0
) {
932 t
= XtNameToWidget(ecdialog1
, "value");
933 XWarpPointer(XtDisplay(t
), None
, XtWindow(t
), 0, 0, 0, 0, 0, 10);
936 dmxConfigECOkCallback(w
, NULL
, NULL
);
938 if (p
== eddialog0
) {
939 t
= XtNameToWidget(eddialog1
, "value");
940 XWarpPointer(XtDisplay(t
), None
, XtWindow(t
), 0, 0, 0, 0, 0, 10);
942 if (p
== eddialog1
) {
943 t
= XtNameToWidget(eddialog2
, "value");
944 XWarpPointer(XtDisplay(t
), None
, XtWindow(t
), 0, 0, 0, 0, 0, 10);
947 dmxConfigEDOkCallback(w
, NULL
, NULL
);
951 main(int argc
, char **argv
)
953 XtAppContext appContext
;
955 Widget parent
, menubox
, bottombox
, databox
, canvasbox
;
956 Widget filebutton
, helpbutton
;
957 Widget filemenu
, openbutton
, savebutton
, quitbutton
;
958 Widget helpmenu
, aboutbutton
, aboutbox
, aboutok
;
959 Widget quitbox
, quitok
, quitcan
;
962 Widget ecbox
, ecokbutton
, eccanbutton
;
963 Widget edbox
, edokbutton
;
966 /* FIXME: add meta-i, ctrl,meta-z,v? */
967 const char *opentrans
= "<Key>Return: openOk()\n\
968 <Key>Linefeed: openOk()\n\
969 Ctrl<Key>M: openOk()\n\
970 Ctrl<Key>J: openOk()\n\
971 Ctrl<Key>O: noop()\n\
972 Ctrl<Key>N: noop()\n\
974 const char *canvastrans
=
975 "<Btn3Down>: placeMenu() XtMenuPopup(buttonpopup)";
976 XtActionsRec actiontable
[] = {
977 {"openOk", dmxConfigOkAction
},
978 {"placeMenu", dmxConfigPlaceMenu
},
982 dmxConfigFilename
= XtNewString((argc
>= 2) ? argv
[1] : "");
984 toplevel
= XtVaAppInitialize(&appContext
, "XDmxconfig",
985 NULL
, 0, &argc
, argv
, NULL
, NULL
);
988 parent
= XtVaCreateManagedWidget("parent", formWidgetClass
, toplevel
,
989 XtNorientation
, XtorientVertical
,
990 XtNwidth
, DMX_MAIN_WIDTH
,
991 XtNheight
, DMX_MAIN_HEIGHT
, NULL
);
992 menubox
= XtVaCreateManagedWidget("menubox", boxWidgetClass
, parent
,
994 XtNorientation
, XtorientHorizontal
,
995 XtNtop
, XtChainTop
, NULL
);
996 bottombox
= XtVaCreateManagedWidget("bottombox", formWidgetClass
, parent
,
998 XtNfromVert
, menubox
,
999 XtNorientation
, XtorientHorizontal
,
1001 databox
= XtVaCreateManagedWidget("databox", formWidgetClass
,
1004 XtNhorizDistance
, 0,
1005 XtNwidth
, DMX_DATA_WIDTH
,
1006 XtNheight
, DMX_DATA_HEIGHT
,
1007 XtNleft
, XtChainLeft
,
1008 XtNorientation
, XtorientVertical
, NULL
);
1011 cnamebox
= XtVaCreateManagedWidget("cnamebox", menuButtonWidgetClass
,
1014 XtNjustify
, XtJustifyLeft
,
1015 XtNwidth
, DMX_DATA_WIDTH
,
1017 XtNmenuName
, "cnamemenu", NULL
);
1018 cdimbox
= XtVaCreateManagedWidget("cdimbox", labelWidgetClass
,
1020 XtNfromVert
, cnamebox
,
1021 XtNjustify
, XtJustifyLeft
,
1022 XtNwidth
, DMX_DATA_WIDTH
,
1023 XtNlabel
, "", NULL
);
1024 namebox
= XtVaCreateManagedWidget("namebox", labelWidgetClass
, databox
,
1025 XtNfromVert
, cdimbox
,
1026 XtNjustify
, XtJustifyLeft
,
1027 XtNwidth
, DMX_DATA_WIDTH
,
1028 XtNlabel
, "", NULL
);
1029 dimbox
= XtVaCreateManagedWidget("dimbox", labelWidgetClass
,
1031 XtNfromVert
, namebox
,
1032 XtNjustify
, XtJustifyLeft
,
1033 XtNwidth
, DMX_DATA_WIDTH
,
1034 XtNlabel
, "", NULL
);
1035 rtbox
= XtVaCreateManagedWidget("rtbox", labelWidgetClass
,
1037 XtNfromVert
, dimbox
,
1038 XtNjustify
, XtJustifyLeft
,
1039 XtNwidth
, DMX_DATA_WIDTH
,
1040 XtNlabel
, "", NULL
);
1041 origbox
= XtVaCreateManagedWidget("origbox", labelWidgetClass
,
1044 XtNjustify
, XtJustifyLeft
,
1045 XtNwidth
, DMX_DATA_WIDTH
,
1046 XtNlabel
, "", NULL
);
1049 canvasbox
= XtVaCreateManagedWidget("canvasbox", boxWidgetClass
,
1052 XtNwidth
, DMX_CANVAS_WIDTH
,
1053 XtNheight
, DMX_CANVAS_HEIGHT
,
1054 XtNfromHoriz
, databox
, NULL
);
1056 canvas
= XtVaCreateManagedWidget("canvas", canvasWidgetClass
,
1058 XtNwidth
, DMX_CANVAS_WIDTH
,
1059 XtNheight
, DMX_CANVAS_HEIGHT
, NULL
);
1061 /* Main menu buttons */
1062 filebutton
= XtVaCreateManagedWidget("File", menuButtonWidgetClass
,
1064 XtNmenuName
, "filemenu", NULL
);
1065 helpbutton
= XtVaCreateManagedWidget("Help", menuButtonWidgetClass
,
1067 XtNmenuName
, "helpmenu", NULL
);
1069 /* File submenu buttons */
1070 filemenu
= XtVaCreatePopupShell("filemenu", simpleMenuWidgetClass
,
1072 openbutton
= XtVaCreateManagedWidget("Open File", smeBSBObjectClass
,
1074 savebutton
= XtVaCreateManagedWidget("Save File", smeBSBObjectClass
,
1076 ncbutton
= XtVaCreateManagedWidget("New Global", smeBSBObjectClass
,
1078 ecbutton
= XtVaCreateManagedWidget("Edit Global", smeBSBObjectClass
,
1080 dcbutton
= XtVaCreateManagedWidget("Delete Global", smeBSBObjectClass
,
1082 ndbutton0
= XtVaCreateManagedWidget("New Display", smeBSBObjectClass
,
1084 quitbutton
= XtVaCreateManagedWidget("Quit", smeBSBObjectClass
,
1087 /* Help submenu button */
1088 helpmenu
= XtVaCreatePopupShell("helpmenu", simpleMenuWidgetClass
,
1090 aboutbutton
= XtVaCreateManagedWidget("About", smeBSBObjectClass
,
1094 openpopup
= XtVaCreatePopupShell("openpopup", transientShellWidgetClass
,
1096 opendialog
= XtVaCreateManagedWidget("opendialog", dialogWidgetClass
,
1098 XtNlabel
, "Filename: ",
1099 XtNvalue
, dmxConfigFilename
, NULL
);
1100 okbutton
= XtVaCreateManagedWidget("Open", commandWidgetClass
,
1102 canbutton
= XtVaCreateManagedWidget("Cancel", commandWidgetClass
,
1106 ecpopup
= XtVaCreatePopupShell("ecpopup", transientShellWidgetClass
,
1108 ecbox
= XtVaCreateManagedWidget("ecbox", boxWidgetClass
, ecpopup
, NULL
);
1109 ecdialog0
= XtVaCreateManagedWidget("ecdialog0", dialogWidgetClass
,
1112 XtNvalue
, "", NULL
);
1113 ecdialog1
= XtVaCreateManagedWidget("ecdialog1", dialogWidgetClass
,
1115 XtNlabel
, "Dimension: ",
1116 XtNvalue
, "", NULL
);
1117 ecokbutton
= XtVaCreateManagedWidget("OK", commandWidgetClass
, ecbox
, NULL
);
1118 eccanbutton
= XtVaCreateManagedWidget("Cancel", commandWidgetClass
,
1122 edpopup
= XtVaCreatePopupShell("edpopup", transientShellWidgetClass
,
1124 edbox
= XtVaCreateManagedWidget("edbox", boxWidgetClass
, edpopup
, NULL
);
1125 eddialog0
= XtVaCreateManagedWidget("eddialog0", dialogWidgetClass
,
1127 XtNlabel
, "Display Name: ",
1128 XtNvalue
, "", NULL
);
1129 eddialog1
= XtVaCreateManagedWidget("eddialog1", dialogWidgetClass
,
1131 XtNlabel
, "Geometry: ",
1132 XtNvalue
, "", NULL
);
1133 eddialog2
= XtVaCreateManagedWidget("eddialog2", dialogWidgetClass
,
1135 XtNlabel
, "Offset: ",
1136 XtNvalue
, "", NULL
);
1137 edokbutton
= XtVaCreateManagedWidget("OK", commandWidgetClass
, edbox
, NULL
);
1138 edcanbutton
= XtVaCreateManagedWidget("Cancel", commandWidgetClass
,
1142 aboutpopup
= XtVaCreatePopupShell("aboutpopup", transientShellWidgetClass
,
1144 aboutbox
= XtVaCreateManagedWidget("aboutbox", boxWidgetClass
,
1146 XtVaCreateManagedWidget("abouttext", labelWidgetClass
,
1147 aboutbox
, XtNlabel
, DMX_INFO
, NULL
);
1148 aboutok
= XtVaCreateManagedWidget("OK", commandWidgetClass
, aboutbox
, NULL
);
1151 quitpopup
= XtVaCreatePopupShell("quitpopup", transientShellWidgetClass
,
1153 quitbox
= XtVaCreateManagedWidget("quitbox", boxWidgetClass
,
1155 XtVaCreateManagedWidget("quittext", labelWidgetClass
,
1158 "Changes to the configuration\n"
1159 "been made that have not yet\n"
1160 "been saved. Do you want to\n"
1161 "quit without saving?", NULL
);
1162 quitok
= XtVaCreateManagedWidget("Quit WITHOUT Saving",
1163 commandWidgetClass
, quitbox
, NULL
);
1164 quitcan
= XtVaCreateManagedWidget("Continue Editing",
1165 commandWidgetClass
, quitbox
, NULL
);
1168 buttonpopup
= XtVaCreatePopupShell("buttonpopup", simpleMenuWidgetClass
,
1170 ndbutton1
= XtVaCreateManagedWidget("New Display", smeBSBObjectClass
,
1172 edbutton
= XtVaCreateManagedWidget("Edit Display", smeBSBObjectClass
,
1174 ddbutton
= XtVaCreateManagedWidget("Delete Display", smeBSBObjectClass
,
1178 XtAddCallback(openbutton
, XtNcallback
, dmxConfigOpenCallback
, NULL
);
1179 XtAddCallback(savebutton
, XtNcallback
, dmxConfigSaveCallback
, NULL
);
1180 XtAddCallback(okbutton
, XtNcallback
, dmxConfigOkCallback
, NULL
);
1181 XtAddCallback(canbutton
, XtNcallback
, dmxConfigCanCallback
, NULL
);
1183 XtAppAddActions(appContext
, actiontable
, XtNumber(actiontable
));
1184 XtOverrideTranslations(canvas
, XtParseTranslationTable(canvastrans
));
1185 XtOverrideTranslations(XtNameToWidget(opendialog
, "value"),
1186 XtParseTranslationTable(opentrans
));
1187 XtOverrideTranslations(XtNameToWidget(ecdialog0
, "value"),
1188 XtParseTranslationTable(opentrans
));
1189 XtOverrideTranslations(XtNameToWidget(ecdialog1
, "value"),
1190 XtParseTranslationTable(opentrans
));
1191 XtOverrideTranslations(XtNameToWidget(eddialog0
, "value"),
1192 XtParseTranslationTable(opentrans
));
1193 XtOverrideTranslations(XtNameToWidget(eddialog1
, "value"),
1194 XtParseTranslationTable(opentrans
));
1195 XtOverrideTranslations(XtNameToWidget(eddialog2
, "value"),
1196 XtParseTranslationTable(opentrans
));
1198 XtAddCallback(ncbutton
, XtNcallback
, dmxConfigNCCallback
, NULL
);
1199 XtAddCallback(ecbutton
, XtNcallback
, dmxConfigECCallback
, NULL
);
1200 XtAddCallback(ecokbutton
, XtNcallback
, dmxConfigECOkCallback
, NULL
);
1201 XtAddCallback(eccanbutton
, XtNcallback
, dmxConfigECCanCallback
, NULL
);
1202 XtAddCallback(dcbutton
, XtNcallback
, dmxConfigDCCallback
, NULL
);
1204 XtAddCallback(ndbutton0
, XtNcallback
, dmxConfigNDCallback
, NULL
);
1205 XtAddCallback(ndbutton1
, XtNcallback
, dmxConfigNDCallback
, NULL
);
1206 XtAddCallback(edbutton
, XtNcallback
, dmxConfigEDCallback
, NULL
);
1207 XtAddCallback(ddbutton
, XtNcallback
, dmxConfigDDCallback
, NULL
);
1208 XtAddCallback(edokbutton
, XtNcallback
, dmxConfigEDOkCallback
, NULL
);
1209 XtAddCallback(edcanbutton
, XtNcallback
, dmxConfigEDCanCallback
, NULL
);
1211 XtAddCallback(aboutbutton
, XtNcallback
, dmxConfigAboutCallback
, NULL
);
1212 XtAddCallback(aboutok
, XtNcallback
, dmxConfigAboutOkCallback
, NULL
);
1213 XtAddCallback(quitok
, XtNcallback
, dmxConfigQuitOkCallback
, NULL
);
1214 XtAddCallback(quitcan
, XtNcallback
, dmxConfigQuitCanCallback
, NULL
);
1216 XtAddCallback(quitbutton
, XtNcallback
, dmxConfigQuitCallback
, NULL
);
1218 XtAddCallback(canvas
, XtNcallback
, dmxConfigCanvasInput
, NULL
);
1219 XtAddCallback(canvas
, XtNcanvasExposeCallback
, dmxConfigCanvasExpose
, NULL
);
1220 XtAddCallback(canvas
, XtNcanvasResizeCallback
, dmxConfigCanvasResize
, NULL
);
1222 if (dmxConfigFilename
)
1223 dmxConfigReadFile();
1225 XtRealizeWidget(toplevel
);
1226 dmxConfigCopystrings();
1227 dmxConfigSetupCnamemenu();
1228 XtAppMainLoop(appContext
);