
/* 



  Program Two
  Bert Nelson
  Copyright 1992 Bert Nelson 
 
  Purpose:  Draw a triangle with different line styles and widths
            Draw a colored Rectangle
            Draw a filled Octagon
            Draw a Circle
            Draw a Pie Chart with a different pattern in each slice
            Draw a series of colored arcs to get a "rainbow" effect
 
 
  Compile Instructions:  cc file.c -lX11 -lm -o file
 
  Run Instructions:  type 'file' after compiling and click a button
                     on the mouse to draw (or redraw) the figures
 
 

   Permission to use, copy, modify, and distribute this software and its
   documentation for any purpose and without fee is hereby granted,
   provided that the above copyright notice appear in all copies and that
   both that copyright notice and this permission notice appear in
   supporting documentation.  It is provided "as is" without any express or
   implied warranty.

   Bert Nelson DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
   ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
   Bert Nelson BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
   ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
   WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
   ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
   SOFTWARE.


*/


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

#define PI 3.141592654
#define stipple_width 16
#define stipple_height 16

char hello[] = "Program Two - by Bert Nelson";
char hi[]    = "Hi!";
char tri_str[] = "Triangle";
char rect_str[] = "Rectangle";
char oct_str[] = "Octagon";
char circ_str[] = "Circle";
char sect_str[] = "Sectors";
char arcs_str[] = "Arcs";
Font font;
static char *ncolors[9] = { 
	" ", "blue","red","green4",
	"chocolate4","gold1","firebrick",
	"magenta1","DarkOrchid4"};

unsigned long fore,back;

Colormap color_map;
XColor colors[8];
XColor exact_colors[8];

Pixmap stipple_pixmap1;
Pixmap stipple_pixmap2;
Pixmap stipple_pixmap3;
Pixmap stipple_pixmap4;
Pixmap stipple_pixmap5;
Pixmap stipple_pixmap6;
Pixmap stipple_pixmap7;



main(argc,argv)
int argc;
char **argv;
{
	Display *mydisplay;
	Window  mywindow;
	GC mygc;
	XEvent myevent;
	KeySym mykey;
	XSizeHints myhint;

	int myscreen;
	unsigned long myforeground, mybackground;
	int i;
	char text[10];
	int done;



	mydisplay = XOpenDisplay("");

	myscreen = DefaultScreen (mydisplay);
	back = mybackground = WhitePixel (mydisplay, myscreen);
	fore = myforeground = BlackPixel (mydisplay, myscreen);

	myhint.x = 0;
	myhint.y = 0;

	myhint.width = 630;
	myhint.height = 425;
	myhint.flags = PPosition | PSize;
	mywindow = XCreateSimpleWindow (mydisplay,
	    DefaultRootWindow (mydisplay),
	    myhint.x, myhint.y, myhint.width, myhint.height,
	    5, myforeground, mybackground);

	XSetStandardProperties (mydisplay, mywindow, hello, hello,
	    None, argv, argc, &myhint);

	mygc = XCreateGC (mydisplay, mywindow, 0, 0);


	font = XLoadFont(mydisplay,"8x16");
	XSetFont(mydisplay,mygc,font);


	XSetBackground (mydisplay, mygc, mybackground);
	XSetForeground (mydisplay, mygc, myforeground);

	XSelectInput (mydisplay, mywindow,
	    ButtonPressMask | KeyPressMask | ExposureMask);

	XMapRaised (mydisplay, mywindow);

	color_set_up(mydisplay);


	done = 0;
	while (done == 0) {
		XNextEvent (mydisplay, &myevent );
		switch (myevent.type) {

		case Expose:
			if (myevent.xexpose.count == 0)

				break;


		case MappingNotify:
			XRefreshKeyboardMapping (&myevent);
			break;

		case ButtonPress:

			triangle(mydisplay,mywindow,mygc);
			rect(mydisplay,mywindow,mygc);
			oct(mydisplay,mywindow,mygc);
			circ(mydisplay,mywindow,mygc);
			sectors(mydisplay,mywindow,mygc);
			arcs(mydisplay,mywindow,mygc);
			
			break;


		case KeyPress:
			i = XLookupString (&myevent, text, 10, &mykey, 0);
			if (i == 1 && text[0] == 'q')
				done = 1;
			break;


		} /* switch */


	} /* while (done == 0) */

	XFreeGC (mydisplay, mygc);
	XDestroyWindow (mydisplay, mywindow);
	XCloseDisplay (mydisplay);

	exit(0);

} /* main */


/* Draw a Triangle */

triangle(the_display,the_window,the_gc)
Display *the_display;
Drawable the_window;
GC the_gc;

