ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/rxvt-unicode/src/command.C
(Generate patch)

Comparing rxvt-unicode/src/command.C (file contents):
Revision 1.44 by pcg, Fri Feb 13 12:17:07 2004 UTC vs.
Revision 1.64 by pcg, Wed Mar 3 04:07:52 2004 UTC

25 * - extensive modifications 25 * - extensive modifications
26 * Copyright (c) 1998 Alfredo K. Kojima <kojima@windowmaker.org> 26 * Copyright (c) 1998 Alfredo K. Kojima <kojima@windowmaker.org>
27 * Copyright (c) 2001 Marius Gedminas 27 * Copyright (c) 2001 Marius Gedminas
28 * - Ctrl/Mod4+Tab works like Meta+Tab (options) 28 * - Ctrl/Mod4+Tab works like Meta+Tab (options)
29 * Copyright (c) 2003 Rob McMullen <robm@flipturn.org> 29 * Copyright (c) 2003 Rob McMullen <robm@flipturn.org>
30 * Copyright (c) 2003-2004 Marc Lehmann <pcg@goof.com>
30 * 31 *
31 * This program is free software; you can redistribute it and/or modify 32 * This program is free software; you can redistribute it and/or modify
32 * it under the terms of the GNU General Public License as published by 33 * it under the terms of the GNU General Public License as published by
33 * the Free Software Foundation; either version 2 of the License, or 34 * the Free Software Foundation; either version 2 of the License, or
34 * (at your option) any later version. 35 * (at your option) any later version.
55 56
56/*{{{ Convert the keypress event into a string */ 57/*{{{ Convert the keypress event into a string */
57void 58void
58rxvt_term::lookup_key (XKeyEvent &ev) 59rxvt_term::lookup_key (XKeyEvent &ev)
59{ 60{
60 int ctrl, meta, shft, len; 61 int ctrl, meta, shft, len;
61 unsigned int newlen; 62 unsigned int newlen;
62 KeySym keysym; 63 KeySym keysym;
63#ifdef DEBUG_CMD 64#ifdef DEBUG_CMD
64 static int debug_key = 1; /* accessible by a debugger only */ 65 static int debug_key = 1; /* accessible by a debugger only */
65#endif 66#endif
66 int valid_keysym; 67 int valid_keysym;
67 unsigned char kbuf[KBUFSZ]; 68 unsigned char kbuf[KBUFSZ];
68 69
69 /* 70 /*
70 * use Num_Lock to toggle Keypad on/off. If Num_Lock is off, allow an 71 * use Num_Lock to toggle Keypad on/off. If Num_Lock is off, allow an
71 * escape sequence to toggle the Keypad. 72 * escape sequence to toggle the Keypad.
88 if (Input_Context) 89 if (Input_Context)
89 { 90 {
90 Status status_return; 91 Status status_return;
91 92
92#ifdef X_HAVE_UTF8_STRING 93#ifdef X_HAVE_UTF8_STRING
93 if (enc_utf8 && 0) 94 if (enc_utf8 && 0) // currently disabled, doesn't seem to work, nor is useful
94 len = Xutf8LookupString (Input_Context, &ev, (char *)kbuf, 95 len = Xutf8LookupString (Input_Context, &ev, (char *)kbuf,
95 KBUFSZ, &keysym, &status_return); 96 KBUFSZ, &keysym, &status_return);
96 else 97 else
97#endif 98#endif
98
99 { 99 {
100 wchar_t wkbuf[KBUFSZ + 1]; 100 wchar_t wkbuf[KBUFSZ + 1];
101 101
102 // the XOpenIM manpage lies about hardcoding the locale 102 // the XOpenIM manpage lies about hardcoding the locale
103 // at the point of XOpenIM, so temporarily switch locales 103 // at the point of XOpenIM, so temporarily switch locales
108 KBUFSZ, &keysym, &status_return); 108 KBUFSZ, &keysym, &status_return);
109 if (rs[Rs_imLocale]) 109 if (rs[Rs_imLocale])
110 SET_LOCALE (locale); 110 SET_LOCALE (locale);
111 111
112 if (status_return == XLookupChars 112 if (status_return == XLookupChars
113 || status_return == XLookupBoth) 113 || status_return == XLookupBoth)
114 { 114 {
115 /* make sure the user can type ctrl-@, i.e. NUL */
116 if (len == 1 && *wkbuf == 0)
117 {
118 kbuf[0] = 0;
119 len = 1;
120 }
121 else
122 {
115 wkbuf[len] = 0; 123 wkbuf[len] = 0;
116 len = wcstombs ((char *)kbuf, wkbuf, KBUFSZ); 124 len = wcstombs ((char *)kbuf, wkbuf, KBUFSZ);
117 if (len < 0) 125 if (len < 0)
118 len = 0; 126 len = 0;
127 }
119 } 128 }
120 else 129 else
121 len = 0; 130 len = 0;
122 } 131 }
123 132
124 valid_keysym = status_return == XLookupKeySym 133 valid_keysym = status_return == XLookupKeySym
125 || status_return == XLookupBoth; 134 || status_return == XLookupBoth;
126 } 135 }
127 else 136 else
128#endif 137#endif
129
130 { 138 {
131 len = XLookupString (&ev, (char *)kbuf, KBUFSZ, &keysym, &compose); 139 len = XLookupString (&ev, (char *)kbuf, KBUFSZ, &keysym, &compose);
132 valid_keysym = !len; 140 valid_keysym = keysym != NoSymbol;
133 } 141 }
134 142
135 if (valid_keysym) 143 if (valid_keysym)
136 { 144 {
137 /* for some backwards compatibility */ 145 /* for some backwards compatibility */
142 if (meta) 150 if (meta)
143# endif 151# endif
144 { 152 {
145 if (keysym == ks_bigfont) 153 if (keysym == ks_bigfont)
146 { 154 {
147 change_font (0, FONT_UP); 155 change_font (FONT_UP);
148 return; 156 return;
149 } 157 }
150 else if (keysym == ks_smallfont) 158 else if (keysym == ks_smallfont)
151 { 159 {
152 change_font (0, FONT_DN); 160 change_font (FONT_DN);
153 return; 161 return;
154 } 162 }
155 } 163 }
156#endif 164#endif
157 165
162 { 170 {
163#else 171#else
164 if (IS_SCROLL_MOD) 172 if (IS_SCROLL_MOD)
165 { 173 {
166#endif 174#endif
167 int lnsppg; 175 int lnsppg;
168 176
169#ifdef PAGING_CONTEXT_LINES 177#ifdef PAGING_CONTEXT_LINES
170 lnsppg = TermWin.nrow - PAGING_CONTEXT_LINES; 178 lnsppg = TermWin.nrow - PAGING_CONTEXT_LINES;
171#else 179#else
172 lnsppg = TermWin.nrow * 4 / 5; 180 lnsppg = TermWin.nrow * 4 / 5;
210 scr_move_to (1, 0); 218 scr_move_to (1, 0);
211 return; 219 return;
212 } 220 }
213 } 221 }
214#endif 222#endif
215
216 } 223 }
217 224
218 if (shft) 225 if (shft)
219 { 226 {
220 /* Shift + F1 - F10 generates F11 - F20 */ 227 /* Shift + F1 - F10 generates F11 - F20 */
231 case XK_Insert: /* Shift+Insert = paste mouse selection */ 238 case XK_Insert: /* Shift+Insert = paste mouse selection */
232 selection_request (ev.time, 0, 0); 239 selection_request (ev.time, 0, 0);
233 return; 240 return;
234 /* rxvt extras */ 241 /* rxvt extras */
235 case XK_KP_Add: /* Shift+KP_Add = bigger font */ 242 case XK_KP_Add: /* Shift+KP_Add = bigger font */
236 change_font (0, FONT_UP); 243 change_font (FONT_UP);
237 return; 244 return;
238 case XK_KP_Subtract: /* Shift+KP_Subtract = smaller font */ 245 case XK_KP_Subtract: /* Shift+KP_Subtract = smaller font */
239 change_font (0, FONT_DN); 246 change_font (FONT_DN);
240 return; 247 return;
241 } 248 }
242 } 249 }
243 } 250 }
244#ifdef PRINTPIPE 251#ifdef PRINTPIPE
245 if (keysym == XK_Print) 252 if (keysym == XK_Print)
246 { 253 {
247 scr_printscreen (ctrl | shft); 254 scr_printscreen (ctrl | shft);
248 return;
249 }
250#endif
251#ifdef GREEK_SUPPORT
252 if (keysym == ks_greekmodeswith)
253 {
254 greek_mode = !greek_mode;
255 if (greek_mode)
256 {
257 xterm_seq (XTerm_title,
258 (greek_getmode () == GREEK_ELOT928
259 ? "[Greek: iso]" : "[Greek: ibm]"), CHAR_ST);
260 greek_reset ();
261 }
262 else
263 xterm_seq (XTerm_title, APL_NAME "-" VERSION, CHAR_ST);
264 return; 255 return;
265 } 256 }
266#endif 257#endif
267 258
268 if (keysym >= 0xFF00 && keysym <= 0xFFFF) 259 if (keysym >= 0xFF00 && keysym <= 0xFFFF)
286 tt_write (kbuf0, l); 277 tt_write (kbuf0, l);
287 return; 278 return;
288 } 279 }
289 else 280 else
290#endif 281#endif
291
292 { 282 {
293 newlen = 1; 283 newlen = 1;
294 switch (keysym) 284 switch (keysym)
295 { 285 {
296#ifndef NO_BACKSPACE_KEY 286#ifndef NO_BACKSPACE_KEY
301 ^ !!ctrl) ? '\b' : '\177'; 291 ^ !!ctrl) ? '\b' : '\177';
302 kbuf[1] = '\0'; 292 kbuf[1] = '\0';
303 } 293 }
304 else 294 else
305 STRCPY (kbuf, key_backspace); 295 STRCPY (kbuf, key_backspace);
306# ifdef MULTICHAR_SET
307 if ((Options & Opt_mc_hack) && screen.cur.col > 0)
308 {
309 int col, row;
310
311 newlen = STRLEN (kbuf);
312 col = screen.cur.col - 1;
313 row = screen.cur.row + TermWin.saveLines;
314 if (IS_MULTI2 (screen.rend[row][col]))
315 MEMMOVE (kbuf + newlen, kbuf, newlen + 1);
316 }
317# endif
318 break; 296 break;
319#endif 297#endif
320#ifndef NO_DELETE_KEY 298#ifndef NO_DELETE_KEY
321 case XK_Delete: 299 case XK_Delete:
322 STRCPY (kbuf, key_delete); 300 STRCPY (kbuf, key_delete);
323# ifdef MULTICHAR_SET
324 if (Options & Opt_mc_hack)
325 {
326 int col, row;
327
328 newlen = STRLEN (kbuf);
329 col = screen.cur.col;
330 row = screen.cur.row + TermWin.saveLines;
331 if (IS_MULTI1 (screen.rend[row][col]))
332 MEMMOVE (kbuf + newlen, kbuf, newlen + 1);
333 }
334# endif
335 break; 301 break;
336#endif 302#endif
337 case XK_Tab: 303 case XK_Tab:
338 if (shft) 304 if (shft)
339 STRCPY (kbuf, "\033[Z"); 305 STRCPY (kbuf, "\033[Z");
349#endif 315#endif
350 newlen = 0; 316 newlen = 0;
351 } 317 }
352 break; 318 break;
353 319
354
355#ifdef XK_KP_Left 320#ifdef XK_KP_Left
356 case XK_KP_Up: /* \033Ox or standard */ 321 case XK_KP_Up: /* \033Ox or standard */
357 case XK_KP_Down: /* \033Or or standard */ 322 case XK_KP_Down: /* \033Or or standard */
358 case XK_KP_Right: /* \033Ov or standard */ 323 case XK_KP_Right: /* \033Ov or standard */
359 case XK_KP_Left: /* \033Ot or standard */ 324 case XK_KP_Left: /* \033Ot or standard */
360 if ((PrivateModes & PrivMode_aplKP) ? !shft : shft) 325 if ((PrivateModes & PrivMode_aplKP) ? !shft : shft)
361 { 326 {
362 STRCPY (kbuf, "\033OZ"); 327 STRCPY (kbuf, "\033OZ");
363 kbuf[2] = ("txvr"[keysym - XK_KP_Left]); 328 kbuf[2] = "txvr"[keysym - XK_KP_Left];
364 break; 329 break;
365 } 330 }
366 else 331 else
367 /* translate to std. cursor key */ 332 /* translate to std. cursor key */
368 keysym = XK_Left + (keysym - XK_KP_Left); 333 keysym = XK_Left + (keysym - XK_KP_Left);
371 case XK_Up: /* "\033[A" */ 336 case XK_Up: /* "\033[A" */
372 case XK_Down: /* "\033[B" */ 337 case XK_Down: /* "\033[B" */
373 case XK_Right: /* "\033[C" */ 338 case XK_Right: /* "\033[C" */
374 case XK_Left: /* "\033[D" */ 339 case XK_Left: /* "\033[D" */
375 STRCPY (kbuf, "\033[Z"); 340 STRCPY (kbuf, "\033[Z");
376 kbuf[2] = ("DACB"[keysym - XK_Left]); 341 kbuf[2] = "DACB"[keysym - XK_Left];
377 /* do Shift first */ 342 /* do Shift first */
378 if (shft) 343 if (shft)
379 kbuf[2] = ("dacb"[keysym - XK_Left]); 344 kbuf[2] = "dacb"[keysym - XK_Left];
380 else if (ctrl) 345 else if (ctrl)
381 { 346 {
382 kbuf[1] = 'O'; 347 kbuf[1] = 'O';
383 kbuf[2] = ("dacb"[keysym - XK_Left]); 348 kbuf[2] = "dacb"[keysym - XK_Left];
384 } 349 }
385 else if (PrivateModes & PrivMode_aplCUR) 350 else if (PrivateModes & PrivMode_aplCUR)
386 kbuf[1] = 'O'; 351 kbuf[1] = 'O';
387#ifdef MULTICHAR_SET
388 //TODO: ??
389 if (Options & Opt_mc_hack)
390 {
391 int col, row, m;
392
393 col = screen.cur.col;
394 row = screen.cur.row + TermWin.saveLines;
395 m = 0;
396 if (keysym == XK_Right
397 && IS_MULTI1 (screen.rend[row][col]))
398 m = 1;
399 else if (keysym == XK_Left)
400 {
401 if (col > 0)
402 {
403 if (IS_MULTI2 (screen.rend[row][col - 1]))
404 m = 1;
405 }
406 else if (screen.cur.row > 0)
407 {
408 col = screen.tlen[--row];
409 if (col == -1)
410 col = TermWin.ncol - 1;
411 else
412 col--;
413 if (col > 0
414 && IS_MULTI2 (screen.rend[row][col]))
415 m = 1;
416 }
417 }
418 if (m)
419 MEMMOVE (kbuf + 3, kbuf, 3 + 1);
420 }
421#endif
422 break; 352 break;
423 353
424#ifndef UNSHIFTED_SCROLLKEYS 354#ifndef UNSHIFTED_SCROLLKEYS
425# ifdef XK_KP_Prior 355# ifdef XK_KP_Prior
426 case XK_KP_Prior: 356 case XK_KP_Prior:
482 STRCPY (kbuf, "\033OP"); 412 STRCPY (kbuf, "\033OP");
483 kbuf[2] += (keysym - XK_KP_F1); 413 kbuf[2] += (keysym - XK_KP_F1);
484 break; 414 break;
485 415
486 case XK_KP_Multiply: /* "\033Oj" : "*" */ 416 case XK_KP_Multiply: /* "\033Oj" : "*" */
487 case XK_KP_Add: /* "\033Ok" : "+" */ 417 case XK_KP_Add: /* "\033Ok" : "+" */
488 case XK_KP_Separator: /* "\033Ol" : "," */ 418 case XK_KP_Separator: /* "\033Ol" : "," */
489 case XK_KP_Subtract: /* "\033Om" : "-" */ 419 case XK_KP_Subtract: /* "\033Om" : "-" */
490 case XK_KP_Decimal: /* "\033On" : "." */ 420 case XK_KP_Decimal: /* "\033On" : "." */
491 case XK_KP_Divide: /* "\033Oo" : "/" */ 421 case XK_KP_Divide: /* "\033Oo" : "/" */
492 case XK_KP_0: /* "\033Op" : "0" */ 422 case XK_KP_0: /* "\033Op" : "0" */
642 for (ch = kbuf; ch < kbuf + len; ch++) 572 for (ch = kbuf; ch < kbuf + len; ch++)
643 *ch |= 0x80; 573 *ch |= 0x80;
644 meta = 0; 574 meta = 0;
645 } 575 }
646#endif 576#endif
647#ifdef GREEK_SUPPORT
648 if (greek_mode)
649 len = greek_xlat (kbuf, len);
650#endif
651 /* nil */ ; 577 /* nil */ ;
652 } 578 }
653 } 579 }
654 580
655 if (len <= 0) 581 if (len <= 0)
677 kbuf[len - 1] = (shft ? (ctrl ? '@' : '$') : (ctrl ? '^' : '~')); 603 kbuf[len - 1] = (shft ? (ctrl ? '@' : '$') : (ctrl ? '^' : '~'));
678 604
679 /* escape prefix */ 605 /* escape prefix */
680 if (meta 606 if (meta
681#ifdef META8_OPTION 607#ifdef META8_OPTION
682 && (meta_char == C0_ESC) 608 && meta_char == C0_ESC
683#endif 609#endif
684 ) 610 )
685 { 611 {
686 const unsigned char ch = C0_ESC; 612 const unsigned char ch = C0_ESC;
687
688 tt_write (&ch, 1); 613 tt_write (&ch, 1);
689 } 614 }
615
690#ifdef DEBUG_CMD 616#if defined(DEBUG_CMD)
691 if (debug_key)
692 { /* Display keyboard buffer contents */ 617 /* Display keyboard buffer contents */
693 char *p; 618 unsigned char *p;
694 int i; 619 int i;
695 620
696 fprintf (stderr, "key 0x%04X [%d]: `", (unsigned int)keysym, len); 621 fprintf (stderr, "key 0x%04X [%d]: `", (unsigned int)keysym, len);
697 for (i = 0, p = kbuf; i < len; i++, p++) 622 for (i = 0, p = kbuf; i < len; i++, p++)
698 fprintf (stderr, (*p >= ' ' && *p < '\177' ? "%c" : "\\%03o"), *p); 623 fprintf (stderr, (*p >= ' ' && *p < '\177' ? "%c" : "\\%03o"), *p);
699 fprintf (stderr, "'\n"); 624 fprintf (stderr, "'\n");
700 }
701#endif /* DEBUG_CMD */ 625#endif /* DEBUG_CMD */
702 tt_write (kbuf, (unsigned int)len); 626 tt_write (kbuf, (unsigned int)len);
703} 627}
704/*}}} */ 628/*}}} */
705 629
711{ 635{
712 unsigned int n, s; 636 unsigned int n, s;
713 637
714 n = cmdbuf_ptr - cmdbuf_base; 638 n = cmdbuf_ptr - cmdbuf_base;
715 s = cmdbuf_base + BUFSIZ - 1 - cmdbuf_endp; 639 s = cmdbuf_base + BUFSIZ - 1 - cmdbuf_endp;
640
716 if (n > 0 && s < count) 641 if (n > 0 && s < count)
717 { 642 {
718 MEMMOVE (cmdbuf_base, cmdbuf_ptr, 643 MEMMOVE (cmdbuf_base, cmdbuf_ptr,
719 (unsigned int) (cmdbuf_endp - cmdbuf_ptr)); 644 (unsigned int) (cmdbuf_endp - cmdbuf_ptr));
720 cmdbuf_ptr = cmdbuf_base; 645 cmdbuf_ptr = cmdbuf_base;
721 cmdbuf_endp -= n; 646 cmdbuf_endp -= n;
722 s += n; 647 s += n;
723 } 648 }
649
724 if (count > s) 650 if (count > s)
725 { 651 {
726 rxvt_print_error ("data loss: cmd_write too large"); 652 rxvt_print_error ("data loss: cmd_write too large");
727 count = s; 653 count = s;
728 } 654 }
655
729 for (; count--;) 656 for (; count--;)
730 *cmdbuf_endp++ = *str++; 657 *cmdbuf_endp++ = *str++;
658
659 cmd_parse ();
660
731 return 0; 661 return 0;
732} 662}
733#endif /* MENUBAR_MAX */ 663#endif /* MENUBAR_MAX */
734 664
735void 665void
807 cmdbuf_endp += n; 737 cmdbuf_endp += n;
808 return true; 738 return true;
809 } 739 }
810 else if (n < 0 && errno != EAGAIN) 740 else if (n < 0 && errno != EAGAIN)
811 destroy (); 741 destroy ();
812 742
813 return false; 743 return false;
814} 744}
815 745
816void 746void
817rxvt_term::pty_cb (io_watcher &w, short revents) 747rxvt_term::pty_cb (io_watcher &w, short revents)
834 seen_input = 1; 764 seen_input = 1;
835 /* once we know the shell is running, send the screen size. Again! */ 765 /* once we know the shell is running, send the screen size. Again! */
836 tt_winch (); 766 tt_winch ();
837 } 767 }
838 768
769 if (cmd_parse ())
770 break;
771 }
772 }
773}
774
775bool
776rxvt_term::cmd_parse ()
777{
778 bool flag = false;
839 uint32_t ch = NOCHAR; 779 uint32_t ch = NOCHAR;
780
781 for (;;)
782 {
783 if (ch == NOCHAR)
784 ch = next_char ();
785
786 if (ch == NOCHAR) // TODO: improve
787 break;
788
789 if (ch >= ' ' || ch == '\t' || ch == '\n' || ch == '\r')
790 {
791 /* Read a text string from the input buffer */
792 uint32_t buf[BUFSIZ];
793 bool refreshnow = false;
794 int nlines = 0;
795 uint32_t *str = buf;
796
797 *str++ = ch;
840 798
841 for (;;) 799 for (;;)
842 { 800 {
843 if (ch == NOCHAR)
844 ch = next_char (); 801 ch = next_char ();
845 802
846 if (ch == NOCHAR) // TODO: improve 803 if (ch == NOCHAR || (ch < ' ' && ch != '\t' && ch != '\n' && ch != '\r'))
847 break; 804 break;
848 805 else
849 if (ch >= ' ' || ch == '\t' || ch == '\n' || ch == '\r')
850 { 806 {
851 /* Read a text string from the input buffer */
852 uint32_t buf[BUFSIZ];
853 bool refreshnow = false;
854 int nlines = 0;
855 uint32_t *str = buf;
856
857 *str++ = ch; 807 *str++ = ch;
858 808
859 for (;;) 809 if (ch == '\n')
860 { 810 {
861 ch = next_char ();
862
863 if (ch == NOCHAR || (ch < ' ' && ch != '\t' && ch != '\n' && ch != '\r'))
864 break;
865 else 811 nlines++;
812 refresh_count++;
813
814 if (! (Options & Opt_jumpScroll)
815 || (refresh_count >= (refresh_limit * (TermWin.nrow - 1))))
866 { 816 {
867 *str++ = ch;
868
869 if (ch == '\n')
870 {
871 nlines++;
872 refresh_count++;
873
874 if (! (Options & Opt_jumpScroll)
875 || (refresh_count >= (refresh_limit * (TermWin.nrow - 1))))
876 {
877 refreshnow = true; 817 refreshnow = true;
878 flag = false; 818 flag = false;
879 ch = NOCHAR; 819 ch = NOCHAR;
880 break; 820 break;
881 } 821 }
882 822
883 // scr_add_lines only works for nlines < TermWin.nrow - 1. 823 // scr_add_lines only works for nlines < TermWin.nrow - 1.
884 if (nlines >= TermWin.nrow - 1) 824 if (nlines >= TermWin.nrow - 1)
885 { 825 {
886 scr_add_lines (buf, nlines, str - buf); 826 scr_add_lines (buf, nlines, str - buf);
887 nlines = 0; 827 nlines = 0;
888 str = buf; 828 str = buf;
889 }
890 }
891
892 if (str >= buf + BUFSIZ)
893 {
894 ch = NOCHAR;
895 break;
896 }
897 } 829 }
898 } 830 }
899 831
900 scr_add_lines (buf, nlines, str - buf); 832 if (str >= buf + BUFSIZ)
901
902 /*
903 * If there have been a lot of new lines, then update the screen
904 * What the heck I'll cheat and only refresh less than every page-full.
905 * the number of pages between refreshes is refresh_limit, which
906 * is incremented here because we must be doing flat-out scrolling.
907 *
908 * refreshing should be correct for small scrolls, because of the
909 * time-out
910 */
911 if (refreshnow)
912 { 833 {
913 if ((Options & Opt_jumpScroll) && refresh_limit < REFRESH_PERIOD) 834 ch = NOCHAR;
914 refresh_limit++; 835 break;
915
916 scr_refresh (refresh_type);
917 } 836 }
918
919 }
920 else
921 {
922 switch (ch)
923 {
924 default:
925 process_nonprinting (ch);
926 break;
927 case C0_ESC: /* escape char */
928 process_escape_seq ();
929 break;
930 /*case 0x9b: */ /* CSI */
931 /* process_csi_seq (); */
932 }
933
934 ch = NOCHAR;
935 } 837 }
936 } 838 }
839
840 scr_add_lines (buf, nlines, str - buf);
841
842 /*
843 * If there have been a lot of new lines, then update the screen
844 * What the heck I'll cheat and only refresh less than every page-full.
845 * the number of pages between refreshes is refresh_limit, which
846 * is incremented here because we must be doing flat-out scrolling.
847 *
848 * refreshing should be correct for small scrolls, because of the
849 * time-out
850 */
851 if (refreshnow)
852 {
853 if ((Options & Opt_jumpScroll) && refresh_limit < REFRESH_PERIOD)
854 refresh_limit++;
855
856 scr_refresh (refresh_type);
857 }
858
859 }
860 else
937 } 861 {
862 switch (ch)
863 {
864 default:
865 process_nonprinting (ch);
866 break;
867 case C0_ESC: /* escape char */
868 process_escape_seq ();
869 break;
870 /*case 0x9b: */ /* CSI */
871 /* process_csi_seq (); */
872 }
873
874 ch = NOCHAR;
875 }
938 } 876 }
877
878 return flag;
939} 879}
940 880
941// read the next character, currently handles UTF-8 881// read the next character, currently handles UTF-8
942// will probably handle all sorts of other stuff in the future 882// will probably handle all sorts of other stuff in the future
943uint32_t 883uint32_t
944rxvt_term::next_char () 884rxvt_term::next_char ()
945{ 885{
946 while (cmdbuf_ptr < cmdbuf_endp) 886 while (cmdbuf_ptr < cmdbuf_endp)
947 { 887 {
948 if (*cmdbuf_ptr < 0x80) // assume < 0x80 to be ascii ALWAYS (all shift-states etc.) uh-oh 888 // assume 0x20 .. 0x7f to be ascii ALWAYS (all shift-states etc.) uh-oh
889 if ((*cmdbuf_ptr <= 0x7f && 0x20 <= *cmdbuf_ptr)
890 || !*cmdbuf_ptr)
949 return *cmdbuf_ptr++; 891 return *cmdbuf_ptr++;
950 892
951 wchar_t wc; 893 wchar_t wc;
952 size_t len = mbrtowc (&wc, (char *)cmdbuf_ptr, cmdbuf_endp - cmdbuf_ptr, &mbstate.mbs); 894 size_t len = mbrtowc (&wc, (char *)cmdbuf_ptr, cmdbuf_endp - cmdbuf_ptr, mbstate);
953 895
954 if (len == (size_t)-2) 896 if (len == (size_t)-2)
955 return NOCHAR; 897 {
898 // the mbstate stores incomplete sequences. didn't know this :/
899 cmdbuf_ptr = cmdbuf_endp;
900 break;
901 }
956 902
957 if (len == (size_t)-1) 903 if (len == (size_t)-1)
958 return *cmdbuf_ptr++; // the _occasional_ latin1 character is allowed to slip through 904 return *cmdbuf_ptr++; // the _occasional_ latin1 character is allowed to slip through
959 905
960 // assume wchar == unicode 906 // assume wchar == unicode
1021 pointer_blank (); 967 pointer_blank ();
1022} 968}
1023#endif 969#endif
1024 970
1025void 971void
1026rxvt_term::mouse_report (const XButtonEvent &ev) 972rxvt_term::mouse_report (XButtonEvent &ev)
1027{ 973{
1028 int button_number, key_state = 0; 974 int button_number, key_state = 0;
1029 int x, y; 975 int x, y;
1030 976
1031 x = ev.x; 977 x = ev.x;
1032 y = ev.y; 978 y = ev.y;
1033 pixel_position (&x, &y); 979 pixel_position (&x, &y);
1034 980
1428 } 1374 }
1429#ifdef MENUBAR 1375#ifdef MENUBAR
1430 if (menubar_visible () && isMenuBarWindow (ev.xany.window)) 1376 if (menubar_visible () && isMenuBarWindow (ev.xany.window))
1431 menubar_expose (); 1377 menubar_expose ();
1432#endif 1378#endif
1433#ifdef RXVT_GRAPHICS
1434 Gr_expose (ev.xany.window);
1435#endif
1436
1437 } 1379 }
1438 break; 1380 break;
1439 1381
1440 case MotionNotify: 1382 case MotionNotify:
1441#ifdef POINTER_BLANK 1383#ifdef POINTER_BLANK
1443 pointer_unblank (); 1385 pointer_unblank ();
1444#endif 1386#endif
1445#if MENUBAR 1387#if MENUBAR
1446 if (isMenuBarWindow (ev.xany.window)) 1388 if (isMenuBarWindow (ev.xany.window))
1447 { 1389 {
1448 menubar_control (& (ev.xbutton)); 1390 menubar_control (ev.xbutton);
1449 break; 1391 break;
1450 } 1392 }
1451#endif 1393#endif
1452 if ((PrivateModes & PrivMode_mouse_report) && ! (bypass_keystate)) 1394 if ((PrivateModes & PrivMode_mouse_report) && ! (bypass_keystate))
1453 break; 1395 break;
1582#endif 1524#endif
1583 } 1525 }
1584} 1526}
1585 1527
1586void 1528void
1587rxvt_term::button_press (const XButtonEvent &ev) 1529rxvt_term::button_press (XButtonEvent &ev)
1588{ 1530{
1589 int reportmode = 0, clickintime; 1531 int reportmode = 0, clickintime;
1590 1532
1591 bypass_keystate = ev.state & (ModMetaMask | ShiftMask); 1533 bypass_keystate = ev.state & (ModMetaMask | ShiftMask);
1592 if (!bypass_keystate) 1534 if (!bypass_keystate)
1594 /* 1536 /*
1595 * VT window processing of button press 1537 * VT window processing of button press
1596 */ 1538 */
1597 if (ev.window == TermWin.vt) 1539 if (ev.window == TermWin.vt)
1598 { 1540 {
1599#if RXVT_GRAPHICS
1600 if (ev.subwindow != None)
1601 rxvt_Gr_ButtonPress (ev.x, ev.y);
1602 else
1603#endif
1604
1605 {
1606 clickintime = ev.time - MEvent.time < MULTICLICK_TIME; 1541 clickintime = ev.time - MEvent.time < MULTICLICK_TIME;
1607 if (reportmode) 1542 if (reportmode)
1543 {
1544 /* mouse report from vt window */
1545 /* save the xbutton state (for ButtonRelease) */
1546 MEvent.state = ev.state;
1547#ifdef MOUSE_REPORT_DOUBLECLICK
1548 if (ev.button == MEvent.button && clickintime)
1608 { 1549 {
1609 /* mouse report from vt window */ 1550 /* same button, within alloted time */
1610 /* save the xbutton state (for ButtonRelease) */ 1551 MEvent.clicks++;
1611 MEvent.state = ev.state; 1552 if (MEvent.clicks > 1)
1612#ifdef MOUSE_REPORT_DOUBLECLICK
1613 if (ev.button == MEvent.button && clickintime)
1614 { 1553 {
1615 /* same button, within alloted time */
1616 MEvent.clicks++;
1617 if (MEvent.clicks > 1)
1618 {
1619 /* only report double clicks */ 1554 /* only report double clicks */
1620 MEvent.clicks = 2; 1555 MEvent.clicks = 2;
1621 mouse_report (ev); 1556 mouse_report (ev);
1622 1557
1623 /* don't report the release */ 1558 /* don't report the release */
1624 MEvent.clicks = 0; 1559 MEvent.clicks = 0;
1625 MEvent.button = AnyButton; 1560 MEvent.button = AnyButton;
1626 }
1627 } 1561 }
1628 else
1629 {
1630 /* different button, or time expired */
1631 MEvent.clicks = 1;
1632 MEvent.button = ev.button;
1633 mouse_report (ev);
1634 }
1635#else
1636 MEvent.button = ev.button;
1637 mouse_report (ev);
1638#endif /* MOUSE_REPORT_DOUBLECLICK */
1639
1640 } 1562 }
1641 else 1563 else
1642 { 1564 {
1565 /* different button, or time expired */
1566 MEvent.clicks = 1;
1567 MEvent.button = ev.button;
1568 mouse_report (ev);
1569 }
1570#else
1571 MEvent.button = ev.button;
1572 mouse_report (ev);
1573#endif /* MOUSE_REPORT_DOUBLECLICK */
1574
1575 }
1576 else
1577 {
1643 if (ev.button != MEvent.button) 1578 if (ev.button != MEvent.button)
1644 MEvent.clicks = 0; 1579 MEvent.clicks = 0;
1645 switch (ev.button) 1580 switch (ev.button)
1646 { 1581 {
1647 case Button1: 1582 case Button1:
1648 /* allow shift+left click to extend selection */ 1583 /* allow shift+left click to extend selection */
1649 if (ev.state & ShiftMask && ! (PrivateModes & PrivMode_mouse_report)) 1584 if (ev.state & ShiftMask && ! (PrivateModes & PrivMode_mouse_report))
1650 { 1585 {
1651 if (MEvent.button == Button1 && clickintime)
1652 selection_rotate (ev.x, ev.y);
1653 else
1654 selection_extend (ev.x, ev.y, 1);
1655 }
1656 else
1657 {
1658 if (MEvent.button == Button1 && clickintime)
1659 MEvent.clicks++;
1660 else
1661 MEvent.clicks = 1;
1662
1663 selection_click (MEvent.clicks, ev.x, ev.y);
1664 }
1665
1666 MEvent.button = Button1;
1667 break;
1668
1669 case Button3:
1670 if (MEvent.button == Button3 && clickintime) 1586 if (MEvent.button == Button1 && clickintime)
1671 selection_rotate (ev.x, ev.y); 1587 selection_rotate (ev.x, ev.y);
1672 else 1588 else
1673 selection_extend (ev.x, ev.y, 1); 1589 selection_extend (ev.x, ev.y, 1);
1590 }
1591 else
1592 {
1593 if (MEvent.button == Button1 && clickintime)
1594 MEvent.clicks++;
1595 else
1596 MEvent.clicks = 1;
1597
1598 selection_click (MEvent.clicks, ev.x, ev.y);
1599 }
1600
1601 MEvent.button = Button1;
1602 break;
1603
1604 case Button3:
1605 if (MEvent.button == Button3 && clickintime)
1606 selection_rotate (ev.x, ev.y);
1607 else
1608 selection_extend (ev.x, ev.y, 1);
1674 MEvent.button = Button3; 1609 MEvent.button = Button3;
1675 break; 1610 break;
1676 }
1677 } 1611 }
1612 }
1678 MEvent.time = ev.time; 1613 MEvent.time = ev.time;
1679 return; 1614 return;
1680 }
1681 } 1615 }
1682 1616
1683 /* 1617 /*
1684 * Scrollbar window processing of button press 1618 * Scrollbar window processing of button press
1685 */ 1619 */
1828 menubar_control (ev); 1762 menubar_control (ev);
1829#endif 1763#endif
1830} 1764}
1831 1765
1832void 1766void
1833rxvt_term::button_release (const XButtonEvent &ev) 1767rxvt_term::button_release (XButtonEvent &ev)
1834{ 1768{
1835 int reportmode = 0; 1769 int reportmode = 0;
1836 1770
1837 csrO = 0; /* reset csr Offset */ 1771 csrO = 0; /* reset csr Offset */
1838 if (!bypass_keystate) 1772 if (!bypass_keystate)
1850#ifdef SELECTION_SCROLLING 1784#ifdef SELECTION_SCROLLING
1851 pending_scroll_selection=0; 1785 pending_scroll_selection=0;
1852#endif 1786#endif
1853 if (ev.window == TermWin.vt) 1787 if (ev.window == TermWin.vt)
1854 { 1788 {
1855#ifdef RXVT_GRAPHICS
1856 if (ev.subwindow != None)
1857 rxvt_Gr_ButtonRelease (ev.x, ev.y);
1858 else
1859#endif
1860
1861 {
1862 if (reportmode) 1789 if (reportmode)
1790 {
1791 /* mouse report from vt window */
1792 /* don't report release of wheel "buttons" */
1793 if (ev.button >= 4)
1794 return;
1795#ifdef MOUSE_REPORT_DOUBLECLICK
1796 /* only report the release of 'slow' single clicks */
1797 if (MEvent.button != AnyButton
1798 && (ev.button != MEvent.button
1799 || (ev.time - MEvent.time
1800 > MULTICLICK_TIME / 2)))
1863 { 1801 {
1864 /* mouse report from vt window */
1865 /* don't report release of wheel "buttons" */
1866 if (ev.button >= 4)
1867 return;
1868#ifdef MOUSE_REPORT_DOUBLECLICK
1869 /* only report the release of 'slow' single clicks */
1870 if (MEvent.button != AnyButton
1871 && (ev.button != MEvent.button
1872 || (ev.time - MEvent.time
1873 > MULTICLICK_TIME / 2)))
1874 {
1875 MEvent.clicks = 0; 1802 MEvent.clicks = 0;
1876 MEvent.button = AnyButton;
1877 mouse_report (ev);
1878 }
1879#else /* MOUSE_REPORT_DOUBLECLICK */
1880 MEvent.button = AnyButton; 1803 MEvent.button = AnyButton;
1881 mouse_report (ev); 1804 mouse_report (ev);
1805 }
1806#else /* MOUSE_REPORT_DOUBLECLICK */
1807 MEvent.button = AnyButton;
1808 mouse_report (ev);
1882#endif /* MOUSE_REPORT_DOUBLECLICK */ 1809#endif /* MOUSE_REPORT_DOUBLECLICK */
1883 return; 1810 return;
1884 } 1811 }
1885 /* 1812 /*
1886 * dumb hack to compensate for the failure of click-and-drag 1813 * dumb hack to compensate for the failure of click-and-drag
1887 * when overriding mouse reporting 1814 * when overriding mouse reporting
1888 */ 1815 */
1889 if (PrivateModes & PrivMode_mouse_report 1816 if (PrivateModes & PrivMode_mouse_report
1890 && bypass_keystate 1817 && bypass_keystate
1891 && ev.button == Button1 && MEvent.clicks <= 1) 1818 && ev.button == Button1 && MEvent.clicks <= 1)
1892 selection_extend (ev.x, ev.y, 0); 1819 selection_extend (ev.x, ev.y, 0);
1893 1820
1894 switch (ev.button) 1821 switch (ev.button)
1822 {
1823 case Button1:
1824 case Button3:
1825 selection_make (ev.time);
1826 break;
1827 case Button2:
1828 selection_request (ev.time, ev.x, ev.y);
1829 break;
1830#ifdef MOUSE_WHEEL
1831 case Button4:
1832 case Button5:
1895 { 1833 {
1896 case Button1: 1834 int i;
1897 case Button3: 1835 page_dirn v;
1898 selection_make (ev.time); 1836
1837 v = (ev.button == Button4) ? UP : DN;
1838 if (ev.state & ShiftMask)
1899 break; 1839 i = 1;
1900 case Button2: 1840 else if ((Options & Opt_mouseWheelScrollPage))
1901 selection_request (ev.time, ev.x, ev.y); 1841 i = TermWin.nrow - 1;
1842 else
1902 break; 1843 i = 5;
1903#ifdef MOUSE_WHEEL 1844# ifdef MOUSE_SLIP_WHEELING
1904 case Button4: 1845 if (ev.state & ControlMask)
1905 case Button5:
1906 { 1846 {
1907 int i;
1908 page_dirn v;
1909
1910 v = (ev.button == Button4) ? UP : DN;
1911 if (ev.state & ShiftMask)
1912 i = 1;
1913 else if ((Options & Opt_mouseWheelScrollPage))
1914 i = TermWin.nrow - 1;
1915 else
1916 i = 5;
1917# ifdef MOUSE_SLIP_WHEELING
1918 if (ev.state & ControlMask)
1919 {
1920 mouse_slip_wheel_speed += (v ? -1 : 1); 1847 mouse_slip_wheel_speed += (v ? -1 : 1);
1921 mouse_slip_wheel_delay = SCROLLBAR_CONTINUOUS_DELAY; 1848 mouse_slip_wheel_delay = SCROLLBAR_CONTINUOUS_DELAY;
1922 } 1849 }
1923# endif 1850# endif
1924# ifdef JUMP_MOUSE_WHEEL 1851# ifdef JUMP_MOUSE_WHEEL
1852 scr_page (v, i);
1853 scr_refresh (SMOOTH_REFRESH);
1854 scrollbar_show (1);
1855# else
1856 while (i--)
1857 {
1925 scr_page (v, i); 1858 scr_page (v, 1);
1926 scr_refresh (SMOOTH_REFRESH); 1859 scr_refresh (SMOOTH_REFRESH);
1927 scrollbar_show (1); 1860 scrollbar_show (1);
1928# else
1929 while (i--)
1930 {
1931 scr_page (v, 1);
1932 scr_refresh (SMOOTH_REFRESH);
1933 scrollbar_show (1);
1934 } 1861 }
1935# endif 1862# endif
1936 1863
1937 }
1938 break;
1939#endif
1940
1941 } 1864 }
1865 break;
1866#endif
1867
1942 } 1868 }
1943 } 1869 }
1944#ifdef MENUBAR 1870#ifdef MENUBAR
1945 else if (isMenuBarWindow (ev.window)) 1871 else if (isMenuBarWindow (ev.window))
1946 menubar_control (ev); 1872 menubar_control (ev);
2381 scr_charset_set (2, (unsigned int)cmd_getc ()); 2307 scr_charset_set (2, (unsigned int)cmd_getc ());
2382 break; 2308 break;
2383 case '+': 2309 case '+':
2384 scr_charset_set (3, (unsigned int)cmd_getc ()); 2310 scr_charset_set (3, (unsigned int)cmd_getc ());
2385 break; 2311 break;
2386#ifdef MULTICHAR_SET
2387 case '$':
2388 scr_charset_set (-2, (unsigned int)cmd_getc ());
2389 break;
2390#endif
2391#ifndef NO_FRILLS 2312#ifndef NO_FRILLS
2392 case '6': 2313 case '6':
2393 scr_backindex (); 2314 scr_backindex ();
2394 break; 2315 break;
2395#endif 2316#endif
2736 case 7: /* unofficial extension */ 2657 case 7: /* unofficial extension */
2737 tt_printf ("%-.250s\n", rs[Rs_display_name]); 2658 tt_printf ("%-.250s\n", rs[Rs_display_name]);
2738 break; 2659 break;
2739#endif 2660#endif
2740 case 8: /* unofficial extension */ 2661 case 8: /* unofficial extension */
2741 xterm_seq (XTerm_title, APL_NAME "-" VERSION, CHAR_ST); 2662 xterm_seq (XTerm_title, RESNAME "-" VERSION, CHAR_ST);
2742 break; 2663 break;
2743 } 2664 }
2744 break; 2665 break;
2745 2666
2746 case CSI_TBC: /* 8.3.155: (0) TABULATION CLEAR */ 2667 case CSI_TBC: /* 8.3.155: (0) TABULATION CLEAR */
3015 * 19 = change underlined character color 2936 * 19 = change underlined character color
3016 * 46 = change logfile (not implemented) 2937 * 46 = change logfile (not implemented)
3017 * 50 = change font 2938 * 50 = change font
3018 * 2939 *
3019 * rxvt extensions: 2940 * rxvt extensions:
2941 * 9 = change locale (NYI)
3020 * 10 = menu (may change in future) 2942 * 10 = menu (may change in future)
3021 * 20 = bg pixmap 2943 * 20 = bg pixmap
3022 * 39 = change default fg color 2944 * 39 = change default fg color
3023 * 49 = change default bg color 2945 * 49 = change default bg color
3024 * 55 = dump scrollback buffer and all of screen 2946 * 55 = dump scrollback buffer and all of screen
3115 set_window_color (Color_bg, str); 3037 set_window_color (Color_bg, str);
3116 break; 3038 break;
3117 case XTerm_logfile: 3039 case XTerm_logfile:
3118 break; 3040 break;
3119 case XTerm_font: 3041 case XTerm_font:
3120 change_font (0, str); 3042 change_font (str);
3121 break; 3043 break;
3044#ifndef NO_FRILLS
3045 case XTerm_locale:
3046 if (str[0] == '?' && !str[1])
3047 tt_printf ("%-.250s\n", locale);
3048 else
3049 {
3050 set_locale (str);
3051# ifdef USE_XIM
3052 im_cb ();
3053# endif
3054 // TODO: call selection_make with the right values set
3055 // to re-fresh the selection.
3056 if (display->selection_owner == this)
3057 display->set_selection_owner (0);
3058 }
3059 break;
3060#endif
3122#if 0 3061#if 0
3123 case XTerm_dumpscreen: /* no error notices */ 3062 case XTerm_dumpscreen: /* no error notices */
3124 { 3063 {
3125 int fd; 3064 int fd;
3126 if ((fd = open (str, O_RDWR | O_CREAT | O_EXCL, 0600)) >= 0) 3065 if ((fd = open (str, O_RDWR | O_CREAT | O_EXCL, 0600)) >= 0)
3476void 3415void
3477rxvt_term::process_graphics () 3416rxvt_term::process_graphics ()
3478{ 3417{
3479 unsigned char ch, cmd = cmd_getc (); 3418 unsigned char ch, cmd = cmd_getc ();
3480 3419
3481#ifndef RXVT_GRAPHICS
3482 if (cmd == 'Q') 3420 if (cmd == 'Q')
3483 { /* query graphics */ 3421 { /* query graphics */
3484 tt_printf ("\033G0\n"); /* no graphics */ 3422 tt_printf ("\033G0\n"); /* no graphics */
3485 return; 3423 return;
3486 } 3424 }
3487 /* swallow other graphics sequences until terminating ':' */ 3425 /* swallow other graphics sequences until terminating ':' */
3488 do 3426 do
3489 ch = cmd_getc (); 3427 ch = cmd_getc ();
3490 while (ch != ':'); 3428 while (ch != ':');
3491#else
3492 unsigned int nargs;
3493 int args[NGRX_PTS];
3494 unsigned char *text = NULL;
3495
3496 if (cmd == 'Q')
3497 { /* query graphics */
3498 tt_printf ("\033G1\n"); /* yes, graphics (color) */
3499 return;
3500 }
3501 for (nargs = 0; nargs < (sizeof (args) / sizeof (args[0])) - 1;)
3502 {
3503 int neg;
3504
3505 ch = cmd_getc ();
3506 neg = (ch == '-');
3507 if (neg || ch == '+')
3508 ch = cmd_getc ();
3509
3510 for (args[nargs] = 0; isdigit (ch); ch = cmd_getc ())
3511 args[nargs] = args[nargs] * 10 + (ch - '0');
3512 if (neg)
3513 args[nargs] = -args[nargs];
3514
3515 nargs++;
3516 args[nargs] = 0;
3517 if (ch != ';')
3518 break;
3519 }
3520
3521 if ((cmd == 'T') && (nargs >= 5))
3522 {
3523 int i, len = args[4];
3524
3525 text = (unsigned char *)rxvt_malloc ((len + 1) * sizeof (char));
3526
3527 if (text != NULL)
3528 {
3529 for (i = 0; i < len; i++)
3530 text[i] = cmd_getc ();
3531 text[len] = '\0';
3532 }
3533 }
3534 Gr_do_graphics (cmd, nargs, args, text);
3535#endif
3536} 3429}
3537/*}}} */ 3430/*}}} */
3538 3431
3539/* ------------------------------------------------------------------------- */ 3432/* ------------------------------------------------------------------------- */
3540 3433

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines