[comp.sources.x] v07i077: X color editor, Part01/01

peebles@mips.com (Andrew Peebles) (05/27/90)

Submitted-by: peebles@mips.com (Andrew Peebles)
Posting-number: Volume 7, Issue 77
Archive-name: xce/part01

[ From the README ]
This is a Motif color editor.  It can be used in various ways, but the most
interesting feature is the ability to pick an existing application window,
get a pixmap copy of it, and play with the colors.  You can get a feel for
how the whole application will look like with new colors.  There is also
a special window that shows the system's rgb.txt file and the resulting
colors.  This can be used as a reference palet when experimenting with
new colors.

#---------------------------------- cut here ----------------------------------
# This is a shell archive.  Remove anything before this line,
# then unpack it by saving it in a file and typing "sh file".
#
# Wrapped by  peebles@krell on Thu May 17 16:15:42 PDT 1990
#
# This archive contains:
#	README
#	Imakefile
#	Makefile
#	XCe
#	WIDGETS
#	xce.1
#	SetArg.c
#	color_lib.c
#	image.c
#	main.c
#	image.h
#	patchlevel.h
#	pix.h
#
LANG=""; export LANG
echo x - README
cat > README << '@EOF'
This is a Motif color editor.  It can be used in various ways, but the most
interesting feature is the ability to pick an existing application window,
get a pixmap copy of it, and play with the colors.  You can get a feel for
how the whole application will look like with new colors.  There is also
a special window that shows the system's rgb.txt file and the resulting
colors.  This can be used as a reference palet when experimenting with
new colors.

This, of course, is not a commercial application.  It is pretty much hard
wired for 8-bit displays w/ read/write color maps.  It should be easy
though to change a bit of code to make it work for other display setups.

Distribution and copying policy:

	1.  Have fun and don't sell it.
	2.  Don't tell anybody I wrote it.

Author

Andrew Peebles
Mips Computer Systems
peebles@mips.com

(P.S.  Its Motif, ya may have to hack the Imakefile for your system)
@EOF
echo x - Imakefile
cat > Imakefile << '@EOF'
       MOTIFLIB = -lXm
    DEPMOTIFLIB = $(USRLIBDIR)/libXm.a

LOCAL_LIBRARIES = $(MOTIFLIB) $(XTOOLLIB) $(XLIB) 
       	DEPLIBS = $(DEPMOTIFLIB) $(DEPXTOOLLIB) $(DEPXLIB)

           SRCS = main.c color_lib.c SetArg.c image.c

           OBJS = main.o color_lib.o SetArg.o image.o

ComplexProgramTarget(xce)
@EOF
echo x - Makefile
cat > Makefile << '@EOF'
# Makefile generated by imake - do not edit!
# $XConsortium: imake.c,v 1.51 89/12/12 12:37:30 jim Exp $

###########################################################################
# Makefile generated from "Imake.tmpl" and <Imakefile>
# $XConsortium: Imake.tmpl,v 1.77 89/12/18 17:01:37 jim Exp $
#
# Platform-specific parameters may be set in the appropriate .cf
# configuration files.  Site-wide parameters may be set in the file
# site.def.  Full rebuilds are recommended if any parameters are changed.
#
# If your C preprocessor doesn't define any unique symbols, you'll need
# to set BOOTSTRAPCFLAGS when rebuilding imake (usually when doing
# "make Makefile", "make Makefiles", or "make World").
#
# If you absolutely can't get imake to work, you'll need to set the
# variables at the top of each Makefile as well as the dependencies at the
# bottom (makedepend will do this automatically).
#

###########################################################################
# platform-specific configuration parameters - edit Mips.cf to change

# platform:  $XConsortium: Mips.macros,v 1.30 88/10/23 11:00:33 jim Exp $

         SYSVTYPE = -systype sysv
          BSDTYPE = -systype bsd43
         SYSVDEFS = -DMips -DSYSV
          BSDDEFS = -DMips -DBSD43
         SYSVINCS = -I/usr/include/bsd
          BSDINCS =
         SYSVLIBS = -lbsd -lmld
          BSDLIBS = -lmld

  EXTENSIONBSDLIB = $(EXTENSIONSRC)/lib/libbsdXext.a
          XBSDLIB = $(XLIBSRC)/libbsdX11.a
        XMUBSDLIB = $(XMUSRC)/libbsdXmu.a
       OLDXBSDLIB = $(OLDXLIBSRC)/libbsdoldX.a
      XTOOLBSDLIB = $(TOOLKITSRC)/libbsdXt.a
        XAWBSDLIB = $(AWIDGETSRC)/libbsdXaw.a

          SYSTYPE = $(BSDTYPE)
          SYSDEFS = $(BSDDEFS)
          SYSINCS = $(BSDINCS)
          SYSLIBS = $(BSDLIBS)

     OPTIM = -O
     CCOPT = -signed
SYSVCFLAGS = $(OPTIM) $(CCOPT) $(SYSVTYPE) $(INCLUDES) $(SYSVDEFS) $(SYSVINCS) $(DEFINES)
 BSDCFLAGS = $(OPTIM) $(CCOPT) $(BSDTYPE)  $(INCLUDES) $(BSDDEFS)  $(BSDINCS)  $(DEFINES)

          ARFLAGS = clr
           ETCDIR = /etc
          ULIBDIR = /usr/lib

      XINSTALLDIR = X11
     INSTALLFLAGS = -m 0555
        RS1210DIR = $(DESTDIR)/usr/$(XINSTALLDIR)/RS1210
       CONTRIBDIR = $(DESTDIR)/usr/$(XINSTALLDIR)/contrib
     RS1210LIBDIR = $(LIBDIR)/ncd

          BINPATH = /usr/bin/X11
          LIBPATH = /usr/lib/X11
          ETCPATH = /usr/etc/X11
          ADMPATH = /usr/adm
          NCDPATH = /usr/X11/ncd
       NCDLIBPATH = $(LIBPATH)/ncd
        XINITPATH = $(LIBPATH)/xinit
          XDMPATH = $(ETCPATH)/xdm
          UWMPATH = $(LIBPATH)/uwm
          AWMPATH = $(LIBPATH)/awm
          MWMPATH = $(LIBPATH)/mwm
          TWMPATH = $(LIBPATH)/twm
     XAPPLOADPATH = $(LIBPATH)/app-defaults
        RS1210SRC = $(TOP)/rs1210

       MOTIFSRC = $(TOP)/motif
        MLIBSRC = $(MOTIFSRC)/lib
     MCLIENTSRC = $(MOTIFSRC)/clients
       MDEMOSRC = $(MOTIFSRC)/demos
    MTOOLKITSRC = $(MLIBSRC)/Xt
     MWIDGETSRC = $(MLIBSRC)/Xm
   INCLUDEXMSRC = $(MLIBSRC)/Xm
   MRESOURCESRC = $(MLIBSRC)/Mrm
         MWMDIR = $(LIBDIR)/Mwm
     DEMOBINDIR = $(DESTDIR)/usr/$(XINSTALLDIR)/demos/bin
     DEMOSRCDIR = $(DESTDIR)/usr/$(XINSTALLDIR)/demos/src
      XMTOOLLIB = $(MTOOLKITSRC)/libXt.a
          XMLIB = $(MWIDGETSRC)/libXm.a
   MRESOURCELIB = $(MRESOURCESRC)/libMrm.a
       MINCLUDE = $(TOP)/include
         UILSRC = $(MCLIENTSRC)/uil
         UILLIB = $(UILSRC)/libUil.a
            UIL = $(UILSRC)/uil

