File:  [Research Unix] / researchv9 / X11 / src / X.V11R1 / clients / xterm / misc.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 17:40:15 2018 UTC (8 years, 1 month ago) by root
Branches: belllabs, MAIN
CVS tags: researchv9-SUN3, HEAD
researchv9-SUN3

/*
 *	$Source: /var/lib/cvsd/repos/research/researchv9/X11/src/X.V11R1/clients/xterm/misc.c,v $
 *	$Header: /var/lib/cvsd/repos/research/researchv9/X11/src/X.V11R1/clients/xterm/misc.c,v 1.1.1.2 2018/04/24 17:40:15 root Exp $
 */


#include <X11/copyright.h>

/*
 * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
 *
 *                         All Rights Reserved
 *
 * Permission to use, copy, modify, and distribute this software and its
 * documentation for any purpose and without fee is hereby granted,
 * provided that the above copyright notice appear in all copies and that
 * both that copyright notice and this permission notice appear in
 * supporting documentation, and that the name of Digital Equipment
 * Corporation not be used in advertising or publicity pertaining to
 * distribution of the software without specific, written prior permission.
 *
 *
 * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
 * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
 * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
 * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
 * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
 * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
 * SOFTWARE.
 */

#include <stdio.h>
#include <setjmp.h>
#include <signal.h>
#include <ctype.h>
#include <pwd.h>
#include <strings.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#include <X11/Xtlib.h>
#include "ptyx.h"
#include "data.h"
#include "error.h"
#include <X11/cursorfont.h>
#include "gray.ic"
#include "hilite.ic"
#include "wait.ic"
#include "waitmask.ic"

extern char *malloc();
extern char *mktemp();
extern void exit();
extern void perror();
extern void abort();

#ifndef lint
static char rcs_id[] = "$Header: /var/lib/cvsd/repos/research/researchv9/X11/src/X.V11R1/clients/xterm/misc.c,v 1.1.1.2 2018/04/24 17:40:15 root Exp $";
#endif	lint

xevents()
{
	XEvent event;
	register TScreen *screen = &term.screen;
	XtEventReturnCode returnCode;

	if(screen->scroll_amt)
		FlushScroll(screen);
	XPending (screen->display);
	do {
		if (waitingForTrackInfo)
			return;
		XNextEvent (screen->display, &event);
		returnCode = XtDispatchEvent(&event);
		switch (returnCode) {
			case XteventHandled :
				break;
			case XteventNotHandled :
/* |||
fprintf(stderr, "Event %d not handled for window %d (subwindow %d)\n",
 (int)event.type, (int)event.window, (int)event.subwindow);
*/
				break;
			case XteventNoHandler :
/* |||
fprintf(stderr, "Event %d no entry for window %d (subwindow %d)\n",
 (int)event.type, (int)event.window, (int)event.subwindow);
*/
				break;
		}
	} while (QLength(screen->display) > 0);
}

/*ARGSUSED*/
XtEventReturnCode EventDoNothing(event, eventdata)
XEvent *event;
caddr_t eventdata;
{
	return (XteventHandled);
}

/*ARGSUSED*/
XtEventReturnCode HandleKeyPressed(event, eventdata)
XEvent *event;
caddr_t eventdata;
{
	Input (&term.keyboard, &term.screen, (XKeyPressedEvent *)event);
	return (XteventHandled);
}
/*ARGSUSED*/
XtEventReturnCode HandleEnterWindow(event, eventdata)
register XEnterWindowEvent *event;
caddr_t eventdata;
{
	register TScreen *screen = &term.screen;

	if (((event->detail) != NotifyInferior)
	 && event->mode == NotifyNormal
	 && event->focus) {
#ifdef DEBUG
		if(debug)
			fprintf(stderr, "EnterWindow %s\n", window ==
			 VWindow(screen) ? "VT" : "Tek");
#endif DEBUG
		selectwindow(screen, INWINDOW);
	}
	return (XteventHandled);
}

/*ARGSUSED*/
XtEventReturnCode HandleLeaveWindow(event, eventdata)
register XEnterWindowEvent *event;
caddr_t eventdata;
{
	register TScreen *screen = &term.screen;

	if (((event->detail) != NotifyInferior)
	 && event->mode == NotifyNormal
	 && event->focus) {
#ifdef DEBUG
		if(debug)
			fprintf(stderr, "LeaveWindow %s\n", window ==
			 VWindow(screen) ? "VT" : "Tek");
#endif DEBUG
		unselectwindow(screen, INWINDOW);
	}
	return (XteventHandled);
}


