HelenOS sources
This source file includes following definitions.
- wndmgt_open
- wndmgt_callback_create
- wndmgt_close
- wndmgt_get_window_list
- wndmgt_free_window_list
- wndmgt_get_window_info
- wndmgt_free_window_info
- wndmgt_activate_window
- wndmgt_close_window
- wndmgt_get_event
- wndmgt_ev_pending
- wndmgt_cb_conn
#include <async.h>
#include <wndmgt.h>
#include <errno.h>
#include <fibril_synch.h>
#include <ipc/wndmgt.h>
#include <ipc/services.h>
#include <loc.h>
#include <mem.h>
#include <stdlib.h>
#include "../private/wndmgt.h"
static errno_t wndmgt_callback_create(wndmgt_t *);
static void wndmgt_cb_conn(ipc_call_t *, void *);
errno_t wndmgt_open(const char *wmname, wndmgt_cb_t *cb, void *cb_arg,
wndmgt_t **rwndmgt)
{
service_id_t wndmgt_svc;
wndmgt_t *wndmgt;
errno_t rc;
wndmgt = calloc(1, sizeof(wndmgt_t));
if (wndmgt == NULL)
return ENOMEM;
wndmgt->cb = cb;
wndmgt->cb_arg = cb_arg;
fibril_mutex_initialize(&wndmgt->lock);
fibril_condvar_initialize(&wndmgt->cv);
if (wmname == NULL)
wmname = SERVICE_NAME_WNDMGT;
rc = loc_service_get_id(wmname, &wndmgt_svc, 0);
if (rc != EOK) {
free(wndmgt);
return ENOENT;
}
wndmgt->sess = loc_service_connect(wndmgt_svc, INTERFACE_WNDMGT,
0);
if (wndmgt->sess == NULL) {
free(wndmgt);
return ENOENT;
}
rc = wndmgt_callback_create(wndmgt);
if (rc != EOK) {
async_hangup(wndmgt->sess);
free(wndmgt);
return EIO;
}
*rwndmgt = wndmgt;
return EOK;
}
static errno_t wndmgt_callback_create(wndmgt_t *wndmgt)
{
async_exch_t *exch = async_exchange_begin(wndmgt->sess);
aid_t req = async_send_0(exch, WNDMGT_CALLBACK_CREATE, NULL);
port_id_t port;
errno_t rc = async_create_callback_port(exch, INTERFACE_WNDMGT_CB, 0, 0,
wndmgt_cb_conn, wndmgt, &port);
async_exchange_end(exch);
if (rc != EOK)
return rc;
errno_t retval;
async_wait_for(req, &retval);
return retval;
}
void wndmgt_close(wndmgt_t *wndmgt)
{
fibril_mutex_lock(&wndmgt->lock);
async_hangup(wndmgt->sess);
wndmgt->sess = NULL;
while (!wndmgt->cb_done)
fibril_condvar_wait(&wndmgt->cv, &wndmgt->lock);
fibril_mutex_unlock(&wndmgt->lock);
free(wndmgt);
}
errno_t wndmgt_get_window_list(wndmgt_t *wndmgt, wndmgt_window_list_t **rlist)
{
async_exch_t *exch;
aid_t req;
ipc_call_t answer;
wndmgt_window_list_t *list;
sysarg_t nwindows;
sysarg_t *windows;
errno_t rc;
exch = async_exchange_begin(wndmgt->sess);
req = async_send_0(exch, WNDMGT_GET_WINDOW_LIST, &answer);
rc = async_data_read_start(exch, &nwindows, sizeof (nwindows));
if (rc != EOK) {
async_exchange_end(exch);
async_wait_for(req, &rc);
return rc;
}
windows = calloc(nwindows, sizeof(sysarg_t));
if (windows == NULL) {
async_exchange_end(exch);
async_forget(req);
return ENOMEM;
}
rc = async_data_read_start(exch, windows, nwindows * 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(wndmgt_window_list_t));
if (list == NULL)
return ENOMEM;
list->nwindows = nwindows;
list->windows = windows;
*rlist = list;
return EOK;
}
void wndmgt_free_window_list(wndmgt_window_list_t *list)
{
free(list->windows);
free(list);
}
errno_t wndmgt_get_window_info(wndmgt_t *wndmgt, sysarg_t wnd_id,
wndmgt_window_info_t **rinfo)
{
async_exch_t *exch;
aid_t req;
ipc_call_t answer;
wndmgt_window_info_t *info;
sysarg_t capsize;
char *caption;
errno_t rc;
exch = async_exchange_begin(wndmgt->sess);
req = async_send_1(exch, WNDMGT_GET_WINDOW_INFO, wnd_id, &answer);
rc = async_data_read_start(exch, &capsize, sizeof (capsize));
if (rc != EOK) {
async_exchange_end(exch);
async_wait_for(req, &rc);
return rc;
}
caption = calloc(capsize + 1, sizeof(char));
if (caption == NULL) {
async_exchange_end(exch);
async_forget(req);
return ENOMEM;
}
rc = async_data_read_start(exch, caption, capsize);
async_exchange_end(exch);
if (rc != EOK) {
async_forget(req);
return rc;
}
async_wait_for(req, &rc);
if (rc != EOK)
return rc;
caption[capsize] = '\0';
info = calloc(1, sizeof(wndmgt_window_info_t));
if (info == NULL)
return ENOMEM;
info->caption = caption;
info->flags = ipc_get_arg1(&answer);
info->nfocus = ipc_get_arg2(&answer);
*rinfo = info;
return EOK;
}
void wndmgt_free_window_info(wndmgt_window_info_t *info)
{
free(info->caption);
free(info);
}
errno_t wndmgt_activate_window(wndmgt_t *wndmgt, sysarg_t dev_id,
sysarg_t wnd_id)
{
async_exch_t *exch;
errno_t rc;
exch = async_exchange_begin(wndmgt->sess);
rc = async_req_2_0(exch, WNDMGT_ACTIVATE_WINDOW, dev_id,
wnd_id);
async_exchange_end(exch);
return rc;
}
errno_t wndmgt_close_window(wndmgt_t *wndmgt, sysarg_t wnd_id)
{
async_exch_t *exch;
errno_t rc;
exch = async_exchange_begin(wndmgt->sess);
rc = async_req_1_0(exch, WNDMGT_CLOSE_WINDOW, wnd_id);
async_exchange_end(exch);
return rc;
}
static errno_t wndmgt_get_event(wndmgt_t *wndmgt, wndmgt_ev_t *event)
{
async_exch_t *exch;
ipc_call_t answer;
aid_t req;
errno_t rc;
exch = async_exchange_begin(wndmgt->sess);
req = async_send_0(exch, WNDMGT_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 wndmgt_ev_pending(wndmgt_t *wndmgt, ipc_call_t *icall)
{
errno_t rc;
wndmgt_ev_t event;
while (true) {
fibril_mutex_lock(&wndmgt->lock);
if (wndmgt->sess != NULL)
rc = wndmgt_get_event(wndmgt, &event);
else
rc = ENOENT;
fibril_mutex_unlock(&wndmgt->lock);
if (rc != EOK)
break;
switch (event.etype) {
case wmev_window_added:
if (wndmgt->cb != NULL &&
wndmgt->cb->window_added != NULL) {
wndmgt->cb->window_added(wndmgt->cb_arg,
event.wnd_id);
}
break;
case wmev_window_removed:
if (wndmgt->cb != NULL &&
wndmgt->cb->window_removed != NULL) {
wndmgt->cb->window_removed(wndmgt->cb_arg,
event.wnd_id);
}
break;
case wmev_window_changed:
if (wndmgt->cb != NULL &&
wndmgt->cb->window_changed != NULL) {
wndmgt->cb->window_changed(wndmgt->cb_arg,
event.wnd_id);
}
break;
}
}
async_answer_0(icall, EOK);
}
static void wndmgt_cb_conn(ipc_call_t *icall, void *arg)
{
wndmgt_t *wndmgt = (wndmgt_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 WNDMGT_EV_PENDING:
wndmgt_ev_pending(wndmgt, &call);
break;
default:
async_answer_0(&call, ENOTSUP);
break;
}
}
out:
fibril_mutex_lock(&wndmgt->lock);
wndmgt->cb_done = true;
fibril_mutex_unlock(&wndmgt->lock);
fibril_condvar_broadcast(&wndmgt->cv);
}
HelenOS homepage, sources at GitHub