[75731f]: xterm-patch Maximize Restore History

Download this file

xterm-patch    1137 lines (1102 with data), 30.8 kB

diff -Naur xterm-200/VTPrsTbl.c xterm-200-new/VTPrsTbl.c
--- xterm-200/VTPrsTbl.c	2004-11-30 20:27:46.000000000 -0500
+++ xterm-200-new/VTPrsTbl.c	2005-04-05 22:35:40.000000000 -0400
@@ -399,6 +399,330 @@
 CASE_PRINT,
 };
 
+Const PARSE_T take_table[] =		/* TAKE Base64 SELECTION DATA */
+{
+/*	NUL		SOH		STX		ETX	*/
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+/*	EOT		ENQ		ACK		BEL	*/
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+/*	BS		HT		NL		VT	*/
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+/*	NP		CR		SO		SI	*/
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+/*	DLE		DC1		DC2		DC3	*/
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+/*	DC4		NAK		SYN		ETB	*/
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+/*	CAN		EM		SUB		ESC	*/
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+/*	FS		GS		RS		US	*/
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+/*	SP		!		"		#	*/
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+/*	$		%		&		'	*/
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+/*	(		)		*		+	*/
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE,
+/*	,		-		.		/	*/
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE,
+/*	0		1		2		3	*/
+CASE_TAKE,
+CASE_TAKE,
+CASE_TAKE,
+CASE_TAKE,
+/*	4		5		6		7	*/
+CASE_TAKE,
+CASE_TAKE,
+CASE_TAKE,
+CASE_TAKE,
+/*	8		9		:		;	*/
+CASE_TAKE,
+CASE_TAKE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+/*	<		=		>		?	*/
+CASE_TAKE_DONE,
+CASE_IGNORE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+/*	@		A		B		C	*/
+CASE_TAKE_DONE,
+CASE_TAKE,
+CASE_TAKE,
+CASE_TAKE,
+/*	D		E		F		G	*/
+CASE_TAKE,
+CASE_TAKE,
+CASE_TAKE,
+CASE_TAKE,
+/*	H		I		J		K	*/
+CASE_TAKE,
+CASE_TAKE,
+CASE_TAKE,
+CASE_TAKE,
+/*	L		M		N		O	*/
+CASE_TAKE,
+CASE_TAKE,
+CASE_TAKE,
+CASE_TAKE,
+/*	P		Q		R		S	*/
+CASE_TAKE,
+CASE_TAKE,
+CASE_TAKE,
+CASE_TAKE,
+/*	T		U		V		W	*/
+CASE_TAKE,
+CASE_TAKE,
+CASE_TAKE,
+CASE_TAKE,
+/*	X		Y		Z		[	*/
+CASE_TAKE,
+CASE_TAKE,
+CASE_TAKE,
+CASE_TAKE_DONE,
+/*	\		]		^		_	*/
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+/*	`		a		b		c	*/
+CASE_TAKE_DONE,
+CASE_TAKE,
+CASE_TAKE,
+CASE_TAKE,
+/*	d		e		f		g	*/
+CASE_TAKE,
+CASE_TAKE,
+CASE_TAKE,
+CASE_TAKE,
+/*	h		i		j		k	*/
+CASE_TAKE,
+CASE_TAKE,
+CASE_TAKE,
+CASE_TAKE,
+/*	l		m		n		o	*/
+CASE_TAKE,
+CASE_TAKE,
+CASE_TAKE,
+CASE_TAKE,
+/*	p		q		r		s	*/
+CASE_TAKE,
+CASE_TAKE,
+CASE_TAKE,
+CASE_TAKE,
+/*	t		u		v		w	*/
+CASE_TAKE,
+CASE_TAKE,
+CASE_TAKE,
+CASE_TAKE,
+/*	x		y		z		{	*/
+CASE_TAKE,
+CASE_TAKE,
+CASE_TAKE,
+CASE_TAKE_DONE,
+/*	|		}		~		DEL	*/
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+/*      0x80            0x81            0x82            0x83    */
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+/*      0x84            0x85            0x86            0x87    */
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+/*      0x88            0x89            0x8a            0x8b    */
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+/*      0x8c            0x8d            0x8e            0x8f    */
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+/*      0x90            0x91            0x92            0x93    */
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+/*      0x94            0x95            0x96            0x97    */
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+/*      0x98            0x99            0x9a            0x9b    */
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+/*      0x9c            0x9d            0x9e            0x9f    */
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+/*      nobreakspace    exclamdown      cent            sterling        */
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+/*      currency        yen             brokenbar       section         */
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+/*      diaeresis       copyright       ordfeminine     guillemotleft   */
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+/*      notsign         hyphen          registered      macron          */
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+/*      degree          plusminus       twosuperior     threesuperior   */
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+/*      acute           mu              paragraph       periodcentered  */
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+/*      cedilla         onesuperior     masculine       guillemotright  */
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+/*      onequarter      onehalf         threequarters   questiondown    */
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+/*      Agrave          Aacute          Acircumflex     Atilde          */
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+/*      Adiaeresis      Aring           AE              Ccedilla        */
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+/*      Egrave          Eacute          Ecircumflex     Ediaeresis      */
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+/*      Igrave          Iacute          Icircumflex     Idiaeresis      */
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+/*      Eth             Ntilde          Ograve          Oacute          */
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+/*      Ocircumflex     Otilde          Odiaeresis      multiply        */
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+/*      Ooblique        Ugrave          Uacute          Ucircumflex     */
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+/*      Udiaeresis      Yacute          Thorn           ssharp          */
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+/*      agrave          aacute          acircumflex     atilde          */
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+/*      adiaeresis      aring           ae              ccedilla        */
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+/*      egrave          eacute          ecircumflex     ediaeresis      */
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+/*      igrave          iacute          icircumflex     idiaeresis      */
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+/*      eth             ntilde          ograve          oacute          */
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+/*      ocircumflex     otilde          odiaeresis      division        */
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+/*      oslash          ugrave          uacute          ucircumflex     */
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+/*      udiaeresis      yacute          thorn           ydiaeresis      */
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE,
+CASE_TAKE_DONE
+};
+
 Const PARSE_T csi_table[] =		/* CSI */
 {
 /*	NUL		SOH		STX		ETX	*/
@@ -877,7 +1201,7 @@
 CASE_GROUND_STATE,
 /*	x		y		z		{	*/
 CASE_DECREQTPARM,
-CASE_GROUND_STATE,
+CASE_PASTE,
 CASE_GROUND_STATE,
 CASE_GROUND_STATE,
 /*	|		}		~		DEL	*/
@@ -2774,7 +3098,7 @@
 CASE_GROUND_STATE,
 CASE_GROUND_STATE,
 /*	P		Q		R		S	*/
-CASE_GROUND_STATE,
+CASE_PASTE,
 CASE_GROUND_STATE,
 CASE_GROUND_STATE,
 CASE_GROUND_STATE,
diff -Naur xterm-200/VTparse.def xterm-200-new/VTparse.def
--- xterm-200/VTparse.def	2004-11-30 20:27:46.000000000 -0500
+++ xterm-200-new/VTparse.def	2005-04-05 22:29:16.000000000 -0400
@@ -140,3 +140,6 @@
 CASE_DECCARA
 CASE_DECRARA
 CASE_CSI_STAR_STATE
+CASE_PASTE
+CASE_TAKE
+CASE_TAKE_DONE
diff -Naur xterm-200/VTparse.h xterm-200-new/VTparse.h
--- xterm-200/VTparse.h	2004-11-30 20:27:46.000000000 -0500
+++ xterm-200-new/VTparse.h	2005-04-06 11:52:19.000000000 -0400
@@ -82,6 +82,7 @@
 extern Const PARSE_T scrtable[];
 extern Const PARSE_T scstable[];
 extern Const PARSE_T sos_table[];
+extern Const PARSE_T take_table[];
 
 #if OPT_DEC_LOCATOR
 extern Const PARSE_T csi_tick_table[];
@@ -244,5 +245,8 @@
 #define CASE_DECCARA 128
 #define CASE_DECRARA 129
 #define CASE_CSI_STAR_STATE 130
+#define CASE_PASTE 131
+#define CASE_TAKE 132
+#define CASE_TAKE_DONE 133
 
 #endif /* included_VTparse_h */
diff -Naur xterm-200/button.c xterm-200-new/button.c
--- xterm-200/button.c	2005-02-06 16:42:37.000000000 -0500
+++ xterm-200-new/button.c	2005-04-06 11:31:46.000000000 -0400
@@ -1174,7 +1174,9 @@
     return cutbuffer;
 }
 
