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 librararies 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"
77 #define SRVBUFSIZE 1024
78 #define DEFAULT_COLOR_PALETTE "Default.dp"
79 #define DEFAULT_GRAYSCALE_PALETTE "GrayScale.dp"
81 #define DtRColorUse "ColorUse"
82 #define DtRForegroundColor "ForegroundColor"
83 #define DtRShadowPixmaps "ShadowPixmaps"
85 #define TYPE_OF_MONITOR "Type Of Monitor" /* also in dtstyle/ColorMain.c */
87 /* global color server struct */
91 /*************************
92 * Color Server Resources
93 *************************/
99 Boolean WriteXrdbColors;
101 char *MonochromePalette;
102 } Appdata, *AppdataPtr;
104 static XtResource resources[] = {
110 XtOffset(AppdataPtr, ColorUse),
118 XtOffset(AppdataPtr, ShadowPixmaps),
126 XtOffset(AppdataPtr, ForegroundColor),
134 XtOffset(AppdataPtr, DynamicColor),
142 XtOffset(AppdataPtr, WriteXrdbColors),
150 XtOffset(AppdataPtr, ColorPalette),
152 (XtPointer)"DEFAULT"},
154 { "monochromePalette",
158 XtOffset(AppdataPtr, MonochromePalette),
160 (XtPointer)"Black.dp"},
163 Appdata pColorSrvRsrc;
165 /************************************
167 ***********************************/
169 Widget shell[MAX_NUM_SCREENS];
171 /******** Static Function Declarations ********/
173 static Boolean AllocateColors(
175 static char *convert_pixel_set(
178 static Boolean convert_selection(
184 unsigned long *length,
186 static void lose_selection(
189 static int FindMaximumDefault(
192 static int FindNumOfPixels(
195 static int GetNumOfPixels(
197 static void MatchAndStore(
200 unsigned long *pixels) ;
201 static Boolean AllocReadWrite(
205 static void AllocReadOnly(
208 static void CvtStringToColorUse(
213 static void CvtStringToForegroundColor(
218 static void CvtStringToShadowPixmaps(
223 static Boolean _DtWmStringsAreEqual(
224 register char *in_str,
225 register char *test_str) ;
226 static void SetDefaults(
230 static void _DtCacheProperties(
233 /******** End Static Function Declarations ********/
235 #define MSG1 ((char *)GETMESSAGE(26, 1, "Color Server Warning: couldn't get ownership of the selection: "))
236 #define MSG2 ((char *)GETMESSAGE(26, 2, "Color Server Warning, losing ownership of the selection: "))
237 #define MSG2a ((char *)GETMESSAGE(26, 3, "Should never lose the selection."))
238 #define MSG3 ((char *)GETMESSAGE(26, 4, "Warning, found more pixels then are available."))
240 /***********************************************************************
242 * InitializeDtcolor - calls all the routines which do the initialization
243 * for the color server.
245 **********************************************************************/
251 int status, screen_number;
252 char xrdb_string[100];
254 /* find out what type of monitor(s?) is being used */
255 status = CheckMonitor(dpy);
259 /* Allocate colors for the default palette */
264 screen_number != colorSrv.NumOfScreens;
267 /* Set disown selections of the pixel set atoms */
268 XtDisownSelection(shell[screen_number],
269 colorSrv.XA_CUSTOMIZE[screen_number],
275 /* don't set resources if writeXrdbColors == false */
276 if (!pColorSrvRsrc.WriteXrdbColors)
280 OWsyncColorResources(dpy, colorSrv.TypeOfMonitor[0],
281 colorSrv.pCurrentPalette[0]->color);
282 OWsyncLocaleResources(dpy);
284 /* Set the *background: resource
285 What gets set depends on what type of monitor */
286 /* For XmCO_HIGH_COLOR the default primary colorset is 4, else 1 */
287 if(colorSrv.TypeOfMonitor[0] != XmCO_BLACK_WHITE)
289 int chipnum = colorSrv.TypeOfMonitor[0] == XmCO_HIGH_COLOR ? 4 : 1;
291 "*background: #%04X%04X%04X\n*foreground: #%04X%04X%04X\n",
292 colorSrv.pCurrentPalette[0]->color[chipnum].bg.red,
293 colorSrv.pCurrentPalette[0]->color[chipnum].bg.green,
294 colorSrv.pCurrentPalette[0]->color[chipnum].bg.blue,
295 colorSrv.pCurrentPalette[0]->color[chipnum].fg.red,
296 colorSrv.pCurrentPalette[0]->color[chipnum].fg.green,
297 colorSrv.pCurrentPalette[0]->color[chipnum].fg.blue);
300 /* For XmCO_BLACK_WHITE the resources depended on whether the default
301 palette is White on Black or Black on White */
302 else /* XmCO_BLACK_WHITE */
304 if(strcmp(colorSrv.pCurrentPalette[0]->name, W_O_B) == 0 ||
305 strcmp(colorSrv.pCurrentPalette[0]->name, B_ONLY) == 0)
308 "*background: #000000000000\n*foreground: #FFFFFFFFFFFF\n");
313 "*background: #FFFFFFFFFFFF\n*foreground: #000000000000\n");
316 /* go merge the xrdb_string into the xrdb */
317 _DtAddToResource(dpy, xrdb_string);
320 _DtCacheProperties(dpy, XtWindow(shell[0])) ;
330 Atom pixel_set_atom ;
331 struct _palette *palette ;
334 int screen_number = 0 ; /*assuming simple case i.e. screen 0 */
336 pixel_set_atom = XInternAtom(dpy, XmSPIXEL_SET_PROP, FALSE) ;
338 palette = colorSrv.pCurrentPalette[screen_number];
339 typeOfMonitor = colorSrv.TypeOfMonitor[screen_number];
340 if (palette->converted == NULL)
342 palette->converted = convert_pixel_set(typeOfMonitor, palette->color);
343 palette->converted_len = strlen(palette->converted);
346 *(palette->converted + palette->converted_len) = XmPIXEL_SET_PROP_VERSION ;
347 palette->converted_len++ ;
348 palette->converted[palette->converted_len] = NULL ;
349 XChangeProperty(dpy, win, pixel_set_atom, XA_STRING, 8, PropModeAppend,
350 (unsigned char *) XtNewString(palette->converted),
351 palette->converted_len) ;
354 /*****************************************************************************
356 ** Allocates color cells to be used by clients. The global varible
357 ** DynamicColor[screen_number] determines if the cells are to be allocated
358 ** read/write or read only. Right now this routine allocates
359 ** all cells needed for a palette up front. For performance tuning we will
360 ** want to look at allocating on demand. The allocation scheme looks like
361 ** the following: (AT - Alway True)
362 ** # TypeOfMonior UsePixmaps FgColor # of Cells allocated per palette
363 ** - ------------ ---------- ------ -------------------------------
364 ** 1 HIGH_COLOR FALSE DYNAMIC (fg,bg,ts,bs,sc) 5*8 = 40
365 ** 2 HIGH_COLOR FALSE BLACK or WHITE (bg,ts,bs,sc) 4*8 = 32
366 ** 3 HIGH_COLOR TRUE DYNAMIC (fg,bg,sc) 3*8 = 24
367 ** 4 HIGH_COLOR TRUE BLACK or WHITE (bg,sc) 2*8 = 16
369 ** 5 MEDIUM_COLOR FALSE DYNAMIC (fg,bg,ts,bs,sc) 5*4 = 20
370 ** 6 MEDIUM_COLOR FALSE BLACK or WHITE (bg,ts,bs,sc) 4*4 = 16
371 ** 7 MEDIUM_COLOR TRUE DYNAMIC (fg,bg,sc) 3*4 = 12
372 ** 8 MEDIUM_COLOR TRUE BLACK or WHITE (bg,sc) 2*4 = 8
374 ** 9 LOW_COLOR FALSE DYNAMIC (fg,bg,ts,bs,sc) 5*2 = 10
375 ** 10 LOW_COLOR FALSE BLACK or WHITE (bg,ts,bs,sc) 4*2 = 8
376 ** 11 LOW_COLOR TRUE DYNAMIC (fg,bg,sc) 3*2 = 6
377 ** 12 LOW_COLOR TRUE BLACK or WHITE (bg,sc) 2*2 = 4
379 ** 13 BLACK_WHITE AT Aways opposite 0
382 ***************************************************************************/
390 /* Determine how many pixels to allocate (numOfPixels) */
391 for(screen_number=0;screen_number != colorSrv.NumOfScreens;screen_number++)
393 numOfPixels = GetNumOfPixels(screen_number);
395 /* Now allocate the correct number of pixels using numOfPixels */
396 if(numOfPixels != 0) /* Not XmCO_BLACK_WHITE */
398 if(colorSrv.DynamicColor[screen_number] == True)
400 /* go allocate Read/Write cells for the color server */
401 if(!AllocReadWrite(dpy, screen_number, numOfPixels))
405 /* go allocate Read Only cells for the color server */
406 AllocReadOnly(dpy, screen_number);
409 if(colorSrv.TypeOfMonitor[screen_number] == XmCO_BLACK_WHITE)
411 #define BlackColorSet(dpy,scr,xcolor) \
412 (xcolor).pixel = BlackPixel((dpy),(scr)); \
413 (xcolor).red = (xcolor).green = (xcolor).blue = 0;
414 #define WhiteColorSet(dpy,scr,xcolor) \
415 (xcolor).pixel = WhitePixel((dpy),(scr)); \
416 (xcolor).red = (xcolor).green = (xcolor).blue = 65535;
418 palettes *palette = colorSrv.pCurrentPalette[screen_number];
420 /* Check to see what black and white palette it is */
421 /* note: color[0] = secondary, color[1] = primary (as of 8/8/90) */
422 if(!(strcmp(colorSrv.pCurrentPalette[screen_number]->name, W_O_B)))
424 WhiteColorSet(dpy,screen_number,palette->color[0].bg);
425 BlackColorSet(dpy,screen_number,palette->color[0].fg);
426 BlackColorSet(dpy,screen_number,palette->color[0].ts);
427 BlackColorSet(dpy,screen_number,palette->color[0].bs);
428 WhiteColorSet(dpy,screen_number,palette->color[0].sc);
430 BlackColorSet(dpy,screen_number,palette->color[1].bg);
431 WhiteColorSet(dpy,screen_number,palette->color[1].fg);
432 WhiteColorSet(dpy,screen_number,palette->color[1].ts);
433 WhiteColorSet(dpy,screen_number,palette->color[1].bs);
434 BlackColorSet(dpy,screen_number,palette->color[1].sc);
437 if(!(strcmp(colorSrv.pCurrentPalette[screen_number]->name, B_O_W)))
439 BlackColorSet(dpy,screen_number,palette->color[0].bg);
440 WhiteColorSet(dpy,screen_number,palette->color[0].fg);
441 WhiteColorSet(dpy,screen_number,palette->color[0].ts);
442 WhiteColorSet(dpy,screen_number,palette->color[0].bs);
443 BlackColorSet(dpy,screen_number,palette->color[0].sc);
445 WhiteColorSet(dpy,screen_number,palette->color[1].bg);
446 BlackColorSet(dpy,screen_number,palette->color[1].fg);
447 BlackColorSet(dpy,screen_number,palette->color[1].ts);
448 BlackColorSet(dpy,screen_number,palette->color[1].bs);
449 WhiteColorSet(dpy,screen_number,palette->color[1].sc);
452 if(!(strcmp(colorSrv.pCurrentPalette[screen_number]->name, W_ONLY)))
454 WhiteColorSet(dpy,screen_number,palette->color[0].bg);
455 BlackColorSet(dpy,screen_number,palette->color[0].fg);
456 BlackColorSet(dpy,screen_number,palette->color[0].ts);
457 BlackColorSet(dpy,screen_number,palette->color[0].bs);
458 WhiteColorSet(dpy,screen_number,palette->color[0].sc);
460 WhiteColorSet(dpy,screen_number,palette->color[1].bg);
461 BlackColorSet(dpy,screen_number,palette->color[1].fg);
462 BlackColorSet(dpy,screen_number,palette->color[1].ts);
463 BlackColorSet(dpy,screen_number,palette->color[1].bs);
464 WhiteColorSet(dpy,screen_number,palette->color[1].sc);
466 else /* black only */
468 BlackColorSet(dpy,screen_number,palette->color[0].bg);
469 WhiteColorSet(dpy,screen_number,palette->color[0].fg);
470 WhiteColorSet(dpy,screen_number,palette->color[0].ts);
471 WhiteColorSet(dpy,screen_number,palette->color[0].bs);
472 BlackColorSet(dpy,screen_number,palette->color[0].sc);
474 BlackColorSet(dpy,screen_number,palette->color[1].bg);
475 WhiteColorSet(dpy,screen_number,palette->color[1].fg);
476 WhiteColorSet(dpy,screen_number,palette->color[1].ts);
477 WhiteColorSet(dpy,screen_number,palette->color[1].bs);
478 BlackColorSet(dpy,screen_number,palette->color[1].sc);
484 } /* for screen_number=0 ; screen_number < NumOfScreens; screen_number++ */
489 /************************************************************************
491 ** CheckMonitor - check to determine which type of monitor each of the
492 ** screens on the server is running on.
494 ************************************************************************/
499 int n, screen_number, result;
501 char screenStr[5], cust_msg[24];
503 char tmpPalette[SRVBUFSIZE];
508 XtAppContext app_context;
510 /* Determine the number of screens attached to this server */
511 colorSrv.NumOfScreens = ScreenCount(dpy);
513 /* Initialize the Atoms used to pass information */
514 colorSrv.XA_PIXEL_SET = XInternAtom(dpy, XmSPIXEL_SET, FALSE);
515 colorSrv.XA_TYPE_MONITOR = XInternAtom(dpy, TYPE_OF_MONITOR, FALSE);
517 /* create a top level shell to retrieve subresources from */
519 XtSetArg(args[n], XmNbackground,
520 BlackPixelOfScreen(DefaultScreenOfDisplay(dpy))); n++;
521 XtSetArg(args[n], XmNmappedWhenManaged, False); n++;
522 XtSetArg (args[n], XmNwidth, 1); n++;
523 XtSetArg (args[n], XmNheight, 1); n++;
524 mainShell = XtAppCreateShell("dtsession", XmSCOLOR_SRV_NAME,
525 applicationShellWidgetClass,
528 /* create an application context */
529 app_context = XtWidgetToApplicationContext(mainShell);
531 /* Register the resource converters */
532 XtAppAddConverter(app_context, XmRString, "ColorUse",
533 CvtStringToColorUse, NULL, 0);
534 XtAppAddConverter(app_context, XmRString, "ForegroundColor",
535 CvtStringToForegroundColor, NULL, 0);
536 XtAppAddConverter(app_context, XmRString, "ShadowPixmaps",
537 CvtStringToShadowPixmaps, NULL, 0);
539 /* cycle through each screen */
540 for(screen_number=0;screen_number != colorSrv.NumOfScreens;screen_number++)
542 sprintf(screenStr,"%d",screen_number);
544 XtSetArg(args[n], XmNbackground,
545 BlackPixelOfScreen(DefaultScreenOfDisplay(dpy))); n++;
546 XtSetArg(args[n], XmNmappedWhenManaged, False); n++;
547 XtSetArg (args[n], XmNwidth, 1); n++;
548 XtSetArg (args[n], XmNheight, 1); n++;
549 shell[screen_number] = XtAppCreateShell(screenStr, XmSCOLOR_SRV_NAME,
550 applicationShellWidgetClass,
554 * widget needs to be realized for the window ID for
558 XtRealizeWidget(shell[screen_number]);
560 sprintf(cust_msg,"%s%d", XmSCUSTOMIZE_DATA, screen_number);
561 colorSrv.XA_CUSTOMIZE[screen_number] =
562 XInternAtom(dpy, cust_msg, FALSE);
564 /* go set ownership of the pixel set atoms */
565 result = XtOwnSelection(shell[screen_number],
566 colorSrv.XA_CUSTOMIZE[screen_number],
567 CurrentTime, convert_selection,
568 lose_selection, NULL);
573 * Don't forget to add length for the extra characters.
575 tmpStr = (char *)SRV_MALLOC(strlen(MSG1) + 25 + 5 + 1 + 1);
576 sprintf(tmpStr,"%s colorSrv.XA_CUSTOMIZE[%d].\n",
577 MSG1, screen_number);
578 _DtSimpleError(XmSCOLOR_SRV_NAME, DtWarning, NULL, tmpStr, NULL);
583 /* Get the colorserver resources for this screen */
585 XtGetSubresources(mainShell, &pColorSrvRsrc, screenStr, screenStr,
586 resources, XtNumber(resources), NULL, 0);
589 * Set TypeOfMonitor, UsePixmaps FgColor and
590 * DynamicColor for this screen
593 SetDefaults(dpy, screen_number);
595 if (colorSrv.TypeOfMonitor[screen_number] != XmCO_BLACK_WHITE)
597 colorSrv.pCurrentPalette[screen_number] =
598 (struct _palette *) GetPaletteDefinition(dpy,
600 pColorSrvRsrc.ColorPalette);
604 /* Allocate space for new palette. */
605 colorSrv.pCurrentPalette[screen_number] =
606 (struct _palette *) SRV_MALLOC( sizeof(struct _palette) + 1 );
608 /* allocate enough space for the name */
609 strcpy(tmpPalette, pColorSrvRsrc.MonochromePalette);
610 for (token1=tmpPalette; *token1; token1++);
611 while (token1!=tmpPalette && *token1!='.') token1--;
612 if (!strcmp(token1,PALETTE_SUFFIX)) *token1 = '\0';
613 colorSrv.pCurrentPalette[screen_number]->name =
614 (char *)SRV_MALLOC(strlen(tmpPalette) + 1);
615 strcpy(colorSrv.pCurrentPalette[screen_number]->name,
616 (char *) tmpPalette);
617 colorSrv.pCurrentPalette[screen_number]->converted=NULL;
620 if (colorSrv.pCurrentPalette[screen_number] == (struct _palette *) NULL)
625 /* write out the color or monochrome palette resource for the screen */
627 xrdb_string = XtMalloc(BUFSIZ);
629 if (colorSrv.TypeOfMonitor[0] == XmCO_HIGH_COLOR ||
630 colorSrv.TypeOfMonitor[0] == XmCO_MEDIUM_COLOR ||
631 colorSrv.TypeOfMonitor[0] == XmCO_LOW_COLOR)
633 sprintf(xrdb_string, "*%d*ColorPalette: %s%s\n",
635 colorSrv.pCurrentPalette[screen_number]->name,
638 else /* XmCO_BLACK_WHITE */
640 sprintf(xrdb_string, "*%d*MonochromePalette: %s%s\n",
642 colorSrv.pCurrentPalette[screen_number]->name,
645 _DtAddToResource(dpy, xrdb_string);
649 } /* for each screen */
653 /************************************************************************
655 ** convert_pixel_set - converts palette pixel set to selection format
657 ************************************************************************/
666 int colormappingindex;
668 const int colormapping [4][XmCO_MAX_NUM_COLORS] = {
669 {0, 1, 2, 3, 4, 5, 6, 7}, /* XmCO_HIGH_COLOR */
670 {0, 1, 2, 3, 1, 1, 2, 1}, /* XmCO_MEDIUM_COLOR */
671 {0, 1, 1, 1, 1, 1, 1, 1}, /* XmCO_LOW_COLOR */
672 {0, 1, 1, 1, 1, 1, 1, 1} /* XmCO_BLACK_WHITE */
675 #if 0 /* map when hi-color was the default */
676 const int colormapping [4][XmCO_MAX_NUM_COLORS] = {
677 {0, 1, 2, 3, 4, 5, 6, 7}, /* XmCO_HIGH_COLOR */
678 {0, 1, 2, 3, 3, 3, 3, 3}, /* XmCO_MEDIUM_COLOR */
679 {0, 1, 1, 0, 0, 0, 0, 0}, /* XmCO_LOW_COLOR */
680 {0, 1, 1, 0, 0, 0, 0, 0} /* XmCO_BLACK_WHITE */
684 switch(typeOfMonitor)
686 case XmCO_HIGH_COLOR: colormappingindex = 0; break;
687 case XmCO_MEDIUM_COLOR: colormappingindex = 1; break;
688 case XmCO_LOW_COLOR: colormappingindex = 2; break;
689 case XmCO_BLACK_WHITE: colormappingindex = 3; break;
692 p = converted = (char *)SRV_MALLOC(400);
694 /* lead the string with the type of monitor */
695 p += sprintf(p, "%x_", typeOfMonitor);
697 for (i = 0; i < NUM_OF_COLORS; i++)
699 p += sprintf (p, "%lx_%lx_%lx_%lx_%lx_",
700 color[colormapping[colormappingindex][i]].bg.pixel,
701 color[colormapping[colormappingindex][i]].fg.pixel,
702 color[colormapping[colormappingindex][i]].ts.pixel,
703 color[colormapping[colormappingindex][i]].bs.pixel,
704 color[colormapping[colormappingindex][i]].sc.pixel);
710 /************************************************************************
712 ** convert_selection - Callback, called when some other client wishes
713 ** to get information from the dtcolor (color server)
715 ************************************************************************/
723 unsigned long *length,
727 int i, screen_number;
729 char *str_type_return;
730 XrmValue value_return;
733 char instanceName[30], instanceClass[30];
735 struct _palette *palette;
739 /* Determine for which screen the selection came from */
740 for(i=0; i < MAX_NUM_SCREENS; i++)
742 if(colorSrv.XA_CUSTOMIZE[i] == *selection)
749 palette = colorSrv.pCurrentPalette[screen_number];
750 typeOfMonitor = colorSrv.TypeOfMonitor[screen_number];
752 if(*target == colorSrv.XA_PIXEL_SET)
754 /* wants to know the pixels allocated for the palette */
756 if (palette->converted == NULL)
758 palette->converted = convert_pixel_set(typeOfMonitor, palette->color);
759 palette->converted_len = strlen(palette->converted);
763 *length = palette->converted_len;
764 *value = XtNewString(palette->converted);
768 else if(*target == colorSrv.XA_TYPE_MONITOR)
770 /* wants to know ColorUse, ShadowPixmaps, ForegroundColor,
773 temp = (char *)SRV_MALLOC(20);
774 sprintf (temp, "%x_%x_%x_%x", colorSrv.TypeOfMonitor[screen_number],
775 colorSrv.UsePixmaps[screen_number],
776 colorSrv.FgColor[screen_number],
777 colorSrv.DynamicColor[screen_number]);
778 *length = strlen(temp);
787 /************************************************************************
789 ** lose_selection - Callback, called when some other client wishes
790 ** to take ownership of one of the servers selections ...
791 ** should never happen.
793 ************************************************************************/
799 char *tmpStr, *tmpStr2;
801 Atom pixel_set_atom ;
802 pixel_set_atom = XInternAtom(XtDisplay(w), XmSPIXEL_SET_PROP, FALSE) ;
803 XDeleteProperty(XtDisplay(w), XtWindow(shell[0]), pixel_set_atom) ;
805 tmpStr = (char *)SRV_MALLOC(strlen(MSG2) + strlen(MSG2a) + 6);
806 tmpStr2 = (char *)SRV_MALLOC(strlen(MSG2) + 1);
807 sprintf(tmpStr2,"%s", MSG2);
808 sprintf(tmpStr,"%s%s%s", tmpStr2, selection, MSG2a);
809 _DtSimpleError(XmSCOLOR_SRV_NAME, DtWarning, NULL, tmpStr, NULL);
814 /*****************************************************************************
816 ** FindMaximumDefault .. used when the actual or user defaults for
817 ** TypeOfMonitor, UsePixmaps, and FgColor try to allocate more cells than
818 ** are available .. this finds and allocates the maximum that are available
819 ** It also adjusts TypeOfMonitor, UsePixmaps, and FgColor accordingly.
821 ******************************************************************************/
829 /* go find the Number of pixels left to allocate */
830 numOfPixelsLeft = FindNumOfPixels(dpy, screen_number);
832 if(numOfPixelsLeft < 4)
834 /* Use Black and White */
835 colorSrv.TypeOfMonitor[screen_number] = XmCO_BLACK_WHITE;
838 if((colorSrv.TypeOfMonitor[screen_number] ==
839 XmCO_HIGH_COLOR && numOfPixelsLeft >= 40) ||
840 (colorSrv.TypeOfMonitor[screen_number] ==
841 XmCO_MEDIUM_COLOR && numOfPixelsLeft >= 20) ||
842 (colorSrv.TypeOfMonitor[screen_number] ==
843 XmCO_LOW_COLOR && numOfPixelsLeft >= 10))
845 /* should never get here */
848 else if(colorSrv.TypeOfMonitor[screen_number] == XmCO_HIGH_COLOR)
850 if(numOfPixelsLeft >= 32) /* was asking for 40 */
852 colorSrv.UsePixmaps[screen_number] = FALSE;
853 colorSrv.FgColor[screen_number] = WHITE;
856 else if(numOfPixelsLeft >= 24)
858 colorSrv.UsePixmaps[screen_number] = TRUE;
859 colorSrv.FgColor[screen_number] = DYNAMIC;
862 else if(numOfPixelsLeft >= 16)
864 colorSrv.UsePixmaps[screen_number] = TRUE;
865 colorSrv.FgColor[screen_number] = WHITE;
868 else /* can't use XmCO_HIGH_COLOR anymore so set to
869 next highest XmCO_MEDIUM_COLOR */
871 colorSrv.TypeOfMonitor[screen_number] = XmCO_MEDIUM_COLOR;
872 colorSrv.pCurrentPalette[screen_number]->num_of_colors = 4;
876 /* need to do an if instead of an else because TypeOfMonitor can be reset
877 in the else if above */
878 if(colorSrv.TypeOfMonitor[screen_number] == XmCO_MEDIUM_COLOR)
880 if(numOfPixelsLeft >= 16)
882 colorSrv.UsePixmaps[screen_number] = FALSE;
883 colorSrv.FgColor[screen_number] = WHITE;
886 if(numOfPixelsLeft >= 12)
888 colorSrv.UsePixmaps[screen_number] = TRUE;
889 colorSrv.FgColor[screen_number] = DYNAMIC;
892 else if(numOfPixelsLeft >= 8)
894 colorSrv.UsePixmaps[screen_number] = TRUE;
895 colorSrv.FgColor[screen_number] = WHITE;
898 else /* can't use XmCO_MEDIUM_COLOR anymore so set to next */
899 /* highest XmCO_LOW_COLOR*/
901 colorSrv.TypeOfMonitor[screen_number] = XmCO_LOW_COLOR;
902 colorSrv.pCurrentPalette[screen_number]->num_of_colors = 2;
903 SwitchAItoPS(colorSrv.pCurrentPalette[screen_number]);
907 /* need to do an if instead of an else because TypeOfMonitor can be reset
908 in the else if above */
909 if(colorSrv.TypeOfMonitor[screen_number] == XmCO_LOW_COLOR)
911 if(numOfPixelsLeft >= 10)
913 colorSrv.UsePixmaps[screen_number] = FALSE;
914 colorSrv.FgColor[screen_number] = DYNAMIC;
917 else if(numOfPixelsLeft >= 8)
919 colorSrv.UsePixmaps[screen_number] = FALSE;
920 colorSrv.FgColor[screen_number] = WHITE;
923 else if(numOfPixelsLeft >= 6)
925 colorSrv.UsePixmaps[screen_number] = TRUE;
926 colorSrv.FgColor[screen_number] = DYNAMIC;
929 else if(numOfPixelsLeft >= 4)
931 colorSrv.UsePixmaps[screen_number] = TRUE;
932 colorSrv.FgColor[screen_number] = WHITE;
935 /* should never get here */
940 /****************************************************************************
942 ** FindNumOfPixels ... routine used to determine the num of allocable cells
943 ** left in the default colormap. With this number we can determine the
944 ** Maximum default for the user
946 ******************************************************************************/
952 unsigned long *pixels;
953 unsigned long plane_mask;
954 int i, iterations, status;
955 int num_of_pixels, count, base, countdown;
958 colormap = DefaultColormap(dpy, screen_number);
960 /* get the total number of cells in this screen */
961 num_of_pixels = XDisplayCells(dpy, screen_number);
963 /* get the number of iterations to be used .. the number of plane in this
965 iterations = XDisplayPlanes(dpy, screen_number);
967 /* Allocate enough space to store the pixels. */
968 pixels = (unsigned long *)SRV_MALLOC (num_of_pixels * sizeof (unsigned long));
970 /* now iterate through until the we know how many cells are available */
971 count = num_of_pixels;
974 for(i = 0; i < iterations; i++)
976 status = XAllocColorCells (dpy, colormap, (Boolean)0, &plane_mask,
979 countdown = countdown / 2;
982 count = base + countdown;
986 XFreeColors(dpy, colormap, pixels, count, (unsigned long)0);
987 if(count != num_of_pixels)
990 count = base + countdown;
994 status = XAllocColorCells (dpy, colormap, (Boolean)0, &plane_mask,
999 XFreeColors(dpy, colormap, pixels, count, (unsigned long)0);
1000 SRV_FREE((char *) pixels);
1004 /************************************************************************
1006 ** GetNumOfPixels - returns the number of pixels to allocate based on the
1007 ** resources ColorUse(TypeOfMonitor), ShadowPixmaps(UsePixmaps),
1008 ** and ForegroundColor(FgColor).
1010 ************************************************************************/
1016 if(colorSrv.TypeOfMonitor[screen_number] == XmCO_BLACK_WHITE)
1020 else /* non Black and White monitor */
1022 if(colorSrv.UsePixmaps[screen_number] == FALSE)
1024 if(colorSrv.FgColor[screen_number] == DYNAMIC)
1026 return(colorSrv.pCurrentPalette[screen_number]->num_of_colors * 5);
1028 else /*FgColor == BLACK or WHITE ... bg, ts, bs, & sc used */
1030 return(colorSrv.pCurrentPalette[screen_number]->num_of_colors * 4);
1033 else /* UsePixmaps == True */
1035 if(colorSrv.FgColor[screen_number] == DYNAMIC) /* fg, bg, & sc used */
1037 return(colorSrv.pCurrentPalette[screen_number]->num_of_colors * 3);
1039 else /*FgColor == BLACK or WHITE ... bg & sc used */
1041 return(colorSrv.pCurrentPalette[screen_number]->num_of_colors * 2);
1047 /************************************************************************
1049 ** MatchAndStore - match the pixels already allocated with the current
1050 ** palettes storage .. then do a Store Colors to set the colors
1051 ** correctly at the X server.
1053 ************************************************************************/
1058 unsigned long *pixels )
1064 p = colorSrv.pCurrentPalette[screen_number];
1065 xcolor = (XColor *)SRV_MALLOC (p->num_of_colors * 5 * sizeof (XColor));
1067 for(i = 0; i < p->num_of_colors; i++)
1069 /* Background Pixel */
1070 p->color[i].bg.pixel = pixels[count];
1071 p->color[i].bg.flags = DoRed | DoGreen | DoBlue;
1072 xcolor[count] = p->color[i].bg;
1075 /* SelectColor (ArmColor) Pixel */
1076 p->color[i].sc.pixel = pixels[count];
1077 p->color[i].sc.flags = DoRed | DoGreen | DoBlue;
1078 xcolor[count] = p->color[i].sc;
1081 if(colorSrv.UsePixmaps[screen_number] == FALSE)
1083 /* TopShadow Pixel */
1084 p->color[i].ts.pixel = pixels[count];
1085 p->color[i].ts.flags = DoRed | DoGreen | DoBlue;
1086 xcolor[count] = p->color[i].ts;
1089 /* BottomShadow Pixel */
1090 p->color[i].bs.pixel = pixels[count];
1091 p->color[i].bs.flags = DoRed | DoGreen | DoBlue;
1092 xcolor[count] = p->color[i].bs;
1095 else /* colorSrv.UsePixmaps = True */
1097 /* TopShadow Pixel set to white */
1098 p->color[i].ts.pixel = WhitePixel(dpy,screen_number);
1099 p->color[i].ts.flags = 0;
1101 /* BottomShadow Pixel set to black */
1102 p->color[i].bs.pixel = BlackPixel(dpy,screen_number);
1103 p->color[i].bs.flags = 0;
1105 if(colorSrv.FgColor[screen_number] == DYNAMIC)
1107 /* Foreground Pixel */
1108 p->color[i].fg.pixel = pixels[count];
1109 p->color[i].fg.flags = DoRed | DoGreen | DoBlue;
1110 xcolor[count] = p->color[i].fg;
1113 else if(colorSrv.FgColor[screen_number] == BLACK)
1115 /* Foreground Pixel set to BLACK */
1116 p->color[i].fg.pixel = BlackPixel(dpy,screen_number);
1117 p->color[i].fg.flags = 0;
1121 /* Foreground Pixel set to WHITE */
1122 p->color[i].fg.pixel = WhitePixel(dpy,screen_number);
1123 p->color[i].fg.flags = 0;
1129 XStoreColors(dpy, DefaultColormap(dpy, screen_number), xcolor, count);
1132 SRV_FREE((char *) xcolor);
1135 /************************************************************************
1137 ** AllocReadWrite - Allocates Read/Write cells for use by the color
1138 ** server. If the X server can't allocate enough cells (numOfPixels)
1139 ** this routine finds the number of pixels available, and sets
1140 ** the varibles TypeOfMonitor, UsePixmaps, and FgColor accordingly.
1142 ************************************************************************/
1150 unsigned long *pixels;
1151 unsigned long plane_mask;
1154 /* Allocate enough space to store the pixels. */
1155 pixels = (unsigned long *)SRV_MALLOC (numOfPixels * sizeof (unsigned long));
1157 /* Now actually allocate R/W pixels */
1158 status = XAllocColorCells (dpy, DefaultColormap(dpy, screen_number),
1159 (Boolean)0, &plane_mask, 0, pixels, numOfPixels);
1161 /* When status is false means the alloc couldn't get all the pixels
1162 the user wanted or what the default is .. so lets go find the
1163 minumum and set up and use that */
1166 SRV_FREE((char *) pixels);
1167 numOfPixels = FindMaximumDefault(dpy, screen_number);
1168 if(numOfPixels == 0)
1170 tmpStr = (char *)SRV_MALLOC(strlen(MSG3) + 6);
1171 sprintf(tmpStr,"%s%d", MSG3, screen_number);
1172 _DtSimpleError(XmSCOLOR_SRV_NAME, DtWarning, NULL, tmpStr, NULL);
1178 if(colorSrv.TypeOfMonitor[screen_number] != XmCO_BLACK_WHITE)
1180 /* Allocate enough space to store the pixels. */
1181 pixels = (unsigned long *)SRV_MALLOC (numOfPixels *
1182 sizeof (unsigned long));
1184 /* Now actually allocate R/W pixels */
1185 status = XAllocColorCells(dpy, DefaultColormap(dpy,screen_number),
1186 (Boolean)0, &plane_mask, 0, pixels, numOfPixels);
1190 SRV_FREE((char *) pixels);
1191 _DtSimpleError(XmSCOLOR_SRV_NAME, DtWarning, NULL, ((char *)GETMESSAGE(26, 5, "Warning, can't allocate enough pixels.\n")), NULL);
1198 if(colorSrv.TypeOfMonitor[screen_number] != XmCO_BLACK_WHITE)
1200 /* Go match pixels allocated with the colorsets then use store
1201 XStoreColors to set the RGB values of them */
1202 MatchAndStore(dpy, screen_number, pixels);
1206 /* free the allocated space for pixels */
1207 SRV_FREE((char *) pixels);
1211 /************************************************************************
1213 ** AllocReadOnly - Allocates Read Only cells for use by the color
1214 ** server. If the X server can't allocate the cell it finds the
1215 ** closest approximation to the color of a cell already allocated.
1216 ** Therefore there is no error recorded.
1218 ************************************************************************/
1226 for(i=0; i < colorSrv.pCurrentPalette[screen_number]->num_of_colors; i++)
1228 XAllocColor(dpy, DefaultColormap(dpy, screen_number),
1229 &(colorSrv.pCurrentPalette[screen_number]->color[i].bg));
1230 XAllocColor(dpy, DefaultColormap(dpy, screen_number),
1231 &(colorSrv.pCurrentPalette[screen_number]->color[i].sc));
1233 /* Check UsePixmaps varible */
1234 if(colorSrv.UsePixmaps[screen_number] == FALSE)
1236 XAllocColor(dpy, DefaultColormap(dpy, screen_number),
1237 &(colorSrv.pCurrentPalette[screen_number]->color[i].ts));
1238 XAllocColor(dpy, DefaultColormap(dpy, screen_number),
1239 &(colorSrv.pCurrentPalette[screen_number]->color[i].bs));
1241 else /* colorSrv.UsePixmaps[screen_number] == True */
1243 colorSrv.pCurrentPalette[screen_number]->color[i].ts.pixel =
1244 WhitePixel(dpy,screen_number);
1245 colorSrv.pCurrentPalette[screen_number]->color[i].bs.pixel =
1246 BlackPixel(dpy,screen_number);
1249 /* Check FgColor varible */
1250 if(colorSrv.FgColor[screen_number] == DYNAMIC)
1251 XAllocColor(dpy, DefaultColormap(dpy, screen_number),
1252 &(colorSrv.pCurrentPalette[screen_number]->color[i].fg));
1254 else if(colorSrv.FgColor[screen_number] == BLACK)
1255 colorSrv.pCurrentPalette[screen_number]->color[i].fg.pixel =
1256 BlackPixel(dpy,screen_number);
1259 colorSrv.pCurrentPalette[screen_number]->color[i].fg.pixel =
1260 WhitePixel(dpy,screen_number);
1264 /*********************************************************************
1266 ** Converter which converts a string to the ColorUse value
1268 **********************************************************************/
1270 CvtStringToColorUse(
1276 char * in_str = (char *) (from_val->addr);
1279 to_val->size = sizeof (int);
1280 to_val->addr = (XtPointer) &i;
1282 if (_DtWmStringsAreEqual (in_str, "high_color"))
1283 i = XmCO_HIGH_COLOR;
1284 else if (_DtWmStringsAreEqual (in_str, "medium_color"))
1285 i = XmCO_MEDIUM_COLOR;
1286 else if (_DtWmStringsAreEqual (in_str, "low_color"))
1288 else if (_DtWmStringsAreEqual (in_str, "b_w"))
1289 i = XmCO_BLACK_WHITE;
1290 else if (_DtWmStringsAreEqual (in_str, "default"))
1295 to_val->addr = NULL;
1296 XtStringConversionWarning ((char *)from_val->addr, DtRColorUse);
1299 /**********************************************************************
1301 ** Converter which converts a string to the ForegroundColor value
1303 **********************************************************************/
1305 CvtStringToForegroundColor(
1311 char * in_str = (char *) (from_val->addr);
1314 to_val->size = sizeof (int);
1315 to_val->addr = (XtPointer) &i;
1317 if (_DtWmStringsAreEqual (in_str, "dynamic"))
1319 else if (_DtWmStringsAreEqual (in_str, "black"))
1321 else if (_DtWmStringsAreEqual (in_str, "white"))
1326 to_val->addr = NULL;
1327 XtStringConversionWarning ((char *)from_val->addr, DtRForegroundColor);
1331 /***********************************************************************
1333 ** Converter which converts a string to the ShadowPixmaps value
1335 ***********************************************************************/
1337 CvtStringToShadowPixmaps(
1343 char * in_str = (char *) (from_val->addr);
1346 to_val->size = sizeof (int);
1347 to_val->addr = (XtPointer) &i;
1349 if (_DtWmStringsAreEqual (in_str, "true"))
1351 else if (_DtWmStringsAreEqual (in_str, "false"))
1353 else if (_DtWmStringsAreEqual (in_str, "default"))
1358 to_val->addr = NULL;
1359 XtStringConversionWarning ((char *)from_val->addr, DtRShadowPixmaps);
1363 /************************************************************************
1365 * _DtWmStringsAreEqual
1366 * Compare two strings and return true if equal.
1367 * The comparison is on lower cased strings. It is the callers
1368 * responsibility to ensure that test_str is already lower cased.
1370 ************************************************************************/
1372 _DtWmStringsAreEqual(
1373 register char *in_str,
1374 register char *test_str )
1387 if ((mblen(in_str, MB_CUR_MAX) == 1))
1388 if (isupper (i)) i = tolower (i);
1390 if (isupper (i)) i = tolower (i);
1392 if (i != j) return (False);
1393 if (i == 0) return (True);
1400 /************************************************************************
1402 * SetDefaults - set the TypeOfMonitor, UsePixmaps, FgColor, and DynamicColor
1403 * for the screen passed in. Use the resource values, the number of
1404 * colors for this screen, and the visual type of the screen to
1405 * determine which values best fit.
1407 *************************************************************************/
1416 /* Initialize colorSrv data for this screen with specified resource values */
1417 colorSrv.UsePixmaps[screen_number] = pColorSrvRsrc.ShadowPixmaps;
1418 colorSrv.DynamicColor[screen_number] = pColorSrvRsrc.DynamicColor;
1420 /* If this is a static color visual class, set DynamicColor to False. */
1421 visual = XDefaultVisual(dpy, screen_number);
1424 /* GrayScale and PseudoColor are the only visual types that make */
1425 /* sense to change dynamically with the current implementation */
1426 if ((visual->class != GrayScale) && (visual->class != PseudoColor))
1427 colorSrv.DynamicColor[screen_number] = False;
1429 /* if not specified, set ColorPalette default */
1430 if (strcmp(pColorSrvRsrc.ColorPalette,"DEFAULT") == 0)
1432 if ((visual->class == GrayScale) || (visual->class == StaticGray))
1434 pColorSrvRsrc.ColorPalette =
1435 XtMalloc(strlen(DEFAULT_GRAYSCALE_PALETTE)+1);
1436 strcpy(pColorSrvRsrc.ColorPalette, DEFAULT_GRAYSCALE_PALETTE);
1440 pColorSrvRsrc.ColorPalette =
1441 XtMalloc(strlen(DEFAULT_COLOR_PALETTE)+1);
1442 strcpy(pColorSrvRsrc.ColorPalette, DEFAULT_COLOR_PALETTE);
1446 numPlanes = XDisplayPlanes(dpy, screen_number);
1448 if( numPlanes < 3) /* 1 or 2 planes */
1450 colorSrv.TypeOfMonitor[screen_number] = XmCO_BLACK_WHITE;
1451 colorSrv.DynamicColor[screen_number] = False;
1453 else if( numPlanes == 3 ) /* 3 planes */
1455 switch(pColorSrvRsrc.ColorUse) {
1456 case XmCO_LOW_COLOR:
1457 colorSrv.TypeOfMonitor[screen_number] = XmCO_LOW_COLOR;
1460 colorSrv.TypeOfMonitor[screen_number] = XmCO_BLACK_WHITE;
1461 colorSrv.DynamicColor[screen_number] = False;
1463 /* for 3 planes UsePixmaps (ShadowPixmaps) have to be on (TRUE) */
1464 colorSrv.UsePixmaps[screen_number] = 1;
1466 else if( numPlanes == 4 ) /* 4 planes */
1468 switch(pColorSrvRsrc.ColorUse) {
1469 case XmCO_MEDIUM_COLOR:
1470 /* for 4 planes ColorUse = Med_color shadowPixmaps have to be True */
1471 pColorSrvRsrc.ShadowPixmaps = -1;
1472 colorSrv.TypeOfMonitor[screen_number] = XmCO_MEDIUM_COLOR;
1474 case XmCO_BLACK_WHITE:
1475 colorSrv.TypeOfMonitor[screen_number] = XmCO_BLACK_WHITE;
1476 colorSrv.DynamicColor[screen_number] = False;
1479 colorSrv.TypeOfMonitor[screen_number] = XmCO_LOW_COLOR;
1482 /* check to see what type of shadow pixmap to use */
1483 if(pColorSrvRsrc.ShadowPixmaps == -1)
1484 colorSrv.UsePixmaps[screen_number] = 1;
1486 else if( numPlanes == 5 ) /* 5 planes */
1488 switch(pColorSrvRsrc.ColorUse) {
1489 case XmCO_HIGH_COLOR:
1490 /* for 5 planes ColorUse = hi_color shadowPixmaps have to be True */
1491 pColorSrvRsrc.ShadowPixmaps = -1;
1492 colorSrv.TypeOfMonitor[screen_number] = XmCO_HIGH_COLOR;
1494 case XmCO_MEDIUM_COLOR:
1495 colorSrv.TypeOfMonitor[screen_number] = XmCO_MEDIUM_COLOR;
1497 case XmCO_BLACK_WHITE:
1498 colorSrv.TypeOfMonitor[screen_number] = XmCO_BLACK_WHITE;
1499 colorSrv.DynamicColor[screen_number] = False;
1502 colorSrv.TypeOfMonitor[screen_number] = XmCO_LOW_COLOR;
1505 else /* 6 and above planes */
1507 switch(pColorSrvRsrc.ColorUse) {
1508 case XmCO_HIGH_COLOR:
1509 colorSrv.TypeOfMonitor[screen_number] = XmCO_HIGH_COLOR;
1511 case XmCO_LOW_COLOR:
1512 colorSrv.TypeOfMonitor[screen_number] = XmCO_LOW_COLOR;
1514 case XmCO_BLACK_WHITE:
1515 colorSrv.TypeOfMonitor[screen_number] = XmCO_BLACK_WHITE;
1516 colorSrv.DynamicColor[screen_number] = False;
1519 colorSrv.TypeOfMonitor[screen_number] = XmCO_MEDIUM_COLOR;
1522 /* check to see what type of shadow pixmap to use */
1523 if(pColorSrvRsrc.ShadowPixmaps == -1)
1524 colorSrv.UsePixmaps[screen_number] = 0;
1527 /* Determine the correct foreground color useage */
1528 switch(pColorSrvRsrc.ForegroundColor) {
1530 colorSrv.FgColor[screen_number] = BLACK;
1533 colorSrv.FgColor[screen_number] = WHITE;
1536 colorSrv.FgColor[screen_number] = DYNAMIC;