x11-xserver-utils/xcmsdb/xcmsdb.c

871 lines
20 KiB
C
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* $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
*/
#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 (void)
{
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(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);
}
int
main(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*/
}
static Atom
ParseAtom(Display *dpy, 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.
*
*/
{
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 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 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
*/
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;
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(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(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);
}