###########################################################################
# site-specific configuration parameters - edit site.def to change

# site:  $XConsortium: site.def,v 1.21 89/12/06 11:46:50 jim Exp $

            SHELL = 	/bin/sh

              TOP = .
      CURRENT_DIR = .

               AR = ar
  BOOTSTRAPCFLAGS = $(SYSDEFS)
               CC = cc2.0

         COMPRESS = compress
              CPP = cc2.0 -E $(STD_CPP_DEFINES)
    PREPROCESSCMD = cc2.0 -E $(STD_CPP_DEFINES)
          INSTALL = $(ETCDIR)/mipsinstall
               LD = ld2.0
             LINT = lint
      LINTLIBFLAG = -C
         LINTOPTS = -axz
               LN = ln -s
             MAKE = make ETCDIR='$(ETCDIR)' ULIBDIR='$(ULIBDIR)'
               MV = mv
               CP = cp
           RANLIB = /bin/true
  RANLIBINSTFLAGS =
               RM = rm -f
     STD_INCLUDES =
  STD_CPP_DEFINES = $(SYSDEFS)
      STD_DEFINES = $(SYSDEFS) $(SYSINCS)
 EXTRA_LOAD_FLAGS =
  EXTRA_LIBRARIES = $(SYSLIBS)
             TAGS = ctags

   SIGNAL_DEFINES = -DSIGNALRETURNSINT

    PROTO_DEFINES =

     INSTPGMFLAGS =

     INSTBINFLAGS = -m 0755
     INSTUIDFLAGS = -m 4755
     INSTLIBFLAGS = -m 0664
     INSTINCFLAGS = -m 0444
     INSTMANFLAGS = -m 0444
     INSTDATFLAGS = -m 0444
    INSTKMEMFLAGS = -m 4755

          DESTDIR = $(DESTROOT)

     TOP_INCLUDES = -I$(INCROOT)

      CDEBUGFLAGS = $(OPTIM) $(CCOPT) $(SYSTYPE)
        CCOPTIONS =
      COMPATFLAGS =

      ALLINCLUDES = $(STD_INCLUDES) $(TOP_INCLUDES) $(INCLUDES) $(EXTRA_INCLUDES)
       ALLDEFINES = $(ALLINCLUDES) $(STD_DEFINES) $(PROTO_DEFINES) $(DEFINES) $(COMPATFLAGS)
           CFLAGS = $(CDEBUGFLAGS) $(CCOPTIONS) $(ALLDEFINES)
        LINTFLAGS = $(LINTOPTS) -DLINT $(ALLDEFINES)
           LDLIBS = $(SYS_LIBRARIES) $(EXTRA_LIBRARIES)
        LDOPTIONS = $(CDEBUGFLAGS) $(CCOPTIONS)
   LDCOMBINEFLAGS = -X -r

        MACROFILE = Mips.cf
           RM_CMD = $(RM) *.CKP *.ln *.BAK *.bak *.o core errs ,* *~ *.a .emacs_* tags TAGS make.log MakeOut *.u *.b

    IMAKE_DEFINES =

         IRULESRC = $(CONFIGDIR)
        IMAKE_CMD = $(IMAKE) -DUseInstalled -I$(IRULESRC) $(IMAKE_DEFINES)

     ICONFIGFILES = $(IRULESRC)/Imake.tmpl $(IRULESRC)/Imake.rules \
			$(IRULESRC)/Project.tmpl $(IRULESRC)/site.def \
			$(IRULESRC)/$(MACROFILE) $(EXTRA_ICONFIGFILES)

###########################################################################
# X Window System Build Parameters
# $XConsortium: Project.tmpl,v 1.63 89/12/18 16:46:44 jim Exp $

###########################################################################
# X Window System make variables; this need to be coordinated with rules
# $XConsortium: Project.tmpl,v 1.63 89/12/18 16:46:44 jim Exp $

          PATHSEP = /
        USRLIBDIR = $(DESTDIR)/usr/$(XINSTALLDIR)/lib
           BINDIR = $(DESTDIR)/usr/$(XINSTALLDIR)/bin
          INCROOT = ./
     BUILDINCROOT = $(TOP)
      BUILDINCDIR = $(BUILDINCROOT)/X11
      BUILDINCTOP = ..
           INCDIR = $(INCROOT)/X11
           ADMDIR = $(DESTDIR)/usr/adm
           LIBDIR = $(USRLIBDIR)/X11
        CONFIGDIR = $(LIBDIR)/config
       LINTLIBDIR = $(USRLIBDIR)/lint

          FONTDIR = $(LIBDIR)/fonts
         XINITDIR = $(LIBDIR)/xinit
           XDMDIR = $(DESTDIR)/usr/X11/etc/xdm
           AWMDIR = $(LIBDIR)/awm
           TWMDIR = $(LIBDIR)/twm
           GWMDIR = $(LIBDIR)/gwm
          MANPATH = $(DESTDIR)/usr/$(XINSTALLDIR)/man/cat
    MANSOURCEPATH = $(MANPATH)/man
           MANDIR = $(MANSOURCEPATH)1
        LIBMANDIR = $(MANSOURCEPATH)3
      XAPPLOADDIR = $(LIBDIR)/app-defaults

       FONTCFLAGS = -t

     INSTAPPFLAGS = $(INSTDATFLAGS)

            IMAKE = imake
           DEPEND = makedepend
              RGB = rgb
            FONTC = bdftosnf
        MKFONTDIR = mkfontdir
        MKDIRHIER = 	/bin/sh $(BINDIR)/mkdirhier.sh

        CONFIGSRC = $(TOP)/config
        CLIENTSRC = $(TOP)/clients
          DEMOSRC = $(TOP)/demos
           LIBSRC = $(TOP)/lib
          FONTSRC = $(TOP)/fonts
       INCLUDESRC = $(TOP)/X11
        SERVERSRC = $(TOP)/server
          UTILSRC = $(TOP)/util
        SCRIPTSRC = $(UTILSRC)/scripts
       EXAMPLESRC = $(TOP)/examples
       CONTRIBSRC = $(TOP)/../contrib
           DOCSRC = $(TOP)/doc
           RGBSRC = $(TOP)/rgb
        DEPENDSRC = $(UTILSRC)/makedepend
         IMAKESRC = $(CONFIGSRC)
         XAUTHSRC = $(LIBSRC)/Xau
          XLIBSRC = $(LIBSRC)/X
           XMUSRC = $(LIBSRC)/Xmu
       TOOLKITSRC = $(LIBSRC)/Xt
       AWIDGETSRC = $(LIBSRC)/Xaw
       OLDXLIBSRC = $(LIBSRC)/oldX
      XDMCPLIBSRC = $(LIBSRC)/Xdmcp
      BDFTOSNFSRC = $(FONTSRC)/bdftosnf
     MKFONTDIRSRC = $(FONTSRC)/mkfontdir
     EXTENSIONSRC = $(TOP)/extensions

  DEPEXTENSIONLIB =  $(USRLIBDIR)/libXext.a
     EXTENSIONLIB = 			  -lXext

          DEPXLIB = $(DEPEXTENSIONLIB)  $(USRLIBDIR)/libX11.a
             XLIB = $(EXTENSIONLIB) 			  -lX11

      DEPXAUTHLIB =  $(USRLIBDIR)/libXau.a
         XAUTHLIB = 			  -lXau

        DEPXMULIB =  $(USRLIBDIR)/libXmu.a
           XMULIB = 			  -lXmu

       DEPOLDXLIB =  $(USRLIBDIR)/liboldX.a
          OLDXLIB = 			  -loldX

      DEPXTOOLLIB =  $(USRLIBDIR)/libXt.a
         XTOOLLIB = 			  -lXt

        DEPXAWLIB =  $(USRLIBDIR)/libXaw.a
           XAWLIB = 			  -lXaw

 LINTEXTENSIONLIB =  $(USRLIBDIR)/llib-lXext.ln
         LINTXLIB =  $(USRLIBDIR)/llib-lX11.ln
          LINTXMU =  $(USRLIBDIR)/llib-lXmu.ln
        LINTXTOOL =  $(USRLIBDIR)/llib-lXt.ln
          LINTXAW =  $(USRLIBDIR)/llib-lXaw.ln

          DEPLIBS = $(LOCAL_LIBRARIES)

         DEPLIBS1 = $(DEPLIBS)
         DEPLIBS2 = $(DEPLIBS)
         DEPLIBS3 = $(DEPLIBS)

