diff --git a/graphics/nxglyphs/Makefile b/graphics/nxglyphs/Makefile index ef4e44294..3634e3030 100644 --- a/graphics/nxglyphs/Makefile +++ b/graphics/nxglyphs/Makefile @@ -48,19 +48,21 @@ CXXSRCS += glyph_capslock.cxx glyph_radiobuttonon.cxx glyph_windowdepthdown.cxx CXXSRCS += glyph_checkboxmu.cxx glyph_return.cxx glyph_windowdepthup.cxx CXXSRCS += glyph_checkboxoff.cxx glyph_screendepthdown.cxx -# Glyphs used by NxWM +# Glyphs used by NxWM and Twm4Nx ifeq ($(CONFIG_NXGLPYHS_LARGE_ICONS),y) # Large icons CXXSRCS += glyph_calculator47x49.cxx glyph_calibration48x42.cxx glyph_cmd49x43.cxx CXXSRCS += glyph_minimize42x42.cxx glyph_play48x48.cxx glyph_stop42x42.cxx +CXXSRCS += glyph_menu42x42.cxx glyph_resize42x42.cxx glyph_nxicon42x42.cxx else # Small icons CXXSRCS += glyph_calculator24x25.cxx glyph_calibration24x21.cxx glyph_cmd25x22.cxx CXXSRCS += glyph_minimize21x21.cxx glyph_play24x24.cxx glyph_stop21x21.cxx +CXXSRCS += glyph_menu21x21.cxx glyph_resize21x21.cxx glyph_nxicon21x21.cxx endif ifeq ($(CONFIG_NXGLPYHS_LARGE_ICONS),y) diff --git a/graphics/nxglyphs/images/menu21x21.png b/graphics/nxglyphs/images/menu21x21.png new file mode 100644 index 000000000..d1da97196 Binary files /dev/null and b/graphics/nxglyphs/images/menu21x21.png differ diff --git a/graphics/nxglyphs/images/menu42x42.png b/graphics/nxglyphs/images/menu42x42.png new file mode 100644 index 000000000..cfe61c5e9 Binary files /dev/null and b/graphics/nxglyphs/images/menu42x42.png differ diff --git a/graphics/nxglyphs/images/nxicon-21x21.png b/graphics/nxglyphs/images/nxicon-21x21.png new file mode 100644 index 000000000..e7045427f Binary files /dev/null and b/graphics/nxglyphs/images/nxicon-21x21.png differ diff --git a/graphics/nxglyphs/images/nxicon-42x42.png b/graphics/nxglyphs/images/nxicon-42x42.png new file mode 100644 index 000000000..858c6c1a9 Binary files /dev/null and b/graphics/nxglyphs/images/nxicon-42x42.png differ diff --git a/graphics/nxglyphs/images/resize21x21.png b/graphics/nxglyphs/images/resize21x21.png new file mode 100644 index 000000000..048c3cb7a Binary files /dev/null and b/graphics/nxglyphs/images/resize21x21.png differ diff --git a/graphics/nxglyphs/images/resize42x42.png b/graphics/nxglyphs/images/resize42x42.png new file mode 100644 index 000000000..b2c0ffced Binary files /dev/null and b/graphics/nxglyphs/images/resize42x42.png differ diff --git a/graphics/nxglyphs/include/mkcursor.c b/graphics/nxglyphs/include/mkcursor.c index d9086f6d2..8fd3d5023 100644 --- a/graphics/nxglyphs/include/mkcursor.c +++ b/graphics/nxglyphs/include/mkcursor.c @@ -1,5 +1,5 @@ /**************************************************************************** - * apps/grpahics/nxglyphs/include/mkcursor.c + * apps/graphics/nxglyphs/include/mkcursor.c * * Copyright (C) 2019 Gregory Nutt. All rights reserved. * Author: Gregory Nutt diff --git a/graphics/nxglyphs/src/.gitignore b/graphics/nxglyphs/src/.gitignore new file mode 100644 index 000000000..e953c8174 --- /dev/null +++ b/graphics/nxglyphs/src/.gitignore @@ -0,0 +1,2 @@ +/_mksrle.exe + diff --git a/graphics/nxglyphs/src/glyph_menu21x21.cxx b/graphics/nxglyphs/src/glyph_menu21x21.cxx new file mode 100644 index 000000000..4df453177 --- /dev/null +++ b/graphics/nxglyphs/src/glyph_menu21x21.cxx @@ -0,0 +1,169 @@ +/******************************************************************************************** + * apps/graphics/nxwm/src/glyph_menu21x21.cxx + * + * 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, NxWidgets, nor the names of its contributors + * me 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 "graphics/nxwidgets/crlepalettebitmap.hxx" +#include "graphics/nxglyphs.hxx" + +/******************************************************************************************** + * Pre-Processor Definitions + ********************************************************************************************/ + +#define BITMAP_NROWS 21 +#define BITMAP_NCOLUMNS 21 +#define BITMAP_NLUTCODES 6 + +/******************************************************************************************** + * Private Bitmap Data + ********************************************************************************************/ + +using namespace NXWidgets; + +#if CONFIG_NXWIDGETS_BPP == 24 || CONFIG_NXWIDGETS_BPP == 32 +// RGB24 (8-8-8) Colors + +static const uint32_t g_menuNormalLut[BITMAP_NLUTCODES] = +{ + 0xc49c4c, 0xdc9000, 0xfcb800, 0xfcfcfc, 0xc47c00, 0x9c5800, /* Codes 0-5 */ +}; + +static const uint32_t g_menuBrightLut[BITMAP_NLUTCODES] = +{ + 0xd2b478, 0xe4ab3f, 0xfcc93f, 0xfcfcfc, 0xd29c3f, 0xb4813f, /* Codes 0-5 */ +}; + +#elif CONFIG_NXWIDGETS_BPP == 16 +// RGB16 (565) Colors (four of the colors in this map are duplicates) + +static const uint16_t g_menuNormalLut[BITMAP_NLUTCODES] = +{ + 0xc4e9, 0xdc80, 0xfdc0, 0xffff, 0xc3e0, 0x9ac0, /* Codes 0-5 */ +}; + +static const uint16_t g_menuBrightLut[BITMAP_NLUTCODES] = +{ + 0xd5af, 0xe547, 0xfe47, 0xffff, 0xd4e7, 0xb407, /* Codes 0-5 */ +}; + +#elif CONFIG_NXWIDGETS_BPP == 8 +// 8-bit color lookups. NOTE: This is really dumb! The lookup index is 8-bits and it used +// to lookup an 8-bit value. There is no savings in that! It would be better to just put +// the 8-bit color/greyscale value in the run-length encoded image and save the cost of these +// pointless lookups. But these p;ointless lookups do make the logic compatible with the +// 16- and 24-bit types. +/// + +# ifdef CONFIG_NXWIDGETS_GREYSCALE +// 8-bit Greyscale + +static const uint8_t g_menuNormalLut[BITMAP_NLUTCODES] = +{ + 0x9e, 0x96, 0xb7, 0xfc, 0x83, 0x62, /* Codes 0-5 */ +} + +static const uint8_t g_menuBrightLut[BITMAP_NLUTCODES] = +{ + 0xb6, 0xaf, 0xc8, 0xfc, 0xa1, 0x88, /* Codes 0-5 */ +}; + +# else /* CONFIG_NXWIDGETS_GREYSCALE */ +// RGB8 (332) Colors + +static const nxgl_mxpixel_t g_menuNormalLut[BITMAP_NLUTCODES] = +{ + 0xd1, 0xd0, 0xf4, 0xff, 0xcc, 0x88, /* Codes 0-5 */ +}; + +static const uint8_t g_menuBrightLut[BITMAP_NLUTCODES] = +{ + 0xd5, 0xf5, 0xf9, 0xff, 0xd1, 0xb1, /* Codes 0-5 */ +}; + +# endif +#else +# error Unsupported pixel format +#endif + +static const struct SRlePaletteBitmapEntry g_menuRleEntries[] = +{ + { 21, 0}, // Row 0 + { 1, 0}, { 4, 1}, { 7, 2}, { 9, 1}, // Row 1 + { 1, 0}, { 3, 1}, { 9, 2}, { 8, 1}, // Row 2 + { 1, 0}, { 2, 1}, { 10, 2}, { 8, 1}, // Row 3 + { 1, 0}, { 1, 1}, { 2, 2}, { 14, 3}, { 3, 1}, // Row 4 + { 1, 0}, { 1, 1}, { 2, 2}, { 1, 3}, { 6, 2}, { 6, 1}, { 1, 3}, { 2, 1}, // Row 5 + { 1, 4}, + { 1, 0}, { 3, 2}, { 1, 3}, { 5, 2}, { 7, 1}, { 1, 3}, { 2, 1}, { 1, 4}, // Row 6 + { 1, 0}, { 3, 2}, { 1, 3}, { 4, 2}, { 8, 1}, { 1, 3}, { 2, 1}, { 1, 4}, // Row 7 + { 1, 0}, { 3, 2}, { 14, 3}, { 1, 1}, { 2, 4}, // Row 8 + { 1, 0}, { 3, 2}, { 1, 3}, { 1, 2}, { 11, 1}, { 1, 3}, { 1, 1}, { 2, 4}, // Row 9 + { 1, 0}, { 1, 1}, { 2, 2}, { 1, 3}, { 12, 1}, { 1, 3}, { 3, 4}, // Row 10 + { 1, 0}, { 3, 1}, { 14, 3}, { 3, 4}, // Row 11 + { 1, 0}, { 3, 1}, { 1, 3}, { 11, 1}, { 1, 4}, { 1, 3}, { 3, 4}, // Row 12 + { 1, 0}, { 3, 1}, { 1, 3}, { 10, 1}, { 2, 4}, { 1, 3}, { 3, 4}, // Row 13 + { 1, 0}, { 3, 1}, { 14, 3}, { 3, 4}, // Row 14 + { 1, 0}, { 3, 1}, { 1, 3}, { 8, 1}, { 4, 4}, { 1, 3}, { 3, 4}, // Row 15 + { 1, 0}, { 3, 1}, { 1, 3}, { 6, 1}, { 6, 4}, { 1, 3}, { 3, 4}, // Row 16 + { 1, 0}, { 3, 1}, { 14, 3}, { 3, 4}, // Row 17 + { 1, 0}, { 4, 1}, { 16, 4}, // Row 18 + { 1, 0}, { 2, 1}, { 18, 4}, // Row 19 + { 1, 0}, { 19, 4}, { 1, 5}, // Row 20 + }; + +/******************************************************************************************** + * Public Bitmap Structure Definitions + ********************************************************************************************/ + +const struct SRlePaletteBitmap NXWidgets::g_menuBitmap = +{ + CONFIG_NXWIDGETS_BPP, // bpp - Bits per pixel + CONFIG_NXWIDGETS_FMT, // fmt - Color format + BITMAP_NLUTCODES, // nlut - Number of colors in the lLook-Up Table (LUT) + BITMAP_NCOLUMNS, // width - Width in pixels + BITMAP_NROWS, // height - Height in rows + { // lut - Pointer to the beginning of the Look-Up Table (LUT) + g_menuNormalLut, // Index 0: Unselected LUT + g_menuBrightLut, // Index 1: Selected LUT + }, + g_menuRleEntries // data - Pointer to the beginning of the RLE data +}; + diff --git a/graphics/nxglyphs/src/glyph_menu42x42.cxx b/graphics/nxglyphs/src/glyph_menu42x42.cxx new file mode 100644 index 000000000..fda701f43 --- /dev/null +++ b/graphics/nxglyphs/src/glyph_menu42x42.cxx @@ -0,0 +1,209 @@ +/******************************************************************************************** + * apps/graphics/nxwm/src/glyph_men42x42.cxx + * + * 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, NxWidgets, nor the names of its contributors + * me 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 "graphics/nxwidgets/crlepalettebitmap.hxx" +#include "graphics/nxglyphs.hxx" + +/******************************************************************************************** + * Pre-Processor Definitions + ********************************************************************************************/ + +#define BITMAP_NROWS 42 +#define BITMAP_NCOLUMNS 42 +#define BITMAP_NLUTCODES 7 + +/******************************************************************************************** + * Private Bitmap Data + ********************************************************************************************/ + +using namespace NXWidgets; + +#if CONFIG_NXWIDGETS_BPP == 24 || CONFIG_NXWIDGETS_BPP == 32 +// RGB24 (8-8-8) Colors + +static const uint32_t g_menuNormalLut[BITMAP_NLUTCODES] = +{ + 0xc49c4c, 0xdc9000, 0xfcb800, 0x9c5800, 0xfcfcfc, 0xdcb468, 0xc47c00, /* Codes 0-6 */ +}; + +static const uint32_t g_menuBrightLut[BITMAP_NLUTCODES] = +{ + 0xd2b478, 0xe4ab3f, 0xfcc93f, 0xb4813f, 0xfcfcfc, 0xe4c68d, 0xd29c3f, /* Codes 0-6 */ +}; + +#elif CONFIG_NXWIDGETS_BPP == 16 +// RGB16 (565) Colors (four of the colors in this map are duplicates) + +static const uint16_t g_menuNormalLut[BITMAP_NLUTCODES] = +{ + 0xc4e9, 0xdc80, 0xfdc0, 0x9ac0, 0xffff, 0xddad, 0xc3e0, /* Codes 0-6 */ +}; + +static const uint16_t g_menuBrightLut[BITMAP_NLUTCODES] = +{ + 0xd5af, 0xe547, 0xfe47, 0xb407, 0xffff, 0xe631, 0xd4e7, /* Codes 0-6 */ +}; + +#elif CONFIG_NXWIDGETS_BPP == 8 +// 8-bit color lookups. NOTE: This is really dumb! The lookup index is 8-bits and it used +// to lookup an 8-bit value. There is no savings in that! It would be better to just put +// the 8-bit color/greyscale value in the run-length encoded image and save the cost of these +// pointless lookups. But these p;ointless lookups do make the logic compatible with the +// 16- and 24-bit types. +/// + +# ifdef CONFIG_NXWIDGETS_GREYSCALE +// 8-bit Greyscale + +static const uint8_t g_menuNormalLut[BITMAP_NLUTCODES] = +{ + 0x9e, 0x96, 0xb7, 0x62, 0xfc, 0xb7, 0x83, /* Codes 0-6 */ +} + +static const uint8_t g_menuBrightLut[BITMAP_NLUTCODES] = +{ + 0xb6, 0xaf, 0xc8, 0x88, 0xfc, 0xc8, 0xa1, /* Codes 0-6 */ +}; + +# else /* CONFIG_NXWIDGETS_GREYSCALE */ +// RGB8 (332) Colors + +static const nxgl_mxpixel_t g_menuNormalLut[BITMAP_NLUTCODES] = +{ + 0xd1, 0xd0, 0xf4, 0x88, 0xff, 0xd5, 0xcc, /* Codes 0-6 */ +}; + +static const uint8_t g_menuBrightLut[BITMAP_NLUTCODES] = +{ + 0xd5, 0xf5, 0xf9, 0xb1, 0xff, 0xfa, 0xd1, /* Codes 0-6 */ +}; + +# endif +#else +# error Unsupported pixel format +#endif + +static const struct SRlePaletteBitmapEntry g_menuRleEntries[] = +{ + { 42, 0}, // Row 0 + { 1, 0}, { 11, 1}, { 10, 2}, { 19, 1}, { 1, 0}, // Row 1 + { 1, 0}, { 9, 1}, { 14, 2}, { 17, 1}, { 1, 3}, // Row 2 + { 1, 0}, { 7, 1}, { 17, 2}, { 16, 1}, { 1, 3}, // Row 3 + { 1, 0}, { 6, 1}, { 18, 2}, { 16, 1}, { 1, 3}, // Row 4 + { 1, 0}, { 5, 1}, { 19, 2}, { 16, 1}, { 1, 3}, // Row 5 + { 1, 0}, { 4, 1}, { 20, 2}, { 16, 1}, { 1, 3}, // Row 6 + { 1, 0}, { 3, 1}, { 20, 2}, { 17, 1}, { 1, 3}, // Row 7 + { 1, 0}, { 3, 1}, { 3, 2}, { 27, 4}, { 7, 1}, { 1, 3}, // Row 8 + { 1, 0}, { 2, 1}, { 4, 2}, { 1, 4}, { 25, 5}, { 1, 4}, { 1, 5}, { 5, 1}, // Row 9 + { 1, 6}, { 1, 3}, + { 1, 0}, { 2, 1}, { 4, 2}, { 1, 4}, { 1, 5}, { 13, 2}, { 11, 1}, { 1, 4}, // Row 10 + { 1, 5}, { 5, 1}, { 1, 6}, { 1, 3}, + { 1, 0}, { 1, 1}, { 5, 2}, { 1, 4}, { 1, 5}, { 12, 2}, { 12, 1}, { 1, 4}, // Row 11 + { 1, 5}, { 5, 1}, { 1, 6}, { 1, 3}, + { 1, 0}, { 1, 1}, { 5, 2}, { 1, 4}, { 1, 5}, { 11, 2}, { 13, 1}, { 1, 4}, // Row 12 + { 1, 5}, { 5, 1}, { 1, 6}, { 1, 3}, + { 1, 0}, { 6, 2}, { 1, 4}, { 1, 5}, { 10, 2}, { 14, 1}, { 1, 4}, { 1, 5}, // Row 13 + { 4, 1}, { 2, 6}, { 1, 3}, + { 1, 0}, { 6, 2}, { 1, 4}, { 1, 5}, { 9, 2}, { 15, 1}, { 1, 4}, { 1, 5}, // Row 14 + { 4, 1}, { 2, 6}, { 1, 3}, + { 1, 0}, { 6, 2}, { 27, 4}, { 1, 5}, { 3, 1}, { 3, 6}, { 1, 3}, // Row 15 + { 1, 0}, { 6, 2}, { 1, 4}, { 25, 5}, { 1, 4}, { 1, 5}, { 3, 1}, { 3, 6}, // Row 16 + { 1, 3}, + { 1, 0}, { 6, 2}, { 1, 4}, { 1, 5}, { 4, 2}, { 20, 1}, { 1, 4}, { 1, 5}, // Row 17 + { 2, 1}, { 4, 6}, { 1, 3}, + { 1, 0}, { 6, 2}, { 1, 4}, { 1, 5}, { 2, 2}, { 22, 1}, { 1, 4}, { 1, 5}, // Row 18 + { 2, 1}, { 4, 6}, { 1, 3}, + { 1, 0}, { 1, 1}, { 5, 2}, { 1, 4}, { 1, 5}, { 1, 2}, { 23, 1}, { 1, 4}, // Row 19 + { 1, 5}, { 1, 1}, { 5, 6}, { 1, 3}, + { 1, 0}, { 2, 1}, { 4, 2}, { 1, 4}, { 1, 5}, { 24, 1}, { 1, 4}, { 1, 5}, // Row 20 + { 1, 1}, { 5, 6}, { 1, 3}, + { 1, 0}, { 4, 1}, { 2, 2}, { 1, 4}, { 1, 5}, { 24, 1}, { 1, 4}, { 1, 5}, // Row 21 + { 6, 6}, { 1, 3}, + { 1, 0}, { 6, 1}, { 27, 4}, { 1, 5}, { 6, 6}, { 1, 3}, // Row 22 + { 1, 0}, { 6, 1}, { 1, 4}, { 25, 5}, { 1, 4}, { 1, 5}, { 6, 6}, { 1, 3}, // Row 23 + { 1, 0}, { 6, 1}, { 1, 4}, { 1, 5}, { 23, 1}, { 1, 6}, { 1, 4}, { 1, 5}, // Row 24 + { 6, 6}, { 1, 3}, + { 1, 0}, { 6, 1}, { 1, 4}, { 1, 5}, { 22, 1}, { 2, 6}, { 1, 4}, { 1, 5}, // Row 25 + { 6, 6}, { 1, 3}, + { 1, 0}, { 6, 1}, { 1, 4}, { 1, 5}, { 21, 1}, { 3, 6}, { 1, 4}, { 1, 5}, // Row 26 + { 6, 6}, { 1, 3}, + { 1, 0}, { 6, 1}, { 1, 4}, { 1, 5}, { 20, 1}, { 4, 6}, { 1, 4}, { 1, 5}, // Row 27 + { 6, 6}, { 1, 3}, + { 1, 0}, { 6, 1}, { 27, 4}, { 1, 5}, { 6, 6}, { 1, 3}, // Row 28 + { 1, 0}, { 6, 1}, { 1, 4}, { 25, 5}, { 1, 4}, { 1, 5}, { 6, 6}, { 1, 3}, // Row 29 + { 1, 0}, { 6, 1}, { 1, 4}, { 1, 5}, { 16, 1}, { 8, 6}, { 1, 4}, { 1, 5}, // Row 30 + { 6, 6}, { 1, 3}, + { 1, 0}, { 6, 1}, { 1, 4}, { 1, 5}, { 14, 1}, { 10, 6}, { 1, 4}, { 1, 5}, // Row 31 + { 6, 6}, { 1, 3}, + { 1, 0}, { 6, 1}, { 1, 4}, { 1, 5}, { 13, 1}, { 11, 6}, { 1, 4}, { 1, 5}, // Row 32 + { 6, 6}, { 1, 3}, + { 1, 0}, { 6, 1}, { 1, 4}, { 1, 5}, { 12, 1}, { 12, 6}, { 1, 4}, { 1, 5}, // Row 33 + { 6, 6}, { 1, 3}, + { 1, 0}, { 6, 1}, { 27, 4}, { 1, 5}, { 6, 6}, { 1, 3}, // Row 34 + { 1, 0}, { 7, 1}, { 27, 5}, { 6, 6}, { 1, 3}, // Row 35 + { 1, 0}, { 8, 1}, { 32, 6}, { 1, 3}, // Row 36 + { 1, 0}, { 6, 1}, { 34, 6}, { 1, 3}, // Row 37 + { 1, 0}, { 4, 1}, { 36, 6}, { 1, 3}, // Row 38 + { 1, 0}, { 2, 1}, { 37, 6}, { 2, 3}, // Row 39 + { 1, 0}, { 39, 6}, { 2, 3}, // Row 40 + { 2, 0}, { 40, 3}, // Row 41 + }; + +/******************************************************************************************** + * Public Bitmap Structure Definitions + ********************************************************************************************/ + +const struct SRlePaletteBitmap NXWidgets::g_menuBitmap = +{ + CONFIG_NXWIDGETS_BPP, // bpp - Bits per pixel + CONFIG_NXWIDGETS_FMT, // fmt - Color format + BITMAP_NLUTCODES, // nlut - Number of colors in the lLook-Up Table (LUT) + BITMAP_NCOLUMNS, // width - Width in pixels + BITMAP_NROWS, // height - Height in rows + { // lut - Pointer to the beginning of the Look-Up Table (LUT) + g_menuNormalLut, // Index 0: Unselected LUT + g_menuBrightLut, // Index 1: Selected LUT + }, + g_menuRleEntries // data - Pointer to the beginning of the RLE data +}; + diff --git a/graphics/nxglyphs/src/glyph_nxicon21x21.cxx b/graphics/nxglyphs/src/glyph_nxicon21x21.cxx new file mode 100644 index 000000000..af39667bc --- /dev/null +++ b/graphics/nxglyphs/src/glyph_nxicon21x21.cxx @@ -0,0 +1,207 @@ +/******************************************************************************************** + * apps/graphics/nxwm/src/glyph_nxicon21x21.cxx + * + * 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, NxWidgets, nor the names of its contributors + * me 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 "graphics/nxwidgets/crlepalettebitmap.hxx" +#include "graphics/nxglyphs.hxx" + +/******************************************************************************************** + * Pre-Processor Definitions + ********************************************************************************************/ + +#define BITMAP_NROWS 21 +#define BITMAP_NCOLUMNS 21 +#define BITMAP_NLUTCODES 31 + +/******************************************************************************************** + * Private Bitmap Data + ********************************************************************************************/ + +using namespace NXWidgets; + +#if CONFIG_NXWIDGETS_BPP == 24 || CONFIG_NXWIDGETS_BPP == 32 +// RGB24 (8-8-8) Colors + +static const uint32_t g_nxiconNormalLut[BITMAP_NLUTCODES] = +{ + 0xfcfcfc, 0x3830e0, 0x3c34e0, 0xcce0f0, 0x2c20e0, 0xc8e0f0, 0x181074, 0xd4e8f4, /* Codes 0-7 */ + 0x5894bc, 0xd4ecf0, 0x282480, 0x3c34ec, 0x848cf0, 0x4c8cb4, 0x7c84b8, 0x8488e8, /* Codes 8-15 */ + 0x3028e4, 0x100870, 0x3830d0, 0x3c34e8, 0x3028e0, 0x302cb0, 0x20187c, 0xd8ecf8, /* Codes 16-23 */ + 0x58a0e4, 0xd8ecf4, 0xe4f0f8, 0xd0d0f8, 0xc8e0ec, 0x94bcd4, 0xd4e4f4, /* Codes 24-30 */ +}; + +static const uint32_t g_nxiconBrightLut[BITMAP_NLUTCODES] = +{ + 0xfcfcfc, 0x6963e7, 0x6c66e7, 0xd8e7f3, 0x6057e7, 0xd5e7f3, 0x514b96, 0xdeedf6, /* Codes 0-7 */ + 0x81aecc, 0xdef0f3, 0x5d5a9f, 0x6c66f0, 0xa2a8f3, 0x78a8c6, 0x9ca2c9, 0xa2a5ed, /* Codes 8-15 */ + 0x635dea, 0x4b4593, 0x6963db, 0x6c66ed, 0x635de7, 0x6360c3, 0x57519c, 0xe1f0f9, /* Codes 16-23 */ + 0x81b7ea, 0xe1f0f6, 0xeaf3f9, 0xdbdbf9, 0xd5e7f0, 0xaeccde, 0xdeeaf6, /* Codes 24-30 */ +}; + +#elif CONFIG_NXWIDGETS_BPP == 16 +// RGB16 (565) Colors (four of the colors in this map are duplicates) + +static const uint16_t g_nxiconNormalLut[BITMAP_NLUTCODES] = +{ + 0xffff, 0x399c, 0x39bc, 0xcf1e, 0x291c, 0xcf1e, 0x188e, 0xd75e, 0x5cb7, 0xd77e, /* Codes 0-9 */ + 0x2930, 0x39bd, 0x847e, 0x4c76, 0x7c37, 0x845d, 0x315c, 0x104e, 0x399a, 0x39bd, /* Codes 10-19 */ + 0x315c, 0x3176, 0x20cf, 0xdf7f, 0x5d1c, 0xdf7e, 0xe79f, 0xd69f, 0xcf1d, 0x95fa, /* Codes 20-29 */ + 0xd73e, /* Codes 30-30 */ +}; + +static const uint16_t g_nxiconBrightLut[BITMAP_NLUTCODES] = +{ + 0xffff, 0x6b1c, 0x6b3c, 0xdf3e, 0x62bc, 0xd73e, 0x5252, 0xdf7e, 0x8579, 0xdf9e, /* Codes 0-9 */ + 0x5ad3, 0x6b3e, 0xa55e, 0x7d58, 0x9d19, 0xa53d, 0x62fd, 0x4a32, 0x6b1b, 0x6b3d, /* Codes 10-19 */ + 0x62fc, 0x6318, 0x5293, 0xe79f, 0x85bd, 0xe79e, 0xef9f, 0xdedf, 0xd73e, 0xae7b, /* Codes 20-29 */ + 0xdf5e, /* Codes 30-30 */ +}; + +#elif CONFIG_NXWIDGETS_BPP == 8 +// 8-bit color lookups. NOTE: This is really dumb! The lookup index is 8-bits and it used +// to lookup an 8-bit value. There is no savings in that! It would be better to just put +// the 8-bit color/greyscale value in the run-length encoded image and save the cost of these +// pointless lookups. But these p;ointless lookups do make the logic compatible with the +// 16- and 24-bit types. +/// + +# ifdef CONFIG_NXWIDGETS_GREYSCALE +// 8-bit Greyscale + +static const uint8_t g_nxiconNormalLut[BITMAP_NLUTCODES] = +{ + 0xfc, 0x46, 0x4a, 0xdb, 0x39, 0xda, 0x1d, 0xe3, 0x86, 0xe5, 0x2f, 0x4b, 0x95, 0x7d, 0x87, 0x91, /* Codes 0-15 */ + 0x3f, 0x16, 0x44, 0x4a, 0x3f, 0x3c, 0x25, 0xe7, 0x92, 0xe6, 0xed, 0xd4, 0xda, 0xb2, 0xe1, /* Codes 16-30 */ +} + +static const uint8_t g_nxiconBrightLut[BITMAP_NLUTCODES] = +{ + 0xfc, 0x73, 0x76, 0xe3, 0x6a, 0xe2, 0x55, 0xe9, 0xa3, 0xea, 0x62, 0x77, 0xae, 0x9d, 0xa4, 0xac, /* Codes 0-15 */ + 0x6e, 0x4f, 0x72, 0x77, 0x6e, 0x6c, 0x5b, 0xec, 0xac, 0xec, 0xf0, 0xde, 0xe2, 0xc5, 0xe7, /* Codes 16-30 */ +}; + +# else /* CONFIG_NXWIDGETS_GREYSCALE */ +// RGB8 (332) Colors + +static const nxgl_mxpixel_t g_nxiconNormalLut[BITMAP_NLUTCODES] = +{ + 0xff, 0x27, 0x27, 0xdf, 0x27, 0xdf, 0x01, 0xdf, 0x53, 0xdf, 0x26, 0x27, 0x93, 0x52, 0x72, 0x93, /* Codes 0-15 */ + 0x27, 0x01, 0x27, 0x27, 0x27, 0x26, 0x22, 0xdf, 0x57, 0xdf, 0xff, 0xdb, 0xdf, 0x97, 0xdf, /* Codes 16-30 */ +}; + +static const uint8_t g_nxiconBrightLut[BITMAP_NLUTCODES] = +{ + 0xff, 0x6f, 0x6f, 0xdf, 0x6b, 0xdf, 0x4a, 0xff, 0x97, 0xff, 0x4a, 0x6f, 0xb7, 0x77, 0x97, 0xb7, /* Codes 0-15 */ + 0x6b, 0x4a, 0x6f, 0x6f, 0x6b, 0x6f, 0x4a, 0xff, 0x97, 0xff, 0xff, 0xdb, 0xdf, 0xbb, 0xff, /* Codes 16-30 */ +}; + +# endif +#else +# error Unsupported pixel format +#endif + +static const struct SRlePaletteBitmapEntry g_nxiconRleEntries[] = +{ + { 10, 0}, { 1, 1}, { 10, 0}, // Row 0 + { 9, 0}, { 1, 1}, { 1, 2}, { 1, 1}, { 9, 0}, // Row 1 + { 8, 0}, { 1, 1}, { 3, 2}, { 1, 1}, { 8, 0}, // Row 2 + { 3, 0}, { 2, 3}, { 2, 0}, { 1, 1}, { 1, 2}, { 1, 4}, { 1, 5}, { 1, 6}, // Row 3 + { 1, 2}, { 1, 1}, { 4, 0}, { 1, 7}, { 2, 0}, + { 4, 0}, { 1, 3}, { 1, 8}, { 1, 1}, { 2, 2}, { 1, 9}, { 1, 0}, { 1, 3}, // Row 4 + { 1, 10}, { 1, 2}, { 1, 1}, { 1, 0}, { 1, 3}, { 1, 0}, { 1, 8}, { 2, 0}, + { 5, 0}, { 1, 3}, { 1, 11}, { 2, 2}, { 1, 9}, { 2, 0}, { 1, 10}, { 2, 2}, // Row 5 + { 1, 12}, { 1, 0}, { 1, 3}, { 1, 8}, { 2, 0}, + { 5, 0}, { 1, 3}, { 1, 10}, { 2, 2}, { 1, 9}, { 2, 0}, { 1, 3}, { 1, 10}, // Row 6 + { 1, 2}, { 1, 3}, { 1, 0}, { 1, 13}, { 3, 0}, + { 4, 0}, { 1, 3}, { 1, 0}, { 1, 3}, { 1, 11}, { 1, 2}, { 1, 9}, { 1, 0}, // Row 7 + { 1, 3}, { 1, 0}, { 1, 14}, { 1, 15}, { 1, 0}, { 1, 3}, { 1, 10}, { 3, 0}, + { 2, 0}, { 1, 16}, { 1, 0}, { 1, 3}, { 1, 0}, { 1, 3}, { 1, 10}, { 1, 2}, // Row 8 + { 1, 9}, { 1, 0}, { 1, 17}, { 1, 0}, { 2, 3}, { 1, 0}, { 1, 14}, { 1, 1}, + { 1, 18}, { 2, 0}, + { 1, 0}, { 1, 19}, { 1, 20}, { 1, 0}, { 2, 3}, { 1, 0}, { 1, 3}, { 1, 21}, // Row 9 + { 1, 9}, { 1, 0}, { 1, 22}, { 1, 3}, { 2, 0}, { 1, 3}, { 1, 10}, { 2, 2}, + { 1, 1}, { 1, 0}, + { 1, 19}, { 1, 2}, { 1, 20}, { 1, 0}, { 1, 3}, { 1, 10}, { 1, 0}, { 1, 3}, // Row 10 + { 1, 10}, { 1, 9}, { 1, 0}, { 1, 22}, { 1, 4}, { 2, 0}, { 1, 10}, { 1, 1}, + { 3, 2}, { 1, 1}, + { 1, 0}, { 1, 1}, { 1, 20}, { 1, 0}, { 1, 3}, { 1, 10}, { 1, 3}, { 1, 0}, // Row 11 + { 1, 3}, { 1, 23}, { 1, 0}, { 1, 22}, { 1, 3}, { 2, 0}, { 1, 6}, { 1, 1}, + { 3, 2}, { 1, 24}, + { 2, 0}, { 1, 20}, { 1, 0}, { 1, 3}, { 1, 10}, { 1, 2}, { 1, 0}, { 1, 3}, // Row 12 + { 1, 25}, { 1, 0}, { 1, 22}, { 1, 26}, { 2, 0}, { 1, 3}, { 1, 10}, { 2, 2}, + { 1, 24}, { 1, 0}, + { 2, 0}, { 1, 27}, { 1, 0}, { 1, 3}, { 1, 10}, { 1, 2}, { 1, 3}, { 1, 0}, // Row 13 + { 1, 3}, { 1, 0}, { 1, 3}, { 1, 0}, { 2, 3}, { 1, 0}, { 1, 14}, { 1, 2}, + { 1, 24}, { 2, 0}, + { 4, 0}, { 1, 3}, { 1, 10}, { 2, 2}, { 1, 0}, { 1, 3}, { 1, 0}, { 1, 28}, // Row 14 + { 1, 0}, { 1, 10}, { 1, 2}, { 1, 0}, { 1, 3}, { 1, 10}, { 3, 0}, + { 4, 0}, { 1, 3}, { 1, 10}, { 2, 2}, { 1, 3}, { 3, 0}, { 1, 3}, { 1, 10}, // Row 15 + { 1, 2}, { 1, 3}, { 1, 0}, { 1, 29}, { 3, 0}, + { 4, 0}, { 1, 3}, { 1, 8}, { 1, 1}, { 2, 2}, { 3, 0}, { 1, 10}, { 1, 1}, // Row 16 + { 1, 2}, { 1, 24}, { 1, 0}, { 1, 3}, { 1, 8}, { 2, 0}, + { 4, 0}, { 1, 3}, { 1, 8}, { 1, 0}, { 1, 1}, { 1, 2}, { 1, 3}, { 1, 0}, // Row 17 + { 1, 3}, { 1, 10}, { 1, 2}, { 1, 24}, { 1, 0}, { 1, 3}, { 1, 0}, { 1, 8}, + { 2, 0}, + { 4, 0}, { 1, 30}, { 1, 8}, { 2, 0}, { 1, 18}, { 1, 2}, { 1, 3}, { 1, 10}, // Row 18 + { 1, 2}, { 1, 24}, { 3, 0}, { 1, 3}, { 1, 8}, { 2, 0}, + { 4, 0}, { 2, 8}, { 3, 0}, { 1, 1}, { 2, 2}, { 1, 24}, { 8, 0}, // Row 19 + { 10, 0}, { 1, 1}, { 1, 24}, { 9, 0}, // Row 20 + }; + +/******************************************************************************************** + * Public Bitmap Structure Definitions + ********************************************************************************************/ + +const struct SRlePaletteBitmap NXWidgets::g_nxiconBitmap = +{ + CONFIG_NXWIDGETS_BPP, // bpp - Bits per pixel + CONFIG_NXWIDGETS_FMT, // fmt - Color format + BITMAP_NLUTCODES, // nlut - Number of colors in the lLook-Up Table (LUT) + BITMAP_NCOLUMNS, // width - Width in pixels + BITMAP_NROWS, // height - Height in rows + { // lut - Pointer to the beginning of the Look-Up Table (LUT) + g_nxiconNormalLut, // Index 0: Unselected LUT + g_nxiconBrightLut, // Index 1: Selected LUT + }, + g_nxiconRleEntries // data - Pointer to the beginning of the RLE data +}; + diff --git a/graphics/nxglyphs/src/glyph_nxicon42x42.cxx b/graphics/nxglyphs/src/glyph_nxicon42x42.cxx new file mode 100644 index 000000000..50a818984 --- /dev/null +++ b/graphics/nxglyphs/src/glyph_nxicon42x42.cxx @@ -0,0 +1,306 @@ +/******************************************************************************************** + * apps/graphics/nxwm/src/glyph_nxicon42x42.cxx + * + * 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, NxWidgets, nor the names of its contributors + * me 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 "graphics/nxwidgets/crlepalettebitmap.hxx" +#include "graphics/nxglyphs.hxx" + +/******************************************************************************************** + * Pre-Processor Definitions + ********************************************************************************************/ + +#define BITMAP_NROWS 42 +#define BITMAP_NCOLUMNS 42 +#define BITMAP_NLUTCODES 52 + +/******************************************************************************************** + * Private Bitmap Data + ********************************************************************************************/ + +using namespace NXWidgets; + +#if CONFIG_NXWIDGETS_BPP == 24 || CONFIG_NXWIDGETS_BPP == 32 +// RGB24 (8-8-8) Colors + +static const uint32_t g_nxiconNormalLut[BITMAP_NLUTCODES] = +{ + 0xfcfcfc, 0x3830e0, 0x3c34e0, 0x3828e0, 0xe0f0f8, 0xdcd8f8, 0x8488e8, 0xd4ecf0, /* Codes 0-7 */ + 0x2c20e0, 0x3830d0, 0xcce0f0, 0xd4e8f4, 0x5894bc, 0xc8e0f0, 0x181074, 0x2c2894, /* Codes 8-15 */ + 0xf4f8f8, 0xe4f0f4, 0xe4f0f8, 0x282480, 0x3c34ec, 0xc8e0ec, 0x90bcd4, 0x848cf0, /* Codes 16-23 */ + 0x4c8cb4, 0xe0ecf4, 0x302cb0, 0x7c84b8, 0xd8ecf8, 0x282478, 0x3028e4, 0x100870, /* Codes 24-31 */ + 0x08006c, 0x3c34e8, 0x3028e0, 0x20187c, 0xdcf4f0, 0xf0f4f8, 0x5ca4e8, 0x58a0e4, /* Codes 32-39 */ + 0xd8ecf4, 0xc4dcec, 0xdcf4fc, 0xd0e8f4, 0xd0d0f8, 0x94bcd4, 0x5080b0, 0xd4e4f4, /* Codes 40-47 */ + 0x303c8c, 0x1c1870, 0x3830cc, 0x382ce0, /* Codes 48-51 */ +}; + +static const uint32_t g_nxiconBrightLut[BITMAP_NLUTCODES] = +{ + 0xfcfcfc, 0x6963e7, 0x6c66e7, 0x695de7, 0xe7f3f9, 0xe4e1f9, 0xa2a5ed, 0xdef0f3, /* Codes 0-7 */ + 0x6057e7, 0x6963db, 0xd8e7f3, 0xdeedf6, 0x81aecc, 0xd5e7f3, 0x514b96, 0x605dae, /* Codes 8-15 */ + 0xf6f9f9, 0xeaf3f6, 0xeaf3f9, 0x5d5a9f, 0x6c66f0, 0xd5e7f0, 0xabccde, 0xa2a8f3, /* Codes 16-23 */ + 0x78a8c6, 0xe7f0f6, 0x6360c3, 0x9ca2c9, 0xe1f0f9, 0x5d5a99, 0x635dea, 0x4b4593, /* Codes 24-31 */ + 0x453f90, 0x6c66ed, 0x635de7, 0x57519c, 0xe4f6f3, 0xf3f6f9, 0x84baed, 0x81b7ea, /* Codes 32-39 */ + 0xe1f0f6, 0xd2e4f0, 0xe4f6fc, 0xdbedf6, 0xdbdbf9, 0xaeccde, 0x7b9fc3, 0xdeeaf6, /* Codes 40-47 */ + 0x636ca8, 0x545193, 0x6963d8, 0x6960e7, /* Codes 48-51 */ +}; + +#elif CONFIG_NXWIDGETS_BPP == 16 +// RGB16 (565) Colors (four of the colors in this map are duplicates) + +static const uint16_t g_nxiconNormalLut[BITMAP_NLUTCODES] = +{ + 0xffff, 0x399c, 0x39bc, 0x395c, 0xe79f, 0xdedf, 0x845d, 0xd77e, 0x291c, 0x399a, /* Codes 0-9 */ + 0xcf1e, 0xd75e, 0x5cb7, 0xcf1e, 0x188e, 0x2952, 0xf7df, 0xe79e, 0xe79f, 0x2930, /* Codes 10-19 */ + 0x39bd, 0xcf1d, 0x95fa, 0x847e, 0x4c76, 0xe77e, 0x3176, 0x7c37, 0xdf7f, 0x292f, /* Codes 20-29 */ + 0x315c, 0x104e, 0x080d, 0x39bd, 0x315c, 0x20cf, 0xdfbe, 0xf7bf, 0x5d3d, 0x5d1c, /* Codes 30-39 */ + 0xdf7e, 0xc6fd, 0xdfbf, 0xd75e, 0xd69f, 0x95fa, 0x5416, 0xd73e, 0x31f1, 0x18ce, /* Codes 40-49 */ + 0x3999, 0x397c, /* Codes 50-51 */ +}; + +static const uint16_t g_nxiconBrightLut[BITMAP_NLUTCODES] = +{ + 0xffff, 0x6b1c, 0x6b3c, 0x6afc, 0xe79f, 0xe71f, 0xa53d, 0xdf9e, 0x62bc, 0x6b1b, /* Codes 0-9 */ + 0xdf3e, 0xdf7e, 0x8579, 0xd73e, 0x5252, 0x62f5, 0xf7df, 0xef9e, 0xef9f, 0x5ad3, /* Codes 10-19 */ + 0x6b3e, 0xd73e, 0xae7b, 0xa55e, 0x7d58, 0xe79e, 0x6318, 0x9d19, 0xe79f, 0x5ad3, /* Codes 20-29 */ + 0x62fd, 0x4a32, 0x41f2, 0x6b3d, 0x62fc, 0x5293, 0xe7be, 0xf7bf, 0x85dd, 0x85bd, /* Codes 30-39 */ + 0xe79e, 0xd73e, 0xe7bf, 0xdf7e, 0xdedf, 0xae7b, 0x7cf8, 0xdf5e, 0x6375, 0x5292, /* Codes 40-49 */ + 0x6b1b, 0x6b1c, /* Codes 50-51 */ +}; + +#elif CONFIG_NXWIDGETS_BPP == 8 +// 8-bit color lookups. NOTE: This is really dumb! The lookup index is 8-bits and it used +// to lookup an 8-bit value. There is no savings in that! It would be better to just put +// the 8-bit color/greyscale value in the run-length encoded image and save the cost of these +// pointless lookups. But these p;ointless lookups do make the logic compatible with the +// 16- and 24-bit types. +/// + +# ifdef CONFIG_NXWIDGETS_GREYSCALE +// 8-bit Greyscale + +static const uint8_t g_nxiconNormalLut[BITMAP_NLUTCODES] = +{ + 0xfc, 0x46, 0x4a, 0x41, 0xec, 0xdc, 0x91, 0xe5, 0x39, 0x44, 0xdb, 0xe3, 0x86, 0xda, 0x1d, 0x35, /* Codes 0-15 */ + 0xf6, 0xec, 0xed, 0x2f, 0x4b, 0xda, 0xb1, 0x95, 0x7d, 0xe9, 0x3c, 0x87, 0xe7, 0x2e, 0x3f, 0x16, /* Codes 16-31 */ + 0x0e, 0x4a, 0x3f, 0x25, 0xec, 0xf3, 0x96, 0x92, 0xe6, 0xd6, 0xed, 0xe2, 0xd4, 0xb2, 0x77, 0xe1, /* Codes 32-47 */ + 0x41, 0x23, 0x44, 0x44, /* Codes 48-51 */ +} + +static const uint8_t g_nxiconBrightLut[BITMAP_NLUTCODES] = +{ + 0xfc, 0x73, 0x76, 0x70, 0xf0, 0xe4, 0xac, 0xea, 0x6a, 0x72, 0xe3, 0xe9, 0xa3, 0xe2, 0x55, 0x67, /* Codes 0-15 */ + 0xf8, 0xf0, 0xf0, 0x62, 0x77, 0xe2, 0xc4, 0xae, 0x9d, 0xed, 0x6c, 0xa4, 0xec, 0x62, 0x6e, 0x4f, /* Codes 16-31 */ + 0x4a, 0x77, 0x6e, 0x5b, 0xf0, 0xf5, 0xaf, 0xac, 0xec, 0xdf, 0xf1, 0xe8, 0xde, 0xc5, 0x98, 0xe7, /* Codes 32-47 */ + 0x70, 0x59, 0x72, 0x72, /* Codes 48-51 */ +}; + +# else /* CONFIG_NXWIDGETS_GREYSCALE */ +// RGB8 (332) Colors + +static const nxgl_mxpixel_t g_nxiconNormalLut[BITMAP_NLUTCODES] = +{ + 0xff, 0x27, 0x27, 0x27, 0xff, 0xdb, 0x93, 0xdf, 0x27, 0x27, 0xdf, 0xdf, 0x53, 0xdf, 0x01, 0x26, /* Codes 0-15 */ + 0xff, 0xff, 0xff, 0x26, 0x27, 0xdf, 0x97, 0x93, 0x52, 0xff, 0x26, 0x72, 0xdf, 0x25, 0x27, 0x01, /* Codes 16-31 */ + 0x01, 0x27, 0x27, 0x22, 0xdf, 0xff, 0x57, 0x57, 0xdf, 0xdb, 0xdf, 0xdf, 0xdb, 0x97, 0x52, 0xdf, /* Codes 32-47 */ + 0x26, 0x01, 0x27, 0x27, /* Codes 48-51 */ +}; + +static const uint8_t g_nxiconBrightLut[BITMAP_NLUTCODES] = +{ + 0xff, 0x6f, 0x6f, 0x6b, 0xff, 0xff, 0xb7, 0xff, 0x6b, 0x6f, 0xdf, 0xff, 0x97, 0xdf, 0x4a, 0x6a, /* Codes 0-15 */ + 0xff, 0xff, 0xff, 0x4a, 0x6f, 0xdf, 0xbb, 0xb7, 0x77, 0xff, 0x6f, 0x97, 0xff, 0x4a, 0x6b, 0x4a, /* Codes 16-31 */ + 0x4a, 0x6f, 0x6b, 0x4a, 0xff, 0xff, 0x97, 0x97, 0xff, 0xdf, 0xff, 0xdf, 0xdb, 0xbb, 0x77, 0xff, /* Codes 32-47 */ + 0x6e, 0x4a, 0x6f, 0x6f, /* Codes 48-51 */ +}; + +# endif +#else +# error Unsupported pixel format +#endif + +static const struct SRlePaletteBitmapEntry g_nxiconRleEntries[] = +{ + { 20, 0}, { 1, 1}, { 1, 2}, { 20, 0}, // Row 0 + { 19, 0}, { 1, 1}, { 1, 3}, { 1, 1}, { 1, 2}, { 19, 0}, // Row 1 + { 18, 0}, { 1, 1}, { 1, 3}, { 2, 2}, { 1, 1}, { 1, 2}, { 18, 0}, // Row 2 + { 17, 0}, { 1, 1}, { 1, 3}, { 4, 2}, { 1, 1}, { 1, 2}, { 17, 0}, // Row 3 + { 15, 0}, { 1, 4}, { 1, 1}, { 1, 3}, { 6, 2}, { 1, 1}, { 1, 2}, { 1, 5}, // Row 4 + { 15, 0}, + { 15, 0}, { 1, 1}, { 3, 2}, { 1, 6}, { 1, 7}, { 1, 8}, { 3, 2}, { 1, 9}, // Row 5 + { 1, 2}, { 6, 0}, { 3, 10}, { 6, 0}, + { 5, 0}, { 1, 11}, { 3, 10}, { 1, 12}, { 4, 0}, { 1, 1}, { 1, 3}, { 2, 2}, // Row 6 + { 1, 8}, { 1, 10}, { 1, 13}, { 1, 10}, { 1, 14}, { 1, 15}, { 2, 2}, { 1, 1}, + { 1, 2}, { 5, 0}, { 1, 10}, { 1, 0}, { 1, 10}, { 1, 11}, { 5, 0}, + { 5, 0}, { 1, 10}, { 1, 0}, { 1, 16}, { 1, 10}, { 2, 12}, { 2, 0}, { 1, 1}, // Row 7 + { 1, 3}, { 3, 2}, { 1, 7}, { 1, 17}, { 1, 0}, { 1, 18}, { 1, 10}, { 1, 19}, + { 1, 20}, { 2, 2}, { 1, 1}, { 1, 2}, { 3, 0}, { 1, 10}, { 1, 18}, { 1, 0}, + { 1, 21}, { 1, 10}, { 1, 12}, { 4, 0}, + { 5, 0}, { 1, 10}, { 2, 0}, { 2, 10}, { 1, 12}, { 1, 0}, { 1, 1}, { 1, 3}, // Row 8 + { 4, 2}, { 1, 7}, { 3, 0}, { 1, 10}, { 1, 14}, { 1, 19}, { 3, 2}, { 1, 1}, + { 1, 2}, { 2, 0}, { 1, 10}, { 2, 0}, { 1, 10}, { 2, 12}, { 4, 0}, + { 5, 0}, { 1, 10}, { 3, 0}, { 1, 10}, { 1, 22}, { 1, 19}, { 1, 3}, { 5, 2}, // Row 9 + { 1, 7}, { 3, 0}, { 1, 18}, { 1, 10}, { 1, 19}, { 1, 20}, { 3, 2}, { 1, 1}, + { 1, 2}, { 1, 10}, { 1, 18}, { 1, 0}, { 1, 21}, { 1, 10}, { 2, 12}, { 4, 0}, + { 5, 0}, { 1, 10}, { 3, 0}, { 2, 10}, { 1, 19}, { 1, 20}, { 5, 2}, { 1, 7}, // Row 10 + { 4, 0}, { 1, 10}, { 2, 19}, { 4, 2}, { 1, 23}, { 1, 10}, { 2, 0}, { 1, 10}, + { 1, 24}, { 1, 12}, { 5, 0}, + { 5, 0}, { 1, 10}, { 3, 0}, { 1, 18}, { 1, 10}, { 1, 14}, { 1, 19}, { 5, 2}, // Row 11 + { 1, 7}, { 2, 0}, { 1, 25}, { 1, 0}, { 1, 21}, { 1, 10}, { 1, 19}, { 1, 26}, + { 3, 2}, { 1, 10}, { 1, 21}, { 1, 0}, { 1, 18}, { 1, 10}, { 2, 12}, { 5, 0}, + { 5, 0}, { 1, 10}, { 4, 0}, { 2, 10}, { 1, 19}, { 1, 20}, { 4, 2}, { 1, 7}, // Row 12 + { 2, 0}, { 1, 13}, { 2, 0}, { 1, 10}, { 2, 19}, { 2, 2}, { 1, 6}, { 1, 10}, + { 2, 0}, { 1, 10}, { 1, 24}, { 1, 12}, { 6, 0}, + { 5, 0}, { 1, 10}, { 2, 0}, { 1, 10}, { 2, 0}, { 1, 10}, { 1, 14}, { 1, 19}, // Row 13 + { 4, 2}, { 1, 7}, { 2, 0}, { 1, 13}, { 1, 18}, { 1, 0}, { 1, 21}, { 1, 10}, + { 1, 19}, { 1, 26}, { 1, 2}, { 1, 10}, { 2, 0}, { 1, 18}, { 1, 10}, { 1, 19}, + { 1, 12}, { 6, 0}, + { 5, 0}, { 1, 10}, { 2, 0}, { 1, 10}, { 2, 0}, { 2, 10}, { 1, 19}, { 1, 20}, // Row 14 + { 3, 2}, { 1, 7}, { 2, 0}, { 1, 13}, { 1, 10}, { 2, 0}, { 1, 10}, { 1, 27}, + { 1, 19}, { 1, 6}, { 1, 10}, { 2, 0}, { 1, 10}, { 1, 14}, { 1, 19}, { 1, 1}, + { 6, 0}, + { 4, 0}, { 1, 28}, { 1, 10}, { 2, 0}, { 2, 10}, { 2, 0}, { 1, 10}, { 1, 14}, // Row 15 + { 1, 19}, { 3, 2}, { 1, 7}, { 2, 0}, { 1, 13}, { 1, 10}, { 1, 18}, { 1, 0}, + { 1, 21}, { 1, 10}, { 1, 19}, { 1, 10}, { 2, 0}, { 1, 18}, { 1, 10}, { 1, 19}, + { 1, 29}, { 1, 1}, { 1, 2}, { 5, 0}, + { 4, 0}, { 1, 30}, { 1, 10}, { 2, 0}, { 2, 10}, { 2, 0}, { 2, 10}, { 1, 19}, // Row 16 + { 1, 1}, { 2, 2}, { 1, 7}, { 2, 0}, { 1, 13}, { 1, 31}, { 1, 10}, { 2, 0}, + { 1, 10}, { 1, 32}, { 1, 10}, { 2, 0}, { 1, 10}, { 1, 27}, { 1, 19}, { 1, 1}, + { 1, 2}, { 1, 9}, { 1, 2}, { 4, 0}, + { 3, 0}, { 1, 33}, { 1, 34}, { 1, 10}, { 2, 0}, { 3, 10}, { 2, 0}, { 1, 10}, // Row 17 + { 2, 19}, { 2, 2}, { 1, 7}, { 2, 0}, { 1, 13}, { 1, 35}, { 1, 10}, { 2, 0}, + { 1, 18}, { 1, 10}, { 1, 18}, { 1, 0}, { 1, 21}, { 1, 10}, { 2, 19}, { 3, 2}, + { 1, 1}, { 1, 2}, { 3, 0}, + { 2, 0}, { 1, 33}, { 1, 2}, { 1, 34}, { 1, 10}, { 2, 0}, { 1, 10}, { 1, 19}, // Row 18 + { 1, 10}, { 2, 0}, { 2, 10}, { 1, 19}, { 1, 26}, { 1, 2}, { 1, 7}, { 2, 0}, + { 1, 13}, { 1, 35}, { 1, 14}, { 1, 10}, { 2, 0}, { 1, 10}, { 2, 0}, { 1, 10}, + { 1, 27}, { 1, 19}, { 1, 1}, { 4, 2}, { 1, 1}, { 1, 2}, { 2, 0}, + { 1, 0}, { 1, 33}, { 2, 2}, { 1, 34}, { 1, 10}, { 2, 0}, { 1, 10}, { 1, 19}, // Row 19 + { 1, 27}, { 1, 10}, { 2, 0}, { 1, 10}, { 2, 19}, { 1, 2}, { 1, 7}, { 2, 0}, + { 1, 13}, { 1, 35}, { 1, 19}, { 1, 10}, { 4, 0}, { 1, 21}, { 1, 10}, { 2, 19}, + { 6, 2}, { 1, 1}, { 1, 2}, { 1, 0}, + { 1, 33}, { 3, 2}, { 1, 34}, { 1, 10}, { 2, 0}, { 1, 10}, { 2, 19}, { 1, 10}, // Row 20 + { 2, 0}, { 2, 10}, { 1, 19}, { 1, 26}, { 1, 7}, { 2, 0}, { 1, 13}, { 1, 35}, + { 1, 19}, { 1, 8}, { 1, 10}, { 3, 0}, { 1, 10}, { 2, 19}, { 1, 1}, { 7, 2}, + { 1, 1}, { 1, 2}, + { 1, 2}, { 1, 1}, { 2, 2}, { 1, 34}, { 1, 10}, { 2, 0}, { 1, 10}, { 2, 19}, // Row 21 + { 1, 36}, { 1, 10}, { 1, 0}, { 1, 18}, { 1, 10}, { 1, 14}, { 1, 19}, { 1, 7}, + { 2, 0}, { 1, 13}, { 1, 35}, { 1, 19}, { 1, 8}, { 1, 10}, { 2, 0}, { 1, 37}, + { 1, 10}, { 2, 19}, { 9, 2}, { 1, 38}, + { 1, 0}, { 1, 2}, { 1, 1}, { 1, 2}, { 1, 34}, { 1, 10}, { 2, 0}, { 1, 10}, // Row 22 + { 2, 19}, { 1, 2}, { 1, 10}, { 2, 0}, { 2, 10}, { 1, 19}, { 1, 28}, { 2, 0}, + { 1, 13}, { 1, 35}, { 1, 19}, { 1, 10}, { 1, 18}, { 3, 0}, { 1, 10}, { 1, 14}, + { 1, 19}, { 1, 1}, { 7, 2}, { 1, 39}, { 1, 0}, + { 2, 0}, { 1, 2}, { 1, 1}, { 1, 34}, { 1, 10}, { 2, 0}, { 1, 10}, { 2, 19}, // Row 23 + { 1, 2}, { 1, 36}, { 1, 10}, { 1, 0}, { 1, 18}, { 1, 10}, { 1, 14}, { 1, 40}, + { 2, 0}, { 1, 13}, { 1, 35}, { 1, 14}, { 1, 10}, { 2, 0}, { 1, 41}, { 1, 0}, + { 1, 18}, { 1, 10}, { 2, 19}, { 6, 2}, { 1, 39}, { 2, 0}, + { 3, 0}, { 1, 2}, { 1, 34}, { 1, 10}, { 2, 0}, { 1, 10}, { 2, 19}, { 2, 2}, // Row 24 + { 1, 10}, { 2, 0}, { 2, 10}, { 1, 40}, { 2, 0}, { 1, 13}, { 1, 35}, { 1, 10}, + { 1, 18}, { 2, 0}, { 1, 10}, { 2, 0}, { 1, 10}, { 1, 42}, { 1, 19}, { 1, 1}, + { 4, 2}, { 1, 39}, { 3, 0}, + { 4, 0}, { 1, 34}, { 1, 10}, { 2, 0}, { 1, 10}, { 2, 19}, { 2, 2}, { 1, 36}, // Row 25 + { 1, 10}, { 2, 0}, { 2, 10}, { 2, 0}, { 1, 13}, { 1, 31}, { 1, 10}, { 2, 0}, + { 1, 10}, { 1, 43}, { 1, 21}, { 1, 0}, { 1, 18}, { 1, 10}, { 2, 19}, { 2, 2}, + { 1, 1}, { 1, 39}, { 4, 0}, + { 4, 0}, { 1, 44}, { 1, 10}, { 2, 0}, { 1, 10}, { 2, 19}, { 3, 2}, { 1, 10}, // Row 26 + { 2, 0}, { 2, 10}, { 2, 0}, { 1, 13}, { 1, 10}, { 1, 21}, { 2, 0}, { 1, 10}, + { 1, 19}, { 1, 10}, { 2, 0}, { 1, 10}, { 1, 27}, { 1, 19}, { 2, 2}, { 1, 39}, + { 5, 0}, + { 5, 0}, { 1, 10}, { 2, 0}, { 1, 10}, { 2, 19}, { 3, 2}, { 1, 10}, { 1, 21}, // Row 27 + { 2, 0}, { 1, 10}, { 2, 0}, { 1, 13}, { 1, 10}, { 2, 0}, { 2, 10}, { 1, 19}, + { 1, 42}, { 1, 18}, { 2, 0}, { 1, 10}, { 1, 19}, { 1, 29}, { 1, 39}, { 6, 0}, + { 5, 0}, { 1, 10}, { 2, 0}, { 1, 10}, { 2, 19}, { 4, 2}, { 1, 10}, { 2, 0}, // Row 28 + { 1, 10}, { 2, 0}, { 1, 13}, { 1, 21}, { 2, 0}, { 1, 10}, { 2, 19}, { 1, 2}, + { 1, 10}, { 2, 0}, { 1, 10}, { 1, 27}, { 1, 19}, { 7, 0}, + { 5, 0}, { 1, 10}, { 2, 0}, { 1, 10}, { 2, 19}, { 4, 2}, { 2, 10}, { 4, 0}, // Row 29 + { 1, 13}, { 2, 0}, { 1, 10}, { 1, 27}, { 1, 19}, { 1, 29}, { 1, 2}, { 1, 36}, + { 1, 18}, { 2, 0}, { 1, 10}, { 2, 12}, { 6, 0}, + { 5, 0}, { 1, 10}, { 2, 0}, { 1, 10}, { 2, 19}, { 5, 2}, { 1, 10}, { 4, 0}, // Row 30 + { 1, 41}, { 2, 0}, { 1, 10}, { 2, 19}, { 3, 2}, { 1, 10}, { 2, 0}, { 1, 10}, + { 1, 45}, { 1, 12}, { 6, 0}, + { 5, 0}, { 1, 10}, { 2, 0}, { 1, 10}, { 1, 46}, { 1, 19}, { 1, 1}, { 4, 2}, // Row 31 + { 1, 36}, { 1, 10}, { 5, 0}, { 1, 10}, { 1, 42}, { 2, 19}, { 3, 2}, { 1, 10}, + { 1, 21}, { 1, 0}, { 1, 18}, { 1, 10}, { 2, 12}, { 5, 0}, + { 5, 0}, { 1, 10}, { 2, 0}, { 1, 10}, { 2, 12}, { 1, 2}, { 1, 1}, { 4, 2}, // Row 32 + { 1, 10}, { 5, 0}, { 1, 10}, { 2, 19}, { 1, 1}, { 2, 2}, { 1, 9}, { 1, 2}, + { 1, 10}, { 2, 0}, { 1, 10}, { 1, 24}, { 1, 12}, { 5, 0}, + { 5, 0}, { 1, 10}, { 2, 0}, { 1, 10}, { 2, 12}, { 1, 0}, { 1, 2}, { 1, 1}, // Row 33 + { 3, 2}, { 1, 36}, { 1, 10}, { 3, 0}, { 1, 10}, { 1, 42}, { 1, 19}, { 1, 26}, + { 2, 2}, { 1, 9}, { 1, 2}, { 1, 0}, { 1, 18}, { 1, 21}, { 1, 0}, { 1, 18}, + { 1, 10}, { 2, 12}, { 4, 0}, + { 5, 0}, { 1, 10}, { 2, 0}, { 1, 10}, { 2, 12}, { 2, 0}, { 1, 2}, { 1, 1}, // Row 34 + { 3, 2}, { 1, 10}, { 3, 0}, { 1, 10}, { 2, 19}, { 2, 2}, { 1, 9}, { 1, 2}, + { 3, 0}, { 1, 10}, { 2, 0}, { 1, 10}, { 2, 12}, { 4, 0}, + { 5, 0}, { 1, 10}, { 2, 0}, { 1, 10}, { 2, 12}, { 3, 0}, { 1, 2}, { 1, 1}, // Row 35 + { 2, 2}, { 1, 36}, { 1, 10}, { 1, 0}, { 1, 10}, { 1, 42}, { 1, 19}, { 1, 26}, + { 1, 2}, { 1, 9}, { 1, 2}, { 4, 0}, { 1, 18}, { 1, 13}, { 1, 18}, { 1, 10}, + { 3, 12}, { 3, 0}, + { 5, 0}, { 1, 10}, { 2, 0}, { 1, 47}, { 2, 12}, { 4, 0}, { 1, 2}, { 1, 9}, // Row 36 + { 2, 2}, { 3, 10}, { 2, 19}, { 1, 2}, { 1, 48}, { 1, 2}, { 6, 0}, { 3, 10}, + { 2, 12}, { 4, 0}, + { 7, 0}, { 4, 12}, { 4, 0}, { 1, 5}, { 1, 2}, { 1, 1}, { 2, 2}, { 1, 49}, // Row 37 + { 2, 19}, { 1, 50}, { 1, 9}, { 1, 2}, { 8, 0}, { 4, 12}, { 4, 0}, + { 7, 0}, { 4, 12}, { 6, 0}, { 1, 2}, { 1, 1}, { 4, 2}, { 1, 9}, { 1, 2}, // Row 38 + { 17, 0}, + { 18, 0}, { 1, 2}, { 1, 1}, { 2, 2}, { 1, 9}, { 1, 2}, { 18, 0}, // Row 39 + { 19, 0}, { 1, 2}, { 1, 1}, { 1, 9}, { 1, 2}, { 19, 0}, // Row 40 + { 20, 0}, { 1, 51}, { 1, 2}, { 20, 0}, // Row 41 + }; + +/******************************************************************************************** + * Public Bitmap Structure Definitions + ********************************************************************************************/ + +const struct SRlePaletteBitmap NXWidgets::g_nxiconBitmap = +{ + CONFIG_NXWIDGETS_BPP, // bpp - Bits per pixel + CONFIG_NXWIDGETS_FMT, // fmt - Color format + BITMAP_NLUTCODES, // nlut - Number of colors in the lLook-Up Table (LUT) + BITMAP_NCOLUMNS, // width - Width in pixels + BITMAP_NROWS, // height - Height in rows + { // lut - Pointer to the beginning of the Look-Up Table (LUT) + g_nxiconNormalLut, // Index 0: Unselected LUT + g_nxiconBrightLut, // Index 1: Selected LUT + }, + g_nxiconRleEntries // data - Pointer to the beginning of the RLE data +}; + diff --git a/graphics/nxglyphs/src/glyph_resize21x21.cxx b/graphics/nxglyphs/src/glyph_resize21x21.cxx new file mode 100644 index 000000000..79c0c3457 --- /dev/null +++ b/graphics/nxglyphs/src/glyph_resize21x21.cxx @@ -0,0 +1,169 @@ +/******************************************************************************************** + * apps/graphics/nxwm/src/glyph_resize21x21.cxx + * + * 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, NxWidgets, nor the names of its contributors + * me 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 "graphics/nxwidgets/crlepalettebitmap.hxx" +#include "graphics/nxglyphs.hxx" + +/******************************************************************************************** + * Pre-Processor Definitions + ********************************************************************************************/ + +#define BITMAP_NROWS 21 +#define BITMAP_NCOLUMNS 21 +#define BITMAP_NLUTCODES 6 + +/******************************************************************************************** + * Private Bitmap Data + ********************************************************************************************/ + +using namespace NXWidgets; + +#if CONFIG_NXWIDGETS_BPP == 24 || CONFIG_NXWIDGETS_BPP == 32 +// RGB24 (8-8-8) Colors + +static const uint32_t g_resizeNormalLut[BITMAP_NLUTCODES] = +{ + 0x90f0cc, 0x00b400, 0x00d800, 0xfcfcfc, 0x00a400, 0x046414, /* Codes 0-5 */ +}; + +static const uint32_t g_resizeBrightLut[BITMAP_NLUTCODES] = +{ + 0xabf3d8, 0x3fc63f, 0x3fe13f, 0xfcfcfc, 0x3fba3f, 0x428a4e, /* Codes 0-5 */ +}; + +#elif CONFIG_NXWIDGETS_BPP == 16 +// RGB16 (565) Colors (four of the colors in this map are duplicates) + +static const uint16_t g_resizeNormalLut[BITMAP_NLUTCODES] = +{ + 0x9799, 0x05a0, 0x06c0, 0xffff, 0x0520, 0x0322, /* Codes 0-5 */ +}; + +static const uint16_t g_resizeBrightLut[BITMAP_NLUTCODES] = +{ + 0xaf9b, 0x3e27, 0x3f07, 0xffff, 0x3dc7, 0x4449, /* Codes 0-5 */ +}; + +#elif CONFIG_NXWIDGETS_BPP == 8 +// 8-bit color lookups. NOTE: This is really dumb! The lookup index is 8-bits and it used +// to lookup an 8-bit value. There is no savings in that! It would be better to just put +// the 8-bit color/greyscale value in the run-length encoded image and save the cost of these +// pointless lookups. But these p;ointless lookups do make the logic compatible with the +// 16- and 24-bit types. +/// + +# ifdef CONFIG_NXWIDGETS_GREYSCALE +// 8-bit Greyscale + +static const uint8_t g_resizeNormalLut[BITMAP_NLUTCODES] = +{ + 0xcf, 0x69, 0x7e, 0xfc, 0x60, 0x3e, /* Codes 0-5 */ +} + +static const uint8_t g_resizeBrightLut[BITMAP_NLUTCODES] = +{ + 0xda, 0x8e, 0x9e, 0xfc, 0x87, 0x6d, /* Codes 0-5 */ +}; + +# else /* CONFIG_NXWIDGETS_GREYSCALE */ +// RGB8 (332) Colors + +static const nxgl_mxpixel_t g_resizeNormalLut[BITMAP_NLUTCODES] = +{ + 0x9f, 0x14, 0x18, 0xff, 0x14, 0x0c, /* Codes 0-5 */ +}; + +static const uint8_t g_resizeBrightLut[BITMAP_NLUTCODES] = +{ + 0xbf, 0x59, 0x5d, 0xff, 0x55, 0x51, /* Codes 0-5 */ +}; + +# endif +#else +# error Unsupported pixel format +#endif + +static const struct SRlePaletteBitmapEntry g_resizeRleEntries[] = +{ + { 21, 0}, // Row 0 + { 1, 0}, { 4, 1}, { 7, 2}, { 9, 1}, // Row 1 + { 1, 0}, { 3, 1}, { 9, 2}, { 8, 1}, // Row 2 + { 1, 0}, { 2, 1}, { 10, 2}, { 8, 1}, // Row 3 + { 1, 0}, { 1, 1}, { 2, 2}, { 14, 3}, { 3, 1}, // Row 4 + { 1, 0}, { 1, 1}, { 2, 2}, { 1, 3}, { 6, 2}, { 6, 1}, { 1, 3}, { 2, 1}, // Row 5 + { 1, 4}, + { 1, 0}, { 3, 2}, { 1, 3}, { 5, 2}, { 7, 1}, { 1, 3}, { 2, 1}, { 1, 4}, // Row 6 + { 1, 0}, { 3, 2}, { 1, 3}, { 4, 2}, { 8, 1}, { 1, 3}, { 2, 1}, { 1, 4}, // Row 7 + { 1, 0}, { 3, 2}, { 1, 3}, { 3, 2}, { 9, 1}, { 1, 3}, { 1, 1}, { 2, 4}, // Row 8 + { 1, 0}, { 3, 2}, { 1, 3}, { 1, 2}, { 11, 1}, { 1, 3}, { 1, 1}, { 2, 4}, // Row 9 + { 1, 0}, { 1, 1}, { 2, 2}, { 1, 3}, { 12, 1}, { 1, 3}, { 3, 4}, // Row 10 + { 1, 0}, { 3, 1}, { 1, 3}, { 12, 1}, { 1, 3}, { 3, 4}, // Row 11 + { 1, 0}, { 3, 1}, { 1, 3}, { 11, 1}, { 1, 4}, { 1, 3}, { 3, 4}, // Row 12 + { 1, 0}, { 3, 1}, { 1, 3}, { 10, 1}, { 2, 4}, { 1, 3}, { 3, 4}, // Row 13 + { 1, 0}, { 3, 1}, { 1, 3}, { 9, 1}, { 3, 4}, { 1, 3}, { 3, 4}, // Row 14 + { 1, 0}, { 3, 1}, { 1, 3}, { 8, 1}, { 4, 4}, { 1, 3}, { 3, 4}, // Row 15 + { 1, 0}, { 3, 1}, { 1, 3}, { 6, 1}, { 6, 4}, { 1, 3}, { 3, 4}, // Row 16 + { 1, 0}, { 3, 1}, { 14, 3}, { 3, 4}, // Row 17 + { 1, 0}, { 4, 1}, { 16, 4}, // Row 18 + { 1, 0}, { 2, 1}, { 18, 4}, // Row 19 + { 1, 0}, { 19, 4}, { 1, 5}, // Row 20 + }; + +/******************************************************************************************** + * Public Bitmap Structure Definitions + ********************************************************************************************/ + +const struct SRlePaletteBitmap NXWidgets::g_resizeBitmap = +{ + CONFIG_NXWIDGETS_BPP, // bpp - Bits per pixel + CONFIG_NXWIDGETS_FMT, // fmt - Color format + BITMAP_NLUTCODES, // nlut - Number of colors in the lLook-Up Table (LUT) + BITMAP_NCOLUMNS, // width - Width in pixels + BITMAP_NROWS, // height - Height in rows + { // lut - Pointer to the beginning of the Look-Up Table (LUT) + g_resizeNormalLut, // Index 0: Unselected LUT + g_resizeBrightLut, // Index 1: Selected LUT + }, + g_resizeRleEntries // data - Pointer to the beginning of the RLE data +}; + diff --git a/graphics/nxglyphs/src/glyph_resize42x42.cxx b/graphics/nxglyphs/src/glyph_resize42x42.cxx new file mode 100644 index 000000000..6c46a69f8 --- /dev/null +++ b/graphics/nxglyphs/src/glyph_resize42x42.cxx @@ -0,0 +1,214 @@ +/******************************************************************************************** + * apps/graphics/nxwm/src/glyph_resize42x42.cxx + * + * 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, NxWidgets, nor the names of its contributors + * me 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 "graphics/nxwidgets/crlepalettebitmap.hxx" +#include "graphics/nxglyphs.hxx" + +/******************************************************************************************** + * Pre-Processor Definitions + ********************************************************************************************/ + +#define BITMAP_NROWS 42 +#define BITMAP_NCOLUMNS 42 +#define BITMAP_NLUTCODES 7 + +/******************************************************************************************** + * Private Bitmap Data + ********************************************************************************************/ + +using namespace NXWidgets; + +#if CONFIG_NXWIDGETS_BPP == 24 || CONFIG_NXWIDGETS_BPP == 32 +// RGB24 (8-8-8) Colors + +static const uint32_t g_resizeNormalLut[BITMAP_NLUTCODES] = +{ + 0x90f0cc, 0x00b400, 0x00d800, 0x046414, 0xfcfcfc, 0xd8fcfc, 0x00a400, /* Codes 0-6 */ +}; + +static const uint32_t g_resizeBrightLut[BITMAP_NLUTCODES] = +{ + 0xabf3d8, 0x3fc63f, 0x3fe13f, 0x428a4e, 0xfcfcfc, 0xe1fcfc, 0x3fba3f, /* Codes 0-6 */ +}; + +#elif CONFIG_NXWIDGETS_BPP == 16 +// RGB16 (565) Colors (four of the colors in this map are duplicates) + +static const uint16_t g_resizeNormalLut[BITMAP_NLUTCODES] = +{ + 0x9799, 0x05a0, 0x06c0, 0x0322, 0xffff, 0xdfff, 0x0520, /* Codes 0-6 */ +}; + +static const uint16_t g_resizeBrightLut[BITMAP_NLUTCODES] = +{ + 0xaf9b, 0x3e27, 0x3f07, 0x4449, 0xffff, 0xe7ff, 0x3dc7, /* Codes 0-6 */ +}; + +#elif CONFIG_NXWIDGETS_BPP == 8 +// 8-bit color lookups. NOTE: This is really dumb! The lookup index is 8-bits and it used +// to lookup an 8-bit value. There is no savings in that! It would be better to just put +// the 8-bit color/greyscale value in the run-length encoded image and save the cost of these +// pointless lookups. But these p;ointless lookups do make the logic compatible with the +// 16- and 24-bit types. +/// + +# ifdef CONFIG_NXWIDGETS_GREYSCALE +// 8-bit Greyscale + +static const uint8_t g_resizeNormalLut[BITMAP_NLUTCODES] = +{ + 0xcf, 0x69, 0x7e, 0x3e, 0xfc, 0xf1, 0x60, /* Codes 0-6 */ +} + +static const uint8_t g_resizeBrightLut[BITMAP_NLUTCODES] = +{ + 0xda, 0x8e, 0x9e, 0x6d, 0xfc, 0xf3, 0x87, /* Codes 0-6 */ +}; + +# else /* CONFIG_NXWIDGETS_GREYSCALE */ +// RGB8 (332) Colors + +static const nxgl_mxpixel_t g_resizeNormalLut[BITMAP_NLUTCODES] = +{ + 0x9f, 0x14, 0x18, 0x0c, 0xff, 0xdf, 0x14, /* Codes 0-6 */ +}; + +static const uint8_t g_resizeBrightLut[BITMAP_NLUTCODES] = +{ + 0xbf, 0x59, 0x5d, 0x51, 0xff, 0xff, 0x55, /* Codes 0-6 */ +}; + +# endif +#else +# error Unsupported pixel format +#endif + +static const struct SRlePaletteBitmapEntry g_resizeRleEntries[] = +{ + { 42, 0}, // Row 0 + { 1, 0}, { 11, 1}, { 10, 2}, { 19, 1}, { 1, 0}, // Row 1 + { 1, 0}, { 9, 1}, { 14, 2}, { 17, 1}, { 1, 3}, // Row 2 + { 1, 0}, { 7, 1}, { 17, 2}, { 16, 1}, { 1, 3}, // Row 3 + { 1, 0}, { 6, 1}, { 18, 2}, { 16, 1}, { 1, 3}, // Row 4 + { 1, 0}, { 5, 1}, { 19, 2}, { 16, 1}, { 1, 3}, // Row 5 + { 1, 0}, { 4, 1}, { 20, 2}, { 16, 1}, { 1, 3}, // Row 6 + { 1, 0}, { 3, 1}, { 20, 2}, { 17, 1}, { 1, 3}, // Row 7 + { 1, 0}, { 3, 1}, { 3, 2}, { 27, 4}, { 7, 1}, { 1, 3}, // Row 8 + { 1, 0}, { 2, 1}, { 4, 2}, { 1, 4}, { 24, 5}, { 2, 4}, { 1, 5}, { 5, 1}, // Row 9 + { 1, 6}, { 1, 3}, + { 1, 0}, { 2, 1}, { 4, 2}, { 1, 4}, { 1, 5}, { 13, 2}, { 11, 1}, { 1, 4}, // Row 10 + { 1, 5}, { 5, 1}, { 1, 6}, { 1, 3}, + { 1, 0}, { 1, 1}, { 5, 2}, { 1, 4}, { 1, 5}, { 12, 2}, { 12, 1}, { 1, 4}, // Row 11 + { 1, 5}, { 5, 1}, { 1, 6}, { 1, 3}, + { 1, 0}, { 1, 1}, { 5, 2}, { 1, 4}, { 1, 5}, { 11, 2}, { 13, 1}, { 1, 4}, // Row 12 + { 1, 5}, { 5, 1}, { 1, 6}, { 1, 3}, + { 1, 0}, { 6, 2}, { 1, 4}, { 1, 5}, { 10, 2}, { 14, 1}, { 1, 4}, { 1, 5}, // Row 13 + { 4, 1}, { 2, 6}, { 1, 3}, + { 1, 0}, { 6, 2}, { 1, 4}, { 1, 5}, { 9, 2}, { 15, 1}, { 1, 4}, { 1, 5}, // Row 14 + { 4, 1}, { 2, 6}, { 1, 3}, + { 1, 0}, { 6, 2}, { 1, 4}, { 1, 5}, { 7, 2}, { 17, 1}, { 1, 4}, { 1, 5}, // Row 15 + { 3, 1}, { 3, 6}, { 1, 3}, + { 1, 0}, { 6, 2}, { 1, 4}, { 1, 5}, { 6, 2}, { 18, 1}, { 1, 4}, { 1, 5}, // Row 16 + { 3, 1}, { 3, 6}, { 1, 3}, + { 1, 0}, { 6, 2}, { 1, 4}, { 1, 5}, { 4, 2}, { 20, 1}, { 1, 4}, { 1, 5}, // Row 17 + { 2, 1}, { 4, 6}, { 1, 3}, + { 1, 0}, { 6, 2}, { 1, 4}, { 1, 5}, { 2, 2}, { 22, 1}, { 1, 4}, { 1, 5}, // Row 18 + { 2, 1}, { 4, 6}, { 1, 3}, + { 1, 0}, { 1, 1}, { 5, 2}, { 1, 4}, { 1, 5}, { 1, 2}, { 23, 1}, { 1, 4}, // Row 19 + { 1, 5}, { 1, 1}, { 5, 6}, { 1, 3}, + { 1, 0}, { 2, 1}, { 4, 2}, { 1, 4}, { 1, 5}, { 24, 1}, { 1, 4}, { 1, 5}, // Row 20 + { 1, 1}, { 5, 6}, { 1, 3}, + { 1, 0}, { 4, 1}, { 2, 2}, { 1, 4}, { 1, 5}, { 24, 1}, { 1, 4}, { 1, 5}, // Row 21 + { 6, 6}, { 1, 3}, + { 1, 0}, { 6, 1}, { 1, 4}, { 1, 5}, { 24, 1}, { 1, 4}, { 1, 5}, { 6, 6}, // Row 22 + { 1, 3}, + { 1, 0}, { 6, 1}, { 1, 4}, { 1, 5}, { 24, 1}, { 1, 4}, { 1, 5}, { 6, 6}, // Row 23 + { 1, 3}, + { 1, 0}, { 6, 1}, { 1, 4}, { 1, 5}, { 23, 1}, { 1, 6}, { 1, 4}, { 1, 5}, // Row 24 + { 6, 6}, { 1, 3}, + { 1, 0}, { 6, 1}, { 1, 4}, { 1, 5}, { 22, 1}, { 2, 6}, { 1, 4}, { 1, 5}, // Row 25 + { 6, 6}, { 1, 3}, + { 1, 0}, { 6, 1}, { 1, 4}, { 1, 5}, { 21, 1}, { 3, 6}, { 1, 4}, { 1, 5}, // Row 26 + { 6, 6}, { 1, 3}, + { 1, 0}, { 6, 1}, { 1, 4}, { 1, 5}, { 20, 1}, { 4, 6}, { 1, 4}, { 1, 5}, // Row 27 + { 6, 6}, { 1, 3}, + { 1, 0}, { 6, 1}, { 1, 4}, { 1, 5}, { 19, 1}, { 5, 6}, { 1, 4}, { 1, 5}, // Row 28 + { 6, 6}, { 1, 3}, + { 1, 0}, { 6, 1}, { 1, 4}, { 1, 5}, { 18, 1}, { 6, 6}, { 1, 4}, { 1, 5}, // Row 29 + { 6, 6}, { 1, 3}, + { 1, 0}, { 6, 1}, { 1, 4}, { 1, 5}, { 16, 1}, { 8, 6}, { 1, 4}, { 1, 5}, // Row 30 + { 6, 6}, { 1, 3}, + { 1, 0}, { 6, 1}, { 1, 4}, { 1, 5}, { 14, 1}, { 10, 6}, { 1, 4}, { 1, 5}, // Row 31 + { 6, 6}, { 1, 3}, + { 1, 0}, { 6, 1}, { 1, 4}, { 1, 5}, { 13, 1}, { 11, 6}, { 1, 4}, { 1, 5}, // Row 32 + { 6, 6}, { 1, 3}, + { 1, 0}, { 6, 1}, { 2, 4}, { 12, 1}, { 12, 6}, { 1, 4}, { 1, 5}, { 6, 6}, // Row 33 + { 1, 3}, + { 1, 0}, { 6, 1}, { 27, 4}, { 1, 5}, { 6, 6}, { 1, 3}, // Row 34 + { 1, 0}, { 7, 1}, { 27, 5}, { 6, 6}, { 1, 3}, // Row 35 + { 1, 0}, { 8, 1}, { 32, 6}, { 1, 3}, // Row 36 + { 1, 0}, { 6, 1}, { 34, 6}, { 1, 3}, // Row 37 + { 1, 0}, { 4, 1}, { 36, 6}, { 1, 3}, // Row 38 + { 1, 0}, { 2, 1}, { 37, 6}, { 2, 3}, // Row 39 + { 1, 0}, { 39, 6}, { 2, 3}, // Row 40 + { 2, 0}, { 40, 3}, // Row 41 + }; + +/******************************************************************************************** + * Public Bitmap Structure Definitions + ********************************************************************************************/ + +const struct SRlePaletteBitmap NXWidgets::g_resizeBitmap = +{ + CONFIG_NXWIDGETS_BPP, // bpp - Bits per pixel + CONFIG_NXWIDGETS_FMT, // fmt - Color format + BITMAP_NLUTCODES, // nlut - Number of colors in the lLook-Up Table (LUT) + BITMAP_NCOLUMNS, // width - Width in pixels + BITMAP_NROWS, // height - Height in rows + { // lut - Pointer to the beginning of the Look-Up Table (LUT) + g_resizeNormalLut, // Index 0: Unselected LUT + g_resizeBrightLut, // Index 1: Selected LUT + }, + g_resizeRleEntries // data - Pointer to the beginning of the RLE data +}; + diff --git a/graphics/nxglyphs/src/mksrle.c b/graphics/nxglyphs/src/mksrle.c new file mode 100644 index 000000000..6a9e7539e --- /dev/null +++ b/graphics/nxglyphs/src/mksrle.c @@ -0,0 +1,577 @@ +/**************************************************************************** + * apps/graphics/nxglyphs/src/mksrle.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 + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct rgb_s +{ + unsigned char r; + unsigned char g; + unsigned char b; +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct rgb_s pixels[1024]; +static int npixels = 0; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static unsigned char getmono(unsigned char r, unsigned char g, unsigned char b) +{ + float mono; + unsigned int imono; + + //mono = 0.2125 * (float)r +(0.7154 * (float)g + 0.0721 * (float)b; + mono = 0.299 * (float)r + 0.587 * (float)g + 0.114 * (float)b; + + imono = (unsigned int)mono; + if (mono > 255) + { + mono = 255; + } + + return mono; +} + +static int findpixel(unsigned char r, unsigned char g, unsigned char b) +{ + int i; + + /* Throw away some accuracy */ + + r &= 0xfc; + g &= 0xfc; + b &= 0xfc; + + for (i = 0; i < npixels; i++) + { + if (pixels[i].r == r && pixels[i].g == g && pixels[i].b == b) + { + return i; + } + } + + fprintf(stderr, "Pixel not found\n"); + exit(1); +} + +static void addpixel(unsigned char r, unsigned char g, unsigned char b) +{ + int i; + + /* Throw away some accuracy */ + + r &= 0xfc; + g &= 0xfc; + b &= 0xfc; + + for (i = 0; i < npixels; i++) + { + if (pixels[i].r == r && pixels[i].g == g && pixels[i].b == b) + { + return; + } + } + + pixels[npixels].r = r; + pixels[npixels].g = g; + pixels[npixels].b = b; + npixels++; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +int main(int argc, char **argv, char **envp) +{ + const unsigned char *ptr; + unsigned char r; + unsigned char g; + unsigned char b; + int ncode; + int code; + int last; + int nruns; + int first; + int len; + int i; + int j; + + printf("/********************************************************************************************\n"); + printf(" * apps/graphics/nxwm/src/glyph_xxxxxx.cxx\n"); + printf(" *\n"); + printf(" * Copyright (C) 2019 Gregory Nutt. All rights reserved.\n"); + printf(" * Author: Gregory Nutt \n"); + printf(" *\n"); + printf(" * Redistribution and use in source and binary forms, with or without\n"); + printf(" * modification, are permitted provided that the following conditions\n"); + printf(" * are met:\n"); + printf(" *\n"); + printf(" * 1. Redistributions of source code must retain the above copyright\n"); + printf(" * notice, this list of conditions and the following disclaimer.\n"); + printf(" * 2. Redistributions in binary form must reproduce the above copyright\n"); + printf(" * notice, this list of conditions and the following disclaimer in\n"); + printf(" * the documentation and/or other materials provided with the\n"); + printf(" * distribution.\n"); + printf(" * 3. Neither the name NuttX, NxWidgets, nor the names of its contributors\n"); + printf(" * me be used to endorse or promote products derived from this software\n"); + printf(" * without specific prior written permission.\n"); + printf(" *\n"); + printf(" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n"); + printf(" * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n"); + printf(" * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n"); + printf(" * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n"); + printf(" * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n"); + printf(" * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n"); + printf(" * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n"); + printf(" * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n"); + printf(" * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n"); + printf(" * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n"); + printf(" * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n"); + printf(" * POSSIBILITY OF SUCH DAMAGE.\n"); + printf(" *\n"); + printf(" ********************************************************************************************/\n\n"); + + printf("/********************************************************************************************\n"); + printf(" * Included Files\n"); + printf(" ********************************************************************************************/\n\n"); + printf("#include \n"); + printf("#include \n"); + printf("#include \n\n"); + printf("#include \"graphics/nxwidgets/crlepalettebitmap.hxx\"\n"); + printf("#include \"graphics/nxglyphs.hxx\"\n\n"); + + /* Count the number of colors (npixels) */ + + ptr = gimp_image.pixel_data; + + for (i = 0; i < gimp_image.height; i++) + { + for (j = 0; j < gimp_image.width; j++) + { + r = *ptr++; + g = *ptr++; + b = *ptr++; + + addpixel(r, g, b); + } + } + + printf("/********************************************************************************************\n"); + printf(" * Pre-Processor Definitions\n"); + printf(" ********************************************************************************************/\n\n"); + printf("#define BITMAP_NROWS %u\n", gimp_image.height); + printf("#define BITMAP_NCOLUMNS %u\n", gimp_image.width); + printf("#define BITMAP_NLUTCODES %u\n\n", npixels); + + printf("/********************************************************************************************\n"); + printf(" * Private Bitmap Data\n"); + printf(" ********************************************************************************************/\n\n"); + printf("using namespace NXWidgets;\n\n"); + + printf("#if CONFIG_NXWIDGETS_BPP == 24 || CONFIG_NXWIDGETS_BPP == 32\n"); + printf("// RGB24 (8-8-8) Colors\n\n"); + printf("static const uint32_t g_xxxNormalLut[BITMAP_NLUTCODES] =\n"); + printf("{\n"); + + for (i = 0; i < npixels; i += 8) + { + printf(" "); + for (j = 0; j < 8 && i + j < npixels; j++) + { + unsigned int r = pixels[i+j].r; /* 8->8 bits */ + unsigned int g = pixels[i+j].g; /* 8->8 bits */ + unsigned int b = pixels[i+j].b; /* 8->8 bits */ + unsigned int pix24 = r << 16 | g << 8 | b; + printf(" 0x%06x,", pix24); + } + + printf(" /* Codes %d-%d */\n", i, i+j-1); + } + + printf("};\n\n"); + printf("static const uint32_t g_xxxBrightLut[BITMAP_NLUTCODES] =\n"); + printf("{\n"); + + for (i = 0; i < npixels; i += 8) + { + printf(" "); + for (j = 0; j < 8 && i + j < npixels; j++) + { + unsigned int r = pixels[i+j].r; /* 8->8 bits */ + unsigned int g = pixels[i+j].g; /* 8->8 bits */ + unsigned int b = pixels[i+j].b; /* 8->8 bits */ + + r = (3*r + 0xff) >> 2; + g = (3*g + 0xff) >> 2; + b = (3*b + 0xff) >> 2; + + unsigned int pix24 = r << 16 | g << 8 | b; + printf(" 0x%06x,", pix24); + } + + printf(" /* Codes %d-%d */\n", i, i+j-1); + } + + printf("};\n\n"); + printf("#elif CONFIG_NXWIDGETS_BPP == 16\n"); + printf("// RGB16 (565) Colors (four of the colors in this map are duplicates)\n\n"); + printf("static const uint16_t g_xxxNormalLut[BITMAP_NLUTCODES] =\n"); + printf("{\n"); + + for (i = 0; i < npixels; i += 10) + { + printf(" "); + for (j = 0; j < 10 && i+j < npixels; j++) + { + unsigned int r = pixels[i+j].r >> 3; /* 8->5 bits */ + unsigned int g = pixels[i+j].g >> 2; /* 8->6 bits */ + unsigned int b = pixels[i+j].b >> 3; /* 8->5 bits */ + + if (r > 0x1f) + { + r = 0x1f; + } + + if (g > 0x3f) + { + g = 0x3f; + } + + if (b > 0x1f) + { + b = 0x1f; + } + + unsigned int pix16 = r << 11 | g << 5 | b; + printf(" 0x%04x,", pix16); + } + + printf(" /* Codes %d-%d */\n", i, i+j-1); + } + + printf("};\n\n"); + printf("static const uint16_t g_xxxBrightLut[BITMAP_NLUTCODES] =\n"); + printf("{\n"); + + for (i = 0; i < npixels; i += 10) + { + printf(" "); + for (j = 0; j < 10 && i+j < npixels; j++) + { + unsigned int r = pixels[i+j].r; + unsigned int g = pixels[i+j].g; + unsigned int b = pixels[i+j].b; + + r = (3*r + 0xff) >> 2; + g = (3*g + 0xff) >> 2; + b = (3*b + 0xff) >> 2; + + r >>= 3; /* 8->5 bits */ + g >>= 2; /* 8->6 bits */ + b >>= 3; /* 8->5 bits */ + + if (r > 0x1f) + { + r = 0x1f; + } + + if (g > 0x3f) + { + g = 0x3f; + } + + if (b > 0x1f) + { + b = 0x1f; + } + + unsigned int pix16 = r << 11 | g << 5 | b; + printf(" 0x%04x,", pix16); + } + + printf(" /* Codes %d-%d */\n", i, i+j-1); + } + + printf("};\n\n"); + + printf("#elif CONFIG_NXWIDGETS_BPP == 8\n"); + printf("// 8-bit color lookups. NOTE: This is really dumb! The lookup index is 8-bits and it used\n"); + printf("// to lookup an 8-bit value. There is no savings in that! It would be better to just put\n"); + printf("// the 8-bit color/greyscale value in the run-length encoded image and save the cost of these\n"); + printf("// pointless lookups. But these p;ointless lookups do make the logic compatible with the\n"); + printf("// 16- and 24-bit types.\n"); + printf("///\n\n"); + + printf("# ifdef CONFIG_NXWIDGETS_GREYSCALE\n"); + printf("// 8-bit Greyscale\n\n"); + printf("static const uint8_t g_xxxNormalLut[BITMAP_NLUTCODES] =\n"); + printf("{\n"); + + for (i = 0; i < npixels; i += 16) + { + printf(" "); + for (j = 0; j < 16 && i+j < npixels; j++) + { + unsigned int r = pixels[i+j].r; /* 8->8 bits */ + unsigned int g = pixels[i+j].g; /* 8->8 bits */ + unsigned int b = pixels[i+j].b; /* 8->8 bits */ + + printf(" 0x%02x,", getmono(r, g, b)); + } + + printf(" /* Codes %d-%d */\n", i, i+j-1); + } + + printf("}\n\n"); + printf("static const uint8_t g_xxxBrightLut[BITMAP_NLUTCODES] =\n"); + printf("{\n"); + + for (i = 0; i < npixels; i += 16) + { + printf(" "); + for (j = 0; j < 16 && i+j < npixels; j++) + { + unsigned int r = pixels[i+j].r; /* 8->8 bits */ + unsigned int g = pixels[i+j].g; /* 8->8 bits */ + unsigned int b = pixels[i+j].b; /* 8->8 bits */ + + r = (3*r + 0xff) >> 2; + g = (3*g + 0xff) >> 2; + b = (3*b + 0xff) >> 2; + + printf(" 0x%02x,", getmono(r, g, b)); + } + + printf(" /* Codes %d-%d */\n", i, i+j-1); + } + + printf("};\n\n"); + printf("# else /* CONFIG_NXWIDGETS_GREYSCALE */\n"); + printf("// RGB8 (332) Colors\n\n"); + printf("static const nxgl_mxpixel_t g_xxxNormalLut[BITMAP_NLUTCODES] =\n"); + printf("{\n"); + + for (i = 0; i < npixels; i += 16) + { + printf(" "); + for (j = 0; j < 16 && i+j < npixels; j++) + { + unsigned int r = (pixels[i+j].r + 2) >> 5; /* 8->3 bits */ + unsigned int g = (pixels[i+j].g + 2) >> 5; /* 8->3 bits */ + unsigned int b = (pixels[i+j].b + 4) >> 6; /* 8->2 bits */ + + if (r > 0x07) + { + r = 0x07; + } + if (g > 0x07) + { + g = 0x07; + } + if (b > 0x03) + { + b = 0x03; + } + + unsigned int pix8 = r << 5 | g << 2 | b; + printf(" 0x%02x,", pix8); + } + + printf(" /* Codes %d-%d */\n", i, i+j-1); + } + + printf("};\n\n"); + printf("static const uint8_t g_xxxBrightLut[BITMAP_NLUTCODES] =\n"); + printf("{\n"); + + for (i = 0; i < npixels; i += 16) + { + printf(" "); + for (j = 0; j < 16 && i+j < npixels; j++) + { + unsigned int r = pixels[i+j].r; + unsigned int g = pixels[i+j].g; + unsigned int b = pixels[i+j].b; + + r = (3*r + 0xff) >> 2; + g = (3*g + 0xff) >> 2; + b = (3*b + 0xff) >> 2; + + r = (r + 2) >> 5; /* 8->3 bits */ + g = (g + 2) >> 5; /* 8->3 bits */ + b = (b + 4) >> 6; /* 8->2 bits */ + + if (r > 0x07) + { + r = 0x07; + } + if (g > 0x07) + { + g = 0x07; + } + if (b > 0x03) + { + b = 0x03; + } + + unsigned int pix8 = r << 5 | g << 2 | b; + printf(" 0x%02x,", pix8); + } + + printf(" /* Codes %d-%d */\n", i, i+j-1); + } + + printf("};\n\n"); + printf("# endif\n"); + printf("#else\n"); + printf("# error Unsupported pixel format\n"); + printf("#endif\n\n"); + + printf("static const struct SRlePaletteBitmapEntry g_xxxRleEntries[] =\n"); + printf("{\n "); + + ptr = gimp_image.pixel_data; + + for (i = 0; i < gimp_image.height; i++) + { + ncode = 0; + last = -1; + nruns = 0; + first = 1; + len = 0; + + for (j = 0; j < gimp_image.width; j++) + { + r = *ptr++; + g = *ptr++; + b = *ptr++; + + code = findpixel(r, g, b); + if (code == last && ncode < 256) + { + ncode++; + } + else + { + if (ncode > 0) + { + len += printf(" {%3d, %3d},", ncode, last); + if (++nruns > 7) + { + if (first) + { + while (len < 100) + { + putchar(' '); + len++; + } + + printf("// Row %d\n ", i); + first = 0; + len = 0; + } + else + { + printf("\n "); + len = 0; + } + + nruns = 0; + } + } + + ncode = 1; + last = code; + } + } + + if (ncode > 0) + { + len += printf(" {%3d, %3d},", ncode, last); + } + + if (first) + { + while (len < 100) + { + putchar(' '); + len++; + } + + printf("// Row %d\n ", i); + } + else + { + printf("\n "); + } + } + + printf("};\n\n"); + printf("/********************************************************************************************\n"); + printf(" * Public Bitmap Structure Definitions\n"); + printf(" ********************************************************************************************/\n\n"); + printf("const struct SRlePaletteBitmap NXWidgets::g_xxxBitmap =\n"); + printf("{\n"); + printf(" CONFIG_NXWIDGETS_BPP, // bpp - Bits per pixel\n"); + printf(" CONFIG_NXWIDGETS_FMT, // fmt - Color format\n"); + printf(" BITMAP_NLUTCODES, // nlut - Number of colors in the lLook-Up Table (LUT)\n"); + printf(" BITMAP_NCOLUMNS, // width - Width in pixels\n"); + printf(" BITMAP_NROWS, // height - Height in rows\n"); + printf(" { // lut - Pointer to the beginning of the Look-Up Table (LUT)\n"); + printf(" g_xxxNormalLut, // Index 0: Unselected LUT\n"); + printf(" g_xxxBrightLut, // Index 1: Selected LUT\n"); + printf(" },\n"); + printf(" g_xxxRleEntries // data - Pointer to the beginning of the RLE data\n"); + printf("};\n\n"); + + return 0; +} diff --git a/graphics/nxglyphs/src/mksrle.sh b/graphics/nxglyphs/src/mksrle.sh new file mode 100644 index 000000000..fc4e4a1d7 --- /dev/null +++ b/graphics/nxglyphs/src/mksrle.sh @@ -0,0 +1,110 @@ +#!/bin/bash +# apps/graphics/nxglyphs/src/mksrle.sh +# +# 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. +# + +# Get the input parameter list +# +# - A 4-color image exported as a GIMP C-source file. +# - A 2-bpp cursor image in NuttX cursor format +# - Treated as the transparent background color (default, 0x000000) +# - Usually the primary color of the image (default, 0xff0000) +# - Usually the outline color of the image (default, 0x00007f) +# - Usually blend of color1 and color2 for low-cost anti-aliasing (default, 0x7f003f) +# Output is to stdout, but may be re-directed to a file. + +PROGNAME=$0 +USAGE="USAGE: $PROGNAME [-d] -f -o " + +CFILE=mksrle.c +TMPFILE1=_tmpfile1.c +TMPFILE2=_mksrle.c +TMPPROG=_mksrle.exe + +unset INFILE +unset OUTFILE + +while [ ! -z "$1" ]; do + case $1 in + -d ) + set -x + ;; + -f ) + shift + INFILE=$1 + ;; + -o ) + shift + OUTFILE=$1 + ;; + * ) + echo "Unrecognized argument: $1" + echo $USAGE + exit 1 + ;; + esac + shift +done + +# Check arguments + +if [ -z "${INFILE}" ]; then + echo "MK: Missing input Gimp C-source file name" + echo $USAGE + exit 1 +fi + +if [ ! -r ${INFILE} ]; then + echo "MK: No readable file at ${INFILE}" + exit 1 +fi + +if [ ! -r ${CFILE} ]; then + echo "MK: Can't find ${CFILE}" + exit 1 +fi + +if [ -z ${OUTFILE} ]; then + echo "MK: Missing output file name" + exit 1 +fi + +echo "#include " > ${TMPFILE1} +echo "typedef uint8_t guint8;" >> ${TMPFILE1} +echo "typedef uint16_t guint;" >> ${TMPFILE1} + +cat ${TMPFILE1} ${INFILE} ${CFILE} > ${TMPFILE2} + +gcc -g -o ${TMPPROG} ${TMPFILE2} +./${TMPPROG} > ${OUTFILE} + +rm ${TMPFILE1} ${TMPFILE2} diff --git a/graphics/nxwidgets/UnitTests/CListBox/clistbox_main.cxx b/graphics/nxwidgets/UnitTests/CListBox/clistbox_main.cxx index d652c18a2..db42c4505 100644 --- a/graphics/nxwidgets/UnitTests/CListBox/clistbox_main.cxx +++ b/graphics/nxwidgets/UnitTests/CListBox/clistbox_main.cxx @@ -171,7 +171,7 @@ static void initMemoryUsage(void) ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// -// Name: nxheaders_main +// Name: clistbox_main ///////////////////////////////////////////////////////////////////////////// int clistbox_main(int argc, char *argv[]) @@ -195,6 +195,7 @@ int clistbox_main(int argc, char *argv[]) delete test; return 1; } + updateMemoryUsage(g_mmPrevious, "clistbox_main: After connecting to the server"); // Create a window to draw into @@ -206,6 +207,7 @@ int clistbox_main(int argc, char *argv[]) delete test; return 1; } + updateMemoryUsage(g_mmPrevious, "clistbox_main: After creating a window"); // Create a listbox @@ -218,6 +220,7 @@ int clistbox_main(int argc, char *argv[]) delete test; return 1; } + updateMemoryUsage(g_mmPrevious, "clistbox_main: After creating a listbox"); // Show the initial state of the listbox @@ -236,6 +239,7 @@ int clistbox_main(int argc, char *argv[]) printf("clistbox_main: %d. New option %s\n", i, g_options[i]); usleep(500000); // The simulation needs this to let the X11 event loop run } + updateMemoryUsage(g_mmPrevious, "clistbox_main: After adding the listbox items"); sleep(1); @@ -310,6 +314,7 @@ int clistbox_main(int argc, char *argv[]) } sleep(1); } + updateMemoryUsage(g_mmPrevious, "clistbox_main: After the listbox is empty again"); sleep(1); diff --git a/graphics/twm4nx/.gitignore b/graphics/twm4nx/.gitignore new file mode 100644 index 000000000..6d84d42c4 --- /dev/null +++ b/graphics/twm4nx/.gitignore @@ -0,0 +1,12 @@ +/twm4nx +/Make.dep +/.depend +/.built +/*.asm +/*.obj +/*.rel +/*.lst +/*.sym +/*.adb +/*.lib +/*.src diff --git a/graphics/twm4nx/COPYING b/graphics/twm4nx/COPYING new file mode 100644 index 000000000..8cc6cb9a5 --- /dev/null +++ b/graphics/twm4nx/COPYING @@ -0,0 +1,82 @@ +The following is the full text of the COPYING file for TWM 1.0.10. Twm4Nx +is largely an original development, but owes acknowledge to TWM for its +design base and thanks fot TWM for many years in the open source community. + +This copyright notice is probably not necessary since Twm4Nx is not TWM, +but this assures that things are right. See the top-level README.txt file +for additional information. + +============================================================================ + +Copyright 1989, 1994, 1998 The Open Group +Copyright 2005 Hitachi, Ltd. + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + + Copyright 1988 by Evans & Sutherland Computer Corporation, + Salt Lake City, Utah + Cambridge, Massachusetts + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that copyright notice and this permis- +sion notice appear in supporting documentation, and that the +name of Evans & Sutherland not be used in advertising +in publicity pertaining to distribution of the software without +specific, written prior permission. + +EVANS & SUTHERLAND DISCLAIMs ALL WARRANTIES WITH REGARD +TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- +ABILITY AND FITNESS, IN NO EVENT SHALL EVANS & SUTHERLAND +BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAM- +AGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA +OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE +OR PERFORMANCE OF THIS SOFTWARE. + +Copyright (C) 1998 The XFree86 Project, Inc. All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to +deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the XFree86 Project shall +not be used in advertising or otherwise to promote the sale, use or other +dealings in this Software without prior written authorization from the +XFree86 Project. + diff --git a/graphics/twm4nx/Kconfig b/graphics/twm4nx/Kconfig new file mode 100644 index 000000000..34a915f60 --- /dev/null +++ b/graphics/twm4nx/Kconfig @@ -0,0 +1,44 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +config GRAPHICS_TWM4NX + tristate "Minimal Tom's Window Manager (TWM) for NuttX (Twm4Nx)" + default n + select NX_RAMBACKED + select NXWIDGETS + depends on NX && EXPERIMENTAL + ---help--- + Enable Tom's Window Manager (TWM) for NuttX (Twm4Nx). + + Use of this window manager requires keyboard and mouse input. + Output is through the NX server. + +if GRAPHICS_TWM4NX + +config TWM4NX_PROGNAME + string "Twm4Nx program name" + default "twm4nx" + depends on BUILD_LOADABLE + ---help--- + This is the name of the program that will be use when the NSH ELF + program is installed. + +config TWM4NX_PRIORITY + int "Twm4Nx task priority" + default 100 + +config TWM4NX_STACKSIZE + int "Twm4Nx stack size" + default 2048 + +config TWM4NX_REVMAJOR + string "Twm4Nx major version number" + default "0" + +config TWM4NX_REVMINOR + string "Twm4Nx minor version number" + default "0" + +endif # GRAPHICS_TWM4NX diff --git a/graphics/twm4nx/Make.defs b/graphics/twm4nx/Make.defs new file mode 100644 index 000000000..308106ccc --- /dev/null +++ b/graphics/twm4nx/Make.defs @@ -0,0 +1,40 @@ +############################################################################ +# apps/graphics/twm4nx/Make.defs +# Adds selected applications to apps/ build +# +# 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. +# +############################################################################ + +ifeq ($(CONFIG_GRAPHICS_TWM4NX),y) +CONFIGURED_APPS += graphics/twm4nx +endif + diff --git a/graphics/twm4nx/Makefile b/graphics/twm4nx/Makefile new file mode 100644 index 000000000..ede5562f8 --- /dev/null +++ b/graphics/twm4nx/Makefile @@ -0,0 +1,69 @@ +############################################################################ +# apps/graphics/twm4nx/Makefile +# +# 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. +# +############################################################################ + +-include $(TOPDIR)/Make.defs +-include $(APPDIR)/Make.defs + +# Add patch to cursor images to CXXFLAGS + +CXXFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" "$(APPDIR)/graphics/nxglyphs/include"} + +# Twm4Nx built-in application info + +CONFIG_TWM4NX_PRIORITY ?= SCHED_PRIORITY_DEFAULT +CONFIG_TWM4NX_STACKSIZE ?= 2048 + +APPNAME = twm4nx + +PRIORITY = $(CONFIG_TWM4NX_PRIORITY) +STACKSIZE = $(CONFIG_TWM4NX_STACKSIZE) + +# Twm4Nx + +ASRCS = +CSRCS = +CXXSRCS = cwindow.cxx cwindowfactory.cxx ciconwin.cxx cwindowevent.cxx +CXXSRCS += cicon.cxx ciconmgr.cxx cbackground.cxx cfonts.cxx cresize.cxx +CXXSRCS += cmenus.cxx cinput.cxx twm4nx_cursor.cxx +MAINSRC = ctwm4nx.cxx + +VPATH = src + +CONFIG_TWM4NX_PROGNAME ?= hello$(EXEEXT) +PROGNAME = $(CONFIG_TWM4NX_PROGNAME) + +MODULE = CONFIG_GRAPHICS_TWM4NX + +include $(APPDIR)/Application.mk diff --git a/graphics/twm4nx/README.txt b/graphics/twm4nx/README.txt new file mode 100644 index 000000000..0e51ee247 --- /dev/null +++ b/graphics/twm4nx/README.txt @@ -0,0 +1,28 @@ +README +====== + +Twm4Nx is a port of twm, Tab Window Manager (or Tom's Window Manager) +version 1.0.10 to NuttX NX windows server. No, a port is not the right +word. It is a re-design of TWM from the inside out to work with the NuttX +NX server. The name Twm4Nx reflects this legacy. But Twm4Nx is more a +homage to TWM than a port of TWM. + +The original TWM was based on X11 which provides a rich set of features. +TWM provided titlebars, shaped windows, several forms of icon management, +user-defined macro functions, click-to-type and pointer-driven keyboard +focus, graphic contexts, and user-specified key and pointer button bindings, +etc. + +Twm4Nx, on the other hand is based on the NuttX NX server which provides +comparatively minimal support. Additional drawing support comes from +the NuttX NxWidgets library (which necessitated the change to C++). + +Twm4Nx is greatly stripped down and targeted on small embedded systems +with minimal resources. For example, no assumption is made about the +availability of a file system; no .twmrc file is used. Bitmaps are not +used (other than for fonts). + +The TWM license is, I believe compatible with the BSD license used by NuttX. +The origin TWM license required notice of copyrights within each file and +a full copy of the original license which you can find in the COPYING file. +within this directory. diff --git a/graphics/twm4nx/Twm4NX-Threading.pdf b/graphics/twm4nx/Twm4NX-Threading.pdf new file mode 100644 index 000000000..9e857384c Binary files /dev/null and b/graphics/twm4nx/Twm4NX-Threading.pdf differ diff --git a/graphics/twm4nx/src/cbackground.cxx b/graphics/twm4nx/src/cbackground.cxx new file mode 100644 index 000000000..e4f4f56fe --- /dev/null +++ b/graphics/twm4nx/src/cbackground.cxx @@ -0,0 +1,310 @@ +///////////////////////////////////////////////////////////////////////////// +// apps/graphics/twm4nx/include/cbackground.hxx +// Manage background image +// +// 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 "graphics/nxwidgets/cscaledbitmap.hxx" +#include "graphics/nxwidgets/cbgwindow.hxx" +#include "graphics/nxwidgets/cwidgetcontrol.hxx" +#include "graphics/nxwidgets/crlepalettebitmap.hxx" +#include "graphics/nxwidgets/cimage.hxx" + +#include "graphics/twm4nx/twm4nx_config.hxx" +#include "graphics/twm4nx/cwindowevent.hxx" +#include "graphics/twm4nx/cbackground.hxx" + +///////////////////////////////////////////////////////////////////////////// +// CBackground Method Implementations +///////////////////////////////////////////////////////////////////////////// + +using namespace Twm4Nx; + +/** + * CBackground Constructor + * + * @param hWnd - NX server handle + */ + +CBackground::CBackground(FAR CTwm4Nx *twm4nx) +{ + m_twm4nx = twm4nx; + m_backWindow = (NXWidgets::CBgWindow *)0; + m_backImage = (NXWidgets::CImage *)0; +} + +/** + * CBackground Destructor + */ + +CBackground::~CBackground(void) +{ + // Delete the background + + if (m_backWindow != (NXWidgets::CBgWindow *)0) + { + // Delete the contained widget control. We are responsible for it + // because we created it + + NXWidgets::CWidgetControl *control = m_backWindow->getWidgetControl(); + if (control != (NXWidgets::CWidgetControl *)0) + { + delete control; + } + + // Then delete the background + + delete m_backWindow; + m_backWindow = (NXWidgets::CBgWindow *)0; + } + + // Delete the background image + + if (m_backImage != (NXWidgets::CImage *)0) + { + delete m_backImage; + m_backImage = (NXWidgets::CImage *)0; + } +} + +/** + * Set the background image + * + * @param sbitmap. Identifies the bitmap to paint on background + * @return true on success + */ + +bool CBackground:: + setBackgroundImage(FAR const struct NXWidgets::SRlePaletteBitmap *sbitmap) +{ + // Create the background window (if we have not already done so) + + if (m_backWindow == (NXWidgets::CBgWindow *)0 && + !createBackgroundWindow()) + { + return false; + } + + // Free any existing background image + + if (m_backImage != (NXWidgets::CImage *)0) + { + delete m_backImage; + m_backImage = (NXWidgets::CImage *)0; + } + + // Create the new background image + + if (!createBackgroundImage(sbitmap)) + { + return false; + } + + return true; +} + +/** + * Get the size of the physical display device which is equivalent to + * size of the background window. + * + * @return The size of the display + */ + +void CBackground::getDisplaySize(FAR struct nxgl_size_s &size) +{ + // Get the widget control from the task bar window. The physical window geometry + // should be the same for all windows. + + NXWidgets::CWidgetControl *control = m_backWindow->getWidgetControl(); + + // Get the window bounding box from the widget control + + NXWidgets::CRect rect = control->getWindowBoundingBox(); + + // And return the size of the window + + rect.getSize(size); +} + +/** + * Create the background window. + * + * @return true on success + */ + +bool CBackground::createBackgroundWindow(void) +{ + // Create an instance of the background window + // 1. Get the server instance. m_twm4nx inherits from NXWidgets::CNXServer + // so we all ready have the server instance. + // 2. Create the style, using the selected colors (REVISIT) + + // 3. Create a Widget control instance for the window using the default + // style for now. CWindowEvent derives from CWidgetControl. + + FAR CWindowEvent *control = new CWindowEvent(m_twm4nx); + + m_backWindow = m_twm4nx->getBgWindow(control); + if (m_backWindow == (FAR NXWidgets::CBgWindow *)0) + { + return false; + } + + return true; +} + +/** + * Create the background image. + * + * @return true on success + */ + +bool CBackground:: + createBackgroundImage(FAR const struct NXWidgets::SRlePaletteBitmap *sbitmap) +{ + // Get the size of the display + + struct nxgl_size_s windowSize; + if (!m_backWindow->getSize(&windowSize)) + { + return false; + } + + // Get the widget control from the background window + + NXWidgets::CWidgetControl *control = m_backWindow->getWidgetControl(); + + // Create the sbitmap object + + NXWidgets::CRlePaletteBitmap *cbitmap = + new NXWidgets::CRlePaletteBitmap(sbitmap); + + if (cbitmap == (NXWidgets::CRlePaletteBitmap *)0) + { + return false; + } + + // Get the size of the bitmap image + + struct nxgl_size_s imageSize; + imageSize.w = cbitmap->getWidth(); + imageSize.h = (nxgl_coord_t)cbitmap->getHeight(); + + // Pick an X/Y position such that the image will be centered in the display + + struct nxgl_point_s imagePos; + if (imageSize.w >= windowSize.w) + { + imagePos.x = 0; + } + else + { + imagePos.x = (windowSize.w - imageSize.w) >> 1; + } + + if (imageSize.h >= windowSize.h) + { + imagePos.y = 0; + } + else + { + imagePos.y = (windowSize.h - imageSize.h) >> 1; + } + + // Now we have enough information to create the image + + m_backImage = new NXWidgets::CImage(control, imagePos.x, imagePos.y, + imageSize.w, imageSize.h, cbitmap); + if (!m_backImage) + { + delete cbitmap; + return false; + } + + // Configure the background image + + m_backImage->setBorderless(true); + m_backImage->setRaisesEvents(false); + + return true; +} + +/** + * (Re-)draw the background window. + * + * @return true on success + */ + +bool CBackground::redrawBackgroundWindow(void) +{ + // Get the widget control from the background window + + NXWidgets::CWidgetControl *control = m_backWindow->getWidgetControl(); + + // Get the graphics port for drawing on the background window + + NXWidgets::CGraphicsPort *port = control->getGraphicsPort(); + + // Get the size of the window + + struct nxgl_size_s windowSize; + if (!m_backWindow->getSize(&windowSize)) + { + return false; + } + + // Fill the entire window with the background color + + port->drawFilledRect(0, 0, windowSize.w, windowSize.h, + CONFIG_TWM4NX_DEFAULT_BACKGROUNDCOLOR); + + // Then re-draw the background image on the window + + if (m_backImage) + { + m_backImage->enableDrawing(); + m_backImage->redraw(); + } + + return true; +} diff --git a/graphics/twm4nx/src/cfonts.cxx b/graphics/twm4nx/src/cfonts.cxx new file mode 100644 index 000000000..ada145b6f --- /dev/null +++ b/graphics/twm4nx/src/cfonts.cxx @@ -0,0 +1,177 @@ +///////////////////////////////////////////////////////////////////////////// +// apps/graphics/twm4nx/src/cfonts.cxx +// Font support for twm4nx +// +// Copyright (C) 2019 Gregory Nutt. All rights reserved. +// Author: Gregory Nutt +// +// Largely an original work but derives from TWM 1.0.10 in many ways: +// +// Copyright 1989,1998 The Open Group +// Copyright 1988 by Evans & Sutherland Computer Corporation, +// +// Please refer to apps/twm4nx/COPYING for detailed copyright information. +// +// 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 "graphics/nxwidgets/cnxfont.hxx" + +#include "graphics/twm4nx/twm4nx_config.hxx" +#include "graphics/twm4nx/ctwm4nx.hxx" +#include "graphics/twm4nx/cfonts.hxx" + +///////////////////////////////////////////////////////////////////////////// +// CFonts Method Implementations +///////////////////////////////////////////////////////////////////////////// + +using namespace Twm4Nx; + +/** + * CFonts Constructor + * + * @param twm4nx. An instance of the NX server. + */ + +CFonts::CFonts(CTwm4Nx *twm4nx) +{ + m_twm4nx = twm4nx; // Save the NX server + m_titleFont = (FAR NXWidgets::CNxFont *)0; // Title bar font + m_menuFont = (FAR NXWidgets::CNxFont *)0; // Menu font + m_iconFont = (FAR NXWidgets::CNxFont *)0; // Icon font + m_sizeFont = (FAR NXWidgets::CNxFont *)0; // Resize font + m_iconManagerFont = (FAR NXWidgets::CNxFont *)0; // Window list font + m_defaultFont = (FAR NXWidgets::CNxFont *)0; // The default found +} + +/** + * CFonts Destructor + */ + +CFonts::~CFonts(void) +{ + if (m_titleFont != (FAR NXWidgets::CNxFont *)0) + { + delete m_titleFont; + } + + if (m_menuFont != (FAR NXWidgets::CNxFont *)0) + { + delete m_menuFont; + } + + if (m_iconFont != (FAR NXWidgets::CNxFont *)0) + { + delete m_iconFont; + } + + if (m_sizeFont != (FAR NXWidgets::CNxFont *)0) + { + delete m_sizeFont; + } + + if (m_iconManagerFont != (FAR NXWidgets::CNxFont *)0) + { + delete m_iconManagerFont; + } + + if (m_defaultFont != (FAR NXWidgets::CNxFont *)0) + { + delete m_defaultFont; + } +} + +/** + * Initialize fonts + */ + +bool CFonts::initialize(void) +{ + m_titleFont = + new NXWidgets::CNxFont((enum nx_fontid_e)CONFIG_TWM4NX_TITLE_FONTID, + CONFIG_TWM4NX_TITLE_FONTCOLOR, + CONFIG_TWM4NX_TRANSPARENT_COLOR); + if (m_titleFont == (FAR NXWidgets::CNxFont *)0) + { + return false; + } + + m_menuFont = + new NXWidgets::CNxFont((enum nx_fontid_e)CONFIG_TWM4NX_MENU_FONTID, + CONFIG_TWM4NX_MENU_FONTCOLOR, + CONFIG_TWM4NX_TRANSPARENT_COLOR); + if (m_menuFont == (FAR NXWidgets::CNxFont *)0) + { + return false; + } + + m_iconFont = + new NXWidgets::CNxFont((enum nx_fontid_e)CONFIG_TWM4NX_ICON_FONTID, + CONFIG_TWM4NX_ICON_FONTCOLOR, + CONFIG_TWM4NX_TRANSPARENT_COLOR); + if (m_iconFont == (FAR NXWidgets::CNxFont *)0) + { + return false; + } + + m_sizeFont = + new NXWidgets::CNxFont((enum nx_fontid_e)CONFIG_TWM4NX_SIZE_FONTID, + CONFIG_TWM4NX_SIZE_FONTCOLOR, + CONFIG_TWM4NX_TRANSPARENT_COLOR); + if (m_sizeFont == (FAR NXWidgets::CNxFont *)0) + { + return false; + } + + m_iconManagerFont = + new NXWidgets::CNxFont((enum nx_fontid_e)CONFIG_TWM4NX_ICONMGR_SIZEFONTID, + CONFIG_TWM4NX_ICONMGR_FONTCOLOR, + CONFIG_TWM4NX_TRANSPARENT_COLOR); + if (m_iconManagerFont == (FAR NXWidgets::CNxFont *)0) + { + return false; + } + + m_defaultFont = + new NXWidgets::CNxFont((enum nx_fontid_e)NXFONT_DEFAULT, + CONFIG_TWM4NX_DEFAULT_FONTCOLOR, + CONFIG_TWM4NX_TRANSPARENT_COLOR); + if (m_defaultFont == (FAR NXWidgets::CNxFont *)0) + { + return false; + } + + return true; +} diff --git a/graphics/twm4nx/src/cicon.cxx b/graphics/twm4nx/src/cicon.cxx new file mode 100644 index 000000000..c96d4b780 --- /dev/null +++ b/graphics/twm4nx/src/cicon.cxx @@ -0,0 +1,469 @@ +///////////////////////////////////////////////////////////////////////////// +// apps/graphics/twm4nx/src/cicon.cxx +// Icon releated routines +// +// Copyright (C) 2019 Gregory Nutt. All rights reserved. +// Author: Gregory Nutt +// +// Largely an original work but derives from TWM 1.0.10 in many ways: +// +// Copyright 1989,1998 The Open Group +// +// Please refer to apps/twm4nx/COPYING for detailed copyright information. +// +// 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 "nuttx/nx/nxglib.h" + +#include "graphics/twm4nx/ctwm4nx.hxx" +#include "graphics/twm4nx/cwindow.hxx" +#include "graphics/twm4nx/cwindowevent.hxx" +#include "graphics/twm4nx/cicon.hxx" + +///////////////////////////////////////////////////////////////////////////// +// CTwm4Nx Implementation +///////////////////////////////////////////////////////////////////////////// + +using namespace Twm4Nx; + +/** + * CIcon Constructor + */ + +CIcon::CIcon(CTwm4Nx *twm4nx) +{ + m_twm4nx = twm4nx; // Cached the Twm4Nx session + m_icons = (FAR struct SNameList *)0; // List of icon images + m_regionHead = (FAR struct SIconRegion *)0; // Pointer to icon regions + m_regionTail = (FAR struct SIconRegion *)0; // Pointer to the last icon region +} + +/** + * CIcon Destructor + */ + +CIcon::~CIcon(void) +{ + freeIconRegions(); +} + +/** + * Create a new icon region and add it to the list of icon regions. + * + * @param pos The position of the region on the background + * @param size The size of the region + * @param step + */ + +void CIcon::addIconRegion(FAR nxgl_point_s *pos, FAR nxgl_size_s *size, + FAR struct nxgl_point_s *step) +{ + FAR struct SIconRegion *ir; + + // Allocate the new region + + ir = (FAR struct SIconRegion *)std::malloc(sizeof(struct SIconRegion)); + + // Add the new region to the list of regions + + ir->flink = (FAR struct SIconRegion *)0; + + if (m_regionTail != (FAR struct SIconRegion *)0) + { + m_regionTail->flink = ir; + } + + m_regionTail = ir; + + if (m_regionHead != (FAR struct SIconRegion *)0) + { + m_regionHead = ir; + } + + // Initiliaze the region + + ir->entries = NULL; + + if (step->x <= 0) + { + step->x = 1; + } + + if (step->y <= 0) + { + step->y = 1; + } + + ir->step.x = step->x; + ir->step.y = step->y; + ir->pos.x = pos->x; + ir->pos.y = pos->y; + ir->size.w = size->w; + ir->size.h = size->h; + + struct nxgl_size_s displaySize; + m_twm4nx->getDisplaySize(&displaySize); + + if (ir->pos.x < 0) + { + ir->pos.x += displaySize.w - ir->size.w; + } + + if (ir->pos.y < 0) + { + ir->pos.y += displaySize.h - ir->size.h; + } + + // Allocate one region entry + + ir->entries = (FAR struct SIconEntry *)malloc(sizeof(struct SIconRegion)); + if (ir->entries != (FAR struct SIconEntry *)0) + { + ir->entries->flink = (FAR struct SIconEntry *)0; + ir->entries->pos.x = ir->pos.x; + ir->entries->pos.y = ir->pos.y; + ir->entries->size.w = ir->size.w; + ir->entries->size.h = ir->size.h; + ir->entries->cwin = (FAR CWindow *)0; + ir->entries->used = false; + } +} + +/** + * Position an icon on the background + * + * @param cwin The Window whose icon will be placed + * @param pos An backup position to use is there are no available regions + * @param final A location in which to return the selection icon position + */ + +void CIcon::place(FAR CWindow *cwin, FAR const struct nxgl_point_s *pos, + FAR struct nxgl_point_s *final) +{ + // Try each region + + FAR struct SIconEntry *ie = (FAR struct SIconEntry *)0; + for (FAR struct SIconRegion *ir = m_regionHead; ir; ir = ir->flink) + { + struct nxgl_size_s iconWindowSize; + cwin->getIconWindowSize(&iconWindowSize); + + struct nxgl_size_s tmpsize; + tmpsize.w = roundUp(iconWindowSize.w, ir->step.x); + tmpsize.h = roundUp(iconWindowSize.h, ir->step.y); + + // Try each entry in the regions + + for (ie = ir->entries; ie; ie = ie->flink) + { + // Look for an unused entry + + if (ie->used) + { + continue; + } + + // Does the entry describe a region that is of sufficient size? + + if (ie->size.w >= tmpsize.w && ie->size.h >= tmpsize.h) + { + // Yes.. We have it. Break out with ie non-NULL + + break; + } + } + + // Break out of the outer loop if the the region entry was found by + // the inner loop + + if (ie != (FAR struct SIconEntry *)0) + { + break; + } + } + + // Did we find an entry? + + if (ie != (FAR struct SIconEntry *)0) + { + // Yes.. place the icon in this region + + ie->used = true; + ie->cwin = cwin; + + struct nxgl_size_s iconWindowSize; + cwin->getIconWindowSize(&iconWindowSize); + + final->x = ie->pos.x + (ie->size.w - iconWindowSize.w) / 2; + final->y = ie->pos.y + (ie->size.h - iconWindowSize.h) / 2; + } + else + { + // No.. place it.. wherever + + final->x = pos->x; + final->y = pos->y; + } +} + +/** + * Bring the window up. + * + * @param cwin The window to be brought up. + */ + +void CIcon::up(FAR CWindow *cwin) +{ + struct nxgl_point_s newpos; + struct nxgl_point_s oldpos; + + // Did the user move the icon? + + if (cwin->hasIconMoved()) + { + struct nxgl_size_s oldsize; + if (!cwin->getIconWindowSize(&oldsize)) + { + return; + } + + if (!cwin->getIconWindowPosition(&oldpos)) + { + return; + } + + newpos.x = oldpos.x + ((int)oldsize.w) / 2; + newpos.y = oldpos.y + ((int)oldsize.h) / 2; + + FAR struct SIconRegion *ir; + for (ir = m_regionHead; ir; ir = ir->flink) + { + if (newpos.x >= ir->pos.x && + newpos.x < (ir->pos.x + ir->size.w) && + newpos.y >= ir->pos.y && + newpos.y < (ir->pos.y + ir->size.h)) + { + break; + } + } + + if (ir == NULL) + { + return; // outside icon regions, leave alone + } + } + + oldpos.x = -100; + oldpos.y = -100; + + place(cwin, &oldpos, &newpos); + + if (newpos.x != oldpos.x || newpos.y != oldpos.y) + { + (void)cwin->getIconWindowPosition(&newpos); + cwin->setIconMoved(false); // since we've restored it + } +} + +/** + * Take the window down. + * + * @param vwin The window to be taken down. + */ + +void CIcon::down(FAR CWindow *cwin) +{ + FAR struct SIconRegion *ir; + FAR struct SIconEntry *ie; + + ie = findEntry(cwin, &ir); + if (ie != (FAR struct SIconEntry *)0) + { + ie->cwin = 0; + ie->used = false; + + FAR struct SIconEntry *ip = prevEntry(ie, ir); + FAR struct SIconEntry *in = ie->flink; + + for (; ; ) + { + if (ip && ip->used == false && + ((ip->pos.x == ie->pos.x && ip->size.w == ie->size.w) || + (ip->pos.y == ie->pos.y && ip->size.h == ie->size.h))) + { + ip->flink = ie->flink; + mergeEntries(ie, ip); + free(ie); + ie = ip; + ip = prevEntry(ip, ir); + } + else if (in && in->used == false && + ((in->pos.x == ie->pos.x && in->size.w == ie->size.w) || + (in->pos.y == ie->pos.y && in->size.h == ie->size.h))) + { + ie->flink = in->flink; + mergeEntries(in, ie); + free(in); + in = ie->flink; + } + else + { + break; + } + } + } +} + +/** + * Find the icon region holding the window 'cwin' + * + * @param cwin The window whose icon region is sought + * @param irp A location in which to provide the region + */ + +FAR struct SIconEntry *CIcon::findEntry(FAR CWindow *cwin, + FAR struct SIconRegion **irp) +{ + FAR struct SIconRegion *ir; + FAR struct SIconEntry *ie; + + for (ir = m_regionHead; ir; ir = ir->flink) + { + for (ie = ir->entries; ie; ie = ie->flink) + if (ie->cwin == cwin) + { + if (irp) + { + *irp = ir; + } + + return ie; + } + } + + return (FAR struct SIconEntry *)0; +} + +/** + * Given entry 'ie' in the list 'ir', return the entry just prior to 'ie' + * + * @param ie The entry whose predecessor is sought + * @param ir The region containing the entry + * @return The entry just before 'ie' in the list + */ + +FAR struct SIconEntry *CIcon::prevEntry(FAR struct SIconEntry *ie, + FAR struct SIconRegion *ir) +{ + FAR struct SIconEntry *ip; + + if (ie == ir->entries) + { + return (FAR struct SIconEntry *)0; + } + + for (ip = ir->entries; ip->flink != ie; ip = ip->flink) + { + } + + return ip; +} + +/** + * 'old' is being freed; and is adjacent to ie. Merge + * regions together + */ + +void CIcon::mergeEntries(FAR struct SIconEntry *old, + FAR struct SIconEntry *ie) +{ + if (old->pos.y == ie->pos.y) + { + ie->size.w = old->size.w + ie->size.w; + if (old->pos.x < ie->pos.x) + { + ie->pos.x = old->pos.x; + } + } + else + { + ie->size.h = old->size.h + ie->size.h; + if (old->pos.y < ie->pos.y) + { + ie->pos.y = old->pos.y; + } + } +} + +/** + * Free all of the icon entries linked to a region + * + * @param ir The region whose entries will be freed + */ + +void CIcon::freeIconEntries(FAR struct SIconRegion *ir) +{ + FAR struct SIconEntry *ie; + FAR struct SIconEntry *tmp; + + for (ie = ir->entries; ie; ie = tmp) + { + tmp = ie->flink; + std::free(ie); + } +} + +/** + * Free all icon regions and all of the region entries linked into the + * region + */ + +void CIcon::freeIconRegions(void) +{ + struct SIconRegion *ir; + struct SIconRegion *tmp; + + for (ir = m_regionHead; ir != NULL;) + { + tmp = ir; + freeIconEntries(ir); + ir = ir->flink; + free(tmp); + } + + m_regionHead = NULL; + m_regionTail = NULL; +} diff --git a/graphics/twm4nx/src/ciconmgr.cxx b/graphics/twm4nx/src/ciconmgr.cxx new file mode 100644 index 000000000..507d1329b --- /dev/null +++ b/graphics/twm4nx/src/ciconmgr.cxx @@ -0,0 +1,757 @@ +///////////////////////////////////////////////////////////////////////////// +// apps/graphics/twm4nx/src/ciconmgr.cxx +// Icon Manager routines +// +// Copyright (C) 2019 Gregory Nutt. All rights reserved. +// Author: Gregory Nutt +// +// Largely an original work but derives from TWM 1.0.10 in many ways: +// +// Copyright 1989,1998 The Open Group +// +// Please refer to apps/twm4nx/COPYING for detailed copyright information. +// +// 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 "graphics/nxwidgets/cnxwindow.hxx" +#include "graphics/nxwidgets/cnxfont.hxx" + +#include +#include + +#include "graphics/nxglyphs.hxx" + +#include "graphics/twm4nx/twm4nx_config.hxx" +#include "graphics/twm4nx/ctwm4nx.hxx" +#include "graphics/twm4nx/cfonts.hxx" +#include "graphics/twm4nx/cresize.hxx" +#include "graphics/twm4nx/cmenus.hxx" +#include "graphics/twm4nx/cwindow.hxx" +#include "graphics/twm4nx/cwindowevent.hxx" +#include "graphics/twm4nx/cwindowfactory.hxx" +#include "graphics/twm4nx/ciconmgr.hxx" + +///////////////////////////////////////////////////////////////////////////// +// Class Implementations +///////////////////////////////////////////////////////////////////////////// + +using namespace Twm4Nx; + +/** + * CIconMgr Constructor + * + * @param twm4nx The Twm4Nx session + * @param ncolumns The number of columns this icon manager has + */ + +CIconMgr::CIconMgr(CTwm4Nx *twm4nx, int ncolumns) +{ + m_twm4nx = twm4nx; // Cached the Twm4Nx session + m_head = (FAR struct SWindowEntry *)0; // Head of the winow list + m_tail = (FAR struct SWindowEntry *)0; // Tail of the winow list + m_active = (FAR struct SWindowEntry *)0; // No active window + m_window = (FAR CWindow *)0; // No icon manager Window + m_columns = ncolumns; + m_currows = 0; + m_curcolumns = 0; + m_count = 0; +} + +/** + * CIconMgr Destructor + */ + +CIconMgr::~CIconMgr(void) +{ + // Free memory allocations + + // Free the icon manager window + + if (m_window != (FAR CWindow *)0) + { + delete m_window; + } +} + +/** + * Create and initialize the icon manager window + * + * @param name The prefix for this icon manager name + */ + +bool CIconMgr::initialize(FAR const char *prefix) +{ + // Create the icon manager window + + if (!createWindow(prefix)) + { + gerr("ERROR: Failed to create window\n"); + return false; + } + + // Create the button array widget + + if (!createButtonArray()) + { + gerr("ERROR: Failed to button array\n"); + + CWindowFactory *factory = m_twm4nx->getWindowFactory(); + factory->destroyWindow(m_window); + m_window = (FAR CWindow *)0; + return false; + } + + return true; +} + +/** + * Add a window to an icon manager + * + * @param win the TWM window structure + */ + +bool CIconMgr::add(FAR CWindow *cwin) +{ + // Don't add the icon manager to itself + + if (cwin->isIconMgr()) + { + return false; + } + + // Allocate a new icon manager entry + + FAR struct SWindowEntry *wentry = + (FAR struct SWindowEntry *)malloc(sizeof(struct SWindowEntry)); + + if (wentry == (FAR struct SWindowEntry *)0) + { + return false; + } + + wentry->flink = NULL; + wentry->iconmgr = this; + wentry->active = false; + wentry->down = false; + wentry->cwin = cwin; + + FAR CFonts *fonts = m_twm4nx->getFonts(); + FAR NXWidgets::CNxFont *iconManagerFont = fonts->getIconManagerFont(); + + wentry->me = m_count; + wentry->pos.x = -1; + wentry->pos.y = -1; + + // Insert the new entry into the list + + insertEntry(wentry, cwin); + + // The height of one row is determined (mostly) by the fond height + + int rowHeight = iconManagerFont->getHeight() + 10; + if (rowHeight < (CONFIG_TWM4NX_ICONMGR_IMAGE.width + 4)) + { + rowHeight = CONFIG_TWM4NX_ICONMGR_IMAGE.width + 4; + } + + // Increase the icon window size + + struct nxgl_size_s windowSize; + if (!m_window->getWindowSize(&windowSize)) + { + gerr("ERROR: Failed to get window size\n"); + } + else + { + windowSize.h = rowHeight * m_count; + m_window->setWindowSize(&windowSize); + } + + // Increment the window count + + m_count++; + + // Pack the windows + + pack(); + + // If no other window is active, then mark this as the active window + + if (m_active == NULL) + { + m_active = wentry; + } + + return true; +} + +/** + * Remove a window from the icon manager + * + * @param win the TWM window structure + */ + +void CIconMgr::remove(FAR struct SWindow *win) +{ + FAR struct SWindowEntry *wentry = win->wentry; + + if (wentry != NULL) + { + // Remove the list from the window structure + + removeEntry(wentry); + + // Destroy the button array widget +#warning Missing logic + + // Destroy the window + + CWindowFactory *factory = m_twm4nx->getWindowFactory(); + factory->destroyWindow(wentry->cwin); + + m_count -= 1; + std::free(wentry); + pack(); + } +} + +/** + * Move the pointer around in an icon manager + * + * @param dir one of the following: + * - EVENT_ICONMGR_FORWARD: Forward in the window list + * - EVENT_ICONMGR_BACK: Backward in the window list + * - EVENT_ICONMGR_UP: Up one row + * - EVENT_ICONMGR_DOWN: Down one row + * - EVENT_ICONMGR_LEFT: Left one column + * - EVENT_ICONMGR_RIGHT: Right one column + */ + +void CIconMgr::move(int dir) +{ + if (!m_active) + { + return; + } + + int curRow = m_active->row; + int curCol = m_active->col; + + int rowIncr = 0; + int colIncr = 0; + bool gotIt = false; + + FAR struct SWindowEntry *wentry = (FAR struct SWindowEntry *)0; + + switch (dir) + { + case EVENT_ICONMGR_FORWARD: + if ((wentry = m_active->flink) == (FAR struct SWindowEntry *)0) + { + wentry = m_head; + } + + gotIt = true; + break; + + case EVENT_ICONMGR_BACK: + if ((wentry = m_active->blink) == (FAR struct SWindowEntry *)0) + { + wentry = m_tail; + } + + gotIt = true; + break; + + case EVENT_ICONMGR_UP: + rowIncr = -1; + break; + + case EVENT_ICONMGR_DOWN: + rowIncr = 1; + break; + + case EVENT_ICONMGR_LEFT: + colIncr = -1; + break; + + case EVENT_ICONMGR_RIGHT: + colIncr = 1; + break; + } + + // If gotIt is false ast this point then we got a left, right, up, or down, + // command. + + int newRow = curRow; + int newCol = curCol; + + while (!gotIt) + { + newRow += rowIncr; + newCol += colIncr; + + if (newRow < 0) + { + newRow = m_currows - 1; + } + + if (newCol < 0) + { + newCol = m_curcolumns - 1; + } + + if (newRow >= (int)m_currows) + { + newRow = 0; + } + + if (newCol >= (int)m_curcolumns) + { + newCol = 0; + } + + // Now let's go through the list to see if there is an entry with this + // new position. + + for (wentry = m_head; wentry != NULL; wentry = wentry->flink) + { + if (wentry->row == newRow && wentry->col == newCol) + { + gotIt = true; + break; + } + } + } + + if (!gotIt) + { + gwarn("WARNING: unable to find window (%d, %d) in icon manager\n", + newRow, newCol); + return; + } + + // raise the frame so the icon manager is visible +} + +/** + * Pack the icon manager windows following an addition or deletion + */ + +void CIconMgr::pack(void) +{ + FAR CFonts *fonts = m_twm4nx->getFonts(); + FAR NXWidgets::CNxFont *iconManagerFont = fonts->getIconManagerFont(); + + struct nxgl_size_s colsize; + + colsize.h = iconManagerFont->getHeight() + 10; + if (colsize.h < (CONFIG_TWM4NX_ICONMGR_IMAGE.height + 4)) + { + colsize.h = CONFIG_TWM4NX_ICONMGR_IMAGE.height + 4; + } + + struct nxgl_size_s windowSize; + if (!m_window->getWindowSize(&windowSize)) + { + gerr("ERROR: Failed to get window size\n"); + return; + } + + colsize.w = windowSize.w / m_columns; + + int rowIncr = colsize.h; + int colIncr = colsize.w; + + int row = 0; + int col = m_columns; + int maxcol = 0; + + FAR struct SWindowEntry *wentry; + int i; + + for (i = 0, wentry = m_head; + wentry != (FAR struct SWindowEntry *)0; + i++, wentry = wentry->flink) + { + wentry->me = i; + if (++col >= (int)m_columns) + { + col = 0; + row += 1; + } + + if (col > maxcol) + { + maxcol = col; + } + + struct nxgl_point_s newpos; + newpos.x = col * colIncr; + newpos.y = (row - 1) * rowIncr; + + wentry->row = row - 1; + wentry->col = col; + + // If the position or size has not changed, don't touch it + + if (wentry->pos.x != newpos.x || wentry->size.w != colsize.w) + { + if (!wentry->cwin->setWindowSize(&colsize)) + { + return; + } + + wentry->pos.x = newpos.x; + wentry->pos.y = newpos.y; + wentry->size.w = colsize.w; + wentry->size.h = colsize.h; + } + } + + maxcol += 1; + m_currows = row; + m_curcolumns = maxcol; + + // The height of one row is determined (mostly) by the fond height + + int rowHeight = iconManagerFont->getHeight() + 10; + if (rowHeight < (CONFIG_TWM4NX_ICONMGR_IMAGE.width + 4)) + { + rowHeight = CONFIG_TWM4NX_ICONMGR_IMAGE.width + 4; + } + + windowSize.h = rowHeight * m_count; + m_window->setWindowSize(&windowSize); + + if (windowSize.h == 0) + { + windowSize.h = rowIncr; + } + + struct nxgl_size_s newsize; + newsize.w = maxcol * colIncr; + + if (newsize.w == 0) + { + newsize.w = colIncr; + } + + newsize.h = windowSize.h; + + if (!m_window->setWindowSize(&newsize)) + { + return; + } + + // Get the net size of the containing frame + + struct nxgl_size_s frameSize; + m_window->windowToFrameSize(&windowSize, &frameSize); + + struct nxgl_point_s framePos; + m_window->getFramePosition(&framePos); + + // Resize the frame + + FAR CResize *resize = m_twm4nx->getResize(); + resize->setupWindow(m_window, &framePos, &frameSize); +} + +/** + * Sort the windows + */ + +void CIconMgr::sort(void) +{ + FAR struct SWindowEntry *tmpwin1; + FAR struct SWindowEntry *tmpwin2; + bool done; + + done = false; + do + { + for (tmpwin1 = m_head; tmpwin1 != NULL; tmpwin1 = tmpwin1->flink) + { + if ((tmpwin2 = tmpwin1->flink) == NULL) + { + done = true; + break; + } + + if (std::strcmp(tmpwin1->cwin->getWindowName(), + tmpwin2->cwin->getWindowName()) > 0) + { + // Take it out and put it back in + + removeEntry(tmpwin2); + insertEntry(tmpwin2, tmpwin2->cwin); + break; + } + } + } + while (!done); + + pack(); +} + +/** + * Handle ICONMGR events. + * + * @param msg. The received NxWidget ICONMGR event message. + * @return True if the message was properly handled. false is + * return on any failure. + */ + +bool CIconMgr::event(FAR struct SEventMsg *msg) +{ + bool ret = true; + + switch (msg->eventID) + { + case EVENT_ICONMGR_UP: + case EVENT_ICONMGR_DOWN: + case EVENT_ICONMGR_LEFT: + case EVENT_ICONMGR_RIGHT: + case EVENT_ICONMGR_FORWARD: + case EVENT_ICONMGR_BACK: + { + move(msg->eventID); + } + break; + + case EVENT_ICONMGR_SHOWPARENT: // Raise Icon manager parent window + { + m_window->deIconify(); + } + break; + + case EVENT_ICONMGR_HIDE: // Hide the Icon Manager + { + hide(); + } + break; + + case EVENT_ICONMGR_SORT: // Sort the Icon Manager + { + sort(); + } + break; + + default: + ret = false; + break; + } + + return ret; +} + +/** + * Create and initialize the icon manager window + * + * @param name The prefix for this icon manager name + */ + +bool CIconMgr::createWindow(FAR const char *prefix) +{ + static FAR const char *rootName = "Icon Manager"; + + // Create the icon manager name using any prefix provided by the creator + + FAR char *allocName = (FAR char *)0; + + if (prefix != (FAR const char *)0) + { + std::asprintf(&allocName, "%s %s", prefix, rootName); + } + + FAR const char *name = (allocName == (FAR char *)0) ? rootName : allocName; + + // Create the icon manager window + + CWindowFactory *factory = m_twm4nx->getWindowFactory(); + bool success = true; + + m_window = factory->createWindow(name, &CONFIG_TWM4NX_ICONMGR_IMAGE, + true, this, false); + + if (m_window == (FAR CWindow *)0) + { + gerr("ERROR: Failed to create icon manager window"); + success = false; + } + + // Free any temporary name strings + + if (allocName != (FAR char *)0) + { + std::free(allocName); + } + + return success; +} + +/** + * Create the button array widget + */ + +bool CIconMgr::createButtonArray(void) +{ +#warning Missing logic + return false; +} + +/** + * Put an allocated entry into an icon manager + * + * @param wentry the entry to insert + */ + +void CIconMgr::insertEntry(FAR struct SWindowEntry *wentry, + FAR CWindow *cwin) +{ + FAR struct SWindowEntry *tmpwin; + bool added; + + added = false; + if (m_head == NULL) + { + m_head = wentry; + wentry->blink = NULL; + m_tail = wentry; + added = true; + } + + for (tmpwin = m_head; tmpwin != NULL; tmpwin = tmpwin->flink) + { + // Insert the new window in name order + + if (strcmp(cwin->getWindowName(), tmpwin->cwin->getWindowName()) < 0) + { + wentry->flink = tmpwin; + wentry->blink = tmpwin->blink; + tmpwin->blink = wentry; + + if (wentry->blink == NULL) + { + m_head = wentry; + } + else + { + wentry->blink->flink = wentry; + } + + added = true; + break; + } + } + + if (!added) + { + m_tail->flink = wentry; + wentry->blink = m_tail; + m_tail = wentry; + } +} + +/** + * Remove an entry from an icon manager + * + * @param wentry the entry to remove + */ + +void CIconMgr::removeEntry(FAR struct SWindowEntry *wentry) +{ + if (wentry->blink == NULL) + { + m_head = wentry->flink; + } + else + { + wentry->blink->flink = wentry->flink; + } + + if (wentry->flink == NULL) + { + m_tail = wentry->blink; + } + else + { + wentry->flink->blink = wentry->blink; + } +} + +/** + * Set active window + * + * @active Window to become active. + */ + +void CIconMgr::active(FAR struct SWindowEntry *wentry) +{ + wentry->active = true; + m_active = wentry; +} + +/** + * Set window inactive + * + * @active windows to become inactive. + */ + +void CIconMgr::inactive(FAR struct SWindowEntry *wentry) +{ + wentry->active = false; +} + +/** + * Free window list entry. + */ + +void CIconMgr::freeWEntry(FAR struct SWindowEntry *wentry) +{ + if (wentry->cwin != (FAR CWindow *)0) + { + delete wentry->cwin; + wentry->cwin = (FAR CWindow *)0; + } + + free(wentry); +} diff --git a/graphics/twm4nx/src/ciconwin.cxx b/graphics/twm4nx/src/ciconwin.cxx new file mode 100644 index 000000000..4bdaef963 --- /dev/null +++ b/graphics/twm4nx/src/ciconwin.cxx @@ -0,0 +1,385 @@ +///////////////////////////////////////////////////////////////////////////// +// apps/graphics/twm4nx/src/ciconwin.cxx +// Icon Windows +// +// Copyright (C) 2019 Gregory Nutt. All rights reserved. +// Author: Gregory Nutt +// +// Largely an original work but derives from TWM 1.0.10 in many ways: +// +// Copyright 1989,1998 The Open Group +// +// Please refer to apps/twm4nx/COPYING for detailed copyright information. +// +// 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 "graphics/nxwidgets/cnxwindow.hxx" +#include "graphics/nxwidgets/crlepalettebitmap.hxx" + +#include "graphics/twm4nx/twm4nx_config.hxx" +#include "graphics/twm4nx/ctwm4nx.hxx" +#include "graphics/twm4nx/cfonts.hxx" +#include "graphics/twm4nx/cmenus.hxx" +#include "graphics/twm4nx/cwindow.hxx" +#include "graphics/twm4nx/cwindowevent.hxx" +#include "graphics/twm4nx/cicon.hxx" +#include "graphics/twm4nx/ciconwin.hxx" +#include "graphics/twm4nx/twm4nx_widgetevents.hxx" +#include "graphics/twm4nx/twm4nx_cursor.hxx" + +///////////////////////////////////////////////////////////////////////////// +// CTwm4Nx Implementation +///////////////////////////////////////////////////////////////////////////// + +using namespace Twm4Nx; + +/** + * CIconWin Constructor + */ + +CIconWin::CIconWin(CTwm4Nx *twm4nx) +{ + m_twm4nx = twm4nx; // Cached the Twm4Nx session + m_nxwin = (FAR NXWidgets::CNxWindow *)0; // The cursor "raw" window + + // Dragging + + m_drag = false; // No drag in progress + m_dragOffset.x = 0; // Offset from mouse to window origin + m_dragOffset.y = 0; + m_dragCSize.w = 0; // The grab cursor size + m_dragCSize.h = 0; +} + +/** + * CIconWin Destructor + */ + +CIconWin::~CIconWin(void) +{ + cleanup(); +} + +/** + * Create the icon window + * + * @param parent The parent window + * @param sbitmap The Icon image + * @param pos The default position + */ + +bool CIconWin::initialize(FAR CWindow *parent, + FAR const NXWidgets::SRlePaletteBitmap *sbitmap, + FAR const struct nxgl_point_s *pos) +{ + struct nxgl_point_s final; + + // Git the size of the Icon Image + + struct nxgl_size_s iconImageSize; + iconImageSize.h = sbitmap->height; + iconImageSize.w = sbitmap->height; + + // Git the size of the Icon name + + FAR CFonts *fonts = m_twm4nx->getFonts(); + FAR NXWidgets::CNxFont *iconFont = fonts->getIconFont(); + FAR const char *iconName = parent->getWindowName(); + + struct nxgl_size_s iconWindowSize; + iconWindowSize.w = iconFont->getStringWidth(iconName); + iconWindowSize.w += 6; + + // Handle the case where the name string is wider than the icon + + struct nxgl_point_s iconWindowPos; + if (iconWindowSize.w < iconImageSize.w) + { + // Center + + iconWindowPos.x = (iconImageSize.w - iconWindowSize.w) / 2; + iconWindowPos.x += 3; + iconWindowSize.w = iconImageSize.w; + } + else + { + iconWindowPos.x = 3; + } + + iconWindowPos.y = iconImageSize.h + iconFont->getHeight(); + iconWindowSize.h = iconImageSize.h + iconFont->getHeight() + 4; + + // Create the icon window + // 1. Get the server instance. m_twm4nx inherits from NXWidgets::CNXServer + // so we all ready have the server instance. + // 2. Create the style, using the selected colors (REVISIT) + + // 3. Create a Widget control instance for the window using the default + // style for now. CWindowEvent derives from CWidgetControl. + + FAR CWindowEvent *control = new CWindowEvent(m_twm4nx); + + // 4. Create the icon window + + m_nxwin = m_twm4nx->createRawWindow(control); + if (m_nxwin == (FAR NXWidgets::CNxWindow *)0) + { + delete control; + return false; + } + + // 5. Open and initialize the icon window + + bool success = m_nxwin->open(); + if (!success) + { + delete m_nxwin; + m_nxwin = (FAR NXWidgets::CNxWindow *)0; + return false; + } + + // 6. Set the initial window size + + if (!m_nxwin->setSize(&iconWindowSize)) + { + delete m_nxwin; + m_nxwin = (FAR NXWidgets::CNxWindow *)0; + return false; + } + + // 7. Set the initial window position + + if (!m_nxwin->setPosition(&iconWindowPos)) + { + delete m_nxwin; + m_nxwin = (FAR NXWidgets::CNxWindow *)0; + return false; + } + + // We need to figure out where to put the icon window now, because getting + // here means that we am going to make the icon visible. + + FAR CIcon *cicon = m_twm4nx->getIcon(); + cicon->place(parent, pos, &final); + + struct nxgl_size_s displaySize; + m_twm4nx->getDisplaySize(&displaySize); + + if (final.x > displaySize.w) + { + final.x = displaySize.w - iconWindowSize.w; + } + + if (final.y > displaySize.h) + { + final.y = displaySize.h - iconImageSize.h - iconFont->getHeight() - 4; + } + + (void)m_nxwin->setPosition(&final); + return true; +} + +/** + * Handle ICON events. + * + * @param eventmsg. The received NxWidget ICON event message. + * @return True if the message was properly handled. false is + * return on any failure. + */ + +bool CIconWin::event(FAR struct SEventMsg *eventmsg) +{ + bool success = true; + + switch (eventmsg->eventID) + { + case EVENT_ICONWIN_GRAB: /* Left click on icon. Start drag */ + success = iconGrab(eventmsg); + break; + + case EVENT_ICONWIN_DRAG: /* Mouse movement while clicked */ + success = iconDrag(eventmsg); + break; + + case EVENT_ICONWIN_UNGRAB: /* Left click release while dragging. */ + success = iconUngrab(eventmsg); + break; + + default: + success = false; + break; + } + + return success; +} + +/** + * Handle the ICON_GRAB event. That corresponds to a left + * mouse click on the icon + * + * @param eventmsg. The received NxWidget event message. + * @return True if the message was properly handled. false is + * return on any failure. + */ + +bool CIconWin::iconGrab(FAR struct SEventMsg *eventmsg) +{ + // Promote the icon to a modal window + + m_nxwin->modal(true); + + // Indicate that dragging has started. + + m_drag = false; + + // Get the icon position. + + struct nxgl_point_s framePos; + m_nxwin->getPosition(&framePos); + + // Determine the relative position of the icon and the mouse + + m_dragOffset.x = framePos.x - eventmsg->pos.x; + m_dragOffset.y = framePos.y - eventmsg->pos.y; + + // Select the grab cursor image + + m_twm4nx->setCursorImage(&CONFIG_TWM4NX_GBCURSOR_IMAGE); + + // Remember the grab cursor size + + m_dragCSize.w = CONFIG_TWM4NX_GBCURSOR_IMAGE.size.w; + m_dragCSize.h = CONFIG_TWM4NX_GBCURSOR_IMAGE.size.h; + return true; +} + +/** + * Handle the ICON_DRAG event. That corresponds to a mouse + * movement when the icon is in a grabbed state. + * + * @param eventmsg. The received NxWidget event message. + * @return True if the message was properly handled. false is + * return on any failure. + */ + +bool CIconWin::iconDrag(FAR struct SEventMsg *eventmsg) +{ + if (m_drag) + { + // Calculate the new icon position + + struct nxgl_point_s newpos; + newpos.x = eventmsg->pos.x + m_dragOffset.x; + newpos.y = eventmsg->pos.y + m_dragOffset.y; + + // Keep the icon on the display (at least enough of it so that we + // can still grab it) + + struct nxgl_size_s displaySize; + m_twm4nx->getDisplaySize(&displaySize); + + if (newpos.x < 0) + { + newpos.x = 0; + } + else if (newpos.x + m_dragCSize.w > displaySize.w) + { + newpos.x = displaySize.w - m_dragCSize.w; + } + + if (newpos.y < 0) + { + newpos.y = 0; + } + else if (newpos.y + m_dragCSize.h > displaySize.h) + { + newpos.y = displaySize.h - m_dragCSize.h; + } + + // Set the new window position + + return m_nxwin->setPosition(&newpos); + } + + return false; +} + +/** + * Handle the ICON_UNGRAB event. The corresponds to a mouse + * left button release while in the grabbed + * + * @param eventmsg. The received NxWidget event message. + * @return True if the message was properly handled. false is + * return on any failure. + */ + +bool CIconWin::iconUngrab(FAR struct SEventMsg *eventmsg) +{ + // One last position update + + if (!iconDrag(eventmsg)) + { + return false; + } + + // Indicate no longer dragging + + m_drag = false; + + // No long modal + + m_nxwin->modal(false); + + // Restore the normal cursor image + + m_twm4nx->setCursorImage(&CONFIG_TWM4NX_CURSOR_IMAGE); + return false; +} + +/** + * Cleanup on failure or as part of the destructor + */ + +void CIconWin::cleanup(void) +{ + // Close windows + + if (m_nxwin != (FAR NXWidgets::CNxWindow *)0) + { + delete m_nxwin; + m_nxwin = (FAR NXWidgets::CNxWindow *)0; + } +} diff --git a/graphics/twm4nx/src/cinput.cxx b/graphics/twm4nx/src/cinput.cxx new file mode 100644 index 000000000..7e741bab6 --- /dev/null +++ b/graphics/twm4nx/src/cinput.cxx @@ -0,0 +1,692 @@ +/******************************************************************************************** + * apps/graphics/NxWidgets/nxwm/src/cinput.cxx + * + * Copyright (C) 2012 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, NxWidgets, nor the names of its contributors + * me 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 +#include +#include + +#include + +#include "graphics/twm4nx/twm4nx_config.hxx" +#include "graphics/twm4nx/ctwm4nx.hxx" +#include "graphics/twm4nx/twm4nx_cursor.hxx" +#include "graphics/twm4nx/cinput.hxx" + +/******************************************************************************************** + * Pre-Processor Definitions + ********************************************************************************************/ + +/******************************************************************************************** + * CInput Method Implementations + ********************************************************************************************/ + +using namespace Twm4Nx; + +/** + * CInput Constructor + * + * @param twm4nx. An instance of the NX server. This will be needed for + * injecting keyboard data. + */ + +CInput::CInput(CTwm4Nx *twm4nx) +{ + m_twm4nx = twm4nx; // Save the NX server + m_kbdFd = -1; // Device driver is not opened + m_state = LISTENER_NOTRUNNING; // The listener thread is not running yet + + // Initialize the semaphore used to synchronize with the listener thread + + sem_init(&m_waitSem, 0, 0); +} + +/** + * CInput Destructor + */ + +CInput::~CInput(void) +{ + // Stop the listener thread + + m_state = LISTENER_STOPREQUESTED; + + // Wake up the listener thread so that it will use our buffer + // to receive data + // REVISIT: Need wait here for the listener thread to terminate + + (void)pthread_kill(m_thread, CONFIG_TWM4NX_INPUT_SIGNO); + + // Close the keyboard device (or should these be done when the thread exits?) + + if (m_kbdFd >= 0) + { + std::close(m_kbdFd); + } +} + +/** + * Start the keyboard listener thread. + * + * @return True if the keyboard listener thread was correctly started. + */ + +bool CInput::start(void) +{ + pthread_attr_t attr; + + ginfo("Starting listener\n"); + + // Start a separate thread to listen for keyboard events + + (void)pthread_attr_init(&attr); + + struct sched_param param; + param.sched_priority = CONFIG_TWM4NX_INPUT_LISTENERPRIO; + (void)pthread_attr_setschedparam(&attr, ¶m); + + (void)pthread_attr_setstacksize(&attr, CONFIG_TWM4NX_INPUT_LISTENERSTACK); + + m_state = LISTENER_STARTED; // The listener thread has been started, but is not yet running + + int ret = pthread_create(&m_thread, &attr, listener, (FAR void *)this); + if (ret != 0) + { + gerr("ERROR: CInput::start: pthread_create failed: %d\n", ret); + return false; + } + + // Detach from the thread + + (void)pthread_detach(m_thread); + + // Don't return until we are sure that the listener thread is running + // (or until it reports an error). + + while (m_state == LISTENER_STARTED) + { + // Wait for the listener thread to wake us up when we really + // are connected. + + (void)sem_wait(&m_waitSem); + } + + // Then return true only if the listener thread reported successful + // initialization. + + ginfo("Listener m_state=%d\n", (int)m_state); + return m_state == LISTENER_RUNNING; +} + +/** + * Open the keyboard device. Not very interesting for the case of + * standard device but much more interesting for a USB keyboard device + * that may disappear when the keyboard is disconnect but later reappear + * when the keyboard is reconnected. In this case, this function will + * not return until the keyboard device was successfully opened (or + * until an irrecoverable error occurs. + * + * Opens the keyboard device specified by CONFIG_TWM4NX_KEYBOARD_DEVPATH. + * + * @return On success, then method returns a valid file descriptor. A + * negated errno value is returned if an irrecoverable error occurs. + */ + +int CInput::keyboardOpen(void) +{ + int fd; + + // Loop until we have successfully opened the USB keyboard (or until some + // irrecoverable error occurs). + + do + { + // Try to open the keyboard device + + fd = std::open(CONFIG_TWM4NX_KEYBOARD_DEVPATH, O_RDONLY); + if (fd < 0) + { + int errcode = errno; + DEBUGASSERT(errcode > 0); + + // EINTR should be ignored because it is not really an error at + // all. We should retry immediately + + if (errcode != EINTR) + { +#ifdef CONFIG_TWM4NX_KEYBOARD_USBHOST + // ENOENT means that the USB keyboard is not yet connected and, + // hence, has no entry under /dev. If the USB driver still + // exists under /dev (because other threads still have the driver + // open), then we might also get ENODEV. + + if (errcode == ENOENT || errcode == ENODEV) + { + // REVIST: Can we inject a constant string here to let the + // user know that we are waiting for a USB keyboard to be + // connected? + + // Sleep a bit and try again + + ginfo("WAITING for a USB keyboard\n"); + std::sleep(2); + } + + // Anything else would be really bad. + + else +#endif + { + // Let the top-level logic decide what it wants to do + // about all really bad things + + gerr("ERROR: Failed to open %s for reading: %d\n", + CONFIG_TWM4NX_KEYBOARD_DEVPATH, errcode); + return -errcode; + } + } + } + } + while (fd < 0); + + return fd; +} + +/** + * Open the mouse input devices. Not very interesting for the + * case of standard character device but much more interesting for + * USB mouse devices that may disappear when disconnected but later + * reappear when reconnected. In this case, this function will + * not return until the input device was successfully opened (or + * until an irrecoverable error occurs). + * + * Opens the mouse input device specified by CONFIG_TWM4NX_MOUSE_DEVPATH. + * + * @return On success, then method returns a valid file descriptor. A + * negated errno value is returned if an irrecoverable error occurs. + */ + +inline int CInput::mouseOpen(void) +{ + int fd; + + // Loop until we have successfully opened the USB mouse (or until some + // irrecoverable error occurs). + + do + { + // Try to open the mouse device + + fd = std::open(CONFIG_TWM4NX_MOUSE_DEVPATH, O_RDONLY); + if (fd < 0) + { + int errcode = errno; + DEBUGASSERT(errcode > 0); + + // EINTR should be ignored because it is not really an error at + // all. We should retry immediately + + if (errcode != EINTR) + { +#ifdef CONFIG_TWM4NX_MOUSE_USBHOST + // ENOENT means that the USB mouse is not yet connected and, + // hence, has no entry under /dev. If the USB driver still + // exists under /dev (because other threads still have the driver + // open), then we might also get ENODEV. + + if (errcode == ENOENT || errcode == ENODEV) + { + // REVIST: Can we inject a constant string here to let the + // user know that we are waiting for a USB mouse to be + // connected? + + // Sleep a bit and try again + + ginfo("WAITING for a USB mouse\n"); + std::sleep(2); + } + + // Anything else would be really bad. + + else +#endif + { + // Let the top-level logic decide what it wants to do + // about all really bad things + + gerr("ERROR: Failed to open %s for reading: %d\n", + CONFIG_TWM4NX_MOUSE_DEVPATH, errcode); + return -errcode; + } + } + } + } + while (fd < 0); + + return fd; +} + +/** + * Read data from the keyboard device and inject the keyboard data + * into NX for proper distribution. + * + * @return On success, then method returns a valid file descriptor. A + * negated errno value is returned if an irrecoverable error occurs. + */ + +int CInput::keyboardInput(void) +{ + // Read one keyboard sample + + ginfo("Reading keyboard input\n"); + + uint8_t rxbuffer[CONFIG_TWM4NX_KEYBOARD_BUFSIZE]; + ssize_t nbytes = read(m_kbdFd, rxbuffer, + CONFIG_TWM4NX_KEYBOARD_BUFSIZE); + + // Check for errors + + if (nbytes < 0) + { + int errcode = errno; + DEBUGASSERT(errcode > 0); + + // EINTR is not really an error, it simply means that something is + // trying to get our attention. We need to check m_state to see + // if we were asked to terminate + + if (errcode != EINTR) + { + // Let the top-level listener logic decide what to do about + // the read failure. + + gerr("ERROR: read %s failed: %d\n", + CONFIG_TWM4NX_KEYBOARD_DEVPATH, errcode); + return -errcode; + } + + fwarn("WARNING: Awakened with EINTR\n"); + } + + // Give the keyboard input to NX + + else if (nbytes > 0) + { + // Looks like good keyboard input... process it. + // NOTE: m_twm4nx inherits from NXWidgets::CNXServer so we all ready + // have the server instance. + + // Inject the keyboard input into NX + + int ret = nx_kbdin(m_twm4nx, (uint8_t)nbytes, rxbuffer); + if (ret < 0) + { + gerr("ERROR: nx_kbdin failed: %d\n", ret); + + // Ignore the error + } + } + + return OK; +} + +/** + * Read data from the mouse device, update the cursor position, and + * inject the mouse data into NX for proper distribution. + * + * @return On success, then method returns a valid file descriptor. A + * negated errno value is returned if an irrecoverable error occurs. + */ + +int CInput::mouseInput(void) +{ + // Read one mouse sample + + ginfo("Reading mouse input\n"); + + uint8_t rxbuffer[CONFIG_TWM4NX_MOUSE_BUFSIZE]; + ssize_t nbytes = read(m_mouseFd, rxbuffer, + CONFIG_TWM4NX_MOUSE_BUFSIZE); + + // Check for errors + + if (nbytes < 0) + { + int errcode = errno; + DEBUGASSERT(errcode > 0); + + // EINTR is not really an error, it simply means that something is + // trying to get our attention. We need to check m_state to see + // if we were asked to terminate + + if (errcode != EINTR) + { + // Let the top-level listener logic decide what to do about + // the read failure. + + gerr("ERROR: read %s failed: %d\n", + CONFIG_TWM4NX_KEYBOARD_DEVPATH, errcode); + return -errcode; + } + + fwarn("WARNING: Awakened with EINTR\n"); + } + + // On a truly successful read, the size of the returned data will + // be greater than or equal to size of one touchscreen sample. It + // be greater only in the case of a multi-touch touchscreen device + // when multi-touches are reported. + + else if (nbytes < (ssize_t)sizeof(struct mouse_report_s)) + { + gerr("ERROR Unexpected read size=%d, expected=%d\n", + nbytes, sizeof(struct mouse_report_s)); + return -EIO; + } + else + { + // Looks like good mouse input... process it. + // NOTE: m_twm4nx inherits from NXWidgets::CNXServer so we all ready + // have the server instance. + + // Update the cursor position + + FAR struct mouse_report_s *rpt = + (FAR struct mouse_report_s *)rxbuffer; + + struct nxgl_point_s pos = + { + .x = rpt->x, + .y = rpt->y + }; + + int ret = nxcursor_setposition(m_twm4nx, &pos); + if (ret < 0) + { + gerr("ERROR: nxcursor_setposition failed: %d\n", ret); + + // Ignore the error + } + + // Then inject the mouse input into NX + + ret = nx_mousein(m_twm4nx, rpt->x, rpt->y, rpt->buttons); + if (ret < 0) + { + gerr("ERROR: nx_mousein failed: %d\n", ret); + + // Ignore the error + } + } + + return OK; +} + +/** + * This is the heart of the keyboard/mouse listener thread. It + * contains the actual logic that listeners for and dispatches input + * events to the NX server. + * + * @return If the session terminates gracefully (i.e., because >m_state + * is no longer equal to LISTENER_RUNNING, then method returns OK. A + * negated errno value is returned if an error occurs while reading from + * the input device. A read error, depending upon the type of the + * error, may simply indicate that a USB device was removed and we + * should wait for the device to be connected. + */ + +int CInput::session(void) +{ + ginfo("Session started\n"); + + // Center the cursor + + struct nxgl_size_s size; + m_twm4nx->getDisplaySize(&size); + + struct nxgl_point_s pos; + pos.x = size.w / 2, + pos.y = size.h / 2, + + m_twm4nx->setCursorPosition(&pos); + + // Set the default cursor image + + m_twm4nx->setCursorImage(&CONFIG_TWM4NX_CURSOR_IMAGE); + + // Enable the cursor + + m_twm4nx->enableCursor(true); + + // Loop, reading and dispatching keyboard data + + int ret = OK; + while (m_state == LISTENER_RUNNING) + { + // Wait for data availability + + struct pollfd pfd[2] = + { + { + .fd = m_kbdFd, + .events = POLLIN | POLLERR | POLLHUP, + .revents = 0 + }, + { + .fd = m_mouseFd, + .events = POLLIN | POLLERR | POLLHUP, + .revents = 0 + }, + }; + + ret = poll(pfd, 2, -1); + if (ret < 0) + { + int errcode = errno; + + /* Ignore signal interruptions */ + + if (errcode == EINTR) + { + continue; + } + else + { + gerr("ERROR: poll() failed"); + break; + } + } + + // Check for keyboard input + + if ((pfd[0].revents & (POLLERR | POLLHUP)) != 0) + { + gerr("ERROR: keyboard poll() failed. revents=%04x\n", + pfd[0].revents); + ret = -EIO; + break; + } + + if ((pfd[0].revents & POLLIN) != 0) + { + ret = keyboardInput(); + if (ret < 0) + { + gerr("ERROR: keyboardInput() failed: %d\n", ret); + break; + } + } + + // Check for mouse input + + if ((pfd[1].revents & (POLLERR | POLLHUP)) != 0) + { + gerr("ERROR: Mouse poll() failed. revents=%04x\n", + pfd[1].revents); + ret = -EIO; + break; + } + + if ((pfd[1].revents & POLLIN) != 0) + { + ret = mouseInput(); + if (ret < 0) + { + gerr("ERROR: mouseInput() failed: %d\n", ret); + break; + } + } + } + + // Disable the cursor + + m_twm4nx->enableCursor(false); + return ret; +} + +/** + * The keyboard/mouse listener thread. This is the entry point of a + * thread that listeners for and dispatches keyboard and mouse events + * to the NX server. It simply opens the input devices (using + * CInput::keyboardOpen() and CInput::mouseOpen()) and executes the + * session (via CInput::session()). + * + * If an errors while reading from the input device AND that device is + * configured to use a USB connection, then this function will wait for + * the USB device to be re-connected. + * + * @param arg. The CInput 'this' pointer cast to a void*. + * @return This function normally does not return but may return NULL + * on error conditions. + */ + +FAR void *CInput::listener(FAR void *arg) +{ + CInput *This = (CInput *)arg; + + ginfo("Listener started\n"); + +#if defined(CONFIG_TWM4NX_KEYBOARD_USBHOST) || defined(CONFIG_TWM4NX_MOUSE_USBHOST) + // Indicate that we have successfully started. We might be stuck waiting + // for a USB keyboard to be connected, but we are technically running + + This->m_state = LISTENER_RUNNING; + sem_post(&This->m_waitSem); + + // Loop until we are told to quit + + while (This->m_state == LISTENER_RUNNING) +#endif + { + // Open/Re-open the keyboard device + + This->m_kbdFd = This->keyboardOpen(); + if (This->m_kbdFd < 0) + { + gerr("ERROR: open failed: %d\n", This->m_kbdFd); + This->m_state = LISTENER_FAILED; + sem_post(&This->m_waitSem); + return (FAR void *)0; + } + + // Open/Re-open the mouse device + + This->m_mouseFd = This->mouseOpen(); + if (This->m_mouseFd < 0) + { + gerr("ERROR: open failed: %d\n", This->m_mouseFd); + This->m_state = LISTENER_FAILED; + sem_post(&This->m_waitSem); + return (FAR void *)0; + } + +#if !defined(CONFIG_TWM4NX_KEYBOARD_USBHOST) && !defined(CONFIG_TWM4NX_MOUSE_USBHOST) + // Indicate that we have successfully initialized + + This->m_state = LISTENER_RUNNING; + sem_post(&This->m_waitSem); +#endif + + // Now execute the session. The session will run until either (1) we + // were asked to terminate gracefully (with m_state !=LISTENER_RUNNING), + // of if an error occurred while reading from the keyboard device. If + // we are configured to use a USB keyboard, then this error, depending + // upon what the error is, may indicate that the USB keyboard has been + // removed. In that case, we need to continue looping and, hopefully, + // the USB keyboard will be reconnected. + + int ret = This->session(); +#if defined(CONFIG_TWM4NX_KEYBOARD_USBHOST) || defined(CONFIG_TWM4NX_MOUSE_USBHOST) + if (ret < 0) + { + ferr("ERROR: CInput::session() returned %d\n", ret); + } +#else + // No errors from session() are expected + + DEBUGASSERT(ret == OK); + UNUSED(ret); +#endif + + // Close the keyboard device + + (void)std::close(This->m_kbdFd); + This->m_kbdFd = -1; + + // Close the mouse device + + (void)std::close(This->m_mouseFd); + This->m_mouseFd = -1; + } + + // We should get here only if we were asked to terminate via + // m_state = LISTENER_STOPREQUESTED (or perhaps if some irrecoverable + // error has occurred). + + ginfo("Listener exiting\n"); + This->m_state = LISTENER_TERMINATED; + return (FAR void *)0; +} diff --git a/graphics/twm4nx/src/cmenus.cxx b/graphics/twm4nx/src/cmenus.cxx new file mode 100644 index 000000000..660149090 --- /dev/null +++ b/graphics/twm4nx/src/cmenus.cxx @@ -0,0 +1,882 @@ +///////////////////////////////////////////////////////////////////////////// +// apps/graphics/twm4nx/src/cmenus.cxx +// twm menu code +// +// Copyright (C) 2019 Gregory Nutt. All rights reserved. +// Author: Gregory Nutt +// +// Largely an original work but derives from TWM 1.0.10 in many ways: +// +// Copyright 1989,1998 The Open Group +// Copyright 1988 by Evans & Sutherland Computer Corporation, +// +// Please refer to apps/twm4nx/COPYING for detailed copyright information. +// +// 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 + +#include + +#include "graphics/nxwidgets/cnxfont.hxx" +#include "graphics/nxwidgets/clistbox.hxx" + +#include "graphics/twm4nx/ctwm4nx.hxx" +#include "graphics/twm4nx/cmenus.hxx" +#include "graphics/twm4nx/cresize.hxx" +#include "graphics/twm4nx/cfonts.hxx" +#include "graphics/twm4nx/cicon.hxx" +#include "graphics/twm4nx/ciconmgr.hxx" +#include "graphics/twm4nx/cwindow.hxx" +#include "graphics/twm4nx/cwindowfactory.hxx" +#include "graphics/twm4nx/cwindowevent.hxx" +#include "graphics/twm4nx/twm4nx_widgetevents.hxx" +#include "graphics/twm4nx/cmenus.hxx" + +//////////////////////////////////////////////////////////////////////////// +// Class Implementations +///////////////////////////////////////////////////////////////////////////// + +using namespace Twm4Nx; + +/** + * CMenus Constructor + */ + +CMenus::CMenus(CTwm4Nx *twm4nx) +{ + // Save the Twm4Nx session + + m_twm4nx = twm4nx; // Save the Twm4Nx session + + // Menus + + m_popUpMenu = (FAR CMenus *)0; // No pop-up menu + m_activeItem = (FAR struct SMenuItem *)0; // No active menu item + m_nMenuItems = 0; // No menu items yet + m_menuDepth = 0; // No menus up + m_entryHeight = 0; // Menu entry height + m_menuPull = false; // No pull right entry + + // Windows + + m_menuWindow = (FAR NXWidgets::CNxTkWindow *)0; // The menu window + + // Widgets + + m_menuListBox = (FAR NXWidgets::CListBox *)0; //The menu list box + + // Functions + + m_funcKeyHead = (FAR struct SFuncKey *)0; +} + +/** + * CMenus Destructor + */ + +CMenus::~CMenus(void) +{ + cleanup(); +} + +/** + * CMenus Initializer. Performs the parts of the CMenus construction + * that may fail. + * + * @result True is returned on success + */ + +bool CMenus::initialize(FAR const char *name) +{ + // Open a message queue to NX events. + + FAR const char *mqname = m_twm4nx->getEventQueueName(); + m_eventq = mq_open(mqname, O_WRONLY | O_NONBLOCK); + if (m_eventq == (mqd_t)-1) + { + gerr("ERROR: Failed open message queue '%s': %d\n", + mqname, errno); + } + + // Save the menu name + + m_menuName = strdup(name); + if (m_menuName == (FAR char *)0) + { + return false; + } + + // Create the menu window + + if (!createMenuWindow()) + { + gerr("ERROR: Failed to create menu window\n"); + cleanup(); + return false; + } + + // Create the menu list box + + if (!createMenuListBox()) + { + gerr("ERROR: Failed to create menu list box\n"); + cleanup(); + return false; + } + + return true; +} + +/** + * Add an item to a menu + * + * \param text The text to appear in the menu + * \param action The string to possibly execute + * \param subMenu The menu if it is a pull-right entry + * \param func The numeric function + */ + +// REVISIT: Only used internally. Was used in .twmrc parsing. + +bool CMenus::addMenuItem(FAR const char *text, + FAR const char *action, FAR CMenus *subMenu, + int func) +{ + ginfo("Adding menu text=\"%s\", action=%s, subMenu=%d, f=%d\n", + text, action, subMenu, func); + + // Allocate a new menu item entry + + FAR struct SMenuItem *item = new SMenuItem; + + if (item == (FAR struct SMenuItem *)0) + { + gerr("ERROR: Failed to allocate menu item\n"); + return false; + } + + // Clone the item name so that we have control over its lifespan + + item->text = std::strdup(text); + if (item->text == (FAR char *)0) + { + gerr("ERROR: strdup of item text failed\n"); + std::free(item); + return false; + } + + // Save information about the menu item + + item->action = action; + item->flink = NULL; + item->subMenu = NULL; + item->func = func; + + CFonts *fonts = m_twm4nx->getFonts(); + FAR NXWidgets::CNxFont *menuFont = fonts->getMenuFont(); + int width = menuFont->getStringWidth(text); + + if (width <= 0) + { + width = 1; + } + + struct nxgl_size_s menuSize; + m_menuWindow->getSize(&menuSize); + + if (width > menuSize.w) + { + menuSize.w = width; + m_menuWindow->setSize(&menuSize); + } + + if (subMenu != NULL) + { + item->subMenu = subMenu; + m_menuPull = true; + } + + // Save the index to this item and increment the total number of menu + // items + + item->index = m_nMenuItems++; + + // Add the menu item to the tail of the item list + + if (m_menuHead == NULL) + { + m_menuHead = item; + item->blink = (FAR struct SMenuItem *)0; + } + else + { + m_menuTail->flink = item; + item->blink = m_menuTail; + } + + m_menuTail = item; + item->flink = (FAR struct SMenuItem *)0; + + // Add the item text to the list box + + m_menuListBox->addOption(item->text, item->index); + + // Update the menu window size + + setMenuWindowSize(); + + // Redraw the list box + + m_menuListBox->enableDrawing(); + m_menuListBox->setRaisesEvents(true); + m_menuListBox->redraw(); + return true; +} + +/** + * Handle MENU events. + * + * @param eventmsg. The received NxWidget MENU event message. + * @return True if the message was properly handled. false is + * return on any failure. + */ + +bool CMenus::event(FAR struct SEventMsg *eventmsg) +{ + bool success = true; + + switch (eventmsg->eventID) + { + case EVENT_MENU_IDENTIFY: // Describe the window + { + identify((FAR CWindow *)eventmsg->obj); + } + break; + + case EVENT_MENU_VERSION: // Show the Twm4Nx version + identify((FAR CWindow *) NULL); + break; + + case EVENT_MENU_DEICONIFY: // Window icon pressed + case EVENT_MENU_ICONIFY: // Tool bar minimize button pressed + { + FAR CWindow *cwin = (FAR CWindow *)eventmsg->obj; + if (cwin->isIconified()) + { + cwin->deIconify(); + } + else if (eventmsg->eventID == EVENT_MENU_ICONIFY) + { + cwin->iconify(); + } + } + break; + + case EVENT_MENU_FUNCTION: // Perform function on unknown menu + { + FAR struct SMenuItem *item; + + for (item = m_menuHead; item != NULL; item = item->flink) + { + // Send another event message to the session manager + + struct SEventMsg newmsg; + newmsg.eventID = item->func; + newmsg.pos.x = eventmsg->pos.x; + newmsg.pos.y = eventmsg->pos.y; + newmsg.context = eventmsg->context; + newmsg.pulldown = eventmsg->pulldown; + newmsg.action = item->action; + newmsg.nxwin = eventmsg->nxwin; + newmsg.obj = eventmsg->obj; + + // NOTE that we cannot block because we are on the same thread + // as the message reader. If the event queue becomes full then + // we have no other option but to lose events. + // + // I suppose we could recurse and call Twm4Nx::dispatchEvent at + // the risk of runawy stack usage. + + int ret = mq_send(m_eventq, (FAR const char *)&newmsg, + sizeof(struct SEventMsg), 100); + if (ret < 0) + { + gerr("ERROR: mq_send failed: %d\n", ret); + success = false; + } + } + } + break; + + case EVENT_MENU_TITLE: // Really an action not an event + case EVENT_MENU_ROOT: // Popup root menu, really an action not an event + default: + success = false; + break; + } + + return success; +} + +void CMenus::identify(FAR CWindow *cwin) +{ + int n = 0; +#if CONFIG_VERSION_MAJOR != 0 || CONFIG_VERSION_MINOR != 0 + std::snprintf(m_info[n], INFO_SIZE, "Twm4Nx: NuttX-" CONFIG_VERSION_STRING); +#else + std::snprintf(m_info[n], INFO_SIZE, "Twm4Nx:"); +#endif + m_info[n++][0] = '\0'; + + if (cwin != (FAR CWindow *)0) + { + // Get the size of the window + + struct nxgl_size_s windowSize; + if (!cwin->getFrameSize(&windowSize)) + { + return; + } + + struct nxgl_point_s windowPos; + if (!cwin->getFramePosition(&windowPos)) + { + return; + } + + std::snprintf(m_info[n++], INFO_SIZE, "Name = \"%s\"", + cwin->getWindowName()); + m_info[n++][0] = '\0'; + std::snprintf(m_info[n++], INFO_SIZE, "Geometry/root = %dx%d+%d+%d", + windowSize.w, windowSize.h, windowPos.x, windowPos.y); + } + + m_info[n++][0] = '\0'; + std::snprintf(m_info[n++], INFO_SIZE, "Click to dismiss...."); + + // Figure out the width and height of the info window + + FAR CFonts *fonts = m_twm4nx->getFonts(); + FAR NXWidgets::CNxFont *defaultFont = fonts->getDefaultFont(); + + struct nxgl_size_s menuSize; + menuSize.h = n * (defaultFont->getHeight() + 2); + menuSize.w = 1; + + for (int i = 0; i < n; i++) + { + int twidth = defaultFont->getStringWidth(m_info[i]); + if (twidth > menuSize.w) + { + menuSize.w = twidth; + } + } + + menuSize.w += 10; // some padding + + // Make sure that the window is on the display + + struct nxgl_point_s menuPos; + if (m_menuWindow->getPosition(&menuPos)) + { + menuPos.x -= (menuSize.w / 2); + menuPos.y -= (menuSize.h / 3); + + struct nxgl_size_s displaySize; + m_twm4nx->getDisplaySize(&displaySize); + + struct nxgl_size_s frameSize; + menuToFrameSize(&menuSize, &frameSize); + + if (menuPos.x + frameSize.w >= displaySize.w) + { + menuPos.x = displaySize.w - frameSize.w; + } + + if (menuPos.y + frameSize.h >= displaySize.h) + { + menuPos.y = displaySize.h - frameSize.h; + } + + if (menuPos.x < 0) + { + menuPos.x = 0; + } + + if (menuPos.y < 0) + { + menuPos.y = 0; + } + + frameToMenuSize(&frameSize, &menuSize); + } + else + { + menuPos.x = 0; + menuPos.y = 0; + } + + // Set the new window size and position + + if (!m_menuWindow->setPosition(&menuPos) || + !m_menuWindow->setSize(&menuSize)) + { + return; + } + + // Raise it to the top of the hiearchy + + m_menuWindow->raise(); +} + +/** + * Create the menu window + * + * @result True is returned on success + */ + +bool CMenus::createMenuWindow(void) +{ + // Create the menu window + // 1. Get the server instance. m_twm4nx inherits from NXWidgets::CNXServer + // so we all ready have the server instance. + // 2. Create the style, using the selected colors (REVISIT) + + // 3. Create a Widget control instance for the window using the default + // style for now. CWindowEvent derives from CWidgetControl. + + FAR CWindowEvent *control = new CWindowEvent(m_twm4nx); + + // 4. Create the menu window + + m_menuWindow = m_twm4nx->createFramedWindow(control); + if (m_menuWindow == (FAR NXWidgets::CNxTkWindow *)0) + { + delete control; + return false; + } + + // 5. Open and initialize the menu window + + bool success = m_menuWindow->open(); + if (!success) + { + delete m_menuWindow; + m_menuWindow = (FAR NXWidgets::CNxTkWindow *)0; + return false; + } + + // 6. Set the initial window size + + if (!setMenuWindowSize()) + { + delete m_menuWindow; + m_menuWindow = (FAR NXWidgets::CNxTkWindow *)0; + return false; + } + + // 7. Set the initial window position + + struct nxgl_point_s pos = + { + .x = 0, + .y = 0 + }; + + if (!m_menuWindow->setPosition(&pos)) + { + delete m_menuWindow; + m_menuWindow = (FAR NXWidgets::CNxTkWindow *)0; + return false; + } + + return true; +} + +/** + * Update the menu window size + * + * @result True is returned on success + */ + +bool CMenus::setMenuWindowSize(void) +{ + CFonts *fonts = m_twm4nx->getFonts(); + FAR NXWidgets::CNxFont *menuFont = fonts->getMenuFont(); + + m_entryHeight = menuFont->getHeight() + 4; + + // Get the length of the longest item string in in the menu + + nxgl_coord_t maxstring = 0; + for (FAR struct SMenuItem *curr = m_menuHead; + curr != NULL; + curr = curr->flink) + { + if (curr->text != (FAR char *)0) + { + nxgl_coord_t stringlen = menuFont->getStringWidth(curr->text); + if (stringlen > maxstring) + { + maxstring = stringlen; + } + } + } + + // Lets first size the window accordingly + + struct nxgl_size_s menuSize; + menuSize.w = maxstring + 10; + + unsigned int nMenuItems = m_nMenuItems > 0 ? m_nMenuItems : 1; + menuSize.h = nMenuItems * m_entryHeight; + + if (m_menuPull == true) + { + menuSize.w += 16; + } + + // Clip to the size of the display + + struct nxgl_size_s displaySize; + m_twm4nx->getDisplaySize(&displaySize); + + struct nxgl_size_s frameSize; + menuToFrameSize(&menuSize, &frameSize); + + if (frameSize.w > displaySize.w) + { + frameSize.w = displaySize.w; + } + + if (frameSize.h > displaySize.h) + { + frameSize.h = displaySize.h; + } + + // Set the new menu window size + + frameToMenuSize(&frameSize, &menuSize); + + if (!m_menuWindow->setSize(&menuSize)) + { + gerr("ERROR: Failed to set window size\n"); + return false; + } + + return true; +} + +/** + * Set the position of the menu window. Supports positioning of a + * pop-up window. + * + * @param framePos The position of the menu window frame + * @result True is returned on success + */ + +bool CMenus::setMenuWindowPosition(FAR struct nxgl_point_s *framePos) +{ + struct nxgl_point_s menuPos; + frameToMenuPos(framePos, &menuPos); + return m_menuWindow->setPosition(&menuPos); +} + +/** + * Create the menu list box + * + * @result True is returned on success + */ + +bool CMenus::createMenuListBox(void) +{ + // Create the menu list box + // 1. Get the server instance. m_twm4nx inherits from NXWidgets::CNXServer + // so we all ready have the server instance. + // 2. Create the style, using the selected colors (REVISIT) + + // 3. Create a Widget control instance for the window using the default + // style for now. CWindowEvent derives from CWidgetControl. + + FAR CWindowEvent *control = new CWindowEvent(m_twm4nx); + + // 4. Create the menu list box + + struct nxgl_point_s pos; + pos.x = 0; + pos.y = 0; + + struct nxgl_size_s size; + pos.x = 0; + pos.y = 0; + + m_menuListBox = new NXWidgets::CListBox(control, pos.x, pos.y, + size.w, size.h); + if (m_menuListBox == (FAR NXWidgets::CListBox *)0) + { + gerr("ERROR: Failed to instantiate list box\n"); + delete control; + return false; + } + + // Configure the list box + + m_menuListBox->disable(); + m_menuListBox->disableDrawing(); + m_menuListBox->disableDrawing(); + + // Register to get events from the mouse clicks on the image + + m_menuListBox->addWidgetEventHandler(this); + return true; +} + +/** + * Pop up a pull down menu. + * + * @param pos Location of upper left of menu frame + */ + +bool CMenus::popUpMenu(FAR struct nxgl_point_s *pos) +{ + // If there is already a popup menu, then delete it. We only permit + // one popup at this level. + + if (m_popUpMenu != (FAR CMenus *)0) + { + delete m_popUpMenu; + } + + // Create and initialize a new menu + + m_popUpMenu = new CMenus(m_twm4nx); + if (m_popUpMenu == (FAR CMenus *)0) + { + gerr("ERROR: Failed to create popup menu.\n"); + return false; + } + + if (!m_popUpMenu->initialize(m_activeItem->text)) + { + gerr("ERROR: Failed to intialize popup menu.\n"); + delete m_popUpMenu; + m_popUpMenu = (FAR CMenus *)0; + return false; + } + + m_popUpMenu->addMenuItem("TWM Windows", (FAR const char *)0, + (FAR CMenus *)0, 0); + + FAR CWindowFactory *factory = m_twm4nx->getWindowFactory(); + int nWindowNames; + + FAR struct SWindow *swin; + for (swin = factory->windowHead(), nWindowNames = 0; + swin != NULL; swin = swin->flink) + { + nWindowNames++; + } + + if (nWindowNames != 0) + { + FAR CWindow **windowNames = + (FAR CWindow **)std::malloc(sizeof(FAR CWindow *) * nWindowNames); + + if (windowNames == (FAR CWindow **)0) + { + gerr("ERROR: Failed to allocat window name\n"); + return false; + } + + swin = factory->windowHead(); + windowNames[0] = swin->cwin; + + for (nWindowNames = 1; + swin != NULL; + swin = swin->flink, nWindowNames++) + { + FAR CWindow *tmpcwin1 = swin->cwin; + for (int i = 0; i < nWindowNames; i++) + { + FAR const char *windowName1 = tmpcwin1->getWindowName(); + FAR const char *windowName2 = windowNames[i]->getWindowName(); + + if (std::strcmp(windowName1, windowName2) < 0) + { + FAR CWindow *tmpcwin2; + tmpcwin2 = tmpcwin1; + tmpcwin1 = windowNames[i]; + windowNames[i] = tmpcwin2; + } + } + + windowNames[nWindowNames] = tmpcwin1; + } + + for (int i = 0; i < nWindowNames; i++) + { + m_popUpMenu->addMenuItem(windowNames[i]->getWindowName(), + (FAR const char *)0, (FAR CMenus *)0, + EVENT_WINDOW_POPUP); + } + + std::free(windowNames); + } + + if (m_nMenuItems == 0) + { + delete m_popUpMenu; + m_popUpMenu = (FAR CMenus *)0; + return false; + } + + // Clip to screen + + struct nxgl_size_s displaySize; + m_twm4nx->getDisplaySize(&displaySize); + + struct nxgl_size_s menuSize; + m_menuWindow->getSize(&menuSize); + + struct nxgl_size_s frameSize; + menuToFrameSize(&menuSize, &frameSize); + + if (pos->x + frameSize.w > displaySize.w) + { + pos->x = displaySize.w - frameSize.w; + } + + if (pos->x < 0) + { + pos->x = 0; + } + + if (pos->y + frameSize.h > displaySize.h) + { + pos->y = displaySize.h - frameSize.h; + } + + if (pos->y < 0) + { + pos->y = 0; + } + + DEBUGASSERT(m_menuDepth < UINT8_MAX); + m_menuDepth++; + + if (!m_popUpMenu->setMenuWindowPosition(pos)) + { + delete m_popUpMenu; + m_popUpMenu = (FAR CMenus *)0; + return false; + } + + m_popUpMenu->raiseMenuWindow(); + m_menuWindow->synchronize(); + return m_popUpMenu; +} + +/** + * Cleanup or initialization error or on deconstruction. + */ + +void CMenus::cleanup(void) +{ + // Close the NxWidget event message queue + + if (m_eventq != (mqd_t)-1) + { + (void)mq_close(m_eventq); + m_eventq = (mqd_t)-1; + } + + // Free any popup menus + + if (m_popUpMenu != (FAR CMenus *)0) + { + delete m_popUpMenu; + } + + // Free the menu window + + if (m_menuWindow != (FAR NXWidgets::CNxTkWindow *)0) + { + delete m_menuWindow; + m_menuWindow = (FAR NXWidgets::CNxTkWindow *)0; + } + + // Free each menu item + + FAR struct SMenuItem *curr; + FAR struct SMenuItem *next; + + for (curr = m_menuHead; curr != (FAR struct SMenuItem *)0; curr = next) + { + next = curr->flink; + + // Free the menu item text + + if (curr->text != (FAR char *)0) + { + std::free(curr->text); + } + + // Free any subMenu + + if (curr->subMenu != (FAR CMenus *)0) + { + delete curr->subMenu; + } + + // Free the menu item + + delete curr; + } + + // Free allocated memory + + if (m_menuName != (FAR char *)0) + { + std::free(m_menuName); + m_menuName = (FAR char *)0; + } +} diff --git a/graphics/twm4nx/src/cresize.cxx b/graphics/twm4nx/src/cresize.cxx new file mode 100644 index 000000000..74132b333 --- /dev/null +++ b/graphics/twm4nx/src/cresize.cxx @@ -0,0 +1,1080 @@ +///////////////////////////////////////////////////////////////////////////// +// apps/graphics/twm4nx/src/cresize.cxx +// +// Copyright (C) 2019 Gregory Nutt. All rights reserved. +// Author: Gregory Nutt +// +// Largely an original work but derives from TWM 1.0.10 in many ways: +// +// Copyright 1989,1998 The Open Group +// Copyright 1988 by Evans & Sutherland Computer Corporation, +// +// Please refer to apps/twm4nx/COPYING for detailed copyright information. +// +// 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 "graphics/nxwidgets/cnxfont.hxx" + +#include "graphics/twm4nx/twm4nx_config.hxx" +#include "graphics/twm4nx/ctwm4nx.hxx" +#include "graphics/twm4nx/cmenus.hxx" +#include "graphics/twm4nx/cresize.hxx" +#include "graphics/twm4nx/ciconmgr.hxx" +#include "graphics/twm4nx/cwindowevent.hxx" +#include "graphics/twm4nx/cfonts.hxx" +#include "graphics/twm4nx/cwindow.hxx" + +///////////////////////////////////////////////////////////////////////////// +// Pre-processor Definitions +///////////////////////////////////////////////////////////////////////////// + +#define MINHEIGHT 0 // had been 32 +#define MINWIDTH 0 // had been 60 + +#define makemult(a,b) ((b==1) ? (a) : (((int)((a) / (b))) * (b))) + +#ifndef MIN +# define MIN(a,b) (((a) < (b)) ? (a) : (b)) +#endif + +///////////////////////////////////////////////////////////////////////////// +// Class Implementations +///////////////////////////////////////////////////////////////////////////// + +using namespace Twm4Nx; + +/** + * CResize Constructor + */ + +CResize::CResize(CTwm4Nx *twm4nx) +{ + // Save the Twm4Nx session + + m_twm4nx = twm4nx; + + // Windows + + m_sizeWindow = (FAR NXWidgets::CNxTkWindow *)0; + + // Strings + + m_stringWidth = 0; +} + +/** + * CResize Destructor + */ + +CResize::~CResize(void) +{ + // Free the resize dimensions window + + if (m_sizeWindow != (FAR NXWidgets::CNxTkWindow *)0) + { + delete m_sizeWindow; + m_sizeWindow = (FAR NXWidgets::CNxTkWindow *)0; + } +} + +/** + * CResize Initializer. Performs the parts of the CResize construction + * that may fail. + * + * @result True is returned on success + */ + +bool CResize::initialize(void) +{ + // Create the main window + // 1. Get the server instance. m_twm4nx inherits from NXWidgets::CNXServer + // so we all ready have the server instance. + // 2. Create the style, using the selected colors (REVISIT) + + // 3. Create a Widget control instance for the window using the default + // style for now. CWindowEvent derives from CWidgetControl. + + FAR CWindowEvent *control = new CWindowEvent(m_twm4nx); + + // 4. Create the main window + + m_sizeWindow = m_twm4nx->createFramedWindow(control); + if (m_sizeWindow == (FAR NXWidgets::CNxTkWindow *)0) + { + delete control; + return false; + } + + // 5. Open and initialize the main window + + bool success = m_sizeWindow->open(); + if (!success) + { + delete m_sizeWindow; + m_sizeWindow = (FAR NXWidgets::CNxTkWindow *)0; + return false; + } + + // 6. Set the initial window size + + // Create the resize dimension window + + FAR CFonts *fonts = m_twm4nx->getFonts(); + FAR NXWidgets::CNxFont *sizeFont = fonts->getSizeFont(); + + m_stringWidth = sizeFont->getStringWidth(" 8888 x 8888 "); + + struct nxgl_size_s size; + size.w = m_stringWidth, + size.h = (sizeFont->getHeight() + CONFIG_TWM4NX_ICONMGR_VSPACING * 2); + + if (!m_sizeWindow->setSize(&size)) + { + delete m_sizeWindow; + m_sizeWindow = (FAR NXWidgets::CNxTkWindow *)0; + return false; + } + + // 7. Set the initial window position + + struct nxgl_point_s pos = + { + .x = 0, + .y = 0 + }; + + if (!m_sizeWindow->setPosition(&pos)) + { + delete m_sizeWindow; + m_sizeWindow = (FAR NXWidgets::CNxTkWindow *)0; + return false; + } + + return true; +} + +void CResize::resizeFromCenter(FAR CWindow *cwin) +{ + // Get the current frame size and position + + struct nxgl_point_s winpos; + if (!cwin->getFramePosition(&winpos)) + { + return; + } + + struct nxgl_size_s winsize; + if (!cwin->getFrameSize(&winsize)) + { + return; + } + + FAR CResize *resize = m_twm4nx->getResize(); + resize->addingSize(&winsize); + + resize->menuStartResize(cwin, &winpos, &winsize); +} + +/** + * Begin a window resize operation + * + * @param ev the event structure (button press) + * @param cwin the TWM window pointer + */ + +void CResize::startResize(FAR struct SEventMsg *eventmsg, FAR CWindow *cwin) +{ + m_resizeWindow = cwin; + + // Get the current position and size + + if (!cwin->getFramePosition(&m_dragpos)) + { + return; + } + + if (!cwin->getFrameSize(&m_dragsize)) + { + return; + } + + m_dragpos.x += 0; + m_dragpos.y += 0; + m_origpos.x = m_dragpos.x; + m_origpos.y = m_dragpos.y; + m_origsize.w = m_dragsize.w; + m_origsize.h = m_dragsize.h; + m_clamp.pt1.y = 0; + m_clamp.pt2.y = 0; + m_clamp.pt1.x = 0; + m_clamp.pt2.x = 0; + m_delta.x = 0; + m_delta.y = 0; + +#ifdef CONFIG_TWM4NX_AUTO_RERESIZE // Resize relative to position in quad + autoClamp(cwin, eventmsg); +#endif + + FAR CFonts *fonts = m_twm4nx->getFonts(); + FAR NXWidgets::CNxFont *sizeFont = fonts->getSizeFont(); + + struct nxgl_size_s size; + size.w = m_stringWidth + CONFIG_TWM4NX_ICONMGR_HSPACING * 2; + size.h = sizeFont->getHeight() + CONFIG_TWM4NX_ICONMGR_VSPACING * 2; + + // Set the window size + + if (!m_sizeWindow->setSize(&size)) + { + return; + } + + // Move the window to the top of the hierarchy + + m_sizeWindow->raise(); + + m_last.w = 0; + m_last.h = 0; + + displaySize(cwin, &m_origsize); + + // Set the new frame position and size + + if (!cwin->resizeFrame(&m_dragsize, &m_dragpos)) + { + gerr("ERROR: Failed to resize frame\n"); + } +} + +void CResize::menuStartResize(FAR CWindow *cwin, + FAR struct nxgl_point_s *pos, + FAR struct nxgl_size_s *size) +{ + m_dragpos.x = pos->x; + m_dragpos.y = pos->y; + m_origpos.x = m_dragpos.x; + m_origpos.y = m_dragpos.y; + m_origsize.w = size->w; + m_origsize.h = size->h; + m_dragsize.w = size->w; + m_dragsize.h = size->h; + m_clamp.pt1.x = 0; + m_clamp.pt1.y = 0; + m_clamp.pt2.x = 0; + m_clamp.pt2.y = 0; + m_delta.x = 0; + m_delta.y = 0; + m_last.w = 0; + m_last.h = 0; + + FAR CFonts *fonts = m_twm4nx->getFonts(); + FAR NXWidgets::CNxFont *sizeFont = fonts->getSizeFont(); + + // Set the window size + + struct nxgl_size_s winsize; + winsize.w = m_stringWidth + CONFIG_TWM4NX_ICONMGR_HSPACING * 2; + winsize.h = sizeFont->getHeight() + CONFIG_TWM4NX_ICONMGR_VSPACING * 2; + + if (!m_sizeWindow->setSize(&winsize)) + { + return; + } + + // Move the size window it to the top of the hieararchy + + m_sizeWindow->raise(); + displaySize(cwin, &m_origsize); + + // Set the new frame position and size + + if (!cwin->resizeFrame(&m_dragsize, &m_dragpos)) + { + gerr("ERROR: Failed to resize frame\n"); + } +} + +/** + * Begin a window resize operation + * + * @param cwin the Twm4Nx window pointer + */ + +void CResize::addStartResize(FAR CWindow *cwin, + FAR struct nxgl_point_s *pos, + FAR struct nxgl_size_s *size) +{ + m_dragpos.x = pos->x; + m_dragpos.y = pos->y; + m_origpos.x = m_dragpos.x; + m_origpos.y = m_dragpos.y; + m_origsize.w = size->w; + m_origsize.h = size->h; + m_dragsize.w = m_origsize.w; + m_dragsize.h = m_origsize.h; + + m_clamp.pt1.x = 0; + m_clamp.pt1.y = 0; + m_clamp.pt2.x = 0; + m_clamp.pt2.y = 0; + m_delta.x = 0; + m_delta.y = 0; + m_last.w = 0; + m_last.h = 0; + + m_last.w = 0; + m_last.h = 0; + displaySize(cwin, &m_origsize); +} + +/** + * @param cwin The current Twm4Nx window + * @param root The X position in the root window + */ + +void CResize::menuDoResize(FAR CWindow *cwin, + FAR struct nxgl_point_s *root) +{ + int action; + + action = 0; + + root->x -= m_delta.x; + root->y -= m_delta.y; + + if (m_clamp.pt1.y) + { + int delta = root->y - m_dragpos.y; + if (m_dragsize.h - delta < MINHEIGHT) + { + delta = m_dragsize.h - MINHEIGHT; + m_clamp.pt1.y = 0; + } + + m_dragpos.y += delta; + m_dragsize.h -= delta; + action = 1; + } + else if (root->y <= m_dragpos.y) + { + m_dragpos.y = root->y; + m_dragsize.h = m_origpos.y + m_origsize.h - root->y; + m_clamp.pt2.y = 0; + m_clamp.pt1.y = 1; + m_delta.y = 0; + action = 1; + } + + if (m_clamp.pt1.x) + { + int delta = root->x - m_dragpos.x; + if (m_dragsize.w - delta < MINWIDTH) + { + delta = m_dragsize.w - MINWIDTH; + m_clamp.pt1.x = 0; + } + + m_dragpos.x += delta; + m_dragsize.w -= delta; + action = 1; + } + else if (root->x <= m_dragpos.x) + { + m_dragpos.x = root->x; + m_dragsize.w = m_origpos.x + m_origsize.w - root->x; + m_clamp.pt2.x = 0; + m_clamp.pt1.x = 1; + m_delta.x = 0; + action = 1; + } + + if (m_clamp.pt2.y) + { + int delta = root->y - m_dragpos.y - m_dragsize.h; + if (m_dragsize.h + delta < MINHEIGHT) + { + delta = MINHEIGHT - m_dragsize.h; + m_clamp.pt2.y = 0; + } + + m_dragsize.h += delta; + action = 1; + } + else if (root->y >= m_dragpos.y + m_dragsize.h) + { + m_dragpos.y = m_origpos.y; + m_dragsize.h = 1 + root->y - m_dragpos.y; + m_clamp.pt1.y = 0; + m_clamp.pt2.y = 1; + m_delta.y = 0; + action = 1; + } + + if (m_clamp.pt2.x) + { + int delta = root->x - m_dragpos.x - m_dragsize.w; + if (m_dragsize.w + delta < MINWIDTH) + { + delta = MINWIDTH - m_dragsize.w; + m_clamp.pt2.x = 0; + } + + m_dragsize.w += delta; + action = 1; + } + else if (root->x >= m_dragpos.x + m_dragsize.w) + { + m_dragpos.x = m_origpos.x; + m_dragsize.w = 1 + root->x - m_origpos.x; + m_clamp.pt1.x = 0; + m_clamp.pt2.x = 1; + m_delta.x = 0; + action = 1; + } + + if (action) + { + constrainSize(cwin, &m_dragsize); + if (m_clamp.pt1.x) + { + m_dragpos.x = m_origpos.x + m_origsize.w - m_dragsize.w; + } + + if (m_clamp.pt1.y) + { + m_dragpos.y = m_origpos.y + m_origsize.h - m_dragsize.h; + } + + // Set the new frame position and size + + if (!cwin->resizeFrame(&m_dragsize, &m_dragpos)) + { + gerr("ERROR: Failed to resize frame\n"); + } + } + + displaySize(cwin, &m_dragsize); +} + +/** + * Move the rubberband around. This is called for each motion event when + * we are resizing + * + * @param cwin The current Twm4Nx window + * @param root The X position in the root window + */ + +void CResize::doResize(FAR CWindow *cwin, + FAR struct nxgl_point_s *root) +{ + int action; + + action = 0; + + root->x -= m_delta.x; + root->y -= m_delta.y; + + if (m_clamp.pt1.y) + { + int delta = root->y - m_dragpos.y; + if (m_dragsize.h - delta < MINHEIGHT) + { + delta = m_dragsize.h - MINHEIGHT; + m_clamp.pt1.y = 0; + } + + m_dragpos.y += delta; + m_dragsize.h -= delta; + action = 1; + } + else if (root->y <= m_dragpos.y) + { + m_dragpos.y = root->y; + m_dragsize.h = m_origpos.y + m_origsize.h - root->y; + m_clamp.pt2.y = 0; + m_clamp.pt1.y = 1; + m_delta.y = 0; + action = 1; + } + + if (m_clamp.pt1.x) + { + int delta = root->x - m_dragpos.x; + if (m_dragsize.w - delta < MINWIDTH) + { + delta = m_dragsize.w - MINWIDTH; + m_clamp.pt1.x = 0; + } + + m_dragpos.x += delta; + m_dragsize.w -= delta; + action = 1; + } + else if (root->x <= m_dragpos.x) + { + m_dragpos.x = root->x; + m_dragsize.w = m_origpos.x + m_origsize.w - root->x; + m_clamp.pt2.x = 0; + m_clamp.pt1.x = 1; + m_delta.x = 0; + action = 1; + } + + if (m_clamp.pt2.y) + { + int delta = root->y - m_dragpos.y - m_dragsize.h; + if (m_dragsize.h + delta < MINHEIGHT) + { + delta = MINHEIGHT - m_dragsize.h; + m_clamp.pt2.y = 0; + } + + m_dragsize.h += delta; + action = 1; + } + else if (root->y >= m_dragpos.y + m_dragsize.h - 1) + { + m_dragpos.y = m_origpos.y; + m_dragsize.h = 1 + root->y - m_dragpos.y; + m_clamp.pt1.y = 0; + m_clamp.pt2.y = 1; + m_delta.y = 0; + action = 1; + } + + if (m_clamp.pt2.x) + { + int delta = root->x - m_dragpos.x - m_dragsize.w; + if (m_dragsize.w + delta < MINWIDTH) + { + delta = MINWIDTH - m_dragsize.w; + m_clamp.pt2.x = 0; + } + + m_dragsize.w += delta; + action = 1; + } + else if (root->x >= m_dragpos.x + m_dragsize.w - 1) + { + m_dragpos.x = m_origpos.x; + m_dragsize.w = 1 + root->x - m_origpos.x; + m_clamp.pt1.x = 0; + m_clamp.pt2.x = 1; + m_delta.x = 0; + action = 1; + } + + if (action) + { + constrainSize(cwin, &m_dragsize); + if (m_clamp.pt1.x) + { + m_dragpos.x = m_origpos.x + m_origsize.w - m_dragsize.w; + } + + if (m_clamp.pt1.y) + { + m_dragpos.y = m_origpos.y + m_origsize.h - m_dragsize.h; + } + + // Set the new frame position and size + + if (!cwin->resizeFrame(&m_dragsize, &m_dragpos)) + { + gerr("ERROR: Failed to resize frame\n"); + } + } + + displaySize(cwin, &m_dragsize); +} + +/** + * Finish the resize operation + */ + +void CResize::endResize(FAR CWindow *cwin) +{ + struct nxgl_point_s pos = + { + .x = 0, + .y = 0 + }; + + struct nxgl_size_s size = + { + .w = 0, + .h = 0 + }; + + if (!cwin->resizeFrame(&size, &pos)) + { + gerr("ERROR: Failed to resize frame\n"); + } + + constrainSize(cwin, &m_dragsize); + + struct nxgl_size_s framesize; + cwin->getFrameSize(&framesize); + + if (m_dragsize.w != framesize.w || m_dragsize.h != framesize.h) + { + cwin->setZoom(ZOOM_NONE); + } + + setupWindow(cwin, &m_dragpos, &m_dragsize); + + if (cwin->isIconMgr()) + { + CIconMgr *iconMgr = cwin->getIconMgr(); + DEBUGASSERT(iconMgr != (CIconMgr *)0); + + unsigned int currcol = iconMgr->getCurrColumn(); + if (currcol == 0) + { + currcol = 1; + } + + struct nxgl_size_s iconMgrSize; + iconMgr->getSize(&iconMgrSize); + + iconMgrSize.w = (unsigned int) + ((m_dragsize.w * (unsigned long)iconMgr->getColumns()) / currcol); + + cwin->resizeFrame(&iconMgrSize, &pos); + iconMgr->pack(); + } + + cwin->raiseWindow(); + m_resizeWindow = (FAR CWindow *)0; +} + +void CResize::menuEndResize(FAR CWindow *cwin) +{ + struct nxgl_point_s pos = + { + .x = 0, + .y = 0 + }; + + struct nxgl_size_s size = + { + .w = 0, + .h = 0 + }; + + // Set the window frame size (and position) + + if (!cwin->resizeFrame(&size, &pos)) + { + gerr("ERROR: CWindow::resizeFrame() failed\n"); + } + + constrainSize(cwin, &m_dragsize); + setupWindow(cwin, &m_dragpos, &m_dragsize); +} + +/** + * Finish the resize operation for AddWindowindowToFrameSize(&nullSize, &minSize); + + // Clip to minimim size + + if (size->w < minSize.w) + { + size->w = minSize.w; + } + + if (size->h < minSize.h) + { + size->h = minSize.h; + } + + // Get the maximum window size from CTwm4Nx + + struct nxgl_size_s maxSize; + m_twm4nx->maxWindowSize(&maxSize); + + // Clip to maximim size + + if (size->w > maxSize.w) + { + size->w = maxSize.w; + } + + if (size->h > maxSize.h) + { + size->h = maxSize.h; + } +} + +/** + * Set window sizes. + * + * Special Considerations: + * This routine will check to make sure the window is not completely off the + * display, if it is, it'll bring some of it back on. + * + * The cwin->frame_XXX variables should NOT be updated with the values of + * x,y,w,h prior to calling this routine, since the new values are compared + * against the old to see whether a synthetic ConfigureNotify event should be + * sent. (It should be sent if the window was moved but not resized.) + * + * @param cwin The CWindow instance + * @param pos The position of the upper-left outer corner of the frame + * @param size The size of the frame window + */ + +void CResize::setupWindow(FAR CWindow *cwin, FAR nxgl_point_s *pos, + FAR nxgl_size_s *size) +{ + ginfo("pos={%d, %d} size={%d, %d}\n", + pos->x, pos->y, size->w, size->h); + + // Clip the position the so that it is within the display (with a little + // extra space for the cursor) + + struct nxgl_size_s displaySize; + m_twm4nx->getDisplaySize(&displaySize); + + if (pos->x >= displaySize.w - 16) + { + pos->x = displaySize.w - 16; // one "average" cursor width + } + + if (pos->y >= displaySize.h - 16) + { + pos->y = displaySize.h - 16; // one "average" cursor width + } + + if (cwin->isIconMgr()) + { + struct nxgl_size_s imsize; + cwin->getFrameSize(&imsize); + size->h = imsize.h; + } + + // Set the window frame size (and position) + + if (!cwin->resizeFrame(size, pos)) + { + gerr("ERROR: CWindow::resizeFrame() failed\n"); + } +} + +/** + * Zooms window to full height of screen or to full height and width of screen. + * (Toggles so that it can undo the zoom - even when switching between fullZoom + * and vertical zoom.) + * + * @param cwin the TWM window pointer + */ + +void CResize::fullZoom(FAR CWindow *cwin, int flag) +{ + // Get the current position and size + + if (!cwin->getFramePosition(&m_dragpos)) + { + return; + } + + if (!cwin->getFrameSize(&m_dragsize)) + { + return; + } + + struct nxgl_point_s base; + base.x = 0; + base.y = 0; + + uint16_t zoom = cwin->getZoom(); + if (zoom == flag) + { + cwin->getFramePosition(&m_dragpos); + cwin->getFrameSize(&m_dragsize); + cwin->setZoom(ZOOM_NONE); + } + else + { + if (zoom == ZOOM_NONE) + { + cwin->resizeFrame(&m_dragsize, &m_dragpos); + } + + cwin->setZoom(flag); + + struct nxgl_size_s displaySize; + m_twm4nx->getDisplaySize(&displaySize); + + switch (flag) + { + case ZOOM_NONE: + break; + + case EVENT_RESIZE_VERTZOOM: + m_dragsize.h = displaySize.h; + m_dragpos.y = base.y; + break; + + case EVENT_RESIZE_HORIZOOM: + m_dragpos.x = base.x; + m_dragsize.w = displaySize.w; + break; + + case EVENT_RESIZE_FULLZOOM: + m_dragpos.x = base.x; + m_dragpos.y = base.y; + m_dragsize.h = displaySize.h; + m_dragsize.w = displaySize.w; + break; + + case EVENT_RESIZE_LEFTZOOM: + m_dragpos.x = base.x; + m_dragpos.y = base.y; + m_dragsize.h = displaySize.h; + m_dragsize.w = displaySize.w / 2; + break; + + case EVENT_RESIZE_RIGHTZOOM: + m_dragpos.x = base.x + displaySize.w / 2; + m_dragpos.y = base.y; + m_dragsize.h = displaySize.h; + m_dragsize.w = displaySize.w / 2; + break; + + case EVENT_RESIZE_TOPZOOM: + m_dragpos.x = base.x; + m_dragpos.y = base.y; + m_dragsize.h = displaySize.h / 2; + m_dragsize.w = displaySize.w; + break; + + case EVENT_RESIZE_BOTTOMZOOM: + m_dragpos.x = base.x; + m_dragpos.y = base.y + displaySize.h / 2; + m_dragsize.h = displaySize.h / 2; + m_dragsize.w = displaySize.w; + break; + } + } + + cwin->raiseWindow(); + constrainSize(cwin, &m_dragsize); + setupWindow(cwin, &m_dragpos, &m_dragsize); +} + +/** + * Handle RESIZE events. + * + * @param eventmsg. The received NxWidget RESIZE event message. + * @return True if the message was properly handled. false is + * return on any failure. + */ + +bool CResize::event(FAR struct SEventMsg *eventmsg) +{ + bool success = true; + + switch (eventmsg->eventID) + { + case EVENT_RESIZE_START: // Start window resize + { + // Can't resize icons + + FAR CWindow *cwin = (FAR CWindow *)eventmsg->obj; + DEBUGASSERT(cwin != (FAR CWindow *)0); + + if (cwin->isIconMgr()) + { + // Check for resize from a menu + + if (eventmsg->context == EVENT_CONTEXT_FRAME || + eventmsg->context == EVENT_CONTEXT_WINDOW || + eventmsg->context == EVENT_CONTEXT_TITLE) + { + resizeFromCenter(cwin); + } + else + { + startResize(eventmsg, cwin); + } + } + } + break; + + case EVENT_RESIZE_VERTZOOM: // Zoom vertically only + case EVENT_RESIZE_HORIZOOM: // Zoom horizontally only + case EVENT_RESIZE_FULLZOOM: // Zoom both vertically and horizontally + case EVENT_RESIZE_LEFTZOOM: // Zoom left only + case EVENT_RESIZE_RIGHTZOOM: // Zoom right only + case EVENT_RESIZE_TOPZOOM: // Zoom top only + case EVENT_RESIZE_BOTTOMZOOM: // Zoom bottom only + fullZoom((FAR CWindow *)eventmsg->obj, eventmsg->eventID); + break; + + default: + success = false; + break; + } + + return success; +} + +#ifdef CONFIG_TWM4NX_AUTO_RERESIZE // Resize relative to position in quad +void CResize::autoClamp(FAR CWindow *cwin, + FAR struct SEventMsg *eventmsg *eventmsg) +{ + FAR NXWidgets::CNxTkWindow *root; + struct nxgl_point_s pos; + int h; + int v; + unsigned int mask; + + switch (eventmsg->type) + { + case ButtonPress: + pos.x = eventmsg->pos.x; + pos.y = eventmsg->pos.y; + break; + + case KeyPress: + pos.x = eventmsg->pos.x; + pos.y = eventmsg->pos.y; + break; + + default: + // Root window position + + root.x = 0; // REVISIT + root.y = 0; + + // Relative window position + + if (!xxx->getPosition(&pos)) + { + return; + } + } + + h = ((pos.x - m_dragpos.x) / (m_dragsize.w < 3 ? 1 : (m_dragsize.w / 3))); + v = ((pos.y - m_dragpos.y) / (m_dragsize.h < 3 ? 1 : (m_dragsize.h / 3))); + + if (h <= 0) + { + m_clamp.pt1.x = 1; + m_delta.x = (pos.x - m_dragpos.x); + } + else if (h >= 2) + { + m_clamp.pt2.x = 1; + m_delta.x = (pos.x - m_dragpos.x - m_dragsize.w); + } + + if (v <= 0) + { + m_clamp.pt1.y = 1; + m_delta.y = (pos.y - m_dragpos.y); + } + else if (v >= 2) + { + m_clamp.pt2.y = 1; + m_delta.y = (pos.y - m_dragpos.y - m_dragsize.h); + } +} +#endif + +/** + * Display the size in the dimensions window. + * + * @param cwin The current window being resize + * @param size She size of the rubber band + */ + +void CResize::displaySize(FAR CWindow *cwin, FAR struct nxgl_size_s *size) +{ + if (m_last.w == size->w && m_last.h == size->h) + { + return; + } + + m_last.w = size->w; + m_last.h = size->h; + + char str[100]; + (void)snprintf(str, sizeof(str), " %4d x %-4d ", size->w, size->h); + + m_sizeWindow->raise(); + +#warning Missing logic +#if 0 + FAR CFonts *fonts = m_twm4nx->getFonts(); + FAR NXWidgets::CNxFont *sizeFont = fonts->getSizeFont(); + + // Show the string in the CLable in the size window + + // REVISIT: This no longer exists + fonts->renderString(m_twm4nx, m_sizeWindow, sizeFont, + CONFIG_TWM4NX_ICONMGR_HSPACING, + sizeFont->getHeight() + CONFIG_TWM4NX_ICONMGR_VSPACING, str); +#endif +} diff --git a/graphics/twm4nx/src/ctwm4nx.cxx b/graphics/twm4nx/src/ctwm4nx.cxx new file mode 100644 index 000000000..18e008254 --- /dev/null +++ b/graphics/twm4nx/src/ctwm4nx.cxx @@ -0,0 +1,596 @@ +///////////////////////////////////////////////////////////////////////////// +// apps/graphics/twm4nx/src/ctwm4nx.cxx +// Twm4Nx - "Tom's Window Manager" for the NuttX NX Server +// +// Copyright (C) 2019 Gregory Nutt. All rights reserved. +// Author: Gregory Nutt +// +// Largely an original work but derives from TWM 1.0.10 in many ways: +// +// Copyright 1989,1998 The Open Group +// Copyright 1988 by Evans & Sutherland Computer Corporation, +// +// Please refer to apps/twm4nx/COPYING for detailed copyright information. +// +// 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 +#include + +#include +#include +#include + +#include +#include +#include + +#include "platform/cxxinitialize.h" + +#include "graphics/twm4nx/twm4nx_config.hxx" +#include "graphics/twm4nx/ctwm4nx.hxx" +#include "graphics/twm4nx/cbackground.hxx" +#include "graphics/twm4nx/cwindow.hxx" +#include "graphics/twm4nx/cwindowfactory.hxx" +#include "graphics/twm4nx/cwindowevent.hxx" +#include "graphics/twm4nx/cinput.hxx" +#include "graphics/twm4nx/cicon.hxx" +#include "graphics/twm4nx/ciconwin.hxx" +#include "graphics/twm4nx/ciconmgr.hxx" +#include "graphics/twm4nx/cmenus.hxx" +#include "graphics/twm4nx/cresize.hxx" +#include "graphics/twm4nx/cfonts.hxx" +#include "graphics/twm4nx/twm4nx_widgetevents.hxx" + +///////////////////////////////////////////////////////////////////////////// +// Pre-processor Definitions +///////////////////////////////////////////////////////////////////////////// + +#define DEFAULT_NICE_FONT "variable" +#define DEFAULT_FAST_FONT "fixed" + +///////////////////////////////////////////////////////////////////////////// +// Public Function Prototypes +///////////////////////////////////////////////////////////////////////////// + +// Suppress name-mangling + +#ifdef BUILD_MODULE +extern "C" int main(int argc, FAR char *argv[]); +#else +extern "C" int twm4nx_main(int argc, char *argv[]); +#endif + +///////////////////////////////////////////////////////////////////////////// +// Public Data +///////////////////////////////////////////////////////////////////////////// + +using namespace Twm4Nx; + +const char Twm4Nx::GNoName[] = "Untitled"; // Name if no name is specified + +///////////////////////////////////////////////////////////////////////////// +// CTwm4Nx Implementation +///////////////////////////////////////////////////////////////////////////// + +/** + * CTwm4Nx Constructor + * + * @param display. Indicates which display will be used. Usually zero + * except in the case wehre there of multiple displays. + */ + +CTwm4Nx::CTwm4Nx(int display) +{ + m_display = display; + m_eventq = (mqd_t)-1; + m_background = (FAR CBackground *)0; + m_input = (FAR CInput *)0; + m_icon = (FAR CIcon *)0; + m_iconmgr = (FAR CIconMgr *)0; + m_factory = (FAR CWindowFactory *)0; + m_fonts = (FAR CFonts *)0; + m_resize = (FAR CResize *)0; +} + +/** + * CTwm4Nx Destructor + */ + +CTwm4Nx::~CTwm4Nx(void) +{ + cleanup(); +} + +/** + * This is the main, controlling thread of the window manager. It is + * called only from the extern "C" main() entry point. + * + * NOTE: In the event of truly abnormal conditions, this function will + * not return. It will exit via the abort() method. + * + * @return True if the window manager was terminated properly. false is + * return on any failure. + */ + +bool CTwm4Nx::run(void) +{ + // Open a message queue to receive NxWidget-related events. We need to + // do this early so that the messasge queue name will be available to + // constructors + + genMqName(); // Generate a random message queue name + m_eventq = mq_open(m_queueName, O_RDONLY | O_CREAT, 0666); + if (m_eventq == (mqd_t)-1) + { + gerr("ERROR: Failed open message queue '%s': %d\n", + m_queueName, errno); + cleanup(); + return false; + } + +#if defined(CONFIG_HAVE_CXX) && defined(CONFIG_HAVE_CXXINITIALIZE) + // Call all C++ static constructors + + up_cxxinitialize(); +#endif + +#if defined(CONFIG_LIB_BOARDCTL) && !defined(CONFIG_BOARD_LATE_INITIALIZE) + // Should we perform board-specific initialization? There are two ways + // that board initialization can occur: 1) automatically via + // board_late_initialize() during bootup if CONFIG_BOARD_LATE_INITIALIZE, or + // 2) here via a call to boardctl() if the interface is enabled + // (CONFIG_LIB_BOARDCTL=y). + + (void)boardctl(BOARDIOC_INIT, 0); +#endif + + // Connect to the NX server + + if (!connect()) + { + gerr("ERROR: Failed to connect to the NX server\n"); + cleanup(); + return false; + } + + // Get the background up as soon as possible + + m_background = new CBackground(this); + if (m_background == (FAR CBackground *)0) + { + gerr("ERROR: Failed to create CBackground\n"); + cleanup(); + return false; + } + + // Paint the background image + + if (!m_background->setBackgroundImage(&CONFIG_TWM4NX_BACKGROUND_IMAGE)) + { + gerr("ERROR: Failed to set backgournd image\n"); + cleanup(); + return false; + } + + // Get the size of the display (which is equivalent to size of the + // background window). + + m_background->getDisplaySize(m_displaySize); + + DEBUGASSERT((unsigned int)m_displaySize.w <= INT16_MAX && + (unsigned int)m_displaySize.h <= INT16_MAX); + + m_maxWindow.w = INT16_MAX - m_displaySize.w; + m_maxWindow.h = INT16_MAX - m_displaySize.w; + + // Create the keyboard/mouse input device thread + + m_input = new CInput(this); + if (m_input == (CInput *)0) + { + gerr("ERROR: Failed to create CInput\n"); + cleanup(); + return false; + } + + if (!m_input->start()) + { + gerr("ERROR: Failed start the keyboard/mouse listener\n"); + cleanup(); + return false; + } + + // Create the Icon Manager + + m_iconmgr = new CIconMgr(this, 4); + if (m_iconmgr == (CIconMgr *)0) + { + cleanup(); + return false; + } + + if (!m_iconmgr->initialize("Twm4Nx")) + { + cleanup(); + return false; + } + + // Cache a CIcon instance for use across the session + + m_icon = new CIcon(this); + if (m_iconmgr == (CIconMgr *)0) + { + cleanup(); + return false; + } + + // Cache a CFonts instance for use across the session + + m_fonts = new CFonts(this); + if (m_fonts == (CFonts *)0) + { + cleanup(); + return false; + } + + // Create all fonts + + if (!m_fonts->initialize()) + { + cleanup(); + return false; + } + + // Cache a CWindowFactory instance for use across the session + + m_factory = new CWindowFactory(this); + if (m_factory == (CWindowFactory *)0) + { + cleanup(); + return false; + } + + // Cache a CResize instance for use across the session + + m_resize = new CResize(this); + if (m_resize == (CResize *)0) + { + cleanup(); + return false; + } + + if (!m_resize->initialize()) + { + cleanup(); + return false; + } + + // Enter the event loop + + for (; ; ) + { + // Wait for the next NxWidget event + + struct SEventMsg eventmsg; + int ret = mq_receive(m_eventq, (FAR char *)&eventmsg, + sizeof(struct SEventMsg), (FAR unsigned int *)0); + if (ret < 0) + { + gerr("ERROR: mq_receive failed: %d\n", errno); + cleanup(); + return false; + } + + // Dispatch the new event + + if (!dispatchEvent(&eventmsg)) + { + gerr("ERROR: dispatchEvent failed\n"); + cleanup(); + return false; + } + } + + return true; // Not reachable +} + +/** + * Connect to the NX server + * + * @return True if the message was properly handled. false is + * return on any failure. + */ + +bool CTwm4Nx::connect(void) +{ + // Connect to the server + + bool nxConnected = CNxServer::connect(); + if (nxConnected) + { + // Set the background color + + if (!setBackgroundColor(CONFIG_TWM4NX_DEFAULT_BACKGROUNDCOLOR)) + { + // Failed + } + } + + return nxConnected; +} + +/** + * Generate a random message queue name. Different message queue + * names are required for each instance of Twm4Nx that is started. + */ + +void CTwm4Nx::genMqName(void) +{ + unsigned long randvalue = + (unsigned long)std::random() & 0x00fffffful; + + (void)std::asprintf(&m_queueName, "Twm4Nx%06ul", randvalue); +} + +/** + * Handle SYSTEM events. + * + * @param eventmsg. The received NxWidget event message. + * @return True if the message was properly handled. false is + * return on any failure. + */ + +bool CTwm4Nx::systemEvent(FAR struct SEventMsg *eventmsg) +{ + switch (eventmsg->eventID) + { + case EVENT_SYSTEM_ERROR: // Report system error + // REVISIT: An audible tone should be generated + break; + + case EVENT_SYSTEM_EXIT: // Terminate the Twm4Nx session + abort(); + break; // Does not return + + default: + return false; + } + + return true; +}; + +/** + * Dispatch NxWidget-related events. + * + * @param eventmsg. The received NxWidget event message. + * @return True if the message was properly dispatched. false is + * return on any failure. + */ + +bool CTwm4Nx::dispatchEvent(FAR struct SEventMsg *eventmsg) +{ + enum EEventRecipient recipient = + (enum EEventRecipient)(eventmsg->eventID & EVENT_RECIPIENT_MASK); + + bool ret = false; + switch (recipient) + { + case EVENT_RECIPIENT_MSG: // NX message event + ret = CWindowEvent::event(eventmsg); + break; + + case EVENT_RECIPIENT_SYSTEM: // Twm4Nx system event + ret = systemEvent(eventmsg); + break; + + case EVENT_RECIPIENT_ICONWIN: // Icon window event + { + FAR CIconWin *iconWin = (FAR CIconWin *)eventmsg->obj; + DEBUGASSERT(iconWin != (FAR CIconWin *)0); + ret = iconWin->event(eventmsg); + } + break; + + case EVENT_RECIPIENT_ICONMGR: // Icon Manager event + ret = m_iconmgr->event(eventmsg); + break; + + case EVENT_RECIPIENT_MENU: // Menu related event + { + FAR CMenus *menus = (FAR CMenus *)eventmsg->obj; + DEBUGASSERT(menus != (FAR CMenus *)0); + ret = menus->event(eventmsg); + } + break; + + case EVENT_RECIPIENT_WINDOW: // Window related event + case EVENT_RECIPIENT_TOOLBAR: // Toolbar related event + case EVENT_RECIPIENT_BORDER: // Window border related event + ret = m_factory->event(eventmsg); + break; + + case EVENT_RECIPIENT_RESIZE: // Windw resize event + ret = m_resize->event(eventmsg); + break; + + case EVENT_RECIPIENT_MASK: // Used to isolate recipient + default: + break; + } + + return ret; +} + +/** + * Cleanup and exit Twm4Nx abnormally. + */ + +void CTwm4Nx::abort() +{ + cleanup(); + std::exit(EXIT_FAILURE); +} + +/** + * Cleanup in preparation for termination. + */ + +void CTwm4Nx::cleanup() +{ + // Close the NxWidget event message queue + + if (m_eventq != (mqd_t)-1) + { + (void)mq_close(m_eventq); + m_eventq = (mqd_t)-1; + } + + // Delete the background + + if (m_background != (FAR CBackground *)0) + { + delete m_background; + m_background = (FAR CBackground *)0; + } + + // Halt the keyboard/mouse listener and destroy the CInput class + + if (m_input != (CInput *)0) + { + delete m_input; + m_input = (CInput *)0; + } + + // Free the Icon Manager + + if (m_iconmgr != (CIconMgr *)0) + { + delete m_iconmgr; + m_iconmgr = (CIconMgr *)0; + } + + // Free the session CWindowFactory instance + + if (m_factory != (CWindowFactory *)0) + { + delete m_factory; + m_factory = (CWindowFactory *)0; + } + + // Free the session CResize instance + + if (m_resize != (CResize *)0) + { + delete m_resize; + m_resize = (CResize *)0; + } + + CNxServer::disconnect(); +} + +///////////////////////////////////////////////////////////////////////////// +// Public Functions +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Name: main/twm4nx_main +// +// Description: +// Start of TWM +// +///////////////////////////////////////////////////////////////////////////// + +#ifdef BUILD_MODULE +int main(int argc, FAR char *argv[]) +#else +int twm4nx_main(int argc, char *argv[]) +#endif +{ + int display = 0; + + for (int i = 1; i < argc; i++) + { + if (argv[i][0] == '-') + { + switch (argv[i][1]) + { + case 'd': // -display + if (std::strcmp(&argv[i][1], "display")) + { + goto usage; + } + + if (++i >= argc) + { + goto usage; + } + + display = atoi(argv[i]); + continue; + } + } + + usage: + gerr("Usage: %s [-display ]\n", argv[0]); + return EXIT_FAILURE; + } + + /* Create an instance of CTwm4Nx and and run it */ + + FAR CTwm4Nx *twm4nx = new CTwm4Nx(display); + if (twm4nx == (FAR CTwm4Nx *)0) + { + gerr("ERROR: Failed to instantiate CTwm4Nx\n"); + return EXIT_FAILURE; + } + + // Start the window manager + + bool success = twm4nx->run(); + if (!success) + { + gerr(" ERROR: Terminating due to failure\n"); + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} diff --git a/graphics/twm4nx/src/cwindow.cxx b/graphics/twm4nx/src/cwindow.cxx new file mode 100644 index 000000000..78dd3a270 --- /dev/null +++ b/graphics/twm4nx/src/cwindow.cxx @@ -0,0 +1,1229 @@ +///////////////////////////////////////////////////////////////////////////// +// apps/graphics/twm4nx/src/cwindow.cxx +// Represents one window instance +// +// Copyright (C) 2019 Gregory Nutt. All rights reserved. +// Author: Gregory Nutt +// +// Largely an original work but derives from TWM 1.0.10 in many ways: +// +// Copyright 1989,1998 The Open Group +// Copyright 1988 by Evans & Sutherland Computer Corporation, +// +// Please refer to apps/twm4nx/COPYING for detailed copyright information. +// +// 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 + +#include + +#include "graphics/nxglyphs.hxx" + +#include "graphics/nxwidgets/cnxtkwindow.hxx" +#include "graphics/nxwidgets/cnxtoolbar.hxx" +#include "graphics/nxwidgets/crlepalettebitmap.hxx" +#include "graphics/nxwidgets/cscaledbitmap.hxx" +#include "graphics/nxwidgets/cimage.hxx" +#include "graphics/nxwidgets/clabel.hxx" +#include "graphics/nxwidgets/cnxfont.hxx" + +#include "graphics/twm4nx/twm4nx_config.hxx" +#include "graphics/twm4nx/ctwm4nx.hxx" +#include "graphics/twm4nx/cfonts.hxx" +#include "graphics/twm4nx/cresize.hxx" +#include "graphics/twm4nx/ciconwin.hxx" +#include "graphics/twm4nx/ciconmgr.hxx" +#include "graphics/twm4nx/cwindowevent.hxx" +#include "graphics/twm4nx/cwindow.hxx" +#include "graphics/twm4nx/cwindowfactory.hxx" +#include "graphics/twm4nx/twm4nx_widgetevents.hxx" +#include "graphics/twm4nx/twm4nx_cursor.hxx" + +///////////////////////////////////////////////////////////////////////////// +// Private Data +///////////////////////////////////////////////////////////////////////////// + +using namespace Twm4Nx; + +// Association of configured bitmaps with buttons + +static FAR const NXWidgets::SRlePaletteBitmap *GTbBitmaps[NTOOLBAR_BUTTONS] = +{ + &CONFIG_TWM4NX_MENU_IMAGE, // MENU_BUTTON (first on left) + &CONFIG_TWM4NX_TERMINATE_IMAGE, // DELETE_BUTTON (first on right) + &CONFIG_TWM4NX_RESIZE_IMAGE, // RESIZE_BUTTON + &CONFIG_TWM4NX_MINIMIZE_IMAGE // MINIMIZE_BUTTON +}; + +static bool GButtonRightSide[NTOOLBAR_BUTTONS] = +{ + false, true, true, true, +}; + +///////////////////////////////////////////////////////////////////////////// +// CWindow Implementation +///////////////////////////////////////////////////////////////////////////// + +/** + * CWindow Constructor + * + * @param twm4nx. Twm4Nx session + */ + +CWindow::CWindow(CTwm4Nx *twm4nx) +{ + m_twm4nx = twm4nx; // Save the Twm4Nx session + m_eventq = (mqd_t)-1; // No widget message queue yet + + // Windows + + m_nxWin = (FAR NXWidgets::CNxTkWindow *)0; + m_toolbar = (FAR NXWidgets::CNxToolbar *)0; + m_zoom = ZOOM_NONE; + m_modal = false; + + // Toolbar + + m_tbTitle = (FAR NXWidgets::CLabel *)0; + m_tbHeight = 0; // Height of the toolbar + m_tbLeftX = 0; // Temporaries + m_tbRightX = 0; + + // Icons/Icon Manager + + m_iconWin = (FAR CIconWin *)0; + m_iconMgr = (FAR CIconMgr *)0; + m_isIconMgr = false; + m_iconOn = false; + m_iconified = false; + + // Dragging + + m_drag = false; + m_dragOffset.x = 0; + m_dragOffset.y = 0; + m_dragCSize.w = 0; + m_dragCSize.h = 0; + + // Toolbar buttons + + std::memset(m_tbButtons, 0, NTOOLBAR_BUTTONS * sizeof(NXWidgets::CImage *)); +} + +/** + * CWindow Destructor + */ + +CWindow::~CWindow(void) +{ + cleanup(); +} + +/** + * CWindow Initializer (unlike the constructor, this may fail) + * + * @param name The the name of the window (and its icon) + * @param pos The initialize position of the window + * @param size The initial size of the window + * @param sbitmap The Icon bitmap image + * @param isIconMgr Flag to tell if this is an icon manager window + * @param iconMgr Pointer to icon manager instance + * @param noToolbar True: Don't add Title Bar + * @return True if the window was successfully initialize; false on + * any failure, + */ + +bool CWindow::initialize(FAR const char *name, + FAR const struct nxgl_point_s *pos, + FAR const struct nxgl_size_s *size, + FAR const struct NXWidgets::SRlePaletteBitmap *sbitmap, + bool isIconMgr, FAR CIconMgr *iconMgr, + bool noToolbar) +{ + // Open a message queue to send fully digested NxWidget events. + + FAR const char *mqname = m_twm4nx->getEventQueueName(); + + m_eventq = mq_open(mqname, O_WRONLY); + if (m_eventq == (mqd_t)-1) + { + gerr("ERROR: Failed open message queue '%s': %d\n", + mqname, errno); + return false; + } + + m_isIconMgr = isIconMgr; + m_iconMgr = iconMgr; + + if (name == (FAR const char *)0) + { + m_name = std::strdup(GNoName); + } + else + { + m_name = std::strdup(name); + } + + // Do initial clip to the maximum window size + + struct nxgl_size_s maxWindow; + m_twm4nx->maxWindowSize(&maxWindow); + + struct nxgl_size_s winsize; + winsize.w = size->w; + if (winsize.w > maxWindow.w) + { + winsize.w = maxWindow.w; + } + + winsize.h = size->h; + if (winsize.h > maxWindow.h) + { + winsize.h = maxWindow.h; + } + + m_iconOn = false; + + // Create the window + + m_nxWin = (FAR NXWidgets::CNxTkWindow *)0; + m_toolbar = (FAR NXWidgets::CNxToolbar *)0; + + // Create the main window + + if (!createMainWindow(&winsize, pos)) + { + gerr("ERROR: createMainWindow() failed\n"); + cleanup(); + return false; + } + + m_tbHeight = 0; + m_toolbar = (FAR NXWidgets::CNxToolbar *)0; + + if (!noToolbar) + { + // Toolbar height should be based on size of images and fonts. + + if (!getToolbarHeight(name)) + { + gerr("ERROR: getToolbarHeight() failed\n"); + cleanup(); + return false; + } + + // Create the toolbar + + if (!createToolbar()) + { + gerr("ERROR: createToolbar() failed\n"); + cleanup(); + return false; + } + + // Add buttons to the toolbar + + if (!createToolbarButtons()) + { + gerr("ERROR: createToolbarButtons() failed\n"); + cleanup(); + return false; + } + + // Add the title to the toolbar + + if (!createToolbarTitle(name)) + { + gerr("ERROR: createToolbarTitle() failed\n"); + cleanup(); + return false; + } + } + + // Create and initialize the icon window + + m_iconWin = new CIconWin(m_twm4nx); + if (m_iconWin == (FAR CIconWin *)0) + { + gerr("ERROR: Failed to create the icon Window\n"); + cleanup(); + return false; + } + + if (!m_iconWin->initialize(this, sbitmap, pos)) + { + gerr("ERROR: Failed to initialize the icon Window\n"); + cleanup(); + return false; + } + + enableWidgets(); + return true; +} + +/** + * Get the raw window size (including toolbar and frame) + * + * @param framesize Location to return the window frame size + */ + +bool CWindow::getFrameSize(FAR struct nxgl_size_s *framesize) +{ + // Get the window size + + struct nxgl_size_s winsize; + bool success = getWindowSize(&winsize); + if (success) + { + // Convert the window size to the frame size + + windowToFrameSize(&winsize, framesize); + } + + return success; +} + +/** + * Update the window frame after a resize operation (includes the toolbar + * and user window) + * + * @param size The new window frame size + * @param pos The frame location which may also have changed + */ + +bool CWindow::resizeFrame(FAR const struct nxgl_size_s *size, + FAR struct nxgl_point_s *pos) +{ + // Account for toolbar and border + + struct nxgl_size_s delta; + delta.w = 2 * CONFIG_NXTK_BORDERWIDTH; + delta.h = m_tbHeight + 2 * CONFIG_NXTK_BORDERWIDTH; + + // Don't set the window size smaller than one pixel + + struct nxgl_size_s winsize; + if (size->w <= delta.w) + { + winsize.w = 1; + } + else + { + winsize.w = size->w - delta.w; + } + + if (size->h <= delta.h) + { + winsize.h = 1; + } + else + { + winsize.h = size->h - delta.h; + } + + // Set the usable window size + + bool success = m_nxWin->setSize(&winsize); + if (!success) + { + gerr("ERROR: Failed to setSize()\n"); + return false; + } + + // Set the new frame position (in case it changed too) + + success = setFramePosition(pos); + if (!success) + { + gerr("ERROR: Failed to setSize()\n"); + return false; + } + + // Synchronize with the NX server to make sure that the new geometry is + // truly in effect. + + m_nxWin->synchronize(); + + // Then update the toolbar layout + + return updateToolbarLayout(); +} + +/** + * Get the window frame position (accounting for toolbar and frame) + * + * @param size Location to return the window frame position + */ + +bool CWindow::getFramePosition(FAR struct nxgl_point_s *framepos) +{ + // Get the window position + + struct nxgl_point_s winpos; + bool success = m_nxWin->getPosition(&winpos); + if (success) + { + // Convert the window position to a frame position + + windowToFramePos(&winpos, framepos); + } + + return success; +} + +/** + * Set the window frame position (accounting for toolbar and frame) + * + * @param size The new raw window position + */ + +bool CWindow::setFramePosition(FAR const struct nxgl_point_s *framepos) +{ + // Convert the frame position to the contained, primary window positio + + struct nxgl_point_s winpos; + frameToWindowPos(framepos, &winpos); + + // And set the window position + + return m_nxWin->setPosition(&winpos); +} + +void CWindow::iconify(void) +{ + if (!isIconified()) + { + // Make sure to exit any modal state before minimizing + + m_modal = false; + m_nxWin->modal(false); + + // Raise the icon window and lower the main window + + m_iconified = true; + m_nxWin->lower(); + m_iconWin->raise(); + m_iconOn = true; + m_nxWin->synchronize(); + } +} + +void CWindow::deIconify(void) +{ + // De-iconify the window + + if (isIconified()) + { + // Raise the main window and lower the icon window + + m_iconified = false; + m_iconWin->lower(); + m_nxWin->raise(); + m_iconOn = false; + m_nxWin->synchronize(); + } +} + +/** + * Handle WINDOW events. + * + * @param eventmsg. The received NxWidget WINDOW event message. + * @return True if the message was properly handled. false is + * return on any failure. + */ + +bool CWindow::event(FAR struct SEventMsg *eventmsg) +{ + FAR NXWidgets::CNxTkWindow *nxwin = eventmsg->nxwin; + bool success = true; + + switch (eventmsg->eventID) + { + case EVENT_WINDOW_RAISE: // Raise window to the top of the heirarchy + nxwin->raise(); // Could be the main or the icon window + break; + + case EVENT_WINDOW_LOWER: // Lower window to the bottom of the heirarchy + nxwin->lower(); // Could be the main or the icon window + break; + + case EVENT_WINDOW_POPUP: // De-iconify and raise the main window + { + deIconify(); + } + break; + + case EVENT_WINDOW_FOCUS: + if (!isIconified()) + { + m_modal = !m_modal; + m_nxWin->modal(m_modal); + } + + break; + + case EVENT_TOOLBAR_TERMINATE: // Toolbar terminate button pressed + if (isIconMgr()) + { + // Don't terminate the Icon manager, just hide it + + CIconMgr *iconMgr = m_twm4nx->getIconMgr(); + DEBUGASSERT(iconMgr != (CIconMgr *)0); + + iconMgr->hide(); + } + else + { + // Close the window... but not yet. Send the blocked message. + // The actual termination will no occur until the NX server + // drains all of the message events. We will get the + // EVENT_WINDOW_DELETE event at that point + + NXWidgets::CWidgetControl *control = nxwin->getWidgetControl(); + nxtk_block(control->getWindowHandle(), (FAR void *)m_nxWin); + } + + break; + + case EVENT_WINDOW_DELETE: // Toolbar terminate button pressed + { + // Poll for pending events before closing. + + FAR CWindow *cwin = (FAR CWindow *)eventmsg->obj; + success = cwin->pollToolbarEvents(); + + FAR CWindowFactory *factory = m_twm4nx->getWindowFactory(); + factory->destroyWindow(cwin); + } + break; + + case EVENT_WINDOW_UNFOCUS: // Exit modal state + { + m_modal = false; + m_nxWin->modal(false); + } + break; + + case EVENT_TOOLBAR_GRAB: /* Left click on title widget. Start drag */ + success = toolbarGrab(eventmsg); + break; + + case EVENT_WINDOW_DRAG: /* Mouse movement while clicked */ + success = windowDrag(eventmsg); + break; + + case EVENT_TOOLBAR_UNGRAB: /* Left click release while dragging. */ + success = toolbarUngrab(eventmsg); + break; + + default: + success = false; + break; + } + + return success; +} + +/** + * Create the main window + * + * @param winsize The initial window size + * @param winpos The initial window position + */ + +bool CWindow::createMainWindow(FAR const nxgl_size_s *winsize, + FAR const nxgl_point_s *winpos) +{ + // 1. Get the server instance. m_twm4nx inherits from NXWidgets::CNXServer + // so we all ready have the server instance. + // 2. Create the style, using the selected colors (REVISIT) + + // 3. Create a Widget control instance for the window using the default + // style for now. CWindowEvent derives from CWidgetControl. + + FAR CWindowEvent *control = new CWindowEvent(m_twm4nx); + + // 4. Create the window + + m_nxWin = m_twm4nx->createFramedWindow(control); + if (m_nxWin == (FAR NXWidgets::CNxTkWindow *)0) + { + delete control; + return false; + } + + // 5. Open and initialize the window + + bool success = m_nxWin->open(); + if (!success) + { + return false; + } + + // 6. Set the initial window size + + if (!m_nxWin->setSize(winsize)) + { + return false; + } + + // 7. Set the initial window position + + if (!m_nxWin->setPosition(winpos)) + { + return false; + } + + return true; +} + +/** + * Calculate the height of the tool bar + */ + +bool CWindow::getToolbarHeight(FAR const char *name) +{ + // The tool bar height is the largest of the toolbar button heights or the + // title text font + + // Check if there is a title. If so, get the font height. + + m_tbHeight = 0; + if (name != (FAR const char *)0) + { + FAR CFonts *fonts = m_twm4nx->getFonts(); + FAR NXWidgets::CNxFont *titleFont = fonts->getTitleFont(); + m_tbHeight = titleFont->getHeight(); + } + + // Now compare this to the height of each toolbar image + + for (int btindex = 0; btindex < NTOOLBAR_BUTTONS; btindex++) + { + nxgl_coord_t btnHeight = GTbBitmaps[btindex]->height; + if (btnHeight > m_tbHeight) + { + m_tbHeight = btnHeight; + } + } + + // Plus somoe lines for good separation + + m_tbHeight += CONFIG_TWM4NX_FRAME_VSPACING; + return true; +} + +/** + * Create the tool bar + */ + +bool CWindow::createToolbar(void) +{ + // Create the toolbar + // 1. Create the style, using the selected colors (REVISIT) + + // 2. Create a Widget control instance for the window using the default + // style for now. CWindowEvent derives from CWidgetControl. + + FAR CWindowEvent *control = new CWindowEvent(m_twm4nx); + + // 3. Get the toolbar sub-window from the framed window + + m_toolbar = m_nxWin->openToolbar(m_tbHeight, control); + if (m_toolbar == (FAR NXWidgets::CNxToolbar *)0) + { + delete control; + return false; + } + + // 4. Open and initialize the tool bar + + return m_toolbar->open(); +} + +/** + * Update the toolbar layout, resizing the title text window and + * repositioning all windows on the toolbar. + */ + +bool CWindow::updateToolbarLayout(void) +{ + // Disable widget drawing and events while we do this + + disableWidgets(); + + // Reposition all right buttons. Change the width of the + // toolbar does not effect the left side spacing. + + m_tbRightX = 0; + for (int btindex = 0; btindex < NTOOLBAR_BUTTONS; btindex++) + { + if (GButtonRightSide[btindex]) + { + FAR NXWidgets::CImage *cimage = m_tbButtons[btindex]; + + // Set the position of the Icon image in the toolbar + + struct nxgl_size_s windowSize; + getWindowSize(&windowSize); + + // Center image vertically + + struct nxgl_point_s pos; + pos.y = (m_tbHeight - cimage->getHeight()) / 2; + + // Pack on the right horizontally + + m_tbRightX -= (cimage->getWidth() + CONFIG_TWM4NX_TOOLBAR_HSPACING); + pos.x = m_tbRightX; + + if (!cimage->moveTo(pos.x, pos.y)) + { + gerr("ERROR: Faile to move button image\n"); + return false; + } + } + } + + // Vertical size of the title window is selected to fill the entire + // toolbar. This really needs to be only the font height. However, + // this improves the click-ability of the widget for small fonts. + // + // The Horizontal size of the title widget is determined by the available + // space between m_tbLeftX and m_tbRightX. + + struct nxgl_size_s titleSize; + titleSize.h = m_tbHeight; + titleSize.w = m_tbRightX - m_tbLeftX - CONFIG_TWM4NX_FRAME_VSPACING + 1; + + bool success = m_tbTitle->resize(titleSize.w, titleSize.h); + enableWidgets(); + return success; +} + +/** + * Disable widget drawing and widget events. + */ + +bool CWindow::disableWidgets(void) +{ + for (int btindex = 0; btindex < NTOOLBAR_BUTTONS; btindex++) + { + FAR NXWidgets::CImage *cimage = m_tbButtons[btindex]; + cimage->disableDrawing(); + cimage->setRaisesEvents(false); + } + + m_tbTitle->disableDrawing(); + m_tbTitle->setRaisesEvents(false); + return true; +} + +/** + * Enable widget drawing and widget events. + */ + +bool CWindow::enableWidgets(void) +{ + for (int btindex = 0; btindex < NTOOLBAR_BUTTONS; btindex++) + { + FAR NXWidgets::CImage *cimage = m_tbButtons[btindex]; + cimage->enableDrawing(); + cimage->setRaisesEvents(true); + cimage->redraw(); + } + + m_tbTitle->enableDrawing(); + m_tbTitle->setRaisesEvents(true); + m_tbTitle->redraw(); + return true; +} + +/** + * Create all toolbar buttons + */ + +bool CWindow::createToolbarButtons(void) +{ + struct nxgl_size_s winsize; + if (!getWindowSize(&winsize)) + { + return false; + } + + // Create the title bar windows + // Set up the toolbar horizonal spacing + + m_tbRightX = winsize.w; + m_tbLeftX = 0; + + for (int btindex = 0; btindex < NTOOLBAR_BUTTONS; btindex++) + { + FAR const NXWidgets::SRlePaletteBitmap *sbitmap = GTbBitmaps[btindex]; + +#ifdef CONFIG_TWM4NX_TOOLBAR_ICONSCALE + // Create a CScaledBitmap to scale the bitmap icon + + struct nxgl_size_s iconSize; + iconSize.w = CONFIG_TWM4NX_TOOLBAR_ICONWIDTH; + iconSize.h = CONFIG_TWM4NX_TOOLBAR_ICONHEIGHT; + + FAR NXWidgets::CScaledBitmap *scaler = + new NXWidgets::CScaledBitmap(sbitmap, iconSize); + + if (scaler == (FAR NXWidgets::CScaledBitmap *)0) + { + gerr("ERROR: Failed to created scaled bitmap\n"); + return false; + } +#endif + // Create the image. The image will serve as button since it + // can detect clicks and release just like a button. + + m_tbButtons[btindex] = (FAR NXWidgets::CImage *)0; + nxgl_coord_t w = 1; + nxgl_coord_t h = 1; + + // Get the toolbar CWdigetControl instance + + NXWidgets::CWidgetControl *control = m_toolbar->getWidgetControl(); + +#ifdef CONFIG_TWM4NX_TOOLBAR_ICONSCALE + w = scaler->getWidth(); + h = scaler->getHeight(); + + m_tbButtons[btindex] = + new NXWidgets::CImage(control, 0, 0, w, h, scaler, 0); + if (m_tbButtons[btindex] == (FAR NXWidgets::CImage *)0) + { + gerr("ERROR: Failed to create image\n"); + delete scalar; + return false; + } +#else + FAR NXWidgets::CRlePaletteBitmap *cbitmap = + new NXWidgets::CRlePaletteBitmap(sbitmap); + if (cbitmap == (FAR NXWidgets::CRlePaletteBitmap *)0) + { + gerr("ERROR: Failed to create CrlPaletteBitmap\n"); + return false; + } + + w = cbitmap->getWidth(); + h = cbitmap->getHeight(); + + m_tbButtons[btindex] = + new NXWidgets::CImage(control, 0, 0, w, h, cbitmap, 0); + if (m_tbButtons[btindex] == (FAR NXWidgets::CImage *)0) + { + gerr("ERROR: Failed to create image\n"); + delete cbitmap; + return false; + } +#endif + + // Configure the image, disabling drawing for now + + FAR NXWidgets::CImage *cimage = m_tbButtons[btindex]; + cimage->setBorderless(true); + cimage->disableDrawing(); + cimage->setRaisesEvents(false); + + // Register to get events from the mouse clicks on the image + + cimage->addWidgetEventHandler(this); + + // Set the position of the Icon image in the toolbar + + struct nxgl_size_s windowSize; + getWindowSize(&windowSize); + + // Center image vertically + + struct nxgl_point_s pos; + pos.y = (m_tbHeight - cimage->getHeight()) / 2; + + // Pack on the left or right horizontally + + if (GButtonRightSide[btindex]) + { + m_tbRightX -= (cimage->getWidth() + CONFIG_TWM4NX_TOOLBAR_HSPACING); + pos.x = m_tbRightX; + } + else + { + m_tbLeftX += CONFIG_TWM4NX_TOOLBAR_HSPACING; + pos.x = m_tbLeftX; + m_tbLeftX += cimage->getWidth(); + } + + if (!cimage->moveTo(pos.x, pos.y)) + { + delete m_tbButtons[btindex]; + m_tbButtons[btindex] = (FAR NXWidgets::CImage *)0; + return false; + } + } + + return true; +} + +/** + * Add buttons and title widgets to the tool bar + * + * @param name The name to use for the toolbar title + */ + +bool CWindow::createToolbarTitle(FAR const char *name) +{ + // Is there a title? + + if (name != (FAR const char *)0) + { + // No.. then there is nothing to be done here + + return true; + } + + // Vertical size of the title window is selected to fill the entire + // toolbar. This really needs to be only the font height. However, + // this improves the click-ability of the widget for small fonts. + // + // The Horizontal size of the title widget is determined by the available + // space between m_tbLeftX and m_tbRightX. + + struct nxgl_size_s titleSize; + titleSize.h = m_tbHeight; + titleSize.w = m_tbRightX - m_tbLeftX - CONFIG_TWM4NX_FRAME_VSPACING + 1; + + // Position the tile. Packed to the left horizontally, positioned at the + // top of the toolbar. + + struct nxgl_point_s titlePos; + titlePos.x = m_tbLeftX + CONFIG_TWM4NX_FRAME_VSPACING; + titlePos.y = 0; + + // Create the widget control (with the window messenger) using the default style + + // REVISIT: Create the style, using the selected colors. + + // Create a Widget control instance for the window using the default style + // for now. CWindowEvent derives from CWidgetControl. + + FAR CWindowEvent *control = new CWindowEvent(m_twm4nx); + if (control == (FAR CWindowEvent *)0) + { + return false; + } + + // Create the toolbar title widget + + m_tbTitle = new NXWidgets::CLabel(control, titlePos.x, titlePos.y, + titleSize.w, titleSize.h, name); + if (m_tbTitle == (FAR NXWidgets::CLabel *)0) + { + gerr("ERROR: Failed to construct tool bar title widget\n"); + return false; + } + + // Configure the title widget + + FAR CFonts *fonts = m_twm4nx->getFonts(); + FAR NXWidgets::CNxFont *titleFont = fonts->getTitleFont(); + + m_tbTitle->setFont(titleFont); + m_tbTitle->setBorderless(true); + m_tbTitle->disableDrawing(); + m_tbTitle->setTextAlignmentHoriz(NXWidgets::CLabel::TEXT_ALIGNMENT_HORIZ_LEFT); + m_tbTitle->setTextAlignmentVert(NXWidgets::CLabel::TEXT_ALIGNMENT_VERT_CENTER); + m_tbTitle->setRaisesEvents(false); + + // Register to get events from the mouse clicks on the image + + m_tbTitle->addWidgetEventHandler(this); + return true; +} + +/** + * Override the mouse button drag event. + * + * @param e The event data. + */ + +void CWindow::handleDragEvent(const NXWidgets::CWidgetEventArgs &e) +{ + // We are interested only the the drag event on the title box while we are + // in the dragging state. + + if (m_drag) + { +#warning Missing logic + } +} + +/** + * Override a drop event, triggered when the widget has been dragged-and-dropped. + * + * @param e The event data. + */ + +void CWindow::handleDropEvent(const NXWidgets::CWidgetEventArgs &e) +{ + // We are interested only the the drag drop event on the title box while we + // are in the dragging state. + + if (m_drag) + { +#warning Missing logic + } +} + +/** + * Handle a key press event. + * + * @param e The event data. + */ + +void CWindow::handleKeyPressEvent(const NXWidgets::CWidgetEventArgs &e) +{ + // We are interested only the the press event on the title box + + if (!m_drag) + { +#warning Missing logic + } +} + +/** + * Override the virtual CWidgetEventHandler::handleActionEvent. This + * event will fire when the image is released but before it has been + * has been drawn. isClicked() will return true for the appropriate + * images. + */ + +void CWindow::handleActionEvent(const NXWidgets::CWidgetEventArgs &e) +{ + // We are are interested in the pre-release event for any of the + // toolbar buttons. +#warning Missing logic +} + +/** + * Handle the TOOLBAR_GRAB event. That corresponds to a left + * mouse click on the tile widget in the toolbar + * + * @param eventmsg. The received NxWidget event message. + * @return True if the message was properly handled. false is + * return on any failure. + */ + +bool CWindow::toolbarGrab(FAR struct SEventMsg *eventmsg) +{ + // Promote the window to a modal window + + m_modal = true; + m_nxWin->modal(true); + + // Indicate that dragging has started. + + m_drag = true; + + // Get the frame position. + + struct nxgl_point_s framePos; + getFramePosition(&framePos); + + // Determine the relative position of the frame and the mouse + + m_dragOffset.x = framePos.x - eventmsg->pos.x; + m_dragOffset.y = framePos.y - eventmsg->pos.y; + + // Select the grab cursor image + + m_twm4nx->setCursorImage(&CONFIG_TWM4NX_GBCURSOR_IMAGE); + + // Remember the grab cursor size + + m_dragCSize.w = CONFIG_TWM4NX_GBCURSOR_IMAGE.size.w; + m_dragCSize.h = CONFIG_TWM4NX_GBCURSOR_IMAGE.size.h; + return true; +} + +/** + * Handle the WINDOW_DRAG event. That corresponds to a mouse + * movement when the window is in a grabbed state. + * + * @param eventmsg. The received NxWidget event message. + * @return True if the message was properly handled. false is + * return on any failure. + */ + +bool CWindow::windowDrag(FAR struct SEventMsg *eventmsg) +{ + if (m_drag) + { + // Calculate the new Window position + + struct nxgl_point_s newpos; + newpos.x = eventmsg->pos.x + m_dragOffset.x; + newpos.y = eventmsg->pos.y + m_dragOffset.y; + + // Keep the window on the display (at least enough of it so that we + // can still grab it) + + struct nxgl_size_s displaySize; + m_twm4nx->getDisplaySize(&displaySize); + + if (newpos.x < 0) + { + newpos.x = 0; + } + else if (newpos.x + m_dragCSize.w > displaySize.w) + { + newpos.x = displaySize.w - m_dragCSize.w; + } + + if (newpos.y < 0) + { + newpos.y = 0; + } + else if (newpos.y + m_dragCSize.h > displaySize.h) + { + newpos.y = displaySize.h - m_dragCSize.h; + } + + // Set the new window position + + return setFramePosition(&newpos); + } + + return false; +} + +/** + * Handle the TOOLBAR_UNGRAB event. The corresponds to a mouse + * left button release while in the grabbed state + * + * @param eventmsg. The received NxWidget event message. + * @return True if the message was properly handled. false is + * return on any failure. + */ + +bool CWindow::toolbarUngrab(FAR struct SEventMsg *eventmsg) +{ + // One last position update + + if (!windowDrag(eventmsg)) + { + return false; + } + + // Indicate no longer dragging + + m_drag = false; + + // No longer modal + + m_modal = false; + m_nxWin->modal(false); + + // Restore the normal cursor image + + m_twm4nx->setCursorImage(&CONFIG_TWM4NX_CURSOR_IMAGE); + return false; +} + +/** + * Free windows from Twm4Nx window structure. + */ + +void CWindow::cleanup(void) +{ + // Close the NxWidget event message queue + + if (m_eventq != (mqd_t)-1) + { + (void)mq_close(m_eventq); + m_eventq = (mqd_t)-1; + } + + // Delete toolbar images + + for (int btindex = 0; btindex < NTOOLBAR_BUTTONS; btindex++) + { + FAR NXWidgets::CImage *cimage = m_tbButtons[btindex]; + if (cimage != (NXWidgets::CImage *)0) + { + delete m_tbButtons[btindex]; + m_tbButtons[btindex] = (NXWidgets::CImage *)0; + } + } + + if (m_tbTitle != (FAR NXWidgets::CLabel *)0) + { + delete m_tbTitle; + m_tbTitle = (FAR NXWidgets::CLabel *)0; + } + + // Close windows + + if (m_nxWin != (FAR NXWidgets::CNxTkWindow *)0) + { + delete m_nxWin; + m_nxWin = (FAR NXWidgets::CNxTkWindow *)0; + } + + if (m_iconWin != (FAR CIconWin *)0) + { + delete m_iconWin; + m_iconWin = (FAR CIconWin *)0; + } + + // Free memory + + if (m_name != (FAR char *)0) + { + std::free(m_name); + m_name = (FAR char *)0; + } +} diff --git a/graphics/twm4nx/src/cwindowevent.cxx b/graphics/twm4nx/src/cwindowevent.cxx new file mode 100644 index 000000000..fc1a88915 --- /dev/null +++ b/graphics/twm4nx/src/cwindowevent.cxx @@ -0,0 +1,249 @@ +// apps/graphics/twm4nx/src/cwindowevent.cxx +// Shim to manage the interface between NX messages and NxWidgets +// +// 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 "graphics/nxwidgets/cwidgetcontrol.hxx" + +#include "graphics/twm4nx/cwindow.hxx" +#include "graphics/twm4nx/cwindowevent.hxx" + +///////////////////////////////////////////////////////////////////////////// +// CWindowEvent Method Implementations +///////////////////////////////////////////////////////////////////////////// + +using namespace Twm4Nx; + +/** + * CWindowEvent Constructor + * + * @param twm4nx. The Twm4Nx session instance. + * @param style The default style that all widgets on this display + * should use. If this is not specified, the widget will use the + * values stored in the defaultCWidgetStyle object. + */ + +CWindowEvent::CWindowEvent(FAR CTwm4Nx *twm4nx, + FAR const NXWidgets::CWidgetStyle *style) +: NXWidgets::CWidgetControl(style) +{ + m_twm4nx = twm4nx; // Cache the Twm4Nx session + + // Open a message queue to send raw NX events. This cannot fail! + + FAR const char *mqname = twm4nx->getEventQueueName(); + m_eventq = mq_open(mqname, O_WRONLY); + if (m_eventq == (mqd_t)-1) + { + gerr("ERROR: Failed open message queue '%s': %d\n", + mqname, errno); + } + + // Add ourself to the list of window event handlers + + addWindowEventHandler(this); +} + +/** + * CWindowEvent Destructor. + */ + +CWindowEvent::~CWindowEvent(void) +{ + // Close the NxWidget event message queue + + if (m_eventq != (mqd_t)-1) + { + (void)mq_close(m_eventq); + m_eventq = (mqd_t)-1; + } + + // Remove ourself from the list of the window event handlers + + removeWindowEventHandler(this); +} + +/** + * Handle MSG events. + * + * @param msg. The received system MSG event message. + * @return True if the message was properly handled. false is + * return on any failure. + */ + +bool CWindowEvent::event(FAR struct SEventMsg *eventmsg) +{ + bool success = true; + + // Handle the event + + switch (eventmsg->eventID) + { + case EVENT_MSG_POLL: // Poll for event + { + // Poll for pending events before closing. + + FAR CWindow *cwin = (FAR CWindow *)eventmsg->obj; + success = cwin->pollToolbarEvents(); + } + break; + + default: + success = false; + break; + } + + return success; +} + +/** + * Send the EVENT_MSG_POLL input event message to the Twm4Nx event loop. + */ + +void CWindowEvent::sendInputEvent(void) +{ + // The logic path here is tortuous but flexible: + // + // 1. A listener thread receives mouse or touchscreen input and injects + // that into NX via nx_mousein + // 2. In the multi-user mode, this will send a message to the NX server + // 3. The NX server will determine which window gets the mouse input + // and send a window event message to the NX listener thread. + // 4. The NX listener thread receives a windows event. The NX listener thread + // is part of CTwm4Nx and was created when NX server connection was + // established. This event may be a positional change notification, a + // redraw request, or mouse or keyboard input. In this case, mouse input. + // 5. The NX listener thread handles the message by calling nx_eventhandler(). + // nx_eventhandler() dispatches the message by calling a method in the + // NXWidgets::CCallback instance associated with the window. + // NXWidgets::CCallback is a part of the CWidgetControl. + // 6. NXWidgets::CCallback calls into NXWidgets::CWidgetControl to process + // the event. + // 7. NXWidgets::CWidgetControl records the new state data and raises a + // window event. + // 8. NXWidgets::CWindowEventHandlerList will give the event to this method + // NxWM::CWindowEvent. + // 9. This NxWM::CWindowEvent method will send a message to the Event + // loop running in the Twm4Nx main thread. + // 10. The Twm4Nx main thread will call the CWindowEvent::event() method + // which + // 11. Finally call pollEvents() to execute whatever actions the input event + // should trigger. + // 12. This might call an event handler in and overrident method of + // CWidgetEventHandler which will again notify the Event loop running + // in the Twm4Nx main thread. The event will, finally be delivered + // to the recipient in its fully digested and decorated form. + + struct SNxEventMsg msg = + { + .eventID = EVENT_MSG_POLL, + .instance = this, + .win = (FAR struct SWindow *)0 + }; + + int ret = mq_send(m_eventq, (FAR const char *)&msg, + sizeof(struct SNxEventMsg), 100); + if (ret < 0) + { + gerr("ERROR: mq_send failed: %d\n", ret); + } +} + +/** + * Handle an NX window mouse input event. + */ + +#ifdef CONFIG_NX_XYINPUT +void CWindowEvent::handleMouseEvent(void) +{ + // Stimulate an input poll + + sendInputEvent(); +} +#endif + +#ifdef CONFIG_NX_KBD +/** + * Handle a NX window keyboard input event. + */ + +void CWindowEvent::handleKeyboardEvent(void) +{ + // Stimulate an input poll + + sendInputEvent(); +} +#endif + +/** + * Handle a NX window blocked event. This handler is called when we + * receive the BLOCKED message meaning that there are no further pending + * actions on the window. It is now safe to delete the window. + * + * This is handled by sending a message to the start window thread (vs just + * calling the destructors) because in the case where an application + * destroys itself (because of pressing the stop button), then we need to + * unwind and get out of the application logic before destroying all of its + * objects. + * + * @param arg - User provided argument (see nx_block or nxtk_block) + */ + +void CWindowEvent::handleBlockedEvent(FAR void *arg) +{ + struct SNxEventMsg msg = + { + .eventID = EVENT_WINDOW_DELETE, + .instance = this, + .win = (FAR struct SWindow *)arg + }; + + int ret = mq_send(m_eventq, (FAR const char *)&msg, + sizeof(struct SNxEventMsg), 100); + if (ret < 0) + { + gerr("ERROR: mq_send failed: %d\n", ret); + } +} diff --git a/graphics/twm4nx/src/cwindowfactory.cxx b/graphics/twm4nx/src/cwindowfactory.cxx new file mode 100644 index 000000000..44b36bb1b --- /dev/null +++ b/graphics/twm4nx/src/cwindowfactory.cxx @@ -0,0 +1,330 @@ +///////////////////////////////////////////////////////////////////////////// +// apps/graphics/twm4nx/src/cwindowfactory.cxx +// A collection of Window Helpers: Add a new window, put the titlebar and +// other stuff around the window +// +// Copyright (C) 2019 Gregory Nutt. All rights reserved. +// Author: Gregory Nutt +// +// Largely an original work but derives from TWM 1.0.10 in many ways: +// +// Copyright 1989,1998 The Open Group +// Copyright 1988 by Evans & Sutherland Computer Corporation, +// +// Please refer to apps/twm4nx/COPYING for detailed copyright information. +// +// 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 "graphics/nxwidgets/cwidgetcontrol.hxx" +#include "graphics/nxwidgets/cnxwindow.hxx" +#include "graphics/nxwidgets/cnxtkwindow.hxx" +#include "graphics/nxwidgets/cnxtoolbar.hxx" + +#include "graphics/twm4nx/ctwm4nx.hxx" +#include "graphics/twm4nx/cwindow.hxx" +#include "graphics/twm4nx/cwindowfactory.hxx" +#include "graphics/twm4nx/ciconmgr.hxx" +#include "graphics/twm4nx/twm4nx_widgetevents.hxx" + +///////////////////////////////////////////////////////////////////////////// +// CWindowFactory Implementation +///////////////////////////////////////////////////////////////////////////// + +using namespace Twm4Nx; + +/** + * CWindowFactory Constructor + * + * @param twm4nx. Twm4Nx session + */ + +CWindowFactory::CWindowFactory(FAR CTwm4Nx *twm4nx) +{ + m_twm4nx = twm4nx; // Cached copy of the Twm4Nx session object + m_windowHead = (FAR struct SWindow *)0; // List of all Windows + + // Set up the position where we will create the initial window + + m_winpos.x = 50; + m_winpos.y = 50; +} + +/** + * CWindowFactory Destructor + */ + +CWindowFactory::~CWindowFactory(void) +{ +} + +/** + * Create a new window and add it to the window list. + * + * @param name The window name + * @param sbitmap The Icon bitmap + * @param isIconMgr Flag to tell if this is an icon manager window + * @param iconMgr Pointer to icon manager instance + * @param noToolbar True: Don't add Title Bar + * @return Reference to the allocated CWindow instance + */ + +FAR CWindow * + CWindowFactory::createWindow(FAR const char *name, + FAR const struct NXWidgets::SRlePaletteBitmap *sbitmap, + bool isIconMgr, FAR CIconMgr *iconMgr, + bool noToolbar) +{ + ginfo("name=%p\n", name); + + // Allocate a container for the Twm4NX window + + FAR struct SWindow *win = + (FAR struct SWindow *)std::zalloc(sizeof(struct SWindow)); + if (win == (FAR struct SWindow *)0) + { + gerr("ERROR: Unable to allocate memory to manage window %s\n", + name); + return (FAR CWindow *)0; + } + + // Create and initialize the window itself + + win->cwin = new CWindow(m_twm4nx); + if (win->cwin == (FAR CWindow *)0) + { + gerr("ERROR: Failed to create CWindow\n"); + std::free(win); + return (FAR CWindow *)0; + } + + // Place the window at a random position + // Default size: Try a one quarter of the display. + + struct nxgl_size_s displaySize; + m_twm4nx->getDisplaySize(&displaySize); + + struct nxgl_size_s winsize; + winsize.w = displaySize.w / 2; + winsize.h = displaySize.h / 2; + + if ((m_winpos.x + winsize.w) > displaySize.w) + { + m_winpos.x = 50; + } + + if ((m_winpos.x + winsize.w) > (displaySize.w - 16)) + { + winsize.w = displaySize.w - m_winpos.x - 16; + } + + if ((m_winpos.y + winsize.h) > displaySize.h) + { + m_winpos.y = 50; + } + + if ((m_winpos.y + winsize.h) > (displaySize.h - 16)) + { + winsize.h = displaySize.h - m_winpos.y - 16; + } + + ginfo("Position window at (%d,%d), size (%d,%d)\n", + m_winpos.x, m_winpos.y, winsize.w, winsize.h); + + if (!win->cwin->initialize(name, &m_winpos, &winsize, sbitmap, + isIconMgr, iconMgr, noToolbar)) + { + gerr("ERROR: Failed to initialize CWindow\n"); + delete win->cwin; + std::free(win); + return (FAR CWindow *)0; + } + + // Update the position for the next window + + m_winpos.x += 30; + m_winpos.y += 30; + + // Add the window into the Twm4Nx window list + + addWindow(win); + + // Add the window container to the icon manager + + CIconMgr *iconmgr = m_twm4nx->getIconMgr(); + DEBUGASSERT(iconmgr != (CIconMgr *)0); + + (void)iconmgr->add(win->cwin); + + // Return the contained window + + return win->cwin; +} + +/** + * Handle the EVENT_WINDOW_DELETE event. The logic sequence is as + * follows: + * + * 1. The TERMINATE button in pressed in the Window Toolbar + * 2. CWindowFactory::event receives the widget event, + * EVENT_WINDOW_TERMINATE and request to halt the NX Server + * messages queues. + * 3. The server responds with the EVENT_WINDOW_DELETE which is + * caught by this function. + * + * @param cwin The CWindow instance. This will be deleted and its + * associated container will be freed. + */ + +void CWindowFactory::destroyWindow(FAR CWindow *cwin) +{ + // Find the container of the window + + FAR struct SWindow *win = findWindow(cwin); + if (win == (FAR struct SWindow *)0) + { + // This should not happen.. worthy of an assertion + + gerr("ERROR: Failed to find CWindow container\n"); + } + else + { + // Remove the window container from the window list + + removeWindow(win); + } + + // Delete the contained CWindow instance + + delete cwin; + + // And, finally, free the CWindow container + + free(win); +} + +/** + * Handle WINDOW events. + * + * @param eventmsg. The received NxWidget WINDOW event message. + * @return True if the message was properly handled. false is + * return on any failure. + */ + +bool CWindowFactory::event(FAR struct SEventMsg *eventmsg) +{ + FAR CWindow *cwin = (FAR CWindow *)eventmsg->obj; + DEBUGASSERT(cwin != (FAR CWindow *)0); + + // Forward the event to the appropriate window + + return cwin->event(eventmsg); +} + +/** + * Add a window container to the window list. + * + * @param win. The window container to be added to the list. + */ + +void CWindowFactory::addWindow(FAR struct SWindow *win) +{ + win->blink = (FAR struct SWindow *)0; + win->flink = m_windowHead; + + if (m_windowHead != (FAR struct SWindow *)0) + { + m_windowHead->blink = win; + } + + m_windowHead = win; +} + +/** + * Remove a window container from the window list. + * + * @param win. The window container to be removed from the list. + */ + +void CWindowFactory::removeWindow(FAR struct SWindow *win) +{ + FAR struct SWindow *prev = win->blink; + FAR struct SWindow *next = win->flink; + + if (prev == (FAR struct SWindow *)0) + { + m_windowHead = next; + } + else + { + prev->flink = next; + } + + if (next != (FAR struct SWindow *)0) + { + next->blink = prev; + } + + win->flink = NULL; + win->blink = NULL; +} + +/** + * Find the window container that contains the specified window. + * + * @param cwin. The window whose container is needed. + * @return On success, the container of the specific window is returned; + * NULL is returned on failure. + */ + +FAR struct SWindow *CWindowFactory::findWindow(FAR CWindow *cwin) +{ + for (FAR struct SWindow *win = m_windowHead; + win != (FAR struct SWindow *)0; + win = win->flink) + { + if (win->cwin == cwin) + { + return win; + } + } + + return (FAR struct SWindow *)0; +} diff --git a/graphics/twm4nx/src/twm4nx_cursor.cxx b/graphics/twm4nx/src/twm4nx_cursor.cxx new file mode 100644 index 000000000..19a7a84b2 --- /dev/null +++ b/graphics/twm4nx/src/twm4nx_cursor.cxx @@ -0,0 +1,65 @@ +///////////////////////////////////////////////////////////////////////////// +// apps/graphics/twm4nx/src/twm4nx_cursor.cxx +// Cursor images +// +// 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 "graphics/twm4nx/twm4nx_cursor.hxx" + +#ifdef CONFIG_NX_SWCURSOR + +///////////////////////////////////////////////////////////////////////////// +// Pulbic Data +///////////////////////////////////////////////////////////////////////////// + +namespace Twm4Nx +{ +#ifdef CONFIG_TWM4NX_CURSOR_LARGE +# include "cursor-arrow1-30x30.h" +# include "cursor-grab-25x30.h" +# include "cursor-wait-23x30.h" +#else +# include "cursor-arrow1-16x16.h" +# include "cursor-grab-14x16.h" +# include "cursor-wait-13x16.h" +#endif +} + +#endif // CONFIG_NX_SWCURSOR diff --git a/include/graphics/nxglyphs.hxx b/include/graphics/nxglyphs.hxx index b71336e11..a028ab913 100644 --- a/include/graphics/nxglyphs.hxx +++ b/include/graphics/nxglyphs.hxx @@ -129,12 +129,15 @@ namespace NXWidgets extern const struct SBitmap g_capslock; extern const struct SBitmap g_control; - // Bitmaps used by NxWM + // Bitmaps used by NxWM and Twm4Nx // Global RLE Paletted Bitmaps extern const struct SRlePaletteBitmap g_calculatorBitmap; extern const struct SRlePaletteBitmap g_calibrationBitmap; extern const struct SRlePaletteBitmap g_cmdBitmap; + extern const struct SRlePaletteBitmap g_menuBitmap; + extern const struct SRlePaletteBitmap g_resizeBitmap; + extern const struct SRlePaletteBitmap g_nxiconBitmap; // Used by NxWM meda player diff --git a/include/graphics/nxwidgets/cnxfont.hxx b/include/graphics/nxwidgets/cnxfont.hxx index d7cc57a47..6b896bc5f 100644 --- a/include/graphics/nxwidgets/cnxfont.hxx +++ b/include/graphics/nxwidgets/cnxfont.hxx @@ -48,6 +48,8 @@ #include #include +#include "graphics/nxwidgets/nxconfig.hxx" + /**************************************************************************** * Pre-Processor Definitions ****************************************************************************/ diff --git a/include/graphics/nxwidgets/cwidgetcontrol.hxx b/include/graphics/nxwidgets/cwidgetcontrol.hxx index eef05dcc2..0666003f1 100644 --- a/include/graphics/nxwidgets/cwidgetcontrol.hxx +++ b/include/graphics/nxwidgets/cwidgetcontrol.hxx @@ -437,8 +437,8 @@ namespace NXWidgets * pollKeyboardEvents() * pollCursorControlEvents() * - * @param widget. Specific widget to poll. Use NULL to run the - * all widgets in the window. + * @param widget. Specific widget to poll. Use NULL to run through + * of the widgets in the window. * @return True means some interesting event occurred */ diff --git a/include/graphics/twm4nx/cbackground.hxx b/include/graphics/twm4nx/cbackground.hxx new file mode 100644 index 000000000..5f60090b7 --- /dev/null +++ b/include/graphics/twm4nx/cbackground.hxx @@ -0,0 +1,141 @@ +///////////////////////////////////////////////////////////////////////////// +// apps/graphics/twm4nx/include/cbackground.hxx +// Manage background image +// +// 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. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef __APPS_INCLUDE_GRAPHICS_TWM4NX_CBACKGROUND_HXX +#define __APPS_INCLUDE_GRAPHICS_TWM4NX_CBACKGROUND_HXX + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "graphics/nxwidgets/nxconfig.hxx" +#include "graphics/nxwidgets/cnxwindow.hxx" +#include "graphics/nxwidgets/cnxserver.hxx" +#include "graphics/nxwidgets/cwidgeteventhandler.hxx" +#include "graphics/nxwidgets/cwidgeteventargs.hxx" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Implementation Class Definition + ****************************************************************************/ + +namespace NXWidgets +{ + class CBgWindow; // Forward reference + class CImage; // Forward reference + struct SRlePaletteBitmap; // Forward reference +} + +namespace Twm4Nx +{ + class CTwm4Nx; // Forward reference + /** + * Background management + */ + + class CBackground + { + protected: + FAR CTwm4Nx *m_twm4nx; /**< Cached CTwm4Nx instance */ + FAR NXWidgets::CBgWindow *m_backWindow; /**< The background window */ + FAR NXWidgets::CImage *m_backImage; /**< The background image */ + + /** + * Create the background window. + * + * @return true on success + */ + + bool createBackgroundWindow(void); + + /** + * Create the background image. + * + * @param sbitmap. Identifies the bitmap to paint on background + * @return true on success + */ + + bool createBackgroundImage(FAR const struct NXWidgets::SRlePaletteBitmap *sbitmap); + + /** + * (Re-)draw the background window. + * + * @return true on success + */ + + bool redrawBackgroundWindow(void); + + public: + /** + * CBackground Constructor + * + * @param twm4nx The Twm4Nx session object + */ + + CBackground(FAR CTwm4Nx *twm4nx); + + /** + * CBackground Destructor + */ + + ~CBackground(void); + + /** + * Set the background image + * + * @param sbitmap. Identifies the bitmap to paint on background + * @return true on success + */ + + bool setBackgroundImage(FAR const struct NXWidgets::SRlePaletteBitmap *sbitmap); + + /** + * Get the size of the physical display device which is equivalent to + * size of the background window. + * + * @return The size of the display + */ + + void getDisplaySize(FAR struct nxgl_size_s &size); + }; +} + +#endif // __APPS_INCLUDE_GRAPHICS_TWM4NX_CBACKGROUND_HXX diff --git a/include/graphics/twm4nx/cfonts.hxx b/include/graphics/twm4nx/cfonts.hxx new file mode 100644 index 000000000..916a59f1c --- /dev/null +++ b/include/graphics/twm4nx/cfonts.hxx @@ -0,0 +1,182 @@ +///////////////////////////////////////////////////////////////////////////// +// apps/graphics/twm4nx/include/cfonts.hxx +// Font support for twm4nx +// +// Copyright (C) 2019 Gregory Nutt. All rights reserved. +// Author: Gregory Nutt +// +// Largely an original work but derives from TWM 1.0.10 in many ways: +// +// Copyright 1989,1998 The Open Group +// Copyright 1988 by Evans & Sutherland Computer Corporation, +// +// Please refer to apps/twm4nx/COPYING for detailed copyright information. +// +// 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. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef __APPS_INCLUDE_GRAPHICS_TWM4NX_CFONTS_HXX +#define __APPS_INCLUDE_GRAPHICS_TWM4NX_CFONTS_HXX + +///////////////////////////////////////////////////////////////////////////// +// Included Files +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Included Files +///////////////////////////////////////////////////////////////////////////// + +#include + +#include +#include +#include + +///////////////////////////////////////////////////////////////////////////// +// Implementation Classes +///////////////////////////////////////////////////////////////////////////// + +namespace NXWidgets +{ + class CNxFont; // Forward reference +} + +namespace Twm4Nx +{ + class CTwm4Nx; // Forward reference + + /** + * The CFonts class encapsulates font support. + */ + + class CFonts + { + private: + FAR CTwm4Nx *m_twm4nx; /**< The Twm4Nx session */ + FAR NXWidgets::CNxFont *m_titleFont; /**< Title bar font */ + FAR NXWidgets::CNxFont *m_menuFont; /**< Menu font */ + FAR NXWidgets::CNxFont *m_iconFont; /**< Icon font */ + FAR NXWidgets::CNxFont *m_sizeFont; /**< Resize font */ + FAR NXWidgets::CNxFont *m_iconManagerFont; /**< Window list font */ + FAR NXWidgets::CNxFont *m_defaultFont; /**< The default found */ + + public: + + /** + * CFonts Constructor + * + * @param twm4nx. An instance of the Twm4Nx session. + */ + + CFonts(FAR CTwm4Nx *twm4nx); + + /** + * CFonts Destructor + */ + + ~CFonts(void); + + /** + * Initialize fonts + * + * @return True is returned if the fonts were correctly initialized; + * false is returned in the event of an error. + */ + + bool initialize(void); + + /** + * Return the Title font + * + * @return A reference to the initialized title font. + */ + + FAR NXWidgets::CNxFont *getTitleFont(void) + { + return m_titleFont; + } + + /** + * Return the Menu font + * + * @return A reference to the initialized menu font. + */ + + FAR NXWidgets::CNxFont *getMenuFont(void) + { + return m_menuFont; + } + + /** + * Return the Icon font + * + * @return A reference to the initialized menu font. + */ + + FAR NXWidgets::CNxFont *getIconFont(void) + { + return m_iconFont; + } + + /** + * Return the Size font + * + * @return A reference to the initialized menu font. + */ + + FAR NXWidgets::CNxFont *getSizeFont(void) + { + return m_sizeFont; + } + + /** + * Return the IconManager font + * + * @return A reference to the initialized menu font. + */ + + FAR NXWidgets::CNxFont *getIconManagerFont(void) + { + return m_iconManagerFont; + } + + /** + * Return the Default font + * + * @return A reference to the initialized menu font. + */ + + FAR NXWidgets::CNxFont *getDefaultFont(void) + { + return m_defaultFont; + } + }; +} + +#endif // __APPS_INCLUDE_GRAPHICS_TWM4NX_CFONTS_HXX diff --git a/include/graphics/twm4nx/cicon.hxx b/include/graphics/twm4nx/cicon.hxx new file mode 100644 index 000000000..1a4d5265d --- /dev/null +++ b/include/graphics/twm4nx/cicon.hxx @@ -0,0 +1,189 @@ +///////////////////////////////////////////////////////////////////////////// +// apps/graphics/twm4nx/include/cicon.hxx +// Icon related definitions +// +// Copyright (C) 2019 Gregory Nutt. All rights reserved. +// Author: Gregory Nutt +// +// Largely an original work but derives from TWM 1.0.10 in many ways: +// +// Copyright 1989,1998 The Open Group +// +// Please refer to apps/twm4nx/COPYING for detailed copyright information. +// +// 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. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef __APPS_INCLUDE_GRAPHICS_TWM4NX_CICON_HXX +#define __APPS_INCLUDE_GRAPHICS_TWM4NX_CICON_HXX + +///////////////////////////////////////////////////////////////////////////// +// Implementation Classes +///////////////////////////////////////////////////////////////////////////// + +namespace Twm4Nx +{ + class CTwm4Nx; /* Forward reference */ + struct SIconEntry; /* Forward reference */ + + struct SIconRegion + { + FAR struct SIconRegion *flink; + struct nxgl_point_s pos; + struct nxgl_size_s size; + struct nxgl_point_s step; // allocation granularity + FAR struct SIconEntry *entries; + }; + + struct SIconEntry + { + FAR struct SIconEntry *flink; + struct nxgl_point_s pos; + struct nxgl_size_s size; + FAR CWindow *cwin; + bool used; + }; + + /** + * The CIcon class supports a database of icons. + */ + + class CIcon + { + private: + + FAR CTwm4Nx *m_twm4nx; /**< The Twm4Nx session */ + FAR struct SNameList *m_icons; /**< List of icon images */ + FAR struct SIconRegion *m_regionHead; /**< Head of the icon region list */ + FAR struct SIconRegion *m_regionTail; /**< Tail of the icon region list */ + + inline int roundUp(int v, int multiple) + { + return ((v + multiple - 1) / multiple) * multiple; + } + + /** + * Find the icon region holding the window 'cwin' + * + * @param cwin The window whose icon region is sought + * @param irp A location in which to provide the region + */ + + FAR struct SIconEntry *findEntry(FAR CWindow *cwin, + FAR struct SIconRegion **irp); + + /** + * Given entry 'ie' in the list 'ir', return the entry just prior to 'ie' + * + * @param ie The entry whose predecessor is sought + * @param ir The region containing the entry + * @return The entry just before 'ie' in the list + */ + + FAR struct SIconEntry *prevEntry(FAR struct SIconEntry *ie, + FAR struct SIconRegion *ir); + + /** + * 'old' is being freed; and is adjacent to ie. Merge + * regions together + */ + + void mergeEntries(FAR struct SIconEntry *old, + FAR struct SIconEntry *ie); + + /** + * Free all of the icon entries linked to a region + * + * @param ir The region whose entries will be freed + */ + + void freeIconEntries(FAR struct SIconRegion *ir); + + /** + * Free all icon regions and all of the region entries linked into the + * region + */ + + void freeIconRegions(void); + + public: + + /** + * CIcon Constructor + */ + + CIcon(FAR CTwm4Nx *twm4nx); + + /** + * CIcon Destructor + */ + + ~CIcon(void); + + /** + * Create a new icon region and add it to the list of icon regions. + * + * @param pos The position of the region on the background + * @param size The size of the region + * @param step + */ + + void addIconRegion(FAR nxgl_point_s *pos, FAR nxgl_size_s *size, + FAR struct nxgl_point_s *step); + + /** + * Position an icon on the background + * + * @param cwin The Window whose icon will be placed + * @param pos An backup position to use is there are no available regions + * @param final A location in which to return the selection icon position + */ + + void place(FAR CWindow *cwin, FAR const struct nxgl_point_s *pos, + FAR struct nxgl_point_s *final); + + /** + * Bring the window up. + * + * @param cwin. The window to be brought up. + */ + + void up(FAR CWindow *cwin); + + /** + * Take the window down. + * + * @param cwin. The window to be taken down. + */ + + void down(FAR CWindow *cwin); + }; +} + +#endif // __APPS_INCLUDE_GRAPHICS_TWM4NX_CICON_HXX diff --git a/include/graphics/twm4nx/ciconmgr.hxx b/include/graphics/twm4nx/ciconmgr.hxx new file mode 100644 index 000000000..cb689b578 --- /dev/null +++ b/include/graphics/twm4nx/ciconmgr.hxx @@ -0,0 +1,269 @@ +///////////////////////////////////////////////////////////////////////////// +// apps/graphics/twm4nx/include/ciconmgr.hxx +// Icon Manager includes +// +// Copyright (C) 2019 Gregory Nutt. All rights reserved. +// Author: Gregory Nutt +// +// Largely an original work but derives from TWM 1.0.10 in many ways: +// +// Copyright 1989,1998 The Open Group +// +// Please refer to apps/twm4nx/COPYING for detailed copyright information. +// +// 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. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef __APPS_INCLUDE_GRAPHICS_TWM4NX_CICONMGR_HXX +#define __APPS_INCLUDE_GRAPHICS_TWM4NX_CICONMGR_HXX + +///////////////////////////////////////////////////////////////////////////// +// Included Files +///////////////////////////////////////////////////////////////////////////// + +#include +#include "graphics/twm4nx/cwindow.hxx" + +///////////////////////////////////////////////////////////////////////////// +// Implementation Classes +///////////////////////////////////////////////////////////////////////////// + +namespace NXWidgets +{ + class CNxTkWindow; // Forward reference + struct SRlePaletteBitmap; // Forward reference +} + +namespace Twm4Nx +{ + struct SWindowEntry + { + FAR struct SWindowEntry *flink; + FAR struct SWindowEntry *blink; + FAR CWindow *cwin; // Used only for the window name + FAR CIconMgr *iconmgr; + nxgl_point_s pos; + nxgl_size_s size; + int row; + int col; + int me; + bool active; + bool down; + }; + + class CIconMgr + { + private: + + FAR CTwm4Nx *m_twm4nx; /**< Cached Twm4Nx session */ + FAR struct SWindowEntry *m_head; /**< Head of the window list */ + FAR struct SWindowEntry *m_tail; /**< Tail of the window list */ + FAR struct SWindowEntry *m_active; /**< The active entry */ + FAR struct CWindow *m_window; /**< Parent window */ + unsigned int m_columns; /**< Number of columns icon manager */ + unsigned int m_currows; + unsigned int m_curcolumns; + unsigned int m_count; + + /** + * Create and initialize the icon manager window + * + * @param name The prefix for this icon manager name + */ + + bool createWindow(FAR const char *prefix); + + /** + * Create the button array widget + */ + + bool createButtonArray(void); + + /** + * Put an allocated entry into an icon manager + * + * @param wentry the entry to insert + */ + + void insertEntry(FAR struct SWindowEntry *wentry, + FAR CWindow *cwin); + + /** + * Remove an entry from an icon manager + * + * @param wentry the entry to remove + */ + + void removeEntry(FAR struct SWindowEntry *wentry); + + /** + * Set active window + * + * @param wentry Window to become active. + */ + + void active(FAR struct SWindowEntry *wentry); + + /** + * Set window inactive + * + * @param wentry windows to become inactive. + */ + + void inactive(FAR struct SWindowEntry *wentry); + + /** + * Free window list entry. + */ + + void freeWEntry(FAR struct SWindowEntry *wentry); + + public: + + /** + * CIconMgr Constructor + * + * @param twm4nx The Twm4Nx session + * @param ncolumns The number of columns this icon manager has + */ + + CIconMgr(CTwm4Nx *twm4nx, int ncolumns); + + /** + * CIconMgr Destructor + */ + + ~CIconMgr(void); + + /** + * Create and initialize the icon manager window + * + * @param name The prefix for this icon manager name + */ + + bool initialize(FAR const char *prefix); + + /** + * Add a window to an the icon manager + * + * @param win the TWM window structure + */ + + bool add(FAR CWindow *win); + + /** + * Hide the icon manager + */ + + inline void hide(void) + { + if (m_window != (FAR CWindow *)0) + { + m_window->iconify(); + } + } + + /** + * Remove a window from the icon manager + * + * @param win the TWM window structure + */ + + void remove(FAR struct SWindow *win); + + /** + * Get the number of columns + */ + + inline unsigned int getColumns(void) + { + return m_columns; + } + + /** + * Get the current column + */ + + inline unsigned int getCurrColumn(void) + { + return m_curcolumns; + } + + /** + * Get the current size + */ + + inline bool getSize(FAR struct nxgl_size_s *size) + { + return m_window->getFrameSize(size); + } + + /** + * Move the pointer around in an icon manager + * + * @param dir one of the following: + * - EVENT_ICONMGR_FORWARD: Forward in the window list + * - EVENT_ICONMGR_BACK: Backward in the window list + * - EVENT_ICONMGR_UP: Up one row + * - EVENT_ICONMGR_DOWN: Down one row + * - EVENT_ICONMGR_LEFT: Left one column + * - EVENT_ICONMGR_RIGHT: Right one column + */ + + void move(int dir); + + /** + * Pack the icon manager windows following an addition or deletion + */ + + void pack(void); + + /** + * sort the windows + */ + + void sort(void); + + /** + * Handle ICONMGR events. + * + * @param eventmsg. The received NxWidget ICONMGR event message. + * @return True if the message was properly handled. false is + * return on any failure. + */ + + bool event(FAR struct SEventMsg *eventmsg); + }; +} + +///////////////////////////////////////////////////////////////////////////// +// Public Function Prototypes +///////////////////////////////////////////////////////////////////////////// + +#endif // __APPS_INCLUDE_GRAPHICS_TWM4NX_CICONMGR_HXX diff --git a/include/graphics/twm4nx/ciconwin.hxx b/include/graphics/twm4nx/ciconwin.hxx new file mode 100644 index 000000000..4b949909e --- /dev/null +++ b/include/graphics/twm4nx/ciconwin.hxx @@ -0,0 +1,214 @@ +///////////////////////////////////////////////////////////////////////////// +// apps/graphics/twm4nx/include/ciconwin.hxx +// Icon Windows +// +// Copyright (C) 2019 Gregory Nutt. All rights reserved. +// Author: Gregory Nutt +// +// Largely an original work but derives from TWM 1.0.10 in many ways: +// +// Copyright 1989,1998 The Open Group +// +// Please refer to apps/twm4nx/COPYING for detailed copyright information. +// +// 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. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef __APPS_INCLUDE_GRAPHICS_TWM4NX_CICONWIN_HXX +#define __APPS_INCLUDE_GRAPHICS_TWM4NX_CICONWIN_HXX + +///////////////////////////////////////////////////////////////////////////// +// Included Files +///////////////////////////////////////////////////////////////////////////// + +#include + +#include "graphics/nxwidgets/cnxwindow.hxx" + +///////////////////////////////////////////////////////////////////////////// +// Implementation Classes +///////////////////////////////////////////////////////////////////////////// + +namespace NXWidgets +{ + struct SRlePaletteBitmap; // Forward reference +} + +namespace Twm4Nx +{ + class CTwm4Nx; // Forward reference + class CWindow; // Forward reference + + /** + * The CIconWin represents on icon window + */ + + class CIconWin + { + private: + + FAR CTwm4Nx *m_twm4nx; /**< The Twm4Nx session */ + FAR NXWidgets::CNxWindow *m_nxwin; /**< The cursor "raw" window */ + + // Dragging + + struct nxgl_point_s m_dragPos; /**< Last mouse position */ + struct nxgl_point_s m_dragOffset; /**< Offset from mouse to window origin */ + struct nxgl_size_s m_dragCSize; /**< The grab cursor size */ + bool m_drag; /**< Drag in-progress */ + + /** + * Handle the ICON_GRAB event. That corresponds to a left + * mouse click on the icon + * + * @param eventmsg. The received NxWidget event message. + * @return True if the message was properly handled. false is + * return on any failure. + */ + + bool iconGrab(FAR struct SEventMsg *eventmsg); + + /** + * Handle the ICON_DRAG event. That corresponds to a mouse + * movement when the icon is in a grabbed state. + * + * @param eventmsg. The received NxWidget event message. + * @return True if the message was properly handled. false is + * return on any failure. + */ + + bool iconDrag(FAR struct SEventMsg *eventmsg); + + /** + * Handle the ICON_UNGRAB event. The corresponds to a mouse + * left button release while in the grabbed + * + * @param eventmsg. The received NxWidget event message. + * @return True if the message was properly handled. false is + * return on any failure. + */ + + bool iconUngrab(FAR struct SEventMsg *eventmsg); + + /** + * Cleanup on failure or as part of the destructor + */ + + void cleanup(void); + + public: + + /** + * CIconWin Constructor + */ + + CIconWin(CTwm4Nx *twm4nx); + + /** + * CIconWin Destructor + */ + + ~CIconWin(void); + + /** + * Initialize the icon window + * + * @param parent The parent window + * @param sbitmap The Icon bitmap image + * @param pos The default position + */ + + bool initialize(FAR CWindow *parent, + FAR const struct NXWidgets::SRlePaletteBitmap *sbitmap, + FAR const struct nxgl_point_s *pos); + + /** + * Get the size of the icon window on the background + * + * @param size The location to return the size of the icon window + */ + + inline bool getSize(FAR struct nxgl_size_s *size) + { + return m_nxwin->getSize(size); + } + + /** + * Get the icon window position on the background + * + * @param size The location to return the position of the icon window + */ + + inline bool getPosition(FAR struct nxgl_point_s *pos) + { + return m_nxwin->getPosition(pos); + } + + /** + * Set the icon window position on the background + * + * @param size The new position of the icon window + */ + + inline bool setPosition(FAR const struct nxgl_point_s *pos) + { + return m_nxwin->setPosition(pos); + } + + /** + * Raise the icon window. + */ + + inline void raise(void) + { + m_nxwin->raise(); + } + + /** + * Lower the icon window. + */ + + inline void lower(void) + { + m_nxwin->lower(); + } + + /** + * Handle ICON WINDOW events. + * + * @param eventmsg. The received NxWidget ICON event message. + * @return True if the message was properly handled. false is + * return on any failure. + */ + + bool event(FAR struct SEventMsg *eventmsg); + }; +} + +#endif // __APPS_INCLUDE_GRAPHICS_TWM4NX_CICONWIN_HXX diff --git a/include/graphics/twm4nx/cinput.hxx b/include/graphics/twm4nx/cinput.hxx new file mode 100644 index 000000000..e4a9ea218 --- /dev/null +++ b/include/graphics/twm4nx/cinput.hxx @@ -0,0 +1,209 @@ +///////////////////////////////////////////////////////////////////////////// +// apps/graphics/twm4nx/include/cinput.hxx +// Keyboard injection +// +// 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. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef __APPS_INCLUDE_GRAPHICS_TWM4NX_CINPUT_HXX +#define __APPS_INCLUDE_GRAPHICS_TWM4NX_CINPUT_HXX + +///////////////////////////////////////////////////////////////////////////// +// Included Files +///////////////////////////////////////////////////////////////////////////// + +#include + +#include +#include + +#include + +#include "graphics/nxwidgets/cnxserver.hxx" + +///////////////////////////////////////////////////////////////////////////// +// Implementation Classes +///////////////////////////////////////////////////////////////////////////// + +namespace Twm4Nx +{ + class CTwm4Nx; // Forward reference + + /** + * The CInput class provides receives raw keyboard and mouse inputs and + * injects that input into NX which it can be properly distributed to the + * window that has focus (i.e., the window at the top of the display + * hierarchy, often a modal window). In additional, the cursor is + * controlled to track the mouse position. + */ + + class CInput + { + private: + + /** + * The state of the listener thread. + */ + + enum EListenerState + { + LISTENER_NOTRUNNING = 0, /**< The listener thread has not yet been started */ + LISTENER_STARTED, /**< The listener thread has been started, but is not yet running */ + LISTENER_RUNNING, /**< The listener thread is running normally */ + LISTENER_STOPREQUESTED, /**< The listener thread has been requested to stop */ + LISTENER_TERMINATED, /**< The listener thread terminated normally */ + LISTENER_FAILED /**< The listener thread terminated abnormally */ + }; + + /** + * CInput state data + */ + + CTwm4Nx *m_twm4nx; /**< The Twm4Nx session */ + int m_kbdFd; /**< File descriptor of the opened keyboard device */ + int m_mouseFd; /**< File descriptor of the opened mouse device */ + pthread_t m_thread; /**< The listener thread ID */ + volatile enum EListenerState m_state; /**< The state of the listener thread */ + sem_t m_waitSem; /**< Used to synchronize with the listener thread */ + + /** + * Open the keyboard device. Not very interesting for the case of + * standard device but much more interesting for a USB keyboard device + * that may disappear when the keyboard is disconnect but later reappear + * when the keyboard is reconnected. In this case, this function will + * not return until the keyboard device was successfully opened (or + * until an irrecoverable error occurs. + * + * Opens the keyboard device specified by CONFIG_TWM4NX_KEYBOARD_DEVPATH. + * + * @return On success, then method returns a valid file descriptor. A + * negated errno value is returned if an irrecoverable error occurs. + */ + + inline int keyboardOpen(void); + + /** + * Open the mouse input devices. Not very interesting for the + * case of standard character device but much more interesting for + * USB mouse devices that may disappear when disconnected but later + * reappear when reconnected. In this case, this function will + * not return until the input device was successfully opened (or + * until an irrecoverable error occurs). + * + * Opens the mouse input device specified by CONFIG_TWM4NX_MOUSE_DEVPATH. + * + * @return On success, then method returns a valid file descriptor. A + * negated errno value is returned if an irrecoverable error occurs. + */ + + inline int mouseOpen(void); + + /** + * Read data from the keyboard device and inject the keyboard data + * into NX for proper distribution. + * + * @return On success, then method returns a valid file descriptor. A + * negated errno value is returned if an irrecoverable error occurs. + */ + + inline int keyboardInput(void); + + /** + * Read data from the mouse device, update the cursor position, and + * inject the mouse data into NX for proper distribution. + * + * @return On success, then method returns a valid file descriptor. A + * negated errno value is returned if an irrecoverable error occurs. + */ + + inline int mouseInput(void); + + /** + * This is the heart of the keyboard/mouse listener thread. It + * contains the actual logic that listeners for and dispatches input + * events to the NX server. + * + * @return If the session terminates gracefully (i.e., because >m_state + * is no longer equal to LISTENER_RUNNING, then method returns OK. A + * negated errno value is returned if an error occurs while reading from + * the input device. A read error, depending upon the type of the + * error, may simply indicate that a USB device was removed and we + * should wait for the device to be connected. + */ + + inline int session(void); + + /** + * The keyboard/mouse listener thread. This is the entry point of a + * thread that listeners for and dispatches keyboard and mouse events + * to the NX server. It simply opens the input devices (using + * CInput::keyboardOpen() and CInput::mouseOpen()) and executes the + * session (via CInput::session()). + * + * If an errors while reading from the input device AND that device is + * configured to use a USB connection, then this function will wait for + * the USB device to be re-connected. + * + * @param arg. The CInput 'this' pointer cast to a void*. + * @return This function normally does not return but may return NULL + * on error conditions. + */ + + static FAR void *listener(FAR void *arg); + + public: + + /** + * CInput Constructor + * + * @param twm4nx. An instance of the Twm4Nx session. + */ + + CInput(CTwm4Nx *twm4nx); + + /** + * CInput Destructor + */ + + ~CInput(void); + + /** + * Start the keyboard listener thread. + * + * @return True if the keyboard listener thread was correctly started. + */ + + bool start(void); + }; +} + +#endif // __APPS_INCLUDE_GRAPHICS_TWM4NX_CINPUT_HXX diff --git a/include/graphics/twm4nx/cmenus.hxx b/include/graphics/twm4nx/cmenus.hxx new file mode 100644 index 000000000..f790b8590 --- /dev/null +++ b/include/graphics/twm4nx/cmenus.hxx @@ -0,0 +1,289 @@ +///////////////////////////////////////////////////////////////////////////// +// apps/graphics/twm4nx/include/Cmenus.hxx +// Twm4Nx menus definitions +// +// Copyright (C) 2019 Gregory Nutt. All rights reserved. +// Author: Gregory Nutt +// +// Largely an original work but derives from TWM 1.0.10 in many ways: +// +// Copyright 1989,1998 The Open Group +// Copyright 1988 by Evans & Sutherland Computer Corporation, +// +// Please refer to apps/twm4nx/COPYING for detailed copyright information. +// +// 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. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef __APPS_INCLUDE_GRAPHICS_TWM4NX_CMENUS_HXX +#define __APPS_INCLUDE_GRAPHICS_TWM4NX_CMENUS_HXX + +///////////////////////////////////////////////////////////////////////////// +// Included Files +///////////////////////////////////////////////////////////////////////////// + +#include "mqueue.h" + +#include "graphics/nxwidgets/cwidgeteventhandler.hxx" +#include "graphics/nxwidgets/cwidgeteventargs.hxx" + +///////////////////////////////////////////////////////////////////////////// +// Pre-processor Definitions +///////////////////////////////////////////////////////////////////////////// + +#define TWM_WINDOWS "TwmNxWindows" // for f.menu "TwmNxWindows" + +#define SIZE_HINDENT 10 +#define SIZE_VINDENT 2 + +#define MAXMENUDEPTH 10 // max number of nested menus + +#define MOVE_NONE 0 // modes of constrained move +#define MOVE_VERT 1 +#define MOVE_HORIZ 2 + +#define SHADOWWIDTH 5 // in pixels + +// Info stings defines + +#define INFO_LINES 30 +#define INFO_SIZE 200 + +///////////////////////////////////////////////////////////////////////////// +// Implementation Classes +///////////////////////////////////////////////////////////////////////////// + +namespace NXWidgets +{ + class CNxTkWindow; // Forward reference + class CListBox; // Forward reference +} + +namespace Twm4Nx +{ + struct SEventMsg; // Forward referernce + class CWindow; // Forward reference + class CMenus; // Forward reference + + struct SMenuItem + { + FAR struct SMenuItem *flink; /**< Forward link to next menu item */ + FAR struct SMenuItem *blink; /**< Backward link previous menu item */ + FAR CMenus *subMenu; /**< Menu root of a pull right menu */ + FAR char *text; /**< The text string for the menu item */ + FAR const char *action; /**< Action to be performed */ + short index; /**< Index of this menu item */ + short func; /**< Built-in function */ + }; + + class CMenus: protected NXWidgets::CWidgetEventHandler + { + private: + + CTwm4Nx *m_twm4nx; /**< Cached Twm4Nx session */ + mqd_t m_eventq; /**< NxWidget event message queue */ + FAR struct SFuncKey *m_funcKeyHead; /**< Head of function key list */ + FAR NXWidgets::CNxTkWindow *m_menuWindow; /**< The menu window */ + FAR CMenus *m_popUpMenu; /**< Pop-up menu */ + FAR NXWidgets::CListBox *m_menuListBox; /**< The menu list box */ + FAR struct SMenuItem *m_activeItem; /**< The active menu item */ + FAR struct SMenuItem *m_menuHead; /**< First item in menu */ + FAR struct SMenuItem *m_menuTail; /**< Last item in menu */ + FAR char *m_menuName; /**< The name of the menu */ + nxgl_coord_t m_entryHeight; /**< Menu entry height */ + uint16_t m_nMenuItems; /**< Number of items in the menu */ + uint8_t m_menuDepth; /**< Number of menus up */ + bool m_menuPull; /**< Is there a pull right entry? */ + char m_info[INFO_LINES][INFO_SIZE]; + + void identify(FAR CWindow *cwin); + + /** + * Convert the position of a menu window to the position of + * the containing frame. + */ + + inline void menuToFramePos(FAR const struct nxgl_point_s *menupos, + FAR struct nxgl_point_s *framepos) + { + framepos->x = menupos->x - CONFIG_NXTK_BORDERWIDTH; + framepos->y = menupos->y - CONFIG_NXTK_BORDERWIDTH; + } + + /** + * Convert the position of the containing frame to the position of + * the menu window. + */ + + inline void frameToMenuPos(FAR const struct nxgl_point_s *framepos, + FAR struct nxgl_point_s *menupos) + { + menupos->x = framepos->x + CONFIG_NXTK_BORDERWIDTH; + menupos->y = framepos->y + CONFIG_NXTK_BORDERWIDTH; + } + + /** + * Convert the size of a menu window to the size of the containing + * frame. + */ + + inline void menuToFrameSize(FAR const struct nxgl_size_s *menusize, + FAR struct nxgl_size_s *framesize) + { + framesize->w = menusize->w + 2 * CONFIG_NXTK_BORDERWIDTH; + framesize->h = menusize->h + 2 * CONFIG_NXTK_BORDERWIDTH; + } + + /** + * Convert the size of a containing frame to the size of the menu + * window. + */ + + inline void frameToMenuSize(FAR const struct nxgl_size_s *framesize, + FAR struct nxgl_size_s *menusize) + { + menusize->w = framesize->w - 2 * CONFIG_NXTK_BORDERWIDTH; + menusize->h = framesize->h - 2 * CONFIG_NXTK_BORDERWIDTH; + } + + /** + * Create the menu window + * + * @result True is returned on success + */ + + bool createMenuWindow(void); + + /** + * Update the menu window size + * + * @result True is returned on success + */ + + bool setMenuWindowSize(void); + + /** + * Set the position of the menu window. Supports positioning of a + * pop-up window. + * + * @param framePos The position of the menu window frame + * @result True is returned on success + */ + + bool setMenuWindowPosition(FAR struct nxgl_point_s *framePos); + + /** + * Set the position of the menu window. Supports presentation of a + * pop-up window. + * + * @param framePos The position of the menu window frame + * @result True is returned on success + */ + + inline bool raiseMenuWindow() + { + return m_menuWindow->raise(); + } + + /** + * Create the menu list box + * + * @result True is returned on success + */ + + bool createMenuListBox(void); + + void paintMenu(void); + void destroyMenu(void); + + /** + * Pop up a pull down menu. + * + * @param pos Location of upper left of menu + */ + + bool popUpMenu(FAR struct nxgl_point_s *pos); + + /** + * Cleanup or initialization error or on deconstruction. + */ + + void cleanup(void); + + public: + /** + * CMenus Constructor + * + * @param twm4nx. Twm4Nx session + */ + + CMenus(CTwm4Nx *twm4nx); + + /** + * CMenus Destructor + */ + + ~CMenus(void); + + /** + * CMenus Initializer. Performs the parts of the CMenus construction + * that may fail. + * + * @param name The menu name + * @result True is returned on success + */ + + bool initialize(FAR const char *name); + + /** + * Add an item to a root menu + * + * \param text The text to appear in the menu + * \param action The string to possibly execute + * \param subMenu The menu root if it is a pull-right entry + * \param func The numeric function + */ + + bool addMenuItem(FAR const char *text, + FAR const char *action, + FAR CMenus *subMenu, int func); + + /** + * Handle MENU events. + * + * @param msg. The received NxWidget MENU event message. + * @return True if the message was properly handled. false is + * return on any failure. + */ + + bool event(FAR struct SEventMsg *msg); + }; +} + +#endif // __APPS_INCLUDE_GRAPHICS_TWM4NX_CMENUS_HXX diff --git a/include/graphics/twm4nx/cresize.hxx b/include/graphics/twm4nx/cresize.hxx new file mode 100644 index 000000000..139a60a9d --- /dev/null +++ b/include/graphics/twm4nx/cresize.hxx @@ -0,0 +1,248 @@ +///////////////////////////////////////////////////////////////////////////// +// apps/graphics/twm4nx/include/cresize.hxx +// Resize function externs +// +// Copyright (C) 2019 Gregory Nutt. All rights reserved. +// Author: Gregory Nutt +// +// Largely an original work but derives from TWM 1.0.10 in many ways: +// +// Copyright 1989,1998 The Open Group +// Copyright 1988 by Evans & Sutherland Computer Corporation, +// +// Please refer to apps/twm4nx/COPYING for detailed copyright information. +// +// 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. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef __APPS_INCLUDE_GRAPHICS_TWM4NX_CRESIZE_HXX +#define __APPS_INCLUDE_GRAPHICS_TWM4NX_CRESIZE_HXX + +///////////////////////////////////////////////////////////////////////////// +// Included Files +///////////////////////////////////////////////////////////////////////////// + +#include + +#include + +///////////////////////////////////////////////////////////////////////////// +// Implementation Classes +///////////////////////////////////////////////////////////////////////////// + +namespace NXWidgets +{ + class CNxTkWindow; // Forward reference +} + +namespace Twm4Nx +{ + class CWindow; // Forward referernce + struct SEventMsg; // Forward referernce + + class CResize + { + private: + + CTwm4Nx *m_twm4nx; /**< Cached Twm4Nx session */ + FAR NXWidgets::CNxTkWindow *m_sizeWindow; /**< The resize dimensions window */ + FAR CWindow *m_resizeWindow; /**< The window being resized */ + struct nxgl_point_s m_origpos; /**< Original position */ + struct nxgl_size_s m_origsize; /**< Original size */ + struct nxgl_point_s m_dragpos; /**< Dragged position */ + struct nxgl_size_s m_dragsize; /**< Dragged size */ + struct nxgl_rect_s m_clamp; + struct nxgl_point_s m_delta; + struct nxgl_size_s m_last; + struct nxgl_point_s m_addingPos; + struct nxgl_size_s m_addingSize; + int m_stringWidth; /**< Size of current size string */ + +#ifdef CONFIG_TWM4NX_AUTO_RERESIZE // Resize relative to position in quad + void autoClamp(CWindow *cwin, FAR struct SEventMsg *eventmsg); +#endif + + void resizeFromCenter(FAR CWindow *win); + + /** + * Begin a window resize operation + * @param ev the event structure (button press) + * @param cwin the TWM window pointer + */ + + void startResize(FAR struct SEventMsg *eventmsg, FAR CWindow *cwin); + + void menuStartResize(FAR CWindow *cwin, + FAR struct nxgl_point_s *pos, + FAR struct nxgl_size_s *size); + + /** + * Display the size in the dimensions window. + * + * @param cwin The current window + * @param size The size of the rubber band + */ + + void displaySize(FAR CWindow *cwin, FAR struct nxgl_size_s *size); + + public: + + /** + * CResize Constructor + * + * @param twm4nx The Twm4Nx session + */ + + CResize(CTwm4Nx *twm4nx); + + /** + * CResize Destructor + */ + + ~CResize(void); + + /** + * CResize Initializer. Performs the parts of the CResize construction + * that may fail. + * + * @result True is returned on success + */ + + bool initialize(void); + + /** + * What is this? + */ + + void addingSize(FAR struct nxgl_size_s *size) + { + m_addingSize.w = size->w; + m_addingSize.h = size->h; + } + + /** + * Begin a window resize operation + * + * @param cwin the Twm4Nx window pointer + */ + + void addStartResize(FAR CWindow *cwin, + FAR struct nxgl_point_s *pos, + FAR struct nxgl_size_s *size); + + /** + * @param cwin The current Twm4Nx window + * @param root The X position in the root window + */ + + void menuDoResize(FAR CWindow *cwin, + FAR struct nxgl_point_s *root); + + /** + * Move the rubberband around. This is called for each motion event when + * we are resizing + * + * @param cwin The current Twm4Nx window + * @param root The X position in the root window + */ + + void doResize(FAR CWindow *cwin, + FAR struct nxgl_point_s *root); + + /** + * Finish the resize operation + */ + + void endResize(FAR CWindow *cwin); + + void menuEndResize(FAR CWindow *cwin); + + /** + * Finish the resize operation for AddWindoframe_XXX variables should NOT be updated with the values of + * x,y,w,h prior to calling this routine, since the new values are compared + * against the old to see whether a synthetic ConfigureNotify event should be + * sent. (It should be sent if the window was moved but not resized.) + * + * @param cwin The CWiondow instance + * @param pos The position of the upper-left outer corner of the frame + * @param size The size of the frame window + */ + + void setupWindow(FAR CWindow *cwin, + FAR struct nxgl_point_s *pos, + FAR struct nxgl_size_s *size); + + /** + * Zooms window to full height of screen or to full height and width of screen. + * (Toggles so that it can undo the zoom - even when switching between fullZoom + * and vertical zoom.) + * + * @param cwin the TWM window pointer + */ + + void fullZoom(FAR CWindow *cwin, int flag); + + /** + * Handle RESIZE events. + * + * @param msg. The received NxWidget RESIZE event message. + * @return True if the message was properly handled. false is + * return on any failure. + */ + + bool event(FAR struct SEventMsg *msg); + }; +} + +#endif // __APPS_INCLUDE_GRAPHICS_TWM4NX_CRESIZE_HXX diff --git a/include/graphics/twm4nx/ctwm4nx.hxx b/include/graphics/twm4nx/ctwm4nx.hxx new file mode 100644 index 000000000..f4234bcd6 --- /dev/null +++ b/include/graphics/twm4nx/ctwm4nx.hxx @@ -0,0 +1,315 @@ +///////////////////////////////////////////////////////////////////////////// +// apps/graphics/twm4nx/include/ctwm4nx.hxx +// twm include file +// +// Copyright (C) 2019 Gregory Nutt. All rights reserved. +// Author: Gregory Nutt +// +// Largely an original work but derives from TWM 1.0.10 in many ways: +// +// Copyright 1989,1998 The Open Group +// Copyright 1988 by Evans & Sutherland Computer Corporation, +// +// Please refer to apps/twm4nx/COPYING for detailed copyright information. +// +// 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. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef __APPS_INCLUDE_GRAPHICS_TWM4NX_CTWM4NX_HXX +#define __APPS_INCLUDE_GRAPHICS_TWM4NX_CTWM4NX_HXX + +///////////////////////////////////////////////////////////////////////////// +// Included Files +///////////////////////////////////////////////////////////////////////////// + +#include + +#include +#include +#include + +#include +#include +#include + +#include "graphics/nxwidgets/nxconfig.hxx" +#include "graphics/nxwidgets/cnxserver.hxx" +#include "graphics/nxwidgets/cnxwindow.hxx" +#include "graphics/nxwidgets/cimage.hxx" + +#include "graphics/twm4nx/cwindowevent.hxx" +#include "graphics/twm4nx/twm4nx_widgetevents.hxx" + +///////////////////////////////////////////////////////////////////////////// +// Pre-processor Definitions +///////////////////////////////////////////////////////////////////////////// + +// Defines for zooming/unzooming + +#define ZOOM_NONE 0 + +///////////////////////////////////////////////////////////////////////////// +// Implementation Classes +///////////////////////////////////////////////////////////////////////////// + +namespace Twm4Nx +{ + class CInput; // Forward reference + class CBackground; // Forward reference + class CWidgetEvent; // Forward reference + class CIcon; // Forward reference + class CIconMgr; // Forward reference + class CFonts; // Forward reference + class CWindow; // Forward reference + class CResize; // Forward reference + class CWindowFactory; // Forward reference + class CResize; // Forward reference + struct SWindow; // Forward reference + + /** + * Public Constant Data + */ + + extern const char GNoName[]; /**< Name to use when there is no name */ + + /** + * This class provides the overall state of the window manager. It is also + * the heart of the window manager: It inherits for CNxServer and, hence, + * represents the NX server itself. + */ + + class CTwm4Nx : public NXWidgets::CNxServer + { + private: + int m_display; /**< Display that we are using */ + FAR char *m_queueName; /**< NxWidget event queue name */ + mqd_t m_eventq; /**< NxWidget event message queue */ + FAR CBackground *m_background; /**< Background window management */ + FAR CInput *m_input; /**< Keyboard/mouse input injector */ + FAR CIcon *m_icon; /**< The cached Cicon instance */ + FAR CIconMgr *m_iconmgr; /**< The Default icon manager */ + FAR CWindowFactory *m_factory; /**< The cached CWindowFactory instance */ + FAR CFonts *m_fonts; /**< The cached Cfonts instance */ + FAR CResize *m_resize; /**< The cached CResize instance */ + + /* Display properties */ + + FAR struct nxgl_size_s m_displaySize; /**< Size of the display */ + FAR struct nxgl_size_s m_maxWindow; /**< Maximum size of a window */ + + /** + * Connect to the NX server + * + * @return True if the message was properly handled. false is + * return on any failure. + */ + + bool connect(void); + + /** + * Generate a random message queue name. Different message queue + * names are required for each instance of Twm4Nx that is started. + */ + + inline void genMqName(void); + + /** + * Handle SYSTEM events. + * + * @param eventmsg. The received NxWidget SYSTEM event message. + * @return True if the message was properly handled. false is + * return on any failure. + */ + + inline bool systemEvent(FAR struct SEventMsg *eventmsg); + + /** + * Cleanup in preparation for termination. + */ + + void cleanup(void); + + public: + + /** + * CTwm4Nx Constructor + * + * @param display. Indicates which display will be used. Usually zero + * except in the case wehre there of multiple displays. + */ + + CTwm4Nx(int display); + + /** + * CTwm4Nx Destructor + */ + + ~CTwm4Nx(void); + + /** + * This is the main, controlling thread of the window manager. It is + * called only from the extern "C" main() entry point. + * + * NOTE: In the event of truly abnormal conditions, this function will + * not return. It will exit via the abort() method. + * + * @return True if the window manager was terminated properly. false is + * return on any failure. + */ + + bool run(void); + + /** + * Return a reference to the randomly generated event messageq queue + * name. Different message queue names are required for each instance + * of Twm4Nx that is started. + */ + + inline FAR const char *getEventQueueName(void) + { + return m_queueName; + } + + /** + * Return the size of the physical display (whichi is equivalent to the + * size of the contained background window). + * + * @return The size of the display. + */ + + inline void getDisplaySize(FAR struct nxgl_size_s *size) + { + size->w = m_displaySize.w; + size->h = m_displaySize.h; + } + + /** + * Return the pixel depth. + * + * REVISIT: Currently only the pixel depth configured for NxWidgets is + * supported. That is probably compatible ith support for multiple + * displays of differing resolutions. + * + * @return The number of bits-per-pixel. + */ + + inline uint8_t getPixelDepth(void) + { + return CONFIG_NXWIDGETS_BPP; + } + + /** + * Return the maximum size of a window. + * + * @return The maximum size of a window. + */ + + inline void maxWindowSize(FAR struct nxgl_size_s *size) + { + size->w = m_maxWindow.w; + size->h = m_maxWindow.h; + } + + /** + * Return the session's Icon instance. + * + * @return The contained instance of the Icon class for this session. + */ + + inline FAR CIcon *getIcon(void) + { + return m_icon; + } + + /** + * Return the session's Icon Manager instance. + * + * @return The contained instance of the Icon Manager for this session. + */ + + inline FAR CIconMgr *getIconMgr(void) + { + return m_iconmgr; + } + + /** + * Return the session's CWindowFactory instance. + * + * @return The contained instance of the CWindow instance this session. + */ + + inline FAR CWindowFactory *getWindowFactory(void) + { + return m_factory; + } + + /** + * Return the session's CFonts instance. + * + * @return The contained instance of the CMenus instance for this session. + */ + + inline FAR CFonts *getFonts(void) + { + return m_fonts; + } + + /** + * Return the session's CResize instance. + * + * @return The contained instance of the CResize instance for this + * session. + */ + + inline FAR CResize *getResize(void) + { + return m_resize; + } + + /** + * Dispatch NxWidget-related events. Normally used only internally + * but there is one use case where messages are injected here from + * CMenus. + * + * @param eventmsg. The received NxWidget event message. + * @return True if the message was properly dispatched. false is + * return on any failure. + */ + + bool dispatchEvent(FAR struct SEventMsg *eventmsg); + + /** + * Cleanup and exit Twm4Nx abnormally. + */ + + void abort(void); + }; +} + +#endif // __APPS_INCLUDE_GRAPHICS_TWM4NX_CTWM4NX_HXX diff --git a/include/graphics/twm4nx/cwindow.hxx b/include/graphics/twm4nx/cwindow.hxx new file mode 100644 index 000000000..0f6f919fb --- /dev/null +++ b/include/graphics/twm4nx/cwindow.hxx @@ -0,0 +1,592 @@ +///////////////////////////////////////////////////////////////////////////// +// apps/graphics/twm4nx/include/cwindow.hxx +// Represents one window instance +// +// Copyright (C) 2019 Gregory Nutt. All rights reserved. +// Author: Gregory Nutt +// +// Largely an original work but derives from TWM 1.0.10 in many ways: +// +// Copyright 1989,1998 The Open Group +// Copyright 1988 by Evans & Sutherland Computer Corporation, +// +// Please refer to apps/twm4nx/COPYING for detailed copyright information. +// +// 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. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef __APPS_INCLUDE_GRAPHICS_TWM4NX_CWINDOW_HXX +#define __APPS_INCLUDE_GRAPHICS_TWM4NX_CWINDOW_HXX + +///////////////////////////////////////////////////////////////////////////// +// Included Files +///////////////////////////////////////////////////////////////////////////// + +#include + +#include + +#include "graphics/nxwidgets/cnxtoolbar.hxx" +#include "graphics/nxwidgets/cwidgeteventhandler.hxx" +#include "graphics/nxwidgets/cwidgeteventargs.hxx" + +#include "graphics/twm4nx/ciconwin.hxx" + +///////////////////////////////////////////////////////////////////////////// +// Pre-processor Definitions +///////////////////////////////////////////////////////////////////////////// + +/** + * Toolbar Icons. The Title bar contains (from left to right): + * + * 1. Menu button + * 2. Window title (text) + * 3. Minimize (Iconify) button + * 4. Resize button + * 5. Delete button + * + * There is no focus indicator + */ + +#define MENU_BUTTON 0 // First on left +#define DELETE_BUTTON 1 // First on right +#define RESIZE_BUTTON 2 +#define MINIMIZE_BUTTON 3 +#define NTOOLBAR_BUTTONS 4 + +///////////////////////////////////////////////////////////////////////////// +// Implementation Classes +///////////////////////////////////////////////////////////////////////////// + +namespace NXWidgets +{ + class CImage; // Forward reference + class CLabel; // Forward reference + struct SRlePaletteBitmap; // Forward reference +} + +namespace Twm4Nx +{ + class CIconWin; // Forward reference + class CIconMgr; // Forward reference + class CWindow; // Forward reference + struct SMenuRoot; // Forward reference + struct SMenuItem; // Forward reference + struct SToolbarButton; // Forward reference + + // The CWindow class implements a standard, framed window with a toolbar + // containing the standard buttons and the window title. + + class CWindow : protected NXWidgets::CWidgetEventHandler + { + private: + CTwm4Nx *m_twm4nx; /**< Cached Twm4Nx session */ + mqd_t m_eventq; /**< NxWidget event message queue */ + + // Primary Window + + FAR char *m_name; /**< Name of the window */ + FAR NXWidgets::CNxTkWindow *m_nxWin; /**< The contained NX primary window */ + uint16_t m_zoom; /**< Window zoom: ZOOM_NONE or EVENT_RESIZE_* */ + bool m_modal; /**< Window zoom: ZOOM_NONE or EVENT_RESIZE_* */ + + // Icon + + FAR CIconWin *m_iconWin; /**< The icon window */ + FAR CIconMgr *m_iconMgr; /**< Pointer to it if this is an icon manager */ + bool m_isIconMgr; /**< This is an icon manager window */ + bool m_iconMoved; /**< User explicitly moved the icon. */ + bool m_iconOn; /**< Icon is visible. */ + bool m_iconified; /**< Is the window an icon now ? */ + + // Toolbar + + FAR NXWidgets::CNxToolbar *m_toolbar; /**< The tool bar sub-window */ + FAR NXWidgets::CLabel *m_tbTitle; /**< Toolbar title widget */ + nxgl_coord_t m_tbHeight; /**< Height of the toolbar */ + nxgl_coord_t m_tbLeftX; /**< Rightmost position of left buttons */ + nxgl_coord_t m_tbRightX; /**< Leftmost position of right buttons */ + + // List of all toolbar button images + + FAR NXWidgets::CImage *m_tbButtons[NTOOLBAR_BUTTONS]; + + // Dragging + + struct nxgl_point_s m_dragOffset; /**< Offset from mouse to window origin */ + struct nxgl_size_s m_dragCSize; /**< The grab cursor size */ + bool m_drag; /**< Drag in-progress */ + + /** + * Create the main window + * + * @param winsize The initial window size + * @param winpos The initial window position + */ + + bool createMainWindow(FAR const nxgl_size_s *winsize, + FAR const nxgl_point_s *winpos); + + /** + * Calculate the height of the tool bar + */ + + bool getToolbarHeight(FAR const char *name); + + /** + * Create all toolbar buttons + */ + + bool createToolbarButtons(void); + + /** + * Add buttons and title widgets to the tool bar + * + * @param name The name to use for the toolbar title + */ + + bool createToolbarTitle(FAR const char *name); + + /** + * Create the tool bar + */ + + bool createToolbar(void); + + /** + * Update the toolbar layout, resizing the title text window and + * repositioning all windows on the toolbar. + */ + + bool updateToolbarLayout(void); + + /** + * Disable widget drawing and widget events. + */ + + bool disableWidgets(void); + + /** + * Enable widget drawing and widget events. + */ + + bool enableWidgets(void); + + /** + * Override the mouse button drag event. + * + * @param e The event data. + */ + + void handleDragEvent(const NXWidgets::CWidgetEventArgs &e); + + /** + * Override a drop event, triggered when the widget has been dragged-and-dropped. + * + * @param e The event data. + */ + + void handleDropEvent(const NXWidgets::CWidgetEventArgs &e); + + /** + * Handle a key press event. + * + * @param e The event data. + */ + + void handleKeyPressEvent(const NXWidgets::CWidgetEventArgs &e); + + /** + * Override the virtual CWidgetEventHandler::handleActionEvent. This + * event will fire when the image is released but before it has been + * has been drawn. isClicked() will return true for the appropriate + * images. + * + * @param e The event data. + */ + + void handleActionEvent(const NXWidgets::CWidgetEventArgs &e); + + /** + * Handle the TOOLBAR_GRAB event. That corresponds to a left + * mouse click on the toolbar (other than on an icon) + * + * @param eventmsg. The received NxWidget event message. + * @return True if the message was properly handled. false is + * return on any failure. + */ + + bool toolbarGrab(FAR struct SEventMsg *eventmsg); + + /** + * Handle the WINDOW_DRAG event. That corresponds to a mouse + * movement when the window is in a grabbed state. + * + * @param eventmsg. The received NxWidget event message. + * @return True if the message was properly handled. false is + * return on any failure. + */ + + bool windowDrag(FAR struct SEventMsg *eventmsg); + + /** + * Handle the TOOLBAR_UNGRAB event. The corresponds to a mouse + * left button release while in the grabbed + * + * @param eventmsg. The received NxWidget event message. + * @return True if the message was properly handled. false is + * return on any failure. + */ + + bool toolbarUngrab(FAR struct SEventMsg *eventmsg); + + /** + * Cleanup on failure or as part of the destructor + */ + + void cleanup(void); + + public: + + /** + * CWindow Constructor + * + * @param twm4nx. Twm4Nx session + */ + + CWindow(CTwm4Nx *twm4nx); + + /** + * CWindow Destructor + */ + + ~CWindow(void); + + /** + * CWindow Initializer (unlike the constructor, this may fail) + * + * @param name The the name of the window (and its icon) + * @param pos The initial position of the window + * @param size The initial size of the window + * @param sbitmap The Icon bitmap image + * @param isIconMgr Flag to tell if this is an icon manager window + * @param iconMgr Pointer to icon manager instance + * @param noToolbar True: Don't add Title Bar + * @return True if the window was successfully initialize; false on + * any failure, + */ + + bool initialize(FAR const char *name, + FAR const struct nxgl_point_s *pos, + FAR const struct nxgl_size_s *size, + FAR const struct NXWidgets::SRlePaletteBitmap *sbitmap, + bool isIconMgr, FAR CIconMgr *iconMgr, bool noToolbar); + + /** + * Get the name of the window + */ + + inline FAR const char *getWindowName(void) + { + return m_name; + } + + /** + * Return true if this is an Icon Manager Window + */ + + inline bool isIconMgr(void) + { + return m_isIconMgr; + } + + /** + * Return the Icon Manager Window instance + */ + + inline FAR CIconMgr *getIconMgr(void) + { + return m_iconMgr; + } + + /** + * Get the size of the primary window. This is useful only + * for applications that need to know the drawing area. + * + * @param size Location to return the primary window size + */ + + inline bool getWindowSize(FAR struct nxgl_size_s *size) + { + return m_nxWin->getSize(size); + } + + /** + * Set the size of the primary window. This is useful only + * for oapplications that need to control the drawing area. + * + * @param size New primary window size + */ + + inline bool setWindowSize(FAR const struct nxgl_size_s *size) + { + return m_nxWin->setSize(size); + } + + /** + * Get the height of the tool bar + */ + + inline nxgl_coord_t getToolbarHeight(void) + { + return m_tbHeight; + } + + /** + * Raise the window to the top of the hierarchy. + */ + + inline bool raiseWindow(void) + { + return m_nxWin->raise(); + } + + /** + * Lower the window to the bottom of the hierarchy. + */ + + inline bool lowerWindow(void) + { + return m_nxWin->lower(); + } + + /** + * Convert the position of a primary window to the position of + * the containing frame. + */ + + inline void windowToFramePos(FAR const struct nxgl_point_s *winpos, + FAR struct nxgl_point_s *framepos) + { + framepos->x = winpos->x - CONFIG_NXTK_BORDERWIDTH; + framepos->y = winpos->y - m_tbHeight - CONFIG_NXTK_BORDERWIDTH; + } + + /** + * Convert the position of the containing frame to the position of the + * primary window. + */ + + inline void frameToWindowPos(FAR const struct nxgl_point_s *framepos, + FAR struct nxgl_point_s *winpos) + { + winpos->x = framepos->x + CONFIG_NXTK_BORDERWIDTH; + winpos->y = framepos->y + m_tbHeight + CONFIG_NXTK_BORDERWIDTH; + } + + /** + * Convert the size of a primary window to the size of the containing + * frame. + */ + + inline void windowToFrameSize(FAR const struct nxgl_size_s *winsize, + FAR struct nxgl_size_s *framesize) + { + framesize->w = winsize->w + 2 * CONFIG_NXTK_BORDERWIDTH; + framesize->h = winsize->h + m_tbHeight + 2 * CONFIG_NXTK_BORDERWIDTH; + } + + /** + * Convert the size of the containing frame to the size of the primary window to the size of the containing + * frame. + */ + + inline void frameToWindowSize(FAR const struct nxgl_size_s *framesize, + FAR struct nxgl_size_s *winsize) + { + winsize->w = framesize->w - 2 * CONFIG_NXTK_BORDERWIDTH; + winsize->h = framesize->h - m_tbHeight - 2 * CONFIG_NXTK_BORDERWIDTH; + } + + /** + * Get the raw window size (including toolbar and frame) + * + * @param framesize Location to return the window frame size + */ + + bool getFrameSize(FAR struct nxgl_size_s *framesize); + + /** + * Update the window frame after a resize operation (includes the toolbar + * and user window) + * + * @param size The new window frame size + * @param pos The frame location which may also have changed + */ + + bool resizeFrame(FAR const struct nxgl_size_s *framesize, + FAR struct nxgl_point_s *framepos); + + /** + * Get the raw frame position (accounting for toolbar and frame) + * + * @param framepos Location to return the window frame position + */ + + bool getFramePosition(FAR struct nxgl_point_s *framepos); + + /** + * Set the raw frame position (accounting for toolbar and frame) + * + * @param framepos The new raw window position + */ + + bool setFramePosition(FAR const struct nxgl_point_s *framepos); + + /* Minimize (iconify) the window */ + + void iconify(void); + + /** + * De-iconify the window + */ + + void deIconify(void); + + /** + * Is the window iconified? + */ + + inline bool isIconified(void) + { + return m_iconified; + } + + /** + * Has the Icon moved? + */ + + inline bool hasIconMoved(void) + { + return m_iconMoved; + } + + /** + * Set Icon moved + */ + + inline void setIconMoved(bool moved) + { + m_iconMoved = moved; + } + + /** + * Get the size of the icon window associated with this application + * window. This is needed for placement of the icon on the background + * window. + * + * @param size Location to return the icon window size + */ + + inline bool getIconWindowSize(FAR struct nxgl_size_s *size) + { + return m_iconWin->getSize(size); + } + + /** + * Get the current position of the icon window associated with the + * application window. This is needed for placement of the icon on + * the background window. + * + * @param pos Location to return the icon window position + */ + + inline bool getIconWindowPosition(FAR struct nxgl_point_s *pos) + { + return m_iconWin->getPosition(pos); + } + + /** + * Set the new position of the icon window associated with the + * application window. This is needed for placement of the icon on the + * background window. + * + * @param pos The new location of the icon window + */ + + inline bool setIconWindowPosition(FAR const struct nxgl_point_s *pos) + { + return m_iconWin->setPosition(pos); + } + + /** + * Get zoom + */ + + inline uint16_t getZoom(void) + { + return m_zoom; + } + + /** + * Set zoom + * + * @param zoom The new zoom setting + */ + + inline void setZoom(uint16_t zoom) + { + m_zoom = zoom; + } + + /** + * Check for widget-related toolbar events, typically button presses. + * This is called by event handling logic for events that require + * detection of widget events. + */ + + inline bool pollToolbarEvents(void) + { + NXWidgets::CWidgetControl *control = m_toolbar->getWidgetControl(); + return control->pollEvents(); + } + + /** + * Handle WINDOW events. + * + * @param eventmsg. The received NxWidget WINDOW event message. + * @return True if the message was properly handled. false is + * return on any failure. + */ + + bool event(FAR struct SEventMsg *eventmsg); + }; +} + +#endif // __APPS_INCLUDE_GRAPHICS_TWM4NX_CWINDOW_HXX diff --git a/include/graphics/twm4nx/cwindowevent.hxx b/include/graphics/twm4nx/cwindowevent.hxx new file mode 100644 index 000000000..ab0a5266d --- /dev/null +++ b/include/graphics/twm4nx/cwindowevent.hxx @@ -0,0 +1,145 @@ +///////////////////////////////////////////////////////////////////////////// +// apps/graphics/twm4nx/src/cwindowevent.hxx +// Shim to manage the interface between NX messages and NxWidgets +// +// 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. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef __APPS_INCLUDE_GRAPHICS_TWM4NX_CWINDOWEVENT_HXX +#define __APPS_INCLUDE_GRAPHICS_TWM4NX_CWINDOWEVENT_HXX + +///////////////////////////////////////////////////////////////////////////// +// Included Files +///////////////////////////////////////////////////////////////////////////// + +#include + +#include +#include + +#include "graphics/nxwidgets/cwindoweventhandler.hxx" +#include "graphics/nxwidgets/cwidgetstyle.hxx" +#include "graphics/nxwidgets/cwidgetcontrol.hxx" +#include "graphics/twm4nx/twm4nx_widgetevents.hxx" +#include "graphics/twm4nx/ctwm4nx.hxx" + +///////////////////////////////////////////////////////////////////////////// +// Implementation Classes +///////////////////////////////////////////////////////////////////////////// + +#if defined(__cplusplus) + +namespace Twm4Nx +{ + /** + * The class CWindowEvent integrates the widget control with some special + * handling of mouse and keyboard inputs needs by NxWM. It use used + * in place of CWidgetControl whenever an NxWM window is created. + * + * CWindowEvent cohabitates with CWidgetControl only because it needs the + * CWidgetControl as an argument in its messaging. + */ + + class CWindowEvent : public NXWidgets::CWindowEventHandler, + public NXWidgets::CWidgetControl + { + private: + FAR CTwm4Nx *m_twm4nx; /**< Cached instance of CTwm4Nx */ + mqd_t m_eventq; /**< NxWidget event message queue */ + + /** + * Send the EVENT_MSG_POLL input event message to the Twm4Nx event loop. + */ + + void sendInputEvent(void); + + // Override CWidgetEventHandler virutal methods /////////////////////// + +#ifdef CONFIG_NX_XYINPUT + /** + * Handle an NX window mouse input event. + */ + + void handleMouseEvent(void); +#endif + +#ifdef CONFIG_NX_KBD + /** + * Handle a NX window keyboard input event. + */ + + void handleKeyboardEvent(void); +#endif + + /** + * Handle a NX window blocked event + * + * @param arg - User provided argument (see nx_block or nxtk_block) + */ + + void handleBlockedEvent(FAR void *arg); + + public: + + /** + * CWindowEvent Constructor + * + * @param twm4nx. The Twm4Nx session instance. + * @param style The default style that all widgets on this display + * should use. If this is not specified, the widget will use the + * values stored in the defaultCWidgetStyle object. + */ + + CWindowEvent(FAR CTwm4Nx *twm4nx, + FAR const NXWidgets::CWidgetStyle *style = + (const NXWidgets::CWidgetStyle *)NULL); + + /** + * CWindowEvent Destructor. + */ + + ~CWindowEvent(void); + + /** + * Handle MSG events. + * + * @param msg. The received system MSG event message. + * @return True if the message was properly handled. false is + * return on any failure. + */ + + static bool event(FAR struct SEventMsg *msg); + }; +} +#endif // __cplusplus + +#endif // __APPS_INCLUDE_GRAPHICS_TWM4NX_CWINDOWEVENT_HXX diff --git a/include/graphics/twm4nx/cwindowfactory.hxx b/include/graphics/twm4nx/cwindowfactory.hxx new file mode 100644 index 000000000..6c18ef232 --- /dev/null +++ b/include/graphics/twm4nx/cwindowfactory.hxx @@ -0,0 +1,194 @@ +///////////////////////////////////////////////////////////////////////////// +// apps/graphics/twm4nx/include/cwindowfactory.hxx +// A collection of Window Helpers: Add a new window, put the titlebar and +// other stuff around the window +// +// Copyright (C) 2019 Gregory Nutt. All rights reserved. +// Author: Gregory Nutt +// +// Largely an original work but derives from TWM 1.0.10 in many ways: +// +// Copyright 1989,1998 The Open Group +// Copyright 1988 by Evans & Sutherland Computer Corporation, +// +// Please refer to apps/twm4nx/COPYING for detailed copyright information. +// +// 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. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef __APPS_INCLUDE_GRAPHICS_TWM4NX_CWINDOWFACTORY_HXX +#define __APPS_INCLUDE_GRAPHICS_TWM4NX_CWINDOWFACTORY_HXX + +///////////////////////////////////////////////////////////////////////////// +// Included Files +///////////////////////////////////////////////////////////////////////////// + +#include + +#include "graphics/twm4nx/cwindow.hxx" + +///////////////////////////////////////////////////////////////////////////// +// Implementation Classes +///////////////////////////////////////////////////////////////////////////// + +namespace NXWidgets +{ + struct SRlePaletteBitmap; // Forward reference +} + +namespace Twm4Nx +{ + class CWindow; // Forward reference + class CIconMgr; // Forward reference + struct SWindowEntry; // Forward reference + + // For each window that is on the display, one of these structures + // is allocated and linked into a list. It is essentially just a + // container for a window. + + struct SWindow + { + FAR struct SWindow *flink; /**< Foward link tonext window */ + FAR struct SWindow *blink; /**< Backward link to previous window */ + FAR struct SWindowEntry *wentry; /**< Icon manager list entry (for list removal) */ + FAR CWindow *cwin; /**< Window object payload */ + }; + + /** + * The CWindowFactory class creates new window instances and manages some + * things that are common to all windows. + */ + + class CWindowFactory + { + private: + + CTwm4Nx *m_twm4nx; /**< Cached Twm4Nx session */ + struct nxgl_point_s m_winpos; /**< Position of next window created */ + FAR struct SWindow *m_windowHead; /**< List of all windows on the display */ + + /** + * Add a window container to the window list. + * + * @param win. The window container to be added to the list. + */ + + void addWindow(FAR struct SWindow *win); + + /** + * Remove a window container from the window list. + * + * @param win. The window container to be removed from the list. + */ + + void removeWindow(FAR struct SWindow *win); + + /** + * Find the window container that contains the specified window. + * + * @param cwin. The window whose container is needed. + * @return On success, the container of the specific window is returned; + * NULL is returned on failure. + */ + + FAR struct SWindow *findWindow(FAR CWindow *cwin); + + public: + + /** + * CWindowFactory Constructor + * + * @param twm4nx. Twm4Nx session + */ + + CWindowFactory(CTwm4Nx *twm4nx); + + /** + * CWindowFactory Destructor + */ + + ~CWindowFactory(void); + + /** + * Create a new window and add it to the window list. + * + * @param name The window name + * @param sbitmap The Icon bitmap + * @param isIconMgr Flag to tell if this is an icon manager window + * @param iconMgr Pointer to icon manager instance + * @param noToolbar True: Don't add Title Bar + * @return Reference to the allocated CWindow instance + */ + + FAR CWindow * + createWindow(FAR const char *name, + FAR const struct NXWidgets::SRlePaletteBitmap *sbitmap, + bool isIconMgr, FAR CIconMgr *iconMgr, bool noToolbar); + + /** + * Handle the EVENT_WINDOW_DELETE event. The logic sequence is as + * follows: + * + * 1. The TERMINATE button in pressed in the Window Toolbar + * 2. CWindowFactory::event receives the widget event, + * EVENT_WINDOW_TERMINATE and request to halt the NX Server + * messages queues. + * 3. The server responds with the EVENT_WINDOW_DELETE which is + * caught by this function. + * + * @param cwin The CWindow instance. This will be deleted and its + * associated container will be freed. + */ + + void destroyWindow(FAR CWindow *cwin); + + /** + * Return the head of the window list. + * + * @return The head of the window list. + */ + + inline FAR struct SWindow *windowHead(void) + { + return m_windowHead; + } + + /** + * Handle WINDOW events. + * + * @param msg. The received NxWidget WINDOW event message. + * @return True if the message was properly handled. false is + * return on any failure. + */ + + bool event(FAR struct SEventMsg *msg); + }; +} + +#endif // __APPS_INCLUDE_GRAPHICS_TWM4NX_CWINDOWFACTORY_HXX diff --git a/include/graphics/twm4nx/twm4nx_config.hxx b/include/graphics/twm4nx/twm4nx_config.hxx new file mode 100644 index 000000000..9a7580f80 --- /dev/null +++ b/include/graphics/twm4nx/twm4nx_config.hxx @@ -0,0 +1,455 @@ +///////////////////////////////////////////////////////////////////////////// +// apps/graphics/twm4nx/include/twm4nx_config.hxx +// Twm4Nx configuration settings +// +// 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. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef __APPS_INCLUDE_GRAPHICS_TWM4NX_TWM4NX_CONFIG_HXX +#define __APPS_INCLUDE_GRAPHICS_TWM4NX_TWM4NX_CONFIG_HXX + +///////////////////////////////////////////////////////////////////////////// +// Included Files +///////////////////////////////////////////////////////////////////////////// + +#include + +#include "graphics/nxglyphs.hxx" +#include "graphics/nxwidgets/nxconfig.hxx" +#include "graphics/nxwidgets/crlepalettebitmap.hxx" + +///////////////////////////////////////////////////////////////////////////// +// Pre-Processor Definitions +///////////////////////////////////////////////////////////////////////////// + +// General Configuration //////////////////////////////////////////////////// + +/** + * Required settings: + * + * CONFIG_HAVE_CXX : C++ support is required + * CONFIG_NX : NX must enabled + * CONFIG_NXTERM=y : For NxTerm support + * CONFIG_SCHED_ONEXIT : Support for on_exit() + */ + +#ifndef CONFIG_HAVE_CXX +# error "C++ support is required (CONFIG_HAVE_CXX)" +#endif + +/** + * NX Multi-user support is required + */ + +#ifndef CONFIG_NX +# error "NX support is required (CONFIG_NX)" +#endif + +/** + * NxTerm support is (probably) required to support NxTWM terminals + */ + +#if defined(CONFIG_TWM4NX_NXTERM) && !defined(CONFIG_NXTERM) +# warning "NxTerm support may be needed (CONFIG_NXTERM)" +#endif + +/** + * on_exit() support is (probably) required. on_exit() is the normal + * mechanism used by Twm4Nx applications to clean-up on a application task + * exit. + */ + +#ifndef CONFIG_SCHED_ONEXIT +# warning "on_exit() support may be needed (CONFIG_SCHED_ONEXIT)" +#endif + +// Background /////////////////////////////////////////////////////////////// + +/** + * CONFIG_TWM4NX_DEFAULT_BACKGROUNDCOLOR - Normal background color. Default: + * MKRGB(148,189,215) + * CONFIG_TWM4NX_BACKGROUND_IMAGE - The name of the image to use in the + * background window. Default:NXWidgets::g_nuttxBitmap160x160 + */ + +#ifndef CONFIG_TWM4NX_BACKGROUND_IMAGE +# define CONFIG_TWM4NX_BACKGROUND_IMAGE NXWidgets::g_nuttxBitmap160x160 +#endif + +// Windows ////////////////////////////////////////////////////////////////// + +// Toolbar ///////////////////////////////////////////////////////////////// + +/** + * Toolbar Icons. The Title bar contains (from left to right): + * + * 1. Menu button + * 2. Window title (text) + * 3. Minimize (Iconify) button + * 4. Resize button + * 5. Delete button + * + * There is no focus indicator + */ + +#ifndef CONFIG_TWM4NX_MENU_IMAGE +# define CONFIG_TWM4NX_MENU_IMAGE NXWidgets::g_menuBitmap +#endif + +#ifndef CONFIG_TWM4NX_MINIMIZE_IMAGE +# define CONFIG_TWM4NX_MINIMIZE_IMAGE NXWidgets::g_minimizeBitmap +#endif + +#ifndef CONFIG_TWM4NX_RESIZE_IMAGE +# define CONFIG_TWM4NX_RESIZE_IMAGE NXWidgets::g_resizeBitmap +#endif + +#ifndef CONFIG_TWM4NX_TERMINATE_IMAGE +# define CONFIG_TWM4NX_TERMINATE_IMAGE NXWidgets::g_stopBitmap +#endif + +#ifndef CONFIG_TWM4NX_ICONMGR_IMAGE +# define CONFIG_TWM4NX_ICONMGR_IMAGE NXWidgets::g_nxiconBitmap +#endif + +// Spacing. Defaults values good at 75 and 100 DPI + +#ifndef CONFIG_TWM4NX_TOOLBAR_HSPACING +# define CONFIG_TWM4NX_TOOLBAR_HSPACING 8 +#endif + +#ifndef CONFIG_TWM4NX_ICONMGR_VSPACING +# define CONFIG_TWM4NX_FRAME_VSPACING 2 +#endif + +#ifndef CONFIG_TWM4NX_BUTTON_INDENT +# define CONFIG_TWM4NX_BUTTON_INDENT 1 +#endif + +#ifndef CONFIG_TWM4NX_ICONMGR_VSPACING +# define CONFIG_TWM4NX_ICONMGR_VSPACING 2 +#endif + +#ifndef CONFIG_TWM4NX_ICONMGR_HSPACING +# define CONFIG_TWM4NX_ICONMGR_HSPACING 2 +#endif + +// Menus //////////////////////////////////////////////////////////////////// + +/** + * CONFIG_TWM4NX_MENU_IMAGE. Menu image (see toolbar icons) + */ + +// Colors /////////////////////////////////////////////////////////////////// + +/* Colors *******************************************************************/ + +/** + * Color configuration + * + * CONFIG_TWM4NX_DEFAULT_BACKGROUNDCOLOR - Normal background color. Default: + * MKRGB(148,189,215) + * CONFIG_TWM4NX_DEFAULT_SELECTEDBACKGROUNDCOLOR - Select background color. + * Default: MKRGB(206,227,241) + * CONFIG_TWM4NX_DEFAULT_SHINEEDGECOLOR - Color of the bright edge of a border. + * Default: MKRGB(255,255,255) + * CONFIG_TWM4NX_DEFAULT_SHADOWEDGECOLOR - Color of the shadowed edge of a border. + * Default: MKRGB(0,0,0) + * CONFIG_TWM4NX_DEFAULT_FONTCOLOR - Default font color. Default: + * MKRGB(0,0,0) + * CONFIG_TWM4NX_TRANSPARENT_COLOR - The "transparent" color. Default: + * MKRGB(0,0,0) + */ + +/** + * Normal background color + */ + +#ifndef CONFIG_TWM4NX_DEFAULT_BACKGROUNDCOLOR +# define CONFIG_TWM4NX_DEFAULT_BACKGROUNDCOLOR MKRGB(148,189,215) +#endif + +/** + * Default selected background color + */ + +#ifndef CONFIG_TWM4NX_DEFAULT_SELECTEDBACKGROUNDCOLOR +# define CONFIG_TWM4NX_DEFAULT_SELECTEDBACKGROUNDCOLOR MKRGB(206,227,241) +#endif + +/** + * Border colors + */ + +#ifndef CONFIG_TWM4NX_DEFAULT_SHINEEDGECOLOR +# define CONFIG_TWM4NX_DEFAULT_SHINEEDGECOLOR MKRGB(248,248,248) +#endif + +#ifndef CONFIG_TWM4NX_DEFAULT_SHADOWEDGECOLOR +# define CONFIG_TWM4NX_DEFAULT_SHADOWEDGECOLOR MKRGB(35,58,73) +#endif + +/** + * The default font color + */ + +#ifndef CONFIG_TWM4NX_DEFAULT_FONTCOLOR +# define CONFIG_TWM4NX_DEFAULT_FONTCOLOR MKRGB(255,255,255) +#endif + +/** + * The transparent color + */ + +#ifndef CONFIG_TWM4NX_TRANSPARENT_COLOR +# define CONFIG_TWM4NX_TRANSPARENT_COLOR MKRGB(0,0,0) +#endif + +// Toolbar Configuration //////////////////////////////////////////////////// + +/** + * CONFIG_TWM4NX_TOOLBAR_HEIGHT. The height of the tool bar in each + * application window. At present, all icons are 21 or 42 pixels in height + * (depending on the setting of CONFIG_TWM4NX_LARGE_ICONS) and, hence require + * a task bar of at least that size. + */ + +#ifndef CONFIG_TWM4NX_TOOLBAR_HEIGHT +# define CONFIG_TWM4NX_TOOLBAR_HEIGHT \ + (CONFIG_TWM4NX_TASKBAR_ICONHEIGHT + 2 * CONFIG_TWM4NX_TASKBAR_HSPACING) +#endif + +/* CONFIG_TWM4NX_TOOLBAR_FONTID overrides the default Twm4Nx font selection */ + +#ifndef CONFIG_TWM4NX_TOOLBAR_FONTID +# define CONFIG_TWM4NX_TOOLBAR_FONTID CONFIG_TWM4NX_DEFAULT_FONTID +#endif + +// Background Image ////////////////////////////////////////////////////////// + +/** + * CONFIG_TWM4NX_BACKGROUND_IMAGE - The name of the image to use in the + * background window. Default:NXWidgets::g_nuttxBitmap160x160 + */ + +#ifndef CONFIG_TWM4NX_BACKGROUND_IMAGE +# define CONFIG_TWM4NX_BACKGROUND_IMAGE NXWidgets::g_nuttxBitmap160x160 +#endif + +// Cursor //////////////////////////////////////////////////////////////////// +// Cursor Images + +#ifndef CONFIG_TWM4NX_CURSOR_IMAGE // The normal cursor image +# define CONFIG_TWM4NX_CURSOR_IMAGE g_arrow1Cursor +#endif + +#ifndef CONFIG_TWM4NX_GBCURSOR_IMAGE // Grab cursor image +# define CONFIG_TWM4NX_GBCURSOR_IMAGE g_grabCursor +#endif + +#ifndef CONFIG_TWM4NX_WTCURSOR_IMAGE // Wait cursor image +# define CONFIG_TWM4NX_WTCURSOR_IMAGE g_waitCursor +#endif + +// Fonts ///////////////////////////////////////////////////////////////////// + +// Font IDs + +#ifndef CONFIG_TWM4NX_TITLE_FONTID +# define CONFIG_TWM4NX_TITLE_FONTID NXFONT_DEFAULT +#endif + +#ifndef CONFIG_TWM4NX_MENU_FONTID +# define CONFIG_TWM4NX_MENU_FONTID NXFONT_DEFAULT +#endif + +#ifndef CONFIG_TWM4NX_ICON_FONTID +# define CONFIG_TWM4NX_ICON_FONTID NXFONT_DEFAULT +#endif + +#ifndef CONFIG_TWM4NX_SIZE_FONTID +# define CONFIG_TWM4NX_SIZE_FONTID NXFONT_DEFAULT +#endif + +#ifndef CONFIG_TWM4NX_ICONMGR_SIZEFONTID +# define CONFIG_TWM4NX_ICONMGR_SIZEFONTID NXFONT_DEFAULT +#endif + +// Font Colors + +#ifndef CONFIG_TWM4NX_TITLE_FONTCOLOR +# define CONFIG_TWM4NX_TITLE_FONTCOLOR MKRGB(0,64,0) +#endif + +#ifndef CONFIG_TWM4NX_MENU_FONTCOLOR +# define CONFIG_TWM4NX_MENU_FONTCOLOR MKRGB(0,64,0) +#endif + +#ifndef CONFIG_TWM4NX_ICON_FONTCOLOR +# define CONFIG_TWM4NX_ICON_FONTCOLOR MKRGB(0,64,0) +#endif + +#ifndef CONFIG_TWM4NX_SIZE_FONTCOLOR +# define CONFIG_TWM4NX_SIZE_FONTCOLOR MKRGB(0,64,0) +#endif + +#ifndef CONFIG_TWM4NX_ICONMGR_FONTCOLOR +# define CONFIG_TWM4NX_ICONMGR_FONTCOLOR MKRGB(0,64,0) +#endif + +#ifndef CONFIG_TWM4NX_DEFAULT_FONTCOLOR +# define CONFIG_TWM4NX_DEFAULT_FONTCOLOR MKRGB(0,64,0) +#endif + +// NxTerm Window ///////////////////////////////////////////////////////////// + +/** + * NxTerm Window Configuration + * + * CONFIG_TWM4NX_NXTERM_PRIO - Priority of the NxTerm task. Default: + * SCHED_PRIORITY_DEFAULT. NOTE: This priority should be less than + * CONFIG_NXSTART_SERVERPRIO or else there may be data overrun errors. + * Such errors would most likely appear as duplicated rows of data on the + * display. + * CONFIG_TWM4NX_NXTERM_STACKSIZE - The stack size to use when starting the + * NxTerm task. Default: 2048 bytes. + * CONFIG_TWM4NX_NXTERM_WCOLOR - The color of the NxTerm window background. + * Default: MKRGB(192,192,192) + * CONFIG_TWM4NX_NXTERM_FONTCOLOR - The color of the fonts to use in the + * NxTerm window. Default: MKRGB(0,0,0) + * CONFIG_TWM4NX_NXTERM_FONTID - The ID of the font to use in the NxTerm + * window. Default: CONFIG_TWM4NX_DEFAULT_FONTID + * CONFIG_TWM4NX_NXTERM_ICON - The glyph to use as the NxTerm icon + */ + +#ifdef CONFIG_TWM4NX_NXTERM +# ifndef CONFIG_TWM4NX_NXTERM_PRIO +# define CONFIG_TWM4NX_NXTERM_PRIO SCHED_PRIORITY_DEFAULT +# endif + +# if CONFIG_NXSTART_SERVERPRIO <= CONFIG_TWM4NX_NXTERM_PRIO +# warning "CONFIG_NXSTART_SERVERPRIO <= CONFIG_TWM4NX_NXTERM_PRIO" +# warning" -- This can result in data overrun errors" +# endif + +# ifndef CONFIG_TWM4NX_NXTERM_STACKSIZE +# define CONFIG_TWM4NX_NXTERM_STACKSIZE 2048 +# endif + +# ifndef CONFIG_TWM4NX_NXTERM_WCOLOR +# define CONFIG_TWM4NX_NXTERM_WCOLOR CONFIG_TWM4NX_DEFAULT_BACKGROUNDCOLOR +# endif + +# ifndef CONFIG_TWM4NX_NXTERM_FONTCOLOR +# define CONFIG_TWM4NX_NXTERM_FONTCOLOR CONFIG_TWM4NX_DEFAULT_FONTCOLOR +# endif + +# ifndef CONFIG_TWM4NX_NXTERM_FONTID +# define CONFIG_TWM4NX_NXTERM_FONTID CONFIG_TWM4NX_DEFAULT_FONTID +# endif + + /** + * The NxTerm window glyph + */ + +# ifndef CONFIG_TWM4NX_NXTERM_ICON +# define CONFIG_TWM4NX_NXTERM_ICON NXWidgets::g_cmdBitmap +# endif +#endif + +// Input Devices ///////////////////////////////////////////////////////////// + +/** Common input device settings + * + * CONFIG_TWM4NX_INPUT_SIGNO - The realtime signal used to wake up the + * keyboard/mouse listener thread. Default: 6 + * CONFIG_TWM4NX_INPUT_LISTENERPRIO - Priority of the touchscreen listener + * thread. Default: (SCHED_PRIORITY_DEFAULT + 20) + * CONFIG_TWM4NX_INPUT_LISTENERSTACK - Input listener thread stack + * size. Default 1024 + */ + +#ifndef CONFIG_TWM4NX_INPUT_SIGNO +# define CONFIG_TWM4NX_INPUT_SIGNO 6 +#endif + +#ifndef CONFIG_TWM4NX_INPUT_LISTENERPRIO +# define CONFIG_TWM4NX_INPUT_LISTENERPRIO (SCHED_PRIORITY_DEFAULT + 20) +#endif + +#ifndef CONFIG_TWM4NX_INPUT_LISTENERSTACK +# define CONFIG_TWM4NX_INPUT_LISTENERSTACK 1024 +#endif + +// Mouse Input Device //////////////////////////////////////////////////////// + +/** + * Mouse device settings + * + * CONFIG_TWM4NX_MOUSE_DEVPATH - The full path to the mouse device. + * Default: "/dev/console" + * CONFIG_TWM4NX_MOUSE_USBHOST - Indicates the the mouse is attached via + * USB + * CONFIG_TWM4NX_MOUSE_BUFSIZE - The size of the mouse read data buffer. + * Default: sizeof(struct mouse_report_s) + */ + +#ifndef CONFIG_TWM4NX_MOUSE_DEVPATH +# define CONFIG_TWM4NX_MOUSE_DEVPATH "/dev/mouse0" +#endif + +#ifndef CONFIG_TWM4NX_MOUSE_BUFSIZE +# define CONFIG_TWM4NX_MOUSE_BUFSIZE sizeof(struct mouse_report_s) +#endif + +// Keyboard device /////////////////////////////////////////////////////////// + +/** + * Keyboard device settings + * + * CONFIG_TWM4NX_KEYBOARD_DEVPATH - The full path to the keyboard device. + * Default: "/dev/console" + * CONFIG_TWM4NX_KEYBOARD_USBHOST - Indicates the the keyboard is attached via + * USB + * CONFIG_TWM4NX_KEYBOARD_BUFSIZE - The size of the keyboard read data buffer. + * Default: 16 + */ + +#ifndef CONFIG_TWM4NX_KEYBOARD_DEVPATH +# define CONFIG_TWM4NX_KEYBOARD_DEVPATH "/dev/kbd0" +#endif + +#ifndef CONFIG_TWM4NX_KEYBOARD_BUFSIZE +# define CONFIG_TWM4NX_KEYBOARD_BUFSIZE 6 +#endif + +#endif // __APPS_INCLUDE_GRAPHICS_TWM4NX_TWM4NX_CONFIG_HXX diff --git a/include/graphics/twm4nx/twm4nx_cursor.hxx b/include/graphics/twm4nx/twm4nx_cursor.hxx new file mode 100644 index 000000000..7f98d55d4 --- /dev/null +++ b/include/graphics/twm4nx/twm4nx_cursor.hxx @@ -0,0 +1,70 @@ +///////////////////////////////////////////////////////////////////////////// +// apps/graphics/twm4nx/include/twm4nx_cursor.hxx +// Cursor-related definitions +// +// 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. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef __APPS_GRAPHICS_TWM4NX_INCLUDE_TWM4NX_CURSOR_HXX +#define __APPS_GRAPHICS_TWM4NX_INCLUDE_TWM4NX_CURSOR_HXX + +///////////////////////////////////////////////////////////////////////////// +// Included Files +///////////////////////////////////////////////////////////////////////////// + +#include +#include + +#include "graphics/twm4nx/twm4nx_config.hxx" + +#ifdef CONFIG_NX_SWCURSOR + +///////////////////////////////////////////////////////////////////////////// +// Public Constant Data +///////////////////////////////////////////////////////////////////////////// + +namespace Twm4Nx +{ + extern const struct nx_cursorimage_s // Normal cursor + CONFIG_TWM4NX_CURSOR_IMAGE; + extern const struct nx_cursorimage_s // Grab button + CONFIG_TWM4NX_GBCURSOR_IMAGE; + extern const struct nx_cursorimage_s // Wait cursor + CONFIG_TWM4NX_WTCURSOR_IMAGE; +} + +///////////////////////////////////////////////////////////////////////////// +// Public Function Prototypes +///////////////////////////////////////////////////////////////////////////// + +#endif // CONFIG_NX_SWCURSOR +#endif // __APPS_GRAPHICS_TWM4NX_INCLUDE_TWM4NX_CURSOR_HXX diff --git a/include/graphics/twm4nx/twm4nx_widgetevents.hxx b/include/graphics/twm4nx/twm4nx_widgetevents.hxx new file mode 100644 index 000000000..58bedc1f5 --- /dev/null +++ b/include/graphics/twm4nx/twm4nx_widgetevents.hxx @@ -0,0 +1,215 @@ +///////////////////////////////////////////////////////////////////////////// +// apps/graphics/twm4nx/include/twm4nx_widgetevents.hxx +// Twm4Nx Widget Event Handling +// +// 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. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef __APPS_INCLUDE_GRAPHICS_TWM4NX_TWM4NX_WIDGETEVENTS_HXX +#define __APPS_INCLUDE_GRAPHICS_TWM4NX_TWM4NX_WIDGETEVENTS_HXX + +///////////////////////////////////////////////////////////////////////////// +// Included Files +///////////////////////////////////////////////////////////////////////////// + +#include + +#include +#include + +#include +#include "graphics/nxwidgets/cwindoweventhandler.hxx" + +///////////////////////////////////////////////////////////////////////////// +// Preprocessor Definitions +///////////////////////////////////////////////////////////////////////////// + +#define MAX_EVENT_PAYLOAD (64 - sizeof(uint16_t)) + +///////////////////////////////////////////////////////////////////////////// +// WidgetEvent +///////////////////////////////////////////////////////////////////////////// + +namespace NXWidgets +{ + class CNxTkWindow; // Forward reference +} + +namespace Twm4Nx +{ + class CWindow; // Forward reference + class CWindowEvent; // Forward reference + class CTwm4Nx; // Forward reference + + /////////////////////////////////////////////////////////////////////////// + // Public Types + /////////////////////////////////////////////////////////////////////////// + + /** + * This enumeration identifies the recipient of the event + */ + + enum EEventRecipient + { + EVENT_RECIPIENT_MSG = 0x0000, /**< Twm4Nx messenging event */ + EVENT_RECIPIENT_SYSTEM = 0x1000, /**< Twm4Nx system event */ + EVENT_RECIPIENT_ICONWIN = 0x2000, /**< Icon Window event */ + EVENT_RECIPIENT_ICONMGR = 0x3000, /**< Icon Manager event */ + EVENT_RECIPIENT_MENU = 0x4000, /**< Menu related event */ + EVENT_RECIPIENT_WINDOW = 0x5000, /**< Window related event */ + EVENT_RECIPIENT_TOOLBAR = 0x6000, /**< Toolbar related event */ + EVENT_RECIPIENT_BORDER = 0x7000, /**< Window border related event */ + EVENT_RECIPIENT_RESIZE = 0x8000, /**< Window resize event */ + EVENT_RECIPIENT_MASK = 0xf000, /**< Used to isolate recipient */ + }; + + /** + * Specific events include the recipient as part of the event ID encoding. + */ + + enum EEventID + { + // Recipient == MSG + + EVENT_MSG_POLL = 0x0000, /**< Poll widgets for events */ + + // Recipient == SYSTEM + + EVENT_SYSTEM_ERROR = 0x1000, /**< Report system error */ + EVENT_SYSTEM_EXIT = 0x1001, /**< Terminate the Twm4Nx session */ + + // Recipient == ICONWIN + + EVENT_ICONWIN_GRAB = 0x2000, /**< Click on toolbar (not toolbar buttons) */ + EVENT_ICONWIN_DRAG = 0x2001, /**< Drag window */ + EVENT_ICONWIN_UNGRAB = 0x2002, /**< Release click on toolbar */ + + // Recipient == ICONMGR + + EVENT_ICONMGR_FORWARD = 0x3000, /**< Forward in the window list */ + EVENT_ICONMGR_BACK = 0x3001, /**< Backward in the window list */ + EVENT_ICONMGR_UP = 0x3002, /**< Up one row */ + EVENT_ICONMGR_DOWN = 0x3003, /**< Down one row */ + EVENT_ICONMGR_LEFT = 0x3004, /**< Left one column */ + EVENT_ICONMGR_RIGHT = 0x3005, /**< Right one column */ + EVENT_ICONMGR_SHOWPARENT = 0x3006, /**< Raise Icon Manager parent window */ + EVENT_ICONMGR_HIDE = 0x3007, /**< Hide the Icon Manager */ + EVENT_ICONMGR_SORT = 0x3008, /**< Sort the Icon Manager */ + + // Recipient == MENU + + EVENT_MENU_IDENTIFY = 0x4001, /**< Describe the window */ + EVENT_MENU_VERSION = 0x4002, /**< Show the Twm4Nx version */ + EVENT_MENU_ICONIFY = 0x4003, /**< Tool bar minimize button pressed */ + EVENT_MENU_DEICONIFY = 0x4004, /**< Window icon pressed */ + EVENT_MENU_FUNCTION = 0x4005, /**< Perform function on unknown menu */ + EVENT_MENU_TITLE = 0x4006, /**< REVISIT: Really an action not an event */ + EVENT_MENU_ROOT = 0x4007, /**< REVISIT: Popup root menu */ + + // Recipient == WINDOW + + EVENT_WINDOW_FOCUS = 0x5000, /**< Enter modal state */ + EVENT_WINDOW_UNFOCUS = 0x5001, /**< Exit modal state */ + EVENT_WINDOW_RAISE = 0x5002, /**< Raise window to the top of the heirarchy */ + EVENT_WINDOW_LOWER = 0x5003, /**< Lower window to the bottom of the heirarchy */ + EVENT_WINDOW_DRAG = 0x5004, /**< Drag window */ + EVENT_WINDOW_POPUP = 0x5005, /**< De-iconify and raise window */ + EVENT_WINDOW_DELETE = 0x5006, /**< Delete window */ + + // Recipient == TOOLBAR + + EVENT_TOOLBAR_GRAB = 0x6000, /**< Click on title widget */ + EVENT_TOOLBAR_UNGRAB = 0x6001, /**< Release click on title widget */ + EVENT_TOOLBAR_MENU = 0x6002, /**< Toolbar menu button released */ + EVENT_TOOLBAR_MINIMIZE = 0x6003, /**< Toolbar minimize button released */ + EVENT_TOOLBAR_RESIZE = 0x6004, /**< Toolbar resize button released */ + EVENT_TOOLBAR_TERMINATE = 0x6005, /**< Toolbar delete button released */ + + // Recipient == BORDER + + // Recipient == RESIZE + + EVENT_RESIZE_START = 0x8000, /**< Start window resize */ + EVENT_RESIZE_VERTZOOM = 0x8001, /**< Zoom vertically only */ + EVENT_RESIZE_HORIZOOM = 0x8002, /**< Zoom horizontally only */ + EVENT_RESIZE_FULLZOOM = 0x8003, /**< Zoom both vertically and horizontally */ + EVENT_RESIZE_LEFTZOOM = 0x8004, /**< Zoom left only */ + EVENT_RESIZE_RIGHTZOOM = 0x8005, /**< Zoom right only */ + EVENT_RESIZE_TOPZOOM = 0x8006, /**< Zoom top only */ + EVENT_RESIZE_BOTTOMZOOM = 0x8007, /**< Zoom bottom only */ + }; + + // Contexts for button press events + + enum EButtonContext + { + EVENT_CONTEXT_WINDOW = 0, + EVENT_CONTEXT_TITLE, + EVENT_CONTEXT_ICON, + EVENT_CONTEXT_ROOT, + EVENT_CONTEXT_FRAME, + EVENT_CONTEXT_ICONMGR, + EVENT_CONTEXT_NAME, + EVENT_CONTEXT_IDENTIFY, + NUM_CONTEXTS + }; + + /** + * This type represents a generic message containing all possible, + * message-specific options (wasteful, but a lot easier). + */ + + struct SEventMsg + { + uint16_t eventID; /**< Encoded event ID */ + struct nxgl_point_s pos; /**< X/Y position */ + uint8_t context; /**< Button press context */ + bool pulldown; /**< Pull-down menu */ + FAR const char *action; /**< Menu action */ + FAR NXWidgets::CNxTkWindow *nxwin; /**< Raw NX window reference */ + FAR void *obj; /**< Window object (CWindow or CIconWin) */ + }; + + /** + * This is the alternative form of the message used on in + * CWindowEvent::event() + */ + + struct SNxEventMsg + { + uint16_t eventID; /**< Encoded event ID */ + FAR CWindowEvent *instance; /**< X/Y position */ + FAR struct SWindow *win; /**< Twm4NX window reference */ + }; +} + +#endif // __APPS_INCLUDE_GRAPHICS_TWM4NX_TWM4NX_WIDGETEVENTS_HXX