1 /*----------------------------------------------------------------------*/
2 /* xtfuncs.c --- Functions associated with the XCircuit Xt GUI */
3 /* (no Tcl/Tk interpreter) */
4 /* Copyright (c) 2002 Tim Edwards, Johns Hopkins University */
5 /*----------------------------------------------------------------------*/
13 #include <sys/types.h>
18 #include <X11/Intrinsic.h>
19 #include <X11/StringDefs.h>
20 #include <X11/Xutil.h>
23 #include "Xw/MenuBtn.h"
24 #include "Xw/PopupMgr.h"
27 /*----------------------------------------------------------------------*/
29 /*----------------------------------------------------------------------*/
31 #include "colordefs.h"
34 /*----------------------------------------------------------------------*/
35 /* Function prototype declarations */
36 /*----------------------------------------------------------------------*/
37 #include "prototypes.h"
39 /*----------------------------------------------------------------------*/
40 /* External Variable definitions */
41 /*----------------------------------------------------------------------*/
43 extern char _STR2
[250];
44 extern char _STR
[150]; /* Generic multipurpose string */
47 extern Globaldata xobjs
;
48 extern XCWindowData
*areawin
;
49 extern int number_colors
;
50 extern colorindex
*colorlist
;
51 extern ApplicationData appdata
;
52 extern Cursor appcursors
[NUM_CURSORS
];
53 extern fontinfo
*fonts
;
54 extern short fontcount
;
55 extern xcWidget menuwidgets
[];
56 extern xcWidget toolbar
;
57 extern short popups
; /* total number of popup windows */
59 /*----------------------------------------------------------------------*/
60 /* The rest of the local includes depend on the prototype declarations */
61 /* and some of the external global variable declarations. */
62 /*----------------------------------------------------------------------*/
67 /*----------------------------------------------------------------------*/
68 /* External variable definitions */
69 /*----------------------------------------------------------------------*/
71 extern u_short
*fontnumbers
;
72 extern u_char nfontnumbers
;
74 /*----------------------------------------------*/
75 /* Set Poly and Arc line styles and fill styles */
76 /*----------------------------------------------*/
78 #define BORDERS (NOBORDER | DOTTED | DASHED)
79 #define ALLFILLS (FILLSOLID | FILLED)
81 /*--------------------------------------------------------------*/
82 /* Menu toggle button functions (keeps Xt functions out of the */
83 /* file menucalls.c). These are wrappers for toggleexcl(). */
84 /*--------------------------------------------------------------*/
86 void togglegridstyles(xcWidget button
) {
88 toggleexcl(button
, GridStyles
, XtNumber(GridStyles
));
91 void toggleanchors(xcWidget button
) {
93 toggleexcl(button
, Anchors
, XtNumber(Anchors
));
96 void togglefontstyles(xcWidget button
) {
98 toggleexcl(button
, FontStyles
, XtNumber(FontStyles
));
101 void toggleencodings(xcWidget button
) {
103 toggleexcl(button
, FontEncodings
, XtNumber(FontEncodings
));
106 /*--------------------------------------------------------------*/
107 /* Toggle a bit in the anchoring field of a label */
108 /*--------------------------------------------------------------*/
110 void doanchorbit(xcWidget w
, labelptr settext
, short bitfield
)
112 if (settext
!= NULL
) {
113 int oldanchor
= (int)settext
->anchor
;
116 settext
->anchor
^= bitfield
;
118 pwriteback(areawin
->topinstance
);
120 register_for_undo(XCF_Anchor
, UNDO_MORE
, areawin
->topinstance
,
121 (genericptr
)settext
, oldanchor
);
124 areawin
->anchor
^= bitfield
;
129 boolval
= (settext
->anchor
& bitfield
) ? 0 : 1;
131 boolval
= (areawin
->anchor
& bitfield
) ? 0 : 1;
132 toggle(w
, (pointertype
)(-1), &boolval
);
136 /*--------------------------------------------------------------*/
137 /* Toggle a pin-related bit in the anchoring field of a */
138 /* label. This differs from doanchorbit() in that the label */
139 /* must be a pin, and this function cannot change the default */
140 /* behavior set by areawin->anchor. */
141 /*--------------------------------------------------------------*/
143 void dopinanchorbit(xcWidget w
, labelptr settext
, short bitfield
)
145 if ((settext
!= NULL
) && settext
->pin
) {
146 int oldanchor
= (int)settext
->anchor
;
149 settext
->anchor
^= bitfield
;
151 pwriteback(areawin
->topinstance
);
153 register_for_undo(XCF_Anchor
, UNDO_MORE
, areawin
->topinstance
,
154 (genericptr
)settext
, oldanchor
);
157 Boolean boolval
= (settext
->anchor
& bitfield
) ? 0 : 1;
158 toggle(w
, (pointertype
)(-1), &boolval
);
163 /*----------------------------------------------------------------*/
164 /* Set the anchoring for the label passed as 3rd parameter */
165 /*----------------------------------------------------------------*/
167 void setanchor(xcWidget w
, pointertype value
, labelptr settext
, short mode
)
169 short newanchor
, oldanchor
;
171 if (settext
!= NULL
) {
174 newanchor
= (settext
->anchor
& (NONANCHORFIELD
| TBANCHORFIELD
))
177 newanchor
= (settext
->anchor
& (NONANCHORFIELD
| RLANCHORFIELD
))
180 if (settext
->anchor
!= newanchor
) {
181 oldanchor
= (int)settext
->anchor
;
183 settext
->anchor
= newanchor
;
185 pwriteback(areawin
->topinstance
);
187 register_for_undo(XCF_Anchor
, UNDO_MORE
, areawin
->topinstance
,
188 (genericptr
)settext
, oldanchor
);
193 newanchor
= (areawin
->anchor
& (NONANCHORFIELD
| TBANCHORFIELD
))
196 newanchor
= (areawin
->anchor
& (NONANCHORFIELD
| RLANCHORFIELD
))
198 areawin
->anchor
= newanchor
;
200 if (w
!= NULL
) toggleanchors(w
);
203 /*--------------------------------------------------------------*/
204 /* Set vertical anchoring (top, middle, bottom) on all */
205 /* selected labels */
206 /*--------------------------------------------------------------*/
208 void setvanchor(xcWidget w
, pointertype value
, caddr_t nulldata
)
212 short labelcount
= 0;
214 if (eventmode
== TEXT_MODE
|| eventmode
== ETEXT_MODE
) {
215 settext
= *((labelptr
*)EDITPART
);
216 setanchor(w
, value
, settext
, 2);
219 for (fselect
= areawin
->selectlist
; fselect
< areawin
->selectlist
+
220 areawin
->selects
; fselect
++) {
221 if (SELECTTYPE(fselect
) == LABEL
) {
223 settext
= SELTOLABEL(fselect
);
224 setanchor(NULL
, value
, settext
, 2);
227 if (labelcount
== 0) setanchor(w
, value
, NULL
, 2);
232 /*----------------------------------------------------------------*/
233 /* Set horizontal anchoring (left, center, right) on all */
234 /* selected labels */
235 /*----------------------------------------------------------------*/
237 void sethanchor(xcWidget w
, pointertype value
, caddr_t nulldata
)
241 short labelcount
= 0;
243 if (eventmode
== TEXT_MODE
|| eventmode
== ETEXT_MODE
) {
244 settext
= *((labelptr
*)EDITPART
);
245 setanchor(w
, value
, settext
, 1);
248 for (fselect
= areawin
->selectlist
; fselect
< areawin
->selectlist
+
249 areawin
->selects
; fselect
++) {
250 if (SELECTTYPE(fselect
) == LABEL
) {
252 settext
= SELTOLABEL(fselect
);
253 setanchor(NULL
, value
, settext
, 1);
256 if (labelcount
== 0) setanchor(w
, value
, NULL
, 1);
261 /*--------------------------------------------------------------*/
262 /* Set an anchor field bit on all selected labels */
263 /* (flip invariance, latex mode, etc.) */
264 /*--------------------------------------------------------------*/
266 void setanchorbit(xcWidget w
, pointertype value
, caddr_t nulldata
)
270 short labelcount
= 0;
272 if (eventmode
== TEXT_MODE
|| eventmode
== ETEXT_MODE
) {
273 settext
= *((labelptr
*)EDITPART
);
274 doanchorbit(w
, settext
, (short)value
);
277 for (fselect
= areawin
->selectlist
; fselect
< areawin
->selectlist
+
278 areawin
->selects
; fselect
++) {
279 if (SELECTTYPE(fselect
) == LABEL
) {
281 settext
= SELTOLABEL(fselect
);
282 doanchorbit(NULL
, settext
, (short)value
);
285 if (labelcount
== 0) doanchorbit(w
, NULL
, (short)value
);
290 /*--------------------------------------------------------------*/
291 /* Set pin-related bit field of "anchor" on all selected pins */
292 /* (e.g., pin visibility) */
293 /*--------------------------------------------------------------*/
295 void setpinanchorbit(xcWidget w
, pointertype value
, caddr_t nulldata
)
300 if (eventmode
== TEXT_MODE
|| eventmode
== ETEXT_MODE
) {
301 settext
= *((labelptr
*)EDITPART
);
303 dopinanchorbit(w
, settext
, (short)value
);
306 for (fselect
= areawin
->selectlist
; fselect
< areawin
->selectlist
+
307 areawin
->selects
; fselect
++) {
308 if (SELECTTYPE(fselect
) == LABEL
) {
309 settext
= SELTOLABEL(fselect
);
311 dopinanchorbit(NULL
, settext
, (short)value
);
318 /*--------------------------------------------------------------*/
319 /* Enable or Disable the toolbar */
320 /*--------------------------------------------------------------*/
323 void dotoolbar(xcWidget w
, caddr_t clientdata
, caddr_t calldata
)
327 if (areawin
->toolbar_on
) {
328 areawin
->toolbar_on
= False
;
329 XtUnmanageChild(toolbar
);
330 XtSetArg(wargs
[0], XtNlabel
, "Enable Toolbar");
331 XtSetValues(OptionsDisableToolbarButton
, wargs
, 1);
332 XtRemoveCallback(areawin
->area
, XtNresize
, (XtCallbackProc
)resizetoolbar
, NULL
);
335 areawin
->toolbar_on
= True
;
336 XtManageChild(toolbar
);
337 XtSetArg(wargs
[0], XtNlabel
, "Disable Toolbar");
338 XtSetValues(OptionsDisableToolbarButton
, wargs
, 1);
339 XtAddCallback(areawin
->area
, XtNresize
, (XtCallbackProc
)resizetoolbar
, NULL
);
343 /*--------------------------------------------------------------*/
344 /* Overwrite the toolbar pixmap for color or stipple entries */
345 /*--------------------------------------------------------------*/
349 void overdrawpixmap(xcWidget button
)
356 if (button
== NULL
) return;
358 XtSetArg(args
[0], XtNlabelType
, <ype
);
359 XtGetValues(button
, args
, 1);
361 if (ltype
!= XwRECT
&& button
!= ColorInheritColorButton
) return;
363 XtSetArg(args
[0], XtNrectColor
, &color
);
364 XtSetArg(args
[1], XtNrectStipple
, &stippix
);
365 XtGetValues(button
, args
, 2);
367 if (stippix
== (Pixmap
)NULL
&& button
!= FillBlackButton
)
368 pbutton
= ColorsToolButton
;
370 pbutton
= FillsToolButton
;
372 if (button
== ColorInheritColorButton
) {
373 XtSetArg(args
[0], XtNlabelType
, XwIMAGE
);
374 XtSetValues(pbutton
, args
, 1);
376 else if (button
== FillBlackButton
) {
377 XtSetArg(args
[0], XtNlabelType
, XwRECT
);
378 XtSetArg(args
[1], XtNrectColor
, color
);
379 XtSetArg(args
[2], XtNrectStipple
, (Pixmap
)NULL
);
380 XtSetValues(pbutton
, args
, 3);
382 else if (button
!= FillOpaqueButton
) {
383 XtSetArg(args
[0], XtNlabelType
, XwRECT
);
384 if (stippix
== (Pixmap
)NULL
)
385 XtSetArg(args
[1], XtNrectColor
, color
);
387 XtSetArg(args
[1], XtNrectStipple
, stippix
);
389 XtSetValues(pbutton
, args
, 2);
396 void overdrawpixmap(xcWidget button
) {}
399 /*--------------------------------------------------------------*/
400 /* Generic routine for use by all other data handling routines */
401 /*--------------------------------------------------------------*/
403 buttonsave
*getgeneric(xcWidget button
, void (*getfunction
)(), void *dataptr
)
408 saveptr
= (buttonsave
*)malloc(sizeof(buttonsave
));
409 saveptr
->button
= button
;
410 saveptr
->buttoncall
= getfunction
;
411 saveptr
->dataptr
= dataptr
;
413 if (button
!= NULL
) {
414 XtSetArg(wargs
[0], XtNforeground
, &saveptr
->foreground
);
415 XtGetValues(button
, wargs
, 1);
416 XtSetArg(wargs
[0], XtNforeground
, colorlist
[OFFBUTTONCOLOR
].color
.pixel
);
417 XtSetValues(button
, wargs
, 1);
418 XtRemoveAllCallbacks(button
, XtNselect
);
423 /*--------------------------------------------------------------*/
424 /* Generate popup dialog for snap space value input */
425 /*--------------------------------------------------------------*/
427 void getsnapspace(xcWidget button
, caddr_t clientdata
, caddr_t calldata
)
430 buttonsave
*savebutton
;
431 float *floatptr
= &xobjs
.pagelist
[areawin
->page
]->snapspace
;
433 savebutton
= getgeneric(button
, getsnapspace
, (void *)floatptr
);
434 measurestr(*floatptr
, buffer
);
435 popupprompt(button
, "Enter value:", buffer
, setgrid
, savebutton
, NULL
);
438 /*--------------------------------------------------------------*/
439 /* Generate popup dialog for grid space value input */
440 /*--------------------------------------------------------------*/
442 void getgridspace(xcWidget button
, caddr_t clientdata
, caddr_t calldata
)
445 buttonsave
*savebutton
;
446 float *floatptr
= &xobjs
.pagelist
[areawin
->page
]->gridspace
;
448 savebutton
= getgeneric(button
, getgridspace
, (void *)floatptr
);
449 measurestr(*floatptr
, buffer
);
450 popupprompt(button
, "Enter value:", buffer
, setgrid
, savebutton
, NULL
);
453 /*----------------------------------------------------------------*/
454 /* Generic routine for setting a floating-point value (through a */
455 /* (float *) pointer passed as the second parameter) */
456 /*----------------------------------------------------------------*/
458 void setfloat(xcWidget w
, float *dataptr
)
460 float oldvalue
= *dataptr
;
461 int res
= sscanf(_STR2
, "%f", dataptr
);
463 if (res
== 0 || *dataptr
<= 0) {
465 Wprintf("Illegal value");
467 if (oldvalue
!= *dataptr
) drawarea(NULL
, NULL
, NULL
);
470 /*----------------------------------------------------------------*/
471 /* Set text scale. */
472 /*----------------------------------------------------------------*/
474 void settsize(xcWidget w
, labelptr settext
)
478 int res
= sscanf(_STR2
, "%f", &tmpres
);
480 if (res
== 0 || tmpres
<= 0) { /* can't interpret value or bad value */
481 Wprintf("Illegal value");
484 changetextscale(tmpres
);
486 if (areawin
->selects
> 0) unselect_all();
489 /*--------------------------------------------------------------*/
490 /* Auto-set: Enable automatic scaling */
491 /*--------------------------------------------------------------*/
493 void autoset(xcWidget w
, xcWidgetList entertext
, caddr_t nulldata
)
495 xobjs
.pagelist
[areawin
->page
]->pmode
|= 2;
496 updatetext(w
, entertext
, nulldata
);
499 /*--------------------------------------------------------------*/
501 void autostop(xcWidget w
, caddr_t clientdata
, caddr_t nulldata
)
503 xobjs
.pagelist
[areawin
->page
]->pmode
&= 1;
506 /*--------------------------------------------------------------*/
507 /* Set the denomenator value of the drawing scale */
508 /*--------------------------------------------------------------*/
510 void setscaley(xcWidget w
, float *dataptr
)
512 float oldvalue
= *dataptr
;
513 int res
= sscanf(_STR2
, "%f", dataptr
);
515 if (res
== 0 || *dataptr
<= 0 || topobject
->bbox
.height
== 0) {
517 Wprintf("Illegal value");
520 *dataptr
= (*dataptr
* 72) / topobject
->bbox
.height
;
521 *dataptr
/= getpsscale(1.0, areawin
->page
);
525 /*----------------------------------------------------------------*/
526 /* Set the numerator value of the drawing scale */
527 /*----------------------------------------------------------------*/
529 void setscalex(xcWidget w
, float *dataptr
)
531 float oldvalue
= *dataptr
;
532 int res
= sscanf(_STR2
, "%f", dataptr
);
534 if (res
== 0 || *dataptr
<= 0 || topobject
->bbox
.width
== 0) {
536 Wprintf("Illegal value");
539 *dataptr
= (*dataptr
* 72) / topobject
->bbox
.width
;
540 *dataptr
/= getpsscale(1.0, areawin
->page
);
544 /*----------------------------------------------------------------*/
545 /* Set the page orientation (either Landscape or Portrait) */
546 /*----------------------------------------------------------------*/
548 void setorient(xcWidget w
, short *dataptr
)
554 XtSetArg(wargs
[0], XtNlabel
, "Landscape");
558 XtSetArg(wargs
[0], XtNlabel
, "Portrait");
560 XtSetValues(w
, wargs
, 1);
563 /*----------------------------------------------------------------*/
564 /* Set the output mode to "Full Page" (unencapsulated PostScript) */
565 /* or "Embedded" (encapsulated PostScript) */
566 /*----------------------------------------------------------------*/
568 void setpmode(xcWidget w
, short *dataptr
)
571 xcWidget pwidg
= XtParent(w
);
572 xcWidget autowidg
= XtNameToWidget(pwidg
, "Auto-fit");
574 if (!(*dataptr
& 1)) {
576 XtSetArg(wargs
[0], XtNlabel
, "Full Page");
578 XtManageChild(XtNameToWidget(pwidg
, "fpedit"));
579 XtManageChild(XtNameToWidget(pwidg
, "fpokay"));
580 XtManageChild(autowidg
);
583 *dataptr
= 0; /* This also turns off auto-fit */
584 XtSetArg(wargs
[0], XtNset
, False
);
585 XtSetValues(autowidg
, wargs
, 1);
586 XtSetArg(wargs
[0], XtNlabel
, "Embedded");
588 XtUnmanageChild(XtNameToWidget(pwidg
, "fpedit"));
589 XtUnmanageChild(XtNameToWidget(pwidg
, "fpokay"));
590 XtUnmanageChild(autowidg
);
592 XtSetValues(w
, wargs
, 1);
595 /*--------------------------------------------------------------*/
596 /* Set the output page size, in the current unit of measure */
597 /*--------------------------------------------------------------*/
599 void setpagesize(xcWidget w
, XPoint
*dataptr
)
605 is_inches
= setoutputpagesize(dataptr
);
606 sprintf(fpedit
, "%3.2f x %3.2f %s",
607 (float)xobjs
.pagelist
[areawin
->page
]->pagesize
.x
/ 72.0,
608 (float)xobjs
.pagelist
[areawin
->page
]->pagesize
.y
/ 72.0,
609 (is_inches
) ? "in" : "cm");
611 XtSetArg(wargs
[0], XtNstring
, fpedit
);
612 XtSetValues(XtNameToWidget(XtParent(w
), "fpedit"), wargs
, 1);
615 /*--------------------------------------------------------------*/
616 /* Generate popup dialog to get a character kern value, which */
617 /* is two integer numbers in the range -128 to +127 (size char) */
618 /*--------------------------------------------------------------*/
620 void getkern(xcWidget button
, caddr_t nulldata
, caddr_t calldata
)
623 buttonsave
*savebutton
;
625 stringpart
*strptr
, *nextptr
;
627 strcpy(buffer
, "0,0");
629 if (eventmode
== TEXT_MODE
|| eventmode
== ETEXT_MODE
) {
630 labelptr curlabel
= TOLABEL(EDITPART
);
631 strptr
= findstringpart(areawin
->textpos
- 1, NULL
, curlabel
->string
,
632 areawin
->topinstance
);
633 nextptr
= findstringpart(areawin
->textpos
, NULL
, curlabel
->string
,
634 areawin
->topinstance
);
635 if (strptr
->type
== KERN
) {
636 kx
= strptr
->data
.kern
[0];
637 ky
= strptr
->data
.kern
[1];
638 sprintf(buffer
, "%d,%d", kx
, ky
);
640 else if (nextptr
&& nextptr
->type
== KERN
) {
642 kx
= strptr
->data
.kern
[0];
643 ky
= strptr
->data
.kern
[1];
644 sprintf(buffer
, "%d,%d", kx
, ky
);
649 savebutton
= getgeneric(button
, getkern
, strptr
);
650 popupprompt(button
, "Enter Kern X,Y:", buffer
, setkern
, savebutton
, NULL
);
653 /*----------------------------------------------------------------*/
654 /* Generate popup dialog to get the drawing scale, specified as a */
655 /* whole-number ratio X:Y */
656 /*----------------------------------------------------------------*/
658 void getdscale(xcWidget button
, caddr_t nulldata
, caddr_t calldata
)
661 buttonsave
*savebutton
;
662 XPoint
*ptptr
= &(xobjs
.pagelist
[areawin
->page
]->drawingscale
);
664 savebutton
= getgeneric(button
, getdscale
, ptptr
);
665 sprintf(buffer
, "%d:%d", ptptr
->x
, ptptr
->y
);
666 popupprompt(button
, "Enter Scale:", buffer
, setdscale
, savebutton
, NULL
);
669 /*--------------------------------------------------------------*/
670 /* Generate the popup dialog for getting text scale. */
671 /*--------------------------------------------------------------*/
673 void gettsize(xcWidget button
, caddr_t nulldata
, caddr_t calldata
)
676 buttonsave
*savebutton
;
681 settext
= gettextsize(&floatptr
);
682 sprintf(buffer
, "%5.2f", *floatptr
);
685 savebutton
= getgeneric(button
, gettsize
, settext
);
686 popupprompt(button
, "Enter text scale:", buffer
, settsize
, savebutton
, NULL
);
689 savebutton
= getgeneric(button
, gettsize
, floatptr
);
691 "Enter default text scale:", buffer
, setfloat
, savebutton
, NULL
);
695 /*----------------------------------------------------------------*/
696 /* Generate popup dialog for getting object scale */
697 /*----------------------------------------------------------------*/
699 void getosize(xcWidget button
, caddr_t clientdata
, caddr_t calldata
)
703 buttonsave
*savebutton
;
704 short *osel
= areawin
->selectlist
;
706 objinstptr setobj
= NULL
;
708 for (; osel
< areawin
->selectlist
+ areawin
->selects
; osel
++)
709 if (SELECTTYPE(osel
) == OBJINST
) {
710 setobj
= SELTOOBJINST(osel
);
714 if (setobj
== NULL
) {
715 Wprintf("No objects were selected for scaling.");
718 flval
= setobj
->scale
;
719 savebutton
= getgeneric(button
, getosize
, setobj
);
720 sprintf(buffer
, "%4.2f", flval
);
721 popupprompt(button
, "Enter object scale:", buffer
, setosize
, savebutton
, NULL
);
724 /*----------------------------------------------------------------*/
725 /* Generate popup prompt for getting global linewidth */
726 /*----------------------------------------------------------------*/
728 void getwirewidth(xcWidget button
, caddr_t clientdata
, caddr_t calldata
)
731 buttonsave
*savebutton
;
734 widthptr
= &(xobjs
.pagelist
[areawin
->page
]->wirewidth
);
735 savebutton
= getgeneric(button
, getwirewidth
, widthptr
);
736 sprintf(buffer
, "%4.2f", *widthptr
/ 2.0);
737 popupprompt(button
, "Enter new global linewidth:", buffer
, setwidth
,
741 /*----------------------------------------------------------------*/
742 /* Generate popup dialong for getting linewidths of elements */
743 /*----------------------------------------------------------------*/
745 void getwwidth(xcWidget button
, caddr_t clientdata
, caddr_t calldata
)
748 buttonsave
*savebutton
;
749 short *osel
= areawin
->selectlist
;
753 for (; osel
< areawin
->selectlist
+ areawin
->selects
; osel
++) {
754 setel
= *(topobject
->plist
+ (*osel
));
756 flval
= ((arcptr
)setel
)->width
;
759 else if (IS_POLYGON(setel
)) {
760 flval
= ((polyptr
)setel
)->width
;
763 else if (IS_SPLINE(setel
)) {
764 flval
= ((splineptr
)setel
)->width
;
767 else if (IS_PATH(setel
)) {
768 flval
= ((pathptr
)setel
)->width
;
772 savebutton
= getgeneric(button
, getwwidth
, setel
);
773 if (osel
== areawin
->selectlist
+ areawin
->selects
) {
774 sprintf(buffer
, "%4.2f", areawin
->linewidth
);
775 popupprompt(button
, "Enter new default line width:", buffer
, setwwidth
,
779 sprintf(buffer
, "%4.2f", flval
);
780 popupprompt(button
, "Enter new line width:", buffer
, setwwidth
,
785 /*----------------------------------------------------------------*/
786 /* Generic popup prompt for getting a floating-point value */
787 /*----------------------------------------------------------------*/
789 void getfloat(xcWidget button
, float *floatptr
, caddr_t calldata
)
792 buttonsave
*savebutton
;
794 savebutton
= getgeneric(button
, getfloat
, floatptr
);
795 sprintf(buffer
, "%4.2f", *floatptr
);
796 popupprompt(button
, "Enter value:", buffer
, setfloat
, savebutton
, NULL
);
799 /*----------------------------------------------------------------*/
800 /* Set the filename for the current page */
801 /*----------------------------------------------------------------*/
803 void setfilename(xcWidget w
, char **dataptr
)
805 short cpage
, depend
= 0;
807 char *oldstr
= xobjs
.pagelist
[areawin
->page
]->filename
;
809 if ((*dataptr
!= NULL
) && !strcmp(*dataptr
, _STR2
))
810 return; /* no change in string */
812 /* Make the change to the current page */
813 xobjs
.pagelist
[areawin
->page
]->filename
= strdup(_STR2
);
815 /* All existing filenames which match the old string should also be changed */
816 for (cpage
= 0; cpage
< xobjs
.pages
; cpage
++) {
817 if ((xobjs
.pagelist
[cpage
]->pageinst
!= NULL
) && (cpage
!= areawin
->page
)) {
818 if ((oldstr
!= NULL
) && (!strcmp(xobjs
.pagelist
[cpage
]->filename
, oldstr
))) {
819 free(xobjs
.pagelist
[cpage
]->filename
);
820 xobjs
.pagelist
[cpage
]->filename
= strdup(_STR2
);
827 /*----------------------------------------------------------------*/
828 /* Set the page label for the current page */
829 /*----------------------------------------------------------------*/
831 void setpagelabel(xcWidget w
, char *dataptr
)
835 /* Whitespace and non-printing characters not allowed */
837 for (i
= 0; i
< strlen(_STR2
); i
++) {
838 if ((!isprint(_STR2
[i
])) || (isspace(_STR2
[i
]))) {
840 Wprintf("Replaced illegal whitespace in name with underscore");
844 if (!strcmp(dataptr
, _STR2
)) return; /* no change in string */
845 if (strlen(_STR2
) == 0)
846 sprintf(topobject
->name
, "Page %d", areawin
->page
+ 1);
848 sprintf(topobject
->name
, "%.79s", _STR2
);
850 /* For schematics, all pages with associations to symbols must have */
852 if (topobject
->symschem
!= NULL
) checkpagename(topobject
);
854 printname(topobject
);
855 renamepage(areawin
->page
);
858 /*--------------------------------------------------------------*/
859 /* Change the Button1 binding for a particular mode (non-Tcl) */
860 /*--------------------------------------------------------------*/
862 /*--------------------------------------------------------------*/
863 /* Change to indicated tool (key binding w/o value) */
864 /*--------------------------------------------------------------*/
866 void changetool(xcWidget w
, pointertype value
, caddr_t nulldata
)
868 mode_rebinding((int)value
, (short)-1);
869 highlightexcl(w
, (int)value
, (int)-1);
872 /*--------------------------------------------------------------*/
873 /* Execute function binding for the indicated tool if something */
874 /* is selected; otherwise, change to the indicated tool mode. */
875 /*--------------------------------------------------------------*/
877 void exec_or_changetool(xcWidget w
, pointertype value
, caddr_t nulldata
)
879 if (areawin
->selects
> 0)
880 mode_tempbinding((int)value
, -1);
882 mode_rebinding((int)value
, -1);
883 highlightexcl(w
, (int)value
, -1);
887 /*--------------------------------------------------------------*/
888 /* Special case of exec_or_changetool(), where an extra value */
889 /* is passed to the routine indication amount of rotation, or */
890 /* type of flip operation. */
891 /*--------------------------------------------------------------*/
893 void rotatetool(xcWidget w
, pointertype value
, caddr_t nulldata
)
895 if (areawin
->selects
> 0)
896 mode_tempbinding(XCF_Rotate
, (int)value
);
898 mode_rebinding(XCF_Rotate
, (int)value
);
899 highlightexcl(w
, (int)XCF_Rotate
, (int)value
);
903 /*--------------------------------------------------------------*/
904 /* Special case of changetool() for pan mode, where a value is */
905 /* required to pass to the key binding routine. */
906 /*--------------------------------------------------------------*/
908 void pantool(xcWidget w
, pointertype value
, caddr_t nulldata
)
910 mode_rebinding(XCF_Pan
, (int)value
);
911 highlightexcl(w
, (int)XCF_Pan
, (int)value
);
914 /*--------------------------------------------------------------*/
915 /* Add a new font name to the list of known fonts */
916 /* Register the font number for the Alt-F cycling mechanism */
917 /* Tcl: depends on command tag mechanism for GUI menu update. */
918 /*--------------------------------------------------------------*/
920 void makenewfontbutton()
925 xcWidget newbutton
, cascade
;
927 if (fontcount
== 0) return;
929 cascade
= XtParent(FontAddNewFontButton
);
930 XtnSetArg(XtNfont
, appdata
.xcfont
);
931 newbutton
= XtCreateWidget(fonts
[fontcount
- 1].family
, XwmenubuttonWidgetClass
,
934 XtAddCallback (newbutton
, XtNselect
, (XtCallbackProc
)setfont
,
935 Number(fontcount
- 1));
936 XtManageChild(newbutton
);
939 if (nfontnumbers
== 1)
940 fontnumbers
= (u_short
*)malloc(sizeof(u_short
));
942 fontnumbers
= (u_short
*)realloc(fontnumbers
, nfontnumbers
944 fontnumbers
[nfontnumbers
- 1] = fontcount
- 1;
947 /*--------------------------------------------------------------*/
948 /* Make new encoding menu button */
949 /*--------------------------------------------------------------*/
951 void makenewencodingbutton(char *ename
, char value
)
955 xcWidget newbutton
, cascade
;
957 cascade
= XtParent(EncodingStandardButton
);
959 /* return if button has already been made */
960 newbutton
= XtNameToWidget(cascade
, ename
);
961 if (newbutton
!= NULL
) return;
963 XtnSetArg(XtNfont
, appdata
.xcfont
);
964 newbutton
= XtCreateWidget(ename
, XwmenubuttonWidgetClass
,
967 XtAddCallback (newbutton
, XtNselect
, (XtCallbackProc
)setfontencoding
,
969 XtManageChild(newbutton
);
972 /*--------------------------------------------------------------*/
973 /* Set the menu checkmarks on the font menu */
974 /*--------------------------------------------------------------*/
976 void togglefontmark(int fontval
)
979 xcWidget widget
, cascade
, sibling
;
982 cascade
= XtParent(FontAddNewFontButton
);
983 widget
= XtNameToWidget(cascade
, fonts
[fontval
].family
);
985 /* Remove checkmark from all widgets in the list */
987 XtSetArg(args
[0], XtNsetMark
, False
);
988 for (i
= 0; i
< fontcount
; i
++) {
990 sibling
= XtNameToWidget(cascade
, fonts
[i
].family
);
991 XtSetValues(sibling
, args
, 1);
995 /* Add checkmark to designated font */
997 XtSetArg(args
[0], XtNsetMark
, True
);
998 XtSetValues(widget
, args
, 1);
1001 /*--------------------------------------------------------------------*/
1002 /* Toggle one of a set of menu items, only one of which can be active */
1003 /*--------------------------------------------------------------------*/
1005 void toggleexcl(xcWidget widget
, menuptr menu
, int menulength
)
1008 xcWidget parent
= xcParent(widget
);
1010 menuptr mitem
, mtest
;
1013 /* find the menu item which corresponds to the widget which was pushed */
1015 for (mtest
= menu
; mtest
< menu
+ menulength
; mtest
++) {
1016 sibling
= XtNameToWidget(parent
, mtest
->name
);
1017 if (sibling
== widget
) break;
1020 /* remove checkmark from other widgets in the list */
1022 XtSetArg(args
[0], XtNsetMark
, False
);
1023 if (menu
== Fonts
) { /* special action for font list */
1024 for (i
= 0; i
< fontcount
; i
++) {
1025 sibling
= XtNameToWidget(parent
, fonts
[i
].family
);
1026 if (sibling
!= widget
)
1027 XtSetValues(sibling
, args
, 1);
1029 mtest
= &Fonts
[3]; /* so that mtest->func has correct value below */
1031 else if (mtest
== menu
+ menulength
) return; /* something went wrong? */
1033 for (mitem
= menu
; mitem
< menu
+ menulength
; mitem
++) {
1034 sibling
= XtNameToWidget(parent
, mitem
->name
);
1035 if (mitem
->func
== mtest
->func
)
1036 XtSetValues(sibling
, args
, 1);
1039 /* Now set the currently pushed widget */
1041 XtSetArg(args
[0], XtNsetMark
, True
);
1042 XtSetValues(widget
, args
, 1);
1045 /*----------------------------------------------------------------------*/
1046 /* Cursor changes based on toolbar mode */
1047 /*----------------------------------------------------------------------*/
1049 void toolcursor(int mode
)
1051 /* Some cursor types for different modes */
1057 XDefineCursor (dpy
, areawin
->window
, ARROW
);
1058 areawin
->defaultcursor
= &ARROW
;
1061 XDefineCursor (dpy
, areawin
->window
, HAND
);
1062 areawin
->defaultcursor
= &HAND
;
1065 XDefineCursor (dpy
, areawin
->window
, SCISSORS
);
1066 areawin
->defaultcursor
= &SCISSORS
;
1069 XDefineCursor (dpy
, areawin
->window
, COPYCURSOR
);
1070 areawin
->defaultcursor
= ©CURSOR
;
1073 case XCF_Select_Save
:
1074 XDefineCursor (dpy
, areawin
->window
, QUESTION
);
1075 areawin
->defaultcursor
= &QUESTION
;
1080 XDefineCursor (dpy
, areawin
->window
, ROTATECURSOR
);
1081 areawin
->defaultcursor
= &ROTATECURSOR
;
1084 XDefineCursor (dpy
, areawin
->window
, EDCURSOR
);
1085 areawin
->defaultcursor
= &EDCURSOR
;
1088 XDefineCursor (dpy
, areawin
->window
, CIRCLE
);
1089 areawin
->defaultcursor
= &CIRCLE
;
1093 case XCF_Pin_Global
:
1094 case XCF_Info_Label
:
1095 XDefineCursor (dpy
, areawin
->window
, TEXTPTR
);
1096 areawin
->defaultcursor
= &TEXTPTR
;
1099 XDefineCursor (dpy
, areawin
->window
, CROSS
);
1100 areawin
->defaultcursor
= &CROSS
;
1105 /*--------------------------------------------------------------------------*/
1106 /* Highlight one of a set of toolbar items, only one of which can be active */
1107 /*--------------------------------------------------------------------------*/
1109 void highlightexcl(xcWidget widget
, int func
, int value
)
1113 xcWidget parent
= xcParent(PanToolButton
);
1114 xcWidget sibling
, self
= (xcWidget
)NULL
;
1115 toolbarptr titem
, ttest
;
1117 /* remove highlight from all widgets in the toolbar */
1119 XtSetArg(args
[0], XtNbackground
, colorlist
[BACKGROUND
].color
.pixel
);
1120 XtSetArg(args
[1], XtNborderColor
, colorlist
[SNAPCOLOR
].color
.pixel
);
1121 for (titem
= ToolBar
; titem
< ToolBar
+ toolbuttons
; titem
++) {
1122 sibling
= XtNameToWidget(parent
, titem
->name
);
1123 if (sibling
== widget
)
1126 XtSetValues(sibling
, args
, 2);
1129 if (self
== (xcWidget
)NULL
) {
1130 /* We invoked a toolbar button from somewhere else. Highlight */
1131 /* the toolbar associated with the function value. */
1134 self
= PanToolButton
;
1139 self
= RotPToolButton
;
1141 self
= RotNToolButton
;
1145 for (titem
= ToolBar
; titem
< ToolBar
+ toolbuttons
; titem
++) {
1146 if (func
== (pointertype
)(titem
->passeddata
)) {
1147 self
= XtNameToWidget(parent
, titem
->name
);
1155 /* Now highlight the currently pushed widget */
1157 if (self
!= (xcWidget
)NULL
) {
1158 XtSetArg(args
[0], XtNbackground
, colorlist
[RATSNESTCOLOR
].color
.pixel
);
1159 XtSetArg(args
[1], XtNborderColor
, colorlist
[RATSNESTCOLOR
].color
.pixel
);
1160 XtSetValues(self
, args
, 2);
1162 #endif /* HAVE_XPM */
1165 /*--------------------*/
1166 /* Toggle a menu item */
1167 /*--------------------*/
1169 void toggle(xcWidget w
, pointertype soffset
, Boolean
*setdata
)
1175 boolvalue
= setdata
;
1177 boolvalue
= (Boolean
*)(areawin
+ soffset
);
1179 *boolvalue
= !(*boolvalue
);
1180 XtSetArg(wargs
[0], XtNsetMark
, *boolvalue
);
1181 XtSetValues(w
, wargs
, 1);
1182 drawarea(w
, NULL
, NULL
);
1185 /*----------------------------------------------------------------*/
1186 /* Invert the color scheme used for the background/foreground */
1187 /*----------------------------------------------------------------*/
1189 void inversecolor(xcWidget w
, pointertype soffset
, caddr_t calldata
)
1191 Boolean
*boolvalue
= (Boolean
*)(areawin
+ soffset
);
1193 /* change color scheme */
1195 setcolorscheme(*boolvalue
);
1197 /* toggle checkmark in menu on "Alt colors" */
1199 if (w
== NULL
) w
= OptionsAltColorsButton
;
1200 if (w
!= NULL
) toggle(w
, soffset
, calldata
);
1201 if (eventmode
== NORMAL_MODE
)
1202 XDefineCursor (dpy
, areawin
->window
, DEFAULTCURSOR
);
1205 /*----------------------------------------------------------------*/
1206 /* Change menu selection for reported measurement units */
1207 /*----------------------------------------------------------------*/
1209 void togglegrid(u_short type
)
1211 xcWidget button
, bparent
= XtParent(GridtypedisplayDecimalInchesButton
);
1213 if (type
== CM
) button
= XtNameToWidget(bparent
, "Centimeters");
1214 else if (type
== FRAC_INCH
) button
= XtNameToWidget(bparent
, "Fractional Inches");
1215 else if (type
== DEC_INCH
) button
= XtNameToWidget(bparent
, "Decimal Inches");
1216 else if (type
== INTERNAL
) button
= XtNameToWidget(bparent
, "Internal Units");
1217 else button
= XtNameToWidget(bparent
, "Coordinates");
1219 toggleexcl(button
, GridStyles
, XtNumber(GridStyles
));
1224 /*----------------------------------------------------------------*/
1225 /* Set the default reported grid units to inches or centimeters */
1226 /*----------------------------------------------------------------*/
1228 void setgridtype(char *string
)
1230 xcWidget button
, bparent
= XtParent(GridtypedisplayDecimalInchesButton
);
1232 if (!strcmp(string
, "inchscale")) {
1233 button
= XtNameToWidget(bparent
, "Fractional Inches");
1234 getgridtype(button
, FRAC_INCH
, NULL
);
1236 else if (!strcmp(string
, "cmscale")) {
1237 button
= XtNameToWidget(bparent
, "Centimeters");
1238 getgridtype(button
, CM
, NULL
);
1242 /*----------------------------------------------*/
1243 /* Make new library and add a new button to the */
1244 /* "Libraries" cascaded menu. */
1245 /*----------------------------------------------*/
1247 int createlibrary(Boolean force
)
1249 xcWidget libmenu
, newbutton
, oldbutton
;
1253 objectptr newlibobj
;
1255 /* If there's an empty library, return its number */
1256 if ((!force
) && (libnum
= findemptylib()) >= 0) return (libnum
+ LIBRARY
);
1257 libnum
= (xobjs
.numlibs
++) + LIBRARY
;
1258 xobjs
.libtop
= (objinstptr
*)realloc(xobjs
.libtop
,
1259 (libnum
+ 1) * sizeof(objinstptr
));
1260 xobjs
.libtop
[libnum
] = xobjs
.libtop
[libnum
- 1];
1263 newlibobj
= (objectptr
) malloc(sizeof(object
));
1265 xobjs
.libtop
[libnum
] = newpageinst(newlibobj
);
1267 sprintf(newlibobj
->name
, "Library %d", libnum
- LIBRARY
+ 1);
1269 /* Create the library */
1271 xobjs
.userlibs
= (Library
*) realloc(xobjs
.userlibs
, xobjs
.numlibs
1273 xobjs
.userlibs
[libnum
+ 1 - LIBRARY
] = xobjs
.userlibs
[libnum
- LIBRARY
];
1274 xobjs
.userlibs
[libnum
- LIBRARY
].library
= (objectptr
*) malloc(sizeof(objectptr
));
1275 xobjs
.userlibs
[libnum
- LIBRARY
].number
= 0;
1276 xobjs
.userlibs
[libnum
- LIBRARY
].instlist
= NULL
;
1278 /* To-do: initialize technology list */
1280 xobjs.userlibs[libnum - LIBRARY].filename = NULL;
1281 xobjs.userlibs[libnum - LIBRARY].flags = (char)0;
1284 /* Previously last button becomes new library pointer */
1286 oldbutton
= GotoLibraryLibrary2Button
;
1287 XtRemoveAllCallbacks (oldbutton
, XtNselect
);
1288 XtAddCallback (oldbutton
, XtNselect
, (XtCallbackProc
)startcatalog
,
1290 XtSetArg(wargs
[0], XtNlabel
, xobjs
.libtop
[libnum
]->thisobject
->name
);
1291 XtSetValues(oldbutton
, wargs
, 1);
1293 /* Make new entry in the menu to replace the User Library button */
1294 /* xcWidget name is unique so button can be found later. Label is */
1295 /* always set to "User Library" */
1297 sprintf(libstring
, "Library %d", libnum
- LIBRARY
+ 2);
1298 libmenu
= XtParent(GotoLibraryAddNewLibraryButton
);
1299 XtSetArg(wargs
[0], XtNfont
, appdata
.xcfont
);
1300 XtSetArg(wargs
[1], XtNlabel
, "User Library");
1301 newbutton
= XtCreateWidget(libstring
, XwmenubuttonWidgetClass
,
1303 XtAddCallback (newbutton
, XtNselect
, (XtCallbackProc
)startcatalog
,
1304 Number(libnum
+ 1));
1305 XtManageChild(newbutton
);
1306 GotoLibraryLibrary2Button
= newbutton
;
1308 /* Update the library directory to include the new page */
1315 /*--------------------------------------------------------------*/
1316 /* Routine called by newpage() if new button needs to be made */
1317 /* to add to the "Pages" cascaded menu. */
1318 /*--------------------------------------------------------------*/
1320 void makepagebutton()
1322 xcWidget pagemenu
, newbutton
;
1324 char pagestring
[10];
1326 /* make new entry in the menu */
1328 pagemenu
= XtParent(GotoPageAddNewPageButton
);
1329 XtSetArg(wargs
[0], XtNfont
, appdata
.xcfont
);
1330 sprintf(pagestring
, "Page %d", xobjs
.pages
);
1331 newbutton
= XtCreateWidget(pagestring
, XwmenubuttonWidgetClass
,
1332 pagemenu
, wargs
, 1);
1333 XtAddCallback (newbutton
, XtNselect
, (XtCallbackProc
)newpagemenu
,
1334 Number(xobjs
.pages
- 1));
1335 XtManageChild(newbutton
);
1337 /* Update the page directory */
1339 composelib(PAGELIB
);
1342 /*----------------------------------------------------------------*/
1343 /* Find the Page menu button associated with the page number */
1344 /* (passed parameter) and set the label of that button to the */
1345 /* object name (= page label) */
1346 /*----------------------------------------------------------------*/
1348 void renamepage(short pagenumber
)
1351 objinstptr thisinst
= xobjs
.pagelist
[pagenumber
]->pageinst
;
1353 xcWidget parent
= XtParent(GotoPageAddNewPageButton
);
1357 sprintf(bname
, "Page %d", pagenumber
+ 1);
1358 button
= XtNameToWidget(parent
, bname
);
1360 if ((button
!= NULL
) && (thisinst
!= NULL
)) {
1361 if (thisinst
->thisobject
->name
!= NULL
)
1362 XtSetArg(wargs
[0], XtNlabel
,
1363 thisinst
->thisobject
->name
);
1365 XtSetArg(wargs
[0], XtNlabel
, bname
);
1366 XtSetValues(button
, wargs
, 1);
1368 else if (button
== NULL
)
1369 Fprintf(stderr
, "Error: No Button Widget named \"%9s\"\n", bname
);
1372 /*--------------------------------------------------------------*/
1373 /* Same routine as above, for Library page menu buttons */
1374 /*--------------------------------------------------------------*/
1376 void renamelib(short libnumber
)
1379 xcWidget parent
= XtParent(GotoLibraryAddNewLibraryButton
);
1383 sprintf(bname
, "Library %d", libnumber
- LIBRARY
+ 1);
1384 button
= XtNameToWidget(parent
, bname
);
1386 if (button
!= NULL
) {
1387 if (xobjs
.libtop
[libnumber
]->thisobject
->name
!= NULL
)
1388 XtSetArg(wargs
[0], XtNlabel
, xobjs
.libtop
[libnumber
]->thisobject
->name
);
1390 XtSetArg(wargs
[0], XtNlabel
, bname
);
1391 XtSetValues(button
, wargs
, 1);
1394 Fprintf(stderr
, "Error: No Button Widget named \"%12s\"\n", bname
);
1397 /*--------------------------------------------------------------*/
1398 /* Set the menu checkmarks on the color menu */
1399 /*--------------------------------------------------------------*/
1401 void setcolormark(int colorval
)
1407 if (colorval
== DEFAULTCOLOR
)
1408 w
= ColorInheritColorButton
;
1410 w
= colorlist
[colorval
].cbutton
;
1412 /* Remove mark from all menu items */
1414 XtSetArg(args
[0], XtNsetMark
, False
);
1415 for (i
= NUMBER_OF_COLORS
; i
< number_colors
; i
++)
1416 XtSetValues(colorlist
[i
].cbutton
, args
, 1);
1417 XtSetValues(ColorInheritColorButton
, args
, 1);
1419 /* Add mark to the menu button for the chosen color */
1421 if (w
!= (xcWidget
)NULL
) {
1423 XtSetArg(args
[0], XtNsetMark
, True
);
1424 XtSetValues(w
, args
, 1);
1428 /*----------------------------------------------------------------*/
1429 /* Set the checkmarks on the element styles menu */
1430 /*----------------------------------------------------------------*/
1432 void setallstylemarks(u_short styleval
)
1437 XtSetArg(wargs
[0], XtNsetMark
, (styleval
& UNCLOSED
) ? 0 : 1);
1438 XtSetValues(BorderClosedButton
, wargs
, 1);
1440 XtSetArg(wargs
[0], XtNsetMark
, (styleval
& BBOX
) ? 1 : 0);
1441 XtSetValues(BorderBoundingBoxButton
, wargs
, 1);
1443 if (styleval
& NOBORDER
)
1444 w
= BorderUnborderedButton
;
1445 else if (styleval
& DASHED
)
1446 w
= BorderDashedButton
;
1447 else if (styleval
& DOTTED
)
1448 w
= BorderDottedButton
;
1450 w
= BorderSolidButton
;
1451 toggleexcl(w
, BorderStyles
, XtNumber(BorderStyles
));
1453 if (styleval
& OPAQUE
)
1454 w
= FillOpaqueButton
;
1456 w
= FillTransparentButton
;
1457 toggleexcl(w
, Stipples
, XtNumber(Stipples
));
1459 if (!(styleval
& FILLED
))
1460 w
= FillWhiteButton
;
1462 styleval
&= FILLSOLID
;
1465 case 0: w
= FillGray87Button
; break;
1466 case 1: w
= FillGray75Button
; break;
1467 case 2: w
= FillGray62Button
; break;
1468 case 3: w
= FillGray50Button
; break;
1469 case 4: w
= FillGray37Button
; break;
1470 case 5: w
= FillGray25Button
; break;
1471 case 6: w
= FillGray12Button
; break;
1472 case 7: w
= FillBlackButton
; break;
1475 toggleexcl(w
, Stipples
, XtNumber(Stipples
));
1478 /*--------------------------------------------------------------*/
1479 /* The following five routines are all wrappers for */
1480 /* setelementstyle(), */
1481 /* used in menudefs to differentiate between sections, each of */
1482 /* which has settings independent of the others. */
1483 /*--------------------------------------------------------------*/
1485 void setfill(xcWidget w
, pointertype value
, caddr_t calldata
)
1487 setelementstyle(w
, (u_short
)value
, OPAQUE
| FILLED
| FILLSOLID
);
1490 /*--------------------------------------------------------------*/
1492 void makebbox(xcWidget w
, pointertype value
, caddr_t calldata
)
1494 setelementstyle(w
, (u_short
)value
, BBOX
);
1497 /*--------------------------------------------------------------*/
1499 void setclosure(xcWidget w
, pointertype value
, caddr_t calldata
)
1501 setelementstyle(w
, (u_short
)value
, UNCLOSED
);
1504 /*----------------------------------------------------------------*/
1506 void setopaque(xcWidget w
, pointertype value
, caddr_t calldata
)
1508 setelementstyle(w
, (u_short
)value
, OPAQUE
);
1511 /*----------------------------------------------------------------*/
1513 void setline(xcWidget w
, pointertype value
, caddr_t calldata
)
1515 setelementstyle(w
, (u_short
)value
, BORDERS
);
1518 /*-----------------------------------------------*/
1519 /* Set the color value for all selected elements */
1520 /*-----------------------------------------------*/
1522 void setcolor(xcWidget w
, pointertype value
, caddr_t calldata
)
1525 int *ecolor
, cindex
, cval
;
1527 Boolean selected
= False
;
1528 stringpart
*strptr
, *nextptr
;
1530 /* Get the color index value from the menu button widget itself */
1535 XtSetArg(wargs
[0], XtNrectColor
, &cval
);
1536 XtGetValues(w
, wargs
, 1);
1538 for (cindex
= NUMBER_OF_COLORS
; cindex
< number_colors
; cindex
++)
1539 if (colorlist
[cindex
].color
.pixel
== cval
)
1541 if (cindex
>= number_colors
) {
1542 Wprintf("Error: No such color!");
1547 if (eventmode
== TEXT_MODE
|| eventmode
== ETEXT_MODE
) {
1548 labelptr curlabel
= TOLABEL(EDITPART
);
1549 strptr
= findstringpart(areawin
->textpos
- 1, NULL
, curlabel
->string
,
1550 areawin
->topinstance
);
1551 nextptr
= findstringpart(areawin
->textpos
, NULL
, curlabel
->string
,
1552 areawin
->topinstance
);
1553 if (strptr
->type
== FONT_COLOR
) {
1554 undrawtext(curlabel
);
1555 strptr
->data
.color
= cindex
;
1556 redrawtext(curlabel
);
1558 else if (nextptr
&& nextptr
->type
== FONT_COLOR
) {
1559 undrawtext(curlabel
);
1560 nextptr
->data
.color
= cindex
;
1561 redrawtext(curlabel
);
1564 sprintf(_STR2
, "%d", cindex
);
1565 labeltext(FONT_COLOR
, (char *)&cindex
);
1569 else if (areawin
->selects
> 0) {
1570 for (scolor
= areawin
->selectlist
; scolor
< areawin
->selectlist
1571 + areawin
->selects
; scolor
++) {
1572 ecolor
= &(SELTOCOLOR(scolor
));
1579 setcolormark(cindex
);
1581 if (eventmode
!= TEXT_MODE
&& eventmode
!= ETEXT_MODE
)
1582 areawin
->color
= cindex
;
1587 /*----------------------------------------------------------------*/
1588 /* Parse a new color entry and add it to the color list. */
1589 /*----------------------------------------------------------------*/
1591 void setnewcolor(xcWidget w
, caddr_t
nullptr)
1593 int ccolor
, red
, green
, blue
;
1596 ppos
= strchr(_STR2
, '#');
1597 cpos
= strchr(_STR2
, ',');
1599 if (cpos
!= NULL
|| ppos
!= NULL
) {
1600 if (cpos
!= NULL
|| strlen(ppos
+ 1) == 6) {
1602 sscanf(_STR2
, "%d, %d, %d", &red
, &green
, &blue
);
1604 sscanf(ppos
+ 1, "%2x%2x%2x", &red
, &green
, &blue
);
1609 else if (sscanf(ppos
+ 1, "%4x%4x%4x", &red
, &green
, &blue
) != 3) {
1610 Wprintf("Bad color entry. Use #rrggbb");
1613 ccolor
= rgb_alloccolor(red
, green
, blue
);
1616 ccolor
= xc_alloccolor(_STR2
);
1617 addnewcolorentry(ccolor
);
1621 /*----------------------------------------------------------------*/
1622 /* Generate popup dialog for adding a new color name or RGB value */
1623 /*----------------------------------------------------------------*/
1625 void addnewcolor(xcWidget w
, caddr_t clientdata
, caddr_t calldata
)
1627 buttonsave
*savebutton
;
1629 savebutton
= getgeneric(w
, addnewcolor
, NULL
);
1630 popupprompt(w
, "Enter color name or #rgb or r,g,b:", "\0", setnewcolor
,
1634 /*------------------------------------------------------*/
1636 void setfontmarks(short fvalue
, short jvalue
)
1641 if ((fvalue
>= 0) && (fontcount
> 0)) {
1642 switch(fonts
[fvalue
].flags
& 0x03) {
1643 case 0: w
= StyleNormalButton
; break;
1644 case 1: w
= StyleBoldButton
; break;
1645 case 2: w
= StyleItalicButton
; break;
1646 case 3: w
= StyleBoldItalicButton
; break;
1648 toggleexcl(w
, FontStyles
, XtNumber(FontStyles
));
1650 switch((fonts
[fvalue
].flags
& 0xf80) >> 7) {
1651 case 0: w
= EncodingStandardButton
; break;
1652 case 2: w
= EncodingISOLatin1Button
; break;
1655 if (w
!= NULL
) toggleexcl(w
, FontEncodings
, XtNumber(FontEncodings
));
1657 togglefontmark(fvalue
);
1660 switch(jvalue
& (RLANCHORFIELD
)) {
1661 case NORMAL
: w
= AnchoringLeftAnchoredButton
; break;
1662 case NOTLEFT
: w
= AnchoringCenterAnchoredButton
; break;
1663 case RIGHT
|NOTLEFT
: w
= AnchoringRightAnchoredButton
; break;
1665 toggleexcl(w
, Anchors
, XtNumber(Anchors
));
1667 switch(jvalue
& (TBANCHORFIELD
)) {
1668 case NORMAL
: w
= AnchoringBottomAnchoredButton
; break;
1669 case NOTBOTTOM
: w
= AnchoringMiddleAnchoredButton
; break;
1670 case TOP
|NOTBOTTOM
: w
= AnchoringTopAnchoredButton
; break;
1673 toggleexcl(w
, Anchors
, XtNumber(Anchors
));
1675 /* Flip Invariance property */
1676 w
= AnchoringFlipInvariantButton
;
1677 if (jvalue
& FLIPINV
)
1678 XtSetArg(wargs
[0], XtNsetMark
, True
);
1680 XtSetArg(wargs
[0], XtNsetMark
, False
);
1681 XtSetValues(w
, wargs
, 1);
1683 /* Pin visibility property */
1684 w
= NetlistPinVisibilityButton
;
1685 if (jvalue
& PINVISIBLE
)
1686 XtSetArg(wargs
[0], XtNsetMark
, True
);
1688 XtSetArg(wargs
[0], XtNsetMark
, False
);
1689 XtSetValues(w
, wargs
, 1);
1693 /*----------------------------------------------*/
1694 /* GUI wrapper for startparam() */
1695 /*----------------------------------------------*/
1697 void promptparam(xcWidget w
, caddr_t clientdata
, caddr_t calldata
)
1699 buttonsave
*popdata
= (buttonsave
*)malloc(sizeof(buttonsave
));
1701 if (areawin
->selects
== 0) return; /* nothing was selected */
1703 /* Get a name for the new object */
1705 eventmode
= NORMAL_MODE
;
1706 popdata
->dataptr
= NULL
;
1707 popdata
->button
= NULL
; /* indicates that no button is assc'd w/ the popup */
1708 popupprompt(w
, "Enter name for new parameter:", "\0", stringparam
, popdata
, NULL
);
1711 /*---------------------------*/
1712 /* Set polygon editing style */
1713 /*---------------------------*/
1715 void boxedit(xcWidget w
, pointertype value
, caddr_t nulldata
)
1719 case MANHATTAN
: w
= PolygonEditManhattanBoxEditButton
; break;
1720 case RHOMBOIDX
: w
= PolygonEditRhomboidXButton
; break;
1721 case RHOMBOIDY
: w
= PolygonEditRhomboidYButton
; break;
1722 case RHOMBOIDA
: w
= PolygonEditRhomboidAButton
; break;
1723 case NORMAL
: w
= PolygonEditNormalButton
; break;
1727 if (areawin
->boxedit
== value
) return;
1729 toggleexcl(w
, BoxEditStyles
, XtNumber(BoxEditStyles
));
1730 areawin
->boxedit
= value
;
1733 /*----------------------------------------------------*/
1734 /* Generate popup dialog for entering a new font name */
1735 /*----------------------------------------------------*/
1737 void addnewfont(xcWidget w
, caddr_t clientdata
, caddr_t calldata
)
1739 buttonsave
*savebutton
;
1740 char *tempstr
= malloc(2 * sizeof(char));
1742 savebutton
= getgeneric(w
, addnewfont
, tempstr
);
1743 popupprompt(w
, "Enter font name:", tempstr
, locloadfont
, savebutton
, NULL
);
1746 /*-------------------------------------------------*/
1747 /* Wrapper for labeltext when called from the menu */
1748 /*-------------------------------------------------*/
1750 void addtotext(xcWidget w
, pointertype value
, caddr_t nulldata
)
1752 if (eventmode
!= TEXT_MODE
&& eventmode
!= ETEXT_MODE
) return;
1753 if (value
== (pointertype
)SPECIAL
)
1756 labeltext((int)value
, (char *)1);
1759 /*----------------------------------------------------------*/
1760 /* Position a popup menu directly beside the toolbar button */
1761 /*----------------------------------------------------------*/
1763 void position_popup(xcWidget toolbutton
, xcWidget menubutton
)
1767 Position pz
, pw
, ph
;
1770 xcWidget cascade
= XtParent(menubutton
);
1771 xcWidget pshell
= XtParent(XtParent(cascade
));
1773 XtnSetArg(XtNheight
, &pz
);
1774 XtGetValues(toolbutton
, wargs
, n
); n
= 0;
1776 XtnSetArg(XtNwidth
, &pw
);
1777 XtnSetArg(XtNheight
, &ph
);
1778 XtGetValues(cascade
, wargs
, n
); n
= 0;
1781 dy
= (pz
- ph
) >> 1;
1783 XwPostPopup(pshell
, cascade
, toolbutton
, dx
, dy
);
1786 /*------------------------------------------------------*/
1787 /* Functions which pop up a menu cascade in sticky mode */
1788 /*------------------------------------------------------*/
1790 void border_popup(xcWidget w
, caddr_t clientdata
, caddr_t calldata
)
1792 position_popup(w
, BorderLinewidthButton
);
1795 /*-------------------------------------------------------------------------*/
1797 void color_popup(xcWidget w
, caddr_t clientdata
, caddr_t calldata
)
1799 position_popup(w
, ColorAddNewColorButton
);
1802 /*-------------------------------------------------------------------------*/
1804 void fill_popup(xcWidget w
, caddr_t clientdata
, caddr_t calldata
)
1806 position_popup(w
, FillOpaqueButton
);
1809 /*-------------------------------------------------------------------------*/
1811 void param_popup(xcWidget w
, caddr_t clientdata
, caddr_t calldata
)
1813 position_popup(w
, ParametersSubstringButton
);
1816 /*-------------------------------------------------------------------------*/
1818 #endif /* TCL_WRAPPER */