satyen@xwis.Sun.COM (satyendra Dhingra) (08/29/89)
Does anyone have a good way of doing rubberbanding with Xlib, by good I mean where rubberband box keeps up with the cursor. The normal way of doing rubberbanding erasebox(flush buffer)-redrawbox(flush buffer)-erasebox.. requires a roundtrip for each request (batching requests makes it even worse) and the cursor is always ahead of the box being drawn. Has anyone worked a solution where rubberbanding box always tracks thr cursor very closely. thanks, satyendra satyen@sun.com
erik@srava.sra.JUNET (Erik M. van der Poel) (08/29/89)
Does anyone have a good way of doing rubberbanding with Xlib, by good I mean where rubberband box keeps up with the cursor. I have found that you can keep up with the cursor quite well if you first erase the box, then call XTrackMouse (supplied below), and finally draw the box again. XTrackMouse first calls XSync to make sure the server has processed all of your requests and has sent all events. Then all mouse events (except for the last one) are skipped to obtain the most up-to-date one. XTrackMouse(event) register XMotionEvent *event; { register Display *display; register Window window; if (event->type != MotionNotify) { return; } display = event->display; window = event->window; XSync(display, 0); while (XCheckTypedWindowEvent(display, window, MotionNotify, event)) { } } Note that XTrackMouse only works for rubberbanding in a window (as opposed to rubberbanding all over the display like window managers do). However, this can be changed easily by using XCheckTypedEvent instead of XCheckTypedWindowEvent. As far as I know, Xlib does not contain a convenience function like this, although it might be nice if it did (nudge nudge :-). -- Erik M. van der Poel erik@sra.junet (Japan) SRA, 1-1-1 Hirakawa-cho, Chiyoda-ku erik%sra.junet@uunet.uu.net (USA) Tokyo 102 Japan. TEL +81-3-234-2692 erik%sra.junet@mcvax.uucp (Europe)
tbecker@incas.UUCP (3295) (08/29/89)
satyen@xwis.Sun.COM (satyendra Dhingra) writes: >Does anyone have a good way of doing rubberbanding with Xlib, by good >I mean where rubberband box keeps up with the cursor. The normal way of >doing rubberbanding >erasebox(flush buffer)-redrawbox(flush buffer)-erasebox.. >requires a roundtrip for each request (batching requests makes it even >worse) and the cursor is always ahead of the box being drawn. Has anyone >worked a solution where rubberbanding box always tracks thr cursor very >closely. I have written several applications with Xlib, using X11R3 on a Sun3/60, each application used rubberbanding as you described it. However, in none of them, the cursor was much ahead of the bounding box, though I have used exactly the same mecahnism as you described above. Maybe this has to do with the way you determine when to move the box. Moving the pointer might generate a great number of PointerMotion events. If you use each of them to update your rubberband, too much action is necessary to follow the pointer. Instead, set the PointerMotionHintMask and consider only PointerMotionEvents with the is_hint member set to NotifyHint. Then use XQueryPointer to get the current pointer location and update your rubberband. This way you make sure the bounding box follows the pointer tightly. >thanks, >satyendra >satyen@sun.com Hope this helps ... Thomas Becker ------------------------------------------------------------------------------- Thomas Becker-----------University of Kaiserslautern---------------West Germany ---------------P.O. 3049------------------------D-6750 Kaiserslautern---------- ---------------------e-mail: incas!tbecker@uklirb.uucp------------------------- --------------------------phone: +49 631 205 3295------------------------------ -------------------------------------------------------------------------------
laffra@HLERUL5I.BITNET (08/29/89)
In response to:
Does anyone have a good way of doing rubberbanding with Xlib, by good
I mean where rubberband box keeps up with the cursor. The normal way of
doing rubberbanding
erasebox(flush buffer)-redrawbox(flush buffer)-erasebox..
requires a roundtrip for each request (batching requests makes it even
worse) and the cursor is always ahead of the box being drawn. Has anyone
worked a solution where rubberbanding box always tracks thr cursor very
closely.
There is a way:
You have to make sure that you do not redraw your box with every motion event.
What I generally do (and it works very nicely) is the following:
XNextEvent(&event);
switch( type_of(&event) ) {
case MotionNotify :
if (event_queue_is_empty_now()) {
erase_box(...); draw(box(...);
else
ignore();
}
The 'event_queue_is_empty_now()' function calls XPending() (XLib function).
In this way you only redraw the box when the mouse pointer is not moving
anymore. This reduce the delay of redrawing and the box will follow the
cursor better.
If your picture is very complicated you might want to test the queue for
new motion event even while you are drawing the picture. The you do not
finish the picture but erase the sofar drawn parts.
Chris Laffra
laffra@HLERUL5I.BITNET
h
marbru@auto-trol.UUCP (Martin Brunecky) (08/31/89)
> Implement rubberbanding ....
I'v seen some advices so far. What I do is as follows (and it DID
generate good results on VS2000 running FT of DECWINDOWS long time
ago. However, you will NEVER track the pointer EXACTLY, there is
always a delay due to the roundtrip. We solve this by using NONE
cursor (which is unfortunatelly missing in the standard cursors, you have
to create one by hand using XCreatePixmapCursor... with a "blank"
pixmap 1x1 pixel).
1) we set pointer motions hint in the window event mask so that we
don't get swamped with hundreds of motion events. Or in Xt,
specify compress_motion in core part to TRUE.
2) when we get a motion event, we call XQueryPointer. It costs a round-trip,
but we get the true LAST pointer position.
3) we compare position to the previous one = no move, skip it
4) we try to do the undraw-draw in one protocol request (using Xor)
if possible - i.e. using XDrawSegments. Till about 50 (?) segments
you get good results. Above that, blt from pixmap may be better.
###############################################################################
Martin Brunecky, Auto-trol Technology Corporation,
12500 North Washington Street, Denver, CO-80241-2404
(303) 252-2499 ncar!ico!auto-trol!marbru
###############################################################################