###########################################################################
# Imake rules for building libraries, programs, scripts, and data files
# rules:  $XConsortium: Imake.rules,v 1.67 89/12/18 17:14:15 jim Exp $

###########################################################################
# start of Imakefile

       MOTIFLIB = -lXm
    DEPMOTIFLIB = $(USRLIBDIR)/libXm.a

LOCAL_LIBRARIES = $(MOTIFLIB) $(XTOOLLIB) $(XLIB)
       	DEPLIBS = $(DEPMOTIFLIB) $(DEPXTOOLLIB) $(DEPXLIB)

           SRCS = main.c color_lib.c SetArg.c image.c

           OBJS = main.o color_lib.o SetArg.o image.o

        PROGRAM = xce

all:: xce

xce: $(OBJS) $(DEPLIBS)
	 $(RM) $@
	$(CC) -o $@ $(OBJS) $(LDOPTIONS) $(LOCAL_LIBRARIES) $(LDLIBS) $(EXTRA_LOAD_FLAGS)

install:: xce
	$(INSTALL) -c $(INSTPGMFLAGS)   xce $(BINDIR)

xce.1		:: xce.man
	nroff -man $? > $@

clean::
	rm -f xce.1

install.man:: xce.1
	$(INSTALL) -c $(INSTMANFLAGS) -f xce.1		 $(MANDIR)/xce.1

depend::
	$(DEPEND) -s "# DO NOT DELETE" -- $(ALLDEFINES) -- $(SRCS)

lint:
	$(LINT) $(LINTFLAGS) $(SRCS) $(LINTLIBS)
lint1:
	$(LINT) $(LINTFLAGS) $(FILE) $(LINTLIBS)

clean::
	$(RM) $(PROGRAM)

###########################################################################
# common rules for all Makefiles - do not edit

emptyrule::

clean::
	$(RM_CMD) \#*

Makefile::
	-@if [ -f Makefile ]; then \
		echo "	$(RM) Makefile.bak; $(MV) Makefile Makefile.bak"; \
		$(RM) Makefile.bak; $(MV) Makefile Makefile.bak; \
	else exit 0; fi
	$(IMAKE_CMD) -DTOPDIR=$(TOP) -DCURDIR=$(CURRENT_DIR)

tags::
	$(TAGS) -w *.[ch]
	$(TAGS) -xw *.[ch] > TAGS

###########################################################################
# empty rules for directories that do not have SUBDIRS - do not edit

install::
	@echo "install in $(CURRENT_DIR) done"

install.man::
	@echo "install.man in $(CURRENT_DIR) done"

Makefiles::

includes::

###########################################################################
# dependencies generated by makedepend

@EOF
echo x - XCe
cat > XCe << '@EOF'
!
! Example resources for xce, a color editor for X11
!
! Andrew Peebles
!
! These resources assume you have a color display, which if you didn't
! you wouldn't likely be using xce, or reading this comment for that
! matter.
!

!
! Some decent internal spacing for the main window
!
xce*verticalSpacing:	7
xce*horizontalSpacing:	7

!
! global colors and font
!
xce*background:		#00979e
xce*foreground:		black
xce*fontList:		9x15

!
! a different color for the `color under test' screen
!
xce*pix*background:	gold

!
! the color palet row column widget
!
xce*palet.numColumns:		5
xce*palet.packing:		PACK_COLUMN
xce*palet.orientation:		VERTICAL
xce*palet.spacing:		5

!
! size of buttons on palet
!
xce*palet*color.marginWidth:	25
xce*palet*color.marginHeight:	25

!
! smaller font for sliders
!
xce*Red*fontList:		6x13
xce*Green*fontList:		6x13
xce*Blue*fontList:		6x13
xce*Intensity*fontList:		6x13

!
! I like no value or text, just color on my sliders.  If you like value
! and text as well, use a resource like this:
!
! xce*Red.showValue:   True
! xce*Red.titleString: red, dude!
!
xce*Red*foreground: 		red
xce*Green*foreground: 		green
xce*Blue*foreground: 		blue
xce*Intensity*foreground:	black

!
! The help sceen (I'm already using xce to make colors!)
!
xce*helpWindow.foreground:	#ffff00
xce*helpWindow.background:	#cc4b32

!
! The rgb screen
!
xce*rgb.numColumns:		5
xce*rgb.packing:		PACK_COLUMN
xce*rgb.orientation:		VERTICAL
xce*rgb.spacing:		5
xce*rgb*fontList:		fgb-13
xce*rgb*background:		#007d5b

@EOF
echo x - WIDGETS
cat > WIDGETS << '@EOF'
xce:    			ApplicationShell
   form:        		XmForm

      !! main color display screen

      frame:    		XmFrame
         pix:   		XmLabel

      !! color mix controllers

      Red:      		XmScale
         scale_title:   	XmLabelGadget
         scale_scrollbar:       XmScrollBar
      Green:    		XmScale
         scale_title:   	XmLabelGadget
         scale_scrollbar:       XmScrollBar
      Blue:     		XmScale
         scale_title:   	XmLabelGadget
         scale_scrollbar:       XmScrollBar

      !! current color spec in ascii

      entry:    		XmText

      Quit:     		XmPushButton
      Window:   		XmPushButton

      !! help window

      help:     		XmPushButton
         helpWindow:    	XmDialogShell
            helpWindow:         XmMessageBox
               SymbolLabel:     XmLabelGadget
               MessageLabel:    XmLabelGadget
               Separator:       XmSeparatorGadget
               OK:      	XmPushButtonGadget
               Cancel:  	XmPushButtonGadget
               Help:    	XmPushButtonGadget

   !! color palet

   palet:			XmRowColumn
      color:			XmPushButton
@EOF
echo x - xce.1
cat > xce.1 << '@EOF'
.\";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.\"
.\" File:         template.man
.\" RCS:          $Header$
.\" Description:  man page template
.\" Author:	  
.\" Created:      
.\" Modified:
.\" Language:     Text
.\" Package:      
.\"
.\";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.TH XCE 1 "" "Underware"
.ad b

.SH NAME
xce \- color editor tool for X11/Motif

.SH SYNOPSIS
.br
\fBxce\fP [ \-toolkit_options ]

.SH DESCRIPTION
\fIxce\fP is a simple tool for experimenting with color combinations on
a window in real time.  When it comes up, a small screen is displayed
next to four sliders.  Three of the four sliders represent the primary
colors red, green, and blue.  By moving the sliders, one can adjust the
mix of primary colors in the small screen.  A lable displays the hex
representation of the current color, suitable for cut and paste into
application resource files.  The forth slider adjusts the intensity of
the current color buy causing the three primary color sliders to move
at the same time.

There is a button labeled `Window' in the right corner of the main
display.  When this button is pushed, the cursor changes to a cross
hair.  You then move the cursor over a window (or application) that
you'd like to edit and click the left mouse button.  A new window is
then created which will display a copy of the window you clicked on.
You can set them side-by-side for comparisons.  Also, another window
is created, called the palet, which contains buttons marked with the
different colors that make up the window you chose.

