summaryrefslogtreecommitdiff
path: root/app/xcmsdb/loadData.c
diff options
context:
space:
mode:
authorMatthieu Herrb <matthieu@cvs.openbsd.org>2006-11-25 20:39:09 +0000
committerMatthieu Herrb <matthieu@cvs.openbsd.org>2006-11-25 20:39:09 +0000
commit2387c426e6dfc2b0a2d0aa5585dbeb580f5ea91e (patch)
tree12721540663213a17c4c6a294f8f9473621fd503 /app/xcmsdb/loadData.c
parentdc4a2107be04f29ad06d6e60e102370bf68739cd (diff)
Importing from X.Org 7.2RC2
Diffstat (limited to 'app/xcmsdb/loadData.c')
-rw-r--r--app/xcmsdb/loadData.c1731
1 files changed, 1731 insertions, 0 deletions
diff --git a/app/xcmsdb/loadData.c b/app/xcmsdb/loadData.c
new file mode 100644
index 000000000..8d2cbac97
--- /dev/null
+++ b/app/xcmsdb/loadData.c
@@ -0,0 +1,1731 @@
+/* $Xorg: loadData.c,v 1.4 2000/08/17 19:54:13 cpqbld Exp $ */
+
+/*
+ * (c) Copyright 1990 Tektronix Inc.
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Tektronix not be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission.
+ *
+ * Tektronix disclaims all warranties with regard to this software, including
+ * all implied warranties of merchantability and fitness, in no event shall
+ * Tektronix be liable for any special, indirect or consequential damages or
+ * any damages whatsoever resulting from loss of use, data or profits,
+ * whether in an action of contract, negligence or other tortious action,
+ * arising out of or in connection with the use or performance of this
+ * software.
+ *
+ *
+ * NAME
+ * LoadSCCData.c
+ *
+ * DESCRIPTION
+ * TekCMS API routine that reads screen data from a file
+ * and then loads the data on the root window of the screen.
+ *
+ *
+ *
+ */
+/* $XFree86: xc/programs/xcmsdb/loadData.c,v 3.3 2001/07/25 15:05:18 dawes Exp $ */
+
+/*
+ * INCLUDES
+ */
+
+#include <X11/Xos.h>
+#include <sys/stat.h>
+#include <stdio.h>
+
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+#include "SCCDFile.h"
+
+
+/*
+ * EXTERNS
+ * External declarations required locally to this package
+ * that are not already declared in any of the included header
+ * files (external includes or internal includes).
+ */
+
+#include <stdlib.h>
+
+/*
+ * LOCAL TYPEDEFS
+ * typedefs local to this package (for use with local vars).
+ *
+ */
+
+typedef struct _DefineEntry {
+ char *pString;
+ int define;
+} DefineEntry;
+
+
+/*
+ * LOCAL VARIABLES
+ */
+static int linenum = 0;
+
+static DefineEntry KeyTbl[] = {
+ { SC_BEGIN_KEYWORD, SC_BEGIN },
+ { SC_END_KEYWORD, SC_END },
+ { COMMENT_KEYWORD, COMMENT },
+ { NAME_KEYWORD, NAME },
+ { MODEL_KEYWORD, MODEL },
+ { PART_NUMBER_KEYWORD, PART_NUMBER },
+ { SERIAL_NUMBER_KEYWORD, SERIAL_NUMBER },
+ { REVISION_KEYWORD, REVISION },
+ { SCREEN_CLASS_KEYWORD, SCREEN_CLASS },
+ { COLORIMETRIC_BEGIN_KEYWORD, COLORIMETRIC_BEGIN },
+ { COLORIMETRIC_END_KEYWORD, COLORIMETRIC_END },
+ { XYZTORGBMAT_BEGIN_KEYWORD, XYZTORGBMAT_BEGIN },
+ { XYZTORGBMAT_END_KEYWORD, XYZTORGBMAT_END },
+ { WHITEPT_XYZ_BEGIN_KEYWORD, WHITEPT_XYZ_BEGIN },
+ { WHITEPT_XYZ_END_KEYWORD, WHITEPT_XYZ_END },
+ { RGBTOXYZMAT_BEGIN_KEYWORD, RGBTOXYZMAT_BEGIN },
+ { RGBTOXYZMAT_END_KEYWORD, RGBTOXYZMAT_END },
+ { IPROFILE_BEGIN_KEYWORD, IPROFILE_BEGIN },
+ { IPROFILE_END_KEYWORD, IPROFILE_END },
+ { ITBL_BEGIN_KEYWORD, ITBL_BEGIN },
+ { ITBL_END_KEYWORD, ITBL_END },
+ { "", -1 }
+};
+
+static DefineEntry ScrnClassTbl[] = {
+ { VIDEO_RGB_KEYWORD, VIDEO_RGB },
+#ifdef GRAY
+ { VIDEO_GRAY_KEYWORD, VIDEO_GRAY },
+#endif /* GRAY */
+ { "", -1 }
+};
+
+#define KEY_VISUALID 1
+#define KEY_DEPTH 2
+#define KEY_CLASS 3
+#define KEY_RED_MASK 4
+#define KEY_GREEN_MASK 5
+#define KEY_BLUE_MASK 6
+#define KEY_COLORMAP_SIZE 7
+#define KEY_BITS_PER_RGB 8
+
+static DefineEntry VisualOptKeyTbl[] = {
+ { "visualid", KEY_VISUALID },
+ { "depth", KEY_DEPTH },
+ { "class", KEY_CLASS },
+ { "red_mask", KEY_RED_MASK },
+ { "green_mask", KEY_GREEN_MASK },
+ { "blue_mask", KEY_BLUE_MASK },
+ { "colormap_size", KEY_COLORMAP_SIZE },
+ { "bits_per_rgb", KEY_BITS_PER_RGB },
+ { "", -1 }
+};
+static DefineEntry VisualClassTbl[] = {
+ { "StaticGray", StaticGray },
+ { "GrayScale", GrayScale },
+ { "StaticColor", StaticColor },
+ { "PseudoColor", PseudoColor },
+ { "TrueColor", TrueColor },
+ { "DirectColor", DirectColor },
+ { "", -1 }
+};
+
+
+/************************************************************************
+ * *
+ * PRIVATE ROUTINES *
+ * *
+ ************************************************************************/
+
+/*
+ * NAME
+ * StrToDefine - convert a string to a define
+ *
+ * SYNOPSIS
+ */
+static int
+StrToDefine(DefineEntry pde[], /* IN: table of X string-define pairs */
+ /* last entry must contain pair "", 0 */
+ char *pstring) /* IN: string to be looked up in that table */
+/*
+ * DESCRIPTION
+ * Converts a string to an integer define.
+ *
+ * Looks up the string in the table and returns the integer
+ * associated with the string.
+ *
+ * Later may need similar function for unsigned long define.
+ *
+ *
+ *
+ * RETURNS
+ * The int equivalent of the defined string.
+ * -1 if the string is not found in table
+ *
+ */
+{
+ while( strcmp(pde->pString,"") != 0 ){
+ if( strcmp(pde->pString,pstring) == 0){
+ return(pde->define);
+ }
+ pde++;
+ }
+ return(-1);
+}
+
+/*
+ * NAME
+ * DefineToStr
+ *
+ * SYNOPSIS
+ */
+static char *
+DefineToStr(DefineEntry pde[], /* IN: table of X string-define pairs */
+ /* last entry must contain pair "", 0 */
+ int id) /* IN: id to be looked up in that table */
+/*
+ * DESCRIPTION
+ * Converts a string to an integer define.
+ *
+ * Looks up the string in the table and returns the integer
+ * associated with the string.
+ *
+ * Later may need similar function for unsigned long define.
+ *
+ *
+ *
+ * RETURNS
+ * The int equivalent of the defined string.
+ * -1 if the string is not found in table
+ *
+ */
+{
+ while(pde->define != -1) {
+ if (pde->define == id) {
+ return(pde->pString);
+ }
+ pde++;
+ }
+ return(NULL);
+}
+
+/*
+ * NAME
+ * SCKeyOf - convert keyword into key ID
+ *
+ * SYNOPSIS
+ */
+static int
+SCKeyOf(char *string)
+/*
+ * DESCRIPTION
+ * Converts a string to an integer define.
+ *
+ * Looks up the string in the table and returns the integer
+ * associated with the string.
+ *
+ * Later may need similar function for unsigned long define.
+ *
+ *
+ *
+ * RETURNS
+ * The int equivalent of the defined string.
+ * -1 if the string is not found in table
+ *
+ */
+{
+ return(StrToDefine(KeyTbl, string));
+}
+
+
+/*
+ * NAME
+ * SCScrnClassOf - convert screen class string into class ID
+ *
+ * SYNOPSIS
+ */
+static int
+SCScrnClassOf(char *string)
+/*
+ * DESCRIPTION
+ * Converts a string to an integer define.
+ *
+ * Looks up the string in the table and returns the integer
+ * associated with the string.
+ *
+ * Later may need similar function for unsigned long define.
+ *
+ *
+ *
+ * RETURNS
+ * The int equivalent of the defined string.
+ * -1 if the string is not found in table
+ *
+ */
+{
+ return(StrToDefine(ScrnClassTbl, string));
+}
+
+
+/*
+ * NAME
+ * SCScrnClassStringOf - convert screen class id into class string
+ *
+ * SYNOPSIS
+ */
+static char *
+SCScrnClassStringOf(int id)
+/*
+ * DESCRIPTION
+ * Converts a id to astring
+ *
+ * RETURNS
+ * Pointer to string if found; otherwise NULL.
+ *
+ */
+{
+ return(DefineToStr(ScrnClassTbl, id));
+}
+
+/* close the stream and return any memory allocated. */
+/*ARGSUSED*/
+static void
+closeS(FILE *stream, XDCCC_Correction *pCorrection)
+{
+ XDCCC_Correction* pNext;
+ if (stream) {
+ fclose (stream);
+ }
+ while (pCorrection) {
+ pNext = pCorrection->next;
+ free(pCorrection);
+ pCorrection = pNext;
+ }
+}
+
+/*
+ * Get a line of text from the stream.
+ */
+static char *
+nextline(char *buf, int maxch, FILE *stream)
+{
+ linenum++;
+ return (fgets(buf, maxch, stream));
+}
+
+
+static int
+ProcessColorimetric(FILE *stream, XDCCC_Matrix *pMatrix, int VisualFlag)
+{
+ char buf[BUFSIZ];
+ char keyword[BUFSIZ];
+ char token[BUFSIZ], *ptoken;
+ int ntok;
+ unsigned int matrices_processed = 0;
+ /* bit 0 for XYZtoRGB matrix */
+ /* bit 1 for RGBtoXYZ matrix */
+ int state = 0;
+ /* 0 -- looking for matrix */
+ /* 1 -- processing data from matrix */
+ /* 2 -- both matrices processed */
+ /* Note: the order of the matrices is not important. */
+ int count = -1;
+ XcmsFloat *pElement = NULL;
+
+ while ((nextline(buf, BUFSIZ, stream)) != NULL) {
+ if ((ntok = sscanf(buf, "%s %s", keyword, token)) > 0) {
+ switch (SCKeyOf(keyword)) {
+ case XYZTORGBMAT_BEGIN :
+ if (VisualFlag != VIDEO_RGB) {
+ fprintf(stderr,
+ "Line %d: Keyword XYZTORGBMAT_BEGIN mismatch for visual %s.\n",
+ linenum, SCScrnClassStringOf(VisualFlag));
+ return (0);
+ }
+ if (state != 0) {
+ fprintf(stderr,
+ "Line %d: Extraneous keyword %s.\n",
+ linenum, keyword);
+ return (0);
+ }
+ state = 1;
+ count = 0;
+ pElement = (XcmsFloat *) pMatrix->XYZtoRGBmatrix;
+ break;
+ case XYZTORGBMAT_END :
+ if (VisualFlag != VIDEO_RGB) {
+ fprintf(stderr,
+ "Line %d: Keyword XYZTORGBMAT_END mismatch for visual %s.\n",
+ linenum, SCScrnClassStringOf(VisualFlag));
+ return (0);
+ }
+ if ((state != 1) || (count != 9)) {
+ fprintf(stderr,
+ "Line %d: Incomplete XYZtoRGB matrix -- Premature %s\n",
+ linenum, keyword);
+ return (0);
+ }
+ matrices_processed |= 0x1;
+ if (matrices_processed == 3) {
+ state = 2;
+ } else {
+ state = 0;
+ }
+ break;
+ case RGBTOXYZMAT_BEGIN :
+ if (VisualFlag != VIDEO_RGB) {
+ fprintf(stderr,
+ "Line %d: Keyword RGBTOXYZMAT_BEGIN mismatch for visual %s.\n",
+ linenum, SCScrnClassStringOf(VisualFlag));
+ return (0);
+ }
+ if (state != 0) {
+ fprintf(stderr, "Line %d: Extraneous keyword %s.\n",
+ linenum, keyword);
+ return (0);
+ }
+ state = 1;
+ count = 0;
+ pElement = (XcmsFloat *) pMatrix->RGBtoXYZmatrix;
+ break;
+ case RGBTOXYZMAT_END :
+ if (VisualFlag != VIDEO_RGB) {
+ fprintf(stderr,
+ "Line %d: Keyword RGBTOXYZMAT_END mismatch for visual %s.\n",
+ linenum, SCScrnClassStringOf(VisualFlag));
+ return (0);
+ }
+ if ((state != 1) || (count != 9)) {
+ fprintf(stderr,
+ "Line %d: Incomplete RGBtoXYZ matrix -- Premature %s\n",
+ linenum, keyword);
+ return (0);
+ }
+ matrices_processed |= 0x2;
+ if (matrices_processed == 3) {
+ state = 2;
+ } else {
+ state = 0;
+ }
+ break;
+#ifdef GRAY
+ case WHITEPT_XYZ_BEGIN :
+ if (VisualFlag != VIDEO_GRAY) {
+ fprintf(stderr,
+ "Line %d: Keyword WHITEPT_XYZ_BEGIN mismatch for visual %s.\n",
+ linenum, SCScrnClassStringOf(VisualFlag));
+ return (0);
+ }
+ if (state != 0) {
+ fprintf(stderr,
+ "Line %d: Extraneous keyword %s.\n",
+ linenum, keyword);
+ return (0);
+ }
+ state = 1;
+ count = 0;
+ pElement = (XcmsFloat *) pMatrix->XYZtoRGBmatrix;
+ break;
+ case WHITEPT_XYZ_END :
+ if (VisualFlag != VIDEO_GRAY) {
+ fprintf(stderr,
+ "Line %d: Keyword WHITEPT_XYZ_END mismatch for visual %s.\n",
+ linenum, SCScrnClassStringOf(VisualFlag));
+ return (0);
+ }
+ if ((state != 1) || (count != 3)) {
+ fprintf(stderr,
+ "Line %d: Incomplete white point -- Premature %s\n",
+ linenum, keyword);
+ return (0);
+ }
+ state = 2;
+ break;
+#endif /* GRAY */
+ case DATA :
+ for (ptoken = strtok(buf, DATA_DELIMS); ptoken != NULL;
+ ptoken = strtok(NULL, DATA_DELIMS)) {
+ if (sscanf(ptoken, "%lf", pElement) != 1) {
+ if (VisualFlag == VIDEO_RGB) {
+ fprintf(stderr,
+ "Line %d: Invalid matrix value %s.",
+ linenum, ptoken);
+ } else {
+ fprintf(stderr,
+ "Line %d: Invalid CIEXYZ value %s.\n",
+ linenum, ptoken);
+ }
+ return (0);
+ }
+ pElement++;
+ if (VisualFlag == VIDEO_RGB) {
+ if (++count > 9) {
+ fprintf(stderr,
+ "Line %d: Extra matrix value %s\n",
+ linenum, ptoken);
+ return (0);
+ }
+ } else {
+ if (++count > 3) {
+ fprintf(stderr,
+ "Line %d: Extra CIEXYZ value %s.\n",
+ linenum, ptoken);
+ return (0);
+ }
+ }
+ }
+ break;
+ case COLORIMETRIC_BEGIN :
+ fprintf(stderr,
+ "Line %d: Extraneous keyword %s.\n",
+ linenum, keyword);
+ return (0);
+/* NOTREACHED */break;
+ case COLORIMETRIC_END :
+ if (state != 2) {
+ fprintf(stderr,
+ "Line %d: Incomplete Colorimetric data -- Premature %s\n",
+ linenum, keyword);
+ return (0);
+ }
+ return (1);
+ case COMMENT :
+ /* Currently, do nothing. */
+ break;
+ default :
+ fprintf(stderr,
+ "Line %d: Unexpected keyword %s\n",
+ linenum, keyword);
+ return (0);
+/* NOTREACHED */break;
+ }
+ } else if (ntok < 0) {
+ /* mismatch */
+ fprintf(stderr, "Line %d: Unrecognized keyword\n", linenum);
+ return (0);
+/* NOTREACHED */break;
+ }
+ }
+ return (0);
+}
+
+static int
+ProcessIProfile(FILE *stream, XDCCC_Correction *pCorrection)
+{
+ char buf[BUFSIZ];
+ char *keyword;
+ char *tableStr, *sizeStr, *ptoken;
+ int size;
+ int state = 0;
+ /************************************************
+ * 0 -- Looking for Intensity Table(s) *
+ * 1 -- Processing Intensity Table(s) *
+ ************************************************/
+ int nTbl = 0;
+ int count = 0;
+ IntensityRec *pIRec = NULL;
+
+ while ((nextline(buf, BUFSIZ, stream)) != NULL) {
+ ptoken = keyword = strtok(buf, DATA_DELIMS);
+ if (keyword != (char*)NULL) {
+ switch (SCKeyOf(keyword)) {
+ case ITBL_BEGIN :
+ if (state != 0) {
+ fprintf(stderr,"Line %d: unexpected keyword %s\n",
+ linenum, keyword);
+ return (0);
+ }
+ tableStr = strtok((char*)NULL, DATA_DELIMS);
+ sizeStr = strtok((char*)NULL, DATA_DELIMS);
+ if ((sizeStr == (char*)NULL) ||
+ sscanf(sizeStr, "%d", &size) != 1) {
+ fprintf(stderr,
+ "Line %d: invalid Intensity Table size, %s.\n",
+ linenum, sizeStr);
+ return (0);
+ }
+ if (size < 0) {
+ fprintf(stderr,
+ "Line %d: count %d < 0 for Intensity Table.\n",
+ linenum, size);
+ return (0);
+ }
+ if (strcmp(tableStr, "GREEN") == 0) {
+ if (pCorrection->nTables != 3) {
+ fprintf(stderr,"Line %d: incorrect number of tables\n",
+ linenum);
+ return (0);
+ }
+ if (pCorrection->pGreenTbl->pBase != NULL) {
+ fprintf(stderr,
+ "Line %d: multiple GREEN Intensity Profiles\n",
+ linenum);
+ return (0);
+ }
+ pCorrection->pGreenTbl->nEntries = size;
+ pCorrection->pGreenTbl->pBase =
+ (IntensityRec *) calloc (size, sizeof(IntensityRec));
+ if (!pCorrection->pGreenTbl->pBase) {
+ fprintf(stderr,
+ "Line %d: Unable to allocate space for GREEN Intensity Profile\n", linenum);
+ return (0);
+ }
+ pIRec = pCorrection->pGreenTbl->pBase;
+ } else if (strcmp(tableStr, "BLUE") == 0) {
+ if (pCorrection->nTables != 3) {
+ fprintf(stderr,
+ "Line %d: incorrect number of tables\n",
+ linenum);
+ return (0);
+ }
+ if (pCorrection->pBlueTbl->pBase != NULL) {
+ fprintf(stderr,
+ "Line %d: multiple BLUE Intensity Profiles\n",
+ linenum);
+ return (0);
+ }
+ pCorrection->pBlueTbl->nEntries = size;
+ pCorrection->pBlueTbl->pBase =
+ (IntensityRec *) calloc (size, sizeof(IntensityRec));
+ if (!pCorrection->pBlueTbl->pBase) {
+ fprintf(stderr,
+ "Line %d: Unable to allocate space for BLUE Intensity Profile\n", linenum);
+ return (0);
+ }
+ pIRec = pCorrection->pBlueTbl->pBase;
+ } else {
+ if (!strcmp(tableStr, "RGB") && pCorrection->nTables != 1) {
+ fprintf(stderr,"Line %d: multiple RGB Intensity Tables",
+ linenum);
+ return (0);
+ }
+ if (pCorrection->pRedTbl->pBase != NULL) {
+ fprintf(stderr,
+ "Line %d: multiple RED or GREEN or BLUE Intensity Tables\n",
+ linenum);
+ return (0);
+ }
+ pCorrection->pRedTbl->nEntries = size;
+ pCorrection->pRedTbl->pBase =
+ (IntensityRec *) calloc (size, sizeof(IntensityRec));
+ if (!pCorrection->pRedTbl->pBase) {
+ fprintf(stderr,
+ "Line %d: Unable to allocate space for intensity table\n", linenum);
+ return (0);
+ }
+ pIRec = pCorrection->pRedTbl->pBase;
+ }
+ state = 1;
+ count = 0;
+ break;
+ case ITBL_END :
+ if ((state != 1) || (count != size)) {
+ fprintf(stderr,
+ "Line %d: incomplete Intensity Table -- Premature %s\n",
+ linenum, keyword);
+ return (0);
+ }
+ nTbl++;
+ state = 0;
+ break;
+ case DATA :
+ do {
+ /********************************************************
+ * Note: tableType should only be 0 or 1 at this point.
+ * 0 indicates value and intensity stored.
+ * 1 indicates only intensity stored.
+ ********************************************************/
+ if (pCorrection->tableType) {
+ if (sscanf(ptoken, "%lf", &pIRec->intensity) != 1) {
+ fprintf(stderr,
+ "Line %d: invalid Intensity Profile value %s\n",
+ linenum, ptoken);
+ return (0);
+ }
+ /* With tableType 1 only store the intensity. */
+ pIRec++;
+ } else {
+ short tmp;
+ /* Note ansi C can handle 0x preceeding hex number */
+ if (sscanf(ptoken, "%hi", &tmp) != 1) {
+ fprintf(stderr,
+ "Line %d: invalid Intensity Profile value %s\n",
+ linenum, ptoken);
+ return (0);
+ } else
+ pIRec->value = tmp;
+ if ((ptoken = strtok(NULL, DATA_DELIMS)) == NULL) {
+ fprintf(stderr,
+ "Line %d: missing Intensity Profile value\n",
+ linenum);
+ return (0);
+ }
+ if (sscanf(ptoken, "%lf", &pIRec->intensity) != 1) {
+ fprintf(stderr,
+ "Line %d: invalid Intensity Profile intensity %s\n",
+ linenum, ptoken);
+ return (0);
+ }
+ /* With tableType 0 only store both value & intensity*/
+ pIRec++;
+ }
+ if (++count > size) {
+ fprintf(stderr,
+ "Line %d: extra Intensity value %s\n",
+ linenum, ptoken);
+ return (0);
+ }
+ ptoken = strtok(NULL, DATA_DELIMS);
+ } while(ptoken != NULL);
+ break;
+ case IPROFILE_BEGIN :
+ fprintf(stderr,"Line %d: extraneous keyword %s\n",
+ linenum, keyword);
+ return (0);
+/* NOTREACHED */break;
+ case IPROFILE_END :
+ if ((state != 0) || (nTbl != pCorrection->nTables)) {
+ fprintf(stderr,
+ "Line %d: incomplete Intensity Profile data -- Premature %s\n",
+ linenum, keyword);
+ return (0);
+ }
+ return (1);
+ case COMMENT :
+ /* ignore line */
+ break;
+ default :
+ fprintf(stderr,"Line %d: unexpected keyword %s\n",
+ linenum, keyword);
+ return (0);
+/* NOTREACHED */break;
+ }
+ } /* else its was just a blank line */
+ }
+ return (0);
+}
+
+static void
+PutTableType0Card8(IntensityTbl *pTbl, unsigned char **pCard8)
+{
+ unsigned int count;
+ IntensityRec *pIRec;
+
+ pIRec = pTbl->pBase;
+ count = pTbl->nEntries;
+ **pCard8 = count - 1;
+ *pCard8 += 1;
+ for (; count; count--, pIRec++) {
+ **pCard8 = pIRec->value >> 8;
+ *pCard8 += 1;
+ **pCard8 = pIRec->intensity * 255.0;
+ *pCard8 += 1;
+ }
+}
+
+static void
+PutTableType1Card8(IntensityTbl *pTbl, unsigned char **pCard8)
+{
+ unsigned int count;
+ IntensityRec *pIRec;
+
+ pIRec = pTbl->pBase;
+ count = pTbl->nEntries;
+ **pCard8 = count - 1;
+ *pCard8 += 1;
+ for (; count; count--, pIRec++) {
+ **pCard8 = pIRec->intensity * 255.0;
+ *pCard8 += 1;
+ }
+}
+
+static void
+PutTableType0Card16(IntensityTbl *pTbl, unsigned short **pCard16)
+{
+ unsigned int count;
+ IntensityRec *pIRec;
+
+ pIRec = pTbl->pBase;
+ count = pTbl->nEntries;
+ **pCard16 = count - 1;
+ *pCard16 += 1;
+ for (; count; count--, pIRec++) {
+ **pCard16 = pIRec->value;
+ *pCard16 += 1;
+ **pCard16 = pIRec->intensity * 65535.0;
+ *pCard16 += 1;
+ }
+}
+
+static void
+PutTableType1Card16(IntensityTbl *pTbl, unsigned short **pCard16)
+{
+ unsigned int count;
+ IntensityRec *pIRec;
+
+ pIRec = pTbl->pBase;
+ count = pTbl->nEntries;
+ **pCard16 = count - 1;
+ *pCard16 += 1;
+ for (; count; count--, pIRec++) {
+ **pCard16 = pIRec->intensity * 65535.0;
+ *pCard16 += 1;
+ }
+}
+
+static void
+PutTableType0Card32(IntensityTbl *pTbl, unsigned long **pCard32)
+{
+ unsigned int count;
+ IntensityRec *pIRec;
+
+ pIRec = pTbl->pBase;
+ count = pTbl->nEntries;
+ **pCard32 = count - 1;
+ *pCard32 += 1;
+ for (; count; count--, pIRec++) {
+ **pCard32 = pIRec->value;
+ *pCard32 += 1;
+ **pCard32 = pIRec->intensity * 4294967295.0;
+ *pCard32 += 1;
+ }
+}
+
+static void
+PutTableType1Card32(IntensityTbl *pTbl, unsigned long **pCard32)
+{
+ unsigned int count;
+ IntensityRec *pIRec;
+
+ pIRec = pTbl->pBase;
+ count = pTbl->nEntries;
+ **pCard32 = count - 1;
+ *pCard32 += 1;
+ for (; count; count--, pIRec++) {
+ **pCard32 = pIRec->intensity * 4294967295.0;
+ *pCard32 += 1;
+ }
+}
+
+
+static void
+LoadMatrix(Display *pDpy, Window root, XDCCC_Matrix *pMatrix)
+{
+ int count;
+ unsigned long *pCard32;
+ unsigned long Card32Array[18];
+ Atom MatricesAtom;
+ XcmsFloat *pValue;
+
+ /*
+ * Store the XDCCC_LINEAR_RGB_MATRICES
+ */
+ pCard32 = Card32Array;
+ pValue = (XcmsFloat *)pMatrix->XYZtoRGBmatrix;
+ for (count = 0; count < 9; count++) {
+ *pCard32++ = (unsigned long) (*pValue++ * (XcmsFloat) XDCCC_NUMBER);
+ }
+ pValue = (XcmsFloat *)pMatrix->RGBtoXYZmatrix;
+ for (count = 0; count < 9; count++) {
+ *pCard32++ = (unsigned long) (*pValue++ * (XcmsFloat) XDCCC_NUMBER);
+ }
+ MatricesAtom = XInternAtom (pDpy, XDCCC_MATRIX_ATOM_NAME, False);
+ XChangeProperty (pDpy, root, MatricesAtom, XA_INTEGER, 32,
+ PropModeReplace, (unsigned char *)Card32Array, 18);
+}
+
+
+static int
+LoadCorrections(Display *pDpy, Window root, XDCCC_Correction *pCorrection,
+ int targetFormat)
+{
+ unsigned char *pCard8;
+ unsigned char *pCard8Array = (unsigned char *)NULL;
+ unsigned short *pCard16;
+ unsigned short *pCard16Array = (unsigned short *)NULL;
+ unsigned long *pCard32;
+ unsigned long *pCard32Array = (unsigned long *)NULL;
+ Atom CorrectAtom;
+ int total;
+ int i;
+
+ /*
+ * Store each XDCCC_CORRECTION into XDCCC_LINEAR_RGB_CORRECTION property
+ */
+ CorrectAtom = XInternAtom (pDpy, XDCCC_CORRECT_ATOM_NAME, False);
+
+ for (i = 0; pCorrection; i++, pCorrection = pCorrection->next) {
+ if ((pCorrection->tableType != 0) && (pCorrection->tableType != 1)) {
+ if (pCorrection->visual_info.visualid) {
+ fprintf(stderr,"RGB Correction for visualid %ld: Invalid intensity table type %d.\n",
+ pCorrection->visual_info.visualid,
+ pCorrection->tableType);
+ } else {
+ fprintf(stderr,"Global RGB Correction: Invalid intensity table type %d.\n",
+ pCorrection->tableType);
+ }
+ return(0);
+ }
+
+ if (pCorrection->nTables != 1 && pCorrection->nTables != 3) {
+ if (pCorrection->visual_info.visualid) {
+ fprintf(stderr,"RGB Correction for visualid %ld: %d invalid number of tables.\n",
+ pCorrection->visual_info.visualid,
+ pCorrection->nTables);
+ } else {
+ fprintf(stderr,"Global RGB Correction: %d invalid number of tables.\n",
+ pCorrection->nTables);
+ }
+ return(0);
+ }
+
+ if (pCorrection->nTables == 1) {
+ if (pCorrection->pRedTbl->nEntries < 2) {
+ if (pCorrection->visual_info.visualid) {
+ fprintf(stderr,"RGB Correction for visualid %ld: Illegal number of entries in table\n",
+ pCorrection->visual_info.visualid);
+ } else {
+ fprintf(stderr,"Global RGB Correction: Illegal number of entries in table\n");
+ }
+ return (0);
+ }
+ switch (targetFormat) {
+ case 8:
+ total = 7 + (pCorrection->pRedTbl->nEntries *
+ (pCorrection->tableType == 0 ? 2 : 1));
+ if ((pCard8 = pCard8Array = (unsigned char *) calloc (total,
+ sizeof (unsigned char))) == NULL) {
+ fprintf(stderr,"Unable allocate array of ints\n");
+ return (0);
+ }
+ *pCard8++ = (pCorrection->visual_info.visualid >> 24) & 0xFF;
+ *pCard8++ = (pCorrection->visual_info.visualid >> 16) & 0xFF;
+ *pCard8++ = (pCorrection->visual_info.visualid >> 8) & 0xFF;
+ *pCard8++ = (pCorrection->visual_info.visualid) & 0xFF;
+ *pCard8++ = pCorrection->tableType; /* type */
+ *pCard8++ = 1; /* number of tables = 1 */
+ if (pCorrection->tableType == 0) {
+ PutTableType0Card8(pCorrection->pRedTbl, &pCard8);
+ } else {
+ PutTableType1Card8(pCorrection->pRedTbl, &pCard8);
+ }
+ XChangeProperty (pDpy, root, CorrectAtom, XA_INTEGER, 8,
+ i ? PropModeAppend : PropModeReplace,
+ (unsigned char *)pCard8Array, total);
+ free(pCard8Array);
+ break;
+ case 16:
+ total = 5 + (pCorrection->pRedTbl->nEntries *
+ (pCorrection->tableType == 0 ? 2 : 1));
+ if ((pCard16 = pCard16Array = (unsigned short *) calloc (total,
+ sizeof (unsigned short))) == NULL) {
+ fprintf(stderr,"Unable allocate array of ints\n");
+ return (0);
+ }
+ *pCard16++ = (pCorrection->visual_info.visualid >> 16) & 0xFFFF;
+ *pCard16++ = (pCorrection->visual_info.visualid) & 0xFFFF;
+ *pCard16++ = pCorrection->tableType; /* type */
+ *pCard16++ = 1; /* number of tables = 1 */
+ if (pCorrection->tableType == 0) {
+ PutTableType0Card16(pCorrection->pRedTbl, &pCard16);
+ } else {
+ PutTableType1Card16(pCorrection->pRedTbl, &pCard16);
+ }
+ XChangeProperty (pDpy, root, CorrectAtom, XA_INTEGER, 16,
+ i ? PropModeAppend : PropModeReplace,
+ (unsigned char *)pCard16Array, total);
+ free(pCard16Array);
+ break;
+ case 32:
+ total = 4 + (pCorrection->pRedTbl->nEntries *
+ (pCorrection->tableType == 0 ? 2 : 1));
+ if ((pCard32 = pCard32Array =
+ (unsigned long *) calloc (total,
+ sizeof (unsigned long))) == NULL) {
+ fprintf(stderr,"Unable allocate array of ints\n");
+ return (0);
+ }
+ *pCard32++ = pCorrection->visual_info.visualid;
+ *pCard32++ = pCorrection->tableType; /* type */
+ *pCard32++ = 1; /* number of tables = 1 */
+ if (pCorrection->tableType == 0) {
+ PutTableType0Card32(pCorrection->pRedTbl, &pCard32);
+ } else {
+ PutTableType1Card32(pCorrection->pRedTbl, &pCard32);
+ }
+ XChangeProperty (pDpy, root, CorrectAtom, XA_INTEGER, 32,
+ i ? PropModeAppend : PropModeReplace,
+ (unsigned char *)pCard32Array, total);
+ free(pCard32Array);
+ break;
+ default:
+ if (pCorrection->visual_info.visualid) {
+ fprintf(stderr,"RGB Correction for visualid %ld: Invalid property format\n",
+ pCorrection->visual_info.visualid);
+ } else {
+ fprintf(stderr,"Global RGB Correction: Invalid property format\n");
+ }
+ return (0);
+ }
+ } else { /* pCorrection->nTables == 3 */
+ if ((pCorrection->pRedTbl->nEntries < 2) ||
+ (pCorrection->pGreenTbl->nEntries < 2) ||
+ (pCorrection->pBlueTbl->nEntries < 2)) {
+ if (pCorrection->visual_info.visualid) {
+ fprintf(stderr,"RGB Correction for visualid %ld: Illegal number of entries in table\n",
+ pCorrection->visual_info.visualid);
+ } else {
+ fprintf(stderr,"Global RGB Correction: Illegal number of entries in table\n");
+ }
+ return (0);
+ }
+ switch (targetFormat) {
+ case 8:
+ total = 9 + /* visualID, type, and 3 lengths */
+ (pCorrection->pRedTbl->nEntries * (pCorrection->tableType == 0 ? 2 : 1)) +
+ (pCorrection->pGreenTbl->nEntries * (pCorrection->tableType == 0 ? 2 : 1)) +
+ (pCorrection->pBlueTbl->nEntries * (pCorrection->tableType == 0 ? 2 : 1));
+ if ((pCard8 = pCard8Array =
+ (unsigned char *) calloc (total,
+ sizeof (unsigned char))) == NULL) {
+ fprintf(stderr,"Unable allocate array of ints\n");
+ return (0);
+ }
+ *pCard8++ = (pCorrection->visual_info.visualid >> 24) & 0xFF;
+ *pCard8++ = (pCorrection->visual_info.visualid >> 16) & 0xFF;
+ *pCard8++ = (pCorrection->visual_info.visualid >> 8) & 0xFF;
+ *pCard8++ = (pCorrection->visual_info.visualid) & 0xFF;
+ *pCard8++ = pCorrection->tableType; /* type */
+ *pCard8++ = 3; /* number of tables = 3 */
+ if (pCorrection->tableType == 0) {
+ PutTableType0Card8(pCorrection->pRedTbl, &pCard8);
+ PutTableType0Card8(pCorrection->pGreenTbl, &pCard8);
+ PutTableType0Card8(pCorrection->pBlueTbl, &pCard8);
+ } else {
+ PutTableType1Card8(pCorrection->pRedTbl, &pCard8);
+ PutTableType1Card8(pCorrection->pGreenTbl, &pCard8);
+ PutTableType1Card8(pCorrection->pBlueTbl, &pCard8);
+ }
+ XChangeProperty (pDpy, root, CorrectAtom, XA_INTEGER, 8,
+ i ? PropModeAppend : PropModeReplace,
+ (unsigned char *)pCard8Array, total);
+ free(pCard8Array);
+ break;
+ case 16:
+ total = 7 + /* visualID, type, and 3 lengths */
+ (pCorrection->pRedTbl->nEntries * (pCorrection->tableType == 0 ? 2 : 1)) +
+ (pCorrection->pGreenTbl->nEntries * (pCorrection->tableType == 0 ? 2 : 1)) +
+ (pCorrection->pBlueTbl->nEntries * (pCorrection->tableType == 0 ? 2 : 1));
+ if ((pCard16 = pCard16Array =
+ (unsigned short *) calloc (total,
+ sizeof (unsigned short))) == NULL) {
+ fprintf(stderr,"Unable allocate array of ints\n");
+ return (0);
+ }
+ *pCard16++ = (pCorrection->visual_info.visualid >> 16) & 0xFFFF;
+ *pCard16++ = (pCorrection->visual_info.visualid) & 0xFFFF;
+ *pCard16++ = pCorrection->tableType; /* type = 0 */
+ *pCard16++ = 3; /* number of tables = 3 */
+ if (pCorrection->tableType == 0) {
+ PutTableType0Card16(pCorrection->pRedTbl, &pCard16);
+ PutTableType0Card16(pCorrection->pGreenTbl, &pCard16);
+ PutTableType0Card16(pCorrection->pBlueTbl, &pCard16);
+ } else {
+ PutTableType1Card16(pCorrection->pRedTbl, &pCard16);
+ PutTableType1Card16(pCorrection->pGreenTbl, &pCard16);
+ PutTableType1Card16(pCorrection->pBlueTbl, &pCard16);
+ }
+ XChangeProperty (pDpy, root, CorrectAtom, XA_INTEGER, 16,
+ i ? PropModeAppend : PropModeReplace,
+ (unsigned char *)pCard16Array, total);
+ free(pCard16Array);
+ break;
+ case 32:
+ total = 6 + /* visualID, type, and 3 lengths */
+ (pCorrection->pRedTbl->nEntries * (pCorrection->tableType == 0 ? 2 : 1)) +
+ (pCorrection->pGreenTbl->nEntries * (pCorrection->tableType == 0 ? 2 : 1)) +
+ (pCorrection->pBlueTbl->nEntries * (pCorrection->tableType == 0 ? 2 : 1));
+ if ((pCard32 = pCard32Array =
+ (unsigned long *) calloc (total,
+ sizeof (unsigned long))) == NULL) {
+ fprintf(stderr,"Unable allocate array of ints\n");
+ return (0);
+ }
+ *pCard32++ = pCorrection->visual_info.visualid;
+ *pCard32++ = pCorrection->tableType; /* type */
+ *pCard32++ = 3; /* number of tables = 3 */
+ if (pCorrection->tableType == 0) {
+ PutTableType0Card32(pCorrection->pRedTbl, &pCard32);
+ PutTableType0Card32(pCorrection->pGreenTbl, &pCard32);
+ PutTableType0Card32(pCorrection->pBlueTbl, &pCard32);
+ } else {
+ PutTableType1Card32(pCorrection->pRedTbl, &pCard32);
+ PutTableType1Card32(pCorrection->pGreenTbl, &pCard32);
+ PutTableType1Card32(pCorrection->pBlueTbl, &pCard32);
+ }
+ XChangeProperty (pDpy, root, CorrectAtom, XA_INTEGER, 32,
+ i ? PropModeAppend : PropModeReplace,
+ (unsigned char *)pCard32Array, total);
+ free(pCard32Array);
+ break;
+ default:
+ if (pCorrection->visual_info.visualid) {
+ fprintf(stderr,"RGB Correction for visualid %ld: Invalid property format\n",
+ pCorrection->visual_info.visualid);
+ } else {
+ fprintf(stderr,"Global RGB Correction: Invalid property format\n");
+ }
+ return (0);
+ }
+ }
+ }
+
+ return (1);
+}
+
+#ifdef GRAY
+
+static int
+LoadDataGray(Display *pDpy, window root, int tableType,
+ LINEAR_RGB_SCCData *pScreenData, int targetFormat)
+{
+ unsigned char *ret_prop;
+ int count;
+ int nLevels;
+ unsigned char *pCard8;
+ unsigned char *pCard8Array = (unsigned char *)NULL;
+ unsigned short *pCard16;
+ unsigned short *pCard16Array = (unsigned short *)NULL;
+ unsigned long *pCard32;
+ unsigned long *pCard32Array = (unsigned long *)NULL;
+ unsigned long Card32Array[18];
+ int ret_format;
+ unsigned long ret_len, ret_after;
+ Atom MatricesAtom, CorrectAtom, ret_atom;
+ XcmsFloat *pValue;
+ int total;
+
+ /* Now store the XDCCC_SCREENWHITEPT */
+ pCard32 = Card32Array;
+ pValue = (XcmsFloat *)pScreenData->XYZtoRGBmatrix;
+ for (count = 0; count < 3; count++) {
+ *pCard32++ = (unsigned long) (*pValue++ * (XcmsFloat) XDCCC_NUMBER);
+ }
+ MatricesAtom = XInternAtom (pDpy,XDCCC_SCREENWHITEPT_ATOM_NAME,False);
+ XChangeProperty (pDpy, root, MatricesAtom, XA_INTEGER, 32,
+ PropModeReplace, (unsigned char *)Card32Array, 3);
+
+ /* Now store the XDCCC_GRAY_CORRECTION */
+ CorrectAtom = XInternAtom (pDpy, XDCCC_GRAY_CORRECT_ATOM_NAME, False);
+
+ if (tableType == CORR_TYPE_NONE) {
+ XGetWindowProperty (pDpy, root, CorrectAtom,
+ 0, 5, False, XA_INTEGER,
+ &ret_atom, &ret_format, &ret_len, &ret_after,
+ &ret_prop);
+ if (ret_format != 0) {
+ XDeleteProperty (pDpy, root, CorrectAtom);
+ XFree ((char *)ret_prop);
+ }
+ return (1);
+ }
+ nLevels = pScreenData->pRedTbl->nEntries;
+ if (nLevels < 2) {
+ fprintf(stderr,"Illegal number of entries in table\n");
+ return (0);
+ }
+ switch (targetFormat) {
+ case 8:
+ total = 6 /* visualID, type, length */
+ + (nLevels * (tableType == 0 ? 2 : 1));
+ if ((pCard8 = pCard8Array = (unsigned char *)
+ calloc (total, sizeof (unsigned char))) == NULL) {
+ fprintf(stderr,"Unable allocate array of Card8\n");
+ return (0);
+ }
+ *pCard8++ = 0; /* VisualID = 0 */
+ *pCard8++ = 0; /* VisualID = 0 */
+ *pCard8++ = 0; /* VisualID = 0 */
+ *pCard8++ = 0; /* VisualID = 0 */
+ *pCard8++ = tableType; /* type */
+ if (tableType == 0) {
+ PutTableType0Card8(pScreenData->pRedTbl, &pCard8);
+ } else { /* tableType == 1 */
+ PutTableType1Card8(pScreenData->pRedTbl, &pCard8);
+ }
+ XChangeProperty (pDpy, root, CorrectAtom, XA_INTEGER, 8,
+ PropModeReplace, (unsigned char *)pCard8Array,
+ total);
+ free (pCard8Array);
+ break;
+ case 16:
+ total = 4 /* visualID, type, length */
+ + (nLevels * (tableType == 0 ? 2 : 1));
+ if ((pCard16 = pCard16Array = (unsigned short *)
+ calloc (total, sizeof (unsigned short))) == NULL) {
+ fprintf(stderr,"Unable allocate array of Card16\n");
+ return (0);
+ }
+ *pCard16++ = 0; /* VisualID = 0 */
+ *pCard16++ = 0; /* VisualID = 0 */
+ *pCard16++ = tableType; /* type */
+ if (tableType == 0) {
+ PutTableType0Card16(pScreenData->pRedTbl, &pCard16);
+ } else { /* tableType == 1 */
+ PutTableType1Card16(pScreenData->pRedTbl, &pCard16);
+ }
+ XChangeProperty (pDpy, root, CorrectAtom, XA_INTEGER, 16,
+ PropModeReplace, (unsigned char *)pCard16Array,
+ total);
+ free (pCard16Array);
+ break;
+ case 32:
+ total = 3 /* visualID, type, length */
+ + (nLevels * (tableType == 0 ? 2 : 1));
+ if ((pCard32 = pCard32Array = (unsigned long *)
+ calloc (total, sizeof (unsigned long))) == NULL) {
+ fprintf(stderr,"Unable allocate array of Card32\n");
+ return (0);
+ }
+ *pCard32++ = 0; /* VisualID = 0 */
+ *pCard32++ = tableType; /* type */
+ if (tableType == 0) {
+ PutTableType0Card32(pScreenData->pRedTbl, &pCard32);
+ } else { /* tableType == 1 */
+ PutTableType1Card32(pScreenData->pRedTbl, &pCard32);
+ }
+ XChangeProperty (pDpy, root, CorrectAtom, XA_INTEGER, 32,
+ PropModeReplace, (unsigned char *)pCard32Array,
+ total);
+ free (pCard32Array);
+ break;
+ default:
+ fprintf(stderr,"Invalid property format\n");
+ return (0);
+ }
+ return (1);
+}
+#endif /* GRAY */
+
+
+static void
+PrintVisualOptions(XDCCC_Correction *pCorrection)
+{
+ if (pCorrection->visual_info_mask & VisualIDMask) {
+ fprintf(stderr, "\t%s:0x%lx\n",
+ DefineToStr(VisualOptKeyTbl, KEY_VISUALID),
+ (unsigned long)pCorrection->visual_info.visualid);
+ }
+ if (pCorrection->visual_info_mask & VisualDepthMask) {
+ fprintf(stderr, "\t%s:%d\n",
+ DefineToStr(VisualOptKeyTbl, KEY_DEPTH),
+ pCorrection->visual_info.depth);
+ }
+ if (pCorrection->visual_info_mask & VisualClassMask) {
+ fprintf(stderr, "\t%s:%s\n",
+ DefineToStr(VisualOptKeyTbl, KEY_CLASS),
+ DefineToStr(VisualClassTbl, pCorrection->visual_info.class));
+ }
+ if (pCorrection->visual_info_mask & VisualRedMaskMask) {
+ fprintf(stderr, "\t%s:0x%lx\n",
+ DefineToStr(VisualOptKeyTbl, KEY_RED_MASK),
+ pCorrection->visual_info.red_mask);
+ }
+ if (pCorrection->visual_info_mask & VisualGreenMaskMask) {
+ fprintf(stderr, "\t%s:0x%lx\n",
+ DefineToStr(VisualOptKeyTbl, KEY_GREEN_MASK),
+ pCorrection->visual_info.green_mask);
+ }
+ if (pCorrection->visual_info_mask & VisualBlueMaskMask) {
+ fprintf(stderr, "\t%s:0x%lx\n",
+ DefineToStr(VisualOptKeyTbl, KEY_BLUE_MASK),
+ pCorrection->visual_info.blue_mask);
+ }
+ if (pCorrection->visual_info_mask & VisualColormapSizeMask) {
+ fprintf(stderr, "\t%s:0x%x\n",
+ DefineToStr(VisualOptKeyTbl, KEY_COLORMAP_SIZE),
+ pCorrection->visual_info.colormap_size);
+ }
+ if (pCorrection->visual_info_mask & VisualBitsPerRGBMask) {
+ fprintf(stderr, "\t%s:%d\n",
+ DefineToStr(VisualOptKeyTbl, KEY_BITS_PER_RGB),
+ pCorrection->visual_info.bits_per_rgb);
+ }
+}
+
+
+static int
+ParseVisualOptions(Display *pDpy, XDCCC_Correction *pCorrection, char *pbuf)
+{
+ char *key;
+ char *value;
+ XVisualInfo *vinfo;
+ int n_matches;
+ char delims[8];
+
+ strcpy(delims, DATA_DELIMS);
+ strcat(delims, ":");
+ pCorrection->visual_info_mask = VisualNoMask;
+ key = strtok(pbuf, delims);
+ do {
+ long tmp;
+ value = strtok((char*)NULL, delims);
+ if ((key == (char*)NULL) || (value == (char*)NULL)) {
+ return (0);
+ }
+ switch (StrToDefine(VisualOptKeyTbl, key)) {
+ case KEY_VISUALID:
+ if (sscanf(value, "%li", &tmp) != 1) {
+ fprintf(stderr,
+ "Line %d: invalid VisualID specified, %s\n",
+ linenum, value);
+ return (0);
+ } else
+ pCorrection->visual_info.visualid = tmp;
+ pCorrection->visual_info_mask |= VisualIDMask;
+ break;
+ case KEY_DEPTH:
+ if (sscanf(value, "%i", &pCorrection->visual_info.depth) != 1) {
+ fprintf(stderr,
+ "Line %d: invalid depth specified, %s\n",
+ linenum, value);
+ return (0);
+ }
+ pCorrection->visual_info_mask |= VisualDepthMask;
+ break;
+ case KEY_CLASS:
+ switch (pCorrection->visual_info.class =
+ StrToDefine(VisualClassTbl, value)) {
+ case StaticColor:
+ break;
+ case PseudoColor:
+ break;
+ case TrueColor:
+ break;
+ case DirectColor:
+ break;
+ case StaticGray:
+ /* invalid, fall through */
+ case GrayScale:
+ /* invalid, fall through */
+ default:
+ fprintf(stderr,
+ "Line %d: invalid Visual Class -- %s\n",
+ linenum, value);
+ return (0);
+ }
+ pCorrection->visual_info_mask |= VisualClassMask;
+ break;
+ case KEY_RED_MASK:
+ if (sscanf(value, "%li", &tmp) != 1) {
+ fprintf(stderr,
+ "Line %d: invalid red_mask specified -- %s\n",
+ linenum, value);
+ return (0);
+ } else
+ pCorrection->visual_info.red_mask = tmp;
+ pCorrection->visual_info_mask |= VisualRedMaskMask;
+ break;
+ case KEY_GREEN_MASK:
+ if (sscanf(value, "%li", &tmp) != 1) {
+ fprintf(stderr,
+ "Line %d: invalid green_mask specified -- %s\n",
+ linenum, value);
+ return (0);
+ } else
+ pCorrection->visual_info.green_mask = tmp;
+ pCorrection->visual_info_mask |= VisualGreenMaskMask;
+ break;
+ case KEY_BLUE_MASK:
+ if (sscanf(value, "%li", &tmp) != 1) {
+ fprintf(stderr,
+ "Line %d: invalid blue_mask specified -- %s\n",
+ linenum, value);
+ return (0);
+ } else
+ pCorrection->visual_info.blue_mask = tmp;
+ pCorrection->visual_info_mask |= VisualBlueMaskMask;
+ break;
+ case KEY_COLORMAP_SIZE:
+ if (sscanf(value, "%i", &pCorrection->visual_info.colormap_size) != 1) {
+ fprintf(stderr,
+ "Line %d: invalid colormap_size specified -- %s\n",
+ linenum, value);
+ return (0);
+ }
+ pCorrection->visual_info_mask |= VisualColormapSizeMask;
+ break;
+ case KEY_BITS_PER_RGB:
+ if (sscanf(value, "%i", &pCorrection->visual_info.bits_per_rgb) != 1) {
+ fprintf(stderr,
+ "Line %d: invalid bits_per_rgb specified -- %s\n",
+ linenum, value);
+ return (0);
+ }
+ pCorrection->visual_info_mask |= VisualBitsPerRGBMask;
+ break;
+ default:
+ fprintf(stderr,
+ "Line %d: invalid keyword %s\n", linenum, key);
+ return (0);
+ }
+ key = strtok((char*)NULL, delims);
+ } while (key != (char *)NULL);
+
+ vinfo = XGetVisualInfo(pDpy,
+ pCorrection->visual_info_mask,
+ &pCorrection->visual_info,
+ &n_matches);
+
+ if (!n_matches) {
+ fprintf(stderr, "Line %d: Cannot find visual matching ...\n", linenum);
+ PrintVisualOptions(pCorrection);
+ fprintf(stderr, "\n");
+ return(0);
+ }
+ if (n_matches > 1) {
+ fprintf(stderr, "Line %d: Found more than one visual matching ...\n", linenum);
+ PrintVisualOptions(pCorrection);
+ fprintf(stderr, " Using VisualId 0x%lx\n", (unsigned long)vinfo->visualid);
+ }
+ memcpy((char*)&pCorrection->visual_info, (char*)vinfo,
+ sizeof(XVisualInfo));
+ return (1);
+}
+
+
+/************************************************************************
+ * *
+ * PUBLIC ROUTINES *
+ * *
+ ************************************************************************/
+
+/*
+ * NAME
+ * LoadSCCData - Read and store the screen data
+ *
+ * SYNOPSIS
+ */
+int
+LoadSCCData(Display *pDpy, int screenNumber, char *filename, int targetFormat)
+
+/*
+ * DESCRIPTION
+ * Using the X Device Color Characterization Convention (XDCCC)
+ * read the screen data and store it on the root window of the
+ * screen.
+ *
+ * RETURNS
+ * Returns 0 if failed; otherwise 1.
+ *
+ */
+{
+ FILE *stream;
+ char *pStr;
+ char buf[BUFSIZ];
+ char *keyword, *token1, *token2, *token3;
+ int state = 0;
+ int VisualFlag = -2;
+ Window root;
+ XDCCC_Matrix matrix;
+ XDCCC_Correction* CorrectionTail = (XDCCC_Correction*)NULL;
+ XDCCC_Correction* CorrectionHead = (XDCCC_Correction*)NULL;
+ XDCCC_Correction* pCurrent;
+
+ if (screenNumber < 0) {
+ fprintf(stderr,"Invalid Screen Number %d\n", screenNumber);
+ return(0);
+ }
+ root = RootWindow(pDpy, screenNumber);
+
+ if (!root) {
+ /* if no root window is available then return an error */
+ fprintf(stderr,"Could not open root window supplied.\n ");
+ return (0);
+ }
+ /*
+ * Open the file, determine its size, then read it into memory.
+ */
+ if (filename == NULL) {
+ stream = stdin;
+ filename = "stdin";
+ } else if ((stream = fopen(filename, "r")) == NULL) {
+ fprintf(stderr,"Could not open file %s.\n", filename);
+ return (0);
+ }
+
+ /*
+ * Advance to starting keyword
+ * Anything before this keyword is just treated as comments.
+ */
+
+ while((pStr = nextline(buf, BUFSIZ, stream)) != NULL) {
+ keyword = strtok(buf, DATA_DELIMS);
+ if (keyword != (char *)NULL &&
+ (strcmp(keyword, SC_BEGIN_KEYWORD) == 0)) {
+ break;
+ } /* else ignore the line */
+ }
+
+ if (pStr == NULL) {
+ fprintf(stderr,"File %s is missing %s\n", filename, SC_BEGIN_KEYWORD);
+ closeS (stream, CorrectionHead);
+ return (0);
+ }
+
+ token1 = strtok((char*)NULL, DATA_DELIMS);
+ if ((strcmp(token1, TXT_FORMAT_VERSION) != 0) &&
+ (strcmp(token1, "0.3") != 0)) {
+ fprintf(stderr,
+ "Screen data format version mismatch in file %s-- expected %s, found %s\n",
+ filename, TXT_FORMAT_VERSION, token1);
+ closeS (stream, CorrectionHead);
+ return (0);
+ }
+
+ while ((pStr = nextline(buf, BUFSIZ, stream)) != NULL) {
+ token1 = token2 = token3 = (char*)NULL;
+ keyword = strtok(buf, DATA_DELIMS);
+ if (keyword != (char*)NULL) {
+ switch (SCKeyOf(keyword)) {
+ case COMMENT :
+ case NAME :
+ case PART_NUMBER :
+ case MODEL :
+ case SERIAL_NUMBER :
+ case REVISION :
+ /* Do nothing */
+ break;
+ case SCREEN_CLASS :
+ token1 = strtok((char*)NULL, DATA_DELIMS);
+ token2 = strtok((char*)NULL, DATA_DELIMS);
+ if ((token1 == (char*)NULL)
+ || ((VisualFlag = SCScrnClassOf(token1)) == -1)) {
+ closeS (stream, CorrectionHead);
+ return (0);
+ }
+ /*include code to handle screen number input*/
+ if (token2 != (char*)NULL) {
+ screenNumber = atoi(token2);
+
+ if (screenNumber < 0) {
+ fprintf(stderr,"Invalid Screen Number %d\n",
+ screenNumber);
+ }
+ else {
+ root = RootWindow(pDpy, screenNumber);
+ if (!root) {
+ /* if no root window is available then return an error */
+ fprintf(stderr,
+ "Could not open root window supplied.\n ");
+ return (0);
+ }
+ }
+ }
+ break;
+ case COLORIMETRIC_BEGIN :
+ if (VisualFlag == -2) {
+ closeS (stream, CorrectionHead);
+ return (0);
+ }
+ if (!ProcessColorimetric(stream,
+ &matrix, VisualFlag)) {
+ closeS (stream, CorrectionHead);
+ return (0);
+ }
+ state |= 0x02;
+ break;
+ case IPROFILE_BEGIN :
+ if (VisualFlag == -2) {
+ closeS (stream, CorrectionHead);
+ return (0);
+ }
+ token1 = strtok((char*)NULL, DATA_DELIMS);
+ token2 = strtok((char*)NULL, DATA_DELIMS);
+ if ((token1 == (char*)NULL) || (token2 == (char*)NULL)) {
+ fprintf(stderr,
+ "Line %d: Intensity profile missing TableType and/or nTables.",
+ linenum);
+ closeS (stream, CorrectionHead);
+ return (0);
+ }
+
+ if ((pCurrent = (XDCCC_Correction *)
+ calloc(1, sizeof(XDCCC_Correction))) ==NULL) {
+ fprintf(stderr,
+ "Line %d: Could not allocate memory for intensity profile.",
+ linenum);
+ closeS (stream, CorrectionHead);
+ return (0);
+ }
+
+ if (sscanf(token1, "%d", &pCurrent->tableType) != 1 ||
+ (pCurrent->tableType < 0 || pCurrent->tableType > 1)) {
+ fprintf(stderr,
+ "Line %d: invalid table type specified -- %s\n",
+ linenum, buf);
+ closeS (stream, CorrectionHead);
+ return (0);
+ }
+
+ if ((VisualFlag == VIDEO_RGB) && (token2 == (char *)NULL)) {
+ fprintf(stderr,
+ "Line %d: invalid number of tables specified -- %s\n",
+ linenum, buf);
+ closeS (stream, CorrectionHead);
+ return (0);
+ }
+
+ if (VisualFlag == VIDEO_RGB) {
+ if (sscanf(token2, "%d", &pCurrent->nTables) != 1 ||
+ (pCurrent->nTables != 0 && pCurrent->nTables != 1
+ && pCurrent->nTables != 3)) {
+ fprintf(stderr,
+ "Line %d: invalid number of tables (must be 0, 1, or 3)\n",
+ linenum);
+ closeS (stream, CorrectionHead);
+ return (0);
+ }
+ } else {
+ pCurrent->nTables = 0;
+ }
+
+ token3 = strtok((char*)NULL, "\n");
+ if (token3 != (char*)NULL) {
+ if (!ParseVisualOptions(pDpy, pCurrent, token3)) {
+ goto ByPassThisIProfile;
+ }
+ }
+
+ switch (pCurrent->nTables) {
+ case 3 :
+ if (!(pCurrent->pRedTbl = (IntensityTbl *)
+ calloc (1, sizeof (IntensityTbl)))) {
+ fprintf(stderr,
+ "Line %d: Could not allocate Red Intensity Table\n",
+ linenum);
+ closeS (stream, CorrectionHead);
+ return (0);
+ }
+ if (!(pCurrent->pGreenTbl = (IntensityTbl *)
+ calloc (1, sizeof (IntensityTbl)))) {
+ fprintf(stderr,
+ "Line %d: Could not allocate Green Intensity Table\n",
+ linenum);
+ closeS (stream, CorrectionHead);
+ return (0);
+ }
+ if (!(pCurrent->pBlueTbl = (IntensityTbl *)
+ calloc (1, sizeof (IntensityTbl)))) {
+ fprintf(stderr,
+ "Line %d: Could not allocate Blue Intensity Table",
+ linenum);
+ closeS (stream, CorrectionHead);
+ return (0);
+ }
+ if (!ProcessIProfile(stream, pCurrent)) {
+ goto ByPassThisIProfile;
+ }
+ break;
+ case 1 :
+ if (!(pCurrent->pRedTbl = (IntensityTbl *)
+ calloc (1, sizeof (IntensityTbl)))) {
+ fprintf(stderr,
+ "Line %d: Could not allocate Red Intensity Table",
+ linenum);
+ closeS (stream, CorrectionHead);
+ return (0);
+ }
+ pCurrent->pGreenTbl = pCurrent->pRedTbl;
+ pCurrent->pBlueTbl = pCurrent->pRedTbl;
+ if (!ProcessIProfile(stream, pCurrent)) {
+ goto ByPassThisIProfile;
+ }
+ break;
+ default :
+ /* do nothing */
+ break;
+ }
+
+ if (CorrectionHead == NULL) {
+ CorrectionHead = CorrectionTail = pCurrent;
+ } else {
+ CorrectionTail->next = pCurrent;
+ CorrectionTail = pCurrent;
+ }
+ state |= 0x04;
+ break;
+ByPassThisIProfile:
+ /* read till INTENSITY_PROFILE_END */
+ while ((pStr = nextline(buf, BUFSIZ, stream)) != NULL) {
+ keyword = strtok(buf, DATA_DELIMS);
+ if (keyword != (char*)NULL) {
+ switch (SCKeyOf(keyword)) {
+ case ITBL_BEGIN:
+ case ITBL_END:
+ case COMMENT:
+ case DATA:
+ break;
+ case IPROFILE_END:
+ goto IProfileProcessed;
+ default:
+ closeS (stream, CorrectionHead);
+ return (0);
+ }
+ }
+ }
+ free(pCurrent);
+IProfileProcessed:
+ state |= 0x04;
+ break;
+ case SC_END :
+ if (!(state & 0x02)) {
+ fprintf(stderr,
+ "File %s is missing Colorimetric data.\n",
+ filename);
+ closeS (stream, CorrectionHead);
+ return (0);
+ }
+ if (!(state & 0x04)) {
+ fprintf(stderr,
+ "File %s is missing Intensity Profile Data.\n",
+ filename);
+ }
+ if (VisualFlag == VIDEO_RGB) {
+ LoadMatrix(pDpy, root, &matrix);
+ if (!LoadCorrections(pDpy, root, CorrectionHead,
+ targetFormat)) {
+ closeS (stream, CorrectionHead);
+ return (0);
+ }
+#ifdef GRAY
+ } else if (VisualFlag == VIDEO_GRAY) {
+ if (!LoadDataGray(pDpy, root,
+ pCurrent->tableType, pScreenData, targetFormat)) {
+ closeS (stream, CorrectionHead);
+ return (0);
+ }
+#endif /* GRAY */
+ } else {
+ fprintf(stderr,"File %s Visual missing.", filename);
+ }
+ closeS (stream, CorrectionHead);
+ return (1);
+/* NOTREACHED */ break;
+ default :
+ fprintf(stderr,"Line %d: extraneous keyword %s\n",
+ linenum, keyword);
+ closeS (stream, CorrectionHead);
+ return (0);
+
+ }
+ } /* else it was just a blank line */
+ }
+ closeS (stream, CorrectionHead);
+ return (1);
+}