loadData.c revision 2c7c4e3d
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 64typedef struct _DefineEntry { 65 char *pString; 66 int define; 67} DefineEntry; 68 69 70/* 71 * LOCAL VARIABLES 72 */ 73static int linenum = 0; 74 75static 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 100static 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 117static 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}; 128static 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 */ 151static int 152StrToDefine(DefineEntry pde[], /* IN: table of X string-define pairs */ 153 /* last entry must contain pair "", 0 */ 154 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 */ 187static char * 188DefineToStr(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 */ 223static int 224SCKeyOf(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 */ 252static int 253SCScrnClassOf(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 */ 281static char * 282SCScrnClassStringOf(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*/ 297static void 298closeS(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 */ 314static char * 315nextline(char *buf, int maxch, FILE *stream) 316{ 317 linenum++; 318 return (fgets(buf, maxch, stream)); 319} 320 321 322static int 323ProcessColorimetric(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/* NOTREACHED */break; 489 case COLORIMETRIC_END : 490 if (state != 2) { 491 fprintf(stderr, 492 "Line %d: Incomplete Colorimetric data -- Premature %s\n", 493 linenum, keyword); 494 return (0); 495 } 496 return (1); 497 case COMMENT : 498 /* Currently, do nothing. */ 499 break; 500 default : 501 fprintf(stderr, 502 "Line %d: Unexpected keyword %s\n", 503 linenum, keyword); 504 return (0); 505/* NOTREACHED */break; 506 } 507 } else if (ntok < 0) { 508 /* mismatch */ 509 fprintf(stderr, "Line %d: Unrecognized keyword\n", linenum); 510 return (0); 511/* NOTREACHED */break; 512 } 513 } 514 return (0); 515} 516 517static int 518ProcessIProfile(FILE *stream, XDCCC_Correction *pCorrection) 519{ 520 char buf[BUFSIZ]; 521 char *keyword; 522 char *tableStr, *sizeStr, *ptoken; 523 int size; 524 int state = 0; 525 /************************************************ 526 * 0 -- Looking for Intensity Table(s) * 527 * 1 -- Processing Intensity Table(s) * 528 ************************************************/ 529 int nTbl = 0; 530 int count = 0; 531 IntensityRec *pIRec = NULL; 532 533 while ((nextline(buf, BUFSIZ, stream)) != NULL) { 534 ptoken = keyword = strtok(buf, DATA_DELIMS); 535 if (keyword != (char*)NULL) { 536 switch (SCKeyOf(keyword)) { 537 case ITBL_BEGIN : 538 if (state != 0) { 539 fprintf(stderr,"Line %d: unexpected keyword %s\n", 540 linenum, keyword); 541 return (0); 542 } 543 tableStr = strtok((char*)NULL, DATA_DELIMS); 544 sizeStr = strtok((char*)NULL, DATA_DELIMS); 545 if ((sizeStr == (char*)NULL) || 546 sscanf(sizeStr, "%d", &size) != 1) { 547 fprintf(stderr, 548 "Line %d: invalid Intensity Table size, %s.\n", 549 linenum, sizeStr); 550 return (0); 551 } 552 if (size < 0) { 553 fprintf(stderr, 554 "Line %d: count %d < 0 for Intensity Table.\n", 555 linenum, size); 556 return (0); 557 } 558 if (strcmp(tableStr, "GREEN") == 0) { 559 if (pCorrection->nTables != 3) { 560 fprintf(stderr,"Line %d: incorrect number of tables\n", 561 linenum); 562 return (0); 563 } 564 if (pCorrection->pGreenTbl->pBase != NULL) { 565 fprintf(stderr, 566 "Line %d: multiple GREEN Intensity Profiles\n", 567 linenum); 568 return (0); 569 } 570 pCorrection->pGreenTbl->nEntries = size; 571 pCorrection->pGreenTbl->pBase = 572 (IntensityRec *) calloc (size, sizeof(IntensityRec)); 573 if (!pCorrection->pGreenTbl->pBase) { 574 fprintf(stderr, 575 "Line %d: Unable to allocate space for GREEN Intensity Profile\n", linenum); 576 return (0); 577 } 578 pIRec = pCorrection->pGreenTbl->pBase; 579 } else if (strcmp(tableStr, "BLUE") == 0) { 580 if (pCorrection->nTables != 3) { 581 fprintf(stderr, 582 "Line %d: incorrect number of tables\n", 583 linenum); 584 return (0); 585 } 586 if (pCorrection->pBlueTbl->pBase != NULL) { 587 fprintf(stderr, 588 "Line %d: multiple BLUE Intensity Profiles\n", 589 linenum); 590 return (0); 591 } 592 pCorrection->pBlueTbl->nEntries = size; 593 pCorrection->pBlueTbl->pBase = 594 (IntensityRec *) calloc (size, sizeof(IntensityRec)); 595 if (!pCorrection->pBlueTbl->pBase) { 596 fprintf(stderr, 597 "Line %d: Unable to allocate space for BLUE Intensity Profile\n", linenum); 598 return (0); 599 } 600 pIRec = pCorrection->pBlueTbl->pBase; 601 } else { 602 if (!strcmp(tableStr, "RGB") && pCorrection->nTables != 1) { 603 fprintf(stderr,"Line %d: multiple RGB Intensity Tables", 604 linenum); 605 return (0); 606 } 607 if (pCorrection->pRedTbl->pBase != NULL) { 608 fprintf(stderr, 609 "Line %d: multiple RED or GREEN or BLUE Intensity Tables\n", 610 linenum); 611 return (0); 612 } 613 pCorrection->pRedTbl->nEntries = size; 614 pCorrection->pRedTbl->pBase = 615 (IntensityRec *) calloc (size, sizeof(IntensityRec)); 616 if (!pCorrection->pRedTbl->pBase) { 617 fprintf(stderr, 618 "Line %d: Unable to allocate space for intensity table\n", linenum); 619 return (0); 620 } 621 pIRec = pCorrection->pRedTbl->pBase; 622 } 623 state = 1; 624 count = 0; 625 break; 626 case ITBL_END : 627 if ((state != 1) || (count != size)) { 628 fprintf(stderr, 629 "Line %d: incomplete Intensity Table -- Premature %s\n", 630 linenum, keyword); 631 return (0); 632 } 633 nTbl++; 634 state = 0; 635 break; 636 case DATA : 637 do { 638 /******************************************************** 639 * Note: tableType should only be 0 or 1 at this point. 640 * 0 indicates value and intensity stored. 641 * 1 indicates only intensity stored. 642 ********************************************************/ 643 if (pCorrection->tableType) { 644 if (sscanf(ptoken, "%lf", &pIRec->intensity) != 1) { 645 fprintf(stderr, 646 "Line %d: invalid Intensity Profile value %s\n", 647 linenum, ptoken); 648 return (0); 649 } 650 /* With tableType 1 only store the intensity. */ 651 pIRec++; 652 } else { 653 short tmp; 654 /* Note ansi C can handle 0x preceeding hex number */ 655 if (sscanf(ptoken, "%hi", &tmp) != 1) { 656 fprintf(stderr, 657 "Line %d: invalid Intensity Profile value %s\n", 658 linenum, ptoken); 659 return (0); 660 } else 661 pIRec->value = tmp; 662 if ((ptoken = strtok(NULL, DATA_DELIMS)) == NULL) { 663 fprintf(stderr, 664 "Line %d: missing Intensity Profile value\n", 665 linenum); 666 return (0); 667 } 668 if (sscanf(ptoken, "%lf", &pIRec->intensity) != 1) { 669 fprintf(stderr, 670 "Line %d: invalid Intensity Profile intensity %s\n", 671 linenum, ptoken); 672 return (0); 673 } 674 /* With tableType 0 only store both value & intensity*/ 675 pIRec++; 676 } 677 if (++count > size) { 678 fprintf(stderr, 679 "Line %d: extra Intensity value %s\n", 680 linenum, ptoken); 681 return (0); 682 } 683 ptoken = strtok(NULL, DATA_DELIMS); 684 } while(ptoken != NULL); 685 break; 686 case IPROFILE_BEGIN : 687 fprintf(stderr,"Line %d: extraneous keyword %s\n", 688 linenum, keyword); 689 return (0); 690/* NOTREACHED */break; 691 case IPROFILE_END : 692 if ((state != 0) || (nTbl != pCorrection->nTables)) { 693 fprintf(stderr, 694 "Line %d: incomplete Intensity Profile data -- Premature %s\n", 695 linenum, keyword); 696 return (0); 697 } 698 return (1); 699 case COMMENT : 700 /* ignore line */ 701 break; 702 default : 703 fprintf(stderr,"Line %d: unexpected keyword %s\n", 704 linenum, keyword); 705 return (0); 706/* NOTREACHED */break; 707 } 708 } /* else its was just a blank line */ 709 } 710 return (0); 711} 712 713static void 714PutTableType0Card8(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 731static void 732PutTableType1Card8(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 747static void 748PutTableType0Card16(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 765static void 766PutTableType1Card16(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 781static void 782PutTableType0Card32(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 799static void 800PutTableType1Card32(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 816static void 817LoadMatrix(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 843static int 844LoadCorrections(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 1093static int 1094LoadDataGray(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 1216static void 1217PrintVisualOptions(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 1262static int 1263ParseVisualOptions(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 */ 1414int 1415LoadSCCData(Display *pDpy, int screenNumber, char *filename, int targetFormat) 1416 1417/* 1418 * DESCRIPTION 1419 * Using the X Device Color Characterization Convention (XDCCC) 1420 * read the screen data and store it on the root window of the 1421 * screen. 1422 * 1423 * RETURNS 1424 * Returns 0 if failed; otherwise 1. 1425 * 1426 */ 1427{ 1428 FILE *stream; 1429 char *pStr; 1430 char buf[BUFSIZ]; 1431 char *keyword, *token1, *token2, *token3; 1432 int state = 0; 1433 int VisualFlag = -2; 1434 Window root; 1435 XDCCC_Matrix matrix; 1436 XDCCC_Correction* CorrectionTail = (XDCCC_Correction*)NULL; 1437 XDCCC_Correction* CorrectionHead = (XDCCC_Correction*)NULL; 1438 XDCCC_Correction* pCurrent; 1439 1440 if (screenNumber < 0) { 1441 fprintf(stderr,"Invalid Screen Number %d\n", screenNumber); 1442 return(0); 1443 } 1444 root = RootWindow(pDpy, screenNumber); 1445 1446 if (!root) { 1447 /* if no root window is available then return an error */ 1448 fprintf(stderr,"Could not open root window supplied.\n "); 1449 return (0); 1450 } 1451 /* 1452 * Open the file, determine its size, then read it into memory. 1453 */ 1454 if (filename == NULL) { 1455 stream = stdin; 1456 filename = "stdin"; 1457 } else if ((stream = fopen(filename, "r")) == NULL) { 1458 fprintf(stderr,"Could not open file %s.\n", filename); 1459 return (0); 1460 } 1461 1462 /* 1463 * Advance to starting keyword 1464 * Anything before this keyword is just treated as comments. 1465 */ 1466 1467 while((pStr = nextline(buf, BUFSIZ, stream)) != NULL) { 1468 keyword = strtok(buf, DATA_DELIMS); 1469 if (keyword != (char *)NULL && 1470 (strcmp(keyword, SC_BEGIN_KEYWORD) == 0)) { 1471 break; 1472 } /* else ignore the line */ 1473 } 1474 1475 if (pStr == NULL) { 1476 fprintf(stderr,"File %s is missing %s\n", filename, SC_BEGIN_KEYWORD); 1477 closeS (stream, CorrectionHead); 1478 return (0); 1479 } 1480 1481 token1 = strtok((char*)NULL, DATA_DELIMS); 1482 if ((strcmp(token1, TXT_FORMAT_VERSION) != 0) && 1483 (strcmp(token1, "0.3") != 0)) { 1484 fprintf(stderr, 1485 "Screen data format version mismatch in file %s-- expected %s, found %s\n", 1486 filename, TXT_FORMAT_VERSION, token1); 1487 closeS (stream, CorrectionHead); 1488 return (0); 1489 } 1490 1491 while ((pStr = nextline(buf, BUFSIZ, stream)) != NULL) { 1492 token1 = token2 = token3 = (char*)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; 1663ByPassThisIProfile: 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); 1683IProfileProcessed: 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/* NOTREACHED */ break; 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