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