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.545 by sf-exg, Sat Apr 26 15:05:17 2014 UTC vs.
Revision 1.587 by sf-exg, Sat May 8 06:16:21 2021 UTC

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-2014 Marc Lehmann <schmorp@schmorp.de> 30 * Copyright (c) 2003-2014 Marc Lehmann <schmorp@schmorp.de>
31 * Copyright (c) 2007 Emanuele Giaquinta <e.giaquinta@glauco.it> 31 * Copyright (c) 2007,2015 Emanuele Giaquinta <e.giaquinta@glauco.it>
32 * 32 *
33 * This program is free software; you can redistribute it and/or modify 33 * This program is free software; you can redistribute it and/or modify
34 * it under the terms of the GNU General Public License as published by 34 * it under the terms of the GNU General Public License as published by
35 * the Free Software Foundation; either version 2 of the License, or 35 * the Free Software Foundation; either version 3 of the License, or
36 * (at your option) any later version. 36 * (at your option) any later version.
37 * 37 *
38 * This program is distributed in the hope that it will be useful, 38 * This program is distributed in the hope that it will be useful,
39 * but WITHOUT ANY WARRANTY; without even the implied warranty of 39 * but WITHOUT ANY WARRANTY; without even the implied warranty of
40 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 40 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
210 210
211 max_it (width, strlen (attr)); 211 max_it (width, strlen (attr));
212 212
213 if (y >= 0) 213 if (y >= 0)
214 { 214 {
215 y = (y >= nrow - len - 4 && x < width + 2) ? 0 : -1; 215 y = (y >= nrow - len - 5 && x < width + 2) ? 0 : -1;
216 x = 0; 216 x = 0;
217 } 217 }
218 218
219 scr_overlay_new (x, y, width, len * 2 + 2); 219 scr_overlay_new (x, y, width, len * 2 + 2);
220 220
315 XK_KP_7, // XK_KP_Home 315 XK_KP_7, // XK_KP_Home
316 XK_KP_4, // XK_KP_Left 316 XK_KP_4, // XK_KP_Left
317 XK_KP_8, // XK_KP_Up 317 XK_KP_8, // XK_KP_Up
318 XK_KP_6, // XK_KP_Right 318 XK_KP_6, // XK_KP_Right
319 XK_KP_2, // XK_KP_Down 319 XK_KP_2, // XK_KP_Down
320# ifndef UNSHIFTED_SCROLLKEYS
321 XK_KP_9, // XK_KP_Prior 320 XK_KP_9, // XK_KP_Prior
322 XK_KP_3, // XK_KP_Next 321 XK_KP_3, // XK_KP_Next
323# else
324 XK_Prior,
325 XK_Next,
326# endif
327 XK_KP_1, // XK_KP_End 322 XK_KP_1, // XK_KP_End
328 XK_KP_5, // XK_KP_Begin 323 XK_KP_5, // XK_KP_Begin
329 }; 324 };
330 325
331 if (IN_RANGE_INC (keysym, XK_KP_Home, XK_KP_Begin)) 326 if (IN_RANGE_INC (keysym, XK_KP_Home, XK_KP_Begin))
376 param = 3; 371 param = 3;
377 break; 372 break;
378 case XK_Select: 373 case XK_Select:
379 param = 4; 374 param = 4;
380 break; 375 break;
381#ifndef UNSHIFTED_SCROLLKEYS
382 case XK_Prior: 376 case XK_Prior:
383 param = 5; 377 param = 5;
384 break; 378 break;
385 case XK_Next: 379 case XK_Next:
386 param = 6; 380 param = 6;
389 param = 7; 383 param = 7;
390 break; 384 break;
391 case XK_End: 385 case XK_End:
392 param = 8; 386 param = 8;
393 break; 387 break;
394#endif
395 case XK_Help: 388 case XK_Help:
396 param = 28; 389 param = 28;
397 break; 390 break;
398 case XK_Menu: 391 case XK_Menu:
399 param = 29; 392 param = 29;
413 406
414void ecb_cold 407void ecb_cold
415rxvt_term::key_press (XKeyEvent &ev) 408rxvt_term::key_press (XKeyEvent &ev)
416{ 409{
417 int ctrl, meta, shft, len; 410 int ctrl, meta, shft, len;
418 KeySym keysym; 411 KeySym keysym = NoSymbol;
419 int valid_keysym;
420 char rkbuf[KBUFSZ]; 412 char rkbuf[KBUFSZ + 1];
421 char *kbuf = rkbuf + 1; 413 char *kbuf = rkbuf + 1;
422 414
423#if ISO_14755 415#if ISO_14755
424 if (iso14755buf & ISO_14755_52) 416 if (iso14755buf & ISO_14755_52)
425 return; 417 return;
483 } 475 }
484 } 476 }
485 else 477 else
486 len = 0; 478 len = 0;
487 } 479 }
488
489 valid_keysym = status_return == XLookupKeySym
490 || status_return == XLookupBoth;
491 } 480 }
492 else 481 else
493#endif 482#endif
494 { 483 {
495 len = XLookupString (&ev, kbuf, KBUFSZ, &keysym, &compose); 484 len = XLookupString (&ev, kbuf, KBUFSZ, &keysym, &compose);
496 valid_keysym = keysym != NoSymbol;
497 }
498
499 if (valid_keysym)
500 { 485 }
486
487 if (keysym != NoSymbol)
488 {
489 KeySym orig_keysym = keysym;
490
491 /* Shift + F1 - F10 generates F11 - F20 */
492 if (shft && keysym >= XK_F1 && keysym <= XK_F10)
493 {
494 keysym += (XK_F11 - XK_F1);
495 shft = 0; /* turn off Shift */
496 }
497
501 if (keysym >= 0xFF00 && keysym <= 0xFFFF) 498 if (keysym >= 0xFF00 && keysym <= 0xFFFF)
502 { 499 {
503 bool kp = priv_modes & PrivMode_aplKP ? !shft : shft; 500 bool kp = priv_modes & PrivMode_aplKP ? !shft : shft;
504 unsigned int newlen = 1; 501 unsigned int newlen = 1;
505 502
679 { 676 {
680 char *ch; 677 char *ch;
681 678
682 for (ch = kbuf; ch < kbuf + len; ch++) 679 for (ch = kbuf; ch < kbuf + len; ch++)
683 *ch |= 0x80; 680 *ch |= 0x80;
684
685 meta = 0;
686 } 681 }
687#endif 682#endif
688 /* nil */ ; 683 /* nil */ ;
689 } 684 }
685
686 keysym = orig_keysym;
690 } 687 }
691 688
692 /* escape prefix */ 689 /* escape prefix */
693 if (len && meta 690 if (len && meta
694#ifdef META8_OPTION 691#ifdef META8_OPTION
698 { 695 {
699 *--kbuf = C0_ESC; 696 *--kbuf = C0_ESC;
700 len++; 697 len++;
701 } 698 }
702 699
703 if (valid_keysym) 700 if (HOOK_INVOKE ((this, HOOK_KEY_PRESS, DT_XEVENT, &ev, DT_INT, keysym, DT_STR_LEN, kbuf, len, DT_END)))
701 return;
702
703 if (keysym != NoSymbol)
704 { 704 {
705#ifdef KEYSYM_RESOURCE 705#ifdef KEYSYM_RESOURCE
706 if (keyboard->dispatch (this, keysym, ev.state, kbuf, len)) 706 if (keyboard->dispatch (this, keysym, ev.state, kbuf, len))
707 return; 707 return;
708#endif 708#endif
767#endif 767#endif
768 } 768 }
769 769
770 if (shft) 770 if (shft)
771 { 771 {
772 /* Shift + F1 - F10 generates F11 - F20 */
773 if (keysym >= XK_F1 && keysym <= XK_F10)
774 {
775 keysym += (XK_F11 - XK_F1);
776 shft = 0; /* turn off Shift */
777 }
778 else if (!ctrl && !meta && (priv_modes & PrivMode_ShiftKeys)) 772 if (!ctrl && !meta && (priv_modes & PrivMode_ShiftKeys))
779 { 773 {
780 switch (keysym) 774 switch (keysym)
781 { 775 {
782 /* normal XTerm key bindings */ 776 /* normal XTerm key bindings */
783 case XK_Insert: /* Shift+Insert = paste mouse selection */ 777 case XK_Insert: /* Shift+Insert = paste mouse selection */
871 return; 865 return;
872 } 866 }
873#endif 867#endif
874 } 868 }
875 869
876 if (HOOK_INVOKE ((this, HOOK_KEY_PRESS, DT_XEVENT, &ev, DT_INT, keysym, DT_STR_LEN, kbuf, len, DT_END)))
877 return;
878
879 if (len <= 0) 870 if (len <= 0)
880 return; /* not mapped */ 871 return; /* not mapped */
881 872
882 if (option (Opt_scrollTtyKeypress))
883 if (view_start)
884 {
885 view_start = 0;
886 want_refresh = 1;
887 }
888
889 tt_write (kbuf, (unsigned int)len); 873 tt_write_user_input (kbuf, (unsigned int)len);
890} 874}
891 875
892void ecb_cold 876void ecb_cold
893rxvt_term::key_release (XKeyEvent &ev) 877rxvt_term::key_release (XKeyEvent &ev)
894{ 878{
1050 1034
1051#ifdef CURSOR_BLINK 1035#ifdef CURSOR_BLINK
1052void 1036void
1053rxvt_term::cursor_blink_reset () 1037rxvt_term::cursor_blink_reset ()
1054{ 1038{
1039 if (!focus)
1040 return;
1041
1055 if (hidden_cursor) 1042 if (hidden_cursor)
1056 { 1043 {
1057 hidden_cursor = 0; 1044 hidden_cursor = 0;
1058 want_refresh = 1; 1045 want_refresh = 1;
1059 } 1046 }
1060 1047
1061 if (option (Opt_cursorBlink)) 1048 if (option (Opt_cursorBlink) || (priv_modes & PrivMode_BlinkingCursor))
1062 cursor_blink_ev.again (); 1049 cursor_blink_ev.again ();
1063 else 1050 else
1064 cursor_blink_ev.stop (); 1051 cursor_blink_ev.stop ();
1065} 1052}
1066 1053
1255 1242
1256void ecb_cold 1243void ecb_cold
1257rxvt_term::pointer_unblank () 1244rxvt_term::pointer_unblank ()
1258{ 1245{
1259 XDefineCursor (dpy, vt, TermWin_cursor); 1246 XDefineCursor (dpy, vt, TermWin_cursor);
1260 recolour_cursor (); 1247 recolor_cursor ();
1261 1248
1262#ifdef POINTER_BLANK 1249#ifdef POINTER_BLANK
1263 hidden_pointer = 0; 1250 hidden_pointer = 0;
1264 1251
1265 if (option (Opt_pointerBlank)) 1252 if (option (Opt_pointerBlank))
1290#endif 1277#endif
1291 1278
1292void 1279void
1293rxvt_term::mouse_report (XButtonEvent &ev) 1280rxvt_term::mouse_report (XButtonEvent &ev)
1294{ 1281{
1295 int button_number, key_state = 0; 1282 int button_number, state = 0;
1296 int x, y; 1283 int x, y;
1297 int code = 32; 1284 bool release = ev.type == ButtonRelease;
1298 1285
1299 x = Pixel2Col (ev.x) + 1; 1286 x = Pixel2Col (ev.x) + 1;
1300 y = Pixel2Row (ev.y) + 1; 1287 y = Pixel2Row (ev.y) + 1;
1301 1288
1302 if (ev.type == MotionNotify) 1289 if (ev.type == MotionNotify)
1304 if (x == mouse_row && y == mouse_col) 1291 if (x == mouse_row && y == mouse_col)
1305 return; 1292 return;
1306 1293
1307 mouse_row = x; 1294 mouse_row = x;
1308 mouse_col = y; 1295 mouse_col = y;
1309 code += 32; 1296 state += 32;
1310 }
1311
1312 if (MEvent.button == AnyButton)
1313 button_number = 3;
1314 else
1315 { 1297 }
1298
1316 button_number = MEvent.button - Button1; 1299 button_number = MEvent.button - Button1;
1317 /* add 0x3D for wheel events, like xterm does */ 1300 /* add 0x3D for wheel events, like xterm does */
1318 if (button_number >= 3) 1301 if (button_number >= 3)
1319 button_number += 64 - 3; 1302 button_number += 64 - 3;
1320 }
1321 1303
1322 if (priv_modes & PrivMode_MouseX10) 1304 if (priv_modes & PrivMode_MouseX10)
1323 { 1305 {
1324 /* 1306 /*
1325 * do not report ButtonRelease 1307 * do not report ButtonRelease
1326 * no state info allowed 1308 * no state info allowed
1327 */ 1309 */
1328 key_state = 0; 1310 if (release)
1329 if (button_number == 3)
1330 return; 1311 return;
1331 } 1312 }
1332 else 1313 else
1333 { 1314 {
1334 /* XTerm mouse reporting needs these values: 1315 /* XTerm mouse reporting needs these values:
1336 * 8 = Meta 1317 * 8 = Meta
1337 * 16 = Control 1318 * 16 = Control
1338 * plus will add in our own Double-Click reporting 1319 * plus will add in our own Double-Click reporting
1339 * 32 = Double Click 1320 * 32 = Double Click
1340 */ 1321 */
1341 key_state = ((MEvent.state & ShiftMask) ? 4 : 0) 1322 state += ((MEvent.state & ShiftMask) ? 4 : 0)
1342 + ((MEvent.state & ModMetaMask) ? 8 : 0) 1323 + ((MEvent.state & ModMetaMask) ? 8 : 0)
1343 + ((MEvent.state & ControlMask) ? 16 : 0); 1324 + ((MEvent.state & ControlMask) ? 16 : 0);
1344#ifdef MOUSE_REPORT_DOUBLECLICK 1325#ifdef MOUSE_REPORT_DOUBLECLICK
1345 key_state += ((MEvent.clicks > 1) ? 32 : 0); 1326 state += ((MEvent.clicks > 1) ? 32 : 0);
1346#endif 1327#endif
1347 } 1328 }
1329
1330 int code = 32 + (release ? 3 : button_number) + state;
1348 1331
1349#if DEBUG_MOUSEREPORT 1332#if DEBUG_MOUSEREPORT
1350 fprintf (stderr, "Mouse ["); 1333 fprintf (stderr, "Mouse [");
1351 if (key_state & 16) 1334 if (state & 16)
1352 fputc ('C', stderr); 1335 fputc ('C', stderr);
1353 if (key_state & 4) 1336 if (state & 4)
1354 fputc ('S', stderr); 1337 fputc ('S', stderr);
1355 if (key_state & 8) 1338 if (state & 8)
1356 fputc ('A', stderr); 1339 fputc ('A', stderr);
1357 if (key_state & 32) 1340 if (state & 32)
1358 fputc ('2', stderr); 1341 fputc ('2', stderr);
1359 fprintf (stderr, "]: <%d>, %d/%d\n", 1342 fprintf (stderr, "]: <%d>, %d/%d\n",
1360 button_number, 1343 button_number,
1361 x, 1344 x,
1362 y); 1345 y);
1363#endif 1346#endif
1364 1347
1365#if ENABLE_FRILLS 1348#if ENABLE_FRILLS
1366 if (priv_modes & PrivMode_ExtMouseRight) 1349 if (priv_modes & PrivMode_ExtMouseSGR)
1350 tt_printf ("\033[<%d;%d;%d%c",
1351 button_number + state,
1352 x,
1353 y,
1354 release ? 'm' : 'M');
1355 else if (priv_modes & PrivMode_ExtMouseUrxvt)
1367 tt_printf ("\033[%d;%d;%dM", 1356 tt_printf ("\033[%d;%d;%dM",
1368 code + button_number + key_state, 1357 code,
1369 x, 1358 x,
1370 y); 1359 y);
1371 else if (priv_modes & PrivMode_ExtModeMouse) 1360 else if (priv_modes & PrivMode_ExtMouseUTF8)
1372 tt_printf ("\033[M%c%lc%lc", 1361 tt_printf ("\033[M%c%lc%lc",
1373 code + button_number + key_state, 1362 code,
1374 wint_t (32 + x), 1363 wint_t (32 + x),
1375 wint_t (32 + y)); 1364 wint_t (32 + y));
1376 else 1365 else
1377#endif 1366#endif
1378 tt_printf ("\033[M%c%c%c", 1367 tt_printf ("\033[M%c%c%c",
1379 code + button_number + key_state, 1368 code,
1380 32 + x, 1369 32 + x,
1381 32 + y); 1370 32 + y);
1382} 1371}
1383 1372
1384/*{{{ process an X event */ 1373/*{{{ process an X event */
1495 while (XCheckTypedWindowEvent (dpy, ev.xconfigure.window, ConfigureNotify, &ev)) 1484 while (XCheckTypedWindowEvent (dpy, ev.xconfigure.window, ConfigureNotify, &ev))
1496 ; 1485 ;
1497 1486
1498 bool want_position_change = SHOULD_INVOKE (HOOK_POSITION_CHANGE); 1487 bool want_position_change = SHOULD_INVOKE (HOOK_POSITION_CHANGE);
1499 1488
1500 bool moved = false;
1501#ifdef HAVE_BG_PIXMAP
1502 if (bg_window_position_sensitive ())
1503 {
1504 want_position_change = true;
1505 if (bg_img == 0)
1506 moved = true;
1507 }
1508#endif
1509
1510 if (want_position_change) 1489 if (want_position_change)
1511 { 1490 {
1512 int x, y; 1491 int x, y;
1513 1492
1514 if (ev.xconfigure.send_event) 1493 if (ev.xconfigure.send_event)
1522 if (x != parent_x || y != parent_y) 1501 if (x != parent_x || y != parent_y)
1523 { 1502 {
1524 parent_x = x; 1503 parent_x = x;
1525 parent_y = y; 1504 parent_y = y;
1526 HOOK_INVOKE ((this, HOOK_POSITION_CHANGE, DT_INT, x, DT_INT, y, DT_END)); 1505 HOOK_INVOKE ((this, HOOK_POSITION_CHANGE, DT_INT, x, DT_INT, y, DT_END));
1527 moved = true;
1528 } 1506 }
1529 } 1507 }
1530 1508
1531 if (szHint.width != ev.xconfigure.width || szHint.height != ev.xconfigure.height) 1509 if (szHint.width != ev.xconfigure.width || szHint.height != ev.xconfigure.height)
1532 { 1510 {
1533 seen_resize = 1; 1511 seen_resize = 1;
1534 resize_all_windows (ev.xconfigure.width, ev.xconfigure.height, 1); 1512 resize_all_windows (ev.xconfigure.width, ev.xconfigure.height, 1);
1535 } 1513 }
1536 else
1537 {
1538#ifdef HAVE_BG_PIXMAP
1539 if (moved)
1540 update_background ();
1541#endif
1542 }
1543 1514
1544 HOOK_INVOKE ((this, HOOK_CONFIGURE_NOTIFY, DT_XEVENT, &ev, DT_END)); 1515 HOOK_INVOKE ((this, HOOK_CONFIGURE_NOTIFY, DT_XEVENT, &ev, DT_END));
1545 } 1516 }
1546 break; 1517 break;
1547 1518
1556 case SelectionRequest: 1527 case SelectionRequest:
1557 selection_send (ev.xselectionrequest); 1528 selection_send (ev.xselectionrequest);
1558 break; 1529 break;
1559 1530
1560 case MapNotify: 1531 case MapNotify:
1561#ifdef HAVE_BG_PIXMAP
1562 // This is needed at startup for the case of no window manager
1563 // or a non-reparenting window manager and also because we
1564 // defer bg image updates if the window is not mapped. The
1565 // short delay is to optimize for multiple ConfigureNotify
1566 // events at startup when the window manager reparents the
1567 // window, so as to perform the computation after we have
1568 // received all of them.
1569 if (bg_img == 0)
1570 update_background_ev.start (0.025);
1571#endif
1572 mapped = 1; 1532 mapped = 1;
1573#ifdef TEXT_BLINK 1533#ifdef TEXT_BLINK
1574 text_blink_ev.start (); 1534 text_blink_ev.start ();
1575#endif 1535#endif
1576 HOOK_INVOKE ((this, HOOK_MAP_NOTIFY, DT_XEVENT, &ev, DT_END)); 1536 HOOK_INVOKE ((this, HOOK_MAP_NOTIFY, DT_XEVENT, &ev, DT_END));
1625 case MotionNotify: 1585 case MotionNotify:
1626#ifdef POINTER_BLANK 1586#ifdef POINTER_BLANK
1627 if (hidden_pointer) 1587 if (hidden_pointer)
1628 pointer_unblank (); 1588 pointer_unblank ();
1629#endif 1589#endif
1590 if (!bypass_keystate
1630 if ((priv_modes & PrivMode_MouseBtnEvent && ev.xbutton.state & (Button1Mask|Button2Mask|Button3Mask)) 1591 && ((priv_modes & PrivMode_MouseBtnEvent && ev.xbutton.state & (Button1Mask|Button2Mask|Button3Mask))
1631 || priv_modes & PrivMode_MouseAnyEvent) 1592 || priv_modes & PrivMode_MouseAnyEvent))
1632 mouse_report (ev.xbutton); 1593 mouse_report (ev.xbutton);
1633 if ((priv_modes & PrivMode_mouse_report) && !bypass_keystate) 1594 if ((priv_modes & PrivMode_mouse_report) && !bypass_keystate)
1634 break; 1595 break;
1635 1596
1636 if (ev.xany.window == vt) 1597 if (ev.xany.window == vt)
1648 &unused_root_x, &unused_root_y, 1609 &unused_root_x, &unused_root_y,
1649 &ev.xbutton.x, &ev.xbutton.y, 1610 &ev.xbutton.x, &ev.xbutton.y,
1650 &ev.xbutton.state); 1611 &ev.xbutton.state);
1651#ifdef MOUSE_THRESHOLD 1612#ifdef MOUSE_THRESHOLD
1652 /* deal with a `jumpy' mouse */ 1613 /* deal with a `jumpy' mouse */
1653 if ((ev.xmotion.time - MEvent.time) > MOUSE_THRESHOLD) 1614 if (ev.xmotion.time - MEvent.time > MOUSE_THRESHOLD)
1615#endif
1654 { 1616 {
1655#endif
1656#if ISO_14755 1617#if ISO_14755
1657 // 5.4 1618 // 5.4
1658 if (iso14755buf & (ISO_14755_STARTED | ISO_14755_54)) 1619 if (iso14755buf & (ISO_14755_STARTED | ISO_14755_54))
1659 { 1620 {
1660 iso14755_54 (ev.xbutton.x, ev.xbutton.y); 1621 iso14755_54 (ev.xbutton.x, ev.xbutton.y);
1709 * shouldn't be scrolling 1670 * shouldn't be scrolling
1710 */ 1671 */
1711 sel_scroll_ev.stop(); 1672 sel_scroll_ev.stop();
1712 } 1673 }
1713#endif 1674#endif
1714#ifdef MOUSE_THRESHOLD
1715 } 1675 }
1716#endif
1717 } 1676 }
1718 } 1677 }
1719 else if (scrollBar.state == SB_STATE_MOTION && ev.xany.window == scrollBar.win) 1678 else if (scrollBar.state == SB_STATE_MOTION && ev.xany.window == scrollBar.win)
1720 { 1679 {
1721 while (XCheckTypedWindowEvent (dpy, scrollBar.win, 1680 while (XCheckTypedWindowEvent (dpy, scrollBar.win,
1795#endif 1754#endif
1796#if OFF_FOCUS_FADING 1755#if OFF_FOCUS_FADING
1797 if (rs[Rs_fade]) 1756 if (rs[Rs_fade])
1798 { 1757 {
1799 pix_colors = pix_colors_focused; 1758 pix_colors = pix_colors_focused;
1800 scr_recolour (); 1759 scr_recolor ();
1801 } 1760 }
1802#endif 1761#endif
1803#if ENABLE_FRILLS 1762#if ENABLE_FRILLS
1804 if (option (Opt_urgentOnBell)) 1763 if (option (Opt_urgentOnBell))
1805 set_urgency (0); 1764 set_urgency (0);
1765
1766 if (priv_modes & PrivMode_FocusEvent)
1767 tt_printf ("\x1b[I");
1806#endif 1768#endif
1807 1769
1808 HOOK_INVOKE ((this, HOOK_FOCUS_IN, DT_END)); 1770 HOOK_INVOKE ((this, HOOK_FOCUS_IN, DT_END));
1809 } 1771 }
1810} 1772}
1818 want_refresh = 1; 1780 want_refresh = 1;
1819 1781
1820#if ENABLE_FRILLS 1782#if ENABLE_FRILLS
1821 if (option (Opt_urgentOnBell)) 1783 if (option (Opt_urgentOnBell))
1822 set_urgency (0); 1784 set_urgency (0);
1785
1786 if (priv_modes & PrivMode_FocusEvent)
1787 tt_printf ("\x1b[O");
1823#endif 1788#endif
1824#if ENABLE_FRILLS || ISO_14755 1789#if ENABLE_FRILLS || ISO_14755
1825 if (iso14755buf) 1790 if (iso14755buf)
1826 { 1791 {
1827 iso14755buf = 0; 1792 iso14755buf = 0;
1842#endif 1807#endif
1843#if OFF_FOCUS_FADING 1808#if OFF_FOCUS_FADING
1844 if (rs[Rs_fade]) 1809 if (rs[Rs_fade])
1845 { 1810 {
1846 pix_colors = pix_colors_unfocused; 1811 pix_colors = pix_colors_unfocused;
1847 scr_recolour (); 1812 scr_recolor ();
1848 } 1813 }
1849#endif 1814#endif
1850 1815
1851 HOOK_INVOKE ((this, HOOK_FOCUS_OUT, DT_END)); 1816 HOOK_INVOKE ((this, HOOK_FOCUS_OUT, DT_END));
1852 } 1817 }
1853} 1818}
1854 1819
1855void ecb_cold 1820void ecb_cold
1856rxvt_term::update_fade_color (unsigned int idx) 1821rxvt_term::update_fade_color (unsigned int idx, bool first_time)
1857{ 1822{
1858#if OFF_FOCUS_FADING 1823#if OFF_FOCUS_FADING
1859 if (rs[Rs_fade]) 1824 if (rs[Rs_fade])
1860 { 1825 {
1826 if (!first_time)
1827 pix_colors_focused [idx].free (this);
1828
1861 rgba c; 1829 rgba c;
1862 pix_colors [Color_fade].get (c); 1830 pix_colors [Color_fade].get (c);
1863 pix_colors_focused [idx].fade (this, atoi (rs[Rs_fade]), pix_colors_unfocused [idx], c); 1831 pix_colors_focused [idx].fade (this, atoi (rs[Rs_fade]), pix_colors_unfocused [idx], c);
1864 } 1832 }
1865#endif 1833#endif
1866} 1834}
1867 1835
1868#if BG_IMAGE_FROM_ROOT || ENABLE_PERL 1836#if ENABLE_PERL
1869void ecb_hot 1837void ecb_hot
1870rxvt_term::rootwin_cb (XEvent &ev) 1838rxvt_term::rootwin_cb (XEvent &ev)
1871{ 1839{
1872 make_current (); 1840 make_current ();
1873 1841
1883 * use the property to determine the pixmap. We use it later on. 1851 * use the property to determine the pixmap. We use it later on.
1884 */ 1852 */
1885 if (ev.xproperty.atom == xa[XA_XROOTPMAP_ID] 1853 if (ev.xproperty.atom == xa[XA_XROOTPMAP_ID]
1886 || ev.xproperty.atom == xa[XA_ESETROOT_PMAP_ID]) 1854 || ev.xproperty.atom == xa[XA_ESETROOT_PMAP_ID])
1887 { 1855 {
1888#if BG_IMAGE_FROM_ROOT
1889 if (option (Opt_transparent))
1890 {
1891 rxvt_img::new_from_root (this)->replace (root_img);
1892 update_background ();
1893 }
1894#endif
1895 HOOK_INVOKE ((this, HOOK_ROOTPMAP_CHANGE, DT_END)); 1856 HOOK_INVOKE ((this, HOOK_ROOTPMAP_CHANGE, DT_END));
1896 } 1857 }
1897 1858
1898 break; 1859 break;
1899 } 1860 }
1927 iso14755_54 (ev.x, ev.y); 1888 iso14755_54 (ev.x, ev.y);
1928 return; 1889 return;
1929 } 1890 }
1930#endif 1891#endif
1931 1892
1932 clickintime = ev.time - MEvent.time < MULTICLICK_TIME; 1893 clickintime = ev.time - MEvent.time < multiClickTime;
1933 1894
1934 if (reportmode) 1895 if (reportmode)
1935 { 1896 {
1936 /* mouse report from vt window */ 1897 /* mouse report from vt window */
1937 /* save the xbutton state (for ButtonRelease) */ 1898 /* save the xbutton state (for ButtonRelease) */
2187#ifdef MOUSE_REPORT_DOUBLECLICK 2148#ifdef MOUSE_REPORT_DOUBLECLICK
2188 /* only report the release of 'slow' single clicks */ 2149 /* only report the release of 'slow' single clicks */
2189 if (MEvent.button != AnyButton 2150 if (MEvent.button != AnyButton
2190 && (ev.button != MEvent.button 2151 && (ev.button != MEvent.button
2191 || (ev.time - MEvent.time 2152 || (ev.time - MEvent.time
2192 > MULTICLICK_TIME / 2))) 2153 > multiClickTime / 2)))
2193 { 2154 {
2194 MEvent.clicks = 0; 2155 MEvent.clicks = 0;
2195 MEvent.button = AnyButton; 2156 MEvent.button = ev.button;
2196 mouse_report (ev); 2157 mouse_report (ev);
2197 } 2158 }
2198#else /* MOUSE_REPORT_DOUBLECLICK */ 2159#else /* MOUSE_REPORT_DOUBLECLICK */
2199 MEvent.button = AnyButton; 2160 MEvent.button = ev.button;
2200 mouse_report (ev); 2161 mouse_report (ev);
2201#endif /* MOUSE_REPORT_DOUBLECLICK */ 2162#endif /* MOUSE_REPORT_DOUBLECLICK */
2202 return; 2163 return;
2203 } 2164 }
2204 2165
2395wchar_t ecb_hot 2356wchar_t ecb_hot
2396rxvt_term::next_char () NOTHROW 2357rxvt_term::next_char () NOTHROW
2397{ 2358{
2398 while (cmdbuf_ptr < cmdbuf_endp) 2359 while (cmdbuf_ptr < cmdbuf_endp)
2399 { 2360 {
2400 // assume 7-bit to be ascii ALWAYS 2361 // assume 7-bit to be ascii ALWAYS (always true in POSIX)
2401 if (ecb_likely ((unsigned char)*cmdbuf_ptr <= 0x7f && *cmdbuf_ptr != 0x1b)) 2362 if (ecb_likely ((unsigned char)*cmdbuf_ptr <= 0x7f))
2402 return *cmdbuf_ptr++; 2363 return *cmdbuf_ptr++;
2403 2364
2404 wchar_t wc; 2365 wchar_t wc;
2405 size_t len = mbrtowc (&wc, cmdbuf_ptr, cmdbuf_endp - cmdbuf_ptr, mbstate); 2366 size_t len = mbrtowc (&wc, cmdbuf_ptr, cmdbuf_endp - cmdbuf_ptr, mbstate);
2406 2367
2587 scr_charset_choose (0); 2548 scr_charset_choose (0);
2588 break; 2549 break;
2589 2550
2590#ifdef EIGHT_BIT_CONTROLS 2551#ifdef EIGHT_BIT_CONTROLS
2591 // 8-bit controls 2552 // 8-bit controls
2592 case 0x90: /* DCS */ 2553 case 0x90: /* DCS */
2593 process_dcs_seq (); 2554 process_dcs_seq ();
2594 break; 2555 break;
2595 case 0x9b: /* CSI */ 2556 case 0x9b: /* CSI */
2596 process_csi_seq (); 2557 process_csi_seq ();
2597 break; 2558 break;
2598 case 0x9d: /* OSC */ 2559 case 0x9d: /* OSC */
2599 process_osc_seq (); 2560 process_osc_seq ();
2600 break; 2561 break;
2601#endif 2562#endif
2602 } 2563 }
2603} 2564}
2731 wchar_t nlcr[] = { C0_LF, C0_CR }; 2692 wchar_t nlcr[] = { C0_LF, C0_CR };
2732 scr_add_lines (nlcr, ecb_array_length (nlcr), 1); 2693 scr_add_lines (nlcr, ecb_array_length (nlcr), 1);
2733 } 2694 }
2734 break; 2695 break;
2735 2696
2697#if 0 // disabled because embedded newlines can make exploits easier
2736 /* kidnapped escape sequence: Should be 8.3.48 */ 2698 /* kidnapped escape sequence: Should be 8.3.48 */
2737 case C1_ESA: /* ESC G */ 2699 case C1_ESA: /* ESC G */
2738 // used by original rxvt for rob nations own graphics mode 2700 // used by original rxvt for rob nations own graphics mode
2739 if (cmd_getc () == 'Q') 2701 if (cmd_getc () == 'Q' && option (Opt_insecure))
2740 tt_printf ("\033G0\012"); /* query graphics - no graphics */ 2702 tt_printf ("\033G0\012"); /* query graphics - no graphics */
2741 break; 2703 break;
2704#endif
2742 2705
2743 /* 8.3.63: CHARACTER TABULATION SET */ 2706 /* 8.3.63: CHARACTER TABULATION SET */
2744 case C1_HTS: /* ESC H */ 2707 case C1_HTS: /* ESC H */
2745 scr_set_tab (1); 2708 scr_set_tab (1);
2746 break; 2709 break;
2913 { 2876 {
2914 /* DECSTR: soft terminal reset, used by our terminfo since 9.06 */ 2877 /* DECSTR: soft terminal reset, used by our terminfo since 9.06 */
2915 scr_soft_reset (); 2878 scr_soft_reset ();
2916 2879
2917 static const int pm_h[] = { 7, 25 }; 2880 static const int pm_h[] = { 7, 25 };
2918 static const int pm_l[] = { 1, 3, 4, 5, 6, 9, 66, 1000, 1001, 1005, 1015, 1049 }; 2881 static const int pm_l[] = { 1, 3, 4, 5, 6, 9, 66, 1000, 1001, 1005, 1006, 1015, 1049 };
2919 2882
2920 process_terminal_mode ('h', 0, ecb_array_length (pm_h), pm_h); 2883 process_terminal_mode ('h', 0, ecb_array_length (pm_h), pm_h);
2921 process_terminal_mode ('l', 0, ecb_array_length (pm_l), pm_l); 2884 process_terminal_mode ('l', 0, ecb_array_length (pm_l), pm_l);
2922 } 2885 }
2923 break; 2886 break;
2953 case CSI_VPR: /* 8.3.161: (1) LINE POSITION FORWARD */ 2916 case CSI_VPR: /* 8.3.161: (1) LINE POSITION FORWARD */
2954 scr_gotorc (arg[0], 0, RELATIVE); 2917 scr_gotorc (arg[0], 0, RELATIVE);
2955 break; 2918 break;
2956 2919
2957 case CSI_CUB: /* 8.3.18: (1) CURSOR LEFT */ 2920 case CSI_CUB: /* 8.3.18: (1) CURSOR LEFT */
2958 case CSI_HPB: /* 8.3.59: (1) CHARACTER POSITION BACKWARD */ 2921 case CSI_HPB: /* 8.3.59: (1) CHARACTER POSITION BACKWARD */
2959#ifdef ISO6429 2922#ifdef ISO6429
2960 arg[0] = -arg[0]; 2923 arg[0] = -arg[0];
2961#else /* emulate common DEC VTs */ 2924#else /* emulate common DEC VTs */
2962 arg[0] = arg[0] ? -arg[0] : -1; 2925 arg[0] = arg[0] ? -arg[0] : -1;
2963#endif 2926#endif
3108 scr_insert_mode (1); 3071 scr_insert_mode (1);
3109 else if (arg[0] == 20) 3072 else if (arg[0] == 20)
3110 priv_modes |= PrivMode_LFNL; 3073 priv_modes |= PrivMode_LFNL;
3111 break; 3074 break;
3112 3075
3113 case CSI_71: // DESCUSR: set cursor style 3076 case CSI_71: // DECSCUSR: set cursor style
3114 if (prev_ch == ' ') 3077 if (prev_ch == ' ')
3115 set_cursor_style (arg[0]); 3078 set_cursor_style (arg[0]);
3116 break; 3079 break;
3117 3080
3118 /* 3081 /*
3339 free (s); 3302 free (s);
3340 } 3303 }
3341 } 3304 }
3342} 3305}
3343 3306
3307static unsigned int
3308colorcube_index (unsigned int idx_r,
3309 unsigned int idx_g,
3310 unsigned int idx_b)
3311{
3312 assert (idx_r < Red_levels);
3313 assert (idx_g < Green_levels);
3314 assert (idx_b < Blue_levels);
3315
3316 return idx_r * Blue_levels * Green_levels +
3317 idx_g * Blue_levels +
3318 idx_b;
3319}
3320
3321/*
3322 * Find the nearest color slot in the hidden color cube,
3323 * adapt its value to the 32bit RGBA color.
3324 */
3325unsigned int
3326rxvt_term::map_rgb24_color (unsigned int r, unsigned int g, unsigned int b, unsigned int a)
3327{
3328 r &= 0xff;
3329 g &= 0xff;
3330 b &= 0xff;
3331 a &= 0xff;
3332
3333 uint32_t color = (a << 24) | (r << 16) | (g << 8) | b;
3334
3335 unsigned int idx_r = r * (Red_levels - 1) / 0xff;
3336 unsigned int idx_g = g * (Green_levels - 1) / 0xff;
3337 unsigned int idx_b = b * (Blue_levels - 1) / 0xff;
3338 unsigned int idx = colorcube_index (idx_r, idx_g, idx_b);
3339
3340 /* we allow one of the 6 directly neighbouring colours */
3341 /* to replace the current color, if they not used recently */
3342 static const signed char dxyz[][3] = {
3343 0, 0, 0,
3344 0, 0, +1,
3345 0, 0, -1,
3346 0, +1, 0,
3347 0, -1, 0,
3348 +1, 0, 0,
3349 -1, 0, 0,
3350 };
3351
3352 for (int n = 0; n < ecb_array_length (dxyz); ++n)
3353 {
3354 int r = idx_r + dxyz[n][0];
3355 int g = idx_g + dxyz[n][1];
3356 int b = idx_b + dxyz[n][2];
3357
3358 if (!IN_RANGE_EXC (r, 0, Red_levels )) continue;
3359 if (!IN_RANGE_EXC (g, 0, Green_levels)) continue;
3360 if (!IN_RANGE_EXC (b, 0, Blue_levels )) continue;
3361
3362 unsigned int index = colorcube_index (r, g, b);
3363
3364 if (rgb24_color[index] == color)
3365 {
3366 rgb24_seqno[index] = ++rgb24_sequence;
3367 return index + minTermCOLOR24;
3368 }
3369
3370 // minor issue: could update index 0 few more times
3371 if ((rgb24_seqno[index] | rgb24_color[index]) == 0)
3372 {
3373 idx = index;
3374 goto update;
3375 }
3376
3377 // like (rgb24_seqno[idx] > rgb24_seqno[index])
3378 // but also handles wrap around values good enough
3379 if ((uint16_t)(rgb24_seqno[idx] - rgb24_seqno[index]) < 0x7fff)
3380 idx = index;
3381 }
3382
3383update:
3384 rgb24_color[idx] = color;
3385 rgb24_seqno[idx] = ++rgb24_sequence;
3386
3387 idx += minTermCOLOR24;
3388 pix_colors_focused [idx].free (this);
3389 pix_colors_focused [idx].set (this, rgba (r * 0x0101, g * 0x0101, b * 0x0101, a * 0x0101));
3390 update_fade_color (idx, false);
3391
3392 return idx;
3393}
3394
3344void 3395void
3345rxvt_term::process_color_seq (int report, int color, const char *str, char resp) 3396rxvt_term::process_color_seq (int report, int color, const char *str, char resp)
3346{ 3397{
3347 if (str[0] == '?' && !str[1]) 3398 if (str[0] == '?' && !str[1])
3348 { 3399 {
3349 rgba c; 3400 rgba c;
3350 pix_colors_focused[color].get (c); 3401 pix_colors_focused[color].get (c);
3351 3402
3352#if XFT 3403#if XFT
3353 if (c.a != rgba::MAX_CC) 3404 if (c.a != rgba::MAX_CC)
3354 tt_printf ("\033]%d;rgba:%04x/%04x/%04x/%04x%c", report, c.a, c.r, c.g, c.b, resp); 3405 tt_printf ("\033]%d;rgba:%04x/%04x/%04x/%04x%c", report, c.r, c.g, c.b, c.a, resp);
3355 else 3406 else
3356#endif 3407#endif
3357 tt_printf ("\033]%d;rgb:%04x/%04x/%04x%c", report, c.r, c.g, c.b, resp); 3408 tt_printf ("\033]%d;rgb:%04x/%04x/%04x%c", report, c.r, c.g, c.b, resp);
3358 } 3409 }
3359 else 3410 else
3485 break; 3536 break;
3486#endif 3537#endif
3487 case URxvt_Color_border: 3538 case URxvt_Color_border:
3488 process_color_seq (op, Color_border, str, resp); 3539 process_color_seq (op, Color_border, str, resp);
3489 break; 3540 break;
3490
3491#if BG_IMAGE_FROM_ROOT
3492 case URxvt_Color_tint:
3493 process_color_seq (op, Color_tint, str, resp);
3494 {
3495 bool changed = false;
3496
3497 if (ISSET_PIXCOLOR (Color_tint))
3498 changed = root_effects.set_tint (pix_colors_focused [Color_tint]);
3499
3500 if (changed)
3501 update_background ();
3502 }
3503
3504 break;
3505#endif
3506
3507#if BG_IMAGE_FROM_FILE
3508 case Rxvt_Pixmap:
3509 if (!strcmp (str, "?"))
3510 {
3511 char str[256];
3512 int h_scale = fimage.h_scale;
3513 int v_scale = fimage.v_scale;
3514 int h_align = fimage.h_align;
3515 int v_align = fimage.v_align;
3516
3517 sprintf (str, "[%dx%d+%d+%d]",
3518 h_scale, v_scale,
3519 h_align, v_align);
3520 process_xterm_seq (XTerm_title, str, CHAR_ST);
3521 }
3522 else
3523 {
3524 bool changed = false;
3525
3526 if (*str != ';')
3527 {
3528 try
3529 {
3530 fimage.set_file_geometry (this, str);
3531 changed = true;
3532 }
3533 catch (const class rxvt_failure_exception &e)
3534 {
3535 }
3536 }
3537 else
3538 {
3539 str++;
3540 if (fimage.set_geometry (str, true))
3541 changed = true;
3542 }
3543
3544 if (changed)
3545 {
3546 if (bg_window_position_sensitive ())
3547 {
3548 int x, y;
3549 get_window_origin (x, y);
3550 parent_x = x;
3551 parent_y = y;
3552 }
3553 update_background ();
3554 }
3555 }
3556 break;
3557#endif
3558 3541
3559 case XTerm_logfile: 3542 case XTerm_logfile:
3560 // TODO, when secure mode? 3543 // TODO, when secure mode?
3561 break; 3544 break;
3562 3545
3696 { 5, PrivMode_rVideo }, // DECSCNM 3679 { 5, PrivMode_rVideo }, // DECSCNM
3697 { 6, PrivMode_relOrigin }, // DECOM 3680 { 6, PrivMode_relOrigin }, // DECOM
3698 { 7, PrivMode_Autowrap }, // DECAWM 3681 { 7, PrivMode_Autowrap }, // DECAWM
3699 // 8, auto-repeat keys // DECARM 3682 // 8, auto-repeat keys // DECARM
3700 { 9, PrivMode_MouseX10 }, 3683 { 9, PrivMode_MouseX10 },
3684 { 12, PrivMode_BlinkingCursor },
3701 // 18 end FF to printer after print screen 3685 // 18 end FF to printer after print screen
3702 // 19 Print screen prints full screen/scroll region 3686 // 19 Print screen prints full screen/scroll region
3703 { 25, PrivMode_VisibleCursor }, // DECTCEM cnorm/cvvis/civis 3687 { 25, PrivMode_VisibleCursor }, // DECTCEM cnorm/cvvis/civis
3704#ifdef scrollBar_esc 3688#ifdef scrollBar_esc
3705 { scrollBar_esc, PrivMode_scrollBar }, 3689 { scrollBar_esc, PrivMode_scrollBar },
3717#endif 3701#endif
3718 { 1000, PrivMode_MouseX11 }, 3702 { 1000, PrivMode_MouseX11 },
3719 { 1002, PrivMode_MouseBtnEvent }, 3703 { 1002, PrivMode_MouseBtnEvent },
3720 { 1003, PrivMode_MouseAnyEvent }, 3704 { 1003, PrivMode_MouseAnyEvent },
3721#if ENABLE_FRILLS 3705#if ENABLE_FRILLS
3706 { 1004, PrivMode_FocusEvent },
3722 { 1005, PrivMode_ExtModeMouse }, 3707 { 1005, PrivMode_ExtMouseUTF8 },
3708 { 1006, PrivMode_ExtMouseSGR },
3723#endif 3709#endif
3724 { 1010, PrivMode_TtyOutputInh }, // rxvt extension 3710 { 1010, PrivMode_TtyOutputInh }, // rxvt extension
3725 { 1011, PrivMode_Keypress }, // rxvt extension 3711 { 1011, PrivMode_Keypress }, // rxvt extension
3726#if ENABLE_FRILLS 3712#if ENABLE_FRILLS
3727 { 1015, PrivMode_ExtMouseRight }, // urxvt extension of 1005 3713 { 1015, PrivMode_ExtMouseUrxvt }, // urxvt extension of 1005
3728#endif 3714#endif
3729 // 1035 enable modifiers for alt, numlock NYI 3715 // 1035 enable modifiers for alt, numlock NYI
3730 // 1036 send ESC for meta keys NYI 3716 // 1036 send ESC for meta keys NYI
3731 // 1037 send DEL for keypad delete NYI 3717 // 1037 send DEL for keypad delete NYI
3732 { 1047, PrivMode_Screen }, 3718 { 1047, PrivMode_Screen },
3814 scrollBar.map (state); 3800 scrollBar.map (state);
3815 resize_all_windows (0, 0, 0); 3801 resize_all_windows (0, 0, 0);
3816 scr_touch (true); 3802 scr_touch (true);
3817 break; 3803 break;
3818#endif 3804#endif
3805#ifdef CURSOR_BLINK
3806 case 12:
3807 cursor_blink_reset ();
3808 break;
3809#endif
3819 case 25: /* visible/invisible cursor */ 3810 case 25: /* visible/invisible cursor */
3820 scr_cursor_visible (state); 3811 scr_cursor_visible (state);
3821 break; 3812 break;
3822 /* case 35: - shift keys */ 3813 /* case 35: - shift keys */
3823 /* case 40: - 80 <--> 132 mode */ 3814 /* case 40: - 80 <--> 132 mode */
3928 //case 19: // ninth alt font 3919 //case 19: // ninth alt font
3929 //case 20: // gothic 3920 //case 20: // gothic
3930 case 21: // disable bold, faint, sometimes doubly underlined (iso 8613) 3921 case 21: // disable bold, faint, sometimes doubly underlined (iso 8613)
3931 rendset = 0, rendstyle = RS_Bold; 3922 rendset = 0, rendstyle = RS_Bold;
3932 break; 3923 break;
3933 case 22: // normal intensity 3924 case 22: // bold off (vt220)
3934 rendset = 0, rendstyle = RS_Bold; 3925 rendset = 0, rendstyle = RS_Bold;
3935 break; 3926 break;
3936 case 23: // disable italic 3927 case 23: // disable italic
3937 rendset = 0, rendstyle = RS_Italic; 3928 rendset = 0, rendstyle = RS_Italic;
3938 break; 3929 break;
3939 case 24: 3930 case 24: // underline off (vt220)
3940 rendset = 0, rendstyle = RS_Uline; 3931 rendset = 0, rendstyle = RS_Uline;
3941 break; 3932 break;
3942 case 25: 3933 case 25: // blink off (vt220)
3943 rendset = 0, rendstyle = RS_Blink; 3934 rendset = 0, rendstyle = RS_Blink;
3944 break; 3935 break;
3945 case 26: // variable spacing (iso 8613) 3936 case 26: // variable spacing (iso 8613)
3946 rendset = 0, rendstyle = RS_Blink; 3937 rendset = 0, rendstyle = RS_Blink;
3947 break; 3938 break;
3948 case 27: 3939 case 27: // reverse off (vt220)
3949 rendset = 0, rendstyle = RS_RVid; 3940 rendset = 0, rendstyle = RS_RVid;
3950 break; 3941 break;
3951 //case 28: // visible. NYI 3942 //case 28: // visible. NYI
3952 //case 29: // not crossed-out 3943 //case 29: // not crossed-out
3953 } 3944 }
3968 case 35: 3959 case 35:
3969 case 36: 3960 case 36:
3970 case 37: 3961 case 37:
3971 scr_color ((unsigned int) (minCOLOR + (arg[i] - 30)), Color_fg); 3962 scr_color ((unsigned int) (minCOLOR + (arg[i] - 30)), Color_fg);
3972 break; 3963 break;
3973 case 38: // set fg color, ISO 8613-6
3974 if (nargs > i + 2 && arg[i + 1] == 5)
3975 {
3976 scr_color ((unsigned int) (minCOLOR + arg[i + 2]), Color_fg);
3977 i += 2;
3978 }
3979 break;
3980 case 39: /* default fg */ 3964 case 39: /* default fg */
3981 scr_color (Color_fg, Color_fg); 3965 scr_color (Color_fg, Color_fg);
3982 break; 3966 break;
3983 3967
3984 case 40: 3968 case 40:
3989 case 45: 3973 case 45:
3990 case 46: 3974 case 46:
3991 case 47: 3975 case 47:
3992 scr_color ((unsigned int) (minCOLOR + (arg[i] - 40)), Color_bg); 3976 scr_color ((unsigned int) (minCOLOR + (arg[i] - 40)), Color_bg);
3993 break; 3977 break;
3994 case 48: // set bg color, ISO 8613-6
3995 if (nargs > i + 2 && arg[i + 1] == 5)
3996 {
3997 scr_color ((unsigned int) (minCOLOR + arg[i + 2]), Color_bg);
3998 i += 2;
3999 }
4000 break;
4001 case 49: /* default bg */ 3978 case 49: /* default bg */
4002 scr_color (Color_bg, Color_bg); 3979 scr_color (Color_bg, Color_bg);
3980 break;
3981
3982 case 38: // set fg color, ISO 8613-6
3983 case 48: // set bg color, ISO 8613-6
3984 {
3985 unsigned int fgbg = arg[i] == 38 ? Color_fg : Color_bg;
3986 unsigned int idx;
3987
3988 if (nargs > i + 2 && arg[i + 1] == 5)
3989 {
3990 idx = minCOLOR + arg[i + 2];
3991 i += 2;
3992
3993 scr_color (idx, fgbg);
3994 }
3995 else if (nargs > i + 4 && arg[i + 1] == 2)
3996 {
3997 unsigned int r = arg[i + 2];
3998 unsigned int g = arg[i + 3];
3999 unsigned int b = arg[i + 4];
4000 unsigned int a = 0xff;
4001
4002 idx = map_rgb24_color (r, g, b, a);
4003
4004 i += 4;
4005
4006 scr_color (idx, fgbg);
4007 }
4008 }
4003 break; 4009 break;
4004 4010
4005 //case 50: // not variable spacing 4011 //case 50: // not variable spacing
4006 4012
4007#if !ENABLE_MINIMAL 4013#if !ENABLE_MINIMAL
4031} 4037}
4032 4038
4033void 4039void
4034rxvt_term::set_cursor_style (int style) 4040rxvt_term::set_cursor_style (int style)
4035{ 4041{
4036 if (!IN_RANGE_INC (style, 0, 4)) 4042 if (!IN_RANGE_INC (style, 0, 6))
4037 return; 4043 return;
4038 4044
4045 if (style == 0)
4046 style = 1;
4047
4048 cursor_type = (style - 1) / 2;
4039 set_option (Opt_cursorUnderline, style >= 3); 4049 set_option (Opt_cursorUnderline, cursor_type == 1);
4040 4050
4041#ifdef CURSOR_BLINK 4051#ifdef CURSOR_BLINK
4042 set_option (Opt_cursorBlink, !style || (style & 1)); 4052 set_option (Opt_cursorBlink, style & 1);
4043 cursor_blink_reset (); 4053 cursor_blink_reset ();
4044#endif 4054#endif
4045 4055
4046 want_refresh = 1; 4056 want_refresh = 1;
4047} 4057}
4048/*}}} */ 4058/*}}} */
4049 4059
4050/* ------------------------------------------------------------------------- */ 4060/* ---------------------------------------------------------------------- */
4061/* Write data to the pty as typed by the user, pasted with the mouse,
4062 * or generated by us in response to a query ESC sequence.
4063 */
4051 4064
4052/* 4065/*
4053 * Send printf () formatted output to the command. 4066 * Send printf () formatted output to the command.
4054 * Only use for small amounts of data. 4067 * Only use for small amounts of data.
4055 */ 4068 */
4063 vsnprintf ((char *)buf, 256, fmt, arg_ptr); 4076 vsnprintf ((char *)buf, 256, fmt, arg_ptr);
4064 va_end (arg_ptr); 4077 va_end (arg_ptr);
4065 tt_write (buf, strlen (buf)); 4078 tt_write (buf, strlen (buf));
4066} 4079}
4067 4080
4068/* ---------------------------------------------------------------------- */
4069/* Write data to the pty as typed by the user, pasted with the mouse, 4081/* Write data to the pty as typed by the user. */
4070 * or generated by us in response to a query ESC sequence. 4082void
4071 */ 4083rxvt_term::tt_write_user_input (const char *data, unsigned int len)
4072static const unsigned int MAX_PTY_WRITE = 255; // minimum MAX_INPUT 4084{
4085 if (HOOK_INVOKE ((this, HOOK_TT_WRITE, DT_STR_LEN, data, len, DT_END)))
4086 return;
4087
4088 if (option (Opt_scrollTtyKeypress))
4089 if (view_start)
4090 {
4091 view_start = 0;
4092 want_refresh = 1;
4093 }
4094
4095 tt_write_ (data, len);
4096}
4073 4097
4074void 4098void
4075rxvt_term::tt_write (const char *data, unsigned int len) 4099rxvt_term::tt_write (const char *data, unsigned int len)
4076{ 4100{
4077 if (HOOK_INVOKE ((this, HOOK_TT_WRITE, DT_STR_LEN, data, len, DT_END))) 4101 if (HOOK_INVOKE ((this, HOOK_TT_WRITE, DT_STR_LEN, data, len, DT_END)))
4078 return; 4102 return;
4079 4103
4104 tt_write_ (data, len);
4105}
4106
4107static const unsigned int MAX_PTY_WRITE = 255; // minimum MAX_INPUT
4108
4109void
4110rxvt_term::tt_write_ (const char *data, unsigned int len)
4111{
4080 if (pty->pty < 0) 4112 if (pty->pty < 0)
4081 return; 4113 return;
4082 4114
4083 if (v_buflen == 0) 4115 if (v_buflen == 0)
4084 { 4116 {

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines