From 43dda7996da934aad29f0d7cba8df850bcc10679 Mon Sep 17 00:00:00 2001 From: patacongo Date: Sat, 17 Nov 2012 13:50:59 +0000 Subject: [PATCH] Patches 7-9 from Petteri Aimonen git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@5366 42af7a65-404d-4744-a932-0658087f49c3 --- ChangeLog | 7 +++++ graphics/nxmu/nx_bitmap.c | 29 ++++++++++++++++++- graphics/nxmu/nx_getrectangle.c | 30 ++++++++++++++++++-- graphics/nxmu/nxfe.h | 21 ++++++++++++++ graphics/nxmu/nxmu_kbdin.c | 2 +- graphics/nxmu/nxmu_mouse.c | 4 +-- graphics/nxmu/nxmu_redrawreq.c | 2 +- graphics/nxmu/nxmu_reportposition.c | 2 +- graphics/nxmu/nxmu_sendwindow.c | 44 +++++++++++++++++++++++++++++ graphics/nxmu/nxmu_server.c | 10 +++++++ include/nuttx/wqueue.h | 24 ++++++++++++++-- 11 files changed, 164 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index c53f9c891e..551e5c0fcf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3641,4 +3641,11 @@ window. From Petteri Aimonen. * nuttx/graphics/nxmu/nx_block.c: One more fixe to the NX block message logic from Petteri Aimonen. + * include/nuttx/wqueue.h: Some basic definitions to support a user- + space work queue (someday in the future). + * graphics/nxmu: Add semaphores so buffers messages that send buffers + will block until the buffer data has been acted upon. + * graphics/nxmw: Extended the blocked messages to cover mouse movement + and redraw events. These will also cause problems if sent to a window + while it is closing. diff --git a/graphics/nxmu/nx_bitmap.c b/graphics/nxmu/nx_bitmap.c index a86eda96ac..a0bd748b09 100644 --- a/graphics/nxmu/nx_bitmap.c +++ b/graphics/nxmu/nx_bitmap.c @@ -100,6 +100,8 @@ int nx_bitmap(NXWINDOW hwnd, FAR const struct nxgl_rect_s *dest, FAR struct nxbe_window_s *wnd = (FAR struct nxbe_window_s *)hwnd; struct nxsvrmsg_bitmap_s outmsg; int i; + int ret; + sem_t sem_done; #ifdef CONFIG_DEBUG if (!wnd || !dest || !src || !origin) @@ -124,7 +126,32 @@ int nx_bitmap(NXWINDOW hwnd, FAR const struct nxgl_rect_s *dest, outmsg.origin.y = origin->y; nxgl_rectcopy(&outmsg.dest, dest); + + /* Create a semaphore for tracking command completion */ + + outmsg.sem_done = &sem_done; + ret = sem_init(&sem_done, 0, 0); + + if (ret != OK) + { + gdbg("sem_init failed: %d\n", errno); + return ret; + } + /* Forward the fill command to the server */ - return nxmu_sendwindow(wnd, &outmsg, sizeof(struct nxsvrmsg_bitmap_s)); + ret = nxmu_sendwindow(wnd, &outmsg, sizeof(struct nxsvrmsg_bitmap_s)); + + /* Wait that the command is completed, so that caller can release the buffer. */ + + if (ret == OK) + { + ret = sem_wait(&sem_done); + } + + /* Destroy the semaphore and return. */ + + sem_destroy(&sem_done); + + return ret; } diff --git a/graphics/nxmu/nx_getrectangle.c b/graphics/nxmu/nx_getrectangle.c index f32065129c..9b7d3679c4 100644 --- a/graphics/nxmu/nx_getrectangle.c +++ b/graphics/nxmu/nx_getrectangle.c @@ -98,7 +98,9 @@ int nx_getrectangle(NXWINDOW hwnd, FAR const struct nxgl_rect_s *rect, { FAR struct nxbe_window_s *wnd = (FAR struct nxbe_window_s *)hwnd; struct nxsvrmsg_getrectangle_s outmsg; - + int ret; + sem_t sem_done; + #ifdef CONFIG_DEBUG if (!hwnd || !rect || !dest) { @@ -118,7 +120,31 @@ int nx_getrectangle(NXWINDOW hwnd, FAR const struct nxgl_rect_s *rect, nxgl_rectcopy(&outmsg.rect, rect); + /* Create a semaphore for tracking command completion */ + + outmsg.sem_done = &sem_done; + ret = sem_init(&sem_done, 0, 0); + + if (ret != OK) + { + gdbg("sem_init failed: %d\n", errno); + return ret; + } + /* Forward the fill command to the server */ - return nxmu_sendwindow(wnd, &outmsg, sizeof(struct nxsvrmsg_getrectangle_s)); + ret = nxmu_sendwindow(wnd, &outmsg, sizeof(struct nxsvrmsg_getrectangle_s)); + + /* Wait that the command is completed, so that caller can release the buffer. */ + + if (ret == OK) + { + ret = sem_wait(&sem_done); + } + + /* Destroy the semaphore and return. */ + + sem_destroy(&sem_done); + + return ret; } diff --git a/graphics/nxmu/nxfe.h b/graphics/nxmu/nxfe.h index 8b6a21ef48..b9e02616ce 100644 --- a/graphics/nxmu/nxfe.h +++ b/graphics/nxmu/nxfe.h @@ -392,6 +392,7 @@ struct nxsvrmsg_getrectangle_s unsigned int plane; /* The plane number to read */ FAR uint8_t *dest; /* Memory location in which to store the graphics data */ unsigned int deststride; /* Width of the destination memory in bytes */ + sem_t *sem_done; /* Semaphore to report when command is done. */ }; /* Fill a trapezoidal region in the window with a color */ @@ -425,6 +426,7 @@ struct nxsvrmsg_bitmap_s FAR const void *src[CONFIG_NX_NPLANES]; /* The start of the source image. */ struct nxgl_point_s origin; /* Offset into the source image data */ unsigned int stride; /* The width of the full source image in pixels. */ + sem_t *sem_done; /* Semaphore to report when command is done. */ }; /* Set the color of the background */ @@ -586,6 +588,25 @@ EXTERN int nxmu_sendwindow(FAR struct nxbe_window_s *wnd, FAR const void *msg, EXTERN int nxmu_sendclient(FAR struct nxfe_conn_s *conn, FAR const void *msg, size_t msglen); +/**************************************************************************** + * Name: nxmu_sendclientwindow + * + * Description: + * Send a message to the client at NX_CLIMSG_PRIO priority + * + * Input Parameters: + * wnd - A pointer to the back-end window structure + * msg - A pointer to the message to send + * msglen - The length of the message in bytes. + * + * Return: + * OK on success; ERROR on failure with errno set appropriately + * + ****************************************************************************/ + +int nxmu_sendclientwindow(FAR struct nxbe_window_s *wnd, FAR const void *msg, + size_t msglen); + /**************************************************************************** * Name: nxmu_openwindow * diff --git a/graphics/nxmu/nxmu_kbdin.c b/graphics/nxmu/nxmu_kbdin.c index 2c658009bc..0308c2bfa8 100644 --- a/graphics/nxmu/nxmu_kbdin.c +++ b/graphics/nxmu/nxmu_kbdin.c @@ -108,7 +108,7 @@ void nxmu_kbdin(FAR struct nxfe_state_s *fe, uint8_t nch, FAR uint8_t *ch) outmsg->ch[i] = ch[i]; } - (void)nxmu_sendclient(fe->be.topwnd->conn, outmsg, size); + (void)nxmu_sendclientwindow(fe->be.topwnd, outmsg, size); free(outmsg); } } diff --git a/graphics/nxmu/nxmu_mouse.c b/graphics/nxmu/nxmu_mouse.c index 93441cc01f..1b8f4a5921 100644 --- a/graphics/nxmu/nxmu_mouse.c +++ b/graphics/nxmu/nxmu_mouse.c @@ -130,7 +130,7 @@ int nxmu_mousereport(struct nxbe_window_s *wnd) outmsg.buttons = g_mbutton; nxgl_vectsubtract(&outmsg.pos, &g_mpos, &wnd->bounds.pt1); - return nxmu_sendclient(wnd->conn, &outmsg, sizeof(struct nxclimsg_mousein_s)); + return nxmu_sendclientwindow(wnd, &outmsg, sizeof(struct nxclimsg_mousein_s)); } } @@ -202,7 +202,7 @@ int nxmu_mousein(FAR struct nxfe_state_s *fe, outmsg.buttons = g_mbutton; nxgl_vectsubtract(&outmsg.pos, &g_mpos, &g_mwnd->bounds.pt1); - return nxmu_sendclient(g_mwnd->conn, &outmsg, sizeof(struct nxclimsg_mousein_s)); + return nxmu_sendclientwindow(g_mwnd, &outmsg, sizeof(struct nxclimsg_mousein_s)); } /* Pick the window to receive the mouse event. Start with the top diff --git a/graphics/nxmu/nxmu_redrawreq.c b/graphics/nxmu/nxmu_redrawreq.c index 32ca477a26..f54aa85a7e 100644 --- a/graphics/nxmu/nxmu_redrawreq.c +++ b/graphics/nxmu/nxmu_redrawreq.c @@ -87,7 +87,7 @@ void nxfe_redrawreq(FAR struct nxbe_window_s *wnd, FAR const struct nxgl_rect_s outmsg.more = false; nxgl_rectoffset(&outmsg.rect, rect, -wnd->bounds.pt1.x, -wnd->bounds.pt1.y); - (void)nxmu_sendclient(wnd->conn, &outmsg, sizeof(struct nxclimsg_redraw_s)); + (void)nxmu_sendclientwindow(wnd, &outmsg, sizeof(struct nxclimsg_redraw_s)); } diff --git a/graphics/nxmu/nxmu_reportposition.c b/graphics/nxmu/nxmu_reportposition.c index f9b5f9dafa..6ffb3f4ee7 100644 --- a/graphics/nxmu/nxmu_reportposition.c +++ b/graphics/nxmu/nxmu_reportposition.c @@ -100,7 +100,7 @@ void nxfe_reportposition(FAR struct nxbe_window_s *wnd) /* And provide this to the client */ - ret = nxmu_sendclient(wnd->conn, &outmsg, sizeof(struct nxclimsg_newposition_s)); + ret = nxmu_sendclientwindow(wnd, &outmsg, sizeof(struct nxclimsg_newposition_s)); if (ret < 0) { gdbg("nxmu_sendclient failed: %d\n", errno); diff --git a/graphics/nxmu/nxmu_sendwindow.c b/graphics/nxmu/nxmu_sendwindow.c index 6f64ffff2c..0826a45bc9 100644 --- a/graphics/nxmu/nxmu_sendwindow.c +++ b/graphics/nxmu/nxmu_sendwindow.c @@ -112,3 +112,47 @@ int nxmu_sendwindow(FAR struct nxbe_window_s *wnd, FAR const void *msg, return ret; } + +/**************************************************************************** + * Name: nxmu_sendclientwindow + * + * Description: + * Send a message to the client at NX_CLIMSG_PRIO priority + * + * Input Parameters: + * wnd - A pointer to the back-end window structure + * msg - A pointer to the message to send + * msglen - The length of the message in bytes. + * + * Return: + * OK on success; ERROR on failure with errno set appropriately + * + ****************************************************************************/ + +int nxmu_sendclientwindow(FAR struct nxbe_window_s *wnd, FAR const void *msg, + size_t msglen) +{ + int ret = OK; + + /* Sanity checking */ + +#ifdef CONFIG_DEBUG + if (!wnd || !wnd->conn) + { + errno = EINVAL; + return ERROR; + } +#endif + + /* Ignore messages destined to a blocked window (no errors reported) */ + + if (!NXBE_ISBLOCKED(wnd)) + { + /* Send the message to the server */ + + ret = nxmu_sendclient(wnd->conn, msg, msglen); + } + + return ret; +} + diff --git a/graphics/nxmu/nxmu_server.c b/graphics/nxmu/nxmu_server.c index 2730e0ea28..cfaa5bbf5d 100644 --- a/graphics/nxmu/nxmu_server.c +++ b/graphics/nxmu/nxmu_server.c @@ -451,6 +451,11 @@ int nx_runinstance(FAR const char *mqname, FAR NX_DRIVERTYPE *dev) { FAR struct nxsvrmsg_getrectangle_s *getmsg = (FAR struct nxsvrmsg_getrectangle_s *)buffer; nxbe_getrectangle(getmsg->wnd, &getmsg->rect, getmsg->plane, getmsg->dest, getmsg->deststride); + + if (getmsg->sem_done) + { + sem_post(getmsg->sem_done); + } } break; @@ -471,6 +476,11 @@ int nx_runinstance(FAR const char *mqname, FAR NX_DRIVERTYPE *dev) { FAR struct nxsvrmsg_bitmap_s *bmpmsg = (FAR struct nxsvrmsg_bitmap_s *)buffer; nxbe_bitmap(bmpmsg->wnd, &bmpmsg->dest, bmpmsg->src, &bmpmsg->origin, bmpmsg->stride); + + if (bmpmsg->sem_done) + { + sem_post(bmpmsg->sem_done); + } } break; diff --git a/include/nuttx/wqueue.h b/include/nuttx/wqueue.h index 644585c56f..c509bf197b 100644 --- a/include/nuttx/wqueue.h +++ b/include/nuttx/wqueue.h @@ -109,17 +109,35 @@ # endif #endif -/* Work queue IDs (indices). These are both zero if there is only one work - * queue. +/* Work queue IDs (indices): + * + * Kernel Work Queues: + * HPWORK: This ID of the high priority work queue that should only be used for + * hi-priority, time-critical, driver bottom-half functions. + * + * LPWORK: This is the ID of the low priority work queue that can be used for any + * purpose. if CONFIG_SCHED_LPWORK is not defined, then there is only one kernel + * work queue and LPWORK == HPWORK. + * + * User Work Queue: + * USRWORK: CONFIG_NUTTX_KERNEL and CONFIG_SCHED_USRWORK are defined, then NuttX + * will also support a user-accessible work queue. Otherwise, USRWORK == LPWORK. */ #define HPWORK 0 #ifdef CONFIG_SCHED_LPWORK -# define LPWORK 1 +# define LPWORK (HPWORK+1) #else # define LPWORK HPWORK #endif +#if defined(CONFIG_NUTTX_KERNEL) && defined(CONFIG_SCHED_USRWORK) +# warning "Feature not implemented" +# define USRWORK (LPWORK+1) +#else +# define USRWORK LPWORK +#endif + /**************************************************************************** * Public Types ****************************************************************************/