Imported Upstream version 1.15.1
[deb_xorg-server.git] / hw / dmx / config / xdmxconfig.c
CommitLineData
a09e091a
JB
1/*
2 * Copyright 2002 Red Hat Inc., Durham, North Carolina.
3 *
4 * All Rights Reserved.
5 *
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:
13 *
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.
17 *
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
25 * SOFTWARE.
26 */
27
28/*
29 * Authors:
30 * Rickard E. (Rik) Faith <faith@redhat.com>
31 *
32 */
33
34
35#include <stdio.h>
36#include <stdlib.h>
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>
49#include "Canvas.h"
50
51#include "dmxparse.h"
52#include "dmxprint.h"
53#include "dmxlog.h"
54
55extern int yyparse(void);
56extern FILE *yyin;
57
58#define DMX_INFO "xdmxconfig v0.9\nCopyright 2002 Red Hat Inc.\n"
59
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
66
67DMXConfigEntryPtr dmxConfigEntry;
68static DMXConfigVirtualPtr dmxConfigCurrent, dmxConfigNewVirtual;
69static DMXConfigDisplayPtr dmxConfigCurrentDisplay, dmxConfigNewDisplay;
70static int dmxConfigGrabbed, dmxConfigGrabbedFine;
71static int dmxConfigGrabbedX, dmxConfigGrabbedY;
72static char *dmxConfigFilename;
73static GC dmxConfigGC, dmxConfigGCRev, dmxConfigGCHL;
74static int dmxConfigGCInit = 0;
75static Dimension dmxConfigWidgetWidth, dmxConfigWidgetHeight;
76static Dimension dmxConfigWallWidth, dmxConfigWallHeight;
77static double dmxConfigScaleX, dmxConfigScaleY;
78static int dmxConfigNotSaved;
79static enum {
80 dmxConfigStateOpen,
81 dmxConfigStateSave
82} dmxConfigState;
83
84/* Global widgets */
85static Widget canvas;
86static Widget cnamebox, cdimbox;
87static Widget openpopup, opendialog;
88static Widget namebox, dimbox, rtbox, origbox;
89static Widget okbutton, buttonpopup;
90static Widget ecbutton, dcbutton;
91static Widget ndbutton0, ndbutton1, edbutton, ddbutton;
92static Widget ecpopup, ecdialog0, ecdialog1;
93static Widget edpopup, eddialog0, eddialog1, eddialog2;
94static Widget aboutpopup, quitpopup;
95
96static void
97dmxConfigCanvasGCs(void)
98{
99 Display *dpy = XtDisplay(canvas);
100 Window win = XtWindow(canvas);
101 XGCValues gcvals;
102 unsigned long mask;
103 Colormap colormap;
104 XColor fg, bg, hl, tmp;
105
106 if (dmxConfigGCInit++)
107 return;
108
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);
113
114 mask = (GCFunction | GCPlaneMask | GCClipMask | GCForeground |
115 GCBackground | GCLineWidth | GCLineStyle | GCCapStyle |
116 GCFillStyle);
117
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;
128
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);
135}
136
137static void
138dmxConfigGetDims(int *maxWidth, int *maxHeight)
139{
140 DMXConfigSubPtr pt;
141 DMXConfigEntryPtr e;
142
143 *maxWidth = dmxConfigWallWidth = 0;
144 *maxHeight = dmxConfigWallHeight = 0;
145 if (!dmxConfigCurrent)
146 return;
147
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;
155
156 if (x > dmxConfigWallWidth)
157 dmxConfigWallWidth = x;
158 if (y > dmxConfigWallHeight)
159 dmxConfigWallHeight = y;
160 }
161 }
162 }
163 /* Compute maximums */
164 *maxWidth = *maxHeight = 0;
165 for (e = dmxConfigEntry; e; e = e->next) {
166 if (e->type != dmxConfigVirtual)
167 continue;
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;
172
173 if (x > *maxWidth)
174 *maxWidth = x;
175 if (y > *maxHeight)
176 *maxHeight = y;
177 }
178 }
179 }
180 if (dmxConfigWallWidth > *maxWidth)
181 *maxWidth = dmxConfigWallWidth;
182 if (dmxConfigWallHeight > *maxHeight)
183 *maxHeight = dmxConfigWallHeight;
184}
185
186static int
187scalex(int x)
188{
189 return (int) ((x * dmxConfigScaleX) + .5);
190}
191
192static int
193scaley(int y)
194{
195 return (int) ((y * dmxConfigScaleY) + .5);
196}
197
198static int
199unscalex(int x)
200{
201 return (int) ((x / dmxConfigScaleX) + .5);
202}
203
204static int
205unscaley(int y)
206{
207 return (int) ((y / dmxConfigScaleY) + .5);
208}
209
210static void
211dmxConfigDataUpdate(void)
212{
213 /* FIXME: could result in buffer overflows */
214 char cnambuf[512];
215 char cdimbuf[128];
216 char nambuf[512];
217 char dimbuf[128];
218 char rtbuf[128];
219 char offbuf[128];
220 const char *name;
221
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);
229 }
230 else {
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);
241 }
242
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);
250 }
251 else {
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);
277 }
278}
279
280static void
281dmxConfigCanvasUpdate(void)
282{
283 DMXConfigSubPtr pt;
284 Display *dpy = XtDisplay(canvas);
285 Window win = XtWindow(canvas);
286 GContext gcontext = XGContextFromGC(dmxConfigGC);
287 XFontStruct *fs;
288 int w, h;
289
290 XFillRectangle(dpy, win, dmxConfigGCRev,
291 0, 0, dmxConfigWidgetWidth, dmxConfigWidgetHeight);
292 dmxConfigDataUpdate();
293 if (!dmxConfigCurrent)
294 return;
295
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) {
305 int x, y, len;
306 int xo = 3, yo = fs->ascent + fs->descent + 2;
307 GC gc;
308
309 if (pt->type != dmxConfigDisplay)
310 continue;
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);
323 if (fs && len) {
324 while (len && XTextWidth(fs, pt->display->name, len) >= w - 2 * xo)
325 --len;
326 if (len)
327 XDrawString(dpy, win, gc, x + xo, y + yo, pt->display->name,
328 len);
329 }
330 }
331 if (fs)
332 XFreeFontInfo(NULL, fs, 0);
333}
334
335static void
336dmxConfigCanvasDraw(Region region)
337{
338 Display *dpy = XtDisplay(canvas);
339 int maxWidth, maxHeight;
340
341 dmxConfigCanvasGCs();
342 if (region) {
343 XSetRegion(dpy, dmxConfigGC, region);
344 XSetRegion(dpy, dmxConfigGCRev, region);
345 XSetRegion(dpy, dmxConfigGCHL, region);
346 }
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();
358 if (region) {
359 XSetClipMask(dpy, dmxConfigGC, None);
360 XSetClipMask(dpy, dmxConfigGCRev, None);
361 XSetClipMask(dpy, dmxConfigGCHL, None);
362 }
363}
364
365static void
366dmxConfigSelectCallback(Widget w, XtPointer closure, XtPointer callData)
367{
368 dmxConfigCurrent = closure;
369 dmxConfigVirtualPrint(stdout, dmxConfigCurrent);
370 dmxConfigCanvasDraw(NULL);
371}
372
373static void
374dmxConfigCopystrings(void)
375{
376 DMXConfigEntryPtr pt;
377 DMXConfigSubPtr sub;
378
379 if (!dmxConfigCurrent)
380 return;
381
382 /* FIXME: this is all a per-config file
383 * memory leak */
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 : "");
388
389 for (sub = pt->virtual->subentry; sub; sub = sub->next) {
390 if (sub->type != dmxConfigDisplay)
391 continue;
392 sub->display->name = XtNewString(sub->display->name
393 ? sub->display->name : "");
394 }
395 }
396 }
397}
398
399static void
400dmxConfigGetValueString(char **d, Widget w)
401{
402 const char *tmp = XawDialogGetValueString(w);
403
404 if (*d)
405 XtFree(*d);
406 *d = XtNewString(tmp);
407}
408
409static void
410dmxConfigSetupCnamemenu(void)
411{
412 static Widget cnamemenu = NULL;
413 Widget w;
414 DMXConfigEntryPtr pt;
415
416 if (cnamemenu)
417 XtDestroyWidget(cnamemenu);
418 cnamemenu = NULL;
419
420 if (!dmxConfigCurrent)
421 return;
422 cnamemenu = XtVaCreatePopupShell("cnamemenu", simpleMenuWidgetClass,
423 cnamebox, NULL);
424
425 for (pt = dmxConfigEntry; pt; pt = pt->next) {
426 if (pt->type == dmxConfigVirtual) {
427 w = XtVaCreateManagedWidget(pt->virtual->name
428 ? pt->virtual->name
429 : "",
430 smeBSBObjectClass, cnamemenu, NULL);
431 XtAddCallback(w, XtNcallback, dmxConfigSelectCallback, pt->virtual);
432 }
433 }
434}
435
436static void
437dmxConfigReadFile(void)
438{
439 FILE *str;
440 DMXConfigEntryPtr pt;
441
442 if (!(str = fopen(dmxConfigFilename, "r"))) {
443 dmxLog(dmxWarning, "Unable to read configuration file %s\n",
444 dmxConfigFilename);
445 return;
446 }
447 yyin = str;
448 yydebug = 0;
449 yyparse();
450 fclose(str);
451 dmxLog(dmxInfo, "Read configuration file %s\n", dmxConfigFilename);
452
453 for (pt = dmxConfigEntry; pt; pt = pt->next) {
454 if (pt->type == dmxConfigVirtual) {
455 dmxConfigCurrent = pt->virtual;
456 break;
457 }
458 }
459
460 if (XtIsRealized(canvas)) {
461 dmxConfigCopystrings();
462 dmxConfigSetupCnamemenu();
463 dmxConfigCanvasDraw(NULL);
464 }
465 dmxConfigVirtualPrint(stdout, dmxConfigCurrent);
466}
467
468static void
469dmxConfigWriteFile(void)
470{
471 FILE *str;
472
473 if (!(str = fopen(dmxConfigFilename, "w"))) {
474 dmxLog(dmxWarning, "Unable to write configuration file %s\n",
475 dmxConfigFilename);
476 return;
477 }
478 dmxConfigPrint(str, dmxConfigEntry);
479 fclose(str);
480}
481
482static DMXConfigDisplayPtr
483dmxConfigFindDisplay(int x, int y)
484{
485 DMXConfigSubPtr pt;
486
487 if (!dmxConfigCurrent)
488 return NULL;
489 for (pt = dmxConfigCurrent->subentry; pt; pt = pt->next) {
490 DMXConfigDisplayPtr d = pt->display;
491
492 if (pt->type != dmxConfigDisplay)
493 continue;
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))
498 return d;
499 }
500 return NULL;
501}
502
503static void
504dmxConfigSetPopupPosition(Widget popup)
505{
506 Position x, y;
507 Window t1, t2;
508 int root_x, root_y;
509 int temp_x, temp_y;
510 unsigned int temp;
511
512 XtRealizeWidget(popup);
513 if (!XQueryPointer(XtDisplay(popup), XtWindow(popup), &t1, &t2,
514 &root_x, &root_y, &temp_x, &temp_y, &temp))
515 root_x = root_y = 0;
516
517 x = root_x - 5;
518 y = root_y - 5;
519 XtVaSetValues(popup, XtNx, x, XtNy, y, NULL);
520}
521
522static void
523dmxConfigPlaceMenu(Widget w, XEvent * event,
524 String * params, Cardinal * num_params)
525{
526 dmxConfigSetPopupPosition(buttonpopup);
527}
528
529static void
530dmxConfigMove(int deltaX, int deltaY)
531{
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;
543 }
544 dmxConfigCanvasUpdate();
545 dmxConfigNotSaved = 1;
546}
547
548static void
549dmxConfigCanvasInput(Widget w, XtPointer closure, XtPointer callData)
550{
551 XEvent *e = (XEvent *) callData;
552 DMXConfigDisplayPtr display = NULL;
553
554 switch (e->type) {
555 case ButtonPress:
556 if (e->xbutton.button == Button1) {
557 dmxConfigGrabbed = 1;
558 dmxConfigGrabbedFine = 0;
559 dmxConfigGrabbedX = e->xbutton.x;
560 dmxConfigGrabbedY = e->xbutton.y;
561 }
562 if (e->xbutton.button == Button2) {
563 dmxConfigGrabbed = 1;
564 dmxConfigGrabbedFine = 1;
565 dmxConfigGrabbedX = e->xbutton.x;
566 dmxConfigGrabbedY = e->xbutton.y;
567 }
568 break;
569 case ButtonRelease:
570 if (e->xbutton.button == Button1)
571 dmxConfigGrabbed = 0;
572 if (e->xbutton.button == Button2)
573 dmxConfigGrabbed = 0;
574 break;
575 case MotionNotify:
576 if (dmxConfigGrabbed && dmxConfigCurrentDisplay) {
577 int deltaX = e->xmotion.x - dmxConfigGrabbedX;
578 int deltaY = e->xmotion.y - dmxConfigGrabbedY;
579
580 dmxConfigMove(dmxConfigGrabbedFine ? deltaX : unscalex(deltaX),
581 dmxConfigGrabbedFine ? deltaY : unscaley(deltaY));
582 dmxConfigGrabbedX = e->xmotion.x;
583 dmxConfigGrabbedY = e->xmotion.y;
584 }
585 else {
586 display = dmxConfigFindDisplay(e->xmotion.x, e->xmotion.y);
587 if (display != dmxConfigCurrentDisplay) {
588 dmxConfigCurrentDisplay = display;
589 dmxConfigCanvasUpdate();
590 }
591 }
592 break;
593 case KeyPress:
594 switch (XLookupKeysym(&e->xkey, 0)) {
595 case XK_Right:
596 dmxConfigMove(1, 0);
597 break;
598 case XK_Left:
599 dmxConfigMove(-1, 0);
600 break;
601 case XK_Down:
602 dmxConfigMove(0, 1);
603 break;
604 case XK_Up:
605 dmxConfigMove(0, -1);
606 break;
607 }
608 break;
609 }
610}
611
612static void
613dmxConfigCanvasResize(Widget w, XtPointer closure, XtPointer callData)
614{
615 dmxConfigCanvasDraw(NULL);
616}
617
618static void
619dmxConfigCanvasExpose(Widget w, XtPointer closure, XtPointer callData)
620{
621 CanvasExposeDataPtr data = (CanvasExposeDataPtr) callData;
622
623 dmxConfigCanvasDraw(data->region);
624}
625
626static void
627dmxConfigOpenCallback(Widget w, XtPointer closure, XtPointer callData)
628{
629 dmxConfigState = dmxConfigStateOpen;
630 XtVaSetValues(okbutton, XtNlabel, "Open", NULL);
631 dmxConfigSetPopupPosition(openpopup);
632 XtPopup(openpopup, XtGrabExclusive);
633}
634
635static void
636dmxConfigSaveCallback(Widget w, XtPointer closure, XtPointer callData)
637{
638 dmxConfigState = dmxConfigStateSave;
639 XtVaSetValues(okbutton, XtNlabel, "Save", NULL);
640 dmxConfigSetPopupPosition(openpopup);
641 XtPopup(openpopup, XtGrabExclusive);
642}
643
644static void
645dmxConfigOkCallback(Widget w, XtPointer closure, XtPointer callData)
646{
647 dmxConfigGetValueString(&dmxConfigFilename, opendialog);
648 XtPopdown(openpopup);
649 if (dmxConfigState == dmxConfigStateOpen)
650 dmxConfigReadFile();
651 else
652 dmxConfigWriteFile();
653 dmxConfigNotSaved = 0;
654}
655
656static void
657dmxConfigCanCallback(Widget w, XtPointer closure, XtPointer callData)
658{
659 XtPopdown(openpopup);
660}
661
662static void
663dmxConfigECCallback(Widget w, XtPointer closure, XtPointer callData)
664{
665 char buf[256]; /* RATS: Only used in snprintf */
666
667 if (!dmxConfigCurrent)
668 return;
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);
676}
677
678static void
679dmxConfigNCCallback(Widget w, XtPointer closure, XtPointer callData)
680{
681 int width = 1280 * 2, height = 1024 * 2;
682
683 if (dmxConfigCurrent) {
684 width = dmxConfigCurrent->width;
685 height = dmxConfigCurrent->height;
686 }
687
688 dmxConfigCurrent = dmxConfigCreateVirtual(NULL, NULL, NULL,
689 NULL, NULL, NULL);
690 dmxConfigNewVirtual = dmxConfigCurrent;
691 dmxConfigCurrent->width = width;
692 dmxConfigCurrent->height = height;
693 dmxConfigEntry = dmxConfigAddEntry(dmxConfigEntry, dmxConfigVirtual, NULL,
694 dmxConfigCurrent);
695 dmxConfigECCallback(w, closure, callData);
696}
697
698static void
699dmxConfigDCCallback(Widget w, XtPointer closure, XtPointer callData)
700{
701 DMXConfigEntryPtr pt;
702
703 if (!dmxConfigEntry)
704 return;
705 if (dmxConfigEntry
706 && dmxConfigEntry->type == dmxConfigVirtual
707 && dmxConfigEntry->virtual == dmxConfigCurrent) {
708 dmxConfigEntry = dmxConfigEntry->next;
709 }
710 else {
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;
715 break;
716 }
717 }
718 dmxConfigFreeVirtual(dmxConfigCurrent);
719 dmxConfigCurrent = NULL;
720 dmxConfigCurrentDisplay = NULL;
721
722 /* Make the first entry current */
723 for (pt = dmxConfigEntry; pt; pt = pt->next) {
724 if (pt->type == dmxConfigVirtual) {
725 dmxConfigCurrent = pt->virtual;
726 break;
727 }
728 }
729
730 dmxConfigSetupCnamemenu();
731 dmxConfigCanvasDraw(NULL);
732}
733
734static void
735dmxConfigECOkCallback(Widget w, XtPointer closure, XtPointer callData)
736{
737 const char *value;
738 char *endpt;
739
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);
744 XtPopdown(ecpopup);
745 dmxConfigCurrentDisplay = NULL;
746 dmxConfigNewVirtual = NULL;
747 dmxConfigSetupCnamemenu();
748 dmxConfigCanvasDraw(NULL);
749 dmxConfigNotSaved = 1;
750}
751
752static void
753dmxConfigECCanCallback(Widget w, XtPointer closure, XtPointer callData)
754{
755 if (dmxConfigNewVirtual)
756 dmxConfigDCCallback(w, closure, callData);
757 dmxConfigNewVirtual = NULL;
758 XtPopdown(ecpopup);
759}
760
761static void
762dmxConfigEDCallback(Widget w, XtPointer closure, XtPointer callData)
763{
764 char buf[256]; /* RATS: Only used in snprintf */
765
766 if (!dmxConfigCurrent || !dmxConfigCurrentDisplay)
767 return;
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);
785}
786
787static void
788dmxConfigNDCallback(Widget w, XtPointer closure, XtPointer callData)
789{
790 int width = 1280, height = 1024;
791
792 if (!dmxConfigCurrent)
793 return;
794 if (dmxConfigCurrentDisplay) {
795 width = dmxConfigCurrentDisplay->scrnWidth;
796 height = dmxConfigCurrentDisplay->scrnHeight;
797 }
798 dmxConfigCurrentDisplay = dmxConfigCreateDisplay(NULL, NULL, NULL,
799 NULL, NULL);
800 dmxConfigNewDisplay = dmxConfigCurrentDisplay;
801 dmxConfigCurrentDisplay->scrnWidth = width;
802 dmxConfigCurrentDisplay->scrnHeight = height;
803
804 dmxConfigCurrent->subentry
805 = dmxConfigAddSub(dmxConfigCurrent->subentry,
806 dmxConfigSubDisplay(dmxConfigCurrentDisplay));
807 dmxConfigEDCallback(w, closure, callData);
808}
809
810static void
811dmxConfigDDCallback(Widget w, XtPointer closure, XtPointer callData)
812{
813 DMXConfigSubPtr pt;
814
815 if (!dmxConfigCurrent || !dmxConfigCurrentDisplay)
816 return;
817 /* First */
818 if (dmxConfigCurrent->subentry
819 && dmxConfigCurrent->subentry->type == dmxConfigDisplay
820 && dmxConfigCurrent->subentry->display == dmxConfigCurrentDisplay) {
821 dmxConfigCurrent->subentry = dmxConfigCurrent->subentry->next;
822 }
823 else {
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;
828 break;
829 }
830 }
831 dmxConfigFreeDisplay(dmxConfigCurrentDisplay);
832 dmxConfigCurrentDisplay = NULL;
833 dmxConfigSetupCnamemenu();
834 dmxConfigCanvasDraw(NULL);
835}
836
837static void
838dmxConfigAboutCallback(Widget w, XtPointer closure, XtPointer callData)
839{
840 dmxConfigSetPopupPosition(aboutpopup);
841 XtPopup(aboutpopup, XtGrabExclusive);
842}
843
844static void
845dmxConfigAboutOkCallback(Widget w, XtPointer closure, XtPointer CallData)
846{
847 XtPopdown(aboutpopup);
848}
849
850static void
851dmxConfigQuitCallback(Widget w, XtPointer closure, XtPointer callData)
852{
853 if (dmxConfigNotSaved) {
854 dmxConfigSetPopupPosition(quitpopup);
855 XtPopup(quitpopup, XtGrabExclusive);
856 return;
857 }
858 exit(0);
859}
860
861static void
862dmxConfigQuitOkCallback(Widget w, XtPointer closure, XtPointer callData)
863{
864 XtPopdown(quitpopup);
865 exit(0);
866}
867
868static void
869dmxConfigQuitCanCallback(Widget w, XtPointer closure, XtPointer callData)
870{
871 XtPopdown(quitpopup);
872}
873
874static void
875dmxConfigEDOkCallback(Widget w, XtPointer closure, XtPointer callData)
876{
877 char *value;
878 char *endpt;
879
880 dmxConfigNewDisplay = NULL;
881 dmxConfigGetValueString((char **) &dmxConfigCurrentDisplay->name,
882 eddialog0);
883 value = XawDialogGetValueString(eddialog1);
884 if (*value == '-' || *value == '+') {
885 dmxConfigCurrentDisplay->scrnWidth = 0;
886 dmxConfigCurrentDisplay->scrnHeight = 0;
887 endpt = value;
888 }
889 else {
890 dmxConfigCurrentDisplay->scrnWidth = strtol(value, &endpt, 10);
891 dmxConfigCurrentDisplay->scrnHeight = strtol(endpt + 1, &endpt, 10);
892 }
893 if (*endpt) {
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);
898 }
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);
906 XtPopdown(edpopup);
907 dmxConfigSetupCnamemenu();
908 dmxConfigCanvasDraw(NULL);
909 dmxConfigNotSaved = 1;
910}
911
912static void
913dmxConfigEDCanCallback(Widget w, XtPointer closure, XtPointer callData)
914{
915 if (dmxConfigNewDisplay)
916 dmxConfigDDCallback(w, closure, callData);
917 dmxConfigNewDisplay = NULL;
918 XtPopdown(edpopup);
919}
920
921static void
922dmxConfigOkAction(Widget w, XEvent * event,
923 String * params, Cardinal * num_params)
924{
925 Widget p = XtParent(w);
926 Widget t;
927
928 if (p == opendialog)
929 dmxConfigOkCallback(w, NULL, NULL);
930
931 if (p == ecdialog0) {
932 t = XtNameToWidget(ecdialog1, "value");
933 XWarpPointer(XtDisplay(t), None, XtWindow(t), 0, 0, 0, 0, 0, 10);
934 }
935 if (p == ecdialog1)
936 dmxConfigECOkCallback(w, NULL, NULL);
937
938 if (p == eddialog0) {
939 t = XtNameToWidget(eddialog1, "value");
940 XWarpPointer(XtDisplay(t), None, XtWindow(t), 0, 0, 0, 0, 0, 10);
941 }
942 if (p == eddialog1) {
943 t = XtNameToWidget(eddialog2, "value");
944 XWarpPointer(XtDisplay(t), None, XtWindow(t), 0, 0, 0, 0, 0, 10);
945 }
946 if (p == eddialog2)
947 dmxConfigEDOkCallback(w, NULL, NULL);
948}
949
950int
951main(int argc, char **argv)
952{
953 XtAppContext appContext;
954 Widget toplevel;
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;
960 Widget ncbutton;
961 Widget canbutton;
962 Widget ecbox, ecokbutton, eccanbutton;
963 Widget edbox, edokbutton;
964 Widget edcanbutton;
965
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\
973 Ctrl<Key>P: noop()";
974 const char *canvastrans =
975 "<Btn3Down>: placeMenu() XtMenuPopup(buttonpopup)";
976 XtActionsRec actiontable[] = {
977 {"openOk", dmxConfigOkAction},
978 {"placeMenu", dmxConfigPlaceMenu},
979 {"noop", NULL}
980 };
981
982 dmxConfigFilename = XtNewString((argc >= 2) ? argv[1] : "");
983
984 toplevel = XtVaAppInitialize(&appContext, "XDmxconfig",
985 NULL, 0, &argc, argv, NULL, NULL);
986
987 /* Main boxes */
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,
993 XtNborderWidth, 0,
994 XtNorientation, XtorientHorizontal,
995 XtNtop, XtChainTop, NULL);
996 bottombox = XtVaCreateManagedWidget("bottombox", formWidgetClass, parent,
997 XtNborderWidth, 0,
998 XtNfromVert, menubox,
999 XtNorientation, XtorientHorizontal,
1000 NULL);
1001 databox = XtVaCreateManagedWidget("databox", formWidgetClass,
1002 bottombox,
1003 XtNborderWidth, 0,
1004 XtNhorizDistance, 0,
1005 XtNwidth, DMX_DATA_WIDTH,
1006 XtNheight, DMX_DATA_HEIGHT,
1007 XtNleft, XtChainLeft,
1008 XtNorientation, XtorientVertical, NULL);
1009
1010 /* Data */
1011 cnamebox = XtVaCreateManagedWidget("cnamebox", menuButtonWidgetClass,
1012 databox,
1013 XtNtop, XtChainTop,
1014 XtNjustify, XtJustifyLeft,
1015 XtNwidth, DMX_DATA_WIDTH,
1016 XtNlabel, "",
1017 XtNmenuName, "cnamemenu", NULL);
1018 cdimbox = XtVaCreateManagedWidget("cdimbox", labelWidgetClass,
1019 databox,
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,
1030 databox,
1031 XtNfromVert, namebox,
1032 XtNjustify, XtJustifyLeft,
1033 XtNwidth, DMX_DATA_WIDTH,
1034 XtNlabel, "", NULL);
1035 rtbox = XtVaCreateManagedWidget("rtbox", labelWidgetClass,
1036 databox,
1037 XtNfromVert, dimbox,
1038 XtNjustify, XtJustifyLeft,
1039 XtNwidth, DMX_DATA_WIDTH,
1040 XtNlabel, "", NULL);
1041 origbox = XtVaCreateManagedWidget("origbox", labelWidgetClass,
1042 databox,
1043 XtNfromVert, rtbox,
1044 XtNjustify, XtJustifyLeft,
1045 XtNwidth, DMX_DATA_WIDTH,
1046 XtNlabel, "", NULL);
1047
1048 /* Canvas */
1049 canvasbox = XtVaCreateManagedWidget("canvasbox", boxWidgetClass,
1050 bottombox,
1051 XtNborderWidth, 0,
1052 XtNwidth, DMX_CANVAS_WIDTH,
1053 XtNheight, DMX_CANVAS_HEIGHT,
1054 XtNfromHoriz, databox, NULL);
1055
1056 canvas = XtVaCreateManagedWidget("canvas", canvasWidgetClass,
1057 canvasbox,
1058 XtNwidth, DMX_CANVAS_WIDTH,
1059 XtNheight, DMX_CANVAS_HEIGHT, NULL);
1060
1061 /* Main menu buttons */
1062 filebutton = XtVaCreateManagedWidget("File", menuButtonWidgetClass,
1063 menubox,
1064 XtNmenuName, "filemenu", NULL);
1065 helpbutton = XtVaCreateManagedWidget("Help", menuButtonWidgetClass,
1066 menubox,
1067 XtNmenuName, "helpmenu", NULL);
1068
1069 /* File submenu buttons */
1070 filemenu = XtVaCreatePopupShell("filemenu", simpleMenuWidgetClass,
1071 filebutton, NULL);
1072 openbutton = XtVaCreateManagedWidget("Open File", smeBSBObjectClass,
1073 filemenu, NULL);
1074 savebutton = XtVaCreateManagedWidget("Save File", smeBSBObjectClass,
1075 filemenu, NULL);
1076 ncbutton = XtVaCreateManagedWidget("New Global", smeBSBObjectClass,
1077 filemenu, NULL);
1078 ecbutton = XtVaCreateManagedWidget("Edit Global", smeBSBObjectClass,
1079 filemenu, NULL);
1080 dcbutton = XtVaCreateManagedWidget("Delete Global", smeBSBObjectClass,
1081 filemenu, NULL);
1082 ndbutton0 = XtVaCreateManagedWidget("New Display", smeBSBObjectClass,
1083 filemenu, NULL);
1084 quitbutton = XtVaCreateManagedWidget("Quit", smeBSBObjectClass,
1085 filemenu, NULL);
1086
1087 /* Help submenu button */
1088 helpmenu = XtVaCreatePopupShell("helpmenu", simpleMenuWidgetClass,
1089 helpbutton, NULL);
1090 aboutbutton = XtVaCreateManagedWidget("About", smeBSBObjectClass,
1091 helpmenu, NULL);
1092
1093 /* Open popup */
1094 openpopup = XtVaCreatePopupShell("openpopup", transientShellWidgetClass,
1095 toplevel, NULL);
1096 opendialog = XtVaCreateManagedWidget("opendialog", dialogWidgetClass,
1097 openpopup,
1098 XtNlabel, "Filename: ",
1099 XtNvalue, dmxConfigFilename, NULL);
1100 okbutton = XtVaCreateManagedWidget("Open", commandWidgetClass,
1101 opendialog, NULL);
1102 canbutton = XtVaCreateManagedWidget("Cancel", commandWidgetClass,
1103 opendialog, NULL);
1104
1105 /* EC popup */
1106 ecpopup = XtVaCreatePopupShell("ecpopup", transientShellWidgetClass,
1107 toplevel, NULL);
1108 ecbox = XtVaCreateManagedWidget("ecbox", boxWidgetClass, ecpopup, NULL);
1109 ecdialog0 = XtVaCreateManagedWidget("ecdialog0", dialogWidgetClass,
1110 ecbox,
1111 XtNlabel, "Name: ",
1112 XtNvalue, "", NULL);
1113 ecdialog1 = XtVaCreateManagedWidget("ecdialog1", dialogWidgetClass,
1114 ecbox,
1115 XtNlabel, "Dimension: ",
1116 XtNvalue, "", NULL);
1117 ecokbutton = XtVaCreateManagedWidget("OK", commandWidgetClass, ecbox, NULL);
1118 eccanbutton = XtVaCreateManagedWidget("Cancel", commandWidgetClass,
1119 ecbox, NULL);
1120
1121 /* ED popup */
1122 edpopup = XtVaCreatePopupShell("edpopup", transientShellWidgetClass,
1123 toplevel, NULL);
1124 edbox = XtVaCreateManagedWidget("edbox", boxWidgetClass, edpopup, NULL);
1125 eddialog0 = XtVaCreateManagedWidget("eddialog0", dialogWidgetClass,
1126 edbox,
1127 XtNlabel, "Display Name: ",
1128 XtNvalue, "", NULL);
1129 eddialog1 = XtVaCreateManagedWidget("eddialog1", dialogWidgetClass,
1130 edbox,
1131 XtNlabel, "Geometry: ",
1132 XtNvalue, "", NULL);
1133 eddialog2 = XtVaCreateManagedWidget("eddialog2", dialogWidgetClass,
1134 edbox,
1135 XtNlabel, "Offset: ",
1136 XtNvalue, "", NULL);
1137 edokbutton = XtVaCreateManagedWidget("OK", commandWidgetClass, edbox, NULL);
1138 edcanbutton = XtVaCreateManagedWidget("Cancel", commandWidgetClass,
1139 edbox, NULL);
1140
1141 /* About popup */
1142 aboutpopup = XtVaCreatePopupShell("aboutpopup", transientShellWidgetClass,
1143 toplevel, NULL);
1144 aboutbox = XtVaCreateManagedWidget("aboutbox", boxWidgetClass,
1145 aboutpopup, NULL);
1146 XtVaCreateManagedWidget("abouttext", labelWidgetClass,
1147 aboutbox, XtNlabel, DMX_INFO, NULL);
1148 aboutok = XtVaCreateManagedWidget("OK", commandWidgetClass, aboutbox, NULL);
1149
1150 /* Quit popup */
1151 quitpopup = XtVaCreatePopupShell("quitpopup", transientShellWidgetClass,
1152 toplevel, NULL);
1153 quitbox = XtVaCreateManagedWidget("quitbox", boxWidgetClass,
1154 quitpopup, NULL);
1155 XtVaCreateManagedWidget("quittext", labelWidgetClass,
1156 quitbox,
1157 XtNlabel,
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);
1166
1167 /* Button popup */
1168 buttonpopup = XtVaCreatePopupShell("buttonpopup", simpleMenuWidgetClass,
1169 toplevel, NULL);
1170 ndbutton1 = XtVaCreateManagedWidget("New Display", smeBSBObjectClass,
1171 buttonpopup, NULL);
1172 edbutton = XtVaCreateManagedWidget("Edit Display", smeBSBObjectClass,
1173 buttonpopup, NULL);
1174 ddbutton = XtVaCreateManagedWidget("Delete Display", smeBSBObjectClass,
1175 buttonpopup, NULL);
1176
1177 /* Callbacks */
1178 XtAddCallback(openbutton, XtNcallback, dmxConfigOpenCallback, NULL);
1179 XtAddCallback(savebutton, XtNcallback, dmxConfigSaveCallback, NULL);
1180 XtAddCallback(okbutton, XtNcallback, dmxConfigOkCallback, NULL);
1181 XtAddCallback(canbutton, XtNcallback, dmxConfigCanCallback, NULL);
1182
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));
1197
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);
1203
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);
1210
1211 XtAddCallback(aboutbutton, XtNcallback, dmxConfigAboutCallback, NULL);
1212 XtAddCallback(aboutok, XtNcallback, dmxConfigAboutOkCallback, NULL);
1213 XtAddCallback(quitok, XtNcallback, dmxConfigQuitOkCallback, NULL);
1214 XtAddCallback(quitcan, XtNcallback, dmxConfigQuitCanCallback, NULL);
1215
1216 XtAddCallback(quitbutton, XtNcallback, dmxConfigQuitCallback, NULL);
1217
1218 XtAddCallback(canvas, XtNcallback, dmxConfigCanvasInput, NULL);
1219 XtAddCallback(canvas, XtNcanvasExposeCallback, dmxConfigCanvasExpose, NULL);
1220 XtAddCallback(canvas, XtNcanvasResizeCallback, dmxConfigCanvasResize, NULL);
1221
1222 if (dmxConfigFilename)
1223 dmxConfigReadFile();
1224
1225 XtRealizeWidget(toplevel);
1226 dmxConfigCopystrings();
1227 dmxConfigSetupCnamemenu();
1228 XtAppMainLoop(appContext);
1229 return 0;
1230}