diff options
author | Reinhard Tartler <siretart@tauware.de> | 2011-10-10 17:43:39 +0200 |
---|---|---|
committer | Reinhard Tartler <siretart@tauware.de> | 2011-10-10 17:43:39 +0200 |
commit | f4092abdf94af6a99aff944d6264bc1284e8bdd4 (patch) | |
tree | 2ac1c9cc16ceb93edb2c4382c088dac5aeafdf0f /nx-X11/lib/dpstk/ColorSB.c | |
parent | a840692edc9c6d19cd7c057f68e39c7d95eb767d (diff) | |
download | nx-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.c | 3388 |
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); +} |