Changeset 7e0cb78 in mainline for uspace/app/bdsh/input.c


Ignore:
Timestamp:
2009-12-05T15:52:24Z (14 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
ed372da
Parents:
0b772f5
Message:

Basic selections in bdsh input module.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/bdsh/input.c

    r0b772f5 r7e0cb78  
    3636#include <io/keycode.h>
    3737#include <io/style.h>
     38#include <io/color.h>
    3839#include <vfs/vfs.h>
    3940#include <errno.h>
     
    5657        int nc;
    5758        int pos;
     59        int sel_start;
    5860
    5961        char *history[1 + HISTORY_LEN];
    6062        int hnum;
    6163        int hpos;
     64        bool done;
    6265} tinput_t;
    6366
     
    7073
    7174static char *tinput_read(tinput_t *ti);
     75static void tinput_sel_get_bounds(tinput_t *ti, int *sa, int *sb);
     76static bool tinput_sel_active(tinput_t *ti);
     77static void tinput_sel_delete(tinput_t *ti);
     78static void tinput_key_ctrl(tinput_t *ti, console_event_t *ev);
     79static void tinput_key_shift(tinput_t *ti, console_event_t *ev);
     80static void tinput_key_ctrl_shift(tinput_t *ti, console_event_t *ev);
     81static void tinput_key_unmod(tinput_t *ti, console_event_t *ev);
     82static void tinput_pre_seek(tinput_t *ti, bool shift_held);
     83static void tinput_post_seek(tinput_t *ti, bool shift_held);
    7284
    7385/* Tokenizes input from console, sees if the first word is a built-in, if so
     
    123135static void tinput_display_tail(tinput_t *ti, int start, int pad)
    124136{
    125         int i;
     137        static wchar_t dbuf[INPUT_MAX + 1];
     138        int sa, sb;
     139        int i, p;
     140
     141        tinput_sel_get_bounds(ti, &sa, &sb);
    126142
    127143        console_goto(fphone(stdout), (ti->col0 + start) % ti->con_cols,
    128144            ti->row0 + (ti->col0 + start) / ti->con_cols);
    129         printf("%ls", ti->buffer + start);
     145        console_set_color(fphone(stdout), COLOR_BLACK, COLOR_WHITE, 0);
     146
     147        p = start;
     148        if (p < sa) {
     149                memcpy(dbuf, ti->buffer + p, (sa - p) * sizeof(wchar_t));
     150                dbuf[sa - p] = '\0';
     151                printf("%ls", dbuf);
     152                p = sa;
     153        }
     154
     155        if (p < sb) {
     156                fflush(stdout);
     157                console_set_color(fphone(stdout), COLOR_BLACK, COLOR_RED, 0);
     158                memcpy(dbuf, ti->buffer + p,
     159                    (sb - p) * sizeof(wchar_t));
     160                dbuf[sb - p] = '\0';
     161                printf("%ls", dbuf);
     162                p = sb;
     163        }
     164
     165        fflush(stdout);
     166        console_set_color(fphone(stdout), COLOR_BLACK, COLOR_WHITE, 0);
     167
     168        if (p < ti->nc) {
     169                memcpy(dbuf, ti->buffer + p,
     170                    (ti->nc - p) * sizeof(wchar_t));
     171                dbuf[ti->nc - p] = '\0';
     172                printf("%ls", dbuf);
     173        }
     174
    130175        for (i = 0; i < pad; ++i)
    131176                putchar(' ');
     
    180225        ti->nc += 1;
    181226        ti->buffer[ti->nc] = '\0';
     227        ti->sel_start = ti->pos;
    182228
    183229        tinput_display_tail(ti, ti->pos - 1, 0);
     
    190236        int i;
    191237
     238        if (tinput_sel_active(ti)) {
     239                tinput_sel_delete(ti);
     240                return;
     241        }
     242 
    192243        if (ti->pos == 0)
    193244                return;
     
    198249        ti->nc -= 1;
    199250        ti->buffer[ti->nc] = '\0';
     251        ti->sel_start = ti->pos;
    200252
    201253        tinput_display_tail(ti, ti->pos, 1);
     
    205257static void tinput_delete(tinput_t *ti)
    206258{
     259        if (tinput_sel_active(ti)) {
     260                tinput_sel_delete(ti);
     261                return;
     262        }
     263
    207264        if (ti->pos == ti->nc)
    208265                return;
    209266
    210267        ti->pos += 1;
     268        ti->sel_start = ti->pos;
     269
    211270        tinput_backspace(ti);
    212271}
    213272
    214 static void tinput_seek_cell(tinput_t *ti, seek_dir_t dir)
    215 {
     273static void tinput_seek_cell(tinput_t *ti, seek_dir_t dir, bool shift_held)
     274{
     275        tinput_pre_seek(ti, shift_held);
     276
    216277        if (dir == seek_forward) {
    217278                if (ti->pos < ti->nc)
     
    222283        }
    223284
    224         tinput_position_caret(ti);
    225 }
    226 
    227 static void tinput_seek_word(tinput_t *ti, seek_dir_t dir)
    228 {
     285        tinput_post_seek(ti, shift_held);
     286}
     287
     288static void tinput_seek_word(tinput_t *ti, seek_dir_t dir, bool shift_held)
     289{
     290        tinput_pre_seek(ti, shift_held);
     291
    229292        if (dir == seek_forward) {
    230293                if (ti->pos == ti->nc)
     
    258321        }
    259322
    260         tinput_position_caret(ti);
    261 }
    262 
    263 static void tinput_seek_vertical(tinput_t *ti, seek_dir_t dir)
    264 {
     323        tinput_post_seek(ti, shift_held);
     324}
     325
     326static void tinput_seek_vertical(tinput_t *ti, seek_dir_t dir, bool shift_held)
     327{
     328        tinput_pre_seek(ti, shift_held);
     329
    265330        if (dir == seek_forward) {
    266331                if (ti->pos + ti->con_cols <= ti->nc)
     
    271336        }
    272337
    273         tinput_position_caret(ti);
    274 }
    275 
    276 static void tinput_seek_max(tinput_t *ti, seek_dir_t dir)
    277 {
     338        tinput_post_seek(ti, shift_held);
     339}
     340
     341static void tinput_seek_max(tinput_t *ti, seek_dir_t dir, bool shift_held)
     342{
     343        tinput_pre_seek(ti, shift_held);
     344
    278345        if (dir == seek_backward)
    279346                ti->pos = 0;
     
    281348                ti->pos = ti->nc;
    282349
     350        tinput_post_seek(ti, shift_held);
     351}
     352
     353static void tinput_pre_seek(tinput_t *ti, bool shift_held)
     354{
     355        if (tinput_sel_active(ti) && !shift_held) {
     356                /* Unselect and redraw. */
     357                ti->sel_start = ti->pos;
     358                tinput_display_tail(ti, 0, 0);
     359                tinput_position_caret(ti);
     360        }
     361}
     362
     363static void tinput_post_seek(tinput_t *ti, bool shift_held)
     364{
     365        if (shift_held) {
     366                /* Selecting text. Need redraw. */
     367                tinput_display_tail(ti, 0, 0);
     368        } else {
     369                /* Shift not held. Keep selection empty. */
     370                ti->sel_start = ti->pos;
     371        }
    283372        tinput_position_caret(ti);
    284373}
     
    311400        ti->nc = wstr_length(ti->buffer);
    312401        ti->pos = ti->nc;
     402        ti->sel_start = ti->pos;
     403}
     404
     405static void tinput_sel_get_bounds(tinput_t *ti, int *sa, int *sb)
     406{
     407        if (ti->sel_start < ti->pos) {
     408                *sa = ti->sel_start;
     409                *sb = ti->pos;
     410        } else {
     411                *sa = ti->pos;
     412                *sb = ti->sel_start;
     413        }
     414}
     415
     416static bool tinput_sel_active(tinput_t *ti)
     417{
     418        return ti->sel_start != ti->pos;
     419}
     420
     421static void tinput_sel_delete(tinput_t *ti)
     422{
     423        int sa, sb;
     424
     425        tinput_sel_get_bounds(ti, &sa, &sb);
     426        if (sa == sb)
     427                return;
     428
     429        memmove(ti->buffer + sa, ti->buffer + sb,
     430            (ti->nc - sb) * sizeof(wchar_t));
     431        ti->pos = ti->sel_start = sa;
     432        ti->nc -= (sb - sa);
     433        ti->buffer[ti->nc] = '\0';
     434
     435        tinput_display_tail(ti, sa, sb - sa);
     436        tinput_position_caret(ti);
    313437}
    314438
     
    356480                return NULL;
    357481
    358         ti->pos = 0;
     482        ti->pos = ti->sel_start = 0;
    359483        ti->nc = 0;
    360484        ti->buffer[0] = '\0';
    361 
    362         while (true) {
     485        ti->done = false;
     486
     487        while (!ti->done) {
    363488                fflush(stdout);
    364489                if (!console_get_event(fphone(stdin), &ev))
    365490                        return NULL;
    366                
     491
    367492                if (ev.type != KEY_PRESS)
    368493                        continue;
     
    370495                if ((ev.mods & KM_CTRL) != 0 &&
    371496                    (ev.mods & (KM_ALT | KM_SHIFT)) == 0) {
    372                         switch (ev.key) {
    373                         case KC_LEFT:
    374                                 tinput_seek_word(ti, seek_backward);
    375                                 break;
    376                         case KC_RIGHT:
    377                                 tinput_seek_word(ti, seek_forward);
    378                                 break;
    379                         case KC_UP:
    380                                 tinput_seek_vertical(ti, seek_backward);
    381                                 break;
    382                         case KC_DOWN:
    383                                 tinput_seek_vertical(ti, seek_forward);
    384                                 break;
    385                         }
     497                        tinput_key_ctrl(ti, &ev);
    386498                }
    387499
     500                if ((ev.mods & KM_SHIFT) != 0 &&
     501                    (ev.mods & (KM_CTRL | KM_ALT)) == 0) {
     502                        tinput_key_shift(ti, &ev);
     503                }
     504
     505                if ((ev.mods & KM_CTRL) != 0 &&
     506                    (ev.mods & KM_SHIFT) != 0 &&
     507                    (ev.mods & KM_ALT) == 0) {
     508                        tinput_key_ctrl_shift(ti, &ev);
     509                }
     510
    388511                if ((ev.mods & (KM_CTRL | KM_ALT | KM_SHIFT)) == 0) {
    389                         switch (ev.key) {
    390                         case KC_ENTER:
    391                         case KC_NENTER:
    392                                 goto done;
    393                         case KC_BACKSPACE:
    394                                 tinput_backspace(ti);
    395                                 break;
    396                         case KC_DELETE:
    397                                 tinput_delete(ti);
    398                                 break;
    399                         case KC_LEFT:
    400                                 tinput_seek_cell(ti, seek_backward);
    401                                 break;
    402                         case KC_RIGHT:
    403                                 tinput_seek_cell(ti, seek_forward);
    404                                 break;
    405                         case KC_HOME:
    406                                 tinput_seek_max(ti, seek_backward);
    407                                 break;
    408                         case KC_END:
    409                                 tinput_seek_max(ti, seek_forward);
    410                                 break;
    411                         case KC_UP:
    412                                 tinput_history_seek(ti, +1);
    413                                 break;
    414                         case KC_DOWN:
    415                                 tinput_history_seek(ti, -1);
    416                                 break;
    417                         }
     512                        tinput_key_unmod(ti, &ev);
    418513                }
    419514
    420515                if (ev.c >= ' ') {
     516                        tinput_sel_delete(ti);
    421517                        tinput_insert_char(ti, ev.c);
    422518                }
    423519        }
    424520
    425 done:
    426521        ti->pos = ti->nc;
    427522        tinput_position_caret(ti);
     
    436531        return str;
    437532}
     533
     534static void tinput_key_ctrl(tinput_t *ti, console_event_t *ev)
     535{
     536        switch (ev->key) {
     537        case KC_LEFT:
     538                tinput_seek_word(ti, seek_backward, false);
     539                break;
     540        case KC_RIGHT:
     541                tinput_seek_word(ti, seek_forward, false);
     542                break;
     543        case KC_UP:
     544                tinput_seek_vertical(ti, seek_backward, false);
     545                break;
     546        case KC_DOWN:
     547                tinput_seek_vertical(ti, seek_forward, false);
     548                break;
     549        default:
     550                break;
     551        }
     552}
     553
     554static void tinput_key_ctrl_shift(tinput_t *ti, console_event_t *ev)
     555{
     556        switch (ev->key) {
     557        case KC_LEFT:
     558                tinput_seek_word(ti, seek_backward, true);
     559                break;
     560        case KC_RIGHT:
     561                tinput_seek_word(ti, seek_forward, true);
     562                break;
     563        case KC_UP:
     564                tinput_seek_vertical(ti, seek_backward, true);
     565                break;
     566        case KC_DOWN:
     567                tinput_seek_vertical(ti, seek_forward, true);
     568                break;
     569        default:
     570                break;
     571        }
     572}
     573
     574static void tinput_key_shift(tinput_t *ti, console_event_t *ev)
     575{
     576        switch (ev->key) {
     577        case KC_LEFT:
     578                tinput_seek_cell(ti, seek_backward, true);
     579                break;
     580        case KC_RIGHT:
     581                tinput_seek_cell(ti, seek_forward, true);
     582                break;
     583        case KC_UP:
     584                tinput_seek_vertical(ti, seek_backward, true);
     585                break;
     586        case KC_DOWN:
     587                tinput_seek_vertical(ti, seek_forward, true);
     588                break;
     589        case KC_HOME:
     590                tinput_seek_max(ti, seek_backward, true);
     591                break;
     592        case KC_END:
     593                tinput_seek_max(ti, seek_forward, true);
     594                break;
     595        default:
     596                break;
     597        }
     598}
     599
     600static void tinput_key_unmod(tinput_t *ti, console_event_t *ev)
     601{
     602        switch (ev->key) {
     603        case KC_ENTER:
     604        case KC_NENTER:
     605                ti->done = true;
     606                break;
     607        case KC_BACKSPACE:
     608                tinput_backspace(ti);
     609                break;
     610        case KC_DELETE:
     611                tinput_delete(ti);
     612                break;
     613        case KC_LEFT:
     614                tinput_seek_cell(ti, seek_backward, false);
     615                break;
     616        case KC_RIGHT:
     617                tinput_seek_cell(ti, seek_forward, false);
     618                break;
     619        case KC_HOME:
     620                tinput_seek_max(ti, seek_backward, false);
     621                break;
     622        case KC_END:
     623                tinput_seek_max(ti, seek_forward, false);
     624                break;
     625        case KC_UP:
     626                tinput_history_seek(ti, +1);
     627                break;
     628        case KC_DOWN:
     629                tinput_history_seek(ti, -1);
     630                break;
     631        default:
     632                break;
     633        }
     634}
     635
    438636
    439637void get_input(cliuser_t *usr)
Note: See TracChangeset for help on using the changeset viewer.