aboutsummaryrefslogtreecommitdiff
path: root/nx-X11/lib/dpstk/ColorSB.c
diff options
context:
space:
mode:
authorReinhard Tartler <siretart@tauware.de>2011-10-10 17:43:39 +0200
committerReinhard Tartler <siretart@tauware.de>2011-10-10 17:43:39 +0200
commitf4092abdf94af6a99aff944d6264bc1284e8bdd4 (patch)
tree2ac1c9cc16ceb93edb2c4382c088dac5aeafdf0f /nx-X11/lib/dpstk/ColorSB.c
parenta840692edc9c6d19cd7c057f68e39c7d95eb767d (diff)
downloadnx-libs-f4092abdf94af6a99aff944d6264bc1284e8bdd4.tar.gz
nx-libs-f4092abdf94af6a99aff944d6264bc1284e8bdd4.tar.bz2
nx-libs-f4092abdf94af6a99aff944d6264bc1284e8bdd4.zip
Imported nx-X11-3.1.0-1.tar.gznx-X11/3.1.0-1
Summary: Imported nx-X11-3.1.0-1.tar.gz Keywords: Imported nx-X11-3.1.0-1.tar.gz into Git repository
Diffstat (limited to 'nx-X11/lib/dpstk/ColorSB.c')
-rw-r--r--nx-X11/lib/dpstk/ColorSB.c3388
1 files changed, 3388 insertions, 0 deletions
diff --git a/nx-X11/lib/dpstk/ColorSB.c b/nx-X11/lib/dpstk/ColorSB.c
new file mode 100644
index 000000000..d2d71088e
--- /dev/null
+++ b/nx-X11/lib/dpstk/ColorSB.c
@@ -0,0 +1,3388 @@
+/*
+ * ColorSB.c
+ *
+ * (c) Copyright 1993-1994 Adobe Systems Incorporated.
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sublicense this software
+ * and its documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notices appear in all copies and that
+ * both those copyright notices and this permission notice appear in
+ * supporting documentation and that the name of Adobe Systems Incorporated
+ * not be used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission. No trademark license
+ * to use the Adobe trademarks is hereby granted. If the Adobe trademark
+ * "Display PostScript"(tm) is used to describe this software, its
+ * functionality or for any other purpose, such use shall be limited to a
+ * statement that this software works in conjunction with the Display
+ * PostScript system. Proper trademark attribution to reflect Adobe's
+ * ownership of the trademark shall be given whenever any such reference to
+ * the Display PostScript system is made.
+ *
+ * ADOBE MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THE SOFTWARE FOR
+ * ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
+ * ADOBE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON- INFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL ADOBE BE LIABLE
+ * TO YOU OR ANY OTHER PARTY FOR ANY SPECIAL, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE, STRICT LIABILITY OR ANY OTHER ACTION ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ADOBE WILL NOT
+ * PROVIDE ANY TRAINING OR OTHER SUPPORT FOR THE SOFTWARE.
+ *
+ * Adobe, PostScript, and Display PostScript are trademarks of Adobe Systems
+ * Incorporated which may be registered in certain jurisdictions
+ *
+ * Author: Adobe Systems Incorporated
+ */
+/* $XFree86$ */
+
+#ifndef X_NOT_POSIX
+#include <unistd.h>
+#endif
+
+#include <X11/IntrinsicP.h>
+#include <X11/StringDefs.h>
+#include <X11/ShellP.h>
+#include <stdlib.h>
+#include <Xm/Xm.h>
+
+/* There are no words to describe how I feel about having to do this */
+
+#if XmVersion > 1001
+#include <Xm/ManagerP.h>
+#else
+#include <Xm/XmP.h>
+#endif
+
+#include <Xm/Form.h>
+#include <Xm/Label.h>
+#include <Xm/LabelG.h>
+#include <Xm/PushB.h>
+#include <Xm/PushBG.h>
+#include <Xm/SeparatoG.h>
+#include <Xm/DrawingA.h>
+#include <Xm/Scale.h>
+#include <Xm/RowColumn.h>
+#include <Xm/Frame.h>
+#include <Xm/MessageB.h>
+
+#include <DPS/dpsXclient.h>
+#include "dpsXcommonI.h"
+#include <DPS/dpsXshare.h>
+#include "eyedrop16.xbm"
+#include "eyedropmask16.xbm"
+#include "eyedrop32.xbm"
+#include "eyedropmask32.xbm"
+#include "heyedrop.xbm"
+#include "square.xbm"
+#include "squaremask.xbm"
+#include "CSBwraps.h"
+#include <math.h>
+#include <stdio.h>
+#include <pwd.h>
+#include <DPS/ColorSBP.h>
+
+#define PATH_BUF_SIZE 1024
+
+/* Turn a string into a compound string */
+#define CS(str, w) CreateSharedCS(str, w)
+
+#undef MIN
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+#undef MAX
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+#define TO_PCT(val) ((int) (val * 100.0 + 0.5))
+#define TO_X(color) ((color) * 65535)
+
+#define Offset(field) XtOffsetOf(ColorSelectionBoxRec, csb.field)
+
+static XtResource resources[] = {
+ {XtNcontext, XtCContext, XtRDPSContext, sizeof(DPSContext),
+ Offset(context), XtRDPSContext, (XtPointer) NULL},
+ {XtNrgbLabels, XtCRgbLabels, XtRString, sizeof(String),
+ Offset(rgb_labels), XtRString, (XtPointer) "R:G:B"},
+ {XtNcmykLabels, XtCCmykLabels, XtRString, sizeof(String),
+ Offset(cmyk_labels), XtRString, (XtPointer) "C:M:Y:K"},
+ {XtNhsbLabels, XtCHsbLabels, XtRString, sizeof(String),
+ Offset(hsb_labels), XtRString, (XtPointer) "H:S:B"},
+ {XtNgrayLabels, XtCGrayLabels, XtRString, sizeof(String),
+ Offset(gray_labels), XtRString, (XtPointer) "Gray"},
+ {XtNcellSize, XtCCellSize, XtRDimension, sizeof(Dimension),
+ Offset(cell_size), XtRImmediate, (XtPointer) 15},
+ {XtNnumCells, XtCNumCells, XtRShort, sizeof(short),
+ Offset(num_cells), XtRImmediate, (XtPointer) 30},
+ {XtNfillMe, XtCFillMe, XtRString, sizeof(String),
+ Offset(fill_me), XtRString, (XtPointer) "Fill me with colors"},
+ {XtNcurrentSpace, XtCCurrentSpace, XtRColorSpace, sizeof(CSBColorSpace),
+ Offset(current_space), XtRImmediate, (XtPointer) CSBSpaceHSB},
+ {XtNcurrentRendering, XtCCurrentRendering, XtRRenderingType,
+ sizeof(CSBRenderingType), Offset(current_rendering),
+ XtRImmediate, (XtPointer) CSBDisplayDPS},
+ {XtNcurrentPalette, XtCCurrentPalette, XtRShort, sizeof(short),
+ Offset(current_palette), XtRImmediate, (XtPointer) 0},
+ {XtNbrokenPaletteLabel, XtCBrokenPaletteLabel, XtRString,
+ sizeof(String), Offset(broken_palette_label),
+ XtRString, (XtPointer) "(broken)"},
+ {XtNbrokenPaletteMessage, XtCBrokenPaletteMessage, XtRString,
+ sizeof(String), Offset(broken_palette_message),
+ XtRString, (XtPointer) "The current palette contains an error"},
+
+ {XtNpalette0Label, XtCPaletteLabel, XtRString, sizeof(String),
+ Offset(palette_label[0]), XtRString, (XtPointer) NULL},
+ {XtNpalette0Space, XtCPaletteSpace, XtRColorSpace, sizeof(CSBColorSpace),
+ Offset(palette_space[0]), XtRImmediate, (XtPointer) CSBSpaceRGB},
+ {XtNpalette0ColorDependent, XtCPaletteColorDependent,
+ XtRBoolean, sizeof(Boolean),
+ Offset(palette_color_dependent[0]), XtRImmediate, (XtPointer) False},
+ {XtNpalette0Function, XtCPaletteFunction, XtRString, sizeof(String),
+ Offset(palette_function[0]), XtRImmediate, (XtPointer) NULL},
+
+ {XtNpalette1Label, XtCPaletteLabel, XtRString, sizeof(String),
+ Offset(palette_label[1]), XtRString, (XtPointer) NULL},
+ {XtNpalette1Space, XtCPaletteSpace, XtRColorSpace, sizeof(CSBColorSpace),
+ Offset(palette_space[1]), XtRImmediate, (XtPointer) CSBSpaceRGB},
+ {XtNpalette1ColorDependent, XtCPaletteColorDependent,
+ XtRBoolean, sizeof(Boolean),
+ Offset(palette_color_dependent[1]), XtRImmediate, (XtPointer) False},
+ {XtNpalette1Function, XtCPaletteFunction, XtRString, sizeof(String),
+ Offset(palette_function[1]), XtRImmediate, (XtPointer) NULL},
+
+ {XtNpalette2Label, XtCPaletteLabel, XtRString, sizeof(String),
+ Offset(palette_label[2]), XtRString, (XtPointer) NULL},
+ {XtNpalette2Space, XtCPaletteSpace, XtRColorSpace, sizeof(CSBColorSpace),
+ Offset(palette_space[2]), XtRImmediate, (XtPointer) CSBSpaceRGB},
+ {XtNpalette2ColorDependent, XtCPaletteColorDependent,
+ XtRBoolean, sizeof(Boolean),
+ Offset(palette_color_dependent[2]), XtRImmediate, (XtPointer) False},
+ {XtNpalette2Function, XtCPaletteFunction, XtRString, sizeof(String),
+ Offset(palette_function[2]), XtRImmediate, (XtPointer) NULL},
+
+ {XtNpalette3Label, XtCPaletteLabel, XtRString, sizeof(String),
+ Offset(palette_label[3]), XtRString, (XtPointer) NULL},
+ {XtNpalette3Space, XtCPaletteSpace, XtRColorSpace, sizeof(CSBColorSpace),
+ Offset(palette_space[3]), XtRImmediate, (XtPointer) CSBSpaceRGB},
+ {XtNpalette3ColorDependent, XtCPaletteColorDependent,
+ XtRBoolean, sizeof(Boolean),
+ Offset(palette_color_dependent[3]), XtRImmediate, (XtPointer) False},
+ {XtNpalette3Function, XtCPaletteFunction, XtRString, sizeof(String),
+ Offset(palette_function[3]), XtRImmediate, (XtPointer) NULL},
+
+ {XtNpalette4Label, XtCPaletteLabel, XtRString, sizeof(String),
+ Offset(palette_label[4]), XtRString, (XtPointer) NULL},
+ {XtNpalette4Space, XtCPaletteSpace, XtRColorSpace, sizeof(CSBColorSpace),
+ Offset(palette_space[4]), XtRImmediate, (XtPointer) CSBSpaceRGB},
+ {XtNpalette4ColorDependent, XtCPaletteColorDependent,
+ XtRBoolean, sizeof(Boolean),
+ Offset(palette_color_dependent[4]), XtRImmediate, (XtPointer) False},
+ {XtNpalette4Function, XtCPaletteFunction, XtRString, sizeof(String),
+ Offset(palette_function[4]), XtRImmediate, (XtPointer) NULL},
+
+ {XtNpalette5Label, XtCPaletteLabel, XtRString, sizeof(String),
+ Offset(palette_label[5]), XtRString, (XtPointer) NULL},
+ {XtNpalette5Space, XtCPaletteSpace, XtRColorSpace, sizeof(CSBColorSpace),
+ Offset(palette_space[5]), XtRImmediate, (XtPointer) CSBSpaceRGB},
+ {XtNpalette5ColorDependent, XtCPaletteColorDependent,
+ XtRBoolean, sizeof(Boolean),
+ Offset(palette_color_dependent[5]), XtRImmediate, (XtPointer) False},
+ {XtNpalette5Function, XtCPaletteFunction, XtRString, sizeof(String),
+ Offset(palette_function[5]), XtRImmediate, (XtPointer) NULL},
+
+ {XtNpalette6Label, XtCPaletteLabel, XtRString, sizeof(String),
+ Offset(palette_label[6]), XtRString, (XtPointer) NULL},
+ {XtNpalette6Space, XtCPaletteSpace, XtRColorSpace, sizeof(CSBColorSpace),
+ Offset(palette_space[6]), XtRImmediate, (XtPointer) CSBSpaceRGB},
+ {XtNpalette6ColorDependent, XtCPaletteColorDependent,
+ XtRBoolean, sizeof(Boolean),
+ Offset(palette_color_dependent[6]), XtRImmediate, (XtPointer) False},
+ {XtNpalette6Function, XtCPaletteFunction, XtRString, sizeof(String),
+ Offset(palette_function[6]), XtRImmediate, (XtPointer) NULL},
+
+ {XtNpalette7Label, XtCPaletteLabel, XtRString, sizeof(String),
+ Offset(palette_label[7]), XtRString, (XtPointer) NULL},
+ {XtNpalette7Space, XtCPaletteSpace, XtRColorSpace, sizeof(CSBColorSpace),
+ Offset(palette_space[7]), XtRImmediate, (XtPointer) CSBSpaceRGB},
+ {XtNpalette7ColorDependent, XtCPaletteColorDependent,
+ XtRBoolean, sizeof(Boolean),
+ Offset(palette_color_dependent[7]), XtRImmediate, (XtPointer) False},
+ {XtNpalette7Function, XtCPaletteFunction, XtRString, sizeof(String),
+ Offset(palette_function[7]), XtRImmediate, (XtPointer) NULL},
+
+ {XtNpalette8Label, XtCPaletteLabel, XtRString, sizeof(String),
+ Offset(palette_label[8]), XtRString, (XtPointer) NULL},
+ {XtNpalette8Space, XtCPaletteSpace, XtRColorSpace, sizeof(CSBColorSpace),
+ Offset(palette_space[8]), XtRImmediate, (XtPointer) CSBSpaceRGB},
+ {XtNpalette8ColorDependent, XtCPaletteColorDependent,
+ XtRBoolean, sizeof(Boolean),
+ Offset(palette_color_dependent[8]), XtRImmediate, (XtPointer) False},
+ {XtNpalette8Function, XtCPaletteFunction, XtRString, sizeof(String),
+ Offset(palette_function[8]), XtRImmediate, (XtPointer) NULL},
+
+ {XtNpalette9Label, XtCPaletteLabel, XtRString, sizeof(String),
+ Offset(palette_label[9]), XtRString, (XtPointer) NULL},
+ {XtNpalette9Space, XtCPaletteSpace, XtRColorSpace, sizeof(CSBColorSpace),
+ Offset(palette_space[9]), XtRImmediate, (XtPointer) CSBSpaceRGB},
+ {XtNpalette9ColorDependent, XtCPaletteColorDependent,
+ XtRBoolean, sizeof(Boolean),
+ Offset(palette_color_dependent[9]), XtRImmediate, (XtPointer) False},
+ {XtNpalette9Function, XtCPaletteFunction, XtRString, sizeof(String),
+ Offset(palette_function[9]), XtRImmediate, (XtPointer) NULL},
+
+ {XtNokCallback, XtCCallback, XtRCallback, sizeof(XtCallbackList),
+ Offset(ok_callback), XtRCallback, (XtPointer) NULL},
+ {XtNapplyCallback, XtCCallback, XtRCallback, sizeof(XtCallbackList),
+ Offset(apply_callback), XtRCallback, (XtPointer) NULL},
+ {XtNresetCallback, XtCCallback, XtRCallback, sizeof(XtCallbackList),
+ Offset(reset_callback), XtRCallback, (XtPointer) NULL},
+ {XtNcancelCallback, XtCCallback, XtRCallback, sizeof(XtCallbackList),
+ Offset(cancel_callback), XtRCallback, (XtPointer) NULL},
+ {XtNvalueChangedCallback, XtCCallback, XtRCallback, sizeof(XtCallbackList),
+ Offset(value_changed_callback), XtRCallback, (XtPointer) NULL}
+};
+
+static Boolean SetColor (Widget w, CSBColorSpace space, double c1, double c2, double c3, double c4, Bool setSpace);
+static Boolean SetValues (Widget old, Widget req, Widget new, ArgList args, Cardinal *num_args);
+static XtGeometryResult GeometryManager (Widget w, XtWidgetGeometry *desired, XtWidgetGeometry *allowed);
+static void ChangeLabel (Widget label, double n);
+static void ChangeManaged (Widget w);
+static void ClassInitialize (void);
+static void ClassPartInitialize (WidgetClass widget_class);
+static void CreateChildren (ColorSelectionBoxWidget csb);
+static void Destroy (Widget widget);
+static void DrawDock (ColorSelectionBoxWidget csb);
+static void DrawPalette (ColorSelectionBoxWidget csb);
+static void FillPatch (ColorSelectionBoxWidget csb);
+static void GetColor (Widget w, CSBColorSpace space, float *c1, float *c2, float *c3, float *c4);
+static void Initialize (Widget request, Widget new, ArgList args, Cardinal *num_args);
+static void InitializeDock (ColorSelectionBoxWidget csb);
+static void Realize (Widget w, XtValueMask *mask, XSetWindowAttributes *attr);
+static void Resize (Widget widget);
+static void SaveDockContents (ColorSelectionBoxWidget csb);
+static void SetBackground (ColorSelectionBoxWidget csb);
+static void SetCMYKValues (ColorSelectionBoxWidget csb);
+static void SetColorSpace (ColorSelectionBoxWidget csb);
+static void SetGrayValues (ColorSelectionBoxWidget csb);
+static void SetHSBValues (ColorSelectionBoxWidget csb);
+static void SetRGBValues (ColorSelectionBoxWidget csb);
+static void SetRendering (ColorSelectionBoxWidget csb);
+static void SetSliders (ColorSelectionBoxWidget csb);
+static void UpdateColorSpaces (ColorSelectionBoxWidget csb, CSBColorSpace masterSpace);
+
+static void DockPress (Widget w, XtPointer data, XEvent *event, Boolean *goOn);
+static void EyedropPointer (Widget w, XtPointer data, XEvent *event, Boolean *goOn);
+static void FormResize (Widget w, XtPointer data, XEvent *event, Boolean *goOn);
+static void PalettePress (Widget w, XtPointer data, XEvent *event, Boolean *goOn);
+static void PatchPress (Widget w, XtPointer data, XEvent *event, Boolean *goOn);
+static void PatchRelease (Widget w, XtPointer data, XEvent *event, Boolean *goOn);
+
+static void ApplyCallback (Widget w, XtPointer clientData, XtPointer callData);
+static void DoEyedropCallback (Widget w, XtPointer clientData, XtPointer callData);
+static void DrawDockCallback (Widget w, XtPointer clientData, XtPointer callData);
+static void DrawPaletteCallback (Widget w, XtPointer clientData, XtPointer callData);
+static void FillPatchCallback (Widget w, XtPointer clientData, XtPointer callData);
+static void OKCallback (Widget w, XtPointer clientData, XtPointer callData);
+static void SetCMYKCallback (Widget w, XtPointer clientData, XtPointer callData);
+static void SetGrayCallback (Widget w, XtPointer clientData, XtPointer callData);
+static void SetHSBCallback (Widget w, XtPointer clientData, XtPointer callData);
+static void SetRGBCallback (Widget w, XtPointer clientData, XtPointer callData);
+static void Slider1Callback (Widget w, XtPointer clientData, XtPointer callData);
+static void Slider2Callback (Widget w, XtPointer clientData, XtPointer callData);
+static void Slider3Callback (Widget w, XtPointer clientData, XtPointer callData);
+static void Slider4Callback (Widget w, XtPointer clientData, XtPointer callData);
+
+ColorSelectionBoxClassRec colorSelectionBoxClassRec = {
+ /* Core class part */
+ {
+ /* superclass */ (WidgetClass) &xmManagerClassRec,
+ /* class_name */ "ColorSelectionBox",
+ /* widget_size */ sizeof(ColorSelectionBoxRec),
+ /* class_initialize */ ClassInitialize,
+ /* class_part_initialize */ ClassPartInitialize,
+ /* class_inited */ False,
+ /* initialize */ Initialize,
+ /* initialize_hook */ NULL,
+ /* realize */ Realize,
+ /* actions */ NULL,
+ /* num_actions */ 0,
+ /* resources */ resources,
+ /* num_resources */ XtNumber(resources),
+ /* xrm_class */ NULLQUARK,
+ /* compress_motion */ True,
+ /* compress_exposure */ XtExposeCompressMultiple,
+ /* compress_enterleave */ True,
+ /* visible_interest */ False,
+ /* destroy */ Destroy,
+ /* resize */ Resize,
+ /* expose */ NULL,
+ /* set_values */ SetValues,
+ /* set_values_hook */ NULL,
+ /* set_values_almost */ XtInheritSetValuesAlmost,
+ /* get_values_hook */ NULL,
+ /* accept_focus */ NULL,
+ /* version */ XtVersion,
+ /* callback offsets */ NULL,
+ /* tm_table */ NULL,
+ /* query_geometry */ XtInheritQueryGeometry,
+ /* display_accelerator */ NULL,
+ /* extension */ NULL,
+ },
+ /* Composite class part */
+ {
+ /* geometry_manager */ GeometryManager,
+ /* change_managed */ ChangeManaged,
+ /* insert_child */ XtInheritInsertChild,
+ /* delete_child */ XtInheritDeleteChild,
+ /* extension */ NULL,
+ },
+ /* Constraint class part */
+ {
+ /* resources */ NULL,
+ /* num_resources */ 0,
+ /* constraint_size */ 0,
+ /* initialize */ NULL,
+ /* destroy */ NULL,
+ /* set_values */ NULL,
+ /* extension */ NULL,
+ },
+ /* Manager class part */
+ {
+ /* translations */ XtInheritTranslations,
+ /* syn_resources */ NULL,
+ /* num_syn_resources */ 0,
+ /* syn_constraint_resources */ NULL,
+ /* num_syn_constraint_resources */ 0,
+ /* parent_process */ XmInheritParentProcess,
+ /* extension */ NULL,
+ },
+ /* ColorSelectionBox class part */
+ {
+ /* set_color */ SetColor,
+ /* get_color */ GetColor,
+ /* extension */ NULL,
+ }
+};
+
+WidgetClass colorSelectionBoxWidgetClass =
+ (WidgetClass) &colorSelectionBoxClassRec;
+
+static XmString CreateSharedCS(String str, Widget w)
+{
+ XrmValue src, dst;
+ XmString result;
+
+ src.addr = str;
+ src.size = strlen(str);
+
+ dst.addr = (caddr_t) &result;
+ dst.size = sizeof(result);
+
+ if (XtConvertAndStore(w, XtRString, &src, XmRXmString, &dst)) {
+ return result;
+ } else return NULL;
+}
+
+static Boolean LowerCase(String from, String to, int size)
+{
+ register char ch;
+ register int i;
+
+ for (i = 0; i < size; i++) {
+ ch = from[i];
+ if (ch >= 'A' && ch <= 'Z') to[i] = ch - 'A' + 'a';
+ else to[i] = ch;
+ if (ch == '\0') return False;
+ }
+ return TRUE;
+}
+
+/* ARGSUSED */
+
+static Boolean CvtStringToColorSpace(
+ Display *dpy,
+ XrmValuePtr args,
+ Cardinal *num_args,
+ XrmValuePtr from,
+ XrmValuePtr to,
+ XtPointer *data)
+{
+#define LOWER_SIZE 5
+ char lower[LOWER_SIZE]; /* Lower cased string value */
+ Boolean badConvert;
+ static CSBColorSpace c;
+
+ if (*num_args != 0) { /* Check for correct number */
+ XtAppErrorMsg(XtDisplayToApplicationContext(dpy),
+ "cvtStringToColorSpace", "wrongParameters",
+ "XtToolkitError",
+ "String to colorspace conversion needs no extra arguments",
+ (String *) NULL, (Cardinal *) NULL);
+ }
+
+ /* Lower case the value */
+ badConvert = LowerCase(from->addr, lower, LOWER_SIZE);
+
+ /* Try to convert if a short enough string specified */
+ if (!badConvert) {
+ if (strcmp(lower, "rgb") == 0) c = CSBSpaceRGB;
+ else if (strcmp(lower, "cmyk") == 0) c = CSBSpaceCMYK;
+ else if (strcmp(lower, "hsb") == 0) c = CSBSpaceHSB;
+ else if (strcmp(lower, "gray") == 0) c = CSBSpaceGray;
+ else if (strcmp(lower, "grey") == 0) c = CSBSpaceGray;
+ else badConvert = True;
+ }
+
+ /* String too long or unknown value -- issue warning */
+ if (badConvert) {
+ XtDisplayStringConversionWarning(dpy, from->addr, "ColorSpace");
+ } else {
+ if (to->addr == NULL) to->addr = (caddr_t) &c;
+
+ else if (to->size < sizeof(CSBColorSpace)) badConvert = TRUE;
+ else *(CSBColorSpace *) to->addr = c;
+
+ to->size = sizeof(CSBColorSpace);
+ }
+ return !badConvert;
+#undef LOWER_SIZE
+}
+
+/* ARGSUSED */
+
+static Boolean CvtStringToRenderingType(
+ Display *dpy,
+ XrmValuePtr args,
+ Cardinal *num_args,
+ XrmValuePtr from,
+ XrmValuePtr to,
+ XtPointer *data)
+{
+#define LOWER_SIZE 5
+ char lower[LOWER_SIZE]; /* Lower cased string value */
+ Boolean badConvert;
+ static CSBRenderingType c;
+
+ if (*num_args != 0) { /* Check for correct number */
+ XtAppErrorMsg(XtDisplayToApplicationContext(dpy),
+ "cvtStringToRenderingType", "wrongParameters",
+ "XtToolkitError",
+ "String to rendering type conversion needs no extra arguments",
+ (String *) NULL, (Cardinal *) NULL);
+ }
+
+ /* Lower case the value */
+ badConvert = LowerCase(from->addr, lower, LOWER_SIZE);
+
+ /* Try to convert if a short enough string specified */
+ if (!badConvert) {
+ if (strcmp(lower, "x") == 0) c = CSBDisplayX;
+ else if (strcmp(lower, "dps") == 0) c = CSBDisplayDPS;
+ else if (strcmp(lower, "both") == 0) c = CSBDisplayBoth;
+ else badConvert = True;
+ }
+
+ /* String too long or unknown value -- issue warning */
+ if (badConvert) {
+ XtDisplayStringConversionWarning(dpy, from->addr, "RenderingType");
+ } else {
+ if (to->addr == NULL) to->addr = (caddr_t) &c;
+
+ else if (to->size < sizeof(CSBRenderingType)) badConvert = TRUE;
+ else *(CSBRenderingType *) to->addr = c;
+
+ to->size = sizeof(CSBRenderingType);
+ }
+ return !badConvert;
+#undef LOWER_SIZE
+}
+
+static void ClassInitialize(void)
+{
+ /* Register converters */
+
+ XtSetTypeConverter(XtRString, XtRColorSpace,
+ CvtStringToColorSpace, (XtConvertArgList) NULL, 0,
+ XtCacheAll, (XtDestructor) NULL);
+ XtSetTypeConverter(XtRString, XtRRenderingType,
+ CvtStringToRenderingType, (XtConvertArgList) NULL, 0,
+ XtCacheAll, (XtDestructor) NULL);
+}
+
+/* ARGSUSED */
+
+static void ClassPartInitialize(WidgetClass widget_class)
+{
+ register ColorSelectionBoxWidgetClass wc =
+ (ColorSelectionBoxWidgetClass) widget_class;
+ ColorSelectionBoxWidgetClass super =
+ (ColorSelectionBoxWidgetClass) wc->core_class.superclass;
+
+ if (wc->csb_class.set_color == InheritSetColor) {
+ wc->csb_class.set_color = super->csb_class.set_color;
+ }
+ if (wc->csb_class.get_color == InheritGetColor) {
+ wc->csb_class.get_color = super->csb_class.get_color;
+ }
+}
+
+static void ToUserSpace(
+ ColorSelectionBoxWidget csb,
+ int xWidth, int xHeight,
+ float *uWidth, float *uHeight)
+{
+ register float *i = csb->csb.itransform;
+
+ *uWidth = i[0] * xWidth - i[2] * xHeight + i[4];
+ *uHeight= i[1] * xWidth - i[3] * xHeight + i[5];
+}
+
+static void ColorizeRGB(ColorSelectionBoxWidget csb)
+{
+ Dimension height, width;
+ int depth, steps;
+ float w, h;
+
+ XtVaGetValues(csb->csb.slider_child[0], XtNwidth, &width,
+ XtNheight, &height,
+ XtNdepth, &depth, NULL);
+
+ if (csb->csb.red_pixmap != None && width != csb->csb.rgb_slider_width) {
+ XFreePixmap(XtDisplay(csb), csb->csb.red_pixmap);
+ XFreePixmap(XtDisplay(csb), csb->csb.green_pixmap);
+ XFreePixmap(XtDisplay(csb), csb->csb.blue_pixmap);
+ csb->csb.red_pixmap = None;
+ }
+
+ if (csb->csb.red_pixmap == None) {
+ csb->csb.rgb_slider_width = width;
+ if (csb->csb.visual_class == TrueColor) steps = width / 2;
+ else steps = width / 4;
+
+ ToUserSpace(csb, width, height, &w, &h);
+
+ csb->csb.red_pixmap = XCreatePixmap(XtDisplay(csb), XtWindow(csb),
+ width, height, depth);
+
+ XDPSSetContextGState(csb->csb.context, csb->csb.base_gstate);
+ XDPSSetContextDrawable(csb->csb.context, csb->csb.red_pixmap, height);
+
+ _DPSCRGBBlend(csb->csb.context, 0.0, 0.0, w, h, "0 0", steps);
+
+ csb->csb.green_pixmap = XCreatePixmap(XtDisplay(csb), XtWindow(csb),
+ width, height, depth);
+
+ XDPSSetContextDrawable(csb->csb.context,
+ csb->csb.green_pixmap, height);
+
+ _DPSCRGBBlend(csb->csb.context, 0.0, 0.0, w, h, "0 exch 0", steps);
+
+ csb->csb.blue_pixmap = XCreatePixmap(XtDisplay(csb), XtWindow(csb),
+ width, height, depth);
+
+ XDPSSetContextDrawable(csb->csb.context, csb->csb.blue_pixmap, height);
+
+ _DPSCRGBBlend(csb->csb.context,
+ 0.0, 0.0, w, h, "0 0 3 -1 roll", steps);
+
+ DPSWaitContext(csb->csb.context);
+ }
+
+ XtVaSetValues(csb->csb.slider_child[0],
+ XtNbackgroundPixmap, csb->csb.red_pixmap, NULL);
+ XtVaSetValues(csb->csb.slider_child[1],
+ XtNbackgroundPixmap, csb->csb.green_pixmap, NULL);
+ XtVaSetValues(csb->csb.slider_child[2],
+ XtNbackgroundPixmap, csb->csb.blue_pixmap, NULL);
+}
+
+static void ColorizeCMYK(ColorSelectionBoxWidget csb)
+{
+ Dimension height, width;
+ int depth, steps;
+ float w, h;
+
+ XtVaGetValues(csb->csb.slider_child[0], XtNwidth, &width,
+ XtNheight, &height,
+ XtNdepth, &depth, NULL);
+
+ if (csb->csb.cyan_pixmap != None && width != csb->csb.cmyk_slider_width) {
+ XFreePixmap(XtDisplay(csb), csb->csb.cyan_pixmap);
+ XFreePixmap(XtDisplay(csb), csb->csb.magenta_pixmap);
+ XFreePixmap(XtDisplay(csb), csb->csb.yellow_pixmap);
+ XFreePixmap(XtDisplay(csb), csb->csb.black_pixmap);
+ csb->csb.cyan_pixmap = None;
+ }
+
+ if (csb->csb.cyan_pixmap == None) {
+ csb->csb.cmyk_slider_width = width;
+ if (csb->csb.visual_class == TrueColor) steps = width / 2;
+ else steps = width / 4;
+
+ ToUserSpace(csb, width, height, &w, &h);
+
+ csb->csb.cyan_pixmap = XCreatePixmap(XtDisplay(csb), XtWindow(csb),
+ width, height, depth);
+
+ XDPSSetContextGState(csb->csb.context, csb->csb.base_gstate);
+ XDPSSetContextDrawable(csb->csb.context, csb->csb.cyan_pixmap, height);
+
+ _DPSCCMYKBlend(csb->csb.context, 0.0, 0.0, w, h, "0 0 0", steps);
+
+ csb->csb.magenta_pixmap = XCreatePixmap(XtDisplay(csb), XtWindow(csb),
+ width, height, depth);
+
+ XDPSSetContextDrawable(csb->csb.context, csb->csb.magenta_pixmap,
+ height);
+
+ _DPSCCMYKBlend(csb->csb.context, 0.0, 0.0, w, h, "0 exch 0 0", steps);
+
+ csb->csb.yellow_pixmap = XCreatePixmap(XtDisplay(csb), XtWindow(csb),
+ width, height, depth);
+
+ XDPSSetContextDrawable(csb->csb.context, csb->csb.yellow_pixmap,
+ height);
+
+ _DPSCCMYKBlend(csb->csb.context, 0.0, 0.0, w, h, "0 0 3 -1 roll 0",
+ steps);
+
+ csb->csb.black_pixmap = XCreatePixmap(XtDisplay(csb), XtWindow(csb),
+ width, height, depth);
+
+ XDPSSetContextDrawable(csb->csb.context, csb->csb.black_pixmap,
+ height);
+
+ _DPSCCMYKBlend(csb->csb.context, 0.0, 0.0, w, h, "0 0 0 4 -1 roll",
+ steps);
+
+ DPSWaitContext(csb->csb.context);
+ }
+
+ XtVaSetValues(csb->csb.slider_child[0], XtNbackgroundPixmap,
+ csb->csb.cyan_pixmap, NULL);
+ XtVaSetValues(csb->csb.slider_child[1], XtNbackgroundPixmap,
+ csb->csb.magenta_pixmap, NULL);
+ XtVaSetValues(csb->csb.slider_child[2], XtNbackgroundPixmap,
+ csb->csb.yellow_pixmap, NULL);
+ XtVaSetValues(csb->csb.slider_child[3], XtNbackgroundPixmap,
+ csb->csb.black_pixmap, NULL);
+}
+
+static void ColorizeHSB(ColorSelectionBoxWidget csb)
+{
+ Dimension height, width;
+ int depth, steps;
+ float w, h;
+
+ XtVaGetValues(csb->csb.slider_child[0], XtNwidth, &width,
+ XtNheight, &height,
+ XtNdepth, &depth, NULL);
+
+ if (csb->csb.hue_pixmap != None && width != csb->csb.hsb_slider_width) {
+ XFreePixmap(XtDisplay(csb), csb->csb.hue_pixmap);
+ XFreePixmap(XtDisplay(csb), csb->csb.sat_pixmap);
+ XFreePixmap(XtDisplay(csb), csb->csb.bright_pixmap);
+ csb->csb.hue_pixmap = None;
+ }
+
+ if (csb->csb.hue_pixmap == None) {
+ csb->csb.hsb_slider_width = width;
+ if (csb->csb.visual_class == TrueColor) steps = width / 2;
+ else steps = width / 4;
+
+ ToUserSpace(csb, width, height, &w, &h);
+
+ csb->csb.hue_pixmap = XCreatePixmap(XtDisplay(csb), XtWindow(csb),
+ width, height, depth);
+
+ XDPSSetContextGState(csb->csb.context, csb->csb.base_gstate);
+ XDPSSetContextDrawable(csb->csb.context, csb->csb.hue_pixmap, height);
+
+ _DPSCHSBBlend(csb->csb.context, 0.0, 0.0, w, h, "1 1", steps);
+
+ csb->csb.sat_pixmap = XCreatePixmap(XtDisplay(csb), XtWindow(csb),
+ width, height, depth);
+
+ XDPSSetContextDrawable(csb->csb.context, csb->csb.sat_pixmap, height);
+
+ _DPSCHSBBlend(csb->csb.context, 0.0, 0.0, w, h, "0 exch 1", steps);
+
+ csb->csb.bright_pixmap = XCreatePixmap(XtDisplay(csb), XtWindow(csb),
+ width, height, depth);
+
+ XDPSSetContextDrawable(csb->csb.context, csb->csb.bright_pixmap,
+ height);
+
+ _DPSCHSBBlend(csb->csb.context, 0.0, 0.0, w, h, "0 1 3 -1 roll",
+ steps);
+
+ DPSWaitContext(csb->csb.context);
+ }
+
+ XtVaSetValues(csb->csb.slider_child[0], XtNbackgroundPixmap,
+ csb->csb.hue_pixmap, NULL);
+ XtVaSetValues(csb->csb.slider_child[1], XtNbackgroundPixmap,
+ csb->csb.sat_pixmap, NULL);
+ XtVaSetValues(csb->csb.slider_child[2], XtNbackgroundPixmap,
+ csb->csb.bright_pixmap, NULL);
+}
+
+static void ColorizeGray(ColorSelectionBoxWidget csb)
+{
+ Dimension height, width;
+ int depth, steps;
+ float w, h;
+
+ XtVaGetValues(csb->csb.slider_child[0], XtNwidth, &width,
+ XtNheight, &height,
+ XtNdepth, &depth, NULL);
+
+ if (csb->csb.gray_pixmap != None && width != csb->csb.gray_slider_width) {
+ XFreePixmap(XtDisplay(csb), csb->csb.gray_pixmap);
+ csb->csb.gray_pixmap = None;
+ }
+
+ if (csb->csb.gray_pixmap == None) {
+ csb->csb.gray_slider_width = width;
+ if (csb->csb.visual_class == TrueColor) steps = width / 2;
+ else steps = width / 4;
+
+ ToUserSpace(csb, width, height, &w, &h);
+
+ csb->csb.gray_pixmap = XCreatePixmap(XtDisplay(csb), XtWindow(csb),
+ width, height, depth);
+
+ XDPSSetContextGState(csb->csb.context, csb->csb.base_gstate);
+ XDPSSetContextDrawable(csb->csb.context, csb->csb.gray_pixmap, height);
+
+ _DPSCGrayBlend(csb->csb.context, 0.0, 0.0, w, h, " ", steps);
+
+ DPSWaitContext(csb->csb.context);
+ }
+
+ XtVaSetValues(csb->csb.slider_child[0], XtNbackgroundPixmap,
+ csb->csb.gray_pixmap, NULL);
+}
+
+static void ColorizeSliders(ColorSelectionBoxWidget csb)
+{
+ if (!XtIsRealized(csb)) return;
+
+ switch (csb->csb.current_space) {
+ case CSBSpaceRGB:
+ ColorizeRGB(csb);
+ break;
+ case CSBSpaceCMYK:
+ ColorizeCMYK(csb);
+ break;
+ case CSBSpaceHSB:
+ ColorizeHSB(csb);
+ break;
+ case CSBSpaceGray:
+ ColorizeGray(csb);
+ break;
+ }
+}
+
+/* ARGSUSED */
+
+static void FormResize(
+ Widget w,
+ XtPointer data,
+ XEvent *event,
+ Boolean *goOn)
+{
+ ColorSelectionBoxWidget csb = (ColorSelectionBoxWidget) data;
+
+ if (event->type != ConfigureNotify && event->type != MapNotify) return;
+
+ csb->csb.rgb_slider_width = csb->csb.cmyk_slider_width =
+ csb->csb.hsb_slider_width = csb->csb.gray_slider_width = 0;
+ csb->csb.palette_pixmap_valid = False;
+ if (csb->csb.patch_gstate != 0) {
+ XDPSFreeContextGState(csb->csb.context, csb->csb.patch_gstate);
+ csb->csb.patch_gstate = 0;
+ }
+ if (csb->csb.dock_gstate != 0) {
+ XDPSFreeContextGState(csb->csb.context, csb->csb.dock_gstate);
+ csb->csb.dock_gstate = 0;
+ }
+ ColorizeSliders(csb);
+ DrawPalette(csb);
+ if (XtIsRealized(csb->csb.patch_child)) {
+ XClearArea(XtDisplay(csb), XtWindow(csb->csb.patch_child),
+ 0, 0, 1000, 1000, True);
+ }
+}
+
+static void FillCallbackRec(
+ ColorSelectionBoxWidget csb,
+ CSBCallbackRec *rec)
+{
+ rec->current_space = csb->csb.current_space;
+ rec->red = csb->csb.current_color.red;
+ rec->green = csb->csb.current_color.green;
+ rec->blue = csb->csb.current_color.blue;
+ rec->cyan = csb->csb.current_color.cyan;
+ rec->magenta = csb->csb.current_color.magenta;
+ rec->yellow = csb->csb.current_color.yellow;
+ rec->black = csb->csb.current_color.black;
+ rec->hue = csb->csb.current_color.hue;
+ rec->saturation = csb->csb.current_color.saturation;
+ rec->brightness = csb->csb.current_color.brightness;
+ rec->gray = csb->csb.current_color.gray;
+}
+
+/* ARGSUSED */
+
+static void OKCallback(
+ Widget w,
+ XtPointer clientData, XtPointer callData)
+{
+ ColorSelectionBoxWidget csb = (ColorSelectionBoxWidget) clientData;
+ CSBCallbackRec rec;
+
+ csb->csb.save_color = csb->csb.current_color;
+ FillCallbackRec(csb, &rec);
+ rec.reason = CSBOK;
+ XtCallCallbackList((Widget) csb, csb->csb.ok_callback, (XtPointer) &rec);
+ if (XtIsShell(XtParent(csb))) XtPopdown(XtParent(csb));
+
+ SaveDockContents(csb);
+}
+
+/* ARGSUSED */
+
+static void ApplyCallback(
+ Widget w,
+ XtPointer clientData, XtPointer callData)
+{
+ ColorSelectionBoxWidget csb = (ColorSelectionBoxWidget) clientData;
+ CSBCallbackRec rec;
+
+ csb->csb.save_color = csb->csb.current_color;
+ FillCallbackRec(csb, &rec);
+ rec.reason = CSBApply;
+ XtCallCallbackList((Widget) csb, csb->csb.apply_callback,
+ (XtPointer) &rec);
+
+ SaveDockContents(csb);
+}
+
+/* ARGSUSED */
+
+static void ResetCallback(
+ Widget w,
+ XtPointer clientData, XtPointer callData)
+{
+ ColorSelectionBoxWidget csb = (ColorSelectionBoxWidget) clientData;
+ CSBCallbackRec rec;
+
+ csb->csb.current_color = csb->csb.save_color;
+ FillPatch(csb);
+ SetSliders(csb);
+ FillCallbackRec(csb, &rec);
+ rec.reason = CSBReset;
+ XtCallCallbackList((Widget) csb, csb->csb.reset_callback,
+ (XtPointer) &rec);
+}
+
+/* ARGSUSED */
+
+static void CancelCallback(
+ Widget w,
+ XtPointer clientData, XtPointer callData)
+{
+ ColorSelectionBoxWidget csb = (ColorSelectionBoxWidget) clientData;
+ CSBCallbackRec rec;
+
+ csb->csb.current_color = csb->csb.save_color;
+ FillPatch(csb);
+ SetSliders(csb);
+ FillCallbackRec(csb, &rec);
+ rec.reason = CSBCancel;
+ XtCallCallbackList((Widget) csb, csb->csb.cancel_callback,
+ (XtPointer) &rec);
+ if (XtIsShell(XtParent(csb))) XtPopdown(XtParent(csb));
+}
+
+/* ARGSUSED */
+
+static void DoValueChangedCallback(ColorSelectionBoxWidget csb)
+{
+ CSBCallbackRec rec;
+
+ FillCallbackRec(csb, &rec);
+ rec.reason = CSBValueChanged;
+ XtCallCallbackList((Widget) csb, csb->csb.value_changed_callback,
+ (XtPointer) &rec);
+}
+
+/* ARGSUSED */
+
+static void ChangeLabelCallback(
+ Widget w,
+ XtPointer clientData, XtPointer callData)
+{
+ XmScaleCallbackStruct *scaleData = (XmScaleCallbackStruct *) callData;
+
+ ChangeLabel((Widget) clientData, ((float) scaleData->value) / 100.0);
+}
+
+static void ChangeLabel(Widget label, double n)
+{
+ char buf[10];
+
+ sprintf(buf, "%d", TO_PCT(n));
+ XtVaSetValues(label, XmNlabelString, CS(buf, label), NULL);
+}
+
+static void CreateModelMenu(Widget parent, Widget csb)
+{
+ Widget kids[4];
+
+ kids[0] = XmCreatePushButtonGadget(parent, "rgb", (ArgList) NULL, 0);
+ XtAddCallback(kids[0], XmNactivateCallback,
+ SetRGBCallback, (XtPointer) csb);
+ kids[1] = XmCreatePushButtonGadget(parent, "cmyk", (ArgList) NULL, 0);
+ XtAddCallback(kids[1], XmNactivateCallback,
+ SetCMYKCallback, (XtPointer) csb);
+ kids[2] = XmCreatePushButtonGadget(parent, "hsb", (ArgList) NULL, 0);
+ XtAddCallback(kids[2], XmNactivateCallback,
+ SetHSBCallback, (XtPointer) csb);
+ kids[3] = XmCreatePushButtonGadget(parent, "gray", (ArgList) NULL, 0);
+ XtAddCallback(kids[3], XmNactivateCallback,
+ SetGrayCallback, (XtPointer) csb);
+
+ XtManageChildren(kids, 4);
+}
+
+typedef struct {
+ ColorSelectionBoxWidget csb;
+ CSBRenderingType rendering;
+} RenderingRec;
+
+/* ARGSUSED */
+
+static void SetRenderingCallback(
+ Widget w,
+ XtPointer clientData, XtPointer callData)
+{
+ RenderingRec *r = (RenderingRec *) clientData;
+
+ r->csb->csb.current_rendering = r->rendering;
+ FillPatch(r->csb);
+}
+
+static void CreateDisplayMenu(Widget parent, ColorSelectionBoxWidget csb)
+{
+ Widget kids[3];
+ RenderingRec *r;
+
+ r = XtNew(RenderingRec);
+ r->csb = csb;
+ r->rendering = CSBDisplayDPS;
+ kids[0] = XmCreatePushButtonGadget(parent, "displayDPS",
+ (ArgList) NULL, 0);
+ XtAddCallback(kids[0], XmNactivateCallback,
+ SetRenderingCallback, (XtPointer) r);
+ r = XtNew(RenderingRec);
+ r->csb = csb;
+ r->rendering = CSBDisplayX;
+ kids[1] = XmCreatePushButtonGadget(parent, "displayX", (ArgList) NULL, 0);
+ XtAddCallback(kids[1], XmNactivateCallback,
+ SetRenderingCallback, (XtPointer) r);
+ r = XtNew(RenderingRec);
+ r->csb = csb;
+ r->rendering = CSBDisplayBoth;
+ kids[2] = XmCreatePushButtonGadget(parent, "displayBoth",
+ (ArgList) NULL, 0);
+ XtAddCallback(kids[2], XmNactivateCallback,
+ SetRenderingCallback, (XtPointer) r);
+
+ XtManageChildren(kids, 3);
+}
+
+typedef struct {
+ ColorSelectionBoxWidget csb;
+ int n;
+} PaletteRec;
+
+/* ARGSUSED */
+
+static void SetPaletteCallback(
+ Widget w,
+ XtPointer clientData, XtPointer callData)
+{
+ PaletteRec *p = (PaletteRec *) clientData;
+
+ if (p->csb->csb.palette_broken[p->n]) return;
+
+ if (p->n != p->csb->csb.current_palette ||
+ p->csb->csb.palette_color_dependent[p->n]) {
+ p->csb->csb.palette_pixmap_valid = False;
+ }
+
+ p->csb->csb.current_palette = p->n;
+ DrawPalette(p->csb);
+}
+
+static void CreatePaletteMenu(Widget parent, ColorSelectionBoxWidget csb)
+{
+ Widget w, managed[PALETTE_MAX];
+ int j, k;
+ char buf[10];
+ PaletteRec *p;
+
+ j = 0;
+
+ for (k = 0; k < PALETTE_MAX; k++) {
+ p = XtNew(PaletteRec);
+ p->csb = csb;
+ p->n = k;
+ sprintf(buf, "palette%d", k);
+ w = XtVaCreateWidget(buf, xmPushButtonGadgetClass, parent, NULL);
+ if (csb->csb.palette_label[k] != NULL) {
+ XtVaSetValues(w, XtVaTypedArg, XmNlabelString,
+ XtRString, csb->csb.palette_label[k],
+ strlen(csb->csb.palette_label[k])+1,
+ NULL);
+ }
+ XtAddCallback(w, XmNactivateCallback,
+ SetPaletteCallback, (XtPointer) p);
+ if (csb->csb.palette_function[k] != NULL) managed[j++] = w;
+ }
+
+ if (j != 0) XtManageChildren(managed, j);
+}
+
+static void CreateChildren(ColorSelectionBoxWidget csb)
+{
+ int i;
+ Arg args[20];
+ Widget form, menu, button, w, dock_frame, palette_frame;
+ Pixel fg, bg;
+ int depth;
+ Pixmap eyedrop;
+
+ i = 0;
+ XtSetArg(args[i], XmNresizePolicy, XmRESIZE_NONE); i++;
+ form = XtCreateManagedWidget("panel", xmFormWidgetClass,
+ (Widget) csb, args, i);
+ csb->csb.form_child = form;
+ XtAddEventHandler(form, StructureNotifyMask, False, FormResize,
+ (XtPointer) csb);
+
+ i = 0;
+ menu = XmCreatePulldownMenu(form, "modelMenu", args, i);
+ CreateModelMenu(menu, (Widget) csb);
+
+ i = 0;
+ XtSetArg(args[i], XmNleftAttachment, XmATTACH_FORM); i++;
+ XtSetArg(args[i], XmNtopAttachment, XmATTACH_FORM); i++;
+ XtSetArg(args[i], XmNsubMenuId, menu); i++;
+ csb->csb.model_option_menu_child =
+ XmCreateOptionMenu(form, "modelOptionMenu",
+ args, i);
+ XtManageChild(csb->csb.model_option_menu_child);
+
+ XtVaGetValues(form, XtNbackground, &bg, XmNforeground, &fg,
+ XtNdepth, &depth, NULL);
+ eyedrop = XCreatePixmapFromBitmapData(XtDisplay(csb),
+ RootWindowOfScreen(XtScreen(csb)),
+ (char *) heyedrop_bits,
+ heyedrop_width, heyedrop_height,
+ fg, bg, depth);
+
+ i = 0;
+ XtSetArg(args[i], XmNleftAttachment, XmATTACH_WIDGET); i++;
+ XtSetArg(args[i], XmNleftWidget, csb->csb.model_option_menu_child); i++;
+ XtSetArg(args[i], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); i++;
+ XtSetArg(args[i], XmNtopWidget, csb->csb.model_option_menu_child); i++;
+ XtSetArg(args[i], XmNlabelPixmap, eyedrop); i++;
+ button = XtCreateManagedWidget("eyedropButton", xmPushButtonWidgetClass,
+ form, args, i);
+ XtAddCallback(button, XmNactivateCallback,
+ DoEyedropCallback, (XtPointer) csb);
+ XtInsertRawEventHandler(button, PointerMotionMask | ButtonReleaseMask,
+ False, EyedropPointer, (XtPointer) csb,
+ XtListHead);
+
+ i = 0;
+ XtSetArg(args[i], XmNleftAttachment, XmATTACH_FORM); i++;
+ XtSetArg(args[i], XmNtopAttachment, XmATTACH_WIDGET); i++;
+ XtSetArg(args[i], XmNtopWidget, csb->csb.model_option_menu_child); i++;
+ csb->csb.label_child[0] =
+ XtCreateManagedWidget("label1", xmLabelWidgetClass, form, args, i);
+
+ i = 0;
+ XtSetArg(args[i], XmNtopAttachment, XmATTACH_WIDGET); i++;
+ XtSetArg(args[i], XmNtopWidget, csb->csb.model_option_menu_child); i++;
+ XtSetArg(args[i], XmNrightAttachment, XmATTACH_POSITION); i++;
+ csb->csb.value_child[0] =
+ XtCreateManagedWidget("value1", xmLabelWidgetClass, form, args, i);
+
+ i = 0;
+ XtSetArg(args[i], XmNleftAttachment, XmATTACH_WIDGET); i++;
+ XtSetArg(args[i], XmNleftWidget, csb->csb.label_child[0]); i++;
+ XtSetArg(args[i], XmNtopAttachment, XmATTACH_WIDGET); i++;
+ XtSetArg(args[i], XmNtopWidget, csb->csb.model_option_menu_child); i++;
+ XtSetArg(args[i], XmNrightAttachment, XmATTACH_WIDGET); i++;
+ XtSetArg(args[i], XmNrightWidget, csb->csb.value_child[0]); i++;
+ csb->csb.slider_child[0] =
+ XtCreateManagedWidget("slider1", xmScaleWidgetClass,
+ form, args, i);
+ XtAddCallback(csb->csb.slider_child[0], XmNvalueChangedCallback,
+ ChangeLabelCallback, (XtPointer) csb->csb.value_child[0]);
+ XtAddCallback(csb->csb.slider_child[0], XmNdragCallback,
+ ChangeLabelCallback, (XtPointer) csb->csb.value_child[0]);
+ XtAddCallback(csb->csb.slider_child[0], XmNvalueChangedCallback,
+ Slider1Callback, (XtPointer) csb);
+ XtAddCallback(csb->csb.slider_child[0], XmNdragCallback,
+ Slider1Callback, (XtPointer) csb);
+
+ i = 0;
+ XtSetArg(args[i], XmNleftAttachment, XmATTACH_FORM); i++;
+ XtSetArg(args[i], XmNtopAttachment, XmATTACH_WIDGET); i++;
+ XtSetArg(args[i], XmNtopWidget, csb->csb.slider_child[0]); i++;
+ csb->csb.label_child[1] =
+ XtCreateManagedWidget("label2", xmLabelWidgetClass, form, args, i);
+
+ i = 0;
+ XtSetArg(args[i], XmNtopAttachment, XmATTACH_WIDGET); i++;
+ XtSetArg(args[i], XmNtopWidget, csb->csb.slider_child[0]); i++;
+ XtSetArg(args[i], XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET); i++;
+ XtSetArg(args[i], XmNrightWidget, csb->csb.value_child[0]); i++;
+ csb->csb.value_child[1] =
+ XtCreateManagedWidget("value2", xmLabelWidgetClass, form, args, i);
+
+ i = 0;
+ XtSetArg(args[i], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET); i++;
+ XtSetArg(args[i], XmNleftWidget, csb->csb.slider_child[0]); i++;
+ XtSetArg(args[i], XmNtopAttachment, XmATTACH_WIDGET); i++;
+ XtSetArg(args[i], XmNtopWidget, csb->csb.slider_child[0]); i++;
+ XtSetArg(args[i], XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET); i++;
+ XtSetArg(args[i], XmNrightWidget, csb->csb.slider_child[0]); i++;
+ csb->csb.slider_child[1] =
+ XtCreateManagedWidget("slider2", xmScaleWidgetClass,
+ form, args, i);
+ XtAddCallback(csb->csb.slider_child[1], XmNvalueChangedCallback,
+ ChangeLabelCallback, (XtPointer) csb->csb.value_child[1]);
+ XtAddCallback(csb->csb.slider_child[1], XmNdragCallback,
+ ChangeLabelCallback, (XtPointer) csb->csb.value_child[1]);
+ XtAddCallback(csb->csb.slider_child[1], XmNvalueChangedCallback,
+ Slider2Callback, (XtPointer) csb);
+ XtAddCallback(csb->csb.slider_child[1], XmNdragCallback,
+ Slider2Callback, (XtPointer) csb);
+
+ i = 0;
+ XtSetArg(args[i], XmNleftAttachment, XmATTACH_FORM); i++;
+ XtSetArg(args[i], XmNtopAttachment, XmATTACH_WIDGET); i++;
+ XtSetArg(args[i], XmNtopWidget, csb->csb.slider_child[1]); i++;
+ csb->csb.label_child[2] =
+ XtCreateManagedWidget("label3", xmLabelWidgetClass, form, args, i);
+
+ i = 0;
+ XtSetArg(args[i], XmNtopAttachment, XmATTACH_WIDGET); i++;
+ XtSetArg(args[i], XmNtopWidget, csb->csb.slider_child[1]); i++;
+ XtSetArg(args[i], XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET); i++;
+ XtSetArg(args[i], XmNrightWidget, csb->csb.value_child[0]); i++;
+ csb->csb.value_child[2] =
+ XtCreateManagedWidget("value3", xmLabelWidgetClass, form, args, i);
+
+ i = 0;
+ XtSetArg(args[i], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET); i++;
+ XtSetArg(args[i], XmNleftWidget, csb->csb.slider_child[0]); i++;
+ XtSetArg(args[i], XmNtopAttachment, XmATTACH_WIDGET); i++;
+ XtSetArg(args[i], XmNtopWidget, csb->csb.slider_child[1]); i++;
+ XtSetArg(args[i], XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET); i++;
+ XtSetArg(args[i], XmNrightWidget, csb->csb.slider_child[0]); i++;
+ csb->csb.slider_child[2] =
+ XtCreateManagedWidget("slider3", xmScaleWidgetClass,
+ form, args, i);
+ XtAddCallback(csb->csb.slider_child[2], XmNvalueChangedCallback,
+ ChangeLabelCallback, (XtPointer) csb->csb.value_child[2]);
+ XtAddCallback(csb->csb.slider_child[2], XmNdragCallback,
+ ChangeLabelCallback, (XtPointer) csb->csb.value_child[2]);
+ XtAddCallback(csb->csb.slider_child[2], XmNvalueChangedCallback,
+ Slider3Callback, (XtPointer) csb);
+ XtAddCallback(csb->csb.slider_child[2], XmNdragCallback,
+ Slider3Callback, (XtPointer) csb);
+
+ i = 0;
+ XtSetArg(args[i], XmNleftAttachment, XmATTACH_FORM); i++;
+ XtSetArg(args[i], XmNtopAttachment, XmATTACH_WIDGET); i++;
+ XtSetArg(args[i], XmNtopWidget, csb->csb.slider_child[2]); i++;
+ csb->csb.label_child[3] =
+ XtCreateManagedWidget("label4", xmLabelWidgetClass, form, args, i);
+
+ i = 0;
+ XtSetArg(args[i], XmNtopAttachment, XmATTACH_WIDGET); i++;
+ XtSetArg(args[i], XmNtopWidget, csb->csb.slider_child[2]); i++;
+ XtSetArg(args[i], XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET); i++;
+ XtSetArg(args[i], XmNrightWidget, csb->csb.value_child[0]); i++;
+ csb->csb.value_child[3] =
+ XtCreateManagedWidget("value4", xmLabelWidgetClass, form, args, i);
+
+ i = 0;
+ XtSetArg(args[i], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET); i++;
+ XtSetArg(args[i], XmNleftWidget, csb->csb.slider_child[0]); i++;
+ XtSetArg(args[i], XmNtopAttachment, XmATTACH_WIDGET); i++;
+ XtSetArg(args[i], XmNtopWidget, csb->csb.slider_child[2]); i++;
+ XtSetArg(args[i], XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET); i++;
+ XtSetArg(args[i], XmNrightWidget, csb->csb.slider_child[0]); i++;
+ csb->csb.slider_child[3] =
+ XtCreateManagedWidget("slider4", xmScaleWidgetClass,
+ form, args, i);
+ XtAddCallback(csb->csb.slider_child[3], XmNvalueChangedCallback,
+ ChangeLabelCallback, (XtPointer) csb->csb.value_child[3]);
+ XtAddCallback(csb->csb.slider_child[3], XmNdragCallback,
+ ChangeLabelCallback, (XtPointer) csb->csb.value_child[3]);
+ XtAddCallback(csb->csb.slider_child[3], XmNvalueChangedCallback,
+ Slider4Callback, (XtPointer) csb);
+ XtAddCallback(csb->csb.slider_child[3], XmNdragCallback,
+ Slider4Callback, (XtPointer) csb);
+
+ i = 0;
+ XtSetArg(args[i], XmNleftAttachment, XmATTACH_FORM); i++;
+ XtSetArg(args[i], XmNbottomAttachment, XmATTACH_FORM); i++;
+ button = XtCreateManagedWidget("okButton", xmPushButtonWidgetClass,
+ form, args, i);
+ XtAddCallback(button, XmNactivateCallback, OKCallback, (XtPointer) csb);
+
+ i = 0;
+ XtSetArg(args[i], XmNdefaultButton, button); i++;
+ XtSetValues(form, args, i);
+
+ i = 0;
+ XtSetArg(args[i], XmNleftAttachment, XmATTACH_WIDGET); i++;
+ XtSetArg(args[i], XmNleftWidget, button); i++;
+ XtSetArg(args[i], XmNbottomAttachment, XmATTACH_FORM); i++;
+ button = XtCreateManagedWidget("applyButton", xmPushButtonWidgetClass,
+ form, args, i);
+
+ XtAddCallback(button, XmNactivateCallback, ApplyCallback, (XtPointer) csb);
+
+ i = 0;
+ XtSetArg(args[i], XmNleftAttachment, XmATTACH_WIDGET); i++;
+ XtSetArg(args[i], XmNleftWidget, button); i++;
+ XtSetArg(args[i], XmNbottomAttachment, XmATTACH_FORM); i++;
+ button = XtCreateManagedWidget("resetButton", xmPushButtonWidgetClass,
+ form, args, i);
+ XtAddCallback(button, XmNactivateCallback, ResetCallback, (XtPointer) csb);
+
+ i = 0;
+ XtSetArg(args[i], XmNleftAttachment, XmATTACH_WIDGET); i++;
+ XtSetArg(args[i], XmNleftWidget, button); i++;
+ XtSetArg(args[i], XmNbottomAttachment, XmATTACH_FORM); i++;
+ button = XtCreateManagedWidget("cancelButton", xmPushButtonWidgetClass,
+ form, args, i);
+ XtAddCallback(button, XmNactivateCallback,
+ CancelCallback, (XtPointer) csb);
+
+ i = 0;
+ XtSetArg(args[i], XmNleftAttachment, XmATTACH_FORM); i++;
+ XtSetArg(args[i], XmNrightAttachment, XmATTACH_FORM); i++;
+ XtSetArg(args[i], XmNbottomAttachment, XmATTACH_WIDGET); i++;
+ XtSetArg(args[i], XmNbottomWidget, button); i++;
+ w = XtCreateManagedWidget("separator", xmSeparatorGadgetClass,
+ form, args, i);
+
+ i = 0;
+ XtSetArg(args[i], XmNleftAttachment, XmATTACH_FORM); i++;
+ XtSetArg(args[i], XmNrightAttachment, XmATTACH_FORM); i++;
+ XtSetArg(args[i], XmNbottomAttachment, XmATTACH_WIDGET); i++;
+ XtSetArg(args[i], XmNbottomWidget, w); i++;
+ palette_frame = XtCreateManagedWidget("paletteFrame", xmFrameWidgetClass,
+ form, args, i);
+
+ i = 0;
+ csb->csb.palette_child =
+ XtCreateManagedWidget("palette", xmDrawingAreaWidgetClass,
+ palette_frame, args, i);
+ XtAddCallback(csb->csb.palette_child, XmNexposeCallback,
+ DrawPaletteCallback, (XtPointer) csb);
+ XtAddEventHandler(csb->csb.palette_child, ButtonPressMask, False,
+ PalettePress, (XtPointer) csb);
+
+ i = 0;
+ menu = XmCreatePulldownMenu(form, "paletteMenu", args, i);
+ CreatePaletteMenu(menu, csb);
+
+ i = 0;
+ XtSetArg(args[i], XmNleftAttachment, XmATTACH_FORM); i++;
+ XtSetArg(args[i], XmNbottomAttachment, XmATTACH_WIDGET); i++;
+ XtSetArg(args[i], XmNbottomWidget, palette_frame); i++;
+ XtSetArg(args[i], XmNsubMenuId, menu); i++;
+ csb->csb.palette_option_menu_child =
+ XmCreateOptionMenu(form, "paletteOptionMenu",
+ args, i);
+ XtManageChild(csb->csb.palette_option_menu_child);
+
+ i = 0;
+ menu = XmCreatePulldownMenu(form, "displayMenu", args, i);
+ CreateDisplayMenu(menu, csb);
+
+ i = 0;
+ XtSetArg(args[i], XmNleftAttachment, XmATTACH_POSITION); i++;
+ XtSetArg(args[i], XmNrightAttachment, XmATTACH_FORM); i++;
+ XtSetArg(args[i], XmNtopAttachment, XmATTACH_FORM); i++;
+ XtSetArg(args[i], XmNsubMenuId, menu); i++;
+ csb->csb.display_option_menu_child =
+ XmCreateOptionMenu(form, "displayOptionMenu",
+ args, i);
+ XtManageChild(csb->csb.display_option_menu_child);
+
+ i = 0;
+ XtSetArg(args[i], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET); i++;
+ XtSetArg(args[i], XmNleftWidget, csb->csb.display_option_menu_child);i++;
+ XtSetArg(args[i], XmNrightAttachment, XmATTACH_FORM); i++;
+ XtSetArg(args[i], XmNbottomAttachment, XmATTACH_WIDGET); i++;
+ XtSetArg(args[i], XmNbottomWidget, palette_frame); i++;
+ dock_frame = XtCreateManagedWidget("dockFrame", xmFrameWidgetClass,
+ form, args, i);
+
+ i = 0;
+ csb->csb.dock_child =
+ XtCreateManagedWidget("dock", xmDrawingAreaWidgetClass,
+ dock_frame, args, i);
+ XtAddCallback(csb->csb.dock_child, XmNexposeCallback,
+ DrawDockCallback, (XtPointer) csb);
+ XtAddEventHandler(csb->csb.dock_child, ButtonPressMask, False, DockPress,
+ (XtPointer) csb);
+
+ {
+ Dimension height;
+ int q;
+
+ XtVaGetValues(csb->csb.dock_child, XtNheight, &height, NULL);
+ if (height < csb->csb.cell_size) height = csb->csb.cell_size;
+ else if (height % csb->csb.cell_size != 0) {
+ q = height / csb->csb.cell_size;
+ height = csb->csb.cell_size * q;
+ }
+ XtVaSetValues(csb->csb.dock_child, XtNheight, height, NULL);
+ }
+
+ i = 0;
+ XtSetArg(args[i], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET); i++;
+ XtSetArg(args[i], XmNleftWidget, dock_frame); i++;
+ XtSetArg(args[i], XmNrightAttachment, XmATTACH_FORM); i++;
+ XtSetArg(args[i], XmNtopAttachment, XmATTACH_WIDGET); i++;
+ XtSetArg(args[i], XmNtopWidget, csb->csb.display_option_menu_child);i++;
+ XtSetArg(args[i], XmNbottomAttachment, XmATTACH_WIDGET); i++;
+ XtSetArg(args[i], XmNbottomWidget, dock_frame); i++;
+ w = XtCreateManagedWidget("patchFrame", xmFrameWidgetClass,
+ form, args, i);
+
+ i = 0;
+ csb->csb.patch_child =
+ XtCreateManagedWidget("patch", xmDrawingAreaWidgetClass,
+ w, args, i);
+ XtAddCallback(csb->csb.patch_child, XmNexposeCallback,
+ FillPatchCallback, (XtPointer) csb);
+ XtAddRawEventHandler(csb->csb.patch_child, ButtonPressMask,
+ False, PatchPress, (XtPointer) csb);
+ XtAddRawEventHandler(csb->csb.patch_child, ButtonReleaseMask,
+ False, PatchRelease, (XtPointer) csb);
+}
+
+static void NoBackgroundPixel(ColorSelectionBoxWidget csb)
+{
+ Widget w, message;
+
+ csb->csb.no_background = True;
+ w = XtNameToWidget((Widget) csb, "*displayX");
+ XtSetSensitive(w, False);
+ w = XtNameToWidget((Widget) csb, "*displayBoth");
+ XtSetSensitive(w, False);
+ w = XtNameToWidget((Widget) csb, "*displayDPS");
+ XtVaSetValues(csb->csb.display_option_menu_child, XmNmenuHistory, w, NULL);
+
+ message = XmCreateInformationDialog(csb->csb.form_child,
+ "noBackgroundMessage",
+ (ArgList) NULL, 0);
+ w = XmMessageBoxGetChild(message, XmDIALOG_CANCEL_BUTTON);
+ XtUnmanageChild(w);
+ w = XmMessageBoxGetChild(message, XmDIALOG_HELP_BUTTON);
+ XtUnmanageChild(w);
+
+ XtManageChild(message);
+}
+
+/* labelString is changed by this */
+
+static void ParseLabels(String labelString, String labels[4], int n)
+{
+ register char *ch;
+ int i;
+
+ ch = labelString;
+ for (i = 0; i < n; i++) {
+ labels[i] = ch;
+ while (*ch != ':' && *ch != '\0') ch++;
+ *ch++ = '\0';
+ }
+
+ for (i = n; i < 4; i++) labels[i] = NULL;
+}
+
+static void SetLabels(ColorSelectionBoxWidget csb, String *labels)
+{
+ Widget w = (Widget) csb;
+ int i;
+
+ for (i = 0; i < 4; i++) {
+ if (labels[i] != NULL) {
+ XtVaSetValues(csb->csb.label_child[i],
+ XmNlabelString, CS(labels[i], w), NULL);
+ }
+ }
+}
+
+static void MapChildren(Widget *children, int n)
+{
+ XtManageChildren(children, n);
+}
+
+static void UnmapChildren(Widget *children, int n)
+{
+ XtUnmanageChildren(children, n);
+}
+
+static void SetSliders(ColorSelectionBoxWidget csb)
+{
+ switch(csb->csb.current_space) {
+ case CSBSpaceRGB: SetRGBValues(csb); break;
+ case CSBSpaceCMYK: SetCMYKValues(csb); break;
+ case CSBSpaceHSB: SetHSBValues(csb); break;
+ case CSBSpaceGray: SetGrayValues(csb); break;
+ }
+}
+
+static void SetRGBValues(ColorSelectionBoxWidget csb)
+{
+ XmScaleSetValue(csb->csb.slider_child[0],
+ TO_PCT(csb->csb.current_color.red));
+ XmScaleSetValue(csb->csb.slider_child[1],
+ TO_PCT(csb->csb.current_color.green));
+ XmScaleSetValue(csb->csb.slider_child[2],
+ TO_PCT(csb->csb.current_color.blue));
+ ChangeLabel(csb->csb.value_child[0], csb->csb.current_color.red);
+ ChangeLabel(csb->csb.value_child[1], csb->csb.current_color.green);
+ ChangeLabel(csb->csb.value_child[2], csb->csb.current_color.blue);
+}
+
+/* ARGSUSED */
+
+static void SetRGBCallback(
+ Widget w,
+ XtPointer clientData, XtPointer callData)
+{
+ ColorSelectionBoxWidget csb = (ColorSelectionBoxWidget) clientData;
+ Widget rgb;
+ Widget children[6];
+ String labels[4];
+ int i, j;
+
+ csb->csb.current_space = CSBSpaceRGB;
+
+ ParseLabels(csb->csb.rgb_labels, labels, 3);
+
+ rgb = XtNameToWidget((Widget) csb, "*rgb");
+
+ XtVaSetValues(csb->csb.model_option_menu_child, XmNmenuHistory, rgb, NULL);
+
+ SetLabels(csb, labels);
+
+ SetRGBValues(csb);
+
+ j = 0;
+ for (i = 1; i < 3; i++) {
+ children[j++] = csb->csb.label_child[i];
+ children[j++] = csb->csb.slider_child[i];
+ children[j++] = csb->csb.value_child[i];
+ }
+
+ MapChildren(children, 6);
+
+ children[0] = csb->csb.label_child[3];
+ children[1] = csb->csb.slider_child[3];
+ children[2] = csb->csb.value_child[3];
+
+ UnmapChildren(children, 3);
+
+ ColorizeSliders(csb);
+ FillPatch(csb);
+}
+
+static void SetCMYKValues(ColorSelectionBoxWidget csb)
+{
+ XmScaleSetValue(csb->csb.slider_child[0],
+ TO_PCT(csb->csb.current_color.cyan));
+ XmScaleSetValue(csb->csb.slider_child[1],
+ TO_PCT(csb->csb.current_color.magenta));
+ XmScaleSetValue(csb->csb.slider_child[2],
+ TO_PCT(csb->csb.current_color.yellow));
+ XmScaleSetValue(csb->csb.slider_child[3],
+ TO_PCT(csb->csb.current_color.black));
+ ChangeLabel(csb->csb.value_child[0], csb->csb.current_color.cyan);
+ ChangeLabel(csb->csb.value_child[1], csb->csb.current_color.magenta);
+ ChangeLabel(csb->csb.value_child[2], csb->csb.current_color.yellow);
+ ChangeLabel(csb->csb.value_child[3], csb->csb.current_color.black);
+}
+
+/* ARGSUSED */
+
+static void SetCMYKCallback(
+ Widget w,
+ XtPointer clientData, XtPointer callData)
+{
+ ColorSelectionBoxWidget csb = (ColorSelectionBoxWidget) clientData;
+ Widget cmyk;
+ Widget children[9];
+ String labels[4];
+ int i, j;
+
+ csb->csb.current_space = CSBSpaceCMYK;
+
+ ParseLabels(csb->csb.cmyk_labels, labels, 4);
+
+ cmyk = XtNameToWidget((Widget) csb, "*cmyk");
+
+ XtVaSetValues(csb->csb.model_option_menu_child,
+ XmNmenuHistory, cmyk, NULL);
+
+ SetLabels(csb, labels);
+
+ SetCMYKValues(csb);
+
+ j = 0;
+ for (i = 1; i < 4; i++) {
+ children[j++] = csb->csb.label_child[i];
+ children[j++] = csb->csb.slider_child[i];
+ children[j++] = csb->csb.value_child[i];
+ }
+
+ MapChildren(children, 9);
+
+ ColorizeSliders(csb);
+ FillPatch(csb);
+}
+
+static void SetHSBValues(ColorSelectionBoxWidget csb)
+{
+ XmScaleSetValue(csb->csb.slider_child[0],
+ TO_PCT(csb->csb.current_color.hue));
+ XmScaleSetValue(csb->csb.slider_child[1],
+ TO_PCT(csb->csb.current_color.saturation));
+ XmScaleSetValue(csb->csb.slider_child[2],
+ TO_PCT(csb->csb.current_color.brightness));
+ ChangeLabel(csb->csb.value_child[0], csb->csb.current_color.hue);
+ ChangeLabel(csb->csb.value_child[1], csb->csb.current_color.saturation);
+ ChangeLabel(csb->csb.value_child[2], csb->csb.current_color.brightness);
+}
+
+/* ARGSUSED */
+
+static void SetHSBCallback(
+ Widget w,
+ XtPointer clientData, XtPointer callData)
+{
+ ColorSelectionBoxWidget csb = (ColorSelectionBoxWidget) clientData;
+ Widget hsb;
+ Widget children[6];
+ String labels[4];
+ int i, j;
+
+ csb->csb.current_space = CSBSpaceHSB;
+
+ ParseLabels(csb->csb.hsb_labels, labels, 3);
+
+ hsb = XtNameToWidget((Widget) csb, "*hsb");
+
+ XtVaSetValues(csb->csb.model_option_menu_child, XmNmenuHistory, hsb, NULL);
+
+ SetLabels(csb, labels);
+
+ SetHSBValues(csb);
+
+ j = 0;
+ for (i = 1; i < 3; i++) {
+ children[j++] = csb->csb.label_child[i];
+ children[j++] = csb->csb.slider_child[i];
+ children[j++] = csb->csb.value_child[i];
+ }
+
+ MapChildren(children, 6);
+
+ children[0] = csb->csb.label_child[3];
+ children[1] = csb->csb.slider_child[3];
+ children[2] = csb->csb.value_child[3];
+
+ UnmapChildren(children, 3);
+
+ ColorizeSliders(csb);
+ FillPatch(csb);
+}
+
+static void SetGrayValues(ColorSelectionBoxWidget csb)
+{
+ XmScaleSetValue(csb->csb.slider_child[0],
+ TO_PCT(csb->csb.current_color.gray));
+ ChangeLabel(csb->csb.value_child[0], csb->csb.current_color.gray);
+}
+
+/* ARGSUSED */
+
+static void SetGrayCallback(
+ Widget w,
+ XtPointer clientData, XtPointer callData)
+{
+ ColorSelectionBoxWidget csb = (ColorSelectionBoxWidget) clientData;
+ Widget gray;
+ Widget children[9];
+ String labels[4];
+ int i, j;
+
+ csb->csb.current_space = CSBSpaceGray;
+
+ gray = XtNameToWidget((Widget) csb, "*gray");
+
+ XtVaSetValues(csb->csb.model_option_menu_child, XmNmenuHistory, gray, NULL);
+
+ labels[0] = csb->csb.gray_labels;
+ labels[1] = labels[2] = labels[3] = NULL;
+ SetLabels(csb, labels);
+
+ SetGrayValues(csb);
+
+ j = 0;
+ for (i = 1; i < 4; i++) {
+ children[j++] = csb->csb.label_child[i];
+ children[j++] = csb->csb.slider_child[i];
+ children[j++] = csb->csb.value_child[i];
+ }
+
+ UnmapChildren(children, 9);
+
+ ColorizeSliders(csb);
+ FillPatch(csb);
+}
+
+static void RGBToCMYK(ColorSelectionBoxWidget csb)
+{
+ csb->csb.current_color.cyan = 1.0 - csb->csb.current_color.red;
+ csb->csb.current_color.magenta = 1.0 - csb->csb.current_color.green;
+ csb->csb.current_color.yellow = 1.0 - csb->csb.current_color.blue;
+ csb->csb.current_color.black = 0.0;
+}
+
+static void RGBToGray(ColorSelectionBoxWidget csb)
+{
+ csb->csb.current_color.gray = .3 * csb->csb.current_color.red +
+ .59 * csb->csb.current_color.green +
+ .11 * csb->csb.current_color.blue;
+}
+
+static void HSBToRGB(ColorSelectionBoxWidget csb)
+{
+ double r, g, bl;
+ double h, s, b;
+ double f, m, n, k;
+ int i;
+
+ if (csb->csb.current_color.saturation == 0) {
+ r = g = bl = csb->csb.current_color.brightness;
+ } else {
+ h = csb->csb.current_color.hue;
+ s = csb->csb.current_color.saturation;
+ b = csb->csb.current_color.brightness;
+
+ h = 6.0 * h;
+ if (h >= 6.0) h = 0.0;
+ i = (int) h;
+ f = h - (double)i;
+ m = b * (1.0 - s);
+ n = b * (1.0 - (s * f));
+ k = b * (1.0 - (s * (1.0 - f)));
+
+ switch(i) {
+ default:
+ case 0: r = b; g = k; bl = m; break;
+ case 1: r = n; g = b; bl = m; break;
+ case 2: r = m; g = b; bl = k; break;
+ case 3: r = m; g = n; bl = b; break;
+ case 4: r = k; g = m; bl = b; break;
+ case 5: r = b; g = m; bl = n; break;
+ }
+ }
+
+ csb->csb.current_color.red = r;
+ csb->csb.current_color.green = g;
+ csb->csb.current_color.blue = bl;
+}
+
+static void RGBToHSB(ColorSelectionBoxWidget csb)
+{
+ double hue, sat, value;
+ double diff, x, r, g, b;
+ double red, green, blue;
+
+ red = csb->csb.current_color.red;
+ green = csb->csb.current_color.green;
+ blue = csb->csb.current_color.blue;
+
+ hue = sat = 0.0;
+ value = x = red;
+ if (green > value) value = green; else x = green;
+ if (blue > value) value = blue;
+ if (blue < x) x = blue;
+
+ if (value != 0.0) {
+ diff = value - x;
+ if (diff != 0.0) {
+ sat = diff / value;
+ r = (value - red) / diff;
+ g = (value - green) / diff;
+ b = (value - blue) / diff;
+ if (red == value) hue = (green == x) ? 5.0 + b : 1.0 - g;
+ else if (green == value) hue = (blue == x) ? 1.0 + r : 3.0 - b;
+ else hue = (red == x) ? 3.0 + g : 5.0 - r;
+ hue /= 6.0; if (hue >= 1.0 || hue <= 0.0) hue = 0.0;
+ }
+ }
+ csb->csb.current_color.hue = hue;
+ csb->csb.current_color.saturation = sat;
+ csb->csb.current_color.brightness = value;
+}
+
+static void UpdateColorSpaces(
+ ColorSelectionBoxWidget csb,
+ CSBColorSpace masterSpace)
+{
+ switch (masterSpace) {
+ case CSBSpaceRGB:
+ RGBToCMYK(csb);
+ RGBToHSB(csb);
+ RGBToGray(csb);
+ break;
+
+ case CSBSpaceCMYK:
+ csb->csb.current_color.red =
+ 1.0 - MIN(1.0, csb->csb.current_color.cyan +
+ csb->csb.current_color.black);
+ csb->csb.current_color.green =
+ 1.0 - MIN(1.0, csb->csb.current_color.magenta +
+ csb->csb.current_color.black);
+ csb->csb.current_color.blue =
+ 1.0 - MIN(1.0, csb->csb.current_color.yellow +
+ csb->csb.current_color.black);
+ RGBToHSB(csb);
+ RGBToGray(csb);
+ break;
+
+ case CSBSpaceHSB:
+ HSBToRGB(csb);
+ RGBToCMYK(csb);
+ RGBToGray(csb);
+ break;
+
+ case CSBSpaceGray:
+ csb->csb.current_color.red = csb->csb.current_color.green =
+ csb->csb.current_color.blue = csb->csb.current_color.gray;
+
+ csb->csb.current_color.hue =
+ csb->csb.current_color.saturation = 0.0;
+ csb->csb.current_color.brightness = csb->csb.current_color.gray;
+
+ csb->csb.current_color.cyan = csb->csb.current_color.magenta =
+ csb->csb.current_color.yellow = 0.0;
+ csb->csb.current_color.black = 1.0 - csb->csb.current_color.gray;
+ break;
+ }
+}
+
+/* ARGSUSED */
+
+static void Slider1Callback(
+ Widget w,
+ XtPointer clientData, XtPointer callData)
+{
+ ColorSelectionBoxWidget csb = (ColorSelectionBoxWidget) clientData;
+ XmScaleCallbackStruct *scaleData = (XmScaleCallbackStruct *) callData;
+
+ switch(csb->csb.current_space) {
+ case CSBSpaceRGB:
+ csb->csb.current_color.red = scaleData->value / 100.0;
+ break;
+ case CSBSpaceCMYK:
+ csb->csb.current_color.cyan = scaleData->value / 100.0;
+ break;
+ case CSBSpaceHSB:
+ csb->csb.current_color.hue = scaleData->value / 100.0;
+ break;
+ case CSBSpaceGray:
+ csb->csb.current_color.gray = scaleData->value / 100.0;
+ break;
+ }
+
+ UpdateColorSpaces(csb, csb->csb.current_space);
+ DoValueChangedCallback(csb);
+ FillPatch(csb);
+}
+
+/* ARGSUSED */
+
+static void Slider2Callback(
+ Widget w,
+ XtPointer clientData, XtPointer callData)
+{
+ ColorSelectionBoxWidget csb = (ColorSelectionBoxWidget) clientData;
+ XmScaleCallbackStruct *scaleData = (XmScaleCallbackStruct *) callData;
+
+ switch(csb->csb.current_space) {
+ case CSBSpaceRGB:
+ csb->csb.current_color.green = scaleData->value / 100.0;
+ break;
+ case CSBSpaceCMYK:
+ csb->csb.current_color.magenta = scaleData->value / 100.0;
+ break;
+ case CSBSpaceHSB:
+ csb->csb.current_color.saturation = scaleData->value / 100.0;
+ break;
+ case CSBSpaceGray:
+ break;
+ }
+
+ UpdateColorSpaces(csb, csb->csb.current_space);
+ DoValueChangedCallback(csb);
+ FillPatch(csb);
+}
+
+/* ARGSUSED */
+
+static void Slider3Callback(
+ Widget w,
+ XtPointer clientData, XtPointer callData)
+{
+ ColorSelectionBoxWidget csb = (ColorSelectionBoxWidget) clientData;
+ XmScaleCallbackStruct *scaleData = (XmScaleCallbackStruct *) callData;
+
+ switch(csb->csb.current_space) {
+ case CSBSpaceRGB:
+ csb->csb.current_color.blue = scaleData->value / 100.0;
+ break;
+ case CSBSpaceCMYK:
+ csb->csb.current_color.yellow = scaleData->value / 100.0;
+ break;
+ case CSBSpaceHSB:
+ csb->csb.current_color.brightness = scaleData->value / 100.0;
+ break;
+ case CSBSpaceGray:
+ break;
+ }
+
+ UpdateColorSpaces(csb, csb->csb.current_space);
+ DoValueChangedCallback(csb);
+ FillPatch(csb);
+}
+
+/* ARGSUSED */
+
+static void Slider4Callback(
+ Widget w,
+ XtPointer clientData, XtPointer callData)
+{
+ ColorSelectionBoxWidget csb = (ColorSelectionBoxWidget) clientData;
+ XmScaleCallbackStruct *scaleData = (XmScaleCallbackStruct *) callData;
+
+ csb->csb.current_color.black = scaleData->value / 100.0;
+
+ UpdateColorSpaces(csb, csb->csb.current_space);
+ DoValueChangedCallback(csb);
+ FillPatch(csb);
+}
+
+static void FillPatch(ColorSelectionBoxWidget csb)
+{
+ Colormap c;
+ XColor xc;
+ Widget patch = csb->csb.patch_child;
+
+ if (!XtIsRealized(csb->csb.patch_child)) return;
+
+ if (csb->csb.no_background) {
+ XClearArea(XtDisplay(patch), XtWindow(patch), 0, 0, 1000, 1000, True);
+ return;
+ }
+
+ /* All we have to do is set the background; the expose event will
+ do the rest */
+
+ XtVaGetValues(patch, XtNcolormap, (XtPointer) &c, NULL);
+
+ if (csb->csb.current_space == CSBSpaceGray) {
+ xc.red = xc.green = xc.blue = TO_X(csb->csb.current_color.gray);
+ } else {
+ xc.red = TO_X(csb->csb.current_color.red);
+ xc.green = TO_X(csb->csb.current_color.green);
+ xc.blue = TO_X(csb->csb.current_color.blue);
+ }
+
+ if (csb->csb.static_visual) {
+ (void) XAllocColor(XtDisplay(patch), c, &xc);
+ csb->csb.background = xc.pixel;
+ XtVaSetValues(patch, XtNbackground, csb->csb.background, NULL);
+ } else {
+ xc.pixel = csb->csb.background;
+ xc.flags = DoRed | DoGreen | DoBlue;
+ XStoreColor(XtDisplay(patch), c, &xc);
+ }
+
+ XClearArea(XtDisplay(patch), XtWindow(patch), 0, 0, 1000, 1000, True);
+}
+
+/* ARGSUSED */
+
+static void FillPatchCallback(
+ Widget w,
+ XtPointer clientData, XtPointer callData)
+{
+ ColorSelectionBoxWidget csb = (ColorSelectionBoxWidget) clientData;
+ Dimension height, width;
+ float fh, fw;
+
+ if (csb->csb.current_rendering != CSBDisplayX) {
+ XtVaGetValues(w, XtNheight, &height, XtNwidth, &width, NULL);
+ if (csb->csb.patch_gstate == 0) {
+ XDPSSetContextGState(csb->csb.context, csb->csb.base_gstate);
+ XDPSSetContextDrawable(csb->csb.context, XtWindow(w), height);
+ (void) XDPSCaptureContextGState(csb->csb.context,
+ &csb->csb.patch_gstate);
+ } else XDPSSetContextGState(csb->csb.context, csb->csb.patch_gstate);
+
+ switch (csb->csb.current_space) {
+ case CSBSpaceRGB:
+ DPSsetrgbcolor(csb->csb.context, csb->csb.current_color.red,
+ csb->csb.current_color.green,
+ csb->csb.current_color.blue);
+ break;
+ case CSBSpaceCMYK:
+ DPSsetcmykcolor(csb->csb.context, csb->csb.current_color.cyan,
+ csb->csb.current_color.magenta,
+ csb->csb.current_color.yellow,
+ csb->csb.current_color.black);
+ break;
+ case CSBSpaceHSB:
+ DPSsethsbcolor(csb->csb.context, csb->csb.current_color.hue,
+ csb->csb.current_color.saturation,
+ csb->csb.current_color.brightness);
+ break;
+ case CSBSpaceGray:
+ DPSsetgray(csb->csb.context, csb->csb.current_color.gray);
+ break;
+ }
+ }
+
+ switch (csb->csb.current_rendering) {
+ case CSBDisplayDPS:
+ DPSrectfill(csb->csb.context, 0.0, 0.0, 1000.0, 1000.0);
+ break;
+ case CSBDisplayX:
+ break;
+ case CSBDisplayBoth:
+ ToUserSpace(csb, width, height, &fw, &fh);
+ _DPSCTriangle(csb->csb.context, fh, fw);
+ break;
+ }
+}
+
+/* The following function Copyright 1987, 1988 by Digital Equipment
+Corporation, Maynard, Massachusetts, and the Massachusetts Institute of
+Technology, Cambridge, Massachusetts. */
+
+static String GetRootDirName(String buf)
+{
+#ifndef X_NOT_POSIX
+ uid_t uid;
+#else
+ int uid;
+ extern int getuid();
+#ifndef SYSV386
+ extern struct passwd *getpwuid(), *getpwnam();
+#endif
+#endif
+ struct passwd *pw;
+ static char *ptr = NULL;
+
+ if (ptr == NULL) {
+ if (!(ptr = getenv("HOME"))) {
+ if ((ptr = getenv("USER")) != 0) {
+ pw = getpwnam(ptr);
+ } else {
+ uid = getuid();
+ pw = getpwuid(uid);
+ }
+ if (pw) ptr = pw->pw_dir;
+ else {
+ ptr = NULL;
+ *buf = '\0';
+ }
+ }
+ }
+
+ if (ptr)
+ (void) strcpy(buf, ptr);
+
+ buf += strlen(buf);
+ *buf = '/';
+ buf++;
+ *buf = '\0';
+ return buf;
+}
+
+static void AllocateDock(ColorSelectionBoxWidget csb)
+{
+ int entry;
+
+ csb->csb.dock_cyan = (float *) XtCalloc(csb->csb.num_cells, sizeof(float));
+ csb->csb.dock_magenta =
+ (float *) XtCalloc(csb->csb.num_cells, sizeof(float));
+ csb->csb.dock_yellow =
+ (float *) XtCalloc(csb->csb.num_cells, sizeof(float));
+ csb->csb.dock_black =
+ (float *) XtCalloc(csb->csb.num_cells, sizeof(float));
+ csb->csb.dock_used =
+ (Boolean *) XtCalloc(csb->csb.num_cells, sizeof(Boolean));
+
+ for (entry = 0; entry < csb->csb.num_cells; entry++) {
+ csb->csb.dock_used[entry] = 0;
+ }
+}
+
+static void InitializeDock(ColorSelectionBoxWidget csb)
+{
+ String dockEnv;
+ char homeDir[PATH_BUF_SIZE];
+ FILE *dockFile = NULL;
+ char fileName[PATH_BUF_SIZE];
+#define BUF 256
+ char buf[BUF+1];
+ int entry;
+ float cyan, magenta, yellow, black;
+#define CHECK(v) ((v) > 1.0 ? 1.0 : ((v) < 0.0 ? 0.0 : (v)))
+
+ AllocateDock(csb);
+ csb->csb.dock_changed = False;
+
+ dockEnv = getenv("DPSCPICKRC");
+
+ if (dockEnv != NULL) dockFile = fopen(dockEnv, "r");
+
+ if (dockFile == NULL) {
+ (void) GetRootDirName(homeDir);
+
+ if (dockFile == NULL) {
+ sprintf(fileName, "%s/.dpscpickrc", homeDir);
+ dockFile = fopen(fileName, "r");
+
+ if (dockFile == NULL) return;
+ }
+ }
+
+ while (1) {
+ if (fgets(buf, BUF, dockFile) == NULL) {
+ fclose(dockFile);
+ return;
+ }
+ if (sscanf(buf, "%d %f %f %f %f",
+ &entry, &cyan, &magenta, &yellow, &black) == 5) {
+ if (entry <= csb->csb.num_cells) {
+ csb->csb.dock_cyan[entry] = CHECK(cyan);
+ csb->csb.dock_magenta[entry] = CHECK(magenta);
+ csb->csb.dock_yellow[entry] = CHECK(yellow);
+ csb->csb.dock_black[entry] = CHECK(black);
+ csb->csb.dock_used[entry] = True;
+ }
+ }
+ }
+
+#undef BUF
+#undef CHECK
+}
+
+static void SaveDockContents(ColorSelectionBoxWidget csb)
+{
+ String dockEnv;
+ char homeDir[PATH_BUF_SIZE];
+ FILE *dockFile = NULL;
+ char fileName[PATH_BUF_SIZE];
+ int i;
+
+ if (!csb->csb.dock_changed) return;
+
+ dockEnv = getenv("DPSCPICKRC");
+
+ if (dockEnv != NULL) dockFile = fopen(dockEnv, "w");
+
+ if (dockFile == NULL) {
+ (void) GetRootDirName(homeDir);
+
+ if (dockFile == NULL) {
+ sprintf(fileName, "%s/.dpscpickrc", homeDir);
+ dockFile = fopen(fileName, "w");
+
+ if (dockFile == NULL) return;
+ }
+ }
+
+ for (i = 0; i < csb->csb.num_cells; i++) {
+ if (!csb->csb.dock_used[i]) continue;
+ fprintf(dockFile, "%d %g %g %g %g\n", i, csb->csb.dock_cyan[i],
+ csb->csb.dock_magenta[i], csb->csb.dock_yellow[i],
+ csb->csb.dock_black[i]);
+ }
+ fclose(dockFile);
+ csb->csb.dock_changed = False;
+}
+
+/* ARGSUSED */
+
+static void DrawDockCallback(
+ Widget w,
+ XtPointer clientData, XtPointer callData)
+{
+ ColorSelectionBoxWidget csb = (ColorSelectionBoxWidget) clientData;
+
+ XClearArea(XtDisplay(csb), XtWindow(csb->csb.dock_child),
+ 0, 0, 1000, 1000, False);
+ DrawDock(csb);
+}
+
+static void DrawDock(ColorSelectionBoxWidget csb)
+{
+ Dimension height;
+ float w, h;
+ int lines;
+ int i, row, col;
+ Boolean didAny = False;
+
+ XtVaGetValues(csb->csb.dock_child, XtNheight, &height, NULL);
+
+ lines = height / csb->csb.cell_size;
+
+ if (csb->csb.dock_gstate == 0) {
+ XDPSSetContextGState(csb->csb.context, csb->csb.base_gstate);
+ XDPSSetContextDrawable(csb->csb.context,
+ XtWindow(csb->csb.dock_child), height);
+ (void) XDPSCaptureContextGState(csb->csb.context,
+ &csb->csb.dock_gstate);
+ } else XDPSSetContextGState(csb->csb.context, csb->csb.dock_gstate);
+
+ ToUserSpace(csb, csb->csb.cell_size, csb->csb.cell_size, &w, &h);
+
+ for (i = 0; i < csb->csb.num_cells; i++) {
+ if (!csb->csb.dock_used[i]) continue;
+ row = (lines - 1) - (i % lines);
+ col = i / lines;
+
+ DPSsetcmykcolor(csb->csb.context, csb->csb.dock_cyan[i],
+ csb->csb.dock_magenta[i], csb->csb.dock_yellow[i],
+ csb->csb.dock_black[i]);
+
+ DPSrectfill(csb->csb.context,
+ (float) (col * w), (float) (row * h), w, h);
+ didAny = True;
+ }
+ if (!didAny) _DPSCShowFillMe(csb->csb.context, csb->csb.fill_me);
+}
+
+static void StoreColorInDock(
+ ColorSelectionBoxWidget csb,
+ int x_offset,
+ int y_offset,
+ Dimension dockHeight)
+{
+ int i, lines, row, col;
+
+ lines = dockHeight / csb->csb.cell_size;
+
+ row = y_offset / (int) csb->csb.cell_size;
+ col = x_offset / (int) csb->csb.cell_size;
+ i = col * lines + row;
+
+ if (i >= csb->csb.num_cells) i = csb->csb.num_cells;
+ csb->csb.dock_cyan[i] = csb->csb.current_color.cyan;
+ csb->csb.dock_magenta[i] = csb->csb.current_color.magenta;
+ csb->csb.dock_yellow[i] = csb->csb.current_color.yellow;
+ csb->csb.dock_black[i] = csb->csb.current_color.black;
+ csb->csb.dock_used[i] = True;
+ csb->csb.dock_changed = True;
+ DrawDock(csb);
+}
+
+/* ARGSUSED */
+
+static void DockPress(
+ Widget w,
+ XtPointer data,
+ XEvent *event,
+ Boolean *goOn)
+{
+ ColorSelectionBoxWidget csb = (ColorSelectionBoxWidget) data;
+ Dimension height;
+ int i, lines, row, col;
+
+ XtVaGetValues(csb->csb.dock_child, XtNheight, &height, NULL);
+
+ lines = height / csb->csb.cell_size;
+
+ row = event->xbutton.y / (int) csb->csb.cell_size;
+ col = event->xbutton.x / (int) csb->csb.cell_size;
+ i = col * lines + row;
+ if (i >= csb->csb.num_cells) i = csb->csb.num_cells;
+
+ if (!csb->csb.dock_used[i]) return;
+
+ csb->csb.current_color.cyan = csb->csb.dock_cyan[i];
+ csb->csb.current_color.magenta = csb->csb.dock_magenta[i];
+ csb->csb.current_color.yellow = csb->csb.dock_yellow[i];
+ csb->csb.current_color.black = csb->csb.dock_black[i];
+ UpdateColorSpaces(csb, CSBSpaceCMYK);
+ DoValueChangedCallback(csb);
+ FillPatch(csb);
+ SetSliders(csb);
+}
+
+static void InitializePalettes(ColorSelectionBoxWidget csb)
+{
+ int k;
+
+ for (k = 0; k < PALETTE_MAX; k++) {
+ if (csb->csb.palette_function[k] != NULL) {
+ DPSPrintf(csb->csb.context,
+ "/palette%dfunc%d { %s } bind def\n", k, (int) csb,
+ csb->csb.palette_function[k]);
+ }
+ csb->csb.palette_broken[k] = False;
+ }
+}
+
+static void InvalidatePalette(ColorSelectionBoxWidget csb)
+{
+ int len;
+ char *buf;
+ Widget w;
+ register int i = csb->csb.current_palette;
+
+ len = strlen(csb->csb.palette_label[i]) +
+ strlen(csb->csb.broken_palette_label) + 2;
+ len = MAX(len, 11);
+ buf = (char *) XtMalloc(len);
+
+ csb->csb.palette_broken[i] = True;
+ sprintf(buf, "*palette%d", csb->csb.current_palette);
+ w = XtNameToWidget((Widget) csb, buf);
+ if (w != NULL) XtSetSensitive(w, False);
+ sprintf(buf, "%s %s", csb->csb.palette_label[i],
+ csb->csb.broken_palette_label);
+ len = strlen(buf);
+ XtVaSetValues(w, XtVaTypedArg, XmNlabelString, XtRString, buf, len, NULL);
+}
+
+static void DoPalette(
+ ColorSelectionBoxWidget csb,
+ Dimension pixelWidth,
+ float w,
+ float h)
+{
+ char whichFunc[25];
+ int steps;
+ int success;
+
+ sprintf(whichFunc, "palette%dfunc%d", csb->csb.current_palette, (int) csb);
+ if (csb->csb.visual_class == TrueColor) steps = pixelWidth / 2;
+ else steps = pixelWidth / 4;
+
+ if (csb->csb.palette_color_dependent[csb->csb.current_palette]) {
+ switch (csb->csb.palette_space[csb->csb.current_palette]) {
+ case CSBSpaceRGB:
+ _DPSCDoRGBColorPalette(csb->csb.context, whichFunc,
+ csb->csb.current_color.red,
+ csb->csb.current_color.green,
+ csb->csb.current_color.blue,
+ w, h, steps, &success);
+ break;
+ case CSBSpaceCMYK:
+ _DPSCDoCMYKColorPalette(csb->csb.context, whichFunc,
+ csb->csb.current_color.cyan,
+ csb->csb.current_color.magenta,
+ csb->csb.current_color.yellow,
+ csb->csb.current_color.black,
+ w, h, steps, &success);
+ break;
+ case CSBSpaceHSB:
+ _DPSCDoHSBColorPalette(csb->csb.context, whichFunc,
+ csb->csb.current_color.hue,
+ csb->csb.current_color.saturation,
+ csb->csb.current_color.brightness,
+ w, h, steps, &success);
+ break;
+ case CSBSpaceGray:
+ _DPSCDoGrayColorPalette(csb->csb.context, whichFunc,
+ csb->csb.current_color.gray,
+ w, h, steps, &success);
+ break;
+ }
+ } else {
+ switch (csb->csb.palette_space[csb->csb.current_palette]) {
+ case CSBSpaceRGB:
+ _DPSCDoRGBPalette(csb->csb.context, whichFunc, w, h,
+ steps, &success);
+ break;
+ case CSBSpaceCMYK:
+ _DPSCDoCMYKPalette(csb->csb.context, whichFunc, w, h,
+ steps, &success);
+ break;
+ case CSBSpaceHSB:
+ _DPSCDoHSBPalette(csb->csb.context, whichFunc, w, h,
+ steps, &success);
+ break;
+ case CSBSpaceGray:
+ _DPSCDoGrayPalette(csb->csb.context, whichFunc, w, h,
+ steps, &success);
+ break;
+ }
+ }
+ if (!success) {
+ InvalidatePalette(csb);
+ _DPSCShowMessage(csb->csb.context, csb->csb.broken_palette_message);
+ }
+}
+
+static void DrawPalette(ColorSelectionBoxWidget csb)
+{
+ DrawPaletteCallback(csb->csb.palette_child,
+ (XtPointer) csb, (XtPointer) NULL);
+}
+
+/* ARGSUSED */
+
+static void DrawPaletteCallback(
+ Widget wid,
+ XtPointer clientData, XtPointer callData)
+{
+ ColorSelectionBoxWidget csb = (ColorSelectionBoxWidget) clientData;
+ Dimension width, height;
+ Pixmap palette_pixmap;
+ int depth;
+ float w, h;
+
+ if (csb->csb.palette_broken[csb->csb.current_palette]) return;
+ if (!csb->csb.palette_pixmap_valid) {
+ XtVaGetValues(csb->csb.palette_child,
+ XtNwidth, &width, XtNheight, &height,
+ XtNdepth, &depth, NULL);
+
+ ToUserSpace(csb, width, height, &w, &h);
+
+ palette_pixmap =
+ XCreatePixmap(XtDisplay(csb), XtWindow(csb->csb.palette_child),
+ width, height, depth);
+
+ XDPSSetContextGState(csb->csb.context, csb->csb.base_gstate);
+ XDPSSetContextDrawable(csb->csb.context, palette_pixmap, height);
+
+ DoPalette(csb, width, w, h);
+ csb->csb.palette_color = csb->csb.current_color;
+ DPSWaitContext(csb->csb.context);
+ XtVaSetValues(csb->csb.palette_child,
+ XtNbackgroundPixmap, palette_pixmap, NULL);
+ XFreePixmap(XtDisplay(csb), palette_pixmap);
+ csb->csb.palette_pixmap_valid = True;
+ }
+}
+
+/* ARGSUSED */
+
+static void PalettePress(
+ Widget w,
+ XtPointer data,
+ XEvent *event,
+ Boolean *goOn)
+{
+ ColorSelectionBoxWidget csb = (ColorSelectionBoxWidget) data;
+ Dimension width;
+ float pct;
+ char whichFunc[25];
+ int success;
+ float f1, f2, f3, f4;
+
+ if (csb->csb.palette_broken[csb->csb.current_palette]) return;
+
+ sprintf(whichFunc, "palette%dfunc%d", csb->csb.current_palette, (int) csb);
+
+ XtVaGetValues(csb->csb.palette_child, XtNwidth, &width, NULL);
+
+ pct = ((float) event->xbutton.x) / ((float) width);
+
+ if (csb->csb.palette_color_dependent[csb->csb.current_palette]) {
+ switch (csb->csb.palette_space[csb->csb.current_palette]) {
+ case CSBSpaceRGB:
+ _DPSCQueryRGBColorPalette(csb->csb.context, whichFunc, pct,
+ csb->csb.palette_color.red,
+ csb->csb.palette_color.green,
+ csb->csb.palette_color.blue,
+ &f1, &f2, &f3, &success);
+ if (success) {
+ csb->csb.current_color.red = f1;
+ csb->csb.current_color.green = f2;
+ csb->csb.current_color.blue = f3;
+ }
+ break;
+ case CSBSpaceCMYK:
+ _DPSCQueryCMYKColorPalette(csb->csb.context, whichFunc, pct,
+ csb->csb.palette_color.cyan,
+ csb->csb.palette_color.magenta,
+ csb->csb.palette_color.yellow,
+ csb->csb.palette_color.black,
+ &f1, &f2, &f3, &f4, &success);
+ if (success) {
+ csb->csb.current_color.cyan = f1;
+ csb->csb.current_color.magenta = f2;
+ csb->csb.current_color.yellow = f3;
+ csb->csb.current_color.black = f4;
+ }
+ break;
+ case CSBSpaceHSB:
+ _DPSCQueryHSBColorPalette(csb->csb.context, whichFunc, pct,
+ csb->csb.palette_color.hue,
+ csb->csb.palette_color.saturation,
+ csb->csb.palette_color.brightness,
+ &f1, &f2, &f3, &success);
+ if (success) {
+ csb->csb.current_color.hue = f1;
+ csb->csb.current_color.saturation = f2;
+ csb->csb.current_color.brightness = f3;
+ }
+ break;
+ case CSBSpaceGray:
+ _DPSCQueryGrayColorPalette(csb->csb.context, whichFunc, pct,
+ csb->csb.palette_color.gray,
+ &f1, &success);
+ if (success) csb->csb.current_color.gray = f1;
+ break;
+ }
+ } else {
+ switch (csb->csb.palette_space[csb->csb.current_palette]) {
+ case CSBSpaceRGB:
+ _DPSCQueryRGBPalette(csb->csb.context, whichFunc, pct,
+ &f1, &f2, &f3, &success);
+ if (success) {
+ csb->csb.current_color.red = f1;
+ csb->csb.current_color.green = f2;
+ csb->csb.current_color.blue = f3;
+ }
+ break;
+ case CSBSpaceCMYK:
+ _DPSCQueryCMYKPalette(csb->csb.context, whichFunc, pct,
+ &f1, &f2, &f3, &f4, &success);
+ if (success) {
+ csb->csb.current_color.cyan = f1;
+ csb->csb.current_color.magenta = f2;
+ csb->csb.current_color.yellow = f3;
+ csb->csb.current_color.black = f4;
+ }
+ break;
+ case CSBSpaceHSB:
+ _DPSCQueryHSBPalette(csb->csb.context, whichFunc, pct,
+ &f1, &f2, &f3, &success);
+ if (success) {
+ csb->csb.current_color.hue = f1;
+ csb->csb.current_color.saturation = f2;
+ csb->csb.current_color.brightness = f3;
+ }
+ break;
+ case CSBSpaceGray:
+ _DPSCQueryGrayPalette(csb->csb.context, whichFunc, pct,
+ &f1, &success);
+ if (success) csb->csb.current_color.gray = f1;
+ break;
+ }
+ }
+ if (!success) InvalidatePalette(csb);
+ else {
+ UpdateColorSpaces(csb,
+ csb->csb.palette_space[csb->csb.current_palette]);
+ DoValueChangedCallback(csb);
+ FillPatch(csb);
+ SetSliders(csb);
+ }
+}
+
+/* ARGSUSED */
+
+static void DoEyedropCallback(
+ Widget w,
+ XtPointer clientData, XtPointer callData)
+{
+ ColorSelectionBoxWidget csb = (ColorSelectionBoxWidget) clientData;
+ Pixmap eyedropBitmap, eyedropMaskBitmap;
+ XColor black, fg;
+ Display *dpy;
+ unsigned int x, y;
+ XEvent ev;
+
+ dpy = XtDisplay(w);
+
+ black.red = 0;
+ black.green = 0;
+ black.blue = 0;
+
+ fg.red = 65535;
+ fg.green = 65535;
+ fg.blue = 65535;
+
+ if (csb->csb.eyedrop == None) {
+ XQueryBestCursor(dpy, XtWindow(w), 32, 32,
+ &x, &y);
+
+ if (x >= 32 && y >= 32) {
+ eyedropBitmap =
+ XCreateBitmapFromData(dpy, XtWindow(w),
+ (char *) eyedrop32_bits,
+ eyedrop32_width, eyedrop32_height);
+
+ eyedropMaskBitmap =
+ XCreateBitmapFromData(dpy, XtWindow(w),
+ (char *) eyedropmask32_bits,
+ eyedropmask32_width,
+ eyedropmask32_height);
+
+ csb->csb.eyedrop =
+ XCreatePixmapCursor(dpy, eyedropBitmap,
+ eyedropMaskBitmap,
+ &fg, &black,
+ eyedrop32_x_hot, eyedrop32_y_hot);
+ } else {
+ eyedropBitmap =
+ XCreateBitmapFromData(dpy, XtWindow(w),
+ (char *) eyedrop16_bits,
+ eyedrop16_width, eyedrop16_height);
+
+ eyedropMaskBitmap =
+ XCreateBitmapFromData(dpy, XtWindow(w),
+ (char *) eyedropmask16_bits,
+ eyedropmask16_width,
+ eyedropmask16_height);
+
+ csb->csb.eyedrop =
+ XCreatePixmapCursor(dpy, eyedropBitmap,
+ eyedropMaskBitmap,
+ &fg, &black,
+ eyedrop16_x_hot, eyedrop16_y_hot);
+ }
+ } else {
+ XRecolorCursor(dpy, csb->csb.eyedrop, &fg, &black);
+ }
+
+ (void) XtGrabPointer(w, False,
+ PointerMotionMask | PointerMotionHintMask |
+ ButtonReleaseMask,
+ GrabModeAsync, GrabModeAsync,
+ None, csb->csb.eyedrop,
+ XtLastTimestampProcessed(dpy));
+ csb->csb.eyedrop_grabbed = True;
+
+ ev.type = 0;
+ EyedropPointer(w, (XtPointer) csb, &ev, (Boolean *) NULL);
+}
+
+/* ARGSUSED */
+
+static void EyedropPointer(
+ Widget w,
+ XtPointer data,
+ XEvent *event,
+ Boolean *goOn)
+{
+ ColorSelectionBoxWidget csb = (ColorSelectionBoxWidget) data;
+ XColor fg, black;
+ Window root, child, stop, old_child = None;
+ int root_x, root_y, x, y;
+ unsigned int mask;
+ XWindowAttributes att;
+ XImage *image;
+ Pixel pixel;
+ Colormap colormap = 0;
+ Display *dpy = XtDisplay(w);
+
+ if (!csb->csb.eyedrop_grabbed) return;
+
+ if (event->type == ButtonPress || event->type == ButtonRelease) {
+ root = event->xbutton.root;
+ root_x = event->xbutton.x_root;
+ root_y = event->xbutton.y_root;
+
+ XTranslateCoordinates(dpy, root, root, root_x, root_y, &x, &y, &child);
+
+ } else {
+ XQueryPointer(dpy, RootWindowOfScreen(XtScreen(w)),
+ &root, &child, &root_x, &root_y, &x, &y, &mask);
+ }
+
+ if (child == None) child = root;
+ else {
+ stop = child;
+
+ while (stop != None) {
+ XTranslateCoordinates(dpy, root, stop, x, y, &x, &y, &child);
+ root = stop;
+ if (child != None && XGetWindowAttributes(dpy, child, &att) &&
+ att.class != InputOutput) break;
+ stop = child;
+ }
+ child = root;
+ }
+
+ if (child != old_child) {
+ XGetWindowAttributes(dpy, child, &att);
+ colormap = att.colormap;
+ old_child = child;
+ }
+
+ image = XGetImage(dpy, child, x, y, 1, 1, AllPlanes, XYPixmap);
+
+ pixel = XGetPixel(image, 0, 0);
+
+ XDestroyImage(image);
+ fg.pixel = pixel;
+ XQueryColors(dpy, colormap, &fg, 1);
+
+ black.red = 0;
+ black.green = 0;
+ black.blue = 0;
+
+ XRecolorCursor(dpy, csb->csb.eyedrop, &fg, &black);
+
+ if (event->type == ButtonRelease) {
+ XtUngrabPointer(w, XtLastTimestampProcessed(dpy));
+ csb->csb.eyedrop_grabbed = False;
+
+ csb->csb.current_color.red = (float) fg.red / 65535.0;
+ csb->csb.current_color.green = (float) fg.green / 65535.0;
+ csb->csb.current_color.blue = (float) fg.blue / 65535.0;
+ UpdateColorSpaces(csb, CSBSpaceRGB);
+ DoValueChangedCallback(csb);
+ FillPatch(csb);
+ SetSliders(csb);
+ }
+}
+
+/* ARGSUSED */
+
+static void PatchPress(
+ Widget w,
+ XtPointer data,
+ XEvent *event,
+ Boolean *goOn)
+{
+ ColorSelectionBoxWidget csb = (ColorSelectionBoxWidget) data;
+ Pixmap squareBitmap, squareMaskBitmap;
+ XColor black, fg;
+ Display *dpy;
+
+ dpy = XtDisplay(w);
+
+ black.red = 0;
+ black.green = 0;
+ black.blue = 0;
+
+ fg.red = TO_X(csb->csb.current_color.red);
+ fg.green = TO_X(csb->csb.current_color.green);
+ fg.blue = TO_X(csb->csb.current_color.blue);
+
+ if (csb->csb.square == None) {
+ squareBitmap =
+ XCreateBitmapFromData(dpy, XtWindow(w), (char *) square_bits,
+ square_width, square_height);
+
+ squareMaskBitmap =
+ XCreateBitmapFromData(dpy, XtWindow(w),
+ (char *) squaremask_bits,
+ squaremask_width, squaremask_height);
+
+ csb->csb.square =
+ XCreatePixmapCursor(dpy, squareBitmap, squareMaskBitmap,
+ &fg, &black, square_x_hot, square_y_hot);
+ } else {
+ XRecolorCursor(dpy, csb->csb.square, &fg, &black);
+ }
+
+ (void) XtGrabPointer(w, False, ButtonReleaseMask,
+ GrabModeAsync, GrabModeAsync,
+ None, csb->csb.square, XtLastTimestampProcessed(dpy));
+}
+
+/* ARGSUSED */
+
+static void PatchRelease(
+ Widget w,
+ XtPointer data,
+ XEvent *event,
+ Boolean *goOn)
+{
+ ColorSelectionBoxWidget csb = (ColorSelectionBoxWidget) data;
+ Dimension width, height;
+ Position left, top;
+
+ XtUngrabPointer(w, XtLastTimestampProcessed(XtDisplay(w)));
+ XFlush(XtDisplay(w));
+
+ XtVaGetValues(csb->csb.dock_child, XtNwidth, &width,
+ XtNheight, &height, NULL);
+
+ XtTranslateCoords(csb->csb.dock_child, (Position) 0, (Position) 0,
+ &left, &top);
+
+ if ((int) event->xbutton.x_root >= left &&
+ (int) event->xbutton.x_root <= left + (int) width &&
+ (int) event->xbutton.y_root >= top &&
+ (int) event->xbutton.y_root <= top + (int) height) {
+ StoreColorInDock(csb, event->xbutton.x_root - left,
+ event->xbutton.y_root - top, height);
+ }
+}
+
+static void GetVisualInfo(
+ ColorSelectionBoxWidget csb,
+ Visual **visual)
+{
+ Widget w = (Widget) csb;
+ XVisualInfo *vip, viproto;
+ int n;
+ XWindowAttributes xwa;
+
+ XGetWindowAttributes(XtDisplay(w), XtWindow(w), &xwa);
+
+ *visual = viproto.visual = xwa.visual;
+ viproto.visualid = XVisualIDFromVisual(xwa.visual);
+ vip = XGetVisualInfo(XtDisplay(w), VisualIDMask, &viproto, &n);
+
+ if (n != 1) {
+ csb->csb.static_visual = False; /* Actually we have no idea, but... */
+ csb->csb.visual_class = PseudoColor;
+ } else {
+ csb->csb.visual_class = vip->class;
+ csb->csb.static_visual = (vip->class == StaticGray ||
+ vip->class == TrueColor ||
+ vip->class == StaticColor);
+ }
+
+ if (n > 0) XFree((char *) vip);
+}
+
+static void SetBackground(ColorSelectionBoxWidget csb)
+{
+ Colormap c;
+ XColor xc;
+ int status;
+ unsigned long pix;
+ unsigned long mask;
+
+ XtVaGetValues(csb->csb.patch_child, XtNcolormap, (XtPointer) &c, NULL);
+
+ if (csb->csb.current_space == CSBSpaceGray) {
+ xc.red = xc.green = xc.blue = TO_X(csb->csb.current_color.gray);
+ } else {
+ xc.red = TO_X(csb->csb.current_color.red);
+ xc.green = TO_X(csb->csb.current_color.green);
+ xc.blue = TO_X(csb->csb.current_color.blue);
+ }
+
+ if (csb->csb.static_visual) {
+ status = XAllocColor(XtDisplay(csb), c, &xc);
+ if (status == 0) NoBackgroundPixel(csb);
+ else {
+ csb->csb.background = xc.pixel;
+ XtVaSetValues(csb->csb.patch_child,
+ XtNbackground, csb->csb.background, NULL);
+ }
+
+ } else {
+ if (csb->csb.visual_class == DirectColor) {
+ status = XAllocColorPlanes(XtDisplay(csb), c,
+ False, &pix, 1, 0, 0, 0,
+ &mask, &mask, &mask);
+ } else {
+ status = XAllocColorCells(XtDisplay(csb), c,
+ False, (unsigned long *) NULL, 0,
+ &pix, 1);
+ }
+
+ if (status == 0) NoBackgroundPixel(csb);
+ else {
+ xc.pixel = pix;
+ xc.flags = DoRed | DoGreen | DoBlue;
+ XStoreColor(XtDisplay(csb), c, &xc);
+
+ csb->csb.background = xc.pixel;
+ XtVaSetValues(csb->csb.patch_child,
+ XtNbackground, csb->csb.background, NULL);
+ }
+ }
+}
+
+/* ARGSUSED */
+
+static void Initialize(
+ Widget request, Widget new,
+ ArgList args,
+ Cardinal *num_args)
+{
+ ColorSelectionBoxWidget csb = (ColorSelectionBoxWidget) new;
+ Bool inited;
+ int i;
+
+ if (csb->csb.rgb_labels != NULL) {
+ csb->csb.rgb_labels = XtNewString(csb->csb.rgb_labels);
+ }
+ if (csb->csb.cmyk_labels != NULL) {
+ csb->csb.cmyk_labels = XtNewString(csb->csb.cmyk_labels);
+ }
+ if (csb->csb.hsb_labels != NULL) {
+ csb->csb.hsb_labels = XtNewString(csb->csb.hsb_labels);
+ }
+ if (csb->csb.gray_labels != NULL) {
+ csb->csb.gray_labels = XtNewString(csb->csb.gray_labels);
+ }
+ if (csb->csb.fill_me != NULL) {
+ csb->csb.fill_me = XtNewString(csb->csb.fill_me);
+ }
+ if (csb->csb.broken_palette_label != NULL) {
+ csb->csb.broken_palette_label =
+ XtNewString(csb->csb.broken_palette_label);
+ }
+ if (csb->csb.broken_palette_message != NULL) {
+ csb->csb.broken_palette_message =
+ XtNewString(csb->csb.broken_palette_message);
+ }
+
+ for (i = 0; i < PALETTE_MAX; i++) {
+ if (csb->csb.palette_function[i] != NULL) {
+ csb->csb.palette_function[i] =
+ XtNewString(csb->csb.palette_function[i]);
+ }
+ }
+
+ if (csb->csb.num_cells <= 0) csb->csb.num_cells = 1;
+
+ /* Get the context */
+
+ if (csb->csb.context == NULL) {
+ csb->csb.context = XDPSGetSharedContext(XtDisplay(csb));
+ }
+
+ if (_XDPSTestComponentInitialized(csb->csb.context,
+ dps_init_bit_csb, &inited) ==
+ dps_status_unregistered_context) {
+ XDPSRegisterContext(csb->csb.context, False);
+ }
+
+ if (!inited) {
+ (void) _XDPSSetComponentInitialized(csb->csb.context,
+ dps_init_bit_csb);
+ InitializePalettes(csb);
+ }
+
+ if (csb->csb.current_palette < 0 ||
+ csb->csb.current_palette > PALETTE_MAX ||
+ csb->csb.palette_function[csb->csb.current_palette] == NULL) {
+ csb->csb.current_palette = 0;
+ }
+
+ /* Initialize non-resource fields */
+
+ CreateChildren(csb);
+ csb->csb.no_background = False;
+ csb->csb.patch_gstate = csb->csb.dock_gstate = 0;
+ csb->csb.red_pixmap = csb->csb.green_pixmap = csb->csb.blue_pixmap =
+ csb->csb.cyan_pixmap = csb->csb.magenta_pixmap =
+ csb->csb.yellow_pixmap = csb->csb.black_pixmap =
+ csb->csb.hue_pixmap = csb->csb.sat_pixmap =
+ csb->csb.bright_pixmap = csb->csb.gray_pixmap = None;
+
+ csb->csb.square = csb->csb.eyedrop = None;
+ csb->csb.eyedrop_grabbed = False;
+
+ for (i = 0; i < PALETTE_MAX; i++) csb->csb.palette_broken[i] = False;
+ csb->csb.palette_pixmap_valid = False;
+
+ csb->csb.current_color.hue = 0.0;
+ csb->csb.current_color.saturation = 1.0;
+ csb->csb.current_color.brightness = 1.0;
+ UpdateColorSpaces(csb, CSBSpaceHSB);
+ csb->csb.save_color = csb->csb.current_color;
+ SetSliders(csb);
+
+ InitializeDock(csb);
+ SetColorSpace(csb);
+ SetRendering(csb);
+}
+
+static void Destroy(Widget widget)
+{
+ ColorSelectionBoxWidget csb = (ColorSelectionBoxWidget) widget;
+ Display *dpy = XtDisplay(csb);
+ int i;
+
+ /* Lots of stuff to destroy! */
+
+ if (csb->csb.patch_gstate != 0) {
+ XDPSFreeContextGState(csb->csb.context, csb->csb.patch_gstate);
+ }
+ if (csb->csb.dock_gstate != 0) {
+ XDPSFreeContextGState(csb->csb.context, csb->csb.dock_gstate);
+ }
+ if (csb->csb.base_gstate != 0) {
+ XDPSFreeContextGState(csb->csb.context, csb->csb.base_gstate);
+ }
+
+ if (csb->csb.rgb_labels != NULL) XtFree(csb->csb.rgb_labels);
+ if (csb->csb.cmyk_labels != NULL) XtFree(csb->csb.cmyk_labels);
+ if (csb->csb.hsb_labels != NULL) XtFree(csb->csb.hsb_labels);
+ if (csb->csb.gray_labels != NULL) XtFree(csb->csb.gray_labels);
+ if (csb->csb.fill_me != NULL) XtFree(csb->csb.fill_me);
+ if (csb->csb.broken_palette_message != NULL) {
+ XtFree(csb->csb.broken_palette_message);
+ }
+ if (csb->csb.broken_palette_label != NULL) {
+ XtFree(csb->csb.broken_palette_label);
+ }
+
+ XtFree((XtPointer) csb->csb.dock_cyan);
+ XtFree((XtPointer) csb->csb.dock_magenta);
+ XtFree((XtPointer) csb->csb.dock_yellow);
+ XtFree((XtPointer) csb->csb.dock_black);
+ XtFree((XtPointer) csb->csb.dock_used);
+
+ for (i = 0; i < PALETTE_MAX; i++) {
+ if (csb->csb.palette_function[i] != NULL) {
+ XtFree(csb->csb.palette_function[i]);
+ }
+ }
+
+ if (csb->csb.eyedrop != None) XFreeCursor(dpy, csb->csb.eyedrop);
+ if (csb->csb.square != None) XFreeCursor(dpy, csb->csb.square);
+
+ if (csb->csb.red_pixmap != None) XFreePixmap(dpy, csb->csb.red_pixmap);
+ if (csb->csb.green_pixmap != None) XFreePixmap(dpy, csb->csb.green_pixmap);
+ if (csb->csb.blue_pixmap != None) XFreePixmap(dpy, csb->csb.blue_pixmap);
+ if (csb->csb.cyan_pixmap != None) XFreePixmap(dpy, csb->csb.cyan_pixmap);
+ if (csb->csb.magenta_pixmap != None)
+ XFreePixmap(dpy, csb->csb.magenta_pixmap);
+ if (csb->csb.yellow_pixmap != None)
+ XFreePixmap(dpy, csb->csb.yellow_pixmap);
+ if (csb->csb.black_pixmap != None) XFreePixmap(dpy, csb->csb.black_pixmap);
+ if (csb->csb.hue_pixmap != None) XFreePixmap(dpy, csb->csb.hue_pixmap);
+ if (csb->csb.sat_pixmap != None) XFreePixmap(dpy, csb->csb.sat_pixmap);
+ if (csb->csb.bright_pixmap != None)
+ XFreePixmap(dpy, csb->csb.bright_pixmap);
+ if (csb->csb.gray_pixmap != None) XFreePixmap(dpy, csb->csb.gray_pixmap);
+}
+
+static void ChangeManaged(Widget w)
+{
+ ColorSelectionBoxWidget csb = (ColorSelectionBoxWidget) w;
+
+ w->core.width = csb->composite.children[0]->core.width;
+ w->core.height = csb->composite.children[0]->core.height;
+}
+
+/* ARGSUSED */
+
+static XtGeometryResult GeometryManager(
+ Widget w,
+ XtWidgetGeometry *desired, XtWidgetGeometry *allowed)
+{
+#define WANTS(flag) (desired->request_mode & flag)
+
+ if (WANTS(XtCWQueryOnly)) return XtGeometryYes;
+
+ if (WANTS(CWWidth)) w->core.width = desired->width;
+ if (WANTS(CWHeight)) w->core.height = desired->height;
+ if (WANTS(CWX)) w->core.x = desired->x;
+ if (WANTS(CWY)) w->core.y = desired->y;
+ if (WANTS(CWBorderWidth)) {
+ w->core.border_width = desired->border_width;
+ }
+
+ return XtGeometryYes;
+#undef WANTS
+}
+
+static void SetColorSpace(ColorSelectionBoxWidget csb)
+{
+ switch(csb->csb.current_space) {
+ case CSBSpaceRGB:
+ SetRGBCallback((Widget) csb, (XtPointer) csb, (XtPointer) NULL);
+ break;
+
+ case CSBSpaceCMYK:
+ SetCMYKCallback((Widget) csb, (XtPointer) csb, (XtPointer) NULL);
+ break;
+
+ case CSBSpaceHSB:
+ SetHSBCallback((Widget) csb, (XtPointer) csb, (XtPointer) NULL);
+ break;
+
+ case CSBSpaceGray:
+ SetGrayCallback((Widget) csb, (XtPointer) csb, (XtPointer) NULL);
+ break;
+ }
+}
+
+static void SetRendering(ColorSelectionBoxWidget csb)
+{
+ Widget w;
+
+ switch(csb->csb.current_rendering) {
+ default:
+ case CSBDisplayDPS:
+ w = XtNameToWidget((Widget) csb, "*displayDPS");
+ break;
+ case CSBDisplayX:
+ w = XtNameToWidget((Widget) csb, "*displayX");
+ break;
+ case CSBDisplayBoth:
+ w = XtNameToWidget((Widget) csb, "*displayBoth");
+ break;
+ }
+ XtVaSetValues(csb->csb.display_option_menu_child, XmNmenuHistory, w, NULL);
+ if (XtIsRealized(csb->csb.patch_child)) {
+ XClearArea(XtDisplay(csb), XtWindow(csb->csb.patch_child),
+ 0, 0, 1000, 1000, True);
+ }
+}
+
+static void SetPalette(ColorSelectionBoxWidget csb)
+{
+ Widget w;
+ char buf[10];
+
+ sprintf(buf, "*palette%d", csb->csb.current_palette);
+ w = XtNameToWidget((Widget) csb, buf);
+
+ XtVaSetValues(csb->csb.palette_option_menu_child, XmNmenuHistory, w, NULL);
+
+ csb->csb.palette_pixmap_valid = False;
+ DrawPalette(csb);
+}
+
+static void SetBaseGState(
+ ColorSelectionBoxWidget csb,
+ Visual *visual)
+{
+ XStandardColormap colorCube, grayRamp;
+ int match;
+
+ /* If the context's colormap matches the widget's colormap, assume that
+ everything is already set up right in the color cube department. This
+ allows an application to supply us with a custom color cube by
+ installing it in the context before calling us */
+
+ _DPSCColormapMatch(csb->csb.context, csb->core.colormap, &match);
+
+ if (match) {
+ XDPSSetContextParameters(csb->csb.context, XtScreen(csb),
+ csb->core.depth, XtWindow(csb),
+ csb->core.height, NULL, NULL,
+ XDPSContextScreenDepth | XDPSContextDrawable);
+ } else {
+ grayRamp.colormap = colorCube.colormap = csb->core.colormap;
+
+ XDPSCreateStandardColormaps(XtDisplay(csb), XtWindow(csb), visual,
+ 0, 0, 0, 0, &colorCube, &grayRamp, False);
+
+ XDPSSetContextParameters(csb->csb.context, XtScreen(csb),
+ csb->core.depth, XtWindow(csb),
+ csb->core.height,
+ (XDPSStandardColormap *) &colorCube,
+ (XDPSStandardColormap *) &grayRamp,
+ XDPSContextScreenDepth | XDPSContextDrawable |
+ XDPSContextRGBMap | XDPSContextGrayMap);
+ }
+
+ XDPSCaptureContextGState(csb->csb.context, &csb->csb.base_gstate);
+}
+
+/* ARGSUSED */
+
+static Boolean SetValues(
+ Widget old, Widget req, Widget new,
+ ArgList args,
+ Cardinal *num_args)
+{
+ ColorSelectionBoxWidget oldcsb = (ColorSelectionBoxWidget) old;
+ ColorSelectionBoxWidget newcsb = (ColorSelectionBoxWidget) new;
+ Bool inited;
+ char buf[10];
+ Widget w = 0;
+ int i;
+
+#define NE(field) newcsb->csb.field != oldcsb->csb.field
+
+ if (NE(rgb_labels)) {
+ XtFree(oldcsb->csb.rgb_labels);
+ newcsb->csb.rgb_labels = XtNewString(newcsb->csb.rgb_labels);
+ }
+ if (NE(cmyk_labels)) {
+ XtFree(oldcsb->csb.cmyk_labels);
+ newcsb->csb.cmyk_labels = XtNewString(newcsb->csb.cmyk_labels);
+ }
+ if (NE(hsb_labels)) {
+ XtFree(oldcsb->csb.hsb_labels);
+ newcsb->csb.hsb_labels = XtNewString(newcsb->csb.hsb_labels);
+ }
+ if (NE(gray_labels)) {
+ XtFree(oldcsb->csb.gray_labels);
+ newcsb->csb.gray_labels = XtNewString(newcsb->csb.gray_labels);
+ }
+
+ if (NE(context)) {
+ if (newcsb->csb.context == NULL) {
+ newcsb->csb.context = XDPSGetSharedContext(XtDisplay(newcsb));
+ }
+ if (_XDPSTestComponentInitialized(newcsb->csb.context,
+ dps_init_bit_csb, &inited) ==
+ dps_status_unregistered_context) {
+ XDPSRegisterContext(newcsb->csb.context, False);
+ }
+ if (!inited) {
+ (void) _XDPSSetComponentInitialized(newcsb->csb.context,
+ dps_init_bit_csb);
+ InitializePalettes(newcsb);
+ }
+ newcsb->csb.patch_gstate = newcsb->csb.dock_gstate = 0;
+ XDPSFreeContextGState(newcsb->csb.context, newcsb->csb.patch_gstate);
+ XDPSFreeContextGState(newcsb->csb.context, newcsb->csb.dock_gstate);
+ if (XtIsRealized(newcsb)) {
+ XWindowAttributes xwa;
+
+ XGetWindowAttributes(XtDisplay(newcsb), XtWindow(newcsb), &xwa);
+ SetBaseGState(newcsb, xwa.visual);
+ }
+ }
+
+ if (NE(fill_me)) {
+ XtFree(oldcsb->csb.fill_me);
+ newcsb->csb.fill_me = XtNewString(newcsb->csb.fill_me);
+ }
+
+ if (NE(broken_palette_label)) {
+ XtFree(oldcsb->csb.broken_palette_label);
+ newcsb->csb.broken_palette_label =
+ XtNewString(newcsb->csb.broken_palette_label);
+ }
+
+ if (NE(broken_palette_message)) {
+ XtFree(oldcsb->csb.broken_palette_message);
+ newcsb->csb.broken_palette_message =
+ XtNewString(newcsb->csb.broken_palette_message);
+ }
+
+ if (newcsb->csb.num_cells <= 0) newcsb->csb.num_cells = 1;
+ if (NE(num_cells)) {
+ int i, min;
+
+ AllocateDock(newcsb);
+ min = MIN(newcsb->csb.num_cells, oldcsb->csb.num_cells);
+ for (i = 0; i < min; i++) {
+ newcsb->csb.dock_cyan[i] = oldcsb->csb.dock_cyan[i];
+ newcsb->csb.dock_magenta[i] = oldcsb->csb.dock_magenta[i];
+ newcsb->csb.dock_yellow[i] = oldcsb->csb.dock_yellow[i];
+ newcsb->csb.dock_black[i] = oldcsb->csb.dock_black[i];
+ newcsb->csb.dock_used[i] = oldcsb->csb.dock_used[i];
+ }
+ XtFree((XtPointer) oldcsb->csb.dock_cyan);
+ XtFree((XtPointer) oldcsb->csb.dock_magenta);
+ XtFree((XtPointer) oldcsb->csb.dock_yellow);
+ XtFree((XtPointer) oldcsb->csb.dock_black);
+ XtFree((XtPointer) oldcsb->csb.dock_used);
+ }
+
+ for (i = 0; i < PALETTE_MAX; i++) {
+ if (NE(palette_function[i]) || NE(palette_label[i])) {
+ sprintf(buf, "*palette%d", i);
+ w = XtNameToWidget((Widget) newcsb, buf);
+ }
+ if (NE(palette_function[i])) {
+ if (newcsb->csb.palette_function[i] != NULL) {
+ DPSPrintf(newcsb->csb.context,
+ "/palette%dfunc%d { %s } bind def\n", i,
+ (int) newcsb, newcsb->csb.palette_function[i]);
+ /* Assume the best... */
+ newcsb->csb.palette_broken[i] = False;
+ XtManageChild(w);
+ } else {
+ XtUnmanageChild(w);
+ if (newcsb->csb.current_palette == i) {
+ newcsb->csb.current_palette = -1;
+ }
+ }
+ }
+ if (NE(palette_label[i]) || NE(palette_function[i])) {
+ XtSetSensitive(w, True);
+ XtVaSetValues(w, XtVaTypedArg, XmNlabelString, XtRString,
+ newcsb->csb.palette_label[i],
+ strlen(newcsb->csb.palette_label[i])+1, NULL);
+ }
+ }
+
+ if (NE(current_palette)) {
+ if (newcsb->csb.current_palette < 0 ||
+ newcsb->csb.current_palette > PALETTE_MAX ||
+ newcsb->csb.palette_function[newcsb->csb.current_palette] == NULL ||
+ newcsb->csb.palette_broken[newcsb->csb.current_palette]) {
+ newcsb->csb.current_palette = 0;
+ }
+ }
+ if (NE(current_palette) ||
+ NE(palette_function[newcsb->csb.current_palette])) SetPalette(newcsb);
+
+ if ((NE(cell_size) || NE(fill_me)) &&
+ XtIsRealized(newcsb->csb.dock_child)) {
+ XClearArea(XtDisplay(newcsb), XtWindow(newcsb->csb.dock_child),
+ 0, 0, 1000, 1000, True);
+ }
+
+ if (NE(current_space)) SetColorSpace(newcsb);
+ if (NE(current_rendering)) SetRendering(newcsb);
+
+ return False;
+#undef NE
+}
+
+static void Realize(
+ Widget w,
+ XtValueMask *mask,
+ XSetWindowAttributes *attr)
+{
+ ColorSelectionBoxWidget csb = (ColorSelectionBoxWidget) w;
+ Visual *v;
+
+ (*colorSelectionBoxClassRec.core_class.superclass->core_class.realize)
+ (w, mask, attr);
+
+ GetVisualInfo(csb, &v);
+ SetBackground(csb);
+ SetBaseGState(csb, v);
+ _DPSCGetInvCTM(csb->csb.context, csb->csb.itransform);
+}
+
+static void Resize(Widget widget)
+{
+ ColorSelectionBoxWidget csb = (ColorSelectionBoxWidget) widget;
+
+ XtResizeWidget(csb->csb.form_child, csb->core.width, csb->core.height, 0);
+}
+
+static Boolean SetColor(
+ Widget w,
+ CSBColorSpace space,
+ double c1, double c2, double c3, double c4,
+ Bool setSpace)
+{
+ ColorSelectionBoxWidget csb = (ColorSelectionBoxWidget) w;
+#define CHECK(c) if ((c) > 1.0 || (c) < 0.0) return False;
+
+ CHECK(c1);
+ switch (space) {
+ case CSBSpaceRGB:
+ CHECK(c2);
+ CHECK(c3);
+ csb->csb.current_color.red = c1;
+ csb->csb.current_color.green = c2;
+ csb->csb.current_color.blue = c3;
+ break;
+ case CSBSpaceCMYK:
+ CHECK(c2);
+ CHECK(c3);
+ CHECK(c4);
+ csb->csb.current_color.cyan = c1;
+ csb->csb.current_color.magenta = c2;
+ csb->csb.current_color.yellow = c3;
+ csb->csb.current_color.black = c4;
+ break;
+ case CSBSpaceHSB:
+ CHECK(c2);
+ CHECK(c3);
+ csb->csb.current_color.hue = c1;
+ csb->csb.current_color.saturation = c2;
+ csb->csb.current_color.brightness = c3;
+ break;
+ case CSBSpaceGray:
+ csb->csb.current_color.gray = c1;
+ break;
+ }
+ UpdateColorSpaces(csb, space);
+ csb->csb.save_color = csb->csb.current_color;
+ DoValueChangedCallback(csb);
+ FillPatch(csb);
+ SetSliders(csb);
+ if (setSpace) XtVaSetValues(w, XtNcurrentSpace, space, NULL);
+ return True;
+#undef CHECK
+}
+
+Boolean CSBSetColor(
+ Widget w,
+ CSBColorSpace space,
+ double c1, double c2, double c3, double c4,
+ Bool setSpace)
+{
+ XtCheckSubclass(w, colorSelectionBoxWidgetClass, NULL);
+
+ return (*((ColorSelectionBoxWidgetClass) XtClass(w))->
+ csb_class.set_color) (w, space, c1, c2, c3, c4, setSpace);
+}
+
+static void GetColor(
+ Widget w,
+ CSBColorSpace space,
+ float *c1, float *c2, float *c3, float *c4)
+{
+ ColorSelectionBoxWidget csb = (ColorSelectionBoxWidget) w;
+
+ switch (space) {
+ case CSBSpaceRGB:
+ *c1 = csb->csb.current_color.red;
+ *c2 = csb->csb.current_color.green;
+ *c3 = csb->csb.current_color.blue;
+ break;
+ case CSBSpaceCMYK:
+ *c1 = csb->csb.current_color.cyan;
+ *c2 = csb->csb.current_color.magenta;
+ *c3 = csb->csb.current_color.yellow;
+ *c4 = csb->csb.current_color.black;
+ break;
+ case CSBSpaceHSB:
+ *c1 = csb->csb.current_color.hue;
+ *c2 = csb->csb.current_color.saturation;
+ *c3 = csb->csb.current_color.brightness;
+ break;
+ case CSBSpaceGray:
+ *c1 = csb->csb.current_color.gray;
+ break;
+ }
+}
+
+void CSBGetColor(
+ Widget w,
+ CSBColorSpace space,
+ float *c1, float *c2, float *c3, float *c4)
+{
+ XtCheckSubclass(w, colorSelectionBoxWidgetClass, NULL);
+
+ (*((ColorSelectionBoxWidgetClass) XtClass(w))->
+ csb_class.get_color) (w, space, c1, c2, c3, c4);
+}