1/* $Xorg: xcmsdb.c,v 1.3 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 * xcmsdb.c 26 * 27 * DESCRIPTION 28 * Program to load, query or remove the Screen Color 29 * Characterization Data from the root window of the screen. 30 * 31 */ 32/* $XFree86: xc/programs/xcmsdb/xcmsdb.c,v 1.5 2001/01/17 23:45:19 dawes Exp $ */ 33 34/* 35 * INCLUDES 36 */ 37 38#ifdef HAVE_CONFIG_H 39#include "config.h" 40#endif 41 42#include <stdio.h> 43#include <stdlib.h> 44#include <X11/Xlib.h> 45#include <X11/Xatom.h> 46#include <X11/Xos.h> 47#include <ctype.h> 48 49#include "SCCDFile.h" 50 51static void QuerySCCDataRGB(Display *dpy, Window root); 52static void RemoveSCCData(Display *dpy, Window root, int colorFlag); 53static unsigned long _XcmsGetElement(int format, char **pValue, 54 unsigned long *pCount); 55static int _XcmsGetProperty(Display *pDpy, Window w, Atom property, 56 int *pFormat, unsigned long *pNItems, 57 unsigned long *pNBytes, char **pValue); 58 59static char *ProgramName; 60 61static void 62Syntax(int exitcode) 63{ 64 fprintf(stderr, 65 "usage: %s [-options ...] [filename]\n\n%s", 66 ProgramName, 67 "where options include:\n" 68 " -display host:dpy[.scrn] display to use\n" 69 " -format [ 32 | 16 | 8 ] property format\n" 70 " -query query Screen Color Characterization Data\n" 71 " -remove remove Screen Color Characterization Data\n" 72#ifdef GRAY 73 " -color use color as default\n" 74 " -gray use gray-scale as default\n" 75#endif /* GRAY */ 76 " -version print program version\n" "\n"); 77 exit(exitcode); 78} 79 80static void 81MissingArg(const char *option) 82{ 83 fprintf(stderr, "%s: %s requires an argument\n", ProgramName, option); 84 Syntax(1); 85} 86 87static Bool 88optionmatch(const char *opt, const char *arg, int minlen) 89{ 90 int arglen; 91 92 if (strcmp(opt, arg) == 0) { 93 return (True); 94 } 95 96 if ((arglen = strlen(arg)) >= (int) strlen(opt) || arglen < minlen) { 97 return (False); 98 } 99 100 if (strncmp(opt, arg, arglen) == 0) { 101 return (True); 102 } 103 104 return (False); 105} 106 107int 108main(int argc, char *argv[]) 109{ 110 Display *dpy; 111 char *displayname = NULL; 112 char *filename = NULL; 113 int query = 0; 114 int remove = 0; 115 int load = 0; 116 int color = -1; 117 int targetFormat = 32; 118 119 ProgramName = argv[0]; 120 121 for (int i = 1; i < argc; i++) { 122 char *arg = argv[i]; 123 124 if (arg[0] == '-') { 125 if (arg[1] == '\0') { 126 filename = NULL; 127 continue; 128 } 129 else if (optionmatch("-help", arg, 1)) { 130 Syntax(0); 131 /* doesn't return */ 132 } 133 else if (optionmatch("-display", arg, 1)) { 134 if (++i >= argc) 135 MissingArg("-display"); 136 displayname = argv[i]; 137 continue; 138 } 139 else if (optionmatch("-format", arg, 1)) { 140 if (++i >= argc) 141 MissingArg("-format"); 142 targetFormat = atoi(argv[i]); 143 if (targetFormat != 32 && targetFormat != 16 && 144 targetFormat != 8) { 145 fprintf(stderr, "%s: invalid value for -format: %d\n", 146 ProgramName, targetFormat); 147 Syntax(1); 148 } 149 continue; 150 } 151 else if (optionmatch("-query", arg, 1)) { 152 query = 1; 153 continue; 154 } 155 else if (optionmatch("-remove", arg, 1)) { 156 remove = 1; 157 continue; 158#ifdef GRAY 159 } 160 else if (optionmatch("-color", arg, 1)) { 161 color = 1; 162 continue; 163 } 164 else if (optionmatch("-gray", arg, 1)) { 165 color = 0; 166 continue; 167#endif /* GRAY */ 168 } 169 else if (optionmatch("-version", arg, 1)) { 170 puts(PACKAGE_STRING); 171 exit(0); 172 } 173 fprintf(stderr, "%s: unrecognized option '%s'\n", ProgramName, arg); 174 Syntax(1); 175 } 176 else { 177 load = 1; 178 filename = arg; 179 } 180 } 181 182 /* Open display */ 183 if (!(dpy = XOpenDisplay(displayname))) { 184 fprintf(stderr, "%s: Can't open display '%s'\n", 185 ProgramName, XDisplayName(displayname)); 186 exit(1); 187 } 188 189 if (query || remove) { 190 load = 0; 191 } 192 193 if (load) { 194 LoadSCCData(dpy, DefaultScreen(dpy), filename, targetFormat); 195 } 196 197 if (query) { 198 if (color != 0) 199 QuerySCCDataRGB(dpy, RootWindow(dpy, DefaultScreen(dpy))); 200#ifdef GRAY 201 if (color != 1) 202 QuerySCCDataGray(dpy, RootWindow(dpy, DefaultScreen(dpy))); 203#endif /* GRAY */ 204 } 205 206 if (remove) { 207 RemoveSCCData(dpy, RootWindow(dpy, DefaultScreen(dpy)), color); 208 } 209 210 XCloseDisplay(dpy); 211 exit(0); 212 /*NOTREACHED*/ 213} 214 215static Atom 216ParseAtom(Display *dpy, const char *name, int only_flag) 217{ 218 return (XInternAtom(dpy, name, only_flag)); 219} 220 221/* 222 * NAME 223 * PrintTableType0 224 * 225 * SYNOPSIS 226 */ 227static void 228PrintTableType0(int format, char **pChar, unsigned long *pCount) 229/* 230 * DESCRIPTION 231 * 232 * RETURNS 233 * XcmsFailure if failed. 234 * XcmsSuccess if succeeded. 235 * 236 */ 237{ 238 unsigned int nElements; 239 unsigned short hValue; 240 XcmsFloat fValue; 241 242 nElements = _XcmsGetElement(format, pChar, pCount) + 1; 243 printf("\t length:%d\n", nElements); 244 245 switch (format) { 246 case 8: 247 while (nElements--) { 248 /* 0xFFFF/0xFF = 0x101 */ 249 hValue = _XcmsGetElement(format, pChar, pCount) * 0x101; 250 fValue = _XcmsGetElement(format, pChar, pCount) 251 / (XcmsFloat) 255.0; 252 printf("\t\t0x%x\t%8.5f\n", hValue, fValue); 253 } 254 break; 255 case 16: 256 while (nElements--) { 257 hValue = _XcmsGetElement(format, pChar, pCount); 258 fValue = _XcmsGetElement(format, pChar, pCount) 259 / (XcmsFloat) 65535.0; 260 printf("\t\t0x%x\t%8.5f\n", hValue, fValue); 261 } 262 break; 263 case 32: 264 while (nElements--) { 265 hValue = _XcmsGetElement(format, pChar, pCount); 266 fValue = _XcmsGetElement(format, pChar, pCount) 267 / (XcmsFloat) 4294967295.0; 268 printf("\t\t0x%x\t%8.5f\n", hValue, fValue); 269 } 270 break; 271 default: 272 return; 273 } 274} 275 276/* 277 * NAME 278 * PrintTableType1 279 * 280 * SYNOPSIS 281 */ 282static void 283PrintTableType1(int format, char **pChar, unsigned long *pCount) 284/* 285 * DESCRIPTION 286 * 287 * RETURNS 288 * XcmsFailure if failed. 289 * XcmsSuccess if succeeded. 290 * 291 */ 292{ 293 unsigned int count; 294 unsigned int max_index; 295 unsigned short hValue; 296 XcmsFloat fValue; 297 298 max_index = _XcmsGetElement(format, pChar, pCount); 299 printf("\t length:%d\n", max_index + 1); 300 301 switch (format) { 302 case 8: 303 for (count = 0; count < max_index + 1; count++) { 304 hValue = (count * 65535) / max_index; 305 fValue = _XcmsGetElement(format, pChar, pCount) 306 / (XcmsFloat) 255.0; 307 printf("\t\t0x%x\t%8.5f\n", hValue, fValue); 308 } 309 break; 310 case 16: 311 for (count = 0; count < max_index + 1; count++) { 312 hValue = (count * 65535) / max_index; 313 fValue = _XcmsGetElement(format, pChar, pCount) 314 / (XcmsFloat) 65535.0; 315 printf("\t\t0x%x\t%8.5f\n", hValue, fValue); 316 } 317 break; 318 case 32: 319 for (count = 0; count < max_index + 1; count++) { 320 hValue = (count * 65535) / max_index; 321 fValue = _XcmsGetElement(format, pChar, pCount) 322 / (XcmsFloat) 4294967295.0; 323 printf("\t\t0x%x\t%8.5f\n", hValue, fValue); 324 } 325 break; 326 default: 327 return; 328 } 329} 330 331/* 332 * NAME 333 * QuerySCCData - Query for the SCC data on the root window 334 * 335 * SYNOPSIS 336 */ 337static void 338QuerySCCDataRGB(Display * dpy, Window root) 339/* 340 * DESCRIPTION 341 * 342 * RETURNS 343 * None 344 */ 345{ 346 char *property_return, *pChar; 347 int i, j; 348 int count, format, cType, nTables; 349 unsigned long nitems, nbytes_return; 350 Atom MatricesAtom, CorrectAtom; 351 VisualID visualID; 352 XVisualInfo vinfo_template, *vinfo_ret; 353 int nvis; 354 355 static const char *visual_strings[] = { 356 "StaticGray", 357 "GrayScale", 358 "StaticColor", 359 "PseudoColor", 360 "TrueColor", 361 "DirectColor" 362 }; 363 364 /* 365 * Get Matrices 366 */ 367 MatricesAtom = ParseAtom(dpy, XDCCC_MATRIX_ATOM_NAME, True); 368 if (MatricesAtom != None) { 369 if (_XcmsGetProperty(dpy, root, MatricesAtom, &format, &nitems, 370 &nbytes_return, &property_return) == XcmsFailure) { 371 format = 0; 372 } 373 else if (nitems != 18) { 374 printf("Property %s had invalid length of %ld\n", 375 XDCCC_MATRIX_ATOM_NAME, nitems); 376 if (property_return) { 377 XFree(property_return); 378 } 379 return; 380 } 381 } 382 if (MatricesAtom == None || !format) { 383 printf("Could not find property %s\n", XDCCC_MATRIX_ATOM_NAME); 384 } 385 else if (format != 32) { 386 printf("Data in property %s not in 32 bit format\n", 387 XDCCC_MATRIX_ATOM_NAME); 388 } 389 else { 390 pChar = property_return; 391 printf("Screen: %d\n", DefaultScreen(dpy)); 392 printf("Querying property %s\n", XDCCC_MATRIX_ATOM_NAME); 393 printf("\tXYZtoRGB matrix :\n"); 394 for (i = 0; i < 3; i++) { 395 printf("\t"); 396 for (j = 0; j < 3; j++) { 397 printf("\t%8.5f", 398 (long) _XcmsGetElement(format, &pChar, &nitems) 399 / (XcmsFloat) XDCCC_NUMBER); 400 } 401 printf("\n"); 402 } 403 printf("\tRGBtoXYZ matrix :\n"); 404 for (i = 0; i < 3; i++) { 405 printf("\t"); 406 for (j = 0; j < 3; j++) { 407 printf("\t%8.5f", 408 (long) _XcmsGetElement(format, &pChar, &nitems) 409 / (XcmsFloat) XDCCC_NUMBER); 410 } 411 printf("\n"); 412 } 413 XFree(property_return); 414 } 415 416 /* 417 * Get Intensity Tables 418 */ 419 CorrectAtom = XInternAtom(dpy, XDCCC_CORRECT_ATOM_NAME, True); 420 if (CorrectAtom != None) { 421 if (_XcmsGetProperty(dpy, root, CorrectAtom, &format, &nitems, 422 &nbytes_return, &property_return) == XcmsFailure) { 423 format = 0; 424 } 425 else if (nitems <= 0) { 426 printf("Property %s had invalid length of %ld\n", 427 XDCCC_CORRECT_ATOM_NAME, nitems); 428 if (property_return) { 429 XFree(property_return); 430 } 431 return; 432 } 433 } 434 if (CorrectAtom == None || !format) { 435 printf("Could not find property %s\n", XDCCC_CORRECT_ATOM_NAME); 436 } 437 else { 438 printf("\nQuerying property %s\n", XDCCC_CORRECT_ATOM_NAME); 439 pChar = property_return; 440 441 while (nitems) { 442 switch (format) { 443 case 8: 444 /* 445 * Must have at least: 446 * VisualID0 447 * VisualID1 448 * VisualID2 449 * VisualID3 450 * type 451 * count 452 * length 453 * intensity1 454 * intensity2 455 */ 456 if (nitems < 9) { 457 goto IntensityTblError; 458 } 459 count = 3; 460 break; 461 case 16: 462 /* 463 * Must have at least: 464 * VisualID0 465 * VisualID3 466 * type 467 * count 468 * length 469 * intensity1 470 * intensity2 471 */ 472 if (nitems < 7) { 473 goto IntensityTblError; 474 } 475 count = 1; 476 break; 477 case 32: 478 /* 479 * Must have at least: 480 * VisualID0 481 * type 482 * count 483 * length 484 * intensity1 485 * intensity2 486 */ 487 if (nitems < 6) { 488 goto IntensityTblError; 489 } 490 count = 0; 491 break; 492 default: 493 goto IntensityTblError; 494 } 495 496 /* 497 * Get VisualID 498 */ 499 visualID = _XcmsGetElement(format, &pChar, &nitems); 500 /* add the depth, class, and bits info in output */ 501 vinfo_template.visualid = visualID; 502 vinfo_ret = XGetVisualInfo(dpy, VisualIDMask, &vinfo_template, 503 &nvis); 504 while (count--) { 505 visualID = visualID << format; 506 visualID |= _XcmsGetElement(format, &pChar, &nitems); 507 } 508 509 if (vinfo_ret != NULL) { 510 printf 511 ("\n\tVisualID: 0x%lx class: %s depth: %d bits_per_rgb: %d\n", 512 visualID, visual_strings[vinfo_ret->class], 513 vinfo_ret->depth, vinfo_ret->bits_per_rgb); 514 } 515 else 516 printf("\n\tVisualID: 0x%lx\n", visualID); 517 XFree(vinfo_ret); 518 cType = _XcmsGetElement(format, &pChar, &nitems); 519 printf("\ttype: %d\n", cType); 520 nTables = _XcmsGetElement(format, &pChar, &nitems); 521 printf("\tcount: %d\n", nTables); 522 523 switch (cType) { 524 case 0: 525 /* Red Table should always exist */ 526 printf("\tRed Conversion Table:\n"); 527 PrintTableType0(format, &pChar, &nitems); 528 if (nTables > 1) { 529 printf("\tGreen Conversion Table:\n"); 530 PrintTableType0(format, &pChar, &nitems); 531 printf("\tBlue Conversion Table:\n"); 532 PrintTableType0(format, &pChar, &nitems); 533 } 534 break; 535 case 1: 536 /* Red Table should always exist */ 537 printf("\tRed Conversion Table:\n"); 538 PrintTableType1(format, &pChar, &nitems); 539 if (nTables > 1) { 540 printf("\tGreen Conversion Table:\n"); 541 PrintTableType1(format, &pChar, &nitems); 542 printf("\tBlue Conversion Table:\n"); 543 PrintTableType1(format, &pChar, &nitems); 544 } 545 break; 546 default: 547 goto IntensityTblError; 548 } 549 } 550 XFree(property_return); 551 } 552 return; 553 554 IntensityTblError: 555 XFree(property_return); 556 printf("Fatal error in %s property\n", XDCCC_CORRECT_ATOM_NAME); 557} 558 559#ifdef GRAY 560 561/* 562 * NAME 563 * QuerySCCDataGray - Query for the SCC data on the root window 564 * 565 * SYNOPSIS 566 */ 567int 568QuerySCCDataGray(Display * dpy, Window root) 569/* 570 * DESCRIPTION 571 * 572 * RETURNS 573 * None 574 */ 575{ 576 char *property_return, *pChar; 577 int count, format, cType; 578 unsigned long nitems, nbytes_return; 579 Atom MatricesAtom, CorrectAtom; 580 VisualID visualID; 581 582 MatricesAtom = ParseAtom(dpy, XDCCC_SCREENWHITEPT_ATOM_NAME, True); 583 if (MatricesAtom != None) { 584 if (_XcmsGetProperty(dpy, root, MatricesAtom, &format, &nitems, 585 &nbytes_return, &property_return) == XcmsFailure) { 586 format = 0; 587 } 588 else if (nitems != 3) { 589 printf("Property %s had invalid length of %d\n", 590 XDCCC_SCREENWHITEPT_ATOM_NAME, nitems); 591 if (property_return) { 592 XFree(property_return); 593 } 594 return; 595 } 596 } 597 if (MatricesAtom == None || !format) { 598 printf("Could not find property %s\n", XDCCC_SCREENWHITEPT_ATOM_NAME); 599 } 600 else { 601 pChar = property_return; 602 printf("\nQuerying property %s\n", XDCCC_SCREENWHITEPT_ATOM_NAME); 603 printf("\tWhite Point XYZ :\n"); 604 printf("\t"); 605 for (int j = 0; j < 3; j++) { 606 printf("\t%8.5lf", 607 (long) _XcmsGetElement(format, &pChar, &nitems) / 608 (XcmsFloat) XDCCC_NUMBER); 609 } 610 printf("\n"); 611 XFree(property_return); 612 } 613 614 CorrectAtom = XInternAtom(dpy, XDCCC_GRAY_CORRECT_ATOM_NAME, True); 615 if (CorrectAtom != None) { 616 if (_XcmsGetProperty(dpy, root, CorrectAtom, &format, &nitems, 617 &nbytes_return, &property_return) == XcmsFailure) { 618 format = 0; 619 } 620 else if (nitems <= 0) { 621 printf("Property %s had invalid length of %d\n", 622 XDCCC_GRAY_CORRECT_ATOM_NAME, nitems); 623 if (property_return) { 624 XFree(property_return); 625 } 626 return; 627 } 628 } 629 if (CorrectAtom == None || !format) { 630 printf("Could not find property %s\n", XDCCC_GRAY_CORRECT_ATOM_NAME); 631 } 632 else { 633 printf("\nQuerying property %s\n\n", XDCCC_GRAY_CORRECT_ATOM_NAME); 634 pChar = property_return; 635 636 while (nitems) { 637 switch (format) { 638 case 8: 639 /* 640 * Must have at least: 641 * VisualID0 642 * VisualID1 643 * VisualID2 644 * VisualID3 645 * type 646 * count 647 * length 648 * intensity1 649 * intensity2 650 */ 651 if (nitems < 9) { 652 goto IntensityTblError; 653 } 654 count = 3; 655 break; 656 case 16: 657 /* 658 * Must have at least: 659 * VisualID0 660 * VisualID3 661 * type 662 * count 663 * length 664 * intensity1 665 * intensity2 666 */ 667 if (nitems < 7) { 668 goto IntensityTblError; 669 } 670 count = 1; 671 break; 672 case 32: 673 /* 674 * Must have at least: 675 * VisualID0 676 * type 677 * count 678 * length 679 * intensity1 680 * intensity2 681 */ 682 if (nitems < 6) { 683 goto IntensityTblError; 684 } 685 count = 0; 686 break; 687 default: 688 goto IntensityTblError; 689 break; 690 } 691 692 /* 693 * Get VisualID 694 */ 695 visualID = _XcmsGetElement(format, &pChar, &nitems); 696 while (count--) { 697 visualID = visualID << format; 698 visualID |= _XcmsGetElement(format, &pChar, &nitems); 699 } 700 701 printf("\n\tVisualID: 0x%lx\n", visualID); 702 cType = _XcmsGetElement(format, &pChar, &nitems); 703 printf("\ttype: %d\n", cType); 704 printf("\tGray Conversion Table:\n"); 705 switch (cType) { 706 case 0: 707 PrintTableType0(format, &pChar, &nitems); 708 break; 709 case 1: 710 PrintTableType1(format, &pChar, &nitems); 711 break; 712 default: 713 goto IntensityTblError; 714 } 715 } 716 XFree(property_return); 717 } 718 return; 719 IntensityTblError: 720 XFree(property_return); 721 printf("Fatal error in %s property\n", XDCCC_CORRECT_ATOM_NAME); 722} 723#endif /* GRAY */ 724 725/* 726 * NAME 727 * RemoveSCCData - Remove for the SCC data on the root window 728 * 729 * SYNOPSIS 730 */ 731static void 732RemoveSCCData(Display *dpy, Window root, int colorFlag) 733/* 734 * DESCRIPTION 735 * 736 * RETURNS 737 * None 738 */ 739{ 740 unsigned char *ret_prop; 741 unsigned long ret_len, ret_after; 742 int ret_format, status = -1; 743 Atom MatricesAtom, CorrectAtom, ret_atom; 744 745 if (colorFlag != 0) { 746 MatricesAtom = ParseAtom(dpy, XDCCC_MATRIX_ATOM_NAME, True); 747 if (MatricesAtom != None) { 748 status = XGetWindowProperty(dpy, root, MatricesAtom, 0, 8192, 749 False, XA_INTEGER, &ret_atom, 750 &ret_format, &ret_len, &ret_after, 751 &ret_prop); 752 } 753 if (MatricesAtom == None || status != Success || !ret_format) { 754 printf("Could not find property %s\n", XDCCC_MATRIX_ATOM_NAME); 755 } 756 else { 757 printf("Deleting property %s\n", XDCCC_MATRIX_ATOM_NAME); 758 XDeleteProperty(dpy, root, MatricesAtom); 759 XFree(ret_prop); 760 } 761 762 CorrectAtom = XInternAtom(dpy, XDCCC_CORRECT_ATOM_NAME, True); 763 if (CorrectAtom != None) { 764 status = XGetWindowProperty(dpy, root, CorrectAtom, 0, 8192, 765 False, XA_INTEGER, &ret_atom, 766 &ret_format, &ret_len, &ret_after, 767 &ret_prop); 768 } 769 if (CorrectAtom == None || status != Success || !ret_format) { 770 printf("Could not find property %s\n", XDCCC_CORRECT_ATOM_NAME); 771 } 772 else { 773 printf("Deleting property %s\n", XDCCC_CORRECT_ATOM_NAME); 774 XDeleteProperty(dpy, root, CorrectAtom); 775 XFree(ret_prop); 776 } 777 } 778#ifdef GRAY 779 if (colorFlag != 1) { 780 MatricesAtom = ParseAtom(dpy, XDCCC_SCREENWHITEPT_ATOM_NAME, True); 781 if (MatricesAtom != None) { 782 status = XGetWindowProperty(dpy, root, MatricesAtom, 0, 8192, 783 False, XA_INTEGER, &ret_atom, 784 &ret_format, &ret_len, &ret_after, 785 &ret_prop); 786 } 787 if (MatricesAtom == None || status != Success || !ret_format) { 788 printf("Could not find property %s\n", 789 XDCCC_SCREENWHITEPT_ATOM_NAME); 790 } 791 else { 792 printf("Deleting property %s\n", XDCCC_SCREENWHITEPT_ATOM_NAME); 793 XDeleteProperty(dpy, root, MatricesAtom); 794 XFree(ret_prop); 795 } 796 797 CorrectAtom = XInternAtom(dpy, XDCCC_GRAY_CORRECT_ATOM_NAME, True); 798 if (CorrectAtom != None) { 799 status = XGetWindowProperty(dpy, root, CorrectAtom, 0, 8192, 800 False, XA_INTEGER, &ret_atom, 801 &ret_format, &ret_len, &ret_after, 802 &ret_prop); 803 } 804 if (CorrectAtom == None || status != Success || !ret_format) { 805 printf("Could not find property %s\n", 806 XDCCC_GRAY_CORRECT_ATOM_NAME); 807 } 808 else { 809 printf("Deleting property %s\n", XDCCC_GRAY_CORRECT_ATOM_NAME); 810 XDeleteProperty(dpy, root, CorrectAtom); 811 XFree(ret_prop); 812 } 813 } 814#endif /* GRAY */ 815} 816 817static unsigned long 818_XcmsGetElement(int format, char **pValue, unsigned long *pCount) 819/* 820 * DESCRIPTION 821 * Get the next element from the property and return it. 822 * Also increment the pointer the amount needed. 823 * 824 * Returns 825 * unsigned long 826 */ 827{ 828 unsigned long value; 829 830 switch (format) { 831 case 32: 832 value = *((unsigned long *) (*pValue)) & 0xFFFFFFFF; 833 *pValue += sizeof(unsigned long); 834 *pCount -= 1; 835 break; 836 case 16: 837 value = *((unsigned short *) (*pValue)); 838 *pValue += sizeof(unsigned short); 839 *pCount -= 1; 840 break; 841 case 8: 842 value = *((unsigned char *) (*pValue)); 843 *pValue += 1; 844 *pCount -= 1; 845 break; 846 default: 847 value = 0; 848 break; 849 } 850 return (value); 851} 852 853/* 854 * NAME 855 * _XcmsGetProperty -- Determine the existence of a property 856 * 857 * SYNOPSIS 858 */ 859static int 860_XcmsGetProperty(Display *pDpy, Window w, Atom property, int *pFormat, 861 unsigned long *pNItems, unsigned long *pNBytes, char **pValue) 862/* 863 * DESCRIPTION 864 * 865 * Returns 866 * 0 if property does not exist. 867 * 1 if property exists. 868 */ 869{ 870 char *prop_ret; 871 int format_ret; 872 long len = 6516; 873 unsigned long nitems_ret, after_ret; 874 Atom atom_ret; 875 int xgwp_ret; 876 877 while (True) { 878 xgwp_ret = XGetWindowProperty(pDpy, w, property, 0, len, False, 879 XA_INTEGER, &atom_ret, &format_ret, 880 &nitems_ret, &after_ret, 881 (unsigned char **) &prop_ret); 882 if (xgwp_ret == Success && after_ret > 0) { 883 len += nitems_ret * (format_ret >> 3); 884 XFree(prop_ret); 885 } 886 else { 887 break; 888 } 889 } 890 if (xgwp_ret != Success || format_ret == 0 || nitems_ret == 0) { 891 /* the property does not exist or is of an unexpected type or 892 getting window property failed */ 893 return (XcmsFailure); 894 } 895 896 *pFormat = format_ret; 897 *pNItems = nitems_ret; 898 *pNBytes = nitems_ret * (format_ret >> 3); 899 *pValue = prop_ret; 900 return (XcmsSuccess); 901} 902