/* * NAME * _XcmsResolveColorString - * * SYNOPSIS */ Status _XcmsResolveColorString ( XcmsCCC ccc, const char **color_string, XcmsColor *pColor_exact_return, XcmsColorFormat result_format) /* * DESCRIPTION * The XcmsLookupColor function finds the color specification * associated with a color name in the Device-Independent Color * Name Database. * RETURNS * XcmsFailure if failed to convert valid color string. * XcmsSuccess if succeeded in converting color string to * XcmsColor. * _XCMS_NEWNAME if failed to parse the string or find it in * the database, or if succeeded in looking it up and * found another name which is not in the database. * Note that the new name is returned in color_string. * * This function returns both the color specification found in the * database (db specification) and the color specification for the * color displayable by the specified screen (screen * specification). The calling routine sets the format for these * returned specifications in the XcmsColor format component. * If XcmsUndefinedFormat, the specification is returned in the * format used to store the color in the database. */ { XcmsColor dbWhitePt; /* whitePt associated with pColor_exact_return*/ /* the screen's white point */ XcmsColor *pClientWhitePt; int retval; const char *strptr = whitePtStr; /* * 0. Check for invalid arguments. */ if (ccc == NULL || (*color_string)[0] == '\0' || pColor_exact_return == NULL) { return(XcmsFailure); } /* * 1. First attempt to parse the string * If successful, then convert the specification to the target format * and return. */ if (_XcmsParseColorString(ccc, *color_string, pColor_exact_return) == 1) { if (result_format != XcmsUndefinedFormat && pColor_exact_return->format != result_format) { /* need to be converted to the target format */ return(XcmsConvertColors(ccc, pColor_exact_return, 1, result_format, (Bool *)NULL)); } else { return(XcmsSuccess); } } /* * 2. Attempt to find it in the DI Color Name Database */ /* * a. Convert String into a XcmsColor structure * Attempt to extract the specification for color_string from the * DI Database (pColor_exact_return). If the DI Database does not * have this entry, then return failure. */ retval = _XcmsLookupColorName(ccc, color_string, pColor_exact_return); if (retval != XcmsSuccess) { /* color_string replaced with a color name, or not found */ return(_XCMS_NEWNAME); } if (pColor_exact_return->format == XcmsUndefinedFormat) { return(XcmsFailure); } /* * b. If result_format not defined, then assume target format * is the exact format. */ if (result_format == XcmsUndefinedFormat) { result_format = pColor_exact_return->format; } if ((ClientWhitePointOfCCC(ccc))->format == XcmsUndefinedFormat) { pClientWhitePt = ScreenWhitePointOfCCC(ccc); } else { pClientWhitePt = ClientWhitePointOfCCC(ccc); } /* * c. Convert to the target format, making adjustments for white * point differences as necessary. */ if (XCMS_DD_ID(pColor_exact_return->format)) { /* * The spec format is Device-Dependent, therefore assume the * its white point is the Screen White Point. */ if (XCMS_DD_ID(result_format)) { /* * Target format is Device-Dependent * Therefore, DD --> DD conversion */ return(_XcmsDDConvertColors(ccc, pColor_exact_return, 1, result_format, (Bool *) NULL)); } else { /* * Target format is Device-Independent * Therefore, DD --> DI conversion */ if (ccc->whitePtAdjProc && !_XcmsEqualWhitePts(ccc, pClientWhitePt, ScreenWhitePointOfCCC(ccc))) { return((*ccc->whitePtAdjProc)(ccc, ScreenWhitePointOfCCC(ccc), pClientWhitePt, result_format, pColor_exact_return, 1, (Bool *) NULL)); } else { if (_XcmsDDConvertColors(ccc, pColor_exact_return, 1, XcmsCIEXYZFormat, (Bool *) NULL) == XcmsFailure) { return(XcmsFailure); } return(_XcmsDIConvertColors(ccc, pColor_exact_return, pClientWhitePt, 1, result_format)); } } } else { /* * The spec format is Device-Independent, therefore attempt * to find a database white point. * * If the Database does not have a white point, then assume the * database white point is the same as the Screen White Point. */ if (_XcmsLookupColorName(ccc, &strptr, &dbWhitePt) != 1) { memcpy((char *)&dbWhitePt, (char *)&ccc->pPerScrnInfo->screenWhitePt, sizeof(XcmsColor)); } if (XCMS_DD_ID(result_format)) { /* * Target format is Device-Dependent * Therefore, DI --> DD conversion */ if (ccc->whitePtAdjProc && !_XcmsEqualWhitePts(ccc, &dbWhitePt, ScreenWhitePointOfCCC(ccc))) { return((*ccc->whitePtAdjProc)(ccc, &dbWhitePt, ScreenWhitePointOfCCC(ccc), result_format, pColor_exact_return, 1, (Bool *)NULL)); } else { if (pColor_exact_return->format != XcmsCIEXYZFormat) { if (_XcmsDIConvertColors(ccc, pColor_exact_return, &dbWhitePt, 1, XcmsCIEXYZFormat) == XcmsFailure) { return(XcmsFailure); } } return (_XcmsDDConvertColors(ccc, pColor_exact_return, 1, result_format, (Bool *)NULL)); } } else { /* * Target format is Device-Independent * Therefore, DI --> DI conversion */ if (ccc->whitePtAdjProc && !_XcmsEqualWhitePts(ccc, &dbWhitePt, pClientWhitePt)) { /* * The calling routine wants to resolve this color * in terms if it's white point (i.e. Client White Point). * Therefore, apply white adjustment for the displacement * between dbWhitePt to clientWhitePt. */ return((*ccc->whitePtAdjProc)(ccc, &dbWhitePt, pClientWhitePt, result_format, pColor_exact_return, 1, (Bool *)NULL)); } else if (_XcmsEqualWhitePts(ccc, &dbWhitePt, pClientWhitePt)) { /* * Can use either dbWhitePt or pClientWhitePt to * convert to the result_format. */ if (pColor_exact_return->format == result_format) { return(XcmsSuccess); } else { return (_XcmsDIConvertColors(ccc, pColor_exact_return, &dbWhitePt, 1, result_format)); } } else { /* * Need to convert to a white point independent color * space (let's choose CIEXYZ) then convert to the * target color space. Why? Lets assume that * pColor_exact_return->format and result format * are white point dependent format (e.g., CIELUV, CIELAB, * TekHVC ... same or any combination). If so, we'll * need to convert the color with dbWhitePt to an absolute * spec (i.e. non-white point dependent) then convert that * absolute value with clientWhitePt to the result_format. */ if (pColor_exact_return->format != XcmsCIEXYZFormat) { if (_XcmsDIConvertColors(ccc, pColor_exact_return, &dbWhitePt, 1, XcmsCIEXYZFormat) == XcmsFailure) { return(XcmsFailure); } } if (result_format == XcmsCIEXYZFormat) { return(XcmsSuccess); } else { return(_XcmsDIConvertColors(ccc, pColor_exact_return, pClientWhitePt, 1, result_format)); } } } } }
/* * NAME * XcmsLookupColor - * * SYNOPSIS */ Status XcmsLookupColor ( Display *dpy, Colormap cmap, _Xconst char *colorname, XcmsColor *pColor_exact_return, XcmsColor *pColor_scrn_return, XcmsColorFormat result_format) /* * DESCRIPTION * The XcmsLookupColor function finds the color specification * associated with a color name in the Device-Independent Color * Name Database. * RETURNS * This function returns both the color specification found in the * database (db specification) and the color specification for the * color displayable by the specified screen (screen * specification). The calling routine sets the format for these * returned specifications in the XcmsColor format component. * If XcmsUndefinedFormat, the specification is returned in the * format used to store the color in the database. */ { Status retval1 = XcmsSuccess; Status retval2 = XcmsSuccess; XcmsCCC ccc; register int n; xLookupColorReply reply; register xLookupColorReq *req; XColor def, scr; /* * 0. Check for invalid arguments. */ if (dpy == NULL || colorname[0] == '\0' || pColor_scrn_return == 0 || pColor_exact_return == NULL) { return(XcmsFailure); } if ((ccc = XcmsCCCOfColormap(dpy, cmap)) == (XcmsCCC)NULL) { return(XcmsFailure); } /* * 1. Convert string to a XcmsColor */ if ((retval1 = _XcmsResolveColorString(ccc, &colorname, pColor_exact_return, result_format)) == XcmsFailure) { return(XcmsFailure); } if (retval1 == _XCMS_NEWNAME) { goto PassToServer; } /* * 2. pColor_scrn_return * Assume the pColor_exact_return has already been adjusted to * the Client White Point. * */ /* * Convert to RGB, adjusting for white point differences if necessary. */ memcpy((char *)pColor_scrn_return, (char *)pColor_exact_return, sizeof(XcmsColor)); if (pColor_scrn_return->format == XcmsRGBFormat) { retval2 = XcmsSuccess; } else if ((retval2 = XcmsConvertColors(ccc, pColor_scrn_return, 1, XcmsRGBFormat, (Bool *)NULL)) == XcmsFailure) { return(XcmsFailure); } /* * Then, convert XcmsColor structure to the target specification * format. Note that we must use NULL instead of passing * pCompressed. */ if (result_format == XcmsUndefinedFormat) { result_format = pColor_exact_return->format; } if (result_format == XcmsRGBFormat) { _XcmsUnresolveColor(ccc, pColor_scrn_return); } else { _XcmsResolveColor(ccc, pColor_scrn_return); if (XcmsConvertColors(ccc, pColor_scrn_return, 1, result_format, (Bool *) NULL) == XcmsFailure) { return(XcmsFailure); } } return(retval1 > retval2 ? retval1 : retval2); PassToServer: /* * Xcms and i18n methods failed, so lets pass it to the server * for parsing. */ LockDisplay(dpy); GetReq (LookupColor, req); req->cmap = cmap; req->nbytes = n = strlen(colorname); req->length += (n + 3) >> 2; Data (dpy, colorname, (long)n); if (!_XReply (dpy, (xReply *) &reply, 0, xTrue)) { UnlockDisplay(dpy); SyncHandle(); return (XcmsFailure); } def.red = reply.exactRed; def.green = reply.exactGreen; def.blue = reply.exactBlue; scr.red = reply.screenRed; scr.green = reply.screenGreen; scr.blue = reply.screenBlue; UnlockDisplay(dpy); SyncHandle(); _XColor_to_XcmsRGB(ccc, &def, pColor_exact_return, 1); _XColor_to_XcmsRGB(ccc, &scr, pColor_scrn_return, 1); /* * Then, convert XcmsColor structure to the target specification * format. Note that we must use NULL instead of passing * pCompressed. */ if (result_format != XcmsRGBFormat && result_format != XcmsUndefinedFormat) { if (XcmsConvertColors(ccc, pColor_exact_return, 1, result_format, (Bool *) NULL) == XcmsFailure) { return(XcmsFailure); } if (XcmsConvertColors(ccc, pColor_scrn_return, 1, result_format, (Bool *) NULL) == XcmsFailure) { return(XcmsFailure); } } return(XcmsSuccess); }
/* * NAME * XcmsAllocNamedColor - * * SYNOPSIS */ Status XcmsAllocNamedColor ( Display *dpy, Colormap cmap, _Xconst char *colorname, XcmsColor *pColor_scrn_return, XcmsColor *pColor_exact_return, XcmsColorFormat result_format) /* * DESCRIPTION * Finds the color specification associated with the color * name in the Device-Independent Color Name Database, then * converts that color specification to an RGB format. This * RGB value is then used in a call to XAllocColor to allocate * a read-only color cell. * * RETURNS * 0 if failed to parse string or find any entry in the database. * 1 if succeeded in converting color name to XcmsColor. * 2 if succeeded in converting color name to another color name. * */ { long nbytes; xAllocNamedColorReply rep; xAllocNamedColorReq *req; XColor hard_def; XColor exact_def; Status retval1 = 1; Status retval2 = XcmsSuccess; XcmsColor tmpColor; XColor XColor_in_out; XcmsCCC ccc; /* * 0. Check for invalid arguments. */ if (dpy == NULL || colorname[0] == '\0' || pColor_scrn_return == 0 || pColor_exact_return == NULL) { return(XcmsFailure); } if ((ccc = XcmsCCCOfColormap(dpy, cmap)) == (XcmsCCC)NULL) { return(XcmsFailure); } /* * 1. Convert string to a XcmsColor using Xcms and i18n mechanism */ if ((retval1 = _XcmsResolveColorString(ccc, &colorname, &tmpColor, result_format)) == XcmsFailure) { return(XcmsFailure); } if (retval1 == _XCMS_NEWNAME) { goto PassToServer; } memcpy((char *)pColor_exact_return, (char *)&tmpColor, sizeof(XcmsColor)); /* * 2. Convert tmpColor to RGB * Assume pColor_exact_return is now adjusted to Client White Point */ if ((retval2 = XcmsConvertColors(ccc, &tmpColor, 1, XcmsRGBFormat, (Bool *) NULL)) == XcmsFailure) { return(XcmsFailure); } /* * 3. Convert to XColor and call XAllocColor */ _XcmsRGB_to_XColor(&tmpColor, &XColor_in_out, 1); if (XAllocColor(ccc->dpy, cmap, &XColor_in_out) == 0) { return(XcmsFailure); } /* * 4. pColor_scrn_return * * Now convert to the target format. * We can ignore the return value because we're already in a * device-dependent format. */ _XColor_to_XcmsRGB(ccc, &XColor_in_out, pColor_scrn_return, 1); if (result_format != XcmsRGBFormat) { if (result_format == XcmsUndefinedFormat) { result_format = pColor_exact_return->format; } if (XcmsConvertColors(ccc, pColor_scrn_return, 1, result_format, (Bool *) NULL) == XcmsFailure) { return(XcmsFailure); } } return(retval1 > retval2 ? retval1 : retval2); PassToServer: /* * All previous methods failed, so lets pass it to the server * for parsing. */ dpy = ccc->dpy; LockDisplay(dpy); GetReq(AllocNamedColor, req); req->cmap = cmap; nbytes = req->nbytes = strlen(colorname); req->length += (nbytes + 3) >> 2; /* round up to mult of 4 */ _XSend(dpy, colorname, nbytes); /* _XSend is more efficient that Data, since _XReply follows */ if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) { UnlockDisplay(dpy); SyncHandle(); return (0); } exact_def.red = rep.exactRed; exact_def.green = rep.exactGreen; exact_def.blue = rep.exactBlue; hard_def.red = rep.screenRed; hard_def.green = rep.screenGreen; hard_def.blue = rep.screenBlue; exact_def.pixel = hard_def.pixel = rep.pixel; UnlockDisplay(dpy); SyncHandle(); /* * Now convert to the target format. */ _XColor_to_XcmsRGB(ccc, &exact_def, pColor_exact_return, 1); _XColor_to_XcmsRGB(ccc, &hard_def, pColor_scrn_return, 1); if (result_format != XcmsRGBFormat && result_format != XcmsUndefinedFormat) { if (XcmsConvertColors(ccc, pColor_exact_return, 1, result_format, (Bool *) NULL) == XcmsFailure) { return(XcmsFailure); } if (XcmsConvertColors(ccc, pColor_scrn_return, 1, result_format, (Bool *) NULL) == XcmsFailure) { return(XcmsFailure); } } return(XcmsSuccess); }
/* * NAME * XcmsSetColor - * * SYNOPSIS */ Status _XcmsSetGetColor( Status (*xColorProc)( Display* /* display */, Colormap /* colormap */, XColor* /* screen_in_out */), Display *dpy, Colormap cmap, XcmsColor *pColors_in_out, XcmsColorFormat result_format, Bool *pCompressed) /* * DESCRIPTION * Routine containing code common to: * XcmsAllocColor * XcmsQueryColor * XcmsStoreColor * * RETURNS * XcmsFailure if failed; * XcmsSuccess if it succeeded without gamut compression; * XcmsSuccessWithCompression if it succeeded with gamut * compression; */ { XcmsCCC ccc; XColor XColors_in_out; Status retval = XcmsSuccess; /* * Argument Checking * 1. Assume xColorProc is correct * 2. Insure ccc not NULL * 3. Assume cmap correct (should be checked by Server) * 4. Insure pColors_in_out valid * 5. Assume method_in is valid (should be checked by Server) */ if (dpy == NULL) { return(XcmsFailure); } if (result_format == XcmsUndefinedFormat) { return(XcmsFailure); } if ( !((*xColorProc == XAllocColor) || (*xColorProc == XStoreColor) || (*xColorProc == XQueryColor)) ) { return(XcmsFailure); } if ((ccc = XcmsCCCOfColormap(dpy, cmap)) == (XcmsCCC)NULL) { return(XcmsFailure); } if (*xColorProc == XQueryColor) { goto Query; } /* * Convert to RGB, adjusting for white point differences if necessary. */ if ((retval = XcmsConvertColors(ccc, pColors_in_out, 1, XcmsRGBFormat, pCompressed)) == XcmsFailure) { return(XcmsFailure); } Query: /* * Convert XcmsColor to XColor structures */ _XcmsRGB_to_XColor(pColors_in_out, &XColors_in_out, 1); /* * Now make appropriate X Call */ if (*xColorProc == XAllocColor) { if ((*xColorProc)(ccc->dpy, cmap, &XColors_in_out) == 0) { return(XcmsFailure); } } else if ((*xColorProc == XQueryColor) || (*xColorProc == XStoreColor)) { /* Note: XQueryColor and XStoreColor do not return any Status */ (*xColorProc)(ccc->dpy, cmap, &XColors_in_out); } else { return(XcmsFailure); } if ((*xColorProc == XStoreColor)) { return(retval); } /* * Now, convert the returned XColor (i.e., rgb) to XcmsColor structures */ _XColor_to_XcmsRGB(ccc, &XColors_in_out, pColors_in_out, 1); /* * Then, convert XcmsColor structures to the original specification * format. Note that we must use NULL instead of passing * pCompressed. */ if (result_format != XcmsRGBFormat) { if (XcmsConvertColors(ccc, pColors_in_out, 1, result_format, (Bool *) NULL) == XcmsFailure) { return(XcmsFailure); } } return(retval); }