Now you may click on a button on the palet.  The small color edit
screen then changes to the same color as the button.  When the sliders
are moved now, they affect the small color edit window, the button on
the palet, and the corresponding color in the window image.  In this
manner, you can adjust and fiddle with application defaults from
now until doomsday!

.SH OPTIONS
\fIxce\fP understands all of the standard X toolkit options.  See
X(1) for details.

.SH FILES
.nf
.ta \w'/usr/local/bin/prog/config              'u
/usr/lib/X11/app-defaults/XCe		resource file for xce
.fi

.SH BUGS
This thing is pretty much hard-wired for 8-bit color displays 
with read/write colormaps.  Bad things will probably happen on
monochrome screens.

.SH AUTHOR
Andrew Peebles, Mips Computer Systems

@EOF
echo x - SetArg.c
cat > SetArg.c << '@EOF'
#include <stdio.h>
#include <X11/Xlib.h>
#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>

#include <varargs.h>

/*
 * Function SetArgs
 *
 * SetArgs fills an ArgList (an array of Args) with a given list of values.
 * The list of values is NULL terminated.
 *
 * SetArgs returns the number of arguments that were set.
 *
 * EXAMPLE USAGE:
 *
 * int n;
 * Arg args[10];
 *
 * n = SetArgs (args,
 *		XmNwidth, 10,
 *		XmNheight, 20,
 *		NULL);
 * XtSetValues (w, args, n);
 */

SetArgs(va_alist)
va_dcl
{
  va_list a;

  /* The first argument is the array to fill. */
  register ArgList this_arg;

  /* Others are name and value pairs. */
  String name;
  
  /* How many Args have we set? */
  int count = 0;
  
  va_start(a);
  this_arg = va_arg(a, ArgList);
  
  while ((name = va_arg(a, String)) != NULL)
    {
      XtSetArg(this_arg[count], name, va_arg(a, XtArgVal));    
      ++count;
    }
  
  va_end(a);
  return count;
}


@EOF
echo x - color_lib.c
cat > color_lib.c << '@EOF'
/***************************************************************************
 *
 * FILE NAME		: color_lib.c
 *
 * AUTHOR		: Andrew Peebles
 *
 * DESCRIPTION		: routines for handling color
 *
 * VERSIONS		: %W%
 *
 ***************************************************************************/

/*
 * standard includes
 */
#include <stdio.h>
#include <ctype.h>

#include <Xm/Xm.h>

extern Widget top;

XColor *
PixelToRGB (display, cm, pixel)
Display	*display;
Colormap cm;
unsigned long pixel;
{
  XColor *rgb = (XColor *) XtMalloc (sizeof(XColor));
  int	status;

  rgb->pixel = pixel;
  status = XQueryColor (display, cm, rgb);
  if (status == BadColor) {
    Warning (top, "XQueryColor: Bad Color");
    XtFree (rgb);
    return (NULL);
  }
  if (status == BadValue) {
    Warning (top, "XQueryColor: Bad Value");
    XtFree (rgb);
    return (NULL);
  }

  return (rgb);
}
  
@EOF
echo x - image.c
cat > image.c << '@EOF'
/***************************************************************************
 *
 * FILE NAME		: image.c
 *
 * AUTHOR		: Andrew Peebles
 *
 * DESCRIPTION		: Contains Xm routines for pixmap handling
 *
 * VERSIONS		: %W%
 *
 ***************************************************************************/

/*
 * standard includes
 */
#include <stdio.h>
#include <X11/Intrinsic.h>
#include <X11/IntrinsicP.h>
#include <Xm/Xm.h>
#include "image.h"

/*
 * Function:
 */
Boolean
CreateAndInstallPixmap (bits, width, height, name)
/*
 * Takes arguments from a bitmap include file, creates an image
 * from the data and stores it in the PIXMAP cache under name.
 * These pixmaps can then be retrieved with GetPixmap and used
 * for button labels, etc.
 */
char	*bits;
int	width, height;
char	*name;
{
    XImage *image;

    image = (XImage *) XtMalloc (sizeof (XImage));
    image->width = width;
    image->height = height;
    image->data = bits;
    image->depth = 1;
    image->xoffset = 0;
    image->format = XYBitmap;
    image->byte_order = LSBFirst;
    image->bitmap_unit = 8;
    image->bitmap_bit_order = LSBFirst;
    image->bitmap_pad = 8;
    image->bytes_per_line = (width+7)/8;

    return (XmInstallImage (image, name));
}

/*
 * Function:
 */
Pixmap
GetPixmap (w, name)
/*
 * Used to retrieve pixmaps stored in the PIXMAP cache.  Returns
 * a pixmap id.  Uses the pasted in widget to calculate the foreground
 * and background values of the pixmap.
 */
Widget	w;
char	*name;
{
  Pixmap	p;
  Arg		args[5];
  Pixel		f,b;

  XtSetArg (args[0], XmNforeground, &f);
  XtSetArg (args[1], XmNbackground, &b);
  XtGetValues (w, args, 2);
  p = XmGetPixmap (w->core.screen,
		   name,
		   f, b);
  return (p);
}

/*
 * Function:
 */
void
InstallDefaultPixmaps ()
/*
 * Install some default pixmaps in the PIXMAP cache.  These
 * are the dialog pixmaps used by the Motif dialog widget set.
 * They can be retrieved with the function GetPixmap with the
 * following names:
 *
 *	xm_error
 *	xm_warning
 *	xm_question
 *	xm_info
 *	xm_working
 */
{
  XImage	*image;

  CreateAndInstallPixmap (errorBits,
			  errorWidth,
			  errorHeight,
			  "xm_error");

  CreateAndInstallPixmap (infoBits,
			  infoWidth,
			  infoHeight,
			  "xm_info");

  CreateAndInstallPixmap (questionBits,
			  questionWidth,
			  questionHeight,
			  "xm_question");

  CreateAndInstallPixmap (warningBits,
			  warningWidth,
			  warningHeight,
			  "xm_warning");

  CreateAndInstallPixmap (workingBits,
			  workingWidth,
			  workingHeight,
			  "xm_working");

}

/*
 * Function:
 */
XImage *
MakeImage (width, height, data)
/*
 * takes arguments from a bitmap include file and returns an XImage
 * pointer to that data.
 */
int	width, height;
char	*data;
{
  XImage	*image;

      image = (XImage *) XtMalloc (sizeof (XImage));
      image->width = width;
      image->height = height;
      image->data = data;
      image->depth = 1;
      image->xoffset = 0;
      image->format = XYBitmap;
      image->byte_order = LSBFirst;
      image->bitmap_unit = 8;
      image->bitmap_bit_order = LSBFirst;
      image->bitmap_pad = 8;
      image->bytes_per_line = (width+7)/8;
      return (image);
}

@EOF
echo x - main.c
cat > main.c << '@EOF'
/***************************************************************************
 *
 * FILE NAME		: xce
 *
 * AUTHOR		: Andrew Peebles
 *
 * DESCRIPTION		: color edit program, an experiment in colormaps
 *
 * VERSIONS		: %W%
 *
 ***************************************************************************/

/*
 * standard includes
 */
#include <stdio.h>
#include <ctype.h>

#include "patchlevel.h"

