This is a very old bug/feature. I spent some time looking into it.
Not being very experienced at X coding, so I haven't attempted a fix.
Demo of bug:
- in an xterm running a shell, type: echo -e '\033[?1001h'
- click in the window
xterm now locks up (this is documented in ctlseqs.ms) and eats all
available CPU (not documented).
Mouse hilite tracking notifies a program of a button press,
receives a range of lines from the program, highlights the region
covered by the mouse within that range until button release, and
then sends the program the release coordinates. It is enabled by
specifying parameter 1001 to DECSET. Highlighting is performed
only for button 1, though other button events can be received.
Warning: use of this mode requires a cooperating program or it
will hang xterm. On button press, the same information as for
normal tracking is generated; xterm then waits for the program to
send mouse tracking information. All X events are ignored until
the proper escape sequence is received from the pty: CSI Ps ; Ps
; Ps ; Ps ; Ps T . The parameters are func, startx , starty,
firstrow, and lastrow. func is non-zero to initiate hilite
tracking and zero to abort. startx and starty give the starting x
and y location for t he highlighted region. The ending location
tracks the mouse, but will never be above row firstrow and will
always be above row lastrow. (The top of the screen is row 1.)
Confirmed by someone else on Xfree86 4.2.99.4.
On Red Hat LINUX 8.0, I straced such a hung xterm. There was a cycle
of 4 select system calls. It is all within one invocation of
xc/programs/xterm/charproc.c:ip_put
The cycle within in_put is:
XtAppPending which eventually calls select
select
XtAppPending which eventually calls select
xevents which calls XtAppPending which eventually calls select
It seems to me that it would be possible to make at least one of these
selects blocking. This would elmininate the CPU load. It doesn't
avoid the hang.
The last two calls are in the following fragment of ip_put:
/* if there are X events already in our queue, it
counts as being readable */
if (XtAppPending(app_con) ||
FD_ISSET (ConnectionNumber(screen->display), &select_mask)) {
xevents();
if (VTbuffer.cnt > 0) /* HandleInterpret */
break;
It turns out that xecents doesn't do anything if
(XtAppPending(app_con) & XtIMTimer) == 0 &&
(input_mask & XtIMXEvent) != XtIMXEvent
which is true in this case.
Since ip_put can figure this out after its first call to XtAppPending,
it could decide that the select should not timeout immediately:
[This is my untested, hand-made, sort-of context diff]
/*
* if there's either an XEvent or an XtTimeout pending, just take
* a quick peek, i.e. timeout from the select() immediately. If
* there's nothing pending, let select() block a little while, but
* for a shorter interval than the arrow-style scrollbar timeout.
* The blocking is optional, because it tends to increase the load
* on the host.
*/
+ XtInputMask input_mask;
+
- if (XtAppPending(app_con)) {
- select_timeout.tv_usec = 0;
+ if (input_mask = XtAppPending(app_con)) {
+ if (input_mask & XtIMTimer) == 0
+ && (input_mask & XtIMXEvent) != XtIMXEvent)
+ select_timeout.tv_usec = 50000; /* right magic number? */
+ else
+ select_timeout.tv_usec = 0;
time_select = 1;
} else if (screen->awaitInput) {
select_timeout.tv_usec = 50000;
time_select = 1;
#if OPT_BLINK_CURS
} else if ((screen->cursor_blink &&
((screen->select&FOCUS) || screen->always_highlight)) ||
(screen->cursor_state == BLINKED_OFF)) {
select_timeout.tv_usec = tick;
while( select_timeout.tv_usec > 1000000 ) {
select_timeout.tv_usec -= 1000000;
select_timeout.tv_sec++;
}
time_select = 1;
#endif
}
i = select(max_plus1, &select_mask, &write_mask, 0,
time_select ? &select_timeout : 0);
================
I'm not familiare with the whole system. I'm sure that there must be
a more elegant way. I just hope that this suggests a reasonable
starting point.
================
Now: what about avoiding the hang altogether? I've not understood the
code well enough to know what I'd do.
The hang is fundamental. The xterm does not know how to act until
it gets the CSI...T sequence from the pty. Perhaps a better approach
would be to act as if a default one had been received until the actual
one arrives.
Hugh Redelmeier
[EMAIL PROTECTED]
PS: I've spent some hours trying to figure out the best way to present
this bug report. I've lurked on %sfree86-devel. I've read the
mailing list.
At the cost of starting a flame-war, I think that a bug tracking
system would be great. I have some experience submitting bugs to Red
Hat's bugzilla (hi, Mike). I spent about an hour trying to use google
to find other reports of this bug. Not good.
As a develper (www.freeswan.org) I'm not quite as thrilled by bug
tracking systems -- they are all a bit clumsy.
_______________________________________________
Devel mailing list
[EMAIL PROTECTED]
http://XFree86.Org/mailman/listinfo/devel