/*ARGSUSED*/
XtEventReturnCode HandleFocusChange(event, eventdata)
register XFocusChangeEvent *event;
caddr_t eventdata;
{
        register TScreen *screen = &term.screen;

        if(event->type == FocusIn)
                selectwindow(screen, FOCUS);
        else
                unselectwindow(screen, FOCUS);
        return (XteventHandled);
}



selectwindow(screen, flag)
register TScreen *screen;
register int flag;
{
	if(screen->TekEmu) {
		TekSelect();
		if(!Ttoggled)
			TCursorToggle(TOGGLE);
		if(screen->cellsused) {
			screen->colorcells[2].pixel =
			 screen->Tcursorcolor;
			XStoreColor(screen->display, 
			 DefaultColormap(screen->display,
				DefaultScreen(screen->display)),
			 &screen->colorcells[2]);
		}
		screen->select |= flag;
		if(!Ttoggled)
			TCursorToggle(TOGGLE);
		return;
	} else {
		VTSelect();
		if(screen->cursor_state &&
		   (screen->cursor_col != screen->cur_col ||
		    screen->cursor_row != screen->cur_row))
		    HideCursor();
		screen->select |= flag;
		if(screen->cursor_state)
			ShowCursor();
		return;
	}
}

unselectwindow(screen, flag)
register TScreen *screen;
register int flag;
{
	register int i;

	screen->select &= ~flag;
	if(!(screen->select)) {
		if(screen->TekEmu) {
			TekUnselect();
			if(!Ttoggled)
				TCursorToggle(TOGGLE);
			if(screen->cellsused) {
				i = (term.flags & REVERSE_VIDEO) == 0;
				screen->colorcells[i].pixel =
				 screen->Tcursorcolor;
				XStoreColor(screen->display, 
			         DefaultColormap(screen->display,
					       DefaultScreen(screen->display)),
				 &screen->colorcells[i]);
			}
			if(!Ttoggled)
				TCursorToggle(TOGGLE);
		} else {
			VTUnselect();
			if(screen->cursor_state &&
			 (screen->cursor_col != screen->cur_col ||
			 screen->cursor_row != screen->cur_row))
				HideCursor();
			if(screen->cursor_state)
				ShowCursor();
		}
	}
}

reselectwindow(screen)
register TScreen *screen;
{
	Window root, win;
	int rootx, rooty, x, y;
	unsigned int mask;

	if(XQueryPointer(
	    screen->display, 
	    DefaultRootWindow(screen->display), 
	    &root, &win,
	    &rootx, &rooty,
	    &x, &y,
	    &mask)) {
		if(win && (win == VWindow(screen) || win == TWindow(screen)))
			selectwindow(screen, INWINDOW);
		else	unselectwindow(screen, INWINDOW);
	}
}

Pixmap Make_tile(width, height, bits, foreground, background, depth)
	unsigned int width, height, depth;
	Pixel foreground, background;
	char *bits;
{
	register GC gc;
	register Pixmap pix;
	register TScreen *screen = &term.screen;
	XGCValues gcVals;
	XImage tileimage;
	GC XtGetGC();

        pix = (Pixmap)XCreatePixmap(screen->display, 
	  DefaultRootWindow(screen->display), width, height, depth);
	gcVals.foreground = foreground;
	gcVals.background = background;
	gc = XCreateGC(screen->display, (Drawable) pix, 
	  GCForeground+GCBackground, &gcVals);
	tileimage.height = height;
	tileimage.width = width;
	tileimage.xoffset = 0;
	tileimage.format = XYBitmap;
	tileimage.data = bits;
	tileimage.byte_order = LSBFirst;
	tileimage.bitmap_unit = 8;
	tileimage.bitmap_bit_order = LSBFirst;
	tileimage.bitmap_pad = 8;
	tileimage.bytes_per_line = (width+7)>>3;
	tileimage.depth = 1;
        XPutImage(screen->display, pix, gc, &tileimage, 0, 0, 0, 0, width, height);
        /* done with gc */
	return(pix);
}


