HelenOS sources
This source file includes following definitions.
- dispcfg_open
- dispcfg_callback_create
- dispcfg_close
- dispcfg_get_seat_list
- dispcfg_free_seat_list
- dispcfg_get_seat_info
- dispcfg_free_seat_info
- dispcfg_seat_create
- dispcfg_seat_delete
- dispcfg_dev_assign
- dispcfg_dev_unassign
- dispcfg_get_asgn_dev_list
- dispcfg_free_dev_list
- dispcfg_get_event
- dispcfg_ev_pending
- dispcfg_cb_conn
#include <async.h>
#include <dispcfg.h>
#include <errno.h>
#include <fibril_synch.h>
#include <ipc/dispcfg.h>
#include <ipc/services.h>
#include <loc.h>
#include <mem.h>
#include <stdlib.h>
#include <str.h>
#include "../private/dispcfg.h"
static errno_t dispcfg_callback_create(dispcfg_t *);
static void dispcfg_cb_conn(ipc_call_t *, void *);
errno_t dispcfg_open(const char *wmname, dispcfg_cb_t *cb, void *cb_arg,
dispcfg_t **rdispcfg)
{
service_id_t dispcfg_svc;
dispcfg_t *dispcfg;
errno_t rc;
dispcfg = calloc(1, sizeof(dispcfg_t));
if (dispcfg == NULL)
return ENOMEM;
dispcfg->cb = cb;
dispcfg->cb_arg = cb_arg;
fibril_mutex_initialize(&dispcfg->lock);
fibril_condvar_initialize(&dispcfg->cv);
if (wmname == NULL)
wmname = SERVICE_NAME_DISPCFG;
rc = loc_service_get_id(wmname, &dispcfg_svc, 0);
if (rc != EOK) {
free(dispcfg);
return ENOENT;
}
dispcfg->sess = loc_service_connect(dispcfg_svc, INTERFACE_DISPCFG,
0);
if (dispcfg->sess == NULL) {
free(dispcfg);
return ENOENT;
}
rc = dispcfg_callback_create(dispcfg);
if (rc != EOK) {
async_hangup(dispcfg->sess);
free(dispcfg);
return EIO;
}
*rdispcfg = dispcfg;
return EOK;
}
static errno_t dispcfg_callback_create(dispcfg_t *dispcfg)
{
async_exch_t *exch = async_exchange_begin(dispcfg->sess);
aid_t req = async_send_0(exch, DISPCFG_CALLBACK_CREATE, NULL);
port_id_t port;
errno_t rc = async_create_callback_port(exch, INTERFACE_DISPCFG_CB, 0, 0,
dispcfg_cb_conn, dispcfg, &port);
async_exchange_end(exch);
if (rc != EOK)
return rc;
errno_t retval;
async_wait_for(req, &retval);
return retval;
}
void dispcfg_close(dispcfg_t *dispcfg)
{
fibril_mutex_lock(&dispcfg->lock);
async_hangup(dispcfg->sess);
dispcfg->sess = NULL;
while (!dispcfg->cb_done)
fibril_condvar_wait(&dispcfg->cv, &dispcfg->lock);
fibril_mutex_unlock(&dispcfg->lock);
free(dispcfg);
}
errno_t dispcfg_get_seat_list(dispcfg_t *dispcfg, dispcfg_seat_list_t **rlist)
{
async_exch_t *exch;
aid_t req;
ipc_call_t answer;
dispcfg_seat_list_t *list;
sysarg_t nseats;
sysarg_t *seats;
errno_t rc;
exch = async_exchange_begin(dispcfg->sess);
req = async_send_0(exch, DISPCFG_GET_SEAT_LIST, &answer);
rc = async_data_read_start(exch, &nseats, sizeof (nseats));
if (rc != EOK) {
async_exchange_end(exch);
async_wait_for(req, &rc);
return rc;
}
seats = calloc(nseats, sizeof(sysarg_t));
if (seats == NULL) {
async_exchange_end(exch);
async_forget(req);
return ENOMEM;
}
rc = async_data_read_start(exch, seats, nseats * sizeof (sysarg_t));
async_exchange_end(exch);
if (rc != EOK) {
async_forget(req);
return rc;
}
async_wait_for(req, &rc);
if (rc != EOK)
return rc;
list = calloc(1, sizeof(dispcfg_seat_list_t));
if (list == NULL)
return ENOMEM;
list->nseats = nseats;
list->seats = seats;
*rlist = list;
return EOK;
}
void dispcfg_free_seat_list(dispcfg_seat_list_t *list)
{
free(list->seats);
free(list);
}
errno_t dispcfg_get_seat_info(dispcfg_t *dispcfg, sysarg_t seat_id,
dispcfg_seat_info_t **rinfo)
{
async_exch_t *exch;
aid_t req;
ipc_call_t answer;
dispcfg_seat_info_t *info;
sysarg_t namesize;
char *name;
errno_t rc;
exch = async_exchange_begin(dispcfg->sess);
req = async_send_1(exch, DISPCFG_GET_SEAT_INFO, seat_id, &answer);
rc = async_data_read_start(exch, &namesize, sizeof (namesize));
if (rc != EOK) {
async_exchange_end(exch);
async_wait_for(req, &rc);
return rc;
}
name = calloc(namesize + 1, sizeof(char));
if (name == NULL) {
async_exchange_end(exch);
async_forget(req);
return ENOMEM;
}
rc = async_data_read_start(exch, name, namesize);
async_exchange_end(exch);
if (rc != EOK) {
async_forget(req);
return rc;
}
async_wait_for(req, &rc);
if (rc != EOK)
return rc;
name[namesize] = '\0';
info = calloc(1, sizeof(dispcfg_seat_info_t));
if (info == NULL)
return ENOMEM;
info->name = name;
*rinfo = info;
return EOK;
}
void dispcfg_free_seat_info(dispcfg_seat_info_t *info)
{
free(info->name);
free(info);
}
errno_t dispcfg_seat_create(dispcfg_t *dispcfg, const char *name,
sysarg_t *rseat_id)
{
async_exch_t *exch;
aid_t req;
ipc_call_t answer;
size_t name_size;
errno_t rc;
name_size = str_size(name);
exch = async_exchange_begin(dispcfg->sess);
req = async_send_0(exch, DISPCFG_SEAT_CREATE, &answer);
rc = async_data_write_start(exch, name, name_size);
async_exchange_end(exch);
if (rc != EOK) {
async_forget(req);
return rc;
}
async_wait_for(req, &rc);
if (rc != EOK)
return rc;
*rseat_id = ipc_get_arg1(&answer);
return EOK;
}
errno_t dispcfg_seat_delete(dispcfg_t *dispcfg, sysarg_t seat_id)
{
async_exch_t *exch;
errno_t rc;
exch = async_exchange_begin(dispcfg->sess);
rc = async_req_1_0(exch, DISPCFG_SEAT_DELETE, seat_id);
async_exchange_end(exch);
return rc;
}
errno_t dispcfg_dev_assign(dispcfg_t *dispcfg, sysarg_t svc_id,
sysarg_t seat_id)
{
async_exch_t *exch;
errno_t rc;
exch = async_exchange_begin(dispcfg->sess);
rc = async_req_2_0(exch, DISPCFG_DEV_ASSIGN, svc_id, seat_id);
async_exchange_end(exch);
return rc;
}
errno_t dispcfg_dev_unassign(dispcfg_t *dispcfg, sysarg_t svc_id)
{
async_exch_t *exch;
errno_t rc;
exch = async_exchange_begin(dispcfg->sess);
rc = async_req_1_0(exch, DISPCFG_DEV_UNASSIGN, svc_id);
async_exchange_end(exch);
return rc;
}
errno_t dispcfg_get_asgn_dev_list(dispcfg_t *dispcfg, sysarg_t seat_id,
dispcfg_dev_list_t **rlist)
{
async_exch_t *exch;
aid_t req;
ipc_call_t answer;
dispcfg_dev_list_t *list;
sysarg_t ndevs;
sysarg_t *devs;
errno_t rc;
exch = async_exchange_begin(dispcfg->sess);
req = async_send_1(exch, DISPCFG_GET_ASGN_DEV_LIST, seat_id, &answer);
rc = async_data_read_start(exch, &ndevs, sizeof (ndevs));
if (rc != EOK) {
async_exchange_end(exch);
async_wait_for(req, &rc);
return rc;
}
devs = calloc(ndevs, sizeof(sysarg_t));
if (devs == NULL) {
async_exchange_end(exch);
async_forget(req);
return ENOMEM;
}
rc = async_data_read_start(exch, devs, ndevs * sizeof (sysarg_t));
async_exchange_end(exch);
if (rc != EOK) {
async_forget(req);
return rc;
}
async_wait_for(req, &rc);
if (rc != EOK)
return rc;
list = calloc(1, sizeof(dispcfg_dev_list_t));
if (list == NULL)
return ENOMEM;
list->ndevs = ndevs;
list->devs = devs;
*rlist = list;
return EOK;
}
void dispcfg_free_dev_list(dispcfg_dev_list_t *list)
{
free(list->devs);
free(list);
}
static errno_t dispcfg_get_event(dispcfg_t *dispcfg, dispcfg_ev_t *event)
{
async_exch_t *exch;
ipc_call_t answer;
aid_t req;
errno_t rc;
exch = async_exchange_begin(dispcfg->sess);
req = async_send_0(exch, DISPCFG_GET_EVENT, &answer);
rc = async_data_read_start(exch, event, sizeof(*event));
async_exchange_end(exch);
if (rc != EOK) {
async_forget(req);
return rc;
}
async_wait_for(req, &rc);
if (rc != EOK)
return rc;
return EOK;
}
static void dispcfg_ev_pending(dispcfg_t *dispcfg, ipc_call_t *icall)
{
errno_t rc;
dispcfg_ev_t event;
while (true) {
fibril_mutex_lock(&dispcfg->lock);
if (dispcfg->sess != NULL)
rc = dispcfg_get_event(dispcfg, &event);
else
rc = ENOENT;
fibril_mutex_unlock(&dispcfg->lock);
if (rc != EOK)
break;
switch (event.etype) {
case dcev_seat_added:
if (dispcfg->cb != NULL &&
dispcfg->cb->seat_added != NULL) {
dispcfg->cb->seat_added(dispcfg->cb_arg,
event.seat_id);
}
break;
case dcev_seat_removed:
if (dispcfg->cb != NULL &&
dispcfg->cb->seat_removed != NULL) {
dispcfg->cb->seat_removed(dispcfg->cb_arg,
event.seat_id);
}
break;
}
}
async_answer_0(icall, EOK);
}
static void dispcfg_cb_conn(ipc_call_t *icall, void *arg)
{
dispcfg_t *dispcfg = (dispcfg_t *) arg;
while (true) {
ipc_call_t call;
async_get_call(&call);
if (!ipc_get_imethod(&call)) {
async_answer_0(&call, EOK);
goto out;
}
switch (ipc_get_imethod(&call)) {
case DISPCFG_EV_PENDING:
dispcfg_ev_pending(dispcfg, &call);
break;
default:
async_answer_0(&call, ENOTSUP);
break;
}
}
out:
fibril_mutex_lock(&dispcfg->lock);
dispcfg->cb_done = true;
fibril_mutex_unlock(&dispcfg->lock);
fibril_condvar_broadcast(&dispcfg->cv);
}
HelenOS homepage, sources at GitHub