#include <X11/Xatom.h>
#include <X11/cursorfont.h>
#include <Xm/mwm.h>
#include <Xm/Form.h>
#include <Xm/MessageB.h>
#include <Xm/Scale.h>
#include <Xm/PushB.h>
#include <Xm/Separator.h>
#include <Xm/Frame.h>
#include <Xm/Label.h>
#include <Xm/Text.h>
#include <Xm/DrawingA.h>
#include <Xm/RowColumn.h>
#include <Xm/ToggleB.h>
#include <X11/Shell.h>

#include "pix.h"

Widget	top,
        form,
        red, green, blue, intensity,
        frame,
        label,
        text,
        from_text, from_window,
        quit, rgbBtn,
        sep1,
        image_dialog,
        image_window,
        palet_dialog,
        palet_window;

static
XmStringCharSet char_set = (XmStringCharSet) XmSTRING_DEFAULT_CHARSET;

#define xmstr(str) XmStringCreateLtoR (str, char_set)

Display	*display;
XStandardColormap standard_colormap;
Colormap colormap;
int screen;
XColor *rgb, *PixelToRGB();
Pixel	pxs[5];
XImage *image = NULL;
GC gc = 0;
Pixel  *NewPixels = NULL;
int	ncolors;

main (argc, argv)
int	argc;
char	**argv;
{
  int status;
  Colormap *clist;

  top = XtInitialize ("main",
		      "XCe",
		      NULL,NULL,
		      &argc,argv);

  display = XtDisplay(top);
  screen = DefaultScreen(display);
  colormap = DefaultColormap (display,screen);

  CreateApplicationWidgets();

  CreateAndInstallPixmap (pix_bits,
			  pix_width, pix_height,
			  "pix");

  XtRealizeWidget (top);

  FixUp();

  XtMainLoop ();
}

FixUp()
/*
 * pin the sliders to the right side of the form for proper resizing
 */
{
  Arg	args[5];
  int	n;

  n = SetArgs (args,
	       XmNrightAttachment, XmATTACH_FORM,
	       NULL);
  XtSetValues (red, args, n);
  XtSetValues (green, args, n);
  XtSetValues (blue, args, n);
  XtSetValues (intensity, args, n);
}

CreateApplicationWidgets ()
/*
 * create the main screen
 */
{
  Arg	args[20];
  int	n;
  Pixel	pix_bg;
  char	rgb_value[80];
  void	drag_cb(), quit_cb(), window_cb(), help_cb();
  void  CreateRgbDialog();

  n = 0;
  form = XmCreateForm (top,
		       "form",
		       args, n);
  XtManageChild (form);

  n = SetArgs (args,
	       XmNtopAttachment, XmATTACH_FORM,
	       XmNleftAttachment, XmATTACH_FORM,
	       NULL);
  frame = XmCreateFrame (form,
			 "frame",
			 args, n);
  XtManageChild (frame);

  n = 0;
  label = XmCreateLabel (frame,
			 "pix",
			 args, n);
  XtManageChild (label);

  n = SetArgs (args,
	       XmNlabelType, XmPIXMAP,
	       XmNlabelPixmap, GetPixmap (label, "pix"),
	       NULL);
  XtSetValues (label, args, n);

  n = SetArgs (args,
	       XmNwidth, pix_width,
	       XmNheight, pix_height,
	       NULL);
  XtSetValues (frame, args, n);

/***/

  /*
   * get the pixel number from the object under test
   */
  n = SetArgs (args,
	       XmNbackground, &pix_bg,
	       NULL);
  XtGetValues (label, args, n);

  /*
   * obtain an XColor struct for that pixel in the default color map
   */
  rgb = PixelToRGB (display, colormap, pix_bg);

  /*
   * allocate some r/w cells in the default color map, return pixel
   * numbers to use
   */
  XAllocColorCells (display, colormap, False,
		    NULL, 0,
		    pxs, 1);

  /*
   * take our otherwise filled in XColor struct and set its pixel
   * number to one of our r/w cells
   */
  rgb->pixel = pxs[0];

  /*
   * make that pixel number the original objects color
   */
  XStoreColor(display,colormap,rgb);

  /*
   * change the objects pixel number to our new one, same color but
   * now we can change its color on the fly
   */
  n = SetArgs (args,
	       XmNbackground, pxs[0],
	       NULL);
  XtSetValues (label, args, n);

/***/

  n = SetArgs (args,
	       XmNtopAttachment, XmATTACH_FORM,
	       XmNleftAttachment, XmATTACH_WIDGET,
	       XmNleftWidget, frame,
	       XmNorientation, XmHORIZONTAL,
	       XmNmaximum, 255,
	       XmNvalue, (rgb->red>>8),
	       NULL);
  red = XmCreateScale (form,
		       "Red",
		       args, n);
  XtManageChild (red);

  n = SetArgs (args,
	       XmNtopAttachment, XmATTACH_WIDGET,
	       XmNtopWidget, red,
	       XmNleftAttachment, XmATTACH_WIDGET,
	       XmNleftWidget, frame,
	       XmNorientation, XmHORIZONTAL,
	       XmNmaximum, 255,
	       XmNvalue, (rgb->green>>8),
	       NULL);
  green = XmCreateScale (form,
		       "Green",
		       args, n);
  XtManageChild (green);

  n = SetArgs (args,
	       XmNtopAttachment, XmATTACH_WIDGET,
	       XmNtopWidget, green,
	       XmNleftAttachment, XmATTACH_WIDGET,
	       XmNleftWidget, frame,
	       XmNorientation, XmHORIZONTAL,
	       XmNmaximum, 255,
	       XmNvalue, (rgb->blue>>8),
	       NULL);
  blue = XmCreateScale (form,
		       "Blue",
		       args, n);
  XtManageChild (blue);

  n = SetArgs (args,
	       XmNtopAttachment, XmATTACH_WIDGET,
	       XmNtopWidget, blue,
	       XmNleftAttachment, XmATTACH_WIDGET,
	       XmNleftWidget, frame,
	       XmNorientation, XmHORIZONTAL,
	       XmNmaximum, 127,
	       XmNminimum, -127,
	       XmNvalue, 0,
	       NULL);
  intensity = XmCreateScale (form,
			     "Intensity",
			     args, n);
  XtManageChild (intensity);

  sprintf (rgb_value, "#%02x%02x%02x", 
	   (rgb->red>>8), 
	   (rgb->green>>8), 
	   (rgb->blue>>8));

  n = SetArgs (args,
	       XmNtopAttachment, XmATTACH_WIDGET,
	       XmNtopWidget, intensity,
	       XmNleftAttachment, XmATTACH_FORM,
	       XmNrightAttachment, XmATTACH_FORM,
	       
	       XmNeditMode, XmSINGLE_LINE_EDIT,
	       XmNeditable, False,
	       XmNvalue, rgb_value,
	       NULL);
  text = XmCreateText (form,
		       "entry",
		       args, n);
  XtManageChild (text);

  n = SetArgs (args,
	       XmNtopAttachment, XmATTACH_WIDGET,
	       XmNtopWidget, text,
	       XmNleftAttachment, XmATTACH_FORM,
	       NULL);
  quit = XmCreatePushButton (form,
			     "Quit",
			     args, n);
  XtManageChild (quit);

  n = SetArgs (args,
	       XmNtopAttachment, XmATTACH_WIDGET,
	       XmNtopWidget, text,
	       XmNrightAttachment, XmATTACH_FORM,
	       NULL);
  from_window = XmCreatePushButton (form,
				    "Window",
				    args, n);
  XtManageChild (from_window);

  n = SetArgs (args,
	       XmNtopAttachment, XmATTACH_WIDGET,
	       XmNtopWidget, text,
	       XmNrightAttachment, XmATTACH_WIDGET,
	       XmNrightWidget, from_window,
	       NULL);
  from_text = XmCreatePushButton (form,
				  "help",
				  args, n);
  XtManageChild (from_text);

  n = SetArgs (args,
	       XmNtopAttachment, XmATTACH_WIDGET,
	       XmNtopWidget, text,
	       XmNrightAttachment, XmATTACH_WIDGET,
	       XmNrightWidget, from_text,
	       NULL);
  rgbBtn = XmCreatePushButton (form,
			       "RGB",
			       args, n);
  XtManageChild (rgbBtn);


  XtAddCallback (red, XmNdragCallback, drag_cb, 0);
  XtAddCallback (red, XmNvalueChangedCallback, drag_cb, 0);
  XtAddCallback (green, XmNdragCallback, drag_cb, 1);
  XtAddCallback (green, XmNvalueChangedCallback, drag_cb, 1);
  XtAddCallback (blue, XmNdragCallback, drag_cb, 2);
  XtAddCallback (blue, XmNvalueChangedCallback, drag_cb, 2);
  
  XtAddCallback (intensity, XmNdragCallback, drag_cb, 3);
  XtAddCallback (intensity, XmNvalueChangedCallback, drag_cb, 3);

  XtAddCallback (quit, XmNactivateCallback, quit_cb, NULL);
  XtAddCallback (from_window, XmNactivateCallback, window_cb, NULL);
  XtAddCallback (from_text, XmNactivateCallback, help_cb, NULL);
  XtAddCallback (rgbBtn, XmNactivateCallback, CreateRgbDialog, NULL);
}

