Commit | Line | Data |
---|---|---|
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 | ||
55 | extern int yyparse(void); | |
56 | extern 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 | ||
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; | |
79 | static enum { | |
80 | dmxConfigStateOpen, | |
81 | dmxConfigStateSave | |
82 | } dmxConfigState; | |
83 | ||
84 | /* Global widgets */ | |
85 | static Widget canvas; | |
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; | |
95 | ||
96 | static void | |
97 | dmxConfigCanvasGCs(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 | ||
137 | static void | |
138 | dmxConfigGetDims(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 | ||
186 | static int | |
187 | scalex(int x) | |
188 | { | |
189 | return (int) ((x * dmxConfigScaleX) + .5); | |
190 | } | |
191 | ||
192 | static int | |
193 | scaley(int y) | |
194 | { | |
195 | return (int) ((y * dmxConfigScaleY) + .5); | |
196 | } | |
197 | ||
198 | static int | |
199 | unscalex(int x) | |
200 | { | |
201 | return (int) ((x / dmxConfigScaleX) + .5); | |
202 | } | |
203 | ||
204 | static int | |
205 | unscaley(int y) | |
206 | { | |
207 | return (int) ((y / dmxConfigScaleY) + .5); | |
208 | } | |
209 | ||
210 | static void | |
211 | dmxConfigDataUpdate(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 | ||
280 | static void | |
281 | dmxConfigCanvasUpdate(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 | ||
335 | static void | |
336 | dmxConfigCanvasDraw(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 | ||
365 | static void | |
366 | dmxConfigSelectCallback(Widget w, XtPointer closure, XtPointer callData) | |
367 | { | |
368 | dmxConfigCurrent = closure; | |
369 | dmxConfigVirtualPrint(stdout, dmxConfigCurrent); | |
370 | dmxConfigCanvasDraw(NULL); | |
371 | } | |
372 | ||
373 | static void | |
374 | dmxConfigCopystrings(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 | ||
399 | static void | |
400 | dmxConfigGetValueString(char **d, Widget w) | |
401 | { | |
402 | const char *tmp = XawDialogGetValueString(w); | |
403 | ||
404 | if (*d) | |
405 | XtFree(*d); | |
406 | *d = XtNewString(tmp); | |
407 | } | |
408 | ||
409 | static void | |
410 | dmxConfigSetupCnamemenu(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 | ||
436 | static void | |
437 | dmxConfigReadFile(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 | ||
468 | static void | |
469 | dmxConfigWriteFile(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 | ||
482 | static DMXConfigDisplayPtr | |
483 | dmxConfigFindDisplay(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 | ||
503 | static void | |
504 | dmxConfigSetPopupPosition(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 | ||
522 | static void | |
523 | dmxConfigPlaceMenu(Widget w, XEvent * event, | |
524 | String * params, Cardinal * num_params) | |
525 | { | |
526 | dmxConfigSetPopupPosition(buttonpopup); | |
527 | } | |
528 | ||
529 | static void | |
530 | dmxConfigMove(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 | ||
548 | static void | |
549 | dmxConfigCanvasInput(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 | ||
612 | static void | |
613 | dmxConfigCanvasResize(Widget w, XtPointer closure, XtPointer callData) | |
614 | { | |
615 | dmxConfigCanvasDraw(NULL); | |
616 | } | |
617 | ||
618 | static void | |
619 | dmxConfigCanvasExpose(Widget w, XtPointer closure, XtPointer callData) | |
620 | { | |
621 | CanvasExposeDataPtr data = (CanvasExposeDataPtr) callData; | |
622 | ||
623 | dmxConfigCanvasDraw(data->region); | |
624 | } | |
625 | ||
626 | static void | |
627 | dmxConfigOpenCallback(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 | ||
635 | static void | |
636 | dmxConfigSaveCallback(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 | ||
644 | static void | |
645 | dmxConfigOkCallback(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 | ||
656 | static void | |
657 | dmxConfigCanCallback(Widget w, XtPointer closure, XtPointer callData) | |
658 | { | |
659 | XtPopdown(openpopup); | |
660 | } | |
661 | ||
662 | static void | |
663 | dmxConfigECCallback(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 | ||
678 | static void | |
679 | dmxConfigNCCallback(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 | ||
698 | static void | |
699 | dmxConfigDCCallback(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 | ||
734 | static void | |
735 | dmxConfigECOkCallback(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 | ||
752 | static void | |
753 | dmxConfigECCanCallback(Widget w, XtPointer closure, XtPointer callData) | |
754 | { | |
755 | if (dmxConfigNewVirtual) | |
756 | dmxConfigDCCallback(w, closure, callData); | |
757 | dmxConfigNewVirtual = NULL; | |
758 | XtPopdown(ecpopup); | |
759 | } | |
760 | ||
761 | static void | |
762 | dmxConfigEDCallback(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 | ||
787 | static void | |
788 | dmxConfigNDCallback(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 | ||
810 | static void | |
811 | dmxConfigDDCallback(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 | ||
837 | static void | |
838 | dmxConfigAboutCallback(Widget w, XtPointer closure, XtPointer callData) | |
839 | { | |
840 | dmxConfigSetPopupPosition(aboutpopup); | |
841 | XtPopup(aboutpopup, XtGrabExclusive); | |
842 | } | |
843 | ||
844 | static void | |
845 | dmxConfigAboutOkCallback(Widget w, XtPointer closure, XtPointer CallData) | |
846 | { | |
847 | XtPopdown(aboutpopup); | |
848 | } | |
849 | ||
850 | static void | |
851 | dmxConfigQuitCallback(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 | ||
861 | static void | |
862 | dmxConfigQuitOkCallback(Widget w, XtPointer closure, XtPointer callData) | |
863 | { | |
864 | XtPopdown(quitpopup); | |
865 | exit(0); | |
866 | } | |
867 | ||
868 | static void | |
869 | dmxConfigQuitCanCallback(Widget w, XtPointer closure, XtPointer callData) | |
870 | { | |
871 | XtPopdown(quitpopup); | |
872 | } | |
873 | ||
874 | static void | |
875 | dmxConfigEDOkCallback(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 | ||
912 | static void | |
913 | dmxConfigEDCanCallback(Widget w, XtPointer closure, XtPointer callData) | |
914 | { | |
915 | if (dmxConfigNewDisplay) | |
916 | dmxConfigDDCallback(w, closure, callData); | |
917 | dmxConfigNewDisplay = NULL; | |
918 | XtPopdown(edpopup); | |
919 | } | |
920 | ||
921 | static void | |
922 | dmxConfigOkAction(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 | ||
950 | int | |
951 | main(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 | } |