Commit adb4796796a073d782d0be3566f91e2489dc7065

Authored by ths
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 }
... ...