{

	XPoint points[4] ;


	points[0].x = 100;
	points[0].y = 100;
	points[1].x = 50;
	points[1].y = 200;
	points[2].x = 150;
	points[2].y = 200;
	points[3].x = 100;
	points[3].y = 100;


	XSetLineAttributes(the_display,the_gc,1,LineSolid,CapButt,JoinMiter);

	XDrawLine(the_display,the_window,the_gc,100,100,50,200);

	XSetLineAttributes(the_display,the_gc,3,
		LineOnOffDash,CapButt,JoinMiter);

	XDrawLine(the_display,the_window,the_gc,50,200,150,200);

	XSetLineAttributes(the_display,the_gc,5,
		LineDoubleDash,CapButt,JoinMiter);

	XDrawLine(the_display,the_window,the_gc,150,200,100,100);

	XDrawImageString(the_display,the_window,the_gc,70,220,
	    tri_str,strlen(tri_str));

	/* reset back to normal line atrributes */

	XSetLineAttributes(the_display,the_gc,0,LineSolid,CapButt,JoinMiter);

}


/* Draw a blue rectangle */


rect(the_display,the_window,the_gc)


Display *the_display;
Drawable the_window;
GC the_gc;
{

	XSetForeground(the_display,the_gc,colors[1].pixel);
	XDrawRectangle(the_display,the_window,the_gc,225,100,150,100);
	reset_colors(the_display,the_gc);

	XDrawImageString(the_display,the_window,the_gc,265,85,                
	    rect_str,strlen(rect_str));
}


/* Draw a filled octagon that is red */


oct(the_display,the_window,the_gc)


Display *the_display;
Drawable the_window;
GC the_gc;

{

	XPoint points[9];

	points[0].x = 517;
	points[0].y = 100;
	points[1].x = 550;
	points[1].y = 133;
	points[2].x = 550;
	points[2].y = 166;
	points[3].x = 516;
	points[3].y = 200;
	points[4].x = 484;
	points[4].y = 200;
	points[5].x = 450;
	points[5].y = 166;
	points[6].x = 450;
	points[6].y = 133;
	points[7].x = 483;
	points[7].y = 100;
	points[8].x = 516;
	points[8].y = 100;

	XSetForeground(the_display,the_gc,colors[2].pixel);


	XDrawLines(the_display,the_window,the_gc,points,9,CoordModeOrigin);

	XFillPolygon(the_display,the_window,the_gc,points,
		9,Convex,CoordModeOrigin);
	reset_colors(the_display,the_gc);

	XDrawImageString(the_display,the_window,the_gc,470,85,
	    oct_str,strlen(oct_str));


}

/* Draw a circle */


circ(the_display,the_window,the_gc)

Display *the_display;
Drawable the_window;
GC the_gc;

{

	XDrawArc(the_display,the_window,the_gc,50,300,100,100,0,360*64);

	XDrawImageString(the_display,the_window,the_gc,75,358,
	    circ_str,strlen(circ_str));

}

/* Draw a pie chart */


sectors(the_display,the_window,the_gc)

Display *the_display;
Drawable the_window;
GC the_gc;

{

	int i;
	double x;
	double y;
	int index=0;
	int degrees[13];
	int degrees2[13];
	XPoint points[2];

	degrees[0] = 0;
	degrees[1] = 20;
	degrees[2] = 25;
	degrees[3] = 85;
	degrees[4] = 90;
	degrees[5] = 175;
	degrees[6] = 180;
	degrees[7] = 215;
	degrees[8] = 220;
	degrees[9] = 295;
	degrees[10] = 300;
	degrees[11] = 355;
	degrees[12] = 0;

	points[0].x = 300;
	points[0].y = 350;



	for( i=0; i<12; i++)

	{

		

		x = cos(degrees[i] * (PI/180)) * 50;
		y = sin(degrees[i] * (PI/180)) * 50;
		y = -1.0 * y;


		points[1].x = x + 300;
		points[1].y = y + 350;


		if (i == 0 || (i%2) == 0)
		{

			index++;

			change_stipple(the_display,the_window,the_gc);

			XSetForeground(the_display,the_gc,colors[index].pixel);


			XDrawArc(the_display,the_window,the_gc,
			    250,300,100,100,degrees[i] * 64,
				(degrees[i+1] - degrees[i])*64);

			XFillArc(the_display,the_window,the_gc,
			    250,300,100,100,degrees[i] * 64, 
				(degrees[i+1] - degrees[i])*64);

		}



		XDrawLines(the_display,the_window,the_gc,
			points,2,CoordModeOrigin);

	} /* end for loop */

	reset_colors(the_display,the_gc);

	XDrawImageString(the_display,the_window,the_gc,275,285,sect_str,
	    strlen(sect_str));


}