Pixmap make_gray(fg, bg, depth)
Pixel fg, bg;
{
	return(Make_tile(gray_width, gray_height, gray_bits, fg, bg, depth));
}

/* ARGSUSED */
Cursor make_tcross(fg, bg)
Pixel fg, bg;
{
	register TScreen *screen = &term.screen;
	Cursor c;
	
	c = XCreateFontCursor(screen->display, XC_tcross);
/*
	XRecolorCursor(screen->display, c, PixelToColor(fg), PixelToColor(bg));
*/
	return(c);
}

/* ARGSUSED */
Cursor make_xterm(fg, bg)
unsigned long fg, bg;
{
	register TScreen *screen = &term.screen;
	Cursor c;
	
	c = XCreateFontCursor(screen->display, XC_xterm);
/*
	XRecolorCursor(screen->display, c, PixelToColor(fg), PixelToColor(bg));
*/
	return(c);
}

static XColor foreground = { 0L, 65535, 65535, 65535 };
static XColor background = { 0L,    0,     0,     0 };

Cursor make_wait(fg, bg)
Pixel fg, bg;
{
	register TScreen *screen = &term.screen;
	Pixmap source, mask;

	source = Make_tile(wait_width, wait_height, wait_bits, fg, bg, 1);
	mask = Make_tile(waitmask_width, waitmask_height, waitmask_bits, 
	 fg, bg, 1);
/*
	return(XCreatePixmapCursor(screen->display, source, mask, PixelToColor(fg),
	 PixelToColor(bg), wait_x_hot, wait_y_hot));
*/
	return(XCreatePixmapCursor(screen->display, source, mask, 
	 &foreground, &background, wait_x_hot, wait_y_hot));
}

/* ARGSUSED */
Cursor make_arrow(fg, bg)
unsigned long fg, bg;

{
	register TScreen *screen = &term.screen;
	Cursor c;
	
	c = XCreateFontCursor(screen->display, XC_left_ptr);
/*
	XRecolorCursor(screen->display, c, PixelToColor(fg), PixelToColor(bg));
*/
	return(c);
}

char *uniquesuffix(name)
char *name;
{
	register int *np, *fp, i;
	register Window *cp;
	register int temp, j, k, exact, *number;
	char *wname;
	Window *children, parent, root;
	unsigned int nchildren;
	static char *suffix, sufbuf[10];
	TScreen *screen = &term.screen;
	char *malloc();

	if(suffix)
		return(suffix);
	suffix = sufbuf;
	if(!XQueryTree(
	    screen->display, 
	    DefaultRootWindow(screen->display), 
	    &root, &parent,
	    &children, &nchildren) ||
	 nchildren < 1 || (number = (int *)malloc((unsigned)nchildren * sizeof(int)))
	 == NULL)
		return(suffix);
	exact = FALSE;
	i = strlen(name);
	for(np = number, cp = children, j = nchildren ; j > 0 ; cp++, j--) {
		if(!XFetchName(screen->display, *cp, &wname) || wname == NULL)
			continue;
		if(strncmp(name, wname, i) == 0) {
			if(wname[i] == 0 || XStrCmp(&wname[i], " (Tek)") == 0)
				exact = TRUE;
			else if(strncmp(&wname[i], " #", 2) == 0)
				*np++ = atoi(&wname[i + 2]);
		}
		free(wname);
	}
	free((char *)children);
	if(exact) {
		if(np <= number)
			strcpy(suffix, " #2");
		else {
			exact = np - number;
			np = number;
			/* shell sort */
			for(i = exact / 2 ; i > 0 ; i /= 2)
				for(k = i ; k < exact ; k++)
					for(j = k - i ; j >= 0 &&
					 np[j] > np[j + i] ; j -= i) {
						temp = np[j];
						np[j] = np[j + i];
						np[j + i] = temp;
					}
			/* make numbers unique */
			for(fp = np + 1, i = exact - 1 ; i > 0 ; fp++, i--)
				if(*fp != *np)
					*++np = *fp;
			/* find least unique number */
			for(i = 2, fp = number ; fp <= np ; fp++) {
				if(i < *fp)
					break;
				if(i == *fp)
					i++;
			}
			sprintf(suffix, " #%d", i);
		}
	}
	free((char *)number);
	return(suffix);
}

