Commit adb4796796a073d782d0be3566f91e2489dc7065
1 parent
dabd98dd
Improved console handling, thanks Stefan Weil.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2322 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
155 additions
and
18 deletions
console.c
| ... | ... | @@ -121,6 +121,7 @@ struct TextConsole { |
| 121 | 121 | int total_height; |
| 122 | 122 | int backscroll_height; |
| 123 | 123 | int x, y; |
| 124 | + int x_saved, y_saved; | |
| 124 | 125 | int y_displayed; |
| 125 | 126 | int y_base; |
| 126 | 127 | TextAttributes t_attrib_default; /* default text attributes */ |
| ... | ... | @@ -147,7 +148,7 @@ static int nb_consoles = 0; |
| 147 | 148 | |
| 148 | 149 | void vga_hw_update(void) |
| 149 | 150 | { |
| 150 | - if (active_console->hw_update) | |
| 151 | + if (active_console && active_console->hw_update) | |
| 151 | 152 | active_console->hw_update(active_console->hw); |
| 152 | 153 | } |
| 153 | 154 | |
| ... | ... | @@ -659,10 +660,6 @@ static void console_handle_escape(TextConsole *s) |
| 659 | 660 | { |
| 660 | 661 | int i; |
| 661 | 662 | |
| 662 | - if (s->nb_esc_params == 0) { /* ESC[m sets all attributes to default */ | |
| 663 | - s->t_attrib = s->t_attrib_default; | |
| 664 | - return; | |
| 665 | - } | |
| 666 | 663 | for (i=0; i<s->nb_esc_params; i++) { |
| 667 | 664 | switch (s->esc_params[i]) { |
| 668 | 665 | case 0: /* reset all console attributes to default */ |
| ... | ... | @@ -752,10 +749,21 @@ static void console_handle_escape(TextConsole *s) |
| 752 | 749 | } |
| 753 | 750 | } |
| 754 | 751 | |
| 752 | +static void console_clear_xy(TextConsole *s, int x, int y) | |
| 753 | +{ | |
| 754 | + int y1 = (s->y_base + y) % s->total_height; | |
| 755 | + TextCell *c = &s->cells[y1 * s->width + x]; | |
| 756 | + c->ch = ' '; | |
| 757 | + c->t_attrib = s->t_attrib_default; | |
| 758 | + c++; | |
| 759 | + update_xy(s, x, y); | |
| 760 | +} | |
| 761 | + | |
| 755 | 762 | static void console_putchar(TextConsole *s, int ch) |
| 756 | 763 | { |
| 757 | 764 | TextCell *c; |
| 758 | - int y1, i, x; | |
| 765 | + int y1, i; | |
| 766 | + int x, y; | |
| 759 | 767 | |
| 760 | 768 | switch(s->state) { |
| 761 | 769 | case TTY_STATE_NORM: |
| ... | ... | @@ -781,20 +789,31 @@ static void console_putchar(TextConsole *s, int ch) |
| 781 | 789 | case '\a': /* alert aka. bell */ |
| 782 | 790 | /* TODO: has to be implemented */ |
| 783 | 791 | break; |
| 792 | + case 14: | |
| 793 | + /* SI (shift in), character set 0 (ignored) */ | |
| 794 | + break; | |
| 795 | + case 15: | |
| 796 | + /* SO (shift out), character set 1 (ignored) */ | |
| 797 | + break; | |
| 784 | 798 | case 27: /* esc (introducing an escape sequence) */ |
| 785 | 799 | s->state = TTY_STATE_ESC; |
| 786 | 800 | break; |
| 787 | 801 | default: |
| 802 | + if (s->x >= s->width - 1) { | |
| 803 | + break; | |
| 804 | + } | |
| 788 | 805 | y1 = (s->y_base + s->y) % s->total_height; |
| 789 | 806 | c = &s->cells[y1 * s->width + s->x]; |
| 790 | 807 | c->ch = ch; |
| 791 | 808 | c->t_attrib = s->t_attrib; |
| 792 | 809 | update_xy(s, s->x, s->y); |
| 793 | 810 | s->x++; |
| 811 | +#if 0 /* line wrap disabled */ | |
| 794 | 812 | if (s->x >= s->width) { |
| 795 | 813 | s->x = 0; |
| 796 | 814 | console_put_lf(s); |
| 797 | 815 | } |
| 816 | +#endif | |
| 798 | 817 | break; |
| 799 | 818 | } |
| 800 | 819 | break; |
| ... | ... | @@ -818,32 +837,150 @@ static void console_putchar(TextConsole *s, int ch) |
| 818 | 837 | s->nb_esc_params++; |
| 819 | 838 | if (ch == ';') |
| 820 | 839 | break; |
| 840 | +#ifdef DEBUG_CONSOLE | |
| 841 | + fprintf(stderr, "escape sequence CSI%d;%d%c, %d parameters\n", | |
| 842 | + s->esc_params[0], s->esc_params[1], ch, s->nb_esc_params); | |
| 843 | +#endif | |
| 821 | 844 | s->state = TTY_STATE_NORM; |
| 822 | 845 | switch(ch) { |
| 823 | - case 'D': | |
| 824 | - if (s->x > 0) | |
| 825 | - s->x--; | |
| 846 | + case 'A': | |
| 847 | + /* move cursor up */ | |
| 848 | + if (s->esc_params[0] == 0) { | |
| 849 | + s->esc_params[0] = 1; | |
| 850 | + } | |
| 851 | + s->y -= s->esc_params[0]; | |
| 852 | + if (s->y < 0) { | |
| 853 | + s->y = 0; | |
| 854 | + } | |
| 855 | + break; | |
| 856 | + case 'B': | |
| 857 | + /* move cursor down */ | |
| 858 | + if (s->esc_params[0] == 0) { | |
| 859 | + s->esc_params[0] = 1; | |
| 860 | + } | |
| 861 | + s->y += s->esc_params[0]; | |
| 862 | + if (s->y >= s->height) { | |
| 863 | + s->y = s->height - 1; | |
| 864 | + } | |
| 826 | 865 | break; |
| 827 | 866 | case 'C': |
| 828 | - if (s->x < (s->width - 1)) | |
| 829 | - s->x++; | |
| 867 | + /* move cursor right */ | |
| 868 | + if (s->esc_params[0] == 0) { | |
| 869 | + s->esc_params[0] = 1; | |
| 870 | + } | |
| 871 | + s->x += s->esc_params[0]; | |
| 872 | + if (s->x >= s->width) { | |
| 873 | + s->x = s->width - 1; | |
| 874 | + } | |
| 830 | 875 | break; |
| 876 | + case 'D': | |
| 877 | + /* move cursor left */ | |
| 878 | + if (s->esc_params[0] == 0) { | |
| 879 | + s->esc_params[0] = 1; | |
| 880 | + } | |
| 881 | + s->x -= s->esc_params[0]; | |
| 882 | + if (s->x < 0) { | |
| 883 | + s->x = 0; | |
| 884 | + } | |
| 885 | + break; | |
| 886 | + case 'G': | |
| 887 | + /* move cursor to column */ | |
| 888 | + s->x = s->esc_params[0] - 1; | |
| 889 | + if (s->x < 0) { | |
| 890 | + s->x = 0; | |
| 891 | + } | |
| 892 | + break; | |
| 893 | + case 'f': | |
| 894 | + case 'H': | |
| 895 | + /* move cursor to row, column */ | |
| 896 | + s->x = s->esc_params[1] - 1; | |
| 897 | + if (s->x < 0) { | |
| 898 | + s->x = 0; | |
| 899 | + } | |
| 900 | + s->y = s->esc_params[0] - 1; | |
| 901 | + if (s->y < 0) { | |
| 902 | + s->y = 0; | |
| 903 | + } | |
| 904 | + break; | |
| 905 | + case 'J': | |
| 906 | + switch (s->esc_params[0]) { | |
| 907 | + case 0: | |
| 908 | + /* clear to end of screen */ | |
| 909 | + for (y = s->y; y < s->height; y++) { | |
| 910 | + for (x = 0; x < s->width; x++) { | |
| 911 | + if (y == s->y && x < s->x) { | |
| 912 | + continue; | |
| 913 | + } | |
| 914 | + console_clear_xy(s, x, y); | |
| 915 | + } | |
| 916 | + } | |
| 917 | + break; | |
| 918 | + case 1: | |
| 919 | + /* clear from beginning of screen */ | |
| 920 | + for (y = 0; y <= s->y; y++) { | |
| 921 | + for (x = 0; x < s->width; x++) { | |
| 922 | + if (y == s->y && x > s->x) { | |
| 923 | + break; | |
| 924 | + } | |
| 925 | + console_clear_xy(s, x, y); | |
| 926 | + } | |
| 927 | + } | |
| 928 | + break; | |
| 929 | + case 2: | |
| 930 | + /* clear entire screen */ | |
| 931 | + for (y = 0; y <= s->height; y++) { | |
| 932 | + for (x = 0; x < s->width; x++) { | |
| 933 | + console_clear_xy(s, x, y); | |
| 934 | + } | |
| 935 | + } | |
| 936 | + break; | |
| 937 | + } | |
| 831 | 938 | case 'K': |
| 939 | + switch (s->esc_params[0]) { | |
| 940 | + case 0: | |
| 832 | 941 | /* clear to eol */ |
| 833 | - y1 = (s->y_base + s->y) % s->total_height; | |
| 834 | 942 | for(x = s->x; x < s->width; x++) { |
| 835 | - c = &s->cells[y1 * s->width + x]; | |
| 836 | - c->ch = ' '; | |
| 837 | - c->t_attrib = s->t_attrib_default; | |
| 838 | - c++; | |
| 839 | - update_xy(s, x, s->y); | |
| 943 | + console_clear_xy(s, x, s->y); | |
| 840 | 944 | } |
| 841 | 945 | break; |
| 842 | - default: | |
| 946 | + case 1: | |
| 947 | + /* clear from beginning of line */ | |
| 948 | + for (x = 0; x <= s->x; x++) { | |
| 949 | + console_clear_xy(s, x, s->y); | |
| 950 | + } | |
| 951 | + break; | |
| 952 | + case 2: | |
| 953 | + /* clear entire line */ | |
| 954 | + for(x = 0; x < s->width; x++) { | |
| 955 | + console_clear_xy(s, x, s->y); | |
| 956 | + } | |
| 843 | 957 | break; |
| 844 | 958 | } |
| 959 | + break; | |
| 960 | + case 'm': | |
| 845 | 961 | console_handle_escape(s); |
| 846 | 962 | break; |
| 963 | + case 'n': | |
| 964 | + /* report cursor position */ | |
| 965 | + /* TODO: send ESC[row;colR */ | |
| 966 | + break; | |
| 967 | + case 's': | |
| 968 | + /* save cursor position */ | |
| 969 | + s->x_saved = s->x; | |
| 970 | + s->y_saved = s->y; | |
| 971 | + break; | |
| 972 | + case 'u': | |
| 973 | + /* restore cursor position */ | |
| 974 | + s->x = s->x_saved; | |
| 975 | + s->y = s->y_saved; | |
| 976 | + break; | |
| 977 | + default: | |
| 978 | +#ifdef DEBUG_CONSOLE | |
| 979 | + fprintf(stderr, "unhandled escape character '%c'\n", ch); | |
| 980 | +#endif | |
| 981 | + break; | |
| 982 | + } | |
| 983 | + break; | |
| 847 | 984 | } |
| 848 | 985 | } |
| 849 | 986 | } | ... | ... |