[comp.windows.x] X11 colour example

erc@pai.UUCP (Eric Johnson) (08/15/89)

Awhile back, Pat Ryan asked for help with X11 colour, especially
to draw a line in colour. I can really sympathize--I know exactly
how Pat feels.  X11 colour seems very complex and the examples in
the official documentation leave something to be desired.

Below is a simple example X11 program to draw a line
in colour in a window.  Since I just got back from vacation, I
haven't had the time to test it on anything but a Sun386i.  It is not
intended to be a robust program, just an aid to new X programmers.
(I'm sure I will be flamed for any details missing or wrong. Since I just
wrote it this morning, I don't mind.  The goal, as always, is to 
help X users.)

I just used the Xlib library, so on Unix-like machines, you
can compile it with something like:

% cc -o colortest colortest.c -lX11

if you have your X11 system set up.


I Hope this helps,
-Eric


Eric F. Johnson, Prime Automation, Inc. 
415 W. Travelers Trail, Burnsville, MN 55337 USA.  Phone: +1 612-894-0313. 
erc@pai.mn.org    - or -   sun!tundra!pai!erc      - or -   bungia!pai!erc
(We have a very dumb mailer, so please send a bang-!-style return address.)


---


Pat originally asked:

>     	this is probably going to sound like a inane request but does
>anyone have a fairly simple working demo program using color through
>XWindows?  

It is definitely NOT an inane request.


>           i am using an HP 9000/370 running HP-UX v.6.2.  for those
>of us who are new to windows programming, the documentation is opaque
>to say the least.  the xwindows shelf over at the maryland book exchange
>is consistently empty so that hasn't helped me much.  i find a few
>correct lines of code are worth a thousand pages of documentation.
>basically i need to do things like draw a line from A to B in color
>X.

>thanks,

>pat
>pmr@bootes.gsfc.nasa.gov


-- 
>/patrick/ryan
>st. joseph's university, philadelphia, pennsylvania
>uucp          { bpa | burdvax | drexel | princeton} !sjuvax!ryan
>arpa/cs/bitnet  ryan@sjuvax.sju.edu, ryan%sjuvax.sju.edu@relay.cs.net


--------cut here--------cut here---------cut here---------cut here--------

/*
**	Simple colour program to draw a line in a given colour.
**	Runs on a Sun386i, under X11 R3 from MIT X Consortium.
**
**	E F Johnson
**	(c) Copyright 1989, Eric F. Johnson, All Rights Reserved.
**	Permission granted for non-commercial distribution. The 
**	program is intended for educational use only, and may
**	not work on your machine.  I offer NO guarantee that
**	this program will do anything. Use at your own risk!
**
**	This program shows a simple use of colour.  For
**	more information, see chapter 3 in
**	_X_Window_Applications_Programming_,
**	by Eric Johnson and Kevin Reichard,
**	MIS: Press, 1989, ISBN1-55828-016-2.
**	In the USA, you can dial 1-800-MANUALS.
**
**	This is intended to help new X programmers
**	learn more about the weird way in which X handles
**	colour.  It is NOT intended to be a perfect example.
**	It is NOT intended to be portable to all systems.
**	It works on one system here--the rest is up to you.	
**
**	This program:
**	1) Opens an X display connection.
**	2) Checks if there is more than 1 "colour"
**	plane available in the default visual (could
**	be grey-scale, though).
**	3) Opens a window on the display
**	4) Creates a GC for the window
**	5) Tries to get the closest match for
**	a given colour, from the X11 standard colour
**	name data base. The colour name is passed as
**	a command-line parameter.	
**	6) On Expose events: draws a line in the window in colour.
**	7) On a mouse button press event: quits.
*/

#include   <stdio.h>
#include   <X11/Xlib.h>
#include   <X11/Xutil.h>


main( argc, argv )

int	argc;
char	*argv[];

