diff --git a/graphics/README.txt b/graphics/README.txt index 62c956ba6a..5a2e8a19a9 100644 --- a/graphics/README.txt +++ b/graphics/README.txt @@ -71,13 +71,15 @@ graphics/nxbe This is the "back-end" of a tiny windowing system. It contains most of the important window management logic: clipping, window controls, window drawing, etc. Currently, the NXserver is the only "front-end" + (Historically, there was a single user front-end, NXSU, but that front- + end no longer exists). graphics/nxmu libnx/nxmu This is the NX multi user "front end". When combined with the generic "back-end" (nxbe), it implements a multi-threaded, multi-user windowing system. The files in this directory present the window APIs described in - include/nuttx/nx/nx.h. The multi-user front end includes the NX graphics + include/nuttx/nx/nx.h. The multi-user front-end includes the NX graphics server that executes on its own thread; multiple graphics clients then communicate with the server via a POSIX message queue to serialize window operations from many threads. The multi-user front-end is selected diff --git a/graphics/nxbe/Make.defs b/graphics/nxbe/Make.defs index d052c7e6f8..e55f5801ea 100644 --- a/graphics/nxbe/Make.defs +++ b/graphics/nxbe/Make.defs @@ -34,9 +34,10 @@ ############################################################################ CSRCS += nxbe_bitmap.c nxbe_configure.c nxbe_colormap.c nxbe_clipper.c -CSRCS += nxbe_closewindow.c nxbe_fill.c nxbe_filltrapezoid.c -CSRCS += nxbe_getrectangle.c nxbe_lower.c nxbe_move.c nxbe_raise.c -CSRCS += nxbe_redraw.c nxbe_redrawbelow.c nxbe_setpixel.c nxbe_setposition.c +CSRCS += nxbe_closewindow.c nxbe_redraw.c nxbe_redrawbelow.c +CSRCS += nxbe_setposition.c nxbe_move.c nxbe_getrectangle.c +CSRCS += nxbe_fill.c nxbe_filltrapezoid.c nxbe_setpixel.c +CSRCS += nxbe_lower.c nxbe_raise.c nxbe_modal.c CSRCS += nxbe_setsize.c nxbe_visible.c DEPPATH += --dep-path nxbe diff --git a/graphics/nxbe/nxbe.h b/graphics/nxbe/nxbe.h index 0bd5d769bd..dcbb905331 100644 --- a/graphics/nxbe/nxbe.h +++ b/graphics/nxbe/nxbe.h @@ -62,6 +62,23 @@ #define NX_CLIPORDER_BRLT (3) /* Bottom-right-left-top */ #define NX_CLIPORDER_DEFAULT NX_CLIPORDER_TLRB +/* Server flags and helper macros: + * + * NXBE_STATE_MODAL - One window is in a focused, modal state + */ + +#define NXBE_STATE_MODAL (1 << 0) /* Bit 0: One window is in a focused, + * modal state */ + +/* Helpful flag macros */ + +#define NXBE_STATE_ISMODAL(nxbe) \ + (((nxbe)->flags & NXBE_STATE_MODAL) != 0) +#define NXBE_STATE_SETMODAL(nxbe) \ + do { (nxbe)->flags |= NXBE_STATE_MODAL; } while (0) +#define NXBE_STATE_CLRMODAL(nxbe) \ + do { (nxbe)->flags &= ~NXBE_STATE_MODAL; } while (0) + /**************************************************************************** * Public Types ****************************************************************************/ @@ -171,6 +188,8 @@ struct nxbe_clipops_s struct nxbe_state_s { + uint8_t flags; /* NXBE_STATE_* flags */ + /* The window list (with the background window always at the bottom) */ FAR struct nxbe_window_s *topwnd; /* The window at the top of the display */ @@ -295,6 +314,17 @@ void nxbe_raise(FAR struct nxbe_window_s *wnd); void nxbe_lower(FAR struct nxbe_window_s *wnd); +/**************************************************************************** + * Name: nxbe_modal + * + * Description: + * May be used to either (1) raise a window to the top of the display and + * select modal behavior, or (2) disable modal behavior. + * + ****************************************************************************/ + +void nxbe_modal(FAR struct nxbe_window_s *wnd, bool enable); + /**************************************************************************** * Name: nxbe_setpixel * diff --git a/graphics/nxbe/nxbe_closewindow.c b/graphics/nxbe/nxbe_closewindow.c index 10ed635142..b05bd00376 100644 --- a/graphics/nxbe/nxbe_closewindow.c +++ b/graphics/nxbe/nxbe_closewindow.c @@ -1,7 +1,7 @@ /**************************************************************************** * graphics/nxbe/nxbe_closewindow.c * - * Copyright (C) 2008-2009, 2011 Gregory Nutt. All rights reserved. + * Copyright (C) 2008-2009, 2011, 2019 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -81,9 +81,25 @@ void nxbe_closewindow(FAR struct nxbe_window_s *wnd) DEBUGASSERT(wnd != &be->bkgd); + /* Are we closing a modal window? */ + + if (NXBE_ISMODAL(wnd)) + { + /* Yes.. this should be the top window and the back-end should also + * indicate the modal state. + */ + + DEBUGASSERT(wnd->above == NULL & NXBE_STATE_ISMODAL(be)); + + /* Leave the modal state */ + + NXBE_CLRMODAL(wnd); + NXBE_STATE_CLRMODAL(be); + } + /* Is there a window above the one being closed? */ - if (wnd->above) + if (wnd->above != NULL) { /* Yes, now the window below that one is the window below * the one being closed. diff --git a/graphics/nxbe/nxbe_lower.c b/graphics/nxbe/nxbe_lower.c index c01552454b..77bbbba461 100644 --- a/graphics/nxbe/nxbe_lower.c +++ b/graphics/nxbe/nxbe_lower.c @@ -1,7 +1,7 @@ /**************************************************************************** * graphics/nxbe/nxbe_lower.c * - * Copyright (C) 2008-2009, 2011 Gregory Nutt. All rights reserved. + * Copyright (C) 2008-2009, 2011, 2019 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -62,9 +62,11 @@ void nxbe_lower(FAR struct nxbe_window_s *wnd) FAR struct nxbe_state_s *be = wnd->be; FAR struct nxbe_window_s *below; - /* If the window is already at the bottom, then there is nothing to do */ + /* If the window is already at the bottom, then there is nothing to do. + * Refuse to lower the background window; Refuse to lower a modal window. + */ - if (!wnd->below || wnd->below == &be->bkgd) + if (wnd->below == NULL || wnd->below == &be->bkgd || NXBE_ISMODAL(wnd)) { return; } diff --git a/graphics/nxbe/nxbe_modal.c b/graphics/nxbe/nxbe_modal.c new file mode 100644 index 0000000000..cc36a0651a --- /dev/null +++ b/graphics/nxbe/nxbe_modal.c @@ -0,0 +1,99 @@ +/**************************************************************************** + * graphics/nxbe/nxbe_modal.c + * + * Copyright (C) 2019 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +#include "nxbe.h" +#include "nxmu.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nxbe_modal + * + * Description: + * May be used to either (1) raise a window to the top of the display and + * select modal behavior, or (2) disable modal behavior. + * + ****************************************************************************/ + +void nxbe_modal(FAR struct nxbe_window_s *wnd, bool enable) +{ + FAR struct nxbe_state_s *be = wnd->be; + + /* Are we enabling or disabling the modal state? */ + + if (enable) + { + /* We are enabling the modal state. Ignore the request if the back-end + * is already in a modal state. + */ + + if (!NXBE_STATE_ISMODAL(be)) + { + /* Raise the window to the top of the display */ + + void nxbe_raise(FAR struct nxbe_window_s *wnd); + + /* And enter the modal state */ + + DEBUGASSERT(!NXBE_ISMODAL(wnd)); + NXBE_SETMODAL(wnd); + NXBE_STATE_SETMODAL(be); + } + } + + /* We are disabling the modal state. Verify that we are in a modal state */ + + else if (NXBE_STATE_ISMODAL(be) && NXBE_ISMODAL(wnd)) + { + /* We are in a modal state and this window is the modal window. + * Just disable the modal state. + */ + + NXBE_CLRMODAL(wnd); + NXBE_STATE_CLRMODAL(be); + } +} diff --git a/graphics/nxbe/nxbe_raise.c b/graphics/nxbe/nxbe_raise.c index 2ae2f2d0fe..f9792e0460 100644 --- a/graphics/nxbe/nxbe_raise.c +++ b/graphics/nxbe/nxbe_raise.c @@ -1,7 +1,7 @@ /**************************************************************************** * graphics/nxbe/nxbe_raise.c * - * Copyright (C) 2008-2009, 2011 Gregory Nutt. All rights reserved. + * Copyright (C) 2008-2009, 2011, 2019 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -39,6 +39,8 @@ #include +#include + #include #include "nxbe.h" @@ -70,9 +72,27 @@ void nxbe_raise(FAR struct nxbe_window_s *wnd) { FAR struct nxbe_state_s *be = wnd->be; - /* If this window is already at the top of the display, then do nothing */ + /* A modal window should already be at the top of the heirarchy. */ - if (!wnd->above) + DEBUGASSERT(!NXBE_ISMODAL(wnd) || wnd->above == NULL); + + /* If this window is already at the top of the display, then do nothing + * (this covers modal window which must always be at the top). Don't + * raise the background window. + */ + + if (wnd->above == NULL || wnd->below == NULL) + { + return; + } + + /* This is some non-modal, window above the background. If we are in a + * modal state (i.e., there is some other modal window at the top of the + * heirary), and it is already as high as it can go in the hierarchy, then + * do nothing. + */ + + if (NXBE_STATE_ISMODAL(be) && be->topwnd->below == wnd) { return; } @@ -84,13 +104,31 @@ void nxbe_raise(FAR struct nxbe_window_s *wnd) wnd->above->below = wnd->below; wnd->below->above = wnd->above; - /* Then put it back in the list at the top */ + /* Then put it back in the list. If the top window is a modal window, then + * only raise it to second highest. + */ - wnd->above = NULL; - wnd->below = be->topwnd; + if (NXBE_STATE_ISMODAL(be) && be->topwnd->below != NULL) + { + /* We are in a modal state. The topwnd is not the background and it + * has focus. + */ - be->topwnd->above = wnd; - be->topwnd = wnd; + wnd->above = be->topwnd; + wnd->below = be->topwnd->below; + + be->topwnd->below = wnd; + } + else + { + /* Otherwise re-insert the window at the top on the display. */ + + wnd->above = NULL; + wnd->below = be->topwnd; + + be->topwnd->above = wnd; + be->topwnd = wnd; + } /* This window is now at the top of the display, we know, therefore, that * it is not obscured by another window diff --git a/graphics/nxmu/nxmu.h b/graphics/nxmu/nxmu.h index 0dc842cad8..f5a8bb3615 100644 --- a/graphics/nxmu/nxmu.h +++ b/graphics/nxmu/nxmu.h @@ -62,7 +62,7 @@ /* Server state structure ***************************************************/ -/* This the server 'front-end' state structure */ +/* This the server NXMU state structure */ struct nxmu_state_s { @@ -182,14 +182,14 @@ void nxmu_requestbkgd(FAR struct nxmu_conn_s *conn, * and return control of the background to NX. * * Input Parameters: - * fe - The front-end state structure + * nxmu - The NXMU state structure * * Returned Value: * None * ****************************************************************************/ -void nxmu_releasebkgd(FAR struct nxmu_state_s *fe); +void nxmu_releasebkgd(FAR struct nxmu_state_s *nxmu); /**************************************************************************** * Name: nxmu_reportposition @@ -253,7 +253,7 @@ int nxmu_mousereport(struct nxbe_window_s *wnd); ****************************************************************************/ #ifdef CONFIG_NX_XYINPUT -int nxmu_mousein(FAR struct nxmu_state_s *fe, +int nxmu_mousein(FAR struct nxmu_state_s *nxmu, FAR const struct nxgl_point_s *pos, int button); #endif @@ -268,7 +268,7 @@ int nxmu_mousein(FAR struct nxmu_state_s *fe, ****************************************************************************/ #ifdef CONFIG_NX_KBD -void nxmu_kbdin(FAR struct nxmu_state_s *fe, uint8_t nch, FAR uint8_t *ch); +void nxmu_kbdin(FAR struct nxmu_state_s *nxmu, uint8_t nch, FAR uint8_t *ch); #endif #undef EXTERN diff --git a/graphics/nxmu/nxmu_kbdin.c b/graphics/nxmu/nxmu_kbdin.c index cf9918dc52..554bed4895 100644 --- a/graphics/nxmu/nxmu_kbdin.c +++ b/graphics/nxmu/nxmu_kbdin.c @@ -65,7 +65,7 @@ * ****************************************************************************/ -void nxmu_kbdin(FAR struct nxmu_state_s *fe, uint8_t nch, FAR uint8_t *ch) +void nxmu_kbdin(FAR struct nxmu_state_s *nxmu, uint8_t nch, FAR uint8_t *ch) { FAR struct nxclimsg_kbdin_s *outmsg; int size; @@ -82,7 +82,7 @@ void nxmu_kbdin(FAR struct nxmu_state_s *fe, uint8_t nch, FAR uint8_t *ch) /* Give the keypad input only to the top child */ outmsg->msgid = NX_CLIMSG_KBDIN; - outmsg->wnd = fe->be.topwnd; + outmsg->wnd = nxmu->be.topwnd; outmsg->nch = nch; for (i = 0; i < nch; i++) @@ -90,7 +90,7 @@ void nxmu_kbdin(FAR struct nxmu_state_s *fe, uint8_t nch, FAR uint8_t *ch) outmsg->ch[i] = ch[i]; } - (void)nxmu_sendclientwindow(fe->be.topwnd, outmsg, size); + (void)nxmu_sendclientwindow(nxmu->be.topwnd, outmsg, size); kmm_free(outmsg); } } diff --git a/graphics/nxmu/nxmu_mouse.c b/graphics/nxmu/nxmu_mouse.c index 9edde0905a..83b074c366 100644 --- a/graphics/nxmu/nxmu_mouse.c +++ b/graphics/nxmu/nxmu_mouse.c @@ -169,7 +169,7 @@ int nxmu_mousereport(struct nxbe_window_s *wnd) * ****************************************************************************/ -int nxmu_mousein(FAR struct nxmu_state_s *fe, +int nxmu_mousein(FAR struct nxmu_state_s *nxmu, FAR const struct nxgl_point_s *pos, int buttons) { FAR struct nxbe_window_s *wnd; @@ -216,7 +216,7 @@ int nxmu_mousein(FAR struct nxmu_state_s *fe, if (oldbuttons) { - g_mwnd = nxmu_revalidate_g_mwnd(fe->be.topwnd); + g_mwnd = nxmu_revalidate_g_mwnd(nxmu->be.topwnd); if (g_mwnd && g_mwnd->cb->mousein) { struct nxclimsg_mousein_s outmsg; @@ -240,7 +240,7 @@ int nxmu_mousein(FAR struct nxmu_state_s *fe, * report */ - for (wnd = fe->be.topwnd; wnd; wnd = wnd->below) + for (wnd = nxmu->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()). diff --git a/graphics/nxmu/nxmu_openwindow.c b/graphics/nxmu/nxmu_openwindow.c index 94836f687b..a914b13fd6 100644 --- a/graphics/nxmu/nxmu_openwindow.c +++ b/graphics/nxmu/nxmu_openwindow.c @@ -160,15 +160,33 @@ void nxmu_openwindow(FAR struct nxbe_state_s *be, FAR struct nxbe_window_s *wnd) } #endif - /* Now, insert the new window at the top on the display. topwind is - * never NULL (it may point only at the background window, however) + /* Now, insert the new window at the correct position in the hierarchy. + * topwnd is never NULL (it may point only at the background window, + * however). If we are in a modal state, then we cannot insert the + * window at the top of the display. */ - wnd->above = NULL; - wnd->below = be->topwnd; + if (NXBE_STATE_ISMODAL(be) && be->topwnd->below != NULL) + { + /* We are in a modal state. The topwnd is not the background and it + * has focus. + */ - be->topwnd->above = wnd; - be->topwnd = wnd; + wnd->above = be->topwnd; + wnd->below = be->topwnd->below; + + be->topwnd->below = wnd; + } + else + { + /* Otherwise insert the new window at the top on the display. */ + + wnd->above = NULL; + wnd->below = be->topwnd; + + be->topwnd->above = wnd; + be->topwnd = wnd; + } /* Report the initial size/position of the window to the client */ diff --git a/graphics/nxmu/nxmu_releasebkgd.c b/graphics/nxmu/nxmu_releasebkgd.c index 7d63eadd38..e2209f3a9e 100644 --- a/graphics/nxmu/nxmu_releasebkgd.c +++ b/graphics/nxmu/nxmu_releasebkgd.c @@ -58,25 +58,25 @@ * and return control of the background to NX. * * Input Parameters: - * fe - The front-end state structure + * nxmu - The NXMU state structure * * Returned Value: * None * ****************************************************************************/ -void nxmu_releasebkgd(FAR struct nxmu_state_s *fe) +void nxmu_releasebkgd(FAR struct nxmu_state_s *nxmu) { FAR struct nxbe_state_s *be; - DEBUGASSERT(fe != NULL); + DEBUGASSERT(nxmu != NULL); /* Destroy the client window callbacks and restore the server connection. */ - be = &fe->be; + be = &nxmu->be; be->bkgd.cb = NULL; be->bkgd.arg = NULL; - be->bkgd.conn = &fe->conn; + be->bkgd.conn = &nxmu->conn; /* Redraw the background window */ diff --git a/graphics/nxmu/nxmu_server.c b/graphics/nxmu/nxmu_server.c index 79d3cdc12f..ce3d1c05cc 100644 --- a/graphics/nxmu/nxmu_server.c +++ b/graphics/nxmu/nxmu_server.c @@ -119,7 +119,7 @@ static inline void nxmu_connect(FAR struct nxmu_conn_s *conn) * Name: nxmu_shutdown ****************************************************************************/ -static inline void nxmu_shutdown(FAR struct nxmu_state_s *fe) +static inline void nxmu_shutdown(FAR struct nxmu_state_s *nxmu) { FAR struct nxbe_window_s *wnd; @@ -131,7 +131,7 @@ static inline void nxmu_shutdown(FAR struct nxmu_state_s *fe) * background window, thus close all of the servers message queues. */ - for (wnd = fe->be.topwnd; wnd; wnd = wnd->below) + for (wnd = nxmu->be.topwnd; wnd; wnd = wnd->below) { (void)nxmu_disconnect(wnd->conn); } @@ -165,16 +165,16 @@ static void nxmu_event(FAR struct nxbe_window_s *wnd, enum nx_event_e event, ****************************************************************************/ static inline int nxmu_setup(FAR const char *mqname, FAR NX_DRIVERTYPE *dev, - FAR struct nxmu_state_s *fe) + FAR struct nxmu_state_s *nxmu) { struct mq_attr attr; int ret; - memset(fe, 0, sizeof(struct nxmu_state_s)); + memset(nxmu, 0, sizeof(struct nxmu_state_s)); /* Configure the framebuffer/LCD device */ - ret = nxbe_configure(dev, &fe->be); + ret = nxbe_configure(dev, &nxmu->be); if (ret < 0) { gerr("ERROR: nxbe_configure failed: %d\n", ret); @@ -202,8 +202,8 @@ static inline int nxmu_setup(FAR const char *mqname, FAR NX_DRIVERTYPE *dev, attr.mq_msgsize = NX_MXSVRMSGLEN; attr.mq_flags = 0; - fe->conn.crdmq = mq_open(mqname, O_RDONLY | O_CREAT, 0666, &attr); - if (fe->conn.crdmq == (mqd_t)-1) + nxmu->conn.crdmq = mq_open(mqname, O_RDONLY | O_CREAT, 0666, &attr); + if (nxmu->conn.crdmq == (mqd_t)-1) { int errcode = get_errno(); gerr("ERROR: mq_open(%s) failed: %d\n", mqname, errcode); @@ -219,38 +219,38 @@ static inline int nxmu_setup(FAR const char *mqname, FAR NX_DRIVERTYPE *dev, * the server message loop. */ - fe->conn.swrmq = mq_open(mqname, O_WRONLY); - if (fe->conn.swrmq == (mqd_t)-1) + nxmu->conn.swrmq = mq_open(mqname, O_WRONLY); + if (nxmu->conn.swrmq == (mqd_t)-1) { int errcode = get_errno(); gerr("ERROR: mq_open(%s) failed: %d\n", mqname, errcode); - mq_close(fe->conn.crdmq); + mq_close(nxmu->conn.crdmq); return -errcode; } /* The server is now "connected" to itself via the background window */ - fe->conn.state = NX_CLISTATE_CONNECTED; + nxmu->conn.state = NX_CLISTATE_CONNECTED; /* Initialize the non-NULL elements of the background window */ - fe->be.bkgd.conn = &fe->conn; - fe->be.bkgd.be = (FAR struct nxbe_state_s *)fe; + nxmu->be.bkgd.conn = &nxmu->conn; + nxmu->be.bkgd.be = (FAR struct nxbe_state_s *)nxmu; - fe->be.bkgd.bounds.pt2.x = fe->be.vinfo.xres - 1; - fe->be.bkgd.bounds.pt2.y = fe->be.vinfo.yres - 1; + nxmu->be.bkgd.bounds.pt2.x = nxmu->be.vinfo.xres - 1; + nxmu->be.bkgd.bounds.pt2.y = nxmu->be.vinfo.yres - 1; /* Complete initialization of the server state structure. The * window list contains only one element: The background window * with nothing else above or below it */ - fe->be.topwnd = &fe->be.bkgd; + nxmu->be.topwnd = &nxmu->be.bkgd; /* Initialize the mouse position */ #ifdef CONFIG_NX_XYINPUT - nxmu_mouseinit(fe->be.vinfo.xres, fe->be.vinfo.yres); + nxmu_mouseinit(nxmu->be.vinfo.xres, nxmu->be.vinfo.yres); #endif return OK; } @@ -281,7 +281,7 @@ static inline int nxmu_setup(FAR const char *mqname, FAR NX_DRIVERTYPE *dev, int nx_runinstance(FAR const char *mqname, FAR NX_DRIVERTYPE *dev) { - struct nxmu_state_s fe; + struct nxmu_state_s nxmu; FAR struct nxsvrmsg_s *msg; char buffer[NX_MXSVRMSGLEN]; int nbytes; @@ -293,7 +293,7 @@ int nx_runinstance(FAR const char *mqname, FAR NX_DRIVERTYPE *dev) /* Initialize and configure the server */ - ret = nxmu_setup(mqname, dev, &fe); + ret = nxmu_setup(mqname, dev, &nxmu); if (ret < 0) { return ret; @@ -301,7 +301,7 @@ int nx_runinstance(FAR const char *mqname, FAR NX_DRIVERTYPE *dev) /* Produce the initial, background display */ - nxbe_redraw(&fe.be, &fe.be.bkgd, &fe.be.bkgd.bounds); + nxbe_redraw(&nxmu.be, &nxmu.be.bkgd, &nxmu.be.bkgd.bounds); /* Message Loop ***********************************************************/ @@ -311,7 +311,7 @@ int nx_runinstance(FAR const char *mqname, FAR NX_DRIVERTYPE *dev) { /* Receive the next server message */ - nbytes = nxmq_receive(fe.conn.crdmq, buffer, NX_MXSVRMSGLEN, 0); + nbytes = nxmq_receive(nxmu.conn.crdmq, buffer, NX_MXSVRMSGLEN, 0); if (nbytes < 0) { if (nbytes != -EINTR) @@ -351,7 +351,7 @@ int nx_runinstance(FAR const char *mqname, FAR NX_DRIVERTYPE *dev) case NX_SVRMSG_OPENWINDOW: /* Create a new window */ { FAR struct nxsvrmsg_openwindow_s *openmsg = (FAR struct nxsvrmsg_openwindow_s *)buffer; - nxmu_openwindow(&fe.be, openmsg->wnd); + nxmu_openwindow(&nxmu.be, openmsg->wnd); } break; @@ -379,13 +379,13 @@ int nx_runinstance(FAR const char *mqname, FAR NX_DRIVERTYPE *dev) case NX_SVRMSG_REQUESTBKGD: /* Give access to the background window */ { FAR struct nxsvrmsg_requestbkgd_s *rqbgmsg = (FAR struct nxsvrmsg_requestbkgd_s *)buffer; - nxmu_requestbkgd(rqbgmsg->conn, &fe.be, rqbgmsg->cb, rqbgmsg->arg); + nxmu_requestbkgd(rqbgmsg->conn, &nxmu.be, rqbgmsg->cb, rqbgmsg->arg); } break; case NX_SVRMSG_RELEASEBKGD: /* End access to the background window */ { - nxmu_releasebkgd(&fe); + nxmu_releasebkgd(&nxmu); } break; @@ -424,6 +424,13 @@ int nx_runinstance(FAR const char *mqname, FAR NX_DRIVERTYPE *dev) } break; + case NX_SVRMSG_MODAL: /* Select/De-select window modal state */ + { + FAR struct nxsvrmsg_modal_s *modalmsg = (FAR struct nxsvrmsg_modal_s *)buffer; + nxbe_modal(modalmsg->wnd, modalmsg->modal); + } + break; + case NX_SVRMSG_SETPIXEL: /* Set a single pixel in the window with a color */ { FAR struct nxsvrmsg_setpixel_s *setmsg = (FAR struct nxsvrmsg_setpixel_s *)buffer; @@ -482,12 +489,12 @@ int nx_runinstance(FAR const char *mqname, FAR NX_DRIVERTYPE *dev) /* Has the background color changed? */ - if (!nxgl_colorcmp(fe.be.bgcolor, bgcolormsg->color)) + if (!nxgl_colorcmp(nxmu.be.bgcolor, bgcolormsg->color)) { /* Yes.. fill the background */ - nxgl_colorcopy(fe.be.bgcolor, bgcolormsg->color); - nxbe_fill(&fe.be.bkgd, &fe.be.bkgd.bounds, bgcolormsg->color); + nxgl_colorcopy(nxmu.be.bgcolor, bgcolormsg->color); + nxbe_fill(&nxmu.be.bkgd, &nxmu.be.bkgd.bounds, bgcolormsg->color); } } break; @@ -496,7 +503,7 @@ int nx_runinstance(FAR const char *mqname, FAR NX_DRIVERTYPE *dev) case NX_SVRMSG_MOUSEIN: /* New mouse report from mouse client */ { FAR struct nxsvrmsg_mousein_s *mousemsg = (FAR struct nxsvrmsg_mousein_s *)buffer; - nxmu_mousein(&fe, &mousemsg->pt, mousemsg->buttons); + nxmu_mousein(&nxmu, &mousemsg->pt, mousemsg->buttons); } break; #endif @@ -504,7 +511,7 @@ int nx_runinstance(FAR const char *mqname, FAR NX_DRIVERTYPE *dev) case NX_SVRMSG_KBDIN: /* New keyboard report from keyboard client */ { FAR struct nxsvrmsg_kbdin_s *kbdmsg = (FAR struct nxsvrmsg_kbdin_s *)buffer; - nxmu_kbdin(&fe, kbdmsg->nch, kbdmsg->ch); + nxmu_kbdin(&nxmu, kbdmsg->nch, kbdmsg->ch); } break; #endif @@ -521,11 +528,11 @@ int nx_runinstance(FAR const char *mqname, FAR NX_DRIVERTYPE *dev) case NX_CLIMSG_REDRAW: /* Re-draw the background window */ { FAR struct nxclimsg_redraw_s *redraw = (FAR struct nxclimsg_redraw_s *)buffer; - DEBUGASSERT(redraw->wnd == &fe.be.bkgd); + DEBUGASSERT(redraw->wnd == &nxmu.be.bkgd); ginfo("Re-draw background rect={(%d,%d),(%d,%d)}\n", redraw->rect.pt1.x, redraw->rect.pt1.y, redraw->rect.pt2.x, redraw->rect.pt2.y); - nxbe_fill(&fe.be.bkgd, &redraw->rect, fe.be.bgcolor); + nxbe_fill(&nxmu.be.bkgd, &redraw->rect, nxmu.be.bgcolor); } break; @@ -541,10 +548,10 @@ int nx_runinstance(FAR const char *mqname, FAR NX_DRIVERTYPE *dev) } } - nxmu_shutdown(&fe); + nxmu_shutdown(&nxmu); return OK; errout: - nxmu_shutdown(&fe); + nxmu_shutdown(&nxmu); return ret; } diff --git a/include/nuttx/nx/nx.h b/include/nuttx/nx/nx.h index 33b28798cf..4ed0fcb21e 100644 --- a/include/nuttx/nx/nx.h +++ b/include/nuttx/nx/nx.h @@ -653,7 +653,7 @@ int nx_raise(NXWINDOW hwnd); * Lower the specified window to the bottom of the display. * * Input Parameters: - * hwnd - the window to be lowered + * hwnd - The window to be lowered * * Returned Value: * OK on success; ERROR on failure with errno set appropriately @@ -662,6 +662,24 @@ int nx_raise(NXWINDOW hwnd); int nx_lower(NXWINDOW hwnd); +/**************************************************************************** + * Name: nx_modal + * + * Description: + * May be used to either (1) raise a window to the top of the display and + * select modal behavior, or (2) disable modal behavior. + * + * Input Parameters: + * hwnd - The window to be modified + * modal - True: enter modal state; False: leave modal state + * + * Returned Value: + * OK on success; ERROR on failure with errno set appropriately + * + ****************************************************************************/ + +int nx_modal(NXWINDOW hwnd, bool modal); + /**************************************************************************** * Name: nx_setpixel * diff --git a/include/nuttx/nx/nxbe.h b/include/nuttx/nx/nxbe.h index 741cdd25df..244fb51352 100644 --- a/include/nuttx/nx/nxbe.h +++ b/include/nuttx/nx/nxbe.h @@ -67,13 +67,16 @@ /* Window flags and helper macros: * * NXBE_WINDOW_BLOCKED - Window input is blocked (internal use only) + * NXBE_WINDOW_FRAMED - Framed (NxTK) Window * NXBE_WINDOW_RAMBACKED - Window is backed by a framebuffer + * NXBE_WINDOW_MODAL - Window is in a focused, modal state */ -#define NXBE_WINDOW_BLOCKED (1 << 0) /* The window is blocked and will not - * receive further input. */ -#define NXBE_WINDOW_FRAMED (1 << 1) /* Framed (NxTK) Window */ -#define NXBE_WINDOW_RAMBACKED (1 << 2) /* Window is backed by a framebuffer */ +#define NXBE_WINDOW_BLOCKED (1 << 0) /* Bit 0: The window is blocked and will + * not receive further input. */ +#define NXBE_WINDOW_FRAMED (1 << 1) /* Bit 1: Framed (NxTK) Window */ +#define NXBE_WINDOW_RAMBACKED (1 << 2) /* Bit 2: Window is backed by a framebuffer */ +#define NXBE_WINDOW_MODAL (1 << 3) /* Bit 3: Window is in a focused, modal state */ /* Valid user flags for different window types */ @@ -110,6 +113,13 @@ #define NXBE_CLRRAMBACKED(wnd) \ do { (wnd)->flags &= ~NXBE_WINDOW_RAMBACKED; } while (0) +#define NXBE_ISMODAL(wnd) \ + (((wnd)->flags & NXBE_WINDOW_MODAL) != 0) +#define NXBE_SETMODAL(wnd) \ + do { (wnd)->flags |= NXBE_WINDOW_MODAL; } while (0) +#define NXBE_CLRMODAL(wnd) \ + do { (wnd)->flags &= ~NXBE_WINDOW_MODAL; } while (0) + /**************************************************************************** * Public Types ****************************************************************************/ diff --git a/include/nuttx/nx/nxmu.h b/include/nuttx/nx/nxmu.h index 18f5c8a0db..3f91727639 100644 --- a/include/nuttx/nx/nxmu.h +++ b/include/nuttx/nx/nxmu.h @@ -147,6 +147,7 @@ enum nxmsg_e NX_SVRMSG_GETPOSITION, /* Get the current window position and size */ NX_SVRMSG_RAISE, /* Move the window to the top */ NX_SVRMSG_LOWER, /* Move the window to the bottom */ + NX_SVRMSG_MODAL, /* Select/de-slect window modal state */ NX_SVRMSG_SETPIXEL, /* Set a single pixel in the window with a color */ NX_SVRMSG_FILL, /* Fill a rectangle in the window with a color */ NX_SVRMSG_GETRECTANGLE, /* Get a rectangular region in the window */ @@ -350,7 +351,18 @@ struct nxsvrmsg_raise_s struct nxsvrmsg_lower_s { uint32_t msgid; /* NX_SVRMSG_LOWER */ - FAR struct nxbe_window_s *wnd; /* The window to be lowered */ + FAR struct nxbe_window_s *wnd; /* The window to be lowered */ +}; + +/* This message either (1) raises a window to the top of the display and + * selects the modal state, or (2) de-selects the modal state. + */ + +struct nxsvrmsg_modal_s +{ + uint32_t msgid; /* NX_SVRMSG_MODAL */ + FAR struct nxbe_window_s *wnd; /* The window to be modified */ + bool modal; /* True: enter modal state; False: leave modal state */ }; /* Set a single pixel in the window with a color */ diff --git a/include/nuttx/nx/nxtk.h b/include/nuttx/nx/nxtk.h index 7c978665fb..415b9de5d0 100644 --- a/include/nuttx/nx/nxtk.h +++ b/include/nuttx/nx/nxtk.h @@ -328,6 +328,24 @@ int nxtk_raise(NXTKWINDOW hfwnd); int nxtk_lower(NXTKWINDOW hfwnd); +/**************************************************************************** + * Name: nxtk_modal + * + * Description: + * May be used to either (1) raise a window to the top of the display and + * select modal behavior, or (2) disable modal behavior. + * + * Input Parameters: + * hfwnd - The window to be modified + * modal - True: enter modal state; False: leave modal state + * + * Returned Value: + * OK on success; ERROR on failure with errno set appropriately + * + ****************************************************************************/ + +int nxtk_modal(NXTKWINDOW hfwnd, bool modal); + /**************************************************************************** * Name: nxtk_fillwindow * diff --git a/libs/libnx/nxmu/Make.defs b/libs/libnx/nxmu/Make.defs index 224bbfc9aa..cefaa3b4bb 100644 --- a/libs/libnx/nxmu/Make.defs +++ b/libs/libnx/nxmu/Make.defs @@ -47,7 +47,7 @@ CSRCS += nx_releasebkgd.c nx_requestbkgd.c nx_setbgcolor.c CSRCS += nxmu_sendwindow.c nx_closewindow.c nx_constructwindow.c CSRCS += nx_bitmap.c nx_fill.c nx_filltrapezoid.c nx_getposition.c -CSRCS += nx_getrectangle.c nx_lower.c nx_move.c nx_openwindow.c +CSRCS += nx_getrectangle.c nx_lower.c nx_modal.c nx_move.c nx_openwindow.c CSRCS += nx_raise.c nx_redrawreq.c nx_setpixel.c nx_setposition.c CSRCS += nx_setsize.c diff --git a/libs/libnx/nxmu/nx_lower.c b/libs/libnx/nxmu/nx_lower.c index d46b6bfeba..35dca877b0 100644 --- a/libs/libnx/nxmu/nx_lower.c +++ b/libs/libnx/nxmu/nx_lower.c @@ -69,11 +69,10 @@ int nx_lower(NXWINDOW hwnd) FAR struct nxbe_window_s *wnd = (FAR struct nxbe_window_s *)hwnd; struct nxsvrmsg_lower_s outmsg; - /* Send the RAISE message */ + /* Send the LOWER message */ outmsg.msgid = NX_SVRMSG_LOWER; outmsg.wnd = wnd; return nxmu_sendwindow(wnd, &outmsg, sizeof(struct nxsvrmsg_lower_s)); } - diff --git a/libs/libnx/nxmu/nx_modal.c b/libs/libnx/nxmu/nx_modal.c new file mode 100644 index 0000000000..54f7954b66 --- /dev/null +++ b/libs/libnx/nxmu/nx_modal.c @@ -0,0 +1,81 @@ +/**************************************************************************** + * libs/libnx/nxmu/nx_modal.c + * + * Copyright (C) 2019 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nx_modal + * + * Description: + * May be used to either (1) raise a window to the top of the display and + * select modal behavior, or (2) disable modal behavior. + * + * Input Parameters: + * hwnd - The window to be modified + * modal - True: enter modal state; False: leave modal state + * + * Returned Value: + * OK on success; ERROR on failure with errno set appropriately + * + ****************************************************************************/ + +int nx_modal(NXWINDOW hwnd, bool modal) +{ + FAR struct nxbe_window_s *wnd = (FAR struct nxbe_window_s *)hwnd; + struct nxsvrmsg_modal_s outmsg; + + /* Send the MODAL message */ + + outmsg.msgid = NX_SVRMSG_MODAL; + outmsg.wnd = wnd; + outmsg.modal = modal; + + return nxmu_sendwindow(wnd, &outmsg, sizeof(struct nxsvrmsg_modal_s)); +} diff --git a/libs/libnx/nxtk/Make.defs b/libs/libnx/nxtk/Make.defs index b118c758e2..ad31ce382d 100644 --- a/libs/libnx/nxtk/Make.defs +++ b/libs/libnx/nxtk/Make.defs @@ -37,21 +37,22 @@ ifeq ($(CONFIG_NX),y) -CSRCS += nxtk_openwindow.c nxtk_closewindow.c nxtk_getposition.c -CSRCS += nxtk_setposition.c nxtk_setsize.c nxtk_raise.c nxtk_lower.c -CSRCS += nxtk_fillwindow.c nxtk_getwindow.c nxtk_filltrapwindow.c -CSRCS += nxtk_movewindow.c nxtk_bitmapwindow.c nxtk_events.c -CSRCS += nxtk_setsubwindows.c nxtk_drawcirclewindow.c nxtk_drawlinewindow.c -CSRCS += nxtk_fillcirclewindow.c nxtk_block.c nxtk_synch.c +CSRCS += nxtk_setsubwindows.c nxtk_events.c nxtk_block.c nxtk_synch.c +CSRCS += nxtk_subwindowclip.c nxtk_containerclip.c nxtk_subwindowmove.c +CSRCS += nxtk_drawframe.c +CSRCS += nxtk_raise.c nxtk_lower.c nxtk_modal.c +CSRCS += nxtk_setposition.c nxtk_getposition.c nxtk_setsize.c + +CSRCS += nxtk_openwindow.c nxtk_closewindow.c nxtk_fillwindow.c +CSRCS += nxtk_getwindow.c nxtk_filltrapwindow.c nxtk_movewindow.c +CSRCS += nxtk_bitmapwindow.c nxtk_drawcirclewindow.c nxtk_drawlinewindow.c +CSRCS += nxtk_fillcirclewindow.c CSRCS += nxtk_opentoolbar.c nxtk_closetoolbar.c nxtk_filltoolbar.c CSRCS += nxtk_gettoolbar.c nxtk_filltraptoolbar.c nxtk_movetoolbar.c CSRCS += nxtk_bitmaptoolbar.c nxtk_drawcircletoolbar.c nxtk_drawlinetoolbar.c CSRCS += nxtk_fillcircletoolbar.c nxtk_toolbarbounds.c -CSRCS += nxtk_subwindowclip.c nxtk_containerclip.c nxtk_subwindowmove.c -CSRCS += nxtk_drawframe.c - # Add the nxtk/ directory to the build DEPPATH += --dep-path nxtk diff --git a/libs/libnx/nxtk/nxtk_modal.c b/libs/libnx/nxtk/nxtk_modal.c new file mode 100644 index 0000000000..e7ce92dd3a --- /dev/null +++ b/libs/libnx/nxtk/nxtk_modal.c @@ -0,0 +1,74 @@ +/**************************************************************************** + * libs/libnx/nxtk/nxtk_modal.c + * + * Copyright (C) 2019 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "nxtk.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nxtk_modal + * + * Description: + * May be used to either (1) raise a window to the top of the display and + * select modal behavior, or (2) disable modal behavior. + * + * Input Parameters: + * hfwnd - The window to be modified + * modal - True: enter modal state; False: leave modal state + * + * Returned Value: + * OK on success; ERROR on failure with errno set appropriately + * + ****************************************************************************/ + +int nxtk_modal(NXTKWINDOW hfwnd, bool modal) +{ + return nx_modal((NXWINDOW)hfwnd, modal); +}