/* Purpose: Draw a quadrilateral using four points in a file */ /* Compile with: gcc -g -L /usr/X11R6/lib -lX11 -lm -o rectdrawwin rectdrawwin.c */ #include #include #include #include #include #include "bitmaps/icon_bitmap" #define TOO_SMALL 0 #define BIG_ENOUGH 1 #define TRUE 1 #define FALSE 0 /* Global structure declaration */ struct point { float x; float y; }; /* function prototypes */ void getGC(Window win, GC *gc, XFontStruct *font_info); void load_font(XFontStruct ** font_info); void draw_line( Window win, GC gc, unsigned int window_width, unsigned int window_height, struct point p1, struct point p2); void draw_axes( Window win, GC gc, unsigned int window_width, unsigned int window_height); void TooSmall( Window win, GC gc, XFontStruct *font_info); /* These are used as arguments to nearly every Xlib routine, so it * saves routine arguments to declare them global; if there were * additional source files, they would be declared extern there. */ Display *display; int screen_num; /* progname is the string by which this program was invoked; this * is global because it is needed in most application functions. */ static char *progname; void main(int argc, char *argv[]) { Window win; unsigned int width, height; /* Window size */ int x, y; /* Window position */ unsigned int border_width = 4; /* Four pixels */ unsigned int display_width, display_height; unsigned int icon_width, icon_height; char *window_name = "Rectangle Draw X Window Program"; char *icon_name = "rectdrawwin"; Pixmap icon_pixmap; XSizeHints *size_hints; XIconSize *size_list; XWMHints *wm_hints; XClassHint *class_hints; XTextProperty windowName, iconName; int count; XEvent report; GC gc; XFontStruct *font_info; char *display_name = NULL; int window_size = 0; /* BIG_ENOUGH or TOO_SMALL to * display contents */ struct point p[4]; /* coordinates of the four corners */ float m[2]; /* slopes of the two adjacent sides */ int err[2]; /* vertical line error for slope */ int i; FILE *fpin; int okflag; /* TRUE if right angle found */ char infile[80]; /* filename */ /* read in data for coordinates */ if (argc == 1) { printf("No data file provided.\n"); printf("Usage: rectdrawwin datafilename\n"); exit(0); } strcpy(infile, argv[1]); fpin = fopen(infile, "r"); for( i = 0; i < 4; i++) { fscanf(fpin, "%f%f", &p[i].x, &p[i].y); } fclose(fpin); printf("The points for the quadilateral are:\n"); for( i = 0; i < 4; i++) /* print coordinates */ { printf( "(%.2f, %.2f)\n", p[i].x, p[i].y); } printf("Take a look at it in the window!\n"); printf("Click in the window to terminate the program!\n"); progname = argv[0]; if (!(size_hints = XAllocSizeHints())) { fprintf(stderr, "%s: failure allocating memory\n", progname); exit(0); } if (!(wm_hints = XAllocWMHints())) { fprintf(stderr, "%s: failure allocating memory\n", progname); exit(0); } if (!(class_hints = (XClassHint *)XAllocClassHint())) { fprintf(stderr, "%s: failure allocating memory\n", progname); exit(0); } /* Connect to X server */ if ( (display = XOpenDisplay(display_name)) == NULL) { (void)fprintf( stderr, "%s: cannot connect to X server %s\n", progname, XDisplayName(display_name) ); exit(-1); } /* Get screen size from display structure macro */ screen_num = DefaultScreen(display); display_width = DisplayWidth(display, screen_num); display_height = DisplayHeight(display, screen_num); /* Note that in a real application, x and y would default * to 0 but would be settable from the command line or * resource database */ x = y = 0; /* Size window with enough room for text */ width = display_width/3; height = display_height/4; /* Create opaque window */ win = XCreateSimpleWindow(display, RootWindow(display, screen_num), x, y, width, height, border_width, BlackPixel(display, screen_num), WhitePixel(display, screen_num)); /* Get available icon sizes from window manager */ if (XGetIconSizes(display, RootWindow(display, screen_num), &size_list, &count) == 0) ; /* (void)fprintf( stderr, "%s: Window manager didn't set icon sizes - using default.\n", progname);*/ else { ; /* A real application would search through size_list * here to find an acceptable icon size and then * create a pixmap of that size; this requires that * the application have data for several sizes of icons */ } /* Create pixmap of depth 1 (bitmap) for the icon */ icon_pixmap = XCreateBitmapFromData( display, win, icon_bitmap_bits, icon_bitmap_width, icon_bitmap_height); /* Set size hints for window manager; the window manager * may override these settings */ /* Note that in a real application, if size or position * were set by the user, the flags would be USPosition * USSize and these would override the window manager's * preferences for this window */ /* x, y, width, and height hints are now taken from * the actual settings of the window when mapped; note * that PPosition and PSize must be specified anyway. */ size_hints->flags = PPosition | PSize | PMinSize; size_hints->min_width = 300; size_hints->min_height = 200; /* These calls store window_name and icon_name into * XTextProperty structures and set their other fields properly */ if (XStringListToTextProperty(&window_name, 1, &windowName) == 0) { (void)fprintf( stderr, "%s: structure allocation for windowName failed.\n", progname); exit(-1); } if (XStringListToTextProperty(&icon_name, 1, &iconName) == 0) { (void)fprintf( stderr, "%s: structure allocation for iconName failed.\n", progname); exit(-1); } wm_hints->initial_state = NormalState; wm_hints->input = True; wm_hints->icon_pixmap = icon_pixmap; wm_hints->flags = StateHint | IconPixmapHint | InputHint; class_hints->res_name = progname; class_hints->res_class = "Rectdrawwin"; XSetWMProperties(display, win, &windowName, &iconName, argv, argc, size_hints, wm_hints, class_hints); /* Select event types wanted */ XSelectInput(display, win, ExposureMask | KeyPressMask | ButtonPressMask | StructureNotifyMask); load_font(&font_info); /* Create GC for text and drawing */ getGC(win, &gc, font_info); /* Display window */ XMapWindow(display, win); /* Get events, use first to display text and graphics */ while (1) { XNextEvent(display, &report); switch (report.type) { case Expose: /* Unless this is the last contiguous expose, * don't draw the window. */ if (report.xexpose.count != 0) break; /* If window too small to use */ if ( window_size == TOO_SMALL) TooSmall(win, gc, font_info); else { draw_axes( win, gc, width, height); for(i = 0; i < 3; i++) draw_line( win, gc, width, height, p[i], p[i + 1]); draw_line( win, gc, width, height, p[3], p[0]); } break; case ConfigureNotify: /* Window has been resized; change width * and height to send to place_text and * place_graphics in next Expose */ width = report.xconfigure.width; height = report.xconfigure.height; if ((width < size_hints->min_width) || (height < size_hints->min_height)) window_size = TOO_SMALL; else window_size = BIG_ENOUGH; break; case ButtonPress: /* Trickle down into KeyPress (no break) */ case KeyPress: XUnloadFont(display, font_info->fid); XFreeGC(display, gc); XCloseDisplay(display); exit(1); default: /* All events selected by StructureNotifyMask * except ConfigureNotify are thrown away here, * since nothing is done with them */ break; } /* End switch */ } /* End while(1) */ } void getGC(Window win, GC *gc, XFontStruct *font_info) { unsigned long valuemask = 0; /* Ignore XGCvalues and use defaults */ XGCValues values; unsigned int line_width = 1; int line_style = 0; int cap_style = 0; int join_style = 0; int dash_offset = 0; int list_length = 0; /* Create default Graphics Context */ *gc = XCreateGC(display, win, valuemask, &values); /* Specify font */ XSetFont(display, *gc, font_info->fid); /* Specify black foreground since default widow background * is white and default foreground is undefined */ XSetForeground(display, *gc, BlackPixel(display, screen_num)); /* Set line attributes */ XSetLineAttributes(display, *gc, line_width, line_style, cap_style, join_style); /* Set dashes */ /* XSetDashes(display, *gc, dash_offset, dash_list, list_length);*/ } void load_font(XFontStruct ** font_info) { char *fontname = "9x15"; /* Load font and get font information structure */ if ((*font_info = XLoadQueryFont(display, fontname)) == NULL) { (void)fprintf( stderr, "%s: Cannot open 9x15 font.\n", progname); exit(-1); } } void draw_line( Window win, GC gc, unsigned int window_width, unsigned int window_height, struct point p1, struct point p2) { int x_origin, y_origin; int width, height; x_origin = window_width/2; /* Origin */ y_origin = window_height/2; XDrawLine(display, win, gc, x_origin + p1.x * 10, y_origin - p1.y * 10, x_origin + p2.x * 10, y_origin - p2.y * 10); } void draw_axes( Window win, GC gc, unsigned int window_width, unsigned int window_height) { int x_origin, y_origin; int width, height; x_origin = window_width/2; /* Origin */ y_origin = window_height/2; XDrawLine(display, win, gc, x_origin, 0, x_origin, window_height - 1); XDrawLine(display, win, gc, 0, y_origin, window_width - 1, y_origin); } void TooSmall( Window win, GC gc, XFontStruct *font_info) { char *string1 = "Too Small"; int y_offset, x_offset; y_offset = font_info->ascent + 2; x_offset = 2; /* Output text, centered on each line */ XDrawString(display, win, gc, x_offset, y_offset, string1, strlen(string1)); }