{
	char		colourName[ 120 ];
	Display		*theDisplay;
	int		theScreen;
	Window		theWindow;
	XSizeHints	theSizeHints;
	GC		theGC;
	Colormap	theColormap;
	XColor		theRGBColor, theHardColor;
	int		status;

	/*
	**	Check if a colour name
	**	was given on the command line
	*/
	if ( argc > 1 )
		{
		strcpy( colourName, argv[ 1 ] );
		}
	else
		{
		/* 
		**	Default colour
		*/
		strcpy( colourName, "LimeGreen" );
		}

	/*
	**	1) Open X display connection--assumes
	**	local display only for test.
	*/
	theDisplay = XOpenDisplay( (char *) NULL );

	if ( theDisplay == NULL )
		{
		fprintf( stderr, "Sorry, cannot open X display.\n" );
		exit( 1 );
		}

	/*
	**	2) Check for colours on default
	**	visual only.  You could walk the
	**	list of visuals.
	*/
	theScreen = DefaultScreen( theDisplay );

	if ( DefaultDepth( theDisplay, theScreen ) < 2 )
		{
		fprintf( stderr, "Sorry, no colour/grey planes.\n" );
		XCloseDisplay( theDisplay );
		exit( 1 );
		}

	/*
	**	3) Open a window
	*/
	theWindow = XCreateSimpleWindow( theDisplay,
			RootWindow( theDisplay, theScreen ),
			10, 10, 200, 200,
			2,
			BlackPixel( theDisplay, theScreen ),	
			WhitePixel( theDisplay, theScreen ) );

	/*
	**	Send hints to the Window Manager.
	**	We lie.
	*/
	theSizeHints.flags    = USPosition | USSize;
	theSizeHints.x        = 10;
	theSizeHints.y        = 10;
	theSizeHints.width    = 200;
	theSizeHints.height   = 200;

	XSetNormalHints( theDisplay, theWindow, &theSizeHints );

	/*
	**	4) Create a GC
	*/

	theGC = XCreateGC( theDisplay, theWindow,
			0L, (XGCValues *) NULL );


	/*
	**	Map the window
	*/
	XSelectInput( theDisplay, theWindow, ExposureMask | ButtonPressMask );
	XMapRaised( theDisplay, theWindow );


	/*
	**	5) Set up a colour 
	**	CHECK THE status RETURN VALUE!
	*/
	theColormap = DefaultColormap( theDisplay, theScreen );

	status = XLookupColor( theDisplay, theColormap,
			colourName, &theRGBColor,
			&theHardColor );

	/*
	**	Share if already exists, otherwise try
	**	to allocate.
	**	CHECK THE status RETURN VALUE!
	*/
	status = XAllocColor( theDisplay, theColormap,
			&theHardColor );

	XSetForeground( theDisplay, theGC, theHardColor.pixel );

	/*
	**	6) Loop on events
	*/
	while( eventLoop( theDisplay, theWindow, theGC ) == True );

	XFreeGC( theDisplay, theGC );
	XDestroyWindow( theDisplay, theWindow );
	XCloseDisplay( theDisplay );
	exit( 0 );
}

/* _____________________________________________________________________ */

eventLoop( theDisplay, theWindow, theGC )

Display	*theDisplay;
Window	theWindow;
GC	theGC;

{
	XEvent	theEvent;
	int	status = True;

	/*
	**	Wait for an event 
	*/
	XNextEvent( theDisplay, &theEvent );

	switch( theEvent.type )
		{
		case Expose:
			/* 
			**	6) On Expose events,
			**	draw a coloured line.
			*/
			XDrawLine( theDisplay,
				theWindow, theGC,
				0, 0, 100, 100 );
			XFlush( theDisplay );
			break;
		case ButtonPress:
			/*
			**	7) On a ButtonPress,
			**	Quit.
			*/
			status = False;
			break;
		}

	return( status );

}


/*
**	end of file
*/



-- 
Eric F. Johnson, Prime Automation, Inc. 
415 W. Travelers Trail, Burnsville, MN 55337 USA.  Phone: +1 612-894-0313. 
erc@pai.mn.org    - or -   sun!tundra!pai!erc      - or -   bungia!pai!erc
(We have a very dumb mailer, so please send a bang-!-style return address.)