Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/hid/console/console.c

    r68a552f rb48e680f  
    6363typedef struct {
    6464        atomic_flag refcnt;      /**< Connection reference count */
    65         prodcons_t input_pc;  /**< Incoming keyboard events */
     65        prodcons_t input_pc;  /**< Incoming console events */
    6666
    6767        /**
     
    9999static sysarg_t cols;
    100100static sysarg_t rows;
     101
     102/** Mouse pointer X coordinate */
     103static int pointer_x;
     104/** Mouse pointer Y coordinate */
     105static int pointer_y;
     106/** Character under mouse cursor */
     107static charfield_t pointer_bg;
     108
     109static int mouse_scale_x = 4;
     110static int mouse_scale_y = 8;
    101111
    102112/** Array of data for virtual consoles */
     
    114124static errno_t input_ev_abs_move(input_t *, unsigned, unsigned, unsigned, unsigned);
    115125static errno_t input_ev_button(input_t *, int, int);
     126static errno_t input_ev_dclick(input_t *, int);
    116127
    117128static input_ev_ops_t input_ev_ops = {
     
    121132        .move = input_ev_move,
    122133        .abs_move = input_ev_abs_move,
    123         .button = input_ev_button
     134        .button = input_ev_button,
     135        .dclick = input_ev_dclick
    124136};
    125137
     
    139151static void cons_set_rgb_color(con_srv_t *, pixel_t, pixel_t);
    140152static void cons_set_cursor_visibility(con_srv_t *, bool);
     153static errno_t cons_set_caption(con_srv_t *, const char *);
    141154static errno_t cons_get_event(con_srv_t *, cons_event_t *);
    142155static errno_t cons_map(con_srv_t *, sysarg_t, sysarg_t, charfield_t **);
     
    160173        .set_rgb_color = cons_set_rgb_color,
    161174        .set_cursor_visibility = cons_set_cursor_visibility,
     175        .set_caption = cons_set_caption,
    162176        .get_event = cons_get_event,
    163177        .map = cons_map,
     
    165179        .update = cons_buf_update
    166180};
     181
     182static void pointer_draw(void);
     183static void pointer_undraw(void);
    167184
    168185static console_t *srv_to_console(con_srv_t *srv)
     
    231248
    232249        fibril_mutex_lock(&switch_mtx);
     250        pointer_undraw();
    233251
    234252        if (cons == active_console) {
     
    239257        active_console = cons;
    240258
     259        pointer_draw();
    241260        fibril_mutex_unlock(&switch_mtx);
    242261
    243262        cons_damage(cons);
     263}
     264
     265/** Draw mouse pointer. */
     266static void pointer_draw(void)
     267{
     268        charfield_t *ch;
     269        int col, row;
     270
     271        /* Downscale coordinates to text resolution */
     272        col = pointer_x / mouse_scale_x;
     273        row = pointer_y / mouse_scale_y;
     274
     275        /* Make sure they are in range */
     276        if (col < 0 || row < 0 || col >= (int)cols || row >= (int)rows)
     277                return;
     278
     279        ch = chargrid_charfield_at(active_console->frontbuf, col, row);
     280
     281        /*
     282         * Store background attributes for undrawing the pointer.
     283         * This is necessary as styles cannot be inverted with
     284         * round trip (unlike RGB or INDEX)
     285         */
     286        pointer_bg = *ch;
     287
     288        /* In general the color should be a one's complement of the background */
     289        if (ch->attrs.type == CHAR_ATTR_INDEX) {
     290                ch->attrs.val.index.bgcolor ^= 0xf;
     291                ch->attrs.val.index.fgcolor ^= 0xf;
     292        } else if (ch->attrs.type == CHAR_ATTR_RGB) {
     293                ch->attrs.val.rgb.fgcolor ^= 0xffffff;
     294                ch->attrs.val.rgb.bgcolor ^= 0xffffff;
     295        } else if (ch->attrs.type == CHAR_ATTR_STYLE) {
     296                /* Don't have a proper inverse for each style */
     297                if (ch->attrs.val.style == STYLE_INVERTED)
     298                        ch->attrs.val.style = STYLE_NORMAL;
     299                else
     300                        ch->attrs.val.style = STYLE_INVERTED;
     301        }
     302
     303        /* Make sure the cell gets updated */
     304        ch->flags |= CHAR_FLAG_DIRTY;
     305}
     306
     307/** Undraw mouse pointer. */
     308static void pointer_undraw(void)
     309{
     310        charfield_t *ch;
     311        int col, row;
     312
     313        col = pointer_x / mouse_scale_x;
     314        row = pointer_y / mouse_scale_y;
     315        if (col < 0 || row < 0 || col >= (int)cols || row >= (int)rows)
     316                return;
     317
     318        ch = chargrid_charfield_at(active_console->frontbuf, col, row);
     319        *ch = pointer_bg;
     320        ch->flags |= CHAR_FLAG_DIRTY;
     321}
     322
     323/** Queue console event.
     324 *
     325 * @param cons Console
     326 * @param ev Console event
     327 */
     328static void console_queue_cons_event(console_t *cons, cons_event_t *ev)
     329{
     330        /* Got key press/release event */
     331        cons_event_t *event =
     332            (cons_event_t *) malloc(sizeof(cons_event_t));
     333        if (event == NULL)
     334                return;
     335
     336        *event = *ev;
     337        link_initialize(&event->link);
     338
     339        prodcons_produce(&cons->input_pc, &event->link);
    244340}
    245341
     
    264360    keymod_t mods, char32_t c)
    265361{
     362        cons_event_t event;
     363
    266364        if ((key >= KC_F1) && (key <= KC_F1 + CONSOLE_COUNT) &&
    267365            ((mods & KM_CTRL) == 0)) {
     
    269367        } else {
    270368                /* Got key press/release event */
    271                 kbd_event_t *event =
    272                     (kbd_event_t *) malloc(sizeof(kbd_event_t));
    273                 if (event == NULL) {
    274                         return ENOMEM;
    275                 }
    276 
    277                 link_initialize(&event->link);
    278                 event->type = type;
    279                 event->key = key;
    280                 event->mods = mods;
    281                 event->c = c;
    282 
    283                 prodcons_produce(&active_console->input_pc,
    284                     &event->link);
    285         }
    286 
    287         return EOK;
     369                event.type = CEV_KEY;
     370
     371                event.ev.key.type = type;
     372                event.ev.key.key = key;
     373                event.ev.key.mods = mods;
     374                event.ev.key.c = c;
     375
     376                console_queue_cons_event(active_console, &event);
     377        }
     378
     379        return EOK;
     380}
     381
     382/** Update pointer position.
     383 *
     384 * @param new_x New X coordinate (in pixels)
     385 * @param new_y New Y coordinate (in pixels)
     386 */
     387static void pointer_update(int new_x, int new_y)
     388{
     389        bool upd_pointer;
     390
     391        /* Make sure coordinates are in range */
     392
     393        if (new_x < 0)
     394                new_x = 0;
     395        if (new_x >= (int)cols * mouse_scale_x)
     396                new_x = cols * mouse_scale_x - 1;
     397        if (new_y < 0)
     398                new_y = 0;
     399        if (new_y >= (int)rows * mouse_scale_y)
     400                new_y = rows * mouse_scale_y - 1;
     401
     402        /* Determine if pointer moved to a different character cell */
     403        upd_pointer = (new_x / mouse_scale_x != pointer_x / mouse_scale_x) ||
     404            (new_y / mouse_scale_y != pointer_y / mouse_scale_y);
     405
     406        if (upd_pointer)
     407                pointer_undraw();
     408
     409        /* Store new pointer position */
     410        pointer_x = new_x;
     411        pointer_y = new_y;
     412
     413        if (upd_pointer) {
     414                pointer_draw();
     415                cons_update(active_console);
     416        }
    288417}
    289418
    290419static errno_t input_ev_move(input_t *input, int dx, int dy)
    291420{
     421        pointer_update(pointer_x + dx, pointer_y + dy);
    292422        return EOK;
    293423}
     
    296426    unsigned max_x, unsigned max_y)
    297427{
     428        pointer_update(mouse_scale_x * cols * x / max_x, mouse_scale_y * rows * y / max_y);
    298429        return EOK;
    299430}
     
    301432static errno_t input_ev_button(input_t *input, int bnum, int bpress)
    302433{
     434        cons_event_t event;
     435
     436        event.type = CEV_POS;
     437        event.ev.pos.type = bpress ? POS_PRESS : POS_RELEASE;
     438        event.ev.pos.btn_num = bnum;
     439        event.ev.pos.hpos = pointer_x / mouse_scale_x;
     440        event.ev.pos.vpos = pointer_y / mouse_scale_y;
     441
     442        console_queue_cons_event(active_console, &event);
     443        return EOK;
     444}
     445
     446static errno_t input_ev_dclick(input_t *input, int bnum)
     447{
     448        cons_event_t event;
     449
     450        event.type = CEV_POS;
     451        event.ev.pos.type = POS_DCLICK;
     452        event.ev.pos.btn_num = bnum;
     453        event.ev.pos.hpos = pointer_x / mouse_scale_x;
     454        event.ev.pos.vpos = pointer_y / mouse_scale_y;
     455
     456        console_queue_cons_event(active_console, &event);
    303457        return EOK;
    304458}
     
    310464
    311465        fibril_mutex_lock(&cons->mtx);
     466        pointer_undraw();
    312467
    313468        switch (ch) {
     
    327482        }
    328483
     484        pointer_draw();
    329485        fibril_mutex_unlock(&cons->mtx);
    330486
     
    336492{
    337493        fibril_mutex_lock(&cons->mtx);
     494        pointer_undraw();
    338495        chargrid_set_cursor_visibility(cons->frontbuf, visible);
     496        pointer_draw();
    339497        fibril_mutex_unlock(&cons->mtx);
    340498
     
    379537                if (pos < size) {
    380538                        link_t *link = prodcons_consume(&cons->input_pc);
    381                         kbd_event_t *event = list_get_instance(link, kbd_event_t, link);
     539                        cons_event_t *event = list_get_instance(link,
     540                            cons_event_t, link);
    382541
    383542                        /* Accept key presses of printable chars only. */
    384                         if ((event->type == KEY_PRESS) && (event->c != 0)) {
    385                                 char32_t tmp[2] = { event->c, 0 };
     543                        if (event->type == CEV_KEY && event->ev.key.type == KEY_PRESS &&
     544                            (event->ev.key.c != 0)) {
     545                                char32_t tmp[2] = { event->ev.key.c, 0 };
    386546                                wstr_to_str(cons->char_remains, UTF8_CHAR_BUFFER_SIZE, tmp);
    387547                                cons->char_remains_len = str_size(cons->char_remains);
     
    420580
    421581        fibril_mutex_lock(&cons->mtx);
     582        pointer_undraw();
    422583        chargrid_clear(cons->frontbuf);
     584        pointer_draw();
    423585        fibril_mutex_unlock(&cons->mtx);
    424586
     
    431593
    432594        fibril_mutex_lock(&cons->mtx);
     595        pointer_undraw();
    433596        chargrid_set_cursor(cons->frontbuf, col, row);
     597        pointer_draw();
    434598        fibril_mutex_unlock(&cons->mtx);
    435599
     
    507671}
    508672
     673static errno_t cons_set_caption(con_srv_t *srv, const char *caption)
     674{
     675        console_t *cons = srv_to_console(srv);
     676
     677        (void) cons;
     678        (void) caption;
     679        return EOK;
     680}
     681
    509682static errno_t cons_get_event(con_srv_t *srv, cons_event_t *event)
    510683{
    511684        console_t *cons = srv_to_console(srv);
    512685        link_t *link = prodcons_consume(&cons->input_pc);
    513         kbd_event_t *kevent = list_get_instance(link, kbd_event_t, link);
    514 
    515         event->type = CEV_KEY;
    516         event->ev.key = *kevent;
    517 
    518         free(kevent);
     686        cons_event_t *cevent = list_get_instance(link, cons_event_t, link);
     687
     688        *event = *cevent;
     689        free(cevent);
    519690        return EOK;
    520691}
     
    621792        /* Update front buffer from user buffer */
    622793
     794        pointer_undraw();
     795
    623796        for (row = r0; row < r1; row++) {
    624797                for (col = c0; col < c1; col++) {
     
    628801        }
    629802
     803        pointer_draw();
    630804        fibril_mutex_unlock(&cons->mtx);
    631805
Note: See TracChangeset for help on using the changeset viewer.