From 990276740afafeb69f64b01050a99f113bb89fa6 Mon Sep 17 00:00:00 2001 From: patacongo Date: Tue, 1 May 2012 14:52:54 +0000 Subject: Add beginning of NxWM NxConsole application git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@4681 42af7a65-404d-4744-a932-0658087f49c3 --- NxWidgets/nxwm/src/cnxconsole.cxx | 372 +++++++++++++++++++++++++++++++++++++- 1 file changed, 369 insertions(+), 3 deletions(-) (limited to 'NxWidgets/nxwm/src/cnxconsole.cxx') diff --git a/NxWidgets/nxwm/src/cnxconsole.cxx b/NxWidgets/nxwm/src/cnxconsole.cxx index a127a8a5a..857b67983 100644 --- a/NxWidgets/nxwm/src/cnxconsole.cxx +++ b/NxWidgets/nxwm/src/cnxconsole.cxx @@ -39,6 +39,19 @@ #include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include "cwidgetcontrol.hxx" + #include "nxwmconfig.hxx" #include "cnxconsole.hxx" #include "nxwmglyphs.hxx" @@ -47,6 +60,125 @@ * Pre-Processor Definitions ********************************************************************************************/ +/******************************************************************************************** + * Private Types + ********************************************************************************************/ + +namespace NxWM +{ + /** + * This structure is used to pass start up parameters to nxcon_task and to assure the + * the NxConsole is successfully started. + */ + + struct nxcon_task_s + { + sem_t sem; // Sem that will be posted when the task is successfully initialized + NXTKWINDOW hwnd; // Window handle + NXCONSOLE nxcon; // NxConsole handle + int minor; // Next device minor number + bool result; // True if successfully initialized + }; + +/******************************************************************************************** + * Private Data + ********************************************************************************************/ + + /** + * This global data structure is used to pass start parameters to nxcon_task and to + * assure that the NxConsole is successfully started. + */ + + static struct nxcon_task_s g_nxconvars; + +/******************************************************************************************** + * Private Functions + ********************************************************************************************/ + + /** + * This is the NxConsole task. This function first redirects output to the console window. + */ + + static int nxcon_task(int argc, char *argv[]) + { + // Configure NxConsole + + struct nxcon_window_s wndo; /* Describes the window */ + wndo.wcolor[0] = CONFIG_NXWM_NXCONSOLE_WCOLOR; + wndo.fcolor[0] = CONFIG_NXWM_NXCONSOLE_FONTCOLOR; + wndo.fontid = CONFIG_NXWM_NXCONSOLE_FONTID; + + // To stop compiler complaining about "jump to label crosses initialization of 'int fd' + + int fd = -1; + + // Use the window handle to create the NX console + + g_nxconvars.nxcon = nxtk_register(g_nxconvars.hwnd, &wndo, g_nxconvars.minor); + if (!g_nxconvars.nxcon) + { + goto errout; + } + + // Construct the driver name using this minor number + + char devname[32]; + snprintf(devname, 32, "/dev/nxcon%d", g_nxconvars.minor); + + // Increment the minor number while it is protect by the semaphore + + g_nxconvars.minor++; + + // Open the NxConsole driver + + fd = open(devname, O_WRONLY); + if (fd < 0) + { + goto errout_with_nxcon; + } + + // Now re-direct stdout and stderr so that they use the NX console driver. + // Note that stdin is retained (file descriptor 0, probably the the serial console). + + (void)fflush(stdout); + (void)fflush(stderr); + + (void)fclose(stdout); + (void)fclose(stderr); + + (void)dup2(fd, 1); + (void)dup2(fd, 2); + + // And we can close our original driver file descriptor + + close(fd); + + // Inform the parent thread that we successfully initialize + + g_nxconvars.result = true; + sem_post(&g_nxconvars.sem); + + // Run the NSH console + +#ifdef CONFIG_NSH_CONSOLE + (void)nsh_consolemain(argc, argv); +#endif + + // We get here if console exits +#warning "Missing logic" + return EXIT_SUCCESS; + + errout_with_nxcon: + nxcon_unregister(g_nxconvars.nxcon); + + errout: + g_nxconvars.nxcon = 0; + g_nxconvars.result = false; + sem_post(&g_nxconvars.sem); + return EXIT_FAILURE; + } +} + /******************************************************************************************** * CNxConsole Method Implementations ********************************************************************************************/ @@ -59,8 +191,80 @@ using namespace NxWM; * @param window. The application window */ -CNxConsole::CNxConsole(NXWidgets::INxWindow *window) +CNxConsole::CNxConsole(CTaskbar *taskbar, CApplicationWindow *window) +{ + // Save the constructor data + + m_taskbar = taskbar; + m_window = window; + + // The NxConsole is not runing + + m_pid = -1; + m_nxcon = 0; + + // Add our callbacks to the application window + + window->registerCallbacks(static_cast(this)); +} + +/** + * CNxConsole destructor + * + * @param window. The application window + */ + +CNxConsole::~CNxConsole(void) { + // Although we didn't create it, we are responsible for deleting the + // application window + + if (m_window) + { + delete m_window; + } +} + +/** + * One time NSH initialization. This function must be called exactly + * once during the boot-up sequence to initialize the NSH library. + * + * @return True on successful initialization + */ + +bool nshlibInitialize(void) +{ + // Initialize the global data structure + + sem_init(&g_nxconvars.sem, 0, 0); + + // Initialize the NSH library + + nsh_initialize(); + + // If the Telnet console is selected as a front-end, then start the + // Telnet daemon. + +#ifdef CONFIG_NSH_TELNET + int ret = nsh_telnetstart(); + if (ret < 0) + { + // The daemon is NOT running! + + return false; + } +#endif + return true; +} + +/** + * Each implementation of IApplication must provide a method to recover + * the contained CApplicationWindow instance. + */ + +CApplicationWindow *CNxConsole::getWindow(void) const +{ + return m_window; } /** @@ -73,7 +277,169 @@ CNxConsole::CNxConsole(NXWidgets::INxWindow *window) NXWidgets::IBitmap *CNxConsole::getIcon(void) { - NXWidgets::CRlePaletteBitmap *bitmap = new NXWidgets::CRlePaletteBitmap(&g_nshBitmap); - return static_cast(bitmap); + NXWidgets::CRlePaletteBitmap *bitmap = + new NXWidgets::CRlePaletteBitmap(&g_nshBitmap); + + return bitmap; +} + +/** + * Get the name string associated with the application + * + * @return A copy if CNxString that contains the name of the application. + */ + +NXWidgets::CNxString CNxConsole::getName(void) +{ + return NXWidgets::CNxString("NuttShell"); +} + +/** + * Start the application (perhaps in the minimized state). + * + * @return True if the application was successfully started. + */ + +bool CNxConsole::run(void) +{ + // Some sanity checking + + if (m_pid >= 0 || m_nxcon != 0) + { + return false; + } + + // Recover the NXTK window instance contained in the application window + + NXWidgets::CNxTkWindow *window = m_window->getWindow(); + + // Get the widget control associated with the NXTK window + + NXWidgets::CWidgetControl *control = window->getWidgetControl(); + + // Get the window handle from the widget control + + g_nxconvars.hwnd = control->getWindowHandle(); + + // Start the NxConsole task + + g_nxconvars.result = false; + g_nxconvars.nxcon = 0; + + sched_lock(); + m_pid = TASK_CREATE("NxConsole", CONFIG_NXWM_NXCONSOLE_PRIO, + CONFIG_NXWM_NXCONSOLE_STACKSIZE, nxcon_task, + (FAR const char **)0); + + // Did we successfully start the NxConsole task? + + if (m_pid < 0) + { + return false; + } + + // Wait for up to two second for the task to initialize + + struct timespec abstime; + clock_gettime(CLOCK_REALTIME, &abstime); + abstime.tv_sec += 2; + + int ret = sem_timedwait(&g_nxconvars.sem, &abstime); + if (ret == OK && g_nxconvars.result) + { + // Save the handle to use in the stop method + + m_nxcon = g_nxconvars.nxcon; + return true; + } + else + { + // Stop the application + + stop(); + return false; + } } +/** + * Stop the application. + */ + +void CNxConsole::stop(void) +{ + // Delete the NxConsole task if it is still running (this could strand resources) + + if (m_pid >= 0) + { + task_delete(m_pid); + m_pid = -1; + } + + // Destroy the NX console device + + if (m_nxcon) + { + nxcon_unregister(m_nxcon); + m_nxcon = 0; + } +} + +/** + * The application window is hidden (either it is minimized or it is + * maximized, but not at the top of the hierarchy + */ + +void CNxConsole::hide(void) +{ + // Disable drawing and events +#warning "Missing logic" +} + +/** + * Redraw the entire window. The application has been maximized or + * otherwise moved to the top of the hierarchy. This method is call from + * CTaskbar when the application window must be displayed + */ + +void CNxConsole::redraw(void) +{ + // Recover the NXTK window instance contained in the application window + + NXWidgets::CNxTkWindow *window = m_window->getWindow(); + + // Get the size of the window + + struct nxgl_size_s windowSize; + (void)window->getSize(&windowSize); + + // Redraw the entire NxConsole window + + struct nxgl_rect_s rect; + rect.pt1.x = 0; + rect.pt1.y = 0; + rect.pt2.x = windowSize.w - 1; + rect.pt2.y = windowSize.h - 1; + + nxcon_redraw(m_nxcon, &rect, false); +} + +/** + * Called when the window minimize button is pressed. + */ + +void CNxConsole::minimize(void) +{ + m_taskbar->minimizeApplication(static_cast(this)); +} + +/** + * Called when the window minimize close is pressed. + */ + +void CNxConsole::close(void) +{ + m_taskbar->stopApplication(static_cast(this)); +} + + + -- cgit v1.2.3