Bell()
{
	extern Terminal term;
	register TScreen *screen = &term.screen;
	register Pixel xorPixel = screen->foreground ^ screen->background;
	XGCValues gcval;
	GC visualGC;

	if(screen->visualbell) {
		gcval.function = GXxor;
		gcval.foreground = xorPixel;
		visualGC = XtGetGC(screen->display, (XContext)NULL, 
		 DefaultRootWindow(screen->display),
		 GCFunction+GCForeground, &gcval);
		if(screen->TekEmu) {
			XFillRectangle(
			    screen->display,
			    TWindow(screen), 
			    visualGC,
			    0, 0,
			    (unsigned) TFullWidth(screen),
			    (unsigned) TFullHeight(screen));
			XFlush(screen->display);
			XFillRectangle(
			    screen->display,
			    TWindow(screen), 
			    visualGC,
			    0, 0,
			    (unsigned) TFullWidth(screen),
			    (unsigned) TFullHeight(screen));
		} else {
			XFillRectangle(
			    screen->display,
			    VWindow(screen), 
			    visualGC,
			    0, 0,
			    (unsigned) FullWidth(screen),
			    (unsigned) FullHeight(screen));
			XFlush(screen->display);
			XFillRectangle(
			    screen->display,
			    VWindow(screen), 
			    visualGC,
			    0, 0,
			    (unsigned) FullWidth(screen),
			    (unsigned) FullHeight(screen));
		}
	} else
		XBell(screen->display, 0);
}

Redraw()
{
	extern Terminal term;
	register TScreen *screen = &term.screen;
	XExposeEvent event;

	event.type = Expose;
	event.display = screen->display;
	event.x = 0;
	event.y = 0;
	event.width = DisplayWidth(
	  screen->display, DefaultScreen(screen->display));
	event.height =DisplayHeight(
	  screen->display, DefaultScreen(screen->display));
	event.count = 0; 
	
	if(VWindow(screen)) {
		extern XtEventReturnCode VTExpose();

	        event.window = VWindow(screen);
		(void) VTExpose(&event, (caddr_t)NULL);
		if(screen->scrollbar) {
			RedrawScrollBar(screen->scrollWindow);
		}
	}
	if(TWindow(screen) && screen->Tshow) {
	        event.window = TWindow(screen);
		TekExpose(&event);
	}
}

SyncUnmap(win, mask)
register Window win;
register long int mask;
{
	XEvent ev;
	register XEvent *rep = &ev;
	register TScreen *screen = &term.screen;

	do { /* ignore events through unmap */
		XWindowEvent(screen->display, win, mask, rep);
	} while(rep->type != UnmapNotify);
}

StartLog(screen)
register TScreen *screen;
{
	register char *cp;
	register int i;
	static char *log_default;
	char *malloc(), *rindex();
	extern logpipe();

	if(screen->logging || (screen->inhibit & I_LOG))
		return;
	if(screen->logfile == NULL || *screen->logfile == 0) {
		if(screen->logfile)
			free(screen->logfile);
		if(log_default == NULL)
			mktemp(log_default = log_def_name);
		if((screen->logfile = malloc((unsigned)strlen(log_default) + 1)) == NULL)
			return;
		strcpy(screen->logfile, log_default);
	}
	if(*screen->logfile == '|') {	/* exec command */
		int p[2];
		static char *shell;

		if(pipe(p) < 0 || (i = fork()) < 0)
			return;
		if(i == 0) {	/* child */
			close(p[1]);
			dup2(p[0], 0);
			close(p[0]);
			dup2(fileno(stderr), 1);
			dup2(fileno(stderr), 2);
			close(fileno(stderr));
			fileno(stderr) = 2;
			close(screen->display->fd);
			close(screen->respond);
			if(!shell) {
				register struct passwd *pw;
				char *getenv(), *malloc();
				struct passwd *getpwuid();

				if(((cp = getenv("SHELL")) == NULL || *cp == 0)
				 && ((pw = getpwuid(screen->uid)) == NULL ||
				 *(cp = pw->pw_shell) == 0) ||
				 (shell = malloc((unsigned) strlen(cp) + 1)) == NULL)
					shell = "/bin/sh";
				else
					strcpy(shell, cp);
			}
			signal(SIGHUP, SIG_DFL);
			signal(SIGCHLD, SIG_DFL);
			setgid(screen->gid);
			setuid(screen->uid);
			execl(shell, shell, "-c", &screen->logfile[1], 0);
			fprintf(stderr, "%s: Can't exec `%s'\n", xterm_name,
			 &screen->logfile[1]);
			exit(ERROR_LOGEXEC);
		}
		close(p[0]);
		screen->logfd = p[1];
		signal(SIGPIPE, logpipe);
	} else {
		if(access(screen->logfile, 0) == 0) {
			if(access(screen->logfile, 2) < 0)
				return;
		} else if(cp = rindex(screen->logfile, '/')) {
			*cp = 0;
			i = access(screen->logfile, 2);
			*cp = '/';
			if(i < 0)
				return;
		} else if(access(".", 2) < 0)
			return;
		if (access(screen->logfile, 0) == 0) {
			if ((screen->logfd = open(screen->logfile, 1)) < 0)
				return;
			lseek(screen->logfd, 0, 2);
		}
		else if((screen->logfd = creat(screen->logfile, 0644)) < 0)
			return;
		chown(screen->logfile, screen->uid, screen->gid);

	}
	screen->logstart = screen->TekEmu ? Tbptr : bptr;
	screen->logging = TRUE;
}

