DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T b

⟦644cf6edd⟧ TextFile

    Length: 13270 (0x33d6)
    Types: TextFile
    Names: »basicwin.c«

Derivation

└─⟦8648bda34⟧ Bits:30007244 EUUGD5_II: X11R5
    └─⟦2ca9b63e1⟧ »./contrib-1/contrib-1.00« 
        └─⟦a8392fb20⟧ 
            └─⟦this⟧ »contrib/examples/OReilly/Vol1/basicwin/popup/basicwin.c« 

TextFile

/*
 * 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/keysym.h>

#include <stdio.h>

#include "../bitmaps/icon_bitmap"
#define BITMAPDEPTH 1
#define SMALL 1
#define OK 0
#define MAX_POPUP_STRING_LENGTH 40
#define MAX_MAPPED_STRING_LENGTH 10

/* 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;

void main(argc, argv)
int argc;
char **argv;
{
	Window win;
	unsigned int width, height, x = 0, y = 0; 	/* window size and position */
	unsigned int border_width = 4;	/* four pixels */
	unsigned int display_width, display_height;
	unsigned int icon_width, icon_height;
	char *window_name = "basicwin";
	char *icon_name = "";
	Pixmap icon_pixmap;
	XSizeHints size_hints;
	XIconSize *size_list;
	int count;
	XEvent report;
	GC gc;
	XFontStruct *font_info;
	char *display_name = NULL;
	int window_size = 0;	/* OK, or too SMALL to display contents */

	/* the following are for pop-up window */
	static Window pop_win;
	char buffer[MAX_MAPPED_STRING_LENGTH];
	int bufsize=MAX_MAPPED_STRING_LENGTH;
	int start_x, start_y;
	KeySym keysym;
	XComposeStatus compose;
	int totalcount;
	unsigned int pop_width, pop_height;
	char string[MAX_POPUP_STRING_LENGTH];
	int popped = False;
	int length;

	/* added for key rebinding test */
KeySym modlist[2];   /* array of modifier keysyms */
unsigned int string_length;
unsigned int list_length;

	/* connect to X server */

	if ( (display=XOpenDisplay(display_name)) == NULL )
	{
		(void) fprintf( stderr, "basicwin: cannot connect to X server %s\n", XDisplayName(display_name));
		exit( -1 );
	}

	/* get screen size from display structure macro */
	screen = DefaultScreen(display);
	display_width = DisplayWidth(display, screen);
	display_height = DisplayHeight(display, screen);

	/* note that x and y are 0, since the default position of the window
	 * is the top left corner of the root. This is fine since the window
	 * manager often allows the user to position the window before mapping it. */

	/* size window with enough room for text */
	width = display_width/3, height = display_height/4;

	/* create opaque window */
	win = XCreateSimpleWindow(display, RootWindow(display,screen), x, y, width, height, border_width, BlackPixel(display,
	    screen), WhitePixel(display,screen));


/* map Shift-F1 to "STOP"  */
string_length = 4;
list_length = 1;
modlist[1] = XK_Shift_R;        /* Do right shift key */
XRebindKeysym(display, XK_F1, modlist, list_length, "STOP", string_length);
modlist[1] = XK_Shift_L;        /* Do left shift key */
XRebindKeysym(display, XK_F1, modlist, list_length, "STOP", string_length);

/* map Control-Shift-F1 to "ABORT"  */
string_length = 5;
list_length = 2;
modlist[1] = XK_Shift_R; modlist[2] = XK_Control_R; /* Both Right Pressed */
XRebindKeysym(display, XK_F1, modlist, list_length, "STOP", string_length);
modlist[1] = XK_Shift_L; modlist[2] = XK_Control_R; /* Left Shift, 
                                        Right Control */
XRebindKeysym(display, XK_F1, modlist, list_length, "STOP", string_length);
modlist[1] = XK_Shift_R; modlist[2] = XK_Control_L; /* Right Shift, 
                                        Left Control */
