source: mainline/uspace/lib/c/generic/io/input.c@ a76ba5f3

Last change on this file since a76ba5f3 was a76ba5f3, checked in by Matthieu Riolo <matthieu.riolo@…>, 4 years ago

Relocating IPC calls in the layout to io/input

The IPC calls for changing the layout was located in
the application layout. Now they have been relocated
into the library io/input. This commit also changes
the behaviour of layout when called without any
parameters (no error status is returned)

  • Property mode set to 100644
File size: 6.1 KB
Line 
1/*
2 * Copyright (c) 2012 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 libc
30 * @{
31 */
32/**
33 * @file
34 * @brief Input protocol client stub
35 */
36
37#include <async.h>
38#include <assert.h>
39#include <errno.h>
40#include <io/kbd_event.h>
41#include <io/input.h>
42#include <ipc/input.h>
43#include <stdlib.h>
44#include <str.h>
45
46static void input_cb_conn(ipc_call_t *icall, void *arg);
47
48errno_t input_open(async_sess_t *sess, input_ev_ops_t *ev_ops,
49 void *arg, input_t **rinput)
50{
51 input_t *input = calloc(1, sizeof(input_t));
52 if (input == NULL)
53 return ENOMEM;
54
55 input->sess = sess;
56 input->ev_ops = ev_ops;
57 input->user = arg;
58
59 async_exch_t *exch = async_exchange_begin(sess);
60
61 port_id_t port;
62 errno_t rc = async_create_callback_port(exch, INTERFACE_INPUT_CB, 0, 0,
63 input_cb_conn, input, &port);
64
65 async_exchange_end(exch);
66
67 if (rc != EOK)
68 goto error;
69
70 *rinput = input;
71 return EOK;
72
73error:
74 if (input != NULL)
75 free(input);
76
77 return rc;
78}
79
80void input_close(input_t *input)
81{
82 /* XXX Synchronize with input_cb_conn */
83 free(input);
84}
85
86errno_t input_activate(input_t *input)
87{
88 async_exch_t *exch = async_exchange_begin(input->sess);
89 errno_t rc = async_req_0_0(exch, INPUT_ACTIVATE);
90 async_exchange_end(exch);
91
92 return rc;
93}
94
95static void input_ev_active(input_t *input, ipc_call_t *call)
96{
97 errno_t rc = input->ev_ops->active(input);
98 async_answer_0(call, rc);
99}
100
101static void input_ev_deactive(input_t *input, ipc_call_t *call)
102{
103 errno_t rc = input->ev_ops->deactive(input);
104 async_answer_0(call, rc);
105}
106
107static void input_ev_key(input_t *input, ipc_call_t *call)
108{
109 kbd_event_type_t type;
110 keycode_t key;
111 keymod_t mods;
112 char32_t c;
113 errno_t rc;
114
115 type = ipc_get_arg1(call);
116 key = ipc_get_arg2(call);
117 mods = ipc_get_arg3(call);
118 c = ipc_get_arg4(call);
119
120 rc = input->ev_ops->key(input, type, key, mods, c);
121 async_answer_0(call, rc);
122}
123
124static void input_ev_move(input_t *input, ipc_call_t *call)
125{
126 int dx;
127 int dy;
128 errno_t rc;
129
130 dx = ipc_get_arg1(call);
131 dy = ipc_get_arg2(call);
132
133 rc = input->ev_ops->move(input, dx, dy);
134 async_answer_0(call, rc);
135}
136
137static void input_ev_abs_move(input_t *input, ipc_call_t *call)
138{
139 unsigned x;
140 unsigned y;
141 unsigned max_x;
142 unsigned max_y;
143 errno_t rc;
144
145 x = ipc_get_arg1(call);
146 y = ipc_get_arg2(call);
147 max_x = ipc_get_arg3(call);
148 max_y = ipc_get_arg4(call);
149
150 rc = input->ev_ops->abs_move(input, x, y, max_x, max_y);
151 async_answer_0(call, rc);
152}
153
154static void input_ev_button(input_t *input, ipc_call_t *call)
155{
156 int bnum;
157 int press;
158 errno_t rc;
159
160 bnum = ipc_get_arg1(call);
161 press = ipc_get_arg2(call);
162
163 rc = input->ev_ops->button(input, bnum, press);
164 async_answer_0(call, rc);
165}
166
167static void input_cb_conn(ipc_call_t *icall, void *arg)
168{
169 input_t *input = (input_t *) arg;
170
171 while (true) {
172 ipc_call_t call;
173 async_get_call(&call);
174
175 if (!ipc_get_imethod(&call)) {
176 async_answer_0(&call, EOK);
177 return;
178 }
179
180 switch (ipc_get_imethod(&call)) {
181 case INPUT_EVENT_ACTIVE:
182 input_ev_active(input, &call);
183 break;
184 case INPUT_EVENT_DEACTIVE:
185 input_ev_deactive(input, &call);
186 break;
187 case INPUT_EVENT_KEY:
188 input_ev_key(input, &call);
189 break;
190 case INPUT_EVENT_MOVE:
191 input_ev_move(input, &call);
192 break;
193 case INPUT_EVENT_ABS_MOVE:
194 input_ev_abs_move(input, &call);
195 break;
196 case INPUT_EVENT_BUTTON:
197 input_ev_button(input, &call);
198 break;
199 default:
200 async_answer_0(&call, ENOTSUP);
201 }
202 }
203}
204
205/**
206 * Retrieves the active keyboard layout
207 * @param sess Active session to the input server
208 * @param layout The name of the currently active layout,
209 * needs to be freed by the caller
210 * @return EOK if sucessful or the corresponding error code.
211 * If a failure occurs the param layout is already freed
212 */
213errno_t input_layout_get(async_sess_t *sess, char **layout)
214{
215 errno_t rc;
216 ipc_call_t call;
217 async_exch_t *exch = async_exchange_begin(sess);
218 aid_t mid = async_send_0(exch, INPUT_GET_LAYOUT, &call);
219 async_wait_for(mid, &rc);
220
221 if (rc != EOK) {
222 goto error;
223 }
224
225 size_t length = ipc_get_arg1(&call);
226
227 *layout = malloc(length * sizeof(char *));
228 if (layout == NULL) {
229 rc = ENOMEM;
230 free(*layout);
231 goto error;
232 }
233
234 rc = async_data_read_start(exch, *layout, length);
235
236 if (rc != EOK)
237 free(*layout);
238
239error:
240 async_exchange_end(exch);
241 return rc;
242}
243
244/**
245 * Changes the keyboard layout
246 * @param sess Active session to the input server
247 * @param layout The name of the layout which should be activated
248 * @return EOK if sucessful or the corresponding error code.
249 */
250errno_t input_layout_set(async_sess_t *sess, const char *layout)
251{
252 errno_t rc;
253 ipc_call_t call;
254 async_exch_t *exch = async_exchange_begin(sess);
255
256 aid_t mid = async_send_0(exch, INPUT_CHANGE_LAYOUT, &call);
257 rc = async_data_write_start(exch, layout, str_size(layout));
258
259 if (rc == EOK)
260 async_wait_for(mid, &rc);
261
262 async_exchange_end(exch);
263 return rc;
264}
265
266/** @}
267 */
Note: See TracBrowser for help on using the repository browser.