void PopupMenu::DrawItem( GC& gc, int n ) { if ( n < 0 || n >= list.count() ) { return; } UiCondList ucl; if ( n == selected ) { ucl.Set( uiCurrentItem, true ); } int color_text = UiGetColor( uiColor, uiItem, &ucl, 0x0 ); int color_hotkey = UiGetColor( uiHotkeyColor, uiItem, &ucl, 0x0 ); int color_bg = UiGetColor( uiBackground, uiItem, &ucl, 0xFFFFFF ); int color_left = UiGetColor( uiBackground, 0, 0, 0xFFFFFF ); crect r = list[n].rect; int height = r.Height(); r.right = MENU_LEFT_BLOCK; gc.SetFillColor( n == selected ? color_bg : color_left ); gc.FillRect( r ); r = list[n].rect; r.left = MENU_LEFT_BLOCK ; gc.SetFillColor( color_bg ); gc.FillRect( r ); unsigned colorLine = UiGetColor( uiLineColor, uiItem, &ucl, 0 ); gc.SetLine( colorLine ); gc.MoveTo( r.left, r.top ); gc.LineTo( r.left, r.bottom ); if ( IsSplit( n ) ) { gc.SetLine( colorLine ); int y = r.top + ( r.Height() - 1 ) / 2; gc.MoveTo( 1, y ); gc.LineTo( r.right, y ); } else { gc.Set( GetFont() ); MenuTextInfo& lText = ( list[n].data->leftText ); //unicode_t* lText = list[n].data->leftText.data(); unicode_t* rText = list[n].data->rightText.data(); //if ( lText ) { gc.TextOutF( MENU_LEFT_BLOCK + MENU_TEXT_OFFSET, r.top + ( height - fontHeight ) / 2, lText ); } if ( !lText.isEmpty() ) { lText.DrawItem( gc, MENU_LEFT_BLOCK + MENU_TEXT_OFFSET, r.top + ( height - fontHeight ) / 2, color_text, color_hotkey ); } if ( rText ) { gc.SetTextColor( color_text ); gc.TextOutF( MENU_LEFT_BLOCK + MENU_TEXT_OFFSET + leftWidth + fontHeight, r.top + ( height - fontHeight ) / 2, rText ); } if ( IsSub( n ) ) { int y = r.top + ( height - RightMenuPointer[0] ) / 2; DrawPixelList( gc, RightMenuPointer, r.right - 10 , y, UiGetColor( uiPointerColor, uiItem, &ucl, 0 ) ); } if ( IsCmd( n ) ) { int y = r.top + ( height - MENU_ICON_SIZE ) / 2; int x = ( MENU_LEFT_BLOCK - MENU_ICON_SIZE ) / 2; gc.DrawIcon( x, y, GetCmdIcon( list[n].data->id ) ); } } }
bool PopupMenu::EventKey( cevent_key* pEvent ) { if ( sub.ptr() && sub->EventKey( pEvent ) ) { return true; } if ( pEvent->Type() == EV_KEYDOWN ) { int i; switch ( pEvent->Key() ) { case VK_DOWN: for ( i = ( selected >= 0 && selected + 1 < list.count() ) ? selected + 1 : 0; i < list.count(); i++ ) { if ( !IsSplit( i ) ) { SetSelected( i ); return true; } } break; case VK_UP: for ( i = ( selected > 0 ) ? selected - 1 : list.count() - 1; i >= 0; i-- ) { if ( !IsSplit( i ) ) { SetSelected( i ); return true; } } break; case VK_RIGHT: if ( OpenSubmenu() ) { return true; }; break; //case VK_LEFT: // return false; // to prevent grabbing default case case VK_NUMPAD_RETURN: case VK_RETURN: if ( IsCmd( selected ) && IsEnabled( selected ) ) { int id = list[selected].data->id; if ( IsModal() ) { EndModal( id ); } else if ( Parent() ) { Parent()->Command( id, 0, this, 0 ); } return true; } return OpenSubmenu(); case VK_ESCAPE: if ( IsModal() ) { EndModal( 0 ); } else if ( Parent() ) { Parent()->Command( CMD_MENU_INFO, SCMD_MENU_CANCEL, this, 0 ); } else {/* Botva */} return true; default: { // check if hotkey matches, and process // XXX: pEvent->Key() returns key (like Shift-F1, etc). isHotkeyMatching() expects unicode char, which is not the same unicode_t c = UnicodeUC( pEvent->Char() ); for ( int i = 0; i < list.count(); i++ ) { MenuData::Node* node = list[i].data; if ( node->leftText.isHotkeyMatching( c ) ) { if ( node->id != 0 ) // menu command { if ( Parent() ) { Parent()->Command( node->id, 0, this, 0 ); } return true; } else // sumbenu { SetSelected( i ); OpenSubmenu(); return true; } } } return false; } } } return false; }
bool PopupMenu::EventMouse( cevent_mouse* pEvent ) { int N = -1; cpoint point = pEvent->Point(); for ( int i = 0; i < list.count(); i++ ) { crect* pr = &( list[i].rect ); if ( point.x >= pr->left && point.x < pr->right && point.y >= pr->top && point.y < pr->bottom ) { N = i; break; } } switch ( pEvent->Type() ) { case EV_MOUSE_MOVE: if ( N < 0 ) { if ( !sub.ptr() ) { return false; } crect rect = ScreenRect(); crect sr = sub->ScreenRect(); pEvent->Point().x += rect.left - sr.left; pEvent->Point().y += rect.top - sr.top; return sub->EventMouse( pEvent ); } if ( SetSelected( N ) ) { if ( this->IsSub( selected ) && IsEnabled( selected ) ) { OpenSubmenu(); } } return true; case EV_MOUSE_PRESS: if ( N < 0 ) { if ( sub.ptr() ) { crect rect = ScreenRect(); crect sr = sub->ScreenRect(); pEvent->Point().x += rect.left - sr.left; pEvent->Point().y += rect.top - sr.top; if ( sub->EventMouse( pEvent ) ) { return true; } } if ( IsModal() ) { EndModal( 0 ); } else if ( Parent() ) { Parent()->Command( CMD_MENU_INFO, SCMD_MENU_CANCEL, this, 0 ); } return true; } if ( SetSelected( N ) ) { if ( IsCmd( selected ) && IsEnabled( selected ) ) { int id = list[N].data->id; if ( IsModal() ) { EndModal( id ); } else if ( Parent() ) { Parent()->Command( id, 0, this, 0 ); } } else { OpenSubmenu(); } } return true; } return false; }
void CCommandProcessor::ParseCommand ( const char * const cmdBegin, const uint64_t currentTime ) { const char * const cmdEnd = SkipCharsNotInSet( cmdBegin, SPACE_AND_TAB ); assert( cmdBegin != cmdEnd ); const char * const paramBegin = SkipCharsInSet( cmdEnd, SPACE_AND_TAB ); bool extraParamsFound = false; if ( IsCmd( cmdBegin, cmdEnd, CMDNAME_QUESTION_MARK, true, false, &extraParamsFound ) || IsCmd( cmdBegin, cmdEnd, CMDNAME_HELP, false, false, &extraParamsFound ) ) { PrintStr( "This console is similar to the Bus Pirate console." EOL ); PrintStr( "Commands longer than 1 character are case insensitive." EOL ); PrintStr( "WARNING: If a command takes too long to run, the watchdog may reset the board." EOL ); PrintStr( "Commands are:" EOL ); Printf( " %s, %s: Show this help text." EOL, CMDNAME_QUESTION_MARK, CMDNAME_HELP ); Printf( " %s: Show version information." EOL, CMDNAME_I ); Printf( " %s: Test USB transfer speed." EOL, CMDNAME_USBSPEEDTEST ); Printf( " %s: Show JTAG pin status (read as inputs)." EOL, CMDNAME_JTAGPINS ); Printf( " %s: Test JTAG shift speed. WARNING: Do NOT connect any JTAG device." EOL, CMDNAME_JTAGSHIFTSPEEDTEST ); Printf( " %s: Exercises malloc()." EOL, CMDNAME_MALLOCTEST ); Printf( " %s: Exercises C++ exceptions." EOL, CMDNAME_CPP_EXCEPTION_TEST ); Printf( " %s: Shows memory usage." EOL, CMDNAME_MEMORY_USAGE ); Printf( " %s" EOL, CMDNAME_CPU_LOAD ); Printf( " %s" EOL, CMDNAME_UPTIME ); Printf( " %s" EOL, CMDNAME_RESET ); Printf( " %s" EOL, CMDNAME_RESET_CAUSE ); Printf( " %s <addr> <byte count>" EOL, CMDNAME_PRINT_MEMORY ); Printf( " %s <milliseconds>" EOL, CMDNAME_BUSY_WAIT ); Printf( " %s <command|protocol>" EOL, CMDNAME_SIMULATE_ERROR ); return; } if ( IsCmd( cmdBegin, cmdEnd, CMDNAME_I, true, false, &extraParamsFound ) ) { #ifndef NDEBUG const char buildType[] = "Debug build"; #else const char buildType[] = "Release build"; #endif Printf( "JtagDue %s" EOL, PACKAGE_VERSION ); Printf( "%s, compiler version %s" EOL, buildType, __VERSION__ ); Printf( "Watchdog %s" EOL, ENABLE_WDT ? "enabled" : "disabled" ); return; } if ( IsCmd( cmdBegin, cmdEnd, CMDNAME_RESET, false, false, &extraParamsFound ) ) { // This message does not reach the other side, we would need to add some delay. // UsbPrint( txBuffer, "Resetting the board..." EOL ); __disable_irq(); // Note that this message always goes to the serial port console, // even if the user is connected over USB. It might be possible to send // it over USB and then wait for the outgoing buffer to be empty. SerialSyncWriteStr( "Resetting the board..." EOL ); SerialWaitForDataSent(); ResetBoard( ENABLE_WDT ); assert( false ); // We should never reach this point. return; } if ( IsCmd( cmdBegin, cmdEnd, CMDNAME_CPU_LOAD, false, false, &extraParamsFound ) ) { if ( ENABLE_CPU_SLEEP ) PrintStr( "CPU load statistics not available." EOL ); else DisplayCpuLoad(); return; } if ( IsCmd( cmdBegin, cmdEnd, CMDNAME_UPTIME, false, false, &extraParamsFound ) ) { char buffer[ CONVERT_TO_DEC_BUF_SIZE ]; Printf( "Uptime: %s seconds." EOL, convert_unsigned_to_dec_th( GetUptime() / 1000, buffer, ',' ) ); return; } if ( IsCmd( cmdBegin, cmdEnd, CMDNAME_RESET_CAUSE, false, false, &extraParamsFound ) ) { DisplayResetCause(); return; } if ( IsCmd( cmdBegin, cmdEnd, CMDNAME_PRINT_MEMORY, false, true, &extraParamsFound ) ) { PrintMemory( paramBegin ); return; } if ( IsCmd( cmdBegin, cmdEnd, CMDNAME_BUSY_WAIT, false, true, &extraParamsFound ) ) { BusyWait( paramBegin ); return; } if ( IsCmd( cmdBegin, cmdEnd, CMDNAME_USBSPEEDTEST, false, true, &extraParamsFound ) ) { ProcessUsbSpeedTestCmd( paramBegin, currentTime ); return; } if ( IsCmd( cmdBegin, cmdEnd, CMDNAME_JTAGPINS, false, false, &extraParamsFound ) ) { PrintJtagPinStatus(); return; } if ( IsCmd( cmdBegin, cmdEnd, CMDNAME_JTAGSHIFTSPEEDTEST, false, false, &extraParamsFound ) ) { if ( !IsNativeUsbPort() ) throw std::runtime_error( "This command is only available on the 'Native' USB port." ); // Fill the Rx buffer with some test data. assert( m_rxBuffer != NULL ); m_rxBuffer->Reset(); for ( uint32_t i = 0; !m_rxBuffer->IsFull(); ++i ) { m_rxBuffer->WriteElem( CUsbRxBuffer::ElemType( i ) ); } // If the mode is set to MODE_HIZ, you cannot see the generated signal with the oscilloscope. // Note also that the built-in pull-ups on the Atmel ATSAM3X8 are too weak (between 50 and 100 KOhm, // yields too slow a rising time) to be of any use. const bool oldPullUps = GetJtagPullups(); SetJtagPullups( false ); const JtagPinModeEnum oldMode = GetJtagPinMode(); SetJtagPinMode ( MODE_JTAG ); // Each JTAG transfer needs 2 bits in the Rx buffer, TMS and TDI, // but produces only 1 bit, TDO. const uint32_t jtagByteCount = m_rxBuffer->GetElemCount() / 2; const uint16_t bitCount = jtagByteCount * 8; // Shift all JTAG data through several times. const uint64_t startTime = GetUptime(); const uint32_t iterCount = 50; for ( uint32_t i = 0; i < iterCount; ++i ) { // We hope that this will not clear the buffer contents. assert( m_rxBuffer != NULL ); assert( m_txBuffer != NULL ); m_rxBuffer->Reset(); m_rxBuffer->CommitWrittenElements( jtagByteCount * 2 ); m_txBuffer->Reset(); ShiftJtagData( m_rxBuffer, m_txBuffer, bitCount ); assert( m_txBuffer->GetElemCount() == jtagByteCount ); } const uint64_t finishTime = GetUptime(); const uint32_t elapsedTime = uint32_t( finishTime - startTime ); m_rxBuffer->Reset(); m_txBuffer->Reset(); const unsigned kBitsPerSec = unsigned( uint64_t(bitCount) * iterCount * 1000 / elapsedTime / 1024 ); SetJtagPinMode( oldMode ); SetJtagPullups( oldPullUps ); // I am getting 221 KiB/s with GCC 4.7.3 and optimisation level "-O3". Printf( EOL "Finished JTAG shift speed test, throughput %u Kbits/s (%u KiB/s)." EOL, kBitsPerSec, kBitsPerSec / 8 ); return; } if ( IsCmd( cmdBegin, cmdEnd, CMDNAME_MALLOCTEST, false, false, &extraParamsFound ) ) { PrintStr( "Allocalling memory..." EOL ); volatile uint32_t * const volatile mallocTest = (volatile uint32_t *) malloc(123); *mallocTest = 123; PrintStr( "Releasing memory..." EOL ); free( const_cast< uint32_t * >( mallocTest ) ); PrintStr( "Test finished." EOL ); return; } if ( IsCmd( cmdBegin, cmdEnd, CMDNAME_CPP_EXCEPTION_TEST, false, false, &extraParamsFound ) ) { try { PrintStr( "Throwing integer exception..." EOL ); throw 123; PrintStr( "Throw did not work." EOL ); assert( false ); } catch ( ... ) { PrintStr( "Caught integer exception." EOL ); } PrintStr( "Test finished." EOL ); return; } if ( IsCmd( cmdBegin, cmdEnd, CMDNAME_SIMULATE_ERROR, false, true, &extraParamsFound ) ) { SimulateError( paramBegin ); return; } if ( IsCmd( cmdBegin, cmdEnd, CMDNAME_MEMORY_USAGE, false, false, &extraParamsFound ) ) { const unsigned heapSize = unsigned( GetHeapEndAddr() - uintptr_t( &_end ) ); Printf( "Partitions: malloc heap: %u bytes, free: %u bytes, stack: %u bytes." EOL, heapSize, GetStackStartAddr() - GetHeapEndAddr(), STACK_SIZE ); Printf( "Used stack (estimated): %u from %u bytes." EOL, unsigned( GetStackSizeUsageEstimate() ), STACK_SIZE ); const struct mallinfo mi = mallinfo(); const unsigned heapSizeAccordingToNewlib = unsigned( mi.arena ); Printf( "Heap: %u allocated from %u bytes." EOL, unsigned( mi.uordblks ), unsigned( mi.arena ) ); assert( heapSize == heapSizeAccordingToNewlib ); UNUSED_IN_RELEASE( heapSizeAccordingToNewlib ); return; } if ( extraParamsFound ) Printf( "Command \"%.*s\" does not take any parameters." EOL, cmdEnd - cmdBegin, cmdBegin ); else Printf( "Unknown command \"%.*s\"." EOL, cmdEnd - cmdBegin, cmdBegin ); }
void CCommandProcessor::ProcessUsbSpeedTestCmd ( const char * const paramBegin, const uint64_t currentTime ) { // Examples about how to automate the speed test from the bash command line: // Tests where the Arduino Due is sending: // echo "UsbSpeedTest TxFastLoopRawUsb" | socat - /dev/jtagdue1,b115200,raw,echo=0,crnl | pv -pertb >/dev/null // Tests where the Arduino Due is receiving: // (echo "UsbSpeedTest RxWithCircularBuffer" && yes ".") | pv -pertb - | socat - /dev/jtagdue1,b115200,raw,echo=0,crnl >/dev/null const uint32_t TEST_TIME_IN_MS = 5000; // We could make a user parameter out of this value. if ( *paramBegin == 0 ) { PrintStr( "Please specify the test type as an argument:" EOL ); PrintStr( " TxSimpleWithTimestamps" EOL ); PrintStr( " TxSimpleLoop" EOL ); PrintStr( " TxFastLoopCircularBuffer" EOL ); PrintStr( " TxFastLoopRawUsb" EOL ); PrintStr( " RxWithCircularBuffer" EOL ); return; } const char * const paramEnd = SkipCharsNotInSet( paramBegin, SPACE_AND_TAB ); assert( g_usbSpeedTestType == stNone ); UsbSpeedTestEnum testType = stNone; bool extraParamsFound = false; if ( IsCmd( paramBegin, paramEnd, "TxSimpleWithTimestamps", false, false, &extraParamsFound ) ) testType = stTxSimpleWithTimestamps; else if ( IsCmd( paramBegin, paramEnd, "TxSimpleLoop", false, false, &extraParamsFound ) ) testType = stTxSimpleLoop; else if ( IsCmd( paramBegin, paramEnd, "TxFastLoopCircularBuffer", false, false, &extraParamsFound ) ) testType = stTxFastLoopCircularBuffer; else if ( IsCmd( paramBegin, paramEnd, "TxFastLoopRawUsb", false, false, &extraParamsFound ) ) testType = stTxFastLoopRawUsb; else if ( IsCmd( paramBegin, paramEnd, "RxWithCircularBuffer", false, false, &extraParamsFound ) ) testType = stRxWithCircularBuffer; if ( testType != stNone ) { for ( size_t i = 0; i < sizeof( g_usbSpeedTestBuffer ); ++i ) g_usbSpeedTestBuffer[ i ] = '.'; g_usbSpeedTestEndTime = currentTime + TEST_TIME_IN_MS; g_usbSpeedTestType = testType; // This message may not make it to the console, depending on the test type. PrintStr( "Starting USB speed test..." EOL ); WakeFromMainLoopSleep(); return; } if ( extraParamsFound ) Printf( "No parameters are allowed after test type \"%.*s\"." EOL, paramEnd - paramBegin, paramBegin ); else Printf( "Unknown test type \"%.*s\"." EOL, paramEnd - paramBegin, paramBegin ); }
int ArcApp::OnRun() { wxString progname; m_validCmd = false; m_help = argc < 2; bool ok = false; bool dashdash = false; if (*argv && **argv) progname = wxFileName(*argv).GetName(); else progname = _T("arc"); // parse the command line for (int i = 1; i < argc; ++i) { wxString arg = argv[i]; if (!dashdash) { if (arg == _T("--")) { dashdash = true; continue; } else { if (arg == _T("--help") || arg == _T("-h") || arg == _T("/?")) { m_help = true; continue; } else { if (*arg == _T('-')) { m_errMsg = _T("invalid option '") + arg + _T("'"); break; } } } } if (m_cmd.empty()) m_cmd = arg; else if (m_archive.empty()) m_archive = arg; else m_args.push_back(arg); } if (m_errMsg.empty() && !m_archive.empty() && !MakeFactory()) return EXIT_FAILURE; m_filter = m_archive.find(_T('.')) == wxString::npos; // dispatch the command, and build up help information if (IsCmd(_T("add"), _T("FILES..."), _T("add files to an archive"))) ok = Add(); if (IsCmd(_T("create"), _T("FILES..."), _T("create an archive"))) ok = Create(); if (IsCmd(_T("extract"),_T("[PATTERN]"), _T("extract entries"))) ok = Extract(); if (IsCmd(_T("list"), _T("[PATTERN]"), _T("list contents"))) ok = List(); if (IsCmd(_T("remove"), _T("PATTERN"), _T("delete entries"))) ok = Remove(); if (IsCmd(_T("rename"), _T("FROM TO"), _T("rename an entry"))) ok = Rename(); // IsCmd populates m_availCmds, now use it to make a usage string wxString usage = _T("Usage: ") + progname + _T(" [-h|--help|/?] [COMMAND ARCHIVE [ARGUMENTS...]]\n") + _T("Commands:\n") + m_availCmds; // display help or error if necessary if (m_errMsg.empty()) if (m_help) { std::cout << usage.mb_str() << "Examples:\n" << " " << progname.mb_str() << " add test.zip *\n" << " The archive type is deduced from the file extension.\n" << " " << progname.mb_str() << " extract zip < test.zip\n" << " If ARCHIVE has no extension it is taken to be the name\n" << " of an archive format and " << progname.mb_str() << " acts as a filter.\n"; ok = true; } else if (!m_validCmd) { m_errMsg = _T("invalid command '") + m_cmd + _T("'"); } if (!m_errMsg.empty()) std::cerr << progname.mb_str() << ": " << m_errMsg.mb_str() << "\n" << usage.mb_str(); return ok ? EXIT_SUCCESS : EXIT_FAILURE; }