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 ~ 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 */