dcmartin@INGRES.BERKELEY.EDU.UUCP (02/23/87)
The manual says that XUpdateMouse() "eliminates any mouse moved events at the head of the queue..." Does this mean that all mouse moved events are flushed from the queue, with the exception of the last, or are all mouse moved events flushed? Thanks. dcm
don@BRILLIG.UMD.EDU.UUCP (02/24/87)
There's no fundemental reason it can't handle more than 2 shift modifiers at once, except for the fact that the .uwmrc yacc grammar only allows for up to two. Find the label "keyexpr:" in "uwm/gram.y", and make it look like the following: (adding the last two cases) keyexpr: /* empty */ { $$ = 0; } | kmask { $$ = $1; } | kmask '|' kmask { $$ = $1 | $3; } | kmask '|' kmask '|' kmask { $$ = $1 | $3 | $5; } | kmask '|' kmask '|' kmask '|' kmask { $$ = $1 | $3 | $5 | $7; } ; I suppose you could make it a recursive definition, so you could specify as many kmasks as you wanted. Would that be any more or less efficient? Now you should be able to "or" together up to four shift modifiers to specify an event for uwm to look for. i.e. this would not work before but will now: f.menu= c|m|s :: left : "Ctrl-Meta-Shift-Mouse-Left Menu" I would like to be able to make a function key assert some combination of shift keys (all at the same time, on one function key), but there does not seem to be any simple way to do that. If I could do that, then I'd bind function keys to ungainly shift combinations, and use them to modify mouse clicks. Each function key would correspond to a class of window manager (or whatever) commands. -Don P.S.: While you're waiting for it to recompile, you can sing this: Double Bucky (Sung to the tune of "Rubber Duckie") Double bucky, you're the one! You make my keyboard lots of fun Double bucky, an additional bit or two: (Vo-vo-de-o!) Control and Meta side by side, Augmented ASCII, nine bits wide! Double bucky, a half a thousand glyphs, plus a few! Oh, I sure wish that I Had a couple of bits more! Perhaps a Set of pedals to Make the number of Bits four: Double double bucky! Double bucky, left and right OR'd together, outta sight! Double bucky, I'd like a whole word of Double bucky, I'm happy I heard of Double bucky, I'd like a whole word of you! (C) 1978 by Guy L. Steele, Jr. (For those of you who are interested, the term "bucky bits" comes from Niklaus Wirth, known as "bucky" to friends, who suggested that an extra bit be added to terminal codes on 36 bit machines for use by screen editors.)
glennw@hercules.UUCP (02/26/87)
Fcc:x In article <8702231839.AA02342@ingres.Berkeley.EDU>, dcmartin@INGRES.BERKELEY.EDU (David C. Martin) writes: > The manual says that XUpdateMouse() "eliminates any mouse moved events at the > head of the queue..." > > Does this mean that all mouse moved events are flushed from the queue, with > the exception of the last, or are all mouse moved events flushed? XUpdateMouse only flushes the contiguous block of MouseMoved events at the head of the queue, that is, flushing ceases when the first non-mouse event is encountered. In the little project I am doing now, I have found this to be less than optimal. For one thing, there is no good way to be sure that the pointer is not in another window overlapping yours, because there is no way to find out if any mouse events actually occured. For another, there is no reason to leave any Mouse events lying around in the queue once the mouse has been queried. Also, I have found it useful to have the one routine missing from the set, XUpdateMouseButtons. So I have written a new Mouse polling routine, XUpdatePointer (V11-style name), which adds a return argument to XQueryMouseButtons giving the number of events removed from the queue, and deletes all MouseMoved and Button events throughout the queue. The calling routine uses the last mouse state if no events are found. This routine significantly improves performance when mouse buttons and keys are intermixed in the queue. The source is enclosed. A correct XUpdateMouse or XUpdateMouseButtons is a simple reduction from this routine. I hit one minor mystery which I coded around, not having time to figure it out. Apparently, either GetReq() or _XReply allows new events to enter the queue, so I had to move the XPending call after these calls to get an accurate count of the events removed from the queue. One annoying problem with getting buttons with QueryButton is that it is easy to miss a fast button press. I am thinking about a further hack on this routine which would return the state of each button event, if any instead of polling the pointer, guaranteeing accurate capture of the button presses and additionally reducing the IPC overhead a bit. ----------- #include <X/mit-copyright.h> /* $Header: XUpdatePointer.c,v 1.1 87/02/23 06:31:02 glennw Exp $ */ /* Copyright Massachusetts Institute of Technology 1985 */ #include "XlibInternal.h" extern _QEvent *_qfree; /* Like XQueryButtons, but also reads pending events and flushes any * MouseMoved, ButtonPressed, or ButtonRelease events anywhere in the queue. * It returns the number of events flushed in the removed argument. * A good way to track the mouse is to use a MouseMoved or Button event * as a "hint", by calling this routine to get up to date coordinates. */ Status XUpdatePointer (w, x, y, subw, state, removed) Window w; Window *subw; int *x, *y; short *state; int *removed; { register Display *dpy; register XReq *req; register _QEvent *qelt, *qprev; _QEvent qdummy; XRep rep; int quelen; GetReq(X_QueryMouse, w); if (!_XReply(dpy, &rep)) return(0); quelen = XPending(); /* read all events in socket's kernel buffer, flush output */ /* note - apparently GetReq or XReply allows more events to get in, so XPending is moved after them to get a correct queue length */ qprev = &qdummy; /* temporary stash for next ptr while at head */ qelt = dpy->head; while (qelt) { if ((qelt->event.type & (MouseMoved | ButtonPressed | ButtonReleased)) != 0) { qprev->next = qelt->next; /* stash next ptr or splice cur out */ qelt->next = _qfree; /* and into free list */ _qfree = qelt; qelt = qprev->next; /* move to next item */ dpy->qlen--; } else { if (qprev == &qdummy) /* first non-Mouse event; reset head */ { dpy->head = qelt; } qprev = qelt; qelt = qelt->next; /* skip over non-Mouse events */ } } if(qprev == &qdummy) /* found no non-Mouse event; queue is empty */ dpy->head = dpy->tail = NULL; else dpy->tail = qprev; /* in case we removed events from end of queue */ *x = rep.param.s[2]; *y = rep.param.s[3]; *subw = rep.param.l[0]; *state = rep.params4; *removed = quelen - dpy->qlen; return (1); } -- Glenn Widener
glennw@hercules.UUCP (02/26/87)
Recently I heard a presentation from a workstation supplier on its plan to support X. They plan to provide an optimized Xlib that uses shared memory instead of IPC when talking locally to their own server. Having just suggested a user extension to Xlib, I am concerned that any re-architecture of the Xlib/server interface like this must permit user extensions to the Xlib to be used in conjunction with the re-architected interface. Otherwise, people should be warned to avoid any non-standard, non-Xlib interface to the protocol. -- Glenn Widener