[comp.sources.x] v06i048: XCol -- Color-Selector, Part02/02

hoenig@informatik.uni-kl.de (Helmut Hoenig) (03/23/90)

Submitted-by: Helmut Hoenig <hoenig@informatik.uni-kl.de>
Posting-number: Volume 6, Issue 48
Archive-name: xcol/part02



Please excuse me for typing in the wrong number of parts in the
Subject-entry of the first part of the posting. I recognized it
just when it was gone. This time it is correct. This is the second
and last part.

Helmut Hoenig
hoenig@informatik.uni-kl.de

----------------------------------------------------------------------
#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  xcol.part2 xcol.man README
# Wrapped by hoenig@popper on Wed Mar 21 16:47:56 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f xcol.part2 -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"xcol.part2\"
else
echo shar: Extracting \"xcol.part2\" \(36359 characters\)
sed "s/^X//" >xcol.part2 <<'END_OF_xcol.part2'
X/********************************************************************************
X *			    Textwindow-Functions				*
X ********************************************************************************/
X
X
Xvoid draw_message( num )
X	int	num;
X/* draws upper (0) or lower (1) message-entry */
X{
Xint	y;
X
X	y = (num)?(tw_lines+1)*char_height:0;
X
X	XClearArea( display, tw, 0, y, twidth, char_height, False );
X	XSetForeground( display, gc, white );
X	if (tw_message[num])
X	{	XSetFont( display, gc, tinfo->fid );
X		XDrawString( display, tw, gc, 
X			0, y+tinfo->ascent, 
X			tw_message[num], strlen( tw_message[num] ) );
X	}
X	if (num)	XDrawLine( display, tw, gc, 0, y, twidth, y );
X	else		XDrawLine( display, tw, gc, 0, char_height-1, twidth, char_height-1 );
X}
X
Xvoid set_message( msg, num )
X	char	*msg;
X	int	num;
X/* sets upper or lower message entry */
X{
X	if (tw_message[num])		free(tw_message[num]);
X	if (msg)
X	{	tw_message[num] = (char *)malloc((unsigned) strlen(msg)+1 );
X		strcpy( tw_message[num], msg );
X	}
X	else	tw_message[num]=NULL;
X
X	draw_message( num );
X}
X
Xvoid reset_messages()
X{
Xchar	mess[20];
X
X	if (act_offset)
X	{	sprintf( mess, "*** UP (%d) ***", act_offset);
X		set_message( mess, 0 );
X	}
X	else	set_message( "  click right button here to write file.", 0 );
X
X	if (act_offset+tw_lines<color_lines)
X	{	sprintf( mess, "*** DOWN (%d) ***", color_lines-act_offset-tw_lines);
X		set_message( mess, 1 );
X	}
X	else	set_message( (char *)NULL, 1 );
X}
X
Xvoid draw_string( i )
X	int	i;
X/* draws a color-line */
X{
Xint	j;
Xint	y;
Xint	p1,p2;
Xunsigned long	fg_pixel, bg_pixel, help;
X
X	j=i-act_offset;
X	if ((tw==(Window)0)||(j<0)||(j>=tw_lines))	return;
X
X	y=(j+1)*char_height;
X
X	fg_pixel = line[i].color->pixel;
X	if (fg_pixel==NotAllocated)
X	{	fprintf(stderr, "fg_pixel of %s not allocated.\n", line[i].line->contents);
X	}
X	bg_pixel = line[i].help->pixel;
X	if (bg_pixel==NotAllocated)
X	{	fprintf(stderr, "bg_pixel of %s not allocated.\n", line[i].line->contents);
X	}
X
X	if (line[i].reverse)
X	{	help     = fg_pixel;
X		fg_pixel = bg_pixel;
X		bg_pixel = help;
X	}
X
X/* clearing the background */
X	XSetForeground(display, gc, bg_pixel);
X	XFillRectangle( display, tw, gc, 0, y, twidth, char_height);
X
X	XSetFont( display, gc, tinfo->fid );
X	XSetForeground( display, gc, fg_pixel );
X
X	p1 = line[i].pos_in_line;
X	p2 = p1 + strlen( line[i].color->name );
X	p1 = XTextWidth( tinfo, line[i].line->contents, p1 )+2*char_width;
X	p2 = XTextWidth( tinfo, line[i].line->contents, p2 )+2*char_width;
X
X	XDrawString( display, tw, gc, 
X		2*char_width, y+tinfo->ascent, 
X		line[i].line->contents, strlen(line[i].line->contents)-1 );
X
X	XSetForeground( display, gc, fg_pixel );
X	XDrawLine( display, tw, gc, p1, y+char_height-2, p2, y+char_height-2 );	
X
X/* draws the pixmap (at least some planes of it) */
X	XSetState( display, gc, (unsigned long)AllPlanes, (unsigned long)0,
X				GXxor, fg_pixel^bg_pixel );
X	XCopyArea( display, grey_pixmap, tw, gc, 0, 0, char_width, char_height, twidth-3*char_width, y );
X	XSetState( display, gc, fg_pixel, bg_pixel,
X				GXcopy, (unsigned long)AllPlanes );
X	
X	if (i==act_line)
X	{	XDrawRectangle( display, tw, gc, 0, y, twidth-1, char_height-1);
X		XFillRectangle( display, tw, gc, 0, y, 2*char_width, char_height);
X		XFillRectangle( display, tw, gc, twidth-2*char_width, y, 2*char_width, char_height);
X		XSetForeground( display, gc, bg_pixel );
X	}
X	else	XSetForeground( display, gc, fg_pixel );
X
X/* drawing indicator 'bg', 'fg', or 'R' */
X	if (line[i].reverse)
X	{	if (line[i].assoc>=0)
X		{	XDrawString( display, tw, gc, 0, y+tinfo->ascent, "bg", 2 );
X		}
X		else
X		{	XSetForeground( display, gc, black );
X			XSetBackground( display, gc, white );
X			XDrawImageString( display, tw, gc, 0, y+tinfo->ascent, "R", 1 );
X		}
X	}
X	else
X	{	if (line[i].assoc>=0)
X			XDrawString( display, tw, gc, 0, y+tinfo->ascent, "fg", 2 );
X	}
X}
X
Xvoid change_color( act_line, new_color )
X	int		act_line;
X	ColorDef	*new_color;
X/* complete change of the color in the given line */
X{
X	if (act_line<0)	return;
X
X/* change the string */
X	string_exchange( &line[act_line], new_color );
X
X/* allocate the color */
X	exchange( &line[act_line].color, new_color );
X
X/* update the window (exchange corresponding color too) */
X	draw_string(act_line);
X	if (line[act_line].assoc>=0)
X	{	exchange( &line[line[act_line].assoc].help, new_color );
X		draw_string(line[act_line].assoc);
X	}
X}
X
Xint redraw_tw( l1, l2 )
X	int	l1, l2;
X/* redraws parts of the text-window */
X{
Xint	i;
X
X	if (l1==0)
X	{	draw_message( 0 );
X		l1++;
X	}
X	if (l2>tw_lines)
X	{	draw_message( 1 );
X		l2=tw_lines;
X	}
X	for (i=l1;i<=l2;i++)	draw_string( act_offset+i-1 );
X}
X
X/*----------------------------------------------------------------------------*/
X
Xvoid show_string( row, text )
X	int		row;
X	TextLine	*text;
X{
X	if (text)
X	{	XSetForeground( display, gc, white );
X		XFillRectangle( display, tw, gc, 0, row*char_height, twidth, char_height );
X		XSetForeground( display, gc, black );
X		XDrawString( display, tw, gc, 
X			2*char_width, row*char_height+tinfo->ascent, 
X			text->contents, strlen(text->contents) );
X	}
X	else
X	{	XSetForeground( display, gc, black );
X		XFillRectangle( display, tw, gc, 0, row*char_height, twidth, char_height );
X	}
X}
X
Xvoid show_text( i )
X	int	i;
X/* shows the part of the text, where line i occurred. The old contents of the
X * text-window is stored in a pixmap if possible.
X */
X{
XTextLine	*upper,*lower;
Xint		upper_i,lower_i;
XXEvent		event;
XPixmap		back;
X
X	back = XCreatePixmap( display, tw, twidth, (tw_lines+2)*char_height, DefaultDepthOfScreen(screen) );
X	if (back)
X	{	XCopyArea( display, tw, back, gc, 
X			0, 0, twidth, (tw_lines+2)*char_height, 
X			0, 0 );
X	}
X	
X	XGrabPointer(display, tw, False, 
X		ButtonPressMask|ButtonReleaseMask, GrabModeAsync, GrabModeAsync, 
X		tw, text_cursor, CurrentTime );
X	XSetFont( display, gc, tinfo->fid );
X
X	upper   = line[i].line;
X	upper_i = i-act_offset+1;
X	XSetForeground( display, gc, grey );
X	XFillRectangle( display, tw, gc, 0, upper_i*char_height, twidth, char_height );
X	XSetForeground( display, gc, black );
X	XDrawString( display, tw, gc, 
X		2*char_width, upper_i*char_height+tinfo->ascent, 
X		upper->contents, strlen(upper->contents) );
X
X	lower = upper;
X	upper = upper;
X	lower_i = upper_i + 1;
X	upper_i--;
X
X	while( ( upper_i>=0 )||(lower_i<=tw_lines+1) )
X	{	if ( upper_i>=0 )
X		{	if (upper)	upper=upper->previous;
X			show_string( upper_i--, upper );
X		}
X		if (lower_i<=tw_lines+1)
X		{	if (lower)	lower=lower->next;
X			show_string( lower_i++, lower );
X		}
X	}
X
X	XWindowEvent( display, tw, ButtonPressMask|ButtonReleaseMask, &event );
X
X	XUngrabPointer( display, CurrentTime );
X	if (back)
X	{	XCopyArea( display, back, tw, gc, 
X			0, 0, twidth, (tw_lines+2)*char_height, 
X			0, 0 );
X		XFreePixmap( display, back );
X	}
X	else	redraw_tw( 0, tw_lines+1 );
X}
X
X/*----------------------------------------------------------------------------*/
X
Xvoid write_quest( num )
X	int	num;
X/* waits for a confirmation before the file is written with backup. */
X{
XXEvent	event;
X
X	set_message( "  confirm writing with right button !", num );
X	XBell( display, 10 );
X
X	XGrabPointer(display, tw, False, 
X		ButtonPressMask|LeaveWindowMask, GrabModeAsync, GrabModeAsync, None, quest_cursor, CurrentTime );
X	XWindowEvent( display, tw, ButtonPressMask|LeaveWindowMask, &event );
X
X	if ((event.xany.type==ButtonPress)&&(event.xbutton.button==Button3))
X	{	char	back_name[MAXPATHLEN];
X
X		strcpy( back_name, file_name );
X		strcat( back_name, "~" );
X
X		if (rename( file_name, back_name ))
X		{	set_message("  can't create backup. writing aborted.", num);
X		}
X		else
X		{	if (write_file( file_name ))
X				set_message("  writing failed.", num);
X			else	set_message("  file written with backup.", num);
X		}
X	}
X	else set_message("  writing aborted.", num);
X
X	XUngrabPointer( display, CurrentTime );
X}
X
X/*----------------------------------------------------------------------------*/
X
Xvoid new_assoc( act )
X	int	act;
X/* the function waits, until the button is released or the mouse is moved
X * into an associated line. If both lines were already connected, they get
X * disconnected. If no line was connected, the first line will get the
X * foreground and the second line the background of the association.
X */
X{
XXEvent	event;
Xint	new;
X
X	if (line[act].assoc>=0)
X	{	set_message( "  move to associated line to disconnect.", 0 );
X	}
X	else	set_message( "  move to background to connect.", 0 );
X
X	XGrabPointer(display, tw, False, 
X		ButtonReleaseMask|PointerMotionMask, GrabModeAsync, GrabModeAsync, tw, updown_cursor, CurrentTime );
X
X	new = act;
X	do
X	{	XWindowEvent( display, tw, ButtonReleaseMask|PointerMotionMask, &event );
X		if (event.xany.type==MotionNotify)
X		{	new = (event.xmotion.y/char_height)+act_offset-1;
X			if (new!=act)	break;
X		}
X	}
X	while( event.xany.type!=ButtonRelease );
X
X	if (new==act)
X	{	if (line[act].assoc<0)
X		{	line[act].reverse^=1;
X		}
X		else
X		{	ColorDef	*help;
X
X			help = line[act].color;
X			change_color( act, line[line[act].assoc].color );
X			change_color( line[act].assoc, help );
X		}
X		reset_messages();
X	}
X	else
X	{	if (line[act].assoc<0)
X		{	if (line[new].assoc<0)
X			{	set_message( "  new association set.", 0 );
X				XBell( display, 5 );
X
X				line[act].assoc   = new;
X				exchange( &line[act].help, line[new].color );
X				line[act].reverse = 0;
X
X				line[new].assoc   = act;
X				exchange( &line[new].help, line[act].color );
X				line[new].reverse = 1;
X
X				draw_string( new );
X				draw_string( act );
X			}
X			else
X			{	set_message( "  line already connected.", 0 );
X				XBell( display, 10 );
X			}
X		}
X		else
X		{	if (line[act].assoc==new)
X			{	set_message( "  disconnected.", 0 );
X				XBell( display, 5 );
X				line[act].assoc = -1;
X				line[new].assoc = -1;
X				draw_string( new );
X				draw_string( act );
X			}
X			else
X			{	set_message( "  lines not associated.", 0 );
X				XBell( display, 10 );
X			}
X		}
X	}
X
X	while (event.xany.type!=ButtonRelease)
X	{	XWindowEvent( display, tw, ButtonReleaseMask, &event );
X	}
X	XUngrabPointer( display, CurrentTime );
X}
X
X/*----------------------------------------------------------------------------*/
X
Xvoid tw_event( event )
X	XEvent	*event;
X/* event-execution for the text-window */
X{
X    switch( event->xany.type )
X    {
X	case ConfigureNotify:
X	{	XEvent	help;
X		int	tw_new;
X	
X		tw_new = (event->xconfigure.height/char_height)-2;
X		if ((twidth==event->xconfigure.width)&&(tw_lines==tw_new))	break;
X
X		twidth   = event->xconfigure.width;
X		tw_lines = tw_new;
X
X		if (tw_lines>color_lines)	tw_lines=color_lines;
X		if (act_offset+tw_lines>color_lines)
X			act_offset = color_lines-tw_lines;
X
X		redraw_tw( 0, tw_lines+1 );
X		XSync(display, 0);
X		while( XCheckWindowEvent( display, tw, ExposureMask, &help ) );
X
X		break;
X	}
X
X	case KeyPress:
X	{	char	sign;
X		KeySym	keysym;
X
X	   	XLookupString(event, &sign, 1, &keysym, NULL);
X		if (sign=='q')	exit(0);
X		break;
X	}
X
X	case Expose:
X	{	XEvent	help;
X		int	first, first2;
X		int	last, last2;
X
X		first = event->xexpose.y/char_height;
X		last  = (event->xexpose.y + event->xexpose.height)/char_height+1;
X
X		while( XCheckWindowEvent( display, tw, ExposureMask, &help ) )
X		{	first2 = help.xexpose.y/char_height;
X			last2  = (help.xexpose.y + help.xexpose.height)/char_height+1;
X
X			if (first2 < first)	first = first2;
X			if (last2  > last)	last  = last2;
X		}
X		redraw_tw( first, last );
X		break;
X	}
X
X	case ButtonPress:
X	{	int	i;
X		int	old_act;
X		int	offset_delta;
X
X		i= (event->xbutton.y / char_height)-1;
X
X	/* has the header or footer of the textwindow been selected ? */
X		if (i<0)
X		{	if (event->xbutton.button==Button3)
X			{	write_quest(0);
X				return;
X			}
X			else if (act_offset)
X			{	offset_delta=(event->xbutton.button==Button1)?1:10;
X				if (act_offset-offset_delta<0)
X					offset_delta = act_offset;
X				act_offset -= offset_delta;
X				XCopyArea( display, tw, tw, gc,
X					0, char_height, twidth, (tw_lines-offset_delta)*char_height,
X					0, (offset_delta+1)*char_height );
X				redraw_tw( 1, offset_delta+1 );
X			}
X			else	XBell(display, 10);
X			break;
X		}
X		if (i>=tw_lines)
X		{	if (event->xbutton.button==Button3)
X			{	write_quest(1);
X				return;
X			}
X			else if (act_offset+tw_lines<color_lines)
X			{	offset_delta=(event->xbutton.button==Button1)?1:10;
X				if (act_offset+offset_delta>color_lines-tw_lines)
X					offset_delta = color_lines-act_offset-tw_lines;
X				act_offset += offset_delta;
X				XCopyArea( display, tw, tw, gc,
X					0, (offset_delta+1)*char_height,
X					twidth, (tw_lines-offset_delta)*char_height,
X					0, char_height );
X				redraw_tw( tw_lines-offset_delta+1, tw_lines );
X			}
X			else	XBell(display, 10);
X			break;
X		}
X		i+=act_offset;
X
X	/* action on a textline depending on the button */
X		switch(event->xbutton.button)
X		{
X		case Button2:
X			old_act  = act_line;
X			act_line = -1;
X			draw_string( old_act );
X			new_assoc( i );
X			act_line=i;
X			draw_string( act_line );
X			return;
X
X		case Button1:
X			old_act = act_line;
X			act_line = i;
X			draw_string( old_act );
X			draw_string( act_line );
X			break;
X
X		case Button3:
X			old_act = act_line;
X			act_line = i;
X			draw_string( old_act );
X			show_text( act_line );
X			draw_string( act_line );
X			break;
X
X		break;
X		}
X	} /* end case ButtonPress */
X    } /* end switch(type) */
X    reset_messages();
X}
X
X/*----------------------------------------------------------------------------*/
X
XWindow create_textwindow( fname )
X	char	*fname;
X{
XWindow			tw;
XXSizeHints		hints;
XXWMHints		normal_hints;
XXClassHint		class_hints;
X
Xstatic char *iname = "TextView";
Xchar	wname[MAXPATHLEN+10];
Xchar	*name_ptr;
X
X/* parsing the geometry */ 
X	hints.flags = PSize | PMaxSize | PMinSize | PResizeInc;
X
X	if (color_lines<4)	hints.min_height = (color_lines+2) * (char_height);
X	else			hints.min_height = 7 * (char_height);
X	hints.min_width = 20 * char_width;
X
X	if (color_lines>50)	tw_lines = 25;
X	else			tw_lines = color_lines;
X	hints.width = longest_colored+ 6 * char_width;
X	hints.height= (tw_lines+2) * (char_height);
X	act_offset = 0;
X
X	hints.max_height = (color_lines+2) * (char_height);
X	hints.max_width = 2*(longest_colored);
X
X	hints.width_inc  = char_width;
X	hints.height_inc = char_height;
X
X	twidth = hints.width;
X
X/* names */
X	name_ptr = rindex( fname, '/' );
X	if (name_ptr)	fname = name_ptr+1;
X
X	sprintf( wname, "TextView '%s'", fname );
X	name_ptr = wname;
X
X	tw = XCreateSimpleWindow( display, RootWindowOfScreen(screen), 
X		0, 0, hints.width, hints.height, 3, grey, black );
X
X/* class-hints */
X	class_hints.res_name = "xcol";
X	class_hints.res_class= "XCol";
X
X/* normal-hint */
X	normal_hints.flags = StateHint | WindowGroupHint;
X	
X	normal_hints.initial_state = NormalState;
X	normal_hints.window_group  = mw;
X
X#ifdef XTextProperty
X{	
XXTextProperty		window_name, icon_name;
X
X	XStringListToTextProperty( &name_ptr, 1, &window_name );
X	XStringListToTextProperty( &iname, 1, &icon_name );
X	
X	XSetWMProperties( display, tw, &window_name, &icon_name, (char **)0, 0, 
X				&hints, &normal_hints, &class_hints );
X
X	XFree( (char *)window_name.value );
X	XFree( (char *)icon_name.value );
X}
X#else
X	XSetStandardProperties( display, tw, name_ptr, iname, None, (char **)0, 0, &hints );
X	XSetNormalHints( display, tw, &normal_hints );
X	XSetClassHint( display, tw, &class_hints );
X#endif
X
X	XSelectInput( display, tw, 
X		ExposureMask | ButtonPressMask | StructureNotifyMask |
X		KeyPressMask | EnterWindowMask | LeaveWindowMask );
X	XDefineCursor( display, tw, tw_cursor );
X	XMapRaised( display, tw );
X	return( tw );
X}
X
X
X/********************************************************************************
X *			    Subwindow-Functions					*
X ********************************************************************************/
X
X
Xvoid destroy_subwindow( i )
X	int	i;
X/* destroys the tiny subwindow and its associated colors */
X{
XColorDef	*act;
X
X	act  = color[i];
X	while( act->associated )
X	{	act = act->associated;
X		unload_color( act );
X	}
X	XDestroyWindow( display, subw );
X}
X
Xvoid create_subwindow( i )
X	int	i;
X/* creates, maps and draws a tiny information-window for the given color */
X{
XXSetWindowAttributes    attrib;
Xint	x, y;
Xint	subs;
Xint	j;
XColorDef	*shades[MAX_COLS];
XColorDef	*act;
Xint	bord=6;
X
X/* what associated color should be shown ? */
X	act = color[i];
X	subs = 0;
X	shades[subs++] = act;
X	while( act->associated )
X	{	act = act->associated;
X		shades[subs++]=act;
X	}
X	if (subs>gran+1)
X	{	for (j=0;j<(gran);j++)
X		{	shades[j+1]= shades[1+(j*(subs-2))/(gran-1)];
X		}
X		subs=gran+1;
X	}
X	for (j=0;j<subs;j++)		load_color( shades[j] );
X	
X/* compute size */
X	sdx = XTextWidth( finfo, color[i]->name, strlen(color[i]->name) )+4;
X	sdy = finfo->ascent + finfo->descent+2;
X	if (subs>1)
X	{	int	palette_width=8;
X
X		sdy += 14;
X		if (sdx<(subs*palette_width))
X		{	do
X			{	sdx=subs*palette_width;
X				palette_width--;
X			}
X			while( (sdx+2*bord>dx)&&(palette_width>3) );
X		}
X		subcols = subs;
X	}
X	else
X	{	subcols = subs = 0;
X	}
X
X/* compute position */
X	if (color[i]->x < dx/2)		x = color[i]->x + BO;
X	else				x = color[i]->x -BO -(2*bord) -sdx;
X	if (x+sdx+(2*bord)>dx)		x = dx - sdx - (2*bord);
X	if (x<0)			x=0;
X
X	if (color[i]->y < dy/2)		y = color[i]->y + BO;
X	else				y = color[i]->y -BO -(2*bord) -sdy;
X
X/* create, map and draw */
X	subw = XCreateSimpleWindow( display, mw, x, y, sdx, sdy, bord, color[i]->pixel, black );
X	attrib.save_under = True;
X	XChangeWindowAttributes( display, subw, CWSaveUnder, &attrib );
X	XMapRaised( display, subw );
X
X	XSetFont( display, gc, finfo->fid );
X	XSetForeground( display, gc, white );
X	XSetBackground( display, gc, black );
X	XDrawImageString( display, subw, gc, 
X				(sdx-XTextWidth( finfo, color[i]->name, strlen(color[i]->name)))>>1, 
X				finfo->ascent, color[i]->name, strlen( color[i]->name ) );
X	if (subs)
X	{	for (j=0;j<subs;j++)
X		{
X			XSetForeground( display, gc, shades[j]->pixel );
X			XFillRectangle( display, subw, gc, 2+j*(sdx-2)/subs, sdy-12, (j+1)*(sdx-2)/subs-(2+j*(sdx-2)/subs), 10);
X		}
X	}
X}
X
X/*----------------------------------------------------------------------------*/
X
X/* LittleBox draws 2 rectangles around a color-field of the subwindow */
X#define	LittleBox(col)							\
X	XDrawRectangle( display, subw, gc, 				\
X		1+col*(sdx-2)/subcols, sdy-13, 				\
X		(col+1)*(sdx-2)/subcols-(2+col*(sdx-2)/subcols)+1, 11);	\
X	XDrawRectangle( display, subw, gc, 				\
X		1+col*(sdx-2)/subcols-1, sdy-13-1, 			\
X		(col+1)*(sdx-2)/subcols-(2+col*(sdx-2)/subcols)+1+2, 11+2)
X
X
Xvoid sub_select( line_index, i, help_color )
X	int	line_index, i, help_color;
X/* select a sub-color */
X{
XColorDef *shades[MAX_COLS];
XColorDef *act;
Xint	subs, j;
XXEvent	event;
Xint	col_index;	/* current index to the shades-field */
Xint	old_col_index;	/* last index to the shades-field */
X
X/* collect shades (shades[0] is used for the old value of the color) */
X	if (help_color)		shades[0] = line[line_index].help;
X	else			shades[0] = line[line_index].color;
X
X	act = color[i];
X	subs = 1;
X	shades[subs++] = act;
X	while( act->associated )
X	{	act = act->associated;
X		shades[subs++]=act;
X	}
X
X	if (subs>gran+1)
X	{	for (j=0;j<(gran);j++)
X		{	shades[j+2]= shades[2+(j*(subs-3))/(gran-1)];
X		}
X	}
X
X/* first exchange of the color */
X	col_index = 0;
X	if (help_color)
X	{	exchange( &line[line_index].help, shades[col_index+1] );
X		draw_string( line_index );
X	}
X	else	change_color( line_index, shades[col_index+1] );
X
X/* if there are no associated colors, the selection is done */
X	if (subs<=2)	return;
X
X	col_index=0;
X	old_col_index=0;
X	XSetForeground( display, gc, white );
X	LittleBox( col_index );
X
X/* warp the pointer to the main color of the subwindow */
X	XWarpPointer( display, None, subw, 0, 0,  0, 0, ((sdx/subcols)>>1)+2, sdy-7 );
X	XGrabPointer(display, subw, False, 
X		ButtonPressMask | ButtonReleaseMask | PointerMotionMask, 
X		GrabModeAsync, GrabModeAsync, 
X		subw, subsel_cursor, CurrentTime );
X
X	do
X	{	XWindowEvent( display, subw, ButtonPressMask | ButtonReleaseMask | PointerMotionMask, &event );
X		if (event.xany.type!=ButtonRelease)
X		{
X			if (event.xany.type==MotionNotify)
X			{	while(XCheckMaskEvent(display, PointerMotionMask, &event));
X
X				col_index = (event.xmotion.x-1)*subcols/(sdx-2);
X				if (col_index<0)	col_index=0;
X				if (col_index>=subcols)	col_index=subcols-1;
X
X				if ((event.xmotion.y<sdy-13)||(event.xmotion.y>sdy-2))
X				{	col_index = -1;
X				}
X			}
X			else		col_index = -1;	/* another ButtonPress == abort */
X
X			if (old_col_index!=col_index)
X			{	if (old_col_index>=0)
X				{	XSetForeground( display, gc, black );
X					LittleBox( old_col_index );
X				}
X				if (col_index>=0)
X				{	XSetForeground( display, gc, white );
X					LittleBox( col_index );
X				}
X				old_col_index = col_index;
X				if (help_color)
X				{	exchange( &line[line_index].help, shades[col_index+1] );
X					draw_string( line_index );
X				}
X				else	change_color( line_index, shades[col_index+1] );
X			}
X		}
X	}
X	while( event.xany.type==MotionNotify );
X
X	XUngrabPointer(display, CurrentTime);
X	XSetForeground( display, gc, black );
X	LittleBox( old_col_index );
X/* warp pointer back to its former position */
X	XWarpPointer( display, None, mw, 0, 0, 0, 0, shades[1]->x, shades[1]->y );
X/*	XSync(display, 1);	*/
X}
X
X
X/********************************************************************************
X *			    main-window-functions				*
X ********************************************************************************/
X
X
Xint act_color( x, y )
X	int	x, y;
X/* queries the next color in range of the mouse-pointer */
X{
Xint i;
Xint min_dist;
Xint min_i;
Xint dx1, dy1;
X
X	min_dist = dy*dy+dx*dx;
X
X	for (i=0;i<color_number;i++)
X	{	dx1 = abs(color[i]->x-x);
X		dy1 = abs(color[i]->y-y);
X
X		if (dx1*dx1+dy1*dy1<min_dist)
X		{	min_dist = dx1*dx1+dy1*dy1;
X			min_i = i;
X		}
X	}
X	if (min_dist<(BO)*(BO))
X		return(min_i);
X	else
X		return(-1);
X}
X
X/*----------------------------------------------------------------------------*/
X	
X#define	XPos(r, g, b)	( (BO>>1)+2+					\
X			  ( (reverse)	? (127+(255-r)-((255-b)>>1))	\
X			  		: (127+r-((b)>>1))		\
X			  ) * (dx-BO-4)/384				\
X			)
X#define	YPos(r, g, b)	( (BO>>1)+2+					\
X			  ( (reverse)	? (g+((255-b)>>1))		\
X			  		: ((255-g)+(b>>1))		\
X			  ) * (dy-BO-4)/384				\
X			)
X
Xvoid redraw_window()
X/* redraws the cube and the color-boxes in the main window */
X{
Xint i, j, op;
Xint ex[8], ey[8];
Xint dummy;
XWindow	root;
X
X	XGetGeometry( display, mw, &root, &dummy, &dummy, &dx, &dy, &dummy, &dummy );
X	if (BO_def)
X		BO = BO_def;
X	else
X	{	BO = (dx/50);
X		if ((dy/50)>BO)	BO=(dy/50);
X	}
X	XClearWindow( display, mw );
X
X/* draw the cube */
X	XSetForeground( display, gc, white );
X	for (i=0;i<8;i++)
X	{	ex[i] = XPos( ((i&1)?255:0), ((i&2)?255:0), ((i&4)?255:0) );
X		ey[i] = YPos( ((i&1)?255:0), ((i&2)?255:0), ((i&4)?255:0) );
X	}
X	for (i=0;i<8;i++)
X	{	for (j=0;j<3;j++)
X		{	op = i^(1<<j);
X			if (op<i);
X				XDrawLine(display, mw, gc, ex[i], ey[i], ex[op], ey[op]);
X		}
X	}
X
X/* draw the boxes */
X	for (i=0;i<color_number;i++)
X	{
X		color[i]->x = XPos(color[i]->r, color[i]->g, color[i]->b);
X		color[i]->y = YPos(color[i]->r, color[i]->g, color[i]->b);
X
X		XSetForeground( display, gc, color[i]->pixel );
X		XFillRectangle( display, mw, gc, 
X			color[i]->x-(BO>>1), color[i]->y-(BO>>1), BO, BO);
X	}
X	XFlush(display);
X}
X
X/*----------------------------------------------------------------------------*/
X
Xmw_event( event )
X	XEvent	*event;
X{
Xstatic int new_i;
Xstatic int old_i= -1;
X
X    switch( event->xany.type )
X    {
X    case Expose:
X    		while(XCheckWindowEvent( display, mw, ExposureMask, event ));
X
X    		if (event->xexpose.count==0)	redraw_window();
X    		break;
X
X    case MotionNotify:
X    		while( XCheckWindowEvent( display, mw, PointerMotionMask, event ) );
X		new_i = act_color( event->xmotion.x, event->xmotion.y );
X		if ((old_i!=new_i)&&(old_i>=0))
X		{	destroy_subwindow(old_i);
X			old_i = -1;
X		}
X		if (old_i!=new_i)
X		{	create_subwindow(new_i);
X			old_i = new_i;
X		}
X    		break;
X
X    case EnterNotify:
X    	update_map();
X    	break;
X
X    case LeaveNotify:
X    	if (old_i>=0)
X    	{	destroy_subwindow(old_i);
X    		old_i = -1;
X    	}
X    	break;
X
X    case ButtonPress:
X        switch (event->xbutton.button)
X    	{
X    	    case Button1:
X    	    {	if ((tw)&&(old_i>=0))
X		{	sub_select( act_line, old_i, 0 );
X		}
X		else
X		{	if (old_i>=0)
X			{	sub_select( 0, old_i, 0 );
X				XStoreBytes( display, line[0].color->name, strlen(line[0].color->name) );
X				XBell(display, 10);
X			}
X		}
X		break;	/* end switch(button) */
X	    }
X
X	    case Button2:
X	    {	if ((tw)&&(act_line>=0)&&(old_i>=0))
X		{	if (line[act_line].assoc<0)
X				sub_select( act_line, old_i, 1 );
X			else	sub_select( line[act_line].assoc, old_i, 0 );
X		}
X		break;	/* end switch(button) */
X	    }
X
X	    case Button3:
X	    {	ColorDef	*act;
X		char		*short_name;
X		char		*name;
X		char		name_copy[30];
X		int		name_length;
X
X		name = short_name = NULL;
X
X		if ((tw)&&(act_line>=0))
X		{	short_name = cut_digits( line[act_line].color->name );
X		}
X		else
X		{	if (tw==(Window)0)
X			{	name = XFetchBytes( display, &name_length );
X				if (name_length<28)
X				{	strncpy( name_copy, name, name_length );
X					name_copy[ name_length ] = '\0';
X					short_name = cut_digits( name );
X				}
X				XFree( name );
X			}
X		}
X		if (short_name)
X		{	act = find_color( short_name );
X			if (act)
X			XWarpPointer( display, None, mw, 0, 0,  0, 0, 
X				XPos( act->r, act->g, act->b ), 	YPos( act->r, act->g, act->b ) );
X		}
X		if (name)	XFree(name);
X
X		break;	/* end switch(button) */
X	    }
X	break;	/* end switch(type) */
X    	}
X
X    case KeyPress:
X	{	char	sign;
X		KeySym	keysym;
X
X	   	XLookupString(event, &sign, 1, &keysym, NULL);
X		if (sign=='q')	exit(0);
X		break;
X	}
X    }
X}
X
X/*----------------------------------------------------------------------------*/
X
Xvoid create_mainwindow( argc, argv, geometry )
X	int	argc;
X	char	**argv;
X	char	*geometry;
X{
Xint			x, y;
Xint			result;
XXSizeHints		hints;
XXWMHints		normal_hints;
XXClassHint		class_hints;
Xstatic char *window_string = "ColorView";
Xstatic char *icon_string   = "ColorView";
X
X/* parsing the geometry */ 
X	if (geometry)
X		result = XParseGeometry( geometry, &x, &y, &dx, &dy );
X	else	result = 0;
X
X	hints.flags = PAspect | PMinSize | PMaxSize;
X	hints.min_width = hints.min_height = 100;
X	hints.max_width = hints.max_height = HeightOfScreen(screen);
X
X	hints.min_aspect.x = 1;	hints.min_aspect.y = 1;
X	hints.max_aspect.x = 1;	hints.max_aspect.y = 1;
X
X	if ((result&XValue)&&(result&YValue))
X	{	hints.x = x;
X		hints.y = y;
X		hints.flags |= USPosition;
X	}
X	else
X	{	x=0;
X		y=0;
X	}
X	if ((result&WidthValue)&&(result&HeightValue))
X	{	hints.width  = dx;
X		hints.height = dy;
X		hints.flags |= USSize;
X	}
X	else
X	{	hints.width  = dx = HeightOfScreen(screen)/3;
X		hints.height = dy = HeightOfScreen(screen)/3;
X		hints.flags |= PSize;
X	}
X
X	mw = XCreateSimpleWindow( display, RootWindowOfScreen(screen), 
X		x, y, dx, dy, 3, WhitePixelOfScreen(screen), BlackPixelOfScreen(screen) );
X
X/* class-hints */
X	class_hints.res_name = "xcol";
X	class_hints.res_class= "XCol";
X
X/* normal-hint */
X	normal_hints.flags = StateHint | WindowGroupHint;
X	normal_hints.initial_state = NormalState;
X	normal_hints.window_group  = mw;
X
X#ifdef XTextProperty
X{	
XXTextProperty		window_name, icon_name;
X
X	XStringListToTextProperty( &window_string, 1, &window_name );
X	XStringListToTextProperty( &icon_string, 1, &icon_name );
X	
X	XSetWMProperties( display, mw, &window_name, &icon_name, argv, argc, 
X				&hints, &normal_hints, &class_hints );
X
X	XFree( (char *)window_name.value );
X	XFree( (char *)icon_name.value );
X}
X#else
X	XSetStandardProperties( display, mw, window_string, icon_string, None, argv, argc, &hints );
X	XSetNormalHints( display, mw, &normal_hints );
X	XSetClassHint( display, mw, &class_hints );
X#endif
X}
X
X
X/********************************************************************************
X *			initialization and helps				*
X ********************************************************************************/
X
X
Xvoid help()
X{
Xprintf("ColorView:\n");
Xprintf("\tThe colors of the rgb.txt-file of the server can be selected\n");
Xprintf("\tin this window. The Colors are sorted by their RGB-values. Colors\n");
Xprintf("\twith different intensity, but equal names, are grouped together.\n");
Xprintf("\n");
Xprintf("\t\tButton1:\tselect color for active line.\n");
Xprintf("\t\tButton2:\tselect help-color for active line.\n");
Xprintf("\t\tButton3:\twarp to color of active line.\n");
Xprintf("\t\t'q':\t\tquit the program.\n");
Xprintf("\n");
Xprintf("TextView:\n");
Xprintf("\tAll appearances of color-names in a textfile are collected and\n");
Xprintf("\tdisplayed in this window. For each line, the color and an additional\n");
Xprintf("\thelp-color can be set.\n");
Xprintf("\n");
Xprintf("in textline:\tButton1:\tselect line as active line.\n");
Xprintf("\t\tButton2:\ttoggle reverse-mode / make association\n");
Xprintf("\t\tButton3:\tshow line in textfile.\n");
Xprintf("\n");
Xprintf("in header or footer:\n");
Xprintf("\t\tButton1 (Button2):\tscroll by 1 (10), if possible.\n");
Xprintf("\t\tButton3:\twrite file with backup (after confirmation).\n");
X}
X
Xvoid usage()
X{
X	printf("usage:\txcol [options]\n\n");
X	printf("options:\n");
X	printf("\t<name>\t\tname of the textfile to be edited.\n");
X	printf("\t-rv\t\tcolor-positions are reversed in the cube.\n");
X	printf("\t-b<n>\t\tsize of color blocks is set to constant <n>.\n");
X	printf("\t-gran<n>\tsets maximum number of associated colors to <n>.\n");
X	printf("\t-dark<n>\tsets the percentage of the intensity of other colors.\n");
X
X	printf("\t-strings\tnames of colors in the file are only recognized\n");
X	printf("\t\t\twhen used in a string (useful for C-Sources).\n");
X
X	printf("\t+<char_list>\tadd characters to list of 'space'-letters.\n" );
X
X	printf("\t-case\t\tconvert color-strings to correct case.\n");
X	printf("\t-help\t\tprint some instructions (usage of buttons).\n");
X	printf("\t-file <name>\tname of a different 'rgb.txt'-file.\n");
X
X	printf("\n");
X	printf("\t-display <display_name>\n");
X	printf("\t-geometry <geometry>\n");
X	exit(0);
X}
X
X/*----------------------------------------------------------------------------*/
X
Xmain( argc, argv )
X	int	argc;
X	char	**argv;
X{
Xint		disparg=0;
Xchar		*geometry=NULL;
Xchar		linebuffer[80];	/* buffer for lines of the color-file */
X
Xchar		*name;
XColorDef	act;
X
XFILE		*fp;
Xchar		*rgb_file;
Xint		i, l;
XXEvent		event;
X
Xint		last;
X
X	file_name = NULL;
X	rgb_file  = NULL;
X
X	set_default_spaces();
X
X/* parse some parameters */
X	for (i=1;i<argc;i++)
X	{	if (strcmp(argv[i], "-display")==0)      disparg = ++i;
X		else if (strcmp(argv[i], "-geometry")==0) geometry= argv[++i];
X		else if (strcmp(argv[i], "-file")==0)	rgb_file = argv[++i];
X		else if (strcmp(argv[i], "-rv")==0)	reverse = 1;
X		else if (strncmp(argv[i], "-b", 2)==0)	BO_def = atoi(&argv[i][2]);
X		else if (argv[i][0]=='+')
X		{	l = strlen(argv[i]);
X			while(l-->1)	space_char[argv[i][l]]=1;
X		}
X		else if (strncmp(argv[i], "-gran", 5)==0)
X		{	gran = atoi(&argv[i][5]);
X			if (gran==0)	gran=11;
X		}
X		else if (strncmp(argv[i], "-dark", 5)==0)
X		{	darkness = atoi(&argv[i][5]);
X			if (darkness>100)	darkness=100;
X		}
X		else if (strcmp(argv[i], "-help")==0)		help();
X		else if (strcmp(argv[i], "-case")==0)		original=1;
X		else if (strcmp(argv[i], "-strings")==0)
X		{	memset( space_char, 0, sizeof(space_char) );
X			space_char['"'] = 1;
X		}
X		else if (argv[i][0]=='-')	usage();
X		else file_name = argv[i];
X	}
X
X	if ((display = XOpenDisplay( (disparg>0)?argv[disparg]:NULL ))==NULL)
X	{	fprintf(stderr, "*** can't open display. ***\n");
X		exit(0);
X	}
X	screen = ScreenOfDisplay(display, DefaultScreen(display));
X	cells  = CellsOfScreen(screen);
X
X	if (cells<256)
X	{	fprintf(stderr, "You don't have enough color-cells to use this program.\n" );
X		exit(0);
X	}
X	if (cells>MAX_CELLS)
X	{	fprintf(stderr, "There are many color-cells on your screen.\n" );
X		cells=MAX_CELLS;
X	}
X
X/* load textfonts */
X	finfo = XLoadQueryFont(display, COLOR_FONT );
X	tinfo = XLoadQueryFont(display, TEXT_FONT );
X	char_height = tinfo->descent + tinfo->ascent;
X	char_width = tinfo->max_bounds.rbearing + tinfo->min_bounds.lbearing;
X
X/* load the file with colors */
X	if (rgb_file)	fp = fopen( rgb_file, "r" );
X	else		fp = fopen( RGB_FILE, "r" );
X
X	if (fp==NULL)
X	{	fprintf( stderr, "unable to load the 'rgb.txt'-file.\n" );
X		exit(0);
X	}
X	color_number=0;
X	load_standard( &std_black );
X	load_standard( &std_white );
X	load_standard( &std_grey  );
X
X	while (fgets( linebuffer, sizeof linebuffer, fp )!=NULL)
X	{	int n;
X
X		linebuffer[strlen(linebuffer)-1]='\0';
X
X		n = sscanf(linebuffer, "%d %d %d", 
X			&act.r, &act.g, &act.b);
X
X		if (n==3)
X		{	name = linebuffer;
X			while( !isalpha(*name) )	name++;
X
X			act.name = (char *)malloc((unsigned)strlen(name)+1);
X			strcpy(act.name, name);
X			new_color( &act );
X		}
X	}
X	fclose( fp );
X
X/* sort the colors */
X	if (reverse)
X		qsort( (char *)color, color_number, sizeof(ColorDef *), color_sort_r );
X	else	qsort( (char *)color, color_number, sizeof(ColorDef *), color_sort );
X
X	for (i=0;i<color_number;i++)
X	{	ColorDef	*act;
X
X		brother_sort( &color[i] );
X		act = color[i];
X		while( act )
X		{	associated_sort( act );
X			act = act->brother;
X		};
X	}
X
X/* collect the color-names */
X	color_names = 0;
X	for (i=0;i<color_number;i++)
X	{	ColorDef	*act, *assoc;
X
X		act = color[i];
X		if (act->pixel==Undefined)
X		{
X	/* if the unindexed name is not defined, the first associated
X	 * entry of its list is copied onto it.
X	 */
X			assoc = act->associated;
X			memcpy( (char *)act, (char *)assoc, sizeof(ColorDef) );
X			free( (char *)assoc );
X		}
X
X		do
X		{	next_name( act );
X			assoc = act->associated;
X			while( assoc )
X			{	next_name( assoc );
X				assoc = assoc->associated;
X			}
X			act = act->brother;
X		}
X		while (act);
X	}
X	qsort( (char *)cname, color_names, sizeof(ColorString), color_name_sort );
X	last = 0;
X	first[0] = &cname[0];
X	for (i=0;i<color_names;i++)
X	{	if (cname[i].name[0]!=last)
X		{	do
X			{	last++;
X				first[last] = &cname[i];
X			}
X			while( cname[i].name[0]!=last );
X		}
X	}
X	while( last<255 )
X	{	last++;
X		first[last] = &cname[i];
X	}
X
X/* initializing XWindow stuff */
X	grey_pixmap = XCreatePixmapFromBitmapData( display, RootWindowOfScreen(screen), 
X			grey_bits, grey_width, grey_height, AllPlanes, 0, DefaultDepthOfScreen(screen) );
X	gc = XCreateGC( display, RootWindowOfScreen(screen), (long)0, NULL);
X	XCopyGC(display, DefaultGCOfScreen(screen), (long)-1, gc);
X	XSetGraphicsExposures( display, gc, False );
X
X	create_mainwindow( argc, argv, geometry );
X	create_new_map();
X	XSetWindowColormap( display, mw, my_map );
X	XSetWindowBackground( display, mw, black );
X	XSetWindowBorder( display, mw, grey );
X	
X	mw_cursor     = XCreateFontCursor( display, XC_top_left_arrow );
X	tw_cursor     = mw_cursor;
X	subsel_cursor = mw_cursor;
X	text_cursor   = XCreateFontCursor( display, XC_middlebutton );
X	quest_cursor  = mw_cursor;
X	updown_cursor = XCreateFontCursor( display, XC_sb_v_double_arrow );
X
X#ifdef RECOLOR_CURSOR
X/* the cursor have to get the pixel-values of my colormap
X * not working the way i expected. i don't think it's my fault.
X * only in the main-, not in the text-window, the colors are correct.
X */
X {	ColorDef *fg, *bg;	/* Cursor Foreground/Background */
X	XColor	 xfg, xbg;
X
X	bg = find_color( "LightGoldenrod" );
X	fg = find_color( "MidnightBlue" );
X	load_color( bg );
X	load_color( fg );
X	xbg.pixel = bg->pixel;
X	xfg.pixel = fg->pixel;
X	XQueryColor( display, my_map, &xbg );
X	XQueryColor( display, my_map, &xfg );
X
X	XRecolorCursor( display, mw_cursor, 	&xfg, &xbg );
X	XRecolorCursor( display, text_cursor, 	&xfg, &xbg );
X	XRecolorCursor( display, updown_cursor, &xfg, &xbg );
X }
X#endif
X
X	XDefineCursor( display, mw, mw_cursor );
X	XSelectInput( display, mw, 
X		ExposureMask | PointerMotionMask |
X		ButtonPressMask | LeaveWindowMask | EnterWindowMask |
X		KeyPressMask );
X
X	XMapRaised( display, mw );
X	XSync( display, 0 );
X	redraw_window();
X
X/* loading the file */
X	back_def = find_color( GREY_STRING );
X
X	if (file_name)
X	{
X		if (load_file( file_name ))
X		{	if (color_lines>0)
X			{	find_assocs();
X				tw = create_textwindow( file_name );
X				load_text_colors();
X				if (only_mine)
X				{	XSetWindowColormap( display, tw, my_map );
X				}
X			}
X			else
X				printf("no colors found in your file.\n");
X		};
X	}
X	else
X	{	loaded_text = (TextLine *)malloc( (unsigned)sizeof(TextLine) );
X		loaded_text->next = loaded_text->previous = NULL;
X		loaded_text->contents = (char *)malloc( 6 );
X		strcpy( loaded_text->contents, "white" );
X
X		line[0].line		= loaded_text;
X		line[0].color		= find_color( WHITE_STRING );
X		line[0].help		= find_color( BLACK_STRING );
X		line[0].reverse		= 0;
X		line[0].pos_in_line	= 0;
X		line[0].assoc		= -1;
X
X		color_lines = 1;
X	}
X
X	do
X	{	XNextEvent( display, &event );
X		if (event.xany.window==mw)
X		{	mw_event( &event );
X		}
X		else
X		{	tw_event( &event );
X		}
X	}
X	while(1);	
X}
X
X
END_OF_xcol.part2
if test 36359 -ne `wc -c <xcol.part2`; then
    echo shar: \"xcol.part2\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f xcol.man -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"xcol.man\"
