diff options
author | Ruben Undheim <ruben.undheim@gmail.com> | 2018-10-20 17:43:57 +0200 |
---|---|---|
committer | Ruben Undheim <ruben.undheim@gmail.com> | 2018-10-20 17:43:57 +0200 |
commit | 04d5d0ea0f65a434e568fe031f6396caec9b3a8d (patch) | |
tree | decc35c37120084c4a55311cb4e801524369ff57 /help.c |
Import Upstream version 3.8.78.dfsg
Diffstat (limited to 'help.c')
-rw-r--r-- | help.c | 514 |
1 files changed, 514 insertions, 0 deletions
@@ -0,0 +1,514 @@ +/*----------------------------------------------------------------------*/ +/* Copyright (c) 2002 Tim Edwards, Johns Hopkins University */ +/*----------------------------------------------------------------------*/ + +/*----------------------------------------------------------------------*/ +/* Spun off from xcircuit.c 10/4/98 */ +/* Functionality will not be expanded in the Xt version. All new */ +/* capabilities will be developed in the TCL version of help. */ +/*----------------------------------------------------------------------*/ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +#ifndef XC_WIN32 +#include <X11/Intrinsic.h> +#include <X11/StringDefs.h> +#include <X11/Shell.h> +#endif + +#ifdef TCL_WRAPPER +#include <tk.h> +#else +#ifndef XC_WIN32 +#include "Xw/Xw.h" +#include "Xw/Form.h" +#include "Xw/WorkSpace.h" +#include "Xw/MenuBtn.h" +#endif +#endif + +/*----------------------------------------------------------------------*/ +/* Local includes */ +/*----------------------------------------------------------------------*/ + +#include "colordefs.h" +#include "xcircuit.h" +#include "menudep.h" + +/*----------------------------------------------------------------------*/ +/* Function prototype declarations */ +/*----------------------------------------------------------------------*/ +#include "prototypes.h" + +/*----------------------------------------------------------------------*/ +/* Global Variable definitions */ +/*----------------------------------------------------------------------*/ + +#ifdef TCL_WRAPPER +extern Tcl_Interp *xcinterp; +#endif + +#ifndef TCL_WRAPPER + +extern Display *dpy; +extern GC hgc; +extern XCWindowData *areawin; +extern ApplicationData appdata; +extern int *appcolors; +extern xcWidget top; +extern short popups; +extern xcWidget menuwidgets[]; +extern char *function_names[NUM_FUNCTIONS]; + +Pixmap helppix = (Pixmap)NULL; /* For help window */ +Dimension helpwidth, helpheight, hheight; +int helptop; +short help_up; + +/*-----------------------------------------*/ +/* Print help list into a pixmap */ +/* Return width and height of map through */ +/* global variables helpwidth, helpheight. */ +/*-----------------------------------------*/ + +typedef struct { + int function; + char *text; +} helpstruct; + +void printhelppix() +{ + static char *helptitle = "Macro Key Binding Summary:"; + static helpstruct helptext[] = { + { XCF_Finish, "Finish"}, + { XCF_Cancel, "Cancel"}, + { XCF_Zoom_In, "Zoom in 3/2"}, + { XCF_Zoom_Out, "Zoom out 3/2"}, + { XCF_Pan, "Pan (various modes)"}, + { XCF_Double_Snap, "Double snap-to spacing"}, + { XCF_Halve_Snap, "Halve snap-to spacing"}, + { XCF_Next_Library, "Go To Next Library"}, + { XCF_Library_Pop, "Return from Library"}, + { XCF_Push, "Push object"}, + { XCF_Pop, "Pop object"}, + { XCF_Redraw, "Refresh screen"}, + { XCF_Page, "Go To Page"}, + { XCF_Write, "Popup Output dialog"}, +#ifdef HAVE_PYTHON + { XCF_Prompt, "Python Command entry"}, +#else + { XCF_Prompt, "Command entry"}, +#endif + { XCF_Exit, "Quit XCircuit"}, + { XCF_SPACER, NULL}, + { XCF_Wire, "Begin Polygon"}, + { XCF_Box, "Begin Box"}, + { XCF_Arc, "Begin Arc"}, + { XCF_Text, "Begin Text"}, + { XCF_Spline, "Begin Spline"}, + { XCF_Select_Save, "Make object"}, + { XCF_Virtual, "Make library instance"}, + { XCF_Join, "Join elements (make path)"}, + { XCF_Unjoin, "Un-join elements"}, + { XCF_Dot, "Place a dot"}, + { XCF_SPACER, NULL}, + { XCF_Delete, "Delete"}, + { XCF_Undo, "Undo"}, + { XCF_Redo, "Redo"}, + { XCF_Select, "Select"}, + { XCF_Unselect, "Deselect"}, + { XCF_Copy, "Copy"}, + { XCF_Edit, "Edit"}, + { XCF_SPACER, NULL}, + { XCF_Rotate, "Rotate"}, + { XCF_Flip_X, "Flip horizontally"}, + { XCF_Flip_Y, "Flip vertically"}, + { XCF_Snap, "Snap to grid"}, + { XCF_Attach, "Attach to"}, + { XCF_Dashed, "Dashed line style"}, + { XCF_Dotted, "Dotted line style"}, + { XCF_Solid, "Solid line style"}, + { XCF_SPACER, NULL}, + { XCF_Justify, "Text Justification"}, + { XCF_Superscript, "Text Superscript"}, + { XCF_Subscript, "Text Subscript"}, + { XCF_Font, "Toggle text font"}, + { XCF_Boldfont, "Begin Bold text"}, + { XCF_Italicfont, "Begin Italic text"}, + { XCF_Normalfont, "Resume normal text"}, + { XCF_ISO_Encoding, "Begin Latin-1 encoding"}, + { XCF_Overline, "Begin text overline"}, + { XCF_Underline, "Begin text underline"}, + { XCF_Parameter, "Insert parameter"}, + { XCF_Halfspace, "Insert half-space"}, + { XCF_Quarterspace, "Insert quarter-space"}, + { XCF_Linebreak, "Insert return character"}, + { XCF_Special, "Insert special character"}, + { XCF_TabStop, "Set tab stop"}, + { XCF_TabForward, "Forward tab"}, + { XCF_TabBackward, "Backward tab"}, + { XCF_Text_Home, "Go to label beginning"}, + { XCF_Text_End, "Go to label end"}, + { XCF_Text_Left, "Move left one position"}, + { XCF_Text_Right, "Move right one position"}, + { XCF_Text_Up, "Move up one line"}, + { XCF_Text_Down, "Move down one line"}, + { XCF_Text_Delete, "Delete character(s)"}, + { XCF_Text_Return, "End text edit"}, + { XCF_Text_Split, "Split label at cursor"}, + { XCF_SPACER, NULL}, + { XCF_Edit_Next, "Edit: next position"}, + { XCF_Edit_Delete, "Edit: delete point"}, + { XCF_Edit_Insert, "Edit: insert point"}, + { XCF_Edit_Param, "Edit: insert parameter"}, + { XCF_SPACER, NULL}, + { XCF_Library_Edit, "Library: name edit"}, + { XCF_Library_Move, "Library: move object/page"}, + { XCF_Library_Delete, "Library: object delete"}, + { XCF_Library_Hide, "Library: hide object"}, + { XCF_Library_Duplicate, "Library: copy object"}, + { XCF_Library_Virtual, "Library: copy instance"}, + { XCF_SPACER, NULL}, + { XCF_Pin_Label, "Make Pin Label"}, + { XCF_Pin_Global, "Make Global Pin"}, + { XCF_Info_Label, "Make Info Label"}, + { XCF_Swap, "Go to Symbol or Schematic"}, + { XCF_Connectivity, "See net connectivity"}, + { XCF_Sim, "Generate Sim netlist"}, + { XCF_SPICE, "Generate SPICE netlist"}, + { XCF_SPICEflat, "Generate flattened SPICE"}, + { XCF_PCB, "Generate PCB netlist"}, + { XCF_ENDDATA, NULL}, + }; + + XGCValues values; + Window hwin = DefaultRootWindow(dpy); + Dimension htmp, vtmp, lineheight, mwidth; + int i, j, t1, t2, dum, numlines; + XCharStruct csdum; + char *bindings, *bptr, *cptr; + + if (hwin == 0) return; + + /* Set up the GC for drawing to the help window pixmap */ + + if (hgc == NULL) { + values.foreground = FOREGROUND; + values.background = BACKGROUND; + values.graphics_exposures = False; + values.font = appdata.helpfont->fid; + hgc = XCreateGC(dpy, hwin, GCForeground | GCBackground | GCFont + | GCGraphicsExposures, &values); + } + + /* Determine the dimensions of the help text */ + + mwidth = helpwidth = lineheight = numlines = 0; + + for (i = 0; helptext[i].function != XCF_ENDDATA; i++) { + if (helptext[i].function == XCF_SPACER) { + numlines++; + continue; + } + + htmp = XTextWidth(appdata.helpfont, helptext[i].text, strlen(helptext[i].text)); + if (htmp > mwidth) mwidth = htmp; + + XTextExtents(appdata.helpfont, helptext[i].text, strlen(helptext[i].text), + &dum, &t1, &t2, &csdum); + vtmp = t1 + t2 + 5; + if (vtmp > lineheight) lineheight = vtmp; + + bindings = function_binding_to_string(0, helptext[i].function); + + /* Limit list to three key bindings per line */ + bptr = bindings; + while (bptr != NULL) { + cptr = bptr; + for (j = 0; j < 3; j++) { + cptr = strchr(cptr + 1, ','); + if (cptr == NULL) break; + } + if (cptr != NULL) *(++cptr) = '\0'; + + htmp = XTextWidth(appdata.helpfont, bptr, strlen(bptr)); + if (htmp > helpwidth) helpwidth = htmp; + + XTextExtents(appdata.helpfont, bptr, strlen(bptr), + &dum, &t1, &t2, &csdum); + vtmp = t1 + t2 + 5; + if (vtmp > lineheight) lineheight = vtmp; + numlines++; + + if (cptr == NULL) break; + bptr = cptr + 1; + } + free(bindings); + } + XTextExtents(appdata.helpfont, helptitle, strlen(helptitle), &dum, &t1, + &t2, &csdum); + t1 += t2; + helpwidth += mwidth + 15; + + helpheight = lineheight * numlines + 15 + t1; /* full height of help text */ + if (helppix != (Pixmap)NULL) { + Wprintf("Error: Help window not cancelled?"); + return; + } + helppix = XCreatePixmap(dpy, hwin, helpwidth, helpheight, + DefaultDepthOfScreen(DefaultScreenOfDisplay(dpy))); + + XSetForeground(dpy, hgc, FOREGROUND); + XFillRectangle(dpy, helppix, hgc, 0, 0, helpwidth, helpheight); + + XSetForeground(dpy, hgc, BACKGROUND); + XDrawString(dpy, helppix, hgc, (helpwidth - XTextWidth(appdata.helpfont, + helptitle, strlen(helptitle))) >> 1, t1 + 2, helptitle, strlen(helptitle)); + vtmp = lineheight + 15; + for (i = 0; helptext[i].function != XCF_ENDDATA; i++) { + if (helptext[i].function == XCF_SPACER) { + vtmp += lineheight; + continue; + } + XDrawString(dpy, helppix, hgc, 7, vtmp, helptext[i].text, + strlen(helptext[i].text)); + bindings = function_binding_to_string(0, helptext[i].function); + bptr = bindings; + while (bptr != NULL) { + cptr = bptr; + for (j = 0; j < 3; j++) { + cptr = strchr(cptr + 1, ','); + if (cptr == NULL) break; + } + if (cptr != NULL) *(++cptr) = '\0'; + XDrawString(dpy, helppix, hgc, 7 + mwidth, vtmp, bptr, strlen(bptr)); + vtmp += lineheight; + if (cptr == NULL) break; + bptr = cptr + 1; + } + free(bindings); + } + XSetForeground(dpy, hgc, AUXCOLOR); + XDrawLine(dpy, helppix, hgc, 0, t1 + 7, helpwidth, t1 + 7); +} + +/*----------------------------------------------*/ +/* Create the help popup window (Xt version) */ +/*----------------------------------------------*/ + +#ifndef XC_WIN32 + +void starthelp(xcWidget button, caddr_t clientdata, caddr_t calldata) +{ + Arg wargs[11]; + xcWidget popup, cancelbutton, hspace, help2, hsb; + short n = 0; + popupstruct *okaystruct; + buttonsave *savebutton; + Dimension areawidth, bwidth, pheight; + Position xpos, ypos; + u_int xmax, ymax; + + if (help_up) return; /* no multiple help windows */ + + /* for positioning the help window outside of the xcircuit */ + /* window, get information about the display width and height */ + /* and the xcircuit window. */ + + /* The "- 50" leaves space for the Windows-95-type title bar that */ + /* runs across the bottom of the screen in some window managers */ + /* (specifically, fvwm95 which is the default for RedHat Linux) */ + + xmax = DisplayWidth(dpy, DefaultScreen(dpy)) - 100; + ymax = DisplayHeight(dpy, DefaultScreen(dpy)) - 50; + + XtnSetArg(XtNwidth, &areawidth); + XtGetValues(areawin->area, wargs, n); n = 0; + XtTranslateCoords(areawin->area, (Position) (areawidth + 10), -50, + &xpos, &ypos); + + /* Always direct the call to the main menu button. */ + button = OptionsHelpButton; + + savebutton = getgeneric(button, starthelp, NULL); + + /* Generate the pixmap and write the help text to it */ + + if (helppix == (Pixmap)NULL) printhelppix(); + + /* Use the pixmap size to size the help window */ + + if (xpos + helpwidth + SBARSIZE > xmax) xpos = xmax - helpwidth - SBARSIZE - 4; + if (ypos + helpheight > ymax) ypos = ymax - helpheight - 4; + if (ypos < 4) ypos = 4; + + XtnSetArg(XtNx, xpos); + XtnSetArg(XtNy, ypos); + popup = XtCreatePopupShell("help", transientShellWidgetClass, + button, wargs, n); n = 0; + popups++; + help_up = True; + helptop = 0; + + XtnSetArg(XtNyResizable, True); + XtnSetArg(XtNxResizable, False); + help2 = XtCreateManagedWidget("help2", XwformWidgetClass, + popup, wargs, n); n = 0; + + XtnSetArg(XtNfont, appdata.xcfont); + cancelbutton = XtCreateManagedWidget("Dismiss", XwmenuButtonWidgetClass, + help2, wargs, n); n = 0; + + XtnSetArg(XtNwidth, helpwidth); + XtnSetArg(XtNheight, areawin->height); + XtnSetArg(XtNyRefWidget, cancelbutton); + XtnSetArg(XtNyAddHeight, True); + XtnSetArg(XtNyAttachBottom, True); + XtnSetArg(XtNyResizable, True); + XtnSetArg(XtNborderWidth, 0); + XtnSetArg(XtNxAttachRight, False); + hspace = XtCreateManagedWidget("HSpace", XwworkSpaceWidgetClass, + help2, wargs, n); n = 0; + + /* Create scrollbar */ + XtnSetArg(XtNwidth, SBARSIZE); + XtnSetArg(XtNxRefWidget, hspace); + XtnSetArg(XtNxAddWidth, True); + XtnSetArg(XtNyRefWidget, cancelbutton); + XtnSetArg(XtNyAddHeight, True); + XtnSetArg(XtNyResizable, True); + XtnSetArg(XtNyAttachBottom, True); + XtnSetArg(XtNborderWidth, 1); + hsb = XtCreateManagedWidget("HSB", XwworkSpaceWidgetClass, + help2, wargs, n); n = 0; + + okaystruct = (popupstruct *) malloc(sizeof(popupstruct)); + okaystruct->buttonptr = savebutton; + okaystruct->popup = popup; + okaystruct->filter = NULL; + + XtPopup(popup, XtGrabNone); + + /* reposition the "Dismiss" button to center */ + + XtSetArg(wargs[0], XtNwidth, &bwidth); + XtGetValues(cancelbutton, wargs, 1); + XtnSetArg(XtNx, ((helpwidth - bwidth) >> 1)); + XtSetValues(cancelbutton, wargs, n); n = 0; + + XtSetArg(wargs[0], XtNheight, &pheight); + XtGetValues(help2, wargs, 1); + + if (pheight > (ymax - 8)) { + XtnSetArg(XtNheight, ymax - 8); + XtSetValues(help2, wargs, n); n = 0; + } + + XtAddEventHandler(hsb, ButtonMotionMask | ButtonPressMask, False, + (XtEventHandler)simplescroll, hspace); + + /* Expose and End callbacks */ + + XtAddCallback(cancelbutton, XtNselect, (XtCallbackProc)destroypopup, okaystruct); + XtAddCallback(hspace, XtNexpose, (XtCallbackProc)exposehelp, NULL); + XtAddCallback(hsb, XtNexpose, (XtCallbackProc)showhsb, NULL); +} + +/*----------------------------------------------*/ +/* Very simple scroll mechanism (grab-and-pan) */ +/*----------------------------------------------*/ + +void simplescroll(xcWidget hsb, xcWidget hspace, XMotionEvent *event) +{ + Dimension oldtop = helptop; + + helptop = (((int)(event->y) * helpheight) / hheight) - (hheight / 2); + + if (helptop < 0) helptop = 0; + else if (helptop > helpheight - hheight) helptop = helpheight - hheight; + + if (helptop != oldtop) { + showhsb(hsb, NULL, NULL); + printhelp(hspace); + } +} + +/*----------------------------------------------*/ +/* Expose callback for the help scrollbar */ +/*----------------------------------------------*/ + +void showhsb(xcWidget hsb, caddr_t clientdata, caddr_t calldata) +{ + Window hwin = xcWindow(hsb); + Dimension sheight; + int pstart, pheight; + short n = 0; + + if (helppix == (Pixmap)NULL) printhelppix(); + if (helpheight == 0) helpheight = 1; + + pstart = (helptop * hheight) / helpheight; + pheight = (hheight * hheight) / helpheight; + + if (pheight < 3) pheight = 3; + + XClearArea(dpy, hwin, 0, 0, SBARSIZE, pstart, False); + XClearArea(dpy, hwin, 0, pstart + pheight, SBARSIZE, + hheight - (pstart + pheight), False); + + XSetForeground(dpy, hgc, BARCOLOR); + XFillRectangle(dpy, hwin, hgc, 0, pstart, SBARSIZE, pheight); +} + +/*----------------------------------------------*/ +/* Expose callback for the help window */ +/*----------------------------------------------*/ + +void exposehelp(xcWidget hspace, caddr_t clientdata, caddr_t calldata) +{ + Arg wargs[1]; + + XtSetArg(wargs[0], XtNheight, &hheight); + XtGetValues(hspace, wargs, 1); + + if (helppix == (Pixmap)NULL) printhelppix(); + if (hheight < 1) hheight = 1; + + printhelp(hspace); +} + +/*----------------------------------------------*/ +/* Expose callback for the help window */ +/*----------------------------------------------*/ + +void printhelp(xcWidget hspace) +{ + Window hwin = xcWindow(hspace); + XEvent discard; + + /* Draw the pixmap to the window */ + + XCopyArea(dpy, helppix, hwin, hgc, 0, helptop - 5, helpwidth, helpheight, + 0, 0); + + /* flush out multiple expose events */ + + while (XCheckWindowEvent(dpy, hwin, ExposureMask, &discard) == True); +} + +#endif + +/*----------------------------------------------------------------------*/ +/* The TCL version assumes the existence of command "helpwindow". */ +/*----------------------------------------------------------------------*/ + +#else + +void starthelp(xcWidget button, caddr_t clientdata, caddr_t calldata) +{ + Tcl_Eval(xcinterp, "catch xcircuit::helpwindow"); +} + +#endif /* !TCL_WRAPPER */ |