12c7c4e3dSmrg/* $Xorg: loadData.c,v 1.4 2000/08/17 19:54:13 cpqbld Exp $ */
22c7c4e3dSmrg
32c7c4e3dSmrg/*
42c7c4e3dSmrg * (c) Copyright 1990 Tektronix Inc.
52c7c4e3dSmrg * 	All Rights Reserved
62c7c4e3dSmrg *
72c7c4e3dSmrg * Permission to use, copy, modify, and distribute this software and its
82c7c4e3dSmrg * documentation for any purpose and without fee is hereby granted,
92c7c4e3dSmrg * provided that the above copyright notice appear in all copies and that
102c7c4e3dSmrg * both that copyright notice and this permission notice appear in
112c7c4e3dSmrg * supporting documentation, and that the name of Tektronix not be used
122c7c4e3dSmrg * in advertising or publicity pertaining to distribution of the software
132c7c4e3dSmrg * without specific, written prior permission.
142c7c4e3dSmrg *
152c7c4e3dSmrg * Tektronix disclaims all warranties with regard to this software, including
162c7c4e3dSmrg * all implied warranties of merchantability and fitness, in no event shall
172c7c4e3dSmrg * Tektronix be liable for any special, indirect or consequential damages or
182c7c4e3dSmrg * any damages whatsoever resulting from loss of use, data or profits,
192c7c4e3dSmrg * whether in an action of contract, negligence or other tortious action,
202c7c4e3dSmrg * arising out of or in connection with the use or performance of this
212c7c4e3dSmrg * software.
222c7c4e3dSmrg *
232c7c4e3dSmrg *
242c7c4e3dSmrg *	NAME
252c7c4e3dSmrg *		LoadSCCData.c
262c7c4e3dSmrg *
272c7c4e3dSmrg *	DESCRIPTION
282c7c4e3dSmrg *		TekCMS API routine that reads screen data from a file
292c7c4e3dSmrg *	        and then loads the data on the root window of the screen.
302becc446Smrg *
312c7c4e3dSmrg *
322c7c4e3dSmrg *
332c7c4e3dSmrg */
342c7c4e3dSmrg/* $XFree86: xc/programs/xcmsdb/loadData.c,v 3.3 2001/07/25 15:05:18 dawes Exp $ */
352c7c4e3dSmrg
362c7c4e3dSmrg/*
372c7c4e3dSmrg *      INCLUDES
382c7c4e3dSmrg */
392c7c4e3dSmrg
40c1e8faa6Smrg#ifdef HAVE_CONFIG_H
41c1e8faa6Smrg#include "config.h"
42c1e8faa6Smrg#endif
43c1e8faa6Smrg
442c7c4e3dSmrg#include <X11/Xos.h>
452c7c4e3dSmrg#include <sys/stat.h>
462c7c4e3dSmrg#include <stdio.h>
472c7c4e3dSmrg
482c7c4e3dSmrg#include <X11/Xlib.h>
492c7c4e3dSmrg#include <X11/Xatom.h>
502c7c4e3dSmrg#include "SCCDFile.h"
512c7c4e3dSmrg
522c7c4e3dSmrg
532c7c4e3dSmrg/*
542c7c4e3dSmrg *      EXTERNS
552c7c4e3dSmrg *              External declarations required locally to this package
562c7c4e3dSmrg *              that are not already declared in any of the included header
572c7c4e3dSmrg *		files (external includes or internal includes).
582c7c4e3dSmrg */
592c7c4e3dSmrg
602c7c4e3dSmrg#include <stdlib.h>
612c7c4e3dSmrg
622c7c4e3dSmrg/*
632c7c4e3dSmrg *      LOCAL TYPEDEFS
642c7c4e3dSmrg *              typedefs local to this package (for use with local vars).
652c7c4e3dSmrg *
662c7c4e3dSmrg */
672c7c4e3dSmrg
68c1e8faa6Smrgtypedef const struct _DefineEntry {
692becc446Smrg    const char	*pString;
702c7c4e3dSmrg    int		define;
712c7c4e3dSmrg} DefineEntry;
722c7c4e3dSmrg
732c7c4e3dSmrg
742c7c4e3dSmrg/*
752c7c4e3dSmrg *      LOCAL VARIABLES
762c7c4e3dSmrg */
772c7c4e3dSmrgstatic int linenum = 0;
782c7c4e3dSmrg
792c7c4e3dSmrgstatic DefineEntry KeyTbl[] = {
802c7c4e3dSmrg    { SC_BEGIN_KEYWORD,			SC_BEGIN },
812c7c4e3dSmrg    { SC_END_KEYWORD,			SC_END },
822c7c4e3dSmrg    { COMMENT_KEYWORD,			COMMENT },
832c7c4e3dSmrg    { NAME_KEYWORD,			NAME },
842c7c4e3dSmrg    { MODEL_KEYWORD,			MODEL },
852c7c4e3dSmrg    { PART_NUMBER_KEYWORD,		PART_NUMBER },
862c7c4e3dSmrg    { SERIAL_NUMBER_KEYWORD,		SERIAL_NUMBER },
872c7c4e3dSmrg    { REVISION_KEYWORD,			REVISION },
882c7c4e3dSmrg    { SCREEN_CLASS_KEYWORD,		SCREEN_CLASS },
892c7c4e3dSmrg    { COLORIMETRIC_BEGIN_KEYWORD,	COLORIMETRIC_BEGIN },
902c7c4e3dSmrg    { COLORIMETRIC_END_KEYWORD,		COLORIMETRIC_END },
912c7c4e3dSmrg    { XYZTORGBMAT_BEGIN_KEYWORD,	XYZTORGBMAT_BEGIN },
922c7c4e3dSmrg    { XYZTORGBMAT_END_KEYWORD,		XYZTORGBMAT_END },
932c7c4e3dSmrg    { WHITEPT_XYZ_BEGIN_KEYWORD,	WHITEPT_XYZ_BEGIN },
942c7c4e3dSmrg    { WHITEPT_XYZ_END_KEYWORD,		WHITEPT_XYZ_END },
952c7c4e3dSmrg    { RGBTOXYZMAT_BEGIN_KEYWORD,	RGBTOXYZMAT_BEGIN },
962c7c4e3dSmrg    { RGBTOXYZMAT_END_KEYWORD,		RGBTOXYZMAT_END },
972c7c4e3dSmrg    { IPROFILE_BEGIN_KEYWORD,		IPROFILE_BEGIN },
982c7c4e3dSmrg    { IPROFILE_END_KEYWORD,		IPROFILE_END },
992c7c4e3dSmrg    { ITBL_BEGIN_KEYWORD,		ITBL_BEGIN },
1002c7c4e3dSmrg    { ITBL_END_KEYWORD,			ITBL_END },
1012c7c4e3dSmrg    { "",				-1 }
1022c7c4e3dSmrg};
1032c7c4e3dSmrg
1042c7c4e3dSmrgstatic DefineEntry ScrnClassTbl[] = {
1052c7c4e3dSmrg    { VIDEO_RGB_KEYWORD,		VIDEO_RGB },
1062c7c4e3dSmrg#ifdef GRAY
1072c7c4e3dSmrg    { VIDEO_GRAY_KEYWORD,		VIDEO_GRAY },
1082c7c4e3dSmrg#endif /* GRAY */
1092c7c4e3dSmrg    { "",				-1 }
1102c7c4e3dSmrg};
1112c7c4e3dSmrg
1122c7c4e3dSmrg#define KEY_VISUALID		1
1132c7c4e3dSmrg#define KEY_DEPTH		2
1142c7c4e3dSmrg#define KEY_CLASS		3
1152c7c4e3dSmrg#define KEY_RED_MASK		4
1162c7c4e3dSmrg#define KEY_GREEN_MASK		5
1172c7c4e3dSmrg#define KEY_BLUE_MASK		6
1182c7c4e3dSmrg#define KEY_COLORMAP_SIZE	7
1192c7c4e3dSmrg#define KEY_BITS_PER_RGB	8
1202c7c4e3dSmrg
1212c7c4e3dSmrgstatic DefineEntry VisualOptKeyTbl[] = {
1222c7c4e3dSmrg    { "visualid",		KEY_VISUALID },
1232c7c4e3dSmrg    { "depth",			KEY_DEPTH },
1242c7c4e3dSmrg    { "class",			KEY_CLASS },
1252c7c4e3dSmrg    { "red_mask",		KEY_RED_MASK },
1262c7c4e3dSmrg    { "green_mask",		KEY_GREEN_MASK },
1272c7c4e3dSmrg    { "blue_mask",		KEY_BLUE_MASK },
1282c7c4e3dSmrg    { "colormap_size",		KEY_COLORMAP_SIZE },
1292c7c4e3dSmrg    { "bits_per_rgb",		KEY_BITS_PER_RGB },
1303458e6c2Smrg    { "",			-1 }
1312c7c4e3dSmrg};
1323458e6c2Smrg
1332c7c4e3dSmrgstatic DefineEntry VisualClassTbl[] = {
1342c7c4e3dSmrg    { "StaticGray",		StaticGray },
1352c7c4e3dSmrg    { "GrayScale",		GrayScale },
1362c7c4e3dSmrg    { "StaticColor",		StaticColor },
1372c7c4e3dSmrg    { "PseudoColor",		PseudoColor },
1382c7c4e3dSmrg    { "TrueColor",		TrueColor },
1392c7c4e3dSmrg    { "DirectColor",		DirectColor },
1403458e6c2Smrg    { "",			-1 }
1412c7c4e3dSmrg};
1422c7c4e3dSmrg
1432c7c4e3dSmrg
1442c7c4e3dSmrg/************************************************************************
1452c7c4e3dSmrg *									*
1462c7c4e3dSmrg *			 PRIVATE ROUTINES				*
1472c7c4e3dSmrg *									*
1482c7c4e3dSmrg ************************************************************************/
1492c7c4e3dSmrg
1502c7c4e3dSmrg/*
1512c7c4e3dSmrg *	NAME
1522c7c4e3dSmrg *		StrToDefine - convert a string to a define
1532c7c4e3dSmrg *
1542c7c4e3dSmrg *	SYNOPSIS
1552c7c4e3dSmrg */
1562c7c4e3dSmrgstatic int
1573458e6c2SmrgStrToDefine(DefineEntry pde[],   /* IN: table of X string-define pairs     */
1583458e6c2Smrg                                 /*     last entry must contain pair "", 0 */
1593458e6c2Smrg            const char *pstring) /* IN: string to be looked up in that table */
1602c7c4e3dSmrg/*
1612c7c4e3dSmrg *	DESCRIPTION
1622c7c4e3dSmrg *		Converts a string to an integer define.
1632c7c4e3dSmrg *
1642c7c4e3dSmrg *		Looks up the string in the table and returns the integer
1652c7c4e3dSmrg *		associated with the string.
1662c7c4e3dSmrg *
1672c7c4e3dSmrg *		Later may need similar function for unsigned long define.
1682c7c4e3dSmrg *
1692c7c4e3dSmrg *
1702c7c4e3dSmrg *
1712c7c4e3dSmrg *	RETURNS
1722c7c4e3dSmrg *		The int equivalent of the defined string.
1732c7c4e3dSmrg *		-1 if the string is not found in table
1742c7c4e3dSmrg *
1752c7c4e3dSmrg */
1762c7c4e3dSmrg{
1773458e6c2Smrg    while (strcmp(pde->pString, "") != 0) {
1783458e6c2Smrg        if (strcmp(pde->pString, pstring) == 0) {
1793458e6c2Smrg            return (pde->define);
1803458e6c2Smrg        }
1813458e6c2Smrg        pde++;
1822c7c4e3dSmrg    }
1833458e6c2Smrg    return (-1);
1842c7c4e3dSmrg}
1852c7c4e3dSmrg
1862c7c4e3dSmrg/*
1872c7c4e3dSmrg *	NAME
1882c7c4e3dSmrg *		DefineToStr
1892c7c4e3dSmrg *
1902c7c4e3dSmrg *	SYNOPSIS
1912c7c4e3dSmrg */
1922becc446Smrgstatic const char *
1933458e6c2SmrgDefineToStr(DefineEntry pde[],  /* IN: table of X string-define pairs */
1943458e6c2Smrg                                /*     last entry must contain pair "", 0 */
1953458e6c2Smrg            int id)             /* IN: id to be looked up in that table   */
1962c7c4e3dSmrg/*
1972c7c4e3dSmrg *	DESCRIPTION
198c1e8faa6Smrg *		Converts an integer define to a string.
1992c7c4e3dSmrg *
200c1e8faa6Smrg *		Looks up the integer in the table and returns the string
201c1e8faa6Smrg *		associated with the integer.
2022c7c4e3dSmrg *
2032c7c4e3dSmrg *		Later may need similar function for unsigned long define.
2042c7c4e3dSmrg *
2052c7c4e3dSmrg *
2062c7c4e3dSmrg *
2072c7c4e3dSmrg *	RETURNS
2082c7c4e3dSmrg *		The int equivalent of the defined string.
209c1e8faa6Smrg *		NULL if the string is not found in table
2102c7c4e3dSmrg *
2112c7c4e3dSmrg */
2122c7c4e3dSmrg{
2133458e6c2Smrg    while (pde->define != -1) {
2143458e6c2Smrg        if (pde->define == id) {
2153458e6c2Smrg            return (pde->pString);
2163458e6c2Smrg        }
2173458e6c2Smrg        pde++;
2182c7c4e3dSmrg    }
2193458e6c2Smrg    return (NULL);
2202c7c4e3dSmrg}
2212c7c4e3dSmrg
2222c7c4e3dSmrg/*
2232c7c4e3dSmrg *	NAME
2242c7c4e3dSmrg *		SCKeyOf - convert keyword into key ID
2252c7c4e3dSmrg *
2262c7c4e3dSmrg *	SYNOPSIS
2272c7c4e3dSmrg */
2282c7c4e3dSmrgstatic int
2292becc446SmrgSCKeyOf(const char *string)
2302c7c4e3dSmrg/*
2312c7c4e3dSmrg *	DESCRIPTION
2322c7c4e3dSmrg *		Converts a string to an integer define.
2332c7c4e3dSmrg *
2342c7c4e3dSmrg *		Looks up the string in the table and returns the integer
2352c7c4e3dSmrg *		associated with the string.
2362c7c4e3dSmrg *
2372c7c4e3dSmrg *		Later may need similar function for unsigned long define.
2382c7c4e3dSmrg *
2392c7c4e3dSmrg *
2402c7c4e3dSmrg *
2412c7c4e3dSmrg *	RETURNS
2422c7c4e3dSmrg *		The int equivalent of the defined string.
2432c7c4e3dSmrg *		-1 if the string is not found in table
2442c7c4e3dSmrg *
2452c7c4e3dSmrg */
2462c7c4e3dSmrg{
2473458e6c2Smrg    return (StrToDefine(KeyTbl, string));
2482c7c4e3dSmrg}
2492c7c4e3dSmrg
2502c7c4e3dSmrg/*
2512c7c4e3dSmrg *	NAME
2522c7c4e3dSmrg *		SCScrnClassOf - convert screen class string into class ID
2532c7c4e3dSmrg *
2542c7c4e3dSmrg *	SYNOPSIS
2552c7c4e3dSmrg */
2562c7c4e3dSmrgstatic int
2572becc446SmrgSCScrnClassOf(const char *string)
2582c7c4e3dSmrg/*
2592c7c4e3dSmrg *	DESCRIPTION
2602c7c4e3dSmrg *		Converts a string to an integer define.
2612c7c4e3dSmrg *
2622c7c4e3dSmrg *		Looks up the string in the table and returns the integer
2632c7c4e3dSmrg *		associated with the string.
2642c7c4e3dSmrg *
2652c7c4e3dSmrg *		Later may need similar function for unsigned long define.
2662c7c4e3dSmrg *
2672c7c4e3dSmrg *
2682c7c4e3dSmrg *
2692c7c4e3dSmrg *	RETURNS
2702c7c4e3dSmrg *		The int equivalent of the defined string.
2712c7c4e3dSmrg *		-1 if the string is not found in table
2722c7c4e3dSmrg *
2732c7c4e3dSmrg */
2742c7c4e3dSmrg{
2753458e6c2Smrg    return (StrToDefine(ScrnClassTbl, string));
2762c7c4e3dSmrg}
2772c7c4e3dSmrg
2782c7c4e3dSmrg/*
2792c7c4e3dSmrg *	NAME
2802c7c4e3dSmrg *		SCScrnClassStringOf - convert screen class id into class string
2812c7c4e3dSmrg *
2822c7c4e3dSmrg *	SYNOPSIS
2832c7c4e3dSmrg */
2842becc446Smrgstatic const char *
2852c7c4e3dSmrgSCScrnClassStringOf(int id)
2862c7c4e3dSmrg/*
2872c7c4e3dSmrg *	DESCRIPTION
2882c7c4e3dSmrg *		Converts a id to astring
2892c7c4e3dSmrg *
2902c7c4e3dSmrg *	RETURNS
291c1e8faa6Smrg *		Pointer to string if found; otherwise "unknown".
2922c7c4e3dSmrg *
2932c7c4e3dSmrg */
2942c7c4e3dSmrg{
295c1e8faa6Smrg    const char *str = DefineToStr(ScrnClassTbl, id);
296c1e8faa6Smrg
297c1e8faa6Smrg    if (str != NULL)
298c1e8faa6Smrg        return str;
299c1e8faa6Smrg    else
300c1e8faa6Smrg        return "unknown";
3012c7c4e3dSmrg}
3022c7c4e3dSmrg
3032c7c4e3dSmrg/* close the stream and return any memory allocated. */
3042becc446Smrgstatic void
3052becc446SmrgcloseS(FILE *stream, XDCCC_Correction *pCorrection)
3062c7c4e3dSmrg{
3072c7c4e3dSmrg    if (stream) {
3083458e6c2Smrg        fclose(stream);
3092c7c4e3dSmrg    }
3102c7c4e3dSmrg    while (pCorrection) {
311c1e8faa6Smrg        XDCCC_Correction *pNext = pCorrection->next;
3123458e6c2Smrg        free(pCorrection);
3133458e6c2Smrg        pCorrection = pNext;
3142c7c4e3dSmrg    }
3152c7c4e3dSmrg}
3162c7c4e3dSmrg
3172c7c4e3dSmrg/*
3182c7c4e3dSmrg *  Get a line of text from the stream.
3192c7c4e3dSmrg */
3202c7c4e3dSmrgstatic char *
3212c7c4e3dSmrgnextline(char *buf, int maxch, FILE *stream)
3222c7c4e3dSmrg{
3232c7c4e3dSmrg    linenum++;
3242c7c4e3dSmrg    return (fgets(buf, maxch, stream));
3252c7c4e3dSmrg}
3262c7c4e3dSmrg
3272c7c4e3dSmrgstatic int
3282c7c4e3dSmrgProcessColorimetric(FILE *stream, XDCCC_Matrix *pMatrix, int VisualFlag)
3292c7c4e3dSmrg{
3302c7c4e3dSmrg    char buf[BUFSIZ];
3312c7c4e3dSmrg    char keyword[BUFSIZ];
332c1e8faa6Smrg    char token[BUFSIZ];
3332c7c4e3dSmrg    unsigned int matrices_processed = 0;
3342c7c4e3dSmrg		/* bit 0 for XYZtoRGB matrix */
3352c7c4e3dSmrg		/* bit 1 for RGBtoXYZ matrix */
3362c7c4e3dSmrg    int	 state = 0;
3372c7c4e3dSmrg		 /* 0 -- looking for matrix */
3382c7c4e3dSmrg		 /* 1 -- processing data from matrix */
3392c7c4e3dSmrg		 /* 2 -- both matrices processed */
3402c7c4e3dSmrg		 /* Note: the order of the matrices is not important. */
3412c7c4e3dSmrg    int	 count = -1;
3422c7c4e3dSmrg    XcmsFloat *pElement = NULL;
3432c7c4e3dSmrg
3442c7c4e3dSmrg    while ((nextline(buf, BUFSIZ, stream)) != NULL) {
345c1e8faa6Smrg        int ntok = sscanf(buf, "%1023s %1023s", keyword, token);
346c1e8faa6Smrg
347c1e8faa6Smrg        if (ntok > 0) {
3483458e6c2Smrg            switch (SCKeyOf(keyword)) {
3493458e6c2Smrg            case XYZTORGBMAT_BEGIN:
3503458e6c2Smrg                if (VisualFlag != VIDEO_RGB) {
3513458e6c2Smrg                    fprintf(stderr,
3523458e6c2Smrg                            "Line %d: Keyword XYZTORGBMAT_BEGIN mismatch for visual %s.\n",
3533458e6c2Smrg                            linenum, SCScrnClassStringOf(VisualFlag));
3543458e6c2Smrg                    return (0);
3553458e6c2Smrg                }
3563458e6c2Smrg                if (state != 0) {
3573458e6c2Smrg                    fprintf(stderr,
3583458e6c2Smrg                            "Line %d: Extraneous keyword %s.\n",
3593458e6c2Smrg                            linenum, keyword);
3603458e6c2Smrg                    return (0);
3613458e6c2Smrg                }
3623458e6c2Smrg                state = 1;
3633458e6c2Smrg                count = 0;
3643458e6c2Smrg                pElement = (XcmsFloat *) pMatrix->XYZtoRGBmatrix;
3653458e6c2Smrg                break;
3663458e6c2Smrg            case XYZTORGBMAT_END:
3673458e6c2Smrg                if (VisualFlag != VIDEO_RGB) {
3683458e6c2Smrg                    fprintf(stderr,
3693458e6c2Smrg                            "Line %d: Keyword XYZTORGBMAT_END mismatch for visual %s.\n",
3703458e6c2Smrg                            linenum, SCScrnClassStringOf(VisualFlag));
3713458e6c2Smrg                    return (0);
3723458e6c2Smrg                }
3733458e6c2Smrg                if ((state != 1) || (count != 9)) {
3743458e6c2Smrg                    fprintf(stderr,
3753458e6c2Smrg                            "Line %d: Incomplete XYZtoRGB matrix -- Premature %s\n",
3763458e6c2Smrg                            linenum, keyword);
3773458e6c2Smrg                    return (0);
3783458e6c2Smrg                }
3793458e6c2Smrg                matrices_processed |= 0x1;
3803458e6c2Smrg                if (matrices_processed == 3) {
3813458e6c2Smrg                    state = 2;
3823458e6c2Smrg                }
3833458e6c2Smrg                else {
3843458e6c2Smrg                    state = 0;
3853458e6c2Smrg                }
3863458e6c2Smrg                break;
3873458e6c2Smrg            case RGBTOXYZMAT_BEGIN:
3883458e6c2Smrg                if (VisualFlag != VIDEO_RGB) {
3893458e6c2Smrg                    fprintf(stderr,
3903458e6c2Smrg                            "Line %d: Keyword RGBTOXYZMAT_BEGIN mismatch for visual %s.\n",
3913458e6c2Smrg                            linenum, SCScrnClassStringOf(VisualFlag));
3923458e6c2Smrg                    return (0);
3933458e6c2Smrg                }
3943458e6c2Smrg                if (state != 0) {
3953458e6c2Smrg                    fprintf(stderr, "Line %d: Extraneous keyword %s.\n",
3963458e6c2Smrg                            linenum, keyword);
3973458e6c2Smrg                    return (0);
3983458e6c2Smrg                }
3993458e6c2Smrg                state = 1;
4003458e6c2Smrg                count = 0;
4013458e6c2Smrg                pElement = (XcmsFloat *) pMatrix->RGBtoXYZmatrix;
4023458e6c2Smrg                break;
4033458e6c2Smrg            case RGBTOXYZMAT_END:
4043458e6c2Smrg                if (VisualFlag != VIDEO_RGB) {
4053458e6c2Smrg                    fprintf(stderr,
4063458e6c2Smrg                            "Line %d: Keyword RGBTOXYZMAT_END mismatch for visual %s.\n",
4073458e6c2Smrg                            linenum, SCScrnClassStringOf(VisualFlag));
4083458e6c2Smrg                    return (0);
4093458e6c2Smrg                }
4103458e6c2Smrg                if ((state != 1) || (count != 9)) {
4113458e6c2Smrg                    fprintf(stderr,
4123458e6c2Smrg                            "Line %d: Incomplete RGBtoXYZ matrix -- Premature %s\n",
4133458e6c2Smrg                            linenum, keyword);
4143458e6c2Smrg                    return (0);
4153458e6c2Smrg                }
4163458e6c2Smrg                matrices_processed |= 0x2;
4173458e6c2Smrg                if (matrices_processed == 3) {
4183458e6c2Smrg                    state = 2;
4193458e6c2Smrg                }
4203458e6c2Smrg                else {
4213458e6c2Smrg                    state = 0;
4223458e6c2Smrg                }
4233458e6c2Smrg                break;
4242c7c4e3dSmrg#ifdef GRAY
4253458e6c2Smrg            case WHITEPT_XYZ_BEGIN:
4263458e6c2Smrg                if (VisualFlag != VIDEO_GRAY) {
4273458e6c2Smrg                    fprintf(stderr,
4283458e6c2Smrg                            "Line %d: Keyword WHITEPT_XYZ_BEGIN mismatch for visual %s.\n",
4293458e6c2Smrg                            linenum, SCScrnClassStringOf(VisualFlag));
4303458e6c2Smrg                    return (0);
4313458e6c2Smrg                }
4323458e6c2Smrg                if (state != 0) {
4333458e6c2Smrg                    fprintf(stderr,
4343458e6c2Smrg                            "Line %d: Extraneous keyword %s.\n",
4353458e6c2Smrg                            linenum, keyword);
4363458e6c2Smrg                    return (0);
4373458e6c2Smrg                }
4383458e6c2Smrg                state = 1;
4393458e6c2Smrg                count = 0;
4403458e6c2Smrg                pElement = (XcmsFloat *) pMatrix->XYZtoRGBmatrix;
4413458e6c2Smrg                break;
4423458e6c2Smrg            case WHITEPT_XYZ_END:
4433458e6c2Smrg                if (VisualFlag != VIDEO_GRAY) {
4443458e6c2Smrg                    fprintf(stderr,
4453458e6c2Smrg                            "Line %d: Keyword WHITEPT_XYZ_END mismatch for visual %s.\n",
4463458e6c2Smrg                            linenum, SCScrnClassStringOf(VisualFlag));
4473458e6c2Smrg                    return (0);
4483458e6c2Smrg                }
4493458e6c2Smrg                if ((state != 1) || (count != 3)) {
4503458e6c2Smrg                    fprintf(stderr,
4513458e6c2Smrg                            "Line %d: Incomplete white point -- Premature %s\n",
4523458e6c2Smrg                            linenum, keyword);
4533458e6c2Smrg                    return (0);
4543458e6c2Smrg                }
4553458e6c2Smrg                state = 2;
4563458e6c2Smrg                break;
4572c7c4e3dSmrg#endif /* GRAY */
4583458e6c2Smrg            case DATA:
459c1e8faa6Smrg                for (char *ptoken = strtok(buf, DATA_DELIMS); ptoken != NULL;
4603458e6c2Smrg                     ptoken = strtok(NULL, DATA_DELIMS)) {
4613458e6c2Smrg                    if (sscanf(ptoken, "%lf", pElement) != 1) {
4623458e6c2Smrg                        if (VisualFlag == VIDEO_RGB) {
4633458e6c2Smrg                            fprintf(stderr,
4643458e6c2Smrg                                    "Line %d: Invalid matrix value %s.",
4653458e6c2Smrg                                    linenum, ptoken);
4663458e6c2Smrg                        }
4673458e6c2Smrg                        else {
4683458e6c2Smrg                            fprintf(stderr,
4693458e6c2Smrg                                    "Line %d: Invalid CIEXYZ value %s.\n",
4703458e6c2Smrg                                    linenum, ptoken);
4713458e6c2Smrg                        }
4723458e6c2Smrg                        return (0);
4733458e6c2Smrg                    }
4743458e6c2Smrg                    pElement++;
4753458e6c2Smrg                    if (VisualFlag == VIDEO_RGB) {
4763458e6c2Smrg                        if (++count > 9) {
4773458e6c2Smrg                            fprintf(stderr,
4783458e6c2Smrg                                    "Line %d: Extra matrix value %s\n",
4793458e6c2Smrg                                    linenum, ptoken);
4803458e6c2Smrg                            return (0);
4813458e6c2Smrg                        }
4823458e6c2Smrg                    }
4833458e6c2Smrg                    else {
4843458e6c2Smrg                        if (++count > 3) {
4853458e6c2Smrg                            fprintf(stderr,
4863458e6c2Smrg                                    "Line %d: Extra CIEXYZ value %s.\n",
4873458e6c2Smrg                                    linenum, ptoken);
4883458e6c2Smrg                            return (0);
4893458e6c2Smrg                        }
4903458e6c2Smrg                    }
4913458e6c2Smrg                }
4923458e6c2Smrg                break;
4933458e6c2Smrg            case COLORIMETRIC_BEGIN:
4943458e6c2Smrg                fprintf(stderr,
4953458e6c2Smrg                        "Line %d: Extraneous keyword %s.\n", linenum, keyword);
4963458e6c2Smrg                return (0);
4973458e6c2Smrg            case COLORIMETRIC_END:
4983458e6c2Smrg                if (state != 2) {
4993458e6c2Smrg                    fprintf(stderr,
5003458e6c2Smrg                            "Line %d: Incomplete Colorimetric data -- Premature %s\n",
5013458e6c2Smrg                            linenum, keyword);
5023458e6c2Smrg                    return (0);
5033458e6c2Smrg                }
5043458e6c2Smrg                return (1);
5053458e6c2Smrg            case COMMENT:
5063458e6c2Smrg                /* Currently, do nothing. */
5073458e6c2Smrg                break;
5083458e6c2Smrg            default:
5093458e6c2Smrg                fprintf(stderr,
5103458e6c2Smrg                        "Line %d: Unexpected keyword %s\n", linenum, keyword);
5113458e6c2Smrg                return (0);
5123458e6c2Smrg            }
5133458e6c2Smrg        }
5143458e6c2Smrg        else if (ntok < 0) {
5153458e6c2Smrg            /* mismatch */
5163458e6c2Smrg            fprintf(stderr, "Line %d: Unrecognized keyword\n", linenum);
5173458e6c2Smrg            return (0);
5183458e6c2Smrg        }
5192c7c4e3dSmrg    }
5202c7c4e3dSmrg    return (0);
5212c7c4e3dSmrg}
5222c7c4e3dSmrg
5232c7c4e3dSmrgstatic int
5242c7c4e3dSmrgProcessIProfile(FILE *stream, XDCCC_Correction *pCorrection)
5252c7c4e3dSmrg{
5262c7c4e3dSmrg    char buf[BUFSIZ];
527c1e8faa6Smrg    char *tableStr, *sizeStr;
5282c7c4e3dSmrg    int  size;
5293458e6c2Smrg    int  state = 0;
5303458e6c2Smrg         /************************************************
5312c7c4e3dSmrg	  * 0 -- Looking for Intensity Table(s)          *
5322c7c4e3dSmrg	  * 1 -- Processing Intensity Table(s)           *
5332c7c4e3dSmrg          ************************************************/
5343458e6c2Smrg    int  nTbl = 0;
5353458e6c2Smrg    int  count = 0;
5362c7c4e3dSmrg    IntensityRec *pIRec = NULL;
5372c7c4e3dSmrg
5382c7c4e3dSmrg    while ((nextline(buf, BUFSIZ, stream)) != NULL) {
539c1e8faa6Smrg        char *ptoken = strtok(buf, DATA_DELIMS);
540c1e8faa6Smrg        char *keyword = ptoken;
541c1e8faa6Smrg
5423458e6c2Smrg        if (keyword != NULL) {
5433458e6c2Smrg            switch (SCKeyOf(keyword)) {
5443458e6c2Smrg            case ITBL_BEGIN:
5453458e6c2Smrg                if (state != 0) {
5463458e6c2Smrg                    fprintf(stderr, "Line %d: unexpected keyword %s\n",
5473458e6c2Smrg                            linenum, keyword);
5483458e6c2Smrg                    return (0);
5493458e6c2Smrg                }
5503458e6c2Smrg                tableStr = strtok(NULL, DATA_DELIMS);
5513458e6c2Smrg                sizeStr = strtok(NULL, DATA_DELIMS);
5523458e6c2Smrg                if ((sizeStr == NULL) ||
5533458e6c2Smrg                    sscanf(sizeStr, "%d", &size) != 1) {
5543458e6c2Smrg                    fprintf(stderr,
5553458e6c2Smrg                            "Line %d: invalid Intensity Table size, %s.\n",
556c1e8faa6Smrg                            linenum, sizeStr ? sizeStr : "\"\"");
5573458e6c2Smrg                    return (0);
5583458e6c2Smrg                }
5593458e6c2Smrg                if (size < 0) {
5603458e6c2Smrg                    fprintf(stderr,
5613458e6c2Smrg                            "Line %d: count %d < 0 for Intensity Table.\n",
5623458e6c2Smrg                            linenum, size);
5633458e6c2Smrg                    return (0);
5643458e6c2Smrg                }
5653458e6c2Smrg                if (strcmp(tableStr, "GREEN") == 0) {
5663458e6c2Smrg                    if (pCorrection->nTables != 3) {
5673458e6c2Smrg                        fprintf(stderr, "Line %d: incorrect number of tables\n",
5683458e6c2Smrg                                linenum);
5693458e6c2Smrg                        return (0);
5703458e6c2Smrg                    }
5713458e6c2Smrg                    if (pCorrection->pGreenTbl->pBase != NULL) {
5723458e6c2Smrg                        fprintf(stderr,
5733458e6c2Smrg                                "Line %d: multiple GREEN Intensity Profiles\n",
5743458e6c2Smrg                                linenum);
5753458e6c2Smrg                        return (0);
5763458e6c2Smrg                    }
5773458e6c2Smrg                    pCorrection->pGreenTbl->nEntries = size;
5783458e6c2Smrg                    pCorrection->pGreenTbl->pBase =
5793458e6c2Smrg                        calloc(size, sizeof(IntensityRec));
5803458e6c2Smrg                    if (pCorrection->pGreenTbl->pBase == NULL) {
5813458e6c2Smrg                        fprintf(stderr,
5823458e6c2Smrg                                "Line %d: Unable to allocate space for GREEN Intensity Profile\n",
5833458e6c2Smrg                                linenum);
5843458e6c2Smrg                        return (0);
5853458e6c2Smrg                    }
5863458e6c2Smrg                    pIRec = pCorrection->pGreenTbl->pBase;
5873458e6c2Smrg                }
5883458e6c2Smrg                else if (strcmp(tableStr, "BLUE") == 0) {
5893458e6c2Smrg                    if (pCorrection->nTables != 3) {
5903458e6c2Smrg                        fprintf(stderr,
5913458e6c2Smrg                                "Line %d: incorrect number of tables\n",
5923458e6c2Smrg                                linenum);
5933458e6c2Smrg                        return (0);
5943458e6c2Smrg                    }
5953458e6c2Smrg                    if (pCorrection->pBlueTbl->pBase != NULL) {
5963458e6c2Smrg                        fprintf(stderr,
5973458e6c2Smrg                                "Line %d: multiple BLUE Intensity Profiles\n",
5983458e6c2Smrg                                linenum);
5993458e6c2Smrg                        return (0);
6003458e6c2Smrg                    }
6013458e6c2Smrg                    pCorrection->pBlueTbl->nEntries = size;
6023458e6c2Smrg                    pCorrection->pBlueTbl->pBase =
6033458e6c2Smrg                        calloc(size, sizeof(IntensityRec));
6043458e6c2Smrg                    if (pCorrection->pBlueTbl->pBase == NULL) {
6053458e6c2Smrg                        fprintf(stderr,
6063458e6c2Smrg                                "Line %d: Unable to allocate space for BLUE Intensity Profile\n",
6073458e6c2Smrg                                linenum);
6083458e6c2Smrg                        return (0);
6093458e6c2Smrg                    }
6103458e6c2Smrg                    pIRec = pCorrection->pBlueTbl->pBase;
6113458e6c2Smrg                }
6123458e6c2Smrg                else {
6133458e6c2Smrg                    if (!strcmp(tableStr, "RGB") && pCorrection->nTables != 1) {
6143458e6c2Smrg                        fprintf(stderr,
6153458e6c2Smrg                                "Line %d: multiple RGB Intensity Tables",
6163458e6c2Smrg                                linenum);
6173458e6c2Smrg                        return (0);
6183458e6c2Smrg                    }
6193458e6c2Smrg                    if (pCorrection->pRedTbl->pBase != NULL) {
6203458e6c2Smrg                        fprintf(stderr,
6213458e6c2Smrg                                "Line %d: multiple RED or GREEN or BLUE Intensity Tables\n",
6223458e6c2Smrg                                linenum);
6233458e6c2Smrg                        return (0);
6243458e6c2Smrg                    }
6253458e6c2Smrg                    pCorrection->pRedTbl->nEntries = size;
6263458e6c2Smrg                    pCorrection->pRedTbl->pBase =
6273458e6c2Smrg                        calloc(size, sizeof(IntensityRec));
6283458e6c2Smrg                    if (pCorrection->pRedTbl->pBase == NULL) {
6293458e6c2Smrg                        fprintf(stderr,
6303458e6c2Smrg                                "Line %d: Unable to allocate space for intensity table\n",
6313458e6c2Smrg                                linenum);
6323458e6c2Smrg                        return (0);
6333458e6c2Smrg                    }
6343458e6c2Smrg                    pIRec = pCorrection->pRedTbl->pBase;
6353458e6c2Smrg                }
6363458e6c2Smrg                state = 1;
6373458e6c2Smrg                count = 0;
6383458e6c2Smrg                break;
6393458e6c2Smrg            case ITBL_END:
6403458e6c2Smrg                if ((state != 1) || (count != size)) {
6413458e6c2Smrg                    fprintf(stderr,
6423458e6c2Smrg                            "Line %d: incomplete Intensity Table -- Premature %s\n",
6433458e6c2Smrg                            linenum, keyword);
6443458e6c2Smrg                    return (0);
6453458e6c2Smrg                }
6463458e6c2Smrg                nTbl++;
6473458e6c2Smrg                state = 0;
6483458e6c2Smrg                break;
6493458e6c2Smrg            case DATA:
6503458e6c2Smrg                if (pIRec == NULL) {
6513458e6c2Smrg                    fprintf(stderr,
6523458e6c2Smrg                            "Line %d: Invalid Intensity Profile -- Premature %s\n",
6533458e6c2Smrg                            linenum, keyword);
6543458e6c2Smrg                    return (0);
6553458e6c2Smrg                }
6563458e6c2Smrg                do {
6573458e6c2Smrg                    /********************************************************
6582becc446Smrg		     * Note: tableType should only be 0 or 1 at this point.
6592c7c4e3dSmrg		     *       0 indicates value and intensity stored.
6602becc446Smrg		     *       1 indicates only intensity stored.
6612c7c4e3dSmrg		     ********************************************************/
6623458e6c2Smrg                    if (pCorrection->tableType) {
6633458e6c2Smrg                        if (sscanf(ptoken, "%lf", &pIRec->intensity) != 1) {
6643458e6c2Smrg                            fprintf(stderr,
6653458e6c2Smrg                                    "Line %d: invalid Intensity Profile value %s\n",
6663458e6c2Smrg                                    linenum, ptoken);
6673458e6c2Smrg                            return (0);
6683458e6c2Smrg                        }
6693458e6c2Smrg                        /* With tableType 1 only store the intensity. */
6703458e6c2Smrg                        pIRec++;
6713458e6c2Smrg                    }
6723458e6c2Smrg                    else {
6733458e6c2Smrg                        short tmp;
6743458e6c2Smrg
6753458e6c2Smrg                        /* Note ANSI C can handle 0x preceding hex number */
6763458e6c2Smrg                        if (sscanf(ptoken, "%hi", &tmp) != 1) {
6773458e6c2Smrg                            fprintf(stderr,
6783458e6c2Smrg                                    "Line %d: invalid Intensity Profile value %s\n",
6793458e6c2Smrg                                    linenum, ptoken);
6803458e6c2Smrg                            return (0);
6813458e6c2Smrg                        }
6823458e6c2Smrg                        else
6833458e6c2Smrg                            pIRec->value = tmp;
6843458e6c2Smrg                        if ((ptoken = strtok(NULL, DATA_DELIMS)) == NULL) {
6853458e6c2Smrg                            fprintf(stderr,
6863458e6c2Smrg                                    "Line %d: missing Intensity Profile value\n",
6873458e6c2Smrg                                    linenum);
6883458e6c2Smrg                            return (0);
6893458e6c2Smrg                        }
6903458e6c2Smrg                        if (sscanf(ptoken, "%lf", &pIRec->intensity) != 1) {
6913458e6c2Smrg                            fprintf(stderr,
6923458e6c2Smrg                                    "Line %d: invalid Intensity Profile intensity %s\n",
6933458e6c2Smrg                                    linenum, ptoken);
6943458e6c2Smrg                            return (0);
6953458e6c2Smrg                        }
6963458e6c2Smrg                        /* With tableType 0 only store both value & intensity */
6973458e6c2Smrg                        pIRec++;
6983458e6c2Smrg                    }
6993458e6c2Smrg                    if (++count > size) {
7003458e6c2Smrg                        fprintf(stderr,
7013458e6c2Smrg                                "Line %d: extra Intensity value %s\n",
7023458e6c2Smrg                                linenum, ptoken);
7033458e6c2Smrg                        return (0);
7043458e6c2Smrg                    }
7053458e6c2Smrg                    ptoken = strtok(NULL, DATA_DELIMS);
7063458e6c2Smrg                } while (ptoken != NULL);
7073458e6c2Smrg                break;
7083458e6c2Smrg            case IPROFILE_BEGIN:
7093458e6c2Smrg                fprintf(stderr, "Line %d: extraneous keyword %s\n",
7103458e6c2Smrg                        linenum, keyword);
7113458e6c2Smrg                return (0);
7123458e6c2Smrg            case IPROFILE_END:
7133458e6c2Smrg                if ((state != 0) || (nTbl != pCorrection->nTables)) {
7143458e6c2Smrg                    fprintf(stderr,
7153458e6c2Smrg                            "Line %d: incomplete Intensity Profile data -- Premature %s\n",
7163458e6c2Smrg                            linenum, keyword);
7173458e6c2Smrg                    return (0);
7183458e6c2Smrg                }
7193458e6c2Smrg                return (1);
7203458e6c2Smrg            case COMMENT:
7213458e6c2Smrg                /* ignore line */
7223458e6c2Smrg                break;
7233458e6c2Smrg            default:
7243458e6c2Smrg                fprintf(stderr, "Line %d: unexpected keyword %s\n",
7253458e6c2Smrg                        linenum, keyword);
7263458e6c2Smrg                return (0);
7273458e6c2Smrg            }
7283458e6c2Smrg        }                       /* else its was just a blank line */
7292c7c4e3dSmrg    }
7302c7c4e3dSmrg    return (0);
7312c7c4e3dSmrg}
7322c7c4e3dSmrg
7332c7c4e3dSmrgstatic void
7342c7c4e3dSmrgPutTableType0Card8(IntensityTbl *pTbl, unsigned char **pCard8)
7352c7c4e3dSmrg{
7362c7c4e3dSmrg    unsigned int count;
7372c7c4e3dSmrg    IntensityRec *pIRec;
7382c7c4e3dSmrg
7392c7c4e3dSmrg    pIRec = pTbl->pBase;
7402c7c4e3dSmrg    count = pTbl->nEntries;
7412c7c4e3dSmrg    **pCard8 = count - 1;
7422c7c4e3dSmrg    *pCard8 += 1;
7432c7c4e3dSmrg    for (; count; count--, pIRec++) {
7443458e6c2Smrg        **pCard8 = pIRec->value >> 8;
7453458e6c2Smrg        *pCard8 += 1;
7463458e6c2Smrg        **pCard8 = pIRec->intensity * 255.0;
7473458e6c2Smrg        *pCard8 += 1;
7482c7c4e3dSmrg    }
7492c7c4e3dSmrg}
7502c7c4e3dSmrg
7512c7c4e3dSmrgstatic void
7522c7c4e3dSmrgPutTableType1Card8(IntensityTbl *pTbl, unsigned char **pCard8)
7532c7c4e3dSmrg{
7542c7c4e3dSmrg    unsigned int count;
7552c7c4e3dSmrg    IntensityRec *pIRec;
7562c7c4e3dSmrg
7572c7c4e3dSmrg    pIRec = pTbl->pBase;
7582c7c4e3dSmrg    count = pTbl->nEntries;
7592c7c4e3dSmrg    **pCard8 = count - 1;
7602c7c4e3dSmrg    *pCard8 += 1;
7612c7c4e3dSmrg    for (; count; count--, pIRec++) {
7623458e6c2Smrg        **pCard8 = pIRec->intensity * 255.0;
7633458e6c2Smrg        *pCard8 += 1;
7642c7c4e3dSmrg    }
7652c7c4e3dSmrg}
7662c7c4e3dSmrg
7672c7c4e3dSmrgstatic void
7682c7c4e3dSmrgPutTableType0Card16(IntensityTbl *pTbl, unsigned short **pCard16)
7692c7c4e3dSmrg{
7702c7c4e3dSmrg    unsigned int count;
7712c7c4e3dSmrg    IntensityRec *pIRec;
7722c7c4e3dSmrg
7732c7c4e3dSmrg    pIRec = pTbl->pBase;
7742c7c4e3dSmrg    count = pTbl->nEntries;
7752c7c4e3dSmrg    **pCard16 = count - 1;
7762c7c4e3dSmrg    *pCard16 += 1;
7772c7c4e3dSmrg    for (; count; count--, pIRec++) {
7783458e6c2Smrg        **pCard16 = pIRec->value;
7793458e6c2Smrg        *pCard16 += 1;
7803458e6c2Smrg        **pCard16 = pIRec->intensity * 65535.0;
7813458e6c2Smrg        *pCard16 += 1;
7822c7c4e3dSmrg    }
7832c7c4e3dSmrg}
7842c7c4e3dSmrg
7852c7c4e3dSmrgstatic void
7862c7c4e3dSmrgPutTableType1Card16(IntensityTbl *pTbl, unsigned short **pCard16)
7872c7c4e3dSmrg{
7882c7c4e3dSmrg    unsigned int count;
7892c7c4e3dSmrg    IntensityRec *pIRec;
7902c7c4e3dSmrg
7912c7c4e3dSmrg    pIRec = pTbl->pBase;
7922c7c4e3dSmrg    count = pTbl->nEntries;
7932c7c4e3dSmrg    **pCard16 = count - 1;
7942c7c4e3dSmrg    *pCard16 += 1;
7952c7c4e3dSmrg    for (; count; count--, pIRec++) {
7963458e6c2Smrg        **pCard16 = pIRec->intensity * 65535.0;
7973458e6c2Smrg        *pCard16 += 1;
7982c7c4e3dSmrg    }
7992c7c4e3dSmrg}
8002c7c4e3dSmrg
8012c7c4e3dSmrgstatic void
8022c7c4e3dSmrgPutTableType0Card32(IntensityTbl *pTbl, unsigned long **pCard32)
8032c7c4e3dSmrg{
8042c7c4e3dSmrg    unsigned int count;
8052c7c4e3dSmrg    IntensityRec *pIRec;
8062c7c4e3dSmrg
8072c7c4e3dSmrg    pIRec = pTbl->pBase;
8082c7c4e3dSmrg    count = pTbl->nEntries;
8092c7c4e3dSmrg    **pCard32 = count - 1;
8102c7c4e3dSmrg    *pCard32 += 1;
8112c7c4e3dSmrg    for (; count; count--, pIRec++) {
8123458e6c2Smrg        **pCard32 = pIRec->value;
8133458e6c2Smrg        *pCard32 += 1;
8143458e6c2Smrg        **pCard32 = pIRec->intensity * 4294967295.0;
8153458e6c2Smrg        *pCard32 += 1;
8162c7c4e3dSmrg    }
8172c7c4e3dSmrg}
8182c7c4e3dSmrg
8192c7c4e3dSmrgstatic void
8202c7c4e3dSmrgPutTableType1Card32(IntensityTbl *pTbl, unsigned long **pCard32)
8212c7c4e3dSmrg{
8222c7c4e3dSmrg    unsigned int count;
8232c7c4e3dSmrg    IntensityRec *pIRec;
8242c7c4e3dSmrg
8252c7c4e3dSmrg    pIRec = pTbl->pBase;
8262c7c4e3dSmrg    count = pTbl->nEntries;
8272c7c4e3dSmrg    **pCard32 = count - 1;
8282c7c4e3dSmrg    *pCard32 += 1;
8292c7c4e3dSmrg    for (; count; count--, pIRec++) {
8303458e6c2Smrg        **pCard32 = pIRec->intensity * 4294967295.0;
8313458e6c2Smrg        *pCard32 += 1;
8322c7c4e3dSmrg    }
8332c7c4e3dSmrg}
8342c7c4e3dSmrg
8352c7c4e3dSmrgstatic void
8363458e6c2SmrgLoadMatrix(Display * pDpy, Window root, XDCCC_Matrix * pMatrix)
8372c7c4e3dSmrg{
8383458e6c2Smrg    int count;
8393458e6c2Smrg    unsigned long *pCard32;
8403458e6c2Smrg    unsigned long Card32Array[18];
8412c7c4e3dSmrg    Atom MatricesAtom;
8422c7c4e3dSmrg    XcmsFloat *pValue;
8432c7c4e3dSmrg
8442c7c4e3dSmrg    /*
8452c7c4e3dSmrg     * Store the XDCCC_LINEAR_RGB_MATRICES
8462c7c4e3dSmrg     */
8472c7c4e3dSmrg    pCard32 = Card32Array;
8483458e6c2Smrg    pValue = (XcmsFloat *) pMatrix->XYZtoRGBmatrix;
8492c7c4e3dSmrg    for (count = 0; count < 9; count++) {
8503458e6c2Smrg        *pCard32++ = (unsigned long) (*pValue++ * (XcmsFloat) XDCCC_NUMBER);
8512c7c4e3dSmrg    }
8523458e6c2Smrg    pValue = (XcmsFloat *) pMatrix->RGBtoXYZmatrix;
8532c7c4e3dSmrg    for (count = 0; count < 9; count++) {
8543458e6c2Smrg        *pCard32++ = (unsigned long) (*pValue++ * (XcmsFloat) XDCCC_NUMBER);
8552c7c4e3dSmrg    }
8563458e6c2Smrg    MatricesAtom = XInternAtom(pDpy, XDCCC_MATRIX_ATOM_NAME, False);
8573458e6c2Smrg    XChangeProperty(pDpy, root, MatricesAtom, XA_INTEGER, 32,
8583458e6c2Smrg                    PropModeReplace, (unsigned char *) Card32Array, 18);
8592c7c4e3dSmrg}
8602c7c4e3dSmrg
8612c7c4e3dSmrgstatic int
8622becc446SmrgLoadCorrections(Display *pDpy, Window root, XDCCC_Correction *pCorrection,
8633458e6c2Smrg                int targetFormat)
8642c7c4e3dSmrg{
8653458e6c2Smrg    unsigned char *pCard8;
8663458e6c2Smrg    unsigned char *pCard8Array = NULL;
8673458e6c2Smrg    unsigned short *pCard16;
8683458e6c2Smrg    unsigned short *pCard16Array = NULL;
8693458e6c2Smrg    unsigned long *pCard32;
8703458e6c2Smrg    unsigned long *pCard32Array = NULL;
8712c7c4e3dSmrg    Atom CorrectAtom;
8723458e6c2Smrg    int total;
8732c7c4e3dSmrg    int i;
8742c7c4e3dSmrg
8752c7c4e3dSmrg    /*
8762c7c4e3dSmrg     * Store each XDCCC_CORRECTION into XDCCC_LINEAR_RGB_CORRECTION property
8772c7c4e3dSmrg     */
8783458e6c2Smrg    CorrectAtom = XInternAtom(pDpy, XDCCC_CORRECT_ATOM_NAME, False);
8792c7c4e3dSmrg
8802c7c4e3dSmrg    for (i = 0; pCorrection; i++, pCorrection = pCorrection->next) {
8813458e6c2Smrg        if ((pCorrection->tableType != 0) && (pCorrection->tableType != 1)) {
8823458e6c2Smrg            if (pCorrection->visual_info.visualid) {
8833458e6c2Smrg                fprintf(stderr,
8843458e6c2Smrg                        "RGB Correction for visualid %ld: Invalid intensity table type %d.\n",
8853458e6c2Smrg                        pCorrection->visual_info.visualid,
8863458e6c2Smrg                        pCorrection->tableType);
8873458e6c2Smrg            }
8883458e6c2Smrg            else {
8893458e6c2Smrg                fprintf(stderr,
8903458e6c2Smrg                        "Global RGB Correction: Invalid intensity table type %d.\n",
8913458e6c2Smrg                        pCorrection->tableType);
8923458e6c2Smrg            }
8933458e6c2Smrg            return (0);
8943458e6c2Smrg        }
8953458e6c2Smrg
8963458e6c2Smrg        if (pCorrection->nTables != 1 && pCorrection->nTables != 3) {
8973458e6c2Smrg            if (pCorrection->visual_info.visualid) {
8983458e6c2Smrg                fprintf(stderr,
8993458e6c2Smrg                        "RGB Correction for visualid %ld: %d invalid number of tables.\n",
9003458e6c2Smrg                        pCorrection->visual_info.visualid,
9013458e6c2Smrg                        pCorrection->nTables);
9023458e6c2Smrg            }
9033458e6c2Smrg            else {
9043458e6c2Smrg                fprintf(stderr,
9053458e6c2Smrg                        "Global RGB Correction: %d invalid number of tables.\n",
9063458e6c2Smrg                        pCorrection->nTables);
9073458e6c2Smrg            }
9083458e6c2Smrg            return (0);
9093458e6c2Smrg        }
9103458e6c2Smrg
9113458e6c2Smrg        if (pCorrection->nTables == 1) {
9123458e6c2Smrg            if (pCorrection->pRedTbl->nEntries < 2) {
9133458e6c2Smrg                if (pCorrection->visual_info.visualid) {
9143458e6c2Smrg                    fprintf(stderr,
9153458e6c2Smrg                            "RGB Correction for visualid %ld: Illegal number of entries in table\n",
9163458e6c2Smrg                            pCorrection->visual_info.visualid);
9173458e6c2Smrg                }
9183458e6c2Smrg                else {
9193458e6c2Smrg                    fprintf(stderr,
9203458e6c2Smrg                            "Global RGB Correction: Illegal number of entries in table\n");
9213458e6c2Smrg                }
9223458e6c2Smrg                return (0);
9233458e6c2Smrg            }
9243458e6c2Smrg            switch (targetFormat) {
9253458e6c2Smrg            case 8:
9263458e6c2Smrg                total = 7 + (pCorrection->pRedTbl->nEntries *
9273458e6c2Smrg                             (pCorrection->tableType == 0 ? 2 : 1));
9283458e6c2Smrg                pCard8 = pCard8Array = calloc(total, sizeof(unsigned char));
9293458e6c2Smrg                if (pCard8 == NULL) {
9303458e6c2Smrg                    fprintf(stderr, "Unable allocate array of ints\n");
9313458e6c2Smrg                    return (0);
9323458e6c2Smrg                }
9333458e6c2Smrg                *pCard8++ = (pCorrection->visual_info.visualid >> 24) & 0xFF;
9343458e6c2Smrg                *pCard8++ = (pCorrection->visual_info.visualid >> 16) & 0xFF;
9353458e6c2Smrg                *pCard8++ = (pCorrection->visual_info.visualid >> 8) & 0xFF;
9363458e6c2Smrg                *pCard8++ = (pCorrection->visual_info.visualid) & 0xFF;
9373458e6c2Smrg                *pCard8++ = pCorrection->tableType;     /* type */
9383458e6c2Smrg                *pCard8++ = 1;  /* number of tables = 1 */
9393458e6c2Smrg                if (pCorrection->tableType == 0) {
9403458e6c2Smrg                    PutTableType0Card8(pCorrection->pRedTbl, &pCard8);
9413458e6c2Smrg                }
9423458e6c2Smrg                else {
9433458e6c2Smrg                    PutTableType1Card8(pCorrection->pRedTbl, &pCard8);
9443458e6c2Smrg                }
9453458e6c2Smrg                XChangeProperty(pDpy, root, CorrectAtom, XA_INTEGER, 8,
9463458e6c2Smrg                                i ? PropModeAppend : PropModeReplace,
9473458e6c2Smrg                                (unsigned char *) pCard8Array, total);
9483458e6c2Smrg                free(pCard8Array);
9493458e6c2Smrg                break;
9503458e6c2Smrg            case 16:
9513458e6c2Smrg                total = 5 + (pCorrection->pRedTbl->nEntries *
9523458e6c2Smrg                             (pCorrection->tableType == 0 ? 2 : 1));
9533458e6c2Smrg                pCard16 = pCard16Array = calloc(total, sizeof (unsigned short));
9543458e6c2Smrg                if (pCard16 == NULL) {
9553458e6c2Smrg                    fprintf(stderr, "Unable allocate array of ints\n");
9563458e6c2Smrg                    return (0);
9573458e6c2Smrg                }
9583458e6c2Smrg                *pCard16++ = (pCorrection->visual_info.visualid >> 16) & 0xFFFF;
9593458e6c2Smrg                *pCard16++ = (pCorrection->visual_info.visualid) & 0xFFFF;
9603458e6c2Smrg                *pCard16++ = pCorrection->tableType;    /* type */
9613458e6c2Smrg                *pCard16++ = 1; /* number of tables = 1 */
9623458e6c2Smrg                if (pCorrection->tableType == 0) {
9633458e6c2Smrg                    PutTableType0Card16(pCorrection->pRedTbl, &pCard16);
9643458e6c2Smrg                }
9653458e6c2Smrg                else {
9663458e6c2Smrg                    PutTableType1Card16(pCorrection->pRedTbl, &pCard16);
9673458e6c2Smrg                }
9683458e6c2Smrg                XChangeProperty(pDpy, root, CorrectAtom, XA_INTEGER, 16,
9693458e6c2Smrg                                i ? PropModeAppend : PropModeReplace,
9703458e6c2Smrg                                (unsigned char *) pCard16Array, total);
9713458e6c2Smrg                free(pCard16Array);
9723458e6c2Smrg                break;
9733458e6c2Smrg            case 32:
9743458e6c2Smrg                total = 4 + (pCorrection->pRedTbl->nEntries *
9753458e6c2Smrg                             (pCorrection->tableType == 0 ? 2 : 1));
9763458e6c2Smrg                pCard32 = pCard32Array = calloc(total, sizeof(unsigned long));
9773458e6c2Smrg                if (pCard32 == NULL) {
9783458e6c2Smrg                    fprintf(stderr, "Unable allocate array of ints\n");
9793458e6c2Smrg                    return (0);
9803458e6c2Smrg                }
9813458e6c2Smrg                *pCard32++ = pCorrection->visual_info.visualid;
9823458e6c2Smrg                *pCard32++ = pCorrection->tableType;    /* type */
9833458e6c2Smrg                *pCard32++ = 1; /* number of tables = 1 */
9843458e6c2Smrg                if (pCorrection->tableType == 0) {
9853458e6c2Smrg                    PutTableType0Card32(pCorrection->pRedTbl, &pCard32);
9863458e6c2Smrg                }
9873458e6c2Smrg                else {
9883458e6c2Smrg                    PutTableType1Card32(pCorrection->pRedTbl, &pCard32);
9893458e6c2Smrg                }
9903458e6c2Smrg                XChangeProperty(pDpy, root, CorrectAtom, XA_INTEGER, 32,
9913458e6c2Smrg                                i ? PropModeAppend : PropModeReplace,
9923458e6c2Smrg                                (unsigned char *) pCard32Array, total);
9933458e6c2Smrg                free(pCard32Array);
9943458e6c2Smrg                break;
9953458e6c2Smrg            default:
9963458e6c2Smrg                if (pCorrection->visual_info.visualid) {
9973458e6c2Smrg                    fprintf(stderr,
9983458e6c2Smrg                            "RGB Correction for visualid %ld: Invalid property format\n",
9993458e6c2Smrg                            pCorrection->visual_info.visualid);
10003458e6c2Smrg                }
10013458e6c2Smrg                else {
10023458e6c2Smrg                    fprintf(stderr,
10033458e6c2Smrg                            "Global RGB Correction: Invalid property format\n");
10043458e6c2Smrg                }
10053458e6c2Smrg                return (0);
10063458e6c2Smrg            }
10073458e6c2Smrg        }
10083458e6c2Smrg        else {                  /* pCorrection->nTables == 3 */
10093458e6c2Smrg            if ((pCorrection->pRedTbl->nEntries < 2) ||
10103458e6c2Smrg                (pCorrection->pGreenTbl->nEntries < 2) ||
10113458e6c2Smrg                (pCorrection->pBlueTbl->nEntries < 2)) {
10123458e6c2Smrg                if (pCorrection->visual_info.visualid) {
10133458e6c2Smrg                    fprintf(stderr,
10143458e6c2Smrg                            "RGB Correction for visualid %ld: Illegal number of entries in table\n",
10153458e6c2Smrg                            pCorrection->visual_info.visualid);
10163458e6c2Smrg                }
10173458e6c2Smrg                else {
10183458e6c2Smrg                    fprintf(stderr,
10193458e6c2Smrg                            "Global RGB Correction: Illegal number of entries in table\n");
10203458e6c2Smrg                }
10213458e6c2Smrg                return (0);
10223458e6c2Smrg            }
10233458e6c2Smrg            switch (targetFormat) {
10243458e6c2Smrg            case 8:
10253458e6c2Smrg                total = 9 +     /* visualID, type, and 3 lengths */
10263458e6c2Smrg                    (pCorrection->pRedTbl->nEntries *
10273458e6c2Smrg                     (pCorrection->tableType == 0 ? 2 : 1)) +
10283458e6c2Smrg                    (pCorrection->pGreenTbl->nEntries *
10293458e6c2Smrg                     (pCorrection->tableType == 0 ? 2 : 1)) +
10303458e6c2Smrg                    (pCorrection->pBlueTbl->nEntries *
10313458e6c2Smrg                     (pCorrection->tableType == 0 ? 2 : 1));
10323458e6c2Smrg                pCard8 = pCard8Array = calloc(total, sizeof(unsigned char));
10333458e6c2Smrg                if (pCard8 == NULL) {
10343458e6c2Smrg                    fprintf(stderr, "Unable allocate array of ints\n");
10353458e6c2Smrg                    return (0);
10363458e6c2Smrg                }
10373458e6c2Smrg                *pCard8++ = (pCorrection->visual_info.visualid >> 24) & 0xFF;
10383458e6c2Smrg                *pCard8++ = (pCorrection->visual_info.visualid >> 16) & 0xFF;
10393458e6c2Smrg                *pCard8++ = (pCorrection->visual_info.visualid >> 8) & 0xFF;
10403458e6c2Smrg                *pCard8++ = (pCorrection->visual_info.visualid) & 0xFF;
10413458e6c2Smrg                *pCard8++ = pCorrection->tableType;     /* type */
10423458e6c2Smrg                *pCard8++ = 3;  /* number of tables = 3 */
10433458e6c2Smrg                if (pCorrection->tableType == 0) {
10443458e6c2Smrg                    PutTableType0Card8(pCorrection->pRedTbl, &pCard8);
10453458e6c2Smrg                    PutTableType0Card8(pCorrection->pGreenTbl, &pCard8);
10463458e6c2Smrg                    PutTableType0Card8(pCorrection->pBlueTbl, &pCard8);
10473458e6c2Smrg                }
10483458e6c2Smrg                else {
10493458e6c2Smrg                    PutTableType1Card8(pCorrection->pRedTbl, &pCard8);
10503458e6c2Smrg                    PutTableType1Card8(pCorrection->pGreenTbl, &pCard8);
10513458e6c2Smrg                    PutTableType1Card8(pCorrection->pBlueTbl, &pCard8);
10523458e6c2Smrg                }
10533458e6c2Smrg                XChangeProperty(pDpy, root, CorrectAtom, XA_INTEGER, 8,
10543458e6c2Smrg                                i ? PropModeAppend : PropModeReplace,
10553458e6c2Smrg                                (unsigned char *) pCard8Array, total);
10563458e6c2Smrg                free(pCard8Array);
10573458e6c2Smrg                break;
10583458e6c2Smrg            case 16:
10593458e6c2Smrg                total = 7 +     /* visualID, type, and 3 lengths */
10603458e6c2Smrg                    (pCorrection->pRedTbl->nEntries *
10613458e6c2Smrg                     (pCorrection->tableType == 0 ? 2 : 1)) +
10623458e6c2Smrg                    (pCorrection->pGreenTbl->nEntries *
10633458e6c2Smrg                     (pCorrection->tableType == 0 ? 2 : 1)) +
10643458e6c2Smrg                    (pCorrection->pBlueTbl->nEntries *
10653458e6c2Smrg                     (pCorrection->tableType == 0 ? 2 : 1));
10663458e6c2Smrg                pCard16 = pCard16Array = calloc(total, sizeof(unsigned short));
10673458e6c2Smrg                if (pCard16 == NULL) {
10683458e6c2Smrg                    fprintf(stderr, "Unable allocate array of ints\n");
10693458e6c2Smrg                    return (0);
10703458e6c2Smrg                }
10713458e6c2Smrg                *pCard16++ = (pCorrection->visual_info.visualid >> 16) & 0xFFFF;
10723458e6c2Smrg                *pCard16++ = (pCorrection->visual_info.visualid) & 0xFFFF;
10733458e6c2Smrg                *pCard16++ = pCorrection->tableType;    /* type = 0 */
10743458e6c2Smrg                *pCard16++ = 3; /* number of tables = 3 */
10753458e6c2Smrg                if (pCorrection->tableType == 0) {
10763458e6c2Smrg                    PutTableType0Card16(pCorrection->pRedTbl, &pCard16);
10773458e6c2Smrg                    PutTableType0Card16(pCorrection->pGreenTbl, &pCard16);
10783458e6c2Smrg                    PutTableType0Card16(pCorrection->pBlueTbl, &pCard16);
10793458e6c2Smrg                }
10803458e6c2Smrg                else {
10813458e6c2Smrg                    PutTableType1Card16(pCorrection->pRedTbl, &pCard16);
10823458e6c2Smrg                    PutTableType1Card16(pCorrection->pGreenTbl, &pCard16);
10833458e6c2Smrg                    PutTableType1Card16(pCorrection->pBlueTbl, &pCard16);
10843458e6c2Smrg                }
10853458e6c2Smrg                XChangeProperty(pDpy, root, CorrectAtom, XA_INTEGER, 16,
10863458e6c2Smrg                                i ? PropModeAppend : PropModeReplace,
10873458e6c2Smrg                                (unsigned char *) pCard16Array, total);
10883458e6c2Smrg                free(pCard16Array);
10893458e6c2Smrg                break;
10903458e6c2Smrg            case 32:
10913458e6c2Smrg                total = 6 +     /* visualID, type, and 3 lengths */
10923458e6c2Smrg                    (pCorrection->pRedTbl->nEntries *
10933458e6c2Smrg                     (pCorrection->tableType == 0 ? 2 : 1)) +
10943458e6c2Smrg                    (pCorrection->pGreenTbl->nEntries *
10953458e6c2Smrg                     (pCorrection->tableType == 0 ? 2 : 1)) +
10963458e6c2Smrg                    (pCorrection->pBlueTbl->nEntries *
10973458e6c2Smrg                     (pCorrection->tableType == 0 ? 2 : 1));
10983458e6c2Smrg                pCard32 = pCard32Array = calloc(total, sizeof(unsigned long));
10993458e6c2Smrg                if (pCard32 == NULL) {
11003458e6c2Smrg                    fprintf(stderr, "Unable allocate array of ints\n");
11013458e6c2Smrg                    return (0);
11023458e6c2Smrg                }
11033458e6c2Smrg                *pCard32++ = pCorrection->visual_info.visualid;
11043458e6c2Smrg                *pCard32++ = pCorrection->tableType;    /* type */
11053458e6c2Smrg                *pCard32++ = 3; /* number of tables = 3 */
11063458e6c2Smrg                if (pCorrection->tableType == 0) {
11073458e6c2Smrg                    PutTableType0Card32(pCorrection->pRedTbl, &pCard32);
11083458e6c2Smrg                    PutTableType0Card32(pCorrection->pGreenTbl, &pCard32);
11093458e6c2Smrg                    PutTableType0Card32(pCorrection->pBlueTbl, &pCard32);
11103458e6c2Smrg                }
11113458e6c2Smrg                else {
11123458e6c2Smrg                    PutTableType1Card32(pCorrection->pRedTbl, &pCard32);
11133458e6c2Smrg                    PutTableType1Card32(pCorrection->pGreenTbl, &pCard32);
11143458e6c2Smrg                    PutTableType1Card32(pCorrection->pBlueTbl, &pCard32);
11153458e6c2Smrg                }
11163458e6c2Smrg                XChangeProperty(pDpy, root, CorrectAtom, XA_INTEGER, 32,
11173458e6c2Smrg                                i ? PropModeAppend : PropModeReplace,
11183458e6c2Smrg                                (unsigned char *) pCard32Array, total);
11193458e6c2Smrg                free(pCard32Array);
11203458e6c2Smrg                break;
11213458e6c2Smrg            default:
11223458e6c2Smrg                if (pCorrection->visual_info.visualid) {
11233458e6c2Smrg                    fprintf(stderr,
11243458e6c2Smrg                            "RGB Correction for visualid %ld: Invalid property format\n",
11253458e6c2Smrg                            pCorrection->visual_info.visualid);
11263458e6c2Smrg                }
11273458e6c2Smrg                else {
11283458e6c2Smrg                    fprintf(stderr,
11293458e6c2Smrg                            "Global RGB Correction: Invalid property format\n");
11303458e6c2Smrg                }
11313458e6c2Smrg                return (0);
11323458e6c2Smrg            }
11333458e6c2Smrg        }
11342c7c4e3dSmrg    }
11352c7c4e3dSmrg
11362c7c4e3dSmrg    return (1);
11372c7c4e3dSmrg}
11382c7c4e3dSmrg
11392c7c4e3dSmrg#ifdef GRAY
11402c7c4e3dSmrg
11412c7c4e3dSmrgstatic int
11422becc446SmrgLoadDataGray(Display *pDpy, window root, int tableType,
11433458e6c2Smrg             LINEAR_RGB_SCCData *pScreenData, int targetFormat)
11442c7c4e3dSmrg{
11453458e6c2Smrg    int nLevels;
11463458e6c2Smrg    unsigned char *pCard8;
11473458e6c2Smrg    unsigned char *pCard8Array = NULL;
11483458e6c2Smrg    unsigned short *pCard16;
11493458e6c2Smrg    unsigned short *pCard16Array = NULL;
11503458e6c2Smrg    unsigned long *pCard32;
11513458e6c2Smrg    unsigned long *pCard32Array = NULL;
11523458e6c2Smrg    unsigned long Card32Array[18];
1153c1e8faa6Smrg    Atom MatricesAtom, CorrectAtom;
11542c7c4e3dSmrg    XcmsFloat *pValue;
11552c7c4e3dSmrg    int total;
11562c7c4e3dSmrg
11572c7c4e3dSmrg    /* Now store the XDCCC_SCREENWHITEPT */
11582c7c4e3dSmrg    pCard32 = Card32Array;
11593458e6c2Smrg    pValue = (XcmsFloat *) pScreenData->XYZtoRGBmatrix;
1160c1e8faa6Smrg    for (int count = 0; count < 3; count++) {
11613458e6c2Smrg        *pCard32++ = (unsigned long) (*pValue++ * (XcmsFloat) XDCCC_NUMBER);
11622c7c4e3dSmrg    }
11633458e6c2Smrg    MatricesAtom = XInternAtom(pDpy, XDCCC_SCREENWHITEPT_ATOM_NAME, False);
11643458e6c2Smrg    XChangeProperty(pDpy, root, MatricesAtom, XA_INTEGER, 32,
11653458e6c2Smrg                    PropModeReplace, (unsigned char *) Card32Array, 3);
11662c7c4e3dSmrg
11672c7c4e3dSmrg    /* Now store the XDCCC_GRAY_CORRECTION */
11683458e6c2Smrg    CorrectAtom = XInternAtom(pDpy, XDCCC_GRAY_CORRECT_ATOM_NAME, False);
11692c7c4e3dSmrg
11702c7c4e3dSmrg    if (tableType == CORR_TYPE_NONE) {
1171c1e8faa6Smrg        unsigned char *ret_prop;
1172c1e8faa6Smrg        Atom ret_atom;
1173c1e8faa6Smrg        int ret_format;
1174c1e8faa6Smrg        unsigned long ret_len, ret_after;
1175c1e8faa6Smrg
11763458e6c2Smrg        XGetWindowProperty(pDpy, root, CorrectAtom,
11773458e6c2Smrg                           0, 5, False, XA_INTEGER,
11783458e6c2Smrg                           &ret_atom, &ret_format, &ret_len, &ret_after,
11793458e6c2Smrg                           &ret_prop);
11803458e6c2Smrg        if (ret_format != 0) {
11813458e6c2Smrg            XDeleteProperty(pDpy, root, CorrectAtom);
11823458e6c2Smrg            XFree(ret_prop);
11833458e6c2Smrg        }
11843458e6c2Smrg        return (1);
11852c7c4e3dSmrg    }
11862c7c4e3dSmrg    nLevels = pScreenData->pRedTbl->nEntries;
11872c7c4e3dSmrg    if (nLevels < 2) {
11883458e6c2Smrg        fprintf(stderr, "Illegal number of entries in table\n");
11893458e6c2Smrg        return (0);
11902c7c4e3dSmrg    }
11912c7c4e3dSmrg    switch (targetFormat) {
11923458e6c2Smrg    case 8:
11933458e6c2Smrg        total = 6               /* visualID, type, length */
11943458e6c2Smrg            + (nLevels * (tableType == 0 ? 2 : 1));
11953458e6c2Smrg        pCard8 = pCard8Array = calloc(total, sizeof(unsigned char));
11963458e6c2Smrg        if (pCard8 == NULL) {
11973458e6c2Smrg            fprintf(stderr, "Unable allocate array of Card8\n");
11983458e6c2Smrg            return (0);
11993458e6c2Smrg        }
12003458e6c2Smrg        *pCard8++ = 0;          /* VisualID = 0 */
12013458e6c2Smrg        *pCard8++ = 0;          /* VisualID = 0 */
12023458e6c2Smrg        *pCard8++ = 0;          /* VisualID = 0 */
12033458e6c2Smrg        *pCard8++ = 0;          /* VisualID = 0 */
12043458e6c2Smrg        *pCard8++ = tableType;  /* type */
12053458e6c2Smrg        if (tableType == 0) {
12063458e6c2Smrg            PutTableType0Card8(pScreenData->pRedTbl, &pCard8);
12073458e6c2Smrg        }
12083458e6c2Smrg        else {                  /* tableType == 1 */
12093458e6c2Smrg            PutTableType1Card8(pScreenData->pRedTbl, &pCard8);
12103458e6c2Smrg        }
12113458e6c2Smrg        XChangeProperty(pDpy, root, CorrectAtom, XA_INTEGER, 8,
12123458e6c2Smrg                        PropModeReplace, (unsigned char *) pCard8Array, total);
12133458e6c2Smrg        free(pCard8Array);
12143458e6c2Smrg        break;
12153458e6c2Smrg    case 16:
12163458e6c2Smrg        total = 4               /* visualID, type, length */
12173458e6c2Smrg            + (nLevels * (tableType == 0 ? 2 : 1));
12183458e6c2Smrg        pCard16 = pCard16Array = calloc(total, sizeof(unsigned short));
12193458e6c2Smrg        if (pCard16 == NULL) {
12203458e6c2Smrg            fprintf(stderr, "Unable allocate array of Card16\n");
12213458e6c2Smrg            return (0);
12223458e6c2Smrg        }
12233458e6c2Smrg        *pCard16++ = 0;         /* VisualID = 0 */
12243458e6c2Smrg        *pCard16++ = 0;         /* VisualID = 0 */
12253458e6c2Smrg        *pCard16++ = tableType; /* type */
12263458e6c2Smrg        if (tableType == 0) {
12273458e6c2Smrg            PutTableType0Card16(pScreenData->pRedTbl, &pCard16);
12283458e6c2Smrg        }
12293458e6c2Smrg        else {                  /* tableType == 1 */
12303458e6c2Smrg            PutTableType1Card16(pScreenData->pRedTbl, &pCard16);
12313458e6c2Smrg        }
12323458e6c2Smrg        XChangeProperty(pDpy, root, CorrectAtom, XA_INTEGER, 16,
12333458e6c2Smrg                        PropModeReplace, (unsigned char *) pCard16Array, total);
12343458e6c2Smrg        free(pCard16Array);
12353458e6c2Smrg        break;
12363458e6c2Smrg    case 32:
12373458e6c2Smrg        total = 3               /* visualID, type, length */
12383458e6c2Smrg            + (nLevels * (tableType == 0 ? 2 : 1));
12393458e6c2Smrg        pCard32 = pCard32Array = calloc(total, sizeof(unsigned long));
12403458e6c2Smrg        if ((pCard32 == NULL) {
12413458e6c2Smrg            fprintf(stderr, "Unable allocate array of Card32\n");
12423458e6c2Smrg            return (0);
12433458e6c2Smrg        }
12443458e6c2Smrg        *pCard32++ = 0;         /* VisualID = 0 */
12453458e6c2Smrg        *pCard32++ = tableType; /* type */
12463458e6c2Smrg        if (tableType == 0) {
12473458e6c2Smrg            PutTableType0Card32(pScreenData->pRedTbl, &pCard32);
12483458e6c2Smrg        }
12493458e6c2Smrg        else {                  /* tableType == 1 */
12503458e6c2Smrg            PutTableType1Card32(pScreenData->pRedTbl, &pCard32);
12513458e6c2Smrg        }
12523458e6c2Smrg        XChangeProperty(pDpy, root, CorrectAtom, XA_INTEGER, 32,
12533458e6c2Smrg                        PropModeReplace, (unsigned char *) pCard32Array, total);
12543458e6c2Smrg        free(pCard32Array);
12553458e6c2Smrg        break;
12563458e6c2Smrg    default:
12573458e6c2Smrg        fprintf(stderr, "Invalid property format\n");
12583458e6c2Smrg        return (0);
12592c7c4e3dSmrg    }
12602c7c4e3dSmrg    return (1);
12612c7c4e3dSmrg}
12623458e6c2Smrg#endif                          /* GRAY */
12632c7c4e3dSmrg
12642c7c4e3dSmrgstatic void
12653458e6c2SmrgPrintVisualOptions(XDCCC_Correction * pCorrection)
12662c7c4e3dSmrg{
12672c7c4e3dSmrg    if (pCorrection->visual_info_mask & VisualIDMask) {
12683458e6c2Smrg        fprintf(stderr, "\t%s:0x%lx\n",
12693458e6c2Smrg                DefineToStr(VisualOptKeyTbl, KEY_VISUALID),
12703458e6c2Smrg                (unsigned long) pCorrection->visual_info.visualid);
12712c7c4e3dSmrg    }
12722c7c4e3dSmrg    if (pCorrection->visual_info_mask & VisualDepthMask) {
12733458e6c2Smrg        fprintf(stderr, "\t%s:%d\n",
12743458e6c2Smrg                DefineToStr(VisualOptKeyTbl, KEY_DEPTH),
12753458e6c2Smrg                pCorrection->visual_info.depth);
12762c7c4e3dSmrg    }
12772c7c4e3dSmrg    if (pCorrection->visual_info_mask & VisualClassMask) {
12783458e6c2Smrg        fprintf(stderr, "\t%s:%s\n",
12793458e6c2Smrg                DefineToStr(VisualOptKeyTbl, KEY_CLASS),
12803458e6c2Smrg                DefineToStr(VisualClassTbl, pCorrection->visual_info.class));
12812c7c4e3dSmrg    }
12822c7c4e3dSmrg    if (pCorrection->visual_info_mask & VisualRedMaskMask) {
12833458e6c2Smrg        fprintf(stderr, "\t%s:0x%lx\n",
12843458e6c2Smrg                DefineToStr(VisualOptKeyTbl, KEY_RED_MASK),
12853458e6c2Smrg                pCorrection->visual_info.red_mask);
12862c7c4e3dSmrg    }
12872c7c4e3dSmrg    if (pCorrection->visual_info_mask & VisualGreenMaskMask) {
12883458e6c2Smrg        fprintf(stderr, "\t%s:0x%lx\n",
12893458e6c2Smrg                DefineToStr(VisualOptKeyTbl, KEY_GREEN_MASK),
12903458e6c2Smrg                pCorrection->visual_info.green_mask);
12912c7c4e3dSmrg    }
12922c7c4e3dSmrg    if (pCorrection->visual_info_mask & VisualBlueMaskMask) {
12933458e6c2Smrg        fprintf(stderr, "\t%s:0x%lx\n",
12943458e6c2Smrg                DefineToStr(VisualOptKeyTbl, KEY_BLUE_MASK),
12953458e6c2Smrg                pCorrection->visual_info.blue_mask);
12962c7c4e3dSmrg    }
12972c7c4e3dSmrg    if (pCorrection->visual_info_mask & VisualColormapSizeMask) {
12983458e6c2Smrg        fprintf(stderr, "\t%s:0x%x\n",
12993458e6c2Smrg                DefineToStr(VisualOptKeyTbl, KEY_COLORMAP_SIZE),
13003458e6c2Smrg                pCorrection->visual_info.colormap_size);
13012c7c4e3dSmrg    }
13022c7c4e3dSmrg    if (pCorrection->visual_info_mask & VisualBitsPerRGBMask) {
13033458e6c2Smrg        fprintf(stderr, "\t%s:%d\n",
13043458e6c2Smrg                DefineToStr(VisualOptKeyTbl, KEY_BITS_PER_RGB),
13053458e6c2Smrg                pCorrection->visual_info.bits_per_rgb);
13062c7c4e3dSmrg    }
13072c7c4e3dSmrg}
13082c7c4e3dSmrg
13092c7c4e3dSmrgstatic int
13102c7c4e3dSmrgParseVisualOptions(Display *pDpy, XDCCC_Correction *pCorrection, char *pbuf)
13112c7c4e3dSmrg{
13122c7c4e3dSmrg    char *key;
13132c7c4e3dSmrg    XVisualInfo *vinfo;
13142c7c4e3dSmrg    int n_matches;
1315c1e8faa6Smrg    const char *delims = DATA_DELIMS ":";
13162c7c4e3dSmrg
13172c7c4e3dSmrg    pCorrection->visual_info_mask = VisualNoMask;
13182c7c4e3dSmrg    key = strtok(pbuf, delims);
13192c7c4e3dSmrg    do {
13203458e6c2Smrg        long tmp;
1321c1e8faa6Smrg        char *value = strtok(NULL, delims);
13223458e6c2Smrg
13233458e6c2Smrg        if ((key == NULL) || (value == NULL)) {
13243458e6c2Smrg            return (0);
13253458e6c2Smrg        }
13263458e6c2Smrg        switch (StrToDefine(VisualOptKeyTbl, key)) {
13273458e6c2Smrg        case KEY_VISUALID:
13283458e6c2Smrg            if (sscanf(value, "%li", &tmp) != 1) {
13293458e6c2Smrg                fprintf(stderr,
13303458e6c2Smrg                        "Line %d: invalid VisualID specified, %s\n",
13313458e6c2Smrg                        linenum, value);
13323458e6c2Smrg                return (0);
13333458e6c2Smrg            }
13343458e6c2Smrg            else
13353458e6c2Smrg                pCorrection->visual_info.visualid = tmp;
13363458e6c2Smrg            pCorrection->visual_info_mask |= VisualIDMask;
13373458e6c2Smrg            break;
13383458e6c2Smrg        case KEY_DEPTH:
13393458e6c2Smrg            if (sscanf(value, "%i", &pCorrection->visual_info.depth) != 1) {
13403458e6c2Smrg                fprintf(stderr,
13413458e6c2Smrg                        "Line %d: invalid depth specified, %s\n",
13423458e6c2Smrg                        linenum, value);
13433458e6c2Smrg                return (0);
13443458e6c2Smrg            }
13453458e6c2Smrg            pCorrection->visual_info_mask |= VisualDepthMask;
13463458e6c2Smrg            break;
13473458e6c2Smrg        case KEY_CLASS:
13483458e6c2Smrg            switch (pCorrection->visual_info.class =
13493458e6c2Smrg                    StrToDefine(VisualClassTbl, value)) {
13503458e6c2Smrg            case StaticColor:
13513458e6c2Smrg                break;
13523458e6c2Smrg            case PseudoColor:
13533458e6c2Smrg                break;
13543458e6c2Smrg            case TrueColor:
13553458e6c2Smrg                break;
13563458e6c2Smrg            case DirectColor:
13573458e6c2Smrg                break;
13583458e6c2Smrg            case StaticGray:
13593458e6c2Smrg                /* invalid, fall through */
13603458e6c2Smrg            case GrayScale:
13613458e6c2Smrg                /* invalid, fall through */
13623458e6c2Smrg            default:
13633458e6c2Smrg                fprintf(stderr,
13643458e6c2Smrg                        "Line %d: invalid Visual Class -- %s\n",
13653458e6c2Smrg                        linenum, value);
13663458e6c2Smrg                return (0);
13673458e6c2Smrg            }
13683458e6c2Smrg            pCorrection->visual_info_mask |= VisualClassMask;
13693458e6c2Smrg            break;
13703458e6c2Smrg        case KEY_RED_MASK:
13713458e6c2Smrg            if (sscanf(value, "%li", &tmp) != 1) {
13723458e6c2Smrg                fprintf(stderr,
13733458e6c2Smrg                        "Line %d: invalid red_mask specified -- %s\n",
13743458e6c2Smrg                        linenum, value);
13753458e6c2Smrg                return (0);
13763458e6c2Smrg            }
13773458e6c2Smrg            else
13783458e6c2Smrg                pCorrection->visual_info.red_mask = tmp;
13793458e6c2Smrg            pCorrection->visual_info_mask |= VisualRedMaskMask;
13803458e6c2Smrg            break;
13813458e6c2Smrg        case KEY_GREEN_MASK:
13823458e6c2Smrg            if (sscanf(value, "%li", &tmp) != 1) {
13833458e6c2Smrg                fprintf(stderr,
13843458e6c2Smrg                        "Line %d: invalid green_mask specified -- %s\n",
13853458e6c2Smrg                        linenum, value);
13863458e6c2Smrg                return (0);
13873458e6c2Smrg            }
13883458e6c2Smrg            else
13893458e6c2Smrg                pCorrection->visual_info.green_mask = tmp;
13903458e6c2Smrg            pCorrection->visual_info_mask |= VisualGreenMaskMask;
13913458e6c2Smrg            break;
13923458e6c2Smrg        case KEY_BLUE_MASK:
13933458e6c2Smrg            if (sscanf(value, "%li", &tmp) != 1) {
13943458e6c2Smrg                fprintf(stderr,
13953458e6c2Smrg                        "Line %d: invalid blue_mask specified -- %s\n",
13963458e6c2Smrg                        linenum, value);
13973458e6c2Smrg                return (0);
13983458e6c2Smrg            }
13993458e6c2Smrg            else
14003458e6c2Smrg                pCorrection->visual_info.blue_mask = tmp;
14013458e6c2Smrg            pCorrection->visual_info_mask |= VisualBlueMaskMask;
14023458e6c2Smrg            break;
14033458e6c2Smrg        case KEY_COLORMAP_SIZE:
14043458e6c2Smrg            if (sscanf(value, "%i", &pCorrection->visual_info.colormap_size) !=
14053458e6c2Smrg                1) {
14063458e6c2Smrg                fprintf(stderr,
14073458e6c2Smrg                        "Line %d: invalid colormap_size specified -- %s\n",
14083458e6c2Smrg                        linenum, value);
14093458e6c2Smrg                return (0);
14103458e6c2Smrg            }
14113458e6c2Smrg            pCorrection->visual_info_mask |= VisualColormapSizeMask;
14123458e6c2Smrg            break;
14133458e6c2Smrg        case KEY_BITS_PER_RGB:
14143458e6c2Smrg            if (sscanf(value, "%i", &pCorrection->visual_info.bits_per_rgb) !=
14153458e6c2Smrg                1) {
14163458e6c2Smrg                fprintf(stderr,
14173458e6c2Smrg                        "Line %d: invalid bits_per_rgb specified -- %s\n",
14183458e6c2Smrg                        linenum, value);
14193458e6c2Smrg                return (0);
14203458e6c2Smrg            }
14213458e6c2Smrg            pCorrection->visual_info_mask |= VisualBitsPerRGBMask;
14223458e6c2Smrg            break;
14233458e6c2Smrg        default:
14243458e6c2Smrg            fprintf(stderr, "Line %d: invalid keyword %s\n", linenum, key);
14253458e6c2Smrg            return (0);
14263458e6c2Smrg        }
14273458e6c2Smrg        key = strtok(NULL, delims);
14283458e6c2Smrg    } while (key != NULL);
14292c7c4e3dSmrg
14302c7c4e3dSmrg    vinfo = XGetVisualInfo(pDpy,
14313458e6c2Smrg                           pCorrection->visual_info_mask,
14323458e6c2Smrg                           &pCorrection->visual_info, &n_matches);
14332c7c4e3dSmrg
14342c7c4e3dSmrg    if (!n_matches) {
14353458e6c2Smrg        fprintf(stderr, "Line %d: Cannot find visual matching ...\n", linenum);
14363458e6c2Smrg        PrintVisualOptions(pCorrection);
14373458e6c2Smrg        fprintf(stderr, "\n");
14383458e6c2Smrg        return (0);
14392c7c4e3dSmrg    }
14402c7c4e3dSmrg    if (n_matches > 1) {
14413458e6c2Smrg        fprintf(stderr, "Line %d: Found more than one visual matching ...\n",
14423458e6c2Smrg                linenum);
14433458e6c2Smrg        PrintVisualOptions(pCorrection);
14443458e6c2Smrg        fprintf(stderr, "    Using VisualId 0x%lx\n",
14453458e6c2Smrg                (unsigned long) vinfo->visualid);
14462c7c4e3dSmrg    }
14473458e6c2Smrg    memcpy(&pCorrection->visual_info, vinfo, sizeof(XVisualInfo));
14482c7c4e3dSmrg    return (1);
14492becc446Smrg}
14502c7c4e3dSmrg
14512c7c4e3dSmrg/************************************************************************
14522c7c4e3dSmrg *									*
14532c7c4e3dSmrg *			 PUBLIC ROUTINES				*
14542c7c4e3dSmrg *									*
14552c7c4e3dSmrg ************************************************************************/
14562c7c4e3dSmrg
14572c7c4e3dSmrg/*
14582c7c4e3dSmrg *	NAME
14592c7c4e3dSmrg *		LoadSCCData - Read and store the screen data
14602c7c4e3dSmrg *
14612c7c4e3dSmrg *	SYNOPSIS
14622c7c4e3dSmrg */
14632c7c4e3dSmrgint
14642becc446SmrgLoadSCCData(Display *pDpy, int screenNumber, const char *filename,
14652becc446Smrg            int targetFormat)
14662c7c4e3dSmrg
14672c7c4e3dSmrg/*
14682c7c4e3dSmrg *	DESCRIPTION
14692c7c4e3dSmrg *		Using the X Device Color Characterization Convention (XDCCC)
14702c7c4e3dSmrg *		read the screen data and store it on the root window of the
14712c7c4e3dSmrg *		screen.
14722c7c4e3dSmrg *
14732c7c4e3dSmrg *	RETURNS
14742c7c4e3dSmrg *		Returns 0 if failed; otherwise 1.
14752c7c4e3dSmrg *
14762c7c4e3dSmrg */
14772becc446Smrg{
14782c7c4e3dSmrg    FILE *stream;
14792c7c4e3dSmrg    char *pStr;
14802c7c4e3dSmrg    char buf[BUFSIZ];
14812c7c4e3dSmrg    char *keyword, *token1, *token2, *token3;
14823458e6c2Smrg    int state = 0;
14832c7c4e3dSmrg    int VisualFlag = -2;
14842c7c4e3dSmrg    Window root;
14852c7c4e3dSmrg    XDCCC_Matrix matrix;
14863458e6c2Smrg    XDCCC_Correction *CorrectionTail = NULL;
14873458e6c2Smrg    XDCCC_Correction *CorrectionHead = NULL;
14883458e6c2Smrg    XDCCC_Correction *pCurrent;
14892c7c4e3dSmrg
14902c7c4e3dSmrg    if (screenNumber < 0) {
14913458e6c2Smrg        fprintf(stderr, "Invalid Screen Number %d\n", screenNumber);
14923458e6c2Smrg        return (0);
14932c7c4e3dSmrg    }
14942c7c4e3dSmrg    root = RootWindow(pDpy, screenNumber);
14952c7c4e3dSmrg
14962c7c4e3dSmrg    if (!root) {
14973458e6c2Smrg        /* if no root window is available then return an error */
14983458e6c2Smrg        fprintf(stderr, "Could not open root window supplied.\n ");
14993458e6c2Smrg        return (0);
15002c7c4e3dSmrg    }
15012c7c4e3dSmrg    /*
15022c7c4e3dSmrg     * Open the file, determine its size, then read it into memory.
15032c7c4e3dSmrg     */
15042c7c4e3dSmrg    if (filename == NULL) {
15053458e6c2Smrg        stream = stdin;
15063458e6c2Smrg        filename = "stdin";
15073458e6c2Smrg    }
15083458e6c2Smrg    else if ((stream = fopen(filename, "r")) == NULL) {
15093458e6c2Smrg        fprintf(stderr, "Could not open file %s.\n", filename);
15103458e6c2Smrg        return (0);
15112c7c4e3dSmrg    }
15122c7c4e3dSmrg
15132c7c4e3dSmrg    /*
15142becc446Smrg     * Advance to starting keyword
15152c7c4e3dSmrg     * Anything before this keyword is just treated as comments.
15162c7c4e3dSmrg     */
15172c7c4e3dSmrg
15183458e6c2Smrg    while ((pStr = nextline(buf, BUFSIZ, stream)) != NULL) {
15193458e6c2Smrg        keyword = strtok(buf, DATA_DELIMS);
15203458e6c2Smrg        if (keyword != NULL &&
15213458e6c2Smrg            (strcmp(keyword, SC_BEGIN_KEYWORD) == 0)) {
15223458e6c2Smrg            break;
15233458e6c2Smrg        }                       /* else ignore the line */
15242c7c4e3dSmrg    }
15252c7c4e3dSmrg
15262c7c4e3dSmrg    if (pStr == NULL) {
15273458e6c2Smrg        fprintf(stderr, "File %s is missing %s\n", filename, SC_BEGIN_KEYWORD);
15283458e6c2Smrg        closeS(stream, CorrectionHead);
15293458e6c2Smrg        return (0);
15302c7c4e3dSmrg    }
15312c7c4e3dSmrg
15323458e6c2Smrg    token1 = strtok(NULL, DATA_DELIMS);
15333458e6c2Smrg    if (token1 && (strcmp(token1, TXT_FORMAT_VERSION) != 0) &&
15343458e6c2Smrg        (strcmp(token1, "0.3") != 0)) {
15353458e6c2Smrg        fprintf(stderr,
15363458e6c2Smrg                "Screen data format version mismatch in file %s-- expected %s, found %s\n",
15373458e6c2Smrg                filename, TXT_FORMAT_VERSION, token1);
15383458e6c2Smrg        closeS(stream, CorrectionHead);
15393458e6c2Smrg        return (0);
15402c7c4e3dSmrg    }
15412c7c4e3dSmrg
15422c7c4e3dSmrg    while ((pStr = nextline(buf, BUFSIZ, stream)) != NULL) {
15433458e6c2Smrg        keyword = strtok(buf, DATA_DELIMS);
15443458e6c2Smrg        if (keyword != NULL) {
15453458e6c2Smrg            switch (SCKeyOf(keyword)) {
15463458e6c2Smrg            case COMMENT:
15473458e6c2Smrg            case NAME:
15483458e6c2Smrg            case PART_NUMBER:
15493458e6c2Smrg            case MODEL:
15503458e6c2Smrg            case SERIAL_NUMBER:
15513458e6c2Smrg            case REVISION:
15523458e6c2Smrg                /* Do nothing */
15533458e6c2Smrg                break;
15543458e6c2Smrg            case SCREEN_CLASS:
15553458e6c2Smrg                token1 = strtok(NULL, DATA_DELIMS);
15563458e6c2Smrg                token2 = strtok(NULL, DATA_DELIMS);
15573458e6c2Smrg                if ((token1 == NULL)
15583458e6c2Smrg                    || ((VisualFlag = SCScrnClassOf(token1)) == -1)) {
15593458e6c2Smrg                    closeS(stream, CorrectionHead);
15603458e6c2Smrg                    return (0);
15613458e6c2Smrg                }
15623458e6c2Smrg                /*include code to handle screen number input */
15633458e6c2Smrg                if (token2 != NULL) {
15643458e6c2Smrg                    screenNumber = atoi(token2);
15653458e6c2Smrg
15663458e6c2Smrg                    if (screenNumber < 0) {
15673458e6c2Smrg                        fprintf(stderr, "Invalid Screen Number %d\n",
15683458e6c2Smrg                                screenNumber);
15693458e6c2Smrg                    }
15703458e6c2Smrg                    else {
15713458e6c2Smrg                        root = RootWindow(pDpy, screenNumber);
15723458e6c2Smrg                        if (!root) {
15733458e6c2Smrg                            /* if no root window is available then return an error */
15743458e6c2Smrg                            fprintf(stderr,
15753458e6c2Smrg                                    "Could not open root window supplied.\n ");
15763458e6c2Smrg                            return (0);
15773458e6c2Smrg                        }
15783458e6c2Smrg                    }
15793458e6c2Smrg                }
15803458e6c2Smrg                break;
15813458e6c2Smrg            case COLORIMETRIC_BEGIN:
15823458e6c2Smrg                if (VisualFlag == -2) {
15833458e6c2Smrg                    closeS(stream, CorrectionHead);
15843458e6c2Smrg                    return (0);
15853458e6c2Smrg                }
15863458e6c2Smrg                if (!ProcessColorimetric(stream, &matrix, VisualFlag)) {
15873458e6c2Smrg                    closeS(stream, CorrectionHead);
15883458e6c2Smrg                    return (0);
15893458e6c2Smrg                }
15903458e6c2Smrg                state |= 0x02;
15913458e6c2Smrg                break;
15923458e6c2Smrg            case IPROFILE_BEGIN:
15933458e6c2Smrg                if (VisualFlag == -2) {
15943458e6c2Smrg                    closeS(stream, CorrectionHead);
15953458e6c2Smrg                    return (0);
15963458e6c2Smrg                }
15973458e6c2Smrg                token1 = strtok(NULL, DATA_DELIMS);
15983458e6c2Smrg                token2 = strtok(NULL, DATA_DELIMS);
15993458e6c2Smrg                if ((token1 == NULL) || (token2 == NULL)) {
16003458e6c2Smrg                    fprintf(stderr,
16013458e6c2Smrg                            "Line %d: Intensity profile missing TableType and/or nTables.",
16023458e6c2Smrg                            linenum);
16033458e6c2Smrg                    closeS(stream, CorrectionHead);
16043458e6c2Smrg                    return (0);
16053458e6c2Smrg                }
16063458e6c2Smrg
16073458e6c2Smrg                pCurrent = calloc(1, sizeof(XDCCC_Correction));
16083458e6c2Smrg                if (pCurrent  == NULL) {
16093458e6c2Smrg                    fprintf(stderr,
16103458e6c2Smrg                            "Line %d: Could not allocate memory for intensity profile.",
16113458e6c2Smrg                            linenum);
16123458e6c2Smrg                    closeS(stream, CorrectionHead);
16133458e6c2Smrg                    return (0);
16143458e6c2Smrg                }
16153458e6c2Smrg
16163458e6c2Smrg                if (sscanf(token1, "%d", &pCurrent->tableType) != 1 ||
16173458e6c2Smrg                    (pCurrent->tableType < 0 || pCurrent->tableType > 1)) {
16183458e6c2Smrg                    fprintf(stderr,
16193458e6c2Smrg                            "Line %d: invalid table type specified -- %s\n",
16203458e6c2Smrg                            linenum, buf);
16213458e6c2Smrg                    closeS(stream, CorrectionHead);
16223458e6c2Smrg                    free(pCurrent);
16233458e6c2Smrg                    return (0);
16243458e6c2Smrg                }
16253458e6c2Smrg
16263458e6c2Smrg                if ((VisualFlag == VIDEO_RGB) && (token2 == NULL)) {
16273458e6c2Smrg                    fprintf(stderr,
16283458e6c2Smrg                            "Line %d: invalid number of tables specified -- %s\n",
16293458e6c2Smrg                            linenum, buf);
16303458e6c2Smrg                    closeS(stream, CorrectionHead);
16313458e6c2Smrg                    free(pCurrent);
16323458e6c2Smrg                    return (0);
16333458e6c2Smrg                }
16343458e6c2Smrg
16353458e6c2Smrg                if (VisualFlag == VIDEO_RGB) {
16363458e6c2Smrg                    if (sscanf(token2, "%d", &pCurrent->nTables) != 1 ||
16373458e6c2Smrg                        (pCurrent->nTables != 0 && pCurrent->nTables != 1
16383458e6c2Smrg                         && pCurrent->nTables != 3)) {
16393458e6c2Smrg                        fprintf(stderr,
16403458e6c2Smrg                                "Line %d: invalid number of tables (must be 0, 1, or 3)\n",
16413458e6c2Smrg                                linenum);
16423458e6c2Smrg                        closeS(stream, CorrectionHead);
16433458e6c2Smrg                        free(pCurrent);
16443458e6c2Smrg                        return (0);
16453458e6c2Smrg                    }
16463458e6c2Smrg                }
16473458e6c2Smrg                else {
16483458e6c2Smrg                    pCurrent->nTables = 0;
16493458e6c2Smrg                }
16503458e6c2Smrg
16513458e6c2Smrg                token3 = strtok(NULL, "\n");
16523458e6c2Smrg                if (token3 != NULL) {
16533458e6c2Smrg                    if (!ParseVisualOptions(pDpy, pCurrent, token3)) {
16543458e6c2Smrg                        goto ByPassThisIProfile;
16553458e6c2Smrg                    }
16563458e6c2Smrg                }
16573458e6c2Smrg
16583458e6c2Smrg                switch (pCurrent->nTables) {
16593458e6c2Smrg                case 3:
16603458e6c2Smrg                    pCurrent->pRedTbl = calloc(1, sizeof(IntensityTbl));
16613458e6c2Smrg                    if (pCurrent->pRedTbl == NULL) {
16623458e6c2Smrg                        fprintf(stderr,
16633458e6c2Smrg                                "Line %d: Could not allocate Red Intensity Table\n",
16643458e6c2Smrg                                linenum);
16653458e6c2Smrg                        closeS(stream, CorrectionHead);
16663458e6c2Smrg                        free(pCurrent);
16673458e6c2Smrg                        return (0);
16683458e6c2Smrg                    }
16693458e6c2Smrg                    pCurrent->pGreenTbl = calloc(1, sizeof(IntensityTbl));
16703458e6c2Smrg                    if (pCurrent->pGreenTbl == NULL) {
16713458e6c2Smrg                        fprintf(stderr,
16723458e6c2Smrg                                "Line %d: Could not allocate Green Intensity Table\n",
16733458e6c2Smrg                                linenum);
16743458e6c2Smrg                        closeS(stream, CorrectionHead);
16753458e6c2Smrg                        free(pCurrent->pRedTbl);
16763458e6c2Smrg                        free(pCurrent);
16773458e6c2Smrg                        return (0);
16783458e6c2Smrg                    }
16793458e6c2Smrg                    pCurrent->pBlueTbl = calloc(1, sizeof(IntensityTbl));
16803458e6c2Smrg                    if (pCurrent->pBlueTbl == NULL) {
16813458e6c2Smrg                        fprintf(stderr,
16823458e6c2Smrg                                "Line %d: Could not allocate Blue Intensity Table",
16833458e6c2Smrg                                linenum);
16843458e6c2Smrg                        closeS(stream, CorrectionHead);
16853458e6c2Smrg                        free(pCurrent->pRedTbl);
16863458e6c2Smrg                        free(pCurrent->pGreenTbl);
16873458e6c2Smrg                        free(pCurrent);
16883458e6c2Smrg                        return (0);
16893458e6c2Smrg                    }
16903458e6c2Smrg                    if (!ProcessIProfile(stream, pCurrent)) {
16913458e6c2Smrg                        goto ByPassThisIProfile;
16923458e6c2Smrg                    }
16933458e6c2Smrg                    break;
16943458e6c2Smrg                case 1:
16953458e6c2Smrg                    pCurrent->pRedTbl = calloc(1, sizeof(IntensityTbl));
16963458e6c2Smrg                    if (pCurrent->pRedTbl == NULL) {
16973458e6c2Smrg                        fprintf(stderr,
16983458e6c2Smrg                                "Line %d: Could not allocate Red Intensity Table",
16993458e6c2Smrg                                linenum);
17003458e6c2Smrg                        closeS(stream, CorrectionHead);
17013458e6c2Smrg                        free(pCurrent);
17023458e6c2Smrg                        return (0);
17033458e6c2Smrg                    }
17043458e6c2Smrg                    pCurrent->pGreenTbl = pCurrent->pRedTbl;
17053458e6c2Smrg                    pCurrent->pBlueTbl = pCurrent->pRedTbl;
17063458e6c2Smrg                    if (!ProcessIProfile(stream, pCurrent)) {
17073458e6c2Smrg                        goto ByPassThisIProfile;
17083458e6c2Smrg                    }
17093458e6c2Smrg                    break;
17103458e6c2Smrg                default:
17113458e6c2Smrg                    /* do nothing */
17123458e6c2Smrg                    break;
17133458e6c2Smrg                }
17143458e6c2Smrg
17153458e6c2Smrg                if (CorrectionHead == NULL) {
17163458e6c2Smrg                    CorrectionHead = CorrectionTail = pCurrent;
17173458e6c2Smrg                }
17183458e6c2Smrg                else {
17193458e6c2Smrg                    CorrectionTail->next = pCurrent;
17203458e6c2Smrg                    CorrectionTail = pCurrent;
17213458e6c2Smrg                }
17223458e6c2Smrg                state |= 0x04;
17233458e6c2Smrg                break;
17243458e6c2Smrg ByPassThisIProfile:
17253458e6c2Smrg                /* read till INTENSITY_PROFILE_END */
17263458e6c2Smrg                while ((pStr = nextline(buf, BUFSIZ, stream)) != NULL) {
17273458e6c2Smrg                    keyword = strtok(buf, DATA_DELIMS);
17283458e6c2Smrg                    if (keyword != NULL) {
17293458e6c2Smrg                        switch (SCKeyOf(keyword)) {
17303458e6c2Smrg                        case ITBL_BEGIN:
17313458e6c2Smrg                        case ITBL_END:
17323458e6c2Smrg                        case COMMENT:
17333458e6c2Smrg                        case DATA:
17343458e6c2Smrg                            break;
17353458e6c2Smrg                        case IPROFILE_END:
17363458e6c2Smrg                            goto IProfileProcessed;
17373458e6c2Smrg                        default:
17383458e6c2Smrg                            closeS(stream, CorrectionHead);
17393458e6c2Smrg                            return (0);
17403458e6c2Smrg                        }
17413458e6c2Smrg                    }
17423458e6c2Smrg                }
17433458e6c2Smrg                free(pCurrent);
17443458e6c2Smrg IProfileProcessed:
17453458e6c2Smrg                state |= 0x04;
17463458e6c2Smrg                break;
17473458e6c2Smrg            case SC_END:
17483458e6c2Smrg                if (!(state & 0x02)) {
17493458e6c2Smrg                    fprintf(stderr,
17503458e6c2Smrg                            "File %s is missing Colorimetric data.\n",
17513458e6c2Smrg                            filename);
17523458e6c2Smrg                    closeS(stream, CorrectionHead);
17533458e6c2Smrg                    return (0);
17543458e6c2Smrg                }
17553458e6c2Smrg                if (!(state & 0x04)) {
17563458e6c2Smrg                    fprintf(stderr,
17573458e6c2Smrg                            "File %s is missing Intensity Profile Data.\n",
17583458e6c2Smrg                            filename);
17593458e6c2Smrg                }
17603458e6c2Smrg                if (VisualFlag == VIDEO_RGB) {
17613458e6c2Smrg                    LoadMatrix(pDpy, root, &matrix);
17623458e6c2Smrg                    if (!LoadCorrections(pDpy, root, CorrectionHead,
17633458e6c2Smrg                                         targetFormat)) {
17643458e6c2Smrg                        closeS(stream, CorrectionHead);
17653458e6c2Smrg                        return (0);
17663458e6c2Smrg                    }
17672c7c4e3dSmrg#ifdef GRAY
17683458e6c2Smrg                }
17693458e6c2Smrg                else if (VisualFlag == VIDEO_GRAY) {
17703458e6c2Smrg                    if (!LoadDataGray(pDpy, root,
17713458e6c2Smrg                                      pCurrent->tableType, pScreenData,
17723458e6c2Smrg                                      targetFormat)) {
17733458e6c2Smrg                        closeS(stream, CorrectionHead);
17743458e6c2Smrg                        return (0);
17753458e6c2Smrg                    }
17763458e6c2Smrg#endif                          /* GRAY */
17773458e6c2Smrg                }
17783458e6c2Smrg                else {
17793458e6c2Smrg                    fprintf(stderr, "File %s Visual missing.", filename);
17803458e6c2Smrg                }
17813458e6c2Smrg                closeS(stream, CorrectionHead);
17823458e6c2Smrg                return (1);
17833458e6c2Smrg
17843458e6c2Smrg            default:
17853458e6c2Smrg                fprintf(stderr, "Line %d: extraneous keyword %s\n",
17863458e6c2Smrg                        linenum, keyword);
17873458e6c2Smrg                closeS(stream, CorrectionHead);
17883458e6c2Smrg                return (0);
17893458e6c2Smrg
17903458e6c2Smrg            }
17913458e6c2Smrg        }                       /* else it was just a blank line */
17922c7c4e3dSmrg    }
17933458e6c2Smrg    closeS(stream, CorrectionHead);
17942c7c4e3dSmrg    return (1);
17952c7c4e3dSmrg}
1796