else
echo shar: Extracting \"xcol.man\" \(3400 characters\)
sed "s/^X//" >xcol.man <<'END_OF_xcol.man'
X.TH xcol 1 "5 March 1990" "X Version 11"
X.SH NAME
Xxcol \- change color-entries in textfiles
X.SH SYNOPSIS
X.B xcol
X[-options ...]
X[\fIfilename\fP]
X.SH DESCRIPTION
X.I XCol
Xdisplays the colors defined in the \fIrgb.txt\fP-file of the XServer.
XThe colors are sorted by their names and their RGB-values and shown
Xin a cube in the \fIColorView\fP-Window (The positions represent the RGB-values).
XSince there usually are
Xmore colors defined in the file than cells in the colormap, entries with
Xthe same name but different RGB-values for different intensities, are
Xgrouped together.
X.PP
XIf a filename is given as a parameter, all occurrences of color-names in that
Xfile are shown in an additional \fITextView\fP-Window. To change the colors,
Xa text-line has to be made active. Afterwards a new color
Xcan be selected in the ColorView-Window. To get a better
Ximpression of the color, a help-color (background) can be selected for each
Xtext-line. If 2 lines define a foreground and a background color, an
Xassociation can be made and the colors of both lines can be selected together.
X.SH "BUTTONS"
Xin \fIColorView\fP-Window
X.RS
X.TP 8
X.B left:
Xselect color for the active line.
X.PD 0
X.IP middle:
Xselect help-color for the active line.
X.IP right:
Xwarp pointer to color of active line.
X.PD 1
X.RE
X.PP
Xin \fITextView\fP-Window
X.RS
X.TP 8
X.B left:
Xselect line as active line.
X.PD 0
X.IP middle:
Xtoggle reverse-mode or
X.IP
Xconnect/disconnect 2 lines.
X.IP right:
Xshow line in the textfile.
X.PD 1
X.RE
X.SH OPTIONS
X.TP 8
X.B -rv
XColor-positions are reversed in the cube. Some new colors can become visible
Xin the area of the very bright colors.
X.TP
X.B -b<n>
XThe size of color blocks is set to the constant <n>. By default, it
Xdepends on the size of the ColorView-Window.
X.TP
X.B -gran<n>
XThe maximum number of associated colors is set to <n>. By default, this value
Xis 11. (You can see the effect when reaching the grey-field, where
X101 associated entries are possibly available.)
X.TP
X.B -dark<n>
XThe percentage of the intensity of other colors can be set (default: 50). It
Xis easier to select a color, if the screen is darkened a little bit.
X.TP
X.B +<char_list>
Xadd characters to list of 'space'-chars. The color-string in the textfile
Xhas to occur between 2 'space'-chars to be recognized. By default, these
Xletters are ' ', '\\t', '\\n', ':', '"'.
X.TP
X.B -strings
XNames of colors in the file are only recognized when used in a string
X(useful for C-Sources). This means that the list of 'space'-chars is
Xset to '"' only.
X.TP
X.B -case
XAll occurrences of color-names in wrong case are replaced by the color-name
Xof the 'rgb.txt'-file.
X.TP
X.B -help
Xprint some instructions (usage of buttons).
X.TP
X.B -file <name>
Xname of a different 'rgb.txt'-file.
X.SH FILES
X/usr/lib/X11/rgb.txt
X.SH "SEE ALSO"
XX(1)
X.SH BUGS
XActually I wanted the program to work with the selection
Xmechanism used in xterm (when no textfile is given), but it seems to be
Xtoo complicated to use it here.
XSo, the current version always stores the string of the color in CUT_BUFFER0.
XIf anyone has an easy way to use the correct selection mechanism, please
Xinform me.
X.SH COPYRIGHT
XCopyright 1990, University of Kaiserslautern.
X.PP
XAuthor: Helmut Hoenig (hoenig@informatik.uni-kl.de)
X.PP
XPermission to use, copy, modify, and distribute this
Xsoftware for any purpose and without
Xfee is hereby granted, provided that the above copyright
Xnotice appear in all copies.
END_OF_xcol.man
if test 3400 -ne `wc -c <xcol.man`; then
    echo shar: \"xcol.man\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f README -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"README\"
