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 -----