Corrected a long-standing error in which ending text with a literal
[xcircuit.git] / xtfuncs.c
bloba3e8b1f66dd1da49535e27a98b984b77abe3911f
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 /*----------------------------------------------------------------------*/
7 #ifndef TCL_WRAPPER
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <ctype.h>
13 #include <sys/types.h>
14 #include <errno.h>
15 #include <limits.h>
17 #ifndef XC_WIN32
18 #include <X11/Intrinsic.h>
19 #include <X11/StringDefs.h>
20 #include <X11/Xutil.h>
22 #include "Xw/Xw.h"
23 #include "Xw/MenuBtn.h"
24 #include "Xw/PopupMgr.h"
25 #endif
27 /*----------------------------------------------------------------------*/
28 /* Local includes */
29 /*----------------------------------------------------------------------*/
31 #include "colordefs.h"
32 #include "xcircuit.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 */
45 extern xcWidget top;
46 extern Display *dpy;
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 /*----------------------------------------------------------------------*/
64 #include "menus.h"
65 #include "menudep.h"
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) {
87 if (button != NULL)
88 toggleexcl(button, GridStyles, XtNumber(GridStyles));
91 void toggleanchors(xcWidget button) {
92 if (button != NULL)
93 toggleexcl(button, Anchors, XtNumber(Anchors));
96 void togglefontstyles(xcWidget button) {
97 if (button != NULL)
98 toggleexcl(button, FontStyles, XtNumber(FontStyles));
101 void toggleencodings(xcWidget button) {
102 if (button != NULL)
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;
115 undrawtext(settext);
116 settext->anchor ^= bitfield;
117 redrawtext(settext);
118 pwriteback(areawin->topinstance);
120 register_for_undo(XCF_Anchor, UNDO_MORE, areawin->topinstance,
121 (genericptr)settext, oldanchor);
123 else
124 areawin->anchor ^= bitfield;
126 if (w != NULL) {
127 Boolean boolval;
128 if (settext)
129 boolval = (settext->anchor & bitfield) ? 0 : 1;
130 else
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;
148 undrawtext(settext);
149 settext->anchor ^= bitfield;
150 redrawtext(settext);
151 pwriteback(areawin->topinstance);
153 register_for_undo(XCF_Anchor, UNDO_MORE, areawin->topinstance,
154 (genericptr)settext, oldanchor);
156 if (w != NULL) {
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) {
173 if (mode == 1)
174 newanchor = (settext->anchor & (NONANCHORFIELD | TBANCHORFIELD))
175 | value;
176 else
177 newanchor = (settext->anchor & (NONANCHORFIELD | RLANCHORFIELD))
178 | value;
180 if (settext->anchor != newanchor) {
181 oldanchor = (int)settext->anchor;
182 undrawtext(settext);
183 settext->anchor = newanchor;
184 redrawtext(settext);
185 pwriteback(areawin->topinstance);
187 register_for_undo(XCF_Anchor, UNDO_MORE, areawin->topinstance,
188 (genericptr)settext, oldanchor);
191 else {
192 if (mode == 1)
193 newanchor = (areawin->anchor & (NONANCHORFIELD | TBANCHORFIELD))
194 | value;
195 else
196 newanchor = (areawin->anchor & (NONANCHORFIELD | RLANCHORFIELD))
197 | value;
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)
210 short *fselect;
211 labelptr settext;
212 short labelcount = 0;
214 if (eventmode == TEXT_MODE || eventmode == ETEXT_MODE) {
215 settext = *((labelptr *)EDITPART);
216 setanchor(w, value, settext, 2);
218 else {
219 for (fselect = areawin->selectlist; fselect < areawin->selectlist +
220 areawin->selects; fselect++) {
221 if (SELECTTYPE(fselect) == LABEL) {
222 labelcount++;
223 settext = SELTOLABEL(fselect);
224 setanchor(NULL, value, settext, 2);
227 if (labelcount == 0) setanchor(w, value, NULL, 2);
228 else unselect_all();
232 /*----------------------------------------------------------------*/
233 /* Set horizontal anchoring (left, center, right) on all */
234 /* selected labels */
235 /*----------------------------------------------------------------*/
237 void sethanchor(xcWidget w, pointertype value, caddr_t nulldata)
239 short *fselect;
240 labelptr settext;
241 short labelcount = 0;
243 if (eventmode == TEXT_MODE || eventmode == ETEXT_MODE) {
244 settext = *((labelptr *)EDITPART);
245 setanchor(w, value, settext, 1);
247 else {
248 for (fselect = areawin->selectlist; fselect < areawin->selectlist +
249 areawin->selects; fselect++) {
250 if (SELECTTYPE(fselect) == LABEL) {
251 labelcount++;
252 settext = SELTOLABEL(fselect);
253 setanchor(NULL, value, settext, 1);
256 if (labelcount == 0) setanchor(w, value, NULL, 1);
257 else unselect_all();
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)
268 short *fselect;
269 labelptr settext;
270 short labelcount = 0;
272 if (eventmode == TEXT_MODE || eventmode == ETEXT_MODE) {
273 settext = *((labelptr *)EDITPART);
274 doanchorbit(w, settext, (short)value);
276 else {
277 for (fselect = areawin->selectlist; fselect < areawin->selectlist +
278 areawin->selects; fselect++) {
279 if (SELECTTYPE(fselect) == LABEL) {
280 labelcount++;
281 settext = SELTOLABEL(fselect);
282 doanchorbit(NULL, settext, (short)value);
285 if (labelcount == 0) doanchorbit(w, NULL, (short)value);
286 else unselect_all();
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)
297 short *fselect;
298 labelptr settext;
300 if (eventmode == TEXT_MODE || eventmode == ETEXT_MODE) {
301 settext = *((labelptr *)EDITPART);
302 if (settext->pin)
303 dopinanchorbit(w, settext, (short)value);
305 else {
306 for (fselect = areawin->selectlist; fselect < areawin->selectlist +
307 areawin->selects; fselect++) {
308 if (SELECTTYPE(fselect) == LABEL) {
309 settext = SELTOLABEL(fselect);
310 if (settext->pin)
311 dopinanchorbit(NULL, settext, (short)value);
314 unselect_all();
318 /*--------------------------------------------------------------*/
319 /* Enable or Disable the toolbar */
320 /*--------------------------------------------------------------*/
322 #ifdef HAVE_XPM
323 void dotoolbar(xcWidget w, caddr_t clientdata, caddr_t calldata)
325 Arg wargs[1];
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);
334 else {
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 /*--------------------------------------------------------------*/
347 #ifndef XC_WIN32
349 void overdrawpixmap(xcWidget button)
351 xcWidget pbutton;
352 Arg args[3];
353 int ltype, color;
354 Pixmap stippix;
356 if (button == NULL) return;
358 XtSetArg(args[0], XtNlabelType, &ltype);
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;
369 else
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);
386 else
387 XtSetArg(args[1], XtNrectStipple, stippix);
389 XtSetValues(pbutton, args, 2);
393 #endif
395 #else
396 void overdrawpixmap(xcWidget button) {}
397 #endif /* XPM */
399 /*--------------------------------------------------------------*/
400 /* Generic routine for use by all other data handling routines */
401 /*--------------------------------------------------------------*/
403 buttonsave *getgeneric(xcWidget button, void (*getfunction)(), void *dataptr)
405 Arg wargs[1];
406 buttonsave *saveptr;
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);
420 return saveptr;
423 /*--------------------------------------------------------------*/
424 /* Generate popup dialog for snap space value input */
425 /*--------------------------------------------------------------*/
427 void getsnapspace(xcWidget button, caddr_t clientdata, caddr_t calldata)
429 char buffer[50];
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)
444 char buffer[50];
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) {
464 *dataptr = oldvalue;
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)
476 float tmpres;
478 int res = sscanf(_STR2, "%f", &tmpres);
480 if (res == 0 || tmpres <= 0) { /* can't interpret value or bad value */
481 Wprintf("Illegal value");
482 return;
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) {
516 *dataptr = oldvalue;
517 Wprintf("Illegal value");
519 else {
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) {
535 *dataptr = oldvalue;
536 Wprintf("Illegal value");
538 else {
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)
550 Arg wargs[1];
552 if (*dataptr == 0) {
553 *dataptr = 90;
554 XtSetArg(wargs[0], XtNlabel, "Landscape");
556 else {
557 *dataptr = 0;
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)
570 Arg wargs[1];
571 xcWidget pwidg = XtParent(w);
572 xcWidget autowidg = XtNameToWidget(pwidg, "Auto-fit");
574 if (!(*dataptr & 1)) {
575 *dataptr = 1;
576 XtSetArg(wargs[0], XtNlabel, "Full Page");
578 XtManageChild(XtNameToWidget(pwidg, "fpedit"));
579 XtManageChild(XtNameToWidget(pwidg, "fpokay"));
580 XtManageChild(autowidg);
582 else {
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)
601 char fpedit[75];
602 Arg wargs[1];
603 Boolean is_inches;
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)
622 char buffer[50];
623 buttonsave *savebutton;
624 int kx, ky;
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) {
641 strptr = nextptr;
642 kx = strptr->data.kern[0];
643 ky = strptr->data.kern[1];
644 sprintf(buffer, "%d,%d", kx, ky);
646 else strptr = NULL;
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)
660 char buffer[50];
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)
675 char buffer[50];
676 buttonsave *savebutton;
677 float *floatptr;
678 Boolean local;
679 labelptr settext;
681 settext = gettextsize(&floatptr);
682 sprintf(buffer, "%5.2f", *floatptr);
684 if (settext) {
685 savebutton = getgeneric(button, gettsize, settext);
686 popupprompt(button, "Enter text scale:", buffer, settsize, savebutton, NULL);
688 else {
689 savebutton = getgeneric(button, gettsize, floatptr);
690 popupprompt(button,
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)
701 char buffer[50];
702 float flval;
703 buttonsave *savebutton;
704 short *osel = areawin->selectlist;
705 short selects = 0;
706 objinstptr setobj = NULL;
708 for (; osel < areawin->selectlist + areawin->selects; osel++)
709 if (SELECTTYPE(osel) == OBJINST) {
710 setobj = SELTOOBJINST(osel);
711 selects++;
712 break;
714 if (setobj == NULL) {
715 Wprintf("No objects were selected for scaling.");
716 return;
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)
730 char buffer[50];
731 buttonsave *savebutton;
732 float *widthptr;
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,
738 savebutton, NULL);
741 /*----------------------------------------------------------------*/
742 /* Generate popup dialong for getting linewidths of elements */
743 /*----------------------------------------------------------------*/
745 void getwwidth(xcWidget button, caddr_t clientdata, caddr_t calldata)
747 char buffer[50];
748 buttonsave *savebutton;
749 short *osel = areawin->selectlist;
750 genericptr setel;
751 float flval;
753 for (; osel < areawin->selectlist + areawin->selects; osel++) {
754 setel = *(topobject->plist + (*osel));
755 if (IS_ARC(setel)) {
756 flval = ((arcptr)setel)->width;
757 break;
759 else if (IS_POLYGON(setel)) {
760 flval = ((polyptr)setel)->width;
761 break;
763 else if (IS_SPLINE(setel)) {
764 flval = ((splineptr)setel)->width;
765 break;
767 else if (IS_PATH(setel)) {
768 flval = ((pathptr)setel)->width;
769 break;
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,
776 savebutton, NULL);
778 else {
779 sprintf(buffer, "%4.2f", flval);
780 popupprompt(button, "Enter new line width:", buffer, setwwidth,
781 savebutton, NULL);
785 /*----------------------------------------------------------------*/
786 /* Generic popup prompt for getting a floating-point value */
787 /*----------------------------------------------------------------*/
789 void getfloat(xcWidget button, float *floatptr, caddr_t calldata)
791 char buffer[50];
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;
806 objectptr checkpage;
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);
824 free(oldstr);
827 /*----------------------------------------------------------------*/
828 /* Set the page label for the current page */
829 /*----------------------------------------------------------------*/
831 void setpagelabel(xcWidget w, char *dataptr)
833 short i;
835 /* Whitespace and non-printing characters not allowed */
837 for (i = 0; i < strlen(_STR2); i++) {
838 if ((!isprint(_STR2[i])) || (isspace(_STR2[i]))) {
839 _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);
847 else
848 sprintf(topobject->name, "%.79s", _STR2);
850 /* For schematics, all pages with associations to symbols must have */
851 /* unique names. */
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);
881 else {
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);
897 else {
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()
923 Arg wargs[1];
924 int n = 0;
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,
932 cascade, wargs, n);
934 XtAddCallback (newbutton, XtNselect, (XtCallbackProc)setfont,
935 Number(fontcount - 1));
936 XtManageChild(newbutton);
938 nfontnumbers++;
939 if (nfontnumbers == 1)
940 fontnumbers = (u_short *)malloc(sizeof(u_short));
941 else
942 fontnumbers = (u_short *)realloc(fontnumbers, nfontnumbers
943 * sizeof(u_short));
944 fontnumbers[nfontnumbers - 1] = fontcount - 1;
947 /*--------------------------------------------------------------*/
948 /* Make new encoding menu button */
949 /*--------------------------------------------------------------*/
951 void makenewencodingbutton(char *ename, char value)
953 Arg wargs[1];
954 int n = 0;
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,
965 cascade, wargs, n);
967 XtAddCallback (newbutton, XtNselect, (XtCallbackProc)setfontencoding,
968 Number(value));
969 XtManageChild(newbutton);
972 /*--------------------------------------------------------------*/
973 /* Set the menu checkmarks on the font menu */
974 /*--------------------------------------------------------------*/
976 void togglefontmark(int fontval)
978 Arg args[1];
979 xcWidget widget, cascade, sibling;
980 short i;
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++) {
989 if (i != fontval) {
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)
1007 Arg args[1];
1008 xcWidget parent = xcParent(widget);
1009 xcWidget sibling;
1010 menuptr mitem, mtest;
1011 short i;
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 */
1052 switch(mode) {
1053 case XCF_Spline:
1054 case XCF_Move:
1055 case XCF_Join:
1056 case XCF_Unjoin:
1057 XDefineCursor (dpy, areawin->window, ARROW);
1058 areawin->defaultcursor = &ARROW;
1059 break;
1060 case XCF_Pan:
1061 XDefineCursor (dpy, areawin->window, HAND);
1062 areawin->defaultcursor = &HAND;
1063 break;
1064 case XCF_Delete:
1065 XDefineCursor (dpy, areawin->window, SCISSORS);
1066 areawin->defaultcursor = &SCISSORS;
1067 break;
1068 case XCF_Copy:
1069 XDefineCursor (dpy, areawin->window, COPYCURSOR);
1070 areawin->defaultcursor = &COPYCURSOR;
1071 break;
1072 case XCF_Push:
1073 case XCF_Select_Save:
1074 XDefineCursor (dpy, areawin->window, QUESTION);
1075 areawin->defaultcursor = &QUESTION;
1076 break;
1077 case XCF_Rotate:
1078 case XCF_Flip_X:
1079 case XCF_Flip_Y:
1080 XDefineCursor (dpy, areawin->window, ROTATECURSOR);
1081 areawin->defaultcursor = &ROTATECURSOR;
1082 break;
1083 case XCF_Edit:
1084 XDefineCursor (dpy, areawin->window, EDCURSOR);
1085 areawin->defaultcursor = &EDCURSOR;
1086 break;
1087 case XCF_Arc:
1088 XDefineCursor (dpy, areawin->window, CIRCLE);
1089 areawin->defaultcursor = &CIRCLE;
1090 break;
1091 case XCF_Text:
1092 case XCF_Pin_Label:
1093 case XCF_Pin_Global:
1094 case XCF_Info_Label:
1095 XDefineCursor (dpy, areawin->window, TEXTPTR);
1096 areawin->defaultcursor = &TEXTPTR;
1097 break;
1098 default:
1099 XDefineCursor (dpy, areawin->window, CROSS);
1100 areawin->defaultcursor = &CROSS;
1101 break;
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)
1111 #ifdef HAVE_XPM
1112 Arg args[2];
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)
1124 self = sibling;
1125 else
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. */
1132 switch (func) {
1133 case XCF_Pan:
1134 self = PanToolButton;
1135 break;
1137 case XCF_Rotate:
1138 if (value > 0)
1139 self = RotPToolButton;
1140 else
1141 self = RotNToolButton;
1142 break;
1144 default:
1145 for (titem = ToolBar; titem < ToolBar + toolbuttons; titem++) {
1146 if (func == (pointertype)(titem->passeddata)) {
1147 self = XtNameToWidget(parent, titem->name);
1148 break;
1151 break;
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)
1171 Arg wargs[1];
1172 Boolean *boolvalue;
1174 if (soffset == -1)
1175 boolvalue = setdata;
1176 else
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");
1218 if (button) {
1219 toggleexcl(button, GridStyles, XtNumber(GridStyles));
1220 W1printf(" ");
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;
1250 Arg wargs[2];
1251 char libstring[20];
1252 int libnum;
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];
1261 libnum--;
1263 newlibobj = (objectptr) malloc(sizeof(object));
1264 initmem(newlibobj);
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
1272 * sizeof(Library));
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,
1289 Number(libnum));
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,
1302 libmenu, wargs, 2);
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 */
1310 composelib(LIBLIB);
1312 return libnum;
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;
1323 Arg wargs[1];
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)
1350 int page;
1351 objinstptr thisinst = xobjs.pagelist[pagenumber]->pageinst;
1352 Arg wargs[1];
1353 xcWidget parent = XtParent(GotoPageAddNewPageButton);
1354 xcWidget button;
1355 char bname[10];
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);
1364 else
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)
1378 Arg wargs[1];
1379 xcWidget parent = XtParent(GotoLibraryAddNewLibraryButton);
1380 xcWidget button;
1381 char bname[13];
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);
1389 else
1390 XtSetArg(wargs[0], XtNlabel, bname);
1391 XtSetValues(button, wargs, 1);
1393 else
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)
1403 Arg args[1];
1404 xcWidget w = NULL;
1405 short i;
1407 if (colorval == DEFAULTCOLOR)
1408 w = ColorInheritColorButton;
1409 else
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) {
1422 overdrawpixmap(w);
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)
1434 xcWidget w;
1435 Arg wargs[1];
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;
1449 else
1450 w = BorderSolidButton;
1451 toggleexcl(w, BorderStyles, XtNumber(BorderStyles));
1453 if (styleval & OPAQUE)
1454 w = FillOpaqueButton;
1455 else
1456 w = FillTransparentButton;
1457 toggleexcl(w, Stipples, XtNumber(Stipples));
1459 if (!(styleval & FILLED))
1460 w = FillWhiteButton;
1461 else {
1462 styleval &= FILLSOLID;
1463 styleval /= STIP0;
1464 switch(styleval) {
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)
1524 short *scolor;
1525 int *ecolor, cindex, cval;
1526 Arg wargs[1];
1527 Boolean selected = False;
1528 stringpart *strptr, *nextptr;
1530 /* Get the color index value from the menu button widget itself */
1532 if (value == 1)
1533 cindex = cval = -1;
1534 else {
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)
1540 break;
1541 if (cindex >= number_colors) {
1542 Wprintf("Error: No such color!");
1543 return;
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);
1563 else {
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));
1574 *ecolor = cindex;
1575 selected = True;
1579 setcolormark(cindex);
1580 if (!selected) {
1581 if (eventmode != TEXT_MODE && eventmode != ETEXT_MODE)
1582 areawin->color = cindex;
1583 overdrawpixmap(w);
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;
1594 char *ppos, *cpos;
1596 ppos = strchr(_STR2, '#');
1597 cpos = strchr(_STR2, ',');
1599 if (cpos != NULL || ppos != NULL) {
1600 if (cpos != NULL || strlen(ppos + 1) == 6) {
1601 if (cpos != NULL)
1602 sscanf(_STR2, "%d, %d, %d", &red, &green, &blue);
1603 else
1604 sscanf(ppos + 1, "%2x%2x%2x", &red, &green, &blue);
1605 red *= 256;
1606 green *= 256;
1607 blue *= 256;
1609 else if (sscanf(ppos + 1, "%4x%4x%4x", &red, &green, &blue) != 3) {
1610 Wprintf("Bad color entry. Use #rrggbb");
1611 return;
1613 ccolor = rgb_alloccolor(red, green, blue);
1615 else {
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,
1631 savebutton, NULL);
1634 /*------------------------------------------------------*/
1636 void setfontmarks(short fvalue, short jvalue)
1638 xcWidget w;
1639 Arg wargs[1];
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;
1653 default: w = NULL;
1655 if (w != NULL) toggleexcl(w, FontEncodings, XtNumber(FontEncodings));
1657 togglefontmark(fvalue);
1659 if (jvalue >= 0) {
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);
1679 else
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);
1687 else
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)
1717 if (w == NULL) {
1718 switch (value) {
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));
1741 tempstr[0] = '\0';
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)
1754 dospecial();
1755 else
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)
1765 int n = 0;
1766 Arg wargs[2];
1767 Position pz, pw, ph;
1768 int dx, dy;
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;
1780 dx = -pw - 6;
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 */