Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/clui/src/tinput.c

    r899bdfd r7b907a0a  
    113113static void tinput_display_tail(tinput_t *ti, size_t start, size_t pad)
    114114{
    115         char32_t stash;
     115        char32_t *dbuf = malloc((INPUT_MAX_SIZE + 1) * sizeof(char32_t));
     116        if (!dbuf)
     117                return;
     118
    116119        size_t sa;
    117120        size_t sb;
    118121        tinput_sel_get_bounds(ti, &sa, &sb);
    119         assert(sa <= sb);
    120122
    121123        tinput_console_set_lpos(ti, ti->text_coord + start);
    122124        console_set_style(ti->console, STYLE_NORMAL);
    123125
    124         sa = max(start, sa);
    125         sb = max(start, sb);
    126 
    127         if (start < sa) {
    128                 stash = ti->buffer[sa];
    129                 ti->buffer[sa] = L'\0';
    130                 printf("%ls", &ti->buffer[start]);
    131                 ti->buffer[sa] = stash;
    132         }
    133 
    134         if (sa < sb) {
     126        size_t p = start;
     127        if (p < sa) {
     128                memcpy(dbuf, ti->buffer + p, (sa - p) * sizeof(char32_t));
     129                dbuf[sa - p] = '\0';
     130                printf("%ls", dbuf);
     131                p = sa;
     132        }
     133
     134        if (p < sb) {
    135135                console_flush(ti->console);
    136136                console_set_style(ti->console, STYLE_SELECTED);
    137137
    138                 stash = ti->buffer[sb];
    139                 ti->buffer[sb] = L'\0';
    140                 printf("%ls", &ti->buffer[sa]);
    141                 ti->buffer[sb] = stash;
    142 
    143                 console_flush(ti->console);
    144                 console_set_style(ti->console, STYLE_NORMAL);
    145         }
    146 
    147         if (sb < ti->nc) {
    148                 ti->buffer[ti->nc] = L'\0';
    149                 printf("%ls", &ti->buffer[sb]);
    150         }
    151 
    152         for (; pad > 0; pad--)
     138                memcpy(dbuf, ti->buffer + p,
     139                    (sb - p) * sizeof(char32_t));
     140                dbuf[sb - p] = '\0';
     141                printf("%ls", dbuf);
     142                p = sb;
     143        }
     144
     145        console_flush(ti->console);
     146        console_set_style(ti->console, STYLE_NORMAL);
     147
     148        if (p < ti->nc) {
     149                memcpy(dbuf, ti->buffer + p,
     150                    (ti->nc - p) * sizeof(char32_t));
     151                dbuf[ti->nc - p] = '\0';
     152                printf("%ls", dbuf);
     153        }
     154
     155        for (p = 0; p < pad; p++)
    153156                putuchar(' ');
    154157
    155158        console_flush(ti->console);
     159
     160        free(dbuf);
    156161}
    157162
     
    213218        tinput_display_prompt(ti);
    214219
    215         /* The screen might have scrolled after printing the prompt */
     220        /* The screen might have scrolled after priting the prompt */
    216221        tinput_update_origin_coord(ti, ti->prompt_coord + str_width(ti->prompt));
    217222
     
    232237                return;
    233238
    234         /* Disallow text longer than 1 page for now. */
    235         unsigned prompt_len = ti->text_coord - ti->prompt_coord;
    236         if (prompt_len + ti->nc + 1 >= ti->con_cols * ti->con_rows)
    237                 return;
     239        unsigned new_width = LIN_TO_COL(ti, ti->text_coord) + ti->nc + 1;
     240        if (new_width % ti->con_cols == 0) {
     241                /* Advancing to new line. */
     242                sysarg_t new_height = (new_width / ti->con_cols) + 1;
     243                if (new_height >= ti->con_rows) {
     244                        /* Disallow text longer than 1 page for now. */
     245                        return;
     246                }
     247        }
    238248
    239249        size_t i;
     
    871881}
    872882
    873 static errno_t tinput_resize(tinput_t *ti)
    874 {
    875         assert(ti->prompt_coord % ti->con_cols == 0);
    876 
    877         errno_t rc = console_get_size(ti->console, &ti->con_cols, &ti->con_rows);
    878         if (rc != EOK)
    879                 return rc;
    880 
    881         sysarg_t col, row;
    882         rc = console_get_pos(ti->console, &col, &row);
    883         if (rc != EOK)
    884                 return rc;
    885 
    886         assert(ti->prompt_coord <= ti->text_coord);
    887         unsigned prompt_len = ti->text_coord - ti->prompt_coord;
    888 
    889         size_t new_caret_coord = row * ti->con_cols + col;
    890 
    891         if (prompt_len <= new_caret_coord && ti->pos <= new_caret_coord - prompt_len) {
    892                 ti->text_coord = new_caret_coord - ti->pos;
    893                 ti->prompt_coord = ti->text_coord - prompt_len;
    894 
    895                 unsigned prompt_col = ti->prompt_coord % ti->con_cols;
    896                 if (prompt_col != 0) {
    897                         /*
    898                          * Prompt doesn't seem to start at column 0, which means
    899                          * the console didn't reflow the line like we expected it to.
    900                          * Change offsets a bit to recover.
    901                          */
    902                         fprintf(stderr, "Unexpected prompt position after resize.\n");
    903                         ti->prompt_coord -= prompt_col;
    904                         ti->text_coord -= prompt_col;
    905 
    906                         console_cursor_visibility(ti->console, false);
    907                         tinput_display_prompt(ti);
    908                         tinput_display_tail(ti, 0, prompt_col);
    909                         tinput_position_caret(ti);
    910                         console_cursor_visibility(ti->console, true);
    911                 }
    912 
    913                 assert(ti->prompt_coord % ti->con_cols == 0);
    914         } else {
    915                 /*
    916                  * Overflown screen.
    917                  * We will just trim the buffer and rewrite everything.
    918                  */
    919                 console_clear(ti->console);
    920 
    921                 ti->nc = min(ti->nc, ti->con_cols * ti->con_rows - prompt_len - 1);
    922                 ti->pos = min(ti->pos, ti->nc);
    923                 ti->sel_start = min(ti->sel_start, ti->nc);
    924 
    925                 ti->prompt_coord = 0;
    926                 ti->text_coord = prompt_len;
    927 
    928                 console_cursor_visibility(ti->console, false);
    929                 tinput_display_prompt(ti);
    930                 tinput_display_tail(ti, 0, 0);
    931                 tinput_position_caret(ti);
    932                 console_cursor_visibility(ti->console, true);
    933         }
    934 
    935         assert(ti->nc + ti->text_coord < ti->con_cols * ti->con_rows);
    936 
    937         return EOK;
    938 }
    939 
    940883/** Read in one line of input with initial text provided.
    941884 *
     
    984927                        tinput_pos(ti, &ev.ev.pos);
    985928                        break;
    986                 case CEV_RESIZE:
    987                         tinput_resize(ti);
    988                         break;
    989929                }
    990930        }
Note: See TracChangeset for help on using the changeset viewer.