/* Draw four arcs; each one being a different color */


arcs(the_display,the_window,the_gc)

Display *the_display;
Drawable the_window;
GC the_gc;

{

	XSetStipple(the_display,the_gc,stipple_pixmap7);


	XSetForeground(the_display,the_gc,colors[1].pixel);

	XDrawArc(the_display,the_window,the_gc,460,350,100,100,0,180*64);

	XSetForeground(the_display,the_gc,colors[6].pixel );

	XDrawArc(the_display,the_window,the_gc,470,360,80,80,0,180*64);

	XSetForeground(the_display,the_gc,colors[2].pixel);

	XDrawArc(the_display,the_window,the_gc,480,370,60,60,0,180*64);

	XSetForeground(the_display,the_gc,colors[5].pixel);

	XDrawArc(the_display,the_window,the_gc,490,380,40,40,0,180*64);

	reset_colors(the_display,the_gc);

	XDrawImageString(the_display,the_window,the_gc,
	    490,340,arcs_str,strlen(arcs_str)+1);


}


/* set up colors */

color_set_up(the_display)

Display *the_display;

{

	int i;

	color_map = DefaultColormap(the_display,0);


	for (i=1; i<9; i++)
	{

		XAllocNamedColor(the_display,color_map,
			ncolors[i],&exact_colors[i],
		    	&colors[i]);

	}

}

reset_colors(display,gc)

Display *display;
GC gc;


{

	XSetForeground(display,gc,fore);

}

/* change stipple pattern */

change_stipple(the_display,the_window,the_gc)

Display *the_display;
Window the_window;
GC the_gc;

{


	/* set up stipple patterns in Hexadecimal */


	static char stipple_bits1[] = {


		0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
		0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff,
		0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
		0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff	};

	static char stipple_bits2[] = {

		0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
		0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
		0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
		0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 	};

	static char stipple_bits3[] = {

		0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
		0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
		0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
		0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03 	};


	static char stipple_bits4[] = {

		0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff,
		0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff,
		0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff,
		0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff 	};


	static char stipple_bits5[] = {

		0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
		0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
		0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
		0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99 	};


	static char stipple_bits6[] = {

		0x02, 0x02, 0xff, 0xff, 0x02, 0x02, 0xff, 0xff, 0x02, 0x02,
		0xff, 0xff, 0x02, 0x02, 0xff, 0xff, 0x02, 0x02, 0xff, 0xff,
		0x02, 0x02, 0xff, 0xff, 0x02, 0x02, 0xff, 0xff, 0x02, 0x02,
		0xff, 0xff, 0x02, 0x02, 0xff, 0xff, 0x02, 0x02, 0xff, 0xff 	};

	static char stipple_bits7[] = {

		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff 	};


	static int i=0;


	i++;


	if (i > 6)
		i = 0;

	stipple_pixmap7 = XCreateBitmapFromData(the_display, 
	    the_window,stipple_bits7,stipple_width,stipple_height);

	/* for each time this function is called create a different
		stipple pattern */



	if (i == 1)

	{

		stipple_pixmap1 = XCreateBitmapFromData(the_display,    
		    the_window,stipple_bits1,stipple_width,stipple_height);

		XSetStipple(the_display,the_gc,stipple_pixmap1);

	}


	if (i == 2)

	{

		stipple_pixmap2 = XCreateBitmapFromData(the_display,
		    the_window,stipple_bits2,stipple_width,stipple_height);

		XSetStipple(the_display,the_gc,stipple_pixmap2);


	}



	if (i==3)


	{

		stipple_pixmap3 = XCreateBitmapFromData(the_display,
		    the_window,stipple_bits3,stipple_width,stipple_height);

		XSetStipple(the_display,the_gc,stipple_pixmap3);

	}



	if (i == 4)


	{

		stipple_pixmap4 = XCreateBitmapFromData(the_display,
		    the_window,stipple_bits4,stipple_width,stipple_height);

		XSetStipple(the_display,the_gc,stipple_pixmap4);

	}


	if (i == 5)


	{

		stipple_pixmap5 = XCreateBitmapFromData(the_display,
		    the_window,stipple_bits5,stipple_width,stipple_height);

		XSetStipple(the_display,the_gc,stipple_pixmap5);

	}


	if (i==6)

	{
		stipple_pixmap6 = XCreateBitmapFromData(the_display,
		    the_window,stipple_bits6,stipple_width,stipple_height);

		XSetStipple(the_display,the_gc,stipple_pixmap6);

	}


	XSetFillStyle(the_display,the_gc,FillStippled);

}
