xse - An interface to XSendEvent() part03/03 REPOST

George Ferguson ferguson at cs.rochester.edu
Fri Aug 17 05:38:18 AEST 1990


#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 3 (of 3)."
# Contents:  parse.c
# Wrapped by ferguson at swan.cs.rochester.edu on Thu Aug 16 15:18:00 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'parse.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'parse.c'\"
else
echo shar: Extracting \"'parse.c'\" \(20674 characters\)
sed "s/^X//" >'parse.c' <<'END_OF_FILE'
X/*
X *	parse.c - Parse event specifications (see Xt manual, appendix B)
X *
X *	George Ferguson, ferguson at cs.rochester.edu, 1 Jun 1990.
X *
X *	$Id: parse.c,v 1.4 90/08/15 11:32:19 ferguson Exp $
X *
X */
X
X#include <stdio.h>
X#include <ctype.h>
X#include <string.h>
X#include <X11/Xlib.h>
X#include <X11/keysym.h>
X#include "parse.h"
Xextern Display *display;
Xextern Window root;
X
X/*
X * Functions defined
X */
Xchar *parseEventList();
Xvoid freeEventList();
Xstatic char *parseEvent(),*parseMods(),*parseType(),*parseDetail();
Xstatic unsigned int lookup();
Xstatic void parseError();
X
X#define SKIPWHITE(S)	while (isspace(*(S))) (S) += 1
X
X/*
X * Text to value mappings
X */
Xtypedef struct {
X        char *name;
X        unsigned int value;
X} NameValue;
X
Xstatic NameValue booleans[] = {
X    {"True",	True},
X    {"False",	False},
X    {"On",	True},
X    {"Off",	False},
X    {NULL,	0},
X};
X
Xstatic NameValue modifiers[] = {
X    {"None",	None},
X    {"Shift",	ShiftMask},
X    {"Lock",	LockMask},
X    {"Ctrl",	ControlMask},
X    {"Mod1",	Mod1Mask},
X    {"Mod2",	Mod2Mask},
X    {"Mod3",	Mod3Mask},
X    {"Mod4",	Mod4Mask},
X    {"Mod5",	Mod5Mask},
X    {"Meta",	XK_Meta_L},
X    {"m",	XK_Meta_L},
X    {"h",	XK_Hyper_L},
X    {"su",	XK_Super_L},
X    {"a",	XK_Alt_L},
X    {"Hyper",	XK_Hyper_L},
X    {"Super",	XK_Super_L},
X    {"Alt",	XK_Alt_L},
X    {"Button1",	Button1Mask},
X    {"Button2",	Button2Mask},
X    {"Button3",	Button3Mask},
X    {"Button4",	Button4Mask},
X    {"Button5",	Button5Mask},
X    {"Any",	AnyModifier},
X    {"c",	ControlMask},
X    {"s",	ShiftMask},
X    {"l",	LockMask},
X    {NULL,	0},
X};
X
Xstatic NameValue buttonNames[] = {
X    {"Button1",	Button1},
X    {"Button2", Button2},
X    {"Button3", Button3},
X    {"Button4", Button4},
X    {"Button5", Button5},
X    {NULL,	0},
X};
X
Xstatic NameValue motionDetails[] = {
X    {"Normal",	NotifyNormal},
X    {"Hint",	NotifyHint},
X    {NULL,	0},
X};
X
Xstatic NameValue notifyModes[] = {
X    {"Normal",		NotifyNormal},
X    {"Grab",		NotifyGrab},
X    {"Ungrab",		NotifyUngrab},
X    {"WhileGrabbed",    NotifyWhileGrabbed},
X    {NULL,		0},
X};
X
Xstatic NameValue notifyDetails[] = {
X    {"Ancestor",	NotifyAncestor},
X    {"Virtual",		NotifyVirtual},
X    {"Inferior",	NotifyInferior},
X    {"Nonlinear",	NotifyNonlinear},
X    {"NonlinearVirtual",NotifyNonlinearVirtual},
X    {"Pointer",		NotifyPointer},
X    {"PointerRoot",	NotifyPointerRoot},
X    {"DetailNone",	NotifyDetailNone},
X    {NULL,		0},
X};
X
Xstatic NameValue circulateDetails[] = {
X    {"PlaceOnTop",	PlaceOnTop},
X    {"OnTop",		PlaceOnTop},
X    {"PlaceOnBottom", 	PlaceOnBottom},
X    {"OnBottom", 	PlaceOnBottom},
X    {NULL,		0},
X};
X
Xstatic NameValue mappingDetails[] = {
X    {"Modifier",	MappingModifier},
X    {"Keyboard",	MappingKeyboard},
X    {"Pointer",		MappingPointer},
X    {NULL,		0},
X};
X
Xstatic NameValue visibilityDetails[] = {
X    {"Unobscured",	 VisibilityUnobscured},
X    {"PartiallyObscured",VisibilityPartiallyObscured},
X    {"FullyObscured",    VisibilityFullyObscured},
X    {NULL,		0},
X};
X
Xstatic NameValue propertyDetails[] = {
X    {"NewValue",	PropertyNewValue},
X    {"Delete",		PropertyDelete},
X    {NULL,		0},
X};
X
Xtypedef struct {
X        char *name;
X        unsigned int value;
X        unsigned int mods;
X        unsigned int detail;
X} NameValueModsDetail;
X
Xstatic NameValueModsDetail types[] = {
X{"KeyPress",	     KeyPress,	 0,		0},
X{"Key", 	     KeyPress,	 0,		0},
X{"KeyDown",	     KeyPress,	 0,		0},
X{"Ctrl",             KeyPress,   ControlMask,	0},
X{"Shift",            KeyPress,   ShiftMask,	0},
X{"Meta",             KeyPress,   0,		0},
X{"KeyUp",	     KeyRelease, 0,		0},
X{"KeyRelease",	     KeyRelease, 0,		0},
X{"ButtonPress",      ButtonPress, 0,	0},
X{"BtnDown",	     ButtonPress, 0,	0},
X{"Btn1Down",	     ButtonPress, 0,	Button1},
X{"Btn2Down", 	     ButtonPress, 0,	Button2},
X{"Btn3Down", 	     ButtonPress, 0,	Button3},
X{"Btn4Down", 	     ButtonPress, 0,	Button4},
X{"Btn5Down", 	     ButtonPress, 0,	Button5},
X{"ButtonRelease",    ButtonRelease, 0,	0},
X{"BtnUp", 	     ButtonRelease, 0,	0},
X{"Btn1Up", 	     ButtonRelease, 0,	Button1},
X{"Btn2Up", 	     ButtonRelease, 0,	Button2},
X{"Btn3Up", 	     ButtonRelease, 0,	Button3},
X{"Btn4Up", 	     ButtonRelease, 0,	Button4},
X{"Btn5Up", 	     ButtonRelease, 0,	Button5},
X{"MotionNotify",     MotionNotify, 0,			0},
X{"PtrMoved", 	     MotionNotify, 0,			0},
X{"Motion", 	     MotionNotify, 0,			0},
X{"MouseMoved", 	     MotionNotify, 0,			0},
X{"BtnMotion",        MotionNotify, 0,			0},
X{"Btn1Motion",       MotionNotify, Button1Mask,		0},
X{"Btn2Motion",       MotionNotify, Button2Mask,		0},
X{"Btn3Motion",       MotionNotify, Button3Mask,		0},
X{"Btn4Motion",       MotionNotify, Button4Mask,		0},
X{"Btn5Motion",       MotionNotify, Button5Mask,		0},
X{"EnterNotify",      EnterNotify, 0, 0},
X{"Enter",	     EnterNotify, 0, 0},
X{"EnterWindow",      EnterNotify, 0, 0},
X{"LeaveNotify",      LeaveNotify, 0, 0},
X{"LeaveWindow",      LeaveNotify, 0, 0},
X{"Leave",	     LeaveNotify, 0, 0},
X{"FocusIn",	     FocusIn,  0, 0},
X{"FocusOut",	     FocusOut, 0, 0},
X{"KeymapNotify",     KeymapNotify, 0, 0},
X{"Keymap",	     KeymapNotify, 0, 0},
X{"Expose", 	     Expose, 0, 0},
X{"GraphicsExpose",   GraphicsExpose, 0, 0},
X{"GrExp",	     GraphicsExpose, 0, 0},
X{"NoExpose",	     NoExpose, 0, 0},
X{"NoExp",	     NoExpose, 0, 0},
X{"VisibilityNotify", VisibilityNotify, 0, 0},
X{"Visible",	     VisibilityNotify, 0, 0},
X{"CreateNotify",     CreateNotify, 0, 0},
X{"Create",	     CreateNotify, 0, 0},
X{"DestroyNotify",    DestroyNotify, 0, 0},
X{"Destroy",	     DestroyNotify, 0, 0},
X{"UnmapNotify",      UnmapNotify, 0, 0},
X{"Unmap",	     UnmapNotify, 0, 0},
X{"MapNotify",	     MapNotify,	0, 0},
X{"Map",		     MapNotify,	0, 0},
X{"MapRequest",	     MapRequest, 0, 0},
X{"MapReq",	     MapRequest, 0, 0},
X{"ReparentNotify",   ReparentNotify, 0, 0},
X{"Reparent",	     ReparentNotify, 0, 0},
X{"ConfigureNotify",  ConfigureNotify, 0, 0},
X{"Configure",	     ConfigureNotify, 0, 0},
X{"ConfigureRequest", ConfigureRequest, 0, 0},
X{"ConfigureReq",     ConfigureRequest, 0, 0},
X{"GravityNotify",    GravityNotify, 0, 0},
X{"Grav",	     GravityNotify, 0, 0},
X{"ResizeRequest",    ResizeRequest, 0, 0},
X{"ResReq",	     ResizeRequest, 0, 0},
X{"CirculateNotify",  CirculateNotify, 0, 0},
X{"Circ",	     CirculateNotify, 0, 0},
X{"CirculateRequest", CirculateRequest, 0, 0},
X{"CircReq",	     CirculateRequest, 0, 0},
X{"PropertyNotify",   PropertyNotify, 0, 0},
X{"Prop",	     PropertyNotify, 0, 0},
X{"SelectionClear",   SelectionClear, 0, 0},
X{"SelClr",	     SelectionClear, 0, 0},
X{"SelectionRequest", SelectionRequest, 0, 0},
X{"SelReq",	     SelectionRequest, 0, 0},
X{"SelectionNotify",  SelectionNotify, 0, 0},
X{"Select",	     SelectionNotify, 0, 0},
X{"ColormapNotify",   ColormapNotify, 0, 0},
X{"Clrmap",	     ColormapNotify, 0, 0},
X{"ClientMessage",    ClientMessage, 0, 0},
X{"Message",	     ClientMessage, 0, 0},
X{"MappingNotify",    MappingNotify, 0, 0},
X{"Mapping",	     MappingNotify, 0, 0},
X{NULL,		     0, 0, 0}
X};
X
X/*	-	-	-	-	-	-	-	-	*/
X
Xstatic unsigned int
Xlookup(table,name)
XNameValue *table;
Xchar *name;
X{
X    while (table->name != NULL && strcasecmp(name,table->name) != 0)
X	table += 1;
X    return(table->value);
X}
X
Xchar *
XparseEventList(str,evp)
Xchar *str;
XEventListPtr *evp;
X{
X    EventListPtr ev,end;
X
X    *evp == NULL;
X    while (*str) {
X	str = parseEvent(str,&ev);
X	if (ev != NULL)
X	    if (*evp == NULL)
X		end = *evp = ev;
X	    else
X		end = end->next = ev;	/* wow! */
X	else
X	    return(str);
X	if (*str && *str != ',') {
X	    parseError("',' expected",str);
X	    return(str);
X	} else if (*str)
X	   str += 1;		/* skip comma */
X    }
X    return(str);
X}
X
Xstatic char *
XparseEvent(str,evp)
Xchar *str;
XEventListPtr *evp;
X{
X    unsigned int mods;
X    int type,count;
X    unsigned int detail;
X
X    str = parseMods(str,&mods);
X    SKIPWHITE(str);
X    if (*str != '<') {
X	parseError("'<' expected",str);
X	return(str);
X    } else
X	str += 1;
X    str = parseType(str,&type,&mods,&detail);
X    if (*str != '>') {
X	parseError("'>' expected",str);
X	return(str);
X    } else
X	str += 1;
X    SKIPWHITE(str);
X    count = 1;		/* default */
X    if (*str == '(') {
X	str += 1;
X	count = (int)strtol(str,&str,0);
X	if (count == 0) {
X	    parseError("count expected",str);
X	    return(str);
X	}
X	if (*str != ')')  {
X	    parseError("')' expected",str);
X	    return(str);
X	} else
X	    str += 1;
X    }
X    SKIPWHITE(str);
X    *evp = (EventListElem *)malloc(sizeof(EventListElem)); 
X    (*evp)->count = count;
X    (*evp)->next = NULL;
X    str = parseDetail(str,&((*evp)->event),type,mods,detail);
X    return(str);
X}
X
Xstatic char *
XparseMods(str,modsp)
Xchar *str;
Xunsigned int *modsp;
X{
X    char modstr[32];
X    int i;
X    unsigned int m;
X
X    *modsp = (unsigned int)0;
X    while (*str && *str != '<') {
X	SKIPWHITE(str);
X	i = 0;
X	while (isalnum(*str) && i < 30)
X	    modstr[i++] = *str++;
X	if (i == 31)
X	    parseError("modifier name too long",str);
X	modstr[i] = '\0';
X	if ((m=lookup(modifiers,modstr)) == 0)
X	    parseError("unknown modifier",modstr);
X	else
X	    *modsp |= m;
X    }
X    return(str);
X}
X
Xstatic char *
XparseType(str,typep,modsp,detailp)
Xchar *str;
Xint *typep;
Xunsigned int *modsp,*detailp;
X{
X    char typestr[32];
X    int i; 
X
X    i = 0;
X    while (isalnum(*str) && i < 30)
X	typestr[i++] = *str++;
X    if (i == 31)
X	parseError("event type too long",str);
X    typestr[i] = '\0';
X    for (i=0; types[i].name!=NULL && strcasecmp(types[i].name,typestr)!=0; i++);
X    if (types[i].name == NULL) {
X	parseError("unknown event type",typestr);
X	*typep = 0;
X    } else {
X	*typep = types[i].value;
X	*detailp = types[i].detail;
X	*modsp |= types[i].mods;
X    }
X    return(str);
X}
X
Xstatic char *
XparseDetail(str,xevp,type,mods,detail)
Xchar *str;
XXEvent *xevp;
Xint type;
Xunsigned int mods,detail;
X{
X    char detailstr[256];
X    int i;
X
X    i = 0;
X    while (*str && !(i > 0 && *str == ',') && i < 255)
X	detailstr[i++] = *str++;
X    if (i == 255)
X	parseError("detail too long (truncated)",str);
X    detailstr[i] = '\0';
X    xevp->type = type;
X    switch (type) {
X	case KeyPress:
X	case KeyRelease: {
X	    XKeyEvent *xkevp = (XKeyEvent *)xevp;
X	    KeyCode k;
X	    char *s = strchr(detailstr,' ');
X	    if (s != NULL)
X		*s++ = '\0';
X	    k = XKeysymToKeycode(display,XStringToKeysym(detailstr));
X	    if (detail != 0 && k != 0) {
X		parseError("key detail conflict",detailstr);
X	    	xkevp->type = -1;
X		break;
X	    } else if (detail == 0)
X	    	xkevp->keycode = k;
X	    else
X	    	xkevp->keycode = detail;
X	    if (s != NULL) {
X		xkevp->x = (int)strtol(s,&s,0);
X		xkevp->y = (int)strtol(s,&s,0);
X		xkevp->x_root = (int)strtol(s,&s,0);
X		xkevp->y_root = (int)strtol(s,&s,0);
X	    }
X	    xkevp->state = mods;
X	    xkevp->root = root;
X	    xkevp->same_screen = True;
X	    break;
X	}
X	case ButtonPress:
X	case ButtonRelease: {
X	    XButtonEvent *xbevp = (XButtonEvent *)xevp;
X	    unsigned b = lookup(buttonNames,detailstr);
X	    if (*detailstr && b == 0) {
X		parseError("bad button detail",detailstr);
X		xbevp->type = -1;
X		break;
X	    }
X	    if (detail != 0 && b != 0) {
X		parseError("button detail conflict",detailstr);
X	    	xbevp->button = 0;
X	    } else if (detail == 0)
X	    	xbevp->button = b;
X	    else
X	    	xbevp->button = detail;
X	    xbevp->state = mods;
X	    xbevp->root = root;
X	    xbevp->same_screen = True;
X	    break;
X	}
X	case MotionNotify: {
X	    XMotionEvent *xmevp = (XMotionEvent *)xevp;
X	    xmevp->is_hint = lookup(motionDetails,detailstr);
X	    if (*detailstr && xmevp->is_hint == 0) {
X		parseError("bad motion detail",detailstr);
X		xmevp->type = -1;
X	    }
X	    xmevp->state = mods;
X	    xmevp->root = root;
X	    xmevp->same_screen = True;
X	    break;
X	}
X	case EnterNotify:
X	case LeaveNotify: {
X	    XCrossingEvent *xcevp = (XCrossingEvent *)xevp;
X	    char *s = strchr(detailstr,' ');
X	    if (s != NULL)
X		*s++ = '\0';
X	    xcevp->mode = lookup(notifyModes,detailstr);
X	    if (s != NULL)
X		xcevp->detail = lookup(notifyDetails,s);
X	    xcevp->state = mods;
X	    xcevp->root = root;
X	    xcevp->same_screen = True;
X	    break;
X	}
X	case FocusIn:
X	case FocusOut: {
X	    XFocusChangeEvent *xfcevp = (XFocusChangeEvent *)xevp;
X	    char *s = strchr(detailstr,' ');
X	    if (s != NULL)
X		*s++ = '\0';
X	    xfcevp->mode = lookup(notifyModes,detailstr);
X	    if (s != NULL)
X	        xfcevp->detail = lookup(notifyDetails,s);
X	    if (*detailstr && xfcevp->mode == 0 && xfcevp->detail == 0) {
X		parseError("bad focus mode or detail",detailstr);
X		xfcevp->type = -1;
X	    }
X	    break;
X	}
X	case KeymapNotify: {
X	    XKeymapEvent *xkevp = (XKeymapEvent *)xevp;
X	    int i;
X	    char *s = detailstr;
X	    for (i=0; i < 32; i++)
X		xkevp->key_vector[i] = (char)strtol(s,&s,0);
X	    break;
X	}
X	case Expose: {
X	    XExposeEvent *xeevp = (XExposeEvent *)xevp;
X	    char *s = detailstr;
X	    xeevp->x = (int)strtol(s,&s,0);
X	    xeevp->y = (int)strtol(s,&s,0);
X	    xeevp->width = (int)strtol(s,&s,0);
X	    xeevp->height = (int)strtol(s,&s,0);
X	    xeevp->count = (int)strtol(s,&s,0);
X	    break;
X	}
X	case GraphicsExpose: {
X	    XGraphicsExposeEvent *xgevp = (XGraphicsExposeEvent *)xevp;
X	    char *s = detailstr;
X	    xgevp->x = (int)strtol(s,&s,0);
X	    xgevp->y = (int)strtol(s,&s,0);
X	    xgevp->width = (int)strtol(s,&s,0);
X	    xgevp->height = (int)strtol(s,&s,0);
X	    xgevp->count = (int)strtol(s,&s,0);
X	    xgevp->major_code = (int)strtol(s,&s,0);
X	    xgevp->minor_code = (int)strtol(s,&s,0);
X	    break;
X	}
X	case NoExpose: {
X	    XNoExposeEvent *xnevp = (XNoExposeEvent *)xevp;
X	    char *s = detailstr;
X	    xnevp->major_code = (int)strtol(s,&s,0);
X	    xnevp->minor_code = (int)strtol(s,&s,0);
X	    break;
X	}
X	case CirculateNotify:
X	case CirculateRequest: {
X	    XCirculateEvent *xcevp = (XCirculateEvent *)xevp;
X	    if ((xcevp->place=lookup(circulateDetails,detailstr)) == 99) {
X		parseError("bad circulate detail",detailstr);
X		xcevp->type = -1;
X	    }
X	    break;
X	}
X	case ConfigureNotify:
X	case ConfigureRequest: {
X	    XConfigureEvent *xcevp = (XConfigureEvent *)xevp;
X	    char *s = detailstr;
X	    xcevp->x = (int)strtol(s,&s,0);
X	    xcevp->y = (int)strtol(s,&s,0);
X	    xcevp->width = (int)strtol(s,&s,0);
X	    xcevp->height = (int)strtol(s,&s,0);
X	    xcevp->border_width = (int)strtol(s,&s,0);
X	    xcevp->above = (Window)strtol(s,&s,0);
X	    SKIPWHITE(s);
X	    xcevp->override_redirect=lookup(booleans,s);
X	    break;
X	}
X	case CreateNotify: {
X	    XCreateWindowEvent *xcevp = (XCreateWindowEvent *)xevp;
X	    char *s = detailstr;
X	    xcevp->x = (int)strtol(s,&s,0);
X	    xcevp->y = (int)strtol(s,&s,0);
X	    xcevp->width = (int)strtol(s,&s,0);
X	    xcevp->height = (int)strtol(s,&s,0);
X	    xcevp->border_width = (int)strtol(s,&s,0);
X	    SKIPWHITE(s);
X	    xcevp->override_redirect=lookup(booleans,s);
X	    break;
X	}
X	case DestroyNotify: {
X	    XDestroyWindowEvent *xdevp = (XDestroyWindowEvent *)xevp;
X	    xdevp->window = (Window)strtol(detailstr,NULL,0);
X	    break;
X	}
X	case GravityNotify: {
X	    XGravityEvent *xgevp = (XGravityEvent *)xevp;
X	    char *s = detailstr;
X	    xgevp->x = (int)strtol(s,&s,0);
X	    xgevp->y = (int)strtol(s,&s,0);
X	    break;
X	}
X	case MapNotify:
X	case MapRequest: {
X	    XMapEvent *xmevp = (XMapEvent *)xevp;
X	    xmevp->override_redirect = lookup(booleans,detailstr);
X	    break;
X	}
X	case MappingNotify: {
X	    XMappingEvent *xmevp = (XMappingEvent *)xevp;
X	    char *s=strchr(detailstr,' ');
X	    if (s != NULL)
X		*s++ = '\0';
X	    if ((xmevp->request=lookup(mappingDetails,detailstr)) == 0) {
X		parseError("bad mapping detail",detailstr);
X		xmevp->type = -1;
X	    }
X	    if (xmevp->request == MappingKeyboard && s != NULL) {
X		SKIPWHITE(s);
X		xmevp->first_keycode = (int)strtol(s,&s,0);
X		xmevp->count = (int)strtol(s,&s,0);
X	    }
X	    break;
X	}
X	case ReparentNotify: {
X	    XReparentEvent *xrevp = (XReparentEvent *)xevp;
X	    char *s = strchr(detailstr,' ');
X	    if (s != NULL)
X		*s++ = '\0';
X	    xrevp->parent = (Window)strtol(detailstr,NULL,0);
X	    if (s != NULL) {
X		SKIPWHITE(s);
X		xrevp->x = (int)strtol(s,&s,0);
X		xrevp->y = (int)strtol(s,&s,0);
X		SKIPWHITE(s);
X		xrevp->override_redirect = lookup(booleans,s);
X	    }
X	    break;
X	}
X	case UnmapNotify: {
X	    XUnmapEvent *xuevp = (XUnmapEvent *)xevp;
X	    xuevp->from_configure = lookup(booleans,detailstr);
X	    break;
X	}
X	case VisibilityNotify: {
X	    XVisibilityEvent *xvevp = (XVisibilityEvent *)xevp;
X	    xvevp->state = lookup(visibilityDetails,detailstr);
X	    break;
X	}
X	case ResizeRequest: {
X	    XResizeRequestEvent *xrevp = (XResizeRequestEvent *)xevp;
X	    char *s = detailstr;
X	    xrevp->width = (int)strtol(s,&s,0);
X	    xrevp->height = (int)strtol(s,&s,0);
X	    break;
X	}
X	case ColormapNotify:
X	    parseError("can't handle ColormapNotify events","");
X	    xevp->type = -1;
X	    break;
X	case ClientMessage: {
X	    XClientMessageEvent *xcevp = (XClientMessageEvent *)xevp;
X	    char *s = strchr(detailstr,' ');
X	    int i;
X	    if (*detailstr == '\0') {
X		parseError("missing atom for client message","");
X		xcevp->type = -1;
X		break;
X	    }
X	    if (s != NULL)
X		*s++ = '\0';
X	    xcevp->message_type = XInternAtom(display,detailstr,True);
X	    if (s != NULL) {
X		SKIPWHITE(s);
X		if (*s == 'b') {
X		    xcevp->format = 8;
X		    SKIPWHITE(s);
X		    for (i=0; i < 20; i++)
X			xcevp->data.b[i] = (char)strtol(s,&s,0);
X		} else if (*s == 'c') {
X		    xcevp->format = 8;
X		    SKIPWHITE(s);
X		    for (i=0; i < 20; i++)
X			xcevp->data.b[i] = *s++;
X		} else if (*s == 's') {
X		    xcevp->format = 16;
X		    SKIPWHITE(s);
X		    for (i=0; i < 10; i++)
X			xcevp->data.s[i] = (short)strtol(s,&s,0);
X		} else if (*s == 'l') {
X		    xcevp->format = 32;
X		    SKIPWHITE(s);
X		    for (i=0; i < 5; i++)
X			xcevp->data.l[i] = strtol(s,&s,0);
X		}
X	    }
X	}
X	case PropertyNotify: {
X	    XPropertyEvent *xpevp = (XPropertyEvent *)xevp;
X	    char *s = strchr(detailstr,' ');
X	    if (*detailstr == '\0') {
X		parseError("missing atom for property notify","");
X		xpevp->type = -1;
X		break;
X	    }
X	    if (s != NULL)
X		*s++ = '\0';
X	    xpevp->atom = XInternAtom(display,detailstr,True);
X	    if (s != NULL) {
X		SKIPWHITE(s);
X		xpevp->state = lookup(propertyDetails,s);
X	    }
X	    xpevp->time = CurrentTime;
X	    break;
X	}
X	case SelectionClear: {
X	    XSelectionClearEvent *xsevp = (XSelectionClearEvent *)xevp;
X	    if (*detailstr == '\0') {
X		parseError("missing atom for selection clear","");
X		xsevp->type = -1;
X		break;
X	    }
X	    xsevp->selection = XInternAtom(display,detailstr,True);
X	    xsevp->time = CurrentTime;
X	    break;
X	}
X	/* Note SelectionRequest and Selection are identical except the
X	   event types have different structures (and different errors). */
X	case SelectionRequest: {
X	    XSelectionRequestEvent *xsevp = (XSelectionRequestEvent *)xevp;
X	    char *s1 = detailstr;
X	    char *s2,*s3;
X	    if (*s1 == '\0') {
X		parseError("missing atom for selection request (selection)","");
X		xsevp->type = -1;
X		break;
X	    }
X	    if ((s2=strchr(s1,' ')) == NULL) {
X		parseError("missing atom for selection request (target)","");
X		xsevp->type = -1;
X		break;
X	    }
X	    *s2++ = '\0';
X	    SKIPWHITE(s2);
X	    if ((s3=strchr(s2,' ')) == NULL) {
X		parseError("missing atom for selection request (property)","");
X		xsevp->type = -1;
X		break;
X	    }
X	    *s3++ = '\0';
X	    SKIPWHITE(s3);
X	    xsevp->selection = XInternAtom(display,s1,True);
X	    xsevp->target = XInternAtom(display,s2,True);
X	    if (*s3 == '\0' || strcasecmp(s3,"None") == 0)
X		xsevp->property = None;
X	    else
X		xsevp->property = XInternAtom(display,s3,True);
X	    xsevp->time = CurrentTime;
X	}
X	case SelectionNotify: {
X	    XSelectionEvent *xsevp = (XSelectionEvent *)xevp;
X	    char *s1 = detailstr;
X	    char *s2,*s3;
X	    if (*s1 == '\0') {
X		parseError("missing atom for selection notify (selection)","");
X		xsevp->type = -1;
X		break;
X	    }
X	    if ((s2=strchr(s1,' ')) == NULL) {
X		parseError("missing atom for selection notify (target)","");
X		xsevp->type = -1;
X		break;
X	    }
X	    *s2++ = '\0';
X	    SKIPWHITE(s2);
X	    if ((s3=strchr(s2,' ')) == NULL) {
X		parseError("missing atom for selection notify (property)","");
X		xsevp->type = -1;
X		break;
X	    }
X	    *s3++ = '\0';
X	    SKIPWHITE(s3);
X	    xsevp->selection = XInternAtom(display,s1,True);
X	    xsevp->target = XInternAtom(display,s2,True);
X	    if (*s3 == '\0' || strcasecmp(s3,"None") == 0)
X		xsevp->property = None;
X	    else
X		xsevp->property = XInternAtom(display,s3,True);
X	    xsevp->time = CurrentTime;
X	}
X	default:
X	    parseError("don't understand event type\n","");
X	    xevp->type = -1;
X    }
X    return(str);
X}
X
Xstatic void
XparseError(s1,s2)
Xchar *s1,*s2;
X{
X    if (*s2 == '\0')
X	fprintf(stderr,"xse: %s\n",s1);
X    else
X	fprintf(stderr,"xse: %s: \"%s\"\n",s1,s2);
X}
X
Xvoid
XfreeEventList(p)
XEventListPtr p;
X{
X    EventListPtr q;
X
X    while (p != NULL) {
X	q = p;
X	p = p->next;
X	free(q);
X    }
X}
END_OF_FILE
if test 20674 -ne `wc -c <'parse.c'`; then
    echo shar: \"'parse.c'\" unpacked with wrong size!
fi
# end of 'parse.c'
fi
echo shar: End of archive 3 \(of 3\).
cp /dev/null ark3isdone
MISSING=""
for I in 1 2 3 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 3 archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
George Ferguson			ARPA: ferguson at cs.rochester.edu
University of Rochester		UUCP: {decvax,rutgers}!rochester!ferguson
Rochester  NY  14627		VOX:  (716) 275-2527



More information about the Alt.sources mailing list