else
echo shar: Extracting \"README\" \(646 characters\)
sed "s/^X//" >README <<'END_OF_README'
XXCol is a program to edit occurrences of color-names in text-files
X(i.e. the '.twmrc'-file). It shows the available colors and you can
Xchange the textfile by selecting new colors with the mouse.
X
XEven without editing a textfile, it gives you a good impression
Xof the available colors (the colors defined in the 'rgb.txt'-file
Xof the server).
X
XUse make to build the program. As there is only one
XSource-Modul you can also use 'cc xcol.c -lX11 -o xcol'.
X
XThe program runs on X11R4. It should run on X11R3 too, but I
Xalready had some small problems with the created colormap.
XA manual page is included.
X
Xby Helmut Hoenig
Xhoenig@informatik.uni-kl.de
END_OF_README
if test 646 -ne `wc -c <README`; then
    echo shar: \"README\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of shell archive.
# additional concatenation of splitted file
if test -f xcol.part1 ; then 
  echo '      concatenation of "xcol.part1" and "xcol.part2" to "xcol.c".'
  cat xcol.part1 xcol.part2 > xcol.c
  echo '      removing "xcol.part1" and "xcol.part2".'
  rm xcol.part1 xcol.part2
else
  echo '      unpack the first part now.'
fi
exit 0

dan
-----------------------------------------------------------
		    O'Reilly && Associates
		argv@sun.com / argv@ora.com
	   632 Petaluma Ave, Sebastopol, CA 95472 
     800-338-NUTS, in CA: 800-533-NUTS, FAX 707-829-0104
    Opinions expressed reflect those of the author only.