PageRenderTime 76ms CodeModel.GetById 30ms RepoModel.GetById 0ms app.codeStats 0ms

/nx-3.5.0/nx-X11/lib/dpstk/ColorSB.c

#
C | 3388 lines | 2774 code | 516 blank | 98 comment | 418 complexity | b6ead1ec887261fcc4de0735b5c04568 MD5 | raw file
Possible License(s): BSD-3-Clause, GPL-2.0, LGPL-2.0
  1. /*
  2. * ColorSB.c
  3. *
  4. * (c) Copyright 1993-1994 Adobe Systems Incorporated.
  5. * All rights reserved.
  6. *
  7. * Permission to use, copy, modify, distribute, and sublicense this software
  8. * and its documentation for any purpose and without fee is hereby granted,
  9. * provided that the above copyright notices appear in all copies and that
  10. * both those copyright notices and this permission notice appear in
  11. * supporting documentation and that the name of Adobe Systems Incorporated
  12. * not be used in advertising or publicity pertaining to distribution of the
  13. * software without specific, written prior permission. No trademark license
  14. * to use the Adobe trademarks is hereby granted. If the Adobe trademark
  15. * "Display PostScript"(tm) is used to describe this software, its
  16. * functionality or for any other purpose, such use shall be limited to a
  17. * statement that this software works in conjunction with the Display
  18. * PostScript system. Proper trademark attribution to reflect Adobe's
  19. * ownership of the trademark shall be given whenever any such reference to
  20. * the Display PostScript system is made.
  21. *
  22. * ADOBE MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THE SOFTWARE FOR
  23. * ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
  24. * ADOBE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
  25. * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  26. * NON- INFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL ADOBE BE LIABLE
  27. * TO YOU OR ANY OTHER PARTY FOR ANY SPECIAL, INDIRECT, OR CONSEQUENTIAL
  28. * DAMAGES OR ANY DAMAGES WHATSOEVER WHETHER IN AN ACTION OF CONTRACT,
  29. * NEGLIGENCE, STRICT LIABILITY OR ANY OTHER ACTION ARISING OUT OF OR IN
  30. * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ADOBE WILL NOT
  31. * PROVIDE ANY TRAINING OR OTHER SUPPORT FOR THE SOFTWARE.
  32. *
  33. * Adobe, PostScript, and Display PostScript are trademarks of Adobe Systems
  34. * Incorporated which may be registered in certain jurisdictions
  35. *
  36. * Author: Adobe Systems Incorporated
  37. */
  38. /* $XFree86$ */
  39. #ifndef X_NOT_POSIX
  40. #include <unistd.h>
  41. #endif
  42. #include <X11/IntrinsicP.h>
  43. #include <X11/StringDefs.h>
  44. #include <X11/ShellP.h>
  45. #include <stdlib.h>
  46. #include <Xm/Xm.h>
  47. /* There are no words to describe how I feel about having to do this */
  48. #if XmVersion > 1001
  49. #include <Xm/ManagerP.h>
  50. #else
  51. #include <Xm/XmP.h>
  52. #endif
  53. #include <Xm/Form.h>
  54. #include <Xm/Label.h>
  55. #include <Xm/LabelG.h>
  56. #include <Xm/PushB.h>
  57. #include <Xm/PushBG.h>
  58. #include <Xm/SeparatoG.h>
  59. #include <Xm/DrawingA.h>
  60. #include <Xm/Scale.h>
  61. #include <Xm/RowColumn.h>
  62. #include <Xm/Frame.h>
  63. #include <Xm/MessageB.h>
  64. #include <DPS/dpsXclient.h>
  65. #include "dpsXcommonI.h"
  66. #include <DPS/dpsXshare.h>
  67. #include "eyedrop16.xbm"
  68. #include "eyedropmask16.xbm"
  69. #include "eyedrop32.xbm"
  70. #include "eyedropmask32.xbm"
  71. #include "heyedrop.xbm"
  72. #include "square.xbm"
  73. #include "squaremask.xbm"
  74. #include "CSBwraps.h"
  75. #include <math.h>
  76. #include <stdio.h>
  77. #include <pwd.h>
  78. #include <DPS/ColorSBP.h>
  79. #define PATH_BUF_SIZE 1024
  80. /* Turn a string into a compound string */
  81. #define CS(str, w) CreateSharedCS(str, w)
  82. #undef MIN
  83. #define MIN(a, b) ((a) < (b) ? (a) : (b))
  84. #undef MAX
  85. #define MAX(a, b) ((a) > (b) ? (a) : (b))
  86. #define TO_PCT(val) ((int) (val * 100.0 + 0.5))
  87. #define TO_X(color) ((color) * 65535)
  88. #define Offset(field) XtOffsetOf(ColorSelectionBoxRec, csb.field)
  89. static XtResource resources[] = {
  90. {XtNcontext, XtCContext, XtRDPSContext, sizeof(DPSContext),
  91. Offset(context), XtRDPSContext, (XtPointer) NULL},
  92. {XtNrgbLabels, XtCRgbLabels, XtRString, sizeof(String),
  93. Offset(rgb_labels), XtRString, (XtPointer) "R:G:B"},
  94. {XtNcmykLabels, XtCCmykLabels, XtRString, sizeof(String),
  95. Offset(cmyk_labels), XtRString, (XtPointer) "C:M:Y:K"},
  96. {XtNhsbLabels, XtCHsbLabels, XtRString, sizeof(String),
  97. Offset(hsb_labels), XtRString, (XtPointer) "H:S:B"},
  98. {XtNgrayLabels, XtCGrayLabels, XtRString, sizeof(String),
  99. Offset(gray_labels), XtRString, (XtPointer) "Gray"},
  100. {XtNcellSize, XtCCellSize, XtRDimension, sizeof(Dimension),
  101. Offset(cell_size), XtRImmediate, (XtPointer) 15},
  102. {XtNnumCells, XtCNumCells, XtRShort, sizeof(short),
  103. Offset(num_cells), XtRImmediate, (XtPointer) 30},
  104. {XtNfillMe, XtCFillMe, XtRString, sizeof(String),
  105. Offset(fill_me), XtRString, (XtPointer) "Fill me with colors"},
  106. {XtNcurrentSpace, XtCCurrentSpace, XtRColorSpace, sizeof(CSBColorSpace),
  107. Offset(current_space), XtRImmediate, (XtPointer) CSBSpaceHSB},
  108. {XtNcurrentRendering, XtCCurrentRendering, XtRRenderingType,
  109. sizeof(CSBRenderingType), Offset(current_rendering),
  110. XtRImmediate, (XtPointer) CSBDisplayDPS},
  111. {XtNcurrentPalette, XtCCurrentPalette, XtRShort, sizeof(short),
  112. Offset(current_palette), XtRImmediate, (XtPointer) 0},
  113. {XtNbrokenPaletteLabel, XtCBrokenPaletteLabel, XtRString,
  114. sizeof(String), Offset(broken_palette_label),
  115. XtRString, (XtPointer) "(broken)"},
  116. {XtNbrokenPaletteMessage, XtCBrokenPaletteMessage, XtRString,
  117. sizeof(String), Offset(broken_palette_message),
  118. XtRString, (XtPointer) "The current palette contains an error"},
  119. {XtNpalette0Label, XtCPaletteLabel, XtRString, sizeof(String),
  120. Offset(palette_label[0]), XtRString, (XtPointer) NULL},
  121. {XtNpalette0Space, XtCPaletteSpace, XtRColorSpace, sizeof(CSBColorSpace),
  122. Offset(palette_space[0]), XtRImmediate, (XtPointer) CSBSpaceRGB},
  123. {XtNpalette0ColorDependent, XtCPaletteColorDependent,
  124. XtRBoolean, sizeof(Boolean),
  125. Offset(palette_color_dependent[0]), XtRImmediate, (XtPointer) False},
  126. {XtNpalette0Function, XtCPaletteFunction, XtRString, sizeof(String),
  127. Offset(palette_function[0]), XtRImmediate, (XtPointer) NULL},
  128. {XtNpalette1Label, XtCPaletteLabel, XtRString, sizeof(String),
  129. Offset(palette_label[1]), XtRString, (XtPointer) NULL},
  130. {XtNpalette1Space, XtCPaletteSpace, XtRColorSpace, sizeof(CSBColorSpace),
  131. Offset(palette_space[1]), XtRImmediate, (XtPointer) CSBSpaceRGB},
  132. {XtNpalette1ColorDependent, XtCPaletteColorDependent,
  133. XtRBoolean, sizeof(Boolean),
  134. Offset(palette_color_dependent[1]), XtRImmediate, (XtPointer) False},
  135. {XtNpalette1Function, XtCPaletteFunction, XtRString, sizeof(String),
  136. Offset(palette_function[1]), XtRImmediate, (XtPointer) NULL},
  137. {XtNpalette2Label, XtCPaletteLabel, XtRString, sizeof(String),
  138. Offset(palette_label[2]), XtRString, (XtPointer) NULL},
  139. {XtNpalette2Space, XtCPaletteSpace, XtRColorSpace, sizeof(CSBColorSpace),
  140. Offset(palette_space[2]), XtRImmediate, (XtPointer) CSBSpaceRGB},
  141. {XtNpalette2ColorDependent, XtCPaletteColorDependent,
  142. XtRBoolean, sizeof(Boolean),
  143. Offset(palette_color_dependent[2]), XtRImmediate, (XtPointer) False},
  144. {XtNpalette2Function, XtCPaletteFunction, XtRString, sizeof(String),
  145. Offset(palette_function[2]), XtRImmediate, (XtPointer) NULL},
  146. {XtNpalette3Label, XtCPaletteLabel, XtRString, sizeof(String),
  147. Offset(palette_label[3]), XtRString, (XtPointer) NULL},
  148. {XtNpalette3Space, XtCPaletteSpace, XtRColorSpace, sizeof(CSBColorSpace),
  149. Offset(palette_space[3]), XtRImmediate, (XtPointer) CSBSpaceRGB},
  150. {XtNpalette3ColorDependent, XtCPaletteColorDependent,
  151. XtRBoolean, sizeof(Boolean),
  152. Offset(palette_color_dependent[3]), XtRImmediate, (XtPointer) False},
  153. {XtNpalette3Function, XtCPaletteFunction, XtRString, sizeof(String),
  154. Offset(palette_function[3]), XtRImmediate, (XtPointer) NULL},
  155. {XtNpalette4Label, XtCPaletteLabel, XtRString, sizeof(String),
  156. Offset(palette_label[4]), XtRString, (XtPointer) NULL},
  157. {XtNpalette4Space, XtCPaletteSpace, XtRColorSpace, sizeof(CSBColorSpace),
  158. Offset(palette_space[4]), XtRImmediate, (XtPointer) CSBSpaceRGB},
  159. {XtNpalette4ColorDependent, XtCPaletteColorDependent,
  160. XtRBoolean, sizeof(Boolean),
  161. Offset(palette_color_dependent[4]), XtRImmediate, (XtPointer) False},
  162. {XtNpalette4Function, XtCPaletteFunction, XtRString, sizeof(String),
  163. Offset(palette_function[4]), XtRImmediate, (XtPointer) NULL},
  164. {XtNpalette5Label, XtCPaletteLabel, XtRString, sizeof(String),
  165. Offset(palette_label[5]), XtRString, (XtPointer) NULL},
  166. {XtNpalette5Space, XtCPaletteSpace, XtRColorSpace, sizeof(CSBColorSpace),
  167. Offset(palette_space[5]), XtRImmediate, (XtPointer) CSBSpaceRGB},
  168. {XtNpalette5ColorDependent, XtCPaletteColorDependent,
  169. XtRBoolean, sizeof(Boolean),
  170. Offset(palette_color_dependent[5]), XtRImmediate, (XtPointer) False},
  171. {XtNpalette5Function, XtCPaletteFunction, XtRString, sizeof(String),
  172. Offset(palette_function[5]), XtRImmediate, (XtPointer) NULL},
  173. {XtNpalette6Label, XtCPaletteLabel, XtRString, sizeof(String),
  174. Offset(palette_label[6]), XtRString, (XtPointer) NULL},
  175. {XtNpalette6Space, XtCPaletteSpace, XtRColorSpace, sizeof(CSBColorSpace),
  176. Offset(palette_space[6]), XtRImmediate, (XtPointer) CSBSpaceRGB},
  177. {XtNpalette6ColorDependent, XtCPaletteColorDependent,
  178. XtRBoolean, sizeof(Boolean),
  179. Offset(palette_color_dependent[6]), XtRImmediate, (XtPointer) False},
  180. {XtNpalette6Function, XtCPaletteFunction, XtRString, sizeof(String),
  181. Offset(palette_function[6]), XtRImmediate, (XtPointer) NULL},
  182. {XtNpalette7Label, XtCPaletteLabel, XtRString, sizeof(String),
  183. Offset(palette_label[7]), XtRString, (XtPointer) NULL},
  184. {XtNpalette7Space, XtCPaletteSpace, XtRColorSpace, sizeof(CSBColorSpace),
  185. Offset(palette_space[7]), XtRImmediate, (XtPointer) CSBSpaceRGB},
  186. {XtNpalette7ColorDependent, XtCPaletteColorDependent,
  187. XtRBoolean, sizeof(Boolean),
  188. Offset(palette_color_dependent[7]), XtRImmediate, (XtPointer) False},
  189. {XtNpalette7Function, XtCPaletteFunction, XtRString, sizeof(String),
  190. Offset(palette_function[7]), XtRImmediate, (XtPointer) NULL},
  191. {XtNpalette8Label, XtCPaletteLabel, XtRString, sizeof(String),
  192. Offset(palette_label[8]), XtRString, (XtPointer) NULL},
  193. {XtNpalette8Space, XtCPaletteSpace, XtRColorSpace, sizeof(CSBColorSpace),
  194. Offset(palette_space[8]), XtRImmediate, (XtPointer) CSBSpaceRGB},
  195. {XtNpalette8ColorDependent, XtCPaletteColorDependent,
  196. XtRBoolean, sizeof(Boolean),
  197. Offset(palette_color_dependent[8]), XtRImmediate, (XtPointer) False},
  198. {XtNpalette8Function, XtCPaletteFunction, XtRString, sizeof(String),
  199. Offset(palette_function[8]), XtRImmediate, (XtPointer) NULL},
  200. {XtNpalette9Label, XtCPaletteLabel, XtRString, sizeof(String),
  201. Offset(palette_label[9]), XtRString, (XtPointer) NULL},
  202. {XtNpalette9Space, XtCPaletteSpace, XtRColorSpace, sizeof(CSBColorSpace),
  203. Offset(palette_space[9]), XtRImmediate, (XtPointer) CSBSpaceRGB},
  204. {XtNpalette9ColorDependent, XtCPaletteColorDependent,
  205. XtRBoolean, sizeof(Boolean),
  206. Offset(palette_color_dependent[9]), XtRImmediate, (XtPointer) False},
  207. {XtNpalette9Function, XtCPaletteFunction, XtRString, sizeof(String),
  208. Offset(palette_function[9]), XtRImmediate, (XtPointer) NULL},
  209. {XtNokCallback, XtCCallback, XtRCallback, sizeof(XtCallbackList),
  210. Offset(ok_callback), XtRCallback, (XtPointer) NULL},
  211. {XtNapplyCallback, XtCCallback, XtRCallback, sizeof(XtCallbackList),
  212. Offset(apply_callback), XtRCallback, (XtPointer) NULL},
  213. {XtNresetCallback, XtCCallback, XtRCallback, sizeof(XtCallbackList),
  214. Offset(reset_callback), XtRCallback, (XtPointer) NULL},
  215. {XtNcancelCallback, XtCCallback, XtRCallback, sizeof(XtCallbackList),
  216. Offset(cancel_callback), XtRCallback, (XtPointer) NULL},
  217. {XtNvalueChangedCallback, XtCCallback, XtRCallback, sizeof(XtCallbackList),
  218. Offset(value_changed_callback), XtRCallback, (XtPointer) NULL}
  219. };
  220. static Boolean SetColor (Widget w, CSBColorSpace space, double c1, double c2, double c3, double c4, Bool setSpace);
  221. static Boolean SetValues (Widget old, Widget req, Widget new, ArgList args, Cardinal *num_args);
  222. static XtGeometryResult GeometryManager (Widget w, XtWidgetGeometry *desired, XtWidgetGeometry *allowed);
  223. static void ChangeLabel (Widget label, double n);
  224. static void ChangeManaged (Widget w);
  225. static void ClassInitialize (void);
  226. static void ClassPartInitialize (WidgetClass widget_class);
  227. static void CreateChildren (ColorSelectionBoxWidget csb);
  228. static void Destroy (Widget widget);
  229. static void DrawDock (ColorSelectionBoxWidget csb);
  230. static void DrawPalette (ColorSelectionBoxWidget csb);
  231. static void FillPatch (ColorSelectionBoxWidget csb);
  232. static void GetColor (Widget w, CSBColorSpace space, float *c1, float *c2, float *c3, float *c4);
  233. static void Initialize (Widget request, Widget new, ArgList args, Cardinal *num_args);
  234. static void InitializeDock (ColorSelectionBoxWidget csb);
  235. static void Realize (Widget w, XtValueMask *mask, XSetWindowAttributes *attr);
  236. static void Resize (Widget widget);
  237. static void SaveDockContents (ColorSelectionBoxWidget csb);
  238. static void SetBackground (ColorSelectionBoxWidget csb);
  239. static void SetCMYKValues (ColorSelectionBoxWidget csb);
  240. static void SetColorSpace (ColorSelectionBoxWidget csb);
  241. static void SetGrayValues (ColorSelectionBoxWidget csb);
  242. static void SetHSBValues (ColorSelectionBoxWidget csb);
  243. static void SetRGBValues (ColorSelectionBoxWidget csb);
  244. static void SetRendering (ColorSelectionBoxWidget csb);
  245. static void SetSliders (ColorSelectionBoxWidget csb);
  246. static void UpdateColorSpaces (ColorSelectionBoxWidget csb, CSBColorSpace masterSpace);
  247. static void DockPress (Widget w, XtPointer data, XEvent *event, Boolean *goOn);
  248. static void EyedropPointer (Widget w, XtPointer data, XEvent *event, Boolean *goOn);
  249. static void FormResize (Widget w, XtPointer data, XEvent *event, Boolean *goOn);
  250. static void PalettePress (Widget w, XtPointer data, XEvent *event, Boolean *goOn);
  251. static void PatchPress (Widget w, XtPointer data, XEvent *event, Boolean *goOn);
  252. static void PatchRelease (Widget w, XtPointer data, XEvent *event, Boolean *goOn);
  253. static void ApplyCallback (Widget w, XtPointer clientData, XtPointer callData);
  254. static void DoEyedropCallback (Widget w, XtPointer clientData, XtPointer callData);
  255. static void DrawDockCallback (Widget w, XtPointer clientData, XtPointer callData);
  256. static void DrawPaletteCallback (Widget w, XtPointer clientData, XtPointer callData);
  257. static void FillPatchCallback (Widget w, XtPointer clientData, XtPointer callData);
  258. static void OKCallback (Widget w, XtPointer clientData, XtPointer callData);
  259. static void SetCMYKCallback (Widget w, XtPointer clientData, XtPointer callData);
  260. static void SetGrayCallback (Widget w, XtPointer clientData, XtPointer callData);
  261. static void SetHSBCallback (Widget w, XtPointer clientData, XtPointer callData);
  262. static void SetRGBCallback (Widget w, XtPointer clientData, XtPointer callData);
  263. static void Slider1Callback (Widget w, XtPointer clientData, XtPointer callData);
  264. static void Slider2Callback (Widget w, XtPointer clientData, XtPointer callData);
  265. static void Slider3Callback (Widget w, XtPointer clientData, XtPointer callData);
  266. static void Slider4Callback (Widget w, XtPointer clientData, XtPointer callData);
  267. ColorSelectionBoxClassRec colorSelectionBoxClassRec = {
  268. /* Core class part */
  269. {
  270. /* superclass */ (WidgetClass) &xmManagerClassRec,
  271. /* class_name */ "ColorSelectionBox",
  272. /* widget_size */ sizeof(ColorSelectionBoxRec),
  273. /* class_initialize */ ClassInitialize,
  274. /* class_part_initialize */ ClassPartInitialize,
  275. /* class_inited */ False,
  276. /* initialize */ Initialize,
  277. /* initialize_hook */ NULL,
  278. /* realize */ Realize,
  279. /* actions */ NULL,
  280. /* num_actions */ 0,
  281. /* resources */ resources,
  282. /* num_resources */ XtNumber(resources),
  283. /* xrm_class */ NULLQUARK,
  284. /* compress_motion */ True,
  285. /* compress_exposure */ XtExposeCompressMultiple,
  286. /* compress_enterleave */ True,
  287. /* visible_interest */ False,
  288. /* destroy */ Destroy,
  289. /* resize */ Resize,
  290. /* expose */ NULL,
  291. /* set_values */ SetValues,
  292. /* set_values_hook */ NULL,
  293. /* set_values_almost */ XtInheritSetValuesAlmost,
  294. /* get_values_hook */ NULL,
  295. /* accept_focus */ NULL,
  296. /* version */ XtVersion,
  297. /* callback offsets */ NULL,
  298. /* tm_table */ NULL,
  299. /* query_geometry */ XtInheritQueryGeometry,
  300. /* display_accelerator */ NULL,
  301. /* extension */ NULL,
  302. },
  303. /* Composite class part */
  304. {
  305. /* geometry_manager */ GeometryManager,
  306. /* change_managed */ ChangeManaged,
  307. /* insert_child */ XtInheritInsertChild,
  308. /* delete_child */ XtInheritDeleteChild,
  309. /* extension */ NULL,
  310. },
  311. /* Constraint class part */
  312. {
  313. /* resources */ NULL,
  314. /* num_resources */ 0,
  315. /* constraint_size */ 0,
  316. /* initialize */ NULL,
  317. /* destroy */ NULL,
  318. /* set_values */ NULL,
  319. /* extension */ NULL,
  320. },
  321. /* Manager class part */
  322. {
  323. /* translations */ XtInheritTranslations,
  324. /* syn_resources */ NULL,
  325. /* num_syn_resources */ 0,
  326. /* syn_constraint_resources */ NULL,
  327. /* num_syn_constraint_resources */ 0,
  328. /* parent_process */ XmInheritParentProcess,
  329. /* extension */ NULL,
  330. },
  331. /* ColorSelectionBox class part */
  332. {
  333. /* set_color */ SetColor,
  334. /* get_color */ GetColor,
  335. /* extension */ NULL,
  336. }
  337. };
  338. WidgetClass colorSelectionBoxWidgetClass =
  339. (WidgetClass) &colorSelectionBoxClassRec;
  340. static XmString CreateSharedCS(String str, Widget w)
  341. {
  342. XrmValue src, dst;
  343. XmString result;
  344. src.addr = str;
  345. src.size = strlen(str);
  346. dst.addr = (caddr_t) &result;
  347. dst.size = sizeof(result);
  348. if (XtConvertAndStore(w, XtRString, &src, XmRXmString, &dst)) {
  349. return result;
  350. } else return NULL;
  351. }
  352. static Boolean LowerCase(String from, String to, int size)
  353. {
  354. register char ch;
  355. register int i;
  356. for (i = 0; i < size; i++) {
  357. ch = from[i];
  358. if (ch >= 'A' && ch <= 'Z') to[i] = ch - 'A' + 'a';
  359. else to[i] = ch;
  360. if (ch == '\0') return False;
  361. }
  362. return TRUE;
  363. }
  364. /* ARGSUSED */
  365. static Boolean CvtStringToColorSpace(
  366. Display *dpy,
  367. XrmValuePtr args,
  368. Cardinal *num_args,
  369. XrmValuePtr from,
  370. XrmValuePtr to,
  371. XtPointer *data)
  372. {
  373. #define LOWER_SIZE 5
  374. char lower[LOWER_SIZE]; /* Lower cased string value */
  375. Boolean badConvert;
  376. static CSBColorSpace c;
  377. if (*num_args != 0) { /* Check for correct number */
  378. XtAppErrorMsg(XtDisplayToApplicationContext(dpy),
  379. "cvtStringToColorSpace", "wrongParameters",
  380. "XtToolkitError",
  381. "String to colorspace conversion needs no extra arguments",
  382. (String *) NULL, (Cardinal *) NULL);
  383. }
  384. /* Lower case the value */
  385. badConvert = LowerCase(from->addr, lower, LOWER_SIZE);
  386. /* Try to convert if a short enough string specified */
  387. if (!badConvert) {
  388. if (strcmp(lower, "rgb") == 0) c = CSBSpaceRGB;
  389. else if (strcmp(lower, "cmyk") == 0) c = CSBSpaceCMYK;
  390. else if (strcmp(lower, "hsb") == 0) c = CSBSpaceHSB;
  391. else if (strcmp(lower, "gray") == 0) c = CSBSpaceGray;
  392. else if (strcmp(lower, "grey") == 0) c = CSBSpaceGray;
  393. else badConvert = True;
  394. }
  395. /* String too long or unknown value -- issue warning */
  396. if (badConvert) {
  397. XtDisplayStringConversionWarning(dpy, from->addr, "ColorSpace");
  398. } else {
  399. if (to->addr == NULL) to->addr = (caddr_t) &c;
  400. else if (to->size < sizeof(CSBColorSpace)) badConvert = TRUE;
  401. else *(CSBColorSpace *) to->addr = c;
  402. to->size = sizeof(CSBColorSpace);
  403. }
  404. return !badConvert;
  405. #undef LOWER_SIZE
  406. }
  407. /* ARGSUSED */
  408. static Boolean CvtStringToRenderingType(
  409. Display *dpy,
  410. XrmValuePtr args,
  411. Cardinal *num_args,
  412. XrmValuePtr from,
  413. XrmValuePtr to,
  414. XtPointer *data)
  415. {
  416. #define LOWER_SIZE 5
  417. char lower[LOWER_SIZE]; /* Lower cased string value */
  418. Boolean badConvert;
  419. static CSBRenderingType c;
  420. if (*num_args != 0) { /* Check for correct number */
  421. XtAppErrorMsg(XtDisplayToApplicationContext(dpy),
  422. "cvtStringToRenderingType", "wrongParameters",
  423. "XtToolkitError",
  424. "String to rendering type conversion needs no extra arguments",
  425. (String *) NULL, (Cardinal *) NULL);
  426. }
  427. /* Lower case the value */
  428. badConvert = LowerCase(from->addr, lower, LOWER_SIZE);
  429. /* Try to convert if a short enough string specified */
  430. if (!badConvert) {
  431. if (strcmp(lower, "x") == 0) c = CSBDisplayX;
  432. else if (strcmp(lower, "dps") == 0) c = CSBDisplayDPS;
  433. else if (strcmp(lower, "both") == 0) c = CSBDisplayBoth;
  434. else badConvert = True;
  435. }
  436. /* String too long or unknown value -- issue warning */
  437. if (badConvert) {
  438. XtDisplayStringConversionWarning(dpy, from->addr, "RenderingType");
  439. } else {
  440. if (to->addr == NULL) to->addr = (caddr_t) &c;
  441. else if (to->size < sizeof(CSBRenderingType)) badConvert = TRUE;
  442. else *(CSBRenderingType *) to->addr = c;
  443. to->size = sizeof(CSBRenderingType);
  444. }
  445. return !badConvert;
  446. #undef LOWER_SIZE
  447. }
  448. static void ClassInitialize(void)
  449. {
  450. /* Register converters */
  451. XtSetTypeConverter(XtRString, XtRColorSpace,
  452. CvtStringToColorSpace, (XtConvertArgList) NULL, 0,
  453. XtCacheAll, (XtDestructor) NULL);
  454. XtSetTypeConverter(XtRString, XtRRenderingType,
  455. CvtStringToRenderingType, (XtConvertArgList) NULL, 0,
  456. XtCacheAll, (XtDestructor) NULL);
  457. }
  458. /* ARGSUSED */
  459. static void ClassPartInitialize(WidgetClass widget_class)
  460. {
  461. register ColorSelectionBoxWidgetClass wc =
  462. (ColorSelectionBoxWidgetClass) widget_class;
  463. ColorSelectionBoxWidgetClass super =
  464. (ColorSelectionBoxWidgetClass) wc->core_class.superclass;
  465. if (wc->csb_class.set_color == InheritSetColor) {
  466. wc->csb_class.set_color = super->csb_class.set_color;
  467. }
  468. if (wc->csb_class.get_color == InheritGetColor) {
  469. wc->csb_class.get_color = super->csb_class.get_color;
  470. }
  471. }
  472. static void ToUserSpace(
  473. ColorSelectionBoxWidget csb,
  474. int xWidth, int xHeight,
  475. float *uWidth, float *uHeight)
  476. {
  477. register float *i = csb->csb.itransform;
  478. *uWidth = i[0] * xWidth - i[2] * xHeight + i[4];
  479. *uHeight= i[1] * xWidth - i[3] * xHeight + i[5];
  480. }
  481. static void ColorizeRGB(ColorSelectionBoxWidget csb)
  482. {
  483. Dimension height, width;
  484. int depth, steps;
  485. float w, h;
  486. XtVaGetValues(csb->csb.slider_child[0], XtNwidth, &width,
  487. XtNheight, &height,
  488. XtNdepth, &depth, NULL);
  489. if (csb->csb.red_pixmap != None && width != csb->csb.rgb_slider_width) {
  490. XFreePixmap(XtDisplay(csb), csb->csb.red_pixmap);
  491. XFreePixmap(XtDisplay(csb), csb->csb.green_pixmap);
  492. XFreePixmap(XtDisplay(csb), csb->csb.blue_pixmap);
  493. csb->csb.red_pixmap = None;
  494. }
  495. if (csb->csb.red_pixmap == None) {
  496. csb->csb.rgb_slider_width = width;
  497. if (csb->csb.visual_class == TrueColor) steps = width / 2;
  498. else steps = width / 4;
  499. ToUserSpace(csb, width, height, &w, &h);
  500. csb->csb.red_pixmap = XCreatePixmap(XtDisplay(csb), XtWindow(csb),
  501. width, height, depth);
  502. XDPSSetContextGState(csb->csb.context, csb->csb.base_gstate);
  503. XDPSSetContextDrawable(csb->csb.context, csb->csb.red_pixmap, height);
  504. _DPSCRGBBlend(csb->csb.context, 0.0, 0.0, w, h, "0 0", steps);
  505. csb->csb.green_pixmap = XCreatePixmap(XtDisplay(csb), XtWindow(csb),
  506. width, height, depth);
  507. XDPSSetContextDrawable(csb->csb.context,
  508. csb->csb.green_pixmap, height);
  509. _DPSCRGBBlend(csb->csb.context, 0.0, 0.0, w, h, "0 exch 0", steps);
  510. csb->csb.blue_pixmap = XCreatePixmap(XtDisplay(csb), XtWindow(csb),
  511. width, height, depth);
  512. XDPSSetContextDrawable(csb->csb.context, csb->csb.blue_pixmap, height);
  513. _DPSCRGBBlend(csb->csb.context,
  514. 0.0, 0.0, w, h, "0 0 3 -1 roll", steps);
  515. DPSWaitContext(csb->csb.context);
  516. }
  517. XtVaSetValues(csb->csb.slider_child[0],
  518. XtNbackgroundPixmap, csb->csb.red_pixmap, NULL);
  519. XtVaSetValues(csb->csb.slider_child[1],
  520. XtNbackgroundPixmap, csb->csb.green_pixmap, NULL);
  521. XtVaSetValues(csb->csb.slider_child[2],
  522. XtNbackgroundPixmap, csb->csb.blue_pixmap, NULL);
  523. }
  524. static void ColorizeCMYK(ColorSelectionBoxWidget csb)
  525. {
  526. Dimension height, width;
  527. int depth, steps;
  528. float w, h;
  529. XtVaGetValues(csb->csb.slider_child[0], XtNwidth, &width,
  530. XtNheight, &height,
  531. XtNdepth, &depth, NULL);
  532. if (csb->csb.cyan_pixmap != None && width != csb->csb.cmyk_slider_width) {
  533. XFreePixmap(XtDisplay(csb), csb->csb.cyan_pixmap);
  534. XFreePixmap(XtDisplay(csb), csb->csb.magenta_pixmap);
  535. XFreePixmap(XtDisplay(csb), csb->csb.yellow_pixmap);
  536. XFreePixmap(XtDisplay(csb), csb->csb.black_pixmap);
  537. csb->csb.cyan_pixmap = None;
  538. }
  539. if (csb->csb.cyan_pixmap == None) {
  540. csb->csb.cmyk_slider_width = width;
  541. if (csb->csb.visual_class == TrueColor) steps = width / 2;
  542. else steps = width / 4;
  543. ToUserSpace(csb, width, height, &w, &h);
  544. csb->csb.cyan_pixmap = XCreatePixmap(XtDisplay(csb), XtWindow(csb),
  545. width, height, depth);
  546. XDPSSetContextGState(csb->csb.context, csb->csb.base_gstate);
  547. XDPSSetContextDrawable(csb->csb.context, csb->csb.cyan_pixmap, height);
  548. _DPSCCMYKBlend(csb->csb.context, 0.0, 0.0, w, h, "0 0 0", steps);
  549. csb->csb.magenta_pixmap = XCreatePixmap(XtDisplay(csb), XtWindow(csb),
  550. width, height, depth);
  551. XDPSSetContextDrawable(csb->csb.context, csb->csb.magenta_pixmap,
  552. height);
  553. _DPSCCMYKBlend(csb->csb.context, 0.0, 0.0, w, h, "0 exch 0 0", steps);
  554. csb->csb.yellow_pixmap = XCreatePixmap(XtDisplay(csb), XtWindow(csb),
  555. width, height, depth);
  556. XDPSSetContextDrawable(csb->csb.context, csb->csb.yellow_pixmap,
  557. height);
  558. _DPSCCMYKBlend(csb->csb.context, 0.0, 0.0, w, h, "0 0 3 -1 roll 0",
  559. steps);
  560. csb->csb.black_pixmap = XCreatePixmap(XtDisplay(csb), XtWindow(csb),
  561. width, height, depth);
  562. XDPSSetContextDrawable(csb->csb.context, csb->csb.black_pixmap,
  563. height);
  564. _DPSCCMYKBlend(csb->csb.context, 0.0, 0.0, w, h, "0 0 0 4 -1 roll",
  565. steps);
  566. DPSWaitContext(csb->csb.context);
  567. }
  568. XtVaSetValues(csb->csb.slider_child[0], XtNbackgroundPixmap,
  569. csb->csb.cyan_pixmap, NULL);
  570. XtVaSetValues(csb->csb.slider_child[1], XtNbackgroundPixmap,
  571. csb->csb.magenta_pixmap, NULL);
  572. XtVaSetValues(csb->csb.slider_child[2], XtNbackgroundPixmap,
  573. csb->csb.yellow_pixmap, NULL);
  574. XtVaSetValues(csb->csb.slider_child[3], XtNbackgroundPixmap,
  575. csb->csb.black_pixmap, NULL);
  576. }
  577. static void ColorizeHSB(ColorSelectionBoxWidget csb)
  578. {
  579. Dimension height, width;
  580. int depth, steps;
  581. float w, h;
  582. XtVaGetValues(csb->csb.slider_child[0], XtNwidth, &width,
  583. XtNheight, &height,
  584. XtNdepth, &depth, NULL);
  585. if (csb->csb.hue_pixmap != None && width != csb->csb.hsb_slider_width) {
  586. XFreePixmap(XtDisplay(csb), csb->csb.hue_pixmap);
  587. XFreePixmap(XtDisplay(csb), csb->csb.sat_pixmap);
  588. XFreePixmap(XtDisplay(csb), csb->csb.bright_pixmap);
  589. csb->csb.hue_pixmap = None;
  590. }
  591. if (csb->csb.hue_pixmap == None) {
  592. csb->csb.hsb_slider_width = width;
  593. if (csb->csb.visual_class == TrueColor) steps = width / 2;
  594. else steps = width / 4;
  595. ToUserSpace(csb, width, height, &w, &h);
  596. csb->csb.hue_pixmap = XCreatePixmap(XtDisplay(csb), XtWindow(csb),
  597. width, height, depth);
  598. XDPSSetContextGState(csb->csb.context, csb->csb.base_gstate);
  599. XDPSSetContextDrawable(csb->csb.context, csb->csb.hue_pixmap, height);
  600. _DPSCHSBBlend(csb->csb.context, 0.0, 0.0, w, h, "1 1", steps);
  601. csb->csb.sat_pixmap = XCreatePixmap(XtDisplay(csb), XtWindow(csb),
  602. width, height, depth);
  603. XDPSSetContextDrawable(csb->csb.context, csb->csb.sat_pixmap, height);
  604. _DPSCHSBBlend(csb->csb.context, 0.0, 0.0, w, h, "0 exch 1", steps);
  605. csb->csb.bright_pixmap = XCreatePixmap(XtDisplay(csb), XtWindow(csb),
  606. width, height, depth);
  607. XDPSSetContextDrawable(csb->csb.context, csb->csb.bright_pixmap,
  608. height);
  609. _DPSCHSBBlend(csb->csb.context, 0.0, 0.0, w, h, "0 1 3 -1 roll",
  610. steps);
  611. DPSWaitContext(csb->csb.context);
  612. }
  613. XtVaSetValues(csb->csb.slider_child[0], XtNbackgroundPixmap,
  614. csb->csb.hue_pixmap, NULL);
  615. XtVaSetValues(csb->csb.slider_child[1], XtNbackgroundPixmap,
  616. csb->csb.sat_pixmap, NULL);
  617. XtVaSetValues(csb->csb.slider_child[2], XtNbackgroundPixmap,
  618. csb->csb.bright_pixmap, NULL);
  619. }
  620. static void ColorizeGray(ColorSelectionBoxWidget csb)
  621. {
  622. Dimension height, width;
  623. int depth, steps;
  624. float w, h;
  625. XtVaGetValues(csb->csb.slider_child[0], XtNwidth, &width,
  626. XtNheight, &height,
  627. XtNdepth, &depth, NULL);
  628. if (csb->csb.gray_pixmap != None && width != csb->csb.gray_slider_width) {
  629. XFreePixmap(XtDisplay(csb), csb->csb.gray_pixmap);
  630. csb->csb.gray_pixmap = None;
  631. }
  632. if (csb->csb.gray_pixmap == None) {
  633. csb->csb.gray_slider_width = width;
  634. if (csb->csb.visual_class == TrueColor) steps = width / 2;
  635. else steps = width / 4;
  636. ToUserSpace(csb, width, height, &w, &h);
  637. csb->csb.gray_pixmap = XCreatePixmap(XtDisplay(csb), XtWindow(csb),
  638. width, height, depth);
  639. XDPSSetContextGState(csb->csb.context, csb->csb.base_gstate);
  640. XDPSSetContextDrawable(csb->csb.context, csb->csb.gray_pixmap, height);
  641. _DPSCGrayBlend(csb->csb.context, 0.0, 0.0, w, h, " ", steps);
  642. DPSWaitContext(csb->csb.context);
  643. }
  644. XtVaSetValues(csb->csb.slider_child[0], XtNbackgroundPixmap,
  645. csb->csb.gray_pixmap, NULL);
  646. }
  647. static void ColorizeSliders(ColorSelectionBoxWidget csb)
  648. {
  649. if (!XtIsRealized(csb)) return;
  650. switch (csb->csb.current_space) {
  651. case CSBSpaceRGB:
  652. ColorizeRGB(csb);
  653. break;
  654. case CSBSpaceCMYK:
  655. ColorizeCMYK(csb);
  656. break;
  657. case CSBSpaceHSB:
  658. ColorizeHSB(csb);
  659. break;
  660. case CSBSpaceGray:
  661. ColorizeGray(csb);
  662. break;
  663. }
  664. }
  665. /* ARGSUSED */
  666. static void FormResize(
  667. Widget w,
  668. XtPointer data,
  669. XEvent *event,
  670. Boolean *goOn)
  671. {
  672. ColorSelectionBoxWidget csb = (ColorSelectionBoxWidget) data;
  673. if (event->type != ConfigureNotify && event->type != MapNotify) return;
  674. csb->csb.rgb_slider_width = csb->csb.cmyk_slider_width =
  675. csb->csb.hsb_slider_width = csb->csb.gray_slider_width = 0;
  676. csb->csb.palette_pixmap_valid = False;
  677. if (csb->csb.patch_gstate != 0) {
  678. XDPSFreeContextGState(csb->csb.context, csb->csb.patch_gstate);
  679. csb->csb.patch_gstate = 0;
  680. }
  681. if (csb->csb.dock_gstate != 0) {
  682. XDPSFreeContextGState(csb->csb.context, csb->csb.dock_gstate);
  683. csb->csb.dock_gstate = 0;
  684. }
  685. ColorizeSliders(csb);
  686. DrawPalette(csb);
  687. if (XtIsRealized(csb->csb.patch_child)) {
  688. XClearArea(XtDisplay(csb), XtWindow(csb->csb.patch_child),
  689. 0, 0, 1000, 1000, True);
  690. }
  691. }
  692. static void FillCallbackRec(
  693. ColorSelectionBoxWidget csb,
  694. CSBCallbackRec *rec)
  695. {
  696. rec->current_space = csb->csb.current_space;
  697. rec->red = csb->csb.current_color.red;
  698. rec->green = csb->csb.current_color.green;
  699. rec->blue = csb->csb.current_color.blue;
  700. rec->cyan = csb->csb.current_color.cyan;
  701. rec->magenta = csb->csb.current_color.magenta;
  702. rec->yellow = csb->csb.current_color.yellow;
  703. rec->black = csb->csb.current_color.black;
  704. rec->hue = csb->csb.current_color.hue;
  705. rec->saturation = csb->csb.current_color.saturation;
  706. rec->brightness = csb->csb.current_color.brightness;
  707. rec->gray = csb->csb.current_color.gray;
  708. }
  709. /* ARGSUSED */
  710. static void OKCallback(
  711. Widget w,
  712. XtPointer clientData, XtPointer callData)
  713. {
  714. ColorSelectionBoxWidget csb = (ColorSelectionBoxWidget) clientData;
  715. CSBCallbackRec rec;
  716. csb->csb.save_color = csb->csb.current_color;
  717. FillCallbackRec(csb, &rec);
  718. rec.reason = CSBOK;
  719. XtCallCallbackList((Widget) csb, csb->csb.ok_callback, (XtPointer) &rec);
  720. if (XtIsShell(XtParent(csb))) XtPopdown(XtParent(csb));
  721. SaveDockContents(csb);
  722. }
  723. /* ARGSUSED */
  724. static void ApplyCallback(
  725. Widget w,
  726. XtPointer clientData, XtPointer callData)
  727. {
  728. ColorSelectionBoxWidget csb = (ColorSelectionBoxWidget) clientData;
  729. CSBCallbackRec rec;
  730. csb->csb.save_color = csb->csb.current_color;
  731. FillCallbackRec(csb, &rec);
  732. rec.reason = CSBApply;
  733. XtCallCallbackList((Widget) csb, csb->csb.apply_callback,
  734. (XtPointer) &rec);
  735. SaveDockContents(csb);
  736. }
  737. /* ARGSUSED */
  738. static void ResetCallback(
  739. Widget w,
  740. XtPointer clientData, XtPointer callData)
  741. {
  742. ColorSelectionBoxWidget csb = (ColorSelectionBoxWidget) clientData;
  743. CSBCallbackRec rec;
  744. csb->csb.current_color = csb->csb.save_color;
  745. FillPatch(csb);
  746. SetSliders(csb);
  747. FillCallbackRec(csb, &rec);
  748. rec.reason = CSBReset;
  749. XtCallCallbackList((Widget) csb, csb->csb.reset_callback,
  750. (XtPointer) &rec);
  751. }
  752. /* ARGSUSED */
  753. static void CancelCallback(
  754. Widget w,
  755. XtPointer clientData, XtPointer callData)
  756. {
  757. ColorSelectionBoxWidget csb = (ColorSelectionBoxWidget) clientData;
  758. CSBCallbackRec rec;
  759. csb->csb.current_color = csb->csb.save_color;
  760. FillPatch(csb);
  761. SetSliders(csb);
  762. FillCallbackRec(csb, &rec);
  763. rec.reason = CSBCancel;
  764. XtCallCallbackList((Widget) csb, csb->csb.cancel_callback,
  765. (XtPointer) &rec);
  766. if (XtIsShell(XtParent(csb))) XtPopdown(XtParent(csb));
  767. }
  768. /* ARGSUSED */
  769. static void DoValueChangedCallback(ColorSelectionBoxWidget csb)
  770. {
  771. CSBCallbackRec rec;
  772. FillCallbackRec(csb, &rec);
  773. rec.reason = CSBValueChanged;
  774. XtCallCallbackList((Widget) csb, csb->csb.value_changed_callback,
  775. (XtPointer) &rec);
  776. }
  777. /* ARGSUSED */
  778. static void ChangeLabelCallback(
  779. Widget w,
  780. XtPointer clientData, XtPointer callData)
  781. {
  782. XmScaleCallbackStruct *scaleData = (XmScaleCallbackStruct *) callData;
  783. ChangeLabel((Widget) clientData, ((float) scaleData->value) / 100.0);
  784. }
  785. static void ChangeLabel(Widget label, double n)
  786. {
  787. char buf[10];
  788. sprintf(buf, "%d", TO_PCT(n));
  789. XtVaSetValues(label, XmNlabelString, CS(buf, label), NULL);
  790. }
  791. static void CreateModelMenu(Widget parent, Widget csb)
  792. {
  793. Widget kids[4];
  794. kids[0] = XmCreatePushButtonGadget(parent, "rgb", (ArgList) NULL, 0);
  795. XtAddCallback(kids[0], XmNactivateCallback,
  796. SetRGBCallback, (XtPointer) csb);
  797. kids[1] = XmCreatePushButtonGadget(parent, "cmyk", (ArgList) NULL, 0);
  798. XtAddCallback(kids[1], XmNactivateCallback,
  799. SetCMYKCallback, (XtPointer) csb);
  800. kids[2] = XmCreatePushButtonGadget(parent, "hsb", (ArgList) NULL, 0);
  801. XtAddCallback(kids[2], XmNactivateCallback,
  802. SetHSBCallback, (XtPointer) csb);
  803. kids[3] = XmCreatePushButtonGadget(parent, "gray", (ArgList) NULL, 0);
  804. XtAddCallback(kids[3], XmNactivateCallback,
  805. SetGrayCallback, (XtPointer) csb);
  806. XtManageChildren(kids, 4);
  807. }
  808. typedef struct {
  809. ColorSelectionBoxWidget csb;
  810. CSBRenderingType rendering;
  811. } RenderingRec;
  812. /* ARGSUSED */
  813. static void SetRenderingCallback(
  814. Widget w,
  815. XtPointer clientData, XtPointer callData)
  816. {
  817. RenderingRec *r = (RenderingRec *) clientData;
  818. r->csb->csb.current_rendering = r->rendering;
  819. FillPatch(r->csb);
  820. }
  821. static void CreateDisplayMenu(Widget parent, ColorSelectionBoxWidget csb)
  822. {
  823. Widget kids[3];
  824. RenderingRec *r;
  825. r = XtNew(RenderingRec);
  826. r->csb = csb;
  827. r->rendering = CSBDisplayDPS;
  828. kids[0] = XmCreatePushButtonGadget(parent, "displayDPS",
  829. (ArgList) NULL, 0);
  830. XtAddCallback(kids[0], XmNactivateCallback,
  831. SetRenderingCallback, (XtPointer) r);
  832. r = XtNew(RenderingRec);
  833. r->csb = csb;
  834. r->rendering = CSBDisplayX;
  835. kids[1] = XmCreatePushButtonGadget(parent, "displayX", (ArgList) NULL, 0);
  836. XtAddCallback(kids[1], XmNactivateCallback,
  837. SetRenderingCallback, (XtPointer) r);
  838. r = XtNew(RenderingRec);
  839. r->csb = csb;
  840. r->rendering = CSBDisplayBoth;
  841. kids[2] = XmCreatePushButtonGadget(parent, "displayBoth",
  842. (ArgList) NULL, 0);
  843. XtAddCallback(kids[2], XmNactivateCallback,
  844. SetRenderingCallback, (XtPointer) r);
  845. XtManageChildren(kids, 3);
  846. }
  847. typedef struct {
  848. ColorSelectionBoxWidget csb;
  849. int n;
  850. } PaletteRec;
  851. /* ARGSUSED */
  852. static void SetPaletteCallback(
  853. Widget w,
  854. XtPointer clientData, XtPointer callData)
  855. {
  856. PaletteRec *p = (PaletteRec *) clientData;
  857. if (p->csb->csb.palette_broken[p->n]) return;
  858. if (p->n != p->csb->csb.current_palette ||
  859. p->csb->csb.palette_color_dependent[p->n]) {
  860. p->csb->csb.palette_pixmap_valid = False;
  861. }
  862. p->csb->csb.current_palette = p->n;
  863. DrawPalette(p->csb);
  864. }
  865. static void CreatePaletteMenu(Widget parent, ColorSelectionBoxWidget csb)
  866. {
  867. Widget w, managed[PALETTE_MAX];
  868. int j, k;
  869. char buf[10];
  870. PaletteRec *p;
  871. j = 0;
  872. for (k = 0; k < PALETTE_MAX; k++) {
  873. p = XtNew(PaletteRec);
  874. p->csb = csb;
  875. p->n = k;
  876. sprintf(buf, "palette%d", k);
  877. w = XtVaCreateWidget(buf, xmPushButtonGadgetClass, parent, NULL);
  878. if (csb->csb.palette_label[k] != NULL) {
  879. XtVaSetValues(w, XtVaTypedArg, XmNlabelString,
  880. XtRString, csb->csb.palette_label[k],
  881. strlen(csb->csb.palette_label[k])+1,
  882. NULL);
  883. }
  884. XtAddCallback(w, XmNactivateCallback,
  885. SetPaletteCallback, (XtPointer) p);
  886. if (csb->csb.palette_function[k] != NULL) managed[j++] = w;
  887. }
  888. if (j != 0) XtManageChildren(managed, j);
  889. }
  890. static void CreateChildren(ColorSelectionBoxWidget csb)
  891. {
  892. int i;
  893. Arg args[20];
  894. Widget form, menu, button, w, dock_frame, palette_frame;
  895. Pixel fg, bg;
  896. int depth;
  897. Pixmap eyedrop;
  898. i = 0;
  899. XtSetArg(args[i], XmNresizePolicy, XmRESIZE_NONE); i++;
  900. form = XtCreateManagedWidget("panel", xmFormWidgetClass,
  901. (Widget) csb, args, i);
  902. csb->csb.form_child = form;
  903. XtAddEventHandler(form, StructureNotifyMask, False, FormResize,
  904. (XtPointer) csb);
  905. i = 0;
  906. menu = XmCreatePulldownMenu(form, "modelMenu", args, i);
  907. CreateModelMenu(menu, (Widget) csb);
  908. i = 0;
  909. XtSetArg(args[i], XmNleftAttachment, XmATTACH_FORM); i++;
  910. XtSetArg(args[i], XmNtopAttachment, XmATTACH_FORM); i++;
  911. XtSetArg(args[i], XmNsubMenuId, menu); i++;
  912. csb->csb.model_option_menu_child =
  913. XmCreateOptionMenu(form, "modelOptionMenu",
  914. args, i);
  915. XtManageChild(csb->csb.model_option_menu_child);
  916. XtVaGetValues(form, XtNbackground, &bg, XmNforeground, &fg,
  917. XtNdepth, &depth, NULL);
  918. eyedrop = XCreatePixmapFromBitmapData(XtDisplay(csb),
  919. RootWindowOfScreen(XtScreen(csb)),
  920. (char *) heyedrop_bits,
  921. heyedrop_width, heyedrop_height,
  922. fg, bg, depth);
  923. i = 0;
  924. XtSetArg(args[i], XmNleftAttachment, XmATTACH_WIDGET); i++;
  925. XtSetArg(args[i], XmNleftWidget, csb->csb.model_option_menu_child); i++;
  926. XtSetArg(args[i], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); i++;
  927. XtSetArg(args[i], XmNtopWidget, csb->csb.model_option_menu_child); i++;
  928. XtSetArg(args[i], XmNlabelPixmap, eyedrop); i++;
  929. button = XtCreateManagedWidget("eyedropButton", xmPushButtonWidgetClass,
  930. form, args, i);
  931. XtAddCallback(button, XmNactivateCallback,
  932. DoEyedropCallback, (XtPointer) csb);
  933. XtInsertRawEventHandler(button, PointerMotionMask | ButtonReleaseMask,
  934. False, EyedropPointer, (XtPointer) csb,
  935. XtListHead);
  936. i = 0;
  937. XtSetArg(args[i], XmNleftAttachment, XmATTACH_FORM); i++;
  938. XtSetArg(args[i], XmNtopAttachment, XmATTACH_WIDGET); i++;
  939. XtSetArg(args[i], XmNtopWidget, csb->csb.model_option_menu_child); i++;
  940. csb->csb.label_child[0] =
  941. XtCreateManagedWidget("label1", xmLabelWidgetClass, form, args, i);
  942. i = 0;
  943. XtSetArg(args[i], XmNtopAttachment, XmATTACH_WIDGET); i++;
  944. XtSetArg(args[i], XmNtopWidget, csb->csb.model_option_menu_child); i++;
  945. XtSetArg(args[i], XmNrightAttachment, XmATTACH_POSITION); i++;
  946. csb->csb.value_child[0] =
  947. XtCreateManagedWidget("value1", xmLabelWidgetClass, form, args, i);
  948. i = 0;
  949. XtSetArg(args[i], XmNleftAttachment, XmATTACH_WIDGET); i++;
  950. XtSetArg(args[i], XmNleftWidget, csb->csb.label_child[0]); i++;
  951. XtSetArg(args[i], XmNtopAttachment, XmATTACH_WIDGET); i++;
  952. XtSetArg(args[i], XmNtopWidget, csb->csb.model_option_menu_child); i++;
  953. XtSetArg(args[i], XmNrightAttachment, XmATTACH_WIDGET); i++;
  954. XtSetArg(args[i], XmNrightWidget, csb->csb.value_child[0]); i++;
  955. csb->csb.slider_child[0] =
  956. XtCreateManagedWidget("slider1", xmScaleWidgetClass,
  957. form, args, i);
  958. XtAddCallback(csb->csb.slider_child[0], XmNvalueChangedCallback,
  959. ChangeLabelCallback, (XtPointer) csb->csb.value_child[0]);
  960. XtAddCallback(csb->csb.slider_child[0], XmNdragCallback,
  961. ChangeLabelCallback, (XtPointer) csb->csb.value_child[0]);
  962. XtAddCallback(csb->csb.slider_child[0], XmNvalueChangedCallback,
  963. Slider1Callback, (XtPointer) csb);
  964. XtAddCallback(csb->csb.slider_child[0], XmNdragCallback,
  965. Slider1Callback, (XtPointer) csb);
  966. i = 0;
  967. XtSetArg(args[i], XmNleftAttachment, XmATTACH_FORM); i++;
  968. XtSetArg(args[i], XmNtopAttachment, XmATTACH_WIDGET); i++;
  969. XtSetArg(args[i], XmNtopWidget, csb->csb.slider_child[0]); i++;
  970. csb->csb.label_child[1] =
  971. XtCreateManagedWidget("label2", xmLabelWidgetClass, form, args, i);
  972. i = 0;
  973. XtSetArg(args[i], XmNtopAttachment, XmATTACH_WIDGET); i++;
  974. XtSetArg(args[i], XmNtopWidget, csb->csb.slider_child[0]); i++;
  975. XtSetArg(args[i], XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET); i++;
  976. XtSetArg(args[i], XmNrightWidget, csb->csb.value_child[0]); i++;
  977. csb->csb.value_child[1] =
  978. XtCreateManagedWidget("value2", xmLabelWidgetClass, form, args, i);
  979. i = 0;
  980. XtSetArg(args[i], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET); i++;
  981. XtSetArg(args[i], XmNleftWidget, csb->csb.slider_child[0]); i++;
  982. XtSetArg(args[i], XmNtopAttachment, XmATTACH_WIDGET); i++;
  983. XtSetArg(args[i], XmNtopWidget, csb->csb.slider_child[0]); i++;
  984. XtSetArg(args[i], XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET); i++;
  985. XtSetArg(args[i], XmNrightWidget, csb->csb.slider_child[0]); i++;
  986. csb->csb.slider_child[1] =
  987. XtCreateManagedWidget("slider2", xmScaleWidgetClass,
  988. form, args, i);
  989. XtAddCallback(csb->csb.slider_child[1], XmNvalueChangedCallback,
  990. ChangeLabelCallback, (XtPointer) csb->csb.value_child[1]);
  991. XtAddCallback(csb->csb.slider_child[1], XmNdragCallback,
  992. ChangeLabelCallback, (XtPointer) csb->csb.value_child[1]);
  993. XtAddCallback(csb->csb.slider_child[1], XmNvalueChangedCallback,
  994. Slider2Callback, (XtPointer) csb);
  995. XtAddCallback(csb->csb.slider_child[1], XmNdragCallback,
  996. Slider2Callback, (XtPointer) csb);
  997. i = 0;
  998. XtSetArg(args[i], XmNleftAttachment, XmATTACH_FORM); i++;
  999. XtSetArg(args[i], XmNtopAttachment, XmATTACH_WIDGET); i++;
  1000. XtSetArg(args[i], XmNtopWidget, csb->csb.slider_child[1]); i++;
  1001. csb->csb.label_child[2] =
  1002. XtCreateManagedWidget("label3", xmLabelWidgetClass, form, args, i);
  1003. i = 0;
  1004. XtSetArg(args[i], XmNtopAttachment, XmATTACH_WIDGET); i++;
  1005. XtSetArg(args[i], XmNtopWidget, csb->csb.slider_child[1]); i++;
  1006. XtSetArg(args[i], XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET); i++;
  1007. XtSetArg(args[i], XmNrightWidget, csb->csb.value_child[0]); i++;
  1008. csb->csb.value_child[2] =
  1009. XtCreateManagedWidget("value3", xmLabelWidgetClass, form, args, i);
  1010. i = 0;
  1011. XtSetArg(args[i], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET); i++;
  1012. XtSetArg(args[i], XmNleftWidget, csb->csb.slider_child[0]); i++;
  1013. XtSetArg(args[i], XmNtopAttachment, XmATTACH_WIDGET); i++;
  1014. XtSetArg(args[i], XmNtopWidget, csb->csb.slider_child[1]); i++;
  1015. XtSetArg(args[i], XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET); i++;
  1016. XtSetArg(args[i], XmNrightWidget, csb->csb.slider_child[0]); i++;
  1017. csb->csb.slider_child[2] =
  1018. XtCreateManagedWidget("slider3", xmScaleWidgetClass,
  1019. form, args, i);
  1020. XtAddCallback(csb->csb.slider_child[2], XmNvalueChangedCallback,
  1021. ChangeLabelCallback, (XtPointer) csb->csb.value_child[2]);
  1022. XtAddCallback(csb->csb.slider_child[2], XmNdragCallback,
  1023. ChangeLabelCallback, (XtPointer) csb->csb.value_child[2]);
  1024. XtAddCallback(csb->csb.slider_child[2], XmNvalueChangedCallback,
  1025. Slider3Callback, (XtPointer) csb);
  1026. XtAddCallback(csb->csb.slider_child[2], XmNdragCallback,
  1027. Slider3Callback, (XtPointer) csb);
  1028. i = 0;
  1029. XtSetArg(args[i], XmNleftAttachment, XmATTACH_FORM); i++;
  1030. XtSetArg(args[i], XmNtopAttachment, XmATTACH_WIDGET); i++;
  1031. XtSetArg(args[i], XmNtopWidget, csb->csb.slider_child[2]); i++;
  1032. csb->csb.label_child[3] =
  1033. XtCreateManagedWidget("label4", xmLabelWidgetClass, form, args, i);
  1034. i = 0;
  1035. XtSetArg(args[i], XmNtopAttachment, XmATTACH_WIDGET); i++;
  1036. XtSetArg(args[i], XmNtopWidget, csb->csb.slider_child[2]); i++;
  1037. XtSetArg(args[i], XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET); i++;
  1038. XtSetArg(args[i], XmNrightWidget, csb->csb.value_child[0]); i++;
  1039. csb->csb.value_child[3] =
  1040. XtCreateManagedWidget("value4", xmLabelWidgetClass, form, args, i);
  1041. i = 0;
  1042. XtSetArg(args[i], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET); i++;
  1043. XtSetArg(args[i], XmNleftWidget, csb->csb.slider_child[0]); i++;
  1044. XtSetArg(args[i], XmNtopAttachment, XmATTACH_WIDGET); i++;
  1045. XtSetArg(args[i], XmNtopWidget, csb->csb.slider_child[2]); i++;
  1046. XtSetArg(args[i], XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET); i++;
  1047. XtSetArg(args[i], XmNrightWidget, csb->csb.slider_child[0]); i++;
  1048. csb->csb.slider_child[3] =
  1049. XtCreateManagedWidget("slider4", xmScaleWidgetClass,
  1050. form, args, i);
  1051. XtAddCallback(csb->csb.slider_child[3], XmNvalueChangedCallback,
  1052. ChangeLabelCallback, (XtPointer) csb->csb.value_child[3]);
  1053. XtAddCallback(csb->csb.slider_child[3], XmNdragCallback,
  1054. ChangeLabelCallback, (XtPointer) csb->csb.value_child[3]);
  1055. XtAddCallback(csb->csb.slider_child[3], XmNvalueChangedCallback,
  1056. Slider4Callback, (XtPointer) csb);
  1057. XtAddCallback(csb->csb.slider_child[3], XmNdragCallback,
  1058. Slider4Callback, (XtPointer) csb);
  1059. i = 0;
  1060. XtSetArg(args[i], XmNleftAttachment, XmATTACH_FORM); i++;
  1061. XtSetArg(args[i], XmNbottomAttachment, XmATTACH_FORM); i++;
  1062. button = XtCreateManagedWidget("okButton", xmPushButtonWidgetClass,
  1063. form, args, i);
  1064. XtAddCallback(button, XmNactivateCallback, OKCallback, (XtPointer) csb);
  1065. i = 0;
  1066. XtSetArg(args[i], XmNdefaultButton, button); i++;
  1067. XtSetValues(form, args, i);
  1068. i = 0;
  1069. XtSetArg(args[i], XmNleftAttachment, XmATTACH_WIDGET); i++;
  1070. XtSetArg(args[i], XmNleftWidget, button); i++;
  1071. XtSetArg(args[i], XmNbottomAttachment, XmATTACH_FORM); i++;
  1072. button = XtCreateManagedWidget("applyButton", xmPushButtonWidgetClass,
  1073. form, args, i);
  1074. XtAddCallback(button, XmNactivateCallback, ApplyCallback, (XtPointer) csb);
  1075. i = 0;
  1076. XtSetArg(args[i], XmNleftAttachment, XmATTACH_WIDGET); i++;
  1077. XtSetArg(args[i], XmNleftWidget, button); i++;
  1078. XtSetArg(args[i], XmNbottomAttachment, XmATTACH_FORM); i++;
  1079. button = XtCreateManagedWidget("resetButton", xmPushButtonWidgetClass,
  1080. form, args, i);
  1081. XtAddCallback(button, XmNactivateCallback, ResetCallback, (XtPointer) csb);
  1082. i = 0;
  1083. XtSetArg(args[i], XmNleftAttachment, XmATTACH_WIDGET); i++;
  1084. XtSetArg(args[i], XmNleftWidget, button); i++;
  1085. XtSetArg(args[i], XmNbottomAttachment, XmATTACH_FORM); i++;
  1086. button = XtCreateManagedWidget("cancelButton", xmPushButtonWidgetClass,
  1087. form, args, i);
  1088. XtAddCallback(button, XmNactivateCallback,
  1089. CancelCallback, (XtPointer) csb);
  1090. i = 0;
  1091. XtSetArg(args[i], XmNleftAttachment, XmATTACH_FORM); i++;
  1092. XtSetArg(args[i], XmNrightAttachment, XmATTACH_FORM); i++;
  1093. XtSetArg(args[i], XmNbottomAttachment, XmATTACH_WIDGET); i++;
  1094. XtSetArg(args[i], XmNbottomWidget, button); i++;
  1095. w = XtCreateManagedWidget("separator", xmSeparatorGadgetClass,
  1096. form, args, i);
  1097. i = 0;
  1098. XtSetArg(args[i], XmNleftAttachment, XmATTACH_FORM); i++;
  1099. XtSetArg(args[i], XmNrightAttachment, XmATTACH_FORM); i++;
  1100. XtSetArg(args[i], XmNbottomAttachment, XmATTACH_WIDGET); i++;
  1101. XtSetArg(args[i], XmNbottomWidget, w); i++;
  1102. palette_frame = XtCreateManagedWidget("paletteFrame", xmFrameWidgetClass,
  1103. form, args, i);
  1104. i = 0;
  1105. csb->csb.palette_child =
  1106. XtCreateManagedWidget("palette", xmDrawingAreaWidgetClass,
  1107. palette_frame, args, i);
  1108. XtAddCallback(csb->csb.palette_child, XmNexposeCallback,
  1109. DrawPaletteCallback, (XtPointer) csb);
  1110. XtAddEventHandler(csb->csb.palette_child, ButtonPressMask, False,
  1111. PalettePress, (XtPointer) csb);
  1112. i = 0;
  1113. menu = XmCreatePulldownMenu(form, "paletteMenu", args, i);
  1114. CreatePaletteMenu(menu, csb);
  1115. i = 0;
  1116. XtSetArg(args[i], XmNleftAttachment, XmATTACH_FORM); i++;
  1117. XtSetArg(args[i], XmNbottomAttachment, XmATTACH_WIDGET); i++;
  1118. XtSetArg(args[i], XmNbottomWidget, palette_frame); i++;
  1119. XtSetArg(args[i], XmNsubMenuId, menu); i++;
  1120. csb->csb.palette_option_menu_child =
  1121. XmCreateOptionMenu(form, "paletteOptionMenu",
  1122. args, i);
  1123. XtManageChild(csb->csb.palette_option_menu_child);
  1124. i = 0;
  1125. menu = XmCreatePulldownMenu(form, "displayMenu", args, i);
  1126. CreateDisplayMenu(menu, csb);
  1127. i = 0;
  1128. XtSetArg(args[i], XmNleftAttachment, XmATTACH_POSITION); i++;
  1129. XtSetArg(args[i], XmNrightAttachment, XmATTACH_FORM); i++;
  1130. XtSetArg(args[i], XmNtopAttachment, XmATTACH_FORM); i++;
  1131. XtSetArg(args[i], XmNsubMenuId, menu); i++;
  1132. csb->csb.display_option_menu_child =
  1133. XmCreateOptionMenu(form, "displayOptionMenu",
  1134. args, i);
  1135. XtManageChild(csb->csb.display_option_menu_child);
  1136. i = 0;
  1137. XtSetArg(args[i], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET); i++;
  1138. XtSetArg(args[i], XmNleftWidget, csb->csb.display_option_menu_child);i++;
  1139. XtSetArg(args[i], XmNrightAttachment, XmATTACH_FORM); i++;
  1140. XtSetArg(args[i], XmNbottomAttachment, XmATTACH_WIDGET); i++;
  1141. XtSetArg(args[i], XmNbottomWidget, palette_frame); i++;
  1142. dock_frame = XtCreateManagedWidget("dockFrame", xmFrameWidgetClass,
  1143. form, args, i);
  1144. i = 0;
  1145. csb->csb.dock_child =
  1146. XtCreateManagedWidget("dock", xmDrawingAreaWidgetClass,
  1147. dock_frame, args, i);
  1148. XtAddCallback(csb->csb.dock_child, XmNexposeCallback,
  1149. DrawDockCallback, (XtPointer) csb);
  1150. XtAddEventHandler(csb->csb.dock_child, ButtonPressMask, False, DockPress,
  1151. (XtPointer) csb);
  1152. {
  1153. Dimension height;
  1154. int q;
  1155. XtVaGetValues(csb->csb.dock_child, XtNheight, &height, NULL);
  1156. if (height < csb->csb.cell_size) height = csb->csb.cell_size;
  1157. else if (height % csb->csb.cell_size != 0) {
  1158. q = height / csb->csb.cell_size;
  1159. height = csb->csb.cell_size * q;
  1160. }
  1161. XtVaSetValues(csb->csb.dock_child, XtNheight, height, NULL);
  1162. }
  1163. i = 0;
  1164. XtSetArg(args[i], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET); i++;
  1165. XtSetArg(args[i], XmNleftWidget, dock_frame); i++;
  1166. XtSetArg(args[i], XmNrightAttachment, XmATTACH_FORM); i++;
  1167. XtSetArg(args[i], XmNtopAttachment, XmATTACH_WIDGET); i++;
  1168. XtSetArg(args[i], XmNtopWidget, csb->csb.display_option_menu_child);i++;
  1169. XtSetArg(args[i], XmNbottomAttachment, XmATTACH_WIDGET); i++;
  1170. XtSetArg(args[i], XmNbottomWidget, dock_frame); i++;
  1171. w = XtCreateManagedWidget("patchFrame", xmFrameWidgetClass,
  1172. form, args, i);
  1173. i = 0;
  1174. csb->csb.patch_child =
  1175. XtCreateManagedWidget("patch", xmDrawingAreaWidgetClass,
  1176. w, args, i);
  1177. XtAddCallback(csb->csb.patch_child, XmNexposeCallback,
  1178. FillPatchCallback, (XtPointer) csb);
  1179. XtAddRawEventHandler(csb->csb.patch_child, ButtonPressMask,
  1180. False, PatchPress, (XtPointer) csb);
  1181. XtAddRawEventHandler(csb->csb.patch_child, ButtonReleaseMask,
  1182. False, PatchRelease, (XtPointer) csb);
  1183. }
  1184. static void NoBackgroundPixel(ColorSelectionBoxWidget csb)
  1185. {
  1186. Widget w, message;
  1187. csb->csb.no_background = True;
  1188. w = XtNameToWidget((Widget) csb, "*displayX");
  1189. XtSetSensitive(w, False);
  1190. w = XtNameToWidget((Widget) csb, "*displayBoth");
  1191. XtSetSensitive(w, False);
  1192. w = XtNameToWidget((Widget) csb, "*displayDPS");
  1193. XtVaSetValues(csb->csb.display_option_menu_child, XmNmenuHistory, w, NULL);
  1194. message = XmCreateInformationDialog(csb->csb.form_child,
  1195. "noBackgroundMessage",
  1196. (ArgList) NULL, 0);
  1197. w = XmMessageBoxGetChild(message, XmDIALOG_CANCEL_BUTTON);
  1198. XtUnmanageChild(w);
  1199. w = XmMessageBoxGetChild(message, XmDIALOG_HELP_BUTTON);
  1200. XtUnmanageChild(w);
  1201. XtManageChild(message);
  1202. }
  1203. /* labelString is changed by this */
  1204. static void ParseLabels(String labelString, String labels[4], int n)
  1205. {
  1206. register char *ch;
  1207. int i;
  1208. ch = labelString;
  1209. for (i = 0; i < n; i++) {
  1210. labels[i] = ch;
  1211. while (*ch != ':' && *ch != '\0') ch++;
  1212. *ch++ = '\0';
  1213. }
  1214. for (i = n; i < 4; i++) labels[i] = NULL;
  1215. }
  1216. static void SetLabels(ColorSelectionBoxWidget csb, String *labels)
  1217. {
  1218. Widget w = (Widget) csb;
  1219. int i;
  1220. for (i = 0; i < 4; i++) {
  1221. if (labels[i] != NULL) {
  1222. XtVaSetValues(csb->csb.label_child[i],
  1223. XmNlabelString, CS(labels[i], w), NULL);
  1224. }
  1225. }
  1226. }
  1227. static void MapChildren(Widget *children, int n)
  1228. {
  1229. XtManageChildren(children, n);
  1230. }
  1231. static void UnmapChildren(Widget *children, int n)
  1232. {
  1233. XtUnmanageChildren(children, n);
  1234. }
  1235. static void SetSliders(ColorSelectionBoxWidget csb)
  1236. {
  1237. switch(csb->csb.current_space) {
  1238. case CSBSpaceRGB: SetRGBValues(csb); break;
  1239. case CSBSpaceCMYK: SetCMYKValues(csb); break;
  1240. case CSBSpaceHSB: SetHSBValues(csb); break;
  1241. case CSBSpaceGray: SetGrayValues(csb); break;
  1242. }
  1243. }
  1244. static void SetRGBValues(ColorSelectionBoxWidget csb)
  1245. {
  1246. XmScaleSetValue(csb->csb.slider_child[0],
  1247. TO_PCT(csb->csb.current_color.red));
  1248. XmScaleSetValue(csb->csb.slider_child[1],
  1249. TO_PCT(csb->csb.current_color.green));
  1250. XmScaleSetValue(csb->csb.slider_child[2],
  1251. TO_PCT(csb->csb.current_color.blue));
  1252. ChangeLabel(csb->csb.value_child[0], csb->csb.current_color.red);
  1253. ChangeLabel(csb->csb.value_child[1], csb->csb.current_color.green);
  1254. ChangeLabel(csb->csb.value_child[2], csb->csb.current_color.blue);
  1255. }
  1256. /* ARGSUSED */
  1257. static void SetRGBCallback(
  1258. Widget w,
  1259. XtPointer clientData, XtPointer callData)
  1260. {
  1261. ColorSelectionBoxWidget csb = (ColorSelectionBoxWidget) clientData;
  1262. Widget rgb;
  1263. Widget children[6];
  1264. String labels[4];
  1265. int i, j;
  1266. csb->csb.current_space = CSBSpaceRGB;
  1267. ParseLabels(csb->csb.rgb_labels, labels, 3);
  1268. rgb = XtNameToWidget((Widget) csb, "*rgb");
  1269. XtVaSetValues(csb->csb.model_option_menu_child, XmNmenuHistory, rgb, NULL);
  1270. SetLabels(csb, labels);
  1271. SetRGBValues(csb);
  1272. j = 0;
  1273. for (i = 1; i < 3; i++) {
  1274. children[j++] = csb->csb.label_child[i];
  1275. children[j++] = csb->csb.slider_child[i];
  1276. children[j++] = csb->csb.value_child[i];
  1277. }
  1278. MapChildren(children, 6);
  1279. children[0] = csb->csb.label_child[3];
  1280. children[1] = csb->csb.slider_child[3];
  1281. children[2] = csb->csb.value_child[3];
  1282. UnmapChildren(children, 3);
  1283. ColorizeSliders(csb);
  1284. FillPatch(csb);
  1285. }
  1286. static void SetCMYKValues(ColorSelectionBoxWidget csb)
  1287. {
  1288. XmScaleSetValue(csb->csb.slider_child[0],
  1289. TO_PCT(csb->csb.current_color.cyan));
  1290. XmScaleSetValue(csb->csb.slider_child[1],
  1291. TO_PCT(csb->csb.current_color.magenta));
  1292. XmScaleSetValue(csb->csb.slider_child[2],
  1293. TO_PCT(csb->csb.current_color.yellow));
  1294. XmScaleSetValue(csb->csb.slider_child[3],
  1295. TO_PCT(csb->csb.current_color.black));
  1296. ChangeLabel(csb->csb.value_child[0], csb->csb.current_color.cyan);
  1297. ChangeLabel(csb->csb.value_child[1], csb->csb.current_color.magenta);
  1298. ChangeLabel(csb->csb.value_child[2], csb->csb.current_color.yellow);
  1299. ChangeLabel(csb->csb.value_child[3], csb->csb.current_color.black);
  1300. }
  1301. /* ARGSUSED */
  1302. static void SetCMYKCallback(
  1303. Widget w,
  1304. XtPointer clientData, XtPointer callData)
  1305. {
  1306. ColorSelectionBoxWidget csb = (ColorSelectionBoxWidget) clientData;
  1307. Widget cmyk;
  1308. Widget children[9];
  1309. String labels[4];
  1310. int i, j;
  1311. csb->csb.current_space = CSBSpaceCMYK;
  1312. ParseLabels(csb->csb.cmyk_labels, labels, 4);
  1313. cmyk = XtNameToWidget((Widget) csb, "*cmyk");
  1314. XtVaSetValues(csb->csb.model_option_menu_child,
  1315. XmNmenuHistory, cmyk, NULL);
  1316. SetLabels(csb, labels);
  1317. SetCMYKValues(csb);
  1318. j = 0;
  1319. for (i = 1; i < 4; i++) {
  1320. children[j++] = csb->csb.label_child[i];
  1321. children[j++] = csb->csb.slider_child[i];
  1322. children[j++] = csb->csb.value_child[i];
  1323. }
  1324. MapChildren(children, 9);
  1325. ColorizeSliders(csb);
  1326. FillPatch(csb);
  1327. }
  1328. static void SetHSBValues(ColorSelectionBoxWidget csb)
  1329. {
  1330. XmScaleSetValue(csb->csb.slider_child[0],
  1331. TO_PCT(csb->csb.current_color.hue));
  1332. XmScaleSetValue(csb->csb.slider_child[1],
  1333. TO_PCT(csb->csb.current_color.saturation));
  1334. XmScaleSetValue(csb->csb.slider_child[2],
  1335. TO_PCT(csb->csb.current_color.brightness));
  1336. ChangeLabel(csb->csb.value_child[0], csb->csb.current_color.hue);
  1337. ChangeLabel(csb->csb.value_child[1], csb->csb.current_color.saturation);
  1338. ChangeLabel(csb->csb.value_child[2], csb->csb.current_color.brightness);
  1339. }
  1340. /* ARGSUSED */
  1341. static void SetHSBCallback(
  1342. Widget w,
  1343. XtPointer clientData, XtPointer callData)
  1344. {
  1345. ColorSelectionBoxWidget csb = (ColorSelectionBoxWidget) clientData;
  1346. Widget hsb;
  1347. Widget children[6];
  1348. String labels[4];
  1349. int i, j;
  1350. csb->csb.current_space = CSBSpaceHSB;
  1351. ParseLabels(csb->csb.hsb_labels, labels, 3);
  1352. hsb = XtNameToWidget((Widget) csb, "*hsb");
  1353. XtVaSetValues(csb->csb.model_option_menu_child, XmNmenuHistory, hsb, NULL);
  1354. SetLabels(csb, labels);
  1355. SetHSBValues(csb);
  1356. j = 0;
  1357. for (i = 1; i < 3; i++) {
  1358. children[j++] = csb->csb.label_child[i];
  1359. children[j++] = csb->csb.slider_child[i];
  1360. children[j++] = csb->csb.value_child[i];
  1361. }
  1362. MapChildren(children, 6);
  1363. children[0] = csb->csb.label_child[3];
  1364. children[1] = csb->csb.slider_child[3];
  1365. children[2] = csb->csb.value_child[3];
  1366. UnmapChildren(children, 3);
  1367. ColorizeSliders(csb);
  1368. FillPatch(csb);
  1369. }
  1370. static void SetGrayValues(ColorSelectionBoxWidget csb)
  1371. {
  1372. XmScaleSetValue(csb->csb.slider_child[0],
  1373. TO_PCT(csb->csb.current_color.gray));
  1374. ChangeLabel(csb->csb.value_child[0], csb->csb.current_color.gray);
  1375. }
  1376. /* ARGSUSED */
  1377. static void SetGrayCallback(
  1378. Widget w,
  1379. XtPointer clientData, XtPointer callData)
  1380. {
  1381. ColorSelectionBoxWidget csb = (ColorSelectionBoxWidget) clientData;
  1382. Widget gray;
  1383. Widget children[9];
  1384. String labels[4];
  1385. int i, j;
  1386. csb->csb.current_space = CSBSpaceGray;
  1387. gray = XtNameToWidget((Widget) csb, "*gray");
  1388. XtVaSetValues(csb->csb.model_option_menu_child, XmNmenuHistory, gray, NULL);
  1389. labels[0] = csb->csb.gray_labels;
  1390. labels[1] = labels[2] = labels[3] = NULL;
  1391. SetLabels(csb, labels);
  1392. SetGrayValues(csb);
  1393. j = 0;
  1394. for (i = 1; i < 4; i++) {
  1395. children[j++] = csb->csb.label_child[i];
  1396. children[j++] = csb->csb.slider_child[i];
  1397. children[j++] = csb->csb.value_child[i];
  1398. }
  1399. UnmapChildren(children, 9);
  1400. ColorizeSliders(csb);
  1401. FillPatch(csb);
  1402. }
  1403. static void RGBToCMYK(ColorSelectionBoxWidget csb)
  1404. {
  1405. csb->csb.current_color.cyan = 1.0 - csb->csb.current_color.red;
  1406. csb->csb.current_color.magenta = 1.0 - csb->csb.current_color.green;
  1407. csb->csb.current_color.yellow = 1.0 - csb->csb.current_color.blue;
  1408. csb->csb.current_color.black = 0.0;
  1409. }
  1410. static void RGBToGray(ColorSelectionBoxWidget csb)
  1411. {
  1412. csb->csb.current_color.gray = .3 * csb->csb.current_color.red +
  1413. .59 * csb->csb.current_color.green +
  1414. .11 * csb->csb.current_color.blue;
  1415. }
  1416. static void HSBToRGB(ColorSelectionBoxWidget csb)
  1417. {
  1418. double r, g, bl;
  1419. double h, s, b;
  1420. double f, m, n, k;
  1421. int i;
  1422. if (csb->csb.current_color.saturation == 0) {
  1423. r = g = bl = csb->csb.current_color.brightness;
  1424. } else {
  1425. h = csb->csb.current_color.hue;
  1426. s = csb->csb.current_color.saturation;
  1427. b = csb->csb.current_color.brightness;
  1428. h = 6.0 * h;
  1429. if (h >= 6.0) h = 0.0;
  1430. i = (int) h;
  1431. f = h - (double)i;
  1432. m = b * (1.0 - s);
  1433. n = b * (1.0 - (s * f));
  1434. k = b * (1.0 - (s * (1.0 - f)));
  1435. switch(i) {
  1436. default:
  1437. case 0: r = b; g = k; bl = m; break;
  1438. case 1: r = n; g = b; bl = m; break;
  1439. case 2: r = m; g = b; bl = k; break;
  1440. case 3: r = m; g = n; bl = b; break;
  1441. case 4: r = k; g = m; bl = b; break;
  1442. case 5: r = b; g = m; bl = n; break;
  1443. }
  1444. }
  1445. csb->csb.current_color.red = r;
  1446. csb->csb.current_color.green = g;
  1447. csb->csb.current_color.blue = bl;
  1448. }
  1449. static void RGBToHSB(ColorSelectionBoxWidget csb)
  1450. {
  1451. double hue, sat, value;
  1452. double diff, x, r, g, b;
  1453. double red, green, blue;
  1454. red = csb->csb.current_color.red;
  1455. green = csb->csb.current_color.green;
  1456. blue = csb->csb.current_color.blue;
  1457. hue = sat = 0.0;
  1458. value = x = red;
  1459. if (green > value) value = green; else x = green;
  1460. if (blue > value) value = blue;
  1461. if (blue < x) x = blue;
  1462. if (value != 0.0) {
  1463. diff = value - x;
  1464. if (diff != 0.0) {
  1465. sat = diff / value;
  1466. r = (value - red) / diff;
  1467. g = (value - green) / diff;
  1468. b = (value - blue) / diff;
  1469. if (red == value) hue = (green == x) ? 5.0 + b : 1.0 - g;
  1470. else if (green == value) hue = (blue == x) ? 1.0 + r : 3.0 - b;
  1471. else hue = (red == x) ? 3.0 + g : 5.0 - r;
  1472. hue /= 6.0; if (hue >= 1.0 || hue <= 0.0) hue = 0.0;
  1473. }
  1474. }
  1475. csb->csb.current_color.hue = hue;
  1476. csb->csb.current_color.saturation = sat;
  1477. csb->csb.current_color.brightness = value;
  1478. }
  1479. static void UpdateColorSpaces(
  1480. ColorSelectionBoxWidget csb,
  1481. CSBColorSpace masterSpace)
  1482. {
  1483. switch (masterSpace) {
  1484. case CSBSpaceRGB:
  1485. RGBToCMYK(csb);
  1486. RGBToHSB(csb);
  1487. RGBToGray(csb);
  1488. break;
  1489. case CSBSpaceCMYK:
  1490. csb->csb.current_color.red =
  1491. 1.0 - MIN(1.0, csb->csb.current_color.cyan +
  1492. csb->csb.current_color.black);
  1493. csb->csb.current_color.green =
  1494. 1.0 - MIN(1.0, csb->csb.current_color.magenta +
  1495. csb->csb.current_color.black);
  1496. csb->csb.current_color.blue =
  1497. 1.0 - MIN(1.0, csb->csb.current_color.yellow +
  1498. csb->csb.current_color.black);
  1499. RGBToHSB(csb);
  1500. RGBToGray(csb);
  1501. break;
  1502. case CSBSpaceHSB:
  1503. HSBToRGB(csb);
  1504. RGBToCMYK(csb);
  1505. RGBToGray(csb);
  1506. break;
  1507. case CSBSpaceGray:
  1508. csb->csb.current_color.red = csb->csb.current_color.green =
  1509. csb->csb.current_color.blue = csb->csb.current_color.gray;
  1510. csb->csb.current_color.hue =
  1511. csb->csb.current_color.saturation = 0.0;
  1512. csb->csb.current_color.brightness = csb->csb.current_color.gray;
  1513. csb->csb.current_color.cyan = csb->csb.current_color.magenta =
  1514. csb->csb.current_color.yellow = 0.0;
  1515. csb->csb.current_color.black = 1.0 - csb->csb.current_color.gray;
  1516. break;
  1517. }
  1518. }
  1519. /* ARGSUSED */
  1520. static void Slider1Callback(
  1521. Widget w,
  1522. XtPointer clientData, XtPointer callData)
  1523. {
  1524. ColorSelectionBoxWidget csb = (ColorSelectionBoxWidget) clientData;
  1525. XmScaleCallbackStruct *scaleData = (XmScaleCallbackStruct *) callData;
  1526. switch(csb->csb.current_space) {
  1527. case CSBSpaceRGB:
  1528. csb->csb.current_color.red = scaleData->value / 100.0;
  1529. break;
  1530. case CSBSpaceCMYK:
  1531. csb->csb.current_color.cyan = scaleData->value / 100.0;
  1532. break;
  1533. case CSBSpaceHSB:
  1534. csb->csb.current_color.hue = scaleData->value / 100.0;
  1535. break;
  1536. case CSBSpaceGray:
  1537. csb->csb.current_color.gray = scaleData->value / 100.0;
  1538. break;
  1539. }
  1540. UpdateColorSpaces(csb, csb->csb.current_space);
  1541. DoValueChangedCallback(csb);
  1542. FillPatch(csb);
  1543. }
  1544. /* ARGSUSED */
  1545. static void Slider2Callback(
  1546. Widget w,
  1547. XtPointer clientData, XtPointer callData)
  1548. {
  1549. ColorSelectionBoxWidget csb = (ColorSelectionBoxWidget) clientData;
  1550. XmScaleCallbackStruct *scaleData = (XmScaleCallbackStruct *) callData;
  1551. switch(csb->csb.current_space) {
  1552. case CSBSpaceRGB:
  1553. csb->csb.current_color.green = scaleData->value / 100.0;
  1554. break;
  1555. case CSBSpaceCMYK:
  1556. csb->csb.current_color.magenta = scaleData->value / 100.0;
  1557. break;
  1558. case CSBSpaceHSB:
  1559. csb->csb.current_color.saturation = scaleData->value / 100.0;
  1560. break;
  1561. case CSBSpaceGray:
  1562. break;
  1563. }
  1564. UpdateColorSpaces(csb, csb->csb.current_space);
  1565. DoValueChangedCallback(csb);
  1566. FillPatch(csb);
  1567. }
  1568. /* ARGSUSED */
  1569. static void Slider3Callback(
  1570. Widget w,
  1571. XtPointer clientData, XtPointer callData)
  1572. {
  1573. ColorSelectionBoxWidget csb = (ColorSelectionBoxWidget) clientData;
  1574. XmScaleCallbackStruct *scaleData = (XmScaleCallbackStruct *) callData;
  1575. switch(csb->csb.current_space) {
  1576. case CSBSpaceRGB:
  1577. csb->csb.current_color.blue = scaleData->value / 100.0;
  1578. break;
  1579. case CSBSpaceCMYK:
  1580. csb->csb.current_color.yellow = scaleData->value / 100.0;
  1581. break;
  1582. case CSBSpaceHSB:
  1583. csb->csb.current_color.brightness = scaleData->value / 100.0;
  1584. break;
  1585. case CSBSpaceGray:
  1586. break;
  1587. }
  1588. UpdateColorSpaces(csb, csb->csb.current_space);
  1589. DoValueChangedCallback(csb);
  1590. FillPatch(csb);
  1591. }
  1592. /* ARGSUSED */
  1593. static void Slider4Callback(
  1594. Widget w,
  1595. XtPointer clientData, XtPointer callData)
  1596. {
  1597. ColorSelectionBoxWidget csb = (ColorSelectionBoxWidget) clientData;
  1598. XmScaleCallbackStruct *scaleData = (XmScaleCallbackStruct *) callData;
  1599. csb->csb.current_color.black = scaleData->value / 100.0;
  1600. UpdateColorSpaces(csb, csb->csb.current_space);
  1601. DoValueChangedCallback(csb);
  1602. FillPatch(csb);
  1603. }
  1604. static void FillPatch(ColorSelectionBoxWidget csb)
  1605. {
  1606. Colormap c;
  1607. XColor xc;
  1608. Widget patch = csb->csb.patch_child;
  1609. if (!XtIsRealized(csb->csb.patch_child)) return;
  1610. if (csb->csb.no_background) {
  1611. XClearArea(XtDisplay(patch), XtWindow(patch), 0, 0, 1000, 1000, True);
  1612. return;
  1613. }
  1614. /* All we have to do is set the background; the expose event will
  1615. do the rest */
  1616. XtVaGetValues(patch, XtNcolormap, (XtPointer) &c, NULL);
  1617. if (csb->csb.current_space == CSBSpaceGray) {
  1618. xc.red = xc.green = xc.blue = TO_X(csb->csb.current_color.gray);
  1619. } else {
  1620. xc.red = TO_X(csb->csb.current_color.red);
  1621. xc.green = TO_X(csb->csb.current_color.green);
  1622. xc.blue = TO_X(csb->csb.current_color.blue);
  1623. }
  1624. if (csb->csb.static_visual) {
  1625. (void) XAllocColor(XtDisplay(patch), c, &xc);
  1626. csb->csb.background = xc.pixel;
  1627. XtVaSetValues(patch, XtNbackground, csb->csb.background, NULL);
  1628. } else {
  1629. xc.pixel = csb->csb.background;
  1630. xc.flags = DoRed | DoGreen | DoBlue;
  1631. XStoreColor(XtDisplay(patch), c, &xc);
  1632. }
  1633. XClearArea(XtDisplay(patch), XtWindow(patch), 0, 0, 1000, 1000, True);
  1634. }
  1635. /* ARGSUSED */
  1636. static void FillPatchCallback(
  1637. Widget w,
  1638. XtPointer clientData, XtPointer callData)
  1639. {
  1640. ColorSelectionBoxWidget csb = (ColorSelectionBoxWidget) clientData;
  1641. Dimension height, width;
  1642. float fh, fw;
  1643. if (csb->csb.current_rendering != CSBDisplayX) {
  1644. XtVaGetValues(w, XtNheight, &height, XtNwidth, &width, NULL);
  1645. if (csb->csb.patch_gstate == 0) {
  1646. XDPSSetContextGState(csb->csb.context, csb->csb.base_gstate);
  1647. XDPSSetContextDrawable(csb->csb.context, XtWindow(w), height);
  1648. (void) XDPSCaptureContextGState(csb->csb.context,
  1649. &csb->csb.patch_gstate);
  1650. } else XDPSSetContextGState(csb->csb.context, csb->csb.patch_gstate);
  1651. switch (csb->csb.current_space) {
  1652. case CSBSpaceRGB:
  1653. DPSsetrgbcolor(csb->csb.context, csb->csb.current_color.red,
  1654. csb->csb.current_color.green,
  1655. csb->csb.current_color.blue);
  1656. break;
  1657. case CSBSpaceCMYK:
  1658. DPSsetcmykcolor(csb->csb.context, csb->csb.current_color.cyan,
  1659. csb->csb.current_color.magenta,
  1660. csb->csb.current_color.yellow,
  1661. csb->csb.current_color.black);
  1662. break;
  1663. case CSBSpaceHSB:
  1664. DPSsethsbcolor(csb->csb.context, csb->csb.current_color.hue,
  1665. csb->csb.current_color.saturation,
  1666. csb->csb.current_color.brightness);
  1667. break;
  1668. case CSBSpaceGray:
  1669. DPSsetgray(csb->csb.context, csb->csb.current_color.gray);
  1670. break;
  1671. }
  1672. }
  1673. switch (csb->csb.current_rendering) {
  1674. case CSBDisplayDPS:
  1675. DPSrectfill(csb->csb.context, 0.0, 0.0, 1000.0, 1000.0);
  1676. break;
  1677. case CSBDisplayX:
  1678. break;
  1679. case CSBDisplayBoth:
  1680. ToUserSpace(csb, width, height, &fw, &fh);
  1681. _DPSCTriangle(csb->csb.context, fh, fw);
  1682. break;
  1683. }
  1684. }
  1685. /* The following function Copyright 1987, 1988 by Digital Equipment
  1686. Corporation, Maynard, Massachusetts, and the Massachusetts Institute of
  1687. Technology, Cambridge, Massachusetts. */
  1688. static String GetRootDirName(String buf)
  1689. {
  1690. #ifndef X_NOT_POSIX
  1691. uid_t uid;
  1692. #else
  1693. int uid;
  1694. extern int getuid();
  1695. #ifndef SYSV386
  1696. extern struct passwd *getpwuid(), *getpwnam();
  1697. #endif
  1698. #endif
  1699. struct passwd *pw;
  1700. static char *ptr = NULL;
  1701. if (ptr == NULL) {
  1702. if (!(ptr = getenv("HOME"))) {
  1703. if ((ptr = getenv("USER")) != 0) {
  1704. pw = getpwnam(ptr);
  1705. } else {
  1706. uid = getuid();
  1707. pw = getpwuid(uid);
  1708. }
  1709. if (pw) ptr = pw->pw_dir;
  1710. else {
  1711. ptr = NULL;
  1712. *buf = '\0';
  1713. }
  1714. }
  1715. }
  1716. if (ptr)
  1717. (void) strcpy(buf, ptr);
  1718. buf += strlen(buf);
  1719. *buf = '/';
  1720. buf++;
  1721. *buf = '\0';
  1722. return buf;
  1723. }
  1724. static void AllocateDock(ColorSelectionBoxWidget csb)
  1725. {
  1726. int entry;
  1727. csb->csb.dock_cyan = (float *) XtCalloc(csb->csb.num_cells, sizeof(float));
  1728. csb->csb.dock_magenta =
  1729. (float *) XtCalloc(csb->csb.num_cells, sizeof(float));
  1730. csb->csb.dock_yellow =
  1731. (float *) XtCalloc(csb->csb.num_cells, sizeof(float));
  1732. csb->csb.dock_black =
  1733. (float *) XtCalloc(csb->csb.num_cells, sizeof(float));
  1734. csb->csb.dock_used =
  1735. (Boolean *) XtCalloc(csb->csb.num_cells, sizeof(Boolean));
  1736. for (entry = 0; entry < csb->csb.num_cells; entry++) {
  1737. csb->csb.dock_used[entry] = 0;
  1738. }
  1739. }
  1740. static void InitializeDock(ColorSelectionBoxWidget csb)
  1741. {
  1742. String dockEnv;
  1743. char homeDir[PATH_BUF_SIZE];
  1744. FILE *dockFile = NULL;
  1745. char fileName[PATH_BUF_SIZE];
  1746. #define BUF 256
  1747. char buf[BUF+1];
  1748. int entry;
  1749. float cyan, magenta, yellow, black;
  1750. #define CHECK(v) ((v) > 1.0 ? 1.0 : ((v) < 0.0 ? 0.0 : (v)))
  1751. AllocateDock(csb);
  1752. csb->csb.dock_changed = False;
  1753. dockEnv = getenv("DPSCPICKRC");
  1754. if (dockEnv != NULL) dockFile = fopen(dockEnv, "r");
  1755. if (dockFile == NULL) {
  1756. (void) GetRootDirName(homeDir);
  1757. if (dockFile == NULL) {
  1758. sprintf(fileName, "%s/.dpscpickrc", homeDir);
  1759. dockFile = fopen(fileName, "r");
  1760. if (dockFile == NULL) return;
  1761. }
  1762. }
  1763. while (1) {
  1764. if (fgets(buf, BUF, dockFile) == NULL) {
  1765. fclose(dockFile);
  1766. return;
  1767. }
  1768. if (sscanf(buf, "%d %f %f %f %f",
  1769. &entry, &cyan, &magenta, &yellow, &black) == 5) {
  1770. if (entry <= csb->csb.num_cells) {
  1771. csb->csb.dock_cyan[entry] = CHECK(cyan);
  1772. csb->csb.dock_magenta[entry] = CHECK(magenta);
  1773. csb->csb.dock_yellow[entry] = CHECK(yellow);
  1774. csb->csb.dock_black[entry] = CHECK(black);
  1775. csb->csb.dock_used[entry] = True;
  1776. }
  1777. }
  1778. }
  1779. #undef BUF
  1780. #undef CHECK
  1781. }
  1782. static void SaveDockContents(ColorSelectionBoxWidget csb)
  1783. {
  1784. String dockEnv;
  1785. char homeDir[PATH_BUF_SIZE];
  1786. FILE *dockFile = NULL;
  1787. char fileName[PATH_BUF_SIZE];
  1788. int i;
  1789. if (!csb->csb.dock_changed) return;
  1790. dockEnv = getenv("DPSCPICKRC");
  1791. if (dockEnv != NULL) dockFile = fopen(dockEnv, "w");
  1792. if (dockFile == NULL) {
  1793. (void) GetRootDirName(homeDir);
  1794. if (dockFile == NULL) {
  1795. sprintf(fileName, "%s/.dpscpickrc", homeDir);
  1796. dockFile = fopen(fileName, "w");
  1797. if (dockFile == NULL) return;
  1798. }
  1799. }
  1800. for (i = 0; i < csb->csb.num_cells; i++) {
  1801. if (!csb->csb.dock_used[i]) continue;
  1802. fprintf(dockFile, "%d %g %g %g %g\n", i, csb->csb.dock_cyan[i],
  1803. csb->csb.dock_magenta[i], csb->csb.dock_yellow[i],
  1804. csb->csb.dock_black[i]);
  1805. }
  1806. fclose(dockFile);
  1807. csb->csb.dock_changed = False;
  1808. }
  1809. /* ARGSUSED */
  1810. static void DrawDockCallback(
  1811. Widget w,
  1812. XtPointer clientData, XtPointer callData)
  1813. {
  1814. ColorSelectionBoxWidget csb = (ColorSelectionBoxWidget) clientData;
  1815. XClearArea(XtDisplay(csb), XtWindow(csb->csb.dock_child),
  1816. 0, 0, 1000, 1000, False);
  1817. DrawDock(csb);
  1818. }
  1819. static void DrawDock(ColorSelectionBoxWidget csb)
  1820. {
  1821. Dimension height;
  1822. float w, h;
  1823. int lines;
  1824. int i, row, col;
  1825. Boolean didAny = False;
  1826. XtVaGetValues(csb->csb.dock_child, XtNheight, &height, NULL);
  1827. lines = height / csb->csb.cell_size;
  1828. if (csb->csb.dock_gstate == 0) {
  1829. XDPSSetContextGState(csb->csb.context, csb->csb.base_gstate);
  1830. XDPSSetContextDrawable(csb->csb.context,
  1831. XtWindow(csb->csb.dock_child), height);
  1832. (void) XDPSCaptureContextGState(csb->csb.context,
  1833. &csb->csb.dock_gstate);
  1834. } else XDPSSetContextGState(csb->csb.context, csb->csb.dock_gstate);
  1835. ToUserSpace(csb, csb->csb.cell_size, csb->csb.cell_size, &w, &h);
  1836. for (i = 0; i < csb->csb.num_cells; i++) {
  1837. if (!csb->csb.dock_used[i]) continue;
  1838. row = (lines - 1) - (i % lines);
  1839. col = i / lines;
  1840. DPSsetcmykcolor(csb->csb.context, csb->csb.dock_cyan[i],
  1841. csb->csb.dock_magenta[i], csb->csb.dock_yellow[i],
  1842. csb->csb.dock_black[i]);
  1843. DPSrectfill(csb->csb.context,
  1844. (float) (col * w), (float) (row * h), w, h);
  1845. didAny = True;
  1846. }
  1847. if (!didAny) _DPSCShowFillMe(csb->csb.context, csb->csb.fill_me);
  1848. }
  1849. static void StoreColorInDock(
  1850. ColorSelectionBoxWidget csb,
  1851. int x_offset,
  1852. int y_offset,
  1853. Dimension dockHeight)
  1854. {
  1855. int i, lines, row, col;
  1856. lines = dockHeight / csb->csb.cell_size;
  1857. row = y_offset / (int) csb->csb.cell_size;
  1858. col = x_offset / (int) csb->csb.cell_size;
  1859. i = col * lines + row;
  1860. if (i >= csb->csb.num_cells) i = csb->csb.num_cells;
  1861. csb->csb.dock_cyan[i] = csb->csb.current_color.cyan;
  1862. csb->csb.dock_magenta[i] = csb->csb.current_color.magenta;
  1863. csb->csb.dock_yellow[i] = csb->csb.current_color.yellow;
  1864. csb->csb.dock_black[i] = csb->csb.current_color.black;
  1865. csb->csb.dock_used[i] = True;
  1866. csb->csb.dock_changed = True;
  1867. DrawDock(csb);
  1868. }
  1869. /* ARGSUSED */
  1870. static void DockPress(
  1871. Widget w,
  1872. XtPointer data,
  1873. XEvent *event,
  1874. Boolean *goOn)
  1875. {
  1876. ColorSelectionBoxWidget csb = (ColorSelectionBoxWidget) data;
  1877. Dimension height;
  1878. int i, lines, row, col;
  1879. XtVaGetValues(csb->csb.dock_child, XtNheight, &height, NULL);
  1880. lines = height / csb->csb.cell_size;
  1881. row = event->xbutton.y / (int) csb->csb.cell_size;
  1882. col = event->xbutton.x / (int) csb->csb.cell_size;
  1883. i = col * lines + row;
  1884. if (i >= csb->csb.num_cells) i = csb->csb.num_cells;
  1885. if (!csb->csb.dock_used[i]) return;
  1886. csb->csb.current_color.cyan = csb->csb.dock_cyan[i];
  1887. csb->csb.current_color.magenta = csb->csb.dock_magenta[i];
  1888. csb->csb.current_color.yellow = csb->csb.dock_yellow[i];
  1889. csb->csb.current_color.black = csb->csb.dock_black[i];
  1890. UpdateColorSpaces(csb, CSBSpaceCMYK);
  1891. DoValueChangedCallback(csb);
  1892. FillPatch(csb);
  1893. SetSliders(csb);
  1894. }
  1895. static void InitializePalettes(ColorSelectionBoxWidget csb)
  1896. {
  1897. int k;
  1898. for (k = 0; k < PALETTE_MAX; k++) {
  1899. if (csb->csb.palette_function[k] != NULL) {
  1900. DPSPrintf(csb->csb.context,
  1901. "/palette%dfunc%d { %s } bind def\n", k, (int) csb,
  1902. csb->csb.palette_function[k]);
  1903. }
  1904. csb->csb.palette_broken[k] = False;
  1905. }
  1906. }
  1907. static void InvalidatePalette(ColorSelectionBoxWidget csb)
  1908. {
  1909. int len;
  1910. char *buf;
  1911. Widget w;
  1912. register int i = csb->csb.current_palette;
  1913. len = strlen(csb->csb.palette_label[i]) +
  1914. strlen(csb->csb.broken_palette_label) + 2;
  1915. len = MAX(len, 11);
  1916. buf = (char *) XtMalloc(len);
  1917. csb->csb.palette_broken[i] = True;
  1918. sprintf(buf, "*palette%d", csb->csb.current_palette);
  1919. w = XtNameToWidget((Widget) csb, buf);
  1920. if (w != NULL) XtSetSensitive(w, False);
  1921. sprintf(buf, "%s %s", csb->csb.palette_label[i],
  1922. csb->csb.broken_palette_label);
  1923. len = strlen(buf);
  1924. XtVaSetValues(w, XtVaTypedArg, XmNlabelString, XtRString, buf, len, NULL);
  1925. }
  1926. static void DoPalette(
  1927. ColorSelectionBoxWidget csb,
  1928. Dimension pixelWidth,
  1929. float w,
  1930. float h)
  1931. {
  1932. char whichFunc[25];
  1933. int steps;
  1934. int success;
  1935. sprintf(whichFunc, "palette%dfunc%d", csb->csb.current_palette, (int) csb);
  1936. if (csb->csb.visual_class == TrueColor) steps = pixelWidth / 2;
  1937. else steps = pixelWidth / 4;
  1938. if (csb->csb.palette_color_dependent[csb->csb.current_palette]) {
  1939. switch (csb->csb.palette_space[csb->csb.current_palette]) {
  1940. case CSBSpaceRGB:
  1941. _DPSCDoRGBColorPalette(csb->csb.context, whichFunc,
  1942. csb->csb.current_color.red,
  1943. csb->csb.current_color.green,
  1944. csb->csb.current_color.blue,
  1945. w, h, steps, &success);
  1946. break;
  1947. case CSBSpaceCMYK:
  1948. _DPSCDoCMYKColorPalette(csb->csb.context, whichFunc,
  1949. csb->csb.current_color.cyan,
  1950. csb->csb.current_color.magenta,
  1951. csb->csb.current_color.yellow,
  1952. csb->csb.current_color.black,
  1953. w, h, steps, &success);
  1954. break;
  1955. case CSBSpaceHSB:
  1956. _DPSCDoHSBColorPalette(csb->csb.context, whichFunc,
  1957. csb->csb.current_color.hue,
  1958. csb->csb.current_color.saturation,
  1959. csb->csb.current_color.brightness,
  1960. w, h, steps, &success);
  1961. break;
  1962. case CSBSpaceGray:
  1963. _DPSCDoGrayColorPalette(csb->csb.context, whichFunc,
  1964. csb->csb.current_color.gray,
  1965. w, h, steps, &success);
  1966. break;
  1967. }
  1968. } else {
  1969. switch (csb->csb.palette_space[csb->csb.current_palette]) {
  1970. case CSBSpaceRGB:
  1971. _DPSCDoRGBPalette(csb->csb.context, whichFunc, w, h,
  1972. steps, &success);
  1973. break;
  1974. case CSBSpaceCMYK:
  1975. _DPSCDoCMYKPalette(csb->csb.context, whichFunc, w, h,
  1976. steps, &success);
  1977. break;
  1978. case CSBSpaceHSB:
  1979. _DPSCDoHSBPalette(csb->csb.context, whichFunc, w, h,
  1980. steps, &success);
  1981. break;
  1982. case CSBSpaceGray:
  1983. _DPSCDoGrayPalette(csb->csb.context, whichFunc, w, h,
  1984. steps, &success);
  1985. break;
  1986. }
  1987. }
  1988. if (!success) {
  1989. InvalidatePalette(csb);
  1990. _DPSCShowMessage(csb->csb.context, csb->csb.broken_palette_message);
  1991. }
  1992. }
  1993. static void DrawPalette(ColorSelectionBoxWidget csb)
  1994. {
  1995. DrawPaletteCallback(csb->csb.palette_child,
  1996. (XtPointer) csb, (XtPointer) NULL);
  1997. }
  1998. /* ARGSUSED */
  1999. static void DrawPaletteCallback(
  2000. Widget wid,
  2001. XtPointer clientData, XtPointer callData)
  2002. {
  2003. ColorSelectionBoxWidget csb = (ColorSelectionBoxWidget) clientData;
  2004. Dimension width, height;
  2005. Pixmap palette_pixmap;
  2006. int depth;
  2007. float w, h;
  2008. if (csb->csb.palette_broken[csb->csb.current_palette]) return;
  2009. if (!csb->csb.palette_pixmap_valid) {
  2010. XtVaGetValues(csb->csb.palette_child,
  2011. XtNwidth, &width, XtNheight, &height,
  2012. XtNdepth, &depth, NULL);
  2013. ToUserSpace(csb, width, height, &w, &h);
  2014. palette_pixmap =
  2015. XCreatePixmap(XtDisplay(csb), XtWindow(csb->csb.palette_child),
  2016. width, height, depth);
  2017. XDPSSetContextGState(csb->csb.context, csb->csb.base_gstate);
  2018. XDPSSetContextDrawable(csb->csb.context, palette_pixmap, height);
  2019. DoPalette(csb, width, w, h);
  2020. csb->csb.palette_color = csb->csb.current_color;
  2021. DPSWaitContext(csb->csb.context);
  2022. XtVaSetValues(csb->csb.palette_child,
  2023. XtNbackgroundPixmap, palette_pixmap, NULL);
  2024. XFreePixmap(XtDisplay(csb), palette_pixmap);
  2025. csb->csb.palette_pixmap_valid = True;
  2026. }
  2027. }
  2028. /* ARGSUSED */
  2029. static void PalettePress(
  2030. Widget w,
  2031. XtPointer data,
  2032. XEvent *event,
  2033. Boolean *goOn)
  2034. {
  2035. ColorSelectionBoxWidget csb = (ColorSelectionBoxWidget) data;
  2036. Dimension width;
  2037. float pct;
  2038. char whichFunc[25];
  2039. int success;
  2040. float f1, f2, f3, f4;
  2041. if (csb->csb.palette_broken[csb->csb.current_palette]) return;
  2042. sprintf(whichFunc, "palette%dfunc%d", csb->csb.current_palette, (int) csb);
  2043. XtVaGetValues(csb->csb.palette_child, XtNwidth, &width, NULL);
  2044. pct = ((float) event->xbutton.x) / ((float) width);
  2045. if (csb->csb.palette_color_dependent[csb->csb.current_palette]) {
  2046. switch (csb->csb.palette_space[csb->csb.current_palette]) {
  2047. case CSBSpaceRGB:
  2048. _DPSCQueryRGBColorPalette(csb->csb.context, whichFunc, pct,
  2049. csb->csb.palette_color.red,
  2050. csb->csb.palette_color.green,
  2051. csb->csb.palette_color.blue,
  2052. &f1, &f2, &f3, &success);
  2053. if (success) {
  2054. csb->csb.current_color.red = f1;
  2055. csb->csb.current_color.green = f2;
  2056. csb->csb.current_color.blue = f3;
  2057. }
  2058. break;
  2059. case CSBSpaceCMYK:
  2060. _DPSCQueryCMYKColorPalette(csb->csb.context, whichFunc, pct,
  2061. csb->csb.palette_color.cyan,
  2062. csb->csb.palette_color.magenta,
  2063. csb->csb.palette_color.yellow,
  2064. csb->csb.palette_color.black,
  2065. &f1, &f2, &f3, &f4, &success);
  2066. if (success) {
  2067. csb->csb.current_color.cyan = f1;
  2068. csb->csb.current_color.magenta = f2;
  2069. csb->csb.current_color.yellow = f3;
  2070. csb->csb.current_color.black = f4;
  2071. }
  2072. break;
  2073. case CSBSpaceHSB:
  2074. _DPSCQueryHSBColorPalette(csb->csb.context, whichFunc, pct,
  2075. csb->csb.palette_color.hue,
  2076. csb->csb.palette_color.saturation,
  2077. csb->csb.palette_color.brightness,
  2078. &f1, &f2, &f3, &success);
  2079. if (success) {
  2080. csb->csb.current_color.hue = f1;
  2081. csb->csb.current_color.saturation = f2;
  2082. csb->csb.current_color.brightness = f3;
  2083. }
  2084. break;
  2085. case CSBSpaceGray:
  2086. _DPSCQueryGrayColorPalette(csb->csb.context, whichFunc, pct,
  2087. csb->csb.palette_color.gray,
  2088. &f1, &success);
  2089. if (success) csb->csb.current_color.gray = f1;
  2090. break;
  2091. }
  2092. } else {
  2093. switch (csb->csb.palette_space[csb->csb.current_palette]) {
  2094. case CSBSpaceRGB:
  2095. _DPSCQueryRGBPalette(csb->csb.context, whichFunc, pct,
  2096. &f1, &f2, &f3, &success);
  2097. if (success) {
  2098. csb->csb.current_color.red = f1;
  2099. csb->csb.current_color.green = f2;
  2100. csb->csb.current_color.blue = f3;
  2101. }
  2102. break;
  2103. case CSBSpaceCMYK:
  2104. _DPSCQueryCMYKPalette(csb->csb.context, whichFunc, pct,
  2105. &f1, &f2, &f3, &f4, &success);
  2106. if (success) {
  2107. csb->csb.current_color.cyan = f1;
  2108. csb->csb.current_color.magenta = f2;
  2109. csb->csb.current_color.yellow = f3;
  2110. csb->csb.current_color.black = f4;
  2111. }
  2112. break;
  2113. case CSBSpaceHSB:
  2114. _DPSCQueryHSBPalette(csb->csb.context, whichFunc, pct,
  2115. &f1, &f2, &f3, &success);
  2116. if (success) {
  2117. csb->csb.current_color.hue = f1;
  2118. csb->csb.current_color.saturation = f2;
  2119. csb->csb.current_color.brightness = f3;
  2120. }
  2121. break;
  2122. case CSBSpaceGray:
  2123. _DPSCQueryGrayPalette(csb->csb.context, whichFunc, pct,
  2124. &f1, &success);
  2125. if (success) csb->csb.current_color.gray = f1;
  2126. break;
  2127. }
  2128. }
  2129. if (!success) InvalidatePalette(csb);
  2130. else {
  2131. UpdateColorSpaces(csb,
  2132. csb->csb.palette_space[csb->csb.current_palette]);
  2133. DoValueChangedCallback(csb);
  2134. FillPatch(csb);
  2135. SetSliders(csb);
  2136. }
  2137. }
  2138. /* ARGSUSED */
  2139. static void DoEyedropCallback(
  2140. Widget w,
  2141. XtPointer clientData, XtPointer callData)
  2142. {
  2143. ColorSelectionBoxWidget csb = (ColorSelectionBoxWidget) clientData;
  2144. Pixmap eyedropBitmap, eyedropMaskBitmap;
  2145. XColor black, fg;
  2146. Display *dpy;
  2147. unsigned int x, y;
  2148. XEvent ev;
  2149. dpy = XtDisplay(w);
  2150. black.red = 0;
  2151. black.green = 0;
  2152. black.blue = 0;
  2153. fg.red = 65535;
  2154. fg.green = 65535;
  2155. fg.blue = 65535;
  2156. if (csb->csb.eyedrop == None) {
  2157. XQueryBestCursor(dpy, XtWindow(w), 32, 32,
  2158. &x, &y);
  2159. if (x >= 32 && y >= 32) {
  2160. eyedropBitmap =
  2161. XCreateBitmapFromData(dpy, XtWindow(w),
  2162. (char *) eyedrop32_bits,
  2163. eyedrop32_width, eyedrop32_height);
  2164. eyedropMaskBitmap =
  2165. XCreateBitmapFromData(dpy, XtWindow(w),
  2166. (char *) eyedropmask32_bits,
  2167. eyedropmask32_width,
  2168. eyedropmask32_height);
  2169. csb->csb.eyedrop =
  2170. XCreatePixmapCursor(dpy, eyedropBitmap,
  2171. eyedropMaskBitmap,
  2172. &fg, &black,
  2173. eyedrop32_x_hot, eyedrop32_y_hot);
  2174. } else {
  2175. eyedropBitmap =
  2176. XCreateBitmapFromData(dpy, XtWindow(w),
  2177. (char *) eyedrop16_bits,
  2178. eyedrop16_width, eyedrop16_height);
  2179. eyedropMaskBitmap =
  2180. XCreateBitmapFromData(dpy, XtWindow(w),
  2181. (char *) eyedropmask16_bits,
  2182. eyedropmask16_width,
  2183. eyedropmask16_height);
  2184. csb->csb.eyedrop =
  2185. XCreatePixmapCursor(dpy, eyedropBitmap,
  2186. eyedropMaskBitmap,
  2187. &fg, &black,
  2188. eyedrop16_x_hot, eyedrop16_y_hot);
  2189. }
  2190. } else {
  2191. XRecolorCursor(dpy, csb->csb.eyedrop, &fg, &black);
  2192. }
  2193. (void) XtGrabPointer(w, False,
  2194. PointerMotionMask | PointerMotionHintMask |
  2195. ButtonReleaseMask,
  2196. GrabModeAsync, GrabModeAsync,
  2197. None, csb->csb.eyedrop,
  2198. XtLastTimestampProcessed(dpy));
  2199. csb->csb.eyedrop_grabbed = True;
  2200. ev.type = 0;
  2201. EyedropPointer(w, (XtPointer) csb, &ev, (Boolean *) NULL);
  2202. }
  2203. /* ARGSUSED */
  2204. static void EyedropPointer(
  2205. Widget w,
  2206. XtPointer data,
  2207. XEvent *event,
  2208. Boolean *goOn)
  2209. {
  2210. ColorSelectionBoxWidget csb = (ColorSelectionBoxWidget) data;
  2211. XColor fg, black;
  2212. Window root, child, stop, old_child = None;
  2213. int root_x, root_y, x, y;
  2214. unsigned int mask;
  2215. XWindowAttributes att;
  2216. XImage *image;
  2217. Pixel pixel;
  2218. Colormap colormap = 0;
  2219. Display *dpy = XtDisplay(w);
  2220. if (!csb->csb.eyedrop_grabbed) return;
  2221. if (event->type == ButtonPress || event->type == ButtonRelease) {
  2222. root = event->xbutton.root;
  2223. root_x = event->xbutton.x_root;
  2224. root_y = event->xbutton.y_root;
  2225. XTranslateCoordinates(dpy, root, root, root_x, root_y, &x, &y, &child);
  2226. } else {
  2227. XQueryPointer(dpy, RootWindowOfScreen(XtScreen(w)),
  2228. &root, &child, &root_x, &root_y, &x, &y, &mask);
  2229. }
  2230. if (child == None) child = root;
  2231. else {
  2232. stop = child;
  2233. while (stop != None) {
  2234. XTranslateCoordinates(dpy, root, stop, x, y, &x, &y, &child);
  2235. root = stop;
  2236. if (child != None && XGetWindowAttributes(dpy, child, &att) &&
  2237. att.class != InputOutput) break;
  2238. stop = child;
  2239. }
  2240. child = root;
  2241. }
  2242. if (child != old_child) {
  2243. XGetWindowAttributes(dpy, child, &att);
  2244. colormap = att.colormap;
  2245. old_child = child;
  2246. }
  2247. image = XGetImage(dpy, child, x, y, 1, 1, AllPlanes, XYPixmap);
  2248. pixel = XGetPixel(image, 0, 0);
  2249. XDestroyImage(image);
  2250. fg.pixel = pixel;
  2251. XQueryColors(dpy, colormap, &fg, 1);
  2252. black.red = 0;
  2253. black.green = 0;
  2254. black.blue = 0;
  2255. XRecolorCursor(dpy, csb->csb.eyedrop, &fg, &black);
  2256. if (event->type == ButtonRelease) {
  2257. XtUngrabPointer(w, XtLastTimestampProcessed(dpy));
  2258. csb->csb.eyedrop_grabbed = False;
  2259. csb->csb.current_color.red = (float) fg.red / 65535.0;
  2260. csb->csb.current_color.green = (float) fg.green / 65535.0;
  2261. csb->csb.current_color.blue = (float) fg.blue / 65535.0;
  2262. UpdateColorSpaces(csb, CSBSpaceRGB);
  2263. DoValueChangedCallback(csb);
  2264. FillPatch(csb);
  2265. SetSliders(csb);
  2266. }
  2267. }
  2268. /* ARGSUSED */
  2269. static void PatchPress(
  2270. Widget w,
  2271. XtPointer data,
  2272. XEvent *event,
  2273. Boolean *goOn)
  2274. {
  2275. ColorSelectionBoxWidget csb = (ColorSelectionBoxWidget) data;
  2276. Pixmap squareBitmap, squareMaskBitmap;
  2277. XColor black, fg;
  2278. Display *dpy;
  2279. dpy = XtDisplay(w);
  2280. black.red = 0;
  2281. black.green = 0;
  2282. black.blue = 0;
  2283. fg.red = TO_X(csb->csb.current_color.red);
  2284. fg.green = TO_X(csb->csb.current_color.green);
  2285. fg.blue = TO_X(csb->csb.current_color.blue);
  2286. if (csb->csb.square == None) {
  2287. squareBitmap =
  2288. XCreateBitmapFromData(dpy, XtWindow(w), (char *) square_bits,
  2289. square_width, square_height);
  2290. squareMaskBitmap =
  2291. XCreateBitmapFromData(dpy, XtWindow(w),
  2292. (char *) squaremask_bits,
  2293. squaremask_width, squaremask_height);
  2294. csb->csb.square =
  2295. XCreatePixmapCursor(dpy, squareBitmap, squareMaskBitmap,
  2296. &fg, &black, square_x_hot, square_y_hot);
  2297. } else {
  2298. XRecolorCursor(dpy, csb->csb.square, &fg, &black);
  2299. }
  2300. (void) XtGrabPointer(w, False, ButtonReleaseMask,
  2301. GrabModeAsync, GrabModeAsync,
  2302. None, csb->csb.square, XtLastTimestampProcessed(dpy));
  2303. }
  2304. /* ARGSUSED */
  2305. static void PatchRelease(
  2306. Widget w,
  2307. XtPointer data,
  2308. XEvent *event,
  2309. Boolean *goOn)
  2310. {
  2311. ColorSelectionBoxWidget csb = (ColorSelectionBoxWidget) data;
  2312. Dimension width, height;
  2313. Position left, top;
  2314. XtUngrabPointer(w, XtLastTimestampProcessed(XtDisplay(w)));
  2315. XFlush(XtDisplay(w));
  2316. XtVaGetValues(csb->csb.dock_child, XtNwidth, &width,
  2317. XtNheight, &height, NULL);
  2318. XtTranslateCoords(csb->csb.dock_child, (Position) 0, (Position) 0,
  2319. &left, &top);
  2320. if ((int) event->xbutton.x_root >= left &&
  2321. (int) event->xbutton.x_root <= left + (int) width &&
  2322. (int) event->xbutton.y_root >= top &&
  2323. (int) event->xbutton.y_root <= top + (int) height) {
  2324. StoreColorInDock(csb, event->xbutton.x_root - left,
  2325. event->xbutton.y_root - top, height);
  2326. }
  2327. }
  2328. static void GetVisualInfo(
  2329. ColorSelectionBoxWidget csb,
  2330. Visual **visual)
  2331. {
  2332. Widget w = (Widget) csb;
  2333. XVisualInfo *vip, viproto;
  2334. int n;
  2335. XWindowAttributes xwa;
  2336. XGetWindowAttributes(XtDisplay(w), XtWindow(w), &xwa);
  2337. *visual = viproto.visual = xwa.visual;
  2338. viproto.visualid = XVisualIDFromVisual(xwa.visual);
  2339. vip = XGetVisualInfo(XtDisplay(w), VisualIDMask, &viproto, &n);
  2340. if (n != 1) {
  2341. csb->csb.static_visual = False; /* Actually we have no idea, but... */
  2342. csb->csb.visual_class = PseudoColor;
  2343. } else {
  2344. csb->csb.visual_class = vip->class;
  2345. csb->csb.static_visual = (vip->class == StaticGray ||
  2346. vip->class == TrueColor ||
  2347. vip->class == StaticColor);
  2348. }
  2349. if (n > 0) XFree((char *) vip);
  2350. }
  2351. static void SetBackground(ColorSelectionBoxWidget csb)
  2352. {
  2353. Colormap c;
  2354. XColor xc;
  2355. int status;
  2356. unsigned long pix;
  2357. unsigned long mask;
  2358. XtVaGetValues(csb->csb.patch_child, XtNcolormap, (XtPointer) &c, NULL);
  2359. if (csb->csb.current_space == CSBSpaceGray) {
  2360. xc.red = xc.green = xc.blue = TO_X(csb->csb.current_color.gray);
  2361. } else {
  2362. xc.red = TO_X(csb->csb.current_color.red);
  2363. xc.green = TO_X(csb->csb.current_color.green);
  2364. xc.blue = TO_X(csb->csb.current_color.blue);
  2365. }
  2366. if (csb->csb.static_visual) {
  2367. status = XAllocColor(XtDisplay(csb), c, &xc);
  2368. if (status == 0) NoBackgroundPixel(csb);
  2369. else {
  2370. csb->csb.background = xc.pixel;
  2371. XtVaSetValues(csb->csb.patch_child,
  2372. XtNbackground, csb->csb.background, NULL);
  2373. }
  2374. } else {
  2375. if (csb->csb.visual_class == DirectColor) {
  2376. status = XAllocColorPlanes(XtDisplay(csb), c,
  2377. False, &pix, 1, 0, 0, 0,
  2378. &mask, &mask, &mask);
  2379. } else {
  2380. status = XAllocColorCells(XtDisplay(csb), c,
  2381. False, (unsigned long *) NULL, 0,
  2382. &pix, 1);
  2383. }
  2384. if (status == 0) NoBackgroundPixel(csb);
  2385. else {
  2386. xc.pixel = pix;
  2387. xc.flags = DoRed | DoGreen | DoBlue;
  2388. XStoreColor(XtDisplay(csb), c, &xc);
  2389. csb->csb.background = xc.pixel;
  2390. XtVaSetValues(csb->csb.patch_child,
  2391. XtNbackground, csb->csb.background, NULL);
  2392. }
  2393. }
  2394. }
  2395. /* ARGSUSED */
  2396. static void Initialize(
  2397. Widget request, Widget new,
  2398. ArgList args,
  2399. Cardinal *num_args)
  2400. {
  2401. ColorSelectionBoxWidget csb = (ColorSelectionBoxWidget) new;
  2402. Bool inited;
  2403. int i;
  2404. if (csb->csb.rgb_labels != NULL) {
  2405. csb->csb.rgb_labels = XtNewString(csb->csb.rgb_labels);
  2406. }
  2407. if (csb->csb.cmyk_labels != NULL) {
  2408. csb->csb.cmyk_labels = XtNewString(csb->csb.cmyk_labels);
  2409. }
  2410. if (csb->csb.hsb_labels != NULL) {
  2411. csb->csb.hsb_labels = XtNewString(csb->csb.hsb_labels);
  2412. }
  2413. if (csb->csb.gray_labels != NULL) {
  2414. csb->csb.gray_labels = XtNewString(csb->csb.gray_labels);
  2415. }
  2416. if (csb->csb.fill_me != NULL) {
  2417. csb->csb.fill_me = XtNewString(csb->csb.fill_me);
  2418. }
  2419. if (csb->csb.broken_palette_label != NULL) {
  2420. csb->csb.broken_palette_label =
  2421. XtNewString(csb->csb.broken_palette_label);
  2422. }
  2423. if (csb->csb.broken_palette_message != NULL) {
  2424. csb->csb.broken_palette_message =
  2425. XtNewString(csb->csb.broken_palette_message);
  2426. }
  2427. for (i = 0; i < PALETTE_MAX; i++) {
  2428. if (csb->csb.palette_function[i] != NULL) {
  2429. csb->csb.palette_function[i] =
  2430. XtNewString(csb->csb.palette_function[i]);
  2431. }
  2432. }
  2433. if (csb->csb.num_cells <= 0) csb->csb.num_cells = 1;
  2434. /* Get the context */
  2435. if (csb->csb.context == NULL) {
  2436. csb->csb.context = XDPSGetSharedContext(XtDisplay(csb));
  2437. }
  2438. if (_XDPSTestComponentInitialized(csb->csb.context,
  2439. dps_init_bit_csb, &inited) ==
  2440. dps_status_unregistered_context) {
  2441. XDPSRegisterContext(csb->csb.context, False);
  2442. }
  2443. if (!inited) {
  2444. (void) _XDPSSetComponentInitialized(csb->csb.context,
  2445. dps_init_bit_csb);
  2446. InitializePalettes(csb);
  2447. }
  2448. if (csb->csb.current_palette < 0 ||
  2449. csb->csb.current_palette > PALETTE_MAX ||
  2450. csb->csb.palette_function[csb->csb.current_palette] == NULL) {
  2451. csb->csb.current_palette = 0;
  2452. }
  2453. /* Initialize non-resource fields */
  2454. CreateChildren(csb);
  2455. csb->csb.no_background = False;
  2456. csb->csb.patch_gstate = csb->csb.dock_gstate = 0;
  2457. csb->csb.red_pixmap = csb->csb.green_pixmap = csb->csb.blue_pixmap =
  2458. csb->csb.cyan_pixmap = csb->csb.magenta_pixmap =
  2459. csb->csb.yellow_pixmap = csb->csb.black_pixmap =
  2460. csb->csb.hue_pixmap = csb->csb.sat_pixmap =
  2461. csb->csb.bright_pixmap = csb->csb.gray_pixmap = None;
  2462. csb->csb.square = csb->csb.eyedrop = None;
  2463. csb->csb.eyedrop_grabbed = False;
  2464. for (i = 0; i < PALETTE_MAX; i++) csb->csb.palette_broken[i] = False;
  2465. csb->csb.palette_pixmap_valid = False;
  2466. csb->csb.current_color.hue = 0.0;
  2467. csb->csb.current_color.saturation = 1.0;
  2468. csb->csb.current_color.brightness = 1.0;
  2469. UpdateColorSpaces(csb, CSBSpaceHSB);
  2470. csb->csb.save_color = csb->csb.current_color;
  2471. SetSliders(csb);
  2472. InitializeDock(csb);
  2473. SetColorSpace(csb);
  2474. SetRendering(csb);
  2475. }
  2476. static void Destroy(Widget widget)
  2477. {
  2478. ColorSelectionBoxWidget csb = (ColorSelectionBoxWidget) widget;
  2479. Display *dpy = XtDisplay(csb);
  2480. int i;
  2481. /* Lots of stuff to destroy! */
  2482. if (csb->csb.patch_gstate != 0) {
  2483. XDPSFreeContextGState(csb->csb.context, csb->csb.patch_gstate);
  2484. }
  2485. if (csb->csb.dock_gstate != 0) {
  2486. XDPSFreeContextGState(csb->csb.context, csb->csb.dock_gstate);
  2487. }
  2488. if (csb->csb.base_gstate != 0) {
  2489. XDPSFreeContextGState(csb->csb.context, csb->csb.base_gstate);
  2490. }
  2491. if (csb->csb.rgb_labels != NULL) XtFree(csb->csb.rgb_labels);
  2492. if (csb->csb.cmyk_labels != NULL) XtFree(csb->csb.cmyk_labels);
  2493. if (csb->csb.hsb_labels != NULL) XtFree(csb->csb.hsb_labels);
  2494. if (csb->csb.gray_labels != NULL) XtFree(csb->csb.gray_labels);
  2495. if (csb->csb.fill_me != NULL) XtFree(csb->csb.fill_me);
  2496. if (csb->csb.broken_palette_message != NULL) {
  2497. XtFree(csb->csb.broken_palette_message);
  2498. }
  2499. if (csb->csb.broken_palette_label != NULL) {
  2500. XtFree(csb->csb.broken_palette_label);
  2501. }
  2502. XtFree((XtPointer) csb->csb.dock_cyan);
  2503. XtFree((XtPointer) csb->csb.dock_magenta);
  2504. XtFree((XtPointer) csb->csb.dock_yellow);
  2505. XtFree((XtPointer) csb->csb.dock_black);
  2506. XtFree((XtPointer) csb->csb.dock_used);
  2507. for (i = 0; i < PALETTE_MAX; i++) {
  2508. if (csb->csb.palette_function[i] != NULL) {
  2509. XtFree(csb->csb.palette_function[i]);
  2510. }
  2511. }
  2512. if (csb->csb.eyedrop != None) XFreeCursor(dpy, csb->csb.eyedrop);
  2513. if (csb->csb.square != None) XFreeCursor(dpy, csb->csb.square);
  2514. if (csb->csb.red_pixmap != None) XFreePixmap(dpy, csb->csb.red_pixmap);
  2515. if (csb->csb.green_pixmap != None) XFreePixmap(dpy, csb->csb.green_pixmap);
  2516. if (csb->csb.blue_pixmap != None) XFreePixmap(dpy, csb->csb.blue_pixmap);
  2517. if (csb->csb.cyan_pixmap != None) XFreePixmap(dpy, csb->csb.cyan_pixmap);
  2518. if (csb->csb.magenta_pixmap != None)
  2519. XFreePixmap(dpy, csb->csb.magenta_pixmap);
  2520. if (csb->csb.yellow_pixmap != None)
  2521. XFreePixmap(dpy, csb->csb.yellow_pixmap);
  2522. if (csb->csb.black_pixmap != None) XFreePixmap(dpy, csb->csb.black_pixmap);
  2523. if (csb->csb.hue_pixmap != None) XFreePixmap(dpy, csb->csb.hue_pixmap);
  2524. if (csb->csb.sat_pixmap != None) XFreePixmap(dpy, csb->csb.sat_pixmap);
  2525. if (csb->csb.bright_pixmap != None)
  2526. XFreePixmap(dpy, csb->csb.bright_pixmap);
  2527. if (csb->csb.gray_pixmap != None) XFreePixmap(dpy, csb->csb.gray_pixmap);
  2528. }
  2529. static void ChangeManaged(Widget w)
  2530. {
  2531. ColorSelectionBoxWidget csb = (ColorSelectionBoxWidget) w;
  2532. w->core.width = csb->composite.children[0]->core.width;
  2533. w->core.height = csb->composite.children[0]->core.height;
  2534. }
  2535. /* ARGSUSED */
  2536. static XtGeometryResult GeometryManager(
  2537. Widget w,
  2538. XtWidgetGeometry *desired, XtWidgetGeometry *allowed)
  2539. {
  2540. #define WANTS(flag) (desired->request_mode & flag)
  2541. if (WANTS(XtCWQueryOnly)) return XtGeometryYes;
  2542. if (WANTS(CWWidth)) w->core.width = desired->width;
  2543. if (WANTS(CWHeight)) w->core.height = desired->height;
  2544. if (WANTS(CWX)) w->core.x = desired->x;
  2545. if (WANTS(CWY)) w->core.y = desired->y;
  2546. if (WANTS(CWBorderWidth)) {
  2547. w->core.border_width = desired->border_width;
  2548. }
  2549. return XtGeometryYes;
  2550. #undef WANTS
  2551. }
  2552. static void SetColorSpace(ColorSelectionBoxWidget csb)
  2553. {
  2554. switch(csb->csb.current_space) {
  2555. case CSBSpaceRGB:
  2556. SetRGBCallback((Widget) csb, (XtPointer) csb, (XtPointer) NULL);
  2557. break;
  2558. case CSBSpaceCMYK:
  2559. SetCMYKCallback((Widget) csb, (XtPointer) csb, (XtPointer) NULL);
  2560. break;
  2561. case CSBSpaceHSB:
  2562. SetHSBCallback((Widget) csb, (XtPointer) csb, (XtPointer) NULL);
  2563. break;
  2564. case CSBSpaceGray:
  2565. SetGrayCallback((Widget) csb, (XtPointer) csb, (XtPointer) NULL);
  2566. break;
  2567. }
  2568. }
  2569. static void SetRendering(ColorSelectionBoxWidget csb)
  2570. {
  2571. Widget w;
  2572. switch(csb->csb.current_rendering) {
  2573. default:
  2574. case CSBDisplayDPS:
  2575. w = XtNameToWidget((Widget) csb, "*displayDPS");
  2576. break;
  2577. case CSBDisplayX:
  2578. w = XtNameToWidget((Widget) csb, "*displayX");
  2579. break;
  2580. case CSBDisplayBoth:
  2581. w = XtNameToWidget((Widget) csb, "*displayBoth");
  2582. break;
  2583. }
  2584. XtVaSetValues(csb->csb.display_option_menu_child, XmNmenuHistory, w, NULL);
  2585. if (XtIsRealized(csb->csb.patch_child)) {
  2586. XClearArea(XtDisplay(csb), XtWindow(csb->csb.patch_child),
  2587. 0, 0, 1000, 1000, True);
  2588. }
  2589. }
  2590. static void SetPalette(ColorSelectionBoxWidget csb)
  2591. {
  2592. Widget w;
  2593. char buf[10];
  2594. sprintf(buf, "*palette%d", csb->csb.current_palette);
  2595. w = XtNameToWidget((Widget) csb, buf);
  2596. XtVaSetValues(csb->csb.palette_option_menu_child, XmNmenuHistory, w, NULL);
  2597. csb->csb.palette_pixmap_valid = False;
  2598. DrawPalette(csb);
  2599. }
  2600. static void SetBaseGState(
  2601. ColorSelectionBoxWidget csb,
  2602. Visual *visual)
  2603. {
  2604. XStandardColormap colorCube, grayRamp;
  2605. int match;
  2606. /* If the context's colormap matches the widget's colormap, assume that
  2607. everything is already set up right in the color cube department. This
  2608. allows an application to supply us with a custom color cube by
  2609. installing it in the context before calling us */
  2610. _DPSCColormapMatch(csb->csb.context, csb->core.colormap, &match);
  2611. if (match) {
  2612. XDPSSetContextParameters(csb->csb.context, XtScreen(csb),
  2613. csb->core.depth, XtWindow(csb),
  2614. csb->core.height, NULL, NULL,
  2615. XDPSContextScreenDepth | XDPSContextDrawable);
  2616. } else {
  2617. grayRamp.colormap = colorCube.colormap = csb->core.colormap;
  2618. XDPSCreateStandardColormaps(XtDisplay(csb), XtWindow(csb), visual,
  2619. 0, 0, 0, 0, &colorCube, &grayRamp, False);
  2620. XDPSSetContextParameters(csb->csb.context, XtScreen(csb),
  2621. csb->core.depth, XtWindow(csb),
  2622. csb->core.height,
  2623. (XDPSStandardColormap *) &colorCube,
  2624. (XDPSStandardColormap *) &grayRamp,
  2625. XDPSContextScreenDepth | XDPSContextDrawable |
  2626. XDPSContextRGBMap | XDPSContextGrayMap);
  2627. }
  2628. XDPSCaptureContextGState(csb->csb.context, &csb->csb.base_gstate);
  2629. }
  2630. /* ARGSUSED */
  2631. static Boolean SetValues(
  2632. Widget old, Widget req, Widget new,
  2633. ArgList args,
  2634. Cardinal *num_args)
  2635. {
  2636. ColorSelectionBoxWidget oldcsb = (ColorSelectionBoxWidget) old;
  2637. ColorSelectionBoxWidget newcsb = (ColorSelectionBoxWidget) new;
  2638. Bool inited;
  2639. char buf[10];
  2640. Widget w = 0;
  2641. int i;
  2642. #define NE(field) newcsb->csb.field != oldcsb->csb.field
  2643. if (NE(rgb_labels)) {
  2644. XtFree(oldcsb->csb.rgb_labels);
  2645. newcsb->csb.rgb_labels = XtNewString(newcsb->csb.rgb_labels);
  2646. }
  2647. if (NE(cmyk_labels)) {
  2648. XtFree(oldcsb->csb.cmyk_labels);
  2649. newcsb->csb.cmyk_labels = XtNewString(newcsb->csb.cmyk_labels);
  2650. }
  2651. if (NE(hsb_labels)) {
  2652. XtFree(oldcsb->csb.hsb_labels);
  2653. newcsb->csb.hsb_labels = XtNewString(newcsb->csb.hsb_labels);
  2654. }
  2655. if (NE(gray_labels)) {
  2656. XtFree(oldcsb->csb.gray_labels);
  2657. newcsb->csb.gray_labels = XtNewString(newcsb->csb.gray_labels);
  2658. }
  2659. if (NE(context)) {
  2660. if (newcsb->csb.context == NULL) {
  2661. newcsb->csb.context = XDPSGetSharedContext(XtDisplay(newcsb));
  2662. }
  2663. if (_XDPSTestComponentInitialized(newcsb->csb.context,
  2664. dps_init_bit_csb, &inited) ==
  2665. dps_status_unregistered_context) {
  2666. XDPSRegisterContext(newcsb->csb.context, False);
  2667. }
  2668. if (!inited) {
  2669. (void) _XDPSSetComponentInitialized(newcsb->csb.context,
  2670. dps_init_bit_csb);
  2671. InitializePalettes(newcsb);
  2672. }
  2673. newcsb->csb.patch_gstate = newcsb->csb.dock_gstate = 0;
  2674. XDPSFreeContextGState(newcsb->csb.context, newcsb->csb.patch_gstate);
  2675. XDPSFreeContextGState(newcsb->csb.context, newcsb->csb.dock_gstate);
  2676. if (XtIsRealized(newcsb)) {
  2677. XWindowAttributes xwa;
  2678. XGetWindowAttributes(XtDisplay(newcsb), XtWindow(newcsb), &xwa);
  2679. SetBaseGState(newcsb, xwa.visual);
  2680. }
  2681. }
  2682. if (NE(fill_me)) {
  2683. XtFree(oldcsb->csb.fill_me);
  2684. newcsb->csb.fill_me = XtNewString(newcsb->csb.fill_me);
  2685. }
  2686. if (NE(broken_palette_label)) {
  2687. XtFree(oldcsb->csb.broken_palette_label);
  2688. newcsb->csb.broken_palette_label =
  2689. XtNewString(newcsb->csb.broken_palette_label);
  2690. }
  2691. if (NE(broken_palette_message)) {
  2692. XtFree(oldcsb->csb.broken_palette_message);
  2693. newcsb->csb.broken_palette_message =
  2694. XtNewString(newcsb->csb.broken_palette_message);
  2695. }
  2696. if (newcsb->csb.num_cells <= 0) newcsb->csb.num_cells = 1;
  2697. if (NE(num_cells)) {
  2698. int i, min;
  2699. AllocateDock(newcsb);
  2700. min = MIN(newcsb->csb.num_cells, oldcsb->csb.num_cells);
  2701. for (i = 0; i < min; i++) {
  2702. newcsb->csb.dock_cyan[i] = oldcsb->csb.dock_cyan[i];
  2703. newcsb->csb.dock_magenta[i] = oldcsb->csb.dock_magenta[i];
  2704. newcsb->csb.dock_yellow[i] = oldcsb->csb.dock_yellow[i];
  2705. newcsb->csb.dock_black[i] = oldcsb->csb.dock_black[i];
  2706. newcsb->csb.dock_used[i] = oldcsb->csb.dock_used[i];
  2707. }
  2708. XtFree((XtPointer) oldcsb->csb.dock_cyan);
  2709. XtFree((XtPointer) oldcsb->csb.dock_magenta);
  2710. XtFree((XtPointer) oldcsb->csb.dock_yellow);
  2711. XtFree((XtPointer) oldcsb->csb.dock_black);
  2712. XtFree((XtPointer) oldcsb->csb.dock_used);
  2713. }
  2714. for (i = 0; i < PALETTE_MAX; i++) {
  2715. if (NE(palette_function[i]) || NE(palette_label[i])) {
  2716. sprintf(buf, "*palette%d", i);
  2717. w = XtNameToWidget((Widget) newcsb, buf);
  2718. }
  2719. if (NE(palette_function[i])) {
  2720. if (newcsb->csb.palette_function[i] != NULL) {
  2721. DPSPrintf(newcsb->csb.context,
  2722. "/palette%dfunc%d { %s } bind def\n", i,
  2723. (int) newcsb, newcsb->csb.palette_function[i]);
  2724. /* Assume the best... */
  2725. newcsb->csb.palette_broken[i] = False;
  2726. XtManageChild(w);
  2727. } else {
  2728. XtUnmanageChild(w);
  2729. if (newcsb->csb.current_palette == i) {
  2730. newcsb->csb.current_palette = -1;
  2731. }
  2732. }
  2733. }
  2734. if (NE(palette_label[i]) || NE(palette_function[i])) {
  2735. XtSetSensitive(w, True);
  2736. XtVaSetValues(w, XtVaTypedArg, XmNlabelString, XtRString,
  2737. newcsb->csb.palette_label[i],
  2738. strlen(newcsb->csb.palette_label[i])+1, NULL);
  2739. }
  2740. }
  2741. if (NE(current_palette)) {
  2742. if (newcsb->csb.current_palette < 0 ||
  2743. newcsb->csb.current_palette > PALETTE_MAX ||
  2744. newcsb->csb.palette_function[newcsb->csb.current_palette] == NULL ||
  2745. newcsb->csb.palette_broken[newcsb->csb.current_palette]) {
  2746. newcsb->csb.current_palette = 0;
  2747. }
  2748. }
  2749. if (NE(current_palette) ||
  2750. NE(palette_function[newcsb->csb.current_palette])) SetPalette(newcsb);
  2751. if ((NE(cell_size) || NE(fill_me)) &&
  2752. XtIsRealized(newcsb->csb.dock_child)) {
  2753. XClearArea(XtDisplay(newcsb), XtWindow(newcsb->csb.dock_child),
  2754. 0, 0, 1000, 1000, True);
  2755. }
  2756. if (NE(current_space)) SetColorSpace(newcsb);
  2757. if (NE(current_rendering)) SetRendering(newcsb);
  2758. return False;
  2759. #undef NE
  2760. }
  2761. static void Realize(
  2762. Widget w,
  2763. XtValueMask *mask,
  2764. XSetWindowAttributes *attr)
  2765. {
  2766. ColorSelectionBoxWidget csb = (ColorSelectionBoxWidget) w;
  2767. Visual *v;
  2768. (*colorSelectionBoxClassRec.core_class.superclass->core_class.realize)
  2769. (w, mask, attr);
  2770. GetVisualInfo(csb, &v);
  2771. SetBackground(csb);
  2772. SetBaseGState(csb, v);
  2773. _DPSCGetInvCTM(csb->csb.context, csb->csb.itransform);
  2774. }
  2775. static void Resize(Widget widget)
  2776. {
  2777. ColorSelectionBoxWidget csb = (ColorSelectionBoxWidget) widget;
  2778. XtResizeWidget(csb->csb.form_child, csb->core.width, csb->core.height, 0);
  2779. }
  2780. static Boolean SetColor(
  2781. Widget w,
  2782. CSBColorSpace space,
  2783. double c1, double c2, double c3, double c4,
  2784. Bool setSpace)
  2785. {
  2786. ColorSelectionBoxWidget csb = (ColorSelectionBoxWidget) w;
  2787. #define CHECK(c) if ((c) > 1.0 || (c) < 0.0) return False;
  2788. CHECK(c1);
  2789. switch (space) {
  2790. case CSBSpaceRGB:
  2791. CHECK(c2);
  2792. CHECK(c3);
  2793. csb->csb.current_color.red = c1;
  2794. csb->csb.current_color.green = c2;
  2795. csb->csb.current_color.blue = c3;
  2796. break;
  2797. case CSBSpaceCMYK:
  2798. CHECK(c2);
  2799. CHECK(c3);
  2800. CHECK(c4);
  2801. csb->csb.current_color.cyan = c1;
  2802. csb->csb.current_color.magenta = c2;
  2803. csb->csb.current_color.yellow = c3;
  2804. csb->csb.current_color.black = c4;
  2805. break;
  2806. case CSBSpaceHSB:
  2807. CHECK(c2);
  2808. CHECK(c3);
  2809. csb->csb.current_color.hue = c1;
  2810. csb->csb.current_color.saturation = c2;
  2811. csb->csb.current_color.brightness = c3;
  2812. break;
  2813. case CSBSpaceGray:
  2814. csb->csb.current_color.gray = c1;
  2815. break;
  2816. }
  2817. UpdateColorSpaces(csb, space);
  2818. csb->csb.save_color = csb->csb.current_color;
  2819. DoValueChangedCallback(csb);
  2820. FillPatch(csb);
  2821. SetSliders(csb);
  2822. if (setSpace) XtVaSetValues(w, XtNcurrentSpace, space, NULL);
  2823. return True;
  2824. #undef CHECK
  2825. }
  2826. Boolean CSBSetColor(
  2827. Widget w,
  2828. CSBColorSpace space,
  2829. double c1, double c2, double c3, double c4,
  2830. Bool setSpace)
  2831. {
  2832. XtCheckSubclass(w, colorSelectionBoxWidgetClass, NULL);
  2833. return (*((ColorSelectionBoxWidgetClass) XtClass(w))->
  2834. csb_class.set_color) (w, space, c1, c2, c3, c4, setSpace);
  2835. }
  2836. static void GetColor(
  2837. Widget w,
  2838. CSBColorSpace space,
  2839. float *c1, float *c2, float *c3, float *c4)
  2840. {
  2841. ColorSelectionBoxWidget csb = (ColorSelectionBoxWidget) w;
  2842. switch (space) {
  2843. case CSBSpaceRGB:
  2844. *c1 = csb->csb.current_color.red;
  2845. *c2 = csb->csb.current_color.green;
  2846. *c3 = csb->csb.current_color.blue;
  2847. break;
  2848. case CSBSpaceCMYK:
  2849. *c1 = csb->csb.current_color.cyan;
  2850. *c2 = csb->csb.current_color.magenta;
  2851. *c3 = csb->csb.current_color.yellow;
  2852. *c4 = csb->csb.current_color.black;
  2853. break;
  2854. case CSBSpaceHSB:
  2855. *c1 = csb->csb.current_color.hue;
  2856. *c2 = csb->csb.current_color.saturation;
  2857. *c3 = csb->csb.current_color.brightness;
  2858. break;
  2859. case CSBSpaceGray:
  2860. *c1 = csb->csb.current_color.gray;
  2861. break;
  2862. }
  2863. }
  2864. void CSBGetColor(
  2865. Widget w,
  2866. CSBColorSpace space,
  2867. float *c1, float *c2, float *c3, float *c4)
  2868. {
  2869. XtCheckSubclass(w, colorSelectionBoxWidgetClass, NULL);
  2870. (*((ColorSelectionBoxWidgetClass) XtClass(w))->
  2871. csb_class.get_color) (w, space, c1, c2, c3, c4);
  2872. }