HelenOS sources
This source file includes following definitions.
- adb_mouse_event_button
- adb_mouse_event_move
- adb_mouse_data
- adb_mouse_events
- adb_mouse_add
- adb_mouse_remove
- adb_mouse_gone
- adb_mouse_conn
#include <async.h>
#include <ddf/log.h>
#include <errno.h>
#include <ipc/adb.h>
#include <ipc/mouseev.h>
#include <loc.h>
#include <stdio.h>
#include "adb-mouse.h"
static void adb_mouse_conn(ipc_call_t *, void *);
static void adb_mouse_event_button(adb_mouse_t *mouse, int bnum, int bpress)
{
async_exch_t *exch = async_exchange_begin(mouse->client_sess);
async_msg_2(exch, MOUSEEV_BUTTON_EVENT, bnum, bpress);
async_exchange_end(exch);
}
static void adb_mouse_event_move(adb_mouse_t *mouse, int dx, int dy, int dz)
{
async_exch_t *exch = async_exchange_begin(mouse->client_sess);
async_msg_3(exch, MOUSEEV_MOVE_EVENT, dx, dy, dz);
async_exchange_end(exch);
}
static void adb_mouse_data(adb_mouse_t *mouse, sysarg_t data)
{
bool b1, b2;
uint16_t udx, udy;
int dx, dy;
b1 = ((data >> 15) & 1) == 0;
udy = (data >> 8) & 0x7f;
b2 = ((data >> 7) & 1) == 0;
udx = data & 0x7f;
dx = (udx & 0x40) ? (udx - 0x80) : udx;
dy = (udy & 0x40) ? (udy - 0x80) : udy;
if (b1 != mouse->b1_pressed) {
adb_mouse_event_button(mouse, 1, b1);
mouse->b1_pressed = b1;
}
if (b2 != mouse->b2_pressed) {
adb_mouse_event_button(mouse, 2, b2);
mouse->b2_pressed = b2;
}
if (dx != 0 || dy != 0)
adb_mouse_event_move(mouse, dx, dy, 0);
}
static void adb_mouse_events(ipc_call_t *icall, void *arg)
{
adb_mouse_t *mouse = (adb_mouse_t *) arg;
while (true) {
ipc_call_t call;
async_get_call(&call);
errno_t retval = EOK;
if (!ipc_get_imethod(&call)) {
return;
}
switch (ipc_get_imethod(&call)) {
case ADB_REG_NOTIF:
adb_mouse_data(mouse, ipc_get_arg1(&call));
break;
default:
retval = ENOENT;
}
async_answer_0(&call, retval);
}
}
errno_t adb_mouse_add(adb_mouse_t *mouse)
{
errno_t rc;
bool bound = false;
mouse->fun = ddf_fun_create(mouse->dev, fun_exposed, "a");
if (mouse->fun == NULL) {
ddf_msg(LVL_ERROR, "Error creating function");
rc = ENOMEM;
goto error;
}
mouse->parent_sess = ddf_dev_parent_sess_get(mouse->dev);
if (mouse->parent_sess == NULL) {
ddf_msg(LVL_ERROR, "Error connecting parent driver");
rc = EIO;
goto error;
}
async_exch_t *exch = async_exchange_begin(mouse->parent_sess);
if (exch == NULL) {
ddf_msg(LVL_ERROR, "Error starting exchange with parent");
rc = ENOMEM;
goto error;
}
port_id_t port;
rc = async_create_callback_port(exch, INTERFACE_ADB_CB, 0, 0,
adb_mouse_events, mouse, &port);
async_exchange_end(exch);
if (rc != EOK) {
ddf_msg(LVL_ERROR, "Error creating callback from device");
goto error;
}
ddf_fun_set_conn_handler(mouse->fun, adb_mouse_conn);
rc = ddf_fun_bind(mouse->fun);
if (rc != EOK) {
ddf_msg(LVL_ERROR, "Error binding function");
goto error;
}
bound = true;
rc = ddf_fun_add_to_category(mouse->fun, "mouse");
if (rc != EOK) {
ddf_msg(LVL_ERROR, "Error adding function to category");
goto error;
}
return EOK;
error:
if (bound)
ddf_fun_unbind(mouse->fun);
if (mouse->parent_sess != NULL) {
async_hangup(mouse->parent_sess);
mouse->parent_sess = NULL;
}
if (mouse->fun != NULL) {
ddf_fun_destroy(mouse->fun);
mouse->fun = NULL;
}
return rc;
}
errno_t adb_mouse_remove(adb_mouse_t *con)
{
return ENOTSUP;
}
errno_t adb_mouse_gone(adb_mouse_t *con)
{
return ENOTSUP;
}
static void adb_mouse_conn(ipc_call_t *icall, void *arg)
{
ipc_call_t call;
sysarg_t method;
adb_mouse_t *mouse;
async_accept_0(icall);
mouse = (adb_mouse_t *)ddf_dev_data_get(ddf_fun_get_dev((ddf_fun_t *)arg));
while (true) {
async_get_call(&call);
method = ipc_get_imethod(&call);
if (!method) {
async_answer_0(&call, EOK);
return;
}
async_sess_t *sess =
async_callback_receive_start(EXCHANGE_SERIALIZE, &call);
if (sess != NULL) {
mouse->client_sess = sess;
async_answer_0(&call, EOK);
} else {
async_answer_0(&call, EINVAL);
}
}
}
HelenOS homepage, sources at GitHub