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