From ef9197f052a147755d76e93dcfc7576a856dfe55 Mon Sep 17 00:00:00 2001 From: Vladimir Ananiev Date: Sun, 23 Dec 2007 00:51:14 +0300 Subject: [PATCH 10/10] [neuros] add generic MSG interface Signed-off-by: Vladimir Ananiev --- src/include/nano-X.h | 29 +++++++++++++++++++++++++---- src/nanox/client.c | 31 +++++++++++++++++++++++++++++++ src/nanox/nxproto.h | 11 ++++++++++- src/nanox/srvfunc.c | 43 +++++++++++++++++++++++++++++++++++++++++++ src/nanox/srvnet.c | 13 +++++++++++++ 5 files changed, 122 insertions(+), 5 deletions(-) diff --git a/src/include/nano-X.h b/src/include/nano-X.h index 2aa8669..da57c30 100644 --- a/src/include/nano-X.h +++ b/src/include/nano-X.h @@ -333,6 +333,7 @@ typedef struct { #define GR_EVENT_TYPE_SELECTION_CHANGED 20 #define GR_EVENT_TYPE_TIMER 21 #define GR_EVENT_TYPE_PORTRAIT_CHANGED 22 +#define GR_EVENT_TYPE_MSG 23 /* Event masks */ #define GR_EVENTMASK(n) (((GR_EVENT_MASK) 1) << (n)) @@ -359,8 +360,9 @@ typedef struct { #define GR_EVENT_MASK_CLIENT_DATA_REQ GR_EVENTMASK(GR_EVENT_TYPE_CLIENT_DATA_REQ) #define GR_EVENT_MASK_CLIENT_DATA GR_EVENTMASK(GR_EVENT_TYPE_CLIENT_DATA) #define GR_EVENT_MASK_SELECTION_CHANGED GR_EVENTMASK(GR_EVENT_TYPE_SELECTION_CHANGED) -#define GR_EVENT_MASK_TIMER GR_EVENTMASK(GR_EVENT_TYPE_TIMER) -#define GR_EVENT_MASK_PORTRAIT_CHANGED GR_EVENTMASK(GR_EVENT_TYPE_PORTRAIT_CHANGED) +#define GR_EVENT_MASK_TIMER GR_EVENTMASK(GR_EVENT_TYPE_TIMER) +#define GR_EVENT_MASK_PORTRAIT_CHANGED GR_EVENTMASK(GR_EVENT_TYPE_PORTRAIT_CHANGED) +#define GR_EVENT_MASK_MSG GR_EVENTMASK(GR_EVENT_TYPE_MSG) /* Event mask does not affect GR_EVENT_TYPE_HOTKEY_DOWN and * GR_EVENT_TYPE_HOTKEY_UP, hence no masks for those events. */ @@ -537,6 +539,25 @@ typedef struct { } GR_EVENT_TIMER; /** + * GR_EVENT_TYPE_MSG + */ +// MSG_LEN is set to 64 bytes as a reasonable number with follwing factors in +// consideration, +// 1. it accommodates most cases where message does not need to be split. +// 2. minimize the nano-x server request memory allocation overhead. +// pls note that server allocates EVENT dynamically, and currently GR_EVENT_MSG +// dictates the size of the EVENT. With event queue in place, if EVENT is too big, +// memory requirement can grow pretty quickly. +// +#define NANOX_MAX_MSG_LEN 64 +typedef struct { + GR_EVENT_TYPE type; /**< event type, GR_EVENT_TYPE_MSG */ + GR_WINDOW_ID wid; /**< ID of window MSG is destined for */ + int bytes; /**< msg length. */ + unsigned char msg[NANOX_MAX_MSG_LEN]; /**< msg buffer. */ +} GR_EVENT_MSG; + +/** * Union of all possible event structures. * This is the structure returned by GrGetNextEvent() and similar routines. */ @@ -555,6 +576,7 @@ typedef union { GR_EVENT_CLIENT_DATA clientdata; /**< Client data events */ GR_EVENT_SELECTION_CHANGED selectionchanged; /**< Selection owner changed */ GR_EVENT_TIMER timer; /**< Timer events */ + GR_EVENT_MSG msg; /**< Generic MSG events. */ } GR_EVENT; typedef void (*GR_FNCALLBACKEVENT)(GR_EVENT *); @@ -916,8 +938,7 @@ void GrUnregisterInput(int fd); void GrMainLoop(GR_FNCALLBACKEVENT fncb); GR_FNCALLBACKEVENT GrSetErrorHandler(GR_FNCALLBACKEVENT fncb); void GrDefaultErrorHandler(GR_EVENT *ep); -int GrSnapScreenToImage(const char *path,GR_COORD x, GR_COORD y, - GR_SIZE width, GR_SIZE height); +int GrSendMsg(GR_WINDOW_ID wid, void * msg, int bytes); /* passive library entry points - available with client/server only*/ void GrPrepareSelect(int *maxfd,void *rfdset); diff --git a/src/nanox/client.c b/src/nanox/client.c index 80360b4..e7b7605 100644 --- a/src/nanox/client.c +++ b/src/nanox/client.c @@ -4868,3 +4868,34 @@ GrSnapScreenToImage(const char *path,GR_COORD x, GR_COORD y, UNLOCK(&nxGlobalLock); return ret; } + +/** + * Delivers generic message to given window. + * + * @param wid target window ID. + * @param msg msg pointer. + * @param bytes msg length in bytes. + * @return + * 0 if successful, otherwise -1. + */ +int +GrSendMsg(GR_WINDOW_ID wid, void * msg, int bytes) +{ + int ret; + nxSendMsgReq *req; + + // msg can not be longer than NANOX_MAX_MSG_LEN, see nano-X.h + if (bytes > NANOX_MAX_MSG_LEN || bytes < 0 || wid == -1) return -1; + + LOCK(&nxGlobalLock); + req = AllocReqExtra(SendMsg, bytes); + req->wid = wid; + req->bytes = bytes; + memcpy(GetReqData(req), msg, bytes); + + if (TypedReadBlock(&ret, sizeof(ret), GrNumSendMsg) == -1) + ret = -1; + + UNLOCK(&nxGlobalLock); + return ret; +} diff --git a/src/nanox/nxproto.h b/src/nanox/nxproto.h index a4bc274..0af6ef2 100644 --- a/src/nanox/nxproto.h +++ b/src/nanox/nxproto.h @@ -1395,5 +1395,14 @@ typedef struct { UINT16 height; } nxSnapScreenToImageReq; +#define GrNumSendMsg 127 +typedef struct { + BYTE8 reqType; + BYTE8 hilength; + UINT16 length; + IDTYPE wid; + UINT32 bytes; +} nxSendMsgReq; + -#define GrTotalNumCalls 127 +#define GrTotalNumCalls 128 diff --git a/src/nanox/srvfunc.c b/src/nanox/srvfunc.c index 1a780cd..0747e7d 100644 --- a/src/nanox/srvfunc.c +++ b/src/nanox/srvfunc.c @@ -4347,3 +4347,46 @@ GrSnapScreenToImage(const char *path,GR_COORD x, GR_COORD y, SERVER_UNLOCK(); return ret; } + +/* + * Sends generic message to target wid. + * return 0 if successful, otherwise -1. + */ +int +GrSendMsg(GR_WINDOW_ID wid, void * msg, int bytes) +{ + GR_WINDOW *wp; + GR_EVENT_MSG *emp; /* general msg event */ + GR_EVENT_CLIENT *ecp; /* current event client */ + int ret = -1; + + SERVER_LOCK(); + + if (!(wp = GsFindWindow(wid))) { + //mask "GsError", because it can lead nano-x to exit, and application will be exit too. + //GsError(GR_ERROR_BAD_WINDOW_ID, wid); + DPRINTF("nano-X: ERROR (Bad window id: %d) !\n,",wid); + goto bail; + } + + // deliver msg to all clients. + for (ecp = wp->eventclients; ecp; ecp = ecp->next) { + if ((ecp->eventmask & GR_EVENT_MASK_MSG) == 0) + continue; + + emp = (GR_EVENT_MSG *) GsAllocEvent(ecp->client); + if (emp == NULL) + continue; + + emp->type = GR_EVENT_TYPE_MSG; + emp->wid = wid; + emp->bytes = bytes; + memcpy(emp->msg, msg, bytes); + ret = 0; + } + + bail: + SERVER_UNLOCK(); + return ret; +} + diff --git a/src/nanox/srvnet.c b/src/nanox/srvnet.c index 2b85853..69200a6 100644 --- a/src/nanox/srvnet.c +++ b/src/nanox/srvnet.c @@ -1616,6 +1616,18 @@ GrSnapScreenToImageWrapper(void *r) } +static void +GrSendMsgWrapper(void *r) +{ + nxSendMsgReq *req = r; + int ret; + + ret = GrSendMsg(req->wid, GetReqData(req), req->bytes); + + GsWriteType(current_fd, GrNumSendMsg); + GsWrite(current_fd, &ret, sizeof(ret)); +} + void GrShmCmdsFlushWrapper(void *r); @@ -1754,6 +1766,7 @@ static const struct GrFunction GrFunctions[] = { /* 124 */ {GrCopyFontWrapper, "GrCopyFont"}, /* 125 */ {GrDrawImagePartToFitWrapper, "GrDrawImagePartToFit"}, /* 126 */ {GrSnapScreenToImageWrapper, "GrSnapScreenToImage"}, + /* 127 */ {GrSendMsgWrapper, "GrSendMsg"}, }; void -- 1.5.1.6