/* * Copyright (c) 1994, Riley Rainey, riley@netcon.com * * Permission to use, copy, modify and distribute (without charge) this * software, documentation, images, etc. is granted, provided that this * comment and the author's name is retained. * * This software is provided by the author as is, and without any expressed * or implied warranties, including, but not limited to, the implied * warranties of merchantability and fitness for a particular purpose. In no * event shall the author be liable for any direct, indirect, incidental, or * consequential damages arising in any way out of the use of this software. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define DEFINE_STORAGE #include "gedit.h" #include "XrMisc.h" #include "curs_poly" #include "curs_poly_mask" #include "curs_marker" #include "curs_marker_mask" static unsigned char grid_dash_list[2] = { 1, 4 }; static XmStringCharSet charset = (XmStringCharSet) XmSTRING_DEFAULT_CHARSET; /* * fallback resources */ static String fallback[] = { "*.Background: GhostWhite", "*buttons*highlightColor: GhostWhite", "*.fontList: -*-helvetica-medium-r-*-*-*-140-*", "*.rulerFont: -*-courier-bold-r-*-*-*-140-*", "*XmTextField.fontList: -*-courier-medium-r-*-*-*-140-*", "*XmPushButton.shadowThickness: 3", "*XmDrawingArea.traversalOn: false", "*.menu_bar*Background: #4af", "*.menu_bar.spacing: 10", "*.top_frame.shadowType: XmSHADOW_ETCHED_OUT", "*.bottom_frame.shadowType: XmSHADOW_ETCHED_OUT", "*.twindow.background: #d8d8d8", "*.twindow.foreground: black", "*.bwindow.background: #e1caac", "*.bwindow.foreground: black", "*.main.form.height: 950", "*.main.form.width: 950", "*set_views.labelString: Set Views ...", "*mirror_xz.labelString: Mirror left/right", "*mirror_xz.acceleratorText: Alt-L", "*mirror_xz.accelerator: Metal:", "*mirror_xz.mnemonic: l", "*mirror_xy.labelString: Mirror top/bottom", "*mirror_xy.acceleratorText: Alt-T", "*mirror_xy.accelerator: Metat:", "*mirror_xy.mnemonic: t", "*mirror_yz.labelString: Mirror front/back", "*mirror_yz.acceleratorText: Alt-F", "*mirror_yz.accelerator: Metaf:", "*mirror_yz.mnemonic: f", "*rescale.labelString: Rescale Object ...", "*rescale.mnemonic: R", "*info.labelString: Aircraft Information ...", "*gear.labelString: Landing Gear ...", "*stability.labelString: Stability Derivatives ...", "*powerplant.labelString: Powerplant ...", "*rescale_dialog.dialogTitle: Rescale Object", "*open_d.dialogTitle: Open a File", "*open_d.okLabelString: Open", "*open_d.selectionLabelString: Open which file?", "*open_d.autoUnmanage: true", "*open_d*pattern: *.gdf", "*save_as_d.dialogTitle: Save Work", "*save_as_d.selectionLabelString: File name:", "*save_as_d.okLabelString: Save", "*save_as_d.*.fontList: -*-helvetica-medium-r-*-*-*-120-*", "*gedit_format.labelString: Gedit format", "*gedit_format.set: true", "*v_format.labelString: V format", "*rayshade_format.labelString: ACM Inventory format", "*show_grid.visibleWhenOff: true", "*show_ruler.visibleWhenOff: true", "*coodinates*columns: 8", "*coodinates*sensitive: false", "*new.labelString: New", "*open.labelString: Open ...", "*save.labelString: Save", "*save_as.labelString: Save As ...", "*exit.labelString: Exit", "*new.acceleratorText: Alt-N", "*new.accelerator: Metan:", "*new.mnemonic: N", "*open.acceleratorText: Alt-O", "*open.accelerator: Metao:", "*open.mnemonic: O", "*save.acceleratorText: Alt-S", "*save.accelerator: Metas:", "*save.mnemonic: S", "*save_as.mnemonic: A", "*exit.acceleratorText: Alt-E", "*exit.accelerator: Metae:", "*exit.mnemonic: E", "*cut.labelString: Cut", "*cut.acceleratorText: Shift-Del", "*cut.accelerator: ShiftDelete:", "*cut.mnemonic: t", "*copy.labelString: Copy", "*copy.acceleratorText: Ctrl-Ins", "*copy.accelerator: CtrlInsert:", "*copy.mnemonic: C", "*paste.labelString: Paste", "*paste.acceleratorText: Shift-Ins", "*paste.accelerator: ShiftInsert:", "*paste.mnemonic: P", "*clear.labelString: Clear", "*clear.mnemonic: e", "*rotx.labelString: Rotate 90 about X-Axis", "*info_dialog*XmLabelGadget.topOffset: 7", "*info_dialog*XmLabelGadget.rightOffset: 10", "*info_dialog*XmLabelGadget.leftOffset: 10", "*info_dialog*XmTextField.rightOffset: 10", "*gear_dialog*XmLabelGadget.topOffset: 7", "*gear_dialog*XmLabelGadget.rightOffset: 10", "*gear_dialog*XmLabelGadget.leftOffset: 10", "*gear_dialog*XmTextField.rightOffset: 10", "*powerplant_dialog*XmLabelGadget.topOffset: 7", "*powerplant_dialog*XmLabelGadget.rightOffset: 10", "*powerplant_dialog*XmLabelGadget.leftOffset: 10", "*powerplant_dialog*XmTextField.rightOffset: 10", "*stability_dialog*XmLabelGadget.topOffset: 7", "*stability_dialog*XmLabelGadget.rightOffset: 10", "*stability_dialog*XmLabelGadget.leftOffset: 10", "*stability_dialog*XmTextField.rightOffset: 10", "*stability_dialog*Calculate.sensitive: false", "*info_dialog*Calculate.sensitive: false", "*info_dialog*Calculate.sensitive: false", NULL }; static XrmOptionDescRec options[] = { {"-controllerClass", "*controllerClass", XrmoptionSepArg, "is"}, }; static XtResource resources[] = { { XtNselectionColor, XtCSelectionColor, XtRPixel, sizeof(Pixel), XtOffset(AppDataPtr, select_pixel), XtRString, (caddr_t) "firebrick" }, { XtNgridColor, XtCGridColor, XtRPixel, sizeof(Pixel), XtOffset(AppDataPtr, grid_pixel), XtRString, (caddr_t) "black" }, { XtNlineThickness, XtCLineThickness, XtRInt, sizeof(int), XtOffset(AppDataPtr, line_thickness), XtRImmediate, (caddr_t) 0 }, { XtNselectionThickness, XtCSelectionThickness, XtRInt, sizeof(int), XtOffset(AppDataPtr, selection_thickness), XtRImmediate, (caddr_t) 2 }, { XtNboxSize, XtCBoxSize, XtRInt, sizeof(int), XtOffset(AppDataPtr, box_size), XtRImmediate, (caddr_t) 5 }, { XtNpickSensitivity, XtCPickSensitivity, XtRInt, sizeof(int), XtOffset(AppDataPtr, pick_sensitivity), XtRImmediate, (caddr_t) 64 }, { XtNbuttonSize, XtCButtonSize, XtRInt, sizeof(int), XtOffset(AppDataPtr, button_size), XtRImmediate, (caddr_t) 32 }, { XtNcursorForeground, XtCCursorForeground, XtRPixel, sizeof(Pixel), XtOffset(AppDataPtr, cursor_foreground), XtRString, (caddr_t) "black" }, { XtNcursorBackground, XtCCursorBackground, XtRPixel, sizeof(Pixel), XtOffset(AppDataPtr, cursor_background), XtRString, (caddr_t) "white" }, { XtNshowGrid, XtCShowGrid, XmRBoolean, sizeof(Boolean), XtOffset(AppDataPtr, show_grid), XtRString, (caddr_t) "true" }, { XtNshowRuler, XtCShowRuler, XmRBoolean, sizeof(Boolean), XtOffset(AppDataPtr, show_ruler), XtRString, (caddr_t) "false" }, { XtNrulerFont, XtCFont, XtRFontStruct, sizeof(XFontStruct *), XtOffset(AppDataPtr, ruler_font), XtRString, (caddr_t) "fixed" } }; typedef struct { Boolean defined_in_this_version; Widget widget; char *name; char *pixmap_file; } button_list_t; button_list_t button_list[] = { { True, NULL, "point", "cursor_%d.xbm" }, { False, NULL, "hand", "hand_%d.xbm" }, { True, NULL, "polygon", "polygon_%d.xbm" }, { True, NULL, "circle", "circle_%d.xbm" }, { True, NULL, "origin", "origin_%d.xbm" }, { True, NULL, "zoom_out", "zoom_out_%d.xbm" }, { True, NULL, "zoom_in", "zoom_in_%d.xbm" } }; #define MAX_ARGS 16 #define APP_CLASS "Gedit" void QuitCB(), HelpCB(), ButtonCB(), WindowCB(); void MenuCB(), FileCB(), ViewCB(); void InitializeCursors(), SetCursor(); extern void InitializeTranslations(), DrawWidget(), ClearSelection(); extern void DetermineObjectExtent(); extern void CreateMarkerList(); Widget CreateHelp (), CreateViewsDialog(), CreateRescaleDialog(); Widget CreateInfoDialog(), CreateGearDialog(); Widget CreateDerivDialog(), CreatePowerplantDialog(); Widget help_box; Widget view_box = (Widget) NULL; static view_info_t t_info, b_info; main (argc, argv) int argc; char *argv[]; { Widget toplevel; Widget main_window; Widget menu_bar; Widget menu_pane; Widget button; Widget cascade; Widget top_frame, bottom_frame, main_form, row_col; Widget row_col1, form, index_form; int n, i; Arg args[16]; char name[128]; XmString label_string; XtAppContext context; static int tw = 1, bw = 2; Display *display; Pixmap pixmap; Pixel fg, bg; XGCValues gcv; XmString string; toplevel = XtAppInitialize (&context, APP_CLASS, options, XtNumber(options), &argc, argv, fallback, NULL, 0); XtGetApplicationResources (toplevel, &app_data, resources, XtNumber(resources), NULL, 0); n = 0; main_window = XmCreateMainWindow (toplevel, "main", args, n); XtManageChild (main_window); n = 0; menu_bar = XmCreateMenuBar (main_window, "menu_bar", args, n); XtManageChild (menu_bar); /* * The File menu */ n = 0; menu_pane = XmCreatePulldownMenu (menu_bar, "file_menu", args, n); n = 0; button = XmCreatePushButton (menu_pane, "new", args, n); XtManageChild (button); XtAddCallback (button, XmNactivateCallback, MenuCB, (XtPointer) MENU_NEW); n = 0; button = XmCreatePushButton (menu_pane, "open", args, n); XtManageChild (button); XtAddCallback (button, XmNactivateCallback, MenuCB, (XtPointer) MENU_OPEN); XmStringFree (string); n = 0; button = XmCreatePushButton (menu_pane, "save", args, n); XtManageChild (button); XtAddCallback (button, XmNactivateCallback, MenuCB, (XtPointer) MENU_SAVE); /* XmStringFree (string); */ n = 0; button = XmCreatePushButton (menu_pane, "save_as", args, n); XtManageChild (button); XtAddCallback (button, XmNactivateCallback, MenuCB, (XtPointer) MENU_SAVE_AS); n = 0; button = XmCreatePushButton (menu_pane, "exit", args, n); XtManageChild (button); XtAddCallback (button, XmNactivateCallback, QuitCB, NULL); n = 0; XtSetArg (args[n], XmNsubMenuId, menu_pane); n++; XtSetArg (args[n], XmNmnemonic, 'F'); n++; cascade = XmCreateCascadeButton (menu_bar, "File", args, n); XtManageChild (cascade); /* * The Edit menu */ n = 0; menu_pane = XmCreatePulldownMenu (menu_bar, "edit_menu", args, n); n = 0; button = XmCreatePushButton (menu_pane, "cut", args, n); XtManageChild (button); XtAddCallback (button, XmNactivateCallback, MenuCB, (XtPointer) MENU_CUT); n = 0; button = XmCreatePushButton (menu_pane, "copy", args, n); XtManageChild (button); XtAddCallback (button, XmNactivateCallback, MenuCB, (XtPointer) MENU_COPY); n = 0; button = XmCreatePushButton (menu_pane, "paste", args, n); XtManageChild (button); XtAddCallback (button, XmNactivateCallback, MenuCB, (XtPointer) MENU_PASTE); n = 0; button = XmCreateSeparator (menu_pane, "separator1", args, n); XtManageChild (button); n = 0; button = XmCreatePushButton (menu_pane, "clear", args, n); XtManageChild (button); XtAddCallback (button, XmNactivateCallback, MenuCB, (XtPointer) MENU_CLEAR); n = 0; button = XmCreateSeparator (menu_pane, "separator2", args, n); XtManageChild (button); n = 0; button = XmCreatePushButton (menu_pane, "rotx", args, n); XtManageChild (button); XtAddCallback (button, XmNactivateCallback, MenuCB, (XtPointer) MENU_ROTATE_X); n = 0; button = XmCreatePushButton (menu_pane, "mirror_xz", args, n); XtManageChild (button); XtAddCallback (button, XmNactivateCallback, MenuCB, (XtPointer) MENU_MIRROR_XZ); n = 0; button = XmCreatePushButton (menu_pane, "mirror_xy", args, n); XtManageChild (button); XtAddCallback (button, XmNactivateCallback, MenuCB, (XtPointer) MENU_MIRROR_XY); n = 0; button = XmCreatePushButton (menu_pane, "mirror_yz", args, n); XtManageChild (button); XtAddCallback (button, XmNactivateCallback, MenuCB, (XtPointer) MENU_MIRROR_YZ); n = 0; button = XmCreateSeparator (menu_pane, "separator", args, n); XtManageChild (button); n = 0; button = XmCreatePushButton (menu_pane, "rescale", args, n); XtManageChild (button); XtAddCallback (button, XmNactivateCallback, MenuCB, (XtPointer) MENU_RESCALE); n = 0; XtSetArg (args[n], XmNsubMenuId, menu_pane); n++; XtSetArg (args[n], XmNmnemonic, 'E'); n++; cascade = XmCreateCascadeButton (menu_bar, "Edit", args, n); XtManageChild (cascade); /* * The Layout menu */ n = 0; menu_pane = XmCreatePulldownMenu (menu_bar, "layout_menu", args, n); n = 0; string = XmStringCreateSimple ("Show Grid"); XtSetArg (args[n], XmNlabelString, string); n++; XtSetArg (args[n], XmNset, app_data.show_grid); n++; XtSetArg (args[n], XmNindicatorType, XmN_OF_MANY); n++; XtSetArg (args[n], XmNradioBehavior, False); n++; button = XmCreateToggleButton (menu_pane, "show_grid", args, n); XmStringFree (string); XtManageChild (button); XtAddCallback (button, XmNvalueChangedCallback, MenuCB, (XtPointer) MENU_GRID); n = 0; string = XmStringCreateSimple ("Show Ruler"); XtSetArg (args[n], XmNlabelString, string); n++; XtSetArg (args[n], XmNset, app_data.show_ruler); n++; XtSetArg (args[n], XmNindicatorType, XmN_OF_MANY); n++; XtSetArg (args[n], XmNradioBehavior, False); n++; button = XmCreateToggleButton (menu_pane, "show_ruler", args, n); XmStringFree (string); XtManageChild (button); XtAddCallback (button, XmNvalueChangedCallback, MenuCB, (XtPointer) MENU_RULER); n = 0; button = XmCreateSeparator (menu_pane, "separator", args, n); XtManageChild (button); n = 0; button = XmCreatePushButton (menu_pane, "set_views", args, n); XtManageChild (button); XtAddCallback (button, XmNactivateCallback, MenuCB, (XtPointer) MENU_SET_VIEWS); n = 0; XtSetArg (args[n], XmNsubMenuId, menu_pane); n++; XtSetArg (args[n], XmNmnemonic, 'L'); n++; cascade = XmCreateCascadeButton (menu_bar, "Layout", args, n); XtManageChild (cascade); CreateMarkerList (menu_bar); n = 0; XtSetArg (args[n], XmNmnemonic, 'H'); n++; cascade = XmCreateCascadeButton (menu_bar, "Help", args, n); XtManageChild (cascade); XtAddCallback (cascade, XmNactivateCallback, HelpCB, NULL); n = 0; XtSetArg (args[n], XmNmenuHelpWidget, cascade); n++; XtSetValues (menu_bar, args, n); /* * The Aircraft Performance menu */ n = 0; menu_pane = XmCreatePulldownMenu (menu_bar, "perf_menu", args, n); n = 0; button = XmCreatePushButton (menu_pane, "info", args, n); XtManageChild (button); XtAddCallback (button, XmNactivateCallback, MenuCB, (XtPointer) MENU_INFO); n = 0; button = XmCreatePushButton (menu_pane, "gear", args, n); XtManageChild (button); XtAddCallback (button, XmNactivateCallback, MenuCB, (XtPointer) MENU_GEAR); n = 0; button = XmCreatePushButton (menu_pane, "stability", args, n); XtManageChild (button); XtAddCallback (button, XmNactivateCallback, MenuCB, (XtPointer) MENU_DERIV); n = 0; button = XmCreatePushButton (menu_pane, "powerplant", args, n); XtManageChild (button); XtAddCallback (button, XmNactivateCallback, MenuCB, (XtPointer) MENU_PWR); n = 0; XtSetArg (args[n], XmNsubMenuId, menu_pane); n++; XtSetArg (args[n], XmNmnemonic, 'P'); n++; cascade = XmCreateCascadeButton (menu_bar, "Performance", args, n); XtManageChild (cascade); /* * The main window hierarchy */ main_form = XtVaCreateWidget ("form", xmFormWidgetClass, main_window, NULL); XtVaSetValues (main_window, XmNworkWindow, main_form, NULL); index_form = XtVaCreateWidget ("index", xmFormWidgetClass, main_form, XmNleftAttachment, XmATTACH_FORM, XmNtopAttachment, XmATTACH_FORM, XmNbottomAttachment, XmATTACH_FORM, NULL); row_col = XtVaCreateWidget ("buttons", xmRowColumnWidgetClass, index_form, XmNleftAttachment, XmATTACH_FORM, XmNtopAttachment, XmATTACH_FORM, NULL); XtVaGetValues (row_col, XmNforeground, &fg, XmNbackground, &bg, NULL); for (i=0; i < XtNumber(button_list); ++i) { if (button_list[i].defined_in_this_version) { sprintf (name, button_list[i].pixmap_file, app_data.button_size); pixmap = XmGetPixmap (XtScreen (row_col), name, fg, bg); button_list[i].widget = XtVaCreateManagedWidget ( button_list[i].name, xmPushButtonWidgetClass, row_col, XmNlabelType, XmPIXMAP, XmNlabelPixmap, pixmap, XmNwidth, 64, XmNheight, 64, XmNshadowType, XmSHADOW_ETCHED_OUT, NULL); XtAddCallback (button_list[i].widget, XmNactivateCallback, ButtonCB, (XtPointer) i); } } XtManageChild (row_col); row_col1 = XtVaCreateWidget ("coordinates", xmRowColumnWidgetClass, index_form, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, row_col, XmNbottomAttachment, XmATTACH_FORM, NULL); x_field = XtVaCreateManagedWidget("x", xmTextFieldWidgetClass, row_col1, XmNcolumns, 12, NULL); y_field = XtVaCreateManagedWidget("y", xmTextFieldWidgetClass, row_col1, XmNcolumns, 12, NULL); z_field = XtVaCreateManagedWidget("z", xmTextFieldWidgetClass, row_col1, XmNcolumns, 12, NULL); XtManageChild (row_col1); XtManageChild (index_form); top_frame = XtVaCreateManagedWidget ("top_frame", xmFrameWidgetClass, main_form, XmNtopAttachment, XmATTACH_FORM, XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, index_form, XmNrightAttachment, XmATTACH_FORM, XmNbottomAttachment, XmATTACH_POSITION, XmNbottomPosition, 50, NULL); twindow = XmCreateDrawingArea (top_frame, "twindow", args, n); XtAddCallback (twindow, XmNexposeCallback, WindowCB, (caddr_t) &tw); XtAddCallback (twindow, XmNinputCallback, WindowCB, (caddr_t) &tw); XtAddCallback (twindow, XmNresizeCallback, WindowCB, (caddr_t) &tw); XtManageChild (twindow); bottom_frame = XtVaCreateManagedWidget ("bottom_frame", xmFrameWidgetClass, main_form, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, top_frame, XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, index_form, XmNrightAttachment, XmATTACH_FORM, XmNbottomAttachment, XmATTACH_FORM, NULL); n = 0; bwindow = XmCreateDrawingArea (bottom_frame, "bwindow", args, n); XtAddCallback (bwindow, XmNexposeCallback, WindowCB, (caddr_t) &bw); XtAddCallback (bwindow, XmNinputCallback, WindowCB, (caddr_t) &bw); XtAddCallback (bwindow, XmNresizeCallback, WindowCB, (caddr_t) &bw); XtManageChild (bwindow); XtManageChild (main_form); InitializeTranslations (context, twindow, bwindow); /* * File dialogs */ n = 0; open_dialog = XmCreateFileSelectionDialog (toplevel, "open_d", args, n); XtAddCallback (open_dialog, XmNokCallback, FileCB, (XtPointer) MENU_OPEN); n = 0; save_as_dialog = XmCreatePromptDialog (toplevel, "save_as_d", args, n); XtAddCallback (save_as_dialog, XmNokCallback, FileCB, (XtPointer) MENU_SAVE_AS); n = 0; row_col = XmCreateRadioBox (save_as_dialog, "file_formats", args, n); XtManageChild (row_col); save_formats[0] = XtVaCreateManagedWidget ("gedit_format", xmToggleButtonWidgetClass, row_col, NULL); save_formats[1] = XtVaCreateManagedWidget ("v_format", xmToggleButtonWidgetClass, row_col, NULL); save_formats[2] = XtVaCreateManagedWidget ("rayshade_format", xmToggleButtonWidgetClass, row_col, NULL); set_views_dialog = CreateViewsDialog (toplevel); rescale_dialog = CreateRescaleDialog (toplevel); info_dialog = CreateInfoDialog(toplevel); gear_dialog = CreateGearDialog(toplevel); deriv_dialog = CreateDerivDialog(toplevel); powerplant_dialog = CreatePowerplantDialog(toplevel); /* * We logically cross-connect each of the two drawing areas with a data * structure that is hung off each widget's userData field. */ display = XtDisplay (twindow); t_info.flags = 0; t_info.other_view = &b_info; t_info.layout = VL_NXZ; t_info.other_widget = bwindow; t_info.other_window = XtWindow (bwindow); gcv.graphics_exposures = False; gcv.line_style = LineOnOffDash; gcv.font = app_data.ruler_font->fid; t_info.gc = XCreateGC (display, RootWindow(display, DefaultScreen(display)), GCGraphicsExposures | GCFont, &gcv); t_info.erase_gc = XCreateGC (display, RootWindow(display, DefaultScreen(display)), GCGraphicsExposures, &gcv); t_info.grid_gc = XCreateGC (display, RootWindow(display, DefaultScreen(display)), GCGraphicsExposures | GCLineStyle, &gcv); XSetDashes (display, t_info.grid_gc, 0, grid_dash_list, 2); XtVaSetValues (twindow, XmNuserData, &t_info, NULL); display = XtDisplay (twindow); b_info.flags = 0; b_info.other_view = &t_info; b_info.layout = VL_NXNY; b_info.other_widget = twindow; b_info.other_window = XtWindow (twindow); b_info.gc = XCreateGC (display, RootWindow(display, DefaultScreen(display)), GCGraphicsExposures | GCFont, &gcv); b_info.erase_gc = XCreateGC (display, RootWindow(display, DefaultScreen(display)), GCGraphicsExposures, &gcv); b_info.grid_gc = XCreateGC (display, RootWindow(display, DefaultScreen(display)), GCGraphicsExposures | GCLineStyle, &gcv); XSetDashes (display, b_info.grid_gc, 0, grid_dash_list, 2); XtVaSetValues (bwindow, XmNuserData, &b_info, NULL); help_box = CreateHelp (toplevel); edit_state = STATE_POINT; cur_polygon = (polygon_t *) NULL; polygon_max = 256; polygon_list = (polygon_t *) malloc (polygon_max * sizeof (polygon_t)); sel_polygon = unsel_polygon = clipboard_polygon = -1; drag_mode = False; for (i=0; iset == False) return; if (id == 0) desired_view = VIEW_LEFT_TOP; else desired_view = VIEW_FRONT_TOP; } void QuitCB (w, client_data, call_data) Widget w; caddr_t client_data; caddr_t call_data; { exit (0); } void HelpCB (w, client_data, call_data) Widget w; caddr_t client_data; caddr_t call_data; { XtManageChild (help_box); } void ButtonCB (w, client_data, call_data) Widget w; caddr_t client_data; caddr_t call_data; { switch ((int) client_data) { case 0: edit_state = STATE_POINT; SetCursor (CURSOR_POINT); break; case 1: break; case 2: edit_state = STATE_POLYGON; SetCursor (CURSOR_POLY); break; case 3: edit_state = STATE_CIRCLE; SetCursor (CURSOR_CIRCLE); break; case 4: edit_state = STATE_MOVE_ORIGIN; SetCursor (CURSOR_ORIGIN); break; case 5: RescaleView(twindow, 1 / 1.2); XmProcessTraversal (button_list[0].widget, XmTRAVERSE_CURRENT); edit_state = STATE_POINT; SetCursor (CURSOR_POINT); break; case 6: RescaleView(twindow, 1.2); XmProcessTraversal (button_list[0].widget, XmTRAVERSE_CURRENT); edit_state = STATE_POINT; SetCursor (CURSOR_POINT); break; default: printf ("button %d\n", (int) client_data); } } void MenuCB (w, client_data, call_data) Widget w; caddr_t client_data; caddr_t call_data; { register int menu_id = (int) client_data; extern void Mirror(); Boolean value; VPoint extent; XmString string; char s[64], *factor_s; double factor; if (menu_id >= MENU_MARKER && menu_id < MENU_MARKER+32) { current_marker = menu_id - MENU_MARKER; if (marker_list[current_marker].defined) DisplayPoint(&marker_list[current_marker].location); SetCursor (CURSOR_MARKER); edit_state = STATE_MARKER; return; } switch (menu_id) { case MENU_MIRROR_XZ: case MENU_MIRROR_XY: case MENU_MIRROR_YZ: Mirror (menu_id); break; case MENU_CLEAR: ClearSelection(); break; case MENU_COPY: CopySelection(); break; case MENU_PASTE: PasteSelection(); break; case MENU_ROTATE_X: RotateXSelection(); break; case MENU_SAVE: if (filename_valid) WriteGeditFile (filename); else XtManageChild (save_as_dialog); break; case MENU_GRID: XtVaGetValues (w, XmNset, &value, NULL); if (value != app_data.show_grid) { app_data.show_grid = value; DrawWidget (twindow, False); DrawWidget (bwindow, False); } else { app_data.show_grid = value; } break; case MENU_RULER: XtVaGetValues (w, XmNset, &value, NULL); if (value != app_data.show_ruler) { app_data.show_ruler = value; DrawWidget (twindow, False); DrawWidget (bwindow, False); } else { app_data.show_ruler = value; } break; case MENU_OPEN: XtManageChild (open_dialog); break; case MENU_SAVE_AS: XtManageChild (save_as_dialog); break; case MENU_SET_VIEWS: XtManageChild (set_views_dialog); break; case MENU_SET_VIEWS_COMPLETE: switch (desired_view) { case VIEW_LEFT_TOP: t_info.layout = VL_NXZ; b_info.layout = VL_NXNY; break; case VIEW_FRONT_TOP: t_info.layout = VL_NYZ; b_info.layout = VL_NYX; break; } RescaleView (twindow, 1.0); XtUnmanageChild (set_views_dialog); break; case MENU_SET_VIEWS_CANCEL: XtUnmanageChild (set_views_dialog); break; case MENU_RESCALE: DetermineObjectExtent (&extent); sprintf (s, " %s : %f", "X", extent.x); string = XmStringCreateSimple(s); XtVaSetValues (extent_x, XmNlabelString, string, NULL); XmStringFree (string); sprintf (s, " %s : %f", "Y", extent.y); string = XmStringCreateSimple(s); XtVaSetValues (extent_y, XmNlabelString, string, NULL); XmStringFree (string); sprintf (s, " %s : %f", "Z", extent.z); string = XmStringCreateSimple(s); XtVaSetValues (extent_z, XmNlabelString, string, NULL); XmStringFree (string); XtManageChild (rescale_dialog); break; case MENU_RESCALE_APPLY: factor_s = XmTextFieldGetString (rescale_field); factor = atof(factor_s); if (factor != 0.0) RescaleObject (factor); break; case MENU_RESCALE_CANCEL: XtUnmanageChild (rescale_dialog); break; case MENU_GEAR: XtManageChild (gear_dialog); break; case MENU_GEAR_CANCEL: GetCraftInfo (&c); XtUnmanageChild (gear_dialog); break; case MENU_GEAR_CALCULATE: GearCalculate (&c); GetCraftInfo (&c); break; case MENU_INFO: XtManageChild (info_dialog); break; case MENU_INFO_CANCEL: GetCraftInfo (&c); XtUnmanageChild (info_dialog); break; case MENU_INFO_CALCULATE: GetCraftInfo (&c); break; case MENU_DERIV: XtManageChild (deriv_dialog); break; case MENU_DERIV_CANCEL: GetCraftInfo (&c); XtUnmanageChild (deriv_dialog); break; case MENU_DERIV_CALCULATE: GetCraftInfo (&c); break; case MENU_PWR: XtManageChild (powerplant_dialog); break; case MENU_PWR_CANCEL: GetCraftInfo (&c); XtUnmanageChild (powerplant_dialog); break; case MENU_PWR_CALCULATE: GetCraftInfo (&c); break; } } void FileCB (w, client_data, call_data) Widget w; caddr_t client_data; caddr_t call_data; { register int menu_id = (int) client_data, i; register XmSelectionBoxCallbackStruct *p = (XmSelectionBoxCallbackStruct *) call_data; char *value; Boolean state; extern int ReadGeditFile(), WriteGeditFile(); XmStringGetLtoR (p->value, charset, &value); switch (menu_id) { case MENU_OPEN: ReadGeditFile (value); break; case MENU_SAVE_AS: for (i=0; i < 3; ++i) { XtVaGetValues (save_formats[i], XmNset, &state, NULL); if (state) { switch (i) { case 0: WriteGeditFile (value); break; case 1: WriteVFile (value); break; } break; } } break; } strcpy (filename, value); filename_valid = True; XtFree (value); } void AllocPixmap (w, width, height) Widget w; Dimension width, height; { Pixel bg; view_info_t *p; Display *d; int depth; d = XtDisplay (w); XtVaGetValues (w, XmNbackground, &bg, XmNuserData, &p, XmNdepth, &depth, NULL); if (p->flags & VI_PIXMAP_ALLOCATED) XFreePixmap (d, p->pixmap); p->pixmap = XCreatePixmap (d, RootWindow (d, DefaultScreen(d)), width, height, depth); XSetForeground (d, p->erase_gc, bg); XSetLineAttributes (d, p->erase_gc, app_data.selection_thickness, LineSolid, CapButt, JoinMiter); XFillRectangle (d, p->pixmap, p->erase_gc, 0, 0, width, height); p->width = width; p->height = height; p->flags |= VI_PIXMAP_ALLOCATED; } void WindowCB (w, client_data, call_data) Widget w; caddr_t client_data; caddr_t call_data; { register XmDrawingAreaCallbackStruct *q; view_info_t *p; q = (XmDrawingAreaCallbackStruct *) call_data; XtVaGetValues (w, XmNuserData, &p, NULL); switch (q->reason) { case XmCR_EXPOSE: if ((p->flags & VI_PIXMAP_ALLOCATED) == 0) { XtVaGetValues (w, XmNwidth, &p->width, XmNheight, &p->height, NULL); AllocPixmap (w, p->width, p->height); } XCopyArea (XtDisplay(w), p->pixmap, XtWindow(w), p->gc, 0, 0, p->width, p->height, 0, 0); break; case XmCR_RESIZE: XtVaGetValues (w, XmNwidth, &p->width, XmNheight, &p->height, NULL); AllocPixmap (w, p->width, p->height); p->origin_x = (p->width + 1) / 2; p->origin_y = (p->height + 1) / 2; DrawWidget (w, False); break; } } void InitializeCursors() { unsigned long fg = 1, bg = 0; XColor colors[2]; Drawable d; Display *dpy; Pixmap source, mask; Colormap cmap; dpy = XtDisplay (twindow); d = RootWindow(dpy, DefaultScreen(dpy)); XtVaGetValues (twindow, XmNcolormap, &cmap, NULL); cursors[CURSOR_POINT] = XCreateFontCursor (dpy, XC_left_ptr); source = XCreatePixmapFromBitmapData (dpy, d, curs_poly_bits, curs_poly_width, curs_poly_height, fg, bg, 1); mask = XCreatePixmapFromBitmapData (dpy, d, curs_poly_mask_bits, curs_poly_width, curs_poly_height, fg, bg, 1); colors[0].pixel = app_data.cursor_foreground; colors[1].pixel = app_data.cursor_background; XQueryColors (dpy, cmap, colors, 2); cursors[CURSOR_POLY] = XCreatePixmapCursor (dpy, source, mask, &colors[0], &colors[1], curs_poly_x_hot, curs_poly_y_hot); XFreePixmap (dpy, source); XFreePixmap (dpy, mask); source = XCreatePixmapFromBitmapData (dpy, d, curs_marker_bits, curs_marker_width, curs_marker_height, fg, bg, 1); mask = XCreatePixmapFromBitmapData (dpy, d, curs_marker_mask_bits, curs_marker_width, curs_marker_height, fg, bg, 1); cursors[CURSOR_MARKER] = XCreatePixmapCursor (dpy, source, mask, &colors[0], &colors[1], curs_marker_x_hot, curs_marker_y_hot); XFreePixmap (dpy, source); XFreePixmap (dpy, mask); cursors[CURSOR_ORIGIN] = XCreateFontCursor (dpy, XC_crosshair); } void SetCursor (id) int id; { Cursor cursor; switch (id) { case CURSOR_POINT: cursor = cursors[CURSOR_POINT]; break; case CURSOR_POLY_PLANE: cursor = cursors[CURSOR_POLY]; break; case CURSOR_CIRCLE: case CURSOR_POLY: cursor = cursors[CURSOR_POLY]; break; case CURSOR_ORIGIN: cursor = cursors[CURSOR_ORIGIN]; break; case CURSOR_MARKER: cursor = cursors[CURSOR_MARKER]; break; } XDefineCursor (XtDisplay(twindow), XtWindow(twindow), cursor); XDefineCursor (XtDisplay(bwindow), XtWindow(bwindow), cursor); }