aboutsummaryrefslogtreecommitdiff
path: root/nuttx/graphics/nxmu
diff options
context:
space:
mode:
Diffstat (limited to 'nuttx/graphics/nxmu')
-rw-r--r--nuttx/graphics/nxmu/nx_bitmap.c29
-rw-r--r--nuttx/graphics/nxmu/nx_block.c2
-rw-r--r--nuttx/graphics/nxmu/nx_getrectangle.c30
-rw-r--r--nuttx/graphics/nxmu/nxfe.h21
-rw-r--r--nuttx/graphics/nxmu/nxmu_kbdin.c2
-rw-r--r--nuttx/graphics/nxmu/nxmu_mouse.c46
-rw-r--r--nuttx/graphics/nxmu/nxmu_redrawreq.c2
-rw-r--r--nuttx/graphics/nxmu/nxmu_reportposition.c2
-rw-r--r--nuttx/graphics/nxmu/nxmu_sendwindow.c44
-rw-r--r--nuttx/graphics/nxmu/nxmu_server.c10
10 files changed, 168 insertions, 20 deletions
diff --git a/nuttx/graphics/nxmu/nx_bitmap.c b/nuttx/graphics/nxmu/nx_bitmap.c
index a86eda96a..a0bd748b0 100644
--- a/nuttx/graphics/nxmu/nx_bitmap.c
+++ b/nuttx/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/nuttx/graphics/nxmu/nx_block.c b/nuttx/graphics/nxmu/nx_block.c
index 3a051f9d7..7b198613c 100644
--- a/nuttx/graphics/nxmu/nx_block.c
+++ b/nuttx/graphics/nxmu/nx_block.c
@@ -140,7 +140,7 @@ int nx_block(NXWINDOW hwnd, FAR void *arg)
* that it will not be blocked.
*/
- ret = nxmu_sendserver(wnd->conn, &outmsg, sizeof(struct nxbe_window_s));
+ ret = nxmu_sendserver(wnd->conn, &outmsg, sizeof(struct nxsvrmsg_blocked_s));
}
return ret;
diff --git a/nuttx/graphics/nxmu/nx_getrectangle.c b/nuttx/graphics/nxmu/nx_getrectangle.c
index f32065129..9b7d3679c 100644
--- a/nuttx/graphics/nxmu/nx_getrectangle.c
+++ b/nuttx/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/nuttx/graphics/nxmu/nxfe.h b/nuttx/graphics/nxmu/nxfe.h
index 8b6a21ef4..b9e02616c 100644
--- a/nuttx/graphics/nxmu/nxfe.h
+++ b/nuttx/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 */
@@ -587,6 +589,25 @@ 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
*
* Description:
diff --git a/nuttx/graphics/nxmu/nxmu_kbdin.c b/nuttx/graphics/nxmu/nxmu_kbdin.c
index 2c658009b..0308c2bfa 100644
--- a/nuttx/graphics/nxmu/nxmu_kbdin.c
+++ b/nuttx/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/nuttx/graphics/nxmu/nxmu_mouse.c b/nuttx/graphics/nxmu/nxmu_mouse.c
index 3ebe062d2..1b8f4a592 100644
--- a/nuttx/graphics/nxmu/nxmu_mouse.c
+++ b/nuttx/graphics/nxmu/nxmu_mouse.c
@@ -61,9 +61,10 @@
* Private Data
****************************************************************************/
-static struct nxgl_point_s g_mpos;
-static struct nxgl_point_s g_mrange;
-static uint8_t g_mbutton;
+static struct nxgl_point_s g_mpos;
+static struct nxgl_point_s g_mrange;
+static uint8_t g_mbutton;
+static struct nxbe_window_s *g_mwnd;
/****************************************************************************
* Public Data
@@ -129,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));
}
}
@@ -154,6 +155,7 @@ int nxmu_mousein(FAR struct nxfe_state_s *fe,
struct nxbe_window_s *wnd;
nxgl_coord_t x = pos->x;
nxgl_coord_t y = pos->y;
+ uint8_t oldbuttons;
int ret;
/* Clip x and y to within the bounding rectangle */
@@ -182,20 +184,36 @@ int nxmu_mousein(FAR struct nxfe_state_s *fe,
{
/* Update the mouse value */
- g_mpos.x = x;
- g_mpos.y = y;
- g_mbutton = buttons;
+ oldbuttons = g_mbutton;
+ g_mpos.x = x;
+ g_mpos.y = y;
+ g_mbutton = buttons;
- /* Pick the window to receive the mouse event. Start with
- * the top window and go down. Stop with the first window
- * that gets the mouse report
+ /* If a button is already down, regard this as part of a mouse drag
+ * event. Pass all the following events to the window where the drag
+ * started in.
+ */
+
+ if (oldbuttons && g_mwnd && g_mwnd->cb->mousein)
+ {
+ struct nxclimsg_mousein_s outmsg;
+ outmsg.msgid = NX_CLIMSG_MOUSEIN;
+ outmsg.wnd = g_mwnd;
+ outmsg.buttons = g_mbutton;
+ nxgl_vectsubtract(&outmsg.pos, &g_mpos, &g_mwnd->bounds.pt1);
+
+ return nxmu_sendclientwindow(g_mwnd, &outmsg, sizeof(struct nxclimsg_mousein_s));
+ }
+
+ /* Pick the window to receive the mouse event. Start with the top
+ * window and go down. Stop with the first window that gets the mouse
+ * report
*/
for (wnd = fe->be.topwnd; wnd; wnd = wnd->below)
{
- /* The background window normally has no callback structure
- * (unless a client has taken control of the background via
- * nx_requestbkgd()).
+ /* The background window normally has no callback structure (unless
+ * a client has taken control of the background via nx_requestbkgd()).
*/
if (wnd->cb)
@@ -207,6 +225,8 @@ int nxmu_mousein(FAR struct nxfe_state_s *fe,
}
}
}
+
+ g_mwnd = wnd;
}
return OK;
diff --git a/nuttx/graphics/nxmu/nxmu_redrawreq.c b/nuttx/graphics/nxmu/nxmu_redrawreq.c
index 32ca477a2..f54aa85a7 100644
--- a/nuttx/graphics/nxmu/nxmu_redrawreq.c
+++ b/nuttx/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/nuttx/graphics/nxmu/nxmu_reportposition.c b/nuttx/graphics/nxmu/nxmu_reportposition.c
index f9b5f9daf..6ffb3f4ee 100644
--- a/nuttx/graphics/nxmu/nxmu_reportposition.c
+++ b/nuttx/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/nuttx/graphics/nxmu/nxmu_sendwindow.c b/nuttx/graphics/nxmu/nxmu_sendwindow.c
index 6f64ffff2..0826a45bc 100644
--- a/nuttx/graphics/nxmu/nxmu_sendwindow.c
+++ b/nuttx/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/nuttx/graphics/nxmu/nxmu_server.c b/nuttx/graphics/nxmu/nxmu_server.c
index 2730e0ea2..cfaa5bbf5 100644
--- a/nuttx/graphics/nxmu/nxmu_server.c
+++ b/nuttx/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;