Changes in / [034bf0e:65c1778] in mainline


Ignore:
Location:
uspace
Files:
2 deleted
4 edited

Legend:

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

    r034bf0e r65c1778  
    3636#include <io/keycode.h>
    3737#include <io/style.h>
    38 #include <io/color.h>
    3938#include <vfs/vfs.h>
    40 #include <clipboard.h>
    41 #include <macros.h>
    4239#include <errno.h>
    4340#include <assert.h>
     
    5350#define HISTORY_LEN 10
    5451
    55 /** Text input field. */
    5652typedef struct {
    57         /** Buffer holding text currently being edited */
    58         wchar_t buffer[INPUT_MAX + 1];
    59         /** Screen coordinates of the top-left corner of the text field */
     53        wchar_t buffer[INPUT_MAX];
    6054        int col0, row0;
    61         /** Screen dimensions */
    6255        int con_cols, con_rows;
    63         /** Number of characters in @c buffer */
    6456        int nc;
    65         /** Caret position within buffer */
    6657        int pos;
    67         /** Selection mark position within buffer */
    68         int sel_start;
    69 
    70         /** History (dynamically allocated strings) */
     58
    7159        char *history[1 + HISTORY_LEN];
    72         /** Number of entries in @c history, not counting [0] */
    7360        int hnum;
    74         /** Current position in history */
    7561        int hpos;
    76         /** Exit flag */
    77         bool done;
    7862} tinput_t;
    7963
    80 /** Seek direction */
    8164typedef enum {
    8265        seek_backward = -1,
     
    8770
    8871static char *tinput_read(tinput_t *ti);
    89 static void tinput_insert_string(tinput_t *ti, const char *str);
    90 static void tinput_sel_get_bounds(tinput_t *ti, int *sa, int *sb);
    91 static bool tinput_sel_active(tinput_t *ti);
    92 static void tinput_sel_all(tinput_t *ti);
    93 static void tinput_sel_delete(tinput_t *ti);
    94 static void tinput_key_ctrl(tinput_t *ti, console_event_t *ev);
    95 static void tinput_key_shift(tinput_t *ti, console_event_t *ev);
    96 static void tinput_key_ctrl_shift(tinput_t *ti, console_event_t *ev);
    97 static void tinput_key_unmod(tinput_t *ti, console_event_t *ev);
    98 static void tinput_pre_seek(tinput_t *ti, bool shift_held);
    99 static void tinput_post_seek(tinput_t *ti, bool shift_held);
    10072
    10173/* Tokenizes input from console, sees if the first word is a built-in, if so
     
    151123static void tinput_display_tail(tinput_t *ti, int start, int pad)
    152124{
    153         static wchar_t dbuf[INPUT_MAX + 1];
    154         int sa, sb;
    155         int i, p;
    156 
    157         tinput_sel_get_bounds(ti, &sa, &sb);
     125        int i;
    158126
    159127        console_goto(fphone(stdout), (ti->col0 + start) % ti->con_cols,
    160128            ti->row0 + (ti->col0 + start) / ti->con_cols);
    161         console_set_color(fphone(stdout), COLOR_BLACK, COLOR_WHITE, 0);
    162 
    163         p = start;
    164         if (p < sa) {
    165                 memcpy(dbuf, ti->buffer + p, (sa - p) * sizeof(wchar_t));
    166                 dbuf[sa - p] = '\0';
    167                 printf("%ls", dbuf);
    168                 p = sa;
    169         }
    170 
    171         if (p < sb) {
    172                 fflush(stdout);
    173                 console_set_color(fphone(stdout), COLOR_BLACK, COLOR_RED, 0);
    174                 memcpy(dbuf, ti->buffer + p,
    175                     (sb - p) * sizeof(wchar_t));
    176                 dbuf[sb - p] = '\0';
    177                 printf("%ls", dbuf);
    178                 p = sb;
    179         }
    180 
    181         fflush(stdout);
    182         console_set_color(fphone(stdout), COLOR_BLACK, COLOR_WHITE, 0);
    183 
    184         if (p < ti->nc) {
    185                 memcpy(dbuf, ti->buffer + p,
    186                     (ti->nc - p) * sizeof(wchar_t));
    187                 dbuf[ti->nc - p] = '\0';
    188                 printf("%ls", dbuf);
    189         }
    190 
     129        printf("%ls", ti->buffer + start);
    191130        for (i = 0; i < pad; ++i)
    192131                putchar(' ');
     
    212151        width = ti->col0 + ti->nc;
    213152        rows = (width / ti->con_cols) + 1;
    214 
     153 
    215154        /* Update row0 if the screen scrolled. */
    216155        if (ti->row0 + rows > ti->con_rows)
     
    241180        ti->nc += 1;
    242181        ti->buffer[ti->nc] = '\0';
    243         ti->sel_start = ti->pos;
    244182
    245183        tinput_display_tail(ti, ti->pos - 1, 0);
     
    248186}
    249187
    250 static void tinput_insert_string(tinput_t *ti, const char *str)
     188static void tinput_backspace(tinput_t *ti)
    251189{
    252190        int i;
    253         int new_width, new_height;
    254         int ilen;
    255         wchar_t c;
    256         size_t off;
    257 
    258         ilen = min((ssize_t) str_length(str), INPUT_MAX - ti->nc);
    259         if (ilen == 0)
    260                 return;
    261 
    262         new_width = ti->col0 + ti->nc + ilen;
    263         new_height = (new_width / ti->con_cols) + 1;
    264         if (new_height >= ti->con_rows)
    265                 return; /* Disallow text longer than 1 page for now. */
    266 
    267         for (i = ti->nc - 1; i >= ti->pos; --i)
    268                 ti->buffer[i + ilen] = ti->buffer[i];
    269 
    270         off = 0; i = 0;
    271         while (i < ilen) {
    272                 c = str_decode(str, &off, STR_NO_LIMIT);
    273                 if (c == '\0')
    274                         break;
    275 
    276                 /* Filter out non-printable chars. */
    277                 if (c < 32)
    278                         c = 32;
    279 
    280                 ti->buffer[ti->pos + i] = c;
    281                 ++i;
    282         }
    283 
    284         ti->pos += ilen;
    285         ti->nc += ilen;
    286         ti->buffer[ti->nc] = '\0';
    287         ti->sel_start = ti->pos;
    288 
    289         tinput_display_tail(ti, ti->pos - ilen, 0);
    290         tinput_update_origin(ti);
    291         tinput_position_caret(ti);
    292 }
    293 
    294 static void tinput_backspace(tinput_t *ti)
    295 {
    296         int i;
    297 
    298         if (tinput_sel_active(ti)) {
    299                 tinput_sel_delete(ti);
    300                 return;
    301         }
    302191
    303192        if (ti->pos == 0)
     
    309198        ti->nc -= 1;
    310199        ti->buffer[ti->nc] = '\0';
    311         ti->sel_start = ti->pos;
    312200
    313201        tinput_display_tail(ti, ti->pos, 1);
     
    317205static void tinput_delete(tinput_t *ti)
    318206{
    319         if (tinput_sel_active(ti)) {
    320                 tinput_sel_delete(ti);
    321                 return;
    322         }
    323 
    324207        if (ti->pos == ti->nc)
    325208                return;
    326209
    327210        ti->pos += 1;
    328         ti->sel_start = ti->pos;
    329 
    330211        tinput_backspace(ti);
    331212}
    332213
    333 static void tinput_seek_cell(tinput_t *ti, seek_dir_t dir, bool shift_held)
    334 {
    335         tinput_pre_seek(ti, shift_held);
    336 
     214static void tinput_seek_cell(tinput_t *ti, seek_dir_t dir)
     215{
    337216        if (dir == seek_forward) {
    338217                if (ti->pos < ti->nc)
     
    343222        }
    344223
    345         tinput_post_seek(ti, shift_held);
    346 }
    347 
    348 static void tinput_seek_word(tinput_t *ti, seek_dir_t dir, bool shift_held)
    349 {
    350         tinput_pre_seek(ti, shift_held);
    351 
     224        tinput_position_caret(ti);
     225}
     226
     227static void tinput_seek_word(tinput_t *ti, seek_dir_t dir)
     228{
    352229        if (dir == seek_forward) {
    353230                if (ti->pos == ti->nc)
     
    381258        }
    382259
    383         tinput_post_seek(ti, shift_held);
    384 }
    385 
    386 static void tinput_seek_vertical(tinput_t *ti, seek_dir_t dir, bool shift_held)
    387 {
    388         tinput_pre_seek(ti, shift_held);
    389 
     260        tinput_position_caret(ti);
     261}
     262
     263static void tinput_seek_vertical(tinput_t *ti, seek_dir_t dir)
     264{
    390265        if (dir == seek_forward) {
    391266                if (ti->pos + ti->con_cols <= ti->nc)
     
    396271        }
    397272
    398         tinput_post_seek(ti, shift_held);
    399 }
    400 
    401 static void tinput_seek_max(tinput_t *ti, seek_dir_t dir, bool shift_held)
    402 {
    403         tinput_pre_seek(ti, shift_held);
    404 
     273        tinput_position_caret(ti);
     274}
     275
     276static void tinput_seek_max(tinput_t *ti, seek_dir_t dir)
     277{
    405278        if (dir == seek_backward)
    406279                ti->pos = 0;
     
    408281                ti->pos = ti->nc;
    409282
    410         tinput_post_seek(ti, shift_held);
    411 }
    412 
    413 static void tinput_pre_seek(tinput_t *ti, bool shift_held)
    414 {
    415         if (tinput_sel_active(ti) && !shift_held) {
    416                 /* Unselect and redraw. */
    417                 ti->sel_start = ti->pos;
    418                 tinput_display_tail(ti, 0, 0);
    419                 tinput_position_caret(ti);
    420         }
    421 }
    422 
    423 static void tinput_post_seek(tinput_t *ti, bool shift_held)
    424 {
    425         if (shift_held) {
    426                 /* Selecting text. Need redraw. */
    427                 tinput_display_tail(ti, 0, 0);
    428         } else {
    429                 /* Shift not held. Keep selection empty. */
    430                 ti->sel_start = ti->pos;
    431         }
    432283        tinput_position_caret(ti);
    433284}
     
    460311        ti->nc = wstr_length(ti->buffer);
    461312        ti->pos = ti->nc;
    462         ti->sel_start = ti->pos;
    463 }
    464 
    465 static void tinput_sel_get_bounds(tinput_t *ti, int *sa, int *sb)
    466 {
    467         if (ti->sel_start < ti->pos) {
    468                 *sa = ti->sel_start;
    469                 *sb = ti->pos;
    470         } else {
    471                 *sa = ti->pos;
    472                 *sb = ti->sel_start;
    473         }
    474 }
    475 
    476 static bool tinput_sel_active(tinput_t *ti)
    477 {
    478         return ti->sel_start != ti->pos;
    479 }
    480 
    481 static void tinput_sel_all(tinput_t *ti)
    482 {
    483         ti->sel_start = 0;
    484         ti->pos = ti->nc;
    485         tinput_display_tail(ti, 0, 0);
    486         tinput_position_caret(ti);
    487 }
    488 
    489 static void tinput_sel_delete(tinput_t *ti)
    490 {
    491         int sa, sb;
    492 
    493         tinput_sel_get_bounds(ti, &sa, &sb);
    494         if (sa == sb)
    495                 return;
    496 
    497         memmove(ti->buffer + sa, ti->buffer + sb,
    498             (ti->nc - sb) * sizeof(wchar_t));
    499         ti->pos = ti->sel_start = sa;
    500         ti->nc -= (sb - sa);
    501         ti->buffer[ti->nc] = '\0';
    502 
    503         tinput_display_tail(ti, sa, sb - sa);
    504         tinput_position_caret(ti);
    505 }
    506 
    507 static void tinput_sel_copy_to_cb(tinput_t *ti)
    508 {
    509         int sa, sb;
    510         wchar_t tmp_c;
    511         char *str;
    512 
    513         tinput_sel_get_bounds(ti, &sa, &sb);
    514 
    515         if (sb < ti->nc) {
    516                 tmp_c = ti->buffer[sb];
    517                 ti->buffer[sb] = '\0';
    518         }
    519 
    520         str = wstr_to_astr(ti->buffer + sa);
    521 
    522         if (sb < ti->nc)
    523                 ti->buffer[sb] = tmp_c;
    524 
    525         if (str == NULL)
    526                 goto error;
    527 
    528         if (clipboard_put_str(str) != EOK)
    529                 goto error;
    530 
    531         free(str);
    532         return;
    533 error:
    534         return;
    535         /* TODO: Give the user some warning. */
    536 }
    537 
    538 static void tinput_paste_from_cb(tinput_t *ti)
    539 {
    540         char *str;
    541         int rc;
    542 
    543         rc = clipboard_get_str(&str);
    544         if (rc != EOK || str == NULL)
    545                 return; /* TODO: Give the user some warning. */
    546 
    547         tinput_insert_string(ti, str);
    548         free(str);
    549313}
    550314
     
    573337}
    574338
    575 /** Initialize text input field.
    576  *
    577  * Must be called before using the field. It clears the history.
    578  */
    579339static void tinput_init(tinput_t *ti)
    580340{
     
    584344}
    585345
    586 /** Read in one line of input. */
    587346static char *tinput_read(tinput_t *ti)
    588347{
     
    597356                return NULL;
    598357
    599         ti->pos = ti->sel_start = 0;
     358        ti->pos = 0;
    600359        ti->nc = 0;
    601360        ti->buffer[0] = '\0';
    602         ti->done = false;
    603 
    604         while (!ti->done) {
     361
     362        while (true) {
    605363                fflush(stdout);
    606364                if (!console_get_event(fphone(stdin), &ev))
    607365                        return NULL;
    608 
     366               
    609367                if (ev.type != KEY_PRESS)
    610368                        continue;
     
    612370                if ((ev.mods & KM_CTRL) != 0 &&
    613371                    (ev.mods & (KM_ALT | KM_SHIFT)) == 0) {
    614                         tinput_key_ctrl(ti, &ev);
     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                        }
    615386                }
    616387
    617                 if ((ev.mods & KM_SHIFT) != 0 &&
    618                     (ev.mods & (KM_CTRL | KM_ALT)) == 0) {
    619                         tinput_key_shift(ti, &ev);
     388                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                        }
    620418                }
    621419
    622                 if ((ev.mods & KM_CTRL) != 0 &&
    623                     (ev.mods & KM_SHIFT) != 0 &&
    624                     (ev.mods & KM_ALT) == 0) {
    625                         tinput_key_ctrl_shift(ti, &ev);
    626                 }
    627 
    628                 if ((ev.mods & (KM_CTRL | KM_ALT | KM_SHIFT)) == 0) {
    629                         tinput_key_unmod(ti, &ev);
    630                 }
    631 
    632420                if (ev.c >= ' ') {
    633                         tinput_sel_delete(ti);
    634421                        tinput_insert_char(ti, ev.c);
    635422                }
    636423        }
    637424
     425done:
    638426        ti->pos = ti->nc;
    639427        tinput_position_caret(ti);
     
    647435
    648436        return str;
    649 }
    650 
    651 static void tinput_key_ctrl(tinput_t *ti, console_event_t *ev)
    652 {
    653         switch (ev->key) {
    654         case KC_LEFT:
    655                 tinput_seek_word(ti, seek_backward, false);
    656                 break;
    657         case KC_RIGHT:
    658                 tinput_seek_word(ti, seek_forward, false);
    659                 break;
    660         case KC_UP:
    661                 tinput_seek_vertical(ti, seek_backward, false);
    662                 break;
    663         case KC_DOWN:
    664                 tinput_seek_vertical(ti, seek_forward, false);
    665                 break;
    666         case KC_X:
    667                 tinput_sel_copy_to_cb(ti);
    668                 tinput_sel_delete(ti);
    669                 break;
    670         case KC_C:
    671                 tinput_sel_copy_to_cb(ti);
    672                 break;
    673         case KC_V:
    674                 tinput_sel_delete(ti);
    675                 tinput_paste_from_cb(ti);
    676                 break;
    677         case KC_A:
    678                 tinput_sel_all(ti);
    679                 break;
    680         default:
    681                 break;
    682         }
    683 }
    684 
    685 static void tinput_key_ctrl_shift(tinput_t *ti, console_event_t *ev)
    686 {
    687         switch (ev->key) {
    688         case KC_LEFT:
    689                 tinput_seek_word(ti, seek_backward, true);
    690                 break;
    691         case KC_RIGHT:
    692                 tinput_seek_word(ti, seek_forward, true);
    693                 break;
    694         case KC_UP:
    695                 tinput_seek_vertical(ti, seek_backward, true);
    696                 break;
    697         case KC_DOWN:
    698                 tinput_seek_vertical(ti, seek_forward, true);
    699                 break;
    700         default:
    701                 break;
    702         }
    703 }
    704 
    705 static void tinput_key_shift(tinput_t *ti, console_event_t *ev)
    706 {
    707         switch (ev->key) {
    708         case KC_LEFT:
    709                 tinput_seek_cell(ti, seek_backward, true);
    710                 break;
    711         case KC_RIGHT:
    712                 tinput_seek_cell(ti, seek_forward, true);
    713                 break;
    714         case KC_UP:
    715                 tinput_seek_vertical(ti, seek_backward, true);
    716                 break;
    717         case KC_DOWN:
    718                 tinput_seek_vertical(ti, seek_forward, true);
    719                 break;
    720         case KC_HOME:
    721                 tinput_seek_max(ti, seek_backward, true);
    722                 break;
    723         case KC_END:
    724                 tinput_seek_max(ti, seek_forward, true);
    725                 break;
    726         default:
    727                 break;
    728         }
    729 }
    730 
    731 static void tinput_key_unmod(tinput_t *ti, console_event_t *ev)
    732 {
    733         switch (ev->key) {
    734         case KC_ENTER:
    735         case KC_NENTER:
    736                 ti->done = true;
    737                 break;
    738         case KC_BACKSPACE:
    739                 tinput_backspace(ti);
    740                 break;
    741         case KC_DELETE:
    742                 tinput_delete(ti);
    743                 break;
    744         case KC_LEFT:
    745                 tinput_seek_cell(ti, seek_backward, false);
    746                 break;
    747         case KC_RIGHT:
    748                 tinput_seek_cell(ti, seek_forward, false);
    749                 break;
    750         case KC_HOME:
    751                 tinput_seek_max(ti, seek_backward, false);
    752                 break;
    753         case KC_END:
    754                 tinput_seek_max(ti, seek_forward, false);
    755                 break;
    756         case KC_UP:
    757                 tinput_history_seek(ti, +1);
    758                 break;
    759         case KC_DOWN:
    760                 tinput_history_seek(ti, -1);
    761                 break;
    762         default:
    763                 break;
    764         }
    765437}
    766438
  • uspace/app/edit/edit.c

    r034bf0e r65c1778  
    4545#include <align.h>
    4646#include <macros.h>
    47 #include <clipboard.h>
    4847#include <bool.h>
    4948
     
    7574        tag_t caret_pos;
    7675
    77         /** Start of selection */
    78         tag_t sel_start;
    79 
    8076        /**
    8177         * Ideal column where the caret should try to get. This is used
     
    111107static void key_handle_unmod(console_event_t const *ev);
    112108static void key_handle_ctrl(console_event_t const *ev);
    113 static void key_handle_shift(console_event_t const *ev);
    114 static void key_handle_movement(unsigned int key, bool shift);
    115 
    116109static int file_save(char const *fname);
    117110static void file_save_as(void);
     
    120113    spt_t const *epos);
    121114static char *filename_prompt(char const *prompt, char const *init_value);
    122 static char *range_get_str(spt_t const *spos, spt_t const *epos);
    123 
    124115static void pane_text_display(void);
    125116static void pane_row_display(void);
     
    127118static void pane_status_display(void);
    128119static void pane_caret_display(void);
    129 
    130120static void insert_char(wchar_t c);
    131121static void delete_char_before(void);
     
    133123static void caret_update(void);
    134124static void caret_move(int drow, int dcolumn, enum dir_spec align_dir);
    135 
    136 static bool selection_active(void);
    137 static void selection_sel_all(void);
    138 static void selection_get_points(spt_t *pa, spt_t *pb);
    139 static void selection_delete(void);
    140 static void selection_copy(void);
    141 static void insert_clipboard_data(void);
    142 
    143125static void pt_get_sof(spt_t *pt);
    144126static void pt_get_eof(spt_t *pt);
    145 static int tag_cmp(tag_t const *a, tag_t const *b);
    146 static int spt_cmp(spt_t const *a, spt_t const *b);
    147 static int coord_cmp(coord_t const *a, coord_t const *b);
    148 
    149127static void status_display(char const *str);
    150128
     
    194172        caret_move(-ED_INFTY, -ED_INFTY, dir_before);
    195173
    196         /* Place selection start tag. */
    197         tag_get_pt(&pane.caret_pos, &pt);
    198         sheet_place_tag(&doc.sh, &pt, &pane.sel_start);
    199 
    200174        /* Initial display */
    201175        console_clear(con);
     
    216190                        /* Handle key press. */
    217191                        if (((ev.mods & KM_ALT) == 0) &&
    218                             ((ev.mods & KM_SHIFT) == 0) &&
    219192                             (ev.mods & KM_CTRL) != 0) {
    220193                                key_handle_ctrl(&ev);
    221                         } else if (((ev.mods & KM_ALT) == 0) &&
    222                             ((ev.mods & KM_CTRL) == 0) &&
    223                              (ev.mods & KM_SHIFT) != 0) {
    224                                 key_handle_shift(&ev);
    225                         } else if ((ev.mods & (KM_CTRL | KM_ALT | KM_SHIFT)) == 0) {
     194                        } else if ((ev.mods & (KM_CTRL | KM_ALT)) == 0) {
    226195                                key_handle_unmod(&ev);
    227196                        }
     
    238207                if (pane.rflags & REDRAW_CARET)
    239208                        pane_caret_display();
     209                       
    240210        }
    241211
     
    250220        switch (ev->key) {
    251221        case KC_ENTER:
    252                 selection_delete();
    253222                insert_char('\n');
    254223                caret_update();
    255224                break;
    256225        case KC_LEFT:
     226                caret_move(0, -1, dir_before);
     227                break;
    257228        case KC_RIGHT:
     229                caret_move(0, 0, dir_after);
     230                break;
    258231        case KC_UP:
     232                caret_move(-1, 0, dir_before);
     233                break;
    259234        case KC_DOWN:
     235                caret_move(+1, 0, dir_before);
     236                break;
    260237        case KC_HOME:
     238                caret_move(0, -ED_INFTY, dir_before);
     239                break;
    261240        case KC_END:
     241                caret_move(0, +ED_INFTY, dir_before);
     242                break;
    262243        case KC_PAGE_UP:
     244                caret_move(-pane.rows, 0, dir_before);
     245                break;
    263246        case KC_PAGE_DOWN:
    264                 key_handle_movement(ev->key, false);
     247                caret_move(+pane.rows, 0, dir_before);
    265248                break;
    266249        case KC_BACKSPACE:
    267                 if (selection_active())
    268                         selection_delete();
    269                 else
    270                         delete_char_before();
     250                delete_char_before();
    271251                caret_update();
    272252                break;
    273253        case KC_DELETE:
    274                 if (selection_active())
    275                         selection_delete();
    276                 else
    277                         delete_char_after();
     254                delete_char_after();
    278255                caret_update();
    279256                break;
    280257        default:
    281258                if (ev->c >= 32 || ev->c == '\t') {
    282                         selection_delete();
    283                         insert_char(ev->c);
    284                         caret_update();
    285                 }
    286                 break;
    287         }
    288 }
    289 
    290 /** Handle Shift-key combination. */
    291 static void key_handle_shift(console_event_t const *ev)
    292 {
    293         switch (ev->key) {
    294         case KC_LEFT:
    295         case KC_RIGHT:
    296         case KC_UP:
    297         case KC_DOWN:
    298         case KC_HOME:
    299         case KC_END:
    300         case KC_PAGE_UP:
    301         case KC_PAGE_DOWN:
    302                 key_handle_movement(ev->key, true);
    303                 break;
    304         default:
    305                 if (ev->c >= 32 || ev->c == '\t') {
    306                         selection_delete();
    307259                        insert_char(ev->c);
    308260                        caret_update();
     
    328280                file_save_as();
    329281                break;
    330         case KC_C:
    331                 selection_copy();
    332                 break;
    333         case KC_V:
    334                 selection_delete();
    335                 insert_clipboard_data();
    336                 pane.rflags |= REDRAW_TEXT;
    337                 caret_update();
    338                 break;
    339         case KC_X:
    340                 selection_copy();
    341                 selection_delete();
    342                 pane.rflags |= REDRAW_TEXT;
    343                 caret_update();
    344                 break;
    345         case KC_A:
    346                 selection_sel_all();
    347                 break;
    348282        default:
    349283                break;
    350         }
    351 }
    352 
    353 static void key_handle_movement(unsigned int key, bool select)
    354 {
    355         spt_t pt;
    356         spt_t caret_pt;
    357         coord_t c_old, c_new;
    358         bool had_sel;
    359 
    360         /* Check if we had selection before. */
    361         tag_get_pt(&pane.caret_pos, &caret_pt);
    362         tag_get_pt(&pane.sel_start, &pt);
    363         had_sel = !spt_equal(&caret_pt, &pt);
    364 
    365         switch (key) {
    366         case KC_LEFT:
    367                 caret_move(0, -1, dir_before);
    368                 break;
    369         case KC_RIGHT:
    370                 caret_move(0, 0, dir_after);
    371                 break;
    372         case KC_UP:
    373                 caret_move(-1, 0, dir_before);
    374                 break;
    375         case KC_DOWN:
    376                 caret_move(+1, 0, dir_before);
    377                 break;
    378         case KC_HOME:
    379                 caret_move(0, -ED_INFTY, dir_before);
    380                 break;
    381         case KC_END:
    382                 caret_move(0, +ED_INFTY, dir_before);
    383                 break;
    384         case KC_PAGE_UP:
    385                 caret_move(-pane.rows, 0, dir_before);
    386                 break;
    387         case KC_PAGE_DOWN:
    388                 caret_move(+pane.rows, 0, dir_before);
    389                 break;
    390         default:
    391                 break;
    392         }
    393 
    394         if (select == false) {
    395                 /* Move sel_start to the same point as caret. */
    396                 sheet_remove_tag(&doc.sh, &pane.sel_start);
    397                 tag_get_pt(&pane.caret_pos, &pt);
    398                 sheet_place_tag(&doc.sh, &pt, &pane.sel_start);
    399         }
    400 
    401         if (select) {
    402                 tag_get_pt(&pane.caret_pos, &pt);
    403                 spt_get_coord(&caret_pt, &c_old);
    404                 spt_get_coord(&pt, &c_new);
    405 
    406                 if (c_old.row == c_new.row)
    407                         pane.rflags |= REDRAW_ROW;
    408                 else
    409                         pane.rflags |= REDRAW_TEXT;
    410 
    411         } else if (had_sel == true) {
    412                 /* Redraw because text was unselected. */
    413                 pane.rflags |= REDRAW_TEXT;
    414284        }
    415285}
     
    603473}
    604474
    605 /** Return contents of range as a new string. */
    606 static char *range_get_str(spt_t const *spos, spt_t const *epos)
    607 {
    608         char *buf;
    609         spt_t sp, bep;
    610         size_t bytes;
    611         size_t buf_size, bpos;
    612 
    613         buf_size = 1;
    614 
    615         buf = malloc(buf_size);
    616         if (buf == NULL)
    617                 return NULL;
    618 
    619         bpos = 0;
    620         sp = *spos;
    621 
    622         while (true) {
    623                 sheet_copy_out(&doc.sh, &sp, epos, &buf[bpos], buf_size - bpos,
    624                     &bep);
    625                 bytes = str_size(&buf[bpos]);
    626                 bpos += bytes;
    627                 sp = bep;
    628 
    629                 if (spt_equal(&bep, epos))
    630                         break;
    631 
    632                 buf_size *= 2;
    633                 buf = realloc(buf, buf_size);
    634                 if (buf == NULL)
    635                         return NULL;
    636         }
    637 
    638         return buf;
    639 }
    640 
    641475static void pane_text_display(void)
    642476{
     
    683517{
    684518        int i, j, fill;
    685         spt_t rb, re, dep, pt;
     519        spt_t rb, re, dep;
    686520        coord_t rbc, rec;
    687521        char row_buf[ROW_BUF_SIZE];
     
    689523        size_t pos, size;
    690524        unsigned s_column;
    691         coord_t csel_start, csel_end, ctmp;
    692 
    693         /* Determine selection start and end. */
    694 
    695         tag_get_pt(&pane.sel_start, &pt);
    696         spt_get_coord(&pt, &csel_start);
    697 
    698         tag_get_pt(&pane.caret_pos, &pt);
    699         spt_get_coord(&pt, &csel_end);
    700 
    701         if (coord_cmp(&csel_start, &csel_end) > 0) {
    702                 ctmp = csel_start;
    703                 csel_start = csel_end;
    704                 csel_end = ctmp;
    705         }
    706525
    707526        /* Draw rows from the sheet. */
     
    724543                /* Display text from the buffer. */
    725544
    726                 if (coord_cmp(&csel_start, &rbc) <= 0 &&
    727                     coord_cmp(&rbc, &csel_end) < 0) {
    728                         fflush(stdout);
    729                         console_set_color(con, COLOR_BLACK, COLOR_RED, 0);
    730                         fflush(stdout);
    731                 }
    732 
    733545                console_goto(con, 0, i);
    734546                size = str_size(row_buf);
     
    736548                s_column = 1;
    737549                while (pos < size) {
    738                         if (csel_start.row == rbc.row && csel_start.column == s_column) {
    739                                 fflush(stdout);
    740                                 console_set_color(con, COLOR_BLACK, COLOR_RED, 0);
    741                                 fflush(stdout);
    742                         }
    743        
    744                         if (csel_end.row == rbc.row && csel_end.column == s_column) {
    745                                 fflush(stdout);
    746                                 console_set_color(con, COLOR_BLACK, COLOR_WHITE, 0);
    747                                 fflush(stdout);
    748                         }
    749        
    750550                        c = str_decode(row_buf, &pos, size);
    751551                        if (c != '\t') {
     
    762562                }
    763563
    764                 if (csel_end.row == rbc.row && csel_end.column == s_column) {
    765                         fflush(stdout);
    766                         console_set_color(con, COLOR_BLACK, COLOR_WHITE, 0);
    767                         fflush(stdout);
    768                 }
    769 
    770564                /* Fill until the end of display area. */
    771565
     
    778572                        putchar(' ');
    779573                fflush(stdout);
    780                 console_set_color(con, COLOR_BLACK, COLOR_WHITE, 0);
    781574        }
    782575
     
    967760}
    968761
    969 /** Check for non-empty selection. */
    970 static bool selection_active(void)
    971 {
    972         return (tag_cmp(&pane.caret_pos, &pane.sel_start) != 0);
    973 }
    974 
    975 static void selection_get_points(spt_t *pa, spt_t *pb)
    976 {
    977         spt_t pt;
    978 
    979         tag_get_pt(&pane.sel_start, pa);
    980         tag_get_pt(&pane.caret_pos, pb);
    981 
    982         if (spt_cmp(pa, pb) > 0) {
    983                 pt = *pa;
    984                 *pa = *pb;
    985                 *pb = pt;
    986         }
    987 }
    988 
    989 /** Delete selected text. */
    990 static void selection_delete(void)
    991 {
    992         spt_t pa, pb;
    993         coord_t ca, cb;
    994         int rel;
    995 
    996         tag_get_pt(&pane.sel_start, &pa);
    997         tag_get_pt(&pane.caret_pos, &pb);
    998         spt_get_coord(&pa, &ca);
    999         spt_get_coord(&pb, &cb);
    1000         rel = coord_cmp(&ca, &cb);
    1001 
    1002         if (rel == 0)
    1003                 return;
    1004 
    1005         if (rel < 0)
    1006                 sheet_delete(&doc.sh, &pa, &pb);
    1007         else
    1008                 sheet_delete(&doc.sh, &pb, &pa);
    1009 
    1010         if (ca.row == cb.row)
    1011                 pane.rflags |= REDRAW_ROW;
    1012         else
    1013                 pane.rflags |= REDRAW_TEXT;
    1014 }
    1015 
    1016 static void selection_sel_all(void)
    1017 {
    1018         spt_t spt, ept;
    1019 
    1020         pt_get_sof(&spt);
    1021         pt_get_eof(&ept);
    1022         sheet_remove_tag(&doc.sh, &pane.sel_start);
    1023         sheet_place_tag(&doc.sh, &spt, &pane.sel_start);
    1024         sheet_remove_tag(&doc.sh, &pane.caret_pos);
    1025         sheet_place_tag(&doc.sh, &ept, &pane.caret_pos);
    1026 
    1027         pane.rflags |= REDRAW_TEXT;
    1028 }
    1029 
    1030 static void selection_copy(void)
    1031 {
    1032         spt_t pa, pb;
    1033         char *str;
    1034 
    1035         selection_get_points(&pa, &pb);
    1036         str = range_get_str(&pa, &pb);
    1037         if (str == NULL || clipboard_put_str(str) != EOK) {
    1038                 status_display("Copying to clipboard failed!");
    1039         }
    1040         free(str);
    1041 }
    1042 
    1043 static void insert_clipboard_data(void)
    1044 {
    1045         char *str;
    1046         size_t off;
    1047         wchar_t c;
    1048         int rc;
    1049 
    1050         rc = clipboard_get_str(&str);
    1051         if (rc != EOK || str == NULL)
    1052                 return;
    1053 
    1054         off = 0;
    1055 
    1056         while (true) {
    1057                 c = str_decode(str, &off, STR_NO_LIMIT);
    1058                 if (c == '\0')
    1059                         break;
    1060 
    1061                 insert_char(c);
    1062         }
    1063 
    1064         free(str);
    1065 }
    1066762
    1067763/** Get start-of-file s-point. */
     
    1085781
    1086782        sheet_get_cell_pt(&doc.sh, &coord, dir_after, pt);
    1087 }
    1088 
    1089 /** Compare tags. */
    1090 static int tag_cmp(tag_t const *a, tag_t const *b)
    1091 {
    1092         spt_t pa, pb;
    1093 
    1094         tag_get_pt(a, &pa);
    1095         tag_get_pt(b, &pb);
    1096 
    1097         return spt_cmp(&pa, &pb);
    1098 }
    1099 
    1100 /** Compare s-points. */
    1101 static int spt_cmp(spt_t const *a, spt_t const *b)
    1102 {
    1103         coord_t ca, cb;
    1104 
    1105         spt_get_coord(a, &ca);
    1106         spt_get_coord(b, &cb);
    1107 
    1108         return coord_cmp(&ca, &cb);
    1109 }
    1110 
    1111 /** Compare coordinats. */
    1112 static int coord_cmp(coord_t const *a, coord_t const *b)
    1113 {
    1114         if (a->row - b->row != 0)
    1115                 return a->row - b->row;
    1116 
    1117         return a->column - b->column;
    1118783}
    1119784
  • uspace/lib/libc/Makefile.build

    r034bf0e r65c1778  
    5050        generic/as.c \
    5151        generic/cap.c \
    52         generic/clipboard.c \
    5352        generic/devmap.c \
    5453        generic/event.c \
  • uspace/lib/libc/generic/io/io.c

    r034bf0e r65c1778  
    494494       
    495495        if (chr_encode(c, buf, &sz, STR_BOUNDS(1)) == EOK) {
    496                 size_t wr = fwrite(buf, 1, sz, stream);
     496                size_t wr = fwrite(buf, sz, 1, stream);
    497497               
    498498                if (wr < sz)
Note: See TracChangeset for help on using the changeset viewer.