repo: rxvt-unicode-sixel action: commit revision: path_from: revision_from: cfb8cfc3428fecca0d8b8a3afd14751931cbfdb9: path_to: revision_to:
commit cfb8cfc3428fecca0d8b8a3afd14751931cbfdb9 Author: Marc LehmannDate: Mon Dec 13 01:29:03 2004 +0000 *** empty log message *** diff --git a/Changes b/Changes
--- a/Changes
+++ b/Changes
@@ -2,9 +2,7 @@ Lines marked with "xterm:" indicate either xterm features ported to rxvt
or changed rxvt behaviour to make it more compatible to xterm (usually
xfree86's xterm).
-TODO: underline colour changes?
TODO: read property sequence is broken with respect to utf-8 etc.
-TODO: +ssc -ssr seems to scroll at wrong time, scrolling up the empty sec. scr.
FEAT: hotkey font resizing
FEAT: searchable backlog
FEAT: meta-tagging of data by regex (my dream project)
@@ -13,7 +11,11 @@ FEAT: double-click: more intelligent (urls etc.)
FEAT: OnTheSpot editing.
FEAT: tabbed windows
-4.4
+ - completely re-wrote selection pasting. This should fix
+ garbled incomplete characters at 32k boundaries and too-short
+ INCR selections.
+
+4.4 Sun Dec 12 22:10:06 CET 2004
- rewrote handling of default-char width.
- implement _NET_WM_NAME et al., and also use UTF8_STRING
for the xterm property esc. sequence. Allows i18n window
diff --git a/src/command.C b/src/command.C
--- a/src/command.C
+++ b/src/command.C
@@ -1338,7 +1338,7 @@ rxvt_term::x_cb (XEvent &ev)
&data);
set_string_property (XA_CUT_BUFFER0, data);
XFree (data);
- selection_paste (display->root, XA_CUT_BUFFER0, True);
+ selection_paste (display->root, XA_CUT_BUFFER0, true);
XSetInputFocus (display->display, display->root, RevertToNone, CurrentTime);
}
#endif /* OFFIX_DND */
@@ -1470,8 +1470,7 @@ rxvt_term::x_cb (XEvent &ev)
case SelectionNotify:
if (selection_wait == Sel_normal)
- selection_paste (ev.xselection.requestor,
- ev.xselection.property, True);
+ selection_paste (ev.xselection.requestor, ev.xselection.property, true);
break;
case SelectionRequest:
diff --git a/src/main.C b/src/main.C
--- a/src/main.C +++ b/src/main.C @@ -261,9 +261,7 @@ rxvt_term::~rxvt_term () free (env_term); free (env_colorfgbg); free (locale); -#if 0 - free (codeset); -#endif + free (incr_buf); delete envv; delete argv; diff --git a/src/rxvt.h b/src/rxvt.h
--- a/src/rxvt.h
+++ b/src/rxvt.h
@@ -1104,6 +1104,8 @@ struct rxvt_term : zero_initialized, rxvt_vars {
Time selection_time,
selection_request_time;
pid_t cmd_pid; /* process id of child */
+ char * incr_buf;
+ size_t incr_buf_size, incr_buf_fill;
/* ---------- */
Cursor leftptr_cursor;
#ifdef POINTER_BLANK
@@ -1450,7 +1452,7 @@ struct rxvt_term : zero_initialized, rxvt_vars {
void scr_reverse_selection ();
void scr_dump (int fd);
void selection_check (int check_more);
- int selection_paste (Window win, Atom prop, bool delete_prop);
+ void selection_paste (Window win, Atom prop, bool delete_prop);
void selection_property (Window win, Atom prop);
void selection_request (Time tm, int x, int y);
int selection_request_other (Atom target, int selnum);
diff --git a/src/screen.C b/src/screen.C
--- a/src/screen.C
+++ b/src/screen.C
@@ -41,7 +41,8 @@ inline void fill_text (text_t *start, text_t value, int len)
}
/* ------------------------------------------------------------------------- */
-#define PROP_SIZE 16384
+#define PROP_SIZE 256*1024
+#define PASTE_SIZE 32768
#define TABSIZE 8 /* default tab size */
/* ------------------------------------------------------------------------- *
@@ -602,8 +603,7 @@ rxvt_term::scr_change_screen (int scrn)
else
#endif
if (options & Opt_secondaryScroll)
- //if (current_screen == PRIMARY)
- scr_scroll_text (0, prev_nrow - 1, prev_nrow, 0);
+ scr_scroll_text (0, prev_nrow - 1, prev_nrow, 0);
return scrn;
}
@@ -2661,12 +2661,12 @@ void
rxvt_term::paste (const unsigned char *data, unsigned int len)
{
unsigned int i, j, n;
- unsigned char *ds = (unsigned char *)rxvt_malloc (PROP_SIZE);
+ unsigned char *ds = (unsigned char *)rxvt_malloc (PASTE_SIZE);
/* convert normal newline chars into common keyboard Return key sequence */
- for (i = 0; i < len; i += PROP_SIZE)
+ for (i = 0; i < len; i += PASTE_SIZE)
{
- n = min (len - i, PROP_SIZE);
+ n = min (len - i, PASTE_SIZE);
memcpy (ds, data + i, n);
for (j = 0; j < n; j++)
@@ -2684,13 +2684,9 @@ rxvt_term::paste (const unsigned char *data, unsigned int len)
* Respond to a notification that a primary selection has been sent
* EXT: SelectionNotify
*/
-int
+void
rxvt_term::selection_paste (Window win, Atom prop, bool delete_prop)
{
- long nread = 0;
- unsigned long bytes_after;
- XTextProperty ct;
-
if (prop == None) /* check for failed XConvertSelection */
{
if ((selection_type & Sel_CompoundText))
@@ -2713,36 +2709,83 @@ rxvt_term::selection_paste (Window win, Atom prop, bool delete_prop)
selection_type = 0;
}
- return 0;
+ return;
}
- for (;;)
+ unsigned long bytes_after;
+ XTextProperty ct;
+
+ if (XGetWindowProperty (display->display, win, prop,
+ 0, (long)(PROP_SIZE / 4),
+ delete_prop, AnyPropertyType,
+ &ct.encoding, &ct.format,
+ &ct.nitems, &bytes_after,
+ &ct.value) != Success)
{
- if (XGetWindowProperty (display->display, win, prop, (long) (nread / 4),
- (long) (PROP_SIZE / 4), delete_prop,
- AnyPropertyType, &ct.encoding, &ct.format,
- &ct.nitems, &bytes_after,
- &ct.value) != Success)
- break;
+ ct.value = 0;
+ goto bailout;
+ }
- if (ct.encoding == 0)
- break;
+ if (ct.encoding == None)
+ goto bailout;
- if (ct.encoding == xa[XA_INCR])
- {
- // INCR selection, start handshake
- XDeleteProperty (display->display, win, prop);
- selection_wait = Sel_incr;
- incr_ev.start (NOW + 10);
- break;
- }
+ if (bytes_after)
+ {
+ // fetch and append remaining data
+ XTextProperty ct2;
+ unsigned long bytes_after2;
+
+ if (XGetWindowProperty (display->display, win, prop,
+ ct.nitems / 4, (long) (bytes_after + 3) / 4,
+ delete_prop, AnyPropertyType,
+ &ct2.encoding, &ct2.format,
+ &ct2.nitems, &bytes_after2,
+ &ct2.value) != Success)
+ goto bailout;
+
+ // realloc should be compatible to XFree, here, and elsewhere, too
+ ct.value = (unsigned char *)realloc (ct.value, ct.nitems + bytes_after);
+ memcpy (ct.value + ct.nitems, ct2.value, ct2.nitems);
+ ct.nitems += ct2.nitems;
+
+ XFree (ct2.value);
+ }
+ else if (delete_prop)
+ XDeleteProperty (display->display, win, prop);
+
+ if (ct.value == 0)
+ goto bailout;
+
+ if (ct.encoding == xa[XA_INCR])
+ {
+ // INCR selection, start handshake
+ if (!delete_prop)
+ XDeleteProperty (display->display, win, prop);
- if (ct.value == NULL)
- continue;
+ selection_wait = Sel_incr;
+ incr_buf_fill = 0;
+ incr_ev.start (NOW + 10);
- if (ct.nitems == 0)
+ goto bailout;
+ }
+
+ if (ct.nitems == 0)
+ {
+ if (selection_wait == Sel_incr)
{
- if (selection_wait == Sel_normal && nread == 0
+ XFree (ct.value);
+
+ // finally complete, now paste the whole thing
+ selection_wait = Sel_normal;
+ ct.value = (unsigned char *)incr_buf;
+ ct.nitems = incr_buf_fill;
+ incr_buf = 0;
+ incr_buf_size = 0;
+ incr_ev.stop ();
+ }
+ else
+ {
+ if (selection_wait == Sel_normal
&& (win != display->root || prop != XA_CUT_BUFFER0)) // avoid recursion
{
/*
@@ -2752,54 +2795,58 @@ rxvt_term::selection_paste (Window win, Atom prop, bool delete_prop)
selection_paste (display->root, XA_CUT_BUFFER0, False);
}
- nread = -1; /* discount any previous stuff */
- break;
+ goto bailout;
}
+ }
+ else if (selection_wait == Sel_incr)
+ {
+ incr_ev.start (NOW + 10);
- nread += ct.nitems;
-
- char **cl;
- int cr;
-
-#if ENABLE_FRILLS
- // xlib is horribly broken with respect to UTF8_STRING, and nobody cares to fix it
- // so recode it manually
- if (ct.encoding == xa[XA_UTF8_STRING])
+ while (incr_buf_fill + ct.nitems > incr_buf_size)
{
- wchar_t *w = rxvt_utf8towcs ((const char *)ct.value, ct.nitems);
- char *s = rxvt_wcstombs (w);
+ incr_buf_size = incr_buf_size ? incr_buf_size * 2 : 128*1024;
+ incr_buf = (char *)realloc (incr_buf, incr_buf_size);
+ }
- // TODO: strlen == only the first element will be converted. well...
- paste ((unsigned char *)s, strlen (s));
+ memcpy (incr_buf + incr_buf_fill, ct.value, ct.nitems);
+ incr_buf_fill += ct.nitems;
- free (s);
- free (w);
- }
- else
-#endif
- if (XmbTextPropertyToTextList (display->display, &ct, &cl, &cr) >= 0 && cl)
- {
- for (int i = 0; i < cr; i++)
- paste ((unsigned char *)cl[i], strlen (cl[i]));
+ goto bailout;
+ }
- XFreeStringList (cl);
- }
- else
- paste (ct.value, ct.nitems);
+ char **cl;
+ int cr;
- if (bytes_after == 0)
- break;
+#if ENABLE_FRILLS
+ // xlib is horribly broken with respect to UTF8_STRING, and nobody cares to fix it
+ // so recode it manually
+ if (ct.encoding == xa[XA_UTF8_STRING])
+ {
+ wchar_t *w = rxvt_utf8towcs ((const char *)ct.value, ct.nitems);
+ char *s = rxvt_wcstombs (w);
+ free (w);
+ // TODO: strlen == only the first element will be converted. well...
+ paste ((unsigned char *)s, strlen (s));
+ free (s);
+ }
+ else
+#endif
+ if (XmbTextPropertyToTextList (display->display, &ct, &cl, &cr) >= 0
+ && cl)
+ {
+ for (int i = 0; i < cr; i++)
+ paste ((unsigned char *)cl[i], strlen (cl[i]));
- XFree (ct.value);
+ XFreeStringList (cl);
}
+ else
+ paste (ct.value, ct.nitems); // paste raw
- if (ct.value)
- XFree (ct.value);
+bailout:
+ XFree (ct.value);
if (selection_wait == Sel_normal)
selection_wait = Sel_none;
-
- return (int)nread;
}
void
@@ -2807,25 +2854,19 @@ rxvt_term::incr_cb (time_watcher &w)
{
selection_wait = Sel_none;
+ incr_buf_size = 0;
+ free (incr_buf);
+
rxvt_warn ("data loss: timeout on INCR selection paste, ignoring.\n");
}
-/*
- * INCR support originally provided by Paul Sheer
- */
void
rxvt_term::selection_property (Window win, Atom prop)
{
if (prop == None || selection_wait != Sel_incr)
return;
- if (selection_paste (win, prop, 1) > 0)
- incr_ev.start (NOW + 10);
- else
- {
- selection_wait = Sel_none;
- incr_ev.stop ();
- }
+ selection_paste (win, prop, true);
}
/* ------------------------------------------------------------------------- */
@@ -2872,8 +2913,8 @@ rxvt_term::selection_request (Time tm, int x, int y)
}
}
- selection_wait = Sel_none; /* don't loop in rxvt_selection_paste () */
- selection_paste (display->root, XA_CUT_BUFFER0, False);
+ selection_wait = Sel_none; /* don't loop in selection_paste () */
+ selection_paste (display->root, XA_CUT_BUFFER0, false);
}
int
-----END OF PAGE-----