… | |
… | |
694 | { |
694 | { |
695 | unsigned int n, s; |
695 | unsigned int n, s; |
696 | |
696 | |
697 | n = cmdbuf_ptr - cmdbuf_base; |
697 | n = cmdbuf_ptr - cmdbuf_base; |
698 | s = cmdbuf_base + BUFSIZ - 1 - cmdbuf_endp; |
698 | s = cmdbuf_base + BUFSIZ - 1 - cmdbuf_endp; |
|
|
699 | |
699 | if (n > 0 && s < count) |
700 | if (n > 0 && s < count) |
700 | { |
701 | { |
701 | MEMMOVE (cmdbuf_base, cmdbuf_ptr, |
702 | MEMMOVE (cmdbuf_base, cmdbuf_ptr, |
702 | (unsigned int) (cmdbuf_endp - cmdbuf_ptr)); |
703 | (unsigned int) (cmdbuf_endp - cmdbuf_ptr)); |
703 | cmdbuf_ptr = cmdbuf_base; |
704 | cmdbuf_ptr = cmdbuf_base; |
704 | cmdbuf_endp -= n; |
705 | cmdbuf_endp -= n; |
705 | s += n; |
706 | s += n; |
706 | } |
707 | } |
|
|
708 | |
707 | if (count > s) |
709 | if (count > s) |
708 | { |
710 | { |
709 | rxvt_print_error ("data loss: cmd_write too large"); |
711 | rxvt_print_error ("data loss: cmd_write too large"); |
710 | count = s; |
712 | count = s; |
711 | } |
713 | } |
|
|
714 | |
712 | for (; count--;) |
715 | for (; count--;) |
713 | *cmdbuf_endp++ = *str++; |
716 | *cmdbuf_endp++ = *str++; |
|
|
717 | |
|
|
718 | cmd_parse (); |
|
|
719 | |
714 | return 0; |
720 | return 0; |
715 | } |
721 | } |
716 | #endif /* MENUBAR_MAX */ |
722 | #endif /* MENUBAR_MAX */ |
717 | |
723 | |
718 | void |
724 | void |
… | |
… | |
790 | cmdbuf_endp += n; |
796 | cmdbuf_endp += n; |
791 | return true; |
797 | return true; |
792 | } |
798 | } |
793 | else if (n < 0 && errno != EAGAIN) |
799 | else if (n < 0 && errno != EAGAIN) |
794 | destroy (); |
800 | destroy (); |
795 | |
801 | |
796 | return false; |
802 | return false; |
797 | } |
803 | } |
798 | |
804 | |
799 | void |
805 | void |
800 | rxvt_term::pty_cb (io_watcher &w, short revents) |
806 | rxvt_term::pty_cb (io_watcher &w, short revents) |
… | |
… | |
817 | seen_input = 1; |
823 | seen_input = 1; |
818 | /* once we know the shell is running, send the screen size. Again! */ |
824 | /* once we know the shell is running, send the screen size. Again! */ |
819 | tt_winch (); |
825 | tt_winch (); |
820 | } |
826 | } |
821 | |
827 | |
|
|
828 | if (cmd_parse ()) |
|
|
829 | break; |
|
|
830 | } |
|
|
831 | } |
|
|
832 | } |
|
|
833 | |
|
|
834 | bool |
|
|
835 | rxvt_term::cmd_parse () |
|
|
836 | { |
|
|
837 | bool flag = false; |
822 | uint32_t ch = NOCHAR; |
838 | uint32_t ch = NOCHAR; |
|
|
839 | |
|
|
840 | for (;;) |
|
|
841 | { |
|
|
842 | if (ch == NOCHAR) |
|
|
843 | ch = next_char (); |
|
|
844 | |
|
|
845 | if (ch == NOCHAR) // TODO: improve |
|
|
846 | break; |
|
|
847 | |
|
|
848 | if (ch >= ' ' || ch == '\t' || ch == '\n' || ch == '\r') |
|
|
849 | { |
|
|
850 | /* Read a text string from the input buffer */ |
|
|
851 | uint32_t buf[BUFSIZ]; |
|
|
852 | bool refreshnow = false; |
|
|
853 | int nlines = 0; |
|
|
854 | uint32_t *str = buf; |
|
|
855 | |
|
|
856 | *str++ = ch; |
823 | |
857 | |
824 | for (;;) |
858 | for (;;) |
825 | { |
859 | { |
826 | if (ch == NOCHAR) |
|
|
827 | ch = next_char (); |
860 | ch = next_char (); |
828 | |
861 | |
829 | if (ch == NOCHAR) // TODO: improve |
862 | if (ch == NOCHAR || (ch < ' ' && ch != '\t' && ch != '\n' && ch != '\r')) |
830 | break; |
863 | break; |
831 | |
864 | else |
832 | if (ch >= ' ' || ch == '\t' || ch == '\n' || ch == '\r') |
|
|
833 | { |
865 | { |
834 | /* Read a text string from the input buffer */ |
|
|
835 | uint32_t buf[BUFSIZ]; |
|
|
836 | bool refreshnow = false; |
|
|
837 | int nlines = 0; |
|
|
838 | uint32_t *str = buf; |
|
|
839 | |
|
|
840 | *str++ = ch; |
866 | *str++ = ch; |
841 | |
867 | |
842 | for (;;) |
868 | if (ch == '\n') |
843 | { |
869 | { |
844 | ch = next_char (); |
|
|
845 | |
|
|
846 | if (ch == NOCHAR || (ch < ' ' && ch != '\t' && ch != '\n' && ch != '\r')) |
|
|
847 | break; |
|
|
848 | else |
870 | nlines++; |
|
|
871 | refresh_count++; |
|
|
872 | |
|
|
873 | if (! (Options & Opt_jumpScroll) |
|
|
874 | || (refresh_count >= (refresh_limit * (TermWin.nrow - 1)))) |
849 | { |
875 | { |
850 | *str++ = ch; |
|
|
851 | |
|
|
852 | if (ch == '\n') |
|
|
853 | { |
|
|
854 | nlines++; |
|
|
855 | refresh_count++; |
|
|
856 | |
|
|
857 | if (! (Options & Opt_jumpScroll) |
|
|
858 | || (refresh_count >= (refresh_limit * (TermWin.nrow - 1)))) |
|
|
859 | { |
|
|
860 | refreshnow = true; |
876 | refreshnow = true; |
861 | flag = false; |
877 | flag = false; |
862 | ch = NOCHAR; |
878 | ch = NOCHAR; |
863 | break; |
879 | break; |
864 | } |
880 | } |
865 | |
881 | |
866 | // scr_add_lines only works for nlines < TermWin.nrow - 1. |
882 | // scr_add_lines only works for nlines < TermWin.nrow - 1. |
867 | if (nlines >= TermWin.nrow - 1) |
883 | if (nlines >= TermWin.nrow - 1) |
868 | { |
884 | { |
869 | scr_add_lines (buf, nlines, str - buf); |
885 | scr_add_lines (buf, nlines, str - buf); |
870 | nlines = 0; |
886 | nlines = 0; |
871 | str = buf; |
887 | str = buf; |
872 | } |
|
|
873 | } |
|
|
874 | |
|
|
875 | if (str >= buf + BUFSIZ) |
|
|
876 | { |
|
|
877 | ch = NOCHAR; |
|
|
878 | break; |
|
|
879 | } |
|
|
880 | } |
888 | } |
881 | } |
889 | } |
882 | |
890 | |
883 | scr_add_lines (buf, nlines, str - buf); |
891 | if (str >= buf + BUFSIZ) |
884 | |
|
|
885 | /* |
|
|
886 | * If there have been a lot of new lines, then update the screen |
|
|
887 | * What the heck I'll cheat and only refresh less than every page-full. |
|
|
888 | * the number of pages between refreshes is refresh_limit, which |
|
|
889 | * is incremented here because we must be doing flat-out scrolling. |
|
|
890 | * |
|
|
891 | * refreshing should be correct for small scrolls, because of the |
|
|
892 | * time-out |
|
|
893 | */ |
|
|
894 | if (refreshnow) |
|
|
895 | { |
892 | { |
896 | if ((Options & Opt_jumpScroll) && refresh_limit < REFRESH_PERIOD) |
893 | ch = NOCHAR; |
897 | refresh_limit++; |
894 | break; |
898 | |
|
|
899 | scr_refresh (refresh_type); |
|
|
900 | } |
895 | } |
901 | |
|
|
902 | } |
|
|
903 | else |
|
|
904 | { |
|
|
905 | switch (ch) |
|
|
906 | { |
|
|
907 | default: |
|
|
908 | process_nonprinting (ch); |
|
|
909 | break; |
|
|
910 | case C0_ESC: /* escape char */ |
|
|
911 | process_escape_seq (); |
|
|
912 | break; |
|
|
913 | /*case 0x9b: */ /* CSI */ |
|
|
914 | /* process_csi_seq (); */ |
|
|
915 | } |
|
|
916 | |
|
|
917 | ch = NOCHAR; |
|
|
918 | } |
896 | } |
919 | } |
897 | } |
|
|
898 | |
|
|
899 | scr_add_lines (buf, nlines, str - buf); |
|
|
900 | |
|
|
901 | /* |
|
|
902 | * If there have been a lot of new lines, then update the screen |
|
|
903 | * What the heck I'll cheat and only refresh less than every page-full. |
|
|
904 | * the number of pages between refreshes is refresh_limit, which |
|
|
905 | * is incremented here because we must be doing flat-out scrolling. |
|
|
906 | * |
|
|
907 | * refreshing should be correct for small scrolls, because of the |
|
|
908 | * time-out |
|
|
909 | */ |
|
|
910 | if (refreshnow) |
|
|
911 | { |
|
|
912 | if ((Options & Opt_jumpScroll) && refresh_limit < REFRESH_PERIOD) |
|
|
913 | refresh_limit++; |
|
|
914 | |
|
|
915 | scr_refresh (refresh_type); |
|
|
916 | } |
|
|
917 | |
|
|
918 | } |
|
|
919 | else |
920 | } |
920 | { |
|
|
921 | switch (ch) |
|
|
922 | { |
|
|
923 | default: |
|
|
924 | process_nonprinting (ch); |
|
|
925 | break; |
|
|
926 | case C0_ESC: /* escape char */ |
|
|
927 | process_escape_seq (); |
|
|
928 | break; |
|
|
929 | /*case 0x9b: */ /* CSI */ |
|
|
930 | /* process_csi_seq (); */ |
|
|
931 | } |
|
|
932 | |
|
|
933 | ch = NOCHAR; |
|
|
934 | } |
921 | } |
935 | } |
|
|
936 | |
|
|
937 | return flag; |
922 | } |
938 | } |
923 | |
939 | |
924 | // read the next character, currently handles UTF-8 |
940 | // read the next character, currently handles UTF-8 |
925 | // will probably handle all sorts of other stuff in the future |
941 | // will probably handle all sorts of other stuff in the future |
926 | uint32_t |
942 | uint32_t |