-static void
+int base64_paste = 0;	/* Set if paste data should be sent as base64 */
+
+void
 _GetSelection(Widget w,
 	      Time ev_time,
 	      String * params,	/* selections in precedence order */
@@ -1208,19 +1210,34 @@
 	int fmt8 = 8;
 	Atom type = XA_STRING;
 	char *line;
+	int x;
+
+        /* Selection from X server */
+
+#if OPT_WIDE_CHARS
+        /* Joe Allen - 2005-4-4: assume X's cut buffer is UTF-8 if
+           the xterm is UTF-8 */
+        if (term->screen.utf8_mode)
+            type = XA_UTF8_STRING(XtDisplay(w));
+#endif
 
 	/* 'line' is freed in SelectionReceived */
 	line = XFetchBuffer(XtDisplay(w), &inbytes, cutbuffer);
 	nbytes = (unsigned long) inbytes;
+
 	if (nbytes > 0)
 	    SelectionReceived(w, NULL, &selection, &type, (XtPointer) line,
 			      &nbytes, &fmt8);
 	else if (num_params > 1)
 	    _GetSelection(w, ev_time, params + 1, num_params - 1, NULL);
+        else
+            base64_paste = 0;
 	return;
     } else {
 	struct _SelectionList *list;
 
+	/* Selection owned by someone */
+
 	if (targets == NULL || targets[0] == None) {
 	    targets = _SelectionTargets(w);
 	}
@@ -1280,9 +1297,65 @@
 #  define tty_vwrite(pty,lag,l)		v_write(pty,lag,l)
 #endif /* defined VMS */
 
+/* Return base64 code character given 6-bit number */
+
+char base64_code[]="\
+ABCDEFGHIJKLMNOPQRSTUVWXYZ\
+abcdefghijklmnopqrstuvwxyz\
+0123456789+/";
+
+/* Be careful: _qWriteSelectionData expects these to be initialized
+   to zero.  Base64_flush() is the last step of the conversion, it
+   clears these variables. */
+
+int base64_accu = 0;
+int base64_count = 0;
+int base64_pad = 0;
+
 static void
 _qWriteSelectionData(TScreen * screen, Char * lag, unsigned length)
 {
+    if (base64_paste) {
+        /* Send data as base64 */
+        unsigned char *p = (unsigned char *)lag;
+        Char buf[64];
+        unsigned x = 0;
+        while (length--) {
+            switch (base64_count) {
+                case 0:
+                    buf[x++] = base64_code[*p >> 2];
+                    base64_accu = (*p & 0x3);
+                    base64_count = 2;
+                    ++p;
+                    break;
+                case 2:
+                    buf[x++] = base64_code[(base64_accu << 4) + (*p >> 4)];
+                    base64_accu = (*p & 0xF);
+                    base64_count = 4;
+                    ++p;
+                    break;
+                case 4:
+                    buf[x++] = base64_code[(base64_accu << 2) + (*p >> 6)];
+                    buf[x++] = base64_code[*p & 0x3F];
+                    base64_accu = 0;
+                    base64_count = 0;
+                    ++p;
+                    break;
+            }
+            if (x >= 63) {
+                /* Write 63 or 64 characters */
+                base64_pad += x;
+                tty_vwrite(screen->respond, buf, x);
+                x = 0;
+            }
+        }
+        if (x != 0) {
+            base64_pad += x;
+            tty_vwrite(screen->respond, buf, x);
+        }
+        return;
+    }
+
 #if OPT_READLINE
     if (SCREEN_FLAG(screen, paste_quotes)) {
 	while (length--) {
@@ -1295,6 +1368,29 @@
 }
 
 static void
+base64_flush(TScreen *screen)
+{
+    unsigned char x;
+    switch (base64_count) {
+        case 0:
+            break;
+        case 2:
+            x = base64_code[base64_accu << 4];
+            tty_vwrite(screen->respond, &x, 1);
+            break;
+        case 4:
+            x = base64_code[base64_accu << 2];
+            tty_vwrite(screen->respond, &x, 1);
+            break;
+    }
+    if (base64_pad & 3)
+        tty_vwrite(screen->respond, "===", 4 - (base64_pad & 3));
+    base64_count = 0;
+    base64_accu = 0;
+    base64_pad = 0;
+}
+
+static void
 _WriteSelectionData(TScreen * screen, Char * line, int length)
 {
     /* Write data to pty a line at a time. */
@@ -1325,13 +1421,14 @@
     if (lag != end) {
 	_qWriteSelectionData(screen, lag, (unsigned) (end - lag));
     }
+    if (base64_paste)
+        base64_flush(screen);
 #ifdef VMS
     tt_pasting = False;
     tt_start_read();		/* reenable reads or a character may be lost */
 #endif
 }
 
-#if OPT_READLINE
 static void
 _WriteKey(TScreen * screen, Char * in)
 {
@@ -1350,7 +1447,6 @@
     line[count++] = '~';
     tty_vwrite(screen->respond, line, count);
 }
-#endif /* OPT_READLINE */
 
 /* SelectionReceived: stuff received selection text into pty */
 
@@ -1434,18 +1530,20 @@
     if (text_list != NULL && text_list_count != 0) {
 	int i;
 
-#if OPT_READLINE
-	if (SCREEN_FLAG(screen, paste_brackets))
+	if (base64_paste)
+	    _WriteKey(screen, "202");
+	else if (screen->paste_brackets)
 	    _WriteKey(screen, "200");
-#endif
 	for (i = 0; i < text_list_count; i++) {
 	    int len = strlen(text_list[i]);
 	    _WriteSelectionData(screen, (Char *) text_list[i], len);
 	}
-#if OPT_READLINE
-	if (SCREEN_FLAG(screen, paste_brackets))
+	if (base64_paste) {
+	    tty_vwrite(screen->respond, "\33", 1);
+	    base64_paste = 0;
+        }
+        else if (screen->paste_brackets)
 	    _WriteKey(screen, "201");
-#endif
 	XFreeStringList(text_list);
     } else
 	goto fail;
@@ -1461,6 +1559,8 @@
 	_GetSelection(w, list->time,
 		      list->params, list->count, list->targets);
 	XtFree((char *) client_data);
+    } else {
+        base64_paste = 0;
     }
     return;
 }
@@ -2452,6 +2552,96 @@
     _OwnSelection(term, params, num_params);
 }
 