void
quit_cb (w, client, call)
Widget	w;
caddr_t	client, call;
{
  /*
   * We'll need to do some king of XFreeColors here ...
   */
  XFreeColors (display, colormap, pxs, 1, 8);
  if (NewPixels)
    XFreeColors (display, colormap, NewPixels, ncolors);
  if (image)
    XDestroyImage(image);
  exit(0);
}

int last_value = 0;
void
drag_cb (w, client, call)
Widget	w;
int	client;
XmScaleCallbackStruct *call;
{
  char	rgb_value[80];

  switch (client) {
  case 0:
    rgb->red = (unsigned short) (call->value<<8);
    XmScaleSetValue (intensity, 0);
    last_value = 0;
    break;
  case 1:
    rgb->green = (unsigned short) (call->value<<8);
    XmScaleSetValue (intensity, 0);
    last_value = 0;
    break;
  case 2:
    rgb->blue = (unsigned short) (call->value<<8);
    XmScaleSetValue (intensity, 0);
    last_value = 0;
    break;
  case 3:
    if (call->value > last_value) 
      call->value = 1;
    else if (call->value < last_value)
      call->value = -1;
    else
      call->value = 0;

    last_value += call->value;

    if ((int) (rgb->red>>8) + call->value > 0) {
      rgb->red = (rgb->red>>8) + call->value;
      if (rgb->red > 255) rgb->red = 255;
      rgb->red = rgb->red<<8;
    }
    else {
      rgb->red = 0;
    }
    XmScaleSetValue (red, rgb->red>>8);

    if ((int) (rgb->green>>8) + call->value > 0) {
      rgb->green = (rgb->green>>8) + call->value;
      if (rgb->green > 255) rgb->green = 255;
      rgb->green = rgb->green<<8;
    }
    else {
      rgb->green = 0;
    }
    XmScaleSetValue (green, rgb->green>>8);

    if ((int) (rgb->blue>>8) + call->value > 0) {
      rgb->blue = (rgb->blue>>8) + call->value;
      if (rgb->blue > 255) rgb->blue = 255;
      rgb->blue = rgb->blue<<8;
    }
    else {
      rgb->blue = 0;
    }
    XmScaleSetValue (blue, rgb->blue>>8);

    break;
  }
  XStoreColor (display, colormap, rgb);

  sprintf (rgb_value, "#%02x%02x%02x", 
	   (rgb->red>>8), 
	   (rgb->green>>8), 
	   (rgb->blue>>8));
  XmTextSetString (text, rgb_value);
}


void
window_cb(w, client, call)
Widget	w;
caddr_t	client, call;
{
  Arg	args[5];
  int	n;

  Window target_window, Select_Window();
  target_window = Select_Window (display);
  ObtainImage (display, target_window);

  /*
   * only allow this to happen once
   */
  n = SetArgs (args,
	       XmNsensitive, False,
	       NULL);
  XtSetValues (w, args, n);
}

ObtainImage (dpy, window)
/*
 * Some of this code comes from xwd and xwud.  Many thanks to those
 * authors.  I've removed most of the nice machine independent code
 * so this app is pretty much hard wired to 8 bit r/w colormap displays.
 */
Display	*dpy;
Window	window;
{
  XWindowAttributes win_info;
  int absx, absy, x, y;
  unsigned width, height;
  int dwidth, dheight;
  int bw;
  int nobdrs = True;
  int format = ZPixmap;
  Window new_window;
  GC gc;
  XGCValues values;
  XColor NewColors[256];
  Pixel  OldPixels[256];
  int	i,j;
  int	isize;

  XGetWindowAttributes(dpy, window, &win_info);
  absx = win_info.x + (nobdrs ? win_info.border_width : 0);
  absy = win_info.y + (nobdrs ? win_info.border_width : 0);
  width = win_info.width + (nobdrs ? 0 : (2 * win_info.border_width));
  height = win_info.height + (nobdrs ? 0 : (2 * win_info.border_width));
  dwidth = DisplayWidth (dpy, screen);
  dheight = DisplayHeight (dpy, screen);

  /* clip to window */
  if (absx < 0) width += absx, absx = 0;
  if (absy < 0) height += absy, absy = 0;
  if (absx + width > dwidth) width = dwidth - absx;
  if (absy + height > dheight) width = dheight - absy;

  bw = nobdrs ? 0 : win_info.border_width;
  x = absx - win_info.x - bw;
  y = absy - win_info.y - bw;
  image = XGetImage (dpy, window, x, y, width, height, AllPlanes, format);
  if (!image) {
    fprintf (stderr, "%s:  unable to get image at %dx%d+%d+%d\n",
	     "xce", width, height, x, y);
    exit (1);
  }
  
  /*
   * we got the image, now create a dialog window to display the
   * image and take care of exposures
   */
  CreateImageDialog();

  /*
   * now we're gonna create some r/w color cells.  March through
   * the pixel data and find all unique pixel values:
   */
  isize = Image_Size (image);

  ncolors = 0;
  for (i=0; i<isize; i++) {
    Boolean found = False;
    for (j=0; j<ncolors; j++) {
      if ((unsigned long) image->data[i] == NewColors[j].pixel) {
	found = True;
	break;
      }
    }
    if (!found) {
      OldPixels[ncolors] =
      NewColors[ncolors].pixel = (unsigned long) image->data[i];
      ++ncolors;
    }
  }

  /*
   * Query those new colors to get rgb values
   */
  XQueryColors (display, colormap, NewColors, ncolors);

  NewPixels = (Pixel *) XtMalloc (ncolors * sizeof(Pixel));
  XAllocColorCells (display, colormap, False, NULL, 0,
		    NewPixels, ncolors);
  for (i=0; i<ncolors; i++)
    NewColors[i].pixel = NewPixels[i];

  XStoreColors (display, colormap, NewColors, ncolors);

  /*
   * now change the pixel values in the image to point to our
   * new color map entries
   */
  for (i=0; i<isize; i++) {
    for (j=0; j<ncolors; j++) {
      if ((unsigned long) image->data[i] == OldPixels[j]) {
	image->data[i] = NewPixels[j];
	break;
      }
    }
  }

  /*
   * Now create a popup panel of colors for this image
   */
  CreatePalet (ncolors, NewPixels);

}

