diff etc/tests/external-widget/test-ew-xlib.c @ 2:ac2d302a0011 r19-15b2

Import from CVS: tag r19-15b2
author cvs
date Mon, 13 Aug 2007 08:46:35 +0200
parents
children 03ab78e48ef6
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/etc/tests/external-widget/test-ew-xlib.c	Mon Aug 13 08:46:35 2007 +0200
@@ -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));
+}