Fix compiler warnings in dtsession
[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 #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;
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;
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      tmpStr = (char *)SRV_MALLOC(strlen(MSG2) + strlen(MSG2a) +  6);
808      tmpStr2 = (char *)SRV_MALLOC(strlen(MSG2) + 1);
809      if (selection != NULL) {
810           tmpStr3 = XGetAtomName(XtDisplay(w), *selection);
811      } else {
812           tmpStr3 = NULL;
813      }
814      printf(tmpStr2,"%s", MSG2);
815      sprintf(tmpStr,"%s%s%s", tmpStr2, (tmpStr3 == NULL) ? "(null)" : tmpStr3, MSG2a);
816      _DtSimpleError(XmSCOLOR_SRV_NAME, DtWarning, NULL, tmpStr, NULL);
817      SRV_FREE(tmpStr);
818      SRV_FREE(tmpStr2);
819 }
820
821 /*****************************************************************************
822 **
823 ** FindMaximumDefault .. used when the actual or user defaults for
824 ** TypeOfMonitor, UsePixmaps, and FgColor try to allocate more cells than
825 ** are available .. this finds and allocates the maximum that are available
826 ** It also adjusts TypeOfMonitor, UsePixmaps, and FgColor accordingly.
827 **
828 ******************************************************************************/ 
829 static int 
830 FindMaximumDefault(
831         Display *dpy,
832         int screen_number )
833 {
834    int numOfPixelsLeft;
835
836    /* go find the Number of pixels left to allocate */
837    numOfPixelsLeft = FindNumOfPixels(dpy, screen_number);
838
839    if(numOfPixelsLeft < 4)
840    {
841      /* Use Black and White */
842       colorSrv.TypeOfMonitor[screen_number] = XmCO_BLACK_WHITE;
843       return(1);
844    }
845    if((colorSrv.TypeOfMonitor[screen_number] ==
846        XmCO_HIGH_COLOR && numOfPixelsLeft >= 40) ||
847       (colorSrv.TypeOfMonitor[screen_number] ==
848        XmCO_MEDIUM_COLOR && numOfPixelsLeft >= 20) ||
849       (colorSrv.TypeOfMonitor[screen_number] ==
850        XmCO_LOW_COLOR && numOfPixelsLeft >= 10))
851    {
852      /* should never get here */
853        return(0);
854    }
855    else if(colorSrv.TypeOfMonitor[screen_number] == XmCO_HIGH_COLOR)
856    {
857        if(numOfPixelsLeft >= 32) /* was asking for 40 */ 
858        {
859           colorSrv.UsePixmaps[screen_number] = FALSE;
860           colorSrv.FgColor[screen_number] = WHITE;
861           return(32);
862        }
863        else if(numOfPixelsLeft >= 24)
864        {
865           colorSrv.UsePixmaps[screen_number] = TRUE;
866           colorSrv.FgColor[screen_number] = DYNAMIC;
867           return(24);
868        } 
869        else if(numOfPixelsLeft >= 16)
870        {
871           colorSrv.UsePixmaps[screen_number] = TRUE;
872           colorSrv.FgColor[screen_number] = WHITE;
873           return(16);
874        } 
875        else  /* can't use XmCO_HIGH_COLOR anymore so set to
876                 next highest XmCO_MEDIUM_COLOR */
877        {
878           colorSrv.TypeOfMonitor[screen_number] = XmCO_MEDIUM_COLOR;
879           colorSrv.pCurrentPalette[screen_number]->num_of_colors = 4;
880        }
881     }
882
883    /* need to do an if instead of an else because TypeOfMonitor can be reset
884       in the else if above */     
885     if(colorSrv.TypeOfMonitor[screen_number] == XmCO_MEDIUM_COLOR)
886     {
887        if(numOfPixelsLeft >= 16)
888        {
889           colorSrv.UsePixmaps[screen_number] = FALSE;
890           colorSrv.FgColor[screen_number] = WHITE;
891           return(16);
892        }
893        if(numOfPixelsLeft >= 12)
894        {
895           colorSrv.UsePixmaps[screen_number] = TRUE;
896           colorSrv.FgColor[screen_number] = DYNAMIC;
897           return(12);
898        }
899        else if(numOfPixelsLeft >= 8)
900        {
901           colorSrv.UsePixmaps[screen_number] = TRUE;
902           colorSrv.FgColor[screen_number] = WHITE;
903           return(8);
904        }
905        else /* can't use XmCO_MEDIUM_COLOR anymore so set to next */
906             /* highest XmCO_LOW_COLOR*/ 
907        {
908           colorSrv.TypeOfMonitor[screen_number] = XmCO_LOW_COLOR;
909           colorSrv.pCurrentPalette[screen_number]->num_of_colors = 2;
910           SwitchAItoPS(colorSrv.pCurrentPalette[screen_number]);
911        }
912     }
913
914    /* need to do an if instead of an else because TypeOfMonitor can be reset
915       in the else if above */     
916     if(colorSrv.TypeOfMonitor[screen_number] == XmCO_LOW_COLOR)
917     {
918        if(numOfPixelsLeft >= 10)
919        {
920           colorSrv.UsePixmaps[screen_number] = FALSE;
921           colorSrv.FgColor[screen_number] = DYNAMIC;
922           return(10);
923        }
924        else if(numOfPixelsLeft >= 8)
925        {
926           colorSrv.UsePixmaps[screen_number] = FALSE;
927           colorSrv.FgColor[screen_number] = WHITE;
928           return(8);
929        }
930        else if(numOfPixelsLeft >= 6)
931        {
932           colorSrv.UsePixmaps[screen_number] = TRUE;
933           colorSrv.FgColor[screen_number] = DYNAMIC;
934           return(6);
935        }
936        else if(numOfPixelsLeft >= 4)
937        {
938           colorSrv.UsePixmaps[screen_number] = TRUE;
939           colorSrv.FgColor[screen_number] = WHITE;
940           return(4);
941        }
942    }
943    /* should never get here */
944    return(0);
945 }
946
947 /****************************************************************************
948 **
949 ** FindNumOfPixels ... routine used to determine the num of allocable cells
950 ** left in the default colormap.  With this number we can determine the
951 ** Maximum default for the user
952 **
953 ******************************************************************************/
954 static int 
955 FindNumOfPixels(
956         Display *dpy,
957         int screen_number )
958 {
959     unsigned long   *pixels;
960     unsigned long   plane_mask;
961     int  i, iterations, status;
962     int  num_of_pixels, count, base, countdown;
963     Colormap colormap;
964
965     colormap = DefaultColormap(dpy, screen_number);
966
967    /* get the total number of cells in this screen */
968     num_of_pixels = XDisplayCells(dpy, screen_number);
969
970    /* get the number of iterations to be used .. the number of plane in this
971       screen */
972     iterations = XDisplayPlanes(dpy, screen_number);
973
974    /* Allocate enough space to store the pixels.  */
975     pixels = (unsigned long *)SRV_MALLOC (num_of_pixels * sizeof (unsigned long));
976
977   /* now iterate through until the we know how many cells are available */
978     count = num_of_pixels;
979     countdown = count;
980     base = 0;
981     for(i = 0; i < iterations; i++)
982     {
983        status = XAllocColorCells (dpy, colormap, (Boolean)0, &plane_mask,
984                                                    0, pixels, count);
985
986        countdown = countdown / 2;
987        if(status == False)
988        {
989           count = base + countdown;
990        }
991        else
992        {
993           XFreeColors(dpy, colormap, pixels, count, (unsigned long)0);
994           if(count != num_of_pixels)
995           {
996              base = count;
997              count = base + countdown;
998           }
999        }
1000     }
1001     status = XAllocColorCells (dpy, colormap, (Boolean)0, &plane_mask,
1002                                                    0, pixels, count);
1003     if(status == False)
1004        count--;
1005     else
1006        XFreeColors(dpy, colormap, pixels, count, (unsigned long)0);
1007     SRV_FREE((char *) pixels);
1008     return(count);
1009 }
1010
1011 /************************************************************************
1012 **
1013 ** GetNumOfPixels - returns the number of pixels to allocate based on the
1014 **        resources ColorUse(TypeOfMonitor), ShadowPixmaps(UsePixmaps),
1015 **        and ForegroundColor(FgColor).
1016 **
1017 ************************************************************************/
1018 static int 
1019 GetNumOfPixels(
1020         int screen_number )
1021 {
1022
1023    if(colorSrv.TypeOfMonitor[screen_number] == XmCO_BLACK_WHITE)
1024    {
1025       return(0);
1026    }
1027    else  /* non Black and White monitor */
1028    {
1029       if(colorSrv.UsePixmaps[screen_number] == FALSE)
1030       {
1031          if(colorSrv.FgColor[screen_number] == DYNAMIC) 
1032          {
1033             return(colorSrv.pCurrentPalette[screen_number]->num_of_colors * 5);
1034          }
1035          else  /*FgColor == BLACK or WHITE ... bg, ts, bs, & sc used */
1036          {
1037             return(colorSrv.pCurrentPalette[screen_number]->num_of_colors * 4);
1038          }
1039       }
1040       else  /* UsePixmaps == True */
1041       {
1042          if(colorSrv.FgColor[screen_number] == DYNAMIC) /* fg, bg, & sc used */
1043          {
1044             return(colorSrv.pCurrentPalette[screen_number]->num_of_colors * 3);
1045          }
1046          else  /*FgColor == BLACK or WHITE ... bg & sc used */
1047          {
1048             return(colorSrv.pCurrentPalette[screen_number]->num_of_colors * 2);
1049          }
1050       }
1051    }
1052 }
1053
1054 /************************************************************************
1055 **
1056 ** MatchAndStore - match the pixels already allocated with the current
1057 **        palettes storage .. then do a Store Colors to set the colors
1058 **        correctly at the X server.
1059 **
1060 ************************************************************************/
1061 static void 
1062 MatchAndStore(
1063         Display *dpy,
1064         int screen_number,
1065         unsigned long *pixels )
1066 {
1067    int i, count = 0;
1068    struct _palette    *p;
1069    XColor *xcolor;
1070
1071    p = colorSrv.pCurrentPalette[screen_number];
1072    xcolor = (XColor *)SRV_MALLOC (p->num_of_colors * 5 * sizeof (XColor));
1073
1074    for(i = 0; i < p->num_of_colors; i++) 
1075    {
1076       /* Background Pixel */
1077       p->color[i].bg.pixel = pixels[count];
1078       p->color[i].bg.flags = DoRed | DoGreen | DoBlue;
1079       xcolor[count] = p->color[i].bg;
1080       count++;
1081
1082       /* SelectColor (ArmColor) Pixel */
1083       p->color[i].sc.pixel = pixels[count];
1084       p->color[i].sc.flags = DoRed | DoGreen | DoBlue;
1085       xcolor[count] = p->color[i].sc;
1086       count++;
1087
1088       if(colorSrv.UsePixmaps[screen_number] == FALSE)
1089       {
1090          /* TopShadow Pixel */
1091          p->color[i].ts.pixel = pixels[count];
1092          p->color[i].ts.flags = DoRed | DoGreen | DoBlue;
1093          xcolor[count] = p->color[i].ts;
1094          count++;
1095
1096          /* BottomShadow Pixel */
1097          p->color[i].bs.pixel = pixels[count];
1098          p->color[i].bs.flags = DoRed | DoGreen | DoBlue;
1099          xcolor[count] = p->color[i].bs;
1100          count++;
1101       }
1102       else  /* colorSrv.UsePixmaps = True */
1103       {
1104          /* TopShadow Pixel set to white */
1105          p->color[i].ts.pixel = WhitePixel(dpy,screen_number);
1106          p->color[i].ts.flags = 0;
1107
1108          /* BottomShadow Pixel set to black */
1109          p->color[i].bs.pixel = BlackPixel(dpy,screen_number);
1110          p->color[i].bs.flags = 0;
1111       }
1112       if(colorSrv.FgColor[screen_number] == DYNAMIC)
1113       {
1114          /* Foreground Pixel */
1115          p->color[i].fg.pixel = pixels[count];
1116          p->color[i].fg.flags = DoRed | DoGreen | DoBlue;
1117          xcolor[count] = p->color[i].fg;
1118          count++;
1119       }
1120       else if(colorSrv.FgColor[screen_number] == BLACK)
1121       {
1122          /* Foreground Pixel set to BLACK */
1123          p->color[i].fg.pixel = BlackPixel(dpy,screen_number);
1124          p->color[i].fg.flags = 0;
1125       }
1126       else
1127       {
1128          /* Foreground Pixel set to WHITE */
1129          p->color[i].fg.pixel = WhitePixel(dpy,screen_number);
1130          p->color[i].fg.flags = 0;
1131       }
1132    } /* for */
1133
1134    if (count > 0)
1135    {
1136      XStoreColors(dpy, DefaultColormap(dpy, screen_number), xcolor, count);
1137    }
1138
1139    SRV_FREE((char *) xcolor);
1140 }
1141
1142 /************************************************************************
1143 **
1144 ** AllocReadWrite - Allocates Read/Write cells for use by the color
1145 **        server.  If the X server can't allocate enough cells (numOfPixels)
1146 **        this routine finds the number of pixels available, and sets
1147 **        the varibles TypeOfMonitor, UsePixmaps, and FgColor accordingly.
1148 **
1149 ************************************************************************/
1150 static Boolean 
1151 AllocReadWrite(
1152         Display *dpy,
1153         int screen_number,
1154         int numOfPixels )
1155 {
1156    char *tmpStr;
1157    unsigned long *pixels;
1158    unsigned long plane_mask;
1159    int status;
1160
1161   /* Allocate enough space to store the pixels. */
1162    pixels = (unsigned long *)SRV_MALLOC (numOfPixels * sizeof (unsigned long));
1163
1164   /* Now actually allocate R/W pixels */
1165    status = XAllocColorCells (dpy, DefaultColormap(dpy, screen_number),
1166                               (Boolean)0, &plane_mask, 0, pixels, numOfPixels);
1167
1168   /* When status is false means the alloc couldn't get all the pixels 
1169     the user wanted or what the default is .. so lets go find the
1170     minumum and set up and use that */
1171    if(status == False)
1172    {
1173        SRV_FREE((char *) pixels);
1174        numOfPixels = FindMaximumDefault(dpy, screen_number);
1175        if(numOfPixels == 0)
1176        {
1177             tmpStr = (char *)SRV_MALLOC(strlen(MSG3) + 6);
1178             sprintf(tmpStr,"%s%d", MSG3, screen_number);
1179             _DtSimpleError(XmSCOLOR_SRV_NAME, DtWarning, NULL, tmpStr, NULL);
1180             SRV_FREE(tmpStr);
1181             return(False);
1182        }
1183        else
1184        {
1185            if(colorSrv.TypeOfMonitor[screen_number] != XmCO_BLACK_WHITE)
1186            {
1187            /* Allocate enough space to store the pixels. */
1188               pixels = (unsigned long *)SRV_MALLOC (numOfPixels *
1189                                             sizeof (unsigned long));
1190
1191         /* Now actually allocate R/W pixels */
1192               status = XAllocColorCells(dpy, DefaultColormap(dpy,screen_number),
1193                             (Boolean)0, &plane_mask, 0, pixels, numOfPixels);
1194
1195               if(status == False)
1196               {
1197                  SRV_FREE((char *) pixels);
1198                  _DtSimpleError(XmSCOLOR_SRV_NAME, DtWarning, NULL, ((char *)GETMESSAGE(26, 5, "Warning, can't allocate enough pixels.\n")), NULL);
1199                  return(False);
1200               }
1201            }
1202        }
1203    }
1204
1205    if(colorSrv.TypeOfMonitor[screen_number] != XmCO_BLACK_WHITE)
1206    {
1207      /* Go match pixels allocated with the colorsets then use store
1208         XStoreColors to set the RGB values of them */
1209       MatchAndStore(dpy, screen_number, pixels);
1210
1211    } 
1212
1213   /* free the allocated space for pixels */
1214    SRV_FREE((char *) pixels);
1215    return(True);
1216
1217
1218 /************************************************************************
1219 **
1220 ** AllocReadOnly - Allocates Read Only cells for use by the color
1221 **        server.  If the X server can't allocate the cell it finds the
1222 **        closest approximation to the color of a cell already allocated.
1223 **        Therefore there is no error recorded.  
1224 **
1225 ************************************************************************/
1226 static void 
1227 AllocReadOnly(
1228         Display *dpy,
1229         int screen_number )
1230 {
1231    int i;
1232
1233    for(i=0; i < colorSrv.pCurrentPalette[screen_number]->num_of_colors; i++)
1234    {
1235       XAllocColor(dpy, DefaultColormap(dpy, screen_number),
1236                 &(colorSrv.pCurrentPalette[screen_number]->color[i].bg));
1237       XAllocColor(dpy, DefaultColormap(dpy, screen_number),
1238                 &(colorSrv.pCurrentPalette[screen_number]->color[i].sc));
1239
1240     /* Check UsePixmaps varible */
1241       if(colorSrv.UsePixmaps[screen_number] == FALSE)
1242       {
1243          XAllocColor(dpy, DefaultColormap(dpy, screen_number),
1244                      &(colorSrv.pCurrentPalette[screen_number]->color[i].ts));
1245          XAllocColor(dpy, DefaultColormap(dpy, screen_number),
1246                      &(colorSrv.pCurrentPalette[screen_number]->color[i].bs));
1247       }
1248       else /* colorSrv.UsePixmaps[screen_number] == True */
1249       {
1250          colorSrv.pCurrentPalette[screen_number]->color[i].ts.pixel =
1251                                           WhitePixel(dpy,screen_number);
1252          colorSrv.pCurrentPalette[screen_number]->color[i].bs.pixel =
1253                                           BlackPixel(dpy,screen_number);
1254       }
1255
1256     /* Check FgColor varible */
1257       if(colorSrv.FgColor[screen_number] == DYNAMIC)
1258          XAllocColor(dpy, DefaultColormap(dpy, screen_number),
1259                      &(colorSrv.pCurrentPalette[screen_number]->color[i].fg));
1260
1261       else if(colorSrv.FgColor[screen_number] == BLACK)
1262          colorSrv.pCurrentPalette[screen_number]->color[i].fg.pixel =
1263                                           BlackPixel(dpy,screen_number);
1264
1265       else
1266          colorSrv.pCurrentPalette[screen_number]->color[i].fg.pixel =
1267                                           WhitePixel(dpy,screen_number);
1268    }
1269
1270
1271 /*********************************************************************
1272 **
1273 ** Converter which converts a string to the ColorUse value 
1274 **
1275 **********************************************************************/
1276 static void 
1277 CvtStringToColorUse(
1278         XrmValue *args,
1279         Cardinal *num_args,
1280         XrmValue *from_val,
1281         XrmValue *to_val )
1282 {
1283    char * in_str = (char *) (from_val->addr);
1284    static int i;
1285
1286    to_val->size = sizeof (int);
1287    to_val->addr = (XtPointer) &i;
1288
1289    if (_DtWmStringsAreEqual (in_str, "high_color"))
1290       i = XmCO_HIGH_COLOR;
1291    else if (_DtWmStringsAreEqual (in_str, "medium_color"))
1292       i = XmCO_MEDIUM_COLOR;
1293    else if (_DtWmStringsAreEqual (in_str, "low_color"))
1294       i = XmCO_LOW_COLOR;
1295    else if (_DtWmStringsAreEqual (in_str, "b_w"))
1296       i = XmCO_BLACK_WHITE;
1297    else if (_DtWmStringsAreEqual (in_str, "default"))
1298       i = DEFAULT;
1299    else
1300    {
1301       to_val->size = 0;
1302       to_val->addr = NULL;
1303       XtStringConversionWarning ((char *)from_val->addr, DtRColorUse);
1304    }
1305 }
1306 /**********************************************************************
1307 **
1308 ** Converter which converts a string to the ForegroundColor value 
1309 **
1310 **********************************************************************/
1311 static void 
1312 CvtStringToForegroundColor(
1313         XrmValue *args,
1314         Cardinal *num_args,
1315         XrmValue *from_val,
1316         XrmValue *to_val )
1317 {
1318    char * in_str = (char *) (from_val->addr);
1319    static int i;
1320
1321    to_val->size = sizeof (int);
1322    to_val->addr = (XtPointer) &i;
1323
1324    if (_DtWmStringsAreEqual (in_str, "dynamic"))
1325       i = DYNAMIC;
1326    else if (_DtWmStringsAreEqual (in_str, "black"))
1327       i = BLACK;
1328    else if (_DtWmStringsAreEqual (in_str, "white"))
1329       i = WHITE;
1330    else
1331    {
1332       to_val->size = 0;
1333       to_val->addr = NULL;
1334       XtStringConversionWarning ((char *)from_val->addr, DtRForegroundColor);
1335    }
1336 }
1337
1338 /***********************************************************************
1339 **
1340 ** Converter which converts a string to the ShadowPixmaps value 
1341 **
1342 ***********************************************************************/
1343 static void 
1344 CvtStringToShadowPixmaps(
1345         XrmValue *args,
1346         Cardinal *num_args,
1347         XrmValue *from_val,
1348         XrmValue *to_val )
1349 {
1350    char * in_str = (char *) (from_val->addr);
1351    static int i;
1352
1353    to_val->size = sizeof (int);
1354    to_val->addr = (XtPointer) &i;
1355
1356    if (_DtWmStringsAreEqual (in_str, "true"))
1357       i = 1;
1358    else if (_DtWmStringsAreEqual (in_str, "false"))
1359       i = 0;
1360    else if (_DtWmStringsAreEqual (in_str, "default"))
1361       i = -1;
1362    else
1363    {
1364       to_val->size = 0;
1365       to_val->addr = NULL;
1366       XtStringConversionWarning ((char *)from_val->addr, DtRShadowPixmaps);
1367    }
1368 }
1369
1370 /************************************************************************
1371  *
1372  *  _DtWmStringsAreEqual
1373  *      Compare two strings and return true if equal.
1374  *      The comparison is on lower cased strings.  It is the callers
1375  *      responsibility to ensure that test_str is already lower cased.
1376  *
1377  ************************************************************************/
1378 static Boolean 
1379 _DtWmStringsAreEqual(
1380         register char *in_str,
1381         register char *test_str )
1382
1383 {
1384    register int i;
1385    register int j;
1386    i = *in_str;
1387
1388    for (;;)
1389    {
1390       i = *in_str;
1391       j = *test_str;
1392
1393 #ifdef MULTIBYTE
1394       if ((mblen(in_str, MB_CUR_MAX) == 1))
1395           if (isupper (i)) i = tolower (i);
1396 #else
1397           if (isupper (i)) i = tolower (i);
1398 #endif
1399       if (i != j) return (False);
1400       if (i == 0) return (True);
1401
1402       in_str++;
1403       test_str++;
1404    }
1405 }
1406   
1407 /************************************************************************
1408  *
1409  * SetDefaults - set the TypeOfMonitor, UsePixmaps, FgColor, and DynamicColor
1410  *       for the screen passed in.  Use the resource values, the number of
1411  *       colors for this screen, and the visual type of the screen to 
1412  *       determine which values best fit.
1413  *
1414  *************************************************************************/
1415 static void 
1416 SetDefaults(
1417         Display *dpy,
1418         int screen_number )
1419 {
1420    int numPlanes;
1421    Visual *visual;
1422
1423    /* Initialize colorSrv data for this screen with specified resource values */
1424    colorSrv.UsePixmaps[screen_number] = pColorSrvRsrc.ShadowPixmaps;
1425    colorSrv.DynamicColor[screen_number] = pColorSrvRsrc.DynamicColor;
1426
1427    /* If this is a static color visual class, set DynamicColor to False. */
1428    visual = XDefaultVisual(dpy, screen_number);
1429
1430
1431    /* GrayScale and PseudoColor are the only visual types that make */
1432    /* sense to change dynamically with the current implementation   */
1433    if ((visual->class != GrayScale) && (visual->class != PseudoColor))
1434       colorSrv.DynamicColor[screen_number] = False;
1435
1436    /* if not specified, set ColorPalette default */
1437    if (strcmp(pColorSrvRsrc.ColorPalette,"DEFAULT") == 0)
1438    {
1439       if ((visual->class == GrayScale) || (visual->class == StaticGray))
1440       {
1441           pColorSrvRsrc.ColorPalette = 
1442                 XtMalloc(strlen(DEFAULT_GRAYSCALE_PALETTE)+1);
1443           strcpy(pColorSrvRsrc.ColorPalette, DEFAULT_GRAYSCALE_PALETTE);
1444       }
1445       else
1446       {
1447           pColorSrvRsrc.ColorPalette = 
1448                 XtMalloc(strlen(DEFAULT_COLOR_PALETTE)+1);
1449           strcpy(pColorSrvRsrc.ColorPalette, DEFAULT_COLOR_PALETTE);
1450       }
1451    }
1452
1453    numPlanes = XDisplayPlanes(dpy, screen_number);
1454
1455    if( numPlanes < 3) /* 1 or 2 planes */
1456    { 
1457       colorSrv.TypeOfMonitor[screen_number] = XmCO_BLACK_WHITE;
1458       colorSrv.DynamicColor[screen_number] = False;
1459    }
1460    else if( numPlanes == 3 ) /* 3 planes */
1461    {
1462       switch(pColorSrvRsrc.ColorUse) {
1463          case XmCO_LOW_COLOR:
1464             colorSrv.TypeOfMonitor[screen_number] = XmCO_LOW_COLOR;
1465             break;
1466          default:
1467             colorSrv.TypeOfMonitor[screen_number] = XmCO_BLACK_WHITE;
1468             colorSrv.DynamicColor[screen_number] = False;
1469       }
1470       /* for 3 planes UsePixmaps (ShadowPixmaps) have to be on (TRUE) */
1471       colorSrv.UsePixmaps[screen_number] = 1;
1472    }
1473    else if( numPlanes == 4 ) /* 4 planes */
1474    {
1475       switch(pColorSrvRsrc.ColorUse) {
1476          case XmCO_MEDIUM_COLOR:
1477            /* for 4 planes ColorUse = Med_color shadowPixmaps have to be True */
1478             pColorSrvRsrc.ShadowPixmaps = -1;
1479             colorSrv.TypeOfMonitor[screen_number] = XmCO_MEDIUM_COLOR;
1480             break;
1481          case XmCO_BLACK_WHITE:
1482             colorSrv.TypeOfMonitor[screen_number] = XmCO_BLACK_WHITE;
1483             colorSrv.DynamicColor[screen_number] = False;
1484             break;
1485          default:
1486             colorSrv.TypeOfMonitor[screen_number] = XmCO_LOW_COLOR;
1487       }
1488
1489      /* check to see what type of shadow pixmap to use */
1490       if(pColorSrvRsrc.ShadowPixmaps == -1)
1491          colorSrv.UsePixmaps[screen_number] = 1;
1492    }
1493    else if( numPlanes == 5 ) /* 5 planes */
1494    {
1495       switch(pColorSrvRsrc.ColorUse) {
1496          case XmCO_HIGH_COLOR:
1497            /* for 5 planes ColorUse = hi_color shadowPixmaps have to be True */
1498             pColorSrvRsrc.ShadowPixmaps = -1;
1499             colorSrv.TypeOfMonitor[screen_number] = XmCO_HIGH_COLOR; 
1500             break; 
1501          case XmCO_MEDIUM_COLOR:
1502             colorSrv.TypeOfMonitor[screen_number] = XmCO_MEDIUM_COLOR;
1503             break;
1504          case XmCO_BLACK_WHITE:
1505             colorSrv.TypeOfMonitor[screen_number] = XmCO_BLACK_WHITE;
1506             colorSrv.DynamicColor[screen_number] = False;
1507             break;
1508          default:
1509             colorSrv.TypeOfMonitor[screen_number] = XmCO_LOW_COLOR;
1510       }
1511    }
1512    else /* 6 and above planes */
1513    {
1514       switch(pColorSrvRsrc.ColorUse) {
1515          case XmCO_HIGH_COLOR:
1516             colorSrv.TypeOfMonitor[screen_number] = XmCO_HIGH_COLOR;
1517             break;
1518          case XmCO_LOW_COLOR:
1519             colorSrv.TypeOfMonitor[screen_number] = XmCO_LOW_COLOR;
1520             break;
1521          case XmCO_BLACK_WHITE:
1522             colorSrv.TypeOfMonitor[screen_number] = XmCO_BLACK_WHITE;
1523             colorSrv.DynamicColor[screen_number] = False;
1524             break;
1525          default:
1526             colorSrv.TypeOfMonitor[screen_number] = XmCO_MEDIUM_COLOR;
1527       }
1528
1529      /* check to see what type of shadow pixmap to use */
1530       if(pColorSrvRsrc.ShadowPixmaps == -1)
1531          colorSrv.UsePixmaps[screen_number] = 0;
1532    }
1533
1534  /* Determine the correct foreground color useage */
1535    switch(pColorSrvRsrc.ForegroundColor) {
1536       case BLACK:
1537          colorSrv.FgColor[screen_number] = BLACK;
1538          break;
1539       case WHITE:
1540          colorSrv.FgColor[screen_number] = WHITE;
1541          break;
1542       default:
1543          colorSrv.FgColor[screen_number] = DYNAMIC;
1544   }
1545 }