/* * Copyright 1991 Klaus Zitzmann, 1993-1996 Johannes Sixt * * Permission to use, copy, modify and distribute this software and its * documentation for any purpose other than its commercial exploitation * is hereby granted without fee, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation. The authors * make no representations about the suitability of this software for * any purpose. It is provided "as is" without express or implied warranty. * * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. * * Authors: Klaus Zitzmann * Johannes Sixt */ #include #include /* getenv */ #include #include /* need MAXPATHLEN */ #include #include #include #include #include #include #include #include #include #include /* #include included by */ #if !defined(XtSpecificationRelease) || XtSpecificationRelease < 5 #define XawRubber XtRubber #define XawChainBottom XtChainBottom #define XawChainTop XtChainTop #define XawChainLeft XtChainLeft #define XawChainRight XtChainRight #endif /* pre Release 5 */ #include #include /* #include included by */ /* #include included by */ #include #include #include "patchlevel.h" #include "objects.h" #include "io_trans.h" #include "modify.h" #include "graphics.h" #include "shift.xbm" #include "icon.h" #include "tickMark.xbm" static char titlename[20]; static char current_file[MAXPATHLEN]; static char unnamed_name[] = "No name"; static XtAppContext appContext; static Pixmap check_mark_bitmap; static Widget topLevel; static Widget coordinates; static XtPopdownIDRec zoomDown; static Widget rasterOn, snapOn, slope, diameters, lineal, crossW, llline; static Widget fileselector, messenger, message, confirmer, accept; static Widget rastHeight, zoomFact, moveBaseValue; static XtCallbackProc acceptProc; #define ZOOM_TEXT_LEN 10 static char zoomFactorStr[ZOOM_TEXT_LEN]; static String zoomFactorFmt; static struct _app_resources { XFontStruct *font; XFontStruct *ruler_font; Pixel foreground; float initMoveBase; float initRasterHeight; String initZoomFactor; String initUnitLength; Boolean Raster; Boolean Snappy; Boolean Ruler; Boolean Cross; Boolean unlimitedSlopes; Boolean unlimitedCircles; Boolean unlimitedLengths; String saveext; } app_res; #include "resources.h" /* fallback resources */ #define offset(field) XtOffsetOf(struct _app_resources, field) static XtResource resources[] = { {XtNfont, XtCFont, XtRFontStruct, sizeof(XFontStruct *), offset(font), XtRString, XtDefaultFont}, {"rulerFont", XtCFont, XtRFontStruct, sizeof(XFontStruct *), offset(ruler_font), XtRString, XtDefaultFont}, {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel), offset(foreground), XtRString, XtDefaultForeground}, {"initOffset", "InitOffset", XtRFloat, sizeof(float), offset(initMoveBase), XtRString, (XtPointer) "10.0"}, {"initGridDistance", "InitGridDistance", XtRFloat, sizeof(float), offset(initRasterHeight), XtRString, (XtPointer) "10.0"}, {"initZoomFactor", "InitZoomFactor", XtRString, sizeof(String), offset(initZoomFactor), XtRString, "100"}, {"defaultUnitLength", "DefaultUnitLength", XtRString, sizeof(String), offset(initUnitLength), XtRString, "1.0pt"}, {"initSnapGrid", "InitSnapGrid", XtRBoolean, sizeof(Boolean), offset(Snappy), XtRImmediate, (XtPointer)False}, {"initGrid", "InitRuler", XtRBoolean, sizeof(Boolean), offset(Raster), XtRImmediate, (XtPointer)False}, {"initRuler", "InitRuler", XtRBoolean, sizeof(Boolean), offset(Ruler), XtRImmediate, (XtPointer)False}, {"initCross", "InitRuler", XtRBoolean, sizeof(Boolean), offset(Cross), XtRImmediate, (XtPointer)False}, {"initUnlimitedSlopes", "InitUnlimited", XtRBoolean, sizeof(Boolean), offset(unlimitedSlopes), XtRImmediate, (XtPointer)False}, {"initUnlimitedCircles", "InitUnlimited", XtRBoolean, sizeof(Boolean), offset(unlimitedCircles), XtRImmediate, (XtPointer)False}, {"initUnlimitedLengths", "InitUnlimited", XtRBoolean, sizeof(Boolean), offset(unlimitedLengths), XtRImmediate, (XtPointer)False}, {"backupSuffix", "BackupSuffix", XtRString, sizeof(String), offset(saveext), XtRString, ".old"}, }; #undef offset static XrmOptionDescRec options[] = { {"-fn", ".font", XrmoptionSepArg, NULL}, }; static void MenuLineInit(Widget parent); static Widget ShiftInit(Widget parent, XtPopdownID pDown); static Widget ZoomInit(Widget parent, XtPopdownID pDown); static void ZoomCB(Widget w, XtPointer client, XtPointer call_data); static Widget ConfirmInit(Widget parent); static void MessageInit(Widget parent); static Widget OptionsInit(Widget parent, XtPopdownID pDown); static void SetCheckMarkCB(Widget w, XtPointer client, XtPointer call); static void PopupLoad(Widget w, XtPointer client_data, XtPointer call_data); static void MaybePopupSave(Widget w, XtPointer client_data, XtPointer calldata); static void PopupSave(Widget w, XtPointer client_data, XtPointer call_data); static void Popdown(Widget w, XtPointer client_data, XtPointer call_data); static void Quit(Widget w, XtPointer client_data, XtPointer call_data); static void RefreshCB(Widget w, XtPointer client_data, XtPointer call_data); static void OptionFlagCB(Widget w, XtPointer client_data, XtPointer call_data); static void ConfirmCB(Widget w, XtPointer client_data, XtPointer call_data); static void ExecuteAccept(Widget w, XtPointer client_data, XtPointer call_data); static void MessageUp(char *text); static void PopAtPointer(Widget w, XtGrabKind grab); static void NewCB(Widget w, XtPointer client_data, XtPointer call_data); static void LoadCB(Widget w, XtPointer client_data, XtPointer call_data); static void SaveAsCB(Widget w, XtPointer client_data, XtPointer call_data); static void SetTitle(void); static void SetNewZoom(void); void main(int argc, char *argv[]) { Widget topForm; Pixel background; sprintf(titlename, "XTeXcad %s.%s", VERSION, PATCHLEVEL); topLevel = XtVaAppInitialize(&appContext, "XTeXcad", options, XtNumber(options), &argc, argv, fallbacks, /* fallback resources */ XtNtitle, (XtArgVal) titlename, NULL); /* get some resources */ XtGetApplicationResources(topLevel, (XtPointer) &app_res, resources, XtNumber(resources), NULL, 0); /* connect the TeXcad - icon to the toplevel-shell */ XtVaSetValues(topLevel, XtNiconPixmap, (XtArgVal) XCreateBitmapFromData(XtDisplay(topLevel), RootWindowOfScreen(XtScreen(topLevel)), icon_bits, icon_width, icon_height), NULL); /* build the desktop */ topForm = XtVaCreateManagedWidget("topForm", panedWidgetClass, topLevel, XtNorientation, (XtArgVal) XtorientVertical, NULL); MenuLineInit(topForm); InitDB(topForm, app_res.initMoveBase, app_res.initUnitLength); fileselector = XtVaCreatePopupShell("fileShell", fileNominatorWindowWidgetClass, topForm, NULL); XtAddCallback(FileNominatorWindowFileNominatorWidget(fileselector), XtNcancelCallback, Popdown, (XtPointer) fileselector); XtRealizeWidget(topLevel); /* realize all */ /* the size of the coordinates widget was specified using a dummy * value (in the app-defaults); erase this string */ XtVaSetValues(coordinates, XtNlabel, (XtArgVal) "", NULL); XtVaGetValues(pboard, XtNbackground, (XtArgVal) &background, NULL); ObjInit(XtDisplay(pboard), XtScreen(pboard), XtWindow(pboard), app_res.font, app_res.foreground, background, app_res.initRasterHeight); strncpy(zoomFactorStr, app_res.initZoomFactor, ZOOM_TEXT_LEN); zoomFactorStr[ZOOM_TEXT_LEN-1] = '\0'; SetNewZoom(); /* convert zoomFactorStr into zoomFactor */ GraphicsInit(appContext, topForm, coordinates, app_res.ruler_font, app_res.foreground, background); raster = app_res.Raster; XtVaSetValues(rasterOn, XtNstate, (XtArgVal) raster, NULL); snap = app_res.Snappy; XtVaSetValues(snapOn, XtNstate, (XtArgVal) snap, NULL); unlimitedSlopes = app_res.unlimitedSlopes; XtVaSetValues(slope, XtNstate, (XtArgVal) unlimitedSlopes, NULL); unlimitedDiameters = app_res.unlimitedCircles; XtVaSetValues(diameters, XtNstate, (XtArgVal)unlimitedDiameters, NULL); ruler = app_res.Ruler; XtVaSetValues(lineal, XtNstate, (XtArgVal) ruler, NULL); cross = app_res.Cross; XtVaSetValues(crossW, XtNstate, (XtArgVal) cross, NULL); noMinLength = app_res.unlimitedLengths; XtVaSetValues(llline, XtNstate, (XtArgVal) noMinLength, NULL); ToggleRaster(rasterOn, NULL, NULL); /* load a file if there is one specified */ strcpy(current_file, unnamed_name); if ((argc > 1)) { if (LoadFromFile(argv[1], MessageUp)) { strcpy(current_file, argv[1]); } } else { SetCoordOrigin(); } /* notify text widgets of new values */ XtVaSetValues(rastHeight, XtNstring, (XtArgVal) rasterHeightStr, NULL); XtVaSetValues(zoomFact, XtNstring, (XtArgVal) zoomFactorStr, NULL); XtVaSetValues(moveBaseValue, XtNstring, (XtArgVal) moveBaseStr, NULL); XSync(XtDisplay(topLevel), False); /* Why do I need this? */ SetTitle(); XtAppMainLoop(appContext); } static void MenuLineInit(Widget parent) { Widget menuLine, fileMenuButton, fileMenu, drawMenuButton, drawMenu, editMenuButton, editMenu; Widget load, save, saveas, quit, entry, del, copy, tedit, refr; int i; String str; static XtPopdownIDRec optionsDown, shiftDown; static char sepName[] = "separator"; static struct { char *name; GraphMode client_data; Widget menu_entry; } cm[] = { {"pick", graphEditPick}, {sepName, (GraphMode) 0}, {"line", graphLine}, {"vector", graphVector}, {"bezier", graphBezier}, {sepName, (GraphMode) 0}, {"framed", graphFramed}, {"dashed", graphDashed}, {"text", graphText}, {sepName, (GraphMode) 0}, {"circle", graphCircle}, {"disc", graphDisc}, {sepName, (GraphMode) 0}, {"filled", graphFilled}, {"rounded", graphOval}, }; menuLine = XtVaCreateManagedWidget("menuLine", formWidgetClass, parent, NULL); fileMenuButton = XtVaCreateManagedWidget ("file", menuButtonWidgetClass, menuLine, XtNmenuName, (XtArgVal) "fileMenu", /* constraints */ XtNleft, (XtArgVal) XawChainLeft, XtNright, (XtArgVal) XawChainLeft, NULL); fileMenu = XtVaCreatePopupShell ("fileMenu", simpleMenuWidgetClass, fileMenuButton, NULL); confirmer = ConfirmInit(parent); MessageInit(parent); entry = XtVaCreateManagedWidget("new", smeBSBObjectClass, fileMenu, NULL); XtAddCallback(entry, XtNcallback, ConfirmCB, (XtPointer) NewCB); load = XtVaCreateManagedWidget("load", smeBSBObjectClass, fileMenu, NULL); XtAddCallback(load, XtNcallback, ConfirmCB, (XtPointer) PopupLoad); save = XtVaCreateManagedWidget("save", smeBSBObjectClass, fileMenu, NULL); XtAddCallback(save, XtNcallback, MaybePopupSave, NULL); saveas = XtVaCreateManagedWidget("saveas", smeBSBObjectClass, fileMenu, NULL); XtAddCallback(saveas, XtNcallback, PopupSave, NULL); quit = XtVaCreateManagedWidget("quit", smeBSBObjectClass, fileMenu, NULL); XtAddCallback(quit, XtNcallback, ConfirmCB, (XtPointer) Quit); editMenuButton = XtVaCreateManagedWidget ("edit", menuButtonWidgetClass, menuLine, XtNmenuName, (XtArgVal) "editMenu", /* constraints */ XtNfromHoriz, (XtArgVal) fileMenuButton, XtNleft, (XtArgVal) XawChainLeft, XtNright, (XtArgVal) XawChainLeft, NULL); editMenu = XtVaCreatePopupShell ("editMenu", simpleMenuWidgetClass, editMenuButton, NULL); copy = XtVaCreateManagedWidget("copy", smeBSBObjectClass, editMenu, NULL); XtAddCallback(copy, XtNcallback, CopyCB, NULL); del = XtVaCreateManagedWidget("delete", smeBSBObjectClass, editMenu, NULL); XtAddCallback(del, XtNcallback, DeleteCB, NULL); tedit = XtVaCreateManagedWidget("editText", smeBSBObjectClass, editMenu, NULL); XtAddCallback(tedit, XtNcallback, EditTextCB, NULL); XtVaCreateManagedWidget("separator", smeLineObjectClass, editMenu, NULL); refr = XtVaCreateManagedWidget("refresh", smeBSBObjectClass, editMenu, NULL); XtAddCallback(refr, XtNcallback, RefreshCB, NULL); drawMenuButton = XtVaCreateManagedWidget ("draw", menuButtonWidgetClass, menuLine, XtNmenuName, (XtArgVal) "drawMenu", /* constraints */ XtNfromHoriz, (XtArgVal) editMenuButton, XtNleft, (XtArgVal) XawChainLeft, XtNright, (XtArgVal) XawChainLeft, NULL); drawMenu = XtVaCreatePopupShell ("drawMenu", simpleMenuWidgetClass, drawMenuButton, NULL); for (i = 0; i < XtNumber(cm); i++) { if (cm[i].name == sepName) { XtVaCreateManagedWidget(sepName, smeLineObjectClass, drawMenu, NULL); } else { cm[i].menu_entry = entry = XtVaCreateManagedWidget(cm[i].name, smeBSBObjectClass, drawMenu, XtNleftMargin, (XtArgVal) tickMark_width + 6, NULL); XtAddCallback(entry, XtNcallback, CommandCB, (XtPointer) cm[i].client_data); XtAddCallback(entry, XtNcallback, SetCheckMarkCB, NULL); } } check_mark_bitmap = XCreateBitmapFromData(XtDisplay(parent), RootWindowOfScreen(XtScreen(parent)), tickMark_bits, tickMark_width, tickMark_height); /* set first check mark */ SetCheckMarkCB(cm[0].menu_entry, NULL, NULL); optionsDown.shell_widget = OptionsInit(parent, &optionsDown); optionsDown.enable_widget = XtVaCreateManagedWidget("options", commandWidgetClass, menuLine, /* constraints */ XtNfromHoriz, (XtArgVal) drawMenuButton, XtNleft, (XtArgVal) XawChainLeft, XtNright, (XtArgVal) XawChainLeft, NULL); XtAddCallback(optionsDown.enable_widget, XtNcallback, XtCallbackNone, (XtPointer) optionsDown.shell_widget); shiftDown.shell_widget = ShiftInit(parent, &shiftDown); shiftDown.enable_widget = XtVaCreateManagedWidget("shift", commandWidgetClass, menuLine, /* constraints */ XtNfromHoriz, (XtArgVal) optionsDown.enable_widget, XtNleft, (XtArgVal) XawChainLeft, XtNright, (XtArgVal) XawChainLeft, NULL); XtAddCallback(shiftDown.enable_widget, XtNcallback, XtCallbackNone, (XtPointer) shiftDown.shell_widget); /* --- zoom factor button and display area--- */ zoomDown.shell_widget = ZoomInit(parent, &zoomDown); zoomDown.enable_widget = XtVaCreateManagedWidget("zoom", commandWidgetClass, menuLine, /* constraints */ XtNfromHoriz, (XtArgVal) shiftDown.enable_widget, XtNleft, (XtArgVal) XawChainLeft, XtNright, (XtArgVal) XawChainLeft, NULL); XtAddCallback(zoomDown.enable_widget, XtNcallback, XtCallbackNone, (XtPointer) zoomDown.shell_widget); /* The label (specified in the resources) will contain a printf * control sequence. We use it to format the zoom factor in * SetNewZoom()! */ XtVaGetValues(zoomDown.enable_widget, XtNlabel, (XtArgVal) &str, NULL); zoomFactorFmt = strdup(str); /* --- coordinate display area--- */ coordinates = XtVaCreateManagedWidget("coord", labelWidgetClass, menuLine, XtNfromHoriz, (XtArgVal) zoomDown.enable_widget, XtNleft, (XtArgVal) XawChainLeft, XtNright, (XtArgVal) XawChainLeft, NULL); } static Widget ShiftInit(Widget parent, XtPopdownID pDown) { /* buttons top right placement */ Pixmap icon; Display *disp; Window win; Widget shell; Widget moveBase; Widget left, right, up, down, center, done; disp = XtDisplay(topLevel); win = RootWindow(disp, DefaultScreen(disp)); shell = XtVaCreatePopupShell("shiftShell", topLevelShellWidgetClass, parent, XtNallowShellResize, (XtArgVal) False, NULL); /* base moving buttons */ moveBase = XtVaCreateManagedWidget("moveBase", compositeWidgetClass, shell, XtNwidth, (XtArgVal) 68, XtNheight, (XtArgVal) 120, NULL); icon = XCreateBitmapFromData(disp, win, up_bits, 35, 20); up = XtVaCreateManagedWidget("up", commandWidgetClass, moveBase, XtNbitmap, (XtArgVal) icon, XtNborderWidth, (XtArgVal) 0, XtNx, (XtArgVal) 0, XtNy, (XtArgVal) 0, NULL); XtAddCallback(up, XtNcallback, MoveBase, (XtPointer) MoveBaseUp); XtAddCallback(up, XtNcallback, AbortGraphCB, NULL); icon = XCreateBitmapFromData(disp, win, right_bits, 20, 35); right = XtVaCreateManagedWidget("right", commandWidgetClass, moveBase, XtNbitmap, (XtArgVal) icon, XtNborderWidth, (XtArgVal) 0, XtNx, (XtArgVal) 46, XtNy, (XtArgVal) 0, NULL); XtAddCallback(right, XtNcallback, MoveBase, (XtPointer) MoveBaseRight); XtAddCallback(right, XtNcallback, AbortGraphCB, NULL); icon = XCreateBitmapFromData(disp, win, left_bits, 20, 35); left = XtVaCreateManagedWidget("left", commandWidgetClass, moveBase, XtNbitmap, (XtArgVal) icon, XtNborderWidth, (XtArgVal) 0, XtNx, (XtArgVal) 0, XtNy, (XtArgVal) 27, NULL); XtAddCallback(left, XtNcallback, MoveBase, (XtPointer) MoveBaseLeft); XtAddCallback(left, XtNcallback, AbortGraphCB, NULL); icon = XCreateBitmapFromData(disp, win, down_bits, 35, 20); down = XtVaCreateManagedWidget("down", commandWidgetClass, moveBase, XtNbitmap, (XtArgVal) icon, XtNborderWidth, (XtArgVal) 0, XtNx, (XtArgVal) 31, XtNy, (XtArgVal) 42, NULL); XtAddCallback(down, XtNcallback, MoveBase, (XtPointer) MoveBaseDown); XtAddCallback(down, XtNcallback, AbortGraphCB, NULL); icon = XCreateBitmapFromData(disp, win, zen_bits, 8, 8); center = XtVaCreateManagedWidget("center", commandWidgetClass, moveBase, XtNbitmap, (XtArgVal) icon, XtNborderWidth, (XtArgVal) 0, XtNinternalWidth, (XtArgVal) 2, XtNx, (XtArgVal) 31, XtNy, (XtArgVal) 27, NULL); XtAddCallback(center, XtNcallback, MoveBase, (XtPointer)MoveBaseCenter); XtAddCallback(center, XtNcallback, AbortGraphCB, NULL); moveBaseValue = XtVaCreateManagedWidget("offset", asciiTextWidgetClass, moveBase, XtNstring, (XtArgVal) moveBaseStr, XtNuseStringInPlace, (XtArgVal) True, XtNlength, (XtArgVal) MOVE_BASE_STR_LEN, XtNwidth, (XtArgVal) 54, XtNeditType, (XtArgVal) XawtextEdit, XtNx, (XtArgVal) 2, XtNy, (XtArgVal) 68, NULL); done = XtVaCreateManagedWidget("done", commandWidgetClass, moveBase, XtNx, (XtArgVal) 2, XtNy, (XtArgVal) 98, NULL); XtAddCallback(done, XtNcallback, XtCallbackPopdown, (XtPointer) pDown); XtSetKeyboardFocus(moveBase, moveBaseValue); return shell; } static Widget ZoomInit(Widget parent, XtPopdownID pDown) { Display *disp; Widget shell, dialog, done; XtTranslations okAcc; static char okAccelTable[] = "#override " "Return: set() notify() unset()\n" "KP_Enter: set() notify() unset()"; disp = XtDisplay(topLevel); shell = XtVaCreatePopupShell("zoomShell", topLevelShellWidgetClass, parent, NULL); dialog = XtVaCreateManagedWidget("entry", boxWidgetClass, shell, NULL); XtVaCreateManagedWidget("zoom", labelWidgetClass, dialog, XtNleft, (XtArgVal) XawChainLeft, XtNright, (XtArgVal) XawChainLeft, NULL); zoomFact = XtVaCreateManagedWidget("factor", asciiTextWidgetClass, dialog, XtNstring, (XtArgVal) zoomFactorStr, XtNuseStringInPlace, (XtArgVal) True, XtNlength, (XtArgVal) XtNumber(zoomFactorStr), XtNeditType, (XtArgVal) XawtextEdit, NULL); okAcc = XtParseAcceleratorTable(okAccelTable); done = XtVaCreateManagedWidget("done", commandWidgetClass, dialog, XtNaccelerators, (XtArgVal) okAcc, NULL); XtAddCallback(done, XtNcallback, ZoomCB, NULL); XtAddCallback(done, XtNcallback, XtCallbackPopdown, (XtPointer) pDown); XtInstallAllAccelerators(zoomFact,dialog); XtSetKeyboardFocus(dialog, zoomFact); return shell; } /*ARGSUSED*/ static void ZoomCB(Widget w, XtPointer client_data, XtPointer call_data) { /* scale objects to normal size using old zoom factor*/ RescaleAll(1.0/zoomFactor); /* scale objects to new size using current zoom factor string */ SetNewZoom(); /* convert zoomFactorStr into zoomFactor */ RescaleAll(zoomFactor); /* redraw and de-select all objects (it would be better to * handle zoom modify.c, but I can't do it) */ RemoveAllGrips(); if (XtIsRealized(pboard)) XClearArea(XtDisplay(pboard), XtWindow(pboard), 0, 0, 0, 0, True); } static Widget ConfirmInit(Widget parent) { Widget shell, dialog; shell = XtVaCreatePopupShell("confirmer", transientShellWidgetClass, parent, NULL); dialog = XtVaCreateManagedWidget("dialog", dialogWidgetClass, shell, NULL); accept = XtVaCreateManagedWidget("confirm", commandWidgetClass, dialog, NULL); XtAddCallback(accept, XtNcallback, Popdown, (XtPointer) shell); XtAddCallback(accept, XtNcallback, ExecuteAccept, (XtPointer) 0); XawDialogAddButton(dialog, "cancel", Popdown, (XtPointer) shell); return shell; } static void MessageInit(Widget parent) { messenger = XtVaCreatePopupShell("message", transientShellWidgetClass, parent, NULL); message = XtVaCreateManagedWidget("dialog", dialogWidgetClass, messenger, NULL); XawDialogAddButton(message, "done", Popdown, (XtPointer) messenger); } static Widget OptionsInit(Widget parent, XtPopdownID pDown) { /* creates the 'settings'-menu */ Widget shell, box, button; shell = XtVaCreatePopupShell("optionsShell", topLevelShellWidgetClass, parent, NULL); box = XtVaCreateManagedWidget("box", boxWidgetClass, shell, NULL); rasterOn = XtVaCreateManagedWidget("rasterOn", toggleWidgetClass, box, NULL); XtAddCallback(rasterOn, XtNcallback, ToggleRaster, NULL); rastHeight = XtVaCreateManagedWidget("value", asciiTextWidgetClass, box, XtNuseStringInPlace, (XtArgVal) True, XtNstring, (XtArgVal) rasterHeightStr, XtNlength, (XtArgVal) XtNumber(rasterHeightStr), XtNeditType, (XtArgVal) XawtextEdit, NULL); snapOn = XtVaCreateManagedWidget("snapOn", toggleWidgetClass, box, NULL); XtAddCallback(snapOn, XtNcallback, OptionFlagCB, (XtPointer) &snap); slope = XtVaCreateManagedWidget("slope", toggleWidgetClass, box, NULL); XtAddCallback(slope, XtNcallback, OptionFlagCB, (XtPointer) &unlimitedSlopes); diameters = XtVaCreateManagedWidget("diameters", toggleWidgetClass, box, NULL); XtAddCallback(diameters, XtNcallback, OptionFlagCB, (XtPointer) &unlimitedDiameters); lineal = XtVaCreateManagedWidget("lineal", toggleWidgetClass, box, NULL); XtAddCallback(lineal, XtNcallback, ToggleRuler, NULL); crossW = XtVaCreateManagedWidget("cross", toggleWidgetClass, box, NULL); XtAddCallback(crossW, XtNcallback, OptionFlagCB, (XtPointer) &cross); llline = XtVaCreateManagedWidget("llline", toggleWidgetClass, box, NULL); XtAddCallback(llline, XtNcallback, OptionFlagCB, (XtPointer) &noMinLength); button = XtVaCreateManagedWidget("done", commandWidgetClass, box, NULL); XtAddCallback(button, XtNcallback, XtCallbackPopdown, (XtPointer) pDown); XtSetKeyboardFocus(box, rastHeight); return shell; } /*ARGSUSED*/ static void SetCheckMarkCB(Widget w, XtPointer client_data, XtPointer call_data) { static Widget last_checked = (Widget) 0; if (w != last_checked) { if (last_checked != (Widget) 0) { XtVaSetValues(last_checked, XtNleftBitmap, None, NULL); } XtVaSetValues(w, XtNleftBitmap, check_mark_bitmap, NULL); last_checked = w; } } /*ARGSUSED*/ static void ConfirmCB(Widget w, XtPointer client_data, XtPointer call_data) { XtCallbackProc proc = (XtCallbackProc) client_data; if (changeMade) { acceptProc = proc; PopAtPointer(confirmer, XtGrabNonexclusive); } else proc((Widget) 0, (XtPointer) 0, call_data); } /*ARGSUSED*/ static void ExecuteAccept(Widget w, XtPointer client_data, XtPointer call_data) { acceptProc((Widget) 0, (XtPointer) 0, call_data); } /*ARGSUSED*/ static void PopupLoad(Widget w, XtPointer client_data, XtPointer call_data) { Widget fnw = FileNominatorWindowFileNominatorWidget(fileselector); XtRemoveAllCallbacks(fnw, XtNselectCallback); XtAddCallback(fnw, XtNselectCallback, LoadCB, NULL); XtAddCallback(fnw, XtNselectCallback, Popdown, (XtPointer) fileselector); XtVaSetValues(fileselector, XtNtitle, "Load", NULL); PopAtPointer(fileselector, XtGrabNone); } /*ARGSUSED*/ static void MaybePopupSave(Widget w, XtPointer client_data, XtPointer call_data) { if (strcmp(current_file, unnamed_name) == 0) { PopupSave(w, client_data, call_data); } else { (void) SaveToFile(current_file, MessageUp, app_res.saveext); } } /*ARGSUSED*/ static void PopupSave(Widget w, XtPointer client_data, XtPointer call_data) { Widget fnw = FileNominatorWindowFileNominatorWidget(fileselector); XtRemoveAllCallbacks(fnw, XtNselectCallback); XtAddCallback(fnw, XtNselectCallback, SaveAsCB, NULL); XtAddCallback(fnw, XtNselectCallback, Popdown, (XtPointer) fileselector); XtVaSetValues(fileselector, XtNtitle, "Save as", NULL); PopAtPointer(fileselector, XtGrabNone); } /*ARGSUSED*/ static void Popdown(Widget w, XtPointer client_data, XtPointer call_data) { XtPopdown((Widget) client_data); } /*ARGSUSED*/ static void Quit(Widget w, XtPointer client_data, XtPointer call_data) { exit(0); } /*ARGSUSED*/ static void RefreshCB(Widget w, XtPointer client_data, XtPointer call_data) { XClearArea(XtDisplay(pboard), XtWindow(pboard), 0, 0, 0, 0, True); } /*ARGSUSED*/ static void OptionFlagCB(Widget w, XtPointer client_data, XtPointer call_data) { XtVaGetValues(w, XtNstate, (Boolean *) client_data, NULL); } /*ARGSUSED*/ static void MessageUp(char *text) { XtVaSetValues(message, XtNlabel, (XtArgVal) text, NULL); PopAtPointer(messenger, XtGrabNone); XBell(XtDisplay(messenger), 0); } static void PopAtPointer(Widget w, XtGrabKind grab) { Window child, root; int x_r, y_r, x, y; Dimension width, height; unsigned mask; XtRealizeWidget(w); /* sorry for this: */ XQueryPointer(XtDisplay(topLevel), XtWindow(topLevel), &root, &child, &x_r, &y_r, &x, &y, &mask); XtVaGetValues(w, XtNwidth, (XtArgVal) &width, XtNheight, (XtArgVal) &height, NULL); x_r -= width/2; y_r -= height/2; XtVaSetValues(w, XtNx, (XtArgVal) x_r < 0 ? 0 : x_r, XtNy, (XtArgVal) y_r < 0 ? 0 : y_r, NULL); XtPopup(w, grab); } /*ARGSUSED*/ static void NewCB(Widget w, XtPointer client_data, XtPointer call_data) { Erase(); RemoveAllGrips(); ToggleRaster(rasterOn, NULL, NULL); ToggleRuler(lineal, NULL, NULL); strcpy(current_file, unnamed_name); SetTitle(); } /*ARGSUSED*/ static void LoadCB(Widget w, XtPointer client_data, XtPointer call_data) { FileNominatorStruct *data = (FileNominatorStruct *) call_data; char name[MAXPATHLEN]; strcpy(name, data->directoryPart); strcat(name, data->filenamePart); if (LoadFromFile(name, MessageUp)) { strcpy(current_file, name); SetTitle(); } RemoveAllGrips(); } /*ARGSUSED*/ static void SaveAsCB(Widget w, XtPointer client_data, XtPointer call_data) { FileNominatorStruct *data = (FileNominatorStruct *) call_data; char name[MAXPATHLEN]; strcpy(name, data->directoryPart); strcat(name, data->filenamePart); if (SaveToFile(name, MessageUp, app_res.saveext)) { strcpy(current_file, name); SetTitle(); } } static void SetTitle(void) { static char newtitle[20 + MAXPATHLEN]; static Arg arg = { XtNtitle, (XtArgVal) newtitle }; char *home; int home_len; if ((home = getenv("HOME")) && strncmp(current_file, home, (home_len = strlen(home))) == 0) { sprintf(newtitle, "%s: ~/%s", titlename, ¤t_file[home_len + 1]); } else { sprintf(newtitle, "%s: %s", titlename, current_file); } XtSetValues(topLevel, &arg, 1); } #define MAX_ZOOM 4.0 #define MIN_ZOOM 0.25 static void SetNewZoom(void) { static char newZoom[100]; static Arg arg = { XtNlabel, (XtArgVal) newZoom }; /* user enters zoom factor in percent */ if (sscanf(zoomFactorStr, "%f", &zoomFactor) != 1) zoomFactor = 1.0; else { zoomFactor /= 100.0; if (zoomFactor < MIN_ZOOM) zoomFactor = MIN_ZOOM; else if (zoomFactor > MAX_ZOOM) zoomFactor = MAX_ZOOM; } /* display new factor in zoom button in percent */ sprintf(newZoom, zoomFactorFmt, (int) (zoomFactor*100.0 + 0.5)); XtSetValues(zoomDown.enable_widget, &arg, 1); }