XEmacs 21.2-b1
[chise/xemacs-chise.git.1] / etc / tests / external-widget / test-ew-xlib.c
diff --git a/etc/tests/external-widget/test-ew-xlib.c b/etc/tests/external-widget/test-ew-xlib.c
new file mode 100644 (file)
index 0000000..677f4d2
--- /dev/null
@@ -0,0 +1,361 @@
+/*
+ * Copyright 1989 O'Reilly and Associates, Inc.
+ * See ../Copyright for complete rights and liability information.
+ */
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xos.h>
+#include <X11/Xatom.h>
+
+#include <stdio.h>
+
+#define BITMAPDEPTH 1
+#define TOO_SMALL 0
+#define BIG_ENOUGH 1
+
+/* These are used as arguments to nearly every Xlib routine, so it saves 
+ * routine arguments to declare them global.  If there were 
+ * additional source files, they would be declared extern there. */
+Display *display;
+int screen_num;
+
+static char *progname; /* name this program was invoked by */
+
+void main(argc, argv)
+int argc;
+char **argv;
+{
+       Window topwin, win, win2;
+       unsigned int width, height;     /* window size */
+       int x, y;       /* window position */
+       unsigned int border_width = 4;  /* four pixels */
+       unsigned int display_width, display_height;
+       char *window_name = "Basic Window Program";
+       char *icon_name = "basicwin";
+       XSizeHints size_hints;
+       int count;
+       XEvent report;
+       GC gc;
+       XFontStruct *font_info;
+       char *display_name = NULL;
+       int window_size = BIG_ENOUGH;   /* or TOO_SMALL to display contents */
+
+       progname = argv[0];
+
+       /* connect to X server */
+       if ( (display=XOpenDisplay(display_name)) == NULL )
+       {
+               (void) fprintf( stderr, "%s: cannot connect to X server %s\n", 
+                               progname, XDisplayName(display_name));
+               exit( -1 );
+       }
+
+       /* get screen size from display structure macro */
+       screen_num = DefaultScreen(display);
+       display_width = DisplayWidth(display, screen_num);
+       display_height = DisplayHeight(display, screen_num);
+
+       /* Note that in a real application, x and y would default to 0
+        * but would be settable from the command line or resource database.  
+        */
+       x = y = 0;
+
+       /* size window with enough room for text */
+       width = display_width/2, height = display_height/3;
+
+        /* ------------------------------------------------------------ */
+
+       /* create top-level window */
+       topwin = XCreateSimpleWindow(display, RootWindow(display,screen_num), 
+                       x, y, width, 2*height, border_width,
+                       BlackPixel(display, screen_num),
+                       WhitePixel(display,screen_num));
+
+       /* Set size hints for window manager.  The window manager may
+        * override these settings.  Note that in a real
+        * application if size or position were set by the user
+        * the flags would be UPosition and USize, and these would
+        * override the window manager's preferences for this window. */
+
+       /* x, y, width, and height hints are now taken from
+        * the actual settings of the window when mapped. Note
+        * that PPosition and PSize must be specified anyway. */
+
+       size_hints.flags = PPosition | PSize | PMinSize;
+       size_hints.min_width = 300;
+       size_hints.min_height = 200;
+
+       {
+       XWMHints wm_hints;
+       XClassHint class_hints;
+
+       /* format of the window name and icon name 
+        * arguments has changed in R4 */
+       XTextProperty windowName, iconName;
+
+       /* These calls store window_name and icon_name into
+        * XTextProperty structures and set their other 
+        * fields properly. */
+       if (XStringListToTextProperty(&window_name, 1, &windowName) == 0) {
+               (void) fprintf( stderr, "%s: structure allocation for windowName failed.\n", 
+                               progname);
+               exit(-1);
+       }
+               
+       if (XStringListToTextProperty(&icon_name, 1, &iconName) == 0) {
+               (void) fprintf( stderr, "%s: structure allocation for iconName failed.\n", 
+                               progname);
+               exit(-1);
+       }
+
+       wm_hints.initial_state = NormalState;
+       wm_hints.input = True;
+       wm_hints.flags = StateHint | InputHint;
+
+       class_hints.res_name = progname;
+       class_hints.res_class = "Basicwin";
+
+       XSetWMProperties(display, topwin, &windowName, &iconName, 
+                       argv, argc, &size_hints, &wm_hints, 
+                       &class_hints);
+       }
+
+        /* ------------------------------------------------------------ */
+
+       /* create the window we're in charge of */
+
+       win = XCreateSimpleWindow(display, topwin, 
+                       x, y, width, height, border_width, BlackPixel(display,
+                       screen_num), WhitePixel(display,screen_num));
+
+       /* Select event types wanted */
+       XSelectInput(display, win, ExposureMask | KeyPressMask | 
+                       ButtonPressMask | StructureNotifyMask);
+
+       load_font(&font_info);
+
+       /* create GC for text and drawing */
+       getGC(win, &gc, font_info);
+
+        /* ------------------------------------------------------------ */
+
+       /* create the external-client window */
+
+       win2 = XCreateSimpleWindow(display, topwin, 
+                       x, y+height, width, height, border_width,
+                       BlackPixel(display, screen_num),
+                       WhitePixel(display,screen_num));
+       printf("external window: %d\n", win2);
+       ExternalClientInitialize(display, win2);
+
+        /* ------------------------------------------------------------ */
+
+       /* Display windows */
+       XMapWindow(display, topwin);
+       XMapWindow(display, win);
+       XMapWindow(display, win2);
+
+       /* get events, use first to display text and graphics */
+       while (1)  {
+               XNextEvent(display, &report);
+               if (report.xany.window == win2)
+                 ExternalClientEventHandler(display, win2, &report);
+               else
+               switch  (report.type) {
+               case Expose:
+                       /* unless this is the last contiguous expose,
+                        * don't draw the window */
+                       if (report.xexpose.count != 0)
+                               break;
+
+                       /* if window too small to use */
+                       if (window_size == TOO_SMALL)
+                               TooSmall(win, gc, font_info);
+                       else {
+                               /* place text in window */
+                               draw_text(win, gc, font_info, width, height);
+
+                               /* place graphics in window, */
+                               draw_graphics(win, gc, width, height);
+                       }
+                       break;
+               case ConfigureNotify:
+                       /* window has been resized, change width and
+                        * height to send to draw_text and draw_graphics
+                        * in next Expose */
+                       width = report.xconfigure.width;
+                       height = report.xconfigure.height;
+                       if ((width < size_hints.min_width) || 
+                                       (height < size_hints.min_height))
+                               window_size = TOO_SMALL;
+                       else
+                               window_size = BIG_ENOUGH;
+                       break;
+               case ButtonPress:
+                       /* trickle down into KeyPress (no break) */
+               case KeyPress:
+                       XUnloadFont(display, font_info->fid);
+                       XFreeGC(display, gc);
+                       XCloseDisplay(display);
+                       exit(1);
+               default:
+                       /* all events selected by StructureNotifyMask
+                        * except ConfigureNotify are thrown away here,
+                        * since nothing is done with them */
+                       break;
+               } /* end switch */
+       } /* end while */
+}
+
+getGC(win, gc, font_info)
+Window win;
+GC *gc;
+XFontStruct *font_info;
+{
+       unsigned long valuemask = 0; /* ignore XGCvalues and use defaults */
+       XGCValues values;
+       unsigned int line_width = 6;
+       int line_style = LineOnOffDash;
+       int cap_style = CapRound;
+       int join_style = JoinRound;
+       int dash_offset = 0;
+       static char dash_list[] = {12, 24};
+       int list_length = 2;
+
+       /* Create default Graphics Context */
+       *gc = XCreateGC(display, win, valuemask, &values);
+
+       /* specify font */
+       XSetFont(display, *gc, font_info->fid);
+
+       /* specify black foreground since default window background is 
+        * white and default foreground is undefined. */
+       XSetForeground(display, *gc, BlackPixel(display,screen_num));
+
+       /* set line attributes */
+       XSetLineAttributes(display, *gc, line_width, line_style, 
+                       cap_style, join_style);
+
+       /* set dashes */
+       XSetDashes(display, *gc, dash_offset, dash_list, list_length);
+}
+
+load_font(font_info)
+XFontStruct **font_info;
+{
+       char *fontname = "9x15";
+
+       /* Load font and get font information structure. */
+       if ((*font_info = XLoadQueryFont(display,fontname)) == NULL)
+       {
+               (void) fprintf( stderr, "%s: Cannot open 9x15 font\n", 
+                               progname);
+               exit( -1 );
+       }
+}
+
+draw_text(win, gc, font_info, win_width, win_height)
+Window win;
+GC gc;
+XFontStruct *font_info;
+unsigned int win_width, win_height;
+{
+       char *string1 = "Hi! I'm a window, who are you?";
+       char *string2 = "To terminate program; Press any key";
+       char *string3 = "or button while in this window.";
+       char *string4 = "Screen Dimensions:";
+       int len1, len2, len3, len4;
+       int width1, width2, width3;
+       char cd_height[50], cd_width[50], cd_depth[50];
+       int font_height;
+       int initial_y_offset, x_offset;
+
+
+       /* need length for both XTextWidth and XDrawString */
+       len1 = strlen(string1);
+       len2 = strlen(string2);
+       len3 = strlen(string3);
+
+       /* get string widths for centering */
+       width1 = XTextWidth(font_info, string1, len1);
+       width2 = XTextWidth(font_info, string2, len2);
+       width3 = XTextWidth(font_info, string3, len3);
+
+       font_height = font_info->ascent + font_info->descent;
+
+       /* output text, centered on each line */
+       XDrawString(display, win, gc, (win_width - width1)/2, 
+                       font_height,
+                       string1, len1);
+       XDrawString(display, win, gc, (win_width - width2)/2, 
+                       (int)(win_height - (2 * font_height)),
+                       string2, len2);
+       XDrawString(display, win, gc, (win_width - width3)/2, 
+                       (int)(win_height - font_height),
+                       string3, len3);
+
+       /* copy numbers into string variables */
+       (void) sprintf(cd_height, " Height - %d pixels", 
+                       DisplayHeight(display,screen_num));
+       (void) sprintf(cd_width, " Width  - %d pixels", 
+                       DisplayWidth(display,screen_num));
+       (void) sprintf(cd_depth, " Depth  - %d plane(s)", 
+                       DefaultDepth(display, screen_num));
+
+       /* reuse these for same purpose */
+       len4 = strlen(string4);
+       len1 = strlen(cd_height);
+       len2 = strlen(cd_width);
+       len3 = strlen(cd_depth);
+
+       /* To center strings vertically, we place the first string
+        * so that the top of it is two font_heights above the center
+        * of the window.  Since the baseline of the string is what we
+        * need to locate for XDrawString, and the baseline is one
+        * font_info->ascent below the top of the character,
+        * the final offset of the origin up from the center of the 
+        * window is one font_height + one descent. */
+
+       initial_y_offset = win_height/2 - font_height - font_info->descent;
+       x_offset = (int) win_width/4;
+       XDrawString(display, win, gc, x_offset, (int) initial_y_offset, 
+                       string4,len4);
+
+       XDrawString(display, win, gc, x_offset, (int) initial_y_offset + 
+                       font_height,cd_height,len1);
+       XDrawString(display, win, gc, x_offset, (int) initial_y_offset + 
+                       2 * font_height,cd_width,len2);
+       XDrawString(display, win, gc, x_offset, (int) initial_y_offset + 
+                       3 * font_height,cd_depth,len3);
+}
+
+draw_graphics(win, gc, window_width, window_height)
+Window win;
+GC gc;
+unsigned int window_width, window_height;
+{
+       int x, y;
+       int width, height;
+
+       height = window_height/2;
+       width = 3 * window_width/4;
+       x = window_width/2 - width/2;  /* center */
+       y = window_height/2 - height/2;
+       XDrawRectangle(display, win, gc, x, y, width, height);
+}
+
+TooSmall(win, gc, font_info)
+Window win;
+GC gc;
+XFontStruct *font_info;
+{
+       char *string1 = "Too Small";
+       int y_offset, x_offset;
+
+       y_offset = font_info->ascent + 2;
+       x_offset = 2;
+
+       /* output text, centered on each line */
+       XDrawString(display, win, gc, x_offset, y_offset, string1, 
+                       strlen(string1));
+}