source: mainline/uspace/srv/hid/display/cfgops.c@ 95658c9

ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 95658c9 was b3eeae5, checked in by Jiri Svoboda <jiri@…>, 3 years ago

Assigning devices to seats

  • Property mode set to 100644
File size: 7.9 KB
Line 
1/*
2 * Copyright (c) 2023 Jiri Svoboda
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup display
30 * @{
31 */
32/**
33 * @file Display configuration ops implementation
34 */
35
36#include <errno.h>
37#include <io/log.h>
38#include <stdlib.h>
39#include <str.h>
40#include <dispcfg_srv.h>
41#include "display.h"
42#include "idevcfg.h"
43#include "seat.h"
44#include "cfgclient.h"
45
46static errno_t dispc_get_seat_list(void *, dispcfg_seat_list_t **);
47static errno_t dispc_get_seat_info(void *, sysarg_t, dispcfg_seat_info_t **);
48static errno_t dispc_seat_create(void *, const char *, sysarg_t *);
49static errno_t dispc_seat_delete(void *, sysarg_t);
50static errno_t dispc_dev_assign(void *, sysarg_t, sysarg_t);
51static errno_t dispc_dev_unassign(void *, sysarg_t);
52static errno_t dispc_get_event(void *, dispcfg_ev_t *);
53
54dispcfg_ops_t dispcfg_srv_ops = {
55 .get_seat_list = dispc_get_seat_list,
56 .get_seat_info = dispc_get_seat_info,
57 .seat_create = dispc_seat_create,
58 .seat_delete = dispc_seat_delete,
59 .dev_assign = dispc_dev_assign,
60 .dev_unassign = dispc_dev_unassign,
61 .get_event = dispc_get_event,
62};
63
64/** Get seat list.
65 *
66 * @param arg Argument (CFG client)
67 * @param rlist Place to store pointer to new list
68 * @return EOK on success or an error code
69 */
70static errno_t dispc_get_seat_list(void *arg, dispcfg_seat_list_t **rlist)
71{
72 ds_cfgclient_t *cfgclient = (ds_cfgclient_t *)arg;
73 dispcfg_seat_list_t *list;
74 ds_seat_t *seat;
75 unsigned i;
76
77 log_msg(LOG_DEFAULT, LVL_DEBUG, "dispcfg_get_seat_list()");
78
79 list = calloc(1, sizeof(dispcfg_seat_list_t));
80 if (list == NULL)
81 return ENOMEM;
82
83 ds_display_lock(cfgclient->display);
84
85 /* Count the number of seats */
86 list->nseats = 0;
87 seat = ds_display_first_seat(cfgclient->display);
88 while (seat != NULL) {
89 ++list->nseats;
90 seat = ds_display_next_seat(seat);
91 }
92
93 /* Allocate array for seat IDs */
94 list->seats = calloc(list->nseats, sizeof(sysarg_t));
95 if (list->seats == NULL) {
96 ds_display_unlock(cfgclient->display);
97 free(list);
98 return ENOMEM;
99 }
100
101 /* Fill in seat IDs */
102 i = 0;
103 seat = ds_display_first_seat(cfgclient->display);
104 while (seat != NULL) {
105 list->seats[i++] = seat->id;
106 seat = ds_display_next_seat(seat);
107 }
108
109 ds_display_unlock(cfgclient->display);
110 *rlist = list;
111 return EOK;
112}
113
114/** Get seat information.
115 *
116 * @param arg Argument (CFG client)
117 * @param seat_id Seat ID
118 * @param rinfo Place to store pointer to new seat information structure
119 * @return EOK on success or an error code
120 */
121static errno_t dispc_get_seat_info(void *arg, sysarg_t seat_id,
122 dispcfg_seat_info_t **rinfo)
123{
124 ds_cfgclient_t *cfgclient = (ds_cfgclient_t *)arg;
125 ds_seat_t *seat;
126 dispcfg_seat_info_t *info;
127
128 log_msg(LOG_DEFAULT, LVL_DEBUG, "dispcfg_get_seat_info()");
129
130 ds_display_lock(cfgclient->display);
131 seat = ds_display_find_seat(cfgclient->display, seat_id);
132 if (seat == NULL) {
133 ds_display_unlock(cfgclient->display);
134 return ENOENT;
135 }
136
137 info = calloc(1, sizeof(dispcfg_seat_info_t));
138 if (info == NULL) {
139 ds_display_unlock(cfgclient->display);
140 return ENOMEM;
141 }
142
143 (void)seat;
144 info->name = str_dup(seat->name);
145 if (info->name == NULL) {
146 ds_display_unlock(cfgclient->display);
147 free(info);
148 return ENOMEM;
149 }
150
151 ds_display_unlock(cfgclient->display);
152 *rinfo = info;
153 return EOK;
154}
155
156/** Create seat.
157 *
158 * @param arg Argument (CFG client)
159 * @param name Seat name
160 * @param rseat_id Place to store ID of the new seat
161 * @return EOK on success or an error code
162 */
163static errno_t dispc_seat_create(void *arg, const char *name,
164 sysarg_t *rseat_id)
165{
166 ds_cfgclient_t *cfgclient = (ds_cfgclient_t *)arg;
167 ds_seat_t *seat;
168 errno_t rc;
169
170 log_msg(LOG_DEFAULT, LVL_DEBUG, "dispcfg_seat_create()");
171
172 ds_display_lock(cfgclient->display);
173
174 rc = ds_seat_create(cfgclient->display, name, &seat);
175 if (rc != EOK) {
176 ds_display_unlock(cfgclient->display);
177 return rc;
178 }
179
180 (void) ds_display_paint(cfgclient->display, NULL);
181 ds_display_unlock(cfgclient->display);
182
183 *rseat_id = seat->id;
184 return EOK;
185}
186
187/** Delete seat.
188 *
189 * @param arg Argument (CFG client)
190 * @param seat_id Seat ID
191 * @return EOK on success or an error code
192 */
193static errno_t dispc_seat_delete(void *arg, sysarg_t seat_id)
194{
195 ds_cfgclient_t *cfgclient = (ds_cfgclient_t *)arg;
196 ds_seat_t *seat;
197
198 log_msg(LOG_DEFAULT, LVL_DEBUG, "dispcfg_seat_delete()");
199
200 ds_display_lock(cfgclient->display);
201 seat = ds_display_find_seat(cfgclient->display, seat_id);
202 if (seat == NULL) {
203 ds_display_unlock(cfgclient->display);
204 return ENOENT;
205 }
206
207 ds_seat_destroy(seat);
208
209 (void) ds_display_paint(cfgclient->display, NULL);
210 ds_display_unlock(cfgclient->display);
211 return EOK;
212}
213
214/** Assign device to seat.
215 *
216 * @param arg Argument (CFG client)
217 * @param svc_id Device service ID
218 * @param seat_id Seat ID
219 * @return EOK on success or an error code
220 */
221static errno_t dispc_dev_assign(void *arg, sysarg_t svc_id, sysarg_t seat_id)
222{
223 ds_cfgclient_t *cfgclient = (ds_cfgclient_t *)arg;
224 ds_seat_t *seat;
225 ds_idevcfg_t *idevcfg;
226 errno_t rc;
227
228 log_msg(LOG_DEFAULT, LVL_DEBUG, "dispcfg_dev_assign()");
229
230 ds_display_lock(cfgclient->display);
231 seat = ds_display_find_seat(cfgclient->display, seat_id);
232 if (seat == NULL) {
233 ds_display_unlock(cfgclient->display);
234 return ENOENT;
235 }
236
237 rc = ds_idevcfg_create(cfgclient->display, svc_id, seat, &idevcfg);
238 if (rc != EOK) {
239 assert(rc == ENOMEM);
240 ds_display_unlock(cfgclient->display);
241 return ENOMEM;
242 }
243
244 (void)idevcfg;
245
246 ds_display_unlock(cfgclient->display);
247 return EOK;
248}
249
250/** Unassign device from any seat.
251 *
252 * @param arg Argument (CFG client)
253 * @param svc_id Device service ID
254 * @return EOK on success or an error code
255 */
256static errno_t dispc_dev_unassign(void *arg, sysarg_t svc_id)
257{
258 ds_cfgclient_t *cfgclient = (ds_cfgclient_t *)arg;
259 ds_idevcfg_t *idevcfg;
260
261 log_msg(LOG_DEFAULT, LVL_DEBUG, "dispcfg_dev_unassign()");
262
263 ds_display_lock(cfgclient->display);
264
265 idevcfg = ds_display_first_idevcfg(cfgclient->display);
266 while (idevcfg != NULL) {
267 if (idevcfg->svc_id == svc_id)
268 break;
269
270 idevcfg = ds_display_next_idevcfg(idevcfg);
271 }
272
273 if (idevcfg == NULL) {
274 ds_display_unlock(cfgclient->display);
275 return ENOENT;
276 }
277
278 ds_idevcfg_destroy(idevcfg);
279 ds_display_unlock(cfgclient->display);
280 return EOK;
281}
282
283/** Get display configuration event.
284 *
285 * @param arg Argument (CFG client)
286 * @param ev Place to store event
287 * @return EOK on success, ENOENT if there are no events
288 */
289static errno_t dispc_get_event(void *arg, dispcfg_ev_t *ev)
290{
291 ds_cfgclient_t *cfgclient = (ds_cfgclient_t *)arg;
292 errno_t rc;
293
294 log_msg(LOG_DEFAULT, LVL_DEBUG, "dispcfg_get_event()");
295
296 ds_display_lock(cfgclient->display);
297 rc = ds_cfgclient_get_event(cfgclient, ev);
298 ds_display_unlock(cfgclient->display);
299 return rc;
300}
301
302/** @}
303 */
Note: See TracBrowser for help on using the repository browser.