Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/hid/display/seat.c

    r1543d4c rd7f82635  
    11/*
    2  * Copyright (c) 2023 Jiri Svoboda
     2 * Copyright (c) 2021 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    3939#include <gfx/render.h>
    4040#include <stdlib.h>
    41 #include <str.h>
    4241#include "client.h"
    4342#include "cursor.h"
    4443#include "display.h"
    45 #include "idevcfg.h"
    4644#include "seat.h"
    4745#include "window.h"
     
    5351 *
    5452 * @param display Parent display
    55  * @param name Seat name
    5653 * @param rseat Place to store pointer to new seat.
    5754 * @return EOK on success, ENOMEM if out of memory
    5855 */
    59 errno_t ds_seat_create(ds_display_t *display, const char *name,
    60     ds_seat_t **rseat)
     56errno_t ds_seat_create(ds_display_t *display, ds_seat_t **rseat)
    6157{
    6258        ds_seat_t *seat;
    63         ds_seat_t *s0;
    64 
    65         s0 = ds_display_first_seat(display);
    66         while (s0 != NULL) {
    67                 if (str_cmp(s0->name, name) == 0)
    68                         return EEXIST;
    69                 s0 = ds_display_next_seat(s0);
    70         }
    7159
    7260        seat = calloc(1, sizeof(ds_seat_t));
     
    7462                return ENOMEM;
    7563
    76         seat->name = str_dup(name);
    77         if (seat->name == NULL) {
    78                 free(seat);
    79                 return ENOMEM;
    80         }
    81 
    82         list_initialize(&seat->idevcfgs);
    83 
    8464        ds_display_add_seat(display, seat);
    8565        seat->pntpos.x = 0;
     
    8868        seat->client_cursor = display->cursor[dcurs_arrow];
    8969        seat->wm_cursor = NULL;
    90         seat->focus = ds_display_first_window(display);
    9170
    9271        *rseat = seat;
     
    10079void ds_seat_destroy(ds_seat_t *seat)
    10180{
    102         ds_idevcfg_t *idevcfg;
    103 
    104         /* Remove all input device configuration entries pointing to this seat */
    105         idevcfg = ds_seat_first_idevcfg(seat);
    106         while (idevcfg != NULL) {
    107                 ds_idevcfg_destroy(idevcfg);
    108                 idevcfg = ds_seat_first_idevcfg(seat);
    109         }
    110 
    111         /* Remove this seat's focus */
    112         if (seat->focus != NULL)
    113                 ds_window_post_unfocus_event(seat->focus);
    114 
    11581        ds_display_remove_seat(seat);
    116 
    117         free(seat->name);
    11882        free(seat);
    11983}
     
    12690void ds_seat_set_focus(ds_seat_t *seat, ds_window_t *wnd)
    12791{
    128         errno_t rc;
    129 
    13092        if (wnd == seat->focus) {
    13193                /* Focus is not changing */
    13294                return;
    133         }
    134 
    135         if (wnd != NULL) {
    136                 rc = ds_window_unminimize(wnd);
    137                 if (rc != EOK)
    138                         return;
    13995        }
    14096
     
    174130/** Evacuate seat references to window.
    175131 *
    176  * If seat's focus is @a wnd, it will be set to NULL.
     132 * If seat's focus is @a wnd, it will be set to a different window.
    177133 * If seat's popup window is @a wnd, it will be set to NULL.
    178134 *
    179135 * @param seat Seat
    180  * @param wnd Window to evacuate references from
     136 * @param wnd Window to evacuate focus from
    181137 */
    182138void ds_seat_evac_wnd_refs(ds_seat_t *seat, ds_window_t *wnd)
    183139{
    184         if (seat->focus == wnd)
    185                 ds_seat_set_focus(seat, NULL);
     140        ds_window_t *nwnd;
     141
     142        if (seat->focus == wnd) {
     143                nwnd = ds_display_prev_window(wnd);
     144                if (nwnd == NULL)
     145                        nwnd = ds_display_last_window(wnd->display);
     146                if (nwnd == wnd)
     147                        nwnd = NULL;
     148
     149                ds_seat_set_focus(seat, nwnd);
     150        }
    186151
    187152        if (seat->popup == wnd)
     
    189154}
    190155
    191 /** Unfocus window.
    192  *
    193  * If seat's focus is @a wnd, it will be set to a different window
    194  * that is not minimized, preferably not a system window.
    195  *
    196  * @param seat Seat
    197  * @param wnd Window to remove focus from
    198  */
    199 void ds_seat_unfocus_wnd(ds_seat_t *seat, ds_window_t *wnd)
     156/** Switch focus to another window.
     157 *
     158 * @param seat Seat
     159 * @param wnd Window to evacuate focus from
     160 */
     161void ds_seat_switch_focus(ds_seat_t *seat)
    200162{
    201163        ds_window_t *nwnd;
    202164
    203         if (seat->focus != wnd)
    204                 return;
    205 
    206         /* Find alternate window that is neither system nor minimized */
    207         nwnd = ds_window_find_prev(wnd, ~(wndf_minimized | wndf_system));
    208 
    209         if (nwnd == NULL) {
    210                 /* Find alternate window that is not minimized */
    211                 nwnd = ds_window_find_prev(wnd, ~wndf_minimized);
    212         }
    213 
    214         ds_seat_set_focus(seat, nwnd);
    215 }
    216 
    217 /** Switch focus to another window.
    218  *
    219  * @param seat Seat
    220  * @param wnd Window to evacuate focus from
    221  */
    222 void ds_seat_switch_focus(ds_seat_t *seat)
    223 {
    224         ds_window_t *nwnd;
    225 
    226         if (seat->focus != NULL) {
    227                 /* Find alternate window that is not a system window */
    228                 nwnd = ds_window_find_next(seat->focus, ~wndf_system);
    229         } else {
    230                 /* Currently no focus. Focus topmost window. */
    231                 nwnd = ds_display_first_window(seat->display);
    232         }
    233 
    234         /* Only switch focus if there is another window */
     165        if (seat->focus != NULL)
     166                nwnd = ds_display_prev_window(seat->focus);
     167        else
     168                nwnd = NULL;
     169
     170        if (nwnd == NULL)
     171                nwnd = ds_display_last_window(seat->display);
     172
    235173        if (nwnd != NULL)
    236174                ds_seat_set_focus(seat, nwnd);
     
    424362        }
    425363
    426         if (event->type == PTD_PRESS || event->type == PTD_RELEASE ||
    427             event->type == PTD_DCLICK) {
    428                 pevent.pos_id = event->pos_id;
    429                 switch (event->type) {
    430                 case PTD_PRESS:
    431                         pevent.type = POS_PRESS;
    432                         break;
    433                 case PTD_RELEASE:
    434                         pevent.type = POS_RELEASE;
    435                         break;
    436                 case PTD_DCLICK:
    437                         pevent.type = POS_DCLICK;
    438                         break;
    439                 default:
    440                         assert(false);
    441                 }
    442 
     364        if (event->type == PTD_PRESS || event->type == PTD_RELEASE) {
     365                pevent.pos_id = 0;
     366                pevent.type = (event->type == PTD_PRESS) ?
     367                    POS_PRESS : POS_RELEASE;
    443368                pevent.btn_num = event->btn_num;
    444369                pevent.hpos = seat->pntpos.x;
     
    457382                seat->pntpos = npos;
    458383
    459                 pevent.pos_id = event->pos_id;
     384                pevent.pos_id = 0;
    460385                pevent.type = POS_UPDATE;
    461386                pevent.btn_num = 0;
     
    485410                seat->pntpos = npos;
    486411
    487                 pevent.pos_id = event->pos_id;
     412                pevent.pos_id = 0;
    488413                pevent.type = POS_UPDATE;
    489414                pevent.btn_num = 0;
     
    515440        wnd = ds_display_window_by_pos(seat->display, &seat->pntpos);
    516441
     442        /* Click outside popup window */
     443        if (event->type == POS_PRESS && wnd != seat->popup) {
     444                /* Close popup window */
     445                ds_seat_set_popup(seat, NULL);
     446        }
     447
    517448        /* Deliver event to popup window. */
    518         if (seat->popup != NULL && event->type != POS_PRESS) {
     449        if (seat->popup != NULL) {
    519450                rc = ds_window_post_pos_event(seat->popup, event);
    520451                if (rc != EOK)
     
    540471                 * to the same window above.
    541472                 */
    542                 if (wnd != seat->popup || event->type == POS_PRESS) {
     473                if (wnd != seat->popup) {
    543474                        rc = ds_window_post_pos_event(wnd, event);
    544475                        if (rc != EOK)
     
    550481        }
    551482
    552         /* Click outside popup window */
    553         if (event->type == POS_PRESS && wnd != seat->popup) {
    554                 /* Close popup window */
    555                 ds_seat_set_popup(seat, NULL);
    556         }
    557 
    558483        return EOK;
    559484}
     
    572497}
    573498
    574 /** Add input device configuration entry to seat.
    575  *
    576  * @param seat Seat
    577  * @param idevcfg Input device configuration
    578  */
    579 void ds_seat_add_idevcfg(ds_seat_t *seat, ds_idevcfg_t *idevcfg)
    580 {
    581         assert(idevcfg->seat == NULL);
    582         assert(!link_used(&idevcfg->lseatidcfgs));
    583 
    584         idevcfg->seat = seat;
    585         list_append(&idevcfg->lseatidcfgs, &seat->idevcfgs);
    586 }
    587 
    588 /** Remove input device configuration entry from seat.
    589  *
    590  * @param idevcfg Input device configuration entry
    591  */
    592 void ds_seat_remove_idevcfg(ds_idevcfg_t *idevcfg)
    593 {
    594         list_remove(&idevcfg->lseatidcfgs);
    595         idevcfg->seat = NULL;
    596 }
    597 
    598 /** Get first input device configuration entry in seat.
    599  *
    600  * @param disp Display
    601  * @return First input device configuration entry or @c NULL if there is none
    602  */
    603 ds_idevcfg_t *ds_seat_first_idevcfg(ds_seat_t *seat)
    604 {
    605         link_t *link = list_first(&seat->idevcfgs);
    606 
    607         if (link == NULL)
    608                 return NULL;
    609 
    610         return list_get_instance(link, ds_idevcfg_t, lseatidcfgs);
    611 }
    612 
    613 /** Get next input device configuration entry in seat.
    614  *
    615  * @param idevcfg Current input device configuration entry
    616  * @return Next input device configuration entry or @c NULL if there is none
    617  */
    618 ds_idevcfg_t *ds_seat_next_idevcfg(ds_idevcfg_t *idevcfg)
    619 {
    620         link_t *link = list_next(&idevcfg->lseatidcfgs, &idevcfg->seat->idevcfgs);
    621 
    622         if (link == NULL)
    623                 return NULL;
    624 
    625         return list_get_instance(link, ds_idevcfg_t, lseatidcfgs);
    626 }
    627 
    628499/** @}
    629500 */
Note: See TracChangeset for help on using the changeset viewer.