home *** CD-ROM | disk | FTP | other *** search
-
-
- /*
- Program Six
- Bert Nelson
- Copyright 1992 Bert Nelson
-
- Compile Instructions: cc file.c -lX11 -lm -o file
-
- Run Instructions: type 'file' after compiling and click an item
- in the menu bar to do an option
-
- Program Purpose: Draw lines, circles, and ellipses using only
- the DrawPoint command.
-
- 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.
-
-
- */
-
- #define ASPECT_RATIO .999
- #define UNDEFINED 0
- #define XOFF 500
- #define YOFF 350
- #define TRUE 1
- #define FALSE 0
-
- #include <X11/Xlib.h>
- #include <X11/Xutil.h>
- #include <string.h>
- #include <math.h>
- #include <X11/keysym.h>
- #define PI 3.141592654 /* set up PI defintion */
-
- XPoint points[9];
-
-
- /* set strings as global */
- int sides;
- char enter_str[1];
- char rotate_str[1];
- char scale_str[1];
- char trans_str[1];
- char hello[] = "Fundamental Drawing by Bert Nelson";
- char lines_str[] = "Line";
- char circle_str[] = "Circle";
- char view_str[] = "View";
- char reset_str[] = "Reset";
- char quit_str[] = "Quit";
- Font font;
- int number;
-
- unsigned long black,white;
-
- main(argc,argv)
- int argc;
- char **argv;
- {
- Display *mydisplay;
- Window mywindow,child1,child2,child3,child4;
- GC enter_gc,mygc;
- XEvent myevent;
- KeySym mykey;
- XSizeHints myhint;
- XGCValues gvalues;
- XComposeStatus cs;
- char string[20];
- char newstring[20];
- int nchar;
- int count;
-
- int myscreen;
- unsigned long myforeground, mybackground;
- int i;
- char text[10];
- int done;
-
-
- /* set up display and foreground/background */
-
- mydisplay = XOpenDisplay("");
-
- myscreen = DefaultScreen (mydisplay);
- white = mybackground = WhitePixel (mydisplay, myscreen);
- black = myforeground = BlackPixel (mydisplay, myscreen);
-
- /* create a window with a size of 1000 x 700 */
-
- myhint.x = 0;
- myhint.y = 0;
- myhint.width = 1000;
- myhint.height = 700;
- myhint.flags = PPosition | PSize;
- mywindow = XCreateSimpleWindow (mydisplay,
- DefaultRootWindow (mydisplay),
- myhint.x, myhint.y, myhint.width, myhint.height,
- 5, myforeground, mybackground);
-
-
- /* create children windows that will act as menu buttons */
-
- child1 = XCreateSimpleWindow (mydisplay,mywindow,
- 0,0,100,25,2,myforeground,mybackground);
-
-
- child2 = XCreateSimpleWindow (mydisplay,mywindow,
- 100,0,100,25,2,myforeground,mybackground);
-
-
- child3 = XCreateSimpleWindow (mydisplay,mywindow,
- 200,0,100,25,2,myforeground,mybackground);
-
-
- child4 = XCreateSimpleWindow (mydisplay,mywindow,
- 300,0,175,25,2,myforeground,mybackground);
-
-
-
- /* print program name at the top */
-
- XSetStandardProperties (mydisplay, mywindow, hello, hello,
- None, argv, argc, &myhint);
-
- /* set up foreground/backgrounds and set up colors */
-
-
- mygc = XCreateGC (mydisplay, mywindow, 0, 0);
-
- gvalues.foreground = myforeground;
- gvalues.background = mybackground;
-
- enter_gc = XCreateGC(mydisplay,child1,0,0);
-
-
- XSetBackground (mydisplay, mygc, mybackground);
- XSetForeground (mydisplay, mygc, myforeground);
- XSetBackground (mydisplay,enter_gc,myforeground);
- XSetForeground (mydisplay,enter_gc,mybackground);
-
-
- /* Load up a font called 8x16 */
-
- font = XLoadFont(mydisplay,"8x16");
- XSetFont(mydisplay,mygc,font);
- XSetFont(mydisplay,enter_gc,font);
-
- /* Ask for input from the mouse and keyboard */
-
- XSelectInput (mydisplay, mywindow,
- ButtonPressMask | KeyPressMask | ExposureMask);
-
- /* map window to the screen */
- XMapRaised (mydisplay, mywindow);
-
- /* Map children windows to the screen */
-
- XMapRaised (mydisplay, child1);
- XMapRaised (mydisplay, child2);
- XMapRaised (mydisplay, child3);
- XMapRaised (mydisplay, child4);
-
- /* Display menu strings */
-
- XNextEvent(mydisplay,&myevent);
-
- XDrawImageString(mydisplay,child1,mygc,
- 30,20,lines_str,strlen(lines_str));
-
- XDrawImageString(mydisplay,child2,mygc,
- 25,20,circle_str,strlen(circle_str));
-
- XDrawImageString(mydisplay,child3,mygc,
- 25,20,reset_str,strlen(reset_str));
-
- XDrawImageString(mydisplay,child4,mygc,
- 65,20,quit_str,strlen(quit_str));
-
-
- /* Loop through until a q is press when the cursor is in
- the window, which will cause the application to quit */
-
- done = 0;
- while (done == 0) {
- XNextEvent (mydisplay, &myevent );
-
- if (myevent.type == ButtonPress)
- {
-
- if (myevent.xbutton.subwindow == child1)
- {
- process_line(mydisplay,mywindow,
- child1,mygc,enter_gc);
-
- }
-
- if (myevent.xbutton.subwindow == child2)
-
- process_circle(mydisplay,mywindow,child2,
- mygc,enter_gc);
-
- if (myevent.xbutton.subwindow == child3)
- process_reset(mydisplay,mywindow,child3,
- mygc,enter_gc);
-
-
- if (myevent.xbutton.subwindow == child4)
- {
- done = 1;
- break;
- }
-
- }
-
-
- if (myevent.xany.window == mywindow)
- {
- switch (myevent.type) {
-
- case KeyPress:
-
- {
- i = XLookupString (&myevent,
- text, 10, &mykey, 0);
- if (i == 1 && text[0] == 'q')
- done = 1;
- break;
-
- } /* case */
- } /* switch */
-
- } /* end if */
- } /* while */
-
- /* Free up and clean up the windows created */
-
- XFreeGC (mydisplay, mygc);
- XDestroyWindow (mydisplay, mywindow);
- XCloseDisplay (mydisplay);
-
- exit(0);
-
-
- }
-
- /* Ask for the user to enter the number of sides and the points
- for each side. By definition there are n+1 sides in reality because
- you need to draw back to where you started from, so the last point
- is assigned to the first point, which makes entering the points
- in order important */
-
-
- process_line(display,parent,child,parent_gc,child_gc)
-
- Display *display;
- Window parent,child;
- GC parent_gc,child_gc;
- {
-
- int i,j,offy,offx;
- Window enter_window;
- XEvent enter_event;
- Font enter_font;
- GC enter_gc;
- int count;
- char text[10];
- int string[10];
- KeySym key;
-
- /* Flash the Enter button on and off */
-
- XClearWindow(display,child);
- XFillRectangle(display,child,parent_gc,0,0,100,25);
- XDrawImageString(display,child,child_gc,
- 25,20,lines_str,strlen(lines_str));
- XFlush(display);
- for (i=0; i<1000; i++)
- XNoOp(display);
- XClearWindow(display,child);
- XDrawImageString(display,child,parent_gc,
- 25,20,lines_str,strlen(lines_str));
-
-
- /* set up input window */
-
-
- enter_window = XCreateSimpleWindow(display,parent,40,150,
- 300,150,3,black,white);
-
- enter_gc = parent_gc;
-
-
- XMapRaised(display,enter_window);
- XClearWindow(display,enter_window);
-
-
- XDrawString(display,enter_window,parent_gc,
- 75,25,"Enter Start/End Points",22);
-
- XSelectInput(display,enter_window,ButtonPressMask|KeyPressMask);
-
- /* set up a smaller font */
-
- font = XLoadFont(display,"7x13");
- XSetFont(display,enter_gc,font);
-
- /* reset everything */
-
- XFlush(display);
- string[0] = '\0';
- key = 0;
-
- /* prompt the user to input the number of sides */
-
-
- sides = 2;
-
- /* abort module if there are less than three or greater
- than eight sides to the figure */
-
-
- /* Clear everything out of the buffers and reset */
-
- XFlush(display);
- string[0] = '\0';
- key = 0;
- text[0] = '\0';
-
-
- /* Ask user to input a x value for n number of sides */
-
- /* Place the input into a string and convert it to
- a integer */
-
- for (i=0; i<sides; i++)
- {
-
- j = 67;
- XDrawString(display,enter_window,enter_gc,
- 15,65+i*30,"Enter x: ",9);
-
- do
- {
- j = j + 8;
- offx = 65+i*30;
- XNextEvent(display,&enter_event);
- count = XLookupString(&enter_event,text,10,&key,0);
- text[count] = '\0';
- if (key != XK_Return)
- XDrawString(display,enter_window,enter_gc,
- j,offx,text,1);
- strcat(string,text);
- } while (key != XK_Return && enter_event.type == KeyPress);
-
- /* convert the input string to an integer */
-
-
- points[i].x = XOFF + strtol(string,NULL,10) ;
-
-
- /* Flush out the buffers and reset everything */
-
-
- XFlush(display);
-
- key = 0;
- string[0] = '\0';
- j = 67;
-
- XDrawString(display,enter_window,enter_gc,
- 15,65+i*30+15,"Enter y: ",9);
-
- /* Ask user for a y value for each side of the figure */
- /* Accept a value only after a RETURN key has been pressed */
-
- do
- {
- j = j + 8; /* move over 8 pixels */
- offy = 80+i*30; /* move down some pixels */
-
- XNextEvent(display,&enter_event); /* ask for input */
-
- count = XLookupString(&enter_event,text,10,&key,0);
- text[count] = '\0';
-
- /* if the return key is NOT pressed display the key
- that was just pressed */
-
- if (key != XK_Return)
- XDrawString(display,enter_window,enter_gc,
- j,offy,text,1);
-
- strcat(string,text);
- } while (key != XK_Return && enter_event.type == KeyPress);
-
-
- /* flush out buffers and reset */
-
-
- points[i].y = YOFF - strtol(string,NULL,10);
-
-
- XFlush(display);
- key = 0;
- string[0] = '\0';
-
-
- }
-
-
-
-
- /* Tell the user he must press a key (or a mouse button)
- to exit. Note: for this to work the cursor must
- be inside the pop up window */
-
- XDrawString(display,enter_window,enter_gc,
- 55,65+i*30+10,"Press any key to Exit",22);
-
- /* Ask for input until a key is pressed */
-
- do
- XNextEvent(display,&enter_event);
- while( enter_event.xbutton.window != enter_window);
-
- /* set the font back to what it was before */
- /* don't ask me why, but it works this way */
-
- font = XLoadFont(display,"8x16");
- XSetFont(display,enter_gc,font);
-
- XDestroyWindow(display,enter_window);
-
-
-
- draw_line(display,parent,parent_gc);
-
-
- }
-
- /* Draw a line using a simple digital differential analyzer */
-
- draw_line(display,parent,gc)
-
- Display *display;
- Window parent;
- GC gc;
-
- {
-
- float xi=0;
- float yi=0;
- float xr=0;
- float yr=0;
- float m;
- float minverse;
- float xstart = points[0].x;
- float ystart = points[0].y;
- float xend = points[1].x;
- float yend = points[1].y;
- int temp=0;
- int temp2=0;
- int x1=0;
- int x2=0;
- int i=0;
-
-
-
-
- XSetBackground(display,gc,white);
- XSetForeground(display,gc,black);
-
- /* Draw x and y axis */
-
- XDrawLine(display,parent,gc,XOFF,0,XOFF,YOFF*2);
- XDrawLine(display,parent,gc,0,YOFF,XOFF*2,YOFF);
-
- /* Draw notches in x and y axis */
-
- for (i=25; i<YOFF*2; i=i+25)
- XDrawLine(display,parent,gc,
- XOFF-3,i,XOFF+3,i);
-
- for (i=25; i<XOFF*2; i= i+25)
- XDrawLine(display,parent,gc,
- i,YOFF-3,i,YOFF+3);
-
-
- XFlush(display);
-
- /* check for a slope of zero -- a vertical line */
-
- if (xend - xstart == 0)
- m = UNDEFINED;
- else
- m = (yend - ystart) / (xend - xstart);
-
-
- if ( (m == UNDEFINED && ystart < yend )
- || (fabs(m) <= 1 && (xstart > xend)) ||
- ((fabs (m) > 1) && (ystart > yend)))
- {
- temp = xend;
- xend = xstart;
- xstart = temp;
- temp = yend;
- yend = ystart;
- ystart = temp;
- }
-
-
- XDrawPoint(display,parent,gc,xstart,ystart);
-
- if (yend == ystart || fabs(m) == 1.0 || (fabs (m) < 1 && m != UNDEFINED))
- {
- yr = ystart;
- for (xi=xstart + 1.0; xi<xend - 1; xi++)
- {
- yr = yr + m;
- temp = xi;
- temp2 = yr + .5; /* round it off */
- XDrawPoint(display,parent,gc,temp,temp2);
- }
- }
-
- if (fabs (m) > 1 )
- {
- minverse = 1/m;
- xr = xstart;
- for (yi = ystart +1; yi<yend -1; yi++)
- {
- xr = xr + minverse;
- temp = xr + .5; /* round it off */
- temp2 = yi;
- XDrawPoint(display,parent,gc,temp,temp2);
- }
-
- }
-
-
- /* handle vertical lines, which are not done by the DDA */
-
- if ( m == UNDEFINED )
- {
-
- temp = xstart;
- for (yi = yend + 1; yi < ystart -1; yi++)
-
- {
- temp2 = yi;
- XDrawPoint(display,parent,gc,temp,temp2);
- }
-
- }
-
-
- XDrawPoint(display,parent,gc,xend,yend);
- }
-
-
- /* Ask user to enter in the x and y translation factors for the figure */
-
-
-
-
-
- process_circle(display,parent,child,parent_gc,child_gc)
-
-
- Display *display;
- Window parent,child;
- GC parent_gc,child_gc;
- {
-
-
- int i,off;
- Window circle_window;
- XEvent circle_event;
- Font circle_font;
- GC circle_gc;
- int count;
- char text[10];
- char radius[10];
- int string[10];
- KeySym key=0;
- float radians;
- double tempcos;
- double tempsin;
- float circle_radius;
-
- int circle_x;
- int circle_y;
-
- /* Flash circle button on and off */
-
- XClearWindow(display,child);
- XFillRectangle(display,child,parent_gc,0,0,100,25);
- XDrawImageString(display,child,child_gc,
- 25,20,circle_str,strlen(circle_str));
- XFlush(display);
- for (i=0; i<1000; i++)
- XNoOp(display);
- XClearWindow(display,child);
- XDrawImageString(display,child,parent_gc,
- 25,20,circle_str,strlen(circle_str));
-
- /* create a pop up window */
-
- circle_window = XCreateSimpleWindow(display,parent,40,125,
- 300,200,3,black,white);
-
- circle_gc = parent_gc;
-
-
- XMapRaised(display,circle_window);
- XClearWindow(display,circle_window);
-
- XDrawString(display,circle_window,parent_gc,
- 35,25,"Enter Radius/Center of Circle",30);
-
-
- XSelectInput(display,circle_window,ButtonPressMask
- |KeyPressMask);
-
- /* load up a small font */
-
- font = XLoadFont(display,"7x13");
- XSetFont(display,circle_gc,font);
-
- XDrawString(display,circle_window,circle_gc,
- 55,75,"Enter Circle Radius: ",
- 22);
- string[0] = '\0';
- key = 0;
- text[0] ='\0';
-
-
- i = 190;
- do
- {
- i = i + 8;
- XNextEvent(display,&circle_event);
- count = XLookupString(&circle_event,text,10,&key,0);
- text[count] = '\0';
- if (key != XK_Return)
- XDrawString(display,circle_window,circle_gc,
- i,75,text,1);
- strcat(string,text);
- } while (key != XK_Return && circle_event.type == KeyPress);
-
-
-
- circle_radius = atof(string);
-
- /* Prompt and get input from the user to the X value to
- circle about */
-
- XDrawString(display,circle_window,circle_gc,
- 55,105,"Enter X value of center: ",
- 25);
-
-
- /* reset values */
-
- key = 0;
- text[0] ='\0';
- string[0] = '\0';
- i = 220;
-
- do
- {
- i = i + 8;
- XNextEvent(display,&circle_event);
- count = XLookupString(&circle_event,text,10,&key,0);
- text[count] = '\0';
- if (key != XK_Return)
- XDrawString(display,circle_window,circle_gc,
- i,105,text,1);
- strcat(string,text);
- } while (key != XK_Return && circle_event.type == KeyPress);
-
- /* convert the string to an integer */
-
- circle_x = XOFF + strtol(string,NULL,10);
-
- /* Ask for the user to enter a y value */
-
- XDrawString(display,circle_window,circle_gc,
- 55,135,"Enter Y value of center: ",
- 25);
-
- key = 0;
- text[0] ='\0';
- string[0] = '\0';
- i = 220;
-
- do
- {
- i = i + 8;
- XNextEvent(display,&circle_event);
- count = XLookupString(&circle_event,text,10,&key,0);
- text[count] = '\0';
- if (key != XK_Return)
- XDrawString(display,circle_window,circle_gc,
- i,135,text,1);
- strcat(string,text);
- } while (key != XK_Return && circle_event.type == KeyPress);
-
- /* conver the string to an integer */
-
- circle_y = YOFF - strtol(string,NULL,10);
-
- XDrawString(display,circle_window,circle_gc,
- 75,180,"Press any key to Exit",22);
-
- XFlush(display);
-
- do
- XNextEvent(display,&circle_event);
- while( circle_event.xbutton.window != circle_window);
-
- font = XLoadFont(display,"8x16");
- XSetFont(display,circle_gc,font);
-
- XDestroyWindow(display,circle_window);
-
- XFlush(display);
-
- draw_circle(circle_radius,display,parent,parent_gc,circle_x,circle_y);
-
-
- }
-
-
- draw_circle(rad,display,parent,gc,xc,yc)
-
- float rad;
- Display *display;
- Window parent;
- int xc;
- int yc;
-
- {
-
- float dtheta;
- float ct;
- float st;
- float x=0;
- float y=0;
- float xtemp;
- int tempx;
- int tempy;
- int i;
-
- XFlush(display);
-
-
- XSetBackground(display,gc,white);
- XSetForeground(display,gc,black);
-
- /* Draw x and y axis */
-
- XDrawLine(display,parent,gc,XOFF,0,XOFF,YOFF*2);
- XDrawLine(display,parent,gc,0,YOFF,XOFF*2,YOFF);
-
- /* Draw notches in x and y axis */
-
- for (i=25; i<YOFF*2; i=i+25)
- XDrawLine(display,parent,gc,
- XOFF-3,i,XOFF+3,i);
-
- for (i=25; i<XOFF*2; i= i+25)
- XDrawLine(display,parent,gc,
- i,YOFF-3,i,YOFF+3);
-
-
-
- dtheta = 1/rad;
-
- ct = cos(dtheta);
- st = sin(dtheta);
-
- x = 0;
- y = rad;
-
- while (y >= x)
- {
-
-
- tempx = xc +x;
- tempy = yc + y * ASPECT_RATIO;
-
- XDrawPoint(display,parent,gc,tempx,tempy);
-
- tempx = xc - x;
-
- XDrawPoint(display,parent,gc,tempx,tempy);
-
- tempx = xc + x;
- tempy = yc - y * ASPECT_RATIO;
-
- XDrawPoint(display,parent,gc,tempx,tempy);
-
- tempx = xc - x;
-
- XDrawPoint(display,parent,gc,tempx,tempy);
-
- tempx = xc + y;
- tempy = yc + x * ASPECT_RATIO;
-
- XDrawPoint(display,parent,gc,tempx,tempy);
-
- tempx = xc - y;
-
- XDrawPoint(display,parent,gc,tempx,tempy);
-
- tempx = xc + y;
- tempy = yc - x * ASPECT_RATIO;
-
- XDrawPoint(display,parent,gc,tempx,tempy);
-
- tempx = xc - y;
-
- XDrawPoint(display,parent,gc,tempx,tempy);
-
- xtemp = x;
- x = (x*ct - y *st);
- y = (y*ct + xtemp*st);
-
-
- }
-
- }
-
- /* clear the screen of the old figures and reset everything */
-
-
- process_reset(display,parent,child,parent_gc,child_gc)
-
-
- Display *display;
- Window parent,child;
- GC parent_gc,child_gc;
- {
-
- int i;
-
- /* flash the reset button */
-
- XClearWindow(display,child);
- XFillRectangle(display,child,parent_gc,0,0,100,25);
- XDrawImageString(display,child,child_gc,
- 25,20,reset_str,strlen(reset_str));
- XFlush(display);
- for (i=0; i<1000; i++)
- XNoOp(display);
- XClearWindow(display,child);
- XDrawImageString(display,child,parent_gc,
- 25,20,reset_str,strlen(reset_str));
-
- XClearWindow(display,parent);
-
-
- }
-
-