prb@UMN-REI-UC.ARPA.UUCP (04/11/87)
Since I have gotten several requests for my xterm hacks (and that is what
they are) to fix the cut buffers I will just post the changes for all to
enjoy and mock.
To fix the Cut Buffer problem in Xterm 6.6A2 I have added Code Fragment #1
(see below) in charproc.c just before the definition of in_put() (around line
750 or so). Just before in_put() there is also a definition:
static int select_maskl;
Add
static int write_mask;
Change the tail end of in_put() to Code Fragment #2.
Add Code Fragment #3 to the end of charproc.c.
In input.c change the beginning of the code for the Input() function to
look like Code Fragment #4.
In button.c change the 4 calls to write() to be calls to v_write(). (Each
of these writes should be writing to file descriptor `pty').
That's it.
What this gets you:
a) When you paste a cut buffer the whole buffer should be pasted
and not the first `some number less that you wanted' bytes.
b) If a key is mapped to an ascii string that starts with a '\377'
then the rest of the characters in that string will be read as
if they were output instead of input (mapo feature of SUN's
suntools).
Have fun.
-Paul R Borman
Cray Research, Inc.
prb@umn-rei-uc.arpa
------- Code Fragment # 1 ------
static char v_buffer[4096];
static char *v_bufstr;
static char *v_bufptr;
static char *v_bufend;
#define ptymask() (v_bufptr > v_bufstr ? pty_mask : 0)
v_write(f, d, l)
int f;
char *d;
int l;
{
int r;
int c = l;
if (!v_bufstr) {
v_bufstr = v_buffer;
v_bufptr = v_buffer;
v_bufend = &v_buffer[4096];
}
if ((1 << f) != pty_mask)
return(write(f, d, l));
if (v_bufptr > v_bufstr) {
if (l) {
if (v_bufend > v_bufptr + l) {
bcopy(d, v_bufptr, l);
v_bufptr += l;
} else {
if (v_bufstr != v_buffer) {
bcopy(v_bufstr, v_buffer,
v_bufptr - v_bufstr);
v_bufptr -= v_bufstr - v_buffer;
v_bufstr = v_buffer;
}
if (v_bufend > v_bufptr + l) {
bcopy(d, v_bufptr, l);
v_bufptr += l;
} else if (v_bufptr < v_bufend) {
fprintf(stderr, "Out of buffer space\n");
c = v_bufend - v_bufptr;
bcopy(d, v_bufptr, c);
v_bufptr = v_bufend;
} else {
fprintf(stderr, "Out of buffer space\n");
c = 0;
}
}
}
if (v_bufptr > v_bufstr) {
if ((r = write(f, v_bufstr, v_bufptr - v_bufstr)) <= 0)
return(r);
if ((v_bufstr += r) >= v_bufptr)
v_bufstr = v_bufptr = v_buffer;
}
} else if (l) {
if ((r = write(f, d, l)) < 0) {
if (errno == EWOULDBLOCK)
r = 0;
else if (errno == EINTR)
r = 0;
else
return(r);
}
if (l - r) {
if (l - r > v_bufend - v_buffer) {
fprintf(stderr, "Truncating to %d\n",
v_bufend - v_buffer);
l = (v_bufend - v_buffer) + r;
}
bcopy(d + r, v_buffer, l - r);
v_bufstr = v_buffer;
v_bufptr = v_buffer + (l - r);
}
}
return(c);
}
----- Code Fragment #2 -------
if(QLength())
select_mask = X_mask;
else {
write_mask = ptymask();
XFlush();
select_mask = Select_mask;
if((i = select(max_plus1, &select_mask, &write_mask,
NULL, screen->timeout)) < 0) {
if (errno != EINTR)
SysError(ERROR_SELECT);
continue;
} else if(i == 0) {
if(GetButtonState(screen->sb) & HILITED)
WindowScroll(screen,
ButtonRegion(screen->sb));
screen->timeout->tv_usec = STEPTIME;
continue;
}
}
if (write_mask & ptymask())
v_write(screen->respond, 0, 0); /* flush buffer */
if (select_mask & X_mask) {
if (bcnt <= 0) {
bcnt = 0;
bptr = buffer;
}
xevents();
if (bcnt > 0)
break;
}
}
bcnt--;
return(*bptr++);
}
----- Code Fragment # 3 -----
fakinput(string, nbytes)
char *string;
int nbytes;
{
if (bptr + bcnt + nbytes < &buffer[BUF_SIZE]) {
strncpy(bptr+bcnt, string, nbytes);
bcnt += nbytes;
}
}
----- Code Fragment # 4 -----
string = XLookupMapping (event, &nbytes);
if (nbytes > 0) {
if (*string == 0377) {
fakinput(string+1, nbytes-1);
return;
}
if(screen->TekGIN) {
TekEnqMouse(*string++);
TekGINoff();
nbytes--;
}
----- End of Code Fragments -----