1 /* $Xorg: loadData.c,v 1.4 2000/08/17 19:54:13 cpqbld Exp $ */
2 
3 /*
4  * (c) Copyright 1990 Tektronix Inc.
5  * 	All Rights Reserved
6  *
7  * Permission to use, copy, modify, and distribute this software and its
8  * documentation for any purpose and without fee is hereby granted,
9  * provided that the above copyright notice appear in all copies and that
10  * both that copyright notice and this permission notice appear in
11  * supporting documentation, and that the name of Tektronix not be used
12  * in advertising or publicity pertaining to distribution of the software
13  * without specific, written prior permission.
14  *
15  * Tektronix disclaims all warranties with regard to this software, including
16  * all implied warranties of merchantability and fitness, in no event shall
17  * Tektronix be liable for any special, indirect or consequential damages or
18  * any damages whatsoever resulting from loss of use, data or profits,
19  * whether in an action of contract, negligence or other tortious action,
20  * arising out of or in connection with the use or performance of this
21  * software.
22  *
23  *
24  *	NAME
25  *		LoadSCCData.c
26  *
27  *	DESCRIPTION
28  *		TekCMS API routine that reads screen data from a file
29  *	        and then loads the data on the root window of the screen.
30  *
31  *
32  *
33  */
34 /* $XFree86: xc/programs/xcmsdb/loadData.c,v 3.3 2001/07/25 15:05:18 dawes Exp $ */
35 
36 /*
37  *      INCLUDES
38  */
39 
40 #include <X11/Xos.h>
41 #include <sys/stat.h>
42 #include <stdio.h>
43 
44 #include <X11/Xlib.h>
45 #include <X11/Xatom.h>
46 #include "SCCDFile.h"
47 
48 
49 /*
50  *      EXTERNS
51  *              External declarations required locally to this package
52  *              that are not already declared in any of the included header
53  *		files (external includes or internal includes).
54  */
55 
56 #include <stdlib.h>
57 
58 /*
59  *      LOCAL TYPEDEFS
60  *              typedefs local to this package (for use with local vars).
61  *
62  */
63 
64 typedef struct _DefineEntry {
65     const char	*pString;
66     int		define;
67 } DefineEntry;
68 
69 
70 /*
71  *      LOCAL VARIABLES
72  */
73 static int linenum = 0;
74 
75 static DefineEntry KeyTbl[] = {
76     { SC_BEGIN_KEYWORD,			SC_BEGIN },
77     { SC_END_KEYWORD,			SC_END },
78     { COMMENT_KEYWORD,			COMMENT },
79     { NAME_KEYWORD,			NAME },
80     { MODEL_KEYWORD,			MODEL },
81     { PART_NUMBER_KEYWORD,		PART_NUMBER },
82     { SERIAL_NUMBER_KEYWORD,		SERIAL_NUMBER },
83     { REVISION_KEYWORD,			REVISION },
84     { SCREEN_CLASS_KEYWORD,		SCREEN_CLASS },
85     { COLORIMETRIC_BEGIN_KEYWORD,	COLORIMETRIC_BEGIN },
86     { COLORIMETRIC_END_KEYWORD,		COLORIMETRIC_END },
87     { XYZTORGBMAT_BEGIN_KEYWORD,	XYZTORGBMAT_BEGIN },
88     { XYZTORGBMAT_END_KEYWORD,		XYZTORGBMAT_END },
89     { WHITEPT_XYZ_BEGIN_KEYWORD,	WHITEPT_XYZ_BEGIN },
90     { WHITEPT_XYZ_END_KEYWORD,		WHITEPT_XYZ_END },
91     { RGBTOXYZMAT_BEGIN_KEYWORD,	RGBTOXYZMAT_BEGIN },
92     { RGBTOXYZMAT_END_KEYWORD,		RGBTOXYZMAT_END },
93     { IPROFILE_BEGIN_KEYWORD,		IPROFILE_BEGIN },
94     { IPROFILE_END_KEYWORD,		IPROFILE_END },
95     { ITBL_BEGIN_KEYWORD,		ITBL_BEGIN },
96     { ITBL_END_KEYWORD,			ITBL_END },
97     { "",				-1 }
98 };
99 
100 static DefineEntry ScrnClassTbl[] = {
101     { VIDEO_RGB_KEYWORD,		VIDEO_RGB },
102 #ifdef GRAY
103     { VIDEO_GRAY_KEYWORD,		VIDEO_GRAY },
104 #endif /* GRAY */
105     { "",				-1 }
106 };
107 
108 #define KEY_VISUALID		1
109 #define KEY_DEPTH		2
110 #define KEY_CLASS		3
111 #define KEY_RED_MASK		4
112 #define KEY_GREEN_MASK		5
113 #define KEY_BLUE_MASK		6
114 #define KEY_COLORMAP_SIZE	7
115 #define KEY_BITS_PER_RGB	8
116 
117 static DefineEntry VisualOptKeyTbl[] = {
118     { "visualid",		KEY_VISUALID },
119     { "depth",			KEY_DEPTH },
120     { "class",			KEY_CLASS },
121     { "red_mask",		KEY_RED_MASK },
122     { "green_mask",		KEY_GREEN_MASK },
123     { "blue_mask",		KEY_BLUE_MASK },
124     { "colormap_size",		KEY_COLORMAP_SIZE },
125     { "bits_per_rgb",		KEY_BITS_PER_RGB },
126     { "",				-1 }
127 };
128 static DefineEntry VisualClassTbl[] = {
129     { "StaticGray",		StaticGray },
130     { "GrayScale",		GrayScale },
131     { "StaticColor",		StaticColor },
132     { "PseudoColor",		PseudoColor },
133     { "TrueColor",		TrueColor },
134     { "DirectColor",		DirectColor },
135     { "",				-1 }
136 };
137 
138 
139 /************************************************************************
140  *									*
141  *			 PRIVATE ROUTINES				*
142  *									*
143  ************************************************************************/
144 
145 /*
146  *	NAME
147  *		StrToDefine - convert a string to a define
148  *
149  *	SYNOPSIS
150  */
151 static int
StrToDefine(DefineEntry pde[],const char * pstring)152 StrToDefine(DefineEntry pde[],	/* IN: table of X string-define pairs     */
153 				/*     last entry must contain pair "", 0 */
154 	   const char *pstring)	/* IN: string to be looked up in that table */
155 /*
156  *	DESCRIPTION
157  *		Converts a string to an integer define.
158  *
159  *		Looks up the string in the table and returns the integer
160  *		associated with the string.
161  *
162  *		Later may need similar function for unsigned long define.
163  *
164  *
165  *
166  *	RETURNS
167  *		The int equivalent of the defined string.
168  *		-1 if the string is not found in table
169  *
170  */
171 {
172     while( strcmp(pde->pString,"") != 0 ){
173 	if( strcmp(pde->pString,pstring) == 0){
174 	    return(pde->define);
175 	}
176 	pde++;
177     }
178     return(-1);
179 }
180 
181 /*
182  *	NAME
183  *		DefineToStr
184  *
185  *	SYNOPSIS
186  */
187 static const char *
DefineToStr(DefineEntry pde[],int id)188 DefineToStr(DefineEntry pde[],	/* IN: table of X string-define pairs */
189 				/*     last entry must contain pair "", 0 */
190 	    int id)		/* IN: id to be looked up in that table	*/
191 /*
192  *	DESCRIPTION
193  *		Converts a string to an integer define.
194  *
195  *		Looks up the string in the table and returns the integer
196  *		associated with the string.
197  *
198  *		Later may need similar function for unsigned long define.
199  *
200  *
201  *
202  *	RETURNS
203  *		The int equivalent of the defined string.
204  *		-1 if the string is not found in table
205  *
206  */
207 {
208     while(pde->define != -1) {
209 	if (pde->define == id) {
210 	    return(pde->pString);
211 	}
212 	pde++;
213     }
214     return(NULL);
215 }
216 
217 /*
218  *	NAME
219  *		SCKeyOf - convert keyword into key ID
220  *
221  *	SYNOPSIS
222  */
223 static int
SCKeyOf(const char * string)224 SCKeyOf(const char *string)
225 /*
226  *	DESCRIPTION
227  *		Converts a string to an integer define.
228  *
229  *		Looks up the string in the table and returns the integer
230  *		associated with the string.
231  *
232  *		Later may need similar function for unsigned long define.
233  *
234  *
235  *
236  *	RETURNS
237  *		The int equivalent of the defined string.
238  *		-1 if the string is not found in table
239  *
240  */
241 {
242     return(StrToDefine(KeyTbl, string));
243 }
244 
245 
246 /*
247  *	NAME
248  *		SCScrnClassOf - convert screen class string into class ID
249  *
250  *	SYNOPSIS
251  */
252 static int
SCScrnClassOf(const char * string)253 SCScrnClassOf(const char *string)
254 /*
255  *	DESCRIPTION
256  *		Converts a string to an integer define.
257  *
258  *		Looks up the string in the table and returns the integer
259  *		associated with the string.
260  *
261  *		Later may need similar function for unsigned long define.
262  *
263  *
264  *
265  *	RETURNS
266  *		The int equivalent of the defined string.
267  *		-1 if the string is not found in table
268  *
269  */
270 {
271     return(StrToDefine(ScrnClassTbl, string));
272 }
273 
274 
275 /*
276  *	NAME
277  *		SCScrnClassStringOf - convert screen class id into class string
278  *
279  *	SYNOPSIS
280  */
281 static const char *
SCScrnClassStringOf(int id)282 SCScrnClassStringOf(int id)
283 /*
284  *	DESCRIPTION
285  *		Converts a id to astring
286  *
287  *	RETURNS
288  *		Pointer to string if found; otherwise NULL.
289  *
290  */
291 {
292     return(DefineToStr(ScrnClassTbl, id));
293 }
294 
295 /* close the stream and return any memory allocated. */
296 /*ARGSUSED*/
297 static void
closeS(FILE * stream,XDCCC_Correction * pCorrection)298 closeS(FILE *stream, XDCCC_Correction *pCorrection)
299 {
300     XDCCC_Correction* pNext;
301     if (stream) {
302         fclose (stream);
303     }
304     while (pCorrection) {
305 	pNext = pCorrection->next;
306 	free(pCorrection);
307 	pCorrection = pNext;
308     }
309 }
310 
311 /*
312  *  Get a line of text from the stream.
313  */
314 static char *
nextline(char * buf,int maxch,FILE * stream)315 nextline(char *buf, int maxch, FILE *stream)
316 {
317     linenum++;
318     return (fgets(buf, maxch, stream));
319 }
320 
321 
322 static int
ProcessColorimetric(FILE * stream,XDCCC_Matrix * pMatrix,int VisualFlag)323 ProcessColorimetric(FILE *stream, XDCCC_Matrix *pMatrix, int VisualFlag)
324 {
325     char buf[BUFSIZ];
326     char keyword[BUFSIZ];
327     char token[BUFSIZ], *ptoken;
328     int  ntok;
329     unsigned int matrices_processed = 0;
330 		/* bit 0 for XYZtoRGB matrix */
331 		/* bit 1 for RGBtoXYZ matrix */
332     int	 state = 0;
333 		 /* 0 -- looking for matrix */
334 		 /* 1 -- processing data from matrix */
335 		 /* 2 -- both matrices processed */
336 		 /* Note: the order of the matrices is not important. */
337     int	 count = -1;
338     XcmsFloat *pElement = NULL;
339 
340     while ((nextline(buf, BUFSIZ, stream)) != NULL) {
341 	if ((ntok = sscanf(buf, "%s %s", keyword, token)) > 0) {
342 	    switch (SCKeyOf(keyword)) {
343 	      case XYZTORGBMAT_BEGIN :
344 		if (VisualFlag != VIDEO_RGB) {
345 		  fprintf(stderr,
346 			 "Line %d: Keyword XYZTORGBMAT_BEGIN mismatch for visual %s.\n",
347 			  linenum, SCScrnClassStringOf(VisualFlag));
348 		  return (0);
349 		}
350 		if (state != 0) {
351 		  fprintf(stderr,
352 			  "Line %d: Extraneous keyword %s.\n",
353 			  linenum, keyword);
354 		  return (0);
355 		}
356 		state = 1;
357 		count = 0;
358 		pElement = (XcmsFloat *) pMatrix->XYZtoRGBmatrix;
359 		break;
360 	      case XYZTORGBMAT_END :
361 		if (VisualFlag != VIDEO_RGB) {
362 		  fprintf(stderr,
363 			  "Line %d: Keyword XYZTORGBMAT_END mismatch for visual %s.\n",
364 			  linenum, SCScrnClassStringOf(VisualFlag));
365 		  return (0);
366 		}
367 		if ((state != 1) || (count != 9)) {
368 		  fprintf(stderr,
369 			  "Line %d: Incomplete XYZtoRGB matrix -- Premature %s\n",
370 			  linenum, keyword);
371 		  return (0);
372 		}
373 		matrices_processed |= 0x1;
374 		if (matrices_processed == 3) {
375 		    state = 2;
376 		} else {
377 		    state = 0;
378 		}
379 		break;
380 	      case RGBTOXYZMAT_BEGIN :
381 		if (VisualFlag != VIDEO_RGB) {
382 		  fprintf(stderr,
383 			 "Line %d: Keyword RGBTOXYZMAT_BEGIN mismatch for visual %s.\n",
384 			  linenum, SCScrnClassStringOf(VisualFlag));
385 		  return (0);
386 		}
387 		if (state != 0) {
388 		    fprintf(stderr, "Line %d: Extraneous keyword %s.\n",
389 			    linenum, keyword);
390 		    return (0);
391 		}
392 		state = 1;
393 		count = 0;
394 		pElement = (XcmsFloat *) pMatrix->RGBtoXYZmatrix;
395 		break;
396 	      case RGBTOXYZMAT_END :
397 		if (VisualFlag != VIDEO_RGB) {
398 		    fprintf(stderr,
399 			   "Line %d: Keyword RGBTOXYZMAT_END mismatch for visual %s.\n",
400 			    linenum, SCScrnClassStringOf(VisualFlag));
401 		    return (0);
402 		}
403 		if ((state != 1) || (count != 9)) {
404 		    fprintf(stderr,
405 			   "Line %d: Incomplete RGBtoXYZ matrix -- Premature %s\n",
406 			    linenum, keyword);
407 		    return (0);
408 		}
409 		matrices_processed |= 0x2;
410 		if (matrices_processed == 3) {
411 		    state = 2;
412 		} else {
413 		    state = 0;
414 		}
415 		break;
416 #ifdef GRAY
417 	      case WHITEPT_XYZ_BEGIN :
418 		if (VisualFlag != VIDEO_GRAY) {
419 		    fprintf(stderr,
420 			 "Line %d: Keyword WHITEPT_XYZ_BEGIN mismatch for visual %s.\n",
421 			    linenum, SCScrnClassStringOf(VisualFlag));
422 		    return (0);
423 		}
424 		if (state != 0) {
425 		  fprintf(stderr,
426 			  "Line %d: Extraneous keyword %s.\n",
427 			  linenum, keyword);
428 		  return (0);
429 		}
430 		state = 1;
431 		count = 0;
432 		pElement = (XcmsFloat *) pMatrix->XYZtoRGBmatrix;
433 		break;
434 	      case WHITEPT_XYZ_END :
435 		if (VisualFlag != VIDEO_GRAY) {
436 		    fprintf(stderr,
437 			   "Line %d: Keyword WHITEPT_XYZ_END mismatch for visual %s.\n",
438 			    linenum, SCScrnClassStringOf(VisualFlag));
439 		    return (0);
440 		}
441 		if ((state != 1) || (count != 3)) {
442 		    fprintf(stderr,
443 			"Line %d: Incomplete white point -- Premature %s\n",
444 			    linenum, keyword);
445 		    return (0);
446 		}
447 		state = 2;
448 		break;
449 #endif /* GRAY */
450 	      case DATA :
451 		for (ptoken = strtok(buf, DATA_DELIMS); ptoken != NULL;
452 			ptoken = strtok(NULL, DATA_DELIMS)) {
453 		    if (sscanf(ptoken, "%lf", pElement) != 1) {
454 			if (VisualFlag == VIDEO_RGB) {
455 			    fprintf(stderr,
456 				    "Line %d: Invalid matrix value %s.",
457 				    linenum, ptoken);
458 			} else {
459 			    fprintf(stderr,
460 				    "Line %d: Invalid CIEXYZ value %s.\n",
461 				    linenum, ptoken);
462 			}
463 			return (0);
464 		    }
465 		    pElement++;
466 		    if (VisualFlag == VIDEO_RGB) {
467 			if (++count > 9) {
468 			    fprintf(stderr,
469 				   "Line %d: Extra matrix value %s\n",
470 				    linenum, ptoken);
471 			    return (0);
472 			}
473 		    } else {
474 			if (++count > 3) {
475 			    fprintf(stderr,
476 				    "Line %d: Extra CIEXYZ value %s.\n",
477 				    linenum, ptoken);
478 			    return (0);
479 			  }
480 		    }
481 		}
482 		break;
483 	      case COLORIMETRIC_BEGIN :
484 		fprintf(stderr,
485 			"Line %d: Extraneous keyword %s.\n",
486 			linenum, keyword);
487 		return (0);
488 	      case COLORIMETRIC_END :
489 		if (state != 2) {
490 		    fprintf(stderr,
491 		   "Line %d: Incomplete Colorimetric data -- Premature %s\n",
492 			    linenum, keyword);
493 		    return (0);
494 		}
495 		return (1);
496 	      case COMMENT :
497 		/* Currently, do nothing. */
498 		break;
499 	      default :
500 		fprintf(stderr,
501 			"Line %d: Unexpected keyword %s\n",
502 			linenum, keyword);
503 		return (0);
504 	    }
505 	} else if (ntok < 0) {
506 	    /* mismatch */
507 	    fprintf(stderr, "Line %d: Unrecognized keyword\n", linenum);
508 	    return (0);
509 	}
510     }
511     return (0);
512 }
513 
514 static int
ProcessIProfile(FILE * stream,XDCCC_Correction * pCorrection)515 ProcessIProfile(FILE *stream, XDCCC_Correction *pCorrection)
516 {
517     char buf[BUFSIZ];
518     char *keyword;
519     char *tableStr, *sizeStr, *ptoken;
520     int  size;
521     int	 state = 0;
522 	 /************************************************
523 	  * 0 -- Looking for Intensity Table(s)          *
524 	  * 1 -- Processing Intensity Table(s)           *
525           ************************************************/
526     int	 nTbl = 0;
527     int	 count = 0;
528     IntensityRec *pIRec = NULL;
529 
530     while ((nextline(buf, BUFSIZ, stream)) != NULL) {
531 	ptoken = keyword = strtok(buf, DATA_DELIMS);
532 	if (keyword != (char*)NULL) {
533 	    switch (SCKeyOf(keyword)) {
534 	      case ITBL_BEGIN :
535 		if (state != 0) {
536 		    fprintf(stderr,"Line %d: unexpected keyword %s\n",
537 			   linenum, keyword);
538 		    return (0);
539 		}
540 		tableStr = strtok((char*)NULL, DATA_DELIMS);
541 		sizeStr = strtok((char*)NULL, DATA_DELIMS);
542 		if ((sizeStr == (char*)NULL) ||
543 			sscanf(sizeStr, "%d", &size) != 1) {
544 		    fprintf(stderr,
545 			    "Line %d: invalid Intensity Table size, %s.\n",
546 			      linenum, sizeStr);
547 		    return (0);
548 		}
549 		if (size < 0) {
550 		    fprintf(stderr,
551 			    "Line %d: count %d < 0 for Intensity Table.\n",
552 			      linenum, size);
553 		    return (0);
554 		}
555 		if (strcmp(tableStr, "GREEN") == 0) {
556 		    if (pCorrection->nTables != 3) {
557 			fprintf(stderr,"Line %d: incorrect number of tables\n",
558 			linenum);
559 			return (0);
560 		    }
561 		    if (pCorrection->pGreenTbl->pBase != NULL) {
562 			fprintf(stderr,
563 			     "Line %d: multiple GREEN Intensity Profiles\n",
564 			           linenum);
565 			return (0);
566 		    }
567 		    pCorrection->pGreenTbl->nEntries = size;
568 		    pCorrection->pGreenTbl->pBase =
569 			 (IntensityRec *) calloc (size, sizeof(IntensityRec));
570 		    if (!pCorrection->pGreenTbl->pBase) {
571 			fprintf(stderr,
572 		     "Line %d: Unable to allocate space for GREEN Intensity Profile\n", linenum);
573 			return (0);
574 		    }
575 		    pIRec = pCorrection->pGreenTbl->pBase;
576 		} else if (strcmp(tableStr, "BLUE") == 0) {
577 		    if (pCorrection->nTables != 3) {
578 			fprintf(stderr,
579 				"Line %d: incorrect number of tables\n",
580 				linenum);
581 			return (0);
582 		    }
583 		    if (pCorrection->pBlueTbl->pBase != NULL) {
584 			fprintf(stderr,
585 			      "Line %d: multiple BLUE Intensity Profiles\n",
586 			           linenum);
587 			return (0);
588 		    }
589 		    pCorrection->pBlueTbl->nEntries = size;
590 		    pCorrection->pBlueTbl->pBase =
591 			 (IntensityRec *) calloc (size, sizeof(IntensityRec));
592 		    if (!pCorrection->pBlueTbl->pBase) {
593 			fprintf(stderr,
594 		      "Line %d: Unable to allocate space for BLUE Intensity Profile\n", linenum);
595 			return (0);
596 		    }
597 		    pIRec = pCorrection->pBlueTbl->pBase;
598 		} else {
599 		    if (!strcmp(tableStr, "RGB") && pCorrection->nTables != 1) {
600 			fprintf(stderr,"Line %d: multiple RGB Intensity Tables",
601 			      linenum);
602 			return (0);
603 		    }
604 		    if (pCorrection->pRedTbl->pBase != NULL) {
605 			fprintf(stderr,
606 		  "Line %d: multiple RED or GREEN or BLUE Intensity Tables\n",
607 				   linenum);
608 			return (0);
609 		    }
610 		    pCorrection->pRedTbl->nEntries = size;
611 		    pCorrection->pRedTbl->pBase =
612 			 (IntensityRec *) calloc (size, sizeof(IntensityRec));
613 		    if (!pCorrection->pRedTbl->pBase) {
614 			fprintf(stderr,
615 			     "Line %d: Unable to allocate space for intensity table\n", linenum);
616 			return (0);
617 		    }
618 		    pIRec = pCorrection->pRedTbl->pBase;
619 		}
620 		state = 1;
621 		count = 0;
622 		break;
623 	      case ITBL_END :
624 		if ((state != 1) || (count != size)) {
625 		    fprintf(stderr,
626 		    "Line %d: incomplete Intensity Table -- Premature %s\n",
627 			  linenum, keyword);
628 		    return (0);
629 		}
630 		nTbl++;
631 		state = 0;
632 		break;
633 	      case DATA :
634 		if(pIRec == NULL) {
635 		    fprintf(stderr, "Line %d: Invalid Intensity Profile -- Premature %s\n",
636 		            linenum, keyword);
637 		    return (0);
638 		}
639 		do {
640 		    /********************************************************
641 		     * Note: tableType should only be 0 or 1 at this point.
642 		     *       0 indicates value and intensity stored.
643 		     *       1 indicates only intensity stored.
644 		     ********************************************************/
645 		    if (pCorrection->tableType) {
646 			if (sscanf(ptoken, "%lf", &pIRec->intensity) != 1) {
647 			    fprintf(stderr,
648 			   "Line %d: invalid Intensity Profile value %s\n",
649 				  linenum, ptoken);
650 			    return (0);
651 			}
652 			/* With tableType 1 only store the intensity. */
653 			pIRec++;
654 		    } else {
655 			short tmp;
656 			/* Note ansi C can handle 0x preceeding hex number */
657 			if (sscanf(ptoken, "%hi", &tmp) != 1) {
658 			    fprintf(stderr,
659 			    "Line %d: invalid Intensity Profile value %s\n",
660 				  linenum, ptoken);
661 			    return (0);
662 			} else
663 			    pIRec->value = tmp;
664 			if ((ptoken = strtok(NULL, DATA_DELIMS)) == NULL) {
665 			    fprintf(stderr,
666 				  "Line %d: missing Intensity Profile value\n",
667 				  linenum);
668 			    return (0);
669 			}
670 			if (sscanf(ptoken, "%lf", &pIRec->intensity) != 1) {
671 			    fprintf(stderr,
672 			"Line %d: invalid Intensity Profile intensity %s\n",
673 				  linenum, ptoken);
674 			    return (0);
675 			}
676 			/* With tableType 0 only store both value & intensity*/
677 			pIRec++;
678 		    }
679 		    if (++count > size) {
680 			fprintf(stderr,
681 				"Line %d: extra Intensity value %s\n",
682 				linenum, ptoken);
683 			return (0);
684 		    }
685 		    ptoken = strtok(NULL, DATA_DELIMS);
686 		} while(ptoken != NULL);
687 		break;
688 	      case IPROFILE_BEGIN :
689 		fprintf(stderr,"Line %d: extraneous keyword %s\n",
690 			  linenum, keyword);
691 		return (0);
692 	      case IPROFILE_END :
693 		if ((state != 0) || (nTbl != pCorrection->nTables)) {
694 		    fprintf(stderr,
695 	     "Line %d: incomplete Intensity Profile data -- Premature %s\n",
696 			   linenum, keyword);
697 		    return (0);
698 		}
699 		return (1);
700 	      case COMMENT :
701 		/* ignore line */
702 		break;
703 	      default :
704 		fprintf(stderr,"Line %d: unexpected keyword %s\n",
705 		      linenum, keyword);
706 		return (0);
707 	    }
708 	} /* else its was just a blank line */
709     }
710     return (0);
711 }
712 
713 static void
PutTableType0Card8(IntensityTbl * pTbl,unsigned char ** pCard8)714 PutTableType0Card8(IntensityTbl *pTbl, unsigned char **pCard8)
715 {
716     unsigned int count;
717     IntensityRec *pIRec;
718 
719     pIRec = pTbl->pBase;
720     count = pTbl->nEntries;
721     **pCard8 = count - 1;
722     *pCard8 += 1;
723     for (; count; count--, pIRec++) {
724 	**pCard8 = pIRec->value >> 8;
725 	*pCard8 += 1;
726 	**pCard8 = pIRec->intensity * 255.0;
727 	*pCard8 += 1;
728     }
729 }
730 
731 static void
PutTableType1Card8(IntensityTbl * pTbl,unsigned char ** pCard8)732 PutTableType1Card8(IntensityTbl *pTbl, unsigned char **pCard8)
733 {
734     unsigned int count;
735     IntensityRec *pIRec;
736 
737     pIRec = pTbl->pBase;
738     count = pTbl->nEntries;
739     **pCard8 = count - 1;
740     *pCard8 += 1;
741     for (; count; count--, pIRec++) {
742 	**pCard8 = pIRec->intensity * 255.0;
743 	*pCard8 += 1;
744     }
745 }
746 
747 static void
PutTableType0Card16(IntensityTbl * pTbl,unsigned short ** pCard16)748 PutTableType0Card16(IntensityTbl *pTbl, unsigned short **pCard16)
749 {
750     unsigned int count;
751     IntensityRec *pIRec;
752 
753     pIRec = pTbl->pBase;
754     count = pTbl->nEntries;
755     **pCard16 = count - 1;
756     *pCard16 += 1;
757     for (; count; count--, pIRec++) {
758 	**pCard16 = pIRec->value;
759 	*pCard16 += 1;
760 	**pCard16 = pIRec->intensity * 65535.0;
761 	*pCard16 += 1;
762     }
763 }
764 
765 static void
PutTableType1Card16(IntensityTbl * pTbl,unsigned short ** pCard16)766 PutTableType1Card16(IntensityTbl *pTbl, unsigned short **pCard16)
767 {
768     unsigned int count;
769     IntensityRec *pIRec;
770 
771     pIRec = pTbl->pBase;
772     count = pTbl->nEntries;
773     **pCard16 = count - 1;
774     *pCard16 += 1;
775     for (; count; count--, pIRec++) {
776 	**pCard16 = pIRec->intensity * 65535.0;
777 	*pCard16 += 1;
778     }
779 }
780 
781 static void
PutTableType0Card32(IntensityTbl * pTbl,unsigned long ** pCard32)782 PutTableType0Card32(IntensityTbl *pTbl, unsigned long **pCard32)
783 {
784     unsigned int count;
785     IntensityRec *pIRec;
786 
787     pIRec = pTbl->pBase;
788     count = pTbl->nEntries;
789     **pCard32 = count - 1;
790     *pCard32 += 1;
791     for (; count; count--, pIRec++) {
792 	**pCard32 = pIRec->value;
793 	*pCard32 += 1;
794 	**pCard32 = pIRec->intensity * 4294967295.0;
795 	*pCard32 += 1;
796     }
797 }
798 
799 static void
PutTableType1Card32(IntensityTbl * pTbl,unsigned long ** pCard32)800 PutTableType1Card32(IntensityTbl *pTbl, unsigned long **pCard32)
801 {
802     unsigned int count;
803     IntensityRec *pIRec;
804 
805     pIRec = pTbl->pBase;
806     count = pTbl->nEntries;
807     **pCard32 = count - 1;
808     *pCard32 += 1;
809     for (; count; count--, pIRec++) {
810 	**pCard32 = pIRec->intensity * 4294967295.0;
811 	*pCard32 += 1;
812     }
813 }
814 
815 
816 static void
LoadMatrix(Display * pDpy,Window root,XDCCC_Matrix * pMatrix)817 LoadMatrix(Display *pDpy, Window root, XDCCC_Matrix *pMatrix)
818 {
819     int  count;
820     unsigned long  *pCard32;
821     unsigned long  Card32Array[18];
822     Atom MatricesAtom;
823     XcmsFloat *pValue;
824 
825     /*
826      * Store the XDCCC_LINEAR_RGB_MATRICES
827      */
828     pCard32 = Card32Array;
829     pValue = (XcmsFloat *)pMatrix->XYZtoRGBmatrix;
830     for (count = 0; count < 9; count++) {
831 	*pCard32++ = (unsigned long) (*pValue++ * (XcmsFloat) XDCCC_NUMBER);
832     }
833     pValue = (XcmsFloat *)pMatrix->RGBtoXYZmatrix;
834     for (count = 0; count < 9; count++) {
835 	*pCard32++ = (unsigned long) (*pValue++ * (XcmsFloat) XDCCC_NUMBER);
836     }
837     MatricesAtom = XInternAtom (pDpy, XDCCC_MATRIX_ATOM_NAME, False);
838     XChangeProperty (pDpy, root, MatricesAtom, XA_INTEGER, 32,
839 		     PropModeReplace, (unsigned char *)Card32Array, 18);
840 }
841 
842 
843 static int
LoadCorrections(Display * pDpy,Window root,XDCCC_Correction * pCorrection,int targetFormat)844 LoadCorrections(Display *pDpy, Window root, XDCCC_Correction *pCorrection,
845 		int targetFormat)
846 {
847     unsigned char  *pCard8;
848     unsigned char  *pCard8Array = (unsigned char *)NULL;
849     unsigned short  *pCard16;
850     unsigned short  *pCard16Array = (unsigned short *)NULL;
851     unsigned long  *pCard32;
852     unsigned long  *pCard32Array = (unsigned long *)NULL;
853     Atom CorrectAtom;
854     int	total;
855     int i;
856 
857     /*
858      * Store each XDCCC_CORRECTION into XDCCC_LINEAR_RGB_CORRECTION property
859      */
860     CorrectAtom = XInternAtom (pDpy, XDCCC_CORRECT_ATOM_NAME, False);
861 
862     for (i = 0; pCorrection; i++, pCorrection = pCorrection->next) {
863 	if ((pCorrection->tableType != 0) && (pCorrection->tableType != 1)) {
864 	    if (pCorrection->visual_info.visualid) {
865 		fprintf(stderr,"RGB Correction for visualid %ld: Invalid intensity table type %d.\n",
866 			pCorrection->visual_info.visualid,
867 			pCorrection->tableType);
868 	    } else {
869 		fprintf(stderr,"Global RGB Correction: Invalid intensity table type %d.\n",
870 			pCorrection->tableType);
871 	    }
872 	    return(0);
873 	}
874 
875 	if (pCorrection->nTables != 1 && pCorrection->nTables != 3) {
876 	    if (pCorrection->visual_info.visualid) {
877 		fprintf(stderr,"RGB Correction for visualid %ld: %d invalid number of tables.\n",
878 			pCorrection->visual_info.visualid,
879 			pCorrection->nTables);
880 	    } else {
881 		fprintf(stderr,"Global RGB Correction: %d invalid number of tables.\n",
882 			pCorrection->nTables);
883 	    }
884 	    return(0);
885 	}
886 
887 	if (pCorrection->nTables == 1) {
888 	    if (pCorrection->pRedTbl->nEntries < 2) {
889 		if (pCorrection->visual_info.visualid) {
890 		    fprintf(stderr,"RGB Correction for visualid %ld: Illegal number of entries in table\n",
891 			    pCorrection->visual_info.visualid);
892 		} else {
893 		    fprintf(stderr,"Global RGB Correction: Illegal number of entries in table\n");
894 		}
895 		return (0);
896 	    }
897 	    switch (targetFormat) {
898 	      case 8:
899 		total = 7 + (pCorrection->pRedTbl->nEntries *
900 			(pCorrection->tableType == 0 ? 2 : 1));
901 		if ((pCard8 = pCard8Array = (unsigned char *) calloc (total,
902 			sizeof (unsigned char))) == NULL) {
903 		    fprintf(stderr,"Unable allocate array of ints\n");
904 		    return (0);
905 		}
906 		*pCard8++ = (pCorrection->visual_info.visualid >> 24) & 0xFF;
907 		*pCard8++ = (pCorrection->visual_info.visualid >> 16) & 0xFF;
908 		*pCard8++ = (pCorrection->visual_info.visualid >> 8) & 0xFF;
909 		*pCard8++ = (pCorrection->visual_info.visualid) & 0xFF;
910 		*pCard8++ = pCorrection->tableType;	/* type */
911 		*pCard8++ = 1;		/* number of tables = 1 */
912 		if (pCorrection->tableType == 0) {
913 		    PutTableType0Card8(pCorrection->pRedTbl, &pCard8);
914 		} else {
915 		    PutTableType1Card8(pCorrection->pRedTbl, &pCard8);
916 		}
917 		XChangeProperty (pDpy, root, CorrectAtom, XA_INTEGER, 8,
918 			i ? PropModeAppend : PropModeReplace,
919 			(unsigned char *)pCard8Array, total);
920 		free(pCard8Array);
921 		break;
922 	      case 16:
923 		total = 5 + (pCorrection->pRedTbl->nEntries *
924 			(pCorrection->tableType == 0 ? 2 : 1));
925 		if ((pCard16 = pCard16Array = (unsigned short *) calloc (total,
926 			sizeof (unsigned short))) == NULL) {
927 		    fprintf(stderr,"Unable allocate array of ints\n");
928 		    return (0);
929 		}
930 		*pCard16++ = (pCorrection->visual_info.visualid >> 16) & 0xFFFF;
931 		*pCard16++ = (pCorrection->visual_info.visualid) & 0xFFFF;
932 		*pCard16++ = pCorrection->tableType;	/* type */
933 		*pCard16++ = 1;		/* number of tables = 1 */
934 		if (pCorrection->tableType == 0) {
935 		    PutTableType0Card16(pCorrection->pRedTbl, &pCard16);
936 		} else {
937 		    PutTableType1Card16(pCorrection->pRedTbl, &pCard16);
938 		}
939 		XChangeProperty (pDpy, root, CorrectAtom, XA_INTEGER, 16,
940 			i ? PropModeAppend : PropModeReplace,
941 			(unsigned char *)pCard16Array, total);
942 		free(pCard16Array);
943 		break;
944 	      case 32:
945 		total = 4 + (pCorrection->pRedTbl->nEntries *
946 			(pCorrection->tableType == 0 ? 2 : 1));
947 		if ((pCard32 = pCard32Array =
948 			(unsigned long *) calloc (total,
949 			sizeof (unsigned long))) == NULL) {
950 		    fprintf(stderr,"Unable allocate array of ints\n");
951 		    return (0);
952 		}
953 		*pCard32++ = pCorrection->visual_info.visualid;
954 		*pCard32++ = pCorrection->tableType;	/* type */
955 		*pCard32++ = 1;		/* number of tables = 1 */
956 		if (pCorrection->tableType == 0) {
957 		    PutTableType0Card32(pCorrection->pRedTbl, &pCard32);
958 		} else {
959 		    PutTableType1Card32(pCorrection->pRedTbl, &pCard32);
960 		}
961 		XChangeProperty (pDpy, root, CorrectAtom, XA_INTEGER, 32,
962 			i ? PropModeAppend : PropModeReplace,
963 			(unsigned char *)pCard32Array, total);
964 		free(pCard32Array);
965 		break;
966 	      default:
967 		if (pCorrection->visual_info.visualid) {
968 		    fprintf(stderr,"RGB Correction for visualid %ld: Invalid property format\n",
969 			    pCorrection->visual_info.visualid);
970 		} else {
971 		    fprintf(stderr,"Global RGB Correction: Invalid property format\n");
972 		}
973 		return (0);
974 	    }
975 	  } else { /* pCorrection->nTables == 3 */
976 	    if ((pCorrection->pRedTbl->nEntries < 2) ||
977 		    (pCorrection->pGreenTbl->nEntries < 2) ||
978 		    (pCorrection->pBlueTbl->nEntries < 2)) {
979 		if (pCorrection->visual_info.visualid) {
980 		    fprintf(stderr,"RGB Correction for visualid %ld: Illegal number of entries in table\n",
981 			    pCorrection->visual_info.visualid);
982 		} else {
983 		    fprintf(stderr,"Global RGB Correction: Illegal number of entries in table\n");
984 		}
985 		return (0);
986 	    }
987 	    switch (targetFormat) {
988 	      case 8:
989 		total = 9 +	/* visualID, type, and 3 lengths */
990 		    (pCorrection->pRedTbl->nEntries * (pCorrection->tableType == 0 ? 2 : 1)) +
991 		    (pCorrection->pGreenTbl->nEntries * (pCorrection->tableType == 0 ? 2 : 1)) +
992 		    (pCorrection->pBlueTbl->nEntries * (pCorrection->tableType == 0 ? 2 : 1));
993 		if ((pCard8 = pCard8Array =
994 			(unsigned char *) calloc (total,
995 			sizeof (unsigned char))) == NULL) {
996 		    fprintf(stderr,"Unable allocate array of ints\n");
997 		    return (0);
998 		}
999 		*pCard8++ = (pCorrection->visual_info.visualid >> 24) & 0xFF;
1000 		*pCard8++ = (pCorrection->visual_info.visualid >> 16) & 0xFF;
1001 		*pCard8++ = (pCorrection->visual_info.visualid >> 8) & 0xFF;
1002 		*pCard8++ = (pCorrection->visual_info.visualid) & 0xFF;
1003 		*pCard8++ = pCorrection->tableType;	/* type */
1004 		*pCard8++ = 3;		/* number of tables = 3 */
1005 		if (pCorrection->tableType == 0) {
1006 		    PutTableType0Card8(pCorrection->pRedTbl, &pCard8);
1007 		    PutTableType0Card8(pCorrection->pGreenTbl, &pCard8);
1008 		    PutTableType0Card8(pCorrection->pBlueTbl, &pCard8);
1009 		} else {
1010 		    PutTableType1Card8(pCorrection->pRedTbl, &pCard8);
1011 		    PutTableType1Card8(pCorrection->pGreenTbl, &pCard8);
1012 		    PutTableType1Card8(pCorrection->pBlueTbl, &pCard8);
1013 		}
1014 		XChangeProperty (pDpy, root, CorrectAtom, XA_INTEGER, 8,
1015 			i ? PropModeAppend : PropModeReplace,
1016 			(unsigned char *)pCard8Array, total);
1017 		free(pCard8Array);
1018 		break;
1019 	      case 16:
1020 		total = 7 +	/* visualID, type, and 3 lengths */
1021 		    (pCorrection->pRedTbl->nEntries * (pCorrection->tableType == 0 ? 2 : 1)) +
1022 		    (pCorrection->pGreenTbl->nEntries * (pCorrection->tableType == 0 ? 2 : 1)) +
1023 		    (pCorrection->pBlueTbl->nEntries * (pCorrection->tableType == 0 ? 2 : 1));
1024 		if ((pCard16 = pCard16Array =
1025 			(unsigned short *) calloc (total,
1026 			sizeof (unsigned short))) == NULL) {
1027 		    fprintf(stderr,"Unable allocate array of ints\n");
1028 		    return (0);
1029 		}
1030 		*pCard16++ = (pCorrection->visual_info.visualid >> 16) & 0xFFFF;
1031 		*pCard16++ = (pCorrection->visual_info.visualid) & 0xFFFF;
1032 		*pCard16++ = pCorrection->tableType;	/* type = 0 */
1033 		*pCard16++ = 3;		/* number of tables = 3 */
1034 		if (pCorrection->tableType == 0) {
1035 		    PutTableType0Card16(pCorrection->pRedTbl, &pCard16);
1036 		    PutTableType0Card16(pCorrection->pGreenTbl, &pCard16);
1037 		    PutTableType0Card16(pCorrection->pBlueTbl, &pCard16);
1038 		} else {
1039 		    PutTableType1Card16(pCorrection->pRedTbl, &pCard16);
1040 		    PutTableType1Card16(pCorrection->pGreenTbl, &pCard16);
1041 		    PutTableType1Card16(pCorrection->pBlueTbl, &pCard16);
1042 		}
1043 		XChangeProperty (pDpy, root, CorrectAtom, XA_INTEGER, 16,
1044 			i ? PropModeAppend : PropModeReplace,
1045 			(unsigned char *)pCard16Array, total);
1046 		free(pCard16Array);
1047 		break;
1048 	      case 32:
1049 		total = 6 +	/* visualID, type, and 3 lengths */
1050 		    (pCorrection->pRedTbl->nEntries * (pCorrection->tableType == 0 ? 2 : 1)) +
1051 		    (pCorrection->pGreenTbl->nEntries * (pCorrection->tableType == 0 ? 2 : 1)) +
1052 		    (pCorrection->pBlueTbl->nEntries * (pCorrection->tableType == 0 ? 2 : 1));
1053 		if ((pCard32 = pCard32Array =
1054 			(unsigned long *) calloc (total,
1055 			sizeof (unsigned long))) == NULL) {
1056 		    fprintf(stderr,"Unable allocate array of ints\n");
1057 		    return (0);
1058 		}
1059 		*pCard32++ = pCorrection->visual_info.visualid;
1060 		*pCard32++ = pCorrection->tableType;	/* type */
1061 		*pCard32++ = 3;		/* number of tables = 3 */
1062 		if (pCorrection->tableType == 0) {
1063 		    PutTableType0Card32(pCorrection->pRedTbl, &pCard32);
1064 		    PutTableType0Card32(pCorrection->pGreenTbl, &pCard32);
1065 		    PutTableType0Card32(pCorrection->pBlueTbl, &pCard32);
1066 		} else {
1067 		    PutTableType1Card32(pCorrection->pRedTbl, &pCard32);
1068 		    PutTableType1Card32(pCorrection->pGreenTbl, &pCard32);
1069 		    PutTableType1Card32(pCorrection->pBlueTbl, &pCard32);
1070 		}
1071 		XChangeProperty (pDpy, root, CorrectAtom, XA_INTEGER, 32,
1072 			i ? PropModeAppend : PropModeReplace,
1073 			(unsigned char *)pCard32Array, total);
1074 		free(pCard32Array);
1075 		break;
1076 	      default:
1077 		if (pCorrection->visual_info.visualid) {
1078 		    fprintf(stderr,"RGB Correction for visualid %ld: Invalid property format\n",
1079 			    pCorrection->visual_info.visualid);
1080 		} else {
1081 		    fprintf(stderr,"Global RGB Correction: Invalid property format\n");
1082 		}
1083 		return (0);
1084 	    }
1085 	}
1086     }
1087 
1088     return (1);
1089 }
1090 
1091 #ifdef GRAY
1092 
1093 static int
LoadDataGray(Display * pDpy,window root,int tableType,LINEAR_RGB_SCCData * pScreenData,int targetFormat)1094 LoadDataGray(Display *pDpy, window root, int tableType,
1095 	     LINEAR_RGB_SCCData *pScreenData, int targetFormat)
1096 {
1097     unsigned char *ret_prop;
1098     int  count;
1099     int  nLevels;
1100     unsigned char  *pCard8;
1101     unsigned char  *pCard8Array = (unsigned char *)NULL;
1102     unsigned short  *pCard16;
1103     unsigned short  *pCard16Array = (unsigned short *)NULL;
1104     unsigned long  *pCard32;
1105     unsigned long  *pCard32Array = (unsigned long *)NULL;
1106     unsigned long  Card32Array[18];
1107     int  ret_format;
1108     unsigned long ret_len, ret_after;
1109     Atom MatricesAtom, CorrectAtom, ret_atom;
1110     XcmsFloat *pValue;
1111     int total;
1112 
1113     /* Now store the XDCCC_SCREENWHITEPT */
1114     pCard32 = Card32Array;
1115     pValue = (XcmsFloat *)pScreenData->XYZtoRGBmatrix;
1116     for (count = 0; count < 3; count++) {
1117 	*pCard32++ = (unsigned long) (*pValue++ * (XcmsFloat) XDCCC_NUMBER);
1118     }
1119     MatricesAtom = XInternAtom (pDpy,XDCCC_SCREENWHITEPT_ATOM_NAME,False);
1120     XChangeProperty (pDpy, root, MatricesAtom, XA_INTEGER, 32,
1121 		     PropModeReplace, (unsigned char *)Card32Array, 3);
1122 
1123     /* Now store the XDCCC_GRAY_CORRECTION */
1124     CorrectAtom = XInternAtom (pDpy, XDCCC_GRAY_CORRECT_ATOM_NAME, False);
1125 
1126     if (tableType == CORR_TYPE_NONE) {
1127 	XGetWindowProperty (pDpy, root, CorrectAtom,
1128 			    0, 5, False, XA_INTEGER,
1129 			    &ret_atom, &ret_format, &ret_len, &ret_after,
1130 			    &ret_prop);
1131 	if (ret_format != 0) {
1132 	    XDeleteProperty (pDpy, root, CorrectAtom);
1133 	    XFree ((char *)ret_prop);
1134 	}
1135 	return (1);
1136     }
1137     nLevels = pScreenData->pRedTbl->nEntries;
1138     if (nLevels < 2) {
1139 	fprintf(stderr,"Illegal number of entries in table\n");
1140 	return (0);
1141     }
1142     switch (targetFormat) {
1143       case 8:
1144 	total = 6 /* visualID, type, length */
1145 		+ (nLevels * (tableType == 0 ? 2 : 1));
1146 	if ((pCard8 = pCard8Array = (unsigned char *)
1147 		calloc (total, sizeof (unsigned char))) == NULL) {
1148 	    fprintf(stderr,"Unable allocate array of Card8\n");
1149 	    return (0);
1150 	}
1151 	*pCard8++ = 0;		/* VisualID = 0 */
1152 	*pCard8++ = 0;		/* VisualID = 0 */
1153 	*pCard8++ = 0;		/* VisualID = 0 */
1154 	*pCard8++ = 0;		/* VisualID = 0 */
1155 	*pCard8++ = tableType;	/* type */
1156 	if (tableType == 0) {
1157 	    PutTableType0Card8(pScreenData->pRedTbl, &pCard8);
1158 	} else { /* tableType == 1 */
1159 	    PutTableType1Card8(pScreenData->pRedTbl, &pCard8);
1160 	}
1161 	XChangeProperty (pDpy, root, CorrectAtom, XA_INTEGER, 8,
1162 			 PropModeReplace, (unsigned char *)pCard8Array,
1163 			 total);
1164 	free (pCard8Array);
1165 	break;
1166       case 16:
1167 	total = 4 /* visualID, type, length */
1168 		+ (nLevels * (tableType == 0 ? 2 : 1));
1169 	if ((pCard16 = pCard16Array = (unsigned short *)
1170 		calloc (total, sizeof (unsigned short))) == NULL) {
1171 	    fprintf(stderr,"Unable allocate array of Card16\n");
1172 	    return (0);
1173 	}
1174 	*pCard16++ = 0;		/* VisualID = 0 */
1175 	*pCard16++ = 0;		/* VisualID = 0 */
1176 	*pCard16++ = tableType;	/* type */
1177 	if (tableType == 0) {
1178 	    PutTableType0Card16(pScreenData->pRedTbl, &pCard16);
1179 	} else { /* tableType == 1 */
1180 	    PutTableType1Card16(pScreenData->pRedTbl, &pCard16);
1181 	}
1182 	XChangeProperty (pDpy, root, CorrectAtom, XA_INTEGER, 16,
1183 			 PropModeReplace, (unsigned char *)pCard16Array,
1184 			 total);
1185 	free (pCard16Array);
1186 	break;
1187       case 32:
1188 	total = 3 /* visualID, type, length */
1189 		+ (nLevels * (tableType == 0 ? 2 : 1));
1190 	if ((pCard32 = pCard32Array = (unsigned long *)
1191 		calloc (total, sizeof (unsigned long))) == NULL) {
1192 	    fprintf(stderr,"Unable allocate array of Card32\n");
1193 	    return (0);
1194 	}
1195 	*pCard32++ = 0;		/* VisualID = 0 */
1196 	*pCard32++ = tableType;	/* type */
1197 	if (tableType == 0) {
1198 	    PutTableType0Card32(pScreenData->pRedTbl, &pCard32);
1199 	} else { /* tableType == 1 */
1200 	    PutTableType1Card32(pScreenData->pRedTbl, &pCard32);
1201 	}
1202 	XChangeProperty (pDpy, root, CorrectAtom, XA_INTEGER, 32,
1203 			 PropModeReplace, (unsigned char *)pCard32Array,
1204 			 total);
1205 	free (pCard32Array);
1206 	break;
1207       default:
1208 	fprintf(stderr,"Invalid property format\n");
1209 	return (0);
1210     }
1211     return (1);
1212 }
1213 #endif /* GRAY */
1214 
1215 
1216 static void
PrintVisualOptions(XDCCC_Correction * pCorrection)1217 PrintVisualOptions(XDCCC_Correction *pCorrection)
1218 {
1219     if (pCorrection->visual_info_mask & VisualIDMask) {
1220 	fprintf(stderr, "\t%s:0x%lx\n",
1221 		DefineToStr(VisualOptKeyTbl, KEY_VISUALID),
1222 		(unsigned long)pCorrection->visual_info.visualid);
1223     }
1224     if (pCorrection->visual_info_mask & VisualDepthMask) {
1225 	fprintf(stderr, "\t%s:%d\n",
1226 		DefineToStr(VisualOptKeyTbl, KEY_DEPTH),
1227 		pCorrection->visual_info.depth);
1228     }
1229     if (pCorrection->visual_info_mask & VisualClassMask) {
1230 	fprintf(stderr, "\t%s:%s\n",
1231 		DefineToStr(VisualOptKeyTbl, KEY_CLASS),
1232 		DefineToStr(VisualClassTbl, pCorrection->visual_info.class));
1233     }
1234     if (pCorrection->visual_info_mask & VisualRedMaskMask) {
1235 	fprintf(stderr, "\t%s:0x%lx\n",
1236 		DefineToStr(VisualOptKeyTbl, KEY_RED_MASK),
1237 		pCorrection->visual_info.red_mask);
1238     }
1239     if (pCorrection->visual_info_mask & VisualGreenMaskMask) {
1240 	fprintf(stderr, "\t%s:0x%lx\n",
1241 		DefineToStr(VisualOptKeyTbl, KEY_GREEN_MASK),
1242 		pCorrection->visual_info.green_mask);
1243     }
1244     if (pCorrection->visual_info_mask & VisualBlueMaskMask) {
1245 	fprintf(stderr, "\t%s:0x%lx\n",
1246 		DefineToStr(VisualOptKeyTbl, KEY_BLUE_MASK),
1247 		pCorrection->visual_info.blue_mask);
1248     }
1249     if (pCorrection->visual_info_mask & VisualColormapSizeMask) {
1250 	fprintf(stderr, "\t%s:0x%x\n",
1251 		DefineToStr(VisualOptKeyTbl, KEY_COLORMAP_SIZE),
1252 		pCorrection->visual_info.colormap_size);
1253     }
1254     if (pCorrection->visual_info_mask & VisualBitsPerRGBMask) {
1255 	fprintf(stderr, "\t%s:%d\n",
1256 		DefineToStr(VisualOptKeyTbl, KEY_BITS_PER_RGB),
1257 		pCorrection->visual_info.bits_per_rgb);
1258     }
1259 }
1260 
1261 
1262 static int
ParseVisualOptions(Display * pDpy,XDCCC_Correction * pCorrection,char * pbuf)1263 ParseVisualOptions(Display *pDpy, XDCCC_Correction *pCorrection, char *pbuf)
1264 {
1265     char *key;
1266     char *value;
1267     XVisualInfo *vinfo;
1268     int n_matches;
1269     char delims[8];
1270 
1271     strcpy(delims, DATA_DELIMS);
1272     strcat(delims, ":");
1273     pCorrection->visual_info_mask = VisualNoMask;
1274     key = strtok(pbuf, delims);
1275     do {
1276 	long tmp;
1277 	value = strtok((char*)NULL, delims);
1278 	if ((key == (char*)NULL) || (value == (char*)NULL)) {
1279 	    return (0);
1280 	}
1281 	switch (StrToDefine(VisualOptKeyTbl, key)) {
1282 	  case  KEY_VISUALID:
1283 	    if (sscanf(value, "%li", &tmp) != 1) {
1284 		fprintf(stderr,
1285 			"Line %d: invalid VisualID specified, %s\n",
1286 			linenum, value);
1287 		return (0);
1288 	    } else
1289 		pCorrection->visual_info.visualid = tmp;
1290 	    pCorrection->visual_info_mask |= VisualIDMask;
1291 	    break;
1292 	  case  KEY_DEPTH:
1293 	    if (sscanf(value, "%i", &pCorrection->visual_info.depth) != 1) {
1294 		fprintf(stderr,
1295 			"Line %d: invalid depth specified, %s\n",
1296 			linenum, value);
1297 		return (0);
1298 	    }
1299 	    pCorrection->visual_info_mask |= VisualDepthMask;
1300 	    break;
1301 	  case  KEY_CLASS:
1302 	    switch (pCorrection->visual_info.class =
1303 		    StrToDefine(VisualClassTbl, value)) {
1304 	      case  StaticColor:
1305 		break;
1306 	      case  PseudoColor:
1307 		break;
1308 	      case  TrueColor:
1309 		break;
1310 	      case  DirectColor:
1311 		break;
1312 	      case  StaticGray:
1313 		/* invalid, fall through */
1314 	      case  GrayScale:
1315 		/* invalid, fall through */
1316 	      default:
1317 		fprintf(stderr,
1318 			"Line %d: invalid Visual Class -- %s\n",
1319 			linenum, value);
1320 		return (0);
1321 	    }
1322 	    pCorrection->visual_info_mask |= VisualClassMask;
1323 	    break;
1324 	  case  KEY_RED_MASK:
1325 	    if (sscanf(value, "%li", &tmp) != 1) {
1326 		fprintf(stderr,
1327 			"Line %d: invalid red_mask specified -- %s\n",
1328 			linenum, value);
1329 		return (0);
1330 	    } else
1331 		pCorrection->visual_info.red_mask = tmp;
1332 	    pCorrection->visual_info_mask |= VisualRedMaskMask;
1333 	    break;
1334 	  case  KEY_GREEN_MASK:
1335 	    if (sscanf(value, "%li", &tmp) != 1) {
1336 		fprintf(stderr,
1337 			"Line %d: invalid green_mask specified -- %s\n",
1338 			linenum, value);
1339 		return (0);
1340 	    } else
1341 		pCorrection->visual_info.green_mask = tmp;
1342 	    pCorrection->visual_info_mask |= VisualGreenMaskMask;
1343 	    break;
1344 	  case  KEY_BLUE_MASK:
1345 	    if (sscanf(value, "%li", &tmp) != 1) {
1346 		fprintf(stderr,
1347 			"Line %d: invalid blue_mask specified -- %s\n",
1348 			linenum, value);
1349 		return (0);
1350 	    } else
1351 		pCorrection->visual_info.blue_mask = tmp;
1352 	    pCorrection->visual_info_mask |= VisualBlueMaskMask;
1353 	    break;
1354 	  case  KEY_COLORMAP_SIZE:
1355 	    if (sscanf(value, "%i", &pCorrection->visual_info.colormap_size) != 1) {
1356 		fprintf(stderr,
1357 			"Line %d: invalid colormap_size specified -- %s\n",
1358 			linenum, value);
1359 		return (0);
1360 	    }
1361 	    pCorrection->visual_info_mask |= VisualColormapSizeMask;
1362 	    break;
1363 	  case  KEY_BITS_PER_RGB:
1364 	    if (sscanf(value, "%i", &pCorrection->visual_info.bits_per_rgb) != 1) {
1365 		fprintf(stderr,
1366 			"Line %d: invalid bits_per_rgb specified -- %s\n",
1367 			linenum, value);
1368 		return (0);
1369 	    }
1370 	    pCorrection->visual_info_mask |= VisualBitsPerRGBMask;
1371 	    break;
1372 	  default:
1373 	    fprintf(stderr,
1374 		    "Line %d: invalid keyword %s\n", linenum, key);
1375 	    return (0);
1376 	}
1377 	key = strtok((char*)NULL, delims);
1378     } while (key != (char *)NULL);
1379 
1380     vinfo = XGetVisualInfo(pDpy,
1381 	    pCorrection->visual_info_mask,
1382 	    &pCorrection->visual_info,
1383 	    &n_matches);
1384 
1385     if (!n_matches) {
1386 	fprintf(stderr, "Line %d: Cannot find visual matching ...\n", linenum);
1387 	PrintVisualOptions(pCorrection);
1388 	fprintf(stderr, "\n");
1389 	return(0);
1390     }
1391     if (n_matches > 1) {
1392 	fprintf(stderr, "Line %d: Found more than one visual matching ...\n", linenum);
1393 	PrintVisualOptions(pCorrection);
1394 	fprintf(stderr, "    Using VisualId 0x%lx\n", (unsigned long)vinfo->visualid);
1395     }
1396     memcpy((char*)&pCorrection->visual_info, (char*)vinfo,
1397 	    sizeof(XVisualInfo));
1398     return (1);
1399 }
1400 
1401 
1402 /************************************************************************
1403  *									*
1404  *			 PUBLIC ROUTINES				*
1405  *									*
1406  ************************************************************************/
1407 
1408 /*
1409  *	NAME
1410  *		LoadSCCData - Read and store the screen data
1411  *
1412  *	SYNOPSIS
1413  */
1414 int
LoadSCCData(Display * pDpy,int screenNumber,const char * filename,int targetFormat)1415 LoadSCCData(Display *pDpy, int screenNumber, const char *filename,
1416             int targetFormat)
1417 
1418 /*
1419  *	DESCRIPTION
1420  *		Using the X Device Color Characterization Convention (XDCCC)
1421  *		read the screen data and store it on the root window of the
1422  *		screen.
1423  *
1424  *	RETURNS
1425  *		Returns 0 if failed; otherwise 1.
1426  *
1427  */
1428 {
1429     FILE *stream;
1430     char *pStr;
1431     char buf[BUFSIZ];
1432     char *keyword, *token1, *token2, *token3;
1433     int  state = 0;
1434     int VisualFlag = -2;
1435     Window root;
1436     XDCCC_Matrix matrix;
1437     XDCCC_Correction* CorrectionTail = (XDCCC_Correction*)NULL;
1438     XDCCC_Correction* CorrectionHead = (XDCCC_Correction*)NULL;
1439     XDCCC_Correction* pCurrent;
1440 
1441     if (screenNumber < 0) {
1442 	fprintf(stderr,"Invalid Screen Number %d\n", screenNumber);
1443 	return(0);
1444     }
1445     root = RootWindow(pDpy, screenNumber);
1446 
1447     if (!root) {
1448 	/* if no root window is available then return an error */
1449 	fprintf(stderr,"Could not open root window supplied.\n ");
1450 	return (0);
1451     }
1452     /*
1453      * Open the file, determine its size, then read it into memory.
1454      */
1455     if (filename == NULL) {
1456 	stream = stdin;
1457 	filename = "stdin";
1458     } else if ((stream = fopen(filename, "r")) == NULL) {
1459 	fprintf(stderr,"Could not open file %s.\n", filename);
1460 	return (0);
1461     }
1462 
1463     /*
1464      * Advance to starting keyword
1465      * Anything before this keyword is just treated as comments.
1466      */
1467 
1468     while((pStr = nextline(buf, BUFSIZ, stream)) != NULL) {
1469 	keyword = strtok(buf, DATA_DELIMS);
1470 	if (keyword != (char *)NULL &&
1471 		(strcmp(keyword, SC_BEGIN_KEYWORD) == 0)) {
1472 	    break;
1473 	}  /* else ignore the line */
1474     }
1475 
1476     if (pStr == NULL) {
1477 	fprintf(stderr,"File %s is missing %s\n", filename, SC_BEGIN_KEYWORD);
1478 	closeS (stream, CorrectionHead);
1479 	return (0);
1480     }
1481 
1482     token1 = strtok((char*)NULL, DATA_DELIMS);
1483     if ( token1 && (strcmp(token1, TXT_FORMAT_VERSION) != 0) &&
1484 	    (strcmp(token1, "0.3") != 0)) {
1485 	fprintf(stderr,
1486     "Screen data format version mismatch in file %s-- expected %s, found %s\n",
1487 		filename, TXT_FORMAT_VERSION, token1);
1488 	closeS (stream, CorrectionHead);
1489 	return (0);
1490     }
1491 
1492     while ((pStr = nextline(buf, BUFSIZ, stream)) != NULL) {
1493 	keyword = strtok(buf, DATA_DELIMS);
1494 	if (keyword != (char*)NULL) {
1495 	    switch (SCKeyOf(keyword)) {
1496 	      case COMMENT :
1497 	      case NAME :
1498 	      case PART_NUMBER :
1499 	      case MODEL :
1500 	      case SERIAL_NUMBER :
1501 	      case REVISION :
1502 		/* Do nothing */
1503 		break;
1504 	      case SCREEN_CLASS :
1505 		token1 = strtok((char*)NULL, DATA_DELIMS);
1506 		token2 = strtok((char*)NULL, DATA_DELIMS);
1507 		if ((token1 == (char*)NULL)
1508 			|| ((VisualFlag = SCScrnClassOf(token1)) == -1)) {
1509 		    closeS (stream, CorrectionHead);
1510 		    return (0);
1511 		}
1512 		/*include code to handle screen number input*/
1513 		if (token2 != (char*)NULL) {
1514 		    screenNumber = atoi(token2);
1515 
1516 		    if (screenNumber < 0) {
1517 			fprintf(stderr,"Invalid Screen Number %d\n",
1518 				screenNumber);
1519 		    }
1520 		    else {
1521 			root = RootWindow(pDpy, screenNumber);
1522 			if (!root) {
1523 	/* if no root window is available then return an error */
1524 			    fprintf(stderr,
1525 				    "Could not open root window supplied.\n ");
1526 			    return (0);
1527 			}
1528 		    }
1529 		}
1530 		break;
1531 	      case COLORIMETRIC_BEGIN :
1532 		if (VisualFlag == -2) {
1533 		    closeS (stream, CorrectionHead);
1534 		    return (0);
1535 		}
1536 		if (!ProcessColorimetric(stream,
1537 					 &matrix, VisualFlag)) {
1538 		    closeS (stream, CorrectionHead);
1539 		    return (0);
1540 		}
1541 		state |= 0x02;
1542 		break;
1543 	      case IPROFILE_BEGIN :
1544 		if (VisualFlag == -2) {
1545 		    closeS (stream, CorrectionHead);
1546 		    return (0);
1547 		}
1548 		token1 = strtok((char*)NULL, DATA_DELIMS);
1549 		token2 = strtok((char*)NULL, DATA_DELIMS);
1550 		if ((token1 == (char*)NULL) || (token2 == (char*)NULL)) {
1551 		    fprintf(stderr,
1552 			"Line %d: Intensity profile missing TableType and/or nTables.",
1553 			linenum);
1554 		    closeS (stream, CorrectionHead);
1555 		    return (0);
1556 		}
1557 
1558 		if ((pCurrent = (XDCCC_Correction *)
1559 			calloc(1, sizeof(XDCCC_Correction))) ==NULL) {
1560 		    fprintf(stderr,
1561 			"Line %d: Could not allocate memory for intensity profile.",
1562 			linenum);
1563 		    closeS (stream, CorrectionHead);
1564 		    return (0);
1565 		}
1566 
1567 		if (sscanf(token1, "%d", &pCurrent->tableType) != 1 ||
1568 		    (pCurrent->tableType < 0 || pCurrent->tableType > 1)) {
1569 		    fprintf(stderr,
1570 			    "Line %d: invalid table type specified -- %s\n",
1571 			    linenum, buf);
1572 		    closeS (stream, CorrectionHead);
1573 		    return (0);
1574 		}
1575 
1576 		if ((VisualFlag == VIDEO_RGB) && (token2 == (char *)NULL)) {
1577 		    fprintf(stderr,
1578 			"Line %d: invalid number of tables specified -- %s\n",
1579 			    linenum, buf);
1580 		    closeS (stream, CorrectionHead);
1581 		    return (0);
1582 		}
1583 
1584 		if (VisualFlag == VIDEO_RGB) {
1585 		    if (sscanf(token2, "%d", &pCurrent->nTables) != 1 ||
1586 			    (pCurrent->nTables != 0 && pCurrent->nTables != 1
1587 			    && pCurrent->nTables != 3)) {
1588 			fprintf(stderr,
1589 				"Line %d: invalid number of tables (must be 0, 1, or 3)\n",
1590 				linenum);
1591 			closeS (stream, CorrectionHead);
1592 			return (0);
1593 		    }
1594 		} else {
1595 		    pCurrent->nTables = 0;
1596 		}
1597 
1598 		token3 = strtok((char*)NULL, "\n");
1599 		if (token3 != (char*)NULL) {
1600 		    if (!ParseVisualOptions(pDpy, pCurrent, token3)) {
1601 			goto ByPassThisIProfile;
1602 		    }
1603 		}
1604 
1605 		switch (pCurrent->nTables) {
1606 		  case 3 :
1607 		    if (!(pCurrent->pRedTbl = (IntensityTbl *)
1608 			calloc (1, sizeof (IntensityTbl)))) {
1609 			fprintf(stderr,
1610 			       "Line %d: Could not allocate Red Intensity Table\n",
1611 			       linenum);
1612 			closeS (stream, CorrectionHead);
1613 			return (0);
1614 		    }
1615 		    if (!(pCurrent->pGreenTbl = (IntensityTbl *)
1616 			calloc (1, sizeof (IntensityTbl)))) {
1617 			fprintf(stderr,
1618 			     "Line %d: Could not allocate Green Intensity Table\n",
1619 			     linenum);
1620 			closeS (stream, CorrectionHead);
1621 			return (0);
1622 		    }
1623 		    if (!(pCurrent->pBlueTbl = (IntensityTbl *)
1624 			calloc (1, sizeof (IntensityTbl)))) {
1625 			fprintf(stderr,
1626 				"Line %d: Could not allocate Blue Intensity Table",
1627 				linenum);
1628 			closeS (stream, CorrectionHead);
1629 			return (0);
1630 		    }
1631 		    if (!ProcessIProfile(stream, pCurrent)) {
1632 			goto ByPassThisIProfile;
1633 		    }
1634 		    break;
1635 		  case 1 :
1636 		    if (!(pCurrent->pRedTbl = (IntensityTbl *)
1637 			  calloc (1, sizeof (IntensityTbl)))) {
1638 			fprintf(stderr,
1639 				"Line %d: Could not allocate Red Intensity Table",
1640 				linenum);
1641 			closeS (stream, CorrectionHead);
1642 			return (0);
1643 		    }
1644 		    pCurrent->pGreenTbl = pCurrent->pRedTbl;
1645 		    pCurrent->pBlueTbl = pCurrent->pRedTbl;
1646 		    if (!ProcessIProfile(stream, pCurrent)) {
1647 			goto ByPassThisIProfile;
1648 		    }
1649 		    break;
1650 		  default :
1651 		    /* do nothing */
1652 		    break;
1653 		}
1654 
1655 		if (CorrectionHead == NULL) {
1656 		    CorrectionHead = CorrectionTail = pCurrent;
1657 		} else {
1658 		    CorrectionTail->next = pCurrent;
1659 		    CorrectionTail = pCurrent;
1660 		}
1661 		state |= 0x04;
1662 		break;
1663 ByPassThisIProfile:
1664 		/* read till INTENSITY_PROFILE_END */
1665 		while ((pStr = nextline(buf, BUFSIZ, stream)) != NULL) {
1666 		    keyword = strtok(buf, DATA_DELIMS);
1667 		    if (keyword != (char*)NULL) {
1668 			switch (SCKeyOf(keyword)) {
1669 			  case ITBL_BEGIN:
1670 			  case ITBL_END:
1671 			  case COMMENT:
1672 			  case DATA:
1673 			    break;
1674 			  case IPROFILE_END:
1675 			    goto IProfileProcessed;
1676 			  default:
1677 			    closeS (stream, CorrectionHead);
1678 			    return (0);
1679 			}
1680 		    }
1681 		}
1682 		free(pCurrent);
1683 IProfileProcessed:
1684 		state |= 0x04;
1685 		break;
1686 	      case SC_END :
1687 		if (!(state & 0x02)) {
1688 		    fprintf(stderr,
1689 			    "File %s is missing Colorimetric data.\n",
1690 			    filename);
1691 		    closeS (stream, CorrectionHead);
1692 		    return (0);
1693 		}
1694 		if (!(state & 0x04)) {
1695 		    fprintf(stderr,
1696 			    "File %s is missing Intensity Profile Data.\n",
1697 			    filename);
1698 		}
1699 		if (VisualFlag == VIDEO_RGB) {
1700 		    LoadMatrix(pDpy, root, &matrix);
1701 		    if (!LoadCorrections(pDpy, root, CorrectionHead,
1702 			    targetFormat)) {
1703 			closeS (stream, CorrectionHead);
1704 			return (0);
1705 		    }
1706 #ifdef GRAY
1707 		} else if (VisualFlag == VIDEO_GRAY) {
1708 		    if (!LoadDataGray(pDpy, root,
1709 				      pCurrent->tableType, pScreenData, targetFormat)) {
1710 			closeS (stream, CorrectionHead);
1711 			return (0);
1712 		    }
1713 #endif /* GRAY */
1714 		} else {
1715 		    fprintf(stderr,"File %s Visual missing.", filename);
1716 		}
1717 		closeS (stream, CorrectionHead);
1718 		return (1);
1719 
1720 	      default :
1721 		fprintf(stderr,"Line %d: extraneous keyword %s\n",
1722 			linenum, keyword);
1723 		closeS (stream, CorrectionHead);
1724 		return (0);
1725 
1726 	    }
1727 	}   /* else it was just a blank line */
1728     }
1729     closeS (stream, CorrectionHead);
1730     return (1);
1731 }
1732