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 / doreg / basicwin.c next >
C/C++ Source or Header  |  1989-12-30  |  10KB  |  315 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 TOO_SMALL 1
  14. #define BIG_ENOUGH 0
  15.  
  16. /* These are used as arguments to nearly every Xlib routine, so it saves 
  17.  * routine arguments to declare them global.  If there were 
  18.  * additional source files, they would be declared extern there. */
  19. Display *display;
  20. int screen;
  21.  
  22. void main(argc, argv)
  23. int argc;
  24. char **argv;
  25. {
  26.     Window win;
  27.     unsigned int width, height, x = 0, y = 0;     /* window size and position */
  28.     unsigned int border_width = 4;    /* four pixels */
  29.     unsigned int display_width, display_height;
  30.     unsigned int icon_width, icon_height;
  31.     char *window_name = "basicwin";
  32.     char *icon_name = "";
  33.     Pixmap icon_pixmap;
  34.     XSizeHints size_hints;
  35.     XIconSize *size_list;
  36.     int count;
  37.     XEvent report;
  38.     GC gc;
  39.     XFontStruct *font_info;
  40.     char *display_name = NULL;
  41.     int window_size = 0;    /* BIG_ENOUGH, or too TOO_SMALL to display contents */
  42.     Region region;        /* for exposure event processing */
  43.     XRectangle rectangle;    /* for exposure event processing */
  44.  
  45.     /* connect to X server */
  46.  
  47.     if ( (display=XOpenDisplay(display_name)) == NULL )
  48.     {
  49.         (void) fprintf( stderr, "basicwin: cannot connect to X server %s\n", XDisplayName(display_name));
  50.         exit( -1 );
  51.     }
  52.  
  53.     /* get screen size from display structure macro */
  54.     screen = DefaultScreen(display);
  55.     display_width = DisplayWidth(display, screen);
  56.     display_height = DisplayHeight(display, screen);
  57.  
  58.     /* note that x and y are 0, since the default position of the window
  59.      * is the top left corner of the root. This is fine since the window
  60.      * manager often allows the user to position the window before mapping it. */
  61.  
  62.     /* size window with enough room for text */
  63.     width = display_width/3, height = display_height/4;
  64.  
  65.     /* create opaque window */
  66.     win = XCreateSimpleWindow(display, RootWindow(display,screen), x, y, width, height, border_width, BlackPixel(display,
  67.         screen), WhitePixel(display,screen));
  68.  
  69.     /* Get available icon sizes from Window manager
  70.     if (XGetIconSizes(display, RootWindow(display,screen), &size_list, &count) == 0)
  71.     {
  72.         (void) fprintf( stderr, "Window manager didn't set icon sizes - using default.\n");
  73.         icon_width = 40;
  74.         icon_height = 40;
  75.     }
  76.     else
  77.     {
  78.         while (icon_width < size_list->min_width
  79.         icon_width = size_list->max_width;
  80.         icon_height = size_list->max_height;
  81.     }
  82.     all the icon size stuff commented out */
  83.  
  84.     /* Create pixmap of depth 1 (bitmap) for icon */
  85.     icon_pixmap = XCreateBitmapFromData(display, win, icon_bitmap_bits, icon_bitmap_width, icon_bitmap_height);
  86.  
  87.     /* Set resize hints */
  88.     size_hints.flags = PPosition | PSize | PMinSize;
  89.     size_hints.x = x;
  90.     size_hints.y = y;
  91.     size_hints.width = width;
  92.     size_hints.height = height;
  93.     size_hints.min_width = 300;
  94.     size_hints.min_height = 200;
  95.  
  96.     /* set Properties for window manager (always before mapping) */
  97.     XSetStandardProperties(display, win, window_name, icon_name, 
  98.         icon_pixmap, argv, argc, &size_hints);
  99.  
  100.     /* Select event types wanted */
  101.     XSelectInput(display, win, ExposureMask | KeyPressMask | ButtonPressMask | StructureNotifyMask);
  102.  
  103.  
  104.     load_font(&font_info);
  105.  
  106.     /* create GC for text and drawing */
  107.     getGC(win, &gc, font_info);
  108.  
  109.     /* Display window */
  110.     XMapWindow(display, win);
  111.  
  112.     /* create region for exposure event processing */
  113.     region = XCreateRegion();
  114.     printf("creating region\n");
  115.  
  116.     /* get events, use first to display text and graphics */
  117.     while (1)  {
  118.         XNextEvent(display, &report);
  119.         switch  (report.type) {
  120.         case Expose:
  121.             if (window_size == TOO_SMALL) {
  122.                 TooSmall(win, gc, font_info);
  123.                 break;
  124.             }
  125.             /* set rectangle to be exposed area */
  126.             rectangle.x = (short) report.xexpose.x;
  127.             rectangle.y = (short) report.xexpose.y;
  128.             rectangle.width = (unsigned short) report.xexpose.width;
  129.             rectangle.height = (unsigned short) report.xexpose.height;
  130.  
  131.             /* union this rect into a region */
  132.             XUnionRectWithRegion(&rectangle, region, region);
  133.             printf("adding rect to region\n");
  134.  
  135.             /* if this is the last contiguous expose
  136.              * in a group, set the clip region, clear region 
  137.              * for next time, and draw. */
  138.             if (report.xexpose.count == 0) {
  139.                 XSetRegion(display, gc, region);
  140.                 printf("setting clip region\n");
  141.                 XDestroyRegion(region);
  142.                 region = XCreateRegion();
  143.                 printf("\nclearing region for next time\n");
  144.                 /* place text in window */
  145.                 place_text(win, gc, font_info, width, height);
  146.     
  147.                 /* place graphics in window, */
  148.                 place_graphics(win, gc, width, height);
  149.             }
  150.             break;
  151.         case ConfigureNotify:
  152.             /* window has been resized, change width and
  153.              * height to send to place_text and place_graphics
  154.              * in next Expose */
  155.             width = report.xconfigure.width;
  156.             height = report.xconfigure.height;
  157.             if ((width < size_hints.min_width) || (height < size_hints.min_height))
  158.                 window_size = TOO_SMALL;
  159.             else
  160.                 window_size = BIG_ENOUGH;
  161.             break;
  162.         case ButtonPress:
  163.             /* trickle down into KeyPress (no break) */
  164.         case KeyPress:
  165.             XUnloadFont(display, font_info->fid);
  166.             XFreeGC(display, gc);
  167.             XCloseDisplay(display);
  168.             exit(1);
  169.         default:
  170.             /* all events selected by StructureNotifyMask
  171.              * except ConfigureNotify are thrown away here,
  172.              * since nothing is done with them */
  173.             break;
  174.         } /* end switch */
  175.     } /* end while */
  176. }
  177.  
  178. getGC(win, gc, font_info)
  179. Window win;
  180. GC *gc;
  181. XFontStruct *font_info;
  182. {
  183.     unsigned long valuemask = 0; /* ignore XGCvalues and use defaults */
  184.     XGCValues values;
  185.     unsigned int line_width = 6;
  186.     int line_style = LineOnOffDash;
  187.     int cap_style = CapRound;
  188.     int join_style = JoinRound;
  189.     int dash_offset = 0;
  190.     static char dash_list[] = {12, 24};
  191.     int list_length = 2;
  192.  
  193.     /* Create default Graphics Context */
  194.     *gc = XCreateGC(display, win, valuemask, &values);
  195.  
  196.     /* specify font */
  197.     XSetFont(display, *gc, font_info->fid);
  198.  
  199.     /* specify black foreground since default may be white on white */
  200.     XSetForeground(display, *gc, BlackPixel(display,screen));
  201.  
  202.     /* set line attributes */
  203.     XSetLineAttributes(display, *gc, line_width, line_style, cap_style, join_style);
  204.  
  205.     /* set dashes to be line_width in length */
  206.     XSetDashes(display, *gc, dash_offset, dash_list, list_length);
  207. }
  208.  
  209. load_font(font_info)
  210. XFontStruct **font_info;
  211. {
  212.     char *fontname = "9x15";
  213.  
  214.     /* Access font */
  215.     if ((*font_info = XLoadQueryFont(display,fontname)) == NULL)
  216.     {
  217.         (void) fprintf( stderr, "Basic: Cannot open 9x15 font\n");
  218.         exit( -1 );
  219.     }
  220. }
  221.  
  222. place_text(win, gc, font_info, win_width, win_height)
  223. Window win;
  224. GC gc;
  225. XFontStruct *font_info;
  226. unsigned int win_width, win_height;
  227. {
  228.     int y = 20;     /* offset from corner of window*/
  229.     char *string1 = "Hi! I'm a window, who are you?";
  230.     char *string2 = "To terminate program; Press any key";
  231.     char *string3 = "or button while in this window.";
  232.     char *string4 = "Screen Dimensions:";
  233.     int len1, len2, len3, len4;
  234.     int width1, width2, width3;
  235.     char cd_height[50], cd_width[50], cd_depth[50];
  236.     int font_height;
  237.     int initial_y_offset, x_offset;
  238.  
  239.  
  240.     /* need length for both XTextWidth and XDrawString */
  241.     len1 = strlen(string1);
  242.     len2 = strlen(string2);
  243.     len3 = strlen(string3);
  244.  
  245.     /* get string widths for centering */
  246.     width1 = XTextWidth(font_info, string1, len1);
  247.     width2 = XTextWidth(font_info, string2, len2);
  248.     width3 = XTextWidth(font_info, string3, len3);
  249.  
  250.     /* output text, centered on each line */
  251.     XDrawString(display,win,gc,(win_width - width1)/2,y,string1,len1);
  252.     XDrawString(display,win,gc,(win_width - width2)/2, (int)(win_height - 35),string2,len2);
  253.     XDrawString(display,win,gc,(win_width - width3)/2, (int)(win_height - 15),string3,len3);
  254.  
  255.     /* copy numbers into string variables */
  256.     (void) sprintf(cd_height, " Height - %d pixels", DisplayHeight(display,screen));
  257.     (void) sprintf(cd_width, " Width  - %d pixels", DisplayWidth(display,screen));
  258.     (void) sprintf(cd_depth, " Depth  - %d plane(s)", DefaultDepth(display, screen));
  259.  
  260.     /* reuse these for same purpose */
  261.     len4 = strlen(string4);
  262.     len1 = strlen(cd_height);
  263.     len2 = strlen(cd_width);
  264.     len3 = strlen(cd_depth);
  265.  
  266.     font_height = font_info->max_bounds.ascent + font_info->max_bounds.descent;
  267.  
  268.     /* To center strings vertically, we place the first string
  269.      * so that the top of it is two font_heights above the center
  270.      * of the window.  Since the baseline of the string is what we
  271.      * need to locate for XDrawString, and the baseline is one
  272.      * font_info->max_bounds.ascent below the top of the chacter,
  273.      * the final offset of the origin up from the center of the 
  274.      * window is one font_height + one descent. */
  275.  
  276.     initial_y_offset = win_height/2 - font_height - font_info->max_bounds.descent;
  277.     x_offset = (int) win_width/4;
  278.     XDrawString(display, win, gc, x_offset, (int) initial_y_offset, string4,len4);
  279.  
  280.     XDrawString(display, win, gc, x_offset, (int) initial_y_offset + font_height,cd_height,len1);
  281.     XDrawString(display, win, gc, x_offset, (int) initial_y_offset + 2 * font_height,cd_width,len2);
  282.     XDrawString(display, win, gc, x_offset, (int) initial_y_offset + 3 * font_height,cd_depth,len3);
  283. }
  284.  
  285.  
  286. place_graphics(win, gc, window_width, window_height)
  287. Window win;
  288. GC gc;
  289. unsigned int window_width, window_height;
  290. {
  291.     int x, y;
  292.     int width, height;
  293.  
  294.     height = window_height/2;
  295.     width = 3 * window_width/4;
  296.     x = window_width/2 - width/2;  /* center */
  297.     y = window_height/2 - height/2;
  298.     XDrawRectangle(display, win, gc, x, y, width, height);
  299. }
  300.  
  301. TooSmall(win, gc, font_info)
  302. Window win;
  303. GC gc;
  304. XFontStruct *font_info;
  305. {
  306.     char *string1 = "Too Small";
  307.     int y_offset, x_offset;
  308.  
  309.     y_offset = font_info->max_bounds.ascent + 2;
  310.     x_offset = 2;
  311.  
  312.     /* output text, centered on each line */
  313.     XDrawString(display, win, gc, x_offset, y_offset, string1, strlen(string1));
  314. }
  315.