Пример #1
0
/*
 *	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));
		}
	    }
	}
    }
}
Пример #2
0
/*
 *	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);
}
Пример #3
0
/*
 *	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);
}
Пример #4
0
/*
 *	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);
}