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