Interaction with PPS control object of a simple window manager.
/*
* $QNXLicenseC:
* Copyright 2012, QNX Software Systems Limited. All Rights Reserved.
*
* This software is QNX Confidential Information subject to
* confidentiality restrictions. DISCLOSURE OF THIS SOFTWARE
* IS PROHIBITED UNLESS AUTHORIZED BY QNX SOFTWARE SYSTEMS IN
* WRITING.
*
* You must obtain a written license from and pay applicable license
* fees to QNX Software Systems Limited before you may reproduce, modify
* or distribute this software, or any work that includes all or part
* of this software. For more information visit
* http://licensing.qnx.com or email licensing@qnx.com.
*
* This file may contain contributions from others. Please review
* this entire file for other proprietary rights or license notices,
* as well as the QNX Development Suite License Guide at
* http://licensing.qnx.com/license-guide/ for other information.
* $
*/
#include "struct.h"
static int pps_parse(window_manager_t *winmgr, char* reqbuf);
/**
* pps thread loop
*/
void* pps_thread(void *arg){
window_manager_t *winmgr = (window_manager_t*)arg;
char buf[1024];
int fd = -1;
int nread = -1;
pthread_setname_np(winmgr->pps_tid = pthread_self(), "pps");
while (1) {
while (fd == -1){
if (winmgr->state & NAV_TERMINATE){
goto terminate;
}
if ((fd = open ("/pps/services/launcher/control?wait,delta", O_RDWR)) == -1 ){
sleep(1);
} else {
winmgr->pps_fd = fd;
}
}
while (nread == -1){
if (winmgr->state & NAV_TERMINATE){
goto terminate;
}
nread = read(fd, buf, sizeof(buf)-1);
if (nread > 1){
buf[nread] = '\0';
// process received message
if(pps_parse(winmgr, buf) == EOK
&& !(winmgr->ptype == PPS_EVENT_OBJECT_CHANGED
&& !winmgr->numattrs)
&& winmgr->ptype != PPS_EVENT_OBJECT_UNKNOWN) {
launcher_pps(winmgr);
}
}
}
if (nread == -1 && errno == EBADF){
fd = -1;
}
nread = -1;
}
terminate:
close(fd);
pthread_exit(NULL);
return NULL;
}
int pps_write(int pps_fd, const char *msgbuf, int msgsize)
{
int ret = 0;
ret = write(pps_fd, msgbuf, (unsigned)msgsize);
return ret;
}
int pps_is_open(int pps_fd)
{
int ret = 1;
if(pps_fd == 0 || pps_fd == -1) {
ret = 0;
}
return ret;
}
pps_attr_t*
pps_lookup_attr(window_manager_t *winmgr, char *name)
{
int i;
for (i = 0; i < winmgr->numattrs; ++i)
if (strcmp(winmgr->attrs[i].name, name) == 0)
return &(winmgr->attrs[i]);
return NULL;
}
char *
pps_lookup(window_manager_t *winmgr, char *name)
{
pps_attr_t* attr = pps_lookup_attr(winmgr, name);
if (!attr)
return NULL;
if (attr->value)
return attr->value;
else
return attr->name;
}
static
int
pps_parse_attr(window_manager_t *winmgr, const pps_attrib_t* info)
{
if(winmgr->numattrs >= MAX_ATTRS) {
SLOG_NOTICE("Too many attributes.");
return E2BIG;
} else {
winmgr->attrs[winmgr->numattrs].name = info->attr_name;
winmgr->attrs[winmgr->numattrs].encoding = info->encoding;
winmgr->attrs[winmgr->numattrs++].value = info->value;
return EOK;
}
}
static int
pps_parse(window_manager_t *winmgr, char* reqbuf)
{
pps_attrib_t info;
pps_status_t rc;
// Clear the request structure
winmgr->numattrs = 0;
winmgr->objname = NULL;
winmgr->ptype = PPS_EVENT_OBJECT_UNKNOWN;
while((rc = ppsparse(&reqbuf, NULL, NULL, &info, 0)) != PPS_END) {
switch(rc) {
case PPS_OBJECT_CREATED:
winmgr->objname = info.obj_name;
winmgr->ptype = PPS_EVENT_OBJECT_CREATED;
break;
case PPS_OBJECT_TRUNCATED:
case PPS_OBJECT_DELETED:
winmgr->objname = info.obj_name;
winmgr->ptype = PPS_EVENT_OBJECT_DELETED;
break;
case PPS_OBJECT:
if(info.obj_name[0] != '@') {
return EOK;
}
winmgr->objname = info.obj_name;
winmgr->ptype = PPS_EVENT_OBJECT_CHANGED;
break;
case PPS_ATTRIBUTE_DELETED: {
--info.attr_name;
int err = pps_parse_attr(winmgr, &info);
if(err != EOK)
return err;
break;
}
case PPS_ATTRIBUTE: {
int err = pps_parse_attr(winmgr, &info);
if(err != EOK)
return err;
break;
}
case PPS_ERROR:
default:
SLOG_WARNING("We got a parsing error.");
return EINVAL;
}
}
return EOK;
}