From: root Date: Mon, 13 Dec 2004 01:29:03 +0000 (+0000) Subject: *** empty log message *** X-Git-Url: http://git.openbox.org/?a=commitdiff_plain;h=f326ea3e55b373a8fc76ec7eb0f06ea78df2e5ab;p=dana%2Furxvt.git *** empty log message *** --- diff --git a/Changes b/Changes index 60d7d3c5..28a1ef81 100644 --- 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 index aef23f41..e79ab868 100644 --- 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 index 76795d0c..942089fa 100644 --- 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 index cd539607..e2d5595f 100644 --- 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 index f232beb8..e0d7dbca 100644 --- 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