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

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

Create menu windows in the correct seat

Add a mechanism to set the seat of a new display window, UI window,
UI popup - input device ID. This is set to the ID of the device which
activated the menu (mouse, keyboard). The display server determines
the correct seat from there.

This makes sure clicking outside closes the correct pop-up window.

  • 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 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;
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/** Handle close event in popup window.
193 *
194 * @param window Window
195 * @param arg Argument (ui_popup_t *)
196 */
197static void ui_popup_window_close(ui_window_t *window, void *arg)
198{
199 ui_popup_t *popup = (ui_popup_t *)arg;
200
201 if (popup->cb != NULL && popup->cb->close != NULL)
202 popup->cb->close(popup, popup->arg);
203}
204
205/** Handle keyboard event in popup window.
206 *
207 * @param window Window
208 * @param arg Argument (ui_popup_t *)
209 * @param event Keyboard event
210 */
211static void ui_popup_window_kbd(ui_window_t *window, void *arg,
212 kbd_event_t *event)
213{
214 ui_popup_t *popup = (ui_popup_t *)arg;
215
216 if (popup->cb != NULL && popup->cb->kbd != NULL)
217 popup->cb->kbd(popup, popup->arg, event);
218}
219
220/** Handle position event in popup window.
221 *
222 * @param window Window
223 * @param arg Argument (ui_popup_t *)
224 * @param event Position event
225 */
226static void ui_popup_window_pos(ui_window_t *window, void *arg,
227 pos_event_t *event)
228{
229 ui_popup_t *popup = (ui_popup_t *)arg;
230
231 if (popup->cb != NULL && popup->cb->pos != NULL)
232 popup->cb->pos(popup, popup->arg, event);
233}
234
235/** @}
236 */
Note: See TracBrowser for help on using the repository browser.