1/*
2 * Copyright (c) 2007, 2008, 2009, 2010, ETH Zurich.
3 * All rights reserved.
4 *
5 * This file is distributed under the terms in the attached LICENSE file.
6 * If you do not find this file, copies can be found by writing to:
7 * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
8 */
9
10#include <stdlib.h>
11#include <stdio.h>
12#include <barrelfish/barrelfish.h>
13#include <barrelfish/nameservice_client.h>
14
15#include <usb/usb.h>
16
17#include <if/keyboard_defs.h>
18
19#include "usb_keyboard_service.h"
20
21/*
22 * Service Variables
23 */
24
25/// name of the keyboard service
26static const char *keyboard_service_name = "keyboard";
27
28/// connected keyboard clients
29static struct keyboard_binding *keyboard_clients = NULL;
30
31static volatile uint8_t keyboard_service_registered = 0;
32
33
34/*
35 * Flounder callbacks
36 */
37
38/**
39 *
40 */
41static errval_t usb_keyboard_connect_handler(void *st,
42        struct keyboard_binding *b)
43{
44    USB_DEBUG("usb_keyboard_connect_handler()\n");
45    // add to list of clients
46    // XXX: abusing st pointer for list node
47    b->st = keyboard_clients;
48    keyboard_clients = b;
49    return (SYS_ERR_OK);
50}
51
52/**
53 *
54 */
55static void usb_keyboard_export_cb(void *st, errval_t err, iref_t iref)
56{
57    assert(err_is_ok(err));
58    err = nameservice_register(keyboard_service_name, iref);
59    assert(err_is_ok(err));
60
61    keyboard_service_registered = 1;
62}
63
64/*
65 *
66 */
67
68
69
70/**
71 * \brief   broadcasts the key event to all clients
72 *
73 * \param   scancode
74 * \param   extended
75 */
76void key_event(uint8_t scancode, bool extended)
77{
78    struct keyboard_binding *c;
79    errval_t err;
80
81    for (c = keyboard_clients; c != NULL; c = c->st) {
82        err = c->tx_vtbl.key_event(c, NOP_CONT, scancode, extended);
83        if (err_is_fail(err)) {
84            DEBUG_ERR(err, "unable to send key event");
85        }
86    }
87}
88
89/**
90 * \brief   initialize the service and exports it
91 */
92errval_t usb_keyboard_service_init(void)
93{
94    errval_t err;
95
96    err = keyboard_export(NULL, usb_keyboard_export_cb,
97            usb_keyboard_connect_handler, get_default_waitset(),
98            IDC_EXPORT_FLAGS_DEFAULT);
99
100    if (err_is_fail(err)) {
101        debug_printf("ERROR: Could not export the service\n");
102        return (err);
103    }
104
105    while (!keyboard_service_registered) {
106        event_dispatch(get_default_waitset());
107    }
108
109    return (SYS_ERR_OK);
110}
111