home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / x / xlibpr3.zip / basicwin / predproc / basicwin.c next >
C/C++ Source or Header  |  1989-11-27  |  10KB  |  352 lines

  1. /*
  2.  * Copyright 1989 O'Reilly and Associates, Inc.
  3.  * See ../Copyright for complete rights and liability information.
  4.  */
  5. #include <X11/Xlib.h>
  6. #include <X11/Xutil.h>
  7. #include <X11/Xos.h>
  8.  
  9. #include <stdio.h>
  10.  
  11. #include "../bitmaps/icon_bitmap"
  12. #define BITMAPDEPTH 1
  13. #define SMALL 1
  14. #define OK 0
  15. #define BUF_SIZE 2000
  16.  
  17. /* These are used as arguments to nearly every Xlib routine, so it saves 
  18.  * routine arguments to declare them global.  If there were 
  19.  * additional source files, they would be declared extern there. */
  20. Display *display;
  21. int screen;
  22.  
  23. void main(argc, argv)
  24. int argc;
  25. char **argv;
  26. {
  27.     Window win;
  28.     unsigned int width, height, x = 0, y = 0;     /* window size and position */
  29.     unsigned int border_width = 4;    /* four pixels */
  30.     unsigned int display_width, display_height;
  31.     char *window_name = "basicwin";
  32.     char *icon_name = "";
  33.     Pixmap icon_pixmap;
  34.     XSizeHints size_hints;
  35.     XEvent report;
  36.     GC gc;
  37.     XFontStruct *font_info;
  38.     char *display_name = NULL;
  39.     int window_size = 0;    /* OK, or too SMALL to display contents */
  40.     int root_x, root_y;
  41.     Window root, child;
  42.     unsigned int keys_buttons;
  43.  
  44.     Window wint;
  45.     XPoint points[BUF_SIZE];
  46.     int index = 0;
  47.     int pos_x, pos_y;
  48.     int prev_x, prev_y;
  49.     GC gcx;
  50.  
  51.     Bool predproc();
  52.     static char *stuff = "do this or that";
  53.  
  54.     /* connect to X server */
  55.  
  56.     if ( (display=XOpenDisplay(display_name)) == NULL )
  57.     {
  58.         (void) fprintf( stderr, "basicwin: cannot connect to X server %s\n", XDisplayName(display_name));
  59.         exit( -1 );
  60.     }
  61.  
  62.     /* get screen size from display structure macro */
  63.     screen = DefaultScreen(display);
  64.     display_width = DisplayWidth(display, screen);
  65.     display_height = DisplayHeight(display, screen);
  66.  
  67.     /* note that x and y are 0, since the default position of the window
  68.      * is the top left corner of the root. This is fine since the window
  69.      * manager often allows the user to position the window before mapping it. */
  70.  
  71.     /* size window with enough room for text */
  72.     width = display_width/3, height = display_height/4;
  73.  
  74.     /* create opaque window */
  75.     win = XCreateSimpleWindow(display, RootWindow(display,screen), x, y, width, height, border_width, BlackPixel(display,
  76.         screen), WhitePixel(display,screen));
  77.  
  78.     wint = XCreateSimpleWindow(display, win, 20, 20, 50, 50, border_width, BlackPixel(display,
  79.         screen), WhitePixel(display,screen));
  80.  
  81.     /* Create pixmap of depth 1 (bitmap) for icon */
  82.     icon_pixmap = XCreateBitmapFromData(display, win, icon_bitmap_bits, icon_bitmap_width, icon_bitmap_height);
  83.  
  84.     /* Set resize hints */
  85.     size_hints.flags = PPosition | PSize | PMinSize;
  86.     size_hints.x = x;
  87.     size_hints.y = y;
  88.     size_hints.width = width;
  89.     size_hints.height = height;
  90.     size_hints.min_width = 300;
  91.     size_hints.min_height = 200;
  92.  
  93.     /* set Properties for window manager (always before mapping) */
  94.     XSetStandardProperties(display, win, window_name, icon_name, 
  95.         icon_pixmap, argv, argc, &size_hints);
  96.  
  97.     /* Select event types wanted */
  98.     XSelectInput(display, win, ExposureMask | KeyPressMask | ButtonPressMask | StructureNotifyMask);
  99.  
  100.     XSelectInput(display, wint, ExposureMask | PointerMotionMask | PointerMotionHintMask);
  101.  
  102.     load_font(&font_info);
  103.  
  104.     /* create GC for text and drawing */
  105.     getGC(win, &gc, font_info);
  106.  
  107.     gcx = XCreateGC(display, win, 0, NULL);
  108.     XSetFunction(display, gcx, GXxor);
  109.     XSetForeground(display, gcx,
  110.         WhitePixel(display, screen)^BlackPixel(display, screen));
  111.  
  112.     /* Display window */
  113.     XMapWindow(display, win);
  114.     XMapWindow(display, wint);
  115.  
  116.     /* get events, use first to display text and graphics */
  117.     while (1)  {
  118.         XIfEvent(display, &report, predproc, stuff);
  119.         switch  (report.type) {
  120.         case MotionNotify:
  121.             printf("got a motion event\n");
  122.                         if (!XQueryPointer(display, report.xmotion.window,
  123.                                 &root, &child, &root_x, &root_y, &pos_x,
  124.                                 &pos_y, &keys_buttons))
  125.                 /* pointer is on other screen */
  126.                 break;
  127.  
  128.                         if (index != 0)
  129.                 XDrawLine(display, wint, gcx, prev_x, prev_y,
  130.                                     pos_x, pos_y);
  131.  
  132.             if (index < BUF_SIZE) {
  133.                 points[index].x = pos_x;
  134.                 points[index].y = pos_y;
  135.                 index++;
  136.             }
  137.  
  138.             prev_x = pos_x;
  139.             prev_y = pos_y;
  140.             break;
  141.  
  142.         case Expose:
  143.             printf("got expose event\n");
  144.  
  145.             if (report.xexpose.window == wint) {
  146.                       while (XCheckTypedWindowEvent(display, wint, Expose, &report));
  147.                 if (index != 0)
  148.                     XDrawLines(display, wint, gcx, points, index, CoordModeOrigin);
  149.             }
  150.             else {
  151.                       while (XCheckTypedWindowEvent(display, win, Expose, &report));
  152.                 if (window_size == SMALL)
  153.                     TooSmall(win, gc, font_info);
  154.                 else {
  155.                     /* place text in window */
  156.                     place_text(win, gc, font_info, width, height);
  157.     
  158.                     /* place graphics in window, */
  159.                     place_graphics(win, gc, width, height);
  160.                 }
  161.             }
  162.             break;
  163.         case ConfigureNotify:
  164.             printf("got configure event\n");
  165.             /* window has been resized, change width and
  166.              * height to send to place_text and place_graphics
  167.              * in next Expose */
  168.             width = report.xconfigure.width;
  169.             height = report.xconfigure.height;
  170.             if ((width < size_hints.min_width) || (height < size_hints.min_height))
  171.                 window_size = SMALL;
  172.             else
  173.                 window_size = OK;
  174.             break;
  175.         case ButtonPress:
  176.         case KeyPress:
  177.             XUnloadFont(display, font_info->fid);
  178.             XFreeGC(display, gc);
  179.             XCloseDisplay(display);
  180.             exit(1);
  181.         default:
  182.             /* all events selected by StructureNotifyMask
  183.              * except ConfigureNotify are thrown away here,
  184.              * since nothing is done with them */
  185.             break;
  186.         } /* end switch */
  187.     } /* end while */
  188. }
  189.  
  190. getGC(win, gc, font_info)
  191. Window win;
  192. GC *gc;
  193. XFontStruct *font_info;
  194. {
  195.     unsigned long valuemask = 0; /* ignore XGCvalues and use defaults */
  196.     XGCValues values;
  197.     unsigned int line_width = 6;
  198.     int line_style = LineOnOffDash;
  199.     int cap_style = CapRound;
  200.     int join_style = JoinRound;
  201.     int dash_offset = 0;
  202.     static char dash_list[] = {12, 24};
  203.     int list_length = 2;
  204.  
  205.     /* Create default Graphics Context */
  206.     *gc = XCreateGC(display, win, valuemask, &values);
  207.  
  208.     /* specify font */
  209.     XSetFont(display, *gc, font_info->fid);
  210.  
  211.     /* specify black foreground since default may be white on white */
  212.     XSetForeground(display, *gc, BlackPixel(display,screen));
  213.  
  214.     /* set line attributes */
  215.     XSetLineAttributes(display, *gc, line_width, line_style, cap_style, join_style);
  216.  
  217.     /* set dashes to be line_width in length */
  218.     XSetDashes(display, *gc, dash_offset, dash_list, list_length);
  219. }
  220.  
  221. load_font(font_info)
  222. XFontStruct **font_info;
  223. {
  224.     char *fontname = "9x15";
  225.  
  226.     /* Access font */
  227.     if ((*font_info = XLoadQueryFont(display,fontname)) == NULL)
  228.     {
  229.         (void) fprintf( stderr, "Basic: Cannot open 9x15 font\n");
  230.         exit( -1 );
  231.     }
  232. }
  233.  
  234. place_text(win, gc, font_info, win_width, win_height)
  235. Window win;
  236. GC gc;
  237. XFontStruct *font_info;
  238. unsigned int win_width, win_height;
  239. {
  240.     int y = 20;     /* offset from corner of window*/
  241.     char *string1 = "Hi! I'm a window, who are you?";
  242.     char *string2 = "To terminate program; Press any key";
  243.     char *string3 = "or button while in this window.";
  244.     char *string4 = "Screen Dimensions:";
  245.     int len1, len2, len3, len4;
  246.     int width1, width2, width3;
  247.     char cd_height[50], cd_width[50], cd_depth[50];
  248.     int font_height;
  249.     int initial_y_offset, x_offset;
  250.  
  251.  
  252.     /* need length for both XTextWidth and XDrawString */
  253.     len1 = strlen(string1);
  254.     len2 = strlen(string2);
  255.     len3 = strlen(string3);
  256.  
  257.     /* get string widths for centering */
  258.     width1 = XTextWidth(font_info, string1, len1);
  259.     width2 = XTextWidth(font_info, string2, len2);
  260.     width3 = XTextWidth(font_info, string3, len3);
  261.  
  262.     /* output text, centered on each line */
  263.     XDrawString(display,win,gc,(win_width - width1)/2,y,string1,len1);
  264.     XDrawString(display,win,gc,(win_width - width2)/2, (int)(win_height - 35),string2,len2);
  265.     XDrawString(display,win,gc,(win_width - width3)/2, (int)(win_height - 15),string3,len3);
  266.  
  267.     /* copy numbers into string variables */
  268.     (void) sprintf(cd_height, " Height - %d pixels", DisplayHeight(display,screen));
  269.     (void) sprintf(cd_width, " Width  - %d pixels", DisplayWidth(display,screen));
  270.     (void) sprintf(cd_depth, " Depth  - %d plane(s)", DefaultDepth(display, screen));
  271.  
  272.     /* reuse these for same purpose */
  273.     len4 = strlen(string4);
  274.     len1 = strlen(cd_height);
  275.     len2 = strlen(cd_width);
  276.     len3 = strlen(cd_depth);
  277.  
  278.     font_height = font_info->max_bounds.ascent + font_info->max_bounds.descent;
  279.  
  280.     /* To center strings vertically, we place the first string
  281.      * so that the top of it is two font_heights above the center
  282.      * of the window.  Since the baseline of the string is what we
  283.      * need to locate for XDrawString, and the baseline is one
  284.      * font_info->max_bounds.ascent below the top of the chacter,
  285.      * the final offset of the origin up from the center of the 
  286.      * window is one font_height + one descent. */
  287.  
  288.     initial_y_offset = win_height/2 - font_height - font_info->max_bounds.descent;
  289.     x_offset = (int) win_width/4;
  290.     XDrawString(display, win, gc, x_offset, (int) initial_y_offset, string4,len4);
  291.  
  292.     XDrawString(display, win, gc, x_offset, (int) initial_y_offset + font_height,cd_height,len1);
  293.     XDrawString(display, win, gc, x_offset, (int) initial_y_offset + 2 * font_height,cd_width,len2);
  294.     XDrawString(display, win, gc, x_offset, (int) initial_y_offset + 3 * font_height,cd_depth,len3);
  295. }
  296.  
  297.  
  298. place_graphics(win, gc, window_width, window_height)
  299. Window win;
  300. GC gc;
  301. unsigned int window_width, window_height;
  302. {
  303.     int x, y;
  304.     int width, height;
  305.  
  306.     height = window_height/2;
  307.     width = 3 * window_width/4;
  308.     x = window_width/2 - width/2;  /* center */
  309.     y = window_height/2 - height/2;
  310.     XDrawRectangle(display, win, gc, x, y, width, height);
  311. }
  312.  
  313. TooSmall(win, gc, font_info)
  314. Window win;
  315. GC gc;
  316. XFontStruct *font_info;
  317. {
  318.     char *string1 = "Too Small";
  319.     int y_offset, x_offset;
  320.  
  321.     y_offset = font_info->max_bounds.ascent + 2;
  322.     x_offset = 2;
  323.  
  324.     /* output text, centered on each line */
  325.     XDrawString(display, win, gc, x_offset, y_offset, string1, strlen(string1));
  326. }
  327.  
  328. Bool predproc(display, event, arg)
  329. Display *display;
  330. XEvent *event;
  331. char *arg;
  332. {
  333.     printf("main passed \"%s\" to predicate procedure.\n", arg);
  334.     switch (event->type) {
  335.         case Expose:
  336.         case MotionNotify:
  337.         case ConfigureNotify:
  338.         case KeyPress:
  339.             return(True);
  340.             break;
  341.         case ButtonPress:
  342.         case ButtonRelease:
  343.             if (event->xbutton.button == Button1)
  344.                 return(True);
  345.             else
  346.                 return(False);
  347.             break;
  348.         default:
  349.             break;/* many *Notify event types handled here */
  350.     }
  351. }
  352.