HelenOS sources
This source file includes following definitions.
- kbdev_new
- kbdev_destroy
- kbdev_ctl_init
- kbdev_ctl_set_ind
- kbdev_callback_conn
#include <async.h>
#include <stdbool.h>
#include <errno.h>
#include <io/console.h>
#include <io/keycode.h>
#include <ipc/kbdev.h>
#include <loc.h>
#include <stdlib.h>
#include <vfs/vfs_sess.h>
#include "../gsp.h"
#include "../input.h"
#include "../kbd.h"
#include "../kbd_ctl.h"
#include "../kbd_port.h"
static errno_t kbdev_ctl_init(kbd_dev_t *);
static void kbdev_ctl_set_ind(kbd_dev_t *, unsigned int);
static void kbdev_callback_conn(ipc_call_t *, void *arg);
kbd_ctl_ops_t kbdev_ctl = {
.parse = NULL,
.init = kbdev_ctl_init,
.set_ind = kbdev_ctl_set_ind
};
typedef struct {
kbd_dev_t *kbd_dev;
async_sess_t *sess;
} kbdev_t;
static kbdev_t *kbdev_new(kbd_dev_t *kdev)
{
kbdev_t *kbdev = calloc(1, sizeof(kbdev_t));
if (kbdev == NULL)
return NULL;
kbdev->kbd_dev = kdev;
return kbdev;
}
static void kbdev_destroy(kbdev_t *kbdev)
{
if (kbdev->sess != NULL)
async_hangup(kbdev->sess);
free(kbdev);
}
static errno_t kbdev_ctl_init(kbd_dev_t *kdev)
{
async_sess_t *sess = loc_service_connect(kdev->svc_id,
INTERFACE_DDF, 0);
if (sess == NULL) {
printf("%s: Failed starting session with '%s.'\n", NAME,
kdev->svc_name);
return ENOENT;
}
kbdev_t *kbdev = kbdev_new(kdev);
if (kbdev == NULL) {
printf("%s: Failed allocating device structure for '%s'.\n",
NAME, kdev->svc_name);
async_hangup(sess);
return ENOMEM;
}
kbdev->sess = sess;
async_exch_t *exch = async_exchange_begin(sess);
if (exch == NULL) {
printf("%s: Failed starting exchange with '%s'.\n", NAME,
kdev->svc_name);
kbdev_destroy(kbdev);
return ENOENT;
}
port_id_t port;
errno_t rc = async_create_callback_port(exch, INTERFACE_KBD_CB, 0, 0,
kbdev_callback_conn, kbdev, &port);
if (rc != EOK) {
printf("%s: Failed creating callback connection from '%s'.\n",
NAME, kdev->svc_name);
async_exchange_end(exch);
kbdev_destroy(kbdev);
return rc;
}
async_exchange_end(exch);
kdev->ctl_private = (void *) kbdev;
return 0;
}
static void kbdev_ctl_set_ind(kbd_dev_t *kdev, unsigned mods)
{
async_sess_t *sess = ((kbdev_t *) kdev->ctl_private)->sess;
async_exch_t *exch = async_exchange_begin(sess);
if (!exch)
return;
async_msg_1(exch, KBDEV_SET_IND, mods);
async_exchange_end(exch);
}
static void kbdev_callback_conn(ipc_call_t *icall, void *arg)
{
kbdev_t *kbdev;
errno_t retval;
int type, key;
kbdev = arg;
while (true) {
ipc_call_t call;
async_get_call(&call);
if (!ipc_get_imethod(&call)) {
async_answer_0(&call, EOK);
kbdev_destroy(kbdev);
return;
}
switch (ipc_get_imethod(&call)) {
case KBDEV_EVENT:
retval = 0;
type = ipc_get_arg1(&call);
key = ipc_get_arg2(&call);
kbd_push_event(kbdev->kbd_dev, type, key);
break;
default:
retval = ENOTSUP;
break;
}
async_answer_0(&call, retval);
}
}
HelenOS homepage, sources at GitHub