dthelp: Change to ANSI function definitions
[oweals/cde.git] / cde / programs / dtstyle / ColorEdit.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these libraries and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* $XConsortium: ColorEdit.c /main/5 1995/10/30 13:08:03 rswiston $ */
24 /************************************<+>*************************************
25  ***************************************************************************
26  **
27  **   File:        ColorEdit.c
28  **
29  **   Project:     DT 3.0
30  **
31  **   Description: Controls the Dtstyle Color Editor dialog
32  **
33  **
34  **  (c) Copyright Hewlett-Packard Company, 1990.  
35  **
36  **
37  **
38  ****************************************************************************
39  ************************************<+>*************************************/
40 /* +++++++++++++++++++++++++++++++++++++++*/
41 /*  include files                         */
42 /* +++++++++++++++++++++++++++++++++++++++*/
43 #include <X11/cursorfont.h>
44 #include <X11/keysym.h>
45
46 #include <math.h>
47 #include <errno.h>
48
49 #include <X11/Xlib.h>
50 #include <Xm/MwmUtil.h>
51
52 #include <Xm/XmP.h>
53 #include <Xm/LabelG.h>
54 #include <Xm/PushB.h>
55 #include <Xm/PushBG.h>
56 #include <Xm/Form.h>
57 #include <Xm/Scale.h>
58 #include <Xm/VendorSEP.h>
59
60 #include <Dt/DialogBox.h>
61 #include <Dt/TitleBox.h>
62
63 #include <Dt/UserMsg.h>
64
65 #include "Help.h"
66 #include "Main.h"
67 #include "ColorMain.h"
68 #include "ColorFile.h"
69
70 /*+++++++++++++++++++++++++++++++++++++++*/
71 /* include extern functions              */
72 /*+++++++++++++++++++++++++++++++++++++++*/
73 #include "ColorEdit.h"
74
75 /*+++++++++++++++++++++++++++++++++++++++*/
76 /* Local #defines                        */
77 /*+++++++++++++++++++++++++++++++++++++++*/
78 #define  NONE       0
79 #define  RED        1
80 #define  GREEN      2
81 #define  BLUE       3
82 #define  HUE        4
83 #define  SATURATION 5
84 #define  VALUE      6
85
86 #define MAX_STR_LEN   128
87
88 #define SCALE_LEFT_POSITION        10
89 #define BUTTON_MARGIN              10
90 #define OLD_BUTTON_LEFT_POSITION   10
91 #define SCALE_WIDTH                300
92
93 #define SATURATION_BITS                 "Dtsatur"
94 #define VALUE_BITS                      "Dtvalue"
95
96 /*+++++++++++++++++++++++++++++++++++++++*/
97 /* Internal Functions                    */
98 /*+++++++++++++++++++++++++++++++++++++++*/
99
100 static void CreateColorEditor( Widget parent) ;
101 static void sliderLayoutCB( 
102                         Widget w,
103                         XtPointer client_data,
104                         XtPointer call_data) ;
105 static void InitializeNewButton( void ) ;
106 static void InitializeOldButton( void ) ;
107 static void GenerateColors( void ) ;
108 static Pixel GetPixel( Widget widget,
109                        char *color_string ) ;
110 static void changRGB_CB( 
111                         Widget w,
112                         XtPointer client_data,
113                         XtPointer call_data) ;
114 static void changHSV_CB( 
115                         Widget w,
116                         XtPointer client_data,
117                         XtPointer call_data) ;
118 static void SetScales( XColor *rgb) ;
119 static void SetRGBHSVScales( 
120                         XColor *rgb,
121                         int h,
122                         int s,
123                         int v) ;
124 static void CopyPixelSet( 
125                         ColorSet *color_set_dest,
126                         ColorSet *color_set_src) ;
127 static void HSVtoRGB( 
128                         int h,
129                         int s,
130                         int v,
131                         unsigned short *r,
132                         unsigned short *g,
133                         unsigned short *b) ;
134 static double max( 
135                         double x,
136                         double y,
137                         double z) ;
138 static double min( 
139                         double x,
140                         double y,
141                         double z) ;
142 static void grabcolorCB( 
143                         Widget w,
144                         XtPointer client_data,
145                         XtPointer call_data) ;
146 static void dialogBoxCB( 
147                         Widget w,
148                         XtPointer client_data,
149                         XtPointer call_data) ;
150 static void _DtmapCB( 
151                         Widget w,
152                         XtPointer client_data,
153                         XtPointer call_data) ;
154
155
156 /*+++++++++++++++++++++++++++++++++++++++*/
157 /* Global Variables                      */
158 /*+++++++++++++++++++++++++++++++++++++++*/
159 EditData edit;
160
161 /*+++++++++++++++++++++++++++++++++++++++*/
162 /* Internal Variables                    */
163 /*+++++++++++++++++++++++++++++++++++++++*/
164 static saveRestore save = {FALSE, 0, };
165 static OldNewSame = False;
166
167 /************************************************************************
168  *  ColorEditor() - Create ColorEditor dialog first time up.
169  *  If has already been created, set up oldButton and newButton
170  *  colors, set the scale values for the new color and manage 
171  *  the dialog.
172  ************************************************************************/
173 void 
174 ColorEditor(
175         Widget parent,
176         ColorSet *color_set )
177 {
178     if (edit.DialogShell == NULL)
179     {
180         _DtTurnOnHourGlass(parent);  
181         edit.color_set = color_set;
182         CreateColorEditor(parent);   
183         _DtTurnOffHourGlass(parent);  
184     }
185     else 
186     {
187         if (!XtIsManaged(edit.DialogShell))
188         {
189             edit.color_set = color_set;
190             CopyPixelSet(&edit.oldButtonColor,edit.color_set);
191
192                 /* update "old" button if necessary */
193                 if(style.visualClass==TrueColor || style.visualClass==DirectColor){
194                         XtVaSetValues(edit.oldButton,
195                                 XmNbackground,edit.color_set->bg.pixel,
196                                 XmNarmColor,edit.color_set->bg.pixel,
197                                 XmNforeground,edit.color_set->fg.pixel,
198                                 XmNtopShadowColor,edit.color_set->ts.pixel,
199                                 XmNbottomShadowColor,edit.color_set->bs.pixel,NULL);
200                 }
201             InitializeNewButton();
202             SetScales(&edit.color_set->bg);
203             XtManageChild(edit.DialogShell);
204             XMapRaised(style.display, XtWindow(edit.DialogShell));
205         }
206     }
207 }
208
209
210 /************************************************************************
211  *   CreateColorEditor()
212  *           Create the Color Editor Dialog
213  ************************************************************************/
214 static void 
215 CreateColorEditor(
216         Widget parent )
217 {
218         register int     n,i;
219         Arg              args[MAX_ARGS];
220         Widget           sampleTB;
221         Widget           sampleForm;
222         Widget           sliderTB;
223         XmString         string;               /* temp Xm string */
224         Widget           widgetlist1[10];   /* main_form */
225         Widget           widgetlist2[16];   /* sliderForm */
226         Widget           widgetlist3[10];   /* sampleForm */
227         int              widget_count1 = 0;
228         int              widget_count2 = 0;
229         int              widget_count3 = 0;
230         XmString         button_string[NUM_LABELS]; 
231         Pixel            foreground, background;
232         int              height;
233         WidgetList       children;
234         Dimension        w, width_old, width_new;
235
236         edit.current_scale = NONE;
237
238         /* Set up DialogBox button labels. */
239         button_string[0] = CMPSTR((String) _DtOkString);
240         button_string[1] = CMPSTR((String) _DtCancelString);
241         button_string[2] = CMPSTR((String) _DtHelpString);
242
243         /* Note that save.poscnt has been initialized elsewhere.  
244          * save.posArgs may contain information from restoreColorEdit(). */
245
246         XtSetArg(args[save.poscnt], XmNchildType, XmWORK_AREA);  save.poscnt++;
247         XtSetArg(save.posArgs[save.poscnt], XmNbuttonCount, NUM_LABELS);  
248         save.poscnt++;
249         XtSetArg(save.posArgs[save.poscnt], XmNbuttonLabelStrings, 
250                   button_string);  
251         save.poscnt++;
252         XtSetArg(save.posArgs[save.poscnt], XmNdefaultPosition, False);
253         save.poscnt++;
254         edit.DialogShell = __DtCreateDialogBoxDialog(parent,"colorEditDlg", 
255                                                      save.posArgs, save.poscnt);
256         XtAddCallback(edit.DialogShell, XmNmapCallback, sliderLayoutCB, NULL);
257         XtAddCallback(edit.DialogShell, XmNcallback, dialogBoxCB, NULL);
258         XtAddCallback(edit.DialogShell, XmNmapCallback, _DtmapCB, parent);
259         XtAddCallback(edit.DialogShell, XmNhelpCallback,
260             (XtCallbackProc)HelpRequestCB, (XtPointer)HELP_MODIFY_PALETTE_DIALOG);
261
262         XmStringFree(button_string[0]);
263         XmStringFree(button_string[1]);
264         XmStringFree(button_string[2]);
265
266         widgetlist1[0] = _DtDialogBoxGetButton(edit.DialogShell,2);
267
268         n=0;
269         XtSetArg(args[n], XmNautoUnmanage, False); n++;
270         XtSetArg(args[n], XmNcancelButton, widgetlist1[0]); n++;
271         XtSetValues (edit.DialogShell, args, n);
272
273         n=0;
274         XtSetArg (args[n], XmNtitle, ((char *)GETMESSAGE(17, 16, "Style Manager - Modify Color"))); n++;
275         XtSetArg (args[n], XmNuseAsyncGeometry, True); n++;
276         XtSetArg(args[n], XmNmwmFunctions, DIALOG_MWM_FUNC); n++;
277         XtSetValues (XtParent(edit.DialogShell), args, n);
278   
279         n=0;
280         XtSetArg(args[n], XmNhorizontalSpacing, style.horizontalSpacing); n++;
281         XtSetArg(args[n], XmNverticalSpacing, style.verticalSpacing); n++;
282         edit.main_form = XmCreateForm(edit.DialogShell, "main_form", args, n);
283
284         n=0;
285         XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM);  n++;
286         XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM);  n++;
287         XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM);  n++;
288         XtSetArg (args[n], XmNmarginWidth, 0);  n++;
289         XtSetArg (args[n], XmNmarginHeight, 0);  n++;
290         string = CMPSTR(((char *)GETMESSAGE(17, 4, "Color Sample")));
291         XtSetArg (args[n], XmNtitleString, string); n++;
292         sampleTB = _DtCreateTitleBox(edit.main_form, "sampleTB", args, n);
293         widgetlist1[widget_count1++] = sampleTB;
294         XmStringFree(string);
295         
296         n=0;
297         XtSetArg(args[n], XmNhorizontalSpacing, style.horizontalSpacing); n++;
298         XtSetArg(args[n], XmNverticalSpacing, style.verticalSpacing); n++;
299         sampleForm = XmCreateForm(sampleTB, "sampleForm", args, n);
300         
301         /* Create Old and New Buttons */
302                 if(style.visualClass==TrueColor || style.visualClass==DirectColor){
303                         edit.oldButtonColor.bg.pixel = edit.color_set->bg.pixel;
304                         edit.oldButtonColor.fg.pixel = edit.color_set->fg.pixel;
305                         edit.oldButtonColor.sc.pixel = edit.color_set->sc.pixel;
306                         edit.oldButtonColor.bs.pixel = edit.color_set->bs.pixel;
307                         edit.oldButtonColor.ts.pixel = edit.color_set->ts.pixel;
308                         CopyPixelSet(&edit.oldButtonColor,edit.color_set);
309                 }else{
310                         InitializeOldButton();
311                 }
312
313         if(!OldNewSame) {
314            n=0;
315            string =  CMPSTR(((char *)GETMESSAGE(17, 5, "Old")));
316            XtSetArg(args[n], XmNlabelString, string); n++;
317            XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM);  n++;
318            XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM);  n++;
319            XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM);  n++;
320            /* Set the old button color to the color of the selected button */
321            XtSetArg(args[n], XmNforeground, edit.oldButtonColor.fg.pixel); n++;
322            XtSetArg(args[n], XmNbackground, edit.oldButtonColor.bg.pixel); n++;
323            XtSetArg(args[n], XmNarmColor, edit.oldButtonColor.sc.pixel); n++;
324            XtSetArg(args[n], XmNtopShadowColor,
325                                     edit.oldButtonColor.ts.pixel); n++;
326            XtSetArg(args[n], XmNbottomShadowColor, 
327                                     edit.oldButtonColor.bs.pixel); n++;
328
329            edit.oldButton =
330                           XmCreatePushButton(sampleForm, "oldButton", args, n);
331            widgetlist3[widget_count3++] = edit.oldButton;
332            XmStringFree(string);
333         }
334
335         string =  CMPSTR(((char *)GETMESSAGE(17, 6, "New")));
336         n=0;
337         XtSetArg(args[n], XmNlabelString, string); n++;
338         XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM);  n++;
339         if(!OldNewSame) {
340            XtSetArg (args[n], XmNleftAttachment, XmATTACH_WIDGET);  n++;
341            XtSetArg (args[n], XmNleftWidget, edit.oldButton);  n++;
342         }
343         else {
344            XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM);  n++;
345         }
346         XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM);  n++;
347         edit.newButton = XmCreatePushButton(sampleForm, "newButton", args, n);
348         widgetlist3[widget_count3++] = edit.newButton;
349         XmStringFree(string);
350
351         
352         if(!OldNewSame) {
353            /* make old and new button both the size of the larger of the two */
354            width_old = XtWidth(edit.oldButton);
355            width_new = XtWidth(edit.newButton);
356            w = (width_old>width_new) ? width_old : width_new;
357
358            n=0;
359            XtSetArg (args[n], XmNrecomputeSize, False);  n++;
360            XtSetArg (args[n], XmNwidth, w+2*BUTTON_MARGIN);  n++;
361            XtSetArg (args[n], XmNheight, w+2*BUTTON_MARGIN);  n++;
362            XtSetValues(edit.oldButton, args, n);
363            XtSetValues(edit.newButton, args, n);
364         }
365         else
366         {
367            w = XtWidth(edit.newButton);
368
369            n=0;
370            XtSetArg (args[n], XmNrecomputeSize, False);  n++;
371            XtSetArg (args[n], XmNwidth, w+2*BUTTON_MARGIN);  n++;
372            XtSetArg (args[n], XmNheight, w+2*BUTTON_MARGIN);  n++;
373            XtSetValues(edit.newButton, args, n);
374
375         }
376
377         InitializeNewButton();
378
379         n=0;
380         string =  CMPSTR(((char *)GETMESSAGE(17, 7, "Grab Color")));
381         XtSetArg(args[n], XmNlabelString, string); n++;
382         XtSetArg(args[n], XmNnavigationType, XmTAB_GROUP);  n++;
383         XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM);  n++;
384         XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
385         XtSetArg(args[n], XmNmarginHeight, LB_MARGIN_HEIGHT);  n++;
386         XtSetArg(args[n], XmNmarginWidth, LB_MARGIN_WIDTH);  n++;
387         edit.grabColor = XmCreatePushButtonGadget(sampleForm, "grabColor", args, n);
388         widgetlist3[widget_count3++] = edit.grabColor;
389         XtAddCallback(edit.grabColor, XmNactivateCallback, 
390                       grabcolorCB, (XtPointer)NULL);    
391         XmStringFree(string);
392
393         /* Create frame for RGB/HSV scales */
394         n = 0;
395         XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
396         XtSetArg(args[n], XmNtopWidget, sampleTB); n++;
397         XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
398         XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
399         XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
400         XtSetArg (args[n], XmNmarginWidth, 0);  n++;
401         XtSetArg (args[n], XmNmarginHeight, 0);  n++;
402         string =  CMPSTR(((char *)GETMESSAGE(17, 8, "Color Editor")));
403         XtSetArg (args[n], XmNtitleString, string); n++;
404         sliderTB = _DtCreateTitleBox(edit.main_form, "sliderTB", args, n);
405         widgetlist1[widget_count1++] = sliderTB;
406         XmStringFree(string);
407
408         n = 0;
409         XtSetArg(args[n], XmNhorizontalSpacing,  style.horizontalSpacing); n++;
410         XtSetArg(args[n], XmNverticalSpacing,  style.verticalSpacing); n++;
411         edit.sliderForm = XmCreateForm(sliderTB, "sliderForm", args, n);
412
413         /*
414          * Create Hue label and scale
415          */
416
417         n = 0;
418         string = CMPSTR(((char *)GETMESSAGE(17, 9, "Hue")));
419         XtSetArg(args[n], XmNlabelString, string); n++;
420         edit.hueLabel = XmCreateLabelGadget(edit.sliderForm, "hueLabel", args, n);
421         widgetlist2[widget_count2++] = edit.hueLabel;
422         XmStringFree(string);
423
424         n = 0;
425         XtSetArg(args[n], XmNshowValue, TRUE);  n++;
426         XtSetArg(args[n], XmNorientation, XmVERTICAL);  n++;
427         XtSetArg(args[n], XmNprocessingDirection, XmMAX_ON_BOTTOM);  n++;
428         XtSetArg(args[n], XmNhighlightThickness, SCALE_HIGHLIGHT_THICKNESS);  n++; 
429         XtSetArg(args[n], XmNmaximum, 359);  n++;
430         XtSetArg(args[n], XmNminimum, 0x0);  n++;
431         XtSetArg(args[n], XmNincrement, 1); n++;
432         edit.hueScale = XmCreateScale(edit.sliderForm, "hueScale", args, n);
433         widgetlist2[widget_count2++] = edit.hueScale;
434         XtAddCallback(edit.hueScale, XmNvalueChangedCallback, changHSV_CB, (XtPointer) HUE);
435         XtAddCallback(edit.hueScale, XmNdragCallback, changHSV_CB, (XtPointer) HUE );
436
437         /*
438          * Create RGB scales
439          */
440
441         string =  CMPSTR(((char *)GETMESSAGE(17, 10, "R")));
442         n = 0;
443         XtSetArg(args[n], XmNalignment, XmALIGNMENT_END); n++;
444         XtSetArg(args[n], XmNlabelString, string); n++;
445         XtSetArg(args[n], XmNmarginHeight, 0); n++;
446         edit.redLabel = XmCreateLabelGadget(edit.sliderForm, "redLabel", args, n);
447         widgetlist2[widget_count2++] = edit.redLabel;
448         XmStringFree(string);
449
450         string =  CMPSTR(((char *)GETMESSAGE(17, 11, "G")));
451         n = 0;
452         XtSetArg(args[n], XmNalignment, XmALIGNMENT_END); n++;
453         XtSetArg(args[n], XmNlabelString, string); n++;
454         XtSetArg(args[n], XmNmarginHeight, 0); n++;
455         edit.greenLabel = XmCreateLabelGadget(edit.sliderForm, "greenLabel", args, n);
456         widgetlist2[widget_count2++] = edit.greenLabel;
457         XmStringFree(string);
458
459         string =  CMPSTR(((char *)GETMESSAGE(17, 12, "B")));
460         n = 0;
461         XtSetArg(args[n], XmNalignment, XmALIGNMENT_END); n++;
462         XtSetArg(args[n], XmNlabelString, string); n++;
463         XtSetArg(args[n], XmNmarginHeight, 0); n++;
464         edit.blueLabel = XmCreateLabelGadget(edit.sliderForm, "blueLabel", args, n);
465         widgetlist2[widget_count2++] = edit.blueLabel;
466         XmStringFree(string);
467
468         n = 0;
469         XtSetArg(args[n], XmNshowValue, TRUE);  n++;
470         XtSetArg(args[n], XmNorientation, XmHORIZONTAL);  n++;
471         XtSetArg(args[n], XmNprocessingDirection, XmMAX_ON_RIGHT);  n++;
472         XtSetArg(args[n], XmNhighlightThickness, SCALE_HIGHLIGHT_THICKNESS);  n++; 
473         XtSetArg(args[n], XmNmaximum, 0xff);  n++;
474         XtSetArg(args[n], XmNminimum, 0x0);  n++;
475         XtSetArg(args[n], XmNincrement, 1); n++;
476         XtSetArg(args[n], XmNscaleWidth, SCALE_WIDTH); n++; 
477         widgetlist2[widget_count2++] = edit.redScale = 
478                 XmCreateScale(edit.sliderForm, "redScale", args, n);
479         XtAddCallback(edit.redScale, XmNvalueChangedCallback, changRGB_CB, (XtPointer) RED);
480         XtAddCallback(edit.redScale, XmNdragCallback, changRGB_CB, (XtPointer) RED );
481
482         widgetlist2[widget_count2++] = edit.greenScale = 
483                 XmCreateScale(edit.sliderForm, "greenScale", args, n);
484         XtAddCallback(edit.greenScale, XmNvalueChangedCallback, changRGB_CB, (XtPointer) GREEN );
485         XtAddCallback(edit.greenScale, XmNdragCallback, changRGB_CB, (XtPointer) GREEN );
486
487         widgetlist2[widget_count2++] = edit.blueScale = 
488                 XmCreateScale(edit.sliderForm, "blueScale", args, n);
489         XtAddCallback(edit.blueScale, XmNvalueChangedCallback, changRGB_CB, (XtPointer) BLUE );
490         XtAddCallback(edit.blueScale, XmNdragCallback, changRGB_CB, (XtPointer) BLUE);
491
492         /*
493          * Create SV scales
494          */
495
496         /* create Saturation pixmap */
497         n=0;
498         XtSetArg(args[n], XmNforeground, &foreground); n++;
499         XtSetArg(args[n], XmNbackground, &background); n++;
500         XtGetValues(edit.sliderForm, args, n);
501
502         n = 0;
503         XtSetArg(args[n], XmNalignment, XmALIGNMENT_END); n++;
504         XtSetArg(args[n], XmNlabelType, XmPIXMAP); n++;
505         XtSetArg(args[n], XmNlabelPixmap, XmGetPixmap(style.screen, SATURATION_BITS,
506                                      foreground, background)); n++;
507         XtSetArg(args[n], XmNmarginHeight, 3); n++;
508         edit.satLabel = XmCreateLabelGadget(edit.sliderForm, "satLabel", args, n);
509         widgetlist2[widget_count2++] = edit.satLabel;
510
511         /* create Value pixmap */
512         n = 0;
513         XtSetArg(args[n], XmNalignment, XmALIGNMENT_END); n++;
514         XtSetArg(args[n], XmNlabelType, XmPIXMAP); n++;
515         XtSetArg(args[n], XmNlabelPixmap, XmGetPixmap(style.screen, VALUE_BITS,
516                                         foreground, background)); n++;
517         XtSetArg(args[n], XmNmarginHeight, 3); n++;
518         edit.valLabel = XmCreateLabelGadget(edit.sliderForm, "valLabel", args, n);
519         widgetlist2[widget_count2++] = edit.valLabel;
520
521         n = 0;
522         XtSetArg(args[n], XmNshowValue, TRUE);  n++;
523         XtSetArg(args[n], XmNorientation, XmHORIZONTAL);  n++;
524         XtSetArg(args[n], XmNprocessingDirection, XmMAX_ON_RIGHT);  n++;
525         XtSetArg(args[n], XmNhighlightThickness, SCALE_HIGHLIGHT_THICKNESS);  n++; 
526         XtSetArg(args[n], XmNmaximum, 0xff);  n++;
527         XtSetArg(args[n], XmNminimum, 0x0);  n++;
528         XtSetArg(args[n], XmNincrement, 1); n++;
529         XtSetArg(args[n], XmNscaleWidth, SCALE_WIDTH); n++; 
530         widgetlist2[widget_count2++] = edit.satScale = 
531                 XmCreateScale(edit.sliderForm, "satScale", args, n);
532         XtAddCallback(edit.satScale, XmNvalueChangedCallback, changHSV_CB, (XtPointer) SATURATION);
533         XtAddCallback(edit.satScale, XmNdragCallback, changHSV_CB, (XtPointer) SATURATION );
534
535         widgetlist2[widget_count2++] = edit.valScale = 
536                 XmCreateScale(edit.sliderForm, "valScale", args, n);
537         XtAddCallback(edit.valScale, XmNvalueChangedCallback, changHSV_CB, (XtPointer) VALUE);
538         XtAddCallback(edit.valScale, XmNdragCallback, changHSV_CB, (XtPointer) VALUE );
539
540         /* Set the scales to the bg component of the selected color */
541         SetScales(&edit.color_set->bg);
542
543         /* Do all the mapping */
544
545         XtManageChildren(widgetlist3, widget_count3);
546         XtManageChild(sampleForm);
547
548         XtManageChildren(widgetlist2, widget_count2);
549         XtManageChild(edit.sliderForm);
550
551         XtManageChildren(widgetlist1, widget_count1);
552         XtManageChild(edit.main_form);
553
554         XtManageChild(edit.DialogShell);  
555
556         if(TypeOfMonitor == XmCO_HIGH_COLOR)
557         {
558            /* set the trough colors of the RGB scales -
559               get the composite children of the scales - 
560                           child[1] is the scrollbar */
561            n=0;
562            XtSetArg(args[n], XtNchildren, &children); n++;
563            XtGetValues(edit.redScale, args, n);
564            n=0;
565            XtSetArg(args[n], XmNtroughColor, GetPixel(edit.main_form,"red"));  n++;
566            XtSetValues (children[1], args, n);
567
568            n=0;
569            XtSetArg(args[n], XtNchildren, &children); n++;
570            XtGetValues(edit.greenScale, args, n);
571            n=0;
572            XtSetArg(args[n], XmNtroughColor, GetPixel(edit.main_form,"green"));  n++; 
573            XtSetValues (children[1], args, n);
574
575            n=0;
576            XtSetArg(args[n], XtNchildren, &children); n++;
577            XtGetValues(edit.blueScale, args, n);
578            n=0;
579            XtSetArg(args[n], XmNtroughColor, GetPixel(edit.main_form,"blue"));  n++; 
580            XtSetValues (children[1], args, n);
581         }
582
583 }
584
585
586 static void 
587 sliderLayoutCB(
588         Widget w,
589         XtPointer client_data,
590         XtPointer call_data )
591 {
592         register int     n;
593         Arg              args[12];
594         Dimension        redLabelWidth;
595         Dimension        greenLabelWidth;
596         Dimension        blueLabelWidth;
597         Dimension        satLabelWidth;
598         Dimension        valLabelWidth;
599         Dimension        MaxLabelWidth;
600         Dimension        redLabelHeight;
601         Dimension        satLabelHeight;
602         Dimension        valLabelHeight;
603         Dimension        redScaleHeight;
604         Dimension        TopOffset;
605         Dimension        scale_width;
606         Dimension        pieces;
607
608
609         /* 
610          * Do the scale and label attachments
611          */
612
613         redLabelHeight = XtHeight(edit.redLabel);
614         MaxLabelWidth = redLabelWidth = XtWidth(edit.redLabel);
615
616         greenLabelWidth = XtWidth(edit.greenLabel);
617         if (greenLabelWidth > MaxLabelWidth) 
618         {
619             MaxLabelWidth = greenLabelWidth;
620         }
621         
622         blueLabelWidth = XtWidth(edit.blueLabel);
623         if (blueLabelWidth > MaxLabelWidth) 
624         {
625             MaxLabelWidth = blueLabelWidth;
626         }
627         
628         satLabelHeight = XtHeight(edit.satLabel);
629         satLabelWidth = XtWidth(edit.satLabel);
630         if (satLabelWidth > MaxLabelWidth) 
631         {
632             MaxLabelWidth = satLabelWidth;
633         }
634
635         valLabelHeight = XtHeight(edit.valLabel);
636         valLabelWidth = XtWidth(edit.valLabel);
637         if (valLabelWidth > MaxLabelWidth) 
638         {
639             MaxLabelWidth = valLabelWidth;
640         }
641         
642         redScaleHeight = XtHeight(edit.redScale);
643
644
645         /* Attach grab button to New button if they are overlapping */
646
647         if(!OldNewSame)  
648             pieces = XtWidth(edit.oldButton) +
649                      XtWidth(edit.newButton) +
650                      XtWidth(edit.grabColor) +
651                      4*style.horizontalSpacing;
652         else
653             pieces = XtWidth(edit.newButton) +
654                      XtWidth(edit.grabColor) +
655                      3*style.horizontalSpacing;
656         
657         if (XtWidth(edit.main_form) < pieces)
658         {
659             n=0;
660             XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET);  n++;
661             XtSetArg(args[n], XmNleftWidget, edit.newButton);  n++;
662             XtSetValues (edit.grabColor, args, n);
663
664             scale_width = XtWidth(edit.main_form) - MaxLabelWidth - 
665                           XtWidth(edit.hueScale) - 4*style.horizontalSpacing;
666
667             n=0;
668             XtSetArg(args[n], XmNscaleWidth, scale_width); n++; 
669             XtSetValues (edit.redScale, args, n);
670             XtSetValues (edit.greenScale, args, n);
671             XtSetValues (edit.blueScale, args, n);
672             XtSetValues (edit.satScale, args, n);
673             XtSetValues (edit.valScale, args, n);
674         }
675
676         /* Hue Label */
677         n=0;
678         XtSetArg(args[n], XmNtopAttachment,    XmATTACH_FORM); n++;
679         XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++;
680         XtSetArg(args[n], XmNleftAttachment,   XmATTACH_NONE); n++;
681         XtSetArg(args[n], XmNrightAttachment,  XmATTACH_FORM); n++;
682         XtSetValues (edit.hueLabel, args, n);
683
684         /* Hue Scale */
685         n=0;
686         XtSetArg(args[n], XmNtopAttachment,    XmATTACH_WIDGET); n++;
687         XtSetArg(args[n], XmNtopWidget, edit.hueLabel); n++;
688         XtSetArg(args[n], XmNtopOffset, style.verticalSpacing); n++;
689         XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
690         XtSetArg(args[n], XmNbottomOffset, 
691             2*(style.verticalSpacing + redScaleHeight) + 40); n++;
692         XtSetArg(args[n], XmNleftAttachment,   XmATTACH_NONE); n++;
693         XtSetArg(args[n], XmNrightAttachment,  XmATTACH_FORM); n++;
694         XtSetValues (edit.hueScale, args, n);
695
696         /* Red Label */
697         n=0;
698         XtSetArg(args[n], XmNtopAttachment,    XmATTACH_WIDGET); n++;
699         XtSetArg(args[n], XmNtopWidget, edit.hueLabel); n++;
700         TopOffset = style.verticalSpacing + redScaleHeight - redLabelHeight;
701         XtSetArg(args[n], XmNtopOffset, TopOffset); n++;
702         XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++;
703         XtSetArg(args[n], XmNleftAttachment,   XmATTACH_FORM); n++;
704         XtSetArg(args[n], XmNleftOffset, 
705             style.horizontalSpacing + (MaxLabelWidth - redLabelWidth)); n++;
706         XtSetArg(args[n], XmNrightAttachment,  XmATTACH_NONE); n++;
707         XtSetValues (edit.redLabel, args, n);
708
709         /* Green Label */
710         n=0;
711         XtSetArg(args[n], XmNtopAttachment,    XmATTACH_WIDGET); n++;
712         XtSetArg(args[n], XmNtopWidget, edit.redLabel); n++;
713         XtSetArg(args[n], XmNtopOffset, TopOffset); n++;
714         XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++;
715         XtSetArg(args[n], XmNleftAttachment,   XmATTACH_FORM); n++;
716         XtSetArg(args[n], XmNleftOffset, 
717             style.horizontalSpacing + (MaxLabelWidth - greenLabelWidth)); n++;
718         XtSetArg(args[n], XmNrightAttachment,  XmATTACH_NONE); n++;
719         XtSetValues (edit.greenLabel, args, n);
720
721         /* Blue Label */
722         n=0;
723         XtSetArg(args[n], XmNtopAttachment,    XmATTACH_WIDGET); n++;
724         XtSetArg(args[n], XmNtopWidget, edit.greenLabel); n++;
725         XtSetArg(args[n], XmNtopOffset, TopOffset); n++;
726         XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++;
727         XtSetArg(args[n], XmNleftAttachment,   XmATTACH_FORM); n++;
728         XtSetArg(args[n], XmNleftOffset, 
729             style.horizontalSpacing + (MaxLabelWidth - blueLabelWidth)); n++;
730         XtSetArg(args[n], XmNrightAttachment,  XmATTACH_NONE); n++;
731         XtSetValues (edit.blueLabel, args, n);
732
733         /* Saturation Label */
734         n=0;
735         XtSetArg(args[n], XmNtopAttachment,    XmATTACH_WIDGET); n++;
736         XtSetArg(args[n], XmNtopWidget, edit.blueLabel); n++;
737         TopOffset = style.verticalSpacing + 40 + redScaleHeight - satLabelHeight;
738         XtSetArg(args[n], XmNtopOffset, TopOffset); n++;
739         XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++;
740         XtSetArg(args[n], XmNleftAttachment,   XmATTACH_FORM); n++;
741         XtSetArg(args[n], XmNleftOffset, 
742             style.horizontalSpacing + (MaxLabelWidth - satLabelWidth)); n++;
743         XtSetArg(args[n], XmNrightAttachment,  XmATTACH_NONE); n++;
744         XtSetValues (edit.satLabel, args, n);
745
746         /* Value Label */
747         n=0;
748         XtSetArg(args[n], XmNtopAttachment,    XmATTACH_WIDGET); n++;
749         XtSetArg(args[n], XmNtopWidget, edit.satLabel); n++;
750         TopOffset = style.verticalSpacing + redScaleHeight - valLabelHeight;
751         XtSetArg(args[n], XmNtopOffset, TopOffset); n++;
752         XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
753         XtSetArg(args[n], XmNleftAttachment,   XmATTACH_FORM); n++;
754         XtSetArg(args[n], XmNleftOffset, 
755             style.horizontalSpacing + (MaxLabelWidth - valLabelWidth)); n++;
756         XtSetArg(args[n], XmNrightAttachment,  XmATTACH_NONE); n++;
757         XtSetValues (edit.valLabel, args, n);
758
759         /* Red Scale */
760         n=0;
761         XtSetArg(args[n], XmNtopAttachment,    XmATTACH_NONE); n++;
762         XtSetArg(args[n], XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET); n++;
763         XtSetArg(args[n], XmNbottomWidget, edit.redLabel); n++;
764         XtSetArg(args[n], XmNbottomOffset,  0); n++;
765         XtSetArg(args[n], XmNleftAttachment,   XmATTACH_WIDGET); n++;
766         XtSetArg(args[n], XmNleftWidget, edit.redLabel); n++;
767         XtSetArg(args[n], XmNleftOffset,  style.horizontalSpacing); n++;
768         XtSetArg(args[n], XmNrightAttachment,  XmATTACH_WIDGET); n++;
769         XtSetArg(args[n], XmNrightWidget, edit.hueScale); n++;
770         XtSetValues (edit.redScale, args, n);
771
772         /* Green Scale */
773         n=0;
774         XtSetArg(args[n], XmNtopAttachment,    XmATTACH_NONE); n++;
775         XtSetArg(args[n], XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET); n++;
776         XtSetArg(args[n], XmNbottomWidget, edit.greenLabel); n++;
777         XtSetArg(args[n], XmNbottomOffset,  0); n++;
778         XtSetArg(args[n], XmNleftAttachment,   XmATTACH_WIDGET); n++;
779         XtSetArg(args[n], XmNleftWidget, edit.redLabel); n++;
780         XtSetArg(args[n], XmNleftOffset,  style.horizontalSpacing); n++;
781         XtSetArg(args[n], XmNrightAttachment,  XmATTACH_WIDGET); n++;
782         XtSetArg(args[n], XmNrightWidget, edit.hueScale); n++;
783         XtSetValues (edit.greenScale, args, n);
784
785         /* Blue Scale */
786         n=0;
787         XtSetArg(args[n], XmNtopAttachment,    XmATTACH_NONE); n++;
788         XtSetArg(args[n], XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET); n++;
789         XtSetArg(args[n], XmNbottomWidget, edit.blueLabel); n++;
790         XtSetArg(args[n], XmNbottomOffset,  0); n++;
791         XtSetArg(args[n], XmNleftAttachment,   XmATTACH_WIDGET); n++;
792         XtSetArg(args[n], XmNleftWidget, edit.redLabel); n++;
793         XtSetArg(args[n], XmNleftOffset,  style.horizontalSpacing); n++;
794         XtSetArg(args[n], XmNrightAttachment,  XmATTACH_WIDGET); n++;
795         XtSetArg(args[n], XmNrightWidget, edit.hueScale); n++;
796         XtSetValues (edit.blueScale, args, n);
797
798         /* Saturation Scale */
799         n=0;
800         XtSetArg(args[n], XmNtopAttachment,    XmATTACH_NONE); n++;
801         XtSetArg(args[n], XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET); n++;
802         XtSetArg(args[n], XmNbottomWidget, edit.satLabel); n++;
803         XtSetArg(args[n], XmNbottomOffset,  0); n++;
804         XtSetArg(args[n], XmNleftAttachment,   XmATTACH_WIDGET); n++;
805         XtSetArg(args[n], XmNleftWidget, edit.redLabel); n++;
806         XtSetArg(args[n], XmNleftOffset,  style.horizontalSpacing); n++;
807         XtSetArg(args[n], XmNrightAttachment,  XmATTACH_WIDGET); n++;
808         XtSetArg(args[n], XmNrightWidget, edit.hueScale); n++;
809         XtSetValues (edit.satScale, args, n);
810
811         /* Value Scale */
812         n=0;
813         XtSetArg(args[n], XmNtopAttachment,    XmATTACH_NONE); n++;
814         XtSetArg(args[n], XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET); n++;
815         XtSetArg(args[n], XmNbottomWidget, edit.valLabel); n++;
816         XtSetArg(args[n], XmNbottomOffset,  0); n++;
817         XtSetArg(args[n], XmNleftAttachment,   XmATTACH_WIDGET); n++;
818         XtSetArg(args[n], XmNleftWidget, edit.redLabel); n++;
819         XtSetArg(args[n], XmNleftOffset,  style.horizontalSpacing); n++;
820         XtSetArg(args[n], XmNrightAttachment,  XmATTACH_WIDGET); n++;
821         XtSetArg(args[n], XmNrightWidget, edit.hueScale); n++;
822         XtSetValues (edit.valScale, args, n);
823
824         XtRemoveCallback(edit.DialogShell, XmNmapCallback, sliderLayoutCB, NULL);
825
826 }
827
828
829 /************************************************************************
830  *   InitializeNewButton()
831  *           set NewButton colors to point to the PixelSet being
832  *           modified so they both get updated.
833  ************************************************************************/
834 static void 
835 InitializeNewButton( void )
836 {
837         register int     n;
838         Arg              args[6];
839
840         n=0;
841         XtSetArg(args[n], XmNforeground, edit.color_set->fg.pixel); n++;
842         XtSetArg(args[n], XmNbackground, edit.color_set->bg.pixel); n++;
843         XtSetArg(args[n], XmNarmColor, edit.color_set->sc.pixel); n++;
844         if(UsePixmaps == FALSE)
845         {
846            XtSetArg(args[n], XmNtopShadowColor, 
847                                       edit.color_set->ts.pixel); n++;
848            XtSetArg(args[n], XmNbottomShadowColor, 
849                                       edit.color_set->bs.pixel); n++;
850         }
851         XtSetValues(edit.newButton,args,n);
852 }
853
854
855 /************************************************************************
856  *   InitializeOldButton()
857  *           Called only once from CreateColorEditor.  Allocates a
858  *           new PixelSet to hold onto the original ColorSet values
859  *           while the newButton gets updated.  Shouldn't be called if
860  *           monitor is B_W.
861  ************************************************************************/
862 static void 
863 InitializeOldButton( void )
864 {
865     register int     i,n, numOfPixels;
866     unsigned long    *pixels;
867     unsigned long    plane_mask;
868     int              hue, val, sat, status;
869
870     if(UsePixmaps == FALSE)
871        if(FgColor == DYNAMIC)
872           numOfPixels = 5;
873        else /* FgColor == BLACK or WHITE */
874           numOfPixels = 4;
875     else  /* UsePixmaps == TRUE */
876        if(FgColor == DYNAMIC)
877           numOfPixels = 3;
878        else /* FgColor == BLACK or WHITE */
879           numOfPixels = 2;
880
881    /* Allocate enough space to store numOfPixels. */
882      pixels = (unsigned long *)XtMalloc (numOfPixels * sizeof (unsigned long));
883
884    /* Allocate new color cells for the new button */
885      status = XAllocColorCells (style.display, style.colormap,
886                           0, &plane_mask, 0, pixels, numOfPixels);
887      
888      if(status == FALSE)
889      {
890       /* Dialog stating that can't allocate enough pixels to color 
891          the old button. Just don't create old button.*/
892          edit.oldButtonColor.bg.pixel = edit.color_set->bg.pixel;
893          edit.oldButtonColor.bg.flags = edit.color_set->bg.flags;
894          edit.oldButtonColor.fg.pixel = edit.color_set->fg.pixel;
895          edit.oldButtonColor.fg.flags = edit.color_set->fg.flags;
896          edit.oldButtonColor.sc.pixel = edit.color_set->sc.pixel;
897          edit.oldButtonColor.sc.flags = edit.color_set->sc.flags;
898          edit.oldButtonColor.bs.pixel = edit.color_set->bs.pixel;
899          edit.oldButtonColor.bs.flags = edit.color_set->bs.flags;
900          edit.oldButtonColor.ts.pixel = edit.color_set->ts.pixel;
901          edit.oldButtonColor.ts.flags = edit.color_set->ts.flags;
902          OldNewSame = True;
903      }
904      else
905      {
906
907        /*  Assign the pixels */
908          n=0;
909          edit.oldButtonColor.bg.pixel = pixels[n++];
910          edit.oldButtonColor.bg.flags = DoRed | DoGreen | DoBlue;
911          edit.oldButtonColor.sc.pixel = pixels[n++];
912          edit.oldButtonColor.sc.flags = DoRed | DoGreen | DoBlue;
913          if(FgColor == DYNAMIC)
914          {
915             edit.oldButtonColor.fg.pixel = pixels[n++];
916             edit.oldButtonColor.fg.flags = DoRed | DoGreen | DoBlue;
917          } 
918          else
919          {
920             edit.oldButtonColor.fg.pixel = edit.color_set->fg.pixel;
921             edit.oldButtonColor.fg.flags = edit.color_set->fg.flags;
922          }
923          if(UsePixmaps == FALSE)
924          {
925             edit.oldButtonColor.bs.pixel = pixels[n++];
926             edit.oldButtonColor.bs.flags = DoRed | DoGreen | DoBlue;
927             edit.oldButtonColor.ts.pixel = pixels[n];
928             edit.oldButtonColor.ts.flags = DoRed | DoGreen | DoBlue;
929          }
930          else
931          {
932             edit.oldButtonColor.bs.pixel = edit.color_set->bs.pixel;
933             edit.oldButtonColor.bs.flags = edit.color_set->bs.flags;
934             edit.oldButtonColor.ts.pixel = edit.color_set->ts.pixel;
935             edit.oldButtonColor.ts.flags = edit.color_set->ts.flags;
936          }
937      }
938
939     CopyPixelSet(&edit.oldButtonColor,edit.color_set);
940     
941     RGBtoHSV(edit.oldButtonColor.bg.red, 
942              edit.oldButtonColor.bg.green, 
943              edit.oldButtonColor.bg.blue, 
944              &hue, &sat, &val);
945     
946     XtFree((char *)pixels);
947 }
948
949 /************************************************************************
950  *   GenerateColors()
951  *           Generates new RGB values for fg, ts, bs, sc based on bg.
952  *           The Color generation routine will be exported in motif1.1
953  *           The generated colors are then used to update the pixels
954  *           of the ColorSet being edited.
955  ************************************************************************/
956 static void 
957 GenerateColors( void )
958 {
959     int hue, sat, val;
960     int         j=0;
961     XColor      colors[5];
962
963     if (edit.calcRGB == NULL) 
964         edit.calcRGB = XmGetColorCalculation();
965
966     (*edit.calcRGB) (&edit.color_set->bg, &edit.color_set->fg, 
967                      &edit.color_set->sc, &edit.color_set->ts, 
968                      &edit.color_set->bs);
969
970     RGBtoHSV(edit.color_set->bg.red, edit.color_set->bg.green,
971                 edit.color_set->bg.blue,
972                 &hue, &sat, &val);
973
974     colors[j++] =  edit.color_set->bg;
975     colors[j++] =  edit.color_set->sc;
976
977     if (FgColor == DYNAMIC)
978         colors[j++] =  edit.color_set->fg;
979
980     if(UsePixmaps == FALSE)
981     {
982        colors[j++] =  edit.color_set->ts;
983        colors[j++] =  edit.color_set->bs;
984     }
985     else
986     {
987         edit.color_set->ts.red = 65535;
988         edit.color_set->ts.green = 65535;
989         edit.color_set->ts.blue = 65535;
990
991         edit.color_set->bs.red = 0;
992         edit.color_set->bs.green = 0;
993         edit.color_set->bs.blue = 0;
994     }
995
996     if(style.visualClass==PseudoColor || style.visualClass==StaticColor)
997         {
998                 XStoreColors(style.display, style.colormap, colors, j );
999         }
1000         else if(style.visualClass==TrueColor || style.visualClass==DirectColor)
1001         {
1002                 static unsigned long pixels[4];
1003                 static int count=0;
1004
1005                 if(count){
1006                         XFreeColors(style.display,style.colormap,pixels,count,0);
1007                         count=0;
1008                 }
1009
1010                 if(XAllocColor(style.display,style.colormap,&edit.color_set->fg))
1011                         pixels[count++]=edit.color_set->fg.pixel;
1012                 if(XAllocColor(style.display,style.colormap,&edit.color_set->bg))
1013                         pixels[count++]=edit.color_set->bg.pixel;
1014                 if(XAllocColor(style.display,style.colormap,&edit.color_set->ts))
1015                         pixels[count++]=edit.color_set->ts.pixel;
1016                 if(XAllocColor(style.display,style.colormap,&edit.color_set->bs))
1017                         pixels[count++]=edit.color_set->bs.pixel;
1018
1019                 XtVaSetValues(edit.newButton,
1020                         XmNbackground,edit.color_set->bg.pixel,
1021                         XmNarmColor,edit.color_set->bg.pixel,
1022                         XmNforeground,edit.color_set->fg.pixel,
1023                         XmNtopShadowColor,edit.color_set->ts.pixel,
1024                         XmNbottomShadowColor,edit.color_set->bs.pixel,NULL);
1025         }
1026  }
1027
1028 /************************************************************************
1029  *   changeRGB_CB()
1030  *           Called when one of the RGB scales is moved
1031  ************************************************************************/
1032 static void 
1033 changRGB_CB(
1034         Widget w,
1035         XtPointer client_data,
1036         XtPointer call_data )
1037 {
1038     int reason_code;
1039     int value;
1040     int color;
1041
1042     reason_code = ((XmAnyCallbackStruct *)call_data)->reason;
1043     if ( reason_code == XmCR_VALUE_CHANGED || reason_code == XmCR_DRAG )
1044     {
1045         color = (int) (intptr_t) client_data;
1046         value = ((XmScaleCallbackStruct *)call_data)->value;
1047
1048         if (edit.current_scale == NONE)
1049         {
1050             edit.current_scale = color;       
1051             /*
1052              * Shift value -- to make up for scale max of only 0xff
1053              */
1054             value <<= 8;
1055             switch (color)
1056             {
1057                   case RED:
1058                       edit.color_set->bg.red = value;
1059                       break;
1060                   case GREEN:
1061                       edit.color_set->bg.green = value;
1062                       break;
1063                   case BLUE:
1064                       edit.color_set->bg.blue = value;
1065                       break;
1066                   default:
1067                       /* this case should never be hit */
1068                       return;
1069             }
1070
1071             SetScales(&edit.color_set->bg);
1072             GenerateColors();
1073             edit.current_scale = NONE;
1074         }
1075     }
1076 }
1077
1078
1079 /************************************************************************
1080  *   changHSV_CB()
1081  *           Called when one of the HSV scales is moved
1082  ************************************************************************/
1083 static void 
1084 changHSV_CB(
1085         Widget w,
1086         XtPointer client_data,
1087         XtPointer call_data )
1088 {
1089     int reason_code;
1090     int value;
1091     int scale;
1092     int hue, sat, val;
1093
1094     reason_code = ((XmAnyCallbackStruct *)call_data)->reason;
1095     if ( reason_code == XmCR_VALUE_CHANGED || reason_code == XmCR_DRAG )
1096     {
1097         scale = (int) (intptr_t) client_data;
1098         value = ((XmScaleCallbackStruct *)call_data)->value;
1099
1100         if (edit.current_scale == NONE)
1101         {
1102             edit.current_scale = scale;       
1103             switch (scale)
1104             {
1105                   case HUE:
1106                      hue = value;
1107                      XmScaleGetValue(edit.satScale, &sat);
1108                      XmScaleGetValue(edit.valScale, &val);
1109                      break;
1110                   case SATURATION:
1111                      XmScaleGetValue(edit.hueScale, &hue);
1112                      sat = value;
1113                      XmScaleGetValue(edit.valScale, &val);
1114                      break;
1115                   case VALUE:
1116                      XmScaleGetValue(edit.hueScale, &hue);
1117                      XmScaleGetValue(edit.satScale, &sat);
1118                      val = value;
1119                      break;
1120                   default:
1121                      /* this case should never be hit */
1122                      return;
1123             }
1124
1125             HSVtoRGB(hue, sat, val, 
1126                      &edit.color_set->bg.red, 
1127                      &edit.color_set->bg.green,
1128                      &edit.color_set->bg.blue);
1129
1130             SetRGBHSVScales(&edit.color_set->bg, hue, sat, val);
1131             GenerateColors();
1132             edit.current_scale = NONE;
1133         }      
1134      }
1135 }
1136
1137
1138 /************************************************************************
1139  *   SetScales()
1140  *           passed a XColor, generates HSV values and updates all scales.
1141  ************************************************************************/
1142 static void 
1143 SetScales(
1144         XColor *rgb )
1145 {
1146         int      h, s, v;
1147
1148         RGBtoHSV(rgb->red, rgb->green, rgb->blue, &h, &s, &v);
1149
1150         SetRGBHSVScales(rgb, h, s, v);
1151 }
1152
1153
1154 /************************************************************************
1155  *   SetRGBHSVScales()
1156  *           updates RGB and HSV scales
1157  ************************************************************************/
1158 static void 
1159 SetRGBHSVScales(
1160         XColor *rgb,
1161         int h,
1162         int s,
1163         int v )
1164 {
1165         XmScaleSetValue(edit.redScale,rgb->red >> 8);
1166         XmScaleSetValue(edit.greenScale,rgb->green >> 8);
1167         XmScaleSetValue(edit.blueScale,rgb->blue >> 8);
1168
1169         XmScaleSetValue(edit.hueScale,h);
1170         XmScaleSetValue(edit.satScale,s);
1171         XmScaleSetValue(edit.valScale,v);
1172 }
1173
1174
1175 /************************************************************************
1176  *   CopyPixelSet()
1177  *   
1178  ************************************************************************/
1179 static void 
1180 CopyPixelSet(
1181         ColorSet *color_set_dest,
1182         ColorSet *color_set_src )
1183 {
1184     Arg          args[6];
1185     int          n;
1186     int              j=0;
1187     XColor           colors[5];
1188
1189     color_set_dest->bg.red = color_set_src->bg.red;
1190     color_set_dest->bg.blue = color_set_src->bg.blue;
1191     color_set_dest->bg.green = color_set_src->bg.green;
1192     if(OldNewSame)
1193        color_set_dest->bg.pixel = color_set_src->bg.pixel;
1194     colors[j++] =  color_set_dest->bg;
1195
1196     color_set_dest->sc.red = color_set_src->sc.red;
1197     color_set_dest->sc.blue = color_set_src->sc.blue;
1198     color_set_dest->sc.green = color_set_src->sc.green;
1199     if(OldNewSame)
1200        color_set_dest->bg.pixel = color_set_src->bg.pixel;
1201     colors[j++] =  color_set_dest->sc;
1202
1203     color_set_dest->fg.red = color_set_src->fg.red;
1204     color_set_dest->fg.blue = color_set_src->fg.blue;
1205     color_set_dest->fg.green = color_set_src->fg.green;
1206     if(FgColor == DYNAMIC)
1207     {
1208        if(OldNewSame)
1209           color_set_dest->bg.pixel = color_set_src->bg.pixel;
1210        colors[j++] =  color_set_dest->fg;
1211     }
1212
1213     color_set_dest->ts.red = color_set_src->ts.red;
1214     color_set_dest->ts.blue = color_set_src->ts.blue;
1215     color_set_dest->ts.green = color_set_src->ts.green;
1216     color_set_dest->bs.red = color_set_src->bs.red;
1217     color_set_dest->bs.blue = color_set_src->bs.blue;
1218     color_set_dest->bs.green = color_set_src->bs.green;
1219     if(UsePixmaps == FALSE)
1220     {
1221        if(OldNewSame)
1222           color_set_dest->bg.pixel = color_set_src->bg.pixel;
1223        colors[j++] =  color_set_dest->ts;
1224        colors[j++] =  color_set_dest->bs;
1225     }
1226     if(OldNewSame && edit.oldButton != NULL)
1227     {
1228        n=0;
1229        XtSetArg(args[n], XmNforeground, color_set_dest->fg.pixel); n++;
1230        XtSetArg(args[n], XmNbackground, color_set_dest->bg.pixel); n++;
1231        XtSetArg(args[n], XmNarmColor, color_set_dest->sc.pixel); n++;
1232        XtSetArg(args[n], XmNtopShadowColor,
1233                                     color_set_dest->ts.pixel); n++;
1234        XtSetArg(args[n], XmNbottomShadowColor, 
1235                                     color_set_dest->bs.pixel); n++;
1236
1237        XtSetValues(edit.oldButton, args, n);
1238     }
1239         if(style.visualClass == PseudoColor || style.visualClass == GrayScale)
1240                 XStoreColors(style.display, style.colormap, colors, j );
1241
1242 }
1243
1244
1245 /************************************************************************
1246  *   RGBtoHSV()
1247  *
1248  ************************************************************************/
1249 void 
1250 RGBtoHSV(
1251 #if NeedWidePrototypes
1252         unsigned int r ,
1253         unsigned int g ,
1254         unsigned int b ,
1255 #else
1256         unsigned short r,
1257         unsigned short g,
1258         unsigned short b,
1259 #endif
1260         int *h,
1261         int *s,
1262         int *v )
1263 {
1264    double red, green, blue;
1265    double red1, green1, blue1;
1266    double hue, saturation, value;
1267    double base;
1268
1269
1270    red1 = (double)r / 65280.0;
1271    green1 = (double)g / 65280.0;
1272    blue1 = (double)b / 65280.0;
1273
1274    value = max(red1, green1, blue1);
1275    base = min(red1, green1, blue1);
1276
1277    if(value != 0.0)
1278       saturation = (value - base) / value;
1279    else
1280       saturation = 0.0;
1281
1282    hue = 0.0;
1283
1284    if( saturation != 0.0 )
1285    {
1286       red = (value - red1 ) / (value - base);
1287       green = (value - green1 ) / (value - base);
1288       blue = (value - blue1 ) / (value - base);
1289
1290       if(value == red1)
1291       {
1292          if(base == green1)
1293             hue = 5.0 + blue;
1294          else
1295             hue = 1.0 - green;
1296       }
1297       else if(value == green1)
1298       {
1299          if(base == blue1)
1300             hue = 1.0 + red;
1301          else
1302             hue = 3.0 - blue;
1303       }
1304       else
1305       {
1306          if(base == red1)
1307             hue = 3.0 + green;
1308          else
1309             hue = 5.0 - red;
1310       }
1311       hue *= 60.0;
1312       if( hue == 360.0)
1313         hue = 0.0;
1314     }
1315
1316     *h = (int)hue;
1317     *s = ((int)(saturation * 65280.0)) >> 8;
1318     *v = ((int)(value * 65280.0)) >> 8;
1319 }
1320
1321 /************************************************************************
1322  *   HSVtoRGB()
1323  *
1324  *  Converts hue, saturation, and value to RGB values.  
1325  *  Hue is in the range 0 to 360, while saturation and value
1326  *  are in the range 0 to 255
1327  ************************************************************************/
1328 static void 
1329 HSVtoRGB(
1330         int h,
1331         int s,
1332         int v,
1333         unsigned short *r,
1334         unsigned short *g,
1335         unsigned short *b )
1336 {
1337    double p1, p2, p3;
1338    double hue, sat, val;
1339    double red, green, blue;
1340    double i, f;
1341
1342    hue = (double)h / 60.0;
1343    i = floor(hue);
1344    f = hue - i;
1345
1346    val = (double)v / 255.0;
1347    sat = (double)s / 255.0;
1348
1349    p1 = val * (1.0 - sat);
1350    p2 = val * (1.0 -(sat * f));
1351    p3 = val * (1.0 -(sat * (1.0 - f)));
1352
1353    switch((int)i)
1354    {
1355      case 0:
1356        red = val;
1357        green = p3;
1358        blue = p1;
1359        break;
1360      case 1:
1361        red = p2;
1362        green = val;
1363        blue = p1;
1364        break;
1365      case 2:
1366        red = p1;
1367        green = val;
1368        blue = p3;
1369        break;
1370      case 3:
1371        red = p1;
1372        green = p2;
1373        blue = val;
1374        break;
1375      case 4:
1376        red = p3;
1377        green = p1;
1378        blue = val;
1379        break;
1380      case 5:
1381        red = val;
1382        green = p1;
1383        blue = p2;
1384        break;
1385    }
1386
1387    *r = (int)(red * 65280.0);
1388    *g = (int)(green * 65280.0);
1389    *b = (int)(blue * 65280.0);
1390
1391 }
1392
1393
1394 /************************************************************************
1395  *   max()
1396  * 
1397  ************************************************************************/
1398 static double 
1399 max(
1400         double x,
1401         double y,
1402         double z )
1403 {
1404    if(x >= y && x >= z)
1405       return(x);
1406
1407    if(y >= z && y >= x)
1408       return(y);
1409
1410    if(z >= y && z >= x)
1411       return(z);
1412 }
1413
1414 /************************************************************************
1415  *   min()
1416  *
1417  ************************************************************************/
1418 static double 
1419 min(
1420         double x,
1421         double y,
1422         double z )
1423 {
1424    if(x <= y && x <= z)
1425       return(x);
1426
1427    if(y <= z && y <= x)
1428       return(y);
1429
1430    if(z <= y && z <= x)
1431       return(z);
1432 }
1433
1434 /************************************************************************
1435  *   grabcolorCB()
1436  *           Call back routine for grabbing a color from the screen
1437  ************************************************************************/
1438 static void 
1439 grabcolorCB(
1440         Widget w,
1441         XtPointer client_data,
1442         XtPointer call_data )
1443 {
1444         Cursor cursor = XCreateFontCursor(style.display, XC_crosshair);
1445         XImage *image_ptr; 
1446         Position x,y;
1447         XEvent event;
1448         Pixel pixel;
1449         XColor colorStruct;
1450         char           color_string[MAX_STR_LEN];
1451         int status, offset;
1452         Boolean notDone=True;
1453         KeySym keySym;
1454
1455        /* grab the pointer using target cursor */
1456         status = XtGrabPointer(style.colorDialog, TRUE, 
1457                                 ButtonPressMask | ButtonReleaseMask,
1458                                 GrabModeAsync, GrabModeAsync, None, 
1459                                 cursor, CurrentTime); 
1460         if (status != GrabSuccess)
1461         {
1462                _DtSimpleError (progName, DtWarning, NULL, 
1463                     ((char *)GETMESSAGE(17, 14, "Warning, couldn't grab pointer.\n")), NULL);
1464                return;
1465         }
1466        
1467        /* grab the keyboard so we can get the ESC button press */
1468         status = XtGrabKeyboard(style.colorDialog, False, GrabModeAsync, 
1469                                           GrabModeAsync, CurrentTime);
1470         if (status != GrabSuccess)
1471         {
1472                XtUngrabPointer (style.colorDialog, CurrentTime);
1473                _DtSimpleError (progName, DtWarning, NULL, 
1474                     ((char *)GETMESSAGE(17, 15, "Warning, couldn't grab Keyboard.\n")), NULL);
1475                return;
1476         }
1477  
1478         while(notDone)
1479         {
1480            XtNextEvent(&event);
1481            
1482            switch (event.type) {
1483               case ButtonPress:
1484                  break;
1485               case ButtonRelease:
1486                  notDone = False;
1487                  break;
1488               case KeyPress:
1489                 /* look for ESC key press and stop if we get one */
1490                  if( event.xkey.state & ShiftMask)
1491                    offset = 1;
1492                  else
1493                    offset = 0;
1494                  
1495                  keySym = XLookupKeysym((XKeyEvent *)&event, offset);
1496                  if (keySym == XK_Escape)
1497                  {
1498                     XtUngrabKeyboard (style.colorDialog, CurrentTime);
1499                     XtUngrabPointer (style.colorDialog, CurrentTime);
1500                     return;
1501                  }
1502              default:
1503                  XtDispatchEvent(&event);
1504            }
1505         }
1506
1507         XtUngrabKeyboard (style.colorDialog, CurrentTime);
1508         XtUngrabPointer (style.colorDialog, CurrentTime);
1509
1510         x = (Position)event.xbutton.x_root;
1511         y = (Position)event.xbutton.y_root;
1512         image_ptr = XGetImage (style.display, style.root, x, y, 1, 1, 
1513                                AllPlanes, ZPixmap);
1514         pixel = (Pixel) XGetPixel (image_ptr, 0, 0);
1515         XDestroyImage (image_ptr);
1516
1517         colorStruct.pixel = pixel;
1518
1519         XQueryColor (style.display, style.colormap, &colorStruct);
1520
1521         edit.color_set->bg.red = colorStruct.red;
1522         edit.color_set->bg.green = colorStruct.green;
1523         edit.color_set->bg.blue = colorStruct.blue;
1524
1525         SetScales(&edit.color_set->bg);
1526         GenerateColors();
1527
1528 }
1529
1530 /************************************************************************
1531  *   GetPixel()
1532  *   
1533  ************************************************************************/
1534 static Pixel 
1535 GetPixel(
1536         Widget widget,
1537         char *color_string )
1538 {
1539     XrmValue from, to;
1540
1541     from.size = strlen(color_string) + 1;
1542     if (from.size < sizeof(String))
1543         from.size = sizeof(String);
1544     from.addr = color_string;
1545     XtConvert(widget, XmRString, &from, XmRPixel, &to);
1546
1547     return ((Pixel) *((Pixel *) to.addr));
1548 }
1549
1550
1551
1552 /*
1553 **  dialogBoxCB
1554 **      Process callback from the Ok, Cancel and Help pushButtons in the 
1555 **      DialogBox.
1556 */
1557 static void 
1558 dialogBoxCB(
1559         Widget w,
1560         XtPointer client_data,
1561         XtPointer call_data )
1562 {
1563     palette *tmp_palette;
1564     DtDialogBoxCallbackStruct *cb = (DtDialogBoxCallbackStruct *) call_data;
1565
1566     switch (cb->button_position)
1567     {
1568       case OK_BUTTON:
1569
1570           WriteOutPalette( pCurrentPalette->name);
1571
1572           if(strcmp(pCurrentPalette->name, defaultName) == 0)
1573           {
1574              UpdateDefaultPalette();
1575              SaveOrgPalette();
1576           }
1577
1578           XtUnmanageChild(edit.DialogShell);
1579           break;
1580
1581       case CANCEL_BUTTON:
1582           CopyPixelSet(edit.color_set, &edit.oldButtonColor);
1583           XtUnmanageChild(edit.DialogShell);
1584           break;
1585          
1586       case HELP_BUTTON:
1587         XtCallCallbacks(edit.DialogShell, XmNhelpCallback, (XtPointer)NULL);
1588         break;
1589
1590       default:
1591         break;
1592     }
1593 }
1594
1595
1596
1597 /************************************************************************
1598  * _DtmapCB
1599  *
1600  ************************************************************************/
1601 static void 
1602 _DtmapCB(
1603         Widget w,
1604         XtPointer client_data,
1605         XtPointer call_data )
1606 {
1607     Position     newX,newY;
1608     Position     x,y;
1609     Dimension    editWidth,editHeight;
1610     Dimension    width,height;
1611     Arg          args[6];
1612     int          n;
1613     XtWidgetGeometry reply;
1614     Widget       parent = (Widget) client_data;
1615
1616
1617     DtWsmRemoveWorkspaceFunctions(style.display, XtWindow(XtParent(w)));
1618     
1619     if (!save.restoreFlag)
1620     {
1621         /* get x,y,width,height of parent shell */
1622
1623         x = XtX(XtParent(parent));
1624         y = XtY(XtParent(parent));
1625         height = XtHeight(parent);
1626         width = XtWidth(parent);
1627
1628         editHeight = XtHeight(edit.DialogShell);
1629         editWidth = XtWidth(edit.DialogShell);
1630
1631         newX = x + width/2 - editWidth/2;
1632         if (newX < 0)
1633             newX = 0;
1634         newY = y + height/2 - editHeight;
1635         if (newY < 0)
1636             newY = y + height;
1637             
1638         n = 0;
1639         XtSetArg(args[n], XmNx, newX); n++;
1640         XtSetArg(args[n], XmNy, newY); n++;
1641         XtSetValues(edit.DialogShell,args,n);
1642
1643     }
1644
1645     XtRemoveCallback(edit.DialogShell, XmNmapCallback, _DtmapCB, NULL);
1646
1647 }
1648
1649
1650 /****************************************************
1651  * restoreColor(shell, db)
1652  * restore any state information saved with saveColor.  
1653  * This is called from restoreSession with the application shell 
1654  * and the special xrm database retrieved for restore.
1655  ****************************************************/
1656 void 
1657 restoreColorEdit(
1658         Widget shell,
1659         XrmDatabase db )
1660 {
1661
1662   XrmName xrm_name[5];
1663   XrmRepresentation rep_type;
1664   XrmValue value;
1665
1666     xrm_name [0] = XrmStringToQuark ("colorEditDlg");
1667     xrm_name [2] = 0;
1668
1669     /* get x position */
1670     xrm_name [1] = XrmStringToQuark ("x");
1671     if (XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value)){
1672       XtSetArg (save.posArgs[save.poscnt], XmNx, atoi((char *)value.addr)); save.poscnt++;
1673       save.restoreFlag = True;
1674     }
1675
1676     /* get y position */
1677     xrm_name [1] = XrmStringToQuark ("y");
1678     if (XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value)){
1679       XtSetArg (save.posArgs[save.poscnt], XmNy, atoi((char *)value.addr)); save.poscnt++;
1680     }
1681
1682     /*Collect any other parameters you saved into static variables.*/
1683
1684     xrm_name [1] = XrmStringToQuark ("ismapped");
1685     XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value);
1686     /* Are we supposed to be mapped? */
1687     if (strcmp(value.addr, "True") == 0)
1688       XtCallCallbacks(modifyColorButton, XmNactivateCallback, NULL);
1689 }
1690
1691
1692 /****************************************************
1693  * saveColorEdit(fd)
1694  * This routine will write out to the passed file descriptor any state
1695  * information this dialog needs.  It is called from saveSessionCB with 
1696  * the file already opened.
1697  * All information is saved in xrm format.  There is no restriction
1698  * on what can be saved.  It doesn't have to be defined or be part of any
1699  * widget or Xt definition.  Just name and save it here and recover it in
1700  * restoreColor.  The suggested minimum is whether you are mapped, and your
1701  * location.
1702  *****************************************************/
1703 void 
1704 saveColorEdit(
1705         int fd )
1706 {
1707     Position x,y;
1708     char *bufr = style.tmpBigStr;     /* size=[1024], make bigger if needed */
1709     XmVendorShellExtObject  vendorExt;
1710     XmWidgetExtData         extData;
1711
1712     if (edit.DialogShell != NULL) 
1713     {
1714         if (XtIsManaged(edit.DialogShell))
1715             sprintf(bufr, "*colorEditDlg.ismapped: True\n");
1716         else
1717             sprintf(bufr, "*colorEditDlg.ismapped: False\n");
1718
1719         /* Get and write out the geometry info for our Window */
1720         x = XtX(XtParent(edit.DialogShell));
1721         y = XtY(XtParent(edit.DialogShell));
1722
1723         /* Modify x & y to take into account window mgr frames
1724          * This is pretty bogus, but I don't know a better way to do it.
1725          */
1726         extData = _XmGetWidgetExtData(style.shell, XmSHELL_EXTENSION);
1727         vendorExt = (XmVendorShellExtObject)extData->widget;
1728         x -= vendorExt->vendor.xOffset;
1729         y -= vendorExt->vendor.yOffset;
1730
1731         sprintf(bufr, "%s*colorEditDlg.x: %d\n", bufr, x);
1732         sprintf(bufr, "%s*colorEditDlg.y: %d\n", bufr, y);
1733         /*any other parameter you want to save goes here*/
1734         if(-1 == write (fd, bufr, strlen(bufr))) {
1735                 perror(strerror(errno));
1736         }
1737     }
1738 }
1739