Add GNU LGPL headers to all .c .C and .h files
[oweals/cde.git] / cde / programs / dtsession / SrvPalette.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 librararies 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 /*
24 static char rcsid[] =
25   "$TOG: SrvPalette.c /main/13 1998/07/23 18:08:39 mgreess $";
26 */
27 /*                                                                      *
28  * (c) Copyright 1993, 1994 Hewlett-Packard Company                     *
29  * (c) Copyright 1993, 1994 International Business Machines Corp.       *
30  * (c) Copyright 1993, 1994 Sun Microsystems, Inc.                      *
31  * (c) Copyright 1993, 1994 Novell, Inc.                                *
32  */
33
34 /**********************************<+>*************************************
35 ***************************************************************************
36 **
37 **  File:        SrvPalette.c
38 **
39 **  Project:     HP DT Style Manager , integrated into dtsession 
40 **
41 **  Description:
42 **  -----------
43 **  This is the main program for the color server portion of the dt session
44 **  manager.  It:
45 **             1. Determines the number of color cells for each screen 
46 **                attached to the server this session manager is running on.
47 **             2. Reads in resouces for the colorserver on a per screen
48 **                basis. 
49 **             3. Allocates pixels either Read/Write or Read Only depending
50 **                on the resource DynamicColor.
51 **             4. Handles query's about those allocated pixels through
52 **                Selections. 
53 **
54 *******************************************************************
55 **  (c) Copyright Hewlett-Packard Company, 1990.  All rights are  
56 **  reserved.  Copying or other reproduction of this program      
57 **  except for archival purposes is prohibited without prior      
58 **  written consent of Hewlett-Packard Company.              
59 ********************************************************************
60 **
61 **
62 **************************************************************************
63 **********************************<+>*************************************/
64
65 #include <ctype.h>
66
67 #include <X11/Xatom.h>
68 #include "Srv.h"
69 #include "SrvFile_io.h"
70 #include "SrvPalette.h"
71
72 #ifdef sun
73 #include "OWsync.h"
74 #endif
75
76 #define DEFAULT   4
77 #define SRVBUFSIZE              1024
78 #define DEFAULT_COLOR_PALETTE "Default.dp"
79 #define DEFAULT_GRAYSCALE_PALETTE "GrayScale.dp"
80
81 #define DtRColorUse         "ColorUse"
82 #define DtRForegroundColor  "ForegroundColor"
83 #define DtRShadowPixmaps    "ShadowPixmaps"
84
85 #define TYPE_OF_MONITOR  "Type Of Monitor" /* also in dtstyle/ColorMain.c */
86
87 /* global color server struct */
88 ColorSrv colorSrv;
89
90
91 /*************************
92  * Color Server Resources
93  *************************/
94 typedef struct {
95    int     ColorUse;
96    int     ShadowPixmaps;
97    int     ForegroundColor;
98    Boolean DynamicColor;
99    Boolean WriteXrdbColors;
100    char    *ColorPalette;
101    char    *MonochromePalette;
102 } Appdata, *AppdataPtr;
103
104 static XtResource resources[] = {
105
106     {   "colorUse",
107         DtRColorUse,
108         DtRColorUse,
109         sizeof(int),
110         XtOffset(AppdataPtr, ColorUse),
111         XmRString,
112         "DEFAULT"},
113
114     {   "shadowPixmaps",
115         DtRShadowPixmaps,
116         DtRShadowPixmaps,
117         sizeof(int),
118         XtOffset(AppdataPtr, ShadowPixmaps),
119         XmRString, 
120         "DEFAULT"},
121
122     {   "foregroundColor",
123         DtRForegroundColor,
124         DtRForegroundColor,
125         sizeof(int),
126         XtOffset(AppdataPtr, ForegroundColor),
127         XmRString, 
128         "DYNAMIC"},
129
130     {   "dynamicColor",
131         "DynamicColor",
132         XmRBoolean,
133         sizeof(Boolean),
134         XtOffset(AppdataPtr, DynamicColor),
135         XmRImmediate, 
136         (XtPointer) True},
137
138     {   "writeXrdbColors",
139         "WriteXrdbColors",
140         XmRBoolean,
141         sizeof(Boolean),
142         XtOffset(AppdataPtr, WriteXrdbColors),
143         XmRImmediate, 
144         (XtPointer) True},
145
146     {   "colorPalette",
147         "ColorPalette",
148         XmRString,
149         sizeof(char *),
150         XtOffset(AppdataPtr, ColorPalette),
151         XmRImmediate,
152         (XtPointer)"DEFAULT"},
153
154     {   "monochromePalette",
155         "MonochromePalette",
156         XmRString,
157         sizeof(char *),
158         XtOffset(AppdataPtr, MonochromePalette),
159         XmRImmediate,
160         (XtPointer)"Black.dp"},
161 };
162
163 Appdata pColorSrvRsrc;
164
165 /************************************
166  * External Interface
167  ***********************************/
168 /* variables */
169 Widget shell[MAX_NUM_SCREENS];
170
171 /********    Static Function Declarations    ********/
172
173 static Boolean AllocateColors( 
174                         Display *dpy) ;
175 static char *convert_pixel_set(
176                         int typeOfMonitor,
177                         ColorSet *color );
178 static Boolean convert_selection( 
179                         Widget w,
180                         Atom *selection,
181                         Atom *target,
182                         Atom *type,
183                         XtPointer *value,
184                         unsigned long *length,
185                         int *format) ;
186 static void lose_selection( 
187                         Widget w,
188                         Atom *selection) ;
189 static int FindMaximumDefault( 
190                         Display *dpy,
191                         int screen_number) ;
192 static int FindNumOfPixels( 
193                         Display *dpy,
194                         int screen_number) ;
195 static int GetNumOfPixels( 
196                         int screen_number) ;
197 static void MatchAndStore( 
198                         Display *dpy,
199                         int screen_number,
200                         unsigned long *pixels) ;
201 static Boolean AllocReadWrite( 
202                         Display *dpy,
203                         int screen_number,
204                         int numOfPixels) ;
205 static void AllocReadOnly( 
206                         Display *dpy,
207                         int screen_number) ;
208 static void CvtStringToColorUse( 
209                         XrmValue *args,
210                         Cardinal *num_args,
211                         XrmValue *from_val,
212                         XrmValue *to_val) ;
213 static void CvtStringToForegroundColor( 
214                         XrmValue *args,
215                         Cardinal *num_args,
216                         XrmValue *from_val,
217                         XrmValue *to_val) ;
218 static void CvtStringToShadowPixmaps( 
219                         XrmValue *args,
220                         Cardinal *num_args,
221                         XrmValue *from_val,
222                         XrmValue *to_val) ;
223 static Boolean _DtWmStringsAreEqual( 
224                         register char *in_str,
225                         register char *test_str) ;
226 static void SetDefaults( 
227                         Display *dpy,
228                         int screen_number) ;
229
230 static void _DtCacheProperties( 
231                         Display *dpy,
232                         Window Win) ;
233 /********    End Static Function Declarations    ********/
234
235 #define MSG1  ((char *)GETMESSAGE(26, 1, "Color Server Warning: couldn't get ownership of the selection: "))
236 #define MSG2  ((char *)GETMESSAGE(26, 2, "Color Server Warning, losing ownership of the selection: "))
237 #define MSG2a ((char *)GETMESSAGE(26, 3, "Should never lose the selection."))
238 #define MSG3  ((char *)GETMESSAGE(26, 4, "Warning, found more pixels then are available."))
239
240 /***********************************************************************
241  *
242  * InitializeDtcolor - calls all the routines which do the initialization
243  *      for the color server.
244  *
245  **********************************************************************/
246 int 
247 InitializeDtcolor(
248         Display *dpy,
249         short sessionType )
250 {
251     int status, screen_number;
252     char xrdb_string[100];
253
254   /* find out what type of monitor(s?) is being used */
255     status = CheckMonitor(dpy);
256
257     if(status == 0)
258     {
259       /* Allocate colors for the default palette */
260        AllocateColors(dpy);
261     }
262     else {
263        for(screen_number=0;
264            screen_number != colorSrv.NumOfScreens;
265            screen_number++)
266        {
267          /* Set disown selections of the pixel set atoms */
268           XtDisownSelection(shell[screen_number],
269                       colorSrv.XA_CUSTOMIZE[screen_number],
270                       CurrentTime);
271        }
272        return(-1);
273     }
274
275     /* don't set resources if writeXrdbColors == false */
276     if (!pColorSrvRsrc.WriteXrdbColors)
277         return(0);
278
279 #ifdef sun
280     OWsyncColorResources(dpy, colorSrv.TypeOfMonitor[0], 
281                         colorSrv.pCurrentPalette[0]->color);
282     OWsyncLocaleResources(dpy);
283 #else
284    /* Set the *background: resource 
285        What gets set depends on what type of monitor */
286      /* For XmCO_HIGH_COLOR the default primary colorset is 4, else 1 */
287     if(colorSrv.TypeOfMonitor[0] != XmCO_BLACK_WHITE) 
288     {
289        int chipnum = colorSrv.TypeOfMonitor[0] == XmCO_HIGH_COLOR ? 4 : 1;
290        sprintf(xrdb_string,
291                    "*background: #%04X%04X%04X\n*foreground: #%04X%04X%04X\n",
292                       colorSrv.pCurrentPalette[0]->color[chipnum].bg.red,
293                       colorSrv.pCurrentPalette[0]->color[chipnum].bg.green,
294                       colorSrv.pCurrentPalette[0]->color[chipnum].bg.blue,
295                       colorSrv.pCurrentPalette[0]->color[chipnum].fg.red,
296                       colorSrv.pCurrentPalette[0]->color[chipnum].fg.green,
297                       colorSrv.pCurrentPalette[0]->color[chipnum].fg.blue);
298
299     }
300      /* For XmCO_BLACK_WHITE the resources depended on whether the default 
301         palette is White on Black or Black on White */
302     else /* XmCO_BLACK_WHITE */
303     {
304        if(strcmp(colorSrv.pCurrentPalette[0]->name, W_O_B) == 0 ||
305           strcmp(colorSrv.pCurrentPalette[0]->name, B_ONLY) == 0)
306        {
307           sprintf(xrdb_string,
308                    "*background: #000000000000\n*foreground: #FFFFFFFFFFFF\n");
309        }
310        else
311        {
312           sprintf(xrdb_string,
313                    "*background: #FFFFFFFFFFFF\n*foreground: #000000000000\n");
314        }
315     }
316     /* go merge the xrdb_string into the xrdb */
317     _DtAddToResource(dpy, xrdb_string);
318 #endif    
319
320     _DtCacheProperties(dpy, XtWindow(shell[0])) ;
321
322     return(0);
323 }
324
325 static void
326 _DtCacheProperties(
327         Display *dpy,
328         Window win)
329 {
330   Atom pixel_set_atom ;
331   struct _palette *palette ;
332   int typeOfMonitor;
333
334   int screen_number = 0 ; /*assuming simple case i.e. screen 0 */
335
336   pixel_set_atom = XInternAtom(dpy, XmSPIXEL_SET_PROP, FALSE) ;
337
338   palette = colorSrv.pCurrentPalette[screen_number];
339   typeOfMonitor = colorSrv.TypeOfMonitor[screen_number];
340      if (palette->converted == NULL)
341      {
342        palette->converted = convert_pixel_set(typeOfMonitor, palette->color);
343        palette->converted_len = strlen(palette->converted);
344      }
345   
346   *(palette->converted + palette->converted_len) = XmPIXEL_SET_PROP_VERSION ;
347   palette->converted_len++ ;
348   palette->converted[palette->converted_len] = NULL ;
349   XChangeProperty(dpy, win, pixel_set_atom, XA_STRING, 8, PropModeAppend, 
350                  (unsigned char *) XtNewString(palette->converted), 
351                  palette->converted_len) ;
352 }
353
354 /*****************************************************************************
355 **
356 **  Allocates color cells to be used by clients.  The global varible 
357 **  DynamicColor[screen_number] determines if the cells are to be allocated
358 **  read/write or read only.  Right now this routine allocates
359 **  all cells needed for a palette up front.  For performance tuning we will
360 **  want to look at allocating on demand.  The allocation scheme looks like
361 **  the following:  (AT - Alway True)
362 **  #  TypeOfMonior  UsePixmaps     FgColor     # of Cells allocated per palette
363 **  -  ------------  ----------     ------      -------------------------------
364 **  1   HIGH_COLOR    FALSE         DYNAMIC      (fg,bg,ts,bs,sc) 5*8 = 40
365 **  2   HIGH_COLOR    FALSE      BLACK or WHITE  (bg,ts,bs,sc)    4*8 = 32
366 **  3   HIGH_COLOR    TRUE          DYNAMIC      (fg,bg,sc)       3*8 = 24
367 **  4   HIGH_COLOR    TRUE       BLACK or WHITE  (bg,sc)          2*8 = 16
368 **
369 **  5   MEDIUM_COLOR  FALSE         DYNAMIC      (fg,bg,ts,bs,sc) 5*4 = 20
370 **  6   MEDIUM_COLOR  FALSE      BLACK or WHITE  (bg,ts,bs,sc)    4*4 = 16
371 **  7   MEDIUM_COLOR  TRUE          DYNAMIC      (fg,bg,sc)       3*4 = 12
372 **  8   MEDIUM_COLOR  TRUE       BLACK or WHITE  (bg,sc)          2*4 = 8
373 **
374 **  9   LOW_COLOR     FALSE         DYNAMIC      (fg,bg,ts,bs,sc) 5*2 = 10
375 ** 10   LOW_COLOR     FALSE      BLACK or WHITE  (bg,ts,bs,sc)    4*2 = 8
376 ** 11   LOW_COLOR     TRUE          DYNAMIC      (fg,bg,sc)       3*2 = 6
377 ** 12   LOW_COLOR     TRUE       BLACK or WHITE  (bg,sc)          2*2 = 4
378 **
379 ** 13   BLACK_WHITE    AT        Aways opposite                         0
380 **                                 of Bg
381 **
382 ***************************************************************************/
383 static Boolean 
384 AllocateColors(
385         Display *dpy )
386 {
387     int             screen_number;
388     int             numOfPixels;
389
390     /* Determine how many pixels to allocate (numOfPixels) */
391     for(screen_number=0;screen_number != colorSrv.NumOfScreens;screen_number++)
392     {
393        numOfPixels = GetNumOfPixels(screen_number);
394  
395    /* Now allocate the correct number of pixels using numOfPixels */
396        if(numOfPixels != 0)  /* Not XmCO_BLACK_WHITE */
397        {
398           if(colorSrv.DynamicColor[screen_number] == True)
399           {
400             /* go allocate Read/Write cells for the color server */
401              if(!AllocReadWrite(dpy, screen_number, numOfPixels))
402                 return(False);
403           }
404           else
405             /* go allocate Read Only cells for the color server */
406              AllocReadOnly(dpy, screen_number);
407        } 
408
409        if(colorSrv.TypeOfMonitor[screen_number] == XmCO_BLACK_WHITE)
410        {
411 #define BlackColorSet(dpy,scr,xcolor) \
412         (xcolor).pixel = BlackPixel((dpy),(scr)); \
413         (xcolor).red = (xcolor).green = (xcolor).blue = 0;
414 #define WhiteColorSet(dpy,scr,xcolor) \
415         (xcolor).pixel = WhitePixel((dpy),(scr)); \
416         (xcolor).red = (xcolor).green = (xcolor).blue = 65535;
417
418          palettes *palette = colorSrv.pCurrentPalette[screen_number];
419
420          /* Check to see what black and white palette it is */
421          /* note: color[0] = secondary, color[1] = primary (as of 8/8/90) */
422           if(!(strcmp(colorSrv.pCurrentPalette[screen_number]->name, W_O_B)))
423           {
424              WhiteColorSet(dpy,screen_number,palette->color[0].bg);
425              BlackColorSet(dpy,screen_number,palette->color[0].fg);
426              BlackColorSet(dpy,screen_number,palette->color[0].ts);
427              BlackColorSet(dpy,screen_number,palette->color[0].bs);
428              WhiteColorSet(dpy,screen_number,palette->color[0].sc);
429
430              BlackColorSet(dpy,screen_number,palette->color[1].bg);
431              WhiteColorSet(dpy,screen_number,palette->color[1].fg);
432              WhiteColorSet(dpy,screen_number,palette->color[1].ts);
433              WhiteColorSet(dpy,screen_number,palette->color[1].bs);
434              BlackColorSet(dpy,screen_number,palette->color[1].sc);
435           }
436           else 
437           if(!(strcmp(colorSrv.pCurrentPalette[screen_number]->name, B_O_W)))
438           {
439              BlackColorSet(dpy,screen_number,palette->color[0].bg);
440              WhiteColorSet(dpy,screen_number,palette->color[0].fg);
441              WhiteColorSet(dpy,screen_number,palette->color[0].ts);
442              WhiteColorSet(dpy,screen_number,palette->color[0].bs);
443              BlackColorSet(dpy,screen_number,palette->color[0].sc);
444
445              WhiteColorSet(dpy,screen_number,palette->color[1].bg);
446              BlackColorSet(dpy,screen_number,palette->color[1].fg);
447              BlackColorSet(dpy,screen_number,palette->color[1].ts);
448              BlackColorSet(dpy,screen_number,palette->color[1].bs);
449              WhiteColorSet(dpy,screen_number,palette->color[1].sc);
450           }
451           else 
452           if(!(strcmp(colorSrv.pCurrentPalette[screen_number]->name, W_ONLY)))
453           {
454              WhiteColorSet(dpy,screen_number,palette->color[0].bg);
455              BlackColorSet(dpy,screen_number,palette->color[0].fg);
456              BlackColorSet(dpy,screen_number,palette->color[0].ts);
457              BlackColorSet(dpy,screen_number,palette->color[0].bs);
458              WhiteColorSet(dpy,screen_number,palette->color[0].sc);
459
460              WhiteColorSet(dpy,screen_number,palette->color[1].bg);
461              BlackColorSet(dpy,screen_number,palette->color[1].fg);
462              BlackColorSet(dpy,screen_number,palette->color[1].ts);
463              BlackColorSet(dpy,screen_number,palette->color[1].bs);
464              WhiteColorSet(dpy,screen_number,palette->color[1].sc);
465           }
466           else  /* black only */
467           {
468              BlackColorSet(dpy,screen_number,palette->color[0].bg);
469              WhiteColorSet(dpy,screen_number,palette->color[0].fg);
470              WhiteColorSet(dpy,screen_number,palette->color[0].ts);
471              WhiteColorSet(dpy,screen_number,palette->color[0].bs);
472              BlackColorSet(dpy,screen_number,palette->color[0].sc);
473
474              BlackColorSet(dpy,screen_number,palette->color[1].bg);
475              WhiteColorSet(dpy,screen_number,palette->color[1].fg);
476              WhiteColorSet(dpy,screen_number,palette->color[1].ts);
477              WhiteColorSet(dpy,screen_number,palette->color[1].bs);
478              BlackColorSet(dpy,screen_number,palette->color[1].sc);
479           }
480 #undef BlackColorSet
481 #undef WhiteColorSet
482        }
483      XSync(dpy, 0);
484    } /* for screen_number=0 ; screen_number < NumOfScreens; screen_number++ */
485   
486    return(True);
487 }
488
489 /************************************************************************
490 **
491 ** CheckMonitor - check to determine which type of monitor each of the
492 **                screens on the server is running on.
493 **
494 ************************************************************************/
495 int 
496 CheckMonitor(
497         Display *dpy )
498 {
499     int n, screen_number, result;
500     Arg args[4];
501     char screenStr[5], cust_msg[24];
502     char *tmpStr;
503     char            tmpPalette[SRVBUFSIZE];
504     char            *token1;
505     char            *xrdb_string;
506
507     Widget mainShell;
508     XtAppContext app_context;
509     
510     /* Determine the number of screens attached to this server */
511     colorSrv.NumOfScreens = ScreenCount(dpy);
512
513    /* Initialize the Atoms used to pass information */
514     colorSrv.XA_PIXEL_SET = XInternAtom(dpy, XmSPIXEL_SET, FALSE);
515     colorSrv.XA_TYPE_MONITOR = XInternAtom(dpy, TYPE_OF_MONITOR, FALSE);
516
517    /* create a top level shell to retrieve subresources from */
518     n = 0;
519     XtSetArg(args[n], XmNbackground, 
520         BlackPixelOfScreen(DefaultScreenOfDisplay(dpy))); n++;
521     XtSetArg(args[n], XmNmappedWhenManaged, False); n++;
522     XtSetArg (args[n], XmNwidth, 1); n++;
523     XtSetArg (args[n], XmNheight, 1); n++;
524     mainShell = XtAppCreateShell("dtsession", XmSCOLOR_SRV_NAME,
525                                   applicationShellWidgetClass, 
526                                   dpy, args, n);
527
528    /* create an application context */
529     app_context = XtWidgetToApplicationContext(mainShell);
530     
531    /* Register the resource converters */
532     XtAppAddConverter(app_context, XmRString, "ColorUse", 
533             CvtStringToColorUse, NULL, 0);
534     XtAppAddConverter(app_context, XmRString, "ForegroundColor", 
535             CvtStringToForegroundColor, NULL, 0);
536     XtAppAddConverter(app_context, XmRString, "ShadowPixmaps", 
537             CvtStringToShadowPixmaps, NULL, 0);
538
539    /* cycle through each screen */
540     for(screen_number=0;screen_number != colorSrv.NumOfScreens;screen_number++)
541     {
542        sprintf(screenStr,"%d",screen_number);
543        n = 0;
544        XtSetArg(args[n], XmNbackground, 
545            BlackPixelOfScreen(DefaultScreenOfDisplay(dpy))); n++;
546        XtSetArg(args[n], XmNmappedWhenManaged, False); n++;
547        XtSetArg (args[n], XmNwidth, 1); n++;
548        XtSetArg (args[n], XmNheight, 1); n++;
549        shell[screen_number] = XtAppCreateShell(screenStr, XmSCOLOR_SRV_NAME, 
550                                                applicationShellWidgetClass, 
551                                                dpy, args, n);
552
553        /* 
554         * widget needs to be realized for the window ID for 
555         * selections to work 
556         */
557        
558        XtRealizeWidget(shell[screen_number]);
559        
560        sprintf(cust_msg,"%s%d", XmSCUSTOMIZE_DATA, screen_number);
561        colorSrv.XA_CUSTOMIZE[screen_number] = 
562            XInternAtom(dpy, cust_msg, FALSE);
563        
564        /* go set ownership of the pixel set atoms */
565        result = XtOwnSelection(shell[screen_number],
566                                colorSrv.XA_CUSTOMIZE[screen_number],
567                                CurrentTime, convert_selection, 
568                                lose_selection, NULL);
569   
570        if(result == False)
571        {
572            /*
573             * Don't forget to add length for the extra characters.
574             */
575            tmpStr = (char *)SRV_MALLOC(strlen(MSG1) + 25 + 5 + 1 + 1);
576            sprintf(tmpStr,"%s colorSrv.XA_CUSTOMIZE[%d].\n", 
577                    MSG1, screen_number);
578            _DtSimpleError(XmSCOLOR_SRV_NAME, DtWarning, NULL, tmpStr, NULL);
579            SRV_FREE(tmpStr);
580            return(-1);
581        }
582
583       /* Get the colorserver resources for this screen */
584
585        XtGetSubresources(mainShell, &pColorSrvRsrc, screenStr, screenStr,
586                           resources, XtNumber(resources), NULL, 0);
587
588       /* 
589        * Set TypeOfMonitor, UsePixmaps FgColor and 
590        * DynamicColor for this screen
591        */
592
593        SetDefaults(dpy, screen_number);
594        
595        if (colorSrv.TypeOfMonitor[screen_number] != XmCO_BLACK_WHITE)
596        {
597           colorSrv.pCurrentPalette[screen_number] = 
598                 (struct _palette *) GetPaletteDefinition(dpy, 
599                                      screen_number, 
600                                      pColorSrvRsrc.ColorPalette);
601        }
602        else
603        {
604            /* Allocate space for new palette. */
605            colorSrv.pCurrentPalette[screen_number] =
606                (struct _palette *) SRV_MALLOC( sizeof(struct _palette) + 1 );
607
608            /*  allocate enough space for the name */
609            strcpy(tmpPalette, pColorSrvRsrc.MonochromePalette); 
610            for (token1=tmpPalette; *token1; token1++);
611            while (token1!=tmpPalette && *token1!='.') token1--;
612            if (!strcmp(token1,PALETTE_SUFFIX)) *token1 = '\0';
613            colorSrv.pCurrentPalette[screen_number]->name = 
614                (char *)SRV_MALLOC(strlen(tmpPalette) + 1);
615            strcpy(colorSrv.pCurrentPalette[screen_number]->name,
616                   (char *) tmpPalette);
617            colorSrv.pCurrentPalette[screen_number]->converted=NULL;
618        }
619
620        if (colorSrv.pCurrentPalette[screen_number] == (struct _palette *) NULL)
621        {
622            return(-1);
623        }
624
625       /* write out the color or monochrome palette resource for the screen */
626
627        xrdb_string = XtMalloc(BUFSIZ);
628
629        if (colorSrv.TypeOfMonitor[0] == XmCO_HIGH_COLOR || 
630            colorSrv.TypeOfMonitor[0] == XmCO_MEDIUM_COLOR ||
631            colorSrv.TypeOfMonitor[0] == XmCO_LOW_COLOR)
632        {
633            sprintf(xrdb_string, "*%d*ColorPalette: %s%s\n",
634                    screen_number,
635                    colorSrv.pCurrentPalette[screen_number]->name,
636                    PALETTE_SUFFIX);
637        }
638        else /* XmCO_BLACK_WHITE */
639        {
640            sprintf(xrdb_string, "*%d*MonochromePalette: %s%s\n",
641                    screen_number,
642                    colorSrv.pCurrentPalette[screen_number]->name,
643                    PALETTE_SUFFIX);
644        }
645        _DtAddToResource(dpy, xrdb_string);
646
647        XtFree(xrdb_string);
648     
649    } /* for each screen */
650    return(0);
651 }
652
653 /************************************************************************
654 **
655 ** convert_pixel_set - converts palette pixel set to selection format
656 **
657 ************************************************************************/
658 static char *
659 convert_pixel_set(
660         int typeOfMonitor,
661         ColorSet *color )
662 {
663   int i;
664   char *converted;
665   char *p;
666   int colormappingindex;
667
668   const int colormapping [4][XmCO_MAX_NUM_COLORS] = {
669     {0, 1, 2, 3, 4, 5, 6, 7}, /* XmCO_HIGH_COLOR */
670     {0, 1, 2, 3, 1, 1, 2, 1}, /* XmCO_MEDIUM_COLOR */
671     {0, 1, 1, 1, 1, 1, 1, 1}, /* XmCO_LOW_COLOR */
672     {0, 1, 1, 1, 1, 1, 1, 1}  /* XmCO_BLACK_WHITE */
673   };
674
675 #if 0 /* map when hi-color was the default */
676   const int colormapping [4][XmCO_MAX_NUM_COLORS] = {
677     {0, 1, 2, 3, 4, 5, 6, 7}, /* XmCO_HIGH_COLOR */
678     {0, 1, 2, 3, 3, 3, 3, 3}, /* XmCO_MEDIUM_COLOR */
679     {0, 1, 1, 0, 0, 0, 0, 0}, /* XmCO_LOW_COLOR */
680     {0, 1, 1, 0, 0, 0, 0, 0}  /* XmCO_BLACK_WHITE */
681   };
682 #endif
683
684   switch(typeOfMonitor)
685   {
686     case XmCO_HIGH_COLOR:   colormappingindex = 0; break;
687     case XmCO_MEDIUM_COLOR: colormappingindex = 1; break;
688     case XmCO_LOW_COLOR:    colormappingindex = 2; break;
689     case XmCO_BLACK_WHITE:  colormappingindex = 3; break;
690   } 
691
692   p = converted = (char *)SRV_MALLOC(400);
693  
694   /* lead the string with the type of monitor */
695   p += sprintf(p, "%x_", typeOfMonitor);
696
697   for (i = 0; i < NUM_OF_COLORS; i++)
698   {
699     p += sprintf (p, "%lx_%lx_%lx_%lx_%lx_", 
700                   color[colormapping[colormappingindex][i]].bg.pixel,
701                   color[colormapping[colormappingindex][i]].fg.pixel,
702                   color[colormapping[colormappingindex][i]].ts.pixel,
703                   color[colormapping[colormappingindex][i]].bs.pixel,
704                   color[colormapping[colormappingindex][i]].sc.pixel);
705   }
706  
707   return(converted);
708 }
709
710 /************************************************************************
711 **
712 ** convert_selection - Callback, called when some other client wishes
713 **        to get information from the dtcolor (color server)
714 **
715 ************************************************************************/
716 static Boolean 
717 convert_selection(
718         Widget w,
719         Atom *selection,
720         Atom *target,
721         Atom *type,
722         XtPointer *value,
723         unsigned long *length,
724         int *format )
725 {
726   char pixels[50];
727   int i, screen_number;
728   char *temp;
729   char *str_type_return;
730   XrmValue value_return;
731   XrmValue    cvt_value;
732   XrmDatabase db;
733   char instanceName[30], instanceClass[30];
734   Boolean status;
735   struct _palette *palette;
736   int typeOfMonitor;
737                     
738
739   /* Determine for which screen the selection came from */
740   for(i=0; i < MAX_NUM_SCREENS; i++)
741   {
742      if(colorSrv.XA_CUSTOMIZE[i] == *selection)
743      {
744          screen_number = i;
745          break;
746      }
747   }
748
749   palette = colorSrv.pCurrentPalette[screen_number];
750   typeOfMonitor = colorSrv.TypeOfMonitor[screen_number];
751
752   if(*target == colorSrv.XA_PIXEL_SET)
753   {
754     /* wants to know the pixels allocated for the palette */
755
756      if (palette->converted == NULL)
757      {
758        palette->converted = convert_pixel_set(typeOfMonitor, palette->color);
759        palette->converted_len = strlen(palette->converted);
760      }
761
762      *type   = XA_STRING;
763      *length = palette->converted_len;
764      *value = XtNewString(palette->converted);
765      *format = 8;
766      return TRUE;
767   }
768   else if(*target == colorSrv.XA_TYPE_MONITOR)
769   {
770     /* wants to know ColorUse, ShadowPixmaps, ForegroundColor,
771        and DynamicColor */
772      *type   = XA_STRING;
773      temp = (char *)SRV_MALLOC(20);
774      sprintf (temp, "%x_%x_%x_%x", colorSrv.TypeOfMonitor[screen_number],
775                                 colorSrv.UsePixmaps[screen_number],
776                                 colorSrv.FgColor[screen_number],
777                                 colorSrv.DynamicColor[screen_number]);
778      *length = strlen(temp);
779      *value = temp;
780      *format = 8;
781      return TRUE;
782   }
783   else
784      return FALSE;
785 }
786
787 /************************************************************************
788 **
789 ** lose_selection - Callback, called when some other client wishes
790 **        to take ownership of one of the servers selections ... 
791 **        should never happen.
792 **
793 ************************************************************************/
794 static void 
795 lose_selection(
796         Widget w,
797         Atom *selection )
798 {
799      char *tmpStr, *tmpStr2;
800
801      Atom pixel_set_atom ;
802      pixel_set_atom = XInternAtom(XtDisplay(w), XmSPIXEL_SET_PROP, FALSE) ;
803      XDeleteProperty(XtDisplay(w), XtWindow(shell[0]), pixel_set_atom) ;
804
805      tmpStr = (char *)SRV_MALLOC(strlen(MSG2) + strlen(MSG2a) +  6);
806      tmpStr2 = (char *)SRV_MALLOC(strlen(MSG2) + 1);
807      sprintf(tmpStr2,"%s", MSG2);
808      sprintf(tmpStr,"%s%s%s", tmpStr2, selection, MSG2a);
809      _DtSimpleError(XmSCOLOR_SRV_NAME, DtWarning, NULL, tmpStr, NULL);
810      SRV_FREE(tmpStr);
811      SRV_FREE(tmpStr2);
812 }
813
814 /*****************************************************************************
815 **
816 ** FindMaximumDefault .. used when the actual or user defaults for
817 ** TypeOfMonitor, UsePixmaps, and FgColor try to allocate more cells than
818 ** are available .. this finds and allocates the maximum that are available
819 ** It also adjusts TypeOfMonitor, UsePixmaps, and FgColor accordingly.
820 **
821 ******************************************************************************/ 
822 static int 
823 FindMaximumDefault(
824         Display *dpy,
825         int screen_number )
826 {
827    int numOfPixelsLeft;
828
829    /* go find the Number of pixels left to allocate */
830    numOfPixelsLeft = FindNumOfPixels(dpy, screen_number);
831
832    if(numOfPixelsLeft < 4)
833    {
834      /* Use Black and White */
835       colorSrv.TypeOfMonitor[screen_number] = XmCO_BLACK_WHITE;
836       return(1);
837    }
838    if((colorSrv.TypeOfMonitor[screen_number] ==
839        XmCO_HIGH_COLOR && numOfPixelsLeft >= 40) ||
840       (colorSrv.TypeOfMonitor[screen_number] ==
841        XmCO_MEDIUM_COLOR && numOfPixelsLeft >= 20) ||
842       (colorSrv.TypeOfMonitor[screen_number] ==
843        XmCO_LOW_COLOR && numOfPixelsLeft >= 10))
844    {
845      /* should never get here */
846        return(0);
847    }
848    else if(colorSrv.TypeOfMonitor[screen_number] == XmCO_HIGH_COLOR)
849    {
850        if(numOfPixelsLeft >= 32) /* was asking for 40 */ 
851        {
852           colorSrv.UsePixmaps[screen_number] = FALSE;
853           colorSrv.FgColor[screen_number] = WHITE;
854           return(32);
855        }
856        else if(numOfPixelsLeft >= 24)
857        {
858           colorSrv.UsePixmaps[screen_number] = TRUE;
859           colorSrv.FgColor[screen_number] = DYNAMIC;
860           return(24);
861        } 
862        else if(numOfPixelsLeft >= 16)
863        {
864           colorSrv.UsePixmaps[screen_number] = TRUE;
865           colorSrv.FgColor[screen_number] = WHITE;
866           return(16);
867        } 
868        else  /* can't use XmCO_HIGH_COLOR anymore so set to
869                 next highest XmCO_MEDIUM_COLOR */
870        {
871           colorSrv.TypeOfMonitor[screen_number] = XmCO_MEDIUM_COLOR;
872           colorSrv.pCurrentPalette[screen_number]->num_of_colors = 4;
873        }
874     }
875
876    /* need to do an if instead of an else because TypeOfMonitor can be reset
877       in the else if above */     
878     if(colorSrv.TypeOfMonitor[screen_number] == XmCO_MEDIUM_COLOR)
879     {
880        if(numOfPixelsLeft >= 16)
881        {
882           colorSrv.UsePixmaps[screen_number] = FALSE;
883           colorSrv.FgColor[screen_number] = WHITE;
884           return(16);
885        }
886        if(numOfPixelsLeft >= 12)
887        {
888           colorSrv.UsePixmaps[screen_number] = TRUE;
889           colorSrv.FgColor[screen_number] = DYNAMIC;
890           return(12);
891        }
892        else if(numOfPixelsLeft >= 8)
893        {
894           colorSrv.UsePixmaps[screen_number] = TRUE;
895           colorSrv.FgColor[screen_number] = WHITE;
896           return(8);
897        }
898        else /* can't use XmCO_MEDIUM_COLOR anymore so set to next */
899             /* highest XmCO_LOW_COLOR*/ 
900        {
901           colorSrv.TypeOfMonitor[screen_number] = XmCO_LOW_COLOR;
902           colorSrv.pCurrentPalette[screen_number]->num_of_colors = 2;
903           SwitchAItoPS(colorSrv.pCurrentPalette[screen_number]);
904        }
905     }
906
907    /* need to do an if instead of an else because TypeOfMonitor can be reset
908       in the else if above */     
909     if(colorSrv.TypeOfMonitor[screen_number] == XmCO_LOW_COLOR)
910     {
911        if(numOfPixelsLeft >= 10)
912        {
913           colorSrv.UsePixmaps[screen_number] = FALSE;
914           colorSrv.FgColor[screen_number] = DYNAMIC;
915           return(10);
916        }
917        else if(numOfPixelsLeft >= 8)
918        {
919           colorSrv.UsePixmaps[screen_number] = FALSE;
920           colorSrv.FgColor[screen_number] = WHITE;
921           return(8);
922        }
923        else if(numOfPixelsLeft >= 6)
924        {
925           colorSrv.UsePixmaps[screen_number] = TRUE;
926           colorSrv.FgColor[screen_number] = DYNAMIC;
927           return(6);
928        }
929        else if(numOfPixelsLeft >= 4)
930        {
931           colorSrv.UsePixmaps[screen_number] = TRUE;
932           colorSrv.FgColor[screen_number] = WHITE;
933           return(4);
934        }
935      /* should never get here */
936    return(0);
937    }
938 }
939
940 /****************************************************************************
941 **
942 ** FindNumOfPixels ... routine used to determine the num of allocable cells
943 ** left in the default colormap.  With this number we can determine the
944 ** Maximum default for the user
945 **
946 ******************************************************************************/
947 static int 
948 FindNumOfPixels(
949         Display *dpy,
950         int screen_number )
951 {
952     unsigned long   *pixels;
953     unsigned long   plane_mask;
954     int  i, iterations, status;
955     int  num_of_pixels, count, base, countdown;
956     Colormap colormap;
957
958     colormap = DefaultColormap(dpy, screen_number);
959
960    /* get the total number of cells in this screen */
961     num_of_pixels = XDisplayCells(dpy, screen_number);
962
963    /* get the number of iterations to be used .. the number of plane in this
964       screen */
965     iterations = XDisplayPlanes(dpy, screen_number);
966
967    /* Allocate enough space to store the pixels.  */
968     pixels = (unsigned long *)SRV_MALLOC (num_of_pixels * sizeof (unsigned long));
969
970   /* now iterate through until the we know how many cells are available */
971     count = num_of_pixels;
972     countdown = count;
973     base = 0;
974     for(i = 0; i < iterations; i++)
975     {
976        status = XAllocColorCells (dpy, colormap, (Boolean)0, &plane_mask,
977                                                    0, pixels, count);
978
979        countdown = countdown / 2;
980        if(status == False)
981        {
982           count = base + countdown;
983        }
984        else
985        {
986           XFreeColors(dpy, colormap, pixels, count, (unsigned long)0);
987           if(count != num_of_pixels)
988           {
989              base = count;
990              count = base + countdown;
991           }
992        }
993     }
994     status = XAllocColorCells (dpy, colormap, (Boolean)0, &plane_mask,
995                                                    0, pixels, count);
996     if(status == False)
997        count--;
998     else
999        XFreeColors(dpy, colormap, pixels, count, (unsigned long)0);
1000     SRV_FREE((char *) pixels);
1001     return(count);
1002 }
1003
1004 /************************************************************************
1005 **
1006 ** GetNumOfPixels - returns the number of pixels to allocate based on the
1007 **        resources ColorUse(TypeOfMonitor), ShadowPixmaps(UsePixmaps),
1008 **        and ForegroundColor(FgColor).
1009 **
1010 ************************************************************************/
1011 static int 
1012 GetNumOfPixels(
1013         int screen_number )
1014 {
1015
1016    if(colorSrv.TypeOfMonitor[screen_number] == XmCO_BLACK_WHITE)
1017    {
1018       return(0);
1019    }
1020    else  /* non Black and White monitor */
1021    {
1022       if(colorSrv.UsePixmaps[screen_number] == FALSE)
1023       {
1024          if(colorSrv.FgColor[screen_number] == DYNAMIC) 
1025          {
1026             return(colorSrv.pCurrentPalette[screen_number]->num_of_colors * 5);
1027          }
1028          else  /*FgColor == BLACK or WHITE ... bg, ts, bs, & sc used */
1029          {
1030             return(colorSrv.pCurrentPalette[screen_number]->num_of_colors * 4);
1031          }
1032       }
1033       else  /* UsePixmaps == True */
1034       {
1035          if(colorSrv.FgColor[screen_number] == DYNAMIC) /* fg, bg, & sc used */
1036          {
1037             return(colorSrv.pCurrentPalette[screen_number]->num_of_colors * 3);
1038          }
1039          else  /*FgColor == BLACK or WHITE ... bg & sc used */
1040          {
1041             return(colorSrv.pCurrentPalette[screen_number]->num_of_colors * 2);
1042          }
1043       }
1044    }
1045 }
1046
1047 /************************************************************************
1048 **
1049 ** MatchAndStore - match the pixels already allocated with the current
1050 **        palettes storage .. then do a Store Colors to set the colors
1051 **        correctly at the X server.
1052 **
1053 ************************************************************************/
1054 static void 
1055 MatchAndStore(
1056         Display *dpy,
1057         int screen_number,
1058         unsigned long *pixels )
1059 {
1060    int i, count = 0;
1061    struct _palette    *p;
1062    XColor *xcolor;
1063
1064    p = colorSrv.pCurrentPalette[screen_number];
1065    xcolor = (XColor *)SRV_MALLOC (p->num_of_colors * 5 * sizeof (XColor));
1066
1067    for(i = 0; i < p->num_of_colors; i++) 
1068    {
1069       /* Background Pixel */
1070       p->color[i].bg.pixel = pixels[count];
1071       p->color[i].bg.flags = DoRed | DoGreen | DoBlue;
1072       xcolor[count] = p->color[i].bg;
1073       count++;
1074
1075       /* SelectColor (ArmColor) Pixel */
1076       p->color[i].sc.pixel = pixels[count];
1077       p->color[i].sc.flags = DoRed | DoGreen | DoBlue;
1078       xcolor[count] = p->color[i].sc;
1079       count++;
1080
1081       if(colorSrv.UsePixmaps[screen_number] == FALSE)
1082       {
1083          /* TopShadow Pixel */
1084          p->color[i].ts.pixel = pixels[count];
1085          p->color[i].ts.flags = DoRed | DoGreen | DoBlue;
1086          xcolor[count] = p->color[i].ts;
1087          count++;
1088
1089          /* BottomShadow Pixel */
1090          p->color[i].bs.pixel = pixels[count];
1091          p->color[i].bs.flags = DoRed | DoGreen | DoBlue;
1092          xcolor[count] = p->color[i].bs;
1093          count++;
1094       }
1095       else  /* colorSrv.UsePixmaps = True */
1096       {
1097          /* TopShadow Pixel set to white */
1098          p->color[i].ts.pixel = WhitePixel(dpy,screen_number);
1099          p->color[i].ts.flags = 0;
1100
1101          /* BottomShadow Pixel set to black */
1102          p->color[i].bs.pixel = BlackPixel(dpy,screen_number);
1103          p->color[i].bs.flags = 0;
1104       }
1105       if(colorSrv.FgColor[screen_number] == DYNAMIC)
1106       {
1107          /* Foreground Pixel */
1108          p->color[i].fg.pixel = pixels[count];
1109          p->color[i].fg.flags = DoRed | DoGreen | DoBlue;
1110          xcolor[count] = p->color[i].fg;
1111          count++;
1112       }
1113       else if(colorSrv.FgColor[screen_number] == BLACK)
1114       {
1115          /* Foreground Pixel set to BLACK */
1116          p->color[i].fg.pixel = BlackPixel(dpy,screen_number);
1117          p->color[i].fg.flags = 0;
1118       }
1119       else
1120       {
1121          /* Foreground Pixel set to WHITE */
1122          p->color[i].fg.pixel = WhitePixel(dpy,screen_number);
1123          p->color[i].fg.flags = 0;
1124       }
1125    } /* for */
1126
1127    if (count > 0)
1128    {
1129      XStoreColors(dpy, DefaultColormap(dpy, screen_number), xcolor, count);
1130    }
1131
1132    SRV_FREE((char *) xcolor);
1133 }
1134
1135 /************************************************************************
1136 **
1137 ** AllocReadWrite - Allocates Read/Write cells for use by the color
1138 **        server.  If the X server can't allocate enough cells (numOfPixels)
1139 **        this routine finds the number of pixels available, and sets
1140 **        the varibles TypeOfMonitor, UsePixmaps, and FgColor accordingly.
1141 **
1142 ************************************************************************/
1143 static Boolean 
1144 AllocReadWrite(
1145         Display *dpy,
1146         int screen_number,
1147         int numOfPixels )
1148 {
1149    char *tmpStr;
1150    unsigned long *pixels;
1151    unsigned long plane_mask;
1152    int status;
1153
1154   /* Allocate enough space to store the pixels. */
1155    pixels = (unsigned long *)SRV_MALLOC (numOfPixels * sizeof (unsigned long));
1156
1157   /* Now actually allocate R/W pixels */
1158    status = XAllocColorCells (dpy, DefaultColormap(dpy, screen_number),
1159                               (Boolean)0, &plane_mask, 0, pixels, numOfPixels);
1160
1161   /* When status is false means the alloc couldn't get all the pixels 
1162     the user wanted or what the default is .. so lets go find the
1163     minumum and set up and use that */
1164    if(status == False)
1165    {
1166        SRV_FREE((char *) pixels);
1167        numOfPixels = FindMaximumDefault(dpy, screen_number);
1168        if(numOfPixels == 0)
1169        {
1170             tmpStr = (char *)SRV_MALLOC(strlen(MSG3) + 6);
1171             sprintf(tmpStr,"%s%d", MSG3, screen_number);
1172             _DtSimpleError(XmSCOLOR_SRV_NAME, DtWarning, NULL, tmpStr, NULL);
1173             SRV_FREE(tmpStr);
1174             return(False);
1175        }
1176        else
1177        {
1178            if(colorSrv.TypeOfMonitor[screen_number] != XmCO_BLACK_WHITE)
1179            {
1180            /* Allocate enough space to store the pixels. */
1181               pixels = (unsigned long *)SRV_MALLOC (numOfPixels *
1182                                             sizeof (unsigned long));
1183
1184         /* Now actually allocate R/W pixels */
1185               status = XAllocColorCells(dpy, DefaultColormap(dpy,screen_number),
1186                             (Boolean)0, &plane_mask, 0, pixels, numOfPixels);
1187
1188               if(status == False)
1189               {
1190                  SRV_FREE((char *) pixels);
1191                  _DtSimpleError(XmSCOLOR_SRV_NAME, DtWarning, NULL, ((char *)GETMESSAGE(26, 5, "Warning, can't allocate enough pixels.\n")), NULL);
1192                  return(False);
1193               }
1194            }
1195        }
1196    }
1197
1198    if(colorSrv.TypeOfMonitor[screen_number] != XmCO_BLACK_WHITE)
1199    {
1200      /* Go match pixels allocated with the colorsets then use store
1201         XStoreColors to set the RGB values of them */
1202       MatchAndStore(dpy, screen_number, pixels);
1203
1204    } 
1205
1206   /* free the allocated space for pixels */
1207    SRV_FREE((char *) pixels);
1208    return(True);
1209
1210
1211 /************************************************************************
1212 **
1213 ** AllocReadOnly - Allocates Read Only cells for use by the color
1214 **        server.  If the X server can't allocate the cell it finds the
1215 **        closest approximation to the color of a cell already allocated.
1216 **        Therefore there is no error recorded.  
1217 **
1218 ************************************************************************/
1219 static void 
1220 AllocReadOnly(
1221         Display *dpy,
1222         int screen_number )
1223 {
1224    int i;
1225
1226    for(i=0; i < colorSrv.pCurrentPalette[screen_number]->num_of_colors; i++)
1227    {
1228       XAllocColor(dpy, DefaultColormap(dpy, screen_number),
1229                 &(colorSrv.pCurrentPalette[screen_number]->color[i].bg));
1230       XAllocColor(dpy, DefaultColormap(dpy, screen_number),
1231                 &(colorSrv.pCurrentPalette[screen_number]->color[i].sc));
1232
1233     /* Check UsePixmaps varible */
1234       if(colorSrv.UsePixmaps[screen_number] == FALSE)
1235       {
1236          XAllocColor(dpy, DefaultColormap(dpy, screen_number),
1237                      &(colorSrv.pCurrentPalette[screen_number]->color[i].ts));
1238          XAllocColor(dpy, DefaultColormap(dpy, screen_number),
1239                      &(colorSrv.pCurrentPalette[screen_number]->color[i].bs));
1240       }
1241       else /* colorSrv.UsePixmaps[screen_number] == True */
1242       {
1243          colorSrv.pCurrentPalette[screen_number]->color[i].ts.pixel =
1244                                           WhitePixel(dpy,screen_number);
1245          colorSrv.pCurrentPalette[screen_number]->color[i].bs.pixel =
1246                                           BlackPixel(dpy,screen_number);
1247       }
1248
1249     /* Check FgColor varible */
1250       if(colorSrv.FgColor[screen_number] == DYNAMIC)
1251          XAllocColor(dpy, DefaultColormap(dpy, screen_number),
1252                      &(colorSrv.pCurrentPalette[screen_number]->color[i].fg));
1253
1254       else if(colorSrv.FgColor[screen_number] == BLACK)
1255          colorSrv.pCurrentPalette[screen_number]->color[i].fg.pixel =
1256                                           BlackPixel(dpy,screen_number);
1257
1258       else
1259          colorSrv.pCurrentPalette[screen_number]->color[i].fg.pixel =
1260                                           WhitePixel(dpy,screen_number);
1261    }
1262
1263
1264 /*********************************************************************
1265 **
1266 ** Converter which converts a string to the ColorUse value 
1267 **
1268 **********************************************************************/
1269 static void 
1270 CvtStringToColorUse(
1271         XrmValue *args,
1272         Cardinal *num_args,
1273         XrmValue *from_val,
1274         XrmValue *to_val )
1275 {
1276    char * in_str = (char *) (from_val->addr);
1277    static int i;
1278
1279    to_val->size = sizeof (int);
1280    to_val->addr = (XtPointer) &i;
1281
1282    if (_DtWmStringsAreEqual (in_str, "high_color"))
1283       i = XmCO_HIGH_COLOR;
1284    else if (_DtWmStringsAreEqual (in_str, "medium_color"))
1285       i = XmCO_MEDIUM_COLOR;
1286    else if (_DtWmStringsAreEqual (in_str, "low_color"))
1287       i = XmCO_LOW_COLOR;
1288    else if (_DtWmStringsAreEqual (in_str, "b_w"))
1289       i = XmCO_BLACK_WHITE;
1290    else if (_DtWmStringsAreEqual (in_str, "default"))
1291       i = DEFAULT;
1292    else
1293    {
1294       to_val->size = 0;
1295       to_val->addr = NULL;
1296       XtStringConversionWarning ((char *)from_val->addr, DtRColorUse);
1297    }
1298 }
1299 /**********************************************************************
1300 **
1301 ** Converter which converts a string to the ForegroundColor value 
1302 **
1303 **********************************************************************/
1304 static void 
1305 CvtStringToForegroundColor(
1306         XrmValue *args,
1307         Cardinal *num_args,
1308         XrmValue *from_val,
1309         XrmValue *to_val )
1310 {
1311    char * in_str = (char *) (from_val->addr);
1312    static int i;
1313
1314    to_val->size = sizeof (int);
1315    to_val->addr = (XtPointer) &i;
1316
1317    if (_DtWmStringsAreEqual (in_str, "dynamic"))
1318       i = DYNAMIC;
1319    else if (_DtWmStringsAreEqual (in_str, "black"))
1320       i = BLACK;
1321    else if (_DtWmStringsAreEqual (in_str, "white"))
1322       i = WHITE;
1323    else
1324    {
1325       to_val->size = 0;
1326       to_val->addr = NULL;
1327       XtStringConversionWarning ((char *)from_val->addr, DtRForegroundColor);
1328    }
1329 }
1330
1331 /***********************************************************************
1332 **
1333 ** Converter which converts a string to the ShadowPixmaps value 
1334 **
1335 ***********************************************************************/
1336 static void 
1337 CvtStringToShadowPixmaps(
1338         XrmValue *args,
1339         Cardinal *num_args,
1340         XrmValue *from_val,
1341         XrmValue *to_val )
1342 {
1343    char * in_str = (char *) (from_val->addr);
1344    static int i;
1345
1346    to_val->size = sizeof (int);
1347    to_val->addr = (XtPointer) &i;
1348
1349    if (_DtWmStringsAreEqual (in_str, "true"))
1350       i = 1;
1351    else if (_DtWmStringsAreEqual (in_str, "false"))
1352       i = 0;
1353    else if (_DtWmStringsAreEqual (in_str, "default"))
1354       i = -1;
1355    else
1356    {
1357       to_val->size = 0;
1358       to_val->addr = NULL;
1359       XtStringConversionWarning ((char *)from_val->addr, DtRShadowPixmaps);
1360    }
1361 }
1362
1363 /************************************************************************
1364  *
1365  *  _DtWmStringsAreEqual
1366  *      Compare two strings and return true if equal.
1367  *      The comparison is on lower cased strings.  It is the callers
1368  *      responsibility to ensure that test_str is already lower cased.
1369  *
1370  ************************************************************************/
1371 static Boolean 
1372 _DtWmStringsAreEqual(
1373         register char *in_str,
1374         register char *test_str )
1375
1376 {
1377    register int i;
1378    register int j;
1379    i = *in_str;
1380
1381    for (;;)
1382    {
1383       i = *in_str;
1384       j = *test_str;
1385
1386 #ifdef MULTIBYTE
1387       if ((mblen(in_str, MB_CUR_MAX) == 1))
1388           if (isupper (i)) i = tolower (i);
1389 #else
1390           if (isupper (i)) i = tolower (i);
1391 #endif
1392       if (i != j) return (False);
1393       if (i == 0) return (True);
1394
1395       in_str++;
1396       test_str++;
1397    }
1398 }
1399   
1400 /************************************************************************
1401  *
1402  * SetDefaults - set the TypeOfMonitor, UsePixmaps, FgColor, and DynamicColor
1403  *       for the screen passed in.  Use the resource values, the number of
1404  *       colors for this screen, and the visual type of the screen to 
1405  *       determine which values best fit.
1406  *
1407  *************************************************************************/
1408 static void 
1409 SetDefaults(
1410         Display *dpy,
1411         int screen_number )
1412 {
1413    int numPlanes;
1414    Visual *visual;
1415
1416    /* Initialize colorSrv data for this screen with specified resource values */
1417    colorSrv.UsePixmaps[screen_number] = pColorSrvRsrc.ShadowPixmaps;
1418    colorSrv.DynamicColor[screen_number] = pColorSrvRsrc.DynamicColor;
1419
1420    /* If this is a static color visual class, set DynamicColor to False. */
1421    visual = XDefaultVisual(dpy, screen_number);
1422
1423
1424    /* GrayScale and PseudoColor are the only visual types that make */
1425    /* sense to change dynamically with the current implementation   */
1426    if ((visual->class != GrayScale) && (visual->class != PseudoColor))
1427       colorSrv.DynamicColor[screen_number] = False;
1428
1429    /* if not specified, set ColorPalette default */
1430    if (strcmp(pColorSrvRsrc.ColorPalette,"DEFAULT") == 0)
1431    {
1432       if ((visual->class == GrayScale) || (visual->class == StaticGray))
1433       {
1434           pColorSrvRsrc.ColorPalette = 
1435                 XtMalloc(strlen(DEFAULT_GRAYSCALE_PALETTE)+1);
1436           strcpy(pColorSrvRsrc.ColorPalette, DEFAULT_GRAYSCALE_PALETTE);
1437       }
1438       else
1439       {
1440           pColorSrvRsrc.ColorPalette = 
1441                 XtMalloc(strlen(DEFAULT_COLOR_PALETTE)+1);
1442           strcpy(pColorSrvRsrc.ColorPalette, DEFAULT_COLOR_PALETTE);
1443       }
1444    }
1445
1446    numPlanes = XDisplayPlanes(dpy, screen_number);
1447
1448    if( numPlanes < 3) /* 1 or 2 planes */
1449    { 
1450       colorSrv.TypeOfMonitor[screen_number] = XmCO_BLACK_WHITE;
1451       colorSrv.DynamicColor[screen_number] = False;
1452    }
1453    else if( numPlanes == 3 ) /* 3 planes */
1454    {
1455       switch(pColorSrvRsrc.ColorUse) {
1456          case XmCO_LOW_COLOR:
1457             colorSrv.TypeOfMonitor[screen_number] = XmCO_LOW_COLOR;
1458             break;
1459          default:
1460             colorSrv.TypeOfMonitor[screen_number] = XmCO_BLACK_WHITE;
1461             colorSrv.DynamicColor[screen_number] = False;
1462       }
1463       /* for 3 planes UsePixmaps (ShadowPixmaps) have to be on (TRUE) */
1464       colorSrv.UsePixmaps[screen_number] = 1;
1465    }
1466    else if( numPlanes == 4 ) /* 4 planes */
1467    {
1468       switch(pColorSrvRsrc.ColorUse) {
1469          case XmCO_MEDIUM_COLOR:
1470            /* for 4 planes ColorUse = Med_color shadowPixmaps have to be True */
1471             pColorSrvRsrc.ShadowPixmaps = -1;
1472             colorSrv.TypeOfMonitor[screen_number] = XmCO_MEDIUM_COLOR;
1473             break;
1474          case XmCO_BLACK_WHITE:
1475             colorSrv.TypeOfMonitor[screen_number] = XmCO_BLACK_WHITE;
1476             colorSrv.DynamicColor[screen_number] = False;
1477             break;
1478          default:
1479             colorSrv.TypeOfMonitor[screen_number] = XmCO_LOW_COLOR;
1480       }
1481
1482      /* check to see what type of shadow pixmap to use */
1483       if(pColorSrvRsrc.ShadowPixmaps == -1)
1484          colorSrv.UsePixmaps[screen_number] = 1;
1485    }
1486    else if( numPlanes == 5 ) /* 5 planes */
1487    {
1488       switch(pColorSrvRsrc.ColorUse) {
1489          case XmCO_HIGH_COLOR:
1490            /* for 5 planes ColorUse = hi_color shadowPixmaps have to be True */
1491             pColorSrvRsrc.ShadowPixmaps = -1;
1492             colorSrv.TypeOfMonitor[screen_number] = XmCO_HIGH_COLOR; 
1493             break; 
1494          case XmCO_MEDIUM_COLOR:
1495             colorSrv.TypeOfMonitor[screen_number] = XmCO_MEDIUM_COLOR;
1496             break;
1497          case XmCO_BLACK_WHITE:
1498             colorSrv.TypeOfMonitor[screen_number] = XmCO_BLACK_WHITE;
1499             colorSrv.DynamicColor[screen_number] = False;
1500             break;
1501          default:
1502             colorSrv.TypeOfMonitor[screen_number] = XmCO_LOW_COLOR;
1503       }
1504    }
1505    else /* 6 and above planes */
1506    {
1507       switch(pColorSrvRsrc.ColorUse) {
1508          case XmCO_HIGH_COLOR:
1509             colorSrv.TypeOfMonitor[screen_number] = XmCO_HIGH_COLOR;
1510             break;
1511          case XmCO_LOW_COLOR:
1512             colorSrv.TypeOfMonitor[screen_number] = XmCO_LOW_COLOR;
1513             break;
1514          case XmCO_BLACK_WHITE:
1515             colorSrv.TypeOfMonitor[screen_number] = XmCO_BLACK_WHITE;
1516             colorSrv.DynamicColor[screen_number] = False;
1517             break;
1518          default:
1519             colorSrv.TypeOfMonitor[screen_number] = XmCO_MEDIUM_COLOR;
1520       }
1521
1522      /* check to see what type of shadow pixmap to use */
1523       if(pColorSrvRsrc.ShadowPixmaps == -1)
1524          colorSrv.UsePixmaps[screen_number] = 0;
1525    }
1526
1527  /* Determine the correct foreground color useage */
1528    switch(pColorSrvRsrc.ForegroundColor) {
1529       case BLACK:
1530          colorSrv.FgColor[screen_number] = BLACK;
1531          break;
1532       case WHITE:
1533          colorSrv.FgColor[screen_number] = WHITE;
1534          break;
1535       default:
1536          colorSrv.FgColor[screen_number] = DYNAMIC;
1537   }
1538 }