diff options
author | Kaleb Keithley <kaleb@freedesktop.org> | 2003-11-14 15:54:53 +0000 |
---|---|---|
committer | Kaleb Keithley <kaleb@freedesktop.org> | 2003-11-14 15:54:53 +0000 |
commit | 71194c9839debbb6c1baaa4d5d8105af39907803 (patch) | |
tree | f75595183f24c6e7e9aa9e28898a45b42751fb3b /xcmsdb.c |
R6.6 is the Xorg base-lineXORG-MAINXORG-STABLE
Diffstat (limited to 'xcmsdb.c')
-rw-r--r-- | xcmsdb.c | 888 |
1 files changed, 888 insertions, 0 deletions
diff --git a/xcmsdb.c b/xcmsdb.c new file mode 100644 index 0000000..441e567 --- /dev/null +++ b/xcmsdb.c @@ -0,0 +1,888 @@ +/* $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. + * + */ + +/* + * INCLUDES + */ + +#include <stdio.h> +#include <X11/Xlib.h> +#include <X11/Xatom.h> +#include <X11/Xos.h> +#include <ctype.h> + +#include "SCCDFile.h" + +static unsigned long _XcmsGetElement(); +static int _XcmsGetProperty(); + +char *ProgramName; + +void Syntax () +{ + fprintf (stderr, + "usage: %s [-options ...] [filename]\n\n", + ProgramName); + fprintf (stderr, + "where options include:\n"); + fprintf (stderr, + " -display host:dpy[.scrn] display to use\n"); + fprintf (stderr, + " -format [ 32 | 16 | 8 ] property format\n"); + fprintf (stderr, + " -query query Screen Color Characterization Data\n"); + fprintf (stderr, + " -remove remove Screen Color Characterization Data\n"); +#ifdef GRAY + fprintf (stderr, + " -color use color as default\n"); + fprintf (stderr, + " -gray use gray-scale as default\n"); +#endif /* GRAY */ + fprintf (stderr, + "\n"); + exit (1); +} + +static Bool optionmatch (opt, arg, minlen) + char *opt; + 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); +} + +main (argc, argv) + int argc; + char **argv; +{ + Display *dpy; + int i; + 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 (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 (); + /* doesn't return */ + } else if (optionmatch ("-display", arg, 1)) { + if (++i >= argc) Syntax (); + displayname = argv[i]; + continue; + } else if (optionmatch ("-format", arg, 1)) { + if (++i >= argc) Syntax (); + targetFormat = atoi(argv[i]); + if (targetFormat != 32 && targetFormat != 16 && + targetFormat != 8) Syntax(); + 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 */ + } + Syntax (); + } 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 (load && query) { + load = 0; + } + if (load && remove) { + load = 0; + } + + if (!query && !remove) { + 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*/ +} + + +Atom +ParseAtom (dpy, name, only_flag) + Display *dpy; + char *name; + int only_flag; +{ + return(XInternAtom(dpy, name, only_flag)); +} + + +/* + * NAME + * PrintTableType0 + * + * SYNOPSIS + */ +static void +PrintTableType0(format, pChar, pCount) + 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.5lf\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.5lf\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.5lf\n", hValue, fValue); + } + break; + default: + return; + } +} + + +/* + * NAME + * PrintTableType1 + * + * SYNOPSIS + */ +static void +PrintTableType1(format, pChar, pCount) + int format; + char **pChar; + unsigned long *pCount; +/* + * DESCRIPTION + * + * RETURNS + * XcmsFailure if failed. + * XcmsSuccess if succeeded. + * + */ +{ + 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.5lf\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.5lf\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.5lf\n", hValue, fValue); + } + break; + default: + return; + } +} + + +/* + * NAME + * QuerySCCData - Query for the SCC data on the root window + * + * SYNOPSIS + */ +int +QuerySCCDataRGB(dpy, root) + 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 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 %d\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.5lf", + (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.5lf", + (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 %d\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(dpy, root) + Display *dpy; + Window root; +/* + * DESCRIPTION + * + * RETURNS + * None + */ +{ + char *property_return, *pChar; + int j; + 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 (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 + */ +int +RemoveSCCData(dpy, root, colorFlag) + Display *dpy; + Window root; + int colorFlag; +/* + * DESCRIPTION + * + * RETURNS + * None + */ +{ + unsigned char *ret_prop; + unsigned long ret_len, ret_after; + int ret_format; + Atom MatricesAtom, CorrectAtom, ret_atom; + + if (colorFlag != 0) { + MatricesAtom = ParseAtom (dpy, XDCCC_MATRIX_ATOM_NAME, True); + if (MatricesAtom != None) { + XGetWindowProperty (dpy, root, MatricesAtom, 0, 8192, False, + XA_INTEGER, &ret_atom, &ret_format, &ret_len, + &ret_after, &ret_prop); + } + if (MatricesAtom == None || !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 ((char *)ret_prop); + } + + CorrectAtom = XInternAtom (dpy, XDCCC_CORRECT_ATOM_NAME, True); + if (CorrectAtom != None) { + XGetWindowProperty (dpy, root, CorrectAtom, 0, 8192, False, + XA_INTEGER, &ret_atom, &ret_format, &ret_len, + &ret_after, &ret_prop); + } + if (CorrectAtom == None || !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 ((char *)ret_prop); + } + } +#ifdef GRAY + if (colorFlag != 1) { + MatricesAtom = ParseAtom (dpy, XDCCC_SCREENWHITEPT_ATOM_NAME, True); + if (MatricesAtom != None) { + XGetWindowProperty (dpy, root, MatricesAtom, 0, 8192, False, + XA_INTEGER, &ret_atom, &ret_format, &ret_len, + &ret_after, &ret_prop); + } + if (MatricesAtom == None || !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 ((char *)ret_prop); + } + + CorrectAtom = XInternAtom (dpy, XDCCC_GRAY_CORRECT_ATOM_NAME, True); + if (CorrectAtom != None) { + XGetWindowProperty (dpy, root, CorrectAtom, 0, 8192, False, + XA_INTEGER, &ret_atom, &ret_format, &ret_len, + &ret_after, &ret_prop); + } + if (CorrectAtom == None || !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 ((char *)ret_prop); + } + } +#endif /* GRAY */ +} + +static unsigned long +_XcmsGetElement (format, pValue, pCount) + 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 existance of a property + * + * SYNOPSIS + */ +static int +_XcmsGetProperty (pDpy, w, property, pFormat, pNItems, pNBytes, pValue) + 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; + + while (XGetWindowProperty (pDpy, w, property, 0, len, False, + XA_INTEGER, &atom_ret, &format_ret, + &nitems_ret, &after_ret, + (unsigned char **)&prop_ret)) { + if (after_ret > 0) { + len += nitems_ret * (format_ret >> 3); + XFree (prop_ret); + } else { + break; + } + } + if (format_ret == 0 || nitems_ret == 0) { + /* the property does not exist or is of an unexpected type */ + return(XcmsFailure); + } + + *pFormat = format_ret; + *pNItems = nitems_ret; + *pNBytes = nitems_ret * (format_ret >> 3); + *pValue = prop_ret; + return(XcmsSuccess); +} |