CloseLog(screen)
register TScreen *screen;
{
	if(!screen->logging || (screen->inhibit & I_LOG))
		return;
	FlushLog(screen);
	close(screen->logfd);
	screen->logging = FALSE;
}

FlushLog(screen)
register TScreen *screen;
{
	register char *cp;
	register int i;

	cp = screen->TekEmu ? Tbptr : bptr;
	if((i = cp - screen->logstart) > 0)
		write(screen->logfd, screen->logstart, i);
	screen->logstart = screen->TekEmu ? Tbuffer : buffer;
}

logpipe()
{
	register TScreen *screen = &term.screen;

	if(screen->logging)
		CloseLog(screen);
}


do_osc(func)
int (*func)();
{
	register TScreen *screen = &term.screen;
	register int mode, c;
	register char *cp;
	char buf[512];
	extern char *malloc();

	mode = 0;
	while(isdigit(c = (*func)()))
		mode = 10 * mode + (c - '0');
	cp = buf;
	while(isprint(c = (*func)()))
		*cp++ = c;
	*cp = 0;
	switch(mode) {
	 case 0:	/* new icon name and title*/
		Changename(buf);
		Changetitle(buf);
		break;

	 case 1:	/* new icon name only */
		Changename(buf);
		break;

	 case 2:	/* new title only */
		Changetitle(buf);
		break;


	 case 46:	/* new log file */
		if((cp = malloc((unsigned)strlen(buf) + 1)) == NULL)
			break;
		strcpy(cp, buf);
		if(screen->logfile)
			free(screen->logfile);
		screen->logfile = cp;
		break;
	}
}

Changename(name)
register char *name;
{
	register TScreen *screen = &term.screen;

	free(screen->iconname);
	if((screen->iconname = 
	 malloc((unsigned)(screen->iconnamelen = strlen(name)) + 1)) == NULL)
		Error(ERROR_CNMALLOC1);
	strcpy(screen->iconname, name);
	if(screen->fullVwin.window) {
		XChangeProperty(
		    screen->display,
		    VWindow(screen), 
		    XA_WM_ICON_NAME, XA_STRING,
		    8, PropModeReplace,
		    (unsigned char *)name, screen->iconnamelen);
	}
	if(screen->fullTwin.window) {
		free(screen->Ticonname);
		if((screen->Ticonname = malloc((unsigned)(screen->Ticonnamelen =
		 screen->iconnamelen + 6) + 1)) == NULL)
			Error(ERROR_CNMALLOC2);
		strcpy(screen->Ticonname, name);
		strcat(screen->Ticonname, " (Tek)");
		XChangeProperty(
		    screen->display,
		    VWindow(screen), 
		    XA_WM_ICON_NAME, XA_STRING, 8, PropModeReplace,
		    (unsigned char *)screen->Ticonname, screen->Ticonnamelen);
	}
}