CreatePalet (num, pixvals)
/*
 * build the palet of unique colors for the image under test
 */
int num;
unsigned long pixvals[];
{
  Widget	shell, rc, tb;
  void		act_cb();
  Arg		args[15];
  int		n,i;

  n = SetArgs (args,
	       XmNdeleteResponse, XmUNMAP,
	       NULL);
  shell = XtAppCreateShell ("xce", "XCe",
			    applicationShellWidgetClass,
			    display, args, n);

/*  n=0;  */
  palet_dialog = XtCreatePopupShell ("color palet",
				     topLevelShellWidgetClass,
				     shell, args, n);
  n=0;
  rc = XmCreateRowColumn (palet_dialog,
			  "palet",
			  args, n);

  for (i=0; i<num; i++) {
    n=0;
    tb = XmCreatePushButton (rc,
			       "color",
			       args,n);
    XtManageChild(tb);
    n = SetArgs (args,
		 XmNlabelString, xmstr (""),
		 XmNwidth, pix_width,
		 XmNheight, pix_height,
		 NULL);
    XtSetValues (tb, args, n);
    n = SetArgs (args,
		 XmNbackground, pixvals[i],
		 NULL);
    XtSetValues (tb, args, n);
    XtAddCallback (tb, XmNactivateCallback, act_cb, pixvals[i]);
  }

  XtManageChild(rc);


  XtRealizeWidget (palet_dialog);
  XtPopup (palet_dialog, XtGrabNone);
}

void
act_cb (w, client, call)
/*
 * called when a user pushes a button on the palet
 */
Widget	w;
unsigned long client;
caddr_t call;
{
  Arg	args[5];
  int	n;
  char	rgb_value[80];

  n = SetArgs (args,
	       XmNbackground, client,
	       NULL);
  XtSetValues (label, args, n);

  rgb = PixelToRGB (display, colormap, client);
  rgb->pixel = client;

  XmScaleSetValue (red, (rgb->red>>8));
  XmScaleSetValue (blue, (rgb->blue>>8));
  XmScaleSetValue (green, (rgb->green>>8));
  XmScaleSetValue (intensity, 0);

  sprintf (rgb_value, "#%02x%02x%02x",
           (rgb->red>>8),
           (rgb->green>>8),
           (rgb->blue>>8));
  XmTextSetString (text, rgb_value);
}


Window 
Select_Window(dpy)
/*
 * again, from xwd.
 */
Display *dpy;
{
  int status;
  Cursor cursor;
  XEvent event;
  Window target_win = None;
  int buttons = 0;

  /* Make the target cursor */
  cursor = XCreateFontCursor(dpy, XC_crosshair);

  /* Grab the pointer using target cursor, letting it room all over */
  status = XGrabPointer(dpy, RootWindow(dpy, screen), False,
			ButtonPressMask|ButtonReleaseMask, GrabModeSync,
			GrabModeAsync, None, cursor, CurrentTime);
  if (status != GrabSuccess) {
    fprintf (stderr,"Can't grab the mouse.");
    return 0;
  }

  /* Let the user select a window... */
  while ((target_win == None) || (buttons != 0)) {
    /* allow one more event */
    XAllowEvents(dpy, SyncPointer, CurrentTime);
    XWindowEvent(dpy, RootWindow(dpy, screen),
		 ButtonPressMask|ButtonReleaseMask, &event);
    switch (event.type) {
    case ButtonPress:
      if (target_win == None) {
	target_win = event.xbutton.subwindow; /* window selected */
	if (target_win == None)
	  target_win = RootWindow(dpy, screen);
      }
      buttons++;
      break;
    case ButtonRelease:
      if (buttons > 0) /* there may have been some down before we started */
	buttons--;
       break;
    }
  } 

  XUngrabPointer(dpy, CurrentTime);      /* Done with pointer */
  XSync(display,False);
  return(target_win);
}


void image_expose_cb();
XtCallbackRec expose_cblist[] = {
  {image_expose_cb, NULL},
  {NULL, NULL}
};

CreateImageDialog()
/*
 * create a window for the image
 */
{
  Arg	args[15];
  int	n;

  Widget shell;

  shell = XtAppCreateShell ("xce","XCe",
			    applicationShellWidgetClass,
			    display, NULL, 0);

  n = 0;
  image_dialog = XtCreatePopupShell ("image",
				     topLevelShellWidgetClass,
				     shell, args, n);

  n = SetArgs (args,
	       XmNwidth, image->width,
	       XmNheight, image->height,
	       XmNexposeCallback, expose_cblist,
	       NULL);
  image_window = XmCreateDrawingArea (image_dialog,
				      "image",
				      args, n);
  XtManageChild (image_window);

  XtRealizeWidget (image_dialog);

  XtPopup (image_dialog, XtGrabNone);
}

void
image_expose_cb()
/*
 * handles redraws of the image
 */
{
  XGCValues values;

  if (!gc) {
    values.foreground = (unsigned long) BlackPixel (display, screen);
    values.background = (unsigned long) WhitePixel (display, screen);
    gc = XCreateGC (display, XtWindow(image_window), 
		    GCForeground|GCBackground, &values);
  }

  XPutImage (display, XtWindow(image_window), gc, image,
	     0,0,0,0,
	     image->width, image->height);
}

int Image_Size(image)
XImage *image;
{
  if (image->format != ZPixmap)
    return(image->bytes_per_line * image->height * image->depth);

  return(image->bytes_per_line * image->height);
}


static char help_message[] = "\
Welcome to Color Editor!\n\
\n\
The red, green, and blue labeled slider bars control the amount\n\
of those colors in the mix for the small screen displayed in the\n\
upper left corner.  The forth slider is used to ajust the intensity\n\
of the color displayed.  As the sliders are moved, the color of the screen\n\
changes according to the new vaules of the sliders.  A text string\n\
suitable for use in resources files is also displayed.\n\
\n\
The button labeled `rgb' will pop up a window which contains the default\n\
rgb database on your system.  You can choose colors from this table as a\n\
base for editing in the small color edit screen.\n\
\n\
You may edit the colors for an entire window.  Push the `Window' button\n\
and the cursor will change into cross hairs.  Move this cursor over a\n\
window you'd like to edit and click the left mouse button.  You will\n\
get a new window with the image of the first placed into it.  You will\n\
also get a palet of colors that make up the image.  Select a color and\n\
it will appear in the edit sceen, where it can be ajusted with the sliders.\n\
You may only do this once, since the color table is a limited resource.";

void
help_cb (w, client, call)
Widget	w;
caddr_t	client, call;
{
  Warning (w, help_message);
}

Warning (reference, message)
Widget  reference;
char    *message;
/*
 * post an error message
 */
{
  Widget        mbox;
  Widget        button;
  Arg           args[10];
  int           n;
  XmString      msg_string;

  msg_string = XmStringLtoRCreate (message, XmSTRING_DEFAULT_CHARSET);

  n=0;
  XtSetArg (args[n], XmNmessageString, msg_string); n++;
  XtSetArg (args[n], XmNdefaultPosition, True); n++;
  XtSetArg (args[n], XmNdialogTitle, XmStringCreateLtoR ("Simple Instructions",XmSTRING_DEFAULT_CHARSET)); n++;
  mbox = XmCreateWarningDialog (reference,
                              "helpWindow",
                              args,n);
  button = XmMessageBoxGetChild (mbox, XmDIALOG_CANCEL_BUTTON);
  XtUnmanageChild (button);
  button = XmMessageBoxGetChild (mbox, XmDIALOG_HELP_BUTTON);
  XtUnmanageChild (button);

  /*
   * bring it up
   */
  XtManageChild (mbox);
}

