2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
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)
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
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
25 "$TOG: SrvPalette.c /main/13 1998/07/23 18:08:39 mgreess $";
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. *
34 /**********************************<+>*************************************
35 ***************************************************************************
39 ** Project: HP DT Style Manager , integrated into dtsession
43 ** This is the main program for the color server portion of the dt session
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
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
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 ********************************************************************
62 **************************************************************************
63 **********************************<+>*************************************/
67 #include <X11/Xatom.h>
69 #include "SrvFile_io.h"
70 #include "SrvPalette.h"
79 #define SRVBUFSIZE 1024
80 #define DEFAULT_COLOR_PALETTE "Default.dp"
81 #define DEFAULT_GRAYSCALE_PALETTE "GrayScale.dp"
83 #define DtRColorUse "ColorUse"
84 #define DtRForegroundColor "ForegroundColor"
85 #define DtRShadowPixmaps "ShadowPixmaps"
87 #define TYPE_OF_MONITOR "Type Of Monitor" /* also in dtstyle/ColorMain.c */
89 /* global color server struct */
93 /*************************
94 * Color Server Resources
95 *************************/
100 Boolean DynamicColor;
101 Boolean WriteXrdbColors;
103 char *MonochromePalette;
104 } Appdata, *AppdataPtr;
106 static XtResource resources[] = {
112 XtOffset(AppdataPtr, ColorUse),
120 XtOffset(AppdataPtr, ShadowPixmaps),
128 XtOffset(AppdataPtr, ForegroundColor),
136 XtOffset(AppdataPtr, DynamicColor),
144 XtOffset(AppdataPtr, WriteXrdbColors),
152 XtOffset(AppdataPtr, ColorPalette),
154 (XtPointer)"DEFAULT"},
156 { "monochromePalette",
160 XtOffset(AppdataPtr, MonochromePalette),
162 (XtPointer)"Black.dp"},
165 Appdata pColorSrvRsrc;
167 /************************************
169 ***********************************/
171 Widget shell[MAX_NUM_SCREENS];
173 /******** Static Function Declarations ********/
175 static Boolean AllocateColors(
177 static char *convert_pixel_set(
180 static Boolean convert_selection(
186 unsigned long *length,
188 static void lose_selection(
191 static int FindMaximumDefault(
194 static int FindNumOfPixels(
197 static int GetNumOfPixels(
199 static void MatchAndStore(
202 unsigned long *pixels) ;
203 static Boolean AllocReadWrite(
207 static void AllocReadOnly(
210 static void CvtStringToColorUse(
215 static void CvtStringToForegroundColor(
220 static void CvtStringToShadowPixmaps(
225 static Boolean _DtWmStringsAreEqual(
226 register char *in_str,
227 register char *test_str) ;
228 static void SetDefaults(
232 static void _DtCacheProperties(
235 /******** End Static Function Declarations ********/
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."))
242 /***********************************************************************
244 * InitializeDtcolor - calls all the routines which do the initialization
245 * for the color server.
247 **********************************************************************/
253 int status, screen_number;
254 char xrdb_string[100];
256 /* find out what type of monitor(s?) is being used */
257 status = CheckMonitor(dpy);
261 /* Allocate colors for the default palette */
266 screen_number != colorSrv.NumOfScreens;
269 /* Set disown selections of the pixel set atoms */
270 XtDisownSelection(shell[screen_number],
271 colorSrv.XA_CUSTOMIZE[screen_number],
277 /* don't set resources if writeXrdbColors == false */
278 if (!pColorSrvRsrc.WriteXrdbColors)
282 OWsyncColorResources(dpy, colorSrv.TypeOfMonitor[0],
283 colorSrv.pCurrentPalette[0]->color);
284 OWsyncLocaleResources(dpy);
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)
291 int chipnum = colorSrv.TypeOfMonitor[0] == XmCO_HIGH_COLOR ? 4 : 1;
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);
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 */
306 if(strcmp(colorSrv.pCurrentPalette[0]->name, W_O_B) == 0 ||
307 strcmp(colorSrv.pCurrentPalette[0]->name, B_ONLY) == 0)
310 "*background: #000000000000\n*foreground: #FFFFFFFFFFFF\n");
315 "*background: #FFFFFFFFFFFF\n*foreground: #000000000000\n");
318 /* go merge the xrdb_string into the xrdb */
319 _DtAddToResource(dpy, xrdb_string);
322 _DtCacheProperties(dpy, XtWindow(shell[0])) ;
332 Atom pixel_set_atom ;
333 struct _palette *palette ;
336 int screen_number = 0 ; /*assuming simple case i.e. screen 0 */
338 pixel_set_atom = XInternAtom(dpy, XmSPIXEL_SET_PROP, FALSE) ;
340 palette = colorSrv.pCurrentPalette[screen_number];
341 typeOfMonitor = colorSrv.TypeOfMonitor[screen_number];
342 if (palette->converted == NULL)
344 palette->converted = convert_pixel_set(typeOfMonitor, palette->color);
345 palette->converted_len = strlen(palette->converted);
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) ;
356 /*****************************************************************************
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
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
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
381 ** 13 BLACK_WHITE AT Aways opposite 0
384 ***************************************************************************/
392 /* Determine how many pixels to allocate (numOfPixels) */
393 for(screen_number=0;screen_number != colorSrv.NumOfScreens;screen_number++)
395 numOfPixels = GetNumOfPixels(screen_number);
397 /* Now allocate the correct number of pixels using numOfPixels */
398 if(numOfPixels != 0) /* Not XmCO_BLACK_WHITE */
400 if(colorSrv.DynamicColor[screen_number] == True)
402 /* go allocate Read/Write cells for the color server */
403 if(!AllocReadWrite(dpy, screen_number, numOfPixels))
407 /* go allocate Read Only cells for the color server */
408 AllocReadOnly(dpy, screen_number);
411 if(colorSrv.TypeOfMonitor[screen_number] == XmCO_BLACK_WHITE)
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;
420 palettes *palette = colorSrv.pCurrentPalette[screen_number];
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)))
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);
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);
439 if(!(strcmp(colorSrv.pCurrentPalette[screen_number]->name, B_O_W)))
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);
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);
454 if(!(strcmp(colorSrv.pCurrentPalette[screen_number]->name, W_ONLY)))
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);
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);
468 else /* black only */
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);
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);
486 } /* for screen_number=0 ; screen_number < NumOfScreens; screen_number++ */
491 /************************************************************************
493 ** CheckMonitor - check to determine which type of monitor each of the
494 ** screens on the server is running on.
496 ************************************************************************/
501 int n, screen_number, result;
503 char screenStr[5], cust_msg[24];
505 char tmpPalette[SRVBUFSIZE];
510 XtAppContext app_context;
512 /* Determine the number of screens attached to this server */
513 colorSrv.NumOfScreens = ScreenCount(dpy);
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);
519 /* create a top level shell to retrieve subresources from */
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,
530 /* create an application context */
531 app_context = XtWidgetToApplicationContext(mainShell);
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);
541 /* cycle through each screen */
542 for(screen_number=0;screen_number != colorSrv.NumOfScreens;screen_number++)
544 sprintf(screenStr,"%d",screen_number);
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,
556 * widget needs to be realized for the window ID for
560 XtRealizeWidget(shell[screen_number]);
562 sprintf(cust_msg,"%s%d", XmSCUSTOMIZE_DATA, screen_number);
563 colorSrv.XA_CUSTOMIZE[screen_number] =
564 XInternAtom(dpy, cust_msg, FALSE);
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);
575 * Don't forget to add length for the extra characters.
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);
585 /* Get the colorserver resources for this screen */
587 XtGetSubresources(mainShell, &pColorSrvRsrc, screenStr, screenStr,
588 resources, XtNumber(resources), NULL, 0);
591 * Set TypeOfMonitor, UsePixmaps FgColor and
592 * DynamicColor for this screen
595 SetDefaults(dpy, screen_number);
597 if (colorSrv.TypeOfMonitor[screen_number] != XmCO_BLACK_WHITE)
599 colorSrv.pCurrentPalette[screen_number] =
600 (struct _palette *) GetPaletteDefinition(dpy,
602 pColorSrvRsrc.ColorPalette);
606 /* Allocate space for new palette. */
607 colorSrv.pCurrentPalette[screen_number] =
608 (struct _palette *) SRV_MALLOC( sizeof(struct _palette) + 1 );
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;
622 if (colorSrv.pCurrentPalette[screen_number] == (struct _palette *) NULL)
627 /* write out the color or monochrome palette resource for the screen */
629 xrdb_string = XtMalloc(BUFSIZ);
631 if (colorSrv.TypeOfMonitor[0] == XmCO_HIGH_COLOR ||
632 colorSrv.TypeOfMonitor[0] == XmCO_MEDIUM_COLOR ||
633 colorSrv.TypeOfMonitor[0] == XmCO_LOW_COLOR)
635 sprintf(xrdb_string, "*%d*ColorPalette: %s%s\n",
637 colorSrv.pCurrentPalette[screen_number]->name,
640 else /* XmCO_BLACK_WHITE */
642 sprintf(xrdb_string, "*%d*MonochromePalette: %s%s\n",
644 colorSrv.pCurrentPalette[screen_number]->name,
647 _DtAddToResource(dpy, xrdb_string);
651 } /* for each screen */
655 /************************************************************************
657 ** convert_pixel_set - converts palette pixel set to selection format
659 ************************************************************************/
668 int colormappingindex = 0;
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 */
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 */
686 switch(typeOfMonitor)
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;
694 p = converted = (char *)SRV_MALLOC(400);
696 /* lead the string with the type of monitor */
697 p += sprintf(p, "%x_", typeOfMonitor);
699 for (i = 0; i < NUM_OF_COLORS; i++)
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);
712 /************************************************************************
714 ** convert_selection - Callback, called when some other client wishes
715 ** to get information from the dtcolor (color server)
717 ************************************************************************/
725 unsigned long *length,
729 int i, screen_number = 0;
731 char *str_type_return;
732 XrmValue value_return;
735 char instanceName[30], instanceClass[30];
737 struct _palette *palette;
741 /* Determine for which screen the selection came from */
742 for(i=0; i < MAX_NUM_SCREENS; i++)
744 if(colorSrv.XA_CUSTOMIZE[i] == *selection)
751 palette = colorSrv.pCurrentPalette[screen_number];
752 typeOfMonitor = colorSrv.TypeOfMonitor[screen_number];
754 if(*target == colorSrv.XA_PIXEL_SET)
756 /* wants to know the pixels allocated for the palette */
758 if (palette->converted == NULL)
760 palette->converted = convert_pixel_set(typeOfMonitor, palette->color);
761 palette->converted_len = strlen(palette->converted);
765 *length = palette->converted_len;
766 *value = XtNewString(palette->converted);
770 else if(*target == colorSrv.XA_TYPE_MONITOR)
772 /* wants to know ColorUse, ShadowPixmaps, ForegroundColor,
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);
789 /************************************************************************
791 ** lose_selection - Callback, called when some other client wishes
792 ** to take ownership of one of the servers selections ...
793 ** should never happen.
795 ************************************************************************/
801 char *tmpStr, *tmpStr2, *tmpStr3;
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) ;
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);
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);
821 /*****************************************************************************
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.
828 ******************************************************************************/
836 /* go find the Number of pixels left to allocate */
837 numOfPixelsLeft = FindNumOfPixels(dpy, screen_number);
839 if(numOfPixelsLeft < 4)
841 /* Use Black and White */
842 colorSrv.TypeOfMonitor[screen_number] = XmCO_BLACK_WHITE;
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))
852 /* should never get here */
855 else if(colorSrv.TypeOfMonitor[screen_number] == XmCO_HIGH_COLOR)
857 if(numOfPixelsLeft >= 32) /* was asking for 40 */
859 colorSrv.UsePixmaps[screen_number] = FALSE;
860 colorSrv.FgColor[screen_number] = WHITE;
863 else if(numOfPixelsLeft >= 24)
865 colorSrv.UsePixmaps[screen_number] = TRUE;
866 colorSrv.FgColor[screen_number] = DYNAMIC;
869 else if(numOfPixelsLeft >= 16)
871 colorSrv.UsePixmaps[screen_number] = TRUE;
872 colorSrv.FgColor[screen_number] = WHITE;
875 else /* can't use XmCO_HIGH_COLOR anymore so set to
876 next highest XmCO_MEDIUM_COLOR */
878 colorSrv.TypeOfMonitor[screen_number] = XmCO_MEDIUM_COLOR;
879 colorSrv.pCurrentPalette[screen_number]->num_of_colors = 4;
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)
887 if(numOfPixelsLeft >= 16)
889 colorSrv.UsePixmaps[screen_number] = FALSE;
890 colorSrv.FgColor[screen_number] = WHITE;
893 if(numOfPixelsLeft >= 12)
895 colorSrv.UsePixmaps[screen_number] = TRUE;
896 colorSrv.FgColor[screen_number] = DYNAMIC;
899 else if(numOfPixelsLeft >= 8)
901 colorSrv.UsePixmaps[screen_number] = TRUE;
902 colorSrv.FgColor[screen_number] = WHITE;
905 else /* can't use XmCO_MEDIUM_COLOR anymore so set to next */
906 /* highest XmCO_LOW_COLOR*/
908 colorSrv.TypeOfMonitor[screen_number] = XmCO_LOW_COLOR;
909 colorSrv.pCurrentPalette[screen_number]->num_of_colors = 2;
910 SwitchAItoPS(colorSrv.pCurrentPalette[screen_number]);
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)
918 if(numOfPixelsLeft >= 10)
920 colorSrv.UsePixmaps[screen_number] = FALSE;
921 colorSrv.FgColor[screen_number] = DYNAMIC;
924 else if(numOfPixelsLeft >= 8)
926 colorSrv.UsePixmaps[screen_number] = FALSE;
927 colorSrv.FgColor[screen_number] = WHITE;
930 else if(numOfPixelsLeft >= 6)
932 colorSrv.UsePixmaps[screen_number] = TRUE;
933 colorSrv.FgColor[screen_number] = DYNAMIC;
936 else if(numOfPixelsLeft >= 4)
938 colorSrv.UsePixmaps[screen_number] = TRUE;
939 colorSrv.FgColor[screen_number] = WHITE;
943 /* should never get here */
947 /****************************************************************************
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
953 ******************************************************************************/
959 unsigned long *pixels;
960 unsigned long plane_mask;
961 int i, iterations, status;
962 int num_of_pixels, count, base, countdown;
965 colormap = DefaultColormap(dpy, screen_number);
967 /* get the total number of cells in this screen */
968 num_of_pixels = XDisplayCells(dpy, screen_number);
970 /* get the number of iterations to be used .. the number of plane in this
972 iterations = XDisplayPlanes(dpy, screen_number);
974 /* Allocate enough space to store the pixels. */
975 pixels = (unsigned long *)SRV_MALLOC (num_of_pixels * sizeof (unsigned long));
977 /* now iterate through until the we know how many cells are available */
978 count = num_of_pixels;
981 for(i = 0; i < iterations; i++)
983 status = XAllocColorCells (dpy, colormap, (Boolean)0, &plane_mask,
986 countdown = countdown / 2;
989 count = base + countdown;
993 XFreeColors(dpy, colormap, pixels, count, (unsigned long)0);
994 if(count != num_of_pixels)
997 count = base + countdown;
1001 status = XAllocColorCells (dpy, colormap, (Boolean)0, &plane_mask,
1006 XFreeColors(dpy, colormap, pixels, count, (unsigned long)0);
1007 SRV_FREE((char *) pixels);
1011 /************************************************************************
1013 ** GetNumOfPixels - returns the number of pixels to allocate based on the
1014 ** resources ColorUse(TypeOfMonitor), ShadowPixmaps(UsePixmaps),
1015 ** and ForegroundColor(FgColor).
1017 ************************************************************************/
1023 if(colorSrv.TypeOfMonitor[screen_number] == XmCO_BLACK_WHITE)
1027 else /* non Black and White monitor */
1029 if(colorSrv.UsePixmaps[screen_number] == FALSE)
1031 if(colorSrv.FgColor[screen_number] == DYNAMIC)
1033 return(colorSrv.pCurrentPalette[screen_number]->num_of_colors * 5);
1035 else /*FgColor == BLACK or WHITE ... bg, ts, bs, & sc used */
1037 return(colorSrv.pCurrentPalette[screen_number]->num_of_colors * 4);
1040 else /* UsePixmaps == True */
1042 if(colorSrv.FgColor[screen_number] == DYNAMIC) /* fg, bg, & sc used */
1044 return(colorSrv.pCurrentPalette[screen_number]->num_of_colors * 3);
1046 else /*FgColor == BLACK or WHITE ... bg & sc used */
1048 return(colorSrv.pCurrentPalette[screen_number]->num_of_colors * 2);
1054 /************************************************************************
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.
1060 ************************************************************************/
1065 unsigned long *pixels )
1071 p = colorSrv.pCurrentPalette[screen_number];
1072 xcolor = (XColor *)SRV_MALLOC (p->num_of_colors * 5 * sizeof (XColor));
1074 for(i = 0; i < p->num_of_colors; i++)
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;
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;
1088 if(colorSrv.UsePixmaps[screen_number] == FALSE)
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;
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;
1102 else /* colorSrv.UsePixmaps = True */
1104 /* TopShadow Pixel set to white */
1105 p->color[i].ts.pixel = WhitePixel(dpy,screen_number);
1106 p->color[i].ts.flags = 0;
1108 /* BottomShadow Pixel set to black */
1109 p->color[i].bs.pixel = BlackPixel(dpy,screen_number);
1110 p->color[i].bs.flags = 0;
1112 if(colorSrv.FgColor[screen_number] == DYNAMIC)
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;
1120 else if(colorSrv.FgColor[screen_number] == BLACK)
1122 /* Foreground Pixel set to BLACK */
1123 p->color[i].fg.pixel = BlackPixel(dpy,screen_number);
1124 p->color[i].fg.flags = 0;
1128 /* Foreground Pixel set to WHITE */
1129 p->color[i].fg.pixel = WhitePixel(dpy,screen_number);
1130 p->color[i].fg.flags = 0;
1136 XStoreColors(dpy, DefaultColormap(dpy, screen_number), xcolor, count);
1139 SRV_FREE((char *) xcolor);
1142 /************************************************************************
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.
1149 ************************************************************************/
1157 unsigned long *pixels;
1158 unsigned long plane_mask;
1161 /* Allocate enough space to store the pixels. */
1162 pixels = (unsigned long *)SRV_MALLOC (numOfPixels * sizeof (unsigned long));
1164 /* Now actually allocate R/W pixels */
1165 status = XAllocColorCells (dpy, DefaultColormap(dpy, screen_number),
1166 (Boolean)0, &plane_mask, 0, pixels, numOfPixels);
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 */
1173 SRV_FREE((char *) pixels);
1174 numOfPixels = FindMaximumDefault(dpy, screen_number);
1175 if(numOfPixels == 0)
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);
1185 if(colorSrv.TypeOfMonitor[screen_number] != XmCO_BLACK_WHITE)
1187 /* Allocate enough space to store the pixels. */
1188 pixels = (unsigned long *)SRV_MALLOC (numOfPixels *
1189 sizeof (unsigned long));
1191 /* Now actually allocate R/W pixels */
1192 status = XAllocColorCells(dpy, DefaultColormap(dpy,screen_number),
1193 (Boolean)0, &plane_mask, 0, pixels, numOfPixels);
1197 SRV_FREE((char *) pixels);
1198 _DtSimpleError(XmSCOLOR_SRV_NAME, DtWarning, NULL, ((char *)GETMESSAGE(26, 5, "Warning, can't allocate enough pixels.\n")), NULL);
1205 if(colorSrv.TypeOfMonitor[screen_number] != XmCO_BLACK_WHITE)
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);
1213 /* free the allocated space for pixels */
1214 SRV_FREE((char *) pixels);
1218 /************************************************************************
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.
1225 ************************************************************************/
1233 for(i=0; i < colorSrv.pCurrentPalette[screen_number]->num_of_colors; i++)
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));
1240 /* Check UsePixmaps varible */
1241 if(colorSrv.UsePixmaps[screen_number] == FALSE)
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));
1248 else /* colorSrv.UsePixmaps[screen_number] == True */
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);
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));
1261 else if(colorSrv.FgColor[screen_number] == BLACK)
1262 colorSrv.pCurrentPalette[screen_number]->color[i].fg.pixel =
1263 BlackPixel(dpy,screen_number);
1266 colorSrv.pCurrentPalette[screen_number]->color[i].fg.pixel =
1267 WhitePixel(dpy,screen_number);
1271 /*********************************************************************
1273 ** Converter which converts a string to the ColorUse value
1275 **********************************************************************/
1277 CvtStringToColorUse(
1283 char * in_str = (char *) (from_val->addr);
1286 to_val->size = sizeof (int);
1287 to_val->addr = (XtPointer) &i;
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"))
1295 else if (_DtWmStringsAreEqual (in_str, "b_w"))
1296 i = XmCO_BLACK_WHITE;
1297 else if (_DtWmStringsAreEqual (in_str, "default"))
1302 to_val->addr = NULL;
1303 XtStringConversionWarning ((char *)from_val->addr, DtRColorUse);
1306 /**********************************************************************
1308 ** Converter which converts a string to the ForegroundColor value
1310 **********************************************************************/
1312 CvtStringToForegroundColor(
1318 char * in_str = (char *) (from_val->addr);
1321 to_val->size = sizeof (int);
1322 to_val->addr = (XtPointer) &i;
1324 if (_DtWmStringsAreEqual (in_str, "dynamic"))
1326 else if (_DtWmStringsAreEqual (in_str, "black"))
1328 else if (_DtWmStringsAreEqual (in_str, "white"))
1333 to_val->addr = NULL;
1334 XtStringConversionWarning ((char *)from_val->addr, DtRForegroundColor);
1338 /***********************************************************************
1340 ** Converter which converts a string to the ShadowPixmaps value
1342 ***********************************************************************/
1344 CvtStringToShadowPixmaps(
1350 char * in_str = (char *) (from_val->addr);
1353 to_val->size = sizeof (int);
1354 to_val->addr = (XtPointer) &i;
1356 if (_DtWmStringsAreEqual (in_str, "true"))
1358 else if (_DtWmStringsAreEqual (in_str, "false"))
1360 else if (_DtWmStringsAreEqual (in_str, "default"))
1365 to_val->addr = NULL;
1366 XtStringConversionWarning ((char *)from_val->addr, DtRShadowPixmaps);
1370 /************************************************************************
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.
1377 ************************************************************************/
1379 _DtWmStringsAreEqual(
1380 register char *in_str,
1381 register char *test_str )
1394 if ((mblen(in_str, MB_CUR_MAX) == 1))
1395 if (isupper (i)) i = tolower (i);
1397 if (isupper (i)) i = tolower (i);
1399 if (i != j) return (False);
1400 if (i == 0) return (True);
1407 /************************************************************************
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.
1414 *************************************************************************/
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;
1427 /* If this is a static color visual class, set DynamicColor to False. */
1428 visual = XDefaultVisual(dpy, screen_number);
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;
1436 /* if not specified, set ColorPalette default */
1437 if (strcmp(pColorSrvRsrc.ColorPalette,"DEFAULT") == 0)
1439 if ((visual->class == GrayScale) || (visual->class == StaticGray))
1441 pColorSrvRsrc.ColorPalette =
1442 XtMalloc(strlen(DEFAULT_GRAYSCALE_PALETTE)+1);
1443 strcpy(pColorSrvRsrc.ColorPalette, DEFAULT_GRAYSCALE_PALETTE);
1447 pColorSrvRsrc.ColorPalette =
1448 XtMalloc(strlen(DEFAULT_COLOR_PALETTE)+1);
1449 strcpy(pColorSrvRsrc.ColorPalette, DEFAULT_COLOR_PALETTE);
1453 numPlanes = XDisplayPlanes(dpy, screen_number);
1455 if( numPlanes < 3) /* 1 or 2 planes */
1457 colorSrv.TypeOfMonitor[screen_number] = XmCO_BLACK_WHITE;
1458 colorSrv.DynamicColor[screen_number] = False;
1460 else if( numPlanes == 3 ) /* 3 planes */
1462 switch(pColorSrvRsrc.ColorUse) {
1463 case XmCO_LOW_COLOR:
1464 colorSrv.TypeOfMonitor[screen_number] = XmCO_LOW_COLOR;
1467 colorSrv.TypeOfMonitor[screen_number] = XmCO_BLACK_WHITE;
1468 colorSrv.DynamicColor[screen_number] = False;
1470 /* for 3 planes UsePixmaps (ShadowPixmaps) have to be on (TRUE) */
1471 colorSrv.UsePixmaps[screen_number] = 1;
1473 else if( numPlanes == 4 ) /* 4 planes */
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;
1481 case XmCO_BLACK_WHITE:
1482 colorSrv.TypeOfMonitor[screen_number] = XmCO_BLACK_WHITE;
1483 colorSrv.DynamicColor[screen_number] = False;
1486 colorSrv.TypeOfMonitor[screen_number] = XmCO_LOW_COLOR;
1489 /* check to see what type of shadow pixmap to use */
1490 if(pColorSrvRsrc.ShadowPixmaps == -1)
1491 colorSrv.UsePixmaps[screen_number] = 1;
1493 else if( numPlanes == 5 ) /* 5 planes */
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;
1501 case XmCO_MEDIUM_COLOR:
1502 colorSrv.TypeOfMonitor[screen_number] = XmCO_MEDIUM_COLOR;
1504 case XmCO_BLACK_WHITE:
1505 colorSrv.TypeOfMonitor[screen_number] = XmCO_BLACK_WHITE;
1506 colorSrv.DynamicColor[screen_number] = False;
1509 colorSrv.TypeOfMonitor[screen_number] = XmCO_LOW_COLOR;
1512 else /* 6 and above planes */
1514 switch(pColorSrvRsrc.ColorUse) {
1515 case XmCO_HIGH_COLOR:
1516 colorSrv.TypeOfMonitor[screen_number] = XmCO_HIGH_COLOR;
1518 case XmCO_LOW_COLOR:
1519 colorSrv.TypeOfMonitor[screen_number] = XmCO_LOW_COLOR;
1521 case XmCO_BLACK_WHITE:
1522 colorSrv.TypeOfMonitor[screen_number] = XmCO_BLACK_WHITE;
1523 colorSrv.DynamicColor[screen_number] = False;
1526 colorSrv.TypeOfMonitor[screen_number] = XmCO_MEDIUM_COLOR;
1529 /* check to see what type of shadow pixmap to use */
1530 if(pColorSrvRsrc.ShadowPixmaps == -1)
1531 colorSrv.UsePixmaps[screen_number] = 0;
1534 /* Determine the correct foreground color useage */
1535 switch(pColorSrvRsrc.ForegroundColor) {
1537 colorSrv.FgColor[screen_number] = BLACK;
1540 colorSrv.FgColor[screen_number] = WHITE;
1543 colorSrv.FgColor[screen_number] = DYNAMIC;