12c7c4e3dSmrg/* $Xorg: xcmsdb.c,v 1.3 2000/08/17 19:54:13 cpqbld Exp $ */
22c7c4e3dSmrg
32c7c4e3dSmrg/*
42c7c4e3dSmrg * (c) Copyright 1990 Tektronix Inc.
52c7c4e3dSmrg * 	All Rights Reserved
62c7c4e3dSmrg *
72c7c4e3dSmrg * Permission to use, copy, modify, and distribute this software and its
82c7c4e3dSmrg * documentation for any purpose and without fee is hereby granted,
92c7c4e3dSmrg * provided that the above copyright notice appear in all copies and that
102c7c4e3dSmrg * both that copyright notice and this permission notice appear in
112c7c4e3dSmrg * supporting documentation, and that the name of Tektronix not be used
122c7c4e3dSmrg * in advertising or publicity pertaining to distribution of the software
132c7c4e3dSmrg * without specific, written prior permission.
142c7c4e3dSmrg *
152c7c4e3dSmrg * Tektronix disclaims all warranties with regard to this software, including
162c7c4e3dSmrg * all implied warranties of merchantability and fitness, in no event shall
172c7c4e3dSmrg * Tektronix be liable for any special, indirect or consequential damages or
182c7c4e3dSmrg * any damages whatsoever resulting from loss of use, data or profits,
192c7c4e3dSmrg * whether in an action of contract, negligence or other tortious action,
202c7c4e3dSmrg * arising out of or in connection with the use or performance of this
212c7c4e3dSmrg * software.
222c7c4e3dSmrg *
232c7c4e3dSmrg *
242c7c4e3dSmrg *	NAME
252c7c4e3dSmrg *		xcmsdb.c
262c7c4e3dSmrg *
272c7c4e3dSmrg *	DESCRIPTION
282becc446Smrg *		Program to load, query or remove the Screen Color
292c7c4e3dSmrg *		Characterization Data from the root window of the screen.
302c7c4e3dSmrg *
312c7c4e3dSmrg */
322c7c4e3dSmrg/* $XFree86: xc/programs/xcmsdb/xcmsdb.c,v 1.5 2001/01/17 23:45:19 dawes Exp $ */
332c7c4e3dSmrg
342c7c4e3dSmrg/*
352c7c4e3dSmrg *      INCLUDES
362c7c4e3dSmrg */
372c7c4e3dSmrg
382becc446Smrg#ifdef HAVE_CONFIG_H
393458e6c2Smrg#include "config.h"
402becc446Smrg#endif
412becc446Smrg
422c7c4e3dSmrg#include <stdio.h>
432c7c4e3dSmrg#include <stdlib.h>
442c7c4e3dSmrg#include <X11/Xlib.h>
452c7c4e3dSmrg#include <X11/Xatom.h>
462c7c4e3dSmrg#include <X11/Xos.h>
472c7c4e3dSmrg#include <ctype.h>
482c7c4e3dSmrg
492c7c4e3dSmrg#include "SCCDFile.h"
502c7c4e3dSmrg
512c7c4e3dSmrgstatic void QuerySCCDataRGB(Display *dpy, Window root);
522c7c4e3dSmrgstatic void RemoveSCCData(Display *dpy, Window root, int colorFlag);
532becc446Smrgstatic unsigned long _XcmsGetElement(int format, char **pValue,
543458e6c2Smrg                                     unsigned long *pCount);
552becc446Smrgstatic int _XcmsGetProperty(Display *pDpy, Window w, Atom property,
563458e6c2Smrg                            int *pFormat, unsigned long *pNItems,
573458e6c2Smrg                            unsigned long *pNBytes, char **pValue);
582c7c4e3dSmrg
598650bb69Smrgstatic char *ProgramName;
602c7c4e3dSmrg
612c7c4e3dSmrgstatic void
623458e6c2SmrgSyntax(int exitcode)
632c7c4e3dSmrg{
643458e6c2Smrg    fprintf(stderr,
653458e6c2Smrg            "usage:  %s [-options ...] [filename]\n\n%s",
663458e6c2Smrg            ProgramName,
673458e6c2Smrg            "where options include:\n"
683458e6c2Smrg            "    -display host:dpy[.scrn]     display to use\n"
693458e6c2Smrg            "    -format [ 32 | 16 | 8 ]      property format\n"
703458e6c2Smrg            "    -query                       query Screen Color Characterization Data\n"
713458e6c2Smrg            "    -remove                      remove Screen Color Characterization Data\n"
722c7c4e3dSmrg#ifdef GRAY
733458e6c2Smrg            "    -color                       use color as default\n"
743458e6c2Smrg            "    -gray                        use gray-scale as default\n"
753458e6c2Smrg#endif                          /* GRAY */
763458e6c2Smrg            "    -version                     print program version\n" "\n");
773458e6c2Smrg    exit(exitcode);
782becc446Smrg}
792becc446Smrg
802becc446Smrgstatic void
813458e6c2SmrgMissingArg(const char *option)
822becc446Smrg{
833458e6c2Smrg    fprintf(stderr, "%s: %s requires an argument\n", ProgramName, option);
843458e6c2Smrg    Syntax(1);
852c7c4e3dSmrg}
862c7c4e3dSmrg
872becc446Smrgstatic Bool
882becc446Smrgoptionmatch(const char *opt, const char *arg, int minlen)
892c7c4e3dSmrg{
902c7c4e3dSmrg    int arglen;
912c7c4e3dSmrg
922c7c4e3dSmrg    if (strcmp(opt, arg) == 0) {
933458e6c2Smrg        return (True);
942c7c4e3dSmrg    }
952c7c4e3dSmrg
963458e6c2Smrg    if ((arglen = strlen(arg)) >= (int) strlen(opt) || arglen < minlen) {
973458e6c2Smrg        return (False);
982c7c4e3dSmrg    }
992c7c4e3dSmrg
1003458e6c2Smrg    if (strncmp(opt, arg, arglen) == 0) {
1013458e6c2Smrg        return (True);
1022c7c4e3dSmrg    }
1032becc446Smrg
1043458e6c2Smrg    return (False);
1052c7c4e3dSmrg}
1062c7c4e3dSmrg
1072c7c4e3dSmrgint
1082c7c4e3dSmrgmain(int argc, char *argv[])
1092c7c4e3dSmrg{
1102c7c4e3dSmrg    Display *dpy;
1112c7c4e3dSmrg    char *displayname = NULL;
1122c7c4e3dSmrg    char *filename = NULL;
1132c7c4e3dSmrg    int query = 0;
1142c7c4e3dSmrg    int remove = 0;
1152c7c4e3dSmrg    int load = 0;
1162c7c4e3dSmrg    int color = -1;
1172c7c4e3dSmrg    int targetFormat = 32;
1182c7c4e3dSmrg
1192c7c4e3dSmrg    ProgramName = argv[0];
1202c7c4e3dSmrg
121c1e8faa6Smrg    for (int i = 1; i < argc; i++) {
1223458e6c2Smrg        char *arg = argv[i];
1233458e6c2Smrg
1243458e6c2Smrg        if (arg[0] == '-') {
1253458e6c2Smrg            if (arg[1] == '\0') {
1263458e6c2Smrg                filename = NULL;
1273458e6c2Smrg                continue;
1283458e6c2Smrg            }
1293458e6c2Smrg            else if (optionmatch("-help", arg, 1)) {
1303458e6c2Smrg                Syntax(0);
1313458e6c2Smrg                /* doesn't return */
1323458e6c2Smrg            }
1333458e6c2Smrg            else if (optionmatch("-display", arg, 1)) {
1343458e6c2Smrg                if (++i >= argc)
1353458e6c2Smrg                    MissingArg("-display");
1363458e6c2Smrg                displayname = argv[i];
1373458e6c2Smrg                continue;
1383458e6c2Smrg            }
1393458e6c2Smrg            else if (optionmatch("-format", arg, 1)) {
1403458e6c2Smrg                if (++i >= argc)
1413458e6c2Smrg                    MissingArg("-format");
1423458e6c2Smrg                targetFormat = atoi(argv[i]);
1433458e6c2Smrg                if (targetFormat != 32 && targetFormat != 16 &&
1443458e6c2Smrg                    targetFormat != 8) {
1453458e6c2Smrg                    fprintf(stderr, "%s: invalid value for -format: %d\n",
1463458e6c2Smrg                            ProgramName, targetFormat);
1473458e6c2Smrg                    Syntax(1);
1483458e6c2Smrg                }
1493458e6c2Smrg                continue;
1503458e6c2Smrg            }
1513458e6c2Smrg            else if (optionmatch("-query", arg, 1)) {
1523458e6c2Smrg                query = 1;
1533458e6c2Smrg                continue;
1543458e6c2Smrg            }
1553458e6c2Smrg            else if (optionmatch("-remove", arg, 1)) {
1563458e6c2Smrg                remove = 1;
1573458e6c2Smrg                continue;
1582c7c4e3dSmrg#ifdef GRAY
1593458e6c2Smrg            }
1603458e6c2Smrg            else if (optionmatch("-color", arg, 1)) {
1613458e6c2Smrg                color = 1;
1623458e6c2Smrg                continue;
1633458e6c2Smrg            }
1643458e6c2Smrg            else if (optionmatch("-gray", arg, 1)) {
1653458e6c2Smrg                color = 0;
1663458e6c2Smrg                continue;
1673458e6c2Smrg#endif                          /* GRAY */
1683458e6c2Smrg            }
1693458e6c2Smrg            else if (optionmatch("-version", arg, 1)) {
1703458e6c2Smrg                puts(PACKAGE_STRING);
1713458e6c2Smrg                exit(0);
1723458e6c2Smrg            }
1733458e6c2Smrg            fprintf(stderr, "%s: unrecognized option '%s'\n", ProgramName, arg);
1743458e6c2Smrg            Syntax(1);
1753458e6c2Smrg        }
1763458e6c2Smrg        else {
1773458e6c2Smrg            load = 1;
1783458e6c2Smrg            filename = arg;
1793458e6c2Smrg        }
1802c7c4e3dSmrg    }
1812c7c4e3dSmrg
1822becc446Smrg    /* Open display  */
1833458e6c2Smrg    if (!(dpy = XOpenDisplay(displayname))) {
1843458e6c2Smrg        fprintf(stderr, "%s:  Can't open display '%s'\n",
1853458e6c2Smrg                ProgramName, XDisplayName(displayname));
1863458e6c2Smrg        exit(1);
1872c7c4e3dSmrg    }
1882c7c4e3dSmrg
18916d7e2f1Smrg    if (query || remove) {
1903458e6c2Smrg        load = 0;
1912c7c4e3dSmrg    }
1922c7c4e3dSmrg
19316d7e2f1Smrg    if (load) {
1943458e6c2Smrg        LoadSCCData(dpy, DefaultScreen(dpy), filename, targetFormat);
1952c7c4e3dSmrg    }
1962c7c4e3dSmrg
1972c7c4e3dSmrg    if (query) {
1983458e6c2Smrg        if (color != 0)
1993458e6c2Smrg            QuerySCCDataRGB(dpy, RootWindow(dpy, DefaultScreen(dpy)));
2002c7c4e3dSmrg#ifdef GRAY
2013458e6c2Smrg        if (color != 1)
2023458e6c2Smrg            QuerySCCDataGray(dpy, RootWindow(dpy, DefaultScreen(dpy)));
2032c7c4e3dSmrg#endif /* GRAY */
2042c7c4e3dSmrg    }
2052c7c4e3dSmrg
2062c7c4e3dSmrg    if (remove) {
2073458e6c2Smrg        RemoveSCCData(dpy, RootWindow(dpy, DefaultScreen(dpy)), color);
2082c7c4e3dSmrg    }
2092c7c4e3dSmrg
2102c7c4e3dSmrg    XCloseDisplay(dpy);
2113458e6c2Smrg    exit(0);
2122c7c4e3dSmrg    /*NOTREACHED*/
2132c7c4e3dSmrg}
2142c7c4e3dSmrg
2152c7c4e3dSmrgstatic Atom
2162becc446SmrgParseAtom(Display *dpy, const char *name, int only_flag)
2172c7c4e3dSmrg{
2183458e6c2Smrg    return (XInternAtom(dpy, name, only_flag));
2192c7c4e3dSmrg}
2202c7c4e3dSmrg
2212c7c4e3dSmrg/*
2222c7c4e3dSmrg *	NAME
2232c7c4e3dSmrg *		PrintTableType0
2242c7c4e3dSmrg *
2252c7c4e3dSmrg *	SYNOPSIS
2262c7c4e3dSmrg */
2272c7c4e3dSmrgstatic void
2282c7c4e3dSmrgPrintTableType0(int format, char **pChar, unsigned long *pCount)
2292c7c4e3dSmrg/*
2302c7c4e3dSmrg *	DESCRIPTION
2312c7c4e3dSmrg *
2322c7c4e3dSmrg *	RETURNS
2332c7c4e3dSmrg *		XcmsFailure if failed.
2342c7c4e3dSmrg *		XcmsSuccess if succeeded.
2352c7c4e3dSmrg *
2362c7c4e3dSmrg */
2372c7c4e3dSmrg{
2382c7c4e3dSmrg    unsigned int nElements;
2392c7c4e3dSmrg    unsigned short hValue;
2402c7c4e3dSmrg    XcmsFloat fValue;
2412c7c4e3dSmrg
2422c7c4e3dSmrg    nElements = _XcmsGetElement(format, pChar, pCount) + 1;
2433458e6c2Smrg    printf("\t    length:%d\n", nElements);
2442c7c4e3dSmrg
2452c7c4e3dSmrg    switch (format) {
2463458e6c2Smrg    case 8:
2473458e6c2Smrg        while (nElements--) {
2483458e6c2Smrg            /* 0xFFFF/0xFF = 0x101 */
2493458e6c2Smrg            hValue = _XcmsGetElement(format, pChar, pCount) * 0x101;
2503458e6c2Smrg            fValue = _XcmsGetElement(format, pChar, pCount)
2513458e6c2Smrg                / (XcmsFloat) 255.0;
2523458e6c2Smrg            printf("\t\t0x%x\t%8.5f\n", hValue, fValue);
2533458e6c2Smrg        }
2543458e6c2Smrg        break;
2553458e6c2Smrg    case 16:
2563458e6c2Smrg        while (nElements--) {
2573458e6c2Smrg            hValue = _XcmsGetElement(format, pChar, pCount);
2583458e6c2Smrg            fValue = _XcmsGetElement(format, pChar, pCount)
2593458e6c2Smrg                / (XcmsFloat) 65535.0;
2603458e6c2Smrg            printf("\t\t0x%x\t%8.5f\n", hValue, fValue);
2613458e6c2Smrg        }
2623458e6c2Smrg        break;
2633458e6c2Smrg    case 32:
2643458e6c2Smrg        while (nElements--) {
2653458e6c2Smrg            hValue = _XcmsGetElement(format, pChar, pCount);
2663458e6c2Smrg            fValue = _XcmsGetElement(format, pChar, pCount)
2673458e6c2Smrg                / (XcmsFloat) 4294967295.0;
2683458e6c2Smrg            printf("\t\t0x%x\t%8.5f\n", hValue, fValue);
2693458e6c2Smrg        }
2703458e6c2Smrg        break;
2713458e6c2Smrg    default:
2723458e6c2Smrg        return;
2732c7c4e3dSmrg    }
2742c7c4e3dSmrg}
2752c7c4e3dSmrg
2762c7c4e3dSmrg/*
2772c7c4e3dSmrg *	NAME
2782c7c4e3dSmrg *		PrintTableType1
2792c7c4e3dSmrg *
2802c7c4e3dSmrg *	SYNOPSIS
2812c7c4e3dSmrg */
2822c7c4e3dSmrgstatic void
2832c7c4e3dSmrgPrintTableType1(int format, char **pChar, unsigned long *pCount)
2842c7c4e3dSmrg/*
2852c7c4e3dSmrg *	DESCRIPTION
2862c7c4e3dSmrg *
2872c7c4e3dSmrg *	RETURNS
2882c7c4e3dSmrg *		XcmsFailure if failed.
2892c7c4e3dSmrg *		XcmsSuccess if succeeded.
2902c7c4e3dSmrg *
2912c7c4e3dSmrg */
2922c7c4e3dSmrg{
2933458e6c2Smrg    unsigned int count;
2942c7c4e3dSmrg    unsigned int max_index;
2952c7c4e3dSmrg    unsigned short hValue;
2962c7c4e3dSmrg    XcmsFloat fValue;
2972c7c4e3dSmrg
2982c7c4e3dSmrg    max_index = _XcmsGetElement(format, pChar, pCount);
2993458e6c2Smrg    printf("\t    length:%d\n", max_index + 1);
3002c7c4e3dSmrg
3012c7c4e3dSmrg    switch (format) {
3023458e6c2Smrg    case 8:
3033458e6c2Smrg        for (count = 0; count < max_index + 1; count++) {
3043458e6c2Smrg            hValue = (count * 65535) / max_index;
3053458e6c2Smrg            fValue = _XcmsGetElement(format, pChar, pCount)
3063458e6c2Smrg                / (XcmsFloat) 255.0;
3073458e6c2Smrg            printf("\t\t0x%x\t%8.5f\n", hValue, fValue);
3083458e6c2Smrg        }
3093458e6c2Smrg        break;
3103458e6c2Smrg    case 16:
3113458e6c2Smrg        for (count = 0; count < max_index + 1; count++) {
3123458e6c2Smrg            hValue = (count * 65535) / max_index;
3133458e6c2Smrg            fValue = _XcmsGetElement(format, pChar, pCount)
3143458e6c2Smrg                / (XcmsFloat) 65535.0;
3153458e6c2Smrg            printf("\t\t0x%x\t%8.5f\n", hValue, fValue);
3163458e6c2Smrg        }
3173458e6c2Smrg        break;
3183458e6c2Smrg    case 32:
3193458e6c2Smrg        for (count = 0; count < max_index + 1; count++) {
3203458e6c2Smrg            hValue = (count * 65535) / max_index;
3213458e6c2Smrg            fValue = _XcmsGetElement(format, pChar, pCount)
3223458e6c2Smrg                / (XcmsFloat) 4294967295.0;
3233458e6c2Smrg            printf("\t\t0x%x\t%8.5f\n", hValue, fValue);
3243458e6c2Smrg        }
3253458e6c2Smrg        break;
3263458e6c2Smrg    default:
3273458e6c2Smrg        return;
3282c7c4e3dSmrg    }
3292c7c4e3dSmrg}
3302c7c4e3dSmrg
3312c7c4e3dSmrg/*
3322c7c4e3dSmrg *      NAME
3332c7c4e3dSmrg *		QuerySCCData - Query for the SCC data on the root window
3342c7c4e3dSmrg *
3352c7c4e3dSmrg *      SYNOPSIS
3362c7c4e3dSmrg */
3372c7c4e3dSmrgstatic void
3383458e6c2SmrgQuerySCCDataRGB(Display * dpy, Window root)
3392c7c4e3dSmrg/*
3402c7c4e3dSmrg *      DESCRIPTION
3412c7c4e3dSmrg *
3422c7c4e3dSmrg *      RETURNS
3432c7c4e3dSmrg *		None
3442c7c4e3dSmrg */
3452c7c4e3dSmrg{
3462c7c4e3dSmrg    char *property_return, *pChar;
3473458e6c2Smrg    int i, j;
3483458e6c2Smrg    int count, format, cType, nTables;
3492c7c4e3dSmrg    unsigned long nitems, nbytes_return;
3502c7c4e3dSmrg    Atom MatricesAtom, CorrectAtom;
3512c7c4e3dSmrg    VisualID visualID;
3522c7c4e3dSmrg    XVisualInfo vinfo_template, *vinfo_ret;
3532c7c4e3dSmrg    int nvis;
3543458e6c2Smrg
3552becc446Smrg    static const char *visual_strings[] = {
3563458e6c2Smrg        "StaticGray",
3573458e6c2Smrg        "GrayScale",
3583458e6c2Smrg        "StaticColor",
3593458e6c2Smrg        "PseudoColor",
3603458e6c2Smrg        "TrueColor",
3613458e6c2Smrg        "DirectColor"
3623458e6c2Smrg    };
3632c7c4e3dSmrg
3642c7c4e3dSmrg    /*
3652c7c4e3dSmrg     * Get Matrices
3662c7c4e3dSmrg     */
3673458e6c2Smrg    MatricesAtom = ParseAtom(dpy, XDCCC_MATRIX_ATOM_NAME, True);
3682c7c4e3dSmrg    if (MatricesAtom != None) {
3693458e6c2Smrg        if (_XcmsGetProperty(dpy, root, MatricesAtom, &format, &nitems,
3703458e6c2Smrg                             &nbytes_return, &property_return) == XcmsFailure) {
3713458e6c2Smrg            format = 0;
3723458e6c2Smrg        }
3733458e6c2Smrg        else if (nitems != 18) {
3743458e6c2Smrg            printf("Property %s had invalid length of %ld\n",
3753458e6c2Smrg                   XDCCC_MATRIX_ATOM_NAME, nitems);
3763458e6c2Smrg            if (property_return) {
3773458e6c2Smrg                XFree(property_return);
3783458e6c2Smrg            }
3793458e6c2Smrg            return;
3803458e6c2Smrg        }
3812becc446Smrg    }
3822c7c4e3dSmrg    if (MatricesAtom == None || !format) {
3833458e6c2Smrg        printf("Could not find property %s\n", XDCCC_MATRIX_ATOM_NAME);
3843458e6c2Smrg    }
3853458e6c2Smrg    else if (format != 32) {
3863458e6c2Smrg        printf("Data in property %s not in 32 bit format\n",
3873458e6c2Smrg               XDCCC_MATRIX_ATOM_NAME);
3883458e6c2Smrg    }
3893458e6c2Smrg    else {
3903458e6c2Smrg        pChar = property_return;
3913458e6c2Smrg        printf("Screen: %d\n", DefaultScreen(dpy));
3923458e6c2Smrg        printf("Querying property %s\n", XDCCC_MATRIX_ATOM_NAME);
3933458e6c2Smrg        printf("\tXYZtoRGB matrix :\n");
3943458e6c2Smrg        for (i = 0; i < 3; i++) {
3953458e6c2Smrg            printf("\t");
3963458e6c2Smrg            for (j = 0; j < 3; j++) {
3973458e6c2Smrg                printf("\t%8.5f",
3983458e6c2Smrg                       (long) _XcmsGetElement(format, &pChar, &nitems)
3993458e6c2Smrg                       / (XcmsFloat) XDCCC_NUMBER);
4003458e6c2Smrg            }
4013458e6c2Smrg            printf("\n");
4023458e6c2Smrg        }
4033458e6c2Smrg        printf("\tRGBtoXYZ matrix :\n");
4043458e6c2Smrg        for (i = 0; i < 3; i++) {
4053458e6c2Smrg            printf("\t");
4063458e6c2Smrg            for (j = 0; j < 3; j++) {
4073458e6c2Smrg                printf("\t%8.5f",
4083458e6c2Smrg                       (long) _XcmsGetElement(format, &pChar, &nitems)
4093458e6c2Smrg                       / (XcmsFloat) XDCCC_NUMBER);
4103458e6c2Smrg            }
4113458e6c2Smrg            printf("\n");
4123458e6c2Smrg        }
4133458e6c2Smrg        XFree(property_return);
4142c7c4e3dSmrg    }
4152c7c4e3dSmrg
4162c7c4e3dSmrg    /*
4172c7c4e3dSmrg     * Get Intensity Tables
4182c7c4e3dSmrg     */
4193458e6c2Smrg    CorrectAtom = XInternAtom(dpy, XDCCC_CORRECT_ATOM_NAME, True);
4202c7c4e3dSmrg    if (CorrectAtom != None) {
4213458e6c2Smrg        if (_XcmsGetProperty(dpy, root, CorrectAtom, &format, &nitems,
4223458e6c2Smrg                             &nbytes_return, &property_return) == XcmsFailure) {
4233458e6c2Smrg            format = 0;
4243458e6c2Smrg        }
4253458e6c2Smrg        else if (nitems <= 0) {
4263458e6c2Smrg            printf("Property %s had invalid length of %ld\n",
4273458e6c2Smrg                   XDCCC_CORRECT_ATOM_NAME, nitems);
4283458e6c2Smrg            if (property_return) {
4293458e6c2Smrg                XFree(property_return);
4303458e6c2Smrg            }
4313458e6c2Smrg            return;
4323458e6c2Smrg        }
4332c7c4e3dSmrg    }
4342c7c4e3dSmrg    if (CorrectAtom == None || !format) {
4353458e6c2Smrg        printf("Could not find property %s\n", XDCCC_CORRECT_ATOM_NAME);
4363458e6c2Smrg    }
4373458e6c2Smrg    else {
4383458e6c2Smrg        printf("\nQuerying property %s\n", XDCCC_CORRECT_ATOM_NAME);
4393458e6c2Smrg        pChar = property_return;
4403458e6c2Smrg
4413458e6c2Smrg        while (nitems) {
4423458e6c2Smrg            switch (format) {
4433458e6c2Smrg            case 8:
4443458e6c2Smrg                /*
4453458e6c2Smrg                 * Must have at least:
4463458e6c2Smrg                 *              VisualID0
4473458e6c2Smrg                 *              VisualID1
4483458e6c2Smrg                 *              VisualID2
4493458e6c2Smrg                 *              VisualID3
4503458e6c2Smrg                 *              type
4513458e6c2Smrg                 *              count
4523458e6c2Smrg                 *              length
4533458e6c2Smrg                 *              intensity1
4543458e6c2Smrg                 *              intensity2
4553458e6c2Smrg                 */
4563458e6c2Smrg                if (nitems < 9) {
4573458e6c2Smrg                    goto IntensityTblError;
4583458e6c2Smrg                }
4593458e6c2Smrg                count = 3;
4603458e6c2Smrg                break;
4613458e6c2Smrg            case 16:
4623458e6c2Smrg                /*
4633458e6c2Smrg                 * Must have at least:
4643458e6c2Smrg                 *              VisualID0
4653458e6c2Smrg                 *              VisualID3
4663458e6c2Smrg                 *              type
4673458e6c2Smrg                 *              count
4683458e6c2Smrg                 *              length
4693458e6c2Smrg                 *              intensity1
4703458e6c2Smrg                 *              intensity2
4713458e6c2Smrg                 */
4723458e6c2Smrg                if (nitems < 7) {
4733458e6c2Smrg                    goto IntensityTblError;
4743458e6c2Smrg                }
4753458e6c2Smrg                count = 1;
4763458e6c2Smrg                break;
4773458e6c2Smrg            case 32:
4783458e6c2Smrg                /*
4793458e6c2Smrg                 * Must have at least:
4803458e6c2Smrg                 *              VisualID0
4813458e6c2Smrg                 *              type
4823458e6c2Smrg                 *              count
4833458e6c2Smrg                 *              length
4843458e6c2Smrg                 *              intensity1
4853458e6c2Smrg                 *              intensity2
4863458e6c2Smrg                 */
4873458e6c2Smrg                if (nitems < 6) {
4883458e6c2Smrg                    goto IntensityTblError;
4893458e6c2Smrg                }
4903458e6c2Smrg                count = 0;
4913458e6c2Smrg                break;
4923458e6c2Smrg            default:
4933458e6c2Smrg                goto IntensityTblError;
4943458e6c2Smrg            }
4953458e6c2Smrg
4963458e6c2Smrg            /*
4973458e6c2Smrg             * Get VisualID
4983458e6c2Smrg             */
4993458e6c2Smrg            visualID = _XcmsGetElement(format, &pChar, &nitems);
5003458e6c2Smrg            /* add the depth, class, and bits info in output */
5013458e6c2Smrg            vinfo_template.visualid = visualID;
5023458e6c2Smrg            vinfo_ret = XGetVisualInfo(dpy, VisualIDMask, &vinfo_template,
5033458e6c2Smrg                                       &nvis);
5043458e6c2Smrg            while (count--) {
5053458e6c2Smrg                visualID = visualID << format;
5063458e6c2Smrg                visualID |= _XcmsGetElement(format, &pChar, &nitems);
5073458e6c2Smrg            }
5083458e6c2Smrg
5093458e6c2Smrg            if (vinfo_ret != NULL) {
5103458e6c2Smrg                printf
5113458e6c2Smrg                    ("\n\tVisualID: 0x%lx class: %s depth: %d bits_per_rgb: %d\n",
5123458e6c2Smrg                     visualID, visual_strings[vinfo_ret->class],
5133458e6c2Smrg                     vinfo_ret->depth, vinfo_ret->bits_per_rgb);
5143458e6c2Smrg            }
5153458e6c2Smrg            else
5163458e6c2Smrg                printf("\n\tVisualID: 0x%lx\n", visualID);
5173458e6c2Smrg            XFree(vinfo_ret);
5183458e6c2Smrg            cType = _XcmsGetElement(format, &pChar, &nitems);
5193458e6c2Smrg            printf("\ttype: %d\n", cType);
5203458e6c2Smrg            nTables = _XcmsGetElement(format, &pChar, &nitems);
5213458e6c2Smrg            printf("\tcount: %d\n", nTables);
5223458e6c2Smrg
5233458e6c2Smrg            switch (cType) {
5243458e6c2Smrg            case 0:
5253458e6c2Smrg                /* Red Table should always exist */
5263458e6c2Smrg                printf("\tRed Conversion Table:\n");
5273458e6c2Smrg                PrintTableType0(format, &pChar, &nitems);
5283458e6c2Smrg                if (nTables > 1) {
5293458e6c2Smrg                    printf("\tGreen Conversion Table:\n");
5303458e6c2Smrg                    PrintTableType0(format, &pChar, &nitems);
5313458e6c2Smrg                    printf("\tBlue Conversion Table:\n");
5323458e6c2Smrg                    PrintTableType0(format, &pChar, &nitems);
5333458e6c2Smrg                }
5343458e6c2Smrg                break;
5353458e6c2Smrg            case 1:
5363458e6c2Smrg                /* Red Table should always exist */
5373458e6c2Smrg                printf("\tRed Conversion Table:\n");
5383458e6c2Smrg                PrintTableType1(format, &pChar, &nitems);
5393458e6c2Smrg                if (nTables > 1) {
5403458e6c2Smrg                    printf("\tGreen Conversion Table:\n");
5413458e6c2Smrg                    PrintTableType1(format, &pChar, &nitems);
5423458e6c2Smrg                    printf("\tBlue Conversion Table:\n");
5433458e6c2Smrg                    PrintTableType1(format, &pChar, &nitems);
5443458e6c2Smrg                }
5453458e6c2Smrg                break;
5463458e6c2Smrg            default:
5473458e6c2Smrg                goto IntensityTblError;
5483458e6c2Smrg            }
5493458e6c2Smrg        }
5503458e6c2Smrg        XFree(property_return);
5512becc446Smrg    }
5522c7c4e3dSmrg    return;
5532c7c4e3dSmrg
5543458e6c2Smrg IntensityTblError:
5553458e6c2Smrg    XFree(property_return);
5562c7c4e3dSmrg    printf("Fatal error in %s property\n", XDCCC_CORRECT_ATOM_NAME);
5572c7c4e3dSmrg}
5582c7c4e3dSmrg
5592c7c4e3dSmrg#ifdef GRAY
5602c7c4e3dSmrg
5612c7c4e3dSmrg/*
5622c7c4e3dSmrg *      NAME
5632c7c4e3dSmrg *		QuerySCCDataGray - Query for the SCC data on the root window
5642c7c4e3dSmrg *
5652c7c4e3dSmrg *      SYNOPSIS
5662c7c4e3dSmrg */
5672c7c4e3dSmrgint
5683458e6c2SmrgQuerySCCDataGray(Display * dpy, Window root)
5692c7c4e3dSmrg/*
5702c7c4e3dSmrg *      DESCRIPTION
5712c7c4e3dSmrg *
5722c7c4e3dSmrg *      RETURNS
5732c7c4e3dSmrg *		None
5742c7c4e3dSmrg */
5752c7c4e3dSmrg{
5762c7c4e3dSmrg    char *property_return, *pChar;
5773458e6c2Smrg    int count, format, cType;
5783458e6c2Smrg    unsigned long nitems, nbytes_return;
5792c7c4e3dSmrg    Atom MatricesAtom, CorrectAtom;
5802c7c4e3dSmrg    VisualID visualID;
5812c7c4e3dSmrg
5823458e6c2Smrg    MatricesAtom = ParseAtom(dpy, XDCCC_SCREENWHITEPT_ATOM_NAME, True);
5832c7c4e3dSmrg    if (MatricesAtom != None) {
5843458e6c2Smrg        if (_XcmsGetProperty(dpy, root, MatricesAtom, &format, &nitems,
5853458e6c2Smrg                             &nbytes_return, &property_return) == XcmsFailure) {
5863458e6c2Smrg            format = 0;
5873458e6c2Smrg        }
5883458e6c2Smrg        else if (nitems != 3) {
5893458e6c2Smrg            printf("Property %s had invalid length of %d\n",
5903458e6c2Smrg                   XDCCC_SCREENWHITEPT_ATOM_NAME, nitems);
5913458e6c2Smrg            if (property_return) {
5923458e6c2Smrg                XFree(property_return);
5933458e6c2Smrg            }
5943458e6c2Smrg            return;
5953458e6c2Smrg        }
5962becc446Smrg    }
5972c7c4e3dSmrg    if (MatricesAtom == None || !format) {
5983458e6c2Smrg        printf("Could not find property %s\n", XDCCC_SCREENWHITEPT_ATOM_NAME);
5993458e6c2Smrg    }
6003458e6c2Smrg    else {
6013458e6c2Smrg        pChar = property_return;
6023458e6c2Smrg        printf("\nQuerying property %s\n", XDCCC_SCREENWHITEPT_ATOM_NAME);
6033458e6c2Smrg        printf("\tWhite Point XYZ :\n");
6043458e6c2Smrg        printf("\t");
605c1e8faa6Smrg        for (int j = 0; j < 3; j++) {
6063458e6c2Smrg            printf("\t%8.5lf",
6073458e6c2Smrg                   (long) _XcmsGetElement(format, &pChar, &nitems) /
6083458e6c2Smrg                   (XcmsFloat) XDCCC_NUMBER);
6093458e6c2Smrg        }
6103458e6c2Smrg        printf("\n");
6113458e6c2Smrg        XFree(property_return);
6122c7c4e3dSmrg    }
6132c7c4e3dSmrg
6143458e6c2Smrg    CorrectAtom = XInternAtom(dpy, XDCCC_GRAY_CORRECT_ATOM_NAME, True);
6152c7c4e3dSmrg    if (CorrectAtom != None) {
6163458e6c2Smrg        if (_XcmsGetProperty(dpy, root, CorrectAtom, &format, &nitems,
6173458e6c2Smrg                             &nbytes_return, &property_return) == XcmsFailure) {
6183458e6c2Smrg            format = 0;
6193458e6c2Smrg        }
6203458e6c2Smrg        else if (nitems <= 0) {
6213458e6c2Smrg            printf("Property %s had invalid length of %d\n",
6223458e6c2Smrg                   XDCCC_GRAY_CORRECT_ATOM_NAME, nitems);
6233458e6c2Smrg            if (property_return) {
6243458e6c2Smrg                XFree(property_return);
6253458e6c2Smrg            }
6263458e6c2Smrg            return;
6273458e6c2Smrg        }
6282c7c4e3dSmrg    }
6292c7c4e3dSmrg    if (CorrectAtom == None || !format) {
6303458e6c2Smrg        printf("Could not find property %s\n", XDCCC_GRAY_CORRECT_ATOM_NAME);
6313458e6c2Smrg    }
6323458e6c2Smrg    else {
6333458e6c2Smrg        printf("\nQuerying property %s\n\n", XDCCC_GRAY_CORRECT_ATOM_NAME);
6343458e6c2Smrg        pChar = property_return;
6353458e6c2Smrg
6363458e6c2Smrg        while (nitems) {
6373458e6c2Smrg            switch (format) {
6383458e6c2Smrg            case 8:
6393458e6c2Smrg                /*
6403458e6c2Smrg                 * Must have at least:
6413458e6c2Smrg                 *              VisualID0
6423458e6c2Smrg                 *              VisualID1
6433458e6c2Smrg                 *              VisualID2
6443458e6c2Smrg                 *              VisualID3
6453458e6c2Smrg                 *              type
6463458e6c2Smrg                 *              count
6473458e6c2Smrg                 *              length
6483458e6c2Smrg                 *              intensity1
6493458e6c2Smrg                 *              intensity2
6503458e6c2Smrg                 */
6513458e6c2Smrg                if (nitems < 9) {
6523458e6c2Smrg                    goto IntensityTblError;
6533458e6c2Smrg                }
6543458e6c2Smrg                count = 3;
6553458e6c2Smrg                break;
6563458e6c2Smrg            case 16:
6573458e6c2Smrg                /*
6583458e6c2Smrg                 * Must have at least:
6593458e6c2Smrg                 *              VisualID0
6603458e6c2Smrg                 *              VisualID3
6613458e6c2Smrg                 *              type
6623458e6c2Smrg                 *              count
6633458e6c2Smrg                 *              length
6643458e6c2Smrg                 *              intensity1
6653458e6c2Smrg                 *              intensity2
6663458e6c2Smrg                 */
6673458e6c2Smrg                if (nitems < 7) {
6683458e6c2Smrg                    goto IntensityTblError;
6693458e6c2Smrg                }
6703458e6c2Smrg                count = 1;
6713458e6c2Smrg                break;
6723458e6c2Smrg            case 32:
6733458e6c2Smrg                /*
6743458e6c2Smrg                 * Must have at least:
6753458e6c2Smrg                 *              VisualID0
6763458e6c2Smrg                 *              type
6773458e6c2Smrg                 *              count
6783458e6c2Smrg                 *              length
6793458e6c2Smrg                 *              intensity1
6803458e6c2Smrg                 *              intensity2
6813458e6c2Smrg                 */
6823458e6c2Smrg                if (nitems < 6) {
6833458e6c2Smrg                    goto IntensityTblError;
6843458e6c2Smrg                }
6853458e6c2Smrg                count = 0;
6863458e6c2Smrg                break;
6873458e6c2Smrg            default:
6883458e6c2Smrg                goto IntensityTblError;
6893458e6c2Smrg                break;
6903458e6c2Smrg            }
6913458e6c2Smrg
6923458e6c2Smrg            /*
6933458e6c2Smrg             * Get VisualID
6943458e6c2Smrg             */
6953458e6c2Smrg            visualID = _XcmsGetElement(format, &pChar, &nitems);
6963458e6c2Smrg            while (count--) {
6973458e6c2Smrg                visualID = visualID << format;
6983458e6c2Smrg                visualID |= _XcmsGetElement(format, &pChar, &nitems);
6993458e6c2Smrg            }
7003458e6c2Smrg
7013458e6c2Smrg            printf("\n\tVisualID: 0x%lx\n", visualID);
7023458e6c2Smrg            cType = _XcmsGetElement(format, &pChar, &nitems);
7033458e6c2Smrg            printf("\ttype: %d\n", cType);
7043458e6c2Smrg            printf("\tGray Conversion Table:\n");
7053458e6c2Smrg            switch (cType) {
7063458e6c2Smrg            case 0:
7073458e6c2Smrg                PrintTableType0(format, &pChar, &nitems);
7083458e6c2Smrg                break;
7093458e6c2Smrg            case 1:
7103458e6c2Smrg                PrintTableType1(format, &pChar, &nitems);
7113458e6c2Smrg                break;
7123458e6c2Smrg            default:
7133458e6c2Smrg                goto IntensityTblError;
7143458e6c2Smrg            }
7153458e6c2Smrg        }
7163458e6c2Smrg        XFree(property_return);
7172becc446Smrg    }
7182c7c4e3dSmrg    return;
7193458e6c2Smrg IntensityTblError:
7203458e6c2Smrg    XFree(property_return);
7212c7c4e3dSmrg    printf("Fatal error in %s property\n", XDCCC_CORRECT_ATOM_NAME);
7222c7c4e3dSmrg}
7233458e6c2Smrg#endif                          /* GRAY */
7242c7c4e3dSmrg
7252c7c4e3dSmrg/*
7262c7c4e3dSmrg *      NAME
7272c7c4e3dSmrg *		RemoveSCCData - Remove for the SCC data on the root window
7282c7c4e3dSmrg *
7292c7c4e3dSmrg *      SYNOPSIS
7302c7c4e3dSmrg */
7312c7c4e3dSmrgstatic void
7322c7c4e3dSmrgRemoveSCCData(Display *dpy, Window root, int colorFlag)
7332c7c4e3dSmrg/*
7342c7c4e3dSmrg *      DESCRIPTION
7352c7c4e3dSmrg *
7362c7c4e3dSmrg *      RETURNS
7372c7c4e3dSmrg *		None
7382c7c4e3dSmrg */
7392c7c4e3dSmrg{
7402c7c4e3dSmrg    unsigned char *ret_prop;
7412c7c4e3dSmrg    unsigned long ret_len, ret_after;
7423458e6c2Smrg    int ret_format, status = -1;
7432c7c4e3dSmrg    Atom MatricesAtom, CorrectAtom, ret_atom;
7442c7c4e3dSmrg
7452c7c4e3dSmrg    if (colorFlag != 0) {
7463458e6c2Smrg        MatricesAtom = ParseAtom(dpy, XDCCC_MATRIX_ATOM_NAME, True);
7473458e6c2Smrg        if (MatricesAtom != None) {
7483458e6c2Smrg            status = XGetWindowProperty(dpy, root, MatricesAtom, 0, 8192,
7493458e6c2Smrg                                        False, XA_INTEGER, &ret_atom,
7503458e6c2Smrg                                        &ret_format, &ret_len, &ret_after,
7513458e6c2Smrg                                        &ret_prop);
7523458e6c2Smrg        }
7533458e6c2Smrg        if (MatricesAtom == None || status != Success || !ret_format) {
7543458e6c2Smrg            printf("Could not find property %s\n", XDCCC_MATRIX_ATOM_NAME);
7553458e6c2Smrg        }
7563458e6c2Smrg        else {
7573458e6c2Smrg            printf("Deleting property %s\n", XDCCC_MATRIX_ATOM_NAME);
7583458e6c2Smrg            XDeleteProperty(dpy, root, MatricesAtom);
7593458e6c2Smrg            XFree(ret_prop);
7603458e6c2Smrg        }
7613458e6c2Smrg
7623458e6c2Smrg        CorrectAtom = XInternAtom(dpy, XDCCC_CORRECT_ATOM_NAME, True);
7633458e6c2Smrg        if (CorrectAtom != None) {
7643458e6c2Smrg            status = XGetWindowProperty(dpy, root, CorrectAtom, 0, 8192,
7653458e6c2Smrg                                        False, XA_INTEGER, &ret_atom,
7663458e6c2Smrg                                        &ret_format, &ret_len, &ret_after,
7673458e6c2Smrg                                        &ret_prop);
7683458e6c2Smrg        }
7693458e6c2Smrg        if (CorrectAtom == None || status != Success || !ret_format) {
7703458e6c2Smrg            printf("Could not find property %s\n", XDCCC_CORRECT_ATOM_NAME);
7713458e6c2Smrg        }
7723458e6c2Smrg        else {
7733458e6c2Smrg            printf("Deleting property %s\n", XDCCC_CORRECT_ATOM_NAME);
7743458e6c2Smrg            XDeleteProperty(dpy, root, CorrectAtom);
7753458e6c2Smrg            XFree(ret_prop);
7763458e6c2Smrg        }
7772c7c4e3dSmrg    }
7782c7c4e3dSmrg#ifdef GRAY
7792c7c4e3dSmrg    if (colorFlag != 1) {
7803458e6c2Smrg        MatricesAtom = ParseAtom(dpy, XDCCC_SCREENWHITEPT_ATOM_NAME, True);
7813458e6c2Smrg        if (MatricesAtom != None) {
7823458e6c2Smrg            status = XGetWindowProperty(dpy, root, MatricesAtom, 0, 8192,
7833458e6c2Smrg                                        False, XA_INTEGER, &ret_atom,
7843458e6c2Smrg                                        &ret_format, &ret_len, &ret_after,
7853458e6c2Smrg                                        &ret_prop);
7863458e6c2Smrg        }
7873458e6c2Smrg        if (MatricesAtom == None || status != Success || !ret_format) {
7883458e6c2Smrg            printf("Could not find property %s\n",
7893458e6c2Smrg                   XDCCC_SCREENWHITEPT_ATOM_NAME);
7903458e6c2Smrg        }
7913458e6c2Smrg        else {
7923458e6c2Smrg            printf("Deleting property %s\n", XDCCC_SCREENWHITEPT_ATOM_NAME);
7933458e6c2Smrg            XDeleteProperty(dpy, root, MatricesAtom);
7943458e6c2Smrg            XFree(ret_prop);
7953458e6c2Smrg        }
7963458e6c2Smrg
7973458e6c2Smrg        CorrectAtom = XInternAtom(dpy, XDCCC_GRAY_CORRECT_ATOM_NAME, True);
7983458e6c2Smrg        if (CorrectAtom != None) {
7993458e6c2Smrg            status = XGetWindowProperty(dpy, root, CorrectAtom, 0, 8192,
8003458e6c2Smrg                                        False, XA_INTEGER, &ret_atom,
8013458e6c2Smrg                                        &ret_format, &ret_len, &ret_after,
8023458e6c2Smrg                                        &ret_prop);
8033458e6c2Smrg        }
8043458e6c2Smrg        if (CorrectAtom == None || status != Success || !ret_format) {
8053458e6c2Smrg            printf("Could not find property %s\n",
8063458e6c2Smrg                   XDCCC_GRAY_CORRECT_ATOM_NAME);
8073458e6c2Smrg        }
8083458e6c2Smrg        else {
8093458e6c2Smrg            printf("Deleting property %s\n", XDCCC_GRAY_CORRECT_ATOM_NAME);
8103458e6c2Smrg            XDeleteProperty(dpy, root, CorrectAtom);
8113458e6c2Smrg            XFree(ret_prop);
8123458e6c2Smrg        }
8132c7c4e3dSmrg    }
8143458e6c2Smrg#endif                          /* GRAY */
8152c7c4e3dSmrg}
8162c7c4e3dSmrg
8172c7c4e3dSmrgstatic unsigned long
8182becc446Smrg_XcmsGetElement(int format, char **pValue, unsigned long *pCount)
8192c7c4e3dSmrg/*
8202c7c4e3dSmrg *	DESCRIPTION
8212c7c4e3dSmrg *	    Get the next element from the property and return it.
8222c7c4e3dSmrg *	    Also increment the pointer the amount needed.
8232c7c4e3dSmrg *
8242c7c4e3dSmrg *	Returns
8252c7c4e3dSmrg *	    unsigned long
8262c7c4e3dSmrg */
8272c7c4e3dSmrg{
8282c7c4e3dSmrg    unsigned long value;
8292c7c4e3dSmrg
8302c7c4e3dSmrg    switch (format) {
8313458e6c2Smrg    case 32:
8323458e6c2Smrg        value = *((unsigned long *) (*pValue)) & 0xFFFFFFFF;
8333458e6c2Smrg        *pValue += sizeof(unsigned long);
8343458e6c2Smrg        *pCount -= 1;
8353458e6c2Smrg        break;
8363458e6c2Smrg    case 16:
8373458e6c2Smrg        value = *((unsigned short *) (*pValue));
8383458e6c2Smrg        *pValue += sizeof(unsigned short);
8393458e6c2Smrg        *pCount -= 1;
8403458e6c2Smrg        break;
8413458e6c2Smrg    case 8:
8423458e6c2Smrg        value = *((unsigned char *) (*pValue));
8433458e6c2Smrg        *pValue += 1;
8443458e6c2Smrg        *pCount -= 1;
8453458e6c2Smrg        break;
8463458e6c2Smrg    default:
8473458e6c2Smrg        value = 0;
8483458e6c2Smrg        break;
8492c7c4e3dSmrg    }
8503458e6c2Smrg    return (value);
8512c7c4e3dSmrg}
8522c7c4e3dSmrg
8532c7c4e3dSmrg/*
8542c7c4e3dSmrg *	NAME
8553458e6c2Smrg *		_XcmsGetProperty -- Determine the existence of a property
8562c7c4e3dSmrg *
8572c7c4e3dSmrg *	SYNOPSIS
8582c7c4e3dSmrg */
8592c7c4e3dSmrgstatic int
8602becc446Smrg_XcmsGetProperty(Display *pDpy, Window w, Atom property, int *pFormat,
8613458e6c2Smrg                 unsigned long *pNItems, unsigned long *pNBytes, char **pValue)
8622c7c4e3dSmrg/*
8632c7c4e3dSmrg *	DESCRIPTION
8642c7c4e3dSmrg *
8652c7c4e3dSmrg *	Returns
8662c7c4e3dSmrg *	    0 if property does not exist.
8672c7c4e3dSmrg *	    1 if property exists.
8682c7c4e3dSmrg */
8692c7c4e3dSmrg{
8702c7c4e3dSmrg    char *prop_ret;
8712c7c4e3dSmrg    int format_ret;
8722c7c4e3dSmrg    long len = 6516;
8732c7c4e3dSmrg    unsigned long nitems_ret, after_ret;
8742c7c4e3dSmrg    Atom atom_ret;
8752becc446Smrg    int xgwp_ret;
8762becc446Smrg
8772becc446Smrg    while (True) {
8783458e6c2Smrg        xgwp_ret = XGetWindowProperty(pDpy, w, property, 0, len, False,
8793458e6c2Smrg                                      XA_INTEGER, &atom_ret, &format_ret,
8803458e6c2Smrg                                      &nitems_ret, &after_ret,
8813458e6c2Smrg                                      (unsigned char **) &prop_ret);
8823458e6c2Smrg        if (xgwp_ret == Success && after_ret > 0) {
8833458e6c2Smrg            len += nitems_ret * (format_ret >> 3);
8843458e6c2Smrg            XFree(prop_ret);
8853458e6c2Smrg        }
8863458e6c2Smrg        else {
8873458e6c2Smrg            break;
8883458e6c2Smrg        }
8892c7c4e3dSmrg    }
8902becc446Smrg    if (xgwp_ret != Success || format_ret == 0 || nitems_ret == 0) {
8913458e6c2Smrg        /* the property does not exist or is of an unexpected type or
8922becc446Smrg           getting window property failed */
8933458e6c2Smrg        return (XcmsFailure);
8942c7c4e3dSmrg    }
8952c7c4e3dSmrg
8962c7c4e3dSmrg    *pFormat = format_ret;
8972c7c4e3dSmrg    *pNItems = nitems_ret;
8982c7c4e3dSmrg    *pNBytes = nitems_ret * (format_ret >> 3);
8992c7c4e3dSmrg    *pValue = prop_ret;
9003458e6c2Smrg    return (XcmsSuccess);
9012c7c4e3dSmrg}
902