source: mainline/uspace/lib/ui/src/popup.c@ d92b8e8f

Last change on this file since d92b8e8f was d92b8e8f, checked in by Jiri Svoboda <jiri@…>, 16 months ago

Start menu support for passing input device ID (multiseat)

  • Property mode set to 100644
File size: 6.4 KB
Line 
1/*
2 * Copyright (c) 2024 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 libui
30 * @{
31 */
32/**
33 * @file Popup window
34 */
35
36#include <errno.h>
37#include <gfx/context.h>
38#include <io/kbd_event.h>
39#include <io/pos_event.h>
40#include <mem.h>
41#include <stdlib.h>
42#include <ui/control.h>
43#include <ui/popup.h>
44#include <ui/ui.h>
45#include <ui/window.h>
46#include "../private/popup.h"
47
48static void ui_popup_window_close(ui_window_t *, void *);
49static void ui_popup_window_kbd(ui_window_t *, void *, kbd_event_t *);
50static void ui_popup_window_pos(ui_window_t *, void *, pos_event_t *);
51
52static ui_window_cb_t ui_popup_window_cb = {
53 .close = ui_popup_window_close,
54 .kbd = ui_popup_window_kbd,
55 .pos = ui_popup_window_pos
56};
57
58/** Initialize popup parameters structure.
59 *
60 * Popup parameters structure must always be initialized using this function
61 * first.
62 *
63 * @param params Popup parameters structure
64 */
65void ui_popup_params_init(ui_popup_params_t *params)
66{
67 memset(params, 0, sizeof(ui_popup_params_t));
68}
69
70/** Create new popup window.
71 *
72 * @param ui User interface
73 * @param parent Parent window
74 * @param params Popup parameters
75 * @param rpopup Place to store pointer to new popup window
76 * @return EOK on success or an error code
77 */
78errno_t ui_popup_create(ui_t *ui, ui_window_t *parent,
79 ui_popup_params_t *params, ui_popup_t **rpopup)
80{
81 ui_popup_t *popup;
82 ui_window_t *window = NULL;
83 ui_wnd_params_t wparams;
84 gfx_coord2_t parent_pos;
85 errno_t rc;
86
87 popup = calloc(1, sizeof(ui_popup_t));
88 if (popup == NULL)
89 return ENOMEM;
90
91 rc = ui_window_get_pos(parent, &parent_pos);
92 if (rc != EOK)
93 goto error;
94
95 ui_wnd_params_init(&wparams);
96 wparams.rect = params->rect;
97 wparams.caption = "";
98 wparams.style &= ~ui_wds_decorated;
99 wparams.placement = ui_wnd_place_popup;
100 wparams.flags |= ui_wndf_popup | ui_wndf_topmost;
101 wparams.idev_id = params->idev_id;
102
103 /* Compute position of parent rectangle relative to the screen */
104 gfx_rect_translate(&parent_pos, &params->place, &wparams.prect);
105
106 rc = ui_window_create(ui, &wparams, &window);
107 if (rc != EOK)
108 goto error;
109
110 popup->ui = ui;
111 popup->parent = parent;
112 popup->window = window;
113
114 ui_window_set_cb(window, &ui_popup_window_cb, popup);
115
116 *rpopup = popup;
117 return EOK;
118error:
119 free(popup);
120 return rc;
121}
122
123/** Destroy popup window.
124 *
125 * @param popup Popup window or @c NULL
126 */
127void ui_popup_destroy(ui_popup_t *popup)
128{
129 if (popup == NULL)
130 return;
131
132 ui_window_destroy(popup->window);
133 free(popup);
134}
135
136/** Add control to popup window.
137 *
138 * Only one control can be added to a popup window. If more than one control
139 * is added, the results are undefined.
140 *
141 * @param popup Popup window
142 * @param control Control
143 * @return EOK on success, ENOMEM if out of memory
144 */
145void ui_popup_add(ui_popup_t *popup, ui_control_t *control)
146{
147 ui_window_add(popup->window, control);
148}
149
150/** Remove control from popup window.
151 *
152 * @param popup Popup window
153 * @param control Control
154 */
155void ui_popup_remove(ui_popup_t *popup, ui_control_t *control)
156{
157 ui_window_remove(popup->window, control);
158}
159
160/** Set popup window callbacks.
161 *
162 * @param popup Popup window
163 * @param cb Popup window callbacks
164 * @param arg Callback argument
165 */
166void ui_popup_set_cb(ui_popup_t *popup, ui_popup_cb_t *cb, void *arg)
167{
168 popup->cb = cb;
169 popup->arg = arg;
170}
171
172/** Get UI resource from popup window.
173 *
174 * @param window Window
175 * @return UI resource
176 */
177ui_resource_t *ui_popup_get_res(ui_popup_t *popup)
178{
179 return ui_window_get_res(popup->window);
180}
181
182/** Get popup window GC.
183 *
184 * @param popup Popup window
185 * @return GC (relative to popup window)
186 */
187gfx_context_t *ui_popup_get_gc(ui_popup_t *popup)
188{
189 return ui_window_get_gc(popup->window);
190}
191
192/** Get ID of device that sent the last position event.
193 *
194 * @param popup Popup window
195 * @return Input device ID
196 */
197sysarg_t ui_popup_get_idev_id(ui_popup_t *popup)
198{
199 return popup->idev_id;
200}
201
202/** Handle close event in popup window.
203 *
204 * @param window Window
205 * @param arg Argument (ui_popup_t *)
206 */
207static void ui_popup_window_close(ui_window_t *window, void *arg)
208{
209 ui_popup_t *popup = (ui_popup_t *)arg;
210
211 if (popup->cb != NULL && popup->cb->close != NULL)
212 popup->cb->close(popup, popup->arg);
213}
214
215/** Handle keyboard event in popup window.
216 *
217 * @param window Window
218 * @param arg Argument (ui_popup_t *)
219 * @param event Keyboard event
220 */
221static void ui_popup_window_kbd(ui_window_t *window, void *arg,
222 kbd_event_t *event)
223{
224 ui_popup_t *popup = (ui_popup_t *)arg;
225
226 /* Remember ID of device that sent the last event */
227 popup->idev_id = event->kbd_id;
228
229 if (popup->cb != NULL && popup->cb->kbd != NULL)
230 popup->cb->kbd(popup, popup->arg, event);
231}
232
233/** Handle position event in popup window.
234 *
235 * @param window Window
236 * @param arg Argument (ui_popup_t *)
237 * @param event Position event
238 */
239static void ui_popup_window_pos(ui_window_t *window, void *arg,
240 pos_event_t *event)
241{
242 ui_popup_t *popup = (ui_popup_t *)arg;
243
244 /* Remember ID of device that sent the last event */
245 popup->idev_id = event->pos_id;
246
247 if (popup->cb != NULL && popup->cb->pos != NULL)
248 popup->cb->pos(popup, popup->arg, event);
249}
250
251/** @}
252 */
Note: See TracBrowser for help on using the repository browser.