Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/gui/terminal.c

    r5a6cc679 ra35b458  
    4747#include <atomic.h>
    4848#include <stdarg.h>
     49#include <str.h>
    4950#include "window.h"
    5051#include "terminal.h"
     
    117118        [COLOR_YELLOW]      = PIXEL(255, 240, 240, 0),
    118119        [COLOR_WHITE]       = PIXEL(255, 240, 240, 240),
    119        
     120
    120121        [COLOR_BLACK + 8]   = PIXEL(255, 0, 0, 0),
    121122        [COLOR_BLUE + 8]    = PIXEL(255, 0, 0, 255),
     
    169170        charfield_t *field =
    170171            chargrid_charfield_at(term->backbuf, col, row);
    171        
     172
    172173        bool inverted = chargrid_cursor_at(term->backbuf, col, row);
    173        
     174
    174175        sysarg_t bx = sx + (col * FONT_WIDTH);
    175176        sysarg_t by = sy + (row * FONT_SCANLINES);
    176        
     177
    177178        pixel_t bgcolor = 0;
    178179        pixel_t fgcolor = 0;
    179        
     180
    180181        if (inverted)
    181182                attrs_rgb(field->attrs, &fgcolor, &bgcolor);
    182183        else
    183184                attrs_rgb(field->attrs, &bgcolor, &fgcolor);
    184        
     185
    185186        // FIXME: Glyph type should be actually uint32_t
    186187        //        for full UTF-32 coverage.
    187        
     188
    188189        uint16_t glyph = fb_font_glyph(field->ch, NULL);
    189        
     190
    190191        for (unsigned int y = 0; y < FONT_SCANLINES; y++) {
    191192                pixel_t *dst = pixelmap_pixel_at(
     
    206207{
    207208        sysarg_t top_row = chargrid_get_top_row(term->frontbuf);
    208        
     209
    209210        if (term->top_row == top_row)
    210211                return false;
    211        
     212
    212213        term->top_row = top_row;
    213        
     214
    214215        for (sysarg_t row = 0; row < term->rows; row++) {
    215216                for (sysarg_t col = 0; col < term->cols; col++) {
     
    219220                            chargrid_charfield_at(term->backbuf, col, row);
    220221                        bool update = false;
    221                        
     222
    222223                        if (front_field->ch != back_field->ch) {
    223224                                back_field->ch = front_field->ch;
    224225                                update = true;
    225226                        }
    226                        
     227
    227228                        if (!attrs_same(front_field->attrs, back_field->attrs)) {
    228229                                back_field->attrs = front_field->attrs;
    229230                                update = true;
    230231                        }
    231                        
     232
    232233                        front_field->flags &= ~CHAR_FLAG_DIRTY;
    233                        
     234
    234235                        if (update)
    235236                                term_update_char(term, surface, sx, sy, col, row);
    236237                }
    237238        }
    238        
     239
    239240        return true;
    240241}
     
    244245{
    245246        bool damage = false;
    246        
     247
    247248        sysarg_t front_col;
    248249        sysarg_t front_row;
    249250        chargrid_get_cursor(term->frontbuf, &front_col, &front_row);
    250        
     251
    251252        sysarg_t back_col;
    252253        sysarg_t back_row;
    253254        chargrid_get_cursor(term->backbuf, &back_col, &back_row);
    254        
     255
    255256        bool front_visibility =
    256257            chargrid_get_cursor_visibility(term->frontbuf) &&
     
    258259        bool back_visibility =
    259260            chargrid_get_cursor_visibility(term->backbuf);
    260        
     261
    261262        if (front_visibility != back_visibility) {
    262263                chargrid_set_cursor_visibility(term->backbuf,
     
    265266                damage = true;
    266267        }
    267        
     268
    268269        if ((front_col != back_col) || (front_row != back_row)) {
    269270                chargrid_set_cursor(term->backbuf, front_col, front_row);
     
    272273                damage = true;
    273274        }
    274        
     275
    275276        return damage;
    276277}
     
    279280{
    280281        fibril_mutex_lock(&term->mtx);
    281        
     282
    282283        surface_t *surface = window_claim(term->widget.window);
    283284        if (!surface) {
     
    286287                return;
    287288        }
    288        
     289
    289290        bool damage = false;
    290291        sysarg_t sx = term->widget.hpos;
    291292        sysarg_t sy = term->widget.vpos;
    292        
     293
    293294        if (term_update_scroll(term, surface, sx, sy)) {
    294295                damage = true;
     
    301302                                    chargrid_charfield_at(term->backbuf, x, y);
    302303                                bool update = false;
    303                                
     304
    304305                                if ((front_field->flags & CHAR_FLAG_DIRTY) ==
    305306                                    CHAR_FLAG_DIRTY) {
     
    308309                                                update = true;
    309310                                        }
    310                                        
     311
    311312                                        if (!attrs_same(front_field->attrs,
    312313                                            back_field->attrs)) {
     
    314315                                                update = true;
    315316                                        }
    316                                        
     317
    317318                                        front_field->flags &= ~CHAR_FLAG_DIRTY;
    318319                                }
    319                                
     320
    320321                                if (update) {
    321322                                        term_update_char(term, surface, sx, sy, x, y);
     
    325326                }
    326327        }
    327        
     328
    328329        if (term_update_cursor(term, surface, sx, sy))
    329330                damage = true;
    330        
     331
    331332        window_yield(term->widget.window);
    332        
     333
    333334        if (damage)
    334335                window_damage(term->widget.window);
    335        
     336
    336337        fibril_mutex_unlock(&term->mtx);
    337338}
     
    340341{
    341342        fibril_mutex_lock(&term->mtx);
    342        
     343
    343344        surface_t *surface = window_claim(term->widget.window);
    344345        if (!surface) {
     
    347348                return;
    348349        }
    349        
     350
    350351        sysarg_t sx = term->widget.hpos;
    351352        sysarg_t sy = term->widget.vpos;
    352        
     353
    353354        if (!term_update_scroll(term, surface, sx, sy)) {
    354355                for (sysarg_t y = 0; y < term->rows; y++) {
     
    358359                                charfield_t *back_field =
    359360                                    chargrid_charfield_at(term->backbuf, x, y);
    360                                
     361
    361362                                back_field->ch = front_field->ch;
    362363                                back_field->attrs = front_field->attrs;
    363364                                front_field->flags &= ~CHAR_FLAG_DIRTY;
    364                                
     365
    365366                                term_update_char(term, surface, sx, sy, x, y);
    366367                        }
    367368                }
    368369        }
    369        
     370
    370371        term_update_cursor(term, surface, sx, sy);
    371        
     372
    372373        window_yield(term->widget.window);
    373374        window_damage(term->widget.window);
    374        
     375
    375376        fibril_mutex_unlock(&term->mtx);
    376377}
     
    391392        uint8_t *bbuf = buf;
    392393        size_t pos = 0;
    393        
     394
    394395        /*
    395396         * Read input from keyboard and copy it to the buffer.
     
    402403                        bbuf[pos] = term->char_remains[0];
    403404                        pos++;
    404                        
     405
    405406                        /* Unshift the array. */
    406407                        for (size_t i = 1; i < term->char_remains_len; i++)
    407408                                term->char_remains[i - 1] = term->char_remains[i];
    408                        
     409
    409410                        term->char_remains_len--;
    410411                }
    411                
     412
    412413                /* Still not enough? Then get another key from the queue. */
    413414                if (pos < size) {
    414415                        link_t *link = prodcons_consume(&term->input_pc);
    415416                        cons_event_t *event = list_get_instance(link, cons_event_t, link);
    416                        
     417
    417418                        /* Accept key presses of printable chars only. */
    418419                        if (event->type == CEV_KEY && event->ev.key.type == KEY_PRESS &&
     
    422423                                        0
    423424                                };
    424                                
     425
    425426                                wstr_to_str(term->char_remains, UTF8_CHAR_BUFFER_SIZE, tmp);
    426427                                term->char_remains_len = str_size(term->char_remains);
    427428                        }
    428                        
     429
    429430                        free(event);
    430431                }
    431432        }
    432        
     433
    433434        *nread = size;
    434435        return EOK;
     
    438439{
    439440        sysarg_t updated = 0;
    440        
    441         fibril_mutex_lock(&term->mtx);
    442        
     441
     442        fibril_mutex_lock(&term->mtx);
     443
    443444        switch (ch) {
    444445        case '\n':
     
    456457                updated = chargrid_putchar(term->frontbuf, ch, true);
    457458        }
    458        
    459         fibril_mutex_unlock(&term->mtx);
    460        
     459
     460        fibril_mutex_unlock(&term->mtx);
     461
    461462        if (updated > 1)
    462463                term_update(term);
     
    466467{
    467468        terminal_t *term = srv_to_terminal(srv);
    468        
     469
    469470        size_t off = 0;
    470471        while (off < size)
    471472                term_write_char(term, str_decode(data, &off, size));
    472        
     473
    473474        *nwritten = size;
    474475        return EOK;
     
    478479{
    479480        terminal_t *term = srv_to_terminal(srv);
    480        
     481
    481482        term_update(term);
    482483}
     
    485486{
    486487        terminal_t *term = srv_to_terminal(srv);
    487        
     488
    488489        fibril_mutex_lock(&term->mtx);
    489490        chargrid_clear(term->frontbuf);
    490491        fibril_mutex_unlock(&term->mtx);
    491        
     492
    492493        term_update(term);
    493494}
     
    496497{
    497498        terminal_t *term = srv_to_terminal(srv);
    498        
     499
    499500        fibril_mutex_lock(&term->mtx);
    500501        chargrid_set_cursor(term->frontbuf, col, row);
    501502        fibril_mutex_unlock(&term->mtx);
    502        
     503
    503504        term_update(term);
    504505}
     
    507508{
    508509        terminal_t *term = srv_to_terminal(srv);
    509        
     510
    510511        fibril_mutex_lock(&term->mtx);
    511512        chargrid_get_cursor(term->frontbuf, col, row);
    512513        fibril_mutex_unlock(&term->mtx);
    513        
     514
    514515        return EOK;
    515516}
     
    518519{
    519520        terminal_t *term = srv_to_terminal(srv);
    520        
     521
    521522        fibril_mutex_lock(&term->mtx);
    522523        *cols = term->cols;
    523524        *rows = term->rows;
    524525        fibril_mutex_unlock(&term->mtx);
    525        
     526
    526527        return EOK;
    527528}
     
    531532        (void) srv;
    532533        *caps = TERM_CAPS;
    533        
     534
    534535        return EOK;
    535536}
     
    538539{
    539540        terminal_t *term = srv_to_terminal(srv);
    540        
     541
    541542        fibril_mutex_lock(&term->mtx);
    542543        chargrid_set_style(term->frontbuf, style);
     
    548549{
    549550        terminal_t *term = srv_to_terminal(srv);
    550        
     551
    551552        fibril_mutex_lock(&term->mtx);
    552553        chargrid_set_color(term->frontbuf, bgcolor, fgcolor, attr);
     
    558559{
    559560        terminal_t *term = srv_to_terminal(srv);
    560        
     561
    561562        fibril_mutex_lock(&term->mtx);
    562563        chargrid_set_rgb_color(term->frontbuf, bgcolor, fgcolor);
     
    567568{
    568569        terminal_t *term = srv_to_terminal(srv);
    569        
     570
    570571        fibril_mutex_lock(&term->mtx);
    571572        chargrid_set_cursor_visibility(term->frontbuf, visible);
    572573        fibril_mutex_unlock(&term->mtx);
    573        
     574
    574575        term_update(term);
    575576}
     
    580581        link_t *link = prodcons_consume(&term->input_pc);
    581582        cons_event_t *ev = list_get_instance(link, cons_event_t, link);
    582        
     583
    583584        *event = *ev;
    584585        free(ev);
     
    590591        list_remove(&term->link);
    591592        widget_deinit(&term->widget);
    592        
     593
    593594        if (term->frontbuf)
    594595                chargrid_destroy(term->frontbuf);
    595        
     596
    596597        if (term->backbuf)
    597598                chargrid_destroy(term->backbuf);
     
    601602{
    602603        terminal_t *term = (terminal_t *) widget;
    603        
     604
    604605        deinit_terminal(term);
    605606        free(term);
     
    615616{
    616617        terminal_t *term = (terminal_t *) widget;
    617        
     618
    618619        widget_modify(widget, hpos, vpos, width, height);
    619620        widget->width_ideal = width;
    620621        widget->height_ideal = height;
    621        
     622
    622623        term_damage(term);
    623624}
     
    626627{
    627628        terminal_t *term = (terminal_t *) widget;
    628        
     629
    629630        term_damage(term);
    630631}
     
    637638        if (event == NULL)
    638639                return;
    639        
     640
    640641        *event = *ev;
    641642        link_initialize(&event->link);
    642        
     643
    643644        prodcons_produce(&term->input_pc, &event->link);
    644645}
     
    650651        terminal_t *term = (terminal_t *) widget;
    651652        cons_event_t event;
    652        
     653
    653654        event.type = CEV_KEY;
    654655        event.ev.key = kbd_event;
    655        
     656
    656657        terminal_queue_cons_event(term, &event);
    657658}
     
    679680{
    680681        terminal_t *term = NULL;
    681        
     682
    682683        list_foreach(terms, link, terminal_t, cur) {
    683684                if (cur->dsid == (service_id_t) IPC_GET_ARG2(*icall)) {
     
    686687                }
    687688        }
    688        
     689
    689690        if (term == NULL) {
    690691                async_answer_0(iid, ENOENT);
    691692                return;
    692693        }
    693        
     694
    694695        if (atomic_postinc(&term->refcnt) == 0)
    695696                chargrid_set_cursor_visibility(term->frontbuf, true);
    696        
     697
    697698        con_conn(iid, icall, &term->srvs);
    698699}
     
    702703{
    703704        widget_init(&term->widget, parent, data);
    704        
     705
    705706        link_initialize(&term->link);
    706707        fibril_mutex_initialize(&term->mtx);
    707708        atomic_set(&term->refcnt, 0);
    708        
     709
    709710        prodcons_initialize(&term->input_pc);
    710711        term->char_remains_len = 0;
    711        
     712
    712713        term->widget.width = width;
    713714        term->widget.height = height;
    714715        term->widget.width_ideal = width;
    715716        term->widget.height_ideal = height;
    716        
     717
    717718        term->widget.destroy = terminal_destroy;
    718719        term->widget.reconfigure = terminal_reconfigure;
     
    721722        term->widget.handle_keyboard_event = terminal_handle_keyboard_event;
    722723        term->widget.handle_position_event = terminal_handle_position_event;
    723        
     724
    724725        term->cols = width / FONT_WIDTH;
    725726        term->rows = height / FONT_SCANLINES;
    726        
     727
    727728        term->frontbuf = NULL;
    728729        term->backbuf = NULL;
    729        
     730
    730731        term->frontbuf = chargrid_create(term->cols, term->rows,
    731732            CHARGRID_FLAG_NONE);
     
    734735                return false;
    735736        }
    736        
     737
    737738        term->backbuf = chargrid_create(term->cols, term->rows,
    738739            CHARGRID_FLAG_NONE);
     
    741742                return false;
    742743        }
    743        
     744
    744745        chargrid_clear(term->frontbuf);
    745746        chargrid_clear(term->backbuf);
    746747        term->top_row = 0;
    747        
     748
    748749        async_set_fallback_port_handler(term_connection, NULL);
    749750        con_srvs_init(&term->srvs);
    750751        term->srvs.ops = &con_ops;
    751752        term->srvs.sarg = term;
    752        
     753
    753754        errno_t rc = loc_server_register(NAME);
    754755        if (rc != EOK) {
     
    756757                return false;
    757758        }
    758        
     759
    759760        char vc[LOC_NAME_MAXLEN + 1];
    760761        snprintf(vc, LOC_NAME_MAXLEN, "%s/%" PRIu64, NAMESPACE,
    761762            task_get_id());
    762        
     763
    763764        rc = loc_service_register(vc, &term->dsid);
    764765        if (rc != EOK) {
     
    766767                return false;
    767768        }
    768        
     769
    769770        list_append(&term->link, &terms);
    770771        getterm(vc, "/app/bdsh");
    771        
     772
    772773        return true;
    773774}
     
    779780        if (!term)
    780781                return NULL;
    781        
     782
    782783        bool ret = init_terminal(term, parent, data, width, height);
    783784        if (!ret) {
     
    785786                return NULL;
    786787        }
    787        
     788
    788789        return term;
    789790}
Note: See TracChangeset for help on using the changeset viewer.