void
CreateRgbDialog ()
{
  Widget	rgb_dialog, rgb_window, rc, tb, shell;
  Arg	args[15];
  int	n;
  FILE	*fp, *fopen();
  unsigned long	r,g,b;
  unsigned long	lr,lg,lb;
  char	line[160];
  char	*tok;
  XColor rgb_color, tmp;
  void rgb_select_cb();

  shell = XtAppCreateShell ("xce", "XCe",
			    applicationShellWidgetClass,
                            display, NULL, 0);

  n = 0;
  rgb_dialog = XtCreatePopupShell ("rgb screen",
				   topLevelShellWidgetClass,
				   shell, args, n);
  
  n = SetArgs (args,
	       XmNradioAlwaysOne, True,
	       XmNradioBehavior, True,
	       NULL);
  rc = XmCreateRowColumn (rgb_dialog,
                          "rgb",
                          args, n);
  XtManageChild (rc);

  if ((fp = fopen ("/usr/lib/X11/rgb.txt","r")) == NULL) {
    Warning (top, "Can't open /usr/lib/X11/rgb.txt for input.");
    return;
  }

  lr = lb = lg = 0;

  while (fgets (line, 160, fp)) {
    tok = (char *) strtok (line," ");
    r = (unsigned long) strtol (tok, NULL, 10);
    tok = (char *) strtok (NULL," ");
    g = (unsigned long) strtol (tok, NULL, 10);
    tok = (char *) strtok (NULL," \t");
    b = (unsigned long) strtol (tok, NULL, 10);
    
    tok = (char *) strtok (NULL,"\n");
    if (tok[0] == '\t')
      ++tok;

    if ((r == lr) && (b == lb) && (g == lg))
      continue;

    if ((r == g) && (g == b)) {
      continue;
    }

    lr = r;
    lg = g;
    lb = b;

    if (!XLookupColor (display, colormap, tok, &tmp, &rgb_color))
      continue;

    if (!XAllocColor (display, colormap, &rgb_color))
      continue;

    /*
     * Got a unique color spec and name.  Create a button in the
     * row column to display it.
     */
    n = SetArgs (args,
		 XmNforeground, rgb_color.pixel,
		 XmNlabelString, xmstr (tok),
		 NULL);
    tb = XmCreateToggleButton (rc,
			       "rgbButton",
			       args, n);
    XtManageChild (tb);
    XtAddCallback (tb, XmNarmCallback, rgb_select_cb, rgb_color.pixel);
  }

  XtRealizeWidget (rgb_dialog);
  XtPopup (rgb_dialog, XtGrabNone);
}

void
rgb_select_cb (w, client, call)
Widget	w;
unsigned long client;
caddr_t call;
{
  XColor new_rgb_spec;
  char  rgb_value[80];

  new_rgb_spec.pixel = client;
  XQueryColor (display, colormap, &new_rgb_spec);

  rgb->red = new_rgb_spec.red;
  rgb->green = new_rgb_spec.green;
  rgb->blue = new_rgb_spec.blue;

  XStoreColor (display, colormap, rgb);

  XmScaleSetValue (red, (rgb->red>>8));
  XmScaleSetValue (blue, (rgb->blue>>8));
  XmScaleSetValue (green, (rgb->green>>8));
  XmScaleSetValue (intensity, 0);

  sprintf (rgb_value, "#%02x%02x%02x",
           (rgb->red>>8),
           (rgb->green>>8),
           (rgb->blue>>8));
  XmTextSetString (text, rgb_value);
}
@EOF
echo x - image.h
cat > image.h << '@EOF'
#define errorWidth  20
#define errorHeight 20
static char errorBits[] = {
   0x00, 0x00, 0x00, 0xc0, 0x0f, 0x00, 0xf0, 0x3a, 0x00, 0x58, 0x55, 0x00,
   0x2c, 0xa0, 0x00, 0x56, 0x40, 0x01, 0xaa, 0x80, 0x02, 0x46, 0x81, 0x01,
   0x8a, 0x82, 0x02, 0x06, 0x85, 0x01, 0x0a, 0x8a, 0x02, 0x06, 0x94, 0x01,
   0x0a, 0xe8, 0x02, 0x14, 0x50, 0x01, 0x28, 0xb0, 0x00, 0xd0, 0x5f, 0x00,
   0xa0, 0x2a, 0x00, 0x40, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

#define infoWidth  11 
#define infoHeight 24
static char infoBits[] = {
   0x00, 0x00, 0x78, 0x00, 0x54, 0x00, 0x2c, 0x00, 0x54, 0x00, 0x28, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x2a, 0x00, 0x5c, 0x00, 0x28, 0x00,
   0x58, 0x00, 0x28, 0x00, 0x58, 0x00, 0x28, 0x00, 0x58, 0x00, 0x28, 0x00,
   0x58, 0x00, 0xae, 0x01, 0x56, 0x01, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00};

#define questionWidth  13
#define questionHeight 22
static char questionBits[] = {
   0x00, 0x00, 0xf8, 0x01, 0xac, 0x02, 0x56, 0x05, 0x0a, 0x03, 0x06, 0x05,
   0x0a, 0x03, 0x80, 0x05, 0xc0, 0x02, 0x60, 0x01, 0xb0, 0x00, 0x50, 0x00,
   0xb0, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x50, 0x00,
   0xb0, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00};

#define warningWidth  9 
#define warningHeight 22
static char warningBits[] = {
   0x00, 0x00, 0x18, 0x00, 0x2c, 0x00, 0x56, 0x00, 0x2a, 0x00, 0x56, 0x00,
   0x2a, 0x00, 0x56, 0x00, 0x2c, 0x00, 0x14, 0x00, 0x2c, 0x00, 0x14, 0x00,
   0x2c, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x14, 0x00,
   0x2c, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00};

#define workingWidth  21
#define workingHeight 23
static char workingBits[] = {
   0x00, 0x00, 0x00, 0xfe, 0xff, 0x0f, 0xaa, 0xaa, 0x0a, 0x44, 0x55, 0x06,
   0xcc, 0x2a, 0x02, 0x44, 0x55, 0x06, 0xcc, 0x2a, 0x02, 0x84, 0x15, 0x06,
   0x8c, 0x2a, 0x02, 0x04, 0x15, 0x06, 0x0c, 0x0a, 0x02, 0x04, 0x06, 0x06,
   0x0c, 0x0b, 0x02, 0x84, 0x15, 0x06, 0xcc, 0x2a, 0x02, 0x44, 0x55, 0x06,
   0xcc, 0x2a, 0x02, 0x44, 0x55, 0x06, 0xcc, 0x2a, 0x02, 0x44, 0x55, 0x06,
   0xfe, 0xff, 0x0f, 0x56, 0x55, 0x05, 0x00, 0x00, 0x00};

@EOF
echo x - patchlevel.h
cat > patchlevel.h << '@EOF'
#define PATCHLEVEL 0
@EOF
echo x - pix.h
cat > pix.h << '@EOF'
#define pix_width 50
#define pix_height 50
static char pix_bits[] = {
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00};
@EOF

dan
----------------------------------------------------
O'Reilly && Associates   argv@sun.com / argv@ora.com
Opinions expressed reflect those of the author only.