Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/terminal/terminal.c

    r266ec54 r77ffa01  
    11/*
    2  * Copyright (c) 2020 Jiri Svoboda
     2 * Copyright (c) 2021 Jiri Svoboda
    33 * Copyright (c) 2012 Petr Koupy
    44 * All rights reserved.
     
    3737#include <adt/list.h>
    3838#include <adt/prodcons.h>
     39#include <as.h>
    3940#include <errno.h>
    4041#include <fbfont/font-8x16.h>
     
    4243#include <gfx/bitmap.h>
    4344#include <gfx/context.h>
     45#include <gfx/render.h>
    4446#include <io/con_srv.h>
    4547#include <io/concaps.h>
     
    4850#include <task.h>
    4951#include <stdarg.h>
     52#include <stdio.h>
    5053#include <stdlib.h>
    5154#include <str.h>
     
    8588static void term_set_cursor_visibility(con_srv_t *, bool);
    8689static errno_t term_get_event(con_srv_t *, cons_event_t *);
     90static errno_t term_map(con_srv_t *, sysarg_t, sysarg_t, charfield_t **);
     91static void term_unmap(con_srv_t *);
     92static void term_buf_update(con_srv_t *, sysarg_t, sysarg_t, sysarg_t,
     93    sysarg_t);
    8794
    8895static con_ops_t con_ops = {
     
    101108        .set_rgb_color = term_set_rgb_color,
    102109        .set_cursor_visibility = term_set_cursor_visibility,
    103         .get_event = term_get_event
     110        .get_event = term_get_event,
     111        .map = term_map,
     112        .unmap = term_unmap,
     113        .update = term_buf_update
    104114};
    105115
     
    331341
    332342        bool update = false;
    333         sysarg_t sx = 0/*term->widget.hpos*/;
    334         sysarg_t sy = 0/*term->widget.vpos*/;
     343        sysarg_t sx = 0;
     344        sysarg_t sy = 0;
    335345
    336346        if (term_update_scroll(term, &pixelmap, sx, sy)) {
     
    343353                                charfield_t *back_field =
    344354                                    chargrid_charfield_at(term->backbuf, x, y);
    345                                 bool update = false;
     355                                bool cupdate = false;
    346356
    347357                                if ((front_field->flags & CHAR_FLAG_DIRTY) ==
     
    349359                                        if (front_field->ch != back_field->ch) {
    350360                                                back_field->ch = front_field->ch;
    351                                                 update = true;
     361                                                cupdate = true;
    352362                                        }
    353363
     
    355365                                            back_field->attrs)) {
    356366                                                back_field->attrs = front_field->attrs;
    357                                                 update = true;
     367                                                cupdate = true;
    358368                                        }
    359369
     
    361371                                }
    362372
    363                                 if (update) {
     373                                if (cupdate) {
    364374                                        term_update_char(term, &pixelmap, sx, sy, x, y);
    365375                                        update = true;
     
    524534                term_write_char(term, str_decode(data, &off, size));
    525535
     536        gfx_update(term->gc);
    526537        *nwritten = size;
    527538        return EOK;
     
    533544
    534545        term_update(term);
     546        gfx_update(term->gc);
    535547}
    536548
     
    544556
    545557        term_update(term);
     558        gfx_update(term->gc);
    546559}
    547560
     
    555568
    556569        term_update(term);
     570        gfx_update(term->gc);
    557571}
    558572
     
    626640
    627641        term_update(term);
     642        gfx_update(term->gc);
    628643}
    629644
     
    637652        free(ev);
    638653        return EOK;
     654}
     655
     656/** Create shared buffer for efficient rendering.
     657 *
     658 * @param srv Console server
     659 * @param cols Number of columns in buffer
     660 * @param rows Number of rows in buffer
     661 * @param rbuf Place to store pointer to new sharable buffer
     662 *
     663 * @return EOK on sucess or an error code
     664 */
     665static errno_t term_map(con_srv_t *srv, sysarg_t cols, sysarg_t rows,
     666    charfield_t **rbuf)
     667{
     668        terminal_t *term = srv_to_terminal(srv);
     669        void *buf;
     670
     671        fibril_mutex_lock(&term->mtx);
     672
     673        if (term->ubuf != NULL) {
     674                fibril_mutex_unlock(&term->mtx);
     675                return EBUSY;
     676        }
     677
     678        buf = as_area_create(AS_AREA_ANY, cols * rows * sizeof(charfield_t),
     679            AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE, AS_AREA_UNPAGED);
     680        if (buf == AS_MAP_FAILED) {
     681                fibril_mutex_unlock(&term->mtx);
     682                return ENOMEM;
     683        }
     684
     685        term->ucols = cols;
     686        term->urows = rows;
     687        term->ubuf = buf;
     688        fibril_mutex_unlock(&term->mtx);
     689
     690        *rbuf = buf;
     691        return EOK;
     692}
     693
     694/** Delete shared buffer.
     695 *
     696 * @param srv Console server
     697 */
     698static void term_unmap(con_srv_t *srv)
     699{
     700        terminal_t *term = srv_to_terminal(srv);
     701        void *buf;
     702
     703        fibril_mutex_lock(&term->mtx);
     704
     705        buf = term->ubuf;
     706        term->ubuf = NULL;
     707
     708        if (buf != NULL)
     709                as_area_destroy(buf);
     710
     711        fibril_mutex_unlock(&term->mtx);
     712}
     713
     714/** Update area of terminal from shared buffer.
     715 *
     716 * @param srv Console server
     717 * @param c0 Column coordinate of top-left corner (inclusive)
     718 * @param r0 Row coordinate of top-left corner (inclusive)
     719 * @param c1 Column coordinate of bottom-right corner (exclusive)
     720 * @param r1 Row coordinate of bottom-right corner (exclusive)
     721 */
     722static void term_buf_update(con_srv_t *srv, sysarg_t c0, sysarg_t r0,
     723    sysarg_t c1, sysarg_t r1)
     724{
     725        terminal_t *term = srv_to_terminal(srv);
     726        charfield_t *ch;
     727        sysarg_t col, row;
     728
     729        fibril_mutex_lock(&term->mtx);
     730
     731        if (term->ubuf == NULL) {
     732                fibril_mutex_unlock(&term->mtx);
     733                return;
     734        }
     735
     736        /* Make sure we have meaningful coordinates, within bounds */
     737
     738        if (c1 > term->ucols)
     739                c1 = term->ucols;
     740        if (c1 > term->cols)
     741                c1 = term->cols;
     742        if (c0 >= c1) {
     743                fibril_mutex_unlock(&term->mtx);
     744                return;
     745        }
     746        if (r1 > term->urows)
     747                r1 = term->urows;
     748        if (r1 > term->rows)
     749                r1 = term->rows;
     750        if (r0 >= r1) {
     751                fibril_mutex_unlock(&term->mtx);
     752                return;
     753        }
     754
     755        /* Update front buffer from user buffer */
     756
     757        for (row = r0; row < r1; row++) {
     758                for (col = c0; col < c1; col++) {
     759                        ch = chargrid_charfield_at(term->frontbuf, col, row);
     760                        *ch = term->ubuf[row * term->ucols + col];
     761                }
     762        }
     763
     764        fibril_mutex_unlock(&term->mtx);
     765
     766        /* Update terminal */
     767        term_update(term);
     768        gfx_update(term->gc);
    639769}
    640770
     
    688818        term->is_focused = true;
    689819        term_update(term);
     820        gfx_update(term->gc);
    690821}
    691822
     
    712843        sysarg_t sy = -term->off.y;
    713844
    714         if (event->type == POS_PRESS) {
     845        if (event->type == POS_PRESS || event->type == POS_RELEASE) {
    715846                cevent.type = CEV_POS;
    716847                cevent.ev.pos.type = event->type;
     
    731862        term->is_focused = false;
    732863        term_update(term);
     864        gfx_update(term->gc);
    733865}
    734866
Note: See TracChangeset for help on using the changeset viewer.