Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!sdd.hp.com!zaphod.mps.ohio-state.edu!wuarchive!udel!rochester!ferguson From: ferguson@cs.rochester.edu (George Ferguson) Newsgroups: alt.sources Subject: xse - An interface to XSendEvent() part03/03 REPOST Message-ID: <1990Aug16.193818.11454@cs.rochester.edu> Date: 16 Aug 90 19:38:18 GMT Reply-To: ferguson@cs.rochester.edu (George Ferguson) Distribution: alt Organization: U of Rochester, CS Dept, Rochester, NY Lines: 823 #! /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 'parse.c' <<'END_OF_FILE' X/* X * parse.c - Parse event specifications (see Xt manual, appendix B) X * X * George Ferguson, ferguson@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 X#include X#include X#include X#include 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@cs.rochester.edu University of Rochester UUCP: {decvax,rutgers}!rochester!ferguson Rochester NY 14627 VOX: (716) 275-2527