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