|
|
@ -39,6 +39,19 @@ |
|
|
|
|
|
|
|
|
|
|
|
#include <nuttx/config.h> |
|
|
|
#include <nuttx/config.h> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include <cstdio> |
|
|
|
|
|
|
|
#include <cstdlib> |
|
|
|
|
|
|
|
#include <ctime> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include <unistd.h> |
|
|
|
|
|
|
|
#include <fcntl.h> |
|
|
|
|
|
|
|
#include <semaphore.h> |
|
|
|
|
|
|
|
#include <sched.h> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include <apps/nsh.h> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include "cwidgetcontrol.hxx" |
|
|
|
|
|
|
|
|
|
|
|
#include "nxwmconfig.hxx" |
|
|
|
#include "nxwmconfig.hxx" |
|
|
|
#include "cnxconsole.hxx" |
|
|
|
#include "cnxconsole.hxx" |
|
|
|
#include "nxwmglyphs.hxx" |
|
|
|
#include "nxwmglyphs.hxx" |
|
|
@ -47,6 +60,125 @@ |
|
|
|
* Pre-Processor Definitions |
|
|
|
* 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 |
|
|
|
* CNxConsole Method Implementations |
|
|
|
********************************************************************************************/ |
|
|
|
********************************************************************************************/ |
|
|
@ -59,8 +191,80 @@ using namespace NxWM; |
|
|
|
* @param window. The application window |
|
|
|
* @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<IApplicationCallback *>(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::IBitmap *CNxConsole::getIcon(void) |
|
|
|
{ |
|
|
|
{ |
|
|
|
NXWidgets::CRlePaletteBitmap *bitmap = new NXWidgets::CRlePaletteBitmap(&g_nshBitmap); |
|
|
|
NXWidgets::CRlePaletteBitmap *bitmap = |
|
|
|
return static_cast<NXWidgets::IBitmap *>(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<IApplication*>(this)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* Called when the window minimize close is pressed. |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void CNxConsole::close(void) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
m_taskbar->stopApplication(static_cast<IApplication*>(this)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|