+void ClearSelectionBuffer()
+{
+    TScreen *screen = &term->screen;
+    screen->selection_length = 0;
+    base64_count = 0;
+}
+
+void AppendStrToSelectionBuffer(Char *text,int len)
+{
+    TScreen *screen = &term->screen;
+    if (len != 0) {
+        int j = screen->selection_length + len; /* New length */
+        int k = j + (j >> 2) + 80; /* New size if we grow buffer: grow by ~50% */
+        if (j + 1 >= screen->selection_size) {
+            if (!screen->selection_length) {
+                /* New buffer */
+                Char *line;
+                if ((line = (Char *) malloc((unsigned) k)) == 0)
+                    SysError(ERROR_BMALLOC2);
+                XtFree((char *) screen->selection_data);
+                screen->selection_data = line;
+            } else {
+                /* Realloc buffer */
+                screen->selection_data = (Char *) realloc(screen->selection_data, (unsigned) k);
+                if (screen->selection_data == 0)
+                    SysError(ERROR_BMALLOC2);
+            }
+            screen->selection_size = k;
+        }
+        memcpy(screen->selection_data + screen->selection_length, text, len);
+        screen->selection_length += len;
+        screen->selection_data[screen->selection_length] = 0;
+    }
+}
+
+void AppendToSelectionBuffer(unsigned c)
+{
+    int six;
+    Char ch;
+
+    /* Decode base64 character */
+    if (c >= 'A' && c <= 'Z')
+        six = c - 'A';
+    else if (c >= 'a' && c <= 'z')
+        six = c - 'a' + 26;
+    else if (c >= '0' && c <= '9')
+        six = c - '0' + 52;
+    else if (c == '+')
+        six = 62;
+    else
+        six = 63;
+
+    /* Accumulate bytes */
+    switch (base64_count) {
+        case 0:
+            base64_accu = six;
+            base64_count = 6;
+            break;
+
+        case 2:
+            ch = (base64_accu << 6) + six;
+            base64_count = 0;
+            AppendStrToSelectionBuffer(&ch, 1);
+            break;
+
+        case 4:
+            ch = (base64_accu << 4) + (six >> 2);
+            base64_accu = (six & 0x3);
+            base64_count = 2;
+            AppendStrToSelectionBuffer(&ch, 1);
+            break;
+
+        case 6:
+            ch = (base64_accu << 2) + (six >> 4);
+            base64_accu = (six & 0xF);
+            base64_count = 4;
+            AppendStrToSelectionBuffer(&ch, 1);
+            break;
+    }
+}
+
+extern char *select_args[]; /* in charproc.c */
+
+void CompleteSelection()
+{
+    base64_count = 0;
+    base64_accu = 0;
+    _OwnSelection(term, select_args, 2);
+}
+
 static Bool
 _ConvertSelectionHelper(Widget w,
 			Atom * type, XtPointer *value,
@@ -2715,9 +2905,14 @@
 		 */
 		unsigned long length = termw->screen.selection_length;
 		Char *data = termw->screen.selection_data;
+#ifdef junk
+/* These days it's better to assume that X server's cut & paste buffers
+   are UTF-8 when the locale is UTF-8.
+    Joe Allen, 2005-04-04 */
 		if_OPT_WIDE_CHARS((&(termw->screen)), {
 		    data = UTF8toLatin1(data, length, &length);
 		});
+#endif
 		TRACE(("XStoreBuffer(%d)\n", cutbuffer));
 		XStoreBuffer(XtDisplay((Widget) termw),
 			     (char *) data,
@@ -2885,6 +3080,18 @@
     return (result);
 }
 
+/* 32 + following 7-bit word:
+
+   1:0  Button no: 0, 1, 2.  3=release.
+     2  shift
+     3  meta
+     4  ctrl
+     5  set for motion notify
+     6  set for wheel
+*/
+
+/* Position: 32 - 255. */
+
 static int
 BtnCode(XButtonEvent * event, int button)
 {
@@ -2904,6 +3111,16 @@
 
 #define MOUSE_LIMIT (255 - 32)
 
+/* When screen->out_of_frame set, coordinates can go outside
+   of frame as follows:
+     Code            Coord     
+     ----            -----
+     33 - 240        1 - 208  (208 positive coordinates)
+     32, 255 - 241   0, -1 - -15  (16 negative coordinates)
+
+   When range is exceeded, the maximum closest value is sent
+*/
+
 static void
 EditorButton(XButtonEvent * event)
 {
@@ -2923,20 +3140,41 @@
     row = (event->y - screen->border) / FontHeight(screen);
     col = (event->x - OriginX(screen)) / FontWidth(screen);
 
-    /* Limit to screen dimensions */
-    if (row < 0)
-	row = 0;
-    else if (row > screen->max_row)
-	row = screen->max_row;
-    else if (row > MOUSE_LIMIT)
-	row = MOUSE_LIMIT;
-
-    if (col < 0)
-	col = 0;
-    else if (col > screen->max_col)
-	col = screen->max_col;
-    else if (col > MOUSE_LIMIT)
-	col = MOUSE_LIMIT;
+    if (screen->out_of_frame) {
+        if (row > 207)
+            row = 207;
+        else if (row < -16)
+            row = 208;
+        else if (row == -1)
+            row = -1;
+        else if (row < 0)
+            row = 224 + row;
+
+        if (col > 207)
+            col = 207;
+        else if (col < -16)
+            col = 208;
+        else if (col == -1)
+            col = -1;
+        else if (col < 0)
+            col = 224 + col;
+        
+    } else {
+        /* Limit to screen dimensions */
+        if (row < 0)
+            row = 0;
+        else if (row > screen->max_row)
+            row = screen->max_row;
+        else if (row > MOUSE_LIMIT)
+            row = MOUSE_LIMIT;
+
+        if (col < 0)
+            col = 0;
+        else if (col > screen->max_col)
+            col = screen->max_col;
+        else if (col > MOUSE_LIMIT)
+            col = MOUSE_LIMIT;
+    }
 
     /* Build key sequence starting with \E[M */
     if (screen->control_eight_bits) {
diff -Naur xterm-200/charproc.c xterm-200-new/charproc.c
--- xterm-200/charproc.c	2005-02-06 16:42:38.000000000 -0500
+++ xterm-200-new/charproc.c	2005-04-06 11:32:53.000000000 -0400
@@ -1098,6 +1098,20 @@
 
 static struct ParseState myState;
 
+extern Widget current_widget;
+extern XEvent *current_event;
+extern String *current_params;
+extern Cardinal *current_num_params;
+
+char *select_args[]=
+{
+  "PRIMARY",
+  "CUT_BUFFER0",
+  0
+};
+
+extern int base64_paste;
+
 static Boolean
 doparsing(unsigned c, struct ParseState *sp)
 {
@@ -1121,7 +1135,19 @@
 
     do {
 #if OPT_WIDE_CHARS
-	if (screen->wide_chars
+
+        /* Feed wide characters into state machine when we're
+           reading in a selection */
+        if (sp->parsestate == take_table) {
+            if (c < 256)
+              sp->nextstate = sp->parsestate[E2A(c)];
+            else
+              sp->nextstate = CASE_TAKE;
+            goto just_take_it;
+        }
+
+        /* Jhallen: this code was very very slow, so I put in the (c >= 0x300) */
+	if (c >= 0x300 && screen->wide_chars
 	    && my_wcwidth((int) c) == 0) {
 	    int prev, precomposed;
 
@@ -1366,6 +1392,8 @@
 	    string_used = 0;
 	}
 
+	just_take_it:
+
 	TRACE(("parse %04X -> %d %s\n", c, sp->nextstate, which_table(sp->parsestate)));
 
 	switch (sp->nextstate) {
@@ -1654,6 +1682,38 @@
 	    sp->parsestate = sp->groundtable;
 	    break;
 
+        case CASE_PASTE: {
+            int cmd = param[0];
+            TRACE(("CASE_PASTE - cut & paste\n"));
+            if (cmd < 2)
+                cmd = 0;
+            if (cmd == 0) {
+                TRACE(("CASE_PASTE - paste selection\n"));
+                /* Paste current selection */
+                base64_paste = 1; /* Tells _GetSelection data is base64 encoded */
+                _GetSelection(current_widget, 0, select_args, 2, NULL);
+                /* _GetSelection clears base64_paste */
+                sp->parsestate = sp->groundtable;
+            } else if (cmd == 2) {
+                TRACE(("CASE_PASTE - taking selection data\n"));
+                ClearSelectionBuffer();
+                sp->parsestate = take_table;
+            } else
+                sp->parsestate = sp->groundtable;
+            break;
+        }
+
+        case CASE_TAKE: {
+            AppendToSelectionBuffer(c);
+            sp->parsestate = take_table;
+            break;
+        }
+
+        case CASE_TAKE_DONE:
+            CompleteSelection();
+            sp->parsestate = sp->groundtable;
+            break;
+
 	case CASE_ECH:
 	    TRACE(("CASE_ECH - erase char\n"));
 	    /* ECH */
@@ -3877,6 +3937,12 @@
 	    set_keyboard_type(keyboardIsVT220, func == bitset);
 	    break;
 #endif
+	case SET_PASTE_IN_BRACKET:
+	    screen->paste_brackets = (func == bitset);
+	    break;
+        case SET_OUT_OF_FRAME:
+            screen->out_of_frame = (func == bitset);
+            break;
 #if OPT_READLINE
 	case SET_BUTTON1_MOVE_POINT:
 	    set_mouseflag(click1_moves);
@@ -3887,9 +3953,6 @@
 	case SET_DBUTTON3_DELETE:
 	    set_mouseflag(dclick3_deletes);
 	    break;
-	case SET_PASTE_IN_BRACKET:
-	    set_mouseflag(paste_brackets);
-	    break;
 	case SET_PASTE_QUOTE:
 	    set_mouseflag(paste_quotes);
 	    break;
@@ -3993,6 +4056,12 @@
 		CursorSave(termw);
 	    }
 	    break;
+	case SET_PASTE_IN_BRACKET:
+	    DoSM(DP_PASTE_BRACKETS, screen->paste_brackets);
+	    break;
+        case SET_OUT_OF_FRAME:
+            DoSM(DP_OUT_OF_FRAME, screen->out_of_frame);
+            break;
 #if OPT_READLINE
 	case SET_BUTTON1_MOVE_POINT:
 	    SCREEN_FLAG_save(screen, click1_moves);
@@ -4003,9 +4072,6 @@
 	case SET_DBUTTON3_DELETE:
 	    SCREEN_FLAG_save(screen, dclick3_deletes);
 	    break;
-	case SET_PASTE_IN_BRACKET:
-	    SCREEN_FLAG_save(screen, paste_brackets);
-	    break;
 	case SET_PASTE_QUOTE:
 	    SCREEN_FLAG_save(screen, paste_quotes);
 	    break;
@@ -4156,6 +4222,11 @@
 		CursorRestore(termw);
 	    }
 	    break;
+	case SET_PASTE_IN_BRACKET:
+	    DoRM(DP_PASTE_BRACKETS, screen->paste_brackets);
+	    break;
+        case SET_OUT_OF_FRAME:
+            DoRM(DP_OUT_OF_FRAME, screen->out_of_frame);
 #if OPT_READLINE
 	case SET_BUTTON1_MOVE_POINT:
 	    SCREEN_FLAG_restore(screen, click1_moves);
@@ -4166,9 +4237,6 @@
 	case SET_DBUTTON3_DELETE:
 	    SCREEN_FLAG_restore(screen, dclick3_deletes);
 	    break;
-	case SET_PASTE_IN_BRACKET:
-	    SCREEN_FLAG_restore(screen, paste_brackets);
-	    break;
 	case SET_PASTE_QUOTE:
 	    SCREEN_FLAG_restore(screen, paste_quotes);
 	    break;
diff -Naur xterm-200/ctlseqs.ms xterm-200-new/ctlseqs.ms
--- xterm-200/ctlseqs.ms	2005-01-13 20:50:00.000000000 -0500
+++ xterm-200-new/ctlseqs.ms	2005-04-06 11:45:04.000000000 -0400
@@ -792,6 +792,8 @@
   \*(Ps = \*1\*0\*5\*3 \(-> Set SCO function-key mode.
   \*(Ps = \*1\*0\*6\*0 \(-> Set legacy keyboard emulation (X11R6).
   \*(Ps = \*1\*0\*6\*1 \(-> Set Sun/PC keyboard emulation of VT220 keyboard.
+  \*(Ps = \*2\*0\*0\*4 \(-> Set bracketed paste mode.
+  \*(Ps = \*2\*0\*0\*7 \(-> Allow mouse coordinates beyond frame.
 .
 .IP \\*(Cs\\*(Pm\\*s\\*i
 Media Copy (MC)
@@ -869,6 +871,8 @@
   \*(Ps = \*1\*0\*5\*3 \(-> Reset SCO function-key mode.
   \*(Ps = \*1\*0\*6\*0 \(-> Reset legacy keyboard emulation (X11R6).
   \*(Ps = \*1\*0\*6\*1 \(-> Reset Sun/PC keyboard emulation of VT220 keyboard.
+  \*(Ps = \*2\*0\*0\*4 \(-> Reset bracketed paste mode.
+  \*(Ps = \*2\*0\*0\*7 \(-> Mouse coordinates constrained within frame.
 .
 .IP \\*(Cs\\*(Pm\\*s\\*m
 Character Attributes (SGR)
@@ -1086,6 +1090,15 @@
   \*(Pc is the character to use.
   \*(Pt\*;\*(Pl\*;\*(Pb\*;\*(Pr denotes the rectangle.
 .
+.IP \\*(Cs\\*?\\*(Ps\\*s\\*P
+Cut and Paste.
+  \*(Ps = \*1 \(-> Paste (default).  The current selection is sent to the program in Base64:
+ESC [ ? 202 ~ <base64-data> ESC.
+  \*(Ps = \*2 \(-> Select.  Give Base64 encoded selection
+data to Xterm.  Base64 encoded data is sent to the XTerm following this command.  The Data
+is terminated with a single ESC.  This data becomes the new selection, which is then
+available for pasting by other applications.
+.
 .IP \\*(Cs\\*(Ps\\*s\\*;\\*(Pu\\*s\\*(qu\\*z
 Enable Locator Reporting (DECELR)
 .br
@@ -1563,6 +1576,14 @@
 to make the details of switching independent of the application that
 requests the switch.
 .SH
+Bracketed Paste Mode
+.ds RH Bracketed Paste Mode
+.LP
+When bracketed paste mode is set, pasted text is bracketed with control
+sequences so that the program can differentiate pasted text from typed-in
+text.  When bracketed paste mode is set, the program will receive: ESC [ 200 ~,
+followed by the pasted text, followed by ESC [ 201 ~.
+.SH
 Mouse Tracking
 .ds RH Mouse Tracking
 .LP
@@ -1592,6 +1613,7 @@
 #define SET_VT200_HIGHLIGHT_MOUSE   1001
 #define SET_BTN_EVENT_MOUSE         1002
 #define SET_ANY_EVENT_MOUSE         1003
+#define SET_OUT_OF_FRAME            2007
 .DE
 .LP
 The motion reporting modes are strictly \fIxterm\fP extensions, and are not
@@ -1605,6 +1627,13 @@
 For example, \*! specifies the value 1.
 The upper left character position on the terminal is denoted as 1,1.
 
+If OUT_OF_FRAME mode is enabled, and the mouse goes beyond the window frame,
+coordinates beyond the frame are sent to the program.  Coordinate values 1 -
+208 are sent as usual, as byte values between 33 and 240.  The coordinate
+value 0 (the first cell above or to the left of the frame) is sent as SPACE
+(32).  The coordinate values -15 through -1 are sent as byte values 241
+through 255.
+
 X10 compatibility mode sends an escape sequence only on button press,
 encoding the location and the mouse button pressed.
 It is enabled by specifying parameter 9 to DECSET.
diff -Naur xterm-200/misc.c xterm-200-new/misc.c
--- xterm-200/misc.c	2005-01-29 17:17:32.000000000 -0500
+++ xterm-200-new/misc.c	2005-03-27 17:29:23.000000000 -0500
@@ -228,6 +228,11 @@
     return (c);
 }
 
+Widget current_widget;
+XEvent *current_event;
+String *current_params;
+Cardinal *current_num_params;
+
 /* ARGSUSED */
 void
 HandleKeyPressed(Widget w GCC_UNUSED,
@@ -238,9 +243,14 @@
     TScreen *screen = &term->screen;
 
     TRACE(("Handle 7bit-key\n"));
+    current_widget = w;
+    current_event = event;
+    current_params = params;
+    current_num_params = nparams;
 #ifdef ACTIVEWINDOWINPUTONLY
     if (w == CURRENT_EMU(screen))
 #endif
+
 	Input(&term->keyboard, screen, &event->xkey, False);
 }
 
diff -Naur xterm-200/paste xterm-200-new/paste
--- xterm-200/paste	1969-12-31 19:00:00.000000000 -0500
+++ xterm-200-new/paste	2005-04-06 11:46:10.000000000 -0400
@@ -0,0 +1 @@
+[?P
diff -Naur xterm-200/ptyx.h xterm-200-new/ptyx.h
--- xterm-200/ptyx.h	2005-01-13 20:50:03.000000000 -0500
+++ xterm-200-new/ptyx.h	2005-03-28 22:48:06.000000000 -0500
@@ -1108,6 +1108,8 @@
 #if OPT_TOOLBAR
 	DP_TOOLBAR,
 #endif
+	DP_PASTE_BRACKETS,
+	DP_OUT_OF_FRAME,
 	DP_LAST
 } SaveModes;
 
@@ -1269,11 +1271,12 @@
 	unsigned long	event_mask;
 	unsigned short	send_mouse_pos;	/* user wants mouse transition  */
 					/* and position information	*/
+	unsigned	paste_brackets;
+	unsigned	out_of_frame;
 #if OPT_READLINE
 	unsigned	click1_moves;
 	unsigned	paste_moves;
 	unsigned	dclick3_deletes;
-	unsigned	paste_brackets;
 	unsigned	paste_quotes;
 	unsigned	paste_literal_nl;
 #endif	/* OPT_READLINE */
diff -Naur xterm-200/select xterm-200-new/select
--- xterm-200/select	1969-12-31 19:00:00.000000000 -0500
+++ xterm-200-new/select	2005-04-06 11:47:39.000000000 -0400
@@ -0,0 +1,2 @@
+[?2PSGVsbG8sIHdvcmxkIQo=
+
diff -Naur xterm-200/xcharmouse.h xterm-200-new/xcharmouse.h
--- xterm-200/xcharmouse.h	2002-08-24 14:54:39.000000000 -0400
+++ xterm-200-new/xcharmouse.h	2005-03-28 22:39:35.000000000 -0500
@@ -50,6 +50,8 @@
 #define SET_PASTE_IN_BRACKET        2004 /* Surround paste by escapes */
 #define SET_PASTE_QUOTE             2005 /* Quote each char during paste */
 #define SET_PASTE_LITERAL_NL        2006 /* Paste "\n" as C-j */
+#define SET_OUT_OF_FRAME            2007 /* Give mouse coords even when cursor
+                                            is outside of frame */
 
 #if OPT_DEC_LOCATOR
 
diff -Naur xterm-200/xterm.h xterm-200-new/xterm.h
--- xterm-200/xterm.h	2005-01-13 20:50:03.000000000 -0500
+++ xterm-200-new/xterm.h	2005-03-30 22:35:45.000000000 -0500
@@ -603,6 +603,9 @@
 extern void DisownSelection (XtermWidget termw);
 extern void HandleGINInput            PROTO_XT_ACTIONS_ARGS;
 extern void HandleInsertSelection     PROTO_XT_ACTIONS_ARGS;
+
+extern void _GetSelection (Widget w, Time ev_time, String *params, Cardinal num_params, Atom *targets);
+
 extern void HandleKeyboardSelectEnd   PROTO_XT_ACTIONS_ARGS;
 extern void HandleKeyboardSelectStart PROTO_XT_ACTIONS_ARGS;
 extern void HandleKeyboardStartExtend PROTO_XT_ACTIONS_ARGS;
@@ -630,6 +633,10 @@
 extern Bool iswide(int i);
 #endif
 
+extern void ClearSelectionBuffer ();
+extern void AppendToSelectionBuffer (unsigned c);
+extern void CompleteSelection ();
+
 /* charproc.c */
 extern int VTInit (void);
 extern int v_write (int f, Char *d, unsigned len);
@@ -1052,4 +1059,6 @@
 	}
 #endif
 
+
+
 #endif	/* included_xterm_h */