source: mainline/uspace/srv/hid/display/wmclient.c

Last change on this file was d8503fd, checked in by Jiri Svoboda <jiri@…>, 2 years ago

Display configuration utility and server support

Currently we can only create, list and delete seats using the
'disp' utility (but no way to assign devices).

  • Property mode set to 100644
File size: 6.0 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 server WM client
34 */
35
36#include <adt/list.h>
37#include <errno.h>
38#include <io/log.h>
39#include <stdlib.h>
40#include "display.h"
41#include "window.h"
42#include "wmclient.h"
43
44/** Create WM client.
45 *
46 * @param display Parent display
47 * @param cb WM client callbacks
48 * @param cb_arg Callback argument
49 * @param rwmclient Place to store pointer to new WM client.
50 * @return EOK on success, ENOMEM if out of memory
51 */
52errno_t ds_wmclient_create(ds_display_t *display, ds_wmclient_cb_t *cb,
53 void *cb_arg, ds_wmclient_t **rwmclient)
54{
55 ds_wmclient_t *wmclient;
56
57 wmclient = calloc(1, sizeof(ds_wmclient_t));
58 if (wmclient == NULL)
59 return ENOMEM;
60
61 list_initialize(&wmclient->events);
62 wmclient->cb = cb;
63 wmclient->cb_arg = cb_arg;
64
65 ds_display_add_wmclient(display, wmclient);
66
67 *rwmclient = wmclient;
68 return EOK;
69}
70
71/** Destroy WM client.
72 *
73 * @param wmclient WM client
74 */
75void ds_wmclient_destroy(ds_wmclient_t *wmclient)
76{
77 ds_wmclient_purge_events(wmclient);
78 ds_display_remove_wmclient(wmclient);
79 free(wmclient);
80}
81
82/** Get next event from WM client event queue.
83 *
84 * @param wmclient WM client
85 * @param event Place to store event
86 * @return EOK on success, ENOENT if event queue is empty
87 */
88errno_t ds_wmclient_get_event(ds_wmclient_t *wmclient, wndmgt_ev_t *event)
89{
90 link_t *link;
91 ds_wmclient_ev_t *wevent;
92
93 link = list_first(&wmclient->events);
94 if (link == NULL)
95 return ENOENT;
96
97 wevent = list_get_instance(link, ds_wmclient_ev_t, levents);
98 list_remove(link);
99
100 *event = wevent->event;
101 free(wevent);
102 return EOK;
103}
104
105/** Purge events from WM client event queue.
106 *
107 * @param client Client
108 */
109void ds_wmclient_purge_events(ds_wmclient_t *wmclient)
110{
111 link_t *cur;
112 link_t *next;
113 ds_wmclient_ev_t *wevent;
114
115 cur = list_first(&wmclient->events);
116 while (cur != NULL) {
117 next = list_next(cur, &wmclient->events);
118 wevent = list_get_instance(cur, ds_wmclient_ev_t, levents);
119
120 list_remove(cur);
121 free(wevent);
122 cur = next;
123 }
124}
125
126/** Post window added event to the WM client's message queue.
127 *
128 * @param wmclient WM client
129 * @param wnd_id Window ID of the added window
130 *
131 * @return EOK on success or an error code
132 */
133errno_t ds_wmclient_post_wnd_added_event(ds_wmclient_t *wmclient,
134 sysarg_t wnd_id)
135{
136 ds_wmclient_ev_t *wevent;
137
138 log_msg(LOG_DEFAULT, LVL_DEBUG, "wmclient_pos_wnd_added_event "
139 "wmclient=%p wnd_id=%zu\n", (void *)wmclient, wnd_id);
140
141 wevent = calloc(1, sizeof(ds_wmclient_ev_t));
142 if (wevent == NULL)
143 return ENOMEM;
144
145 wevent->wmclient = wmclient;
146 wevent->event.etype = wmev_window_added;
147 wevent->event.wnd_id = wnd_id;
148 list_append(&wevent->levents, &wmclient->events);
149
150 /* Notify the client */
151 // TODO Do not send more than once until client drains the queue
152 if (wmclient->cb != NULL && wmclient->cb->ev_pending != NULL)
153 wmclient->cb->ev_pending(wmclient->cb_arg);
154
155 return EOK;
156}
157
158/** Post window removed event to the WM client's message queue.
159 *
160 * @param wmclient WM client
161 * @param wnd_id Window ID of the added window
162 *
163 * @return EOK on success or an error code
164 */
165errno_t ds_wmclient_post_wnd_removed_event(ds_wmclient_t *wmclient,
166 sysarg_t wnd_id)
167{
168 ds_wmclient_ev_t *wevent;
169
170 log_msg(LOG_DEFAULT, LVL_DEBUG, "wmclient_pos_wnd_removed_event "
171 "wmclient=%p wnd_id=%zu\n", (void *)wmclient, wnd_id);
172
173 wevent = calloc(1, sizeof(ds_wmclient_ev_t));
174 if (wevent == NULL)
175 return ENOMEM;
176
177 wevent->wmclient = wmclient;
178 wevent->event.etype = wmev_window_removed;
179 wevent->event.wnd_id = wnd_id;
180 list_append(&wevent->levents, &wmclient->events);
181
182 /* Notify the client */
183 // TODO Do not send more than once until client drains the queue
184 if (wmclient->cb != NULL && wmclient->cb->ev_pending != NULL)
185 wmclient->cb->ev_pending(wmclient->cb_arg);
186
187 return EOK;
188}
189
190/** Post window changed event to the WM client's message queue.
191 *
192 * @param wmclient WM client
193 * @param wnd_id Window ID of the added window
194 *
195 * @return EOK on success or an error code
196 */
197errno_t ds_wmclient_post_wnd_changed_event(ds_wmclient_t *wmclient,
198 sysarg_t wnd_id)
199{
200 ds_wmclient_ev_t *wevent;
201
202 log_msg(LOG_DEFAULT, LVL_DEBUG, "wmclient_pos_wnd_changed_event "
203 "wmclient=%p wnd_id=%zu\n", (void *)wmclient, wnd_id);
204
205 wevent = calloc(1, sizeof(ds_wmclient_ev_t));
206 if (wevent == NULL)
207 return ENOMEM;
208
209 wevent->wmclient = wmclient;
210 wevent->event.etype = wmev_window_changed;
211 wevent->event.wnd_id = wnd_id;
212 list_append(&wevent->levents, &wmclient->events);
213
214 /* Notify the client */
215 // TODO Do not send more than once until client drains the queue
216 if (wmclient->cb != NULL && wmclient->cb->ev_pending != NULL)
217 wmclient->cb->ev_pending(wmclient->cb_arg);
218
219 return EOK;
220}
221
222/** @}
223 */
Note: See TracBrowser for help on using the repository browser.