source: mainline/uspace/app/mkbd/main.c@ 3f932a7e

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 3f932a7e was a35b458, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 8 years ago

style: Remove trailing whitespace on _all_ lines, including empty ones, for particular file types.

Command used: tools/srepl '\s\+$' '' -- *.c *.h *.py *.sh *.s *.S *.ag

Currently, whitespace on empty lines is very inconsistent.
There are two basic choices: Either remove the whitespace, or keep empty lines
indented to the level of surrounding code. The former is AFAICT more common,
and also much easier to do automatically.

Alternatively, we could write script for automatic indentation, and use that
instead. However, if such a script exists, it's possible to use the indented
style locally, by having the editor apply relevant conversions on load/save,
without affecting remote repository. IMO, it makes more sense to adopt
the simpler rule.

  • Property mode set to 100644
File size: 7.2 KB
Line 
1/*
2 * Copyright (c) 2011 Lubos Slovak
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 mkbd
30 * @{
31 */
32/**
33 * @file
34 * Sample application using the data from multimedia keys on keyboard
35 */
36
37#include <inttypes.h>
38#include <stdio.h>
39#include <stdlib.h>
40#include <errno.h>
41#include <str_error.h>
42#include <stdbool.h>
43#include <getopt.h>
44#include <devman.h>
45#include <loc.h>
46#include <usbhid_iface.h>
47#include <usb/dev/pipes.h>
48#include <async.h>
49#include <usb/dev.h>
50#include <usb/hid/usages/core.h>
51#include <usb/hid/hidparser.h>
52#include <usb/hid/hiddescriptor.h>
53#include <usb/hid/usages/consumer.h>
54#include <io/console.h>
55#include <io/keycode.h>
56#include <assert.h>
57
58#define NAME "mkbd"
59
60static async_sess_t *dev_sess = NULL;
61
62static errno_t initialize_report_parser(async_sess_t *dev_sess,
63 usb_hid_report_t **report)
64{
65 *report = (usb_hid_report_t *) malloc(sizeof(usb_hid_report_t));
66 if (*report == NULL)
67 return ENOMEM;
68
69 errno_t rc = usb_hid_report_init(*report);
70 if (rc != EOK) {
71 usb_hid_report_deinit(*report);
72 *report = NULL;
73 return rc;
74 }
75
76 /* Get the report descriptor length from the device */
77 size_t report_desc_size;
78 rc = usbhid_dev_get_report_descriptor_length(dev_sess,
79 &report_desc_size);
80 if (rc != EOK) {
81 usb_hid_report_deinit(*report);
82 *report = NULL;
83 return rc;
84 }
85
86 if (report_desc_size == 0) {
87 usb_hid_report_deinit(*report);
88 *report = NULL;
89 // TODO: other error code?
90 return EINVAL;
91 }
92
93 uint8_t *desc = (uint8_t *) malloc(report_desc_size);
94 if (desc == NULL) {
95 usb_hid_report_deinit(*report);
96 *report = NULL;
97 return ENOMEM;
98 }
99
100 /* Get the report descriptor from the device */
101 size_t actual_size;
102 rc = usbhid_dev_get_report_descriptor(dev_sess, desc, report_desc_size,
103 &actual_size);
104 if (rc != EOK) {
105 usb_hid_report_deinit(*report);
106 *report = NULL;
107 free(desc);
108 return rc;
109 }
110
111 if (actual_size != report_desc_size) {
112 usb_hid_report_deinit(*report);
113 *report = NULL;
114 free(desc);
115 // TODO: other error code?
116 return EINVAL;
117 }
118
119 /* Initialize the report parser */
120
121 rc = usb_hid_parse_report_descriptor(*report, desc, report_desc_size);
122 free(desc);
123
124 return rc;
125}
126
127static void print_key(uint8_t *buffer, size_t size, usb_hid_report_t *report)
128{
129 assert(buffer != NULL);
130 assert(report != NULL);
131
132 uint8_t report_id;
133 errno_t rc = usb_hid_parse_report(report, buffer, size, &report_id);
134 if (rc != EOK)
135 return;
136
137 usb_hid_report_path_t *path = usb_hid_report_path();
138 if (path == NULL) {
139 return;
140 }
141
142 usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_CONSUMER, 0);
143
144 usb_hid_report_path_set_report_id(path, report_id);
145
146 usb_hid_report_field_t *field = usb_hid_report_get_sibling(
147 report, NULL, path, USB_HID_PATH_COMPARE_END
148 | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY,
149 USB_HID_REPORT_TYPE_INPUT);
150
151 while (field != NULL) {
152 if (field->value != 0) {
153 const char *key_str =
154 usbhid_multimedia_usage_to_str(field->usage);
155 printf("Pressed key: %s\n", key_str);
156 }
157
158 field = usb_hid_report_get_sibling(
159 report, field, path, USB_HID_PATH_COMPARE_END
160 | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY,
161 USB_HID_REPORT_TYPE_INPUT);
162 }
163
164 usb_hid_report_path_free(path);
165}
166
167static errno_t wait_for_quit_fibril(void *arg)
168{
169 console_ctrl_t *con = console_init(stdin, stdout);
170
171 printf("Press <ESC> to quit the application.\n");
172
173 while (1) {
174 cons_event_t ev;
175 bool ok = console_get_event(con, &ev);
176 if (!ok) {
177 printf("Connection with console broken: %s.\n",
178 str_error(errno));
179 break;
180 }
181
182 if (ev.type == CEV_KEY && ev.ev.key.type == KEY_PRESS &&
183 ev.ev.key.key == KC_ESCAPE) {
184 break;
185 }
186 }
187
188 console_done(con);
189
190 exit(0);
191
192 return EOK;
193}
194
195#define MAX_PATH_LENGTH 1024
196
197static void print_usage(char *app_name)
198{
199#define _INDENT " "
200 printf(NAME ": Print out what multimedia keys were pressed.\n\n");
201 printf("Usage: %s device\n", app_name);
202 printf(_INDENT "The device is a devman path to the device.\n");
203#undef _OPTION
204#undef _INDENT
205}
206
207int main(int argc, char *argv[])
208{
209 int act_event = -1;
210
211 if (argc <= 1) {
212 print_usage(argv[0]);
213 return -1;
214 }
215
216 char *devpath = argv[1];
217
218 devman_handle_t dev_handle = 0;
219
220 errno_t rc = usb_resolve_device_handle(devpath, &dev_handle);
221 if (rc != EOK) {
222 printf("Device not found or not of USB kind: %s.\n",
223 str_error(rc));
224 return rc;
225 }
226
227 async_sess_t *sess = devman_device_connect(dev_handle, 0);
228 if (!sess) {
229 printf(NAME ": failed to connect to the device (handle %"
230 PRIun "): %s.\n", dev_handle, str_error(errno));
231 return errno;
232 }
233
234 dev_sess = sess;
235
236 char path[MAX_PATH_LENGTH];
237 rc = devman_fun_get_path(dev_handle, path, MAX_PATH_LENGTH);
238 if (rc != EOK) {
239 printf(NAME ": failed to get path (handle %"
240 PRIun "): %s.\n", dev_handle, str_error(errno));
241 return ENOMEM;
242 }
243
244 printf("Device path: %s\n", path);
245
246
247 usb_hid_report_t *report = NULL;
248 rc = initialize_report_parser(dev_sess, &report);
249 if (rc != EOK) {
250 printf("Failed to initialize report parser: %s\n",
251 str_error(rc));
252 return rc;
253 }
254
255 assert(report != NULL);
256
257 size_t size;
258 rc = usbhid_dev_get_event_length(dev_sess, &size);
259 if (rc != EOK) {
260 printf("Failed to get event length: %s.\n", str_error(rc));
261 return rc;
262 }
263
264 uint8_t *event = (uint8_t *)malloc(size);
265 if (event == NULL) {
266 printf("Out of memory.\n");
267 // TODO: hangup phone?
268 return ENOMEM;
269 }
270
271 fid_t quit_fibril = fibril_create(wait_for_quit_fibril, NULL);
272 if (quit_fibril == 0) {
273 printf("Failed to start extra fibril.\n");
274 return -1;
275 }
276 fibril_add_ready(quit_fibril);
277
278 size_t actual_size;
279 int event_nr;
280
281 while (true) {
282 /** @todo Try blocking call. */
283 rc = usbhid_dev_get_event(dev_sess, event, size, &actual_size,
284 &event_nr, 0);
285 if (rc != EOK) {
286 // TODO: hangup phone?
287 printf("Error in getting event from the HID driver:"
288 "%s.\n", str_error(rc));
289 break;
290 }
291
292 if (event_nr > act_event) {
293 print_key(event, size, report);
294 act_event = event_nr;
295 }
296
297 async_usleep(10000);
298 }
299
300 return 0;
301}
302
303/** @}
304 */
Note: See TracBrowser for help on using the repository browser.