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 if (selection != NULL) {
808 tmpStr3 = XGetAtomName(XtDisplay(w), *selection);
813 const int str1len = strlen(MSG2) + strlen(MSG2a) + strlen(tmpStr3) + 10;
814 const int str2len = strlen(MSG2) + 1;
815 tmpStr = (char *)SRV_MALLOC(str1len);
816 tmpStr2 = (char *)SRV_MALLOC(str2len);
818 snprintf(tmpStr2, str2len, "%s", MSG2);
819 snprintf(tmpStr, str1len, "%s %s\n%s", tmpStr2, tmpStr3, MSG2a);
820 _DtSimpleError(XmSCOLOR_SRV_NAME, DtWarning, NULL, tmpStr, NULL);
825 /*****************************************************************************
827 ** FindMaximumDefault .. used when the actual or user defaults for
828 ** TypeOfMonitor, UsePixmaps, and FgColor try to allocate more cells than
829 ** are available .. this finds and allocates the maximum that are available
830 ** It also adjusts TypeOfMonitor, UsePixmaps, and FgColor accordingly.
832 ******************************************************************************/
840 /* go find the Number of pixels left to allocate */
841 numOfPixelsLeft = FindNumOfPixels(dpy, screen_number);
843 if(numOfPixelsLeft < 4)
845 /* Use Black and White */
846 colorSrv.TypeOfMonitor[screen_number] = XmCO_BLACK_WHITE;
849 if((colorSrv.TypeOfMonitor[screen_number] ==
850 XmCO_HIGH_COLOR && numOfPixelsLeft >= 40) ||
851 (colorSrv.TypeOfMonitor[screen_number] ==
852 XmCO_MEDIUM_COLOR && numOfPixelsLeft >= 20) ||
853 (colorSrv.TypeOfMonitor[screen_number] ==
854 XmCO_LOW_COLOR && numOfPixelsLeft >= 10))
856 /* should never get here */
859 else if(colorSrv.TypeOfMonitor[screen_number] == XmCO_HIGH_COLOR)
861 if(numOfPixelsLeft >= 32) /* was asking for 40 */
863 colorSrv.UsePixmaps[screen_number] = FALSE;
864 colorSrv.FgColor[screen_number] = WHITE;
867 else if(numOfPixelsLeft >= 24)
869 colorSrv.UsePixmaps[screen_number] = TRUE;
870 colorSrv.FgColor[screen_number] = DYNAMIC;
873 else if(numOfPixelsLeft >= 16)
875 colorSrv.UsePixmaps[screen_number] = TRUE;
876 colorSrv.FgColor[screen_number] = WHITE;
879 else /* can't use XmCO_HIGH_COLOR anymore so set to
880 next highest XmCO_MEDIUM_COLOR */
882 colorSrv.TypeOfMonitor[screen_number] = XmCO_MEDIUM_COLOR;
883 colorSrv.pCurrentPalette[screen_number]->num_of_colors = 4;
887 /* need to do an if instead of an else because TypeOfMonitor can be reset
888 in the else if above */
889 if(colorSrv.TypeOfMonitor[screen_number] == XmCO_MEDIUM_COLOR)
891 if(numOfPixelsLeft >= 16)
893 colorSrv.UsePixmaps[screen_number] = FALSE;
894 colorSrv.FgColor[screen_number] = WHITE;
897 if(numOfPixelsLeft >= 12)
899 colorSrv.UsePixmaps[screen_number] = TRUE;
900 colorSrv.FgColor[screen_number] = DYNAMIC;
903 else if(numOfPixelsLeft >= 8)
905 colorSrv.UsePixmaps[screen_number] = TRUE;
906 colorSrv.FgColor[screen_number] = WHITE;
909 else /* can't use XmCO_MEDIUM_COLOR anymore so set to next */
910 /* highest XmCO_LOW_COLOR*/
912 colorSrv.TypeOfMonitor[screen_number] = XmCO_LOW_COLOR;
913 colorSrv.pCurrentPalette[screen_number]->num_of_colors = 2;
914 SwitchAItoPS(colorSrv.pCurrentPalette[screen_number]);
918 /* need to do an if instead of an else because TypeOfMonitor can be reset
919 in the else if above */
920 if(colorSrv.TypeOfMonitor[screen_number] == XmCO_LOW_COLOR)
922 if(numOfPixelsLeft >= 10)
924 colorSrv.UsePixmaps[screen_number] = FALSE;
925 colorSrv.FgColor[screen_number] = DYNAMIC;
928 else if(numOfPixelsLeft >= 8)
930 colorSrv.UsePixmaps[screen_number] = FALSE;
931 colorSrv.FgColor[screen_number] = WHITE;
934 else if(numOfPixelsLeft >= 6)
936 colorSrv.UsePixmaps[screen_number] = TRUE;
937 colorSrv.FgColor[screen_number] = DYNAMIC;
940 else if(numOfPixelsLeft >= 4)
942 colorSrv.UsePixmaps[screen_number] = TRUE;
943 colorSrv.FgColor[screen_number] = WHITE;
947 /* should never get here */
951 /****************************************************************************
953 ** FindNumOfPixels ... routine used to determine the num of allocable cells
954 ** left in the default colormap. With this number we can determine the
955 ** Maximum default for the user
957 ******************************************************************************/
963 unsigned long *pixels;
964 unsigned long plane_mask;
965 int i, iterations, status;
966 int num_of_pixels, count, base, countdown;
969 colormap = DefaultColormap(dpy, screen_number);
971 /* get the total number of cells in this screen */
972 num_of_pixels = XDisplayCells(dpy, screen_number);
974 /* get the number of iterations to be used .. the number of plane in this
976 iterations = XDisplayPlanes(dpy, screen_number);
978 /* Allocate enough space to store the pixels. */
979 pixels = (unsigned long *)SRV_MALLOC (num_of_pixels * sizeof (unsigned long));
981 /* now iterate through until the we know how many cells are available */
982 count = num_of_pixels;
985 for(i = 0; i < iterations; i++)
987 status = XAllocColorCells (dpy, colormap, (Boolean)0, &plane_mask,
990 countdown = countdown / 2;
993 count = base + countdown;
997 XFreeColors(dpy, colormap, pixels, count, (unsigned long)0);
998 if(count != num_of_pixels)
1001 count = base + countdown;
1005 status = XAllocColorCells (dpy, colormap, (Boolean)0, &plane_mask,
1010 XFreeColors(dpy, colormap, pixels, count, (unsigned long)0);
1011 SRV_FREE((char *) pixels);
1015 /************************************************************************
1017 ** GetNumOfPixels - returns the number of pixels to allocate based on the
1018 ** resources ColorUse(TypeOfMonitor), ShadowPixmaps(UsePixmaps),
1019 ** and ForegroundColor(FgColor).
1021 ************************************************************************/
1027 if(colorSrv.TypeOfMonitor[screen_number] == XmCO_BLACK_WHITE)
1031 else /* non Black and White monitor */
1033 if(colorSrv.UsePixmaps[screen_number] == FALSE)
1035 if(colorSrv.FgColor[screen_number] == DYNAMIC)
1037 return(colorSrv.pCurrentPalette[screen_number]->num_of_colors * 5);
1039 else /*FgColor == BLACK or WHITE ... bg, ts, bs, & sc used */
1041 return(colorSrv.pCurrentPalette[screen_number]->num_of_colors * 4);
1044 else /* UsePixmaps == True */
1046 if(colorSrv.FgColor[screen_number] == DYNAMIC) /* fg, bg, & sc used */
1048 return(colorSrv.pCurrentPalette[screen_number]->num_of_colors * 3);
1050 else /*FgColor == BLACK or WHITE ... bg & sc used */
1052 return(colorSrv.pCurrentPalette[screen_number]->num_of_colors * 2);
1058 /************************************************************************
1060 ** MatchAndStore - match the pixels already allocated with the current
1061 ** palettes storage .. then do a Store Colors to set the colors
1062 ** correctly at the X server.
1064 ************************************************************************/
1069 unsigned long *pixels )
1075 p = colorSrv.pCurrentPalette[screen_number];
1076 xcolor = (XColor *)SRV_MALLOC (p->num_of_colors * 5 * sizeof (XColor));
1078 for(i = 0; i < p->num_of_colors; i++)
1080 /* Background Pixel */
1081 p->color[i].bg.pixel = pixels[count];
1082 p->color[i].bg.flags = DoRed | DoGreen | DoBlue;
1083 xcolor[count] = p->color[i].bg;
1086 /* SelectColor (ArmColor) Pixel */
1087 p->color[i].sc.pixel = pixels[count];
1088 p->color[i].sc.flags = DoRed | DoGreen | DoBlue;
1089 xcolor[count] = p->color[i].sc;
1092 if(colorSrv.UsePixmaps[screen_number] == FALSE)
1094 /* TopShadow Pixel */
1095 p->color[i].ts.pixel = pixels[count];
1096 p->color[i].ts.flags = DoRed | DoGreen | DoBlue;
1097 xcolor[count] = p->color[i].ts;
1100 /* BottomShadow Pixel */
1101 p->color[i].bs.pixel = pixels[count];
1102 p->color[i].bs.flags = DoRed | DoGreen | DoBlue;
1103 xcolor[count] = p->color[i].bs;
1106 else /* colorSrv.UsePixmaps = True */
1108 /* TopShadow Pixel set to white */
1109 p->color[i].ts.pixel = WhitePixel(dpy,screen_number);
1110 p->color[i].ts.flags = 0;
1112 /* BottomShadow Pixel set to black */
1113 p->color[i].bs.pixel = BlackPixel(dpy,screen_number);
1114 p->color[i].bs.flags = 0;
1116 if(colorSrv.FgColor[screen_number] == DYNAMIC)
1118 /* Foreground Pixel */
1119 p->color[i].fg.pixel = pixels[count];
1120 p->color[i].fg.flags = DoRed | DoGreen | DoBlue;
1121 xcolor[count] = p->color[i].fg;
1124 else if(colorSrv.FgColor[screen_number] == BLACK)
1126 /* Foreground Pixel set to BLACK */
1127 p->color[i].fg.pixel = BlackPixel(dpy,screen_number);
1128 p->color[i].fg.flags = 0;
1132 /* Foreground Pixel set to WHITE */
1133 p->color[i].fg.pixel = WhitePixel(dpy,screen_number);
1134 p->color[i].fg.flags = 0;
1140 XStoreColors(dpy, DefaultColormap(dpy, screen_number), xcolor, count);
1143 SRV_FREE((char *) xcolor);
1146 /************************************************************************
1148 ** AllocReadWrite - Allocates Read/Write cells for use by the color
1149 ** server. If the X server can't allocate enough cells (numOfPixels)
1150 ** this routine finds the number of pixels available, and sets
1151 ** the varibles TypeOfMonitor, UsePixmaps, and FgColor accordingly.
1153 ************************************************************************/
1161 unsigned long *pixels;
1162 unsigned long plane_mask;
1165 /* Allocate enough space to store the pixels. */
1166 pixels = (unsigned long *)SRV_MALLOC (numOfPixels * sizeof (unsigned long));
1168 /* Now actually allocate R/W pixels */
1169 status = XAllocColorCells (dpy, DefaultColormap(dpy, screen_number),
1170 (Boolean)0, &plane_mask, 0, pixels, numOfPixels);
1172 /* When status is false means the alloc couldn't get all the pixels
1173 the user wanted or what the default is .. so lets go find the
1174 minumum and set up and use that */
1177 SRV_FREE((char *) pixels);
1178 numOfPixels = FindMaximumDefault(dpy, screen_number);
1179 if(numOfPixels == 0)
1181 tmpStr = (char *)SRV_MALLOC(strlen(MSG3) + 6);
1182 sprintf(tmpStr,"%s%d", MSG3, screen_number);
1183 _DtSimpleError(XmSCOLOR_SRV_NAME, DtWarning, NULL, tmpStr, NULL);
1189 if(colorSrv.TypeOfMonitor[screen_number] != XmCO_BLACK_WHITE)
1191 /* Allocate enough space to store the pixels. */
1192 pixels = (unsigned long *)SRV_MALLOC (numOfPixels *
1193 sizeof (unsigned long));
1195 /* Now actually allocate R/W pixels */
1196 status = XAllocColorCells(dpy, DefaultColormap(dpy,screen_number),
1197 (Boolean)0, &plane_mask, 0, pixels, numOfPixels);
1201 SRV_FREE((char *) pixels);
1202 _DtSimpleError(XmSCOLOR_SRV_NAME, DtWarning, NULL, ((char *)GETMESSAGE(26, 5, "Warning, can't allocate enough pixels.\n")), NULL);
1209 if(colorSrv.TypeOfMonitor[screen_number] != XmCO_BLACK_WHITE)
1211 /* Go match pixels allocated with the colorsets then use store
1212 XStoreColors to set the RGB values of them */
1213 MatchAndStore(dpy, screen_number, pixels);
1217 /* free the allocated space for pixels */
1218 SRV_FREE((char *) pixels);
1222 /************************************************************************
1224 ** AllocReadOnly - Allocates Read Only cells for use by the color
1225 ** server. If the X server can't allocate the cell it finds the
1226 ** closest approximation to the color of a cell already allocated.
1227 ** Therefore there is no error recorded.
1229 ************************************************************************/
1237 for(i=0; i < colorSrv.pCurrentPalette[screen_number]->num_of_colors; i++)
1239 XAllocColor(dpy, DefaultColormap(dpy, screen_number),
1240 &(colorSrv.pCurrentPalette[screen_number]->color[i].bg));
1241 XAllocColor(dpy, DefaultColormap(dpy, screen_number),
1242 &(colorSrv.pCurrentPalette[screen_number]->color[i].sc));
1244 /* Check UsePixmaps varible */
1245 if(colorSrv.UsePixmaps[screen_number] == FALSE)
1247 XAllocColor(dpy, DefaultColormap(dpy, screen_number),
1248 &(colorSrv.pCurrentPalette[screen_number]->color[i].ts));
1249 XAllocColor(dpy, DefaultColormap(dpy, screen_number),
1250 &(colorSrv.pCurrentPalette[screen_number]->color[i].bs));
1252 else /* colorSrv.UsePixmaps[screen_number] == True */
1254 colorSrv.pCurrentPalette[screen_number]->color[i].ts.pixel =
1255 WhitePixel(dpy,screen_number);
1256 colorSrv.pCurrentPalette[screen_number]->color[i].bs.pixel =
1257 BlackPixel(dpy,screen_number);
1260 /* Check FgColor varible */
1261 if(colorSrv.FgColor[screen_number] == DYNAMIC)
1262 XAllocColor(dpy, DefaultColormap(dpy, screen_number),
1263 &(colorSrv.pCurrentPalette[screen_number]->color[i].fg));
1265 else if(colorSrv.FgColor[screen_number] == BLACK)
1266 colorSrv.pCurrentPalette[screen_number]->color[i].fg.pixel =
1267 BlackPixel(dpy,screen_number);
1270 colorSrv.pCurrentPalette[screen_number]->color[i].fg.pixel =
1271 WhitePixel(dpy,screen_number);
1275 /*********************************************************************
1277 ** Converter which converts a string to the ColorUse value
1279 **********************************************************************/
1281 CvtStringToColorUse(
1287 char * in_str = (char *) (from_val->addr);
1290 to_val->size = sizeof (int);
1291 to_val->addr = (XtPointer) &i;
1293 if (_DtWmStringsAreEqual (in_str, "high_color"))
1294 i = XmCO_HIGH_COLOR;
1295 else if (_DtWmStringsAreEqual (in_str, "medium_color"))
1296 i = XmCO_MEDIUM_COLOR;
1297 else if (_DtWmStringsAreEqual (in_str, "low_color"))
1299 else if (_DtWmStringsAreEqual (in_str, "b_w"))
1300 i = XmCO_BLACK_WHITE;
1301 else if (_DtWmStringsAreEqual (in_str, "default"))
1306 to_val->addr = NULL;
1307 XtStringConversionWarning ((char *)from_val->addr, DtRColorUse);
1310 /**********************************************************************
1312 ** Converter which converts a string to the ForegroundColor value
1314 **********************************************************************/
1316 CvtStringToForegroundColor(
1322 char * in_str = (char *) (from_val->addr);
1325 to_val->size = sizeof (int);
1326 to_val->addr = (XtPointer) &i;
1328 if (_DtWmStringsAreEqual (in_str, "dynamic"))
1330 else if (_DtWmStringsAreEqual (in_str, "black"))
1332 else if (_DtWmStringsAreEqual (in_str, "white"))
1337 to_val->addr = NULL;
1338 XtStringConversionWarning ((char *)from_val->addr, DtRForegroundColor);
1342 /***********************************************************************
1344 ** Converter which converts a string to the ShadowPixmaps value
1346 ***********************************************************************/
1348 CvtStringToShadowPixmaps(
1354 char * in_str = (char *) (from_val->addr);
1357 to_val->size = sizeof (int);
1358 to_val->addr = (XtPointer) &i;
1360 if (_DtWmStringsAreEqual (in_str, "true"))
1362 else if (_DtWmStringsAreEqual (in_str, "false"))
1364 else if (_DtWmStringsAreEqual (in_str, "default"))
1369 to_val->addr = NULL;
1370 XtStringConversionWarning ((char *)from_val->addr, DtRShadowPixmaps);
1374 /************************************************************************
1376 * _DtWmStringsAreEqual
1377 * Compare two strings and return true if equal.
1378 * The comparison is on lower cased strings. It is the callers
1379 * responsibility to ensure that test_str is already lower cased.
1381 ************************************************************************/
1383 _DtWmStringsAreEqual(
1384 register char *in_str,
1385 register char *test_str )
1398 if ((mblen(in_str, MB_CUR_MAX) == 1))
1399 if (isupper (i)) i = tolower (i);
1401 if (isupper (i)) i = tolower (i);
1403 if (i != j) return (False);
1404 if (i == 0) return (True);
1411 /************************************************************************
1413 * SetDefaults - set the TypeOfMonitor, UsePixmaps, FgColor, and DynamicColor
1414 * for the screen passed in. Use the resource values, the number of
1415 * colors for this screen, and the visual type of the screen to
1416 * determine which values best fit.
1418 *************************************************************************/
1427 /* Initialize colorSrv data for this screen with specified resource values */
1428 colorSrv.UsePixmaps[screen_number] = pColorSrvRsrc.ShadowPixmaps;
1429 colorSrv.DynamicColor[screen_number] = pColorSrvRsrc.DynamicColor;
1431 /* If this is a static color visual class, set DynamicColor to False. */
1432 visual = XDefaultVisual(dpy, screen_number);
1435 /* GrayScale and PseudoColor are the only visual types that make */
1436 /* sense to change dynamically with the current implementation */
1437 if ((visual->class != GrayScale) && (visual->class != PseudoColor))
1438 colorSrv.DynamicColor[screen_number] = False;
1440 /* if not specified, set ColorPalette default */
1441 if (strcmp(pColorSrvRsrc.ColorPalette,"DEFAULT") == 0)
1443 if ((visual->class == GrayScale) || (visual->class == StaticGray))
1445 pColorSrvRsrc.ColorPalette =
1446 XtMalloc(strlen(DEFAULT_GRAYSCALE_PALETTE)+1);
1447 strcpy(pColorSrvRsrc.ColorPalette, DEFAULT_GRAYSCALE_PALETTE);
1451 pColorSrvRsrc.ColorPalette =
1452 XtMalloc(strlen(DEFAULT_COLOR_PALETTE)+1);
1453 strcpy(pColorSrvRsrc.ColorPalette, DEFAULT_COLOR_PALETTE);
1457 numPlanes = XDisplayPlanes(dpy, screen_number);
1459 if( numPlanes < 3) /* 1 or 2 planes */
1461 colorSrv.TypeOfMonitor[screen_number] = XmCO_BLACK_WHITE;
1462 colorSrv.DynamicColor[screen_number] = False;
1464 else if( numPlanes == 3 ) /* 3 planes */
1466 switch(pColorSrvRsrc.ColorUse) {
1467 case XmCO_LOW_COLOR:
1468 colorSrv.TypeOfMonitor[screen_number] = XmCO_LOW_COLOR;
1471 colorSrv.TypeOfMonitor[screen_number] = XmCO_BLACK_WHITE;
1472 colorSrv.DynamicColor[screen_number] = False;
1474 /* for 3 planes UsePixmaps (ShadowPixmaps) have to be on (TRUE) */
1475 colorSrv.UsePixmaps[screen_number] = 1;
1477 else if( numPlanes == 4 ) /* 4 planes */
1479 switch(pColorSrvRsrc.ColorUse) {
1480 case XmCO_MEDIUM_COLOR:
1481 /* for 4 planes ColorUse = Med_color shadowPixmaps have to be True */
1482 pColorSrvRsrc.ShadowPixmaps = -1;
1483 colorSrv.TypeOfMonitor[screen_number] = XmCO_MEDIUM_COLOR;
1485 case XmCO_BLACK_WHITE:
1486 colorSrv.TypeOfMonitor[screen_number] = XmCO_BLACK_WHITE;
1487 colorSrv.DynamicColor[screen_number] = False;
1490 colorSrv.TypeOfMonitor[screen_number] = XmCO_LOW_COLOR;
1493 /* check to see what type of shadow pixmap to use */
1494 if(pColorSrvRsrc.ShadowPixmaps == -1)
1495 colorSrv.UsePixmaps[screen_number] = 1;
1497 else if( numPlanes == 5 ) /* 5 planes */
1499 switch(pColorSrvRsrc.ColorUse) {
1500 case XmCO_HIGH_COLOR:
1501 /* for 5 planes ColorUse = hi_color shadowPixmaps have to be True */
1502 pColorSrvRsrc.ShadowPixmaps = -1;
1503 colorSrv.TypeOfMonitor[screen_number] = XmCO_HIGH_COLOR;
1505 case XmCO_MEDIUM_COLOR:
1506 colorSrv.TypeOfMonitor[screen_number] = XmCO_MEDIUM_COLOR;
1508 case XmCO_BLACK_WHITE:
1509 colorSrv.TypeOfMonitor[screen_number] = XmCO_BLACK_WHITE;
1510 colorSrv.DynamicColor[screen_number] = False;
1513 colorSrv.TypeOfMonitor[screen_number] = XmCO_LOW_COLOR;
1516 else /* 6 and above planes */
1518 switch(pColorSrvRsrc.ColorUse) {
1519 case XmCO_HIGH_COLOR:
1520 colorSrv.TypeOfMonitor[screen_number] = XmCO_HIGH_COLOR;
1522 case XmCO_LOW_COLOR:
1523 colorSrv.TypeOfMonitor[screen_number] = XmCO_LOW_COLOR;
1525 case XmCO_BLACK_WHITE:
1526 colorSrv.TypeOfMonitor[screen_number] = XmCO_BLACK_WHITE;
1527 colorSrv.DynamicColor[screen_number] = False;
1530 colorSrv.TypeOfMonitor[screen_number] = XmCO_MEDIUM_COLOR;
1533 /* check to see what type of shadow pixmap to use */
1534 if(pColorSrvRsrc.ShadowPixmaps == -1)
1535 colorSrv.UsePixmaps[screen_number] = 0;
1538 /* Determine the correct foreground color useage */
1539 switch(pColorSrvRsrc.ForegroundColor) {
1541 colorSrv.FgColor[screen_number] = BLACK;
1544 colorSrv.FgColor[screen_number] = WHITE;
1547 colorSrv.FgColor[screen_number] = DYNAMIC;