XRebindKeysym(display, XK_F1, modlist, list_length, "STOP", string_length);
modlist[1] = XK_Shift_L; modlist[2] = XK_Control_L; /* Both Left Pressed */
XRebindKeysym(display, XK_F1, modlist, list_length, "STOP", string_length);


	/* Create pixmap of depth 1 (bitmap) for icon */
	icon_pixmap = XCreateBitmapFromData(display, win, icon_bitmap_bits, icon_bitmap_width, icon_bitmap_height);

	/* Set resize hints */
	size_hints.flags = PPosition | PSize | PMinSize;
	size_hints.x = x;
	size_hints.y = y;
	size_hints.width = width;
	size_hints.height = height;
	size_hints.min_width = 300;
	size_hints.min_height = 200;

	/* set Properties for window manager (always before mapping) */
	XSetStandardProperties(display, win, window_name, icon_name, 
	    icon_pixmap, argv, argc, &size_hints);

	/* 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);

	/* Display window */
	XMapWindow(display, win);

	/* get events, use first to display text and graphics */
	while (1)  {
		XNextEvent(display, &report);
		switch  (report.type) {
		case Expose:
			printf("got expose event\n");
			if (report.xexpose.window == pop_win) {
				if (popped)
					XDrawString(display, pop_win, gc, start_x, 
						start_y, string, strlen(string));
			}
			else { /* it's the main window */
				while (XCheckTypedEvent(display, Expose, &report));
				if (window_size == SMALL)
					TooSmall(win, gc, font_info);
				else {
					/* place text in window */
					place_text(win, gc, font_info, width, height);
	
					/* place graphics in window, */
					place_graphics(win, gc, width, height);
				}
			}
			break;
		case ConfigureNotify:
			printf("got configure event\n");
			/* window has been resized, change width and
			 * height to send to place_text and place_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 = SMALL;
			else
				window_size = OK;
			break;
		case ButtonPress:
			/* put up popup window */
			if (!pop_win) {  /* create it */
			pop_width = MAX_POPUP_STRING_LENGTH * font_info->max_bounds.width + 4;
			pop_height = font_info->max_bounds.ascent + font_info->max_bounds.descent + 4;
			pop_win = XCreateSimpleWindow(display, win, x, y, pop_width, pop_height, border_width, BlackPixel(display,
	    				screen), WhitePixel(display, screen));
			/* calculate starting position of string in window (start_x, start_y) */
			start_x = 2;
			start_y = font_info->max_bounds.ascent + 2;
			XSelectInput(display, pop_win, ExposureMask | KeyPressMask);
			XMapWindow(display, pop_win);
			popped = True;
			break;
			}
			/* trickle down into KeyPress on second press (no break) */
		case KeyPress:
			if (report.xkey.window == win) {
				XUnloadFont(display, font_info->fid);
				XFreeGC(display, gc);
				XCloseDisplay(display);
				exit(1);
			}
			else {
/* pop-up a dialog box big enough for a line in specified font (which
 * was already opened).  If this is the first call of 
 * this routine, create a window of the appropriate size; if a 
 * repeat call, resize the window to accommodate the prompt 
 * and user-provided text.  Get characters until you encounter
 * a carriage return, return number of characters.  Deal with 
 * backspaces, etc.  Deal with Expose events on all windows 
 * associated with this application.  Deal with keyboard remapping. */

				count = XLookupString(&report, buffer, bufsize, &keysym, 
						&compose);
				/* now need to do the right thing with
				 * every keysym possibility, as minimum: */
				if ((keysym == XK_Return) || (keysym == XK_KP_Enter) || (keysym == XK_Linefeed)) {
					XUnmapWindow(display, pop_win);
					popped = False;
					printf("string is %s\n", string);
					break;
				}
				else if (((keysym >= XK_KP_Space) && (keysym <= XK_KP_9))
				  || ((keysym >= XK_space) && (keysym <= XK_asciitilde)))
 					{
					if (strlen(string) + strlen(buffer)
					   >= MAX_POPUP_STRING_LENGTH)
						XBell(display, 100);
					else 
						strcat(string, buffer);
					}
				else if ((keysym >= XK_Shift_L) && (keysym <= XK_Hyper_R))
					;/* do nothing because its a modifier key */
				else if ((keysym >= XK_F1) && (keysym <= XK_F35))
					if (buffer == NULL)
						printf("Unmapped function key\n");
					else if (strlen(string) + strlen(buffer)
					   >= MAX_POPUP_STRING_LENGTH)
						XBell(display, 100);
					else 
						strcat(string, buffer);
						
				else if ((keysym == XK_BackSpace) || (keysym == XK_Delete)) {
					if ((length = strlen(string)) > 0) {
						string[length - 1] = NULL;
						XClearWindow(display, pop_win);
					}
					else
						XBell(display, 100);
				}
				else {
					printf("keysym %s is not handled\n", XKeysymToString(keysym));
					XBell(display, 100);
				}
				XDrawString(display, pop_win, gc, start_x, 
					start_y, string, strlen(string));
				/* clear buffer so multi-character strings
				 * are properly supported, even though
				 * they can only be deleted on char at a
				 * time */
				buffer[1] = NULL;
				break;
			}
		case MappingNotify:
		 	XRefreshKeyboardMapping(&report);
			break;
		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 may be white on white */
	XSetForeground(display, *gc, BlackPixel(display,screen));

	/* set line attributes */
	XSetLineAttributes(display, *gc, line_width, line_style, cap_style, join_style);

	/* set dashes to be line_width in length */
	XSetDashes(display, *gc, dash_offset, dash_list, list_length);
}

load_font(font_info)
XFontStruct **font_info;
{
	char *fontname = "9x15";

	/* Access font */
	if ((*font_info = XLoadQueryFont(display,fontname)) == NULL)
	{
		(void) fprintf( stderr, "Basic: Cannot open 9x15 font\n");
		exit( -1 );
	}
}

place_text(win, gc, font_info, win_width, win_height)
Window win;
GC gc;
XFontStruct *font_info;
unsigned int win_width, win_height;
{
	int y = 20; 	/* offset from corner of window*/
	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);

	/* output text, centered on each line */
	XDrawString(display,win,gc,(win_width - width1)/2,y,string1,len1);
	XDrawString(display,win,gc,(win_width - width2)/2, (int)(win_height - 35),string2,len2);
	XDrawString(display,win,gc,(win_width - width3)/2, (int)(win_height - 15),string3,len3);

	/* copy numbers into string variables */
	(void) sprintf(cd_height, " Height - %d pixels", DisplayHeight(display,screen));
	(void) sprintf(cd_width, " Width  - %d pixels", DisplayWidth(display,screen));
	(void) sprintf(cd_depth, " Depth  - %d plane(s)", DefaultDepth(display, screen));

	/* reuse these for same purpose */
	len4 = strlen(string4);
	len1 = strlen(cd_height);
	len2 = strlen(cd_width);
	len3 = strlen(cd_depth);

	font_height = font_info->max_bounds.ascent + font_info->max_bounds.descent;

	/* 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->max_bounds.ascent below the top of the chacter,
	 * 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->max_bounds.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);
}


place_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->max_bounds.ascent + 2;
	x_offset = 2;

	/* output text, centered on each line */
	XDrawString(display, win, gc, x_offset, y_offset, string1, strlen(string1));
}