home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The World of Computer Software
/
World_Of_Computer_Software-02-385-Vol-1of3.iso
/
x
/
xtici.zip
/
xtici
/
xtici.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-08-28
|
16KB
|
551 lines
/*
* Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc.
* All Rights Reserved
*
* This file is a component of an X Window System client which uses the Xcms
* Color Management System. TekColor is a trademark of Tektronix, Inc. The
* TekColor Editor is the subject of U.S. and foreign patents pending. The
* term "TekHVC" designates a particular color space that is the subject of
* U.S. Patent No. 4,985,853 (equivalent foreign patents pending).
* Permission is hereby granted to use, copy, modify, sell, and otherwise
* distribute this software and its documentation for the X Window System
* environment, for any purpose and without fee, provided that:
*
* 1. The code and documentation are only used to implement a
* TekColor Editor in an X Window System environment; and
* 2. This copyright and permission notice is reproduced in all copies
* of the code and in supporting documentation.
*
* Permission is granted to modify this code as required to allow it to
* be compiled on any host computer, provided that the functionality of
* the TekColor Editor is not modified in any way. A description of any
* modifications must be sent to Tektronix, Inc. Contact
* Tektronix Inc., P.O. Box 1000, Mail Station 60-850,
* Network Displays Division Engineering, Wilsonville, OR 97070.
*
* Tektronix makes no representation about the suitability of this software
* for any purpose. It is provided "as is" and with all faults.
*
* TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE,
* INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE. 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 THE PERFORMANCE OF THIS SOFTWARE.
*
* NAME
* xtici.c - the main routine for the the TekColor Editor
*
* SYNOPSIS
* xtici [options]
* options:
* -display {hostname:number.screen}
* -huebar {empty | constant | dynamic}
* -leaf {empty | filled}
* -gamutProc {closest | chroma | value}
*
* DESCRIPTION
* xtici is a colormap editor based on the TekColor(TM)
* color space. It provides an intuitive color selection model
* based on Hue, Value and Chroma.
*
* TekColor is a trademark of Tektronix, Inc.
*
* SEE ALSO
* <related documentation, programs, and packages>
* <not already mentioned>
*
* DIAGNOSTICS
* <error messages, meanings, and corrective actions>
*
* BUGS
* <currently known loony behavior>
*
*/
#ifndef LINT
static char *copy_notice = "Copyright 1991 Tektronix, Inc.";
#ifdef RCS_ID
static char *rcsid= "$Header: xtici.c,v 1.3 91/08/28 10:03:48 adamsc Exp $";
#endif /* RCS_ID */
#endif /* LINT */
/*
* EXTERNAL INCLUDES
*/
/*
* INTERNAL INCLUDES
*/
#include <stdio.h>
#include <X11/StringDefs.h>
#include <X11/IntrinsicP.h>
#include <X11/keysym.h>
#include "xtici.h"
#include "widgets/VShell.h"
/*
* EXTERNS
*/
#ifdef XDEBUG
extern int event_error_handler ();
extern int io_error_handler ();
#endif /* XDEBUG */
extern XcmsColorSpace XcmsTekHVCColorSpace;
/*
* GLOBALS
*/
#ifdef DEC
# define GLOBAL global
#else
# define GLOBAL
#endif
GLOBAL char *exeName = "";
GLOBAL char *versionString = "xtici version 1.0a";
GLOBAL char *dpy_name = NULL;
/* colormap size based on visual selected */
GLOBAL int mapSize = 0;
GLOBAL Time lastTime = 0;
/*
* LOCAL VARIABLES
*/
#ifdef DEBUG
# define STATIC
#else
# define STATIC static
#endif
STATIC XtConvertArgRec convertArgs[] = {
{XtWidgetBaseOffset, (XtPointer)XtOffset(Widget, core.screen), sizeof(Screen *)},
{XtWidgetBaseOffset, (XtPointer)XtOffset(Widget, core.colormap), sizeof(Colormap)}
};
/*
* Replacement string-to-pixel converter that assumes all colormap
* entries are pre-allocated. It simply translates the string into a color
* description, then stores that description into the next available
* color cell.
*/
STATIC String XtNwrongParameters = "wrongParameters";
STATIC String XtCHvcCvtStringToPixelError = "HvcCvtStringToPixelError";
#define CvtDone(type, value) \
{ \
if (to->addr != NULL) { \
if (to->size < sizeof(type)) { \
to->size = sizeof(type); \
return False; \
} else { \
*(type*)(to->addr) = (value); \
} \
} else { \
STATIC type static_val; \
static_val = (value); \
to->addr = (XtPointer)&static_val; \
} \
to->size = sizeof(type); \
RegisterIfPixel(*((Pixel *)(to->addr))); \
return True; \
}
STATIC int CompareISOLatin1(first, second)
char *first, *second;
{
register unsigned char *ap, *bp;
for (ap = (unsigned char *) first, bp = (unsigned char *) second;
*ap && *bp; ap++, bp++) {
register unsigned char a, b;
if ((a = *ap) != (b = *bp)) {
/* try lowercasing and try again */
if ((a >= XK_A) && (a <= XK_Z))
a += (XK_a - XK_A);
else if ((a >= XK_Agrave) && (a <= XK_Odiaeresis))
a += (XK_agrave - XK_Agrave);
else if ((a >= XK_Ooblique) && (a <= XK_Thorn))
a += (XK_oslash - XK_Ooblique);
if ((b >= XK_A) && (b <= XK_Z))
b += (XK_a - XK_A);
else if ((b >= XK_Agrave) && (b <= XK_Odiaeresis))
b += (XK_agrave - XK_Agrave);
else if ((b >= XK_Ooblique) && (b <= XK_Thorn))
b += (XK_oslash - XK_Ooblique);
if (a != b) break;
}
}
return (((int) *bp) - ((int) *ap));
}
/************************************************************************
* *
* PRIVATE ROUTINES *
* *
************************************************************************/
STATIC Boolean IsReveseVideo(dsply)
Display *dsply;
{
XrmDatabase db;
String name, class;
XrmName name_list[3];
XrmName class_list[3];
XrmRepresentation type;
XrmValue val;
XrmQuark QString;
db = XtScreenDatabase(DefaultScreenOfDisplay(dsply));
XtGetApplicationNameAndClass(dsply, &name, &class);
name_list[0] = XrmStringToQuark(name);
name_list[1] = XrmStringToQuark("reverseVideo");
class_list[0] = XrmStringToQuark(class);
class_list[1] = XrmStringToQuark("ReverseVideo");
name_list[2] = class_list[2] = NULLQUARK;
QString = XrmStringToQuark(XtRString);
if (XrmQGetResource(db, name_list, class_list, &type, &val) &&
type == QString) {
/* printf("We found reverse video on.\n"); */
return (True);
}
/* printf("We found reverse video off.\n"); */
return (False);
}
/* ARGSUSED */
STATIC Boolean HvcCvtStringToPixel(dsply, args, count, from, to, cdata)
Display *dsply;
XrmValuePtr args;
Cardinal *count;
XrmValuePtr from, to;
XtPointer *cdata;
{
Display *pDpy;
String str = (String)from->addr;
XcmsColor change;
STATIC XColor target, screenColor;
Screen *screen;
XtAppContext ac;
Colormap map;
Status stat;
String params[1];
Cardinal num_params;
screen = *((Screen**)args[0].addr);
map = *((Colormap *)args[1].addr);
/**************************************************************************
* TODO: sometimes this is passing in NULL values. I have tracked this
* to _XtConvert attempting to convert a string into pixel using a gadget.
* The problem is that a gadget does not have a screen or colormap,
* so garbage is loaded into the args. I am lucky that the garbage happens
* to be zero, so this is easy to detect.
* Need to find out why a gadget is being called to do this -
* the conversion should be done by the parent manager and inherited by
* the gadget!. This might have something to do with resetting the colormap
* and visual.
**************************************************************************/
if (!screen || !map) {
if (!screen)
screen = DefaultScreenOfDisplay(dpy);
pDpy = dpy;
map = cmap;
} else {
if (map != cmap)
map = cmap;
if (dpy != DisplayOfScreen(screen)) {
pDpy = dpy;
screen = DefaultScreenOfDisplay(dpy);
} else
pDpy = DisplayOfScreen(screen);
}
ac = XtDisplayToApplicationContext(pDpy);
if (*count != 2) {
num_params = 0;
XtAppWarningMsg(ac, XtNwrongParameters, "cvtStringToPixel",
XtCHvcCvtStringToPixelError,
"String to pixel conversion needs screen and colormap arguments",
(String *)NULL, &num_params);
}
if (CompareISOLatin1(str, XtDefaultBackground) == 0) {
if (IsReveseVideo(pDpy))
CvtDone(Pixel, BlackPixelOfScreen(screen))
else
CvtDone(Pixel, WhitePixelOfScreen(screen))
} else if (CompareISOLatin1(str, XtDefaultForeground) == 0) {
if (IsReveseVideo(pDpy))
CvtDone(Pixel, WhitePixelOfScreen(screen))
else
CvtDone(Pixel, BlackPixelOfScreen(screen))
}
/* use parse color to allow rgb database colors and # formatted colors */
if (*str == '#') {
stat = XParseColor(pDpy, map, str, &target);
if (stat == 0) {
params[0] = str;
num_params = 1;
XtAppWarningMsg(ac, "badFormat", "cvtStringToPixel",
XtCHvcCvtStringToPixelError,
"RGB color specification \"%s\" has invalid format",
params, &num_params);
return False;
}
/*
* To minimize flashing, allocate the color in the default map,
* then store the color into that pixel of the target map.
*/
stat = XAllocColor(pDpy, DefaultColormapOfScreen(screen), &target);
} else {
stat = XAllocNamedColor(pDpy, DefaultColormapOfScreen(screen),
(char*)str, &screenColor, &target);
}
if (stat == 0) {
String msg, type;
params[0] = str;
num_params = 1;
/* Server returns a specific error code but Xlib discards it. Ugh */
if (*str == '#' ||
XLookupColor(pDpy, DefaultColormapOfScreen(screen), (char*)str,
&target, &screenColor)) {
type = "noColormap";
msg = "Cannot allocate colormap entry for \"%s\"";
} else {
type = "badValue";
msg = "Color name \"%s\" is not defined in server database";
}
XtAppWarningMsg(ac, type, "cvtStringToPixel",
XtCHvcCvtStringToPixelError, msg, params, &num_params);
return False;
}
XStoreColor(pDpy, map, &target);
/* Get the current color in HVC space (from default map) */
change.pixel = target.pixel;
change.format = XcmsTekHVCFormat;
change.spec.TekHVC.H =change.spec.TekHVC.V =change.spec.TekHVC.C =0.0;
if (XcmsQueryColor(pDpy, DefaultColormapOfScreen(screen), &change,
XcmsTekHVCFormat) == XcmsFailure){
#ifdef XDEBUG
fprintf(stderr, "Warning: XcmsQueryColor failed in HvcConvertStringtoPixel\n");
#endif
}
/* Now change private map to match default */
ChangeHvcCells(&change, 1, DECREASE_CHROMA);
/* Remember this is used in the interface */
CvtDone(Pixel, target.pixel)
}
/*****************************************************************************
*
* Replacement routine for XtMainLoop
*
*****************************************************************************/
STATIC void MainLoop(app)
XtAppContext app;
{
Boolean process;
XEvent evnt;
for (;;) {
XtAppNextEvent(app, &evnt);
switch (evnt.type) {
case ButtonPress:
case ButtonRelease:
/* lets keep track of time so that selection.c can work */
lastTime = ((XButtonEvent *)&evnt)->time;
/* if HandleGrab returns non-zero, it has processed the event */
if (grabState != GrabNone && HandleGrab((XButtonEvent *)&evnt))
process = False;
else
process = True;
break;
case ClientMessage:
HandleUserMessage((XClientMessageEvent *)&evnt);
process = True; /* allow rest of toolkit to take a look at it */
break;
default:
process = True;
break;
}
if (process)
XtDispatchEvent(&evnt);
}
}
STATIC void Usage()
{
Error("Usage: xtici [options]\n\
Options:\n\
\t-display {hostname:number.screen_number}\n\
\t-huebar {empty | constant | dynamic}\n\
\t-leaf {filled | empty}\n\
\t-gamutProc {closest | chroma | value}\n");
}
STATIC void ParseArgs(ct, list)
int ct;
char **list;
{
int i;
for (i = 1; i < ct; i++) {
if (!strcmp(list[i], "-huebar")) {
i++;
if (!strcmp(list[i], "empty"))
huebarState = HuebarEmpty;
else if ((!strcmp(list[i], "constant")) && (allowFill <= FillHuebar))
huebarState = HuebarConstant;
else if ((!strcmp(list[i], "dynamic")) && (allowFill <= FillHuebar))
huebarState = HuebarDynamic;
else
Usage();
} else if (!strcmp(list[i], "-leaf")) {
i++;
if (!strcmp(list[i], "empty"))
;
else if (!strcmp(list[i], "filled"))
leafState |= LeafFilled;
else
Usage();
} else if (!strcmp(list[i], "-gamutProc")) {
i++;
if (!strcmp(list[i], "closest"))
GamutComp = GamutCompClosest;
else if (!strcmp(list[i], "chroma"))
GamutComp = GamutCompChroma;
else if (!strcmp(list[i], "value"))
GamutComp = GamutCompValue;
else
Usage();
} else if (!strcmp(list[i], "-display")) {
i++;
dpy_name = list[i];
} else
Usage();
}
}
/*****************************************************************************
*
* This is the main executable.
*
*****************************************************************************/
main(argc, argv)
int argc;
char **argv;
{
Widget top, LayoutWidgets();
XtAppContext app;
extern void CreateColormap(); /* A series of routines from resources.c */
extern void CreateCursors();
extern void CreateAtoms();
extern void ValidateDisplay();
extern void Leave();
STATIC XtActionsRec leave[] = {
{ "leave", Leave },
};
/* reqVisual is forced to be PseudoColor */
reqVisual = PseudoColor;
/* extract executable name */
exeName = strrchr(argv[0], '/');
if (exeName)
exeName++; /* move past last / in pathname */
else
exeName = argv[0]; /* no path portion in name */
ParseArgs(argc, argv);
/* Init the toolkit */
/* Startup takes a long time, so print messages to advise of status */
printf("Initializing toolkit ...\n");
XtToolkitInitialize();
/* Open and validate display */
app = XtCreateApplicationContext();
if (!(dpy = XtOpenDisplay(app, dpy_name, exeName, "Hvc", NULL, 0,
&argc, argv))) {
Error("No display opened, exiting the program.");
}
#ifdef XDEBUG
XSetErrorHandler (event_error_handler);
XSetIOErrorHandler (io_error_handler);
XSynchronize (dpy, 1);
#endif /* XDEBUG */
if (!dpy)
Error("Cannot open display.");
/* set the default CCC and check for PseudoColor Visual */
ValidateDisplay();
if (!XcmsAddColorSpace(&XcmsTekHVCColorSpace)) {
Error("Failed to find or initialize the TekHVC color space.");
}
/*
* Replace the string-to-pixel converter so that we know which colors
* are used by the interface so we can warn people about certain changes.
*/
XtSetTypeConverter(XtRString, XtRPixel, HvcCvtStringToPixel,
convertArgs, XtNumber(convertArgs),
XtCacheNone, (XtDestructor)NULL);
/* Create resources which do not need windows */
CreateColormap();
CreateCursors();
CreateAtoms();
/* add some actions for gesture completion */
XtAppAddActions (app, leave, XtNumber(leave));
/* Layout the widgets for the entire interface */
printf("Creating widgets ...\n");
top = LayoutWidgets();
/* Setup, must happen after widgets are created */
SetFirstIndex();
/*
* Create the windows, and set their attributes according
* to the Widget data.
*/
printf("Realizing widgets ...\n");
XtRealizeWidget(top);
/* There does not seem to be a cursor widget attribute, so do this here */
SetCursor(normalCursor);
/* use this window to take ownership of the selection */
InitSelection(top);
/* Build some resources */
LeafRealize();
/* Make sure the leaf colormap and the local colormap are the same. */
if (leaf->core.colormap != cmap) {
leaf->core.colormap = cmap;
}
/* Now process the events. */
printf("Running xtici ...\n");
MainLoop(app);
/*NOTREACHED*/
}