Changeset 9546146 in mainline


Ignore:
Timestamp:
2024-08-23T18:02:06Z (4 months ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
master
Children:
4af6fb1
Parents:
ca95ccd
Message:

Persistently store display/seat configuration.

Location:
uspace/srv/hid/display
Files:
10 edited

Legend:

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

    rca95ccd r9546146  
    11/*
    2  * Copyright (c) 2023 Jiri Svoboda
     2 * Copyright (c) 2024 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    4141#include "display.h"
    4242#include "idevcfg.h"
     43#include "main.h"
    4344#include "seat.h"
    4445#include "cfgclient.h"
     
    181182
    182183        (void) ds_display_paint(cfgclient->display, NULL);
     184        (void) ds_display_save_cfg(cfgclient->display, cfg_file_path);
    183185        ds_display_unlock(cfgclient->display);
    184186
     
    218220
    219221        (void) ds_display_paint(cfgclient->display, NULL);
    220         ds_display_unlock(cfgclient->display);
     222        (void) ds_display_save_cfg(cfgclient->display, cfg_file_path);
     223        ds_display_unlock(cfgclient->display);
     224
    221225        return EOK;
    222226}
     
    254258        (void)idevcfg;
    255259
     260        (void) ds_display_save_cfg(cfgclient->display, cfg_file_path);
    256261        ds_display_unlock(cfgclient->display);
    257262        return EOK;
     
    287292
    288293        ds_idevcfg_destroy(idevcfg);
     294        (void) ds_display_save_cfg(cfgclient->display, cfg_file_path);
    289295        ds_display_unlock(cfgclient->display);
    290296        return EOK;
  • uspace/srv/hid/display/display.c

    rca95ccd r9546146  
    11/*
    2  * Copyright (c) 2023 Jiri Svoboda
     2 * Copyright (c) 2024 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    4141#include <memgfx/memgc.h>
    4242#include <stdlib.h>
     43#include <str.h>
    4344#include "client.h"
    4445#include "clonegc.h"
     
    4647#include "cursor.h"
    4748#include "display.h"
     49#include "idevcfg.h"
    4850#include "seat.h"
    4951#include "window.h"
     
    100102        list_initialize(&disp->cfgclients);
    101103        disp->next_wnd_id = 1;
     104        disp->next_seat_id = 1;
    102105        list_initialize(&disp->ddevs);
    103106        list_initialize(&disp->idevcfgs);
     
    137140        gfx_color_delete(disp->bg_color);
    138141        free(disp);
     142}
     143
     144/** Load display configuration from SIF file.
     145 *
     146 * @param display Display
     147 * @param cfgpath Configuration file path
     148 *
     149 * @return EOK on success or an error code
     150 */
     151errno_t ds_display_load_cfg(ds_display_t *display, const char *cfgpath)
     152{
     153        sif_doc_t *doc = NULL;
     154        sif_node_t *rnode;
     155        sif_node_t *ndisplay;
     156        sif_node_t *nseats;
     157        sif_node_t *nseat;
     158        ds_seat_t *seat;
     159        sif_node_t *nidevcfgs;
     160        sif_node_t *nidevcfg;
     161        const char *ntype;
     162        ds_idevcfg_t *idevcfg;
     163        errno_t rc;
     164
     165        log_msg(LOG_DEFAULT, LVL_NOTE, "ds_display_load_cfg: load '%s'", cfgpath);
     166        rc = sif_load(cfgpath, &doc);
     167        if (rc != EOK)
     168                goto error;
     169
     170        log_msg(LOG_DEFAULT, LVL_NOTE, "ds_display_load_cfg: get root");
     171        rnode = sif_get_root(doc);
     172        ndisplay = sif_node_first_child(rnode);
     173        ntype = sif_node_get_type(ndisplay);
     174        log_msg(LOG_DEFAULT, LVL_NOTE, "ds_display_load_cfg: check display node");
     175        if (str_cmp(ntype, "display") != 0) {
     176                rc = EIO;
     177                goto error;
     178        }
     179
     180        nseats = sif_node_first_child(ndisplay);
     181        ntype = sif_node_get_type(nseats);
     182        log_msg(LOG_DEFAULT, LVL_NOTE, "ds_display_load_cfg: check seats node");
     183        if (str_cmp(ntype, "seats") != 0) {
     184                rc = EIO;
     185                goto error;
     186        }
     187
     188        /* Load individual seats */
     189        nseat = sif_node_first_child(nseats);
     190        log_msg(LOG_DEFAULT, LVL_NOTE, "ds_display_load_cfg: walk seat nodes");
     191        while (nseat != NULL) {
     192                ntype = sif_node_get_type(nseat);
     193                log_msg(LOG_DEFAULT, LVL_NOTE, "ds_display_load_cfg: check seat node");
     194                if (str_cmp(ntype, "seat") != 0) {
     195                        rc = EIO;
     196                        goto error;
     197                }
     198
     199                log_msg(LOG_DEFAULT, LVL_NOTE, "ds_display_load_cfg: load seat");
     200                rc = ds_seat_load(display, nseat, &seat);
     201                if (rc != EOK)
     202                        goto error;
     203
     204                (void)seat;
     205                nseat = sif_node_next_child(nseat);
     206        }
     207
     208        nidevcfgs = sif_node_next_child(nseats);
     209        ntype = sif_node_get_type(nidevcfgs);
     210        log_msg(LOG_DEFAULT, LVL_NOTE, "ds_display_load_cfg: check idevcfgs node");
     211        if (str_cmp(ntype, "idevcfgs") != 0) {
     212                rc = EIO;
     213                goto error;
     214        }
     215
     216        /* Load individual input device configuration entries */
     217        nidevcfg = sif_node_first_child(nidevcfgs);
     218        log_msg(LOG_DEFAULT, LVL_NOTE, "ds_display_load_cfg: walk idevcfg nodes");
     219        while (nidevcfg != NULL) {
     220                ntype = sif_node_get_type(nidevcfg);
     221                log_msg(LOG_DEFAULT, LVL_NOTE, "ds_display_load_cfg: check idevcfg node");
     222                if (str_cmp(ntype, "idevcfg") != 0) {
     223                        rc = EIO;
     224                        goto error;
     225                }
     226
     227                log_msg(LOG_DEFAULT, LVL_NOTE, "ds_display_load_cfg: load idevcfg");
     228                rc = ds_idevcfg_load(display, nidevcfg, &idevcfg);
     229                if (rc != EOK)
     230                        goto error;
     231
     232                (void)idevcfg;
     233                nidevcfg = sif_node_next_child(nidevcfg);
     234        }
     235
     236        sif_delete(doc);
     237        return EOK;
     238error:
     239        if (doc != NULL)
     240                sif_delete(doc);
     241
     242        seat = ds_display_first_seat(display);
     243        while (seat != NULL) {
     244                ds_seat_destroy(seat);
     245                seat = ds_display_first_seat(display);
     246        }
     247        return rc;
     248}
     249
     250/** Save seat to SIF node.
     251 *
     252 * @param display Display
     253 * @param cfgpath Configuration file path
     254 *
     255 * @return EOK on success or an error code
     256 */
     257errno_t ds_display_save_cfg(ds_display_t *display, const char *cfgpath)
     258{
     259        sif_doc_t *doc = NULL;
     260        sif_node_t *rnode;
     261        sif_node_t *ndisplay;
     262        sif_node_t *nseats;
     263        sif_node_t *nseat;
     264        ds_seat_t *seat;
     265        sif_node_t *nidevcfgs;
     266        sif_node_t *nidevcfg;
     267        ds_idevcfg_t *idevcfg;
     268        errno_t rc;
     269
     270        rc = sif_new(&doc);
     271        if (rc != EOK)
     272                goto error;
     273
     274        rnode = sif_get_root(doc);
     275        rc = sif_node_append_child(rnode, "display", &ndisplay);
     276        if (rc != EOK)
     277                goto error;
     278
     279        rc = sif_node_append_child(ndisplay, "seats", &nseats);
     280        if (rc != EOK)
     281                goto error;
     282
     283        /* Save individual seats */
     284        seat = ds_display_first_seat(display);
     285        while (seat != NULL) {
     286                rc = sif_node_append_child(nseats, "seat", &nseat);
     287                if (rc != EOK)
     288                        goto error;
     289
     290                rc = ds_seat_save(seat, nseat);
     291                if (rc != EOK)
     292                        goto error;
     293
     294                seat = ds_display_next_seat(seat);
     295        }
     296
     297        rc = sif_node_append_child(ndisplay, "idevcfgs", &nidevcfgs);
     298        if (rc != EOK)
     299                goto error;
     300
     301        /* Save individual input device configuration entries */
     302        idevcfg = ds_display_first_idevcfg(display);
     303        while (idevcfg != NULL) {
     304                rc = sif_node_append_child(nidevcfgs, "idevcfg", &nidevcfg);
     305                if (rc != EOK)
     306                        goto error;
     307
     308                rc = ds_idevcfg_save(idevcfg, nidevcfg);
     309                if (rc != EOK)
     310                        goto error;
     311
     312                idevcfg = ds_display_next_idevcfg(idevcfg);
     313        }
     314
     315        rc = sif_save(doc, cfgpath);
     316        if (rc != EOK)
     317                goto error;
     318
     319        sif_delete(doc);
     320        return EOK;
     321error:
     322        if (doc != NULL)
     323                sif_delete(doc);
     324        return rc;
    139325}
    140326
  • uspace/srv/hid/display/display.h

    rca95ccd r9546146  
    11/*
    2  * Copyright (c) 2023 Jiri Svoboda
     2 * Copyright (c) 2024 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    5656    ds_display_t **);
    5757extern void ds_display_destroy(ds_display_t *);
     58errno_t ds_display_load_cfg(ds_display_t *, const char *);
     59errno_t ds_display_save_cfg(ds_display_t *, const char *);
    5860extern void ds_display_lock(ds_display_t *);
    5961extern void ds_display_unlock(ds_display_t *);
  • uspace/srv/hid/display/idevcfg.c

    rca95ccd r9546146  
    11/*
    2  * Copyright (c) 2023 Jiri Svoboda
     2 * Copyright (c) 2024 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    3838#include <io/log.h>
    3939#include <loc.h>
     40#include <stdio.h>
    4041#include <stdlib.h>
    4142#include "display.h"
     
    8081}
    8182
     83/** Load input device configuration entry from SIF node.
     84 *
     85 * @param display Display
     86 * @param enode Entry node from which the entry should be loaded
     87 * @param ridevcfg Place to store pointer to the newly loaded input device
     88 *                 configuration entry
     89 *
     90 * @return EOK on success or an error code
     91 */
     92errno_t ds_idevcfg_load(ds_display_t *display, sif_node_t *enode,
     93    ds_idevcfg_t **ridevcfg)
     94{
     95        const char *svc_name;
     96        const char *sseat_id;
     97        char *endptr;
     98        unsigned long svc_id;
     99        unsigned long seat_id;
     100        ds_seat_t *seat;
     101        ds_idevcfg_t *idevcfg;
     102        errno_t rc;
     103
     104        svc_name = sif_node_get_attr(enode, "svc-name");
     105        if (svc_name == NULL)
     106                return EIO;
     107
     108        sseat_id = sif_node_get_attr(enode, "seat-id");
     109        if (sseat_id == NULL)
     110                return EIO;
     111
     112        rc = loc_service_get_id(svc_name, &svc_id, 0);
     113        if (rc != EOK)
     114                return rc;
     115
     116        seat_id = strtoul(sseat_id, &endptr, 10);
     117        if (*endptr != '\0')
     118                return EIO;
     119
     120        seat = ds_display_find_seat(display, seat_id);
     121        if (seat == NULL)
     122                return EIO;
     123
     124        rc = ds_idevcfg_create(display, svc_id, seat, &idevcfg);
     125        if (rc != EOK)
     126                return rc;
     127
     128        (void)idevcfg;
     129        return EOK;
     130}
     131
     132/** Save input device configuration entry to SIF node.
     133 *
     134 * @param idevcfg Input device configuration entry
     135 * @param enode Entry node to which the entry should be saved
     136 *
     137 * @return EOK on success or an error code
     138 */
     139errno_t ds_idevcfg_save(ds_idevcfg_t *idevcfg, sif_node_t *enode)
     140{
     141        char *svc_name;
     142        char *sseat_id;
     143        errno_t rc;
     144        int rv;
     145
     146        rc = loc_service_get_name(idevcfg->svc_id, &svc_name);
     147        if (rc != EOK)
     148                return rc;
     149
     150        rc = sif_node_set_attr(enode, "svc-name", svc_name);
     151        if (rc != EOK) {
     152                free(svc_name);
     153                return rc;
     154        }
     155
     156        free(svc_name);
     157
     158        rv = asprintf(&sseat_id, "%lu", (unsigned long)idevcfg->seat->id);
     159        if (rv < 0) {
     160                rc = ENOMEM;
     161                return rc;
     162        }
     163
     164        rc = sif_node_set_attr(enode, "seat-id", sseat_id);
     165        if (rc != EOK) {
     166                free(sseat_id);
     167                return rc;
     168        }
     169
     170        free(sseat_id);
     171        return EOK;
     172}
     173
    82174/** @}
    83175 */
  • uspace/srv/hid/display/idevcfg.h

    rca95ccd r9546146  
    11/*
    2  * Copyright (c) 2023 Jiri Svoboda
     2 * Copyright (c) 2024 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    3939#include <errno.h>
    4040#include <loc.h>
     41#include <sif.h>
    4142#include "types/display/display.h"
    4243#include "types/display/idevcfg.h"
     
    4647    ds_idevcfg_t **);
    4748extern void ds_idevcfg_destroy(ds_idevcfg_t *);
     49extern errno_t ds_idevcfg_load(ds_display_t *, sif_node_t *, ds_idevcfg_t **);
     50extern errno_t ds_idevcfg_save(ds_idevcfg_t *, sif_node_t *);
    4851
    4952#endif
  • uspace/srv/hid/display/main.c

    rca95ccd r9546146  
    11/*
    2  * Copyright (c) 2023 Jiri Svoboda
     2 * Copyright (c) 2024 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    6262#include "wmops.h"
    6363
     64const char *cfg_file_path = "/w/cfg/display.sif";
     65
    6466static void display_client_conn(ipc_call_t *, void *);
    6567static void display_client_ev_pending(void *);
     
    137139                goto error;
    138140
    139         rc = ds_seat_create(disp, "Alice", &seat);
    140         if (rc != EOK)
    141                 goto error;
     141        rc = ds_display_load_cfg(disp, cfg_file_path);
     142        if (rc != EOK) {
     143                log_msg(LOG_DEFAULT, LVL_NOTE,
     144                    "Starting with fresh configuration.");
     145
     146                /* Create first seat */
     147                rc = ds_seat_create(disp, "Alice", &seat);
     148                if (rc != EOK)
     149                        goto error;
     150        }
    142151
    143152        rc = ds_output_create(&output);
  • uspace/srv/hid/display/main.h

    rca95ccd r9546146  
    11/*
    2  * Copyright (c) 2019 Jiri Svoboda
     2 * Copyright (c) 2024 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    3838#define NAME "display"
    3939
     40extern const char *cfg_file_path;
     41
    4042#endif
    4143
  • uspace/srv/hid/display/meson.build

    rca95ccd r9546146  
    11#
    2 # Copyright (c) 2023 Jiri Svoboda
     2# Copyright (c) 2024 Jiri Svoboda
    33# All rights reserved.
    44#
     
    2727#
    2828
    29 deps = [ 'ipcgfx', 'memgfx', 'display', 'ddev', 'dispcfg', 'wndmgt', 'input' ]
     29deps = [ 'ipcgfx', 'memgfx', 'display', 'ddev', 'dispcfg', 'wndmgt', 'input',
     30    'sif' ]
    3031
    3132src = files(
  • uspace/srv/hid/display/seat.c

    rca95ccd r9546146  
    3838#include <gfx/color.h>
    3939#include <gfx/render.h>
     40#include <sif.h>
     41#include <stdio.h>
    4042#include <stdlib.h>
    4143#include <str.h>
     
    117119        free(seat->name);
    118120        free(seat);
     121}
     122
     123/** Load seat from SIF node.
     124 *
     125 * @param display Display
     126 * @param snode Seat node from which to load the seat
     127 * @param rseat Place to store pointer to the newly loaded seat
     128 *
     129 * @return EOK on success or an error code
     130 */
     131errno_t ds_seat_load(ds_display_t *display, sif_node_t *snode,
     132    ds_seat_t **rseat)
     133{
     134        const char *sid;
     135        const char *name;
     136        char *endptr;
     137        unsigned long id;
     138        errno_t rc;
     139
     140        sid = sif_node_get_attr(snode, "id");
     141        if (sid == NULL)
     142                return EIO;
     143
     144        name = sif_node_get_attr(snode, "name");
     145        if (name == NULL)
     146                return EIO;
     147
     148        id = strtoul(sid, &endptr, 10);
     149        if (*endptr != '\0')
     150                return EIO;
     151
     152        rc = ds_seat_create(display, name, rseat);
     153        if (rc != EOK)
     154                return EIO;
     155
     156        (*rseat)->id = id;
     157        return EOK;
     158}
     159
     160/** Save seat to SIF node.
     161 *
     162 * @param seat Seat
     163 * @param snode Seat node into which the seat should be saved
     164 *
     165 * @return EOK on success or an error code
     166 */
     167errno_t ds_seat_save(ds_seat_t *seat, sif_node_t *snode)
     168{
     169        char *sid;
     170        errno_t rc;
     171        int rv;
     172
     173        rv = asprintf(&sid, "%lu", (unsigned long)seat->id);
     174        if (rv < 0) {
     175                rc = ENOMEM;
     176                return rc;
     177        }
     178
     179        rc = sif_node_set_attr(snode, "id", sid);
     180        if (rc != EOK) {
     181                free(sid);
     182                return rc;
     183        }
     184
     185        free(sid);
     186
     187        rc = sif_node_set_attr(snode, "name", seat->name);
     188        if (rc != EOK)
     189                return rc;
     190
     191        return EOK;
    119192}
    120193
  • uspace/srv/hid/display/seat.h

    rca95ccd r9546146  
    11/*
    2  * Copyright (c) 2023 Jiri Svoboda
     2 * Copyright (c) 2024 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    4141#include <io/kbd_event.h>
    4242#include <io/pos_event.h>
     43#include <sif.h>
    4344#include "types/display/display.h"
    4445#include "types/display/seat.h"
     
    4849extern errno_t ds_seat_create(ds_display_t *, const char *, ds_seat_t **);
    4950extern void ds_seat_destroy(ds_seat_t *);
     51extern errno_t ds_seat_load(ds_display_t *, sif_node_t *, ds_seat_t **);
     52extern errno_t ds_seat_save(ds_seat_t *, sif_node_t *);
    5053extern void ds_seat_set_focus(ds_seat_t *, ds_window_t *);
    5154extern void ds_seat_set_popup(ds_seat_t *, ds_window_t *);
Note: See TracChangeset for help on using the changeset viewer.