home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / x / xtici.zip / xtici / menu.c < prev    next >
C/C++ Source or Header  |  1991-08-28  |  30KB  |  1,043 lines

  1. /*
  2.  * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc.
  3.  *     All Rights Reserved
  4.  * 
  5.  * This file is a component of an X Window System client which uses the Xcms 
  6.  * Color Management System.  TekColor is a trademark of Tektronix, Inc.  The
  7.  * TekColor Editor is the subject of U.S. and foreign patents pending.  The
  8.  * term "TekHVC" designates a particular color space that is the subject of
  9.  * U.S. Patent No. 4,985,853 (equivalent foreign patents pending).
  10.  * Permission is hereby granted to use, copy, modify, sell, and otherwise
  11.  * distribute this software and its documentation for the X Window System
  12.  * environment, for any purpose and without fee, provided that:
  13.  * 
  14.  * 1.    The code and documentation are only used to implement a 
  15.  *      TekColor Editor in an X Window System environment; and
  16.  * 2.    This copyright and permission notice is reproduced in all copies
  17.  *     of the code and in supporting documentation.
  18.  * 
  19.  * Permission is granted to modify this code as required to allow it to
  20.  * be compiled on any host computer, provided that the functionality of
  21.  * the TekColor Editor is not modified in any way.  A description of any 
  22.  * modifications must be sent to Tektronix, Inc.  Contact 
  23.  * Tektronix Inc., P.O. Box 1000, Mail Station 60-850, 
  24.  * Network Displays Division Engineering, Wilsonville, OR 97070.
  25.  *
  26.  * Tektronix makes no representation about the suitability of this software
  27.  * for any purpose.  It is provided "as is" and with all faults.
  28.  * 
  29.  * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE,
  30.  * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
  31.  * PARTICULAR PURPOSE.  IN NO EVENT SHALL TEKTRONIX BE LIABLE FOR ANY
  32.  * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
  33.  * RESULTING FROM LOSS OF USE, DATA, OR PROFITS, WHETHER IN AN ACTION OF
  34.  * CONTRACT, NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  35.  * CONNECTION WITH THE USE OR THE PERFORMANCE OF THIS SOFTWARE.
  36.  * 
  37.  *    NAME
  38.  *        menu - create and manage menus
  39.  *
  40.  *    DESCRIPTION
  41.  *        Create the menubar, all pulldown and cascading menus,
  42.  *        buttons and dialogs, including help stuff.  Manage callbacks
  43.  *        invoked by menu choices.
  44.  */
  45. #ifndef LINT
  46. static char *copy_notice = "Copyright 1991 Tektronix, Inc.";
  47. #ifdef RCS_ID
  48. static char *rcsid=  "$Header: menu.c,v 1.3 91/08/28 10:02:26 adamsc Exp $";
  49. #endif /* RCS_ID */
  50. #endif /* LINT */
  51.  
  52. /*
  53.  *      EXTERNAL INCLUDES
  54.  */
  55.  
  56.  
  57. /*
  58.  *      INTERNAL INCLUDES
  59.  */
  60. #include "xtici.h"
  61. #include "constrain.off.bm"
  62. #include "constrain.on.bm"
  63.  
  64. #include <X11/Shell.h>
  65. #include <X11/Xaw/Box.h>
  66. #include <X11/Xaw/Command.h>
  67. #include <X11/Xaw/Form.h>
  68. #include <X11/Xaw/Label.h>
  69. #include <X11/Xmu/Misc.h>
  70. #include "widgets/xticiSD.h"
  71. #include "widgets/ColorSP.h"
  72.  
  73. /*
  74.  *      EXTERNS
  75.  */
  76.  
  77. /*
  78.  *      GLOBALS
  79.  */
  80. #ifdef DEC
  81. #  define GLOBAL    global
  82. #else
  83. #  define GLOBAL
  84. #endif
  85.  
  86. /* controls how/if chromas are restricted */
  87. GLOBAL int clampState = ClampMonitor;
  88.  
  89. /*
  90.  *      LOCAL DEFINES
  91.  */
  92. #define EditCopy    0
  93. #define EditPaste    1
  94.  
  95. #define EditOne        0
  96.  
  97. #define CopyHVC        0
  98. #define CopyRGB            1
  99. #define CopyuvY        2
  100.  
  101. #define OptionHue    0
  102. #define OptionLeaf    1
  103. #define OptionClamp    2
  104.  
  105. #define ViewCoord    0
  106.  
  107. #define ViewRGB        0
  108. #define ViewUVY        1
  109.  
  110. #define ImportPixel    0
  111. #define ExportPixel    1
  112.  
  113. #define HelpInterface    0
  114. #define HelpVersion    1
  115. #define HelpQuit    2
  116. #define HelpEdit    3
  117. #define HelpOptions    4
  118. #define HelpImport    5
  119. #define HelpExport    6
  120.  
  121. /*
  122.  *      LOCAL TYPEDEFS
  123.  */
  124.  
  125.  
  126. /*
  127.  *      LOCALS VARIABLES
  128.  */
  129. #ifdef DEBUG
  130. #  define STATIC
  131. #else
  132. #  define STATIC        static
  133. #endif
  134.  
  135. /* These are a series of popup menus that are needed */
  136. STATIC Widget coordmenu, copymenu, editmenu, helpmenu, optionmenu;
  137.  
  138. /* These widgets control which coordinate sets are viewed */
  139. STATIC Widget rgbCoord, uvyCoord;
  140.  
  141. /* These widgets are help dialogs */
  142. STATIC Widget ifHelp, versHelp, quitHelp;
  143. STATIC Widget editHelp, importHelp, optionHelp, exportHelp;
  144.  
  145. /* These are the routines that create them */
  146. STATIC void CreateHelpIf();
  147. STATIC void CreateHelpVersion();
  148. STATIC void CreateHelpQuit();
  149. STATIC void CreateHelpEdit();
  150. STATIC void CreateHelpOptions();
  151. STATIC void CreateHelpImport();
  152. STATIC void CreateHelpExport();
  153. STATIC void PlaceDropDownMenu();
  154. STATIC void PlaceCascadeMenu();
  155.  
  156. STATIC char *exitHelp = "\
  157. You have made some changes in the current colormap.  Those changes will not\n\
  158. be saved automatically when the program exits.  If you want to retain your\n\
  159. changes, cancel this operation and explicitly save the changed colormap.";
  160.  
  161. STATIC char *nograbHelp = "\
  162. In X, normally all pointer actions go to the window where the action occurs.\n\
  163. The editor \"grabs\" the pointer so that it can be used to identify the \n\
  164. object to act on from any window, and prevent any other window from seeing\n\
  165. that action.\n\
  166. This message was generated because the attempt to grab the pointer failed.\n\
  167. Normally this happens because some other client has already grabbed it.\n\
  168. Try to import again.  If you continue to see this message, try to determine\n\
  169. which client in your environment (maybe the window manager) has the pointer\n\
  170. grabbed.";
  171.  
  172.  
  173. /************************************************************************
  174.  *                                    *
  175.  *            PRIVATE ROUTINES                *
  176.  *                                    *
  177.  ************************************************************************/
  178. /* ARGSUSED */
  179. STATIC void Quit(w, pwhich, call)
  180. Widget w;
  181. XtPointer pwhich;
  182. XtPointer call;
  183. {
  184.     if (EditedMap(mapSize) && 
  185.     (Warning("Upon exit, current colormap changes will not be saved", 
  186.             exitHelp) == MessageCancel))
  187.     return;
  188.     exit(0);
  189. }
  190.  
  191. /* ARGSUSED */
  192. STATIC void HelpMenuPopup (w, pwhich, call)
  193. Widget w;
  194. XtPointer pwhich;
  195. XtPointer call;
  196. {
  197.     int which = (int)pwhich;
  198.     Widget help = NULL;
  199.  
  200.     XtPopdown (helpmenu);
  201.  
  202.     switch (which) {
  203.     case HelpInterface:
  204.     if (!ifHelp)
  205.         CreateHelpIf(w);
  206.     help = ifHelp;
  207.     break;
  208.     case HelpVersion:
  209.     if (!versHelp)
  210.         CreateHelpVersion(w);
  211.     help = versHelp;
  212.     break;
  213.     case HelpQuit:
  214.     if (!quitHelp)
  215.         CreateHelpQuit(w);
  216.     help = quitHelp;
  217.     break;
  218.     case HelpEdit:
  219.     if (!editHelp)
  220.         CreateHelpEdit(w);
  221.     help = editHelp;
  222.     break;
  223.     case HelpOptions:
  224.     if (!optionHelp)
  225.         CreateHelpOptions(w);
  226.     help = optionHelp;
  227.     break;
  228.     case HelpImport:
  229.     if (!importHelp)
  230.         CreateHelpImport(w);
  231.     help = importHelp;
  232.     break;
  233.     case HelpExport:
  234.     if (!exportHelp)
  235.         CreateHelpExport(w);
  236.     help = exportHelp;
  237.     break;
  238.      }
  239.  
  240.     if (help) {
  241.     XtPopup (help, XtGrabNonexclusive);
  242.     }
  243. }
  244.  
  245. STATIC void NewClampState(new, what)
  246. int new;
  247. int what;
  248. {
  249.     Pixel *indexes;
  250.     int i, ct;
  251.     XcmsColor color;
  252.  
  253.     clampState = new;
  254.  
  255.     /* apply new clamping to current colors */
  256.     indexes = EditingIndexes(&ct);
  257.     for (i = 0; i < ct; i++)
  258.     ConstrainColor(indexes[i]);
  259.     bcopy ((char *)¤tMap[currentIndex],(char *)&color,sizeof(XcmsColor));
  260.     NewColor(&color, what, ChromaChange);
  261. }
  262.  
  263. STATIC Pixmap bitmapOn, bitmapOff;  /* This is the bitmaps for clamp widget */
  264.  
  265. /* ARGSUSED */
  266. STATIC void OptionsClamp(w, pwhich, call)
  267. Widget w;
  268. XtPointer pwhich;
  269. XtPointer call;
  270. {
  271.     Arg args[1];
  272.     Pixel fore, back;
  273.     int state = (clampState == ClampNone ? ClampMonitor : ClampNone);
  274.  
  275.     XtPopdown (optionmenu);
  276.     NewClampState(state, MenuWidget);
  277.  
  278.     /* Update the widget to reflect new state by the foreground */
  279.     /* and background of the x */
  280.     if (state == ClampNone) 
  281.     XtSetArg(args[0], XtNbitmap, bitmapOff);
  282.     else
  283.     XtSetArg(args[0], XtNbitmap, bitmapOn);
  284.     XtSetValues(w, args, 1);
  285. }
  286.  
  287. /* ARGSUSED */
  288. STATIC void OptionsLeaf (w, pwhich, call)
  289. Widget w;
  290. XtPointer pwhich;
  291. XtPointer call;
  292. {
  293.     int state = (leafState == LeafEmpty ? LeafFilled : LeafEmpty);
  294.  
  295.     XtPopdown (optionmenu);
  296.     NewLeafState(state, MenuWidget);
  297. }
  298.  
  299. /* ARGSUSED */
  300. STATIC void OptionsHue (w, pwhich, call)
  301. Widget w;
  302. XtPointer pwhich;
  303. XtPointer call;
  304. {
  305.     int state = (huebarState == HuebarEmpty ? HuebarConstant : HuebarEmpty);
  306.  
  307.     XtPopdown (optionmenu);
  308.     NewHuebarState(state, MenuWidget);
  309. }
  310.  
  311. /*
  312.  * Coordinate displays are attached right-to-left, in the following order:
  313.  *  (patch) - u'v'Y - rgb - HVC - (form).
  314.  */
  315. /* ARGSUSED */
  316. void Coordinates (w, pwhich, call)
  317. Widget w;
  318. XtPointer pwhich;
  319. XtPointer call;
  320. {
  321.     int which = (int)pwhich;
  322.     int target;
  323.     void NewShow();
  324.  
  325.     XtPopdown (coordmenu);
  326.     XtPopdown (optionmenu);
  327.  
  328.     switch (which) {
  329.     case ViewRGB:
  330.     target = RgbWidget;
  331.     break;
  332.     case ViewUVY:
  333.     target = UvyWidget;
  334.     break;
  335.     }
  336.  
  337.     NewShow(target);
  338. }
  339.  
  340. extern void HandleColorCopy();
  341.  
  342. /* ARGSUSED */
  343. void Copy (w, pwhich, call)
  344. Widget w;
  345. XtPointer pwhich;
  346. XtPointer call;
  347. {
  348.     int which = (int)pwhich;
  349.     unsigned int format;
  350.  
  351.     XtPopdown (copymenu);
  352.     XtPopdown (editmenu);
  353.  
  354.     /* Must convert from HVC to what ever color is asked for here */
  355.     bcopy ((char *)¤tHvc, (char *)&clipColor, sizeof (XcmsColor));
  356.     switch (which) {
  357.     case CopyHVC:
  358.         format = XcmsTekHVCFormat;
  359.         break;
  360.     case CopyRGB:
  361.         format = XcmsRGBFormat;
  362.         break;
  363.     case CopyuvY:
  364.         format = XcmsCIEuvYFormat;
  365.         break;
  366.     default:
  367.         return;
  368.     }
  369.     if ((XcmsConvertColors (pDefaultCCC, &clipColor, 1, format, NULL))
  370.     == XcmsFailure) {
  371.     if (Warning("Could not convert to selected format", (char *)NULL)
  372.         != MessageContinue) {
  373.         return;
  374.     } 
  375.     bcopy ((char *)¤tHvc, (char *)&clipColor, sizeof (XcmsColor));
  376.     }
  377.     HandleColorCopy ();
  378. }
  379.  
  380. /* ARGSUSED */
  381. void Grab (w, pwhich, call)
  382. Widget w;
  383. XtPointer pwhich;
  384. XtPointer call;
  385. {
  386.     int which = (int)pwhich;
  387.     Window win = XtWindow(primary);
  388.  
  389.     /* Just use any visible widget for the grab window */
  390.     if (XGrabPointer(dpy, win, False, 
  391.             ButtonPressMask | ButtonReleaseMask,
  392.             GrabModeAsync, GrabModeAsync, 
  393.             None, grabCursor, CurrentTime)) {
  394.     InformMsg("Could not grab pointer", nograbHelp);
  395.     return;
  396.     }
  397.  
  398.     switch (which) {
  399.     case ImportPixel:
  400.     grabState = GrabUp | GrabPixel;
  401.     break;
  402.     case ExportPixel:
  403.     /* take the selection now, so it can be later exported */
  404.     if (!selectionMine)
  405.         TakeSelection();
  406.     grabState = GrabUp | GrabCell;
  407.     break;
  408.     }
  409. }
  410.  
  411. extern int HandleColorPaste ();
  412.  
  413. /* ARGSUSED */
  414. void Paste (w, pwhich, call)
  415. Widget w;
  416. XtPointer pwhich;
  417. XtPointer call;
  418. {
  419.     XtPopdown (editmenu);
  420.     /* get the pixel value of the current pixel in the patch */
  421.     clipColor.pixel = currentHvc.pixel;
  422.     HandleColorPaste (&clipColor);
  423. }
  424.  
  425. /* ARGSUSED */
  426. STATIC void KillWidget (w, pwhich, call)
  427. Widget w;
  428. XtPointer pwhich;
  429. XtPointer call;
  430. {
  431.     XtPopdown ((Widget)pwhich);
  432. }
  433.  
  434. /*ARGSUSED*/
  435. STATIC Widget CreateHelp(parent, title, message)
  436. Widget parent;
  437. String title;
  438. String message;
  439. {
  440.     Arg args[5];
  441.     int argCt;
  442.     Widget shell, form, help, ok;
  443.  
  444.     argCt = 0;
  445.     shell = XtCreatePopupShell("help_popup", transientShellWidgetClass, 
  446.                   primary, args, argCt);
  447.  
  448.     form = XtCreateManagedWidget("form", formWidgetClass, shell, NULL, 0);
  449.     
  450.     argCt = 0;
  451.     XtSetArg(args[argCt], XtNlabel, message);        argCt++;
  452.     XtSetArg(args[argCt], XtNjustify, XtJustifyLeft);    argCt++;
  453.     help = XtCreateManagedWidget(title, labelWidgetClass, form, args, argCt);
  454.  
  455.     argCt = 0;
  456.     XtSetArg(args[argCt], XtNlabel, "OK");        argCt++;
  457.     XtSetArg(args[argCt], XtNjustify, XtJustifyCenter);    argCt++;
  458.     XtSetArg(args[argCt], XtNfromVert, help);        argCt++;
  459.     ok = XtCreateManagedWidget(title, commandWidgetClass, form, args, argCt);
  460.     XtAddCallback (ok, XtNcallback, KillWidget, (XtPointer)shell);
  461.  
  462.     return(shell);
  463. }
  464.  
  465. STATIC void CreateHelpIf(parent)
  466. Widget parent;
  467. {
  468.     char *str = "\
  469. First choose a colormap entry to edit using either the\n\
  470. colormap control or by importing a pixel from another window.\n\
  471. Then modify hue using the vertical hue bar.  \n\
  472. Modify value and chroma using the leaf\n\
  473. to the right of the hue bar.\n\
  474. \n\
  475. Hue describes the color family, e.g., red, yellow, magenta.\n\
  476. It is a polar coordinate ranging from 0 (red) to 360 degrees.\n\
  477. \n\
  478. Value describes the lightness of the color,\n\
  479. ranging from 0 (black) to 100 (white).\n\
  480. \n\
  481. Chroma describes the vividness of the color.\n\
  482. The maximum chroma achievable for a given hue and value varies,\n\
  483. but 0 (gray) is always the minimum chroma.";
  484.  
  485.     ifHelp = CreateHelp(parent, "color editor interface help", str);
  486. }
  487.  
  488. STATIC void CreateHelpEdit(parent)
  489. Widget parent;
  490. {
  491.     char *str = "\
  492. Copy color copies the color description of the current color cell into a \n\
  493. public selection.  The use of the ICCCM selection mechanism for PRIMARY and\n\
  494. STRING allows this function to be used in copying and pasting color values.\n\
  495. \n\
  496. Paste copies the color description in the public selection \n\
  497. into the current color cell.  The use of the ICCCM selection mechanism \n\
  498. for PRIMARY and STRING allows this function selecting color values.";
  499.  
  500.     editHelp = CreateHelp(parent, "color editor Edit menu help", str);
  501. }
  502.  
  503. STATIC void CreateHelpExport(parent)
  504. Widget parent;
  505. {
  506.     char *str = "\
  507. Export the current color to another window.\n\
  508. \n\
  509. In X, it is not possible for the editor to directly modify a color of a\n\
  510. different window.  For the color to be exported, the program managing that\n\
  511. window must cooperate with the editor to change the color.  If the editor\n\
  512. detects that the client will not accept the requested change, a dialog\n\
  513. will appear explaining that the color cannot be exported.  Even if the\n\
  514. client accepts the new color from the editor, it is up to the client as to\n\
  515. how the new color will be used.";
  516.  
  517.     exportHelp = CreateHelp(parent, "color editor Export menu help", str);
  518. }
  519.  
  520. STATIC void CreateHelpQuit(parent)
  521. Widget parent;
  522. {
  523.     char *str = "Quit terminates the editor.";
  524.  
  525.     quitHelp = CreateHelp(parent, "color editor File menu help", str);
  526. }
  527.  
  528. STATIC void CreateHelpImport(parent)
  529. Widget parent;
  530. {
  531.     char *str = "\
  532. Import the color associated with a pixel from another window.\n\
  533. Any changes to that color cell will be lost.\n\
  534. When this option is chosen, the editor goes into a mode that allows\n\
  535. mouse input in any window to go to the editor - a grab.  Move the cursor\n\
  536. to any pixel on the screen and click the selection button.\n\
  537. The color cell being edited changes to match the chosen pixel.";
  538.  
  539.     importHelp = CreateHelp(parent, "color editor Import menu help", str);
  540. }
  541.  
  542. STATIC void CreateHelpOptions(parent)
  543. Widget parent;
  544. {
  545.     char *str = "\
  546. Fill hue bar controls the appearance of the hue bar.\n\
  547. Empty fills the bar in the background color.\n\
  548. Constant fills the bar with a sample of colors of different hue.\n\
  549. Each color is that with the maximum chroma for that hue.\n\
  550. The constant option uses colors from the colormap,\n\
  551. so editing conflicts are possible when these options are displayed.\n\
  552. \n\
  553. Fill leaf with a sample of colors of constant hue, varying value\n\
  554. and chroma.  This is only a portion of the colors available for this hue.\n\
  555. Colors from the colormap are used to fill the leaf, so editing conflicts\n\
  556. are possible when this option is chosen.\n\
  557. \n\
  558. Coordinates specifies which coordinate systems are used to display\n\
  559. a description of the current color.\n\
  560. \n\
  561. Constrain chroma controls what happens when a color with an unreachable\n\
  562. chroma is specified.  None allows any chroma up to 120.0.  The color\n\
  563. patch displays the closest reachable color with that hue and value.\n\
  564. Monitor restricts colors to those that can be generated on the terminal\n\
  565. or workstation display.";
  566.  
  567.     optionHelp = CreateHelp(parent, "color editor options help", str);
  568. }
  569.  
  570. STATIC void CreateHelpVersion(parent)
  571. Widget parent;
  572. {
  573.     char *str = "\
  574. Tektronix Color Editor Version 1.0b (X - Athena Widgets)\n\
  575. \n\
  576. This is an X Window System client version of the TekColor interface.\n\
  577. \n\
  578. Copyright Tektronix, Inc., 1989, 1990, 1991\n\
  579. Patent pending for portions of the TekColor system.\n\
  580. \n\
  581. TekColor and TekHVC are trademarks of Tektronix, Inc.\n\
  582. X Window System is a trademark of the Massachusetts Institute of Technology\n\
  583. Motif is a trademark of Open Software Foundation, Inc.";
  584.  
  585.     versHelp = CreateHelp(parent, "color editor version help", str);
  586. }
  587.  
  588.  
  589. /*
  590.  * Create the Edit pulldown menu and sub-menus.
  591.  */
  592. STATIC Arg editargs[] = {
  593.     {XtNfromHoriz, NULL},
  594.     {XtNlabel, (XtArgVal)"Edit"}
  595. };
  596.  
  597. STATIC Widget CreateEditPulldown(parent, neighbor)
  598. Widget parent, neighbor;
  599. {
  600.     Widget edit, menuform, copyform;
  601.     Widget copy, paste;        /* menu entries */
  602.     Widget one, two, three;    /* sub menu entries for copy command */
  603.     Arg args[5];
  604.     int argCt;
  605.  
  606.     /* this is the button on the menubar */
  607.     editargs[0].value = (XtArgVal)neighbor;
  608.     edit = XtCreateManagedWidget("edit", commandWidgetClass, parent,
  609.                     editargs, XtNumber(editargs));
  610.  
  611.     /* create the editmenu popup */
  612.     argCt = 0;
  613.     XtSetArg(args[argCt], XtNoverrideRedirect, True);       argCt++;
  614.     editmenu = XtCreatePopupShell("editmenu", transientShellWidgetClass, edit, 
  615.                   args, argCt);
  616.     XtAddCallback(edit, XtNcallback, PlaceDropDownMenu, (XtPointer)editmenu);
  617.  
  618.     menuform = XtCreateManagedWidget("menuform", formWidgetClass,
  619.                     editmenu, NULL, 0);
  620.  
  621.     /* Create the sub menu used by Copy color */
  622.     argCt = 0;
  623.     XtSetArg(args[argCt], XtNlabel, "Copy Color ->");        argCt++;
  624.     copy = XtCreateManagedWidget("copy", commandWidgetClass, menuform,
  625.                     args, argCt);
  626.     argCt = 0;
  627.     XtSetArg(args[argCt], XtNoverrideRedirect, True);       argCt++;
  628.     copymenu = XtCreatePopupShell("copymenu", transientShellWidgetClass,
  629.                   copy, args, argCt);
  630.     XtAddCallback(copy, XtNcallback, PlaceCascadeMenu, (XtPointer)copymenu);
  631.  
  632.     copyform = XtCreateManagedWidget("menuform", formWidgetClass,
  633.                     copymenu, NULL, 0);
  634.  
  635.     argCt = 0;
  636.     XtSetArg(args[argCt], XtNlabel, "TekHVC");            argCt++;
  637.     one =  XtCreateManagedWidget("copyhvc", commandWidgetClass, copyform,
  638.                     args, argCt);
  639.     XtAddCallback(one, XtNcallback, Copy, (XtPointer)CopyHVC);
  640.  
  641.     argCt = 0;
  642.     XtSetArg(args[argCt], XtNlabel, "RGB");            argCt++;
  643.     XtSetArg(args[argCt], XtNfromVert, one);            argCt++;
  644.     two =  XtCreateManagedWidget("copyrgb", commandWidgetClass, copyform,
  645.                     args, argCt);
  646.     XtAddCallback(two, XtNcallback, Copy, (XtPointer)CopyRGB);
  647.  
  648.     argCt = 0;
  649.     XtSetArg(args[argCt], XtNlabel, "CIE u'v'Y");        argCt++;
  650.     XtSetArg(args[argCt], XtNfromVert, two);            argCt++;
  651.     three =  XtCreateManagedWidget("copyuvy", commandWidgetClass, copyform,
  652.                     args, argCt);
  653.     XtAddCallback(three, XtNcallback, Copy, (XtPointer)CopyuvY);
  654.  
  655.     /* Create the Paste Button on the Edit Menu */
  656.     argCt = 0;
  657.     XtSetArg(args[argCt], XtNlabel, "Paste Color");        argCt++;
  658.     XtSetArg(args[argCt], XtNfromVert, copy);            argCt++;
  659.     paste = XtCreateManagedWidget("paste", commandWidgetClass, menuform,
  660.                     args, argCt);
  661.     XtAddCallback(paste, XtNcallback, Paste, (XtPointer)EditPaste);
  662.  
  663.     return(edit);
  664. }
  665.  
  666.  
  667. /*
  668.  * Create the Help pulldown menu; dialogs are created on demand
  669.  */
  670. STATIC Arg helpargs[] = {
  671.     {XtNfromHoriz, NULL},
  672.     {XtNlabel, (XtArgVal)"Help"},
  673. };
  674.  
  675. STATIC void CreateHelpPulldown(parent, neighbor)
  676. Widget parent, neighbor;
  677. {
  678.     Widget help, menuform, interf, version, quit, edit, option, import, export;
  679.     Arg args[5];
  680.     int argCt;
  681.  
  682.     /* create the button to go in the menu bar */
  683.     helpargs[0].value = (XtArgVal)neighbor;
  684.     help = XtCreateManagedWidget("help", commandWidgetClass, parent, 
  685.                     helpargs, XtNumber(helpargs));
  686.  
  687.     /* create the pulldown menu */
  688.     argCt = 0;
  689.     XtSetArg(args[argCt], XtNoverrideRedirect, True);        argCt++;
  690.     helpmenu = XtCreatePopupShell ("helpmenu", transientShellWidgetClass,
  691.                        help, args, argCt);
  692.     XtAddCallback(help, XtNcallback, PlaceDropDownMenu, (XtPointer)helpmenu);
  693.  
  694.     menuform = XtCreateManagedWidget("menuform", formWidgetClass,
  695.                     helpmenu, NULL, 0);
  696.  
  697.     argCt = 0;
  698.     XtSetArg(args[argCt], XtNlabel, "On Interface");        argCt++;
  699.     interf = XtCreateManagedWidget("interface", commandWidgetClass, menuform,
  700.                    args, argCt);
  701.     XtAddCallback(interf, XtNcallback, HelpMenuPopup, HelpInterface);
  702.  
  703.     argCt = 0;
  704.     XtSetArg(args[argCt], XtNlabel, "On Version");        argCt++;
  705.     XtSetArg(args[argCt], XtNfromVert, interf);            argCt++;
  706.     version = XtCreateManagedWidget("version", commandWidgetClass, menuform,
  707.                     args, argCt);
  708.     XtAddCallback(version, XtNcallback, HelpMenuPopup, (XtPointer)HelpVersion);
  709.  
  710.     argCt = 0;
  711.     XtSetArg(args[argCt], XtNlabel, "On Quit Menu");        argCt++;
  712.     XtSetArg(args[argCt], XtNfromVert, version);        argCt++;
  713.     quit = XtCreateManagedWidget("quit", commandWidgetClass, menuform,
  714.                     args, argCt);
  715.     XtAddCallback(quit, XtNcallback, HelpMenuPopup, (XtPointer)HelpQuit);
  716.  
  717.     argCt = 0;
  718.     XtSetArg(args[argCt], XtNlabel, "On Options Menu");        argCt++;
  719.     XtSetArg(args[argCt], XtNfromVert, quit);            argCt++;
  720.     option = XtCreateManagedWidget("option", commandWidgetClass, menuform,
  721.                     args, argCt);
  722.     XtAddCallback(option, XtNcallback, HelpMenuPopup, (XtPointer)HelpOptions);
  723.  
  724.     argCt = 0;
  725.     XtSetArg(args[argCt], XtNlabel, "On Import Menu");        argCt++;
  726.     XtSetArg(args[argCt], XtNfromVert, option);            argCt++;
  727.     import = XtCreateManagedWidget("import", commandWidgetClass, menuform,
  728.                     args, argCt);
  729.     XtAddCallback(import, XtNcallback, HelpMenuPopup, (XtPointer)HelpImport);
  730.  
  731.     argCt = 0;
  732.     XtSetArg(args[argCt], XtNlabel, "On Export Menu");        argCt++;
  733.     XtSetArg(args[argCt], XtNfromVert, import);            argCt++;
  734.     export = XtCreateManagedWidget("export", commandWidgetClass, menuform,
  735.                     args, argCt);
  736.     XtAddCallback(export, XtNcallback, HelpMenuPopup, (XtPointer)HelpExport);
  737.  
  738.     argCt = 0;
  739.     XtSetArg(args[argCt], XtNlabel, "On Edit Menu");        argCt++;
  740.     XtSetArg(args[argCt], XtNfromVert, export);            argCt++;
  741.     edit = XtCreateManagedWidget("edit", commandWidgetClass, menuform,
  742.                     args, argCt);
  743.     XtAddCallback(edit, XtNcallback, HelpMenuPopup, (XtPointer)HelpEdit);
  744. }
  745.  
  746.  
  747.  
  748. /*
  749.  * Create the Option pulldown menu button and tree
  750.  */
  751. STATIC Arg optionargs[] = {
  752.     {XtNfromHoriz, NULL},
  753.     {XtNlabel, (XtArgVal)"Options" }
  754. };
  755. STATIC Arg hfbargs[] = {
  756.     {XtNlabel, (XtArgVal)"Fill Hue Bar"},
  757. };
  758. STATIC Arg lfbargs[] = {
  759.     {XtNlabel, (XtArgVal)"Fill Leaf"},
  760.     {XtNfromVert, (XtArgVal)NULL},
  761. };
  762. STATIC Arg clbargs[] = {
  763.     {XtNbitmap, (XtArgVal)NULL},  
  764.     /* or use {XtNlabel, (XtArgVal)"Constrain Chroma"}, */
  765.     {XtNfromVert, (XtArgVal)NULL},
  766. };
  767. STATIC Arg cobargs[] = {
  768.     {XtNlabel, (XtArgVal)"Coodinates ->"},
  769.     {XtNfromVert, (XtArgVal)NULL},
  770. };
  771.  
  772. STATIC Widget CreateOptionPulldown(parent, neighbor)
  773. Widget parent, neighbor;
  774. {
  775.     Widget option, menuform, coordform;
  776.     /* menu entries */
  777.     Widget huefillbttn;
  778.     Widget leaffillbttn;
  779.     Widget clampbttn;
  780.     Widget coordbttn;
  781.     Widget rgb, uvy;            /* coordinates cascade */
  782.     Arg  args[5];
  783.     int  argCt;
  784.  
  785.     /* the menu item in the menubar */
  786.     optionargs[0].value = (XtArgVal)neighbor;
  787.     option = XtCreateManagedWidget("option", commandWidgetClass,
  788.                     parent, optionargs, XtNumber(optionargs));
  789.  
  790.     /* Create each of the sub menu items and the sub menu cascades, etc. */
  791.     argCt = 0;
  792.     XtSetArg(args[argCt], XtNoverrideRedirect, True);       argCt++;
  793.     optionmenu = XtCreatePopupShell("optionmenu", transientShellWidgetClass,
  794.                     option, args, argCt);
  795.     XtAddCallback(option, XtNcallback, PlaceDropDownMenu, (XtPointer)optionmenu);
  796.  
  797.     menuform = XtCreateManagedWidget("menuform", formWidgetClass,
  798.                     optionmenu, NULL, 0);
  799.  
  800.     /* Create the menu entries in the optionmenu pulldown */
  801.  
  802.     /* only allow hue optionmenu of colormap is large enough */
  803.     if (allowFill <= FillHuebar) {
  804.     /* Create the Fill Hue Bar command widget */
  805.     huefillbttn = XtCreateManagedWidget("huebutton", commandWidgetClass, 
  806.                     menuform, hfbargs, XtNumber(hfbargs));
  807.     XtAddCallback(huefillbttn, XtNcallback, OptionsHue, (XtPointer)NULL);
  808.  
  809.     /* Create the Fill Leaf command widget */
  810.     lfbargs[1].value = (XtArgVal)huefillbttn;
  811.     leaffillbttn = XtCreateManagedWidget("leafbutton", commandWidgetClass,
  812.                     menuform, lfbargs, XtNumber(lfbargs));
  813.     XtAddCallback(leaffillbttn, XtNcallback, OptionsLeaf, (XtPointer)NULL);
  814.     clbargs[1].value = (XtArgVal)leaffillbttn;
  815.     }
  816.  
  817.     /* Create the Clamp command widget */
  818.     bitmapOff = XCreateBitmapFromData(dpy, RootWindow(dpy, DefaultScreen(dpy)),
  819.                       constrain_off_bits, 
  820.                       constrain_width, constrain_height);
  821.     bitmapOn = XCreateBitmapFromData(dpy, RootWindow(dpy, DefaultScreen(dpy)),
  822.                      constrain_on_bits,
  823.                      constrain_width, constrain_height);
  824.     clbargs[0].value = (XtArgVal)bitmapOn;
  825.     clampbttn = XtCreateManagedWidget("clamp", commandWidgetClass, menuform,
  826.                       clbargs, XtNumber(clbargs));
  827.     XtAddCallback(clampbttn, XtNcallback, OptionsClamp, (XtPointer)NULL);
  828.  
  829.     /* Create coordinates button and pulldown */
  830.     cobargs[1].value = (XtArgVal)clampbttn;
  831.     coordbttn = XtCreateManagedWidget("coordinates", commandWidgetClass,
  832.                     menuform, cobargs, XtNumber(cobargs));
  833.  
  834.     argCt = 0;
  835.     XtSetArg(args[argCt], XtNoverrideRedirect, True);       argCt++;
  836.     coordmenu = XtCreatePopupShell("coordmenu", transientShellWidgetClass, 
  837.                     coordbttn, args, argCt);
  838.     XtAddCallback(coordbttn, XtNcallback, PlaceCascadeMenu, (XtPointer)coordmenu);
  839.  
  840.     coordform = XtCreateManagedWidget("menuform", formWidgetClass,
  841.                      coordmenu, NULL, 0);
  842.  
  843.     /* Create the coordinates buttons */
  844.     argCt = 0;
  845.     XtSetArg(args[argCt], XtNlabel, "RGB");            argCt++;
  846.     rgb = XtCreateManagedWidget("rgb", commandWidgetClass, coordform,
  847.                 args, argCt);
  848.     rgbCoord = rgb;
  849.     XtAddCallback(rgb, XtNcallback, Coordinates, (XtPointer)ViewRGB);
  850.  
  851.     argCt = 0;
  852.     XtSetArg(args[argCt], XtNlabel, "CIE u'v'Y");        argCt++;
  853.     XtSetArg(args[argCt], XtNfromVert, rgbCoord);        argCt++;
  854.     uvy = XtCreateManagedWidget("uvY", commandWidgetClass, coordform,
  855.                 args, argCt);
  856.     uvyCoord = uvy;
  857.     XtAddCallback(uvy, XtNcallback, Coordinates, (XtPointer)ViewUVY);
  858.  
  859.     return(option);
  860. }
  861.  
  862.  
  863. /************************************************************************
  864.  *                                    *
  865.  *            PUBLIC ROUTINES                    *
  866.  *                                    *
  867.  ************************************************************************/
  868. STATIC Arg quitargs[] = {
  869.     {XtNlabel, (XtArgVal)"Quit"},
  870. };
  871. STATIC Arg importargs[] = {
  872.     {XtNfromHoriz, NULL},
  873.     {XtNlabel, (XtArgVal)"Import"},
  874. };
  875. STATIC Arg exportargs[] = {
  876.     {XtNfromHoriz, NULL},
  877.     {XtNlabel, (XtArgVal)"Export"},
  878. };
  879.  
  880. /*
  881.  * Create a menu bar widget, its pulldown menus and all buttons, dialogs,
  882.  * etc. found in the menu hierarchy.
  883.  */
  884. Widget CreateMenuBar(parent)
  885. Widget parent;
  886. {
  887.     Widget self = XtCreateManagedWidget("menubar", formWidgetClass, parent, 
  888.                     NULL, 0);
  889.     Widget quit, edit, option, import, export;
  890.  
  891.     quit = XtCreateManagedWidget("quit", commandWidgetClass, self,
  892.                  quitargs, XtNumber(quitargs));
  893.     XtAddCallback(quit, XtNcallback, Quit, (XtPointer)NULL);
  894.  
  895.     option = CreateOptionPulldown(self, quit);
  896.  
  897.     importargs[0].value = (XtArgVal)option;
  898.     import = XtCreateManagedWidget("import", commandWidgetClass, self,
  899.                     importargs, XtNumber(importargs));
  900.     XtAddCallback(import, XtNcallback, Grab, (XtPointer)ImportPixel);
  901.  
  902.     exportargs[0].value = (XtArgVal)import;
  903.     export = XtCreateManagedWidget("export", commandWidgetClass, self,
  904.                     exportargs, XtNumber(exportargs));
  905.     XtAddCallback(export, XtNcallback, Grab, (XtPointer)ExportPixel);
  906.  
  907.     edit = CreateEditPulldown(self, export);
  908.  
  909.     CreateHelpPulldown(self, edit);
  910.  
  911.     return(self);
  912. }
  913.  
  914. /* ARGSUSED */
  915. void NewHuebarState(new, what)
  916. int new;
  917. int what;
  918. {
  919.     Pixel base;
  920.     int len;
  921.     Arg args[2];
  922.  
  923.     if (new == huebarState)
  924.     return;
  925.  
  926.     /* make the necessary changes in the hue bar */
  927.     switch (new) {
  928.     case HuebarEmpty:
  929.     HuebarRangeRestore((Pixel *)&base, (int *)&len);
  930.     break;
  931.     case HuebarConstant:
  932.     if (HuebarRangeBusy()) {        /* allow user to back out */
  933.         return;
  934.     }
  935.     if (huebarState == HuebarEmpty)
  936.         HuebarRangeSave();
  937.     HuebarRangeLoad((Pixel *)&base, (int *)&len);
  938.     break;
  939.     }
  940.  
  941.     if (len > 0) {
  942.     XtSetArg(args[0], XtNbase, base);
  943.     XtSetArg(args[1], XtNlength, len);
  944.     XtSetValues(huebar, args, XtNumber(args));
  945.     }
  946.  
  947.     /* update the menu buttons to reflect new state */
  948.     huebarState = new;
  949. }
  950.  
  951. /* ARGSUSED */
  952. void NewLeafState(new, what)
  953. int new;
  954. int what;
  955. {
  956.     Pixel base;
  957.  
  958.     if (new & LeafFilled) {
  959.     if (LeafRangeBusy()) {        /* allow user to back out */
  960.         return;
  961.     }
  962.     LeafRangeSave((Pixel *)&base);
  963.     } else {
  964.     LeafRangeRestore((Pixel *)&base);
  965.     }
  966.     SetLeafBase(base);
  967.  
  968.     leafState = new;
  969. }
  970.  
  971. extern void ChangeShowed();
  972.  
  973. void NewShow(new)
  974. int new;
  975. {
  976.     ChangeShowed(new);
  977.  
  978.     UpdateShowWidget(new);
  979. }
  980.  
  981. /*
  982.  * Place a drop down widget over the top of the menu item from which it
  983.  * has orginated. 
  984.  */
  985. /* ARGSUSED */
  986. STATIC void PlaceDropDownMenu(wid, pplacewidget, call)
  987. Widget wid;
  988. XtPointer pplacewidget;
  989. XtPointer call;
  990. {
  991.     Widget placewidget = (Widget)pplacewidget;
  992.     Position x, y;
  993.     Arg args[2];
  994.     int i;
  995.  
  996.     /* 
  997.      * Translate the coordinates of the invoking widget into root coordinates
  998.      */
  999.     XtTranslateCoords (wid, (Position)0, wid->core.height, &x, &y);
  1000.     
  1001.     /*
  1002.      * Now move the menu (popup shell so it is covering the invoking button.
  1003.      * Assume borderWidth of 0.
  1004.      */
  1005.     i = 0;
  1006.     XtSetArg (args[i], XtNx, x);    i++;
  1007.     XtSetArg (args[i], XtNy, y);    i++;
  1008.     XtSetValues (placewidget, args, i);
  1009.     XtPopup (placewidget, XtGrabNonexclusive);
  1010. }
  1011.  
  1012. /*
  1013.  * Place a cascade menu widget next to the menu item from which it
  1014.  * has orginated. 
  1015.  */
  1016. /* ARGSUSED */
  1017. STATIC void PlaceCascadeMenu(wid, pplacewidget, evnt)
  1018. Widget wid;
  1019. XtPointer pplacewidget;
  1020. XtPointer evnt;
  1021. {
  1022.     Widget placewidget = (Widget)pplacewidget;
  1023.     Position x, y;
  1024.     Dimension width = wid->core.width;
  1025.     Arg args[2];
  1026.     int i;
  1027.  
  1028.     /* 
  1029.      * Translate the coordinates of the invoking widget into root coordinates
  1030.      */
  1031.     XtTranslateCoords (wid, (Position)0, (Position)0, &x, &y);
  1032.     
  1033.     /*
  1034.      * Now move the menu (popup shell so it is covering the invoking button.
  1035.      * Assume borderWidth of 0.
  1036.      */
  1037.     i = 0;
  1038.     XtSetArg (args[i], XtNx, x + width);    i++;
  1039.     XtSetArg (args[i], XtNy, y);        i++;
  1040.     XtSetValues (placewidget, args, i);
  1041.     XtPopup (placewidget, XtGrabNonexclusive);
  1042. }
  1043.