Changetitle(name)
register char *name;
{
	register TScreen *screen = &term.screen;

	free(screen->titlename);
	if((screen->titlename = 
	 malloc((unsigned)(screen->titlenamelen = strlen(name)) + 1)) == NULL)
		Error(ERROR_CNMALLOC1);
	strcpy(screen->titlename, name);
	if(screen->fullVwin.window) {
		XStoreName(screen->display, VWindow(screen), name);
	}
	if(screen->fullTwin.window) {
		free(screen->Ttitlename);
		if((screen->Ttitlename = malloc((unsigned)(screen->Ttitlenamelen =
		 screen->titlenamelen + 6) + 1)) == NULL)
			Error(ERROR_CNMALLOC2);
		strcpy(screen->Ttitlename, name);
		strcat(screen->Ttitlename, " (Tek)");
		XStoreName(screen->display, TWindow(screen), screen->Ttitlename);
	}
}

#ifndef DEBUG
/* ARGSUSED */
#endif
Panic(s, a)
char	*s;
int a;
{
#ifdef DEBUG
	if(debug) {
		fprintf(stderr, "%s: PANIC!	", xterm_name);
		fprintf(stderr, s, a);
		fputs("\r\n", stderr);
		fflush(stderr);
	}
#endif DEBUG
}

SysError (i)
int i;
{
	fprintf (stderr, "%s: Error %d, errno %d:\n", xterm_name, i, errno);
	perror ("");
	Cleanup(i);
}

Error (i)
int i;
{
	fprintf (stderr, "%s: Error %d\n", xterm_name, i);
	Cleanup(i);
}

/*
 * cleanup by sending SIGHUP to client processes
 */
Cleanup (code)
int code;
{
#ifdef notdef
	extern Terminal term;
	register TScreen *screen;

	screen = &term.screen;
	if (screen->pid > 1)
		kill(-getpgrp(screen->pid), SIGHUP);
#endif
	Exit (code);
}

/*
 * sets the value of var to be arg in the Unix 4.2 BSD environment env.
 * Var should end with '=' (bindings are of the form "var=value").
 * This procedure assumes the memory for the first level of environ
 * was allocated using calloc, with enough extra room at the end so not
 * to have to do a realloc().
 */
Setenv (var, value)
register char *var, *value;
{
	extern char **environ;
	register int index = 0;
	register int len = strlen(var);

	while (environ [index] != NULL) {
	    if (strncmp (environ [index], var, len) == 0) {
		/* found it */
		environ[index] = (char *)malloc ((unsigned)len + strlen (value) + 1);
		strcpy (environ [index], var);
		strcat (environ [index], value);
		return;
	    }
	    index ++;
	}

#ifdef DEBUG
	if (debug) fputs ("expanding env\n", stderr);
#endif DEBUG

	environ [index] = (char *) malloc ((unsigned)len + strlen (value) + 1);
	(void) strcpy (environ [index], var);
	strcat (environ [index], value);
	environ [++index] = NULL;
}

/*
 * returns a pointer to the first occurrence of s2 in s1,
 * or NULL if there are none.
 */
char *strindex (s1, s2)
register char	*s1, *s2;
{
	register char	*s3;
	char		*index();

	while ((s3=index(s1, *s2)) != NULL) {
		if (strncmp(s3, s2, strlen(s2)) == 0)
			return (s3);
		s1 = ++s3;
	}
	return (NULL);
}

/*ARGSUSED*/
xerror(d, ev)
Display *d;
register XErrorEvent *ev;
{
        char buffer[BUFSIZ];
	XGetErrorText(d, ev->error_code, buffer, BUFSIZ);
	fprintf(stderr, "%s: %s\n", xterm_name, buffer);
	fprintf(stderr, "Request code %d, minor code %d, serial #%ld, resource id %ld\n",
	 ev->request_code, ev->minor_code, ev->serial, (long)ev->resourceid);
    	_cleanup();
    	abort();
/*	Exit(ERROR_XERROR); */
}

/*ARGSUSED*/
xioerror(d)
Display *d;
{
	perror(xterm_name);
	Exit(ERROR_XIOERROR);
}

XStrCmp(s1, s2)
char *s1, *s2;
{
  if (s1 && s2) return(strcmp(s1, s2));
  if (s1 && *s1) return(1);
  if (s2 && *s2) return(-1);
  return(0);
}

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.