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