Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 913add60 in mainline


Ignore:
Timestamp:
2022-10-31T10:53:53Z (5 weeks ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
master
Children:
1b92d4b
Parents:
7cc30e9
git-author:
Jiri Svoboda <jiri@…> (2022-10-30 10:53:48)
git-committer:
Jiri Svoboda <jiri@…> (2022-10-31 10:53:53)
Message:

Deliver WM events for windows being added and removed

Location:
uspace
Files:
4 added
12 edited

Legend:

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

    r7cc30e9 r913add60  
    5353};
    5454
     55static void taskbar_wm_window_added(void *, sysarg_t);
     56static void taskbar_wm_window_removed(void *, sysarg_t);
     57
     58static wndmgt_cb_t taskbar_wndmgt_cb = {
     59        .window_added = taskbar_wm_window_added,
     60        .window_removed = taskbar_wm_window_removed
     61};
     62
    5563/** Window close button was clicked.
    5664 *
     
    8997
    9098        if (wndmgt_svc != NULL) {
    91                 rc = wndmgt_open(wndmgt_svc, NULL, NULL, &taskbar->wndmgt);
     99                rc = wndmgt_open(wndmgt_svc, &taskbar_wndmgt_cb,
     100                    (void *)taskbar, &taskbar->wndmgt);
    92101                if (rc != EOK)
    93102                        goto error;
     
    241250}
    242251
     252/** Handle WM window added event.
     253 *
     254 * @param arg Argument (taskbar_t *)
     255 * @param wnd_id Window ID
     256 */
     257static void taskbar_wm_window_added(void *arg, sysarg_t wnd_id)
     258{
     259        taskbar_t *taskbar = (taskbar_t *)arg;
     260
     261        printf("wm_window_added: taskbar=%p wnd_id=%zu\n",
     262            (void *)taskbar, wnd_id);
     263}
     264
     265/** Handle WM window removed event.
     266 *
     267 * @param arg Argument (taskbar_t *)
     268 * @param wnd_id Window ID
     269 */
     270static void taskbar_wm_window_removed(void *arg, sysarg_t wnd_id)
     271{
     272        taskbar_t *taskbar = (taskbar_t *)arg;
     273
     274        printf("wm_window_removed: taskbar=%p wnd_id=%zu\n",
     275            (void *)taskbar, wnd_id);
     276}
     277
    243278/** @}
    244279 */
  • uspace/srv/hid/display/client.c

    r7cc30e9 r913add60  
    181181 * @param ewindow Place to store pointer to window receiving the event
    182182 * @param event Place to store event
    183  * @return Graphic context
     183 * @return EOK on success, ENOENT if event queue is empty
    184184 */
    185185errno_t ds_client_get_event(ds_client_t *client, ds_window_t **ewindow,
  • uspace/srv/hid/display/display.c

    r7cc30e9 r913add60  
    4545#include "cursimg.h"
    4646#include "cursor.h"
     47#include "display.h"
    4748#include "seat.h"
    4849#include "window.h"
    49 #include "display.h"
     50#include "wmclient.h"
    5051
    5152static gfx_context_t *ds_display_get_unbuf_gc(ds_display_t *);
     
    9697        fibril_mutex_initialize(&disp->lock);
    9798        list_initialize(&disp->clients);
     99        list_initialize(&disp->wmclients);
    98100        disp->next_wnd_id = 1;
    99101        list_initialize(&disp->ddevs);
     
    115117{
    116118        assert(list_empty(&disp->clients));
     119        assert(list_empty(&disp->wmclients));
    117120        assert(list_empty(&disp->seats));
    118121        /* XXX destroy cursors */
     
    203206
    204207        return list_get_instance(link, ds_client_t, lclients);
     208}
     209
     210/** Add WM client to display.
     211 *
     212 * @param disp Display
     213 * @param wmclient WM client
     214 */
     215void ds_display_add_wmclient(ds_display_t *disp, ds_wmclient_t *wmclient)
     216{
     217        assert(wmclient->display == NULL);
     218        assert(!link_used(&wmclient->lwmclients));
     219
     220        wmclient->display = disp;
     221        list_append(&wmclient->lwmclients, &disp->wmclients);
     222}
     223
     224/** Remove WM client from display.
     225 *
     226 * @param wmclient WM client
     227 */
     228void ds_display_remove_wmclient(ds_wmclient_t *wmclient)
     229{
     230        list_remove(&wmclient->lwmclients);
     231        wmclient->display = NULL;
     232}
     233
     234/** Get first WM client in display.
     235 *
     236 * @param disp Display
     237 * @return First WM client or @c NULL if there is none
     238 */
     239ds_wmclient_t *ds_display_first_wmclient(ds_display_t *disp)
     240{
     241        link_t *link = list_first(&disp->wmclients);
     242
     243        if (link == NULL)
     244                return NULL;
     245
     246        return list_get_instance(link, ds_wmclient_t, lwmclients);
     247}
     248
     249/** Get next WM client in display.
     250 *
     251 * @param wmclient Current WM client
     252 * @return Next WM client or @c NULL if there is none
     253 */
     254ds_wmclient_t *ds_display_next_wmclient(ds_wmclient_t *wmclient)
     255{
     256        link_t *link = list_next(&wmclient->lwmclients,
     257            &wmclient->display->wmclients);
     258
     259        if (link == NULL)
     260                return NULL;
     261
     262        return list_get_instance(link, ds_wmclient_t, lwmclients);
    205263}
    206264
     
    262320void ds_display_add_window(ds_display_t *display, ds_window_t *wnd)
    263321{
     322        ds_wmclient_t *wmclient;
     323
    264324        assert(wnd->display == NULL);
    265325        assert(!link_used(&wnd->ldwindows));
     
    267327        wnd->display = display;
    268328        list_prepend(&wnd->ldwindows, &display->windows);
     329
     330        /* Notify window managers about the new window */
     331        wmclient = ds_display_first_wmclient(display);
     332        while (wmclient != NULL) {
     333                ds_wmclient_post_wnd_added_event(wmclient, wnd->id);
     334                wmclient = ds_display_next_wmclient(wmclient);
     335        }
    269336}
    270337
     
    275342void ds_display_remove_window(ds_window_t *wnd)
    276343{
     344        ds_wmclient_t *wmclient;
     345        ds_display_t *display;
     346
     347        display = wnd->display;
     348
    277349        list_remove(&wnd->ldwindows);
    278350        wnd->display = NULL;
     351
     352        /* Notify window managers about the removed window */
     353        wmclient = ds_display_first_wmclient(display);
     354        while (wmclient != NULL) {
     355                ds_wmclient_post_wnd_removed_event(wmclient, wnd->id);
     356                wmclient = ds_display_next_wmclient(wmclient);
     357        }
     358}
     359
     360/** Move window to top.
     361 *
     362 * @param display Display
     363 * @param wnd Window
     364 */
     365void ds_display_window_to_top(ds_window_t *wnd)
     366{
     367        assert(wnd->display != NULL);
     368        assert(link_used(&wnd->ldwindows));
     369
     370        list_remove(&wnd->ldwindows);
     371        list_prepend(&wnd->ldwindows, &wnd->display->windows);
    279372}
    280373
  • uspace/srv/hid/display/display.h

    r7cc30e9 r913add60  
    11/*
    2  * Copyright (c) 2019 Jiri Svoboda
     2 * Copyright (c) 2022 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    4848#include "types/display/ptd_event.h"
    4949#include "types/display/seat.h"
     50#include "types/display/wmclient.h"
    5051
    5152extern errno_t ds_display_create(gfx_context_t *, ds_display_flags_t,
     
    5960extern ds_client_t *ds_display_first_client(ds_display_t *);
    6061extern ds_client_t *ds_display_next_client(ds_client_t *);
     62extern void ds_display_add_wmclient(ds_display_t *, ds_wmclient_t *);
     63extern void ds_display_remove_wmclient(ds_wmclient_t *);
     64extern ds_wmclient_t *ds_display_first_wmclient(ds_display_t *);
     65extern ds_wmclient_t *ds_display_next_wmclient(ds_wmclient_t *);
    6166extern ds_window_t *ds_display_find_window(ds_display_t *, ds_wnd_id_t);
    6267extern ds_window_t *ds_display_window_by_pos(ds_display_t *, gfx_coord2_t *);
    6368extern void ds_display_add_window(ds_display_t *, ds_window_t *);
    6469extern void ds_display_remove_window(ds_window_t *);
     70extern void ds_display_window_to_top(ds_window_t *);
    6571extern ds_window_t *ds_display_first_window(ds_display_t *);
    6672extern ds_window_t *ds_display_last_window(ds_display_t *);
  • uspace/srv/hid/display/main.c

    r7cc30e9 r913add60  
    5656#include "seat.h"
    5757#include "window.h"
     58#include "wmclient.h"
    5859#include "wmops.h"
    5960
    6061static void display_client_conn(ipc_call_t *, void *);
    6162static void display_client_ev_pending(void *);
     63static void display_wmclient_ev_pending(void *);
    6264static void display_gc_conn(ipc_call_t *, void *);
    6365static void display_wndmgt_conn(ipc_call_t *, void *);
     
    8082};
    8183
     84static ds_wmclient_cb_t display_wmclient_cb = {
     85        .ev_pending = display_wmclient_ev_pending
     86};
     87
    8288static void display_client_ev_pending(void *arg)
    8389{
     
    8591
    8692        display_srv_ev_pending(srv);
     93}
     94
     95static void display_wmclient_ev_pending(void *arg)
     96{
     97        wndmgt_srv_t *srv = (wndmgt_srv_t *) arg;
     98
     99        wndmgt_srv_ev_pending(srv);
    87100}
    88101
     
    189202        if (svc_id != 0) {
    190203                /* Create client object */
     204                ds_display_lock(disp);
    191205                rc = ds_client_create(disp, &display_client_cb, &srv, &client);
     206                ds_display_unlock(disp);
    192207                if (rc != EOK) {
    193208                        async_answer_0(icall, ENOMEM);
     
    243258{
    244259        ds_display_t *disp = (ds_display_t *) arg;
     260        errno_t rc;
    245261        wndmgt_srv_t srv;
     262        ds_wmclient_t *wmclient = NULL;
     263
     264        /* Create WM client object */
     265        ds_display_lock(disp);
     266        rc = ds_wmclient_create(disp, &display_wmclient_cb, &srv, &wmclient);
     267        ds_display_unlock(disp);
     268        if (rc != EOK) {
     269                async_answer_0(icall, ENOMEM);
     270                return;
     271        }
    246272
    247273        /* Set up protocol structure */
    248274        wndmgt_srv_initialize(&srv);
    249275        srv.ops = &wndmgt_srv_ops;
    250         srv.arg = disp;
     276        srv.arg = wmclient;
    251277
    252278        /* Handle connection */
    253279        wndmgt_conn(icall, &srv);
     280
     281        ds_display_lock(disp);
     282        ds_wmclient_destroy(wmclient);
     283        ds_display_unlock(disp);
    254284}
    255285
  • uspace/srv/hid/display/meson.build

    r7cc30e9 r913add60  
    4242        'seat.c',
    4343        'window.c',
     44        'wmclient.c',
    4445        'wmops.c',
    4546)
     
    5455        'seat.c',
    5556        'window.c',
     57        'wmclient.c',
    5658        'test/client.c',
    5759        'test/clonegc.c',
     
    6163        'test/seat.c',
    6264        'test/window.c',
     65        'test/wmclient.c',
    6366)
  • uspace/srv/hid/display/test/display.c

    r7cc30e9 r913add60  
    11/*
    2  * Copyright (c) 2019 Jiri Svoboda
     2 * Copyright (c) 2022 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    3636#include "../seat.h"
    3737#include "../window.h"
     38#include "../wmclient.h"
    3839
    3940PCUT_INIT;
     
    4748};
    4849
     50static void test_ds_wmev_pending(void *);
     51
     52static ds_wmclient_cb_t test_ds_wmclient_cb = {
     53        .ev_pending = test_ds_wmev_pending
     54};
     55
    4956static void test_ds_ev_pending(void *arg)
    5057{
     
    5360}
    5461
     62static void test_ds_wmev_pending(void *arg)
     63{
     64        bool *called_cb = (bool *) arg;
     65        *called_cb = true;
     66}
     67
    5568/** Display creation and destruction. */
    5669PCUT_TEST(display_create_destroy)
     
    8699
    87100        ds_client_destroy(client);
     101        ds_display_destroy(disp);
     102}
     103
     104/** Basic WM client operation. */
     105PCUT_TEST(display_wmclient)
     106{
     107        ds_display_t *disp;
     108        ds_wmclient_t *wmclient;
     109        ds_wmclient_t *c0, *c1;
     110        errno_t rc;
     111
     112        rc = ds_display_create(NULL, df_none, &disp);
     113        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     114
     115        rc = ds_wmclient_create(disp, &test_ds_wmclient_cb, NULL, &wmclient);
     116        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     117
     118        c0 = ds_display_first_wmclient(disp);
     119        PCUT_ASSERT_EQUALS(c0, wmclient);
     120
     121        c1 = ds_display_next_wmclient(c0);
     122        PCUT_ASSERT_NULL(c1);
     123
     124        ds_wmclient_destroy(wmclient);
    88125        ds_display_destroy(disp);
    89126}
     
    150187        wnd = ds_display_find_window(disp, w0->id + 1);
    151188        PCUT_ASSERT_NULL(wnd);
     189
     190        ds_window_destroy(w0);
     191        ds_window_destroy(w1);
     192        ds_seat_destroy(seat);
     193        ds_client_destroy(client);
     194        ds_display_destroy(disp);
     195}
     196
     197/** Test ds_display_window_to_top() */
     198PCUT_TEST(display_window_to_top)
     199{
     200        ds_display_t *disp;
     201        ds_client_t *client;
     202        ds_seat_t *seat;
     203        ds_window_t *w0;
     204        ds_window_t *w1;
     205        display_wnd_params_t params;
     206        bool called_cb = false;
     207        errno_t rc;
     208
     209        rc = ds_display_create(NULL, df_none, &disp);
     210        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     211
     212        rc = ds_client_create(disp, &test_ds_client_cb, &called_cb, &client);
     213        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     214
     215        rc = ds_seat_create(disp, &seat);
     216        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     217
     218        display_wnd_params_init(&params);
     219        params.rect.p0.x = params.rect.p0.y = 0;
     220        params.rect.p1.x = params.rect.p1.y = 100;
     221
     222        rc = ds_window_create(client, &params, &w0);
     223        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     224
     225        rc = ds_window_create(client, &params, &w1);
     226        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     227
     228        PCUT_ASSERT_EQUALS(w1, ds_display_first_window(disp));
     229        ds_display_window_to_top(w0);
     230        PCUT_ASSERT_EQUALS(w0, ds_display_first_window(disp));
    152231
    153232        ds_window_destroy(w0);
  • uspace/srv/hid/display/test/main.c

    r7cc30e9 r913add60  
    3737PCUT_IMPORT(seat);
    3838PCUT_IMPORT(window);
     39PCUT_IMPORT(wmclient);
    3940
    4041PCUT_MAIN();
  • uspace/srv/hid/display/test/window.c

    r7cc30e9 r913add60  
    5151};
    5252
     53/** Test creating and destroying window */
     54PCUT_TEST(create_destroy)
     55{
     56        ds_display_t *disp;
     57        ds_client_t *client;
     58        ds_seat_t *seat;
     59        ds_window_t *wnd;
     60        display_wnd_params_t params;
     61        errno_t rc;
     62
     63        rc = ds_display_create(NULL, df_none, &disp);
     64        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     65
     66        rc = ds_client_create(disp, NULL, NULL, &client);
     67        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     68
     69        rc = ds_seat_create(disp, &seat);
     70        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     71
     72        display_wnd_params_init(&params);
     73        params.rect.p0.x = params.rect.p0.y = 0;
     74        params.rect.p1.x = params.rect.p1.y = 10;
     75
     76        rc = ds_window_create(client, &params, &wnd);
     77        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     78
     79        ds_window_destroy(wnd);
     80        ds_seat_destroy(seat);
     81        ds_client_destroy(client);
     82        ds_display_destroy(disp);
     83}
     84
     85/** Test ds_window_bring_to_top() brings window to top */
     86PCUT_TEST(bring_to_top)
     87{
     88        ds_display_t *disp;
     89        ds_client_t *client;
     90        ds_seat_t *seat;
     91        ds_window_t *w1;
     92        ds_window_t *w2;
     93        display_wnd_params_t params;
     94        errno_t rc;
     95
     96        rc = ds_display_create(NULL, df_none, &disp);
     97        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     98
     99        rc = ds_client_create(disp, NULL, NULL, &client);
     100        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     101
     102        rc = ds_seat_create(disp, &seat);
     103        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     104
     105        display_wnd_params_init(&params);
     106        params.rect.p0.x = params.rect.p0.y = 0;
     107        params.rect.p1.x = params.rect.p1.y = 10;
     108
     109        rc = ds_window_create(client, &params, &w1);
     110        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     111
     112        rc = ds_window_create(client, &params, &w2);
     113        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     114
     115        /* w2 should be on the top */
     116        PCUT_ASSERT_EQUALS(w2, ds_display_first_window(disp));
     117
     118        /* Bring w1 to top */
     119        ds_window_bring_to_top(w1);
     120
     121        /* Now w1 should be on the top */
     122        PCUT_ASSERT_EQUALS(w1, ds_display_first_window(disp));
     123
     124        ds_window_destroy(w1);
     125        ds_window_destroy(w2);
     126        ds_seat_destroy(seat);
     127        ds_client_destroy(client);
     128        ds_display_destroy(disp);
     129}
     130
    53131/** Test ds_window_resize(). */
    54132PCUT_TEST(window_resize)
  • uspace/srv/hid/display/types/display/display.h

    r7cc30e9 r913add60  
    6262        /** Clients (of ds_client_t) */
    6363        list_t clients;
     64        /** WM clients (of ds_wmclient_t) */
     65        list_t wmclients;
    6466
    6567        /** Next ID to assign to a window.
  • uspace/srv/hid/display/window.c

    r7cc30e9 r913add60  
    197197void ds_window_bring_to_top(ds_window_t *wnd)
    198198{
    199         ds_display_t *disp = wnd->display;
    200 
    201         ds_display_remove_window(wnd);
    202         ds_display_add_window(disp, wnd);
     199        ds_display_window_to_top(wnd);
    203200        (void) ds_display_paint(wnd->display, NULL);
    204201}
  • uspace/srv/hid/display/wmops.c

    r7cc30e9 r913add60  
    4040#include <wndmgt_srv.h>
    4141#include "display.h"
     42#include "wmclient.h"
    4243
    4344static errno_t dispwm_get_window_list(void *, wndmgt_window_list_t **);
     
    5556};
    5657
     58/** Get window list.
     59 *
     60 * @param arg Argument (WM client)
     61 * @param rlist Place to store pointer to new list
     62 * @return EOK on success or an error code
     63 */
    5764static errno_t dispwm_get_window_list(void *arg, wndmgt_window_list_t **rlist)
    5865{
     66        ds_wmclient_t *wmclient = (ds_wmclient_t *)arg;
    5967        wndmgt_window_list_t *list;
    60         ds_display_t *disp = (ds_display_t *)arg;
    6168        ds_window_t *wnd;
    6269        unsigned i;
     
    6875                return ENOMEM;
    6976
     77        ds_display_lock(wmclient->display);
     78
    7079        /* Count the number of windows */
    7180        list->nwindows = 0;
    72         wnd = ds_display_first_window(disp);
     81        wnd = ds_display_first_window(wmclient->display);
    7382        while (wnd != NULL) {
    7483                ++list->nwindows;
     
    7988        list->windows = calloc(list->nwindows, sizeof(sysarg_t));
    8089        if (list->windows == NULL) {
     90                ds_display_unlock(wmclient->display);
    8191                free(list);
    8292                return ENOMEM;
     
    8595        /* Fill in window IDs */
    8696        i = 0;
    87         wnd = ds_display_first_window(disp);
     97        wnd = ds_display_first_window(wmclient->display);
    8898        while (wnd != NULL) {
    8999                list->windows[i++] = wnd->id;
     
    91101        }
    92102
     103        ds_display_unlock(wmclient->display);
    93104        *rlist = list;
    94105        return EOK;
    95106}
    96107
     108/** Get window information.
     109 *
     110 * @param arg Argument (WM client)
     111 * @param wnd_id Window ID
     112 * @param rinfo Place to store pointer to new window information structure
     113 * @return EOK on success or an error code
     114 */
    97115static errno_t dispwm_get_window_info(void *arg, sysarg_t wnd_id,
    98116    wndmgt_window_info_t **rinfo)
    99117{
    100         ds_display_t *disp = (ds_display_t *)arg;
     118        ds_wmclient_t *wmclient = (ds_wmclient_t *)arg;
    101119        ds_window_t *wnd;
    102120        wndmgt_window_info_t *info;
     
    104122        log_msg(LOG_DEFAULT, LVL_DEBUG, "dispwm_get_window_info()");
    105123
    106         wnd = ds_display_find_window(disp, wnd_id);
    107         if (wnd == NULL)
     124        ds_display_lock(wmclient->display);
     125        wnd = ds_display_find_window(wmclient->display, wnd_id);
     126        if (wnd == NULL) {
     127                ds_display_unlock(wmclient->display);
    108128                return ENOENT;
     129        }
    109130
    110131        info = calloc(1, sizeof(wndmgt_window_info_t));
    111         if (info == NULL)
     132        if (info == NULL) {
     133                ds_display_unlock(wmclient->display);
    112134                return ENOMEM;
     135        }
    113136
    114137        info->caption = str_dup(wnd->caption);
    115138        if (info->caption == NULL) {
     139                ds_display_unlock(wmclient->display);
    116140                free(info);
    117141                return ENOMEM;
    118142        }
    119143
     144        ds_display_unlock(wmclient->display);
    120145        *rinfo = info;
    121146        return EOK;
    122147}
    123148
     149/** Activate window.
     150 *
     151 * @param arg Argument (WM client)
     152 * @param wnd_id Window ID
     153 * @return EOK on success or an error code
     154 */
    124155static errno_t dispwm_activate_window(void *arg, sysarg_t wnd_id)
    125156{
     
    130161}
    131162
     163/** Close window.
     164 *
     165 * @param arg Argument (WM client)
     166 * @param wnd_id Window ID
     167 * @return EOK on success or an error code
     168 */
    132169static errno_t dispwm_close_window(void *arg, sysarg_t wnd_id)
    133170{
     
    138175}
    139176
     177/** Get window management event.
     178 *
     179 * @param arg Argument (WM client)
     180 * @param ev Place to store event
     181 * @return EOK on success, ENOENT if there are no events
     182 */
    140183static errno_t dispwm_get_event(void *arg, wndmgt_ev_t *ev)
    141184{
    142         return ENOTSUP;
     185        ds_wmclient_t *wmclient = (ds_wmclient_t *)arg;
     186        errno_t rc;
     187
     188        log_msg(LOG_DEFAULT, LVL_DEBUG, "dispwm_get_event()");
     189
     190        ds_display_lock(wmclient->display);
     191        rc = ds_wmclient_get_event(wmclient, ev);
     192        ds_display_unlock(wmclient->display);
     193        return rc;
    143194}
    144195
Note: See TracChangeset for help on using the changeset viewer.