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