Edit

IABSD.fr/xenocara/app/xcmsdb/xcmsdb.c

Branch :

  • Show log

    Commit

  • Author : matthieu
    Date : 2024-11-11 09:22:15
    Hash : 3be9baab
    Message : update to xcmsdb 1.0.7

  • app/xcmsdb/xcmsdb.c
  • /* $Xorg: xcmsdb.c,v 1.3 2000/08/17 19:54:13 cpqbld Exp $ */
    
    /*
     * (c) Copyright 1990 Tektronix Inc.
     * 	All Rights Reserved
     *
     * Permission to use, copy, modify, and distribute this software and its
     * documentation for any purpose and without fee is hereby granted,
     * provided that the above copyright notice appear in all copies and that
     * both that copyright notice and this permission notice appear in
     * supporting documentation, and that the name of Tektronix not be used
     * in advertising or publicity pertaining to distribution of the software
     * without specific, written prior permission.
     *
     * Tektronix disclaims all warranties with regard to this software, including
     * all implied warranties of merchantability and fitness, in no event shall
     * Tektronix be liable for any special, indirect or consequential damages or
     * any damages whatsoever resulting from loss of use, data or profits,
     * whether in an action of contract, negligence or other tortious action,
     * arising out of or in connection with the use or performance of this
     * software.
     *
     *
     *	NAME
     *		xcmsdb.c
     *
     *	DESCRIPTION
     *		Program to load, query or remove the Screen Color
     *		Characterization Data from the root window of the screen.
     *
     */
    /* $XFree86: xc/programs/xcmsdb/xcmsdb.c,v 1.5 2001/01/17 23:45:19 dawes Exp $ */
    
    /*
     *      INCLUDES
     */
    
    #ifdef HAVE_CONFIG_H
    #include "config.h"
    #endif
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <X11/Xlib.h>
    #include <X11/Xatom.h>
    #include <X11/Xos.h>
    #include <ctype.h>
    
    #include "SCCDFile.h"
    
    static void QuerySCCDataRGB(Display *dpy, Window root);
    static void RemoveSCCData(Display *dpy, Window root, int colorFlag);
    static unsigned long _XcmsGetElement(int format, char **pValue,
                                         unsigned long *pCount);
    static int _XcmsGetProperty(Display *pDpy, Window w, Atom property,
                                int *pFormat, unsigned long *pNItems,
                                unsigned long *pNBytes, char **pValue);
    
    static char *ProgramName;
    
    static void
    Syntax(int exitcode)
    {
        fprintf(stderr,
                "usage:  %s [-options ...] [filename]\n\n%s",
                ProgramName,
                "where options include:\n"
                "    -display host:dpy[.scrn]     display to use\n"
                "    -format [ 32 | 16 | 8 ]      property format\n"
                "    -query                       query Screen Color Characterization Data\n"
                "    -remove                      remove Screen Color Characterization Data\n"
    #ifdef GRAY
                "    -color                       use color as default\n"
                "    -gray                        use gray-scale as default\n"
    #endif                          /* GRAY */
                "    -version                     print program version\n" "\n");
        exit(exitcode);
    }
    
    static void
    MissingArg(const char *option)
    {
        fprintf(stderr, "%s: %s requires an argument\n", ProgramName, option);
        Syntax(1);
    }
    
    static Bool
    optionmatch(const char *opt, const char *arg, int minlen)
    {
        int arglen;
    
        if (strcmp(opt, arg) == 0) {
            return (True);
        }
    
        if ((arglen = strlen(arg)) >= (int) strlen(opt) || arglen < minlen) {
            return (False);
        }
    
        if (strncmp(opt, arg, arglen) == 0) {
            return (True);
        }
    
        return (False);
    }
    
    int
    main(int argc, char *argv[])
    {
        Display *dpy;
        char *displayname = NULL;
        char *filename = NULL;
        int query = 0;
        int remove = 0;
        int load = 0;
        int color = -1;
        int targetFormat = 32;
    
        ProgramName = argv[0];
    
        for (int i = 1; i < argc; i++) {
            char *arg = argv[i];
    
            if (arg[0] == '-') {
                if (arg[1] == '\0') {
                    filename = NULL;
                    continue;
                }
                else if (optionmatch("-help", arg, 1)) {
                    Syntax(0);
                    /* doesn't return */
                }
                else if (optionmatch("-display", arg, 1)) {
                    if (++i >= argc)
                        MissingArg("-display");
                    displayname = argv[i];
                    continue;
                }
                else if (optionmatch("-format", arg, 1)) {
                    if (++i >= argc)
                        MissingArg("-format");
                    targetFormat = atoi(argv[i]);
                    if (targetFormat != 32 && targetFormat != 16 &&
                        targetFormat != 8) {
                        fprintf(stderr, "%s: invalid value for -format: %d\n",
                                ProgramName, targetFormat);
                        Syntax(1);
                    }
                    continue;
                }
                else if (optionmatch("-query", arg, 1)) {
                    query = 1;
                    continue;
                }
                else if (optionmatch("-remove", arg, 1)) {
                    remove = 1;
                    continue;
    #ifdef GRAY
                }
                else if (optionmatch("-color", arg, 1)) {
                    color = 1;
                    continue;
                }
                else if (optionmatch("-gray", arg, 1)) {
                    color = 0;
                    continue;
    #endif                          /* GRAY */
                }
                else if (optionmatch("-version", arg, 1)) {
                    puts(PACKAGE_STRING);
                    exit(0);
                }
                fprintf(stderr, "%s: unrecognized option '%s'\n", ProgramName, arg);
                Syntax(1);
            }
            else {
                load = 1;
                filename = arg;
            }
        }
    
        /* Open display  */
        if (!(dpy = XOpenDisplay(displayname))) {
            fprintf(stderr, "%s:  Can't open display '%s'\n",
                    ProgramName, XDisplayName(displayname));
            exit(1);
        }
    
        if (query || remove) {
            load = 0;
        }
    
        if (load) {
            LoadSCCData(dpy, DefaultScreen(dpy), filename, targetFormat);
        }
    
        if (query) {
            if (color != 0)
                QuerySCCDataRGB(dpy, RootWindow(dpy, DefaultScreen(dpy)));
    #ifdef GRAY
            if (color != 1)
                QuerySCCDataGray(dpy, RootWindow(dpy, DefaultScreen(dpy)));
    #endif /* GRAY */
        }
    
        if (remove) {
            RemoveSCCData(dpy, RootWindow(dpy, DefaultScreen(dpy)), color);
        }
    
        XCloseDisplay(dpy);
        exit(0);
        /*NOTREACHED*/
    }
    
    static Atom
    ParseAtom(Display *dpy, const char *name, int only_flag)
    {
        return (XInternAtom(dpy, name, only_flag));
    }
    
    /*
     *	NAME
     *		PrintTableType0
     *
     *	SYNOPSIS
     */
    static void
    PrintTableType0(int format, char **pChar, unsigned long *pCount)
    /*
     *	DESCRIPTION
     *
     *	RETURNS
     *		XcmsFailure if failed.
     *		XcmsSuccess if succeeded.
     *
     */
    {
        unsigned int nElements;
        unsigned short hValue;
        XcmsFloat fValue;
    
        nElements = _XcmsGetElement(format, pChar, pCount) + 1;
        printf("\t    length:%d\n", nElements);
    
        switch (format) {
        case 8:
            while (nElements--) {
                /* 0xFFFF/0xFF = 0x101 */
                hValue = _XcmsGetElement(format, pChar, pCount) * 0x101;
                fValue = _XcmsGetElement(format, pChar, pCount)
                    / (XcmsFloat) 255.0;
                printf("\t\t0x%x\t%8.5f\n", hValue, fValue);
            }
            break;
        case 16:
            while (nElements--) {
                hValue = _XcmsGetElement(format, pChar, pCount);
                fValue = _XcmsGetElement(format, pChar, pCount)
                    / (XcmsFloat) 65535.0;
                printf("\t\t0x%x\t%8.5f\n", hValue, fValue);
            }
            break;
        case 32:
            while (nElements--) {
                hValue = _XcmsGetElement(format, pChar, pCount);
                fValue = _XcmsGetElement(format, pChar, pCount)
                    / (XcmsFloat) 4294967295.0;
                printf("\t\t0x%x\t%8.5f\n", hValue, fValue);
            }
            break;
        default:
            return;
        }
    }
    
    /*
     *	NAME
     *		PrintTableType1
     *
     *	SYNOPSIS
     */
    static void
    PrintTableType1(int format, char **pChar, unsigned long *pCount)
    /*
     *	DESCRIPTION
     *
     *	RETURNS
     *		XcmsFailure if failed.
     *		XcmsSuccess if succeeded.
     *
     */
    {
        unsigned int count;
        unsigned int max_index;
        unsigned short hValue;
        XcmsFloat fValue;
    
        max_index = _XcmsGetElement(format, pChar, pCount);
        printf("\t    length:%d\n", max_index + 1);
    
        switch (format) {
        case 8:
            for (count = 0; count < max_index + 1; count++) {
                hValue = (count * 65535) / max_index;
                fValue = _XcmsGetElement(format, pChar, pCount)
                    / (XcmsFloat) 255.0;
                printf("\t\t0x%x\t%8.5f\n", hValue, fValue);
            }
            break;
        case 16:
            for (count = 0; count < max_index + 1; count++) {
                hValue = (count * 65535) / max_index;
                fValue = _XcmsGetElement(format, pChar, pCount)
                    / (XcmsFloat) 65535.0;
                printf("\t\t0x%x\t%8.5f\n", hValue, fValue);
            }
            break;
        case 32:
            for (count = 0; count < max_index + 1; count++) {
                hValue = (count * 65535) / max_index;
                fValue = _XcmsGetElement(format, pChar, pCount)
                    / (XcmsFloat) 4294967295.0;
                printf("\t\t0x%x\t%8.5f\n", hValue, fValue);
            }
            break;
        default:
            return;
        }
    }
    
    /*
     *      NAME
     *		QuerySCCData - Query for the SCC data on the root window
     *
     *      SYNOPSIS
     */
    static void
    QuerySCCDataRGB(Display * dpy, Window root)
    /*
     *      DESCRIPTION
     *
     *      RETURNS
     *		None
     */
    {
        char *property_return, *pChar;
        int i, j;
        int count, format, cType, nTables;
        unsigned long nitems, nbytes_return;
        Atom MatricesAtom, CorrectAtom;
        VisualID visualID;
        XVisualInfo vinfo_template, *vinfo_ret;
        int nvis;
    
        static const char *visual_strings[] = {
            "StaticGray",
            "GrayScale",
            "StaticColor",
            "PseudoColor",
            "TrueColor",
            "DirectColor"
        };
    
        /*
         * Get Matrices
         */
        MatricesAtom = ParseAtom(dpy, XDCCC_MATRIX_ATOM_NAME, True);
        if (MatricesAtom != None) {
            if (_XcmsGetProperty(dpy, root, MatricesAtom, &format, &nitems,
                                 &nbytes_return, &property_return) == XcmsFailure) {
                format = 0;
            }
            else if (nitems != 18) {
                printf("Property %s had invalid length of %ld\n",
                       XDCCC_MATRIX_ATOM_NAME, nitems);
                if (property_return) {
                    XFree(property_return);
                }
                return;
            }
        }
        if (MatricesAtom == None || !format) {
            printf("Could not find property %s\n", XDCCC_MATRIX_ATOM_NAME);
        }
        else if (format != 32) {
            printf("Data in property %s not in 32 bit format\n",
                   XDCCC_MATRIX_ATOM_NAME);
        }
        else {
            pChar = property_return;
            printf("Screen: %d\n", DefaultScreen(dpy));
            printf("Querying property %s\n", XDCCC_MATRIX_ATOM_NAME);
            printf("\tXYZtoRGB matrix :\n");
            for (i = 0; i < 3; i++) {
                printf("\t");
                for (j = 0; j < 3; j++) {
                    printf("\t%8.5f",
                           (long) _XcmsGetElement(format, &pChar, &nitems)
                           / (XcmsFloat) XDCCC_NUMBER);
                }
                printf("\n");
            }
            printf("\tRGBtoXYZ matrix :\n");
            for (i = 0; i < 3; i++) {
                printf("\t");
                for (j = 0; j < 3; j++) {
                    printf("\t%8.5f",
                           (long) _XcmsGetElement(format, &pChar, &nitems)
                           / (XcmsFloat) XDCCC_NUMBER);
                }
                printf("\n");
            }
            XFree(property_return);
        }
    
        /*
         * Get Intensity Tables
         */
        CorrectAtom = XInternAtom(dpy, XDCCC_CORRECT_ATOM_NAME, True);
        if (CorrectAtom != None) {
            if (_XcmsGetProperty(dpy, root, CorrectAtom, &format, &nitems,
                                 &nbytes_return, &property_return) == XcmsFailure) {
                format = 0;
            }
            else if (nitems <= 0) {
                printf("Property %s had invalid length of %ld\n",
                       XDCCC_CORRECT_ATOM_NAME, nitems);
                if (property_return) {
                    XFree(property_return);
                }
                return;
            }
        }
        if (CorrectAtom == None || !format) {
            printf("Could not find property %s\n", XDCCC_CORRECT_ATOM_NAME);
        }
        else {
            printf("\nQuerying property %s\n", XDCCC_CORRECT_ATOM_NAME);
            pChar = property_return;
    
            while (nitems) {
                switch (format) {
                case 8:
                    /*
                     * Must have at least:
                     *              VisualID0
                     *              VisualID1
                     *              VisualID2
                     *              VisualID3
                     *              type
                     *              count
                     *              length
                     *              intensity1
                     *              intensity2
                     */
                    if (nitems < 9) {
                        goto IntensityTblError;
                    }
                    count = 3;
                    break;
                case 16:
                    /*
                     * Must have at least:
                     *              VisualID0
                     *              VisualID3
                     *              type
                     *              count
                     *              length
                     *              intensity1
                     *              intensity2
                     */
                    if (nitems < 7) {
                        goto IntensityTblError;
                    }
                    count = 1;
                    break;
                case 32:
                    /*
                     * Must have at least:
                     *              VisualID0
                     *              type
                     *              count
                     *              length
                     *              intensity1
                     *              intensity2
                     */
                    if (nitems < 6) {
                        goto IntensityTblError;
                    }
                    count = 0;
                    break;
                default:
                    goto IntensityTblError;
                }
    
                /*
                 * Get VisualID
                 */
                visualID = _XcmsGetElement(format, &pChar, &nitems);
                /* add the depth, class, and bits info in output */
                vinfo_template.visualid = visualID;
                vinfo_ret = XGetVisualInfo(dpy, VisualIDMask, &vinfo_template,
                                           &nvis);
                while (count--) {
                    visualID = visualID << format;
                    visualID |= _XcmsGetElement(format, &pChar, &nitems);
                }
    
                if (vinfo_ret != NULL) {
                    printf
                        ("\n\tVisualID: 0x%lx class: %s depth: %d bits_per_rgb: %d\n",
                         visualID, visual_strings[vinfo_ret->class],
                         vinfo_ret->depth, vinfo_ret->bits_per_rgb);
                }
                else
                    printf("\n\tVisualID: 0x%lx\n", visualID);
                XFree(vinfo_ret);
                cType = _XcmsGetElement(format, &pChar, &nitems);
                printf("\ttype: %d\n", cType);
                nTables = _XcmsGetElement(format, &pChar, &nitems);
                printf("\tcount: %d\n", nTables);
    
                switch (cType) {
                case 0:
                    /* Red Table should always exist */
                    printf("\tRed Conversion Table:\n");
                    PrintTableType0(format, &pChar, &nitems);
                    if (nTables > 1) {
                        printf("\tGreen Conversion Table:\n");
                        PrintTableType0(format, &pChar, &nitems);
                        printf("\tBlue Conversion Table:\n");
                        PrintTableType0(format, &pChar, &nitems);
                    }
                    break;
                case 1:
                    /* Red Table should always exist */
                    printf("\tRed Conversion Table:\n");
                    PrintTableType1(format, &pChar, &nitems);
                    if (nTables > 1) {
                        printf("\tGreen Conversion Table:\n");
                        PrintTableType1(format, &pChar, &nitems);
                        printf("\tBlue Conversion Table:\n");
                        PrintTableType1(format, &pChar, &nitems);
                    }
                    break;
                default:
                    goto IntensityTblError;
                }
            }
            XFree(property_return);
        }
        return;
    
     IntensityTblError:
        XFree(property_return);
        printf("Fatal error in %s property\n", XDCCC_CORRECT_ATOM_NAME);
    }
    
    #ifdef GRAY
    
    /*
     *      NAME
     *		QuerySCCDataGray - Query for the SCC data on the root window
     *
     *      SYNOPSIS
     */
    int
    QuerySCCDataGray(Display * dpy, Window root)
    /*
     *      DESCRIPTION
     *
     *      RETURNS
     *		None
     */
    {
        char *property_return, *pChar;
        int count, format, cType;
        unsigned long nitems, nbytes_return;
        Atom MatricesAtom, CorrectAtom;
        VisualID visualID;
    
        MatricesAtom = ParseAtom(dpy, XDCCC_SCREENWHITEPT_ATOM_NAME, True);
        if (MatricesAtom != None) {
            if (_XcmsGetProperty(dpy, root, MatricesAtom, &format, &nitems,
                                 &nbytes_return, &property_return) == XcmsFailure) {
                format = 0;
            }
            else if (nitems != 3) {
                printf("Property %s had invalid length of %d\n",
                       XDCCC_SCREENWHITEPT_ATOM_NAME, nitems);
                if (property_return) {
                    XFree(property_return);
                }
                return;
            }
        }
        if (MatricesAtom == None || !format) {
            printf("Could not find property %s\n", XDCCC_SCREENWHITEPT_ATOM_NAME);
        }
        else {
            pChar = property_return;
            printf("\nQuerying property %s\n", XDCCC_SCREENWHITEPT_ATOM_NAME);
            printf("\tWhite Point XYZ :\n");
            printf("\t");
            for (int j = 0; j < 3; j++) {
                printf("\t%8.5lf",
                       (long) _XcmsGetElement(format, &pChar, &nitems) /
                       (XcmsFloat) XDCCC_NUMBER);
            }
            printf("\n");
            XFree(property_return);
        }
    
        CorrectAtom = XInternAtom(dpy, XDCCC_GRAY_CORRECT_ATOM_NAME, True);
        if (CorrectAtom != None) {
            if (_XcmsGetProperty(dpy, root, CorrectAtom, &format, &nitems,
                                 &nbytes_return, &property_return) == XcmsFailure) {
                format = 0;
            }
            else if (nitems <= 0) {
                printf("Property %s had invalid length of %d\n",
                       XDCCC_GRAY_CORRECT_ATOM_NAME, nitems);
                if (property_return) {
                    XFree(property_return);
                }
                return;
            }
        }
        if (CorrectAtom == None || !format) {
            printf("Could not find property %s\n", XDCCC_GRAY_CORRECT_ATOM_NAME);
        }
        else {
            printf("\nQuerying property %s\n\n", XDCCC_GRAY_CORRECT_ATOM_NAME);
            pChar = property_return;
    
            while (nitems) {
                switch (format) {
                case 8:
                    /*
                     * Must have at least:
                     *              VisualID0
                     *              VisualID1
                     *              VisualID2
                     *              VisualID3
                     *              type
                     *              count
                     *              length
                     *              intensity1
                     *              intensity2
                     */
                    if (nitems < 9) {
                        goto IntensityTblError;
                    }
                    count = 3;
                    break;
                case 16:
                    /*
                     * Must have at least:
                     *              VisualID0
                     *              VisualID3
                     *              type
                     *              count
                     *              length
                     *              intensity1
                     *              intensity2
                     */
                    if (nitems < 7) {
                        goto IntensityTblError;
                    }
                    count = 1;
                    break;
                case 32:
                    /*
                     * Must have at least:
                     *              VisualID0
                     *              type
                     *              count
                     *              length
                     *              intensity1
                     *              intensity2
                     */
                    if (nitems < 6) {
                        goto IntensityTblError;
                    }
                    count = 0;
                    break;
                default:
                    goto IntensityTblError;
                    break;
                }
    
                /*
                 * Get VisualID
                 */
                visualID = _XcmsGetElement(format, &pChar, &nitems);
                while (count--) {
                    visualID = visualID << format;
                    visualID |= _XcmsGetElement(format, &pChar, &nitems);
                }
    
                printf("\n\tVisualID: 0x%lx\n", visualID);
                cType = _XcmsGetElement(format, &pChar, &nitems);
                printf("\ttype: %d\n", cType);
                printf("\tGray Conversion Table:\n");
                switch (cType) {
                case 0:
                    PrintTableType0(format, &pChar, &nitems);
                    break;
                case 1:
                    PrintTableType1(format, &pChar, &nitems);
                    break;
                default:
                    goto IntensityTblError;
                }
            }
            XFree(property_return);
        }
        return;
     IntensityTblError:
        XFree(property_return);
        printf("Fatal error in %s property\n", XDCCC_CORRECT_ATOM_NAME);
    }
    #endif                          /* GRAY */
    
    /*
     *      NAME
     *		RemoveSCCData - Remove for the SCC data on the root window
     *
     *      SYNOPSIS
     */
    static void
    RemoveSCCData(Display *dpy, Window root, int colorFlag)
    /*
     *      DESCRIPTION
     *
     *      RETURNS
     *		None
     */
    {
        unsigned char *ret_prop;
        unsigned long ret_len, ret_after;
        int ret_format, status = -1;
        Atom MatricesAtom, CorrectAtom, ret_atom;
    
        if (colorFlag != 0) {
            MatricesAtom = ParseAtom(dpy, XDCCC_MATRIX_ATOM_NAME, True);
            if (MatricesAtom != None) {
                status = XGetWindowProperty(dpy, root, MatricesAtom, 0, 8192,
                                            False, XA_INTEGER, &ret_atom,
                                            &ret_format, &ret_len, &ret_after,
                                            &ret_prop);
            }
            if (MatricesAtom == None || status != Success || !ret_format) {
                printf("Could not find property %s\n", XDCCC_MATRIX_ATOM_NAME);
            }
            else {
                printf("Deleting property %s\n", XDCCC_MATRIX_ATOM_NAME);
                XDeleteProperty(dpy, root, MatricesAtom);
                XFree(ret_prop);
            }
    
            CorrectAtom = XInternAtom(dpy, XDCCC_CORRECT_ATOM_NAME, True);
            if (CorrectAtom != None) {
                status = XGetWindowProperty(dpy, root, CorrectAtom, 0, 8192,
                                            False, XA_INTEGER, &ret_atom,
                                            &ret_format, &ret_len, &ret_after,
                                            &ret_prop);
            }
            if (CorrectAtom == None || status != Success || !ret_format) {
                printf("Could not find property %s\n", XDCCC_CORRECT_ATOM_NAME);
            }
            else {
                printf("Deleting property %s\n", XDCCC_CORRECT_ATOM_NAME);
                XDeleteProperty(dpy, root, CorrectAtom);
                XFree(ret_prop);
            }
        }
    #ifdef GRAY
        if (colorFlag != 1) {
            MatricesAtom = ParseAtom(dpy, XDCCC_SCREENWHITEPT_ATOM_NAME, True);
            if (MatricesAtom != None) {
                status = XGetWindowProperty(dpy, root, MatricesAtom, 0, 8192,
                                            False, XA_INTEGER, &ret_atom,
                                            &ret_format, &ret_len, &ret_after,
                                            &ret_prop);
            }
            if (MatricesAtom == None || status != Success || !ret_format) {
                printf("Could not find property %s\n",
                       XDCCC_SCREENWHITEPT_ATOM_NAME);
            }
            else {
                printf("Deleting property %s\n", XDCCC_SCREENWHITEPT_ATOM_NAME);
                XDeleteProperty(dpy, root, MatricesAtom);
                XFree(ret_prop);
            }
    
            CorrectAtom = XInternAtom(dpy, XDCCC_GRAY_CORRECT_ATOM_NAME, True);
            if (CorrectAtom != None) {
                status = XGetWindowProperty(dpy, root, CorrectAtom, 0, 8192,
                                            False, XA_INTEGER, &ret_atom,
                                            &ret_format, &ret_len, &ret_after,
                                            &ret_prop);
            }
            if (CorrectAtom == None || status != Success || !ret_format) {
                printf("Could not find property %s\n",
                       XDCCC_GRAY_CORRECT_ATOM_NAME);
            }
            else {
                printf("Deleting property %s\n", XDCCC_GRAY_CORRECT_ATOM_NAME);
                XDeleteProperty(dpy, root, CorrectAtom);
                XFree(ret_prop);
            }
        }
    #endif                          /* GRAY */
    }
    
    static unsigned long
    _XcmsGetElement(int format, char **pValue, unsigned long *pCount)
    /*
     *	DESCRIPTION
     *	    Get the next element from the property and return it.
     *	    Also increment the pointer the amount needed.
     *
     *	Returns
     *	    unsigned long
     */
    {
        unsigned long value;
    
        switch (format) {
        case 32:
            value = *((unsigned long *) (*pValue)) & 0xFFFFFFFF;
            *pValue += sizeof(unsigned long);
            *pCount -= 1;
            break;
        case 16:
            value = *((unsigned short *) (*pValue));
            *pValue += sizeof(unsigned short);
            *pCount -= 1;
            break;
        case 8:
            value = *((unsigned char *) (*pValue));
            *pValue += 1;
            *pCount -= 1;
            break;
        default:
            value = 0;
            break;
        }
        return (value);
    }
    
    /*
     *	NAME
     *		_XcmsGetProperty -- Determine the existence of a property
     *
     *	SYNOPSIS
     */
    static int
    _XcmsGetProperty(Display *pDpy, Window w, Atom property, int *pFormat,
                     unsigned long *pNItems, unsigned long *pNBytes, char **pValue)
    /*
     *	DESCRIPTION
     *
     *	Returns
     *	    0 if property does not exist.
     *	    1 if property exists.
     */
    {
        char *prop_ret;
        int format_ret;
        long len = 6516;
        unsigned long nitems_ret, after_ret;
        Atom atom_ret;
        int xgwp_ret;
    
        while (True) {
            xgwp_ret = XGetWindowProperty(pDpy, w, property, 0, len, False,
                                          XA_INTEGER, &atom_ret, &format_ret,
                                          &nitems_ret, &after_ret,
                                          (unsigned char **) &prop_ret);
            if (xgwp_ret == Success && after_ret > 0) {
                len += nitems_ret * (format_ret >> 3);
                XFree(prop_ret);
            }
            else {
                break;
            }
        }
        if (xgwp_ret != Success || format_ret == 0 || nitems_ret == 0) {
            /* the property does not exist or is of an unexpected type or
               getting window property failed */
            return (XcmsFailure);
        }
    
        *pFormat = format_ret;
        *pNItems = nitems_ret;
        *pNBytes = nitems_ret * (format_ret >> 3);
        *pValue = prop_ret;
        return (XcmsSuccess);
    }