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 / attribs / basicwin.c next >
C/C++ Source or Header  |  1990-08-08  |  11KB  |  371 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. #include <X11/Xatom.h>
  9.  
  10. #include <stdio.h>
  11.  
  12. #include "../bitmaps/icon_bitmap"
  13.  
  14. #define BITMAPDEPTH 1
  15. #define TOO_SMALL 0
  16. #define BIG_ENOUGH 1
  17.  
  18. /* These are used as arguments to nearly every Xlib routine, so it saves 
  19.  * routine arguments to declare them global.  If there were 
  20.  * additional source files, they would be declared extern there. */
  21. Display *display;
  22. int screen_num;
  23.  
  24. static char *progname; /* name this program was invoked by */
  25.  
  26. void main(argc, argv)
  27. int argc;
  28. char **argv;
  29. {
  30.     Window win, wint;
  31.     unsigned int width, height;    /* window size */
  32.     int x, y;     /* window position */
  33.     unsigned int border_width = 4;    /* four pixels */
  34.     unsigned int display_width, display_height;
  35.     unsigned int icon_width, icon_height;
  36.     char *window_name = "Basic Window Program";
  37.     char *icon_name = "basicwin";
  38.     Pixmap icon_pixmap;
  39.     XSizeHints size_hints;
  40.     XIconSize *size_list;
  41.     int count;
  42.     XEvent report;
  43.     GC gc;
  44.     XFontStruct *font_info;
  45.     char *display_name = NULL;
  46.     int window_size = BIG_ENOUGH;    /* or TOO_SMALL to display contents */
  47.         XSetWindowAttributes attrib;
  48.         unsigned long valuemask;
  49.  
  50.  
  51.     progname = argv[0];
  52.  
  53.     /* connect to X server */
  54.     if ( (display=XOpenDisplay(display_name)) == NULL )
  55.     {
  56.         (void) fprintf( stderr, "%s: cannot connect to X server %s\n", 
  57.                 progname, XDisplayName(display_name));
  58.         exit( -1 );
  59.     }
  60.  
  61.     /* get screen size from display structure macro */
  62.     screen_num = DefaultScreen(display);
  63.     display_width = DisplayWidth(display, screen_num);
  64.     display_height = DisplayHeight(display, screen_num);
  65.  
  66.     /* Note that in a real application, x and y would default to 0
  67.      * but would be settable from the command line or resource database.  
  68.      */
  69.     x = y = 0;
  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_num), 
  76.             x, y, width, height, border_width, BlackPixel(display,
  77.             screen_num), WhitePixel(display,screen_num));
  78.  
  79.         attrib.background_pixmap = ParentRelative;
  80.         valuemask = CWBackPixmap;
  81.         XChangeWindowAttributes(display, win, valuemask, &attrib);
  82.  
  83.         attrib.win_gravity = NorthEastGravity;
  84.         attrib.background_pixmap = None;
  85.         valuemask = CWWinGravity | CWBackPixmap;
  86.         wint = XCreateSimpleWindow(display, win, 2 * width/3,0, width/3,
  87.         height/3, border_width, BlackPixel(display,screen_num), 
  88.         WhitePixel(display,screen_num));
  89.  
  90.         XChangeWindowAttributes(display, wint, valuemask, &attrib);
  91.  
  92.     /* Create pixmap of depth 1 (bitmap) for icon */
  93.     icon_pixmap = XCreateBitmapFromData(display, win, icon_bitmap_bits, 
  94.             icon_bitmap_width, icon_bitmap_height);
  95.  
  96.     /* Set size hints for window manager.  The window manager may
  97.      * override these settings.  Note that in a real
  98.      * application if size or position were set by the user
  99.      * the flags would be UPosition and USize, and these would
  100.      * override the window manager's preferences for this window. */
  101.  
  102. #ifdef X11R3
  103.     size_hints.flags = PPosition | PSize | PMinSize;
  104.     size_hints.x = x;
  105.     size_hints.y = y;
  106.     size_hints.width = width;
  107.     size_hints.height = height;
  108.     size_hints.min_width = 300;
  109.     size_hints.min_height = 200;
  110.  
  111. #else /* X11R4 or later */
  112.     /* x, y, width, and height hints are now taken from
  113.      * the actual settings of the window when mapped. Note
  114.      * that PPosition and PSize must be specified anyway. */
  115.     size_hints.flags = PPosition | PSize | PMinSize;
  116.     size_hints.min_width = 300;
  117.     size_hints.min_height = 200;
  118. #endif
  119.  
  120. #ifdef X11R3
  121.     /* set Properties for window manager (always before mapping) */
  122.     XSetStandardProperties(display, win, window_name, icon_name, 
  123.             icon_pixmap, argv, argc, &size_hints);
  124.  
  125. #else /* X11R4 or later */
  126.     {
  127.     XWMHints wm_hints;
  128.     XClassHint class_hints;
  129.  
  130.     /* format of the window name and icon name 
  131.      * arguments has changed in R4 */
  132.     XTextProperty windowName, iconName;
  133.     /* These calls store window_name and icon_name into
  134.      * XTextProperty structures and set their other 
  135.      * fields properly. */
  136.     if (XStringListToTextProperty(&window_name, 1, &windowName) == 0) {
  137.         (void) fprintf( stderr, "%s: structure allocation for windowName failed.\n", 
  138.                 progname);
  139.         exit(-1);
  140.     }
  141.         
  142.     if (XStringListToTextProperty(&icon_name, 1, &iconName) == 0) {
  143.         (void) fprintf( stderr, "%s: structure allocation for iconName failed.\n", 
  144.                 progname);
  145.         exit(-1);
  146.     }
  147.  
  148.     wm_hints.initial_state = NormalState;
  149.     wm_hints.input = True;
  150.     wm_hints.icon_pixmap = icon_pixmap;
  151.     wm_hints.flags = StateHint | IconPixmapHint | InputHint;
  152.  
  153.     class_hints.res_name = progname;
  154.     class_hints.res_class = "Basicwin";
  155.  
  156.     XSetWMProperties(display, win, &windowName, &iconName, 
  157.             argv, argc, &size_hints, &wm_hints, 
  158.             &class_hints);
  159.     }
  160. #endif
  161.  
  162.     /* Select event types wanted */
  163.     XSelectInput(display, win, ExposureMask | KeyPressMask | 
  164.             ButtonPressMask | StructureNotifyMask);
  165.  
  166.  
  167.     load_font(&font_info);
  168.  
  169.     /* create GC for text and drawing */
  170.     getGC(win, &gc, font_info);
  171.  
  172.     /* Display window */
  173.     XMapWindow(display, win);
  174.     XMapWindow(display, wint);
  175.  
  176.     /* get events, use first to display text and graphics */
  177.     while (1)  {
  178.         XNextEvent(display, &report);
  179.         switch  (report.type) {
  180.         case Expose:
  181.             /* unless this is the last contiguous expose,
  182.              * don't draw the window */
  183.             if (report.xexpose.count != 0)
  184.                 break;
  185.  
  186.             /* if window too small to use */
  187.             if (window_size == TOO_SMALL)
  188.                 TooSmall(win, gc, font_info);
  189.             else {
  190.                 /* place text in window */
  191.                 draw_text(win, gc, font_info, width, height);
  192.  
  193.                 /* place graphics in window, */
  194.                 draw_graphics(win, gc, width, height);
  195.             }
  196.             break;
  197.         case ConfigureNotify:
  198.             /* window has been resized, change width and
  199.              * height to send to draw_text and draw_graphics
  200.              * in next Expose */
  201.             width = report.xconfigure.width;
  202.             height = report.xconfigure.height;
  203.             if ((width < size_hints.min_width) || 
  204.                     (height < size_hints.min_height))
  205.                 window_size = TOO_SMALL;
  206.             else
  207.                 window_size = BIG_ENOUGH;
  208.             break;
  209.         case ButtonPress:
  210.             /* trickle down into KeyPress (no break) */
  211.         case KeyPress:
  212.             XUnloadFont(display, font_info->fid);
  213.             XFreeGC(display, gc);
  214.             XCloseDisplay(display);
  215.             exit(1);
  216.         default:
  217.             /* all events selected by StructureNotifyMask
  218.              * except ConfigureNotify are thrown away here,
  219.              * since nothing is done with them */
  220.             break;
  221.         } /* end switch */
  222.     } /* end while */
  223. }
  224.  
  225. getGC(win, gc, font_info)
  226. Window win;
  227. GC *gc;
  228. XFontStruct *font_info;
  229. {
  230.     unsigned long valuemask = 0; /* ignore XGCvalues and use defaults */
  231.     XGCValues values;
  232.     unsigned int line_width = 6;
  233.     int line_style = LineOnOffDash;
  234.     int cap_style = CapRound;
  235.     int join_style = JoinRound;
  236.     int dash_offset = 0;
  237.     static char dash_list[] = {12, 24};
  238.     int list_length = 2;
  239.  
  240.     /* Create default Graphics Context */
  241.     *gc = XCreateGC(display, win, valuemask, &values);
  242.  
  243.     /* specify font */
  244.     XSetFont(display, *gc, font_info->fid);
  245.  
  246.     /* specify black foreground since default window background is 
  247.      * white and default foreground is undefined. */
  248.     XSetForeground(display, *gc, BlackPixel(display,screen_num));
  249.  
  250.     /* set line attributes */
  251.     XSetLineAttributes(display, *gc, line_width, line_style, 
  252.             cap_style, join_style);
  253.  
  254.     /* set dashes */
  255.     XSetDashes(display, *gc, dash_offset, dash_list, list_length);
  256. }
  257.  
  258. load_font(font_info)
  259. XFontStruct **font_info;
  260. {
  261.     char *fontname = "9x15";
  262.  
  263.     /* Load font and get font information structure. */
  264.     if ((*font_info = XLoadQueryFont(display,fontname)) == NULL)
  265.     {
  266.         (void) fprintf( stderr, "%s: Cannot open 9x15 font\n", 
  267.                 progname);
  268.         exit( -1 );
  269.     }
  270. }
  271.  
  272. draw_text(win, gc, font_info, win_width, win_height)
  273. Window win;
  274. GC gc;
  275. XFontStruct *font_info;
  276. unsigned int win_width, win_height;
  277. {
  278.     char *string1 = "Hi! I'm a window, who are you?";
  279.     char *string2 = "To terminate program; Press any key";
  280.     char *string3 = "or button while in this window.";
  281.     char *string4 = "Screen Dimensions:";
  282.     int len1, len2, len3, len4;
  283.     int width1, width2, width3;
  284.     char cd_height[50], cd_width[50], cd_depth[50];
  285.     int font_height;
  286.     int initial_y_offset, x_offset;
  287.  
  288.  
  289.     /* need length for both XTextWidth and XDrawString */
  290.     len1 = strlen(string1);
  291.     len2 = strlen(string2);
  292.     len3 = strlen(string3);
  293.  
  294.     /* get string widths for centering */
  295.     width1 = XTextWidth(font_info, string1, len1);
  296.     width2 = XTextWidth(font_info, string2, len2);
  297.     width3 = XTextWidth(font_info, string3, len3);
  298.  
  299.     font_height = font_info->ascent + font_info->descent;
  300.  
  301.     /* output text, centered on each line */
  302.     XDrawString(display,win,gc,(win_width - width1)/2, font_height, string1, len1);
  303.     XDrawString(display,win,gc,(win_width - width2)/2, (int)(win_height - 35),string2,len2);
  304.     XDrawString(display,win,gc,(win_width - width3)/2, (int)(win_height - 15),string3,len3);
  305.  
  306.     /* copy numbers into string variables */
  307.     (void) sprintf(cd_height, " Height - %d pixels", 
  308.             DisplayHeight(display,screen_num));
  309.     (void) sprintf(cd_width, " Width  - %d pixels", 
  310.             DisplayWidth(display,screen_num));
  311.     (void) sprintf(cd_depth, " Depth  - %d plane(s)", 
  312.             DefaultDepth(display, screen_num));
  313.  
  314.     /* reuse these for same purpose */
  315.     len4 = strlen(string4);
  316.     len1 = strlen(cd_height);
  317.     len2 = strlen(cd_width);
  318.     len3 = strlen(cd_depth);
  319.  
  320.     /* To center strings vertically, we place the first string
  321.      * so that the top of it is two font_heights above the center
  322.      * of the window.  Since the baseline of the string is what we
  323.      * need to locate for XDrawString, and the baseline is one
  324.      * font_info->ascent below the top of the character,
  325.      * the final offset of the origin up from the center of the 
  326.      * window is one font_height + one descent. */
  327.  
  328.     initial_y_offset = win_height/2 - font_height - font_info->descent;
  329.     x_offset = (int) win_width/4;
  330.     XDrawString(display, win, gc, x_offset, (int) initial_y_offset, 
  331.             string4,len4);
  332.  
  333.     XDrawString(display, win, gc, x_offset, (int) initial_y_offset + 
  334.             font_height,cd_height,len1);
  335.     XDrawString(display, win, gc, x_offset, (int) initial_y_offset + 
  336.             2 * font_height,cd_width,len2);
  337.     XDrawString(display, win, gc, x_offset, (int) initial_y_offset + 
  338.             3 * font_height,cd_depth,len3);
  339. }
  340.  
  341. draw_graphics(win, gc, window_width, window_height)
  342. Window win;
  343. GC gc;
  344. unsigned int window_width, window_height;
  345. {
  346.     int x, y;
  347.     int width, height;
  348.  
  349.     height = window_height/2;
  350.     width = 3 * window_width/4;
  351.     x = window_width/2 - width/2;  /* center */
  352.     y = window_height/2 - height/2;
  353.     XDrawRectangle(display, win, gc, x, y, width, height);
  354. }
  355.  
  356. TooSmall(win, gc, font_info)
  357. Window win;
  358. GC gc;
  359. XFontStruct *font_info;
  360. {
  361.     char *string1 = "Too Small";
  362.     int y_offset, x_offset;
  363.  
  364.     y_offset = font_info->ascent + 2;
  365.     x_offset = 2;
  366.  
  367.     /* output text, centered on each line */
  368.     XDrawString(display, win, gc, x_offset, y_offset, string1, 
  369.             strlen(string1));
  370. }
  371.