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