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 & WINMGR_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 & WINMGR_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; }