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