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
55 extern int yyparse(void);
56 extern int yydebug;
57 extern FILE *yyin;
58
59 #define DMX_INFO "xdmxconfig v0.9\nCopyright 2002 Red Hat Inc.\n"
60
61 #define DMX_MAIN_WIDTH 800
62 #define DMX_MAIN_HEIGHT 600
63 #define DMX_DATA_WIDTH 200
64 #define DMX_DATA_HEIGHT 200
65 #define DMX_CANVAS_WIDTH 400
66 #define DMX_CANVAS_HEIGHT 500
67
68 extern DMXConfigEntryPtr dmxConfigEntry;
69 static DMXConfigVirtualPtr dmxConfigCurrent, dmxConfigNewVirtual;
70 static DMXConfigDisplayPtr dmxConfigCurrentDisplay, dmxConfigNewDisplay;
71 static int dmxConfigGrabbed, dmxConfigGrabbedFine;
72 static int dmxConfigGrabbedX, dmxConfigGrabbedY;
73 static char *dmxConfigFilename;
74 static GC dmxConfigGC, dmxConfigGCRev, dmxConfigGCHL;
75 static int dmxConfigGCInit = 0;
76 static Dimension dmxConfigWidgetWidth, dmxConfigWidgetHeight;
77 static Dimension dmxConfigWallWidth, dmxConfigWallHeight;
78 static double dmxConfigScaleX, dmxConfigScaleY;
79 static int dmxConfigNotSaved;
80 static enum {
81 dmxConfigStateOpen,
82 dmxConfigStateSave
83 } dmxConfigState;
84
85 /* Global widgets */
86 static Widget canvas;
87 static Widget cnamebox, cdimbox;
88 static Widget openpopup, opendialog;
89 static Widget namebox, dimbox, rtbox, origbox;
90 static Widget okbutton, buttonpopup;
91 static Widget ecbutton, dcbutton;
92 static Widget ndbutton0, ndbutton1, edbutton, ddbutton;
93 static Widget ecpopup, ecdialog0, ecdialog1;
94 static Widget edpopup, eddialog0, eddialog1, eddialog2;
95 static Widget aboutpopup, quitpopup;
96
97 static void
dmxConfigCanvasGCs(void)98 dmxConfigCanvasGCs(void)
99 {
100 Display *dpy = XtDisplay(canvas);
101 Window win = XtWindow(canvas);
102 XGCValues gcvals;
103 unsigned long mask;
104 Colormap colormap;
105 XColor fg, bg, hl, tmp;
106
107 if (dmxConfigGCInit++)
108 return;
109
110 XtVaGetValues(canvas, XtNcolormap, &colormap, NULL);
111 XAllocNamedColor(XtDisplay(canvas), colormap, "black", &bg, &tmp);
112 XAllocNamedColor(XtDisplay(canvas), colormap, "white", &fg, &tmp);
113 XAllocNamedColor(XtDisplay(canvas), colormap, "red", &hl, &tmp);
114
115 mask = (GCFunction | GCPlaneMask | GCClipMask | GCForeground |
116 GCBackground | GCLineWidth | GCLineStyle | GCCapStyle |
117 GCFillStyle);
118
119 /* FIXME: copy this from widget */
120 gcvals.function = GXcopy;
121 gcvals.plane_mask = AllPlanes;
122 gcvals.clip_mask = None;
123 gcvals.foreground = fg.pixel;
124 gcvals.background = bg.pixel;
125 gcvals.line_width = 0;
126 gcvals.line_style = LineSolid;
127 gcvals.cap_style = CapNotLast;
128 gcvals.fill_style = FillSolid;
129
130 dmxConfigGC = XCreateGC(dpy, win, mask, &gcvals);
131 gcvals.foreground = hl.pixel;
132 dmxConfigGCHL = XCreateGC(dpy, win, mask, &gcvals);
133 gcvals.foreground = bg.pixel;
134 gcvals.background = fg.pixel;
135 dmxConfigGCRev = XCreateGC(dpy, win, mask, &gcvals);
136 }
137
138 static void
dmxConfigGetDims(int * maxWidth,int * maxHeight)139 dmxConfigGetDims(int *maxWidth, int *maxHeight)
140 {
141 DMXConfigSubPtr pt;
142 DMXConfigEntryPtr e;
143
144 *maxWidth = dmxConfigWallWidth = 0;
145 *maxHeight = dmxConfigWallHeight = 0;
146 if (!dmxConfigCurrent)
147 return;
148
149 dmxConfigWallWidth = dmxConfigCurrent->width;
150 dmxConfigWallHeight = dmxConfigCurrent->height;
151 if (!dmxConfigWallWidth || !dmxConfigWallHeight) {
152 for (pt = dmxConfigCurrent->subentry; pt; pt = pt->next) {
153 if (pt->type == dmxConfigDisplay) {
154 int x = pt->display->scrnWidth + pt->display->rootXOrigin;
155 int y = pt->display->scrnHeight + pt->display->rootYOrigin;
156
157 if (x > dmxConfigWallWidth)
158 dmxConfigWallWidth = x;
159 if (y > dmxConfigWallHeight)
160 dmxConfigWallHeight = y;
161 }
162 }
163 }
164 /* Compute maximums */
165 *maxWidth = *maxHeight = 0;
166 for (e = dmxConfigEntry; e; e = e->next) {
167 if (e->type != dmxConfigVirtual)
168 continue;
169 for (pt = e->virtual->subentry; pt; pt = pt->next) {
170 if (pt->type == dmxConfigDisplay) {
171 int x = pt->display->scrnWidth + pt->display->rootXOrigin;
172 int y = pt->display->scrnHeight + pt->display->rootYOrigin;
173
174 if (x > *maxWidth)
175 *maxWidth = x;
176 if (y > *maxHeight)
177 *maxHeight = y;
178 }
179 }
180 }
181 if (dmxConfigWallWidth > *maxWidth)
182 *maxWidth = dmxConfigWallWidth;
183 if (dmxConfigWallHeight > *maxHeight)
184 *maxHeight = dmxConfigWallHeight;
185 }
186
187 static int
scalex(int x)188 scalex(int x)
189 {
190 return (int) ((x * dmxConfigScaleX) + .5);
191 }
192
193 static int
scaley(int y)194 scaley(int y)
195 {
196 return (int) ((y * dmxConfigScaleY) + .5);
197 }
198
199 static int
unscalex(int x)200 unscalex(int x)
201 {
202 return (int) ((x / dmxConfigScaleX) + .5);
203 }
204
205 static int
unscaley(int y)206 unscaley(int y)
207 {
208 return (int) ((y / dmxConfigScaleY) + .5);
209 }
210
211 static void
dmxConfigDataUpdate(void)212 dmxConfigDataUpdate(void)
213 {
214 /* FIXME: could result in buffer overflows */
215 char cnambuf[512];
216 char cdimbuf[128];
217 char nambuf[512];
218 char dimbuf[128];
219 char rtbuf[128];
220 char offbuf[128];
221 const char *name;
222
223 if (!dmxConfigCurrent) {
224 XtVaSetValues(cnamebox, XtNlabel, "", XtNsensitive, False, NULL);
225 XtVaSetValues(cdimbox, XtNlabel, "", XtNsensitive, False, NULL);
226 XtVaSetValues(ecbutton, XtNsensitive, False, NULL);
227 XtVaSetValues(dcbutton, XtNsensitive, False, NULL);
228 XtVaSetValues(ndbutton0, XtNsensitive, False, NULL);
229 XtVaSetValues(ndbutton1, XtNsensitive, False, NULL);
230 }
231 else {
232 name = dmxConfigCurrent->name;
233 snprintf(cnambuf, sizeof(cnambuf), "%s", name ? name : "");
234 snprintf(cdimbuf, sizeof(cdimbuf), "%dx%d",
235 dmxConfigWallWidth, dmxConfigWallHeight);
236 XtVaSetValues(cnamebox, XtNlabel, cnambuf, XtNsensitive, True, NULL);
237 XtVaSetValues(cdimbox, XtNlabel, cdimbuf, XtNsensitive, True, NULL);
238 XtVaSetValues(ecbutton, XtNsensitive, True, NULL);
239 XtVaSetValues(dcbutton, XtNsensitive, True, NULL);
240 XtVaSetValues(ndbutton0, XtNsensitive, True, NULL);
241 XtVaSetValues(ndbutton1, XtNsensitive, True, NULL);
242 }
243
244 if (!dmxConfigCurrentDisplay) {
245 XtVaSetValues(namebox, XtNlabel, "", XtNsensitive, False, NULL);
246 XtVaSetValues(dimbox, XtNlabel, "", XtNsensitive, False, NULL);
247 XtVaSetValues(rtbox, XtNlabel, "", XtNsensitive, False, NULL);
248 XtVaSetValues(origbox, XtNlabel, "", XtNsensitive, False, NULL);
249 XtVaSetValues(edbutton, XtNsensitive, False, NULL);
250 XtVaSetValues(ddbutton, XtNsensitive, False, NULL);
251 }
252 else {
253 name = dmxConfigCurrentDisplay->name;
254 snprintf(nambuf, sizeof(nambuf), "%s", name ? name : "");
255 snprintf(dimbuf, sizeof(dimbuf), "%dx%d%c%d%c%d",
256 dmxConfigCurrentDisplay->scrnWidth,
257 dmxConfigCurrentDisplay->scrnHeight,
258 dmxConfigCurrentDisplay->scrnXSign < 0 ? '-' : '+',
259 dmxConfigCurrentDisplay->scrnX,
260 dmxConfigCurrentDisplay->scrnYSign < 0 ? '-' : '+',
261 dmxConfigCurrentDisplay->scrnY);
262 snprintf(rtbuf, sizeof(dimbuf), "%dx%d%c%d%c%d",
263 dmxConfigCurrentDisplay->rootWidth,
264 dmxConfigCurrentDisplay->rootHeight,
265 dmxConfigCurrentDisplay->rootXSign < 0 ? '-' : '+',
266 dmxConfigCurrentDisplay->rootX,
267 dmxConfigCurrentDisplay->rootYSign < 0 ? '-' : '+',
268 dmxConfigCurrentDisplay->rootY);
269 snprintf(offbuf, sizeof(offbuf), "@%dx%d",
270 dmxConfigCurrentDisplay->rootXOrigin,
271 dmxConfigCurrentDisplay->rootYOrigin);
272 XtVaSetValues(namebox, XtNlabel, nambuf, XtNsensitive, True, NULL);
273 XtVaSetValues(dimbox, XtNlabel, dimbuf, XtNsensitive, True, NULL);
274 XtVaSetValues(rtbox, XtNlabel, rtbuf, XtNsensitive, True, NULL);
275 XtVaSetValues(origbox, XtNlabel, offbuf, XtNsensitive, True, NULL);
276 XtVaSetValues(edbutton, XtNsensitive, True, NULL);
277 XtVaSetValues(ddbutton, XtNsensitive, True, NULL);
278 }
279 }
280
281 static void
dmxConfigCanvasUpdate(void)282 dmxConfigCanvasUpdate(void)
283 {
284 DMXConfigSubPtr pt;
285 Display *dpy = XtDisplay(canvas);
286 Window win = XtWindow(canvas);
287 GContext gcontext = XGContextFromGC(dmxConfigGC);
288 XFontStruct *fs;
289 int w, h;
290
291 XFillRectangle(dpy, win, dmxConfigGCRev,
292 0, 0, dmxConfigWidgetWidth, dmxConfigWidgetHeight);
293 dmxConfigDataUpdate();
294 if (!dmxConfigCurrent)
295 return;
296
297 w = scalex(dmxConfigWallWidth);
298 h = scaley(dmxConfigWallHeight);
299 if (w > dmxConfigWidgetWidth - 1)
300 w = dmxConfigWidgetWidth - 1;
301 if (h > dmxConfigWidgetHeight - 1)
302 h = dmxConfigWidgetHeight - 1;
303 XDrawRectangle(dpy, win, dmxConfigGC, 0, 0, w, h);
304 fs = XQueryFont(dpy, gcontext);
305 for (pt = dmxConfigCurrent->subentry; pt; pt = pt->next) {
306 int x, y, len;
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 int xo = 3, yo = fs->ascent + fs->descent + 2;
325
326 while (len && XTextWidth(fs, pt->display->name, len) >= w - 2 * xo)
327 --len;
328 if (len)
329 XDrawString(dpy, win, gc, x + xo, y + yo, pt->display->name,
330 len);
331 }
332 }
333 if (fs)
334 XFreeFontInfo(NULL, fs, 0);
335 }
336
337 static void
dmxConfigCanvasDraw(Region region)338 dmxConfigCanvasDraw(Region region)
339 {
340 Display *dpy = XtDisplay(canvas);
341 int maxWidth, maxHeight;
342
343 dmxConfigCanvasGCs();
344 if (region) {
345 XSetRegion(dpy, dmxConfigGC, region);
346 XSetRegion(dpy, dmxConfigGCRev, region);
347 XSetRegion(dpy, dmxConfigGCHL, region);
348 }
349 XtVaGetValues(canvas,
350 XtNwidth, &dmxConfigWidgetWidth,
351 XtNheight, &dmxConfigWidgetHeight, NULL);
352 dmxConfigGetDims(&maxWidth, &maxHeight);
353 dmxConfigScaleX = (double) dmxConfigWidgetWidth / maxWidth;
354 dmxConfigScaleY = (double) dmxConfigWidgetHeight / maxHeight;
355 if (dmxConfigScaleX > dmxConfigScaleY)
356 dmxConfigScaleX = dmxConfigScaleY;
357 if (dmxConfigScaleY > dmxConfigScaleX)
358 dmxConfigScaleY = dmxConfigScaleX;
359 dmxConfigCanvasUpdate();
360 if (region) {
361 XSetClipMask(dpy, dmxConfigGC, None);
362 XSetClipMask(dpy, dmxConfigGCRev, None);
363 XSetClipMask(dpy, dmxConfigGCHL, None);
364 }
365 }
366
367 static void
dmxConfigSelectCallback(Widget w,XtPointer closure,XtPointer callData)368 dmxConfigSelectCallback(Widget w, XtPointer closure, XtPointer callData)
369 {
370 dmxConfigCurrent = closure;
371 dmxConfigVirtualPrint(stdout, dmxConfigCurrent);
372 dmxConfigCanvasDraw(NULL);
373 }
374
375 static void
dmxConfigCopystrings(void)376 dmxConfigCopystrings(void)
377 {
378 DMXConfigEntryPtr pt;
379 DMXConfigSubPtr sub;
380
381 if (!dmxConfigCurrent)
382 return;
383
384 /* FIXME: this is all a per-config file
385 * memory leak */
386 for (pt = dmxConfigEntry; pt; pt = pt->next) {
387 if (pt->type == dmxConfigVirtual) {
388 pt->virtual->name = XtNewString(pt->virtual->name
389 ? pt->virtual->name : "");
390
391 for (sub = pt->virtual->subentry; sub; sub = sub->next) {
392 if (sub->type != dmxConfigDisplay)
393 continue;
394 sub->display->name = XtNewString(sub->display->name
395 ? sub->display->name : "");
396 }
397 }
398 }
399 }
400
401 static void
dmxConfigGetValueString(char ** d,Widget w)402 dmxConfigGetValueString(char **d, Widget w)
403 {
404 const char *tmp = XawDialogGetValueString(w);
405
406 if (*d)
407 XtFree(*d);
408 *d = XtNewString(tmp);
409 }
410
411 static void
dmxConfigSetupCnamemenu(void)412 dmxConfigSetupCnamemenu(void)
413 {
414 static Widget cnamemenu = NULL;
415 Widget w;
416 DMXConfigEntryPtr pt;
417
418 if (cnamemenu)
419 XtDestroyWidget(cnamemenu);
420 cnamemenu = NULL;
421
422 if (!dmxConfigCurrent)
423 return;
424 cnamemenu = XtVaCreatePopupShell("cnamemenu", simpleMenuWidgetClass,
425 cnamebox, NULL);
426
427 for (pt = dmxConfigEntry; pt; pt = pt->next) {
428 if (pt->type == dmxConfigVirtual) {
429 w = XtVaCreateManagedWidget(pt->virtual->name
430 ? pt->virtual->name
431 : "",
432 smeBSBObjectClass, cnamemenu, NULL);
433 XtAddCallback(w, XtNcallback, dmxConfigSelectCallback, pt->virtual);
434 }
435 }
436 }
437
438 static void
dmxConfigReadFile(void)439 dmxConfigReadFile(void)
440 {
441 FILE *str;
442 DMXConfigEntryPtr pt;
443
444 if (!(str = fopen(dmxConfigFilename, "r"))) {
445 dmxLog(dmxWarning, "Unable to read configuration file %s\n",
446 dmxConfigFilename);
447 return;
448 }
449 yyin = str;
450 yydebug = 0;
451 yyparse();
452 fclose(str);
453 dmxLog(dmxInfo, "Read configuration file %s\n", dmxConfigFilename);
454
455 for (pt = dmxConfigEntry; pt; pt = pt->next) {
456 if (pt->type == dmxConfigVirtual) {
457 dmxConfigCurrent = pt->virtual;
458 break;
459 }
460 }
461
462 if (XtIsRealized(canvas)) {
463 dmxConfigCopystrings();
464 dmxConfigSetupCnamemenu();
465 dmxConfigCanvasDraw(NULL);
466 }
467 dmxConfigVirtualPrint(stdout, dmxConfigCurrent);
468 }
469
470 static void
dmxConfigWriteFile(void)471 dmxConfigWriteFile(void)
472 {
473 FILE *str;
474
475 if (!(str = fopen(dmxConfigFilename, "w"))) {
476 dmxLog(dmxWarning, "Unable to write configuration file %s\n",
477 dmxConfigFilename);
478 return;
479 }
480 dmxConfigPrint(str, dmxConfigEntry);
481 fclose(str);
482 }
483
484 static DMXConfigDisplayPtr
dmxConfigFindDisplay(int x,int y)485 dmxConfigFindDisplay(int x, int y)
486 {
487 DMXConfigSubPtr pt;
488
489 if (!dmxConfigCurrent)
490 return NULL;
491 for (pt = dmxConfigCurrent->subentry; pt; pt = pt->next) {
492 DMXConfigDisplayPtr d = pt->display;
493
494 if (pt->type != dmxConfigDisplay)
495 continue;
496 if (x >= scalex(d->rootXOrigin)
497 && x <= scalex(d->rootXOrigin + d->scrnWidth)
498 && y >= scaley(d->rootYOrigin)
499 && y <= scaley(d->rootYOrigin + d->scrnHeight))
500 return d;
501 }
502 return NULL;
503 }
504
505 static void
dmxConfigSetPopupPosition(Widget popup)506 dmxConfigSetPopupPosition(Widget popup)
507 {
508 Position x, y;
509 Window t1, t2;
510 int root_x, root_y;
511 int temp_x, temp_y;
512 unsigned int temp;
513
514 XtRealizeWidget(popup);
515 if (!XQueryPointer(XtDisplay(popup), XtWindow(popup), &t1, &t2,
516 &root_x, &root_y, &temp_x, &temp_y, &temp))
517 root_x = root_y = 0;
518
519 x = root_x - 5;
520 y = root_y - 5;
521 XtVaSetValues(popup, XtNx, x, XtNy, y, NULL);
522 }
523
524 static void
dmxConfigPlaceMenu(Widget w,XEvent * event,String * params,Cardinal * num_params)525 dmxConfigPlaceMenu(Widget w, XEvent * event,
526 String * params, Cardinal * num_params)
527 {
528 dmxConfigSetPopupPosition(buttonpopup);
529 }
530
531 static void
dmxConfigMove(int deltaX,int deltaY)532 dmxConfigMove(int deltaX, int deltaY)
533 {
534 dmxConfigCurrentDisplay->rootXOrigin += deltaX;
535 dmxConfigCurrentDisplay->rootYOrigin += deltaY;
536 if (dmxConfigCurrentDisplay->rootXOrigin < 0)
537 dmxConfigCurrentDisplay->rootXOrigin = 0;
538 if (dmxConfigCurrentDisplay->rootYOrigin < 0)
539 dmxConfigCurrentDisplay->rootYOrigin = 0;
540 if (dmxConfigWallWidth && dmxConfigWallHeight) {
541 if (dmxConfigCurrentDisplay->rootXOrigin >= dmxConfigWallWidth)
542 dmxConfigCurrentDisplay->rootXOrigin = dmxConfigWallWidth - 1;
543 if (dmxConfigCurrentDisplay->rootYOrigin >= dmxConfigWallHeight)
544 dmxConfigCurrentDisplay->rootYOrigin = dmxConfigWallHeight - 1;
545 }
546 dmxConfigCanvasUpdate();
547 dmxConfigNotSaved = 1;
548 }
549
550 static void
dmxConfigCanvasInput(Widget w,XtPointer closure,XtPointer callData)551 dmxConfigCanvasInput(Widget w, XtPointer closure, XtPointer callData)
552 {
553 XEvent *e = (XEvent *) callData;
554 DMXConfigDisplayPtr display = NULL;
555
556 switch (e->type) {
557 case ButtonPress:
558 if (e->xbutton.button == Button1) {
559 dmxConfigGrabbed = 1;
560 dmxConfigGrabbedFine = 0;
561 dmxConfigGrabbedX = e->xbutton.x;
562 dmxConfigGrabbedY = e->xbutton.y;
563 }
564 if (e->xbutton.button == Button2) {
565 dmxConfigGrabbed = 1;
566 dmxConfigGrabbedFine = 1;
567 dmxConfigGrabbedX = e->xbutton.x;
568 dmxConfigGrabbedY = e->xbutton.y;
569 }
570 break;
571 case ButtonRelease:
572 if (e->xbutton.button == Button1)
573 dmxConfigGrabbed = 0;
574 if (e->xbutton.button == Button2)
575 dmxConfigGrabbed = 0;
576 break;
577 case MotionNotify:
578 if (dmxConfigGrabbed && dmxConfigCurrentDisplay) {
579 int deltaX = e->xmotion.x - dmxConfigGrabbedX;
580 int deltaY = e->xmotion.y - dmxConfigGrabbedY;
581
582 dmxConfigMove(dmxConfigGrabbedFine ? deltaX : unscalex(deltaX),
583 dmxConfigGrabbedFine ? deltaY : unscaley(deltaY));
584 dmxConfigGrabbedX = e->xmotion.x;
585 dmxConfigGrabbedY = e->xmotion.y;
586 }
587 else {
588 display = dmxConfigFindDisplay(e->xmotion.x, e->xmotion.y);
589 if (display != dmxConfigCurrentDisplay) {
590 dmxConfigCurrentDisplay = display;
591 dmxConfigCanvasUpdate();
592 }
593 }
594 break;
595 case KeyPress:
596 switch (XLookupKeysym(&e->xkey, 0)) {
597 case XK_Right:
598 dmxConfigMove(1, 0);
599 break;
600 case XK_Left:
601 dmxConfigMove(-1, 0);
602 break;
603 case XK_Down:
604 dmxConfigMove(0, 1);
605 break;
606 case XK_Up:
607 dmxConfigMove(0, -1);
608 break;
609 }
610 break;
611 }
612 }
613
614 static void
dmxConfigCanvasResize(Widget w,XtPointer closure,XtPointer callData)615 dmxConfigCanvasResize(Widget w, XtPointer closure, XtPointer callData)
616 {
617 dmxConfigCanvasDraw(NULL);
618 }
619
620 static void
dmxConfigCanvasExpose(Widget w,XtPointer closure,XtPointer callData)621 dmxConfigCanvasExpose(Widget w, XtPointer closure, XtPointer callData)
622 {
623 CanvasExposeDataPtr data = (CanvasExposeDataPtr) callData;
624
625 dmxConfigCanvasDraw(data->region);
626 }
627
628 static void
dmxConfigOpenCallback(Widget w,XtPointer closure,XtPointer callData)629 dmxConfigOpenCallback(Widget w, XtPointer closure, XtPointer callData)
630 {
631 dmxConfigState = dmxConfigStateOpen;
632 XtVaSetValues(okbutton, XtNlabel, "Open", NULL);
633 dmxConfigSetPopupPosition(openpopup);
634 XtPopup(openpopup, XtGrabExclusive);
635 }
636
637 static void
dmxConfigSaveCallback(Widget w,XtPointer closure,XtPointer callData)638 dmxConfigSaveCallback(Widget w, XtPointer closure, XtPointer callData)
639 {
640 dmxConfigState = dmxConfigStateSave;
641 XtVaSetValues(okbutton, XtNlabel, "Save", NULL);
642 dmxConfigSetPopupPosition(openpopup);
643 XtPopup(openpopup, XtGrabExclusive);
644 }
645
646 static void
dmxConfigOkCallback(Widget w,XtPointer closure,XtPointer callData)647 dmxConfigOkCallback(Widget w, XtPointer closure, XtPointer callData)
648 {
649 dmxConfigGetValueString(&dmxConfigFilename, opendialog);
650 XtPopdown(openpopup);
651 if (dmxConfigState == dmxConfigStateOpen)
652 dmxConfigReadFile();
653 else
654 dmxConfigWriteFile();
655 dmxConfigNotSaved = 0;
656 }
657
658 static void
dmxConfigCanCallback(Widget w,XtPointer closure,XtPointer callData)659 dmxConfigCanCallback(Widget w, XtPointer closure, XtPointer callData)
660 {
661 XtPopdown(openpopup);
662 }
663
664 static void
dmxConfigECCallback(Widget w,XtPointer closure,XtPointer callData)665 dmxConfigECCallback(Widget w, XtPointer closure, XtPointer callData)
666 {
667 char buf[256]; /* RATS: Only used in snprintf */
668
669 if (!dmxConfigCurrent)
670 return;
671 dmxConfigSetPopupPosition(ecpopup);
672 XtVaSetValues(ecdialog0, XtNvalue,
673 dmxConfigCurrent->name ? dmxConfigCurrent->name : "", NULL);
674 snprintf(buf, sizeof(buf), "%dx%d",
675 dmxConfigCurrent->width, dmxConfigCurrent->height);
676 XtVaSetValues(ecdialog1, XtNvalue, buf, NULL);
677 XtPopup(ecpopup, XtGrabExclusive);
678 }
679
680 static void
dmxConfigNCCallback(Widget w,XtPointer closure,XtPointer callData)681 dmxConfigNCCallback(Widget w, XtPointer closure, XtPointer callData)
682 {
683 int width = 1280 * 2, height = 1024 * 2;
684
685 if (dmxConfigCurrent) {
686 width = dmxConfigCurrent->width;
687 height = dmxConfigCurrent->height;
688 }
689
690 dmxConfigCurrent = dmxConfigCreateVirtual(NULL, NULL, NULL,
691 NULL, NULL, NULL);
692 dmxConfigNewVirtual = dmxConfigCurrent;
693 dmxConfigCurrent->width = width;
694 dmxConfigCurrent->height = height;
695 dmxConfigEntry = dmxConfigAddEntry(dmxConfigEntry, dmxConfigVirtual, NULL,
696 dmxConfigCurrent);
697 dmxConfigECCallback(w, closure, callData);
698 }
699
700 static void
dmxConfigDCCallback(Widget w,XtPointer closure,XtPointer callData)701 dmxConfigDCCallback(Widget w, XtPointer closure, XtPointer callData)
702 {
703 DMXConfigEntryPtr pt;
704
705 if (!dmxConfigEntry)
706 return;
707 if (dmxConfigEntry
708 && dmxConfigEntry->type == dmxConfigVirtual
709 && dmxConfigEntry->virtual == dmxConfigCurrent) {
710 dmxConfigEntry = dmxConfigEntry->next;
711 }
712 else {
713 for (pt = dmxConfigEntry; pt && pt->next; pt = pt->next)
714 if (pt->next->type == dmxConfigVirtual
715 && pt->next->virtual == dmxConfigCurrent) {
716 pt->next = pt->next->next;
717 break;
718 }
719 }
720 dmxConfigFreeVirtual(dmxConfigCurrent);
721 dmxConfigCurrent = NULL;
722 dmxConfigCurrentDisplay = NULL;
723
724 /* Make the first entry current */
725 for (pt = dmxConfigEntry; pt; pt = pt->next) {
726 if (pt->type == dmxConfigVirtual) {
727 dmxConfigCurrent = pt->virtual;
728 break;
729 }
730 }
731
732 dmxConfigSetupCnamemenu();
733 dmxConfigCanvasDraw(NULL);
734 }
735
736 static void
dmxConfigECOkCallback(Widget w,XtPointer closure,XtPointer callData)737 dmxConfigECOkCallback(Widget w, XtPointer closure, XtPointer callData)
738 {
739 const char *value;
740 char *endpt;
741
742 dmxConfigGetValueString((char **) &dmxConfigCurrent->name, ecdialog0);
743 value = XawDialogGetValueString(ecdialog1);
744 dmxConfigCurrent->width = strtol(value, &endpt, 10);
745 dmxConfigCurrent->height = strtol(endpt + 1, NULL, 10);
746 XtPopdown(ecpopup);
747 dmxConfigCurrentDisplay = NULL;
748 dmxConfigNewVirtual = NULL;
749 dmxConfigSetupCnamemenu();
750 dmxConfigCanvasDraw(NULL);
751 dmxConfigNotSaved = 1;
752 }
753
754 static void
dmxConfigECCanCallback(Widget w,XtPointer closure,XtPointer callData)755 dmxConfigECCanCallback(Widget w, XtPointer closure, XtPointer callData)
756 {
757 if (dmxConfigNewVirtual)
758 dmxConfigDCCallback(w, closure, callData);
759 dmxConfigNewVirtual = NULL;
760 XtPopdown(ecpopup);
761 }
762
763 static void
dmxConfigEDCallback(Widget w,XtPointer closure,XtPointer callData)764 dmxConfigEDCallback(Widget w, XtPointer closure, XtPointer callData)
765 {
766 char buf[256]; /* RATS: Only used in snprintf */
767
768 if (!dmxConfigCurrent || !dmxConfigCurrentDisplay)
769 return;
770 dmxConfigSetPopupPosition(edpopup);
771 XtVaSetValues(eddialog0, XtNvalue,
772 dmxConfigCurrentDisplay->name
773 ? dmxConfigCurrentDisplay->name : "", NULL);
774 snprintf(buf, sizeof(buf), "%dx%d%c%d%c%d",
775 dmxConfigCurrentDisplay->scrnWidth,
776 dmxConfigCurrentDisplay->scrnHeight,
777 dmxConfigCurrentDisplay->scrnXSign < 0 ? '-' : '+',
778 dmxConfigCurrentDisplay->scrnY,
779 dmxConfigCurrentDisplay->scrnYSign < 0 ? '-' : '+',
780 dmxConfigCurrentDisplay->scrnY);
781 XtVaSetValues(eddialog1, XtNvalue, buf, NULL);
782 snprintf(buf, sizeof(buf), "@%dx%d",
783 dmxConfigCurrentDisplay->rootXOrigin,
784 dmxConfigCurrentDisplay->rootYOrigin);
785 XtVaSetValues(eddialog2, XtNvalue, buf, NULL);
786 XtPopup(edpopup, XtGrabExclusive);
787 }
788
789 static void
dmxConfigNDCallback(Widget w,XtPointer closure,XtPointer callData)790 dmxConfigNDCallback(Widget w, XtPointer closure, XtPointer callData)
791 {
792 int width = 1280, height = 1024;
793
794 if (!dmxConfigCurrent)
795 return;
796 if (dmxConfigCurrentDisplay) {
797 width = dmxConfigCurrentDisplay->scrnWidth;
798 height = dmxConfigCurrentDisplay->scrnHeight;
799 }
800 dmxConfigCurrentDisplay = dmxConfigCreateDisplay(NULL, NULL, NULL,
801 NULL, NULL);
802 dmxConfigNewDisplay = dmxConfigCurrentDisplay;
803 dmxConfigCurrentDisplay->scrnWidth = width;
804 dmxConfigCurrentDisplay->scrnHeight = height;
805
806 dmxConfigCurrent->subentry
807 = dmxConfigAddSub(dmxConfigCurrent->subentry,
808 dmxConfigSubDisplay(dmxConfigCurrentDisplay));
809 dmxConfigEDCallback(w, closure, callData);
810 }
811
812 static void
dmxConfigDDCallback(Widget w,XtPointer closure,XtPointer callData)813 dmxConfigDDCallback(Widget w, XtPointer closure, XtPointer callData)
814 {
815 DMXConfigSubPtr pt;
816
817 if (!dmxConfigCurrent || !dmxConfigCurrentDisplay)
818 return;
819 /* First */
820 if (dmxConfigCurrent->subentry
821 && dmxConfigCurrent->subentry->type == dmxConfigDisplay
822 && dmxConfigCurrent->subentry->display == dmxConfigCurrentDisplay) {
823 dmxConfigCurrent->subentry = dmxConfigCurrent->subentry->next;
824 }
825 else {
826 for (pt = dmxConfigCurrent->subentry; pt && pt->next; pt = pt->next)
827 if (pt->next->type == dmxConfigDisplay
828 && pt->next->display == dmxConfigCurrentDisplay) {
829 pt->next = pt->next->next;
830 break;
831 }
832 }
833 dmxConfigFreeDisplay(dmxConfigCurrentDisplay);
834 dmxConfigCurrentDisplay = NULL;
835 dmxConfigSetupCnamemenu();
836 dmxConfigCanvasDraw(NULL);
837 }
838
839 static void
dmxConfigAboutCallback(Widget w,XtPointer closure,XtPointer callData)840 dmxConfigAboutCallback(Widget w, XtPointer closure, XtPointer callData)
841 {
842 dmxConfigSetPopupPosition(aboutpopup);
843 XtPopup(aboutpopup, XtGrabExclusive);
844 }
845
846 static void
dmxConfigAboutOkCallback(Widget w,XtPointer closure,XtPointer CallData)847 dmxConfigAboutOkCallback(Widget w, XtPointer closure, XtPointer CallData)
848 {
849 XtPopdown(aboutpopup);
850 }
851
852 static void
dmxConfigQuitCallback(Widget w,XtPointer closure,XtPointer callData)853 dmxConfigQuitCallback(Widget w, XtPointer closure, XtPointer callData)
854 {
855 if (dmxConfigNotSaved) {
856 dmxConfigSetPopupPosition(quitpopup);
857 XtPopup(quitpopup, XtGrabExclusive);
858 return;
859 }
860 exit(0);
861 }
862
863 static void
dmxConfigQuitOkCallback(Widget w,XtPointer closure,XtPointer callData)864 dmxConfigQuitOkCallback(Widget w, XtPointer closure, XtPointer callData)
865 {
866 XtPopdown(quitpopup);
867 exit(0);
868 }
869
870 static void
dmxConfigQuitCanCallback(Widget w,XtPointer closure,XtPointer callData)871 dmxConfigQuitCanCallback(Widget w, XtPointer closure, XtPointer callData)
872 {
873 XtPopdown(quitpopup);
874 }
875
876 static void
dmxConfigEDOkCallback(Widget w,XtPointer closure,XtPointer callData)877 dmxConfigEDOkCallback(Widget w, XtPointer closure, XtPointer callData)
878 {
879 char *value;
880 char *endpt;
881
882 dmxConfigNewDisplay = NULL;
883 dmxConfigGetValueString((char **) &dmxConfigCurrentDisplay->name,
884 eddialog0);
885 value = XawDialogGetValueString(eddialog1);
886 if (*value == '-' || *value == '+') {
887 dmxConfigCurrentDisplay->scrnWidth = 0;
888 dmxConfigCurrentDisplay->scrnHeight = 0;
889 endpt = value;
890 }
891 else {
892 dmxConfigCurrentDisplay->scrnWidth = strtol(value, &endpt, 10);
893 dmxConfigCurrentDisplay->scrnHeight = strtol(endpt + 1, &endpt, 10);
894 }
895 if (*endpt) {
896 dmxConfigCurrentDisplay->scrnXSign = (*endpt == '-') ? -1 : 1;
897 dmxConfigCurrentDisplay->scrnX = strtol(endpt + 1, &endpt, 10);
898 dmxConfigCurrentDisplay->scrnYSign = (*endpt == '-') ? -1 : 1;
899 dmxConfigCurrentDisplay->scrnY = strtol(endpt + 1, NULL, 10);
900 }
901 if (dmxConfigCurrentDisplay->scrnX < 0)
902 dmxConfigCurrentDisplay->scrnX = -dmxConfigCurrentDisplay->scrnX;
903 if (dmxConfigCurrentDisplay->scrnY < 0)
904 dmxConfigCurrentDisplay->scrnY = -dmxConfigCurrentDisplay->scrnY;
905 value = XawDialogGetValueString(eddialog2);
906 dmxConfigCurrentDisplay->rootXOrigin = strtol(value + 1, &endpt, 10);
907 dmxConfigCurrentDisplay->rootYOrigin = strtol(endpt + 1, NULL, 10);
908 XtPopdown(edpopup);
909 dmxConfigSetupCnamemenu();
910 dmxConfigCanvasDraw(NULL);
911 dmxConfigNotSaved = 1;
912 }
913
914 static void
dmxConfigEDCanCallback(Widget w,XtPointer closure,XtPointer callData)915 dmxConfigEDCanCallback(Widget w, XtPointer closure, XtPointer callData)
916 {
917 if (dmxConfigNewDisplay)
918 dmxConfigDDCallback(w, closure, callData);
919 dmxConfigNewDisplay = NULL;
920 XtPopdown(edpopup);
921 }
922
923 static void
dmxConfigOkAction(Widget w,XEvent * event,String * params,Cardinal * num_params)924 dmxConfigOkAction(Widget w, XEvent * event,
925 String * params, Cardinal * num_params)
926 {
927 Widget p = XtParent(w);
928 Widget t;
929
930 if (p == opendialog)
931 dmxConfigOkCallback(w, NULL, NULL);
932
933 if (p == ecdialog0) {
934 t = XtNameToWidget(ecdialog1, "value");
935 XWarpPointer(XtDisplay(t), None, XtWindow(t), 0, 0, 0, 0, 0, 10);
936 }
937 if (p == ecdialog1)
938 dmxConfigECOkCallback(w, NULL, NULL);
939
940 if (p == eddialog0) {
941 t = XtNameToWidget(eddialog1, "value");
942 XWarpPointer(XtDisplay(t), None, XtWindow(t), 0, 0, 0, 0, 0, 10);
943 }
944 if (p == eddialog1) {
945 t = XtNameToWidget(eddialog2, "value");
946 XWarpPointer(XtDisplay(t), None, XtWindow(t), 0, 0, 0, 0, 0, 10);
947 }
948 if (p == eddialog2)
949 dmxConfigEDOkCallback(w, NULL, NULL);
950 }
951
952 int
main(int argc,char ** argv)953 main(int argc, char **argv)
954 {
955 XtAppContext appContext;
956 Widget toplevel;
957 Widget parent, menubox, bottombox, databox, canvasbox;
958 Widget filebutton, helpbutton;
959 Widget filemenu, openbutton, savebutton, quitbutton;
960 Widget helpmenu, aboutbutton, aboutbox, aboutok;
961 Widget quitbox, quitok, quitcan;
962 Widget ncbutton;
963 Widget canbutton;
964 Widget ecbox, ecokbutton, eccanbutton;
965 Widget edbox, edokbutton;
966 Widget edcanbutton;
967
968 /* FIXME: add meta-i, ctrl,meta-z,v? */
969 const char *opentrans = "<Key>Return: openOk()\n\
970 <Key>Linefeed: openOk()\n\
971 Ctrl<Key>M: openOk()\n\
972 Ctrl<Key>J: openOk()\n\
973 Ctrl<Key>O: noop()\n\
974 Ctrl<Key>N: noop()\n\
975 Ctrl<Key>P: noop()";
976 const char *canvastrans =
977 "<Btn3Down>: placeMenu() XtMenuPopup(buttonpopup)";
978 XtActionsRec actiontable[] = {
979 {(char *) "openOk", dmxConfigOkAction},
980 {(char *) "placeMenu", dmxConfigPlaceMenu},
981 {(char *) "noop", NULL}
982 };
983
984 dmxConfigFilename = XtNewString((argc >= 2) ? argv[1] : "");
985
986 toplevel = XtVaAppInitialize(&appContext, "XDmxconfig",
987 NULL, 0, &argc, argv, NULL, NULL);
988
989 /* Main boxes */
990 parent = XtVaCreateManagedWidget("parent", formWidgetClass, toplevel,
991 XtNorientation, XtorientVertical,
992 XtNwidth, DMX_MAIN_WIDTH,
993 XtNheight, DMX_MAIN_HEIGHT, NULL);
994 menubox = XtVaCreateManagedWidget("menubox", boxWidgetClass, parent,
995 XtNborderWidth, 0,
996 XtNorientation, XtorientHorizontal,
997 XtNtop, XtChainTop, NULL);
998 bottombox = XtVaCreateManagedWidget("bottombox", formWidgetClass, parent,
999 XtNborderWidth, 0,
1000 XtNfromVert, menubox,
1001 XtNorientation, XtorientHorizontal,
1002 NULL);
1003 databox = XtVaCreateManagedWidget("databox", formWidgetClass,
1004 bottombox,
1005 XtNborderWidth, 0,
1006 XtNhorizDistance, 0,
1007 XtNwidth, DMX_DATA_WIDTH,
1008 XtNheight, DMX_DATA_HEIGHT,
1009 XtNleft, XtChainLeft,
1010 XtNorientation, XtorientVertical, NULL);
1011
1012 /* Data */
1013 cnamebox = XtVaCreateManagedWidget("cnamebox", menuButtonWidgetClass,
1014 databox,
1015 XtNtop, XtChainTop,
1016 XtNjustify, XtJustifyLeft,
1017 XtNwidth, DMX_DATA_WIDTH,
1018 XtNlabel, "",
1019 XtNmenuName, "cnamemenu", NULL);
1020 cdimbox = XtVaCreateManagedWidget("cdimbox", labelWidgetClass,
1021 databox,
1022 XtNfromVert, cnamebox,
1023 XtNjustify, XtJustifyLeft,
1024 XtNwidth, DMX_DATA_WIDTH,
1025 XtNlabel, "", NULL);
1026 namebox = XtVaCreateManagedWidget("namebox", labelWidgetClass, databox,
1027 XtNfromVert, cdimbox,
1028 XtNjustify, XtJustifyLeft,
1029 XtNwidth, DMX_DATA_WIDTH,
1030 XtNlabel, "", NULL);
1031 dimbox = XtVaCreateManagedWidget("dimbox", labelWidgetClass,
1032 databox,
1033 XtNfromVert, namebox,
1034 XtNjustify, XtJustifyLeft,
1035 XtNwidth, DMX_DATA_WIDTH,
1036 XtNlabel, "", NULL);
1037 rtbox = XtVaCreateManagedWidget("rtbox", labelWidgetClass,
1038 databox,
1039 XtNfromVert, dimbox,
1040 XtNjustify, XtJustifyLeft,
1041 XtNwidth, DMX_DATA_WIDTH,
1042 XtNlabel, "", NULL);
1043 origbox = XtVaCreateManagedWidget("origbox", labelWidgetClass,
1044 databox,
1045 XtNfromVert, rtbox,
1046 XtNjustify, XtJustifyLeft,
1047 XtNwidth, DMX_DATA_WIDTH,
1048 XtNlabel, "", NULL);
1049
1050 /* Canvas */
1051 canvasbox = XtVaCreateManagedWidget("canvasbox", boxWidgetClass,
1052 bottombox,
1053 XtNborderWidth, 0,
1054 XtNwidth, DMX_CANVAS_WIDTH,
1055 XtNheight, DMX_CANVAS_HEIGHT,
1056 XtNfromHoriz, databox, NULL);
1057
1058 canvas = XtVaCreateManagedWidget("canvas", canvasWidgetClass,
1059 canvasbox,
1060 XtNwidth, DMX_CANVAS_WIDTH,
1061 XtNheight, DMX_CANVAS_HEIGHT, NULL);
1062
1063 /* Main menu buttons */
1064 filebutton = XtVaCreateManagedWidget("File", menuButtonWidgetClass,
1065 menubox,
1066 XtNmenuName, "filemenu", NULL);
1067 helpbutton = XtVaCreateManagedWidget("Help", menuButtonWidgetClass,
1068 menubox,
1069 XtNmenuName, "helpmenu", NULL);
1070
1071 /* File submenu buttons */
1072 filemenu = XtVaCreatePopupShell("filemenu", simpleMenuWidgetClass,
1073 filebutton, NULL);
1074 openbutton = XtVaCreateManagedWidget("Open File", smeBSBObjectClass,
1075 filemenu, NULL);
1076 savebutton = XtVaCreateManagedWidget("Save File", smeBSBObjectClass,
1077 filemenu, NULL);
1078 ncbutton = XtVaCreateManagedWidget("New Global", smeBSBObjectClass,
1079 filemenu, NULL);
1080 ecbutton = XtVaCreateManagedWidget("Edit Global", smeBSBObjectClass,
1081 filemenu, NULL);
1082 dcbutton = XtVaCreateManagedWidget("Delete Global", smeBSBObjectClass,
1083 filemenu, NULL);
1084 ndbutton0 = XtVaCreateManagedWidget("New Display", smeBSBObjectClass,
1085 filemenu, NULL);
1086 quitbutton = XtVaCreateManagedWidget("Quit", smeBSBObjectClass,
1087 filemenu, NULL);
1088
1089 /* Help submenu button */
1090 helpmenu = XtVaCreatePopupShell("helpmenu", simpleMenuWidgetClass,
1091 helpbutton, NULL);
1092 aboutbutton = XtVaCreateManagedWidget("About", smeBSBObjectClass,
1093 helpmenu, NULL);
1094
1095 /* Open popup */
1096 openpopup = XtVaCreatePopupShell("openpopup", transientShellWidgetClass,
1097 toplevel, NULL);
1098 opendialog = XtVaCreateManagedWidget("opendialog", dialogWidgetClass,
1099 openpopup,
1100 XtNlabel, "Filename: ",
1101 XtNvalue, dmxConfigFilename, NULL);
1102 okbutton = XtVaCreateManagedWidget("Open", commandWidgetClass,
1103 opendialog, NULL);
1104 canbutton = XtVaCreateManagedWidget("Cancel", commandWidgetClass,
1105 opendialog, NULL);
1106
1107 /* EC popup */
1108 ecpopup = XtVaCreatePopupShell("ecpopup", transientShellWidgetClass,
1109 toplevel, NULL);
1110 ecbox = XtVaCreateManagedWidget("ecbox", boxWidgetClass, ecpopup, NULL);
1111 ecdialog0 = XtVaCreateManagedWidget("ecdialog0", dialogWidgetClass,
1112 ecbox,
1113 XtNlabel, "Name: ",
1114 XtNvalue, "", NULL);
1115 ecdialog1 = XtVaCreateManagedWidget("ecdialog1", dialogWidgetClass,
1116 ecbox,
1117 XtNlabel, "Dimension: ",
1118 XtNvalue, "", NULL);
1119 ecokbutton = XtVaCreateManagedWidget("OK", commandWidgetClass, ecbox, NULL);
1120 eccanbutton = XtVaCreateManagedWidget("Cancel", commandWidgetClass,
1121 ecbox, NULL);
1122
1123 /* ED popup */
1124 edpopup = XtVaCreatePopupShell("edpopup", transientShellWidgetClass,
1125 toplevel, NULL);
1126 edbox = XtVaCreateManagedWidget("edbox", boxWidgetClass, edpopup, NULL);
1127 eddialog0 = XtVaCreateManagedWidget("eddialog0", dialogWidgetClass,
1128 edbox,
1129 XtNlabel, "Display Name: ",
1130 XtNvalue, "", NULL);
1131 eddialog1 = XtVaCreateManagedWidget("eddialog1", dialogWidgetClass,
1132 edbox,
1133 XtNlabel, "Geometry: ",
1134 XtNvalue, "", NULL);
1135 eddialog2 = XtVaCreateManagedWidget("eddialog2", dialogWidgetClass,
1136 edbox,
1137 XtNlabel, "Offset: ",
1138 XtNvalue, "", NULL);
1139 edokbutton = XtVaCreateManagedWidget("OK", commandWidgetClass, edbox, NULL);
1140 edcanbutton = XtVaCreateManagedWidget("Cancel", commandWidgetClass,
1141 edbox, NULL);
1142
1143 /* About popup */
1144 aboutpopup = XtVaCreatePopupShell("aboutpopup", transientShellWidgetClass,
1145 toplevel, NULL);
1146 aboutbox = XtVaCreateManagedWidget("aboutbox", boxWidgetClass,
1147 aboutpopup, NULL);
1148 XtVaCreateManagedWidget("abouttext", labelWidgetClass,
1149 aboutbox, XtNlabel, DMX_INFO, NULL);
1150 aboutok = XtVaCreateManagedWidget("OK", commandWidgetClass, aboutbox, NULL);
1151
1152 /* Quit popup */
1153 quitpopup = XtVaCreatePopupShell("quitpopup", transientShellWidgetClass,
1154 toplevel, NULL);
1155 quitbox = XtVaCreateManagedWidget("quitbox", boxWidgetClass,
1156 quitpopup, NULL);
1157 XtVaCreateManagedWidget("quittext", labelWidgetClass,
1158 quitbox,
1159 XtNlabel,
1160 "Changes to the configuration\n"
1161 "been made that have not yet\n"
1162 "been saved. Do you want to\n"
1163 "quit without saving?", NULL);
1164 quitok = XtVaCreateManagedWidget("Quit WITHOUT Saving",
1165 commandWidgetClass, quitbox, NULL);
1166 quitcan = XtVaCreateManagedWidget("Continue Editing",
1167 commandWidgetClass, quitbox, NULL);
1168
1169 /* Button popup */
1170 buttonpopup = XtVaCreatePopupShell("buttonpopup", simpleMenuWidgetClass,
1171 toplevel, NULL);
1172 ndbutton1 = XtVaCreateManagedWidget("New Display", smeBSBObjectClass,
1173 buttonpopup, NULL);
1174 edbutton = XtVaCreateManagedWidget("Edit Display", smeBSBObjectClass,
1175 buttonpopup, NULL);
1176 ddbutton = XtVaCreateManagedWidget("Delete Display", smeBSBObjectClass,
1177 buttonpopup, NULL);
1178
1179 /* Callbacks */
1180 XtAddCallback(openbutton, XtNcallback, dmxConfigOpenCallback, NULL);
1181 XtAddCallback(savebutton, XtNcallback, dmxConfigSaveCallback, NULL);
1182 XtAddCallback(okbutton, XtNcallback, dmxConfigOkCallback, NULL);
1183 XtAddCallback(canbutton, XtNcallback, dmxConfigCanCallback, NULL);
1184
1185 XtAppAddActions(appContext, actiontable, XtNumber(actiontable));
1186 XtOverrideTranslations(canvas, XtParseTranslationTable(canvastrans));
1187 XtOverrideTranslations(XtNameToWidget(opendialog, "value"),
1188 XtParseTranslationTable(opentrans));
1189 XtOverrideTranslations(XtNameToWidget(ecdialog0, "value"),
1190 XtParseTranslationTable(opentrans));
1191 XtOverrideTranslations(XtNameToWidget(ecdialog1, "value"),
1192 XtParseTranslationTable(opentrans));
1193 XtOverrideTranslations(XtNameToWidget(eddialog0, "value"),
1194 XtParseTranslationTable(opentrans));
1195 XtOverrideTranslations(XtNameToWidget(eddialog1, "value"),
1196 XtParseTranslationTable(opentrans));
1197 XtOverrideTranslations(XtNameToWidget(eddialog2, "value"),
1198 XtParseTranslationTable(opentrans));
1199
1200 XtAddCallback(ncbutton, XtNcallback, dmxConfigNCCallback, NULL);
1201 XtAddCallback(ecbutton, XtNcallback, dmxConfigECCallback, NULL);
1202 XtAddCallback(ecokbutton, XtNcallback, dmxConfigECOkCallback, NULL);
1203 XtAddCallback(eccanbutton, XtNcallback, dmxConfigECCanCallback, NULL);
1204 XtAddCallback(dcbutton, XtNcallback, dmxConfigDCCallback, NULL);
1205
1206 XtAddCallback(ndbutton0, XtNcallback, dmxConfigNDCallback, NULL);
1207 XtAddCallback(ndbutton1, XtNcallback, dmxConfigNDCallback, NULL);
1208 XtAddCallback(edbutton, XtNcallback, dmxConfigEDCallback, NULL);
1209 XtAddCallback(ddbutton, XtNcallback, dmxConfigDDCallback, NULL);
1210 XtAddCallback(edokbutton, XtNcallback, dmxConfigEDOkCallback, NULL);
1211 XtAddCallback(edcanbutton, XtNcallback, dmxConfigEDCanCallback, NULL);
1212
1213 XtAddCallback(aboutbutton, XtNcallback, dmxConfigAboutCallback, NULL);
1214 XtAddCallback(aboutok, XtNcallback, dmxConfigAboutOkCallback, NULL);
1215 XtAddCallback(quitok, XtNcallback, dmxConfigQuitOkCallback, NULL);
1216 XtAddCallback(quitcan, XtNcallback, dmxConfigQuitCanCallback, NULL);
1217
1218 XtAddCallback(quitbutton, XtNcallback, dmxConfigQuitCallback, NULL);
1219
1220 XtAddCallback(canvas, XtNcallback, dmxConfigCanvasInput, NULL);
1221 XtAddCallback(canvas, XtNcanvasExposeCallback, dmxConfigCanvasExpose, NULL);
1222 XtAddCallback(canvas, XtNcanvasResizeCallback, dmxConfigCanvasResize, NULL);
1223
1224 if (dmxConfigFilename)
1225 dmxConfigReadFile();
1226
1227 XtRealizeWidget(toplevel);
1228 dmxConfigCopystrings();
1229 dmxConfigSetupCnamemenu();
1230 XtAppMainLoop(appContext);
1231 return 0;
1232 }
1233