# HG changeset patch # User jlarmour # Date 991433789 0 # Node ID 0d0f03f76f6a5187a808a333072437cac67002a0 # Parent 511f4dc167f684f2d5c6e1f333abf1c67000c033 Merge from eCos master repository on 2001-06-01-18:52:13-BST diff --git a/host/ChangeLog b/host/ChangeLog --- a/host/ChangeLog +++ b/host/ChangeLog @@ -1,3 +1,9 @@ +2001-05-23 Julian Smart + + * Added Srdjan Sobajic's most excellent host/README improvements, + and listed the directories more clearly with a brief reference + to the new Configtool and its own readme. + 2001-05-16 Bart Veer * acinclude.m4 : diff --git a/host/README b/host/README --- a/host/README +++ b/host/README @@ -31,12 +31,21 @@ libcdl/ tools/configtool/ The sources to the various configuration tools can be found here. - In particular the command line ecosconfig tool lives in - tools/configtool/standalone/common; the sources related to - makefile generation currently live in - tools/configtool/common/common, and the graphical configuration - tool is spread over various directories including - tools/configtool/common/win32 and tools/configtool/standalone/win32 + +tools/configtool/standalone/common/ + Contains the command line ecosconfig tool. + +tools/configtool/common/common/ + Contains sources related to makefile generation. + +tools/configtool/common/win32/ +tools/configtool/standalone/win32/ + Contains sources for the MFC-based, Windows-only graphical configuration + tool. + +tools/configtool/standalone/wxwin/ + Contains sources for the wxWindows-based, Linux and Windows graphical + configuration tool. There are various other sub-directories related to the admin tool, testing support, and so on. @@ -46,11 +55,17 @@ undergoing rapid development, and the so and reorganization at any time. Much of the code is cross-platform. The obvious exception is the -graphical configuration tool which, at the time of writing, can only +original, MFC-based graphical configuration tool which can only be built for Windows hosts and requires Visual C++. It should be possible to build the underlying libraries and the command-line -configuration tool using gcc/g++ on any Unix platform. A Unix version -of the graphical configuration tool is planned but not yet available. +configuration tool using gcc/g++ on any Unix platform. + +A combined Unix and Windows version of the graphical +configuration tool, built using the wxWindows GUI toolkit, is +under development and has its own ReadMe in +tools/configtool/standalone/wxwin. Any further reference to the +graphical configuration tool in this document refers to the +original MFC-based version. More Information ================ @@ -206,13 +221,92 @@ installed then due care has to be taken option. -Installing on NT with VC++ -========================== +Installing on NT with VC++ (using Visual Studio) +================================================ It is possible to build both the graphical configuration tool and the ecosconfig command line tool using a Developer Studio project, tools/ecosconfig/standalone/win32/Configtool.dsw +Even if building the host tools from Visual Studio, it is still +necessary to install Cygwin and Tcl 8.x. Additionally, there is a +dependency on either the Microsoft Platform SDK or the Microsoft +HTML Help Workshop. + +The latter is available at: +http://msdn.microsoft.com/library/tools/htmlhelp/wkshp/download.htm + +To prepare the machine for the build, it is necessary to: + +1) Set the TCLHOME environment variable to the root of the Tcl installation. +(For example, TCLHOME=C:\tcl) This can be set from the Enviroment Variables +dialog on the Advanced tab of the System Properties dialog. + +2) It is also necessary to add several directories to Visual Studio's default +file search paths. This is set from the Directories tab in the Options menu. + +The following entries will need to be added (full paths are shown for clarity, +the actual path may be different): + + a) Executable Files + c:\cygwin\bin + b) Include Files + c:\tcl\include + c:\program files\microsoft platform sdk\include _OR_ + c:\program files\html help workshop\include + c) Library Files + c:\tcl\lib + c:\program files\microsoft platform sdk\lib _OR_ + c:\program files\html help workshop\lib + +3) The build process as setup by default in the sources available from CVS is +setup to build the host tools on the DOS v:\ drive. If this drive doesn't exist, +it may be preferable to do a "subst v:\ c:\temp" command from a Windows command +shell. This will effectively create a virtual disk which is located at c:\temp, +and the build process will place all intermediate and build files in this location. +(Alternatively, it is possible to go through the project settings in Visual Studio +and adjust the drive letters manually.) + +4) If you have installed a version of Tcl other than version 8.2, it will be necessary +to change the names of libraries linked with the projects. This can be done by: + +a) Selecting "Settings..." on the ChangeLog file in the cdl project in the +Configtool workspace, you will see the custom build step for the project. +At the end of the first line of the custom build step, there is an option +--with-tcl_version=82. Change this value (82) to correspond to the version of Tcl +installed on the machine. + +b) Selecting "Settings..." on the Configtool project in the workspace, you should +go to the Link tab in the right-hand pane. In this pane you will see a line listing +all the Libraries with which the project is being linked. Change the tcl82.lib entry +to the name appropriate for the version of Tcl installed. + +(NOTE: These settings must be applied to all configurations you intend to build +separately. The eCos host tools as shipped by RedHat are built using the +"Win32 ANSI Release" Configuration. If you build the "Win32 Release" Configuration, +you will also need to have the Unicode version of the MFC libraries and DLLs.) + +5) Click "Build... (F7)". The compiled binaries will be located in the Configtool +folder on the V:\ drive. + + +NOTES: + +1) When using WinCVS, make sure to use the default Windows mode to get the tools. +Using UNIX mode will break the Visual Studio project files and you won't be able +to open them. (It is preferable, in general, to use Windows mode for all eCos files.) + +2) There will be many warnings related to STL header compilation. These are benign. +There are also some warnings related to missing help files at the beginning of the +Configtool project compilation. These can also be ignored. + +3) To build the other Win32 projects in the host tools, it may be necessary to repeat +step 4.b) above. (Again, this depends on which version of Tcl is in use.) + + +Installing on NT with VC++ (using Cygwin) +========================================= + It is also possible to build the command line tool and the various libraries using the configure script. At the time of writing the graphical configuration tool cannot yet be built that way. This still @@ -266,7 +360,7 @@ further information. //####COPYRIGHTBEGIN#### // // ---------------------------------------------------------------------------- -// Copyright (C) 2000 Red Hat, Inc. +// Copyright (C) 2000, 2001 Red Hat, Inc. // // This file is part of the eCos host tools. // diff --git a/host/tools/configtool/standalone/win32/Configtool.cpp b/host/tools/configtool/standalone/win32/Configtool.cpp --- a/host/tools/configtool/standalone/win32/Configtool.cpp +++ b/host/tools/configtool/standalone/win32/Configtool.cpp @@ -360,8 +360,12 @@ void CConfigToolApp::LoadStdProfileSetti } } - // Look for Cygwin 00r1 first, since it's the latest and greatest user tools. - GetRepositoryRegistryClues(m_arstrUserToolPaths, _T("Cygwin 00r1")); + // Look for GNUPro 00r1 first, since it's the latest and greatest user tools. + GetRepositoryRegistryClues(m_arstrUserToolPaths, _T("GNUPro 00r1")); + if (m_arstrUserToolPaths.GetSize() == 0) + { + GetRepositoryRegistryClues(m_arstrUserToolPaths, _T("Cygwin 00r1")); + } if (m_arstrUserToolPaths.GetSize() > 0) { for(i=0;i +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=ConfigtoolVC - Win32 ANSI Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "ConfigtoolVC.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "ConfigtoolVC.mak" CFG="ConfigtoolVC - Win32 ANSI Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "ConfigtoolVC - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "ConfigtoolVC - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE "ConfigtoolVC - Win32 ANSI Debug" (based on "Win32 (x86) Application") +!MESSAGE "ConfigtoolVC - Win32 ANSI Release" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "ConfigtoolVC - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "v:\ConfigToolWX\Release" +# PROP Intermediate_Dir "v:\ConfigToolWX\Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GR /GX /O1 /Ob2 /I "v:\cdl\Release\include" /I "..\..\common\common" /I "..\..\..\Utils\common" /I "..\..\..\ecostest\common" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "__WINDOWS__" /D "__WXMSW__" /D "__WIN95__" /D "__WIN32__" /D WINVER=0x0400 /D "STRICT" /Yu"ecpch.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 +# ADD BASE RSC /l 0x809 /d "NDEBUG" +# ADD RSC /l 0x809 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib winmm.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 wx.lib xpm.lib png.lib zlib.lib jpeg.lib tiff.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib rpcrt4.lib wsock32.lib wininet.lib shlwapi.lib winmm.lib htmlhelp.lib cyginfra.lib cdl.lib tcl82.lib /nologo /subsystem:windows /machine:I386 /nodefaultlib:"libc.lib" /nodefaultlib:"libci.lib" /nodefaultlib:"msvcrtd.lib" /out:"v:/ConfigToolWX/Release/configtool.exe" /libpath:"v:\cdl\release\lib" + +!ELSEIF "$(CFG)" == "ConfigtoolVC - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "v:\ConfigToolWX\Debug" +# PROP Intermediate_Dir "v:\ConfigToolWX\Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /MDd /W3 /Gm /GR /GX /ZI /Od /I "v:\cdl\Debug\include" /I "..\..\common\common" /I "..\..\..\Utils\common" /I "..\..\..\ecostest\common" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "__WINDOWS__" /D "__WXMSW__" /D DEBUG=1 /D "__WXDEBUG__" /D "__WIN95__" /D "__WIN32__" /D WINVER=0x0400 /D "STRICT" /Yu"ecpch.h" /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 +# ADD BASE RSC /l 0x809 /d "_DEBUG" +# ADD RSC /l 0x809 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib winmm.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 wxd.lib xpmd.lib pngd.lib zlibd.lib jpegd.lib tiffd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib rpcrt4.lib wsock32.lib wininet.lib winmm.lib shlwapi.lib htmlhelp.lib cyginfra.lib cdl.lib tcl82d.lib /nologo /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcd.lib" /nodefaultlib:"libcid.lib" /nodefaultlib:"msvcrt.lib" /out:"v:/ConfigToolWX/Debug/configtool.exe" /pdbtype:sept /libpath:"v:\cdl\debug\lib" + +!ELSEIF "$(CFG)" == "ConfigtoolVC - Win32 ANSI Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "ConfigtoolVC___Win32_ANSI_Debug" +# PROP BASE Intermediate_Dir "ConfigtoolVC___Win32_ANSI_Debug" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "v:\ConfigToolWX\ANSIDebug" +# PROP Intermediate_Dir "v:\ConfigToolWX\ANSIDebug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /Gm /GR /GX /ZI /Od /I "v:\cdl\Debug\include" /I "..\..\common\common" /I "..\..\..\Utils\common" /I "..\..\..\ecostest\common" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "__WINDOWS__" /D "__WXMSW__" /D DEBUG=1 /D "__WXDEBUG__" /D "__WIN95__" /D "__WIN32__" /D WINVER=0x0400 /D "STRICT" /Yu"ecpch.h" /FD /c +# ADD CPP /nologo /MDd /W3 /Gm /GR /GX /ZI /Od /I "v:\cdl\Debug\include" /I "..\..\common\common" /I "..\..\..\Utils\common" /I "..\..\..\ecostest\common" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "__WINDOWS__" /D "__WXMSW__" /D DEBUG=1 /D "__WXDEBUG__" /D "__WIN95__" /D "__WIN32__" /D WINVER=0x0400 /D "STRICT" /Yu"ecpch.h" /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 +# ADD BASE RSC /l 0x809 /d "_DEBUG" +# ADD RSC /l 0x809 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 wxd.lib xpmd.lib pngd.lib zlibd.lib jpegd.lib tiffd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib rpcrt4.lib wsock32.lib wininet.lib winmm.lib shlwapi.lib htmlhelp.lib cyginfra.lib cdl.lib tcl82d.lib /nologo /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcd.lib" /nodefaultlib:"libcid.lib" /nodefaultlib:"msvcrt.lib" /out:"Debug/configtool.exe" /pdbtype:sept /libpath:"v:\cdl\debug\lib" +# ADD LINK32 wxd.lib pngd.lib zlibd.lib jpegd.lib tiffd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib rpcrt4.lib wsock32.lib wininet.lib winmm.lib shlwapi.lib htmlhelp.lib cyginfra.lib cdl.lib tcl82d.lib /nologo /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcd.lib" /nodefaultlib:"libcid.lib" /nodefaultlib:"msvcrt.lib" /out:"v:/ConfigToolWX/ANSIDebug/configtool.exe" /pdbtype:sept /libpath:"v:\cdl\debug\lib" + +!ELSEIF "$(CFG)" == "ConfigtoolVC - Win32 ANSI Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "ConfigtoolVC___Win32_ANSI_Release" +# PROP BASE Intermediate_Dir "ConfigtoolVC___Win32_ANSI_Release" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "v:\ConfigToolWX\ANSIRelease" +# PROP Intermediate_Dir "v:\ConfigToolWX\ANSIRelease" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /GR /GX /O1 /Ob2 /I "v:\cdl\Release\include" /I "..\..\common\common" /I "..\..\..\Utils\common" /I "..\..\..\ecostest\common" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "__WINDOWS__" /D "__WXMSW__" /D "__WIN95__" /D "__WIN32__" /D WINVER=0x0400 /D "STRICT" /Yu"ecpch.h" /FD /c +# ADD CPP /nologo /MD /W3 /GR /GX /O1 /Ob2 /I "v:\cdl\Release\include" /I "..\..\common\common" /I "..\..\..\Utils\common" /I "..\..\..\ecostest\common" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "__WINDOWS__" /D "__WXMSW__" /D "__WIN95__" /D "__WIN32__" /D WINVER=0x0400 /D "STRICT" /Yu"ecpch.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 +# ADD BASE RSC /l 0x809 /d "NDEBUG" +# ADD RSC /l 0x809 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 wx.lib xpm.lib png.lib zlib.lib jpeg.lib tiff.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib rpcrt4.lib wsock32.lib wininet.lib shlwapi.lib winmm.lib htmlhelp.lib cyginfra.lib cdl.lib tcl82.lib /nologo /subsystem:windows /machine:I386 /nodefaultlib:"libc.lib" /nodefaultlib:"libci.lib" /nodefaultlib:"msvcrtd.lib" /out:"Release/configtool.exe" /libpath:"v:\cdl\release\lib" +# ADD LINK32 wx.lib png.lib zlib.lib jpeg.lib tiff.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib rpcrt4.lib wsock32.lib wininet.lib shlwapi.lib winmm.lib htmlhelp.lib cyginfra.lib cdl.lib tcl82.lib /nologo /subsystem:windows /machine:I386 /nodefaultlib:"libc.lib" /nodefaultlib:"libci.lib" /nodefaultlib:"msvcrtd.lib" /out:"v:/ConfigToolWX/ANSIRelease/configtool.exe" /libpath:"v:\cdl\release\lib" + +!ENDIF + +# Begin Target + +# Name "ConfigtoolVC - Win32 Release" +# Name "ConfigtoolVC - Win32 Debug" +# Name "ConfigtoolVC - Win32 ANSI Debug" +# Name "ConfigtoolVC - Win32 ANSI Release" +# Begin Group "GUI files" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\aboutdlg.cpp +# End Source File +# Begin Source File + +SOURCE=.\aboutdlg.h +# End Source File +# Begin Source File + +SOURCE=.\admindlg.cpp +# End Source File +# Begin Source File + +SOURCE=.\admindlg.h +# End Source File +# Begin Source File + +SOURCE=.\appsettings.cpp +# End Source File +# Begin Source File + +SOURCE=.\appsettings.h +# End Source File +# Begin Source File + +SOURCE=.\buildoptionsdlg.cpp +# End Source File +# Begin Source File + +SOURCE=.\buildoptionsdlg.h +# End Source File +# Begin Source File + +SOURCE=.\choosereposdlg.cpp +# End Source File +# Begin Source File + +SOURCE=.\choosereposdlg.h +# End Source File +# Begin Source File + +SOURCE=.\configitem.cpp +# End Source File +# Begin Source File + +SOURCE=.\configitem.h +# End Source File +# Begin Source File + +SOURCE=.\configpropdlg.cpp +# End Source File +# Begin Source File + +SOURCE=.\configpropdlg.h +# End Source File +# Begin Source File + +SOURCE=.\configtool.cpp +# ADD CPP /I "..\..\..\include" /Yc"ecpch.h" +# End Source File +# Begin Source File + +SOURCE=.\configtool.h +# End Source File +# Begin Source File + +SOURCE=.\configtool.rc +# ADD BASE RSC /l 0x809 +# ADD RSC /l 0x809 +# End Source File +# Begin Source File + +SOURCE=.\configtooldoc.cpp +# End Source File +# Begin Source File + +SOURCE=.\configtooldoc.h +# End Source File +# Begin Source File + +SOURCE=.\configtoolview.cpp +# End Source File +# Begin Source File + +SOURCE=.\configtoolview.h +# End Source File +# Begin Source File + +SOURCE=.\configtree.cpp +# End Source File +# Begin Source File + +SOURCE=.\configtree.h +# End Source File +# Begin Source File + +SOURCE=.\conflictsdlg.cpp +# End Source File +# Begin Source File + +SOURCE=.\conflictsdlg.h +# End Source File +# Begin Source File + +SOURCE=.\conflictwin.cpp +# End Source File +# Begin Source File + +SOURCE=.\conflictwin.h +# End Source File +# Begin Source File + +SOURCE=.\docsystem.cpp +# End Source File +# Begin Source File + +SOURCE=.\docsystem.h +# End Source File +# Begin Source File + +SOURCE=.\ecpch.h +# End Source File +# Begin Source File + +SOURCE=.\ecscrolwin.cpp +# ADD CPP /Yu +# End Source File +# Begin Source File + +SOURCE=.\ecscrolwin.h +# End Source File +# Begin Source File + +SOURCE=.\ecutils.cpp +# End Source File +# Begin Source File + +SOURCE=.\ecutils.h +# End Source File +# Begin Source File + +SOURCE=.\filename.cpp +# End Source File +# Begin Source File + +SOURCE=.\filename.h +# End Source File +# Begin Source File + +SOURCE=.\finddlg.cpp +# End Source File +# Begin Source File + +SOURCE=.\finddlg.h +# End Source File +# Begin Source File + +SOURCE=.\folderdlg.cpp +# End Source File +# Begin Source File + +SOURCE=.\folderdlg.h +# End Source File +# Begin Source File + +SOURCE=.\htmlparser.cpp +# End Source File +# Begin Source File + +SOURCE=.\htmlparser.h +# End Source File +# Begin Source File + +SOURCE=.\licensedlg.cpp +# End Source File +# Begin Source File + +SOURCE=.\licensedlg.h +# End Source File +# Begin Source File + +SOURCE=.\mainwin.cpp + +!IF "$(CFG)" == "ConfigtoolVC - Win32 Release" + +!ELSEIF "$(CFG)" == "ConfigtoolVC - Win32 Debug" + +# ADD CPP /Yu + +!ELSEIF "$(CFG)" == "ConfigtoolVC - Win32 ANSI Debug" + +# ADD BASE CPP /Yu +# ADD CPP /Yu + +!ELSEIF "$(CFG)" == "ConfigtoolVC - Win32 ANSI Release" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\mainwin.h +# End Source File +# Begin Source File + +SOURCE=.\memmap.cpp +# End Source File +# Begin Source File + +SOURCE=.\memmap.h +# End Source File +# Begin Source File + +SOURCE=.\mltwin.cpp +# End Source File +# Begin Source File + +SOURCE=.\mltwin.h +# End Source File +# Begin Source File + +SOURCE=.\msgdlgex.cpp +# End Source File +# Begin Source File + +SOURCE=.\msgdlgex.h +# End Source File +# Begin Source File + +SOURCE=.\outputwin.cpp +# End Source File +# Begin Source File + +SOURCE=.\outputwin.h +# End Source File +# Begin Source File + +SOURCE=.\packagesdlg.cpp +# End Source File +# Begin Source File + +SOURCE=.\packagesdlg.h +# End Source File +# Begin Source File + +SOURCE=.\platformeditordlg.cpp +# End Source File +# Begin Source File + +SOURCE=.\platformeditordlg.h +# End Source File +# Begin Source File + +SOURCE=.\platformsdlg.cpp +# End Source File +# Begin Source File + +SOURCE=.\platformsdlg.h +# End Source File +# Begin Source File + +SOURCE=.\propertywin.cpp +# End Source File +# Begin Source File + +SOURCE=.\propertywin.h +# End Source File +# Begin Source File + +SOURCE=.\reposdlg.cpp +# End Source File +# Begin Source File + +SOURCE=.\reposdlg.h +# End Source File +# Begin Source File + +SOURCE=.\runtestsdlg.cpp +# End Source File +# Begin Source File + +SOURCE=.\runtestsdlg.h +# End Source File +# Begin Source File + +SOURCE=.\sectiondlg.cpp +# End Source File +# Begin Source File + +SOURCE=.\sectiondlg.h +# End Source File +# Begin Source File + +SOURCE=.\settingsdlg.cpp +# End Source File +# Begin Source File + +SOURCE=.\settingsdlg.h +# End Source File +# Begin Source File + +SOURCE=.\shortdescrwin.cpp +# End Source File +# Begin Source File + +SOURCE=.\shortdescrwin.h +# End Source File +# Begin Source File + +SOURCE=.\solutionswin.cpp +# End Source File +# Begin Source File + +SOURCE=.\solutionswin.h +# End Source File +# Begin Source File + +SOURCE=.\splittree.cpp +# End Source File +# Begin Source File + +SOURCE=.\splittree.h +# End Source File +# Begin Source File + +SOURCE=.\templatesdlg.cpp +# End Source File +# Begin Source File + +SOURCE=.\templatesdlg.h +# End Source File +# End Group +# Begin Group "Common files" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\common\common\build.cxx +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utils\common\Collections.cpp +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utils\common\Collections.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utils\common\eCosSerial.cpp +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utils\common\eCosSerial.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utils\common\eCosSocket.cpp +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utils\common\eCosSocket.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utils\common\eCosStd.cpp +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utils\common\eCosStd.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\ecostest\common\eCosTest.cpp +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\ecostest\common\eCosTest.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\ecostest\common\eCosTestDownloadFilter.cpp +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\ecostest\common\eCosTestDownloadFilter.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\ecostest\common\eCosTestPlatform.cpp +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\ecostest\common\eCosTestPlatform.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\ecostest\common\eCosTestSerialFilter.cpp +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\ecostest\common\eCosTestSerialFilter.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\ecostest\common\eCosTestUtils.cpp +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\ecostest\common\eCosTestUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utils\common\eCosThreadUtils.cpp +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utils\common\eCosThreadUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utils\common\eCosTrace.cpp +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utils\common\eCosTrace.h +# End Source File +# Begin Source File + +SOURCE=..\..\common\common\flags.cxx +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utils\common\Properties.cpp +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utils\common\Properties.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\ecostest\common\ResetAttributes.cpp +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\ecostest\common\ResetAttributes.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utils\common\Subprocess.cpp +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utils\common\Subprocess.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\ecostest\common\TestResource.cpp +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\ecostest\common\TestResource.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utils\common\wcharunix.h +# End Source File +# End Group +# Begin Group "Doc & Setup files" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\about.htm +# End Source File +# Begin Source File + +SOURCE=.\setup\innobott.txt +# End Source File +# Begin Source File + +SOURCE=.\setup\innotop.txt +# End Source File +# Begin Source File + +SOURCE=.\setup\makesetup.sh +# End Source File +# Begin Source File + +SOURCE=.\setup\maketarball.sh +# End Source File +# Begin Source File + +SOURCE=.\readme.html +# End Source File +# Begin Source File + +SOURCE=.\README.txt +# End Source File +# Begin Source File + +SOURCE=.\symbols.h +# End Source File +# End Group +# Begin Source File + +SOURCE=..\..\ChangeLog +# End Source File +# End Target +# End Project diff --git a/host/tools/configtool/standalone/wxwin/ConfigtoolVC.dsw b/host/tools/configtool/standalone/wxwin/ConfigtoolVC.dsw new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/ConfigtoolVC.dsw @@ -0,0 +1,44 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "ConfigtoolVC"=.\ConfigtoolVC.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name cdl + End Project Dependency +}}} + +############################################################################### + +Project: "cdl"=..\..\..\..\libcdl\cdl.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/host/tools/configtool/standalone/wxwin/Makefile b/host/tools/configtool/standalone/wxwin/Makefile new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/Makefile @@ -0,0 +1,399 @@ +# +# File: Makefile for Configtool +# Author: Julian Smart +# Created: 2000.08.25 +# Updated: +# Copyright: (c) Red Hat, Inc. +# +# To make absolutely everything: +# +# % mkdir /tmp/ecos-build +# % cd /tmp/ecos-build +# % make -f $(ECOSDIR)/host/tools/configtool/standalone/wxwin/Makefile WXDIR=$(WXDIR) ECOSDIR=$(ECOSDIR) LEVEL=debug full +# +# To make just Configtool: +# +# % make ... LEVEL=debug ct +# +# To make wxWindows & eCos libraries: +# +# % make ... LEVEL=debug wx ecc +# +# The result will be subdirectories under your /tmp/ecos-build (or other specified +# directory) containing: +# +# ct-build-debug/ +# ecc-build-debug/ +# wxwin-build-debug/ +# +# To make a release version, specify LEVEL=release instead of LEVEL=debug. +# + +# If this is set to gcc, we get some link errors relating to +# streams and such +CC = c++ +#CC = gcc + +PROGRAM = configtool +LEVEL = debug +WXDEBUGFLAGS=--with-debug_flag --with-debug_info --enable-debug --enable-debug_cntxt +ECCDEBUGFLAGS=--enable-debug +CPPDEBUGOPTIONS=-ggdb +LINKDEBUGOPTIONS= +STRIPCOMMAND=echo +USEEXPERIMENTALCODE=1 + +# You should specify this on the command line +WXDIR=You_should_override_the_WXDIR_variable + +# Current (build) directory +CURRDIR = $(shell pwd) +BUILDDIR=$(CURRDIR) + +# Where the CDL, infra etc. libraries have been built +ECOSBUILDDIR=$(BUILDDIR)/ecc-build-$(LEVEL) +WXBUILDDIR=$(BUILDDIR)/wxwin-build-$(LEVEL) +CTBUILDDIR=$(BUILDDIR)/ct-build-$(LEVEL) + +# You have to specify this when invoking make. +ECOSDIR=You_should_override_the_ECOSDIR_variable +CTDIR=$(ECOSDIR)/host/tools/configtool/standalone/wxwin +WXCONFIG=$(WXBUILDDIR)/wx-config +# Where the binary will be installed locally +LOCALBINDIR=/home/ecos/misctools/H-i686-pc-linux-gnu/bin +# A suitable home for archives of the tool +LOCALARCHIVEDIR=/netopt/ecc-share/releng/eCosTools/eCosConfigurationTool + +ifneq "$(LEVEL)" "debug" + WXDEBUGFLAGS=--without-debug_flag --without-debug_info --disable-debug + ECCDEBUGFLAGS=--disable-debug + CPPDEBUGOPTIONS=-O2 + LINKDEBUGOPTIONS=--strip-debug + STRIPCOMMAND=strip +endif + +OBJECTS = \ + $(CTBUILDDIR)/aboutdlg.o \ + $(CTBUILDDIR)/admindlg.o \ + $(CTBUILDDIR)/appsettings.o \ + $(CTBUILDDIR)/build.o \ + $(CTBUILDDIR)/buildoptionsdlg.o \ + $(CTBUILDDIR)/choosereposdlg.o \ + $(CTBUILDDIR)/Collections.o \ + $(CTBUILDDIR)/configitem.o \ + $(CTBUILDDIR)/configpropdlg.o \ + $(CTBUILDDIR)/configtool.o \ + $(CTBUILDDIR)/configtooldoc.o \ + $(CTBUILDDIR)/configtoolview.o \ + $(CTBUILDDIR)/configtree.o \ + $(CTBUILDDIR)/conflictsdlg.o \ + $(CTBUILDDIR)/conflictwin.o \ + $(CTBUILDDIR)/docsystem.o \ + $(CTBUILDDIR)/ecscrolwin.o \ + $(CTBUILDDIR)/eCosSerial.o \ + $(CTBUILDDIR)/eCosSocket.o \ + $(CTBUILDDIR)/eCosStd.o \ + $(CTBUILDDIR)/eCosTest.o \ + $(CTBUILDDIR)/eCosTestDownloadFilter.o \ + $(CTBUILDDIR)/eCosTestPlatform.o \ + $(CTBUILDDIR)/eCosTestSerialFilter.o \ + $(CTBUILDDIR)/eCosTestUtils.o \ + $(CTBUILDDIR)/eCosThreadUtils.o \ + $(CTBUILDDIR)/eCosTrace.o \ + $(CTBUILDDIR)/ecutils.o \ + $(CTBUILDDIR)/filename.o \ + $(CTBUILDDIR)/finddlg.o \ + $(CTBUILDDIR)/flags.o \ + $(CTBUILDDIR)/folderdlg.o \ + $(CTBUILDDIR)/htmlparser.o \ + $(CTBUILDDIR)/licensedlg.o \ + $(CTBUILDDIR)/mainwin.o \ + $(CTBUILDDIR)/mltwin.o \ + $(CTBUILDDIR)/msgdlgex.o \ + $(CTBUILDDIR)/outputwin.o \ + $(CTBUILDDIR)/packagesdlg.o \ + $(CTBUILDDIR)/platformeditordlg.o \ + $(CTBUILDDIR)/platformsdlg.o \ + $(CTBUILDDIR)/propertywin.o \ + $(CTBUILDDIR)/Properties.o \ + $(CTBUILDDIR)/reposdlg.o \ + $(CTBUILDDIR)/ResetAttributes.o \ + $(CTBUILDDIR)/runtestsdlg.o \ + $(CTBUILDDIR)/sectiondlg.o \ + $(CTBUILDDIR)/settingsdlg.o \ + $(CTBUILDDIR)/shortdescrwin.o \ + $(CTBUILDDIR)/solutionswin.o \ + $(CTBUILDDIR)/splittree.o \ + $(CTBUILDDIR)/Subprocess.o \ + $(CTBUILDDIR)/templatesdlg.o \ + $(CTBUILDDIR)/TestResource.o + + +# C++ compiler +CC = c++ + +INCLUDEPREFIX=--prefix=$(WXBUILDDIR) +LIBPREFIX=--prefix=$(WXBUILDDIR) +EXTRACPPFLAGS=\ + -I$(WXDIR)/include\ + -I$(ECOSDIR)/host/libcdl\ + -I$(ECOSDIR)/host/infra\ + -I$(ECOSDIR)/host/tools/configtool/common/common\ + -I$(ECOSDIR)/host/tools/Utils/common\ + -I$(ECOSDIR)/host/tools/ecostest/common\ + -I$(ECOSBUILDDIR)/libcdl\ + -I$(ECOSBUILDDIR)/infra\ + -DecUSE_EXPERIMENTAL_CODE=$(USEEXPERIMENTALCODE) + +EXTRALDFLAGS=-L$(ECOSBUILDDIR)/infra -L$(ECOSBUILDDIR)/libcdl -lcdl -lcyginfra -ltcl + +.SUFFIXES: .o .cpp .cxx + +.cpp.o : + $(CC) $(CPPDEBUGOPTIONS) -c $(EXTRACPPFLAGS) `$(WXCONFIG) $(INCLUDEPREFIX) --cflags` -o $@ $< + +.cxx.o : + $(CC) $(CPPDEBUGOPTIONS) -c $(EXTRACPPFLAGS) `$(WXCONFIG) $(INCLUDEPREFIX) --cflags` -o $@ $< + +all: mkbuilddir $(CTBUILDDIR)/$(PROGRAM) + +ct: mkbuilddir $(CTBUILDDIR)/$(PROGRAM) + +mkbuilddir: + mkdir -p $(CTBUILDDIR) + +$(CTBUILDDIR)/$(PROGRAM): $(OBJECTS) + $(CC) $(LINKDEBUGOPTIONS) -o $(CTBUILDDIR)/$(PROGRAM) $(OBJECTS) $(EXTRALDFLAGS) `$(WXCONFIG) $(LIBPREFIX) --libs` + $(STRIPCOMMAND) $(CTBUILDDIR)/$(PROGRAM) + +full: wx ecc all + +wx: + @mkdir -p $(WXBUILDDIR) ; \ + cd $(WXBUILDDIR) ; \ + if test ! -f Makefile ; then rm -f *.o *.d ; \ + rm -f *.cache ; \ + $(WXDIR)/configure --disable-shared --enable-gui --with-gtk --enable-log $(WXDEBUGFLAGS) --with-threads --without-sockets -without-odbc -without-libjpeg ; \ + fi; \ + make + +ecc: + @mkdir -p $(ECOSBUILDDIR) ; \ + cd $(ECOSBUILDDIR) ; \ + if test ! -f Makefile ; then $(ECOSDIR)/host/configure --prefix=$(ECOSBUILDDIR) $(ECCDEBUGFLAGS) --with-tcl=/usr ; \ + fi ; \ + make + +# Some GTK+ installations are a bit broken and we need to define __WXGTK127__ even if +# we don't really have GTK++ 1.2.7. This manifests itself in a compile error in dcclient.cpp. + +wxgtkfix: + @rm -f $(WXBUILDDIR)/setup.h; rm -f $(WXBUILDIR)/lib/wx/include/wx/gtk*/setup/h; \ + sed -e "s;/\* #undef __WXGTK127__ \*/;#define __WXGTK127__ 1;g;" < $(WXBUILDDIR)/include/wx/gtk/setup.h > /tmp/setup.h ; \ + mv /tmp/setup.h $(WXBUILDDIR)/include/wx/gtk/setup.h + +clean: + rm -f $(CTBUILDDIR)/$(PROGRAM) $(CTBUILDDIR)/*.o + +cleanct: clean + +cleanecc: + rm -f -r $(ECOSBUILDDIR) + +cleanwx: + rm -f -r $(WXBUILDDIR) + +cleanall: clean cleanecc cleanwx + +# Making a binary, RH Linux tarball release using the setup script. +# It will put the result in /tmp/ctdeliver. +releasect: + echo "#include " > /tmp/ctver.c + echo "#include \"symbols.h\"" >> /tmp/ctver.c + echo "int main() { printf(\"%.1f\", ecCONFIGURATION_TOOL_VERSION); }" >> /tmp/ctver.c + cc /tmp/ctver.c -I$(CTDIR) -o /tmp/ctver + chmod a+x $(CTDIR)/setup/maketarball.sh + $(CTDIR)/setup/maketarball.sh $(ECOSDIR)/.. $(CTBUILDDIR) /tmp/ctdeliver `/tmp/ctver` + rm -f /tmp/ctver /tmp/ctver.c + +# Installs the binary and associated files in the correct place for local running +installbinary: releasect + cp /tmp/ctdeliver/configtool/configtool $(LOCALBINDIR)/configtool-`date -I` + mv /tmp/ctdeliver/configtool/README.txt /tmp/ctdeliver/configtool/README-configtool.txt + rm -f $(LOCALBINDIR)/configtool + ln -s $(LOCALBINDIR)/configtool-`date -I` $(LOCALBINDIR)/configtool + cp -r /tmp/ctdeliver/configtool/* $(LOCALBINDIR) + +# Copies an archive to a suitable place for people to grab +installtarball: releasect + mkdir -p $(LOCALARCHIVEDIR)/`date -I` + cp /tmp/ctdeliver/configtool*.tgz $(LOCALARCHIVEDIR)/`date -I` + +### GUI Configtool files + +$(CTBUILDDIR)/aboutdlg.o: $(CTDIR)/aboutdlg.cpp $(CTDIR)/aboutdlg.h $(CTDIR)/symbols.h + $(CC) $(CPPDEBUGOPTIONS) -c $(EXTRACPPFLAGS) `$(WXCONFIG) $(INCLUDEPREFIX) --cflags` -o $@ $< + +$(CTBUILDDIR)/admindlg.o: $(CTDIR)/admindlg.cpp $(CTDIR)/admindlg.h + $(CC) $(CPPDEBUGOPTIONS) -c $(EXTRACPPFLAGS) `$(WXCONFIG) $(INCLUDEPREFIX) --cflags` -o $@ $< + +$(CTBUILDDIR)/appsettings.o: $(CTDIR)/appsettings.cpp $(CTDIR)/appsettings.h + $(CC) $(CPPDEBUGOPTIONS) -c $(EXTRACPPFLAGS) `$(WXCONFIG) $(INCLUDEPREFIX) --cflags` -o $@ $< + +$(CTBUILDDIR)/buildoptionsdlg.o: $(CTDIR)/buildoptionsdlg.cpp $(CTDIR)/buildoptionsdlg.h + $(CC) $(CPPDEBUGOPTIONS) -c $(EXTRACPPFLAGS) `$(WXCONFIG) $(INCLUDEPREFIX) --cflags` -o $@ $< + +$(CTBUILDDIR)/choosereposdlg.o: $(CTDIR)/choosereposdlg.cpp $(CTDIR)/choosereposdlg.h + $(CC) $(CPPDEBUGOPTIONS) -c $(EXTRACPPFLAGS) `$(WXCONFIG) $(INCLUDEPREFIX) --cflags` -o $@ $< + +$(CTBUILDDIR)/configitem.o: $(CTDIR)/configitem.cpp $(CTDIR)/configitem.h + $(CC) $(CPPDEBUGOPTIONS) -c $(EXTRACPPFLAGS) `$(WXCONFIG) $(INCLUDEPREFIX) --cflags` -o $@ $< + +$(CTBUILDDIR)/configpropdlg.o: $(CTDIR)/configpropdlg.cpp $(CTDIR)/configpropdlg.h + $(CC) $(CPPDEBUGOPTIONS) -c $(EXTRACPPFLAGS) `$(WXCONFIG) $(INCLUDEPREFIX) --cflags` -o $@ $< + +$(CTBUILDDIR)/configtool.o: $(CTDIR)/configtool.cpp $(CTDIR)/configtool.h + $(CC) $(CPPDEBUGOPTIONS) -c $(EXTRACPPFLAGS) `$(WXCONFIG) $(INCLUDEPREFIX) --cflags` -o $@ $< + +$(CTBUILDDIR)/configtooldoc.o: $(CTDIR)/configtooldoc.cpp $(CTDIR)/configtooldoc.h + $(CC) $(CPPDEBUGOPTIONS) -c $(EXTRACPPFLAGS) `$(WXCONFIG) $(INCLUDEPREFIX) --cflags` -o $@ $< + +$(CTBUILDDIR)/configtoolview.o: $(CTDIR)/configtoolview.cpp $(CTDIR)/configtoolview.h + $(CC) $(CPPDEBUGOPTIONS) -c $(EXTRACPPFLAGS) `$(WXCONFIG) $(INCLUDEPREFIX) --cflags` -o $@ $< + +$(CTBUILDDIR)/configtree.o: $(CTDIR)/configtree.cpp $(CTDIR)/configtree.h + $(CC) $(CPPDEBUGOPTIONS) -c $(EXTRACPPFLAGS) `$(WXCONFIG) $(INCLUDEPREFIX) --cflags` -o $@ $< + +$(CTBUILDDIR)/conflictsdlg.o: $(CTDIR)/conflictsdlg.cpp $(CTDIR)/conflictsdlg.h + $(CC) $(CPPDEBUGOPTIONS) -c $(EXTRACPPFLAGS) `$(WXCONFIG) $(INCLUDEPREFIX) --cflags` -o $@ $< + +$(CTBUILDDIR)/conflictwin.o: $(CTDIR)/conflictwin.cpp $(CTDIR)/conflictwin.h + $(CC) $(CPPDEBUGOPTIONS) -c $(EXTRACPPFLAGS) `$(WXCONFIG) $(INCLUDEPREFIX) --cflags` -o $@ $< + +$(CTBUILDDIR)/docsystem.o: $(CTDIR)/docsystem.cpp $(CTDIR)/docsystem.h + $(CC) $(CPPDEBUGOPTIONS) -c $(EXTRACPPFLAGS) `$(WXCONFIG) $(INCLUDEPREFIX) --cflags` -o $@ $< + +$(CTBUILDDIR)/ecutils.o: $(CTDIR)/ecutils.cpp $(CTDIR)/ecutils.h + $(CC) $(CPPDEBUGOPTIONS) -c $(EXTRACPPFLAGS) `$(WXCONFIG) $(INCLUDEPREFIX) --cflags` -o $@ $< + +$(CTBUILDDIR)/ecscrolwin.o: $(CTDIR)/ecscrolwin.cpp $(CTDIR)/ecscrolwin.h + $(CC) $(CPPDEBUGOPTIONS) -c $(EXTRACPPFLAGS) `$(WXCONFIG) $(INCLUDEPREFIX) --cflags` -o $@ $< + +$(CTBUILDDIR)/filename.o: $(CTDIR)/filename.cpp $(CTDIR)/filename.h + $(CC) $(CPPDEBUGOPTIONS) -c $(EXTRACPPFLAGS) `$(WXCONFIG) $(INCLUDEPREFIX) --cflags` -o $@ $< + +$(CTBUILDDIR)/finddlg.o: $(CTDIR)/finddlg.cpp $(CTDIR)/finddlg.h + $(CC) $(CPPDEBUGOPTIONS) -c $(EXTRACPPFLAGS) `$(WXCONFIG) $(INCLUDEPREFIX) --cflags` -o $@ $< + +$(CTBUILDDIR)/folderdlg.o: $(CTDIR)/folderdlg.cpp $(CTDIR)/folderdlg.h + $(CC) $(CPPDEBUGOPTIONS) -c $(EXTRACPPFLAGS) `$(WXCONFIG) $(INCLUDEPREFIX) --cflags` -o $@ $< + +$(CTBUILDDIR)/htmlparser.o: $(CTDIR)/htmlparser.cpp $(CTDIR)/htmlparser.h + $(CC) $(CPPDEBUGOPTIONS) -c $(EXTRACPPFLAGS) `$(WXCONFIG) $(INCLUDEPREFIX) --cflags` -o $@ $< + +$(CTBUILDDIR)/licensedlg.o: $(CTDIR)/licensedlg.cpp $(CTDIR)/licensedlg.h + $(CC) $(CPPDEBUGOPTIONS) -c $(EXTRACPPFLAGS) `$(WXCONFIG) $(INCLUDEPREFIX) --cflags` -o $@ $< + +$(CTBUILDDIR)/mainwin.o: $(CTDIR)/mainwin.cpp $(CTDIR)/mainwin.h + $(CC) $(CPPDEBUGOPTIONS) -c $(EXTRACPPFLAGS) `$(WXCONFIG) $(INCLUDEPREFIX) --cflags` -o $@ $< + +$(CTBUILDDIR)/mltwin.o: $(CTDIR)/mltwin.cpp $(CTDIR)/mltwin.h + $(CC) $(CPPDEBUGOPTIONS) -c $(EXTRACPPFLAGS) `$(WXCONFIG) $(INCLUDEPREFIX) --cflags` -o $@ $< + +$(CTBUILDDIR)/msgdlgex.o: $(CTDIR)/msgdlgex.cpp $(CTDIR)/msgdlgex.h + $(CC) $(CPPDEBUGOPTIONS) -c $(EXTRACPPFLAGS) `$(WXCONFIG) $(INCLUDEPREFIX) --cflags` -o $@ $< + +$(CTBUILDDIR)/outputwin.o: $(CTDIR)/outputwin.cpp $(CTDIR)/outputwin.h + $(CC) $(CPPDEBUGOPTIONS) -c $(EXTRACPPFLAGS) `$(WXCONFIG) $(INCLUDEPREFIX) --cflags` -o $@ $< + +$(CTBUILDDIR)/packagesdlg.o: $(CTDIR)/packagesdlg.cpp $(CTDIR)/packagesdlg.h + $(CC) $(CPPDEBUGOPTIONS) -c $(EXTRACPPFLAGS) `$(WXCONFIG) $(INCLUDEPREFIX) --cflags` -o $@ $< + +$(CTBUILDDIR)/platformeditordlg.o: $(CTDIR)/platformeditordlg.cpp $(CTDIR)/platformeditordlg.h + $(CC) $(CPPDEBUGOPTIONS) -c $(EXTRACPPFLAGS) `$(WXCONFIG) $(INCLUDEPREFIX) --cflags` -o $@ $< + +$(CTBUILDDIR)/platformsdlg.o: $(CTDIR)/platformsdlg.cpp $(CTDIR)/platformsdlg.h + $(CC) $(CPPDEBUGOPTIONS) -c $(EXTRACPPFLAGS) `$(WXCONFIG) $(INCLUDEPREFIX) --cflags` -o $@ $< + +$(CTBUILDDIR)/propertywin.o: $(CTDIR)/propertywin.cpp $(CTDIR)/propertywin.h + $(CC) $(CPPDEBUGOPTIONS) -c $(EXTRACPPFLAGS) `$(WXCONFIG) $(INCLUDEPREFIX) --cflags` -o $@ $< + +$(CTBUILDDIR)/reposdlg.o: $(CTDIR)/reposdlg.cpp $(CTDIR)/reposdlg.h + $(CC) $(CPPDEBUGOPTIONS) -c $(EXTRACPPFLAGS) `$(WXCONFIG) $(INCLUDEPREFIX) --cflags` -o $@ $< + +$(CTBUILDDIR)/runtestsdlg.o: $(CTDIR)/runtestsdlg.cpp $(CTDIR)/runtestsdlg.h + $(CC) $(CPPDEBUGOPTIONS) -c $(EXTRACPPFLAGS) `$(WXCONFIG) $(INCLUDEPREFIX) --cflags` -o $@ $< + +$(CTBUILDDIR)/sectiondlg.o: $(CTDIR)/sectiondlg.cpp $(CTDIR)/sectiondlg.h + $(CC) $(CPPDEBUGOPTIONS) -c $(EXTRACPPFLAGS) `$(WXCONFIG) $(INCLUDEPREFIX) --cflags` -o $@ $< + +$(CTBUILDDIR)/settingsdlg.o: $(CTDIR)/settingsdlg.cpp $(CTDIR)/settingsdlg.h + $(CC) $(CPPDEBUGOPTIONS) -c $(EXTRACPPFLAGS) `$(WXCONFIG) $(INCLUDEPREFIX) --cflags` -o $@ $< + +$(CTBUILDDIR)/shortdescrwin.o: $(CTDIR)/shortdescrwin.cpp $(CTDIR)/shortdescrwin.h + $(CC) $(CPPDEBUGOPTIONS) -c $(EXTRACPPFLAGS) `$(WXCONFIG) $(INCLUDEPREFIX) --cflags` -o $@ $< + +$(CTBUILDDIR)/solutionswin.o: $(CTDIR)/solutionswin.cpp $(CTDIR)/solutionswin.h + $(CC) $(CPPDEBUGOPTIONS) -c $(EXTRACPPFLAGS) `$(WXCONFIG) $(INCLUDEPREFIX) --cflags` -o $@ $< + +$(CTBUILDDIR)/splittree.o: $(CTDIR)/splittree.cpp $(CTDIR)/splittree.h + $(CC) $(CPPDEBUGOPTIONS) -c $(EXTRACPPFLAGS) `$(WXCONFIG) $(INCLUDEPREFIX) --cflags` -o $@ $< + +$(CTBUILDDIR)/templatesdlg.o: $(CTDIR)/templatesdlg.cpp $(CTDIR)/templatesdlg.h + $(CC) $(CPPDEBUGOPTIONS) -c $(EXTRACPPFLAGS) `$(WXCONFIG) $(INCLUDEPREFIX) --cflags` -o $@ $< + + +### Common files + +$(CTBUILDDIR)/build.o: $(ECOSDIR)/host/tools/configtool/common/common/build.cxx $(ECOSDIR)/host/tools/configtool/common/common/build.hxx + $(CC) $(CPPDEBUGOPTIONS) -c $(EXTRACPPFLAGS) `$(WXCONFIG) $(INCLUDEPREFIX) --cflags` -o $@ $< + +$(CTBUILDDIR)/flags.o: $(ECOSDIR)/host/tools/configtool/common/common/flags.cxx $(ECOSDIR)/host/tools/configtool/common/common/flags.hxx + $(CC) $(CPPDEBUGOPTIONS) -c $(EXTRACPPFLAGS) `$(WXCONFIG) $(INCLUDEPREFIX) --cflags` -o $@ $< + +$(CTBUILDDIR)/Collections.o: $(ECOSDIR)/host/tools/Utils/common/Collections.cpp + $(CC) $(CPPDEBUGOPTIONS) -c $(EXTRACPPFLAGS) `$(WXCONFIG) $(INCLUDEPREFIX) --cflags` -o $@ $< + +$(CTBUILDDIR)/Properties.o: $(ECOSDIR)/host/tools/Utils/common/Properties.cpp + $(CC) $(CPPDEBUGOPTIONS) -c $(EXTRACPPFLAGS) `$(WXCONFIG) $(INCLUDEPREFIX) --cflags` -o $@ $< + +$(CTBUILDDIR)/Subprocess.o: $(ECOSDIR)/host/tools/Utils/common/Subprocess.cpp + $(CC) $(CPPDEBUGOPTIONS) -c $(EXTRACPPFLAGS) `$(WXCONFIG) $(INCLUDEPREFIX) --cflags` -o $@ $< + +$(CTBUILDDIR)/eCosSerial.o: $(ECOSDIR)/host/tools/Utils/common/eCosSerial.cpp + $(CC) $(CPPDEBUGOPTIONS) -c $(EXTRACPPFLAGS) `$(WXCONFIG) $(INCLUDEPREFIX) --cflags` -o $@ $< + +$(CTBUILDDIR)/eCosSocket.o: $(ECOSDIR)/host/tools/Utils/common/eCosSocket.cpp + $(CC) $(CPPDEBUGOPTIONS) -c $(EXTRACPPFLAGS) `$(WXCONFIG) $(INCLUDEPREFIX) --cflags` -o $@ $< + +$(CTBUILDDIR)/eCosStd.o: $(ECOSDIR)/host/tools/Utils/common/eCosStd.cpp + $(CC) $(CPPDEBUGOPTIONS) -c $(EXTRACPPFLAGS) `$(WXCONFIG) $(INCLUDEPREFIX) --cflags` -o $@ $< + +$(CTBUILDDIR)/eCosThreadUtils.o: $(ECOSDIR)/host/tools/Utils/common/eCosThreadUtils.cpp + $(CC) $(CPPDEBUGOPTIONS) -c $(EXTRACPPFLAGS) `$(WXCONFIG) $(INCLUDEPREFIX) --cflags` -o $@ $< + +$(CTBUILDDIR)/eCosTrace.o: $(ECOSDIR)/host/tools/Utils/common/eCosTrace.cpp + $(CC) $(CPPDEBUGOPTIONS) -c $(EXTRACPPFLAGS) `$(WXCONFIG) $(INCLUDEPREFIX) --cflags` -o $@ $< + +$(CTBUILDDIR)/eCosTest.o: $(ECOSDIR)/host/tools/ecostest/common/eCosTest.cpp + $(CC) $(CPPDEBUGOPTIONS) -c $(EXTRACPPFLAGS) `$(WXCONFIG) $(INCLUDEPREFIX) --cflags` -o $@ $< + +$(CTBUILDDIR)/eCosTestDownloadFilter.o: $(ECOSDIR)/host/tools/ecostest/common/eCosTestDownloadFilter.cpp + $(CC) $(CPPDEBUGOPTIONS) -c $(EXTRACPPFLAGS) `$(WXCONFIG) $(INCLUDEPREFIX) --cflags` -o $@ $< + +$(CTBUILDDIR)/eCosTestPlatform.o: $(ECOSDIR)/host/tools/ecostest/common/eCosTestPlatform.cpp + $(CC) $(CPPDEBUGOPTIONS) -c $(EXTRACPPFLAGS) `$(WXCONFIG) $(INCLUDEPREFIX) --cflags` -o $@ $< + +$(CTBUILDDIR)/eCosTestSerialFilter.o: $(ECOSDIR)/host/tools/ecostest/common/eCosTestSerialFilter.cpp + $(CC) $(CPPDEBUGOPTIONS) -c $(EXTRACPPFLAGS) `$(WXCONFIG) $(INCLUDEPREFIX) --cflags` -o $@ $< + +$(CTBUILDDIR)/eCosTestUtils.o: $(ECOSDIR)/host/tools/ecostest/common/eCosTestUtils.cpp + $(CC) $(CPPDEBUGOPTIONS) -c $(EXTRACPPFLAGS) `$(WXCONFIG) $(INCLUDEPREFIX) --cflags` -o $@ $< + +$(CTBUILDDIR)/ResetAttributes.o: $(ECOSDIR)/host/tools/ecostest/common/ResetAttributes.cpp + $(CC) $(CPPDEBUGOPTIONS) -c $(EXTRACPPFLAGS) `$(WXCONFIG) $(INCLUDEPREFIX) --cflags` -o $@ $< + +$(CTBUILDDIR)/TestResource.o: $(ECOSDIR)/host/tools/ecostest/common/TestResource.cpp + $(CC) $(CPPDEBUGOPTIONS) -c $(EXTRACPPFLAGS) `$(WXCONFIG) $(INCLUDEPREFIX) --cflags` -o $@ $< + + diff --git a/host/tools/configtool/standalone/wxwin/README.txt b/host/tools/configtool/standalone/wxwin/README.txt new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/README.txt @@ -0,0 +1,475 @@ +eCos Cross-platform Configuration Tool +Copyright (c) Red Hat Inc., 2001 +====================================== + +Version 2 +========= + +Contents + + * Introduction + * What's in this release? + * Installing the Configuration Tool + * Running the Configuration Tool + * Frequently Asked Questions + * Building the Configuration Tool under Linux + * Building the Configuration Tool under Windows + + +Introduction +============ + + Welcome to the eCos Configuration Tool, a graphical tool to + help a user configure and build a custom version of the + eCos operating system. + + This is a cross-platform version built using the wxWindows + toolkit. The tool uses the GTK+ widget set on Linux, and the + WIN32 API on Windows 9x, Windows NT and Windows 2000. It is + similar to the MFC, Windows-only version but at present lacks + a few of its features, such as the Memory Layout Tool and the + ability to run tests from within the tool. + + Please note that this is alpha-level code. However, all feedback to + the eCos team is appreciated, via ecos-discuss@sources.redhat.com or the + bug reporting form at http://sources.redhat.com/ecos/problemreport.html. + + These are the instructions for running and building the eCos + Configuration Tool for Linux and Windows. + + +What's in this release? +======================= + + This version allows you to edit, load, save and build eCos + configurations much as the original Windows Configuration Tool. + However the following features are missing with respect to the + original tool: + + - Memory Layout Tool + - Running tests from the tool + - Administration functionality (initial code present but untested) + - Gauge indicating time left to build library and tests + + The following features are present in the new tool but not in the + original tool: + + - Repository Information dialog (available from the Help menu) + - Most dialogs are resizeable + +Documentation works a little differently. Instead of using a +precompiled HTML Help file, this version compiles a documentation +index on the fly for use with its own internal HTML help viewer. The +cached indexes are placed in the .eCosDocs directory under the +user's home directory (Linux) or in the installed repository +(Windows). The internal viewer cannot cope with all of the eCos +and GNUPro documentation, so for these occasions please use an +external browser (see the Settings dialog). + +The documentation for the Configuration Tool is supplied in its +install directory as HTML only, and is a modified version of the +eCos User's Guide. Invoke the tool help from the +"Help|Configuration Tool Help" menu item, or from the internal +help viewer's index, under "Linux Configuration Tool Guide". + +Known bugs: + + - The documentation index only lists the packages in the + configuration active when the documentation was indexed + (normally when the repository is first seen by the + Configuration Tool). + + +Installing the Configuration Tool +================================= + + The Configuration Tool can be used with existing eCos + installations and CVS source hierarchies. You can get the + binaries from ftp://sources.redhat.com/pub/ecos/ct2/. + + See also mirror sites at: + + http://sources.redhat.com/ecos/mirror.html + http://sources.redhat.com/mirrors.html + + Please try to use a mirror site close to you, as it will be + faster. + + *** Under Linux: + + Download: + ftp://sources.redhat.com/pub/ecos/ct2/configtool-2.0-i386.tar.gz + (or similar name). + + Unarchive the tar file into a suitable directory and add the + directory to your path. You do not have to install it as root. + For example: + + % mkdir -p /opt/ecos/configtool/bin + % cd /opt/ecos/configtool/bin + % tar xvfz /cdrom/configtool-2.0.tar.gz + % export PATH=/opt/ecos/configtool/bin:$PATH + + The following files will be extracted to the installation directory: + + configtool + ecoslogo.png + rhlogo.png + about.htm + README.txt + license.txt + ecosplatforms.tar.gz + manual/ + + Optionally, untar the contents of ecosplatforms.tar.gz into your + home directory, where it will create a directory called + .eCosPlatforms. The information in these files isn't yet used + by the Configuration Tool, but will keep the tool from + generating some warnings. + + The executable is statically linked to the wxWindows library, + but does require the GTK+ 1.2, GDK 1.2 and Tcl 8.x libraries + to be installed. + + *** Under Windows: + + Download configtool-2.0-setup.exe (or similar name). + + Run the installer provided, preferably having installed eCos + for Windows on your PC previously so the tool can pick up the + relevant registry information added by the eCos installer. + A new eCos Configuration Tool group will be added to your + Start menu and a shortcut to the Configuration Tool will + appear on your desktop. + + +Running the Configuration Tool +============================== + + Run the configtool executable and (on Linux) ignore any + initial console messages, which may be suppressed by + unarchiving ecosplatforms.tar.gz as per the installation + instructions above. + + You can invoke the tool with zero, one, or two parameters. The + two parameters can be the location of the repository and/or + the location of a save file (extension .ecc). If no parameters + are passed, the tool will look in the current directory for a + save file and also (on Linux) in the /opt/ecos directory for a + suitable repository. Failing that, the tool will use the last + loaded repository or ask the user for a suitable location. + + For detailed information about the Configuration Tool, please + refer to the HTML manual which may be invoked from the Help + menu or by clicking on the "Linux Configuration Tool Guide" in + the internal help system's contents. This is similar to but + different from "The eCos Configuration Tool" section in the + eCos User Guide, which refers to the original Windows version + of the configuration tool (as opposed to the new + cross-platform Linux and Windows version). + + +Frequently Asked Questions +========================== + +Q: On Linux, invoking HTML documentation for a configuration item + doesn't seem to work. + +A: You need to have a .mailcap entry similar to the following: + + text/html; netscape -no-about-splash %s + + and in .mime.types: + + type=text/html \ + desc="HTML document" \ + exts="htm,html" + + Also, be aware that the browser can sometimes end up behind the + configuration tool so it may have run even if you think it didn't. + + +Q: On Linux, right-clicking in the configuration pane and choosing + 'What's This?' causes an information window to pop up and + then quickly disappear. + +A: If the window manager options are set to raise a window when it gains + the focus, the information window can get sent behind the + application window when the popup menu loses focus. Either + adjust your window manager settings, or use an alternate way + of invoking help for the item: click on the arrow/question + mark toolbar button, then on the item you are interested in. + + +Q: The internal HTML help viewer doesn't display HTML correctly. + +A: The internal HTML help viewer cannot display some of the more complex + HTML correctly, such as the GNUPro reference. We hope to + provide the documentation in a suitable form in future, but + for now, please use an external browser to view this + documentation. You can use the Settings dialog, Viewers tab, + to choose to view using an external browser. + + +Q: Why does the Configuration Tool use wxWindows? + +A: wxWindows is an open source, mature multi-platform GUI + toolkit for C++. It makes platform-independence relatively + easy to achieve, whilst remaining compatibility with the + look and feel of GTK+ and WIN32 on the respective platforms. + wxWindows was chosen on its own merits but, by sheer + coincidence, the author of the new Configuration Tool is + also the original author of wxWindows. Using a + platform-independent API will make it easier to port the + Configuration Tool to other platforms if needed. + + +Q: Where can I get more information about wxWindows? + +A: The wxWindows web site is at http://www.wxwindows.org. + wxWindows distributions come with documentation in a + variety of formats. + + +Q: Does the new Configuration Tool make the old one obsolete? + +A: Not yet. The new tool doesn't yet support some features, such + as the Memory Layout Tool and the Run Tests dialog. When + these have been implemented, and the tool has been subject + to the required quality assurance procedure, then we can + retire the old tool. + + +Q: How can I help improve the Configuration Tool? + +A: All help is very welcome: please see + http://sources.redhat.com/ecos/faq.html for how to + contribute. + + +Q: Who do I contact when things go wrong? + +A: Please discuss problems on the ecos-discuss mailing list: + see http://sources.redhat.com/ecos/intouch.html. + + +Q: The compiler fails to compile dcclient.cpp. What do I do? + +A: It may be that you have a non-standard GTK+ 1.2.6 which has changes + backported from 1.2.7. Use the makefile target 'wxgtkfix' to + fix this after the error has happened (i.e. after configure + has produced the setup.h and makefiles): + + % make -f $CONFIGTOOLDIR/Makefile WXDIR=$WXDIR ECOSDIR=$ECOSDIR LEVEL=release wxgtkfix + + or + + % make -f $CONFIGTOOLDIR/Makefile WXDIR=$WXDIR ECOSDIR=$ECOSDIR LEVEL=debug wxgtkfix + + Now use the 'wx ecc ct' targets (not 'full') to continue + building. + + +Building the Configuration Tool under Linux +=========================================== + +This build system is subject to change. + +You will need: + + o gcc 2.95.2 or later + + o GTK+ and glib 1.2.6 or above. Please remove any 1.3 development RPMs + from your setup, using for example: + + rpm -e gtk+-gtkbeta-devel-1.3.1b-2 + + You can get GTK+ and glib for Red Hat 6.2 and above from: + + ftp://ftp.gtk.org/pub/gtk/v1.2/binary/RPMS/RedHat-6.2/RPMS/i386/gtk+-1.2.8-1.i386.rpm + ftp://ftp.gtk.org/pub/gtk/v1.2/binary/RPMS/RedHat-6.2/RPMS/i386/glib-1.2.8-1.i386.rpm + + o a suitable version of wxWindows for GTK+, available from + from ftp://sources.redhat.com/pub/ecos/ct2/. + + Unarchive the file wxGTK-x.y.z.tgz into a suitable directory, e.g. + + % mkdir /home/julians/wxWindows + % cd /home/julians/wxWindows + % tar xvfz /tmp/wxGTK-x.y.z.tgz + + You may also wish to download and unarchive wxWindows + documentation, which is supplied in zip form. Unarchive + using e.g.: + + % cd /home/julians/wxWindows + % unzip -a wxWindows-x.y.z-HTML.zip + + o an eCos source hierarchy. See http://sources.redhat.com/ecos/anoncvs.html + for how to download this from the CVS repository. For example: + + cvs -d :pserver:anoncvs@sources.redhat.com:/cvs/ecos co ecos/host + + o other tools: + + - Tcl/Tk 8.2 or above. See http://dev.scriptics.com/ + +Summary: + + There is no 'configure' step for the eCos Configuration Tool + as a whole, although the host tool libraries and wxWindows + have configure scripts which are invoked by the makefile. + + You work in a build directory of your choosing, and the + makefile will create the following directories underneath it: + + ct-build-debug/ ; Configtool debug build + ecc-build-debug/ ; eCos libraries debug build + wxwin-build-debug/ ; wxWindows debug build + + ct-build-release/ ; Configtool release build + ecc-build-release/ ; eCos libraries release build + wxwin-build-release/ ; wxWindows release build + + You need to pass the wxWindows source directory (WXDIR) and + eCos hierarchy directory (ECOSDIR) to the makefile, along with + the build LEVEL (debug or release). Please see makect.sh in + the source directory, which is a useful helper script for + making it easier to invoke the makefile. + + You also supply a target to build, such as full (everything), + ct (just the Configuration Tool), wx (wxWindows only) or ecc + (eCos libraries only). It is important to supply the target as + the _last_ command(s) on the command line. + + The makefile builds and uses wxWindows as a static library, + which minimizes problems with shared libraries and still + results in a reasonable size of executable (4.5 MB + uncompressed, or under 2 MB when compressed with UPX). + Switching off unnecessary wxWindows features may result in + smaller executables. + + IMPORTANT NOTE: currently, there are inadequate dependencies + in the makefiles, so please make sure you start with a clean + directory before building (use the cleanct target if + necessary). + +Examples: + + 1. This builds the eCos libraries, wxWindows, and the Configuration Tool, + in debug mode. + + % export ECOSDIR=/home/julians/cvs/eCos # The dir above 'host' + % export CONFIGTOOLDIR=$ECOSDIR/host/tools/configtool/standalone/wxwin + % export WXDIR=/home/julians/wxWindows + % + % mkdir /tmp/ecos-build + % cd /tmp/ecos-build + % make -f $CONFIGTOOLDIR/Makefile WXDIR=$WXDIR ECOSDIR=$ECOSDIR LEVEL=debug full + + 2. This builds just the Configuration Tool, say after a file was edited, + in release mode. + + % export ECOSDIR=/home/julians/cvs/eCos + % export CONFIGTOOLDIR=$ECOSDIR/host/tools/configtool/standalone/wxwin + % export WXDIR=/home/julians/wxWindows + % + % cd /tmp/ecos-build + % make -f $CONFIGTOOLDIR/Makefile WXDIR=$WXDIR ECOSDIR=$ECOSDIR LEVEL=release ct + + *** Troubleshooting + + Please see the FAQ for what to do if the wxWindows file + dcclient.cpp fails to compile. + + +Building the Configuration Tool under Windows +============================================= + +You will need: + + o Microsoft Visual C++ 6.0 or later + + o a suitable version of wxWindows for MS Windows, available + from ftp://sources.redhat.com/pub/ecos/ct2/. To install the + sources in 'setup' form, just run the executable and follow + the instructions. If you have downloaded the sources in zip + format, you will need to unarchive the file wxMSW-x.y.z.zip + into a suitable directory, e.g. + + > mkdir c:\wxWindows + > c: + > cd \wxWindows + > unzip c:\temp\wxMSW-x.y.z.zip + + Alternatively, you can use WinZip or similar utility to + unarchive the files. + + Documentation in Windows HTML Help format is supplied in + the setup or zipped distribution and does not have to be + downloaded separately. + + o an eCos source hierarchy. See http://sources.redhat.com/ecos/anoncvs.html + for how to download this from the CVS repository. For example: + + cvs -d :pserver:anoncvs@sources.redhat.com:/cvs/ecos co ecos/host + + o other tools: + + - Cygwin (sometimes called GNUPro). See http://sources.redhat.com/cygwin/ + - Tcl/Tk 8.2 or above. See http://dev.scriptics.com/ + +Summary: + + There are two main steps: building wxWindows, and building the Configuration Tool. + The Configuration Tool project file also builds the required eCos libraries. + Note that unlike compilation under Linux, the wxWindows objects and libraries end up in + the wxWindows source tree. + + Before routinely building the Configuration Tool, you will need to set up + Visual C++ with the correct paths (see below). + +Steps: + + 1. Execute in a DOS box: + + subst v: d:\tmp + + where d:\tmp is a suitable temporary directory where the Configuration Tool + binaries and objects will end up. + + 2. Set the TCLHOME environment variable to where Tcl is installed. On Windows 9x, + edit autoexec.bat. On Windows NT or W2K, use the System control panel applet. + + 3. Build wxWindows. To do this, run VC++ and open src/msvc.dsw in the wxWindows + project hierarchy. Select Build | Batch Build and check + wxvc - WIN32 Debug and wxvc - WIN32 Release. Click on Build. + + 4. Open the eCos/ecc/host/tools/configtool/standalone/wxwin/ConfigtoolVC.dsw + workspace. Choose Tools | Options and click on the Directories tab. + Select Show directories for: Include files. + + You need to add paths such as these: + + c:\Program Files\Tcl\include + d:\wxWindows-010212\include + + Select Show directories for: Library files. Add these paths, changing + as necessary: + + c:\Program Files\Tcl\lib + d:\wxWindows-010212\lib + + 5. Click on Select Active Configuration... and select the one you wish to + build, such as WIN32 Ansi Debug (note that Unicode configurations are + not yet available). Choose Build | Rebuild All to build the project. + The configtool.exe executable should end up in v:\Configtool\AnsiDebug. + +When compiled, configtool.exe depends on the following DLLs found +in your system32 directory that should be supplied with the executable: + + TCL82.DLL (or other name if you used a different version of TCL) + MSVCIRT.DLL + MSVCP60.DLL + MSVCRT.DLL + diff --git a/host/tools/configtool/standalone/wxwin/about.htm b/host/tools/configtool/standalone/wxwin/about.htm new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/about.htm @@ -0,0 +1,95 @@ + + + + + + + + + + + + + + +
+ + + + + + + +
+ + +
+ + eCos Configuration Tool Version $VERSION$
+ $DATE$
+ Copyright (c) 1998-2001
+ Red Hat, Inc. +
+
+
+ +
+ + + + + + + + + + + + + +
+ The eCos engineering team is: +
+ +

+Paul Beskeen
+John Dallaway
+Robert Erksine
+Simon FitzMaurice
+Mark Galassi
+Nick Garnett
+Tim Goodwin
+Stu Grossman
+Eugene Kulesha
+Jonathan Larmour
+David Moore
+Drew Moseley
+

+
+
+ + + +

+Daniel Neades
+Gary Oliverio
+Chris Provenzano
+Mark Salter
+Rob Savoye
+Alex Schuilenburg
+Jesper Skov
+Julian Smart
+Chris Tarpy
+Gary Thomas
+Hugo Tyson
+Bart Veer +

+
+
+
+ +
+ + + + diff --git a/host/tools/configtool/standalone/wxwin/aboutdlg.cpp b/host/tools/configtool/standalone/wxwin/aboutdlg.cpp new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/aboutdlg.cpp @@ -0,0 +1,158 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +// appsettings.cpp : +// +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): julians +// Contact(s): julians +// Date: 2000/09/11 +// Version: $Id: aboutdlg.cpp,v 1.10 2001/05/22 14:31:40 julians Exp $ +// Purpose: +// Description: Implementation file for ecAboutDialog +// Requires: +// Provides: +// See also: +// Known bugs: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== + +#ifdef __GNUG__ + #pragma implementation "aboutdlg.cpp" +#endif + +#include "ecpch.h" + +#include "wx/wxhtml.h" +#include "wx/datetime.h" +#include "wx/file.h" + +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + +#include "aboutdlg.h" +#include "configtool.h" +#include "symbols.h" + +//---------------------------------------------------------------------------- +// ecAboutDialog +//---------------------------------------------------------------------------- + +// WDR: event table for ecAboutDialog + +BEGIN_EVENT_TABLE(ecAboutDialog,wxDialog) +END_EVENT_TABLE() + +ecAboutDialog::ecAboutDialog( wxWindow *parent, wxWindowID id, const wxString &title, + const wxPoint &position, const wxSize& size, long style ) : + wxDialog( parent, id, title, position, size, style ) +{ + AddControls(this); + + Centre(wxBOTH); +} + +bool ecAboutDialog::AddControls(wxWindow* parent) +{ + wxSetWorkingDirectory(wxGetApp().GetAppDir()); + wxString htmlFile(wxGetApp().GetFullAppPath(wxT("about.htm"))); + + wxString htmlText; + if (wxFileExists(htmlFile)) + { + wxFile file; + file.Open(htmlFile, wxFile::read); + long len = file.Length(); + char* buf = htmlText.GetWriteBuf(len + 1); + file.Read(buf, len); + buf[len] = 0; + htmlText.UngetWriteBuf(); + } + else + { + htmlText.Printf(wxT("Warning

Sorry, could not find file for About dialog, %s

"), (const wxChar*) htmlFile); + } + + // Customize the HTML + htmlText.Replace(wxT("$VERSION$"), ecCONFIGURATION_TOOL_VERSION_STRING); + htmlText.Replace(wxT("$DATE$"), __DATE__); + + wxSize htmlSize(420, 390); + + // Note: in later versions of wxWin this will be fixed so wxRAISED_BORDER + // does the right thing. Meanwhile, this is a workaround. +#ifdef __WXMSW__ + long borderStyle = wxDOUBLE_BORDER; +#else + long borderStyle = wxRAISED_BORDER; +#endif + + wxHtmlWindow* html = new wxHtmlWindow(this, ecID_ABOUT_DIALOG_HTML_WINDOW, wxDefaultPosition, htmlSize, borderStyle); + html -> SetBorders(0); + html -> SetPage(htmlText); + + //// Start of sizer-based control creation + + wxSizer *item0 = new wxBoxSizer( wxVERTICAL ); + + wxWindow *item1 = parent->FindWindow( ecID_ABOUT_DIALOG_HTML_WINDOW ); + wxASSERT( item1 ); + item0->Add( item1, 0, wxALIGN_CENTRE|wxALL, 5 ); + + wxButton *item2 = new wxButton( parent, wxID_CANCEL, "&OK", wxDefaultPosition, wxDefaultSize, 0 ); + item2->SetDefault(); + + item0->Add( item2, 0, wxALIGN_RIGHT|wxALL, 10 ); + + parent->SetAutoLayout( TRUE ); + parent->SetSizer( item0 ); + parent->Layout(); + item0->Fit( parent ); + item0->SetSizeHints( parent ); + return TRUE; +} + +/* + * ecSplashScreen. + */ + + +ecSplashScreen::ecSplashScreen(const wxBitmap& bitmap, long splashStyle, int milliseconds, wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style): + wxSplashScreen(bitmap, splashStyle, milliseconds, parent, id, pos, size, style) +{ +} + +ecSplashScreen::~ecSplashScreen() +{ + wxGetApp().m_splashScreen = NULL; +} + + + diff --git a/host/tools/configtool/standalone/wxwin/aboutdlg.h b/host/tools/configtool/standalone/wxwin/aboutdlg.h new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/aboutdlg.h @@ -0,0 +1,91 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +// appsettings.cpp : +// +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): julians +// Contact(s): julians +// Date: 2000/09/11 +// Version: $Id: aboutdlg.h,v 1.2 2001/03/05 15:53:32 julians Exp $ +// Purpose: +// Description: Header file for ecAboutDialog +// Requires: +// Provides: +// See also: +// Known bugs: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== + +#ifndef _ECOS_ABOUTDLG_H_ +#define _ECOS_ABOUTDLG_H_ + +#ifdef __GNUG__ + #pragma interface "aboutdlg.cpp" +#endif + +#include "wx/splash.h" + +//---------------------------------------------------------------------------- +// ecAboutDialog +//---------------------------------------------------------------------------- + +class ecAboutDialog: public wxDialog +{ +public: + // constructors and destructors + ecAboutDialog( wxWindow *parent, wxWindowID id, const wxString &title, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = wxDEFAULT_DIALOG_STYLE ); + + bool AddControls(wxWindow* parent); + +private: + DECLARE_EVENT_TABLE() +}; + +/* + * ecSplashScreen. We have to derive from wxSplashScreen so we can tell + * when the window has been destroyed (so we don't risk destroying a window + * that's already been destroyed) + */ + +class WXDLLEXPORT ecSplashScreen: public wxSplashScreen +{ +public: + ecSplashScreen(const wxBitmap& bitmap, long splashStyle, int milliseconds, wxWindow* parent, wxWindowID id, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxSIMPLE_BORDER|wxFRAME_FLOAT_ON_PARENT); + ~ecSplashScreen(); + +protected: +}; + + +#endif + // _ECOS_ABOUTDLG_H_ diff --git a/host/tools/configtool/standalone/wxwin/admindlg.cpp b/host/tools/configtool/standalone/wxwin/admindlg.cpp new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/admindlg.cpp @@ -0,0 +1,562 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +// admindlg.cpp : +// +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): julians +// Contact(s): julians +// Date: 2000/09/28 +// Version: $Id: admindlg.cpp,v 1.4 2001/03/23 13:38:04 julians Exp $ +// Purpose: +// Description: Implementation file for ecAdminDialog +// Requires: +// Provides: +// See also: +// Known bugs: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== + +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- +#ifdef __GNUG__ +#pragma implementation "admindlg.h" +#endif + +// Includes other headers for precompiled compilation +#include "ecpch.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +// For registry access functions in GetUserToolsPath +#ifdef __WXMSW__ +#include +#include "wx/msw/winundef.h" +#endif + +#include "wx/cshelp.h" +#include "wx/filedlg.h" +#include "wx/file.h" +#include "wx/filefn.h" +#include "wx/progdlg.h" + +#include "configtool.h" +#include "admindlg.h" +#include "configtooldoc.h" +#include "licensedlg.h" +#include "ecutils.h" + +#ifdef __WXGTK__ +#include "bitmaps/package_open.xpm" +#include "bitmaps/package_version.xpm" +#endif + +BEGIN_EVENT_TABLE(ecAdminDialog, ecDialog) + EVT_BUTTON(wxID_OK, ecAdminDialog::OnClose) + EVT_BUTTON(ecID_ADMIN_DIALOG_ADD, ecAdminDialog::OnAdd) + EVT_BUTTON(ecID_ADMIN_DIALOG_REMOVE, ecAdminDialog::OnRemove) + EVT_INIT_DIALOG(ecAdminDialog::OnInitDialog) +END_EVENT_TABLE() + +// ---------------------------------------------------------------------------- +// main frame +// ---------------------------------------------------------------------------- + +// Frame constructor +ecAdminDialog::ecAdminDialog(wxWindow* parent, const wxString& repository, const wxString& userTools): + m_imageList(16, 16, 1) +{ + m_strRepository = repository; + m_strUserTools = userTools; + m_CdlPkgData = NULL; + + SetExtraStyle(wxDIALOG_EX_CONTEXTHELP); + + ecDialog::Create(parent, ecID_ADMIN_DIALOG, _("Administration"), + wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER); + + CreateControls(this); + + m_imageList.Add(wxICON(package_open)); + m_imageList.Add(wxICON(package_version)); + m_treeCtrl->SetImageList(& m_imageList); + + Centre(wxBOTH); +} + +ecAdminDialog::~ecAdminDialog() +{ + ClearPackageTree (); + + // free memory allocated to the CDL database + + if (m_CdlPkgData) + delete m_CdlPkgData; + + m_treeCtrl->SetImageList(NULL); +} + +void ecAdminDialog::OnInitDialog(wxInitDialogEvent& event) +{ + // setup the path to the user tools (tar and gunzip) + + if ((! m_strUserTools.IsEmpty()) || FindUserToolsPath ()) // if the user tools can be located + { + wxString path; + wxGetEnv(wxT("PATH"), & path); + + // TODO: this may not work on all platforms + path = path + wxString(wxPATH_SEP) + m_strUserTools; + wxSetEnv(wxT("PATH"), path); + } + + // populate the package tree + + if (!PopulatePackageTree (m_strRepository)) + { + m_strRepository = wxT(""); + // TODO + // OnPkgadminRepository (); // prompt the user for the repository location + } +} + +void ecAdminDialog::CreateControls(wxWindow* parent) +{ + m_treeCtrl = new wxTreeCtrl(parent, ecID_ADMIN_DIALOG_TREE, + wxDefaultPosition, wxSize(380, 290), wxTR_HAS_BUTTONS | wxSUNKEN_BORDER); + + wxSizer *item0 = new wxBoxSizer( wxHORIZONTAL ); + + wxSizer *item1 = new wxBoxSizer( wxVERTICAL ); + + wxStaticText *item2 = new wxStaticText( parent, wxID_STATIC, _("&Installed packages:"), wxDefaultPosition, wxDefaultSize, 0 ); + item1->Add( item2, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + wxWindow *item3 = parent->FindWindow( ecID_ADMIN_DIALOG_TREE ); + wxASSERT( item3 ); + item1->Add( item3, 1, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + item0->Add( item1, 1, wxGROW|wxALIGN_CENTER_HORIZONTAL|wxALL, 5 ); + + wxSizer *item4 = new wxBoxSizer( wxVERTICAL ); + + wxButton *item5 = new wxButton( parent, ecID_ADMIN_DIALOG_ADD, _("&Add..."), wxDefaultPosition, wxDefaultSize, 0 ); + item4->Add( item5, 0, wxALIGN_CENTRE|wxALL, 5 ); + + wxButton *item6 = new wxButton( parent, ecID_ADMIN_DIALOG_REMOVE, _("&Remove"), wxDefaultPosition, wxDefaultSize, 0 ); + item4->Add( item6, 0, wxALIGN_CENTRE|wxALL, 5 ); + + item4->Add( 20, 20, 1, wxALIGN_CENTRE|wxALL, 5 ); + + wxButton *item7 = new wxButton( parent, wxID_OK, _("&Close"), wxDefaultPosition, wxDefaultSize, 0 ); + item4->Add( item7, 0, wxALIGN_CENTRE|wxALL, 5 ); + +#ifdef __WXGTK__ + wxButton *contextButton = new wxContextHelpButton( parent ); + item4->Add( contextButton, 0, wxALIGN_CENTRE|wxALL, 5 ); +#endif + + item0->Add( item4, 0, wxGROW|wxALIGN_CENTER_HORIZONTAL|wxRIGHT|wxTOP|wxBOTTOM, 5 ); + + item7->SetDefault(); // Make Close the default button + + parent->SetAutoLayout( TRUE ); + parent->SetSizer( item0 ); + parent->Layout(); + item0->Fit( parent ); + //item0->SetSizeHints( parent ); + + // Add context-sensitive help text + parent->FindWindow( ecID_ADMIN_DIALOG_TREE)->SetHelpText(_("Displays the set of packages currently in the eCos component repository.")); + parent->FindWindow( ecID_ADMIN_DIALOG_ADD)->SetHelpText(_("Adds the contents of an eCos package file to the eCos component repository.")); + parent->FindWindow( ecID_ADMIN_DIALOG_REMOVE)->SetHelpText(_("Removes the currently selected package from the eCos component repository.")); + parent->FindWindow( wxID_OK )->SetHelpText(_("Closes the dialog and saves any changes you have made.")); + +#if __WXGTK__ + parent->FindWindow( wxID_CONTEXT_HELP )->SetHelpText(_("Invokes context-sensitive help for the clicked-on window.")); +#endif + +} + +void ecAdminDialog::OnAdd(wxCommandEvent& event) +{ + wxString defaultDir; // TODO + wxString defaultFile; + wxString wildcard = wxT("eCos Package Files (*.epk)|*.epk"); + wxFileDialog dlg(this, _("Open eCos Package Files"), defaultDir, defaultFile, wildcard, wxOPEN|wxMULTIPLE); + + if (wxID_OK == dlg.ShowModal ()) + { + bool bRepositoryChanged = FALSE; + //POSITION posPathName = dlg.GetStartPosition (); + wxArrayString filenames; + dlg.GetFilenames(filenames); + size_t i; + for (i = (size_t) 0; i < filenames.GetCount(); i++) + { + wxString strPathName(filenames[i]); + + if (!wxFileExists(strPathName)) + { + wxString msg; + msg.Printf(_("Cannot open %s"), (const wxChar*) strPathName); + wxMessageBox(msg, wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxOK); + } + else + { + + // get an eCos package distribution file + + // extract the licence file + + wxString strCommand; + strCommand.Printf(wxT("add %s --extract_license"), (const wxChar*) strPathName); + strCommand.Replace(wxT("\\"), wxT("/")); // backslashes -> forward slashes for Tcl_EvalFile + EvalTclFile (3, strCommand); + + wxString strLicenseFile = m_strRepository + wxString(wxFILE_SEP_PATH) + wxT("pkgadd.txt"); +#ifdef __WXMSW__ + strLicenseFile.Replace (wxT("/"), wxT("\\")); // forward slashes -> backslashes for Win32 +#endif + // read the license file + + wxFile fileLicenseFile; + if (fileLicenseFile.Open (strLicenseFile, wxFile::read)) + { + //TRACE (_T("License file found at %s\n"), strLicenseFile); + const off_t dwLicenseLength = fileLicenseFile.Length (); + char* pszBuffer = new char [dwLicenseLength + 1]; // allocate a buffer + fileLicenseFile.Read ((void*) pszBuffer, dwLicenseLength); + fileLicenseFile.Close (); + wxRemoveFile (strLicenseFile); // delete the license file when read + pszBuffer [dwLicenseLength] = 0; // terminate the string in the buffer + wxString strLicenseText (pszBuffer); // copy into a wxString to convert to Unicode + delete [] pszBuffer; +#ifdef __WXMSW__ + if (-1 == strLicenseText.Find (wxT("\r\n"))) // if the file has LF line endings... + strLicenseText.Replace (_T("\n"), _T("\r\n")); // ... replace with CRLF line endings +#endif + // display the license text + + ecLicenseDialog dlgLicense (strLicenseText, this, ecID_LICENSE_DIALOG, strPathName + _(" - Add Packages")); + if (wxID_OK != dlgLicense.ShowModal ()) // if license not accepted by user + continue; // try the next file + } + + // add the contents of the package distribution file + + strCommand.Printf (wxT("add %s --accept_license"), (const wxChar*) strPathName); + strCommand.Replace (wxT("\\"), wxT("/")); // backslashes -> forward slashes for Tcl_EvalFile + if (! EvalTclFile (3, strCommand)) // if not successful + { + // try the next file + } + else + { + bRepositoryChanged = TRUE; + } + } + } + + // refresh the package tree only if necessary + + if (bRepositoryChanged && ! PopulatePackageTree (m_strRepository)) + { + } + } +} + +void ecAdminDialog::OnRemove(wxCommandEvent& event) +{ + wxTreeCtrl* treeCtrl = (wxTreeCtrl*) FindWindow( ecID_ADMIN_DIALOG_TREE) ; + + const wxTreeItemId hTreeItem = treeCtrl->GetSelection (); + if (! hTreeItem || !hTreeItem.IsOk()) + return; + + if (wxYES != wxMessageBox (_("The selected package will be deleted from the repository. Core eCos packages may be restored only by reinstalling eCos.\n\nDo you wish to continue?"), + _("Remove Package"), wxYES_NO | wxICON_EXCLAMATION)) + return; + + ecAdminItemData* data = (ecAdminItemData*) treeCtrl->GetItemData (hTreeItem); + + if (data) // if a package node is selected + { + // remove all package version nodes + + wxString pstrPackage(data->m_string); + + bool bStatus = TRUE; + long cookie; + wxTreeItemId hChildItem = treeCtrl->GetFirstChild (hTreeItem, cookie); + while (hChildItem && bStatus) + { + const wxTreeItemId hNextChildItem = treeCtrl->GetNextSibling (hChildItem); + bStatus = RemovePackageVersion (hChildItem); + hChildItem = hNextChildItem; + } + + // remove the package node + + if (bStatus) + { + treeCtrl->Delete (hTreeItem); + } + } + else // a version node is selected + { + // remove the version node + + const wxTreeItemId hParentItem = treeCtrl->GetParent (hTreeItem); + wxASSERT (hParentItem && hParentItem.IsOk() ); + if (RemovePackageVersion (hTreeItem) && ! treeCtrl->ItemHasChildren (hParentItem)) // if the only version was deleted + { + // remove the package node + + treeCtrl->Delete (hParentItem); + } + } +} + +void ecAdminDialog::OnClose(wxCommandEvent& event) +{ + event.Skip(); +} + +bool ecAdminDialog::FindUserToolsPath() +{ +#ifdef __WXMSW__ + HKEY hKey; + if (ERROR_SUCCESS != RegOpenKeyEx (HKEY_CURRENT_USER, _T("Software\\Red Hat\\eCos\\Configuration Tool\\User Tools"), 0, KEY_READ, &hKey)) + return FALSE; + + TCHAR szBuffer [MAX_PATH + 1]; + DWORD dwBufferLength = MAX_PATH + 1; + LONG lStatus = RegQueryValueEx (hKey, _T("Folder"), NULL, NULL, (LPBYTE) szBuffer, &dwBufferLength); + RegCloseKey (hKey); + if (ERROR_SUCCESS != lStatus) + return FALSE; + + m_strUserTools = szBuffer; + // TRACE (_T("User tools found at %s\n"), m_strUserTools); + return ! m_strUserTools.IsEmpty (); +#else + // wxMessageBox("Sorry, ecAdminDialog::FindUserToolsPath not implemented for this platform."); + return FALSE; +#endif +} + +bool ecAdminDialog::RemovePackageVersion (wxTreeItemId hTreeItem) +{ + wxTreeCtrl* treeCtrl = (wxTreeCtrl*) FindWindow( ecID_ADMIN_DIALOG_TREE) ; + + const wxTreeItemId hParentItem = treeCtrl->GetParent (hTreeItem); + wxASSERT (hParentItem); + + ecAdminItemData* data = (ecAdminItemData*) treeCtrl->GetItemData (hParentItem); + + wxASSERT( data ); + + if (!data) + return FALSE; + + wxString pstrPackage = data->m_string ; + + wxString strCommand; + wxString itemText(treeCtrl->GetItemText (hTreeItem)); + strCommand.Printf (wxT("remove %s --version %s"), (const wxChar*) pstrPackage, (const wxChar*) itemText); + if (! EvalTclFile (3, strCommand)) // if not successful + return false; + + treeCtrl->Delete (hTreeItem); // remove the selected item from the tree + + return TRUE; +} + +void ecAdminDialog::ClearPackageTree () +{ + wxTreeCtrl* treeCtrl = (wxTreeCtrl*) FindWindow( ecID_ADMIN_DIALOG_TREE) ; + + wxTreeItemId hPackage = treeCtrl->GetRootItem (); + if (! hPackage.IsOk()) // if no packages in the tree... + return; // ...nothing to do + + while (hPackage.IsOk()) + { + const wxTreeItemId hNextPackage = treeCtrl->GetNextSibling(hPackage); + treeCtrl->Delete (hPackage); + hPackage = hNextPackage; + } +} + +// Trivial handlers; otherwise CdlPackagesDatabaseBody::make asserts. +static void CdlErrorHandler (std::string message) +{ +}; + +static void CdlWarningHandler (std::string message) +{ +}; + + +bool ecAdminDialog::PopulatePackageTree (const wxString& packageDatabase) +{ + wxTreeCtrl* treeCtrl = (wxTreeCtrl*) FindWindow( ecID_ADMIN_DIALOG_TREE) ; + + // delete any existing CDL database + + if (m_CdlPkgData) + { + delete m_CdlPkgData; + m_CdlPkgData = NULL; + } + + // load the package database + + try + { + // Cdl asserts unless the handlers are present. + m_CdlPkgData = CdlPackagesDatabaseBody::make (ecUtils::UnicodeToStdStr (packageDatabase), &CdlErrorHandler, &CdlWarningHandler); + } + catch (CdlStringException exception) + { + wxString strMessage; + strMessage.Printf (_("Error loading database:\n\n%s"), (const wxChar*) wxString (exception.get_message ().c_str ())); + wxMessageBox(strMessage, wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxOK); + return FALSE; + } + catch (...) + { + wxMessageBox(_("Error loading database"), (const wxChar*) wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxOK); + return FALSE; + } + + // clear the old package tree + + ClearPackageTree (); + + // Add a root item + wxTreeItemId rootId = m_treeCtrl->AddRoot(_("Packages"), 0, -1); + + // populate the new package tree + + const std::vector& packages = m_CdlPkgData->get_packages (); + for (std::vector::const_iterator package = packages.begin (); package != packages.end (); package++) + { + // add a package node + + wxTreeItemId hPackage = treeCtrl->AppendItem (treeCtrl->GetRootItem(), wxString (m_CdlPkgData->get_package_aliases (*package) [0].c_str ())); + treeCtrl->SetItemData (hPackage, new ecAdminItemData(wxString (package->c_str ()))); + treeCtrl->SetItemImage (hPackage, 0, wxTreeItemIcon_Normal); + treeCtrl->SetItemImage (hPackage, 0, wxTreeItemIcon_Selected); + treeCtrl->SetItemImage (hPackage, 0, wxTreeItemIcon_Expanded); + treeCtrl->SetItemImage (hPackage, 0, wxTreeItemIcon_SelectedExpanded); + + const std::vector& versions = m_CdlPkgData->get_package_versions (* package); + for (std::vector::const_iterator version = versions.begin (); version != versions.end (); version++) + { + // add a version node + const wxTreeItemId hVersion = treeCtrl->AppendItem ( hPackage, wxString (version->c_str ())); + treeCtrl->SetItemImage (hVersion, 1, wxTreeItemIcon_Normal); + treeCtrl->SetItemImage (hVersion, 1, wxTreeItemIcon_Selected); + treeCtrl->SetItemImage (hVersion, 1, wxTreeItemIcon_Expanded); + treeCtrl->SetItemImage (hVersion, 1, wxTreeItemIcon_SelectedExpanded); + } + treeCtrl->SortChildren (hPackage); // sort the version nodes + } + + treeCtrl->SortChildren (treeCtrl->GetRootItem()); // sort the package nodes + treeCtrl->Expand(treeCtrl->GetRootItem()); + + return TRUE; +} + + +bool ecAdminDialog::EvalTclFile(int nargc, const wxString& Argv) +{ + wxProgressDialog dlgWait(_("Adding Package"), _("Please wait..."), 100, this); + + dlgWait.Update(50); + +//TRACE (_T("Evaluating ecosadmin.tcl %s\n"), pszArgv); + + // set up the data structure which is passed to the Tcl thread + + wxString strArgc; + strArgc.Printf (wxT("%d"), nargc); + std::string argv0 = ecUtils::UnicodeToStdStr (m_strRepository) + "/ecosadmin.tcl"; + std::string argv = ecUtils::UnicodeToStdStr (Argv); + std::string argc = ecUtils::UnicodeToStdStr (strArgc); + + Tcl_Interp * interp = Tcl_CreateInterp (); + +#ifdef __WXMSW__ + Tcl_Channel outchan = Tcl_OpenFileChannel (interp, "nul", "a+", 777); + Tcl_SetStdChannel (outchan, TCL_STDOUT); // direct standard output to NUL: +#endif + + char * pszStatus = Tcl_SetVar (interp, "argv0", (char*) argv0.c_str(), 0); + pszStatus = Tcl_SetVar (interp, "argv", (char*) argv.c_str(), 0); + pszStatus = Tcl_SetVar (interp, "argc", (char*) argc.c_str(), 0); + pszStatus = Tcl_SetVar (interp, "gui_mode", "1", 0); // return errors in result string + int nStatus = Tcl_EvalFile (interp, (char*) argv0.c_str()); + char* result = Tcl_GetStringResult (interp); + +#ifdef __WXMSW__ + Tcl_SetStdChannel (NULL, TCL_STDOUT); + Tcl_UnregisterChannel (interp, outchan); +#endif + + Tcl_DeleteInterp (interp); + + wxString strErrorMessage (result); + + // report any error + if (! strErrorMessage.IsEmpty ()) + { + wxString msg (_("Command execution error:\n\n") + strErrorMessage); + wxMessageBox(msg, wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxOK); + return FALSE; + } + else if (TCL_OK != nStatus) + { + wxString msg (_("Command execution error")); + wxMessageBox(msg, wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxOK); + return FALSE; + } + + return TRUE; +} diff --git a/host/tools/configtool/standalone/wxwin/admindlg.h b/host/tools/configtool/standalone/wxwin/admindlg.h new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/admindlg.h @@ -0,0 +1,104 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +// admindlg.h : +// +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): julians +// Contact(s): julians +// Date: 2000/09/28 +// Version: $Id: admindlg.h,v 1.2 2001/03/23 13:38:04 julians Exp $ +// Purpose: +// Description: Header file for ecAdminDialog +// Requires: +// Provides: +// See also: +// Known bugs: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== + +#ifndef _ECOS_ADMINDLG_H_ +#define _ECOS_ADMINDLG_H_ + +#ifdef __GNUG__ +#pragma interface "admindlg.cpp" +#endif + +#include "ecutils.h" + +class ecAdminDialog : public ecDialog +{ +public: +// Ctor(s) + ecAdminDialog(wxWindow* parent, const wxString& repository = wxEmptyString, const wxString& userTools = wxEmptyString); + ~ecAdminDialog(); + +//// Event handlers + + void OnClose(wxCommandEvent& event); + void OnAdd(wxCommandEvent& event); + void OnRemove(wxCommandEvent& event); + void OnInitDialog(wxInitDialogEvent& event); + +//// Operations + void CreateControls(wxWindow* parent); + bool FindUserToolsPath(); + bool RemovePackageVersion (wxTreeItemId hTreeItem); + bool EvalTclFile (int nargc, const wxString& argv); + void ClearPackageTree (); + bool PopulatePackageTree (const wxString& packageDatabase); + +protected: + wxTreeCtrl* m_treeCtrl; + wxImageList m_imageList; + +private: + DECLARE_EVENT_TABLE() + + wxString m_strRepository; + wxString m_strUserTools; + CdlPackagesDatabase m_CdlPkgData; +}; + +// Data to associate with each item +class ecAdminItemData : public wxTreeItemData +{ +public: + ecAdminItemData(const wxString& str) : m_string(str) { } + + wxString m_string; +}; + + +#define ecID_ADMIN_DIALOG_TREE 10400 +#define ecID_ADMIN_DIALOG_ADD 10064 +#define ecID_ADMIN_DIALOG_REMOVE 10065 + +#endif + // _ECOS_ADMINDLG_H_ diff --git a/host/tools/configtool/standalone/wxwin/appsettings.cpp b/host/tools/configtool/standalone/wxwin/appsettings.cpp new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/appsettings.cpp @@ -0,0 +1,844 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +// appsettings.cpp : +// +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): julians +// Contact(s): julians +// Date: 2000/08/29 +// Version: $Id: appsettings.cpp,v 1.21 2001/05/30 12:37:24 julians Exp $ +// Purpose: +// Description: Implementation file for the ecSettings +// Requires: +// Provides: +// See also: +// Known bugs: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== + +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- +#ifdef __GNUG__ +#pragma implementation "appsettings.h" +#endif + +// Includes other headers for precompiled compilation +#include "ecpch.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#include "wx/config.h" +#include "wx/file.h" + +#include "appsettings.h" +#include "configtree.h" +#include "outputwin.h" +#include "shortdescrwin.h" +#include "mainwin.h" + +// For SystemInfo +#ifdef __WXMSW__ +#include +#include "wx/msw/winundef.h" +#ifdef GetTempPath +#undef GetTempPath +#endif +#endif + +/* +* User-changeable and other settings to be saved between sessions +*/ + +IMPLEMENT_DYNAMIC_CLASS(ecSettings, wxObject) + +ecSettings::ecSettings() +{ + m_showToolBar = TRUE; + m_frameSize = wxRect(0, 0, 600, 500); + m_appName = _("eCos Configuration Tool"); + m_showSplashScreen = FALSE; + m_userName = wxEmptyString; + m_serialNumber = 0; + m_frameStatus = ecSHOW_STATUS_NORMAL; + + m_treeSashSize = wxSize(400, 1000); + m_conflictsSashSize = wxSize(1000, 80); + m_propertiesSashSize = wxSize(1000, 80); + m_shortDescrSashSize = wxSize(1000, 80); + m_memorySashSize = wxSize(1000, 50); + m_outputSashSize = wxSize(1000, 50); + + m_showConflictsWindow = FALSE; + m_showPropertiesWindow = TRUE; + m_showShortDescrWindow = TRUE; + m_showMemoryWindow = FALSE; + m_showOutputWindow = TRUE; + + m_showMacroNames = FALSE; + + m_bUseCustomViewer = FALSE; + m_bUseExternalBrowser = FALSE; + m_eUseCustomBrowser = ecAssociatedExternal; + m_bHex = FALSE; + m_nRuleChecking = Immediate|Deferred|SuggestFixes ; + +#ifdef __WXMSW__ + m_strViewer = wxT("notepad"); +#endif + + // Find dialog settings + m_findText = wxEmptyString; + m_findMatchWholeWord = FALSE; + m_findMatchCase = FALSE; + m_findDirection = TRUE; // Down is TRUE, Up is FALSE + m_findSearchWhat = _("Macro names"); // Macro names, item names etc. + m_findDialogPos = wxPoint(-1, -1); +} + +// Copy constructor +ecSettings::ecSettings(const ecSettings& settings) +{ + Copy(settings); +} + +void ecSettings::Copy(const ecSettings& settings) +{ + m_showToolBar = settings.m_showToolBar; + m_frameSize = settings.m_frameSize; + m_showSplashScreen = settings.m_showSplashScreen; + m_userName = settings.m_userName; + m_serialNumber = settings.m_serialNumber; + + m_treeSashSize = settings.m_treeSashSize; + m_conflictsSashSize = settings.m_conflictsSashSize; + m_propertiesSashSize = settings.m_propertiesSashSize; + m_memorySashSize = settings.m_memorySashSize; + m_outputSashSize = settings.m_outputSashSize; + + m_showMacroNames = settings.m_showMacroNames; + + m_bUseCustomViewer = settings.m_bUseCustomViewer; + m_bUseExternalBrowser = settings.m_bUseExternalBrowser; + m_eUseCustomBrowser = settings.m_eUseCustomBrowser; + m_bHex = settings.m_bHex; + m_nRuleChecking = settings.m_nRuleChecking; + + // Find dialog settings + m_findText = settings.m_findText; + m_findMatchWholeWord = settings.m_findMatchWholeWord; + m_findMatchCase = settings.m_findMatchCase; + m_findDirection = settings.m_findDirection; // Down is TRUE, Up is FALSE + m_findSearchWhat = settings.m_findSearchWhat; + m_findDialogPos = settings.m_findDialogPos; + + // Run tests settings + m_runTestsSettings = settings.m_runTestsSettings; +} + +ecSettings::~ecSettings() +{ +} + +// Do some initialisation within ecApp::OnInit +bool ecSettings::Init() +{ + return TRUE; +} + +// Get a name suitable for the configuration file on all platforms: +// e.g. eCos Configuration Tool on Windows, .eCosConfigTool on Unix +wxString ecSettings::GetConfigAppName() const +{ +#ifdef __WXGTK__ + return wxString(wxT("eCosConfigTool")); +#else + return GetAppName(); +#endif +} + + +// Create new filename +wxString ecSettings::GenerateFilename(const wxString& rootName) +{ + wxString path; + if (!m_lastFilename.IsEmpty()) + path = wxPathOnly(m_lastFilename); + else + path = wxGetApp().GetAppDir(); + + wxString filename(path); + if (filename.Last() != wxFILE_SEP_PATH ) + filename += wxFILE_SEP_PATH; + filename += rootName; + + wxString fullFilename = filename + wxT(".ecc"); + int i = 0; + wxString postfixStr; + while (wxFileExists(fullFilename)) + { + i ++; + postfixStr.Printf("%d", i); + fullFilename = filename + postfixStr + wxT(".ecc"); + } + + m_lastFilename = fullFilename; + return fullFilename; +} + +// Load config info +bool ecSettings::LoadConfig() +{ + wxConfig config(wxGetApp().GetSettings().GetConfigAppName(), wxT("Red Hat")); + + config.Read(_("/Window Status/FrameStatus"), & m_frameStatus); + config.Read(_("/Window Status/ShowToolBar"), (bool*) & m_showToolBar); + config.Read(_("/Window Status/ShowSplashScreen"), (bool*) & m_showSplashScreen); + config.Read(_("/Window Status/ShowConflictsWindow"), (bool*) & m_showConflictsWindow); + config.Read(_("/Window Status/ShowPropertiesWindow"), (bool*) & m_showPropertiesWindow); + config.Read(_("/Window Status/ShowShortDescrWindow"), (bool*) & m_showShortDescrWindow); + config.Read(_("/Window Status/ShowMemoryWindow"), (bool*) & m_showMemoryWindow); + config.Read(_("/Window Status/ShowOutputWindow"), (bool*) & m_showOutputWindow); + + config.Read(_("/Files/LastFile"), & m_lastFilename); + + config.Read(_("/Window Size/WindowX"), & m_frameSize.x); + config.Read(_("/Window Size/WindowY"), & m_frameSize.y); + config.Read(_("/Window Size/WindowWidth"), & m_frameSize.width); + config.Read(_("/Window Size/WindowHeight"), & m_frameSize.height); + + config.Read(_("/Window Size/TreeSashWidth"), & m_treeSashSize.x); + config.Read(_("/Window Size/TreeSashHeight"), & m_treeSashSize.y); + config.Read(_("/Window Size/ConflictsWidth"), & m_conflictsSashSize.x); + config.Read(_("/Window Size/ConflictsHeight"), & m_conflictsSashSize.y); + config.Read(_("/Window Size/PropertiesWidth"), & m_propertiesSashSize.x); + config.Read(_("/Window Size/PropertiesHeight"), & m_propertiesSashSize.y); + config.Read(_("/Window Size/ShortDescrWidth"), & m_shortDescrSashSize.x); + config.Read(_("/Window Size/ShortDescrHeight"), & m_shortDescrSashSize.y); + config.Read(_("/Window Size/OutputWidth"), & m_outputSashSize.x); + config.Read(_("/Window Size/OutputHeight"), & m_outputSashSize.y); + config.Read(_("/Window Size/MemoryWidth"), & m_memorySashSize.x); + config.Read(_("/Window Size/MemoryHeight"), & m_memorySashSize.y); + + config.Read(_("/Options/ShowMacroNames"), (bool*) & m_showMacroNames); + config.Read(_("/Options/UseCustomViewer"), (bool*) & m_bUseCustomViewer); + config.Read(_("/Options/UseExternalBrowser"), (bool*) & m_bUseExternalBrowser); + + int tmp = (int) m_eUseCustomBrowser; + config.Read(_("/Options/UseCustomBrowser"), & tmp); + m_eUseCustomBrowser = (ecBrowserType) tmp; + + config.Read(_("/Options/Browser"), & m_strBrowser); + config.Read(_("/Options/Viewer"), & m_strViewer); + config.Read(_("/Options/HexDisplay"), (bool*) & m_bHex); + config.Read(_("/Options/UseDefaultFonts"), (bool*) & m_windowSettings.m_useDefaults); + config.Read(_("/Rule/Checking"), & m_nRuleChecking); + + // Find dialog settings + config.Read(_("/Find/Text"), & m_findText); + config.Read(_("/Find/MatchWholeWord"), (bool*) & m_findMatchWholeWord); + config.Read(_("/Find/MatchCase"), & m_findMatchCase); + config.Read(_("/Find/Direction"), (bool*) & m_findDirection); + config.Read(_("/Find/SearchWhat"), & m_findSearchWhat); + config.Read(_("/Find/DialogX"), & m_findDialogPos.x); + config.Read(_("/Find/DialogY"), & m_findDialogPos.y); + + // Run tests settings + m_runTestsSettings.LoadConfig(config); + + // Fonts + m_windowSettings.LoadConfig(config); + + if (!config.Read(_("/Paths/UserToolsDir"), & m_userToolsDir)) + { + // Use the default provided by the installer + config.Read(_("Default User Tools Path"), & m_userToolsDir); + } + + if (!config.Read(_("/Build/Make Options"), & m_strMakeOptions)) + { +#ifdef __WXMSW__ + SYSTEM_INFO SystemInfo; + GetSystemInfo(&SystemInfo); + m_strMakeOptions.Printf(_T("-j%d"),SystemInfo.dwNumberOfProcessors); +#endif + } + + // Set default build tools binary directories as specified by the installer + ecFileName strDefaultBuildToolsPath; + +#ifdef __WXMSW__ + { + // This should look in HKEY_LOCAL_MACHINE + + wxConfig config2(wxT("eCos"), wxT("Red Hat"), wxEmptyString, wxEmptyString, wxCONFIG_USE_GLOBAL_FILE|wxCONFIG_USE_LOCAL_FILE); + + wxString versionKey = GetInstallVersionKey(); + wxConfigPathChanger path(& config2, wxString(wxT("/")) + versionKey + wxT("/")); + + if (!versionKey.IsEmpty() && config2.Read(wxT("Default Build Tools Path"), & strDefaultBuildToolsPath)) + { +#ifdef __WXMSW__ + wxString gccExe(wxT("*-gcc.exe")); +#else + wxString gccExe(wxT("*-gcc")); +#endif + + // Note that this is not a recursive search. Compilers for + // different targets may be in the same directory. This finds all targets. + + // look for *-gcc[.exe] in the default build tools directory + wxLogNull log; + wxDir finder(strDefaultBuildToolsPath); + wxString filename; + + if (finder.IsOpened()) + { + bool bMore = finder.GetFirst(& filename, gccExe); + while (bMore) + { + wxString targetName = filename.Left(filename.Find(wxT("-gcc"))); + m_arstrBinDirs.Set(targetName, strDefaultBuildToolsPath); + + bMore = finder.GetNext(& filename); + } + } + } + } +#endif + + // Read build tools directories (current user) + + { + wxConfigPathChanger path(& config, wxT("/Build Tools/")); + //config.SetPath(wxT("/Build Tools")); + wxString key(wxT("")); + long index; + bool bMore = config.GetFirstEntry(key, index); + while (bMore) + { + wxString value; + if (config.Read(key, & value)) + { + m_arstrBinDirs.Set(key, value); + } + bMore = config.GetNextEntry(key, index); + } + } + + // Read toolchain paths (local machine again) +#ifdef __WXMSW__ + wxArrayString arstrToolChainPaths; + + // Use eCos just as a test. + //GetRepositoryRegistryClues(arstrToolChainPaths,_T("eCos")); + GetRepositoryRegistryClues(arstrToolChainPaths,_T("GNUPro eCos")); + + size_t i; + for (i = (size_t) 0; i < arstrToolChainPaths.GetCount(); i++) + { + ecFileName strDir(arstrToolChainPaths[i]); + strDir += wxT("H-i686-cygwin32\\bin"); + + if (strDir.IsDir()) + { + // This is a potential toolchain location. Look for *-gcc.exe + wxLogNull log; + wxDir finder(strDefaultBuildToolsPath); + wxString filename; + + if (finder.IsOpened()) + { + bool bMore = finder.GetFirst(& filename, wxT("*-gcc.exe")); + while (bMore) + { + // TODO: if there is more than one path, we will have to + // check the existance of this target name in m_arstrBinDirs and + // append to the end, or something. + wxString targetName = filename.Left(filename.Find(wxT("-gcc"))); + m_arstrBinDirs.Set(targetName, strDefaultBuildToolsPath); + + bMore = finder.GetNext(& filename); + } + } + } + } + + // The official user tools are now Cygwin 00r1. If you can't find these, + // try GNUPro unsupported. + GetRepositoryRegistryClues(m_userToolPaths, wxT("GNUPro 00r1")); + if (m_userToolPaths.GetCount() == 0) + { + GetRepositoryRegistryClues(m_userToolPaths, wxT("Cygwin 00r1")); + } + + if (m_userToolPaths.GetCount() > 0) + { + for ( i = (size_t) 0 ; i < m_userToolPaths.GetCount(); i++) + { + ecFileName str(m_userToolPaths[i]); + str += "H-i686-cygwin32\\bin"; + if(str.IsDir()) + { + m_userToolPaths[i] = str; + } else + { + m_userToolPaths.Remove(i); + i--; + } + } + } + else + { + GetRepositoryRegistryClues(m_userToolPaths, wxT("GNUPro unsupported")); + + for ( i = (size_t) 0 ; i < m_userToolPaths.GetCount(); i++) + { + ecFileName str(m_userToolPaths[i]); + str += "H-i686-cygwin32\\bin"; + if(str.IsDir()) + { + m_userToolPaths[i] = str; + } else + { + m_userToolPaths.Remove(i); + i--; + } + } + } +#endif + + // Include the path in the set of potential user paths + { + wxString strPath; + if (wxGetEnv(wxT("PATH"), & strPath)) + { + wxArrayString arstrPath; + ecUtils::Chop(strPath, arstrPath, wxT(';')); + + for (int i = arstrPath.GetCount()-1;i >= 0; --i) + { // Reverse order is important to treat path correctly + + const ecFileName &strFolder = arstrPath[i]; + ecFileName strFile(strFolder); + strFile += wxT("ls.exe"); + if ( strFile.Exists() ) + { + if (!wxArrayStringIsMember(m_userToolPaths, strFolder)) + { + m_userToolPaths.Add(strFolder); + } + + if ( m_userToolsDir.IsEmpty() ) + { + m_userToolsDir = strFolder; + } + } + } + } + } + + // Load current repository from eCos/Common/Repository/Folder + { + wxConfig eCosConfig(wxT("eCos"), wxT("Red Hat"), wxEmptyString, wxEmptyString, wxCONFIG_USE_GLOBAL_FILE|wxCONFIG_USE_LOCAL_FILE); + wxConfigPathChanger path(& config, wxT("/Common/Repository/")); + + //if (!eCosConfig.Read(wxT("Folder"), & m_strRepository)) + if (!eCosConfig.Read(wxT("/Common/Repository/Folder"), & m_strRepository)) + { +#ifdef __WXMSW__ + // If we can't find the current folder, look for clues in the registry. + wxArrayString arstr; + switch (GetRepositoryRegistryClues(arstr, wxT("eCos"))) + { + case 0: + break; + case 1: + default: + m_strRepository = arstr[0]; + break; + } +#elif defined(__WXGTK__) + // If we can't find the current folder, look for the latest version + // in /opt/ecos + m_strRepository = FindLatestVersion(); +#else + // Unsupported platform + m_strRepositor = wxEmptyString; +#endif + } + + // If we have set ECOS_REPOSITORY, this overrides whatever we have + // read or found. + wxString envVarValue = wxGetenv(wxT("ECOS_REPOSITORY")); + if (!envVarValue.IsEmpty()) + { + // Note that ECOS_REPOSITORY has the packages (or ecc) folder in the name. + // In order to be in the form that is compatible with configtool operation, + // it needs to have that stripped off. + wxString packagesName = wxFileNameFromPath(envVarValue); + if (packagesName == wxT("ecc") || packagesName == wxT("packages")) + envVarValue = wxPathOnly(envVarValue); + + m_strRepository = envVarValue; + } + } + +#ifdef __WXGTK__ + if (m_userToolsDir.IsEmpty()) + m_userToolsDir = wxT("/bin"); +#endif + + return TRUE; +} + +// Save config info +bool ecSettings::SaveConfig() +{ + wxConfig config(wxGetApp().GetSettings().GetConfigAppName(), wxT("Red Hat")); + + config.Write(_("/Files/LastFile"), m_lastFilename); + + config.Write(_("/Window Status/FrameStatus"), (long) m_frameStatus); + config.Write(_("/Window Status/ShowToolBar"), m_showToolBar); + config.Write(_("/Window Status/ShowSplashScreen"), m_showSplashScreen); + config.Write(_("/Window Status/ShowConflictsWindow"), m_showConflictsWindow); + config.Write(_("/Window Status/ShowPropertiesWindow"), m_showPropertiesWindow); + config.Write(_("/Window Status/ShowShortDescrWindow"), m_showShortDescrWindow); + config.Write(_("/Window Status/ShowMemoryWindow"), m_showMemoryWindow); + config.Write(_("/Window Status/ShowOutputWindow"), m_showOutputWindow); + + config.Write(_("/Window Size/WindowX"), (long) m_frameSize.x); + config.Write(_("/Window Size/WindowY"), (long) m_frameSize.y); + config.Write(_("/Window Size/WindowWidth"), (long) m_frameSize.width); + config.Write(_("/Window Size/WindowHeight"), (long) m_frameSize.height); + config.Write(_("/Window Size/TreeSashWidth"), (long) m_treeSashSize.x); + config.Write(_("/Window Size/TreeSashHeight"), (long) m_treeSashSize.y); + config.Write(_("/Window Size/ConflictsWidth"), (long) m_conflictsSashSize.x); + config.Write(_("/Window Size/ConflictsHeight"), (long) m_conflictsSashSize.y); + config.Write(_("/Window Size/PropertiesWidth"), (long) m_propertiesSashSize.x); + config.Write(_("/Window Size/PropertiesHeight"), (long) m_propertiesSashSize.y); + config.Write(_("/Window Size/ShortDescrWidth"), (long) m_shortDescrSashSize.x); + config.Write(_("/Window Size/ShortDescrHeight"), (long) m_shortDescrSashSize.y); + config.Write(_("/Window Size/OutputWidth"), (long) m_outputSashSize.x); + config.Write(_("/Window Size/OutputHeight"), (long) m_outputSashSize.y); + config.Write(_("/Window Size/MemoryWidth"), (long) m_memorySashSize.x); + config.Write(_("/Window Size/MemoryHeight"), (long) m_memorySashSize.y); + + config.Write(_("/Options/ShowMacroNames"), m_showMacroNames); + config.Write(_("/Options/UseCustomViewer"), m_bUseCustomViewer); + config.Write(_("/Options/UseExternalBrowser"), m_bUseExternalBrowser); + config.Write(_("/Options/UseCustomBrowser"), (long) m_eUseCustomBrowser); + config.Write(_("/Options/Browser"), m_strBrowser); + config.Write(_("/Options/Viewer"), m_strViewer); + config.Write(_("/Options/HexDisplay"), m_bHex); + config.Write(_("/Options/UseDefaultFonts"), m_windowSettings.m_useDefaults); + + config.Write(_("/Rule/Checking"), (long) m_nRuleChecking); + + config.Write(_("/Paths/UserToolsDir"), m_userToolsDir); + + config.Write(_("/Build/Make Options"), m_strMakeOptions); + + // Find dialog settings + config.Write(_("/Find/Text"), m_findText); + config.Write(_("/Find/MatchWholeWord"), m_findMatchWholeWord); + config.Write(_("/Find/MatchCase"), m_findMatchCase); + config.Write(_("/Find/Direction"), m_findDirection); + config.Write(_("/Find/SearchWhat"), m_findSearchWhat); + config.Write(_("/Find/DialogX"), (long) m_findDialogPos.x); + config.Write(_("/Find/DialogY"), (long) m_findDialogPos.y); + + // Save current repository to eCos/Common/Repository/Folder + // UNLESS it was overridden by ECOS_REPOSITORY + { + wxConfig eCosConfig(wxT("eCos"), wxT("Red Hat")); + + wxString envVarValue = wxGetenv(wxT("ECOS_REPOSITORY")); + if (m_strRepository == envVarValue) + { + // Don't override the value in the local settings + } + else + eCosConfig.Write(wxT("/Common/Repository/Folder"), m_strRepository); + } + + // Run tests settings + m_runTestsSettings.SaveConfig(config); + + // Fonts + m_windowSettings.SaveConfig(config); + + return TRUE; +} + +void ecSettings::ShowSettingsDialog(const wxString& page) +{ +#if 0 + ecSettingsDialog* dialog = new ecSettingsDialog(wxGetApp().GetTopWindow()); + if (!page.IsEmpty()) + dialog->GetNotebook()->SetSelection(ecFindNotebookPage(dialog->GetNotebook(), page)); + + int ret = dialog->ShowModal(); + dialog->Destroy(); +#endif +} + +#ifndef MAX_PATH +#define MAX_PATH 1024 +#endif + +// TODO for non-Windows platforms +const ecFileName& ecSettings::DefaultExternalBrowser() +{ +#ifdef __WXMSW__ + static bool bFirstTime=TRUE; + if(bFirstTime){ + const ecFileName strFile(ecFileName::GetTempPath()+wxT("index.html")); + wxFile f; + if(f.Create(strFile, TRUE)) + { + f.Close(); + bool rc=((int) ::FindExecutable(strFile,wxT("."),m_strDefaultExternalBrowser.GetWriteBuf(MAX_PATH))>32); + m_strDefaultExternalBrowser.UngetWriteBuf(); + if(!rc){ + m_strDefaultExternalBrowser=wxT(""); + } + wxRemoveFile(strFile); + } + bFirstTime=FALSE; + } +#endif + return m_strDefaultExternalBrowser; +} + +ecFileName ecSettings::m_strDefaultExternalBrowser; + +// Go looking for potential candidates in SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths +int ecSettings::GetRepositoryRegistryClues(wxArrayString& arstr, const wxString& pszPrefix) +{ + arstr.Clear(); + +#ifdef __WXMSW__ + wxConfig config(wxT("Windows"), wxT("Microsoft"), wxEmptyString, wxEmptyString, wxCONFIG_USE_GLOBAL_FILE); + config.SetPath(wxT("/CurrentVersion/App Paths")); + + wxString key(wxT("")); + long index; + bool bMore = config.GetFirstGroup(key, index); + while (bMore) + { + if (key.Find(pszPrefix) == 0) + { + wxString value; + //wxString key2(wxString(wxT("/")) + key + wxString(wxT("/Path"))); + wxString key2(key + wxString(wxT("/Path"))); + if (config.Read(key2, & value)) + { + arstr.Add(value); + } + } + bMore = config.GetNextGroup(key, index); + } + return arstr.GetCount(); +#else + return 0; +#endif +} + +// Finds the path of the latest installed eCos +wxString ecSettings::FindLatestVersion() +{ +#ifdef __WXGTK__ + wxString ecosRoot(wxT("/opt/ecos")); + wxLogNull log; + wxDir dir(ecosRoot); + + wxString latestDir; + wxString latestVersion; + + if (dir.IsOpened()) + { + wxString filename; + bool cont = dir.GetFirst(& filename, wxT("ecos-*"), wxDIR_DIRS); + while (cont) + { + wxString ver(filename.Mid(5)); + if (latestVersion.IsEmpty() || latestVersion.CompareTo(ver) < 0) + { + latestVersion = ver; + latestDir = ecosRoot + wxT("/") + filename; + } + + cont = dir.GetNext(& filename); + } + } + if (latestDir.IsEmpty()) + latestDir = wxGetCwd(); + return latestDir; +#else + wxMessageBox(wxT("FindLatestVersion() is only implemented for Unix.")); + return wxEmptyString; +#endif +} + +wxString ecSettings::GetInstallVersionKey () +{ +#ifdef __WXMSW__ + +#ifndef MAX_PATH +#define MAX_PATH 1024 +#endif + + wxString strKey = wxT("SOFTWARE\\Red Hat\\eCos"); + wxString strVersionKey = wxT(""); + wxString rc = wxT(""); + wxChar pszBuffer [MAX_PATH + 1]; + HKEY hKey; + + // get the greatest eCos version subkey + if (ERROR_SUCCESS == RegOpenKeyEx (HKEY_LOCAL_MACHINE, strKey, 0L, KEY_READ, &hKey)) { + DWORD dwIndex = 0; + while (ERROR_SUCCESS == RegEnumKey (hKey, dwIndex++, (LPTSTR) pszBuffer, sizeof (pszBuffer))) { + if (strVersionKey.CompareTo (pszBuffer) < 0) { + strVersionKey = pszBuffer; + } + } + RegCloseKey (hKey); + } + return strVersionKey; +#else + wxMessageBox(wxT("GetInstallVersionKey() is only implemented for Windows.")); + return wxEmptyString; +#endif +} + +/* + * ecRunTestSettings + * Settings relating to running tests + */ + +IMPLEMENT_DYNAMIC_CLASS(ecRunTestsSettings, wxObject) + +ecRunTestsSettings::ecRunTestsSettings(): + m_ep(CeCosTest::ExecutionParameters::RUN), + m_nTimeout(900), + m_nDownloadTimeout(120), + m_nTimeoutType(TIMEOUT_AUTOMATIC), + m_nDownloadTimeoutType(TIMEOUT_SPECIFIED), + m_bRemote(FALSE), + m_bSerial(TRUE), + m_strPort(wxT("COM1")), + m_nBaud(38400), + m_nLocalTCPIPPort(1), + m_nReset(RESET_MANUAL), + m_nResourcePort(1), + m_nRemotePort(1), + m_bFarmed(TRUE), + m_strRemoteHost(wxT("")), + m_strResourceHost(wxT("")), + m_strLocalTCPIPHost(wxT("")), + m_strReset(wxT("")) +{ +} + +ecRunTestsSettings::ecRunTestsSettings(const ecRunTestsSettings& settings) +{ + Copy(settings); +} + +void ecRunTestsSettings::Copy(const ecRunTestsSettings& settings) +{ + m_nTimeoutType = settings.m_nTimeoutType; + m_nDownloadTimeoutType = settings.m_nDownloadTimeoutType; + m_bRemote = settings.m_bRemote; + m_bSerial = settings.m_bSerial; + m_strPort = settings.m_strPort; + m_nBaud = settings.m_nBaud; + m_nLocalTCPIPPort = settings.m_nLocalTCPIPPort; + m_nReset = settings.m_nReset; + m_nResourcePort = settings.m_nResourcePort; + m_nRemotePort = settings.m_nRemotePort; + m_bFarmed = settings.m_bFarmed; + m_strTarget = settings.m_strTarget; + m_strRemoteHost = settings.m_strRemoteHost; + m_strResourceHost = settings.m_strResourceHost; + m_strLocalTCPIPHost = settings.m_strLocalTCPIPHost; + m_strReset = settings.m_strReset; +} + +bool ecRunTestsSettings::LoadConfig(wxConfig& config) +{ + config.Read(_("/Run Tests/TimeoutType"), & m_nTimeoutType); + config.Read(_("/Run Tests/DownloadTimeoutType"), & m_nDownloadTimeoutType); + config.Read(_("/Run Tests/Remote"), (bool*) & m_bRemote); + config.Read(_("/Run Tests/Serial"), (bool*) & m_bSerial); + config.Read(_("/Run Tests/Port"), & m_strPort); + config.Read(_("/Run Tests/Baud"), & m_nBaud); + config.Read(_("/Run Tests/LocalTCPIPHost"), & m_strLocalTCPIPHost); + config.Read(_("/Run Tests/LocalTCPIPPort"), & m_nLocalTCPIPPort); + config.Read(_("/Run Tests/ResetType"), & m_nReset); + config.Read(_("/Run Tests/ResetString"), & m_strReset); + config.Read(_("/Run Tests/ResourceHost"), & m_strResourceHost); + config.Read(_("/Run Tests/ResourcePort"), & m_nResourcePort); + config.Read(_("/Run Tests/RemoteHost"), & m_strRemoteHost); + config.Read(_("/Run Tests/RemotePort"), & m_nRemotePort); + config.Read(_("/Run Tests/Farmed"), (bool*) & m_bFarmed); + + return TRUE; +} + +bool ecRunTestsSettings::SaveConfig(wxConfig& config) +{ + config.Write(_("/Run Tests/TimeoutType"), (long) m_nTimeoutType); + config.Write(_("/Run Tests/DownloadTimeoutType"), (long) m_nDownloadTimeoutType); + config.Write(_("/Run Tests/Remote"), m_bRemote); + config.Write(_("/Run Tests/Serial"), m_bSerial); + config.Write(_("/Run Tests/Port"), m_strPort); + config.Write(_("/Run Tests/Baud"), (long) m_nBaud); + config.Write(_("/Run Tests/LocalTCPIPHost"), m_strLocalTCPIPHost); + config.Write(_("/Run Tests/LocalTCPIPPort"), (long) m_nLocalTCPIPPort); + config.Write(_("/Run Tests/ResetType"), (long) m_nReset); + config.Write(_("/Run Tests/ResetString"), m_strReset); + config.Write(_("/Run Tests/ResourceHost"), m_strResourceHost); + config.Write(_("/Run Tests/ResourcePort"), (long) m_nResourcePort); + config.Write(_("/Run Tests/RemoteHost"), m_strRemoteHost); + config.Write(_("/Run Tests/RemotePort"), (long) m_nRemotePort); + config.Write(_("/Run Tests/Farmed"), m_bFarmed); + + return TRUE; +} + diff --git a/host/tools/configtool/standalone/wxwin/appsettings.h b/host/tools/configtool/standalone/wxwin/appsettings.h new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/appsettings.h @@ -0,0 +1,242 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +// appsettings.h : +// +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): julians +// Contact(s): julians +// Date: 2000/08/29 +// Version: $Id: appsettings.h,v 1.8 2001/04/24 14:39:13 julians Exp $ +// Purpose: +// Description: Header file for the ConfigTool application settings +// Requires: +// Provides: +// See also: +// Known bugs: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== + +#ifndef _ECOS_APPSETTINGS_H_ +#define _ECOS_APPSETTINGS_H_ + +#include "wx/config.h" +#include "filename.h" +#include "ecutils.h" +#include "eCosTest.h" + +#ifdef __WXMSW__ +#include "wx/msw/winundef.h" +#endif + +// Frame status +#define ecSHOW_STATUS_NORMAL 0x01 +#define ecSHOW_STATUS_MINIMIZED 0x02 +#define ecSHOW_STATUS_MAXIMIZED 0x03 + +// What kind of browser (wxHtmlHelpController, default browser, custom browser) +enum ecBrowserType { ecInternal, ecAssociatedExternal, ecCustomExternal }; + +/* + * ecRunTestSettings + * Settings relating to running tests + */ +enum ResetType {RESET_NONE, RESET_X10, RESET_MANUAL}; +enum TimeoutType {TIMEOUT_NONE,TIMEOUT_SPECIFIED, TIMEOUT_AUTOMATIC}; + +class ecRunTestsSettings: public wxObject +{ +DECLARE_DYNAMIC_CLASS(ecRunTestsSettings) +public: + ecRunTestsSettings(); + ecRunTestsSettings(const ecRunTestsSettings& settings); + +//// Operations + void Copy(const ecRunTestsSettings& settings); + + bool SaveConfig(wxConfig& config); + bool LoadConfig(wxConfig& config); + +//// Data members + CeCosTest::ExecutionParameters m_ep; + int m_nTimeout; + int m_nDownloadTimeout; + int m_nTimeoutType; + int m_nDownloadTimeoutType; + bool m_bRemote; + bool m_bSerial; + int m_nBaud; + int m_nLocalTCPIPPort; + int m_nReset; + int m_nResourcePort; + int m_nRemotePort; + bool m_bFarmed; + wxString m_strPort; // Serial port + wxString m_strTarget; + + wxString m_strRemoteHost; + wxString m_strResourceHost; + wxString m_strLocalTCPIPHost; + wxString m_strReset; +}; + +/* + * ecSettings + * Various application settings + */ + +class ecSettings: public wxObject +{ +DECLARE_DYNAMIC_CLASS(ecSettings) +public: + ecSettings(); + ecSettings(const ecSettings& settings); + ~ecSettings(); + +//// Operations + // Copy from settings to 'this' + void Copy(const ecSettings& settings); + + // Load config info + bool LoadConfig(); + + // Save config info + bool SaveConfig(); + + // Load and save font descriptions + bool LoadFont(wxConfig& config, const wxString& windowName, wxFont& font); + bool SaveFont(wxConfig& config, const wxString& windowName, const wxFont& font); + bool LoadFonts(wxConfig& config); + bool SaveFonts(wxConfig& config); + bool ApplyFontsToWindows(); + + // Do some initialisation within ecApp::OnInit + bool Init(); + + // Show settings dialog + void ShowSettingsDialog(const wxString& page = wxEmptyString); + + // Create new filename + wxString GenerateFilename(const wxString& rootName); + + // Go looking for potential candidates in SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths + int GetRepositoryRegistryClues(wxArrayString& arstr, const wxString& pszPrefix); + + // Finds the path of the latest installed eCos (Unix only) + wxString FindLatestVersion(); + + // Find the subkey of the latest installed eCos, e.g. "1.4.9" + wxString GetInstallVersionKey (); + +//// Accessors + + wxString GetAppName() const { return m_appName; } + + // Get a name suitable for the configuration file on all platforms: + // e.g. eCos Configuration Tool on Windows, .eCosConfigTool on Unix + wxString GetConfigAppName() const ; + + wxString& GetLastFilename() { return m_lastFilename; } + + const ecFileName& DefaultExternalBrowser() ; + + const wxString& GetUserToolsDir() const { return m_userToolsDir; } + + wxStringToStringMap& GetBinDirs() { return m_arstrBinDirs; } + + ecRunTestsSettings& GetRunTestsSettings() { return m_runTestsSettings; } + + wxWindowSettings& GetWindowSettings() { return m_windowSettings; } + +public: + bool m_showToolBar; + wxRect m_frameSize; + wxString m_appName; // The current name of the app... + bool m_showSplashScreen; // Show the splash screen + wxString m_userName; + int m_serialNumber; + wxString m_lastFilename; // So we can auto-generate sensible filenames + int m_frameStatus; + + // Sash window sizes + wxSize m_treeSashSize; + wxSize m_conflictsSashSize; + wxSize m_propertiesSashSize; + wxSize m_shortDescrSashSize; + wxSize m_memorySashSize; + wxSize m_outputSashSize; + bool m_showConflictsWindow; + bool m_showPropertiesWindow; + bool m_showShortDescrWindow; + bool m_showMemoryWindow; + bool m_showOutputWindow; + + // Are we showing macro names, or ordinary names? + bool m_showMacroNames ; + + // Viewers & browsers + bool m_bUseCustomViewer; + bool m_bUseExternalBrowser; + wxString m_strBrowser; + ecFileName m_strViewer; + ecBrowserType m_eUseCustomBrowser; + static ecFileName m_strDefaultExternalBrowser; + bool m_bHex; + + ecFileName m_userToolsDir; + + wxString m_strMakeOptions; + + wxStringToStringMap m_arstrBinDirs; // Not saved + wxArrayString m_userToolPaths; // Not saved + + ecFileName m_strRepository; // This is saved/loaded via ecSettings, and + // copied to/from ecConfigToolDoc on doc creation/deletion. + // This is because the doc doesn't have its own profile loading/saving. + + enum {Never=0, Immediate=1, Deferred=2, SuggestFixes=4}; + int m_nRuleChecking; // OR of above values + + // Find dialog settings + wxString m_findText; + bool m_findMatchWholeWord; + bool m_findMatchCase; + bool m_findDirection; // Down is TRUE, Up is FALSE + wxString m_findSearchWhat; // Macro names, item names etc. + wxPoint m_findDialogPos; // Position of dialog + + // Run tests settings + ecRunTestsSettings m_runTestsSettings; + + // Font settings + wxWindowSettings m_windowSettings; +}; + +#endif + // _ECOS_APPSETTINGS_H_ diff --git a/host/tools/configtool/standalone/wxwin/bitmaps/buildlibrary.bmp b/host/tools/configtool/standalone/wxwin/bitmaps/buildlibrary.bmp new file mode 100644 index 0000000000000000000000000000000000000000..d26cad28a42f305d474409a72109f5dcd713f0ca GIT binary patch literal 238 zc${^Ku?>JQ3|NPEpKknc2eW?iMsyYk_0B=C@@is3GO`>>&b1t!Sd<> Dy|_DJ diff --git a/host/tools/configtool/standalone/wxwin/bitmaps/buildlibrary.xpm b/host/tools/configtool/standalone/wxwin/bitmaps/buildlibrary.xpm new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/bitmaps/buildlibrary.xpm @@ -0,0 +1,21 @@ +/* XPM */ +static char *buildlibrary_xpm[] = { +"16 15 3 1", +" c None", +". c #000080", +"X c Black", +" ", +" . . . . ", +" . . . ", +" . . . . ", +" . . . ", +"X . . X ", +"X ..... ..... X ", +"X ... ... X ", +"X . . X ", +"X X ", +"X X X X X X X X ", +"X X ", +"X X X X X X X X ", +"X X ", +"XXXXXXXXXXXXXXX "}; diff --git a/host/tools/configtool/standalone/wxwin/bitmaps/checked.bmp b/host/tools/configtool/standalone/wxwin/bitmaps/checked.bmp new file mode 100644 index 0000000000000000000000000000000000000000..27b7ba1cc2eae24601fd27ca28becc5385857a75 GIT binary patch literal 246 zc${i`1` F>j3y-PCozu diff --git a/host/tools/configtool/standalone/wxwin/bitmaps/checked_dis.ico b/host/tools/configtool/standalone/wxwin/bitmaps/checked_dis.ico new file mode 100644 index 0000000000000000000000000000000000000000..22b32e1d34a4fa46ad039546a58d794741acdea8 GIT binary patch literal 318 zc$}4vu?~PB3`CD;;>zUg$REncMn8)`!#faTG!9;AAGy#{z%jh{tTTcGRsezNnHy8S zRPd$L4pQn+@KQ=4<^XvXmNxtzh9@>f||8wd+ P>f5YG{2yO|>)ZDNLl;#? diff --git a/host/tools/configtool/standalone/wxwin/bitmaps/closedfolder.xpm b/host/tools/configtool/standalone/wxwin/bitmaps/closedfolder.xpm new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/bitmaps/closedfolder.xpm @@ -0,0 +1,25 @@ +/* XPM */ +static char * closedfolder_xpm[] = { +"16 16 6 1", +" c None", +". c #808080", +"X c Yellow", +"o c #c0c0c0", +"O c Gray100", +"+ c Black", +" ", +" ..... ", +" .XoXoX. ", +" .XoXoXoX...... ", +" .OOOOOOOOOOOO.+", +" .OXoXoXoXoXoX.+", +" .OoXoXoXoXoXo.+", +" .OXoXoXoXoXoX.+", +" .OoXoXoXoXoXo.+", +" .OXoXoXoXoXoX.+", +" .OoXoXoXoXoXo.+", +" .OXoXoXoXoXoX.+", +" ..............+", +" ++++++++++++++", +" ", +" "}; diff --git a/host/tools/configtool/standalone/wxwin/bitmaps/closedfolder_dis.bmp b/host/tools/configtool/standalone/wxwin/bitmaps/closedfolder_dis.bmp new file mode 100644 index 0000000000000000000000000000000000000000..7ea10e7b000f83b4eb7100af6499f07824357515 GIT binary patch literal 246 zc${a|Ky%VEfE=&|9UX1R_5lDqcS^4S diff --git a/host/tools/configtool/standalone/wxwin/bitmaps/closedfolder_dis.ico b/host/tools/configtool/standalone/wxwin/bitmaps/closedfolder_dis.ico new file mode 100644 index 0000000000000000000000000000000000000000..f85ff84683e43c13b8ad21a4a717b3cc18af25b0 GIT binary patch literal 318 zc$}qAF%p0<2un`~M-{!m9YeHOl~CdI+Ub1)E6I7%r{XlBMZq84BVP)Q>fQgtEl z2Ja5{6d4Z@K~<%7M{6lEl@wlZB(Sf-_DeNqQj&xH`A+V^olF1dHwX5z|Ge*A6S72D diff --git a/host/tools/configtool/standalone/wxwin/bitmaps/closedfolder_dis.xpm b/host/tools/configtool/standalone/wxwin/bitmaps/closedfolder_dis.xpm new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/bitmaps/closedfolder_dis.xpm @@ -0,0 +1,23 @@ +/* XPM */ +static char * closedfolder_dis_xpm[] = { +"16 16 4 1", +" c None", +". c #808080", +"X c #c0c0c0", +"o c Black", +" ", +" ..... ", +" .XXXXX. ", +".XXXXXXX...... ", +".XXXXXXXXXXXX.o ", +".XXXXXXXXXXXX.o ", +".XXXXXXXXXXXX.o ", +".XXXXXXXXXXXX.o ", +".XXXXXXXXXXXX.o ", +".XXXXXXXXXXXX.o ", +".XXXXXXXXXXXX.o ", +".XXXXXXXXXXXX.o ", +"..............o ", +" oooooooooooooo ", +" ", +" "}; diff --git a/host/tools/configtool/standalone/wxwin/bitmaps/configtool.bmp b/host/tools/configtool/standalone/wxwin/bitmaps/configtool.bmp new file mode 100644 index 0000000000000000000000000000000000000000..7b197d15556938308a147bb9eb9c874cabe8bfed GIT binary patch literal 3126 zc${u+@I){Y*EGDoR?A`S`!Iq7sh zN;YYTfS^ECc^Ezm;EC#e_Rj)rODdl$@|6@kq`kVp3hFdb*I8`vp>12LMKn#QX0c%* zTNZFJo??vq7@NCzgy2I6%Y6Ux&D^^<_bJ8bT@qow{3Ti*a6=(^fAquq&5#;1-{&7Z zF8CEpf9W3n29$c0qQ)cS_W=2MgmgQ|_XhG&La9oxj4St*=d7u^jp{W{V0~^ERAKD% zcD2^}=010)xNjyZKJ;-ef66NrE6RM|E$g=&7kU|o3167^oqWr>`yw^7JIJQ3^P(C#&QOCph!%JS2`fd*wcCu>cAeH76}%dIF3Ce({iF=Cr5H1J=ww4 z{JlX#uVPIP-z5zI?nFX?~r}t4a*TJCQlk P`<_R_^MiN#&#!m`D~VPI diff --git a/host/tools/configtool/standalone/wxwin/bitmaps/copy.xpm b/host/tools/configtool/standalone/wxwin/bitmaps/copy.xpm new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/bitmaps/copy.xpm @@ -0,0 +1,25 @@ +/* XPM */ +static char *copy_xpm[] = { +/* columns rows colors chars-per-pixel */ +"16 15 4 1", +" c None", +". c Black", +"X c Gray100", +"o c #000080", +/* pixels */ +" ", +" ...... ", +" .XXXX.. ", +" .XXXX.X. ", +" .X..X.oooooo ", +" .XXXXXoXXXXoo ", +" .X....oXXXXoXo ", +" .XXXXXoX..Xoooo", +" .X....oXXXXXXXo", +" .XXXXXoX.....Xo", +" ......oXXXXXXXo", +" oX.....Xo", +" oXXXXXXXo", +" ooooooooo", +" " +}; diff --git a/host/tools/configtool/standalone/wxwin/bitmaps/cshelp.bmp b/host/tools/configtool/standalone/wxwin/bitmaps/cshelp.bmp new file mode 100644 index 0000000000000000000000000000000000000000..e80bec0c2019cf29d1a2fa1c81892b501b1fd1ee GIT binary patch literal 238 zc$_tiyA8uI3`8$L02L{0cnZ%E5K!e^QV6C?ji!mbf^z)$$kP*#0KdnL&`Iy~N-y*a zZ_h7!`-Iorhq^a<4_NUt#vm=3-k39BWf33MUs2aXMpCsTkugAu5l9wo)u^_xQ5bM! PN|vN=TeT}qL?8VD4PrgB diff --git a/host/tools/configtool/standalone/wxwin/bitmaps/cshelp.xpm b/host/tools/configtool/standalone/wxwin/bitmaps/cshelp.xpm new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/bitmaps/cshelp.xpm @@ -0,0 +1,21 @@ +/* XPM */ +static char *cshelp_xpm[] = { +"16 15 3 1", +" c None", +". c Black", +"X c #000080", +" ", +". XXXXX ", +".. XX XX ", +"... XX XX ", +".... XX XX ", +"..... XX XX ", +"...... XX ", +"....... XX ", +"........ XX ", +"..... XX ", +".. .. ", +". .. XXX ", +" .. XXX ", +" .. ", +" .. "}; diff --git a/host/tools/configtool/standalone/wxwin/bitmaps/cut.bmp b/host/tools/configtool/standalone/wxwin/bitmaps/cut.bmp new file mode 100644 index 0000000000000000000000000000000000000000..15554338a01bc4d8f0a501c32237e84200e64583 GIT binary patch literal 238 zc${^~!3}^Q3=*2OwoC+i@i z?@#$l@gt>>KK7`!ntjv!NNc1|U)cpjcrr9A)%+6i5gOH92@-(>8fXgge5X&D8*~>) A*#H0l diff --git a/host/tools/configtool/standalone/wxwin/bitmaps/cut.xpm b/host/tools/configtool/standalone/wxwin/bitmaps/cut.xpm new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/bitmaps/cut.xpm @@ -0,0 +1,24 @@ +/* XPM */ +static char *cut_xpm[] = { +/* columns rows colors chars-per-pixel */ +"16 15 3 1", +" c None", +". c Black", +"X c #000080", +/* pixels */ +" ", +" . . ", +" . . ", +" . . ", +" .. .. ", +" . . ", +" ... ", +" . ", +" X.X ", +" X XXX ", +" XXX X X ", +" X X X X ", +" X X X X ", +" X X XX ", +" XX " +}; diff --git a/host/tools/configtool/standalone/wxwin/bitmaps/delete.bmp b/host/tools/configtool/standalone/wxwin/bitmaps/delete.bmp new file mode 100644 index 0000000000000000000000000000000000000000..8dcd63adb3c03dd5118723bae3d0704230ee507e GIT binary patch literal 238 zc$`g5$qj%o3^Ni^A3Q)z!5sYAB`?CWqje%yD9%xdB#s+9O3&*>#7!K;My$ky+4YCm zm%x^OMD;?gL6&^9*2t!GFZ3Q{X%d@`5bs4%Vg^DKxU6P~F$LsCtP1o$r!Tqhcc6K< GjPE`^r9mnH diff --git a/host/tools/configtool/standalone/wxwin/bitmaps/delete.xpm b/host/tools/configtool/standalone/wxwin/bitmaps/delete.xpm new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/bitmaps/delete.xpm @@ -0,0 +1,20 @@ +/* XPM */ +static char *delete_xpm[] = { +"16 15 2 1", +" c None", +". c Black", +" ", +" ... . ", +" .... .. ", +" .... .. ", +" ... .. ", +" ..... ", +" ... ", +" ..... ", +" ... .. ", +" ... .. ", +" ... . ", +" .... . ", +" ... ", +" . . ", +" "}; diff --git a/host/tools/configtool/standalone/wxwin/bitmaps/enumerated.bmp b/host/tools/configtool/standalone/wxwin/bitmaps/enumerated.bmp new file mode 100644 index 0000000000000000000000000000000000000000..bc85b1e0e42aacf2d32c5d97528546f5ece13f87 GIT binary patch literal 246 zc$`&DF%Ezr46KQP!NvFr-{I~bI@Q%l*N!}kSGi(K3(>a6(Yp(5`vX>&U=_@c0miDc zV3`cfgXXBoY@{uhoU^bhr4E#0q^*)3UV(@(C9Zr#4k96f?J}|hesciSea(CB_g?4I KINtp~@_GR-_%we2 diff --git a/host/tools/configtool/standalone/wxwin/bitmaps/enumerated.ico b/host/tools/configtool/standalone/wxwin/bitmaps/enumerated.ico new file mode 100644 index 0000000000000000000000000000000000000000..a504a004d52a805a8d0032b69a0ed31167d84c2f GIT binary patch literal 318 zc${^QI}XDz3`1Xl0$x3J?wDh==!Lpeeas}&+S%{YowN|M+tv9WOc)8`{h-tE}DcSz;3D(@Y-}4vvgrx83w&-@5 U;U$&@o)+GF4&S{k_b2fkeh76cCjbBd diff --git a/host/tools/configtool/standalone/wxwin/bitmaps/enumerated.xpm b/host/tools/configtool/standalone/wxwin/bitmaps/enumerated.xpm new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/bitmaps/enumerated.xpm @@ -0,0 +1,23 @@ +/* XPM */ +static char * enumerated_xpm[] = { +"16 16 4 1", +" c None", +". c Black", +"X c #c0c0c0", +"o c #808080", +" ", +"................", +". ..XXX..", +". ...X...", +". .......", +"................", +". . .", +". . X.Xo.", +". .... . ...o.", +". .ooooo.", +". ...... .......", +". . .", +". ..... . ...o.", +". . X.Xo.", +". .ooooo.", +"................"}; diff --git a/host/tools/configtool/standalone/wxwin/bitmaps/enumerated_dis.bmp b/host/tools/configtool/standalone/wxwin/bitmaps/enumerated_dis.bmp new file mode 100644 index 0000000000000000000000000000000000000000..2f895249d3d03dd3064e99b7229e90feef9acb8c GIT binary patch literal 246 zc$`&@F%Ez*2t_e5VQ?{?!gIKL2dBC+$;#-ldMeing*FQPedYhA-S!8(F4d}oq@jh0GKFp#vs%0 My-so>_y1DV3-(DjdH?_b diff --git a/host/tools/configtool/standalone/wxwin/bitmaps/enumerated_dis.ico b/host/tools/configtool/standalone/wxwin/bitmaps/enumerated_dis.ico new file mode 100644 index 0000000000000000000000000000000000000000..ec550a6c0af1eff2aec521c4fe1f7807d14926d5 GIT binary patch literal 318 zc${@lF%APU2=hsmSTl9*c(3T2*jO3wS@~JcCQ(~eiorNB2qnP5Xsxk6a2~)Dz)3dp zMamaCcF0O(PEqjCd#B17l^A1+LYB&cMTB2hmYSu}a;~bo`lSEP0pY&-VM}ZDyYHhu R)nfaD`l$HckNiW=zX1?IGfMyf diff --git a/host/tools/configtool/standalone/wxwin/bitmaps/enumerated_dis.xpm b/host/tools/configtool/standalone/wxwin/bitmaps/enumerated_dis.xpm new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/bitmaps/enumerated_dis.xpm @@ -0,0 +1,23 @@ +/* XPM */ +static char * enumerated_dis_xpm[] = { +"16 16 4 1", +" c None", +". c Black", +"X c #c0c0c0", +"o c #808080", +" ", +"................", +".XXXXXXXX..XXX..", +".XXXXXXXX...X...", +".XXXXXXXX.......", +"................", +".XXXXXXXX.XXXXX.", +".XXXXXXXX.XX.Xo.", +".X....XXX.X...o.", +".XXXXXXXX.ooooo.", +".X......X.......", +".XXXXXXXX. .", +".X.....XX. ...o.", +".XXXXXXXX. X.Xo.", +".XXXXXXXX.ooooo.", +"................"}; diff --git a/host/tools/configtool/standalone/wxwin/bitmaps/help.bmp b/host/tools/configtool/standalone/wxwin/bitmaps/help.bmp new file mode 100644 index 0000000000000000000000000000000000000000..493e14b37fdfeb5b8e3373d196d51f1d5f98d1d7 GIT binary patch literal 238 zc${60F%Ez*2t_ez(xHRKQ+N({@4_UGJyQ2BJ&{+aAE<)@pVxc{-H)3*PH2M`Xoe;V z=3mg7T+5hyWGl+qp@~Op4OFLFQSS~-wa`R_wINc8AF@NjJO9)7h^t*G(F~A{m4Yp# LYIA%;K;rKHef!(rvJH(g zrKEnKYv2rYLK3cm=@x~5k!z8&lcffw6tO8wEtbW}(j;ra{K0&|o$HBnEHOH(zBtb8 v`!xAouUz%*Jii5uj5Rhl+#hf`!tjRMB(y6g*ZOwXdVR+55}q=i>T~!2KXOIs diff --git a/host/tools/configtool/standalone/wxwin/bitmaps/integer.xpm b/host/tools/configtool/standalone/wxwin/bitmaps/integer.xpm new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/bitmaps/integer.xpm @@ -0,0 +1,23 @@ +/* XPM */ +static char * integer_xpm[] = { +"16 16 4 1", +" c None", +". c #808080", +"X c Blue", +"o c Black", +" ", +"............. ", +". .. ", +". . . ", +". XXX XX X.ooo", +". XX XX XX XX o", +". XX XX XX XX o", +". XXX XX XX o", +". o", +". XX XX XXX o", +". XX XX XX XX o", +". XX XX XX XX o", +". XX XX XoX o", +". o", +".oo .oooo. o", +" .oooo o. o"}; diff --git a/host/tools/configtool/standalone/wxwin/bitmaps/integer2.bmp b/host/tools/configtool/standalone/wxwin/bitmaps/integer2.bmp new file mode 100644 index 0000000000000000000000000000000000000000..b823b4b28d7f87a5a21307d2b2ed606329052c35 GIT binary patch literal 246 zc$`Ixu?@p83ubENkU0*gl`NX?4ySeh!W@)RwE$QI+>q9-M z`>BguyKmHENsXP1O)Sk4(Y(}J$#7a9X)O^Q77x5dfVtQ$ZeAR{im$rql;n`Wpsx7m X_(*@`bVE=hXp%Yi)FJ0AHf1lxzB^f(WUV!SYrfW<-;I6fLU2}zp>pW? z&FSKLol`Tmp-}hvD_~(MQQfdT;Bti98>UqlU^c9-T?f~uyUv@mm++MFRKCLp3|lpA diff --git a/host/tools/configtool/standalone/wxwin/bitmaps/integer2.xpm b/host/tools/configtool/standalone/wxwin/bitmaps/integer2.xpm new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/bitmaps/integer2.xpm @@ -0,0 +1,23 @@ +/* XPM */ +static char * integer2_xpm[] = { +"16 16 4 1", +" c None", +". c #808080", +"X c #008000", +"o c Black", +" ", +"............. ", +". .. ", +". . . ", +". XXX X.ooo", +". XX XX XX o", +". XX XX XX XX o", +". XXX XX XX o", +". o", +". XX XXX o", +". XX XX XX o", +". XX XX XX XX o", +". XX XX XoX o", +". o", +".oo .oooo. o", +" .oooo o. o"}; diff --git a/host/tools/configtool/standalone/wxwin/bitmaps/integer2_dis.bmp b/host/tools/configtool/standalone/wxwin/bitmaps/integer2_dis.bmp new file mode 100644 index 0000000000000000000000000000000000000000..39af26cf87aced5bc1c69fc9ca2b4695f502d0db GIT binary patch literal 246 zc$`IwF%H8p2t}z>DUrHVIYrKqz1Kh;Jq1Q4<74?$U0pCi`S|l%|R{R$ha4j6_LpbocBN UdG=Vz$zBwQUai4~ZK`7G56Hk!{{R30 diff --git a/host/tools/configtool/standalone/wxwin/bitmaps/integer2_dis.ico b/host/tools/configtool/standalone/wxwin/bitmaps/integer2_dis.ico new file mode 100644 index 0000000000000000000000000000000000000000..d682c5bdb7ee300ff9c309dc7193fc631e7181fe GIT binary patch literal 318 zc${@lF%rWd3{$S{g^{Uq#ypSB9=*Y{cuJm-A5a-z+NF^#3v}WR0}CtX%=yH=0B-<0 znaPcG-_dagn+>xNFCKdDRCmT~j1l7HmXGA`Q?XSPsHMt8sZFb0f@e=-( e(<-j&K||!sLL1tIeSdzOw@dxUi+qslTn8UyM@_8& diff --git a/host/tools/configtool/standalone/wxwin/bitmaps/integer2_dis.xpm b/host/tools/configtool/standalone/wxwin/bitmaps/integer2_dis.xpm new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/bitmaps/integer2_dis.xpm @@ -0,0 +1,23 @@ +/* XPM */ +static char * integer2_dis_xpm[] = { +"16 16 4 1", +" c None", +". c #808080", +"X c #c0c0c0", +"o c Black", +" ", +"............. ", +".XXXXXXXXXXX.. ", +".XXXXXXXXXXX. . ", +".XX...XXXXX..ooo", +".X..X..XXXX..XXo", +".X..X..X..X..XXo", +".XX...XX..X..XXo", +".XXXXXXXXXXXXXXo", +".X..XXXXX...XXXo", +".X..XXXX..X..XXo", +".X..X..X..X..XXo", +".X..X..XX.o.XXXo", +".XXXXXXXXXXXXXXo", +".ooXXXX.oooo.XXo", +" .oooo o.Xo"}; diff --git a/host/tools/configtool/standalone/wxwin/bitmaps/integer_dis.bmp b/host/tools/configtool/standalone/wxwin/bitmaps/integer_dis.bmp new file mode 100644 index 0000000000000000000000000000000000000000..33b6cc1eb435e9f14ce32e26a1276e527eccf7e9 GIT binary patch literal 246 zc${5|I}XDj5JV@EC0lZ1$<94jp;4)`XgLJLuh^qmf+n28foxb4)-9C7MF1siegz=f+gywI`qd Q-e@_)_i}bts-{dsU)a=9LjV8( diff --git a/host/tools/configtool/standalone/wxwin/bitmaps/integer_dis.ico b/host/tools/configtool/standalone/wxwin/bitmaps/integer_dis.ico new file mode 100644 index 0000000000000000000000000000000000000000..a727e8e333841069b46bf5e1756bf38bcd33d4b9 GIT binary patch literal 318 zc${@lF%HBa40Clom654)$3Bk@#%%B`p3*1u2b_~gcWQNY;+U8q5ny7(7+GiR6R-l< z$w+Rb`ihPxh$Tc^G%clraZm`DHs diff --git a/host/tools/configtool/standalone/wxwin/bitmaps/open.xpm b/host/tools/configtool/standalone/wxwin/bitmaps/open.xpm new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/bitmaps/open.xpm @@ -0,0 +1,26 @@ +/* XPM */ +static char *open_xpm[] = { +/* columns rows colors chars-per-pixel */ +"16 15 5 1", +" c None", +". c Black", +"X c Yellow", +"o c Gray100", +"O c #bfbf00", +/* pixels */ +" ", +" ... ", +" . . .", +" ..", +" ... ...", +" .XoX....... ", +" .oXoXoXoXo. ", +" .XoXoXoXoX. ", +" .oXoX..........", +" .XoX.OOOOOOOOO.", +" .oo.OOOOOOOOO. ", +" .X.OOOOOOOOO. ", +" ..OOOOOOOOO. ", +" ........... ", +" " +}; diff --git a/host/tools/configtool/standalone/wxwin/bitmaps/package_closed.bmp b/host/tools/configtool/standalone/wxwin/bitmaps/package_closed.bmp new file mode 100644 index 0000000000000000000000000000000000000000..1c3217e86841884580a4bf5877126b644ebe7f8b GIT binary patch literal 246 zc${$141F2_AqZ9xDp58{t diff --git a/host/tools/configtool/standalone/wxwin/bitmaps/package_closed.ico b/host/tools/configtool/standalone/wxwin/bitmaps/package_closed.ico new file mode 100644 index 0000000000000000000000000000000000000000..d4abb0251b7e93c0d3a2d1ceb9864481a3724e99 GIT binary patch literal 318 zc$}3^ArinK3=6m2Ay+j$$@Av0{ER+jPnbur6mT43Nz>3^0yt7cxOW5xoB#qP)J0it zP^^&JAf;|bK2()%No|8#yBRIAHKCN!JmjUAN BI2-@~ diff --git a/host/tools/configtool/standalone/wxwin/bitmaps/package_closed.xpm b/host/tools/configtool/standalone/wxwin/bitmaps/package_closed.xpm new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/bitmaps/package_closed.xpm @@ -0,0 +1,25 @@ +/* XPM */ +static char * package_closed_xpm[] = { +"16 16 6 1", +" c None", +". c Black", +"X c #c0c0c0", +"o c #808000", +"O c Gray100", +"+ c Yellow", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ......... ", +" .XXXXXXX.. ", +" ........o. ", +" .O+O+O+.o. ", +" .+O+O+O.o. ", +" .O+O+O+... ", +" ......... ", +" "}; diff --git a/host/tools/configtool/standalone/wxwin/bitmaps/package_closed_dis.bmp b/host/tools/configtool/standalone/wxwin/bitmaps/package_closed_dis.bmp new file mode 100644 index 0000000000000000000000000000000000000000..dd371b13f08d367f26cc863989177ae23aa545ac GIT binary patch literal 246 zc${o7BoWV diff --git a/host/tools/configtool/standalone/wxwin/bitmaps/package_closed_dis.ico b/host/tools/configtool/standalone/wxwin/bitmaps/package_closed_dis.ico new file mode 100644 index 0000000000000000000000000000000000000000..50c24a8d3702f8896b9175c09a08f4ad0ae765b9 GIT binary patch literal 318 zc$}4vF%Ezr6hlj5f}2dvj@%GOj`ok@5xfDmpa}_Ku>J3se3k-^4k2(ahz{5RL=wnB wbe9Y>`qH&k9$=z0I{*Lx diff --git a/host/tools/configtool/standalone/wxwin/bitmaps/package_closed_dis.xpm b/host/tools/configtool/standalone/wxwin/bitmaps/package_closed_dis.xpm new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/bitmaps/package_closed_dis.xpm @@ -0,0 +1,23 @@ +/* XPM */ +static char * package_closed_dis_xpm[] = { +"16 16 4 1", +" c None", +". c Black", +"X c #c0c0c0", +"o c #808080", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ......... ", +" .XXXXXXXo. ", +" .......... ", +" .XXXXXX.o. ", +" .XXXXXX.o. ", +" .XXXXXX... ", +" ......... ", +" "}; diff --git a/host/tools/configtool/standalone/wxwin/bitmaps/package_open.bmp b/host/tools/configtool/standalone/wxwin/bitmaps/package_open.bmp new file mode 100644 index 0000000000000000000000000000000000000000..c0ea851a18aee560ceec45df0514d2ec8aec3cf4 GIT binary patch literal 246 zc$`IyI}(B+420Lm@Qq&j^Z^zKlq#miclaoO9)rQvaO$?|lft9RN3B sg(hdD)fw2o=jE|2U;GJKxUC8I1HNg*MLrWSZh-|qWF)R9YWH^c0opG%8UO$Q diff --git a/host/tools/configtool/standalone/wxwin/bitmaps/package_open.xpm b/host/tools/configtool/standalone/wxwin/bitmaps/package_open.xpm new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/bitmaps/package_open.xpm @@ -0,0 +1,28 @@ +/* XPM */ +static char * package_open_xpm[] = { +"16 16 9 1", +" c None", +". c Black", +"X c Red", +"o c Blue", +"O c #008000", +"+ c #c0c0c0", +"@ c Gray100", +"# c Yellow", +"$ c #808000", +" ", +" ....", +" . . .XX.", +" .o. .O. .XX.", +".ooo. .OO. ....", +" .o. .O. ", +" . ", +" .. ", +" .+.......... ", +" .++++++.++. ", +" .......... ", +" .@#@#@#.$. ", +" .#@#@#@.$. ", +" .@#@#@#... ", +" ......... ", +" "}; diff --git a/host/tools/configtool/standalone/wxwin/bitmaps/package_open_dis.bmp b/host/tools/configtool/standalone/wxwin/bitmaps/package_open_dis.bmp new file mode 100644 index 0000000000000000000000000000000000000000..f2eb11b56ad2c2d88bf29e9590395ba71ea46733 GIT binary patch literal 246 zc$`g5ITC;%42&~QC~O>G;XCa80~Ixuv^w-G#q0r2VDDIDZS@Qs zn_*}&6pA?;(eWvzfLW>SNv%e7mJq@;?oqHyDN5)3<94X$NrR6z;B{{BL_~+OOMOxi N%Uujg9o%n?nGbrHJ(B!$x?C&-Fc?6z3$V_YtwNz(!+Wa#r diff --git a/host/tools/configtool/standalone/wxwin/bitmaps/package_open_dis.xpm b/host/tools/configtool/standalone/wxwin/bitmaps/package_open_dis.xpm new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/bitmaps/package_open_dis.xpm @@ -0,0 +1,23 @@ +/* XPM */ +static char * package_open_dis_xpm[] = { +"16 16 4 1", +" c None", +". c Black", +"X c #c0c0c0", +"o c #808080", +" ", +" ....", +" . . .XX.", +" .X. .X. .XX.", +".XXX. .XX. ....", +" .X. .X. ", +" . ", +" .. ", +" .X.......... ", +" .XXXXXX.XX. ", +" .......... ", +" .XXXXXX.o. ", +" .XXXXXX.o. ", +" .XXXXXX... ", +" ......... ", +" "}; diff --git a/host/tools/configtool/standalone/wxwin/bitmaps/package_version.bmp b/host/tools/configtool/standalone/wxwin/bitmaps/package_version.bmp new file mode 100644 index 0000000000000000000000000000000000000000..00011822b5748d84bd7a3a3b7e82d2d1ba06f4eb GIT binary patch literal 246 zc$`g)u?<2o3`C6t`bbd}^rv7BdUm0r&PeXlWCSnZ9a7PTyO=Lw=knsSl6>U-Ady&v*hKXyOy_W@1d8wwtU6ZJ7=o3KW2eUP@uy zV4i>jfSD-7i7?%);h$9>s5Qu(lhzv96!ihsAaj!}eA!O*Vx03BE2nMV8w)uPq~5(w xlK7@B(v6dd3$o^MYNQl?cCNQ*?M*xhyZFAmwem0Oalx6|m1``15HIf^_yBK5MUemi diff --git a/host/tools/configtool/standalone/wxwin/bitmaps/package_version.xpm b/host/tools/configtool/standalone/wxwin/bitmaps/package_version.xpm new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/bitmaps/package_version.xpm @@ -0,0 +1,26 @@ +/* XPM */ +static char * package_version_xpm[] = { +"16 16 7 1", +" c None", +". c Black", +"X c Magenta", +"o c #c0c0c0", +"O c Gray100", +"+ c #800080", +"@ c #808080", +" ", +" . ", +" .X. ", +" .XXX. ", +" .XXXXX. ", +" .XXXXXXX. ", +" ..XXXXXXX. ", +" .X.XXXXX.. ", +" .XX.XXX....... ", +" .XX.X..oOOOOo.", +" .XX.+.O.@.OO.", +" .X.+.O.@O.O.", +" ....O.OO.O.", +" . .O.OO.O.", +" .oOOOOo.", +" ...... "}; diff --git a/host/tools/configtool/standalone/wxwin/bitmaps/paste.bmp b/host/tools/configtool/standalone/wxwin/bitmaps/paste.bmp new file mode 100644 index 0000000000000000000000000000000000000000..564f514e0df7225f0a7adbe8457b41af537813bd GIT binary patch literal 238 zc${^OF%E+;3`Kt>BqA}i$KV*Kvc!aP6{eaoV~)elk`wg`>9+&j_|Er>zZB=ae9`ow zNBTuS=?6N`H{2=tK}ro)yp&Q%OR68#+F)f7o2m*muR!EHhn%BGbpGck=X~X&B%e)2 YDrvB9f{`1IdBDz`dk>&zxO%_z11us%B>(^b diff --git a/host/tools/configtool/standalone/wxwin/bitmaps/paste.xpm b/host/tools/configtool/standalone/wxwin/bitmaps/paste.xpm new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/bitmaps/paste.xpm @@ -0,0 +1,27 @@ +/* XPM */ +static char *paste_xpm[] = { +/* columns rows colors chars-per-pixel */ +"16 15 6 1", +" c None", +". c Black", +"X c Yellow", +"o c #808080", +"O c #000080", +"+ c Gray100", +/* pixels */ +" ", +" .... ", +" .....XX..... ", +".ooo.X..X.ooo. ", +".oo. .oo. ", +".oo........oo. ", +".oooooooooooo. ", +".oooooOOOOOOO. ", +".oooooO+++++OO ", +".oooooO+++++O+O ", +".oooooO+OOO+OOO ", +".oooooO+++++++O ", +".oooooO+OOOOO+O ", +" .....O+++++++O ", +" OOOOOOOOO " +}; diff --git a/host/tools/configtool/standalone/wxwin/bitmaps/preview.bmp b/host/tools/configtool/standalone/wxwin/bitmaps/preview.bmp new file mode 100644 index 0000000000000000000000000000000000000000..da1f4dbc4be6c2dd8fb9d7cb71cc48a4a7c139ca GIT binary patch literal 238 zc${^OyA8uI3`7|q0M$8TWRCRS#g$JbyNo4m6IX^eP>!S<7bbanx`RHSd6%q}dQ&fI zq8{>$yvkj*7-=ox%}wuJ%#6v1kueh99{CalnP|qb1Vv2A<68^Jg3X+Yx&(j8ve(FY SPLcP3deiG)Ou?$f>abfQx?D0Tu*oVsozJL+~nP_3^%>SJ3{R0J|~o0;1HM8ti# NGZvlElEz!I^ab^fN{Rpg diff --git a/host/tools/configtool/standalone/wxwin/bitmaps/properties.xpm b/host/tools/configtool/standalone/wxwin/bitmaps/properties.xpm new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/bitmaps/properties.xpm @@ -0,0 +1,22 @@ +/* XPM */ +static char *properties_xpm[] = { +"16 15 4 1", +" c None", +". c Black", +"X c #000080", +"o c Gray100", +" ", +" ...... XX", +" . .XX", +" . . XX", +"..... . . XX", +".oo. . . . .XX", +".o. .o. . ... XX", +".o..ooo. .o. ", +".ooooooo.oo. ", +".oooooooooo. ", +".o..o.....o. ", +".oooooooooo. ", +".o..o.....o. ", +".oooooooooo. ", +"............ "}; diff --git a/host/tools/configtool/standalone/wxwin/bitmaps/radiooff.bmp b/host/tools/configtool/standalone/wxwin/bitmaps/radiooff.bmp new file mode 100644 index 0000000000000000000000000000000000000000..bb2594babcbab2266e48744b4e3307873fec79df GIT binary patch literal 246 zc${`NJ>o=tVDL;S`Fdv_ z;0esGTof)aSs{J!UT8l)s3 K)q^SheD(k{xJRJ? diff --git a/host/tools/configtool/standalone/wxwin/bitmaps/radioon.ico b/host/tools/configtool/standalone/wxwin/bitmaps/radioon.ico new file mode 100644 index 0000000000000000000000000000000000000000..1ae4d3ab049b3e03f84001af919bfe29147a57f2 GIT binary patch literal 318 zc${^PI}XAy5JX=jq|o7tnle2H;7XAw+`7!M+|fi_f+8&kKr%CSQbG3jM&q??=#(J@ z%>zRRXJAkV^+j#pk=ct>i(^b diff --git a/host/tools/configtool/standalone/wxwin/bitmaps/radioon_dis.ico b/host/tools/configtool/standalone/wxwin/bitmaps/radioon_dis.ico new file mode 100644 index 0000000000000000000000000000000000000000..8a6f5e846e4d5347f1a8825f9e47941f0b6a4901 GIT binary patch literal 318 zc${^PyA8uI3`EaJ0K1E-)Gob+S4yXp?4q$aN=C>42IM<2DvUTJPmefJA7Egnl(=58 z48R@0LM3XZ3wERZSU$kZtALJOc{CsJ{aw$iK-{&UX eL!z`&Q%)X>e*oJGd~U#d4Eg1#?rTP~{oD?rSU~y! diff --git a/host/tools/configtool/standalone/wxwin/bitmaps/radioon_dis.xpm b/host/tools/configtool/standalone/wxwin/bitmaps/radioon_dis.xpm new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/bitmaps/radioon_dis.xpm @@ -0,0 +1,23 @@ +/* XPM */ +static char * radioon_dis_xpm[] = { +"16 16 4 1", +" c None", +". c #808080", +"X c Black", +"o c #c0c0c0", +" ", +" ", +" .... ", +" ..XXXX.. ", +" .XXooooXXo ", +" .Xoooooooo ", +" .Xooo..ooooo ", +" .Xoo....oooo ", +" .Xoo....oooo ", +" .Xooo..ooooo ", +" .Xoooooooo ", +" .ooooooooo ", +" oooooooo ", +" oooo ", +" ", +" "}; diff --git a/host/tools/configtool/standalone/wxwin/bitmaps/redo.bmp b/host/tools/configtool/standalone/wxwin/bitmaps/redo.bmp new file mode 100644 index 0000000000000000000000000000000000000000..5877e34e00515f81b063a0efece347301fcea5b5 GIT binary patch literal 238 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

eXUw7i>af{KDHuaz2|u_%2UuPO=O!zMT4z$$ zAe?FI78Ki2@NT-Sj>IAK8bGZSj45vlBEX}8eRK^kc$)EQm+ES*Y(ZUPc*LpOL8HCK z)4glZHFeM8+Fy)H!CDB5B0=!J@Cr()M?fKEj8nh&$DImCLJ@7lTkVVpX@6IU=ar&y z>-6;XJu^I|n#L-wOC>J!eoW}I3HM8#BDh(jkDj|vt$U#RvSI1|EE WR(Lpw)K7r^!cf=j+AFjx_CEj{#Yp=A diff --git a/host/tools/configtool/standalone/wxwin/bitmaps/stopbuild.bmp b/host/tools/configtool/standalone/wxwin/bitmaps/stopbuild.bmp new file mode 100644 index 0000000000000000000000000000000000000000..71f42f1db7d7de0e25b4dfbdde6fb309bb2f8786 GIT binary patch literal 238 zc$_^>u@QtY3^RA!rJ#6BLq_;H=zka*Oc^RORwnutf^2hxRkim7+B>2mO?qR diff --git a/host/tools/configtool/standalone/wxwin/bitmaps/stopbuild.xpm b/host/tools/configtool/standalone/wxwin/bitmaps/stopbuild.xpm new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/bitmaps/stopbuild.xpm @@ -0,0 +1,22 @@ +/* XPM */ +static char *stopbuild_xpm[] = { +"16 15 4 1", +" c None", +". c #800000", +"X c #808080", +"o c Black", +" ..X ", +" ..XX ", +" ...X ..XX ", +" X....XX ", +" X...X ", +" X.... ", +" ..XX.. ", +" ..XX .. ", +"oooo..Xoooo.ooo ", +"o .X o ", +"o o X o o o o o ", +"o o ", +"o o o o o o o o ", +"o o ", +"ooooooooooooooo "}; diff --git a/host/tools/configtool/standalone/wxwin/bitmaps/text.bmp b/host/tools/configtool/standalone/wxwin/bitmaps/text.bmp new file mode 100644 index 0000000000000000000000000000000000000000..8794afd9f3c9bda4992bca9da966af3db48e96c7 GIT binary patch literal 246 zc${U7yA6Oa3`C8D5E2ccUPZp^yd*EFdQ>ddnbQA+a8w# QR|@(27@die>HQUY08}7D(EtDd diff --git a/host/tools/configtool/standalone/wxwin/bitmaps/text.ico b/host/tools/configtool/standalone/wxwin/bitmaps/text.ico new file mode 100644 index 0000000000000000000000000000000000000000..5b02debd688c0ef52b0eaf3b9a59e66cbfc00867 GIT binary patch literal 318 zc${^QF%AMD5Jew}Q7QwCrLi(wdIEcIq45+}OS#A5D4s!MEB=A7#=@C-d}d%K08So4 z(7Ir7umJ`U#7rF5)Jx%EzNPh?jV(aaF&=2RcGCCIA2c diff --git a/host/tools/configtool/standalone/wxwin/bitmaps/text.xpm b/host/tools/configtool/standalone/wxwin/bitmaps/text.xpm new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/bitmaps/text.xpm @@ -0,0 +1,23 @@ +/* XPM */ +static char * text_xpm[] = { +"16 16 4 1", +" c None", +". c #808080", +"X c #800000", +"o c Black", +" ", +"............. ", +". .. ", +". . . ", +". XX .ooo", +". XX o", +". XXX XXXX o", +". XX XX XX o", +". XXXX XX XX o", +". XX XX XX XX o", +". XXXXXXXXX o", +". o", +". o", +". o", +".oo .oooo. o", +" .oooo o. o"}; diff --git a/host/tools/configtool/standalone/wxwin/bitmaps/text_dis.bmp b/host/tools/configtool/standalone/wxwin/bitmaps/text_dis.bmp new file mode 100644 index 0000000000000000000000000000000000000000..37f775c2c452d63233e407d3daa513806414ef51 GIT binary patch literal 246 zc${U6F%H8p2t}z>DV4fZIYrKqz1Kh)GZl|a4#)DTx;h`IyX3?7Gkkk}e<}5W7x?w_ zjqb5mcz&iwMkDc1HQ|LzYYp^GkEY%eUcSP?8xiwk*GUS|u^$q;vKRzf@%A|>|5+l( QW0OIp{9kL**g}0;A5d`9S|e5Indp5$p^}zG{mbUFRbbzCOZ~D2MMhQXJZR_H@}7^w bzI2R!_rXA<{QUXxz8vbm9`uc#a~ymClNC+( diff --git a/host/tools/configtool/standalone/wxwin/bitmaps/text_dis.xpm b/host/tools/configtool/standalone/wxwin/bitmaps/text_dis.xpm new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/bitmaps/text_dis.xpm @@ -0,0 +1,23 @@ +/* XPM */ +static char * text_dis_xpm[] = { +"16 16 4 1", +" c None", +". c #808080", +"X c #c0c0c0", +"o c Black", +" ", +"............. ", +".XXXXXXXXXXX.. ", +".XXXXXXXXXXX. . ", +".XXXXXXX..XX.ooo", +".XXXXXXX..XXXXXo", +".XX...XX....XXXo", +".XXXX..X..X..XXo", +".XX....X..X..XXo", +".X..X..X..X..XXo", +".XX.........XXXo", +".XXXXXXXXXXXXXXo", +".XXXXXXXXXXXXXXo", +".XXXXXXXXXXXXXXo", +".ooXXXX.oooo.XXo", +" .oooo o.Xo"}; diff --git a/host/tools/configtool/standalone/wxwin/bitmaps/unchecked.bmp b/host/tools/configtool/standalone/wxwin/bitmaps/unchecked.bmp new file mode 100644 index 0000000000000000000000000000000000000000..d8e79160ea51f3bae009eaed2d3b01d0849746dd GIT binary patch literal 246 zc${00fFkuK)l5 diff --git a/host/tools/configtool/standalone/wxwin/bitmaps/unchecked.ico b/host/tools/configtool/standalone/wxwin/bitmaps/unchecked.ico new file mode 100644 index 0000000000000000000000000000000000000000..ccd08a57668eaf7ea10c8d1f0a2f77df3704f35e GIT binary patch literal 318 zc$}?Hu?>JQ408n%YbIvKe#qJl&dLWI)S=joSU`vcJB}+WZ386I%-Bcd1k3<3Wz<3` w7aVUWy--S+$b-Anm9$=HElgCTcE`2~@gAoCeD8RC7khBm0XXWnG$&p6P6psRa{vGU diff --git a/host/tools/configtool/standalone/wxwin/bitmaps/unchecked.xpm b/host/tools/configtool/standalone/wxwin/bitmaps/unchecked.xpm new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/bitmaps/unchecked.xpm @@ -0,0 +1,23 @@ +/* XPM */ +static char * unchecked_xpm[] = { +"16 16 4 1", +" c None", +". c #808080", +"X c Black", +"o c #c0c0c0", +" ", +" ", +" ............ ", +" .XXXXXXXXXXo ", +" .X o ", +" .X o ", +" .X o ", +" .X o ", +" .X o ", +" .X o ", +" .X o ", +" .X o ", +" .X o ", +" .ooooooooooo ", +" ", +" "}; diff --git a/host/tools/configtool/standalone/wxwin/bitmaps/unchecked_dis.bmp b/host/tools/configtool/standalone/wxwin/bitmaps/unchecked_dis.bmp new file mode 100644 index 0000000000000000000000000000000000000000..643d57b6a6aced890867189685fce995e9ae61da GIT binary patch literal 246 zc${JQ408n%YbIvKe#n{)&dO)0-HHXofP@{#m8GNs3TbBSGim`=0F^Roqm&DQ rH+V0&4-@%_2)dH&h0I~1BDFh?UEq?xTuT?=?09@P?%=J{H(hfLY;i{5 diff --git a/host/tools/configtool/standalone/wxwin/bitmaps/unchecked_dis.xpm b/host/tools/configtool/standalone/wxwin/bitmaps/unchecked_dis.xpm new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/bitmaps/unchecked_dis.xpm @@ -0,0 +1,23 @@ +/* XPM */ +static char * unchecked_dis_xpm[] = { +"16 16 4 1", +" c None", +". c #808080", +"X c Black", +"o c #c0c0c0", +" ", +" ", +" ............ ", +" .XXXXXXXXXXo ", +" .Xoooooooooo ", +" .Xoooooooooo ", +" .Xoooooooooo ", +" .Xoooooooooo ", +" .Xoooooooooo ", +" .Xoooooooooo ", +" .Xoooooooooo ", +" .Xoooooooooo ", +" .Xoooooooooo ", +" .ooooooooooo ", +" ", +" "}; diff --git a/host/tools/configtool/standalone/wxwin/bitmaps/undo.bmp b/host/tools/configtool/standalone/wxwin/bitmaps/undo.bmp new file mode 100644 index 0000000000000000000000000000000000000000..4ad80c772f8f5281500707222f552d634a9c027a GIT binary patch literal 238 zc${GetBuildInfo().entries) + +{ + SetExtraStyle(wxDIALOG_EX_CONTEXTHELP); + + ecDialog::Create(parent, ecID_BUILD_OPTIONS_DIALOG, _("Build Options"), + wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER); + + CreateControls(this); + + m_imageList.Add(wxICON(package_open)); + m_imageList.Add(wxICON(package_version)); + m_treeCtrl->SetImageList(& m_imageList); + +#if 0 + // Add some dummy items + wxTreeItemId rootId = m_treeCtrl->AddRoot(_("Configuration"), 0, -1); + m_treeCtrl->AppendItem(rootId, _("eCos HAL"), 0, -1); + m_treeCtrl->AppendItem(rootId, _("I/O sub-system"), 0, -1); + m_treeCtrl->AppendItem(rootId, _("Serial device drivers"), 0, -1); + m_treeCtrl->AppendItem(rootId, _("Infrastructure"), 0, -1); + m_treeCtrl->AppendItem(rootId, _("eCos kernel"), 0, -1); + m_treeCtrl->AppendItem(rootId, _("C library"), 0, -1); + + m_treeCtrl->Expand(rootId); +#endif + + Centre(wxBOTH); +} + +ecBuildOptionsDialog::~ecBuildOptionsDialog() +{ + m_treeCtrl->SetImageList(NULL); +} + +void ecBuildOptionsDialog::OnInitDialog(wxInitDialogEvent& event) +{ + m_treeCtrl->DeleteAllItems(); + //wxTreeItemId rootId = m_treeCtrl->AddRoot(_("Configuration"), 0, -1); + CreateItems(wxGetApp().GetConfigToolDoc()->GetFirstItem(), wxTreeItemId()); + + m_treeCtrl->Expand(m_treeCtrl->GetRootItem()); + ((wxChoice*) FindWindow(ecID_BUILD_OPTIONS_CATEGORY))->SetSelection(0); +} + +void ecBuildOptionsDialog::CreateControls(wxWindow* parent) +{ + m_treeCtrl = new wxTreeCtrl(parent, ecID_BUILD_OPTIONS_PACKAGES_TREE, + wxDefaultPosition, wxSize(280, 220), wxTR_HAS_BUTTONS | wxSUNKEN_BORDER); + + wxSizer *item0 = new wxBoxSizer( wxVERTICAL ); + + wxSizer *item1 = new wxBoxSizer( wxHORIZONTAL ); + + wxStaticText *item2 = new wxStaticText( parent, wxID_STATIC, _("&Category:"), wxDefaultPosition, wxDefaultSize, 0 ); + item1->Add( item2, 0, wxALIGN_CENTRE|wxALL, 5 ); + + wxString strs3[] = + { + _("CFLAGS"), + _("LDFLAGS") + }; + wxChoice *item3 = new wxChoice( parent, ecID_BUILD_OPTIONS_CATEGORY, wxDefaultPosition, wxSize(90,-1), 2, strs3, 0 ); + item1->Add( item3, 0, wxALIGN_CENTRE|wxALL, 5 ); + + item1->Add( 20, 20, 20, wxALIGN_CENTRE|wxALL, 5 ); + + wxButton *item4 = new wxButton( parent, wxID_OK, _("&Close"), wxDefaultPosition, wxDefaultSize, 0 ); + item4->SetDefault(); + item1->Add( item4, 0, wxALIGN_CENTRE|wxALL, 5 ); + + item0->Add( item1, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + wxSizer *item5 = new wxBoxSizer( wxHORIZONTAL ); + + wxSizer *item6 = new wxBoxSizer( wxVERTICAL ); + + wxStaticText *item7 = new wxStaticText( parent, wxID_STATIC, _("&Packages:"), wxDefaultPosition, wxDefaultSize, 0 ); + item6->Add( item7, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + wxWindow *item8 = parent->FindWindow( ecID_BUILD_OPTIONS_PACKAGES_TREE ); + wxASSERT( item8 ); + item6->Add( item8, 10, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + item5->Add( item6, 0, wxGROW|wxALIGN_CENTER_HORIZONTAL|wxALL, 0 ); + + wxSizer *item9 = new wxBoxSizer( wxVERTICAL ); + + wxStaticText *item10 = new wxStaticText( parent, wxID_STATIC, _("&Flags:"), wxDefaultPosition, wxDefaultSize, 0 ); + item9->Add( item10, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + wxString *strs11 = (wxString*) NULL; + wxListBox *item11 = new wxListBox( parent, ecID_BUILD_OPTIONS_FLAGS, wxDefaultPosition, wxSize(170,240), 0, strs11, 0 ); + item9->Add( item11, 1, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + item5->Add( item9, 1, wxGROW|wxALIGN_CENTER_HORIZONTAL|wxALL, 0 ); + + item0->Add( item5, 1, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + +#if 0 + wxSizer *item0 = new wxBoxSizer( wxVERTICAL ); + + wxSizer *item1 = new wxBoxSizer( wxHORIZONTAL ); + + wxStaticText *item2 = new wxStaticText( parent, wxID_STATIC, _("&Category:"), wxDefaultPosition, wxDefaultSize, 0 ); + item1->Add( item2, 0, wxALIGN_CENTRE|wxALL, 5 ); + + wxString strs3[] = + { + _("CFLAGS"), + _("LDFLAGS") + }; + wxChoice *item3 = new wxChoice( parent, ecID_BUILD_OPTIONS_CATEGORY, wxDefaultPosition, wxSize(90,-1), 2, strs3, 0 ); + item1->Add( item3, 0, wxALIGN_CENTRE|wxALL, 5 ); + + item1->Add( 20, 20, 20, wxALIGN_CENTRE|wxALL, 5 ); + + wxButton *item4 = new wxButton( parent, wxID_OK, _("&Close"), wxDefaultPosition, wxDefaultSize, 0 ); + item4->SetDefault(); + item1->Add( item4, 0, wxALIGN_CENTRE|wxALL, 5 ); + + item0->Add( item1, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + wxSizer *item5 = new wxBoxSizer( wxHORIZONTAL ); + + wxSizer *item6 = new wxBoxSizer( wxVERTICAL ); + + wxStaticText *item7 = new wxStaticText( parent, wxID_STATIC, _("&Packages:"), wxDefaultPosition, wxDefaultSize, 0 ); + item6->Add( item7, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + wxWindow *item8 = parent->FindWindow( ecID_BUILD_OPTIONS_PACKAGES_TREE ); + wxASSERT( item8 ); + item6->Add( item8, 10, wxALIGN_CENTRE|wxALL, 5 ); + + item5->Add( item6, 0, wxGROW|wxALIGN_CENTER_HORIZONTAL|wxALL, 0 ); + + wxSizer *item9 = new wxBoxSizer( wxVERTICAL ); + + wxStaticText *item10 = new wxStaticText( parent, wxID_STATIC, _("&Flags:"), wxDefaultPosition, wxDefaultSize, 0 ); + item9->Add( item10, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + wxString *strs11 = (wxString*) NULL; + wxListBox *item11 = new wxListBox( parent, ecID_BUILD_OPTIONS_FLAGS, wxDefaultPosition, wxSize(170,240), 0, strs11, 0 ); + item9->Add( item11, 0, wxALIGN_CENTRE|wxALL, 5 ); + + item5->Add( item9, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 0 ); + + item0->Add( item5, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); +#endif + +#ifdef __WXGTK__ + wxButton *contextButton = new wxContextHelpButton( parent ); + item1->Add( contextButton, 0, wxALIGN_CENTRE|wxALL, 5 ); +#endif + + parent->SetAutoLayout( TRUE ); + parent->SetSizer( item0 ); + parent->Layout(); + item0->Fit( parent ); + item0->SetSizeHints( parent ); + + // Add context-sensitive help text + parent->FindWindow( ecID_BUILD_OPTIONS_CATEGORY )->SetHelpText(_("Selects the categorty of build flags for which options are to be displayed.")); + parent->FindWindow( ecID_BUILD_OPTIONS_PACKAGES_TREE )->SetHelpText(_("Displays a view of the packages currently included in the configuration.")); + parent->FindWindow( ecID_BUILD_OPTIONS_FLAGS )->SetHelpText(_("Lists the flags defined for the packages selected in the adjacent Packages window.")); + parent->FindWindow( wxID_OK )->SetHelpText(_("Closes the dialog and saves any changes you have made.")); + parent->FindWindow( wxID_CANCEL )->SetHelpText(_("Closes the dialog without saving any changes you have made.")); + +#if __WXGTK__ + parent->FindWindow( wxID_CONTEXT_HELP )->SetHelpText(_("Invokes context-sensitive help for the clicked-on window.")); +#endif + +} + +void ecBuildOptionsDialog::OnCancel(wxCommandEvent& event) +{ + event.Skip(); +} + +void ecBuildOptionsDialog::OnOK(wxCommandEvent& event) +{ + event.Skip(); +} + +void ecBuildOptionsDialog::CreateItems(ecConfigItem *pti, wxTreeItemId hParent) +{ + if (pti->IsPackage() || !hParent.IsOk()) + { + wxTreeItemId h; + + if (!hParent.IsOk()) // pti->GetItemNameOrMacro() == _("Configuration")) + h = m_treeCtrl->AddRoot(pti->GetItemNameOrMacro(), 0, -1); + else + h = m_treeCtrl->AppendItem(hParent, pti->GetItemNameOrMacro(), 0, -1); + + m_treeCtrl->SetItemData(h, new ecBuildOptionsData(pti)); + // m_Tree.SetItemImage(h,18,18); + for(ecConfigItem *pChild=pti->FirstChild();pChild;pChild=pChild->NextSibling()){ + CreateItems(pChild,h); + } + } +} + +void ecBuildOptionsDialog::Redisplay (wxTreeItemId item) +{ + ecConfigItem *pti= ((ecBuildOptionsData*) m_treeCtrl->GetItemData(item))->GetConfigItem(); + + const CdlValuable valuable = pti->GetCdlValuable(); + std::string name; + const CdlBuildInfo_Loadable *pe=NULL; + if(valuable){ + const char *pszname=valuable->get_name().c_str(); + for(EntriesArray::size_type j=0;jGetStringSelection(); + + const wxString strFlags=get_flags(wxGetApp().GetConfigToolDoc()->GetCdlConfig(), pe, ecUtils::UnicodeToStdStr(strCat)).c_str(); + + wxArrayString ar; + ecUtils::Chop(strFlags,ar, wxT(' '), FALSE, FALSE); + + wxListBox* listBox = (wxListBox*) FindWindow( ecID_BUILD_OPTIONS_FLAGS ); + + wxString strEdit; + bool bRedraw=(listBox->Number() != ar.GetCount()); + if(!bRedraw) + { + for(int i=0;iGetString(i); + + if(strOld!=ar[i]) + { + bRedraw = TRUE; + break; + } + } + } + if(bRedraw){ + listBox->Clear(); + for(int i=0;iAppend(ar[i]); + } + } +} + +void ecBuildOptionsDialog::OnSelCategory(wxCommandEvent& event) +{ + wxTreeItemId item = m_treeCtrl->GetSelection(); + if (item.IsOk()) + { + Redisplay(item); + } +} + +void ecBuildOptionsDialog::OnSelTree(wxTreeEvent& event) +{ + wxTreeItemId item = m_treeCtrl->GetSelection(); + if (item.IsOk()) + { + Redisplay(item); + } +} diff --git a/host/tools/configtool/standalone/wxwin/buildoptionsdlg.h b/host/tools/configtool/standalone/wxwin/buildoptionsdlg.h new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/buildoptionsdlg.h @@ -0,0 +1,104 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +// buildoptionsdlg.h : +// +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): julians +// Contact(s): julians +// Date: 2000/09/27 +// Version: $Id: buildoptionsdlg.h,v 1.2 2001/03/23 13:38:04 julians Exp $ +// Purpose: +// Description: Header file for ecBuildOptionsDialog +// Requires: +// Provides: +// See also: +// Known bugs: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== + +#ifndef _ECOS_BUILDOPTIONSDLG_H_ +#define _ECOS_BUILDOPTIONSDLG_H_ + +#ifdef __GNUG__ +#pragma interface "buildoptionsdlg.cpp" +#endif + +#include "wx/treectrl.h" +#include "ecutils.h" + +class ecBuildOptionsDialog : public ecDialog +{ +public: +// Ctor(s) + ecBuildOptionsDialog(wxWindow* parent); + ~ecBuildOptionsDialog(); + +//// Event handlers + + void OnOK(wxCommandEvent& event); + void OnCancel(wxCommandEvent& event); + void OnSelCategory(wxCommandEvent& event); + void OnSelTree(wxTreeEvent& event); + void OnInitDialog(wxInitDialogEvent& event); + +//// Operations + void CreateControls(wxWindow* parent); + void Redisplay (wxTreeItemId item); + void CreateItems(ecConfigItem *pti, wxTreeItemId hParent); + +protected: + wxTreeCtrl* m_treeCtrl; + wxImageList m_imageList; + + typedef std::vector EntriesArray; + const EntriesArray& m_arEntries; +private: + DECLARE_EVENT_TABLE() +}; + +class ecBuildOptionsData : public wxTreeItemData +{ +public: + ecBuildOptionsData(ecConfigItem* item) : m_configItem(item) { } + + ecConfigItem *GetConfigItem() const { return m_configItem; } + void SetConfigItem(ecConfigItem *item) { m_configItem = item; } + +private: + ecConfigItem* m_configItem; +}; + + +#define ecID_BUILD_OPTIONS_CATEGORY 10054 +#define ecID_BUILD_OPTIONS_PACKAGES_TREE 11000 +#define ecID_BUILD_OPTIONS_FLAGS 10055 + +#endif + // _ECOS_BUILDOPTIONSDLG_H_ diff --git a/host/tools/configtool/standalone/wxwin/choosereposdlg.cpp b/host/tools/configtool/standalone/wxwin/choosereposdlg.cpp new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/choosereposdlg.cpp @@ -0,0 +1,220 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +// choosereposdlg.cpp : +// +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): julians +// Contact(s): julians +// Date: 2000/10/02 +// Version: $Id: choosereposdlg.cpp,v 1.2 2001/03/23 13:38:04 julians Exp $ +// Purpose: +// Description: Implementation file for ecChooseRepositoryDialog +// Requires: +// Provides: +// See also: +// Known bugs: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== + +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- +#ifdef __GNUG__ +#pragma implementation "choosereposdlg.h" +#endif + +// Includes other headers for precompiled compilation +#include "ecpch.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#include "wx/cshelp.h" +#include "wx/dirdlg.h" +#include "wx/valgen.h" + +#include "configtool.h" +#include "configtooldoc.h" +#include "choosereposdlg.h" + +BEGIN_EVENT_TABLE(ecChooseRepositoryDialog, ecDialog) + EVT_BUTTON(ecID_CHOOSE_REPOSITORY_BROWSE, ecChooseRepositoryDialog::OnBrowse) + EVT_BUTTON(wxID_OK, ecChooseRepositoryDialog::OnOK) + EVT_BUTTON(wxID_CANCEL, ecChooseRepositoryDialog::OnCancel) +END_EVENT_TABLE() + +// ---------------------------------------------------------------------------- +// main frame +// ---------------------------------------------------------------------------- + +// Frame constructor +ecChooseRepositoryDialog::ecChooseRepositoryDialog(wxWindow* parent) +{ + SetExtraStyle(wxDIALOG_EX_CONTEXTHELP); + + ecDialog::Create(parent, ecID_CHOOSE_REPOSITORY_DIALOG, _("Choose folder for eCos repository"), + wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER); + + CreateControls(this); + + Centre(wxBOTH); +} + +void ecChooseRepositoryDialog::CreateControls(wxWindow* parent) +{ + wxSizer *item0 = new wxBoxSizer( wxHORIZONTAL ); + + wxSizer *item1 = new wxBoxSizer( wxVERTICAL ); + + wxStaticText *item2 = new wxStaticText( parent, wxID_STATIC, _("Please specify the root of the eCos repository tree."), wxDefaultPosition, wxDefaultSize, 0 ); + item1->Add( item2, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + item1->Add( 20, 20, 1, wxALIGN_CENTRE|wxALL, 5 ); + + wxTextCtrl *item3 = new wxTextCtrl( parent, ecID_CHOOSE_REPOSITORY_TEXT, _(""), wxDefaultPosition, wxSize(320,-1), 0 ); + item1->Add( item3, 1, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 ); + + item0->Add( item1, 1, wxALIGN_CENTRE|wxALL, 5 ); + + wxSizer *item4 = new wxBoxSizer( wxVERTICAL ); + + wxButton *item5 = new wxButton( parent, wxID_OK, _("&OK"), wxDefaultPosition, wxDefaultSize, 0 ); + item4->Add( item5, 0, wxALIGN_CENTRE|wxALL, 5 ); + + wxButton *item6 = new wxButton( parent, wxID_CANCEL, _("&Cancel"), wxDefaultPosition, wxDefaultSize, 0 ); + item4->Add( item6, 0, wxALIGN_CENTRE|wxALL, 5 ); + + wxButton *item7 = new wxButton( parent, ecID_CHOOSE_REPOSITORY_BROWSE, _("&Browse..."), wxDefaultPosition, wxDefaultSize, 0 ); + item4->Add( item7, 0, wxALIGN_CENTRE|wxALL, 5 ); + + item0->Add( item4, 0, wxALIGN_CENTRE|wxALL, 5 ); + +#if 0 + wxSizer *item0 = new wxBoxSizer( wxHORIZONTAL ); + + wxSizer *item1 = new wxBoxSizer( wxVERTICAL ); + + wxStaticText *item2 = new wxStaticText( parent, wxID_STATIC, "Please specify the root of the eCos repository tree.", wxDefaultPosition, wxDefaultSize, 0 ); + item1->Add( item2, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + item1->Add( 20, 20, 1, wxALIGN_CENTRE|wxALL, 5 ); + + wxTextCtrl *item3 = new wxTextCtrl( parent, ecID_CHOOSE_REPOSITORY_TEXT, "", wxDefaultPosition, wxSize(320,-1), 0 ); + item1->Add( item3, 1, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 ); + + item0->Add( item1, 0, wxALIGN_CENTRE|wxALL, 5 ); + + wxSizer *item4 = new wxBoxSizer( wxVERTICAL ); + + wxButton *item5 = new wxButton( parent, wxID_OK, "&OK", wxDefaultPosition, wxDefaultSize, 0 ); + item4->Add( item5, 0, wxALIGN_CENTRE|wxALL, 5 ); + item5->SetDefault(); + + wxButton *item6 = new wxButton( parent, wxID_CANCEL, "&Cancel", wxDefaultPosition, wxDefaultSize, 0 ); + item4->Add( item6, 0, wxALIGN_CENTRE|wxALL, 5 ); + + wxButton *item7 = new wxButton( parent, ecID_CHOOSE_REPOSITORY_BROWSE, "&Browse...", wxDefaultPosition, wxDefaultSize, 0 ); + item4->Add( item7, 0, wxALIGN_CENTRE|wxALL, 5 ); + +#ifdef __WXGTK__ + wxButton *contextButton = new wxContextHelpButton( parent ); + item4->Add( contextButton, 0, wxALIGN_CENTRE|wxALL, 5 ); +#endif + + item0->Add( item4, 0, wxALIGN_CENTRE|wxALL, 5 ); +#endif + +#ifdef __WXGTK__ + wxButton *contextButton = new wxContextHelpButton( parent ); + item4->Add( contextButton, 0, wxALIGN_CENTRE|wxALL, 5 ); +#endif + + parent->SetAutoLayout( TRUE ); + parent->SetSizer( item0 ); + parent->Layout(); + item0->Fit( parent ); + item0->SetSizeHints( parent ); + + parent->FindWindow( ecID_CHOOSE_REPOSITORY_TEXT)->SetFocus(); + + // Add context-sensitive help text + parent->FindWindow( ecID_CHOOSE_REPOSITORY_TEXT)->SetHelpText(_("Selects the repository folder.")); + parent->FindWindow( ecID_CHOOSE_REPOSITORY_BROWSE)->SetHelpText(_("Browse for the folder.")); + parent->FindWindow( wxID_OK )->SetHelpText(_("Closes the dialog and loads the selected repository.")); + parent->FindWindow( wxID_CANCEL )->SetHelpText(_("Closes the dialog without loading a repository.")); + + // Add validators + parent->FindWindow( ecID_CHOOSE_REPOSITORY_TEXT)->SetValidator(wxGenericValidator(& wxGetApp().GetConfigToolDoc()->m_strRepository)); + +#if __WXGTK__ + parent->FindWindow( wxID_CONTEXT_HELP )->SetHelpText(_("Invokes context-sensitive help for the clicked-on window.")); +#endif +} + +void ecChooseRepositoryDialog::OnBrowse(wxCommandEvent& event) +{ + wxDirDialog dialog(this); + if (wxID_OK == dialog.ShowModal()) + { + wxString path = dialog.GetPath(); + ((wxTextCtrl*) FindWindow( ecID_CHOOSE_REPOSITORY_TEXT))->SetValue(path); + } +} + +void ecChooseRepositoryDialog::OnCancel(wxCommandEvent& event) +{ + event.Skip(); +} + +void ecChooseRepositoryDialog::OnOK(wxCommandEvent& event) +{ + wxString folder(GetFolder()); + if (!wxDirExists(folder)) + { + wxMessageBox(_("This is not a valid folder.")); + return; // Don't Skip so we don't dismiss the dialog + } + if (FALSE) + { + wxMessageBox(_("This does not like a valid eCos repository.")); + return; // Don't Skip so we don't dismiss the dialog + } + event.Skip(); +} + +wxString ecChooseRepositoryDialog::GetFolder() +{ + return ((wxTextCtrl*) FindWindow( ecID_CHOOSE_REPOSITORY_TEXT))->GetValue(); +} diff --git a/host/tools/configtool/standalone/wxwin/choosereposdlg.h b/host/tools/configtool/standalone/wxwin/choosereposdlg.h new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/choosereposdlg.h @@ -0,0 +1,82 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +// choosereposdlg.h : +// +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): julians +// Contact(s): julians +// Date: 2000/10/02 +// Version: $Id: choosereposdlg.h,v 1.2 2001/03/23 13:38:04 julians Exp $ +// Purpose: +// Description: Header file for ecChooseRepositoryDialog +// Requires: +// Provides: +// See also: +// Known bugs: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== + +#ifndef _ECOS_CHOOSEREPOSDLG_H_ +#define _ECOS_CHOOSEREPOSDLG_H_ + +#ifdef __GNUG__ +#pragma interface "choosereposdlg.cpp" +#endif + +#include "ecutils.h" + +class ecChooseRepositoryDialog : public ecDialog +{ +public: +// Ctor(s) + ecChooseRepositoryDialog(wxWindow* parent); + +//// Event handlers + + void OnBrowse(wxCommandEvent& event); + void OnOK(wxCommandEvent& event); + void OnCancel(wxCommandEvent& event); + +//// Operations + void CreateControls(wxWindow* parent); + + wxString GetFolder() ; + +protected: + +private: + DECLARE_EVENT_TABLE() +}; + +#define ecID_CHOOSE_REPOSITORY_TEXT 10089 +#define ecID_CHOOSE_REPOSITORY_BROWSE 10090 + +#endif + // _ECOS_CHOOSEREPOSDLG_H_ diff --git a/host/tools/configtool/standalone/wxwin/configitem.cpp b/host/tools/configtool/standalone/wxwin/configitem.cpp new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/configitem.cpp @@ -0,0 +1,1519 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +// configitem.cpp : +// +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): julians +// Contact(s): julians +// Date: 2000/09/01 +// Version: $Id: configitem.cpp,v 1.10 2001/04/30 17:12:32 julians Exp $ +// Purpose: +// Description: Implementation file for the ConfigTool application class +// Requires: +// Provides: +// See also: +// Known bugs: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== + +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- +#ifdef __GNUG__ + #pragma implementation "configitem.h" +#endif + +// Includes other headers for precompiled compilation +#include "ecpch.h" + +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + +#include "wx/settings.h" +#include "wx/valgen.h" + +#include "configitem.h" +#include "configtree.h" +#include "configtooldoc.h" +#include "configtoolview.h" +#include "ecutils.h" + +IMPLEMENT_CLASS(ecConfigItem, wxObject) + +/* + * ecConfigItem + * Represents a node in the configuration hierarchy. + * For every ecConfigItem, there is also an ecTreeItemData + * that points to it. + */ + +ecConfigItem::ecConfigItem(ecConfigItem* parent, const wxString& name, ecConfigType ctype, + ecOptionFlavor flavor, ecOptionType otype, + bool active, bool enabled, ecUIHint hint) +{ + m_CdlItem = NULL; + m_name = name; + m_configType = ctype; + m_optionType = otype; + m_optionFlavor = flavor; + m_enabled = enabled; + m_active = active; + m_parent = parent; + m_hint = hint; + m_treeItem = wxTreeItemId(); + + switch (otype) + { + case ecDouble: + { + m_value = 0.0; + break; + } + case ecString: + case ecEnumerated: + { + m_value = wxT(""); + break; + } + case ecLong: + { + m_value = (long) 0; + break; + } + case ecBool: + { + m_value = (bool) FALSE; + break; + } + default: + { + break; + } + } +} + +ecConfigItem::ecConfigItem(ecConfigItem* parent, CdlUserVisible vitem) +{ + m_name = wxT("UNNAMED"); + m_configType = ecConfigTypeNone; + m_optionType = ecOptionTypeNone; + m_optionFlavor = ecFlavorNone; + m_enabled = FALSE; + m_active = FALSE; + m_parent = parent; + m_CdlItem = vitem; + m_hint = ecHintNone; + m_treeItem = wxTreeItemId(); + + ecConfigTreeCtrl* treeCtrl = wxGetApp().GetTreeCtrl(); + m_treeItem = treeCtrl->AppendItem(parent->GetTreeItem(), m_name, -1, -1, new ecTreeItemData(this)); + + ConvertFromCdl(); + UpdateTreeItem(* treeCtrl); +} + +ecConfigItem::~ecConfigItem() +{ + // Make sure that the tree item no longer references this object + ecConfigTreeCtrl* treeCtrl = wxGetApp().GetTreeCtrl(); + if (m_treeItem && treeCtrl) + { + ecTreeItemData* data = (ecTreeItemData*) treeCtrl->GetItemData(m_treeItem); + data->SetConfigItem(NULL); + } + + ecConfigToolDoc* doc = wxGetApp().GetConfigToolDoc(); + if (doc) + { + doc->GetItems().DeleteObject(this); + } +} + +// Convert from Cdl to internal representation +bool ecConfigItem::ConvertFromCdl() +{ + if (!GetCdlItem()) + return FALSE; + + m_name = GetCdlItem()->get_display ().c_str (); + m_macro = GetCdlItem()->get_name().c_str(); + m_strDescr = ecUtils::StripExtraWhitespace (wxString (GetCdlItem()->get_description ().c_str ())); + + + // FIXME: re-implement using CdlValuableBody::get_widget_hint() + // (comment from original MFC configtool) + + if (IsPackage()) + { + // If a package item, display the package version string + m_optionType = ecString; + m_configType = ecPackage; + m_optionFlavor = ecFlavorNone; + } + else + { + const CdlValuable valuable = dynamic_cast (GetCdlItem()); + switch (valuable->get_flavor ()){ + case CdlValueFlavor_None: + m_optionFlavor = ecFlavorNone; + m_optionType=ecOptionTypeNone; //??? Shouldn't it be ecBool for CdlValueFlavor_Bool? + m_configType = ecContainer; + break; + case CdlValueFlavor_Bool: + m_optionFlavor = ecFlavorBool; + m_optionType=ecOptionTypeNone; //??? Shouldn't it be ecBool for CdlValueFlavor_Bool? + m_configType = ecOption; + m_hint = (HasRadio() ? ecHintRadio : ecHintCheck); + break; + case CdlValueFlavor_Data: + case CdlValueFlavor_BoolData: + + m_optionFlavor = (valuable->get_flavor() == CdlValueFlavor_Data ? ecFlavorData : ecFlavorBoolData); + m_configType = ecOption; + m_hint = (HasRadio() ? ecHintRadio : ecHintCheck); + + if (! valuable->has_legal_values ()) { + m_optionType=ecString; + } else if (0 == valuable->get_legal_values ()->ranges.size ()) { + m_optionType=ecEnumerated; + } else { + CdlListValue list_value; + CdlEvalContext context (NULL, valuable, valuable->get_property (CdlPropertyId_LegalValues)); + valuable->get_legal_values ()->eval (context, list_value); + m_optionType=list_value.get_double_ranges ().size () ? ecDouble : ecLong; + } + break; + default: + wxASSERT (0); // specified flavor not supported + break; + } + } + + m_active = IsActive(); + m_enabled = IsEnabled(); + + return TRUE; +} + +wxString ecConfigItem::GetItemNameOrMacro() const +{ + return (wxGetApp().GetSettings().m_showMacroNames && !GetMacro().IsEmpty() ? GetMacro() : GetName()); +} + +// Sets the text and icon for this item +bool ecConfigItem::UpdateTreeItem(ecConfigTreeCtrl& treeCtrl) +{ + treeCtrl.SetItemText(m_treeItem, m_name); + + static wxColour normalColour = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_WINDOWTEXT); + static wxColour disabledColour = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_GRAYTEXT); + + treeCtrl.SetItemTextColour(m_treeItem, GetActive() ? normalColour : disabledColour); + + + // Find which icon state we're in so we can get the appropriate icon id + int iconState = 0; + wxString iconName; + + switch (GetConfigType()) + { + case ecContainer: + { + iconName = _("Container"); + iconState = 0; + break; + } + case ecPackage: + { + iconName = _("Package"); + iconState = 0; + break; + } + case ecComponent: + { + iconName = _("??"); + iconState = 0; + break; + } + case ecOption: + { + if (GetOptionFlavor() == ecFlavorData) + { + switch (GetOptionType()) + { + case ecDouble: + case ecLong: + { + iconName = _("Integer"); + iconState = 0; + break; + } + case ecEnumerated: + { + iconName = _("Enumerated"); + iconState = 0; + break; + } + case ecString: + { + iconName = _("Text"); + iconState = 0; + break; + } + // ??? Actually I don't think there's such a think as ecBool type, only enabled/disabled + case ecBool: + { + if (GetUIHint() == ecHintCheck) + iconName = _("Checkbox"); + else + iconName = _("Radiobox"); + iconState = (m_value.GetBool() ? 0 : 1); + break; + } + default: + { + break; + } + } + } + if (GetOptionFlavor() == ecFlavorBoolData || GetOptionFlavor() == ecFlavorBool) + { + if (GetUIHint() == ecHintCheck) + iconName = _("Checkbox"); + else + iconName = _("Radiobox"); + iconState = (m_enabled ? 0 : 1); + } + break; + } + default: + { + break; + } + } + + if (!iconName.IsEmpty()) + { + int iconId = treeCtrl.GetIconDB().GetIconId(iconName, iconState, GetActive()); + treeCtrl.SetItemImage(m_treeItem, iconId, wxTreeItemIcon_Normal); + treeCtrl.SetItemImage(m_treeItem, iconId, wxTreeItemIcon_Selected); + } + + return TRUE; +} + +// Handle a left click on the icon: e.g. (un)check the option +// In the old MFC tool, this was handled by CControlView::Bump +void ecConfigItem::OnIconLeftDown(ecConfigTreeCtrl& treeCtrl) +{ + if (GetConfigType() != ecOption) + return; + + switch (GetOptionFlavor()) + { + case ecFlavorBool: + case ecFlavorBoolData: + { + if (GetActive()) + { + wxGetApp().GetConfigToolDoc()->SetEnabled(*this, !m_enabled); + } + break; + } + case ecFlavorData: + { + if (GetActive()) + { + switch (GetOptionType()) + { + case ecLong: + { + int nInc = 1; + + long nOldValue = Value(); + if(nInc==1 && nOldValue == long(-1)) + { + nOldValue=0; + } else if(nInc==-1 && nOldValue==0){ + nOldValue = long(-1); + } else { + nOldValue+=nInc; + } + wxGetApp().GetConfigToolDoc()->SetValue(*this, nOldValue); + break; + } + case ecEnumerated: + { + int nInc = 1; + + wxArrayString arEnum; + EvalEnumStrings (arEnum); // calculate legal values just in time + if (0 == arEnum.GetCount()) // if no legal values... + break; // ...do nothing + int nIndex = -1; + const wxString strCurrent = StringValue (); + int nEnum; + for (nEnum = 0; (nEnum < arEnum.GetCount()) && (nIndex == -1); nEnum++) + if (0 == arEnum[nEnum].CompareTo (strCurrent)) + nIndex = nEnum; // the index of the current value + + if (nIndex != -1) // if the current value is still legal + nIndex += (nInc < 0 ? -1 : 1); // increment/decrement the index + else + nIndex = 0; // otherwise select the first enum + + if (nIndex < 0) // if the new index is negative + nIndex = arEnum.GetCount()-1; // make it positive + + wxGetApp().GetConfigToolDoc()->SetValue(*this, arEnum[nIndex % arEnum.GetCount()]); + break; + } + default: + { + break; + } + } + } + break; + } + default: + { + break; + } + } + +} + +// Gets the value to display (often an empty string) +wxString ecConfigItem::GetDisplayValue() const +{ + wxString str; + switch(GetOptionType()) + { + case ecEnumerated: + case ecLong: + case ecDouble: + case ecString: + { + if (GetCdlValuable()) + str = StringValue(); + } + break; + default: + break; + } + return str; +#if 0 + switch (GetConfigType()) + { + case ecComponent: + case ecContainer: + { + return wxEmptyString; + break; + } + case ecPackage: + { + return m_value.GetString(); + break; + } + case ecOption: + { + switch (GetOptionType()) + { + case ecDouble: + { + wxString val; + val.Printf("%.4lf", (double) m_value.GetDouble()); + return val; + } + case ecLong: + { + wxString val; + val.Printf("%.ld", (long) m_value.GetLong()); + return val; + break; + } + case ecEnumerated: + case ecString: + { + return m_value.GetString(); + break; + } + case ecBool: + { + return wxEmptyString; + break; + } + default: + { + break; + } + } + break; + } + default: + { + break; + } + } + + return wxEmptyString; +#endif +} + +// Can we start editing this item? +bool ecConfigItem::CanEdit() const +{ + if (!GetActive()) + return FALSE; + + if (GetConfigType() != ecOption) + return FALSE; + + if (GetOptionFlavor() != ecFlavorData && GetOptionFlavor() != ecFlavorBoolData) + return FALSE; + + // TODO: other criteria for editability + return TRUE; +} + + +// Creates an edit window. It will be positioned by the caller. +wxWindow* ecConfigItem::CreateEditWindow(wxWindow* parent) +{ + wxWindow* window = NULL; + + switch(GetOptionType()) + { + case ecEnumerated: + { + window = new ecEnumEditorCtrl(parent, ecID_ITEM_EDIT_WINDOW, wxDefaultPosition, wxDefaultSize, + /* wxNO_BORDER */ 0); + wxArrayString arEnumStrings; + EvalEnumStrings(arEnumStrings); + int i; + for (i = 0; i < arEnumStrings.GetCount(); i++) + { + ((ecEnumEditorCtrl*) window)->Append(arEnumStrings[i]); + } + break; + } + case ecLong: + { + window = new ecIntegerEditorCtrl(parent, ecID_ITEM_EDIT_WINDOW, wxDefaultPosition, wxDefaultSize, + /* wxNO_BORDER | */ wxSP_ARROW_KEYS); + break; + } + case ecDouble: + { + window = new ecDoubleEditorCtrl(parent, ecID_ITEM_EDIT_WINDOW, wxDefaultPosition, wxDefaultSize, + /* wxNO_BORDER|*/ wxTE_PROCESS_ENTER); + break; + } + case ecString: + { + window = new ecTextEditorCtrl(parent, ecID_ITEM_EDIT_WINDOW, wxDefaultPosition, wxDefaultSize, + /* wxNO_BORDER|*/ wxTE_PROCESS_ENTER); + break; + } + default: + break; + } + + wxASSERT (window != NULL) ; + + return window; +} + +// Transfers data between item and window +bool ecConfigItem::TransferDataToWindow(wxWindow* window) +{ + if (window->IsKindOf(CLASSINFO(ecTextEditorCtrl))) + { + ecTextEditorCtrl* win = (ecTextEditorCtrl*) window; + win->SetValue(GetDisplayValue()); + } + else if (window->IsKindOf(CLASSINFO(ecDoubleEditorCtrl))) + { + ecDoubleEditorCtrl* win = (ecDoubleEditorCtrl*) window; + win->SetValue(GetDisplayValue()); + } + else if (window->IsKindOf(CLASSINFO(ecEnumEditorCtrl))) + { + ecEnumEditorCtrl* win = (ecEnumEditorCtrl*) window; + win->SetStringSelection(GetDisplayValue()); + } + else if (window->IsKindOf(CLASSINFO(ecIntegerEditorCtrl))) + { + ecIntegerEditorCtrl* win = (ecIntegerEditorCtrl*) window; + long i; + ecUtils::StrToItemIntegerType(StringValue(), i); + + wxString val; + val.Printf(wxT("%ld"), i); + + win->SetValue(val); + } + return TRUE; +} + +bool ecConfigItem::TransferDataFromWindow(wxWindow* window) +{ + ecConfigToolDoc* doc = wxGetApp().GetConfigToolDoc(); + wxASSERT (doc != NULL); + + if (!doc) + return FALSE; + + if (window->IsKindOf(CLASSINFO(ecTextEditorCtrl))) + { + ecTextEditorCtrl* win = (ecTextEditorCtrl*) window; + + wxASSERT ( GetOptionType() == ecString ); + + // TODO: do checking + doc->SetValue(*this, win->GetValue()); + } + else if (window->IsKindOf(CLASSINFO(ecDoubleEditorCtrl))) + { + ecDoubleEditorCtrl* win = (ecDoubleEditorCtrl*) window; + + wxASSERT ( GetOptionType() == ecString ); + + // TODO: do checking + doc->SetValue(*this, atof(win->GetValue())); + } + else if (window->IsKindOf(CLASSINFO(ecEnumEditorCtrl))) + { + ecEnumEditorCtrl* win = (ecEnumEditorCtrl*) window; + + wxASSERT ( GetOptionType() == ecEnumerated ); + + // TODO: do checking + doc->SetValue(*this, win->GetStringSelection()); + } + else if (window->IsKindOf(CLASSINFO(ecIntegerEditorCtrl))) + { + ecIntegerEditorCtrl* win = (ecIntegerEditorCtrl*) window; + + wxASSERT ( GetOptionType() == ecLong ); + + // TODO: do checking + doc->SetValue(*this, (long) win->GetValue()); + } + + return TRUE; +} + +//// Taken from MFC version + +const ecFileName ecConfigItem::GetFilename() const +{ + wxString sep(wxFILE_SEP_PATH); + + ecFileName strFile; + const CdlNode node = dynamic_cast (m_CdlItem); + if (node){ + // get the package which owns the configuration item + const CdlPackage package = GetOwnerPackage(); + if (package){ + + // return the filename of the config header + wxString pkg(wxT("include")); + pkg += sep; + pkg += wxT("pkgconf"); + strFile=ecFileName(wxGetApp().GetConfigToolDoc()->GetInstallTree()+sep+pkg) + package->get_config_header ().c_str (); + } + } + return strFile; +} + +// Change version (of a package) +bool ecConfigItem::ChangeVersion(const wxString &strVersion) +{ + bool rc=FALSE; + CdlPackage package=dynamic_cast(GetCdlItem()); + wxASSERT(package != 0); + const CdlValuable valuable = GetCdlValuable(); + wxASSERT (valuable != 0); + const wxString strMacroName(GetMacro()); + if (strVersion != valuable->get_value ().c_str ()) { // if the wrong version is loaded + // TRACE (wxT("Changing package %s to version '%s'\n"), strMacroName, strVersion); + try { + wxGetApp().GetConfigToolDoc()->GetCdlConfig()->change_package_version (package, ecUtils::UnicodeToStdStr (strVersion), ecConfigToolDoc::CdlParseErrorHandler, ecConfigToolDoc::CdlParseWarningHandler); + rc=TRUE; + } + catch (CdlStringException exception) { + wxString msg; + msg.Printf(wxT("Error changing package %s to version '%s':\n\n%s"), (const wxChar*) strMacroName, (const wxChar*) strVersion, (const wxChar*) wxString (exception.get_message ().c_str ())) ; + wxMessageBox(msg); + } + catch (...) { + wxString msg; + msg.Printf(wxT("Error changing package %s to version '%s'"), (const wxChar*) strMacroName, (const wxChar*) strVersion) ; + wxMessageBox(msg); + } + } + return rc; +} + +// Unload (a package) +bool ecConfigItem::Unload() +{ + bool rc=FALSE; + CdlPackage package=dynamic_cast(GetCdlItem()); + wxASSERT(package); + ecConfigToolDoc* pDoc=wxGetApp().GetConfigToolDoc(); + + // Remove its objects from the view to prevent any painting problems + ecTreeItemData* data = (ecTreeItemData*) wxGetApp().GetTreeCtrl()->GetItemData(GetTreeItem()); + wxASSERT(data); + + // I _think_ we should do this to stop 'this' from being deleted when we delete the item. + // But, in that case, where do we delete this item? + // Perhaps should store them in an array in the document, as per the MFC tool. + data->SetConfigItem(NULL); + + wxGetApp().GetTreeCtrl()->Delete(GetTreeItem()); + + wxNode* node = pDoc->GetItems().First(); + while (node) + { + ecConfigItem* item = wxDynamicCast(node->Data(), ecConfigItem); + if (package == item->GetOwnerPackage()) + { + item->SetTreeItem(wxTreeItemId()); // Make sure we can't attempt to paint it + item->SetCdlItem(NULL); // Make sure we can't access stale data + } + node = node->Next(); + } + + const wxString strMacroName(GetMacro()); + //TRACE (wxT("Unloading package %s\n"), strMacroName); + try { + pDoc->GetCdlConfig()->unload_package (package); + rc=TRUE; + } + catch (CdlStringException exception) { + wxString msg; + wxString exceptionMsg(exception.get_message ().c_str ()); + msg.Printf(wxT("Error unloading package %s:\n\n%s"), (const wxChar*) strMacroName, (const wxChar*) exceptionMsg ); + wxMessageBox(msg); + } + catch (...) { + wxString msg; + msg.Printf(wxT("Error unloading package %s"), (const wxChar*) strMacroName); + wxMessageBox(msg); + } + m_treeItem=wxTreeItemId(); // Make sure we can't attempt to paint it + m_CdlItem=NULL; // Make sure we can't access stale data + return rc; +} + +wxString ecConfigItem::GetURL() const +{ + for(const ecConfigItem *pItem=this;pItem;pItem=pItem->GetParent()){ + if(pItem->GetCdlItem()){ + wxString strURL; + strURL=pItem->GetCdlItem()->get_doc_url().c_str(); + if(strURL.Len()){ + return strURL; + } + strURL=pItem->GetCdlItem()->get_doc().c_str(); + if(strURL.Len()){ + return strURL; + } + } + } + return wxT("ref/ecos-ref.html"); // the default URL +} + +bool ecConfigItem::SetValue(const wxString& value, CdlTransaction transaction/*=NULL*/) +{ + wxASSERT ((m_optionType == ecString) || (m_optionType == ecEnumerated)); + const CdlValuable valuable = GetCdlValuable(); + wxASSERT (valuable); + const std::string str = value.c_str(); + if(transaction){ + if (CdlValueFlavor_BoolData == valuable->get_flavor ()){ + // set the user bool to the current bool when changing a booldata + // value to avoid a possible change in the current bool + valuable->set_enabled_and_value (transaction, valuable->is_enabled (), str, CdlValueSource_User); + } else {// CdlValueFlavor_Data + valuable->set_value (transaction, str, CdlValueSource_User); + } + } else { + if (CdlValueFlavor_BoolData == valuable->get_flavor ()){ + // set the user bool to the current bool when changing a booldata + // value to avoid a possible change in the current bool + valuable->set_enabled_and_value (valuable->is_enabled (), str, CdlValueSource_User); + } else {// CdlValueFlavor_Data + valuable->set_value (str, CdlValueSource_User); + } + } + + // TODO: eliminate m_value, since the value is always taken from the Cdl object. + m_value = value; + + return TRUE; +} + +bool ecConfigItem::SetValue (double dValue, CdlTransaction transaction/*=NULL*/) +{ + wxASSERT (m_optionType == ecDouble); + + const CdlValuable valuable = GetCdlValuable(); + wxASSERT (valuable); + + if(transaction) { + if (CdlValueFlavor_BoolData == valuable->get_flavor ()) { + // set the user bool to the current bool when changing a booldata + // value to avoid a possible change in the current bool + valuable->set_enabled_and_value (transaction, valuable->is_enabled (), dValue, CdlValueSource_User); + } else {// CdlValueFlavor_Data + valuable->set_double_value (transaction, dValue, CdlValueSource_User); + } + } else { + if (CdlValueFlavor_BoolData == valuable->get_flavor ()) { + // set the user bool to the current bool when changing a booldata + // value to avoid a possible change in the current bool + valuable->set_enabled_and_value (valuable->is_enabled (), dValue, CdlValueSource_User); + } else {// CdlValueFlavor_Data + valuable->set_double_value (dValue, CdlValueSource_User); + } + } + + // TODO: BoolData? + m_value = dValue; + + return TRUE; +} + +bool ecConfigItem::SetValue (long nValue, CdlTransaction transaction/*=NULL*/) +{ + wxASSERT (m_optionType == ecLong); + const CdlValuable valuable = GetCdlValuable(); + wxASSERT (valuable); + + if(transaction) { + if (CdlValueFlavor_BoolData == valuable->get_flavor ()) { + // set the user bool to the current bool when changing a booldata + // value to avoid a possible change in the current bool + valuable->set_enabled_and_value (transaction, valuable->is_enabled (), (cdl_int) nValue, CdlValueSource_User); + } else { // CdlValueFlavor_Data + valuable->set_integer_value (transaction, nValue, CdlValueSource_User); + } + } else { + if (CdlValueFlavor_BoolData == valuable->get_flavor ()) { + // set the user bool to the current bool when changing a booldata + // value to avoid a possible change in the current bool + valuable->set_enabled_and_value (valuable->is_enabled (), (cdl_int) nValue, CdlValueSource_User); + } else { // CdlValueFlavor_Data + valuable->set_integer_value (nValue, CdlValueSource_User); + } + } + + // TODO: BoolData? + m_value = nValue; + + return TRUE; +} + +bool ecConfigItem::HasRadio() const +{ + const CdlValuable valuable = GetCdlValuable(); + if (! valuable) + return FALSE; + + CdlWidgetHint hint; + valuable->get_widget_hint (hint); + return (CdlBoolWidget_Radio == hint.bool_widget); +} + +ecConfigItem *ecConfigItem::FirstRadio() const +{ + wxASSERT(HasRadio ()); + + for(ecConfigItem *h=GetParent()->FirstChild();h;h=h->NextSibling()){ + if(h->HasRadio ()){ + return h; + } + } + // No radio buttons found + wxASSERT(FALSE); + return FALSE; +} + +ecConfigItem *ecConfigItem::FirstChild() const +{ + ecConfigTreeCtrl* treeCtrl = wxGetApp().GetTreeCtrl(); + + long cookie; + wxTreeItemId hChild=treeCtrl->GetFirstChild(GetTreeItem(), cookie); + if (hChild) + { + ecTreeItemData* data = (ecTreeItemData*) wxGetApp().GetTreeCtrl()->GetItemData(hChild); + wxASSERT(data); + + return data->GetConfigItem(); + } + else + return NULL; +} + +ecConfigItem *ecConfigItem::NextSibling() const +{ + ecConfigTreeCtrl* treeCtrl = wxGetApp().GetTreeCtrl(); + + wxTreeItemId hChild=treeCtrl->GetNextSibling(GetTreeItem()); + if (hChild) + { + ecTreeItemData* data = (ecTreeItemData*) wxGetApp().GetTreeCtrl()->GetItemData(hChild); + wxASSERT(data); + + return data->GetConfigItem(); + } + else + return NULL; +} + +bool ecConfigItem::IsEnabled() const +{ + const CdlValuable valuable = GetCdlValuable(); + return NULL==valuable ||valuable->is_enabled(); +} + +bool ecConfigItem::IsActive() const +{ +// return GetCdlItem()->is_active(); + const CdlValuable valuable = GetCdlValuable(); + if (valuable && ((GetOptionType() != ecOptionTypeNone) || HasBool())) + { + return (valuable->is_modifiable () && valuable->is_active ()); + } + else + return GetCdlItem()->is_active(); +} + +bool ecConfigItem::HasModifiedChildren() const +{ + for(ecConfigItem *pItem=FirstChild();pItem;pItem=pItem->NextSibling()){ + if(pItem->Modified()||pItem->HasModifiedChildren()){ + return TRUE; + } + } + return FALSE; +} + +bool ecConfigItem::Modified () const +{ + const CdlValuable valuable = GetCdlValuable(); + return + valuable // accommodate the root config item which has no CDL item + && !IsPackage() // packages are never modified + && valuable->get_source () != CdlValueSource_Default; +} + +void ecConfigItem::DumpItem() +{ + //TRACE(wxT("Item %08x\n\tDisplay Name='%s'\n\tMacro Name='%s'\n\tType=%s"), this, Name(), Macro(), TreeItemTypeImage[m_Type]); + //TRACE(wxT("\n\tValue=%s\n\tURL=%s\n\tParent=%08x"),StringValue(), GetURL(), Parent()); + + //TRACE(wxT("\n")); +} + +ecConfigItem * ecConfigItem::NextRadio() const +{ + wxASSERT(this->HasRadio ()); + for(ecConfigItem *pItem=NextSibling();pItem;pItem=pItem->NextSibling()){ + if(pItem->HasRadio()){ + return pItem; + } + } + return NULL; +} + +bool ecConfigItem::IsDescendantOf(ecConfigItem * pAncestor) +{ + for(ecConfigItem *pItem=GetParent();pItem;pItem=pItem->GetParent()){ + if(pItem==pAncestor){ + return TRUE; + } + } + return FALSE; +} + +bool ecConfigItem::ViewHeader() +{ + bool rc=FALSE; + const ecFileName strFile(GetFilename()); + if(!strFile.IsEmpty()) + { + ecConfigToolDoc *pDoc=wxGetApp().GetConfigToolDoc(); + if(pDoc->GetBuildTree().IsEmpty()){ + wxString msg; + msg.Printf(wxT("Cannot display header file until configuration is saved")); + wxMessageBox(msg); + } else + { + rc=wxGetApp().Launch(strFile, wxGetApp().GetSettings().m_strViewer); + } + } + return rc; +} + +bool ecConfigItem::ViewURL() +{ + return wxGetApp().GetConfigToolDoc()->ShowURL(GetURL()); +} + +bool ecConfigItem::HasBool() const +{ + if (!m_CdlItem) { + return FALSE; + } else if (IsPackage()) { + return FALSE; + } else { + const CdlValuable valuable = GetCdlValuable(); + CdlValueFlavor flavor = valuable->get_flavor (); + return (flavor == CdlValueFlavor_Bool) || (flavor == CdlValueFlavor_BoolData); + } +} + +bool ecConfigItem::SetEnabled(bool bEnabled, CdlTransaction current_transaction/*=NULL*/) +{ + const CdlValuable valuable = GetCdlValuable(); + wxASSERT (valuable); + + // use a transaction object to ensure that all config items are changed together + CdlTransaction transaction = current_transaction ? current_transaction : CdlTransactionBody::make (wxGetApp().GetConfigToolDoc ()->GetCdlConfig ()); + + if (HasRadio () && bEnabled) { // if a new radio button has been selected + for (ecConfigItem *pItem = FirstRadio(); pItem; pItem = pItem->NextRadio ()) { // for each radio button in the group + if (pItem != this) { // if not the newly selected radio button + pItem->SetEnabled (FALSE, transaction); // disable the radio button + } + } + } + + if (CdlValueFlavor_BoolData == valuable->get_flavor ()) { + // set the user value to the current data value when enabling/disabling + // a booldata item to avoid a possible change in the current data value + CdlSimpleValue simple_value = valuable->get_simple_value (); + valuable->set_enabled_and_value (transaction, bEnabled, simple_value, CdlValueSource_User); + } else { // CdlValueFlavor_Bool + valuable->set_enabled (transaction, bEnabled, CdlValueSource_User); + } + + if (! current_transaction) { // if not a recursive call to disable a radio button + transaction->body (); // commit the transaction + delete transaction; + transaction = NULL; + } + + return TRUE; +} + +long ecConfigItem::DefaultValue () const +{ + return (long) atoi (StringValue (CdlValueSource_Default)) ; +} + +long ecConfigItem::Value () const +{ + wxASSERT (!IsPackage()); // not a package item + const CdlValuable valuable = GetCdlValuable(); + wxASSERT (valuable); + long nValue (0); + + switch (valuable->get_flavor ()) + { + // case CdlValueFlavor_Bool: + // nValue = valuable->is_enabled (CdlValueSource_Current) ? 1 : 0; + // break; + + case CdlValueFlavor_BoolData: + case CdlValueFlavor_Data: + nValue = (long) valuable->get_integer_value (CdlValueSource_Current); + break; + + default: + wxASSERT (0); // specified flavor not supported + } + + return nValue; +} + +const double ecConfigItem::DoubleValue (CdlValueSource source /* = CdlValueSource_Current */ ) const +{ + wxASSERT (!IsPackage()); // not a package item + const CdlValuable valuable = GetCdlValuable(); + wxASSERT (valuable); + wxASSERT (valuable->has_double_value (source)); + return valuable->get_double_value (source); +} + +const wxString ecConfigItem::StringValue (CdlValueSource source /* = CdlValueSource_Current */ ) const +{ + // wxASSERT (!IsPackage()); // not a package item + const CdlValuable valuable = GetCdlValuable(); + wxASSERT (valuable); + wxString strValue (wxT("")); + + switch (valuable->get_flavor ()) + { + case CdlValueFlavor_Data: + case CdlValueFlavor_BoolData: + case CdlValueFlavor_None: // a package + if (m_optionType == ecLong) + strValue = ecUtils::IntToStr (Value (), wxGetApp().GetSettings().m_bHex); + else if (m_optionType == ecDouble) + strValue = ecUtils::DoubleToStr (DoubleValue ()); + else + strValue = valuable->get_value (source).c_str (); + break; + + default: + wxASSERT (0); // specified flavor not supported + } + + return strValue; +} + +const wxString ecConfigItem::StringValue(ecWhereType where) const +{ + wxString str; + switch(where){ + case ecInName: + str=GetName(); + break; + case ecInMacro: + str=GetMacro(); + break; + case ecInDesc: + str=GetDescription(); + break; + case ecInCurrentValue: + if (ecOptionTypeNone==GetOptionType()) + str = wxEmptyString; + else + str = StringValue(CdlValueSource_Current); + break; + case ecInDefaultValue: + if (ecOptionTypeNone==GetOptionType()) + str = wxEmptyString; + else + str = StringValue(CdlValueSource_Default); + break; + default: + wxASSERT(FALSE); + break; + } + return str; +} + +int ecConfigItem::EvalEnumStrings (wxArrayString &arEnumStrings) const +{ + const CdlValuable valuable = GetCdlValuable(); + wxASSERT (valuable); + /* + if (m_Type == Boolean) + { + arEnumStrings.SetSize (2); + arEnumStrings.SetAt (0, wxT("True")); + arEnumStrings.SetAt (1, wxT("False")); + } + else + */ + { + wxASSERT (m_optionType == ecEnumerated); + CdlListValue list_value; + CdlEvalContext context (NULL, m_CdlItem, m_CdlItem->get_property (CdlPropertyId_LegalValues)); + valuable->get_legal_values ()->eval (context, list_value); + const std::vector & table = list_value.get_table (); + + // add legal values to the list + for (unsigned int nValue = 0; nValue < table.size (); nValue++) + { + arEnumStrings.Add (table [nValue].get_value ().c_str ()); + } + } + return arEnumStrings.GetCount(); +} + +static const wxChar* gs_whereTypes[] = +{ + _("Macro names"), + _("Item names"), + _("Short descriptions"), + _("Current Values"), + _("Default Values") +}; + +// Convert a string representation of 'where' (e.g. "Macro names") to +// ecWhereType +ecWhereType ecConfigItem::WhereStringToType(const wxString& whereString) +{ + int sz = 5; + int i; + for (i = 0; i < sz; i++) + if (whereString == gs_whereTypes[i]) + return (ecWhereType) i; + + wxASSERT( FALSE ); + + return (ecWhereType) 0; +} + +// Convert a type representation of 'where' to a string +wxString ecConfigItem::WhereTypeToString(ecWhereType whereType) +{ + return gs_whereTypes[(size_t) whereType] ; +} + +// Bump by specified amount, or toggle if a boolean value +bool ecConfigItem::BumpItem(int nInc) +{ + bool rc = FALSE; + + // Take an action for clicking on the icon + ecConfigToolDoc* pDoc = wxGetApp().GetConfigToolDoc(); + + // do not modify the option value if it is inactive or not modifiable + const CdlValuable valuable = GetCdlValuable(); + if (!valuable || (valuable->is_modifiable () && valuable->is_active ())) + { + if (0 == nInc) // if a toggle request + { + if (HasBool () && ! (HasRadio () && IsEnabled ())) { // only enable (not disable) a radio button + rc = pDoc->SetEnabled (*this, ! this->IsEnabled ()); // toggle enabled/disabled state + } + } else if (IsEnabled ()) { // the item is enabled... + switch(GetOptionType()) + { + case ecOptionTypeNone: + case ecString: + case ecDouble: + break; + case ecEnumerated: + { + wxArrayString arEnum; + EvalEnumStrings (arEnum); // calculate legal values just in time + if (0==arEnum.Count()) // if no legal values... + break; // ...do nothing + int nIndex = -1; + const wxString strCurrent = StringValue (); + int nEnum; + for (nEnum = 0; (nEnum < arEnum.Count()) && (nIndex == -1); nEnum++) + if (strCurrent == arEnum[nEnum]) + nIndex = nEnum; // the index of the current value + + if (nIndex != -1) // if the current value is still legal + nIndex += (nInc < 0 ? -1 : 1); // increment/decrement the index + else + nIndex = 0; // otherwise select the first enum + + if (nIndex < 0) // if the new index is negative + nIndex = arEnum.Count()-1; // make it positive + + rc=pDoc->SetValue (*this, arEnum[nIndex % arEnum.Count()]); + } + break; + case ecLong: + { + // TODO: if we're editing, we should get the value in the edit item + // and not the ecConfigItem. + long nOldValue = Value(); + if(nInc==1 && nOldValue==-1){ + nOldValue=0; + } else if(nInc==-1 && nOldValue==0){ + nOldValue=-1; + } else { + nOldValue+=nInc; + } + rc=pDoc->SetValue(*this, nOldValue); + break; + } + + break; + /* + case CConfigItem::Boolean: + + { + ItemIntegerType nOldValue=Value(h); + pDoc->SetValue(ti,nOldValue^1); + } + break; + case CConfigItem::Radio: + + if(0==Value(h)){ + pDoc->SetValue(ti, (ItemIntegerType) 1); + } + break; + */ + default: + break; + } + } + } + return rc; +} + +#if 0 + +/* Presumably we don't need this since we use the m_parent member instead +ecConfigItem *ecConfigItem::Parent() const +{ + CTreeCtrl &tree=CConfigTool::GetControlView()->GetTreeCtrl(); + HTREEITEM hParent=tree.GetParentItem(HItem()); + return (NULL==hParent||TVI_ROOT==hParent)?NULL:(ecConfigItem *)tree.GetItemData(hParent); +} +*/ + +#endif + +/* + * ecTextEditorCtrl + * A specialised wxTextCtrl, for editing config values + */ + +BEGIN_EVENT_TABLE(ecTextEditorCtrl, wxTextCtrl) + EVT_TEXT_ENTER(-1, ecTextEditorCtrl::OnEnter) + EVT_KILL_FOCUS(ecTextEditorCtrl::OnKillFocus) + EVT_LEFT_DCLICK(ecTextEditorCtrl::OnLeftDClick) +END_EVENT_TABLE() + +IMPLEMENT_CLASS(ecTextEditorCtrl, wxTextCtrl) + +ecTextEditorCtrl::ecTextEditorCtrl(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, + long style): + wxTextCtrl(parent, id, wxEmptyString, pos, size, style) +{ +} + +void ecTextEditorCtrl::OnEnter(wxCommandEvent& event) +{ + ecValueWindow* parent = (ecValueWindow*) GetParent(); + parent->EndEditing(); +} + +void ecTextEditorCtrl::OnKillFocus(wxFocusEvent& event) +{ + ecValueWindow* parent = (ecValueWindow*) GetParent(); + parent->EndEditing(); +} + +// Edit the string in a separate dialog, for convenience +void ecTextEditorCtrl::OnLeftDClick(wxMouseEvent& event) +{ + ecValueWindow* parent = (ecValueWindow*) GetParent(); + ecConfigItem* item = parent->GetCurrentConfigItem(); + ecConfigToolDoc* doc = wxGetApp().GetConfigToolDoc(); + + wxString initialValue(GetValue()); + + ecEditStringDialog dialog(initialValue, wxGetApp().GetTopWindow(), ecID_EDIT_STRING_DIALOG); + if (dialog.ShowModal() == wxID_OK) + { + wxString val = dialog.GetValue() ; + // This control will have been deleted at this point, due to losing the focus. + // So update the item, not the control. + // wxTextCtrl::SetValue(val); + doc->SetValue(*item, val); + } +} + +/* + * ecDoubleEditorCtrl + * A specialised wxTextCtrl, for editing double config values + */ + +BEGIN_EVENT_TABLE(ecDoubleEditorCtrl, wxTextCtrl) + EVT_TEXT_ENTER(-1, ecDoubleEditorCtrl::OnEnter) + EVT_KILL_FOCUS(ecDoubleEditorCtrl::OnKillFocus) +END_EVENT_TABLE() + +IMPLEMENT_CLASS(ecDoubleEditorCtrl, wxTextCtrl) + +ecDoubleEditorCtrl::ecDoubleEditorCtrl(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, + long style): + wxTextCtrl(parent, id, wxEmptyString, pos, size, style) +{ +} + +void ecDoubleEditorCtrl::OnEnter(wxCommandEvent& event) +{ + ecValueWindow* parent = (ecValueWindow*) GetParent(); + parent->EndEditing(); +} + +void ecDoubleEditorCtrl::OnKillFocus(wxFocusEvent& event) +{ + ecValueWindow* parent = (ecValueWindow*) GetParent(); + parent->EndEditing(); +} + +/* + * ecIntegerEditorCtrl + * A specialised wxTextCtrl, for editing double config values + */ + +BEGIN_EVENT_TABLE(ecIntegerEditorCtrl, wxSpinCtrl) + EVT_TEXT_ENTER(-1, ecIntegerEditorCtrl::OnEnter) + EVT_KILL_FOCUS(ecIntegerEditorCtrl::OnKillFocus) +END_EVENT_TABLE() + +IMPLEMENT_CLASS(ecIntegerEditorCtrl, wxSpinCtrl) + +ecIntegerEditorCtrl::ecIntegerEditorCtrl(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, + long style): + wxSpinCtrl(parent, id, wxEmptyString, pos, size, style, -32000, 32000, 0) +{ +} + +void ecIntegerEditorCtrl::OnEnter(wxCommandEvent& event) +{ + ecValueWindow* parent = (ecValueWindow*) GetParent(); + parent->EndEditing(); +} + +void ecIntegerEditorCtrl::OnKillFocus(wxFocusEvent& event) +{ + ecValueWindow* parent = (ecValueWindow*) GetParent(); + parent->EndEditing(); +} + +/* + * ecEnumEditorCtrl + * A specialised wxChoice, for editing enumerated config values + */ + +BEGIN_EVENT_TABLE(ecEnumEditorCtrl, wxChoice) + EVT_CHAR(ecEnumEditorCtrl::OnChar) + EVT_KILL_FOCUS(ecEnumEditorCtrl::OnKillFocus) +END_EVENT_TABLE() + +IMPLEMENT_CLASS(ecEnumEditorCtrl, wxChoice) + +ecEnumEditorCtrl::ecEnumEditorCtrl(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, + long style): + wxChoice(parent, id, pos, size, 0, 0, style) +{ +} + +void ecEnumEditorCtrl::OnChar(wxKeyEvent& event) +{ + if (event.GetKeyCode() == WXK_RETURN) + { + ecValueWindow* parent = (ecValueWindow*) GetParent(); + parent->EndEditing(); + } + else + event.Skip(); +} + +void ecEnumEditorCtrl::OnKillFocus(wxFocusEvent& event) +{ + ecValueWindow* parent = (ecValueWindow*) GetParent(); + parent->EndEditing(); +} + +/* + * ecEditStringDialog + * Pops up to make it easier to edit large string values + */ + +BEGIN_EVENT_TABLE(ecEditStringDialog, ecDialog) + EVT_BUTTON(wxID_OK, ecEditStringDialog::OnOK) +END_EVENT_TABLE() + +ecEditStringDialog::ecEditStringDialog(const wxString& initialValue, wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, + long style) +{ + m_value = initialValue; + //SetExtraStyle(wxDIALOG_EX_CONTEXTHELP); + + ecDialog::Create(parent, id, _("String Edit"), + wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER); + + CreateControls(this); + + TransferDataToWindow(); + + Centre(wxBOTH); +} + +ecEditStringDialog::~ecEditStringDialog() +{ +} + +//// Event handlers + +void ecEditStringDialog::OnOK(wxCommandEvent& event) +{ + wxDialog::OnOK(event); +} + +//// Operations +void ecEditStringDialog::CreateControls(wxWindow* parent) +{ + wxSizer *item0 = new wxBoxSizer( wxVERTICAL ); + + wxSizer *item1 = new wxBoxSizer( wxHORIZONTAL ); + + item1->Add( 20, 20, 10, wxALIGN_CENTRE|wxALL, 5 ); + + wxButton *item2 = new wxButton( parent, wxID_OK, _("&OK"), wxDefaultPosition, wxDefaultSize, 0 ); + item2->SetDefault(); + item1->Add( item2, 0, wxALIGN_CENTRE|wxALL, 5 ); + + wxButton *item3 = new wxButton( parent, wxID_CANCEL, _("&Cancel"), wxDefaultPosition, wxDefaultSize, 0 ); + item1->Add( item3, 0, wxALIGN_CENTRE|wxALL, 5 ); + + item0->Add( item1, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxTOP, 5 ); + + wxTextCtrl *item4 = new wxTextCtrl( parent, ecID_STRING_EDIT_TEXTCTRL, _(""), wxDefaultPosition, wxSize(420,250), wxTE_MULTILINE ); + item0->Add( item4, 1, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxBOTTOM, 5 ); + + parent->SetAutoLayout( TRUE ); + parent->SetSizer( item0 ); + parent->Layout(); + item0->Fit( parent ); + item0->SetSizeHints( parent ); + + FindWindow(ecID_STRING_EDIT_TEXTCTRL)->SetValidator(wxGenericValidator(& m_value)); + FindWindow(ecID_STRING_EDIT_TEXTCTRL)->SetFocus(); +} diff --git a/host/tools/configtool/standalone/wxwin/configitem.h b/host/tools/configtool/standalone/wxwin/configitem.h new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/configitem.h @@ -0,0 +1,416 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +// configitem.h : +// +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): julians +// Contact(s): julians +// Date: 2000/09/01 +// Version: $Id: configitem.h,v 1.4 2001/04/09 12:51:34 julians Exp $ +// Purpose: +// Description: Header file for ecConfigItem, which describes a config item +// from this tool's perspective. Note that this duplicates +// some of the CDL data structures in order to be able to test the +// UI independently; we may eliminate some of the duplication later. +// Requires: +// Provides: +// See also: +// Known bugs: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== + +#ifndef _ECOS_CONFIGITEM_H_ +#define _ECOS_CONFIGITEM_H_ + +#ifdef __GNUG__ +#pragma interface "configitem.h" +#endif + +#include "wx/variant.h" +#include "wx/treectrl.h" +#include "wx/spinctrl.h" + +#include "filename.h" +#include "cdl.hxx" + +/* + * ecConfigType + * The type of item + */ + +enum ecConfigType +{ + ecConfigTypeNone, + ecContainer, + ecPackage, + ecComponent, + ecOption +}; + +/* + * ecOptionFlavor + * The flavor of the option + */ + +enum ecOptionFlavor +{ + ecFlavorNone, + ecFlavorBool, + ecFlavorBoolData, + ecFlavorData +}; + +/* + * ecOptionType + * The type of option, if this is an option + */ + +enum ecOptionType +{ + ecOptionTypeNone, + ecDouble, + ecLong, + ecBool, + ecString, + ecEnumerated +}; + +/* + * ecUIHint + * What kind of control to use + */ + +enum ecUIHint +{ + ecHintNone, + ecHintCheck, + ecHintRadio +}; + +/* + * Get string from where? + */ + +enum ecWhereType +{ + ecInMacro = 0, + ecInName, + ecInDesc, + ecInCurrentValue, + ecInDefaultValue +}; + +/* + * ecConfigItem + * Represents a node in the configuration hierarchy. + * For every ecConfigItem, there is also an ecTreeItemData + * that points to it. + */ +class ecConfigTreeCtrl; +class ecConfigItem: public wxObject +{ +DECLARE_CLASS(ecConfigItem) + friend class ecConfigToolDoc; + +public: + // active: whether greyed out or not + // enabled: only if this is a Bool or BoolData: whether enabled/disabled (checked/unchecked) + ecConfigItem(ecConfigItem* parent, const wxString& name, ecConfigType ctype = ecConfigTypeNone, + ecOptionFlavor flavor = ecFlavorNone, ecOptionType otype = ecOptionTypeNone, + bool active = TRUE, bool enabled = TRUE, ecUIHint hint = ecHintNone); + ecConfigItem(ecConfigItem* parent, CdlUserVisible vitem); + ~ecConfigItem(); + +//// Accessors + void SetParent(ecConfigItem* parent) { m_parent = parent; } + ecConfigItem* GetParent() const { return m_parent; } + + void SetName(const wxString& name) { m_name = name; } + const wxString& GetName() const { return m_name; } + + void SetMacro(const wxString& name) { m_macro = name; } + const wxString& GetMacro() const { return m_macro; } + + void SetDescription(const wxString& descr) { m_strDescr = descr; } + const wxString& GetDescription() const { return m_strDescr; } + + void SetConfigType(ecConfigType ctype) { m_configType = ctype; } + ecConfigType GetConfigType() const { return m_configType; } + + void SetOptionType(ecOptionType otype) { m_optionType = otype; } + ecOptionType GetOptionType() const { return m_optionType; } + + void SetOptionFlavor(ecOptionFlavor flavor) { m_optionFlavor = flavor; } + ecOptionFlavor GetOptionFlavor() const { return m_optionFlavor; } + + void SetValue(const wxVariant& value) { m_value = value; } + wxVariant& GetValue() { return m_value; } + + // Only appropriate if Bool or BoolData. Otherwise, assume always enabled. + void SetEnabled(bool enabled) { m_enabled = enabled; } + bool GetEnabled() const { return m_enabled; } + + // Whether greyed out or not + void SetActive(bool active) { m_active = active; } + bool GetActive() const { return m_active; } + + // UI hint + void SetUIHint(ecUIHint hint) { m_hint = hint; } + ecUIHint GetUIHint() const { return m_hint; } + + // Gets the value to display (often an empty string) + wxString GetDisplayValue() const ; + + wxTreeItemId GetTreeItem() const { return m_treeItem; }; + void SetTreeItem(wxTreeItemId id) { m_treeItem = id; }; + + CdlUserVisible GetCdlItem() const { return m_CdlItem; } + void SetCdlItem(CdlUserVisible cdlItem) { m_CdlItem = cdlItem; } + + wxString GetItemNameOrMacro() const; + + bool IsPackage () const { return NULL!=dynamic_cast (GetCdlItem()); } + +//// Operations + // Sets the text and icon for this item + bool UpdateTreeItem(ecConfigTreeCtrl& treeCtrl); + + // Handle a left click on the icon: e.g. (un)check the option + void OnIconLeftDown(ecConfigTreeCtrl& treeCtrl); + + // Can we start editing this item? + bool CanEdit() const; + + // Creates an edit window. It will be positioned by the caller. + wxWindow* CreateEditWindow(wxWindow* parent); + + // Transfers data between item and window + bool TransferDataToWindow(wxWindow* window); + bool TransferDataFromWindow(wxWindow* window); + + // Convert from Cdl to internal representation + bool ConvertFromCdl(); + + // Bump by specified amount, or toggle if a boolean value + bool BumpItem(int nInc); + +//// TAKEN FROM MFC VERSION + + const ecFileName GetFilename () const; + CdlPackage GetOwnerPackage() const { return GetCdlItem()?(dynamic_cast (GetCdlItem()->get_owner ())):NULL; } + bool ChangeVersion (const wxString &strVersion); + CdlValuable GetCdlValuable() const { return dynamic_cast (GetCdlItem()); } + bool Unload(); + wxString GetURL () const; + + bool HasRadio () const; + ecConfigItem *FirstRadio() const; + + ecConfigItem *FirstChild() const; + ecConfigItem *NextSibling() const; + + bool HasModifiedChildren() const; + bool IsEnabled() const; + bool IsActive() const; // Added JACS + + bool Modified() const; + + void DumpItem(); + + ecConfigItem * NextRadio() const; + + bool IsDescendantOf (ecConfigItem *pAncestor); + + bool ViewURL(); + bool ViewHeader(); + + bool HasBool () const; + + long DefaultValue() const; + long Value() const; + const wxString StringValue (CdlValueSource source = CdlValueSource_Current) const; + const wxString StringValue(ecWhereType where) const; + const double DoubleValue (CdlValueSource source = CdlValueSource_Current) const; + const wxString StringDefaultValue() const { return StringValue (CdlValueSource_Default); } + const double DoubleDefaultValue () const { return DoubleValue (CdlValueSource_Default); } + int EvalEnumStrings (wxArrayString &arEnumStrings) const; + + // Convert a string representation of 'where' (e.g. "Macro names") to + // ecWhereType + static ecWhereType WhereStringToType(const wxString& whereString); + + // Convert a type representation of 'where' to a string + static wxString WhereTypeToString(ecWhereType whereType); + +protected: + + bool SetValue (const wxString& value, CdlTransaction transaction=NULL); + bool SetValue (double dValue, CdlTransaction transaction=NULL); + bool SetValue (long nValue, CdlTransaction transaction=NULL); + bool SetEnabled (bool bEnabled, CdlTransaction transaction=NULL); + +protected: + wxString m_name; + wxString m_macro; + bool m_enabled; + bool m_active; + ecConfigType m_configType; + ecOptionType m_optionType; + ecOptionFlavor m_optionFlavor; + ecUIHint m_hint; + wxVariant m_value; + ecConfigItem* m_parent; + wxTreeItemId m_treeItem; + CdlUserVisible m_CdlItem; + wxString m_strDescr; // Description +}; + + +//// TODO: put these in separate file + +/* + * ecTextEditorCtrl + * A specialised wxTextCtrl, for editing string config values + */ + +class ecTextEditorCtrl: public wxTextCtrl +{ +DECLARE_CLASS(ecTextEditorCtrl) +public: +// Ctor(s) + ecTextEditorCtrl(wxWindow* parent, wxWindowID id, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, + long style = 0); + +//// Event handlers + + void OnEnter(wxCommandEvent& event); + void OnKillFocus(wxFocusEvent& event); + void OnLeftDClick(wxMouseEvent& event); + +DECLARE_EVENT_TABLE() + +private: +}; + +/* + * ecDoubleEditorCtrl + * A specialised wxTextCtrl, for editing double config values + */ + +class ecDoubleEditorCtrl: public wxTextCtrl +{ +DECLARE_CLASS(ecDoubleEditorCtrl) +public: +// Ctor(s) + ecDoubleEditorCtrl(wxWindow* parent, wxWindowID id, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, + long style = 0); + +//// Event handlers + + void OnEnter(wxCommandEvent& event); + void OnKillFocus(wxFocusEvent& event); + +DECLARE_EVENT_TABLE() +}; + +/* + * ecIntegerEditorCtrl + * A specialised wxSpinCtrl, for editing integer config values + */ + +class ecIntegerEditorCtrl: public wxSpinCtrl +{ +DECLARE_CLASS(ecIntegerEditorCtrl) +public: +// Ctor(s) + ecIntegerEditorCtrl(wxWindow* parent, wxWindowID id, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, + long style = 0); + +//// Event handlers + + void OnEnter(wxCommandEvent& event); + void OnKillFocus(wxFocusEvent& event); + +DECLARE_EVENT_TABLE() +}; + +/* + * ecEnumEditorCtrl + * A specialised wxChoice, for editing enumerated config values + */ + +class ecEnumEditorCtrl: public wxChoice +{ +DECLARE_CLASS(ecEnumEditorCtrl) +public: +// Ctor(s) + ecEnumEditorCtrl(wxWindow* parent, wxWindowID id, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, + long style = 0); + +//// Event handlers + + void OnChar(wxKeyEvent& event); + void OnKillFocus(wxFocusEvent& event); + +DECLARE_EVENT_TABLE() +}; + +/* + * ecEditStringDialog + * Pops up to make it easier to edit large string values + */ + +class ecEditStringDialog : public ecDialog +{ +public: +// Ctor(s) + ecEditStringDialog(const wxString& initialValue, wxWindow* parent, wxWindowID id, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, + long style = 0); + ~ecEditStringDialog(); + +//// Event handlers + + void OnOK(wxCommandEvent& event); + +//// Operations + void CreateControls(wxWindow* parent); + +//// Accessors + wxString GetValue() const { return m_value; } + +//// Member variables +protected: + DECLARE_EVENT_TABLE() + + wxString m_value; +}; + +#endif + // _ECOS_CONFIGITEM_H_ diff --git a/host/tools/configtool/standalone/wxwin/configpropdlg.cpp b/host/tools/configtool/standalone/wxwin/configpropdlg.cpp new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/configpropdlg.cpp @@ -0,0 +1,143 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +// platformsdlg.cpp : +// +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): julians +// Contact(s): julians +// Date: 2000/09/06 +// Version: $Id: configpropdlg.cpp,v 1.2 2001/03/01 15:54:38 julians Exp $ +// Purpose: +// Description: Implementation file for the ecConfigPropertiesDialog +// Requires: +// Provides: +// See also: +// Known bugs: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== + +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- +#ifdef __GNUG__ +#pragma implementation "configpropdlg.h" +#endif + +// Includes other headers for precompiled compilation +#include "ecpch.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#include "wx/cshelp.h" + +#include "configtool.h" +#include "configpropdlg.h" +#include "propertywin.h" + +BEGIN_EVENT_TABLE(ecConfigPropertiesDialog, wxDialog) + EVT_BUTTON(wxID_OK, ecConfigPropertiesDialog::OnClose) +END_EVENT_TABLE() + +// ---------------------------------------------------------------------------- +// main frame +// ---------------------------------------------------------------------------- + +// Frame constructor +ecConfigPropertiesDialog::ecConfigPropertiesDialog(wxWindow* parent, ecConfigItem* item) +{ + m_listCtrl = NULL; + m_item = item; + + SetExtraStyle(wxDIALOG_EX_CONTEXTHELP); + + wxDialog::Create(parent, ecID_CONFIG_PROPERTIES_DIALOG, _("Configuration Item Properties")); + + CreateControls(this); + + m_listCtrl->Fill(m_item); + + Centre(wxBOTH); +} + +void ecConfigPropertiesDialog::CreateControls(wxWindow* parent) +{ + // Create custom windows first + m_listCtrl = new ecPropertyListCtrl(parent, ecID_CONFIG_PROPERTIES_LIST, wxDefaultPosition, wxSize(450, 300), wxLC_REPORT|wxCLIP_CHILDREN|wxSUNKEN_BORDER|wxLC_VRULES|wxLC_HRULES); + //m_listCtrl->InsertColumn(0, _("Property"), wxLIST_FORMAT_LEFT, 100); + //m_listCtrl->InsertColumn(1, _("Value"), wxLIST_FORMAT_LEFT, 100); + + wxSizer *item0 = new wxBoxSizer( wxVERTICAL ); + + wxWindow *item1 = parent->FindWindow( ecID_CONFIG_PROPERTIES_LIST ); + wxASSERT( item1 ); + item0->Add( item1, 1, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + wxSizer *item2 = new wxBoxSizer( wxHORIZONTAL ); + + item2->Add( 20, 20, 1, wxALIGN_CENTRE|wxALL, 5 ); + + wxButton *item3 = new wxButton( parent, wxID_OK, "&Close", wxDefaultPosition, wxDefaultSize, 0 ); + item2->Add( item3, 0, wxALIGN_CENTRE|wxALL, 5 ); + + item0->Add( item2, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + +#ifdef __WXGTK__ + wxButton *contextButton = new wxContextHelpButton( parent ); + item2->Add( contextButton, 0, wxALIGN_CENTRE|wxALL, 5 ); +#endif + + ((wxButton*) parent->FindWindow(wxID_OK))->SetDefault(); + + parent->SetAutoLayout( TRUE ); + parent->SetSizer( item0 ); + parent->Layout(); + item0->Fit( parent ); + item0->SetSizeHints( parent ); + + // Add context-sensitive help text + parent->FindWindow( ecID_CONFIG_PROPERTIES_LIST )->SetHelpText(_("Displays the properties of the currently selected configuration item. You can double-click on a URL property to navigate to that documentation page or on a File property to view that header file.")); + parent->FindWindow( wxID_OK )->SetHelpText(_("Closes the dialog.")); + +#if __WXGTK__ + parent->FindWindow( wxID_CONTEXT_HELP )->SetHelpText(_("Invokes context-sensitive help for the clicked-on window.")); +#endif + +} + +void ecConfigPropertiesDialog::OnClose(wxCommandEvent& event) +{ + event.Skip(); +} diff --git a/host/tools/configtool/standalone/wxwin/configpropdlg.h b/host/tools/configtool/standalone/wxwin/configpropdlg.h new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/configpropdlg.h @@ -0,0 +1,86 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +// configpropdlg.h : +// +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): julians +// Contact(s): julians +// Date: 2000/10/02 +// Version: $Id: configpropdlg.h,v 1.2 2001/03/01 15:54:38 julians Exp $ +// Purpose: +// Description: Header file for ecConfigPropertiesDialog +// Requires: +// Provides: +// See also: +// Known bugs: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== + +#ifndef _ECOS_CONFIGPROPDLG_H_ +#define _ECOS_CONFIGPROPDLG_H_ + +#ifdef __GNUG__ +#pragma interface "configpropdlg.cpp" +#endif + +#include "wx/wx.h" +#include "wx/listctrl.h" + +// Forward declarations +class ecPropertyListCtrl; +class ecConfigItem; + +class ecConfigPropertiesDialog : public wxDialog +{ +public: +// Ctor(s) + ecConfigPropertiesDialog(wxWindow* parent, ecConfigItem* item); + +//// Event handlers + + void OnClose(wxCommandEvent& event); + +//// Operations + void CreateControls(wxWindow* parent); + +protected: + + ecPropertyListCtrl* m_listCtrl; + ecConfigItem* m_item; + +private: + DECLARE_EVENT_TABLE() +}; + +#define ecID_CONFIG_PROPERTIES_LIST 2064 + + +#endif + // _ECOS_CONFIGPROPDLG_H_ diff --git a/host/tools/configtool/standalone/wxwin/configtool.cpp b/host/tools/configtool/standalone/wxwin/configtool.cpp new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/configtool.cpp @@ -0,0 +1,1193 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +// configtool.cpp : +// +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): julians +// Contact(s): julians +// Date: 2000/08/24 +// Version: $Id: configtool.cpp,v 1.34 2001/05/02 10:36:15 julians Exp $ +// Purpose: +// Description: Implementation file for the ConfigTool application class +// Requires: +// Provides: +// See also: +// Known bugs: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== + +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- +#ifdef __GNUG__ + #pragma implementation "configtool.h" +#endif + +// Includes other headers for precompiled compilation +#include "ecpch.h" + +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + +#include "eCosSocket.h" +#include "eCosTestPlatform.h" + +#include "wx/splash.h" +#include "wx/cshelp.h" +#include "wx/image.h" +#include "wx/filesys.h" +#include "wx/fs_zip.h" +#include "wx/config.h" +#include "wx/cmdline.h" +#include "wx/process.h" +#include "wx/mimetype.h" +#include "wx/txtstrm.h" + +#include "configtool.h" +#include "configtoolview.h" +#include "configtree.h" +#include "mainwin.h" +#include "outputwin.h" +#include "configtooldoc.h" +#include "aboutdlg.h" +#include "shortdescrwin.h" +#include "conflictwin.h" +#include "propertywin.h" + +// ---------------------------------------------------------------------------- +// resources +// ---------------------------------------------------------------------------- +// the application icon +#if defined(__WXGTK__) || defined(__WXMOTIF__) + #include "bitmaps/configtool.xpm" +#endif + +// Create a new application object. +IMPLEMENT_APP(ecApp) + +BEGIN_EVENT_TABLE(ecApp, wxApp) +// Don't handle automatically, or it will bypass more specific processing. +// EVT_MENU(ecID_WHATS_THIS, ecApp::OnWhatsThis) +END_EVENT_TABLE() + +bool ecApp::sm_arMounted[26]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + +static const wxCmdLineEntryDesc sg_cmdLineDesc[] = +{ +/* + { wxCMD_LINE_SWITCH, "v", "verbose", "be verbose" }, + { wxCMD_LINE_SWITCH, "q", "quiet", "be quiet" }, + + { wxCMD_LINE_OPTION, "o", "output", "output file" }, + { wxCMD_LINE_OPTION, "i", "input", "input dir" }, + { wxCMD_LINE_OPTION, "s", "size", "output block size", wxCMD_LINE_VAL_NUMBER }, + { wxCMD_LINE_OPTION, "d", "date", "output file date", wxCMD_LINE_VAL_DATE }, +*/ + + { wxCMD_LINE_PARAM, NULL, NULL, "input file 1", wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL }, + { wxCMD_LINE_PARAM, NULL, NULL, "input file 2", wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL }, + + { wxCMD_LINE_NONE } +}; + +ecApp::ecApp() +{ + m_docManager = NULL; + m_mainFrame = NULL; + m_currentDoc = NULL; + m_whatsThisMenu = new wxMenu; + m_whatsThisMenu->Append(ecID_WHATS_THIS, _("&What's This?")); + m_helpFile = wxEmptyString; + m_splashScreen = NULL; + m_pipedProcess = NULL; + m_valuesLocked = 0; + m_helpController = NULL; +} + +ecApp::~ecApp() +{ + delete m_whatsThisMenu; +} + +// 'Main program' equivalent: the program execution "starts" here +bool ecApp::OnInit() +{ + wxLog::SetTimestamp(NULL); + + CeCosSocket::Init(); + CeCosTestPlatform::Load(); + + wxHelpProvider::Set(new wxSimpleHelpProvider); + //wxHelpProvider::Set(new wxHelpControllerHelpProvider(& m_helpController)); + + wxImage::AddHandler(new wxPNGHandler); + wxImage::AddHandler(new wxGIFHandler); + + // Required for advanced HTML help +#if wxUSE_STREAMS && wxUSE_ZIPSTREAM && wxUSE_ZLIB + wxFileSystem::AddHandler(new wxZipFSHandler); +#endif + + wxString currentDir = wxGetCwd(); + + // Use argv to get current app directory + m_appDir = wxFindAppPath(argv[0], currentDir, wxT("CONFIGTOOLDIR")); + + // If the development version, go up a directory. +#ifdef __WXMSW__ + if ((m_appDir.Right(5).CmpNoCase("DEBUG") == 0) || + (m_appDir.Right(11).CmpNoCase("DEBUGSTABLE") == 0) || + (m_appDir.Right(7).CmpNoCase("RELEASE") == 0) || + (m_appDir.Right(13).CmpNoCase("RELEASESTABLE") == 0) + ) + m_appDir = wxPathOnly(m_appDir); +#endif + + wxGetEnv(wxT("PATH"), & m_strOriginalPath); + + // Create a document manager + m_docManager = new wxDocManager; + + // Create a template relating documents to their views + (void) new wxDocTemplate(m_docManager, "Configtool", "*.ecc", "", "ecc", "Configtool Doc", "Configtool View", + CLASSINFO(ecConfigToolDoc), CLASSINFO(ecConfigToolView)); + + // If we've only got one window, we only get to edit + // one document at a time. + m_docManager->SetMaxDocsOpen(1); + + // Initialize config settings + m_settings.Init(); + + // Let wxWindows know what the app name is + SetAppName(m_settings.GetAppName()); + + InitializeWindowSettings(TRUE /* beforeWindowConstruction */) ; + + // Load config settings + m_settings.LoadConfig(); + +#ifdef __WXMSW__ + wxBitmap bitmap(wxBITMAP(splash)); +#else + wxBitmap bitmap; + if (wxFileExists("splash16.png")) + bitmap.LoadFile("splash16.png", wxBITMAP_TYPE_PNG); +#endif + if (bitmap.Ok() && GetSettings().m_showSplashScreen) + { + m_splashScreen = new ecSplashScreen(bitmap, wxSPLASH_CENTRE_ON_SCREEN|wxSPLASH_TIMEOUT, + 6000, NULL, -1, wxDefaultPosition, wxDefaultSize, wxSIMPLE_BORDER|wxFRAME_FLOAT_ON_PARENT|wxSTAY_ON_TOP); + } + + wxYieldIfNeeded(); + + // create the main application window + ecMainFrame *frame = new ecMainFrame(m_docManager, GetSettings().GetAppName(), + wxPoint(GetSettings().m_frameSize.x, GetSettings().m_frameSize.y), + wxSize(GetSettings().m_frameSize.width, GetSettings().m_frameSize.height)); + +#if 0 + // TODO: eCos.hhp/hhc/hhk will eventually be generated as the app starts up. + if ( !GetHelpController().Initialize(GetFullAppPath(wxT("eCos"))) ) + { + //wxMessageBox(_("Cannot initialize the help system, aborting.")); + //return FALSE; + } +#endif + + m_mainFrame = frame; + SetTopWindow(frame); + frame->Show(TRUE); + SendIdleEvents(); // Otherwise UI updates aren't done, because it's busy loading the repository + + InitializeWindowSettings(FALSE /* beforeWindowConstruction */) ; + + if (m_splashScreen) + m_splashScreen->Raise(); + + wxYieldIfNeeded(); + + // Parse the command-line parameters and options + wxCmdLineParser parser(sg_cmdLineDesc, argc, argv); + int res = parser.Parse(); + if (res == -1 || res > 0) + { + parser.Usage(); + return FALSE; + } + wxString filenameToOpen1, filenameToOpen2; + if (parser.GetParamCount() > 0) + { + wxString tmpSaveFile; + + filenameToOpen1 = parser.GetParam(0); + + if (parser.GetParamCount() > 1) + filenameToOpen2 = parser.GetParam(1); + + bool gotRepository = FALSE; + bool gotSavefile = FALSE; + + wxString repositoryDir, saveFile; + + // Might be e.g. . or .. in path, or relative path + filenameToOpen1 = wxGetRealPath(currentDir, filenameToOpen1); + + if (parser.GetParamCount() > 1) + filenameToOpen2 = wxGetRealPath(currentDir, filenameToOpen2); + + wxString path1, name1, ext1; + wxSplitPath(filenameToOpen1, & path1, & name1, & ext1); + + wxString path2, name2, ext2; + wxSplitPath(filenameToOpen2, & path2, & name2, & ext2); + + // Look at the first file + if (ext1 == "ecc" || ext1 == "ECC") + { + if (wxFileExists(filenameToOpen1)) + { + gotSavefile = TRUE; + saveFile = filenameToOpen1; + } + else + { + wxString msg; + msg.Printf("%s is not a valid file.", (const wxChar*) filenameToOpen1); + wxMessageBox(msg, wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxOK); + return FALSE; + } + } + else if (wxDirExists(filenameToOpen1) && FindSaveFileInDir(filenameToOpen1, tmpSaveFile)) + { + saveFile = tmpSaveFile; + gotSavefile = TRUE; + } + else if ((name1 == wxT("ecos") && ext1 == wxT("db") && wxFileExists(filenameToOpen1)) || wxDirExists(filenameToOpen1)) + { + // It's a repository (we hope). + if (name1 == wxT("ecos") && ext1 == wxT("db")) + { + // Go two steps up + filenameToOpen1 = wxPathOnly(filenameToOpen1); + filenameToOpen1 = wxPathOnly(filenameToOpen1); + } + else + { + // If it's the packages directory, we need to strip off + // a directory + wxString eccPath(filenameToOpen1 + wxString(wxFILE_SEP_PATH) + wxT("ecc")); + + // Don't strip off ecc if it's the CVS repository (with ecc below it) + if (name1 == wxT("packages") || (name1 == wxT("ecc") && !wxDirExists(eccPath))) + filenameToOpen1 = wxPathOnly(filenameToOpen1); + } + + repositoryDir = filenameToOpen1; + gotRepository = TRUE; + } + else + { + wxString msg; + msg.Printf("%s is neither a project file nor a valid repository.", (const wxChar*) filenameToOpen1); + wxMessageBox(msg, wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxOK); + return FALSE; + } + + // Look at the second file, if any + if (parser.GetParamCount() > 1) + { + if (ext2 == "ecc" || ext2 == "ECC") + { + if (wxFileExists(filenameToOpen2)) + { + if (gotSavefile) + { + wxString msg; + msg.Printf("%s is a second save file -- please supply only one.", (const wxChar*) filenameToOpen2); + wxMessageBox(msg, wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxOK); + return FALSE; + } + + gotSavefile = TRUE; + saveFile = filenameToOpen2; + } + else + { + wxString msg; + msg.Printf("%s is not a valid file.", (const wxChar*) filenameToOpen2); + wxMessageBox(msg, wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxOK); + return FALSE; + } + } + else if (!gotSavefile && wxDirExists(filenameToOpen2) && FindSaveFileInDir(filenameToOpen2, tmpSaveFile)) + { + saveFile = tmpSaveFile; + gotSavefile = TRUE; + } + else if ((name2 == wxT("ecos") && ext2 == wxT("db") && wxFileExists(filenameToOpen2)) || wxDirExists(filenameToOpen2)) + { + if (gotRepository) + { + wxString msg; + msg.Printf("%s is a second repository -- please supply only one.", (const wxChar*) filenameToOpen2); + wxMessageBox(msg, wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxOK); + return FALSE; + } + + // It's a repository (we hope). + if (name1 == wxT("ecos") && ext1 == wxT("db")) + { + // Go two steps up + filenameToOpen2 = wxPathOnly(filenameToOpen2); + filenameToOpen2 = wxPathOnly(filenameToOpen2); + } + else + { + // If it's the packages directory, we need to strip off + // a directory + wxString eccPath(filenameToOpen2 + wxString(wxFILE_SEP_PATH) + wxT("ecc")); + + // Don't strip off ecc if it's the CVS repository (with ecc below it) + if (name2 == wxT("packages") || (name2 == wxT("ecc") && !wxDirExists(eccPath))) + filenameToOpen2 = wxPathOnly(filenameToOpen2); + } + + repositoryDir = filenameToOpen2; + gotRepository = TRUE; + } + else + { + wxString msg; + msg.Printf("%s is neither a project file nor a valid repository.", (const wxChar*) filenameToOpen2); + wxMessageBox(msg, wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxOK); + return FALSE; + } + } + + // Now we have looked at the two files and decided what they are; let's + // act on it. + + if (gotRepository) + { + GetSettings().m_strRepository = repositoryDir; + } + + if (!gotSavefile) + { + // See if there's a save file in the current dir + if (FindSaveFileInDir(currentDir, saveFile)) + gotSavefile = TRUE; + } + + if (gotSavefile) + { + // The repository will be loaded from m_strRepository, possibly set above. + m_docManager->CreateDocument(saveFile, wxDOC_SILENT); + } + else + { + // Create a new file + m_docManager->CreateDocument(wxString(""), wxDOC_NEW); + } + } + else + { + m_docManager->CreateDocument(wxString(""), wxDOC_NEW); + } + + return TRUE; +} + +// Initialize window settings object +bool ecApp::InitializeWindowSettings(bool beforeWindowConstruction) +{ + wxWindowSettings& settings = GetSettings().m_windowSettings; + ecMainFrame* frame = GetMainFrame(); + + if (beforeWindowConstruction) + { + settings.Add(wxT("Configuration")); + settings.Add(wxT("Short Description")); + settings.Add(wxT("Output")); + settings.Add(wxT("Properties")); + settings.Add(wxT("Conflicts")); + } + else + { + wxArrayPtrVoid arr; + arr.Add(frame->GetTreeCtrl()); + arr.Add(frame->GetValueWindow()); + settings.SetWindows(wxT("Configuration"), arr); + + settings.SetWindow(wxT("Short Description"), frame->GetShortDescriptionWindow()); + settings.SetWindow(wxT("Output"), frame->GetOutputWindow()); + settings.SetWindow(wxT("Properties"), frame->GetPropertyListWindow()); + settings.SetWindow(wxT("Conflicts"), frame->GetConflictsWindow()); + } + + return TRUE; +} + + +bool ecApp::InitializeHelpController() +{ + if (m_helpController) + delete m_helpController; + m_helpController = new wxHelpController; + + if (!m_helpController->Initialize(GetHelpFile())) + { + // TODO + return FALSE; + } + else + { + // Tell the help controller where the repository documentation is. + // For now, just keep this to myself since it uses hacks to wxWin + ecConfigToolDoc* doc = GetConfigToolDoc(); + + // No longer using relative paths +#if 0 + if (doc) + { + wxString htmlDir = wxString(doc->GetRepository()) + wxString(wxT("/doc/html")); + if (!wxDirExists(htmlDir)) + htmlDir = wxString(doc->GetRepository()) + wxString(wxT("/doc")); + + htmlDir += wxString(wxT("/")); + + wxGetApp().GetHelpController().SetBookBasePath(htmlDir); + } +#endif + return TRUE; + } +} + +// Check if there is a (unique) .ecc file in dir +bool ecApp::FindSaveFileInDir(const wxString& dir, wxString& saveFile) +{ + wxDir fileFind; + + if (!fileFind.Open(dir)) + return FALSE; + + wxString wildcard = wxT(".ecc"); + wxString filename; + + bool found = fileFind.GetFirst (& filename, wildcard); + if (found) + { + // Fail if there was more than one matching file. + wxString filename2; + if (fileFind.GetNext (& filename2)) + return FALSE; + else + { + saveFile = dir + wxString(wxFILE_SEP_PATH) + filename; + return TRUE; + } + } + return FALSE; +} + +int ecApp::OnExit(void) +{ +/* + if (m_helpController) + { + delete m_helpController; + m_helpController = NULL; + } +*/ + + if (m_splashScreen) + { + m_splashScreen->Destroy(); + m_splashScreen = NULL; + } + + m_settings.SaveConfig(); + + { + wxConfig config(wxGetApp().GetSettings().GetConfigAppName(), wxT("Red Hat")); + m_docManager->FileHistorySave(config); + } + + delete m_docManager; + + return 0; +} + +// Prepend the current program directory to the name +wxString ecApp::GetFullAppPath(const wxString& filename) const +{ + wxString path(m_appDir); + if (path.Last() != '\\' && path.Last() != '/' && filename[0] != '\\' && filename[0] != '/') +#ifdef __WXGTK__ + path += '/'; +#else + path += '\\'; +#endif + path += filename; + + return path; +} + +// Are we running in 32K colours or more? +bool ecApp::GetHiColour() const +{ + static bool hiColour = (wxDisplayDepth() >= 16) ; + return hiColour; +} + +// General handler for 'What's this?' +void ecApp::OnWhatsThis(wxCommandEvent& event) +{ + wxObject* obj = event.GetEventObject(); + wxWindow* win = NULL; + + if (obj->IsKindOf(CLASSINFO(wxMenu))) + { + win = ((wxMenu*) obj)->GetInvokingWindow(); + } + else if (obj->IsKindOf(CLASSINFO(wxWindow))) + { + win = (wxWindow*) obj; + } + + wxWindow* subjectOfHelp = win; + bool eventProcessed = FALSE; + wxPoint pt = wxGetMousePosition(); + + while (subjectOfHelp && !eventProcessed) + { + wxHelpEvent helpEvent(wxEVT_HELP, subjectOfHelp->GetId(), pt) ; + helpEvent.SetEventObject(this); + eventProcessed = win->GetEventHandler()->ProcessEvent(helpEvent); + + // Go up the window hierarchy until the event is handled (or not). + // I.e. keep submitting ancestor windows until one is recognised + // by the app code that processes the ids and displays help. + subjectOfHelp = subjectOfHelp->GetParent(); + } + // wxGetApp().GetHelpController().DisplayTextPopup(GetHelpText(), wxGetMousePosition()); +} + +// Log to output window +void ecApp::Log(const wxString& msg) +{ + ecMainFrame* frame = (ecMainFrame*) GetTopWindow(); + if (frame) + { + // TODO is SetInsertionPointEnd necessary? + frame->GetOutputWindow()->SetInsertionPointEnd(); + frame->GetOutputWindow()->AppendText(msg /* + wxT("\n") */ ); + if ((msg == wxEmptyString) || (msg.Last() != wxT('\n'))) + frame->GetOutputWindow()->AppendText(wxT("\n")); + } +} + +void ecApp::SetStatusText(const wxString& text, bool clearFailingRulesPane) +{ + ecMainFrame* mainFrame = GetMainFrame(); + if(mainFrame) + { + mainFrame->GetStatusBar()->SetStatusText(text, ecStatusPane); + if (clearFailingRulesPane) + mainFrame->GetStatusBar()->SetStatusText(wxT(""), ecFailRulePane); +#ifdef __WXMSW__ + wxYield(); +#endif + } +} + +// Config tree control +ecConfigTreeCtrl* ecApp::GetTreeCtrl() const +{ + return GetMainFrame()->GetTreeCtrl(); +} + +// MLT window +ecMemoryLayoutWindow* ecApp::GetMLTWindow() const +{ + return GetMainFrame()->GetMemoryLayoutWindow(); +} + +// Get active document +ecConfigToolDoc* ecApp::GetConfigToolDoc() const +{ + if (m_currentDoc) + return m_currentDoc; + + if (!m_docManager) + return NULL; + + return wxDynamicCast(m_docManager->GetCurrentDocument(), ecConfigToolDoc); +} + +bool ecApp::Launch(const wxString & strFileName,const wxString &strViewer) +{ + bool ok = FALSE; + wxString cmd; + + if (!strViewer.IsEmpty()) + { + cmd = strViewer + wxString(wxT(" ")) + strFileName ; + } + else + { + wxString path, filename, ext; + wxSplitPath(strFileName, & path, & filename, & ext); + + wxFileType *ft = wxTheMimeTypesManager->GetFileTypeFromExtension(ext); + if ( !ft ) + { + wxLogError(_T("Impossible to determine the file type for extension '%s'"), + ext.c_str()); + return FALSE; + } + + bool ok = ft->GetOpenCommand(&cmd, + wxFileType::MessageParameters(strFileName, _T(""))); + delete ft; + + if (!ok) + { + // TODO: some kind of configuration dialog here. + wxMessageBox(_("Could not determine the command for opening this file."), + wxGetApp().GetSettings().GetAppName(), wxOK|wxICON_EXCLAMATION); + return FALSE; + } + } + + ok = (wxExecute(cmd, FALSE) != 0); + + return ok; + +#if 0 + bool rc=false; + + if(!strViewer.IsEmpty())//use custom editor + { + CString strCmdline(strViewer); + + TCHAR *pszCmdLine=strCmdline.GetBuffer(strCmdline.GetLength()); + GetShortPathName(pszCmdLine,pszCmdLine,strCmdline.GetLength()); + strCmdline.ReleaseBuffer(); + + strCmdline+=_TCHAR(' '); + strCmdline+=strFileName; + PROCESS_INFORMATION pi; + STARTUPINFO si; + + si.cb = sizeof(STARTUPINFO); + si.lpReserved = NULL; + si.lpReserved2 = NULL; + si.cbReserved2 = 0; + si.lpDesktop = NULL; + si.dwFlags = 0; + si.lpTitle=NULL; + + if(CreateProcess( + NULL, // app name + //strCmdline.GetBuffer(strCmdline.GetLength()), // command line + strCmdline.GetBuffer(strCmdline.GetLength()), // command line + NULL, // process security + NULL, // thread security + TRUE, // inherit handles + 0, + NULL, // environment + NULL, // current dir + &si, // startup info + &pi)){ + CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); + rc=true; + } else { + CUtils::MessageBoxF(_T("Failed to invoke %s.\n"),strCmdline); + } + strCmdline.ReleaseBuffer(); + } else {// Use association + TCHAR szExe[MAX_PATH]; + HINSTANCE h=FindExecutable(strFileName,_T("."),szExe); + if(int(h)<=32){ + CString str; + switch(int(h)){ + case 0: str=_T("The system is out of memory or resources.");break; + case 31: str=_T("There is no association for the specified file type.");break; + case ERROR_FILE_NOT_FOUND: str=_T("The specified file was not found.");break; + case ERROR_PATH_NOT_FOUND: str=_T("The specified path was not found.");break; + case ERROR_BAD_FORMAT: str=_T("The .EXE file is invalid (non-Win32 .EXE or error in .EXE image).");break; + default: break; + } + CUtils::MessageBoxF(_T("Failed to open document %s.\r\n%s"),strFileName,str); + } else { + + SHELLEXECUTEINFO sei = {sizeof(sei), 0, AfxGetMainWnd()->GetSafeHwnd(), _T("open"), + strFileName, NULL, NULL, SW_SHOWNORMAL, AfxGetInstanceHandle( )}; + + sei.hInstApp=0; + HINSTANCE hInst=ShellExecute(AfxGetMainWnd()->GetSafeHwnd(),_T("open"), strFileName, NULL, _T("."), 0)/*ShellExecuteEx(&sei)*/; + if(int(hInst)<=32/*sei.hInstApp==0*/) + { + CString str; + switch(int(hInst)) + { + case 0 : str=_T("The operating system is out of memory or resources. ");break; + case ERROR_FILE_NOT_FOUND : str=_T("The specified file was not found. ");break; + case ERROR_PATH_NOT_FOUND : str=_T("The specified path was not found. ");break; + case ERROR_BAD_FORMAT : str=_T("The .EXE file is invalid (non-Win32 .EXE or error in .EXE image). ");break; + case SE_ERR_ACCESSDENIED : str=_T("The operating system denied access to the specified file. ");break; + case SE_ERR_ASSOCINCOMPLETE : str=_T("The filename association is incomplete or invalid. ");break; + case SE_ERR_DDEBUSY : str=_T("The DDE transaction could not be completed because other DDE transactions were being processed. ");break; + case SE_ERR_DDEFAIL : str=_T("The DDE transaction failed. ");break; + case SE_ERR_DDETIMEOUT : str=_T("The DDE transaction could not be completed because the request timed out. ");break; + case SE_ERR_DLLNOTFOUND : str=_T("The specified dynamic-link library was not found. ");break; + //case SE_ERR_FNF : str=_T("The specified file was not found. ");break; + case SE_ERR_NOASSOC : str=_T("There is no application associated with the given filename extension. ");break; + case SE_ERR_OOM : str=_T("There was not enough memory to complete the operation. ");break; + //case SE_ERR_PNF : str=_T("The specified path was not found. ");break; + case SE_ERR_SHARE : str=_T("A sharing violation occurred. ");break; + default: str=_T("An unexpected error occurred");break; + } + CUtils::MessageBoxF(_T("Failed to open document %s using %s.\r\n%s"),strFileName,szExe,str); + } else { + rc=true; + } + } + } + return rc; +#endif +} + +bool ecApp::PrepareEnvironment(bool bWithBuildTools, wxString* cmdLine) +{ +#ifdef __WXMSW__ + // Under Windows we can set variables. + ecConfigToolDoc *pDoc = GetConfigToolDoc(); + + wxSetEnv(wxT("PATH"), m_strOriginalPath); + + const wxString strPrefix(pDoc->GetCurrentTargetPrefix()); + ecFileName strBinDir; + bool rc = FALSE; + + rc=(! bWithBuildTools) || GetSettings().m_arstrBinDirs.Find(strPrefix, strBinDir); + if(!rc){ + wxCommandEvent event; + GetMainFrame()->OnBuildToolsPath(event); + rc = GetSettings().m_arstrBinDirs.Find(strPrefix, strBinDir); + } + + if (rc) + { + ecFileName strUserBinDir(GetSettings().m_userToolsDir); + if(strUserBinDir.IsEmpty()) + { + if ( 1 == GetSettings().m_userToolPaths.GetCount() ) + { + GetSettings().m_userToolsDir = GetSettings().m_userToolPaths[0]; + } else + { + wxCommandEvent event; + GetMainFrame()->OnUserToolsPath(event); + } + strUserBinDir = GetSettings().m_userToolsDir; + } + if ( !strUserBinDir.IsEmpty() ) + { + // calculate the directory of the host tools from this application's module name + ecFileName strHostToolsBinDir(this->argv[0]); + strHostToolsBinDir = strHostToolsBinDir.Head (); + + // tools directories are in the order host-tools, user-tools, comp-tools, install/bin (if present), contrib-tools (if present) on the path + const ecFileName strContribBinDir(strUserBinDir, wxT("..\\contrib\\bin")); + ecFileName strUsrBinDir(strUserBinDir, wxT("..\\usr\\bin")); + const ecFileName strInstallBinDir(pDoc->GetInstallTree (), wxT("bin")); + + // In case strUserBinDir is e.g. c:\program files\red hat\cygwin-00r1\usertools\h-i686-pc-cygwin\bin + if (!strUsrBinDir.IsDir ()) + strUsrBinDir = ecFileName(strUserBinDir + _T("..\\..\\..\\H-i686-pc-cygwin\\bin")); + + if ( + (strUsrBinDir.IsDir () && ! ecUtils::AddToPath (strUsrBinDir)) || + (strContribBinDir.IsDir () && ! ecUtils::AddToPath (strContribBinDir)) || + (strInstallBinDir.IsDir () && ! ecUtils::AddToPath (strInstallBinDir)) || + (bWithBuildTools && ! ecUtils::AddToPath (strBinDir)) || + ! ecUtils::AddToPath (strUserBinDir) || + ! ecUtils::AddToPath (strHostToolsBinDir)) + { + wxString msg; + msg.Printf(wxT("Failed to set PATH environment variable")); + wxMessageBox(msg, wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxOK); + rc = FALSE; + } else + { + if(!wxSetEnv(_T("MAKE_MODE"),_T("unix"))) + { + wxString msg; + msg.Printf(wxT("Failed to set MAKE_MODE environment variable")); + wxMessageBox(msg, wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxOK); + rc = FALSE; + } else + { + // Remove from the environment + wxUnsetEnv(wxT("GDBTK_LIBRARY")); + wxUnsetEnv(wxT("GCC_EXEC_PREFIX")); + + // Useful for ecosconfig + wxSetEnv(wxT("ECOS_REPOSITORY"), pDoc->GetPackagesDir()); + + if (! pDoc->GetBuildTree().IsEmpty()) + CygMount(pDoc->GetBuildTree()[0]); + if (! pDoc->GetInstallTree().IsEmpty()) + CygMount(pDoc->GetInstallTree()[0]); + if (! pDoc->GetRepository().IsEmpty()) + CygMount(pDoc->GetRepository()[0]); + } + } + } + } + return rc; +#else + wxASSERT ( cmdLine != NULL ); + + (* cmdLine) = wxEmptyString; + + // Under Unix we need to build up a command line to set variables and invoke make + ecConfigToolDoc *pDoc = GetConfigToolDoc(); + + const wxString strPrefix(pDoc->GetCurrentTargetPrefix()); + ecFileName strBinDir; + bool rc = FALSE; + + rc=(! bWithBuildTools) || GetSettings().m_arstrBinDirs.Find(strPrefix, strBinDir); + if(!rc){ + wxCommandEvent event; + GetMainFrame()->OnBuildToolsPath(event); + rc = GetSettings().m_arstrBinDirs.Find(strPrefix, strBinDir); + } + + if (rc) + { + if (!strBinDir.IsEmpty()) + { + (* cmdLine) += wxString(wxT("export PATH=")) + strBinDir + wxT(":$PATH; "); + + // Also set the path + wxString oldPath(wxGetenv(wxT("PATH"))); + wxString path(strBinDir); + if (!oldPath.IsEmpty()) + path += oldPath; + wxSetEnv(wxT("PATH"), path); + } + (* cmdLine) += wxString(wxT("unset GDBTK_LIBRARY; ")) ; + wxUnsetEnv(wxT("GDBTK_LIBRARY")); + + (* cmdLine) += wxString(wxT("unset GCC_EXEC_PREFIX; ")) ; + wxUnsetEnv(wxT("GCC_EXEC_PREFIX")); + + (* cmdLine) += wxString(wxT("export ECOS_REPOSITORY=")) + pDoc->GetPackagesDir()+ wxT("; "); + wxSetEnv(wxT("ECOS_REPOSITORY"), pDoc->GetPackagesDir()); + +#if 0 + ecFileName strUserBinDir(GetSettings().m_userToolsDir); + if(strUserBinDir.IsEmpty()) + { + if ( 1 == GetSettings().m_userToolPaths.GetCount() ) + { + GetSettings().m_userToolsDir = GetSettings().m_userToolPaths[0]; + } else + { + wxCommandEvent event; + GetMainFrame()->OnUserToolsPath(event); + } + strUserBinDir = GetSettings().m_userToolsDir; + } + if ( !strUserBinDir.IsEmpty() ) + { + // calculate the directory of the host tools from this application's module name + ecFileName strHostToolsBinDir(this->argv[0]); + strHostToolsBinDir = strHostToolsBinDir.Head (); + + // tools directories are in the order host-tools, user-tools, comp-tools, install/bin (if present), contrib-tools (if present) on the path + + // TODO: is this right? Assuming that the user tools are already in the user's path. + // const ecFileName strContribBinDir(strUserBinDir, wxT("..\\contrib\\bin")); + // const ecFileName strUsrBinDir(strUserBinDir, wxT("..\\usr\\bin")); + const ecFileName strInstallBinDir(pDoc->GetInstallTree (), wxT("bin")); + + (* cmdLine) += wxString(wxT("export PATH=")) + strInstallBinDir + wxT(":$PATH; "); + (* cmdLine) += wxString(wxT("unset GDBTK_LIBRARY; ")) ; + (* cmdLine) += wxString(wxT("unset GCC_EXEC_PREFIX; ")) ; + (* cmdLine) += wxString(wxT("export ECOS_REPOSITORY=")) + pDoc->GetPackagesDir()+ wxT("; "); + } +#endif + } + return rc; +#endif +} + +void ecApp::CygMount(wxChar c) +{ + wxASSERT(wxIsalpha(c)); + c = wxTolower(c); + if(!sm_arMounted[c-wxChar('a')]) + { + sm_arMounted[c-wxChar('a')] = TRUE; + wxString strCmd; + + strCmd.Printf(wxT("mount.exe %c: /%c"),c,c); + + wxExecute(strCmd, TRUE); + } +} + +void ecApp::Build(const wxString &strWhat /*=wxT("")*/ ) +{ + if (m_pipedProcess) + return; + + ecConfigToolDoc* pDoc = GetConfigToolDoc(); + if (!pDoc) + return; + + if (!wxGetApp().GetMainFrame()->GetOutputWindow()->IsShown()) + { + wxGetApp().GetMainFrame()->ToggleWindow(ecID_TOGGLE_OUTPUT); + } + if (!pDoc->GetDocumentSaved()) + { + pDoc->SaveAs(); + } +/* + if (pDoc->IsModified() && !wxDirExists(pDoc->GetBuildTree())) + { + pDoc->SaveAs(); + } +*/ +// if ( !(pDoc->IsModified() || !wxDirExists(pDoc->GetBuildTree())) ) // verify the save worked + if ( pDoc->GetDocumentSaved() ) + { + //wxString strCmd (wxT("c:\\bin\\testmake.bat")); + wxString strCmd (wxT("make")); + if(!strWhat.IsEmpty()) + { + strCmd += wxT(' '); + strCmd += strWhat; + } + + if(!GetSettings().m_strMakeOptions.IsEmpty()) + { + strCmd += wxT(' '); + strCmd += GetSettings().m_strMakeOptions; + } + strCmd += wxT(" --directory "); + strCmd += pDoc->GetBuildTree(); + + wxString variableSettings; + + if (PrepareEnvironment(TRUE, & variableSettings)) + { +#ifdef __WXMSW__ + // strCmd is all we need +#else + // strCmd has to invoke a shell with variables and make invocation + strCmd = wxString(wxT("sh -c \"")) + variableSettings + strCmd + wxString(wxT("\"")); +#endif + // Output the command so we know what we're doing + Log(strCmd); + Log(wxT("\n")); + + // No: pass --directory + // wxSetWorkingDirectory(pDoc->GetBuildTree()); + + m_pipedProcess = new ecPipedProcess; + int pid = wxExecute(strCmd, FALSE, m_pipedProcess); + if ( pid ) + { + // wxLogStatus(_T("Process %ld (%s) launched."), pid, cmd.c_str()); + } + else + { + wxLogError(_T("Execution of '%s' failed."), strCmd.c_str()); + + delete m_pipedProcess; + m_pipedProcess = NULL; + } + } + +#if 0 + if(PrepareEnvironment()) + { + m_strBuildTarget=strWhat; + SetThermometerMax(250); // This is just a guess. The thread we are about to spawn will work out the correct answer + m_nLogicalLines=0; + UpdateThermometer(0); + CloseHandle(CreateThread(NULL, 0, ThreadFunc, this, 0 ,&m_dwThreadId)); + CString strMsg; + strMsg.Format(_T("Building %s"),strWhat); + SetIdleMessage(strMsg); + + SetTimer(42,1000,0); // This timer checks for process completion + SetCurrentDirectory(pDoc->BuildTree()); + m_sp.Run(SubprocessOutputFunc, this, strCmd, false); + SetIdleMessage(); + } +#endif + } +#if 0 + + if(pDoc->IsModified()||pDoc->BuildTree().IsEmpty()){ + SendMessage (WM_COMMAND, ID_FILE_SAVE); + } + + if(!(pDoc->IsModified()||pDoc->BuildTree().IsEmpty())){ // verify the save worked + CString strCmd (_T("make")); + if(!strWhat.IsEmpty()){ + strCmd+=_TCHAR(' '); + strCmd+=strWhat; + } + if(!GetApp()->m_strMakeOptions.IsEmpty()){ + strCmd+=_TCHAR(' '); + strCmd+=GetApp()->m_strMakeOptions; + } + + if(PrepareEnvironment()){ + m_strBuildTarget=strWhat; + SetThermometerMax(250); // This is just a guess. The thread we are about to spawn will work out the correct answer + m_nLogicalLines=0; + UpdateThermometer(0); + CloseHandle(CreateThread(NULL, 0, ThreadFunc, this, 0 ,&m_dwThreadId)); + CString strMsg; + strMsg.Format(_T("Building %s"),strWhat); + SetIdleMessage(strMsg); + + SetTimer(42,1000,0); // This timer checks for process completion + SetCurrentDirectory(pDoc->BuildTree()); + m_sp.Run(SubprocessOutputFunc, this, strCmd, false); + SetIdleMessage(); + } + } +#endif +} + +void ecApp::OnProcessTerminated(wxProcess* process) +{ + m_pipedProcess = NULL; +} + +// ---------------------------------------------------------------------------- +// ecPipedProcess +// ---------------------------------------------------------------------------- + +bool ecPipedProcess::HasInput() +{ + bool hasInput = FALSE; + + wxInputStream& is = *GetInputStream(); + if ( !is.Eof() ) + { + wxTextInputStream tis(is); + + // this assumes that the output is always line buffered + wxString msg; + msg << tis.ReadLine(); + + wxGetApp().Log(msg); + + hasInput = TRUE; + } + + wxInputStream& es = *GetErrorStream(); + if ( !es.Eof() ) + { + wxTextInputStream tis(es); + + // this assumes that the output is always line buffered + wxString msg; + msg << tis.ReadLine(); + + wxGetApp().Log(msg); + + hasInput = TRUE; + } + + return hasInput; +} + +void ecPipedProcess::OnTerminate(int pid, int status) +{ + // show the rest of the output + while ( HasInput() ) + ; + + wxGetApp().OnProcessTerminated(this); + + //wxLogStatus(m_parent, _T("Process %u ('%s') terminated with exit code %d."), + // pid, m_cmd.c_str(), status); + + // we're not needed any more + delete this; +} + +void ecPingTimer::Notify() +{ + static bool s_inNotify = FALSE; + + if (s_inNotify) + return; + + s_inNotify = TRUE; + + // On Windows, simply having the timer going will ping the message queue + // and cause idle processing to happen. + // On Unix, this doesn't happen so we have to do the processing explicitly. +#ifdef __WXMSW__ + // Nothing to do +#else + // Get some input + if ( wxGetApp().m_pipedProcess ) + while (wxGetApp().m_pipedProcess->HasInput()) + { + // Loop while there is still input + } +#endif + + s_inNotify = FALSE; +} + diff --git a/host/tools/configtool/standalone/wxwin/configtool.h b/host/tools/configtool/standalone/wxwin/configtool.h new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/configtool.h @@ -0,0 +1,417 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +// configtool.h : +// +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): julians +// Contact(s): julians +// Date: 2000/08/24 +// Version: $Id: configtool.h,v 1.22 2001/05/02 10:36:15 julians Exp $ +// Purpose: +// Description: main header file for the ConfigTool application +// Requires: +// Provides: +// See also: +// Known bugs: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== + +#ifndef _ECOS_CONFIGTOOL_H_ +#define _ECOS_CONFIGTOOL_H_ + +#ifdef __GNUG__ +#pragma interface "configtool.h" +#endif + +#include "wx/wx.h" +#include "wx/help.h" +#include "wx/docview.h" +#include "wx/process.h" +#include "wx/timer.h" +#include "splittree.h" + +#include "appsettings.h" + +class ecValueWindow; +class ecMainFrame; +class ecConfigTreeCtrl; +class ecMemoryLayoutWindow; +class ecConfigToolDoc; +class ecSplashScreen; +class ecPipedProcess; + +/* +#ifdef __WXMSW__ +#include "wx/msw/helpchm.h" +#undef wxHelpController +#define wxHelpController wxCHMHelpController +#endif +*/ + +#if defined(__WXGTK__) || defined(__WXMSW__) +#include "wx/html/helpctrl.h" +#undef wxHelpController +#define wxHelpController wxHtmlHelpController +#endif + +#ifdef __VISUALC__ +#pragma warning(disable:4786) +#endif + +#if defined(__WXMSW__) && defined(__WXDEBUG__) +#define ecUSE_MLT 1 +#else +#define ecUSE_MLT 0 +#endif + +// If 1, can optionally use non-standard wxHTML extension to set the base doc path +// If 0, NEVER uses relative paths. +#define ecDOCSYSTEM_USE_RELATIVE_URLS 1 + +#if defined(__WXMSW__) && defined(__WXDEBUG__) +#define ecUSE_EXPERIMENTAL_CODE 1 +#endif + +// Define a new application type, each program should derive a class from wxApp +class ecApp : public wxApp +{ + friend ecMainFrame; +public: +//// Ctor & dtor + ecApp(); + ~ecApp(); + +//// Operations + virtual bool OnInit(); + virtual int OnExit(); + + // Log to output window + void Log(const wxString& msg); + + // Launch strFileName with the given viewer, or find a viewer if strViewer s empty + bool Launch(const wxString & strFileName,const wxString &strViewer); + + // Under Unix, (*cmdLine) is set to the command string appropriate to setting up the variables + // Under Windows, cmdLine isn't used + bool PrepareEnvironment(bool bWithBuildTools = TRUE, wxString* cmdLine = NULL); + + // Fire off a subprocess to build the library or tests + void Build(const wxString& strWhat = wxEmptyString) ; + + static void CygMount(wxChar c); + + bool InitializeHelpController(); + + void SetStatusText(const wxString& text, bool clearFailingRulesPane = TRUE); + +//// Helpers + // Check if there is a (unique) .ecc file in dir + bool FindSaveFileInDir(const wxString& dir, wxString& saveFile); + + // Initialize window settings object + bool InitializeWindowSettings(bool beforeWindowConstruction); + +//// Accessors + + // Get settings + ecSettings& GetSettings() { return m_settings; } + + // Get help controller + wxHelpController& GetHelpController() { return * m_helpController; } + bool HasHelpController() const { return (m_helpController != NULL); } + void DestroyHelpController() { if (m_helpController) delete m_helpController; m_helpController = NULL; } + + // Get app dir + wxString GetAppDir() const { return m_appDir; } + + // Prepend the current app program directory to the name + wxString GetFullAppPath(const wxString& filename) const; + + // Are we running in 32K colours or more? + bool GetHiColour() const; + + // Get main icon + const wxIcon& GetMainIcon() const { return m_mainIcon; } + void SetMainIcon(const wxIcon& icon) { m_mainIcon = icon; } + + // What's This? menu with single item + wxMenu* GetWhatsThisMenu() const { return m_whatsThisMenu; } + + // Main frame + ecMainFrame* GetMainFrame() const { return m_mainFrame; } + + // Config tree control + ecConfigTreeCtrl* GetTreeCtrl() const ; + + // MLT window + ecMemoryLayoutWindow* GetMLTWindow() const ; + + // Document manager + wxDocManager* GetDocManager() const { return m_docManager; } + + // Get active document + ecConfigToolDoc* GetConfigToolDoc() const; + + wxString GetHelpFile() const { return m_helpFile; } + void SetHelpFile(const wxString& file) { m_helpFile = file; } + + // Lock out value changes while conflicts are being resolved, for example + bool GetValuesLocked() { return (m_valuesLocked > 0); } + void LockValues() { m_valuesLocked ++; } + void UnlockValues() { m_valuesLocked --; wxASSERT( m_valuesLocked >= 0); } + +//// Events + void OnWhatsThis(wxCommandEvent& event); + void OnProcessTerminated(wxProcess* process); + + +//// Data members + ecSettings m_settings; + wxString m_appDir; + wxHelpController* m_helpController; + wxIcon m_mainIcon; // Reuse in dialogs + wxMenu* m_whatsThisMenu; + wxDocManager* m_docManager; + ecMainFrame* m_mainFrame; + static bool sm_arMounted[26]; + int m_valuesLocked; // Lock values from being changed + +public: + + ecSplashScreen* m_splashScreen; + wxString m_strOriginalPath; + ecConfigToolDoc* m_currentDoc; + wxString m_helpFile; + ecPipedProcess* m_pipedProcess; + +DECLARE_EVENT_TABLE() +}; + +DECLARE_APP(ecApp); + +/* + * ecPingTimer + * Just to force idle processing now and again while + * the library or tests are building + */ + +class ecPingTimer: public wxTimer +{ +public: + ecPingTimer() {} + + virtual void Notify() ; +}; + +/* + * ecPipedProcess + * For running builds and capturing the output + */ + +class ecPipedProcess : public wxProcess +{ +public: + ecPipedProcess() + { + Redirect(); + m_pingTimer.Start(100); + } + ~ecPipedProcess() + { + m_pingTimer.Stop(); + } + +//// Overrides + virtual void OnTerminate(int pid, int status); + +//// Operations + virtual bool HasInput(); + +protected: + ecPingTimer m_pingTimer; +}; + +// IDs for the controls and the menu commands + +//// Menus & tools +#define ecID_NEW_REGION 2102 +#define ecID_NEW_SECTION 2103 +#define ecID_DELETE 2104 +#define ecID_PROPERTIES 2105 + +// File menu +#define ecID_IMPORT 2150 +#define ecID_EXPORT 2151 + +// Edit menu +#define ecID_SAVE_OUTPUT 2152 +#define ecID_FIND_NEXT 2153 + +// View menu +#define ecID_SETTINGS 2162 +#define ecID_TOOLBARS 2163 +#define ecID_TOOLBARS_STANDARD 2164 +#define ecID_TOOLBARS_MEMORY 2165 +#define ecID_VIEW_NEXT 2166 +#define ecID_VIEW_PREVIOUS 2167 +#define ecID_TOGGLE_CONFLICTS 2168 +#define ecID_TOGGLE_PROPERTIES 2169 +#define ecID_TOGGLE_MEMORY 2170 +#define ecID_TOGGLE_SHORT_DESCR 2171 +#define ecID_TOGGLE_OUTPUT 2172 + +// Build menu +#define ecID_STOP_BUILD 2180 +#define ecID_BUILD_LIBRARY 2181 +#define ecID_BUILD_TESTS 2182 +#define ecID_CLEAN 2183 +#define ecID_BUILD_OPTIONS 2184 +#define ecID_BUILD_REPOSITORY 2185 +#define ecID_BUILD_TEMPLATES 2186 +#define ecID_BUILD_PACKAGES 2187 + +// Tools menu +#define ecID_PATHS 2200 +#define ecID_PATHS_BUILD_TOOLS 2201 +#define ecID_PATHS_USER_TOOLS 2202 +#define ecID_SHELL 2203 +#define ecID_RUN_TESTS 2204 +#define ecID_PLATFORMS 2205 +#define ecID_RESOLVE_CONFLICTS 2206 +#define ecID_ADMINISTRATION 2207 +#define ecID_TOOLS_OPTIONS 2208 +#define ecID_INDEX_DOCS 2209 + +// Help menu +#define ecID_CONFIGTOOL_HELP 2220 +#define ecID_ECOS_HELP 2221 +#define ecID_REDHAT_WEB 2222 +#define ecID_REDHAT_WEB_HOME 2223 +#define ecID_REDHAT_WEB_ECOS 2224 +#define ecID_REDHAT_WEB_NET_RELEASE 2225 +#define ecID_REDHAT_WEB_UITRON 2226 +#define ecID_CONTEXT_HELP 2227 +#define ecID_REPOSITORY_INFO 2228 + +// Tree right-click menu +#define ecID_WHATS_THIS 2250 +#define ecID_TREE_PROPERTIES 2251 +#define ecID_TREE_RESTORE_DEFAULTS 2252 +#define ecID_TREE_VISIT_DOC 2253 +#define ecID_TREE_VIEW_HEADER 2254 +#define ecID_TREE_UNLOAD_PACKAGE 2255 + +// Conflict window right-click menu +#define ecID_LOCATE_ITEM 2256 +#define ecID_RESOLVE_ITEM 2257 + +//// Controls & windows + +#define ecID_TREE_CTRL 2000 +#define ecID_SPLITTER_WINDOW 2001 +#define ecID_VALUE_WINDOW 2002 +#define ecID_MAIN_FRAME 2003 +#define ecID_SCROLLED_WINDOW 2004 +#define ecID_TOOLBAR 2005 + +#define ecID_CONFLICTS_WINDOW 2006 +#define ecID_PROPERTIES_WINDOW 2007 +#define ecID_MEMORY_WINDOW 2008 +#define ecID_SHORT_DESCR_WINDOW 2009 +#define ecID_OUTPUT_WINDOW 2010 + +#define ecID_CONFIG_SASH_WINDOW 2020 +#define ecID_CONFLICTS_SASH_WINDOW 2021 +#define ecID_PROPERTIES_SASH_WINDOW 2022 +#define ecID_MEMORY_SASH_WINDOW 2023 +#define ecID_SHORT_DESCR_SASH_WINDOW 2024 +#define ecID_OUTPUT_SASH_WINDOW 2025 +#define ecID_ABOUT_DIALOG 2026 +#define ecID_ABOUT_DIALOG_HTML_WINDOW 2027 +#define ecID_FIND_DIALOG 2028 + +// The control used to edit a config item value +#define ecID_ITEM_EDIT_WINDOW 2030 + +#define ecID_SETTINGS_DIALOG 2031 +#define ecID_SETTINGS_NOTEBOOK 2032 +#define ecID_SETTINGS_DISPLAY 2033 +#define ecID_SETTINGS_VIEWER 2034 +#define ecID_SETTINGS_PATH 2035 +#define ecID_SETTINGS_CONFLICT_RESOLUTION 2036 +#define ecID_SETTINGS_RUN 2037 + +#define ecID_SECTION_DIALOG 2040 +#define ecID_SECTION_NOTEBOOK 2041 +#define ecID_SECTION_GENERAL 2042 +#define ecID_SECTION_RELOCATION 2043 +#define ecID_SECTION_NOTE 2044 + +#define ecID_PLATFORM_EDITOR_DIALOG 2050 +#define ecID_BUILD_OPTIONS_DIALOG 2051 +#define ecID_PLATFORMS_DIALOG 2052 +#define ecID_TEMPLATES_DIALOG 2053 +#define ecID_ADMIN_DIALOG 2054 +#define ecID_PACKAGES_DIALOG 2055 + +#define ecID_RUN_TESTS_DIALOG 2056 +#define ecID_RUN_TESTS_NOTEBOOK 2057 +#define ecID_RUN_TESTS_EXECUTABLES 2058 +#define ecID_RUN_TESTS_OUTPUT 2059 +#define ecID_RUN_TESTS_SUMMARY 2060 + +#define ecID_RUN_TESTS_RUN 2061 +#define ecID_RUN_TESTS_PROPERTIES 2062 + +//#define ecID_RUN_TESTS_TEST_LIST 2062 +//#define ecID_RUN_TESTS_SUMMARY_LIST 2063 +//#define ecID_CONFIG_PROPERTIES_LIST 2064 + +#define ecID_CHOOSE_REPOSITORY_DIALOG 2070 +#define ecID_CONFIG_PROPERTIES_DIALOG 2071 + +#define ecID_LICENSE_DIALOG 2080 +#define ecID_LICENSE_TEXT 2081 + +#define ecID_FOLDER_DIALOG 2090 +#define ecID_FOLDER_DIALOG_MSG 2091 +#define ecID_FOLDER_DIALOG_BROWSE 2092 +#define ecID_FOLDER_DIALOG_PATHS 2093 + +#define ecID_REPOS_DIALOG_HTML_WINDOW 2094 +#define ecID_REPOS_DIALOG 2095 + +#define ecID_BUILD_TOOLS_DIALOG 2300 +#define ecID_USER_TOOLS_DIALOG 2301 +#define ecID_EDIT_STRING_DIALOG 2302 +#define ecID_STRING_EDIT_TEXTCTRL 2303 + +#endif + // _ECOS_CONFIGTOOL_H_ diff --git a/host/tools/configtool/standalone/wxwin/configtool.rc b/host/tools/configtool/standalone/wxwin/configtool.rc new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/configtool.rc @@ -0,0 +1,48 @@ +aaaaaaaaaa ICON "bitmaps/configtool.ico" +configtool ICON "bitmaps/configtool.ico" + +open BITMAP "bitmaps/open.bmp" +save BITMAP "bitmaps/save.bmp" +new BITMAP "bitmaps/new.bmp" +copy BITMAP "bitmaps/copy.bmp" +cut BITMAP "bitmaps/cut.bmp" +paste BITMAP "bitmaps/paste.bmp" +help BITMAP "bitmaps/help.bmp" +cshelp BITMAP "bitmaps/cshelp.bmp" + +search BITMAP "bitmaps/search.bmp" +stopbuild BITMAP "bitmaps/stopbuild.bmp" +buildlibrary BITMAP "bitmaps/buildlibrary.bmp" +newregion BITMAP "bitmaps/newregion.bmp" +newsection BITMAP "bitmaps/newsection.bmp" +delete BITMAP "bitmaps/delete.bmp" +properties BITMAP "bitmaps/properties.bmp" +splash BITMAP "bitmaps/splash16.bmp" + +closedfolder ICON "bitmaps/closedfolder.ico" +closedfolder_dis ICON "bitmaps/closedfolder_dis.ico" +package_closed ICON "bitmaps/package_closed.ico" +package_closed_dis ICON "bitmaps/package_closed_dis.ico" +package_open ICON "bitmaps/package_open.ico" +package_open_dis ICON "bitmaps/package_open_dis.ico" +package_version ICON "bitmaps/package_version.ico" +checked ICON "bitmaps/checked.ico" +checked_dis ICON "bitmaps/checked_dis.ico" +unchecked ICON "bitmaps/unchecked.ico" +unchecked_dis ICON "bitmaps/unchecked_dis.ico" +integer ICON "bitmaps/integer.ico" +integer_dis ICON "bitmaps/integer_dis.ico" +integer2 ICON "bitmaps/integer2.ico" +integer2_dis ICON "bitmaps/integer2_dis.ico" +enumerated ICON "bitmaps/enumerated.ico" +enumerated_dis ICON "bitmaps/enumerated_dis.ico" +radioon ICON "bitmaps/radioon.ico" +radioon_dis ICON "bitmaps/radioon_dis.ico" +radiooff ICON "bitmaps/radiooff.ico" +radiooff_dis ICON "bitmaps/radiooff_dis.ico" +text ICON "bitmaps/text.ico" +text_dis ICON "bitmaps/text_dis.ico" + +#include "wx/msw/wx.rc" +#include "wx/html/msw/wxhtml.rc" + diff --git a/host/tools/configtool/standalone/wxwin/configtooldoc.cpp b/host/tools/configtool/standalone/wxwin/configtooldoc.cpp new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/configtooldoc.cpp @@ -0,0 +1,2211 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +// configtooldoc.cpp : +// +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): julians +// Contact(s): julians +// Date: 2000/10/05 +// Version: $Id: configtooldoc.cpp,v 1.28 2001/05/02 13:56:39 julians Exp $ +// Purpose: +// Description: Implementation file for the ecConfigToolDoc class +// Requires: +// Provides: +// See also: +// Known bugs: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== + +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- +#ifdef __GNUG__ +#pragma implementation "configtooldoc.h" +#endif + +// Includes other headers for precompiled compilation +#include "ecpch.h" + +#include "wx/config.h" +#include "wx/textfile.h" +#include "wx/process.h" +#include "wx/mimetype.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#ifdef __WXMSW__ +#include +#include +#include +#include "wx/msw/winundef.h" +#ifdef CreateDirectory +#undef CreateDirectory +#endif +#endif + +#include "configtooldoc.h" +#include "configtoolview.h" +#include "configtree.h" +#include "mainwin.h" +#include "ecutils.h" +#include "filename.h" +#include "choosereposdlg.h" +#include "packagesdlg.h" +#include "conflictsdlg.h" +#include "conflictwin.h" +#include "mltwin.h" +#include "build.hxx" +#include "platformeditordlg.h" +#include "runtestsdlg.h" +#include "propertywin.h" +#include "docsystem.h" + +IMPLEMENT_DYNAMIC_CLASS(ecConfigToolDoc, wxDocument) + +ecConfigToolDoc::ecConfigToolDoc() +{ + m_bRepositoryOpen = FALSE; + m_CdlPkgData = NULL; + m_CdlInterp = NULL; + m_CdlConfig = NULL; + m_ConflictsOutcome = OK; + m_strRepository = wxGetApp().GetSettings().m_strRepository; +} + +ecConfigToolDoc::~ecConfigToolDoc() +{ + wxGetApp().m_currentDoc = NULL; + wxGetApp().GetSettings().m_strRepository = m_strRepository; + + CloseRepository(); + + // Delete remaining items -- most (if not all) should already + // have been deleted via the tree item client data + DeleteItems(); +} + +void ecConfigToolDoc::DeleteItems() +{ + // Delete any remaining items + wxNode* node = m_items.First(); + while (node) + { + ecConfigItem* item = wxDynamicCast(node->Data(), ecConfigItem); + wxNode* next = node->Next(); + + // Note: automatically removes itself from this list in ~ecConfigItem + delete item; + node = next; + } +} + +bool ecConfigToolDoc::OnCloseDocument() +{ + if (wxDocument::OnCloseDocument()) + { + DeleteItems(); + return TRUE; + } + else + { + return FALSE; + } +} + +bool ecConfigToolDoc::OnCreate(const wxString& path, long flags) +{ + wxGetApp().m_currentDoc = this; + + if (flags & wxDOC_NEW) + { + m_bRepositoryOpen = FALSE; + + bool prompt = FALSE; + if (flags & ecDOC_PROMPT_FOR_REPOSITORY) + prompt = TRUE; + + if(!OpenRepository(wxEmptyString, prompt)) + { + wxGetApp().m_currentDoc = NULL; + return FALSE; + } + + Modify(FALSE); + SetDocumentSaved(FALSE); + + wxString rootName(wxT("untitled")); + wxStripExtension(rootName); + SetFilename(wxGetApp().GetSettings().GenerateFilename(rootName)); + } + + // Creates the view, so do any view updating after this + bool success = wxDocument::OnCreate(path, flags); + + if (success) + { + if (flags & wxDOC_NEW) + { + wxBusyCursor wait; + + ecConfigToolHint hint(NULL, ecSelChanged); + UpdateAllViews (NULL, & hint); + + SetFilename(GetFilename(), TRUE); + + // load the memory layout for the default target-platform-startup from the current repository + + // TODO + // m_memoryMap.set_map_size (0xFFFFFFFF); // set the maximum memory map size + // NewMemoryLayout (CFileName (m_strPackagesDir, m_strMemoryLayoutFolder, _T("include\\pkgconf"))); + + wxGetApp().SetStatusText(wxT("Updating build information..."), FALSE); + UpdateBuildInfo(); + } + } + return success; +} + +bool ecConfigToolDoc::OnSaveDocument(const wxString& filename) +{ + wxBusyCursor cursor; + + const wxString strOldPath(GetFilename()); + +#if 0 + bool bSaveAs=(filename!=strOldPath); + if(!IsModified() && wxFileExists(filename)) + { + return TRUE; + } +#endif + + bool rc=FALSE; + if (CheckConflictsBeforeSave()) + { // errors already emitted + + const wxString strPathName(filename); + + wxString str; + str.Printf(_("Saving configuration %s"), (const wxChar*) filename); + + /* TODO + CIdleMessage IM(str); + if(CConfigTool::GetCellView()){ + CConfigTool::GetCellView()->CancelCellEdit(); + } + */ + + // check the configuration + + wxASSERT (m_CdlConfig->check_this (cyg_extreme)); + + // save the configuration + + try + { + m_CdlConfig->save ((const wxChar*) filename); + rc=TRUE; + } + + catch (CdlStringException exception) + { + wxString msg; + msg.Printf(_("Error saving eCos configuration:\n\n%s"), exception.get_message ().c_str ()); + wxMessageBox(msg, wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxOK); + } + + catch (...) + { + wxString msg; + msg.Printf(_("Error saving eCos configuration")); + wxMessageBox(msg, wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxOK); + } + + if(rc){ + rc=FALSE; + SetFilename (filename); // called to ensure that MLTDir() will work in this function TODO?? + + // save the memory layout files to the build tree and copy to the install tree + /* TODO + if (bSaveAs || MemoryMap.map_modified ()) { + SaveMemoryMap(); + } + */ + + ecConfigToolHint hint(NULL, ecAllSaved); + UpdateAllViews (NULL, & hint); + + wxASSERT( !m_strBuildTree.IsEmpty() ); + wxASSERT( !m_strInstallTree.IsEmpty() ); + + ecFileName buildFilename(m_strBuildTree); + ecFileName installFilename(m_strInstallTree); + + if (!buildFilename.CreateDirectory() || !installFilename.CreateDirectory()) + { + wxString msg; + msg.Printf(_("Failed to save %s"), (const wxChar*) filename); + + wxMessageBox(msg, wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION); + rc = FALSE; + } + else if (GenerateHeaders() && CopyMLTFiles()) + { + // in each case errors already emitted + // copy new MLT files to the build tree as necessary + rc=generate_build_tree (GetCdlConfig(), ecUtils::UnicodeToStdStr(m_strBuildTree), ecUtils::UnicodeToStdStr(m_strInstallTree)); + rc = TRUE; + } + + } + } + if(rc) + { + Modify(FALSE); + SetDocumentSaved(TRUE); + SetFilename(filename); + wxGetApp().GetSettings().m_lastFilename = filename; + } else + { + SetFilename(strOldPath); + } + return rc; +} + +bool ecConfigToolDoc::OnOpenDocument(const wxString& filename) +{ + wxGetApp().GetSettings().m_lastFilename = filename; + + wxBusyCursor cursor; + + bool rc=FALSE; // Assume the worst + CdlInterpreter NewCdlInterp = NULL; + CdlConfiguration NewCdlConfig = NULL; + + // We have to open the repository or m_CdlPkgData and co. won't be set + if (!OpenRepository()) + return FALSE; + + wxString str; + str.Printf(_("Opening save file %s"), (const wxChar*) filename); + wxGetApp().SetStatusText(str); + + EnableCallbacks(FALSE); + + try + { + NewCdlInterp = CdlInterpreterBody::make (); + NewCdlConfig = CdlConfigurationBody::load ((const wxChar*) filename, m_CdlPkgData, NewCdlInterp, &CdlLoadErrorHandler, &CdlLoadWarningHandler); + rc = TRUE; + } + catch (CdlStringException exception) + { + wxString msg; + msg.Printf(_("Error opening eCos configuration:\n\n%s"), exception.get_message ().c_str ()); + wxMessageBox(msg, wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxOK); + } + catch (...) + { + wxString msg; + msg.Printf(_("Error opening eCos configuration")); + wxMessageBox(msg, wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxOK); + } + + if (rc) + { + rc=FALSE; + // check the new configuration + + wxASSERT (NewCdlConfig->check_this (cyg_extreme)); + + // switch to the new configuration + + delete m_CdlConfig; + delete m_CdlInterp; + m_CdlInterp = NewCdlInterp; + m_CdlConfig = NewCdlConfig; + //SetPathName (lpszPathName, TRUE); // called to ensure that MLTDir() will work in this function + + AddAllItems (); // must precede NewMemoryLayout() [CurrentLinkerScript() calls Find()] + + // load the memory layout from the build tree + // TODO + NewMemoryLayout (MLTDir ()); + + UpdateFailingRuleCount(); + + UpdateBuildInfo(); + + rc = TRUE; + + SetFilename(filename); + + ecConfigToolHint hint(NULL, ecFilenameChanged); + UpdateAllViews (NULL, & hint); + } + + // re-enable the transaction callback + EnableCallbacks(TRUE); + + SetDocumentSaved(TRUE); // Necessary or it will pop up the Save As dialog + + wxGetApp().SetStatusText(wxEmptyString, FALSE); + + return rc; +} + +void ecConfigToolDoc::AddAllItems() +{ + ecConfigTreeCtrl* treeCtrl = wxGetApp().GetMainFrame()->GetTreeCtrl(); + // Ensure there's no dangling pointer + wxGetApp().GetMainFrame()->GetPropertyListWindow()->Fill(NULL); + + treeCtrl->DeleteAllItems(); + + m_strMemoryLayoutFolder = wxT(""); + m_strLinkerScriptFolder = wxT(""); + + // Add the root item + ecConfigItem* item = NULL; + wxTreeItemId rootId = treeCtrl->AddRoot(_(""), -1, -1, new ecTreeItemData(item = new ecConfigItem(NULL, _("Configuration"), ecContainer))); + item->SetTreeItem(rootId); + item->UpdateTreeItem(* treeCtrl); + item->SetDescription(_("The root node for all configurable items")); + m_items.Append(item); + + AddContents(m_CdlConfig, item); + treeCtrl->Expand(rootId); + + // check that exactly one radio button in each group is enabled + CheckRadios (); + + // update the rules (conflicts) view + UpdateFailingRuleCount (); + + if( ! wxGetApp().GetMainFrame() || ! wxGetApp().GetMainFrame()->GetConflictsWindow() || + ! wxGetApp().GetMainFrame()->GetConflictsWindow()->IsShown()) + { + // log all conflicts + // LogConflicts (m_CdlConfig->get_structural_conflicts ()); // relating to package availability - ignore for now + LogConflicts (m_CdlConfig->get_all_conflicts ()); + } + + wxGetApp().GetTreeCtrl()->SelectItem(wxGetApp().GetTreeCtrl()->GetRootItem()); + //ecConfigToolHint hint(item, ecValueChanged); + ecConfigToolHint hint(NULL, ecSelChanged); + + UpdateAllViews (NULL, & hint); + + if(GetItems().Number()>0){ + wxGetApp().GetTreeCtrl()->Expand(rootId); + } + wxGetApp().GetTreeCtrl()->SetFocus(); +} + +void ecConfigToolDoc::AddContents (const CdlContainer container, ecConfigItem *pParent) +{ + // determine the container contents + + const std::vector& contents = container->get_contents (); + std::vector::const_iterator node_i; + for (node_i = contents.begin (); node_i != contents.end (); node_i++) + { + const CdlNode node = * node_i; + const CdlPackage pkg = dynamic_cast (node); + const CdlComponent comp = dynamic_cast (node); + const CdlOption opt = dynamic_cast (node); + const CdlContainer contnr = dynamic_cast (node); + + // if the node in the container is a package, component or option + // then it is visible and should be added to the tree + if (0 != pkg) // the node is a package + { + ecConfigItem * pItem = AddItem (pkg, pParent); // add the package + AddContents (pkg, pItem); // add the package contents + } + else if (0 != comp) // the node is a component + { + ecConfigItem * pItem = AddItem (comp, pParent); // add the component + AddContents (comp, pItem); // add the component contents + } + else if (0 != opt) // the node is an option + AddItem (opt, pParent); // add the option + + else if (0 != contnr) // if the node is a container + AddContents (contnr, pParent); // add the container contents + + // ignore nodes of any other class + } +} + +ecConfigItem * ecConfigToolDoc::AddItem (const CdlUserVisible vitem, ecConfigItem * pParent) +{ + ecConfigItem * pItem = new ecConfigItem (pParent, vitem); + + m_items.Append(pItem); + + if (vitem->get_name () == "CYGHWR_MEMORY_LAYOUT") + { + wxASSERT (m_strMemoryLayoutFolder.IsEmpty ()); + m_strMemoryLayoutFolder = vitem->get_owner ()->get_directory().c_str (); +#ifdef __WXMSW__ + m_strMemoryLayoutFolder.Replace(wxT("/"),wxT("\\")); +#endif + //TRACE (_T("Found memory layout folder: %s\n"), m_strMemoryLayoutFolder); + } + + if (vitem->get_name () == "CYGBLD_LINKER_SCRIPT") + { + wxASSERT (m_strLinkerScriptFolder.IsEmpty ()); + m_strLinkerScriptFolder = vitem->get_owner ()->get_directory().c_str (); +#ifdef __WXMSW__ + m_strLinkerScriptFolder.Replace(wxT("/"),wxT("\\")); +#endif + //TRACE (_T("Found linker script folder: %s\n"), m_strLinkerScriptFolder); + + // the CDL hardware template name will eventually become the target name, + // but for now we must deduce the target name from the linker script file name + + const CdlValuable valuable = dynamic_cast (vitem); + ecFileName strLinkerScript (m_strPackagesDir, m_strLinkerScriptFolder, wxString (valuable->get_value ().c_str ())); + +#ifdef __WXMSW__ + strLinkerScript.Replace (wxT("/"), wxT("\\")); +#endif + + if(!strLinkerScript.Exists ()){ + wxString msg; + msg.Printf(wxT("%s does not exist\n"), (const wxChar*) strLinkerScript); + wxGetApp().Log(msg); + } + //TRACE (_T("Target '%s' selected\n"), strLinkerScript.Tail ().Root (), pItem->Macro()); + } + + //TRACE(_T("Created new item from cdl: ")); + //pItem->DumpItem(); + return pItem; +} + +void ecConfigToolDoc::CheckRadios() +{ + int nItem; + for(nItem=0; nItem < GetItems().Number() ; nItem++) + { + ecConfigItem *pItem=(ecConfigItem*) GetItems()[nItem]; + + if(pItem->HasRadio () && pItem==pItem->FirstRadio()) + { + wxString strMsg; + ecConfigItem *pFirstSet=NULL; + ecConfigItem *pSibItem; + + for ( pSibItem=pItem; pSibItem; pSibItem = pSibItem->NextRadio() ) + { + if(pSibItem->IsEnabled ()) + { + if(pFirstSet) + { + strMsg += wxT(" "); + strMsg += pSibItem->GetMacro (); + } else + { + pFirstSet = pSibItem; + } + } + } + + if ( !strMsg.IsEmpty() ) + { + wxString msg2; + msg2.Printf(_("%s, multiple radio buttons are set: %s%s"), + (const wxChar*) pItem->GetMacro(), (const wxChar*) pFirstSet->GetMacro(), (const wxChar*) strMsg); + wxGetApp().Log(msg2); + } else if ( !pFirstSet ) + { + wxString msg2; + msg2.Printf(_("%s, no radio buttons are set"), (const wxChar*) pItem->GetMacro()); + wxGetApp().Log(msg2); + } + } + } +} + +// Find the ecConfigItem referencing the given CdlValuable +ecConfigItem * ecConfigToolDoc::Find (CdlValuable v) +{ + int nItem; + for (nItem=0 ; nItem < m_items.Number() ; nItem++) + { + ecConfigItem *pItem = (ecConfigItem*) m_items[nItem]; + if( v == pItem->GetCdlValuable() ) + { + return pItem; + } + } + return NULL; +} + +ecConfigItem * ecConfigToolDoc::Find(const wxString & strWhat, ecWhereType where) +{ + int nItem; + for (nItem=0 ; nItem < m_items.Number() ; nItem++) + { + ecConfigItem *pItem = (ecConfigItem*) m_items[nItem]; + if (pItem->StringValue(where) == strWhat) + { + return pItem; + } + } + return NULL; +} + +// a trivial CDL load error handler +void ecConfigToolDoc::CdlLoadErrorHandler (std::string message) +{ + wxGetApp().Log(message.c_str()); +}; + +// a trivial CDL load warning handler +void ecConfigToolDoc::CdlLoadWarningHandler (std::string message) +{ + wxGetApp().Log(message.c_str()); +}; + +// a trivial CDL parse error handler +void ecConfigToolDoc::CdlParseErrorHandler (std::string message) +{ + wxGetApp().Log(message.c_str()); +}; + +// a trivial CDL parse warning handler +void ecConfigToolDoc::CdlParseWarningHandler (std::string message) +{ + wxGetApp().Log(message.c_str()); +}; + + +void ecConfigToolDoc::CloseRepository() +{ + if(m_bRepositoryOpen){ + // delete the libCDL objects with the document + EnableCallbacks(FALSE); // first disable the transaction handler + delete m_CdlConfig; m_CdlConfig = NULL; + delete m_CdlInterp; m_CdlInterp = NULL; + delete m_CdlPkgData; m_CdlPkgData = NULL; + m_bRepositoryOpen=FALSE; + } +} + +bool ecConfigToolDoc::OpenRepository(const wxString& pszRepository /* = wxEmptyString */, bool bPromptInitially/* =FALSE */) +{ + ecMainFrame* mainFrame = wxGetApp().GetMainFrame(); + if(!m_bRepositoryOpen) + { + UpdateFailingRuleCount(); + + wxString strNewRepository; + while(!m_bRepositoryOpen) + { + if(bPromptInitially) + { + ecChooseRepositoryDialog dlg(wxGetApp().GetTopWindow()); + + if(wxID_CANCEL==dlg.ShowModal()){ + wxGetApp().SetStatusText(wxEmptyString); + return FALSE; + } + strNewRepository=dlg.GetFolder(); + } else + { + // Use what came in as parameter or what was found in registry + if (!pszRepository.IsEmpty()) + strNewRepository = pszRepository; + else + strNewRepository = m_strRepository; + + bPromptInitially=TRUE; + } + wxString str; + if (strNewRepository.IsEmpty()) + str.Printf(_("Opening repository...")); + else + str.Printf(_("Opening repository %s..."), (const wxChar*) strNewRepository); + wxGetApp().SetStatusText(str); + + CdlPackagesDatabase NewCdlPkgData = NULL; + CdlInterpreter NewCdlInterp = NULL; + CdlConfiguration NewCdlConfig = NULL; + wxString strNewPackagesDir; + + EnableCallbacks(FALSE); // disable transaction callbacks until the config tree is regenerated + + wxBusyCursor wait; + if(OpenRepository(strNewRepository,NewCdlPkgData,NewCdlInterp,NewCdlConfig,strNewPackagesDir)) + { + // select the "default" template if it exists + // otherwise select the first available template + + std::string default_template = "default"; + if (! NewCdlPkgData->is_known_template (default_template)) + { + const std::vector& templates = NewCdlPkgData->get_templates (); + if (templates.size () != 0) + default_template = templates [0]; + } + + m_templateVersion = ""; + try + { + const std::vector& template_versions = NewCdlPkgData->get_template_versions (default_template); + NewCdlConfig->set_template (default_template, template_versions [0], &CdlParseErrorHandler, &CdlParseWarningHandler); + m_templateVersion = template_versions [0].c_str(); + } + catch (CdlStringException exception) { + wxString msg; + msg.Printf(_("Error loading package template '%s':\n\n%s"), default_template.c_str (), exception.get_message ().c_str ()); + wxMessageBox(msg, wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxOK); + } + catch (...) { + wxString msg; + msg.Printf(_("Error loading package template '%s'."), default_template.c_str ()); + wxMessageBox(msg, wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxOK); + } + + // check the configuration + wxASSERT (NewCdlConfig->check_this (cyg_extreme)); + + // use the new package database, interpreter and configuration + delete m_CdlConfig; // delete the previous configuration + delete m_CdlInterp; // delete the previous interpreter + delete m_CdlPkgData; // delete the previous package database + + m_CdlPkgData = NewCdlPkgData; + m_CdlInterp = NewCdlInterp; + m_CdlConfig = NewCdlConfig; + + // save the repository location + + SetRepository(strNewRepository); + m_strPackagesDir = strNewPackagesDir; + + // clear the previously specified document file name (if any), + // OnNewDocument() calls DeleteContents() so must be called + // before AddAllItems() + + wxDocument::OnNewDocument (); + + // generate the CConfigItems from their CDL descriptions + AddAllItems (); + + m_bRepositoryOpen=TRUE; + + // Rebuild help index if it needs building + RebuildHelpIndex(FALSE); + + } else { + // failure + delete NewCdlConfig; NewCdlConfig = NULL; + delete NewCdlInterp; NewCdlInterp = NULL; + delete NewCdlPkgData; NewCdlPkgData = NULL; + + } + + // install a transaction handler callback function now that the tree exists + EnableCallbacks(TRUE); + } + + } + wxGetApp().SetStatusText(wxEmptyString, FALSE); + return m_bRepositoryOpen; +} + +bool ecConfigToolDoc::OpenRepository (const ecFileName& strNewRepository, CdlPackagesDatabase &NewCdlPkgData,CdlInterpreter &NewCdlInterp,CdlConfiguration &NewCdlConfig, wxString &strNewPackagesDir) +{ + bool rc=FALSE; + + if(!strNewRepository.IsEmpty()) + { + // Now strNewRepository is guaranteed non-empty, but does it exist? + if(!wxDirExists(strNewRepository)) + { + wxString msg; + msg.Printf(_("Cannot open repository - the folder %s does not exist"), (const wxChar*) strNewRepository); + wxMessageBox(msg, wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxOK); + } else + { + // Ok so it exists, but does it look right? + //strNewPackagesDir=strNewRepository+wxString(wxFILE_SEP_PATH)+wxT("ecc"); + strNewPackagesDir=strNewRepository + wxT("ecc"); + if(!wxDirExists(strNewPackagesDir)) + { + //strNewPackagesDir=strNewRepository+wxString(wxFILE_SEP_PATH)+wxT("packages"); + strNewPackagesDir=strNewRepository + wxT("packages"); + } + + if(!wxDirExists(strNewPackagesDir)) + { + // Don't mention the ecc\ attempt + wxString msg; + msg.Printf(_("%s does not seem to be a source repository: the folder %s does not exist"), + (const wxChar*) strNewRepository, (const wxChar*) strNewPackagesDir); + wxMessageBox(msg, wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxOK); + } else { + + const wxString strDatabase = strNewPackagesDir + wxString(wxFILE_SEP_PATH) + wxT("ecos.db"); + if(!wxFileExists(strDatabase)) + { + wxString msg; + msg.Printf(_("%s does not seem to be a source repository: %s does not exist"), (const wxChar*) strNewRepository, (const wxChar*) strDatabase); + wxMessageBox(msg, wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxOK); + } else { + + // create a CDL repository, interpreter and configuration + try {// create a new package database, interpreter and configuration + NewCdlPkgData = CdlPackagesDatabaseBody::make ((const wxChar*) strNewPackagesDir, &CdlParseErrorHandler, &CdlParseWarningHandler); + NewCdlInterp = CdlInterpreterBody::make (); + NewCdlConfig = CdlConfigurationBody::make ("eCos", NewCdlPkgData, NewCdlInterp); + } + catch (CdlStringException exception) + { + wxString msg; + msg.Printf(_("Error opening eCos repository:\n\n%s"), exception.get_message ().c_str ()); + wxMessageBox(msg, wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxOK); + return FALSE; + } + catch (...) + { + wxString msg; + msg.Printf(_("Error opening eCos repository.")); + wxMessageBox(msg, wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxOK); + return FALSE; + } + + // select the default target if specified in the registry + // otherwise select the first available target + wxString default_hardware = GetDefaultHardware (); + + if (! NewCdlPkgData->is_known_target ((const wxChar*) default_hardware)) { + const std::vector& targets = NewCdlPkgData->get_targets (); + if (targets.size () == 0) + { + wxString msg; + msg.Printf(_("Error opening eCos repository:\n\nno hardware templates")); + wxMessageBox(msg, wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxOK); + return FALSE; + } else { + default_hardware = targets [0].c_str(); + } + } + + try { + m_strCdlErrorMessage = wxT(""); + NewCdlConfig->set_hardware ((const wxChar*) default_hardware, &CdlParseErrorHandler, &CdlParseWarningHandler); + } + catch (CdlStringException exception) { + if (m_strCdlErrorMessage.IsEmpty ()) + { + wxString msg; + msg.Printf(_("Error loading the default hardware template '%s':\n\n%s"), default_hardware.c_str (), exception.get_message ().c_str ()); + wxMessageBox(msg, wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxOK); + } + else // report the most recent parser message in the message box since there may be no output pane in which to view it + { + wxString msg; + msg.Printf(_("Error loading the default hardware template '%s':\n\n%s\n\nParser message:\n\n%s"), default_hardware.c_str (), exception.get_message ().c_str (), (const wxChar*) m_strCdlErrorMessage); + wxMessageBox(msg, wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxOK); + } + return FALSE; + } + catch (...) { + wxString msg; + msg.Printf(_("Error loading the default hardware template '%s':\n\n%s"), default_hardware.c_str (), (const wxChar*) m_strCdlErrorMessage); + wxMessageBox(msg, wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxOK); + return FALSE; + } + rc=TRUE; + } + } + } + } + + return rc; +} + +void ecConfigToolDoc::SelectTemplate (const wxString& newTemplate, const wxString& newTemplateVersion) +{ + if ((newTemplate != m_CdlConfig->get_template().c_str()) || (newTemplateVersion != m_templateVersion)){ + + wxBusyCursor wait; // this may take a little while + DeleteItems(); + + m_templateVersion = wxT(""); + try + { + m_CdlConfig->set_template (newTemplate.c_str(), newTemplateVersion.c_str(), CdlParseErrorHandler, CdlParseWarningHandler); + m_templateVersion = newTemplateVersion; + } + catch (CdlStringException exception) + { + wxString msg; + msg.Printf(wxT("Error loading package template '%s':\n\n%s"), (const wxChar*) newTemplate.c_str (), (const wxChar*) exception.get_message ().c_str ()); + wxMessageBox(msg, wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxOK); + } + catch (...) + { + wxString msg; + msg.Printf(wxT("Error loading package template '%s'."), (const wxChar*) newTemplate.c_str ()); + wxMessageBox(msg, wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxOK); + } + RegenerateData(); + + if (!GetFilename().IsEmpty()) + { // not a new document +#if 0 // TODO + CopyMLTFiles (); // copy new MLT files to the build tree as necessary +#endif + } + Modify(TRUE); + wxGetApp().GetMainFrame()->UpdateFrameTitle(); + } +} + +void ecConfigToolDoc::RegenerateData() +{ + wxBusyCursor wait; // This may take a little while + AddAllItems (); // regenerate all the config items since the topology may have changed + if (m_strLinkerScriptFolder.IsEmpty ()) + { + wxMessageBox(_("The eCos linker script macro CYGBLD_LINKER_SCRIPT is not defined."), wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxOK); + } + if (m_strMemoryLayoutFolder.IsEmpty ()) + { + wxMessageBox(_("The eCos memory layout macro CYGHWR_MEMORY_LAYOUT is not defined."), wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxOK); + } + // TODO +#if 0 + SwitchMemoryLayout (TRUE); // the hardware template may have changed +#endif + + UpdateBuildInfo(); + // TODO + // CConfigTool::GetControlView()->SelectItem(Item(0)); +} + +void ecConfigToolDoc::SelectHardware (const wxString& newTemplate) +{ + const std::string OldTemplate=m_CdlConfig->get_hardware(); + if (newTemplate != OldTemplate.c_str()){ + DeleteItems(); + + try + { + m_CdlConfig->set_hardware (newTemplate.c_str(), CdlParseErrorHandler, CdlParseWarningHandler); + } + catch (CdlStringException exception) + { + wxString msg; + msg.Printf(_("Error loading hardware template '%s':\n\n%s"), (const wxChar*) newTemplate, (const wxChar*) exception.get_message ().c_str ()); + wxMessageBox(msg, wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxOK); + m_CdlConfig->set_hardware (OldTemplate, CdlParseErrorHandler, CdlParseWarningHandler); + } + catch (...) + { + wxString msg; + msg.Printf(_("Error loading hardware template '%s'."), (const wxChar*) newTemplate); + wxMessageBox(msg, wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxOK); + m_CdlConfig->set_hardware (OldTemplate, CdlParseErrorHandler, CdlParseWarningHandler); + } + + RegenerateData(); + + // TODO +#if 0 + if (!GetFilename().IsEmpty()) + { + CopyMLTFiles (); // copy new MLT files to the build tree as necessary + } +#endif + + Modify(TRUE); + wxGetApp().GetMainFrame()->UpdateFrameTitle(); + } +} + +void ecConfigToolDoc::SelectPackages () +{ + ecPackagesDialog dlg(wxGetApp().GetTopWindow()); + + // This map holds the ecConfigItem pointers for the packages loaded before the dialog is invoked. + // We cannot use Find(), which traverses all items - potentially those that have been removed + //CMapStringToPtr arLoadedPackages; + wxHashTable arLoadedPackages(wxKEY_STRING); + + wxBeginBusyCursor(); + + // generate the contents of the add/remove list boxes + const std::vector & packages = m_CdlPkgData->get_packages (); + std::vector::const_iterator package_i; + for (package_i = packages.begin (); package_i != packages.end (); package_i++) + { + // if (! m_CdlPkgData->is_hardware_package (* package_i)) // do not list hardware packages + { + const std::vector & aliases = m_CdlPkgData->get_package_aliases (* package_i); + wxString strMacroName = package_i->c_str (); + + // use the first alias (if any) as the package identifier + wxString strPackageName = aliases.size () ? aliases [0].c_str () : strMacroName.c_str(); + ecConfigItem * pItem = Find (strMacroName); + if (pItem) // if the package is loaded + { + arLoadedPackages.Put(strMacroName, pItem); + // pass the currently selected package version string to the dialog box + const CdlValuable valuable = pItem->GetCdlValuable(); + dlg.Insert (strPackageName, TRUE, wxEmptyString, valuable ? wxString (valuable->get_value ().c_str ()) : wxString()); + } + else + { + // pass version string of the most latest version to the dialog box + dlg.Insert (strPackageName, FALSE, wxEmptyString, wxString (m_CdlPkgData->get_package_versions (* package_i) [0].c_str ())); + } + } + } + + wxEndBusyCursor(); + + if (wxID_OK == dlg.ShowModal ()) + { + bool bChanged = FALSE; // until proved otherwise + + // determine whether each package has changed loaded/unloaded state + for (package_i = packages.begin (); package_i != packages.end (); package_i++) + // if (! m_CdlPkgData->is_hardware_package (* package_i)) // do not check hardware packages + { + const std::vector & aliases = m_CdlPkgData->get_package_aliases (* package_i); + wxString strMacroName = package_i->c_str (); + + // use the first alias (if any) as the package identifier + wxString strPackageName = aliases.size () ? aliases [0].c_str () : strMacroName.c_str(); + + ecConfigItem *pItem = (ecConfigItem *) arLoadedPackages.Get(strMacroName); + //bool bPreviouslyLoaded=arLoadedPackages.Lookup(strMacroName,(void *&)pItem); + bool bPreviouslyLoaded = (pItem != NULL); + bool bNowLoaded=dlg.IsAdded (strPackageName); + + // unload packages which are no longer required before + // loading new ones to avoid potential duplicate macro definitions + if (! bNowLoaded && bPreviouslyLoaded){ + // The package was loaded but should now be unloaded: + bChanged|=pItem->Unload(); + } else if (bNowLoaded) {// if the package should be loaded + const wxString strVersion(dlg.GetVersion (strPackageName)); + if (bPreviouslyLoaded) { // if the package is already loaded + CdlTransactionCallback::set_callback_fn (NULL); // avoid value refresh attempts during load/unload + bChanged|=pItem->ChangeVersion(strVersion); + CdlTransactionCallback::set_callback_fn (CdlTransactionHandler); // restore value refresh + } else { + // the package was not loaded but should now be loaded + //TRACE (_T("Loading package %s\n"), strMacroName); + try + { + GetCdlConfig()->load_package (ecUtils::UnicodeToStdStr(strMacroName), ecUtils::UnicodeToStdStr (strVersion), ecConfigToolDoc::CdlParseErrorHandler, ecConfigToolDoc::CdlParseWarningHandler); + bChanged=true; + } + catch (CdlStringException exception) + { + wxString msg; + msg.Printf(_("Error loading package %s:\n\n%s"), (const wxChar*) strMacroName, (const wxChar*) exception.get_message ().c_str ()); + wxMessageBox(msg, wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxOK); + } + catch (...) + { + wxString msg; + msg.Printf(_("Error loading package %s"), (const wxChar*) strMacroName); + wxMessageBox(msg, wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxOK); + } + } + } + } + + if (bChanged) {// at least one package was loaded, unloaded or changed version + Modify(TRUE); + wxGetApp().GetMainFrame()->UpdateFrameTitle(); + RegenerateData(); + } + } +} + + +bool ecConfigToolDoc::UpdateBuildInfo(bool WXUNUSED(bFirstTime)) +{ + try { + GetCdlConfig()->get_build_info(m_BuildInfo); + generate_build_tree (GetCdlConfig(), ecUtils::UnicodeToStdStr(GetBuildTree()), ecUtils::UnicodeToStdStr(GetInstallTree())); + return TRUE; + } + catch(...){ + return FALSE; + } +} + +wxString ecConfigToolDoc::GetDefaultHardware () +{ +#ifdef __WXMSW__ + // get the greatest eCos version subkey + wxConfig config(wxT("eCos"), wxT("Red Hat"), wxEmptyString, wxEmptyString, wxCONFIG_USE_GLOBAL_FILE); + + wxString versionKey(wxT("")); + wxString key(wxT("")); + long index; + bool bMore = config.GetFirstGroup(key, index); + while (bMore) + { + if (wxIsdigit(key[0]) && versionKey.CompareTo(key) < 0) + versionKey = key; + + bMore = config.GetNextGroup(key, index); + } + + if (!versionKey.IsEmpty()) + { + wxString defaultHardware; + wxString defaultHardwareKey(versionKey + wxString(wxT("/")) + wxString(wxT("Default Hardware"))); + if (config.Read(defaultHardwareKey, & defaultHardware)) + { + return defaultHardware; + } + } + return wxEmptyString; +#else + // For other platforms, simply rely on Cdl to get the default hardware. + return wxEmptyString; +#endif +} + +void ecConfigToolDoc::EnableCallbacks (bool bEnable/*=TRUE*/) +{ + CdlTransactionCallback::set_callback_fn(bEnable?&CdlTransactionHandler:0); + CdlTransactionBody::set_inference_callback_fn(bEnable?&CdlInferenceHandler:0); + CdlTransactionBody::set_inference_override(CdlValueSource_Invalid); +} + +CdlInferenceCallbackResult ecConfigToolDoc::CdlGlobalInferenceHandler(CdlTransaction transaction) +{ + CdlInferenceCallbackResult rc=CdlInferenceCallbackResult_Continue; + + ecConfigToolDoc *pDoc = wxGetApp().GetConfigToolDoc(); + pDoc->m_ConflictsOutcome=NotDone; // prepare for the case that there are no solutions + + const std::list& conflicts=pDoc->GetCdlConfig()->get_all_conflicts(); + ecResolveConflictsDialog dlg(wxGetApp().GetTopWindow(), conflicts, transaction, &pDoc->m_arConflictsOfInterest); + + rc = (wxID_OK == dlg.ShowModal()) ? CdlInferenceCallbackResult_Continue:CdlInferenceCallbackResult_Cancel; + pDoc->m_ConflictsOutcome=(CdlInferenceCallbackResult_Continue==rc)?OK:Cancel; + + return rc; +} + +CdlInferenceCallbackResult ecConfigToolDoc::CdlInferenceHandler (CdlTransaction transaction) +{ + CdlInferenceCallbackResult rc=CdlInferenceCallbackResult_Continue; + + ecConfigToolDoc *pDoc=wxGetApp().GetConfigToolDoc(); + const std::list&conflicts=transaction->get_new_conflicts(); + if ((wxGetApp().GetSettings().m_nRuleChecking & ecSettings::Immediate) && conflicts.size()>0) + { + if (wxGetApp().GetSettings().m_nRuleChecking & ecSettings::SuggestFixes) + { + std::list s_conflicts; + for (std::list::const_iterator conf_i= conflicts.begin (); conf_i != conflicts.end (); conf_i++) { // for each conflict + if((*conf_i)->has_known_solution()){ + s_conflicts.push_back(*conf_i); + } + } + if(s_conflicts.size()>0) + { + wxGetApp().LockValues(); + + ecResolveConflictsDialog dlg(wxGetApp().GetTopWindow(), s_conflicts, transaction); + int ret = dlg.ShowModal() ; + + wxGetApp().UnlockValues(); + + return (wxID_OK == ret ? CdlInferenceCallbackResult_Continue:CdlInferenceCallbackResult_Cancel); + } + } + + wxGetApp().LockValues(); + + wxString strMsg; + if(1==conflicts.size()){ + strMsg=wxT("There is 1 unresolved conflict. Make the change anyway?"); + } else { + strMsg.Printf(_("There are %d unresolved conflict%s. Make the change anyway?"), conflicts.size(), (const wxChar*) (1==conflicts.size()? wxT(""):wxT("s")) ); + } + rc = (wxYES == wxMessageBox(strMsg, wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxYES_NO)) ? CdlInferenceCallbackResult_Continue:CdlInferenceCallbackResult_Cancel; + + wxGetApp().UnlockValues(); + + } + return rc; +} + + +// a CDL transaction handler to refresh the configuration tree +void ecConfigToolDoc::CdlTransactionHandler (const CdlTransactionCallback & data) +{ + static int nNesting=0; + //TRACE(_T("Transaction handler: nesting level=%d\n"),nNesting++); + ecConfigToolDoc *pDoc = wxGetApp().GetConfigToolDoc(); + + std::vector::const_iterator val_i; + std::vector::const_iterator node_i; + std::list::const_iterator conf_i; + ecConfigToolView *pControlView = (ecConfigToolView*) pDoc->GetFirstView(); + + for (val_i = data.value_changes.begin(); val_i != data.value_changes.end(); val_i++) + { + const wxString strName((*val_i)->get_name().c_str()); + //TRACE(_T("%s %s : value change\n"), wxString ((*val_i)->get_class_name().c_str()), strName); + pControlView->Refresh(strName); + if (strName==wxT("CYGHWR_MEMORY_LAYOUT")){ // the memory layout has changed... + // TODO + // pDoc->SwitchMemoryLayout (FALSE); // ...so display a new one + } + } + for (node_i = data.active_changes.begin(); node_i != data.active_changes.end(); node_i++) + { + const wxString strName((*node_i)->get_name().c_str()); + //TRACE(_T("%s %s : this has become active or inactive\n"), CString ((*node_i)->get_class_name().c_str()), + // CString ((*node_i)->get_name().c_str())); + if (! dynamic_cast (*node_i)){ // if not an interface node + pControlView->Refresh(strName); + } + } + for (val_i = data.legal_values_changes.begin(); val_i != data.legal_values_changes.end(); val_i++) + { + const wxString strName((*node_i)->get_class_name().c_str()); + //TRACE(_T("%s %s : the legal_values list has changed, a new widget may be needed.\n"), + // CString ((*val_i)->get_class_name().c_str()), strName); + } + + for (val_i = data.value_source_changes.begin(); val_i != data.value_source_changes.end(); val_i++) + { + const wxString strName((*val_i)->get_name().c_str()); + CdlValueSource source = (*val_i)->get_source(); +/* + TRACE(_T("%s %s : the value source has changed to %s\n"), + CString ((*val_i)->get_class_name().c_str()), strName, + CString ((CdlValueSource_Default == source) ? "default" : + (CdlValueSource_Inferred == source) ? "inferred" : + (CdlValueSource_Wizard == source) ? "wizard" : "user")); +*/ + pControlView->Refresh (strName); + } + + pDoc->UpdateFailingRuleCount(); + nNesting--; +} + +bool ecConfigToolDoc::ShowURL(const wxString& strURL1) +{ + bool rc = TRUE; + + wxString strURL(strURL1); + +/* + if(!QualifyDocURL(strURL)){ + return FALSE; // error message already output + } +*/ + + switch (wxGetApp().GetSettings().m_eUseCustomBrowser) + { + case ecInternal: + rc = ShowInternalHtmlHelp(strURL); + break; + case ecAssociatedExternal: + { + rc = ShowExternalHtmlHelp(strURL); + } + + break; + case ecCustomExternal: + QualifyDocURL(strURL, FALSE); + wxGetApp().Launch(strURL, wxGetApp().GetSettings().m_strBrowser); + break; + default: + wxASSERT(FALSE); + } + return rc; +} + +bool ecConfigToolDoc::ShowExternalHtmlHelp (const wxString& strURL) +{ +#if defined(__WXMSW__) || defined(__WXGTK__) + + wxString url; + + wxString sep(wxFILE_SEP_PATH); + wxString docDir(wxString(m_strRepository) + sep + wxString(wxT("doc"))); + if (wxDirExists(docDir + sep + wxT("html"))) + docDir += sep + wxT("html") ; + + if (strURL.Left(7) == wxT("http://") || strURL.Left(7) == wxT("file://")) + url = strURL; + else + url = docDir + sep + strURL; + + wxFileType *ft = wxTheMimeTypesManager->GetFileTypeFromExtension(wxT("html")); + if ( !ft ) + { + wxLogError(_T("Impossible to determine the file type for extension html")); + return FALSE; + } + + wxString cmd; + bool ok = ft->GetOpenCommand(&cmd, + wxFileType::MessageParameters(url, _T(""))); + delete ft; + + if (!ok) + { + // TODO: some kind of configuration dialog here. + wxMessageBox(_("Could not determine the command for running the browser."), + wxGetApp().GetSettings().GetAppName(), wxOK|wxICON_EXCLAMATION); + return FALSE; + } + + // Remove spurious file:// if added +#ifdef __WXMSW__ + if (strURL.Left(7) == wxT("http://")) + cmd.Replace(wxT("file://"), wxT("")); +#endif + + ok = (wxExecute(cmd, FALSE) != 0); + + return ok; + + // Old code using MS HTML Help +#elif 0 + HWND hwndCaller = ::GetDesktopWindow(); + + wxString helpFile(wxGetApp().GetHelpFile()); + bool rc = FALSE; + const ecFileName strFile(HTMLHelpLinkFileName()); + if (wxFileExists(strFile)) + wxRemoveFile(strFile); + + wxTextFile f(strFile); + if(!ecFileName(helpFile).Exists()) + { + wxString msg; + msg.Printf(_("Cannot display help - %s does not exist"), (const wxChar*) helpFile); + wxMessageBox(msg, wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxOK); + } else if (!f.Create()) + { + wxString msg; + msg.Printf(_("Cannot display help - error creating %s"), (const wxChar*) strFile); + wxMessageBox(msg, wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxOK); + } else + { + wxString str; + str.Printf(_T(""), (const wxChar*) strURL); + f.AddLine(str); + f.Write(); + f.Close(); + if(0==HtmlHelp(hwndCaller, wxGetApp().GetHelpFile(), HH_DISPLAY_TOPIC, 0)) + { + wxString msg; + msg.Printf(_("Cannot display %s"), (const wxChar*) strURL); + wxMessageBox(msg, wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxOK); + } +#if 0 + else + { + // JACS: I don't think we need to do this. Even on the MFC version, the notification + // callback didn't do anything interesting. +#define ID_HHNOTIFICATION 55017 + + // FIXME: Do this the first time only? + HH_WINTYPE WinType; + HWND wnd; + HH_WINTYPE *pWinType=NULL; + wxString s = wxGetApp().GetHelpFile() + wxT(">mainwin"); + wnd = HtmlHelp(hwndCaller, s, HH_GET_WIN_TYPE, (DWORD) &pWinType); + WinType=*pWinType; + WinType.hwndCaller=hwndCaller; + WinType.fsWinProperties|=HHWIN_PROP_TRACKING; + WinType.idNotify = ID_HHNOTIFICATION; + wnd = HtmlHelp(hwndCaller, wxGetApp().GetHelpFile(), HH_SET_WIN_TYPE, (DWORD) &WinType); + rc = TRUE; + } +#endif + //wxRemoveFile(strFile); + } + return rc; + +#else + wxMessageBox(_("Sorry, ShowHtmlHelp not yet implemented"), wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxOK); + return FALSE; +#endif +} + +bool ecConfigToolDoc::ShowInternalHtmlHelp (const wxString& strURL) +{ +#if defined(__WXMSW__) || defined(__WXGTK__) + + wxString url(strURL); + + wxString sep(wxFILE_SEP_PATH); + wxString docDir(wxString(m_strRepository) + sep + wxString(wxT("doc"))); + if (wxDirExists(docDir + sep + wxT("html"))) + docDir += sep + wxT("html") ; + + url = docDir + sep + ecHtmlIndexer::Redirect(docDir, url); + +#if 0 + if (strURL.Left(7) == wxT("http://") || strURL.Left(7) == wxT("file://")) + url = strURL; + else + url = docDir + sep + strURL; +#endif + + //url = url.Mid(docDir.Length() + 1); + + if (wxGetApp().HasHelpController()) + { + return wxGetApp().GetHelpController().Display(url); + } + else + return FALSE; + + // Old code using MS HTML Help +#elif 0 + HWND hwndCaller = ::GetDesktopWindow(); + + wxString helpFile(wxGetApp().GetHelpFile()); + bool rc = FALSE; + const ecFileName strFile(HTMLHelpLinkFileName()); + if (wxFileExists(strFile)) + wxRemoveFile(strFile); + + wxTextFile f(strFile); + if(!ecFileName(helpFile).Exists()) + { + wxString msg; + msg.Printf(_("Cannot display help - %s does not exist"), (const wxChar*) helpFile); + wxMessageBox(msg, wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxOK); + } else if (!f.Create()) + { + wxString msg; + msg.Printf(_("Cannot display help - error creating %s"), (const wxChar*) strFile); + wxMessageBox(msg, wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxOK); + } else + { + wxString str; + str.Printf(_T(""), (const wxChar*) strURL); + f.AddLine(str); + f.Write(); + f.Close(); + if(0==HtmlHelp(hwndCaller, wxGetApp().GetHelpFile(), HH_DISPLAY_TOPIC, 0)) + { + wxString msg; + msg.Printf(_("Cannot display %s"), (const wxChar*) strURL); + wxMessageBox(msg, wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxOK); + } + } + return rc; + +#else + wxMessageBox(_("Sorry, ShowHtmlHelp not yet implemented"), wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxOK); + return FALSE; +#endif +} + +const wxString ecConfigToolDoc::HTMLHelpLinkFileName() +{ + return ecFileName(wxGetApp().GetHelpFile()).Head() + wxT("link2.htm"); +} + +bool ecConfigToolDoc::QualifyDocURL(wxString &strURL, bool prefix) +{ + if(-1==strURL.Find(wxT("://"))) + { +#ifdef __WXMSW__ + strURL.Replace(wxT("/"), wxT("\\")); +#endif + wxString originalURL(strURL); + + if (! ecFileName (strURL).IsFile ()) + { // if not an absolute filepath + strURL = GetDocBase () + ecFileName (originalURL); // prepend the doc directory path + } + if (!wxFileExists(strURL)) + strURL = GetDocBase() + ecFileName(wxT("html")) + ecFileName(originalURL); + + if (prefix) + strURL = wxT("file://") + strURL; + } + + if(0==strURL.Find(wxT("file://"))) + { + ecFileName strFile(strURL.Right(strURL.Length()-7)); + int nIndex=strFile.Find(wxT('#'), TRUE); + + if ( -1 != nIndex ) + { + strFile=strFile.Left(nIndex); + } +#ifdef __WXMSW__ + strFile.Replace(wxT("/"), wxT("\\")); +#endif + + if(!strFile.Exists()) + { + wxString msg; + msg.Printf(_("Cannot locate the file %s"), (const wxChar*) strFile); + wxMessageBox(msg, wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxID_OK); + return FALSE; + } + } + return TRUE; +} + +wxString ecConfigToolDoc::GetPackageName (const wxString & strAlias) +{ + const std::vector & packages = m_CdlPkgData->get_packages (); + std::vector::const_iterator package_i; + for (package_i = packages.begin (); package_i != packages.end (); package_i++) + { + const std::vector & aliases = m_CdlPkgData->get_package_aliases (* package_i); + wxString strPackageAlias = aliases [0].c_str (); + if (aliases.size () && (strAlias == strPackageAlias)) + return package_i->c_str (); + } + return wxEmptyString; +} + +const wxString ecConfigToolDoc::GetCurrentTargetPrefix() +{ + ecConfigItem *pItem = Find(wxT("CYGBLD_GLOBAL_COMMAND_PREFIX")); + if (pItem) + return pItem->StringValue(); + else + return wxT(""); +} + +ecConfigToolDoc::GlobalConflictOutcome ecConfigToolDoc::ResolveGlobalConflicts(wxList *parConflictsOfInterest) +{ + m_ConflictsOutcome=NotDone; + m_arConflictsOfInterest.Clear(); + if(parConflictsOfInterest) + { + wxNode* node = parConflictsOfInterest->First(); + while (node) + { + wxObject* obj = (wxObject*) node->Data(); + m_arConflictsOfInterest.Append(obj); + node = node->Next(); + } + } + CdlInferenceCallback fn=CdlTransactionBody::get_inference_callback_fn(); + CdlTransactionBody::set_inference_callback_fn(CdlGlobalInferenceHandler); + GetCdlInterpreter()->get_toplevel()->resolve_all_conflicts(); + CdlTransactionBody::set_inference_callback_fn(fn); + if(NotDone==m_ConflictsOutcome){ + // No solutions were available, but we'll run the dialog anyway + const std::list& conflicts=GetCdlConfig()->get_all_conflicts(); + ecResolveConflictsDialog dlg(wxGetApp().GetTopWindow(), conflicts, NULL, &m_arConflictsOfInterest); + m_ConflictsOutcome = (wxID_OK == dlg.ShowModal())?OK:Cancel; + } + return m_ConflictsOutcome; +} + +bool ecConfigToolDoc::CheckConflictsBeforeSave() +{ + if (GetCdlInterpreter()->get_toplevel()->get_all_conflicts().size()>0) + { + if(ecSettings::Deferred & wxGetApp().GetSettings().m_nRuleChecking) + { + if ((ecSettings::SuggestFixes & wxGetApp().GetSettings().m_nRuleChecking) && + (Cancel==ResolveGlobalConflicts())) + { + return FALSE; + } + int nConflicts = GetCdlInterpreter()->get_toplevel()->get_all_conflicts().size(); + switch (nConflicts) + { + case 0: + break; + case 1: + { + wxString msg; + msg.Printf(_("There is 1 unresolved conflict. Save anyway?")); + if (wxNO == wxMessageBox(msg, wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxYES_NO)) + { + return FALSE; + } + } + default: + { + wxString msg; + msg.Printf(_("There are %d unresolved conflicts. Save anyway?"), nConflicts); + if (wxNO == wxMessageBox(msg, wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxYES_NO)) + { + return FALSE; + } + } + } + } + } + return TRUE; +} + +void ecConfigToolDoc::UpdateFailingRuleCount() +{ + int nCount=0; + if (GetCdlConfig ()) + { + // if configuration information + + // calculate the number of conflicts + nCount = GetCdlConfig ()->get_all_conflicts ().size (); + // GetCdlConfig ()->get_structural_conflicts ().size () + ignore for now + + // update the conflicts view + if (wxGetApp().GetMainFrame() && wxGetApp().GetMainFrame()->GetConflictsWindow()) + { + wxGetApp().GetMainFrame()->GetConflictsWindow()->FillRules (); + } + } + + if (wxGetApp().GetMainFrame()) + { + wxGetApp().GetMainFrame()->SetFailRulePane(nCount); + } +} + +void ecConfigToolDoc::LogConflicts (const std::list & conflicts) +{ + std::list::const_iterator conf_i; + for (conf_i = conflicts.begin (); conf_i != conflicts.end (); conf_i++) // for each conflict + { + wxString strExplain = (* conf_i)->get_explanation ().c_str (); // get the conflict explanation + wxGetApp().Log (ecUtils::StripExtraWhitespace (strExplain)); // display the message in the output window + } +} + +bool ecConfigToolDoc::SetValue (ecConfigItem &ti, double dValue, CdlTransaction transaction/*=NULL*/) +{ + wxASSERT (ti.GetOptionType () == ecDouble); + + // test if the new double value is in range + const CdlValuable valuable = ti.GetCdlValuable(); + CdlListValue list_value; + CdlEvalContext context (NULL, ti.GetCdlItem (), ti.GetCdlItem ()->get_property (CdlPropertyId_LegalValues)); + valuable->get_legal_values ()->eval (context, list_value); + if (! list_value.is_member (dValue)) + { + if ( dValue == valuable->get_double_value(CdlValueSource_Current) ) + return FALSE; + + wxString msg; + msg.Printf(_("%s is not a legal value for %s.\n\nDo you want to use this value anyway?"), + (const wxChar*) ecUtils::DoubleToStr (dValue), (const wxChar*) ti.GetMacro ()); + + if (wxNO == wxMessageBox(msg, wxGetApp().GetSettings().GetAppName(), wxICON_QUESTION|wxYES_NO)) + return FALSE; + } + + if (! ti.SetValue (dValue,transaction)) + return FALSE; + + Modify(TRUE); + wxGetApp().GetMainFrame()->UpdateFrameTitle(); + + // NB UpdateAllViews isn't in the MFC Configtool for double (though it is for the + // other types of value). In theory this should lead to a display inconsistency in the MFC tool. + ecConfigToolHint hint(& ti, ecValueChanged); + UpdateAllViews (NULL, & hint); + + return TRUE; +} + +bool ecConfigToolDoc::SetValue(ecConfigItem &ti, const wxString &strValue, CdlTransaction transaction/*=NULL*/) +{ + // TODO +#if 0 + // warn the user if a modified memory layout is about to be discarded + if (MemoryMap.map_modified () && (ti.Macro () == _T("CYG_HAL_STARTUP")) && + (IDCANCEL == CUtils::MessageBoxFT (MB_OKCANCEL, _T("Changes to the current memory layout will be lost.")))) + return false; +#endif + + bool rc = FALSE; + + switch(ti.GetOptionType()) + { + case ecOptionTypeNone: + break; + case ecEnumerated: + case ecString: + rc = ti.SetValue(strValue, transaction); + break; + case ecLong: + { + long n; + rc = ecUtils::StrToItemIntegerType(strValue,n) && SetValue(ti,n,transaction); + } + break; + case ecDouble: + { + double dValue; + rc = ecUtils::StrToDouble (strValue, dValue) && SetValue (ti, dValue,transaction); + } + break; + default: + wxASSERT(FALSE); + break; + + } + if(rc){ + Modify(TRUE); + wxGetApp().GetMainFrame()->UpdateFrameTitle(); + + ecConfigToolHint hint(& ti, ecValueChanged); + UpdateAllViews (NULL, & hint); + } + return rc; +} + +bool ecConfigToolDoc::SetValue(ecConfigItem &ti, long nValue, CdlTransaction transaction/*=NULL*/) +{ + switch(ti.GetOptionType()) + { + case ecEnumerated: + case ecLong: + break; + case ecOptionTypeNone: + case ecString: + default: + wxASSERT(FALSE); + break; + } + + bool rc = FALSE; + + // TODO +#if 0 + bool bChangingMemmap = MemoryMap.map_modified () && ((ti.Macro ().Compare (_T ("CYG_HAL_STARTUP")) == 0)); +#endif + + if(nValue==ti.Value()) + { + return TRUE; + } + + // test if the new integer value is in range + if (ecLong == ti.GetOptionType ()) + { + const CdlValuable valuable = ti.GetCdlValuable(); + CdlListValue list_value; + CdlEvalContext context (NULL, ti.GetCdlItem (), ti.GetCdlItem ()->get_property (CdlPropertyId_LegalValues)); + valuable->get_legal_values ()->eval (context, list_value); + if (! list_value.is_member ((cdl_int) nValue)) + { + if (nValue == (long) valuable->get_integer_value (CdlValueSource_Current)) + goto Exit; + + wxString msg; + msg.Printf(_("%s is not a legal value for %s.\n\nDo you want to use this value anyway?"), + (const wxChar*) ecUtils::IntToStr (nValue, wxGetApp().GetSettings().m_bHex), (const wxChar*) ti.GetMacro ()); + if (wxNO == wxMessageBox (msg, wxGetApp().GetSettings().GetAppName(), wxICON_QUESTION|wxYES_NO)) + goto Exit; + }; + } + + // TODO +#if 0 + // warn the user if the current memory layout has been changed and will be lost + // this will happen when the layout has been modified and the target-platform-startup is changed + + if (bChangingMemmap && IDCANCEL==CUtils::MessageBoxFT(MB_OKCANCEL,_T("Changes to the current memory layout will be lost."))){ + goto Exit; + } +#endif + + // Save state + if(!ti.SetValue(nValue,transaction)){ + // CanSetValue above should have caught this + wxString msg; + msg.Printf(_("Cannot set '%s' to %d"), (const wxChar*) ti.GetItemNameOrMacro(), nValue); + wxMessageBox(msg, wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxOK); + goto Exit; + } + + rc = TRUE; +Exit: + if(rc) + { + Modify(TRUE); + wxGetApp().GetMainFrame()->UpdateFrameTitle(); + + UpdateFailingRuleCount (); + + ecConfigToolHint hint(& ti, ecValueChanged); + UpdateAllViews (NULL, & hint); + } + return rc; +} + +bool ecConfigToolDoc::SetEnabled(ecConfigItem &ti, bool bEnabled, CdlTransaction transaction/*=NULL*/) +{ + const bool bStatus = ti.SetEnabled (bEnabled, transaction); + + if (bStatus) + { + Modify(TRUE); + ecConfigToolHint hint(& ti, ecValueChanged); + UpdateAllViews (NULL, & hint); + } + return bStatus; +} + +const ecFileName ecConfigToolDoc::CurrentLinkerScript() +{ + const ecConfigItem * pItem = Find (wxT("CYGBLD_LINKER_SCRIPT")); + return pItem ? ecFileName (m_strPackagesDir, m_strLinkerScriptFolder, pItem->StringValue ()) : ecFileName(wxT("")); +} + + +bool ecConfigToolDoc::GenerateHeaders() +{ + wxString sep(wxFILE_SEP_PATH); + + // Generate headers + try { + ecFileName strPkfConfDir(GetInstallTree()); + strPkfConfDir += ecFileName(wxT("include")); + strPkfConfDir += ecFileName(wxT("pkgconf")); + if ( !strPkfConfDir.CreateDirectory()) + { + wxString msg; + msg.Printf(_("Failed to create %s"), (const wxChar*) strPkfConfDir); + wxMessageBox(msg, wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION); + return FALSE; + } + GetCdlConfig()->generate_config_headers(ecUtils::UnicodeToStdStr(strPkfConfDir.ShortName())); + } + catch (CdlInputOutputException e) { + const wxString strMsg(e.get_message().c_str()); + // TRACE(_T("!!! Exception thrown calling generate_config_headers - %s"),strMsg); + wxString msg; + msg.Printf(_("Failed to generate header files - %s"), (const wxChar*) strMsg); + wxMessageBox(msg, wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION); + return FALSE; + } + return TRUE; +} + +const ecFileName ecConfigToolDoc::MLTDir () +{ + wxString strPathName (GetFilename ()); + wxASSERT (! strPathName.IsEmpty ()); + return strPathName.Left (strPathName.Find (wxT('.'), TRUE)) + wxT("_mlt"); +} + +int ecConfigToolDoc::GetTestExeNames (wxArrayString& arTestExes, wxArrayString& arMissing) +{ + arTestExes.Clear(); + arMissing.Clear(); + typedef std::vector EntriesArray; + const EntriesArray &arEntries=GetBuildInfo().entries; + for(EntriesArray::size_type j=0;jStringValue (); + return str; +} + +bool ecConfigToolDoc::ExportFile() +{ + wxFileDialog dialog(wxGetApp().GetTopWindow(), _("Export eCos Minimal Configuration"), + wxT(""), wxT(""), wxT("eCos Minimal Configuration (*.ecm)|*.ecm"), wxSAVE|wxOVERWRITE_PROMPT|wxHIDE_READONLY); + + if (dialog.ShowModal() == wxID_OK) + { + try { + m_CdlConfig->save (ecUtils::UnicodeToStdStr (dialog.GetPath()), /* minimal = */ true); + } + catch (CdlStringException exception) + { + wxString msg; + wxString err(exception.get_message ().c_str ()); + msg.Printf(_("Error exporting eCos minimal configuration:\n\n%s"), (const wxChar*) err ); + wxMessageBox(msg, wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxOK); + return FALSE; + } + catch (...) + { + wxString msg; + msg.Printf(_("Error exporting eCos minimal configuration")); + wxMessageBox(msg, wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxOK); + return FALSE; + } + } + return TRUE; +} + +bool ecConfigToolDoc::ImportFile() +{ + wxFileDialog dialog(wxGetApp().GetTopWindow(), _("Import eCos Minimal Configuration"), + wxT(""), wxT(""), wxT("eCos Minimal Configuration (*.ecm)|*.ecm"), wxOPEN|wxFILE_MUST_EXIST|wxHIDE_READONLY); + + if (dialog.ShowModal() == wxID_OK) + { + try { + m_CdlConfig->add (ecUtils::UnicodeToStdStr (dialog.GetPath ()), ecConfigToolDoc::CdlParseErrorHandler, ecConfigToolDoc::CdlParseWarningHandler); + } + catch (CdlStringException exception) + { + wxString msg; + wxString err(exception.get_message ().c_str ()); + msg.Printf(_("Error importing eCos minimal configuration:\n\n%s"), (const wxChar*) err ); + wxMessageBox(msg, wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxOK); + return FALSE; + } + catch (...) + { + wxString msg; + msg.Printf(_("Error importing eCos minimal configuration")); + wxMessageBox(msg, wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxOK); + return FALSE; + } + + wxBusyCursor wait; + + AddAllItems (); // regenerate all the config items since the topology may have changed + + if (m_strLinkerScriptFolder.IsEmpty ()) + { + wxMessageBox(_("The eCos linker script macro CYGBLD_LINKER_SCRIPT is not defined."), wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxOK); + } + if (m_strMemoryLayoutFolder.IsEmpty ()) + { + wxMessageBox(_("The eCos memory layout macro CYGHWR_MEMORY_LAYOUT is not defined."), wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxOK); + } + SwitchMemoryLayout (TRUE); // the hardware template may have changed + UpdateBuildInfo (); + wxGetApp().GetTreeCtrl()->SelectItem (wxGetApp().GetTreeCtrl()->GetRootItem()); + Modify(TRUE); + + } + return TRUE; +} + +bool ecConfigToolDoc::SwitchMemoryLayout (bool bNewTargetPlatform) +{ + bool rc = TRUE; + if (bNewTargetPlatform && ! m_strBuildTree.IsEmpty ()) // the user has changed target/platform within a build tree + { + // copy default MLT save files for the selected target/platform from the repository to the build tree if they do not already exist + CopyMLTFiles(); + } + + if (m_strBuildTree.IsEmpty ()) // load the memory layout from the repository + { + wxString sep(wxFILE_SEP_PATH); + wxString filename(m_strPackagesDir); + filename += sep; + filename += m_strMemoryLayoutFolder; + filename += sep; + filename += wxT("include"); + filename += sep; + filename += wxT("pkgconf"); + + rc = NewMemoryLayout (ecFileName (filename)); + } + else // load the memory layout from the build tree + { + rc = NewMemoryLayout (MLTDir ()); + } + + return TRUE; // FIXME +} + +bool ecConfigToolDoc::NewMemoryLayout (const wxString &strPrefix) +{ + // TODO +#if ecUSE_MLT + ecFileName strFileName = CurrentLinkerScript (); + wxString sep(wxFILE_SEP_PATH); + + m_memoryMap.new_memory_layout (); // delete the old memory layout regardless + if (! strFileName.IsEmpty ()) + m_memoryMap.import_linker_defined_sections (strFileName); // read the linker-defined section names from the repository (failure is silent) + + wxString strMemoryLayoutFileName = strPrefix + sep + wxString(wxT("mlt_")) + CurrentMemoryLayout () + wxT(".mlt"); + + m_memoryMap.load_memory_layout (strMemoryLayoutFileName); // load the new memory layout (failure is silent) + m_strSelectedSection = wxT(""); + m_strSelectedRegion = wxT(""); + + wxGetApp().GetMLTWindow()->RefreshMLT(); + + // ecConfigToolHint hint(NULL, ecMemLayoutChanged); + // UpdateAllViews (NULL, & hint); +#endif + + return TRUE; // FIXME +} + +void ecConfigToolDoc::RunTests() +{ + wxString strTarget(GetCdlConfig()->get_hardware ().c_str ()); + wxGetApp().GetSettings().GetRunTestsSettings().m_strTarget = strTarget; + + if (NULL==CeCosTestPlatform::Get(strTarget)) + { + wxString msg; + msg.Printf(_("%s is not a recognized platform - do you wish to add it?"), (const wxChar*) strTarget); + if (wxNO == wxMessageBox(msg, wxGetApp().GetSettings().GetAppName(), wxICON_QUESTION|wxYES_NO)) + return; + + ecPlatformEditorDialog dlg(wxGetApp().GetTopWindow()); + + dlg.m_strPlatform = strTarget; + dlg.m_strPrefix = GetCurrentTargetPrefix(); + dlg.m_strCaption=_("New Platform"); + if(wxID_CANCEL == dlg.ShowModal()) + { + return; + } + CeCosTestPlatform::Add(CeCosTestPlatform(dlg.m_strPlatform,dlg.m_strPrefix,dlg.m_strPrompt,dlg.m_strGDB,dlg.m_bServerSideGdb,dlg.m_strInferior)); + CeCosTestPlatform::Save(); + } + + wxArrayString ar; + wxArrayString arTestsMissing; + int nTests = GetTestExeNames(ar, arTestsMissing); + + const CeCosTestPlatform * etPlatform = CeCosTestPlatform::Get(strTarget); + wxASSERT (NULL != etPlatform); + + if (-1 != wxString (etPlatform->GdbCmds ()).Find (wxT("cyg_test_is_simulator"))) + { // if a simulator target, disable 'reset hardware' message box + wxGetApp().GetSettings().GetRunTestsSettings().m_nReset = RESET_NONE ; + } + + // TODO: I think the remote controls was something that wasn't quite implemented in the MFC tool. + // It's in the properties dialog, but not used. + // sheet.HideRemoteControls(); + if (arTestsMissing.Count() > 0) + { + wxString msg; + msg.Printf(_("Not all tests are built. Do you wish to build them now?")); + if (wxYES == wxMessageBox(msg, wxGetApp().GetSettings().GetAppName(), wxICON_QUESTION|wxYES_NO)) + { + wxGetApp().Build(wxT("tests")); + return; + } + } + wxString shellCommands; + if (wxGetApp().PrepareEnvironment(FALSE, & shellCommands)) + { + ecRunTestsDialog dialog(wxGetApp().GetTopWindow()); + int i; + for ( i = 0 ; i < nTests; i++) + { + dialog.Populate(ar[i], TRUE); + } + for ( i = 0 ; i < arTestsMissing.Count(); i++) + { + dialog.Populate(arTestsMissing[i], FALSE); + } + + dialog.ShowModal(); + } +} + +// Rebuild the .hhc, .hhp, .hhk files and reinitialize the help controller +bool ecConfigToolDoc::RebuildHelpIndex(bool force) +{ + ecHtmlIndexer indexer(FALSE /* useRelativeURLs */ ); + + wxString docDir = GetRepository() ; + + wxString projectFile; + if (!indexer.IndexDocs(docDir, projectFile, force)) + { + wxMessageBox("Sorry, could not index documentation."); + return FALSE; + } + else + { + // Now we need to reset the help controller. + wxGetApp().SetHelpFile(projectFile); + wxGetApp().InitializeHelpController(); + return TRUE; + } +} + diff --git a/host/tools/configtool/standalone/wxwin/configtooldoc.h b/host/tools/configtool/standalone/wxwin/configtooldoc.h new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/configtooldoc.h @@ -0,0 +1,219 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +// configtooldoc.h : +// +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): julians +// Contact(s): julians +// Date: 2000/10/05 +// Version: $Id: configtooldoc.h,v 1.12 2001/04/24 10:07:01 julians Exp $ +// Purpose: +// Description: Header file for ecConfigToolDoc +// Requires: +// Provides: +// See also: +// Known bugs: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== + +#ifndef _ECOS_CONFIGTOOLDOC_H_ +#define _ECOS_CONFIGTOOLDOC_H_ + +#ifdef __GNUG__ +#pragma interface "configtooldoc.h" +#endif + +#include "cdl.hxx" + +#include "configitem.h" + +#if ecUSE_MLT +#include "memmap.h" +#endif + +class ecConfigItem; + +// Tell OnCreate to prompt for a repository instead of just loading it silently +#define ecDOC_PROMPT_FOR_REPOSITORY 8 + +/* + * ecConfigToolDoc + * Holds the saveable configtool information + */ + +class ecConfigToolDoc: public wxDocument +{ + DECLARE_DYNAMIC_CLASS(ecConfigToolDoc) +public: + ecConfigToolDoc(); + ~ecConfigToolDoc(); + +//// Overrides + virtual bool OnCreate(const wxString& path, long flags); + virtual bool OnOpenDocument(const wxString& filename); + virtual bool OnSaveDocument(const wxString& filename); + virtual bool OnNewDocument() { return TRUE; } + virtual bool OnCloseDocument() ; + +//// Error and other handlers + static void CdlLoadErrorHandler(std::string message); + static void CdlLoadWarningHandler(std::string message); + static void CdlParseErrorHandler (std::string message); + static void CdlParseWarningHandler (std::string message); + static void CdlTransactionHandler (const CdlTransactionCallback & data); + static CdlInferenceCallbackResult CdlInferenceHandler (CdlTransaction data); + static CdlInferenceCallbackResult CdlGlobalInferenceHandler(CdlTransaction data); + +//// Accessors + CdlPackagesDatabase GetCdlPkgData () { return m_CdlPkgData; } + CdlConfiguration GetCdlConfig () { return m_CdlConfig; } + CdlInterpreter GetCdlInterpreter() { return m_CdlInterp; } + + // Absolute path name to root of respository - parent of PackagesDir below + void SetRepository(const wxString& pszRepository) { m_strRepository = ecFileName(pszRepository); } + const ecFileName& GetRepository() const { return m_strRepository; } + + wxString GetDefaultHardware () ; + const wxString& GetTemplateVersion() const { return m_templateVersion; } + wxString GetPackageName (const wxString & strAlias); + + // Absolute path name to "packages" directory - i.e. the one under the repository + // named "packages" in a delivery or "ecc" in CVS: + const ecFileName& GetPackagesDir() const { return m_strPackagesDir; } + + const wxString& GetInstallTree() const { return m_strInstallTree; } + const wxString& GetBuildTree() const { return m_strBuildTree; } + void SetInstallTree(const wxString& str) { m_strInstallTree = str; } + void SetBuildTree(const wxString& str) { m_strBuildTree = str; } + + wxList& GetItems() { return m_items; } + ecConfigItem* GetItem(size_t i) { return (ecConfigItem*) m_items[i]; } + + CdlBuildInfo& GetBuildInfo() { return m_BuildInfo; } + + ecConfigItem* GetFirstItem() { return (m_items.Number() == 0 ? (ecConfigItem*) NULL : (ecConfigItem*) m_items.First()->Data()); } + + const wxString GetCurrentTargetPrefix(); + + const wxString HTMLHelpLinkFileName(); + + const ecFileName MLTDir (); + const ecFileName CurrentLinkerScript(); + const wxString CurrentMemoryLayout (); + + const ecFileName GetDocBase() const { return GetRepository() + wxT("doc"); } + +//// Operations + bool OpenRepository(const wxString& pszRepository = wxEmptyString, bool bPromptInitially=FALSE) ; + bool OpenRepository (const ecFileName& strNewRepository, CdlPackagesDatabase &NewCdlPkgData,CdlInterpreter &NewCdlInterp,CdlConfiguration &NewCdlConfig, wxString &strNewPackagesDir); + void CloseRepository() ; + void EnableCallbacks (bool bEnable=TRUE); + void AddContents (const CdlContainer container, ecConfigItem *pParent); + void AddAllItems(); + ecConfigItem* AddItem (const CdlUserVisible vitem, ecConfigItem * pParent); + void DeleteItems(); + + // Use the wxHtmlHelpController + bool ShowInternalHtmlHelp (const wxString& strURL); + + // Use an external browser + bool ShowExternalHtmlHelp (const wxString& strURL); + + bool ShowURL(const wxString& strURL); + // If prefix is TRUE, add file:// to beginning + bool QualifyDocURL(wxString &strURL, bool prefix = TRUE); + void CheckRadios(); + bool GenerateHeaders(); + bool ExportFile(); + bool ImportFile(); + void RunTests(); + + void SelectTemplate (const wxString& newTemplate, const wxString& newTemplateVersion); + void SelectHardware (const wxString& newTemplate); + void SelectPackages (); + void RegenerateData(); + bool UpdateBuildInfo(bool bFirstTime=FALSE); + int GetTestExeNames (wxArrayString& arTestExes, wxArrayString& arMissing) ; + bool SaveMemoryMap(); + bool CopyMLTFiles(); + bool SwitchMemoryLayout (bool bNewTargetPlatform); + bool NewMemoryLayout (const wxString &strPrefix); + + // Find the ecConfigItem referencing the given CdlValuable + ecConfigItem * Find (CdlValuable v); + ecConfigItem * Find(const wxString & strWhat, ecWhereType where = ecInMacro); + + enum GlobalConflictOutcome {OK,Cancel,NotDone}; + // Resolve conflicts + GlobalConflictOutcome ResolveGlobalConflicts(wxList *parConflictsOfInterest=NULL); + bool CheckConflictsBeforeSave(); + void LogConflicts (const std::list & conflicts); + void UpdateFailingRuleCount(); + + bool SetValue(ecConfigItem &ti, long nValue, CdlTransaction transaction = NULL); + bool SetValue(ecConfigItem &ti, const wxString &strValue, CdlTransaction transaction = NULL); + bool SetValue (ecConfigItem &ti, double dValue, CdlTransaction transaction = NULL); + bool SetEnabled(ecConfigItem &ti, bool bEnabled, CdlTransaction transaction = NULL); + + // Rebuild the .hhc, .hhp, .hhk files and reinitialize the help controller + bool RebuildHelpIndex(bool force = TRUE); + +protected: + CdlPackagesDatabase m_CdlPkgData; + CdlInterpreter m_CdlInterp; + CdlConfiguration m_CdlConfig; + wxString m_templateVersion; + ecFileName m_strPackagesDir; + wxString m_strCdlErrorMessage; + wxString m_strMemoryLayoutFolder; + wxString m_strLinkerScriptFolder; + ecFileName m_strBuildTree; + ecFileName m_strInstallTree; + wxList m_items; + CdlBuildInfo m_BuildInfo; + + // This data supports communication of information to the failing rules dialog invoked by CdlGlobalInferenceHandler(): + GlobalConflictOutcome m_ConflictsOutcome; + wxList m_arConflictsOfInterest; // used by CRulesView::OnResolve (TODO change comment) + +public: + ecFileName m_strRepository; + bool m_bRepositoryOpen; + +#if ecUSE_MLT + mem_map m_memoryMap; + wxString m_strSelectedSection; + wxString m_strSelectedRegion; +#endif +}; + + +#endif + // _ECOS_CONFIGTOOLDOC_H_ diff --git a/host/tools/configtool/standalone/wxwin/configtoolview.cpp b/host/tools/configtool/standalone/wxwin/configtoolview.cpp new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/configtoolview.cpp @@ -0,0 +1,498 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +// configtoolview.cpp : +// +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): julians +// Contact(s): julians +// Date: 2000/10/05 +// Version: $Id: configtoolview.cpp,v 1.9 2001/04/30 17:12:32 julians Exp $ +// Purpose: +// Description: Implementation file for the ecConfigToolView class +// Requires: +// Provides: +// See also: +// Known bugs: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== + +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- +#ifdef __GNUG__ + #pragma implementation "configtoolview.h" +#endif + +// Includes other headers for precompiled compilation +#include "ecpch.h" + +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + +#include "configtoolview.h" +#include "configtooldoc.h" +#include "configtree.h" +#include "configtool.h" +#include "shortdescrwin.h" +#include "mainwin.h" +#include "propertywin.h" +#include "ecutils.h" + +IMPLEMENT_DYNAMIC_CLASS(ecConfigToolView, wxView) + +BEGIN_EVENT_TABLE(ecConfigToolView, wxView) +END_EVENT_TABLE() + +ecConfigToolView::ecConfigToolView() +{ + m_expandedForFind = wxTreeItemId(); +} + +// What to do when a view is created. Creates actual +// windows for displaying the view. +bool ecConfigToolView::OnCreate(wxDocument *doc, long WXUNUSED(flags) ) +{ + wxGetApp().GetDocManager()->ActivateView(this, TRUE); + + // Single-window mode +#if 0 + m_frame = GetMainFrame(); + + // Associate the appropriate frame with this view. + SetFrame(m_frame); + + // Make sure the document manager knows that this is the + // current view. + Activate(TRUE); + + // Initialize the edit menu Undo and Redo items + doc->GetCommandProcessor()->SetEditMenu(((pzMainFrame *)m_frame)->editMenu); + doc->GetCommandProcessor()->Initialize(); +#endif + + return TRUE; +} + +void ecConfigToolView::OnDraw(wxDC *dc) +{ +} + +void ecConfigToolView::OnUpdate(wxView *WXUNUSED(sender), wxObject *hintObj) +{ + ecConfigToolDoc* pDoc = (ecConfigToolDoc*) GetDocument(); + ecConfigTreeCtrl* treeCtrl = wxGetApp().GetTreeCtrl(); + + wxASSERT (pDoc); + + ecConfigItem* selItem = NULL; + + wxTreeItemId sel = treeCtrl->GetSelection(); + if (sel.IsOk()) + { + ecTreeItemData* data = (ecTreeItemData*) treeCtrl->GetItemData(sel); + if (data) + selItem = data->GetConfigItem() ; + } + + ecConfigToolHint* hint = (ecConfigToolHint*) hintObj; + int hintOp = ecNoHint; + if (hint) + hintOp = hint->m_op; + + switch (hintOp) + { + case ecSelChanged: + + { + // Note that we're cheating a bit here, since we're using the tree view + // to update another view, instead of having a view per control as in the MFC + // version. However, it doesn't seem to be worth the extra machinery. + // Update the description window + if (selItem) + { + wxGetApp().GetMainFrame()->GetShortDescriptionWindow()->SetValue(selItem->GetDescription()); + + // Update the properties window + wxGetApp().GetMainFrame()->GetPropertyListWindow()->Fill(selItem); + } + else + { + wxGetApp().GetMainFrame()->GetShortDescriptionWindow()->Clear(); + wxGetApp().GetMainFrame()->GetPropertyListWindow()->ClearAll(); + } + + } + break; + case ecAllSaved: + + { + int nItem; + for(nItem=0;nItemGetItems().Number();nItem++) + { + ecConfigItem *pItem = (ecConfigItem*) pDoc->GetItems()[nItem]; + wxTreeItemId treeItem = pItem->GetTreeItem(); + if(treeItem){ + treeCtrl->SetItemText(treeItem, pItem->GetItemNameOrMacro()); + //InvalidateItem(h); + } + } + + // Update the properties window + if (selItem) + { + wxGetApp().GetMainFrame()->GetPropertyListWindow()->Fill(selItem); + } + + wxGetApp().GetMainFrame()->UpdateFrameTitle(); + + // Update the value pane + wxGetApp().GetMainFrame()->GetValueWindow()->Refresh(); + } + break; + case ecFilenameChanged: + + { + // Update the properties window + if (selItem) + { + wxGetApp().GetMainFrame()->GetPropertyListWindow()->Fill(selItem); + } + wxGetApp().GetMainFrame()->UpdateFrameTitle(); + } + break; + case ecNameFormatChanged: + { + int nItem; + for(nItem=0;nItemGetItems().Number();nItem++) + { + ecConfigItem *pItem = (ecConfigItem*) pDoc->GetItems()[nItem]; + wxString strName(pItem->GetItemNameOrMacro()); + if(pItem->Modified()){ + strName+=wxT('*'); + } + treeCtrl->SetItemText(pItem->GetTreeItem(), strName); + } + + treeCtrl->Refresh(); + } + break; + case ecIntFormatChanged: + { + if (selItem && selItem->GetOptionType() == ecLong) + { + wxGetApp().GetMainFrame()->GetPropertyListWindow()->SetItem(ecPropertyListCtrl::ecValue, selItem->StringValue()); + wxGetApp().GetMainFrame()->GetPropertyListWindow()->SetItem(ecPropertyListCtrl::ecDefaultValue, ecUtils::IntToStr(selItem->DefaultValue(), wxGetApp().GetSettings().m_bHex)); + } + + } + break; + case ecClear: + { + m_expandedForFind = wxTreeItemId(); + + treeCtrl->DeleteAllItems(); + + wxGetApp().GetMainFrame()->GetShortDescriptionWindow()->Clear(); + wxGetApp().GetMainFrame()->GetPropertyListWindow()->Fill(NULL); + wxGetApp().GetMainFrame()->GetValueWindow()->Refresh(); + break; + } + + case ecValueChanged: + { + ecConfigItem& ti = *(ecConfigItem *)hint->m_item; + + // Update the tree item + ti.ConvertFromCdl(); + ti.UpdateTreeItem(* treeCtrl); + + // Update the value cell + ecValueWindow* valueWindow = wxGetApp().GetMainFrame()->GetValueWindow(); + if (valueWindow) + { + wxRect rect = valueWindow->GetItemRect(& ti); +#ifdef __WXMSW__ + valueWindow->Refresh(TRUE, & rect); +#else + // For some reason, on Linux, the value window gets + // blanked out if a dialog pops up as a result of the value change. + valueWindow->Refresh(); +#endif + } + + // Properties window + if (selItem) + { + wxGetApp().GetMainFrame()->GetPropertyListWindow()->RefreshValue(); + } + wxGetApp().GetMainFrame()->UpdateFrameTitle(); + } + break; + + case ecExternallyChanged: + { + int nItem; + for(nItem=0;nItemGetItems().Number();nItem++) + { + ecConfigItem *pItem = (ecConfigItem*) pDoc->GetItems()[nItem]; + pItem->UpdateTreeItem(* treeCtrl); + } + wxGetApp().GetMainFrame()->UpdateFrameTitle(); + } + break; + default: + break; // not for us, apparently + } +} + +// Clean up windows used for displaying the view. +bool ecConfigToolView::OnClose(bool deleteWindow) +{ + ecConfigToolHint hint(NULL, ecClear); + GetDocument()->UpdateAllViews (NULL, & hint); + + if (!GetDocument()->Close()) + return FALSE; + + wxGetApp().GetDocManager()->ActivateView(this, FALSE); + + // TODO: Set any pointers to this view to NULL + +#if 0 + wxString s(wxTheApp->GetAppName()); + if (m_frame) + m_frame->SetTitle(s); + + SetFrame((wxFrame *) NULL); +#endif + + Activate(FALSE); + + return TRUE; +} + +void ecConfigToolView::OnChangeFilename() +{ + if (wxGetApp().GetTopWindow() && GetDocument()) + { + wxString docTitle(wxFileNameFromPath(GetDocument()->GetFilename())); + wxStripExtension(docTitle); + GetDocument()->SetTitle(docTitle); + + wxString name(GetDocument()->GetFilename()); + wxStripExtension(name); + + ((ecConfigToolDoc*) GetDocument())->SetInstallTree(name + wxT("_build")); + ((ecConfigToolDoc*) GetDocument())->SetBuildTree(name + wxT("_install")); + + wxString title; + + wxString modifiedMarker; + if (GetDocument()->IsModified()) + modifiedMarker = wxT("*"); + + title = docTitle + modifiedMarker + wxString(wxT(" - ")) + wxGetApp().GetSettings().GetAppName(); + + ((wxFrame*) wxGetApp().GetTopWindow())->SetTitle(title); + } +} + +// General disabler +void ecConfigToolView::OnUpdateDisable(wxUpdateUIEvent& event) +{ + event.Enable( FALSE ); +} + +void ecConfigToolView::Refresh(const wxString& macroName) +{ + ecConfigItem * pItem=wxGetApp().GetConfigToolDoc()->Find(macroName); + + if (pItem) // will be NULL if item has been removed + { + pItem->ConvertFromCdl(); + + if (wxGetApp().GetTreeCtrl()) + pItem->UpdateTreeItem(* wxGetApp().GetTreeCtrl()); + + // Update the cell contents. + if (wxGetApp().GetMainFrame() && wxGetApp().GetMainFrame()->GetValueWindow()) + { + wxRect rect = wxGetApp().GetMainFrame()->GetValueWindow()->GetItemRect(pItem); + wxGetApp().GetMainFrame()->GetValueWindow()->Refresh(TRUE, & rect); + } + } +} + +void ecConfigToolView::Refresh (wxTreeItemId h) +{ + if(h) + { + // TODO Not sure if we need this +#if 0 + AdjustItemImage(h); + // Invalidate the labels of the affected items + CRect rect; + GetItemRect(h, rect, TRUE ); + rect.left+=m_TreeXOffsetAdjustment; + InvalidateRect(rect); + // Do the same for the cell view + CRect rcBuddyClient; + CConfigTool::GetCellView()->GetClientRect(rcBuddyClient); + rect.left=rcBuddyClient.left; + rect.right=rcBuddyClient.right; + CConfigTool::GetCellView()->InvalidateRect(rect); +#endif + } +} + +ecConfigItem *ecConfigToolView::DoFind(const wxString& what, wxWindow* parent) +{ + ecConfigToolDoc *pDoc = wxGetApp().GetConfigToolDoc(); + if (!pDoc) + return NULL; + + int nCount = pDoc->GetItems().Number(); + + // static LPCTSTR arWhereImage[]={_T("name"),_T("macro"),_T("description string"),_T("current value"),_T("default value")}; + + wxString strFind(what); + + if(! wxGetApp().GetSettings().m_findMatchCase) + { + strFind.MakeLower(); + } + + wxTreeItemId h = wxGetApp().GetTreeCtrl()->GetSelection(); + + int nItem; + if(!h){ + nItem=0; + } else { + for (nItem=nCount-1;nItem>=0;--nItem) { + if(h==pDoc->GetItem(nItem)->GetTreeItem()) + { + break; + } + } + wxASSERT(nItem>=0); + } + + ecConfigItem *pItem = NULL; + + int i; + for (i=0 ; i < nCount ; i++) + { + if(wxGetApp().GetSettings().m_findDirection) + { + nItem=(nItem+1)%nCount; + } else { + nItem=(nCount+nItem-1)%nCount; + } + pItem = pDoc->GetItem(nItem); + + ecWhereType where = ecConfigItem::WhereStringToType(wxGetApp().GetSettings().m_findSearchWhat); + + wxString strName (pItem->StringValue(where)); + + if (!wxGetApp().GetSettings().m_findMatchCase) + { + strName.MakeLower(); + } + + int nIndex=strName.Find(strFind); + if(-1!=nIndex) + { + if (wxGetApp().GetSettings().m_findMatchWholeWord) + { + // Enforce whole-word semantics: to left and right + if(nIndex>0 && IsWordChar(strName[nIndex-1])){ + continue; + } + nIndex += strFind.Length(); + if (nIndex < strName.Length() && IsWordChar(strName[nIndex])){ + continue; + } + } + break; + } + } + + if (i < nCount) + { + if(m_expandedForFind) + { + wxGetApp().GetTreeCtrl()->Collapse(m_expandedForFind); + } + + wxTreeItemId h=pItem->GetTreeItem(); + // Is h visible? + wxTreeItemId hv; + for(hv=wxGetApp().GetTreeCtrl()->GetFirstVisibleItem();hv;hv=wxGetApp().GetTreeCtrl()->GetNextVisible(hv)) + { + if(hv==h) + { + break; + } + } + if (0==hv) + { + // we want to record the highest unexpanded item + for(hv=wxGetApp().GetTreeCtrl()->GetParent(h);hv;hv=wxGetApp().GetTreeCtrl()->GetParent(hv)) + { + if (!wxGetApp().GetTreeCtrl()->IsExpanded( hv)) + { + m_expandedForFind = hv; + } + } + } + wxGetApp().GetTreeCtrl()->EnsureVisible(h); + wxGetApp().GetTreeCtrl()->SelectItem(h); + + } else + { + wxString msg; + msg.Printf(_("Cannot find '%s' in %s"), (const wxChar*) what, (const wxChar*) wxGetApp().GetSettings().m_findSearchWhat ); + wxMessageBox(msg, _("Find"), wxOK|wxICON_INFORMATION, parent); + } + + return pItem; +} + +bool ecConfigToolView::IsWordChar(wxChar c) +{ + return wxIsalnum(c) || wxT('_')==c; +} + + diff --git a/host/tools/configtool/standalone/wxwin/configtoolview.h b/host/tools/configtool/standalone/wxwin/configtoolview.h new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/configtoolview.h @@ -0,0 +1,125 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +// configtoolview.h : +// +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): julians +// Contact(s): julians +// Date: 2000/10/05 +// Version: $Id: configtoolview.h,v 1.4 2001/03/22 11:27:28 julians Exp $ +// Purpose: +// Description: Header file for ecConfigToolView +// Requires: +// Provides: +// See also: +// Known bugs: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== + +#ifndef _ECOS_CONFIGTOOLVIEW_H_ +#define _ECOS_CONFIGTOOLVIEW_H_ + +#ifdef __GNUG__ +#pragma interface "configtoolview.h" +#endif + +#include "wx/docview.h" +#include "wx/treectrl.h" + +/* + * ecConfigToolView + */ + +class ecConfigItem; +class ecConfigToolView: public wxView +{ + DECLARE_DYNAMIC_CLASS(ecConfigToolView) +public: + ecConfigToolView(); + ~ecConfigToolView() {}; + +//// Overrides + bool OnCreate(wxDocument *doc, long flags); + void OnDraw(wxDC *dc); + void OnUpdate(wxView *sender, wxObject *hint = (wxObject *) NULL); + bool OnClose(bool deleteWindow = TRUE); + void OnChangeFilename(); + +//// Operations + void Refresh(const wxString& macroName); + void Refresh (wxTreeItemId h); + ecConfigItem *DoFind(const wxString& what, wxWindow* parent) ; + +//// Helpers + bool IsWordChar(wxChar c); + +//// Event handlers + + // General disabler + void OnUpdateDisable(wxUpdateUIEvent& event); + +DECLARE_EVENT_TABLE() + +protected: + wxTreeItemId m_expandedForFind; +}; + +/* + * ecConfigToolHint + * + * Hint to pass to UpdateAllViews + * + */ + +// Update hint symbols +#define ecNoHint 0 +#define ecAllSaved 1 +#define ecNameFormatChanged 2 +#define ecIntFormatChanged 3 +#define ecClear 4 +#define ecValueChanged 5 +#define ecExternallyChanged 6 +#define ecSelChanged 7 +#define ecFilenameChanged 8 +#define ecMemLayoutChanged 9 + +class ecConfigItem; +class ecConfigToolHint: public wxObject +{ +public: + ecConfigToolHint(ecConfigItem* item, int op) { m_item = item; m_op = op; } + + ecConfigItem* m_item; + int m_op; +}; + + +#endif + // _ECOS_CONFIGTOOLVIEW_H_ diff --git a/host/tools/configtool/standalone/wxwin/configtree.cpp b/host/tools/configtool/standalone/wxwin/configtree.cpp new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/configtree.cpp @@ -0,0 +1,1054 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +// configtree.cpp : +// +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): julians +// Contact(s): julians +// Date: 2000/08/24 +// Version: $Id: configtree.cpp,v 1.8 2001/04/24 14:39:13 julians Exp $ +// Purpose: +// Description: Implementation file for ecConfigTreeCtrl +// Requires: +// Provides: +// See also: +// Known bugs: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== + +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- +#ifdef __GNUG__ +#pragma implementation "configtree.h" +#endif + +// Includes other headers for precompiled compilation +#include "ecpch.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#include "wx/cshelp.h" + +// Include XPM icons +#if !defined(__WXMSW__) +#include "bitmaps/closedfolder.xpm" +#include "bitmaps/closedfolder_dis.xpm" +#include "bitmaps/package_closed.xpm" +#include "bitmaps/package_closed_dis.xpm" +#include "bitmaps/package_open.xpm" +#include "bitmaps/package_open_dis.xpm" +#include "bitmaps/checked.xpm" +#include "bitmaps/checked_dis.xpm" +#include "bitmaps/unchecked.xpm" +#include "bitmaps/unchecked_dis.xpm" +#include "bitmaps/integer.xpm" +#include "bitmaps/integer_dis.xpm" +#include "bitmaps/integer2.xpm" +#include "bitmaps/integer2_dis.xpm" +#include "bitmaps/enumerated.xpm" +#include "bitmaps/enumerated_dis.xpm" +#include "bitmaps/radioon.xpm" +#include "bitmaps/radioon_dis.xpm" +#include "bitmaps/radiooff.xpm" +#include "bitmaps/radiooff_dis.xpm" +#include "bitmaps/text.xpm" +#include "bitmaps/text_dis.xpm" +#endif + +#include "configtree.h" +#include "configpropdlg.h" +#include "configtooldoc.h" +#include "configtoolview.h" + +/* + * ecConfigTreeCtrl + */ + +IMPLEMENT_CLASS(ecConfigTreeCtrl, wxRemotelyScrolledTreeCtrl) + +BEGIN_EVENT_TABLE(ecConfigTreeCtrl, wxRemotelyScrolledTreeCtrl) + EVT_PAINT(ecConfigTreeCtrl::OnPaint) + EVT_MOUSE_EVENTS(ecConfigTreeCtrl::OnMouseEvent) + EVT_CHAR(ecConfigTreeCtrl::OnKeyDown) + EVT_TREE_SEL_CHANGED(-1, ecConfigTreeCtrl::OnSelChanged) + EVT_TREE_ITEM_EXPANDED(-1, ecConfigTreeCtrl::OnCollapseExpand) + EVT_TREE_ITEM_COLLAPSED(-1, ecConfigTreeCtrl::OnCollapseExpand) + EVT_HELP(-1, ecConfigTreeCtrl::OnHelp) +END_EVENT_TABLE() + +ecConfigTreeCtrl::ecConfigTreeCtrl(wxWindow* parent, wxWindowID id, const wxPoint& pt, + const wxSize& sz, long style): +wxRemotelyScrolledTreeCtrl(parent, id, pt, sz, style) +{ + LoadIcons(); + + m_propertiesMenu = new wxMenu; + + m_propertiesMenu->Append(ecID_WHATS_THIS, _("&What's This?")); + m_propertiesMenu->AppendSeparator(); + m_propertiesMenu->Append(ecID_TREE_PROPERTIES, _("P&roperties")); + m_propertiesMenu->Append(ecID_TREE_RESTORE_DEFAULTS, _("Restore &Defaults")); + m_propertiesMenu->Append(ecID_TREE_VISIT_DOC, _("Visit Documentation")); + m_propertiesMenu->Append(ecID_TREE_VIEW_HEADER, _("View Header")); + m_propertiesMenu->AppendSeparator(); + m_propertiesMenu->Append(ecID_TREE_UNLOAD_PACKAGE, _("&Unload Package...")); + + if (!wxGetApp().GetSettings().GetWindowSettings().GetUseDefaults() && + wxGetApp().GetSettings().GetWindowSettings().GetFont(wxT("Configuration")).Ok()) + { + SetFont(wxGetApp().GetSettings().GetWindowSettings().GetFont(wxT("Configuration"))); + } +} + +// Load the icons and initialize the tree +void ecConfigTreeCtrl::LoadIcons() +{ + m_imageList = new wxImageList(16, 16, TRUE); + m_iconDB.SetImageList(m_imageList); + SetImageList(m_imageList); + + // We associate names and states so we can easily get the appropriate + // icon for a given tree item. This gets used in ecConfigItem::UpdateTreeIcon. + + m_iconDB.AddInfo("Container", wxICON(closedfolder), 0, TRUE); + m_iconDB.AddInfo("Container", wxICON(closedfolder_dis), 0, FALSE); + + m_iconDB.AddInfo("Package", wxICON(package_open), 0, TRUE); + m_iconDB.AddInfo("Package", wxICON(package_open_dis), 0, FALSE); + + m_iconDB.AddInfo("Checkbox", wxICON(checked), 0, TRUE); + m_iconDB.AddInfo("Checkbox", wxICON(checked_dis), 0, FALSE); + m_iconDB.AddInfo("Checkbox", wxICON(unchecked), 1, TRUE); + m_iconDB.AddInfo("Checkbox", wxICON(unchecked_dis), 1, FALSE); + + m_iconDB.AddInfo("Radiobox", wxICON(radioon), 0, TRUE); + m_iconDB.AddInfo("Radiobox", wxICON(radioon_dis), 0, FALSE); + m_iconDB.AddInfo("Radiobox", wxICON(radiooff), 1, TRUE); + m_iconDB.AddInfo("Radiobox", wxICON(radiooff_dis), 1, FALSE); + + m_iconDB.AddInfo("Text", wxICON(text), 0, TRUE); + m_iconDB.AddInfo("Text", wxICON(text_dis), 0, FALSE); + + m_iconDB.AddInfo("Enumerated", wxICON(enumerated), 0, TRUE); + m_iconDB.AddInfo("Enumerated", wxICON(enumerated_dis), 0, FALSE); + + m_iconDB.AddInfo("Integer", wxICON(integer), 0, TRUE); + m_iconDB.AddInfo("Integer", wxICON(integer_dis), 0, FALSE); + +#if 0 + // Add some dummy items + ecConfigItem* item = NULL; + wxTreeItemId rootId = AddRoot(_(""), -1, -1, new ecTreeItemData(item = new ecConfigItem(NULL, _("Configuration"), ecContainer))); + + item->SetTreeItem(rootId); + item->UpdateTreeItem(* this); + + wxTreeItemId childId1 = AppendItem(rootId, _(""), -1, -1, new ecTreeItemData(item = new ecConfigItem(item, _("My Package"), ecPackage, ecFlavorData, ecString))); + item->SetTreeItem(childId1); + item->GetValue() = _("v1_4_1"); + item->UpdateTreeItem(* this); + + wxTreeItemId childId2 = AppendItem(childId1, _(""), -1, -1, new ecTreeItemData(item = new ecConfigItem(item, _("Option 1"), ecOption, ecFlavorData, ecString))); + item->SetTreeItem(childId2); + item->GetValue() = _("The value for this option"); + item->UpdateTreeItem(* this); + + childId2 = AppendItem(childId1, _(""), -1, -1, new ecTreeItemData(item = new ecConfigItem(item, _("Option 2"), ecOption, ecFlavorData, ecLong))); + item->SetTreeItem(childId2); + item->GetValue() = (long) 176343; + item->UpdateTreeItem(* this); + + childId2 = AppendItem(childId2, _(""), -1, -1, new ecTreeItemData(item = new ecConfigItem(item, _("Option 3"), ecOption, ecFlavorBool, ecOptionTypeNone, TRUE, TRUE, ecHintCheck))); + item->SetTreeItem(childId2); + item->GetValue() = (bool) TRUE; + item->UpdateTreeItem(* this); + + childId2 = AppendItem(childId1, _(""), -1, -1, new ecTreeItemData(item = new ecConfigItem(item, _("Option 4"), ecOption, ecFlavorBool, ecOptionTypeNone, TRUE, FALSE, ecHintCheck))); + item->SetTreeItem(childId2); + item->UpdateTreeItem(* this); + + childId2 = AppendItem(childId1, _(""), -1, -1, new ecTreeItemData(item = new ecConfigItem(item, _("Option 5"), ecOption, ecFlavorBool, ecOptionTypeNone, TRUE, TRUE, ecHintRadio))); + item->SetTreeItem(childId2); + item->UpdateTreeItem(* this); + + childId2 = AppendItem(childId1, _(""), -1, -1, new ecTreeItemData(item = new ecConfigItem(item, _("Option 6"), ecOption, ecFlavorBool, ecOptionTypeNone, TRUE, FALSE, ecHintRadio))); + item->SetTreeItem(childId2); + item->GetValue() = (bool) TRUE ; + item->UpdateTreeItem(* this); + + // Another branch + childId1 = AppendItem(rootId, _(""), -1, -1, new ecTreeItemData(item = new ecConfigItem(item, _("My Container"), ecContainer))); + item->SetTreeItem(childId1); + item->UpdateTreeItem(* this); + + childId2 = AppendItem(childId1, _(""), -1, -1, new ecTreeItemData(item = new ecConfigItem(item, _("Option 1"), ecOption, ecFlavorData, ecString, FALSE))); + item->SetTreeItem(childId2); + item->GetValue() = _("The value for this option"); + item->UpdateTreeItem(* this); + + childId2 = AppendItem(childId1, _(""), -1, -1, new ecTreeItemData(item = new ecConfigItem(item, _("Option 2"), ecOption, ecFlavorData, ecLong, FALSE))); + item->SetTreeItem(childId2); + item->GetValue() = (long) 176343; + item->UpdateTreeItem(* this); + + childId2 = AppendItem(childId1, _(""), -1, -1, new ecTreeItemData(item = new ecConfigItem(item, _("Option 3"), ecOption, ecFlavorBool, ecOptionTypeNone, FALSE, TRUE, ecHintCheck))); + item->SetTreeItem(childId2); + item->GetValue() = (bool) TRUE; + item->UpdateTreeItem(* this); + + childId2 = AppendItem(childId1, _(""), -1, -1, new ecTreeItemData(item = new ecConfigItem(item, _("Option 4"), ecOption, ecFlavorBool, ecOptionTypeNone, FALSE, FALSE, ecHintCheck))); + item->SetTreeItem(childId2); + item->UpdateTreeItem(* this); + + childId2 = AppendItem(childId1, _(""), -1, -1, new ecTreeItemData(item = new ecConfigItem(item, _("Option 5"), ecOption, ecFlavorBool, ecOptionTypeNone, FALSE, TRUE, ecHintRadio))); + item->SetTreeItem(childId2); + item->UpdateTreeItem(* this); + + childId2 = AppendItem(childId1, _(""), -1, -1, new ecTreeItemData(item = new ecConfigItem(item, _("Option 6"), ecOption, ecFlavorBool, ecOptionTypeNone, FALSE, FALSE, ecHintRadio))); + item->SetTreeItem(childId2); + item->GetValue() = (bool) TRUE ; + item->UpdateTreeItem(* this); + + Expand(rootId); +#endif +} + +ecConfigTreeCtrl::~ecConfigTreeCtrl() +{ + delete m_propertiesMenu; + + SetImageList(NULL); + delete m_imageList; +} + +// Draw the lines on top of the tree +void ecConfigTreeCtrl::OnPaint(wxPaintEvent& event) +{ + wxPaintDC dc(this); + + wxTreeCtrl::OnPaint(event); + + // Reset the device origin since it may have been set + dc.SetDeviceOrigin(0, 0); + + wxSize sz = GetClientSize(); + + wxPen pen(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DLIGHT), 1, wxSOLID); + dc.SetPen(pen); + dc.SetBrush(* wxTRANSPARENT_BRUSH); + + wxSize clientSize = GetClientSize(); + wxRect itemRect; + int cy=0; + wxTreeItemId h, lastH; + for(h=GetFirstVisibleItem();h;h=GetNextVisible(h)) + { + if (GetBoundingRect(h, itemRect)) + { + cy = itemRect.GetTop(); + dc.DrawLine(0, cy, clientSize.x, cy); + lastH = h; + } + } + + if (lastH && lastH.IsOk() && GetBoundingRect(lastH, itemRect)) + { + cy = itemRect.GetBottom(); + dc.DrawLine(0, cy, clientSize.x, cy); + } +} + +void ecConfigTreeCtrl::OnSelChanged(wxTreeEvent& event) +{ + ecConfigToolDoc* doc = wxGetApp().GetConfigToolDoc(); + if (doc) + { + ecConfigToolHint hint(NULL, ecSelChanged); + doc->UpdateAllViews(NULL, & hint); + } +} + +void ecConfigTreeCtrl::OnMouseEvent(wxMouseEvent& event) +{ + int flags = 0; + wxTreeItemId item = HitTest(wxPoint(event.GetX(), event.GetY()), flags); + + if (item == 0 || !item.IsOk()) + { + if (event.RightDown()) + PopupMenu(wxGetApp().GetWhatsThisMenu(), event.GetX(), event.GetY()); + return; + } + + if (event.LeftDown()) + { + if (flags & wxTREE_HITTEST_ONITEMICON) + { + ecTreeItemData* data = (ecTreeItemData*) GetItemData(item); + data->GetConfigItem()->OnIconLeftDown(* this); + } + } + else if (event.RightDown()) + { + if ((flags & wxTREE_HITTEST_ONITEMBUTTON) || + (flags & wxTREE_HITTEST_ONITEMICON) || + (flags & wxTREE_HITTEST_ONITEMINDENT) || + (flags & wxTREE_HITTEST_ONITEMLABEL)) + { + SelectItem(item); + GetPropertiesMenu()->SetClientData((void*) TRUE); + PopupMenu(GetPropertiesMenu(), event.GetX(), event.GetY()); + } + else + { + wxGetApp().GetWhatsThisMenu()->SetClientData((void*) FALSE); + PopupMenu(wxGetApp().GetWhatsThisMenu(), event.GetX(), event.GetY()); + } + return; + } + event.Skip(); +} + +void ecConfigTreeCtrl::OnKeyDown(wxKeyEvent& event) +{ + wxTreeItemId id = GetSelection(); + if (event.GetKeyCode() == WXK_F10 && event.ShiftDown()) + { + if (id.IsOk()) + { + wxRect rect; + if (GetBoundingRect(id, rect)) + { + GetPropertiesMenu()->SetClientData((void*) TRUE); + PopupMenu(GetPropertiesMenu(), 100, rect.GetTop() + 4); + } + } + } + else if (event.GetKeyCode() == '<') + { + if (id.IsOk()) + { + ecConfigItem* item = ((ecTreeItemData*) GetItemData(id))->GetConfigItem(); + item->BumpItem(-1); + } + } + else if (event.GetKeyCode() == '>') + { + if (id.IsOk()) + { + ecConfigItem* item = ((ecTreeItemData*) GetItemData(id))->GetConfigItem(); + item->BumpItem(+1); + } + } + else if (event.GetKeyCode() == WXK_SPACE) + { + if (id.IsOk()) + { + ecConfigItem* item = ((ecTreeItemData*) GetItemData(id))->GetConfigItem(); + item->BumpItem(0); + } + } + else if (event.GetKeyCode() == WXK_RETURN && event.AltDown()) + { + if (id.IsOk()) + { + ecConfigItem* item = ((ecTreeItemData*) GetItemData(id))->GetConfigItem(); + + ecConfigPropertiesDialog dialog(wxGetApp().GetTopWindow(), item); + dialog.SetTitle(item->GetName()); + dialog.ShowModal(); + } + } + else + { + event.Skip(); + } +} + +void ecConfigTreeCtrl::OnCollapseExpand(wxTreeEvent& event) +{ + if (GetCompanionWindow()) + GetCompanionWindow()->Refresh(); +} + +// show help for this window +void ecConfigTreeCtrl::OnHelp(wxHelpEvent& event) +{ + wxPoint pt = ScreenToClient(event.GetPosition()); + int flags = 0; + wxTreeItemId id = HitTest(pt, flags); + wxHelpProvider *helpProvider = wxHelpProvider::Get(); + if ( helpProvider && id > 0) + { + ecConfigItem* item = ((ecTreeItemData*) GetItemData(id))->GetConfigItem(); + + if (item) + { + wxGetApp().GetHelpController().DisplayTextPopup(item->GetDescription(), event.GetPosition()); + return; + } + } + + event.Skip(); +} + +/* +* ecValueWindow +*/ + +IMPLEMENT_CLASS(ecValueWindow, wxTreeCompanionWindow) + +BEGIN_EVENT_TABLE(ecValueWindow, wxTreeCompanionWindow) + EVT_PAINT(ecValueWindow::OnPaint) + EVT_MOUSE_EVENTS(ecValueWindow::OnMouseEvent) + EVT_SCROLLWIN(ecValueWindow::OnScroll) + EVT_TREE_ITEM_EXPANDED(-1, ecValueWindow::OnExpand) + EVT_TREE_ITEM_COLLAPSED(-1, ecValueWindow::OnExpand) +END_EVENT_TABLE() + +ecValueWindow::ecValueWindow(wxWindow* parent, wxWindowID id, + const wxPoint& pos, + const wxSize& sz, + long style): +wxTreeCompanionWindow(parent, id, pos, sz, style) +{ + SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_LISTBOX)); + + if (!wxGetApp().GetSettings().GetWindowSettings().GetUseDefaults() && + wxGetApp().GetSettings().GetWindowSettings().GetFont(wxT("Configuration")).Ok()) + { + SetFont(wxGetApp().GetSettings().GetWindowSettings().GetFont(wxT("Configuration"))); + } + else + SetFont(wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT)); + + + m_editWindow = NULL; + m_configItem = NULL; +} + +void ecValueWindow::OnPaint(wxPaintEvent& event) +{ + wxPaintDC dc(this); + + if (!m_treeCtrl) + return; + + wxPen pen(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DLIGHT), 1, wxSOLID); + dc.SetPen(pen); + dc.SetBrush(* wxTRANSPARENT_BRUSH); + wxFont font(GetFont()); + dc.SetFont(font); + //dc.SetTextForeground(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_WINDOWTEXT)); + dc.SetBackgroundMode(wxTRANSPARENT); + + wxSize clientSize = GetClientSize(); + wxRect itemRect; + int cy=0; + wxTreeItemId h, lastH; + for(h=m_treeCtrl->GetFirstVisibleItem();h;h=m_treeCtrl->GetNextVisible(h)) + { + if (m_treeCtrl->GetBoundingRect(h, itemRect)) + { + cy = itemRect.GetTop(); + wxRect drawItemRect(0, cy, clientSize.x, itemRect.GetHeight()); + + lastH = h; + + // Draw the actual item + DrawItem(dc, h, drawItemRect); + dc.DrawLine(0, cy, clientSize.x, cy); + } + } + if (lastH && lastH.IsOk() && m_treeCtrl->GetBoundingRect(lastH, itemRect)) + { + cy = itemRect.GetBottom(); + dc.DrawLine(0, cy, clientSize.x, cy); + } +} + +// Returns the rectangle which will enclose the value for this tree item +wxRect ecValueWindow::GetItemRect(ecConfigItem* item) +{ + if (!m_treeCtrl) + return wxRect(0, 0, 0, 0); + + wxSize clientSize = GetClientSize(); + wxRect itemRect; + int cy=0; + wxTreeItemId h; + for(h=m_treeCtrl->GetFirstVisibleItem();h;h=m_treeCtrl->GetNextVisible(h)) + { + ecTreeItemData* data = (ecTreeItemData*) m_treeCtrl->GetItemData(h); + if (data->GetConfigItem() == item) + { + if (m_treeCtrl->GetBoundingRect(h, itemRect)) + { + cy = itemRect.GetTop(); + wxRect drawItemRect(0, cy, clientSize.x, itemRect.GetHeight()); + return drawItemRect; + } + else + return wxRect(0, 0, 0, 0); + } + } + return wxRect(0, 0, 0, 0); +} + +void ecValueWindow::OnMouseEvent(wxMouseEvent& event) +{ + if (event.LeftDown() && (event.GetX() > 2)) + { + // Find if this corresponds to a tree item + int flags = 0; + wxTreeItemId item = m_treeCtrl->HitTest(wxPoint(4, event.GetY()), flags); + if (item.IsOk()) + { + m_treeCtrl->SelectItem(item); + ecConfigItem* configItem = ((ecTreeItemData*) m_treeCtrl->GetItemData(item))->GetConfigItem(); + if (configItem->CanEdit()) + BeginEditing(configItem); + } + } + else if (event.RightDown()) + { + // Find if this corresponds to a tree item + int flags = 0; + wxTreeItemId item = m_treeCtrl->HitTest(wxPoint(4, event.GetY()), flags); + if (item != 0) + { + ecConfigItem* configItem = ((ecTreeItemData*) m_treeCtrl->GetItemData(item))->GetConfigItem(); + m_treeCtrl->SelectItem(item); + ((ecConfigTreeCtrl*) m_treeCtrl)->GetPropertiesMenu()->SetClientData((void*) TRUE); + PopupMenu(((ecConfigTreeCtrl*) m_treeCtrl)->GetPropertiesMenu(), event.GetX(), event.GetY()); + } + else + { + wxGetApp().GetWhatsThisMenu()->SetClientData((void*) FALSE); + PopupMenu(wxGetApp().GetWhatsThisMenu(), event.GetX(), event.GetY()); + } + } +} + +void ecValueWindow::DrawItem(wxDC& dc, wxTreeItemId id, const wxRect& rect) +{ + if (m_treeCtrl) + { + ecConfigItem* item = ((ecTreeItemData*) m_treeCtrl->GetItemData(id))->GetConfigItem(); + if (!item) + return; + wxString text = item->GetDisplayValue(); + + if (text.IsEmpty()) + return; + + static wxColour normalColour = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_WINDOWTEXT); + static wxColour disabledColour = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_GRAYTEXT); + dc.SetTextForeground( (item->GetActive() && (item->GetConfigType() != ecPackage)) ? normalColour : disabledColour ); + + int textW, textH; + dc.GetTextExtent(text, & textW, & textH); + + int x = 2; + int y = rect.GetY() + wxMax(0, (rect.GetHeight() - textH) / 2); + + dc.DrawText(text, x, y); + } +} + +bool ecValueWindow::BeginEditing(ecConfigItem* item) +{ + if (m_configItem) + EndEditing(); + + m_configItem = item; + + m_editWindow = item->CreateEditWindow(this); + if (m_editWindow) + { + m_editWindow->Show(FALSE); + + item->TransferDataToWindow(m_editWindow); + + // Position the control + PositionEditWindow(); + + m_editWindow->Show(TRUE); + m_editWindow->SetFocus(); + + return TRUE; + } + else + { + m_configItem = NULL; + return FALSE; + } +} + +// Position the control +void ecValueWindow::PositionEditWindow() +{ + if (!m_configItem || !m_editWindow) + return; + + // Position the control + wxSize clientSize = GetClientSize(); + wxRect itemRect; + m_treeCtrl->GetBoundingRect(m_configItem->GetTreeItem(), itemRect); + + wxSize sz = m_editWindow->GetSize(); + + // m_editWindow->SetSize(2, itemRect.y+1, clientSize.x, itemRect.GetHeight() /* -2 */); + m_editWindow->SetSize(0, itemRect.y, clientSize.x, sz.y); +} + +bool ecValueWindow::EndEditing() +{ + if (m_configItem) + { + if (m_editWindow && !wxGetApp().GetValuesLocked()) + m_configItem->TransferDataFromWindow(m_editWindow); + m_configItem = NULL; + } + + if (m_editWindow) + { + delete m_editWindow; + m_editWindow = NULL; + } + + return TRUE; +} + +void ecValueWindow::OnScroll(wxScrollWinEvent& event) +{ + wxTreeCompanionWindow::OnScroll(event); + + PositionEditWindow(); +} + +void ecValueWindow::OnExpand(wxTreeEvent& event) +{ + wxTreeCompanionWindow::OnExpand(event); + + EndEditing(); +} + +/* +* wxIconStateInfo +*/ + +wxIconStateInfo::wxIconStateInfo(const wxString& name) +{ + m_maxStates = 0; + m_name = name; + int i; + for (i = 0; i < wxMAX_ICON_STATES; i++) + m_states[i] = 0; +} + +int wxIconStateInfo::GetIconId(int state, bool enabled) const +{ + wxASSERT ( state < (wxMAX_ICON_STATES * 2) ); + wxASSERT ( state < m_maxStates ); + + return m_states[state * 2 + (enabled ? 0 : 1)]; +} + +void wxIconStateInfo::SetIconId(int state, bool enabled, int iconId) +{ + wxASSERT ( state < (wxMAX_ICON_STATES * 2) ); + if (state+1 > m_maxStates) + m_maxStates = state+1; + + m_states[state * 2 + (enabled ? 0 : 1)] = iconId; +} + +/* +* wxIconStateInfoDb +* Contains a list of wxIconStateInfos +*/ + +wxIconStateInfoDB::wxIconStateInfoDB(wxImageList* imageList) +{ + m_imageList = imageList; + DeleteContents(TRUE); +} + +void wxIconStateInfoDB::AppendInfo(wxIconStateInfo* info) +{ + Append(info); +} + +// Easy way of initialising both the image list and the +// info db. It will generate image ids itself while appending the icon. +bool wxIconStateInfoDB::AddInfo(const wxString& name, const wxIcon& icon, int state, bool enabled) +{ + wxASSERT (m_imageList != NULL); + + wxIconStateInfo* info = FindInfo(name); + if (!info) + { + info = new wxIconStateInfo(name); + Append(info); + } + info->SetIconId(state, enabled, m_imageList->Add(icon)); + return TRUE; +} + +wxIconStateInfo* wxIconStateInfoDB::FindInfo(const wxString& name) const +{ + wxNode* node = First(); + while (node) + { + wxIconStateInfo* info = (wxIconStateInfo*) node->Data(); + if (info->GetName() == name) + return info; + node = node->Next(); + } + return NULL; +} + +int wxIconStateInfoDB::GetIconId(const wxString& name, int state, bool enabled) const +{ + wxIconStateInfo* info = FindInfo(name); + if (!info) + return -1; + return info->GetIconId(state, enabled); +} + +bool wxIconStateInfoDB::SetIconId(const wxString& name, int state, bool enabled, int iconId) +{ + wxIconStateInfo* info = FindInfo(name); + if (!info) + return FALSE; + info->SetIconId(state, enabled, iconId); + return TRUE; +} + +#if 0 +wxIcon wxIconStateInfoDB::GetIcon(const wxString& name, int state, bool enabled) const +{ + wxASSERT( m_imageList != NULL ); + + wxIconStateInfo* info = FindInfo(name); + if (!info) + return wxNullIcon; + int id = info->GetIconId(state, enabled); + if (id < 0) + return wxNullIcon; + else + return m_imageList->GetImage(id); // Doesn't exist +} +#endif + +/* +* ecSplitterScrolledWindow +* This window holds the tree and value windows. +* We derive a new class mainly to intercept popup menu commands from both child windows +* without resorting to placing their handlers in the main frame. +*/ + +BEGIN_EVENT_TABLE(ecSplitterScrolledWindow, wxSplitterScrolledWindow) + EVT_MENU(ecID_WHATS_THIS, ecSplitterScrolledWindow::OnWhatsThis) + EVT_MENU(ecID_TREE_PROPERTIES, ecSplitterScrolledWindow::OnProperties) + EVT_MENU(ecID_TREE_RESTORE_DEFAULTS, ecSplitterScrolledWindow::OnRestoreDefaults) + EVT_MENU(ecID_TREE_VISIT_DOC, ecSplitterScrolledWindow::OnVisitDoc) + EVT_MENU(ecID_TREE_VIEW_HEADER, ecSplitterScrolledWindow::OnViewHeader) + EVT_MENU(ecID_TREE_UNLOAD_PACKAGE, ecSplitterScrolledWindow::OnUnloadPackage) + + EVT_UPDATE_UI(ecID_TREE_RESTORE_DEFAULTS, ecSplitterScrolledWindow::OnUpdateRestoreDefaults) + EVT_UPDATE_UI(ecID_TREE_VISIT_DOC, ecSplitterScrolledWindow::OnUpdateVisitDoc) + EVT_UPDATE_UI(ecID_TREE_VIEW_HEADER, ecSplitterScrolledWindow::OnUpdateViewHeader) + EVT_UPDATE_UI(ecID_TREE_UNLOAD_PACKAGE, ecSplitterScrolledWindow::OnUpdateUnloadPackage) +END_EVENT_TABLE() + +static bool ecIsMenuForItem(wxCommandEvent& event) +{ + wxObject* obj = event.GetEventObject(); + wxMenu* menu = NULL; + + if (obj->IsKindOf(CLASSINFO(wxMenu))) + { + // Menu has some client data which tells us if the menu was clicked over an item + // or not + menu = (wxMenu*) obj; + return (bool) (menu->GetClientData() != 0) ; + } + else + return FALSE; +} + +void ecSplitterScrolledWindow::OnWhatsThis(wxCommandEvent& event) +{ + ecConfigTreeCtrl* treeCtrl = (ecConfigTreeCtrl*) FindWindow(ecID_TREE_CTRL); + wxASSERT (treeCtrl != NULL) ; + + wxTreeItemId id = treeCtrl->GetSelection(); + if (id != 0 && ecIsMenuForItem(event)) + { + ecConfigItem* item = ((ecTreeItemData*) treeCtrl->GetItemData(id))->GetConfigItem(); + + wxPoint pt = wxGetMousePosition(); + wxString msg; + msg.Printf("Popping at %d x %d", pt.x, pt.y); + wxLogDebug(msg); + + wxGetApp().GetHelpController().DisplayTextPopup(item->GetDescription(), wxGetMousePosition()); + } + else + event.Skip(); +} + +void ecSplitterScrolledWindow::OnProperties(wxCommandEvent& event) +{ + wxObject* obj = event.GetEventObject(); + wxMenu* menu = NULL; + + if (obj->IsKindOf(CLASSINFO(wxMenu))) + { + // Menu has some client data which tells us if the menu was clicked over an item + // or not + menu = (wxMenu*) obj; + } + + ecConfigTreeCtrl* treeCtrl = (ecConfigTreeCtrl*) FindWindow(ecID_TREE_CTRL); + wxASSERT (treeCtrl != NULL) ; + + wxTreeItemId id = treeCtrl->GetSelection(); + if (id != 0 && ecIsMenuForItem(event)) + { + ecConfigItem* item = ((ecTreeItemData*) treeCtrl->GetItemData(id))->GetConfigItem(); + + ecConfigPropertiesDialog dialog(wxGetApp().GetTopWindow(), item); + dialog.SetTitle(item->GetName()); + dialog.ShowModal(); + } +} + +void ecSplitterScrolledWindow::OnRestoreDefaults(wxCommandEvent& event) +{ + ecConfigTreeCtrl* treeCtrl = (ecConfigTreeCtrl*) FindWindow(ecID_TREE_CTRL); + wxASSERT (treeCtrl != NULL) ; + + wxTreeItemId id = treeCtrl->GetSelection(); + if (id != 0 && ecIsMenuForItem(event)) + { + ecConfigItem* item = ((ecTreeItemData*) treeCtrl->GetItemData(id))->GetConfigItem(); + if (item->HasModifiedChildren()) + { + int ans = wxMessageBox(_("Restore defaults for nested items?"), wxGetApp().GetSettings().GetAppName(), wxYES_NO|wxCANCEL|wxICON_QUESTION); + switch (ans) + { + case wxYES: + RestoreDefault(id, TRUE); + break; + case wxNO: + RestoreDefault(id, FALSE); + break; + case wxCANCEL: + break; + default: + wxASSERT(FALSE); + break; + } + } + else + { + RestoreDefault(id, FALSE); + } + // current values may have changed so refresh the other views + wxGetApp().GetConfigToolDoc ()->UpdateFailingRuleCount (); + + if (item->GetOptionType () != ecOptionTypeNone) + { + ecConfigToolHint hint(item, ecValueChanged); + wxGetApp().GetConfigToolDoc ()->UpdateAllViews (NULL, & hint); + } + } +} + +void ecSplitterScrolledWindow::RestoreDefault(wxTreeItemId h, bool bRecurse /* = FALSE */, bool bTopLevel /* = TRUE */) +{ + ecConfigTreeCtrl* treeCtrl = (ecConfigTreeCtrl*) FindWindow(ecID_TREE_CTRL); + wxASSERT (treeCtrl != NULL) ; + + ecConfigItem* ti = ((ecTreeItemData*) treeCtrl->GetItemData(h))->GetConfigItem(); + + const CdlValuable valuable = ti->GetCdlValuable(); + + if (valuable && (CdlValueFlavor_None != valuable->get_flavor ())) // skip the root node and nodes without a value + valuable->set_source (CdlValueSource_Default); + treeCtrl->SetItemText (h, ti->GetItemNameOrMacro ()); // remove asterisk in control view + + if (bTopLevel && ti->HasRadio ()) // if user-specified item is a radio button + { + for (ecConfigItem * pItem = ti->FirstRadio (); pItem; pItem = pItem->NextRadio ()) + { + if (ti != pItem) + { + const CdlValuable valuable = pItem->GetCdlValuable(); + wxASSERT (valuable); + valuable->set_source (CdlValueSource_Default); // restore default for each sibling radio button + treeCtrl->SetItemText (pItem->GetTreeItem(), pItem->GetItemNameOrMacro ()); // remove asterisk in control view + } + + } + } + + if (bRecurse) + { + long cookie; + for (h = treeCtrl->GetFirstChild(h, cookie); h; h = treeCtrl->GetNextSibling(h)) + { + RestoreDefault (h, TRUE, FALSE); + } + } +} + +void ecSplitterScrolledWindow::OnVisitDoc(wxCommandEvent& event) +{ + ecConfigTreeCtrl* treeCtrl = (ecConfigTreeCtrl*) FindWindow(ecID_TREE_CTRL); + wxASSERT (treeCtrl != NULL) ; + + wxTreeItemId id = treeCtrl->GetSelection(); + if (id != 0 && ecIsMenuForItem(event)) + { + ecConfigItem* item = ((ecTreeItemData*) treeCtrl->GetItemData(id))->GetConfigItem(); + + item->ViewURL(); + } + else + event.Skip(); +} + +void ecSplitterScrolledWindow::OnViewHeader(wxCommandEvent& event) +{ + ecConfigTreeCtrl* treeCtrl = (ecConfigTreeCtrl*) FindWindow(ecID_TREE_CTRL); + wxASSERT (treeCtrl != NULL) ; + + wxTreeItemId id = treeCtrl->GetSelection(); + if (id != 0 && ecIsMenuForItem(event)) + { + ecConfigItem* item = ((ecTreeItemData*) treeCtrl->GetItemData(id))->GetConfigItem(); + + item->ViewHeader(); + } + else + event.Skip(); +} + +void ecSplitterScrolledWindow::OnUnloadPackage(wxCommandEvent& event) +{ + ecConfigTreeCtrl* treeCtrl = (ecConfigTreeCtrl*) FindWindow(ecID_TREE_CTRL); + wxASSERT (treeCtrl != NULL) ; + + wxTreeItemId id = treeCtrl->GetSelection(); + if (id != 0) + { + ecConfigItem* item = ((ecTreeItemData*) treeCtrl->GetItemData(id))->GetConfigItem(); + + if (wxYES == wxMessageBox(_("Are you sure you wish to unload this package?"), wxGetApp().GetSettings().GetAppName(), + wxYES_NO|wxICON_QUESTION)) + { + item->Unload(); + wxGetApp().GetConfigToolDoc()->RegenerateData(); + } + } +} + +void ecSplitterScrolledWindow::OnUpdateRestoreDefaults(wxUpdateUIEvent& event) +{ + ecConfigTreeCtrl* treeCtrl = (ecConfigTreeCtrl*) FindWindow(ecID_TREE_CTRL); + wxASSERT (treeCtrl != NULL) ; + + wxTreeItemId id = treeCtrl->GetSelection(); + if (id != 0) + { + ecConfigItem* item = ((ecTreeItemData*) treeCtrl->GetItemData(id))->GetConfigItem(); + + event.Enable( IsChanged(id, TRUE ) ); + } +} + +void ecSplitterScrolledWindow::OnUpdateVisitDoc(wxUpdateUIEvent& event) +{ + event.Enable( TRUE ); +} + +void ecSplitterScrolledWindow::OnUpdateViewHeader(wxUpdateUIEvent& event) +{ + ecConfigToolDoc *pDoc=wxGetApp().GetConfigToolDoc(); + event.Enable( pDoc && !pDoc->GetBuildTree().IsEmpty() ) ; +} + +void ecSplitterScrolledWindow::OnUpdateUnloadPackage(wxUpdateUIEvent& event) +{ + ecConfigTreeCtrl* treeCtrl = (ecConfigTreeCtrl*) FindWindow(ecID_TREE_CTRL); + wxASSERT (treeCtrl != NULL) ; + + wxTreeItemId id = treeCtrl->GetSelection(); + if (id != 0) + { + ecConfigItem* item = ((ecTreeItemData*) treeCtrl->GetItemData(id))->GetConfigItem(); + + event.Enable( item->IsPackage() ); + } +} + +bool ecSplitterScrolledWindow::IsChanged(wxTreeItemId id, bool bRecurse) +{ + ecConfigTreeCtrl* treeCtrl = (ecConfigTreeCtrl*) FindWindow(ecID_TREE_CTRL); + wxASSERT (treeCtrl != NULL) ; + + ecConfigItem* item = ((ecTreeItemData*) treeCtrl->GetItemData(id))->GetConfigItem(); + bool rc = item->Modified (); + + if(!rc && bRecurse) + { + long cookie; + for (id=treeCtrl->GetFirstChild(id, cookie);id;id=treeCtrl->GetNextSibling(id)) + { + if (IsChanged(id,TRUE)) + { + rc=TRUE; + break; + } + } + } + return rc; +} diff --git a/host/tools/configtool/standalone/wxwin/configtree.h b/host/tools/configtool/standalone/wxwin/configtree.h new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/configtree.h @@ -0,0 +1,299 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +// configtree.h : +// +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): julians +// Contact(s): julians +// Date: 2000/08/24 +// Version: $Id: configtree.h,v 1.5 2001/04/09 12:51:34 julians Exp $ +// Purpose: +// Description: Header file for ecConfigTreeCtrl +// Requires: +// Provides: +// See also: +// Known bugs: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== + +#ifndef _ECOS_CONFIGTREE_H_ +#define _ECOS_CONFIGTREE_H_ + +#ifdef __GNUG__ +#pragma interface "configtree.h" +#endif + +#include "wx/wx.h" +#include "splittree.h" +#include "configitem.h" + +#define wxMAX_ICON_STATES 4 + +/* + +The idea behind wxIconStateInfo, wxIconStateInfoDB +is to associate multiple state icons with items in tree controls +(and potentially other controls). + +So instead of having to remember a lot of image list ids, +you have a named state info object which contains up to 4 different states +(identified by the integers 0 - 3). Each of these states can +be in a further 2 sub-states - enabled or disabled. + +wxIconStateDB holds a list of these state info objects +and has a convenient API. For example, the following adds +icons for a checkbox item that can be: on/enabled, off/enabled, +on/disabled,off/disabled. + + m_iconDB.AddInfo("Checkbox", wxICON(checked), 0, TRUE); + m_iconDB.AddInfo("Checkbox", wxICON(checked_dis), 0, FALSE); + m_iconDB.AddInfo("Checkbox", wxICON(unchecked), 1, TRUE); + m_iconDB.AddInfo("Checkbox", wxICON(unchecked_dis), 1, FALSE); + +When you update the item image in response to (e.g.) user interaction, +you can say something like this: + + int iconId = m_iconDB.GetIconId("Checkbox", 0, FALSE); + + treeCtrl.SetItemImage(itemId, iconId, wxTreeItemIcon_Normal); + treeCtrl.SetItemImage(itemId, iconId, wxTreeItemIcon_Selected); + +See configitem.cpp for further examples. + +These two classes are prefixed 'wx' because they are generic and may +be used elsewhere. + + */ + +/* + * wxIconStateInfo + * Stores information about the visual state of an item in a tree control + */ + +class wxIconStateInfo: public wxObject +{ +public: + wxIconStateInfo(const wxString& name); + + // How many states? (Each state + // has enabled/disabled state) + // Max (say) 4 states, each with + // enabled/disabled + int GetStateCount() const { return m_maxStates; }; + + void SetStateCount(int count) { m_maxStates; } + int GetIconId(int state, bool enabled = TRUE) const; + void SetIconId(int state, bool enabled, int iconId); + + const wxString& GetName() const { return m_name; } + +protected: + int m_maxStates; + int m_states[wxMAX_ICON_STATES * 2]; // Enabled/disabled + wxString m_name; // Name of icon, e.g. "Package" +}; + +/* + * wxIconStateInfoDb + * Contains a list of wxIconStateInfos + */ + +class wxIconStateInfoDB: public wxList +{ +public: + wxIconStateInfoDB(wxImageList* imageList = NULL); + + void AppendInfo(wxIconStateInfo* info); + + // Easy way of initialising both the image list and the + // info db. It will generate image ids itself while appending the icon. + // 'state' is an integer from 0 up to the max allowed, representing a different + // state. There may be only one, or (for a checkbox) there may be two. + // A folder that can be open or closed would have two states. + // Enabled/disabled is taken as a special case. + bool AddInfo(const wxString& name, const wxIcon& icon, int state, bool enabled); + + wxIconStateInfo* FindInfo(const wxString& name) const; + + int GetIconId(const wxString& name, int state, bool enabled = TRUE) const; + bool SetIconId(const wxString& name, int state, bool enabled, int iconId) ; + + void SetImageList(wxImageList* imageList) { m_imageList = imageList; } + wxImageList* GetImageList() const { return m_imageList; } + +protected: + wxImageList* m_imageList; +}; + +/* + * ecTreeItemData + * This holds an association between the tree control item + * and the ecConfigItem. + */ + +class ecConfigItem; +class ecTreeItemData : public wxTreeItemData +{ +public: + ecTreeItemData(ecConfigItem* item) : m_configItem(item) { } + ~ecTreeItemData() { if (m_configItem) delete m_configItem; } + + ecConfigItem *GetConfigItem() const { return m_configItem; } + void SetConfigItem(ecConfigItem *item) { m_configItem = item; } + +private: + ecConfigItem* m_configItem; +}; + + +/* + * ecConfigTreeCtrl + * This control represents the configuration hierarchy. + * It's derived from wxRemotelyScrolledTreeCtrl because we want + * to synchronize the tree scrolling with the value window scrolling, + * and have the scrollbar on the right-hand-side of the value window + * (not the tree control). + */ + +class ecValueWindow; +class ecConfigTreeCtrl: public wxRemotelyScrolledTreeCtrl +{ + DECLARE_CLASS(ecConfigTreeCtrl) +public: + ecConfigTreeCtrl(wxWindow* parent, wxWindowID id, const wxPoint& pt = wxDefaultPosition, + const wxSize& sz = wxDefaultSize, long style = wxTR_HAS_BUTTONS); + ~ecConfigTreeCtrl(); + +//// Event handlers + void OnPaint(wxPaintEvent& event); + void OnMouseEvent(wxMouseEvent& event); + void OnSelChanged(wxTreeEvent& event); + void OnCollapseExpand(wxTreeEvent& event); + void OnHelp(wxHelpEvent& event); + void OnKeyDown(wxKeyEvent& event); + +//// Accessors + wxIconStateInfoDB& GetIconDB() { return m_iconDB; } + wxMenu* GetPropertiesMenu() const { return m_propertiesMenu; } + +//// Operations + void LoadIcons(); + +protected: + wxImageList* m_imageList; + wxIconStateInfoDB m_iconDB; + wxMenu* m_propertiesMenu; + + DECLARE_EVENT_TABLE() +}; + +/* + * ecValueWindow + * This window represents the values associated with the configuration tree. + * It scrolls synchronously with the tree control. + */ + +class ecValueWindow: public wxTreeCompanionWindow +{ +public: + ecValueWindow(wxWindow* parent, wxWindowID id = -1, + const wxPoint& pos = wxDefaultPosition, + const wxSize& sz = wxDefaultSize, + long style = 0); + + //// Overrides + virtual void DrawItem(wxDC& dc, wxTreeItemId id, const wxRect& rect); + + //// Events + void OnPaint(wxPaintEvent& event); + void OnMouseEvent(wxMouseEvent& event); + void OnScroll(wxScrollWinEvent& event); + void OnExpand(wxTreeEvent& event); + + //// Accessors + wxWindow* GetEditWindow() const { return m_editWindow; } + + //// Operations + + bool BeginEditing(ecConfigItem* item); + bool EndEditing(); + void PositionEditWindow(); + wxRect GetItemRect(ecConfigItem* item); + + ecConfigItem* GetCurrentConfigItem() const { return m_configItem; } + + //// Data members +protected: + wxWindow* m_editWindow; // Edit control + ecConfigItem* m_configItem; // Item being edited + + DECLARE_EVENT_TABLE() + DECLARE_CLASS(ecValueWindow) +}; + +/* + * ecSplitterScrolledWindow + * This window holds the tree and value windows. + * We derive a new class mainly to intercept popup menu commands from both child windows + * without resorting to placing their handlers in the main frame. + */ + +class ecSplitterScrolledWindow: public wxSplitterScrolledWindow +{ +public: + ecSplitterScrolledWindow(wxWindow* parent, wxWindowID id, const wxPoint& pt = wxDefaultPosition, + const wxSize& sz = wxDefaultSize, long style = wxVSCROLL): + wxSplitterScrolledWindow(parent, id, pt, sz, style) + { + } + +//// Event handlers + void OnWhatsThis(wxCommandEvent& event); + void OnProperties(wxCommandEvent& event); + void OnRestoreDefaults(wxCommandEvent& event); + void OnVisitDoc(wxCommandEvent& event); + void OnViewHeader(wxCommandEvent& event); + void OnUnloadPackage(wxCommandEvent& event); + + void OnUpdateRestoreDefaults(wxUpdateUIEvent& event); + void OnUpdateVisitDoc(wxUpdateUIEvent& event); + void OnUpdateViewHeader(wxUpdateUIEvent& event); + void OnUpdateUnloadPackage(wxUpdateUIEvent& event); + +//// Helpers + void RestoreDefault(wxTreeItemId h, bool bRecurse = FALSE, bool bTopLevel = TRUE); + bool IsChanged(wxTreeItemId h, bool bRecurse); +protected: + DECLARE_EVENT_TABLE() +}; + + +#endif +// _ECOS_CONFIGTREE_H_ diff --git a/host/tools/configtool/standalone/wxwin/conflictsdlg.cpp b/host/tools/configtool/standalone/wxwin/conflictsdlg.cpp new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/conflictsdlg.cpp @@ -0,0 +1,561 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +// conflictsdlg.cpp : +// +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): julians +// Contact(s): julians +// Date: 2000/09/06 +// Version: $Id: conflictsdlg.cpp,v 1.3 2001/04/03 14:28:56 julians Exp $ +// Purpose: +// Description: Implementation file for the ecResolveConflictsDialog +// Requires: +// Provides: +// See also: +// Known bugs: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== + +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- +#ifdef __GNUG__ +#pragma implementation "conflictsdlg.h" +#endif + +// Includes other headers for precompiled compilation +#include "ecpch.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#include "configtool.h" +#include "conflictsdlg.h" +#include "conflictwin.h" +#include "solutionswin.h" +#include "configtooldoc.h" +#include "configtoolview.h" +#include "configtree.h" + +#include "wx/cshelp.h" + +BEGIN_EVENT_TABLE(ecResolveConflictsDialog, ecDialog) + EVT_BUTTON(ecID_CONFLICTS_ALL, ecResolveConflictsDialog::OnAll) + EVT_BUTTON(ecID_CONFLICTS_NONE, ecResolveConflictsDialog::OnNone) + EVT_BUTTON(ecID_CONFLICTS_CONTINUE, ecResolveConflictsDialog::OnContinue) + EVT_UPDATE_UI(ecID_CONFLICTS_ALL, ecResolveConflictsDialog::OnUpdateAll) + EVT_UPDATE_UI(ecID_CONFLICTS_NONE, ecResolveConflictsDialog::OnUpdateNone) + EVT_LIST_ITEM_SELECTED(ecID_CONFLICTS_CONFLICTS, ecResolveConflictsDialog::OnConflictSelected) + EVT_LIST_ITEM_DESELECTED(ecID_CONFLICTS_CONFLICTS, ecResolveConflictsDialog::OnConflictDeselected) + EVT_INIT_DIALOG(ecResolveConflictsDialog::OnInitDialog) +END_EVENT_TABLE() + +// ---------------------------------------------------------------------------- +// main frame +// ---------------------------------------------------------------------------- + +// Frame constructor +ecResolveConflictsDialog::ecResolveConflictsDialog(wxWindow* parent, std::list conflicts, CdlTransaction transaction, wxList *parConflictsOfInterest): + m_conflicts(conflicts), + m_Transaction(transaction), + m_parConflictsOfInterest(parConflictsOfInterest), + m_Map(wxKEY_INTEGER) + +{ + // Stop values from being changed by other mechanisms during the + // duration of this dialog. + wxGetApp().LockValues(); + + m_conflictsCtrl = NULL; + m_solutionsCtrl = NULL; + + SetExtraStyle(wxDIALOG_EX_CONTEXTHELP); + + ecDialog::Create(parent, ecID_RESOLVE_CONFLICTS_DIALOG, _("Resolve conflicts"), + wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER); + + std::list::const_iterator conf_i; + for (conf_i= m_conflicts.begin (); conf_i != m_conflicts.end (); conf_i++) + { // for each conflict + int nSolutions = (*conf_i)->get_solution().size(); + SolutionInfo *pInfo = (SolutionInfo *) malloc(sizeof(SolutionInfo)+(nSolutions-1)*sizeof(int)); + pInfo->nCount = nSolutions; + int i; + for ( i = 0; i < nSolutions; i++) + { + pInfo->arItem[i] = SolutionInfo::CHECKED; + } + m_Map.Put((long) *conf_i, (wxObject*) pInfo); + } + + CreateControls(this); + + Centre(wxBOTH); +} + +ecResolveConflictsDialog::~ecResolveConflictsDialog() +{ + m_Map.BeginFind(); + wxNode* node = NULL; + while ((node = m_Map.Next())) + { + SolutionInfo *pInfo = (SolutionInfo*) node->Data(); + free(pInfo); + } + m_Map.Clear(); + + // OK to change values again + wxGetApp().UnlockValues(); +} + +void ecResolveConflictsDialog::CreateControls(wxWindow* parent) +{ + // Create custom windows first + m_conflictsCtrl = new ecConflictListCtrl(parent, ecID_CONFLICTS_CONFLICTS, wxDefaultPosition, wxSize(470, 110), wxLC_REPORT|wxCLIP_CHILDREN|wxSUNKEN_BORDER); + m_solutionsCtrl = new ecSolutionListCtrl(parent, ecID_CONFLICTS_SOLUTIONS, wxDefaultPosition, wxSize(470, 110), wxLC_REPORT|wxCLIP_CHILDREN|wxSUNKEN_BORDER); + + wxSizer *item0 = new wxBoxSizer( wxVERTICAL ); + + wxSizer *item1 = new wxBoxSizer( wxHORIZONTAL ); + + wxButton *item2 = new wxButton( parent, ecID_CONFLICTS_CONTINUE, _("&Continue"), wxDefaultPosition, wxDefaultSize, 0 ); + item2->SetDefault(); + item1->Add( item2, 0, wxALIGN_CENTRE|wxALL, 5 ); + + wxButton *item3 = new wxButton( parent, wxID_CANCEL, _("Cancel"), wxDefaultPosition, wxDefaultSize, 0 ); + item1->Add( item3, 0, wxALIGN_CENTRE|wxALL, 5 ); + + item0->Add( item1, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + wxWindow *item4 = parent->FindWindow( ecID_CONFLICTS_CONFLICTS ); + wxASSERT( item4 ); + item0->Add( item4, 1, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + wxSizer *item5 = new wxBoxSizer( wxHORIZONTAL ); + + wxStaticText *item6 = new wxStaticText( parent, ecID_CONFLICTS_MSG, _("Proposed Solutions:"), wxDefaultPosition, wxSize(250,-1), 0 ); + item5->Add( item6, 0, wxALIGN_BOTTOM|wxALIGN_CENTER_HORIZONTAL|wxALL, 0 ); + + item5->Add( 30, 20, 1, wxALIGN_CENTRE|wxALL, 0 ); + + wxButton *item7 = new wxButton( parent, ecID_CONFLICTS_NONE, _("&None"), wxDefaultPosition, wxDefaultSize, 0 ); + item5->Add( item7, 0, wxALIGN_CENTRE|wxALL, 5 ); + + wxButton *item8 = new wxButton( parent, ecID_CONFLICTS_ALL, _("&All"), wxDefaultPosition, wxDefaultSize, 0 ); + item5->Add( item8, 0, wxALIGN_CENTRE|wxALL, 5 ); + + item0->Add( item5, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + wxWindow *item9 = parent->FindWindow( ecID_CONFLICTS_SOLUTIONS ); + wxASSERT( item9 ); + item0->Add( item9, 1, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + +#ifdef __WXGTK__ + wxButton *contextButton = new wxContextHelpButton( parent ); + item1->Add( contextButton, 0, wxALIGN_CENTRE|wxALL, 5 ); +#endif + + parent->SetAutoLayout( TRUE ); + parent->SetSizer( item0 ); + + // N.B. I find I have to call Layout, then Fit, to make this + // work. + parent->Layout(); + item0->Fit( parent ); + item0->SetSizeHints( parent ); + + // Add context-sensitive help text + parent->FindWindow( ecID_CONFLICTS_CONFLICTS )->SetHelpText(_("Displays the set of conflicts for which the fixes are offered.")); + parent->FindWindow( ecID_CONFLICTS_SOLUTIONS )->SetHelpText(_("Displays fixes for the currently selected conflict. Use the checkboxes to enable or disable each fix.")); + parent->FindWindow( ecID_CONFLICTS_CONTINUE )->SetHelpText(_("Continues the current transaction, applying the selected solutions.")); + parent->FindWindow( wxID_CANCEL )->SetHelpText(_("Cancels the current transaction, without applying any solutions.")); + parent->FindWindow( ecID_CONFLICTS_NONE )->SetHelpText(_("Resets all fix checkboxes to the unchecked state.")); + parent->FindWindow( ecID_CONFLICTS_ALL )->SetHelpText(_("Resets all fix checkboxes to the checked state.")); + +#if __WXGTK__ + parent->FindWindow( wxID_CONTEXT_HELP )->SetHelpText(_("Invokes context-sensitive help for the clicked-on window.")); +#endif +} + +void ecResolveConflictsDialog::OnInitDialog(wxInitDialogEvent& event) +{ + wxDialog::OnInitDialog(event); + + // Select the first item and fill the solution set + m_conflictsCtrl->AddConflicts(m_conflicts); + + if (m_parConflictsOfInterest && m_parConflictsOfInterest->Number()>0) + { + wxList &arConflictsOfInterest = *m_parConflictsOfInterest; + int i, j; + for ( i = m_conflictsCtrl->GetItemCount() - 1; i >= 0; --i ) + { + for ( j = arConflictsOfInterest.Number() - 1; j>=0; --j ) + { + CdlConflict conflict = (CdlConflict)m_conflictsCtrl->GetItemData(i); + if ( ((CdlConflict) arConflictsOfInterest[j]) == conflict ) + { + m_conflictsCtrl->SetItemState(i, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED); + m_conflictsCtrl->EnsureVisible(i); + arConflictsOfInterest.DeleteObject(arConflictsOfInterest[j]); + break; + } + } + } + } else + { + for ( int i = m_conflictsCtrl->GetItemCount()-1; i>=0; --i ) + { + m_conflictsCtrl->SetItemState(i, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED); + } + } + m_conflictsCtrl->SetFocus(); +} + +void ecResolveConflictsDialog::OnContinue(wxCommandEvent& event) +{ + // Ensure we have the current conflict check array + int i; + for (i = 0; i < m_conflictsCtrl->GetItemCount(); i++) + { + if (m_conflictsCtrl->GetItemState(i, wxLIST_STATE_SELECTED) & wxLIST_STATE_SELECTED) + RemoveConflictSolutions((CdlConflict) m_conflictsCtrl->GetItemData(i)); + } + + // Dismiss the window + EndModal(wxID_OK); + + std::list::const_iterator conf_i; + + for (conf_i= m_conflicts.begin (); conf_i != m_conflicts.end (); conf_i++) // for each conflict + { + CdlConflict conflict=*conf_i; + //int nSolutions=conflict->get_solution().size(); + SolutionInfo &info=Info(conflict); + int nIndex=0; + const std::vector >&Solution=conflict->get_solution(); + for (std::vector >::const_iterator soln_i = Solution.begin();soln_i != Solution.end(); soln_i++) { + if(SolutionInfo::CHECKED==info.arItem[nIndex++]){ + CdlValuable valuable = soln_i->first; + CdlValue value=soln_i->second; + CdlValueFlavor flavor = valuable->get_flavor(); + const wxString strName(valuable->get_name().c_str()); + const wxString strValue(value.get_value().c_str()); + bool rc = TRUE; + wxString str; + try + { + switch(flavor) + { + case CdlValueFlavor_None : + str = wxT("set CdlValueFlavor_None"); + rc = FALSE; + break; + case CdlValueFlavor_Bool : + str.Printf(_("%s %s\n"), (const wxChar*) (value.is_enabled()?_("disable"):_("enable")), (const wxChar*) strName); + valuable->set_enabled (m_Transaction, value.is_enabled(), CdlValueSource_User); + break; + case CdlValueFlavor_BoolData : + { + bool bEnabled=value.is_enabled(); + str.Printf(_("%s %s and set value to %s\n"), (const wxChar*) (bEnabled? _("disable"):_("enable")), (const wxChar*) strName, (const wxChar*) strValue); + CdlSimpleValue simple_value = valuable->get_simple_value (); + valuable->set_enabled_and_value (m_Transaction, bEnabled, simple_value, CdlValueSource_User); + } + break; + case CdlValueFlavor_Data : + str.Printf(_("set %s to %s\n"), (const wxChar*) strName, (const wxChar*) strValue); + valuable->set_value (m_Transaction, ecUtils::UnicodeToStdStr (strValue), CdlValueSource_User); + break; + } + } + catch(...) + { + rc = FALSE; + } + if(rc) + { + wxGetApp().GetConfigToolDoc()->Modify(TRUE); + } else + { + wxString msg; + msg.Printf(_("Failed to %s\n"), (const wxChar*) str); + wxMessageBox(msg, wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxOK); + } + } + } + } +} + +void ecResolveConflictsDialog::OnAll(wxCommandEvent& event) +{ + SetAll(TRUE); +} + +void ecResolveConflictsDialog::OnNone(wxCommandEvent& event) +{ + SetAll(FALSE); +} + +void ecResolveConflictsDialog::SetAll(bool bOnOff) +{ + long i; + for ( i = m_solutionsCtrl->GetItemCount()-1; i >= 0; --i) + { + m_solutionsCtrl->SetChecked(i, bOnOff); + } +} + +// Update All button +void ecResolveConflictsDialog::OnUpdateAll(wxUpdateUIEvent& event) +{ + if (!m_solutionsCtrl) + return; + + int nCheckCount=0; + int nItemCount = m_solutionsCtrl->GetItemCount(); + int i; + for (i=nItemCount-1;i>=0;--i) + { + nCheckCount+=m_solutionsCtrl->IsChecked(i); + } + event.Enable(nItemCount>0 && nCheckCountGetItemCount(); + int i; + for (i=nItemCount-1;i>=0;--i){ + nCheckCount+=m_solutionsCtrl->IsChecked(i); + } + event.Enable(nItemCount>0 && nCheckCount>0); +} + +// Currently there is no 'locate' button so this is not called from anywhere. +// However, the intention in the MFC configtool must have been to use it, +// although it wasn't in the Resolve Conflicts dialog. +void ecResolveConflictsDialog::OnLocate() +{ + ecConfigItem *pItem = m_conflictsCtrl->AssociatedItem(m_nContextItem, m_nContextRow); + if (pItem) { + if (wxGetApp().GetTreeCtrl()) + wxGetApp().GetTreeCtrl()->SelectItem(pItem->GetTreeItem()); + } +} + +void ecResolveConflictsDialog::RemoveConflictSolutions(CdlConflict conflict) +{ + SolutionInfo &info=Info(conflict); + int i, j, k; + for ( i = 0; i < info.nCount; i++ ) + { + int nItem=info.arItem[i]; + wxASSERT(nItem>=0); + info.arItem[i] = (m_solutionsCtrl->IsChecked(nItem) ? SolutionInfo::CHECKED:SolutionInfo::UNCHECKED); + int nRefs = m_solutionsCtrl->GetItemData(nItem); + if (1 == nRefs) + { + m_solutionsCtrl->DeleteItem(nItem); + for ( k = 0; k < m_conflictsCtrl->GetItemCount(); k++ ) + { + SolutionInfo &info2 = Info((CdlConflict)m_conflictsCtrl->GetItemData(k)); + for ( j = 0; j < info2.nCount; j++) + { + if (info2.arItem[j] > nItem) + { + info2.arItem[j] --; + } + } + } + } else + { + m_solutionsCtrl->SetItemData(nItem, nRefs-1); + } + } +} + +void ecResolveConflictsDialog::AddConflictSolutions(CdlConflict conflict) +{ + // SolutionInfo allows each conflict to know which solutions have been found for it + SolutionInfo &info=Info(conflict); + + const std::vector >&Solution=conflict->get_solution(); + + int i=0; + for (std::vector >::const_iterator soln_i = Solution.begin(); + soln_i != Solution.end(); soln_i++) + { + CdlValuable valuable = soln_i->first; + CdlValue value = soln_i->second; + CdlValueFlavor flavor = valuable->get_flavor(); + + wxString strValue; + switch(flavor) + { + case CdlValueFlavor_None : + break; + case CdlValueFlavor_Bool : + strValue = value.is_enabled() ? _("Enabled") : _("Disabled"); + break; + case CdlValueFlavor_BoolData : + strValue.Printf(wxT("%s, %s"), (const wxChar*) (value.is_enabled() ? _("Enabled") : _("Disabled")), (const wxChar*) value.get_value().c_str()); + break; + case CdlValueFlavor_Data : + strValue = value.get_value().c_str(); + break; + } + + const wxString strName(soln_i->first->get_name().c_str()); + + long nIndex = m_solutionsCtrl->FindItem(0, strName); + wxListItem listItem; + listItem.m_mask = wxLIST_MASK_TEXT; + listItem.m_itemId = nIndex; + listItem.m_col = 1; + if (nIndex != -1) + m_solutionsCtrl->GetItem(listItem); + + if (-1 == nIndex || strValue != listItem.m_text) + { + // We don't have an existing solution that matches this one + nIndex = m_solutionsCtrl->GetItemCount(); + m_solutionsCtrl->InsertItem(nIndex, strName); + m_solutionsCtrl->SetItemData(nIndex, 1); + m_solutionsCtrl->SetItem(nIndex, 1, strValue); + + wxASSERT(info.arItem[i]<0); + + m_solutionsCtrl->SetChecked(nIndex, SolutionInfo::CHECKED==info.arItem[i]); + } else { + // We do - to avoid duplicates, increment the "ref count" + m_solutionsCtrl->SetItemData(nIndex, m_solutionsCtrl->GetItemData(nIndex)+1); + } + info.arItem[i++]=nIndex; + + } + wxStaticText* staticCtrl = (wxStaticText*) FindWindow(ecID_CONFLICTS_MSG); + + if(0==i){ + staticCtrl->SetLabel(_("No solution is available for this conflict")); + m_solutionsCtrl->Show(FALSE); + } else { + staticCtrl->SetLabel(_("Proposed solution:")); + m_solutionsCtrl->Show(TRUE); + // TODO (if necessary) +#if 0 + m_List.SetColumnWidth(0,LVSCW_AUTOSIZE); + CRect rect; + m_List.GetClientRect(rect); + m_List.SetColumnWidth(1,rect.Width()-m_List.GetColumnWidth(0)); +#endif + } +} + +ecResolveConflictsDialog::SolutionInfo & ecResolveConflictsDialog::Info(const CdlConflict conflict) +{ + SolutionInfo *pInfo = (SolutionInfo*) m_Map.Get((long) conflict); + return * pInfo; +} + +void ecResolveConflictsDialog::OnConflictSelected(wxListEvent& event) +{ + CdlConflict conflict=(CdlConflict) m_conflictsCtrl->GetItemData(event.GetIndex()); + + if (1 == m_solutionsCtrl->GetSelectedItemCount()) + { + // TODO ?? + // GetDlgItem(IDC_STATIC1)->ShowWindow(SW_HIDE); + m_solutionsCtrl->Show(TRUE); + } + AddConflictSolutions(conflict); +} + +void ecResolveConflictsDialog::OnConflictDeselected(wxListEvent& event) +{ + CdlConflict conflict=(CdlConflict) m_conflictsCtrl->GetItemData(event.GetIndex()); + + RemoveConflictSolutions(conflict); +} + + +#if 0 +// TODO? + +// We need to use this because the OnItemChanged handler successive receives "not selected" followed by "selected" +// notifications. The result is that the "Select one or more conflicts to display available solutions" message +// would be seen briefly when clicking from one selection to another. +BOOL ecResolveConflictsDialog::OnClick(UINT,LPNMLISTVIEW pnmv, LRESULT* pResult) +{ + if(-1==pnmv->iItem && 0==m_List.GetSelectedCount()){ + SetDlgItemText(IDC_STATIC1,_T("Select one or more conflicts to display available solutions")); + m_List.ShowWindow(SW_HIDE); + GetDlgItem(IDC_STATIC1)->ShowWindow(SW_SHOW); + GetDlgItem(IDC_RESET)->EnableWindow(false); + GetDlgItem(IDC_CONFLICTS_NONE)->EnableWindow(false); + } + *pResult = 0; + return false; // not handled +} + +// TODO +BOOL ecResolveConflictsDialog::OnRClick(UINT, LPNMITEMACTIVATE pnmv, LRESULT* pResult) +{ + DWORD dwPos=GetMessagePos(); + CPoint pt(GET_X_LPARAM(dwPos),GET_Y_LPARAM(dwPos)); + m_nContextItem=pnmv->iItem; + m_nContextRow=pnmv->iSubItem; + if(-1!=m_nContextItem){ + //m_RulesList.SetItemState(m_nContextItem,LVIS_SELECTED,LVIS_SELECTED); + Menu menu; + menu.CreatePopupMenu(); + menu.AppendMenu(1==m_RulesList.GetSelectedCount() && m_RulesList.AssociatedItem(m_nContextItem,m_nContextRow)?MF_STRING:(MF_STRING|MF_GRAYED),ID_LOCATE,_T("&Locate")); +#ifndef PLUGIN + SuppressNextContextMenuMessage(); +#endif + menu.TrackPopupMenu(TPM_LEFTALIGN|TPM_LEFTBUTTON|TPM_RIGHTBUTTON, pt.x,pt.y,this); + } + + *pResult = 0; + return TRUE; // handled +} + +#endif + diff --git a/host/tools/configtool/standalone/wxwin/conflictsdlg.h b/host/tools/configtool/standalone/wxwin/conflictsdlg.h new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/conflictsdlg.h @@ -0,0 +1,127 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +// conflictsdlg.h : +// +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): julians +// Contact(s): julians +// Date: 2000/09/06 +// Version: $Id: conflictsdlg.h,v 1.2 2001/03/23 13:38:04 julians Exp $ +// Purpose: +// Description: Header file for ecResolveConflictsDialog +// Requires: +// Provides: +// See also: +// Known bugs: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== + +#ifndef _ECOS_CONFLICTSDLG_H_ +#define _ECOS_CONFLICTSDLG_H_ + +#ifdef __GNUG__ +#pragma interface "conflictsdlg.h" +#endif + +#include "wx/wx.h" +#include "wx/listctrl.h" + +#include "ecutils.h" + +// Forward declarations +class ecConflictListCtrl; +class ecSolutionListCtrl; + +class ecResolveConflictsDialog : public ecDialog +{ +public: +// Ctor(s) + ecResolveConflictsDialog(wxWindow* parent, std::list conflicts, CdlTransaction=NULL, wxList *parConflictsOfInterest=NULL); + ~ecResolveConflictsDialog(); + +//// Event handlers + + void OnContinue(wxCommandEvent& event); + void OnAll(wxCommandEvent& event); + void OnNone(wxCommandEvent& event); + void OnInitDialog(wxInitDialogEvent& event); + void OnUpdateAll(wxUpdateUIEvent& event); + void OnUpdateNone(wxUpdateUIEvent& event); + void OnConflictSelected(wxListEvent& event) ; + void OnConflictDeselected(wxListEvent& event) ; + +//// Operations + void CreateControls(wxWindow* parent); + +protected: + struct SolutionInfo { + int nCount; + enum {CHECKED=-1,UNCHECKED=-2}; + int arItem[1]; // real size==nCount. + // Each element of nItem==item index (if selected) or accept bool (if not) + }; + + void SetButtons(); + void AddConflictSolutions (CdlConflict conflict); + void RemoveConflictSolutions (CdlConflict conflict); + void OnLocate(); + SolutionInfo & Info (const CdlConflict conflict); + void SetAll (bool bOnOff); + +//// Member variables +protected: + //UINT m_idTimer; + wxHashTable m_Map; // maps conflicts to bool array representing fixes + wxArrayString m_arValues; + const std::list m_conflicts; + CdlTransactionBody* m_Transaction; + wxList* m_parConflictsOfInterest; + int m_nContextItem; + int m_nContextRow; + + + ecConflictListCtrl* m_conflictsCtrl; + ecSolutionListCtrl* m_solutionsCtrl; + +private: + DECLARE_EVENT_TABLE() +}; + +#define ecID_RESOLVE_CONFLICTS_DIALOG 2031 +#define ecID_CONFLICTS_CONTINUE 3000 +#define ecID_CONFLICTS_CONFLICTS 3005 +#define ecID_CONFLICTS_NONE 3001 +#define ecID_CONFLICTS_ALL 3002 +#define ecID_CONFLICTS_SOLUTIONS 3004 +#define ecID_CONFLICTS_MSG 3005 + + +#endif + // _ECOS_CONFLICTSDLG_H_ diff --git a/host/tools/configtool/standalone/wxwin/conflictwin.cpp b/host/tools/configtool/standalone/wxwin/conflictwin.cpp new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/conflictwin.cpp @@ -0,0 +1,349 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +// configtree.cpp : +// +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): julians +// Contact(s): julians +// Date: 2000/09/04 +// Version: $Id: conflictwin.cpp,v 1.3 2001/04/24 14:39:13 julians Exp $ +// Purpose: +// Description: Implementation file for ecConflictListCtrl +// Requires: +// Provides: +// See also: +// Known bugs: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== + +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- +#ifdef __GNUG__ + #pragma implementation "conflictwin.h" +#endif + +// Includes other headers for precompiled compilation +#include "ecpch.h" + +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + +#include "conflictwin.h" +#include "configtool.h" +#include "configtooldoc.h" +#include "configtree.h" + +/* + * ecConflictListCtrl + */ + +IMPLEMENT_CLASS(ecConflictListCtrl, wxListCtrl) + +BEGIN_EVENT_TABLE(ecConflictListCtrl, wxListCtrl) + EVT_RIGHT_DOWN(ecConflictListCtrl::OnRightClick) + EVT_LEFT_DCLICK(ecConflictListCtrl::OnLeftDClick) + + EVT_MENU(ecID_LOCATE_ITEM, ecConflictListCtrl::OnLocate) + EVT_MENU(ecID_RESOLVE_ITEM, ecConflictListCtrl::OnResolve) +END_EVENT_TABLE() + +ecConflictListCtrl::ecConflictListCtrl(wxWindow* parent, wxWindowID id, const wxPoint& pt, + const wxSize& sz, long style): + wxListCtrl(parent, id, pt, sz, style) +{ + if (!wxGetApp().GetSettings().GetWindowSettings().GetUseDefaults() && + wxGetApp().GetSettings().GetWindowSettings().GetFont(wxT("Conflicts")).Ok()) + { + SetFont(wxGetApp().GetSettings().GetWindowSettings().GetFont(wxT("Conflicts"))); + } + + InsertColumn(0, "Item", wxLIST_FORMAT_LEFT, 200); + InsertColumn(1, "Conflict", wxLIST_FORMAT_LEFT, 80); + InsertColumn(2, "Property", wxLIST_FORMAT_LEFT, 200); + + m_contextMenu = new wxMenu; + m_contextMenu->Append(ecID_WHATS_THIS, _("&What's This?")); + m_contextMenu->AppendSeparator(); + m_contextMenu->Append(ecID_LOCATE_ITEM, _("&Locate")); + m_contextMenu->Append(ecID_RESOLVE_ITEM, _("&Resolve")); + + m_contextItem = -1; + m_contextCol = 0; +} + +ecConflictListCtrl::~ecConflictListCtrl() +{ + delete m_contextMenu; +} + +void ecConflictListCtrl::OnRightClick(wxMouseEvent& event) +{ + int flags = 0; + long item = HitTest(wxPoint(event.GetX(), event.GetY()), flags); + + if (item >= 0 && !GetParent ()->IsKindOf (CLASSINFO(wxDialog))) // this menu for conflicts view only + { + m_contextItem = item; + + // Find which column we're on + m_contextCol = wxListCtrlFindColumn(*this, 3, event.GetX()); + + // GetContextMenu()->SetClientData((void*) TRUE); + PopupMenu(GetContextMenu(), event.GetX(), event.GetY()); + } + else + { + m_contextItem = -1; + + PopupMenu(wxGetApp().GetWhatsThisMenu(), event.GetX(), event.GetY()); + } +} + +void ecConflictListCtrl::OnLeftDClick(wxMouseEvent& event) +{ + if (!GetParent ()->IsKindOf (CLASSINFO(wxDialog))) // handle double click for conflicts view only + { + long sel = wxListCtrlGetSelection(* this); + if (sel >= 0) + { + // Find which column we're on + int col = wxListCtrlFindColumn(*this, 3, event.GetX()); + + ecConfigItem * pItem = AssociatedItem (sel, col); // get the referenced item + + if (pItem) { // if a referenced item was found + wxGetApp().GetTreeCtrl()->SelectItem (pItem->GetTreeItem()); // select the refreenced item + } + } + } +} + +void ecConflictListCtrl::OnLocate(wxCommandEvent& event) +{ + if (m_contextItem > -1) + { + ecConfigItem * pItem = AssociatedItem (m_contextItem, m_contextCol); // get the referenced item + + if (pItem) { // if a referenced item was found + wxGetApp().GetTreeCtrl()->SelectItem (pItem->GetTreeItem()); // select the refreenced item + } + } +} + +void ecConflictListCtrl::OnResolve(wxCommandEvent& event) +{ + ecConfigToolDoc *pDoc = wxGetApp().GetConfigToolDoc(); + + wxList conflictsOfInterest; + + long n = GetItemCount(); + long i; + for (i = 0; i < n; i++) + { + if (GetItemState(i, wxLIST_STATE_SELECTED) & wxLIST_STATE_SELECTED) + { + conflictsOfInterest.Append((wxObject*) (void*) GetItemData(i)); + } + } + + pDoc->ResolveGlobalConflicts(& conflictsOfInterest); +} + + +void ecConflictListCtrl::AddConflict (const CdlConflict &conf) +{ + // set the item column string + wxString strMacroName = (conf)->get_node ()->get_name ().c_str (); + int nIndex = InsertItem (GetItemCount (), strMacroName); + + nIndex = GetItemCount() - 1; + + SetItemData (nIndex, (long) (conf)); + + // set the conflict column string + if (0 != dynamic_cast (conf)) {// a conflict of type 'unresolved' + SetItem (nIndex, 1, wxT("Unresolved")); + } else if (0 != dynamic_cast (conf)) { // a conflict of type 'illegal value' + SetItem (nIndex, 1, wxT("Illegal")); + } else if (0 != dynamic_cast (conf)) { // a conflict of type 'evaluation exception' + SetItem (nIndex, 1, wxT("Exception")); + } else if (0 != dynamic_cast (conf)) { // a conflict of type 'goal unsatisfied' + SetItem (nIndex, 1, wxT("Unsatisfied")); + } else if (0 != dynamic_cast (conf)) { // a conflict of type 'bad data' + SetItem (nIndex, 1, wxT("Bad data")); + } else { + wxASSERT (0); + } + + // set the property column string + wxString strProperty = conf->get_property ()->get_property_name ().c_str (); + strProperty += wxT(" "); + const std::vector & argv = conf->get_property ()->get_argv (); + std::vector::const_iterator argv_i; + for (argv_i = argv.begin (); argv_i != argv.end (); argv_i++) {// for each property argument... + if (argv_i != argv.begin ()) // ...except the first + { + strProperty += argv_i->c_str (); // add the argument to the string + strProperty += wxT (" "); // separate arguments by a space character + } + } + strProperty.Trim (TRUE); // remove the trailing space character + SetItem (nIndex, 2, strProperty); +} + +void ecConflictListCtrl::AddConflicts (const std::list& conflicts) +{ + for (std::list::const_iterator conf_i=conflicts.begin (); conf_i != conflicts.end (); conf_i++) { + AddConflict(*conf_i); + } +} + +ecConfigItem *ecConflictListCtrl::AssociatedItem(int nRow,int nCol) +{ + const CdlConflict conflict = (CdlConflict) GetItemData (nRow); + wxASSERT (conflict != NULL); + + ecConfigItem *pItem=NULL; + switch(nCol) + { + case 2: + { + const CdlGoalExpression goal = dynamic_cast (conflict->get_property ()); + if (! goal) // if the item is not a goal expression + break; // do nothing + const CdlExpression expression = goal->get_expression (); + if (1 == expression->references.size ()) // if the property contains a single reference + { + // assume that the reference is to another user visible node and try to find it + const wxString strName(expression->references [0].get_destination_name ().c_str()); + pItem = wxGetApp().GetConfigToolDoc ()->Find(strName); + } + } + break; + case 0: + pItem = wxGetApp().GetConfigToolDoc ()->Find(wxString(conflict->get_node ()->get_name ().c_str())); + break; + default: + break; + } + return pItem; +} + +// This is taken from CRulesView::FillRules in the MFC version +void ecConflictListCtrl::FillRules() +{ + CdlConfiguration CdlConfig = wxGetApp().GetConfigToolDoc()->GetCdlConfig (); + if (CdlConfig) + { // if configuration information + int nCount=0; + bool bRefill=false; + wxHashTable arMap(wxKEY_INTEGER); + int i; + for ( i = 0 ; i < GetItemCount(); i++) + { + arMap.Put(GetItemData(i), (wxObject*) i); + } + + std::list::const_iterator conf_i; + + const std::list& conflicts=CdlConfig->get_all_conflicts(); + for (conf_i = conflicts.begin (); conf_i != conflicts.end (); conf_i++) { // for each conflict + nCount++; + if (!arMap.Get((long) * conf_i)) + { + bRefill=true; + break; + } + } + //for (conf_i = CdlConfig->get_structural_conflicts().begin (); conf_i != CdlConfig->get_structural_conflicts().end (); conf_i++) { // for each conflict + // nCount++; + // if(!arMap.Lookup(*conf_i,w)){ + // bRefill=true; + // break; + // } + //} + if(bRefill || nCount != GetItemCount()) + { + DeleteAllItems(); + //m_List.AddConflicts(CdlConfig->get_structural_conflicts()); + AddConflicts(CdlConfig->get_all_conflicts()); + } + } +} + +#if 0 +int CRulesList::CompareFunc(LPARAM lParam1, LPARAM lParam2) +{ + LV_FINDINFO find1 = { LVFI_PARAM, NULL, lParam1, NULL, NULL }; + LV_FINDINFO find2 = { LVFI_PARAM, NULL, lParam2, NULL, NULL }; + const int nIndex1 = FindItem (&find1); + const int nIndex2 = FindItem (&find2); + const CString str1 = GetItemText (nIndex1, m_nLastCol & 0x7fffffff); + const CString str2 = GetItemText (nIndex2, m_nLastCol & 0x7fffffff); + return (m_nLastCol & 0x80000000) ^ str1.Compare (str2); +} + +void CRulesList::OnColumnclick(NMHDR* pNMHDR, LRESULT* pResult) +{ + NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR; + LPARAM nCol=pNMListView->iSubItem; + if((nCol&0x7fffffff)==(0x7fffffff&m_nLastCol)){ + nCol=m_nLastCol^0x80000000; + } + m_nLastCol=nCol; + SortItems(CompareFunc,(DWORD)this); + + *pResult = 0; +} + +void CRulesList::OnDblclk(NMHDR* pNMHDR, LRESULT* pResult) +{ + if (GetParent ()->IsKindOf (RUNTIME_CLASS (CRulesView))) { // handle double click for conflicts view only + NM_LISTVIEW * pNMListView = (NM_LISTVIEW *) pNMHDR; + int nItem = pNMListView->iItem; + if (-1 != nItem) { // if the double click was on a row of the list + CConfigItem * pItem = AssociatedItem (nItem, pNMListView->iSubItem); // get the referenced item + if (pItem) { // if a referenced item was found + CConfigTool::GetControlView ()->SelectItem (pItem); // select the refreenced item + } + } + } + + *pResult = 0; + UNUSED_ALWAYS(pNMHDR); +} + +#endif diff --git a/host/tools/configtool/standalone/wxwin/conflictwin.h b/host/tools/configtool/standalone/wxwin/conflictwin.h new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/conflictwin.h @@ -0,0 +1,98 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +// propertywin.h : +// +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): julians +// Contact(s): julians +// Date: 2000/09/04 +// Version: $Id: conflictwin.h,v 1.2 2001/04/06 15:29:40 julians Exp $ +// Purpose: +// Description: Header file for ecConflictListCtrl +// Requires: +// Provides: +// See also: +// Known bugs: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== + +#ifndef _ECOS_CONFLICTWIN_H_ +#define _ECOS_CONFLICTWIN_H_ + +#ifdef __GNUG__ +#pragma interface "conflictwin.h" +#endif + +#include "wx/listctrl.h" + +class ecConfigItem; + +/* + * ecConflictListCtrl + * + * Displays conflicts. Equivalent to original configtool's CRulesList class. + */ + +class ecConflictListCtrl : public wxListCtrl +{ +public: +// Ctor(s) + ecConflictListCtrl(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style); + ~ecConflictListCtrl(); + bool IsSelected (int nIndex); + +//// Event handlers + void OnRightClick(wxMouseEvent& event); + void OnLocate(wxCommandEvent& event); + void OnResolve(wxCommandEvent& event); + void OnLeftDClick(wxMouseEvent& event); + +//// Operations + void AddConflict (const CdlConflict& conflict); + void AddConflicts (const std::list& conflicts); + void AddConflicts (const std::vector& conflicts); + ecConfigItem *AssociatedItem (int nRow,int nCol); + void FillRules(); + + wxMenu* GetContextMenu() const { return m_contextMenu; } + +protected: +private: + wxMenu* m_contextMenu; + long m_contextItem; // Item right-clicked over + long m_contextCol; // Column clicked over + + DECLARE_EVENT_TABLE() + DECLARE_CLASS(ecConflictListCtrl) +}; + + +#endif + // _ECOS_CONFLICTWIN_H_ diff --git a/host/tools/configtool/standalone/wxwin/dialogs/configtool.wdr b/host/tools/configtool/standalone/wxwin/dialogs/configtool.wdr new file mode 100644 index 0000000000000000000000000000000000000000..829afce7d766b040a6983b975e3262fa9f80577c GIT binary patch literal 71599 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 + + + + Documentation Roadmap + + +

+ +We need to output something like this: + +
    +
  • +
    • +
    • +
      • +
      • +
      • +
      • +
        • +
        • +
        • +
        • +
        +
      +
    +
+ +*/ + +bool ecHtmlIndexer::CreateHHCByExaminingClass(const wxString& title, const wxString& topURL, const wxString& htmlFile, const wxString& docDir, wxOutputStream& stream, int startIndent) +{ + if (!wxFileExists(htmlFile)) + return FALSE; + + wxString sep(wxFILE_SEP_PATH); + wxString pathPrefix(wxPathOnly(htmlFile)); + if (!wxIsAbsolutePath(htmlFile)) + { + pathPrefix = pathPrefix.Mid(docDir.Length() + 1); + } + + wxString topURL1(topURL); + if (!UseRelativeURLs() && !wxIsAbsolutePath(topURL1)) + topURL1 = docDir + sep + topURL1; + + wxSimpleHtmlParser parser; + if (parser.ParseFile(htmlFile)) + { + stream << "
  • "); + + if (!topURL.IsEmpty()) + { + stream << ""; + } + stream << "\n"; + int indent = startIndent; + wxSimpleHtmlTag* tag = parser.GetTopLevelTag()->GetChildren(); + + while (tag) + { + if (tag->GetType() == wxSimpleHtmlTag_Open) + { + wxSimpleHtmlAttribute* attr = NULL; + if ((tag->NameIs("P") || tag->NameIs("DIV") || + tag->NameIs("H1") || tag->NameIs("H2") || tag->NameIs("H3") || tag->NameIs("H4")) + && + (attr = tag->FindAttribute("CLASS"))) + { + int level = -1; + if (attr->HasValue("Level1IX") || + attr->HasValue("SectionTitleTOC") || + attr->HasValue("IndexTitleTOC")) + level = 1; + + else if (attr->HasValue("Level2IX") || + attr->HasValue("ChapterTitleTOC") || + attr->HasValue("IntroTitleTOC")) + level = 2; + + else if (attr->HasValue("Heading1TOC")) + level = 3; + + else if (attr->HasValue("Heading2TOC")) + level = 4; + + if (level > -1) + { + wxSimpleHtmlTag* aTag = tag->FindTag("A", "HREF"); + if (aTag) + CreateHHCOutputItem(aTag, level, indent, pathPrefix, docDir, stream); + } + } + } + tag = tag->GetNext(); + } + + // Close any remaining levels + int i; + while (indent > startIndent) + { + indent --; + for (i = 0; i < indent*2; i++) stream << " "; + stream << "\n"; + } + + return TRUE; + } + else + return FALSE; +} + +// Append HHC-compatible code to a stream according to the tags found in the +// given HTML file. Use level of
    to determine contents heading level. + +/* + +Find the name and URL from a chunk of HTML like +the following. + +
    +
    + Table of Contents +
    +
    + 1. Overview +
    +
    +
    +
    + Terminology +
    +
    +
    +
    + Component Framework +
    + + ... + +
      +
    • +
      • +
      • +
        • +
        • +
        • +
        • +
          • +
          • +
          • +
          • +
          +
        +
      +
    + +*/ + +bool ecHtmlIndexer::CreateHHCByExaminingList(const wxString& title, const wxString& topURL, const wxString& htmlFile, const wxString& docDir, wxOutputStream& stream, int startIndent) +{ + if (!wxFileExists(htmlFile)) + return FALSE; + + // The path prefix is the path relative to the doc dir + wxString sep(wxFILE_SEP_PATH); + wxString pathPrefix(wxPathOnly(htmlFile)); + if (!wxIsAbsolutePath(htmlFile)) + { + pathPrefix = pathPrefix.Mid(docDir.Length() + 1); + } + + wxString topURL1(topURL); + if (!UseRelativeURLs() && !wxIsAbsolutePath(topURL1)) + topURL1 = docDir + sep + topURL1; + + wxSimpleHtmlParser parser; + if (parser.ParseFile(htmlFile)) + { + stream << "
  • "); + + if (!topURL.IsEmpty()) + { + stream << ""; + } + stream << "\n"; + int indent = startIndent; int level = 0; + wxSimpleHtmlTag* tag = parser.GetTopLevelTag()->GetChildren(); + + while (tag) + { + if (tag->GetType() == wxSimpleHtmlTag_Open && tag->NameIs("DL")) level ++ ; + if (tag->GetType() == wxSimpleHtmlTag_Close && tag->NameIs("DL")) level -- ; + if (tag->GetType() == wxSimpleHtmlTag_Open && tag->NameIs("A") && tag->HasAttribute("HREF") && level > 0) + CreateHHCOutputItem(tag, level, indent, pathPrefix, docDir, stream); + + tag = tag->GetNext(); + } + + // Close any remaining levels + int i; + while (indent > startIndent) + { + indent --; + for (i = 0; i < indent*2; i++) stream << " "; + stream << "\n"; + } + return TRUE; + } + else + return FALSE; +} + +// Just add the given contents item without parsing +bool ecHtmlIndexer::CreateHHCItem(const wxString& title, const wxString& topURL, const wxString& docDir, wxOutputStream& stream, int indent) +{ + wxString sep(wxFILE_SEP_PATH); + wxString topURL1(topURL); + if (!UseRelativeURLs()) + topURL1 = docDir + sep + topURL1; + + int i; + for (i = 0; i < indent*2; i++) stream << " "; + + stream << "
  • \n"; + + return TRUE; +} + +void ecHtmlIndexer::CreateHHCOutputItem(wxSimpleHtmlTag* tag, int level, int& indent, const wxString& pathPrefix, const wxString& docDir, wxOutputStream& stream) +{ + wxString url, text; + tag->GetAttributeValue(url, "HREF"); + tag->FindTextUntilTagClose(text, "A"); + text.Trim(TRUE); // Trim spaces from right of string + text.Replace("\n", " "); // Remove newlines + + // Need to adjust the URL to give the path relative to where the index is + url = pathPrefix + wxString(wxT("/")) + url; + + wxString sep(wxFILE_SEP_PATH); + wxString url1(url); + if (!UseRelativeURLs() && !wxIsAbsolutePath(url)) + url1 = docDir + sep + url; + + int i; + while (level > indent) + { + for (i = 0; i < indent*2; i++) stream << " "; + + stream << "
      "; + indent ++; + + // If we're skipping one or more levels, we need to insert + // a dummy node. + if (level > indent) + { + stream << "\n"; + for (i = 0; i < indent*2; i++) stream << " "; + + stream << "
    • "; + } + stream << "\n"; + } + + while (level < indent) + { + indent--; + for (i = 0; i < indent*2; i++) stream << " "; + + stream << "
    \n"; + } + + for (i = 0; i < indent*2; i++) stream << " "; + + stream << "
  • \n"; +} + +void ecHtmlIndexer::CreateHHCWriteHeader(wxOutputStream& stream) +{ + stream << "\n"; + stream << "\n\n\n"; + stream << "\n\n"; + stream << "
      \n"; +} + +void ecHtmlIndexer::CreateHHCWriteFooter(wxOutputStream& stream) +{ + stream << "
    \n"; + stream << ""; +} + +bool ecHtmlIndexer::CreateHHCStartSection(const wxString& title, const wxString& topURL, const wxString& docDir, wxOutputStream& stream) +{ + wxString sep(wxFILE_SEP_PATH); + wxString url1(topURL); + if (!UseRelativeURLs() && !wxIsAbsolutePath(url1)) + url1 = docDir + sep + url1; + + stream << "
  • "); + + if (!topURL.IsEmpty()) + { + stream << "" ; + } + stream << "\n
      \n" ; + return TRUE; +} + +bool ecHtmlIndexer::CreateHHCEndSection(wxOutputStream& stream) +{ + stream << "
    \n"; + return TRUE; +} + +// Write the project file +bool ecHtmlIndexer::WriteHHP(const wxString& filename, const wxString& docDir) +{ + wxFileOutputStream stream(filename); + + wxString sep(wxFILE_SEP_PATH); + wxString path, name, ext; + wxSplitPath(filename, & path, & name, & ext); + + wxString compiledFile(name + wxT(".chm")); + wxString contentsFile(name + wxT(".hhc")); + wxString keywordFile(name + wxT(".hhk")); + + stream << "[OPTIONS]\n\ +Auto Index=Yes\n\ +Binary Index=No\n\ +Compatibility=1.1 or later\n\ +Compiled file="; + stream << compiledFile << "\nContents file=" << contentsFile << "\n"; + stream << +"Default Window=mainwin\n\ +Default topic="; + if (!UseRelativeURLs()) + stream << docDir + sep; + stream << wxT("index.html") << "\n\ +Display compile progress=Yes\n\ +Full-text search=Yes\n" << + +// Index file=" << keywordFile << "\n + +"Language=0x409 English (United States)\n\ +Title=eCos\n"; + + stream << +"[WINDOWS]\n\ +mainwin=\"eCos Documentation\",\"eCos.hhc\",\"eCos.hhk\",,\"index.html\",\"http://sources.redhat.com/ecos/\",\"Net Release\",\"http://www.redhat.com/products/ecos/\",\"eCos Product\",0x40060420,,0xc287e,[0,0,762,400],,,,,,,0\n\ +\n\ +[FILES]\n\ +index.html\n\ +\n\ +[INFOTYPES]\n" ; + + return TRUE; + +} + +// Create a section for all the Packages in the system, using the current document/repository. +// TODO: check each URL for redirection. +bool ecHtmlIndexer::CreateHHCPackagesSection(const wxString& title, const wxString& topURL, wxOutputStream& stream, const wxString& htmlPath) +{ + ecConfigToolDoc* doc = wxGetApp().GetConfigToolDoc(); + if (!doc) + return FALSE; + + // If we have multiple tutorials or whatever, then we need to repeat this line ONCE + // and then generate the multiple files. Otherwise we'll be repeating the same "Getting Started with eCos" + // line. I.e. it'll only look right if we only have one tutorial. + stream << "
  • "); + + if (!topURL.IsEmpty()) + { + stream << "" ; + } + stream << "\n
      \n" ; + + // generate the contents of the add/remove list boxes + const std::vector & packages = doc->GetCdlPkgData ()->get_packages (); + + std::vector::const_iterator package_i; + for (package_i = packages.begin (); package_i != packages.end (); package_i++) + { + // if (! m_CdlPkgData->is_hardware_package (* package_i)) // do not list hardware packages + { + const std::vector & aliases = doc->GetCdlPkgData ()->get_package_aliases (* package_i); + wxString strMacroName = package_i->c_str (); + + // use the first alias (if any) as the package identifier + wxString strPackageName = aliases.size () ? aliases [0].c_str () : strMacroName.c_str(); + ecConfigItem * pItem = doc->Find (strMacroName); + if (pItem) // if the package is loaded + { + // TODO: what if the package is not loaded? how do we access the URL?? + + wxString url(pItem->GetURL()); + + url = htmlPath + wxString(wxFILE_SEP_PATH) + Redirect(htmlPath, url); + + stream << "
    • "); + + if (!url.IsEmpty()) + { + stream << "" ; + } + stream << "\n" ; + } + } + } + + stream << "
    \n"; + return TRUE; +} + +// Keeping looking for redirection until there's none. +wxString ecHtmlIndexer::Redirect(const wxString& baseName, const wxString& url) +{ + wxString path(baseName); + path += wxFILE_SEP_PATH; + path += url; + + wxString relativePath(wxPathOnly(url)); + + wxSimpleHtmlParser parser; + if ((path.Find(wxT('#')) == -1) && wxFileExists(path) && parser.ParseFile(path)) + { + wxSimpleHtmlTag* tag = parser.GetTopLevelTag()->GetChildren(); + + wxSimpleHtmlTag* refreshTag = tag->FindTag(wxT("meta"), wxT("http-equiv")); + if (refreshTag) + { + wxString value; + if (refreshTag->GetAttributeValue(value, wxT("content"))) + { + if (!value.AfterFirst(wxT('=')).IsEmpty()) + value = value.AfterFirst(wxT('=')) ; + + wxString newURL(relativePath + wxString(wxFILE_SEP_PATH) + value); + return Redirect(baseName, newURL); + } + } + } + return url; +} + +bool ecHtmlIndexer::DoIndexDocs(const wxString& reposDir, wxString& projectFile, bool force) +{ + wxString sep(wxFILE_SEP_PATH); + + wxString docDir(reposDir + sep + wxString(wxT("doc"))) ; + + // The CVS repository has an HTML subdirectory, but the + // packaged version doesn't + if (wxDirExists(docDir + sep + wxT("html"))) + docDir = docDir + sep + wxString(wxT("html")); + + wxString projectDir = FindIndexFilesDir(reposDir); + + projectFile = projectDir + sep + wxT("eCos.hhp"); + wxString contentsFile = projectDir + sep + wxT("eCos.hhc"); + wxString keywordFile = projectDir + sep + wxT("eCos.hhk"); + + // See if it's already been generated + if (wxFileExists(projectFile) && !force) + return TRUE; + + // Project file + if (!WriteHHP(projectFile, docDir)) + return FALSE; + + wxFileOutputStream stream(contentsFile); + + if (!stream.Ok()) + return FALSE; + + // Pop up a progress dialog + wxProgressDialog dialog(wxGetApp().GetSettings().GetAppName(), + _("Compiling documentation index..."), m_indexItems.Number(), + wxGetApp().GetTopWindow()); + + CreateHHCWriteHeader(stream); + + int count = 1; + wxNode* node = m_indexItems.First(); + while (node) + { + dialog.Update(count); + count ++; + + ecIndexItem* item = (ecIndexItem*) node->Data(); + wxString filename(item->m_urlToExamine); + wxString urlFilename(item->m_urlToShow); + + if (!filename.IsEmpty()) + { + if (!wxIsAbsolutePath(filename)) + filename = docDir + sep + filename; +#ifdef __WXMSW__ + filename.Replace(wxT("/"), wxT("\\")); +#endif + } + + // Check that the URL we're going to show is available, + // otherwise don't output it + bool isOk = TRUE; + if (!urlFilename.IsEmpty()) + { + if (!wxIsAbsolutePath(urlFilename)) + urlFilename = docDir + sep + urlFilename; +#ifdef __WXMSW__ + urlFilename.Replace(wxT("/"), wxT("\\")); +#endif + // Remove # part if there is any + if (urlFilename.Find(wxT('#')) != -1) + urlFilename = urlFilename.BeforeLast(wxT('#')); + if (!wxFileExists(urlFilename)) + isOk = FALSE; + } + + if (isOk) + { + switch (item->m_type) + { + case ecIndexByClass: + { + CreateHHCByExaminingClass(item->m_title, item->m_urlToShow, filename, docDir, stream, item->m_startLevel); + break; + } + case ecIndexByList: + { + CreateHHCByExaminingList(item->m_title, item->m_urlToShow, filename, docDir, stream, item->m_startLevel); + break; + } + case ecIndexNoParse: + { + CreateHHCItem(item->m_title, item->m_urlToShow, docDir, stream, item->m_startLevel); + break; + } + case ecIndexStartSection: + { + CreateHHCStartSection(item->m_title, item->m_urlToShow, docDir, stream); + break; + } + case ecIndexEndSection: + { + CreateHHCEndSection(stream); + break; + } + default: + { + wxASSERT( FALSE ); + break; + } + } + } + + node = node->Next(); + } + + CreateHHCPackagesSection(wxT("Packages"), wxEmptyString, stream, docDir); + + CreateHHCWriteFooter(stream); + +#if 0 // def __WXGTK__ + // Hack to restore correct colour to short description window + ecShortDescriptionWindow* sdw = wxGetApp().GetMainFrame()->GetShortDescriptionWindow(); + + wxColour oldColour = sdw->GetBackgroundColour(); + if (oldColour.Ok()) + { + sdw->SetBackgroundColour(*wxBLACK); + sdw->SetBackgroundColour(oldColour); + } +#endif + + return TRUE; +} + +static bool ecDirectoryWriteable(const wxString& dir) +{ + // See if we can write to it + wxString sep(wxFILE_SEP_PATH); + wxString testFile = dir + sep + wxT("_test.tmp"); + + bool ok = FALSE; + + { + wxLogNull log; + wxFile file; + ok = file.Create(testFile) ; + if (ok) + { + file.Close(); + wxRemoveFile(testFile); + } + } + + return ok; +} + +// Find appropriate destination directory for writing files to +wxString ecHtmlIndexer::FindIndexFilesDir(const wxString& reposDir) +{ + wxString sep(wxFILE_SEP_PATH); + + // First try install dir + wxString dir = reposDir; + +#ifdef __WXMSW__ + if (!ecDirectoryWriteable(dir)) + { + // Try temp directory as a last resort + if (!wxGetEnv(wxT("TEMP"), & dir)) + { + dir = wxT("c:\\temp"); + } + return dir; + } + else + { + return dir; + } + +#else + if (!ecDirectoryWriteable(dir)) + { + dir = wxGetHomeDir(); + if (!ecDirectoryWriteable(dir)) + { + // Try temp directory as a last resort + if (!wxGetEnv(wxT("TEMP"), & dir)) + { + dir = wxT("/tmp"); + } + } + else + { + wxString ecosDir = dir + sep + wxT(".eCosDocs"); + if (!wxDirExists(ecosDir)) + { + wxMkdir(ecosDir); + } + wxString name(ecMakeNameFromPath(reposDir)); + wxString ecosVerDir = ecosDir + sep + name; + if (!wxFileExists(ecosVerDir)) + { + wxMkdir(ecosVerDir); + } + dir = ecosVerDir; + } + return dir; + } + else + { + return dir; + } + +#endif +} + +//// Operations on items +void ecHtmlIndexer::AddIndexByClass(const wxString& title, const wxString& urlToShow, const wxString& urlToExamine, int startIndent) +{ + m_indexItems.Append(new ecIndexItem(ecIndexByClass, title, urlToShow, urlToExamine, startIndent)); +} + +void ecHtmlIndexer::AddIndexByList(const wxString& title, const wxString& urlToShow, const wxString& urlToExamine, int startIndent) +{ + m_indexItems.Append(new ecIndexItem(ecIndexByList, title, urlToShow, urlToExamine, startIndent)); +} + +void ecHtmlIndexer::AddIndexItem(const wxString& title, const wxString& urlToShow, int startIndent) +{ + m_indexItems.Append(new ecIndexItem(ecIndexNoParse, title, urlToShow, wxEmptyString, startIndent)); +} + +void ecHtmlIndexer::AddStartSection(const wxString& title, const wxString& urlToShow) +{ + m_indexItems.Append(new ecIndexItem(ecIndexStartSection, title, urlToShow, wxEmptyString)); +} + +void ecHtmlIndexer::AddEndSection() +{ + m_indexItems.Append(new ecIndexItem(ecIndexEndSection, wxEmptyString, wxEmptyString, wxEmptyString)); +} + +void ecHtmlIndexer::ClearItems() +{ + wxNode* node = m_indexItems.First(); + while (node) + { + ecIndexItem* item = (ecIndexItem*) node->Data(); + delete item; + node = node->Next(); + } + m_indexItems.Clear(); +} + +// Top-level function: generate appropriate index files +// and place them either in the install directory or if that is read-only, +// in the user's .eCos directory. +// Returns TRUE and the created project file if successful +bool ecHtmlIndexer::IndexDocs(const wxString& reposDir, wxString& projectFile, bool force) +{ + AddStartSection(wxT("Getting Started with eCos"), wxT("")); + AddIndexByClass(wxT("AM31-33"), wxT("tutorials/am31-33/ecos-tutorial.1.html"), wxT("tutorials/am31-33/ecos-tutorial.2.html")); + AddIndexByClass(wxT("ARM"), wxT("tutorials/arm/ecos-tutorial.1.html"), wxT("/tutorials/arm/ecos-tutorial.2.html")); + AddIndexByClass(wxT("i386 PC"), wxT("tutorials/i386pc/ecos-tutorial.1.html"), wxT("tutorials/i386pc/ecos-tutorial.2.html")); + AddIndexByClass(wxT("PowerPC"), wxT("tutorials/ppc/ecos-tutorial.1.html"), wxT("tutorials/ppc/ecos-tutorial.2.html")); + AddIndexByClass(wxT("SH-3"), wxT("tutorials/sh3/ecos-tutorial.1.html"), wxT("tutorials/sh3/ecos-tutorial.2.html")); + AddIndexByClass(wxT("SPARClite"), wxT("tutorials/sparclite/ecos-tutorial.1.html"), wxT("tutorials/sparclite/ecos-tutorial.2.html")); + AddIndexByClass(wxT("MIPS"), wxT("tutorials/mips/ecos-tutorial.1.html"), wxT("tutorials/mips/ecos-tutorial.2.html")); + AddIndexByClass(wxT("V850"), wxT("tutorials/v850/ecos-tutorial.1.html"), wxT("tutorials/v850/ecos-tutorial.2.html")); + AddEndSection(); + + AddIndexByClass(wxT("eCos User's Guide"), wxT("guides/user-guides.1.html"), wxT("guides/user-guides.2.html")); + + // We don't yet know how to parse the RedBoot guide + AddIndexItem(wxT("RedBoot User's Guide"), wxT("redboot/redboot.html")); + + AddIndexByClass(wxT("Linux Configuration Tool Guide"), wxGetApp().GetFullAppPath(wxT("manual/user-guides.4.html")), wxGetApp().GetFullAppPath(wxT("manual/user-guides.2.html"))); + + AddIndexByList(wxT("eCos Component Writer's Guide"), wxT("cdl/cdl-guide.html"), wxT("cdl/cdl-guide.html")); + + AddIndexByClass(wxT("eCos Reference Manual"), wxT("ref/ecos-ref.1.html"), wxT("ref/ecos-ref.2.html")); + + AddIndexByClass(wxT("eCos-EL/IX Compatibility Guide"), wxT("ecos-elix/ecos-elix.html"), wxT("ecos-elix/ecos-elix.1.html"), 1); + + AddStartSection(wxT("GNUPro Toolkit Reference Manual")); + // Start at indent 1 to avoid a spurious level + AddIndexByClass(wxT("ARM"), wxT("ref/gnupro-ref/arm/ARM_COMBO_front.html"), wxT("ref/gnupro-ref/ARM_COMBOTOC.html"), 1); + AddIndexByClass(wxT("Fujitsu SPARClite"), wxT("ref/gnupro-ref/sparclite/index.html"), wxT("ref/gnupro-ref/sparclite/index.html")); + AddIndexByClass(wxT("Matsushita MN10300"), wxT("ref/gnupro-ref/mn10300/am33_front.html"), wxT("ref/gnupro-ref/mn10300/am33toc.html")); + AddIndexByClass(wxT("PowerPC"), wxT("ref/gnupro-ref/powerpc/index.html"), wxT("ref/gnupro-ref/powerpc/index.html")); + AddIndexByClass(wxT("Toshiba MIPS TX39"), wxT("/gnupro-ref/tx39/index.html"), wxT("/gnupro-ref/tx39/index.html")); + + // Don't parse HTML, just add this item, if the page exists. + // Presumably the HTML can't be parsed for some reason. + AddIndexItem(wxT("Toshiba MIPS TX49"), wxT("ref/gnupro-ref/tx49/tx49_ref.html")); + + AddIndexByClass(wxT("Hitachi SuperH"), wxT("ref/gnupro-ref/sh/SH_front.html"), wxT("ref/gnupro-ref/sh/SHTOC.html")); + + AddIndexItem(wxT("NEC V850"), wxT("ref/gnupro-ref/v850/v850_ref_3.html")); + AddIndexByClass(wxT("NEC VR4300"), wxT("ref/gnupro-ref/vr4300/Vr43REF_front.html"), wxT("ref/gnupro-ref/vr4300/Vr43REFTOC.html")); + AddEndSection(); + + DoIndexDocs(reposDir, projectFile, force); + + return TRUE; +} diff --git a/host/tools/configtool/standalone/wxwin/docsystem.h b/host/tools/configtool/standalone/wxwin/docsystem.h new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/docsystem.h @@ -0,0 +1,147 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): julians +// Contact(s): julians +// Date: 2001/04/04 +// Version: 0.01 +// Purpose: +// Description: Classes for the Configtool documentation system +// Requires: +// Provides: +// See also: +// Known bugs: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== + +#ifndef _EC_DOCSYSTEM_H_ +#define _EC_DOCSYSTEM_H_ + +#ifdef __GNUG__ +#pragma interface "docsystem.cpp" +#endif + +#include "htmlparser.h" + +enum ecIndexType { ecIndexByClass, ecIndexByList, ecIndexNoParse, ecIndexStartSection, ecIndexEndSection } ; + +/* + * ecHtmlIndexer + * A class to parse files and generate suitable MS Html Help/wxHTML Help compatible + * project, contents and keyword files. + */ + +class ecHtmlIndexer: public wxObject +{ +public: + ecHtmlIndexer(bool useRelativeURLs = TRUE); + ~ecHtmlIndexer(); + +//// Operations + // Top-level function: generate appropriate index files + // and place them either in the install directory or if that is read-only, + // in the user's .eCos directory + // Returns TRUE and the created project file if successful + bool IndexDocs(const wxString& reposDir, wxString& projectFile, bool force = TRUE); + + // Creates the project, contents and keywords files using the ecIndexItems + // we previously added. + bool DoIndexDocs(const wxString& reposDir, wxString& projectFile, bool force = TRUE); + + // If tag is an , write the item by looking at the text between and + void CreateHHCOutputItem(wxSimpleHtmlTag* tag, int level, int& indent, const wxString& pathPrefix, const wxString& docDir, wxOutputStream& stream); + + // Append HHC-compatible code to a stream according to the tags found in the + // given HTML file: use P CLASS attributes to determine level. + bool CreateHHCByExaminingClass(const wxString& title, const wxString& topURL, const wxString& htmlFile, const wxString& docDir, wxOutputStream& stream, int startIndent = 0); + + // Append HHC-compatible code to a stream according to the tags found in the + // given HTML file: use
    level + bool CreateHHCByExaminingList(const wxString& title, const wxString& topURL, const wxString& htmlFile, const wxString& docDir, wxOutputStream& stream, int startIndent = 0); + + // Just add the given contents item without parsing + bool CreateHHCItem(const wxString& title, const wxString& topURL, const wxString& docDir, wxOutputStream& stream, int startIndent = 0); + + void CreateHHCWriteHeader(wxOutputStream& stream); + void CreateHHCWriteFooter(wxOutputStream& stream); + + // Start a section, which may or may not contain multiple subsections, one per architecture + bool CreateHHCStartSection(const wxString& title, const wxString& topURL, const wxString& docDir, wxOutputStream& stream); + bool CreateHHCEndSection(wxOutputStream& stream); + + // Create a section for all the Packages in the system, using the current document/repository + bool CreateHHCPackagesSection(const wxString& title, const wxString& topURL, wxOutputStream& stream, const wxString& htmlPath); + + // Convert redirection to actual filename + static wxString Redirect(const wxString& baseName, const wxString& url); + + // Write the project file + bool WriteHHP(const wxString& filename, const wxString& docDir); + + // Find appropriate destination directory for writing files to + wxString FindIndexFilesDir(const wxString& reposDir) ; + +//// Operations on items + void AddIndexByClass(const wxString& title, const wxString& urlToShow, const wxString& urlToExamine, int startIndent = 0); + void AddIndexByList(const wxString& title, const wxString& urlToShow, const wxString& urlToExamine, int startIndent = 0); + void AddIndexItem(const wxString& title, const wxString& urlToShow, int startIndent = 0); + void AddStartSection(const wxString& title, const wxString& urlToShow = wxEmptyString); + void AddEndSection(); + void ClearItems(); + +//// Accessors + wxList& GetIndexItems() { return m_indexItems; } + bool UseRelativeURLs() const { return m_useRelativeURLs; } + +private: + // List of ecIndexItems + wxList m_indexItems; + bool m_useRelativeURLs; +}; + +class ecIndexItem: public wxObject +{ +public: + ecIndexItem(ecIndexType type, const wxString& title, const wxString& urlToShow, + const wxString& urlToExamine, int startLevel = 0) + { + m_type = type; m_title = title; m_urlToShow = urlToShow; + m_urlToExamine = urlToExamine; m_startLevel = startLevel; + } + + ecIndexType m_type; + wxString m_title; + wxString m_urlToShow; + wxString m_urlToExamine; + int m_startLevel; +}; + +#endif + diff --git a/host/tools/configtool/standalone/wxwin/ecoslogo.png b/host/tools/configtool/standalone/wxwin/ecoslogo.png new file mode 100644 index 0000000000000000000000000000000000000000..a5350819e85f32f108e1166ca7fd87d758b0ba49 GIT binary patch literal 1117 zc$@)U1fu(iP)H#W20000LbVXQnLvm$d zbZKvHAXI5>WdH}z2@4AyI10gw>;M1&2XskIMF-Fc3kx0>Upxi|00009a7bBm000ie z000ie0hKEb8vpxMPFZcKhLO_E+4p;7_n?yf%)+kRX^Y{Dz_xJz*|J|G&yZ`_LpGibPRCwC$m``gOK@`9@pvfhNoO%lML(D;iK)v)9 zsE4SRf+^(Br4Wl48xTBrD1kr^9+HBP&k}5^!oq%(1d?imq0^n&c{A@#va6wMPtL{N zb>_Ek-v3!oENR?(EAoo`f60F^d3ack8`bdd8JjoGeNCEFkDHdv54`xXz7UzQzJ}Gx z2X{c`B`*asplj7bBl9OO6*B86TBqFt@~xK=xe!p_;Kj7aM%9}9(@Tw9pyX0|WUXmU zo>)eva&)x!Pvjj;zA=cZGQjB;;l4jQCggrNiH{L1-wymU*M^F0lu?BsLg>ur=$Rq6 zb;vsYz#IA&kvTx#m`Jx?xCVLyvN66vYZRcbEqUTX!m$tJkAjkO#$m;PDpvH!y(B+s z$S%rNQ~fL}95Q-4r%&`P%USaMbCHeEHHVzTbCl5efWDgLpOH84BJn#ipK!>1Jcpaj z`+fk*VeA=MiTA6dJ%lUw*jAJLD|Q*othI){d_MrqO7b+6)bGWS*W}#kmQlD;$B7Xw zH#W*pR~Mj;clx)$;>a@2MBQrq2HwUaVa|bv3>V7EzFRMeA#Wm&*wrDwPC`WE2G#|* zcHd<32VryGx_--saF)rq?xFzcMl$nW5?QKr*wRD(6{`F#a#L`qDcne58UKiUUYv!pyYWQZNV8%Gukk_UJL4>lo*@oUKs^T-#l zpz%ub(>yXHY%xmEa}&2*#W~u@nGHpuZfyM$x$e}zMSMefV>^j_B5*9KQ(=E54&#ZTV$UX7^(m(1qz>BkJ)t9&)2?;$ing?s(8KkeXO_B|nOox(9{sDtQ zJ7%ibwI!QgbPcqMPg>bFCFgy*`Ot01E$&5ay3if%l%4@9$1OzG>BlxMjQ#L!`%L?1 zlrAc*pw%oo>BH^$3zuVDQRyH(|MJc$sh+I@LSEi^aCv9gw9nm`obI;*OiuUv1|g^U jO~xgsJXYitIhOnvh&F`$ZR$9M00000NkvXXu0mjfU?~(B diff --git a/host/tools/configtool/standalone/wxwin/ecoslogosmall.png b/host/tools/configtool/standalone/wxwin/ecoslogosmall.png new file mode 100644 index 0000000000000000000000000000000000000000..1432646221a9cefe2983517893b205c447b4a3f0 GIT binary patch literal 2475 zc%0?d|6dII9tZFtDG|BqNK_)Uk*sj_g;=|{+SAsyZDB=UrXJO96uWd7hh$4?%eN`i z%9mOtcZAv^kCCWxQcXoxQA_HyD(8%&qmdJPKkMB4SKQa*`FVZb^Lfl?9{b}S=Lh(h zo7tE_5M=J>%NBrrFIbCBjX<|NaC`waD;Z~tY}1~YNLhU1uKB|FoiUI}yOG5|Oy-(r z9GwqdFp>H3INy(^IM43j^@F1+Nxoa95Hww8SQ8|U6&eUKg82SI4rGWaWNHXxYGG<> z0Rov?n*tWr)_}FOgEg2PEWqyI@O^;;hJyox0WcUA4oqtYrUSrWG8jxI0}SpAraO!2 z&M*{<1+c)tb!Tx|?pzj&%LTYxfuRKgu0X^Uz<>Zm1j6F}{RE3dFbu%3J68gWBobI6 zg(U)!R0K<5Kq8e&qyiWb!3ZotB!Co9NDu&(BIx&L1VQ8oqCn(;QZA9o5xHD}DnQ9m z1sD`c1q!H81&X3d6va@b3RPlCRH;;|z@!4R3R9^tOogcp4N8q+YBi?D4Fj$=1jp4l zp$0Q3lE87i4m3#^LXzMJCrAR6h9EQ~Xi`HOXi1Ice-B{NYP4GIe>V`FP73P~iB2xn zDG;4Pu0s_%rBbH?R5}d6bZS7Y!*Lx+>PU?a+yS=?p>z~Qu^cEaz@P*GlM=X7B7jA~ zTuLIKq#_D|DMUiarIZ4pP&tJvC?!g%040T~C=8?2DoPDnP2o625R^tkX~C!e{yGRv zQF@xopao1?;7*GG77YVjS|XsOfQXjDGy+IyIUuDK079dHoJJM2Qcf#DqqGW8(iotk z)flZ-(>Q?B1VGRPNs}b40W`EmOKSlgtpg0dfTrm0(d#j#UaiurF+Hx<6S$rv^cqsH z(de~+R<8qedJ3TQ6s-prz!kkd+|fl3K@%XEARt)({~aipHdzEg#xwoc8-+i;Y&a+J z593&-%nsG?^A}GlNRQ$@mtRfIq+);WNS^!Jh4=nZo;co|nVD*{Xw9OGWvNb=t@c&; z|9;ywdGqa)4?~}Pqh>r?-X8brosIT{XRU8r@sZ&RZpi~Ae(&Z6c58W;R7WNcG`q)= z+p|6%&fwU;t@*exUd0WKCBwh&H{P?~a`@z#+$FYFN{`QVIpg!Tg^CzU zG~xKuPfckz@`v^?mt|dryVBFJH3cpCf0PFYRV)((_RRlxe#qyJ`$I!RMXkG^1ao0o~4H(-+XQ%pbG7Qn;)}ACp7qS zvfJagObe_UI~mc`5E*hJcHm0*ZY=!LzRo|h@9){+8xvNuBV`xk#l?5RMBy)-gEd)+ zmEkWAJ2}+J+3AD3jDjsQn49ayYtLLuvwXSxPH}NGeO6Ze^87aM_V+~I^V+qov2SB> z`ebp2pv?BFzfU)NaL~9Yru@sL5wkhpd>@*Qd7drSnykLAw2dJ~BEBwPNg5wTgX~8v z_r8qp49ei_oEq_}<1+F?X`_1qyTt<{Yp$m>?%c}`;uKo7^Ne}%fz9>nyqJ9Za|4le zH7n*N6|L&{1l0v>e<1TI{F3lb|Lpu}wHweg>$mqV(w>^zb+@dq%g$4DI)7LwXq4Tu z`Eg0a+UP5ztTwa9>Aw9@Z%+|(zJ2=%a@p8ZT6|S|L-0E7^4s1slKR$fmf}3_Rt#aBfygm*B5ga?8XSUJxx_)O;br#IapA zHY;IF^yrG6X?NlqpNc$w#b9Zdm2hO>g7N4m(~-da{{O5pAOMJD*W}n>(JO&o7H$qE6W!#pUV4? z^ntfWJSS0@;A%s~jkS5$5yp>`%*tM6G#qZ@n`I6AzuVZOa1YTSz0FI8Qd)IkIedjq@JTDP2S6v-a~>j11;3S_ZMEX5A}xA zMM&TJMj`uTf1V@rQ4gHCAw;}pYo5z>>Y*w$;gU1eb7xd&*;{S@*CDK{@D?FVJ^{tN zF3)+IUA4NH>wUpZhL3MsH#+*PpTao)tSM_^;&031Ht~MWp@*x}kfj diff --git a/host/tools/configtool/standalone/wxwin/ecpch.h b/host/tools/configtool/standalone/wxwin/ecpch.h new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/ecpch.h @@ -0,0 +1,68 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +// ecpch.h : +// +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): julians +// Contact(s): julians +// Date: 2000/08/24 +// Version: $Id: ecpch.h,v 1.1 2001/02/08 18:06:50 julians Exp $ +// Purpose: +// Description: Precompiled header include file +// Requires: +// Provides: +// See also: +// Known bugs: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== + +#ifndef _ECOS_ECPCH_H_ +#define _ECOS_ECPCH_H_ + +#ifdef __VISUALC__ +#pragma warning(disable:4786) +#endif + +#include "wx/wx.h" +#include "wx/splitter.h" +#include "wx/scrolwin.h" +#include "wx/imaglist.h" +#include "wx/laywin.h" +#include "wx/docview.h" + +#ifdef new +#undef new +#endif + +#include "configtool.h" +#include "cdl.hxx" + +#endif + // _ECOS_ECPCH_H_ diff --git a/host/tools/configtool/standalone/wxwin/ecscrolwin.cpp b/host/tools/configtool/standalone/wxwin/ecscrolwin.cpp new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/ecscrolwin.cpp @@ -0,0 +1,707 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: ecscrolwin.cpp +// Purpose: ecScrolledWindow implementation +// Author: Julian Smart +// Modified by: +// Created: 01/02/97 +// RCS-ID: $Id: ecscrolwin.cpp,v 1.2 2001/05/02 10:36:15 julians Exp $ +// Copyright: (c) Julian Smart and Markus Holzem +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// + +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + +#ifdef __GNUG__ + #pragma implementation "ecscrolwin.h" +#endif + +#ifdef __VMS +#define XtDisplay XTDISPLAY +#endif + +// Includes other headers for precompiled compilation +#include "ecpch.h" + +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + +#include "wx/utils.h" +#include "wx/dcclient.h" +#include "wx/panel.h" + +#include "ecscrolwin.h" + +#ifdef __WXMSW__ + #include "windows.h" +#endif + +#ifdef __WXMOTIF__ +// For wxRETAINED implementation +#ifdef __VMS__ //VMS's Xm.h is not (yet) compatible with C++ + //This code switches off the compiler warnings +# pragma message disable nosimpint +#endif +#include +#ifdef __VMS__ +# pragma message enable nosimpint +#endif +#endif + +#if !ecUSE_OWN_SCROLLED_WINDOW + +IMPLEMENT_CLASS(ecScrolledWindow, wxScrolledWindow) + +#else + +// ---------------------------------------------------------------------------- +// event tables +// ---------------------------------------------------------------------------- + +BEGIN_EVENT_TABLE(ecScrolledWindow, wxPanel) + EVT_SCROLLWIN(ecScrolledWindow::OnScroll) + EVT_SIZE(ecScrolledWindow::OnSize) + EVT_PAINT(ecScrolledWindow::OnPaint) + EVT_CHAR(ecScrolledWindow::OnChar) +END_EVENT_TABLE() + +IMPLEMENT_DYNAMIC_CLASS(ecScrolledWindow, wxPanel) + +// ============================================================================ +// implementation +// ============================================================================ + +// ---------------------------------------------------------------------------- +// ecScrolledWindow creation +// ---------------------------------------------------------------------------- + +ecScrolledWindow::ecScrolledWindow() +{ + m_xScrollPixelsPerLine = 0; + m_yScrollPixelsPerLine = 0; + m_xScrollingEnabled = TRUE; + m_yScrollingEnabled = TRUE; + m_xScrollPosition = 0; + m_yScrollPosition = 0; + m_xScrollLines = 0; + m_yScrollLines = 0; + m_xScrollLinesPerPage = 0; + m_yScrollLinesPerPage = 0; + m_scaleX = 1.0; + m_scaleY = 1.0; + m_targetWindow = (wxWindow*) NULL; +} + +bool ecScrolledWindow::Create(wxWindow *parent, + wxWindowID id, + const wxPoint& pos, + const wxSize& size, + long style, + const wxString& name) +{ + m_xScrollPixelsPerLine = 0; + m_yScrollPixelsPerLine = 0; + m_xScrollingEnabled = TRUE; + m_yScrollingEnabled = TRUE; + m_xScrollPosition = 0; + m_yScrollPosition = 0; + m_xScrollLines = 0; + m_yScrollLines = 0; + m_xScrollLinesPerPage = 0; + m_yScrollLinesPerPage = 0; + m_scaleX = 1.0; + m_scaleY = 1.0; + + m_targetWindow = this; + + bool ok = wxPanel::Create(parent, id, pos, size, style, name); + +#ifdef __WXMSW__ + // we need to process arrows ourselves for scrolling + m_lDlgCode |= DLGC_WANTARROWS; +#endif // __WXMSW__ + + return ok; +} + +ecScrolledWindow::~ecScrolledWindow() +{ +} + +// ---------------------------------------------------------------------------- +// setting scrolling parameters +// ---------------------------------------------------------------------------- + +/* + * pixelsPerUnitX/pixelsPerUnitY: number of pixels per unit (e.g. pixels per text line) + * noUnitsX/noUnitsY: : no. units per scrollbar + */ +void ecScrolledWindow::SetScrollbars (int pixelsPerUnitX, int pixelsPerUnitY, + int noUnitsX, int noUnitsY, + int xPos, int yPos, bool noRefresh ) +{ + int xpos, ypos; + + CalcUnscrolledPosition(xPos, yPos, &xpos, &ypos); + bool do_refresh = + ( + (noUnitsX != 0 && m_xScrollLines == 0) || + (noUnitsX < m_xScrollLines && xpos > pixelsPerUnitX*noUnitsX) || + + (noUnitsY != 0 && m_yScrollLines == 0) || + (noUnitsY < m_yScrollLines && ypos > pixelsPerUnitY*noUnitsY) || + (xPos != m_xScrollPosition) || + (yPos != m_yScrollPosition) +// (pixelsPerUnitX != m_xScrollPixelsPerLine) || +// (pixelsPerUnitY != m_yScrollPixelsPerLine) + ); + + m_xScrollPixelsPerLine = pixelsPerUnitX; + m_yScrollPixelsPerLine = pixelsPerUnitY; + m_xScrollPosition = xPos; + m_yScrollPosition = yPos; + m_xScrollLines = noUnitsX; + m_yScrollLines = noUnitsY; + +#ifdef __WXMOTIF__ + // Sorry, some Motif-specific code to implement a backing pixmap + // for the wxRETAINED style. Implementing a backing store can't + // be entirely generic because it relies on the wxWindowDC implementation + // to duplicate X drawing calls for the backing pixmap. + + if ((m_windowStyle & wxRETAINED) == wxRETAINED) + { + Display* dpy = XtDisplay((Widget) GetMainWidget()); + + int totalPixelWidth = m_xScrollLines * m_xScrollPixelsPerLine; + int totalPixelHeight = m_yScrollLines * m_yScrollPixelsPerLine; + if (m_backingPixmap && + !((m_pixmapWidth == totalPixelWidth) && + (m_pixmapHeight == totalPixelHeight))) + { + XFreePixmap (dpy, (Pixmap) m_backingPixmap); + m_backingPixmap = (WXPixmap) 0; + } + + if (!m_backingPixmap && + (noUnitsX != 0) && (noUnitsY != 0)) + { + int depth = wxDisplayDepth(); + m_pixmapWidth = totalPixelWidth; + m_pixmapHeight = totalPixelHeight; + m_backingPixmap = (WXPixmap) XCreatePixmap (dpy, RootWindow (dpy, DefaultScreen (dpy)), + m_pixmapWidth, m_pixmapHeight, depth); + } + + } +#endif // Motif + + AdjustScrollbars(); + + if (do_refresh && !noRefresh) + m_targetWindow->Refresh(); + +#ifdef __WXMSW__ + // GRG: if this turns out to be really necessary, we could + // at least move it to the above if { ... } so that it is + // only done if noRefresh = FALSE (the default). OTOH, if + // this doesn't break anything, which seems to be the + // case, we could just leave it out. + + // Necessary? + // UpdateWindow ((HWND) m_targetWindow->GetHWND()); +#endif +#ifdef __WXMAC__ + m_targetWindow->MacUpdateImmediately() ; +#endif +} + +// ---------------------------------------------------------------------------- +// target window handling +// ---------------------------------------------------------------------------- + +void ecScrolledWindow::SetTargetWindow( wxWindow *target ) +{ + wxASSERT_MSG( target, wxT("target window must not be NULL") ); + m_targetWindow = target; +} + +wxWindow *ecScrolledWindow::GetTargetWindow() +{ + return m_targetWindow; +} + +// ---------------------------------------------------------------------------- +// scrolling implementation itself +// ---------------------------------------------------------------------------- + +void ecScrolledWindow::OnScroll(wxScrollWinEvent& event) +{ + int orient = event.GetOrientation(); + + int nScrollInc = CalcScrollInc(event); + if (nScrollInc == 0) return; + + if (orient == wxHORIZONTAL) + { + int newPos = m_xScrollPosition + nScrollInc; + SetScrollPos(wxHORIZONTAL, newPos, TRUE ); + } + else + { + int newPos = m_yScrollPosition + nScrollInc; + SetScrollPos(wxVERTICAL, newPos, TRUE ); + } + + if (orient == wxHORIZONTAL) + { + m_xScrollPosition += nScrollInc; + } + else + { + m_yScrollPosition += nScrollInc; + } + + if (orient == wxHORIZONTAL) + { + if (m_xScrollingEnabled) + m_targetWindow->ScrollWindow(-m_xScrollPixelsPerLine * nScrollInc, 0, (const wxRect *) NULL); + else + m_targetWindow->Refresh(); + } + else + { + if (m_yScrollingEnabled) + m_targetWindow->ScrollWindow(0, -m_yScrollPixelsPerLine * nScrollInc, (const wxRect *) NULL); + else + m_targetWindow->Refresh(); + } +#ifdef __WXMAC__ + m_targetWindow->MacUpdateImmediately() ; +#endif +} + +int ecScrolledWindow::CalcScrollInc(wxScrollWinEvent& event) +{ + int pos = event.GetPosition(); + int orient = event.GetOrientation(); + + int nScrollInc = 0; + if (event.GetEventType() == wxEVT_SCROLLWIN_TOP) + { + if (orient == wxHORIZONTAL) + nScrollInc = - m_xScrollPosition; + else + nScrollInc = - m_yScrollPosition; + } else + if (event.GetEventType() == wxEVT_SCROLLWIN_BOTTOM) + { + if (orient == wxHORIZONTAL) + nScrollInc = m_xScrollLines - m_xScrollPosition; + else + nScrollInc = m_yScrollLines - m_yScrollPosition; + } else + if (event.GetEventType() == wxEVT_SCROLLWIN_LINEUP) + { + nScrollInc = -1; + } else + if (event.GetEventType() == wxEVT_SCROLLWIN_LINEDOWN) + { + nScrollInc = 1; + } else + if (event.GetEventType() == wxEVT_SCROLLWIN_PAGEUP) + { + if (orient == wxHORIZONTAL) + nScrollInc = -GetScrollPageSize(wxHORIZONTAL); + else + nScrollInc = -GetScrollPageSize(wxVERTICAL); + } else + if (event.GetEventType() == wxEVT_SCROLLWIN_PAGEDOWN) + { + if (orient == wxHORIZONTAL) + nScrollInc = GetScrollPageSize(wxHORIZONTAL); + else + nScrollInc = GetScrollPageSize(wxVERTICAL); + } else + if ((event.GetEventType() == wxEVT_SCROLLWIN_THUMBTRACK) || + (event.GetEventType() == wxEVT_SCROLLWIN_THUMBRELEASE)) + { + if (orient == wxHORIZONTAL) + nScrollInc = pos - m_xScrollPosition; + else + nScrollInc = pos - m_yScrollPosition; + } + + if (orient == wxHORIZONTAL) + { + if (m_xScrollPixelsPerLine > 0) + { + int w, h; + m_targetWindow->GetClientSize(&w, &h); + + int nMaxWidth = m_xScrollLines*m_xScrollPixelsPerLine; + int noPositions = (int) ( ((nMaxWidth - w)/(double)m_xScrollPixelsPerLine) + 0.5 ); + if (noPositions < 0) + noPositions = 0; + + if ( (m_xScrollPosition + nScrollInc) < 0 ) + nScrollInc = -m_xScrollPosition; // As -ve as we can go + else if ( (m_xScrollPosition + nScrollInc) > noPositions ) + nScrollInc = noPositions - m_xScrollPosition; // As +ve as we can go + } + else + m_targetWindow->Refresh(); + } + else + { + if (m_yScrollPixelsPerLine > 0) + { + int w, h; + m_targetWindow->GetClientSize(&w, &h); + + int nMaxHeight = m_yScrollLines*m_yScrollPixelsPerLine; + int noPositions = (int) ( ((nMaxHeight - h)/(double)m_yScrollPixelsPerLine) + 0.5 ); + if (noPositions < 0) + noPositions = 0; + + if ( (m_yScrollPosition + nScrollInc) < 0 ) + nScrollInc = -m_yScrollPosition; // As -ve as we can go + else if ( (m_yScrollPosition + nScrollInc) > noPositions ) + nScrollInc = noPositions - m_yScrollPosition; // As +ve as we can go + } + else + m_targetWindow->Refresh(); + } + + return nScrollInc; +} + +// Adjust the scrollbars - new version. +void ecScrolledWindow::AdjustScrollbars() +{ + int w, h; + m_targetWindow->GetClientSize(&w, &h); + + int oldXScroll = m_xScrollPosition; + int oldYScroll = m_yScrollPosition; + + if (m_xScrollLines > 0) + { + // Calculate page size i.e. number of scroll units you get on the + // current client window + int noPagePositions = (int) ( (w/(double)m_xScrollPixelsPerLine) + 0.5 ); + if (noPagePositions < 1) noPagePositions = 1; + + // Correct position if greater than extent of canvas minus + // the visible portion of it or if below zero + m_xScrollPosition = wxMin( m_xScrollLines-noPagePositions, m_xScrollPosition); + m_xScrollPosition = wxMax( 0, m_xScrollPosition ); + + SetScrollbar(wxHORIZONTAL, m_xScrollPosition, noPagePositions, m_xScrollLines); + // The amount by which we scroll when paging + SetScrollPageSize(wxHORIZONTAL, noPagePositions); + } + else + { + m_xScrollPosition = 0; + SetScrollbar (wxHORIZONTAL, 0, 0, 0, FALSE); + } + + if (m_yScrollLines > 0) + { + // Calculate page size i.e. number of scroll units you get on the + // current client window + int noPagePositions = (int) ( (h/(double)m_yScrollPixelsPerLine) + 0.5 ); + if (noPagePositions < 1) noPagePositions = 1; + + // Correct position if greater than extent of canvas minus + // the visible portion of it or if below zero + m_yScrollPosition = wxMin( m_yScrollLines-noPagePositions, m_yScrollPosition ); + m_yScrollPosition = wxMax( 0, m_yScrollPosition ); + + SetScrollbar(wxVERTICAL, m_yScrollPosition, noPagePositions, m_yScrollLines); + // The amount by which we scroll when paging + SetScrollPageSize(wxVERTICAL, noPagePositions); + } + else + { + m_yScrollPosition = 0; + SetScrollbar (wxVERTICAL, 0, 0, 0, FALSE); + } + + if (oldXScroll != m_xScrollPosition) + { + if (m_xScrollingEnabled) + m_targetWindow->ScrollWindow( m_xScrollPixelsPerLine * (oldXScroll-m_xScrollPosition), 0, (const wxRect *) NULL ); + else + m_targetWindow->Refresh(); + } + + if (oldYScroll != m_yScrollPosition) + { + if (m_yScrollingEnabled) + m_targetWindow->ScrollWindow( 0, m_yScrollPixelsPerLine * (oldYScroll-m_yScrollPosition), (const wxRect *) NULL ); + else + m_targetWindow->Refresh(); + } +} + +// Override this function if you don't want to have ecScrolledWindow +// automatically change the origin according to the scroll position. +void ecScrolledWindow::PrepareDC(wxDC& dc) +{ + dc.SetDeviceOrigin( -m_xScrollPosition * m_xScrollPixelsPerLine, + -m_yScrollPosition * m_yScrollPixelsPerLine ); + dc.SetUserScale( m_scaleX, m_scaleY ); +} + +#if WXWIN_COMPATIBILITY +void ecScrolledWindow::GetScrollUnitsPerPage (int *x_page, int *y_page) const +{ + *x_page = GetScrollPageSize(wxHORIZONTAL); + *y_page = GetScrollPageSize(wxVERTICAL); +} + +void ecScrolledWindow::CalcUnscrolledPosition(int x, int y, float *xx, float *yy) const +{ + if ( xx ) + *xx = (float)(x + m_xScrollPosition * m_xScrollPixelsPerLine); + if ( yy ) + *yy = (float)(y + m_yScrollPosition * m_yScrollPixelsPerLine); +} +#endif // WXWIN_COMPATIBILITY + +void ecScrolledWindow::GetScrollPixelsPerUnit (int *x_unit, int *y_unit) const +{ + if ( x_unit ) + *x_unit = m_xScrollPixelsPerLine; + if ( y_unit ) + *y_unit = m_yScrollPixelsPerLine; +} + +int ecScrolledWindow::GetScrollPageSize(int orient) const +{ + if ( orient == wxHORIZONTAL ) + return m_xScrollLinesPerPage; + else + return m_yScrollLinesPerPage; +} + +void ecScrolledWindow::SetScrollPageSize(int orient, int pageSize) +{ + if ( orient == wxHORIZONTAL ) + m_xScrollLinesPerPage = pageSize; + else + m_yScrollLinesPerPage = pageSize; +} + +/* + * Scroll to given position (scroll position, not pixel position) + */ +void ecScrolledWindow::Scroll( int x_pos, int y_pos ) +{ + if (!m_targetWindow) + return; + + if (((x_pos == -1) || (x_pos == m_xScrollPosition)) && + ((y_pos == -1) || (y_pos == m_yScrollPosition))) return; + + int w, h; + m_targetWindow->GetClientSize(&w, &h); + + if ((x_pos != -1) && (m_xScrollPixelsPerLine)) + { + int old_x = m_xScrollPosition; + m_xScrollPosition = x_pos; + + // Calculate page size i.e. number of scroll units you get on the + // current client window + int noPagePositions = (int) ( (w/(double)m_xScrollPixelsPerLine) + 0.5 ); + if (noPagePositions < 1) noPagePositions = 1; + + // Correct position if greater than extent of canvas minus + // the visible portion of it or if below zero + m_xScrollPosition = wxMin( m_xScrollLines-noPagePositions, m_xScrollPosition ); + m_xScrollPosition = wxMax( 0, m_xScrollPosition ); + + if (old_x != m_xScrollPosition) { + m_targetWindow->SetScrollPos( wxHORIZONTAL, m_xScrollPosition, TRUE ); + m_targetWindow->ScrollWindow( (old_x-m_xScrollPosition)*m_xScrollPixelsPerLine, 0 ); + } + } + if ((y_pos != -1) && (m_yScrollPixelsPerLine)) + { + int old_y = m_yScrollPosition; + m_yScrollPosition = y_pos; + + // Calculate page size i.e. number of scroll units you get on the + // current client window + int noPagePositions = (int) ( (h/(double)m_yScrollPixelsPerLine) + 0.5 ); + if (noPagePositions < 1) noPagePositions = 1; + + // Correct position if greater than extent of canvas minus + // the visible portion of it or if below zero + m_yScrollPosition = wxMin( m_yScrollLines-noPagePositions, m_yScrollPosition ); + m_yScrollPosition = wxMax( 0, m_yScrollPosition ); + + if (old_y != m_yScrollPosition) { + m_targetWindow->SetScrollPos( wxVERTICAL, m_yScrollPosition, TRUE ); + m_targetWindow->ScrollWindow( 0, (old_y-m_yScrollPosition)*m_yScrollPixelsPerLine ); + } + } + +#ifdef __WXMAC__ + m_targetWindow->MacUpdateImmediately(); +#endif +} + +void ecScrolledWindow::EnableScrolling (bool x_scroll, bool y_scroll) +{ + m_xScrollingEnabled = x_scroll; + m_yScrollingEnabled = y_scroll; +} + +void ecScrolledWindow::GetVirtualSize (int *x, int *y) const +{ + if ( x ) + *x = m_xScrollPixelsPerLine * m_xScrollLines; + if ( y ) + *y = m_yScrollPixelsPerLine * m_yScrollLines; +} + +// Where the current view starts from +void ecScrolledWindow::GetViewStart (int *x, int *y) const +{ + if ( x ) + *x = m_xScrollPosition; + if ( y ) + *y = m_yScrollPosition; +} + +void ecScrolledWindow::CalcScrolledPosition(int x, int y, int *xx, int *yy) const +{ + if ( xx ) + *xx = x - m_xScrollPosition * m_xScrollPixelsPerLine; + if ( yy ) + *yy = y - m_yScrollPosition * m_yScrollPixelsPerLine; +} + +void ecScrolledWindow::CalcUnscrolledPosition(int x, int y, int *xx, int *yy) const +{ + if ( xx ) + *xx = x + m_xScrollPosition * m_xScrollPixelsPerLine; + if ( yy ) + *yy = y + m_yScrollPosition * m_yScrollPixelsPerLine; +} + +// ---------------------------------------------------------------------------- +// event handlers +// ---------------------------------------------------------------------------- + +// Default OnSize resets scrollbars, if any +void ecScrolledWindow::OnSize(wxSizeEvent& WXUNUSED(event)) +{ +#if wxUSE_CONSTRAINTS + if (GetAutoLayout()) + Layout(); +#endif + + AdjustScrollbars(); +} + +// This calls OnDraw, having adjusted the origin according to the current +// scroll position +void ecScrolledWindow::OnPaint(wxPaintEvent& WXUNUSED(event)) +{ + wxPaintDC dc(this); + PrepareDC(dc); + + OnDraw(dc); +} + +// kbd handling: notice that we use OnChar() and not OnKeyDown() for +// compatibility here - if we used OnKeyDown(), the programs which process +// arrows themselves in their OnChar() would never get the message and like +// this they always have the priority +void ecScrolledWindow::OnChar(wxKeyEvent& event) +{ + int stx, sty, // view origin + szx, szy, // view size (total) + clix, cliy; // view size (on screen) + + ViewStart(&stx, &sty); + GetClientSize(&clix, &cliy); + GetVirtualSize(&szx, &szy); + + if( m_xScrollPixelsPerLine ) + { + clix /= m_xScrollPixelsPerLine; + szx /= m_xScrollPixelsPerLine; + } + else + { + clix = 0; + szx = -1; + } + if( m_yScrollPixelsPerLine ) + { + cliy /= m_yScrollPixelsPerLine; + szy /= m_yScrollPixelsPerLine; + } + else + { + cliy = 0; + szy = -1; + } + + int dsty; + switch ( event.KeyCode() ) + { + case WXK_PAGEUP: + case WXK_PRIOR: + dsty = sty - (5 * cliy / 6); + Scroll(-1, (dsty == -1) ? 0 : dsty); + break; + + case WXK_PAGEDOWN: + case WXK_NEXT: + Scroll(-1, sty + (5 * cliy / 6)); + break; + + case WXK_HOME: + Scroll(0, event.ControlDown() ? 0 : -1); + break; + + case WXK_END: + Scroll(szx - clix, event.ControlDown() ? szy - cliy : -1); + break; + + case WXK_UP: + Scroll(-1, sty - 1); + break; + + case WXK_DOWN: + Scroll(-1, sty + 1); + break; + + case WXK_LEFT: + Scroll(stx - 1, -1); + break; + + case WXK_RIGHT: + Scroll(stx + 1, -1); + break; + + default: + // not for us + event.Skip(); + } +} +#endif +// ecUSE_OWN_SCROLLED_WINDOW diff --git a/host/tools/configtool/standalone/wxwin/ecscrolwin.h b/host/tools/configtool/standalone/wxwin/ecscrolwin.h new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/ecscrolwin.h @@ -0,0 +1,183 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: ecscrolwin.h +// Purpose: ecScrolledWindow class +// Used here to avoid any harmful changes in the equivalent wxWindows class +// Author: Julian Smart +// Modified by: +// Created: 01/02/97 +// RCS-ID: $Id: ecscrolwin.h,v 1.1 2001/05/01 17:18:47 julians Exp $ +// Copyright: (c) Julian Smart and Markus Holzem +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// + +#ifndef _EC_SCROLLWIN_H_ +#define _EC_SCROLLWIN_H_ + +#ifdef __GNUG__ + #pragma interface "ecscrolwin.h" +#endif + +// ---------------------------------------------------------------------------- +// headers and constants +// ---------------------------------------------------------------------------- + +#include "wx/window.h" +#include "wx/panel.h" + +// 1 to use our own scroled window to insulate us from +// wxWindows changes +#define ecUSE_OWN_SCROLLED_WINDOW 1 + +#if !ecUSE_OWN_SCROLLED_WINDOW +#include "wx/scrolwin.h" +#endif + +WXDLLEXPORT_DATA(extern const wxChar*) wxPanelNameStr; + +// default scrolled window style +#ifndef wxScrolledWindowStyle +#define wxScrolledWindowStyle (wxHSCROLL | wxVSCROLL) +#endif + +// ---------------------------------------------------------------------------- +// ecScrolledWindow +// ---------------------------------------------------------------------------- + +#if ecUSE_OWN_SCROLLED_WINDOW + +class ecScrolledWindow : public wxPanel +{ +public: + ecScrolledWindow(); + ecScrolledWindow(wxWindow *parent, + wxWindowID id = -1, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = wxScrolledWindowStyle, + const wxString& name = wxPanelNameStr) + { + Create(parent, id, pos, size, style, name); + } + + ~ecScrolledWindow(); + + bool Create(wxWindow *parent, + wxWindowID id, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = wxScrolledWindowStyle, + const wxString& name = wxPanelNameStr); + + // Normally the ecScrolledWindow will scroll itself, but in + // some rare occasions you might want it to scroll another + // window (e.g. a child of it in order to scroll only a portion + // the area between the scrollbars (spreadsheet: only cell area + // will move). + virtual void SetTargetWindow( wxWindow *target ); + virtual wxWindow *GetTargetWindow(); + + // Number of pixels per user unit (0 or -1 for no scrollbar) + // Length of virtual canvas in user units + // Length of page in user units + virtual void SetScrollbars(int pixelsPerUnitX, int pixelsPerUnitY, + int noUnitsX, int noUnitsY, + int xPos = 0, int yPos = 0, + bool noRefresh = FALSE ); + + // Physically scroll the window + virtual void Scroll(int x_pos, int y_pos); + +#if WXWIN_COMPATIBILITY + virtual void GetScrollUnitsPerPage(int *x_page, int *y_page) const; + virtual void CalcUnscrolledPosition(int x, int y, float *xx, float *yy) const; +#endif + + int GetScrollPageSize(int orient) const; + void SetScrollPageSize(int orient, int pageSize); + + virtual void GetScrollPixelsPerUnit(int *x_unit, int *y_unit) const; + + // Enable/disable Windows scrolling in either direction. + // If TRUE, wxWindows scrolls the canvas and only a bit of + // the canvas is invalidated; no Clear() is necessary. + // If FALSE, the whole canvas is invalidated and a Clear() is + // necessary. Disable for when the scroll increment is used + // to actually scroll a non-constant distance + virtual void EnableScrolling(bool x_scrolling, bool y_scrolling); + + // Get the view start + virtual void GetViewStart(int *x, int *y) const; + // Compatibility + void ViewStart(int *x, int *y) const + { GetViewStart( x, y ); } + + // Actual size in pixels when scrolling is taken into account + virtual void GetVirtualSize(int *x, int *y) const; + + // Set the scale factor, used in PrepareDC + void SetScale(double xs, double ys) { m_scaleX = xs; m_scaleY = ys; } + double GetScaleX() const { return m_scaleX; } + double GetScaleY() const { return m_scaleY; } + + virtual void CalcScrolledPosition(int x, int y, int *xx, int *yy) const; + virtual void CalcUnscrolledPosition(int x, int y, int *xx, int *yy) const; + + // Adjust the scrollbars + virtual void AdjustScrollbars(void); + + // Override this function to draw the graphic (or just process EVT_PAINT) + virtual void OnDraw(wxDC& WXUNUSED(dc)) {}; + + // Override this function if you don't want to have ecScrolledWindow + // automatically change the origin according to the scroll position. + virtual void PrepareDC(wxDC& dc); + + // implementation from now on + void OnScroll(wxScrollWinEvent& event); + void OnSize(wxSizeEvent& event); + void OnPaint(wxPaintEvent& event); + void OnChar(wxKeyEvent& event); + + // Calculate scroll increment + virtual int CalcScrollInc(wxScrollWinEvent& event); + +protected: + wxWindow *m_targetWindow; + int m_xScrollPixelsPerLine; + int m_yScrollPixelsPerLine; + bool m_xScrollingEnabled; + bool m_yScrollingEnabled; + int m_xScrollPosition; + int m_yScrollPosition; + int m_xScrollLines; + int m_yScrollLines; + int m_xScrollLinesPerPage; + int m_yScrollLinesPerPage; + double m_scaleX; + double m_scaleY; + +private: + DECLARE_EVENT_TABLE() + DECLARE_ABSTRACT_CLASS(ecScrolledWindow) + }; + +#else +class ecScrolledWindow : public wxScrolledWindow +{ +public: + ecScrolledWindow(wxWindow *parent, + wxWindowID id = -1, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = wxScrolledWindowStyle, + const wxString& name = wxPanelNameStr) + { + Create(parent, id, pos, size, style, name); + } + DECLARE_CLASS(ecScrolledWindow) +}; + +#endif + +#endif + // _EC_SCROLLWIN_H_ diff --git a/host/tools/configtool/standalone/wxwin/ecutils.cpp b/host/tools/configtool/standalone/wxwin/ecutils.cpp new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/ecutils.cpp @@ -0,0 +1,1007 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +// +//=========================================================================== +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): sdf +// Contact(s): sdf +// Date: 1998/08/11 +// Version: 0.01 +// Purpose: +// Description: This is a collection of utility functions. +// Modified by julians for wxWindows (originally CTUtils.h) +// Requires: +// Provides: +// See also: +// Known bugs: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== + +#ifdef __GNUG__ +#pragma implementation "ecutils.h" +#endif + +// Includes other headers for precompiled compilation +#include "ecpch.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#include "ecutils.h" +#include "wx/listctrl.h" +#include "wx/stream.h" + +#include // for DBL_DIG macro +#include +#include + +// Otherwise we get a strange link error under Linux +#ifndef __WXMSW__ +#ifdef errno +#undef errno +#endif +#endif + +#if 0 + +#define INCLUDEFILE +#include "IncludeSTL.h" + +#endif + +// Chop str into pieces, using cSep as separator. +// " and \ have usual semantics +// Return value is array of pieces found. + +int ecUtils::Chop(const wxString& psz, wxArrayString &ar, wxChar cSep, + bool bObserveStrings/*=false*/,bool bBackslashQuotes/*=false*/) + +{ + if(wxT(' ') == cSep) + { + return Chop(psz, ar, wxT("\t\n\v\f\r "), bObserveStrings, bBackslashQuotes); + } else { + wxASSERT(wxT('\0')!=cSep); + wxChar c[2]={cSep,wxT('\0')}; + return Chop(psz,ar,wxString(c),bObserveStrings,bBackslashQuotes); + } +} + +int ecUtils::Chop(const wxString& str, wxArrayString &ar, const wxString& sep, + bool bObserveStrings/*=false*/,bool bBackslashQuotes/*=false*/) +{ + ar.Clear(); + + const wxChar* pszSep = (const wxChar*) sep; + const wxChar* psz = (const wxChar*) str; + + int i=0; + for(;;){ + // Skip multiple separators + while(*psz && wxStrchr(pszSep,*psz)){ + psz++; + } + if(!*psz){ + return i; + } + wxString strTok; + if(bObserveStrings){ + bool bInString=FALSE; + do{ + if(*psz == wxT('\\') && bBackslashQuotes && psz[1]){ + strTok += psz[1]; + psz++; + } else if(*psz == wxT('"')){ + bInString ^= 1; + } else if (!bInString && *psz && NULL != wxStrchr(pszSep,*psz)) { + break; + } else { + strTok+=*psz; + } + } while (*++psz); + } else { + const wxChar* pszStart=psz; + do { + psz++; + } while (*psz && ! wxStrchr(pszSep,*psz)); + strTok=wxString(pszStart,psz-pszStart); + } + ar.Add(strTok); + i++; + } + return ar.GetCount(); +} + +#if 0 + +// vararg-style message box formatter +int ecUtils::MessageBoxF (LPCTSTR pszFormat, ...) +{ + int rc; + va_list args; + va_start(args, pszFormat); + rc=ecUtils::vMessageBox(MB_OK, pszFormat,args); + va_end(args); + return rc; +} + +// As above, but with type as first parameter. +int ecUtils::MessageBoxFT (UINT nType, LPCTSTR pszFormat, ...) +{ + int rc; + va_list args; + va_start(args, pszFormat); + rc=ecUtils::vMessageBox(nType, pszFormat,args); + va_end(args); + return rc; +} + +int ecUtils::vMessageBox(UINT nType, LPCTSTR pszFormat, va_list marker) +{ + int rc=0; + for(int nLength=100;nLength;) { + TCHAR *buf=new TCHAR[1+nLength]; + int n=_vsntprintf(buf, nLength, pszFormat, marker ); + if(-1==n){ + nLength*=2; // NT behavior + } else if (n 2 && str[0]==wxT('0') && (str[1]==wxT('x')||str[1]==wxT('X'))); + //d=_tcstol(str,&pEnd,bHex?16:10); + d=wxStrtol(str,&pEnd,bHex?16:10); + rc=(0==errno && (*pEnd==wxT('\0'))); + return rc; +} + +const wxString ecUtils::IntToStr(long d,bool bHex) +{ + wxString s; + s.Printf(bHex?wxT("0x%08x"):wxT("%d"),d); + return s; +} + +const wxString ecUtils::DoubleToStr (double dValue) +{ + wxString s; + s.Printf(wxT("%.*e"), DBL_DIG, dValue); + return s; +} + +bool ecUtils::StrToDouble (const wxString & strValue, double &dValue) +{ + extern int errno; + wxChar* pEnd; + errno = 0; + //dValue = _tcstod (strValue, &pEnd); + dValue = wxStrtod(strValue, &pEnd); + return (0 == errno) && (*pEnd == wxT('\0')); +} + +#if 0 +const wxString ecUtils::Explanation(CFileException & exc) +{ + wxString strMsg; + switch(exc.m_cause){ + case CFileException::none: strMsg=wxT("No error occurred.");break; + case CFileException::generic: strMsg=wxT(" An unspecified error occurred.");break; + case CFileException::fileNotFound: strMsg=wxT(" The file could not be located.");break; + case CFileException::badPath: strMsg=wxT(" All or part of the path is invalid.");break; + case CFileException::tooManyOpenFiles: strMsg=wxT(" The permitted number of open files was exceeded.");break; + case CFileException::accessDenied: strMsg=wxT(" The file could not be accessed.");break; + case CFileException::invalidFile: strMsg=wxT(" There was an attempt to use an invalid file handle.");break; + case CFileException::removeCurrentDir: strMsg=wxT(" The current working directory cannot be removed.");break; + case CFileException::directoryFull: strMsg=wxT(" There are no more directory entries.");break; + case CFileException::badSeek: strMsg=wxT(" There was an error trying to set the file pointer.");break; + case CFileException::hardIO: strMsg=wxT(" There was a hardware error.");break; + case CFileException::sharingViolation: strMsg=wxT(" SHARE.EXE was not loaded, or a shared region was locked.");break; + case CFileException::lockViolation: strMsg=wxT(" There was an attempt to lock a region that was already locked.");break; + case CFileException::diskFull: strMsg=wxT(" The disk is full.");break; + case CFileException::endOfFile: strMsg=wxT(" The end of file was reached. ");break; + default: + strMsg=wxT(" Unknown cause"); + break; + } + return strMsg; +} + + +const wxString ecUtils::LoadString(UINT id) +{ + wxString str; + str.LoadString(id); + return str; +} +#endif + +bool ecUtils::AddToPath(const ecFileName & strFolder, bool bAtFront) +{ + wxString strPath,strOldPath; + + if (wxGetEnv(wxT("PATH"), & strOldPath)) + { + // Place the user tools folders at the head or tail of the new path + if(bAtFront) + { + strPath.Printf(wxT("%s;%s"), (const wxChar*) strFolder.ShortName(), (const wxChar*) strOldPath); + } else + { + strPath.Printf(wxT("%s;%s"), (const wxChar*) strOldPath, (const wxChar*) strFolder.ShortName()); + } + } else + { + // unlikely, but ... + strPath = strFolder; + } + return (TRUE == wxSetEnv(wxT("PATH"),strPath)); +} + +#if 0 +wxString ecUtils::GetLastErrorMessageString() +{ + wxString str; + PTCHAR pszMsg; + FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + (LPTSTR)&pszMsg, + 0, + NULL + ); + + // Display the string. + str=pszMsg; + str.TrimRight(); + // Free the buffer. + LocalFree(pszMsg); + return str; + +} + +bool ecUtils::Launch(const ecFileName &strFileName, const ecFileName &strViewer) +{ + bool rc=false; + + if(!strViewer.IsEmpty())//use custom editor + { + wxString strCmdline(strViewer); + + PTCHAR pszCmdLine=strCmdline.GetBuffer(strCmdline.GetLength()); + GetShortPathName(pszCmdLine,pszCmdLine,strCmdline.GetLength()); + strCmdline.ReleaseBuffer(); + + strCmdline+=_TCHAR(' '); + strCmdline+=strFileName; + PROCESS_INFORMATION pi; + STARTUPINFO si; + + si.cb = sizeof(STARTUPINFO); + si.lpReserved = NULL; + si.lpReserved2 = NULL; + si.cbReserved2 = 0; + si.lpDesktop = NULL; + si.dwFlags = 0; + si.lpTitle=NULL; + + if(CreateProcess( + NULL, // app name + //strCmdline.GetBuffer(strCmdline.GetLength()), // command line + strCmdline.GetBuffer(strCmdline.GetLength()), // command line + NULL, // process security + NULL, // thread security + TRUE, // inherit handles + 0, + NULL, // environment + NULL, // current dir + &si, // startup info + &pi)){ + CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); + rc=true; + } else { + MessageBoxF(wxT("Failed to invoke %s.\n"),strCmdline); + } + strCmdline.ReleaseBuffer(); + } else {// Use association + TCHAR szExe[MAX_PATH]; + HINSTANCE h=FindExecutable(strFileName,wxT("."),szExe); + if(int(h)<=32){ + wxString str; + switch(int(h)){ + case 0: str=wxT("The system is out of memory or resources.");break; + case 31: str=wxT("There is no association for the specified file type.");break; + case ERROR_FILE_NOT_FOUND: str=wxT("The specified file was not found.");break; + case ERROR_PATH_NOT_FOUND: str=wxT("The specified path was not found.");break; + case ERROR_BAD_FORMAT: str=wxT("The .EXE file is invalid (non-Win32 .EXE or error in .EXE image).");break; + default: break; + } + MessageBoxF(wxT("Failed to open document %s.\r\n%s"),strFileName,str); + } else { + + SHELLEXECUTEINFO sei = {sizeof(sei), 0, AfxGetMainWnd()->GetSafeHwnd(), wxT("open"), + strFileName, NULL, NULL, SW_SHOWNORMAL, AfxGetInstanceHandle( )}; + + sei.hInstApp=0; + HINSTANCE hInst=ShellExecute(AfxGetMainWnd()->GetSafeHwnd(),wxT("open"), strFileName, NULL, wxT("."), 0)/*ShellExecuteEx(&sei)*/; + if(int(hInst)<=32/*sei.hInstApp==0*/) + { + wxString str; + switch(int(hInst)) + { + case 0 : str=wxT("The operating system is out of memory or resources. ");break; + case ERROR_FILE_NOT_FOUND : str=wxT("The specified file was not found. ");break; + case ERROR_PATH_NOT_FOUND : str=wxT("The specified path was not found. ");break; + case ERROR_BAD_FORMAT : str=wxT("The .EXE file is invalid (non-Win32 .EXE or error in .EXE image). ");break; + case SE_ERR_ACCESSDENIED : str=wxT("The operating system denied access to the specified file. ");break; + case SE_ERR_ASSOCINCOMPLETE : str=wxT("The filename association is incomplete or invalid. ");break; + case SE_ERR_DDEBUSY : str=wxT("The DDE transaction could not be completed because other DDE transactions were being processed. ");break; + case SE_ERR_DDEFAIL : str=wxT("The DDE transaction failed. ");break; + case SE_ERR_DDETIMEOUT : str=wxT("The DDE transaction could not be completed because the request timed out. ");break; + case SE_ERR_DLLNOTFOUND : str=wxT("The specified dynamic-link library was not found. ");break; + //case SE_ERR_FNF : str=wxT("The specified file was not found. ");break; + case SE_ERR_NOASSOC : str=wxT("There is no application associated with the given filename extension. ");break; + case SE_ERR_OOM : str=wxT("There was not enough memory to complete the operation. ");break; + //case SE_ERR_PNF : str=wxT("The specified path was not found. ");break; + case SE_ERR_SHARE : str=wxT("A sharing violation occurred. ");break; + default: str=wxT("An unexpected error occurred");break; + } + MessageBoxF(wxT("Failed to open document %s using %s.\r\n%s"),strFileName,szExe,str); + } else { + rc=true; + } + } + } + return rc; +} + +#endif + +void ecUtils::UnicodeToCStr(const wxChar* str,char *&psz) +{ + int nLength=1 + wxStrlen(str); + psz=new char[nLength]; +#ifdef _UNICODE + WideCharToMultiByte(CP_ACP, 0, str, -1, psz, nLength, NULL, NULL); +#else + strcpy(psz,str); +#endif +} + +std::string ecUtils::UnicodeToStdStr(const wxChar* str) +{ + std::string stdstr; + char *psz; + UnicodeToCStr(str,psz); + stdstr=std::string(psz); + delete psz; + return stdstr; +} + +// ecUtils::StripExtraWhitespace() returns a modified version of +// a string in which each sequence of whitespace characters is +// replaced by a single space + +static bool ecIsSpace(wxChar ch) +{ + return (ch == wxT(' ') || ch == wxT('\r') || ch == wxT('\n') || ch == wxT('\t')); +} + +wxString ecUtils::StripExtraWhitespace (const wxString & strInput) +{ + wxString strOutput; + wxChar* o=strOutput.GetWriteBuf(1+strInput.Len()); + for(const wxChar* c=strInput.GetData();*c;c++){ + if(ecIsSpace(*c)){ + *o++=wxT(' '); + if (ecIsSpace(c[1])){ + for(c=c+2; ecIsSpace(*c);c++); + c--; + } + } else { + *o++=*c; + } + } + *o=0; + strOutput.UngetWriteBuf(); + strOutput.Trim(TRUE); + strOutput.Trim(FALSE); + return strOutput; +#if 0 + wxString strOutput; + LPTSTR o=strOutput.GetBuffer(1+strInput.GetLength()); + for(LPCTSTR c=strInput;*c;c++){ + if(_istspace(*c)){ + *o++=_TCHAR(' '); + if (_istspace(c[1])){ + for(c=c+2;_istspace(*c);c++); + c--; + } + } else { + *o++=*c; + } + } + *o=0; + strOutput.ReleaseBuffer(); + strOutput.TrimLeft(); + strOutput.TrimRight(); + return strOutput; +#endif +} + +#if 0 +ecFileName ecUtils::WPath(const std::string &str) +{ + // Convert a path as read from cdl into host format + // Change / to \ throughout + ecFileName + strPath(str.c_str()); + strPath.Replace (_TCHAR('/'), _TCHAR('\\')); + return strPath; +} + +// Copy file helper function. +// This makes sure the destination file is only touched as necessary. +// It is written using Posix calls lest it should be more broadly applicable. + +bool ecUtils::CopyFile(LPCTSTR pszSource,LPCTSTR pszDest) +{ + // Compare the files. First set rc to the result of the comparison (true if the same) + bool rc=false; + + struct _stat s1,s2; + if(-1!=_tstat(pszSource,&s1) && -1!=_tstat(pszDest,&s2) && s1.st_size==s2.st_size){ + // Files both exist and are of equal size + FILE *f1=_tfopen(pszSource,wxT("rb")); + if(f1){ + FILE *f2=_tfopen(pszDest,wxT("rb")); + if(f2){ + int nSize1,nSize2; + rc=true; + do{ + char buf1[4096],buf2[4096]; + nSize1=fread(buf1,1,sizeof buf1,f1); + nSize2=fread(buf2,1,sizeof buf2,f2); + if(nSize1!=nSize2 || 0!=memcmp(buf1,buf2,nSize1)){ + rc=false; + break; + } + } while (nSize1>0); + fclose(f2); + } + fclose(f1); + } + } + + if(rc){ + // Files are identical + TRACE(wxT("Copy not necessary: '%s' to '%s'\n"),pszSource,pszDest); + } else { + rc=TRUE==::CopyFile(pszSource,pszDest,FALSE); + if(rc){ + TRACE(wxT("Copied '%s' to '%s'\n"),pszSource,pszDest); + } else { + MessageBoxF(wxT("Failed to copy '%s' to '%s' - %s"),pszSource,pszDest,GetLastErrorMessageString()); + } + } + + return rc; +} + +#endif + +/* + * wxStringToStringMap + * + * Stores string values keyed by strings + */ + +void wxStringToStringMap::Set(const wxString& key, const wxString& value) +{ + wxString oldValue; + if (Find(key, oldValue)) + Remove(key); + m_hashTable.Put(key, (wxObject*) new wxString(value)); +} + +bool wxStringToStringMap::Remove(const wxString& key) +{ + wxString* str = (wxString*) m_hashTable.Delete(key); + if (str) + { + delete str; + return TRUE; + } + else + return FALSE; +} + +bool wxStringToStringMap::Find(const wxString& key, wxString& value) +{ + wxString* str = (wxString*) m_hashTable.Get(key); + if (str) + { + value = * str; + return TRUE; + } + else + return FALSE; +} + +void wxStringToStringMap::Clear() +{ + m_hashTable.BeginFind(); + wxNode* node; + while ((node = m_hashTable.Next())) + { + wxString* str = (wxString*) node->Data(); + delete str; + } +} + +void wxStringToStringMap::BeginFind() +{ + m_hashTable.BeginFind(); +} + +bool wxStringToStringMap::Next(wxString& key, wxString& value) +{ + wxNode* node = m_hashTable.Next(); + if (node) + { + value = * (wxString*) node->Data(); + return TRUE; + } + else + return FALSE; +} + +// Is str a member of arr? +bool wxArrayStringIsMember(const wxArrayString& arr, const wxString& str) +{ + size_t i; + for (i = (size_t) 0; i < arr.GetCount(); i++) + if (arr[i] == str) + return TRUE; + + return FALSE; +} + +// Eliminate .. and . +wxString wxGetRealPath(const wxString& path) +{ + wxChar* p = new wxChar[path.Len() + 1]; + wxStrcpy(p, (const wxChar*) path); + wxRealPath(p); + + wxString str(p); + delete[] p; + return str; +} + +// A version of the above but prepending 'cwd' (current path) first +// if 'path' is relative +wxString wxGetRealPath(const wxString& cwd, const wxString& path) +{ + wxString path1(path); + + if (!wxIsAbsolutePath(path)) + { + path1 = cwd; + if (path1.Last() != wxFILE_SEP_PATH) + path1 += wxFILE_SEP_PATH; + path1 += path; + } + + return wxGetRealPath(path1); +} + +// Find the absolute path where this application has been run from. +// argv0 is wxTheApp->argv[0] +// cwd is the current working directory (at startup) +// appVariableName is the name of a variable containing the directory for this app, e.g. +// MYAPPDIR. This is checked first. + +wxString wxFindAppPath(const wxString& argv0, const wxString& cwd, const wxString& appVariableName) +{ + wxString str; + + // Try appVariableName + if (!appVariableName.IsEmpty()) + { + str = wxGetenv(appVariableName); + if (!str.IsEmpty()) + return str; + } + + if (wxIsAbsolutePath(argv0)) + return wxPathOnly(argv0); + else + { + // Is it a relative path? + wxString currentDir(cwd); + if (currentDir.Last() != wxFILE_SEP_PATH) + currentDir += wxFILE_SEP_PATH; + + str = currentDir + argv0; + if (wxFileExists(str)) + return wxPathOnly(str); + } + + // OK, it's neither an absolute path nor a relative path. + // Search PATH. + + wxPathList pathList; + pathList.AddEnvList(wxT("PATH")); + str = pathList.FindAbsoluteValidPath(argv0); + if (!str.IsEmpty()) + return wxPathOnly(str); + + // Failed + return wxEmptyString; +} + +// Make a path name with no separators, out of a full pathname, +// e.g. opt_ecos_ecos-1.4.5 out of /opt/ecos/ecos-1.4.5 +wxString ecMakeNameFromPath(const wxString& path) +{ + wxString p(path); + p.Replace(wxT("/"), wxT("_")); + p.Replace(wxT("\\"), wxT("_")); + p.Replace(wxT(":"), wxT("_")); + return p; +} + + +// Find the text of the list control item at the given column +wxString wxListCtrlGetItemTextColumn(wxListCtrl& listCtrl, long item, int col) +{ + wxListItem listItem; + listItem.m_mask = wxLIST_MASK_TEXT; + listItem.m_itemId = item; + listItem.m_col = col; + + if (listCtrl.GetItem(listItem)) + return listItem.m_text; + else + return wxEmptyString; +} + +// Select the given item +void wxListCtrlSelectItem(wxListCtrl& listCtrl, long sel, bool deselectOthers) +{ + long n = listCtrl.GetItemCount(); + long i; + if (deselectOthers) + { + for (i = 0; i < n; i++) + { + if (listCtrl.GetItemState(i, wxLIST_STATE_SELECTED) & wxLIST_STATE_SELECTED) + { + listCtrl.SetItemState(i, wxLIST_STATE_SELECTED, 0); + } + } + } + listCtrl.SetItemState(sel, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED); +} + +// Find the selection +long wxListCtrlGetSelection(wxListCtrl& listCtrl) +{ + long n = listCtrl.GetItemCount(); + long i; + for (i = 0; i < n; i++) + { + if (listCtrl.GetItemState(i, wxLIST_STATE_SELECTED) & wxLIST_STATE_SELECTED) + { + return i; + } + } + return -1; +} + +// Find which column the cursor is on +int wxListCtrlFindColumn(wxListCtrl& listCtrl, int noCols, int x) +{ + int col = 0; + + // Find which column we're on + int width = 0; + int i; + for (i = 0; i < noCols; i++) + { + width += listCtrl.GetColumnWidth(i); + if (x <= width) + { + col = i; + break; + } + } + return col; +} + +// Utility function +void wxRefreshControls(wxWindow* win) +{ + wxNode *node = win->GetChildren().First(); + while (node) + { + wxWindow* win = (wxWindow*) node->Data(); + win->Refresh(); + node = node->Next(); + } +} + +wxOutputStream& operator <<(wxOutputStream& stream, const wxString& s) +{ + stream.Write(s, s.Length()); + return stream; +} + +wxOutputStream& operator <<(wxOutputStream& stream, long l) +{ + wxString str; + str.Printf("%ld", l); + return stream << str; +} + +wxOutputStream& operator <<(wxOutputStream& stream, const char c) +{ + wxString str; + str.Printf("%c", c); + return stream << str; +} + +/* + * ecDialog + * Supports features we want to have for all dialogs in the application. + * So far, this just allows dialogs to be resizeable under MSW by + * refreshing the controls in OnSize (otherwise there's a mess) + */ + +IMPLEMENT_CLASS(ecDialog, wxDialog) + +BEGIN_EVENT_TABLE(ecDialog, wxDialog) +#ifdef __WXMSW__ + EVT_SIZE(ecDialog::OnSize) +#endif +END_EVENT_TABLE() + +void ecDialog::OnSize(wxSizeEvent& event) +{ + wxDialog::OnSize(event); + + wxRefreshControls(this); +} + +/* + * Implements saving/loading of window settings - fonts only for now + */ + +wxWindowSettingsObject* wxWindowSettings::FindSettings(const wxString& windowName) const +{ + wxNode* node = m_settings.First(); + while (node) + { + wxWindowSettingsObject* obj = (wxWindowSettingsObject*) node->Data(); + if (obj->m_windowName.CmpNoCase(windowName) == 0) + return obj; + node = node->Next(); + } + return NULL; +} + +bool wxWindowSettings::LoadConfig(wxConfigBase& config) +{ + unsigned int i = 0; + for (i = 0; i < GetCount(); i++) + { + wxWindowSettingsObject* obj = GetNth(i); + + wxString name(obj->m_windowName); + name.Replace(wxT(" "), wxT("")); + + LoadFont(config, name, obj->m_font); + } + + return TRUE; +} + +bool wxWindowSettings::SaveConfig(wxConfigBase& config) +{ + unsigned int i = 0; + for (i = 0; i < GetCount(); i++) + { + wxWindowSettingsObject* obj = GetNth(i); + + wxString name(obj->m_windowName); + name.Replace(wxT(" "), wxT("")); + + SaveFont(config, name, obj->m_font); + } + + return TRUE; +} + +// Load and save font descriptions +bool wxWindowSettings::LoadFont(wxConfigBase& config, const wxString& windowName, wxFont& font) +{ + wxString pathBase(wxT("/Fonts/")); + pathBase += windowName; + pathBase += wxT("/"); + + int pointSize, family, style, weight; + bool underlined = FALSE; + wxString faceName; + + if (!config.Read(pathBase + wxT("PointSize"), & pointSize)) + return FALSE; + + if (!config.Read(pathBase + wxT("Family"), & family)) + return FALSE; + + if (!config.Read(pathBase + wxT("Style"), & style)) + return FALSE; + + if (!config.Read(pathBase + wxT("Weight"), & weight)) + return FALSE; + + config.Read(pathBase + wxT("Underlined"), (bool*) & underlined); + config.Read(pathBase + wxT("FaceName"), & faceName); + + wxFont font1(pointSize, family, style, weight, underlined, faceName); + font = font1; + + return TRUE; +} + +bool wxWindowSettings::SaveFont(wxConfigBase& config, const wxString& windowName, const wxFont& font) +{ + if (!font.Ok()) + return FALSE; + + wxString pathBase(wxT("/Fonts/")); + pathBase += windowName; + pathBase += wxT("/"); + + config.Write(pathBase + wxT("PointSize"), (long) font.GetPointSize()); + config.Write(pathBase + wxT("Family"), (long) font.GetFamily()); + config.Write(pathBase + wxT("Style"), (long) font.GetStyle()); + config.Write(pathBase + wxT("Weight"), (long) font.GetWeight()); + config.Write(pathBase + wxT("Underlined"), (long) font.GetUnderlined()); + config.Write(pathBase + wxT("FaceName"), font.GetFaceName()); + + return TRUE; +} + +wxFont wxWindowSettings::GetFont(const wxString& name) const +{ + wxWindowSettingsObject* obj = FindSettings(name); + if (!obj) + return wxFont(); + else + return obj->m_font; +} + +void wxWindowSettings::SetFont(const wxString& name, const wxFont& font) +{ + wxWindowSettingsObject* obj = FindSettings(name); + if (!obj) + { + obj = new wxWindowSettingsObject(name, NULL) ; + obj->m_font = font; + m_settings.Append(obj); + } + obj->m_font = font; +} + +wxWindow* wxWindowSettings::GetWindow(const wxString& name) const +{ + wxWindowSettingsObject* obj = FindSettings(name); + if (!obj) + return NULL; + if (obj->m_arrWindow.GetCount() > 0) + return (wxWindow*) obj->m_arrWindow[0]; + else + return NULL; +} + +void wxWindowSettings::SetWindow(const wxString& name, wxWindow* win) +{ + wxWindowSettingsObject* obj = FindSettings(name); + if (!obj) + { + obj = new wxWindowSettingsObject(name, win) ; + m_settings.Append(obj); + } + obj->m_arrWindow.Clear(); + + if (win) + obj->m_arrWindow.Add(win); +} + +wxArrayPtrVoid* wxWindowSettings::GetWindows(const wxString& name) const +{ + wxWindowSettingsObject* obj = FindSettings(name); + if (!obj) + return NULL; + return & obj->m_arrWindow ; +} + +void wxWindowSettings::SetWindows(const wxString& name, wxArrayPtrVoid& arr) +{ + wxWindowSettingsObject* obj = FindSettings(name); + if (!obj) + { + obj = new wxWindowSettingsObject(name, NULL) ; + m_settings.Append(obj); + } + obj->m_arrWindow.Clear() ; + obj->m_arrWindow = arr; +} + +bool wxWindowSettings::ApplyFontsToWindows() +{ + if (m_useDefaults) + return FALSE; + + unsigned int i = 0; + for (i = 0; i < GetCount(); i++) + { + wxWindowSettingsObject* obj = GetNth(i); + + unsigned int j = 0; + for (j = 0; j < obj->m_arrWindow.GetCount(); j++) + { + wxWindow* win = (wxWindow*) obj->m_arrWindow[j]; + win->SetFont(obj->m_font); + win->Refresh(); + } + } + return TRUE; +} diff --git a/host/tools/configtool/standalone/wxwin/ecutils.h b/host/tools/configtool/standalone/wxwin/ecutils.h new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/ecutils.h @@ -0,0 +1,297 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): sdf +// Contact(s): sdf +// Date: 1998/08/11 +// Version: 0.01 +// Purpose: +// Description: Interface to various global utility functions. Everything in this +// class is static (there are no instances). +// Modified by julians for wxWindows (originally CTUtils.h) +// Requires: +// Provides: +// See also: +// Known bugs: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== + +#ifndef _ECUTILS_H_ +#define _ECUTILS_H_ + +#ifdef __GNUG__ +#pragma interface "ecutils.cpp" +#endif + +#include "wx/hash.h" +#include "wx/confbase.h" +#include "wx/dynarray.h" + +#include "filename.h" +#include "cdl.hxx" + +//#define INCLUDEFILE +//#include "IncludeSTL.h" + +//#include // vsnprintf + +/* + * ecUtils + * This class implements a miscellany of utility functions. + * They are being implemented as and when they are required during Configtool + * development. + */ + +class ecUtils { +public: +#if 0 + static bool Launch (const ecFileName &strFileName,const ecFileName &strViewer); + static wxString GetLastErrorMessageString (); +#endif + + static bool AddToPath (const ecFileName &strFolder, bool bAtFront=true); + +#if 0 + static const wxString LoadString (UINT id); + + // Messagebox functions + + // Vararg message box compositor + static int MessageBoxF (LPCTSTR pszFormat, ...); + // Same, with type + static int MessageBoxFT (UINT nType, LPCTSTR pszFormat, ...); + // As above but with resource + static int MessageBoxFR (UINT nID, UINT nType, LPCTSTR pszFormat, ...); + // Same, with type + static int MessageBoxFR (UINT nID, LPCTSTR pszFormat, ...); + // vararg form + static int vMessageBox(UINT nType, LPCTSTR pszFormat, va_list marker); + +#endif + // String functions + + // Chop the string into pieces using separator cSep. + // The Boolean controls whether " and \ make a difference + static int Chop(const wxString& psz,wxArrayString &ar, wxChar cSep=wxT(' '), + bool bObserveStrings = FALSE, bool bBackslashQuotes = FALSE); + + static int Chop(const wxString& psz,wxArrayString &ar, const wxString& pszSep, + bool bObserveStrings=FALSE, bool bBackslashQuotes = FALSE); + + // String -> Integer, observing the current hex/decimal setting + //static BOOL StrToItemIntegerType(const wxString &str, __int64 &d); + static bool StrToItemIntegerType(const wxString &str, long &d); + static bool StrToDouble (const wxString &strValue, double &dValue); + + // Integer -> String, observing the current hex/decimal setting + static const wxString IntToStr(long d,bool bHex=false); + static const wxString DoubleToStr (double dValue); + static wxString StripExtraWhitespace (const wxString & strInput); + + static void UnicodeToCStr(const wxChar* str,char *&psz); + static std::string UnicodeToStdStr(const wxChar* str); + +#if 0 + // Provide a failure explanation for what just went wrong + static const wxString Explanation (CFileException &exc); + static ecFileName WPath(const std::string &str); + static bool CopyFile (LPCTSTR pszSource,LPCTSTR pszDest); +#endif +}; + +/* + * wxStringToStringMap + * + * Stores string values keyed by strings. + * Note that only one value is allowed per key. + */ + +class wxStringToStringMap: public wxObject +{ +public: + wxStringToStringMap(): m_hashTable(wxKEY_STRING) {} + ~wxStringToStringMap() { Clear(); } + +//// Operations + + // Remove the key/value pair + bool Remove(const wxString& key); + + // Clear the map + void Clear(); + + // Begin a search through the whole map: use Next to find key/value pairs + void BeginFind(); + + // Retrieve the next key/value pair, FALSE indicates end of data + bool Next(wxString& key, wxString& value); + +//// Accessors + + // Replaces the value (if any) associated with the key + void Set(const wxString& key, const wxString& value); + + // Finds a value associated with the key, returns FALSE if none + bool Find(const wxString& key, wxString& value); + +protected: + wxHashTable m_hashTable; +}; + +// Is str a member of arr? +bool wxArrayStringIsMember(const wxArrayString& arr, const wxString& str); + +// Eliminate .. and . +wxString wxGetRealPath(const wxString& path); + +// A version of the above but prepending the cwd (current path) first +// if 'path' is relative +wxString wxGetRealPath(const wxString& cwd, const wxString& path); + +// Find the absolute path where this application has been run from. +// argv0 is wxTheApp->argv[0] +// cwd is the current working directory (at startup) +// appVariableName is the name of a variable containing the directory for this app, e.g. +// MYAPPDIR. This is used as a last resort. Or should it be a first resort? +wxString wxFindAppPath(const wxString& argv0, const wxString& cwd, const wxString& appVariableName = wxEmptyString); + +// Find the text of the list control item at the given column +class WXDLLEXPORT wxListCtrl; +wxString wxListCtrlGetItemTextColumn(wxListCtrl& listCtrl, long item, int col); + +// Select the given item +void wxListCtrlSelectItem(wxListCtrl& listCtrl, long sel, bool deselectOther = TRUE); + +// Find the selection +long wxListCtrlGetSelection(wxListCtrl& listCtrl); + +// Find which column the cursor is on +int wxListCtrlFindColumn(wxListCtrl& listCtrl, int noCols, int x); + +// Refresh children of this window (e.g. on Windows, laying out a window containing +// controls can cause screen corruption) +void wxRefreshControls(wxWindow* win); + +// Make a path name with no separators, out of a full pathname, +// e.g. opt_ecos_ecos-1.4.5 out of /opt/ecos/ecos-1.4.5 +wxString ecMakeNameFromPath(const wxString& path); + +class WXDLLEXPORT wxOutputStream; + +wxOutputStream& operator <<(wxOutputStream&, const wxString& s); +wxOutputStream& operator <<(wxOutputStream&, const char c); +wxOutputStream& operator <<(wxOutputStream&, long l); + +/* + * ecDialog + * Supports features we want to have for all dialogs in the application. + * So far, this just allows dialogs to be resizeable under MSW by + * refreshing the controls in OnSize (otherwise there's a mess) + */ + +class ecDialog: public wxDialog +{ +public: + DECLARE_CLASS(ecDialog) + + ecDialog() {}; + + ecDialog(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos = wxDefaultPosition, + const wxSize& sz = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE) + { + Create(parent, id, title, pos, sz, style); + } +/* + bool Create(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos = wxDefaultPosition, + const wxSize& sz = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE); +*/ + + void OnSize(wxSizeEvent& event); + +DECLARE_EVENT_TABLE() +}; + +/* + * Implements saving/loading of window settings - fonts only for now + */ + +class wxWindowSettingsObject: public wxObject +{ +public: + wxWindowSettingsObject(const wxString& name, wxWindow* win) { m_windowName = name; if (win) m_arrWindow.Add(win); } + wxString m_windowName; + wxFont m_font; + wxArrayPtrVoid m_arrWindow; +}; + +class wxWindowSettings: public wxObject +{ +public: + wxWindowSettings() { m_useDefaults = TRUE; }; + ~wxWindowSettings() { Clear(); } + +//// Operations + wxWindowSettingsObject* FindSettings(const wxString& windowName) const; + void Add(const wxString& name, wxWindow* win = NULL) { m_settings.Append(new wxWindowSettingsObject(name, win)); } + + bool LoadConfig(wxConfigBase& config); + bool SaveConfig(wxConfigBase& config); + + bool LoadFont(wxConfigBase& config, const wxString& windowName, wxFont& font); + bool SaveFont(wxConfigBase& config, const wxString& windowName, const wxFont& font); + + void Clear() { m_settings.DeleteContents(TRUE); m_settings.Clear(); m_settings.DeleteContents(FALSE); } + + bool ApplyFontsToWindows(); + +//// Accessors + wxFont GetFont(const wxString& name) const; + void SetFont(const wxString& name, const wxFont& font); + + wxWindow* GetWindow(const wxString& name) const; + void SetWindow(const wxString& name, wxWindow* win); + + wxArrayPtrVoid* GetWindows(const wxString& name) const; + void SetWindows(const wxString& name, wxArrayPtrVoid& arr); + + int GetCount() const { return m_settings.Number(); } + wxWindowSettingsObject* GetNth(int i) const { return (wxWindowSettingsObject*) m_settings.Nth(i)->Data(); } + wxString GetName(int i) const { return GetNth(i)->m_windowName; } + + void SetUseDefaults(bool useDefaults) { m_useDefaults = useDefaults; } + bool GetUseDefaults() const { return m_useDefaults; } + +public: + wxList m_settings; + bool m_useDefaults; +}; + +#endif +// _ECUTILS_H_ diff --git a/host/tools/configtool/standalone/wxwin/filename.cpp b/host/tools/configtool/standalone/wxwin/filename.cpp new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/filename.cpp @@ -0,0 +1,715 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### + +#ifdef __GNUG__ +#pragma implementation "filename.h" +#endif + +// Includes other headers for precompiled compilation +#include "ecpch.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#include "wx/filefn.h" +#include "wx/confbase.h" // For wxExpandEnvVars + +#include "filename.h" + +#ifdef __WXMSW__ +#include +#include + +#include +#include + +#include "wx/msw/winundef.h" +#ifdef CreateDirectory +#undef CreateDirectory +#endif +#ifdef ExpandEnvironmentStrings +#undef ExpandEnvironmentStrings +#endif +#ifdef GetCurrentDirectory +#undef GetCurrentDirectory +#endif +#ifdef SetCurrentDirectory +#undef SetCurrentDirectory +#endif +#ifdef GetTempPath +#undef GetTempPath +#endif + +#else + +// #include +#endif + +#include + +#define wxTChar wxT + +const wxChar ecFileName::cSep=wxFILE_SEP_PATH; + +ecFileName::ecFileName(const wxChar* psz1,const wxChar* psz2): +wxString(psz1) +{ + Normalize(); + operator+=(psz2); +} + +ecFileName::ecFileName(const wxChar* psz1,const wxChar* psz2,const wxChar* psz3): +wxString(psz1) +{ + Normalize(); + operator+=(psz2); + operator+=(psz3); +} + +ecFileName::ecFileName(const wxChar* psz1,const wxChar* psz2,const wxChar* psz3,const wxChar* psz4): +wxString(psz1) +{ + Normalize(); + operator+=(psz2); + operator+=(psz3); + operator+=(psz4); +} + +ecFileName::ecFileName(const wxChar* psz1,const wxChar* psz2,const wxChar* psz3,const wxChar* psz4,const wxChar* psz5): +wxString(psz1) +{ + operator+=(psz2); + operator+=(psz3); + operator+=(psz4); + operator+=(psz5); +} + +/* +ecFileName::~ecFileName() +{ + // Unfortunately we can't do this since GetStringData is private in wxString. + // So for now, we may memory leaks since ~wxString is not virtual. + //GetStringData()->Unlock(); +} +*/ + +ecFileName operator+(const ecFileName& string1, const ecFileName& string2) +{ + ecFileName s; + s.ConcatCopy(string1, string2); + return s; +} + +ecFileName operator+(const ecFileName& string, const wxChar* lpsz) +{ + if (lpsz == NULL) + return string; + + ecFileName s; + s.ConcatCopy(string, wxString(lpsz)); + return s; +} + +ecFileName operator+(const wxChar* lpsz, const ecFileName& string) +{ + if (lpsz == NULL) + return string; + + ecFileName s; + s.ConcatCopy(wxString(lpsz), string); + return s; +} + +ecFileName operator+(const ecFileName& string1, wxChar ch) +{ + ecFileName s; + s.ConcatCopy(string1, wxString(ch)); + return s; +} + +ecFileName operator+(wxChar ch, const ecFileName& string) +{ + ecFileName s; + s.ConcatCopy(wxString(ch), string); + return s; +} + +const ecFileName& ecFileName::operator+=(const wxChar* lpsz) +{ + if (lpsz == NULL) + return *this; + + ConcatInPlace(wxString(lpsz)); + return *this; +} + +const ecFileName& ecFileName::operator+=(wxChar ch) +{ + ConcatInPlace(wxString(ch)); + return *this; +} + +const ecFileName& ecFileName::operator+=(const ecFileName& string) +{ + ConcatInPlace(string); + return *this; +} + +void ecFileName::ConcatInPlace(const wxString& src) +{ + ConcatCopy(* this, src); +} + +void ecFileName::ConcatCopy(const wxString& src1, + const wxString& src2) +{ + int nSrc1Len = src1.Len(); + int nSrc2Len = src2.Len(); + int n=1; + int nNewLen = nSrc1Len + nSrc2Len; + if(nSrc1Len>0) + { + if(1==nSrc2Len && cSep==src2[0]) + { + // Appending a single separator to a non-null string is a no-op + return; + } else { + // Count the intervening separators + n=(cSep==src1[nSrc1Len-1])+(cSep==src2[0]); + + switch(n){ + case 0: + (*this) = src1 + wxString(cSep) + src2; + break; + case 1: + (*this) = src1 + src2; + break; + case 2: + (*this) = src1 + src2.Mid(1); + break; + } + return; + } + } +} + +void ecFileName::Normalize() +{ + // Remove any trailing seperator + int len = Len(); + if (len > 0 && (*this)[(size_t)(len - 1)] == cSep) + (*this) = Mid(0, len - 1); +} + + +const ecFileName ecFileName::FullName() const +{ +#ifdef __WXMSW__ + TCHAR* pFile; + long dwSize=::GetFullPathName (*this, 0, NULL, &pFile); + if(dwSize>0){ + wxString strCopy; + ::GetFullPathName (*this, 1+dwSize, strCopy.GetWriteBuf(1+dwSize), &pFile); + strCopy.UngetWriteBuf(); + return strCopy; + } else { + return *this; + } +#else + return wxGetCwd() + wxString(cSep) + *this; +#endif +} + +const ecFileName ecFileName::ShortName() const +{ +#ifdef __WXMSW__ + long dwSize=::GetShortPathName (*this, NULL, 0); + if(dwSize>0){ + wxString strCopy; + ::GetShortPathName (*this, strCopy.GetWriteBuf(1+dwSize), 1+dwSize); + strCopy.UngetWriteBuf(); + return strCopy; + } else { + return *this; + } +#else + return *this; +#endif +} + +const ecFileName ecFileName::NoSpaceName() const// sans spaces +{ +#ifndef __WXMSW__ + return *this; +#else + // Only replace components with spaces with FAT names. + wxArrayString ar1,ar2; + const wxString str2(ShortName()); + + size_t i,pcStart; + + unsigned int len = Len(); + pcStart = 0; + for (i = 0; i < len; i++) + { + if(wxTChar('\\')==(*this)[i]) + { + ar1.Add(this->Mid(pcStart, i - pcStart + 1)); + pcStart = i + 1; + } + } + ar1.Add(this->Mid(pcStart, i - pcStart + 1)); + + len = str2.Len(); + pcStart = 0; + for (i = 0; i < len; i++) + { + if(wxTChar('\\')==str2[i]) + { + ar2.Add(str2.Mid(pcStart, i - pcStart + 1)); + pcStart = i + 1; + } + } + ar2.Add(str2.Mid(pcStart, i - pcStart + 1)); + + wxASSERT(ar1.Count()==ar2.Count()); + + wxString rc; + for(i=0;i0 && (cSep==psz[0]))|| // starts with '\' + (nLength>1 && ( + (wxIsalpha(psz[0]) && wxTChar(':')==psz[1]) || // starts with [e.g.] "c:\" + (cSep==psz[0] && cSep==psz[1]))); // UNC +} + +// TODO (?) +#if 0 +// Return an array of filename pieces. Plugs '\0's into 'this', which +// is therefore subsequently only usable as referenced by the returned array. +const wxChar* *ecFileName::Chop() +{ + wxChar *c; + // Count the separators + int nSeps=0; + for(c=_tcschr(m_pchData,cSep);c;c=_tcschr(c+1,cSep)){ + nSeps++; + } + const wxChar* *ar=new const wxChar*[2+nSeps]; // +1 for first, +1 for terminating 0 + ar[0]=m_pchData; + int i=1; + for(c=_tcschr(m_pchData,cSep);c;c=_tcschr(c+1,cSep)){ + ar[i++]=c+1; + *c=wxTChar('\0'); + } + ar[i]=0; + return ar; +} +#endif + +ecFileName ecFileName::GetTempPath() +{ + ecFileName f; +#ifdef __WXMSW__ +#ifdef _UNICODE + ::GetTempPathW(1+_MAX_PATH,f.GetWriteBuf(1+_MAX_PATH)); +#else + ::GetTempPathA(1+_MAX_PATH,f.GetWriteBuf(1+_MAX_PATH)); +#endif + f.UngetWriteBuf(); +#elif defined(__WXGTK__) +#else + wxFAIL("ecFileName::GetTempPath() not implemented on this platform."); +#endif + f.Normalize(); + return f; +} + +const ecFileName ecFileName::CygPath () const +{ +#ifdef __WXMSW__ + ecFileName rc = ShortName(); + if(wxIsalpha(rc[(size_t)0]) && wxTChar(':')==rc[(size_t)1]) + { + // Convert c:\ to //c/ + wxString s = wxString(wxT("//")) + wxString(rc[(size_t)0]) + rc.Mid(2); + rc = s; + } + size_t i; + for (i = 0; i < rc.Len(); i++) + { + if (rc[i] == wxTChar('\\')) + rc[i] = wxTChar('/'); + } +#else + const ecFileName& rc = * this; +#endif + + return rc; +} + +bool ecFileName::CreateDirectory(bool bParentsToo,bool bFailIfAlreadyExists) const +{ + if(bParentsToo) + { + // Create intermediate directories + + // 'rest' will progressively have its separators replaced by underscores in order + // to find the next separator + wxString rest = * this; + size_t lastPos = 0; + int len = rest.Len(); + while (lastPos != -1) + { + lastPos = rest.Find(cSep); + if (lastPos != -1 && lastPos >= 0) + { + rest[lastPos] = wxT('_'); // So we find the NEXT separator + + // don't attempt to create "C: or /" + if (lastPos > 0 && (*this)[lastPos-1] == wxT(':')) + continue; + else if (lastPos == 0) + continue; + } + + // Fail if any of the dirs exist already + wxString str(this->Mid(0, lastPos)); + bool alreadyExists = wxDirExists(str); + if (alreadyExists && bFailIfAlreadyExists) + return FALSE; + + if (!alreadyExists) + if (!wxMkdir(str)) + return FALSE; + } + } + + + return IsDir()? (!bFailIfAlreadyExists) : (TRUE==wxMkdir(*this)); +} + + +const wxString ecFileName::Extension() const +{ + wxString path, name, ext; + + wxSplitPath(*this, & path, & name, & ext); + return ext; +} + +const wxString ecFileName::Root() const +{ + return wxPathOnly(*this); +} + +ecFileName ecFileName::SetCurrentDirectory(const wxChar* pszDir) +{ + const ecFileName strPwd=wxGetCwd(); + if (::wxSetWorkingDirectory(pszDir)) + return strPwd; + else + return wxT(""); +} + +bool ecFileName::RecursivelyDelete() +{ + wxArrayString ar; + int i; + for(i=FindFiles(*this,ar)-1;i>=0;--i){ + wxRemoveFile(ar[i]); + } + for(i=FindFiles(*this,ar,wxT("*.*"),TRUE,0)-1;i>=0;--i){ + wxRmdir(ar[i]); + } + return TRUE==wxRmdir(*this); +} + +// TODO: take account of dwExclude +int ecFileName::FindFiles (const wxString& pszDir,wxArrayString &ar,const wxString& pszPattern/*=wxT("*.*")*/,bool bRecurse/*=TRUE*/,long dwExclude/*=wxDIR_DIRS|wxDIR_HIDDEN*/) +{ + ar.Clear(); + + // Scoping for wxDir + { + wxDir dir(pszDir); + + wxString fileName; + bool bMore = dir.GetFirst(& fileName, pszPattern, wxDIR_FILES); + while (bMore) + { + if (fileName != wxT(".") && fileName != wxT("..")) + { + // Add full path + ecFileName path(pszDir); + path += (const wxChar*) fileName; + ar.Add(path); + } + bMore = dir.GetNext(& fileName); + } + } + + if (bRecurse) + { + // Since wxDir isn't rentrant, we need to gather all the directories + // first + wxArrayString ar2; + + // Scoping + { + wxDir dir(pszDir); + + wxString fileName; + + bool bMore = dir.GetFirst(& fileName, wxT("*"), wxDIR_DIRS); + while (bMore) + { + if (fileName != wxT(".") && fileName != wxT("..")) + { + // Add full path + ecFileName path(pszDir); + path += (const wxChar*) fileName; + ar2.Add(path); + } + bMore = dir.GetNext(& fileName); + } + } + + unsigned int i; + for (i = 0; i < ar2.Count(); i++) + { + wxString f(ar2[i]); + FindFiles(f, ar, pszPattern, bRecurse, dwExclude); + } + } + + return ar.Count(); +} + +void ecFileName::ReplaceExtension(const wxString& newExt) +{ + wxString ext = newExt; + if (ext[0] == wxT('.')) + ext = ext.Mid(1); + + wxStripExtension(* this); + this->wxString::Append(wxT(".")); + this->wxString::Append(ext); +} diff --git a/host/tools/configtool/standalone/wxwin/filename.h b/host/tools/configtool/standalone/wxwin/filename.h new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/filename.h @@ -0,0 +1,183 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): sdf +// Contact(s): sdf +// Date: 1998/09/11 +// Version: 0.01 +// Purpose: Class to encapsulate filename operations (i.e. broadly on a file which probably do not involve opening +// it). Importantly, the + and += operators performs filename segment addition, making sure that only one '\\' +// comes between each piece. +// Translated to wxWindows conventions by julians (in progress) +// Description: Interface of the filename class +// Requires: +// Provides: +// See also: +// Known bugs: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== + +#ifndef _WX_FILENAME_H_ +#define _WX_FILENAME_H_ + +#include "wx/wxchar.h" +#include "wx/dir.h" + +/* + * ecFileName + * + * This class extends wxString with functionality related + * to filenames. + */ + +class ecFileName : public wxString { +public: + void ReplaceExtension (const wxString& newExt); + + // previous directory is returned: + static ecFileName SetCurrentDirectory (const wxChar* pszDir); + const wxString Root() const; + const wxString Extension() const; + static ecFileName GetTempPath(); + bool IsAbsolute() const; + + static const wxChar cSep; // The path separator ('\' on windows) + + // Standard ctors + ecFileName():wxString(){} + ecFileName(const ecFileName& stringSrc):wxString(stringSrc){Normalize();} + ecFileName(const wxString& stringSrc):wxString(stringSrc){Normalize();} + ecFileName(wxChar ch, int nRepeat = 1):wxString(ch,nRepeat){Normalize();} + + ecFileName(/*LPCSTR*/ const wxChar* lpsz):wxString(lpsz){Normalize();} + + /* TODO + ecFileName(LPCWSTR lpsz):wxString(lpsz){Normalize();} + */ + + ecFileName(/*LPCSTR*/ const wxChar* lpch, int nLength):wxString(lpch,nLength){Normalize();} + + /* TODO + ecFileName(LPCWSTR lpch, int nLength):wxString(lpch,nLength){Normalize();} + */ + ecFileName(const unsigned char* psz):wxString(psz){Normalize();} + + // Construct from path fragments + ecFileName(const wxChar*,const wxChar*); + ecFileName(const wxChar*,const wxChar*,const wxChar*); + ecFileName(const wxChar*,const wxChar*,const wxChar*,const wxChar*); + ecFileName(const wxChar*,const wxChar*,const wxChar*,const wxChar*,const wxChar*); + + //~ecFileName(); + + // catenation operators: exactly one separator is placed between L and R + const ecFileName& operator+=(const ecFileName& string); + const ecFileName& operator+=(wxChar ch); +#ifdef _UNICODE + const ecFileName& operator+=(char ch); +#endif + const ecFileName& operator+=(const wxChar* lpsz); + friend ecFileName operator+(const ecFileName& string1,const ecFileName& string2); + friend ecFileName operator+(const ecFileName& string, wxChar ch); + friend ecFileName operator+(wxChar ch, const ecFileName& string); +#ifdef _UNICODE + friend ecFileName operator+(const ecFileName& string, char ch); + friend ecFileName operator+(char ch, const ecFileName& string); +#endif + friend ecFileName operator+(const ecFileName& string, const wxChar* lpsz); + friend ecFileName operator+(const wxChar* lpsz, const ecFileName& string); + + // Textual append - no separator functionality + const ecFileName& Append (wxChar ch); + const ecFileName& Append (const wxChar* psz); + + // Utility functions + const ecFileName FullName() const; // full path name + const ecFileName NoSpaceName() const;// sans spaces + const ecFileName ShortName() const; // the type with ~s in it + const ecFileName Tail() const; // file name sans directory part + const ecFileName Head() const; // directory part + const ecFileName CygPath() const; // path mangled for CygWin + + static ecFileName GetCurrentDirectory(); + const ecFileName& ExpandEnvironmentStrings(); + static ecFileName ExpandEnvironmentStrings(const wxChar* psz); + + // Form path name relative to given parameter (if NULL, current directory) + const ecFileName& MakeRelative(const wxChar* pszRelativeTo=0); + static ecFileName Relative(const wxChar* psz,const wxChar* pszRelativeTo=0); + + bool SameFile (const ecFileName &strOther) const; + + /* TODO + bool SetFileAttributes (long dwFileAttributes) const; + + long Attributes() const { return ::GetFileAttributes(*this); } + */ + + bool Exists () const ; + bool IsDir () const ; + bool IsFile () const ; + bool IsReadOnly () const ; + + time_t LastModificationTime() const; + + bool RecursivelyDelete(); + + bool CreateDirectory (bool bParentsToo=true,bool bFailIfAlreadyExists=false) const; + + static int FindFiles (const wxString& pszDir,wxArrayString &ar,const wxString& pszPattern=wxT("*.*"),bool bRecurse=TRUE,long dwExclude=wxDIR_DIRS|wxDIR_HIDDEN); + +protected: + + /* Don't appear to be necessary + // Helpers for Relative(): + const wxChar* *Chop (); + static ecFileName Drive(const wxChar* psz); + */ + + // Remove trailing '/' (helper for ctors) + void Normalize(); + + // Implementating catenation functionality: + void ConcatInPlace(const wxString& src); + void ConcatCopy(const wxString& src1, const wxString& src2); +}; + +class wxSaveExcursion { + const ecFileName m_strPrevDir; +public: + wxSaveExcursion(const wxChar* pszDir) : m_strPrevDir(ecFileName::SetCurrentDirectory(pszDir)) {} + ~wxSaveExcursion() { ecFileName::SetCurrentDirectory(m_strPrevDir); } + bool Ok() const { return !m_strPrevDir.IsEmpty(); } +}; + +#endif +// _WX_FILENAME_H_ diff --git a/host/tools/configtool/standalone/wxwin/finddlg.cpp b/host/tools/configtool/standalone/wxwin/finddlg.cpp new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/finddlg.cpp @@ -0,0 +1,265 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +// appsettings.cpp : +// +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): julians +// Contact(s): julians +// Date: 2000/09/11 +// Version: $Id: finddlg.cpp,v 1.3 2001/03/07 18:21:50 julians Exp $ +// Purpose: +// Description: Implementation file for ecFindDialog +// Requires: +// Provides: +// See also: +// Known bugs: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== + +#ifdef __GNUG__ + #pragma implementation "finddlg.cpp" +#endif + +#include "ecpch.h" + +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + +#include "wx/cshelp.h" +#include "wx/valgen.h" + +#include "finddlg.h" +#include "configtool.h" +#include "configtooldoc.h" +#include "configtoolview.h" +#include "configtree.h" +#include "mainwin.h" +#include "appsettings.h" + +//---------------------------------------------------------------------------- +// ecFindDialog +//---------------------------------------------------------------------------- + +BEGIN_EVENT_TABLE(ecFindDialog,wxDialog) + EVT_BUTTON(ecID_FIND_DIALOG_NEXT, ecFindDialog::OnFindNext) + EVT_CLOSE(ecFindDialog::OnCloseWindow) + EVT_BUTTON(wxID_CANCEL, ecFindDialog::OnCancel) +END_EVENT_TABLE() + +ecFindDialog::ecFindDialog( wxWindow *parent, wxWindowID id, const wxString &title, + const wxPoint &position, const wxSize& size, long style ) : + wxDialog( ) +{ + m_directionSelection = 1; + + SetExtraStyle(wxDIALOG_EX_CONTEXTHELP); + + wxDialog::Create( parent, id, title, position, size, style ); + + AddControls(this); + + if (wxGetApp().GetSettings().m_findDialogPos.x == -1 && wxGetApp().GetSettings().m_findDialogPos.y == -1) + Centre(wxBOTH); + else + Move(wxGetApp().GetSettings().m_findDialogPos); +} + +bool ecFindDialog::AddControls(wxWindow* parent) +{ + //// Start of sizer-based control creation + + wxSizer *item0 = new wxBoxSizer( wxHORIZONTAL ); + + wxSizer *item1 = new wxBoxSizer( wxVERTICAL ); + + wxSizer *item2 = new wxBoxSizer( wxHORIZONTAL ); + + wxStaticText *item3 = new wxStaticText( parent, wxID_STATIC, _(" Fi&nd what:"), wxDefaultPosition, wxDefaultSize, 0 ); + item2->Add( item3, 0, wxALIGN_CENTRE|wxLEFT|wxTOP|wxBOTTOM, 5 ); + + wxTextCtrl *item4 = new wxTextCtrl( parent, ecID_FIND_DIALOG_WHAT, _(""), wxDefaultPosition, wxSize(200,-1), 0 ); + item2->Add( item4, 1, wxALIGN_CENTRE|wxALL, 5 ); + + item1->Add( item2, 1, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 0 ); + + wxSizer *item5 = new wxBoxSizer( wxHORIZONTAL ); + + wxSizer *item6 = new wxBoxSizer( wxVERTICAL ); + + wxCheckBox *item7 = new wxCheckBox( parent, ecID_FIND_DIALOG_MATCH_WHOLE, _("Match &whole word only"), wxDefaultPosition, wxDefaultSize, 0 ); + item6->Add( item7, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + wxCheckBox *item8 = new wxCheckBox( parent, ecID_FIND_DIALOG_MATCH_CASE, _("Match &case"), wxDefaultPosition, wxDefaultSize, 0 ); + item6->Add( item8, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + item5->Add( item6, 0, wxALIGN_CENTRE|wxALL, 5 ); + + wxString strs9[] = + { + _("&Up"), + _("&Down") + }; + wxRadioBox *item9 = new wxRadioBox( parent, ecID_FIND_DIALOG_DIRECTION, _("Direction"), wxDefaultPosition, wxDefaultSize, 2, strs9, 1, wxRA_SPECIFY_ROWS ); + item5->Add( item9, 0, wxALIGN_CENTRE|wxALL, 5 ); + + item1->Add( item5, 0, wxALIGN_CENTRE|wxRIGHT, 5 ); + + wxSizer *item10 = new wxBoxSizer( wxHORIZONTAL ); + + wxStaticText *item11 = new wxStaticText( parent, wxID_STATIC, _("&Search in:"), wxDefaultPosition, wxDefaultSize, 0 ); + item10->Add( item11, 0, wxALIGN_CENTRE|wxALL, 5 ); + + wxString strs12[] = + { + _("Macro names"), + _("Item names"), + _("Short descriptions"), + _("Current Values"), + _("Default Values") + }; + wxChoice *item12 = new wxChoice( parent, ecID_FIND_DIALOG_SEARCH_IN, wxDefaultPosition, wxSize(130,-1), 5, strs12, 0 ); + item10->Add( item12, 0, wxALIGN_CENTRE|wxALL, 5 ); + + item1->Add( item10, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 5 ); + + item0->Add( item1, 0, wxALIGN_CENTRE|wxTOP|wxBOTTOM, 5 ); + + wxSizer *item13 = new wxBoxSizer( wxVERTICAL ); + + wxButton *item14 = new wxButton( parent, ecID_FIND_DIALOG_NEXT, _("&Find Next"), wxDefaultPosition, wxDefaultSize, 0 ); + item14->SetDefault(); + item13->Add( item14, 0, wxALIGN_CENTRE|wxALL, 5 ); + + wxButton *item15 = new wxButton( parent, wxID_CANCEL, _("&Close"), wxDefaultPosition, wxDefaultSize, 0 ); + item13->Add( item15, 0, wxALIGN_CENTRE|wxALL, 5 ); + +#ifdef __WXGTK__ + wxButton *contextButton = new wxContextHelpButton( parent ); + item13->Add( contextButton, 0, wxALIGN_CENTRE|wxALL, 5 ); +#endif + + item0->Add( item13, 0, wxALIGN_CENTER_HORIZONTAL|wxRIGHT|wxTOP|wxBOTTOM, 5 ); + + FindWindow(ecID_FIND_DIALOG_WHAT)->SetFocus(); + + // Add validators + FindWindow(ecID_FIND_DIALOG_WHAT)->SetValidator(wxGenericValidator(& wxGetApp().GetSettings().m_findText)); + FindWindow(ecID_FIND_DIALOG_MATCH_WHOLE)->SetValidator(wxGenericValidator(& wxGetApp().GetSettings().m_findMatchWholeWord)); + FindWindow(ecID_FIND_DIALOG_MATCH_CASE)->SetValidator(wxGenericValidator(& wxGetApp().GetSettings().m_findMatchCase)); + FindWindow(ecID_FIND_DIALOG_SEARCH_IN)->SetValidator(wxGenericValidator(& wxGetApp().GetSettings().m_findSearchWhat)); + FindWindow(ecID_FIND_DIALOG_DIRECTION)->SetValidator(wxGenericValidator(& m_directionSelection)); + + // Add help text + FindWindow(ecID_FIND_DIALOG_WHAT)->SetHelpText(_("Enter your search text here.")); + FindWindow(ecID_FIND_DIALOG_MATCH_WHOLE)->SetHelpText(_("Check to match whole words, clear to match parts of words.")); + FindWindow(ecID_FIND_DIALOG_MATCH_CASE)->SetHelpText(_("Check if you want upper and lower case to be significant, clear otherwise.")); + FindWindow(ecID_FIND_DIALOG_SEARCH_IN)->SetHelpText(_("Choose the category for your search.")); + FindWindow(ecID_FIND_DIALOG_DIRECTION)->SetHelpText(_("Choose the direction of your search.")); + FindWindow(ecID_FIND_DIALOG_NEXT)->SetHelpText(_("Click Find Next to search for the next match.")); + FindWindow(wxID_CANCEL)->SetHelpText(_("Click Close to close the dialog.")); + + parent->SetAutoLayout( TRUE ); + parent->SetSizer( item0 ); + parent->Layout(); + item0->Fit( parent ); + item0->SetSizeHints( parent ); + return TRUE; +} + +bool ecFindDialog::TransferDataToWindow() +{ + // Convert to radiobox selection index from bool + m_directionSelection = wxGetApp().GetSettings().m_findDirection ? 1 : 0 ; + + wxPanel::TransferDataToWindow(); + + return TRUE; +} + +bool ecFindDialog::TransferDataFromWindow() +{ + wxPanel::TransferDataFromWindow(); + + // Convert from radiobox selection index to bool + wxGetApp().GetSettings().m_findDirection = (m_directionSelection == 1); + + return TRUE; +} + +void ecFindDialog::OnFindNext(wxCommandEvent& event) +{ + if (!TransferDataFromWindow()) + return; + if (!wxGetApp().GetConfigToolDoc()) + return; + + ecConfigToolView *pControlView = (ecConfigToolView*) wxGetApp().GetConfigToolDoc()->GetFirstView(); + + ecConfigItem* item = pControlView->DoFind(wxGetApp().GetSettings().m_findText, this); + + if (item) + { + // Is the find window on top of the item? + wxRect rect1, rect2; + + if (wxGetApp().GetTreeCtrl()->GetBoundingRect(item->GetTreeItem(), rect1)) + { + wxPoint topLeft(rect1.x, rect1.y); + wxPoint bottomRight(rect1.GetRight(), rect1.GetBottom()); + + topLeft = wxGetApp().GetTreeCtrl()->ClientToScreen(topLeft); + bottomRight = wxGetApp().GetTreeCtrl()->ClientToScreen(bottomRight); + + rect2 = GetRect(); // screen coords + + if (rect2.Inside(topLeft) || rect2.Inside(bottomRight)) + { + Move(wxPoint(topLeft.x + rect1.width, rect2.y)); + } + } + } +} + +void ecFindDialog::OnCloseWindow(wxCloseEvent& event) +{ + wxGetApp().GetSettings().m_findDialogPos = GetPosition(); + wxGetApp().GetMainFrame()->m_findDialog = NULL; + + event.Skip(); +} + +void ecFindDialog::OnCancel(wxCommandEvent& event) +{ + wxGetApp().GetSettings().m_findDialogPos = GetPosition(); + wxGetApp().GetMainFrame()->m_findDialog = NULL; + + event.Skip(); +} \ No newline at end of file diff --git a/host/tools/configtool/standalone/wxwin/finddlg.h b/host/tools/configtool/standalone/wxwin/finddlg.h new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/finddlg.h @@ -0,0 +1,92 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +// appsettings.cpp : +// +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): julians +// Contact(s): julians +// Date: 2000/09/11 +// Version: $Id: finddlg.h,v 1.2 2001/03/07 17:08:33 julians Exp $ +// Purpose: +// Description: Header file for ecFindDialog +// Requires: +// Provides: +// See also: +// Known bugs: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== + +#ifndef _ECOS_FINDDLG_H_ +#define _ECOS_FINDDLG_H_ + +#ifdef __GNUG__ + #pragma interface "finddlg.cpp" +#endif + +//---------------------------------------------------------------------------- +// ecFindDialog +//---------------------------------------------------------------------------- + +class ecFindDialog: public wxDialog +{ +public: + // constructors and destructors + ecFindDialog( wxWindow *parent, wxWindowID id, const wxString &title, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = wxDEFAULT_DIALOG_STYLE ); + +//// Operations + bool AddControls(wxWindow* parent); + + virtual bool TransferDataToWindow(); + virtual bool TransferDataFromWindow(); + +//// Event handlers + void OnFindNext(wxCommandEvent& event); + void OnCancel(wxCommandEvent& event); + void OnCloseWindow(wxCloseEvent& event); + +private: + // Radiobox selection, used by validator + int m_directionSelection; + + DECLARE_EVENT_TABLE() +}; + +#define ecID_FIND_DIALOG_WHAT 10002 +#define ecID_FIND_DIALOG_MATCH_WHOLE 10003 +#define ecID_FIND_DIALOG_MATCH_CASE 10004 +#define ecID_FIND_DIALOG_DIRECTION 10005 +#define ecID_FIND_DIALOG_SEARCH_IN 10006 +#define ecID_FIND_DIALOG_NEXT 10007 + +#endif + // _ECOS_FINDDLG_H_ diff --git a/host/tools/configtool/standalone/wxwin/folderdlg.cpp b/host/tools/configtool/standalone/wxwin/folderdlg.cpp new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/folderdlg.cpp @@ -0,0 +1,188 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +// folderdlg.cpp : +// +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): julians +// Contact(s): julians +// Date: 2000/12/20 +// Version: $Id: folderdlg.cpp,v 1.2 2001/03/23 13:38:04 julians Exp $ +// Purpose: +// Description: Implementation of ecFolderDialog +// Requires: +// Provides: +// See also: +// Known bugs: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== + +#ifdef __GNUG__ + #pragma implementation "folderdlg.cpp" +#endif + +#include "ecpch.h" + +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + +#include "configtool.h" +#include "folderdlg.h" + +//---------------------------------------------------------------------------- +// ecFolderDialog +//---------------------------------------------------------------------------- + +BEGIN_EVENT_TABLE(ecFolderDialog, ecDialog) + EVT_BUTTON( wxID_OK, ecFolderDialog::OnOK ) + EVT_BUTTON( wxID_CANCEL, ecFolderDialog::OnCancel ) + EVT_BUTTON( ecID_FOLDER_DIALOG_BROWSE, ecFolderDialog::OnBrowse ) + EVT_INIT_DIALOG(ecFolderDialog::OnInitDialog) +END_EVENT_TABLE() + +ecFolderDialog::ecFolderDialog( const wxString& defaultPath, const wxArrayString& paths, + const wxString& msg, wxWindow *parent, wxWindowID id, const wxString &title, + const wxPoint &position, const wxSize& size, long style ) +{ + SetExtraStyle(wxDIALOG_EX_CONTEXTHELP); + + m_defaultPath = defaultPath; + m_paths = paths; + m_message = msg; + + wxDialog::Create( parent, id, title, position, size, style ); + + CreateControls(); + + Centre(wxBOTH); +} + +void ecFolderDialog::OnInitDialog(wxInitDialogEvent& event) +{ + wxComboBox* comboBox = (wxComboBox*) FindWindow(ecID_FOLDER_DIALOG_PATHS); + + wxASSERT (comboBox != NULL) ; + + size_t i; + for (i = (size_t) 0; i < m_paths.GetCount(); i++) + { + comboBox->Append(m_paths[i]); + if (m_paths[i] == m_defaultPath) + comboBox->SetSelection(i); + } + if (comboBox->FindString(m_defaultPath) == -1) + comboBox->Append(m_defaultPath); + + if (comboBox->GetSelection() == -1 && comboBox->Number() > 0) + comboBox->SetSelection(0); + + comboBox->SetFocus(); + + wxStaticText* staticText = (wxStaticText*) FindWindow(ecID_FOLDER_DIALOG_MSG); + + wxASSERT ( staticText != NULL ); + + staticText->SetLabel(m_message); +} + +void ecFolderDialog::OnOK(wxCommandEvent &event) +{ + wxComboBox* comboBox = (wxComboBox*) FindWindow(ecID_FOLDER_DIALOG_PATHS); + m_defaultPath = comboBox->GetValue(); + + event.Skip(); +} + +void ecFolderDialog::OnCancel(wxCommandEvent &event) +{ + event.Skip(); +} + +void ecFolderDialog::OnBrowse(wxCommandEvent &event) +{ + wxComboBox* comboBox = (wxComboBox*) FindWindow(ecID_FOLDER_DIALOG_PATHS); + + wxString value = comboBox->GetValue(); + + wxDirDialog dirDialog(this, wxT("Choose a directory"), value); + if (dirDialog.ShowModal() == wxID_OK) + { + comboBox->SetValue(dirDialog.GetPath()); + } +} + +void ecFolderDialog::CreateControls() +{ + wxWindow* parent = this; + + wxSizer *item0 = new wxBoxSizer( wxVERTICAL ); + + wxSizer *item1 = new wxBoxSizer( wxHORIZONTAL ); + + wxStaticText *item2 = new wxStaticText( parent, ecID_FOLDER_DIALOG_MSG, _("text"), wxDefaultPosition, wxSize(-1,70), wxST_NO_AUTORESIZE ); + item1->Add( item2, 10, wxALIGN_CENTER_HORIZONTAL|wxALL, 10 ); + + wxSizer *item3 = new wxBoxSizer( wxVERTICAL ); + + wxButton *item4 = new wxButton( parent, wxID_OK, _("&OK"), wxDefaultPosition, wxDefaultSize, 0 ); + item4->SetDefault(); + item3->Add( item4, 0, wxALIGN_CENTRE|wxALL, 5 ); + + wxButton *item5 = new wxButton( parent, wxID_CANCEL, _("&Cancel"), wxDefaultPosition, wxDefaultSize, 0 ); + item3->Add( item5, 0, wxALIGN_CENTRE|wxALL, 5 ); + + wxButton *item6 = new wxButton( parent, ecID_FOLDER_DIALOG_BROWSE, _("&Browse..."), wxDefaultPosition, wxDefaultSize, 0 ); + item3->Add( item6, 0, wxALIGN_CENTRE|wxALL, 5 ); + + item1->Add( item3, 0, wxALIGN_CENTRE|wxALL, 5 ); + + item0->Add( item1, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + wxString *strs7 = (wxString*) NULL; + wxComboBox *item7 = new wxComboBox( parent, ecID_FOLDER_DIALOG_PATHS, "", wxDefaultPosition, wxSize(470,-1), 0, strs7, wxCB_DROPDOWN ); + item0->Add( item7, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + parent->SetAutoLayout( TRUE ); + parent->SetSizer( item0 ); + parent->Layout(); + item0->Fit( parent ); + item0->SetSizeHints( parent ); + + // Add validators + //parent->FindWindow( ecID_LICENSE_TEXT )->SetValidator(wxGenericValidator(& m_licenseText)); + + // Add context-sensitive help text + parent->FindWindow( wxID_OK )->SetHelpText(_("Confirms your folder selection.")); + parent->FindWindow( wxID_CANCEL )->SetHelpText(_("Cancels the operation.")); + +#if __WXGTK__ + //parent->FindWindow( wxID_CONTEXT_HELP )->SetHelpText(_("Invokes context-sensitive help for the clicked-on window.")); +#endif +} diff --git a/host/tools/configtool/standalone/wxwin/folderdlg.h b/host/tools/configtool/standalone/wxwin/folderdlg.h new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/folderdlg.h @@ -0,0 +1,95 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +// folderdlg.h : +// +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): julians +// Contact(s): julians +// Date: 2000/12/20 +// Version: $Id: folderdlg.h,v 1.2 2001/03/23 13:38:04 julians Exp $ +// Purpose: +// Description: Header for ecFolderDialog +// Requires: +// Provides: +// See also: +// Known bugs: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== + +#ifndef _ECOS_FOLDERDLG_H_ +#define _ECOS_FOLDERDLG_H_ + +#ifdef __GNUG__ + #pragma interface "folderdlg.cpp" +#endif + +#ifndef WX_PRECOMP + #include "wx/wx.h" +#endif + +#include "ecutils.h" + +//---------------------------------------------------------------------------- +// ecFolderDialog +//---------------------------------------------------------------------------- + +class ecFolderDialog: public ecDialog +{ +public: + // constructors and destructors + ecFolderDialog( const wxString& defaultPath, const wxArrayString& paths, + const wxString& msg, wxWindow *parent, wxWindowID id, const wxString &title, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); + +/// Operations + void CreateControls(); + +//// Event handlers + void OnOK( wxCommandEvent &event ); + void OnCancel( wxCommandEvent& event ); + void OnBrowse( wxCommandEvent& event); + void OnInitDialog(wxInitDialogEvent& event); + +//// Accessors + wxString GetPath() const { return m_defaultPath; } + +private: + wxString m_defaultPath; + wxArrayString m_paths; + wxString m_message; + + DECLARE_EVENT_TABLE() +}; + + +#endif + // _ECOS_FOLDERDLG_H_ diff --git a/host/tools/configtool/standalone/wxwin/htmlparser.cpp b/host/tools/configtool/standalone/wxwin/htmlparser.cpp new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/htmlparser.cpp @@ -0,0 +1,807 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +// htmlparser.cpp : +// +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): julians +// Contact(s): julians +// Date: 2001/04/04 +// Version: $Id: htmlparser.cpp,v 1.6 2001/04/12 10:02:22 julians Exp $ +// Purpose: +// Description: HTML parser/HTML Help file generator +// Requires: +// Provides: +// See also: +// Known bugs: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== + +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- +#ifdef __GNUG__ +#pragma implementation "htmlparser.h" +#endif + +// Includes other headers for precompiled compilation +#include "ecpch.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#include "wx/textfile.h" +#include "wx/wfstream.h" + +#include "ecutils.h" +#include "htmlparser.h" + +/* + * wxSimpleHtmlAttribute + * Representation of an attribute + */ + +wxSimpleHtmlParser::wxSimpleHtmlParser() +{ + m_topLevel = NULL; + m_pos = 0; +} + + +wxSimpleHtmlParser::~wxSimpleHtmlParser() +{ + Clear(); +} + +bool wxSimpleHtmlParser::ParseFile(const wxString& filename) +{ + wxTextFile textFile; + + if (textFile.Open(filename)) + { + wxString text; + wxString line; + int i; + int count = textFile.GetLineCount(); + for (i = 0; i < count; i++) + { + if (i == 0) + line = textFile.GetFirstLine(); + else + line = textFile.GetNextLine(); + + text += line; + if (i != (count - 1)) + text += wxT("\n"); + } + +#if 0 + for ( line = textFile.GetFirstLine(); !textFile.Eof(); line = textFile.GetNextLine() ) + { + text += line; + if (!textFile.Eof()) + text += wxT("\n"); + } +#endif + + return ParseString(text); + } + else + return FALSE; +} + +bool wxSimpleHtmlParser::ParseString(const wxString& str) +{ + Clear(); + + m_pos = 0; + m_text = str; + m_length = str.Length(); + + m_topLevel = new wxSimpleHtmlTag(wxT("TOPLEVEL"), wxSimpleHtmlTag_TopLevel); + + return ParseHtml(m_topLevel); +} + +// Main recursive parsing function +bool wxSimpleHtmlParser::ParseHtml(wxSimpleHtmlTag* parent) +{ + while (!Eof()) + { + EatWhitespace(); + if (IsComment()) + { + ParseComment(); + } + else if (IsDirective()) + { + wxSimpleHtmlTag* tag = ParseDirective(); + if (tag) + parent->AppendTag(tag); + } + else if (IsTagClose()) + { + wxSimpleHtmlTag* tag = ParseTagClose(); + if (tag) + parent->AppendTag(tag); + } + else if (IsTagStartBracket(GetChar(m_pos))) + { + wxSimpleHtmlTag* tag = ParseTagHeader(); + if (tag) + parent->AppendTag(tag); + } + else + { + // Just a text string + wxString text; + ParseText(text); + + wxSimpleHtmlTag* tag = new wxSimpleHtmlTag(wxT("TEXT"), wxSimpleHtmlTag_Text); + tag->SetText(text); + parent->AppendTag(tag); + } + } + return TRUE; +} + +// Plain text, up until an angled bracket +bool wxSimpleHtmlParser::ParseText(wxString& text) +{ + while (!Eof() && GetChar(m_pos) != wxT('<')) + { + text += GetChar(m_pos); + m_pos ++; + } + return TRUE; +} + +wxSimpleHtmlTag* wxSimpleHtmlParser::ParseTagHeader() +{ + if (IsTagStartBracket(GetChar(m_pos))) + { + m_pos ++; + EatWhitespace(); + + wxString word; + ReadWord(word, TRUE); + + EatWhitespace(); + + wxSimpleHtmlTag* tag = new wxSimpleHtmlTag(word, wxSimpleHtmlTag_Open); + + ParseAttributes(tag); + + EatWhitespace(); + + if (IsTagEndBracket(GetChar(m_pos))) + m_pos ++; + + return tag; + } + else + return NULL; +} + +wxSimpleHtmlTag* wxSimpleHtmlParser::ParseTagClose() +{ + Matches(wxT(" + while (!IsTagEndBracket(GetChar(m_pos)) && !Eof()) + { + EatWhitespace(); + + wxString attrName, attrValue; + + if (IsString()) + { + ReadString(attrName, TRUE); + tag->AppendAttribute(attrName, wxEmptyString); + } + else if (IsNumeric(GetChar(m_pos))) + { + ReadNumber(attrName, TRUE); + tag->AppendAttribute(attrName, wxEmptyString); + } + else + { + // Try to read an attribute name/value pair, or at least a name + // without the value + ReadLiteral(attrName, TRUE); + EatWhitespace(); + + if (GetChar(m_pos) == wxT('=')) + { + m_pos ++; + EatWhitespace(); + + if (IsString()) + ReadString(attrValue, TRUE); + else if (!Eof() && !IsTagEndBracket(GetChar(m_pos))) + ReadLiteral(attrValue, TRUE); + } + if (!attrName.IsEmpty()) + tag->AppendAttribute(attrName, attrValue); + } + } + return TRUE; +} + +// e.g. +wxSimpleHtmlTag* wxSimpleHtmlParser::ParseDirective() +{ + Matches(wxT(""), TRUE)) + { + m_pos ++; + } + + return TRUE; +} + +bool wxSimpleHtmlParser::EatWhitespace() +{ + while (!Eof() && IsWhitespace(GetChar(m_pos))) + m_pos ++; + return TRUE; +} + +bool wxSimpleHtmlParser::EatWhitespace(int& pos) +{ + while (!Eof(pos) && IsWhitespace(GetChar(pos))) + pos ++; + return TRUE; +} + +bool wxSimpleHtmlParser::ReadString(wxString& str, bool eatIt) +{ + int pos = m_pos; + if (GetChar(pos) == (int) '"') + { + pos ++; + while (!Eof(pos) && GetChar(pos) != (int) '"') + { + // TODO: how are quotes escaped in HTML? + str += (wxChar) GetChar(pos); + pos ++; + } + if (GetChar(pos) == (int) '"') + pos ++; + if (eatIt) + m_pos = pos; + return TRUE; + } + else + return FALSE; +} + +bool wxSimpleHtmlParser::ReadWord(wxString& str, bool eatIt) +{ + int pos = m_pos; + + if (!IsAlpha(GetChar(pos))) + return FALSE; + + str += (wxChar) GetChar(pos) ; + pos ++; + + while (!Eof(pos) && IsWordChar(GetChar(pos))) + { + str += (wxChar) GetChar(pos); + pos ++; + } + if (eatIt) + m_pos = pos; + return TRUE; +} + +bool wxSimpleHtmlParser::ReadNumber(wxString& str, bool eatIt) +{ + int pos = m_pos; + + if (!IsNumeric(GetChar(pos))) + return FALSE; + + str += (wxChar) GetChar(pos) ; + pos ++; + + while (!Eof(pos) && IsNumeric(GetChar(pos))) + { + str += (wxChar) GetChar(pos); + pos ++; + } + if (eatIt) + m_pos = pos; + return TRUE; +} + +// Could be number, string, whatever, but read up until whitespace or end of tag (but not a quoted string) +bool wxSimpleHtmlParser::ReadLiteral(wxString& str, bool eatIt) +{ + int pos = m_pos; + + while (!Eof(pos) && !IsWhitespace(GetChar(pos)) && !IsTagEndBracket(GetChar(pos)) && GetChar(pos) != wxT('=')) + { + str += GetChar(pos); + pos ++; + } + if (eatIt) + m_pos = pos; + return TRUE; +} + +bool wxSimpleHtmlParser::IsTagClose() +{ + return Matches(wxT("')); +} + +bool wxSimpleHtmlParser::IsWhitespace(int ch) +{ + return ((ch == 13) || (ch == 10) || (ch == 32) || (ch == (int) '\t')) ; +} + +bool wxSimpleHtmlParser::IsAlpha(int ch) +{ + return (wxIsalpha((wxChar) ch) != 0); +} + +bool wxSimpleHtmlParser::IsWordChar(int ch) +{ + return (wxIsalpha((wxChar) ch) != 0 || ch == wxT('-') || ch == wxT('_') || IsNumeric(ch)); +} + +bool wxSimpleHtmlParser::IsNumeric(int ch) +{ + return (wxIsdigit((wxChar) ch) != 0 || ch == wxT('-') || ch == wxT('.')) ; +} + +// Matches this string (case insensitive) +bool wxSimpleHtmlParser::Matches(const wxString& tok, bool eatIt) +{ + wxString text(m_text.Mid(m_pos, tok.Length())); + bool success = (text.CmpNoCase(tok) == 0) ; + if (success && eatIt) + { + m_pos += tok.Length(); + } + return success; +} + +// Safe way of getting a character +int wxSimpleHtmlParser::GetChar(size_t i) const +{ + if (i >= m_length) + return -1; + return m_text[i]; +} + +void wxSimpleHtmlParser::Clear() +{ + if (m_topLevel) + delete m_topLevel; + m_topLevel = NULL; + m_text = wxEmptyString; + m_pos = 0; + m_length = 0; +} + +// Write this file +void wxSimpleHtmlParser::Write(wxOutputStream& stream) +{ + if (m_topLevel) + m_topLevel->Write(stream); +} + +bool wxSimpleHtmlParser::WriteFile(wxString& filename) +{ + wxFileOutputStream fstream(filename); + if (fstream.Ok()) + { + Write(fstream); + return TRUE; + } + else + return FALSE; +} + +/* + * wxSimpleHtmlTag + * Representation of a tag or chunk of text + */ + +wxSimpleHtmlTag::wxSimpleHtmlTag(const wxString& tagName, int tagType) +{ + m_name = tagName; + m_type = tagType; + m_attributes = NULL; + m_children = NULL; + m_parent = NULL; + m_next = NULL; +} + +wxSimpleHtmlTag::~wxSimpleHtmlTag() +{ + ClearAttributes(); + ClearChildren(); +} + +//// Operations +void wxSimpleHtmlTag::ClearAttributes() +{ + if (m_attributes) + { + wxSimpleHtmlAttribute* attr = m_attributes; + while (attr) + { + wxSimpleHtmlAttribute* next = attr->m_next; + + attr->m_next = NULL; + delete attr; + attr = next; + } + m_attributes = NULL; + } +} + +wxSimpleHtmlAttribute* wxSimpleHtmlTag::FindAttribute(const wxString& name) const +{ + wxSimpleHtmlAttribute* attr = m_attributes; + while (attr) + { + if (attr->GetName().CmpNoCase(name) == 0) + { + return attr; + } + attr = attr->m_next; + } + return NULL; +} + +void wxSimpleHtmlTag::AppendAttribute(const wxString& name, const wxString& value) +{ + wxSimpleHtmlAttribute* attr = new wxSimpleHtmlAttribute(name, value); + if (m_attributes) + { + // Find tail + wxSimpleHtmlAttribute* last = m_attributes; + while (last->m_next) + last = last->m_next; + + last->m_next = attr; + } + else + m_attributes = attr; +} + +void wxSimpleHtmlTag::ClearChildren() +{ + if (m_children) + { + wxSimpleHtmlTag* child = m_children; + while (child) + { + wxSimpleHtmlTag* next = child->m_next; + + child->m_next = NULL; + delete child; + child = next; + } + m_children = NULL; + } +} + +void wxSimpleHtmlTag::AppendTag(wxSimpleHtmlTag* tag) +{ + if (m_children) + { + // Find tail + wxSimpleHtmlTag* last = m_children; + while (last->m_next) + last = last->m_next; + + last->m_next = tag; + tag->m_parent = this; + } + else + m_children = tag; +} + +// Gets the text from this tag and its descendants +wxString wxSimpleHtmlTag::GetTagText() +{ + wxString text; + if (m_children) + { + wxSimpleHtmlTag* tag = m_children; + while (tag) + { + text += tag->GetTagText(); + tag = tag->m_next; + } + return text; + } + else if (GetType() == wxSimpleHtmlTag_Text) + return GetText(); + else + return wxEmptyString; +} + +int wxSimpleHtmlTag::GetAttributeCount() const +{ + int count = 0; + wxSimpleHtmlAttribute* attr = m_attributes; + while (attr) + { + count ++; + attr = attr->m_next; + } + return count; +} + +wxSimpleHtmlAttribute* wxSimpleHtmlTag::GetAttribute(int i) const +{ + int count = 0; + wxSimpleHtmlAttribute* attr = m_attributes; + while (attr) + { + if (count == i) + return attr; + count ++; + attr = attr->m_next; + } + return NULL; +} + +int wxSimpleHtmlTag::GetChildCount() const +{ + int count = 0; + wxSimpleHtmlTag* tag = m_children; + while (tag) + { + count ++; + tag = tag->m_next; + } + return count; +} + +bool wxSimpleHtmlTag::HasAttribute(const wxString& name, const wxString& value) const +{ + wxSimpleHtmlAttribute* attr = FindAttribute(name); + + return (attr && (attr->GetValue().CmpNoCase(value) == 0)) ; +} + +bool wxSimpleHtmlTag::HasAttribute(const wxString& name) const +{ + return FindAttribute(name) != NULL ; +} + +bool wxSimpleHtmlTag::GetAttributeValue(wxString& value, const wxString& attrName) +{ + wxSimpleHtmlAttribute* attr = FindAttribute(attrName); + if (attr) + { + value = attr->GetValue(); + return TRUE; + } + else + return FALSE; +} + +// Search forward from this tag until we find a tag with this name & attribute +wxSimpleHtmlTag* wxSimpleHtmlTag::FindTag(const wxString& tagName, const wxString& attrName) +{ + wxSimpleHtmlTag* tag = m_next; + while (tag) + { + if (tag->NameIs(tagName) && tag->FindAttribute(attrName)) + return tag; + + tag = tag->m_next; + } + return NULL; +} + +bool wxSimpleHtmlTag::FindTextUntilTagClose(wxString& text, const wxString& tagName) +{ + wxSimpleHtmlTag* tag = this; + while (tag) + { + if (tag->GetType() == wxSimpleHtmlTag_Close && tag->NameIs(tagName)) + return TRUE; + + if (tag->GetType() == wxSimpleHtmlTag_Text) + text += tag->GetText(); + + tag = tag->m_next; + } + return TRUE; +} + + +wxSimpleHtmlTag* wxSimpleHtmlTag::GetChild(int i) const +{ + int count = 0; + wxSimpleHtmlTag* tag = m_children; + while (tag) + { + if (count == i) + return tag; + + count ++; + tag = tag->m_next; + } + return NULL; +} + +void wxSimpleHtmlTag::Write(wxOutputStream& stream) +{ + switch (GetType()) + { + case wxSimpleHtmlTag_Text: + { + stream << m_text; + break; + } + case wxSimpleHtmlTag_Open: + { + stream << "<" << m_name; + if (GetAttributeCount() > 0) + stream << " "; + int i; + for (i = 0; i < GetAttributeCount(); i++) + { + wxSimpleHtmlAttribute* attr = GetAttribute(i); + attr->Write(stream); + if (i < GetAttributeCount() - 1) + stream << " "; + } + stream << ">\n"; + break; + } + case wxSimpleHtmlTag_Directive: + { + stream << "Write(stream); + if (i < GetAttributeCount() - 1) + stream << " "; + } + stream << ">\n"; + break; + } + case wxSimpleHtmlTag_Close: + { + stream << "\n"; + break; + } + default: + { + break; + } + } + wxSimpleHtmlTag* tag = m_children; + while (tag) + { + tag->Write(stream); + tag = tag->m_next; + } + +} + +void wxSimpleHtmlAttribute::Write(wxOutputStream& stream) +{ + if (m_value.IsEmpty()) + stream << m_name; + else + { + stream << m_name; + stream << "=\""; + stream << m_value; + stream << "\""; + } +} diff --git a/host/tools/configtool/standalone/wxwin/htmlparser.h b/host/tools/configtool/standalone/wxwin/htmlparser.h new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/htmlparser.h @@ -0,0 +1,301 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): julians +// Contact(s): julians +// Date: 2001/04/04 +// Version: 0.01 +// Purpose: +// Description: HTML parser/HTML Help file generator +// Requires: +// Provides: +// See also: +// Known bugs: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== + +#ifndef _EC_HTMLPARSER_H_ +#define _EC_HTMLPARSER_H_ + +#ifdef __GNUG__ +#pragma interface "htmlparser.cpp" +#endif + +#include "wx/module.h" +#include "wx/stream.h" + +/* + + So how are going to represent it: compare with my Latex parser. + This generates a hierarchy because it respects the hierarchical nature of the Latex + commands. However, we don't _have_ to do that, we can make it linear, e.g. + + tag-with-attributes text-chunk end-tag-with-attributes tag-with-attributes text-chunk + + Otherwise, we need knowledge about HTML tags to parse hierarchically. This wouldn't be hard. + Would need to specify which tags have open/close parts, which don't, and for which it's optional + (such as

    ). + + + */ + +/* + * wxSimpleHtmlAttribute + * Representation of an attribute + */ + +class wxSimpleHtmlAttribute +{ + friend class wxSimpleHtmlTag; +public: + wxSimpleHtmlAttribute(const wxString& name, const wxString& value) + { + m_name = name; m_value = value; m_next = NULL; + } +//// Operations + + // Write this attribute + void Write(wxOutputStream& stream); + +//// Accessors + const wxString& GetName() const { return m_name; } + const wxString& GetValue() const { return m_value; } + + wxSimpleHtmlAttribute* GetNextAttribute() { return m_next; } + void SetNextAttribute(wxSimpleHtmlAttribute* attr) { m_next = attr; } + + bool HasName(const wxString& name) const { return (0 == m_name.CmpNoCase(name)); } + bool HasValue(const wxString& val) const { return (0 == m_value.CmpNoCase(val)); } + +private: + wxString m_name; + wxString m_value; + wxSimpleHtmlAttribute* m_next; +}; + + +/* + * wxSimpleHtmlTag + * Representation of a tag or chunk of text + */ + +enum { wxSimpleHtmlTag_Text, wxSimpleHtmlTag_TopLevel, wxSimpleHtmlTag_Open, wxSimpleHtmlTag_Close, wxSimpleHtmlTag_Directive }; + +class wxSimpleHtmlTag +{ +public: + wxSimpleHtmlTag(const wxString& tagName, int tagType); + ~wxSimpleHtmlTag(); + +//// Operations + void ClearAttributes(); + wxSimpleHtmlAttribute* FindAttribute(const wxString& name) const ; + void AppendAttribute(const wxString& name, const wxString& value); + void ClearChildren(); + void AppendTag(wxSimpleHtmlTag* tag); + // Write this tag + void Write(wxOutputStream& stream); + + // Gets the text from this tag and its descendants + wxString GetTagText(); + +//// Accessors + const wxString& GetName() const { return m_name; } + void SetName(const wxString& name) { m_name = name; } + + int GetType() const { return m_type; } + void SetType(int t) { m_type = t; } + + // If type is wxSimpleHtmlTag_Text, m_text will contain some text. + const wxString& GetText() const { return m_text; } + void SetText(const wxString& text) { m_text = text; } + + wxSimpleHtmlAttribute* GetFirstAttribute() { return m_attributes; } + void SetFirstAttribute(wxSimpleHtmlAttribute* attr) { m_attributes = attr; } + + int GetAttributeCount() const ; + wxSimpleHtmlAttribute* GetAttribute(int i) const ; + + wxSimpleHtmlTag* GetChildren() const { return m_children; } + void SetChildren(wxSimpleHtmlTag* children) { m_children = children; } + + wxSimpleHtmlTag* GetParent() const { return m_parent; } + void SetParent(wxSimpleHtmlTag* parent) { m_parent = parent; } + int GetChildCount() const; + wxSimpleHtmlTag* GetChild(int i) const; + wxSimpleHtmlTag* GetNext() const { return m_next; } + +//// Convenience accessors & search functions + bool NameIs(const wxString& name) { return (m_name.CmpNoCase(name) == 0); } + bool HasAttribute(const wxString& name, const wxString& value) const; + bool HasAttribute(const wxString& name) const; + bool GetAttributeValue(wxString& value, const wxString& attrName); + + // Search forward from this tag until we find a tag with this name & attribute + wxSimpleHtmlTag* FindTag(const wxString& tagName, const wxString& attrName); + + // Gather the text until we hit the given close tag + bool FindTextUntilTagClose(wxString& text, const wxString& tagName); + +private: + wxString m_name; + int m_type; + wxString m_text; + wxSimpleHtmlAttribute* m_attributes; + + // List of children + wxSimpleHtmlTag* m_children; + wxSimpleHtmlTag* m_next; // Next sibling + wxSimpleHtmlTag* m_parent; +}; + +/* + * wxSimpleHtmlParser + * Simple HTML parser, for such tasks as scanning HTML for keywords, contents, etc. + */ + +class wxSimpleHtmlParser : public wxObject +{ + +public: + wxSimpleHtmlParser(); + ~wxSimpleHtmlParser(); + +//// Operations + bool ParseFile(const wxString& filename); + bool ParseString(const wxString& str); + void Clear(); + // Write this file + void Write(wxOutputStream& stream); + bool WriteFile(wxString& filename); + +//// Helpers + + // Main recursive parsing function + bool ParseHtml(wxSimpleHtmlTag* parent); + + wxSimpleHtmlTag* ParseTagHeader(); + wxSimpleHtmlTag* ParseTagClose(); + bool ParseAttributes(wxSimpleHtmlTag* tag); + wxSimpleHtmlTag* ParseDirective(); // e.g. + bool ParseComment(); // Throw away comments + // Plain text, up until an angled bracket + bool ParseText(wxString& text); + + bool EatWhitespace(); // Throw away whitespace + bool EatWhitespace(int& pos); // Throw away whitespace: using 'pos' + bool ReadString(wxString& str, bool eatIt = FALSE); + bool ReadWord(wxString& str, bool eatIt = FALSE); + bool ReadNumber(wxString& str, bool eatIt = FALSE); + // Could be number, string, whatever, but read up until whitespace. + bool ReadLiteral(wxString& str, bool eatIt = FALSE); + + bool IsDirective(); + bool IsComment(); + bool IsString(); + bool IsWord(); + bool IsTagClose(); + bool IsTagStartBracket(int ch); + bool IsTagEndBracket(int ch); + bool IsWhitespace(int ch); + bool IsAlpha(int ch); + bool IsWordChar(int ch); + bool IsNumeric(int ch); + + // Matches this string (case insensitive) + bool Matches(const wxString& tok, bool eatIt = FALSE) ; + bool Eof() const { return (m_pos >= m_length); } + bool Eof(int pos) const { return (pos >= m_length); } + + void SetPosition(int pos) { m_pos = pos; } + + +//// Accessors + wxSimpleHtmlTag* GetTopLevelTag() const { return m_topLevel; } + + // Safe way of getting a character + int GetChar(size_t i) const; + +private: + + wxSimpleHtmlTag* m_topLevel; + int m_pos; // Position in string + int m_length; // Length of string + wxString m_text; // The actual text + +}; + +/* + * wxSimpleHtmlTagSpec + * Describes a tag, and what type it is. + * wxSimpleHtmlModule will initialise/cleanup a list of these, one per tag type + */ + +#if 0 +class wxSimpleHtmlTagSpec : public wxObject +{ + +public: + wxSimpleHtmlTagSpec(const wxString& name, int type); + +//// Operations + static void AddTagSpec(wxSimpleHtmlTagSpec* spec); + static void Clear(); + +//// Accessors + const wxString& GetName() const { return m_name; } + int GetType() const { return m_type; } + +private: + + wxString m_name; + int m_type; + + static wxList* sm_tagSpecs; +}; + +/* + * wxSimpleHtmlModule + * Responsible for init/cleanup of appropriate data structures + */ + +class wxSimpleHtmlModule : public wxModule +{ +DECLARE_DYNAMIC_CLASS(wxSimpleHtmlModule) + +public: + wxSimpleHtmlModule() {}; + + bool OnInit() ; + void OnExit() ; +}; +#endif + +#endif diff --git a/host/tools/configtool/standalone/wxwin/licensedlg.cpp b/host/tools/configtool/standalone/wxwin/licensedlg.cpp new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/licensedlg.cpp @@ -0,0 +1,142 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +// appsettings.cpp : +// +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): julians +// Contact(s): julians +// Date: 2000/12/18 +// Version: $Id: licensedlg.cpp,v 1.2 2001/03/23 13:38:04 julians Exp $ +// Purpose: +// Description: Implementation file for ecLicenseDialog +// Requires: +// Provides: +// See also: +// Known bugs: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== + +#ifdef __GNUG__ + #pragma implementation "licensedlg.cpp" +#endif + +#include "ecpch.h" + +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + +#include "wx/valgen.h" + +#include "licensedlg.h" +#include "configtool.h" + +//---------------------------------------------------------------------------- +// ecLicenseDialog +//---------------------------------------------------------------------------- + +// WDR: event table for ecLicenseDialog + +BEGIN_EVENT_TABLE(ecLicenseDialog, ecDialog) + EVT_BUTTON( wxID_OK, ecLicenseDialog::OnOK ) + EVT_BUTTON( wxID_CANCEL, ecLicenseDialog::OnCancel ) +END_EVENT_TABLE() + +ecLicenseDialog::ecLicenseDialog( const wxString& licenseText, wxWindow *parent, wxWindowID id, const wxString &title, + const wxPoint &position, const wxSize& size, long style ) +{ + SetExtraStyle(wxDIALOG_EX_CONTEXTHELP); + m_licenseText = licenseText; + + wxDialog::Create( parent, id, title, position, size, style ); + + CreateControls(); + + Centre(wxBOTH); +} + +// WDR: handler implementations for ecLicenseDialog + +void ecLicenseDialog::OnOK(wxCommandEvent &event) +{ + event.Skip(); +} + +void ecLicenseDialog::OnCancel(wxCommandEvent &event) +{ + event.Skip(); +} + +void ecLicenseDialog::CreateControls() +{ + wxWindow* parent = this; + + wxSizer *item0 = new wxBoxSizer( wxVERTICAL ); + + wxTextCtrl *item1 = new wxTextCtrl( parent, ecID_LICENSE_TEXT, _(""), wxDefaultPosition, wxSize(590,260), wxTE_MULTILINE|wxTE_READONLY ); + item0->Add( item1, 1, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + wxStaticText *item2 = new wxStaticText( parent, wxID_STATIC, + _("Do you accept all the terms of the preceding license agreement?"), + wxDefaultPosition, wxDefaultSize, 0 ); + item0->Add( item2, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + wxSizer *item3 = new wxBoxSizer( wxHORIZONTAL ); + + wxButton *item4 = new wxButton( parent, wxID_OK, _("&Yes"), wxDefaultPosition, wxDefaultSize, 0 ); + item4->SetDefault(); + item3->Add( item4, 0, wxALIGN_CENTRE|wxALL, 5 ); + + wxButton *item5 = new wxButton( parent, wxID_CANCEL, _("&No"), wxDefaultPosition, wxDefaultSize, 0 ); + item3->Add( item5, 0, wxALIGN_CENTRE|wxALL, 5 ); + + item0->Add( item3, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 ); + + parent->SetAutoLayout( TRUE ); + parent->SetSizer( item0 ); + parent->Layout(); + item0->Fit( parent ); + item0->SetSizeHints( parent ); + + // Add validators + parent->FindWindow( ecID_LICENSE_TEXT )->SetValidator(wxGenericValidator(& m_licenseText)); + + // Add context-sensitive help text + parent->FindWindow( ecID_LICENSE_TEXT )->SetHelpText(_("Displays the license for this package.")); + parent->FindWindow( wxID_OK )->SetHelpText(_("Confirms that you accept the license.")); + parent->FindWindow( wxID_CANCEL )->SetHelpText(_("Confirms that you do NOT accept the license.")); + +#if __WXGTK__ + // parent->FindWindow( wxID_CONTEXT_HELP )->SetHelpText(_("Invokes context-sensitive help for the clicked-on window.")); +#endif + +} + + diff --git a/host/tools/configtool/standalone/wxwin/licensedlg.h b/host/tools/configtool/standalone/wxwin/licensedlg.h new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/licensedlg.h @@ -0,0 +1,84 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +// appsettings.cpp : +// +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): julians +// Contact(s): julians +// Date: 2000/12/18 +// Version: $Id: licensedlg.h,v 1.2 2001/03/23 13:38:04 julians Exp $ +// Purpose: +// Description: Header file for ecLicenseDialog +// Requires: +// Provides: +// See also: +// Known bugs: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== + +#ifndef _ECOS_LICENSEDLG_H_ +#define _ECOS_LICENSEDLG_H_ + +#ifdef __GNUG__ + #pragma interface "licensedlg.cpp" +#endif + +#include "ecutils.h" + +//---------------------------------------------------------------------------- +// ecLicenseDialog +//---------------------------------------------------------------------------- + +class ecLicenseDialog: public ecDialog +{ +public: + // constructors and destructors + ecLicenseDialog( const wxString& licenseText, wxWindow *parent, wxWindowID id, const wxString &title, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); + +//// Event handlers + + void OnOK(wxCommandEvent& event); + void OnCancel(wxCommandEvent& event); + +//// Operations + void CreateControls(); + +private: + DECLARE_EVENT_TABLE() + + wxString m_licenseText; +}; + + +#endif + // _ECOS_LICENSEDLG_H_ diff --git a/host/tools/configtool/standalone/wxwin/mainwin.cpp b/host/tools/configtool/standalone/wxwin/mainwin.cpp new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/mainwin.cpp @@ -0,0 +1,1651 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +// mainwin.cpp : +// +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): julians +// Contact(s): julians +// Date: 2000/08/24 +// Version: $Id: mainwin.cpp,v 1.42 2001/05/16 16:08:24 julians Exp $ +// Purpose: +// Description: Implementation file for the ConfigTool main window +// Requires: +// Provides: +// See also: +// Known bugs: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== + +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- +#ifdef __GNUG__ +#pragma implementation "mainwin.h" +#endif + +// Includes other headers for precompiled compilation +#include "ecpch.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#include "wx/cshelp.h" +#include "wx/wxhtml.h" +#include "wx/filedlg.h" +#include "wx/wfstream.h" + +#include "mainwin.h" +#include "configtool.h" +#include "configtree.h" +#include "propertywin.h" +#include "conflictwin.h" +#include "mltwin.h" +#include "outputwin.h" +#include "shortdescrwin.h" +#include "conflictsdlg.h" +#include "aboutdlg.h" +#include "finddlg.h" +#include "settingsdlg.h" +#include "platformsdlg.h" +#include "buildoptionsdlg.h" +#include "templatesdlg.h" +#include "admindlg.h" +#include "packagesdlg.h" +#include "configtooldoc.h" +#include "configtoolview.h" +#include "folderdlg.h" +#include "reposdlg.h" +#include "docsystem.h" + +#ifdef __WXMSW__ +#include "wx/msw/winundef.h" +#endif + +// ---------------------------------------------------------------------------- +// resources +// ---------------------------------------------------------------------------- +// the application icon +#if defined(__WXGTK__) || defined(__WXMOTIF__) +#include "bitmaps/configtool.xpm" +#include "bitmaps/new.xpm" +#include "bitmaps/open.xpm" +#include "bitmaps/save.xpm" +#include "bitmaps/copy.xpm" +#include "bitmaps/paste.xpm" +#include "bitmaps/cut.xpm" +#include "bitmaps/delete.xpm" +#include "bitmaps/help.xpm" +#include "bitmaps/cshelp.xpm" +#include "bitmaps/search.xpm" +#include "bitmaps/stopbuild.xpm" +#include "bitmaps/buildlibrary.xpm" +#include "bitmaps/newregion.xpm" +#include "bitmaps/newsection.xpm" +#include "bitmaps/properties.xpm" +#endif + +// ---------------------------------------------------------------------------- +// event tables and other macros for wxWindows +// ---------------------------------------------------------------------------- + +BEGIN_EVENT_TABLE(ecMainFrame, wxDocParentFrame) + EVT_MENU(wxID_EXIT, ecMainFrame::OnQuit) + EVT_MENU(wxID_ABOUT, ecMainFrame::OnAbout) + EVT_MENU(ecID_REPOSITORY_INFO, ecMainFrame::OnRepositoryInfo) + EVT_MENU(wxID_FIND, ecMainFrame::OnFind) + EVT_MENU(ecID_FIND_NEXT, ecMainFrame::OnFindNext) + EVT_SASH_DRAGGED_RANGE(ecID_CONFIG_SASH_WINDOW, ecID_OUTPUT_SASH_WINDOW, ecMainFrame::OnSashDrag) + EVT_SIZE(ecMainFrame::OnSize) + EVT_IDLE(ecMainFrame::OnIdle) + EVT_CLOSE(ecMainFrame::OnCloseWindow) + EVT_MENU(ecID_TOGGLE_CONFLICTS, ecMainFrame::OnToggleWindow) + EVT_MENU(ecID_TOGGLE_PROPERTIES, ecMainFrame::OnToggleWindow) + EVT_MENU(ecID_TOGGLE_MEMORY, ecMainFrame::OnToggleWindow) + EVT_MENU(ecID_TOGGLE_SHORT_DESCR, ecMainFrame::OnToggleWindow) + EVT_MENU(ecID_TOGGLE_OUTPUT, ecMainFrame::OnToggleWindow) + EVT_MENU(ecID_TOOLBARS, ecMainFrame::OnToggleToolbar) + EVT_MENU(ecID_CONFIGTOOL_HELP, ecMainFrame::OnHelpConfigtool) + EVT_MENU(ecID_ECOS_HELP, ecMainFrame::OnHelpEcos) + EVT_MENU(ecID_CONTEXT_HELP, ecMainFrame::OnHelpContext) + EVT_MENU(ecID_RESOLVE_CONFLICTS, ecMainFrame::OnResolveConflicts) + EVT_UPDATE_UI(ecID_RESOLVE_CONFLICTS, ecMainFrame::OnUpdateResolveConflicts) + EVT_MENU(ecID_SETTINGS, ecMainFrame::OnSettings) + EVT_MENU(ecID_PLATFORMS, ecMainFrame::OnPlatforms) + EVT_MENU(ecID_BUILD_OPTIONS, ecMainFrame::OnBuildOptions) + EVT_MENU(ecID_PATHS_BUILD_TOOLS, ecMainFrame::OnBuildToolsPath) + EVT_MENU(ecID_PATHS_USER_TOOLS, ecMainFrame::OnUserToolsPath) + EVT_MENU(ecID_BUILD_TEMPLATES, ecMainFrame::OnTemplates) + EVT_MENU(ecID_ADMINISTRATION, ecMainFrame::OnAdmin) + EVT_MENU(ecID_BUILD_PACKAGES, ecMainFrame::OnPackages) + EVT_MENU(ecID_RUN_TESTS, ecMainFrame::OnRunTests) + EVT_MENU(ecID_BUILD_REPOSITORY, ecMainFrame::OnChooseRepository) + EVT_MENU(ecID_WHATS_THIS, ecMainFrame::OnWhatsThis) + EVT_MENU(ecID_SAVE_OUTPUT, ecMainFrame::OnSaveOutput) + EVT_MENU(ecID_IMPORT, ecMainFrame::OnImport) + EVT_MENU(ecID_EXPORT, ecMainFrame::OnExport) + EVT_MENU(ecID_REDHAT_WEB_HOME, ecMainFrame::OnWebRedHatHome) + EVT_MENU(ecID_REDHAT_WEB_ECOS, ecMainFrame::OnWebEcos) + EVT_MENU(ecID_REDHAT_WEB_NET_RELEASE, ecMainFrame::OnWebNetRelease) + EVT_MENU(ecID_REDHAT_WEB_UITRON, ecMainFrame::OnWebUitron) + EVT_MENU(ecID_STOP_BUILD, ecMainFrame::OnStopBuild) + EVT_MENU(ecID_BUILD_LIBRARY, ecMainFrame::OnBuildLibrary) + EVT_MENU(ecID_BUILD_TESTS, ecMainFrame::OnBuildTests) + EVT_MENU(ecID_CLEAN, ecMainFrame::OnClean) + EVT_MENU(ecID_SHELL, ecMainFrame::OnShell) + EVT_MENU(ecID_INDEX_DOCS, ecMainFrame::OnIndexDocs) + + EVT_UPDATE_UI(ecID_PLATFORMS, ecMainFrame::OnUpdatePlatforms) + EVT_UPDATE_UI(ecID_BUILD_OPTIONS, ecMainFrame::OnUpdateBuildOptions) + EVT_UPDATE_UI(ecID_PATHS_BUILD_TOOLS, ecMainFrame::OnUpdateBuildToolsPath) + EVT_UPDATE_UI(ecID_PATHS_USER_TOOLS, ecMainFrame::OnUpdateUserToolsPath) + EVT_UPDATE_UI(ecID_BUILD_TEMPLATES, ecMainFrame::OnUpdateTemplates) + EVT_UPDATE_UI(ecID_ADMINISTRATION, ecMainFrame::OnUpdateAdmin) + EVT_UPDATE_UI(ecID_BUILD_PACKAGES, ecMainFrame::OnUpdatePackages) + EVT_UPDATE_UI(ecID_RUN_TESTS, ecMainFrame::OnUpdateRunTests) + EVT_UPDATE_UI(ecID_BUILD_REPOSITORY, ecMainFrame::OnUpdateChooseRepository) + EVT_UPDATE_UI(ecID_CLEAN, ecMainFrame::OnUpdateClean) + EVT_UPDATE_UI(ecID_REPOSITORY_INFO, ecMainFrame::OnUpdateRepositoryInfo) + EVT_UPDATE_UI(ecID_INDEX_DOCS, ecMainFrame::OnUpdateIndexDocs) + + EVT_UPDATE_UI(ecID_TOGGLE_CONFLICTS, ecMainFrame::OnUpdateToggleWindow) + EVT_UPDATE_UI(ecID_TOGGLE_PROPERTIES, ecMainFrame::OnUpdateToggleWindow) + EVT_UPDATE_UI(ecID_TOGGLE_MEMORY, ecMainFrame::OnUpdateToggleWindow) + EVT_UPDATE_UI(ecID_TOGGLE_SHORT_DESCR, ecMainFrame::OnUpdateToggleWindow) + EVT_UPDATE_UI(ecID_TOGGLE_OUTPUT, ecMainFrame::OnUpdateToggleWindow) + EVT_UPDATE_UI(ecID_TOOLBARS, ecMainFrame::OnUpdateToggleToolbar) + + // Disable commands that don't make sense immediately or are not yet implemented. + // Also, for text controls, disable if they are not being enabled by currently-focussed controls. + EVT_UPDATE_UI(wxID_COPY, ecMainFrame::OnUpdateDisable) + EVT_UPDATE_UI(wxID_CUT, ecMainFrame::OnUpdateDisable) + EVT_UPDATE_UI(wxID_PASTE, ecMainFrame::OnUpdateDisable) + EVT_UPDATE_UI(wxID_SELECTALL, ecMainFrame::OnUpdateSelectAll) + EVT_UPDATE_UI(wxID_CLEAR, ecMainFrame::OnUpdateClear) + + EVT_UPDATE_UI(wxID_FIND, ecMainFrame::OnUpdateFind) + EVT_UPDATE_UI(ecID_FIND_NEXT, ecMainFrame::OnUpdateFindNext) + + EVT_MENU(ecID_NEW_REGION, ecMainFrame::OnNewRegion) + EVT_MENU(ecID_NEW_SECTION, ecMainFrame::OnNewSection) + EVT_MENU(ecID_DELETE, ecMainFrame::OnDeleteRegionOrSection) + EVT_MENU(ecID_PROPERTIES, ecMainFrame::OnRegionOrSectionProperties) + + EVT_UPDATE_UI(ecID_STOP_BUILD, ecMainFrame::OnUpdateStopBuild) + EVT_UPDATE_UI(ecID_BUILD_LIBRARY, ecMainFrame::OnUpdateBuildLibrary) + EVT_UPDATE_UI(ecID_BUILD_TESTS, ecMainFrame::OnUpdateBuildTests) + + EVT_UPDATE_UI(ecID_SHELL, ecMainFrame::OnUpdateShell) + + EVT_UPDATE_UI(ecID_NEW_REGION, ecMainFrame::OnUpdateNewRegion) + EVT_UPDATE_UI(ecID_NEW_SECTION, ecMainFrame::OnUpdateNewSection) + EVT_UPDATE_UI(ecID_DELETE, ecMainFrame::OnUpdateDeleteRegionOrSection) + EVT_UPDATE_UI(ecID_PROPERTIES, ecMainFrame::OnUpdateRegionOrSectionProperties) + + EVT_UPDATE_UI(ecID_IMPORT, ecMainFrame::OnUpdateImport) + EVT_UPDATE_UI(ecID_EXPORT, ecMainFrame::OnUpdateExport) +END_EVENT_TABLE() + +// ---------------------------------------------------------------------------- +// main frame +// ---------------------------------------------------------------------------- + +// Frame constructor +ecMainFrame::ecMainFrame(wxDocManager *manager, const wxString& title, const wxPoint& pos, const wxSize& size): + wxDocParentFrame(manager, (wxFrame *)NULL, ecID_MAIN_FRAME, title, pos, size, wxDEFAULT_FRAME_STYLE|wxCLIP_CHILDREN|wxNO_FULL_REPAINT_ON_RESIZE ) +{ + m_splitter = NULL; + m_scrolledWindow = NULL; + m_tree = NULL; + m_configSashWindow = NULL; + m_valueWindow = NULL; + m_outputWindow = NULL; + m_shortDescrWindow = NULL; + m_conflictsSashWindow = NULL; + m_propertiesSashWindow = NULL; + m_memorySashWindow = NULL; + m_shortDescrSashWindow = NULL; + m_outputSashWindow = NULL; + m_propertyListWindow = NULL; + m_findDialog = NULL; + m_mltWindow = NULL; + +#ifdef __WXMAC__ + // we need this in order to allow the about menu relocation, since ABOUT is + // not the default id of the about menu + wxApp::s_macAboutMenuItemId = wxID_EXIT; +#endif + + CreateWindows(); + + wxIcon mainIcon(wxICON(configtool)); + wxGetApp().SetMainIcon(mainIcon); + + // set the frame icon + SetIcon(mainIcon); + + // create a menu bar + + // File menu + wxMenu *fileMenu = new wxMenu(wxT(""), wxMENU_TEAROFF); + + fileMenu->Append(wxID_NEW, _("&New\tCtrl+N"), _("Creates a new document")); +#if 0 + wxMenuItem* menuItem = new wxMenuItem(fileMenu, wxID_NEW, _("&New\tCtrl+N"), _("Creates a new document")); + menuItem->SetBitmaps(wxBITMAP(new)); + fileMenu->Append(menuItem); +#endif + + fileMenu->Append(wxID_OPEN, _("&Open\tCtrl+O"), _("Opens an existing document")); + fileMenu->Append(wxID_SAVE, _("&Save\tCtrl+S"), _("Saves the active document")); + fileMenu->Append(wxID_SAVEAS, _("Save &As..."), _("Saves the active document with a new name")); + fileMenu->AppendSeparator(); + fileMenu->Append(ecID_IMPORT, _("&Import..."), _("Imports a minimal configuration exported from another configuration")); + fileMenu->Append(ecID_EXPORT, _("&Export..."), _("Exports a minimal configuration for importing into another configuration")); + fileMenu->AppendSeparator(); + fileMenu->Append(wxID_EXIT, _("E&xit\tAlt+X"), _("Quits the application")); + + // A history of files visited. Use this menu. + wxGetApp().GetDocManager()->FileHistoryUseMenu(fileMenu); + // Load file history + { + wxConfig config(wxGetApp().GetSettings().GetConfigAppName(), wxT("Red Hat")); + wxGetApp().GetDocManager()->FileHistoryLoad(config); + } + + // Edit menu + wxMenu* editMenu = new wxMenu(wxT(""), wxMENU_TEAROFF); + + editMenu->Append(wxID_CUT, _("Cu&t\tCtrl+X"), _("Cuts the output pane selection and moves it to the Clipboard")); + editMenu->Append(wxID_COPY, _("&Copy\tCtrl+C"), _("Copies the output pane selection to the clipboard")); + editMenu->Append(wxID_PASTE, _("&Paste\tCtrl+V"), _("Inserts Clipboard contents")); + editMenu->Append(wxID_CLEAR, _("&Clear"), _("Erases everything in the output pane")); + editMenu->AppendSeparator(); + editMenu->Append(wxID_SELECTALL, _("&Select All\tCtrl+A"), _("Selects the entire output pane")); + editMenu->AppendSeparator(); + editMenu->Append(wxID_FIND, _("&Find...\tCtrl+F"), _("Finds the specified text")); + editMenu->Append(ecID_FIND_NEXT, _("Find &Next\tF3"), _("Finds the next item matching the Find text")); + editMenu->AppendSeparator(); + editMenu->Append(ecID_SAVE_OUTPUT, _("Sa&ve Output..."), _("Saves the contents of the output pane")); + + // View menu + wxMenu* viewMenu = new wxMenu(wxT(""), wxMENU_TEAROFF); + + viewMenu->Append(ecID_SETTINGS, _("&Settings...\tCtrl+T"), _("Shows the application settings dialog")); + viewMenu->AppendSeparator(); + viewMenu->Append(ecID_TOOLBARS, _("&Toolbar"), _("Shows or hides the toolbar"), TRUE); + viewMenu->Append(ecID_TOGGLE_PROPERTIES, _("&Properties\tAlt+1"), _("Shows or hides the properties window"), TRUE); + viewMenu->Append(ecID_TOGGLE_OUTPUT, _("&Output\tAlt+2"), _("Shows the output window"), TRUE); + viewMenu->Append(ecID_TOGGLE_SHORT_DESCR, _("&Short Description\tAlt+3"), _("Shows or hides the short description window"), TRUE); +#if ecUSE_MLT + viewMenu->Append(ecID_TOGGLE_MEMORY, _("&Memory Layout\tAlt+4"), _("Shows or hides the memory layout window"), TRUE); +#endif + + //viewMenu->Enable(ecID_TOGGLE_MEMORY, FALSE); + + viewMenu->Append(ecID_TOGGLE_CONFLICTS, _("&Conflicts\tAlt+5"), _("Shows or hides the conflicts window"), TRUE); + // Not clear what these do, so let's not have them. + //viewMenu->Append(ecID_VIEW_NEXT, _("&Next\tAlt+F6"), _("Selects the next visible pane")); + //viewMenu->Append(ecID_VIEW_PREVIOUS, _("&Previous\tShift+Alt+F6"), _("Selects the previous visible pane")); + + // Build menu + wxMenu* buildMenu = new wxMenu(wxT(""), wxMENU_TEAROFF); + + buildMenu->Append(ecID_BUILD_LIBRARY, _("&Library\tF7"), _("Builds the library")); + buildMenu->Append(ecID_BUILD_TESTS, _("&Tests\tShift+F7"), _("Builds the tests")); + buildMenu->Append(ecID_CLEAN, _("&Clean"), _("Deletes intermediate and output files")); + buildMenu->Append(ecID_STOP_BUILD, _("&Stop"), _("Stops the build")); + buildMenu->AppendSeparator(); + buildMenu->Append(ecID_BUILD_OPTIONS, _("&Options..."), _("Changes build options")); + buildMenu->Append(ecID_BUILD_REPOSITORY, _("&Repository..."), _("Selects repository")); + buildMenu->Append(ecID_BUILD_TEMPLATES, _("&Templates..."), _("Selects the package templates")); + buildMenu->Append(ecID_BUILD_PACKAGES, _("&Packages..."), _("Selects individual packages")); + + // Tools menu + wxMenu* toolsMenu = new wxMenu(wxT(""), wxMENU_TEAROFF); + + wxMenu* pathMenu = new wxMenu; + pathMenu->Append(ecID_PATHS_BUILD_TOOLS, _("&Build Tools..."), _("Specifies the folder containing the build tools")); + pathMenu->Append(ecID_PATHS_USER_TOOLS, _("&User Tools..."), _("Specifies the folder containing the user tools")); + toolsMenu->Append(ecID_PATHS, _("&Paths"), pathMenu); + + toolsMenu->Append(ecID_SHELL, _("&Shell..."), _("Invokes a command shell")); + toolsMenu->Append(ecID_RUN_TESTS, _("&Run Tests...\tCtrl+F5"), _("Runs the configuration tests")); + toolsMenu->Append(ecID_PLATFORMS, _("&Platforms..."), _("Edits the platforms list")); + toolsMenu->Append(ecID_RESOLVE_CONFLICTS, _("Resolve &Conflicts..."), _("Resolves conflicts")); + toolsMenu->Append(ecID_ADMINISTRATION, _("&Administration..."), _("Performs repository administration tasks")); +#if 0 + toolsMenu->AppendSeparator(); + toolsMenu->Append(ecID_TOOLS_OPTIONS, _("&Options..."), _("Changes configuration options")); +#endif + toolsMenu->Append(ecID_INDEX_DOCS, _("Regenerate Help &Index"), _("Regenerates the online help contents")); + + // Help menu + wxMenu* helpMenu = new wxMenu; + helpMenu->Append(ecID_CONFIGTOOL_HELP, _("&Configuration Tool Help\tShift+F1"), _("Displays help")); + helpMenu->Append(ecID_ECOS_HELP, _("&eCos Documentation"), _("Displays the documentation home page")); + helpMenu->Append(ecID_CONTEXT_HELP, _("&Help On..."), _("Displays help for clicked-on windows")); + helpMenu->AppendSeparator(); + + wxMenu* webMenu = new wxMenu; + webMenu->Append(ecID_REDHAT_WEB_HOME, _("&Red Hat Home Page"), _("Opens the Red Hat home page")); + webMenu->Append(ecID_REDHAT_WEB_ECOS, _("&eCos Product Page"), _("Opens the eCos product page")); + webMenu->Append(ecID_REDHAT_WEB_NET_RELEASE, _("eCos &Net Release Page"), _("Opens the eCos net release page")); + webMenu->AppendSeparator(); + webMenu->Append(ecID_REDHAT_WEB_UITRON, _("µ&ITRON"), _("Opens the µITRON specification page")); + + helpMenu->Append(ecID_REDHAT_WEB, _("&Red Hat on the Web"), webMenu); + helpMenu->AppendSeparator(); + helpMenu->Append(ecID_REPOSITORY_INFO, _("Repository &Information...\tCtrl+I"), _("Displays information about the current repository")); + helpMenu->Append(wxID_ABOUT, _("&About the Configuration Tool..."), _("Displays program information, version and copyright")); + + wxMenuBar *menuBar = new wxMenuBar(); + menuBar->Append(fileMenu, _("&File")); + menuBar->Append(editMenu, _("&Edit")); + menuBar->Append(viewMenu, _("&View")); + menuBar->Append(buildMenu, _("&Build")); + menuBar->Append(toolsMenu, _("&Tools")); + menuBar->Append(helpMenu, _("&Help")); + + // ... and attach this menu bar to the frame + SetMenuBar(menuBar); + + // Create the toolbar + RecreateToolbar(); + + if (!wxGetApp().GetSettings().m_showToolBar) + GetToolBar()->Show( FALSE ); + + // Create the status bar + CreateStatusBar(4, wxST_SIZEGRIP); + + int* widths = new int[4]; + widths[0] = -1; widths[1] = 100; widths[2] = 40; widths[3] = 80; + SetStatusWidths(4, widths); + delete[] widths; + + SetStatusText(_("No conflicts"), ecFailRulePane); + SetStatusText(_("Ready"), ecStatusPane); +} + +// Create the windows +void ecMainFrame::CreateWindows() +{ + ecSettings& stg = wxGetApp().GetSettings(); + + // Create the sash layout windows first + + // Sash window for the output window + m_outputSashWindow = new wxSashLayoutWindow(this, ecID_OUTPUT_SASH_WINDOW, wxDefaultPosition, wxDefaultSize, wxNO_BORDER|wxCLIP_SIBLINGS); + m_outputSashWindow->SetDefaultSize(stg.m_outputSashSize); + m_outputSashWindow->SetOrientation(wxLAYOUT_HORIZONTAL); + m_outputSashWindow->SetAlignment(wxLAYOUT_BOTTOM); + m_outputSashWindow->SetSashVisible(wxSASH_TOP, TRUE); + m_outputWindow = new ecOutputWindow(m_outputSashWindow, ecID_OUTPUT_WINDOW, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxCLIP_CHILDREN|wxTE_READONLY); + m_outputWindow->SetHelpText(_("The output window displays various warning and informational messages.")); + + // Sash window for the memory window + m_memorySashWindow = new wxSashLayoutWindow(this, ecID_MEMORY_SASH_WINDOW, wxDefaultPosition, wxDefaultSize, wxNO_BORDER|wxSW_3D|wxCLIP_SIBLINGS); + m_memorySashWindow->SetDefaultSize(stg.m_memorySashSize); + m_memorySashWindow->SetOrientation(wxLAYOUT_HORIZONTAL); + m_memorySashWindow->SetAlignment(wxLAYOUT_BOTTOM); + m_memorySashWindow->SetSashVisible(wxSASH_TOP, TRUE); + //wxTextCtrl* memoryWindow = new wxTextCtrl(m_memorySashWindow, ecID_MEMORY_WINDOW, wxT("This will be the memory layout window."), wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxCLIP_CHILDREN|wxTE_NO_VSCROLL|wxTE_READONLY); + m_mltWindow = new ecMemoryLayoutWindow(m_memorySashWindow, ecID_MEMORY_WINDOW, wxDefaultPosition, wxDefaultSize, wxCLIP_CHILDREN|wxSUNKEN_BORDER); + m_mltWindow->SetHelpText(_("The memory layout window presents a graphical view of the memory layout of the currently selected\ncombination of target architecture, platform and start-up type.")); + + // Sash window for the config tree + m_configSashWindow = new wxSashLayoutWindow(this, ecID_CONFIG_SASH_WINDOW, wxDefaultPosition, wxDefaultSize, wxNO_BORDER|wxCLIP_CHILDREN/*|wxCLIP_SIBLINGS*/); + m_configSashWindow->SetDefaultSize(stg.m_treeSashSize); + m_configSashWindow->SetOrientation(wxLAYOUT_VERTICAL); + m_configSashWindow->SetAlignment(wxLAYOUT_LEFT); + m_configSashWindow->SetSashVisible(wxSASH_RIGHT, TRUE); + + // Sash window for the conflicts window + m_conflictsSashWindow = new wxSashLayoutWindow(this, ecID_CONFLICTS_SASH_WINDOW, wxDefaultPosition, wxDefaultSize, wxNO_BORDER|wxCLIP_SIBLINGS); + m_conflictsSashWindow->SetDefaultSize(stg.m_conflictsSashSize); + m_conflictsSashWindow->SetOrientation(wxLAYOUT_HORIZONTAL); + m_conflictsSashWindow->SetAlignment(wxLAYOUT_TOP); + m_conflictsSashWindow->SetSashVisible(wxSASH_BOTTOM, TRUE); + m_conflictsWindow = new ecConflictListCtrl(m_conflictsSashWindow, ecID_CONFLICTS_WINDOW, wxDefaultPosition, wxDefaultSize, wxLC_REPORT|wxCLIP_CHILDREN|wxSUNKEN_BORDER); + m_conflictsWindow->SetHelpText(_("The conflicts window lists any outstanding conflicts in the configuration.")); + + // Sash window for the properties window + m_propertiesSashWindow = new wxSashLayoutWindow(this, ecID_PROPERTIES_SASH_WINDOW, wxDefaultPosition, wxDefaultSize, wxNO_BORDER|wxCLIP_SIBLINGS); + m_propertiesSashWindow->SetDefaultSize(stg.m_propertiesSashSize); + m_propertiesSashWindow->SetOrientation(wxLAYOUT_HORIZONTAL); + m_propertiesSashWindow->SetAlignment(wxLAYOUT_TOP); + m_propertiesSashWindow->SetSashVisible(wxSASH_BOTTOM, TRUE); +// wxTextCtrl* propertiesWindow = new wxTextCtrl(m_propertiesSashWindow, ecID_PROPERTIES_WINDOW, wxT("This will be the properties window."), wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxCLIP_CHILDREN|wxTE_NO_VSCROLL|wxTE_READONLY); + m_propertyListWindow = new ecPropertyListCtrl(m_propertiesSashWindow, ecID_PROPERTIES_WINDOW, wxDefaultPosition, wxDefaultSize, wxLC_REPORT|wxCLIP_CHILDREN|wxLC_VRULES|wxLC_HRULES|wxSUNKEN_BORDER); + m_propertyListWindow->SetHelpText(_("The properties window shows the properties of the selected configuration item.")); + + // Sash window for the short description window + m_shortDescrSashWindow = new wxSashLayoutWindow(this, ecID_SHORT_DESCR_SASH_WINDOW, wxDefaultPosition, wxDefaultSize, wxNO_BORDER|wxCLIP_SIBLINGS); + m_shortDescrSashWindow->SetDefaultSize(stg.m_shortDescrSashSize); + m_shortDescrSashWindow->SetOrientation(wxLAYOUT_HORIZONTAL); + m_shortDescrSashWindow->SetAlignment(wxLAYOUT_TOP); + //m_shortDescrSashWindow->SetSashVisible(wxSASH_TOP, TRUE); + m_shortDescrWindow = new ecShortDescriptionWindow(m_shortDescrSashWindow, ecID_SHORT_DESCR_WINDOW, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxCLIP_CHILDREN|wxTE_NO_VSCROLL|wxTE_READONLY); + m_shortDescrWindow->SetBackgroundColour(wxColour(255, 255, 225)); + m_shortDescrWindow->SetHelpText(_("The short description window displays brief help on a selected configuration item.")); + + // Create a composite widget to represent the scrolling config window + m_scrolledWindow = new ecSplitterScrolledWindow(m_configSashWindow, ecID_SCROLLED_WINDOW, wxDefaultPosition, + wxDefaultSize, wxNO_BORDER | wxCLIP_CHILDREN | wxVSCROLL); + m_splitter = new wxThinSplitterWindow(m_scrolledWindow, ecID_SPLITTER_WINDOW, wxDefaultPosition, + wxDefaultSize, wxSP_3DBORDER | wxCLIP_CHILDREN /* | wxSP_LIVE_UPDATE */); + m_splitter->SetSashSize(2); + m_tree = new ecConfigTreeCtrl(m_splitter, ecID_TREE_CTRL, wxDefaultPosition, + wxDefaultSize, wxTR_HAS_BUTTONS | wxTR_NO_LINES | wxNO_BORDER ); + m_valueWindow = new ecValueWindow(m_splitter, ecID_VALUE_WINDOW, wxDefaultPosition, + wxDefaultSize, wxNO_BORDER); + m_splitter->SplitVertically(m_tree, m_valueWindow); + //m_splitter->AdjustScrollbars(); + m_splitter->SetSashPosition(200); + m_scrolledWindow->SetTargetWindow(m_tree); + m_scrolledWindow->EnableScrolling(FALSE, FALSE); + m_tree->SetHelpText(_("The configuration window is the principal window used to configure eCos.\nIt takes the form of a tree-based representation of the configuration items within the currently loaded eCos packages.")); + m_valueWindow->SetHelpText(m_tree->GetHelpText()); + + // Let the two controls know about each other + m_valueWindow->SetTreeCtrl(m_tree); + m_tree->SetCompanionWindow(m_valueWindow); + + // Set visibility according to config settings + if (!wxGetApp().GetSettings().m_showConflictsWindow) + m_conflictsSashWindow->Show(FALSE); + if (!wxGetApp().GetSettings().m_showPropertiesWindow) + m_propertiesSashWindow->Show(FALSE); + if (!wxGetApp().GetSettings().m_showShortDescrWindow) + m_shortDescrSashWindow->Show(FALSE); + if (!wxGetApp().GetSettings().m_showOutputWindow) + m_outputSashWindow->Show(FALSE); + if (!wxGetApp().GetSettings().m_showMemoryWindow) + m_memorySashWindow->Show(FALSE); +} +// event handlers + +void ecMainFrame::OnQuit(wxCommandEvent& WXUNUSED(event)) +{ + Close(); +} + +void ecMainFrame::OnFind(wxCommandEvent& event) +{ + if (m_findDialog) + { + m_findDialog->Raise(); + return; + } + + m_findDialog = new ecFindDialog (this, ecID_FIND_DIALOG, _("Find in configuration")); + m_findDialog->Show(TRUE); + + // For some reason, under Windows, the text control doesn't get the focus if we set the focus + // and then call Show. We have to set the focus afterwards instead. + m_findDialog->FindWindow(ecID_FIND_DIALOG_WHAT)->SetFocus(); +} + +void ecMainFrame::OnFindNext(wxCommandEvent& event) +{ + if (wxGetApp().GetConfigToolDoc()) + { + ecConfigToolView* view = (ecConfigToolView*) wxGetApp().GetConfigToolDoc()->GetFirstView() ; + + view->DoFind(wxGetApp().GetSettings().m_findText, this); + } +} + +void ecMainFrame::OnUpdateFind(wxUpdateUIEvent& event) +{ + event.Enable( wxGetApp().GetConfigToolDoc() != NULL ); +} + +void ecMainFrame::OnUpdateFindNext(wxUpdateUIEvent& event) +{ + event.Enable( (wxGetApp().GetConfigToolDoc() != NULL) && !wxGetApp().GetSettings().m_findText.IsEmpty() ); +} + +void ecMainFrame::OnAbout(wxCommandEvent& WXUNUSED(event)) +{ + ecAboutDialog dialog(this, ecID_ABOUT_DIALOG, _("About eCos Configuration Tool")); + dialog.ShowModal(); +} + +void ecMainFrame::OnSize(wxSizeEvent& WXUNUSED(event)) +{ + // First, we need to resize the sash windows proportionately, + // or we may end up with negative sizes, etc. + wxRect rect = GetRect(); + if (rect != wxGetApp().GetSettings().m_frameSize) + { + double factorX = ((double) rect.GetWidth() / (double) wxGetApp().GetSettings().m_frameSize.GetWidth()); + double factorY = ((double) rect.GetHeight() / (double) wxGetApp().GetSettings().m_frameSize.GetHeight()); + + wxNode* node = GetChildren().First(); + while (node) + { + wxWindow* win = (wxWindow*) node->Data(); + if (win->IsKindOf(CLASSINFO(wxSashLayoutWindow))) + { + wxSashLayoutWindow* sashWin = (wxSashLayoutWindow*) win; + wxSize sz = sashWin->GetSize(); + sashWin->SetDefaultSize(wxSize((int) ((double) sz.x * factorX), (int) ((double) sz.y * factorY))); + } + node = node->Next(); + } + } + + wxLayoutAlgorithm layout; + layout.LayoutFrame(this); + + wxGetApp().GetSettings().m_frameSize = rect; +} + +void ecMainFrame::RecreateToolbar() +{ + // delete and recreate the toolbar + wxToolBarBase *toolBar = GetToolBar(); + if (toolBar) + { + delete toolBar; + SetToolBar(NULL); + } + + long style = wxNO_BORDER | wxTB_FLAT | wxTB_HORIZONTAL | wxTB_DOCKABLE; + + toolBar = CreateToolBar(style, ecID_TOOLBAR); + + toolBar->SetMargins( 4, 4 ); + + // Set up toolbar + wxBitmap toolBarBitmaps[20]; + + toolBarBitmaps[0] = wxBITMAP(new); + toolBarBitmaps[1] = wxBITMAP(open); + toolBarBitmaps[2] = wxBITMAP(save); + toolBarBitmaps[3] = wxBITMAP(copy); + toolBarBitmaps[4] = wxBITMAP(cut); + toolBarBitmaps[5] = wxBITMAP(paste); + toolBarBitmaps[6] = wxBITMAP(search); + toolBarBitmaps[7] = wxBITMAP(stopbuild); + toolBarBitmaps[8] = wxBITMAP(buildlibrary); + toolBarBitmaps[9] = wxBITMAP(help); + toolBarBitmaps[10] = wxBITMAP(newregion); + toolBarBitmaps[11] = wxBITMAP(newsection); + toolBarBitmaps[12] = wxBITMAP(delete); + toolBarBitmaps[13] = wxBITMAP(properties); + toolBarBitmaps[14] = wxBITMAP(cshelp); + + toolBar->AddTool(wxID_NEW, toolBarBitmaps[0], wxNullBitmap, FALSE, -1, -1, (wxObject *) NULL, wxT("New file")); + toolBar->AddTool(wxID_OPEN, toolBarBitmaps[1], wxNullBitmap, FALSE, -1, -1, (wxObject *) NULL, wxT("Open file")); + toolBar->AddTool(wxID_SAVE, toolBarBitmaps[2], wxNullBitmap, FALSE, -1, -1, (wxObject *) NULL, wxT("Save file")); + + toolBar->AddSeparator(); + + toolBar->AddTool(wxID_CUT, toolBarBitmaps[4], wxNullBitmap, FALSE, -1, -1, (wxObject *) NULL, "Cut"); + toolBar->AddTool(wxID_COPY, toolBarBitmaps[3], wxNullBitmap, FALSE, -1, -1, (wxObject *) NULL, "Copy"); + toolBar->AddTool(wxID_PASTE, toolBarBitmaps[5], wxNullBitmap, FALSE, -1, -1, (wxObject *) NULL, "Paste"); + toolBar->AddTool(wxID_FIND, toolBarBitmaps[6], wxNullBitmap, FALSE, -1, -1, (wxObject *) NULL, "Search"); + + toolBar->AddSeparator(); + + toolBar->AddTool(ecID_STOP_BUILD, toolBarBitmaps[7], wxNullBitmap, FALSE, -1, -1, (wxObject *) NULL, "Stop build"); + toolBar->AddTool(ecID_BUILD_LIBRARY, toolBarBitmaps[8], wxNullBitmap, FALSE, -1, -1, (wxObject *) NULL, "Build library"); +#if ecUSE_MLT + toolBar->AddSeparator(); + toolBar->AddTool(ecID_NEW_REGION, toolBarBitmaps[10], wxNullBitmap, FALSE, -1, -1, (wxObject *) NULL, "New region"); + toolBar->AddTool(ecID_NEW_SECTION, toolBarBitmaps[11], wxNullBitmap, FALSE, -1, -1, (wxObject *) NULL, "New section"); + toolBar->AddTool(ecID_DELETE, toolBarBitmaps[12], wxNullBitmap, FALSE, -1, -1, (wxObject *) NULL, "Delete"); + toolBar->AddTool(ecID_PROPERTIES, toolBarBitmaps[13], wxNullBitmap, FALSE, -1, -1, (wxObject *) NULL, "Properties"); +#endif + toolBar->AddSeparator(); + toolBar->AddTool(ecID_CONTEXT_HELP, toolBarBitmaps[14], wxNullBitmap, FALSE, -1, -1, (wxObject *) NULL, "Show help for clicked-on windows"); + toolBar->AddTool(ecID_ECOS_HELP, toolBarBitmaps[9], wxNullBitmap, FALSE, -1, -1, (wxObject *) NULL, "Show help"); + + // after adding the buttons to the toolbar, must call Realize() to reflect + // the changes + toolBar->Realize(); + + toolBar->SetHelpText(_("The toolbar allows quick access to commonly-used commands.")); +} + +// Toggle one of the windows +void ecMainFrame::OnToggleWindow(wxCommandEvent& event) +{ + ToggleWindow(event.GetId()); +} + +// Toggle the given window on or off +void ecMainFrame::ToggleWindow(int windowId) +{ + wxWindow* win = NULL; + bool *configSetting = NULL; + switch (windowId) + { + case ecID_TOGGLE_CONFLICTS: + win = m_conflictsSashWindow; + configSetting = & wxGetApp().GetSettings().m_showConflictsWindow; + break; + case ecID_TOGGLE_PROPERTIES: + win = m_propertiesSashWindow; + configSetting = & wxGetApp().GetSettings().m_showPropertiesWindow; + break; + case ecID_TOGGLE_MEMORY: + win = m_memorySashWindow; + configSetting = & wxGetApp().GetSettings().m_showMemoryWindow; + break; + case ecID_TOGGLE_SHORT_DESCR: + win = m_shortDescrSashWindow; + configSetting = & wxGetApp().GetSettings().m_showShortDescrWindow; + break; + case ecID_TOGGLE_OUTPUT: + win = m_outputSashWindow; + configSetting = & wxGetApp().GetSettings().m_showOutputWindow; + break; + } + if (win) + { + bool showing = !win->IsShown(); + + win->Show(showing); + * configSetting = showing; + + // Make sure we don't have ridiculous sizes + if (showing && (windowId == ecID_TOGGLE_CONFLICTS || windowId == ecID_TOGGLE_PROPERTIES || windowId == ecID_TOGGLE_SHORT_DESCR)) + { + m_conflictsSashWindow->SetDefaultSize(wxSize(2000, 50)); + m_propertiesSashWindow->SetDefaultSize(wxSize(2000, 50)); + m_shortDescrSashWindow->SetDefaultSize(wxSize(2000, 50)); + + wxSize frameSize = GetClientSize(); + wxSize configSize = m_configSashWindow->GetSize(); + + if ((frameSize.x - configSize.x) < 5) + { + // We must resize the config window + m_configSashWindow->SetDefaultSize(wxSize(frameSize.x/2, configSize.y)); + } + } + + wxLayoutAlgorithm layout; + layout.LayoutFrame(this); + } +} + +void ecMainFrame::OnUpdateToggleWindow(wxUpdateUIEvent& event) +{ + wxWindow* win = NULL; + switch (event.GetId()) + { + case ecID_TOGGLE_CONFLICTS: + win = m_conflictsSashWindow; + break; + case ecID_TOGGLE_PROPERTIES: + win = m_propertiesSashWindow; + break; + case ecID_TOGGLE_MEMORY: + win = m_memorySashWindow; + break; + case ecID_TOGGLE_SHORT_DESCR: + win = m_shortDescrSashWindow; + break; + case ecID_TOGGLE_OUTPUT: + win = m_outputSashWindow; + break; + } + if (win) + { + event.Enable( TRUE ); + event.Check( win->IsShown() ); + + // Not implemented +#if !ecUSE_MLT + if (event.GetId() == ecID_TOGGLE_MEMORY) + event.Enable( FALSE ); +#endif + } +} + +void ecMainFrame::OnUpdateDisable(wxUpdateUIEvent& event) +{ + event.Enable( FALSE ); +} + +void ecMainFrame::OnToggleToolbar(wxCommandEvent& event) +{ + GetToolBar()->Show( ! GetToolBar()->IsShown() ); + + wxSizeEvent sizeEvent(GetSize(), GetId()); + GetEventHandler()->ProcessEvent(sizeEvent); +#ifdef __WXGTK__ + GtkOnSize( GetPosition().x, GetPosition().y, GetSize().x, GetSize().y); +#endif +} + +void ecMainFrame::OnUpdateToggleToolbar(wxUpdateUIEvent& event) +{ + event.Check( GetToolBar()->IsShown() ); +} + +// Respond to a sash drag operation, by setting the new size +// for this window and then recalculating the layout. +void ecMainFrame::OnSashDrag(wxSashEvent& event) +{ + if (event.GetDragStatus() == wxSASH_STATUS_OUT_OF_RANGE) + return; + + switch (event.GetId()) + { + case ecID_CONFIG_SASH_WINDOW: + { + m_configSashWindow->SetDefaultSize(wxSize(event.GetDragRect().width, 2000)); + break; + } + case ecID_CONFLICTS_SASH_WINDOW: + { + // Change the height of the properties window so we don't affect the + // short description window + int deltaY = event.GetDragRect().height - m_conflictsSashWindow->GetSize().y; + int propertiesHeight = 0; + if (m_propertiesSashWindow->IsShown()) + { + propertiesHeight = m_propertiesSashWindow->GetSize().y - deltaY ; + if (propertiesHeight <= 0) + return; + else + m_propertiesSashWindow->SetDefaultSize(wxSize(2000, propertiesHeight)); + } + m_conflictsSashWindow->SetDefaultSize(wxSize(2000, event.GetDragRect().height)); + break; + } + case ecID_PROPERTIES_SASH_WINDOW: + { + m_propertiesSashWindow->SetDefaultSize(wxSize(2000, event.GetDragRect().height)); + break; + } + case ecID_SHORT_DESCR_SASH_WINDOW: + { + m_shortDescrSashWindow->SetDefaultSize(wxSize(2000, event.GetDragRect().height)); + break; + } + case ecID_MEMORY_SASH_WINDOW: + { + m_memorySashWindow->SetDefaultSize(wxSize(2000, event.GetDragRect().height)); + break; + } + case ecID_OUTPUT_SASH_WINDOW: + { + m_outputSashWindow->SetDefaultSize(wxSize(2000, event.GetDragRect().height)); + break; + } + default: + { + wxFAIL_MSG( _("Shouldn't get here.") ); + break; + } + } + + if (event.GetId() == ecID_MEMORY_SASH_WINDOW || event.GetId() == ecID_OUTPUT_SASH_WINDOW) + { + // Special processing so we don't spoil the layout of the + // conflicts/properties/short description windows + wxList minorWindows; + GetMinorWindows(minorWindows); + + int memoryLayoutHeight = m_memorySashWindow->IsShown() ? m_memorySashWindow->GetSize().y : 0; + int outputHeight = m_memorySashWindow->IsShown() ? m_outputSashWindow->GetSize().y : 0; + int cx, cy; + GetClientSize(& cx, & cy); + + // Calculate how much space will be left after this drag operation. + int heightLeft; + if (event.GetId() == ecID_MEMORY_SASH_WINDOW) + heightLeft = cy - outputHeight - event.GetDragRect().height; + else + heightLeft = cy - memoryLayoutHeight - event.GetDragRect().height; + + DivideSpaceEvenly(minorWindows, wxSize(0, heightLeft), wxVERTICAL); + RestoreDefaultWindowSizes(minorWindows); + } + + wxLayoutAlgorithm layout; + if (!layout.LayoutFrame(this)) + { + // If layout failed, restored default sizes. + wxNode* node = GetChildren().First(); + while (node) + { + wxWindow* win = (wxWindow*) node->Data(); + if (win->IsKindOf(CLASSINFO(wxSashLayoutWindow))) + { + wxSashLayoutWindow* sashWin = (wxSashLayoutWindow*) win; + wxSize sz = sashWin->GetSize(); + sashWin->SetDefaultSize(sz); + } + node = node->Next(); + } + } + +} + +void ecMainFrame::OnIdle(wxIdleEvent& event) +{ + // Normal idle processing + wxFrame::OnIdle(event); + + wxString text; + if (GetStatusBar()) + text = GetStatusBar()->GetStatusText(0); + + // Set the title if we have no document + if (!wxGetApp().GetConfigToolDoc() && GetTitle() != wxGetApp().GetSettings().GetAppName()) + SetTitle(wxGetApp().GetSettings().GetAppName()); + + if ( wxGetApp().m_pipedProcess && wxGetApp().m_pipedProcess->HasInput() ) + { + event.RequestMore(); + } + + if ( wxGetApp().m_pipedProcess ) + { + if (text != _("Building...")) + SetStatusText(_("Building..."), 0); + } + else if (text != _("Ready")) + SetStatusText(_("Ready"), 0); +} + +void ecMainFrame::OnCloseWindow(wxCloseEvent& event) +{ + if (!wxGetApp().GetDocManager()->Clear(FALSE) && event.CanVeto()) + { + event.Veto(); + return; + } + if (wxGetApp().m_pipedProcess) + wxGetApp().m_pipedProcess->Detach(); + + if (m_findDialog) + m_findDialog->Close(TRUE); + + wxGetApp().DestroyHelpController(); + + if (IsMaximized()) + wxGetApp().GetSettings().m_frameStatus = ecSHOW_STATUS_MAXIMIZED ; + else if (IsIconized()) + wxGetApp().GetSettings().m_frameStatus = ecSHOW_STATUS_MINIMIZED ; + else + wxGetApp().GetSettings().m_frameStatus = ecSHOW_STATUS_NORMAL ; + + if (!IsMaximized() && !IsIconized()) + wxGetApp().GetSettings().m_frameSize = GetRect(); + + wxGetApp().GetSettings().m_showToolBar = GetToolBar()->IsShown(); + + wxGetApp().GetSettings().m_treeSashSize = m_configSashWindow->GetSize(); + wxGetApp().GetSettings().m_propertiesSashSize = m_propertiesSashWindow->GetSize(); + wxGetApp().GetSettings().m_conflictsSashSize = m_conflictsSashWindow->GetSize(); + wxGetApp().GetSettings().m_shortDescrSashSize = m_shortDescrSashWindow->GetSize(); + wxGetApp().GetSettings().m_memorySashSize = m_memorySashWindow->GetSize(); + wxGetApp().GetSettings().m_outputSashSize = m_outputSashWindow->GetSize(); + + event.Skip(); +} + +// Enumerate the visible 'minor' sash windows, +// i.e. those in the top-right segment of the frame +void ecMainFrame::GetMinorWindows(wxList& list) +{ + if (m_conflictsSashWindow->IsShown()) + list.Append(m_conflictsSashWindow); + if (m_propertiesSashWindow->IsShown()) + list.Append(m_propertiesSashWindow); + if (m_shortDescrSashWindow->IsShown()) + list.Append(m_shortDescrSashWindow); +} + +// Get all visible sash windows +void ecMainFrame::GetSashWindows(wxList& list) +{ + wxNode* node = GetChildren().First(); + while (node) + { + wxWindow* win = (wxWindow*) node->Data(); + if (win->IsKindOf(CLASSINFO(wxSashLayoutWindow)) && win->IsShown()) + { + list.Append(win); + } + node = node->Next(); + } +} + +// Divide the given space evenly amongst some windows +void ecMainFrame::DivideSpaceEvenly(wxList& list, const wxSize& space, int orient) +{ + if (list.Number() == 0) + return; + + // Find total size first + int totalSize = 0; + double proportion = 0.0; + wxNode* node = list.First(); + while (node) + { + wxWindow* win = (wxWindow*) node->Data(); + wxSize sz = win->GetSize(); + if (orient == wxHORIZONTAL) + totalSize += sz.x; + else + totalSize += sz.y; + node = node->Next(); + } + if (orient == wxHORIZONTAL) + { + if (totalSize == 0) + return; + + proportion = ((double) space.x / (double) totalSize); + } + else + { + if (totalSize == 0) + return; + + proportion = ((double) space.y / (double) totalSize); + } + node = list.First(); + while (node) + { + wxWindow* win = (wxWindow*) node->Data(); + wxSize sz = win->GetSize(); + if (orient == wxHORIZONTAL) + sz.x = (int) (sz.x * proportion); + else + sz.y = (int) (sz.y * proportion); + win->SetSize(sz); + node = node->Next(); + } +} + +// Restore the sash window default size from the actual window size +void ecMainFrame::RestoreDefaultWindowSizes(wxList& list) +{ + wxNode* node = list.First(); + while (node) + { + wxSashLayoutWindow* sashWin = (wxSashLayoutWindow*) node->Data(); + wxSize sz = sashWin->GetSize(); + sashWin->SetDefaultSize(sz); + node = node->Next(); + } +} + +void ecMainFrame::OnHelpEcos(wxCommandEvent& event) +{ + ecConfigToolDoc* doc = wxGetApp().GetConfigToolDoc(); + if (doc) + { + wxString strURL(wxT("index.html")); + doc->QualifyDocURL(strURL, FALSE); + switch (wxGetApp().GetSettings().m_eUseCustomBrowser) + { + case ecInternal: + { + if (wxGetApp().HasHelpController()) + wxGetApp().GetHelpController().DisplayContents(); + break; + } + default: + { + doc->ShowURL(strURL); + } + } + } +} + +void ecMainFrame::OnHelpConfigtool(wxCommandEvent& event) +{ + //wxString strURL(wxT("redirect/the-ecos-configuration-tool.html")); + wxString strURL(wxGetApp().GetFullAppPath(wxT("manual/user-guides.2.html"))); + + if (wxGetApp().GetConfigToolDoc()) + { + wxGetApp().GetConfigToolDoc()->ShowURL(strURL); + } +} + +void ecMainFrame::OnHelpContext(wxCommandEvent& event) +{ + wxContextHelp contextHelp; +} + +void ecMainFrame::OnResolveConflicts(wxCommandEvent& event) +{ +/* + ecResolveConflictsDialog dialog(this); + dialog.ShowModal(); +*/ + if ( ecConfigToolDoc::NotDone == wxGetApp().GetConfigToolDoc()->ResolveGlobalConflicts() ) + { + // Global inference handler was never invoked. Say something + wxString msg; + msg.Printf(_("No solutions can be automatically determined for the current set of conflicts.")); + wxMessageBox(msg, wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxOK); + } +} + +void ecMainFrame::OnUpdateResolveConflicts(wxUpdateUIEvent& event) +{ + if (!wxGetApp().GetConfigToolDoc() || !wxGetApp().GetConfigToolDoc()->GetCdlInterpreter()) + { + event.Enable(FALSE); + return; + } + + event.Enable(wxGetApp().GetConfigToolDoc()->GetCdlInterpreter()->get_toplevel()->get_all_conflicts().size()>0); +} + +void ecMainFrame::OnSettings(wxCommandEvent& event) +{ + ecSettingsDialog dialog(this); + dialog.ShowModal(); +} + +void ecMainFrame::OnPlatforms(wxCommandEvent& event) +{ + ecPlatformsDialog dialog(this); + if (dialog.ShowModal() == wxID_OK) + { + CeCosTestPlatform::RemoveAllPlatforms(); + unsigned int i ; + for(i=0; i < dialog.PlatformCount();i++){ + CeCosTestPlatform::Add(*dialog.Platform(i)); + } + CeCosTestPlatform::Save(); + } +} + +void ecMainFrame::OnBuildOptions(wxCommandEvent& event) +{ + ecBuildOptionsDialog dialog(this); + dialog.ShowModal(); +} + +void ecMainFrame::OnTemplates(wxCommandEvent& event) +{ + ecTemplatesDialog dialog(this); + if (dialog.ShowModal() == wxID_OK) + { + ecConfigToolDoc* doc = wxGetApp().GetConfigToolDoc(); + + doc->SelectHardware(dialog.GetSelectedHardware()); + doc->SelectTemplate(dialog.GetSelectedTemplate(), dialog.GetSelectedTemplateVersion()); + } +} + +void ecMainFrame::OnAdmin(wxCommandEvent& event) +{ + ecConfigToolDoc* doc = wxGetApp().GetConfigToolDoc(); + + wxASSERT (doc) ; + + if (wxYES == wxMessageBox(_("This command will close the current document.\n\nDo you wish to continue?"), + wxGetApp().GetAppName(), wxYES_NO, this)) + { + wxString shellCommands; + // ensure that the user tools are on the path for use by ecosadmin.tcl + // TODO: need to something else for Linux (since it returns settings in shellCommands) + if (wxGetApp().PrepareEnvironment(FALSE, & shellCommands)) + { + // make sure we use doc data before the doc is destroyed + + ecAdminDialog dlg(this, doc->GetPackagesDir(), wxGetApp().GetSettings().GetUserToolsDir()); + + if (dlg.ShowModal() == wxID_OK) + { + // Create new document + wxGetApp().GetDocManager()->CreateDocument(wxEmptyString, wxDOC_NEW); + } + } + } +} + +void ecMainFrame::OnPackages(wxCommandEvent& event) +{ + ecConfigToolDoc* doc = wxGetApp().GetConfigToolDoc(); + if (doc) + doc->SelectPackages(); +} + +void ecMainFrame::OnRunTests(wxCommandEvent& event) +{ + ecConfigToolDoc* doc = wxGetApp().GetConfigToolDoc(); + if (doc) + doc->RunTests(); +} + +void ecMainFrame::OnChooseRepository(wxCommandEvent& event) +{ + ecConfigToolDoc* doc = wxGetApp().GetConfigToolDoc(); + if (doc && !doc->OnSaveModified()) + return; + + if (!doc) + { + doc = (ecConfigToolDoc*) wxGetApp().GetDocManager()->CreateDocument(wxString(""), wxDOC_NEW|ecDOC_PROMPT_FOR_REPOSITORY); + return; + } + + if (doc) + doc->m_bRepositoryOpen = FALSE; + + if (wxGetApp().GetConfigToolDoc()->OpenRepository(wxEmptyString, TRUE)) + { + // TODO +#if 0 + // reset the document title as shown in the frame window + GetDocTemplate ()->SetDefaultTitle (this); + + // load the memory layout for the default target-platform-startup from the new repository + NewMemoryLayout (CFileName (m_strPackagesDir, m_strMemoryLayoutFolder, _T("include\\pkgconf"))); +#endif + + doc->UpdateAllViews(NULL); + doc->UpdateFailingRuleCount(); + } + else + { + if (doc) + doc->m_bRepositoryOpen = TRUE; + } +} + +void ecMainFrame::OnBuildToolsPath(wxCommandEvent& event) +{ + ecConfigToolDoc* doc = wxGetApp().GetConfigToolDoc(); + if (!doc) + return; + + // Add all the paths from the bin dirs to the path array, + // making the default path the appropriate target prefix + wxString defaultPath; + const wxString strPrefix(doc->GetCurrentTargetPrefix()); + wxArrayString arstrPaths; + + wxStringToStringMap& map = wxGetApp().GetSettings().GetBinDirs(); + map.BeginFind(); + wxString key, value; + while (map.Next(key, value)) + { + arstrPaths.Add(value); + if (key == strPrefix) + defaultPath = value; + } + + wxString msg; + msg.Printf(_("Enter the location of the %s build tools\n" + "folder, which should contain %sgcc. You can\n" + "type in a path or use the Browse button to\n" + "navigate to a folder."), + (const wxChar*) (strPrefix.IsEmpty() ? wxString(wxT("native")) : strPrefix), + (const wxChar*) (strPrefix.IsEmpty() ? wxString(wxT("")) : strPrefix + wxT("-")) + ); + wxString caption(_("Build Tools Path")); + + ecFolderDialog dialog(defaultPath, arstrPaths, msg, this, ecID_BUILD_TOOLS_DIALOG, caption); + if (dialog.ShowModal() == wxID_OK) + { + ecFileName strExe; + +#ifdef __WXMSW__ + wxString exeSuffix(wxT(".exe")); +#else + wxString exeSuffix(wxEmptyString); +#endif + wxString path(dialog.GetPath()); + strExe.Printf(wxT("%s%c%s%sgcc%s"), (const wxChar*) path, wxFILE_SEP_PATH, (const wxChar*) strPrefix, + (const wxChar*) strPrefix.IsEmpty() ? wxT("") : wxT("-"), (const wxChar*) exeSuffix); + + wxString msg; + msg.Printf(wxT("%s does not appear to contain the build tools - use this folder anyway?"), (const wxChar*) path); + + if(strExe.Exists() || + (wxID_YES == wxMessageBox(msg, wxGetApp().GetSettings().GetAppName(), wxICON_QUESTION|wxYES_NO))) + { + map.Set(strPrefix, path); + } + } +} + +void ecMainFrame::OnUserToolsPath(wxCommandEvent& event) +{ + ecConfigToolDoc* doc = wxGetApp().GetConfigToolDoc(); + if (!doc) + return; + + wxArrayString paths = wxGetApp().GetSettings().m_userToolPaths; + if (!wxGetApp().GetSettings().m_userToolsDir.IsEmpty()) + paths.Add(wxGetApp().GetSettings().m_userToolsDir); + + wxString msg(_("Enter the location of the user tools folder,\n" + "which should contain cat and ls. You can type in\n" + "a path or use the Browse button to navigate to a\n" + "folder.")); + + wxString caption(_("User Tools Path")); + wxString defaultPath(wxGetApp().GetSettings().m_userToolsDir); + + ecFolderDialog dialog(defaultPath, paths, msg, this, ecID_USER_TOOLS_DIALOG, caption); + if (dialog.ShowModal() == wxID_OK) + { + wxString path(dialog.GetPath()); + ecFileName strFile(path); + +#ifdef __WXMSW__ + wxString exeSuffix(wxT(".exe")); +#else + wxString exeSuffix(wxEmptyString); +#endif + + strFile += wxT("ls"); + strFile += (const wxChar*) exeSuffix; + + wxString msg; + msg.Printf(wxT("%s does not appear to contain the user tools - use this folder anyway?"), (const wxChar*) path); + + if(strFile.Exists() || + (wxID_YES == wxMessageBox(msg, wxGetApp().GetSettings().GetAppName(), wxICON_QUESTION|wxYES_NO))) + { + wxGetApp().GetSettings().m_userToolsDir = path; + } + } +} + +// Process events for the window with the focus first. +bool ecMainFrame::ProcessEvent(wxEvent& event) +{ + static wxEvent* s_lastEvent = NULL; + + if (& event == s_lastEvent) + return FALSE; + + if (event.IsCommandEvent()) + { + s_lastEvent = & event; + + wxWindow* focusWin = wxFindFocusDescendant(this); + bool success = FALSE; + if (focusWin) + { + //long windowId = focusWin->GetId(); + //wxLogDebug("Found focus window %d", windowId); + success = focusWin->GetEventHandler()->ProcessEvent(event); + } + if (!success) + success = wxDocParentFrame::ProcessEvent(event); + + s_lastEvent = NULL; + return success; + } + else + { + return wxDocParentFrame::ProcessEvent(event); + } +} + +void ecMainFrame::SetFailRulePane(int nCount) +{ + wxString strCount; + switch (nCount) + { + case 0: + strCount = wxT("No conflicts"); + break; + case 1: + strCount = wxT("1 conflict"); + break; + default: + strCount.Printf (_("%d conflicts"), nCount); + break; + } + if (GetStatusBar()) + { + GetStatusBar()->SetStatusText(strCount, ecFailRulePane); + } +} + +// Update the title, either via the document's view or explicitly if no doc +void ecMainFrame::UpdateFrameTitle() +{ + if (wxGetApp().GetConfigToolDoc()) + wxGetApp().GetConfigToolDoc()->GetFirstView()->OnChangeFilename(); + else + SetTitle(wxGetApp().GetSettings().GetAppName()); +} + +void ecMainFrame::OnUpdatePlatforms(wxUpdateUIEvent& event) +{ + event.Enable(TRUE); +} + +void ecMainFrame::OnUpdateBuildOptions(wxUpdateUIEvent& event) +{ + event.Enable(wxGetApp().GetConfigToolDoc() != NULL); +} + +void ecMainFrame::OnUpdateBuildToolsPath(wxUpdateUIEvent& event) +{ + event.Enable(wxGetApp().GetConfigToolDoc() != NULL); +} + +void ecMainFrame::OnUpdateUserToolsPath(wxUpdateUIEvent& event) +{ + event.Enable(wxGetApp().GetConfigToolDoc() != NULL); +} + +void ecMainFrame::OnUpdateTemplates(wxUpdateUIEvent& event) +{ + event.Enable(wxGetApp().GetConfigToolDoc() != NULL); +} + +void ecMainFrame::OnUpdateAdmin(wxUpdateUIEvent& event) +{ + event.Enable(wxGetApp().GetConfigToolDoc() != NULL); +} + +void ecMainFrame::OnUpdatePackages(wxUpdateUIEvent& event) +{ + event.Enable(wxGetApp().GetConfigToolDoc() != NULL); +} + +void ecMainFrame::OnUpdateRunTests(wxUpdateUIEvent& event) +{ +#ifdef __WXDEBUG__ + event.Enable(wxGetApp().GetConfigToolDoc() != NULL && !wxGetApp().GetConfigToolDoc()->GetInstallTree().IsEmpty() && (wxGetApp().m_pipedProcess == NULL)); +#else + // TODO: Not implemented yet + event.Enable( FALSE ); +#endif +} + +void ecMainFrame::OnUpdateChooseRepository(wxUpdateUIEvent& event) +{ + event.Enable(TRUE); +} + +void ecMainFrame::OnWhatsThis(wxCommandEvent& event) +{ + wxGetApp().OnWhatsThis(event); +} + +void ecMainFrame::OnSaveOutput(wxCommandEvent& event) +{ + ecOutputWindow* win = GetOutputWindow(); + if (!win) + return; + + wxFileDialog dialog(this, _("Choose a file for saving the output window contents"), + wxT(""), wxT("output.txt"), wxT("*.txt"), wxSAVE|wxOVERWRITE_PROMPT); + if (dialog.ShowModal() == wxID_OK) + { + if (!win->SaveFile(dialog.GetPath())) + { + wxMessageBox(_("Sorry, there was a problem saving the file."), wxGetApp().GetSettings().GetAppName(), + wxICON_EXCLAMATION|wxID_OK); + } + } +} + +void ecMainFrame::OnUpdateSelectAll(wxUpdateUIEvent& event) +{ + wxWindow* win = wxWindow::FindFocus(); + event.Enable (win && win->IsKindOf(CLASSINFO(wxTextCtrl)) ); +} + +void ecMainFrame::OnUpdateClear(wxUpdateUIEvent& event) +{ + wxWindow* win = wxWindow::FindFocus(); + event.Enable (win && win->IsKindOf(CLASSINFO(wxTextCtrl)) ); +} + +void ecMainFrame::OnImport(wxCommandEvent& event) +{ + if (wxGetApp().GetConfigToolDoc()) + { + wxGetApp().GetConfigToolDoc()->ImportFile(); + } +} + +void ecMainFrame::OnExport(wxCommandEvent& event) +{ + if (wxGetApp().GetConfigToolDoc()) + { + wxGetApp().GetConfigToolDoc()->ExportFile(); + } +} + +void ecMainFrame::OnUpdateImport(wxUpdateUIEvent& event) +{ + event.Enable ( wxGetApp().GetConfigToolDoc() != NULL ); +} + +void ecMainFrame::OnUpdateExport(wxUpdateUIEvent& event) +{ + event.Enable ( wxGetApp().GetConfigToolDoc() != NULL ); +} + +void ecMainFrame::OnWebRedHatHome(wxCommandEvent& event) +{ + wxString strURL(wxT("http://www.redhat.com")); + if (wxGetApp().GetConfigToolDoc()) + wxGetApp().GetConfigToolDoc()->ShowURL(strURL); +} + +void ecMainFrame::OnWebEcos(wxCommandEvent& event) +{ + wxString strURL(wxT("http://www.redhat.com/products/ecos")); + if (wxGetApp().GetConfigToolDoc()) + wxGetApp().GetConfigToolDoc()->ShowURL(strURL); +} + +void ecMainFrame::OnWebNetRelease(wxCommandEvent& event) +{ + wxString strURL(wxT("http://sources.redhat.com/ecos")); + if (wxGetApp().GetConfigToolDoc()) + wxGetApp().GetConfigToolDoc()->ShowURL(strURL); +} + +void ecMainFrame::OnWebUitron(wxCommandEvent& event) +{ + wxString strURL(wxT("http://www.itron.gr.jp/")); + if (wxGetApp().GetConfigToolDoc()) + wxGetApp().GetConfigToolDoc()->ShowURL(strURL); +} + +void ecMainFrame::OnBuildLibrary(wxCommandEvent& event) +{ + wxGetApp().Build(); +} + +void ecMainFrame::OnBuildTests(wxCommandEvent& event) +{ + wxGetApp().Build(wxT("tests")); +} + +void ecMainFrame::OnStopBuild(wxCommandEvent& event) +{ + if (wxGetApp().m_pipedProcess) + wxGetApp().m_pipedProcess->Detach(); +} + +void ecMainFrame::OnClean(wxCommandEvent& event) +{ + wxGetApp().Build(wxT("clean")); +} + +void ecMainFrame::OnShell(wxCommandEvent& event) +{ + ecConfigToolDoc *pDoc=wxGetApp().GetConfigToolDoc(); + if (!pDoc) + return; + + wxString variableSettings; + if (wxGetApp().PrepareEnvironment(TRUE, & variableSettings)) + { +#ifdef __WXMSW__ + wxString currentDir = wxGetCwd(); + wxSetWorkingDirectory(pDoc->GetBuildTree()); + + wxExecute("bash.exe"); + + if (!currentDir.IsEmpty()) // if the current directory was changed + { + wxSetWorkingDirectory(currentDir); // restore the previous current directory + } +#else + wxString cmdLine = wxString(wxT("xterm")); + + // TODO: query an appropriate variable, and/or have a setting for this + wxExecute(cmdLine); +#endif + } +} + +void ecMainFrame::OnUpdateBuildLibrary(wxUpdateUIEvent& event) +{ + event.Enable( (wxGetApp().GetConfigToolDoc() != NULL) && (wxGetApp().m_pipedProcess == NULL )); +} + +void ecMainFrame::OnUpdateBuildTests(wxUpdateUIEvent& event) +{ + event.Enable( (wxGetApp().GetConfigToolDoc() != NULL) && (wxGetApp().m_pipedProcess == NULL )); +} + +void ecMainFrame::OnUpdateStopBuild(wxUpdateUIEvent& event) +{ + event.Enable( (wxGetApp().GetConfigToolDoc() != NULL) && (wxGetApp().m_pipedProcess != NULL )); +} + +void ecMainFrame::OnUpdateClean(wxUpdateUIEvent& event) +{ + event.Enable( (wxGetApp().GetConfigToolDoc() != NULL) && (wxGetApp().m_pipedProcess == NULL )); +} + +void ecMainFrame::OnRepositoryInfo(wxCommandEvent& event) +{ + ecRepositoryInfoDialog dialog(this, ecID_REPOSITORY_INFO, _("Repository Information")); + dialog.ShowModal(); +} + +void ecMainFrame::OnUpdateShell(wxUpdateUIEvent& event) +{ + event.Enable( (wxGetApp().GetConfigToolDoc() != NULL) ); +} + +void ecMainFrame::OnUpdateRepositoryInfo(wxUpdateUIEvent& event) +{ + event.Enable( (wxGetApp().GetConfigToolDoc() != NULL) ); +} + +void ecMainFrame::OnNewRegion(wxCommandEvent& event) +{ +#if ecUSE_MLT +#endif +} + +void ecMainFrame::OnNewSection(wxCommandEvent& event) +{ +#if ecUSE_MLT +#endif +} + +void ecMainFrame::OnDeleteRegionOrSection(wxCommandEvent& event) +{ +#if ecUSE_MLT +#endif +} + +void ecMainFrame::OnRegionOrSectionProperties(wxCommandEvent& event) +{ +#if ecUSE_MLT +#endif +} + +void ecMainFrame::OnUpdateNewRegion(wxUpdateUIEvent& event) +{ +#if ecUSE_MLT +#else + event.Enable( FALSE ); +#endif +} + +void ecMainFrame::OnUpdateNewSection(wxUpdateUIEvent& event) +{ +#if ecUSE_MLT +#else + event.Enable( FALSE ); +#endif +} + +void ecMainFrame::OnUpdateDeleteRegionOrSection(wxUpdateUIEvent& event) +{ +#if ecUSE_MLT +#else + event.Enable( FALSE ); +#endif +} + +void ecMainFrame::OnUpdateRegionOrSectionProperties(wxUpdateUIEvent& event) +{ +#if ecUSE_MLT +#else + event.Enable( FALSE ); +#endif +} + +void ecMainFrame::OnIndexDocs(wxCommandEvent& event) +{ + ecConfigToolDoc* doc = wxGetApp().GetConfigToolDoc(); + if (doc) + { + doc->RebuildHelpIndex(TRUE) ; + } +} + +void ecMainFrame::OnUpdateIndexDocs(wxUpdateUIEvent& event) +{ + event.Enable( wxGetApp().GetConfigToolDoc() != NULL ); +} diff --git a/host/tools/configtool/standalone/wxwin/mainwin.h b/host/tools/configtool/standalone/wxwin/mainwin.h new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/mainwin.h @@ -0,0 +1,234 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +// mainwin.h : +// +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): julians +// Contact(s): julians +// Date: 2000/08/24 +// Version: $Id: mainwin.h,v 1.17 2001/04/24 17:01:45 julians Exp $ +// Purpose: +// Description: Header file for the ConfigTool main window +// Requires: +// Provides: +// See also: +// Known bugs: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== + +#ifndef _ECOS_MAINWIN_H_ +#define _ECOS_MAINWIN_H_ + +#ifdef __GNUG__ +#pragma interface "mainwin.h" +#endif + +#include "wx/wx.h" +#include "wx/docview.h" + +#include "splittree.h" + +/* + * Status bar panes + */ + +#define ecStatusPane 0 +#define ecFailRulePane 3 + +class ecValueWindow; +class ecOutputWindow; +class ecConfigTreeCtrl; +class ecShortDescriptionWindow; +class ecPropertyListCtrl; +class ecConflictListCtrl; +class ecFindDialog; +class WXDLLEXPORT wxSashLayoutWindow; + +// Define a new frame type: this is going to be our main frame +class ecMainFrame : public wxDocParentFrame +{ + friend ecFindDialog; + +public: +// Ctor(s) + ecMainFrame(wxDocManager *manager, const wxString& title, const wxPoint& pos, const wxSize& size); + +//// Event handlers + + void OnQuit(wxCommandEvent& event); + void OnAbout(wxCommandEvent& event); + void OnFind(wxCommandEvent& event); + void OnFindNext(wxCommandEvent& event); + void OnSize(wxSizeEvent& event); + void OnIdle(wxIdleEvent& event); + void OnCloseWindow(wxCloseEvent& event); + void OnHelpEcos(wxCommandEvent& event); + void OnHelpConfigtool(wxCommandEvent& event); + void OnHelpContext(wxCommandEvent& event); + void OnResolveConflicts(wxCommandEvent& event); + void OnSettings(wxCommandEvent& event); + void OnPlatforms(wxCommandEvent& event); + void OnBuildOptions(wxCommandEvent& event); + void OnTemplates(wxCommandEvent& event); + void OnAdmin(wxCommandEvent& event); + void OnPackages(wxCommandEvent& event); + void OnRunTests(wxCommandEvent& event); + void OnChooseRepository(wxCommandEvent& event); + void OnBuildToolsPath(wxCommandEvent& event); + void OnUserToolsPath(wxCommandEvent& event); + void OnWhatsThis(wxCommandEvent& event); + void OnSaveOutput(wxCommandEvent& event); + void OnImport(wxCommandEvent& event); + void OnExport(wxCommandEvent& event); + void OnBuildLibrary(wxCommandEvent& event); + void OnBuildTests(wxCommandEvent& event); + void OnStopBuild(wxCommandEvent& event); + void OnClean(wxCommandEvent& event); + void OnShell(wxCommandEvent& event); + + void OnNewRegion(wxCommandEvent& event); + void OnNewSection(wxCommandEvent& event); + void OnDeleteRegionOrSection(wxCommandEvent& event); + void OnRegionOrSectionProperties(wxCommandEvent& event); + + void OnWebRedHatHome(wxCommandEvent& event); + void OnWebEcos(wxCommandEvent& event); + void OnWebNetRelease(wxCommandEvent& event); + void OnWebUitron(wxCommandEvent& event); + void OnRepositoryInfo(wxCommandEvent& event); + void OnIndexDocs(wxCommandEvent& event); + + void OnUpdatePlatforms(wxUpdateUIEvent& event); + void OnUpdateBuildOptions(wxUpdateUIEvent& event); + void OnUpdateBuildToolsPath(wxUpdateUIEvent& event); + void OnUpdateUserToolsPath(wxUpdateUIEvent& event); + void OnUpdateTemplates(wxUpdateUIEvent& event); + void OnUpdateAdmin(wxUpdateUIEvent& event); + void OnUpdatePackages(wxUpdateUIEvent& event); + void OnUpdateRunTests(wxUpdateUIEvent& event); + void OnUpdateChooseRepository(wxUpdateUIEvent& event); + void OnUpdateResolveConflicts(wxUpdateUIEvent& event); + void OnUpdateSelectAll(wxUpdateUIEvent& event); + void OnUpdateClear(wxUpdateUIEvent& event); + void OnUpdateImport(wxUpdateUIEvent& event); + void OnUpdateExport(wxUpdateUIEvent& event); + void OnUpdateBuildLibrary(wxUpdateUIEvent& event); + void OnUpdateBuildTests(wxUpdateUIEvent& event); + void OnUpdateStopBuild(wxUpdateUIEvent& event); + void OnUpdateClean(wxUpdateUIEvent& event); + void OnUpdateRepositoryInfo(wxUpdateUIEvent& event); + void OnUpdateShell(wxUpdateUIEvent& event); + void OnUpdateFind(wxUpdateUIEvent& event); + void OnUpdateFindNext(wxUpdateUIEvent& event); + void OnUpdateIndexDocs(wxUpdateUIEvent& event); + + void OnUpdateNewRegion(wxUpdateUIEvent& event); + void OnUpdateNewSection(wxUpdateUIEvent& event); + void OnUpdateDeleteRegionOrSection(wxUpdateUIEvent& event); + void OnUpdateRegionOrSectionProperties(wxUpdateUIEvent& event); + + // Toggle windows + void OnToggleWindow(wxCommandEvent& event); + void OnUpdateToggleWindow(wxUpdateUIEvent& event); + void OnToggleToolbar(wxCommandEvent& event); + void OnUpdateToggleToolbar(wxUpdateUIEvent& event); + void OnUpdateDisable(wxUpdateUIEvent& event); + +//// Operations + // (Re)create the toolbar + void RecreateToolbar(); + + // Create the windows + void CreateWindows(); + + // Respond to a sash drag operation + void OnSashDrag(wxSashEvent& event); + + // Enumerate the visible 'minor' sash windows, + // i.e. those in the top-right segment of the frame + void GetMinorWindows(wxList& list); + + // Get all visible sash windows + void GetSashWindows(wxList& list); + + // Divide the given space evenly amongst some windows + void DivideSpaceEvenly(wxList& list, const wxSize& space, int orient); + + // Restore the sash window default size from the actual window size + void RestoreDefaultWindowSizes(wxList& list); + + void SetFailRulePane(int nCount); + + // Toggle the given window on or off + void ToggleWindow(int windowId); + + // Update the title, either via the document's view or explicitly if no doc + void UpdateFrameTitle(); + +//// Accessors + ecOutputWindow* GetOutputWindow() const { return m_outputWindow; } + ecConfigTreeCtrl* GetTreeCtrl() const { return m_tree; } + ecValueWindow* GetValueWindow() const { return m_valueWindow; } + ecShortDescriptionWindow* GetShortDescriptionWindow() const { return m_shortDescrWindow; } + ecPropertyListCtrl* GetPropertyListWindow() const { return m_propertyListWindow; } + ecConflictListCtrl* GetConflictsWindow() const { return m_conflictsWindow; } + ecMemoryLayoutWindow* GetMemoryLayoutWindow() const { return m_mltWindow; } + +//// Overrides + + virtual bool ProcessEvent(wxEvent& event); + +protected: + ecConfigTreeCtrl* m_tree; + wxThinSplitterWindow* m_splitter; + wxSplitterScrolledWindow* m_scrolledWindow; + ecValueWindow* m_valueWindow; + ecOutputWindow* m_outputWindow; + ecShortDescriptionWindow* m_shortDescrWindow; + ecPropertyListCtrl* m_propertyListWindow; + ecConflictListCtrl* m_conflictsWindow; + ecFindDialog* m_findDialog; + ecMemoryLayoutWindow* m_mltWindow; + + // Sash layout windows, that contain the 'real' windows + wxSashLayoutWindow* m_configSashWindow; + wxSashLayoutWindow* m_conflictsSashWindow; + wxSashLayoutWindow* m_propertiesSashWindow; + wxSashLayoutWindow* m_memorySashWindow; + wxSashLayoutWindow* m_shortDescrSashWindow; + wxSashLayoutWindow* m_outputSashWindow; + +private: + DECLARE_EVENT_TABLE() +}; + + +#endif + // _ECOS_MAINWIN_H_ diff --git a/host/tools/configtool/standalone/wxwin/makect.sh b/host/tools/configtool/standalone/wxwin/makect.sh new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/makect.sh @@ -0,0 +1,26 @@ +#!/bin/sh +# A shell script for helping to compile the Configuration Tool + +LEVEL=$1 +TARGET="$2 $3 $4 $5 $6 $7 $8 $9" + +if [ "$1" = "" ] || [ "$2" = "" ]; then + echo Usage: makect debug/release full/wx/ct/ecc/cleanall + exit +fi + +if [ "$LEVEL" != "debug" ] && [ "$LEVEL" != "release" ]; then + echo First argument should be debug or release. + exit +fi + +ECOSDIR=/home/julians/cvs/eCos + +# Necessary if you are using a local version of the compiler +# and these haven't been installed +export BISON_SIMPLE=/usr/lib/bison.simple +export BISON_HAIRY=/usr/lib/bison.hairy +export ECOSDIR +export CONFIGTOOLSRCDIR=$ECOSDIR/host/tools/configtool/standalone/wxwin +export WXDIR=/home/julians/local/wx2dev/wxWindows +make -f ${CONFIGTOOLSRCDIR}/Makefile WXDIR=$WXDIR ECOSDIR=$ECOSDIR LEVEL=$LEVEL $TARGET \ No newline at end of file diff --git a/host/tools/configtool/standalone/wxwin/makefile.vc b/host/tools/configtool/standalone/wxwin/makefile.vc new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/makefile.vc @@ -0,0 +1,19 @@ +# Makefile : Builds ConfigTool (VC++, WIN32) +# Use FINAL=1 argument to nmake to build final version with no debug info. +# Created 2000-07-28 + +# Set WXDIR for your system +WXDIR = $(WXWIN) +FINAL=0 +PROGRAM=configtool +OBJECTS = $(PROGRAM).obj appsettings.obj configitem.obj configtree.obj mainwin.obj + +!if "$(FINAL)" == "0" +EXTRALIBS=$(WXDIR)\lib\gizmosd.lib +!else +EXTRALIBS=$(WXDIR)\lib\gizmos.lib +!endif + +!include $(WXDIR)\src\makeprog.vc + + diff --git a/host/tools/configtool/standalone/wxwin/manual/botclear.gif b/host/tools/configtool/standalone/wxwin/manual/botclear.gif new file mode 100644 index 0000000000000000000000000000000000000000..0b907f94585297d0f8b40d04c8459a9db4a0b857 GIT binary patch literal 194 zc$@*k06qUlNk%w1VE_aW0FeLy|NsA#t=<3t00000EC2ui000CK06+qpjE||y?GK}z zwAzca-n{z{hT=$;=82~2%C_zc$MQ_q_KoNI&iDQg3<`(DqVb4KDwoWr^9hYgr_`$T zip^@b+^+Wv4vWX+viXcotJmzd`wfrF=k&V$j?e4&{J#GW7$`VMSZH{Nn5ekO*y#8O w87VnQS!sERnW?$S+3EQS8Y((UT55WVnyR|W+UoiW8!J0YTWfoZD^>siI~0Io=>Px# diff --git a/host/tools/configtool/standalone/wxwin/manual/cygnus.css b/host/tools/configtool/standalone/wxwin/manual/cygnus.css new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/manual/cygnus.css @@ -0,0 +1,1369 @@ +A:link { + color: blue; +} +A:visited { + color: purple; +} +EM.Arrow { + font-family: Arial; +} +A:active { + color: red; +} +OL { + font-size: 12.000000pt; + font-weight: medium; + text-decoration: none; + font-family: Times; +} +UL +{ + LIST-STYLE-type: DISC + font-size: 12.000000pt; + font-weight: medium; + text-decoration: none; + vertical-align: baseline; + font-family: Times; +} +P.ActiveIX { + text-align: justify; + font-size: 12.000000pt; + font-weight: medium; + text-decoration: none; + vertical-align: baseline; + font-family: Times New Roman; +} +P.ActiveTOC { + text-align: justify; + font-size: 12.000000pt; + font-weight: medium; + text-decoration: none; + vertical-align: baseline; + font-family: Arial; +} +H1.Appendix()TOC, H2.Appendix()TOC, H3.Appendix()TOC, H4.Appendix()TOC, H5.Appendix()TOC, H6.Appendix()TOC { + text-align: left; + margin-top: 6.000000pt; + margin-bottom: 6.000000pt; + margin-right: 54.000000pt; + font-size: 12.000000pt; + font-weight: Bold; + text-decoration: none; + vertical-align: baseline; + font-family: Times New Roman; +} +H1.AppendixTitle, H2.AppendixTitle, H3.AppendixTitle, H4.AppendixTitle, H5.AppendixTitle, H6.AppendixTitle { + text-align: left; + margin-bottom: 60.000000pt; + font-size: 28.000000pt; + font-weight: Bold; + text-decoration: none; + vertical-align: baseline; + font-family: Arial; +} +P.AppendixTitleTOC { + text-align: left; + margin-top: 6.000000pt; + margin-bottom: 3.000000pt; + margin-right: 18.000000pt; + font-size: 12.000000pt; + font-weight: Bold; + text-decoration: none; + vertical-align: baseline; + font-family: Times New Roman; +} +P.Body { + text-align: left; + margin-top: 0.000000pt; + font-size: 12.000000pt; + font-weight: medium; + text-decoration: none; + vertical-align: baseline; + font-family: Times New Roman; +} +P.Body-Follow { + text-align: left; + margin-top: 4.000000pt; + font-size 12.000000pt; + font-weight: medium; + vertical-align: baseline; + font-family: Times New Roman; +} +P.Body-Text { + text-align: left; + margin-top: 4.000000pt; + font-size 12.000000pt; + font-weight: medium; + vertical-align: baseline; + font-family: Times New Roman; +} +P.BodyAfterHead { + text-align: left; + font-weight: medium; + vertical-align: baseline; + font-family: Times New Roman; +} +P.BodyFollow { + text-align: left; + margin-top: 4.000000pt; + font-size: 12.000000pt; + font-weight: medium; + vertical-align: baseline; + font-family: Times New Roman; +} +P.BodyHang { + text-align: left; + margin-top: 4.000000pt; + font-size: 12.000000pt; + font-weight: medium; + vertical-align: baseline; + font-family: Times New Roman; +} +P.BodyHang1 { + text-align: left; + margin-top: 3.000000pt; + font-size: 12.000000pt; + font-weight: medium; + vertical-align: baseline; + font-family: Times New Roman; +} +P.BodyHang1List { + text-align: left; + font-size: 12.000000pt; + font-weight: medium; + vertical-align: baseline; + font-family: Times New Roman; +} +P.BodyHang1Next { + text-align: left; + font-size: 12.000000pt; + font-weight: medium; + vertical-align: baseline; + font-family: Times New Roman; +} +P.BodyHang2 { + text-align: left; + margin-top: 3.000000pt; + font-size: 12.000000pt; + font-weight: medium; + vertical-align: baseline; + font-family: Times New Roman; +} +P.BodyHang2List { + text-align: left; + font-size: 12.000000pt; + font-weight: medium; + vertical-align: baseline; + font-family: Times New Roman; +} +P.BodyHang2Next { + text-align: left; + font-size: 12.000000pt; + font-weight: medium; + vertical-align: baseline; + font-family: Times New Roman; +} +P.BodyHang3 { + text-align: left; + margin-top: 3.000000pt; + font-size: 12.000000pt; + font-weight: medium; + vertical-align: baseline; + font-family: Times New Roman; +} +P.BodyHang3List { + text-align: left; + font-size: 12.000000pt; + font-weight: medium; + vertical-align: baseline; + font-family: Times New Roman; +} +P.BodyHang3Next { + text-align: left; + font-size: 12.000000pt; + font-weight: medium; + vertical-align: baseline; + font-family: Times New Roman; +} +P.BodyHang4 { + text-align: left; + margin-top: 3.000000pt; + font-size: 12.000000pt; + font-weight: medium; + vertical-align: baseline; + font-family: Times New Roman; +} +P.BodyHang4List { + text-align: left; + font-size: 12.000000pt; + font-weight: medium; + vertical-align: baseline; + font-family: Times New Roman; +} +P.BodyListFollow { + text-align: left; + margin-top: 3.000000pt; + margin-left: 30.000000pt; + font-size: 12.000000pt; + font-weight: medium; + vertical-align: baseline; + font-family: Times New Roman; +} +P.BodyListFollow2 { + text-align: left; + font-size: 12.000000pt; + font-weight: medium; + vertical-align: baseline; + font-family: Times New Roman; +} +P.BodyListFollow3 { + text-align: left; + margin-top: 3.000000pt; + font-size: 12.000000pt; + font-weight: medium; + vertical-align: baseline; + font-family: Times New Roman; +} +P.BodyListFollow4 { + text-align: left; + margin-top: 3.000000pt; + font-size: 12.000000pt; + font-weight: medium; + vertical-align: baseline; + font-family: Times New Roman; +} +P.BodyListFollowa { + text-align: left; + margin-top: 3.000000pt; + font-size: 12.000000pt; + font-weight: medium; + vertical-align: baseline; + font-family: Times New Roman; +} +P.BodyListFollowa1 { + text-align: left; + margin-top: 3.000000pt; + font-size: 12.000000pt; + font-weight: medium; + vertical-align: baseline; + font-family: Times New Roman; +} +P.BookName { + text-align: left; + font-size: 18.000000pt; + font-weight: Bold; + vertical-align: baseline; + font-family: Arial; +} +P.BookNameTOC { + text-align: left; + margin-top: 6.000000pt; + margin-bottom: 6.000000pt; + font-size: 12.000000pt; + font-weight: Bold; + font-family: Arial; +} +P.BulletSideHead { + text-align: left; + margin-top: 3.000000pt; + font-size: 12.000000pt; + font-weight: medium; + vertical-align: baseline; + font-family: Times New Roman; +} +P.CellBody { + text-align: left; + font-size: 12.000000pt; + font-weight: medium; + vertical-align: baseline; + font-family: Times New Roman; +} +P.CellBody1 { + text-align: left; + font-size: 8.000000pt; + font-weight: medium; + vertical-align: baseline; + font-family: Courier New; +} +P.CellCode { + text-align: left; + font-size: 9.000000pt; + font-weight: medium; + vertical-align: baseline; + font-family: Courier; +} +P.CellHeading { + text-align: left; + font-size: 12.000000pt; + font-weight: Bold; + font-style: Italic; + text-decoration: none; + vertical-align: baseline; + font-family: Times New Roman; +} +H1.ChapterTitle, H2.ChapterTitle, H3.ChapterTitle, H4.ChapterTitle, H5.ChapterTitle, H6.ChapterTitle { + text-align: left; + margin-bottom: 10.000000pt; + font-size: 28.000000pt; + font-weight: Bold; + color: #000077; + text-decoration: none; + vertical-align: baseline; + font-family: Arial; + +} +H2.ChapterTitle, H2.ChapterTitle, H3.ChapterTitle, H4.ChapterTitle, H5.ChapterTitle, H6.ChapterTitle { + text-align: left; + margin-bottom: 1.000000pt; + font-size: 28.000000pt; + font-weight: Bold; + color: #000077; + text-decoration: none; + vertical-align: baseline; + font-family: Arial; + +} +P.ChapterTitleTOC { + text-align: left; + margin-top: 6.000000pt; + margin-bottom: 6.000000pt; + margin-right: 54.000000pt; + font-size: 12.000000pt; + font-weight: Bold; + text-decoration: none; + vertical-align: baseline; + font-family: Times New Roman; +} +H1.ChapterTitleTOC { + text-align: left; + margin-top: 0.000000pt; + margin-bottom: 0.000000pt; + margin-right: 54.000000pt; + margin-left: 16.000000pt; + font-size: 12.000000pt; + font-weight: Bold; + text-decoration: none; + vertical-align: baseline; + font-family: Times New Roman; +} +H2.ChapterTitleTOC { + text-align: left; + margin-top: 0.000000pt; + margin-bottom: 0.000000pt; + margin-right: 54.000000pt; + margin-left: 16.000000pt; + font-size: 12.000000pt; + font-weight: Bold; + text-decoration: none; + vertical-align: baseline; + font-family: Times New Roman; +} +H1.SectionTitle, H2.SectionTitle, H3.SectionTitle, H4.SectionTitle, H5.SectionTitle, H6.SectionTitle { + text-align: left; + margin-bottom: 10.000000pt; + font-size: 28.000000pt; + font-weight: Bold; + color: #000077; + text-decoration: none; + vertical-align: baseline; + font-family: Arial; +} +P.SectionTitleTOC { + text-align: left; + margin-top: 6.000000pt; + margin-bottom: 6.000000pt; + margin-right: 0.000000pt; + font-size: 14.000000pt; + font-weight: Bold; + text-decoration: none; + vertical-align: baseline; + font-family: Times New Roman; +} +H1.SectionTitleTOC { + text-align: left; + margin-top: 6.000000pt; + margin-bottom: 6.000000pt; + margin-right: 0.000000pt; + font-size: 14.000000pt; + font-weight: Bold; + text-decoration: none; + vertical-align: baseline; + font-family: Times New Roman; +} +H2.SectionTitleTOC { + text-align: left; + margin-top: 6.000000pt; + margin-bottom: 6.000000pt; + margin-right: 0.000000pt; + font-size: 14.000000pt; + font-weight: Bold; + text-decoration: none; + vertical-align: baseline; + font-family: Times New Roman; +} +H2.TOCTitleTOC { + text-align: left; + margin-top: 6.000000pt; + margin-bottom: 6.000000pt; + margin-right: 0.000000pt; + font-size: 14.000000pt; + font-weight: Bold; + text-decoration: none; + vertical-align: baseline; + font-family: Times New Roman; +} + +P.CodeExample { + text-align: left; + margin-top: 1.000000pt; + margin-bottom: 1.000000pt; + font-size: 9.000000pt; + font-weight: medium; + text-decoration: none; + vertical-align: baseline; + font-family: Courier; +} +P.CodeExample2 { + text-align: left; + margin-top: 2.000000pt; + margin-bottom: 2.000000pt; + font-size: 9.000000pt; + font-weight: medium; + vertical-align: baseline; + font-family: Courier; +} +P.CodeScreen { + text-align: left; + font-size: 9.000000pt; + font-weight: medium; + vertical-align: baseline; + font-family: Courier; +} +P.CodeScreen2 { + text-align: left; + font-size: 9.000000pt; + font-weight: medium; + vertical-align: baseline; + font-family: Courier; +} +P.ContentsList { + text-align: left; + margin-top: 3.000000pt; + font-size: 12.000000pt; + font-weight: medium; + vertical-align: baseline; + font-family: Times New Roman; +} +P.CopyrightNotice { + text-align: left; + margin-top: 3.000000pt; + font-size: 12.000000pt; + font-weight: medium; + vertical-align: baseline; + font-family: Times New Roman; +} +H2.Descriptor { + text-align: left; + margin-top: 6.000000pt; + margin-bottom: 6.000000pt; + font-size: 16.000000pt; + font-weight: medium; + vertical-align: baseline; + font-family: Times New Roman; +} +P.DescriptorTOC, H2.DescriptorTOC, H3.DescriptorTOC, H4.DescriptorTOC, H5.DescriptorTOC, H6.DescriptorTOC { + text-align: left; + margin-right: 18.000000pt; + font-size: 12.000000pt; + font-weight: medium; + vertical-align: baseline; + font-family: Times; +} +P.Equation { + text-align: center; + margin-top: 10.000000pt; + margin-bottom: 6.000000pt; + font-size: 10.000000pt; + font-weight: medium; + font-family: Times; +} +P.Example { + text-align: left; + margin-top: 3.000000pt; + margin-bottom: 3.000000pt; + font-size: 10.000000pt; + font-weight: medium; + font-family: Courier; +} +P.Example2 { + text-align: left; + margin-top: 3.000000pt; + margin-bottom: 3.000000pt; + font-size: 10.000000pt; + font-weight: medium; + font-family: Courier; +} +P.Example21 { + text-align: left; + margin-top: 3.000000pt; + margin-bottom: 3.000000pt; + font-size: 8.000000pt; + font-weight: medium; + font-style: Italic; + font-family: Courier New; +} +P.ExampleLib { + text-align: left; + margin-top: 3.000000pt; + margin-bottom: 3.000000pt; + font-size: 8.750000pt; + font-weight: medium; + font-family: Courier New; +} +P.ExampleLibrary { + text-align: left; + margin-top: 3.000000pt; + margin-bottom: 3.000000pt; + margin-right: 3.599991pt; + font-size: 10.000000pt; + font-weight: medium; + font-family: Courier; +} +P.ExampleScreen { + text-align: left; + font-size: 10.000000pt; + font-weight: medium; + font-family: Courier; +} +P.ExampleTitle { + text-align: left; + font-size: 12.000000pt; + font-weight: Bold; + font-family: Times New Roman; +} +P.ExampleWide { + text-align: left; + margin-top: 3.000000pt; + margin-bottom: 3.000000pt; + font-size: 10.000000pt; + font-weight: medium; + font-family: Courier; +} +P.Extract { + text-align: left; + margin-top: 7.000000pt; + margin-right: 18.000000pt; + font-size: 9.000000pt; + font-weight: medium; + font-family: Times; +} +P.Figure { + text-align: left; + font-size: 12.000000pt; + font-weight: medium; + font-family: Times New Roman; +} +P.FigureLabel { + text-align: left; + margin-top: 4.000000pt; + margin-bottom: 4.000000pt; + font-size: 12.000000pt; + font-weight: Bold; + font-family: Times New Roman; +} +P.FigureLOF { + text-align: left; + margin-top: 2.000000pt; + font-size: 10.000000pt; + font-weight: medium; + font-family: Times New Roman; +} +P.FigureText { + text-align: left; + font-size: 12.000000pt; + font-weight: medium; + font-family: Arial; +} +P.FigureTitle { + text-align: left; + margin-top: 4.000000pt; + font-size: 12.000000pt; + font-weight: Bold; + font-family: Times New Roman; +} +P.Footnote { + text-align: left; + margin-top: 3.000000pt; + font-size: 9.000000pt; + font-weight: medium; + font-family: Times New Roman; +} +P.GlossarySeparator { + text-align: left; + margin-top: 16.000000pt; + font-size: 18.000000pt; + font-weight: Bold; + font-family: Arial; +} +P.GlossaryTerm { + text-align: left; + margin-top: 6.000000pt; + font-size: 13.000000pt; + font-weight: Bold; + font-family: Arial; +} +P.Gotos { + margin-top: 8.000000pt; + font-size: 10.000000pt; + font-weight: Bold; + color: #000077; + text-decoration: none; + font-family: Arial; +} +P.GroupTitlesIX { + text-align: left; + margin-top: 15.000000pt; + font-size: 14.000000pt; + font-weight: Bold; + font-family: Arial; +} +H1.Heading1Top, H2.Heading1Top, H4.Heading1Top, H5.Heading1Top, H6.Heading1Top { + text-align: left; + margin-top: 4.000000pt; + margin-bottom: 13.000000pt; + margin-right: 48.023987pt; + font-size: 22.000000pt; + font-weight: Bold; + font-family: Arial; +} +H1.Heading1, H2.Heading1, H4.Heading1, H5.Heading1, H6.Heading1 { + text-align: left; + margin-top: 4.000000pt; + margin-bottom: 13.000000pt; + margin-right: 48.023987pt; + font-size: 22.000000pt; + font-weight: Bold; + font-family: Arial; +} +H3.Heading1 { + text-align: left; + margin-top: 12.000000pt; + margin-bottom: 1.000000pt; + margin-right: 48.023987pt; + font-size: 22.000000pt; + font-weight: Bold; + color: #000077; + text-decoration: none; + font-family: Arial; +} + +P.Heading1TOC { + text-align: left; + margin-top: 2.000000pt; + margin-bottom: 0.000000pt; + margin-right: 54.000000pt; + font-size: 12.000000pt; + font-weight: medium; + font-family: Times New Roman; +} +H3.Heading2 { + text-align: left; + margin-top: 4.000000pt; + margin-bottom: 1.000000pt; + font-size: 16.000000pt; + font-weight: Bold; + font-family: Arial; +} +P.Heading2TOC { + text-align: left; + margin-right: 54.000000pt; + margin-top: 0.000000pt; + margin-bottom: 0.000000pt; + font-size: 12.000000pt; + font-weight: medium; + font-family: Times New Roman; + vertical-align: baseline; +} +H4.Heading3 { + text-align: left; + margin-top: 7.000000pt; + font-size: 14.000000pt; + font-weight: Bold; + font-family: Arial; +} +P.Heading3TOC { + text-align: left; + margin-top: 3.000000pt; + font-size: 12.000000pt; + font-weight: medium; + font-family: Times New Roman; +} +H5.Heading4 { + text-align: left; + margin-top: 4.000000pt; + font-size: 12.000000pt; + font-weight: Bold; + font-family: Arial; +} +H1.Heading5, H2.Heading5, H3.Heading5, H4.Heading5, H5.Heading5 +{ + text-align: left; + margin-top: 50.000000pt; + margin-bottom: 6.000000pt; + font-size: 20.000000pt; + font-weight: bold; + font-style: oblique; + color: #800000; + border-top: thick double #800000; + background-color: #dcdcdc; + text-decoration: none; + font-family: Arial; +} +Table { + padding-left: 10.000000pt; +} +P.Heading5TOC { + text-align: left; + margin-right: 54.000000pt; + font-size: 12.000000pt; + font-weight: medium; + font-style: Italic; + font-family: Times New Roman; +} +H1.HeadingFront, H2.HeadingFront, H3.HeadingFront, H4.HeadingFront, H5.HeadingFront, H6.HeadingFront { + text-align: left; + margin-top: 10.000000pt; + margin-bottom: 3.000000pt; + font-size: 18.000000pt; + font-weight: Bold; + font-family: Arial; +} +P.HeadingRunIn { + text-align: left; + margin-top: 12.000000pt; + margin-bottom: 6.000000pt; + font-size: 10.000000pt; + font-weight: Bold; + font-family: Times; +} +P.IgnoreCharsIX { + text-align: justify; + font-size: 12.000000pt; + font-weight: medium; + font-family: Times New Roman; +} +P.Indented { + text-align: left; + font-size: 12.000000pt; + font-weight: medium; + font-family: Times New Roman; +} +P.Index { + text-align: left; + font-size: 18.000000pt; + font-weight: Bold; + font-family: Arial; +} +P.IndexIX { + text-align: left; + font-size: 12.000000pt; + font-weight: medium; + font-family: Times New Roman; +} +P.IndexIXTOC { + text-align: left; + font-size: 12.000000pt; + font-weight: medium; + color: #ffffff; + text-decoration: none; + font-family: Times; +} +H1.IndexTitle, H2.IndexTitle, H3.IndexTitle, H4.IndexTitle, H5.IndexTitle, H6.IndexTitle { + text-align: center; + font-size: 28.000000pt; + font-weight: Bold; + font-family: Arial; +} +P.IndexTitleTOC { + text-align: left; + margin-top: 6.000000pt; + margin-bottom: 6.000000pt; + margin-right: 54.000000pt; + font-size: 12.000000pt; + font-weight: Bold; + font-family: Times New Roman; +} +H1.IntroTitle, H2.IntroTitle, H3.IntroTitle, H4.IntroTitle, H5.IntroTitle, H6.IntroTitle { + text-align: left; + margin-bottom: 10.000000pt; + font-size: 28.000000pt; + font-weight: Bold; + color: #000077; + text-decoration: none; + font-family: Arial; + +} +P.IntroTitleTOC { + text-align: left; + margin-right: 18.000000pt; + margin-bottom: 0.000000pt; + font-size: 12.000000pt; + font-weight: Bold; + font-family: Times; +} +H6.Label, H3.Label { + text-align: left; + padding-left: 20.000000pt; + font-size: 12.000000pt; + font-weight: Bold; + text-decoration: none; + font-family: Arial; + text-transform: capitalize; +} +P.Level1IX { + text-align: left; + font-size: 9.000000pt; + font-weight: medium; + font-family: Times; +} +P.Level2IX { + text-align: left; + margin-left: 8.000000pt; + font-size: 9.000000pt; + font-weight: medium; + font-family: Times; +} +P.Level3IX { + text-align: justify; + font-size: 10.000000pt; + margin-left: 16.000000pt; + font-weight: medium; + font-family: Times New Roman; +} +P.Lib1 { + text-align: left; + margin-top: 6.000000pt; + font-size: 12.000000pt; + font-weight: medium; + font-family: Times New Roman; +} +P.Lib1Follow { + text-align: left; + margin-top: 2.000000pt; + font-size: 12.000000pt; + font-weight: medium; + font-family: Times New Roman; +} +P.Library { + text-align: left; + margin-top: 4.000000pt; + font-size: 12.000000pt; + font-weight: medium; + font-family: Times New Roman; +} +P.LibraryFollow { + text-align: left; + margin-top: 4.000000pt; + font-size: 12.000000pt; + font-weight: medium; + font-family: Times New Roman; +} +P.List3 { + text-align: left; + margin-top: 2.000000pt; + font-size: 12.000000pt; + font-weight: medium; + font-family: Times New Roman; +} +P.ListCompact { + text-align: left; + font-size: 12.000000pt; + font-weight: medium; + font-family: Times New Roman; +} +P.ListFollow { + text-align: left; + margin-top: 3.000000pt; + font-size: 12.000000pt; + font-weight: medium; + font-family: Times New Roman; +} +P.ListFollow2 { + text-align: left; + margin-top: 4.000000pt; + font-size: 12.000000pt; + font-weight: medium; + font-family: Times New Roman; +} +P.ListHang { + text-align: left; + margin-top: 3.000000pt; + font-size: 12.000000pt; + font-weight: medium; + font-family: Times New Roman; +} +P.ListHang2 { + text-align: left; + font-size: 12.000000pt; + font-weight: medium; + font-family: Times New Roman; +} +P.ListHangFollow2 { + text-align: left; + margin-top: 2.000000pt; + font-size: 12.000000pt; + font-weight: medium; + font-family: Times New Roman; +} +P.ListHangList { + text-align: left; + font-size: 12.000000pt; + font-weight: medium; + font-family: Times New Roman; +} +P.ListHangNext { + text-align: left; + font-size: 12.000000pt; + font-weight: medium; + font-family: Times New Roman; +} +P.Mapping-Table-Cell { + text-align: left; + margin-top: 2.000000pt; + margin-bottom: 2.000000pt; + font-size: 12.000000pt; + font-weight: medium; + font-family: Times; +} +P.Mapping-Table-Cell1 { + text-align: left; + font-size: 18.000000pt; + font-weight: Bold; + color: #ffffff; + text-decoration: none; + font-family: Times; +} +P.Mapping-Table-Cell2 { + text-align: left; + font-size: 14.000000pt; + font-weight: Bold; + color: #ffffff; + text-decoration: none; + font-family: Times; +} +P.Mapping-Table-Cell3 { + text-align: left; + font-size: 12.000000pt; + font-weight: Bold; + color: #ffffff; + text-decoration: none; + font-family: Times; +} +P.Mapping-Table-Cell4 { + text-align: left; + font-size: 10.000000pt; + font-weight: Bold; + color: #ffffff; + text-decoration: none; + font-family: Courier; +} +P.Mapping-Table-Title { + text-align: left; + margin-top: 2.000000pt; + margin-bottom: 2.000000pt; + font-size: 14.000000pt; + font-weight: medium; + font-family: Times; +} +P.MappingTitle { + text-align: justify; + font-size: 14.000000pt; + font-weight: Bold; + font-family: Times New Roman; +} +P.Note { + text-align: left; + margin-bottom: 8.000000pt; + margin-top: -8.000000pt; + padding-left: 20.000000pt; + font-size: 12.000000pt; + font-weight: medium; + font-family: Times New Roman; +} +P.Numbered2Follow { + text-align: left; + margin-top: 3.000000pt; + font-size: 12.000000pt; + font-weight: medium; + font-family: Times New Roman; +} +P.NumberedCont { + text-align: left; + margin-top: 3.000000pt; + font-size: 10.000000pt; + font-weight: medium; + font-family: Times; +} +P.NumberedFollow { + text-align: left; + margin-top: 3.000000pt; + font-size: 12.000000pt; + font-weight: medium; + font-family: Times New Roman; + margin-left: 30.000000pt; +} +P.NumberedSpecialFollow { + text-align: left; + margin-top: 3.000000pt; + font-size: 12.000000pt; + font-weight: medium; + font-family: Times New Roman; +} +P.PartNumber { + text-align: left; + margin-top: 16.000000pt; + font-size: 12.000000pt; + font-weight: medium; + font-family: Times New Roman; +} +P.SeparatorsIX { + text-align: left; + font-size: 9.000000pt; + font-weight: medium; + font-family: Times; +} +P.SortOrderIX { + text-align: justify; + font-size: 12.000000pt; + font-weight: medium; + font-family: Times New Roman; +} +P.Table-text { + text-align: left; + margin-right: 6.479996pt; + font-size: 12.000000pt; + font-weight: medium; + font-family: Times New Roman; +} +P.Table-text1 { + text-align: left; + margin-top: 1.000000pt; + margin-bottom: 2.000000pt; + font-size: 10.000000pt; + font-weight: medium; + font-family: Times New Roman; +} +P.Table-text2 { + text-align: left; + margin-top: 2.000000pt; + margin-bottom: 2.399994pt; + font-size: 12.000000pt; + font-weight: medium; + font-family: Times New Roman; +} +P.Table-text3 { + text-align: left; + margin-top: 1.000000pt; + margin-bottom: 1.000000pt; + font-size: 9.000000pt; + font-weight: medium; + font-family: Times New Roman; +} +P.Table-text4 { + text-align: left; + margin-top: 2.000000pt; + margin-bottom: 2.399994pt; + margin-right: 6.479996pt; + font-size: 12.000000pt; + font-weight: medium; + font-family: Times New Roman; +} +P.TableFootnote { + text-align: left; + font-size: 9.000000pt; + font-weight: medium; + font-family: Times New Roman; +} +LI.TableLabel { + text-align: left; + margin-top: 3.000000pt; + font-size: 12.000000pt; + font-weight: Bold; + font-family: Times New Roman; +} +P.TableLOT { + text-align: left; + margin-top: 2.000000pt; + font-size: 10.000000pt; + font-weight: medium; + font-family: Times; +} +H1.TableTitle, H2.TableTitle, H3.TableTitle, H4.TableTitle, H5.TableTitle, H6.TableTitle { + text-align: left; + font-size: 12.000000pt; + font-weight: Bold; + font-family: Times New Roman; +} +LI.TableTitle1 { + text-align: left; + font-size: 12.000000pt; + font-weight: Bold; + font-family: Times New Roman; +} +H1.Title { + text-align: left; + margin-top: 50.000000pt; + font-size: 36.000000pt; + font-weight: Bold; + font-style: Italic; + font-family: Arial; +} +P.Title/Company { + text-align: left; + margin-top: 282.000000pt; + font-size: 16.000000pt; + font-weight: Bold; + font-family: Times New Roman; +} +H1.TitleBook { + text-align: right; + font-size: 28.000000pt; + font-weight: Bold; + font-style: Italic; + font-family: Arial; +} +P.TitleBook1TOC { + text-align: left; + font-size: 12.000000pt; + font-weight: medium; + color: #ffffff; + text-decoration: none; + font-family: Times; +} +P.TitleBook2TOC { + text-align: left; + font-size: 12.000000pt; + font-weight: medium; + color: #ffffff; + text-decoration: none; + font-family: Times; +} +P.TitleBook3TOC { + text-align: left; + font-size: 12.000000pt; + font-weight: medium; + color: #ffffff; + text-decoration: none; + font-family: Times; +} +P.TitleTOC { + text-align: left; + margin-top: 6.000000pt; + margin-bottom: 6.000000pt; + margin-right: 54.000000pt; + font-size: 12.000000pt; + font-weight: Bold; + font-family: Times New Roman; +} +P.TitleTOC/Index { + text-align: left; + font-size: 24.000000pt; + font-weight: medium; + font-family: Times; +} +P.TitleVolume { + text-align: right; + font-size: 28.000000pt; + font-weight: Bold; + font-style: Italic; + font-family: Arial; +} +P.TOC { + text-align: left; + font-size: 18.000000pt; + font-weight: Bold; + font-family: Arial; +} +H1.TOCStart, H2.TOCStart, H3.TOCStart, H4.TOCStart, H5.TOCStart, H6.TOCStart { + text-align: left; + font-size: 18.000000pt; + font-weight: Bold; + font-family: Arial; +} +H1.TOCTitle, H2.TOCTitle, H3.TOCTitle, H4.TOCTitle, H5.TOCTitle, H6.TOCTitle { + text-align: left; + margin-bottom: 6.000000pt; + font-weight: Bold; + font-family: Arial; +} +EM.Address { + font-size: 12.000000pt; + font-weight: medium; + font-family: Times New Roman; +} +SPAN.Bold { + font-size: 12.000000pt; + font-weight: Bold; + font-family: Times New Roman; +} +STRONG.BoldEmphasis { + font-size: 12.000000pt; + font-weight: Bold; + font-style: Italic; + font-family: Times New Roman; +} +EM.Bullet { + font-size: 6.000000pt; + font-weight: medium; + font-family: ZapfDingbats; +} +EM.Bullet2 { + font-size: 6.000000pt; + font-weight: medium; + font-family: ZapfDingbats; +} +EM.Callout { + font-size: 10.000000pt; + font-weight: medium; + font-family: Arial; +} +EM.ChapterTitle { + font-size: 28.000000pt; + font-weight: bold; + font-family: Times New Roman MT Extra Bold; +} +EM.SectionTitle { + font-size: 28.000000pt; + font-weight: bold; + font-family: Times New Roman MT Extra Bold; +} +TT.Code, KBD.Code { + font-size: 9.000000pt; + font-weight: medium; + font-family: Courier; +} +KBD.CodeOutput, STRONG.CodeOutput, CODE.CodeOutput { + font-size: 9.000000pt; + font-weight: Bold; + font-family: Courier; +} +EM.CodeSuperscript { + font-size: 8.000000pt; + font-weight: medium; + font-family: Courier; +} +KBD.CodeVariant { + font-size: 9.000000pt; + font-weight: medium; + font-style: italic; + font-family: Courier; +} +EM.Emphasis { + font-size: 12.000000pt; + font-weight: medium; + font-style: Italic; + font-family: Times New Roman; +} +EM.EquationNumber { + font-size: 8.000000pt; + font-weight: Bold; + font-family: Helvetica; +} +EM.EquationVariables { + font-style: Italic; +} +CODE.FixedFont { + font-size: 26.000000pt; + font-weight: Bold; + font-family: Courier; +} +VAR.FixedFontVariant { + font-size: 24.000000pt; + font-weight: medium; + font-style: Italic; + font-family: Courier New; +} +CODE.Function { + font-size: 18.000000pt; + font-weight: Bold; + font-family: Courier; +} +EM.function-name { +} +VAR.FunctionVariant { + font-size: 18.000000pt; + font-weight: medium; + font-style: Oblique; + font-family: Courier; +} +EM.PageNumber { + font-weight: Bold; +} +EM.SmallCaps { + font-size: 12.000000pt; + font-weight: Bold; + font-style: small-caps Regular; + font-family: Arial; +} +EM.StepNumber { + font-size: 8.000000pt; + font-weight: Bold; + font-family: Helvetica; +} +B.Superscript { + font-size: 9.000000pt; + font-weight: medium; + font-family: Arial; +} +SYM.Symbols { + font-size: 12.000000pt; + font-weight: Bold; + font-family: Times; +} +EM.TableFootBold { + font-size: 9.000000pt; + font-weight: Bold; + font-family: Times New Roman; +} +EM.TableFootBoldEmph { + font-size: 9.000000pt; + font-weight: Bold; + font-style: Italic; + font-family: Times New Roman; +} +EM.TableFootEmph { + font-size: 9.000000pt; + font-weight: medium; + font-style: Italic; + font-family: Times New Roman; +} +PRE.CodeExample { + text-align: left; + margin-top: 1.000000pt; + margin-bottom: 1.000000pt; + margin-left: 16.000000pt; + font-size: 9.000000pt; + font-weight: medium; + text-decoration: none; + vertical-align: baseline; + font-family: Courier; +} +PRE.CodeExample2 { + text-align: left; + margin-top: 2.000000pt; + margin-bottom: 2.000000pt; + margin-left: 24.000000pt; + font-size: 9.000000pt; + font-weight: medium; + vertical-align: baseline; + font-family: Courier; +} +PRE.CodeExampleWide { + text-align: left; + margin-top: 2.000000pt; + margin-bottom: 2.000000pt; + font-size: 9.000000pt; + font-weight: medium; + vertical-align: baseline; + font-family: Courier; +} \ No newline at end of file diff --git a/host/tools/configtool/standalone/wxwin/manual/ecos.gif b/host/tools/configtool/standalone/wxwin/manual/ecos.gif new file mode 100644 index 0000000000000000000000000000000000000000..688151344fe563df164fec0ecb48406ff4e4440c GIT binary patch literal 4009 zc%1E(=_8a2!^ZD>=AO+m-7^Mb>x^YALk7uu(u{o&Gc8oqV;HhV_EM)|?DbA#E1|~_ z8KpugrJO-TIgVY?(GVxJ5lV|Z&w2lf_rv@9a9w}F@4DPrt~S=(IM5CF0{p|~=H{Xr z&<6k;8yf-u`26`ZolgJw@uM1`=HlYg+S)qf;4t4h?BL+={rmT}wzlQ>@8?p5bCIci zeSIaxCEcCfYHDiB%gZGtC1b;50)b#^YHE&3jgN_6TwI(JR?W}PpGiG4;~RSR>{&H6 zV10c(K0bbUaIn0*oXuu`>|ZPp7R1EF%+TpvE_ZHjZoZ<$nr5-9<6%`fPf@}wC>($j&DwW#a-Yz&Jn46jLbnzVQAG}q6tFO1u z-`9Wg#bhWqbY^CzrMZPprFXV>%BEz)!^2aPQ}y-r{eAt(G4Y-*F1_8oE)FhSe{OSA zvjYH}&CV_^D6XogYH4XnO-?N@DQA1KVV;>8LI9YYoP7WOJ=@dM!P=p? zxVWaOrlP!}y{(N-r4A1cuP(24cXtbgLaLftD3{xGs|omj{!gO)75d*c`6vEyf`Q!x zK&+;FgScIQ#T;YxG*otG!@3^j?u}JlXUW?mUiLIzd2*iOl=qS>uI?=~+79ix6ah~*VI=ZLuOlTY4Tq$% zG^|lx+(ULJkapV-&}(6LdtQbp({WJ~1)ZpD`W_17#Oud@CQ|8OGY>V zAs>qr&*wB&@dRWgJ7=pX{s)gd&`RNDUh&(JAwQNswIxl^1%>q!DLQ3Rq^W8{plAa? z7yZ?gDcvoSx<^lL5mq!)mK@cU%(jN%EMj{x2+piNd&T*Q6iO7qo9n(k-1Mlv8*Akl43&Za z&FYK0koqZZ1E{D#H&_AUnO)2c4h?yHQU#ax|Qh{6!-ubyeKdLLVq*-& zbqHUp#f4h&LE56Ex1Op}y|^vn?TwbJ&Tnr%lq-IFOWJge zBPQGlmN`P zH=0e4V+r?64~A~5y%4XTVn%O`JN@Rv!_FG{5Y*y>qYLu5N9B1b%nyiW1XA1{c_`d*Rez%0TNY)AEs~yR z;&FmQ$6z3Xyf~)abwdH4$$XBO=$=rYYcUD8cYV~ZsksL~O{ zYb)c2?Kk5X>BvC*jvLK=S9{`^rkl8=zbN)h}HQTY-N{N>rJ)u>E9>7m$R z#h$gIA4W!-1zOzg=TKQbZ{BsIZ~g17?S7lfuBM_4-E+)b71m)VZ@AFN+1MfVIF3&l zBO;1(lW5C9ycFwvMdv_@WP!Wi^@4H+>Fo~N6rdmrh9ob#F&~JX%CoVW3YOZ~+E#{^ zP--(Z%fJ`~;en+Zy5mhRybs(dKRAk_k}0rJ{qL7M1E@ec{$@!9?E2$R5VW`&AVL{Y{u^!p>@xWj|))tOb%@!M3E{w}Plc4#@Q z=!*o)LL`Zs2JUOO&B7yart+&+G*BNfSn+83t)EX+_%);u z(k$-Ead_%ChlLTnhh!TObxSFIXA)E)7)Z7KQyUe-8Heq*9f%TbM3$v9KzX{ri1 zMn^5(QZHG-{ZSb(XmU@b{Pc?b{2|83h+~-?gOGS3h~!vGQ)<=Z)zZ_vFj8#ckwv0@ z^fR)#!4RS>mXFkL98!>Yj6T(0-N7ylRtJ({i&-G-A?QewY!{g`xUomgnfUTp$TsQ2 z4hT&tWhN}~_sCVFr!_U<2>?I_2q`g=|B1O`NIPJ`!({C2RfIJ1rC!>RmKlB6mIDRd zKP)Y@M0-~i2KZNwWi@{6?NNxBDa2Ouoa9JHu6qwi-c7`&w{&W|c?^`6#EMbWb1}ES zxyioa)}{TlhV4yBJjsT?=3oX{GbzSts;vI`S2|f?j?1jYP~BH=+xR88=8`XxHjkrXd5o zf!`ANSMX@bmi?jI{f&ROtZ~Q9YyL_>699kn9HnvfSV;D^X}=cSgho_j`M{ znL1k+T|yoIJF-bEpzYJfs$$c(s0=_VGj{Ua1AJITl%}_Iof2t;&}gG%=;rWq8Mhe^ zR%$E>16-{BpKHGt1jd`1fUkeZAyiC(niIFC=Qr-&tGSyXk|($7VQrYT`^0}1ES=2v zvF?@AGfVsLP@EK9x*PJ~Lt?kDY-f}r70s6VAPhn;cj6&QbM%YhkYxcY}Mxb6a zY|7$|SHK4s0{dUjQpPQoCSA+{|4Z_-ww_BG=yS1|HU%TE5o%6xIs6P1CG9wR0Bp7U z%0gs(LX!FEMs?9}5m`n1n-wlmwT`G76)HhUMpz1g-+R2izeC&kHy50Iy{J<}ndr9% zwjOB$0v-#S&D$}K>`ZydIUp{@7T^IJn37*X6Oq1ZLZG0--T@rf=Bp|MVQhuk3$M5@ z;cugU>oIoIU%m4d(ZtlkrC}M$(cEDAKzJ>24rTQCjhbhsNAj20Y~Kjd@zW3=U3;4Y zQBW&!m?jX(<7oUMiUinT^YP!t+Yu~lUrww`Xr`%74q^jA&G+50{$+EA2U8F+9?pC1 zV{NELCqyfgk^_=XVF&roMx2O#gz=*~gELS>BIjv7=MY=NN$T+?>9@rs*olakI1cib zPUr*vsVKlK>YZIesI_NAuD2$Hx#Lx|s>dl0dH6X8QJ8`T=*n$IGbamCm>UJ+mEfu%RIJ zQyyv>pqZm+6lFXEaZnZL_$*Y`1#ynZ=Lof`P(W#ktR*{7Tiy$X06$8|M%?U_c@in@ zAgvKdCo16@mB`@f0e3ht(0h**?J0s-GBAOGilV5V?9zyrAp-}{nb}ZWV=jv62T->9 zH5`l7Mz-b)5!2S(*tqKk+Uu_H?_+jJDu+!t`j*Q{2$)TuKAW8u``MB}<)6z8p@Jm9 z2?unP5WFZFXfqBfAIwYPFc@&~K*rN{$R=LpDi%0*G&jv@PbWwXXJ8JRp{=AT%LxIO zj%rxRKnF2$Ep%s<#fMZ(S{4liZM$GRJMr}2Q9hRpP<}-A3G#z`d4&98w?^wHIYfIN zA(#ywW`pTZ;FCs>Yarw!MwzgY%o(I3j4^Bgbe8<1qzGlP9za2uFb<&`(aHcC(neZe zfehK`APO8{cE+;UL zoZ^o);r~h^)XdneHJ_cgWnK!;Ql2*W?=vssh&SVqAKXc&lPW;+&KDho9t-P#f348r zguo}2D3yTERiZMY0)NPd@Sw8)V&!sIC1s*=Yw0fSrL diff --git a/host/tools/configtool/standalone/wxwin/manual/pix/BuildPackages.gif b/host/tools/configtool/standalone/wxwin/manual/pix/BuildPackages.gif new file mode 100644 index 0000000000000000000000000000000000000000..5488635ea0c6187c2f0449e7b47eb051433b235e GIT binary patch literal 43140 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 diff --git a/host/tools/configtool/standalone/wxwin/manual/pix/Image24.gif b/host/tools/configtool/standalone/wxwin/manual/pix/Image24.gif new file mode 100644 index 0000000000000000000000000000000000000000..6852b1c03af37eb379840bee6c9af7d7b5052ada GIT binary patch literal 5169 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 RP%bjQmZ997$I8NB4FLZ+y$%2X diff --git a/host/tools/configtool/standalone/wxwin/manual/pix/Image27.gif b/host/tools/configtool/standalone/wxwin/manual/pix/Image27.gif new file mode 100644 index 0000000000000000000000000000000000000000..d9b6a0d89d2c52f6ca39c28560dfbd7009312186 GIT binary patch literal 1239 zc${fpmlqVcG{xh(1$arj6 zaIl#}SS#klhJ}aQ*_at5I1&~)Ff#E)sYDbeyEe)zcInKRn0&lfIe1mf$xjI1|w zw%jOO;?g2vDz!$k$ia8ML$p>6=cgrp3q2;QsY+dW;y%kL(2mE!wBgcfzL`m(6_b~Q zO)$`8o4d30Mc@YClZ$*KuV&rcuJTatjhDgm$XOXznXX1pTX}Iq)>p5o-a9sU^>hep z$DP@+@$vBq%HH#QZt6L98Zy@8-YVE|=WNUFe_PKKKKJi$W3T(VXKP{Bn$_ORpPt#U z>Fw^m#gl*`L`?aN51QSpSUaK-~O*ZDmLHe^W3e|%8qeH zT*=vgwLE}fiK5t?OvSHH7L;0_Y>TSaRt=jMz}2^PL4kZ-M|`J-SxHjejLhSuR+sb++PaSH#VT1#V)`SZ5Sl-%5YrWp{7Kg`$dFk0n8MfiuEG1ROo4v>asB qOlnSvt(Y+}Chz3Z>7PGNPYQFhx~Wo@&UWM3?1E#O&z%_=8LR>2$KzxG diff --git a/host/tools/configtool/standalone/wxwin/manual/pix/Image28.gif b/host/tools/configtool/standalone/wxwin/manual/pix/Image28.gif new file mode 100644 index 0000000000000000000000000000000000000000..f0403e00b825502754303386f869a905f2613334 GIT binary patch literal 1262 zc${u<95`^`|Ns9CqhJ(_B%t_{1x)LJ2vDAI;P}tL$syyh zVZp&>4q>gB6B`yDZWmBilTrA%kb#MjiRVOzp@VxP15X=|XM@VgNve!JCM!Rscu!DI z+@x}&NX>h;X5cFp&B@EpPqzvUv+)Q_IXFYCl}{w#^P_VM0~UMD^_rS+aTV)aHIW6P ztFNz5*ciuJJ#lelugv^kXCzCWoS&OlsZ_dh+B(l2jt|cr-F+?Z-pXY5d%WH|HatAs zA;=eTX2-_I$0sOz&-2;2>FMbi#@YAIR2n)im$a?pIS``hyNiFKR|xOatq;1^E$(BT zW%TXPI6;3wiClX7Rt@MJi2vT^Hm& z5zM#}{x{V1uG>{t4OyS{mEu#IcojLMBf@{0E_7ZHslKr6#MiIa^EJ5AV_NsFjaZb= zT6H6-@Eq?|`NGS+YEc6kf`z_~P6>O0|_GD7D z0o!%qPWyS+p8Dqh4Nb^R&a)H_m6hY1+Q4oqIe)g&!Jl!>Uotr_xfZ=!uAW%(?&b6O Rx4&|}SkNLC72v>N4FK8I?J58O diff --git a/host/tools/configtool/standalone/wxwin/manual/pix/Image29.gif b/host/tools/configtool/standalone/wxwin/manual/pix/Image29.gif new file mode 100644 index 0000000000000000000000000000000000000000..197ecb8070700eda6d43b7125ab89b68458ef45d GIT binary patch literal 1333 zc${rEMQs(M1b;y1IK>`P7WE5 z4GRu7a|mn2oY=7NaJzuAoQ%T8MMt|?SUGqO6e=HQU}lsMku*|an551+&m}S_#j8o% zcTw;IL9yUG75|a32;`9qS z9BL~bH1U|dc+kA$srthfiMQ?x!_re%ENl}m(^%Llm*f)fDAk+sApg|f)cF-$Yk!D# zC`Oqm<&|F5nA6>`vGsA0xYYEB8n2HhB6@uk%>|+^H@e*Qc=hzhyaeY%;y02X+}ts* zEJ7+WvD^A-$(;l})~9g|nv7SU*089|TsBGJ$Es;*b2%E^tk(%?Wk+wmmi2lq)5@;b>-K!>%5q?^1^_(|7sUVo diff --git a/host/tools/configtool/standalone/wxwin/manual/pix/Image30.gif b/host/tools/configtool/standalone/wxwin/manual/pix/Image30.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e9e7a62c9c8dddb5aca1794a7856de22915a303 GIT binary patch literal 1129 zc${}L>V_|5fpmlqVcG{xh(1$arj6 zaIl#}SS#klhK0_JOmbc+91MxBP2z@9ECmyjk9Wzir?9*%T;$m*XjpYdV}h#pM4@;- z7J&t6zBAQ}U(K0OwCvb)1@1>a7E=~CELJSnioLZ#{c^iXcvsBKkmS>=4c3<(kt%u; zJlSvgv?H@jGcK&pxV(yY_qP?dw--D+2hmcdPpD zHgmZx&G>p<*Y58J4sY$2lGUEF{r#2$neXq-jd*eB;&E^H@VCJX42-?}Li{n)bW&e* z`2Kd2@!w|S+HIDvHD!;5sn5ZSN2}+bkz5tO`lzw?ygQe4KK?k@t3D(0%G&4COK&tT gpWL+Muam7#bNF4YJP62xMSrmgi>Tu$=Vd_(T?`Wj>KYDqhp{ z181q6EPCMGWx?-v=H%w(=jS^#dx>NPFu3=Kb!x?)GI@AzshGLf+ZC6VU7Z>ce(8wT z=T#0<)z@BPnQfYLZ5h}6MX{&1tqs^}%YI_6_x5#ncUOFVb@%l4_4oHTFf;3&x}bbw zbtu2uznwR7?<@=K_mWGnco;S#O@Fqn_qNa1H!V1CrNFMU~6QvAqDQFw;VPNRcI&(9CO!e?t0 z+>Ru=Vxx^G{aYog-Ot=JVm+-z@f_HJ{hcdzk(8Ra{Qh{}-LdX4lwW6pv$g ze6vJ2TzBR5P|q7juUx7(V9gLJVfn`LuuXd1(YXzG1E(Z*s7!k?rBh?si3=TC+d2{h I7#SI?0YD+U#Q*>R diff --git a/host/tools/configtool/standalone/wxwin/manual/pix/Image32.gif b/host/tools/configtool/standalone/wxwin/manual/pix/Image32.gif new file mode 100644 index 0000000000000000000000000000000000000000..98e2e73ceb3428bf54d8eb3f47d4c9298254c471 GIT binary patch literal 1984 zc%1Fi|3A|S0LSr>e2Fw_jysiao0>0mmbShqD``z5Wn)r?e3!@h8pS=x@;#YV^KEQw zF;lk{pP56x6q!mA*fod>}8~RvS+FtiE3sfHzcMlQJa#xEQ*jetF2G^Or;D=>msPIdo zI?e^MQ#p1g_}}2TUQf*C_wdX=-1g<@svRLjc;57DE{2oPeryO~7)7fEHapuV-;$d|xH?3UPa|oDSnk zt>MY*@uP!J-IT{&%Sa^2L~zjVUX&uTKmc{oZ7ls|qg_#?e7UqgaV@(FwYzCQL6I$JBqdWMn19rorge0w}(Q`;a_K26kHz}B9E4*>|*ybj_HZd zGooL|m!T)=JNn}s(JPe%7a{Sdge(y-gLC-wF8Bc>y|}VkOOE2?JQ&T~oxAcDX~x-w zQ)WYI7_$naV2dq7#7B_$1k+46|NG&*i}9HfU%+|CV6sct4BMkXgsm#zQVT0 zD#)XKZb9INv#R1y+=DD5z(pJ|P>X%GNT0ETMV96<4X-8v0F2G6l!zk2v1Y?dIi*{h z#JnYM7CYZm-)OkG3I?%=oDj#`l1B-(%bkv|Tqt!W8P>8F7PJUi_nxX+naEl&Z}$Qz zwnB6rP=4m0vO67OQWEy}K?>Wsjfn6^da@SjM~`<^Vy_)i>FU3}-@$u(6v|y= z_6?ez5sG%Cg*5_&k zi|bO}o!s%M!x@o(P8(B?Fz8zS>mEzX@XbfZ!H^C1;@x&D_LGxAtA1Hvv%x0n9}e5@ z7c{%-1o|3ZcJrrJN$iuq=-68F||t9yM!2!p4Kg4SeCP-?9oi9hYh^VXAkDYz3~rqvvRqFhqpkF)FG0NUdo z_^eo#&v#Au-JrnomaZy830$KL4t+^Sy=3ZM!#o~(n|I50q;Q!YAM2R(3S++6$(KG- zk2LvsHK4I1SI>S^i=lTYcCzF0*N_mVt=(Sx(M{!w>?;oHft)ngXLs;0^Kv=#T&gUF zq1GL83enf=w8EWesX5RkmHdo%B^FkzzU!Pa)$!U0&rzquakXvrZ>j~b+E(?^GW)#b u7#2>CUf^81nV(en?7ijbBAc`6ONk~DCfu`IL})yJg_ZkBo2?H99r*{)<7U_Z diff --git a/host/tools/configtool/standalone/wxwin/manual/pix/Image33.gif b/host/tools/configtool/standalone/wxwin/manual/pix/Image33.gif new file mode 100644 index 0000000000000000000000000000000000000000..06323fb94b31700235ed0ff47254021f69afd08f GIT binary patch literal 1786 zc${W<6(JlC20-1Nj}weIqNJ(5#j zpI&1&xhq%7EX#3o^5s>rr^Ph`Ql6ZBh@~YdgQ`=<4$9n|m~W zOZ9Z#$O}JGvC+xS!#wBq=^4h^brF#{ZpX{4{nhSV_~^T3c5u8%Zb_!=rb>4sK1HN39*-;PEFDOLb?v0qE^s4V*{pxG6-z@#EPZ8E@zahHa_h@Tn z^nbHC6{HfLj)NSWV7aoLJ3qG{2E zM>@l&=Lux7K8)P{_v-!T7ZcUzREy7>9^pK9V!3F;tEm}_s+fdY=Q^@E9hdR@H&^2^ zgC^hBBuCviR*7U0ISJ{MNpCZ5_srV3eMW_#kw^oBkJ-zVUKck@l4%F^{~Sz34J?pD=ku_`vTnHM9UE$dqnXnMQ9(ej08Lhihs!Ba)+)Wz$)?S3wq z*K#UjNq^kT$QO%x_*hZ{%r}WV%a~$hqBfg5QF8I3l&lrk7CRheeXt}m$n)uhB009J zNzD%}m#hpu^xsNu^+evXS5Au8T+{20aav_8J|On;QMr7P)SHdbO3m-r)%7Q0Q6~S9?^h-;Pyc$z z&pmHvbcFu&2iHwMzxnxmLA&0s7k+HEU$#$QUZ)q`|G87_(Ny~0|yTL|Noz16pVrq0~CL5&9RC@( zIb=LGEI8QAA*>a1V#C72?E=bDDg^=!N4kaBBV0TtDm3;paI}bUeoFS7q!zf$hBG1M z)HFTcLo%GfY2LHV3wN#YG)g%)-@!g<&WgeZXL?yDIxX3;Nt3bHr=73FYwN13t0OjN z-CY&B>i8n2sco&13CZ4z(=Ejcxj(-YOeS8bxsqRn4a8Sy25jSUyDvGSt{J-b9UF(*ISd~ z)m?oG8s6UCkt_b>)b8!??;mJARV#J--L z5^S9KJhtqiFq(w ztJRmLew{d*>1^hUg&k_YQj)ycZY74Ox@Fz(Tzc^3@+C90WkXxaCl+itqENi`2BzHg9oV<4V+n7s1uX7u6+O*&8c+%(na{G&AtJm#%e(8E%L+3H= z^}&_XvfuB0>J&A>?UC8@r&I2PdS0DdEF`lezq0FF9%IWjw&nYi*?gWJ{2Y~P5XPq7 zqrD*1bj_W^fqm=+B~fgaMn~h9={)P#ZvK9GYP6orgPGj1tHi?OxVOBRFV|WA>7;#@ z=7;^U$9R^Ny6(R7^n#J`l$4wcv#yF&1-udoKF8C1$N02Wq^+92j^NCv-ZqW7W;f#B zf7#S;ve)Nct%Z9k68_^)UX#I+~v?zLk3T^1i2Rl4Ta>vbGt$y?E^z{azX!&pRs!5RQy CH3X{w diff --git a/host/tools/configtool/standalone/wxwin/manual/pix/Image35.gif b/host/tools/configtool/standalone/wxwin/manual/pix/Image35.gif new file mode 100644 index 0000000000000000000000000000000000000000..234edac941db26916f7682b2f12bde34be0dbb88 GIT binary patch literal 1328 zc${u<95`^`|Ns9CqhJ(_B%t_{1x)LJ2vDAI;P}tL$syyh zVZp&>4q>gB6B`yDZWrL?>+sm9)Y!?)%E5D>Fqwf#mXkrkVu4Bnqk7;hos~vQy{Bpi zZ%fJCxXibMnWcy2K=Bjb*}{fmS8h&LVCc2e-xPCd%gW2k{p!8udKsu+SsgK3O;p2p zRlur*!(Fo8VM`+C#hhLhdwSd2XeKGqtRC$Nsn^#uLAA7UVl^Yui8W@&u8s~t#xOYvF_fy@WJT?&fR7|uD^J3c}4K#dph9_udi>2^*-aZ zdt2&N`@dfI&hFm+{{8{kcp08g8y-Gd^VV!ztfh9|hMC^Y|8ypNI6gtfUM)WJQ>xFq ziQ_H=k z+L!76|5aZ+XwFdma<4@sEaPFT$gyP)+hodKB(^iGyB_5zvFrN-=g$k5#l_sLWDyE{ zyKu{#+$zV?Ma~yJ)oyhiRV=&Pf7|w1tao3a+RP%or6r5gtuo7``gxE3xHRFRV_0O0 z`=sqpoG$WSc@SkIcYI>MqaRz`)Znh=X`azVH&v=aTu%hdaA;y_DD#_kB4#$%-0+YH zo^z5)fz6&`;XPGW$JL!Qzpr=iCbSR`_q{^zjkh(mR9rEMQs(M1b;y1IK>`P7WE5 z4GRu7a|mn2oY=7NaJv9MUx&v=rN&M+RskM?1_t+jSxyECiv>>@7&LsD3|4+hIXP83 zep8F2@Uqjhb#tHHsWe`8biO!iPm1RjjdL?Ka+jH8g}iX-;b>J;<#2fH(de@|>+Y$o ztHW0~DDw$?*!t$$YS!8&-qYLG-ripDILKF9;H_gXm+7OUtBNwO&+uV9FB228{N|)0 z$v)Yt9UH@zi@&#W=?*D4yTnMJyNokpdHNYI!}&3{Bnuw3cI(&O?Fr6&(Ac23-qv^b zwzs$WFUD={-o5?({R1mM>1iz3@$vC7UaPosf3iOu^<3;d-*4}((%1f~(tj+bzYm=0 z7CHOB=>17Qix;liJBj^&?dqJ9@{h}(`0X_KanAO3`n|}_rs>~iN2Xn>>{*$9zwSxz zmYda*zHULq0&X56jVuc34_hVDI%M)g4JGchE7+Mx=N&#M7TKY(Y{jBZu6NrWbsHRd zkyZN;J%i)Sky_vvK5c--%hRH0PJEgCM+?_tFrlcl}RM8&Z>S7cJi*PqMpPhFk4 zbzZp0G}XDa(MC@dr!WBrrX_e|6RYt7|3o`hkuFsnIZTpHu zrbo|Ltor}++i?=l1?GWQtm)-ed+3N)!#;abx+s&?Ny=viy bYuW2Nzua5Be)rpVuix)yVE0LOV6X-Nhn78$ diff --git a/host/tools/configtool/standalone/wxwin/manual/pix/Image37.gif b/host/tools/configtool/standalone/wxwin/manual/pix/Image37.gif new file mode 100644 index 0000000000000000000000000000000000000000..d4f0a9fc6dfad39b6352eb856b0ef85dce8e6987 GIT binary patch literal 1818 zc${IeFRH8RogGuADShJvYxGGD}9GL8W0a$3!6uuSp9oE%RpADwUeL>gp=**-oZb zL0Vz!m=3z#{k2smvdw32o37^q<%9ja3)$v+Z(nzJx6RCdN2<#+F7~n?Ws>u$C~)82 zDy$uMX2-_l_5fbDI-i}Jo}QjzoV{#K>E`raCZ}#W-CGLxFRut*9e3AUIdJcWduMllOYCQHViVVlu?U-gqI}npouAZ;XBs6hDv^`jSu*YNRP+0udw&(Z zzq2;`fA~Bbn~E1svHxRli)PWT+VLW;|7q)ax{c<9LIm+`Pwg6Y`RV9Bx<58D;mG#+)ROv`xGsSy>X7{gh6Bq>_m zaB5U}`P-?Jdtbb4QLeO{d3=^I)6_RR6+NZDzYMefV`wOK9YLnm(KoFCP6(0xI}`$p0GbG~#gT^`AB&2nlr zo6wir(G#X#Q7QI2_F{5Lr`_@uQ_iYNr7nKjdR%pCcUGtDbfY-Wr9JJF#5ETiu8dre z5`J)}T3yYz@>Mnecm9`py{7t;d-m!^DUIn9 ziD~cm{&=?f{k}inUccYZz|Lc^MPE)N%JGZZnu1NscKv?1z`bcpN?@>U=d8u0Z*MH_ zlR1B4L)Dr~>@UJ!W~nOVFx!Q03eh@mDcZ=qY0uTuCg;!O2KoKv+~`oyx@F0EZzIjD zW!++TQ~La>v@}obckSIvQ;K}Eym*U$tG8@8cW2&?@R_}@ zcWk?MEB!WqtImaUEMMMyE~wzHjlJfRd|`U#<&%|F_bQq`OQ=1x;oBSjaDv-Ri~GI7 zyjeG{?&5rK`rX6l-)i$uNhO>$65sK2ZNX;U;*^rxykG9JMy=UVKJoY7udg>;&fD>L z+BFl4X+75We!o8%Xg6uSnR2Q6ysMic@1M+`^zYl}dF$`)d6u&_;>8{A^!>Ar$tQog zRg=;0z3Jr6LplFWB{t66cXr|W`*mmD9p|?{_g;R-qxmB8tl=AOeScpc%j-P-hs-qv ziNEg~ID8cL-db{iZ5K-vOHV?ZQi(BV)Q2WDA!#=A6OKZG7s6%LcouRlU25SHu91WuY diff --git a/host/tools/configtool/standalone/wxwin/manual/pix/Image38.gif b/host/tools/configtool/standalone/wxwin/manual/pix/Image38.gif new file mode 100644 index 0000000000000000000000000000000000000000..0fd9bdc334902ad3121c12ce5e67ae38a6bfc9b7 GIT binary patch literal 4397 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 Hht_`p(D_LL diff --git a/host/tools/configtool/standalone/wxwin/manual/pix/Image39.gif b/host/tools/configtool/standalone/wxwin/manual/pix/Image39.gif new file mode 100644 index 0000000000000000000000000000000000000000..b584af079d6b926fb6691a4e5a54274b2c27ae30 GIT binary patch literal 1377 zc${aw!!&U|_Uk z6*uPdX<%4%h($qI`*LwXLr>Wj3Ryw-9 zKy#bPt1WpRD}s8b`L1esAGq1zwO4LeFyrx-blI|{yCOb@uW1)_%5m7a>FMcd@k#f3 zB8{J)=e23RCo@ysXTG?gnV#0A1#!(a{{P-&ZO^;7mHGCuyRm`>4{s@&+x@#8z97EQ zyZyGE8@p1r-aUDW z-+JEP(u2**mFAq^zaJQAY#Ivn9f|1=8rjQQ9yDW zH`^yxamhTGm%WO2xm@k`xvVkShe}t3Z=KL87 zj$cD^oA;VcU|^CEU)I<1v^6X-L~P0p7ll(1ab0nGm2)O1O^cj8+vV%YY3)a3uRL}C zsTld#$=dgn)STOvv!s`BXJ$=Z5jyddSlPP3A6FRHYfpmlqVcG{xh(0$arj6 zaIl#}SS#kl1%(Di0cAdhf(c27yCsapcoYsiI?yi6%_QM@N!f9-vgxXj6NL74BoTsSM%dxG+bPJydzUw?d64&Iuxz3j+ovDNqH@qJg*J-KE5!ToK# z%Ii*SE{NUL$6dZx`=`#$BQx0b&c&2{_B>}{tF3!e!o+R6qVIQC-HG~%SCj60^}OEl zEqHf=g;R;B-y0 zA};oU>a>K+^`6TXG_%NAOpV_3bNRzInIaB_sFjfw!r5CoE#le~ZylT0s&dXuJlSLI z_M|w4ZDJ3LE_Z&9tySm?NlM^$+crH*qVCIMe+Rp8#X_}h&o4~$)e}jW(jL0wLbf$m zda9GY8)t07gxYDTVewW^gZsR8J)hgNU(|G2e6-NlWqE}`l~Hrc%uG_}g+0ui9m5)? zvaBXci$!$yS=rKMB`xbj7SC>4x+SA(%GsS0=TDjSJz|0ZZ&qgXj8B~jD;9-CW~}6S zdotaZam%Y$t2Z2T(t5pS%eAc6Yvt#4X?ZVscWe2&eR4~(=B1viNZ9zw_gluSzPc^< l7Jt;dmOUepD>Em3?=P!0b8iQoytwv3oA$dM+u2wctO54@C+q+K diff --git a/host/tools/configtool/standalone/wxwin/manual/pix/Image41.gif b/host/tools/configtool/standalone/wxwin/manual/pix/Image41.gif new file mode 100644 index 0000000000000000000000000000000000000000..bf25ec20a23b5d131088199ce3bbcd6798e9acdd GIT binary patch literal 952 zc${IG&CGIaNs|XH3~+-NCJvKS-`XohydjY2ac%>oE$P9 z8x}Y+F>vri>@aX(XcJK86POV22&lqP?+Ay3vTLibY+Fsn#E0%3OhH9&ZWt~;-lCa& zYL4gUl#{c$bC=0<8mGHXRx&oq$^4Y=GRS|9nD=>jVJg5;3UC>xkmI0CS{P<#)yKNy4)XstbDJAsM9$TKq~QW|5Yz>@_pcKwkQgcQ0N{BST)h19ZBSU)&tP zMi;Xqi!mFQSCeWz+kE4G++2AP9;v_HR>F4o79tcw~{D5|MH>@dj1u}BM2Hvgig%Gpfx5k5V0M2%%fN~XVjmJNG^mkP;fuX znd1-D%P#UOQW9Qb2x-1YzXm;B5t>I_Imx>{Sf@~9_Hoo}a0l0fwwZQcPOOdnOLq*f zVc#OwIl3VSi^4o);DS4-^bBtblacAyd)3p>-B9Yhp){e$!uHB~!%|iRCu}+IWvh;4 zr1Mr`=Oq3qxM%0@wTqQKKR#q!BaO!+z&3%CmUiCx)qRX zq^&B0*6iVam{Y(h1$?#q@qAR%k%8;;WGQ}0fMl`i$eS(Ro=w!7higUM=aAmjE!*ox zpNNoI>U;rZB$Uy`{F>m=eO|V7{(}}!Zg*JgvWWBt4H=?JY{0qo-BELWxxG(TNS{5r zttT;XcvOCUZ+uA&&YW<=`mn65rG{d@+%DES^PrdO)Tqo6)w7w7b%z7DBHk!vbNNZD40|9NDiaNKq2>!=M+XKH}t_bd4@peEA z-XV~`mye@YS@js>*#fF$QO(W*_GESQbljr-9^Gu#$`{iz>+nwaRA})wW2sV;u&l4< z^1a$Y;1^53ogG#ZZqu3b)Bb%sr$zS@-h@03Ca@V~Z!UT1(`$C+pbpAJg$*xgHY7qo zDL$4@V|LydSgQlIo96Zaun&iyY+uSHg1{j^gFm=(>Oj6TVG**QK0dyqdhfleo}pwD z!bu3<$@Er;)jk%waN4#_S{tEc<7Uf$n$jps(GAI9cg2Y>_n3h2C_K#NoqVdE-9w!O z6kM>L-?kUB?|2gHR9xktfM}Kzp0c~pe&WpaSVAdqIRYImlU}zvVZUE9(nRO>lKKD2}WEY;#AyDj)VyTPB;$* zTVF&Af~Vk~a7)jzZLF%O>-B(sOY4#95-r_D(Ny5C;dLi~~t@~{txT+j2H-~IHueqZTuYX$D2>TA!&xc8?&@?W8 zK#!yUMtE#3n=)MU)KbBk$X(^PhqMh;t?6w{cH6C>hhGU8Yq6&Udx;uJjqfWCNqB|S z7-DK>1cc+{G47CW`2(DUNr(k&r=}|Kfrn*btLqm2d2X7M3$iwI^&>s8_*i@&qeJc^ zDN?9CW8Pq!)LpXH$vIG@0LtTHF2~SM6SM=;{aB_=p2Lw za;`bQ<{KfoNVwRWqO(VBAYI9cB{Yd=2z_aTE>OP9Zw@~sxKB;o_~tWmMwz9gMM}Rj zlqsR>fsq}Dvtq=4`S~K6G|c&NHpNd+PBJKRwS<4Sc#%^Be<;l=!vbm*Z4~uN1Zgkd zV0j|HQJMCb@`8$YFp=TC|o%BRn95nlrE) zsUDqfR5(dhu&h2XFnNG*n50KIK8cg8FYKo%CYL=3bhrfm33-6;JA+UDd!f-OTsq(dlrie{Zc=b86?{^jL{JTGyNyykFA zptjoP8Hrx6|HNr!$UmztY&DVUcn0K@V*IRAIQXOPFNZmDl&Zf316S`yOM@WwSQhKo z{5PIXwF#G855Y<@lLHPHE`3(+N1EEDl8+ZBvQ-8=?+u1wKgIZ@B Vhht243xt0z8<>S`u(Jbh{SBK`IM4t9 diff --git a/host/tools/configtool/standalone/wxwin/manual/pix/Image43.gif b/host/tools/configtool/standalone/wxwin/manual/pix/Image43.gif new file mode 100644 index 0000000000000000000000000000000000000000..c446167c71902fa153d1c7df52e70764e2b62b30 GIT binary patch literal 2486 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 DfUWw1 diff --git a/host/tools/configtool/standalone/wxwin/manual/pix/Image46.gif b/host/tools/configtool/standalone/wxwin/manual/pix/Image46.gif new file mode 100644 index 0000000000000000000000000000000000000000..532ad0d82a3dab11bed58b1082d29b8546a13ab6 GIT binary patch literal 16018 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 diff --git a/host/tools/configtool/standalone/wxwin/manual/pix/Image47.gif b/host/tools/configtool/standalone/wxwin/manual/pix/Image47.gif new file mode 100644 index 0000000000000000000000000000000000000000..b992e11fb6e592fbab292ab82d9a112bbf6348a2 GIT binary patch literal 7511 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 diff --git a/host/tools/configtool/standalone/wxwin/manual/pix/Image47new.gif b/host/tools/configtool/standalone/wxwin/manual/pix/Image47new.gif new file mode 100644 index 0000000000000000000000000000000000000000..c3f9532970fef5d7d2bdd43ae74fcfcde23f3c89 GIT binary patch literal 6543 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 OBH|&v9uXm(4K_a(61n-Pv$Rp)r@W=CWZ- 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 Q*XedfGogI{4#off0PM}Pm;e9( diff --git a/host/tools/configtool/standalone/wxwin/manual/pix/Image50new.gif b/host/tools/configtool/standalone/wxwin/manual/pix/Image50new.gif new file mode 100644 index 0000000000000000000000000000000000000000..debd88618008616534f32eb62d9e1f14ac65aa10 GIT binary patch literal 4897 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 diff --git a/host/tools/configtool/standalone/wxwin/manual/pix/Image51.gif b/host/tools/configtool/standalone/wxwin/manual/pix/Image51.gif new file mode 100644 index 0000000000000000000000000000000000000000..28ab8d6f490b651f67dac0ff0803b720ff9be3ec GIT binary patch literal 10956 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�F>-YNW#7W|Jy8_p((}t`h{d}hReOf}Y8L!mW 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 diff --git a/host/tools/configtool/standalone/wxwin/manual/pix/Image53.gif b/host/tools/configtool/standalone/wxwin/manual/pix/Image53.gif new file mode 100644 index 0000000000000000000000000000000000000000..3b7609078b02549104e3ecbb54ee8324ccb6b832 GIT binary patch literal 8829 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

    H@_2FyHZxiXAZjuWG*QMW%aO{tW?86BC#f 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 diff --git a/host/tools/configtool/standalone/wxwin/manual/pix/Image57.gif b/host/tools/configtool/standalone/wxwin/manual/pix/Image57.gif new file mode 100644 index 0000000000000000000000000000000000000000..8f5af5fc31060b57a473c0346a9c4436cbae6a78 GIT binary patch literal 920 zc${fpmlqVcGN*P!=WIQ%3 zaBO7eV~W`EVL<}}laN%(ivR_ePEqZ+5|4`ykM&3?H}P~9CLQZ%mRyw+A&`2ok3F_e zrNXe`>}-qTS3MRBmY<*R(A+gAGeGTPyR-VHo|z_3y%>DF?P70k(sZ2Ry4I@oRiO5@ R74EC2@o*cyIoQBp4FG$dJX!z% diff --git a/host/tools/configtool/standalone/wxwin/manual/pix/Image58.gif b/host/tools/configtool/standalone/wxwin/manual/pix/Image58.gif new file mode 100644 index 0000000000000000000000000000000000000000..fcf5ef20970f6d45fb3a51b6d5603cb7e6c77bb0 GIT binary patch literal 926 zc${fpmlqVcGsu@^0WIQ%3 zaBO1c<6<}vu&{xFNmz^J!H2{nU80Iy6D%eyJl@Y{T69F>lhVm%CE2Qw8J`|_O;h8p zThd|l%(F>~`Nf@+o0t1fWNzY;^_r4#dbUNbR88cE6=&KE%>7!Tg0qg#G@h*$+p+bP XN0X0tl&jSR&B)Cjrju+X1Q@IV|0X@V diff --git a/host/tools/configtool/standalone/wxwin/manual/pix/Image59.gif b/host/tools/configtool/standalone/wxwin/manual/pix/Image59.gif new file mode 100644 index 0000000000000000000000000000000000000000..37ec9742e17a2654bbe8140fe12aab1512fabe4a GIT binary patch literal 2107 zc%1Fi`9Bj30LSsYdU%K&sn^;oDVry3qQ^1UQc}Zaay$>Mxv#A@#}kTN%~9(?^1^0g zi{#dFiN&!Fp^nU{WBJ%=u$GqsBP<5PpK@@CTpT zXT!XB^%bLK&QH-SOHsK~-c`y05G=cDnC+V#+I8Gr2U}#_kO6;bBDmH-ilxcs0SWIo zW-sc-rW?+VwUK{OJc;3~^;6HQXc-J}YL|L4wG@H6&2=mNbYs%ofQ4w0?&jxx3&kkJ zz6cytQ%Z9$pK6I7O4!7-n7Z+>>=6x($i{h2^rnKHp2Wa)&O0J@WmdgmXQ@*neBB>u zvOWJcgfyS;}P9egwXBh|}UUD<5rK4=~97kEQDp8C zmCOd=F3S3^1*IYqpsV!2@Y0pLW(;>PuL-y$+dT{|7f4m3{p~}yS!FPjZR;$G!-9=0 zz=d&^QA^4F(9?lTC(|h)HPf5GXYI%9Ocm4dm20I;+8unF*ZAAD^89J zgYp5DHAV~f`I$**{%TPM4GUqC#h|6BECeF2%F>x@kAIQY}mnLW0470>^H(6wVNWiERUD(bT=w^g%q744Ac&%=3)4}NoA$_*L%Wq zlbs$4t=Gm}Z-&7A4DafTC!D3tajNL+Wo+?OaMPxE`mY{+$xI|61)dkkXG`YdE(G14 z51=T0UT~Mru9H)GVA1c>j|7{$J~w?#90C*7^_!1>g{}>N2twoTh9bq{p37Q@`el}t zax=CXY0e_K04aN17Y7GHBfSi0NJ+F|>2I;7Lxo$MBb&P$4=YZN4RRDi{6F;SZNv&K zE^JnHHdi%f2LCnl*0 z;(2Zgnp7FM?}Z>TlWG5c^6wS5cCMk;klQZ-;V>C|UE+6L~xP z&K#38KOL^GtXr?t2H{wPK=^C&_V~>}?XEvf0-UqBI>saWc!ON^;SXeUu-ZcmTA7%8 zi`Q9Ay(RC0tXsr*Kgg$COpkNDj2_xHgS@dSyP}~t^^kb%C6pCPYzH$&C(Nt>$~9P{ zoEaI%0OWe406P*>Ao9L?2^czj7qg*po5{cYZWm9q`35S;1olp>hSy;7`Q08$WsojI-!F1EvTlVWDowM2!IzG9Y;AkfP>tte|12}jYe8;2WYChQbm zy@9quf{tf{bkslgW>)7wl#%sZS7B+^axBCs*`5Zr9Hl?NxGOn`QQB9wJsrOt&azMG z@HvUo&Uj`V6vbOQ+fg5Z*hkH)_ Mb^Gg&ssa%I0!%WYfB*mh diff --git a/host/tools/configtool/standalone/wxwin/manual/pix/Image60.gif b/host/tools/configtool/standalone/wxwin/manual/pix/Image60.gif new file mode 100644 index 0000000000000000000000000000000000000000..14883d3ed36870cc4c646415f39a98c071615bd8 GIT binary patch literal 43643 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 diff --git a/host/tools/configtool/standalone/wxwin/manual/pix/ToolsOptions.gif b/host/tools/configtool/standalone/wxwin/manual/pix/ToolsOptions.gif new file mode 100644 index 0000000000000000000000000000000000000000..feda6639929b8dbde56c2d898d0afa3c555deb62 GIT binary patch literal 3225 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 P&QIc4liIaSBmeM!Q6QFi diff --git a/host/tools/configtool/standalone/wxwin/manual/pix/addplatform.gif b/host/tools/configtool/standalone/wxwin/manual/pix/addplatform.gif new file mode 100644 index 0000000000000000000000000000000000000000..4d85ca06e786008a1008f4682631de99e1a672ba GIT binary patch literal 3040 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 b2Xox<oO`x;Z<;<}vA_I(Gf|Vm diff --git a/host/tools/configtool/standalone/wxwin/manual/pix/arrow.gif b/host/tools/configtool/standalone/wxwin/manual/pix/arrow.gif new file mode 100644 index 0000000000000000000000000000000000000000..4db46042e7b1e67995b5ce6e6a6eac77395d3b1b GIT binary patch literal 847 zc$}?LA#Rmn5S+ZU;Wd~lR7w5=6tyIfU|LhC;|iG32ojLIXRx(<1_ZqVeh)!cctq_zYaak@vSePym4j22ipp6j6;Dlu~4Y1RESs>Fq)j z-RMCpqf;1S8Z#If2`Y$CLjx(mfi{+h-L33Nu&S%3N?GfSEOv2<3JVvT)m=T+3Muyv zYr1A?WR4y!vDBq0DU_qZq|MT_6b0F2Xk&R;5tQ7~|W=}%Cn2oePuXQ$()^E_dx7J0q zZl-k=E#I}A)$&fu9WDJ@3biz7vDD(BwMh$0t6P8bf5u_O?e9+y-yiY({_y`|{}MmW wF5aEv`gn4-!`0n(eZ+ouvVGis9#-jY`+7WmvcvoPUspJN`t0({iw$r706IH=(*OVf diff --git a/host/tools/configtool/standalone/wxwin/manual/pix/bash.gif b/host/tools/configtool/standalone/wxwin/manual/pix/bash.gif new file mode 100644 index 0000000000000000000000000000000000000000..411c8b6dbcbe06070ce2b6c8ce87f31cb6d3c324 GIT binary patch literal 15091 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 E7YxaO8~^|S diff --git a/host/tools/configtool/standalone/wxwin/manual/pix/botclear.gif b/host/tools/configtool/standalone/wxwin/manual/pix/botclear.gif new file mode 100644 index 0000000000000000000000000000000000000000..0b907f94585297d0f8b40d04c8459a9db4a0b857 GIT binary patch literal 194 zc$@*k06qUlNk%w1VE_aW0FeLy|NsA#t=<3t00000EC2ui000CK06+qpjE||y?GK}z zwAzca-n{z{hT=$;=82~2%C_zc$MQ_q_KoNI&iDQg3<`(DqVb4KDwoWr^9hYgr_`$T zip^@b+^+Wv4vWX+viXcotJmzd`wfrF=k&V$j?e4&{J#GW7$`VMSZH{Nn5ekO*y#8O w87VnQS!sERnW?$S+3EQS8Y((UT55WVnyR|W+UoiW8!J0YTWfoZD^>siI~0Io=>Px# diff --git a/host/tools/configtool/standalone/wxwin/manual/pix/build-tools-dialog.gif b/host/tools/configtool/standalone/wxwin/manual/pix/build-tools-dialog.gif new file mode 100644 index 0000000000000000000000000000000000000000..5062ad600f811be9bc934a103ac5125f44416ec3 GIT binary patch literal 10855 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 diff --git a/host/tools/configtool/standalone/wxwin/manual/pix/build-tools2.gif b/host/tools/configtool/standalone/wxwin/manual/pix/build-tools2.gif new file mode 100644 index 0000000000000000000000000000000000000000..bb05da398e7ec35b6318d7ee359a514f11b3eade GIT binary patch literal 11332 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 diff --git a/host/tools/configtool/standalone/wxwin/manual/pix/build3D.gif b/host/tools/configtool/standalone/wxwin/manual/pix/build3D.gif new file mode 100644 index 0000000000000000000000000000000000000000..1696b33000e6ecc5366812b62c63d4039e17dda6 GIT binary patch literal 66517 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

    qs*q_25GMWLu&=;+{2P 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 diff --git a/host/tools/configtool/standalone/wxwin/manual/pix/build3D2.gif b/host/tools/configtool/standalone/wxwin/manual/pix/build3D2.gif new file mode 100644 index 0000000000000000000000000000000000000000..12b55b7786b588890da75e1489442d79351e1ca5 GIT binary patch literal 33535 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 diff --git a/host/tools/configtool/standalone/wxwin/manual/pix/buildoptions.gif b/host/tools/configtool/standalone/wxwin/manual/pix/buildoptions.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e1484af868fffcfcea1b54f380e87b54ca9692f GIT binary patch literal 37640 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 diff --git a/host/tools/configtool/standalone/wxwin/manual/pix/ch_initialscreen.gif b/host/tools/configtool/standalone/wxwin/manual/pix/ch_initialscreen.gif new file mode 100644 index 0000000000000000000000000000000000000000..fd53a9852ecbb7edb824877314208a7cd5f43272 GIT binary patch literal 84695 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 IfzgGo|ExN~=>Px# diff --git a/host/tools/configtool/standalone/wxwin/manual/pix/comprepos.gif b/host/tools/configtool/standalone/wxwin/manual/pix/comprepos.gif new file mode 100644 index 0000000000000000000000000000000000000000..80f61dd9c5b72e67ce9c58a9cfc3ce0cbfdc91ae GIT binary patch literal 8717 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 diff --git a/host/tools/configtool/standalone/wxwin/manual/pix/comprepos1.gif b/host/tools/configtool/standalone/wxwin/manual/pix/comprepos1.gif new file mode 100644 index 0000000000000000000000000000000000000000..a910db740f60b270dffd90f747ec686b6baa53ae GIT binary patch literal 23462 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 diff --git a/host/tools/configtool/standalone/wxwin/manual/pix/comprepos2.gif b/host/tools/configtool/standalone/wxwin/manual/pix/comprepos2.gif new file mode 100644 index 0000000000000000000000000000000000000000..69ce08048395408cf70b58590e388b0008d073b5 GIT binary patch literal 17868 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 J#IKQm`Cs1<6N3N% diff --git a/host/tools/configtool/standalone/wxwin/manual/pix/config-f1.gif b/host/tools/configtool/standalone/wxwin/manual/pix/config-f1.gif new file mode 100644 index 0000000000000000000000000000000000000000..5f2f24b3e618232f2545986731c3b7ab470088c0 GIT binary patch literal 93831 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 JZ{^ru{QvrQ)Mfwx diff --git a/host/tools/configtool/standalone/wxwin/manual/pix/configitemlabels.gif b/host/tools/configtool/standalone/wxwin/manual/pix/configitemlabels.gif new file mode 100644 index 0000000000000000000000000000000000000000..b89a43d655dfa1a5114dfe2a58c3204d5ca3ebbc GIT binary patch literal 29909 zc%0pRT})h8mhP^qQ*bDLa=-<~1SbV1?n)pDHYV*!qE>;8hslj2(&;JTYHVSfE-_&; zBEE?)Qujj@*!W)}QalQtJQO4oSvP=<8@FtShw`sbL?oh_Ohvx)fZg)Qie$-t8Rc!? zwbtI}oPDZJ;W(Y1q?-qObIv~dXYIAu`qt0h{O#Xu+x+w0zwv0^|HD`lgC8s(!UAhy zEY8?CV~dP&{H>*hwZvJ=IBQvCEgWCQTUb2K;^Qp7$l@I9j<>M!I2#{l!NA__T$`TljbjUu@wVhm3Q8 zLBl9vSR7}7JwemZ7JSTcLijuUjK|}P@i@o%LAUVR_;`GLF+R?5x-bfOxi}tQT#PSr zm^};%>c;taoG->XM`9qc;ArqskyO|*v<*!|TO28euiA>IMzi%bEG=bE{>lfIXEr?&M=NG;h;IL z363L<4P(+Ztzb$gki5obrH>VZlv}T-Eg%jO5QI-?!I8lew z{5j2#(;PUBlG8Xi^~9+yPPMuC{YU!IIonZG+j%y1c|>3JOwYpEiK~ZV^@XzITox^f_}dgDLdyJf|!k8!hO-(woQXN0m ziG>ngt*oJYX}Rq{QRQ=eUoYL-a=84d*FNt4@^;7ZHLV5byos;QM`~K%{P)wZf3)oc z6=rvb8d>+w;*YH-Snzpvt=c@++s3?Fu&LWfFi&!d^}hS85%J_7#-R*5SFw3)Inu~9 z{X+DtC~&>c&psVUYPu0xzIlEi!vY30eL0z#@dQJIq07SskJZ0=da&;5XxWqP$HQ;e zUq4#){B!d+p6N-SR2QKn;G^du0}S%UhiUI?&g##=hS zfBM$>0q>ceR}Yu3+jhKq!=7tUxRK0so0VaSgW<7C<~=hT2!;*Dl3ouppbMBhQk(oP{b^BC0LR}Nef4oBg6jEC$@gjb*p`} zbnPz=RKI?E>(R<*+vjftdP7LE>hMwk7jw3zTE|r{0OCaw37Fy8OI13w=<~y%@84`4 z#)*k_*2EK>;r#x$md_77oQQ2S`oR-lMHth(teHCX?x5}CA-Y6N0#QLSmxG!>#6&{$ zF8R)N(@kC-m|_LI0+=F^^iDHamYPN+XNd-kgL@-;Yp4aKGiyK$B!xd)l{9bD@I`6MA z`ugiQdf3lqJO8)0Eqmn!<7h+MQ<1#w@IBWD*fcE5SO}N5vZ?dCiWBC+#l){lY8t|k zh!9j-S0bI%ifdjz+&ppRV9Dbz{!ZU8dF@EBF*bjA!$&s+zjUg?tfuva5+XG7tt5$o z$)V2UKmVuyyzurPZ=9gQ>nSAJTgsES|F|uQUHn0L0tFJlH`OOU|0mHP|5I9wbud4m zs8D&NgOx$S&=cF3RVO$NM4YZq470HJw4SPC!|VmCuV2oAv~NAe3h-5ZVwCCLudPly zzr;0c@>c7S5JMqrU;(()V}uPTf#~uwmPkkNmDrE4Sy)8MO{xuhmW7%Pd{W@W0*XS7 zUWw14fuvT(UAW@z5_VthovR;Aodg-^0TF7TEQJ}OaE3xa3t<7+U1O0{go!$gc-zon zU`bX&1^h_YLIy}s7`@)x8)7~rnIUFo==4g%zTD)TV2Wni8kJ2TgHRb41ZX^{5uoJ= z&Cn2}(!?tq^QJD?W7wA%b3p+1HOVqTg#^?s34;DdrA3scAy%6M0)d%3pxav;Gqme^ ziQ5~yyHY0y{6#Rs-Vh8ZAf_6D#iVwIVR@}rVeA4a6^1oz11gkgLiOAeRB{;790t;3;S)C`ONLhFms+EQqfJ5s}Ln`<3Vex|ph7`274q+($Q-K0i-S zJ}@HU71c>j_57MPWXW{Tr}V^+IyAM%s?*{1^xY9aOUMg&!JTnU~j(DuTan- z+g_a8_tpe*?}oX3(-SzAex~_))-aC)BUB=DHK=;l>GSv(M_?5{*H-C z1r$!(6np~^L0dFa5xZE>JVx@kY3Pg8$r1l_&r6%{t7w%w1beqKL+FEr`rf?^ zPIu!gpu$Y)+{UF>LiD75>1YHB`W&ovq%qoLbOSJF+q;?$O#!!A_4Up6xOt08sMn7ICroiEZAi#CrdkTd!2a#G z&JSm_U7x*xSS$&J{o8v}h}7o+*&-6$1z7iHYce^5m4Ut)t>6;9^7?kJs=j+F4crEJ zIG>oRP{qR@MIK_|!cw-(w1+x-yIo2!6kyLdUO}OFI$NA7pFgK`%736MhX@o-6oHwFKcs@{7XliYQ2H&rcmVJP1b?IZEbQG- zY!<*~Kv}3?_g@d70)Wa!qT^Vpr(2G`aM#{DsC8LW>{XEL>KX)N9wzK|c45DPkjw`N zkPO3uvf9mqAwqdMAn%3w8=uz!3|P-!d&i~4`=`>$sTr`yx)2o=6kv;{e7Xf-rt+Cz zo$i`wKPU@VMl#(`H|T)v=t)>C!qY-c2mG;%{|tf?c8!M(!e)tP3~xw}*q^I~(p`K1 zbu2^(%tRWJ&I~~-d^H?p;kkX=g=6H6uuxPzpA{f|GBdN6wiy6j5GOGKF(pnSJZ!EP zVBd&nn&*sT2-fhRhMKq+zefZ|4Iz9b=oEaWR*)=6E}PbaAWnS1?dha*9AHrmTbLWZ z7UK}Wn8qRTnj1^6m+ONzMQ_MrHyRH@Z@G`UfP)GPV;A?2k=?Qub#faGV}B__id*E6 zofb;$P3RZt%Bg9<$|jn36I8&ie?H&AGrMOcA>s=u`{6KDqTs z#Z&y1_rHb(Cr5a*krr526bgh%g+m?6+9OrFKD&WpFEjJB77;B1Q!Purh3Vj~F+Xp3 z<^3>q_T;X;PrW{Q?JzO0E%tArSEvpLbWN%JI95g!-SA4E4jYQLF-Xw1VIPT=P#XwW z@|g%Lr4u*5&qKyZmTT?X`!$~)S@p9Qv!v3hQttH80iM^iTFktjH4uibi1Tkx_z{GNJk$4;Lswt)>PB%iy_ zd{4uIj1y#Ysa^qS#{r+5WL*cQobdJG#L9?GhBcZqh<$b@Ka&=nyCf_NoYx@fi1G%p zJkyK~ZC{RXSHJJBYn@|XwYrL&@&;I+6+$B0e#FK69&5?}nilhWtR??zTFe#J@?0K8 zz+tR4^ZDrNSz(6t+9O#w6bV$lTz{GJ{|C@#Zmt!vaPI8;!Gxu~7b|02Q`j~G+Uk{N&qtxKFJ@q{$p)i6Mr_Axb7McA5r#nN6Q|1J4}1rjFrx^N%+=zoetSXLf+ zs40*ENSgfP_`fiH$is}*uW8LcBUlSDVE?PmDs`Bw||I)9uca74z9lj_Ra0<>(&%@3qi!?pQ@U zMRtm&583xholSal=T<9{*0BP}%CDLw({7t-BpI9n&d#LPl>`n88*&MZ++cYDJ4-NK?!TK}8H<=#%Mge$I{t zpZ?{?o$u9m9DR(dUUNMm!fn;)${4YN9X=7`pxz8SBqvvnku!k|Kqdn-EM$e-$n3-_ z(3$Apr29Ken2m;-+CAeoht1PJ6@TEO^Wod z5wCc5r5Z&IlxBS|3#E!aD9G+Z6bclwj^vDk3L}b!Xv-Zd6eimgN`+kJb3p%6cx*K@ z1t<6@8u+*U6#r87m>=>R%6Quw*deW4_n->Lp{D9r5iAqx&< zx_7qdmRE~*1ZRc}3I`}=X@{GWR!rG$dY!WJe;}V85@;EHdL_6KC}=26f4_9W4V#@M z<@S;LkXZ>kA8l1#D=`l`35l#XzBwfnK{L6mgq#aWpCAf60McPoB!d7=+iqE(-{G`$ zD)lmZ3AtE9fZY<%7nt!?ISmc_2bz(~ij)>Tk*>s0wVp3>JGEKekfVx&YOU$kGF4?j zh@}xzKH>UEzn`u1Vk&lvT{WX3tp{)kB2qk&5*;SRly>t*9kU~N0@ZP`nEy@D45c$D z>{0o)sYcTy%lYIsap_|UmpbyXwjD3~$-d%0c#FFaly9Sd%G~1B)4i96F>K;p0dPJ@ zIb#PhD!ehi_`!y~H;%7qfx@g>rv&W3K}=v{tml8}p}ip%^cdRMgSy1=HBWjM=&K@S zqP)WF(wk^I9+`t`L&`1Vf1d z01zbRyuv1NDdP6eLMl@{%bxMg4U=ScD$4lTIVWAA>1vs{W9Re;Z142|&TKYer9hm1fn_bkX^CxkRTFNOpjOV% z@wtTE0#M<6@C`;KD3!d}_3|a_v21!Ac)Vf$qXD1w+_UxW_annwrR!)gdWtxr!bG_!$ zNzE`U*O^4S#X&OJNRBy6&nmdt{yah&hShK70!PheMZWi5KU(?eK&FhcmIwh?oBPL* z$vtvwQL1Y~K4}(D5bT?kQ>Hqj&oQUd`pS?EQC==HZ5C!{mw7~X@k4f&&|Lx_UOT`- z?LnNF4UYXTSo8&rmG22L<4F!sEk8Q`3jxRMj1mZPx+;quE-a&twpgw02;@0|q^$4H zc>12QUrnIf4_0F^+k2VUf%4q^jn4s6_@`N?>U-)?kjRAb3B@Uix>QY9MISA_fh^Aret-bDq->gO)e^+re(|sE2}_$InOC4uzM+h!ECU& zj(&B1M9EdqZBj|INVl_AUG1whF}cXM!U1hh;reKosup0yFmbQ%&Z$UaMb0+P%wQ_f zSLX);X79j=VRCbzKS|n_lq*0m49G$O{8!!&m*0{*lrqAAN%vfbzGOaH#7qRkY%hJT ze(CcqDtB;Ge^`NcZ1KTzYxFV9|9Wfrd=lvL_>d@+&hN*Q4c;?F^Z%8#>;CTjZ}Ugs z?_vaA^Tf(G8y0U*2rm8SE^_BSRl9=c;sT}>c~O$vpYMLe&nYX(u|r8-aw%QEr<9J{ z=Hlda*O+|Sca6zkw_@^2NWSpT9g^oi!I=D`hGf1&NIsk!O#{YBfc(!JAo0s^S~54B z<^|clLcj*&jq28T8W_*CTgiYeI(KO_D`lupv28bCjMQ*uz9y8 z>1h7&>blEWr+ikT_}&}CO63&^efqluO8HMUmb1a_~h9~Z2Yh-zhX6=CVR5kQ-QV`@MU3bm?li(p>~xq#>^@kAt@ zVuLPfEBqka-ReajB)X)SbYxl4L(?z9g=2&<)4MO6IcXSCL792#sl*Ju`n`G5Y|70b z9r-7x@hs*{Wv!m-RnBESG*lV6taxnlrY`@MX1ZlV5I6aLfSUHDuiIEi!NfvWEw2IPOSsPB6S`@h%D8tHaszN-0$kIQ+7 z>q)2Xv%SEKfvOTMg@wG#cx<(LLMd7ftrvTGuPH$i^@Llcr&>B0gsc!;l~5xp4o9@s z-vQX)+P{vYjxzcWCYAfZ3ZzdAH)4~*7cfECqcRnPF)ohoGbWmrdGY4i*1UOYO(uiY znk`zpz6lllu;YAYmytK)0W6mez$vZDn&Uw`J?D5Q%8J1UiclYM`${;wVY8QNMi>g@ zSnmww-3#TMLQHCS`OZy6ajbqmhUXR?ex07rhLmx19LpVt^7*d${x8uStpY|HJ7Do7p+9bTQe{n5l8Nb3Q+>j&Ro;#p=}%^2PlsrH)li_Y62g;+gu`?4IkN zUq8lIKmXd?9)GH`(e)Tc?&N=K9nz^Mcfq>YEDA;zo$53l2<^FF{coTzp2yhfW6L*D zX^P6A=`oH^;qJAVtgQLO%$eFoGxN2c~99Yh}nv1}=PRHd?as zYRCJ`lr{WJalrXO2oK6&XZo8{?MXWFbm!ESq|=v6U_wOh#9=Dx3b2H3hnjG#SP0v> zUZ&e^a2eKc3fQC+M>?}}@4Ig;%ixprm{wQYC+-vZ3nCQA5P8@kB5no_m5KRwJi^2< zIB3S{%&?6f?3WNGES!cERTIa@t*kA|*Fe8BL3qcRr6^E(IJ;#GDV7GSIQcEJ@G``UwK(Jnh&gRPs9<>6zdWEK7MOs6{8B)Ym$ql<-{A4Uu8J)tM zq!X2&4ith-5Hb_*B96g}mU-Gd9VYoLr1aW8?8sVCzPAo_IYFmYkY}j!w|p>ASp)Fq zR>X0P?hQOxeb8^kA1g?-wu$(A%FL7$K4C_j%)|jdfhm9oMC2J(UW60_Bq4CYtMB40 za5`TsQ{@mz91cjty4%1MLUOG1gf^{C-6zz*w;ld$?q5o^jTDqt0eDSajznkHG?6wf zD2-i=pM_dI_A>+qRpIkZiq(uauLz61r}rQhdS;c$v{6%+y@KdatU;=(}uujoKqtb^68 z@-Ep8mQOg0kC2vnJ;apHVS{qTcwy}c+tP6l1`~lFcbGhu!-QmzeNhU^sW$maJOPw} z;^jFTxgK{QBim0RE-4dv+xDG1GO-;KY*48Ay^4t+F||h?PutVG+*yeuFX1f_%jt-n zGfy}Dm^bTWU7v&U+ss4PEpdzL+5PO&+mn*<5K{Py#Wi=se!pbSOrT7&oFQGJ5Y)Pa z8VL&Jl_xTfivfZn8(tb-Lyayclnj~NL@KUi81&@A?NK}EX=bfR?^oDyHxp@wUfX3+ zza>YIw;t221O4KXk%&tjjS#HEJ>mk*cg#85BcoB4XL)IL^CxG-=DCY`_7I5`o!PA# z_#fr!tk&bIQ2dn(Ssh7~fjs6}0PFk$gZ`DG^6Qhi#;Tp9jdgk~>ugwb@i1GAw=vT5 zWDfZ}&HaNR2D-dvlThlI$7o)!5GPbxQnRVsNVJV4S@ove>*P6D5%sR(( zK}V*hnQxtxw&}xpVR{0MRAM|dQr8fq7Ct9ixF#Z|RW9bZl*Imu>M(hI3Iv4m+6B zHcXOi^E-D5+FSYgcpDsJ%xSzhj>bjIJRedmG>x*g^~5g;mkZ}WiBcjt-dDOm=W3yT z%4d0k?1`&jJ^Z3CcRK%lzYY)N2Q;1&L$zZrPGw$}E2Z7euzPU)h3 z-0~saaJO4t<-u(H&QA`wC3-%St2VMTHQTiEt;W;Z*vjZ;1X1^8d_-4@>^ zqQdjf=g)E7;7=fQZmcU9pbPlYQ2u=R*uHF6NUh(hS;wndC{h&y!Z`dqNF4v0uSjr3<`e<@E<0nCj!e6D=D=MC}BJhG)URIe?(f}{6jU63#^6_n?)0Lgb{ zJJ7|IaFN{mQ}i9JBpub!@7nvX@_ZLqCW$La$F*^vh*#!8FJ(V&U9b-P3OQBPgdyu; zD2OY|m8%GWC7Z|8gE#0CL~0^n<%-0rYd5cEi3mk0TZE>UTcer)Z3*$DD@2YD34zfH zS^}+FSVVH=GFVD$U)GmXxNB+~^yTHtBNW1+SQ#@fYw`5>x~L0J&>DSkrHQ>M&US{y z6TcS<&;=#BqVb`_;fy zfj10>fOrz7uW%gLw75sX;&BE0EBavbzgU;*h84B*Xy%H_*RE*nzs2h_a1 z=6!|e7aO1!muslbg#v-ndwgJrwA%M>XUy~e8ED2j*0}IZ4CS_Y1P%9y13_fEOSN9Q zG#QToGc{CavYX7kf<9nJcv9JMIZ0nF`*UFzF*^MHSpjVynDbyM_BG?d=_IgF&8g%A zRt({Muz>S1mBi(dsTsfc!wIBFNN%f`b_lQPFCcOXDq5y79j~!Nb;=>Rvf6$>p0_DP zn7N$B%lCWVeT(kF?|FPP#XIeD581a{%NynBD?9>EL)Dti!CSMCPhd>2ax_&jXY10U z$HeLS}jaP~3uoyifpZ zH~{mK1$;s)uP&5siNO2j4M`&Pzp}}eQ}=5=P0Cv{a;;sE9Rb@TD)%gR-Lzrz4ozk9 z~mGHh&mRSLAH>pn}NvRwyu4Q+l=$GUiGx$V2iT|4+j zSHno3dYE$TECeCgJ`L>zs$5cYy6Lo!b*%{e@Q`_AF@*VdQS*El6GOzSJUti8sroFB zQUOa_)1aulPfQilIZDO-45spX!n_G9Fehw7Tcq#W`}d*{(7Mby<7uH`|B9iTP09^y zASNxl)VIUBGKA)=Nc2p%U=x~i*I86vh4TKReAkM?~2Hk}Zdv;Lj1d2}sgsYxTT&jh%9aCPwmpr_cFM z{erR|C@nHyq9Dhs+~N)Lu%6|)RiZ z=Rb6V{NXJgbvu{kBv3nhSW^CbbOWz_fXC!IEW$ zmw_@z-kZyh@rAM7z;CQ!{>D*y_uQPfSFl-j z20@|sf~>P1WMSkAeZMevtNmepJZcwLhf%(gpSxsDh1u77(s`pLesAv(z*Dh(vJ)a| z0WUO;mK5Oy+o<8HH)1YI;y|W*!&dZ#kCuQkmsvz;a9!rZd9T0QI?85dPkkU#mH+{~ zjgf&0Kt>yk#F1jptL7~1n|b@7_fL-$QO*%d9KmZz#_;4L7(vc60>W?JJ6Xv{KD=dJ z>|4KuWxBV&Dlg)CwNDOydx;joi20-Lw8RlP(*z!4qFy!#Ds%pN|yT zbTOQNE$3kqJ1uZH9-pq4EcNDOL?kK+L{wr&ssRV(YX=D}KId=35X+`nH%;EW2>QsX zHNc7Z%34FZKe|`Fm@LaDD3xyaIy!2`m_G~9u57+1{ygSKY z7$%{AhWFH`Ni+P5brJLeV0?#5rOA>iSx$grvy1Ai#2`NE^LUj%N7q~@rIJG#o7o`w z?}`Mvx=Be*`SWeN+m$m4E5rph#Q*(&PDNb$F_aE9Sh?a|o;5`d+U1<>de9qTFa3Y8 C8*`EX diff --git a/host/tools/configtool/standalone/wxwin/manual/pix/configwin.gif b/host/tools/configtool/standalone/wxwin/manual/pix/configwin.gif new file mode 100644 index 0000000000000000000000000000000000000000..98ad4136824ddff79c0e805046fb89ecd0628103 GIT binary patch literal 24399 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 IWxzxK0o`V@*Z=?k diff --git a/host/tools/configtool/standalone/wxwin/manual/pix/connection.gif b/host/tools/configtool/standalone/wxwin/manual/pix/connection.gif new file mode 100644 index 0000000000000000000000000000000000000000..fe824f12ce23f63cdd71239a5955df3b3547e81c GIT binary patch literal 11057 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

    I` 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 diff --git a/host/tools/configtool/standalone/wxwin/manual/pix/ecosprojselect.gif b/host/tools/configtool/standalone/wxwin/manual/pix/ecosprojselect.gif new file mode 100644 index 0000000000000000000000000000000000000000..758b27119a4a21419f875d48d19a381f8c62355f GIT binary patch literal 15853 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 J6shp`{{!=z8FT;u diff --git a/host/tools/configtool/standalone/wxwin/manual/pix/find-dialog.gif b/host/tools/configtool/standalone/wxwin/manual/pix/find-dialog.gif new file mode 100644 index 0000000000000000000000000000000000000000..28bf86e2bb1b34fb48a255f2fbd2de6189e1dff1 GIT binary patch literal 11190 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 diff --git a/host/tools/configtool/standalone/wxwin/manual/pix/html-help.gif b/host/tools/configtool/standalone/wxwin/manual/pix/html-help.gif new file mode 100644 index 0000000000000000000000000000000000000000..e3d9450e7e83d43cee425a1ba3638a918d1d57ff GIT binary patch literal 73279 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 Myz`>R!~W#|1L}HkVgLXD diff --git a/host/tools/configtool/standalone/wxwin/manual/pix/install3D.gif b/host/tools/configtool/standalone/wxwin/manual/pix/install3D.gif new file mode 100644 index 0000000000000000000000000000000000000000..a393b4dc2813ba1568cfe0356e067bf27a86c609 GIT binary patch literal 47382 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 S8!PZ-3w`m|-s%srm;Vou%z&l< diff --git a/host/tools/configtool/standalone/wxwin/manual/pix/memreloc.gif b/host/tools/configtool/standalone/wxwin/manual/pix/memreloc.gif new file mode 100644 index 0000000000000000000000000000000000000000..e75043b8cee5137d04c017a553b1564d0975a9a9 GIT binary patch literal 18903 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 l{QoA&U3G-ay(a`SKlA@58{tu5ldkX*n diff --git a/host/tools/configtool/standalone/wxwin/manual/pix/mlt-region-general.gif b/host/tools/configtool/standalone/wxwin/manual/pix/mlt-region-general.gif new file mode 100644 index 0000000000000000000000000000000000000000..781232dfa117da04b2d802aae6c45fe157fc3688 GIT binary patch literal 4819 zc%1E(_fr$x)`bNGX(|>F5W8Tc`MwHB6H!5WRaz+0A)wN`Lg*x+hCo69kzx{(0Fpo| z2uKfAx}YK=gf2=il27m4f8v|D&&=9u%|3hocFr6;g9}noWE`GpK~zhKl-!qXY_ykkN+oJ+By6m zm;YP-z6ou9&LJLE5qz9kWsN)hi<^@~E*Pfj2b8oz#c%j@cLbESr(e7a6*dSg z>xkjLAa2`9deepc$3@-0G0?L+Uo~Ldfqn~XhP)Fac+Ri}_n}ljTh@^^gpEI9&iNfL z8L|+6h-2-fyHis>ntQKdq3k+^_>t^Ah7 z=M_O5w!9j7XKikf@TBiu{odBsAFLJ4_4;_r|(%0B+JACTvM*5d%Hpap)JLZTOPE_kM}}SY!4}o zcu%LP&f=!iH8myZ2Kx=l6FQF$solXi2C!tjte7szZ!kCvegTgRV0|xYzmp=n zNURw_i`EQqr19^iwWOp zJ3fSy-C|j(;@;fb!DC{J%B`l%#kY^F_kLja4))kBXZ-4beM!5H)_e)k`)mDrH-4`V zO`cYt8N0hQ4|gB^jepj3e#CWC$1et#la6m2+wgHfnjGxSHr%*N)#~%RTd|S+;{qv! zwD9Mn(a9!wyD3F3^ZG9M4m}^Uk>%!HjTK3K9nXg=;9gja7T2^ss0oo3h+K`oNEGHp zUQ^@Q^@uI`cGPco5Y1e^@$!bey~kzUa>bASmQV1PQ1?5U&!fE(GG(WDZ|Upo>nhp= z4mxvQbhOAkU$`%S>f4|LSxYwdnZ^vg_!t%S;D*{ym~)G;NL3gqxNt7@y5SYcQCyn} z>EA1R!8MmPJ>-Bpcjz8V!> zg*){PfH&1L>&j&OYV{e1|_vOknrUHLZ(-IT9b2HRN3856A6FM|bd74J8* zm2Ft29wY=Zm+;Ei%Wx1qULzCL1a&w-FvsXCA$R8?=0R4s)rWr%VO=DgR-w?xBLaOm ztecOSpW!gRL^@)55VYnhsQFn}x%_4Te#NJqiGzm_=}`hddKns3>BGb)t%X)>Lz~iz z*q4I?__YPr=)2vGDut<8(}|q{UrPDgq*~{3r4aKLsC+c{vn7EB8>vopjy0q+^<=p< zPU~}-$P1odrlQJw$e)g(_L;S5+~u~ie3kz^F5W1;cUR7C@Rf>vxg*L$z-?l}QjXdu zQ0kv-g_TKyh=ssbPRH2FXgiRiiW&(28) z+_7WZO|1(4(wvDt=&vlzqn1@-On{7HD5_cHSarfx2cv`35vc6pWiJjurLQg1W2@&! zvX?{o(Lvi5Rm^dSg{%{^Ni0dg{dFeU+FTa1ZKY;K1N2h8+%^%pm&~X8x76ro;|XHLWLFI2wPg5lAQMMdDa{B;>*5~ z%Zz8;2)w#*(OBlr*~mEK=OA=co$0~3-4C2;vH;z|WC@KJ=&Y?V%I2fpIlz9{+Ye66 zNS&|n-Wh0nU+USr2pV}cW(eM__BvATeB(hye?~->u8>cED%_{;knF}U(|VALSKmlm zn*=G_B!TR4>#S#QG=){7@C;$W9M2e5q6kDRKMNyHeCZXZHNUJ5$Yy%CXod0hR6I|v zW`0&1RH@<@-zTj(YI7aDDaA=*g-Ez91*Lq*=k@bgxc|ZjA zm?e#qSjPRq?VH&eqJllN`uZnx@A>(2O>4)0C9$F^l>Bt6Is2Ykoc&G<%h`eagLRx) z{en%*70m~`8*gKrBXo|8jZYkGf_rDHy1ZIp#%aDj#!EE)_rPjqcW>5y z!#T3>H!vwuZ2`%<)7y7oqBgWRvmCrdky~7P8>2Br4cXZD&-uK>G8?MJT=?zh7~@cD z#+jZ+D}T@f0;l>$zW=xz^1L;s*-e9bD*6{SnsWy1)B0j#6pU_uxitOK{!Pr`?Z?yY zU?Eye{S|9-X)Cr3m@xRrL^@719Q+_L_82OzV=a7A@5QE9bl!t#S=IQ7BUj&Fd#Qwq zS4YJ)UyFQjD@tqombQ3;#;pV${>WS`03Dc6uqoq?{kL-KqA`D>sdsR}YFo8HO=#z6PaIeKtF9<)is@_If?^n=SE;?Y2WA0kEo`i zhk^A;7Q~sv;FE6I@Fz2>85IL*nZMG^lapX67SVIs!Y4DfbThaOB-s3E9{MTCwkdW1 zt#>yuE~~1UA`za46EdWf(oaNWounturKE{LvPA4M8#)xutHI~E;F^4?$JwxJ5ctV! zseGOA798APEW6t_TO}e}H81&ZBQ?80RCvj+K6 z^YBPWzG!*A90aH?QSe@^pe4^#b3R|EGph=cMch%eB_Rp~3Jc5gx&&N$BDALf>0AcL z6#9c<1LtakEWNgjr}Rv5OkT2`*QCI!Ysy(vIx=cBgH0|BvMXA=?mW8l#M8?nXf|(P zr^pb3*eZXrlLzN9%-}Ud9|5Kds4EIVUr+74s)N|yQOi9AM0BX3&!F=uJ8<0al?s8t zK3e{1v_u8w{<>AjBiC1uoMJJ_?A#_FhL{%UNvE%DWKt^N>6P7l(LBW9&gol{MT_3a z!DFs9q0SoUf^|2iqk$!R4)n#6Uyd1LZ_?<+jq@dL zhM3bn7%~I{EyDm=nBVgle^xPZWxhCw5g{6h2?K@)GO(cW;;ReTZ)4avhP*2SlL*uY zvq~Z3N)b?8njjR0FUwlMB>>B7?Xa=X@&NU68&-MlLb;P5J}waFXNYff!Q;@DC3q}h zyd2HKRYe9P)d|nW@tHn^jSUX2IMokazU`Nh*g>MreamyU{Ss5 zeQf0>8sCPlnifQ|SXDN*RfmkKR@Cu4`8mHL-;eIYypbxjB1T0 zYL5z1B2&mj8;WNX#XFzkoQrjxAgKvaNI`-v&g3yGU&G>_n+a?Je}X6AjS2P&P5tNW(&*a7fN%6#0jtq{={epiP)y zK$z^=%CY(S4vmU;d(=!=EIp2{JT(zonRHt@vP^qD0dimDxUvYZX1z6v8DdmQ=Jiov z)^EbFdwcq)_Rpz)dpB8q`RFiOP%47ozTrNVVPwXM{Zq%96b}CY)ss+uHHO-ozOhn|VdHPiAv()=_%6=2It=rAUpIS`!Tg;^jxVR2! F{2$W`Z*c$s diff --git a/host/tools/configtool/standalone/wxwin/manual/pix/mlt-section-general.gif b/host/tools/configtool/standalone/wxwin/manual/pix/mlt-section-general.gif new file mode 100644 index 0000000000000000000000000000000000000000..806f1f52cc0c45390d3d72df5181425005f854e3 GIT binary patch literal 6660 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 F06XC%6*T|= diff --git a/host/tools/configtool/standalone/wxwin/manual/pix/new-configtool-conflict-options.gif b/host/tools/configtool/standalone/wxwin/manual/pix/new-configtool-conflict-options.gif new file mode 100644 index 0000000000000000000000000000000000000000..ad83ab8e9916526c3c9e0f4052ef1faa19659c77 GIT binary patch literal 5242 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 Rs{e0lU>i3xGZT~Ae*gt`@k9Us diff --git a/host/tools/configtool/standalone/wxwin/manual/pix/new-configtool-f1.gif b/host/tools/configtool/standalone/wxwin/manual/pix/new-configtool-f1.gif new file mode 100644 index 0000000000000000000000000000000000000000..e07ebf7e48cafc579b42ed67cc22ae762031b3dc GIT binary patch literal 18857 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 diff --git a/host/tools/configtool/standalone/wxwin/manual/pix/open-dialog.gif b/host/tools/configtool/standalone/wxwin/manual/pix/open-dialog.gif new file mode 100644 index 0000000000000000000000000000000000000000..55e53ce0ca75f544153b9f5f4051d43fadaae891 GIT binary patch literal 19275 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 diff --git a/host/tools/configtool/standalone/wxwin/manual/pix/packagesdialog.gif b/host/tools/configtool/standalone/wxwin/manual/pix/packagesdialog.gif new file mode 100644 index 0000000000000000000000000000000000000000..7b7ac0d66ea472ec2090dcb0af1b0d60a4da2a51 GIT binary patch literal 43149 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 E0<4hHo&W#< diff --git a/host/tools/configtool/standalone/wxwin/manual/pix/properties-dialog.gif b/host/tools/configtool/standalone/wxwin/manual/pix/properties-dialog.gif new file mode 100644 index 0000000000000000000000000000000000000000..9a463b0eaa8d588b753de658367a677d6245db53 GIT binary patch literal 15344 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 diff --git a/host/tools/configtool/standalone/wxwin/manual/pix/properties-dialog2.gif b/host/tools/configtool/standalone/wxwin/manual/pix/properties-dialog2.gif new file mode 100644 index 0000000000000000000000000000000000000000..9a463b0eaa8d588b753de658367a677d6245db53 GIT binary patch literal 15344 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 diff --git a/host/tools/configtool/standalone/wxwin/manual/pix/properties-dialog3.gif b/host/tools/configtool/standalone/wxwin/manual/pix/properties-dialog3.gif new file mode 100644 index 0000000000000000000000000000000000000000..9a463b0eaa8d588b753de658367a677d6245db53 GIT binary patch literal 15344 zc%0Q+T}&KTmcCV8T@+0>E^tFIVVuGt9-PKm>^506n~AD1&a#m+!kL*C^kRz;(rPUm zi9{PO(&nMNF^=s_Br+OH>1ZC>Xhs@s_+Pvtu^+&RM=0u*IuBNl{DdtaElyu{)hU#8P4hyUm(rZ0 zG0<4>HJAhD&(StGB^V5p1}!<73I)U1Ff@$C(Q^12e#2j>P~d1tm>-CRU!_u^#KEpG zUC;tv7I>+^Ihq+)C5?U2&>XFfwoBuuXbz5xfHO?vNT@W&H9zI$s0JWH>VZlv}T-Eg_GSmS(cOSI9Z3&{5j2#(;PTy$w?1Rk~odU zsW%tD|3ZHnXF;uPV7a(CtsQ)NWNZ1xr|;-bzWB?5mASk5-2BMxsXsit`|e|Zb>a5Z z%BT^ehIsO{GWF87nGZ^uu5X1*Nv>(^%Ip|-E`=UD`H%m()Bf3&#_zv8|G`eHnS@tu znP8Slxp_@D*mh4YAcgea+0n#w&4CNI)WPgVPN{2s?n?KKJ2TG5 zG5{jv1*RLuY?CA_Be#y4+3ZAx*`EjZ{ajmG2}L!QHFI)MX2zfqV~V}CF|f%lJ`xmpCI^NOO?`ELW1<35FTS*WbE2|X3v({Q zRF&}UqvnPw1%g`C7~Sr{CrYP@=7=2b|6uSz-{r{np1;&`?%|z@d6`CrKWuD;SS~jo zCfmVRA>A0vvYgcrPdZIcBdGa~JO?8)wXsuY*__8fWDZdEHt8%co>Ce1yL#~ZKl)|w8xMMtw(V*1N`5iAuxO6rEjM0(6j&a zwLaE=_29AA+rJHs8t^K#CWB9!N!uqu>42{<^j}k#q_rcHMk3D?O&bsHGjj5*rjtv{ zw5nMd6dNjUCoa`CJv08h@`KY?8lL*muZF%D+ccBUT&PCqP&ahW?bCTK;SSylr!rrP z1{aUi1$U@_QM~@Ht9R?#o6f60JUlb)k(w!ge%IAGlKQwh&L8%Zy06d%84a|VR}UOH z`gnv5B#zT2JTG zGi(^2aDyc)5J)bsC^lUVA3Av|6J+2*o~$<5{?X+mTmED}h1i9IUhfLo3PFgDz7-*V zu@}5H^~%<4`|0T!h;A^WhTI zB0^NHSI8&5zP)T%A_o1fdFbSL2IlP15YqmQKFbP4GscGYB*kVKgN32VxcKbbCm~2( zm(>O4Nhi3~Jv|;QUxTk|6|6x z89pSB4(S^Swr5^Bo@_a)z(xWYP$t64LVQa|t=h+e2 z(99#JS>sbL{-X2TT>sU&g#r3JNBPAxC=ehdD8De)jZPlG^prJ3Y%m6$80<_S3LZm5 zXc!63fT4vhC39xmj3JuTJ0ZC;(ZHc0kPK=7Y!|{5gxlb)K@syg%r91UQ{-;k&H~j& ziZ^(7>;vtM7TyR9A0tEsp%spH>Vinc;mH?%25|7^OtLxk z@nuS8AzD>uK-zU$1RFvZC>mr$YdYdpmIeevi2++qj3r`~=G1WJ%arqk8snKS@At*( z7DnE+pNLoCg^|C{ymsUIguC<4THe25&GfjtGjDkEveRrO)EplF^(bKS#ip*_atP+NixKx%6S%U#M8Z=etDiK3FC=L{ z!!6Uw_SYwZb?WNN%Rs$gIIfaa72NznpGGBg}m}v@9UuBOKbbdB%p84Z!vaNPVq%J(rY+4`qH`6ylQzvz14P zcR{qePLG~ zT=wxh0&ik@WGUL!tD7*vP;(ShGAu^5(KUqNg8L(9AvLV7l2kRY@(5p8ug;KFGkO-y zstf!>z#9@3{27p&dzh2;p${_wbTNVLG5ur3K*v6~eZYV6%F+tONEXs1WMZu3I543$ zC7I=GiI}_)UK{JyKbi;(+Z21hz;qc1r1NzZ^3w#QH*f(P+oO2!1q+i)s2L_c$ngY$ z#Vcqi2pJ*Y=I0lKA=o2OXSGo*om$`4JGs4KCRsQ<{u<~J02NP8jvDaFMmv8}MWi~6 zkx*p`((QJu!0nTftcm8hO)%NwPJ%KC`cMVV=dA`CdAw66m>Y%(iqDm)m-seN6--M= zumTutuWxVU0yXszs~cFZQCCkwtmcwxefYB~3WT7o==E#)NpO3u&LS|Mofr8wby0d#z=$uG?Lg3t7^Y-}SvVE4 z2}B=;;hT^$atQ6oE=XrAOSu{sBP=_?nN4*(#&bTi?RpDUv4PhjKXJ~8WkeT)+`W!2z{tQDbPKg3VM)5 z>i910@g3244BAPOfw4LYPT{E(fM$t&l0_klfZw9_kfrfew5t;~NX+dBpD-!bugO&N z^?*pfJSWmp%N5$anqVA!;$ww9^x+8)RY`49UKm`)-A81u{qrT?OP(H_PO=594L1pg zOTtuJPG!nP@2>Mr_C-abTA<|KUuUli95!_v0HTOKh@%R`nv8}HEQ~zfJBcZyralTF z2jdZ5*O_n@5t7gf45J->JiNN%<-ms~s+ z9zXL6Y;4h|fAX8b8+|jOCU;}mh-H(Y$AHc(YW!si5o@%oWy`{_duozz+eJ=h?ei{B zpzZ~#SkjNiLN-(zUdwzjcjn#Zy^lU<^ zsQ$E1u*N9$5oFP62>M7AlUO5_PdpCQ@X$j9G5?JU5rUYyd1RF!Yo^^0^O~|nYX|XQp+%w0PF%Dh!55fH6#eADMf=gBJk7imHoo&@4o36=^qhhw(JUoa?_TsslIN{4Ls?h?x;Z z+Xt)qY@ec5r#sbA1U%u^Q<*^n@%i~URxE)^jKqh^*EaLOPfxXM`EJ7zSM|Ds$gCO( zjT4(xBPj{8!}STZE_GrEw_z2aKiiXxz13R47ch>Ath5>6?0qxIE1}de5dY^Ojc$Yk zfrX)!lY|Ru1aZzM=ZB7E_94888mZWew11}+q}Ry1utTjM1=cgbK>?MgYJpQ+&&$K- zAKwBs0NXVn-S$~<`#?p&bF3icfnu$z79`^~COhm$;7yzGK7|w@WZ6Dg7y1*z#Mx6X z5B0>v^ss)?|y3*i#rZ)LmA|H^b^ z6qGfS6JQFi%AP6;F6J1CM?LNmXf6vI0k`BEJ1Y+qt&M^N z#rFbHjWM-eR2_2jHg$Ej;+oXQmtoGA09u|Nsva4+&uWlq0(CX*qbql09`K7Jqio5l zmO8#M!*ewPu9Zi(-!o^ovvZfXkJ{Cx*RT<)M{keOicy|>l*t8aGDXds%Gih=h>$6} z16%bAY&^pSR~i!WjIVraNKRo;eG2pGW0jgPEGCLnJ4XHxI-;QsCWT! zl=}GDNg&rrwZ08k&Z=wJUs?W-M;db*&R*q&D5APCA#5oE`^UZ``cQ!P4cB>D&G7jj zBhQ_Ijo`;ETi5Qu-g(TAM-9G`aHyw`yLrwUovT`3<8^?2VkF{sc!O6=qIT_^|C>X5 zGAlL;`VWUl&E376Ts*$E3d>R@Qq7MG^g^7^=d#Jlwi~YQt?dGO?|pyl%rwpCzjJBj zJLD$(JGiv+9WkON36GbY6=R+gSLaUM57zol=E3OoOQlz5A^KXDjjkxDAgNl*6Es?U}z3yuo(-2Y@#=s zeMaK(w;DHJ9uHzF4&XH|oN55CVh}&EE=2_B=*l_F%9=i`q~R$r^e&iOuME;XGXVdC z_O$}*bS$j+oP3>_>%Ro9&B?bfv9RB%mP?O~>Ls*Gc0^pl4YtK*V5jif2TrV`TRZ^+ zl{d`lf#lxBY_M5?!z@w6ihU&ax^tBd8+HF9o%uKEJ!i%M%ociAZa})8cjz=E7*RWU zX>BZs{(^l@Kp$+6-u>Jf=UkNn!5%^21Rz?Cbhbk)-msq-cmx38qMHs#<-H}7X!W$u zA`8}56_CU^3LV}+Hlc0Eg8iy&65y?E^f}1>0LwfaD@T7Ew9p&fH=18Or0nSJ>~hjm zz|}XvnXIaQ4%}n6iU(~Y9u6TWpaYEci|^g*nFi;w&bC!??BP4IeIf#(*==1;qVtbE z+0nFWTlY`r#N`#L|E_$J*3E={wvD%)x~;lv(85~6TL)cH43_4*;yLHT*qy4|52Mzp z7M=M3CYP+!Wfe=z5H)@iQ)I{?qlT3r+({&`cb$Wd5$&q60822Ariv1P5)cszs|uKW zS0AMLqpk`9-TB%b{HJVJ`WLMK#*)Y%etYfS&1n`Ag&{i&WG^R&Rz5*go19<#o~U*N zsz>YAt*L5V`cIDY3t5cBpju5AV=UUkq$bhzG}t5I)5uU zX@~*_bI$eYARJ5Yd;GT7E_nX2Ot+GM`1aRMgVcE9`M0ZmcG?rj`IYLT&Kh_&9THEx z^}h*zIExzN=a8%{wb;u)vC@9h6E5&V%d<}U52$M_Z_ z5zgfPUjilmzjwQL#&co!1425Id(Mz^afXVAE?u(9zl3OIFD<~dgMmLG?($kAXDqUI zTlJin;AORHDO20%p)wVB?)3q=5}#T3y6uRo1A4O48lx*y>%esJWMKWb*XR<}QAkqR z&53!s9EP`8!xvt?OZTfDOG(SH@~kpc>%Oh?XEh9%7*m&4#^?%H9Wbe>_nPP~*9hcg zaCvFu)h3P6lP=A`ta?h$vzV}nixw<0G+~A35ND3rqbJMI0HQ_lSU3w7LE{UMx`Ce{uVu{f`nPAtzYY# z-8R8X8WeNTDwqp3l2T-Yf$&18&C>IryrBpbu<`csYyVEAb@B^e8MPK_A7O zrOU?5i*WH(TZRV#9|acl4%n=FlDJ*kdN@0w*uEhLMKwncbPha2)B%gJK+T0$gZ3s1 zQxx~lvU>ZS=_G4`cxvyt6?hAU@*-W_a?zP~} zd^TMfI&>;iCdZ-6cvu^5U6VJqdy>$IY8$Ru}C55iS9{R`2kDQ;2z)ZTnNNnB6>z)+^D?qg&+Rwa zzBZ%EO7#$@lj@{azMFS;A**%>RxtXn&;_uimA)&>RDlXB;wqwQ!wI@k(|!kFqtTWL zK0v?YL0l-Y=i%Ky2yC%pVi(-8N3{Ap2eyar^?I1bJ(GZi8(#J0MGm=lXQuA4XGVsw z&|eukKC(Xf;Lc2NfemF|YbVT~1PaO8;&WD2B6`pd*3@ zz2duo14AI7_V8qPZ{N=Z;`s&>8pVI2I8G*%CbAH_7M+} z$HSJzsVby1( diff --git a/host/tools/configtool/standalone/wxwin/manual/pix/propwin.gif b/host/tools/configtool/standalone/wxwin/manual/pix/propwin.gif new file mode 100644 index 0000000000000000000000000000000000000000..f48e643c602286a80679dcf567f5f1e773e321d0 GIT binary patch literal 22864 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 O;mE#a@(b(i8~+Cv#Q#+Q diff --git a/host/tools/configtool/standalone/wxwin/manual/pix/regprops.gif b/host/tools/configtool/standalone/wxwin/manual/pix/regprops.gif new file mode 100644 index 0000000000000000000000000000000000000000..fa6e7cd05c4f5222617aa713cee3f9cb6a40fa9b GIT binary patch literal 18574 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 Yd{hO1fMV()n4p3SGT5MlDg^`pJL=a#ga7~l diff --git a/host/tools/configtool/standalone/wxwin/manual/pix/repo3D1.gif b/host/tools/configtool/standalone/wxwin/manual/pix/repo3D1.gif new file mode 100644 index 0000000000000000000000000000000000000000..f35d37ef4538a051e95e09c0aa5fdf26a4af1210 GIT binary patch literal 120465 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 Yd{hO1fMV()n4p3SGT5MlDg^`pJL=a#ga7~l diff --git a/host/tools/configtool/standalone/wxwin/manual/pix/repos-relocate.gif b/host/tools/configtool/standalone/wxwin/manual/pix/repos-relocate.gif new file mode 100644 index 0000000000000000000000000000000000000000..adad71659ae3f01d32c7dfcf6b5e2ee6c658cfed GIT binary patch literal 8687 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 diff --git a/host/tools/configtool/standalone/wxwin/manual/pix/targetlist.gif b/host/tools/configtool/standalone/wxwin/manual/pix/targetlist.gif new file mode 100644 index 0000000000000000000000000000000000000000..0b05863dfaf7d7a48550886fe665720e54da8285 GIT binary patch literal 47216 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

    E|sTeP-RjU#K7SnS*o+JV)YN7CZg-_TV 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 diff --git a/host/tools/configtool/standalone/wxwin/manual/pix/toolsplatforms.gif b/host/tools/configtool/standalone/wxwin/manual/pix/toolsplatforms.gif new file mode 100644 index 0000000000000000000000000000000000000000..3e801de3fa4aa69daaa24c5b9ccf48c27d8cc12f GIT binary patch literal 44308 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 W=IX2YonN$|pL2scTay<1*8c;{K>;iP diff --git a/host/tools/configtool/standalone/wxwin/manual/pix/user-tools-dialog.gif b/host/tools/configtool/standalone/wxwin/manual/pix/user-tools-dialog.gif new file mode 100644 index 0000000000000000000000000000000000000000..8f79d4f94c96a6a5186974910fe63c00ff503e59 GIT binary patch literal 13701 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 BZs`C3 diff --git a/host/tools/configtool/standalone/wxwin/manual/pix/viewmenu.gif b/host/tools/configtool/standalone/wxwin/manual/pix/viewmenu.gif new file mode 100644 index 0000000000000000000000000000000000000000..86d8d3dafbbbf8499df0875bb001f060a94fc9f5 GIT binary patch literal 8462 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 + + + + + eCos User's Guide + +

    +

    + + +eCos +™ +User's Guide
    + +
    +

    +
    + + +March 2000
    + +
    +

    + + +Copying terms

    +

    + + +The contents of this manual are subject to the Red Hat eCos Public License Version 1.1 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.redhat.com/

    +

    + + +Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License.

    +

    + + +The Original Code is eCos - Embedded Configurable Operating System, released September 30, 1998.

    +

    + + +The Initial Developer of the Original Code is Red Hat. Portions created by Red Hat are Copyright © 1998, 1999, 2000 Red Hat Inc. All Rights Reserved.

    +
    +
    +

    + + +Trademarks

    +

    + + +Java +™, + Sun®, and Solaris +™ + are trademarks or registered trademarks of Sun Microsystems, Inc.

    +

    + + +SPARC® is a registered trademark of SPARC International, Inc.

    +

    + + +UNIX +™ + is a trademark of The Open Group.

    +

    + + +Microsoft®, Windows NT®, Windows 95®, Windows 98® and Windows 2000® are registered trademarks of Microsoft Corporation.

    +

    + + +Linux® is a registered trademark of Linus Torvalds.

    +

    + + +Intel® is a registered trademark of Intel Corporation.

    +

    + + +eCos +™ + is a trademark of Red Hat, Inc.

    +

    + + +Red Hat® is a registered trademark of Red Hat, Inc.

    +

    + + +

    +

    + + +

    +

    + + +

    +

    + + +

    +

    + + +

    +

    + + +

    +

    + + +

    +

    + + +

    +

    + + +300-400-1010049-03

    +

    + + +

    +
    +

    eCos™User's Guide

    To Contents

    To previous page

    To next page

    + diff --git a/host/tools/configtool/standalone/wxwin/manual/user-guides.10.html b/host/tools/configtool/standalone/wxwin/manual/user-guides.10.html new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/manual/user-guides.10.html @@ -0,0 +1,199 @@ + + + + + + Compiler and Linker Options + +
    +

    Compiler and Linker Options

    To Contents

    To previous page

    To next page

     




    +

    + + + + + + +Compiler and Linker Options
    + +
    +

    +

    + + +eCos is built using the GNU C and C++ compilers. The versions of the tools +Red Hat + has prepared for this release have some enhancements, such as constructor priority ordering and selective linking, which will eventually become part of the standard distribution.

    +

    + + +Some +GCC + options are required for eCos, and others can be useful. This chapter gives a brief description of the required options as well as some recommended eCos-specific options. All other +GCC + options (described in the +GNUPro + manuals) are available.

    +
    +

    + + + + +Compiling a C Application

    +

    + + +The following command lines demonstrate the +minimum + set of options required to compile and link an eCos program written in C.

    +

    + + +NOTE

    +

    + + +Remember that when this manual shows +gcc + you should type the full name of the cross compile,e.g. +mn10300-elf-gcc +, +mips-tx39-elf-gcc +, +powerpc-eabi-gcc +, +sparclite-elf-gcc +, +arm-elf-gcc, mips64vr4300-elf-gcc, or sh-elf-gcc. +When compiling for the synthetic Linux target, use the native gcc which must have the features required by eCos.

    +
     
    +
    +
     
    +$ gcc -c  -IINSTALL_DIR
    +/include file.c
    +$ gcc -o program file.o -LINSTALL_DIR
    +/lib -Ttarget.ld -nostdlib
    +
    +

    + + +NOTE

    +
      +

    • + + +Certain targets may require extra options, for example the SPARClite architectures require the option +-mcpu=sparclite +. Examine the +BASE_DIR + +/packages/targets + file or +BASE_DIR + +/examples/Makefile + or the "Global compiler flags" option (CYGBLD_GLOBAL_CFLAGS) in your generated eCos configuration) to see if any extra options are required, and if so, what they are.
    • +
    +

    + + +The following command lines use some other options which are recommended because they use the + +selective linking feature:

    +
     
    +$ gcc -c  -I
    +INSTALL_DIR
    +/include -I. -ffunction-sections -fdata-sections -g -O2 file.c
    +$ gcc -o program file.o -ffunction-sections -fdata-sections -Wl,--gc-sections -g -O2 -L
    +INSTALL_DIR
    +/lib -Ttarget.ld -nostdlib
    +
    +
    +
    +

    + + + + +Compiling a C++ Application

    +

    + + +The following command lines demonstrate the +minimum + set of options required to compile and link an eCos program written in C++.

    +

    + + +NOTE

    +
      +

    • + + +Remember that when this manual shows +g++ + you should type the full name of the cross compiler: +mn10300-elf-g++ +, +mips-tx39-elf-g++ +, +powerpc-eabi-g++ +, +sparclite-elf-g++ +, +arm-elf-g++, mips64vr4300-elf-g++, or sh-elf-g++. +When compiling for the synthetic Linux target, use the native +g++ + which must have the features required by eCos.
    • +
    +
     
    +
    +$ g++ -c  -I
    +INSTALL_DIR
    +/include -fno-rtti -fno-exceptions file.cxx
    +$ g++ -o program file.o -L
    +INSTALL_DIR
    +/lib -Ttarget.ld -nostdlib
    +
    +
    +

    + + +NOTE

    +
      +

    • + + +Certain targets may require extra options, for example the SPARClite architectures require the option +-mcpu=sparclite +. Examine the +BASE_DIR + +/packages/targets + file or +BASE_DIR + +/examples/Makefile + or the "Global compiler flags" option (CYGBLD_GLOBAL_CFLAGS) in your generated eCos configuration) to see if any extra options are required, and if so, what they are.
    • +
    +

    + + +The following command lines use some other options which are recommended because they use the + +selective linking feature:

    +
     
    +$ g++ -c  -IINSTALL_DIR
    +/include -I. -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions -fvtable-gc -finit-priority -g -O2 file.cxx
    +$ g++ -o program file.o -W1,--gc-sections -g -O2 -LINSTALL_DIR
    +/lib -Ttarget.ld -nostdlib
    + + + + +
    +
    +
    +

    Compiler and Linker Options

    To Contents

    To previous page

    To next page

    + diff --git a/host/tools/configtool/standalone/wxwin/manual/user-guides.11.html b/host/tools/configtool/standalone/wxwin/manual/user-guides.11.html new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/manual/user-guides.11.html @@ -0,0 +1,410 @@ + + + + + + Debugging Techniques + + +

    + + +Debugging Techniques
    + +
    +

    +

    + + +eCos applications and components can be + +debugged in traditional ways, with printing statements and debugger single-stepping, but there are situations in which these techniques cannot be used. One example of this is when a program is getting data at a high rate from a real-time source, and cannot be slowed down or interrupted.

    +

    + + +eCos's infrastructure module provides a +tracing + formalism, allowing the kernel's tracing macros to be configured in many useful ways. eCos's kernel provides + + +instrumentation buffers + which also collect specific (configurable) data about the system's history and performance.

    +
    +

    + + +Tracing

    +

    + + +To use eCos's tracing facilities you must first configure your system to use + +tracing. You should enable the +Asserts and Tracing + component ( +CYGPKG_INFRA_DEBUG +) and the +Use tracing + component within it ( +CYGDBG_USE_TRACING +). These options can be enabled with the +Configuration Tool + or by editing the file +BUILD_DIR + +/pkgconf/infra.h + manually.

    +

    + + +You should then examine all the tracing-related options in the +Package: Infrastructure + chapter of the +eCos + + Reference Manual. + One useful set of configuration options are: +CYGDBG_INFRA_DEBUG_FUNCTION_REPORTS + and +CYGDBG_INFRA_DEBUG_TRACE_MESSAGE, + which are both enabled by default when tracing is enabled.

    +

    + + +The following "Hello world with tracing" shows the output from running the hello world program (from the programming tutorial in +Getting Started with eCos +) that was built with tracing enabled:

    +

    + + + + +Hello world with tracing

    +
     
    +$ mips-tx39-elf-run --board=jmr3904 hello
    +
    +Hello, eCos world!
    +ASSERT FAIL: <2>cyg_trac.h          [ 623] Cyg_TraceFunction_Report_::set_exitvoid()                                                            exitvoid used in typed function
    +TRACE: <1>mlqueue.cxx         [ 395] Cyg_ThreadQueue_Implementation::enqueue()                                                            {{enter
    +TRACE: <1>mlqueue.cxx         [ 395] Cyg_ThreadQueue_Implementation::enqueue()                                                            }}RETURNING UNSET!
    +TRACE: <1>mlqueue.cxx         [ 126] Cyg_Scheduler_Implementation::add_thread()                                                           }}RETURNING UNSET!
    +TRACE: <1>thread.cxx          [ 654] Cyg_Thread::resume()                                                                                 }}return void
    +TRACE: <1>cstartup.cxx        [ 160] cyg_iso_c_start()                                                                                    }}return void
    +TRACE: <1>startup.cxx         [ 142] cyg_package_start()                                                                                  }}return void
    +TRACE: <1>startup.cxx         [ 150] cyg_user_start()                                                                                     {{enter
    +TRACE: <1>startup.cxx         [ 150] cyg_user_start()                                                                                     (((void)))
    +TRACE: <1>startup.cxx         [ 153] cyg_user_start()                                                                                     'This is the system default cyg_user_start()'
    +TRACE: <1>startup.cxx         [ 157] cyg_user_start()                                                                                     }}return void
    +TRACE: <1>sched.cxx           [ 212] Cyg_Scheduler::start()                                                                               {{enter
    +TRACE: <1>mlqueue.cxx         [ 102] Cyg_Scheduler_Implementation::schedule()                                                             {{enter
    +TRACE: <1>mlqueue.cxx         [ 437] Cyg_ThreadQueue_Implementation::highpri()                                                            {{enter
    +TRACE: <1>mlqueue.cxx         [ 437] Cyg_ThreadQueue_Implementation::highpri()                                                            }}RETURNING UNSET!
    +TRACE: <1>mlqueue.cxx         [ 102] Cyg_Scheduler_Implementation::schedule()                                                             }}RETURNING UNSET!
    +TRACE: <2>intr.cxx            [ 450] Cyg_Interrupt::enable_interrupts()                                                                   {{enter
    +TRACE: <2>intr.cxx            [ 450] Cyg_Interrupt::enable_interrupts()                                                                   }}RETURNING UNSET!
    +TRACE: <2>thread.cxx          [  69] Cyg_HardwareThread::thread_entry()                                                                   {{enter
    +TRACE: <2>cstartup.cxx        [ 127] invoke_main()                                                                                        {{enter
    +TRACE: <2>cstartup.cxx        [ 127] invoke_main()                                                                                        ((argument is ignored))
    +TRACE: <2>dummyxxmain.cxx     [  60] __main()                                                                                             {{enter
    +TRACE: <2>dummyxxmain.cxx     [  60] __main()                                                                                             (((void)))
    +TRACE: <2>dummyxxmain.cxx     [  63] __main()                                                                                             'This is the system default __main()'
    +TRACE: <2>dummyxxmain.cxx     [  67] __main()                                                                                             }}return void
    +TRACE: <2>memcpy.c            [ 112] _memcpy()                                                                                            {{enter
    +TRACE: <2>memcpy.c            [ 112] _memcpy()                                                                                            ((dst=80002804, src=BFC14E58, n=19))
    +TRACE: <2>memcpy.c            [ 164] _memcpy()                                                                                            }}returning 80002804
    +TRACE: <2>cstartup.cxx        [ 137] invoke_main()                                                                                        'main() has returned with code 0. Calling exit()'
    +TRACE: <2>exit.cxx            [  71] __libc_exit()                                                                                        {{enter
    +TRACE: <2>exit.cxx            [  71] __libc_exit()                                                                                        ((status=0 ))
    +TRACE: <2>atexit.cxx          [  84] cyg_libc_invoke_atexit_handlers()                                                                    {{enter
    +TRACE: <2>atexit.cxx          [  84] cyg_libc_invoke_atexit_handlers()                                                                      (((void)))
    +
    +Scheduler:
    +
    +Lock:                0
    +Current Thread:      <null>
    +
    +Threads:
    +
    +Idle Thread          pri =  31 state = R      id =   1
    +                     stack base = 800021F0 ptr = 80002510 size = 00000400
    +                     sleep reason NONE     wake reason NONE    
    +                     queue = 80000C54      wait info = 00000000
    +
    +<null>               pri =   0 state = R      id =   2
    +                     stack base = 80002A48 ptr = 8000A968 size = 00008000
    +                     sleep reason NONE     wake reason NONE    
    +                     queue = 80000BD8      wait info = 00000000
    +
    +	  
    +
    +
    +

    + + +Kernel Instrumentation

    +

    + + + + +Instrument buffers can be used to find out how many events of a given type happened in the kernel during execution of a program.

    +

    + + +You can monitor a class of several types of events, or you can just look at individual events.

    +

    + + +Examples of + +events that can be monitored are:

    +
      +

    • + + +scheduler events
    • +

    • + + +thread operations
    • +

    • + + +interrupts
    • +

    • + + +mutex operations
    • +

    • + + +binary semaphore operations
    • +

    • + + +counting semaphore operations
    • +

    • + + +clock ticks and interrupts
    • +
    +

    + + +Examples of fine-grained scheduler event types are:

    +
      +

    • + + +scheduler lock
    • +

    • + + +scheduler unlock
    • +

    • + + +rescheduling
    • +

    • + + +time slicing
    • +
    +

    + + +Information about the events is stored in an + + +event record. + The structure that defines this record has type +struct Instrument_Record +:

    +

    + + +The list of records is stored in an array called +instrument_buffer +, which you can let the kernel provide or you can provide yourself by setting the configuration option +CYGVAR_KERNEL_INSTRUMENT_EXTERNAL_BUFFER. +

    +

    + + +To write a program that examines the instrumentation buffers:

    +
      +

    1. + + +Enable instrumentation buffers in the eCos kernel configuration. The component macro is +CYGPKG_KERNEL_INSTRUMENT. +
    2. +

    3. + + +To allocate the buffers yourself, enable the configuration option +CYGVAR_KERNEL_INSTRUMENT_EXTERNAL_BUFFER. +
    4. +

    5. + + +Include the header file +cyg/kernel/instrmnt.h +.
      + +#include <cyg/kernel/instrmnt.h> +
    6. +

    7. + + +The +Instrumentation_Record + structure is not published in the kernel header file. In the future there will be a cleaner mechanism to access it, but for now you should paste into your code in the following lines:
      + +struct Instrument_Record
      +{
      + CYG_WORD16 type; // record type
      + CYG_WORD16 thread; // current thread id
      + CYG_WORD timestamp; // 32 bit timestamp
      + CYG_WORD arg1; // first arg
      + CYG_WORD arg2; // second arg
      +};
      +
    8. +

    9. + + +Enable the events you want to record using +cyg_instrument_enable() +, and disable them later. Look at +cyg/kernel/instrmnt.h + and the examples below to see what events can be enabled.
    10. +

    11. + + +Place the code you want to debug between the matching functions +cyg_instrument_enable() + and +cyg_instrument_disable() +.
    12. +

    13. + + +Examine the buffer. For now you need to look at the data in there (the example program below shows how to do that), and future versions of eCos will include a host-side tool to help you understand the data.
    14. +
    +

    + + +

    +

    + + + + +Using instrument buffers

    +

    + + +This program is also provided in the +examples + directory.

    +
     
    +/* this is a program which uses eCos instrumentation buffers; it needs
    + to be linked with a kernel which was compiled with support for
    + instrumentation */
    +
    +#include <stdio.h>
    +#include <pkgconf/kernel.h>
    +#include <cyg/kernel/instrmnt.h>
    +#include <cyg/kernel/kapi.h>
    +
    +#ifndef CYGVAR_KERNEL_INSTRUMENT_EXTERNAL_BUFFER
    +# error You must configure eCos with CYGVAR_KERNEL_INSTRUMENT_EXTERNAL_BUFFER
    +#endif
    +
    +struct Instrument_Record
    +{
    + CYG_WORD16 type; // record type
    + CYG_WORD16 thread; // current thread id
    + CYG_WORD timestamp; // 32 bit timestamp
    + CYG_WORD arg1; // first arg
    + CYG_WORD arg2; // second arg
    +};
    +
    +struct Instrument_Record instrument_buffer[20];
    +cyg_uint32 instrument_buffer_size = 20;
    +
    +int main(void)
    +{
    + int i;
    +
    + cyg_instrument_enable(CYG_INSTRUMENT_CLASS_CLOCK, 0);
    + cyg_instrument_enable(CYG_INSTRUMENT_CLASS_THREAD, 0);
    + cyg_instrument_enable(CYG_INSTRUMENT_CLASS_ALARM, 0);
    +
    + printf("Program to play with instrumentation buffer\n");
    +
    + cyg_thread_delay(2);
    +
    + cyg_instrument_disable(CYG_INSTRUMENT_CLASS_CLOCK, 0);
    + cyg_instrument_disable(CYG_INSTRUMENT_CLASS_THREAD, 0);
    + cyg_instrument_disable(CYG_INSTRUMENT_CLASS_ALARM, 0);
    +
    + for (i = 0; i < instrument_buffer_size; ++i) {
    + printf("Record %02d: type 0x%04x, thread %d, ",
    +	i, instrument_buffer[i].type, instrument_buffer[i].thread);
    + printf("time %5d, arg1 0x%08x, arg2 0x%08x\n",
    +	instrument_buffer[i].timestamp, instrument_buffer[i].arg1,
    +	instrument_buffer[i].arg2);
    + }
    + return 0;
    +}
    +

    + + +Here is how you could compile and run this program in the +examples + directory, using (for example) the MN10300 compiler:

    +
     
    +$ make XCC=mn10300-elf-gcc  PKG_INSTALL_DIR
    +=/tmp/ecos-work-mn10300/install instrument-test
    +mn10300-elf-gcc -c -o instrument-test.o -g -Wall -I/tmp/ecos-work-mn10300/install/include -ffunction-sections -fdata-sections instrument-test.c
    +mn10300-elf-gcc -nostartfiles -L/tmp/ecos-work-mn10300/install/lib -W1,--gc-sections -o instrument-test instrument-test.o -Ttarget.ld -nostdlib
    +$ mn10300-elf-run --board=stdeval1 instrument-test
    +

    + + + + +Instrument buffer output

    +

    + + +Here is the output of the +instrument-test + program. Notice that in little over 2 seconds, and with very little activity, and with few event types enabled, it gathered 17 records. In larger programs it will be necessary to select very few event types for debugging.

    +
     
    +Program to play with instrumentation buffer
    +Record 00: type 0x0207, thread 2, time  6057, arg1 0x48001cd8, arg2 0x00000002
    +Record 01: type 0x0202, thread 2, time  6153, arg1 0x48001cd8, arg2 0x00000000
    +Record 02: type 0x0904, thread 2, time  6358, arg1 0x48001d24, arg2 0x00000000
    +Record 03: type 0x0905, thread 2, time  6424, arg1 0x00000002, arg2 0x00000000
    +Record 04: type 0x0906, thread 2, time  6490, arg1 0x00000000, arg2 0x00000000
    +Record 05: type 0x0901, thread 2, time  6608, arg1 0x48009d74, arg2 0x48001d24
    +Record 06: type 0x0201, thread 2, time  6804, arg1 0x48001cd8, arg2 0x480013e0
    +Record 07: type 0x0803, thread 1, time    94, arg1 0x00000000, arg2 0x00000000
    +Record 08: type 0x0801, thread 1, time   361, arg1 0x00000000, arg2 0x00000000
    +Record 09: type 0x0802, thread 1, time   548, arg1 0x00000001, arg2 0x00000000
    +Record 10: type 0x0803, thread 1, time    94, arg1 0x00000000, arg2 0x00000000
    +Record 11: type 0x0801, thread 1, time   361, arg1 0x00000001, arg2 0x00000000
    +Record 12: type 0x0903, thread 1, time   513, arg1 0x48009d74, arg2 0x48001d24
    +Record 13: type 0x0208, thread 1, time   588, arg1 0x00000000, arg2 0x00000000
    +Record 14: type 0x0203, thread 1, time   697, arg1 0x48001cd8, arg2 0x480013e0
    +Record 15: type 0x0802, thread 1, time   946, arg1 0x00000002, arg2 0x00000000
    +Record 16: type 0x0201, thread 1, time  1083, arg1 0x480013e0, arg2 0x48001cd8
    +Record 17: type 0x0000, thread 0, time     0, arg1 0x00000000, arg2 0x00000000
    +Record 18: type 0x0000, thread 0, time     0, arg1 0x00000000, arg2 0x00000000
    +Record 19: type 0x0000, thread 0, time     0, arg1 0x00000000, arg2 0x00000000
    +
    +

    Debugging Techniques

    To Contents

    To previous page

    To next page

    + diff --git a/host/tools/configtool/standalone/wxwin/manual/user-guides.12.html b/host/tools/configtool/standalone/wxwin/manual/user-guides.12.html new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/manual/user-guides.12.html @@ -0,0 +1,32 @@ + + + + + + Part III: Configuration and the Package Repository + +
    +

    Part III: Configuration and the Package Repository

    To Contents

    To previous page

    To next page

     




    +

    + + +Part III: Configuration and the Package Repository
    + +
    +

    +

    + + +The following chapters contain information on running +ecosconfig + + + (the command line tool that manipulates configurations and constructs build trees) and on managing a source repository across multiple versions of eCos.

    + + + + +
    +
    +

    Part III: Configuration and the Package Repository

    To Contents

    To previous page

    To next page

    + diff --git a/host/tools/configtool/standalone/wxwin/manual/user-guides.13.html b/host/tools/configtool/standalone/wxwin/manual/user-guides.13.html new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/manual/user-guides.13.html @@ -0,0 +1,1793 @@ + + + + Manual Configuration + + + + + + + +

    + + + + + + + + +
    +

    Manual Configuration

    +
    +

    To + Contents

    +
    +

    To previous page

    +
    +

    To next page

    +
     

    +



    +

    +
    +

    +Manual Configuration

    +

    +

    +

    eCos developers using +Windows NT or Linux can choose whether to use either the graphical +Configuration Tool, or the command line ecosconfig +program, for configuring an eCos system and building the target +library. The command line tools can also be used for batch operations +on all platforms, for example as part of a nightly rebuild procedure. +

    +

    In the current release of +the system the command line tools do not provide exactly the same +functionality as the graphical tool. Most importantly, there is no +facility to resolve configuration conflicts interactively.

    +

    The eCos configuration +system, both graphical and command line tools, are under constant +development and enhancement. Developers should note that the +procedures described may change considerably in future releases. +

    +

    Directory Tree +Structure

    +

    When building eCos there +are three main directory trees to consider: the source tree, the +build tree, and the install tree.

    +

    +The source tree, also known as the component repository, is +read-only. It is possible to use a single component repository for +any number of different configurations, and it is also possible to +share a component repository between multiple users by putting it on +a network drive. +

    +

    The build tree contains +everything that is specific to a particular configuration, including +header and other files that contain configuration data, and the +object files that result from compiling the system sources for this +configuration. +

    +

    The install tree is +usually located in the install subdirectory of +the build tree. Once an eCos system has been built, the install tree +contains all the files needed for application development including +the header files and the target library. By making copies of the +install tree after a build it is possible to separate application +development and system configuration, which may be desirable for some +organizations. +

    +

    +Creating the Build Tree

    +

    +Generating a build tree is a non-trivial operation and should not be +attempted manually. Instead, eCos is shipped with a tool called +ecosconfig that should be used to create a +build tree.

    +

    Usually ecosconfig +will be run inside the build tree itself. If you are creating a new +build tree then typically you will create a new empty directory using +the mkdir command, cd +into that directory, and then invoke ecosconfig +to create a configuration. By default, the configuration is stored in +a file ecos.ecc in the current directory. The +configuration may be modified by editing this file directly. +ecosconfig itself deals with a number of +coarse-grained configuration options such as the target platform and +the packages that should be used.

    +

    The ecosconfig +tool is also used subsequently to generate a build tree for a +configuration. Once a build tree exists, it is possible to run +ecosconfig again inside the same build tree. +This will be neccessary if your wish to change some of the +configuration options.

    +

    ecosconfig +does not generate the top-level directory of the build tree; you must +do this yourself. +

    +
     
    +$ mkdir ecos-work
    +$ cd ecos-work

    +The next step is to run ecosconfig +: +

    +
     
    +$ ecosconfig <qualifiers> <command>

    +ecosconfig +qualifiers

    +

    The available command +line qualifiers for ecosconfig are as follows. +Multiple qualifiers may be used on the command line: +

    +

    +--help +

    +

    Provides basic +usage guidelines for the available commands and qualifiers. All other +qualifiers and commands are ignored if --help is used.

    +

    +--config=<file> +

    +

    Specifies an +eCos configuration save file for use by the tool. By default, the +file ecos.ecc in the current directory is used. +Developers may prefer to use a common location for all their eCos +configurations rather than keep the configuration information in the +base of the build tree.

    +

    +--prefix=<dir> +

    +

    Specifies an +alternative location for the install tree. By default, the install +tree resides inside the install directory in +the build tree. Developers may prefer to locate the build tree in a +temporary file hierarchy but keep the install tree in a more +permanent location.

    +

    +--srcdir=<dir> +

    +

    Specifies the +location of the component repository. By default, the tool uses the +location specified in the ECOS_REPOSITORY +environment variable. Developers may prefer to use of this qualifier +if they are working with more than one repository.

    +

    +--no-resolve +

    +

    Disables the +implicit resolution of conflicts while manipulating the configuration +data. Developers may prefer to resolve conflicts by editing the eCos +configuration save file manually. The check command implicitely uses +--no-resolve.

    +

    --ignore-errors
    -i +
    +

    +

    By default, +ecosconfig will exit with an error code if the current +configuration contains any conflicts, and it is not possible to +generate or update a build tree for such configurations. This +qualifier causes ecosconfig to ignore such problems, and +hence it is possible to generate a build tree even if there are still +conflicts. Of course, there are no guarantees that the resulting +system will actually do anything.

    +

    --verbose
    -v +
    +

    +

    Display more +information.

    +

    --quiet
    -q +
    +

    +

    Display less +information.

    +

    The --config, --prefix and --srcdir +qualifiers can also be written with two arguments, for example:

    +

    ecosconfig --srcdir <dir> ...

    +

    This simplifies filename completion with +some shells.

    +

    +ecosconfig commands

    +

    The available commands +for ecosconfig are as follows:

    +

    +list +

    +

    Lists the +available packages, targets and templates as installed in the eCos +repository. Aliases and package versions are also reported.

    +

    +new <target> [<template> [<version>]] +

    +

    Creates a new +eCos configuration for the specified target hardware and saves it. A +software template may also be specified. By default, the template +named 'default' is used. If the template version is not specified, +the latest version is used.

    +

    +target <target> +

    +

    Changes the +target hardware selection for the eCos configuration. This has the +effect of unloading packages supporting the target selected +previously and loading the packages which support the new hardware. +This command will be used typically when switching between a +simulator and real hardware.

    +

    +template <template> [<version>] +

    +

    Changes the +template selection for the eCos configuration. This has the effect of +unloading packages specified by the template selected previously and +loading the packages specified by the new template. By default, the +latest version of the specified template is used.

    +

    +remove <packages> +

    +

    Removes the +specified packages from the eCos configuration. This command will be +used typically when the template on which a configuration is based +contains packages which are not required.

    +

    +add <packages> +

    +

    Adds the +specified packages to the eCos configuration. This command will be +used typically when the template on which a configuration is based +does not contain all the packages which are required. For example, +add-on packages provided by third parties will not be known to the +standard templetes, so they will have to be added explicitely. +

    +

    +version <version> <packages> +

    +

    Selects the +specified version of a number of packages in the eCos configuration. +By default, the most recent version of each package is used. This +command will be used typically when an older version of a package is +required.

    +

    +check +

    +

    Presents the +following information concerning the current configuration:

    +
      +
    1. the selected target hardware +

      +
    2. the selected template +

      +
    3. additional packages +

      +
    4. removed packages +

      +
    5. the selected version of packages + where this is not the most recent version +

      +
    +

    The check command will never perform automatic conflict +resolution, so there is no need to use --no-resolve. +

    +

    +resolve +

    +

    Resolves +conflicts identified in the current eCos configuration by invoking an +inference capability. Resolved conflicts are reported, but not all +conflicts may be resolvable. This command will be used typically +following manual editing of the configuration.

    +

    export +<file> +

    +

    Exports a +minimal eCos configurastion save file with the specified name. This +file contains only those options which do not have their default +value. Such files are used typically to transfer option values from +one configuration to another.

    +

    import +<file> +

    +

    Imports a +minimal eCos configuration save file with the specified name. The +values of those options specified in the file are applied to the +current configuration.

    +

    +tree +

    +

    Generates a +build tree based on the current eCos configuration. This command will +be used typically just before building eCos. Normally a build tree +can only be generated if if the configuration has no unresolved +conflicts, but --ignore-errors can be used to override this.

    +

    +Conflicts and constraints

    +

    Configuration options are not completely independent. +For example the C library's strtod() and atof() functions rely on the +math library package to provide certain functionality. If the math +library package is removed then the C library can no longer provide +these functions. Each package describes constraints like these in CDL +"requires" properties. If a constraint is not satisfied, +then the configuration contains a conflict. For any given conflict +there can be several rtesolution options. For example, it would be +possible to add the math library package back to the configuration, +or to disable the strtod() and atof() functions. +

    +

    The eCos configuration tools will report any +conflicts in the current configuration. If there are any such +conflicts then the configuration is usually unsafe and it makes no +sense to build and run eCos in such circumstances. In fact, any +attempt at building eCos is likely to fail. In exceptional cases it +is possible to override this by using e.g. the --ignore-errors +qualifier with ecosconfig. +

    +

    Many constraints are fairly simple in nature, and the +configuration tools contain an inference engine which can resolve the +associated conflicts automatically. For example, if the math library +package is removed then the inference engine can resolve the +resulting conflict by disabling the configuration option for strtod() +and atof(). All such changes will be reported. Sometimes the +inference engine cannot resolve a conflict, for example it is not +allowed to override a change that has been made explicitly by the +user. Sometimes it will find a solution which does not match the +application's requirements. +

    +

    A typical session involving conflicts would look +something like this: +

    +
    $ ecosconfig new 

    +This creates a new configuration with the default template. For most +targets this will not result in any conflicts, because the default +settings for the various options meet the requirements of the default +template. For some targets there may be conflicts and the inference +engine would come into play. +

    +
    $ ecosconfig remove libm 
    +U CYGSEM_LIBC_STDIO_SCANF_FLOATING_POINT, new inferred value 0 
    +U CYGFUN_LIBC_strtod, new inferred value 0 
    +U CYGSEM_LIBC_STDIO_PRINTF_FLOATING_POINT, new inferred value 0 

    +ecosconfig reports that this change caused three conflicts, all in +the C library. The inference engine was able to resolve all the +conflicts and update the relevant configuration options accordingly. +

    +

    To suppress the inference engine --no-resolve can be +used: +

    +
    $ ecosconfig new  
    +$ ecosconfig --no-resolve remove libm 
    +C CYGSEM_LIBC_STDIO_SCANF_FLOATING_POINT, "requires" constraint not satisfied:      CYGPKG_LIBM 
    +C CYGSEM_LIBC_STDIO_PRINTF_FLOATING_POINT, "requires" constraint not satisfied:      CYGPKG_LIBM 
    +C CYGFUN_LIBC_strtod, "requires" constraint not satisfied: CYGPKG_LIBM 

    +Three unresolved conflicts are reported. The check command can be +used to get the current state of the configuration, and the --verbose +qualifier will provide additional information: +

    +
    $ ecosconfig --srcdir /home/bartv/ecc/ecc --verbose      check 
    +Target: pid 
    +Template: default 
    +Removed:
    + CYGPKG_LIBM 
    +3 conflict(s): 
    +C CYGFUN_LIBC_strtod, "requires" constraint not satisfied: CYGPKG_LIBM
    + Possible solution: 
    +    CYGFUN_LIBC_strtod -> 0 
    +    CYGSEM_LIBC_STDIO_SCANF_FLOATING_POINT -> 0 
    +C CYGSEM_LIBC_STDIO_PRINTF_FLOATING_POINT, "requires" constraint not satisfied:      CYGPKG_LIBM 
    + Possible solution: 
    +    CYGSEM_LIBC_STDIO_PRINTF_FLOATING_POINT -> 0 
    +C CYGSEM_LIBC_STDIO_SCANF_FLOATING_POINT, "requires" constraint not satisfied:      CYGPKG_LIBM 
    + Possible solution: 
    +    CYGSEM_LIBC_STDIO_SCANF_FLOATING_POINT -> 0 

    +If the proposed solutions are acceptable, the resolve command can be +used to apply them: +

    +
    $ ecosconfig resolve 
    +U CYGSEM_LIBC_STDIO_SCANF_FLOATING_POINT, new inferred value 0 
    +U CYGFUN_LIBC_strtod, new inferred value 0 
    +U CYGSEM_LIBC_STDIO_PRINTF_FLOATING_POINT, new inferred value 0 

    +The current configuration is again conflict-free and it is possible +to generate a build tree. The --quiet qualifier can be used to +suppress the change messages, if desired.

    +

    When changing individual configuration options by +editing the ecos.ecc file (as described below), the resulting system +should be checked and any problems should be resolved. For example, +if CYGFUN_LIBC_strtod is explicitly enabled in the savefile: +

    +
    $ edit ecos.ecc
    +$ ecosconfig check 
    +Target: pid 
    +Template: default 
    +Removed: 
    +    CYGPKG_LIBM 
    +1 conflict(s): 
    +C CYGFUN_LIBC_strtod, "requires" constraint not satisfied: CYGPKG_LIBM 
    +$ ecosconfig resolve 
    +C CYGFUN_LIBC_strtod, "requires" constraint not satisfied: CYGPKG_LIBM 

    +In this case the inference engine cannot resolve the conflict +automatically because that would involve changing a user setting. Any +attempt to generate a build tree will fail: +

    +
    $ ecosconfig --srcdir /home/bartv/ecc/ecc tree 
    +C CYGFUN_LIBC_strtod, "requires" constraint not satisfied: CYGPKG_LIBM 

    +Unable to generate build tree, this configuration still contains +conflicts. Either resolve the conflicts or use --ignore-errors +

    +

    It is still possible to generate a build tree: +

    +
    $ ecosconfig --srcdir /home/bartv/ecc/ecc --ignore-errors      tree 
    +C CYGFUN_LIBC_strtod, "requires" constraint not satisfied: CYGPKG_LIBM 
    +$ make 

    +In this case eCos will fail to build. In other cases of unresolved +conflicts eCos may build, but may not run. In general all conflicts +should be resolved by editing the ecos.ecc file, by letting the +inference engine make appropriate changes, or by other means, before +any attempt is made to build or run eCos. +

    +

    +Building the System

    +

    +Once a build tree has been generated with ecosconfig +, building eCos is straightforward:

    +
     
    +$ make

    +The build tree contains the +subdirectories, makefiles, and everything else that is needed to +generate the default configuration for the selected architecture and +platform. The only requirement is that the tools needed for that +architecture, for example powerpc-eabi-g++ , +are available using the standard search path. If this is not the case +then the make will fail with an error message. +If you have a multiprocessor system then it may be more efficient to +use:

    +
     
    +$ make -j 
    +n

    +where n is equal to the number of +processors on your system.

    +

    Once the make +process has completed, the install tree will contain the header files +and the target library that are needed for application development. +

    +

    It is also possible to +build the system's test cases for the current configuration:

    +
     
    +$ make tests
    + 

    +The +resulting test executables will end up in a tests +subdirectory of the install tree. +

    +

    If disk space is scarce +then it is possible to make the copy of the install tree for +application development purposes, and then use: +

    +
     
    +$ make clean

    +The build tree will now use up a minimum +of disk space -- the bulk of what is left consists of configuration +header files that you may have edited and hence should not be deleted +automatically. However, it is possible to rebuild the system at any +time without reinvoking ecosconfig , just by +running make again. +

    +

    Under exceptional +circumstances it may be necessary to run make clean +for other reasons, such as when a new release of the toolchain is +installed. The toolchain includes a number of header files which are +closely tied to the compiler, for example limits.h +, and these header files are not and should not be duplicated by +eCos. The makefiles perform header file dependency analysis, so that +when a header file is changed all affected sources will be rebuilt +during the next make . This is very useful when +the configuration header files are changed, but it also means that a +build tree containing information about the locations of header files +must be rebuilt. If a new version of the toolchain is installed and +the old version is removed then this location information is no +longer accurate, and make will complain that +certain dependencies cannot be satisfied. Under such circumstances it +is necessary to do a make clean first. +

    +

    Packages

    +

    +eCos is a component architecture. The system comes as a number of +packages which can be enabled or disabled as required, and new +packages can be added as they become available. Unfortunately, the +packages are not completely independent: for example the µ +ITRON compatibility package relies almost entirely on functionality +provided by the kernel package, and it would not make sense to try to +build µ ITRON if the kernel was disabled. The C +library has fewer dependencies: some parts of the C library rely on +kernel functionality, but it is possible to disable these parts and +thus build a system that has the C library but no kernel. The +ecosconfig tool has the capability of checking +that all the dependencies are satisfied, but it may still be possible +to produce configurations that will not build or (conceivably) that +will build but not run. Developers should be aware of this and take +appropriate care.

    +

    +By default, ecosconfig will include all +packages that are appropriate for the specified hardware in the +configuration. The common HAL package and the eCos infrastructure +must be present in every configuration. In addition, it is always +necessary to have one architectural HAL package and one platform HAL +package. Other packages are optional, and can be added or removed +from a configuration as required.

    +

    The application may not +require all of the packages; for example, it might not need the µ +ITRON compatibility package, or the floating point support provided +by the math library. There is a slight overhead when eCos is built +because the packages will get compiled, and there is also a small +disk space penalty. However, any unused facilities will get stripped +out at link-time, so having redundant packages will not affect the +final executable. +

    +

    Coarse-grained +Configuration

    +

    +Coarse-grained configuration of an eCos system means making +configuration changes using the ecosconfig +tool. These changes include: +

    +
      +
    1. switching to different target + hardware +

      +
    2. switching to a different template +

      +
    3. adding or removing a package +

      +
    4. changing the version of a package +

      +
    +

    Whenever ecosconfig +generates or updates an eCos configuration, it generates a +configuration save file.

    +

    Suppose that the +configuration was first created using the following command line: +

    +
     
    +$ ecosconfig new stdeval1

    +To change the target hardware to the +Cogent CMA28x PowerPC board, the following command would be needed: +

    +
     
    +$ ecosconfig target cma28x

    +To switch to the PowerPC simulator +instead: +

    +
     
    +$ ecosconfig target psim

    +As the hardware changes, hardware-related +packages such as the HAL packages and device drivers will be added to +and removed from the configuration as appropriate. +

    +

    To remove any package +from the current configuration, use the remove +command: +

    +
     
    +$ ecosconfig remove uitron

    +You can disable multiple packages using +multiple arguments, for example: +

    +
     
    +$ ecosconfig remove uitron libm

    +If this turns out to have been a mistake +then you can reenable one or more packages with the add +command: +

    +
     
    +$ ecosconfig add libm

    +Changing the desired version for a +package is also straightforward:

    +
     
    +$ ecosconfig version v1_3_x kernel

    +where x may be a one or two digit number

    +

    It is necessary to regenerate the build tree and +header files following any changes to the configuration before +rebuilding eCos:

    +
    $ ecosconfig tree

    +Fine-grained Configuration

    +

    +ecosconfig only provides coarse-grained control +over the configuration: the hardware, the template and the packages +that should be built. Unlike the Configuration Tool, ecosconfig +does not provide any facilities for manipulating finer-grained +configuration options such as how many priority levels the scheduler +should support. There are hundreds of these options, and manipulating +them by means of command line arguments would not be sensible. +

    +

    In the current system +fine-grained configuration options may be manipulated by manual +editing of the configuration file. When a file has been edited in +this way, the ecosconfig tool should be used to +check the configuration for any conflicts which may have been +introduced:

    +
     
    +$ ecosconfig check

    +The check command +will list all conflicts and will also rewrite the configuration file, +propogating any changes which affect other options. The user may +choose to resolve the conflicts either by re-editing the +configuration file manually or by invoking the inference engine using +the resolve command:

    +
     
    +$ ecosconfig resolve

    +The resolve command +will list all conflicts which can be resolved and save the resulting +changes to the configuration.

    +

    It is necessary to +regenerate the build tree and header files following any changes to +the configuration before rebuilding eCos:

    +
     
    +$ ecosconfig tree

    +All the configuration options and their +descriptions are listed in the eCos Reference +Manual. +

    +

    Editing an eCos +Savefile

    +

    The eCos configuration +information is held in a single savefile, typically ecos.ecc +, which can be generated by either the GUI configuration tool or by +the command line ecosconfig tool. The file +normally exists at the toplevel of the build tree. It is a text file, +allowing the various configurations options to be edited inside a +suitable text editor or by other programs or scripts, as well as in +the GUI config tool.

    +

    An eCos savefile is +actually a script in the Tcl programming +language, so any modifications to the file need to preserve Tcl +syntax. For most configuration options, any modifications will be +trivial and there is no need to worry about Tcl syntax. For example, +changing a 1 to a 0 to disable an option. For more complicated +options, for example CYGDAT_UITRON_TASK_EXTERNS +, which involves some lines of C code, more care has to be +taken. If an edited savefile is no longer a valid Tcl script then the +configuration tools will be unable to read back the data for further +processing, for example to generate a build tree. An outline of Tcl +syntax is given below. One point worth noting here is that a line +that begins with a "#" is usually a comment, and the bulk +of an eCos savefile actually consists of such comments, to make it +easier to edit.

    +

    Header

    +

    An eCos savefile begins +with a header, which typically looks something like this:

    +
     
    +# eCos saved configuration
    +# ---- commands -------------------------------------------------------- 
    +# This section contains information about the savefile format. 
    +# It should not be edited. Any modifications made to this section 
    +# may make it impossible for the configuration tools to read 
    +# the savefile.
    +
    +cdl_savefile_version 1; 
    +cdl_savefile_command cdl_savefile_version {};
    +cdl_savefile_command cdl_savefile_command {}; 
    +cdl_savefile_command 
    +cdl_configuration { description hardware template package }; 
    +cdl_savefile_command cdl_package { value_source user_value wizard_value inferred_value }; 
    +cdl_savefile_command cdl_component { value_source user_value wizard_value inferred_value }; 
    +cdl_savefile_command cdl_option { value_source user_value wizard_value inferred_value }; 
    +cdl_savefile_command cdl_interface { value_source user_value wizard_value inferred_value }; 

    +This section of the savefile is intended +for use by the configuration system, and should not be edited. If +this section is edited then the various configuration tools may no +longer be able to read in the modified savefile.

    +

    Toplevel Section

    +

    The header is followed by +a section that defines the configuration as a whole. A typical +example would be:

    +
     
    +
    +# ---- toplevel -------------------------------------------------------- 
    +# This section defines the toplevel configuration object. The only 
    +# values that can be changed are the name of the configuration and 
    +# the description field. It is not possible to modify the target, 
    +# the template or the set of packages simply by editing the lines 
    +# below because these changes have wide-ranging effects. Instead 
    +# the appropriate tools should be used to make such modifications.
    +
    +cdl_configuration eCos {     
    +description "" ;         
    +
    +# These fields should not be modified.     
    +hardware    pid ;     
    +template    uitron ;     
    +package -hardware CYGPKG_HAL_ARM current ;     
    +package -hardware CYGPKG_HAL_ARM_PID current ;     
    +package -hardware CYGPKG_IO_SERIAL current ;     
    +package -template CYGPKG_HAL current ;     
    +package -template CYGPKG_IO current ;     
    +package -template CYGPKG_INFRA current ;     
    +package -template CYGPKG_KERNEL current ;     
    +package -template CYGPKG_UITRON current ;     
    +package -template CYGPKG_LIBC current ;     
    +package -template CYGPKG_LIBM current ;     
    +package -template CYGPKG_DEVICES_WALLCLOCK current ;     
    +package -template CYGPKG_ERROR current ; 
    +}; 

    +This section +allows the configuration tools to reload the various packages that +make up the configuration. Most of the information should not be +edited. If it is necessary to add a new package or to remove an +existing one then the appropriate tools should be used for this, for +example:

    +
     
    +$ ecosconfig remove CYGPKG_LIBM

    +There are two fields which can be edited. +Configurations have a name; in this case eCos. They can also have a +description, which is some arbitrary text. The configuration tools do +not make use of these fields, they exist so that users can store +additional information about a configuration.

    +

    Conflicts Section

    +

    The toplevel section is +followed by details of all the conflicts (if any) in the +configuration, for example:

    +
     
    + 
    +# ---- conflicts ------------------------------------------------------- 
    +# There are 2 conflicts. 
    +# 
    +# option CYGNUM_LIBC_TIME_DST_DEFAULT_OFFSET 
    +#   Property LegalValues 
    +#   Illegal current value 100000 
    +#   Legal values are: -90000 to 90000 
    +# 
    +# option CYGSEM_LIBC_TIME_CLOCK_WORKING 
    +#   Property Requires 
    +#   Requires constraint not satisfied: CYGFUN_KERNEL_THREADS_TIMER 

    +When editing +a configuration you may end up with something that is invalid. Any +problems in the configuration will be reported in the conflicts +section. In this case there are two conflicts. The option +CYGNUM_LIBC_TIME_DST_DEFAULT_OFFSET has +been given an illegal value: typically this would be fixed by +searching for the definition of that option later on in the savefile +and modifying the value. The second conflict is more interesting, an +unsatisfied requires constraint. +Configuration options are not independent: disabling some +functionality in, say, the kernel, can have an impact elsewhere; in +this case the C library. The various dependencies between the options +are specified by the component developers and checked by the +configuration system. In this case there are two obvious ways in +which the conflict could be resolved: re-enabling +CYGFUN_KERNEL_THREADS_TIMER, or disabling +CYGSEM_LIBC_TIME_CLOCK_WORKING. Both of +these options will be listed later on in the file.

    +

    Some care has to be taken +when modifying configuration options, to avoid introducing new +conflict. For instance it is possible that there might be other +options in the system which have a dependency on +CYGSEM_LIBC_TIME_CLOCK_WORKING, so +disabling that option may not be the best way to resolve the +conflict. Details of all such dependencies are provided in the +appropriate places in the savefile.

    +

    It is not absolutely +required that a configuration be conflict-free before generating a +build tree and building eCos. It is up to the developers of each +component to decide what would happen if an attempt is made to build +eCos while there are still conflicts. In serious cases there is +likely to be a compile-time failure, or possibly a link-time failure. +In less serious cases the system may build happily and the +application can be linked with the resulting library, but the +component may not quite function as intended - although it may still +be good enough for the specific needs of the application. It is also +possible that everything builds and links, but once in a while the +system will unaccountably crash. Using a configuration that still has +conflicts is done entirely at the user's risk.

    +

    Data Section

    +

    The bulk of the savefile +lists the various packages, components, and options, including their +values and the various dependencies. A number of global options come +first, especially those related to the build process such as compiler +flags. These are followed by the various packages, and the components +and options within those packages, in order.

    +

    Packages, components and +options are organized in a hierarchy. If a particular component is +disabled then all options and sub-components below it will be +inactive: any changes made to these will have no effect. The savefile +contains information about the hierarchy in the form of comments, for +example:

    +
     
    +cdl_package CYGPKG_KERNEL ... 
    +# > 
    +cdl_component CYGPKG_KERNEL_EXCEPTIONS ... 
    +# > 
    +cdl_option CYGSEM_KERNEL_EXCEPTIONS_DECODE ... 
    +cdl_option CYGSEM_KERNEL_EXCEPTIONS_GLOBAL ... 
    +# < 
    +cdl_component CYGPKG_KERNEL_SCHED ... 
    +# > 
    +cdl_option CYGSEM_KERNEL_SCHED_MLQUEUE ... 
    +cdl_option CYGSEM_KERNEL_SCHED_BITMAP ... 
    +# < 
    +# < 

    +This corresponds to the following +hierarchy:

    +
     
    + CYGPKG_KERNEL
    +   CYGPKG_KERNEL_EXCEPTIONS
    +     CYGSEM_KERNEL_EXCEPTIONS_DECODE
    +     CYGSEM_KERNEL_EXCEPTIONS_GLOBAL
    +   CYGPKG_KERNEL_SCHED
    +     CYGSEM_KERNEL_SCHED_MLQUEUE
    +     CYGSEM_KERNEL_SCHED_BITMAP 

    +Providing the hierarchy information in +this way allows programs or scripts to analyze the savefile and +readily determine the hierarchy. It could also be used by a +sufficiently powerful editor to support structured editing of eCos +savefiles. The information is not used by the configuration tools +themselves since they obtain the hierarchy from the original CDL +scripts.

    +

    Each configurable entity +is preceded by a comment, of the following form:

    +
     
    +
    +# Kernel schedulers 
    +# doc: ref/ecos-ref/ecos-kernel-overview.html#THE-SCHEDULER 
    +# The eCos kernel provides a choice of schedulers. In addition 
    +# there are a number of configuration options to control the 
    +# detailed behaviour of these schedulers. 
    +cdl_component CYGPKG_KERNEL_SCHED {     
    +... 
    +}; 

    +This provides a short textual alias +Kernel schedulers for the component. If online +documentation is available for the configurable entity then this will +come next. Finally there is a short description of the entity as a +whole. All this information is provided by the component developers.

    +

    Each configurable entity +takes the form:

    +
     
    +<type> <name> {
    +     <data>
    +};

    +Configurable entities may not be active. +This can be either because the parent is disabled or inactive, or +because there are one or more active_if +properties. Modifying the value of an inactive entity has no effect +on the configuration, so this information is provided first:

    +
     
    +cdl_option CYGSEM_KERNEL_EXCEPTIONS_DECODE {     
    +# This option is not active     
    +# The parent CYGPKG_KERNEL_EXCEPTIONS is disabled     
    +... 
    +};
    + 
    +...
    +
    +cdl_option CYGIMP_IDLE_THREAD_YIELD {     
    +# This option is not active     
    +# ActiveIf constraint: (CYGNUM_KERNEL_SCHED_PRIORITIES == 1)     
    +#     CYGNUM_KERNEL_SCHED_PRIORITIES == 32     
    +#   - 0     
    +... 
    +}; 

    +For CYGIMP_IDLE_THREAD_YIELD +the savefile lists the expression that must be satisfied if the +option is to be active, followed by the current value of all entities +that are referenced in the expression, and finally the result of +evaluating that expression.

    +

    Not all options are +directly modifiable in the savefile. First, the value of packages +(which is the version of that package loaded into the configuration) +cannot be modified here.

    +
     
    +
    +cdl_package CYGPKG_KERNEL {     
    +# Packages cannot be added or removed, nor can their version be changed,     
    +# simply by editing their value. Instead the appropriate configuration     
    +# should be used to perform these actions.     .
    +..; 
    +} 

    +The version of a package can be changed +using e.g.: +

    +
     
    +$ ecosconfig version 1.3 CYGPKG_KERNEL

    +Even though a package's value cannot be +modified here, it is still important for the savefile to contain the +details. In particular packages may impose constraints on other +configurable entities and may be referenced by other configurable +entities. Also it would be difficult to understand or extract the +configuration's hierarchy if the packages were not listed in the +appropriate places in the savefile.

    +

    Some components (or, +conceivably, options) do not have any associated data. Typically they +serve only to introduce another level in the hierarchy, which can be +useful in the context of the GUI configuration tool.

    +
     
    +
    +cdl_component CYGPKG_HAL_COMMON_INTERRUPTS {     
    +# There is no associated value. 
    +}; 

    +Other components or options have a +calculated value. These are not user-modifiable, but typically the +value will depend on other options which can be modified. Such +calculated options can be useful when controlling what gets built or +what ends up in the generated configuration header files. A +calculated value may also effect other parts of the configuration, +for instance, via a requires constraint.

    +
     
    +
    +cdl_option BUFSIZ {     
    +# Calculated value: CYGSEM_LIBC_STDIO_WANT_BUFFERED_IO ? CYGNUM_LIBC_STDIO_BUFSIZE : 0     
    +#     CYGSEM_LIBC_STDIO_WANT_BUFFERED_IO == 1     
    +#     CYGNUM_LIBC_STDIO_BUFSIZE == 256     
    +# Current_value: 256 
    +}; 

    +A special type of calculated value is the +interface. The value of an interface is the +number of active and enabled options which implement +that interface. Again the value of an interface cannot be modified +directly; only by modifying the options which implement the +interface. However, an interface can be referenced by other parts of +the configuration. +

    +
     
    +cdl_interface CYGINT_KERNEL_SCHEDULER {     
    +# Implemented by CYGSEM_KERNEL_SCHED_MLQUEUE, active, enabled     
    +# Implemented by CYGSEM_KERNEL_SCHED_BITMAP, active, disabled     
    +# This value cannot be modified here.     
    +# Current_value: 1     
    +# Requires: 1 == CYGINT_KERNEL_SCHEDULER     
    +#     CYGINT_KERNEL_SCHEDULER == 1     
    +#   - 1
    + 
    +# The following properties are affected by this value     
    +# interface CYGINT_KERNEL_SCHEDULER     
    +#     Requires: 1 == CYGINT_KERNEL_SCHEDULER 
    +}; 

    +If the configurable entity is modifiable +then there will be lines like the following:

    +
     
    + 
    +cdl_option CYGSEM_KERNEL_SCHED_MLQUEUE {     
    +...     
    +# Flavor: bool     
    +# No user value, uncomment the following line to provide one.     
    +# user_value 1     
    +# value_source default     
    +# Default value: 1     
    +... 
    +}; 

    +Configurable entities can have one of +four different flavors: none, bool, data and booldata. Flavor none +indicates that there is no data associated with the entity, typically +it just acts as a placeholder in the overall hierarchy. Flavor bool +is the most common, it is a simple yes-or-no choice. Flavor data is +for more complicated configuration choices, for instance the size of +an array or the name of a device. Flavor booldata is a combination of +bool and data: the option can be enabled or disabled, and there is +some additional data associated with the option as well.

    +

    In the above example the +user has not modified this particular option, as indicated by the +comment and by the commented-out user_value +line. To disable this option the file should be edited to:

    +
     
    +
    +cdl_option CYGSEM_KERNEL_SCHED_MLQUEUE {     
    +...     
    +# Flavor: bool     
    +# No user value, uncomment the following line to provide one.     
    +user_value 0     
    +# value_source default     
    +# Default value: 1     
    +... 
    +} 

    +The comment preceding the user_value +0 line can be removed if desired, otherwise it will be removed +automatically the next time the file is read and updated by the +configuration tools.

    +

    Much the same process +should be used for options with the data flavor, for example:

    +
     
    + 
    +cdl_option CYGNUM_LIBC_TIME_DST_DEFAULT_OFFSET {     
    +# Flavor: data     
    +# No user value, uncomment the following line to provide one.     
    +# user_value 3600     
    +# value_source default     
    +# Default value: 3600     
    +# Legal values: -90000 to 90000 
    +}; 

    +can be changed to:

    +
     
    +
    +cdl_option CYGNUM_LIBC_TIME_DST_DEFAULT_OFFSET {     
    +# Flavor: data     
    +user_value 7200     
    +# value_source default     
    +# Default value: 3600     
    +# Legal values: -90000 to 90000 }; 

    +Note that the original text provides the +default value in the user_value comment, on the +assumption that the desired new value is likely to be similar to the +default value. The value_source comment does +not need to be updated, it will be fixed up if the savefile is fed +back into the configuration system and regenerated.

    +

    For options with the +booldata flavor, the user_value line needs take +two arguments. The first argument is for the boolean part, the second +for the data part. For example:

    +
     
    + 
    +cdl_component CYGNUM_LIBM_COMPATIBILITY {     
    +# Flavor: booldata     
    +# No user value, uncomment the following line to provide one.    
    +# user_value 1 POSIX     
    +# value_source default     
    +# Default value: 1 POSIX     
    +# Legal values:  "POSIX" "IEEE" "XOPEN" "SVID"     
    +... 
    +}; 

    +could be changed to:

    +
     
    + 
    +cdl_component CYGNUM_LIBM_COMPATIBILITY {     
    +# Flavor: booldata     
    +user_value 1 IEEE     
    +# value_source default     
    +# Default value: 1 POSIX     
    +# Legal values:  "POSIX" "IEEE" "XOPEN" "SVID"     
    +... 
    +}; 

    +or alternatively, if the whole component +should be disabled, to:

    +
     
    + 
    +cdl_component CYGNUM_LIBM_COMPATIBILITY {     
    +# Flavor: booldata     
    +user_value 0 POSIX     
    +# value_source default     
    +# Default value: 1 POSIX     
    +# Legal values:  "POSIX" "IEEE" "XOPEN" "SVID"     
    +... 
    +}; 

    +Some options take values that span +multiple lines. An example would be:

    +
     
    +
    +cdl_option CYGDAT_UITRON_MEMPOOLVAR_INITIALIZERS {     
    +# Flavor: data     
    +# No user value, uncomment the following line to provide one.     
    +# user_value \     
    +# "CYG_UIT_MEMPOOLVAR( vpool1, 2000 ), \\     
    +#  CYG_UIT_MEMPOOLVAR( vpool2, 2000 ), \\     
    +#  CYG_UIT_MEMPOOLVAR( vpool3, 2000 ),"     
    +# value_source default     
    +# Default value: \     
    +#     "CYG_UIT_MEMPOOLVAR( vpool1, 2000 ), \\     
    +#      CYG_UIT_MEMPOOLVAR( vpool2, 2000 ), \\     
    +#      CYG_UIT_MEMPOOLVAR( vpool3, 2000 )," 
    +}; 

    +Setting a user value for this option +involves uncommenting and modifying all relevant lines, for example:

    +
     
    +
    +cdl_option CYGDAT_UITRON_MEMPOOLVAR_INITIALIZERS {     
    +# Flavor: data     
    +user_value \     
    +"CYG_UIT_MEMPOOLVAR( vpool1, 4000 ), \\      
    +CYG_UIT_MEMPOOLVAR( vpool2, 4000 ),"     
    +# value_source default     
    +# Default value: \     
    +#     "CYG_UIT_MEMPOOLVAR( vpool1, 2000 ), \\     
    +#      CYG_UIT_MEMPOOLVAR( vpool2, 2000 ), \\     
    +#      CYG_UIT_MEMPOOLVAR( vpool3, 2000 )," 
    +}; 

    +In such cases appropriate care has to be +taken to preserve Tcl syntax, as discussed below.

    +

    The configuration system +has the ability to keep track of several different values for any +given option. All options start off with a default value, in other +words their value source is set to default . If +a configuration involves conflicts and the configuration system's +inference engine is allowed to resolve these automatically then it +may provide an inferred value instead, for +example:

    +
     
    +
    +cdl_option CYGMFN_KERNEL_SYNCH_CONDVAR_TIMED_WAIT {     
    +# Flavor: bool     
    +# No user value, uncomment the following line to provide one.     
    +# user_value 1     
    +# The inferred value should not be edited directly.     
    +inferred_value 0     
    +# value_source inferred     
    +# Default value: 1     
    +... 
    +}; 

    +Inferred values are calculated by the +configuration system and should not be edited by the user. If the +inferred value is not correct then a user value should be substituted +instead:

    +
     
    +
    +cdl_option CYGMFN_KERNEL_SYNCH_CONDVAR_TIMED_WAIT {     
    +# Flavor: bool     
    +user_value 1     
    +# The inferred value should not be edited directly.     
    +inferred_value 0     
    +# value_source inferred     
    +# Default value: 1     
    +... 
    +}; 

    +The inference engine will not override a +user value with an inferred one. Making a change like this may well +re-introduce a conflict, since the inferred value was only calculated +to resolve a conflict. Another run of the inference engine may find a +different and more acceptable way of resolving the conflict, but this +is not guaranteed and it may be up to the user to examine the various +dependencies and work out an acceptable solution.

    +

    Inferred values are +listed in the savefile because the exact inferred value may depend on +the order in which changes were made and conflicts were resolved. If +the inferred values were absent then it is possible that reloading a +savefile would not exactly restore the configuration. Default values +on the other hand are entirely deterministic so there is no actual +need for the values to be listed in the savefile. However, the +default value can be very useful information so it is provided in a +comment.

    +

    Occasionally the user +will want to do some experimentation, and temporarily switch an +option from a user value back to a default or inferred one to see +what the effect would be. This could be achieved by simply commenting +out the user value. For instance, if the current savefile contains:

    +
     
    + 
    +cdl_option CYGMFN_KERNEL_SYNCH_CONDVAR_TIMED_WAIT {     
    +# Flavor: bool     
    +user_value 1     
    +# The inferred value should not be edited directly.     
    +inferred_value 0     
    +# value_source user     
    +# Default value: 1     
    +... 
    +}; 

    +then the inferred value could be restored +by commenting out or removing the user_value +line:

    +
     
    + 
    +cdl_option CYGMFN_KERNEL_SYNCH_CONDVAR_TIMED_WAIT {     
    +# Flavor: bool     
    +# user_value 1     
    +# The inferred value should not be edited directly.     
    +inferred_value 0     
    +# value_source user     
    +# Default value: 1     
    +... 
    +}; 

    +This is fine for simple values. However +if the value is complicated then there is a problem: commenting out +the user_value line or lines means that the +user value becomes invisible to the configuration system, so if the +savefile is loaded and then regenerated the information will be lost. +An alternative approach is to keep the user_value +but explicitly set the value_source line, for +example:

    +
     
    +
    +cdl_option CYGMFN_KERNEL_SYNCH_CONDVAR_TIMED_WAIT {     
    +# Flavor: bool     
    +user_value 1     
    +# The inferred value should not be edited directly.     
    +inferred_value 0     
    +value_source inferred     
    +# Default value: 1     
    +... 
    +}; 

    +In this case the configuration system +will use the inferred value for the purposes of dependency analysis +etc., even though a user value is present. To restore the user value +the value_source line can be commented out +again. If there is no explicit value_source +then the configuration system will just use the highest priority one: +the user value if it exists; otherwise the inferred value if it +exists; otherwise the default value which always exists.

    +

    The default value for an +option can be a simple constant, or it can be an expression involving +other options. In the latter case the expression will be listed, +together with the values for all options referenced in the expression +and the current result of evaluating that expression. This is for +informational purposes only, the default value is always recalculated +deterministically when loading in a savefile.

    +
     
    +
    +cdl_option CYGBLD_GLOBAL_COMMAND_PREFIX {     
    +# Flavor: data     
    +# No user value, uncomment the following line to provide one.     
    +# user_value arm-elf     
    +# value_source default     
    +# Default value:  CYGHWR_THUMB ? "thumb-elf" : "arm-elf"     
    +#     CYGHWR_THUMB == 0     
    +#   - arm-elf 
    +}; 

    +For options with the data or booldata +flavor, there are likely to be constraints on the possible values. If +the value is supposed to be a number in a given range and a user +value of " hello world " is provided +instead then there are likely to be compile-time failures. Component +developers can specify constraints on the legal values, and these +will be listed in the savefile.

    +
     
    + 
    +cdl_option X_TLOSS {     
    +# Flavor: data     
    +# No user value, uncomment the following line to provide one.     
    +# user_value 1.41484755040569E+16     
    +# value_source default     
    +# Default value: 1.41484755040569E+16     
    +# Legal values: 1 to 1e308 
    +};
    + 
    +cdl_component CYGNUM_LIBM_COMPATIBILITY {     
    +# Flavor: booldata     
    +# No user value, uncomment the following line to provide one.     
    +# user_value 1 POSIX     
    +# value_source default     
    +# Default value: 1 POSIX     
    +# Legal values:  "POSIX" "IEEE" "XOPEN" "SVID"     
    +... 
    +};

    +In some cases the legal values list may +be an expression involving other options. If so then the current +values of the referenced options will be listed, together with the +result of evaluating the list expression, just as for default value +expressions.

    +

    If an illegal value is +provided then this will result in a conflict, listed in the conflicts +section of the savefile. For more complicated options a simple legal +values list is not sufficient to allow the current value to be +validated, and the configuration system will be unable to flag +conflicts. This issue will be addressed in future releases of the +configuration system.

    +

    Following the +value-related fields for a given option, any requires +constraints belonging to this option will be listed. These +constraints are only effective if the option is active and, for bool +and booldata flavors, enabled. If some aspect of eCos functionality +is inactive or disabled then it cannot impose any constraints on the +rest of the system. As usual, the full expression will be listed +followed by the current values of all options that are referenced and +the result of evaluating the expression:

    +
     
    +
    +cdl_option CYGSEM_LIBC_TIME_TIME_WORKING {     
    +...     
    +# Requires: CYGPKG_DEVICES_WALLCLOCK     
    +#     CYGPKG_DEVICES_WALLCLOCK == current     
    +#   - 1 
    +};

    +When modifying the value of an option it +is useful to know not only what constraints the option imposes on the +rest of the system but also what other options in the system depend +in some way on this one. The savefile provides this information:

    +
     
    +
    +cdl_option CYGFUN_KERNEL_THREADS_TIMER {     
    +...     
    +# The following properties are affected by this value     
    +# option CYGMFN_KERNEL_SYNCH_CONDVAR_TIMED_WAIT     
    +#     Requires: CYGFUN_KERNEL_THREADS_TIMER     
    +# option CYGIMP_UITRON_STRICT_CONFORMANCE     
    +#     Requires: CYGFUN_KERNEL_THREADS_TIMER     
    +# option CYGSEM_LIBC_TIME_CLOCK_WORKING     
    +#     Requires: CYGFUN_KERNEL_THREADS_TIMER 
    +}; 

    +Tcl Syntax

    +

    eCos savefiles are +implemented as Tcl scripts, and are read in by running the data +through a standard Tcl interpreter that has been extended with a +small number of additional commands such as cdl_option +and cdl_configuration . In many cases this is +an implementation detail that can be safely ignored while editing a +savefile: simply replacing a 1 with a 0 +to disable some functionality is not going to affect whether or not +the savefile is still a valid Tcl script and can be processed by a +Tcl interpreter. However, there are more complicated cases where an +understanding of Tcl syntax is at least desirable, for example:

    +
     
    +
    +cdl_option CYGDAT_UITRON_MEMPOOLVAR_EXTERNS {
    +     # Flavor: data
    +     user_value \
    +      "static char vpool1\[ 2000 \], \\
    +      vpool2\[ 2000 \], \\
    +       vpool3\[ 2000 \];"     
    +# value_source default     
    +# Default value: \
    +     #     "static char vpool1\[ 2000 \], \\
    +     #      vpool2\[ 2000 \], \\
    +    #      vpool3\[ 2000 \];" 
    +};

    +The backslash at the end of the +user_value line is processed by the Tcl +interpreter as a line continuation character. The quote marks around +the user data are also interpreted by the Tcl interpreter and serve +to turn the entire data field into a single argument. The backslashes +preceding the opening and closing square brackets prevent the Tcl +interpreter from treating these characters specially, otherwise there +would be an attempt at command substitution +as described below. The double backslashes at the end of each line of +the data will be turned into a single backslash by the Tcl +interpreter, rather than escaping the newline character, so that the +actual data seen by the configuration system is:

    +
     
    +
    +static char vpool1[ 2000 ], \
    +      vpool2[ 2000 ], \
    +      vpool3[ 2000 ];

    +This is of course the data that should +end up in the µ ITRON configuration header file. The +opening and closing braces surrounding the entire body of the option +data are also significant and cause this body to be passed as a +single argument to the cdl_option command. The +closing semicolon is optional in this example, but provides a small +amount of additional robustness if the savefile is edited such that +it is no longer a valid Tcl script. If the data contained any $ +characters then these would have to be treated specially as well, via +a backslash escape.

    +

    In spite of what all the +above might seem to suggest, Tcl is actually a very simple yet +powerful scripting language: the syntax is defined by just eleven +rules. On occasion this simplicity means that Tcl's behaviour is +subtly different from other languages, which can confuse newcomers.

    +

    When the Tcl interpreter +is passed some data such as puts Hello , it +splits this data into a command and its arguments. The command will +be terminated by a newline or by a semicolon, unless one of the +quoting mechanisms is used. The command and each of its arguments are +separated by white space. So in the following example:

    +
     
    +puts Hello 
    +set x 42 

    +will result in two separate commands +being executed. The first command is puts and +is passed a single argument, Hello . The second +command is set and is passed two arguments, x +and 42 . The intervening newline character +serves to terminate the first command, and a semi-colon separator +could be used instead: +

    +
     
    +puts Hello;set x 42

    +Any white space surrounding the semicolon +is just ignored because it does not serve to separate arguments.

    +

    Now consider the +following:

    +
     
    +set x Hello world

    +This is not valid Tcl. It is an attempt +to invoke the set command with three arguments: +x , Hello , and world +. The set only takes two arguments, a variable +name and a value, so it is necessary to combine the data into a +single argument by quoting:

    +
     
    +set x "Hello world"

    +When the Tcl interpreter encounters the +first quote character it treats all subsequent data up to but not +including the closing quote as part of the current argument. The +quote marks are removed by the interpreter, so the second argument +passed to the set command is just Hello +world without the quote characters. This can be significant in +the context of eCos savefiles. For instance, consider the following +configuration option:

    +
     
    +
    +cdl_option CYGDAT_LIBC_STDIO_DEFAULT_CONSOLE {     
    +# Flavor: data     
    +# No user value, uncomment the following line to provide one.     
    +# user_value "\"/dev/ttydiag\""     
    +# value_source default     
    +# Default value: "\"/dev/ttydiag\"" 
    +}; 

    +The desired value of the configuration +option should be a valid C string, complete with quote characters. If +the savefile was edited to: +

    +
     
    +
    +cdl_option CYGDAT_LIBC_STDIO_DEFAULT_CONSOLE {     
    +# Flavor: data     
    +user_value "/dev/ttydiag"     
    +# value_source default     
    +# Default value: "\"/dev/ttydiag\"" 
    +}; 

    +then the Tcl interpreter would remove the +quote marks when the savefile is read back in, so the option's value +would not have any quote marks and would not be a valid C string. The +configuration system is not yet able to perform the required +validation so the following #define would be +generated in the configuration header file:

    +
     
    +#define CYGDAT_LIBC_STDIO_DEFAULT_CONSOLE /dev/ttydiag 

    +This is likely to cause a compile-time +failure when building eCos.

    +

    A quoted argument +continues until the closing quote character is encountered, which +means that it can span multiple lines. This can also be encountered +in eCos savefiles, for instance, in the +CYGDAT_UITRON_MEMPOOLVAR_EXTERNS example +mentioned earlier. Newline or semicolon characters do not terminate +the current command in such cases.

    +

    The Tcl interpreter +supports much the same forms of backslash substitution as other +common programming languages. Some backslash sequences such as \n +will be replaced by the appropriate character. The sequence \\ +will be replaced by a single backslash. A backslash at the very end +of a line will cause that backslash, the newline character, and any +white space at the start of the next line to be replaced by a single +space. Hence the following two Tcl commands are equivalent:

    +
     
    +puts  "Hello\nworld\n" 
    +puts \ 
    +"Hello 
    +world 
    +"

    +In addition to quote and backslash +characters, the Tcl interpreter treats square brackets, the $ +character, and braces specially. Square brackets are used for command +substitution, for example:

    +
     
    +puts "The answer is [expr 6 * 9]"

    +When the Tcl interpreter encounters the +square brackets it will treat the contents as another command that +should be executed first, and the result of executing that is used +when continuing to process the script. In this case the Tcl +interpreter will execute the command expr 6 * 9 +, yielding a result of 54, and then the Tcl interpreter will execute +puts "The answer is 54" . It should +be noted that the interpreter contains only one level of +substitution: if the result of performing command substitution +performs further special characters such as square brackets then +these will not be treated specially.

    +

    Command line substitution +is very unlikely to prove useful in the context of an eCos savefile, +but it is part of the Tcl language and hence cannot be easily +suppressed while reading in a savefile. As a result care has to be +taken when savefile data involves square brackets. Consider the +following:

    +
     
    +
    +cdl_option CYGDAT_UITRON_MEMPOOLFIXED_EXTERNS {
    +     ...
    +     user_value \ 
    +"static char fpool1[ 2000 ], 
    +fpool2[ 2000 ];"
    +     ... 
    +};

    +The Tcl interpreter will interpret the +square brackets as an attempt at command substitution and hence it +will attempt to execute the command 2000 with +no arguments. No such command is defined by the Tcl language or by +the savefile-related extensions provided by the configuration system, +so this will result in an error when an attempt is made to read back +the savefile. Instead it is necessary to backslash-escape the square +brackets and thus suppress command substitution:

    +
     
    +
    +cdl_option CYGDAT_UITRON_MEMPOOLFIXED_EXTERNS {
    +     ...
    +     user_value \ 
    +"static char fpool1\[ 2000 \], 
    +fpool2\[ 2000 \];"
    +     ... 
    +}; 

    +Similarly the $ +character is used in Tcl scripts to perform variable substitution:

    +
     
    +set x [expr 6 * 9] 
    +puts "The answer is $x" 

    +Variable substitution, like command +substitution, is very unlikely to prove useful in the context of an +eCos savefile. Should it be necessary to have a $ +character in configuration data then again a backslash escape needs +to be used.

    +
     
    +cdl_option FOODAT_MONITOR_PROMPT {
    +     ...
    +     user_value "\$ "
    +     ... 
    +};

    +Braces are used to collect a sequence of +characters into a single argument, just like quotes. The difference +is that variable, command and backslash substitution do not occur +inside braces (with the sole exception of backslash substitution at +the end of a line). So, for example, the +CYGDAT_UITRON_MEMPOOL_EXTERNFIXED_EXTERNS +value could be written as:

    +
     
    +cdl_option CYGDAT_UITRON_MEMPOOLFIXED_EXTERNS {
    +     ...
    +     user_value \ 
    +{static char fpool1[ 2000 ], 
    +fpool2[ 2000 ];}
    +     ... 
    +};

    +The configuration system does not use +this when generating savefiles because for simple edits of a savefile +by inexperienced users the use of brace characters is likely to be a +little bit more confusing than the use of quotes.

    +

    At this stage it is worth +noting that the basic format of each configuration option in the +savefile makes use of braces:

    +
     
    +cdl_option <name> {
    +     ... 
    +};

    +The configuration system extends the Tcl +language with a small number of additional commands such as +cdl_option . These commands take two arguments, +a name and a body, where the body consists of all the text between +the braces. First a check is made that the specified option is +actually present in the configuration. Then the body is executed in a +recursive invocation of the Tcl interpreter, this time with +additional commands such as user_value and +value_source . If, after editing, the braces +are not correctly matched up then the savefile will no longer be a +valid Tcl script and errors will be reported when the savefile is +loaded again.

    +

    Comments in Tcl scripts +are introduced by a hash character # . However, +a hash character only introduces a comment if it occurs where a +command is expected. Consider the following:

    +
     
    +# This is a comment 
    +puts "Hello" # world 

    +The first line is a valid comment, since +the hash character occurs right at the start where a command name is +expected. The second line does not contain a comment. Instead it is +an attempt to invoke the puts command with +three arguments: Hello , # +and world . These are not valid arguments for +the puts command so an error will be raised.

    +

    If the second line was +rewritten as:

    +
     
    +puts "Hello"; # world

    +then this is a valid Tcl script. The +semicolon identifies the end of the current command, so the hash +character occurs at a point where the next command would start and +hence it is interpreted as the start of a comment.

    +

    This handling of comments +can lead to subtle behaviour. Consider the following:

    +
     
    +cdl_option WHATEVER {
    +     # This is a comment }
    +     user_value 42
    +     ... 
    +}

    +Consider the way the Tcl interpreter +processes this. The command name and the first argument do not pose +any special difficulties. The opening brace is interpreted as the +start of the next argument, which continues until a closing brace is +encountered. In this case the closing brace occurs on the second +line, so the second argument passed to cdl_option +is \n # This is a comment . This second +argument is processed in a recursive invocation of the Tcl +interpreter and does not contain any commands, just a comment. +Toplevel savefile processing then resumes, and the next command that +is encountered is user_value . Since the +relevant savefile code is not currently processing a configuration +option this is an error. Later on the Tcl interpreter would encounter +a closing brace by itself, which is also an error. Fortunately this +sequence of events is very unlikely to occur when editing generated +savefiles.

    +

    This should be sufficient +information about Tcl to allow for safe editing of eCos savefiles. +Further information is available from a wide variety of sources, for +example the book Tcl and the Tk Toolkit by +John K Ousterhout.

    +

    +Editing the Sources

    +

    +For many users, controlling the packages and manipulating the +available configuration options will be sufficient to create an +embedded operating system that meets the application's requirements. +However, since eCos is shipped entirely in source form, it is +possible to go further when necessary: you can edit the eCos sources +themselves. This requires some understanding of the way the eCos +build system works. +

    +

    +The most obvious place to edit the source code is directly in the +component repository. For example, you could edit the file +kernel/v1_3_x/src/sync/mutex.cxx to change the +way kernel mutexes work, or possibly just to add some extra +diagnostics or assertions. Once the file has been edited, it is +possible to invoke make at the top level of the +build tree and the target library will be rebuilt as required. A +small optimization is possible: the build tree is largely a mirror of +the component repository, so it too will contain a subdirectory +kernel/v1_3_x ; if make +is invoked in this directory then it will only check for changes to +the kernel sources, which is a bit more efficient than checking for +changes throughout the component repository. +

    +

    Editing a file in the +component repository is fine if this tree is used for only one eCos +configuration. If the repository is used for several different +configurations, however, and especially if it is shared by multiple +users, then making what may be experimental changes to the master +sources would be a bad idea. The build system provides an +alternative. It is possible to make a copy of the file in the build +tree, in other words copy mutex.cxx from the +kernel/v1_3_x/src/sync directory in the +component repository to kernel/v1_3_x/src/sync +in the build tree, and edit the file in the build tree. When make +is invoked it will pick up local copies of any of the sources in +preference to the master versions in the component repository. Once +you have finished modifying the eCos sources you can install the +final version back in the component repository. If the changes were +temporary in nature and only served to aid the debugging process, +then you can discard the modified version of the sources. +

    +

    The situation is slightly +more complicated for the header files that a package may export, such +as the C library's stdio.h header file, which +can be found in the directory language/c/libc/v1_3_x/include +. If such a header file is changed, either directly in the component +repository or after copying it to the build tree, then make +must be invoked at the top level of the build tree. In cases like +this it is not safe to rebuild just the C library because other +packages may depend on the contents of stdio.h +. +

    +

    Modifying the Memory +Layout

    +

    +Each eCos platform package is supplied with linker script fragments +which describe the location of memory regions on the evaluation board +and the location of memory sections within these regions. The correct +linker script fragment is selected and included in the eCos linker +script target.ld when eCos is built.

    +

    +It is not necessary to modify the default memory layouts in order to +start development with eCos. However, it will be necessary to edit a +linker script fragment when the memory map of the evaluation board is +changed. For example, if additional memory is added, the linker must +be notified that the new memory is available for use. As a minimum, +this would involve modifying the length of the corresponding memory +region. Where the available memory is non-contiguous, it may be +necessary to declare a new memory region and reassign certain linker +output sections to the new region.

    +

    +Linker script fragments and memory layout header files should be +edited within the eCos install tree. They are located at +include/pkgconf/mlt_*.* . Where multiple +start-up types are in use, it will be necessary to edit multiple +linker script fragments and header files. The information provided in +the header file and the corresponding linker script fragment must +always match. A typical linker script fragment is shown below:

    +

    +eCos linker script fragment

    +
     
    +MEMORY
    +{
    + rom : ORIGIN = 0x40000000, LENGTH = 0x80000
    + ram : ORIGIN = 0x48000000, LENGTH = 0x200000
    +}
    +
    +SECTIONS
    +{
    + SECTIONS_BEGIN
    + SECTION_rom_vectors (rom, 0x40000000, LMA_EQ_VMA)
    + SECTION_text (rom, ALIGN (0x1), LMA_EQ_VMA)
    + SECTION_fini (rom, ALIGN (0x1), LMA_EQ_VMA)
    + SECTION_rodata (rom, ALIGN (0x1), LMA_EQ_VMA)
    + SECTION_rodata1 (rom, ALIGN (0x1), LMA_EQ_VMA)
    + SECTION_fixup (rom, ALIGN (0x1), LMA_EQ_VMA)
    + SECTION_gcc_except_table (rom, ALIGN (0x1), LMA_EQ_VMA)
    + SECTION_data (ram, 0x48000000, FOLLOWING (.gcc_except_table))
    + SECTION_bss (ram, ALIGN (0x4), LMA_EQ_VMA)
    + SECTIONS_END
    +}

    +The file consists of two blocks, the +MEMORY block contains lines describing the +address ( ORIGIN ) and the size ( +LENGTH ) of each memory region. The MEMORY +block is followed by the SECTIONS block which +contains lines describing each of the linker output sections. Each +section is represented by a macro call. The arguments of these macros +are ordered as follows: +

    +
      +
    1. The memory region in which the + section will finally reside. +

      +
    2. The final address ( + VMA ) of the section. This is expressed using one of the + following forms: +

      +
    +

    n +

    +

    at the absolute +address specified by the unsigned integer n +

    +

    ALIGN ( +n ) +

    +

    following the +final location of the previous section with alignment to the next n +-byte boundary

    +
      +
    1. The initial address ( + LMA ) of the section. This is expressed using one of the + following forms: +

      +
    +

    LMA_EQ_VMA +

    +

    the LMA +equals the VMA (no relocation) +

    +

    AT ( +n ) +

    +

    at the absolute +address specified by the unsigned integer n +

    +

    FOLLOWING (. +name ) +

    +

    following the +initial location of section name +

    +

    +In order to maintain compatibility with linker script fragments and +header files exported by the eCos Configuration Tool, the use of +other expressions within these files is not recommended.

    +

    Note that the names of +the linker output sections will vary between target architectures. A +description of these sections can be found in the specific GNUPro +Toolkit Reference manual for your architecture.

    + + + + +
    +
    +

    + + + + + + + + +
    +

    Manual Configuration

    +
    +

    To + Contents

    +
    +

    To previous page

    +
    +

    To next page

    +


    +

    + + \ No newline at end of file diff --git a/host/tools/configtool/standalone/wxwin/manual/user-guides.14.html b/host/tools/configtool/standalone/wxwin/manual/user-guides.14.html new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/manual/user-guides.14.html @@ -0,0 +1,330 @@ + + + + + + Managing the Package Repository + +
    +

    Managing the Package Repository

    To Contents

    To previous page

    To next page

     




    +

    + + + + +Managing the + +Package Repository
    + +
    +

    +

    + + +A source distribution of eCos consists of a number of packages, such as the kernel, the C library, and the +ITRON subsystems. These are individually versioned in the tree structure of the source code, to support distribution on a per-package basis and to support third party packages whose versioning systems might be different. The +eCos + +Package Administration Tool + is used to manage the installation and removal of packages from a variety of sources with potentially multiple versions.

    +

    + + +The presence of the version information in the source tree structure might be a hindrance to the use of a separate source control system such as +CVS + or +SourceSafe + +™. + To work in this way, you can rename all the version components to some common name (such as "current") thus unifying the structure of source trees from distinct eCos releases.

    +

    + + +The eCos build system will treat any such name as just another version of the package(s), and support building in exactly the same way. However, performing this rename invalidates any existing build trees that referred to the versioned source tree, so do the rename first, before any other work, and do a complete rebuild afterwards.

    +
    +

    + + +Package Installation

    +

    + + +Package installation and removal is performed using the +eCos Package Adminstration Tool. + This tool is a Tcl script named +ecosadmin.tcl + which allows the user to add new eCos packages and new versions of existing packages to an eCos repository. Such packages must be distributed as a single file in the eCos package distribution format. Unwanted packages may also be removed from the repository using this tool. A graphical version of the tool is provided as part of the +eCos + +Developer's Kit. +

    +

    + + +Using the Administration Tool

    +

    + + +The graphical version of the +eCos Package Administration Tool, + provided as part of the +eCos Developer's Kit, + provides functions equivalent to the command-line version for those who prefer a Windows-based interface.

    +

    + + +It may be invoked in one of two ways:

    +
      +

    • + + +from the start menu (by default +StartProgramsRed Hat eCosPackage Administration Tool +)
    • +

    • + + +from the eCos + +Configuration Tool + +via the +ToolsAdministration + menu item
    • +
    +

    + + +

    +
    + +
    +

    + + +The main window of the tool displays the packages which are currently installed in the form of a tree. The installed versions of each package may be examined by expanding the tree.

    +

    + + +Packages may be added to the eCos repository by clicking on the +Add + button. The eCos package distribution file to be added is then selected via a +File Open + dialog box.

    +

    + + +Packages may be removed by selecting a package in the tree and then clicking on the +Remove + button. If a package node is selected, all versions of the selected package will be removed. If a package version node is selected, only the selected version of the package will be removed.

    +

    + + +Using the command line

    +

    + + +The +ecosadmin.tcl + script is located in the base of the eCos repository. Use a command of the following form under versions of UNIX:

    +
     
    +$ tclsh ecosadmin.tcl <command>
    +
    +

    + + +Under Windows, a command of the following form may be used at the Cygwin command line prompt:

    +
     
    +$ cygtclsh80 ecosadmin.tcl <command>
    +
    +

    + + +The following commands are available:

    +

    + + + +add <file> + + +

    +

    + + +Adds the packages contained with the specified package distribution file to the eCos repository and updates the package database accordingly. By convention, eCos package distribution files are given the +.epk + suffix.

    +

    + + + +remove <package> [ --version=<version> ] + + +

    +

    + + +Removes the specified package from the eCos repository and updates the package database accordingly. Where the optional version qualifier is used, only the specified version of the package is removed.

    +

    + + + +list + + +

    +

    + + +Produces a list of the packages which are currently installed and their versions. The available templates and hardware targets are also listed.

    +

    + + +Note that is is possible to remove critical packages such as the common HAL package using this tool. Users should take care to avoid such errors since core eCos packages may only be re-installed in the context of a complete re-installation of eCos.

    +
    +
    +

    + + +Package Structure

    +

    + + +The files in an installed eCos source tree are organized in a natural tree structure, grouping together files which work together into +Packages. + For example, the kernel files are all together in:

    +
     
    +BASE_DIR
    +/kernel/
    +v1_3_x
    +/include/
    +BASE_DIR
    +/kernel/
    +v1_3_x
    +/src/
    +BASE_DIR
    +/kernel/
    +v1_3_x
    +/tests/
    +	
    +

    + + +and +ITRON compatibility layer files are in:

    +
     
    +BASE_DIR
    +/compat/uitron/
    +v1_3_x
    +/include/
    +BASE_DIR
    +/compat/uitron/
    +v1_3_x
    +/src/
    +BASE_DIR
    +/compat/uitron/
    +v1_3_x
    +/tests/
    +	
    +

    + + +The feature of these names which is of interest here is the v1_3_x near the end. If you start using eCos after the Version 1.2 release, you might see a different name here, e.g. v1_4 for version 1.4; if you received pre-release Beta versions you might have seen v0_2 or v0_3 for versions 0.2 and 0.3.

    +

    + + +It may seem odd to place a version number deep in the path, rather than having something like +BASE_DIR + +/ + +v1_3_x + +/...everything... +

    +

    + + +or leaving it up to you to choose a different install-place when a new release of the system arrives.

    +

    + + +There is a rationale for this organization: as indicated, the kernel and the +ITRON compatibility subsystem are examples of software packages. For the first few releases of eCos, all the Red Hat packages will move along in step, i.e. Release 1.3.x will feature Version 1.3.x of every package, and so forth. But in future, especially when third party packages become available, it is intended that the package be the unit of software distribution, so it will be possible to build a system from a selection of packages with different version numbers, and even differing versioning +schemes. + A Tcl script +ecosadmin.tcl + is provided in the eCos repository to manage the installation and removal of packages in this way.

    +

    + + +Many users will have their own source code control system, version control system or equivalent, and will want to use it with eCos sources. In that case, since a new release of eCos comes with different pathnames for all the source files, a bit of work is necessary to import a new release into your source repository.

    +

    + + +One way of handling the import is to rename all the version parts to some common name, for example "current", and continue to work. "current" is suggested because +ecosconfig + recognizes it and places it first in any list of versions. In the future, Red Hat may provide a tool to help with this, or an option in the install wizard. Alternatively, in a POSIX shell environment (Linux or Cygwin on Windows) use the following command:

    +
     
    +find . -name 
    +v1_3_x
    + -type d -printf 'mv %p %h/current\n' | sh
    +
    +	
    +

    + + +Having carried out such a renaming operation, your source tree will now look like this:

    +
     
    +BASE_DIR
    +/kernel/current/include/
    +
    +BASE_DIR
    +/kernel/current/src/
    +
    +BASE_DIR
    +/kernel/current/tests/
    +
    +	...
    +BASE_DIR
    +/compat/uitron/current/include/
    +
    +BASE_DIR
    +/compat/uitron/current/src/
    +
    +BASE_DIR
    +/compat/uitron/current/tests/
    +
    +	
    +

    + + +which is a suitable format for import into your own source code control system. When you get a subsequent release of eCos, do the same thing and use your own source code control system to manage the new source base, by importing the new version from

    +
     
    +	NEW_BASE_DIR
    +/kernel/current/include/
    +	
    +

    + + +and so on.

    +

    + + +The eCos build tool will now offer only the "current" version of each package; select this for the packages you wish to use.

    +

    + + +Making such a change has implications for any build trees you already have in use. A configured build tree contains information about the selected packages and their selected versions. Changing the name of the "versioning" folder in the source tree invalidates this information, and in consequence it also invalidates any local configuration options you have set up in this build tree. So if you want to change the version information in the source tree, do it first, before investing any serious time in configuring and building your system. When you create a new build tree to deal with the new source layout, it will contain default settings for all the configuration options, just like the old build tree did before you configured it. You will need to redo that configuration work in the new tree.

    +

    + + +Moving source code around also invalidates debugging information in any programs or libraries built from the old tree; these will need to be rebuilt.

    +
    +

    Managing the Package Repository

    To Contents

    To previous page

    To next page

    + diff --git a/host/tools/configtool/standalone/wxwin/manual/user-guides.15.html b/host/tools/configtool/standalone/wxwin/manual/user-guides.15.html new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/manual/user-guides.15.html @@ -0,0 +1,28 @@ + + + + + + Part IV: Special Topics + + +

    + + +Part IV: Special Topics
    + +
    +

    +

    + + +

    + + + + +
    +
    +

    Part IV: Special Topics

    To Contents

    To previous page

    To next page

    + diff --git a/host/tools/configtool/standalone/wxwin/manual/user-guides.16.html b/host/tools/configtool/standalone/wxwin/manual/user-guides.16.html new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/manual/user-guides.16.html @@ -0,0 +1,879 @@ + + + + + + Real-time Characterization + +
    +

    Real-time Characterization

    To Contents

    To previous page

    To next page

     




    +

    + + + + +Real-time Characterization
    + +
    +

    +

    + + +When building a real-time system, care must be taken to ensure that the system will be able to perform properly within the constraints of that system. One of these constraints may be how fast certain operations can be performed. Another might be how deterministic the overall behavior of the system is. Lastly the memory footprint (size) and unit cost may be important.

    +

    + + +One of the major problems encountered while evaluating a system will be how to compare it with possible alternatives. Most manufacturers of real-time systems publish performance numbers, ostensibly so that users can compare the different offerings. However, what these numbers mean and how they were gathered is often not clear. The values are typically measured on a particular piece of hardware, so in order to truly compare, one must obtain measurements for exactly the same set of hardware that were gathered in a similar fashion.

    +

    + + +Two major items need to be present in any given set of measurements. First, the raw values for the various operations; these are typically quite easy to measure and will be available for most systems. Second, the determinacy of the numbers; in other words how much the value might change depending on other factors within the system. This value is affected by a number of factors: how long interrupts might be masked, whether or not the function can be interrupted, even very hardware-specific effects such as cache locality and pipeline usage. It is very difficult to measure the determinacy of any given operation, but that determinacy is fundamentally important to proper overall characterization of a system.

    +

    + + +In the discussion and numbers that follow, three key measurements are provided. The first measurement is an estimate of the interrupt latency: this is the length of time from when a hardware interrupt occurs until its + +Interrupt Service Routine (ISR) is called. The second measurement is an estimate of overall interrupt overhead: this is the length of time average interrupt processing takes, as measured by the real-time clock interrupt (other interrupt sources will certainly take a different amount of time, but this data cannot be easily gathered). The third measurement consists of the timings for the various kernel primitives.

    +
    +

    + + + + +Methodology

    +

    + + +Key operations in the kernel were measured by using a simple test program which exercises the various kernel primitive operations. A hardware timer, normally the one used to drive the real-time clock, was used for these measurements. In most cases this timer can be read with quite high resolution, typically in the range of a few microseconds. For each measurement, the operation was repeated a number of times. Time stamps were obtained directly before and after the operation was performed. The data gathered for the entire set of operations was then analyzed, generating average (mean), maximum and minimum values. The sample variance (a measure of how close most samples are to the mean) was also calculated. The cost of obtaining the real-time clock timer values was also measured, and was subtracted from all other times.

    +

    + + +Most + +kernel functions can be measured separately. In each case, a reasonable number of iterations are performed. Where the test case involves a kernel object, for example creating a task, each iteration is performed on a different object. There is also a set of tests which measures the interactions between multiple tasks and certain kernel primitives. Most functions are tested in such a way as to determine the variations introduced by varying numbers of objects in the system. For example, the mailbox tests measure the cost of a 'peek' operation when the mailbox is empty, has a single item, and has multiple items present. In this way, any effects of the state of the object or how many items it contains can be determined.

    +

    + + +There are a few things to consider about these measurements. Firstly, they are quite micro in scale and only measure the operation in question. These measurements do not adequately describe how the timings would be perturbed in a real system with multiple interrupting sources. Secondly, the possible aberration incurred by the real-time clock (system heartbeat tick) is explicitly avoided. Virtually all kernel functions have been designed to be interruptible. Thus the times presented are typical, but best case, since any particular function may be interrupted by the clock tick processing. This number is explicitly calculated so that the value may be included in any deadline calculations required by the end user. Lastly, the reported measurements were obtained from a system built with all options at their default values. Kernel instrumentation and asserts are also disabled for these measurements. Any number of configuration options can change the measured results, sometimes quite dramatically. For example, mutexes are using priority inheritance in these measurements. The numbers will change if the system is built with priority inheritance on mutex variables turned off.

    +

    + + +The final value that is measured is an estimate of interrupt latency. This particular value is not explicitly calculated in the test program used, but rather by instrumenting the kernel itself. The raw number of timer ticks that elapse between the time the timer generates an interrupt and the start of the timer ISR is kept in the kernel. These values are printed by the test program after all other operations have been tested. Thus this should be a reasonable estimate of the interrupt latency over time.

    +
    +
    +

    + + +Using these Measurements

    +

    + + +These measurements can be used in a number of ways. The most typical use will be to compare different real-time kernel offerings on similar hardware, another will be to estimate the cost of implementing a task using eCos (applications can be examined to see what effect the kernel operations will have on the total execution time). Another use would be to observe how the tuning of the kernel affects overall operation.

    +
    +
    +

    + + +Influences on + +Performance

    +

    + + +A number of factors can affect real-time performance in a system. One of the most common factors, yet most difficult to characterize, is the effect of device drivers and interrupts on system timings. Different device drivers will have differing requirements as to how long interrupts are suppressed, for example. The eCos system has been designed with this in mind, by separating the management of interrupts (ISR handlers) and the processing required by the interrupt ( + +DSR--Deferred Service Routine-- handlers). However, since there is so much variability here, and indeed most device drivers will come from the end users themselves, these effects cannot be reliably measured. Attempts have been made to measure the overhead of the single interrupt that eCos relies on, the real-time clock timer. This should give you a reasonable idea of the cost of executing interrupt handling for devices.

    +
    +
    +

    + + +Measured Items

    +

    + + +This section describes the various + +tests and the numbers presented. All tests use the C kernel API (available by way of +cyg/kernel/kapi.h +). There is a single main thread in the system that performs the various tests. Additional threads may be created as part of the testing, but these are short lived and are destroyed between tests unless otherwise noted. The terminology "lower priority" means a priority that is less important, not necessarily lower in numerical value. A higher priority thread will run in preference to a lower priority thread even though the priority value of the higher priority thread may be numerically less than that of the lower priority thread.

    +

    + + + + +Thread Primitives

    +

    + + +Create thread

    +

    + + +This test measures the +cyg_thread_create() + call. Each call creates a totally new thread. The set of threads created by this test will be reused in the subsequent thread primitive tests.

    +

    + + +Yield thread

    +

    + + +This test measures the +cyg_thread_yield() + call. For this test, there are no other runnable threads, thus the test should just measure the overhead of trying to give up the CPU.

    +

    + + +Suspend [suspended] thread

    +

    + + +This test measures the +cyg_thread_suspend() + call. A thread may be suspended multiple times; each thread is already suspended from its initial creation, and is suspended again.

    +

    + + +Resume thread

    +

    + + +This test measures the +cyg_thread_resume() + call. All of the threads have a suspend count of 2, thus this call does not make them runnable. This test just measures the overhead of resuming a thread.

    +

    + + +Set priority

    +

    + + +This test measures the +cyg_thread_set_priority() + call. Each thread, currently suspended, has its priority set to a new value.

    +

    + + +Get priority

    +

    + + +This test measures the +cyg_thread_get_priority() + call.

    +

    + + +Kill [suspended] thread

    +

    + + +This test measures the +cyg_thread_kill() + call. Each thread in the set is killed. All threads are known to be suspended before being killed.

    +

    + + +Yield [no other] thread

    +

    + + +This test measures the +cyg_thread_yield() + call again. This is to demonstrate that the +cyg_thread_yield() + call has a fixed overhead, regardless of whether there are other threads in the system.

    +

    + + +Resume [suspended low priority] thread

    +

    + + +This test measures the +cyg_thread_resume() + call again. In this case, the thread being resumed is lower priority than the main thread, thus it will simply become ready to run but not be granted the CPU. This test measures the cost of making a thread ready to run.

    +

    + + +Resume [runnable low priority] thread

    +

    + + +This test measures the +cyg_thread_resume() + call again. In this case, the thread being resumed is lower priority than the main thread and has already been made runnable, so in fact the resume call has no effect.

    +

    + + +Suspend [runnable] thread

    +

    + + +This test measures the +cyg_thread_suspend() + call again. In this case, each thread has already been made runnable (by previous tests).

    +

    + + +Yield [only low priority] thread

    +

    + + +This test measures the +cyg_thread_yield() + call. In this case, there are many other runnable threads, but they are all lower priority than the main thread, thus no thread switches will take place.

    +

    + + +Suspend [runnablenot runnable] thread

    +

    + + +This test measures the +cyg_thread_suspend() + call again. The thread being suspended will become non-runnable by this action.

    +

    + + +Kill [runnable] thread

    +

    + + +This test measures the +cyg_thread_kill() + call again. In this case, the thread being killed is currently runnable, but lower priority than the main thread.

    +

    + + +Resume [high priority] thread

    +

    + + +This test measures the +cyg_thread_resume() + call. The thread being resumed is higher priority than the main thread, thus a thread switch will take place on each call. In fact there will be two thread switches; one to the new higher priority thread and a second back to the test thread. The test thread exits immediately.

    +

    + + +Thread switch

    +

    + + +This test attempts to measure the cost of switching from one thread to another. Two equal priority threads are started and they will each yield to the other for a number of iterations. A time stamp is gathered in one thread before the +cyg_thread_yield() + call and after the call in the other thread.

    +

    + + + + +Scheduler Primitives

    +

    + + +Scheduler lock

    +

    + + +This test measures the +cyg_scheduler_lock() + call.

    +

    + + +Scheduler unlock [0 threads]

    +

    + + +This test measures the +cyg_scheduler_unlock() + call. There are no other threads in the system and the unlock happens immediately after a lock so there will be no pending DSR's to run.

    +

    + + +Scheduler unlock [1 suspended thread]

    +

    + + +This test measures the +cyg_scheduler_unlock() + call. There is one other thread in the system which is currently suspended.

    +

    + + +Scheduler unlock [many suspended threads]

    +

    + + +This test measures the +cyg_scheduler_unlock() + call. There are many other threads in the system which are currently suspended. The purpose of this test is to determine the cost of having additional threads in the system when the scheduler is activated by way of +cyg_scheduler_unlock() +.

    +

    + + +Scheduler unlock [many low priority threads]

    +

    + + +This test measures the +cyg_scheduler_unlock() + call. There are many other threads in the system which are runnable but are lower priority than the main thread. The purpose of this test is to determine the cost of having additional threads in the system when the scheduler is activated by way of +cyg_scheduler_unlock() +.

    +

    + + + + +Mutex Primitives

    +

    + + +Init mutex

    +

    + + +This test measures the +cyg_mutex_init() + call. A number of separate mutex variables are created. The purpose of this test is to measure the cost of creating a new mutex and introducing it to the system.

    +

    + + +Lock [unlocked] mutex

    +

    + + +This test measures the +cyg_mutex_lock() + call. The purpose of this test is to measure the cost of locking a mutex which is currently unlocked. There are no other threads executing in the system while this test runs.

    +

    + + +Unlock [locked] mutex

    +

    + + +This test measures the +cyg_mutex_unlock() + call. The purpose of this test is to measure the cost of unlocking a mutex which is currently locked. There are no other threads executing in the system while this test runs.

    +

    + + +

    +

    + + +Trylock [unlocked] mutex

    +

    + + +This test measures the +cyg_mutex_trylock() + call. The purpose of this test is to measure the cost of locking a mutex which is currently unlocked. There are no other threads executing in the system while this test runs.

    +

    + + +Trylock [locked] mutex

    +

    + + +This test measures the +cyg_mutex_trylock() + call. The purpose of this test is to measure the cost of locking a mutex which is currently locked. There are no other threads executing in the system while this test runs.

    +

    + + +Destroy mutex

    +

    + + +This test measures the +cyg_mutex_destroy() + call. The purpose of this test is to measure the cost of deleting a mutex from the system. There are no other threads executing in the system while this test runs.

    +

    + + +Unlock/Lock mutex

    +

    + + +This test attempts to measure the cost of unlocking a mutex for which there is another higher priority thread waiting. When the mutex is unlocked, the higher priority waiting thread will immediately take the lock. The time from when the unlock is issued until after the lock succeeds in the second thread is measured, thus giving the round-trip or circuit time for this type of synchronizer.

    +

    + + + + +Mailbox Primitives

    +

    + + +Create mbox

    +

    + + +This test measures the +cyg_mbox_create() + call. A number of separate mailboxes is created. The purpose of this test is to measure the cost of creating a new mailbox and introducing it to the system.

    +

    + + +Peek [empty] mbox

    +

    + + +This test measures the +cyg_mbox_peek() + call. An attempt is made to peek the value in each mailbox, which is currently empty. The purpose of this test is to measure the cost of checking a mailbox for a value without blocking.

    +

    + + +Put [first] mbox

    +

    + + +This test measures the +cyg_mbox_put() + call. One item is added to a currently empty mailbox. The purpose of this test is to measure the cost of adding an item to a mailbox. There are no other threads currently waiting for mailbox items to arrive.

    +

    + + +Peek [1 msg] mbox

    +

    + + +This test measures the +cyg_mbox_peek() + call. An attempt is made to peek the value in each mailbox, which contains a single item. The purpose of this test is to measure the cost of checking a mailbox which has data to deliver.

    +

    + + +Put [second] mbox

    +

    + + +This test measures the +cyg_mbox_put() + call. A second item is added to a mailbox. The purpose of this test is to measure the cost of adding an additional item to a mailbox. There are no other threads currently waiting for mailbox items to arrive.

    +

    + + +Peek [2 msgs] mbox

    +

    + + +This test measures the +cyg_mbox_peek() + call. An attempt is made to peek the value in each mailbox, which contains two items. The purpose of this test is to measure the cost of checking a mailbox which has data to deliver.

    +

    + + +Get [first] mbox

    +

    + + +This test measures the +cyg_mbox_get() + call. The first item is removed from a mailbox that currently contains two items. The purpose of this test is to measure the cost of obtaining an item from a mailbox without blocking.

    +

    + + +Get [second] mbox

    +

    + + +This test measures the +cyg_mbox_get() + call. The last item is removed from a mailbox that currently contains one item. The purpose of this test is to measure the cost of obtaining an item from a mailbox without blocking.

    +

    + + +Tryput [first] mbox

    +

    + + +This test measures the +cyg_mbox_tryput() + call. A single item is added to a currently empty mailbox. The purpose of this test is to measure the cost of adding an item to a mailbox.

    +

    + + +Peek item [non-empty] mbox

    +

    + + +This test measures the +cyg_mbox_peek_item() + call. A single item is fetched from a mailbox that contains a single item. The purpose of this test is to measure the cost of obtaining an item without disturbing the mailbox.

    +

    + + +Tryget [non-empty] mbox

    +

    + + +This test measures the +cyg_mbox_tryget() + call. A single item is removed from a mailbox that contains exactly one item. The purpose of this test is to measure the cost of obtaining one item from a non-empty mailbox.

    +

    + + +Peek item [empty] mbox

    +

    + + +This test measures the +cyg_mbox_peek_item() + call. An attempt is made to fetch an item from a mailbox that is empty. The purpose of this test is to measure the cost of trying to obtain an item when the mailbox is empty.

    +

    + + +Tryget [empty] mbox

    +

    + + +This test measures the +cyg_mbox_tryget() + call. An attempt is made to fetch an item from a mailbox that is empty. The purpose of this test is to measure the cost of trying to obtain an item when the mailbox is empty.

    +

    + + +Waiting to get mbox

    +

    + + +This test measures the +cyg_mbox_waiting_to_get() + call. The purpose of this test is to measure the cost of determining how many threads are waiting to obtain a message from this mailbox.

    +

    + + +Waiting to put mbox

    +

    + + +This test measures the +cyg_mbox_waiting_to_put() + call. The purpose of this test is to measure the cost of determining how many threads are waiting to put a message into this mailbox.

    +

    + + +Delete mbox

    +

    + + +This test measures the +cyg_mbox_delete() + call. The purpose of this test is to measure the cost of destroying a mailbox and removing it from the system.

    +

    + + +Put/Get mbox

    +

    + + +In this round-trip test, one thread is sending data to a mailbox that is being consumed by another thread. The time from when the data is put into the mailbox until it has been delivered to the waiting thread is measured. Note that this time will contain a thread switch.

    +

    + + + + +Semaphore Primitives

    +

    + + +Init semaphore

    +

    + + +This test measures the +cyg_semaphore_init() + call. A number of separate semaphore objects are created and introduced to the system. The purpose of this test is to measure the cost of creating a new semaphore.

    +

    + + +Post [0] semaphore

    +

    + + +This test measures the +cyg_semaphore_post() + call. Each semaphore currently has a value of 0 and there are no other threads in the system. The purpose of this test is to measure the overhead cost of posting to a semaphore. This cost will differ if there is a thread waiting for the semaphore.

    +

    + + +Wait [1] semaphore

    +

    + + +This test measures the +cyg_semaphore_wait() + call. The semaphore has a current value of 1 so the call is non-blocking. The purpose of the test is to measure the overhead of "taking" a semaphore.

    +

    + + +Trywait [0] semaphore

    +

    + + +This test measures the +cyg_semaphore_trywait() + call. The semaphore has a value of 0 when the call is made. The purpose of this test is to measure the cost of seeing if a semaphore can be "taken" without blocking. In this case, the answer would be no.

    +

    + + +

    +

    + + +Trywait [1] semaphore

    +

    + + +This test measures the +cyg_semaphore_trywait() + call. The semaphore has a value of 1 when the call is made. The purpose of this test is to measure the cost of seeing if a semaphore can be "taken" without blocking. In this case, the answer would be yes.

    +

    + + +Peek semaphore

    +

    + + +This test measures the +cyg_semaphore_peek() + call. The purpose of this test is to measure the cost of obtaining the current semaphore count value.

    +

    + + +Destroy semaphore

    +

    + + +This test measures the +cyg_semaphore_destroy() + call. The purpose of this test is to measure the cost of deleting a semaphore from the system.

    +

    + + +Post/Wait semaphore

    +

    + + +In this round-trip test, two threads are passing control back and forth by using a semaphore. The time from when one thread calls +cyg_semaphore_post() + until the other thread completes its +cyg_semaphore_wait() + is measured. Note that each iteration of this test will involve a thread switch.

    +

    + + + + +Counters

    +

    + + +Create counter

    +

    + + +This test measures the +cyg_counter_create() + call. A number of separate counters are created. The purpose of this test is to measure the cost of creating a new counter and introducing it to the system.

    +

    + + +Get counter value

    +

    + + +This test measures the +cyg_counter_current_value() + call. The current value of each counter is obtained.

    +

    + + +Set counter value

    +

    + + +This test measures the +cyg_counter_set_value() + call. Each counter is set to a new value.

    +

    + + +Tick counter

    +

    + + +This test measures the +cyg_counter_tick() + call. Each counter is "ticked" once.

    +

    + + +Delete counter

    +

    + + +This test measures the +cyg_counter_delete() + call. Each counter is deleted from the system. The purpose of this test is to measure the cost of deleting a counter object.

    +

    + + + + +Alarms

    +

    + + +Create alarm

    +

    + + +This test measures the +cyg_alarm_create() + call. A number of separate alarms are created, all attached to the same counter object. The purpose of this test is to measure the cost of creating a new counter and introducing it to the system.

    +

    + + +Initialize alarm

    +

    + + +This test measures the +cyg_alarm_initialize() + call. Each alarm is initialized to a small value.

    +

    + + +Disable alarm

    +

    + + +This test measures the +cyg_alarm_disable() + call. Each alarm is explicitly disabled.

    +

    + + +Enable alarm

    +

    + + +This test measures the +cyg_alarm_enable() + call. Each alarm is explicitly enabled.

    +

    + + +Delete alarm

    +

    + + +This test measures the +cyg_alarm_delete() + call. Each alarm is destroyed. The purpose of this test is to measure the cost of deleting an alarm and removing it from the system.

    +

    + + +Tick counter [1 alarm]

    +

    + + +This test measures the +cyg_counter_tick() + call. A counter is created that has a single alarm attached to it. The purpose of this test is to measure the cost of "ticking" a counter when it has a single attached alarm. In this test, the alarm is not activated (fired).

    +

    + + +Tick counter [many alarms]

    +

    + + +This test measures the +cyg_counter_tick() + call. A counter is created that has multiple alarms attached to it. The purpose of this test is to measure the cost of "ticking" a counter when it has many attached alarms. In this test, the alarms are not activated (fired).

    +

    + + +Tick & fire counter [1 alarm]

    +

    + + +This test measures the +cyg_counter_tick() + call. A counter is created that has a single alarm attached to it. The purpose of this test is to measure the cost of "ticking" a counter when it has a single attached alarm. In this test, the alarm is activated (fired). Thus the measured time will include the overhead of calling the alarm callback function.

    +

    + + +Tick & fire counter [many alarms]

    +

    + + +This test measures the +cyg_counter_tick() + call. A counter is created that has multiple alarms attached to it. The purpose of this test is to measure the cost of "ticking" a counter when it has many attached alarms. In this test, the alarms are activated (fired). Thus the measured time will include the overhead of calling the alarm callback function.

    +

    + + +Alarm latency [0 threads]

    +

    + + +This test attempts to measure the latency in calling an alarm callback function. The time from the clock interrupt until the alarm function is called is measured. In this test, there are no threads that can be run, other than the system idle thread, when the clock interrupt occurs (all threads are suspended).

    +

    + + +Alarm latency [2 threads]

    +

    + + +This test attempts to measure the latency in calling an alarm callback function. The time from the clock interrupt until the alarm function is called is measured. In this test, there are exactly two threads which are running when the clock interrupt occurs. They are simply passing back and forth by way of the +cyg_thread_yield() + call. The purpose of this test is to measure the variations in the latency when there are executing threads.

    +

    + + +Alarm latency [many threads]

    +

    + + +This test attempts to measure the latency in calling an alarm callback function. The time from the clock interrupt until the alarm function is called is measured. In this test, there are a number of threads which are running when the clock interrupt occurs. They are simply passing back and forth by way of the +cyg_thread_yield() + call. The purpose of this test is to measure the variations in the latency when there are many executing threads.

    +
    +
    +

    + + + + +Sample Numbers

    +

    + + +For sample results, see Appendix 1 of +Getting Started with eCos +

    +
     
    +
    +

    + + +

    +

    + +
    +Index
    +

    +
    +

    Real-time Characterization

    To Contents

    To previous page

    To next page

    + diff --git a/host/tools/configtool/standalone/wxwin/manual/user-guides.17.html b/host/tools/configtool/standalone/wxwin/manual/user-guides.17.html new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/manual/user-guides.17.html @@ -0,0 +1,945 @@ + + + + + + Index + + +

    + + +
    +Index
    + +
    +

    +

    + + +A + + + +

    +

    + + + +application build tree +

    +

    + + +B + +

    +

    + + + +Build and Install Trees +

    +

    + + + +build tools +

    +

    + + + +build tree +

    +

    + + + +application +

    +

    + + + +creating manually +

    +

    + + + +build tree (application) +

    +

    + + + + +building + +

    +

    + + + +building eCos +

    +

    + + +C + +

    +

    + + + +compiler options +

    +

    + + +compiling

    +

    + + + +C applications +

    +

    + + + +C++ applications +

    +

    + + + +Component Repository +

    +

    + + + + + +component repository + + +

    +

    + + +configuration

    +

    + + + +coarse-grained +

    +

    + + + +fine-grained +

    +

    + + + +updating +

    +

    + + + +configuration item integer format +

    +

    + + + +configuration item labels +

    +

    + + +Configuration Tool

    +

    + + + +documents +

    +

    + + + +Getting Started +

    +

    + + + +Introduction +

    +

    + + + +invoking +

    +

    + + + +keyboard accelerators +

    +

    + + + +configuration window +

    +

    + + + +conflicts +

    +

    + + + +conflicts window +

    +

    + + + +connection +

    +

    + + + +customization +

    +

    + + +D + +

    +

    + + + +debugging +

    +

    + + + +Deferred Service Routine (DSR) +

    +

    + + + +download timeout +

    +

    + + +E + +

    +

    + + +eCos

    +

    + + + +sources, editing +

    +

    + + + +ecosconfig +

    +

    + + + +ecosconfig commands +

    +

    + + + +ecosconfig qualifiers +

    +

    + + + +event record +

    +

    + + +events

    +

    + + + +monitoring +

    +

    + + +example programs

    +

    + + + +accessing a user-defined memory section +

    +

    + + + +eCos linker script fragment +

    +

    + + + +hello world with tracing +

    +

    + + + +instrument buffer output +

    +

    + + + +using instrument buffers +

    +

    + + + +executables tab +

    +

    + + + +execution +

    +

    + + +F + +

    +

    + + + +fonts +

    +

    + + +H + + + +

    +

    + + + +Hardware Abstraction Layer (HAL) +

    +

    + + + +Help +

    +

    + + +I + +

    +

    + + + +install tree +

    +

    + + + +tests subdirectory +

    +

    + + + + +instrumentation buffers + +

    +

    + + + +Interrupt Service Routine (ISR) +

    +

    + + +K + + + +

    +

    + + + +kernel instrumentation buffers +

    +

    + + + +keyboard accelerators +

    +

    + + +L + +

    +

    + + +linker scripts

    +

    + + + +editing +

    +

    + + + +example linker script fragment +

    +

    + + + +target.ld +

    +

    + + +M + +

    +

    + + +measuring

    +

    + + + +kernel functions +

    +

    + + + +methodology +

    +

    + + + +sample numbers +

    +

    + + + +system performance +

    +

    + + + +tests peformed +

    +

    + + +memory

    +

    + + +layout

    +

    + + + +modifying +

    +

    + + + +memory access +

    +

    + + + +memory layout window +

    +

    + + + +memory regions +

    +

    + + + +memory sections +

    +

    + + +monitoring

    +

    + + + +events +

    +

    + + +O + + + + + +

    +

    + + + +output tab +

    +

    + + + +output window +

    +

    + + +P + +

    +

    + + + +package repository +

    +

    + + + +packages +

    +

    + + + +adding and removing +

    +

    + + +performance

    +

    + + + +sample numbers +

    +

    + + +system

    +

    + + + +influences on +

    +

    + + + +measuring +

    +

    + + + +tests performed +

    +

    + + + + +pkgconf.tcl + +

    +

    + + + + +--builddir + +

    +

    + + + +--defaults +

    +

    + + + +--disable +

    +

    + + + +--enable +

    +

    + + + +--help +

    +

    + + + +--packages +

    +

    + + + +--platform +

    +

    + + + +--prefix +

    +

    + + + +--srcdir +

    +

    + + + + +--target, --targets + +

    +

    + + +-- +-version + + +

    +

    + + + +properties (connectivity) +

    +

    + + + +properties window +

    +

    + + +R + + + +

    +

    + + + +real-time characterization +

    +

    + + + +run time timeout +

    +

    + + + +running tests +

    +

    + + +S + +

    +

    + + + +Save File +

    +

    + + + +screen layout +

    +

    + + + +searching +

    +

    + + +selective linking

    +

    + + + +g++ +

    +

    + + + +gcc +

    +

    + + +shell

    +

    + + + +creating +

    +

    + + + +short description window +

    +

    + + + +summary tab +

    +

    + + +system performance

    +

    + + + +influences on +

    +

    + + + +measuring +

    +

    + + + +sample numbers +

    +

    + + + +tests performed +

    +

    + + +T + +

    +

    + + + +templates +

    +

    + + + +test execution +

    +

    + + +tests

    +

    + + + +alarms +

    +

    + + + +counters +

    +

    + + + +mailbox primitives +

    +

    + + + +mutex primitives +

    +

    + + + +scheduler primitives +

    +

    + + + +semaphore primitives +

    +

    + + + +thread primitives +

    +

    + + + +Toolbars +

    +

    + + + +tracing +

    +

    + + +U + +

    +

    + + + +updating configuration +

    +

    + + + +user tools +

    +

    + + +W + + + +

    +

    + + + +window placement +

    +

    Index

    To Contents

    To previous page

    + diff --git a/host/tools/configtool/standalone/wxwin/manual/user-guides.2.html b/host/tools/configtool/standalone/wxwin/manual/user-guides.2.html new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/manual/user-guides.2.html @@ -0,0 +1,457 @@ + + + + + + Contents + + +

    + + +Contents
    + +
    +

    +

    + + + +eCos + +™ +User's Guide +

    +

    + + + +Copying terms + +

    +

    + + + +Trademarks + +

    +

    + + + +Part I: The eCos Configuration Tool +

    +

    + + + +Getting Started + +

    +

    + + + +Introduction + +

    +

    + + + +Invoking the eCos Configuration Tool + +

    +

    + + + +The Component Repository + +

    +

    + + + +eCos Configuration Tool Documents + +

    +

    + + + +Getting Help + +

    +

    + + + +Context-sensitive Help for Dialogs + +

    +

    + + + +Context-sensitive Help for Other Windows + +

    +

    + + + +Context-sensitive Help for Configuration Items + +

    +

    + + + +Methods of Displaying HTML Help + +

    +

    + + + +Customization + +

    +

    + + + +Screen Layout + +

    +

    + + + +Updating the Configuration + +

    +

    + + + +Adding and Removing Packages + +

    +

    + + + +Platform Selection + +

    +

    + + + +Using Templates + +

    +

    + + + +Searching + +

    +

    + + + +Building + +

    +

    + + + +Selecting Build Tools + +

    +

    + + + +Selecting User Tools + +

    +

    + + + +Execution + +

    +

    + + + +Properties + +

    +

    + + + +Creating a Shell + +

    +

    + + + +Keyboard Accelerators + +

    +

    + + + +Part II: eCos Programming Concepts and Techniques +

    +

    + + + +CDL Concepts + +

    +

    + + + +The Component Repository and Working Directories + +

    +

    + + + +Component Repository + +

    +

    + + + +Build Tree + +

    +

    + + + +Install Tree + +

    +

    + + + +Application Build Tree + +

    +

    + + + +Compiler and Linker Options + +

    +

    + + + +Compiling a C Application + +

    +

    + + + +Compiling a C++ Application + +

    +

    + + + +Debugging Techniques + +

    +

    + + + +Tracing + +

    +

    + + + +Kernel Instrumentation + +

    +

    + + + +Part III: Configuration and the Package Repository +

    +

    + + + +Manual Configuration + +

    +

    + + + +Directory Tree Structure + +

    +

    + + + +Creating the Build Tree + +

    +

    + + + +Building the System + +

    +

    + + + +Packages + +

    +

    + + + +Coarse-grained Configuration + +

    +

    + + + +Fine-grained Configuration + +

    +

    + + + +Editing an eCos Savefile + +

    +

    + + + +Editing the Sources + +

    +

    + + + +Modifying the Memory Layout + +

    +

    + + + +Managing the Package Repository + +

    +

    + + + +Package Installation + +

    +

    + + + +Package Structure + +

    +

    + + + +Part IV: Special Topics +

    +

    + + + +Real-time Characterization + +

    +

    + + + +Methodology + +

    +

    + + + +Using these Measurements + +

    +

    + + + +Influences on Performance + +

    +

    + + + +Measured Items + +

    +

    + + + +Sample Numbers + +

    +

    + + + +
    +Index
    +

    +

    Contents

    To Contents

    To previous page

    To next page

    + diff --git a/host/tools/configtool/standalone/wxwin/manual/user-guides.3.html b/host/tools/configtool/standalone/wxwin/manual/user-guides.3.html new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/manual/user-guides.3.html @@ -0,0 +1,24 @@ + + + + + + Part I: The eCos Configuration Tool + +
    +

    Part I: The eCos Configuration Tool

    To Contents

    To previous page

    To next page

     




    +

    + + +Part I: The eCos Configuration Tool
    + +
    +

    + + + + +
    +
    +

    Part I: The eCos Configuration Tool

    To Contents

    To previous page

    To next page

    + diff --git a/host/tools/configtool/standalone/wxwin/manual/user-guides.4.html b/host/tools/configtool/standalone/wxwin/manual/user-guides.4.html new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/manual/user-guides.4.html @@ -0,0 +1,254 @@ + + + + Getting Started + + + + + + + +

    + + + + + + + + +
    +

    Getting Started

    +
    +

    To + Contents

    +
    +

    To previous page

    +
    +

    To next page

    +
     

    +



    +

    +
    +

    +Getting Started

    +

    +

    +

    +Introduction

    +

    The eCos Configuration +Tool is used to tailor eCos at source level, prior to compilation or +assembly, and provides a configuration file and a set of files used +to build user applications. The sources and other files used for +building a configuration are provided in a component +repository, which is loaded when the eCos Configuration Tool is +invoked. The component repository includes a set of files defining +the structure of relationships between the Configuration Tool and +other components, and is written in a Component +Definition Language (CDL). For a description of the concepts +underlying component configuration, see CDL +Concepts .

    +

    The Configuration Tool runs on both Linux and MS +Windows, adopting the appropriate look and feel on each platform. +There are some minor differences in look and feel, and sometimes +functionality, between the Linux and the MS Windows versions. Where +these differences are significant, they will be described, but +generally screenshots are provided for one platform only.

    +

    +Invoking the eCos Configuration Tool

    +

    On Linux

    +

    Add the eCos Configuration Tool install directory to your PATH, +for example:

    +

    export PATH=/opt/ecos/ecos1.5.0/bin:$PATH

    +

    You may run configtool with zero, one or two arguments. You can +specify the eCos repository location, and/or an eCos save file +(extension .ecc) on the command line. The ordering of these two +arguments is not significant. For example:

    +

    configtool /opt/ecos/ecos1.5.0/packages myfile.ecc

    +

    The Configuration Tool will be displayed (see Figure 1 below).

    +

    On Windows

    +

    There are two ways in +which to invoke the eCos Configuration Tool:

    +
      +
    • from the desktop explorer or + program set up at installation time (by default Start + + Programs + + Red Hat eCos + + Configuration Tool ). +

      +
    • type + (at a command prompt or in the Start menu's Run item): + <foldername>\ConfigTool.exe where <foldername> is the + full path of the directory in which you installed the eCos + Configuration Tool. The Configuration Tool will be displayed (see + Figure 1 below).

      +
    +

    You may run configtool with zero, one or two arguments. You can +specify the eCos repository location, and/or an eCos save file +(extension .ecc) on the command line. The ordering of these two +arguments is not significant. For example:

    +

    configtool "c:\Program Files\Red Hat\eCos\packages" +myfile.ecc

    +

    Figure 1: Configuration Tool

    +




    +

    +

    +The Component Repository

    +

    When you invoke the eCos +Configuration Tool, it accesses the Component Repository, a read-only +location of configuration information. For an explanation of +"Component Repository" see CDL +Concepts .

    +

    The eCos Configuration +Tool will look for a component repository using (in descending order +of preference):

    +
      +
    • A location specified on the command line

      +
    • The component repository most + recently used by the current user +

      +
    • An eCos distribution under /opt/ecos (under Linux) or a + default location set by the installation procedure (under MS + Windows)

      +
    • User input +

      +
    +

    The final case above will +normally only occur if the previous repository has been moved or +(under Windows) installation information stored in the NT registry +has been modified; it will result in a dialog box being displayed +that allows you to specify the repository location:

    +

    Repository +relocation dialog box +

    +

    +

    +

    Note that in order to use +the eCos Configuration Tool you are obliged to provide a valid +repository location. +

    +

    In the rare event that +you subsequently wish to change the component location, select Build + +Repository and the above dialog box will then be displayed.

    +

    +eCos Configuration Tool Documents

    +

    +Configuration Save File

    +

    eCos configuration +settings and other information (such as disabled conflicts) that are +set using the eCos Configuration Tool are saved to a file between +sessions. By default, when the eCos Configuration Tool is first +invoked, it reads and displays information from the Component +Registry and displays the information in an untitled blank document. +You can perform the following operations on a document:

    +

    Save the currently +active document +

    +

    Use the " FileSave +" menu item or click the Save Document icon on the toolbar; if +the current document is unnamed, you will be prompted to supply a +name for the configuration save file.

    +

    Save As dialog box +

    +

    +

    +

    Open an existing +document

    +

    Select File + +Open, or click the Open Document icon on the toolbar. You will be +prompted to supply a name for the configuration save file. +

    +

    Open dialog box +

    +

    +

    +

    Open a document you +have used recently

    +

    Click its name at the +bottom of the File menu. +

    +

    Documents may also be +opened by:

    +
      +
    • double-clicking a Configuration + Save File in the desktop explorer (MS Windows only)

      +
    • invoking the eCos Configuration + Tool with the name of a Configuration File as command-line argument, + or (under MS Windows) by creating a shortcut to the eCos + Configuration Tool with such an argument. +

      +
    +

    Create a new blank +document based on the Component Registry

    +

    Select File + +New, or click the New Document icon on the toolbar.

    +

    Save to a different +file name

    +

    Select File + +Save As. You will be prompted to supply a new name for the +configuration save file.

    +

    +Build and Install Trees

    +

    The location of the build +and install trees are derived from the eCos save file name as +illustrated in the following example using MS Windows filename +conventions:

    +

    Save file name = "c:\My +eCos\config1.ecc"

    +

    Install tree folder = +"c:\My eCos\config1_install"

    +

    Build tree folder = +"c:\My eCos\config1_build"

    +

    These names are +automatically generated from the name of the save file.

    +

    See also CDL +Concepts .

    + + + + +
    +
    +

    + + + + + + + + +
    +

    Getting Started

    +
    +

    To + Contents

    +
    +

    To previous page

    +
    +

    To next page

    +


    +

    + + \ No newline at end of file diff --git a/host/tools/configtool/standalone/wxwin/manual/user-guides.5.html b/host/tools/configtool/standalone/wxwin/manual/user-guides.5.html new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/manual/user-guides.5.html @@ -0,0 +1,141 @@ + + + + Getting Help + + + + + + + +

    + + + + + + + + +
    +

    Getting Help

    +
    +

    To + Contents

    +
    +

    To previous page

    +
    +

    To next page

    +
     

    +



    +

    +
    +

    +Getting Help

    +

    +

    +

    The eCos Configuration +Tool contains several methods for accessing online help.

    +

    +Context-sensitive Help for Dialogs

    +

    Most dialogs displayed by +the eCos Configuration Tool are supplied with context-sensitive help. +You can then get help relating to any control within the current +dialog box by

    +
      +
    • pressing F1

      +
    +

    A brief description of the function of the +selected control will be displayed.

    +
      +
    • Clicking the help (question mark) + button on the dialog (Linux) or in the dialog caption bar (Windows)

      +
    +

    A question mark +cursor will be displayed. Click on any control to display a brief +description of its function.

    +

    Some dialogs may have a +Help button. You can press this to display a more general description +of the function of the dialog box as a whole. This help will be in +HTML form; for more information, see below.

    +

    +Context-sensitive Help for Other Windows

    +

    In the Help menu, click +eCos Configuration Tool Help (or press F1 ). A HTML page describing +the general operation of the currently active window will be +displayed. This help will normally be in HTML format; for more +information, see " +Methods of Displaying HTML Help ".

    +

    +Context-sensitive Help for Configuration Items

    +

    In the configuration +window, right-click on a configuration item. A context menu will be +displayed; select Visit Documentation to display the page in the eCos +documentation that most closely corresponds to the selected item.

    +

    +Methods of Displaying HTML Help

    +

    There are three ways of displaying help, configured +by clicking on the Viewers tab of the Settings dialog.

    +
      +
    1. Using the internal help system. This will show + an internal viewer similar to Microsoft HTML Help, with a contents + hierarchy on the left and HTML pages on the right. The index is + regenerated for each repository. If the documentation in the + repository has changed but the contents does not reflect this, + please use the Tools + + Regenerate Help Index menu item.

      +
    2. Using the default HTML browser. On Unix, you + will need a .mailcap entry similar to this:

      +

      text/html; netscape -no-about-splash %s

      +
    3. Using the specified browser.

      +
    + + + + +
    +

    +
    +
    +

    + + + + + + + + +
    +

    Getting Help

    +
    +

    To + Contents

    +
    +

    To previous page

    +
    +

    To next page

    +


    +

    + + \ No newline at end of file diff --git a/host/tools/configtool/standalone/wxwin/manual/user-guides.6.html b/host/tools/configtool/standalone/wxwin/manual/user-guides.6.html new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/manual/user-guides.6.html @@ -0,0 +1,155 @@ + + + + Customization + + + + + + + +

    + + + + + + + + +
    +

    Customization

    +
    +

    To + Contents

    +
    +

    To previous page

    +
    +

    To next page

    +
     

    +



    +

    +
    +

    +Customization

    +

    +

    +

    The following visual +aspects of the eCos Configuration Tool can be changed to suit +individual preferences. These aspects are saved on a per-user basis, +so that when the eCos Configuration Tool is next invoked by the same +user, the appearance will be as set in the previous session.

    +

    +Window Placement

    +

    The relative sizes of all +windows in the eCos Configuration Tool may be adjusted by dragging +the splitter bars that separate the windows. The chosen sizes will be +used the next time the eCos Configuration Tool is invoked by the +current user. +

    +

    All windows except the +Configuration Window may be shown or hidden by using the commands +under the View menu (for example, ViewOutput +) or the corresponding keyboard accelerators ( Alt+1 to Alt+5 ). By +default the conflicts window is hidden.

    +

    Your chosen set of +windows (and their relative sizes) will be preserved between +invocations of the eCos Configuration Tool.

    +

    +Toolbar

    +

    Select View + +Toolbar to toggle the toolbar on and off.

    +

    +Settings

    +

    To change other visual +aspects, select View + +Settings and then select the Display and View tabs depending on the +settings you wish to alter. The options are as follows:

    +

    Settings: Display tab

    +
    +
    Labels +
    + In the configuration window, you can + choose to have either descriptive names + (the default) or macro names displayed as + tree item labels. Descriptive names are generally more + comprehensible, but macro names are used in some contexts such as + conflict resolution and may be directly related to the source code + of the configuration. Note that it is possible to search for an item + in the configuration view by selecting Edit + + Find (see Searching + ). +
    + Integer items +
    + You can choose to have integer items in the Configuration Window + displayed in decimal or hexadecimal format. +
    + Font +
    + Change the font for a particular window by selecting the window name + using the drop-down list, then clicking on Change Font to select a + font for that window. The changes will be applied when the press OK + to dismiss the Settings dialog. If you never make font changes, then + the windows will take the default setting determined by your current + Windows or Unix environment. +
    + Miscellaneous +
    + If the Splash Screen checkbox is checked, a 'splash' window will + appear as the application is loading. Uncheck this to eliminate the + splash screen +
    +

    +Settings: Viewers tab

    +
    +
    View header files +
    + You can change the viewer used to display header files. +
    + View documentation +
    + You can change the viewer used to display HTML files. +
    + + + + +
    +
    +

    + + + + + + + + +
    +

    Customization

    +
    +

    To + Contents

    +
    +

    To previous page

    +
    +

    To next page

    +


    +

    + + \ No newline at end of file diff --git a/host/tools/configtool/standalone/wxwin/manual/user-guides.7.html b/host/tools/configtool/standalone/wxwin/manual/user-guides.7.html new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/manual/user-guides.7.html @@ -0,0 +1,283 @@ + + + + Screen Layout + + + + + + + +

    + + + + + + + + +
    +

    Screen Layout

    +
    +

    To + Contents

    +
    +

    To previous page

    +
    +

    To next page

    +
     

    +



    +

    +
    +

    +Screen Layout

    +

    +

    +

    The following windows are +available within the eCos Configuration Tool:

    +
      +
    • Configuration Window +

      +
    • Properties Window +

      +
    • Short Description +

      +
    • Conflicts +

      +
    • Output +

      +
    +

    The layout of the windows +my be adjusted to suit your preferences: see Settings +.

    +

    +Configuration Window

    +

    This is the principal +window used to configure eCos. It takes the form of a tree-based +representation of the configuration items within the currently loaded +eCos packages.

    +

    In the case of items +whose values may be changed, controls are available to set the item +values. These either take the form of check boxes or radio buttons +within the tree itself or cells to the right of the thin vertical +splitter bar. Controls in the tree may be used in the usual way; +cells, however, must first be activated.

    +

    To activate a cell, +simply click on it: it will assume a sunken appearance and data can +then be edited in the cell. To terminate in-cell editing, click +elsewhere in the configuration window or press ENTER. To discard the +partial results of in-cell editing and revert to the previous value, +press ESCAPE. Note that an asterisk appears

    +

    against configuration +items which have changed since the configuration was last saved.

    +

    +

    +

    Cells come in three +varieties, according to the type of data they accept:

    + + + + + + + + + + + + + + + + + +
    +

    Cell Type +

    +
    +

    Data Accepted +

    +
    +

    Integer

    +
    +

    Decimal or hexadecimal values

    +
    +

    Floating Point

    +
    +

    Floating point values

    +
    +

    String

    +
    +

    Any

    +
    +

    In the case of string +cells, you can double-click the cell to display a dialog box +containing a larger region in which to edit the string value. This is +useful in the case of long strings, or those spanning multiple lines.

    +

    +Disabled items

    +

    Some items will appear +disabled. In this case the item label and any associated controls and +cells will be grayed. It is not be possible to change the values of +disabled items.

    +
    +Right-Clicking
    +

    You can right-click on an +item in the configuration window item to display a pop-up menu which +(depending on the type of the item selected) allows you to:

    +
      +
    • Properties - information relating + to the currently selected item is displayed. The information is + equivalent to that displayed in the Properties Window. +

      +
    • Restore Defaults - the default + value of the currently selected item is restored. +

      +
    • Visit Documentation - causes the + HTML page most closely relating to the currently selected item to be + displayed. This has the same effect as double-clicking the URL + property in the Properties Window. Note: if this fails to display + the first time you select on it, try again after the browser has + appeared.

      +
    • View Header File - this causes + the file containing the items to be displayed. This is equivalent to + double-clicking on the File property in the Properties Window. The + viewer used for this purpose may be changed using the ViewSettings + menu item (see Settings + ). Note that this operation is only possible when the current + configuration is saved, in order to avoid the possibility of + changing the source repository. +

      +
    • Unload Package - this is + equivalent to using the BuildPackages + menu item to select and unload the package in question. +

      +
    +

    +Conflicts Window

    +

    This window exists to +display any configuration item conflicts. Conflicts are the result of +failures to meet the requirements between configuration items +expressed in the CDL. See "Conflicts" in CDL +Concepts .

    +

    +

    +

    The window comprises +three columns:

    +
      +
    • Item +

      +
    +

    This is the +macro name of the first item involved in the conflict.

    +
      +
    • Conflict +

      +
    +

    This is a +description of the conflict type. The currently supported types are +"unresolved", "illegal value", "evaluation +exception", "goal unsatisfied" and "bad data".

    +
      +
    • Property +

      +
    +

    This contains a +description of the configuration item's property that caused the +conflict.

    +

    Within the conflicts +window you can right-click on any item to display a context menu +which allows you to choose from one of the following options:

    +
      +
    • What's This? Gives a small description of the conflict + window's purpose.

      +
    • Locate the item involved + in the conflict - this will cause the configuration window to + display the item relating most closely to the selected conflict (the + item mentioned in the first or third column depending on where you + clicked). You can also double-click on an item to locate it.

      +
    • Resolve the specified conflict - see Resolving + conflicts.

      +
    +

    +Output Window

    +

    This window displays any +output generated by execution of external tools and any error +messages that are not suitable for display in other forms (for +example, as message boxes).

    +

    Within the output window +you can right-click to display a context menu which allows you to:

    +
      +
    • Save the contents of the window + to a file +

      +
    • Clear the contents of the window +

      +
    +

    +Properties Window

    +

    This window displays the +CDL properties of the item currently selected in the configuration +window. The same information may be displayed by right-clicking the +item and selecting "Properties".

    +

    +

    +

    Two properties may be +double-clicked as follows:

    +
      +
    • URL - double-clicking on a URL + property causes the referenced HTML page to be displayed. This has + the same effect as right-clicking on the item and choosing "Visit + Documentation". +

      +
    • File - double-clicking on a File + property in a saved configuration causes the File to be displayed. + The viewer used for this purpose may be changed using the + ViewSettings + menu item. Note that this operation is only possible when the + current configuration is saved, in order to avoid the possibility of + changing the source repository. +

      +
    +

    +Short Description Window

    +

    This window displays a +short description of the item currently selected in the configuration +window. More extensive documentation may be available by +right-clicking on the item and choosing "Visit Documentation".

    +

    + + + + + + + + +
    +

    Screen Layout

    +
    +

    To + Contents

    +
    +

    To previous page

    +
    +

    To next page

    +


    +

    + + \ No newline at end of file diff --git a/host/tools/configtool/standalone/wxwin/manual/user-guides.8.html b/host/tools/configtool/standalone/wxwin/manual/user-guides.8.html new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/manual/user-guides.8.html @@ -0,0 +1,267 @@ + + + + Updating the Configuration + + + + + + + +

    + + + + + + + + +
    +

    Updating the Configuration

    +
    +

    To + Contents

    +
    +

    To previous page

    +
    +

    To next page

    +
     

    +



    +

    +
    +

    +Updating the Configuration

    +

    +

    +

    +Adding and Removing Packages

    +

    To add or remove packages +from the configuration, select Build + +Packages. The following dialog box will be displayed:

    +

    Packages dialog +box +

    +

    +

    +

    The left list shows those +packages that are available to be loaded. The right-hand list shows +those that are currently loaded. In order to transfer packages from +one list to another (that is, to load or unload packages) +double-click the selection or click the Add or Remove buttons.

    +

    The version drop-list +displays the versions of the selected packages. When loading +packages, this control may be used to load versions other than the +most recent (current). Note that if more than one package is +selected, the version drop-list will display only the versions in +common to all the selected packages.

    +

    The bottommost window in +the dialog displays a brief description of the selected package. If +more than one package is selected, this window will be blank.

    +

    Platform Selection

    +

    To add, modify or remove +entries in the list of platforms used for running tests, select +ToolsPlatforms. +The following dialog will be displayed:

    +

    Platforms dialog +box +

    +

    +

    +

    You may add, modify or +remove platform entries as you wish, but in order to run tests, a +platform must be defined to correspond to the currently loaded +hardware template. The information associated with each platform name +is used to run tests.

    +

    To modify a platform, +click the Modify button with the appropriate platform selected, or +double-click on an entry in the list. A dialog will be displayed that +allows you to change the command prefix, platform type and arguments +for GDB. +

    +

    Platform Modify +dialog box +

    +

    +

    +

    To add a new platform, +click the Add button. A similar dialog will be displayed that allows +you to define a new platform. To remove a platform, click the Delete +button or press the DEL key with the appropriate platform selected.

    +

    New Platform +dialog box +

    +

    +

    +

    The command prefix is +used when running tests in order to determine the names of the +executables (such as gdb) to be used. For example, if the gdb +executable name is "arm-elf-gdb.exe" the prefix should be +set to "arm-elf".

    +

    The platform type +indicates the capabilities of the platform - whether it is hardware +or a simulator, and whether breakpoints are supported.

    +

    The arguments for the GDB +field allow additional arguments to be passed to gdb when it is used +to run a test. This is typically used in the case of simulators +linked to gdb in order to define memory layout.

    +

    +Using Templates

    +

    To load a configuration +based on a template, select Build + +Templates. +

    +

    The following dialog box +will be displayed:

    +

    Templates dialog +box +

    +

    +

    +

    Change the hardware +template, the packages template, or both. To select a hardware +template, choose from the first drop-list. To choose a packages +template, choose from the second. Brief descriptions of each kind of +template are provided in the corresponding edit boxes.

    +

    +Resolving conflicts

    +

    During the process of +configuring eCos it is possible that conflicts will be created. For +more details of the meaning of conflicts, see CDL +Concepts .

    +

    The Conflicts Window +displays all conflicts in the current configuration. Additionally, a +window in the status bar displays a count of the conflicts. Because +the resolution of conflicts can be time-consuming, a mechanism exists +whereby conflicts can be resolved automatically.

    +

    +You can choose conflict resolution options using a dialog box +displayed by means of the ViewSettingsConflict +resolution menu item. +

    +

    Options +

    +

    +

    +

    You can choose to have +conflicts checked under the following circumstances:

    +
      +
    • After any item is changed (in + other words, as soon as the conflict is created) +

      +
    • Before saving the configuration + (including building) +

      +
    • Never +

      +
    +

    The method you chose +depends on how much you need your configuration to be free of +conflicts. You may want to avoid having to clean up all the conflicts +at once, or you may want to keep the configuration consistent at all +times. If you have major changes to implement, which may resolve the +conflicts, then you might want to wait until after you have completed +these changes before you check for conflicts.

    +

    NOTE

    +

    If you choose to check +conflicts after any item is changed, only newly arising conflicts are +displayed. If you choose to check for conflicts before saving the +configuration, the complete set is displayed.

    +

    Automatic resolution

    +

    If you check the +"Automatically suggest fixes" check box, a conflicts +resolution dialog box will be displayed whenever new conflicts are +created. The same dialog box may be displayed at any stage by means +of the ToolsResolve +Conflicts menu item. +

    +

    The conflicts resolution +dialog box contains two major windows. +

    +

    Resolve conflicts +window +

    +

    +

    +

    The upper contains the +set of conflicts to be addressed; the format of the data being as +that of the Conflicts Window. The lower window contains a set of +proposed resolutions - each entry is a suggested configuration item +value change that as a whole may be expected to lead to the currently +selected conflict being resolved. +

    +

    Note that there is no +guarantee:

    +
      +
    • that automatic resolutions will + be determinable for every conflict. +

      +
    • that the resolutions for separate + conflicts will be independent. In other words, the resolution of one + conflict may serve to prevent the resolution of another. +

      +
    • that the resolution conflicts + will not create further conflicts. +

      +
    +

    The above warnings are, +however, conservative. In practice (so long as the number and extent +of conflicts are limited) automatic conflict resolution may be used +to good effect to correct problems without undue amounts of +programmer intervention.

    +

    In order to select the +conflicts to be applied, select or clear the check boxes against the +resolutions for each proposed resolution. By default all resolutions +are selected; you can return to the default state (in other words, +cause all check boxes for each conflict to again become checked) by +pressing the "Reset" button. Note that multiple selection +may be used in the resolutions control to allow ranges of check boxes +to be toggled in one gesture.

    +

    When you are happy to +apply the selected resolutions for each conflict displayed, click +Apply ; this will apply the resolutions. Alternatively you may cancel +from the dialog box without any resolutions being applied.

    + + + + +
    +
    +

    + + + + + + + + +
    +

    Updating the Configuration

    +
    +

    To + Contents

    +
    +

    To previous page

    +
    +

    To next page

    +


    +

    + + \ No newline at end of file diff --git a/host/tools/configtool/standalone/wxwin/manual/user-guides.9.html b/host/tools/configtool/standalone/wxwin/manual/user-guides.9.html new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/manual/user-guides.9.html @@ -0,0 +1,104 @@ + + + + Searching + + + + + + + +

    + + + + + + + + +
    +

    Searching

    +
    +

    To + Contents

    +
    +

    To previous page

    +
    +

    To next page

    +
     

    +



    +

    +
    +

    +Searching

    +

    +

    +

    Select Edit - +Find. You will be presented with a Find dialog box:

    +

    Find dialog box +

    +

    +

    +

    Using this dialog box you +can search for an exact text string in any one of three ways, as +specified by your selection in the "Search in" drop-list:

    +
      +
    • Macro names - the search is for a + text match within configuration item macro names +

      +
    • Item names - the search is for a + text match within configuration item descriptive names +

      +
    • Short descriptions - the search + is for a text match within configuration item short descriptions +

      +
    • Current values - the search is a text match within + configuration item current values

      +
    • Default values - the search is a text match within + configuration item default values

      +
    +

    Note that to invoke Find +you can also click the Find icon on the toolbar. +

    +

    You can repeat your search without showing the Find +dialog box, by using the Edit - +Find Next menu item or by pressing F3.

    + + + + +
    +
    +

    + + + + + + + + +
    +

    Searching

    +
    +

    To + Contents

    +
    +

    To previous page

    +
    +

    To next page

    +


    +

    + + \ No newline at end of file diff --git a/host/tools/configtool/standalone/wxwin/manual/user-guides.a.html b/host/tools/configtool/standalone/wxwin/manual/user-guides.a.html new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/manual/user-guides.a.html @@ -0,0 +1,149 @@ + + + + + + Building + + +

    + + + + + + + + +Building
    + +
    +

    +

    + + +When you have configured eCos, you may build the configuration.

    +

    + + +On the +Build + menu, click:

    +
      +

    • + + + +Library + (or click the Build Library icon on the toolbar) - this causes the eCos configuration to be built. The result of a successful build will be (among other things) a library against which user code can be linked
    • +

    • + + + +Tests + - this causes the eCos configuration to be built, and additionally builds the relevant test cases linked against the eCos library
    • +

    • + + + +Clean + - this removes all intermediate files, thus causing a subsequent build/library or build/tests operation to cause recompilation of all relevant files.
    • +

    • + + + +Stop + - this causes a currently executing build (any of the above steps) to be interrupted
    • +
    +

    + + +Build options may be displayed by using the +BuildOptions + menu item. This displays a dialog box containing a drop-list control and two windows. The drop-list control allows you to select the type of build option to be displayed (for example "LDFLAGS" are the options applied at link-time. The left-hand window is a tree view of the packages loaded in the current configuration. The right-hand window is a list of the build options that will be used for the currently selected package.

    +

    + + +Note that this dialog box currently affords only read-only access to the build options. In order to change build options you must edit the relevant string configuration item.

    +

    + + +A single level of inheritance is supported: each package's build options are combined with the global options (these are to be found in the "Global build options" folder in the configuration view).

    +

    + + +

    +
    + +
    +
    +

    + + + + +Selecting + +Build Tools

    +

    + + +Normally the installation process will supply the information required for the eCos + +Configuration Tool to locate the build tools (compiler, linker, etc...) necessary to perform a build. However if this information is not registered, or it is necessary to specify the location manually (for example, when a new toolchain installation has been made), select +Tools + +Paths + +Build Tools. + The following dialog box will be displayed:

    +

    + + +Build tools

    +
    + +
    +

    + + +This dialog box allows you to locate the folder containing the build tools.

    +
    +
    +

    + + + + +Selecting + +User Tools

    +

    + + +Normally the installation process will supply the information required for the eCos + +Configuration Tool to locate the user tools (cat, ls, etc...) necessary to perform a build. However if this information is not registered, or it is necessary to specify the location manually (for example, when a new toolchain installation has been made), select +Tools + +Paths + +User Tools. + The following dialog box will be displayed:

    +

    + + +User tools

    +
    + +
    + + + + +
    +
    +
    +

    Building

    To Contents

    To previous page

    To next page

    + diff --git a/host/tools/configtool/standalone/wxwin/manual/user-guides.b.html b/host/tools/configtool/standalone/wxwin/manual/user-guides.b.html new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/manual/user-guides.b.html @@ -0,0 +1,279 @@ + + + + Execution + + + + + + + +

    + + + + + + + + +
    +

    Execution

    +
    +

    To + Contents

    +
    +

    To previous page

    +
    +

    To next page

    +
     

    +



    +

    +
    +

    +Execution

    +

    +

    +

    Test executables that +have been linked using the Build/Tests operation against the current +configuration can be executed by selecting Tools + +Run Tests. +

    +

    PLEASE NOTE: this functionality is not yet +implemented.

    +

    When tests are run, the +Configuration Tool looks for a platform name corresponding to the +currently loaded hardware template. If no such platform is found, a +dialog will be displayed for you to define one; this dialog is +similar to that displayed by the Add function in the ToolsPlatforms +dialog, but in this case the platform name cannot be changed.

    +

    When a test run is +invoked, a property sheet is displayed, comprising three tabs: +Executables, Output and Summary. +

    +

    Note that the property +sheet is resizable.

    +

    Three buttons appear on +the property sheet itself: Run/Stop, Close and Properties. +

    +

    The Run button is used to +initiate a test run. Those tests selected on the Executables tab are +run, and the output recorded on the Output and Summary tabs. During +the course of a run, the Run button changes to "Stop". The +button may be used to interrupt a test run at any point.

    +

    +Properties

    +

    The Run Tests settings +dialog can be invoked using the Properties button on the Run Tests +dialog, or by selecting the ViewSettings +menu and choosing the Run Tests tab. This dialog allows you choose +connectivity settings.

    +

    Properties dialog +box +

    +

    +

    +

    +Download Timeout

    +

    This group of controls +serves to set the maximum time that is allowed for downloading a test +to the target board. If the time is exceeded, the test will be deemed +to have failed for reason of "Download Timeout" and the +execution of that particular test will be abandoned. This option only +applies to tests run on hardware, not to those executed in a +simulator. Times are in units of elapsed seconds.

    +

    Three options are +available using the drop-down list:

    +
      +
    • Calculated from file size - an + estimate of the maximum time required for download is made using the + (stripped) executable size and the currently used baud rate +

      +
    • Specified - a user-specified + value may be entered in the adjacent edit box +

      +
    • None - no maximum download time + is to be applied. +

      +
    +

    +Run time Timeout

    +

    This group of controls +serves to set the maximum time that is allowed for executing a test +on the target board or in a simulator. If the time is exceeded, the +test will be deemed to have failed for reason of "Timeout" +and the execution of that particular test will be abandoned. In the +case of hardware, the time is measured in elapsed seconds: in the +case of a simulator it is in CPU seconds.

    +

    Three options are +available using the drop-down list:

    +
      +
    • None - no maximum download time + is to be applied. +

      +
    • Specified - a user-specified + value may be entered in the adjacent edit box +

      +
    • Default - a default value of 30 + seconds is used +

      +
    +

    +Connection

    +

    The Connection controls +may be used to specify how the target board is to be accessed:

    +

    If the target +board is connected using a serial cable, the Serial radio button +should be checked. In this case you can select a port (COM1, COM2, +...) and an appropriate baud rate using drop-list boxes.

    +

    If the target board is +accessed remotely using GDB remote protocol, the "TCP/IP" +radio button should be checked. In this case you can select a host +name and TCP/IP port number using edit boxes.

    +

    +Executables Tab

    +

    This is used to adjust +the set of tests available for execution. A check box against each +executable name indicates whether that executable will be included +when the Run button is pressed. The Check All and Uncheck All buttons +may be used to check or uncheck all items.

    +

    When the property sheet +is first displayed, it will be pre-populated with those test +executables that have been linked using the Build/Tests operation +against the current configuration. +

    +

    Run tests +

    +

    +

    +

    You can right-click in +the window to display a context menu containing Add and Remove items. +Clicking Remove will remove those executables selected. Clicking Add +will display a dialog box that allows you to add to the set of items. +Equivalently the Add button may be used to add executables, and the +DEL key may be used to remove them.

    +

    You can use the Add from +Folder button to add a number of executables in a specified folder +(optionally including subfolders).

    +

    Add files from +folder +

    +

    +

    +

    The "Add from +subfolders" check box should be checked if you wish the search +for executables to descend into subfolders (in the example above the +whole of the C drive would be searched).

    +

    The "Files of type" +edit box should be used to specify the extension of those files to be +matched [for example, "*.exe"].

    +

    +Output Tab

    +

    This tab is used to +display the output from running tests. The output can be saved to a +file or cleared by means of the popup menu displayed when you +right-click in the window.

    +

    +Summary Tab

    +

    This tab is used to +display a record, in summary form, of those tests executed. For each +execution, the following information is displayed:

    +
      +
    • Time - + the date and time of execution +

      +
    • Host - + the host name of the machine from which the test was downloaded +

      +
    • Platform + - the platform on which the test was executed +

      +
    • Executable + - the executable (file name) of the test executed +

      +
    • Status + - the result of executing the test. This will be one of the + following: +

      +
        +
      • Not started +

        +
      • No result +

        +
      • Inapplicable +

        +
      • Pass +

        +
      • DTimeout +

        +
      • Timeout +

        +
      • Cancelled +

        +
      • Fail +

        +
      • Assert fail +

        +
      +
    • Size - + the size [stripped/unstripped] of the test executed +

      +
    • Download + - the download time [mm:ss/mm:ss] used. The first of the two times + displayed represents the actual time used: the second the limit + time. +

      +
    • Elapsed + - the elapsed time [mm:ss] used. +

      +
    • Execution + - the execution time [mm:ss/mm:ss] used. The first of the two times + displayed represents the actual time used: the second the limit + time. +

      +
    +

    The output can be saved +to a file or cleared by means of the popup menu displayed when you +right-click in the window.

    + + + + +
    +
    +

    + + + + + + + + +
    +

    Execution

    +
    +

    To + Contents

    +
    +

    To previous page

    +
    +

    To next page

    +


    +

    + + \ No newline at end of file diff --git a/host/tools/configtool/standalone/wxwin/manual/user-guides.c.html b/host/tools/configtool/standalone/wxwin/manual/user-guides.c.html new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/manual/user-guides.c.html @@ -0,0 +1,372 @@ + + + + Creating a Shell + + + + + + + +

    + + + + + + + + +
    +

    Creating a Shell

    +
    +

    To + Contents

    +
    +

    To previous page

    +
    +

    To next page

    +
     

    +



    +

    +
    +

    +Creating a Shell

    +

    +

    +

    To call up a shell +window, select Tools + +Shell :

    +

    +

    +

    +Keyboard Accelerators

    +

    The following table +presents the list of keyboard accelerators that can be used with the +Configuration Tool. +

    +

    +Keyboard accelerators

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +

    Accelerator

    +
    +

    Action

    +
    +

    Remarks

    +
    +

    Alt+1 +

    +
    +

    hide/show + properties window

    +
    +

    Alt+2 +

    +
    +

    hide/show + documentation window

    +
    +

    Alt+3 +

    +
    +

    hide/show short + description window

    +
    +

    Alt+5 +

    +
    +

    hide/show output + window

    +
    +

    Ctrl+A +

    +
    +

    select all

    +
    +

    output window and + in-cell editing

    +
    +

    Ctrl+C +

    +
    +

    copy

    +
    +

    output window and + in-cell editing

    +
    +

    Ctrl+F +

    +
    +

    EditFind

    +
    +

    Ctrl+N +

    +
    +

    FileNew

    +
    +

    Ctrl+O +

    +
    +

    FileOpen

    +
    +

    Ctrl+S +

    +
    +

    FileSave

    +
    +

    Ctrl+V +

    +
    +

    Paste

    +
    +

    in-cell editing + only

    +
    +

    Ctrl+X +

    +
    +

    Cut

    +
    +

    in-cell-editing + only

    +
    +

    Ctrl+Z +

    +
    +

    Undo

    +
    +

    in-cell editing + only

    +
    +

    F1 +

    +
    +

    Context-sensitive + help

    +
    +

    F3 +

    +
    +

    Find next

    +
    +

    F7 +

    +
    +

    BuildLibrary

    +
    +

    Shift+F7 +

    +
    +

    BuildTests

    +
    +

    Shift+Ins +

    +
    +

    Paste

    +
    +

    in-cell editing + only

    +
    +

    Shift+F10 +

    +
    +

    Display context + menu

    +
    +

    Configuration + window

    +
    +

    Alt+Enter +

    +
    +

    Display properties + dialog box

    +
    +

    Configuration + window

    +
    +

    > +

    +
    +

    Increment item + value

    +
    +

    Configuration + window

    +
    +
    <
    +
    +

    Decrement item + value

    +
    +

    Configuration + window

    +
    +

    Space +

    +
    +

    Toggle item value

    +
    +

    Configuration + window

    +
    +
    +

    + + + + + + + + +
    +

    Creating a Shell

    +
    +

    To + Contents

    +
    +

    To previous page

    +
    +

    To next page

    +


    +

    + + \ No newline at end of file diff --git a/host/tools/configtool/standalone/wxwin/manual/user-guides.d.html b/host/tools/configtool/standalone/wxwin/manual/user-guides.d.html new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/manual/user-guides.d.html @@ -0,0 +1,38 @@ + + + + + + Part II: eCos Programming Concepts and Techniques + +
    +

    Part II: eCos Programming Concepts and Techniques

    To Contents

    To previous page

    To next page

     




    +

    + + +Part II: eCos Programming Concepts and Techniques
    + +
    +

    +

    + + +Programming with eCos is somewhat different from programming in more traditional environments. eCos is a configurable open source system, and you are able to configure and build a system specifically to meet the needs of your application.

    +

    + + +Various different directory hierarchies are involved in configuring and building the system: the +component repository, + the +build tree, + and the +install tree. + These directories exist in addition to the ones used to develop applications.

    + + + + +
    +
    +

    Part II: eCos Programming Concepts and Techniques

    To Contents

    To previous page

    To next page

    + diff --git a/host/tools/configtool/standalone/wxwin/manual/user-guides.e.html b/host/tools/configtool/standalone/wxwin/manual/user-guides.e.html new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/manual/user-guides.e.html @@ -0,0 +1,540 @@ + + + + + + CDL Concepts + + +

    + + + + +CDL Concepts
    + +
    +

    +

    + + +About this Chapter

    +

    + + +This chapter serves as a brief introduction to the concepts involved in eCos (Embedded Configurable Operating System). It describes the configuration architecture and the underlying technology to a level required for the embedded systems developer to configure eCos. It does not describe in detail aspects such as how to write reusable components for eCos: this information is given in the +CDL Writer's Guide. +

    +

    + + +Background

    +

    + + +Software solutions for the embedded space place particularly stringent demands on the developer, typically represented as requirements for small memory footprint, high performance and robustness. These demands are addressed in eCos by providing the ability to perform compile-time specialization: the developer can tailor the operating system to suit the needs of the application. In order to make this process manageable, eCos is built in the context of a Configuration Infrastructure: a set of tools including a +Configuration Tool + and a formal description of the process of configuration by means of a +Component Definition Language. +

    +

    + + +Configurations

    +

    + + +eCos is tailored at source level (that is, before compilation or assembly) in order to create an eCos +configuration. + In concrete terms, an eCos configuration takes the form of a configuration save file (with extension .ecc) and set of files used to build user applications (including, when built, a library file against which the application is linked).

    +

    + + +Component Repository

    +

    + + +eCos is shipped in source in the form of a +component repository + - a directory hierarchy that contains the sources and other files which are used to build a configuration. The component repository can be added to by, for example, downloading from the net.

    +

    + + +Component Definition Language

    +

    + + +Part of the component repository is a set of files containing a definition of its structure. The form used for this purpose is the +Component Definition Language + (CDL). CDL defines the relationships between components and other information used by tools such as the eCos + +Configuration Tool. CDL is generally formulated by the writers of components: it is not necessary to write or understand CDL in order for the embedded systems developer to construct an eCos configuration.

    +

    + + +Packages

    +

    + + +The building blocks of an eCos configuration are called +packages. + Packages are the units of software distribution. A set of core packages (such as kernel, C library and math library) is provided by Red Hat: additional third-party packages will be available in future.

    +

    + + +A package may exist in one of a number of +versions. + The default version is the +current + version. Only one version of a given package may be present in the component repository at any given time.

    +

    + + +Packages are organized in a tree hierarchy. Each package is either at the top-level or is the child of another package.

    +

    + + +The eCos Administration Tool can be used to add or remove packages from the component repository. The eCos + +Configuration Tool can be used to include or exclude packages from the configuration being built.

    +

    + + + Configuration Items

    +

    + + + +Configuration items + are the individual entities that form a configuration. Each item corresponds to the setting of a C pre-processor macro (for example, CYGHWR_HAL_ARM_PID_GDB_BAUD). The code of eCos itself is written to test such preprocessor macros so as to tailor the code. User code can do likewise.

    +

    + + +Configuration items come in the following flavors:

    +
      +

    • + + + +None +: such entities serve only as placeholders in the hierarchy, allowing other entities to be grouped more easily.
    • +

    • + + + +Boolean + entities are the most common flavor; they correspond to units of functionality that can be either enabled or disabled. If the entity is enabled then there will be a #define; code will check the setting using, for example, #ifdef
    • +

    • + + + +Data + entities encapsulate some arbitrary data. Other properties such as a set or range of legal values can be used to constrain the actual values, for example to an integer or floating point value within a certain range.
    • +

    • + + + +Booldata + entities combine the attributes of +Boolean + and +Data +: they can be enabled or disabled and, if enabled, will hold a data value.
    • +
    +

    + + +Like packages, configuration items exist in a tree-based hierarchy: each configuration item has a parent which may be another configuration item or a package. Under some conditions (such as when packages are added or removed from a configuration), items may be "re-parented" such that their position in the tree changes.

    +

    + + +Expressions

    +

    + + +Expressions are relationships between CDL items. There are three types of expression in CDL:

    + + + + + + + + + + + + + + + + + + + + + + +
    +

    + + +CDL Expressions

    +
    +

    + + + +Expression Type +

    +
    +

    + + + +Result +

    +
    +

    + + + +Common Use [see Table 2] +

    +
    +

    + + +Ordinary

    +
    +

    + + +A single value

    +
    +

    + + +legal_values property

    +
    +

    + + +List

    +
    +

    + + +A range of values (for example "1 to 10")

    +
    +

    + + +legal_values property

    +
    +

    + + +Goal

    +
    +

    + + +True or False

    +
    +

    + + +requires and active_if properties

    +
    +

    + + +Properties

    +

    + + +Each configuration item has a set of properties. The following table describes the most commonly used:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +

    + + +Configuration properties

    +
    +

    + + + +Property +

    +
    +

    + + + +Use +

    +
    +

    + + +Flavor

    +
    +

    + + +The "type" of the item, as described above

    +
    +

    + + +Enabled

    +
    +

    + + +Whether the item is enabled

    +
    +

    + + +Current_value

    +
    +

    + + +The current value of the item

    +
    +

    + + +Default_value

    +
    +

    + + +An ordinary expression defining the default value of the item

    +
    +

    + + +Legal_values

    +
    +

    + + +A list expression defining the values the item may hold (for example, 1 to10)

    +
    +

    + + +Active_if

    +
    +

    + + +A goal expression denoting the requirement for this item to be active (see below: +Inactive Items +)

    +
    +

    + + +Requires

    +
    +

    + + +A goal expression denoting requirements this item places on others (see below: +Conflicts +)

    +
    +

    + + +Calculated

    +
    +

    + + +Whether the item as non-modifiable

    +
    +

    + + +Macro

    +
    +

    + + +The corresponding C pre-processor macro

    +
    +

    + + +File

    +
    +

    + + +The C header file in which the macro is defined

    +
    +

    + + +URL

    +
    +

    + + +The URL of a documentation page describing the item

    +
    +

    + + +Hardware

    +
    +

    + + +Indicates that a particular package is related to specific hardware

    +
    +

    + + +A complete description of properties is contained in the +CDL Writer's Guide. +

    +

    + + +Inactive Items

    +

    + + +Descendants of an item that is disabled are inactive: their values may not be changed. Items may also become +inactive + if an active_if expression is used to make the item dependent on an expression involving other items.

    +

    + + +Conflicts

    +

    + + +Not all settings of configuration items will lead to a coherent configuration; for example, the use of a timeout facility might require the existence of timer support, so if the one is required the other cannot be removed. Coherence is policed by means of consistency rules (in particular, the goal expressions that appear as CDL items +requires + and +active_if + attributes [see above]). A violation of consistency rules creates a +conflict, + which must be resolved in order to ensure a consistent configuration. Conflict resolution can be performed manually or with the assistance of the eCos tools. Conflicts come in the following flavors:

    +
      +

    • + + +An +unresolved + conflict means that there is a reference to an entity that is not yet in the current configuration
    • +

    • + + +An +illegal value + conflict is caused when a configuration item is set to a value that is not permitted (that is, a +legal_values + goal expression is failing)
    • +

    • + + +An +evaluation exception + conflict is caused when the evaluation of an expression would fail (for example, because of a division by zero)
    • +

    • + + +An +unsatisfied goal + conflict is caused by a failing +requires + goal expression
    • +

    • + + +A +bad data + conflict arises only rarely, and corresponds to badly constructed CDL. Such a conflict can only be resolved by reference to the CDL writer.
    • +
    +

    + + +Templates

    +

    + + +A +template + is a saved configuration - that is, a set of packages and configuration item settings. Templates are provided with eCos to allow you to get started quickly by instantiating (copying) a saved configuration corresponding to one of a number of common scenarios; for example, a basic eCos configuration template is supplied that contains the infrastructure, kernel, C and math libraries, plus their support packages.

    + + + + +
    +
    +

    CDL Concepts

    To Contents

    To previous page

    To next page

    + diff --git a/host/tools/configtool/standalone/wxwin/manual/user-guides.f.html b/host/tools/configtool/standalone/wxwin/manual/user-guides.f.html new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/manual/user-guides.f.html @@ -0,0 +1,389 @@ + + + + + + The Component Repository and Working Directories + +
    +

    The Component Repository and Working Directories

    To Contents

    To previous page

    To next page

     




    +

    + + +The Component Repository and Working Directories
    + +
    +

    +

    + + +Each of the file trees involved in eCos development has a different role.

    +
    +

    + + +Component Repository

    +

    + + +The eCos + +component repository contains directories for all the packages that are shipped with eCos or provided by third parties.

    +

    + + +The component repository should not be modified as part of application development.

    +

    + + +Component repository

    +
    + +
    +
    + + +Purpose
    +

    + + +The component respository is the master copy of source code for all system and third party components. It also contains some files needed to administer and build the system, such as +ecosadmin.tcl +.

    +
    + + +How is it modified?
    +

    + + +You modify it by importing new versions of packages from a distribution or removing existing packages. These activities are undertaken using the +eCos Package Administration Tool. +

    +
    + + +When is it edited manually?
    +

    + + +Files in the component repository should only be edited manually as determined by the component maintainer.

    +
    + + +User applications
    +

    + + +User application source code should +not + go into the component repository.

    +
    + + +Examples of files in this hierarchy:
    +

    + + + +BASE_DIR + +/doc/ref/ecos-ref.html +

    +

    + + +The top level HTML file for the +eCos + + Reference Manual. +

    +

    + + + +BASE_DIR + +/prebuilt/pid/tests/kernel/v1_3_x/tests/thread_gdb.exe +

    +

    + + + +BASE_DIR + +/prebuilt/linux/tests/kernel/v1_3_x/tests/thread_gdb.exe +

    +

    + + +Prebuilt tests for the supported platforms, and the synthetic Linux target.

    +

    + + + +BASE_DIR + +/examples/twothreads.c +

    +

    + + +One of the example programs.

    +

    + + + +BASE_DIR + +/ecosadmin.tcl +

    +

    + + +The Tcl program which is used to import new versions of packages from a distribution or remove existing packages.

    +

    + + + +BASE_DIR + +/packages/language/c/libm/ + +v1_3_x + +/src/double/portable-api/s_tanh.c +

    +

    + + +Implementation of the hyperbolic tangent function in the standard math library.

    +

    + + + +BASE_DIR + +/pkgconf/rules.mak +

    +

    + + +A file with +make + rules, used by the +makefile +.

    +
    +
    +

    + + + + +Build Tree

    +

    + + +The + +build tree is the directory hierarchy in which all +generated + files are placed. Generated files consist of the +makefile +, the compiled object files, and a dependency file (with a +.d + extension) for each source file.

    +
    + + +Purpose
    +

    + + +The build tree is where all intermediate object files are placed.

    +
    + + +How is it modified?
    +

    + + +Recompiling can modify the object files.

    +
    + + +User applications
    +

    + + +User application source or binary code should +not + go in the build tree.

    +
    + + +Examples of files in this hierarchy
    +

    + + + +ecos-work/language/c/libc/ +v1_3_x/src

    +

    + + +The directory in which object files for the C library are built.

    +
    +
    +

    + + + + +Install Tree

    +

    + + +The + +install tree is the location for all files needed for application development. The +libtarget.a + library, which contains the custom-built eCos kernel and other components, is placed in the install tree, along with all packages' public header files. If you build the tests, the test executable programs will also be placed in the install tree.

    +

    + + +By default, the install tree is created by +ecosconfig + in a subdirectory of the build tree called +install +. This can be modified with the +--prefix + option (see + Manual Configuration +).

    +
    + + +Purpose
    +

    + + +The install tree is where the custom-built +libtarget.a + library, which contains the eCos kernel and other components, is located. The install tree is also the location for all the header files that are part of a published interface for their component.

    +
    + + +How is it modified?
    +

    + + +Recompiling can replace +libtarget.a + and the test executables.

    +
    + + +When is it edited manually?
    +

    + + +Where a memory layout requires modification without use of the eCos Configuration Tool, the memory layout files must be edited directly in the install tree. These files are located at +install/include/pkgconf/mlt_*.* +. Note that subsequent modification of the install tree using the Configuration Tool will result in such manual edits being lost.

    +
    + + +User applications
    +

    + + +User application source or binary code should +not + go in the install tree.

    +
    + + +Examples of files in this hierarchy
    +

    + + + +install/lib/libtarget.a +

    +

    + + +The library containing the kernel and other components.

    +

    + + + +install/include/cyg/kernel/kapi.h +

    +

    + + +The header file for the kernel C language API.

    +

    + + + +install/include/pkgconf/mlt_arm_pid_ram.ldi +

    +

    + + +The linker script fragment describing the memory layout for linking applications intended for execution on an ARM PID development board using RAM startup.

    +

    + + + +install/include/stdio.h +

    +

    + + +The C library header file for standard I/O.

    +
    +
    +

    + + + + +Application + +Build Tree

    +

    + + +This tree is not part of eCos itself: it is the directory in which eCos end users write their own applications.

    +

    + + +Example applications and their +Makefile + are located in the component repository, in the directory +BASE_DIR + +/examples +.

    +

    + + +There is no imposed format on this directory, but there are certain compiler and linker flags that must be used to compile an eCos application. The basic set of flags is shown in the example +Makefile +, and additional details can be found in + Compiler and Linker Options +.

    + + + + +
    +
    +
    +

    The Component Repository and Working Directories

    To Contents

    To previous page

    To next page

    + diff --git a/host/tools/configtool/standalone/wxwin/manual/user-guides.html b/host/tools/configtool/standalone/wxwin/manual/user-guides.html new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/manual/user-guides.html @@ -0,0 +1,10 @@ + + + +redirect + + + + + + diff --git a/host/tools/configtool/standalone/wxwin/memmap.cpp b/host/tools/configtool/standalone/wxwin/memmap.cpp new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/memmap.cpp @@ -0,0 +1,1738 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +//================================================================= +// +// memmap.cpp +// +// Memory Layout Tool map data structure manipulation class +// +//================================================================= +//#####DESCRIPTIONBEGIN#### +// +// Author(s): John Dallaway +// Contact(s): jld +// Date: 1998/07/29 $RcsDate$ {or whatever} +// Version: 0.00+ $RcsVersion$ {or whatever} +// Purpose: Provides functions to create and destroy memory regions +// and sections within the memory map. +// Description: Each function manipulates data structures representing +// memory regions, memory sections and the view of memory +// sections as presented to the user. The section view +// structure organises the sections by region and +// will contain two instances of each relocated section +// Requires: memmap.h +// Provides: create_memory_region() +// delete_memory_region() +// edit_memory_region() +// create_memory_section() +// delete_memory_section() +// edit_memory_section() +// delete_all_memory_sections() +// set_map_size() +// section_list +// region_list +// See also: memmap.h +// Known bugs: +// WARNING: Do not modify data structures other than by using the +// provided functions +// Usage: #include "memmap.h" +// ... +// status = set_map_size (0x8000); +// +//####DESCRIPTIONEND#### + +#pragma warning (disable:4514) /* unreferenced inline function */ +#pragma warning (disable:4710) /* function not inlined */ + +// Includes other headers for precompiled compilation +#include "ecpch.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#include "memmap.h" + +using namespace std; + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +mem_map::mem_map() +{ + map_modified_flag = true; + map_size = (mem_address) 0; +} + +mem_map::~mem_map() +{ + +} + +mem_section::mem_section() +{ + +} + +mem_section::~mem_section() +{ + +} + +/////////////////////////////////////////////////////////////////////// +// get_memory_region() retrieves the parameters of a memory region + +bool mem_map::get_memory_region (std::string region_name, mem_address * region_address, mem_address * region_size, mem_type * region_type, std::string * note) +{ + for (list ::iterator region = region_list.begin (); region != region_list.end (); ++region) + if (region->name == region_name) + { + *region_address = region->address; + *region_size = region->size; + *region_type = region->type; + *note = region->note; + return true; + } + + return false; +} + + +/////////////////////////////////////////////////////////////////////// +// create_memory_region() inserts a new item into the memory region list +// in order of memory address + +int mem_map::create_memory_region (std::string new_region_name, mem_address new_region_address, mem_address new_region_size, mem_type new_region_type, std::string note) +{ + const mem_address new_region_end = new_region_address + new_region_size; // the byte after the new region end + + // check that the new region name is specified + + if (new_region_name == "") + return ERR_MEMMAP_REGION_NONAME; // the new region name must be specified + + // check that the new region lies within the memory map + + if (new_region_end > map_size) + return ERR_MEMMAP_REGION_MAPSIZE; // the new region does not lie within the memory map + + // check that the region end address hasn't exceeded the storage size + + if (new_region_end < new_region_address) + return ERR_MEMMAP_REGION_MAPSIZE; // the new region does not lie within the memory map + + // initialise the insertion point for the new region + + list ::iterator insertion_point = region_list.end (); + + // check that the new region does not overlap existing regions and does not already exist + + for (list ::iterator region = region_list.begin (); region != region_list.end (); ++region) + { + const mem_address region_end = region->address + region->size; // the byte after the region end + + if ((new_region_address >= region->address) && (new_region_address < region_end)) + { + error_info = region->name; + return ERR_MEMMAP_REGION_INTERSECT; // the start of the new region is within an existing region + } + + if ((new_region_end > region->address) && (new_region_end <= region_end)) + { + error_info = region->name; + return ERR_MEMMAP_REGION_INTERSECT; // the end of the new region is within an existing region + } + + if ((new_region_address < region->address) && (new_region_end > region_end)) + { + error_info = region->name; + return ERR_MEMMAP_REGION_INTERSECT; // an existing region lies within the new region + } + + if (region->name == new_region_name) + return ERR_MEMMAP_REGION_NAMEINUSE; // the new region name is not unique + + if ((insertion_point == region_list.end ()) && (region->address > new_region_address)) + insertion_point = region; // insert the new region here + } + + // add the new region to the region list + + list ::iterator new_region = region_list.insert (insertion_point); + new_region->name = new_region_name; + new_region->address = new_region_address; + new_region->size = new_region_size; + new_region->type = new_region_type; + new_region->note = note; + + // initialise the section list for the new region + + calc_section_list (new_region); + + map_modified_flag = true; + return 0; +} + + +/////////////////////////////////////////////////////////////////////// +// edit_memory_region() edits an item in the memory region list + +int mem_map::edit_memory_region (std::string old_region_name, std::string new_region_name, mem_address new_region_address, mem_address new_region_size, mem_type new_region_type, std::string note) +{ + list ::iterator edit_region = find_memory_region (old_region_name); + if (edit_region == NULL) + return ERR_MEMMAP_REGION_NOTFOUND; // the region to be modified does not exist + + // check that the new region name is specified + + if (new_region_name == "") + return ERR_MEMMAP_REGION_NONAME; // the new region name must be specified + + // check that the region end address hasn't exceeded the storage size + + if (new_region_address + new_region_size < new_region_address) + return ERR_MEMMAP_REGION_MAPSIZE; // the new region does not lie within the memory map + + // check region name change + + if ((old_region_name != new_region_name) && + (find_memory_region (new_region_name) != NULL)) + return ERR_MEMMAP_REGION_NAMEINUSE; // new region name is not unique + + // check region address/size change wrt other regions + + const mem_address new_region_end = new_region_address + new_region_size; + if ((new_region_address != edit_region->address) || + (new_region_size != edit_region->size)) + { + for (list ::iterator region = region_list.begin (); region != region_list.end (); ++region) + if (region != edit_region) + { + const mem_address region_end = region->address + region->size; // the byte after the region end + + if ((new_region_address >= region->address) && (new_region_address < region_end)) + { + error_info = region->name; + return ERR_MEMMAP_REGION_INTERSECT; // the start of the modified region is within another region + } + + if ((new_region_end > region->address) && (new_region_end <= region_end)) + { + error_info = region->name; + return ERR_MEMMAP_REGION_INTERSECT; // the end of the modified region is within an existing region + } + + if ((new_region_address < region->address) && (new_region_end > region_end)) + { + error_info = region->name; + return ERR_MEMMAP_REGION_INTERSECT; // another region lies within the modified region + } + } + } + + // check region size change wrt sections within region (if any) + + for (list ::iterator section_view = edit_region->section_view_list.begin (); section_view != edit_region->section_view_list.end (); ++section_view) + if (section_view->section != NULL) + { + if ((section_view->section_location == final_location) || (section_view->section_location == fixed_location)) + if (section_view->section->final_location->anchor == absolute) + if (section_view->section->final_location->address + section_view->section->size - edit_region->address > new_region_size) + return ERR_MEMMAP_REGION_SIZE; // region is now too small + + if (section_view->section_location == initial_location) + if (section_view->section->initial_location->anchor == absolute) + if (section_view->section->initial_location->address + section_view->section->size - edit_region->address > new_region_size) + return ERR_MEMMAP_REGION_SIZE; // region is now too small + } + + // check region read-only change FIXME + + // move sections within the region having absolute anchors + + for (section_view = edit_region->section_view_list.begin (); section_view != edit_region->section_view_list.end (); ++section_view) + if (section_view->section != NULL) + { + if ((section_view->section_location == final_location) || (section_view->section_location == fixed_location)) + if (section_view->section->final_location->anchor == absolute) + section_view->section->final_location->address += (new_region_address - edit_region->address); + + if ((section_view->section_location == initial_location) || (section_view->section_location == fixed_location)) + if (section_view->section->initial_location->anchor == absolute) + section_view->section->initial_location->address += (new_region_address - edit_region->address); + } + + // deleteZ(the region and recreate it to make sure the region list is ordered correctly) + + region_list.erase (edit_region); + if (create_memory_region (new_region_name, new_region_address, new_region_size, new_region_type, note)) + return ERR_MEMMAP_ALLOC; + + map_modified_flag = true; + return 0; +} + + +////////////////////////////////////////////////////////////////// +// delete_memory_region() removes an existing item from the memory +// region list + +bool mem_map::delete_memory_region (std::string name) +{ + // make sure that there are no used sections in this region before deleting it + + for (list ::iterator region = region_list.begin (); region != region_list.end (); ++region) + { + if ((region->name == name) && (region->section_view_list.size () == 1) && (region->section_view_list.front ().section == NULL)) + { + region_list.erase (region); + map_modified_flag = true; + return true; + } + } + + return false; +} + +/////////////////////////////////////////////////////////////////// +// set_map_size() sets the maximum permitted address for the end +// of any memory region + +bool mem_map::set_map_size (mem_address new_map_size) +{ + // check that the new size is sufficient for all previously defined memory regions + + for (list ::iterator region = region_list.begin (); region != region_list.end (); ++region) + { + if (region->address + region->size > new_map_size) + return false; // the new map size is too small + } + + // set the map size + + map_size = new_map_size; + + return true; +} + + +//////////////////////////////////////////////////////////////////// +// edit_memory_section() edits an item to the memory section map + +int mem_map::edit_memory_section (std::string old_section_name, std::string new_section_name, mem_address section_size, mem_address section_alignment, mem_anchor initial_section_anchor, std::string initial_anchor_section_name, mem_address initial_anchor_address, mem_anchor final_section_anchor, std::string final_anchor_section_name, mem_address final_anchor_address, bool relocates, bool anchor_to_initial_location, bool linker_defined, std::string note) +{ + // do all the parameter validation + + if (new_section_name == "") // the new section name must be specified + return ERR_MEMMAP_SECTION_NONAME; + + if ((new_section_name != old_section_name) && + (find_memory_section (new_section_name) != NULL)) + return ERR_MEMMAP_SECTION_NAMEINUSE; // the new section name is not unique + + list ::iterator section = find_memory_section (old_section_name); + if (section == NULL) + return ERR_MEMMAP_SECTION_NOTFOUND; // the specified old section name could not be found + + // check that the LMA (if absolute) is within a memory region + + list ::iterator region; + if (initial_section_anchor == absolute) + { + region = find_region_by_address (initial_anchor_address); + if (region == NULL) + return ERR_MEMMAP_SECTION_LMA_NOTINREGION; // section LMA is not within a memory region + if ((section_size > 0) && (initial_anchor_address + section_size > region->address + region->size)) + return ERR_MEMMAP_SECTION_LMA_NOTINREGION; // end of section is not within the memory region + if (relocates && (region->type == read_write)) + return ERR_MEMMAP_SECTION_LMA_READWRITE; // section LMA must be in a read-only memory region + } + + // check that the VMA (if absolute) is within a memory region + + if (final_section_anchor == absolute) + { + region = find_region_by_address (final_anchor_address); + if (region == NULL) + return ERR_MEMMAP_SECTION_VMA_NOTINREGION; // section VMA is not within a memory region + if ((section_size > 0) && (final_anchor_address + section_size > region->address + region->size)) + return ERR_MEMMAP_SECTION_VMA_NOTINREGION; // end of section is not within the memory region + if (relocates && (region->type == read_only)) + return ERR_MEMMAP_SECTION_VMA_READONLY; // section VMA must be in a read/write memory region + } + + // check relative location information as appropriate + + if (relocates) // only check the initial parent section if the section relocates + { + if (initial_section_anchor == relative) + { + list ::iterator parent_section = find_memory_section (initial_anchor_section_name); + if (parent_section == section_list.end ()) + return ERR_MEMMAP_SECTION_LMA_ANCHORNOTFOUND; // initial anchor name not found + + if ((parent_section->initial_location->following_section != section) && (parent_section->initial_location->following_section != NULL)) + return ERR_MEMMAP_SECTION_LMA_ANCHORNOTAVAIL; // initial anchor specified has changed and is unavailable + + if ((parent_section->size == 0) && (! parent_section->linker_defined)) + return ERR_MEMMAP_SECTION_LMA_ANCHORNOTAVAIL; // initial anchor specified expands to fit available space + + if (find_region_by_section (parent_section, initial_location)->type == read_write) + return ERR_MEMMAP_SECTION_LMA_READWRITE; // initial anchor must be in a read-only memory region + } + } + + if (final_section_anchor == relative) + { + list ::iterator parent_section = find_memory_section (final_anchor_section_name); + if (parent_section == NULL) + return ERR_MEMMAP_SECTION_VMA_ANCHORNOTFOUND; // final anchor name not found + + if ((parent_section->size == 0) && (! parent_section->linker_defined)) + return ERR_MEMMAP_SECTION_VMA_ANCHORNOTAVAIL; // final anchor specified expands to fit available space + + if ((!relocates) && anchor_to_initial_location) // final anchor to initial location of parent section + { + if ((parent_section->initial_location->following_section != section) && (parent_section->initial_location->following_section != NULL)) + return ERR_MEMMAP_SECTION_VMA_ANCHORNOTAVAIL; // final anchor specified has changed and is unavailable + } + else + { + if ((parent_section->final_location->following_section != section) && (parent_section->final_location->following_section != NULL)) + return ERR_MEMMAP_SECTION_VMA_ANCHORNOTAVAIL; // final anchor specified has changed and is unavailable + } + + if (relocates && (find_region_by_section (parent_section, final_location)->type == read_only)) + return ERR_MEMMAP_SECTION_VMA_READONLY; // final anchor of relocating section must be in a read/write memory region + } + + // check for a non-relocating section changing to relocating where the final + // location moves from a read_only region to a read_write region and there + // is a following non-relocating section + + if (relocates && (! section->relocates) && + (find_region_by_section (section, fixed_location)->type == read_only) && + (section->final_location->following_section != NULL) && + (! section->final_location->following_section->relocates)) + { + return ERR_MEMMAP_SECTION_ILLEGAL_RELOCATION; + } + + // FIXME check for overlap of absolute sections + + // modify the initial section location data + + if (section->initial_location->anchor == relative) // initial section anchor was relative + find_preceding_section (section, true)->initial_location->following_section = NULL; + + if (initial_section_anchor == absolute) // initial location now absolute + section->initial_location->address = initial_anchor_address; + else // initial location now relative + { + list ::iterator initial_parent = find_memory_section (initial_anchor_section_name); + if (relocates || (! initial_parent->relocates)) + initial_parent->initial_location->following_section = section; + } + + // modify the final section location data + + if (section->final_location->anchor == relative) // final section anchor was relative + find_preceding_section (section, false)->final_location->following_section = NULL; + + if (final_section_anchor == absolute) // final location now absolute + section->final_location->address = final_anchor_address; + else // final location now relative + { + list ::iterator final_parent = find_memory_section (final_anchor_section_name); + final_parent->final_location->following_section = section; + } + + // handle relocation changes + + if (relocates && (! section->relocates)) // section was non-relocating but now relocates + { + if (find_region_by_section (section, fixed_location)->type == read_only) // the section was in a read_only region + section->final_location->following_section = NULL; // there is now no section following the final location + else + section->initial_location->following_section = NULL; // there is now no section following the initial location + } + + else if ((! relocates) && section->relocates) // section was relocating but is now non-relocating + { + // determine the type of memory region in which the section now resides + + mem_type type; + if ((final_section_anchor == relative) && anchor_to_initial_location) + type = find_region_by_section (find_memory_section (final_anchor_section_name), initial_location)->type; + else if (final_section_anchor == relative) // anchored to final location of preceding section + type = find_region_by_section (find_memory_section (final_anchor_section_name), final_location)->type; + else // final_section_anchor must be absolute + type = find_region_by_address (final_anchor_address)->type; + + if (type == read_only) // the section is now in a read-only memory region + { + if ((section->initial_location->following_section != NULL) && ! section->initial_location->following_section->relocates) + section->final_location->following_section = section->initial_location->following_section; + else + section->final_location->following_section = NULL; + } + else // the section is now in a read-write memory region + { + if ((section->final_location->following_section != NULL) && ! section->final_location->following_section->relocates) + section->initial_location->following_section = section->final_location->following_section; + else + section->initial_location->following_section = NULL; + } + } + + // modify the remaining section data + + section->name = new_section_name; + section->size = section_size; + section->alignment = section_alignment; + section->relocates = relocates; + section->note = note; + section->linker_defined = linker_defined; + section->initial_location->anchor = initial_section_anchor; + section->final_location->anchor = final_section_anchor; + + // recalculate section lists for all regions + + calc_section_lists (); + + map_modified_flag = true; + return 0; +} + + +//////////////////////////////////////////////////////////////////// +// create_memory_section() adds a new item to the memory section map +// either a section name (for relative locations) or an anchor address +// (for absolute locations) must be specified + +int mem_map::create_memory_section (std::string section_name, mem_address section_size, mem_address section_alignment, mem_anchor initial_section_anchor, std::string initial_anchor_section_name, mem_address initial_anchor_address, mem_anchor final_section_anchor, std::string final_anchor_section_name, mem_address final_anchor_address, bool relocates, bool anchor_to_initial_location, bool linker_defined, std::string note) +{ + list ::iterator region; + + // check that the new section name is specified + + if (section_name == "") + return ERR_MEMMAP_SECTION_NONAME; // the new section name must be specified + + // check that the new section name is unique + + if (find_memory_section (section_name) != NULL) + return ERR_MEMMAP_SECTION_NAMEINUSE; // the new section name is not unique + + // check that the LMA (if absolute) is within a memory region + + if (initial_section_anchor == absolute) + { + region = find_region_by_address (initial_anchor_address); + if (region == NULL) + return ERR_MEMMAP_SECTION_LMA_NOTINREGION; // section LMA is not within a memory region + if ((section_size > 0) && (initial_anchor_address + section_size > region->address + region->size)) + return ERR_MEMMAP_SECTION_LMA_NOTINREGION; // end of section is not within the memory region + if (relocates && (region->type == read_write)) + return ERR_MEMMAP_SECTION_LMA_READWRITE; // section LMA must be in a read-only memory region + } + + // check that the VMA (if absolute) is within a memory region + + if (final_section_anchor == absolute) + { + region = find_region_by_address (final_anchor_address); + if (region == NULL) + return ERR_MEMMAP_SECTION_VMA_NOTINREGION; // section VMA is not within a memory region + if ((section_size > 0) && (final_anchor_address + section_size > region->address + region->size)) + return ERR_MEMMAP_SECTION_VMA_NOTINREGION; // end of section is not within the memory region + if (relocates && (region->type == read_only)) + return ERR_MEMMAP_SECTION_VMA_READONLY; // section VMA must be in a read/write memory region + } + + // FIXME check for overlap of absolute sections + + // check that specified parent(s) (for relative anchors) are available + + if (relocates) // only check the initial parent section if the section relocates + { + if (initial_section_anchor == relative) + { + list ::iterator parent_section = find_memory_section (initial_anchor_section_name); + if (parent_section == section_list.end ()) + return ERR_MEMMAP_SECTION_LMA_ANCHORNOTFOUND; // initial anchor name not found +/* + if (parent_section->initial_location->following_section != NULL) + return ERR_MEMMAP_SECTION_LMA_ANCHORNOTAVAIL; // initial anchor specified is unavailable +*/ + if ((parent_section->size == 0) && (! parent_section->linker_defined)) + return ERR_MEMMAP_SECTION_LMA_ANCHORNOTAVAIL; // initial anchor specified expands to fit available space + + if (find_region_by_section (parent_section, initial_location)->type == read_write) + return ERR_MEMMAP_SECTION_LMA_READWRITE; // initial anchor must be in a read-only memory region + } + } + + if (final_section_anchor == relative) + { + list ::iterator parent_section = find_memory_section (final_anchor_section_name); + if (parent_section == NULL) + return ERR_MEMMAP_SECTION_VMA_ANCHORNOTFOUND; // final anchor name not found + + if ((parent_section->size == 0) && (! parent_section->linker_defined)) + return ERR_MEMMAP_SECTION_VMA_ANCHORNOTAVAIL; // final anchor specified expands to fit available space +/* + if ((!relocates) && anchor_to_initial_location) // final anchor to initial location of parent section + { + if (parent_section->initial_location->following_section != NULL) + return ERR_MEMMAP_SECTION_VMA_ANCHORNOTAVAIL; // final anchor specified is unavailable + } + else + { + if (parent_section->final_location->following_section != NULL) + return ERR_MEMMAP_SECTION_VMA_ANCHORNOTAVAIL; // final anchor specified is unavailable + } +*/ + if (relocates && (find_region_by_section (parent_section, final_location)->type == read_only)) + return ERR_MEMMAP_SECTION_VMA_READONLY; // final anchor of relocating section must be in a read/write memory region + } + + // add the new section to the section map + + mem_section new_mem_section; + list ::iterator new_section = section_list.insert (section_list.begin (), new_mem_section); + new_section->name = section_name; + new_section->size = section_size; + new_section->alignment = section_alignment; + new_section->relocates = relocates; + new_section->note = note; + new_section->linker_defined = linker_defined; + new_section->initial_location = new mem_location; + new_section->final_location = new mem_location; + new_section->initial_location->following_section = NULL; // initialize struct + new_section->final_location->following_section = NULL; // initialize struct + new_section->initial_location->anchor = initial_section_anchor; + new_section->final_location->anchor = final_section_anchor; + + if ((initial_section_anchor == relative) && + (!relocates) && (find_memory_section (initial_anchor_section_name)->relocates)) + { + // a non-relocating relative section anchored to a relocating section + + if (anchor_to_initial_location) // new section is anchored to the initial location of a relocating section + { + list ::iterator anchor_section = find_memory_section (initial_anchor_section_name); + new_section->initial_location->following_section = anchor_section->initial_location->following_section; + anchor_section->initial_location->following_section = new_section; + } + else // new section is anchored to the final location of a relocating section + { + list ::iterator anchor_section = find_memory_section (initial_anchor_section_name); + new_section->final_location->following_section = anchor_section->final_location->following_section; + anchor_section->final_location->following_section = new_section; + } + } + else + { + // copy initial location data + + if (initial_section_anchor == relative) // new section follows the named anchor section + { + list ::iterator anchor_section = find_memory_section (initial_anchor_section_name); + new_section->initial_location->following_section = anchor_section->initial_location->following_section; // move anchor of the following section + anchor_section->initial_location->following_section = new_section; // anchor the new section + } + else // new section has an absolute anchor + new_section->initial_location->address = initial_anchor_address; + + // copy final location data + + if (final_section_anchor == relative) // new section follows the named anchor section + { + list ::iterator anchor_section = find_memory_section (final_anchor_section_name); + new_section->final_location->following_section = anchor_section->final_location->following_section; // move anchor of the following section + anchor_section->final_location->following_section = new_section; // anchor the new section + } + else // new section has an absolute anchor + new_section->final_location->address = final_anchor_address; + } + + // recalculate section lists for all regions + + calc_section_lists (); + + map_modified_flag = true; + return 0; +} + + +//////////////////////////////////////////////////////////////////////// +// calc_section_lists() updates the lists of memory sections for all +// memory regions + +bool mem_map::calc_section_lists () +{ + for (list ::iterator region = region_list.begin (); region != region_list.end(); ++region) + calc_section_list (region); + + return true; +} + + +//////////////////////////////////////////////////////////////////////// +// calc_section_list() updates the list of memory sections which reside +// in the specified memory region. It is called whenever the section +// map is modified. + +bool mem_map::calc_section_list (list ::iterator region) +{ + // clear the old list (if any) + + //TRACE (_T("Calculating section list for region '%s'\n"), CString (region->name.c_str())); + region->section_view_list.clear (); + + // add the initial and final locations of each absolute section as necessary + + for (list ::iterator section = section_list.begin (); section != section_list.end (); ++section) + { + if (section->relocates) // the section is relocated and must be added to the view twice + { + add_absolute_section_to_list (region, section, initial_location); + add_absolute_section_to_list (region, section, final_location); + } + else // the section is not relocated and must be added to the view once only + add_absolute_section_to_list (region, section, fixed_location); + } + + // add unused sections to section view list where appropriate + + list ::iterator previous_section_view = region->section_view_list.begin (); + + if (previous_section_view == region->section_view_list.end ()) // no used sections in this region + { + // add a single unused section to the section view list + + mem_section_view new_section_view; + new_section_view.section = NULL; // an unused section + region->section_view_list.push_back (new_section_view); // add to the section list for this region + } + else // there are used sections in this region + { + list ::iterator second_section_view = region->section_view_list.begin (); + ++second_section_view; + + // add unused sections between used sections where they do not meet in either initial or final locations + + for (list ::iterator section_view = second_section_view; section_view != region->section_view_list.end (); ++section_view) + { + if (! (absolute_sections_meet (previous_section_view->section, section_view->section))) + { + list ::iterator new_section_view = region->section_view_list.insert (section_view); // add an unused section + new_section_view->section = NULL; + } + + previous_section_view = section_view; + } + + // add an unused section to end of region if the last section does not reach the end of the region in initial or final locations + + if (! at_end_of_region (region->section_view_list.back().section, region)) + { + mem_section_view new_section_view; + new_section_view.section = NULL; // an unused section + region->section_view_list.push_back (new_section_view); // add an unused section + } + + // add an unused section to start of region if the first section does not start at the start of the region in initial or final locations + + if (! at_start_of_region (region->section_view_list.front().section, region)) + { + mem_section_view new_section_view; + new_section_view.section = NULL; // an unused section + region->section_view_list.push_front (new_section_view); // add an unused section + } + } + + // add the initial and final locations of the each relative section as necessary + + for (list ::iterator section_view = region->section_view_list.begin (); section_view != region->section_view_list.end (); ++section_view) + if (section_view->section != NULL) // if section is used + { + list ::iterator section = section_view->section; +/* + TRACE (_T("Calculating relative sections for section view '%s' %s\n"), CString (section->name.c_str ()), + section_view->section_location == final_location ? _T("(final)") : + section_view->section_location == initial_location ? _T("(initial)") : _T("(fixed)")); +*/ + + if (section_view->section_location == final_location) + { + if (section->final_location->anchor == absolute) + add_relative_sections_to_list (region, section_view, final_location); + } + + else if (section_view->section_location == initial_location) + { + if (section->initial_location->anchor == absolute) + add_relative_sections_to_list (region, section_view, initial_location); + } + + else // section_view->section_location == fixed_location + { + if (section->initial_location->anchor == absolute) + add_relative_sections_to_list (region, section_view, initial_location); + if (section->final_location->anchor == absolute) + add_relative_sections_to_list (region, section_view, final_location); + } + } + + // remove unused sections where user-defined section of unknown size will be placed + + section_view = region->section_view_list.begin (); + while (section_view != region->section_view_list.end ()) + { + bool expanding_section = false; + if ((section_view->section != NULL) && + (section_view->section->size == 0) && + (! section_view->section->linker_defined)) + expanding_section = true; + + ++section_view; + + if (expanding_section && (section_view != region->section_view_list.end ()) && (section_view->section == NULL)) + section_view = region->section_view_list.erase (section_view); + } + + return true; +} + +///////////////////////////////////////////////////////////////////// +// add_relative_sections_to_list() inserts the sections defined relative +// to the specified section list item to the section list for the +// specified region in the appropriate order + +bool mem_map::add_relative_sections_to_list (list ::iterator region, list ::iterator section_view, section_location_type location_type) +{ + // insert following relative sections of type 'location_type' in region_view.section_view_list + + list ::iterator new_section = section_view->section; + mem_location * new_section_location = (location_type == initial_location ? new_section->initial_location : new_section->final_location); + list ::iterator insertion_point = section_view; + ++insertion_point; + bool no_relocation = true; + + while (new_section_location->following_section != NULL) + { + // add the new section to the section view list + + mem_section_view new_section_view; + new_section_view.section = new_section_location->following_section; + const bool section_relocates = new_section->relocates; + new_section = new_section_view.section; + new_section_view.section_location = (new_section->relocates ? location_type : fixed_location); + if ((new_section_view.section_location == fixed_location) && (location_type == final_location) && (! section_view->section->relocates) && (! section_relocates) && no_relocation) + { + // section already added to the view so add nothing but + // increment insertion point for following sections + // TRACE (_T("Skipping section %s %s location (relative) preceding %s\n"), CString (new_section_location->following_section->name.c_str()), location_type == initial_location ? _T("initial") : _T("final"), ((insertion_point != region->section_view_list.end ()) && (insertion_point->section != NULL)) ? CString (insertion_point->section->name.c_str()) : _T("(null)")); + ++insertion_point; + } + else + { + // TRACE (_T("Inserting section %s %s location (relative) preceding %s\n"), CString (new_section_location->following_section->name.c_str()), location_type == initial_location ? _T("initial") : _T("final"), ((insertion_point != region->section_view_list.end ()) && (insertion_point->section != NULL)) ? CString (insertion_point->section->name.c_str()) : _T("(null)")); + region->section_view_list.insert (insertion_point, new_section_view); + no_relocation = no_relocation && ! new_section_view.section->relocates; + } + new_section_location = (location_type == initial_location ? new_section->initial_location : new_section->final_location); + } + + return true; +} + +///////////////////////////////////////////////////////////////////// +// add_absolute_section_to_list() inserts the specified section to the +// specified section list at the appropriate place if it has an +// absolute location and that location is within the specified memory +// region + +bool mem_map::add_absolute_section_to_list (list ::iterator region, list ::iterator additional_section, section_location_type location_type) +{ + // get location of new section + mem_location * new_section_location = (location_type == initial_location ? additional_section->initial_location : additional_section->final_location); + + if ((new_section_location->anchor == absolute) && (new_section_location->address >= region->address) && (new_section_location->address < region->address + region->size)) + { + // the section lies in the region + + // initialise the insertion point for the new section + list ::iterator insertion_point = region->section_view_list.end (); + + for (list ::iterator section = region->section_view_list.begin (); section != region->section_view_list.end (); ++section) + { + // get location of section + mem_location * section_location = (section->section_location == initial_location ? section->section->initial_location : section->section->final_location); + + // compare with location of new section + if ((new_section_location->anchor == absolute) && (section_location->address >= new_section_location->address)) + { + // insert new section here if the current section has a higher address + insertion_point = section; + break; + } + } + + // add the new section to the section view list + + // TRACE (_T("Inserting section %s %s location (absolute) preceding %s\n"), CString (additional_section->name.c_str()), location_type == initial_location ? _T("initial") : _T("final"), insertion_point != region->section_view_list.end () ? CString (insertion_point->section->name.c_str()) : _T("(end)")); + mem_section_view new_section_view; + new_section_view.section = additional_section; + new_section_view.section_location = location_type; + region->section_view_list.insert (insertion_point, new_section_view); + } + + return true; +} + + +//////////////////////////////////////////////////////////////////// +// absolute_sections_meet() determines whether the specified +// absolute memory sections meet. It assumes that section2 comes +// after section1 in the memory map. + +bool mem_map::absolute_sections_meet(list ::iterator section1, list ::iterator section2) +{ + if (section1->size == 0) // size of section1 is unknown + return false; + + // check if initial section locations meet + + if ((section1->initial_location->anchor == absolute) && + ((section2->initial_location->anchor == absolute) && + section1->initial_location->address + section1->size == section2->initial_location->address)) + return true; + + // check if final section locations meet + + if ((section1->final_location->anchor == absolute) && + ((section2->final_location->anchor == absolute) && + section1->final_location->address + section1->size == section2->final_location->address)) + return true; + + return false; +} + + +////////////////////////////////////////////////////////////// +// at_start_of_region() determines whether the specified section +// is located at the very start of the specified region + +bool mem_map::at_start_of_region (list ::iterator section, list ::iterator region) +{ + // check initial section location + + if ((section->initial_location->anchor == absolute) && + (section->initial_location->address == region->address)) + return true; + + // check final section location + + if ((section->final_location->anchor == absolute) && + (section->final_location->address == region->address)) + return true; + + return false; +} + +////////////////////////////////////////////////////////////// +// at_end_of_region() determines whether the specified section +// is located at the very end of the specified region + +bool mem_map::at_end_of_region (list ::iterator section, list ::iterator region) +{ + if (section->size == 0) // size of section is unknown + return false; + + // check initial section location + + if ((section->initial_location->anchor == absolute) && + section->initial_location->address + section->size == region->address + region->size) + return true; + + // check final section location + + if ((section->final_location->anchor == absolute) && + section->final_location->address + section->size == region->address + region->size) + return true; + + return false; +} + +//////////////////////////////////////////////////////////////////////// +// find_preceding_section() finds the preceding section in the +// memory section list + +list ::iterator mem_map::find_preceding_section (list ::iterator reference_section, bool initial_location) +{ + for (list ::iterator section = section_list.begin (); section != section_list.end (); ++section) + { + if (reference_section == (reference_section->relocates && initial_location ? section->initial_location->following_section : section->final_location->following_section)) // if preceding section found + return section; // return the section iterator + } + return NULL; // section not found +} + +//////////////////////////////////////////////////////////////////////// +// find_memory_section() finds an existing section in the +// memory section list + +list ::iterator mem_map::find_memory_section (std::string section_name) +{ + for (list ::iterator section = section_list.begin (); section != section_list.end (); ++section) + if (section->name == section_name) // if section found + return section; // return the section iterator + + return NULL; // section not found +} + + +//////////////////////////////////////////////////////////////////////// +// find_memory_region() finds an existing region in the +// memory region list + +list ::iterator mem_map::find_memory_region (std::string region_name) +{ + for (list ::iterator region = region_list.begin (); region != region_list.end (); ++region) + if (region->name == region_name) // if region found + return region; // return the region iterator + + return NULL; // region not found +} + + +//////////////////////////////////////////////////////////////////////// +// delete_memory_section() removes an existing item from the +// memory section map + +bool mem_map::delete_memory_section (std::string name) +{ + // make sure that the section exists + + list ::iterator section = find_memory_section (name); + if (section == NULL) + return false; // there is no section with this name + +/* + // make sure that there are no sections defined relative to this section before deleting it + + if (section->initial_location->following_section != NULL) + return false; + + if (section->final_location->following_section != NULL) + return false; +*/ + + // if section is absolute, copy the initial and final location information to + // the following sections (if any) + + if ((section->initial_location->anchor == absolute) && (section->initial_location->following_section != NULL)) + { + section->initial_location->following_section->initial_location->anchor = absolute; + section->initial_location->following_section->initial_location->address = section->initial_location->address; + // FIXME adjust new address of following section for alignment here + } + + if ((section->final_location->anchor == absolute) && (section->final_location->following_section != NULL)) + { + section->final_location->following_section->final_location->anchor = absolute; + section->final_location->following_section->final_location->address = section->final_location->address; + // FIXME adjust new address of following section for alignment here + } + + // if section is relative, find the initial and final sections to which it is attached + // and set their pointers to the sections following the one to be deleted (if any) + + list ::iterator related_section; + + if (section->initial_location->anchor == relative) + for (related_section = section_list.begin (); related_section != section_list.end (); ++related_section) + if (related_section->initial_location->following_section == section) + related_section->initial_location->following_section = section->initial_location->following_section; + + if (section->final_location->anchor == relative) + for (related_section = section_list.begin (); related_section != section_list.end (); ++related_section) + if (related_section->final_location->following_section == section) + related_section->final_location->following_section = section->final_location->following_section; + + // delete the section + + delete section->initial_location; + section->initial_location = NULL; + + delete section->final_location; + section->final_location = NULL; + + section_list.erase (section); + + // recalculate section lists for all regions + + calc_section_lists (); + + map_modified_flag = true; + return true; +} + + +//////////////////////////////////////////////////////////////////////// +// delete_memory_sections() deletes all memory sections in preparation +// for layout loading or application closure + +bool mem_map::delete_all_memory_sections () +{ + // deleteZ(each section in turn) + + while (section_list.size () > 0) + { + list ::iterator section = section_list.begin (); + delete section->initial_location; + section->initial_location = NULL; + + delete section->final_location; + section->final_location = NULL; + + section_list.erase (section); + } +// section_list.clear (); + + // recalculate section view lists for all regions + + calc_section_lists (); + + map_modified_flag = true; + return true; +} + + +//////////////////////////////////////////////////////////////////////// +// export_sections() exports section-related info for regions of the +// specified type to the linker script fragment and header file + +bool mem_map::export_sections (FILE * script_stream, FILE * header_stream, mem_type type) +{ + for (list ::iterator region = region_list.begin (); region != region_list.end(); ++region) + if (region->type == type) + { + for (list ::iterator section_view = region->section_view_list.begin (); section_view != region->section_view_list.end (); ++section_view) + { + if ((section_view->section != NULL) && (section_view->section_location != initial_location)) + { + if (section_view->section->linker_defined) // section is linker-defined + { + // output section name and region name + fprintf (script_stream, " SECTION_%s (%s, ", + encode_section_name (section_view->section->name).c_str (), region->name.c_str ()); + + // output VMA + if (section_view->section->final_location->anchor == absolute) // an absolute VMA + fprintf (script_stream, "%#lx, ", section_view->section->final_location->address); // specify absolute address + else // a relative VMA + fprintf (script_stream, "ALIGN (%#lx), ", section_view->section->alignment); // specify alignment + + // output LMA + if (! section_view->section->relocates) // section does not relocate so LMA == VMA + fprintf (script_stream, "LMA_EQ_VMA)"); + else if (section_view->section->initial_location->anchor == absolute) // an absolute LMA + fprintf (script_stream, "AT (%#lx))", section_view->section->initial_location->address); + else // a relative LMA + { + list ::iterator parent_section; + for (parent_section = section_list.begin (); parent_section != section_list.end (); ++parent_section) + if (parent_section->initial_location->following_section == section_view->section) + break; + + if (parent_section->linker_defined) // parent section is linker-defined + fprintf (script_stream, "FOLLOWING (.%s))", parent_section->name.c_str ()); + else // parent section is user-defined + fprintf (script_stream, "AT (__%s + %#lx))", parent_section->name.c_str (), parent_section->size); + } + } + else // section is user-defined + { + // output section symbol + if (section_view->section->final_location->anchor == absolute) // an absolute VMA + fprintf (script_stream, " CYG_LABEL_DEFN(__%s) = %#lx;", section_view->section->name.c_str (), section_view->section->final_location->address); + else // a relative VMA + fprintf (script_stream, " CYG_LABEL_DEFN(__%s) = ALIGN (%#lx);", section_view->section->name.c_str (), section_view->section->alignment); + + // update current location pointer + if (section_view->section->size != 0) // size is known + fprintf (script_stream, " . = CYG_LABEL_DEFN(__%s) + %#lx;", section_view->section->name.c_str (), section_view->section->size); + + // output reference to symbol in header file + fprintf (header_stream, "#ifndef __ASSEMBLER__\nextern char CYG_LABEL_NAME (__%s) [];\n#endif\n", section_view->section->name.c_str ()); + fprintf (header_stream, "#define CYGMEM_SECTION_%s (CYG_LABEL_NAME (__%s))\n", section_view->section->name.c_str (), section_view->section->name.c_str ()); + if (section_view->section->size == 0) // a section of unknown size + { + mem_address section_end_address; + + ++section_view; // move to next section_view + if (section_view == region->section_view_list.end ()) // section continues to end of region + section_end_address = region->address + region->size; + else // section continues to next section with an absolute location + section_end_address = section_view->section->final_location->address; + --section_view; // move back to previous section view + + fprintf (header_stream, "#define CYGMEM_SECTION_%s_SIZE (%#lx - (size_t) CYG_LABEL_NAME (__%s))\n", section_view->section->name.c_str (), section_end_address, section_view->section->name.c_str ()); + } + else // a section of known size + fprintf (header_stream, "#define CYGMEM_SECTION_%s_SIZE (%#lx)\n", section_view->section->name.c_str (), section_view->section->size); + } + + // end of section description + + fprintf (script_stream, "\n"); // new line + } + } + } + return true; +} + + +//////////////////////////////////////////////////////////////////////// +// export_files() creates a fragment of linker script and a header file +// describing the memory layout + +bool mem_map::export_files (const wxChar* script_name, const wxChar* header_name) +{ + FILE * script_stream; + FILE * header_stream; + list ::iterator region; + + // do not export files if the memory layout is empty + // assume that there are default LDI files available + + if (region_list.size () == 0) + return false; + + // open the script fragment file for writing + + script_stream = _tfopen (script_name, _T("wt")); + if (script_stream == NULL) + return false; + + // open the header file for writing + + header_stream = _tfopen (header_name, _T("wt")); + if (header_stream == NULL) + { + fclose (script_stream); + return false; + } + + // output the linker script fragment header + + time_t export_time; + time (&export_time); + struct tm * local = localtime (&export_time); + fprintf (script_stream, "// eCos memory layout - %s\n%s\n\n", asctime (local), MLT_GENERATED_WARNING); + fprintf (script_stream, "#include \n\n"); + + // output the header file header + + fprintf (header_stream, "// eCos memory layout - %s\n%s\n\n", asctime (local), MLT_GENERATED_WARNING); + fprintf (header_stream, "#ifndef __ASSEMBLER__\n"); + fprintf (header_stream, "#include \n"); // for the CYG_LABEL_NAME macro definition + fprintf (header_stream, "#include \n\n"); // for size_t + fprintf (header_stream, "#endif\n"); + + // output the MEMORY block + + fprintf (script_stream, "MEMORY\n{\n"); // start of MEMORY block + for (region = region_list.begin (); region != region_list.end(); ++region) + { + fprintf (script_stream, " %s : ORIGIN = %#lx, LENGTH = %#lx\n", region->name.c_str(), region->address, region->size); + fprintf (header_stream, "#define CYGMEM_REGION_%s (%#lx)\n", region->name.c_str(), region->address); + fprintf (header_stream, "#define CYGMEM_REGION_%s_SIZE (%#lx)\n", region->name.c_str(), region->size); + fprintf (header_stream, "#define CYGMEM_REGION_%s_ATTR (CYGMEM_REGION_ATTR_R%s)\n", region->name.c_str(), (read_write == region->type) ? " | CYGMEM_REGION_ATTR_W" : ""); + } + fprintf (script_stream, "}\n\n"); // end of MEMORY block + + // output the SECTIONS block + + fprintf (script_stream, "SECTIONS\n{\n"); // start of SECTIONS block + fprintf (script_stream, " SECTIONS_BEGIN\n"); // SECTIONS block initial script macro call + export_sections (script_stream, header_stream, read_only); // export sections in read-only regions first + export_sections (script_stream, header_stream, read_write); // followed by sections in read-write regions + fprintf (script_stream, " SECTIONS_END\n"); // SECTIONS block final script macro call + fprintf (script_stream, "}\n"); // end of SECTIONS block + + // close the files + + fclose (script_stream); + fclose (header_stream); + + return true; +} + + +//////////////////////////////////////////////////////////////////////// +// import_linker_defined_sections() reads a the linker-defined section +// names from the "SECTION_*" CPP macro definitions within the linker +// script + +bool mem_map::import_linker_defined_sections (const wxChar* filename) +{ + // clear the linker-defined section name list + + linker_defined_section_list.clear (); + + // open the linker script file for reading + + FILE * stream; + stream = _tfopen (filename, _T("rt")); + if (stream == NULL) + return false; + + bool macro = false; // not reading a CPP macro definition initially + char input_string [32]; + while (! feof (stream)) + { + if (macro) + { + if (fscanf (stream, "%8s", input_string) == EOF) // read the next 8 chars (not including whitespace) + break; + + if (strcmp (input_string, "SECTION_") == 0) // an MLT section macro definition + { + if (fscanf (stream, "%31[^(]", input_string) == EOF) // read the section name up to the '(' character + break; + + std::string section_name = decode_section_name (input_string); + if (find (linker_defined_section_list.begin (), linker_defined_section_list.end (), section_name) == linker_defined_section_list.end ()) // if section name is unique + linker_defined_section_list.push_back (section_name); + } + + macro = false; + } + + else + { + if (fscanf (stream, "%31s", input_string) == EOF) + break; + + if (strcmp (input_string, "#define") == 0) + macro = true; // macro starts with "#define" + } + + } + + // close the file + + if (fclose (stream)) + return false; + + return true; +} + +//////////////////////////////////////////////////////////////////////// +// encode_note() encodes newlines in note + +std::string mem_map::encode_note (std::string in) +{ + std::string out = "!"; // dummy first character to ensure output string length > 0 + + for (unsigned int item = 0; item < in.size (); item++) + if (in [item] == _TCHAR('\n')) // an LF character + out += "\x07F"; // output substitution character 0x7F instead + else if (in [item] != _TCHAR('\r')) // ignore the CR (present under Win32 only) + out += in [item]; // copy other characters to output string unprocessed + + return out; +} + +//////////////////////////////////////////////////////////////////////// +// decode_note() decodes newlines in note + +std::string mem_map::decode_note (std::string in) +{ + std::string out; + + for (unsigned int item = 1; item < in.size (); item++) // ignore dummy first character + if (in [item] == _TCHAR('\x07F')) // the newline substitution character + out += "\r\n"; // output CRLF instead + else + out += in [item]; + + return out; +} + +//////////////////////////////////////////////////////////////////////// +// encode_section_name() encodes period -> double underscore in section name + +std::string mem_map::encode_section_name (std::string in) +{ + std::string out; + + for (unsigned int item = 0; item < in.size (); item++) + if (in [item] == '.') // a period character + out += "__"; // output a double underscore instead + else + out += in [item]; + + return out; +} + +//////////////////////////////////////////////////////////////////////// +// decode_section_name() decodes double underscore -> period in section name + +std::string mem_map::decode_section_name (std::string in) +{ + std::string out; + + for (unsigned int item = 0; item < in.size (); item++) + if ((item + 1 < in.size ()) && (in [item] == '_') && (in [item + 1] == '_')) // two consecutive underscore characters + { + out += "."; // output a period instead + item++; // skip the second underscore + } + else + out += in [item]; + + return out; +} + +//////////////////////////////////////////////////////////////////////// +// save_memory_layout() saves the memory layout to file for later use + +bool mem_map::save_memory_layout (const wxChar* filename) +{ + FILE * stream; + list ::iterator region; + + // open the save file for writing + + stream = _tfopen (filename, _T("wt")); + if (stream == NULL) + return false; + + // write the save file format version number + + fprintf (stream, "version %u\n", (unsigned int) MLT_FILE_VERSION); + + // save the memory region data in address order + + for (region = region_list.begin (); region != region_list.end (); ++region) + fprintf (stream, "region %s %lx %lx %d %s\n", region->name.c_str (), + region->address, region->size, (region->type == read_only), encode_note (region->note).c_str ()); + + // save the memory section data in VMA order + + for (region = region_list.begin (); region != region_list.end(); ++region) + { + for (list ::iterator section_view = region->section_view_list.begin (); section_view != region->section_view_list.end (); ++section_view) + { + if ((section_view->section != NULL) && (section_view->section_location != initial_location)) + { + list ::iterator section = section_view->section; + fprintf (stream, "section %s %lx %lx %d %d %d %d %d %d", + section->name.c_str (), section->size, section->alignment, + section->relocates, section->linker_defined, + section->final_location->anchor == absolute, + section->final_location->following_section != NULL, + section->initial_location->anchor == absolute, + section->initial_location->following_section != NULL); + + if (section->final_location->anchor == absolute) + fprintf (stream, " %lx", section->final_location->address); + + if (section->initial_location->anchor == absolute) + fprintf (stream, " %lx", section->initial_location->address); + + if (section->final_location->following_section != NULL) + fprintf (stream, " %s", section->final_location->following_section->name.c_str ()); + + if (section->initial_location->following_section != NULL) + fprintf (stream, " %s", section->initial_location->following_section->name.c_str ()); + + fprintf (stream, " %s", encode_note (section->note).c_str ()); + + // end of section description + + fprintf (stream, "\n"); // new line + } + } + } + + // close the file + + if (fclose (stream)) + return false; + + map_modified_flag = false; + return true; +} + + +//////////////////////////////////////////////////////////////////////// +// load_memory_layout() loads a previously saved memory layout from file + +bool mem_map::load_memory_layout (const wxChar* filename) +{ + FILE * stream; + + // open the save file for reading + + stream = _tfopen (filename, _T("rt")); + if (stream == NULL) + return false; + + // read the file version + + unsigned int file_version; + if ((fscanf (stream, "%*s %u", &file_version) != 1) || + (file_version != MLT_FILE_VERSION)) + { + fclose (stream); // missing or incorrect file version + return false; + } + + new_memory_layout (); + + // read the new memory layout (first pass) + + while (! feof (stream)) + { + char record_type [32]; + if (fscanf (stream, "%31s", record_type) == EOF) + break; + + if (strcmp (record_type, "section") == 0) // a section record + { + if (! load_memory_section_1 (stream)) + break; + } + else if (strcmp (record_type, "region") == 0) // a region record + { + mem_address address, size; + bool read_only_region; + char name [32]; + char note [1024]; + + fscanf (stream, "%s %lx %lx %d %1023[^\n]", name, &address, &size, &read_only_region, note); + + if (create_memory_region (name, address, size, (read_only_region ? read_only : read_write), decode_note (note))) + break; + } + else // an unknown record type + break; + } + + // quit if the end of the file was not reached (due to an error) + + if (! feof (stream)) + { + new_memory_layout (); + fclose (stream); + return false; + } + + // move the file pointer back to the beginning of the file + + fseek (stream, 0, SEEK_SET); + + while (! feof (stream)) // read the memory layout (second pass) + { + char record_type [32]; + if (fscanf (stream, "%31s", record_type) == EOF) + break; + + if ((strcmp (record_type, "section") == 0) && (! load_memory_section_2 (stream))) + break; + } + + // close the file + + if (fclose (stream)) + { + new_memory_layout (); + return false; + } + + // recalculate section view lists for all regions + + calc_section_lists (); + + map_modified_flag = false; + return true; +} + + +//////////////////////////////////////////////////////////////////////// +// load_memory_section_1() loads a previously saved memory section from +// file (first pass) + +bool mem_map::load_memory_section_1 (FILE * stream) +{ + char section_name [32]; + int relocates, linker_defined; + int final_absolute, initial_absolute, final_following, initial_following; + mem_section new_section; + + new_section.initial_location = new mem_location; + new_section.initial_location->following_section = NULL; + new_section.final_location = new mem_location; + new_section.final_location->following_section = NULL; + + fscanf (stream,"%31s %lx %lx %d %d %d %d %d %d", + section_name, &new_section.size, &new_section.alignment, + &relocates, &linker_defined, &final_absolute, &final_following, + &initial_absolute, &initial_following); + + new_section.name = section_name; + new_section.relocates = (relocates != 0); + new_section.linker_defined = (linker_defined != 0); + + new_section.final_location->anchor = (final_absolute ? absolute : relative); + if (final_absolute) // final location is absolute + fscanf (stream, "%lx", &new_section.final_location->address); + + new_section.initial_location->anchor = (initial_absolute ? absolute : relative); + if (initial_absolute) // initial location is absolute + fscanf (stream, "%lx", &new_section.initial_location->address); + + if (final_following) + fscanf (stream, "%*s"); // skip the final following section field on first pass + + if (initial_following) + fscanf (stream, "%*s"); // skip the initial following section field on first pass + + char note [1024]; + fscanf (stream, " %1023[^\n]", note); + new_section.note = decode_note (note); + + // add the new section to the section map + + section_list.push_front (new_section); + + return true; +} + + +//////////////////////////////////////////////////////////////////////// +// load_memory_section_2() loads a previously saved memory section from +// file (second pass) + +bool mem_map::load_memory_section_2 (FILE * stream) +{ + char section_name [32]; + char following_section_name [32]; + int final_absolute, initial_absolute, final_following, initial_following; + + fscanf (stream,"%31s %*lx %*lx %*d %*d %d %d %d %d", + section_name, &final_absolute, &final_following, + &initial_absolute, &initial_following); + + if (final_absolute) // final location is absolute + fscanf (stream, "%*lx"); // skip the final location + + if (initial_absolute) // initial location is absolute + fscanf (stream, "%*lx"); // skip the initial location + + if (initial_following || final_following) // the section is a parent + { + list ::iterator section = find_memory_section (section_name); + + if (final_following) + { + fscanf (stream, "%31s", following_section_name); // read the final following section name + section->final_location->following_section = + find_memory_section (following_section_name); + } + + if (initial_following) + { + fscanf (stream, "%31s", following_section_name); // read the initial following section name + section->initial_location->following_section = + find_memory_section (following_section_name); + } + } + + fscanf (stream, "%*1023[^\n]"); // skip the note + + return true; +} + + +//////////////////////////////////////////////////////////////////////// +// new_memory_layout() clears the memory layout + +bool mem_map::new_memory_layout () +{ + delete_all_memory_sections (); +// section_list.clear (); + region_list.clear (); + + map_modified_flag = false; // no need to save an empty memory layout + return true; +} + + +//////////////////////////////////////////////////////////////////////// +// section_exists() determines if the specified section is defined + +bool mem_map::section_exists (std::string section_name) +{ + return (find_memory_section (section_name) != NULL); +} + + +//////////////////////////////////////////////////////////////////////// +// find_region_by_address() finds the region containing the specified +// memory address + +list ::iterator mem_map::find_region_by_address (mem_address address) +{ + for (list ::iterator region = region_list.begin (); region !=region_list.end(); ++region) + if ((address >= region->address) && (address < region->address + region->size)) + return region; + + return NULL; // the specified address is not in a memory region +} + + +//////////////////////////////////////////////////////////////////////// +// find_region_by_section() finds the region containing the specified +// section + +list ::iterator mem_map::find_region_by_section (list ::iterator section, section_location_type location_type) +{ + for (list ::iterator region = region_list.begin (); region !=region_list.end(); ++region) + for (list ::iterator section_view = region->section_view_list.begin (); section_view != region->section_view_list.end (); ++section_view) + if ((section_view->section != NULL) && (section_view->section == section) && + (section_view->section_location == (section_view->section->relocates ? location_type : fixed_location))) + return region; + + return NULL; // the specified section location type was not found (you probably searched for the fixed_location of a relocating section) +} diff --git a/host/tools/configtool/standalone/wxwin/memmap.h b/host/tools/configtool/standalone/wxwin/memmap.h new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/memmap.h @@ -0,0 +1,268 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +//================================================================= +// +// memmap.h +// +// Memory Layout Tool map data structure manipulation interface +// +//================================================================= +//================================================================= +//#####DESCRIPTIONBEGIN#### +// +// Author(s): John Dallaway +// Contact(s): jld +// Date: 1998/07/29 $RcsDate$ {or whatever} +// Version: 0.00+ $RcsVersion$ {or whatever} +// Purpose: Provides an interface to create and destroy memory +// regions and sections within the memory map. Exposes +// data structures for the presentation of this data +// by external code. +// See also: memmap.cpp +// Known bugs: +// WARNING: Do not modify data structures other than by using the +// provided functions +// Usage: #include "memmap.h" +// ... +// status = set_map_size (0x8000); +// +//####DESCRIPTIONEND#### + +#if !defined(AFX_MEMMAP_H__75497C90_17F4_11D2_BFBB_00A0C9554250__INCLUDED_) +#define AFX_MEMMAP_H__75497C90_17F4_11D2_BFBB_00A0C9554250__INCLUDED_ + +/* + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 + +#ifdef _AFXDLL +#include "stdafx.h" + #define INCLUDEFILE + #include "IncludeSTL.h" + #define INCLUDEFILE + #include "IncludeSTL.h" + #define INCLUDEFILE + #include "IncludeSTL.h" + #define INCLUDEFILE + #include "IncludeSTL.h" +#else + #include + #include + #include + #include +#endif + +*/ + +#include + +#define ERR_MEMMAP_REGION_NONAME 1 +#define ERR_MEMMAP_REGION_MAPSIZE 2 +#define ERR_MEMMAP_REGION_INTERSECT 3 /* region name returned in error_info */ +#define ERR_MEMMAP_REGION_NAMEINUSE 4 +#define ERR_MEMMAP_REGION_NOTFOUND 5 +#define ERR_MEMMAP_REGION_SIZE 6 +#define ERR_MEMMAP_ALLOC 7 +#define ERR_MEMMAP_SECTION_NONAME 8 +#define ERR_MEMMAP_SECTION_NAMEINUSE 9 +#define ERR_MEMMAP_SECTION_LMA_NOTINREGION 10 +#define ERR_MEMMAP_SECTION_VMA_NOTINREGION 11 +#define ERR_MEMMAP_SECTION_LMA_ANCHORNOTFOUND 12 +#define ERR_MEMMAP_SECTION_LMA_ANCHORNOTAVAIL 13 +#define ERR_MEMMAP_SECTION_VMA_ANCHORNOTFOUND 14 +#define ERR_MEMMAP_SECTION_VMA_ANCHORNOTAVAIL 15 +#define ERR_MEMMAP_SECTION_NOTFOUND 17 +#define ERR_MEMMAP_SECTION_VMA_READONLY 18 +#define ERR_MEMMAP_SECTION_LMA_READWRITE 19 +#define ERR_MEMMAP_SECTION_ILLEGAL_RELOCATION 20 + +#define LD_ILLEGAL_CHARS _T(" ,.") +#define MLT_FILE_VERSION 0 +#define MLT_GENERATED_WARNING "// This is a generated file - do not edit" + +typedef unsigned long mem_address; // FIXME: is a 32-bit memory address sufficient? +typedef struct tag_mem_location mem_location; // forward declaration for struct tag_mem_location + +// the location of each section is specified either relative to another +// section or using an absolute memory address, either the start or end +// address may be specified + +typedef enum mem_anchor {relative, absolute}; + +// each section view item may represent either the initial location of +// the section, the final location, or both locations if the section does +// not relocate + +typedef enum section_location_type {initial_location, final_location, fixed_location}; + +// a memory region may be either ROM (read-only) or RAM (read-write). + +typedef enum mem_type {read_only, read_write}; + +// the memory section structure describes the initial and final locations +// of a section, its size and relocation information + +class mem_section +{ +public: + std::string name; // the name of the section + bool relocates; // if the memory section relocates + bool linker_defined; // if the memory section is linker-defined + mem_address alignment; // the section alignment + mem_address size; // memory section size (zero if unknown) + mem_location * final_location; // the final memory section location (always defined) + mem_location * initial_location; // the initial memory section location (always defined) + std::string note; // comment lines + mem_section (); + ~mem_section (); +}; + +// the memory location structure describes the way in which the section is +// anchored, the absolute address of the anchor (if any) and the names of +// the preceding and following relative sections (if any) + +typedef struct tag_mem_location +{ + mem_anchor anchor; // type of anchor + mem_address address; // the absolute anchor address (if any) + std::list ::iterator following_section; // the section declared as following this one +} mem_location; + +// the section view structure consists of the section name (which is used +// as a key to look up section information in the section map) and an enum +// describing the state of the section which it represents + +typedef struct tag_mem_section_view +{ + std::list ::iterator section; // unused section if NULL + section_location_type section_location; +} mem_section_view; + +// the memory region structure describes the region name, size, address, +// RAM/ROM status and a list of section views which reside in the region + +typedef struct tag_mem_region +{ + std::string name; // the name of the region + mem_address size; // the size of the memory region in bytes + mem_address address; // the absolute location of the memory region + mem_type type; // ROM or RAM + std::list section_view_list; + std::string note; // comment lines +} mem_region; + + +class mem_map +{ +public: + bool delete_memory_section (std::string name); + int edit_memory_section (std::string old_name, + std::string new_name, + mem_address section_size, + mem_address section_alignment, + mem_anchor initial_section_anchor, + std::string initial_anchor_section_name, + mem_address initial_anchor_address, + mem_anchor final_section_anchor, + std::string final_anchor_section_name, + mem_address final_anchor_address, + bool relocates, + bool anchor_to_initial_location, + bool linker_defined, + std::string note); + int create_memory_section (std::string section_name, + mem_address section_size, + mem_address section_alignment, + mem_anchor initial_section_anchor, + std::string initial_anchor_section_name, + mem_address initial_anchor_address, + mem_anchor final_section_anchor, + std::string final_anchor_section_name, + mem_address final_anchor_address, + bool relocates, + bool anchor_to_initial_location, + bool linker_defined, + std::string note); + bool set_map_size (mem_address size); + bool delete_memory_region (std::string name); + bool get_memory_region (std::string region_name, + mem_address * region_address, + mem_address * region_size, + mem_type * region_type, + std::string * note); + int create_memory_region (std::string name, mem_address location, + mem_address size, mem_type type, std::string note); + int edit_memory_region (std::string old_name, std::string new_name, mem_address new_location, + mem_address new_size, mem_type new_type, std::string note); + bool delete_all_memory_sections (); + bool export_files (const wxChar* script_name, const wxChar* header_name); + bool import_linker_defined_sections (const wxChar* filename); + bool save_memory_layout (const wxChar* filename); + bool load_memory_layout (const wxChar* filename); + bool new_memory_layout (); + bool map_modified () { return map_modified_flag; }; + bool section_exists (std::string section_name); + std::list ::iterator find_memory_section (std::string section_name); + std::list ::iterator find_preceding_section (std::list ::iterator section, bool initial_location); + std::string error_info; + std::list region_list; // ordered list of memory regions + std::list section_list; // list of memory sections + std::list linker_defined_section_list; // list of linker-defined sections + + mem_map(); + virtual ~mem_map(); + +private: + std::list ::iterator find_memory_region (std::string); + std::list ::iterator find_region_by_address (mem_address); + std::list ::iterator find_region_by_section (std::list ::iterator section, section_location_type location_type); + mem_address map_size; // total size of memory map + bool add_absolute_section_to_list (std::list ::iterator region, + std::list ::iterator additional_section, + section_location_type location_type); + bool add_relative_sections_to_list (std::list ::iterator region, + std::list ::iterator section_view, + section_location_type location_type); + bool calc_section_list (std::list ::iterator region); + bool calc_section_lists (); + bool at_start_of_region (std::list ::iterator section, + std::list ::iterator region); + bool at_end_of_region (std::list ::iterator section, + std::list ::iterator region); + bool absolute_sections_meet (std::list ::iterator section1, + std::list ::iterator section2); + bool load_memory_section_1 (FILE * stream); + bool load_memory_section_2 (FILE * stream); + bool export_sections (FILE *, FILE *, mem_type); + bool map_modified_flag; + std::string encode_note (std::string); + std::string decode_note (std::string); + std::string encode_section_name (std::string); + std::string decode_section_name (std::string); +}; + +#endif // !defined(AFX_MEMMAP_H__75497C90_17F4_11D2_BFBB_00A0C9554250__INCLUDED_) diff --git a/host/tools/configtool/standalone/wxwin/mltwin.cpp b/host/tools/configtool/standalone/wxwin/mltwin.cpp new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/mltwin.cpp @@ -0,0 +1,540 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +// mltwin.cpp : +// +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): julians +// Contact(s): julians +// Date: 2000/09/27 +// Version: $Id: mltwin.cpp,v 1.2 2001/03/22 11:27:28 julians Exp $ +// Purpose: +// Description: Implementation file for ecMemoryLayoutWindow +// Requires: +// Provides: +// See also: +// Known bugs: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== + +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- +#ifdef __GNUG__ + #pragma implementation "mltwin.h" +#endif + +// Includes other headers for precompiled compilation +#include "ecpch.h" + +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + +#include "mltwin.h" +#include "sectiondlg.h" + +#define VERT_BORDER 30 /* the vertical border at the top/bottom of the client area */ +#define HORIZ_BORDER 30 /* the horizontal border at the left/right of the client area */ +#define BAR_HEIGHT 18 /* the height of the memory section caption bar */ +#define MAP_HEIGHT 66 /* the height of each memory section rectangle (including caption bar) */ +#define REGION_SPACING 115 /* the vertical offset between successive memory regions */ +#define ADDRESS_TEXT_SPACE 0.9 /* use 90% of the section width to draw the address */ +#define EXTERNAL_TEXT_BORDER 5 /* spacing between external text and border of region */ +#define ADDRESS_FORMAT _T("%08X") /* draw memory addresses in hex format */ +#define UNITS_PER_SECTION 3 /* memory section width in units, unused sections are 1 unit wide */ +#define UNIT_WIDTH_MIN 27 /* minimum width of memory section unit before horizontal scrolling enabled */ +#define TICK_HEIGHT 4 /* the height of the tick marks on the memory sections and regions */ + +#define DISPLAY_MODE 1 /* 1 == const unit width for all regions */ +/* 2 == const region width for all regions */ + + +/* + * ecMemoryLayoutWindow + */ + +IMPLEMENT_CLASS(ecMemoryLayoutWindow, wxScrolledWindow) + +BEGIN_EVENT_TABLE(ecMemoryLayoutWindow, wxScrolledWindow) +// EVT_PAINT(ecMemoryLayoutWindow::OnPaint) + EVT_MOUSE_EVENTS(ecMemoryLayoutWindow::OnMouseEvent) + EVT_PAINT(ecMemoryLayoutWindow::OnPaint) + EVT_SIZE(ecMemoryLayoutWindow::OnSize) + EVT_MENU(ecID_TREE_PROPERTIES, ecMemoryLayoutWindow::OnProperties) +END_EVENT_TABLE() + +ecMemoryLayoutWindow::ecMemoryLayoutWindow(wxWindow* parent, wxWindowID id, const wxPoint& pt, + const wxSize& sz, long style): + wxScrolledWindow(parent, id, pt, sz, style) +{ + m_uViewWidth = 0; + m_uClientWidth = 0; + m_uUnitCountMax = 0; + + SetBackgroundColour(* wxWHITE); + + m_propertiesMenu = new wxMenu; + + m_propertiesMenu->Append(ecID_WHATS_THIS, _("&What's This?")); + m_propertiesMenu->AppendSeparator(); + m_propertiesMenu->Append(ecID_TREE_PROPERTIES, _("P&roperties")); +} + +ecMemoryLayoutWindow::~ecMemoryLayoutWindow() +{ + delete m_propertiesMenu; +} + +void ecMemoryLayoutWindow::OnPaint(wxPaintEvent& event) +{ + wxPaintDC dc(this); + + PrepareDC(dc); + + ecConfigToolDoc* pDoc = wxGetApp().GetConfigToolDoc(); + if (pDoc == NULL) // no document so nothing to draw + return; + +#if 0 + // clear the lists of region and section rectangles used for hit testing + + listRegionRect.RemoveAll (); + listSectionRect.RemoveAll (); + + // setup background mode + + int nOldBkMode = pDC->SetBkMode (TRANSPARENT); + + // setup font + + CFont fntName; + if (!fntName.CreatePointFont (80, _T("MS Sans Serif"), pDC)) + return; + CFont * pOldFont = pDC->SelectObject (&fntName); + + // determine max unit count for any region + + mem_map * pMemoryMap = &CConfigTool::GetConfigToolDoc()->MemoryMap; + + // calculate the unit scaling for DISPLAY_MODE 1 + + UINT uPixelsPerUnit = UNIT_WIDTH_MIN; + RECT rectClientRect; + if (m_uUnitCountMax != 0) // if there is something to draw + { + + GetClientRect (&rectClientRect); + uPixelsPerUnit = __max ((m_uClientWidth - HORIZ_BORDER * 2) / m_uUnitCountMax, UNIT_WIDTH_MIN); + m_uViewWidth = uPixelsPerUnit * m_uUnitCountMax + HORIZ_BORDER * 2; + } + + // draw the regions + + UINT uRegion = 0; + UINT uUnitCount; + list ::iterator region; + for (region = pMemoryMap->region_list.begin (); region != pMemoryMap->region_list.end (); ++region) + { + uUnitCount = 0; + for (list ::iterator section_view = region->section_view_list.begin (); section_view != region->section_view_list.end (); ++section_view) + uUnitCount += (section_view->section == NULL ? 1 : UNITS_PER_SECTION); + + if (DISPLAY_MODE == 1) + DrawRegion (pDC, uRegion++, uUnitCount, uPixelsPerUnit, region); + else // DISPLAY_MODE == 2 + DrawRegion (pDC, uRegion++, uUnitCount, (rectClientRect.right - HORIZ_BORDER * 2) / uUnitCount, region); + } + + pDC->SelectObject (pOldFont); + pDC->SetBkMode (nOldBkMode); +#endif +} + +void ecMemoryLayoutWindow::OnMouseEvent(wxMouseEvent& event) +{ + if (event.RightDown()) + { + PopupMenu(GetPropertiesMenu(), event.GetX(), event.GetY()); + } +} + +void ecMemoryLayoutWindow::OnProperties(wxCommandEvent& event) +{ + ecSectionDialog dialog(wxTheApp->GetTopWindow()); + dialog.ShowModal(); +} + +void ecMemoryLayoutWindow::RefreshMLT() +{ +#if 0 + // From OnUpdate in the MFC tool + + if ((lHint != 0) && (pHint != NULL) && (lHint != CConfigToolDoc::MemLayoutChanged)) + return; // no need to invalidate the view + m_arstrTooltipRects.RemoveAll(); + + CalcUnitCountMax (); // recalculate the total view width since the section count may have changed + if (m_uUnitCountMax == 0 || (m_uClientWidth < HORIZ_BORDER * 2)) // there is nothing to draw + m_uViewWidth = 0; + else // allow horizontal scrolling when the unit width reduces to UNIT_WIDTH_MIN + m_uViewWidth = __max ((m_uClientWidth - HORIZ_BORDER * 2) / m_uUnitCountMax, UNIT_WIDTH_MIN) * m_uUnitCountMax + HORIZ_BORDER * 2; + + SIZE sizeTotal; + sizeTotal.cx = __max (m_uViewWidth, m_uClientWidth); + sizeTotal.cy = CConfigTool::GetConfigToolDoc()->MemoryMap.region_list.size () * REGION_SPACING + EXTERNAL_TEXT_BORDER * 2; + SetScrollSizes (MM_TEXT, sizeTotal); +#endif +} + +#if ecUSE_MLT +void ecMemoryLayoutWindow::DrawRegion (wxDC& dc, int uRegion, int uUnitCount, int uPixelsPerUnit, std::list ::iterator region) +{ +#if 0 + BOOL bDrawFocusRect = FALSE; + CRect rectAddress; + CString strAddress; + + // setup the drawing objects + + CBrush brshUnusedSection; + if (!brshUnusedSection.CreateHatchBrush (HS_BDIAGONAL, RGB (128, 128, 128))) + return; + + CBrush brshUsedSection; + if (!brshUsedSection.CreateSolidBrush (GetSysColor (COLOR_WINDOW))) + return; + + CBrush brshInitialSectionBar; + if (!brshInitialSectionBar.CreateSolidBrush (GetSysColor (COLOR_INACTIVECAPTION))) + return; + + CBrush brshFixedSectionBar; + if (!brshFixedSectionBar.CreateSolidBrush (GetSysColor (COLOR_ACTIVECAPTION))) + return; + + CBrush brshFinalSectionBar; + if (!brshFinalSectionBar.CreateSolidBrush (GetSysColor (COLOR_ACTIVECAPTION))) + return; + + CPen penBorder; + if (!penBorder.CreatePen (PS_SOLID, 1, GetSysColor (COLOR_WINDOWTEXT))) + return; + + CPen penSelected; + if (!penSelected.CreatePen (PS_SOLID, 2, GetSysColor (COLOR_WINDOWTEXT))) + return; + + // select the border pen object + + CPen * pOldPen = pDC->SelectObject (&penBorder); + + // calculate the region rectangle + + REGIONRECT srRegion; + srRegion.Rect.SetRect (HORIZ_BORDER, VERT_BORDER + REGION_SPACING * uRegion, HORIZ_BORDER + uUnitCount * uPixelsPerUnit + 1, VERT_BORDER + REGION_SPACING * uRegion + MAP_HEIGHT + 1); + srRegion.Region = region; + listRegionRect.AddTail (srRegion); + + // draw the region + + CPoint pointOrigin (srRegion.Rect.left, srRegion.Rect.top); + pDC->LPtoDP (&pointOrigin); + pointOrigin.x %= 8; + pointOrigin.y %= 8; + pDC->SetBrushOrg (pointOrigin); + CBrush * pOldBrush = pDC->SelectObject (&brshUnusedSection); + pDC->Rectangle (srRegion.Rect); + /* + pDC->MoveTo (srRegion.Rect.left, srRegion.Rect.bottom - 1); // draw tick + pDC->LineTo (srRegion.Rect.left, srRegion.Rect.bottom + TICK_HEIGHT); // draw tick + */ + if (region == m_riSelectedRegion) + { + bDrawFocusRect = TRUE; + m_rectSelectedItem = srRegion.Rect; + } + + // draw the region label + + CRect rectRegionLabel (HORIZ_BORDER, VERT_BORDER + REGION_SPACING * uRegion - EXTERNAL_TEXT_BORDER - 20, m_uViewWidth - HORIZ_BORDER /*HORIZ_BORDER + uUnitCount * uPixelsPerUnit + 1*/, VERT_BORDER + REGION_SPACING * uRegion - EXTERNAL_TEXT_BORDER); + CString strRegionLabel; + strRegionLabel.Format (_T("%s (%08X-%08X)%s"), CString(region->name.c_str ()), region->address, region->address + region->size - 1, ((region->type == read_only) ? _T(" read only") : _T(""))); + pDC->DrawText (strRegionLabel, -1, rectRegionLabel, DT_BOTTOM | DT_SINGLELINE); + + // draw the start address of the region + /* + rectAddress.SetRect (HORIZ_BORDER, VERT_BORDER + REGION_SPACING * uRegion + MAP_HEIGHT + EXTERNAL_TEXT_BORDER, HORIZ_BORDER + ADDRESS_TEXT_SPACE * UNITS_PER_SECTION * uPixelsPerUnit, VERT_BORDER + REGION_SPACING * uRegion + MAP_HEIGHT + EXTERNAL_TEXT_BORDER + 30); + strAddress.Format (ADDRESS_FORMAT, region->address); + pDC->DrawText (strAddress, -1, rectAddress, DT_LEFT | DT_SINGLELINE); + */ + // draw the end address of the region + /* + rectAddress.SetRect (HORIZ_BORDER + (uUnitCount - ADDRESS_TEXT_SPACE) * uPixelsPerUnit, VERT_BORDER + REGION_SPACING * uRegion + MAP_HEIGHT + EXTERNAL_TEXT_BORDER, HORIZ_BORDER + (uUnitCount + ADDRESS_TEXT_SPACE) * uPixelsPerUnit, VERT_BORDER + REGION_SPACING * uRegion + MAP_HEIGHT + EXTERNAL_TEXT_BORDER + 30); + strAddress.Format (ADDRESS_FORMAT, region->address + region->size); + pDC->DrawText (strAddress, -1, rectAddress, DT_CENTER | DT_SINGLELINE); + */ + // draw the sections within the region + + UINT uSectionUnitCount = 0; + CRect rectBar; + SECTIONRECT srSection; + for (list ::iterator section_view = region->section_view_list.begin (); section_view != region->section_view_list.end (); ++section_view) + { + if (section_view->section != NULL) // the section is used + { + // draw the section + + pDC->SelectObject (brshUsedSection); + srSection.Rect.SetRect (HORIZ_BORDER + uSectionUnitCount * uPixelsPerUnit, VERT_BORDER + REGION_SPACING * uRegion, HORIZ_BORDER + (uSectionUnitCount + UNITS_PER_SECTION) * uPixelsPerUnit + 1, VERT_BORDER + REGION_SPACING * uRegion + MAP_HEIGHT + 1); + srSection.SectionView = section_view; + listSectionRect.AddTail (srSection); + pDC->Rectangle (srSection.Rect); + if (section_view == m_sviSelectedSectionView) + { + bDrawFocusRect = TRUE; + m_rectSelectedItem = srSection.Rect; + } + + // draw text within the section + + CString strSection, strSectionLine; + + if ((section_view->section_location != initial_location) && (section_view->section->alignment > 1)) + { + strSectionLine.Format (_T("align %lX\n"), section_view->section->alignment); + strSection += strSectionLine; + } + + if (section_view->section->size > 0) + { + strSectionLine.Format (_T("size %lX\n"), section_view->section->size); + strSection += strSectionLine; + } + + if (section_view->section_location == final_location) + { + strSectionLine.Format (_T("relocated\n")); + strSection += strSectionLine; + } + + pDC->DrawText (strSection, -1, srSection.Rect - (LPCRECT) CRect (EXTERNAL_TEXT_BORDER, EXTERNAL_TEXT_BORDER + BAR_HEIGHT, EXTERNAL_TEXT_BORDER, EXTERNAL_TEXT_BORDER), DT_LEFT); + + // select caption bar colour according to type of section + + if (section_view->section_location == initial_location) + { + pDC->SetTextColor (GetSysColor (COLOR_INACTIVECAPTIONTEXT)); + pDC->SelectObject (&brshInitialSectionBar); + } + else + { + pDC->SetTextColor (GetSysColor (COLOR_CAPTIONTEXT)); + pDC->SelectObject (&brshFinalSectionBar); + } + + // draw the caption bar + + rectBar.SetRect (HORIZ_BORDER + uSectionUnitCount * uPixelsPerUnit, VERT_BORDER + REGION_SPACING * uRegion, HORIZ_BORDER + (uSectionUnitCount + UNITS_PER_SECTION) * uPixelsPerUnit + 1, VERT_BORDER + REGION_SPACING * uRegion + BAR_HEIGHT + 1); + pDC->Rectangle (rectBar); + + // draw the section name within the caption bar + + CString strName(section_view->section->name.c_str ()); + CRect *pRect=NULL; + m_arstrTooltipRects.Lookup(strName,(void *&)pRect); + UINT format; + if(pDC->GetTextExtent(strName).cx>rectBar.Width()-2*EXTERNAL_TEXT_BORDER){ + format=DT_LEFT; + if(pRect){ + pRect->CopyRect(rectBar); + } else { + pRect=new CRect; + m_arstrTooltipRects.SetAt(strName,pRect); + } + // Replace final three characters of name with an elipsis + int nLength=1+max(1,strName.GetLength()-3); + do { + --nLength; + strName=strName.Left(nLength)+_T("..."); + } while(nLength>1 && pDC->GetTextExtent(strName).cx>rectBar.Width()-2*EXTERNAL_TEXT_BORDER); + + rectBar.left+=EXTERNAL_TEXT_BORDER; + rectBar.right-=EXTERNAL_TEXT_BORDER; + } else { + format=DT_CENTER; + if (pRect) { + m_arstrTooltipRects.RemoveKey(strName); + } + } + + pDC->DrawText (strName, -1, rectBar, format | DT_VCENTER | DT_SINGLELINE); + pDC->SetTextColor (GetSysColor (COLOR_WINDOWTEXT)); + + // find the mem_section item describing the current section_view item + + list ::iterator MemorySection = section_view->section; + + // draw the section address if appropriate + + if ((section_view->section_location == initial_location)) + { + if (MemorySection->initial_location->anchor == absolute) + { + pDC->MoveTo (srSection.Rect.left, srSection.Rect.bottom - 1); // draw tick + pDC->LineTo (srSection.Rect.left, srSection.Rect.bottom + TICK_HEIGHT); // draw tick + rectAddress.SetRect (HORIZ_BORDER + uSectionUnitCount * uPixelsPerUnit, VERT_BORDER + REGION_SPACING * uRegion + MAP_HEIGHT + EXTERNAL_TEXT_BORDER, (int) (HORIZ_BORDER + (uSectionUnitCount + ADDRESS_TEXT_SPACE * UNITS_PER_SECTION) * uPixelsPerUnit), VERT_BORDER + REGION_SPACING * uRegion + MAP_HEIGHT + EXTERNAL_TEXT_BORDER + 30); + strAddress.Format (ADDRESS_FORMAT, MemorySection->initial_location->address); + pDC->DrawText (strAddress, -1, rectAddress, DT_LEFT | DT_SINGLELINE); + + /* + if (MemorySection->size > 0) // the end address can be calculated + { + rectAddress.SetRect (HORIZ_BORDER + (uSectionUnitCount + UNITS_PER_SECTION - ADDRESS_TEXT_SPACE) * uPixelsPerUnit, VERT_BORDER + REGION_SPACING * uRegion + MAP_HEIGHT + EXTERNAL_TEXT_BORDER, HORIZ_BORDER + (uSectionUnitCount + UNITS_PER_SECTION + ADDRESS_TEXT_SPACE) * uPixelsPerUnit, VERT_BORDER + REGION_SPACING * uRegion + MAP_HEIGHT + EXTERNAL_TEXT_BORDER + 30); + strAddress.Format (ADDRESS_FORMAT, MemorySection->initial_location->address + MemorySection->size); + pDC->DrawText (strAddress, -1, rectAddress, DT_CENTER | DT_SINGLELINE); + } + */ + } + } + + else if ((section_view->section_location == final_location) || (section_view->section_location == fixed_location)) + { + if (MemorySection->final_location->anchor == absolute) + { + pDC->MoveTo (srSection.Rect.left, srSection.Rect.bottom - 1); // draw tick + pDC->LineTo (srSection.Rect.left, srSection.Rect.bottom + TICK_HEIGHT); // draw tick + rectAddress.SetRect (HORIZ_BORDER + uSectionUnitCount * uPixelsPerUnit, VERT_BORDER + REGION_SPACING * uRegion + MAP_HEIGHT + EXTERNAL_TEXT_BORDER, (int) (HORIZ_BORDER + (uSectionUnitCount + ADDRESS_TEXT_SPACE * UNITS_PER_SECTION) * uPixelsPerUnit), VERT_BORDER + REGION_SPACING * uRegion + MAP_HEIGHT + EXTERNAL_TEXT_BORDER + 30); + strAddress.Format (ADDRESS_FORMAT, MemorySection->final_location->address); + pDC->DrawText (strAddress, -1, rectAddress, DT_LEFT | DT_SINGLELINE); + + /* + if (MemorySection->size > 0) // the end address can be calculated + { + rectAddress.SetRect (HORIZ_BORDER + (uSectionUnitCount + UNITS_PER_SECTION - ADDRESS_TEXT_SPACE) * uPixelsPerUnit, VERT_BORDER + REGION_SPACING * uRegion + MAP_HEIGHT + EXTERNAL_TEXT_BORDER, HORIZ_BORDER + (uSectionUnitCount + UNITS_PER_SECTION + ADDRESS_TEXT_SPACE) * uPixelsPerUnit, VERT_BORDER + REGION_SPACING * uRegion + MAP_HEIGHT + EXTERNAL_TEXT_BORDER + 30); + strAddress.Format (ADDRESS_FORMAT, MemorySection->final_location->address + MemorySection->size); + pDC->DrawText (strAddress, -1, rectAddress, DT_CENTER | DT_SINGLELINE); + } + */ + } + } + + uSectionUnitCount += UNITS_PER_SECTION; + } + else + { + uSectionUnitCount++; // unused sections occupy a single unit + } + } + + // draw the focus rectangle around the selected object (if any) + + if (bDrawFocusRect) + pDC->DrawFocusRect (m_rectSelectedItem + CRect (1, 1, 1, 1)); + + // restore previous drawing objects + + pDC->SelectObject (pOldBrush); + pDC->SelectObject (pOldPen); +#endif +} + +SECTIONRECT * ecMemoryLayoutWindow::SectionHitTest (wxPoint pntTest) +{ +#if 0 + for (POSITION posSection = listSectionRect.GetHeadPosition (); posSection != NULL; listSectionRect.GetNext (posSection)) + { + if (listSectionRect.GetAt (posSection).Rect.PtInRect (pntTest)) + return & listSectionRect.GetAt (posSection); + } +#endif + + return NULL; +} + +REGIONRECT * ecMemoryLayoutWindow::RegionHitTest (wxPoint pntTest) +{ +#if 0 + for (POSITION posRegion = listRegionRect.GetHeadPosition (); posRegion != NULL; listRegionRect.GetNext (posRegion)) + { + CRect rectRegion = listRegionRect.GetAt (posRegion).Rect + + CRect (EXTERNAL_TEXT_BORDER + 20, EXTERNAL_TEXT_BORDER + 20, EXTERNAL_TEXT_BORDER + 20, EXTERNAL_TEXT_BORDER + 20); // extended rectangle to allow clicking on region label + if (rectRegion.PtInRect (pntTest)) + return & listRegionRect.GetAt (posRegion); + } +#endif + + return NULL; +} +#endif + +void ecMemoryLayoutWindow::OnSize(wxSizeEvent& event) +{ +#if 0 + CScrollView::OnSize(nType, cx, cy); + + m_uClientWidth = cx; + if (m_uUnitCountMax == 0) // there is nothing to draw + m_uViewWidth = 0; + else // allow horizontal scrolling when the unit width reduces to UNIT_WIDTH_MIN + m_uViewWidth = __max ((cx - HORIZ_BORDER * 2) / m_uUnitCountMax, UNIT_WIDTH_MIN) * m_uUnitCountMax + HORIZ_BORDER * 2; + + SIZE sizeTotal; + sizeTotal.cx = __max (m_uViewWidth, m_uClientWidth); + if (CConfigTool::GetConfigToolDoc() == NULL) + sizeTotal.cy = 0; + else + sizeTotal.cy = CConfigTool::GetConfigToolDoc()->MemoryMap.region_list.size () * REGION_SPACING + EXTERNAL_TEXT_BORDER * 2; + SetScrollSizes (MM_TEXT, sizeTotal); +#endif +} + +void ecMemoryLayoutWindow::CalcUnitCountMax () +{ +#if 0 + UINT uUnitCountMax = 0; + UINT uUnitCount; + list ::iterator region; + mem_map * pMemoryMap = & (CConfigTool::GetConfigToolDoc()->MemoryMap); + for (region = pMemoryMap->region_list.begin (); region != pMemoryMap->region_list.end (); ++region) + { + uUnitCount = 0; + for (list ::iterator section_view = region->section_view_list.begin (); section_view != region->section_view_list.end (); ++section_view) + uUnitCount += (section_view->section == NULL ? 1 : UNITS_PER_SECTION); + + if (uUnitCount > uUnitCountMax) + uUnitCountMax = uUnitCount; + } + m_uUnitCountMax = uUnitCountMax; + #endif +} diff --git a/host/tools/configtool/standalone/wxwin/mltwin.h b/host/tools/configtool/standalone/wxwin/mltwin.h new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/mltwin.h @@ -0,0 +1,125 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +// mltwin.h : +// +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): julians +// Contact(s): julians +// Date: 2000/09/04 +// Version: $Id: mltwin.h,v 1.2 2001/03/22 11:27:28 julians Exp $ +// Purpose: +// Description: Header file for ecMemoryLayoutWindow +// Requires: +// Provides: +// See also: +// Known bugs: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== + +#ifndef _ECOS_MLTWIN_H_ +#define _ECOS_MLTWIN_H_ + +#ifdef __GNUG__ +#pragma interface "mltwin.h" +#endif + +#if ecUSE_MLT + +#include "memmap.h" + +typedef struct tagREGIONRECT +{ + std::list ::iterator Region; + wxRect Rect; +} +REGIONRECT; + +typedef struct tagSECTIONRECT +{ + std::list ::iterator SectionView; + wxRect Rect; +} +SECTIONRECT; + +#endif + +class ecMemoryLayoutWindow : public wxScrolledWindow +{ +public: +// Ctor(s) + ecMemoryLayoutWindow(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style); + ~ecMemoryLayoutWindow(); + +//// Event handlers + + //void OnPaint(wxPaintEvent& event); + void OnMouseEvent(wxMouseEvent& event); + void OnPaint(wxPaintEvent& event); + void OnSize(wxSizeEvent& event); + void OnProperties(wxCommandEvent& event); + +//// Operations + void RefreshMLT(); + +#if ecUSE_MLT + void DrawRegion (wxDC& dc, int uRegion, int uUnitCount, int uPixelsPerUnit, std::list ::iterator region); + SECTIONRECT * SectionHitTest (wxPoint pntTest); + REGIONRECT * RegionHitTest (wxPoint pntTest); +#endif + + void CalcUnitCountMax (); + + +//// Accessors + wxMenu* GetPropertiesMenu() const { return m_propertiesMenu; } + +protected: + wxMenu* m_propertiesMenu; + + wxList m_listSectionRect; + wxList m_listRegionRect; + +#if ecUSE_MLT + std::list ::iterator m_sviSelectedSectionView; + std::list ::iterator m_riSelectedRegion; +#endif + + int m_uViewWidth, m_uClientWidth; + int m_uUnitCountMax; + wxRect m_rectSelectedItem; + +private: + DECLARE_EVENT_TABLE() + DECLARE_CLASS(ecMemoryLayoutWindow) +}; + + +#endif + // _ECOS_MLTWIN_H_ diff --git a/host/tools/configtool/standalone/wxwin/msgdlgex.cpp b/host/tools/configtool/standalone/wxwin/msgdlgex.cpp new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/msgdlgex.cpp @@ -0,0 +1,286 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: msgdlgex.cpp +// Purpose: wxMessageDialogEx +// Author: Julian Smart +// Modified by: +// Created: 12/12/2000 +// RCS-ID: $Id: msgdlgex.cpp,v 1.1 2001/02/08 18:06:51 julians Exp $ +// Copyright: (c) Julian Smart +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +#ifdef __GNUG__ + #pragma implementation "msgdlgex.cpp" +#endif + +// For compilers that support precompilation, includes "wx/wx.h". +//#include "wx/wxprec.h" +#include "ecpch.h" + +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + +#include "msgdlgex.h" + +// Include wxWindow's headers + +#include "wx/sizer.h" +#include "wx/statline.h" +#include "wx/statbox.h" +#include "wx/stattext.h" +#include "wx/statbmp.h" +#include "wx/bmpbuttn.h" + +//---------------------------------------------------------------------------- +// wxMessageDialogEx +//---------------------------------------------------------------------------- + +IMPLEMENT_CLASS(wxMessageDialogEx,wxDialog) + +BEGIN_EVENT_TABLE(wxMessageDialogEx,wxDialog) + EVT_BUTTON( -1, wxMessageDialogEx::OnCommand ) +END_EVENT_TABLE() + +wxMessageDialogEx::wxMessageDialogEx( wxWindow *parent, const wxString& message, const wxString &caption, + long style, const wxPoint& position) : + wxDialog( parent, -1, caption, position, wxDefaultSize, wxDEFAULT_DIALOG_STYLE ) +{ + m_dialogStyle = style; + + wxBeginBusyCursor(); + + wxBoxSizer *topsizer = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer *icon_text = new wxBoxSizer( wxHORIZONTAL ); + + // 1) icon + if (style & wxICON_MASK) + { + wxStaticBitmap *icon = new wxStaticBitmap( + this, -1, wxTheApp->GetStdIcon((int)(style & wxICON_MASK))); + icon_text->Add( icon, 0, wxCENTER ); + } + + // 2) text + icon_text->Add( CreateTextSizer( message ), 0, wxCENTER | wxLEFT, 10 ); + + topsizer->Add( icon_text, 0, wxCENTER | wxLEFT|wxRIGHT|wxTOP, 10 ); + +#if wxUSE_STATLINE + // 3) static line + topsizer->Add( new wxStaticLine( this, -1 ), 0, wxEXPAND | wxLEFT|wxRIGHT|wxTOP, 10 ); +#endif + + // 4) buttons + topsizer->Add( CreateButtonSizer( style ), 0, wxCENTRE | wxALL, 10 ); + + SetAutoLayout( TRUE ); + SetSizer( topsizer ); + + topsizer->SetSizeHints( this ); + topsizer->Fit( this ); + wxSize size( GetSize() ); + if (size.x < size.y*3/2) + { + size.x = size.y*3/2; + SetSize( size ); + } + + Centre( wxBOTH | wxCENTER_FRAME); + + wxEndBusyCursor(); +} + +wxMessageDialogEx::wxMessageDialogEx() +{ + m_dialogStyle = 0; +} + +wxMessageDialogEx::~wxMessageDialogEx() +{ +} + +void wxMessageDialogEx::OnCommand(wxCommandEvent &event) +{ + EndModal(event.GetId()); +} + +wxSizer *wxMessageDialogEx::CreateButtonSizer( long flags ) +{ + wxBoxSizer *box = new wxBoxSizer( wxHORIZONTAL ); + +#if defined(__WXMSW__) || defined(__WXMAC__) + static const int margin = 6; +#else + static const int margin = 10; +#endif + + wxButton *ok = (wxButton *) NULL; + wxButton *cancel = (wxButton *) NULL; + wxButton *yes = (wxButton *) NULL; + wxButton *no = (wxButton *) NULL; + wxButton *yestoall = (wxButton *) NULL; + wxButton *notoall = (wxButton *) NULL; + wxButton *abort = (wxButton *) NULL; + wxButton *retry = (wxButton *) NULL; + wxButton *ignore = (wxButton *) NULL; + + // always show an OK button, unless only YES_NO is given + // NO, not in this dialog. + //if ((flags & wxYES_NO) == 0) flags = flags | wxOK; + + if (flags & wxMD_YES_NO) + { + yes = new wxButton( this, wxID_YES, _("Yes") ); + box->Add( yes, 0, wxLEFT|wxRIGHT, margin ); + no = new wxButton( this, wxID_NO, _("No") ); + box->Add( no, 0, wxLEFT|wxRIGHT, margin ); + } + + if (flags & wxMD_YES) + { + if (!yes) + { + yes = new wxButton( this, wxID_YES, _("Yes") ); + box->Add( yes, 0, wxLEFT|wxRIGHT, margin ); + } + } + + if (flags & wxMD_YESTOALL) + { + yestoall = new wxButton( this, wxID_YESTOALL, _("Yes to All") ); + box->Add( yestoall, 0, wxLEFT|wxRIGHT, margin ); + } + + if (flags & wxMD_NO) + { + if (!no) + { + no = new wxButton( this, wxID_NO, _("No") ); + box->Add( no, 0, wxLEFT|wxRIGHT, margin ); + } + } + + if (flags & wxMD_NOTOALL) + { + notoall = new wxButton( this, wxID_NOTOALL, _("No to All") ); + box->Add( notoall, 0, wxLEFT|wxRIGHT, margin ); + } + + if (flags & wxMD_ABORT) + { + abort = new wxButton( this, wxID_ABORT, _("Abort") ); + box->Add( abort, 0, wxLEFT|wxRIGHT, margin ); + } + + if (flags & wxMD_RETRY) + { + retry = new wxButton( this, wxID_RETRY, _("Retry") ); + box->Add( retry, 0, wxLEFT|wxRIGHT, margin ); + } + + if (flags & wxMD_IGNORE) + { + ignore = new wxButton( this, wxID_IGNORE, _("Ignore") ); + box->Add( ignore, 0, wxLEFT|wxRIGHT, margin ); + } + + if (flags & wxMD_OK) + { + ok = new wxButton( this, wxID_OK, _("OK") ); + box->Add( ok, 0, wxLEFT|wxRIGHT, margin ); + } + + if (flags & wxMD_CANCEL) + { + cancel = new wxButton( this, wxID_CANCEL, _("Cancel") ); + box->Add( cancel, 0, wxLEFT|wxRIGHT, margin ); + } + + if (flags & wxMD_HELP) + box->Add( new wxButton( this, wxID_HELP, _("Help") ), 0, wxLEFT|wxRIGHT, margin ); + + bool setDefault = FALSE; + + if (flags & wxMD_NO_DEFAULT) + { + if (no) + { + no->SetDefault(); + no->SetFocus(); + setDefault = TRUE; + } + } + else if (flags & wxMD_YES_DEFAULT) + { + if (yes) + { + yes->SetDefault(); + yes->SetFocus(); + setDefault = TRUE; + } + } + else if (flags & wxMD_YESTOALL_DEFAULT) + { + if (yestoall) + { + yestoall->SetDefault(); + yestoall->SetFocus(); + setDefault = TRUE; + } + } + else if (flags & wxMD_NOTOALL_DEFAULT) + { + if (notoall) + { + notoall->SetDefault(); + notoall->SetFocus(); + setDefault = TRUE; + } + } + else if (flags & wxMD_ABORT_DEFAULT) + { + if (abort) + { + abort->SetDefault(); + abort->SetFocus(); + setDefault = TRUE; + } + } + else if (flags & wxMD_RETRY_DEFAULT) + { + if (retry) + { + retry->SetDefault(); + retry->SetFocus(); + setDefault = TRUE; + } + } + else if (flags & wxMD_IGNORE_DEFAULT) + { + if (ignore) + { + ignore->SetDefault(); + ignore->SetFocus(); + setDefault = TRUE; + } + } + + if (!setDefault) + { + if (ok) + { + ok->SetDefault(); + ok->SetFocus(); + } + else if (yes) + { + yes->SetDefault(); + yes->SetFocus(); + } + } + + return box; +} + diff --git a/host/tools/configtool/standalone/wxwin/msgdlgex.h b/host/tools/configtool/standalone/wxwin/msgdlgex.h new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/msgdlgex.h @@ -0,0 +1,93 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: msgdlgex.h +// Purpose: wxMessageDialogEx +// Author: Julian Smart +// Modified by: +// Created: 12/12/2000 +// RCS-ID: $Id: msgdlgex.h,v 1.1 2001/02/08 18:06:51 julians Exp $ +// Copyright: (c) Julian Smart +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_MSGDLGEX_H_ +#define _WX_MSGDLGEX_H_ + +#ifdef __GNUG__ + #pragma interface "msgdlgex.cpp" +#endif + +#include "wx/dialog.h" + +// Styles +#define wxMD_OK 0x00000004 +#define wxMD_YES_NO 0x00000008 +#define wxMD_CANCEL 0x00000010 +#define wxMD_YES 0x00000020 +#define wxMD_NO 0x00000040 +#define wxMD_HELP 0x00008000 + +#define wxMD_YESTOALL 0x00010000 +#define wxMD_NOTOALL 0x00020000 +#define wxMD_ABORT 0x00040000 +#define wxMD_RETRY 0x00080000 +#define wxMD_IGNORE 0x00100000 + +// Use same numbers as wxICON_... equivalents +#define wxMD_ICON_EXCLAMATION 0x00000100 +#define wxMD_ICON_HAND 0x00000200 +#define wxMD_ICON_WARNING wxICON_EXCLAMATION +#define wxMD_ICON_ERROR wxICON_HAND +#define wxMD_ICON_QUESTION 0x00000400 +#define wxMD_ICON_INFORMATION 0x00000800 +#define wxMD_ICON_STOP wxICON_HAND +#define wxMD_ICON_ASTERISK wxICON_INFORMATION +#define wxMD_ICON_MASK (0x00000100|0x00000200|0x00000400|0x00000800) + +#define wxMD_NO_DEFAULT 0x00000080 +#define wxMD_YES_DEFAULT 0x00200000 +// OK and YES are equivalent +#define wxMD_OK_DEFAULT 0x00200000 +#define wxMD_YESTOALL_DEFAULT 0x00400000 +#define wxMD_NOTOALL_DEFAULT 0x00800000 +#define wxMD_ABORT_DEFAULT 0x01000000 +#define wxMD_RETRY_DEFAULT 0x02000000 +#define wxMD_IGNORE_DEFAULT 0x04000000 + +#ifndef wxID_YESTOALL +#define wxID_YESTOALL 5113 +#define wxID_NOTOALL 5114 +#define wxID_ABORT 5115 +#define wxID_RETRY 5116 +#define wxID_IGNORE 5117 +#endif + +//---------------------------------------------------------------------------- +// wxMessageDialogEx +//---------------------------------------------------------------------------- + +class wxMessageDialogEx: public wxDialog +{ +public: + // constructors and destructors + wxMessageDialogEx(); + wxMessageDialogEx( wxWindow *parent, const wxString& message, const wxString& caption, + long style = wxOK|wxCANCEL, + const wxPoint& pos = wxDefaultPosition + ); + virtual ~wxMessageDialogEx(); + +protected: + + //void CreateControls(wxWindow* parent, long style); + wxSizer *CreateButtonSizer( long flags ); + void OnCommand( wxCommandEvent &event ); + + long m_dialogStyle; + +private: + DECLARE_CLASS(wxMessageDialogEx) + DECLARE_EVENT_TABLE() +}; + +#endif + // _WX_MSGDLGEX_H_ diff --git a/host/tools/configtool/standalone/wxwin/outputwin.cpp b/host/tools/configtool/standalone/wxwin/outputwin.cpp new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/outputwin.cpp @@ -0,0 +1,131 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +// outputwin.cpp : +// +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): julians +// Contact(s): julians +// Date: 2000/10/02 +// Version: $Id: outputwin.cpp,v 1.2 2001/04/24 14:39:13 julians Exp $ +// Purpose: +// Description: Implementation file for ecOutputWindow +// Requires: +// Provides: +// See also: +// Known bugs: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== + +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- +#ifdef __GNUG__ + #pragma implementation "outputwin.h" +#endif + +// Includes other headers for precompiled compilation +#include "ecpch.h" + +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + +#include "configtool.h" +#include "outputwin.h" + +/* + * ecOutputWindow + */ + +IMPLEMENT_CLASS(ecOutputWindow, wxTextCtrl) + +BEGIN_EVENT_TABLE(ecOutputWindow, wxTextCtrl) +// EVT_PAINT(ecOutputWindow::OnPaint) + EVT_MOUSE_EVENTS(ecOutputWindow::OnMouseEvent) + EVT_MENU(wxID_CLEAR, ecOutputWindow::OnClear) + EVT_MENU(wxID_SELECTALL, ecOutputWindow::OnSelectAll) + EVT_MENU(wxID_SAVE, ecOutputWindow::OnSave) +END_EVENT_TABLE() + +ecOutputWindow::ecOutputWindow(wxWindow* parent, wxWindowID id, const wxPoint& pt, + const wxSize& sz, long style): + wxTextCtrl(parent, id, wxEmptyString, pt, sz, style) +{ + if (!wxGetApp().GetSettings().GetWindowSettings().GetUseDefaults() && + wxGetApp().GetSettings().GetWindowSettings().GetFont(wxT("Output")).Ok()) + { + SetFont(wxGetApp().GetSettings().GetWindowSettings().GetFont(wxT("Output"))); + } + + m_propertiesMenu = new wxMenu; + + m_propertiesMenu->Append(ecID_WHATS_THIS, _("&What's This?")); + m_propertiesMenu->AppendSeparator(); + m_propertiesMenu->Append(wxID_COPY, _("&Copy")); + m_propertiesMenu->Append(wxID_CLEAR, _("C&lear")); + m_propertiesMenu->Append(wxID_SELECTALL, _("Select &All")); + m_propertiesMenu->AppendSeparator(); + m_propertiesMenu->Append(wxID_SAVE, _("&Save...")); +} + +ecOutputWindow::~ecOutputWindow() +{ + delete m_propertiesMenu; +} + +void ecOutputWindow::OnMouseEvent(wxMouseEvent& event) +{ + if (event.RightDown()) + { + PopupMenu(GetPropertiesMenu(), event.GetX(), event.GetY()); + } + else + { + event.Skip(); + } +} + +void ecOutputWindow::OnClear(wxCommandEvent& event) +{ + Clear(); +} + +void ecOutputWindow::OnSelectAll(wxCommandEvent& event) +{ + SetSelection(0, GetLastPosition()); +} + +void ecOutputWindow::OnSave(wxCommandEvent& event) +{ +} diff --git a/host/tools/configtool/standalone/wxwin/outputwin.h b/host/tools/configtool/standalone/wxwin/outputwin.h new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/outputwin.h @@ -0,0 +1,84 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +// outputwin.h : +// +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): julians +// Contact(s): julians +// Date: 2000/10/2 +// Version: $Id: outputwin.h,v 1.1 2001/02/08 18:06:51 julians Exp $ +// Purpose: +// Description: Header file for ecOutputWindow +// Requires: +// Provides: +// See also: +// Known bugs: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== + +#ifndef _ECOS_OUTPUTWIN_H_ +#define _ECOS_OUTPUTWIN_H_ + +#ifdef __GNUG__ +#pragma interface "outputwin.h" +#endif + +#include "wx/textctrl.h" + +class ecOutputWindow : public wxTextCtrl +{ +public: +// Ctor(s) + ecOutputWindow(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style); + ~ecOutputWindow(); + +//// Event handlers + + void OnMouseEvent(wxMouseEvent& event); + void OnClear(wxCommandEvent& event); + void OnSelectAll(wxCommandEvent& event); + void OnSave(wxCommandEvent& event); + +//// Operations + +//// Accessors + wxMenu* GetPropertiesMenu() const { return m_propertiesMenu; } + +protected: + wxMenu* m_propertiesMenu; + +private: + DECLARE_EVENT_TABLE() + DECLARE_CLASS(ecOutputWindow) +}; + + +#endif + // _ECOS_OUTPUTWIN_H_ diff --git a/host/tools/configtool/standalone/wxwin/packagesdlg.cpp b/host/tools/configtool/standalone/wxwin/packagesdlg.cpp new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/packagesdlg.cpp @@ -0,0 +1,792 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +// packages : +// +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): julians +// Contact(s): julians +// Date: 2000/09/28 +// Version: $Id: packagesdlg.cpp,v 1.2 2001/03/23 13:38:04 julians Exp $ +// Purpose: +// Description: Implementation file for ecPackagesDialog +// Requires: +// Provides: +// See also: +// Known bugs: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== + +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- +#ifdef __GNUG__ +#pragma implementation "packagesdlg.h" +#endif + +// Includes other headers for precompiled compilation +#include "ecpch.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#include "wx/cshelp.h" +#include "wx/valgen.h" + +#include "configtool.h" +#include "packagesdlg.h" +#include "configtooldoc.h" +#include "ecutils.h" + +BEGIN_EVENT_TABLE(ecPackagesDialog, ecDialog) + EVT_BUTTON(wxID_OK, ecPackagesDialog::OnOK) + EVT_BUTTON(wxID_CANCEL, ecPackagesDialog::OnCancel) + EVT_BUTTON(ecID_PACKAGES_DIALOG_ADD, ecPackagesDialog::OnAdd) + EVT_BUTTON(ecID_PACKAGES_DIALOG_REMOVE, ecPackagesDialog::OnRemove) + EVT_LISTBOX_DCLICK(ecID_PACKAGES_DIALOG_AVAILABLE_LIST, ecPackagesDialog::OnDblClickListBox1) + EVT_LISTBOX_DCLICK(ecID_PACKAGES_DIALOG_USE_LIST, ecPackagesDialog::OnDblClickListBox2) + EVT_LISTBOX(ecID_PACKAGES_DIALOG_AVAILABLE_LIST, ecPackagesDialog::OnClickListBox1) + EVT_LISTBOX(ecID_PACKAGES_DIALOG_USE_LIST, ecPackagesDialog::OnClickListBox2) + EVT_LISTBOX(ecID_PACKAGES_DIALOG_VERSION, ecPackagesDialog::OnSelectVersion) + EVT_INIT_DIALOG(ecPackagesDialog::OnInitDialog) +END_EVENT_TABLE() + +// ---------------------------------------------------------------------------- +// main frame +// ---------------------------------------------------------------------------- + +// Frame constructor +ecPackagesDialog::ecPackagesDialog(wxWindow* parent) +{ + m_bHardwarePackageSelected = FALSE; + + SetExtraStyle(wxDIALOG_EX_CONTEXTHELP); + + ecDialog::Create(parent, ecID_PACKAGES_DIALOG, _("Packages"), + wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER); + + CreateControls(this); + + Centre(wxBOTH); +} + +ecPackagesDialog::~ecPackagesDialog() +{ +} + +// TODO: implement wxLB_SORT style in wxGTK. +void ecPackagesDialog::CreateControls(wxWindow* parent) +{ + wxSizer *item0 = new wxBoxSizer( wxVERTICAL ); + + wxSizer *item1 = new wxBoxSizer( wxHORIZONTAL ); + + wxSizer *item2 = new wxBoxSizer( wxVERTICAL ); + + wxStaticText *item3 = new wxStaticText( parent, wxID_STATIC, _("Available &packages:"), wxDefaultPosition, wxDefaultSize, 0 ); + item2->Add( item3, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + wxString *strs4 = (wxString*) NULL; + wxListBox *item4 = new wxListBox( parent, ecID_PACKAGES_DIALOG_AVAILABLE_LIST, wxDefaultPosition, wxSize(180,190), 0, strs4, 0 ); + item2->Add( item4, 1, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxBOTTOM, 5 ); + + item1->Add( item2, 1, wxGROW|wxALIGN_CENTER_HORIZONTAL|wxALL, 0 ); + + wxSizer *item5 = new wxBoxSizer( wxVERTICAL ); + + wxButton *item6 = new wxButton( parent, ecID_PACKAGES_DIALOG_ADD, _("&Add >>"), wxDefaultPosition, wxDefaultSize, 0 ); + item5->Add( item6, 0, wxALIGN_CENTRE|wxALL, 5 ); + + wxButton *item7 = new wxButton( parent, ecID_PACKAGES_DIALOG_REMOVE, _("<< &Remove"), wxDefaultPosition, wxDefaultSize, 0 ); + item5->Add( item7, 0, wxALIGN_CENTRE|wxALL, 5 ); + + item1->Add( item5, 0, wxALIGN_CENTRE|wxALL, 0 ); + + wxSizer *item8 = new wxBoxSizer( wxVERTICAL ); + + wxStaticText *item9 = new wxStaticText( parent, wxID_STATIC, _("&Use these packages:"), wxDefaultPosition, wxDefaultSize, 0 ); + item8->Add( item9, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + wxString *strs10 = (wxString*) NULL; + wxListBox *item10 = new wxListBox( parent, ecID_PACKAGES_DIALOG_USE_LIST, wxDefaultPosition, wxSize(180,190), 0, strs10, 0 ); + item8->Add( item10, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxBOTTOM, 5 ); + + item1->Add( item8, 1, wxGROW|wxALIGN_CENTER_HORIZONTAL|wxALL, 0 ); + + item0->Add( item1, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + wxStaticText *item11 = new wxStaticText( parent, wxID_STATIC, _("&Version:"), wxDefaultPosition, wxDefaultSize, 0 ); + item0->Add( item11, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 10 ); + + wxString *strs12 = (wxString*) NULL; + wxChoice *item12 = new wxChoice( parent, ecID_PACKAGES_DIALOG_VERSION, wxDefaultPosition, wxSize(100,-1), 0, strs12, 0 ); + item0->Add( item12, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 10 ); + + wxTextCtrl *item13 = new wxTextCtrl( parent, ecID_PACKAGES_DIALOG_DESCRIPTION, _(""), wxDefaultPosition, wxSize(80,70), wxTE_MULTILINE ); + item0->Add( item13, 1, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxBOTTOM, 10 ); + + wxSizer *item14 = new wxBoxSizer( wxHORIZONTAL ); + + wxButton *item15 = new wxButton( parent, wxID_OK, _("&OK"), wxDefaultPosition, wxDefaultSize, 0 ); + item15->SetDefault(); + item14->Add( item15, 0, wxALIGN_CENTRE|wxALL, 5 ); + + wxButton *item16 = new wxButton( parent, wxID_CANCEL, _("&Cancel"), wxDefaultPosition, wxDefaultSize, 0 ); + item14->Add( item16, 0, wxALIGN_CENTRE|wxALL, 5 ); + + item0->Add( item14, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxBOTTOM, 5 ); + +#if 0 + wxSizer *item0 = new wxBoxSizer( wxVERTICAL ); + + wxSizer *item1 = new wxBoxSizer( wxHORIZONTAL ); + + wxSizer *item2 = new wxBoxSizer( wxVERTICAL ); + + wxStaticText *item3 = new wxStaticText( parent, wxID_STATIC, "Available &packages:", wxDefaultPosition, wxDefaultSize, 0 ); + item2->Add( item3, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + wxListBox *item4 = new wxListBox( parent, ecID_PACKAGES_DIALOG_AVAILABLE_LIST, wxDefaultPosition, wxSize(180,190), 0, NULL, wxLB_EXTENDED|wxLB_HSCROLL|wxLB_SORT ); + item2->Add( item4, 0, wxALIGN_CENTRE|wxLEFT|wxRIGHT|wxBOTTOM, 5 ); + + item1->Add( item2, 0, wxALIGN_CENTRE|wxALL, 0 ); + + wxSizer *item5 = new wxBoxSizer( wxVERTICAL ); + + wxButton *item6 = new wxButton( parent, ecID_PACKAGES_DIALOG_ADD, "&Add >>", wxDefaultPosition, wxDefaultSize, 0 ); + item5->Add( item6, 0, wxALIGN_CENTRE|wxALL, 5 ); + + wxButton *item7 = new wxButton( parent, ecID_PACKAGES_DIALOG_REMOVE, "<< &Remove", wxDefaultPosition, wxDefaultSize, 0 ); + item5->Add( item7, 0, wxALIGN_CENTRE|wxALL, 5 ); + + item1->Add( item5, 0, wxALIGN_CENTRE|wxALL, 0 ); + + wxSizer *item8 = new wxBoxSizer( wxVERTICAL ); + + wxStaticText *item9 = new wxStaticText( parent, wxID_STATIC, "&Use these packages:", wxDefaultPosition, wxDefaultSize, 0 ); + item8->Add( item9, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + wxListBox *item10 = new wxListBox( parent, ecID_PACKAGES_DIALOG_USE_LIST, wxDefaultPosition, wxSize(180,190), 0, NULL, wxLB_EXTENDED|wxLB_HSCROLL|wxLB_SORT ); + item8->Add( item10, 0, wxALIGN_CENTRE|wxLEFT|wxRIGHT|wxBOTTOM, 5 ); + + item1->Add( item8, 0, wxALIGN_CENTRE|wxALL, 0 ); + + item0->Add( item1, 0, wxALIGN_CENTRE|wxALL, 5 ); + + wxStaticText *item11 = new wxStaticText( parent, wxID_STATIC, "&Version:", wxDefaultPosition, wxDefaultSize, 0 ); + item0->Add( item11, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 10 ); + + wxChoice *item12 = new wxChoice( parent, ecID_PACKAGES_DIALOG_VERSION, wxDefaultPosition, wxSize(100,-1), 0, NULL, 0 ); + item0->Add( item12, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 10 ); + + wxTextCtrl *item13 = new wxTextCtrl( parent, ecID_PACKAGES_DIALOG_DESCRIPTION, "", wxDefaultPosition, wxSize(80,70), wxTE_MULTILINE ); + item0->Add( item13, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxBOTTOM, 10 ); + + wxSizer *item14 = new wxBoxSizer( wxHORIZONTAL ); + + wxButton *item15 = new wxButton( parent, wxID_OK, "&OK", wxDefaultPosition, wxDefaultSize, 0 ); + item15->SetDefault(); + item14->Add( item15, 0, wxALIGN_CENTRE|wxALL, 5 ); + + wxButton *item16 = new wxButton( parent, wxID_CANCEL, "&Cancel", wxDefaultPosition, wxDefaultSize, 0 ); + item14->Add( item16, 0, wxALIGN_CENTRE|wxALL, 5 ); + +#ifdef __WXGTK__ + wxButton *contextButton = new wxContextHelpButton( parent ); + item14->Add( contextButton, 0, wxALIGN_CENTRE|wxALL, 5 ); +#endif + + item0->Add( item14, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxBOTTOM, 5 ); +#endif + +#ifdef __WXGTK__ + wxButton *contextButton = new wxContextHelpButton( parent ); + item14->Add( contextButton, 0, wxALIGN_CENTRE|wxALL, 5 ); +#endif + + parent->SetAutoLayout( TRUE ); + parent->SetSizer( item0 ); + parent->Layout(); + item0->Fit( parent ); + //item0->SetSizeHints( parent ); + + // Add context-sensitive help text + parent->FindWindow( ecID_PACKAGES_DIALOG_AVAILABLE_LIST )->SetHelpText(_("Displays the list of packages available, but not currently loaded.")); + parent->FindWindow( ecID_PACKAGES_DIALOG_USE_LIST )->SetHelpText(_("Displays the list of packages currently loaded.")); + parent->FindWindow( ecID_PACKAGES_DIALOG_ADD )->SetHelpText(_("Add one or more packages to the list to be loaded.")); + parent->FindWindow( ecID_PACKAGES_DIALOG_REMOVE )->SetHelpText(_("Removes one or more packages from the list to be loaded.")); + parent->FindWindow( ecID_PACKAGES_DIALOG_VERSION )->SetHelpText(_("Displays the version of the selected packages.")); + parent->FindWindow( ecID_PACKAGES_DIALOG_DESCRIPTION )->SetHelpText(_("Displays a description of the selected package (blank if more than one package is selected).")); + parent->FindWindow( wxID_OK )->SetHelpText(_("Closes the dialog and saves any changes you have made.")); + parent->FindWindow( wxID_CANCEL )->SetHelpText(_("Closes the dialog without saving any changes you have made.")); + +#if __WXGTK__ + parent->FindWindow( wxID_CONTEXT_HELP )->SetHelpText(_("Invokes context-sensitive help for the clicked-on window.")); +#endif + + // Add validators + parent->FindWindow( ecID_PACKAGES_DIALOG_DESCRIPTION )->SetValidator(wxGenericValidator(& m_packageDescription)); +} + +void ecPackagesDialog::OnInitDialog(wxInitDialogEvent& event) +{ + InitControls(); +} + +void ecPackagesDialog::InitControls() +{ + wxListBox* availableList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_AVAILABLE_LIST ); + wxListBox* useList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_USE_LIST ); + + // Initialize the controls + int i; + for (i = 0; i < GetCount()-1; i++) + { + const wxString& str = m_items[i]; + wxListBox* lb = m_arnItems[i] ? useList : availableList; + + lb->Append(str, (void*) i); + } + + UpdateAddRemoveButtons(); +} + +void ecPackagesDialog::OnCancel(wxCommandEvent& event) +{ + event.Skip(); +} + +void ecPackagesDialog::OnOK(wxCommandEvent& event) +{ + event.Skip(); +} + +void ecPackagesDialog::Add(wxListBox* from, wxListBox* to) +{ + wxArrayInt selections; + wxStringList selectionsStrings; + int n = from -> GetSelections( selections ); + + if (n > 0) + { + int i; + for (i = 0; i < selections.GetCount(); i++) + { + wxString str = from -> GetString(selections[i]); + selectionsStrings.Add(str); + } + + // Now delete from one list and remove from t'other + for (i = 0; i < selectionsStrings.Number(); i++) + { + wxString str = selectionsStrings[i]; + + // Remove + int toDelete = from -> FindString(str); + int itemIndex = -1; + if (toDelete > -1) + { + itemIndex = (int) from -> GetClientData(toDelete); + from -> Delete(toDelete); + } + + wxASSERT (itemIndex > -1); + + // Add + to -> Append(str, (void*) itemIndex); + + // Select it + int addedIndex = to->FindString(str); + to->Select(addedIndex); + + } + //ClearDescription(); + ClearSelections(* from); + UpdateHardwareSelectionFlag(); + UpdatePackageDescription(); + to->SetFocus(); + } +} + +void ecPackagesDialog::OnAdd(wxCommandEvent& event) +{ + if (m_bHardwarePackageSelected) + { + HardwarePackageMessageBox (); + return; + } + wxListBox* availableList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_AVAILABLE_LIST ); + wxListBox* useList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_USE_LIST ); + + Add(availableList, useList); + + UpdateAddRemoveButtons(); +} + +void ecPackagesDialog::OnRemove(wxCommandEvent& event) +{ + if (m_bHardwarePackageSelected) + { + HardwarePackageMessageBox (); + return; + } + + wxListBox* availableList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_AVAILABLE_LIST ); + wxListBox* useList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_USE_LIST ); + + Add(useList, availableList); + + UpdateAddRemoveButtons(); +} + +void ecPackagesDialog::OnDblClickListBox1(wxCommandEvent& event) +{ + if (m_bHardwarePackageSelected) + { + HardwarePackageMessageBox (); + return; + } + + wxListBox* availableList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_AVAILABLE_LIST ); + wxListBox* useList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_USE_LIST ); + + Add(availableList, useList); + + UpdateAddRemoveButtons(); +} + +void ecPackagesDialog::OnDblClickListBox2(wxCommandEvent& event) +{ + if (m_bHardwarePackageSelected) + { + HardwarePackageMessageBox (); + return; + } + + wxListBox* availableList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_AVAILABLE_LIST ); + wxListBox* useList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_USE_LIST ); + + Add(useList, availableList); + + UpdateAddRemoveButtons(); +} + +void ecPackagesDialog::OnClickListBox1(wxCommandEvent& event) +{ + wxListBox* availableList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_AVAILABLE_LIST ); + wxListBox* useList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_USE_LIST ); + +#if 0 + int sel = event.GetSelection(); + if (sel > -1) + { + // TODO: check that this works for multiple-selection listboxes + DisplayDescription(availableList->GetString(sel)); + } +#endif + + ClearSelections(*useList); + UpdatePackageDescription (); + UpdateVersionList (); + UpdateHardwareSelectionFlag (); + UpdateAddRemoveButtons(); +} + +void ecPackagesDialog::OnClickListBox2(wxCommandEvent& event) +{ + wxListBox* availableList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_AVAILABLE_LIST ); + wxListBox* useList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_USE_LIST ); + +#if 0 + int sel = event.GetSelection(); + if (sel > -1) + { + // TODO: check that this works for multiple-selection listboxes + DisplayDescription(useList->GetString(sel)); + } +#endif + + ClearSelections(*availableList); + UpdatePackageDescription (); + UpdateVersionList (); + UpdateHardwareSelectionFlag (); + UpdateAddRemoveButtons(); +} + +void ecPackagesDialog::OnSelectVersion(wxCommandEvent& event) +{ + wxListBox* availableList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_AVAILABLE_LIST ); + wxListBox* useList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_USE_LIST ); + wxChoice* versionChoice = (wxChoice*) FindWindow( ecID_PACKAGES_DIALOG_VERSION ); + + if (-1 == versionChoice->GetSelection ()) // if there is no version selection + return; // do nothing + + wxListBox * pListBox = NULL; + + wxArrayInt selected1, selected2; + availableList->GetSelections(selected1); + useList->GetSelections(selected2); + + int nListSelCount = selected1.GetCount (); + if (nListSelCount > 0) + { + pListBox = availableList; + } + else + { + nListSelCount = selected2.GetCount (); + if (nListSelCount) + pListBox = useList; + } + + wxASSERT (pListBox); + + if (!pListBox) + return; + + // retrieve the list box indices of the selected packages + + wxArrayInt* selected = (pListBox == availableList ? & selected1 : & selected2); + + int nIndex; + for (nIndex = 0; nIndex < nListSelCount; nIndex++) // for each selected package + { + // set the package version to that specified in the version combo box + wxString str = versionChoice->GetString(nIndex); + + // itemIndex is the index into the list of item names. It gets stored with all the listbox items. + int itemIndex = (int) pListBox->GetClientData((*selected)[nIndex]); + m_currentVersions[(size_t)itemIndex] = str; + } +} + +void ecPackagesDialog::Insert(const wxString& str, bool added, const wxString& descr, const wxString& version) +{ + wxListBox* availableList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_AVAILABLE_LIST ); + wxListBox* useList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_USE_LIST ); + + m_items.Add(str); + m_descriptions.Add(str); + m_currentVersions.Add(version); + m_arnItems.Add(added); + + //(added ? useList : availableList) -> Append(str); +} + +bool ecPackagesDialog::IsAdded(const wxString& str) +{ + return (((wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_USE_LIST ))->FindString(str) > -1) ; +} + +static int ecPositionInStringList(const wxStringList& list, const wxString& item) +{ + int i; + for (i = 0 ; i < list.Number(); i++) + if (list[i] == item) + return i; + else + i ++; + return -1; +} + +void ecPackagesDialog::DisplayDescription(const wxString& item) +{ + wxTextCtrl* descrCtrl = (wxTextCtrl*) FindWindow( ecID_PACKAGES_DIALOG_DESCRIPTION ) ; + + int pos = ecPositionInStringList(m_items, item); + if (pos > -1) + { + wxString descr = m_descriptions[pos]; + descrCtrl->SetValue(descr); + } +} + +void ecPackagesDialog::ClearDescription() +{ + wxTextCtrl* descrCtrl = (wxTextCtrl*) FindWindow( ecID_PACKAGES_DIALOG_DESCRIPTION ) ; + descrCtrl->SetValue(wxEmptyString); +} + +wxString ecPackagesDialog::GetVersion (const wxString& item) +{ + int nCount; + for (nCount = GetCount() - 1; nCount >= 0; --nCount) + { + if (m_items [nCount] == item) + { + return m_currentVersions [nCount]; + } + } + wxASSERT (FALSE); + return wxEmptyString; +} + +void ecPackagesDialog::UpdateHardwareSelectionFlag() +{ + m_bHardwarePackageSelected = FALSE; + + wxListBox* availableList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_AVAILABLE_LIST ); + wxListBox* useList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_USE_LIST ); + wxListBox * pListBox = NULL; + + wxArrayInt selections1, selections2; + wxArrayInt* selections = NULL; + availableList->GetSelections(selections1); + useList->GetSelections(selections2); + + int nListSelCount = selections1.GetCount (); + if (nListSelCount) + { + pListBox = availableList; + selections = & selections1; + } + else + { + nListSelCount = selections2.GetCount (); + if (nListSelCount) + { + pListBox = useList; + selections = & selections2; + } + } + + if (pListBox) // if there are packages selected + { + ecConfigToolDoc * pDoc = wxGetApp().GetConfigToolDoc (); + + // retrieve the list box indices of the selected packages + + //int * arnIndices = new int [nListSelCount]; + //pListBox->GetSelItems (nListSelCount, arnIndices); + + int nIndex; + for (nIndex = 0; nIndex < nListSelCount; nIndex++) // for each selected package + { + wxString strPackageAlias = pListBox->GetString((*selections)[nIndex]); + + // check if the package is a hardware package + + //TRACE (_T("Checking '%s' for hardware status\n"), strPackageAlias); + if (pDoc->GetCdlPkgData ()->is_hardware_package (ecUtils::UnicodeToStdStr (pDoc->GetPackageName (strPackageAlias)))) + { + m_bHardwarePackageSelected = TRUE; + break; + } + } + } +} + +void ecPackagesDialog::HardwarePackageMessageBox() +{ + // TODO: could give the user the choice of going to the template dialog. + wxMessageBox (wxT("Add and remove hardware packages by selecting a new hardware template."), + wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxOK, this); +} + +void ecPackagesDialog::UpdatePackageDescription () +{ + ecConfigToolDoc * pDoc = wxGetApp().GetConfigToolDoc (); + + wxListBox* availableList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_AVAILABLE_LIST ); + wxListBox* useList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_USE_LIST ); + + wxListBox * pListBox = NULL; + + wxArrayInt selections1, selections2; + wxArrayInt* selections = NULL; + availableList->GetSelections(selections1); + useList->GetSelections(selections2); + + if (1 == selections1.GetCount ()) + { + pListBox = availableList; + selections = & selections1; + } + else if (1 == selections2.GetCount ()) + { + pListBox = useList; + selections = & selections2; + } + + if (pListBox && selections) + { + int nIndex = (*selections)[0]; + wxString strPackageAlias = pListBox->GetString(nIndex); + m_packageDescription = pDoc->GetCdlPkgData ()->get_package_description (ecUtils::UnicodeToStdStr (pDoc->GetPackageName (strPackageAlias))).c_str (); + m_packageDescription = ecUtils::StripExtraWhitespace (m_packageDescription); + } + else + { + m_packageDescription = wxEmptyString; + } + TransferDataToWindow (); +} + +void ecPackagesDialog::UpdateVersionList () +{ + ecConfigToolDoc * pDoc = wxGetApp().GetConfigToolDoc (); + + wxListBox* availableList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_AVAILABLE_LIST ); + wxListBox* useList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_USE_LIST ); + wxChoice* versionChoice = (wxChoice*) FindWindow( ecID_PACKAGES_DIALOG_VERSION ); + + versionChoice->Clear(); // clear the version combo box + + wxArrayInt selections1, selections2; + wxArrayInt* selections = NULL; + availableList->GetSelections(selections1); + useList->GetSelections(selections2); + wxListBox* pListBox = NULL; + + if (selections1.GetCount () > 0) + { + pListBox = availableList; + selections = & selections1; + } + else if (selections2.GetCount () > 0) + { + pListBox = useList; + selections = & selections2; + } + + if (pListBox) // if there are packages selected + { + std::list common_versions; + bool bCommonSelectedVersion = true; + int nCommonVersionIndex=-1; + int nListSelCount = selections->GetCount(); + + // retrieve the list box indices of the selected packages + + //int * arnIndices = new int [nListSelCount]; + //pListBox->GetSelItems (nListSelCount, arnIndices); + int nIndex; + for (nIndex = 0; nIndex < nListSelCount; nIndex++) // for each selected package + { + // retrieve the first package alias + wxString strPackageAlias = pListBox->GetString ((*selections)[nIndex]); + + // retrieve the dialog item array index for use in + // comparing current version strings + const int nVersionIndex = (int) pListBox->GetClientData ((*selections)[nIndex]); + + // retrieve the installed version array + + //TRACE (_T("Retrieving versions for '%s'\n"), strPackageAlias); + const std::vector& versions = pDoc->GetCdlPkgData ()->get_package_versions (ecUtils::UnicodeToStdStr (pDoc->GetPackageName (strPackageAlias))); + + if (0 == nIndex) // if this is the first selected package + { + // use the version array to initialise a linked list of version + // strings held in common between the selected packages + unsigned int uCount; + for (uCount = 0; uCount < versions.size (); uCount++) + { + //TRACE (_T("Adding common version '%s'\n"), wxString (versions [uCount].c_str ())); + common_versions.push_back (versions [uCount]); + } + nCommonVersionIndex = nVersionIndex; // save the item array index + } + else // this is not the first selected package + { + std::list::iterator i_common_versions = common_versions.begin (); + while (i_common_versions != common_versions.end ()) // iterate through the common versions + { + if (versions.end () == std::find (versions.begin (), versions.end (), * i_common_versions)) // if the common version is not in the versions list + { + //TRACE (_T("Removing common version '%s'\n"), CString (i_common_versions->c_str ())); + common_versions.erase (i_common_versions++); // remove the version from the common versions list + } + else + { + i_common_versions++; + } + } + if (bCommonSelectedVersion) // if the selected versions of all preceding packages are identical + { + // check if the selected version of this package matches that of the preceding ones + bCommonSelectedVersion = (m_currentVersions [nVersionIndex] == m_currentVersions [nCommonVersionIndex]); + } + } + } + + // add the common versions to the version combo box + + std::list::iterator i_common_versions; + for (i_common_versions = common_versions.begin (); i_common_versions != common_versions.end (); i_common_versions++) + { + //TRACE (_T("Adding version '%s'\n"), CString (i_common_versions->c_str ())); + versionChoice->Append(wxString (i_common_versions->c_str ())); + } + + // select the common current version (if any) in the version combo box + + if (bCommonSelectedVersion) + { + //TRACE (_T("Selecting version '%s'\n"), m_arstrVersions [nCommonVersionIndex]); + versionChoice->SetStringSelection (m_currentVersions [nCommonVersionIndex]); + } + + // enable the version combo box only if there are multiple common versions + + versionChoice->Enable (common_versions.size () > 1); + } + else // there are no packages selected + { + versionChoice->Enable (FALSE); // disable the version combo box + } +} + +void ecPackagesDialog::UpdateAddRemoveButtons() +{ + wxListBox* availableList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_AVAILABLE_LIST ); + wxListBox* useList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_USE_LIST ); + + wxArrayInt selections1, selections2; + availableList->GetSelections(selections1); + useList->GetSelections(selections2); + + FindWindow( ecID_PACKAGES_DIALOG_ADD )->Enable( selections1.GetCount() > 0 ); + FindWindow( ecID_PACKAGES_DIALOG_REMOVE )->Enable( selections2.GetCount() > 0 ); +} + +void ecPackagesDialog::ClearSelections(wxListBox& lbox) +{ + int i; + for (i = 0; i < lbox.Number(); i++) + { + lbox.Deselect(i); + } +} diff --git a/host/tools/configtool/standalone/wxwin/packagesdlg.h b/host/tools/configtool/standalone/wxwin/packagesdlg.h new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/packagesdlg.h @@ -0,0 +1,116 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +// packagesdlg.h : +// +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): julians +// Contact(s): julians +// Date: 2000/09/28 +// Version: $Id: packagesdlg.h,v 1.2 2001/03/23 13:38:04 julians Exp $ +// Purpose: +// Description: Header file for ecPackagesDialog +// Requires: +// Provides: +// See also: +// Known bugs: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== + +#ifndef _ECOS_PACKAGESDLG_H_ +#define _ECOS_PACKAGESDLG_H_ + +#ifdef __GNUG__ +#pragma interface "packagesdlg.cpp" +#endif + +#include "ecutils.h" + +class ecPackagesDialog : public ecDialog +{ +public: +// Ctor(s) + ecPackagesDialog(wxWindow* parent); + ~ecPackagesDialog(); + +//// Event handlers + + void OnOK(wxCommandEvent& event); + void OnCancel(wxCommandEvent& event); + void OnAdd(wxCommandEvent& event); + void OnRemove(wxCommandEvent& event); + void OnClickListBox1(wxCommandEvent& event); + void OnClickListBox2(wxCommandEvent& event); + void OnDblClickListBox1(wxCommandEvent& event); + void OnDblClickListBox2(wxCommandEvent& event); + void OnSelectVersion(wxCommandEvent& event); + void OnInitDialog(wxInitDialogEvent& event); + +//// Operations + void CreateControls(wxWindow* parent); + void InitControls(); + void Insert(const wxString& str, bool added, const wxString& descr = wxEmptyString, const wxString& version = wxEmptyString); + void Add(wxListBox* from, wxListBox* to); + void DisplayDescription(const wxString& item); + void ClearDescription(); + void HardwarePackageMessageBox(); + void UpdateHardwareSelectionFlag(); + void UpdatePackageDescription(); + void UpdateVersionList(); + void UpdateAddRemoveButtons(); + void ClearSelections(wxListBox& lbox); + +//// Accessors + bool IsAdded(const wxString& str) ; + int GetCount() const { return m_items.Number(); } + wxString GetVersion (const wxString& item); + +protected: + +private: + DECLARE_EVENT_TABLE() + + wxStringList m_items; + wxStringList m_descriptions; + wxArrayString m_currentVersions; + wxArrayInt m_arnItems; // Whether in 'use list' (1) or not (0) + + bool m_bHardwarePackageSelected; + wxString m_packageDescription; +}; + +#define ecID_PACKAGES_DIALOG_AVAILABLE_LIST 10066 +#define ecID_PACKAGES_DIALOG_ADD 10067 +#define ecID_PACKAGES_DIALOG_REMOVE 10068 +#define ecID_PACKAGES_DIALOG_USE_LIST 10069 +#define ecID_PACKAGES_DIALOG_VERSION 10070 +#define ecID_PACKAGES_DIALOG_DESCRIPTION 10071 + +#endif + // _ECOS_PACKAGESDLG_H_ diff --git a/host/tools/configtool/standalone/wxwin/platformeditordlg.cpp b/host/tools/configtool/standalone/wxwin/platformeditordlg.cpp new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/platformeditordlg.cpp @@ -0,0 +1,311 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +// platformsdlg.cpp : +// +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): julians +// Contact(s): julians +// Date: 2000/09/06 +// Version: $Id: platformeditordlg.cpp,v 1.3 2001/03/23 13:38:04 julians Exp $ +// Purpose: +// Description: Implementation file for the ecPlatformEditorDialog +// Requires: +// Provides: +// See also: +// Known bugs: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== + +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- +#ifdef __GNUG__ +#pragma implementation "platformeditordlg.h" +#endif + +// Includes other headers for precompiled compilation +#include "ecpch.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#include "wx/cshelp.h" +#include "wx/valgen.h" + +#include "eCosTestPlatform.h" +#include "configtool.h" +#include "platformeditordlg.h" + +#ifdef __WXMSW__ +#include "wx/msw/winundef.h" +#endif + +#ifdef __WXMSW__ +static const wxChar* g_NewLineToReplace = wxT("\r\n"); +#else +static const wxChar* g_NewLineToReplace = wxT("\n"); +#endif + +BEGIN_EVENT_TABLE(ecPlatformEditorDialog, ecDialog) + EVT_BUTTON(wxID_OK, ecPlatformEditorDialog::OnOK) + EVT_BUTTON(wxID_CANCEL, ecPlatformEditorDialog::OnCancel) + EVT_COMBOBOX(ecID_MODIFY_PLATFORM_PREFIX, ecPlatformEditorDialog::OnChangeNewPlatformPrefix) + //EVT_TEXT(ecID_MODIFY_PLATFORM_NAME, ecPlatformEditorDialog::OnChangeNewPlatform) + EVT_INIT_DIALOG(ecPlatformEditorDialog::OnInitDialog) +END_EVENT_TABLE() + +// ---------------------------------------------------------------------------- +// main frame +// ---------------------------------------------------------------------------- + +// Frame constructor +ecPlatformEditorDialog::ecPlatformEditorDialog(wxWindow* parent) +{ + m_bServerSideGdb = FALSE; + + SetExtraStyle(wxDIALOG_EX_CONTEXTHELP); + + ecDialog::Create(parent, ecID_PLATFORM_EDITOR_DIALOG, _("Platforms"), + wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER); + + CreateControls(this); + + Centre(wxBOTH); +} + +void ecPlatformEditorDialog::OnInitDialog(wxInitDialogEvent& event) +{ + m_strGDB.Replace(wxT(";"), g_NewLineToReplace); + + wxComboBox* comboBox = (wxComboBox*) FindWindow(ecID_MODIFY_PLATFORM_PREFIX); + + unsigned int i; + for ( i=0 ; i < CeCosTestPlatform::Count() ; i++ ) + { + comboBox->Append(CeCosTestPlatform::Get(i)->Prefix()); + } + + wxDialog::OnInitDialog(event); + + SetTitle(m_strCaption); + if( ! m_strPlatform.IsEmpty() ) + { + ((wxTextCtrl*)FindWindow(ecID_MODIFY_PLATFORM_NAME))->SetValue(m_strPlatform); + + FindWindow(ecID_MODIFY_PLATFORM_NAME)->Enable(FALSE); + } + + FindWindow(wxID_OK)->Enable(!m_strPlatform.IsEmpty() && !m_strPrefix.IsEmpty()); +} + +void ecPlatformEditorDialog::CreateControls(wxWindow* parent) +{ + wxSizer *item0 = new wxBoxSizer( wxVERTICAL ); + + wxSizer *item1 = new wxFlexGridSizer( 2, 0, 0 ); + + wxStaticText *item2 = new wxStaticText( parent, wxID_STATIC, _("Platform &name:"), wxDefaultPosition, wxDefaultSize, 0 ); + item1->Add( item2, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + wxTextCtrl *item3 = new wxTextCtrl( parent, ecID_MODIFY_PLATFORM_NAME, _(""), wxDefaultPosition, wxSize(240,-1), 0 ); + item1->Add( item3, 0, wxGROW|wxALL, 5 ); + + wxStaticText *item4 = new wxStaticText( parent, wxID_STATIC, _("Command &prefix:"), wxDefaultPosition, wxDefaultSize, 0 ); + item1->Add( item4, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + wxString *strs5 = (wxString*) NULL; + wxComboBox *item5 = new wxComboBox( parent, ecID_MODIFY_PLATFORM_PREFIX, "", wxDefaultPosition, wxDefaultSize, 0, strs5, wxCB_DROPDOWN ); + item1->Add( item5, 0, wxGROW|wxALL, 5 ); + + wxStaticText *item6 = new wxStaticText( parent, wxID_STATIC, _("Arguments for &GDB:"), wxDefaultPosition, wxDefaultSize, 0 ); + item1->Add( item6, 0, wxALL, 5 ); + + wxTextCtrl *item7 = new wxTextCtrl( parent, ecID_MODIFY_PLATFORM_ARGS, _(""), wxDefaultPosition, wxSize(-1,140), wxTE_MULTILINE ); + item1->Add( item7, 0, wxGROW|wxALL, 5 ); + + wxStaticText *item8 = new wxStaticText( parent, wxID_STATIC, _("Inferior:"), wxDefaultPosition, wxDefaultSize, 0 ); + item1->Add( item8, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + wxTextCtrl *item9 = new wxTextCtrl( parent, ecID_MODIFY_PLATFORM_INFERIOR, _(""), wxDefaultPosition, wxDefaultSize, 0 ); + item1->Add( item9, 0, wxGROW|wxALL, 5 ); + + wxStaticText *item10 = new wxStaticText( parent, wxID_STATIC, _("Prompt:"), wxDefaultPosition, wxDefaultSize, 0 ); + item1->Add( item10, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + wxTextCtrl *item11 = new wxTextCtrl( parent, ecID_MODIFY_PLATFORM_PROMPT, _(""), wxDefaultPosition, wxDefaultSize, 0 ); + item1->Add( item11, 0, wxGROW|wxALL, 5 ); + + item1->Add( 20, 20, 0, wxALIGN_CENTRE|wxALL, 5 ); + + wxCheckBox *item12 = new wxCheckBox( parent, ecID_MODIFY_PLATFORM_SS_GDB, _("Server-side GDB"), wxDefaultPosition, wxDefaultSize, 0 ); + item1->Add( item12, 0, wxGROW|wxALL, 5 ); + + item0->Add( item1, 1, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + wxSizer *item13 = new wxBoxSizer( wxHORIZONTAL ); + + wxButton *item14 = new wxButton( parent, wxID_OK, _("&OK"), wxDefaultPosition, wxDefaultSize, 0 ); + item14->SetDefault(); + item13->Add( item14, 0, wxALIGN_CENTRE|wxALL, 5 ); + + wxButton *item15 = new wxButton( parent, wxID_CANCEL, _("&Cancel"), wxDefaultPosition, wxDefaultSize, 0 ); + item13->Add( item15, 0, wxALIGN_CENTRE|wxALL, 5 ); + +#ifdef __WXGTK__ + wxButton *contextButton = new wxContextHelpButton( parent ); + item13->Add( contextButton, 0, wxALIGN_CENTRE|wxALL, 5 ); +#endif + + item0->Add( item13, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + +#if 0 + wxSizer *item0 = new wxBoxSizer( wxVERTICAL ); + + wxSizer *item1 = new wxFlexGridSizer( 2, 0, 0 ); + + wxStaticText *item2 = new wxStaticText( parent, wxID_STATIC, "Platform &name:", wxDefaultPosition, wxDefaultSize, 0 ); + item1->Add( item2, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + wxTextCtrl *item3 = new wxTextCtrl( parent, ecID_MODIFY_PLATFORM_NAME, "", wxDefaultPosition, wxSize(200,-1), 0 ); + item1->Add( item3, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + wxStaticText *item4 = new wxStaticText( parent, wxID_STATIC, "Command &prefix:", wxDefaultPosition, wxDefaultSize, 0 ); + item1->Add( item4, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + wxComboBox *item5 = new wxComboBox( parent, ecID_MODIFY_PLATFORM_PREFIX, "", wxDefaultPosition, wxSize(100,-1), 0, NULL, wxCB_DROPDOWN ); + item1->Add( item5, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + wxStaticText *item6 = new wxStaticText( parent, wxID_STATIC, "Arguments for &GDB:", wxDefaultPosition, wxDefaultSize, 0 ); + item1->Add( item6, 0, wxALL, 5 ); + + wxTextCtrl *item7 = new wxTextCtrl( parent, ecID_MODIFY_PLATFORM_ARGS, "", wxDefaultPosition, wxSize(80,140), wxTE_MULTILINE ); + item1->Add( item7, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + wxStaticText *item8 = new wxStaticText( parent, wxID_STATIC, "Inferior:", wxDefaultPosition, wxDefaultSize, 0 ); + item1->Add( item8, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + wxTextCtrl *item9 = new wxTextCtrl( parent, ecID_MODIFY_PLATFORM_INFERIOR, "", wxDefaultPosition, wxSize(80,-1), 0 ); + item1->Add( item9, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + wxStaticText *item10 = new wxStaticText( parent, wxID_STATIC, "Prompt:", wxDefaultPosition, wxDefaultSize, 0 ); + item1->Add( item10, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + wxTextCtrl *item11 = new wxTextCtrl( parent, ecID_MODIFY_PLATFORM_PROMPT, "", wxDefaultPosition, wxSize(80,-1), 0 ); + item1->Add( item11, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + item1->Add( 20, 20, 0, wxALIGN_CENTRE|wxALL, 5 ); + + wxCheckBox *item12 = new wxCheckBox( parent, ecID_MODIFY_PLATFORM_SS_GDB, "Server-side GDB", wxDefaultPosition, wxDefaultSize, 0 ); + item1->Add( item12, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + item0->Add( item1, 0, wxALIGN_CENTRE|wxALL, 5 ); + + wxSizer *item13 = new wxBoxSizer( wxHORIZONTAL ); + + wxButton *item14 = new wxButton( parent, wxID_OK, "&OK", wxDefaultPosition, wxDefaultSize, 0 ); + item13->Add( item14, 0, wxALIGN_CENTRE|wxALL, 5 ); + + wxButton *item15 = new wxButton( parent, wxID_CANCEL, "&Cancel", wxDefaultPosition, wxDefaultSize, 0 ); + item13->Add( item15, 0, wxALIGN_CENTRE|wxALL, 5 ); + +#ifdef __WXGTK__ + wxButton *contextButton = new wxContextHelpButton( parent ); + item13->Add( contextButton, 0, wxALIGN_CENTRE|wxALL, 5 ); +#endif + + item0->Add( item13, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); +#endif + + // Can't do this from wxDesigner :-( + ((wxFlexGridSizer*)item1)->AddGrowableCol(1); + ((wxFlexGridSizer*)item1)->AddGrowableRow(2); + + parent->SetAutoLayout( TRUE ); + parent->SetSizer( item0 ); + parent->Layout(); + item0->Fit( parent ); + item0->SetSizeHints( parent ); + + item3->SetFocus(); + item14->SetDefault(); + + // Add context-sensitive help text + parent->FindWindow( ecID_MODIFY_PLATFORM_NAME )->SetHelpText(_("Specifies the name of the platform. Platform names are arbitrary strings, but must be unique for a given user.")); + parent->FindWindow( ecID_MODIFY_PLATFORM_PREFIX )->SetHelpText(_("Specifies the prefix to be used when invoking tools (for example, 'arm-elf' is the correct prefix if the appropriate gdb executable is arm-elf-gdb.exe).")); + parent->FindWindow( ecID_MODIFY_PLATFORM_ARGS )->SetHelpText(_("Specifies any additional arguments to be used when invoking gdb.")); + parent->FindWindow( ecID_MODIFY_PLATFORM_INFERIOR )->SetHelpText(_("TODO")); + parent->FindWindow( ecID_MODIFY_PLATFORM_PROMPT )->SetHelpText(_("TODO")); + parent->FindWindow( ecID_MODIFY_PLATFORM_SS_GDB )->SetHelpText(_("TODO")); + parent->FindWindow( wxID_OK )->SetHelpText(_("Closes the dialog and saves any changes you have made.")); + parent->FindWindow( wxID_CANCEL )->SetHelpText(_("Closes the dialog without saving any changes you have made.")); + +#if __WXGTK__ + parent->FindWindow( wxID_CONTEXT_HELP )->SetHelpText(_("Invokes context-sensitive help for the clicked-on window.")); +#endif + + // Add validators + parent->FindWindow( ecID_MODIFY_PLATFORM_NAME )->SetValidator(wxGenericValidator(& m_strPlatform)); + parent->FindWindow( ecID_MODIFY_PLATFORM_PREFIX )->SetValidator(wxGenericValidator(& m_strPrefix)); + parent->FindWindow( ecID_MODIFY_PLATFORM_ARGS )->SetValidator(wxGenericValidator(& m_strGDB)); + parent->FindWindow( ecID_MODIFY_PLATFORM_INFERIOR )->SetValidator(wxGenericValidator(& m_strInferior)); + parent->FindWindow( ecID_MODIFY_PLATFORM_PROMPT )->SetValidator(wxGenericValidator(& m_strPrompt)); + parent->FindWindow( ecID_MODIFY_PLATFORM_SS_GDB )->SetValidator(wxGenericValidator(& m_bServerSideGdb)); +} + +void ecPlatformEditorDialog::OnChangeNewPlatformPrefix(wxCommandEvent& event) +{ + TransferDataFromWindow(); + FindWindow(wxID_OK)->Enable(!m_strPlatform.IsEmpty() && !m_strPrefix.IsEmpty()); +} + +void ecPlatformEditorDialog::OnChangeNewPlatform(wxCommandEvent& event) +{ + TransferDataFromWindow(); + FindWindow(wxID_OK)->Enable(!m_strPlatform.IsEmpty() && !m_strPrefix.IsEmpty()); +} + +void ecPlatformEditorDialog::OnCancel(wxCommandEvent& event) +{ + event.Skip(); +} + +void ecPlatformEditorDialog::OnOK(wxCommandEvent& event) +{ + TransferDataFromWindow(); + + m_strGDB.Replace(g_NewLineToReplace, wxT(";")); + + EndModal(wxID_OK); +} diff --git a/host/tools/configtool/standalone/wxwin/platformeditordlg.h b/host/tools/configtool/standalone/wxwin/platformeditordlg.h new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/platformeditordlg.h @@ -0,0 +1,93 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +// platformeditordlg.h : +// +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): julians +// Contact(s): julians +// Date: 2000/09/06 +// Version: $Id: platformeditordlg.h,v 1.2 2001/03/23 13:38:04 julians Exp $ +// Purpose: +// Description: Header file for ecPlatformEditorDialog +// Requires: +// Provides: +// See also: +// Known bugs: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== + +#ifndef _ECOS_PLATFORMEDITORDLG_H_ +#define _ECOS_PLATFORMEDITORDLG_H_ + +#ifdef __GNUG__ +#pragma interface "platformeditordlg.cpp" +#endif + +#include "ecutils.h" + +class ecPlatformEditorDialog : public ecDialog +{ +public: +// Ctor(s) + ecPlatformEditorDialog(wxWindow* parent); + +//// Event handlers + + void OnOK(wxCommandEvent& event); + void OnCancel(wxCommandEvent& event); + void OnChangeNewPlatformPrefix(wxCommandEvent& event); + void OnChangeNewPlatform(wxCommandEvent& event); + void OnInitDialog(wxInitDialogEvent& event); + +//// Operations + void CreateControls(wxWindow* parent); + + wxString m_strCaption; + wxString m_strPlatform; + wxString m_strPrefix; + wxString m_strGDB; + wxString m_strInferior; + wxString m_strPrompt; + bool m_bServerSideGdb; +protected: + +private: + DECLARE_EVENT_TABLE() +}; + +#define ecID_MODIFY_PLATFORM_NAME 10031 +#define ecID_MODIFY_PLATFORM_PREFIX 10032 +#define ecID_MODIFY_PLATFORM_ARGS 10033 +#define ecID_MODIFY_PLATFORM_INFERIOR 10034 +#define ecID_MODIFY_PLATFORM_PROMPT 10035 +#define ecID_MODIFY_PLATFORM_SS_GDB 10036 + +#endif + // _ECOS_PLATFORMEDITORDLG_H_ diff --git a/host/tools/configtool/standalone/wxwin/platformsdlg.cpp b/host/tools/configtool/standalone/wxwin/platformsdlg.cpp new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/platformsdlg.cpp @@ -0,0 +1,382 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +// platformsdlg.cpp : +// +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): julians +// Contact(s): julians +// Date: 2000/09/06 +// Version: $Id: platformsdlg.cpp,v 1.2 2001/03/23 13:38:04 julians Exp $ +// Purpose: +// Description: Implementation file for the ecPlatformsDialog +// Requires: +// Provides: +// See also: +// Known bugs: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== + +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- +#ifdef __GNUG__ +#pragma implementation "platformsdlg.h" +#endif + +// Includes other headers for precompiled compilation +#include "ecpch.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#include "wx/cshelp.h" + +#include "configtool.h" +#include "platformsdlg.h" +#include "platformeditordlg.h" + +#ifdef __WXMSW__ +#include "wx/msw/winundef.h" +#endif + +BEGIN_EVENT_TABLE(ecPlatformsDialog, ecDialog) + EVT_BUTTON(ecID_PLATFORMS_MODIFY, ecPlatformsDialog::OnModify) + EVT_BUTTON(ecID_PLATFORMS_ADD, ecPlatformsDialog::OnAdd) + EVT_BUTTON(ecID_PLATFORMS_DELETE, ecPlatformsDialog::OnDelete) + EVT_BUTTON(wxID_OK, ecPlatformsDialog::OnOK) + EVT_BUTTON(wxID_CANCEL, ecPlatformsDialog::OnCancel) + EVT_UPDATE_UI(ecID_PLATFORMS_MODIFY, ecPlatformsDialog::OnUpdateAny) + EVT_UPDATE_UI(ecID_PLATFORMS_DELETE, ecPlatformsDialog::OnUpdateAny) +END_EVENT_TABLE() + +const wxChar* ecPlatformsDialog::sm_arpszTypes[]={ + wxT("Hardware with breakpoint support"), + wxT("Simulator"), + wxT("Synthetic target"), + wxT("Hardware without breakpoint support"), + wxT("Remote simulator") +}; + + +// Frame constructor +ecPlatformsDialog::ecPlatformsDialog(wxWindow* parent) +{ + m_listCtrl = NULL; + + SetExtraStyle(wxDIALOG_EX_CONTEXTHELP); + + ecDialog::Create(parent, ecID_PLATFORMS_DIALOG, _("Platforms"), + wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER); + + CreateControls(this); + + Centre(wxBOTH); + + unsigned int i; + for(i=0; i < CeCosTestPlatform::Count(); i++) + { + Add(*CeCosTestPlatform::Get(i)); + } +} + +ecPlatformsDialog::~ecPlatformsDialog() +{ + Clear(); +} + +void ecPlatformsDialog::Clear() +{ + wxNode* node = m_arTargetInfo.First(); + while (node) + { + CeCosTestPlatform* platform = (CeCosTestPlatform*) node->Data(); + delete platform; + node = node->Next(); + } + m_arTargetInfo.Clear(); +} + +void ecPlatformsDialog::CreateControls(wxWindow* parent) +{ + // Create custom windows first + m_listCtrl = new ecPlatformsListCtrl(parent, ecID_PLATFORMS_LIST, wxDefaultPosition, wxSize(450, 300), wxLC_REPORT|wxCLIP_CHILDREN|wxSUNKEN_BORDER); + m_listCtrl->InsertColumn(0, _("Target"), wxLIST_FORMAT_LEFT, 70); + m_listCtrl->InsertColumn(1, _("Prefix"), wxLIST_FORMAT_LEFT, 70); + m_listCtrl->InsertColumn(2, _("Commands"), wxLIST_FORMAT_LEFT, 70); + m_listCtrl->InsertColumn(3, _("Inferior"), wxLIST_FORMAT_LEFT, 70); + m_listCtrl->InsertColumn(4, _("Prompt"), wxLIST_FORMAT_LEFT, 70); + m_listCtrl->InsertColumn(5, _("ServerSideGdb"), wxLIST_FORMAT_LEFT, 80); + + wxSizer *item0 = new wxBoxSizer( wxVERTICAL ); + + wxSizer *item1 = new wxBoxSizer( wxHORIZONTAL ); + + wxButton *item2 = new wxButton( parent, ecID_PLATFORMS_MODIFY, _("&Modify..."), wxDefaultPosition, wxDefaultSize, 0 ); + item1->Add( item2, 0, wxALIGN_CENTRE|wxALL, 5 ); + + wxButton *item3 = new wxButton( parent, ecID_PLATFORMS_ADD, _("&Add..."), wxDefaultPosition, wxDefaultSize, 0 ); + item1->Add( item3, 0, wxALIGN_CENTRE|wxALL, 5 ); + + wxButton *item4 = new wxButton( parent, ecID_PLATFORMS_DELETE, _("&Delete..."), wxDefaultPosition, wxDefaultSize, 0 ); + item1->Add( item4, 0, wxALIGN_CENTRE|wxALL, 5 ); + + wxButton *item5 = new wxButton( parent, wxID_OK, _("&OK"), wxDefaultPosition, wxDefaultSize, 0 ); + item1->Add( item5, 0, wxALIGN_CENTRE|wxALL, 5 ); + + wxButton *item6 = new wxButton( parent, wxID_CANCEL, _("&Cancel"), wxDefaultPosition, wxDefaultSize, 0 ); + item1->Add( item6, 0, wxALIGN_CENTRE|wxALL, 5 ); + +#ifdef __WXGTK__ + wxButton *contextButton = new wxContextHelpButton( parent ); + item1->Add( contextButton, 0, wxALIGN_CENTRE|wxALL, 5 ); +#endif + + item0->Add( item1, 0, wxALIGN_CENTRE|wxALL, 5 ); + + wxWindow *item7 = parent->FindWindow( ecID_PLATFORMS_LIST ); + wxASSERT( item7 ); + item0->Add( item7, 2, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + +#if 0 + wxSizer *item0 = new wxBoxSizer( wxVERTICAL ); + + wxSizer *item1 = new wxBoxSizer( wxHORIZONTAL ); + + wxButton *item2 = new wxButton( parent, ecID_PLATFORMS_MODIFY, "&Modify...", wxDefaultPosition, wxDefaultSize, 0 ); + item1->Add( item2, 0, wxALIGN_CENTRE|wxALL, 5 ); + + wxButton *item3 = new wxButton( parent, ecID_PLATFORMS_ADD, "&Add...", wxDefaultPosition, wxDefaultSize, 0 ); + item1->Add( item3, 0, wxALIGN_CENTRE|wxALL, 5 ); + + wxButton *item4 = new wxButton( parent, ecID_PLATFORMS_DELETE, "&Delete...", wxDefaultPosition, wxDefaultSize, 0 ); + item1->Add( item4, 0, wxALIGN_CENTRE|wxALL, 5 ); + + wxButton *item5 = new wxButton( parent, wxID_OK, "&OK", wxDefaultPosition, wxDefaultSize, 0 ); + item1->Add( item5, 0, wxALIGN_CENTRE|wxALL, 5 ); + + wxButton *item6 = new wxButton( parent, wxID_CANCEL, "&Cancel", wxDefaultPosition, wxDefaultSize, 0 ); + item1->Add( item6, 0, wxALIGN_CENTRE|wxALL, 5 ); + +#ifdef __WXGTK__ + wxButton *contextButton = new wxContextHelpButton( parent ); + item1->Add( contextButton, 0, wxALIGN_CENTRE|wxALL, 5 ); +#endif + + item0->Add( item1, 0, wxALIGN_CENTRE|wxALL, 0 ); + + wxWindow *item7 = parent->FindWindow( ecID_PLATFORMS_LIST ); + wxASSERT( item7 ); + item0->Add( item7, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); +#endif + + parent->SetAutoLayout( TRUE ); + parent->SetSizer( item0 ); + parent->Layout(); + item0->Fit( parent ); + item0->SetSizeHints( parent ); + + ((wxButton*) FindWindow(wxID_OK))->SetDefault(); + + // Add context-sensitive help text + parent->FindWindow( ecID_PLATFORMS_LIST )->SetHelpText(_("Displays the list of platforms.")); + parent->FindWindow( ecID_PLATFORMS_MODIFY )->SetHelpText(_("Changes the characteristics of the currently selected platform.")); + parent->FindWindow( ecID_PLATFORMS_ADD )->SetHelpText(_("Adds a new platform.")); + parent->FindWindow( ecID_PLATFORMS_DELETE )->SetHelpText(_("Removes the currently selected platform.")); + parent->FindWindow( wxID_OK )->SetHelpText(_("Closes the dialog and saves any changes you have made.")); + parent->FindWindow( wxID_CANCEL )->SetHelpText(_("Closes the dialog without saving any changes you have made.")); + +#if __WXGTK__ + parent->FindWindow( wxID_CONTEXT_HELP )->SetHelpText(_("Invokes context-sensitive help for the clicked-on window.")); +#endif +} + +void ecPlatformsDialog::OnModify(wxCommandEvent& event) +{ + long n = m_listCtrl->GetItemCount(); + long i; + for (i = 0; i < n; i++) + { + if (m_listCtrl->GetItemState(i, wxLIST_STATE_SELECTED) & wxLIST_STATE_SELECTED) + { + CeCosTestPlatform *pti=Platform(i); + + ecPlatformEditorDialog dlg(this); + + dlg.m_strPlatform = pti->Name(); + dlg.m_strPrefix = pti->Prefix(); + dlg.m_strGDB = pti->GdbCmds(); + dlg.m_strCaption = wxT("Modify Platform"); + dlg.m_strPrompt = pti->Prompt(); + dlg.m_bServerSideGdb = pti->ServerSideGdb(); + dlg.m_strInferior = pti->Inferior(); + + if ( wxID_CANCEL != dlg.ShowModal() ) + { + *pti = CeCosTestPlatform(dlg.m_strPlatform,dlg.m_strPrefix,dlg.m_strPrompt,dlg.m_strGDB,dlg.m_bServerSideGdb,dlg.m_strInferior); + m_listCtrl->SetItem(i, 1, pti->Prefix()); + m_listCtrl->SetItem(i, 2, pti->GdbCmds()); + m_listCtrl->SetItem(i, 3, pti->Inferior()); + m_listCtrl->SetItem(i, 4, pti->Prompt()); + m_listCtrl->SetItem(i, 5, pti->ServerSideGdb() ? wxT("Y") : wxT("N")); + } + } + } +} + +static long ecFindListCtrlSelection(long& whereFrom, wxListCtrl* listCtrl) +{ + long n = listCtrl->GetItemCount(); + long i; + for (i = whereFrom; i < n; i++) + { + if (listCtrl->GetItemState(i, wxLIST_STATE_SELECTED) & wxLIST_STATE_SELECTED) + { + whereFrom = i+1; + return i; + } + } + return -1; +} + +void ecPlatformsDialog::OnDelete(wxCommandEvent& event) +{ + long sel = -1; + long whereFrom = 0; + do + { + sel = ecFindListCtrlSelection(whereFrom, m_listCtrl); + if (sel > -1) + { + if (wxYES == wxMessageBox(wxT("Are you sure you wish to delete this platform?"), wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxYES_NO, this)) + { + delete Platform(sel); + m_listCtrl->DeleteItem(sel); + delete m_arTargetInfo.Nth(sel); + whereFrom = 0; + } + } + } while (sel > -1) ; +} + +void ecPlatformsDialog::OnAdd(wxCommandEvent& event) +{ + ecPlatformEditorDialog dlg(this); + dlg.m_strCaption = wxT("New Platform"); + if (wxID_OK == dlg.ShowModal()) + { + if( -1 == m_listCtrl->FindItem(-1, dlg.m_strPlatform) ) + { + Add(CeCosTestPlatform(dlg.m_strPlatform,dlg.m_strPrefix,dlg.m_strPrompt,dlg.m_strGDB,dlg.m_bServerSideGdb,dlg.m_strInferior)); + } else { + wxMessageBox(wxT("That platform name is already in use."), wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxOK, this); + } + } +} + +void ecPlatformsDialog::OnCancel(wxCommandEvent& event) +{ + event.Skip(); +} + +void ecPlatformsDialog::OnOK(wxCommandEvent& event) +{ + event.Skip(); +} + +void ecPlatformsDialog::Add(const CeCosTestPlatform &ti) +{ + wxListCtrl* listCtrl = (wxListCtrl*) FindWindow( ecID_PLATFORMS_LIST ); + int i = listCtrl->GetItemCount(); + + listCtrl->InsertItem(i,ti.Name()); + listCtrl->SetItem(i,1,ti.Prefix()); + listCtrl->SetItem(i,2,ti.GdbCmds()); + listCtrl->SetItem(i,3,ti.Inferior()); + listCtrl->SetItem(i,4,ti.Prompt()); + listCtrl->SetItem(i,5,ti.ServerSideGdb() ? wxT("Y"):wxT("N")); + + m_arTargetInfo.Append((wxObject*) new CeCosTestPlatform(ti)); +} + +void ecPlatformsDialog::OnUpdateAny(wxUpdateUIEvent& event) +{ + event.Enable( m_listCtrl->GetSelectedItemCount() > 0 ); +} + +void ecPlatformsDialog::OnDoubleLClick() +{ + wxCommandEvent event; + OnModify(event); +} + +void ecPlatformsDialog::OnDeleteKey() +{ + wxCommandEvent event; + OnDelete(event); +} + +/* + * ecPlatformsListCtrl + */ + +IMPLEMENT_CLASS(ecPlatformsListCtrl, wxListCtrl) + +BEGIN_EVENT_TABLE(ecPlatformsListCtrl, wxListCtrl) + EVT_LEFT_DCLICK(ecPlatformsListCtrl::OnDoubleLClick) + EVT_CHAR(ecPlatformsListCtrl::OnChar) +END_EVENT_TABLE() + +ecPlatformsListCtrl::ecPlatformsListCtrl(wxWindow* parent, wxWindowID id, const wxPoint& pt, + const wxSize& sz, long style): + wxListCtrl(parent, id, pt, sz, style) +{ +} + +void ecPlatformsListCtrl::OnDoubleLClick(wxMouseEvent& event) +{ + ecPlatformsDialog* parent = (ecPlatformsDialog*) GetParent(); + parent->OnDoubleLClick(); +} + +void ecPlatformsListCtrl::OnChar(wxKeyEvent& event) +{ + if (event.GetKeyCode() == WXK_DELETE) + { + ecPlatformsDialog* parent = (ecPlatformsDialog*) GetParent(); + parent->OnDeleteKey(); + } + else + event.Skip(); +} diff --git a/host/tools/configtool/standalone/wxwin/platformsdlg.h b/host/tools/configtool/standalone/wxwin/platformsdlg.h new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/platformsdlg.h @@ -0,0 +1,131 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +// platformsdlg.h : +// +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): julians +// Contact(s): julians +// Date: 2000/09/06 +// Version: $Id: platformsdlg.h,v 1.2 2001/03/23 13:38:04 julians Exp $ +// Purpose: +// Description: Header file for ecPlatformsDialog +// Requires: +// Provides: +// See also: +// Known bugs: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== + +#ifndef _ECOS_PLATFORMSDLG_H_ +#define _ECOS_PLATFORMSDLG_H_ + +#ifdef __GNUG__ +#pragma interface "platformsdlg.cpp" +#endif + +#include "wx/wx.h" +#include "wx/listctrl.h" + +#include "eCosTest.h" +#include "ecutils.h" + +/* + * ecPlatformsListCtrl + * + * A list control for the platforms dialog + */ + +class ecPlatformsListCtrl : public wxListCtrl +{ +public: +// Ctor(s) + ecPlatformsListCtrl(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style); + +//// Event handlers + void OnChar(wxKeyEvent& event); + void OnDoubleLClick(wxMouseEvent& event); + +//// Operations + +protected: +private: + DECLARE_EVENT_TABLE() + DECLARE_CLASS(ecPlatformsListCtrl) +}; + +/* + * ecPlatformsDialog + * + */ + +class ecPlatformsDialog : public ecDialog +{ +public: +// Ctor(s) + ecPlatformsDialog(wxWindow* parent); + ~ecPlatformsDialog(); + +//// Event handlers + + void OnModify(wxCommandEvent& event); + void OnAdd(wxCommandEvent& event); + void OnDelete(wxCommandEvent& event); + void OnOK(wxCommandEvent& event); + void OnCancel(wxCommandEvent& event); + void OnUpdateAny(wxUpdateUIEvent& event); + void OnDoubleLClick(); + void OnDeleteKey(); + +//// Operations + void CreateControls(wxWindow* parent); + + CeCosTestPlatform *Platform (int i) { return (CeCosTestPlatform *) m_arTargetInfo[i]; } + unsigned int PlatformCount() const { return m_arTargetInfo.Number(); } + void Add(const CeCosTestPlatform &ti); + void Clear(); + +protected: + + ecPlatformsListCtrl* m_listCtrl; + wxList m_arTargetInfo; + static const wxChar* sm_arpszTypes[]; + +private: + DECLARE_EVENT_TABLE() +}; + +#define ecID_PLATFORMS_ADD 4001 +#define ecID_PLATFORMS_DELETE 4002 +#define ecID_PLATFORMS_MODIFY 4003 +#define ecID_PLATFORMS_LIST 4004 + + +#endif + // _ECOS_PLATFORMSDLG_H_ diff --git a/host/tools/configtool/standalone/wxwin/propertywin.cpp b/host/tools/configtool/standalone/wxwin/propertywin.cpp new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/propertywin.cpp @@ -0,0 +1,464 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +// propertywin.cpp : +// +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): julians +// Contact(s): julians +// Date: 2000/09/04 +// Version: $Id: propertywin.cpp,v 1.7 2001/04/24 14:39:13 julians Exp $ +// Purpose: +// Description: Implementation file for ecPropertyListCtrl +// Requires: +// Provides: +// See also: +// Known bugs: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== + +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- +#ifdef __GNUG__ + #pragma implementation "propertywin.h" +#endif + +// Includes other headers for precompiled compilation +#include "ecpch.h" + +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + +#include "propertywin.h" +#include "configtool.h" +#include "configitem.h" +#include "configtooldoc.h" +#include "ecutils.h" + +// specify the CDL properties which are to be visible in the properties view +const std::string ecPropertyListCtrl::visible_properties [] = +{ + CdlPropertyId_ActiveIf, + CdlPropertyId_BuildProc, + CdlPropertyId_Calculated, + CdlPropertyId_CancelProc, + CdlPropertyId_CheckProc, + CdlPropertyId_Compile, + CdlPropertyId_ConfirmProc, + CdlPropertyId_DecorationProc, + CdlPropertyId_DefaultValue, + CdlPropertyId_Define, + CdlPropertyId_DefineHeader, + CdlPropertyId_DefineProc, +// CdlPropertyId_Description, + CdlPropertyId_Dialog, +// CdlPropertyId_Display, + CdlPropertyId_DisplayProc, + CdlPropertyId_Doc, + CdlPropertyId_EntryProc, + CdlPropertyId_Flavor, + CdlPropertyId_DefineFormat, + CdlPropertyId_Group, + CdlPropertyId_Hardware, + CdlPropertyId_IfDefine, + CdlPropertyId_Implements, + CdlPropertyId_IncludeDir, + CdlPropertyId_IncludeFiles, + CdlPropertyId_InitProc, + CdlPropertyId_InstallProc, + CdlPropertyId_LegalValues, + CdlPropertyId_Library, + CdlPropertyId_LicenseProc, + CdlPropertyId_Make, + CdlPropertyId_Makefile, + CdlPropertyId_MakeObject, + CdlPropertyId_NoDefine, + CdlPropertyId_Object, + CdlPropertyId_Parent, + CdlPropertyId_Requires, + CdlPropertyId_Screen, + CdlPropertyId_Script, + CdlPropertyId_UpdateProc, + CdlPropertyId_Wizard +}; + +const wxChar* ecPropertyListCtrl::sm_fieldTypeImage[ecMAXFIELDTYPE]= + {wxT("Type"), wxT("Value"), wxT("Default"), wxT("Macro"), wxT("File"), wxT("URL"), wxT("Enabled")}; + + +/* + * ecPropertyListCtrl + */ + +IMPLEMENT_CLASS(ecPropertyListCtrl, wxListCtrl) + +BEGIN_EVENT_TABLE(ecPropertyListCtrl, wxListCtrl) + EVT_RIGHT_DOWN(ecPropertyListCtrl::OnRightClick) + EVT_LEFT_DCLICK(ecPropertyListCtrl::OnDoubleClick) +END_EVENT_TABLE() + +ecPropertyListCtrl::ecPropertyListCtrl(wxWindow* parent, wxWindowID id, const wxPoint& pt, + const wxSize& sz, long style): + wxListCtrl(parent, id, pt, sz, style) +{ + if (!wxGetApp().GetSettings().GetWindowSettings().GetUseDefaults() && + wxGetApp().GetSettings().GetWindowSettings().GetFont(wxT("Properties")).Ok()) + { + SetFont(wxGetApp().GetSettings().GetWindowSettings().GetFont(wxT("Properties"))); + } + + m_f[0]=0.25; + m_f[1]=0.75; + m_pti = NULL; + m_nFirstProperty = 0; + m_nOnSizeRecursionCount = 0; + + AddColumns(); + +#if 0 + int j; + int i = 0; + for (j = 0; j < 4; j++) + { + + // Insert some dummy items + + wxListItem info; + info.m_text = _("URL"); + info.m_mask = wxLIST_MASK_TEXT ; // | wxLIST_MASK_IMAGE | wxLIST_MASK_DATA; + info.m_itemId = i; + info.m_image = -1; + //info.m_data = (long) doc; + + long item = InsertItem(info); + + SetItem(i, 1, _("redirects/interrupts.html")); + i ++; + + info.m_text = _("Enabled"); + info.m_mask = wxLIST_MASK_TEXT ; // | wxLIST_MASK_IMAGE | wxLIST_MASK_DATA; + info.m_itemId = i; + info.m_image = -1; + //info.m_data = (long) doc; + + item = InsertItem(info); + + SetItem(i, 1, _("True")); + i ++; + } +#endif + +} + +void ecPropertyListCtrl::OnRightClick(wxMouseEvent& event) +{ + PopupMenu(wxGetApp().GetWhatsThisMenu(), event.GetX(), event.GetY()); +} + +void ecPropertyListCtrl::AddColumns() +{ + InsertColumn(0, "Property", wxLIST_FORMAT_LEFT, 100); + InsertColumn(1, "Value", wxLIST_FORMAT_LEFT, 300); +} + +void ecPropertyListCtrl::Fill(ecConfigItem *pti) +{ + if(NULL==pti){ + ClearAll(); + AddColumns(); + m_nFirstProperty=0; + m_pti=NULL; + } else /* if(pti!=m_pti) */ { + m_pti=pti; + m_nMaxValueWidth=0; + ecOptionType type=m_pti->GetOptionType(); + int i; + + // Initially flag all items as unnecessary - calls of SetItem or SetProperty will change this + for(i=GetItemCount()-1;i>=0;--i){ + SetItemData(i,0); + } + if (m_pti->HasBool () || (ecOptionTypeNone!=type)){ + SetItem(ecMacro, m_pti->GetMacro ()); + } + + if (m_pti->HasBool ()){ + SetItem(ecEnabled, m_pti->IsEnabled() ? wxT("True") : wxT("False")); + } + + if(!m_pti->GetFilename().IsEmpty()){ + SetItem(ecFile, m_pti->GetFilename()); + } + SetItem(ecURL, m_pti->GetURL()); + + if (ecOptionTypeNone!=type){ + + switch(type){ + case ecString: + SetItem(ecValue, m_pti->StringValue()); + SetItem(ecDefaultValue, m_pti->StringDefaultValue()); + break; + case ecLong: + SetItem(ecValue, ecUtils::IntToStr(m_pti->Value(), wxGetApp().GetSettings().m_bHex)); + SetItem(ecDefaultValue, ecUtils::IntToStr(m_pti->DefaultValue(), wxGetApp().GetSettings().m_bHex)); + break; + case ecDouble: + SetItem(ecValue, ecUtils::DoubleToStr(m_pti->DoubleValue())); + SetItem(ecDefaultValue, ecUtils::DoubleToStr(m_pti->DoubleDefaultValue())); + break; + case ecEnumerated: + SetItem(ecValue,m_pti->StringValue()); + SetItem(ecDefaultValue,m_pti->StringDefaultValue()); + break; + default: + wxASSERT( FALSE ); + break; + } + // TODO: set image + // SetItem(ecType, ecConfigItem::TreeItemTypeImage[type]); + } + + // List all the properties applicable to me + const std::string name = ecUtils::UnicodeToStdStr (m_pti->GetMacro ()); + if (name.size () > 0) + { + const CdlConfiguration config = wxGetApp().GetConfigToolDoc ()->GetCdlConfig (); + const CdlNode node = config->find_node (name, true); + wxASSERT (node); + const std::vector & properties = node->get_properties (); + std::vector::const_iterator property_i; + // CMapStringToPtr map; // count of each property name + wxHashTable map(wxKEY_STRING); // count of each property name + + for (property_i = properties.begin (); property_i != properties.end (); property_i++) {// for each property + // get the property name + const CdlProperty &prop=*property_i; + const wxString strName(prop->get_property_name ().c_str()); + enum {VISIBLE_PROPERTIES_COUNT=sizeof visible_properties/sizeof visible_properties[0]}; + if (std::find (visible_properties, visible_properties + VISIBLE_PROPERTIES_COUNT, ecUtils::UnicodeToStdStr(strName)) != visible_properties + VISIBLE_PROPERTIES_COUNT) {// if the property should be displayed + // set the property arguments + wxString strPropertyArgs; + const std::vector & argv = prop->get_argv (); + void *p; + p = (void*) map.Delete(strName); + + p=(void *)((int)p+1); + map.Put(strName, (wxObject*) p); + + std::vector::const_iterator argv_i; + for (argv_i = argv.begin (); argv_i != argv.end (); argv_i++){ // for each property argument... + if (argv_i != argv.begin ()){ // ...except the first (the property name) + wxString strArg(ecUtils::StripExtraWhitespace (wxString(argv_i->c_str()))); + if (strPropertyArgs.Len() + strArg.Len() + 1 > 256) {// if the string is too long for the list control + break; // no need to add any further arguments + } + strPropertyArgs += strArg; // add the argument to the string + strPropertyArgs += wxT (" "); // separate arguments by a space character + } + } + // the list control appears to display a maximum of 256 characters + int nIndex=SetItem(strName, strPropertyArgs, GetItemCount(), (int)p); + SetItemData(nIndex, (long) prop); + + // display the exclamation icon if the property is in a conflicts list + bool bConflictItem = + // PropertyInConflictsList (* property_i, config->get_structural_conflicts ()) || ignore for now + PropertyInConflictsList (prop, config->get_all_conflicts ()); + + // TODO: set the image for a conflict item + // CListCtrl::SetItem (nIndex, 0, LVIF_IMAGE, NULL, bConflictItem ? 1 : 0, 0, 0, 0 ); + } + } + } + + for(i=GetItemCount()-1;i>=0;--i){ + if(0==GetItemData(i)){ + DeleteItem(i); + if(i & conflicts) +{ + std::list::const_iterator conf_i; + for (conf_i = conflicts.begin (); conf_i != conflicts.end (); conf_i++) // for each conflict + if (property == (* conf_i)->get_property ()) + return true; + + return false; +} + +void ecPropertyListCtrl::RefreshValue() +{ + if (!m_pti) + return; + + if (m_pti->HasBool ()){ + SetItem(ecEnabled, m_pti->IsEnabled () ? wxT("True") : wxT("False")); + } + if (m_pti->GetOptionType () != ecOptionTypeNone){ + SetItem(ecValue, m_pti->StringValue()); + } + for (int nItem = m_nFirstProperty; nItem < GetItemCount (); nItem++) + { + CdlProperty property = (CdlProperty) GetItemData (nItem); + wxASSERT (property); + + // display the exclamation icon if the property is in a conflicts list + const CdlConfiguration config = wxGetApp().GetConfigToolDoc ()->GetCdlConfig (); + bool bConflictItem = + // PropertyInConflictsList (property, config->get_structural_conflicts ()) || ignore for now + PropertyInConflictsList (property, config->get_all_conflicts ()); + + // TODO + // CListCtrl::SetItem (nItem, 0, LVIF_IMAGE, NULL, bConflictItem ? 1 : 0, 0, 0, 0 ); + } + +} + +int ecPropertyListCtrl::SetItem(ecFieldType f, const wxString& value) +{ + int nIndex=SetItem(sm_fieldTypeImage[f], value, m_nFirstProperty); + if(nIndex==m_nFirstProperty){ + m_nFirstProperty++; + } + SetItemData(nIndex,1); + return nIndex; +} + +int ecPropertyListCtrl::SetItem(const wxString& item, const wxString& value, int nInsertAs, int nRepeat) +{ + wxASSERT( nInsertAs <= GetItemCount() ); + +/* + LVFINDINFO info; + info.flags =LVFI_STRING; + info.psz =pszItem; + info.vkDirection=VK_DOWN; + int nIndex=-1; + do { + nIndex=FindItem(&info,nIndex); + } while (--nRepeat>0 && nIndex!=-1); +*/ + // NB: wxListCtrl doesn't support reverse search, so could do it explicitly + // by iterating through the items. + // But for now, just ignore the nRepeat flag and find the first one. + int nIndex = -1; + nIndex = FindItem(0, /* nIndex */ item); + + if(-1==nIndex){ + nIndex = InsertItem(nInsertAs, item); + } + + wxListCtrl::SetItem(nIndex, 1, value); + + // TODO +#if 0 + CDC *pDC=GetDC(); + CFont *pOldFont=pDC->SelectObject(GetFont()); + m_nMaxValueWidth=max(m_nMaxValueWidth,pDC->GetTextExtent(pszValue).cx); + pDC->SelectObject(pOldFont); + ReleaseDC(pDC); +#endif + + return nIndex; +} + +void ecPropertyListCtrl::OnDoubleClick(wxMouseEvent& event) +{ + // Double-clicked the item + + int flags; + long item = HitTest(event.GetPosition(), flags); + if (item > -1) + { + const wxString strText = wxListCtrlGetItemTextColumn(*this, item,0); + if(strText == wxT("File")){ + m_pti->ViewHeader(); + } else if (strText == wxT("URL")) { + m_pti->ViewURL(); + } + } + + // TODO +#if 0 + int pos=GetMessagePos(); + CPoint pt(GET_X_LPARAM(pos),GET_Y_LPARAM(pos)); + ScreenToClient(&pt); + int nItem=HitTest(pt,NULL); + + if(GetItemData(nItem)>1){ + // This is a property row + const CdlGoalExpression goal = dynamic_cast ((CdlProperty) GetItemData (nItem)); + if (goal){ + // This is a rule row + const CdlExpression expression = goal->get_expression (); + if (1 == expression->references.size ()) // if the property contains a single reference + { + // assume that the reference is to another user visible node and try to find it + std::string macro_name = expression->references [0].get_destination_name (); + CConfigItem * pItem = CConfigTool::GetConfigToolDoc ()->Find (CString (macro_name.c_str ())); + if (pItem) // the referenced node was found so select it + { + CConfigTool::GetControlView()->GetTreeCtrl().SelectItem(pItem->HItem()); + } + } + } + } else { + const CString strText(GetItemText(nItem,0)); + if(strText==FieldTypeImage[File]){ + m_pti->ViewHeader(); + } else if (strText==FieldTypeImage[URL]) { + m_pti->ViewURL(); + } + } +#endif + event.Skip(); +} diff --git a/host/tools/configtool/standalone/wxwin/propertywin.h b/host/tools/configtool/standalone/wxwin/propertywin.h new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/propertywin.h @@ -0,0 +1,102 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +// propertywin.h : +// +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): julians +// Contact(s): julians +// Date: 2000/09/04 +// Version: $Id: propertywin.h,v 1.4 2001/04/18 11:47:56 julians Exp $ +// Purpose: +// Description: Header file for ecPropertyListCtrl +// Requires: +// Provides: +// See also: +// Known bugs: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== + +#ifndef _ECOS_PROPERTYWIN_H_ +#define _ECOS_PROPERTYWIN_H_ + +#ifdef __GNUG__ +#pragma interface "propertywin.h" +#endif + +#include "wx/listctrl.h" + +class ecConfigItem; + +class ecPropertyListCtrl : public wxListCtrl +{ +public: + enum ecFieldType {ecType, ecValue, ecDefaultValue, ecMacro, ecFile, ecURL, ecEnabled, ecMAXFIELDTYPE}; + +// Ctor(s) + ecPropertyListCtrl(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style); + +//// Event handlers + + void OnRightClick(wxMouseEvent& event); + void OnDoubleClick(wxMouseEvent& event); + +//// Accessors + int SetItem (ecFieldType f, const wxString& value); + int SetItem (const wxString& item, const wxString& value,int nInsertAs,int nRepeat=1); + int SetProperty (const wxString& value, CdlProperty prop); + static bool PropertyInConflictsList (CdlProperty property, const std::list & conflicts); + +//// Operations + + void Fill(ecConfigItem *pti); + void AddColumns(); + void RefreshValue(); + +protected: +private: + DECLARE_EVENT_TABLE() + DECLARE_CLASS(ecPropertyListCtrl) + + double m_fWidth; + enum {NCOLS=2}; + double m_f[NCOLS]; // relative proportions of columns + int m_nLastCol; + int m_nOnSizeRecursionCount; + int m_nMaxValueWidth; + int m_nFirstProperty; + ecConfigItem *m_pti; + + static const std::string ecPropertyListCtrl::visible_properties []; + static const wxChar* sm_fieldTypeImage[ecMAXFIELDTYPE]; +}; + + +#endif + // _ECOS_PROPERTYWIN_H_ diff --git a/host/tools/configtool/standalone/wxwin/readme.html b/host/tools/configtool/standalone/wxwin/readme.html new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/readme.html @@ -0,0 +1,415 @@ + + + + + + + + + + + +

    eCos Configuration Tool Version 2

    +
    +

    This page describes how to run and compile the new, portable +version of the Configuration Tool.

    +

    Contents

    +
      +
    1. Introduction and where to get the Configuration Tool

      +
    2. What's in this release?

      +
    3. Installing the Configuration Tool

      +
    4. Running the Configuration Tool

      +
    5. Frequently Asked Questions

      +
    6. Building the Configuration Tool under Linux

      +
    7. Building the Configuration Tool under Windows

      +
    +

    Introduction

    +

    Welcome to the eCos Configuration Tool, a graphical tool to help a +user configure and build a custom version of the eCos operating +system.

    +

    This is a cross-platform version built using the wxWindows +toolkit. The tool uses the GTK+ widget set on Linux, and the WIN32 +API on Windows 9x, Windows NT and Windows 2000. It is similar to the +MFC, Windows-only version but at present lacks a few of its features, +such as the Memory Layout Tool and the ability to run tests from +within the tool.

    +

    Please note that this is alpha-level code. However, all feedback +to the eCos team is appreciated, via ecos-discuss@sources.redhat.com +or the bug reporting form at +http://sources.redhat.com/ecos/problemreport.html.

    +

    The source for the Configuration Tool is available from anonymous +CVS.

    +

    Binary packages are also available (see instructions below).

    +

    What's in this release?

    +

    This version allows you to edit, load, save and build eCos +configurations much as the original Windows Configuration Tool. +However the following features are missing with respect to the +original tool:

    +
      +
    1. Memory Layout Tool

      +
    2. Running tests from the tool

      +
    3. Administration functionality (initial code present but + untested)

      +
    4. Gauge indicating time left to build library and tests

      +
    +

    The following features are present in the new tool but not in the +original tool:

    +
      +
    1. Repository Information dialog (available from the Help menu)

      +
    2. Most dialogs are resizeable

      +
    +

    Documentation works a little differently. Instead of using a +precompiled HTML Help file, this version compiles a documentation +index on the fly for use with its own internal HTML help viewer. The +cached indexes are placed in the .eCosDocs directory under the user's +home directory (Linux) or in the installed repository (Windows). The +internal viewer cannot cope with all of the eCos and GNUPro +documentation, so for these occasions please use an external browser +(see the Settings dialog).

    +

    The documentation for the Configuration Tool is supplied in its +install directory as HTML only, and is a modified version of the eCos +User's Guide. Invoke the tool help from the "Help|Configuration +Tool Help" menu item, or from the internal help viewer's index, +under "Linux Configuration Tool Guide".

    +

    Known bugs:

    +

    The documentation index only lists the packages in the +configuration active when the documentation was indexed (normally +when the repository is first seen by the Configuration Tool).

    +

    Installing the Configuration Tool

    +

    The Configuration Tool can be used with existing eCos +installations and CVS source hierarchies. You can get the binaries +from ftp://sources.redhat.com/pub/ecos/ct2/.

    +

    See also mirror sites at:

    +

    http://sources.redhat.com/ecos/mirror.html
    http://sources.redhat.com/mirrors.html

    +

    Please try to use a mirror site close to you, as it will be +faster.

    +

    Under Linux:

    +

    Download configtool-2.0-i386.tar.gz.

    +

    Unarchive the tar file into a suitable directory and add the +directory to your path. You do not have to install it as root. For +example:

    +

    % mkdir -p + +/opt/ecos/configtool/bin
    % cd /opt/ecos/configtool/bin
    % tar +xvfz /cdrom/configtool.tgz
    % export +PATH=/opt/ecos/configtool/bin:$PATH

    +

    The following files will be extracted to the installation +directory:

    +

    configtool, ecoslogo.png, +rhlogo.png, about.htm, README.txt, license.txt, ecosplatforms.tar.gz, +manual/

    +

    Optionally, untar the contents of ecosplatforms.tar.gz into your +home directory, where it will create a directory called +.eCosPlatforms. The information in these files isn't yet used by the +Configuration Tool, but will keep the tool from generating some +warnings.

    +

    The executable is statically linked to the wxWindows library, but +does require the GTK+ 1.2, GDK 1.2 and TCL 8.x libraries to be +installed.

    +

    Under Windows:

    +

    Download configtool-2.0-setup.exe.

    +

    Run the installer provided, preferably having installed eCos for +Windows on your PC previously so the tool can pick up the relevant +registry information added by the eCos installer. A new eCos +Configuration Tool group will be added to your Start menu and a +shortcut to the Configuration Tool will appear on your desktop.

    +

    Running the Configuration Tool

    +

    Run the configtool executable and (on Linux) ignore any initial +console messages, which may be suppressed by unarchiving +ecosplatforms.tar.gz as per the installation instructions above.

    +

    You can invoke the tool with zero, one, or two parameters. The two +parameters can be the location of the repository and/or the location +of a save file (extension .ecc). If no parameters are passed, the +tool will look in the current directory for a save file and also (on +Linux) in the /opt/ecos directory for a suitable repository. Failing +that, the tool will use the last loaded repository or ask the user +for a suitable location.

    +

    For detailed information about the Configuration Tool, please +refer to the HTML manual which may be invoked from the Help menu or +by clicking on the "Linux Configuration Tool Guide" in the +internal help system's contents. This is similar to but different +from "The eCos Configuration Tool" section in the eCos User +Guide, which refers to the original Windows version of the +configuration tool (as opposed to the new cross-platform Linux and +Windows version).

    +

    Frequently Asked Questions

    +

    Q: On Linux, invoking HTML documentation for a configuration +item doesn't seem to work.

    +

    A: You need to have a .mailcap entry similar to the following:

    +

    text/html; netscape +-no-about-splash %s +

    +

    and in .mime.types:

    +

    type=text/html \
    desc="HTML +document" \
    exts="htm,html"

    +

    Also, be aware that the browser can sometimes end up behind the +configuration tool so it may have run even if you think it didn't.

    +

    Q: On Linux, right-clicking in the configuration pane and +choosing 'What's This?' causes an information window to pop up and +then quickly disappear.

    +

    A: If the window manager options are set to raise a window when it +gains the focus, the information window can get sent behind the +application window when the popup menu loses focus. Either adjust +your window manager settings, or use an alternate way of invoking +help for the item: click on the arrow/question mark toolbar button, +then on the item you are interested in.

    +

    Q: The internal HTML help viewer doesn't display HTML +correctly.

    +

    A: The internal HTML help viewer cannot display some of the more +complex HTML correctly, such as the GNUPro reference. We hope to +provide the documentation in a suitable form in future, but for now, +please use an external browser to view this documentation. You can +use the Settings dialog, Viewers tab, to choose to view using an +external browser.

    +

    Q: Why does the Configuration Tool use wxWindows?

    +

    A: wxWindows is an open source, mature multi-platform GUI toolkit +for C++. It makes platform-independence relatively easy to achieve, +whilst remaining compatibility with the look and feel of GTK+ and +WIN32 on the respective platforms. wxWindows was chosen on its own +merits but, by sheer coincidence, the author of the new Configuration +Tool is also the original author of wxWindows. Using a +platform-independent API will make it easier to port the +Configuration Tool to other platforms if needed.

    +

    Q: Where can I get more information about wxWindows?

    +

    A: The wxWindows web site is at http://www.wxwindows.org. +wxWindows distributions come with documentation in a variety of +formats.

    +

    Q: Does the new Configuration Tool make the old one obsolete?

    +

    A: Not yet. The new tool doesn't yet support some features, such +as the Memory Layout Tool and the Run Tests dialog. When these have +been implemented, and the tool has been subject to the required +quality assurance procedure, then we can retire the old tool.

    +

    Q: How can I help improve the Configuration Tool?

    +

    A: All help is very welcome: please see +http://sources.redhat.com/ecos/faq.html +for how to contribute.

    +

    Q: Who do I contact when things go wrong?

    +

    A: Please discuss problems on the ecos-discuss mailing list: see +http://sources.redhat.com/ecos/intouch.html.

    +

    Q: The compiler fails to compile dcclient.cpp. What do I do?

    +

    A: It may be that you have a non-standard GTK+ 1.2.6 which has +changes backported from 1.2.7. Use the makefile target 'wxgtkfix' to +fix this after the error has happened (i.e. after configure has +produced the setup.h and makefiles):

    +

    % make -f +$CONFIGTOOLDIR/Makefile WXDIR=$WXDIR ECOSDIR=$ECOSDIR LEVEL=release +wxgtkfix

    +

    or

    +

    % make -f +$CONFIGTOOLDIR/Makefile WXDIR=$WXDIR ECOSDIR=$ECOSDIR LEVEL=debug +wxgtkfix

    +

    Now use the 'wx ecc ct' targets (not 'full') to continue building.

    +

    Building the Configuration Tool under Linux

    +

    This build system is subject to change.

    +

    You will need:

    +
      +
    1. gcc 2.95.2 or later

      +
    2. GTK+ and glib 1.2.6 or above. Please remove any 1.3 + development RPMs from your setup using for example:

      +

      rpm -e gtk+-gtkbeta-devel-1.3.1b-2

      +

      You can get GTK+ and glib for Red Hat 6.2 and above + from:

      ftp://ftp.gtk.org/pub/gtk/v1.2/binary/RPMS/RedHat-6.2/RPMS/i386/gtk+-1.2.8-1.i386.rpm
      ftp://ftp.gtk.org/pub/gtk/v1.2/binary/RPMS/RedHat-6.2/RPMS/i386/glib-1.2.8-1.i386.rpm

      +
    3. a suitable version of wxWindows for GTK+, available from + ftp://sources.redhat.com/pub/ecos/ct2/.

      +

      Unarchive the file wxGTK-x.y.z.tgz into a suitable directory, + e.g. +

      +

      % mkdir /home/julians/wxWindows
      % cd /home/julians/wxWindows
      % + tar xvfz /tmp/wxGTK-x.y.z.tgz

      +

      You may also wish to download and unarchive wxWindows + documentation, which is supplied in zip form. Unarchive using e.g.:

      +

      % cd /home/julians/wxWindows
      % unzip -a + wxWindows-x.y.z-HTML.zip

      +
    4. an eCos source hierarchy. See + http://sources.redhat.com/ecos/anoncvs.html + for how to download this from the CVS repository. For example:

      +

      cvs -d :pserver:anoncvs@sources.redhat.com:/cvs/ecos co ecos/host

      +
    5. other tools:

      +

      Tcl/Tk 8.2 or above. See http://dev.scriptics.com/

      +
    +

    Summary:

    +

    There is no 'configure' step for the eCos Configuration Tool as a +whole, although the host tool libraries and wxWindows have configure +scripts which are invoked by the makefile.

    +

    You work in a build directory of your choosing, and the makefile +will create the following directories underneath it:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +

    ct-build-debug/

    +
    +

    Configtool debug build

    +
    +

    ecc-build-debug/ +

    +
    +

    eCos libraries debug build

    +
    +

    wxwin-build-debug/ +

    +
    +

    wxWindows debug build

    +
    +

    ct-build-release/ +

    +
    +

    Configtool release build

    +
    +

    ecc-build-release/ +

    +
    +

    eCos libraries release build

    +
    +

    wxwin-build-release/ +

    +
    +

    wxWindows release build

    +
    +

    You need to pass the wxWindows source directory (WXDIR) and eCos +hierarchy directory (ECOSDIR) to the makefile, along with the build +LEVEL (debug or release). Please see makect.sh in the source +directory, which is a useful helper script for making it easier to +invoke the makefile.

    +

    You also supply a target to build, such as full (everything), ct +(just the Configuration Tool), wx (wxWindows only) or ecc (eCos +libraries only). It is important to supply the target as the last +command(s) on the command line.

    +

    The makefile builds and uses wxWindows as a static library, which +minimizes problems with shared libraries and still results in a +reasonable size of executable (around 6 MB). Switching off +unnecessary wxWindows features may result in smaller executables.

    +

    IMPORTANT NOTE: currently, there are inadequate dependencies in +the makefiles, so please make sure you start with a clean directory +before building (use the cleanct target if necessary).

    +

    Examples:

    +

    This builds the eCos libraries, wxWindows, and the Configuration +Tool, debug mode.

    +

    % export ECOSDIR=/home/julians/cvs/eCos # The dir above 'host'
    % +export +CONFIGTOOLDIR=$ECOSDIR/host/tools/configtool/standalone/wxwin
    % +export WXDIR=/home/julians/wxWindows
    % mkdir /tmp/ecos-build
    % +cd /tmp/ecos-build
    % make -f $CONFIGTOOLDIR/Makefile WXDIR=$WXDIR +ECOSDIR=$ECOSDIR LEVEL=debug full

    +
    +

    This builds just the Configuration Tool, say after a file was +edited, in release mode.

    +

    % export ECOSDIR=/home/julians/cvs/eCos
    % export +CONFIGTOOLDIR=$ECOSDIR/host/tools/configtool/standalone/wxwin
    % +export WXDIR=/home/julians/wxWindows
    % cd /tmp/ecos-build
    % +make -f $CONFIGTOOLDIR/Makefile WXDIR=$WXDIR ECOSDIR=$ECOSDIR +LEVEL=release ct

    +
    +

    Troubleshooting

    +

    Please see the FAQ for what to do if the wxWindows file +dcclient.cpp fails to compile.

    +

    Building the Configuration Tool under Windows

    +

    You will need:

    +
      +
    1. Microsoft Visual C++ 6.0 or later

      +
    2. a suitable version of wxWindows for MS Windows, available + from ftp://sources.redhat.com/pub/ecos/ct2/. + To install the sources in 'setup' form, just run the executable and + follow the instructions. If you have downloaded the sources in zip + format, you will need to unarchive the file wxMSW-x.y.z.zip into a + suitable directory, e.g.

      + +

      > mkdir c:\wxWindows
      > c:
      > cd \wxWindows
      > + unzip c:\temp\wxMSW-x.y.z.zip

      +
      +

      Alternatively, you can use WinZip or similar utility to unarchive + the files.

      +

      Documentation in Windows HTML Help format is supplied in the + setup or zipped distribution and does not have to be downloaded + separately.

      +
    3. an eCos source hierarchy. See + http://sources.redhat.com/ecos/anoncvs.html + for how to download this from the CVS repository. For example:

      +

      cvs -d :pserver:anoncvs@sources.redhat.com:/cvs/ecos co ecos/host

      +
    4. other tools:

      + +
    +

    Summary:

    +

    There are two main steps: building wxWindows, and building the +Configuration Tool. The Configuration Tool project file also builds +the required eCos libraries. Note that unlike compilation under +Linux, the wxWindows objects and libraries end up in the wxWindows +source tree.

    +

    Before routinely building the Configuration Tool, you will need to +set up Visual C++ with the correct paths (see below).

    +

    Steps:

    +
      +
    1. Execute in a DOS box:

      +

      subst v: d:\tmp

      +

      where d:\tmp is a suitable temporary directory where the + Configuration Tool binaries and objects will end up.

      +
    2. Set the TCLHOME environment variable to where Tcl is + installed. On Windows 9x, edit autoexec.bat. On Windows NT or W2K, + use the System control panel applet.

      +
    3. Build wxWindows. To do this, run VC++ and open src/msvc.dsw + in the wxWindows project hierarchy. Select Build | Batch Build and + check "wxvc - WIN32 Debug" and "wxvc - WIN32 + Release". Click on Build.

      +
    4. Open the + eCos/ecc/host/tools/configtool/standalone/wxwin/ConfigtoolVC.dsw + workspace. Choose Tools | Options and click on the Directories tab.

      +

      Select Show directories for: Include files.

      +

      You need to add paths such as these:

      + +

      c:\Program Files\Tcl\include
      d:\wxWindows-010212\include

      +

      Select Show directories for: Library files. Add these paths, + changing as necessary:

      + +

      c:\Program Files\Tcl\lib
      d:\wxWindows-010212\lib

      +
      +
    5. Click on Select Active Configuration... and select the one + you wish to build, such as WIN32 Ansi Debug (note that Unicode + configurations are not yet available). Choose Build | Rebuild All to + build the project. The configtool.exe executable should end up in + v:\Configtool\AnsiDebug.

      +
    +

    When compiled, configtool.exe depends on the following DLLs found +in your system32 directory that should be supplied with the +executable:

    +
      +
    • TCL82.DLL (or other name if you used a different version of + TCL) +
    • MSVCIRT.DLL +
    • MSVCP60.DLL +
    • MSVCRT.DLL +
    +

    + + diff --git a/host/tools/configtool/standalone/wxwin/reposdlg.cpp b/host/tools/configtool/standalone/wxwin/reposdlg.cpp new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/reposdlg.cpp @@ -0,0 +1,247 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +// appsettings.cpp : +// +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): julians +// Contact(s): julians +// Date: 2000/09/11 +// Version: $Id: reposdlg.cpp,v 1.4 2001/03/19 14:53:41 julians Exp $ +// Purpose: +// Description: Implementation file for ecRepositoryInfoDialog +// Requires: +// Provides: +// See also: +// Known bugs: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== + +#ifdef __GNUG__ + #pragma implementation "reposdlg.cpp" +#endif + +#include "ecpch.h" + +#include "wx/wxhtml.h" + +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + +#include "reposdlg.h" +#include "configtool.h" +#include "configtooldoc.h" + +//---------------------------------------------------------------------------- +// ecRepositoryInfoDialog +//---------------------------------------------------------------------------- + +// WDR: event table for ecRepositoryInfoDialog + +BEGIN_EVENT_TABLE(ecRepositoryInfoDialog,wxDialog) +END_EVENT_TABLE() + +ecRepositoryInfoDialog::ecRepositoryInfoDialog( wxWindow *parent, wxWindowID id, const wxString &title, + const wxPoint &position, const wxSize& size, long style ) : + wxDialog( parent, id, title, position, size, style ) +{ + AddControls(this); + + Centre(wxBOTH); +} + +bool ecRepositoryInfoDialog::AddControls(wxWindow* parent) +{ +#if 0 + wxColour backgroundColour = * wxBLACK; // wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE); + wxColour buttonBackgroundColour = * wxWHITE; // backgroundColour; + wxColour buttonForegroundColour = * wxBLACK; // wxSystemSettings::GetSystemColour(wxSYS_COLOUR_BTNTEXT); + + if (!wxGetApp().GetHiColour()) + { + backgroundColour = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE); + buttonBackgroundColour = backgroundColour; + buttonForegroundColour = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_BTNTEXT); + } + + this->SetBackgroundColour(backgroundColour); +#endif + + wxSize htmlSize(440, 380); + + // Note: in later versions of wxWin this will be fixed so wxRAISED_BORDER + // does the right thing. Meanwhile, this is a workaround. +#ifdef __WXMSW__ + long borderStyle = wxDOUBLE_BORDER; +#else + long borderStyle = wxRAISED_BORDER; +#endif + + wxHtmlWindow* html = new wxHtmlWindow(this, ecID_REPOS_DIALOG_HTML_WINDOW, wxDefaultPosition, htmlSize, + borderStyle); + html -> SetBorders(5); + + wxString info; + if (CreateHtmlInfo(info)) + html -> SetPage(info); + else + { + wxString msg; + msg.Printf(wxT("Warning

    Sorry, could not obtain repository information.

    ")); + html->SetPage(msg); + } + + //// Start of sizer-based control creation + + wxSizer *item0 = new wxBoxSizer( wxVERTICAL ); + + wxWindow *item1 = parent->FindWindow( ecID_REPOS_DIALOG_HTML_WINDOW ); + wxASSERT( item1 ); + item0->Add( item1, 0, wxALIGN_CENTRE|wxALL, 5 ); + + wxButton *item2 = new wxButton( parent, wxID_CANCEL, "&OK", wxDefaultPosition, wxDefaultSize, 0 ); +#if 0 + item2->SetBackgroundColour(buttonBackgroundColour); + item2->SetForegroundColour(buttonForegroundColour); +#endif + item2->SetDefault(); + + //item0->Add( item2, 0, wxALIGN_CENTER|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + //item0->Add( item2, 0, wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + item0->Add( item2, 0, wxALIGN_RIGHT|wxALL, 10 ); + + parent->SetAutoLayout( TRUE ); + parent->SetSizer( item0 ); + parent->Layout(); + item0->Fit( parent ); + item0->SetSizeHints( parent ); + return TRUE; +} + +bool ecRepositoryInfoDialog::CreateHtmlInfo(wxString& info) +{ + ecConfigToolDoc* doc = wxGetApp().GetConfigToolDoc(); + + wxString ecosLogo(wxT("ecoslogosmall.png")); + wxSetWorkingDirectory(wxGetApp().GetAppDir()); + + info += wxT("Repository Information\n"); + info += wxT("\n"); + + info += wxT(""); + info += wxT("
    \n"); + if (wxFileExists(ecosLogo)) + { + wxString s; + s.Printf(wxT("

    "), ecosLogo.c_str()); + info += s; + } + info += wxT("

    \n"); + info += wxT("Repository Information\n"); + + info += wxT("
    \n"); + + info += wxT("


    \n"); + + /////////////////////////////////////////////////// + info += wxT("Repository path:

    \n"); + + info += wxT("

      "); + + if (doc) + { + info += doc->GetRepository(); + } + else + { + info += wxT("Not loaded."); + } + + info += wxT("

    "); + + /////////////////////////////////////////////////// + info += wxT("Save file:

    \n"); + + info += wxT("

      "); + + if (doc) + { + info += doc->GetFilename(); + } + else + { + info += wxT("Not loaded."); + } + + info += wxT("

    "); + + /////////////////////////////////////////////////// + info += wxT("Hardware template:

    \n"); + + info += wxT("

      "); + + if (doc) + { + wxString hardware = doc->GetCdlConfig ()->get_hardware ().c_str(); + + info += hardware; + info += wxT(" "); + + info += doc->GetTemplateVersion () ; + } + else + { + info += wxT("Unknown."); + } + + info += wxT("

    "); + + /////////////////////////////////////////////////// + info += wxT("Default package:

    \n"); + + info += wxT("

      "); + + if (doc) + { + wxString package = doc->GetCdlConfig ()->get_template ().c_str(); + + info += package; + } + else + { + info += wxT("Unknown."); + } + + info += wxT("

    "); + + info += wxT(""); + + return TRUE; +} diff --git a/host/tools/configtool/standalone/wxwin/reposdlg.h b/host/tools/configtool/standalone/wxwin/reposdlg.h new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/reposdlg.h @@ -0,0 +1,75 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +// appsettings.cpp : +// +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): julians +// Contact(s): julians +// Date: 2000/09/11 +// Version: $Id: reposdlg.h,v 1.1 2001/03/16 18:21:09 julians Exp $ +// Purpose: +// Description: Header file for ecRepositoryInfoDialog +// Requires: +// Provides: +// See also: +// Known bugs: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== + +#ifndef _ECOS_REPOSDLG_H_ +#define _ECOS_REPOSDLG_H_ + +#ifdef __GNUG__ + #pragma interface "reposdlg.cpp" +#endif + +//---------------------------------------------------------------------------- +// ecRepositoryInfoDialog +//---------------------------------------------------------------------------- + +class ecRepositoryInfoDialog: public wxDialog +{ +public: + // constructors and destructors + ecRepositoryInfoDialog( wxWindow *parent, wxWindowID id, const wxString &title, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = wxDEFAULT_DIALOG_STYLE ); + +//// Operations + bool AddControls(wxWindow* parent); + bool CreateHtmlInfo(wxString& info); + +private: + DECLARE_EVENT_TABLE() +}; + +#endif + // _ECOS_REPOSDLG_H_ diff --git a/host/tools/configtool/standalone/wxwin/rhlogo.png b/host/tools/configtool/standalone/wxwin/rhlogo.png new file mode 100644 index 0000000000000000000000000000000000000000..28ac54e5459277adacea09b5e55a5d3d320788ae GIT binary patch literal 1296 zc$@(c1@HQaP)WdH}z2@4Dz3$R}Ne*gdg2XskIMF-IX6Acd$^-4(P00009a7bBm000hj z000hj0c#|))&KwiFi=cXMF0Q*3=9~VB_8iZA`>xMPFZcKhLO_E+4p;7_n?yf%)+kRX^Y{Dz_xJz*|J|G&yZ`_MQb|NXRCwCmmN9SJMihYWB2gMr7d%7~2dDo*hW>y8 zsLm2Y5)jEtnpi+YE_EdWmbj$lUrL8gO(S&bWVnNE4S~!l>5!ya5^+$e*LO!Ad1R5Q zC|#uO4K_uJAHVnBy(bd#A6TD$Y=QsLD*m&0+IIo`p?;0Ru0L$GOxJJb<0PA?=uU(m zJJUpYXrLIW2m)Cn=R zYF3>gBka#M2X%BViL1_$)Y*pAykPJFQ5ya$pOXm5MN#@_o23V1W@eG9b(<%zLG(g| z)ZT5i1e-3p>ByOy2@z<6&@gs+Vw>e@H*->S-Y4NRxfGRw*QIvybjAf}Y(ZI-Tb_2K zbW(Ah87uxVM3#>bxF?Z&{LDB*WI7GOAt173f+?;r%63;t!P-qs;$A_iPfO%Zz8?2yQ;KgHjl-gB!vV?lx8x1y)@tzt9}g-*cgB93^o(A zMC6z7c7prUy4uXU?8)=s*-wP*MAhLmok(asRi84fTtq$qTt373g8zdh*yQvuaK2f0 zb#3W5XBQm#{aoI(B69b{o|a+>KESJr2d~l7rUt-fiBz0lj?*}W35*V3_QAr zCoZy!HQTBsz>Dt;2nHzll8peS{WA`q@saiLWjGVh2Bf^=hdUA(v2ICCWf!5AfB()S zjGf)a$YI;}pr;t$GN7U#E=xYhDtVVYbkMs_lm>^N}DbS}wz{xp1y(&fkG50)>U zEf$M8BD-lzW(4SsxeO~F{z6Wy;JgTM+1h{H|Gb$Q8=>V0x1<`-hb zaur$b{x`qYg~U_)&a_j)y;*an$>4}1 z2cM7F;2K^s+cEO|GyW$BO1@ZYF>;E+q8xvB-H-%V;Md~AWgwtfdqb%{E06C~pR0000AddPage(m_executables, wxT("Executables")); + m_executables->TransferDataToWindow(); + + m_output = new ecRunTestsOutputDialog(m_notebook); + m_notebook->AddPage(m_output, wxT("Output")); + m_output->TransferDataToWindow(); + + m_summary = new ecRunTestsSummaryDialog(m_notebook); + m_notebook->AddPage(m_summary, wxT("Summary")); + m_summary->TransferDataToWindow(); + + wxSizer *item0 = new wxBoxSizer( wxVERTICAL ); + + item0->Add( m_notebook, 1, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 ); + + wxSizer *item1 = new wxBoxSizer( wxHORIZONTAL ); + + wxButton *runButton = new wxButton( this, ecID_RUN_TESTS_RUN, "&Run", wxDefaultPosition, wxDefaultSize, 0 ); + item1->Add( runButton, 0, wxALIGN_CENTRE|wxALL, 5 ); + + wxButton *okButton = new wxButton( this, wxID_OK, "&Close", wxDefaultPosition, wxDefaultSize, 0 ); + item1->Add( okButton, 0, wxALIGN_CENTRE|wxALL, 5 ); + + wxButton *propertiesButton = new wxButton( this, ecID_RUN_TESTS_PROPERTIES, "&Properties...", wxDefaultPosition, wxDefaultSize, 0 ); + item1->Add( propertiesButton, 0, wxALIGN_CENTRE|wxALL, 5 ); + +/* + wxButton *helpButton = new wxButton( this, wxID_HELP, "&Help", wxDefaultPosition, wxDefaultSize, 0 ); + item1->Add( helpButton, 0, wxALIGN_CENTRE|wxALL, 5 ); +*/ + +#ifdef __WXGTK__ + // Context-sensitive help button (question mark) + wxButton *contextButton = new wxContextHelpButton( this ); + item1->Add( contextButton, 0, wxALIGN_CENTRE|wxALL, 5 ); +#endif + + // Necessary to add a spacer or the button highlight interferes with the notebook under wxGTK + item0->Add( 4, 4, 0, wxALIGN_CENTRE|wxALL, 0 ); + + item0->Add( item1, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL, 0 ); + + this->SetAutoLayout( TRUE ); + this->SetSizer( item0 ); + + okButton->SetDefault(); + okButton->SetFocus(); + + Layout(); + + m_executables->Layout(); + m_output->Layout(); + m_summary->Layout(); + + okButton->SetHelpText(_("Closes the dialog.")); + runButton->SetHelpText(_("Runs one or more tests selected in the Executables window.")); + propertiesButton->SetHelpText(_("Shows timeout and connection properties.")); + //helpButton->SetHelpText(_("Invokes help for the selected dialog.")); + + Centre(wxBOTH); + + // TODO: Is this necessary? +#if 0 + m_prop.Add(_T("Active timeout"), wxGetApp().GetSettings().GetRunTestsSettings().m_nTimeout); + m_prop.Add(_T("Download timeout"), wxGetApp().GetSettings().GetRunTestsSettings().m_nDownloadTimeout); + m_prop.Add(_T("Active timeout type"), wxGetApp().GetSettings().GetRunTestsSettings().m_nTimeoutType); + m_prop.Add(_T("Download timeout type"), wxGetApp().GetSettings().GetRunTestsSettings().m_nDownloadTimeoutType); + m_prop.Add(_T("Remote"), wxGetApp().GetSettings().GetRunTestsSettings().m_bRemote); + m_prop.Add(_T("Serial"), wxGetApp().GetSettings().GetRunTestsSettings().m_bSerial); + m_prop.Add(_T("Port"), wxGetApp().GetSettings().GetRunTestsSettings().m_strPort); + m_prop.Add(_T("Baud"), wxGetApp().GetSettings().GetRunTestsSettings().m_nBaud); + m_prop.Add(_T("Local TCPIP Host"), wxGetApp().GetSettings().GetRunTestsSettings().m_strLocalTCPIPHost); + m_prop.Add(_T("Local TCPIP Port"), wxGetApp().GetSettings().GetRunTestsSettings().m_nLocalTCPIPPort); + m_prop.Add(_T("Reset Type"), wxGetApp().GetSettings().GetRunTestsSettings().m_nReset); + m_prop.Add(_T("Reset String"), wxGetApp().GetSettings().GetRunTestsSettings().m_strReset); + m_prop.Add(_T("Resource Host"), wxGetApp().GetSettings().GetRunTestsSettings().m_strResourceHost); + m_prop.Add(_T("Resource Port"), wxGetApp().GetSettings().GetRunTestsSettings().m_nResourcePort); + m_prop.Add(_T("Remote Host"), wxGetApp().GetSettings().GetRunTestsSettings().m_strRemoteHost); + m_prop.Add(_T("Remote Port"), wxGetApp().GetSettings().GetRunTestsSettings().m_nRemotePort); + // TODO + //m_prop.Add(_T("Recurse"), executionpage.m_bRecurse); + m_prop.Add(_T("Farmed"), wxGetApp().GetSettings().GetRunTestsSettings().m_bFarmed); + // TODO + // m_prop.Add(_T("Extension"),executionpage.m_strExtension); +#endif + + CeCosTrace::SetOutput(TestOutputCallback, this); + CeCosTrace::SetError (TestOutputCallback, this); +} + +ecRunTestsDialog::~ecRunTestsDialog() +{ + m_runTestsDialog = NULL; + if (m_pResource) + { + delete m_pResource; + } +} + +void ecRunTestsDialog::OnOK(wxCommandEvent& event) +{ + wxDialog::OnOK(event); +} + +void ecRunTestsDialog::OnProperties(wxCommandEvent& event) +{ + ecSettingsDialog dialog(this); + dialog.SetSelection(3); + dialog.ShowModal(); +} + +void ecRunTestsDialog::OnRun(wxCommandEvent& event) +{ + if (ecRunning == m_runStatus) + { + m_output->AddLogMsg(_("Run cancelled")); + m_runStatus = ecStopping; + m_CS.Enter(); + m_nNextToSubmit=0x7fffffff; + m_CS.Leave(); + CeCosTest::CancelAllInstances(); + } + else + { + if ( 0 == m_executables->SelectedTestCount()) + { + wxMessageBox(_("No tests have been selected for execution."), + wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxOK, this); + return ; + } + else + { + m_ep = CeCosTest::ExecutionParameters( + CeCosTest::ExecutionParameters::RUN, + wxGetApp().GetSettings().GetRunTestsSettings().m_strTarget, + TIMEOUT_NONE==wxGetApp().GetSettings().GetRunTestsSettings().m_nTimeoutType?0x7fffffff:TIMEOUT_AUTOMATIC==wxGetApp().GetSettings().GetRunTestsSettings().m_nTimeoutType?900000:1000*wxGetApp().GetSettings().GetRunTestsSettings().m_nTimeout, + TIMEOUT_NONE==wxGetApp().GetSettings().GetRunTestsSettings().m_nDownloadTimeoutType?0x7fffffff:TIMEOUT_AUTOMATIC==wxGetApp().GetSettings().GetRunTestsSettings().m_nDownloadTimeoutType?0:1000*wxGetApp().GetSettings().GetRunTestsSettings().m_nDownloadTimeout); + + if ( wxGetApp().GetSettings().GetRunTestsSettings().m_bRemote ) + { + CTestResource::SetResourceServer(CeCosSocket::HostPort(wxGetApp().GetSettings().GetRunTestsSettings().m_strResourceHost, wxGetApp().GetSettings().GetRunTestsSettings().m_nResourcePort)); + if (!CTestResource::Load()) + { + wxMessageBox(_("Could not connect to resource server."), + wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxOK, this); + return; + } + } + else + { + String strPort; + if (wxGetApp().GetSettings().GetRunTestsSettings().m_bSerial) + strPort = (const wxChar*) wxGetApp().GetSettings().GetRunTestsSettings().m_strPort; + else + strPort = CeCosSocket::HostPort(wxGetApp().GetSettings().GetRunTestsSettings().m_strLocalTCPIPHost,wxGetApp().GetSettings().GetRunTestsSettings().m_nLocalTCPIPPort); + if(0==strPort.size()){ + m_pResource=new CTestResource(_T(""),m_ep.PlatformName()); + } else { + int nBaud = wxGetApp().GetSettings().GetRunTestsSettings().m_bSerial ? wxGetApp().GetSettings().GetRunTestsSettings().m_nBaud:0; + if (RESET_X10 != wxGetApp().GetSettings().GetRunTestsSettings().m_nReset) { + m_pResource=new CTestResource(_T(""),m_ep.PlatformName(), strPort, nBaud); + } else { + m_pResource=new CTestResource(_T(""),m_ep.PlatformName(), strPort, nBaud, wxGetApp().GetSettings().GetRunTestsSettings().m_strReset); + } + } + } + m_runStatus = ecRunning; + m_testsAreComplete = FALSE; + + wxButton* runButton = (wxButton*) FindWindow(ecID_RUN_TESTS_RUN); + runButton->SetLabel(_("&Stop")); + + m_nNextToSubmit=0; + m_output->AddLogMsg(_("Run started")); + + SubmitTests(); + } + } +} + +void ecRunTestsDialog::SubmitTests() +{ + int nResources=wxGetApp().GetSettings().GetRunTestsSettings().m_bRemote ? wxMax(1,CTestResource::GetMatchCount (m_ep)):1; + if(nResources>CeCosTest::InstanceCount){ + if(m_nNextToSubmit >= m_executables->SelectedTestCount()){ + return; + } + ecRunTestsInfo *pInfo=new ecRunTestsInfo; + pInfo->pTest=new CeCosTest(m_ep, m_executables->SelectedTest(m_nNextToSubmit++)); + pInfo->pSheet=this; + m_nTestsToComplete++; + if(wxGetApp().GetSettings().GetRunTestsSettings().m_bRemote){ + CeCosThreadUtils::RunThread(RunRemoteFunc,pInfo, (CeCosThreadUtils::CallbackProc*) RunCallback,_T("RunRemoteFunc")); + } else { + bool bRun=false; + switch((ResetType)wxGetApp().GetSettings().GetRunTestsSettings().m_nReset){ + case RESET_NONE: + bRun=true; + break; + case RESET_X10: + { + // Resetting can take a while, so spawn a thread + bRun=false; + ecResetThread* thread = new ecResetThread(pInfo); + if (thread->Create() != wxTHREAD_NO_ERROR) + { + // Thread will be deleted automatically when it has finished running + thread->Run(); + } + else + delete thread; + + break; + } + case RESET_MANUAL: + { + bRun=(wxOK == wxMessageBox(_("Press OK when target is reset - cancel to abort run"),_("Reset board"), wxOK|wxCANCEL)); + if(!bRun) + { + m_nNextToSubmit = m_executables->SelectedTestCount(); + RunCallback(pInfo); + } + break; + } + } + if(bRun){ + CeCosThreadUtils::RunThread(RunLocalFunc, pInfo, (CeCosThreadUtils::CallbackProc*) RunCallback,_T("RunLocalFunc")); + } + } + } +} + +// thread execution starts here +void *ecResetThread::Entry() +{ + wxString str; + String str1; + bool bOk=false; + CResetAttributes::ResetResult n=m_info->pSheet->m_pResource->Reset(str1); + str = str1; + if(CResetAttributes::RESET_OK!=n){ + str += wxT(">>> Could not reset target\n"); + } + str += wxT('\n'); + + m_info->pSheet->OutputToBuffer(str); + + if(bOk){ + // we're already in a thread, so we can call the function directly + m_info->pTest->RunLocal(); + } + ecRunTestsDialog::RunCallback(m_info); + + return NULL; +} + +// called when the thread exits - whether it terminates normally or is +// stopped with Delete() (but not when it is Kill()ed!) +void ecResetThread::OnExit() +{ +} + +void CALLBACK ecRunTestsDialog::RunLocalFunc(void *pParam) +{ + ((ecRunTestsInfo *)pParam)->pTest->RunLocal(); +} + +void CALLBACK ecRunTestsDialog::RunRemoteFunc(void *pParam) +{ + ((ecRunTestsInfo *)pParam)->pTest->RunRemote(NULL); +} + +void ecRunTestsDialog::RunCallback(void *pParam) +{ + ecRunTestsInfo *pInfo=(ecRunTestsInfo *)pParam; + ecRunTestsDialog *pSheet=pInfo->pSheet; + if (m_runTestsDialog) // Will be NULL if dialog has been closed & deleted + { + CeCosTest *pTest=pInfo->pTest; + + pInfo->pSheet->m_CS.Enter(); + + pSheet->m_summary->AddResult(pTest); + delete pTest; + + pSheet->m_nTestsToComplete--; + pSheet->SubmitTests(); + + if(0==pSheet->m_nTestsToComplete) + { + delete pSheet->m_pResource; + pSheet->m_pResource=0; + + // OnIdle will check this variable and reset the status and button label + pSheet->m_testsAreComplete = TRUE; + } + pInfo->pSheet->m_CS.Leave(); + } + delete pInfo; +} + +void ecRunTestsDialog::OnIdle(wxIdleEvent& event) +{ + FlushBuffer(); + + if (m_testsAreComplete) + { + m_testsAreComplete = FALSE; + + m_runStatus = ecStopped; + + wxButton* runButton = (wxButton*) FindWindow(ecID_RUN_TESTS_RUN); + runButton->SetLabel(_("&Run")); + + m_output->AddLogMsg(_("Run complete")); + } + + event.Skip(); +} + +void CALLBACK ecRunTestsDialog::TestOutputCallback(void *pParam,LPCTSTR psz) +{ + ecRunTestsDialog* pWnd = (ecRunTestsDialog*)pParam; + if (ecRunTestsDialog::m_runTestsDialog) + { + pWnd->OutputToBuffer(psz); + } +} + +// Write to the output buffer for OnIdle to pick up +void ecRunTestsDialog::OutputToBuffer(const wxString& str) +{ + wxCriticalSection ct; + ct.Enter(); + + if (m_outputBufferPresent) + m_outputBuffer += str; + else + m_outputBuffer = str; + m_outputBufferPresent = TRUE; + + ct.Leave(); +} + +// Write any remaining text +void ecRunTestsDialog::FlushBuffer() +{ + if (m_outputBufferPresent) + { + m_output->AddText(m_outputBuffer); + m_outputBuffer = wxEmptyString; + m_outputBufferPresent = FALSE; + } +} + +#if 0 +void ecRunTestsDialog::OnHelp(wxCommandEvent& event) +{ + int sel = m_notebook->GetSelection(); + + wxASSERT_MSG( (sel != -1), wxT("A notebook tab should always be selected.")); + + wxWindow* page = (wxWindow*) m_notebook->GetPage(sel); + + wxString helpTopic; + if (page == m_displayOptions) + { + helpTopic = wxT("Display options dialog"); + } + + if (!helpTopic.IsEmpty()) + { + wxGetApp().GetHelpController().KeywordSearch(helpTopic); + } +} +#endif + +// This sets the text for the selected page, but doesn't help +// when trying to click on a tab: we would expect the appropriate help +// for that tab. We would need to look at the tabs to do this, from within OnContextHelp - +// probably not worth it. +void ecRunTestsDialog::OnPageChange(wxNotebookEvent& event) +{ + event.Skip(); +#if 0 + int sel = m_notebook->GetSelection(); + if (sel < 0) + return; + + wxWindow* page = m_notebook->GetPage(sel); + if (page) + { + wxString helpText; + + if (page == m_displayOptions) + helpText = _("The display options dialog allows you to change display-related options."); + else if (page == m_viewerOptions) + helpText = _("The viewer options dialog allows you to configure viewers."); + else if (page == m_pathOptions) + helpText = _("The path options dialog allows you to change tool paths."); + else if (page == m_conflictResolutionOptions) + helpText = _("The conflict resolution options dialog allows you to change options related to conflict resolution."); + m_notebook->SetHelpText(helpText); + } +#endif +} + +bool ecRunTestsDialog::TransferDataToWindow() +{ + // In this case there is no data to be transferred + m_executables->TransferDataToWindow(); + m_output->TransferDataToWindow(); + m_summary->TransferDataToWindow(); + return TRUE; +} + +bool ecRunTestsDialog::TransferDataFromWindow() +{ + // In this case there is no data to be transferred + m_executables->TransferDataFromWindow(); + m_output->TransferDataFromWindow(); + m_summary->TransferDataFromWindow(); + return TRUE; +} + +void ecRunTestsDialog::OnSize(wxSizeEvent& event) +{ + event.Skip(); + + wxRefreshControls(this); +} + +// Add the test to the dialog +void ecRunTestsDialog::Populate(const wxString& test, bool select) +{ + wxCheckListBox* checkListBox = (wxCheckListBox*) FindWindow(ecID_RUN_TESTS_TEST_LIST); + + wxASSERT( checkListBox ); + + checkListBox->Append(test); + if (select) + checkListBox->Check(checkListBox->Number() - 1, TRUE); +} + + +/* Executables dialog + */ + +IMPLEMENT_CLASS(ecRunTestsExecutablesDialog, wxPanel) + +BEGIN_EVENT_TABLE(ecRunTestsExecutablesDialog, wxPanel) + EVT_BUTTON(ecID_RUN_TESTS_CHECK_ALL, ecRunTestsExecutablesDialog::OnCheckAll) + EVT_BUTTON(ecID_RUN_TESTS_UNCHECK_ALL, ecRunTestsExecutablesDialog::OnUncheckAll) + EVT_BUTTON(ecID_RUN_TESTS_ADD, ecRunTestsExecutablesDialog::OnAdd) + EVT_BUTTON(ecID_RUN_TESTS_ADD_FOLDER, ecRunTestsExecutablesDialog::OnAddFromFolder) + EVT_BUTTON(ecID_RUN_TESTS_REMOVE, ecRunTestsExecutablesDialog::OnRemove) + + EVT_UPDATE_UI(ecID_RUN_TESTS_CHECK_ALL, ecRunTestsExecutablesDialog::OnUpdateCheckAll) + EVT_UPDATE_UI(ecID_RUN_TESTS_UNCHECK_ALL, ecRunTestsExecutablesDialog::OnUpdateUncheckAll) + +END_EVENT_TABLE() + +ecRunTestsExecutablesDialog::ecRunTestsExecutablesDialog(wxWindow* parent): + wxPanel(parent, ecID_RUN_TESTS_EXECUTABLES) +{ + CreateControls(this); + + SetHelpText(_("The executables dialog allows you to select tests to be run.")); +} + +void ecRunTestsExecutablesDialog::CreateControls( wxPanel *parent) +{ + // Create the foreign control + wxCheckListBox* listBox = new wxCheckListBox(parent, ecID_RUN_TESTS_TEST_LIST, wxDefaultPosition, wxSize(100, 100), + 0, NULL, wxSUNKEN_BORDER|wxLB_EXTENDED); + + wxSizer *item0 = new wxBoxSizer( wxVERTICAL ); + + wxSizer *item1 = new wxBoxSizer( wxHORIZONTAL ); + + wxButton *item2 = new wxButton( parent, ecID_RUN_TESTS_CHECK_ALL, "C&heck All", wxDefaultPosition, wxDefaultSize, 0 ); + item1->Add( item2, 0, wxALIGN_CENTRE|wxALL, 5 ); + + item1->Add( 2, 2, 1, wxALIGN_CENTRE|wxALL, 0 ); + + wxButton *item3 = new wxButton( parent, ecID_RUN_TESTS_UNCHECK_ALL, "&Uncheck All", wxDefaultPosition, wxDefaultSize, 0 ); + item1->Add( item3, 0, wxALIGN_CENTRE|wxALL, 5 ); + + item1->Add( 2, 2, 1, wxALIGN_CENTRE|wxALL, 0 ); + + wxButton *item4 = new wxButton( parent, ecID_RUN_TESTS_ADD, "&Add...", wxDefaultPosition, wxDefaultSize, 0 ); + item1->Add( item4, 0, wxALIGN_CENTRE|wxALL, 5 ); + + item1->Add( 2, 2, 1, wxALIGN_CENTRE|wxALL, 0 ); + + wxButton *item5 = new wxButton( parent, ecID_RUN_TESTS_ADD_FOLDER, "Add from &Folder...", wxDefaultPosition, wxDefaultSize, 0 ); + item1->Add( item5, 0, wxALIGN_CENTRE|wxALL, 5 ); + + item1->Add( 2, 2, 1, wxALIGN_CENTRE|wxALL, 0 ); + + wxButton *item6 = new wxButton( parent, ecID_RUN_TESTS_REMOVE, "&Remove", wxDefaultPosition, wxDefaultSize, 0 ); + item1->Add( item6, 0, wxALIGN_CENTRE|wxALL, 5 ); + + item0->Add( item1, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + wxWindow *item7 = parent->FindWindow( ecID_RUN_TESTS_TEST_LIST ); + wxASSERT( item7 ); + item0->Add( item7, 1, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + // Add context-sensitive help + FindWindow(ecID_RUN_TESTS_TEST_LIST)->SetHelpText(_("Displays the set of tests that can be executed. Each test can be selected for execution by checking the adjacent box.")); + FindWindow(ecID_RUN_TESTS_CHECK_ALL)->SetHelpText(_("Selects all tests for execution.")); + FindWindow(ecID_RUN_TESTS_UNCHECK_ALL)->SetHelpText(_("Clears the selection of tests.")); + FindWindow(ecID_RUN_TESTS_ADD)->SetHelpText(_("Adds a test to the set that can be executed.")); + FindWindow(ecID_RUN_TESTS_ADD_FOLDER)->SetHelpText(_("Adds one or more tests to the set that can be executed, from a folder.")); + FindWindow(ecID_RUN_TESTS_REMOVE)->SetHelpText(_("Removes a test from the set that can executed.")); + + parent->SetAutoLayout( TRUE ); + parent->SetSizer( item0 ); +} + +void ecRunTestsExecutablesDialog::OnCheckAll(wxCommandEvent& event) +{ + wxCheckListBox* checkList = (wxCheckListBox*) FindWindow(ecID_RUN_TESTS_TEST_LIST); + if (!checkList) + return; + + int i; + int n = checkList->Number(); + for (i = 0; i < n; i++) + checkList->Check(i, TRUE); +} + +void ecRunTestsExecutablesDialog::OnUncheckAll(wxCommandEvent& event) +{ + wxCheckListBox* checkList = (wxCheckListBox*) FindWindow(ecID_RUN_TESTS_TEST_LIST); + if (!checkList) + return; + + int i; + int n = checkList->Number(); + for (i = 0; i < n; i++) + checkList->Check(i, FALSE); +} + +void ecRunTestsExecutablesDialog::OnAdd(wxCommandEvent& event) +{ + wxCheckListBox* checkList = (wxCheckListBox*) FindWindow(ecID_RUN_TESTS_TEST_LIST); + if (!checkList) + return; + +#ifdef __WXMSW__ + wxString wildcard(wxT("Executables (*.exe)|*.exe")); +#else + wxString wildcard(wxT("Executables (*)|*")); +#endif + + wxFileDialog dialog(this, _("Choose one or more executables to add"), wxGetCwd(), wxEmptyString, + wildcard, wxMULTIPLE|wxOPEN); + + if (dialog.ShowModal() == wxID_OK) + { + wxArrayString paths; + dialog.GetPaths(paths); + + bool err = FALSE; + + unsigned int i; + int n = paths.Count(); + for (i = 0; i < n; i++) + { + // TODO: check that it's the right kind of file + if (-1 == checkList->FindString(paths[i])) + { + checkList->Append(paths[i]); + checkList->Check(checkList->Number()-1, TRUE); + } + else + err = TRUE; + } + if (err) + wxMessageBox(_("One or more of the files was already present"), + wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxOK, this); + } +} + +void ecRunTestsExecutablesDialog::OnAddFromFolder(wxCommandEvent& event) +{ + wxCheckListBox* checkList = (wxCheckListBox*) FindWindow(ecID_RUN_TESTS_TEST_LIST); + if (!checkList) + return; + + // In the MFC tool, a modified version of the folder dialog was used but + // we can't do that in general in wxWindows; so instead we ask the questions + // before we show the folder dialog. + // We won't bother allowing the user to change the extension: on Windows it's .exe, + // on Unix it's anything. +#ifdef __WXMSW__ + wxString filespec(wxT("*.exe")); +#else + wxString filespec(wxT("*")); +#endif + + wxString msg; + msg.Printf(_("Would you like to add from subfolders, or just the folder you specify?\nChoose Yes to add from subfolders.")); + int ans = wxMessageBox(msg, wxGetApp().GetSettings().GetAppName(), wxICON_QUESTION|wxYES_NO|wxCANCEL, this); + if (ans == wxCANCEL) + return; + + bool recurse = (ans == wxYES); + + wxDirDialog dialog(this, _("Choose a folder to add tests from"), wxGetCwd()); + if (dialog.ShowModal() == wxID_OK) + { + wxString folder(dialog.GetPath()); + + if (!wxDirExists(folder)) + { + wxMessageBox(_("Sorry, this folder does not exist."), wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxOK, this); + return; + } + + wxBusyCursor busy; + AddFromFolder(folder, recurse, filespec); + } +} + +void ecRunTestsExecutablesDialog::AddFromFolder(const wxString& folder, bool recurse, const wxString& wildcard) +{ + wxString filename; + wxCheckListBox* checkList = (wxCheckListBox*) FindWindow(ecID_RUN_TESTS_TEST_LIST); + + { + wxDir dir; + if (!dir.Open(folder)) + return; + + + bool success = dir.GetFirst(& filename, wildcard, wxDIR_FILES); + while (success) + { + wxString path = folder + wxString(wxFILE_SEP_PATH) + filename; + + if (-1 == checkList->FindString(path)) + { + checkList->Append(path); + checkList->Check(checkList->Number()-1, TRUE); + } + + success = dir.GetNext(& filename); + } + } + + // Recurse down the subfolders + if (recurse) + { + wxArrayString subfolders; + + { + wxDir dir2; + if (!dir2.Open(folder)) + return; + + bool success = dir2.GetFirst(& filename, wxT("*"), wxDIR_DIRS); + while (success) + { + wxString path = folder + wxString(wxFILE_SEP_PATH) + filename; + subfolders.Add(path); + + success = dir2.GetNext(& filename); + } + } + + unsigned int i; + for (i = 0; i < subfolders.Count(); i ++) + { + AddFromFolder(subfolders[i], recurse, wildcard); + } + } +} + +void ecRunTestsExecutablesDialog::OnRemove(wxCommandEvent& event) +{ + wxCheckListBox* checkList = (wxCheckListBox*) FindWindow(ecID_RUN_TESTS_TEST_LIST); + if (!checkList) + return; + + bool cont = FALSE; + do + { + // Delete the selections one at a time since + // the indexes change when you delete one + + wxArrayInt ar; + if (checkList->GetSelections(ar) > 0) + { + checkList->Delete(ar[0]); + cont = TRUE; + } + else + cont = FALSE; + + } while (cont); + +} + +void ecRunTestsExecutablesDialog::OnUpdateCheckAll(wxUpdateUIEvent& event) +{ + wxCheckListBox* checkList = (wxCheckListBox*) FindWindow(ecID_RUN_TESTS_TEST_LIST); + if (!checkList) + return; + + // If there were no unchecked items, we can disable the check all button + event.Enable( checkList->Number() != SelectedTestCount() ); +} + +void ecRunTestsExecutablesDialog::OnUpdateUncheckAll(wxUpdateUIEvent& event) +{ + event.Enable( SelectedTestCount() > 0 ); +} + +int ecRunTestsExecutablesDialog::SelectedTestCount() +{ + wxCheckListBox* checkList = (wxCheckListBox*) FindWindow(ecID_RUN_TESTS_TEST_LIST); + if (!checkList) + return 0; + + int selCount = 0; + int i; + int n = checkList->Number(); + for (i = 0; i < n; i++) + { + if (checkList->IsChecked(i)) + { + selCount ++; + } + } + return selCount; +} + +wxString ecRunTestsExecutablesDialog::SelectedTest(int nIndex) +{ + wxString str; + wxCheckListBox* checkList = (wxCheckListBox*) FindWindow(ecID_RUN_TESTS_TEST_LIST); + if (!checkList) + return str; + + int i; + for (i=0; i < checkList->Number(); i++) + { + if (checkList->IsChecked(i)) + { + if(0==nIndex--) + { + str = checkList->GetString(i); + break; + } + } + } + return str; +} + +/* Output dialog + */ + +IMPLEMENT_CLASS(ecRunTestsOutputDialog, wxPanel) + +ecRunTestsOutputDialog::ecRunTestsOutputDialog(wxWindow* parent): + wxPanel(parent, ecID_RUN_TESTS_OUTPUT) +{ + CreateControls(this); + + SetHelpText(_("The output dialog displays the run output.")); +} + +void ecRunTestsOutputDialog::CreateControls( wxPanel *parent) +{ + wxSizer *item0 = new wxBoxSizer( wxVERTICAL ); + + wxTextCtrl *item1 = new wxTextCtrl( parent, ecID_RUN_TESTS_OUTPUT_TEXT, "", wxDefaultPosition, wxSize(80,40), wxTE_MULTILINE ); + item0->Add( item1, 1, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + // Add context-sensitive help + FindWindow(ecID_RUN_TESTS_OUTPUT_TEXT)->SetHelpText(_("Displays the output of test execution.")); + + parent->SetAutoLayout( TRUE ); + parent->SetSizer( item0 ); +} + +void ecRunTestsOutputDialog::AddText(const wxString& msg) +{ + wxTextCtrl* textCtrl = (wxTextCtrl*) FindWindow(ecID_RUN_TESTS_OUTPUT_TEXT); + wxASSERT (textCtrl != NULL); + + textCtrl->SetInsertionPointEnd(); + textCtrl->AppendText(msg); +} + +void ecRunTestsOutputDialog::AddLogMsg(const wxString& msg) +{ + wxString msg2(msg); + + if ((msg == wxEmptyString) || (msg.Last() != wxT('\n'))) + msg2 += wxT("\n"); + + AddText(msg2); +} + +/* Summary dialog + */ + +IMPLEMENT_CLASS(ecRunTestsSummaryDialog, wxPanel) + +BEGIN_EVENT_TABLE(ecRunTestsSummaryDialog, wxPanel) + EVT_LIST_COL_CLICK(ecID_RUN_TESTS_SUMMARY_LIST, ecRunTestsSummaryDialog::OnColClick) +END_EVENT_TABLE() + +wxListCtrl* ecRunTestsSummaryDialog::m_listCtrl = NULL; + +ecRunTestsSummaryDialog::ecRunTestsSummaryDialog(wxWindow* parent): + wxPanel(parent, ecID_RUN_TESTS_SUMMARY) +{ + CreateControls(this); + + SetHelpText(_("The summary dialog shows a summary of the results of each run.")); +} + +void ecRunTestsSummaryDialog::CreateControls( wxPanel *parent) +{ + m_listCtrl = new wxListCtrl(parent, ecID_RUN_TESTS_SUMMARY_LIST, wxDefaultPosition, wxSize(100, 100), wxSUNKEN_BORDER|wxLC_REPORT); + m_listCtrl->InsertColumn(0, "Time", wxLIST_FORMAT_LEFT, 60); + m_listCtrl->InsertColumn(1, "Host", wxLIST_FORMAT_LEFT, 60); + m_listCtrl->InsertColumn(2, "Platform", wxLIST_FORMAT_LEFT, 60); + m_listCtrl->InsertColumn(3, "Executable", wxLIST_FORMAT_LEFT, 60); + m_listCtrl->InsertColumn(4, "Status", wxLIST_FORMAT_LEFT, 60); + m_listCtrl->InsertColumn(5, "Size", wxLIST_FORMAT_LEFT, 60); + m_listCtrl->InsertColumn(6, "Download", wxLIST_FORMAT_LEFT, 60); + m_listCtrl->InsertColumn(7, "Elapsed", wxLIST_FORMAT_LEFT, 60); + m_listCtrl->InsertColumn(8, "Execution", wxLIST_FORMAT_LEFT, 60); + + wxSizer *item0 = new wxBoxSizer( wxVERTICAL ); + + wxWindow *item1 = parent->FindWindow( ecID_RUN_TESTS_SUMMARY_LIST ); + wxASSERT( item1 ); + item0->Add( item1, 1, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + parent->SetAutoLayout( TRUE ); + parent->SetSizer( item0 ); + + // Add context-sensitive help + FindWindow(ecID_RUN_TESTS_SUMMARY_LIST)->SetHelpText(_("Displays a summary of test execution.")); +} + +void ecRunTestsSummaryDialog::AddResult (CeCosTest *pTest) +{ + const wxString strResult(pTest->ResultString(FALSE)); + int nLength=strResult.Length(); + wxString arstr[8]; + wxString strTime,strDate; + int i; + + // 1999-05-28 10:29:28 nan:0 TX39-jmr3904-sim tx39-jmr3904sim-libc10-signal2.exe Fail 0k/1108k D=0.0/0.0 Total=9.3 E=0.6/300.0 + wxStringTokenizer tok(strResult, wxT(" ")); + strDate = tok.GetNextToken(); + strTime = tok.GetNextToken(); + + strDate += wxT(" "); + strDate += strTime; + + for (i = 0; i < 8; i++) + arstr[i] = tok.GetNextToken(); + + // Remove characters before '=' in time fields + for ( i = 5 ; i < 8 ; i ++ ) + { + wxString str = arstr[i].AfterFirst(wxT('-')) ; + arstr[i] = str.IsEmpty() ? arstr[i] : str; + } + + int nItem = m_listCtrl->GetItemCount() ; + int nIndex = m_listCtrl->InsertItem (nItem, strDate); + m_listCtrl->SetItemData(nItem,nItem);// to support sorting + for (i = 0; i < 8; i++) + { + m_listCtrl->SetItem(nIndex, i+1, arstr[i]); + } + +#if 0 + // OLD CODE + int i; + // TRACE(_T("%s\n"),strResult); + // 1999-05-28 10:29:28 nan:0 TX39-jmr3904-sim tx39-jmr3904sim-libc10-signal2.exe Fail 0k/1108k D=0.0/0.0 Total=9.3 E=0.6/300.0 + _stscanf(strResult,_T("%s %s %s %s %s %s %s %s %s %s"), + strDate.GetBuffer(1+nLength), + strTime.GetBuffer(1+nLength), + arstr[0].GetBuffer(1+nLength), + arstr[1].GetBuffer(1+nLength), + arstr[2].GetBuffer(1+nLength), + arstr[3].GetBuffer(1+nLength), + arstr[4].GetBuffer(1+nLength), + arstr[5].GetBuffer(1+nLength), + arstr[6].GetBuffer(1+nLength), + arstr[7].GetBuffer(1+nLength)); + + // Remove before '=' in time fields + for(i=5;i<8;i++){ + TCHAR *pch=_tcschr(arstr[i],_TCHAR('=')); + if(pch){ + arstr[i]=pch+1; + } + } + + strDate.ReleaseBuffer(); + strTime.ReleaseBuffer(); + strDate+=_TCHAR(' '); + strDate+=strTime; + int nItem=m_List.GetItemCount(); + m_List.InsertItem(nItem,strDate); + m_List.SetItemData(nItem,nItem);// to support sorting + for(i=0;i<8;i++){ + m_List.SetItemText(nItem,1+i,arstr[i]); + arstr[i].ReleaseBuffer(); + } +#endif +} + +// Sort function. +// The function is passed the client data of the two items, +// plus another general client data value which in this case +// we use for the column index. +int CALLBACK ecRunTestsSummaryDialog::SummarySortFunc(long data1, long data2, long col) +{ + wxString str1 = wxListCtrlGetItemTextColumn(* m_listCtrl, data1, col); + wxString str2 = wxListCtrlGetItemTextColumn(* m_listCtrl, data2, col); + + int ret = str1.CmpNoCase(str2); + return ret; +} + +void ecRunTestsSummaryDialog::OnColClick(wxListEvent& event) +{ + m_listCtrl->SortItems((wxListCtrlCompare) SummarySortFunc,(long) event.m_col); + + // The item data contains the index in the list control, so this needs + // to be reset after sorting. + int i; + for (i = m_listCtrl->GetItemCount()-1;i>=0;--i) + { + m_listCtrl->SetItemData(i,i); + } +} diff --git a/host/tools/configtool/standalone/wxwin/runtestsdlg.h b/host/tools/configtool/standalone/wxwin/runtestsdlg.h new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/runtestsdlg.h @@ -0,0 +1,234 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +// runtestsdlg.cpp : +// +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): julians +// Contact(s): julians +// Date: 2000/09/29 +// Version: $Id: runtestsdlg.h,v 1.8 2001/05/02 10:36:15 julians Exp $ +// Purpose: +// Description: Header file for ecRunTestsDialog +// Requires: +// Provides: +// See also: +// Known bugs: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== + +#ifndef _ECOS_RUNTESTSDLG_H_ +#define _ECOS_RUNTESTSDLG_H_ + +#ifdef __GNUG__ + #pragma interface "runtestsdlg.cpp" +#endif + +#include "wx/notebook.h" +#include "wx/thread.h" + +#include "eCosTest.h" +#include "Properties.h" + +//---------------------------------------------------------------------------- +// ecRunTestsDialog +//---------------------------------------------------------------------------- + +class ecRunTestsExecutablesDialog; +class ecRunTestsOutputDialog; +class ecRunTestsSummaryDialog; + +enum ecRunStatus { ecRunning, ecStopping, ecStopped }; + +#ifdef __WXGTK__ +#define DWORD int +#endif + +class ecRunTestsDialog: public wxDialog +{ +DECLARE_CLASS(ecRunTestsDialog) +friend class ecResetThread; +public: + ecRunTestsDialog(wxWindow* parent); + ~ecRunTestsDialog(); + + void OnOK(wxCommandEvent& event); + void OnRun(wxCommandEvent& event); + void OnProperties(wxCommandEvent& event); + //void OnHelp(wxCommandEvent& event); + void OnPageChange(wxNotebookEvent& event); + void OnSize(wxSizeEvent& event); + void OnIdle(wxIdleEvent& event); + + virtual bool TransferDataToWindow(); + virtual bool TransferDataFromWindow(); + + inline wxNotebook* GetNotebook() const { return m_notebook; } + + // Add the test to the dialog + void Populate(const wxString& test, bool select = TRUE); + void SubmitTests(); + + // Write to the output buffer for OnIdle to pick up + void OutputToBuffer(const wxString& str); + // Write any remaining text + void FlushBuffer(); + + // Thread callbacks + static void RunCallback(void *pParam); + static void CALLBACK RunLocalFunc(void *pParam); + static void CALLBACK RunRemoteFunc(void *pParam); + static void CALLBACK TestOutputCallback(void *pParam,LPCTSTR psz); + +protected: + + ecRunTestsExecutablesDialog* m_executables; + ecRunTestsOutputDialog* m_output; + ecRunTestsSummaryDialog* m_summary; + wxNotebook* m_notebook; + + ecRunStatus m_runStatus; + CeCosTest::ExecutionParameters m_ep; + int m_nNextToSubmit; + CTestResource* m_pResource; + CProperties m_prop; + int m_nTestsToComplete; + wxCriticalSection m_CS; + static ecRunTestsDialog* m_runTestsDialog; + bool m_testsAreComplete; + + // Output text by writing to the buffer and letting + // OnIdle pick it up + wxString m_outputBuffer; + bool m_outputBufferPresent; +DECLARE_EVENT_TABLE() +}; + +/* Executables dialog + */ + +class ecRunTestsExecutablesDialog: public wxPanel +{ +DECLARE_CLASS(ecRunTestsExecutablesDialog) +DECLARE_EVENT_TABLE() +public: + ecRunTestsExecutablesDialog(wxWindow* parent); + + void CreateControls( wxPanel *parent); + void AddFromFolder(const wxString& folder, bool recurse, const wxString& wildcard); + int SelectedTestCount(); + wxString SelectedTest(int nIndex); + + void OnCheckAll(wxCommandEvent& event); + void OnUncheckAll(wxCommandEvent& event); + void OnAdd(wxCommandEvent& event); + void OnAddFromFolder(wxCommandEvent& event); + void OnRemove(wxCommandEvent& event); + void OnUpdateCheckAll(wxUpdateUIEvent& event); + void OnUpdateUncheckAll(wxUpdateUIEvent& event); +}; + +#define ecID_RUN_TESTS_CHECK_ALL 10072 +#define ecID_RUN_TESTS_UNCHECK_ALL 10073 +#define ecID_RUN_TESTS_ADD 10074 +#define ecID_RUN_TESTS_ADD_FOLDER 10075 +#define ecID_RUN_TESTS_REMOVE 10076 +#define ecID_RUN_TESTS_TEST_LIST 2063 + +/* Output dialog + */ + +class ecRunTestsOutputDialog: public wxPanel +{ +DECLARE_CLASS(ecRunTestsOutputDialog) +public: + ecRunTestsOutputDialog(wxWindow* parent); + + void CreateControls( wxPanel *parent); + + void AddText(const wxString& msg); + void AddLogMsg(const wxString& msg); +}; + +#define ecID_RUN_TESTS_OUTPUT_TEXT 10088 + +/* Summary dialog + */ + +class WXDLLEXPORT wxListCtrl; + +// Windows requires the sort function to be of type +// CALLBACK +#ifndef CALLBACK +#define CALLBACK +#endif + +class ecRunTestsSummaryDialog: public wxPanel +{ +DECLARE_CLASS(ecRunTestsSummaryDialog) +DECLARE_EVENT_TABLE() +public: + ecRunTestsSummaryDialog(wxWindow* parent); + + void CreateControls( wxPanel *parent); + void AddResult (CeCosTest *pTest); + void OnColClick(wxListEvent& event); + static int CALLBACK SummarySortFunc(long data1, long data2, long col); + + static wxListCtrl* m_listCtrl; +}; + +#define ecID_RUN_TESTS_SUMMARY_LIST 2063 + +// Information used in thread processing +struct ecRunTestsInfo { + ecRunTestsDialog* pSheet; + CeCosTest * pTest; +}; + +// Thread class used for resetting a remote target +class ecResetThread : public wxThread +{ +public: + ecResetThread(ecRunTestsInfo* info) { m_info = info; }; + + // thread execution starts here + virtual void *Entry(); + + // called when the thread exits - whether it terminates normally or is + // stopped with Delete() (but not when it is Kill()ed!) + virtual void OnExit(); + +public: + ecRunTestsInfo* m_info; +}; + + +#endif + // _ECOS_RUNTESTSDLG_H_ diff --git a/host/tools/configtool/standalone/wxwin/sectiondlg.cpp b/host/tools/configtool/standalone/wxwin/sectiondlg.cpp new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/sectiondlg.cpp @@ -0,0 +1,497 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +// sectiondlg.cpp : +// +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): julians +// Contact(s): julians +// Date: 2000/09/27 +// Version: $Id: sectiondlg.cpp,v 1.2 2001/03/15 17:33:45 julians Exp $ +// Purpose: +// Description: Implementation file for ecSectionDialog +// Requires: +// Provides: +// See also: +// Known bugs: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== + +#ifdef __GNUG__ + #pragma implementation "sectiondlg.cpp" +#endif + +#include "ecpch.h" + +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + +#include "wx/notebook.h" +#include "wx/cshelp.h" + +#include "sectiondlg.h" +#include "configtool.h" + +/* + * Settings dialog + */ + +IMPLEMENT_CLASS(ecSectionDialog, wxDialog) + +BEGIN_EVENT_TABLE(ecSectionDialog, wxDialog) + EVT_BUTTON(wxID_OK, ecSectionDialog::OnOK) + EVT_BUTTON(wxID_CANCEL, ecSectionDialog::OnCancel) + EVT_BUTTON(wxID_HELP, ecSectionDialog::OnHelp) + EVT_BUTTON(wxID_APPLY, ecSectionDialog::OnApply) + EVT_NOTEBOOK_PAGE_CHANGED(-1, ecSectionDialog::OnPageChange) +END_EVENT_TABLE() + +#define PROPERTY_DIALOG_WIDTH 400 +#define PROPERTY_DIALOG_HEIGHT 380 + +// For 400x400 settings dialog, size your panels to about 375x325 in dialog editor +// (209 x 162 dialog units) + +ecSectionDialog::ecSectionDialog(wxWindow* parent): + wxDialog() +{ + SetExtraStyle(wxDIALOG_EX_CONTEXTHELP); + + wxDialog::Create(parent, ecID_SECTION_DIALOG, _("Section Properties"), wxPoint(0, 0), wxSize(PROPERTY_DIALOG_WIDTH, PROPERTY_DIALOG_HEIGHT)); + + // Under MSW, we don't seem to be able to react to a click on the dialog background (no + // event is generated). + SetHelpText(_("TODO")); + + wxScreenDC dc; + wxSize ppi = dc.GetPPI(); + + //double scaleFactor = ((double) charH) / 13.0; + double scaleFactor = ((double) ppi.y) / 96.0; + // Fudge the scale factor to make the dialog slightly smaller, + // otherwise it's a bit big. (We're assuming that most displays + // are 96 or 120 ppi). + if (ppi.y == 120) + scaleFactor = 1.14; + int dialogWidth = (int)(PROPERTY_DIALOG_WIDTH * scaleFactor); + int dialogHeight = (int)(PROPERTY_DIALOG_HEIGHT * scaleFactor); + SetSize(dialogWidth, dialogHeight); + + m_notebook = new wxNotebook(this, ecID_SETTINGS_NOTEBOOK, + wxPoint(2, 2), wxSize(PROPERTY_DIALOG_WIDTH - 4, PROPERTY_DIALOG_HEIGHT - 4)); + + m_general = new ecSectionGeneralDialog(m_notebook); + m_notebook->AddPage(m_general, wxT("General")); + m_general->TransferDataToWindow(); + + m_relocation = new ecSectionRelocationDialog(m_notebook); + m_notebook->AddPage(m_relocation, wxT("Relocation")); + m_relocation->TransferDataToWindow(); + + m_note = new ecSectionNoteDialog(m_notebook); + m_notebook->AddPage(m_note, wxT("Note")); + m_note->TransferDataToWindow(); + + wxSizer *item0 = new wxBoxSizer( wxVERTICAL ); + + item0->Add( m_notebook, 1, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 ); + + wxSizer *item1 = new wxBoxSizer( wxHORIZONTAL ); + + wxButton *okButton = new wxButton( this, wxID_OK, "&OK", wxDefaultPosition, wxDefaultSize, 0 ); + item1->Add( okButton, 0, wxALIGN_CENTRE|wxALL, 5 ); + + wxButton *cancelButton = new wxButton( this, wxID_CANCEL, "&Cancel", wxDefaultPosition, wxDefaultSize, 0 ); + item1->Add( cancelButton, 0, wxALIGN_CENTRE|wxALL, 5 ); + + wxButton *applyButton = new wxButton( this, wxID_APPLY, "&Apply", wxDefaultPosition, wxDefaultSize, 0 ); + item1->Add( applyButton, 0, wxALIGN_CENTRE|wxALL, 5 ); + + wxButton *helpButton = new wxButton( this, wxID_HELP, "&Help", wxDefaultPosition, wxDefaultSize, 0 ); + item1->Add( helpButton, 0, wxALIGN_CENTRE|wxALL, 5 ); + +#ifdef __WXGTK__ + // Context-sensitive help button (question mark) + wxButton *contextButton = new wxContextHelpButton( this ); + item1->Add( contextButton, 0, wxALIGN_CENTRE|wxALL, 5 ); +#endif + + // Necessary to add a spacer or the button highlight interferes with the notebook under wxGTK + item0->Add( 4, 4, 0, wxALIGN_CENTRE|wxALL, 0 ); + + item0->Add( item1, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL, 0 ); + + this->SetAutoLayout( TRUE ); + this->SetSizer( item0 ); + + okButton->SetDefault(); + okButton->SetFocus(); + + Layout(); + + m_general->Layout(); + m_relocation->Layout(); + m_note->Layout(); + + okButton->SetHelpText(_("Closes the dialog and saves any changes you may have made.")); + cancelButton->SetHelpText(_("Closes the dialog without saving any changes you have made.")); + helpButton->SetHelpText(_("Invokes help for the selected dialog.")); + applyButton->SetHelpText(_("Immediately applies any changes you may have made.")); + + Centre(wxBOTH); +} + +void ecSectionDialog::OnOK(wxCommandEvent& event) +{ + wxDialog::OnOK(event); +} + +void ecSectionDialog::OnCancel(wxCommandEvent& event) +{ + wxDialog::OnCancel(event); +} + +void ecSectionDialog::OnApply(wxCommandEvent& event) +{ +} + +void ecSectionDialog::OnHelp(wxCommandEvent& event) +{ + int sel = m_notebook->GetSelection(); + + wxASSERT_MSG( (sel != -1), wxT("A notebook tab should always be selected.")); + + wxWindow* page = (wxWindow*) m_notebook->GetPage(sel); + + wxString helpTopic; + if (page == m_general) + { + helpTopic = wxT("General section dialog"); + } + + if (!helpTopic.IsEmpty()) + { + wxGetApp().GetHelpController().KeywordSearch(helpTopic); + } +} + +// This sets the text for the selected page, but doesn't help +// when trying to click on a tab: we would expect the appropriate help +// for that tab. We would need to look at the tabs to do this, from within OnContextHelp - +// probably not worth it. +void ecSectionDialog::OnPageChange(wxNotebookEvent& event) +{ + event.Skip(); + + int sel = m_notebook->GetSelection(); + if (sel < 0) + return; + + wxWindow* page = m_notebook->GetPage(sel); + if (page) + { + wxString helpText; +#if 0 + if (page == m_displayOptions) + helpText = _("The display options dialog allows you to change display-related options."); + else if (page == m_viewerOptions) + helpText = _("The viewer options dialog allows you to configure viewers."); + else if (page == m_pathOptions) + helpText = _("The path options dialog allows you to change tool paths."); + else if (page == m_conflictResolutionOptions) + helpText = _("The conflict resolution options dialog allows you to change options related to conflict resolution."); + m_notebook->SetHelpText(helpText); +#endif + } +} + +bool ecSectionDialog::TransferDataToWindow() +{ + m_general->TransferDataToWindow(); + m_relocation->TransferDataToWindow(); + m_note->TransferDataToWindow(); + return TRUE; +} + +bool ecSectionDialog::TransferDataFromWindow() +{ + m_general->TransferDataFromWindow(); + m_relocation->TransferDataFromWindow(); + m_note->TransferDataFromWindow(); + return TRUE; +} + +/* General page + */ + +IMPLEMENT_CLASS(ecSectionGeneralDialog, wxPanel) + +ecSectionGeneralDialog::ecSectionGeneralDialog(wxWindow* parent): + wxPanel(parent, ecID_SECTION_GENERAL) +{ + CreateControls(this); + + SetHelpText(_("TODO")); +} + +void ecSectionGeneralDialog::CreateControls( wxPanel *parent) +{ + wxSizer *item0 = new wxBoxSizer( wxVERTICAL ); + + wxStaticBox *item2 = new wxStaticBox( parent, -1, "Name" ); + wxSizer *item1 = new wxStaticBoxSizer( item2, wxHORIZONTAL ); + + wxSizer *item3 = new wxBoxSizer( wxVERTICAL ); + + wxRadioButton *item4 = new wxRadioButton( parent, ecID_SECTION_GENERAL_LINKER, "&Linker-defined:", wxDefaultPosition, wxDefaultSize, wxRB_GROUP ); + item3->Add( item4, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + wxRadioButton *item5 = new wxRadioButton( parent, ecID_SECTION_GENERAL_USER, "&User-defined:", wxDefaultPosition, wxDefaultSize, 0 ); + item3->Add( item5, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxBOTTOM, 5 ); + + item1->Add( item3, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5 ); + + item1->Add( 5, 5, 1, wxALIGN_CENTRE|wxALL, 5 ); + + wxSizer *item6 = new wxBoxSizer( wxVERTICAL ); + + wxTextCtrl *item7 = new wxTextCtrl( parent, ecID_SECTION_GENERAL_LINKER_TEXT, "", wxDefaultPosition, wxSize(200,-1), 0 ); + item6->Add( item7, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + wxString strs8[] = + { + "ChoiceItem" + }; + wxChoice *item8 = new wxChoice( parent, ecID_SECTION_GENERAL_USER_TEXT, wxDefaultPosition, wxSize(100,-1), 1, strs8, 0 ); + item6->Add( item8, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxBOTTOM, 5 ); + + wxSizer *item9 = new wxBoxSizer( wxHORIZONTAL ); + + wxCheckBox *item10 = new wxCheckBox( parent, ecID_SECTION_GENERAL_KNOWN_SIZE, "&Known size:", wxDefaultPosition, wxDefaultSize, 0 ); + item9->Add( item10, 0, wxALIGN_CENTRE|wxALL, 5 ); + + wxString strs11[] = + { + "ChoiceItem" + }; + wxChoice *item11 = new wxChoice( parent, ecID_SECTION_GENERAL_KNOWN_SIZE_CHOICE, wxDefaultPosition, wxSize(100,-1), 1, strs11, 0 ); + item9->Add( item11, 0, wxALIGN_CENTRE|wxALL, 5 ); + + item6->Add( item9, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL, 0 ); + + item1->Add( item6, 0, wxALIGN_CENTRE|wxALL, 5 ); + + item0->Add( item1, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + //item0->Add( 20, 20, 0, wxALIGN_CENTRE|wxALL, 5 ); + item0->Add( 1, 1, 20, wxALIGN_CENTRE|wxALL, 0 ); + + wxStaticBox *item13 = new wxStaticBox( parent, -1, "Find Location (VMA)" ); + wxSizer *item12 = new wxStaticBoxSizer( item13, wxHORIZONTAL ); + + wxSizer *item14 = new wxBoxSizer( wxVERTICAL ); + + wxRadioButton *item15 = new wxRadioButton( parent, ecID_SECTION_GENERAL_ABSOLUTE, "A&bsolute:", wxDefaultPosition, wxDefaultSize, 0 ); + item14->Add( item15, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + wxRadioButton *item16 = new wxRadioButton( parent, ecID_SECTION_GENERAL_FOLLOWING, "&Following:", wxDefaultPosition, wxDefaultSize, 0 ); + item14->Add( item16, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxBOTTOM, 5 ); + + item12->Add( item14, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5 ); + + item12->Add( 20, 20, 1, wxALIGN_CENTRE|wxALL, 5 ); + + wxSizer *item17 = new wxBoxSizer( wxVERTICAL ); + + wxTextCtrl *item18 = new wxTextCtrl( parent, ecID_SECTION_GENERAL_ABSOLUTE_TEXT, "", wxDefaultPosition, wxSize(200,-1), 0 ); + item17->Add( item18, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + wxString strs19[] = + { + "ChoiceItem" + }; + wxChoice *item19 = new wxChoice( parent, ecID_SECTION_GENERAL_FOLLOWING_TEXT, wxDefaultPosition, wxSize(100,-1), 1, strs19, 0 ); + item17->Add( item19, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxBOTTOM, 5 ); + + wxSizer *item20 = new wxBoxSizer( wxHORIZONTAL ); + + wxStaticText *item21 = new wxStaticText( parent, wxID_STATIC, "&Alignment:", wxDefaultPosition, wxDefaultSize, 0 ); + item20->Add( item21, 0, wxALIGN_CENTRE|wxALL, 5 ); + + wxString strs22[] = + { + "ChoiceItem" + }; + wxChoice *item22 = new wxChoice( parent, ecID_SECTION_GENERAL_ALIGNMENT, wxDefaultPosition, wxSize(100,-1), 1, strs22, 0 ); + item20->Add( item22, 0, wxALIGN_CENTRE|wxALL, 5 ); + + item17->Add( item20, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL, 0 ); + + item12->Add( item17, 0, wxGROW|wxALIGN_CENTER_HORIZONTAL|wxALL, 5 ); + + item0->Add( item12, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + + // Add context-sensitive help + //item2->SetHelpText(_("")); + + parent->SetAutoLayout( TRUE ); + parent->SetSizer( item0 ); +} + +bool ecSectionGeneralDialog::TransferDataToWindow() +{ + wxPanel::TransferDataToWindow(); + return TRUE; +} + +bool ecSectionGeneralDialog::TransferDataFromWindow() +{ + wxPanel::TransferDataFromWindow(); + return TRUE; +} + +/* Relocation page + */ + +IMPLEMENT_CLASS(ecSectionRelocationDialog, wxPanel) + +ecSectionRelocationDialog::ecSectionRelocationDialog(wxWindow* parent): + wxPanel(parent, ecID_SECTION_RELOCATION) +{ + CreateControls(this); + + SetHelpText(_("TODO")); +} + +void ecSectionRelocationDialog::CreateControls( wxPanel *parent) +{ + wxSizer *item0 = new wxBoxSizer( wxVERTICAL ); + + item0->Add( 20, 20, 5, wxALIGN_CENTRE|wxALL, 5 ); + + wxCheckBox *item1 = new wxCheckBox( parent, ecID_SECTION_RELOCATION_RELOCATE, "&Relocate section", wxDefaultPosition, wxDefaultSize, 0 ); + item0->Add( item1, 0, wxALIGN_CENTER_VERTICAL|wxALL, 10 ); + + item0->Add( 20, 20, 20, wxALIGN_CENTRE|wxALL, 0 ); + + wxStaticBox *item3 = new wxStaticBox( parent, -1, "Initial Location (LMA)" ); + wxSizer *item2 = new wxStaticBoxSizer( item3, wxVERTICAL ); + + wxSizer *item4 = new wxBoxSizer( wxHORIZONTAL ); + + wxRadioButton *item5 = new wxRadioButton( parent, ecID_SECTION_RELOCATION_ABSOLUTE, "A&bsolute:", wxDefaultPosition, wxDefaultSize, 0 ); + item4->Add( item5, 0, wxALIGN_CENTRE|wxALL, 5 ); + + item4->Add( 20, 20, 1, wxALIGN_CENTRE|wxALL, 5 ); + + wxTextCtrl *item6 = new wxTextCtrl( parent, ecID_SECTION_RELOCATION_ABSOLUTE_TEXT, "", wxDefaultPosition, wxSize(80,-1), 0 ); + item4->Add( item6, 20, wxGROW|wxALIGN_CENTER_HORIZONTAL|wxALL, 5 ); + + item2->Add( item4, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + wxSizer *item7 = new wxBoxSizer( wxHORIZONTAL ); + + wxRadioButton *item8 = new wxRadioButton( parent, ecID_SECTION_RELOCATION_FOLLOWING, "&Following:", wxDefaultPosition, wxDefaultSize, 0 ); + item7->Add( item8, 0, wxALIGN_CENTRE|wxALL, 5 ); + + item7->Add( 20, 20, 1, wxALIGN_CENTRE|wxALL, 5 ); + + wxString strs9[] = + { + "ChoiceItem" + }; + wxChoice *item9 = new wxChoice( parent, ecID_SECTION_RELOCATION_FOLLOWING_CHOICE, wxDefaultPosition, wxSize(100,-1), 1, strs9, 0 ); + item7->Add( item9, 20, wxGROW|wxALIGN_CENTER_HORIZONTAL|wxALL, 5 ); + + item2->Add( item7, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + item0->Add( item2, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + item0->Add( 20, 20, 20, wxALIGN_CENTRE|wxALL, 5 ); + + // Add context-sensitive help + //item2->SetHelpText(_("")); + + parent->SetAutoLayout( TRUE ); + parent->SetSizer( item0 ); +} + +bool ecSectionRelocationDialog::TransferDataToWindow() +{ + wxPanel::TransferDataToWindow(); + return TRUE; +} + +bool ecSectionRelocationDialog::TransferDataFromWindow() +{ + wxPanel::TransferDataFromWindow(); + return TRUE; +} + +/* Note page + */ + +IMPLEMENT_CLASS(ecSectionNoteDialog, wxPanel) + +ecSectionNoteDialog::ecSectionNoteDialog(wxWindow* parent): + wxPanel(parent, ecID_SECTION_NOTE) +{ + CreateControls(this); + + SetHelpText(_("TODO")); +} + +void ecSectionNoteDialog::CreateControls( wxPanel *parent) +{ + wxSizer *item0 = new wxBoxSizer( wxVERTICAL ); + + wxTextCtrl *item1 = new wxTextCtrl( parent, ecID_SECTION_NOTE_TEXT, "", wxDefaultPosition, wxSize(80,40), wxTE_MULTILINE ); + item0->Add( item1, 20, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + + // Add context-sensitive help + //item2->SetHelpText(_("")); + + parent->SetAutoLayout( TRUE ); + parent->SetSizer( item0 ); +} + +bool ecSectionNoteDialog::TransferDataToWindow() +{ + wxPanel::TransferDataToWindow(); + return TRUE; +} + +bool ecSectionNoteDialog::TransferDataFromWindow() +{ + wxPanel::TransferDataFromWindow(); + return TRUE; +} diff --git a/host/tools/configtool/standalone/wxwin/sectiondlg.h b/host/tools/configtool/standalone/wxwin/sectiondlg.h new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/sectiondlg.h @@ -0,0 +1,156 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +// sectiondlg.h.cpp : +// +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): julians +// Contact(s): julians +// Date: 2000/09/27 +// Version: $Id: sectiondlg.h,v 1.1 2001/02/08 18:06:52 julians Exp $ +// Purpose: +// Description: Header file for ecSectionDialog +// Requires: +// Provides: +// See also: +// Known bugs: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== + +#ifndef _ECOS_SECTIONDLG_H_ +#define _ECOS_SECTIONDLG_H_ + +#ifdef __GNUG__ + #pragma interface "sectiondlg.cpp" +#endif + +#include "wx/notebook.h" + +//---------------------------------------------------------------------------- +// ecSectionDialog +//---------------------------------------------------------------------------- + +class ecSectionGeneralDialog; +class ecSectionRelocationDialog; +class ecSectionNoteDialog; + +class ecSectionDialog: public wxDialog +{ +DECLARE_CLASS(ecSectionDialog) +public: + ecSectionDialog(wxWindow* parent); + + void OnOK(wxCommandEvent& event); + void OnCancel(wxCommandEvent& event); + void OnHelp(wxCommandEvent& event); + void OnApply(wxCommandEvent& event); + void OnPageChange(wxNotebookEvent& event); + + virtual bool TransferDataToWindow(); + virtual bool TransferDataFromWindow(); + + inline wxNotebook* GetNotebook() const { return m_notebook; } + +protected: + + ecSectionGeneralDialog* m_general; + ecSectionRelocationDialog* m_relocation; + ecSectionNoteDialog* m_note; + wxNotebook* m_notebook; + +DECLARE_EVENT_TABLE() +}; + +/* General page + */ + +class ecSectionGeneralDialog: public wxPanel +{ +DECLARE_CLASS(ecSectionGeneralDialog) +public: + ecSectionGeneralDialog(wxWindow* parent); + + void CreateControls( wxPanel *parent); + + virtual bool TransferDataToWindow(); + virtual bool TransferDataFromWindow(); +}; + +#define ecID_SECTION_GENERAL_LINKER 10037 +#define ecID_SECTION_GENERAL_USER 10038 +#define ecID_SECTION_GENERAL_LINKER_TEXT 10039 +#define ecID_SECTION_GENERAL_USER_TEXT 10040 +#define ecID_SECTION_GENERAL_KNOWN_SIZE 10041 +#define ecID_SECTION_GENERAL_KNOWN_SIZE_CHOICE 10042 +#define ecID_SECTION_GENERAL_ABSOLUTE 10043 +#define ecID_SECTION_GENERAL_FOLLOWING 10044 +#define ecID_SECTION_GENERAL_ABSOLUTE_TEXT 10045 +#define ecID_SECTION_GENERAL_FOLLOWING_TEXT 10046 +#define ecID_SECTION_GENERAL_ALIGNMENT 10047 + +/* Relocation page + */ + +class ecSectionRelocationDialog: public wxPanel +{ +DECLARE_CLASS(ecSectionRelocationDialog) +public: + ecSectionRelocationDialog(wxWindow* parent); + + void CreateControls( wxPanel *parent); + + virtual bool TransferDataToWindow(); + virtual bool TransferDataFromWindow(); +}; + +#define ecID_SECTION_RELOCATION_RELOCATE 10048 +#define ecID_SECTION_RELOCATION_ABSOLUTE 10049 +#define ecID_SECTION_RELOCATION_ABSOLUTE_TEXT 10050 +#define ecID_SECTION_RELOCATION_FOLLOWING 10051 +#define ecID_SECTION_RELOCATION_FOLLOWING_CHOICE 10052 + +/* Note page + */ + +class ecSectionNoteDialog: public wxPanel +{ +DECLARE_CLASS(ecSectionNoteDialog) +public: + ecSectionNoteDialog(wxWindow* parent); + + void CreateControls( wxPanel *parent); + + virtual bool TransferDataToWindow(); + virtual bool TransferDataFromWindow(); +}; + +#define ecID_SECTION_NOTE_TEXT 10053 + +#endif + // _ECOS_SECTIONDLG_H_ diff --git a/host/tools/configtool/standalone/wxwin/settingsdlg.cpp b/host/tools/configtool/standalone/wxwin/settingsdlg.cpp new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/settingsdlg.cpp @@ -0,0 +1,1086 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +// appsettings.cpp : +// +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): julians +// Contact(s): julians +// Date: 2000/09/11 +// Version: $Id: settingsdlg.cpp,v 1.12 2001/04/24 16:34:55 julians Exp $ +// Purpose: +// Description: Implementation file for ecSettingsDialog +// Requires: +// Provides: +// See also: +// Known bugs: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== + +#ifdef __GNUG__ + #pragma implementation "settingsdlg.cpp" +#endif + +#include "ecpch.h" + +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + +#include "wx/spinctrl.h" +#include "wx/notebook.h" +#include "wx/cshelp.h" +#include "wx/valgen.h" +#include "wx/fontdlg.h" + +#include "settingsdlg.h" +#include "configtool.h" +#include "configtooldoc.h" +#include "configtoolview.h" + +// For now, we're not implementing the paths page on the settings dialog, +// but probably we should eventually for consistency and ease of use +#define ecUSE_PATHS_PAGE 0 + +// Haven't implemented this yet +#ifdef __WXDEBUG__ +#define ecUSE_RUN_PAGE 1 +#else +#define ecUSE_RUN_PAGE 0 +#endif + +/* + * Settings dialog + */ + +IMPLEMENT_CLASS(ecSettingsDialog, wxDialog) + +BEGIN_EVENT_TABLE(ecSettingsDialog, wxDialog) + EVT_BUTTON(wxID_OK, ecSettingsDialog::OnOK) + EVT_BUTTON(wxID_HELP, ecSettingsDialog::OnHelp) + EVT_NOTEBOOK_PAGE_CHANGED(-1, ecSettingsDialog::OnPageChange) +END_EVENT_TABLE() + +// GTK+ widgets seem to be chunkier than WIN32's, so give 'em more elbow-room + +#ifdef __WXMSW__ +#define PROPERTY_DIALOG_WIDTH 380 +#define PROPERTY_DIALOG_HEIGHT 420 +#else +#define PROPERTY_DIALOG_WIDTH 550 // 460 +#define PROPERTY_DIALOG_HEIGHT 480 +#endif + +// For 400x400 settings dialog, size your panels to about 375x325 in dialog editor +// (209 x 162 dialog units) + +ecSettingsDialog::ecSettingsDialog(wxWindow* parent): + wxDialog() +{ + SetExtraStyle(wxDIALOG_EX_CONTEXTHELP); + + wxDialog::Create(parent, ecID_SETTINGS_DIALOG, wxGetApp().GetSettings().GetAppName() + wxT(" Settings"), wxPoint(0, 0), wxSize(PROPERTY_DIALOG_WIDTH, PROPERTY_DIALOG_HEIGHT)); + + // Under MSW, we don't seem to be able to react to a click on the dialog background (no + // event is generated). + SetHelpText(_("The settings dialog provides the ability to change a variety of settings.")); + + wxScreenDC dc; + wxSize ppi = dc.GetPPI(); + + //double scaleFactor = ((double) charH) / 13.0; + double scaleFactor = ((double) ppi.y) / 96.0; + // Fudge the scale factor to make the dialog slightly smaller, + // otherwise it's a bit big. (We're assuming that most displays + // are 96 or 120 ppi). + if (ppi.y == 120) + scaleFactor = 1.14; + int dialogWidth = (int)(PROPERTY_DIALOG_WIDTH * scaleFactor); + int dialogHeight = (int)(PROPERTY_DIALOG_HEIGHT * scaleFactor); + SetSize(dialogWidth, dialogHeight); + + m_displayOptions = NULL; + + m_notebook = new wxNotebook(this, ecID_SETTINGS_NOTEBOOK, + wxPoint(2, 2), wxSize(PROPERTY_DIALOG_WIDTH - 4, PROPERTY_DIALOG_HEIGHT - 4)); + + m_displayOptions = new ecDisplayOptionsDialog(m_notebook); + m_notebook->AddPage(m_displayOptions, wxT("Display")); + m_displayOptions->TransferDataToWindow(); + + m_viewerOptions = new ecViewerOptionsDialog(m_notebook); + m_notebook->AddPage(m_viewerOptions, wxT("Viewers")); + m_viewerOptions->TransferDataToWindow(); + +#if ecUSE_PATHS_PAGE + m_pathOptions = new ecPathOptionsDialog(m_notebook); + m_notebook->AddPage(m_pathOptions, wxT("Paths")); + m_pathOptions->TransferDataToWindow(); +#endif + + m_conflictResolutionOptions = new ecConflictResolutionOptionsDialog(m_notebook); + m_notebook->AddPage(m_conflictResolutionOptions, wxT("Conflict Resolution")); + m_conflictResolutionOptions->TransferDataToWindow(); + +#if ecUSE_RUN_PAGE + m_runOptions = new ecRunOptionsDialog(m_notebook); + m_notebook->AddPage(m_runOptions, wxT("Run Tests")); + m_runOptions->TransferDataToWindow(); +#endif + + wxSizer *item0 = new wxBoxSizer( wxVERTICAL ); + + item0->Add( m_notebook, 1, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 ); + + wxSizer *item1 = new wxBoxSizer( wxHORIZONTAL ); + + wxButton *okButton = new wxButton( this, wxID_OK, "&OK", wxDefaultPosition, wxDefaultSize, 0 ); + item1->Add( okButton, 0, wxALIGN_CENTRE|wxALL, 5 ); + + wxButton *cancelButton = new wxButton( this, wxID_CANCEL, "&Cancel", wxDefaultPosition, wxDefaultSize, 0 ); + item1->Add( cancelButton, 0, wxALIGN_CENTRE|wxALL, 5 ); + + wxButton *helpButton = new wxButton( this, wxID_HELP, "&Help", wxDefaultPosition, wxDefaultSize, 0 ); + item1->Add( helpButton, 0, wxALIGN_CENTRE|wxALL, 5 ); + +#ifdef __WXGTK__ + // Context-sensitive help button (question mark) + wxButton *contextButton = new wxContextHelpButton( this ); + item1->Add( contextButton, 0, wxALIGN_CENTRE|wxALL, 5 ); +#endif + + // Necessary to add a spacer or the button highlight interferes with the notebook under wxGTK + item0->Add( 4, 4, 0, wxALIGN_CENTRE|wxALL, 0 ); + + item0->Add( item1, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL, 0 ); + + this->SetAutoLayout( TRUE ); + this->SetSizer( item0 ); + + okButton->SetDefault(); + okButton->SetFocus(); + + Layout(); + + m_displayOptions->Layout(); + m_viewerOptions->Layout(); +#if ecUSE_PATHS_PAGE + m_pathOptions->Layout(); +#endif + m_conflictResolutionOptions->Layout(); +#if ecUSE_RUN_PAGE + m_runOptions->Layout(); +#endif + + okButton->SetHelpText(_("Closes the dialog and saves any changes you may have made.")); + cancelButton->SetHelpText(_("Closes the dialog without saving any changes you have made.")); + helpButton->SetHelpText(_("Invokes help for the selected dialog.")); + + Centre(wxBOTH); +} + +void ecSettingsDialog::SetSelection(int sel) +{ + m_notebook->SetSelection(sel); +} + +void ecSettingsDialog::OnOK(wxCommandEvent& event) +{ + ecSettings oldSettings(wxGetApp().GetSettings()); + + wxDialog::OnOK(event); + + if (wxGetApp().GetSettings().m_bHex != oldSettings.m_bHex) + { + // Refresh the values window and currently selected properties + ecConfigToolHint hint(NULL, ecAllSaved); + if (wxGetApp().GetConfigToolDoc()) + wxGetApp().GetConfigToolDoc()->UpdateAllViews (NULL, & hint); + } + + if (wxGetApp().GetSettings().m_showMacroNames != oldSettings.m_showMacroNames) + { + ecConfigToolHint hint(NULL, ecNameFormatChanged); + if (wxGetApp().GetConfigToolDoc()) + wxGetApp().GetConfigToolDoc()->UpdateAllViews (NULL, & hint); + } +} + +void ecSettingsDialog::OnHelp(wxCommandEvent& event) +{ + int sel = m_notebook->GetSelection(); + + wxASSERT_MSG( (sel != -1), wxT("A notebook tab should always be selected.")); + + wxWindow* page = (wxWindow*) m_notebook->GetPage(sel); + + wxString helpTopic; + if (page == m_displayOptions) + { + helpTopic = wxT("Display options dialog"); + } + + if (!helpTopic.IsEmpty()) + { + wxGetApp().GetHelpController().KeywordSearch(helpTopic); + } +} + +// This sets the text for the selected page, but doesn't help +// when trying to click on a tab: we would expect the appropriate help +// for that tab. We would need to look at the tabs to do this, from within OnContextHelp - +// probably not worth it. +void ecSettingsDialog::OnPageChange(wxNotebookEvent& event) +{ + event.Skip(); + + int sel = m_notebook->GetSelection(); + if (sel < 0) + return; + + wxWindow* page = m_notebook->GetPage(sel); + if (page) + { + wxString helpText; + + if (page == m_displayOptions) + helpText = _("The display options dialog allows you to change display-related options."); + else if (page == m_viewerOptions) + helpText = _("The viewer options dialog allows you to configure viewers."); +#if ecUSE_PATHS_PAGE + else if (page == m_pathOptions) + helpText = _("The path options dialog allows you to change tool paths."); +#endif + else if (page == m_conflictResolutionOptions) + helpText = _("The conflict resolution options dialog allows you to change options related to conflict resolution."); +#if ecUSE_RUN_PAGE + else if (page == m_runOptions) + helpText = _("The run options dialog allows you to change options related to running tests."); +#endif + m_notebook->SetHelpText(helpText); + } +} + +bool ecSettingsDialog::TransferDataToWindow() +{ + m_displayOptions->TransferDataToWindow(); + m_viewerOptions->TransferDataToWindow(); +#if ecUSE_PATHS_PAGE + m_pathOptions->TransferDataToWindow(); +#endif + m_conflictResolutionOptions->TransferDataToWindow(); +#if ecUSE_RUN_PAGE + m_runOptions->TransferDataToWindow(); +#endif + return TRUE; +} + +bool ecSettingsDialog::TransferDataFromWindow() +{ + m_displayOptions->TransferDataFromWindow(); + m_viewerOptions->TransferDataFromWindow(); +#if ecUSE_PATHS_PAGE + m_pathOptions->TransferDataFromWindow(); +#endif + m_conflictResolutionOptions->TransferDataFromWindow(); +#if ecUSE_RUN_PAGE + m_runOptions->TransferDataFromWindow(); +#endif + return TRUE; +} + +/* Display options dialog + */ + +// For now, disable some unnecessary features +#define ecUSE_FONT_SELECTION 1 + +IMPLEMENT_CLASS(ecDisplayOptionsDialog, wxPanel) + +BEGIN_EVENT_TABLE(ecDisplayOptionsDialog, wxPanel) + EVT_BUTTON(ecID_DISPLAY_OPTIONS_CHANGE_FONT, ecDisplayOptionsDialog::OnChangeFont) +END_EVENT_TABLE() + +ecDisplayOptionsDialog::ecDisplayOptionsDialog(wxWindow* parent): + wxPanel(parent, ecID_SETTINGS_DISPLAY) +{ + CreateControls(this); + + SetHelpText(_("The display options dialog allows you to change display-related options")); +} + +void ecDisplayOptionsDialog::CreateControls( wxPanel *parent) +{ + wxSizer *item0 = new wxBoxSizer( wxVERTICAL ); + + wxStaticBox *item2 = new wxStaticBox( parent, -1, _("Configuration Pane") ); + wxSizer *item1 = new wxStaticBoxSizer( item2, wxHORIZONTAL ); + + wxString strs3[] = + { + _("Use ¯o names"), + _("Use descriptive &names") + }; + wxRadioBox *item3 = new wxRadioBox( parent, ecID_DISPLAY_OPTIONS_LABELS, _("Labels"), wxDefaultPosition, wxDefaultSize, 2, strs3, 1, wxRA_SPECIFY_COLS ); + item1->Add( item3, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + item1->Add( 20, 20, 1, wxALIGN_CENTRE|wxALL, 5 ); + + wxString strs4[] = + { + _("&Decimal"), + _("He&xadecimal") + }; + wxRadioBox *item4 = new wxRadioBox( parent, ecID_DISPLAY_OPTIONS_INTEGER_ITEMS, _("Integer items"), wxDefaultPosition, wxDefaultSize, 2, strs4, 1, wxRA_SPECIFY_COLS ); + item1->Add( item4, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + item0->Add( item1, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + +#if ecUSE_FONT_SELECTION + wxStaticBox *item6 = new wxStaticBox( parent, -1, _("Font") ); + wxSizer *item5 = new wxStaticBoxSizer( item6, wxHORIZONTAL ); + + wxStaticText *item7 = new wxStaticText( parent, wxID_STATIC, _("&Window:"), wxDefaultPosition, wxDefaultSize, 0 ); + item5->Add( item7, 0, wxALIGN_CENTRE|wxALL, 5 ); + + wxChoice *item8 = new wxChoice( parent, ecID_DISPLAY_OPTIONS_FONT_CHOICE, wxDefaultPosition, wxSize(120,-1), 0, NULL, 0 ); + item5->Add( item8, 0, wxALIGN_CENTRE|wxALL, 5 ); + + item5->Add( 20, 20, 1, wxALIGN_CENTRE|wxALL, 5 ); + + wxButton *item9 = new wxButton( parent, ecID_DISPLAY_OPTIONS_CHANGE_FONT, _("Change &Font..."), wxDefaultPosition, wxDefaultSize, 0 ); + item5->Add( item9, 0, wxALIGN_CENTRE|wxALL, 5 ); + + item0->Add( item5, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); +#endif + + wxStaticBox *item11 = new wxStaticBox( parent, -1, _("Miscellaneous") ); + wxSizer *item10 = new wxStaticBoxSizer( item11, wxVERTICAL ); + + wxCheckBox *item12 = new wxCheckBox( parent, ecID_DISPLAY_OPTIONS_SHOW_SPLASH, _("Show initial &splash screen"), wxDefaultPosition, wxDefaultSize, 0 ); + item10->Add( item12, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + item0->Add( item10, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + // Add validators + FindWindow(ecID_DISPLAY_OPTIONS_SHOW_SPLASH)->SetValidator(wxGenericValidator(& wxGetApp().GetSettings().m_showSplashScreen)); + + // Add context-sensitive help + item2->SetHelpText(_("Options relating to the configuration pane.")); + FindWindow(ecID_DISPLAY_OPTIONS_LABELS)->SetHelpText(_("Display macro or descriptive names in the configuration pane.")); + FindWindow(ecID_DISPLAY_OPTIONS_INTEGER_ITEMS)->SetHelpText(_("View integer items in the configuration pane in either decimal or hexadecimal.")); + +#if ecUSE_FONT_SELECTION + FindWindow(ecID_DISPLAY_OPTIONS_FONT_CHOICE)->SetHelpText(_("Selects a window for which the font is to be changed.")); + FindWindow(ecID_DISPLAY_OPTIONS_CHANGE_FONT)->SetHelpText(_("Changes the font of the chosen window.")); + // Init the choice control + unsigned int i; + for (i = 0; i < wxGetApp().GetSettings().GetWindowSettings().GetCount(); i++) + { + ((wxChoice*) FindWindow(ecID_DISPLAY_OPTIONS_FONT_CHOICE))->Append(wxGetApp().GetSettings().GetWindowSettings().GetName(i)); + } + + ((wxChoice*) FindWindow(ecID_DISPLAY_OPTIONS_FONT_CHOICE))->SetSelection(0); +#endif + + FindWindow(ecID_DISPLAY_OPTIONS_SHOW_SPLASH)->SetHelpText(_("Selects whether a splash screen will be shown as the application starts.")); + + parent->SetAutoLayout( TRUE ); + parent->SetSizer( item0 ); +} + +bool ecDisplayOptionsDialog::TransferDataToWindow() +{ + wxPanel::TransferDataToWindow(); + + ((wxRadioBox*) FindWindow(ecID_DISPLAY_OPTIONS_INTEGER_ITEMS))->SetSelection( wxGetApp().GetSettings().m_bHex ? 1 : 0 ) ; + ((wxRadioBox*) FindWindow(ecID_DISPLAY_OPTIONS_LABELS))->SetSelection( wxGetApp().GetSettings().m_showMacroNames ? 0 : 1 ) ; + return TRUE; +} + +bool ecDisplayOptionsDialog::TransferDataFromWindow() +{ + wxPanel::TransferDataFromWindow(); + + wxGetApp().GetSettings().m_bHex = ((wxRadioBox*) FindWindow(ecID_DISPLAY_OPTIONS_INTEGER_ITEMS))->GetSelection() == 1; + wxGetApp().GetSettings().m_showMacroNames = ((wxRadioBox*) FindWindow(ecID_DISPLAY_OPTIONS_LABELS))->GetSelection() == 0 ; + + if (!wxGetApp().GetSettings().GetWindowSettings().GetUseDefaults()) + wxGetApp().GetSettings().GetWindowSettings().ApplyFontsToWindows(); + + return TRUE; +} + +void ecDisplayOptionsDialog::OnChangeFont(wxCommandEvent& event) +{ + wxChoice* choice = (wxChoice*) FindWindow(ecID_DISPLAY_OPTIONS_FONT_CHOICE); + + wxString str = choice->GetStringSelection(); + if (!str.IsEmpty()) + { + wxFontData data; + data.SetInitialFont(wxGetApp().GetSettings().GetWindowSettings().GetFont(str)); + + wxFontDialog dlg(this, & data); + if (dlg.ShowModal() == wxID_OK) + { + wxGetApp().GetSettings().GetWindowSettings().SetFont(str, dlg.GetFontData().GetChosenFont()) ; + + // Changed a font, so start using specified fonts. + wxGetApp().GetSettings().GetWindowSettings().SetUseDefaults(FALSE) ; + } + } +} + + +/* Viewer options dialog + */ + +IMPLEMENT_CLASS(ecViewerOptionsDialog, wxPanel) + +BEGIN_EVENT_TABLE(ecViewerOptionsDialog, wxPanel) + EVT_BUTTON(ecID_VIEWER_DIALOG_BROWSE_HEADER, ecViewerOptionsDialog::OnBrowseForViewer) + EVT_BUTTON(ecID_VIEWER_DIALOG_BROWSE_DOC, ecViewerOptionsDialog::OnBrowseForBrowser) + + EVT_UPDATE_UI(ecID_VIEWER_DIALOG_HEADER_TEXT, ecViewerOptionsDialog::OnUpdateViewerText) + EVT_UPDATE_UI(ecID_VIEWER_DIALOG_BROWSE_HEADER, ecViewerOptionsDialog::OnUpdateViewerText) + EVT_UPDATE_UI(ecID_VIEWER_DIALOG_DOC_TEXT, ecViewerOptionsDialog::OnUpdateBrowserText) + EVT_UPDATE_UI(ecID_VIEWER_DIALOG_BROWSE_DOC, ecViewerOptionsDialog::OnUpdateBrowserText) +END_EVENT_TABLE() + +ecViewerOptionsDialog::ecViewerOptionsDialog(wxWindow* parent): + wxPanel(parent, ecID_SETTINGS_VIEWER) +{ + CreateControls(this); + + SetHelpText(_("The viewer options dialog allows you to configure viewers.")); +} + +bool ecViewerOptionsDialog::TransferDataToWindow() +{ + wxPanel::TransferDataToWindow(); + + ((wxRadioButton*) FindWindow(ecID_VIEWER_DIALOG_HEADER_ASSOCIATED))->SetValue(! wxGetApp().GetSettings().m_bUseCustomViewer); + ((wxRadioButton*) FindWindow(ecID_VIEWER_DIALOG_HEADER_THIS))->SetValue(wxGetApp().GetSettings().m_bUseCustomViewer); + + ((wxRadioButton*) FindWindow(ecID_VIEWER_DIALOG_DOC_BUILTIN))->SetValue(wxGetApp().GetSettings().m_eUseCustomBrowser == ecInternal); + ((wxRadioButton*) FindWindow(ecID_VIEWER_DIALOG_DOC_THIS))->SetValue(wxGetApp().GetSettings().m_eUseCustomBrowser == ecCustomExternal); + ((wxRadioButton*) FindWindow(ecID_VIEWER_DIALOG_DOC_ASSOCIATED))->SetValue(wxGetApp().GetSettings().m_eUseCustomBrowser == ecAssociatedExternal); + + return TRUE; +} + +bool ecViewerOptionsDialog::TransferDataFromWindow() +{ + wxPanel::TransferDataFromWindow(); + + wxGetApp().GetSettings().m_bUseCustomViewer = ! ((wxRadioButton*) FindWindow(ecID_VIEWER_DIALOG_HEADER_ASSOCIATED))->GetValue(); + + if (((wxRadioButton*) FindWindow(ecID_VIEWER_DIALOG_DOC_BUILTIN))->GetValue()) + wxGetApp().GetSettings().m_eUseCustomBrowser = ecInternal; + else if (((wxRadioButton*) FindWindow(ecID_VIEWER_DIALOG_DOC_THIS))->GetValue()) + wxGetApp().GetSettings().m_eUseCustomBrowser = ecCustomExternal; + else if (((wxRadioButton*) FindWindow(ecID_VIEWER_DIALOG_DOC_ASSOCIATED))->GetValue()) + wxGetApp().GetSettings().m_eUseCustomBrowser = ecAssociatedExternal; + + return TRUE; +} + +void ecViewerOptionsDialog::CreateControls( wxPanel *parent) +{ + wxSizer *item0 = new wxBoxSizer( wxVERTICAL ); + + wxStaticBox *item2 = new wxStaticBox( parent, -1, _("View header files using") ); + wxSizer *item1 = new wxStaticBoxSizer( item2, wxVERTICAL ); + + wxRadioButton *item3 = new wxRadioButton( parent, ecID_VIEWER_DIALOG_HEADER_ASSOCIATED, _("Associated viewer"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP ); + item1->Add( item3, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 ); + + wxSizer *item4 = new wxBoxSizer( wxHORIZONTAL ); + + wxRadioButton *item5 = new wxRadioButton( parent, ecID_VIEWER_DIALOG_HEADER_THIS, _("This &viewer:"), wxDefaultPosition, wxDefaultSize, 0 ); + item4->Add( item5, 0, wxALIGN_CENTRE|wxLEFT|wxRIGHT|wxBOTTOM, 5 ); + + item4->Add( 20, 20, 1, wxALIGN_CENTRE|wxALL, 5 ); + + wxButton *item6 = new wxButton( parent, ecID_VIEWER_DIALOG_BROWSE_HEADER, _("&Browse..."), wxDefaultPosition, wxDefaultSize, 0 ); + item4->Add( item6, 0, wxALIGN_CENTRE|wxALL, 5 ); + + item1->Add( item4, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxBOTTOM, 0 ); + + wxTextCtrl *item7 = new wxTextCtrl( parent, ecID_VIEWER_DIALOG_HEADER_TEXT, _(""), wxDefaultPosition, wxSize(80,-1), 0 ); + item1->Add( item7, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + item0->Add( item1, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + +// item0->Add( 20, 20, 1, wxALIGN_CENTRE|wxALL, 5 ); + + wxStaticBox *item9 = new wxStaticBox( parent, -1, _("View documentation using") ); + wxSizer *item8 = new wxStaticBoxSizer( item9, wxVERTICAL ); + + wxRadioButton *item10 = new wxRadioButton( parent, ecID_VIEWER_DIALOG_DOC_BUILTIN, _("&Built-in viewer"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP ); + item8->Add( item10, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 ); + + wxRadioButton *item11 = new wxRadioButton( parent, ecID_VIEWER_DIALOG_DOC_ASSOCIATED, _("Associated browser"), wxDefaultPosition, wxDefaultSize, 0 ); + item8->Add( item11, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + wxSizer *item12 = new wxBoxSizer( wxHORIZONTAL ); + + wxRadioButton *item13 = new wxRadioButton( parent, ecID_VIEWER_DIALOG_DOC_THIS, _("This &browser:"), wxDefaultPosition, wxDefaultSize, 0 ); + item12->Add( item13, 0, wxALIGN_CENTRE|wxLEFT|wxRIGHT|wxBOTTOM, 5 ); + + item12->Add( 20, 20, 1, wxALIGN_CENTRE|wxLEFT|wxRIGHT|wxBOTTOM, 5 ); + + wxButton *item14 = new wxButton( parent, ecID_VIEWER_DIALOG_BROWSE_DOC, _("Br&owse..."), wxDefaultPosition, wxDefaultSize, 0 ); + item12->Add( item14, 0, wxALIGN_CENTRE|wxLEFT|wxRIGHT|wxBOTTOM, 5 ); + + item8->Add( item12, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 0 ); + + wxTextCtrl *item15 = new wxTextCtrl( parent, ecID_VIEWER_DIALOG_DOC_TEXT, _(""), wxDefaultPosition, wxSize(80,-1), 0 ); + item8->Add( item15, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + item0->Add( item8, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + // Disable this option because we don't yet have a built-in browser +#if !ecUSE_EXPERIMENTAL_CODE + FindWindow(ecID_VIEWER_DIALOG_DOC_BUILTIN)->Enable(FALSE); +#endif + + // Add validators + FindWindow(ecID_VIEWER_DIALOG_HEADER_TEXT)->SetValidator(wxGenericValidator(& wxGetApp().GetSettings().m_strViewer)); + FindWindow(ecID_VIEWER_DIALOG_DOC_TEXT)->SetValidator(wxGenericValidator(& wxGetApp().GetSettings().m_strBrowser)); + + // Add context-sensitive help + item2->SetHelpText(_("Allows you to select a viewer to display header files.")); + FindWindow(ecID_VIEWER_DIALOG_HEADER_ASSOCIATED)->SetHelpText(_("Select the default viewer to display header files.")); + FindWindow(ecID_VIEWER_DIALOG_HEADER_THIS)->SetHelpText(_("Select a viewer of your choice to display header files.")); + FindWindow(ecID_VIEWER_DIALOG_BROWSE_HEADER)->SetHelpText(_("Browses for a viewer to be used to display header files.")); + FindWindow(ecID_VIEWER_DIALOG_HEADER_TEXT)->SetHelpText(_("Specify the viewer executable to be used to display header files.")); + item9->SetHelpText(_("Allows you to select a viewer to display documentation.")); + FindWindow(ecID_VIEWER_DIALOG_DOC_BUILTIN)->SetHelpText(_("Select the internal HTML help mechanism to display HTML-based help.")); + FindWindow(ecID_VIEWER_DIALOG_DOC_ASSOCIATED)->SetHelpText(_("Select the default browser to display HTML-based help.")); + FindWindow(ecID_VIEWER_DIALOG_DOC_THIS)->SetHelpText(_("Select a browser of your choice to display HTML-based help.")); + FindWindow(ecID_VIEWER_DIALOG_BROWSE_DOC)->SetHelpText(_("Browses for a browser to be used to display HTML-based help.")); + + parent->SetAutoLayout( TRUE ); + parent->SetSizer( item0 ); +} + +void ecViewerOptionsDialog::OnUpdateViewerText(wxUpdateUIEvent& event) +{ + event.Enable( FindWindow(ecID_VIEWER_DIALOG_HEADER_THIS) && + ((wxRadioButton*) FindWindow(ecID_VIEWER_DIALOG_HEADER_THIS))->GetValue() ); +} + +void ecViewerOptionsDialog::OnUpdateBrowserText(wxUpdateUIEvent& event) +{ + event.Enable( FindWindow(ecID_VIEWER_DIALOG_DOC_THIS) && + ((wxRadioButton*) FindWindow(ecID_VIEWER_DIALOG_DOC_THIS))->GetValue() ); +} + +void ecViewerOptionsDialog::OnBrowseForViewer(wxCommandEvent& event) +{ + wxString currentViewer = ((wxTextCtrl*) FindWindow(ecID_VIEWER_DIALOG_HEADER_TEXT))->GetValue(); + + wxFileDialog dialog(this, _("Choose a viewer executable"), wxPathOnly(currentViewer), + wxFileNameFromPath(currentViewer), wxT("*.exe")); + + if (dialog.ShowModal() == wxID_OK) + { + ((wxTextCtrl*) FindWindow(ecID_VIEWER_DIALOG_HEADER_TEXT))->SetValue(dialog.GetPath()); + } +} + +void ecViewerOptionsDialog::OnBrowseForBrowser(wxCommandEvent& event) +{ + wxString currentViewer = ((wxTextCtrl*) FindWindow(ecID_VIEWER_DIALOG_DOC_TEXT))->GetValue(); + + wxFileDialog dialog(this, _("Choose a browser executable"), wxPathOnly(currentViewer), + wxFileNameFromPath(currentViewer), wxT("*.exe")); + + if (dialog.ShowModal() == wxID_OK) + { + ((wxTextCtrl*) FindWindow(ecID_VIEWER_DIALOG_DOC_TEXT))->SetValue(dialog.GetPath()); + } +} + +/* Path options dialog + */ + +IMPLEMENT_CLASS(ecPathOptionsDialog, wxPanel) + +ecPathOptionsDialog::ecPathOptionsDialog(wxWindow* parent): + wxPanel(parent, ecID_SETTINGS_PATH) +{ + CreateControls(this); + + SetHelpText(_("The path options dialog allows you to change tool paths.")); +} + +bool ecPathOptionsDialog::TransferDataToWindow() +{ + wxPanel::TransferDataToWindow(); + return TRUE; +} + +bool ecPathOptionsDialog::TransferDataFromWindow() +{ + wxPanel::TransferDataFromWindow(); + return TRUE; +} + +void ecPathOptionsDialog::CreateControls( wxPanel *parent) +{ + wxSizer *item0 = new wxBoxSizer( wxVERTICAL ); + + wxStaticBox *item2 = new wxStaticBox( parent, -1, _("Build Tools") ); + wxSizer *item1 = new wxStaticBoxSizer( item2, wxVERTICAL ); + + wxStaticText *item3 = new wxStaticText( parent, ecID_PATHS_BUILD_MSG, + _("Enter the location of the arm-elf build tools " + "folder, which should contain arm-elf-gcc. You can " + "type in a path or use the Browse button to " + "navigate to a folder."), + wxDefaultPosition, wxSize(-1,70), 0 ); + item1->Add( item3, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + wxSizer *item4 = new wxBoxSizer( wxHORIZONTAL ); + + wxString *strs5 = (wxString*) NULL; + wxComboBox *item5 = new wxComboBox( parent, ecID_PATHS_BUILD_COMBO, _(""), wxDefaultPosition, wxSize(100,-1), 0, strs5, wxCB_DROPDOWN ); + item4->Add( item5, 20, wxALIGN_CENTRE|wxALL, 5 ); + + item1->Add( item4, 1, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 0 ); + + wxButton *item6 = new wxButton( parent, ecID_PATHS_BUILD_BROWSE, _("&Browse..."), wxDefaultPosition, wxDefaultSize, 0 ); + item1->Add( item6, 0, wxALIGN_CENTRE|wxALL, 5 ); + + item0->Add( item1, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + wxStaticBox *item8 = new wxStaticBox( parent, -1, _("User Tools") ); + wxSizer *item7 = new wxStaticBoxSizer( item8, wxVERTICAL ); + + wxStaticText *item9 = new wxStaticText( parent, ecID_PATHS_USER_MSG, + _("Enter the location of the user tools folder, " + "which should contain cat and ls. You can type in " + "a path or use the Browse button to navigate to a " + "folder."), + wxDefaultPosition, wxSize(-1,60), 0 ); + item7->Add( item9, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + wxSizer *item10 = new wxBoxSizer( wxHORIZONTAL ); + + wxString *strs11 = (wxString*) NULL; + wxComboBox *item11 = new wxComboBox( parent, ecID_PATHS_USER_COMBO, _(""), wxDefaultPosition, wxSize(100,-1), 0, strs11, wxCB_DROPDOWN ); + item10->Add( item11, 20, wxALIGN_CENTRE|wxALL, 5 ); + + item7->Add( item10, 1, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 0 ); + + wxButton *item12 = new wxButton( parent, ecID_PATHS_USER_BROWSE, _("&Browse..."), wxDefaultPosition, wxDefaultSize, 0 ); + item7->Add( item12, 0, wxALIGN_CENTRE|wxALL, 5 ); + item0->Add( item7, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + + parent->SetAutoLayout( TRUE ); + parent->SetSizer( item0 ); + + // Add context-sensitive help + FindWindow( ecID_PATHS_BUILD_COMBO )->SetHelpText(_("Select the build tools folder.")); + FindWindow( ecID_PATHS_BUILD_BROWSE )->SetHelpText(_("Browse for the build tools folder.")); + FindWindow( ecID_PATHS_USER_COMBO )->SetHelpText(_("Select the user tools folder.")); + FindWindow( ecID_PATHS_USER_BROWSE )->SetHelpText(_("Browse for the user tools folder.")); +} + +/* Conflict resolution options dialog + */ + +IMPLEMENT_CLASS(ecConflictResolutionOptionsDialog, wxPanel) + +ecConflictResolutionOptionsDialog::ecConflictResolutionOptionsDialog(wxWindow* parent): + wxPanel(parent, ecID_SETTINGS_CONFLICT_RESOLUTION) +{ + CreateControls(this); + + m_suggestFixes = ((wxGetApp().GetSettings().m_nRuleChecking & ecSettings::SuggestFixes) != 0); + m_immediate = ((wxGetApp().GetSettings().m_nRuleChecking & ecSettings::Immediate) != 0); + m_deferred = ((wxGetApp().GetSettings().m_nRuleChecking & ecSettings::Deferred) != 0); + + SetHelpText(_("The conflict resolution options dialog allows you to change options related to conflict resolution.")); +} + +bool ecConflictResolutionOptionsDialog::TransferDataToWindow() +{ + wxPanel::TransferDataToWindow(); + return TRUE; +} + +bool ecConflictResolutionOptionsDialog::TransferDataFromWindow() +{ + wxPanel::TransferDataFromWindow(); + + int& ruleChecking = wxGetApp().GetSettings().m_nRuleChecking; + + ruleChecking = 0; + if (m_suggestFixes) + ruleChecking |= ecSettings::SuggestFixes ; + if (m_immediate) + ruleChecking |= ecSettings::Immediate ; + if (m_deferred) + ruleChecking |= ecSettings::Deferred ; + + return TRUE; +} + +void ecConflictResolutionOptionsDialog::CreateControls( wxPanel *parent) +{ + wxSizer *item0 = new wxBoxSizer( wxVERTICAL ); + + wxStaticBox *item2 = new wxStaticBox( parent, -1, _("Check for conflicts:") ); + wxSizer *item1 = new wxStaticBoxSizer( item2, wxVERTICAL ); + + wxCheckBox *item3 = new wxCheckBox( parent, ecID_CONFLICT_OPTIONS_AFTER_ITEM_CHANGED, _("After any item changed"), wxDefaultPosition, wxDefaultSize, 0 ); + item1->Add( item3, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + wxCheckBox *item4 = new wxCheckBox( parent, ecID_CONFLICT_OPTIONS_BEFORE_SAVING, _("Before &saving configuration"), wxDefaultPosition, wxDefaultSize, 0 ); + item1->Add( item4, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + wxCheckBox *item5 = new wxCheckBox( parent, ecID_CONFLICT_OPTIONS_AUTOSUGGEST, _("&Automatically suggest fixes"), wxDefaultPosition, wxDefaultSize, 0 ); + item1->Add( item5, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + item0->Add( item1, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + parent->SetAutoLayout( TRUE ); + parent->SetSizer( item0 ); + + // Add context-sensitive help + item2->SetHelpText(_("Options related to conflict resolution.")); + item3->SetHelpText(_("Check for configuration option conflicts after any configuration option value is changed.")); + item4->SetHelpText(_("Check for configuration option conflicts before saving the configuration.")); + item5->SetHelpText(_("When configuration conflicts are found, provide possible solutions.")); + + // Add validators + FindWindow(ecID_CONFLICT_OPTIONS_AFTER_ITEM_CHANGED)->SetValidator(wxGenericValidator(& m_immediate)); + FindWindow(ecID_CONFLICT_OPTIONS_BEFORE_SAVING)->SetValidator(wxGenericValidator(& m_deferred)); + FindWindow(ecID_CONFLICT_OPTIONS_AUTOSUGGEST)->SetValidator(wxGenericValidator(& m_suggestFixes)); +} + +/* Run options dialog + */ + +IMPLEMENT_CLASS(ecRunOptionsDialog, wxPanel) + +BEGIN_EVENT_TABLE(ecRunOptionsDialog, wxPanel) + EVT_UPDATE_UI(ecID_RUN_PROPERTIES_DOWNLOAD_TIMEOUT, ecRunOptionsDialog::OnUpdateDownloadTimeout) + EVT_UPDATE_UI(ecID_RUN_PROPERTIES_RUNTIME_TIMEOUT, ecRunOptionsDialog::OnUpdateRuntimeTimeout) + EVT_UPDATE_UI(ecID_RUN_PROPERTIES_SERIAL_PORT_ADDR, ecRunOptionsDialog::OnUpdateSerial) + EVT_UPDATE_UI(ecID_RUN_PROPERTIES_SERIAL_PORT_SPEED, ecRunOptionsDialog::OnUpdateSerial) + EVT_UPDATE_UI(ecID_RUN_PROPERTIES_TCPIP_HOST, ecRunOptionsDialog::OnUpdateTCPIP) + EVT_UPDATE_UI(ecID_RUN_PROPERTIES_TCPIP_PORT, ecRunOptionsDialog::OnUpdateTCPIP) +END_EVENT_TABLE() + +ecRunOptionsDialog::ecRunOptionsDialog(wxWindow* parent): + wxPanel(parent, ecID_SETTINGS_RUN), + m_serialOn(TRUE), m_TCPIPOn(FALSE) +{ + CreateControls(this); + + SetHelpText(_("The run properties dialog allows you to change options related to running tests.")); +} + +bool ecRunOptionsDialog::TransferDataToWindow() +{ +#if 0 + // m_strTarget now set in ecConfigToolDoc::RunTests() + ecConfigToolDoc* doc = wxGetApp().GetConfigToolDoc(); + wxString hardware; + if (doc) + { + hardware = doc->GetCdlConfig ()->get_hardware ().c_str(); + } + else + { + hardware = _("Unknown"); + } + wxGetApp().GetSettings().GetRunTestsSettings().m_strTarget = hardware; +#endif + + // Serial/TCPIP + m_serialOn = wxGetApp().GetSettings().GetRunTestsSettings().m_bSerial; + m_TCPIPOn = !wxGetApp().GetSettings().GetRunTestsSettings().m_bSerial; + + switch (wxGetApp().GetSettings().GetRunTestsSettings().m_nDownloadTimeoutType) + { + case TIMEOUT_NONE: + m_downloadTimeoutString = _("None"); + break; + case TIMEOUT_SPECIFIED: + m_downloadTimeoutString = _("Specified"); + break; + default: + case TIMEOUT_AUTOMATIC: + m_downloadTimeoutString = _("Calculated from file size"); + break; + } + + switch (wxGetApp().GetSettings().GetRunTestsSettings().m_nTimeoutType) + { + case TIMEOUT_NONE: + m_runtimeTimeoutString = _("None"); + break; + case TIMEOUT_SPECIFIED: + m_runtimeTimeoutString = _("Specified"); + break; + default: + case TIMEOUT_AUTOMATIC: + m_runtimeTimeoutString = _("Default"); + break; + } + + m_baudString.Printf("%d", wxGetApp().GetSettings().GetRunTestsSettings().m_nBaud); + + wxPanel::TransferDataToWindow(); + + return TRUE; +} + +bool ecRunOptionsDialog::TransferDataFromWindow() +{ + wxPanel::TransferDataFromWindow(); + + if (m_downloadTimeoutString == _("None")) + wxGetApp().GetSettings().GetRunTestsSettings().m_nDownloadTimeoutType = TIMEOUT_NONE; + else if (m_downloadTimeoutString == _("Specified")) + wxGetApp().GetSettings().GetRunTestsSettings().m_nDownloadTimeoutType = TIMEOUT_SPECIFIED; + else + wxGetApp().GetSettings().GetRunTestsSettings().m_nDownloadTimeoutType = TIMEOUT_AUTOMATIC; + + if (m_runtimeTimeoutString == _("None")) + wxGetApp().GetSettings().GetRunTestsSettings().m_nTimeoutType = TIMEOUT_NONE; + else if (m_runtimeTimeoutString == _("Specified")) + wxGetApp().GetSettings().GetRunTestsSettings().m_nTimeoutType = TIMEOUT_SPECIFIED; + else + wxGetApp().GetSettings().GetRunTestsSettings().m_nTimeoutType = TIMEOUT_AUTOMATIC; + + wxGetApp().GetSettings().GetRunTestsSettings().m_nBaud = (int) wxAtol(m_baudString); + + // Serial/TCPIP + wxGetApp().GetSettings().GetRunTestsSettings().m_bSerial = m_serialOn; + + return TRUE; +} + +void ecRunOptionsDialog::CreateControls( wxPanel *parent) +{ + wxSizer *item0 = new wxBoxSizer( wxVERTICAL ); + + wxSizer *item1 = new wxBoxSizer( wxHORIZONTAL ); + + wxStaticText *item2 = new wxStaticText( parent, wxID_STATIC, _("Platform:"), wxDefaultPosition, wxDefaultSize, 0 ); + item1->Add( item2, 0, wxALIGN_CENTRE|wxALL, 5 ); + + wxStaticText *item3 = new wxStaticText( parent, ecID_RUN_PROPERTIES_PLATFORM, _("xxxx"), wxDefaultPosition, wxDefaultSize, 0 ); + item1->Add( item3, 0, wxALIGN_CENTRE|wxALL, 5 ); + + item0->Add( item1, 0, wxALIGN_CENTRE|wxLEFT|wxRIGHT|wxTOP, 5 ); + + wxStaticBox *item5 = new wxStaticBox( parent, -1, _("Timeouts") ); + wxSizer *item4 = new wxStaticBoxSizer( item5, wxVERTICAL ); + + wxSizer *item6 = new wxBoxSizer( wxHORIZONTAL ); + + wxStaticText *item7 = new wxStaticText( parent, wxID_STATIC, _("Download:"), wxDefaultPosition, wxSize(60,-1), 0 ); + item6->Add( item7, 0, wxALIGN_CENTRE|wxALL, 5 ); + + wxString strs8[] = + { + _("None"), + _("Specified"), + _("Calculated from file size") + }; + wxChoice *item8 = new wxChoice( parent, ecID_RUN_PROPERTIES_DOWNLOAD_CHOICE, wxDefaultPosition, wxSize(100,-1), 3, strs8, 0 ); + item6->Add( item8, 1, wxALIGN_CENTRE|wxALL, 5 ); + + wxSpinCtrl *item9 = new wxSpinCtrl( parent, ecID_RUN_PROPERTIES_DOWNLOAD_TIMEOUT, "0", wxDefaultPosition, wxSize(50,-1), 0, 0, 10000, 0 ); + item6->Add( item9, 0, wxALIGN_CENTRE|wxALL, 5 ); + + item4->Add( item6, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + wxSizer *item10 = new wxBoxSizer( wxHORIZONTAL ); + + wxStaticText *item11 = new wxStaticText( parent, wxID_STATIC, _("Runtime:"), wxDefaultPosition, wxSize(60,-1), 0 ); + item10->Add( item11, 0, wxALIGN_CENTRE|wxALL, 5 ); + + wxString strs12[] = + { + _("None"), + _("Specified"), + _("Default") + }; + wxChoice *item12 = new wxChoice( parent, ecID_RUN_PROPERTIES_RUNTIME_CHOICE, wxDefaultPosition, wxSize(100,-1), 3, strs12, 0 ); + item10->Add( item12, 1, wxALIGN_CENTRE|wxALL, 5 ); + + wxSpinCtrl *item13 = new wxSpinCtrl( parent, ecID_RUN_PROPERTIES_RUNTIME_TIMEOUT, "0", wxDefaultPosition, wxSize(50,-1), 0, 0, 10000, 0 ); + item10->Add( item13, 0, wxALIGN_CENTRE|wxALL, 5 ); + + item4->Add( item10, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + item0->Add( item4, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + wxStaticBox *item15 = new wxStaticBox( parent, -1, _("Connection") ); + wxSizer *item14 = new wxStaticBoxSizer( item15, wxVERTICAL ); + + wxSizer *item16 = new wxBoxSizer( wxHORIZONTAL ); + + wxRadioButton *item17 = new wxRadioButton( parent, ecID_RUN_PROPERTIES_SERIAL, _("&Serial"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP ); + item16->Add( item17, 0, wxALIGN_CENTRE|wxALL, 5 ); + + item16->Add( 2, 2, 1, wxALIGN_CENTRE|wxALL, 5 ); + + wxStaticText *item18 = new wxStaticText( parent, wxID_STATIC, _("&Port:"), wxDefaultPosition, wxDefaultSize, 0 ); + item16->Add( item18, 0, wxALIGN_CENTRE|wxLEFT|wxTOP|wxBOTTOM, 5 ); + + wxString strs19[] = + { + _("COM1"), + _("COM2"), + _("COM3"), + _("COM4"), + _("COM5"), + _("COM6"), + _("COM7"), + _("COM8") + }; + wxChoice *item19 = new wxChoice( parent, ecID_RUN_PROPERTIES_SERIAL_PORT_ADDR, wxDefaultPosition, wxSize(70,-1), 8, strs19, 0 ); + item16->Add( item19, 0, wxALIGN_CENTRE|wxALL, 5 ); + + wxStaticText *item20 = new wxStaticText( parent, wxID_STATIC, _("&Baud:"), wxDefaultPosition, wxDefaultSize, 0 ); + item16->Add( item20, 0, wxALIGN_CENTRE|wxLEFT|wxTOP|wxBOTTOM, 5 ); + + wxString strs21[] = + { + _("110"), + _("300"), + _("600"), + _("1200"), + _("2400"), + _("4800"), + _("9600"), + _("14400"), + _("19200"), + _("38400"), + _("56000"), + _("57600"), + _("115200"), + _("128000"), + _("256000") + }; + wxChoice *item21 = new wxChoice( parent, ecID_RUN_PROPERTIES_SERIAL_PORT_SPEED, wxDefaultPosition, wxSize(70,-1), 15, strs21, 0 ); + item16->Add( item21, 0, wxALIGN_CENTRE|wxALL, 5 ); + + item14->Add( item16, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + wxSizer *item22 = new wxBoxSizer( wxHORIZONTAL ); + + wxRadioButton *item23 = new wxRadioButton( parent, ecID_RUN_PROPERTIES_TCPIP, _("&TCP/IP"), wxDefaultPosition, wxDefaultSize, 0 ); + item22->Add( item23, 0, wxALIGN_CENTRE|wxALL, 5 ); + + item22->Add( 2, 2, 1, wxALIGN_CENTRE|wxALL, 5 ); + + wxStaticText *item24 = new wxStaticText( parent, wxID_STATIC, _("&Address:"), wxDefaultPosition, wxDefaultSize, 0 ); + item22->Add( item24, 0, wxALIGN_CENTRE|wxALL, 5 ); + + wxTextCtrl *item25 = new wxTextCtrl( parent, ecID_RUN_PROPERTIES_TCPIP_HOST, _(""), wxDefaultPosition, wxSize(100,-1), 0 ); + item22->Add( item25, 0, wxALIGN_CENTRE|wxALL, 5 ); + + wxStaticText *item26 = new wxStaticText( parent, wxID_STATIC, _(":"), wxDefaultPosition, wxDefaultSize, 0 ); + item22->Add( item26, 0, wxALIGN_CENTRE, 5 ); + + wxTextCtrl *item27 = new wxTextCtrl( parent, ecID_RUN_PROPERTIES_TCPIP_PORT, _(""), wxDefaultPosition, wxSize(30,-1), 0 ); + item22->Add( item27, 0, wxALIGN_CENTRE|wxALL, 5 ); + + item14->Add( item22, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + item0->Add( item14, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + parent->SetAutoLayout( TRUE ); + parent->SetSizer( item0 ); + + // Add context-sensitive help + FindWindow(ecID_RUN_PROPERTIES_PLATFORM)->SetHelpText(_("Shows the hardware currently selected.")); + FindWindow(ecID_RUN_PROPERTIES_DOWNLOAD_CHOICE)->SetHelpText(_("Specifies the kind of timeout to be applied to the download phase of test execution.")); + FindWindow(ecID_RUN_PROPERTIES_DOWNLOAD_TIMEOUT)->SetHelpText(_("Specifies a fixed-period timeout (in seconds) to be applied to the download phase of test execution.")); + FindWindow(ecID_RUN_PROPERTIES_RUNTIME_CHOICE)->SetHelpText(_("Specifies the kind of timeout to be applied to the run phase of test execution.")); + FindWindow(ecID_RUN_PROPERTIES_RUNTIME_TIMEOUT)->SetHelpText(_("Specifies a fixed-period timeout (in seconds) to be applied to the run phase of test execution.")); + FindWindow(ecID_RUN_PROPERTIES_SERIAL)->SetHelpText(_("Specifies that download is local, using a serial communications port.")); + FindWindow(ecID_RUN_PROPERTIES_SERIAL_PORT_ADDR)->SetHelpText(_("Specifies the communication ports to be used for local download.")); + FindWindow(ecID_RUN_PROPERTIES_SERIAL_PORT_SPEED)->SetHelpText(_("Specifies the baud rate at which the communications port is to operate.")); + FindWindow(ecID_RUN_PROPERTIES_TCPIP)->SetHelpText(_("Specifies that download is remote, using GDB remote protocol via a TCP/IP port.")); + FindWindow(ecID_RUN_PROPERTIES_TCPIP_HOST)->SetHelpText(_("Specifies the TCP/IP host to be used for remote download.")); + FindWindow(ecID_RUN_PROPERTIES_TCPIP_PORT)->SetHelpText(_("Specifies the TCP/IP port number to be used for remote download.")); + + // Add validators + FindWindow(ecID_RUN_PROPERTIES_PLATFORM)->SetValidator(wxGenericValidator(& wxGetApp().GetSettings().GetRunTestsSettings().m_strTarget)); + FindWindow(ecID_RUN_PROPERTIES_DOWNLOAD_CHOICE)->SetValidator(wxGenericValidator(& m_downloadTimeoutString)); + FindWindow(ecID_RUN_PROPERTIES_DOWNLOAD_TIMEOUT)->SetValidator(wxGenericValidator(& wxGetApp().GetSettings().GetRunTestsSettings().m_nDownloadTimeout)); + FindWindow(ecID_RUN_PROPERTIES_RUNTIME_CHOICE)->SetValidator(wxGenericValidator(& m_runtimeTimeoutString)); + FindWindow(ecID_RUN_PROPERTIES_RUNTIME_TIMEOUT)->SetValidator(wxGenericValidator(& wxGetApp().GetSettings().GetRunTestsSettings().m_nTimeout)); + FindWindow(ecID_RUN_PROPERTIES_SERIAL)->SetValidator(wxGenericValidator(& m_serialOn)); + FindWindow(ecID_RUN_PROPERTIES_TCPIP)->SetValidator(wxGenericValidator(& m_TCPIPOn)); + FindWindow(ecID_RUN_PROPERTIES_SERIAL_PORT_ADDR)->SetValidator(wxGenericValidator(& wxGetApp().GetSettings().GetRunTestsSettings().m_strPort)); + FindWindow(ecID_RUN_PROPERTIES_SERIAL_PORT_SPEED)->SetValidator(wxGenericValidator(& m_baudString)); + FindWindow(ecID_RUN_PROPERTIES_TCPIP_HOST)->SetValidator(wxGenericValidator(& wxGetApp().GetSettings().GetRunTestsSettings().m_strLocalTCPIPHost)); + FindWindow(ecID_RUN_PROPERTIES_TCPIP_PORT)->SetValidator(wxGenericValidator(& wxGetApp().GetSettings().GetRunTestsSettings().m_nLocalTCPIPPort)); + +} + +void ecRunOptionsDialog::OnUpdateDownloadTimeout(wxUpdateUIEvent& event) +{ + wxChoice* downloadTimeoutChoice = (wxChoice*) FindWindow(ecID_RUN_PROPERTIES_DOWNLOAD_CHOICE); + wxString sel = downloadTimeoutChoice->GetStringSelection(); + event.Enable( sel == _("Specified") ); +} + +void ecRunOptionsDialog::OnUpdateRuntimeTimeout(wxUpdateUIEvent& event) +{ + wxChoice* runTimeoutChoice = (wxChoice*) FindWindow(ecID_RUN_PROPERTIES_RUNTIME_CHOICE); + wxString sel = runTimeoutChoice->GetStringSelection(); + event.Enable( sel == _("Specified") ); +} + +void ecRunOptionsDialog::OnUpdateSerial(wxUpdateUIEvent& event) +{ + wxRadioButton* radio = (wxRadioButton*) FindWindow(ecID_RUN_PROPERTIES_SERIAL); + event.Enable( radio->GetValue() ); +} + +void ecRunOptionsDialog::OnUpdateTCPIP(wxUpdateUIEvent& event) +{ + wxRadioButton* radio = (wxRadioButton*) FindWindow(ecID_RUN_PROPERTIES_SERIAL); + event.Enable( !radio->GetValue() ); +} diff --git a/host/tools/configtool/standalone/wxwin/settingsdlg.h b/host/tools/configtool/standalone/wxwin/settingsdlg.h new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/settingsdlg.h @@ -0,0 +1,241 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +// settingsdlg.cpp : +// +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): julians +// Contact(s): julians +// Date: 2000/09/11 +// Version: $Id: settingsdlg.h,v 1.6 2001/04/24 16:34:55 julians Exp $ +// Purpose: +// Description: Header file for ecSettingsDialog +// Requires: +// Provides: +// See also: +// Known bugs: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== + +#ifndef _ECOS_SETTINGSDLG_H_ +#define _ECOS_SETTINGSDLG_H_ + +#ifdef __GNUG__ + #pragma interface "settingsdlg.cpp" +#endif + +class ecDisplayOptionsDialog; // Configuration Pane/Font +class ecViewerOptionsDialog; +class ecPathOptionsDialog; +class ecConflictResolutionOptionsDialog; +class ecRunOptionsDialog; + +/* + * ecSettingsDialog + * + * This the application settings dialog, containing + * several further tabbed panels. + * + */ + +class ecSettingsDialog: public wxDialog +{ +DECLARE_CLASS(ecSettingsDialog) +public: + ecSettingsDialog(wxWindow* parent); + + void OnOK(wxCommandEvent& event); + void OnHelp(wxCommandEvent& event); + void OnPageChange(wxNotebookEvent& event); + + virtual bool TransferDataToWindow(); + virtual bool TransferDataFromWindow(); + + inline wxNotebook* GetNotebook() const { return m_notebook; } + + void SetSelection(int sel); + +protected: + + ecDisplayOptionsDialog* m_displayOptions; + ecViewerOptionsDialog* m_viewerOptions; + ecPathOptionsDialog* m_pathOptions; + ecConflictResolutionOptionsDialog* m_conflictResolutionOptions; + ecRunOptionsDialog* m_runOptions; + wxNotebook* m_notebook; + +DECLARE_EVENT_TABLE() +}; + +/* Display options dialog + */ + +class ecDisplayOptionsDialog: public wxPanel +{ +DECLARE_CLASS(ecDisplayOptionsDialog) +public: + ecDisplayOptionsDialog(wxWindow* parent); + + void CreateControls( wxPanel *parent); + + void OnChangeFont(wxCommandEvent& event); + + virtual bool TransferDataToWindow(); + virtual bool TransferDataFromWindow(); + +DECLARE_EVENT_TABLE() +}; + +#define ecID_DISPLAY_OPTIONS_LABELS 10100 +#define ecID_DISPLAY_OPTIONS_INTEGER_ITEMS 10101 +#define ecID_DISPLAY_OPTIONS_FONT_CHOICE 10102 +#define ecID_DISPLAY_OPTIONS_CHANGE_FONT 10103 +#define ecID_DISPLAY_OPTIONS_SHOW_SPLASH 10104 + +/* Viewer options dialog + */ + +class ecViewerOptionsDialog: public wxPanel +{ +DECLARE_CLASS(ecViewerOptionsDialog) +public: + ecViewerOptionsDialog(wxWindow* parent); + +//// Operations + void CreateControls( wxPanel *parent); + +//// Overrides + virtual bool TransferDataToWindow(); + virtual bool TransferDataFromWindow(); + +//// Event handlers + void OnUpdateViewerText(wxUpdateUIEvent& event); + void OnUpdateBrowserText(wxUpdateUIEvent& event); + void OnBrowseForViewer(wxCommandEvent& event); + void OnBrowseForBrowser(wxCommandEvent& event); + + DECLARE_EVENT_TABLE() +}; + +#define ecID_VIEWER_DIALOG_HEADER_ASSOCIATED 10008 +#define ecID_VIEWER_DIALOG_HEADER_THIS 10009 +#define ecID_VIEWER_DIALOG_BROWSE_HEADER 10010 +#define ecID_VIEWER_DIALOG_HEADER_TEXT 10011 +#define ecID_VIEWER_DIALOG_DOC_BUILTIN 10012 +#define ecID_VIEWER_DIALOG_DOC_ASSOCIATED 10013 +#define ecID_VIEWER_DIALOG_DOC_THIS 10014 +#define ecID_VIEWER_DIALOG_BROWSE_DOC 10015 +#define ecID_VIEWER_DIALOG_DOC_TEXT 10016 + +/* Path options dialog + */ + +class ecPathOptionsDialog: public wxPanel +{ +DECLARE_CLASS(ecPathOptionsDialog) +public: + ecPathOptionsDialog(wxWindow* parent); + + void CreateControls( wxPanel *parent); + + virtual bool TransferDataToWindow(); + virtual bool TransferDataFromWindow(); +}; + +#define ecID_PATHS_BUILD_MSG 10019 +#define ecID_PATHS_BUILD_COMBO 10020 +#define ecID_PATHS_BUILD_BROWSE 10021 +#define ecID_PATHS_USER_MSG 10022 +#define ecID_PATHS_USER_COMBO 10023 +#define ecID_PATHS_USER_BROWSE 10024 + +/* Conflict resolution options dialog + */ + +class ecConflictResolutionOptionsDialog: public wxPanel +{ +DECLARE_CLASS(ecConflictResolutionOptionsDialog) +public: + ecConflictResolutionOptionsDialog(wxWindow* parent); + + void CreateControls( wxPanel *parent); + + virtual bool TransferDataToWindow(); + virtual bool TransferDataFromWindow(); + + bool m_suggestFixes; + bool m_immediate; + bool m_deferred; +}; + +#define ecID_CONFLICT_OPTIONS_AFTER_ITEM_CHANGED 10025 +#define ecID_CONFLICT_OPTIONS_BEFORE_SAVING 10026 +#define ecID_CONFLICT_OPTIONS_AUTOSUGGEST 10027 + +/* Run options dialog + */ + +class ecRunOptionsDialog: public wxPanel +{ +DECLARE_CLASS(ecRunOptionsDialog) +DECLARE_EVENT_TABLE() +public: + ecRunOptionsDialog(wxWindow* parent); + + void CreateControls( wxPanel *parent); + + virtual bool TransferDataToWindow(); + virtual bool TransferDataFromWindow(); + + void OnUpdateDownloadTimeout(wxUpdateUIEvent& event); + void OnUpdateRuntimeTimeout(wxUpdateUIEvent& event); + void OnUpdateSerial(wxUpdateUIEvent& event); + void OnUpdateTCPIP(wxUpdateUIEvent& event); + + wxString m_downloadTimeoutString; + wxString m_runtimeTimeoutString; + wxString m_baudString; + bool m_serialOn; + bool m_TCPIPOn; +}; + +#define ecID_RUN_PROPERTIES_PLATFORM 10077 +#define ecID_RUN_PROPERTIES_DOWNLOAD_CHOICE 10078 +#define ecID_RUN_PROPERTIES_DOWNLOAD_TIMEOUT 10079 +#define ecID_RUN_PROPERTIES_RUNTIME_CHOICE 10080 +#define ecID_RUN_PROPERTIES_RUNTIME_TIMEOUT 10081 +#define ecID_RUN_PROPERTIES_SERIAL 10082 +#define ecID_RUN_PROPERTIES_SERIAL_PORT_ADDR 10083 +#define ecID_RUN_PROPERTIES_SERIAL_PORT_SPEED 10084 +#define ecID_RUN_PROPERTIES_TCPIP 10085 +#define ecID_RUN_PROPERTIES_TCPIP_HOST 10086 +#define ecID_RUN_PROPERTIES_TCPIP_PORT 10087 + +#endif + // _ECOS_SETTINGSDLG_H_ diff --git a/host/tools/configtool/standalone/wxwin/setup/configtool.iss b/host/tools/configtool/standalone/wxwin/setup/configtool.iss new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/setup/configtool.iss @@ -0,0 +1,223 @@ +; Inno Setup Script +; Created with ScriptMaker Version 1.3.22 +; 14 February 2001 at 10:38 + +[Setup] + MinVersion=4.0,4.0 + AppName=eCos Configuration Tool 2.0 + AppId=eCos Configuration Tool + CreateUninstallRegKey=1 + UsePreviousAppDir=1 + UsePreviousGroup=1 + AppVersion=2.0 + AppVerName=eCos Configuration Tool 2.0 + AppCopyright=Copyright © Red Hat Inc., 2001 + BackColor=$FF0000 + BackColor2=$000000 + BackColorDirection=toptobottom + WindowShowCaption=1 + WindowStartMaximized=1 + WindowVisible=1 + WindowResizable=1 + UninstallLogMode=Append + DirExistsWarning=auto + UninstallFilesDir={app} + DisableDirPage=0 + DisableStartupPrompt=0 + CreateAppDir=1 + DisableProgramGroupPage=0 + AlwaysCreateUninstallIcon=1 + Uninstallable=1 + DefaultDirName=c:\Program Files\Red Hat\eCos Configuration Tool + DefaultGroupName=eCos Configuration Tool + LicenseFile=v:\deliver\configtool\license.txt + InfoBeforeFile=v:\deliver\configtool\readme.txt + MessagesFile=compiler:default.isl + SourceDir=v:\deliver\configtool + OutputDir=v:\deliver + +[Dirs] + Name: {app}\. + Name: {app}\manual + Name: {app}\manual\pix + +[Files] + Source: v:\deliver\configtool\about.htm; DestDir: {app}\ + Source: v:\deliver\configtool\aboutlo.htm; DestDir: {app}\ + Source: v:\deliver\configtool\configtool.exe; DestDir: {app}\ + Source: v:\deliver\configtool\ecoslogo.png; DestDir: {app}\ + Source: v:\deliver\configtool\ecoslogosmall.png; DestDir: {app}\ + Source: v:\deliver\configtool\license.txt; DestDir: {app}\ + Source: v:\deliver\configtool\manual\botclear.gif; DestDir: {app}\manual + Source: v:\deliver\configtool\manual\cygnus.css; DestDir: {app}\manual + Source: v:\deliver\configtool\manual\ecos.gif; DestDir: {app}\manual + Source: v:\deliver\configtool\manual\pix\addfromfolder.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\addplatform.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\admin.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\arrow.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\bash.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\botclear.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\build-tools-dialog.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\build-tools2.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\build3D.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\build3D2.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\buildoptions.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\BuildPackages.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\ch-properties-dialog.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\ch_initialscreen.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\comprepos.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\comprepos1.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\comprepos2.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\config-f1.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\configitemlabels.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\configwin.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\Conflicts.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\conflictwin.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\connection.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\CorrectFailingRules2.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\defineproject.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\docs.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\ecos.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\ecosprojselect.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\find-dialog.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\html-help.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\Image22.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\Image23.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\Image24.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\Image25.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\Image26.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\Image27.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\Image28.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\Image29.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\Image30.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\Image31.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\Image32.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\Image33.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\Image34.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\Image35.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\Image36.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\Image37.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\Image38.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\Image39.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\Image40.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\Image41.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\Image42.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\Image43.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\Image44.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\Image45.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\Image46.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\Image47.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\Image47new.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\Image48.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\Image49.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\Image50.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\Image50new.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\Image51.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\Image52.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\Image53.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\Image54.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\Image54new.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\Image55.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\Image56.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\Image57.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\Image58.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\Image59.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\Image60.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\install3D.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\install3D2.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\memorywin.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\memregions.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\memreloc.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\mlt-region-general.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\mlt-section-general.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\mlt-section-relocation.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\mlt-view.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\modifyplatform.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\new-configtool-conflict-options.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\new-configtool-f1.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\new-configtool-run-options.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\open-dialog.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\options.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\packagesdialog.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\properties-dialog.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\properties-dialog2.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\properties-dialog3.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\propwin.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\regprops.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\repo3D.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\repo3D1.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\repos-relocate.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\resolve-conflicts.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\run-tests.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\save-as-dialog.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\targetlist.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\templates.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\ToolsOptions.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\toolsplatforms.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\user-tools-dialog.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\pix\viewmenu.gif; DestDir: {app}\manual/pix + Source: v:\deliver\configtool\manual\user-guides.1.html; DestDir: {app}\manual + Source: v:\deliver\configtool\manual\user-guides.10.html; DestDir: {app}\manual + Source: v:\deliver\configtool\manual\user-guides.11.html; DestDir: {app}\manual + Source: v:\deliver\configtool\manual\user-guides.12.html; DestDir: {app}\manual + Source: v:\deliver\configtool\manual\user-guides.13.html; DestDir: {app}\manual + Source: v:\deliver\configtool\manual\user-guides.14.html; DestDir: {app}\manual + Source: v:\deliver\configtool\manual\user-guides.15.html; DestDir: {app}\manual + Source: v:\deliver\configtool\manual\user-guides.16.html; DestDir: {app}\manual + Source: v:\deliver\configtool\manual\user-guides.17.html; DestDir: {app}\manual + Source: v:\deliver\configtool\manual\user-guides.2.html; DestDir: {app}\manual + Source: v:\deliver\configtool\manual\user-guides.3.html; DestDir: {app}\manual + Source: v:\deliver\configtool\manual\user-guides.4.html; DestDir: {app}\manual + Source: v:\deliver\configtool\manual\user-guides.5.html; DestDir: {app}\manual + Source: v:\deliver\configtool\manual\user-guides.6.html; DestDir: {app}\manual + Source: v:\deliver\configtool\manual\user-guides.7.html; DestDir: {app}\manual + Source: v:\deliver\configtool\manual\user-guides.8.html; DestDir: {app}\manual + Source: v:\deliver\configtool\manual\user-guides.9.html; DestDir: {app}\manual + Source: v:\deliver\configtool\manual\user-guides.a.html; DestDir: {app}\manual + Source: v:\deliver\configtool\manual\user-guides.b.html; DestDir: {app}\manual + Source: v:\deliver\configtool\manual\user-guides.c.html; DestDir: {app}\manual + Source: v:\deliver\configtool\manual\user-guides.d.html; DestDir: {app}\manual + Source: v:\deliver\configtool\manual\user-guides.e.html; DestDir: {app}\manual + Source: v:\deliver\configtool\manual\user-guides.f.html; DestDir: {app}\manual + Source: v:\deliver\configtool\manual\user-guides.html; DestDir: {app}\manual + Source: v:\deliver\configtool\README.txt; DestDir: {app}\ + Source: v:\deliver\configtool\rhlogo.png; DestDir: {app}\ + Source: c:\winnt\system32\tcl82.dll; DestDir: {sys}\; DestName: tcl82.dll; CopyMode: alwaysskipifsameorolder; Flags: uninsneveruninstall + Source: c:\winnt\system32\msvcirt.dll; DestDir: {sys}\; DestName: msvcirt.dll; CopyMode: alwaysskipifsameorolder; Flags: uninsneveruninstall + Source: c:\winnt\system32\msvcp60.dll; DestDir: {sys}\; DestName: msvcp60.dll; CopyMode: alwaysskipifsameorolder; Flags: uninsneveruninstall + Source: c:\winnt\system32\msvcrt.dll; DestDir: {sys}\; DestName: msvcrt.dll; CopyMode: alwaysskipifsameorolder; Flags: uninsneveruninstall + + +[Icons] + Name: {group}\Configuration Tool; Filename: {app}\configtool.exe; WorkingDir: {app}; IconFilename: {app}\configtool.exe; IconIndex: 0 + Name: {group}\ReadMe; Filename: {app}\README.txt; WorkingDir: {app}; IconIndex: 0; Flags: useapppaths + Name: {group}\License; Filename: {app}\license.txt; WorkingDir: {app}; IconIndex: 0; Flags: useapppaths + Name: {group}\Configuration Tool Manual; Filename: {app}\manual\user-guides.4.html; WorkingDir: {app}; IconIndex: 0; Flags: useapppaths + Name: {userdesktop}\eCos Config Tool; Filename: {app}\configtool.exe; WorkingDir: {app}; IconFilename: {app}\configtool.exe; IconIndex: 0 + +[INI] + +[Registry] + +[UninstallDelete] + +[InstallDelete] + +[Run] + +[UninstallRun] + + +; ============================================== +; The lines below are used by ScriptMaker +; They are not required by Inno Setup +; DO NOT DELETE THEM or you may be unable to reload the script + +;[ScriptSetup] +;VerNum=2.0 +;InnoVer=1.3 +;AddVerTo=AppVerName +;SetupFilename=setup.exe +;OutputFolder=v:\setup +;CopyrightText=Copyright © Red Hat Inc., 2001 + diff --git a/host/tools/configtool/standalone/wxwin/setup/ecosplatforms.tar.gz b/host/tools/configtool/standalone/wxwin/setup/ecosplatforms.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..ede9451a012ee7df7b6a36cc368addd0a4dafbb8 GIT binary patch literal 2541 zc$`(0YdDmN8^)cF%`S3i#X1x!Lf9qII4i}Jk}Whz$sn2vwQap5l0nXt!xR-dO*)XJ zd2KNoL=NRxLr#eaGo_jF&ikyr{-6Gz?oao9J=gEL?&sE{DM%hGknBI(>!cHuZ{^g}FHofvSE=QsZMsy9 zZqQJ;a&~^Me{0QE1C+6{n76lk;UTU@)cP3As(Zk4JqjbZ$c|#psfz$4X6j(@j%_6 zN}99J%R+*SH25^^EO4;4FG5NtId5-bT81Ma0jt$mX~;?-(e?JGo1B{!q3-X1aLcq2 zRUo8-q&~{V$~~B6ayZeE=}>7ahuZYxL^nQT)h<}}qpe7((1ImlvjF_^+Z&Wn8=p~f zS3IIBg|EkLujvW=g}13{V2OLC#Dg*ZZpS1D`{=?uR4<^1OMsya<}d8Dg62o0-gX!> zDWyCT+D72SH!`@pf`G9Ag6WH9PS#-6XV7ROfEZbUR+;Joa;BH@Q4_#skU7xx1k<%!8@2Hw5&4<)ePOlThkj{z#~7{vk9Bheu|oUu`DD z3K_kvh{hLi>CJ}mS%7FBtA!byC_4#CUC)PL?Uuw}?AE3N z`Pu3{cx~+;y!%o*S`gxhdnPWRhkLV;&UT)AaslaavIE(y-dZZ?Cn?`)Rf%Uyg9915 zN+C7+-WZX%;5{Z-KnINf!?_XGl2=qoHiigD)II9_PEv?msaiA4Ip6E47=*8e9-7+bAWChbl~kS`bHa33wdB}mWkZqOZft3^7|~vVYc#L@ju2EuS-c#)icaU^#vICqLwFvZq9HQAat6~_;&DW|YK7G0Yw+z-9*&3xb+Q@<{W z2**|y+s88bDiK&yWgLj?*dr05SPMOcU9)l>QCkc-e+mnVf2$kmMKUNz0JTb(WT2scW$mCGE zynUbV=M)wT5{}Fy~l_Xpi=piurE54>w^3Z-PK&h+^krBh;-fl2S zhR4#DxmyoHbL@vzCRZGqne=U~EpJ9GUn-w0>ANI|_@uJaSBLDmNAbbq`}y>Vqz)^g z$$>Y#Ko6hX*!lruc7fZ3MWAO59ob%W;mWMnby2lEc`SI1hBzfBD+*2#uwq&>TGcxU z%ctna_~Fv6M!7$q!dx-Davg5F#(r}J)eAErEEjE|8EKU_`XN5l>81`t)Om*eQ_xHKXqh#omZ_QnuwjeTB0b;06B$eDvYa{E`^++Ql6OSby|!IR6ZW1lCE zOVTD$2U?N8_AHOS2u1cy$jb5#fkm8zS!mW%T82LRtJR5yT~B|Urzcg)n15b6pQ0HA zjHa5AT)A`D&p}}8mjZ?!$Aa)v6gis!*$uCEa2QqA+$lQQJAN~eZnL0j+ondaaNF1d z3ZD?WyySATreFH>KZ}r7RLCh4lj$Hm22G#Srog|9`1>1{k@IWO1*WTiI+8&pD(TLF zwT;FyEGnOf3v`JaQsLxIuPBNR5jx*$%!6Xr{uX3XO|o)x)M=wXBRCdSuDT=i02QZ6 z0aE@uw74{)Dg+uND>$7EO^ZYgd>568BHBH-(n; z$Ah8VYuvx(&!gkgck`g$Xx;PMRNp1N_lR2An4r&d2=9wHdV;bspGo$;Tqa=Lw|`|y zFowMEoW2P(IR1Y_@%Yu}w-!<1p66q_ZZkRQ3SF50zMN0Faydx(K3p0uo^}&Pf0?V^ z`qanipkF-iP2Q|?4D}h4yidMNFr|FK+!&N}fh-TGeoP~Av%lAD+-xg9?NMFv8F-a_ l=i_(g)=2B|HFs9aNF_Mwt0?@xoTi9~jx5e`iFpZ$e*q-IWq1Gp diff --git a/host/tools/configtool/standalone/wxwin/setup/innobott.txt b/host/tools/configtool/standalone/wxwin/setup/innobott.txt new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/setup/innobott.txt @@ -0,0 +1,38 @@ + Source: c:\winnt\system32\tcl82.dll; DestDir: {sys}\; DestName: tcl82.dll; CopyMode: alwaysskipifsameorolder; Flags: uninsneveruninstall + Source: c:\winnt\system32\msvcirt.dll; DestDir: {sys}\; DestName: msvcirt.dll; CopyMode: alwaysskipifsameorolder; Flags: uninsneveruninstall + Source: c:\winnt\system32\msvcp60.dll; DestDir: {sys}\; DestName: msvcp60.dll; CopyMode: alwaysskipifsameorolder; Flags: uninsneveruninstall + Source: c:\winnt\system32\msvcrt.dll; DestDir: {sys}\; DestName: msvcrt.dll; CopyMode: alwaysskipifsameorolder; Flags: uninsneveruninstall + +[Icons] + Name: {group}\Configuration Tool; Filename: {app}\configtool.exe; WorkingDir: {app}; IconFilename: {app}\configtool.exe; IconIndex: 0 + Name: {group}\ReadMe; Filename: {app}\README.txt; WorkingDir: {app}; IconIndex: 0; Flags: useapppaths + Name: {group}\License; Filename: {app}\license.txt; WorkingDir: {app}; IconIndex: 0; Flags: useapppaths + Name: {group}\Configuration Tool Manual; Filename: {app}\manual\user-guides.4.html; WorkingDir: {app}; IconIndex: 0; Flags: useapppaths + Name: {userdesktop}\eCos Config Tool; Filename: {app}\configtool.exe; WorkingDir: {app}; IconFilename: {app}\configtool.exe; IconIndex: 0 + +[INI] + +[Registry] + +[UninstallDelete] + +[InstallDelete] + +[Run] + +[UninstallRun] + + +; ============================================== +; The lines below are used by ScriptMaker +; They are not required by Inno Setup +; DO NOT DELETE THEM or you may be unable to reload the script + +;[ScriptSetup] +;VerNum=%VERSION% +;InnoVer=1.3 +;AddVerTo=AppVerName +;SetupFilename=setup.exe +;OutputFolder=v:\setup +;CopyrightText=Copyright © Red Hat Inc., 2001 + diff --git a/host/tools/configtool/standalone/wxwin/setup/innotop.txt b/host/tools/configtool/standalone/wxwin/setup/innotop.txt new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/setup/innotop.txt @@ -0,0 +1,38 @@ +; Inno Setup Script +; Created with ScriptMaker Version 1.3.22 +; 14 February 2001 at 10:38 + +[Setup] + MinVersion=4.0,4.0 + AppName=eCos Configuration Tool %VERSION% + AppId=eCos Configuration Tool + CreateUninstallRegKey=1 + UsePreviousAppDir=1 + UsePreviousGroup=1 + AppVersion=%VERSION% + AppVerName=eCos Configuration Tool %VERSION% + AppCopyright=Copyright © Red Hat Inc., 2001 + BackColor=$FF0000 + BackColor2=$000000 + BackColorDirection=toptobottom + WindowShowCaption=1 + WindowStartMaximized=1 + WindowVisible=1 + WindowResizable=1 + UninstallLogMode=Append + DirExistsWarning=auto + UninstallFilesDir={app} + DisableDirPage=0 + DisableStartupPrompt=0 + CreateAppDir=1 + DisableProgramGroupPage=0 + AlwaysCreateUninstallIcon=1 + Uninstallable=1 + DefaultDirName=c:\Program Files\Red Hat\eCos Configuration Tool + DefaultGroupName=eCos Configuration Tool + LicenseFile=v:\deliver\configtool\license.txt + InfoBeforeFile=v:\deliver\configtool\readme.txt + MessagesFile=compiler:default.isl + SourceDir=v:\deliver\configtool + OutputDir=v:\deliver + diff --git a/host/tools/configtool/standalone/wxwin/setup/makeinno.sh b/host/tools/configtool/standalone/wxwin/setup/makeinno.sh new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/setup/makeinno.sh @@ -0,0 +1,76 @@ +#! /bin/sh +# Make an Inno Setup distribution list, where files and dirs are represented by +# sections like this: +# [Dirs] +# Name: {app}\backgrounds +# +# [Files] +# Source: C:\program\setup\about.htm; DestDir: {app}\; DestName: about.htm + +ECOSDIR=$1 +CONFIGTOOLDIR=$ECOSDIR/ecc/host/tools/configtool/standalone/wxwin +DESTDIR=/v/deliver +SRCDIR=/v/deliver/configtool + +if [ ! -d "$ECOSDIR" ]; then + echo eCos root directory $ECOSDIR not found. + exit 1 +fi + +if [ ! -d "$SRCDIR" ]; then + echo Source directory $SRCDIR not found. + exit 1 +fi + +if [ ! -d "$DESTDIR" ]; then + echo Destination directory $DESTDIR not found. + exit 1 +fi + +SRCDIR=`cygpath -u $SRCDIR` +DESTDIR=`cygpath -u $DESTDIR` +TEMPDIR=`cygpath -u $TEMP` + +# Generate a list of all files in the distribution. +# We pass the output through sed in order to remove the preceding "./" +cd $SRCDIR +find . -print | sed -e "s/\.\\///g" > $TEMPDIR/files1.tmp + +echo "[Dirs]" > $TEMPDIR/files2.tmp + +for line in `cat $TEMPDIR/files1.tmp` ; do + + # If a directory, add to file + if [ -d $line ] ; then + # The relative path + line2=`cygpath -w $line` + + echo " Name: {app}\\"$line2 >> $TEMPDIR/files2.tmp + fi +done + +echo "" >> $TEMPDIR/files2.tmp +echo "[Files]" >> $TEMPDIR/files2.tmp + +for line in `cat $TEMPDIR/files1.tmp` ; do + + # If not a directory, add to file + if [ ! -d $line ] ; then + # The relative path + line2=`cygpath -w $line` + # The absolute path + line1=`cygpath -w $SRCDIR`"\\"$line2 + pathonly=`find $line -printf "%h"` + + echo " Source: "$line1"; DestDir: {app}\\"$pathonly >> $TEMPDIR/files2.tmp + fi +done + +echo "" >> $TEMPDIR/files2.tmp + +# Concatenate the 3 sections +cat $CONFIGTOOLDIR/setup/innotop.txt $TEMPDIR/files2.tmp $CONFIGTOOLDIR/setup/innobott.txt > $CONFIGTOOLDIR/setup/configtool.iss + +rm -f $TEMPDIR/files1.tmp + + diff --git a/host/tools/configtool/standalone/wxwin/setup/makesetup.sh b/host/tools/configtool/standalone/wxwin/setup/makesetup.sh new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/setup/makesetup.sh @@ -0,0 +1,189 @@ +#!/bin/sh + +# Make a distribution of eCos Configtool, putting results in /v/deliver. +# ECOSDIR=/d/eCos +ECOSDIR=$1 +CONFIGTOOLDIR=$ECOSDIR/ecc/host/tools/configtool/standalone/wxwin +SRC=$CONFIGTOOLDIR +BINARYSRC=/v/ConfigToolWX/ANSIRelease +DEST=/v/deliver +LOCALARCHIVEDIR=//sandpiper/ecc-share/releng/eCosTools/eCosConfigurationTool +INNOCOMPILER="/c/Program Files/Inno Setup 1.3/compil32.exe" +INNO=1 +INNOONLY=0 +UPX=0 +MAKESCRIPT=1 +COPYTOARCHIVE=0 +# If your zip accepts Cygwin-style paths, then +# use cygpath, else substitute echo +CYGPATHPROG=cygpath +#CYGPATHPROG=echo +PROGNAME=$0 + +# Set this to the required version +VERSION=$2 + +findversion() +{ + echo "#include " > /tmp/ctver.c + echo "#include \"symbols.h\"" >> /tmp/ctver.c + echo "int main() { printf(\"%.1f\", ecCONFIGURATION_TOOL_VERSION); }" >> /tmp/ctver.c + gcc /tmp/ctver.c -I$CONFIGTOOLDIR -o /tmp/ctver + VERSION=`/tmp/ctver` + rm -f /tmp/ctver /tmp/ctver.c +} + +doinno() +{ + mkdir -p $DEST/configtool + mkdir -p $DEST/configtool/manual + mkdir -p $DEST/configtool/manual/pix + cd $DEST/configtool + + cp $SRC/about.htm . + cp $SRC/README.txt . + cp $SRC/*.png . + cp "$ECOSDIR/ecc/release/eCos Install/Setup Files/Uncompressed Files/Disk1/license.txt" . + cp $BINARYSRC/configtool.exe . + cp $CONFIGTOOLDIR/manual/*.html $CONFIGTOOLDIR/manual/*.css $CONFIGTOOLDIR/manual/*.gif $DEST/configtool/manual + cp $CONFIGTOOLDIR/manual/pix/*.gif $DEST/configtool/manual/pix + + if [ "$UPX" != "0" ]; then + upx configtool.exe + fi + + # Time to regenerate the Inno Install script, configtool.iss + if [ "$MAKESCRIPT" != "0" ]; then + echo Calling 'makeinno' to generate configtool.iss... + + sh $CONFIGTOOLDIR/setup/makeinno.sh $ECOSDIR + + # Now replace %VERSION% with the real Configtool version + sed -e "s;%VERSION%;$VERSION;g;" < $SRC/setup/configtool.iss > /tmp/configtool.iss + cp /tmp/configtool.iss $SRC/setup/configtool.iss + rm -f /tmp/configtool.iss + fi + + rm -f $DEST/setup.* + + # Now invoke INNO install on the new configtool.iss + echo Invoking INNO... + + "$INNOCOMPILER" /cc `cygpath -w $SRC`\\setup\\configtool.iss + + cd $DEST + mv setup.exe configtool-$VERSION-setup.exe + + if [ "$COPYTOARCHIVE" = "1" ]; then + echo Copying to $LOCALARCHIVEDIR... + if [ ! -d $LOCALARCHIVEDIR/`date +%Y-%m-%e` ]; then + # Can't use -p because Cygwin mkdir fails on network paths + mkdir "$LOCALARCHIVEDIR/`date +%Y-%m-%e`" + exit 1 + fi + + #echo About to: cp configtool-$VERSION-setup.exe "$LOCALARCHIVEDIR/`date +%Y-%m-%e`" + cp configtool-$VERSION-setup.exe "$LOCALARCHIVEDIR/`date +%Y-%m-%e`" + fi +} + +# We can't use e.g. this: +# ls `cat $SRC/distrib/msw/makefile.rsp` zip -@ -u $DEST/wxWindows-$VERSION-gen.zip +# because there's not enough space on the command line, plus we need to ignore the +# blank lines. +# So if we need to (not in this script so far) we do something like this instead: +# expandlines $SRC/setup/files.rsp temp.txt +# zip -@ `$CYGPATHPROG -w $DEST/archive.zip` < temp.txt + +expandlines() +{ + toexpand=$1 + outputfile=$2 + + rm -f $outputfile + touch $outputfile + for line in `cat $toexpand` ; do + if [ $line != "" ]; then + ls $line >> $outputfile + fi + done +} + +usage() +{ + echo Usage: $PROGNAME "eCosDir Version [ options ]" 1>&2 + echo Options: + echo " --help Display this help message" + echo " --upx Compress executable with UPX" + echo " --nomakescript Don't generate the .iss script" + echo " --copytoarchive Copy to where archives are stored locally" +# At present, we remove these options. If later, we build e.g. a zip file +# as an alternative to setup.exe, then we'll reinstate the options. +# For now, always just build the setup.exe. +# echo " --inno Also build setup.exe" +# echo " --innoonly Build setup.exe only" + exit 1 +} + +if [ "$1" = "" ]; then + usage + exit +fi + +# Process command line options. +shift 1 +if [ "$1" != "" ]; then + shift 1 +fi + +for i in "$@"; do + case "$i" in + --inno) INNO=1 ;; + --innoonly) INNOONLY=1 ;; + --upx) UPX=1 ;; + --nomakescript) MAKESCRIPT=0 ;; + --copytoarchive) COPYTOARCHIVE=1 ;; + *) + usage + exit + ;; + esac +done + +if [ ! -d "$SRC" ]; then + mkdir -p $SRC +fi + +if [ ! -d "$DEST" ]; then + mkdir -p $DEST +fi + +if [ ! -d "$SRC" ]; then + echo $SRC not found. + exit 1 +fi + +if [ ! -d "$DEST" ]; then + echo $DEST not found. + exit 1 +fi + +if [ "$VERSION" = "" ] || [ "$VERSION" = "0" ]; then + findversion + echo Found version $VERSION +fi + +echo Creating distribution in $DEST. Options are $@. + +# Remove all existing files +if [ ! -d "$DEST/configtool" ]; then + rm -f -r $DEST/configtool +fi + +# Skip INNO setup if INNO is 0. +if [ "$INNO" = "1" ]; then + doinno +fi + +echo Configtool archived. + diff --git a/host/tools/configtool/standalone/wxwin/setup/maketarball.sh b/host/tools/configtool/standalone/wxwin/setup/maketarball.sh new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/setup/maketarball.sh @@ -0,0 +1,116 @@ +#!/bin/sh + +# Make a distribution of eCos Configtool for Linux +# Julian Smart 2001-04-27 +# Usage: maketarball.sh cvs-dir bin-dir deliver-dir [ options ] +# For example: maketarball.sh ~/local/eCos /tmp/ecos-build-ct /tmp/ct-deliver + +ECOSDIR=$1 +CONFIGTOOLDIR=$ECOSDIR/ecc/host/tools/configtool/standalone/wxwin +SRC=$CONFIGTOOLDIR +BINARYSRC=$2 +DEST=$3 +BUILD=0 +UPX=0 +PROGNAME=$0 + +# Set this to the required version +VERSION=$4 + +dotar() +{ + rm -f -r $DEST/configtool + rm -f $DEST/configtool-*.tgz + + mkdir -p $DEST/configtool + mkdir -p $DEST/configtool/manual + mkdir -p $DEST/configtool/manual/pix + cd $DEST/configtool + + cp $SRC/*.htm . + cp $SRC/*.png . + cp $SRC/setup/ecosplatforms.tar.gz . + cp $SRC/README.txt . + cp "$ECOSDIR/ecc/release/eCos Install/Setup Files/Uncompressed Files/Disk1/license.txt" . + cp $BINARYSRC/configtool . + cp $CONFIGTOOLDIR/manual/*.html $CONFIGTOOLDIR/manual/*.css $CONFIGTOOLDIR/manual/*.gif $DEST/configtool/manual + cp $CONFIGTOOLDIR/manual/pix/*.gif $DEST/configtool/manual/pix + + strip configtool + + if [ "$UPX" != "0" ]; then + upx configtool + fi + + tar cvfz $DEST/configtool-$VERSION.tgz * +} + +dobuild() +{ + makect release full +} + +usage() +{ + echo Usage: $PROGNAME "cvs-dir bin-dir deliver-dir version-number [ options ]" + echo Options: + echo " --help Display this help message" + echo " --upx Compress executable with UPX" + echo " --build Invoke 'makect release full' first" + echo For example: $PROGNAME ~/local/eCos /tmp/ecos-build-ct /tmp/ct-deliver 1.0 + exit 1 +} + +# Process command line options. +shift 4 +for i in "$@"; do + case "$i" in + --build) BUILD=1 ;; + --upx) UPX=1 ;; + *) + usage + exit + ;; + esac +done + +if [ ! -d "$DEST" ]; then + mkdir -p $DEST +fi + +if [ ! -d "$SRC" ]; then + echo CVS source directory $SRC not found. + usage + exit 1 +fi + +if [ ! -d "$BINARYSRC" ]; then + echo Location of configtool binary $BINARYSRC not found. + usage + exit 1 +fi + +if [ "$VERSION" = "" ]; then + echo Pass the version number as the fourth argument. + usage + exit 1 +fi + +echo Creating Version $VERSION distribution in $DEST, using CVS directory $SRC and configtool binary in $BINARYSRC. +#echo Press return to continue. +#read dummy + +# Remove all existing files +if [ ! -d "$DEST/configtool" ]; then + rm -f -r $DEST/configtool +fi + +# Skip INNO setup if INNO is 0. +if [ "$BUILD" = "1" ]; then + dobuild +fi + +dotar + +echo Configtool archived. + diff --git a/host/tools/configtool/standalone/wxwin/shortdescrwin.cpp b/host/tools/configtool/standalone/wxwin/shortdescrwin.cpp new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/shortdescrwin.cpp @@ -0,0 +1,118 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +// shortdescrwin.cpp : +// +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): julians +// Contact(s): julians +// Date: 2000/10/02 +// Version: $Id: shortdescrwin.cpp,v 1.4 2001/05/16 16:08:24 julians Exp $ +// Purpose: +// Description: Implementation file for ecShortDescriptionWindow +// Requires: +// Provides: +// See also: +// Known bugs: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== + +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- +#ifdef __GNUG__ + #pragma implementation "shortdescrwin.h" +#endif + +// Includes other headers for precompiled compilation +#include "ecpch.h" + +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + +#include "configtool.h" +#include "shortdescrwin.h" + +/* + * ecShortDescriptionWindow + */ + +IMPLEMENT_CLASS(ecShortDescriptionWindow, wxTextCtrl) + +BEGIN_EVENT_TABLE(ecShortDescriptionWindow, wxTextCtrl) + EVT_MOUSE_EVENTS(ecShortDescriptionWindow::OnMouseEvent) +END_EVENT_TABLE() + +ecShortDescriptionWindow::ecShortDescriptionWindow(wxWindow* parent, wxWindowID id, const wxPoint& pt, + const wxSize& sz, long style): + wxTextCtrl(parent, id, wxEmptyString, pt, sz, style) +{ +/* +#ifdef __WXGTK__ + SetThemeEnabled(FALSE); +#endif +*/ + + if (!wxGetApp().GetSettings().GetWindowSettings().GetUseDefaults() && + wxGetApp().GetSettings().GetWindowSettings().GetFont(wxT("Short Description")).Ok()) + { + SetFont(wxGetApp().GetSettings().GetWindowSettings().GetFont(wxT("Short Description"))); + } + + m_propertiesMenu = new wxMenu; + + m_propertiesMenu->Append(ecID_WHATS_THIS, _("&What's This?")); + m_propertiesMenu->AppendSeparator(); + m_propertiesMenu->Append(wxID_COPY, _("&Copy")); + + //SetValue(_("This is a short description, to give you helpful remarks about the selected item.")); +} + +ecShortDescriptionWindow::~ecShortDescriptionWindow() +{ + delete m_propertiesMenu; +} + +void ecShortDescriptionWindow::OnMouseEvent(wxMouseEvent& event) +{ + if (event.RightDown()) + { + PopupMenu(GetPropertiesMenu(), event.GetX(), event.GetY()); + } + else + { + event.Skip(); + } +} + diff --git a/host/tools/configtool/standalone/wxwin/shortdescrwin.h b/host/tools/configtool/standalone/wxwin/shortdescrwin.h new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/shortdescrwin.h @@ -0,0 +1,87 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +// shortdescrwin.h : +// +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): julians +// Contact(s): julians +// Date: 2000/10/2 +// Version: $Id: shortdescrwin.h,v 1.1 2001/02/08 18:06:52 julians Exp $ +// Purpose: +// Description: Header file for ecShortDescriptionWindow +// Requires: +// Provides: +// See also: +// Known bugs: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== + +#ifndef _ECOS_SHORTDESCRWIN_H_ +#define _ECOS_SHORTDESCRWIN_H_ + +#ifdef __GNUG__ +#pragma interface "shortdescrwin.h" +#endif + +#include "wx/textctrl.h" + +/* + * ecShortDescriptionWindow + * + * Shows a description of the current option. + */ + +class ecShortDescriptionWindow : public wxTextCtrl +{ +public: +// Ctor(s) + ecShortDescriptionWindow (wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style); + ~ecShortDescriptionWindow (); + +//// Event handlers + + void OnMouseEvent(wxMouseEvent& event); + +//// Operations + +//// Accessors + wxMenu* GetPropertiesMenu() const { return m_propertiesMenu; } + +protected: + wxMenu* m_propertiesMenu; + +private: + DECLARE_EVENT_TABLE() + DECLARE_CLASS(ecShortDescriptionWindow ) +}; + + +#endif + // _ECOS_SHORTDESCRWIN_H_ diff --git a/host/tools/configtool/standalone/wxwin/solutionswin.cpp b/host/tools/configtool/standalone/wxwin/solutionswin.cpp new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/solutionswin.cpp @@ -0,0 +1,159 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +// configtree.cpp : +// +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): julians +// Contact(s): julians +// Date: 2000/09/08 +// Version: $Id: solutionswin.cpp,v 1.1 2001/02/08 18:06:52 julians Exp $ +// Purpose: +// Description: Implementation file for ecSolutionListCtrl +// Requires: +// Provides: +// See also: +// Known bugs: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== + +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- +#ifdef __GNUG__ + #pragma implementation "solutionswin.h" +#endif + +// Includes other headers for precompiled compilation +#include "ecpch.h" + +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + +#include "solutionswin.h" + +#include "bitmaps/checked.xpm" +#include "bitmaps/unchecked.xpm" + +/* + * ecSolutionListCtrl + */ + +IMPLEMENT_CLASS(ecSolutionListCtrl, wxListCtrl) + +BEGIN_EVENT_TABLE(ecSolutionListCtrl, wxListCtrl) + EVT_LEFT_DOWN(ecSolutionListCtrl::OnMouseEvent) +END_EVENT_TABLE() + +ecSolutionListCtrl::ecSolutionListCtrl(wxWindow* parent, wxWindowID id, const wxPoint& pt, + const wxSize& sz, long style): + wxListCtrl(parent, id, pt, sz, style), m_imageList(16, 16, TRUE) + +{ + SetImageList(& m_imageList, wxIMAGE_LIST_SMALL); + + m_imageList.Add(wxICON(unchecked)); + m_imageList.Add(wxICON(checked)); + + InsertColumn(0, _("Item"), wxLIST_FORMAT_LEFT, 200); + InsertColumn(1, _("Value"), wxLIST_FORMAT_LEFT, 80); + +#if 0 + int i = 0; + int j; + + for (j = 0; j < 10; j++) + { + wxListItem info; + info.m_text = _("CYGPKG_HAL_EXCEPTIONS"); + info.m_mask = wxLIST_MASK_TEXT | wxLIST_MASK_IMAGE ; // | wxLIST_MASK_DATA; + info.m_itemId = i; + info.m_image = 0; + //info.m_data = (long) doc; + + long item = InsertItem(info); + + SetItem(i, 1, _("Disabled")); + i ++; + + info.m_text = _("CYGPKG_KERNEL_EXCEPTIONS"); + info.m_mask = wxLIST_MASK_TEXT | wxLIST_MASK_IMAGE ; // | wxLIST_MASK_DATA; + info.m_itemId = i; + info.m_image = 1; + //info.m_data = (long) doc; + item = InsertItem(info); + + SetItem(item, 1, _("Disabled")); + i ++; + } +#endif +} + +void ecSolutionListCtrl::OnMouseEvent(wxMouseEvent& event) +{ + if (event.LeftDown()) + { + int flags; + long item = HitTest(event.GetPosition(), flags); + if (item > -1 && (flags & wxLIST_HITTEST_ONITEMICON)) + { + SetChecked(item, !IsChecked(item)); + } + else + event.Skip(); + } + else + { + event.Skip(); + } +} + +bool ecSolutionListCtrl::IsChecked(long item) const +{ + wxListItem info; + info.m_mask = wxLIST_MASK_IMAGE ; + info.m_itemId = item; + + if (GetItem(info)) + { + return (info.m_image == 1); + } + else + return FALSE; +} + +void ecSolutionListCtrl::SetChecked(long item, bool checked) +{ + SetItemImage(item, (checked ? 1 : 0), -1); +} diff --git a/host/tools/configtool/standalone/wxwin/solutionswin.h b/host/tools/configtool/standalone/wxwin/solutionswin.h new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/solutionswin.h @@ -0,0 +1,79 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +// propertywin.h : +// +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): julians +// Contact(s): julians +// Date: 2000/09/08 +// Version: $Id: solutionswin.h,v 1.1 2001/02/08 18:06:52 julians Exp $ +// Purpose: +// Description: Header file for ecSolutionListCtrl +// Requires: +// Provides: +// See also: +// Known bugs: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== + +#ifndef _ECOS_SOLUTIONSWIN_H_ +#define _ECOS_SOLUTIONSWIN_H_ + +#ifdef __GNUG__ +#pragma interface "solutionswin.h" +#endif + +#include "wx/listctrl.h" + +class ecSolutionListCtrl : public wxListCtrl +{ +public: +// Ctor(s) + ecSolutionListCtrl(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style); + +//// Event handlers + void OnMouseEvent(wxMouseEvent& event); + +//// Operations + +//// Accessors + bool IsChecked(long item) const; + void SetChecked(long item, bool checked) ; + +protected: + wxImageList m_imageList; +private: + DECLARE_EVENT_TABLE() + DECLARE_CLASS(ecSolutionListCtrl) +}; + + +#endif + // _ECOS_SOLUTIONSWIN_H_ diff --git a/host/tools/configtool/standalone/wxwin/splittree.cpp b/host/tools/configtool/standalone/wxwin/splittree.cpp new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/splittree.cpp @@ -0,0 +1,649 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: splittree.cpp +// Purpose: Classes to achieve a remotely-scrolled tree in a splitter +// window that can be scrolled by a scrolled window higher in the +// hierarchy +// Author: Julian Smart +// Modified by: +// Created: 8/7/2000 +// RCS-ID: $Id: splittree.cpp,v 1.5 2001/05/01 17:18:47 julians Exp $ +// Copyright: (c) Julian Smart +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- +#ifdef __GNUG__ +#pragma implementation "splittree.h" +#endif + +// For compilers that support precompilation, includes "wx/wx.h". +#include "ecpch.h" + +#ifdef __WXMSW__ +#include "wx/msw/private.h" +#endif + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#include "wx/generic/treectlg.h" + +#include "splittree.h" +#include + +/* +* wxRemotelyScrolledTreeCtrl +*/ + +#if USE_GENERIC_TREECTRL +IMPLEMENT_CLASS(wxRemotelyScrolledTreeCtrl, wxGenericTreeCtrl) +#else +IMPLEMENT_CLASS(wxRemotelyScrolledTreeCtrl, wxTreeCtrl) +#endif + +#if USE_GENERIC_TREECTRL +BEGIN_EVENT_TABLE(wxRemotelyScrolledTreeCtrl, wxGenericTreeCtrl) +#else +BEGIN_EVENT_TABLE(wxRemotelyScrolledTreeCtrl, wxTreeCtrl) +#endif +EVT_SIZE(wxRemotelyScrolledTreeCtrl::OnSize) +EVT_TREE_ITEM_EXPANDED(-1, wxRemotelyScrolledTreeCtrl::OnExpand) +EVT_TREE_ITEM_COLLAPSED(-1, wxRemotelyScrolledTreeCtrl::OnExpand) +EVT_SCROLLWIN(wxRemotelyScrolledTreeCtrl::OnScroll) +END_EVENT_TABLE() + +wxRemotelyScrolledTreeCtrl::wxRemotelyScrolledTreeCtrl(wxWindow* parent, wxWindowID id, const wxPoint& pt, + const wxSize& sz, long style): +wxTreeCtrl(parent, id, pt, sz, style) +{ + m_companionWindow = NULL; +} + +wxRemotelyScrolledTreeCtrl::~wxRemotelyScrolledTreeCtrl() +{ +} + +void wxRemotelyScrolledTreeCtrl::HideVScrollbar() +{ +#ifdef __WXMSW__ + if (!IsKindOf(CLASSINFO(wxGenericTreeCtrl))) + { + ::ShowScrollBar((HWND) GetHWND(), SB_VERT, FALSE); + } + else +#endif + { + // Implicit in overriding SetScrollbars + } +} + +// Number of pixels per user unit (0 or -1 for no scrollbar) +// Length of virtual canvas in user units +// Length of page in user units +void wxRemotelyScrolledTreeCtrl::SetScrollbars(int pixelsPerUnitX, int pixelsPerUnitY, + int noUnitsX, int noUnitsY, + int xPos, int yPos, + bool noRefresh) +{ + if (IsKindOf(CLASSINFO(wxGenericTreeCtrl))) + { + wxGenericTreeCtrl* win = (wxGenericTreeCtrl*) this; + win->wxGenericTreeCtrl::SetScrollbars(pixelsPerUnitX, 0, noUnitsX, 0, xPos, 0, noRefresh); + + ecScrolledWindow* scrolledWindow = GetScrolledWindow(); + if (scrolledWindow) + { + scrolledWindow->SetScrollbars(0, pixelsPerUnitY, 0, noUnitsY, 0, yPos, noRefresh); + } + } +} + +// In case we're using the generic tree control. +int wxRemotelyScrolledTreeCtrl::GetScrollPos(int orient) const +{ + ecScrolledWindow* scrolledWindow = GetScrolledWindow(); + + if (IsKindOf(CLASSINFO(wxGenericTreeCtrl))) + { + wxGenericTreeCtrl* win = (wxGenericTreeCtrl*) this; + + if (orient == wxHORIZONTAL) + return win->wxGenericTreeCtrl::GetScrollPos(orient); + else + { + return scrolledWindow->GetScrollPos(orient); + } + } + return 0; +} + + +// In case we're using the generic tree control. +// Get the view start +void wxRemotelyScrolledTreeCtrl::GetViewStart(int *x, int *y) const +{ + ecScrolledWindow* scrolledWindow = GetScrolledWindow(); + + if (IsKindOf(CLASSINFO(wxGenericTreeCtrl))) + { + + wxGenericTreeCtrl* win = (wxGenericTreeCtrl*) this; + int x1, y1, x2, y2; + win->wxGenericTreeCtrl::GetViewStart(& x1, & y1); + * x = x1; * y = y1; + if (!scrolledWindow) + return; + + scrolledWindow->GetViewStart(& x2, & y2); + * y = y2; + } + else + { + // x is wrong since the horizontal scrollbar is controlled by the + // tree control, but we probably don't need it. + scrolledWindow->GetViewStart(x, y); + } +} + +// In case we're using the generic tree control. +void wxRemotelyScrolledTreeCtrl::PrepareDC(wxDC& dc) +{ + if (IsKindOf(CLASSINFO(wxGenericTreeCtrl))) + { + ecScrolledWindow* scrolledWindow = GetScrolledWindow(); + + wxGenericTreeCtrl* win = (wxGenericTreeCtrl*) this; + + int startX, startY; + GetViewStart(& startX, & startY); + + int xppu1, yppu1, xppu2, yppu2; + win->wxGenericTreeCtrl::GetScrollPixelsPerUnit(& xppu1, & yppu1); + scrolledWindow->GetScrollPixelsPerUnit(& xppu2, & yppu2); + + dc.SetDeviceOrigin( -startX * xppu1, -startY * yppu2 ); + // dc.SetUserScale( win->GetScaleX(), win->GetScaleY() ); + } +} + +// Scroll to the given line (in scroll units where each unit is +// the height of an item) +void wxRemotelyScrolledTreeCtrl::ScrollToLine(int posHoriz, int posVert) +{ +#ifdef __WXMSW__ + if (!IsKindOf(CLASSINFO(wxGenericTreeCtrl))) + { + UINT sbCode = SB_THUMBPOSITION; + HWND vertScrollBar = 0; + MSWDefWindowProc((WXUINT) WM_VSCROLL, MAKELONG(sbCode, posVert), (WXHWND) vertScrollBar); + } + else +#endif + { + wxGenericTreeCtrl* win = (wxGenericTreeCtrl*) this; + win->Refresh(); + /* Doesn't work yet because scrolling is ignored by Scroll + int xppu, yppu; + wxScrolledWindow* scrolledWindow = GetScrolledWindow(); + if (scrolledWindow) + { + scrolledWindow->GetScrollPixelsPerUnit(& xppu, & yppu); + win->Scroll(-1, posVert*yppu); + } + */ + } +} + +void wxRemotelyScrolledTreeCtrl::OnSize(wxSizeEvent& event) +{ + HideVScrollbar(); + AdjustRemoteScrollbars(); + event.Skip(); +} + +void wxRemotelyScrolledTreeCtrl::OnExpand(wxTreeEvent& event) +{ + AdjustRemoteScrollbars(); + event.Skip(); + + // If we don't have this, we get some bits of lines still remaining + if (event.GetEventType() == wxEVT_COMMAND_TREE_ITEM_COLLAPSED) + Refresh(); + + // Pass on the event + if (m_companionWindow) + m_companionWindow->GetEventHandler()->ProcessEvent(event); +} + +// Adjust the containing wxScrolledWindow's scrollbars appropriately +void wxRemotelyScrolledTreeCtrl::AdjustRemoteScrollbars() +{ + if (IsKindOf(CLASSINFO(wxGenericTreeCtrl))) + { + // This is for the generic tree control. + // It calls SetScrollbars which has been overridden + // to adjust the parent scrolled window vertical + // scrollbar. + ((wxGenericTreeCtrl*) this)->AdjustMyScrollbars(); + return; + } + else + { + // This is for the wxMSW tree control + ecScrolledWindow* scrolledWindow = GetScrolledWindow(); + if (scrolledWindow) + { + wxRect itemRect; + if (GetBoundingRect(GetRootItem(), itemRect)) + { + // Actually, the real height seems to be 1 less than reported + // (e.g. 16 instead of 16) + int itemHeight = itemRect.GetHeight() - 1; + + int w, h; + GetClientSize(&w, &h); + + wxRect rect(0, 0, 0, 0); + CalcTreeSize(rect); + + double f = ((double) (rect.GetHeight()) / (double) itemHeight) ; + int treeViewHeight = (int) ceil(f); + + int scrollPixelsPerLine = itemHeight; + int scrollPos = - (itemRect.y / itemHeight); + + scrolledWindow->SetScrollbars(0, scrollPixelsPerLine, 0, treeViewHeight, 0, scrollPos); + + // Ensure that when a scrollbar becomes hidden or visible, + // the contained window sizes are right. + // Problem: this is called too early (?) + wxSizeEvent event(scrolledWindow->GetSize(), scrolledWindow->GetId()); + scrolledWindow->GetEventHandler()->ProcessEvent(event); + } + } + } +} + + +// Calculate the area that contains both rectangles +static wxRect CombineRectangles(const wxRect& rect1, const wxRect& rect2) +{ + wxRect rect; + + int right1 = rect1.GetRight(); + int bottom1 = rect1.GetBottom(); + int right2 = rect2.GetRight(); + int bottom2 = rect2.GetBottom(); + + wxPoint topLeft = wxPoint(wxMin(rect1.x, rect2.x), wxMin(rect1.y, rect2.y)); + wxPoint bottomRight = wxPoint(wxMax(right1, right2), wxMax(bottom1, bottom2)); + + rect.x = topLeft.x; rect.y = topLeft.y; + rect.SetRight(bottomRight.x); + rect.SetBottom(bottomRight.y); + + return rect; +} + + +// Calculate the tree overall size so we can set the scrollbar +// correctly + +// static int g_count = 0; + +void wxRemotelyScrolledTreeCtrl::CalcTreeSize(wxRect& rect) +{ + // g_count = 0; + CalcTreeSize(GetRootItem(), rect); +} + +void wxRemotelyScrolledTreeCtrl::CalcTreeSize(const wxTreeItemId& id, wxRect& rect) +{ + // More efficient implementation would be to find the last item (but how?) + // Q: is the bounding rect relative to the top of the virtual tree workspace + // or the top of the window? How would we convert? + wxRect itemSize; + if (GetBoundingRect(id, itemSize)) + { + rect = CombineRectangles(rect, itemSize); +#if 0 + wxString msg; + wxString name = GetItemText(id); + msg.Printf("Item rect for %s (%d) is %dx%d, %dx%d", (const wxChar*) name, g_count, itemSize.x, itemSize.y, itemSize.width, itemSize.height); + wxLogDebug(msg); + g_count ++; +#endif + } + else + { + //wxLogDebug("Couldn't get size."); + } + + long cookie; + wxTreeItemId childId = GetFirstChild(id, cookie); + while (childId != 0) + { + CalcTreeSize(childId, rect); + childId = GetNextChild(childId, cookie); + } +} + +// Find the scrolled window that contains this control +ecScrolledWindow* wxRemotelyScrolledTreeCtrl::GetScrolledWindow() const +{ + wxWindow* parent = wxWindow::GetParent(); + while (parent) + { + if (parent->IsKindOf(CLASSINFO(ecScrolledWindow))) + return (ecScrolledWindow*) parent; + parent = parent->GetParent(); + } + return NULL; +} + +void wxRemotelyScrolledTreeCtrl::OnScroll(wxScrollWinEvent& event) +{ + int orient = event.GetOrientation(); + if (orient == wxHORIZONTAL) + { + event.Skip(); + return; + } + ecScrolledWindow* scrollWin = GetScrolledWindow(); + if (!scrollWin) + return; + + int x, y; + scrollWin->GetViewStart(& x, & y); + + ScrollToLine(-1, y); +} + +/* +* wxTreeCompanionWindow +* +* A window displaying values associated with tree control items. +*/ + +IMPLEMENT_CLASS(wxTreeCompanionWindow, wxWindow) + +BEGIN_EVENT_TABLE(wxTreeCompanionWindow, wxWindow) +EVT_PAINT(wxTreeCompanionWindow::OnPaint) +EVT_SCROLLWIN(wxTreeCompanionWindow::OnScroll) +EVT_TREE_ITEM_EXPANDED(-1, wxTreeCompanionWindow::OnExpand) +EVT_TREE_ITEM_COLLAPSED(-1, wxTreeCompanionWindow::OnExpand) +END_EVENT_TABLE() + +wxTreeCompanionWindow::wxTreeCompanionWindow(wxWindow* parent, wxWindowID id, + const wxPoint& pos, + const wxSize& sz, + long style): +wxWindow(parent, id, pos, sz, style) +{ + m_treeCtrl = NULL; +} + +void wxTreeCompanionWindow::DrawItem(wxDC& dc, wxTreeItemId id, const wxRect& rect) +{ + if (m_treeCtrl) + { + wxString text = m_treeCtrl->GetItemText(id); + dc.SetTextForeground(* wxBLACK); + dc.SetBackgroundMode(wxTRANSPARENT); + + int textW, textH; + dc.GetTextExtent(text, & textW, & textH); + + int x = 5; + int y = rect.GetY() + wxMax(0, (rect.GetHeight() - textH) / 2); + + dc.DrawText(text, x, y); + } +} + +void wxTreeCompanionWindow::OnPaint(wxPaintEvent& event) +{ + wxPaintDC dc(this); + + if (!m_treeCtrl) + return; + + wxPen pen(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DLIGHT), 1, wxSOLID); + dc.SetPen(pen); + dc.SetBrush(* wxTRANSPARENT_BRUSH); + wxFont font(wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT)); + dc.SetFont(font); + + wxSize clientSize = GetClientSize(); + wxRect itemRect; + int cy=0; + wxTreeItemId h, lastH; + for(h=m_treeCtrl->GetFirstVisibleItem();h;h=m_treeCtrl->GetNextVisible(h)) + { + if (m_treeCtrl->GetBoundingRect(h, itemRect)) + { + cy = itemRect.GetTop(); + wxRect drawItemRect(0, cy, clientSize.x, itemRect.GetHeight()); + + lastH = h; + + // Draw the actual item + DrawItem(dc, h, drawItemRect); + dc.DrawLine(0, cy, clientSize.x, cy); + } + } + if (m_treeCtrl->GetBoundingRect(lastH, itemRect)) + { + cy = itemRect.GetBottom(); + dc.DrawLine(0, cy, clientSize.x, cy); + } +} + +void wxTreeCompanionWindow::OnScroll(wxScrollWinEvent& event) +{ + int orient = event.GetOrientation(); + if (orient == wxHORIZONTAL) + { + event.Skip(); + return; + } + if (!m_treeCtrl) + return; + + // TODO: scroll the window physically instead of just refreshing. + Refresh(TRUE); +} + +void wxTreeCompanionWindow::OnExpand(wxTreeEvent& event) +{ + // TODO: something more optimized than simply refresh the whole + // window when the tree is expanded/collapsed. Tricky. + Refresh(); +} + +/* +* wxThinSplitterWindow +*/ + +IMPLEMENT_CLASS(wxThinSplitterWindow, wxSplitterWindow) + +BEGIN_EVENT_TABLE(wxThinSplitterWindow, wxSplitterWindow) +EVT_SIZE(wxThinSplitterWindow::OnSize) +END_EVENT_TABLE() + +wxThinSplitterWindow::wxThinSplitterWindow(wxWindow* parent, wxWindowID id, + const wxPoint& pos, + const wxSize& sz, + long style): +wxSplitterWindow(parent, id, pos, sz, style) +{ +} + +void wxThinSplitterWindow::SizeWindows() +{ + // The client size may have changed inbetween + // the sizing of the first window and the sizing of + // the second. So repeat SizeWindows. + wxSplitterWindow::SizeWindows(); + wxSplitterWindow::SizeWindows(); +} + +// Tests for x, y over sash +bool wxThinSplitterWindow::SashHitTest(int x, int y, int tolerance) +{ + return wxSplitterWindow::SashHitTest(x, y, 4); +} + +void wxThinSplitterWindow::DrawSash(wxDC& dc) +{ + if ( m_sashPosition == 0 || !m_windowTwo) + return; + if (GetWindowStyle() & wxSP_NOSASH) + return; + + int w, h; + GetClientSize(&w, &h); + + if ( m_splitMode == wxSPLIT_VERTICAL ) + { + dc.SetPen(* m_facePen); + dc.SetBrush(* m_faceBrush); + int h1 = h-1; + int y1 = 0; + if ( (GetWindowStyleFlag() & wxSP_BORDER) != wxSP_BORDER && (GetWindowStyleFlag() & wxSP_3DBORDER) != wxSP_3DBORDER ) + h1 += 1; // Not sure why this is necessary... + if ( (GetWindowStyleFlag() & wxSP_3DBORDER) == wxSP_3DBORDER) + { + y1 = 2; h1 -= 3; + } + dc.DrawRectangle(m_sashPosition, y1, m_sashSize, h1); + } + else + { + dc.SetPen(* m_facePen); + dc.SetBrush(* m_faceBrush); + int w1 = w-1; + int x1 = 0; + if ( (GetWindowStyleFlag() & wxSP_BORDER) != wxSP_BORDER && (GetWindowStyleFlag() & wxSP_3DBORDER) != wxSP_3DBORDER ) + w1 ++; + if ( (GetWindowStyleFlag() & wxSP_3DBORDER) == wxSP_3DBORDER) + { + x1 = 2; w1 -= 3; + } + dc.DrawRectangle(x1, m_sashPosition, w1, m_sashSize); + } + + dc.SetPen(wxNullPen); + dc.SetBrush(wxNullBrush); +} + +void wxThinSplitterWindow::OnSize(wxSizeEvent& event) +{ + wxSplitterWindow::OnSize(event); +} + +/* +* wxSplitterScrolledWindow +*/ + +IMPLEMENT_CLASS(wxSplitterScrolledWindow, ecScrolledWindow) + +BEGIN_EVENT_TABLE(wxSplitterScrolledWindow, ecScrolledWindow) +EVT_SCROLLWIN(wxSplitterScrolledWindow::OnScroll) +EVT_SIZE(wxSplitterScrolledWindow::OnSize) +END_EVENT_TABLE() + +wxSplitterScrolledWindow::wxSplitterScrolledWindow(wxWindow* parent, wxWindowID id, + const wxPoint& pos, + const wxSize& sz, + long style): + ecScrolledWindow(parent, id, pos, sz, style) +{ +} + +void wxSplitterScrolledWindow::OnSize(wxSizeEvent& event) +{ + wxSize sz = GetClientSize(); + if (GetChildren().First()) + { + ((wxWindow*) GetChildren().First()->Data())->SetSize(0, 0, sz.x, sz.y); + } +} + +void wxSplitterScrolledWindow::OnScroll(wxScrollWinEvent& event) +{ + // Ensure that events being propagated back up the window hierarchy + // don't cause an infinite loop + static bool inOnScroll = FALSE; + if (inOnScroll) + { + event.Skip(); + return; + } + inOnScroll = TRUE; + + int orient = event.GetOrientation(); + + int nScrollInc = CalcScrollInc(event); + if (nScrollInc == 0) + { + inOnScroll = FALSE; + return; + } + + if (orient == wxHORIZONTAL) + { + inOnScroll = FALSE; + event.Skip(); + return; +#if 0 + int newPos = m_xScrollPosition + nScrollInc; + SetScrollPos(wxHORIZONTAL, newPos, TRUE ); +#endif + } + else + { + int newPos = m_yScrollPosition + nScrollInc; + SetScrollPos(wxVERTICAL, newPos, TRUE ); + } + + if (orient == wxHORIZONTAL) + { + m_xScrollPosition += nScrollInc; + } + else + { + m_yScrollPosition += nScrollInc; + } + + // Find targets in splitter window and send the event to them + wxNode* node = GetChildren().First(); + while (node) + { + wxWindow* child = (wxWindow*) node->Data(); + if (child->IsKindOf(CLASSINFO(wxSplitterWindow))) + { + wxSplitterWindow* splitter = (wxSplitterWindow*) child; + if (splitter->GetWindow1()) + splitter->GetWindow1()->ProcessEvent(event); + if (splitter->GetWindow2()) + splitter->GetWindow2()->ProcessEvent(event); + break; + } + node = node->Next(); + } + +#ifdef __WXMAC__ + m_targetWindow->MacUpdateImmediately() ; +#endif + + inOnScroll = FALSE; +} + diff --git a/host/tools/configtool/standalone/wxwin/splittree.h b/host/tools/configtool/standalone/wxwin/splittree.h new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/splittree.h @@ -0,0 +1,227 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: splittree.h +// Purpose: Classes to achieve a remotely-scrolled tree in a splitter +// window that can be scrolled by a scrolled window higher in the +// hierarchy +// Author: Julian Smart +// Modified by: +// Created: 8/7/2000 +// RCS-ID: $Id: splittree.h,v 1.2 2001/05/01 17:18:47 julians Exp $ +// Copyright: (c) Julian Smart +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_SPLITTREE_H_ +#define _WX_SPLITTREE_H_ + +#ifdef __GNUG__ + #pragma interface "splittree.cpp" +#endif + +// Set this to 1 to use generic tree control (doesn't yet work properly) +#define USE_GENERIC_TREECTRL 0 + +#include "wx/wx.h" +#include "wx/treectrl.h" +#include "wx/splitter.h" +#include "ecscrolwin.h" + +#if USE_GENERIC_TREECTRL +#include "wx/generic/treectlg.h" +#ifndef wxTreeCtrl +#define wxTreeCtrl wxGenericTreeCtrl +#define sm_classwxTreeCtrl sm_classwxGenericTreeCtrl +#endif +#endif + +class wxRemotelyScrolledTreeCtrl; +class wxThinSplitterWindow; +class wxSplitterScrolledWindow; + +/* + * wxRemotelyScrolledTreeCtrl + * + * This tree control disables its vertical scrollbar and catches scroll + * events passed by a scrolled window higher in the hierarchy. + * It also updates the scrolled window vertical scrollbar as appropriate. + */ + +class wxRemotelyScrolledTreeCtrl: public wxTreeCtrl +{ + DECLARE_CLASS(wxRemotelyScrolledTreeCtrl) +public: + wxRemotelyScrolledTreeCtrl(wxWindow* parent, wxWindowID id, const wxPoint& pt = wxDefaultPosition, + const wxSize& sz = wxDefaultSize, long style = wxTR_HAS_BUTTONS); + ~wxRemotelyScrolledTreeCtrl(); + +//// Events + void OnSize(wxSizeEvent& event); + void OnExpand(wxTreeEvent& event); + void OnScroll(wxScrollWinEvent& event); + +//// Overrides + // Override this in case we're using the generic tree control. + // Calls to this should disable the vertical scrollbar. + + // Number of pixels per user unit (0 or -1 for no scrollbar) + // Length of virtual canvas in user units + // Length of page in user units + virtual void SetScrollbars(int pixelsPerUnitX, int pixelsPerUnitY, + int noUnitsX, int noUnitsY, + int xPos = 0, int yPos = 0, + bool noRefresh = FALSE ); + + // In case we're using the generic tree control. + // Get the view start + virtual void GetViewStart(int *x, int *y) const; + + // In case we're using the generic tree control. + virtual void PrepareDC(wxDC& dc); + + // In case we're using the generic tree control. + virtual int GetScrollPos(int orient) const; + +//// Helpers + void HideVScrollbar(); + + // Calculate the tree overall size so we can set the scrollbar + // correctly + void CalcTreeSize(wxRect& rect); + void CalcTreeSize(const wxTreeItemId& id, wxRect& rect); + + // Adjust the containing wxScrolledWindow's scrollbars appropriately + void AdjustRemoteScrollbars(); + + // Find the scrolled window that contains this control + ecScrolledWindow* GetScrolledWindow() const; + + // Scroll to the given line (in scroll units where each unit is + // the height of an item) + void ScrollToLine(int posHoriz, int posVert); + +//// Accessors + + // The companion window is one which will get notified when certain + // events happen such as node expansion + void SetCompanionWindow(wxWindow* companion) { m_companionWindow = companion; } + wxWindow* GetCompanionWindow() const { return m_companionWindow; } + + + DECLARE_EVENT_TABLE() +protected: + wxWindow* m_companionWindow; +}; + +/* + * wxTreeCompanionWindow + * + * A window displaying values associated with tree control items. + */ + +class wxTreeCompanionWindow: public wxWindow +{ +public: + DECLARE_CLASS(wxTreeCompanionWindow) + + wxTreeCompanionWindow(wxWindow* parent, wxWindowID id = -1, + const wxPoint& pos = wxDefaultPosition, + const wxSize& sz = wxDefaultSize, + long style = 0); + +//// Overrides + virtual void DrawItem(wxDC& dc, wxTreeItemId id, const wxRect& rect); + +//// Events + void OnPaint(wxPaintEvent& event); + void OnScroll(wxScrollWinEvent& event); + void OnExpand(wxTreeEvent& event); + +//// Operations + +//// Accessors + wxRemotelyScrolledTreeCtrl* GetTreeCtrl() const { return m_treeCtrl; }; + void SetTreeCtrl(wxRemotelyScrolledTreeCtrl* treeCtrl) { m_treeCtrl = treeCtrl; } + +//// Data members +protected: + wxRemotelyScrolledTreeCtrl* m_treeCtrl; + + DECLARE_EVENT_TABLE() +}; + + +/* + * wxThinSplitterWindow + * + * Implements a splitter with a less obvious sash + * than the usual one. + */ + +class wxThinSplitterWindow: public wxSplitterWindow +{ +public: + DECLARE_DYNAMIC_CLASS(wxThinSplitterWindow) + + wxThinSplitterWindow(wxWindow* parent, wxWindowID id = -1, + const wxPoint& pos = wxDefaultPosition, + const wxSize& sz = wxDefaultSize, + long style = wxSP_3D | wxCLIP_CHILDREN); + +//// Overrides + + void SizeWindows(); + // Tests for x, y over sash. Overriding this allows us to increase + // the tolerance. + bool SashHitTest(int x, int y, int tolerance = 2); + void DrawSash(wxDC& dc); + +//// Events + + void OnSize(wxSizeEvent& event); + +//// Operations + +//// Accessors + +//// Data members +protected: + DECLARE_EVENT_TABLE() +}; + +/* + * wxSplitterScrolledWindow + * + * This scrolled window is aware of the fact that one of its + * children is a splitter window. It passes on its scroll events + * (after some processing) to both splitter children for them + * scroll appropriately. + */ + +class wxSplitterScrolledWindow: public ecScrolledWindow +{ +public: + DECLARE_DYNAMIC_CLASS(wxSplitterScrolledWindow) + + wxSplitterScrolledWindow(wxWindow* parent, wxWindowID id = -1, + const wxPoint& pos = wxDefaultPosition, + const wxSize& sz = wxDefaultSize, + long style = 0); + +//// Overrides + +//// Events + + void OnScroll(wxScrollWinEvent& event); + void OnSize(wxSizeEvent& event); + +//// Operations + +//// Accessors + +//// Data members +public: + DECLARE_EVENT_TABLE() +}; + +#endif + // _SPLITTREE_H_ diff --git a/host/tools/configtool/standalone/wxwin/symbols.h b/host/tools/configtool/standalone/wxwin/symbols.h new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/symbols.h @@ -0,0 +1,47 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +// symbols.h : +// +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): julians +// Contact(s): julians +// Date: 2001/05/14 +// Version: $Id: symbols.h,v 1.2 2001/05/16 10:24:00 julians Exp $ +// Purpose: +// Description: Some important symbols, such as the version +// Requires: +// Provides: +// See also: +// Known bugs: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== + +#define ecCONFIGURATION_TOOL_VERSION 2.0 +#define ecCONFIGURATION_TOOL_VERSION_STRING "2.0" diff --git a/host/tools/configtool/standalone/wxwin/templatesdlg.cpp b/host/tools/configtool/standalone/wxwin/templatesdlg.cpp new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/templatesdlg.cpp @@ -0,0 +1,432 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +// templatesdlg.cpp : +// +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): julians +// Contact(s): julians +// Date: 2000/09/27 +// Version: $Id: templatesdlg.cpp,v 1.5 2001/03/23 13:38:04 julians Exp $ +// Purpose: +// Description: Implementation file for ecTemplatesDialog +// Requires: +// Provides: +// See also: +// Known bugs: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== + +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- +#ifdef __GNUG__ +#pragma implementation "templatesdlg.h" +#endif + +// Includes other headers for precompiled compilation +#include "ecpch.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#include "wx/cshelp.h" +#include "wx/valgen.h" + +#include "configtool.h" +#include "configtooldoc.h" +#include "templatesdlg.h" +#include "ecutils.h" + +BEGIN_EVENT_TABLE(ecTemplatesDialog, ecDialog) + EVT_BUTTON(wxID_OK, ecTemplatesDialog::OnOK) + EVT_BUTTON(wxID_CANCEL, ecTemplatesDialog::OnCancel) + EVT_COMBOBOX(ecID_TEMPLATES_DIALOG_HARDWARE_TEMPLATES, ecTemplatesDialog::OnSelHardwareTemplates) + EVT_CHOICE(ecID_TEMPLATES_DIALOG_PACKAGE_TEMPLATES, ecTemplatesDialog::OnSelPackageTemplates) + EVT_CHOICE(ecID_TEMPLATES_DIALOG_VERSION, ecTemplatesDialog::OnSelPackageVersion) + EVT_BUTTON(ecID_TEMPLATES_DIALOG_DETAILS, ecTemplatesDialog::OnDetails) +END_EVENT_TABLE() + +// ---------------------------------------------------------------------------- +// main frame +// ---------------------------------------------------------------------------- + +// Frame constructor +ecTemplatesDialog::ecTemplatesDialog(wxWindow* parent) +{ + SetExtraStyle(wxDIALOG_EX_CONTEXTHELP); + + ecDialog::Create(parent, ecID_TEMPLATES_DIALOG, _("Templates"), + wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER); + + CreateControls(this); + + Centre(wxBOTH); +} + +ecTemplatesDialog::~ecTemplatesDialog() +{ +} + +void ecTemplatesDialog::CreateControls(wxWindow* parent) +{ + wxSizer *item0 = new wxBoxSizer( wxVERTICAL ); + + wxStaticBox *item2 = new wxStaticBox( parent, -1, _("Hardware") ); + wxSizer *item1 = new wxStaticBoxSizer( item2, wxVERTICAL ); + + wxString *strs3 = (wxString*) NULL; + wxComboBox *item3 = new wxComboBox( parent, ecID_TEMPLATES_DIALOG_HARDWARE_TEMPLATES, "", wxDefaultPosition, wxSize(360,-1), 0, strs3, wxCB_DROPDOWN|wxCB_READONLY ); + item1->Add( item3, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + wxTextCtrl *item4 = new wxTextCtrl( parent, ecID_TEMPLATES_DIALOG_HARDWARE_DESCRIPTION, _(""), wxDefaultPosition, wxSize(90,60), wxTE_MULTILINE|wxTE_READONLY ); + item1->Add( item4, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + item0->Add( item1, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + wxSizer *item5 = new wxBoxSizer( wxHORIZONTAL ); + + wxStaticBox *item7 = new wxStaticBox( parent, -1, _("Packages") ); + wxSizer *item6 = new wxStaticBoxSizer( item7, wxVERTICAL ); + + wxSizer *item8 = new wxBoxSizer( wxHORIZONTAL ); + + wxString *strs9 = (wxString*) NULL; + wxChoice *item9 = new wxChoice( parent, ecID_TEMPLATES_DIALOG_PACKAGE_TEMPLATES, wxDefaultPosition, wxSize(100,-1), 0, strs9, 0 ); + item8->Add( item9, 20, wxALIGN_CENTRE|wxALL, 5 ); + + wxString *strs10 = (wxString*) NULL; + wxChoice *item10 = new wxChoice( parent, ecID_TEMPLATES_DIALOG_VERSION, wxDefaultPosition, wxSize(90,-1), 0, strs10, 0 ); + item8->Add( item10, 0, wxALIGN_CENTRE|wxALL, 5 ); + + item6->Add( item8, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 0 ); + + wxTextCtrl *item11 = new wxTextCtrl( parent, ecID_TEMPLATES_DIALOG_PACKAGE_DESCRIPTION, _(""), wxDefaultPosition, wxSize(110,70), wxTE_MULTILINE|wxTE_READONLY ); + item6->Add( item11, 1, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + item5->Add( item6, 1, wxALIGN_CENTRE|wxLEFT|wxRIGHT|wxBOTTOM, 5 ); + + wxSizer *item12 = new wxBoxSizer( wxVERTICAL ); + + wxButton *item13 = new wxButton( parent, wxID_OK, _("&OK"), wxDefaultPosition, wxDefaultSize, 0 ); + item12->Add( item13, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + wxButton *item14 = new wxButton( parent, wxID_CANCEL, _("&Cancel"), wxDefaultPosition, wxDefaultSize, 0 ); + item12->Add( item14, 0, wxALIGN_CENTRE|wxALL, 5 ); + + item12->Add( 10, 10, 0, wxALIGN_CENTRE|wxALL, 0 ); + + wxButton *item15 = new wxButton( parent, ecID_TEMPLATES_DIALOG_DETAILS, _("&Details >>"), wxDefaultPosition, wxDefaultSize, 0 ); + item12->Add( item15, 0, wxALIGN_CENTRE|wxALL, 5 ); + + item5->Add( item12, 0, wxALIGN_CENTRE|wxALL, 5 ); + + item0->Add( item5, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 0 ); + + wxStaticText *item16 = new wxStaticText( parent, ecID_TEMPLATES_DIALOG_PACKAGES_MSG, _("&Packages in selected template:"), wxDefaultPosition, wxDefaultSize, 0 ); + + wxTextCtrl *item17 = new wxTextCtrl( parent, ecID_TEMPLATES_DIALOG_PACKAGES, _(""), wxDefaultPosition, wxSize(90,100), wxTE_MULTILINE|wxTE_READONLY ); + + // Don't add these yet (until press Details) + //item0->Add( item16, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + //item0->Add( item17, 1, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + item16->Show(FALSE); + item17->Show(FALSE); + +#ifdef __WXGTK__ + wxButton *contextButton = new wxContextHelpButton( parent ); + item12->Add( contextButton, 0, wxALIGN_CENTRE|wxALL, 5 ); +#endif + + parent->SetAutoLayout( TRUE ); + parent->SetSizer( item0 ); + parent->Layout(); + item0->Fit( parent ); + //item0->SetSizeHints( parent ); + + // Add context-sensitive help text + parent->FindWindow( ecID_TEMPLATES_DIALOG_HARDWARE_TEMPLATES )->SetHelpText(_("Selects from the set of available hardware templates.")); + parent->FindWindow( ecID_TEMPLATES_DIALOG_HARDWARE_DESCRIPTION )->SetHelpText(_("Gives a brief description of the currently selected hardware template.")); + parent->FindWindow( ecID_TEMPLATES_DIALOG_PACKAGE_TEMPLATES )->SetHelpText(_("Selects from the set of available package templates.")); + parent->FindWindow( ecID_TEMPLATES_DIALOG_VERSION )->SetHelpText(_("Selects the version of the currently selected template.")); + parent->FindWindow( ecID_TEMPLATES_DIALOG_PACKAGE_DESCRIPTION )->SetHelpText(_("Gives a brief description of the currently selected package template.")); + parent->FindWindow( ecID_TEMPLATES_DIALOG_PACKAGES )->SetHelpText(_("Lists the packages contained in the currently selected template.")); + parent->FindWindow( wxID_OK )->SetHelpText(_("Closes the dialog and saves any changes you have made.")); + parent->FindWindow( wxID_CANCEL )->SetHelpText(_("Closes the dialog without saving any changes you have made.")); + parent->FindWindow( ecID_TEMPLATES_DIALOG_DETAILS )->SetHelpText(_("Shows or hides a portion of the dialog that provides details of the contents of the currently selected template.")); + +#if __WXGTK__ + parent->FindWindow( wxID_CONTEXT_HELP )->SetHelpText(_("Invokes context-sensitive help for the clicked-on window.")); +#endif + + // Add validators + parent->FindWindow( ecID_TEMPLATES_DIALOG_PACKAGE_DESCRIPTION )->SetValidator(wxGenericValidator(& m_strCdlTemplateDescription)); + parent->FindWindow( ecID_TEMPLATES_DIALOG_HARDWARE_DESCRIPTION )->SetValidator(wxGenericValidator(& m_strCdlHardwareDescription)); + parent->FindWindow( ecID_TEMPLATES_DIALOG_PACKAGES)->SetValidator(wxGenericValidator(& m_strCdlTemplatePackages)); + + PopulateControls(); +} + +void ecTemplatesDialog::PopulateControls() +{ + ecConfigToolDoc* doc = wxGetApp().GetConfigToolDoc(); + + m_hardware = doc->GetCdlConfig ()->get_hardware ().c_str(); + + wxComboBox* cdlHardwareCtrl = (wxComboBox*) FindWindow( ecID_TEMPLATES_DIALOG_HARDWARE_TEMPLATES ) ; + wxChoice* cdlPackageCtrl = (wxChoice*) FindWindow( ecID_TEMPLATES_DIALOG_PACKAGE_TEMPLATES ) ; + + + const std::vector & targets = doc->GetCdlPkgData ()->get_targets (); + std::vector::const_iterator target_i; + + // populate the hardware combo box + int nIndex = 0; + for (target_i = targets.begin (); target_i != targets.end (); target_i++) + { + const std::vector & aliases = doc->GetCdlPkgData ()->get_target_aliases (* target_i); + + // use the first alias (if any) as the description + wxString strTargetDescription = aliases.size () ? aliases [0].c_str () : target_i->c_str (); + cdlHardwareCtrl->Append(strTargetDescription, (void*) target_i); // store the target iterator + std::string str(* (target_i)); + if (m_hardware == str.c_str()) // if current target... + cdlHardwareCtrl->SetSelection (nIndex); // ...select the string + nIndex ++; + } + + if (-1 == cdlHardwareCtrl->GetSelection ()) // if no target selected... + cdlHardwareCtrl->SetSelection (0); // ...select the first one + + // populate the template combo box + m_template = doc->GetCdlConfig ()->get_template ().c_str(); + const std::vector & templates = doc->GetCdlPkgData ()->get_templates (); + std::vector::const_iterator template_i; + nIndex = 0; + for (template_i = templates.begin (); template_i != templates.end (); template_i++) + { + wxString strTemplateDescription = template_i->c_str (); + cdlPackageCtrl->Append(strTemplateDescription, (void*) template_i); // store the template iterator + /// m_cboCdlTemplate.SetItemData (nIndex, (DWORD) template_i); // store the template iterator + std::string str(* (template_i)); + if (m_template == str.c_str()) // if current template... + cdlPackageCtrl->SetSelection(nIndex); // ...select the string + nIndex ++; + } + + if (-1 == cdlPackageCtrl->GetSelection()) // if no template selected... + cdlPackageCtrl->SetSelection(0); // ...select the first one + + // display initial target and template descriptions + wxCommandEvent dummyEvent; + OnSelHardwareTemplates(dummyEvent); + OnSelPackageTemplates(dummyEvent); + + // populate the template version combo box + UpdateVersionList (doc->GetTemplateVersion ()); +} + +void ecTemplatesDialog::OnCancel(wxCommandEvent& event) +{ + event.Skip(); +} + +void ecTemplatesDialog::OnOK(wxCommandEvent& event) +{ + event.Skip(); +} + +void ecTemplatesDialog::OnDetails(wxCommandEvent& event) +{ + wxWindow* win1 = FindWindow(ecID_TEMPLATES_DIALOG_PACKAGES); + + wxASSERT( win1 != NULL ); + + bool show = !win1->IsShown(); + + ShowDetails(show); +} + +void ecTemplatesDialog::ShowDetails(bool show) +{ + wxWindow* win1 = FindWindow(ecID_TEMPLATES_DIALOG_PACKAGES); + wxWindow* win2 = FindWindow(ecID_TEMPLATES_DIALOG_PACKAGES_MSG); + wxButton* button = (wxButton*) FindWindow(ecID_TEMPLATES_DIALOG_DETAILS); + + if (show) + { + GetSizer()->Add( win2, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + GetSizer()->Add( win1, 1, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + button->SetLabel("&Details <<"); + } + else + { + GetSizer()->Remove(win1); + GetSizer()->Remove(win2); + button->SetLabel("&Details >>"); + } + win1->Show(show); + win2->Show(show); + + Layout(); + GetSizer()->Fit( this ); +} + +void ecTemplatesDialog::OnSelHardwareTemplates(wxCommandEvent& event) +{ + wxComboBox* cdlHardwareCtrl = (wxComboBox*) FindWindow( ecID_TEMPLATES_DIALOG_HARDWARE_TEMPLATES ) ; + wxChoice* cdlPackageCtrl = (wxChoice*) FindWindow( ecID_TEMPLATES_DIALOG_PACKAGE_TEMPLATES ) ; + + ecConfigToolDoc* doc = wxGetApp().GetConfigToolDoc(); + + // the target has changed so retrieve the new target description + const int nIndex = cdlHardwareCtrl->GetSelection (); + std::vector::const_iterator template_i = (std::vector::const_iterator) cdlHardwareCtrl->GetClientData (nIndex); + m_hardware = template_i->c_str(); + + m_strCdlHardwareDescription = doc->GetCdlPkgData ()->get_target_description ((const wxChar*) m_hardware).c_str (); + m_strCdlHardwareDescription = ecUtils::StripExtraWhitespace (m_strCdlHardwareDescription); + + UpdateDetails (); // display new hardware packages in details box + + TransferDataToWindow (); // display new target description +} + +void ecTemplatesDialog::OnSelPackageTemplates(wxCommandEvent& event) +{ + wxComboBox* cdlHardwareCtrl = (wxComboBox*) FindWindow( ecID_TEMPLATES_DIALOG_HARDWARE_TEMPLATES ) ; + wxChoice* cdlPackageCtrl = (wxChoice*) FindWindow( ecID_TEMPLATES_DIALOG_PACKAGE_TEMPLATES ) ; + + // the template has changed so update the version combo box + int nIndex = cdlPackageCtrl->GetSelection (); + + std::vector::const_iterator template_i = (std::vector::const_iterator) cdlPackageCtrl->GetClientData (nIndex); + m_template = template_i->c_str(); + + UpdateVersionList (wxT("")); // repopulate template versions combo box and select most recent version +} + +void ecTemplatesDialog::OnSelPackageVersion(wxCommandEvent& event) +{ + wxString strVersion; + ecConfigToolDoc* doc = wxGetApp().GetConfigToolDoc(); + wxChoice* cdlVersionCtrl = (wxChoice*) FindWindow( ecID_TEMPLATES_DIALOG_VERSION ) ; + + strVersion = cdlVersionCtrl->GetStringSelection (); + + //TRACE (_T("Version '%s' selected\n"), strVersion); + m_template_version = ecUtils::UnicodeToStdStr (strVersion).c_str(); + m_strCdlTemplateDescription = doc->GetCdlPkgData ()->get_template_description (m_template.c_str(), m_template_version.c_str()).c_str (); + m_strCdlTemplateDescription = ecUtils::StripExtraWhitespace (m_strCdlTemplateDescription); + + UpdateDetails (); // display new template packages in details box + TransferDataToWindow (); // display new template description +} + +void ecTemplatesDialog::UpdateVersionList(const wxString& defaultVersion) +{ + wxComboBox* cdlHardwareCtrl = (wxComboBox*) FindWindow( ecID_TEMPLATES_DIALOG_HARDWARE_TEMPLATES ) ; + wxChoice* cdlPackageCtrl = (wxChoice*) FindWindow( ecID_TEMPLATES_DIALOG_PACKAGE_TEMPLATES ) ; + wxChoice* cdlVersionCtrl = (wxChoice*) FindWindow( ecID_TEMPLATES_DIALOG_VERSION ) ; + + ecConfigToolDoc* doc = wxGetApp().GetConfigToolDoc(); + + // clear the version combo box + cdlVersionCtrl->Clear (); + + // get the template version information + const std::vector& versions = doc->GetCdlPkgData ()->get_template_versions (m_template.c_str()); + wxASSERT (versions.size () > 0); + + // add the template versions to the version combo box + for (unsigned int version = 0; version < versions.size (); version++) { + // TRACE (_T("Adding version '%s'\n"), CString (versions [version].c_str ())); + cdlVersionCtrl->Append (versions [version].c_str ()); + } + + // select the appropriate version in the version combo box + if (defaultVersion.IsEmpty()) { // if no default version specified + cdlVersionCtrl->SetSelection (versions.size () - 1); // select the most recent version + } else { // a default version was specified + cdlVersionCtrl->SetStringSelection (defaultVersion); + } + wxCommandEvent dummyEvent; + + OnSelPackageVersion(dummyEvent); + + // enable the version combo box only if there are multiple versions + cdlVersionCtrl->Enable (versions.size () > 1); +} + +void ecTemplatesDialog::UpdateDetails() +{ + ecConfigToolDoc* doc = wxGetApp().GetConfigToolDoc(); + + // retrieve the template and target package names + const std::vector & template_packages = doc->GetCdlPkgData ()->get_template_packages (m_template.c_str(), m_template_version.c_str()); + std::vector packages = doc->GetCdlPkgData ()->get_target_packages (m_hardware.c_str()); + packages.insert (packages.end (), template_packages.begin (), template_packages.end ()); + + // retrieve the zeroth (verbose) package alias for each package + std::vector aliases; + unsigned int i; + for (i = 0; i < packages.size (); i++) + { + if (doc->GetCdlPkgData ()->is_known_package (packages [i])) // if the package is installed + { + aliases.push_back (doc->GetCdlPkgData ()->get_package_aliases (packages [i]) [0]); + } + else // package is not installed + { + aliases.push_back ("Unknown package " + packages [i]); + } + } + + // sort the aliases into alphabetical order + std::sort (aliases.begin (), aliases.end ()); + + // copy the aliases into the details box + m_strCdlTemplatePackages = wxT(""); + for (i = 0; i < aliases.size (); i++) + { + m_strCdlTemplatePackages += aliases [i].c_str (); +#ifdef __WXMSW__ + m_strCdlTemplatePackages += wxT("\r\n"); // add a CRLF between each alias +#else + m_strCdlTemplatePackages += wxT("\n"); // add a LF between each alias +#endif + } + // TODO: does this work for CRLF? + m_strCdlTemplatePackages.Trim (TRUE); // remove the trailing CRLF +} diff --git a/host/tools/configtool/standalone/wxwin/templatesdlg.h b/host/tools/configtool/standalone/wxwin/templatesdlg.h new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/templatesdlg.h @@ -0,0 +1,106 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +// templatesdlg.h : +// +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): julians +// Contact(s): julians +// Date: 2000/09/27 +// Version: $Id: templatesdlg.h,v 1.2 2001/03/23 13:38:04 julians Exp $ +// Purpose: +// Description: Header file for ecTemplatesDialog +// Requires: +// Provides: +// See also: +// Known bugs: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== + +#ifndef _ECOS_TEMPLATESDLG_H_ +#define _ECOS_TEMPLATESDLG_H_ + +#ifdef __GNUG__ +#pragma interface "templatesdlg.cpp" +#endif + +#include "ecutils.h" + +class ecTemplatesDialog : public ecDialog +{ +public: +// Ctor(s) + ecTemplatesDialog(wxWindow* parent); + ~ecTemplatesDialog(); + +//// Event handlers + + void OnOK(wxCommandEvent& event); + void OnCancel(wxCommandEvent& event); + void OnDetails(wxCommandEvent& event); + void OnSelHardwareTemplates(wxCommandEvent& event); + void OnSelPackageTemplates(wxCommandEvent& event); + void OnSelPackageVersion(wxCommandEvent& event); + + void ShowDetails(bool show); + +//// Operations + void CreateControls(wxWindow* parent); + void PopulateControls(); + void UpdateVersionList(const wxString& defaultVersion); + void UpdateDetails(); + +//// Accesors + wxString GetSelectedHardware () const { return m_hardware; } + wxString GetSelectedTemplate () const { return m_template; } + wxString GetSelectedTemplateVersion () const { return m_template_version; } +protected: + wxString m_hardware; + wxString m_template; + wxString m_template_version; + + wxString m_strCdlHardwareDescription; + wxString m_strCdlTemplateDescription; + wxString m_strCdlTemplatePackages; + +private: + DECLARE_EVENT_TABLE() +}; + +#define ecID_TEMPLATES_DIALOG_HARDWARE_TEMPLATES 10056 +#define ecID_TEMPLATES_DIALOG_HARDWARE_DESCRIPTION 10057 +#define ecID_TEMPLATES_DIALOG_PACKAGE_TEMPLATES 10058 +#define ecID_TEMPLATES_DIALOG_VERSION 10059 +#define ecID_TEMPLATES_DIALOG_PACKAGE_DESCRIPTION 10060 +#define ecID_TEMPLATES_DIALOG_DETAILS 10061 +#define ecID_TEMPLATES_DIALOG_PACKAGES_MSG 10062 +#define ecID_TEMPLATES_DIALOG_PACKAGES 10063 + +#endif + // _ECOS_TEMPLATESDLG_H_ diff --git a/packages/ChangeLog b/packages/ChangeLog --- a/packages/ChangeLog +++ b/packages/ChangeLog @@ -1,3 +1,12 @@ +2001-05-31 Jonathan Larmour + + * ecosadmin.tcl (set_value): Only warn if packages are missing. + +2001-05-23 Jesper Skov + + * ecos.db: Ocelot now uses generic AMD flash driver. + Removed AMD29F040B driver. + 2001-04-30 Jonathan Larmour * ecos.db: Add generic 16x5x driver to iq80310 target. @@ -93,7 +102,7 @@ 2001-01-31 Nick Garnett * ecos.db: Added generic i82559 ethernet driver. - Added QED Ocelot driver. + Added PMC-Sierra Ocelot driver. 2001-01-10 Jesper Skov diff --git a/packages/NEWS b/packages/NEWS --- a/packages/NEWS +++ b/packages/NEWS @@ -1,3 +1,4 @@ +* Added ethernet drivers for SMSC lan91cxx * Added driver for Motorola PowerPC 8xxT "Fast Ethernet Controller". * Added support for Analogue & Micro "viper" - PowerPC 860T based board. Currently this is only alpha since full test farm testing @@ -24,7 +25,7 @@ full eCos. * Added simple ROM based file system support, contributed by Richard Panton of 3G Lab. -* Added support for MIPS QED RM7000 variant and Ocelot board, including +* Added support for MIPS PMC-Sierra RM7000 variant and Ocelot board, including PCI, ethernet and FLASH support. * Added gzip/zlib decompression support to RedBoot. * Added zlib decompression library. diff --git a/packages/devs/eth/mips/ocelot/current/cdl/mips_rm7000_ocelot_eth_drivers.cdl b/packages/devs/eth/mips/ocelot/current/cdl/mips_rm7000_ocelot_eth_drivers.cdl --- a/packages/devs/eth/mips/ocelot/current/cdl/mips_rm7000_ocelot_eth_drivers.cdl +++ b/packages/devs/eth/mips/ocelot/current/cdl/mips_rm7000_ocelot_eth_drivers.cdl @@ -3,7 +3,7 @@ # ocelot_eth_drivers.cdl # # Ethernet drivers - support for i82559 ethernet controller -# on the QED Ocelot board. +# on the PMC-Sierra Ocelot board. # # ==================================================================== #####COPYRIGHTBEGIN#### @@ -41,8 +41,8 @@ # ==================================================================== cdl_package CYGPKG_DEVS_ETH_MIPS_RM7000_OCELOT { - display "QED Ocelot board ethernet driver" - description "Ethernet driver for QED Ocelot board." + display "PMC-Sierra Ocelot board ethernet driver" + description "Ethernet driver for PMC-Sierra Ocelot board." parent CYGPKG_IO_ETH_DRIVERS active_if CYGPKG_IO_ETH_DRIVERS diff --git a/packages/devs/eth/smsc/lan91cxx/current/ChangeLog b/packages/devs/eth/smsc/lan91cxx/current/ChangeLog new file mode 100644 --- /dev/null +++ b/packages/devs/eth/smsc/lan91cxx/current/ChangeLog @@ -0,0 +1,87 @@ +2001-03-27 Hugo Tyson +2001-03-27 Robin Farine + + * src/if_lan91cxx.c (lan91cxx_start): Strip the CRC from + incoming frames. + +2001-01-26 Hugo Tyson + + * src/smsc_lan91cxx.h (smsc_lan91cxx_stats): Add stats structure. + + * src/if_lan91cxx.c (lan91cxx_control): Implement ioctl() call for + SNMP statistics gathering. Implement stats counting generally. + +2001-01-25 Hugo Tyson + + * cdl/smsc_lan91cxx_eth_drivers.cdl + (CYGSEM_DEVS_ETH_SMSC_LAN91CXX_WRITE_EEPROM): New option to + control whether the IOCTL to set the ESA actually writes the + EEPROM. Default disabled for safety. + (CYGINT_DEVS_ETH_SMSC_LAN91CXX_STATIC_ESA): New interface controls + whether a statically configured ESA is picked up from private data. + + * src/smsc_lan91cxx.h (LAN91CXX_CONFIG): Add this, plus + (LAN91CXX_CONTROL_EEPROM_SELECT): et al for EEPROM writing. + + * src/if_lan91cxx.c (lan91cxx_control): Implement updating the + EEPROM with the new ESA, if so configured. Otherwise just set the + ESA in the device and continue, using the new value. + (smsc_lan91cxx_init): Obey the STATIC_ESA interface setting to use the + EEPROM or device data for the ESA. + + Removed some never-compiled, never-used stuff for getting an ESA + out of RedBoot's flash storage. + +2001-01-25 Hugo Tyson + + * cdl/smsc_lan91cxx_eth_drivers.cdl: This generic driver does not + implement CYGHWR_NET_DRIVER_ETH0 et al; the instantiating package + does. + +2001-01-24 Hugo Tyson + + * src/if_lan91cxx.c (lan91cxx_start): Implement promiscuous mode. + This just involves setting a bit in ..._start() if certain + interface flags are set. Also import a couple of other details + under #ifdef CYGPKG_NET from the i82559 driver for safety. + +2001-01-24 Hugo Tyson + + * src/if_lan91cxx.c (DEBUG): Refined debug output, for trying it + in RedBoot experiments. + +2001-01-22 Hugo Tyson + + * src/smsc_lan91cxx.h: New file. + * src/if_lan91cxx.c: New file. + * cdl/smsc_lan91cxx_eth_drivers.cdl: New file. + New component. Based on previous work [mis]named, in the same + idiom, lan900. Hence this new component with a better name. A + major rewrite too, to make the new one work with LAN91C96, + specifically. + +//=========================================================================== +//####COPYRIGHTBEGIN#### +// +// ------------------------------------------- +// The contents of this file are subject to the Red Hat eCos Public License +// Version 1.1 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://www.redhat.com/ +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +// License for the specific language governing rights and limitations under +// the License. +// +// The Original Code is eCos - Embedded Configurable Operating System, +// released September 30, 1998. +// +// The Initial Developer of the Original Code is Red Hat. +// Portions created by Red Hat are +// Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc. +// All Rights Reserved. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +//=========================================================================== diff --git a/packages/devs/eth/smsc/lan91cxx/current/cdl/smsc_lan91cxx_eth_drivers.cdl b/packages/devs/eth/smsc/lan91cxx/current/cdl/smsc_lan91cxx_eth_drivers.cdl new file mode 100644 --- /dev/null +++ b/packages/devs/eth/smsc/lan91cxx/current/cdl/smsc_lan91cxx_eth_drivers.cdl @@ -0,0 +1,97 @@ +# ==================================================================== +# +# smsc_lan91cxx_eth_drivers.cdl +# +# Ethernet drivers - support for LAN91CXX compatible ethernet controllers +# +# ==================================================================== +#####COPYRIGHTBEGIN#### +# +# ------------------------------------------- +# The contents of this file are subject to the Red Hat eCos Public License +# Version 1.1 (the "License"); you may not use this file except in +# compliance with the License. You may obtain a copy of the License at +# http://www.redhat.com/ +# +# Software distributed under the License is distributed on an "AS IS" +# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +# License for the specific language governing rights and limitations under +# the License. +# +# The Original Code is eCos - Embedded Configurable Operating System, +# released September 30, 1998. +# +# The Initial Developer of the Original Code is Red Hat. +# Portions created by Red Hat are +# Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +# All Rights Reserved. +# ------------------------------------------- +# +#####COPYRIGHTEND#### +# ==================================================================== +######DESCRIPTIONBEGIN#### +# +# Author(s): gthomas +# Contributors: gthomas, jskov +# Date: 2000-11-22 +# +#####DESCRIPTIONEND#### +# +# ==================================================================== + +cdl_package CYGPKG_DEVS_ETH_SMSC_LAN91CXX { + display "SMSC LAN91CXX compatible ethernet driver" + description "Ethernet driver for SMSC LAN91CXX compatible controllers." + + parent CYGPKG_IO_ETH_DRIVERS + active_if CYGPKG_IO_ETH_DRIVERS + + active_if CYGINT_DEVS_ETH_SMSC_LAN91CXX_REQUIRED + + include_dir . + include_files ; # none _exported_ whatsoever + compile -library=libextras.a if_lan91cxx.c + + define_proc { + puts $::cdl_header "#include "; + puts $::cdl_header "#include CYGDAT_DEVS_ETH_SMSC_LAN91CXX_CFG"; + } + + cdl_option CYGSEM_DEVS_ETH_SMSC_LAN91CXX_WRITE_EEPROM { + display "SIOCSIFHWADDR records ESA (MAC address) in EEPROM" + default_value 0 + description " + The ioctl() socket call with operand SIOCSIFHWADDR sets the + interface hardware address - the MAC address or Ethernet Station + Address (ESA). This option causes the new MAC address to be written + into the EEPROM associated with the interface, so that the new + MAC address is permanently recorded. Doing this should be a + carefully chosen decision, hence this option." + } + + cdl_interface CYGINT_DEVS_ETH_SMSC_LAN91CXX_STATIC_ESA { + display "ESA is statically configured" + description " + If this is nonzero, then the ESA (MAC address) is statically + configured in the platform-specific package which instantiates + this driver with all its details." + } + + cdl_component CYGPKG_DEVS_ETH_SMSC_LAN91CXX_OPTIONS { + display "LAN91CXX ethernet driver build options" + flavor none + no_define + + cdl_option CYGPKG_DEVS_ETH_SMSC_LAN91CXX_CFLAGS_ADD { + display "Additional compiler flags" + flavor data + no_define + default_value { "-D_KERNEL -D__ECOS" } + description " + This option modifies the set of compiler flags for + building the LAN91CXX ethernet driver package. + These flags are used in addition + to the set of global flags." + } + } +} diff --git a/packages/devs/eth/smsc/lan91cxx/current/src/if_lan91cxx.c b/packages/devs/eth/smsc/lan91cxx/current/src/if_lan91cxx.c new file mode 100644 --- /dev/null +++ b/packages/devs/eth/smsc/lan91cxx/current/src/if_lan91cxx.c @@ -0,0 +1,976 @@ +//========================================================================== +// +// dev/if_lan91cxx.c +// +// Ethernet device driver for SMSC LAN91CXX compatible controllers +// +//========================================================================== +//####COPYRIGHTBEGIN#### +// +// ------------------------------------------- +// The contents of this file are subject to the Red Hat eCos Public License +// Version 1.1 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://www.redhat.com/ +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +// License for the specific language governing rights and limitations under +// the License. +// +// The Original Code is eCos - Embedded Configurable Operating System, +// released September 30, 1998. +// +// The Initial Developer of the Original Code is Red Hat. +// Portions created by Red Hat are +// Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc. +// All Rights Reserved. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +//####BSDCOPYRIGHTBEGIN#### +// +// ------------------------------------------- +// +// Portions of this software may have been derived from OpenBSD or other sources, +// and are covered by the appropriate copyright disclaimers included herein. +// +// ------------------------------------------- +// +//####BSDCOPYRIGHTEND#### +//========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): hmt, based on lan900 (for LAN91C110) driver by jskov +// jskov, based on CS8900 driver by Gary Thomas +// Contributors: gthomas, jskov, hmt +// Date: 2001-01-22 +// Purpose: +// Description: hardware driver for LAN91CXX "LAN9000" ethernet +// Notes: Pointer register is not saved/restored on receive interrupts. +// The pointer is shared by both receive/transmit code. +// But the net stack manages atomicity for you here. +// +// The controller has an autorelease mode that allows TX packets +// to be freed automatically on successful transmission - but +// that is not used since we're only sending one packet at a +// time anyway. +// We may want to pingpong in future for throughput reasons. +// +//####DESCRIPTIONEND#### +// +//========================================================================== + +// Based on LAN91C110 and LAN91C96 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CYGPKG_NET +#include +#include +#include /* Needed for struct ifnet */ +#endif + +#ifdef CYGPKG_INFRA_DEBUG +// Then we log, OOI, the number of times we get a bad packet number +// from the tx done fifo. +int lan91cxx_txfifo_good = 0; +int lan91cxx_txfifo_bad = 0; +#endif + +// Set to perms of: +// 0 disables all debug output +// 1 for process debug output +// 2 for added data IO output: get_reg, put_reg +// 4 for packet allocation/free output +// 8 for only startup status, so we can tell we're installed OK +#define DEBUG 0 + +#if DEBUG & 1 +#define DEBUG_FUNCTION() do { diag_printf("%s\n", __FUNCTION__); } while (0) +#else +#define DEBUG_FUNCTION() do {} while(0) +#endif + +#if defined(ETH_DRV_GET_IF_STATS) || defined (ETH_DRV_GET_IF_STATS_UD) +#define KEEP_STATISTICS +#endif + +#ifdef KEEP_STATISTICS +#define INCR_STAT( _x_ ) (cpd->stats. _x_ ++) +#else +#define INCR_STAT( _x_ ) CYG_EMPTY_STATEMENT +#endif + +#include "smsc_lan91cxx.h" +#include CYGDAT_DEVS_ETH_SMSC_LAN91CXX_INL + +static void lan91cxx_poll(struct eth_drv_sc *sc); +static cyg_interrupt lan91cxx_interrupt; +static cyg_handle_t lan91cxx_interrupt_handle; + +// This ISR is called when the ethernet interrupt occurs +static int +lan91cxx_isr(cyg_vector_t vector, cyg_addrword_t data + /* , HAL_SavedRegisters *regs */ ) +{ + struct eth_drv_sc *sc = (struct eth_drv_sc *)data; + struct lan91cxx_priv_data *cpd = + (struct lan91cxx_priv_data *)sc->driver_private; + + DEBUG_FUNCTION(); + + INCR_STAT( interrupts ); + + cyg_drv_interrupt_mask(cpd->interrupt); + cyg_drv_interrupt_acknowledge(cpd->interrupt); + return (CYG_ISR_HANDLED|CYG_ISR_CALL_DSR); // Run the DSR +} + +// The deliver function (ex-DSR) handles the ethernet [logical] processing +static void +lan91cxx_deliver(struct eth_drv_sc *sc) +{ + struct lan91cxx_priv_data *cpd = + (struct lan91cxx_priv_data *)sc->driver_private; + + DEBUG_FUNCTION(); + + // Service the interrupt: + lan91cxx_poll(sc); + // Allow interrupts to happen again + cyg_drv_interrupt_unmask(cpd->interrupt); +} + +static int +lan91cxx_int_vector(struct eth_drv_sc *sc) +{ + struct lan91cxx_priv_data *cpd = + (struct lan91cxx_priv_data *)sc->driver_private; + + return (cpd->interrupt); +} + +static bool +smsc_lan91cxx_init(struct cyg_netdevtab_entry *tab) +{ + struct eth_drv_sc *sc = (struct eth_drv_sc *)tab->device_instance; + struct lan91cxx_priv_data *cpd = + (struct lan91cxx_priv_data *)sc->driver_private; + unsigned short val; + int i; + + DEBUG_FUNCTION(); + + cpd->txbusy = cpd->within_send = 0; + + // Initialize environment, setup interrupt handler + cyg_drv_interrupt_create(cpd->interrupt, + 99, // Priority - what goes here? + (cyg_addrword_t)sc, // Data item passed to interrupt handler + (cyg_ISR_t *)lan91cxx_isr, + (cyg_DSR_t *)eth_drv_dsr, // The logical driver DSR + &lan91cxx_interrupt_handle, + &lan91cxx_interrupt); + cyg_drv_interrupt_attach(lan91cxx_interrupt_handle); + cyg_drv_interrupt_acknowledge(cpd->interrupt); + cyg_drv_interrupt_unmask(cpd->interrupt); + + HAL_READ_UINT16(cpd->base+LAN91CXX_BS, val); +#if DEBUG & 9 + diag_printf("LAN91CXX - supposed BankReg @ %x = %04x\n", + cpd->base+LAN91CXX_BS, val ); +#endif + CYG_ASSERT( 0x3300 == (0xff00 & val), "No 91Cxx signature" ); + + val = get_reg(sc, LAN91CXX_REVISION); + +#if DEBUG & 9 + diag_printf("LAN91CXX - type: %01x, rev: %01x\n", + (val>>4)&0xf, val & 0xf); +#endif + + // The controller may provide a function used to set up the ESA + if (cpd->config_enaddr) + (*cpd->config_enaddr)(cpd); + + // Reset chip + put_reg(sc, LAN91CXX_RCR, LAN91CXX_RCR_SOFT_RST); + put_reg(sc, LAN91CXX_RCR, 0); + + val = get_reg(sc, LAN91CXX_EPH_STATUS); + +#if DEBUG & 9 + diag_printf("LAN91CXX - status: %04x\n", val); +#endif + +#if 0 < CYGINT_DEVS_ETH_SMSC_LAN91CXX_STATIC_ESA + // Use statically configured ESA from the private data +#if DEBUG & 9 + diag_printf("LAN91CXX - static ESA: %02x:%02x:%02x:%02x:%02x:%02x\n", + cpd->enaddr[0], + cpd->enaddr[1], + cpd->enaddr[2], + cpd->enaddr[3], + cpd->enaddr[4], + cpd->enaddr[5] ); +#endif // DEBUG + // Set up hardware address + for (i = 0; i < sizeof(cpd->enaddr); i += 2) + put_reg(sc, LAN91CXX_IA01+i/2, + cpd->enaddr[i] | (cpd->enaddr[i+1] << 8)); +#else // not CYGINT_DEVS_ETH_SMSC_LAN91CXX_STATIC_ESA + // Use the address from the serial EEPROM + + // Read out hardware address + for (i = 0; i < sizeof(cpd->enaddr); i += 2) { + unsigned short z = get_reg(sc, LAN91CXX_IA01+i/2 ); + cpd->enaddr[i] = (unsigned char)(0xff & z); + cpd->enaddr[i+1] = (unsigned char)(0xff & (z >> 8)); + } +#if DEBUG & 9 + diag_printf("LAN91CXX - eeprom ESA: %02x:%02x:%02x:%02x:%02x:%02x\n", + cpd->enaddr[0], + cpd->enaddr[1], + cpd->enaddr[2], + cpd->enaddr[3], + cpd->enaddr[4], + cpd->enaddr[5] ); +#endif // DEBUG +#endif // !CYGINT_DEVS_ETH_SMSC_LAN91CXX_STATIC_ESA + + // Initialize upper level driver + (sc->funs->eth_drv->init)(sc, cpd->enaddr); + return true; +} + +static void +lan91cxx_stop(struct eth_drv_sc *sc) +{ + DEBUG_FUNCTION(); + // Reset chip + put_reg(sc, LAN91CXX_RCR, LAN91CXX_RCR_SOFT_RST); + put_reg(sc, LAN91CXX_RCR, 0); +} + +// +// This function is called to "start up" the interface. It may be called +// multiple times, even when the hardware is already running. It will be +// called whenever something "hardware oriented" changes and should leave +// the hardware ready to send/receive packets. +// +static void +lan91cxx_start(struct eth_drv_sc *sc, unsigned char *enaddr, int flags) +{ +#ifdef CYGPKG_NET + struct ifnet *ifp = &sc->sc_arpcom.ac_if; +#endif + DEBUG_FUNCTION(); + put_reg(sc, LAN91CXX_INTERRUPT, 0); // disable interrupts + put_reg(sc, LAN91CXX_INTERRUPT, // ack old interrupts + LAN91CXX_INTERRUPT_TX_INT | LAN91CXX_INTERRUPT_TX_EMPTY_INT | + LAN91CXX_INTERRUPT_RX_OVRN_INT | LAN91CXX_INTERRUPT_ERCV_INT); + put_reg(sc, LAN91CXX_RCR, +#ifdef RCR_HAS_ABORT_ENB // 91C96 does not - page 46. + LAN91CXX_RCR_ABORT_ENB | +#endif + LAN91CXX_RCR_STRIP_CRC | + LAN91CXX_RCR_RXEN | LAN91CXX_RCR_ALMUL); + put_reg(sc, LAN91CXX_TCR, LAN91CXX_TCR_TXENA | LAN91CXX_TCR_PAD_EN); + put_reg(sc, LAN91CXX_CONTROL, 0); + put_reg(sc, LAN91CXX_INTERRUPT, // enable interrupts + LAN91CXX_INTERRUPT_RCV_INT_M); +#ifdef CYGPKG_NET + if (( 0 +#ifdef ETH_DRV_FLAGS_PROMISC_MODE + != (flags & ETH_DRV_FLAGS_PROMISC_MODE) +#endif + ) || (ifp->if_flags & IFF_PROMISC) + ) { + // Then we select promiscuous mode. + unsigned short rcr; + rcr = get_reg(sc, LAN91CXX_RCR ); + rcr |= LAN91CXX_RCR_PRMS; + put_reg(sc, LAN91CXX_RCR, rcr ); + } +#endif +} + +// +// This routine is called to perform special "control" opertions +// +static int +lan91cxx_control(struct eth_drv_sc *sc, unsigned long key, + void *data, int data_length) +{ + unsigned char *esa = (unsigned char *)data; + int i; + unsigned short reg; + struct lan91cxx_priv_data *cpd = + (struct lan91cxx_priv_data *)sc->driver_private; + + DEBUG_FUNCTION(); + + switch (key) { + case ETH_DRV_SET_MAC_ADDRESS: +#if 9 & DEBUG + diag_printf("LAN91CXX - set ESA: %02x:%02x:%02x:%02x:%02x:%02x\n", + esa[0], + esa[1], + esa[2], + esa[3], + esa[4], + esa[5] ); +#ifndef CYGSEM_DEVS_ETH_SMSC_LAN91CXX_WRITE_EEPROM + diag_printf("*** PERMANENT EEPROM WRITE NOT ENABLED ***\n"); +#endif +#endif // DEBUG + +#ifdef CYGSEM_DEVS_ETH_SMSC_LAN91CXX_WRITE_EEPROM + // Only now can we command the chip to perform EEPROM writes: + + // select arbitrary writing to the EEPROM + reg = get_reg(sc, LAN91CXX_CONTROL); + reg |= LAN91CXX_CONTROL_EEPROM_SELECT; + put_reg(sc, LAN91CXX_CONTROL, reg ); + + for (i = 0; i < sizeof(cpd->enaddr); i += 2) { + int j; + // Set the address register + put_reg(sc, LAN91CXX_POINTER, LAN91CXX_ESA_EEPROM_OFFSET + i/2); + // Poke the data + put_reg(sc, LAN91CXX_GENERAL, esa[i] | (esa[i+1] << 8)); + // Command the store + reg = get_reg(sc, LAN91CXX_CONTROL); + reg |= LAN91CXX_CONTROL_STORE; + put_reg(sc, LAN91CXX_CONTROL, reg ); + // and poll for completion + for ( j = 1024 * 1024; 0 < j ; j-- ) { + reg = get_reg(sc, LAN91CXX_CONTROL); + if ( 0 == (reg & LAN91CXX_CONTROL_EEPROM_BUSY) ) + break; + } + CYG_ASSERT( 0 < j, "EEPROM write timout!" ); + } + + reg = get_reg(sc, LAN91CXX_CONTROL); + CYG_ASSERT( 0 == (reg & LAN91CXX_CONTROL_EEPROM_BUSY), + "EEPROM still busy!" ); + // Clear the EEPROM selection bit + reg &=~LAN91CXX_CONTROL_EEPROM_SELECT; + put_reg(sc, LAN91CXX_CONTROL, reg ); + // and check it "took" + reg = get_reg(sc, LAN91CXX_CONTROL); + CYG_ASSERT( 0 == (reg & LAN91CXX_CONTROL_EEPROM_SELECT), + "EEPROM still selected!" ); + // and command a complete reload + reg |= LAN91CXX_CONTROL_RELOAD; + put_reg(sc, LAN91CXX_CONTROL, reg ); + for ( i = 1024 * 1024; 0 < i ; i-- ) { + reg = get_reg(sc, LAN91CXX_CONTROL); + if ( 0 == (reg & LAN91CXX_CONTROL_EEPROM_BUSY) ) + break; + } + CYG_ASSERT( 0 < i, "EEPROM reload timout!" ); + // Now extract the MAC address that is in the chip, and tell the + // system about it. + for (i = 0; i < sizeof(cpd->enaddr); i += 2) { + unsigned short z = get_reg(sc, LAN91CXX_IA01+i/2 ); + cpd->enaddr[i] = (unsigned char)(0xff & z); + cpd->enaddr[i+1] = (unsigned char)(0xff & (z >> 8)); + } +#if DEBUG & 9 + diag_printf("LAN91CXX - eeprom new ESA: %02x:%02x:%02x:%02x:%02x:%02x\n", + cpd->enaddr[0], + cpd->enaddr[1], + cpd->enaddr[2], + cpd->enaddr[3], + cpd->enaddr[4], + cpd->enaddr[5] ); +#endif // DEBUG + for (i = 0; i < sizeof(cpd->enaddr); i++ ) { + CYG_ASSERT( esa[i] == cpd->enaddr[i], "ESA not written correctly" ); + if ( esa[i] != cpd->enaddr[i] ) + return 1; // the operation failed. + } +#else // not CYGSEM_DEVS_ETH_SMSC_LAN91CXX_WRITE_EEPROM + // Whatever, we can write the MAC address into the interface info, + // and the chip registers no problem. + for ( i = 0; i < sizeof(cpd->enaddr); i++ ) + cpd->enaddr[i] = esa[i]; + for (i = 0; i < sizeof(cpd->enaddr); i += 2) { + reg = cpd->enaddr[i] | (cpd->enaddr[i+1] << 8); + put_reg(sc, LAN91CXX_IA01+i/2, reg ); + } +#endif // !CYGSEM_DEVS_ETH_SMSC_LAN91CXX_WRITE_EEPROM + return 0; + +#ifdef ETH_DRV_GET_MAC_ADDRESS + case ETH_DRV_GET_MAC_ADDRESS: + // Extract the MAC address that is in the chip, and tell the + // system about it. + for (i = 0; i < sizeof(cpd->enaddr); i += 2) { + unsigned short z = get_reg(sc, LAN91CXX_IA01+i/2 ); + esa[i] = (unsigned char)(0xff & z); + esa[i+1] = (unsigned char)(0xff & (z >> 8)); + } + return 0; +#endif + +#ifdef ETH_DRV_GET_IF_STATS_UD + case ETH_DRV_GET_IF_STATS_UD: // UD == UPDATE +#endif + // drop through +#ifdef ETH_DRV_GET_IF_STATS + case ETH_DRV_GET_IF_STATS: +#endif +#if defined(ETH_DRV_GET_IF_STATS) || defined (ETH_DRV_GET_IF_STATS_UD) + { + struct ether_drv_stats *p = (struct ether_drv_stats *)data; + // Chipset entry is no longer supported; RFC1573. + for ( i = 0; i < SNMP_CHIPSET_LEN; i++ ) + p->snmp_chipset[i] = 0; + + // This perhaps should be a config opt, so you can make up your own + // description, or supply it from the instantiation. + strcpy( p->description, "SMSC LAN91Cxx" ); + // CYG_ASSERT( 48 > strlen(p->description), "Description too long" ); + + reg = get_reg(sc, LAN91CXX_EPH_STATUS); + if ((reg & LAN91CXX_STATUS_LINK_OK) == 0) { + p->operational = 2; // LINK DOWN + p->duplex = 1; // UNKNOWN + p->speed = 0; + } + else { + p->operational = 3; // LINK UP + p->duplex = 2; // 2 = SIMPLEX, 3 = DUPLEX + p->speed = 10 * 1000000; // it's only a 10Mbit device + } + +#ifdef KEEP_STATISTICS + { + struct smsc_lan91cxx_stats *ps = &(cpd->stats); + + // Admit to it... + p->supports_dot3 = true; + + p->tx_good = ps->tx_good ; + p->tx_max_collisions = ps->tx_max_collisions ; + p->tx_late_collisions = ps->tx_late_collisions ; + p->tx_underrun = ps->tx_underrun ; + p->tx_carrier_loss = ps->tx_carrier_loss ; + p->tx_deferred = ps->tx_deferred ; + p->tx_sqetesterrors = ps->tx_sqetesterrors ; + p->tx_single_collisions = ps->tx_single_collisions; + p->tx_mult_collisions = ps->tx_mult_collisions ; + p->tx_total_collisions = ps->tx_total_collisions ; + p->rx_good = ps->rx_good ; + p->rx_crc_errors = ps->rx_crc_errors ; + p->rx_align_errors = ps->rx_align_errors ; + p->rx_resource_errors = ps->rx_resource_errors ; + p->rx_overrun_errors = ps->rx_overrun_errors ; + p->rx_collisions = ps->rx_collisions ; + p->rx_short_frames = ps->rx_short_frames ; + p->rx_too_long_frames = ps->rx_too_long_frames ; + p->rx_symbol_errors = ps->rx_symbol_errors ; + + p->interrupts = ps->interrupts ; + p->rx_count = ps->rx_count ; + p->rx_deliver = ps->rx_deliver ; + p->rx_resource = ps->rx_resource ; + p->rx_restart = ps->rx_restart ; + p->tx_count = ps->tx_count ; + p->tx_complete = ps->tx_complete ; + p->tx_dropped = ps->tx_dropped ; + } +#endif // KEEP_STATISTICS + + p->tx_queue_len = 1; + + return 0; // OK + } +#endif + default: + } + return 1; +} + +// +// This routine is called to see if it is possible to send another packet. +// It will return non-zero if a transmit is possible, zero otherwise. +// +static int +lan91cxx_can_send(struct eth_drv_sc *sc) +{ + struct lan91cxx_priv_data *cpd = + (struct lan91cxx_priv_data *)sc->driver_private; + unsigned short stat; + + DEBUG_FUNCTION(); + stat = get_reg(sc, LAN91CXX_EPH_STATUS); + if ((stat & LAN91CXX_STATUS_LINK_OK) == 0) { + return false; // Link not connected + } + + CYG_ASSERT( cpd->within_send < 10, "can_send: Excess send recursions" ); + cpd->within_send++; + // This helps unstick deadly embraces. + lan91cxx_poll( sc ); // Deal with any outstanding rx state + cpd->within_send--; + + return (cpd->txbusy == 0) && (0 == cpd->within_send); +} + +// +// This routine is called to send data to the hardware. +static void +lan91cxx_send(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len, + int total_len, unsigned long key) +{ + struct lan91cxx_priv_data *cpd = + (struct lan91cxx_priv_data *)sc->driver_private; + int i, len, plen, tcr; + + unsigned short *sdata = NULL; + unsigned short ints, control; + cyg_uint16 packet, status; + + DEBUG_FUNCTION(); + + INCR_STAT( tx_count ); + + // Worry about the TX engine stopping. + tcr = get_reg(sc, LAN91CXX_TCR); + if ( 0 == (LAN91CXX_TCR_TXENA & tcr) ) { +#if DEBUG & 1 + diag_printf("%s: ENGINE RESTART: tcr %x\n", __FUNCTION__, tcr ); +#endif + tcr |= LAN91CXX_TCR_TXENA; + put_reg(sc, LAN91CXX_TCR, tcr); + } + + // This helps unstick deadly embraces. + CYG_ASSERT( cpd->within_send < 10, "send: Excess send recursions" ); + cpd->within_send++; + lan91cxx_poll( sc ); // Deal with any outstanding rx state + cpd->within_send--; + + cpd->txbusy = 1; + cpd->txkey = key; + + // Find packet length + plen = 0; + for (i = 0; i < sg_len; i++) + plen += sg_list[i].len; + + CYG_ASSERT( plen == total_len, "sg data length mismatch" ); + + // Alloc new TX packet + do { + put_reg(sc, LAN91CXX_MMU_COMMAND, + LAN91CXX_MMU_alloc_for_tx | ((plen >> 8) & 0x07)); + i = 1024 * 1024; + do { + status = get_reg(sc, LAN91CXX_INTERRUPT); + } while (0 == (status & LAN91CXX_INTERRUPT_ALLOC_INT) && (--i > 0) ); + if ( i ) + packet = get_reg(sc, LAN91CXX_PNR); + else + packet = 0xffff; +#if DEBUG & 1 + diag_printf("%s: allocated packet %04x\n", __FUNCTION__, packet); +#endif + packet = packet >> 8; + if (packet & 0x80) { + // Hm.. Isn't this a dead end? +#if DEBUG & 1 + diag_printf("%s: Allocation failed! Retrying...\n", __FUNCTION__ ); +#endif + // Not if we can make progress with what's filling memory. + lan91cxx_poll( sc ); // Deal with any outstanding state + continue; + } + } while (0); + +#if DEBUG & 4 + diag_printf("#####Tx packet allocated %x (previous %x)\n", + packet, cpd->txpacket); +#endif + cpd->txpacket = packet; + + put_reg(sc, LAN91CXX_PNR, packet); + // Note: Check FIFO state here before continuing? + put_reg(sc, LAN91CXX_POINTER, LAN91CXX_POINTER_AUTO_INCR | 0x0000); + // Pointer is now set, and the proper bank is selected for + // data writes. + + // Prepare header: + put_data(sc, 0); // reserve space for status word + // packet length (includes status, byte-count and control shorts) + put_data(sc, 0x7FE & (plen + 6) ); // Always even, always < 15xx(dec) + + // Put data into buffer + for (i = 0; i < sg_len; i++) { + sdata = (unsigned short *)sg_list[i].buf; + len = sg_list[i].len; + + CYG_ASSERT(0 == (len & 1) || (i == (sg_len-1)), "odd length"); + CYG_ASSERT( sdata, "No sg data pointer here" ); + while(len >= sizeof(*sdata)) { + put_data(sc, *sdata++); + len -= sizeof(*sdata); + } + } + CYG_ASSERT( sdata, "No sg data pointer outside" ); + + // Lay down the control short unconditionally at the end. + // (or it might use random memory contents) + control = 0; + if ( 1 & plen ) { + // Need to set ODD flag and insert the data + unsigned char onebyte = *(unsigned char*)sdata; + control = onebyte; + control |= LAN91CXX_CONTROLBYTE_ODD; + } + control |= LAN91CXX_CONTROLBYTE_CRC; // Just in case... + put_data(sc, control); + + // Enqueue the packet + put_reg(sc, LAN91CXX_MMU_COMMAND, LAN91CXX_MMU_enq_packet); + + // Ack TX empty int and unmask it. + ints = get_reg(sc, LAN91CXX_INTERRUPT); + ints |= LAN91CXX_INTERRUPT_TX_SET_ACK; + put_reg(sc, LAN91CXX_INTERRUPT, ints); + ints |= LAN91CXX_INTERRUPT_TX_SET_M; + put_reg(sc, LAN91CXX_INTERRUPT, ints); + +#if DEBUG & 1 + ints = get_reg(sc, LAN91CXX_INTERRUPT); + diag_printf("%s:END: ints at TX: %04x\n", __FUNCTION__, ints); +#endif +} + +static void +lan91cxx_TxEvent(struct eth_drv_sc *sc, int stat) +{ + unsigned short packet, ints, tcr; + struct lan91cxx_priv_data *cpd = + (struct lan91cxx_priv_data *)sc->driver_private; + int success = 1; + + DEBUG_FUNCTION(); + + INCR_STAT( tx_complete ); + + // Ack and mask TX interrupt set + ints = get_reg(sc, LAN91CXX_INTERRUPT); + ints &=~LAN91CXX_INTERRUPT_TX_FIFO_ACK; // Do NOT ACK this one here. + ints |= LAN91CXX_INTERRUPT_TX_SET_ACK; // Also ACKs other sources! + ints &= ~LAN91CXX_INTERRUPT_TX_SET_M; + put_reg(sc, LAN91CXX_INTERRUPT, ints); + + // Get number of completed packet and read the status word + packet = get_reg(sc, LAN91CXX_FIFO_PORTS); +#if DEBUG & 1 + diag_printf("%s:START: fifo %04x ints %04x\n", __FUNCTION__, packet, ints); +#endif + +#ifdef KEEP_STATISTICS + { + unsigned short reg; + + reg = get_reg( sc, LAN91CXX_EPH_STATUS ); + + // Covering each bit in turn... + if ( reg & LAN91CXX_STATUS_TX_UNRN ) INCR_STAT( tx_underrun ); + //if ( reg & LAN91CXX_STATUS_LINK_OK ) INCR_STAT( ); + //if ( reg & LAN91CXX_STATUS_CTR_ROL ) INCR_STAT( ); + //if ( reg & LAN91CXX_STATUS_EXC_DEF ) INCR_STAT( ); + if ( reg & LAN91CXX_STATUS_LOST_CARR ) INCR_STAT( tx_carrier_loss ); + if ( reg & LAN91CXX_STATUS_LATCOL ) INCR_STAT( tx_late_collisions ); + //if ( reg & LAN91CXX_STATUS_WAKEUP ) INCR_STAT( ); + if ( reg & LAN91CXX_STATUS_TX_DEFR ) INCR_STAT( tx_deferred ); + //if ( reg & LAN91CXX_STATUS_LTX_BRD ) INCR_STAT( ); + if ( reg & LAN91CXX_STATUS_SQET ) INCR_STAT( tx_sqetesterrors ); + if ( reg & LAN91CXX_STATUS_16COL ) INCR_STAT( tx_max_collisions ); + //if ( reg & LAN91CXX_STATUS_LTX_MULT) INCR_STAT( ); + if ( reg & LAN91CXX_STATUS_MUL_COL ) INCR_STAT( tx_mult_collisions ); + if ( reg & LAN91CXX_STATUS_SNGL_COL ) INCR_STAT( tx_single_collisions ); + if ( reg & LAN91CXX_STATUS_TX_SUC ) INCR_STAT( tx_good ); + + cpd->stats.tx_total_collisions = + cpd->stats.tx_late_collisions + + cpd->stats.tx_max_collisions + + cpd->stats.tx_mult_collisions + + cpd->stats.tx_single_collisions; + + // We do not need to look in the Counter Register (LAN91CXX_COUNTER) + // because it just mimics the info we already have above. + } +#endif // KEEP_STATISTICS + // We do not really care about Tx failure. Ethernet is not a reliable + // medium. But we do care about the TX engine stopping. + tcr = get_reg(sc, LAN91CXX_TCR); + if ( 0 == (LAN91CXX_TCR_TXENA & tcr) ) { +#if DEBUG & 1 + diag_printf("%s: ENGINE RESTART: tcr %x ints %04x\n", __FUNCTION__, tcr, ints); +#endif + tcr |= LAN91CXX_TCR_TXENA; + put_reg(sc, LAN91CXX_TCR, tcr); + success = 0; // And treat this as an error... + } + + packet &= 0xff; + + // Ack the TX int which is supposed to clear the packet from the TX + // completion queue. + ints = get_reg(sc, LAN91CXX_INTERRUPT); + ints |= LAN91CXX_INTERRUPT_TX_FIFO_ACK; + put_reg(sc, LAN91CXX_INTERRUPT, ints); + + // It certainly appears that occasionally the tx fifo tells lies; we + // get the wrong packet number. Freeing the one we allocated seems to + // give correct operation. +#ifdef CYGPKG_INFRA_DEBUG + // Then we log, OOI, the number of times we get a bad packet number + // from the tx done fifo. + if (cpd->txpacket != packet ) + lan91cxx_txfifo_bad++; + else + lan91cxx_txfifo_good++; +#endif +#if DEBUG & 4 + diag_printf("#####Tx packet freed %x (expected %x)\n", packet, cpd->txpacket ); +#endif + // and then free the packet + put_reg(sc, LAN91CXX_PNR, cpd->txpacket); + put_reg(sc, LAN91CXX_MMU_COMMAND, LAN91CXX_MMU_rel_packet); + +#if DEBUG & 1 + // Hm... The free doesn't seem to have the desired effect?!? + ints = get_reg(sc, LAN91CXX_INTERRUPT); + packet = get_reg(sc, LAN91CXX_FIFO_PORTS); + diag_printf("%s:END: fifo %04x ints %04x\n", __FUNCTION__, packet, ints); +#endif + + if ( cpd->txbusy ) { + cpd->txbusy = 0; + (sc->funs->eth_drv->tx_done)(sc, cpd->txkey, success); + } +} + + +// +// This function is called when a packet has been received. Its job is +// to prepare to unload the packet from the hardware. Once the length of +// the packet is known, the upper layer of the driver can be told. When +// the upper layer is ready to unload the packet, the internal function +// 'lan91cxx_recv' will be called to actually fetch it from the hardware. +// +static void +lan91cxx_RxEvent(struct eth_drv_sc *sc) +{ + struct lan91cxx_priv_data *cpd = + (struct lan91cxx_priv_data *)sc->driver_private; + unsigned short stat, len, controlbyte; + + DEBUG_FUNCTION(); + + stat = get_reg(sc, LAN91CXX_FIFO_PORTS); +#if DEBUG & 1 + diag_printf("RxEvent - FIFOs: 0x%04x\n", stat); +#endif + if ( 0x8000 & stat ) + // Then the Rx FIFO is empty + return; + + INCR_STAT( rx_count ); + +#if DEBUG & 4 + diag_printf("#####Rx packet allocated %x (previous %x)\n", + 0xff & (stat >> 8), cpd->rxpacket ); +#endif + // There is an Rx Packet ready + cpd->rxpacket = 0xff & (stat >> 8); + + // Read status and (word) length + put_reg(sc, LAN91CXX_POINTER, (LAN91CXX_POINTER_RCV | LAN91CXX_POINTER_READ | + LAN91CXX_POINTER_AUTO_INCR | 0x0000)); + stat = get_data(sc); + len = get_data(sc) - 6; // minus header/footer words + // Read control byte at end of packet to get last bit of length + put_reg(sc, LAN91CXX_POINTER, (LAN91CXX_POINTER_RCV | LAN91CXX_POINTER_READ | + LAN91CXX_POINTER_AUTO_INCR | (len + 4))); + controlbyte = get_data(sc); + +#ifdef KEEP_STATISTICS + if ( stat & LAN91CXX_RX_STATUS_ALIGNERR ) INCR_STAT( rx_align_errors ); + //if ( stat & LAN91CXX_RX_STATUS_BCAST ) INCR_STAT( ); + if ( stat & LAN91CXX_RX_STATUS_BADCRC ) INCR_STAT( rx_crc_errors ); + if ( stat & LAN91CXX_RX_STATUS_TOOLONG ) INCR_STAT( rx_too_long_frames ); + if ( stat & LAN91CXX_RX_STATUS_TOOSHORT ) INCR_STAT( rx_short_frames ); + //if ( stat & LAN91CXX_RX_STATUS_MCAST ) INCR_STAT( ); +#endif // KEEP_STATISTICS + + if (controlbyte & LAN91CXX_CONTROLBYTE_RX) { + INCR_STAT( rx_good ); + // Then it's OK + if (controlbyte & LAN91CXX_CONTROLBYTE_ODD) + len++; + +#if DEBUG & 1 + diag_printf("RxEvent good rx - stat: 0x%04x, len: 0x%04x\n", stat, len); +#endif + // Check for bogusly short packets; can happen in promisc mode: + // Asserted against and checked by upper layer driver. +#ifdef CYGPKG_NET + if ( len > sizeof( struct ether_header ) ) + // then it is acceptable; offer the data to the network stack +#endif + (sc->funs->eth_drv->recv)(sc, len); + + return; + } + + // Not OK for one reason or another... +#if DEBUG & 1 + diag_printf("RxEvent - No RX bit: stat: 0x%04x, len: 0x%04x, control'byte' 0x%04x\n", + stat, len, controlbyte); +#endif + +#if DEBUG & 4 + stat = get_reg(sc, LAN91CXX_FIFO_PORTS); + if ( 0x8000 & stat ) // Then the Rx FIFO is empty + diag_printf("#####Rx packet (bad controlbyte) NOT freed, stat is %x (expected %x)\n", + stat, cpd->rxpacket ); + else + diag_printf("#####Rx packet (bad controlbyte) freed %x (expected %x)\n", + 0xff & (stat >> 8), cpd->rxpacket ); +#endif + + // Free packet + put_reg(sc, LAN91CXX_MMU_COMMAND, LAN91CXX_MMU_remrel_rx_frame); +} + +// +// This function is called as a result of the "eth_drv_recv()" call above. +// Its job is to actually fetch data for a packet from the hardware once +// memory buffers have been allocated for the packet. Note that the buffers +// may come in pieces, using a scatter-gather list. This allows for more +// efficient processing in the upper layers of the stack. +// +static void +lan91cxx_recv(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len) +{ +#if (4 & DEBUG) || defined(CYGPKG_INFRA_DEBUG) || defined(KEEP_STATISTICS) + struct lan91cxx_priv_data *cpd = + (struct lan91cxx_priv_data *)sc->driver_private; +#endif + int i, mlen=0, plen; + unsigned short *data=NULL, val; + unsigned char *cp, cval; + + DEBUG_FUNCTION(); + + INCR_STAT( rx_deliver ); + + put_reg(sc, LAN91CXX_POINTER, (LAN91CXX_POINTER_RCV | LAN91CXX_POINTER_READ | + LAN91CXX_POINTER_AUTO_INCR | 0x0002)); + // Status is skipped by starting at 2 above. + plen = get_data(sc) - 6; // packet length (minus header/footer) + + for (i = 0; i < sg_len; i++) { + data = (unsigned short *)sg_list[i].buf; + mlen = sg_list[i].len; + + CYG_ASSERT(0 == (mlen & 1) || (i == (sg_len-1)), "odd length"); +#if DEBUG & 1 + diag_printf("%s : mlen %x, plen %x\n", __FUNCTION__, mlen, plen); +#endif + if (data) { + while (mlen >= sizeof(*data)) { + *data++ = get_data(sc); + mlen -= sizeof(*data); + plen -= sizeof(*data); + } + } + } + CYG_ASSERT( data, "No sg data for end byte" ); + val = get_data(sc); // Read control word unconditionally + CYG_ASSERT(val & LAN91CXX_CONTROLBYTE_RX, + "Controlbyte is not for Rx"); + CYG_ASSERT( (1 == mlen) == (0 != (val & LAN91CXX_CONTROLBYTE_ODD)), + "Controlbyte does not match"); + if (data && (1 == mlen) && (val & LAN91CXX_CONTROLBYTE_ODD)) { + cval = val & 0x00ff; // last byte contains data + cp = (unsigned char*)data; + *cp = cval; + } + + val = get_reg(sc, LAN91CXX_FIFO_PORTS); +#if DEBUG & 4 + if ( 0x8000 & val ) // Then the Rx FIFO is empty + diag_printf("#####Rx packet NOT freed, stat is %x (expected %x)\n", + val, cpd->rxpacket); + else + diag_printf("#####Rx packet freed %x (expected %x)\n", + 0xff & (val >> 8), cpd->rxpacket ); +#endif + CYG_ASSERT( (0xff & (val >> 8)) == cpd->rxpacket, "Unexpected rx packet" ); + + // Free packet + put_reg(sc, LAN91CXX_MMU_COMMAND, LAN91CXX_MMU_remrel_rx_frame); +} + +static void +lan91cxx_poll(struct eth_drv_sc *sc) +{ + unsigned short event; + + DEBUG_FUNCTION(); + while (1) { + // Get the (unmasked) requests + event = get_reg(sc, LAN91CXX_INTERRUPT); + event = event & (event >> 8) & 0xff; + if (0 == event) + break; +#if 0 + if (event & LAN91CXX_INTERRUPT_ERCV_INT) { + // Early receive interrupt + } + else if (event & LAN91CXX_INTERRUPT_EPH_INT) { + // ethernet protocol handler failures + } + else if (event & LAN91CXX_INTERRUPT_RX_OVRN_INT) { + // receive overrun + } + else if (event & LAN91CXX_INTERRUPT_ALLOC_INT) { + // allocation interrupt + } + else +#endif + if (event & LAN91CXX_INTERRUPT_TX_SET) { + lan91cxx_TxEvent(sc, event); + } + else if (event & LAN91CXX_INTERRUPT_RCV_INT) { + lan91cxx_RxEvent(sc); + } + else { + diag_printf("%s: Unknown interrupt: 0x%04x\n", + __FUNCTION__, event); + } + } +} + + +// EOF if_lan91cxx.c diff --git a/packages/devs/eth/smsc/lan91cxx/current/src/smsc_lan91cxx.h b/packages/devs/eth/smsc/lan91cxx/current/src/smsc_lan91cxx.h new file mode 100644 --- /dev/null +++ b/packages/devs/eth/smsc/lan91cxx/current/src/smsc_lan91cxx.h @@ -0,0 +1,314 @@ +#ifndef CYGONCE_DEVS_ETH_SMSC_LAN91CXX_LAN91CXX_H +#define CYGONCE_DEVS_ETH_SMSC_LAN91CXX_LAN91CXX_H +//========================================================================== +// +// lan91cxx.h +// +// SMCS LAN91C110 (LAN91CXX compatible) Ethernet chip +// +//========================================================================== +//####COPYRIGHTBEGIN#### +// +// ------------------------------------------- +// The contents of this file are subject to the Red Hat eCos Public License +// Version 1.1 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://www.redhat.com/ +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +// License for the specific language governing rights and limitations under +// the License. +// +// The Original Code is eCos - Embedded Configurable Operating System, +// released September 30, 1998. +// +// The Initial Developer of the Original Code is Red Hat. +// Portions created by Red Hat are +// Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc. +// All Rights Reserved. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +//####BSDCOPYRIGHTBEGIN#### +// +// ------------------------------------------- +// +// Portions of this software may have been derived from OpenBSD or other sources, +// and are covered by the appropriate copyright disclaimers included herein. +// +// ------------------------------------------- +// +//####BSDCOPYRIGHTEND#### +//========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): jskov +// Contributors: jskov, hmt +// Date: 2001-01-22 +// Purpose: Hardware description of LAN9000 series, LAN91C96/110. +// Description: +// +//####DESCRIPTIONEND#### +// +//========================================================================== + +#include + + +#define LAN91CXX_TCR 0x00 +#define LAN91CXX_EPH_STATUS 0x01 +#define LAN91CXX_RCR 0x02 +#define LAN91CXX_COUNTER 0x03 +#define LAN91CXX_MIR 0x04 +#define LAN91CXX_MCR 0x05 +#define LAN91CXX_RESERVED_0 0x06 +#define LAN91CXX_BS 0x07 +#define LAN91CXX_CONFIG 0x08 +#define LAN91CXX_BASE_REG 0x09 +#define LAN91CXX_IA01 0x0a +#define LAN91CXX_IA23 0x0b +#define LAN91CXX_IA45 0x0c +#define LAN91CXX_GENERAL 0x0d // 91C96 - was "RESERVED_1" for others +#define LAN91CXX_CONTROL 0x0e +#define LAN91CXX_BS2 0x0f +#define LAN91CXX_MMU_COMMAND 0x10 +#define LAN91CXX_PNR 0x11 +#define LAN91CXX_FIFO_PORTS 0x12 +#define LAN91CXX_POINTER 0x13 +#define LAN91CXX_DATA_HIGH 0x14 +#define LAN91CXX_DATA 0x15 +#define LAN91CXX_INTERRUPT 0x16 +#define LAN91CXX_BS3 0x17 +#define LAN91CXX_MT01 0x18 +#define LAN91CXX_MT23 0x19 +#define LAN91CXX_MT45 0x1a +#define LAN91CXX_MT67 0x1b +#define LAN91CXX_MGMT 0x1c +#define LAN91CXX_REVISION 0x1d +#define LAN91CXX_ERCV 0x1e +#define LAN91CXX_BS4 0x1f + +#define LAN91CXX_RCR_SOFT_RST 0x8000 // soft reset +#define LAN91CXX_RCR_FILT_CAR 0x4000 // filter carrier +#define LAN91CXX_RCR_ABORT_ENB 0x2000 // abort on collision +#define LAN91CXX_RCR_STRIP_CRC 0x0200 // strip CRC +#define LAN91CXX_RCR_RXEN 0x0100 // enable RX +#define LAN91CXX_RCR_ALMUL 0x0004 // receive all muticasts +#define LAN91CXX_RCR_PRMS 0x0002 // promiscuous +#define LAN91CXX_RCR_RX_ABORT 0x0001 // set when abort due to long frame + +#define LAN91CXX_TCR_SWFDUP 0x8000 // Switched Full Duplex mode +#define LAN91CXX_TCR_ETEN_TYPE 0x4000 // ETEN type (91C96) 0 <=> like a 91C94 +#define LAN91CXX_TCR_EPH_LOOP 0x2000 // loopback mode +#define LAN91CXX_TCR_STP_SQET 0x1000 // Stop transmission on SQET error +#define LAN91CXX_TCR_FDUPLX 0x0800 // full duplex +#define LAN91CXX_TCR_MON_CSN 0x0400 // monitor carrier during tx (91C96) +#define LAN91CXX_TCR_NOCRC 0x0100 // does not append CRC to frames +#define LAN91CXX_TCR_PAD_EN 0x0080 // pads frames with 00 to min length +#define LAN91CXX_TCR_FORCOL 0x0004 // force collision +#define LAN91CXX_TCR_LLOOP 0x0002 // local loopback (91C96) +#define LAN91CXX_TCR_TXENA 0x0001 // enable + +#define LAN91CXX_POINTER_RCV 0x8000 +#define LAN91CXX_POINTER_AUTO_INCR 0x4000 +#define LAN91CXX_POINTER_READ 0x2000 +#define LAN91CXX_POINTER_ETEN 0x1000 +#define LAN91CXX_POINTER_NOT_EMPTY 0x0800 + + +#define LAN91CXX_INTERRUPT_TX_IDLE_M 0x8000 // (91C96) +#define LAN91CXX_INTERRUPT_ERCV_INT_M 0x4000 +#define LAN91CXX_INTERRUPT_EPH_INT_M 0x2000 +#define LAN91CXX_INTERRUPT_RX_OVRN_INT_M 0x1000 +#define LAN91CXX_INTERRUPT_ALLOC_INT_M 0x0800 +#define LAN91CXX_INTERRUPT_TX_EMPTY_INT_M 0x0400 +#define LAN91CXX_INTERRUPT_TX_INT_M 0x0200 +#define LAN91CXX_INTERRUPT_RCV_INT_M 0x0100 +#define LAN91CXX_INTERRUPT_TX_IDLE 0x0080 // (91C96) +#define LAN91CXX_INTERRUPT_ERCV_INT 0x0040 // also ack +#define LAN91CXX_INTERRUPT_EPH_INT 0x0020 +#define LAN91CXX_INTERRUPT_RX_OVRN_INT 0x0010 // also ack +#define LAN91CXX_INTERRUPT_ALLOC_INT 0x0008 +#define LAN91CXX_INTERRUPT_TX_EMPTY_INT 0x0004 // also ack +#define LAN91CXX_INTERRUPT_TX_INT 0x0002 // also ack +#define LAN91CXX_INTERRUPT_RCV_INT 0x0001 + +#if 0 // Whichever we choose, the behaviour is the same. +#define LAN91CXX_INTERRUPT_TX_SET 0x0002 // TX +#define LAN91CXX_INTERRUPT_TX_SET_ACK 0x0000 // -none- +#define LAN91CXX_INTERRUPT_TX_FIFO_ACK 0x0002 // TX alone +#define LAN91CXX_INTERRUPT_TX_SET_M 0x0200 // TX alone +#else +#define LAN91CXX_INTERRUPT_TX_SET 0x0006 // TX_EMPTY + TX +#define LAN91CXX_INTERRUPT_TX_SET_ACK 0x0004 // TX_EMPTY and not plain TX +#define LAN91CXX_INTERRUPT_TX_FIFO_ACK 0x0002 // TX alone +#define LAN91CXX_INTERRUPT_TX_SET_M 0x0600 // TX_EMPTY + TX +#endif + +#define LAN91CXX_CONTROL_RCV_BAD 0x4000 +#define LAN91CXX_CONTROL_AUTO_RELEASE 0x0800 +#define LAN91CXX_CONTROL_LE_ENABLE 0x0080 +#define LAN91CXX_CONTROL_CR_ENABLE 0x0040 +#define LAN91CXX_CONTROL_TE_ENABLE 0x0020 + +// These are for setting the MAC address in the 91C96 serial EEPROM +#define LAN91CXX_CONTROL_EEPROM_SELECT 0x0004 +#define LAN91CXX_CONTROL_RELOAD 0x0002 +#define LAN91CXX_CONTROL_STORE 0x0001 +#define LAN91CXX_CONTROL_EEPROM_BUSY 0x0003 +#define LAN91CXX_ESA_EEPROM_OFFSET 0x0020 + +#define LAN91CXX_STATUS_TX_UNRN 0x8000 +#define LAN91CXX_STATUS_LINK_OK 0x4000 +#define LAN91CXX_STATUS_CTR_ROL 0x1000 +#define LAN91CXX_STATUS_EXC_DEF 0x0800 +#define LAN91CXX_STATUS_LOST_CARR 0x0400 +#define LAN91CXX_STATUS_LATCOL 0x0200 +#define LAN91CXX_STATUS_WAKEUP 0x0100 +#define LAN91CXX_STATUS_TX_DEFR 0x0080 +#define LAN91CXX_STATUS_LTX_BRD 0x0040 +#define LAN91CXX_STATUS_SQET 0x0020 +#define LAN91CXX_STATUS_16COL 0x0010 +#define LAN91CXX_STATUS_LTX_MULT 0x0008 +#define LAN91CXX_STATUS_MUL_COL 0x0004 +#define LAN91CXX_STATUS_SNGL_COL 0x0002 +#define LAN91CXX_STATUS_TX_SUC 0x0001 + +#define LAN91CXX_MMU_noop 0x0000 +#define LAN91CXX_MMU_alloc_for_tx 0x0020 +#define LAN91CXX_MMU_reset_mmu 0x0040 +#define LAN91CXX_MMU_rem_rx_frame 0x0060 +#define LAN91CXX_MMU_rem_tx_frame 0x0070 // (91C96) only when TX stopped +#define LAN91CXX_MMU_remrel_rx_frame 0x0080 +#define LAN91CXX_MMU_rel_packet 0x00a0 +#define LAN91CXX_MMU_enq_packet 0x00c0 +#define LAN91CXX_MMU_reset_tx_fifo 0x00e0 + +#define LAN91CXX_CONTROLBYTE_CRC 0x1000 +#define LAN91CXX_CONTROLBYTE_ODD 0x2000 +#define LAN91CXX_CONTROLBYTE_RX 0x4000 + +#define LAN91CXX_RX_STATUS_ALIGNERR 0x8000 +#define LAN91CXX_RX_STATUS_BCAST 0x4000 +#define LAN91CXX_RX_STATUS_BADCRC 0x2000 +#define LAN91CXX_RX_STATUS_ODDFRM 0x1000 +#define LAN91CXX_RX_STATUS_TOOLONG 0x0800 +#define LAN91CXX_RX_STATUS_TOOSHORT 0x0400 +#define LAN91CXX_RX_STATUS_HASHVALMASK 0x007e // MASK +#define LAN91CXX_RX_STATUS_MCAST 0x0001 + +// ------------------------------------------------------------------------ + +#ifdef KEEP_STATISTICS +struct smsc_lan91cxx_stats { + unsigned int tx_good ; + unsigned int tx_max_collisions ; + unsigned int tx_late_collisions ; + unsigned int tx_underrun ; + unsigned int tx_carrier_loss ; + unsigned int tx_deferred ; + unsigned int tx_sqetesterrors ; + unsigned int tx_single_collisions; + unsigned int tx_mult_collisions ; + unsigned int tx_total_collisions ; + unsigned int rx_good ; + unsigned int rx_crc_errors ; + unsigned int rx_align_errors ; + unsigned int rx_resource_errors ; + unsigned int rx_overrun_errors ; + unsigned int rx_collisions ; + unsigned int rx_short_frames ; + unsigned int rx_too_long_frames ; + unsigned int rx_symbol_errors ; + unsigned int interrupts ; + unsigned int rx_count ; + unsigned int rx_deliver ; + unsigned int rx_resource ; + unsigned int rx_restart ; + unsigned int tx_count ; + unsigned int tx_complete ; + unsigned int tx_dropped ; +}; +#endif + +typedef struct lan91cxx_priv_data { + int txbusy; // A packet has been sent + unsigned long txkey; // Used to ack when packet sent + unsigned short* base; // Base address of controller + // (as it comes out of reset) + int interrupt; // Interrupt vector used by controller + unsigned char enaddr[6]; // Controller ESA + // Function to configure the ESA - may fetch ESA from EPROM or + // RedBoot config option. + void (*config_enaddr)(struct lan91cxx_priv_data* cpd); + int txpacket; + int rxpacket; + int within_send; +#ifdef KEEP_STATISTICS + struct smsc_lan91cxx_stats stats; +#endif +} lan91cxx_priv_data; + +// ------------------------------------------------------------------------ + +static __inline__ unsigned short +get_reg(struct eth_drv_sc *sc, int regno) +{ + struct lan91cxx_priv_data *cpd = + (struct lan91cxx_priv_data *)sc->driver_private; + unsigned short val; + HAL_WRITE_UINT16(cpd->base+LAN91CXX_BS, regno>>3); + HAL_READ_UINT16(cpd->base+(regno&0x7), val); + +#if DEBUG & 2 + diag_printf("read reg %d val 0x%04x\n", regno, val); +#endif + return val; +} + +static __inline__ void +put_reg(struct eth_drv_sc *sc, int regno, unsigned short val) +{ + struct lan91cxx_priv_data *cpd = + (struct lan91cxx_priv_data *)sc->driver_private; + HAL_WRITE_UINT16(cpd->base+LAN91CXX_BS, regno>>3); + HAL_WRITE_UINT16(cpd->base+(regno&0x7), val); + +#if DEBUG & 2 + diag_printf("write reg %d val 0x%04x\n", regno, val); +#endif +} + +// ------------------------------------------------------------------------ +// Assumes bank2 has been selected +static __inline__ void +put_data(struct eth_drv_sc *sc, unsigned short val) +{ + struct lan91cxx_priv_data *cpd = + (struct lan91cxx_priv_data *)sc->driver_private; + HAL_WRITE_UINT16(cpd->base+(LAN91CXX_DATA & 0x7), val); + +#if DEBUG & 2 + diag_printf("write data 0x%04x\n", val); +#endif +} + +// Assumes bank2 has been selected +static __inline__ unsigned short +get_data(struct eth_drv_sc *sc) +{ + unsigned short val; + struct lan91cxx_priv_data *cpd = + (struct lan91cxx_priv_data *)sc->driver_private; + HAL_READ_UINT16(cpd->base+(LAN91CXX_DATA & 0x7), val); + +#if DEBUG & 2 + diag_printf("read data 0x%04x\n", val); +#endif + return val; +} + +// ------------------------------------------------------------------------ +#endif CYGONCE_DEVS_ETH_SMSC_LAN91CXX_LAN91CXX_H +// EOF smsc_lan91cxx.h diff --git a/packages/devs/flash/amd/am29f040b/current/ChangeLog b/packages/devs/flash/amd/am29f040b/current/ChangeLog deleted file mode 100644 --- a/packages/devs/flash/amd/am29f040b/current/ChangeLog +++ /dev/null @@ -1,62 +0,0 @@ -2000-12-07 Jesper Skov - - * src/flash.h: Addresses and sizes are also affected by - interleaving. - * src/flash_erase_block.c: Plug in working loop. - * src/flash_program_buf.c: Same. - -2000-12-06 Jesper Skov - - * src/am29f040b_flash.c (flash_hwr_init): Use new query semantics. - * src/flash_query.c (flash_query): Changed accordingly. - - * src/flash.h (FLASH_Sector_Erase_Timer): Added. - - * src/flash_erase_block.c: Do not check error flag after operation - completes. - * src/flash_program_buf.c: Same. - -2000-12-05 Jonathan Larmour - - * src/am29f040b_flash.c (flash_code_overlaps): Define stext/etext - as array types so no assumptions can be made by the compiler about - location. - -2000-12-05 Jesper Skov - - * Cloned from MBX driver. - -2000-10-20 Gary Thomas - - * src/mbx_flash.c: - * src/flash_query.c: - * src/flash_program_buf.c: - * src/flash_erase_block.c: - * src/flash.h: - * cdl/flash_mbx.cdl: New package/file(s). - -//=========================================================================== -//####COPYRIGHTBEGIN#### -// -// ------------------------------------------- -// The contents of this file are subject to the Red Hat eCos Public License -// Version 1.1 (the "License"); you may not use this file except in -// compliance with the License. You may obtain a copy of the License at -// http://www.redhat.com/ -// -// Software distributed under the License is distributed on an "AS IS" -// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the -// License for the specific language governing rights and limitations under -// the License. -// -// The Original Code is eCos - Embedded Configurable Operating System, -// released September 30, 1998. -// -// The Initial Developer of the Original Code is Red Hat. -// Portions created by Red Hat are -// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. -// All Rights Reserved. -// ------------------------------------------- -// -//####COPYRIGHTEND#### -//=========================================================================== diff --git a/packages/devs/flash/amd/am29f040b/current/cdl/flash_amd_am29f040b.cdl b/packages/devs/flash/amd/am29f040b/current/cdl/flash_amd_am29f040b.cdl deleted file mode 100644 --- a/packages/devs/flash/amd/am29f040b/current/cdl/flash_amd_am29f040b.cdl +++ /dev/null @@ -1,92 +0,0 @@ -# ==================================================================== -# -# flash_amd_am29f040b.cdl -# -# FLASH memory - Hardware support for AMD AM29F040B -# -# ==================================================================== -#####COPYRIGHTBEGIN#### -# -# ------------------------------------------- -# The contents of this file are subject to the Red Hat eCos Public License -# Version 1.1 (the "License"); you may not use this file except in -# compliance with the License. You may obtain a copy of the License at -# http://www.redhat.com/ -# -# Software distributed under the License is distributed on an "AS IS" -# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the -# License for the specific language governing rights and limitations under -# the License. -# -# The Original Code is eCos - Embedded Configurable Operating System, -# released September 30, 1998. -# -# The Initial Developer of the Original Code is Red Hat. -# Portions created by Red Hat are -# Copyright (C) 1998, 1999, 2000 Red Hat, Inc. -# All Rights Reserved. -# ------------------------------------------- -# -#####COPYRIGHTEND#### -# ==================================================================== -######DESCRIPTIONBEGIN#### -# -# Author(s): gthomas -# Contributors: gthomas, jskov -# Date: 2000-12-05 -# -#####DESCRIPTIONEND#### -# -# ==================================================================== - -cdl_package CYGPKG_DEVS_FLASH_AMD_AM29F040B { - display "AMD AM29F040B FLASH memory support" - description "FLASH memory device support for AMD AM29F040B" - parent CYGPKG_IO_FLASH - active_if CYGPKG_IO_FLASH - - active_if CYGINT_DEVS_FLASH_AMD_AM29F040B_REQUIRED - - implements CYGHWR_IO_FLASH_DEVICE - - include_dir . - include_files ; # none _exported_ whatsoever - - compile am29f040b_flash.c - - define_proc { - puts $::cdl_header "#include "; - puts $::cdl_header "#include CYGDAT_DEVS_FLASH_AMD_AM29F040B_CFG"; - } - - make -priority 1 { - flash_query.o: $(REPOSITORY)/$(PACKAGE)/src/flash_query.c - $(CC) -S $(INCLUDE_PATH) -mips2 -EB -fno-function-sections $(REPOSITORY)/$(PACKAGE)/src/flash_query.c - echo "#include " > flash_query2.S - cat flash_query.s >> flash_query2.S - echo "FUNC_END(flash_query_end)" >>flash_query2.S - $(CC) -c $(INCLUDE_PATH) -mips2 -EB -G0 -o flash_query.o flash_query2.S - $(AR) rcs $(PREFIX)/lib/libtarget.a flash_query.o - } - - make -priority 1 { - flash_erase_block.o: $(REPOSITORY)/$(PACKAGE)/src/flash_erase_block.c - $(CC) -S $(INCLUDE_PATH) -mips2 -EB -fno-function-sections $(REPOSITORY)/$(PACKAGE)/src/flash_erase_block.c - echo "#include " > flash_erase_block2.S - cat flash_erase_block.s >> flash_erase_block2.S - echo "FUNC_END(flash_erase_block_end)" >>flash_erase_block2.S - $(CC) -c $(INCLUDE_PATH) -mips2 -EB -G0 -o flash_erase_block.o flash_erase_block2.S - $(AR) rcs $(PREFIX)/lib/libtarget.a flash_erase_block.o - } - - make -priority 1 { - flash_program_buf.o: $(REPOSITORY)/$(PACKAGE)/src/flash_program_buf.c - $(CC) -S $(INCLUDE_PATH) -mips2 -EB -fno-function-sections $(REPOSITORY)/$(PACKAGE)/src/flash_program_buf.c - echo "#include " > flash_program_buf2.S - cat flash_program_buf.s >> flash_program_buf2.S - echo "FUNC_END(flash_program_buf_end)" >>flash_program_buf2.S - $(CC) -c $(INCLUDE_PATH) -mips2 -EB -G0 -o flash_program_buf.o flash_program_buf2.S - $(AR) rcs $(PREFIX)/lib/libtarget.a flash_program_buf.o - } -} - diff --git a/packages/devs/flash/amd/am29f040b/current/src/am29f040b_flash.c b/packages/devs/flash/amd/am29f040b/current/src/am29f040b_flash.c deleted file mode 100644 --- a/packages/devs/flash/amd/am29f040b/current/src/am29f040b_flash.c +++ /dev/null @@ -1,105 +0,0 @@ -//========================================================================== -// -// am29f040b_flash.c -// -// Flash programming -// -//========================================================================== -//####COPYRIGHTBEGIN#### -// -// ------------------------------------------- -// The contents of this file are subject to the Red Hat eCos Public License -// Version 1.1 (the "License"); you may not use this file except in -// compliance with the License. You may obtain a copy of the License at -// http://www.redhat.com/ -// -// Software distributed under the License is distributed on an "AS IS" -// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the -// License for the specific language governing rights and limitations under -// the License. -// -// The Original Code is eCos - Embedded Configurable Operating System, -// released September 30, 1998. -// -// The Initial Developer of the Original Code is Red Hat. -// Portions created by Red Hat are -// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. -// All Rights Reserved. -// ------------------------------------------- -// -//####COPYRIGHTEND#### -//========================================================================== -//#####DESCRIPTIONBEGIN#### -// -// Author(s): gthomas -// Contributors: gthomas, jskov -// Date: 2000-12-05 -// Purpose: -// Description: -// -//####DESCRIPTIONEND#### -// -//========================================================================== - -#include -#include -#include - -#define _FLASH_PRIVATE_ -#include - -#include "flash.h" - -static flash_data_t id[2*CYGHWR_FLASH_INTERLEAVE]; - -int -flash_hwr_init(void) -{ - flash_dev_query(&id); -#if 0 - dump_buf(id, sizeof(id)); -#endif - - // Check that flash_id data is valid - use to set up sizes etc. - - // Hard wired for now - flash_info.block_size = FLASH_BLOCK_SIZE * CYGHWR_FLASH_INTERLEAVE; - flash_info.blocks = FLASH_NUM_REGIONS; - flash_info.start = (void *)CYGHWR_FLASH_BASE; - flash_info.end = (void *)(CYGHWR_FLASH_BASE+ (FLASH_NUM_REGIONS * FLASH_BLOCK_SIZE * CYGHWR_FLASH_INTERLEAVE * CYGHWR_FLASH_SERIES)); - return FLASH_ERR_OK; -} - -// Map a hardware status to a package error -int -flash_hwr_map_error(int e) -{ - flash_data_t err = (flash_data_t) e; - - if (err & (FLASH_Err | FLASH_Drv_Verify_Err)) { - if ((err & FLASH_Drv_Verify_Err) == FLASH_Drv_Verify_Err) { - return FLASH_ERR_DRV_VERIFY; - } else - if (err & FLASH_Err) { - // FIXME: Can't tell error type from status word. Should - // we keep an internal driver state with that that - // information? - return FLASH_ERR_HWR; - } - return FLASH_ERR_HWR; - } else { - return FLASH_ERR_OK; - } -} - -// See if a range of FLASH addresses overlaps currently running code -bool -flash_code_overlaps(void *start, void *end) -{ - extern unsigned char _stext[], _etext[]; - - return ((((unsigned long)&_stext >= (unsigned long)start) && - ((unsigned long)&_stext < (unsigned long)end)) || - (((unsigned long)&_etext >= (unsigned long)start) && - ((unsigned long)&_etext < (unsigned long)end))); -} diff --git a/packages/devs/flash/amd/am29f040b/current/src/flash.h b/packages/devs/flash/amd/am29f040b/current/src/flash.h deleted file mode 100644 --- a/packages/devs/flash/amd/am29f040b/current/src/flash.h +++ /dev/null @@ -1,128 +0,0 @@ -#ifndef CYGONCE_FLASH_AMD_AM29F040B_H -#define CYGONCE_FLASH_AMD_AM29F040B_H -//========================================================================== -// -// flash.h -// -// Flash programming - device constants, etc. -// -//========================================================================== -//####COPYRIGHTBEGIN#### -// -// ------------------------------------------- -// The contents of this file are subject to the Red Hat eCos Public License -// Version 1.1 (the "License"); you may not use this file except in -// compliance with the License. You may obtain a copy of the License at -// http://www.redhat.com/ -// -// Software distributed under the License is distributed on an "AS IS" -// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the -// License for the specific language governing rights and limitations under -// the License. -// -// The Original Code is eCos - Embedded Configurable Operating System, -// released September 30, 1998. -// -// The Initial Developer of the Original Code is Red Hat. -// Portions created by Red Hat are -// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. -// All Rights Reserved. -// ------------------------------------------- -// -//####COPYRIGHTEND#### -//========================================================================== -//#####DESCRIPTIONBEGIN#### -// -// Author(s): gthomas -// Contributors: gthomas -// Date: 2000-10-20 -// Purpose: -// Description: -// -//####DESCRIPTIONEND#### -// -//========================================================================== - -#include // cyg_ types -#include // HAL_READ/WRITE macros - -// Platform specific details -#include CYGDAT_DEVS_FLASH_AMD_AM29F040B_INL - -#define FLASH_Read_ID 0x90 -#define FLASH_Reset 0xFF -#define FLASH_Program 0xA0 -#define FLASH_Block_Erase 0x30 - -#define FLASH_Busy 0x40 // "Toggle" bit -#define FLASH_Err 0x20 -#define FLASH_Sector_Erase_Timer 0x08 -#define FLASH_Drv_Verify_Err 0xff - -#define FLASH_Setup_Addr1 (0x555*CYGHWR_FLASH_INTERLEAVE) -#define FLASH_Setup_Addr2 (0x2AA*CYGHWR_FLASH_INTERLEAVE) -#define FLASH_Setup_Code1 0xAA -#define FLASH_Setup_Code2 0x55 -#define FLASH_Setup_Erase 0x80 - -#define FLASH_BLOCK_SIZE (0x10000*CYGHWR_FLASH_INTERLEAVE) -#define FLASH_NUM_REGIONS 8 - -#define FLASH_DEVICE_SIZE (FLASH_BLOCK_SIZE*FLASH_NUM_REGIONS) - -#define CYGHWR_FLASH_WIDTH 8 - - -//---------------------------------------------------------------------------- -// Macros for accessing mutiple flash devices (interleaved or in series) in -// a consistent way. - -#if (CYGHWR_FLASH_WIDTH == 8) -#define FLASH_READ(_p_, _v_) HAL_READ_UINT8(_p_, _v_) -#define FLASH_WRITE(_p_, _v_) HAL_WRITE_UINT8(_p_, _v_) -typedef cyg_uint8 flash_data_t; -#elif (CYGHWR_FLASH_WIDTH == 16) -#define FLASH_READ(_p_, _v_) HAL_READ_UINT16(_p_, _v_) -#define FLASH_WRITE(_p_, _v_) HAL_WRITE_UINT16(_p_, _v_) -typedef cyg_uint16 flash_data_t; -#elif (CYGHWR_FLASH_WIDTH == 32) -#define FLASH_READ(_p_, _v_) HAL_READ_UINT32(_p_, _v_) -#define FLASH_WRITE(_p_, _v_) HAL_WRITE_UINT32(_p_, _v_) -typedef cyg_uint32 flash_data_t; -#else -# error "Unsupported flash width" -#endif - -#define CYGHWR_FLASH_DEVICES (CYGHWR_FLASH_INTERLEAVE*CYGHWR_FLASH_SERIES) - -// Driver must use the FLASH_CMD_READ/WRITE macros to access devices. This -// will ensure that interleaved devices are properly accessed/programmed. -// However, the driver must handle devices in series itself - otherwise -// it wouldn't be possible to properly control block-specific commands. - -// Note that the _READ macro takes a pointer argument to where data -// read from the device(s) is stored. - -// Note that _p_, and _d_ must be of type flash_data_t*, and _c_ must -// be of type flash_data_t. - -#define FLASH_DATA_READ(_p_, _d_) \ - CYG_MACRO_START \ - int __i; \ - for (__i = 0; __i < CYGHWR_FLASH_INTERLEAVE; __i++) \ - FLASH_READ((_p_)+__i, *((_d_)+__i)); \ - CYG_MACRO_END -#define FLASH_DATA_WRITE(_p_, _d_) \ - CYG_MACRO_START \ - int __i; \ - for (__i = 0; __i < CYGHWR_FLASH_INTERLEAVE; __i++) \ - FLASH_WRITE((_p_)+__i, *((_d_)+__i)); \ - CYG_MACRO_END -#define FLASH_CMD_WRITE(_p_, _c_) \ - CYG_MACRO_START \ - int __i; \ - for (__i = 0; __i < CYGHWR_FLASH_INTERLEAVE; __i++) \ - FLASH_WRITE((_p_)+__i, (_c_)); \ - CYG_MACRO_END - -#endif // CYGONCE_FLASH_AMD_AM29F040B_H diff --git a/packages/devs/flash/amd/am29f040b/current/src/flash_erase_block.c b/packages/devs/flash/amd/am29f040b/current/src/flash_erase_block.c deleted file mode 100644 --- a/packages/devs/flash/amd/am29f040b/current/src/flash_erase_block.c +++ /dev/null @@ -1,158 +0,0 @@ -//========================================================================== -// -// flash_erase_block.c -// -// Flash programming -// -//========================================================================== -//####COPYRIGHTBEGIN#### -// -// ------------------------------------------- -// The contents of this file are subject to the Red Hat eCos Public License -// Version 1.1 (the "License"); you may not use this file except in -// compliance with the License. You may obtain a copy of the License at -// http://www.redhat.com/ -// -// Software distributed under the License is distributed on an "AS IS" -// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the -// License for the specific language governing rights and limitations under -// the License. -// -// The Original Code is eCos - Embedded Configurable Operating System, -// released September 30, 1998. -// -// The Initial Developer of the Original Code is Red Hat. -// Portions created by Red Hat are -// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. -// All Rights Reserved. -// ------------------------------------------- -// -//####COPYRIGHTEND#### -//========================================================================== -//#####DESCRIPTIONBEGIN#### -// -// Author(s): gthomas -// Contributors: gthomas, jskov -// Date: 2000-12-05 -// Purpose: -// Description: -// -//####DESCRIPTIONEND#### -// -//========================================================================== - -#include "flash.h" - -#include -#include -#include - -// -// CAUTION! This code must be copied to RAM before execution. Therefore, -// it must not contain any code which might be position dependent! -// - -int flash_erase_block(volatile flash_data_t *block) -{ - volatile flash_data_t *ROM; - int timeout = 50000; - int len; - int fail = 0; - flash_data_t array1[CYGHWR_FLASH_INTERLEAVE]; - flash_data_t array2[CYGHWR_FLASH_INTERLEAVE]; - flash_data_t *state, *new_state, *tmp_state; - - ROM = (volatile flash_data_t*)((unsigned long)block & ~(FLASH_DEVICE_SIZE-1)); - -#if 1 // So much for my good intentions - { - int erase_state2, new_state2; - - // Erase block - six step sequence - ROM[FLASH_Setup_Addr1] = FLASH_Setup_Code1; - ROM[FLASH_Setup_Addr2] = FLASH_Setup_Code2; - ROM[FLASH_Setup_Addr1] = FLASH_Setup_Erase; - ROM[FLASH_Setup_Addr1] = FLASH_Setup_Code1; - ROM[FLASH_Setup_Addr2] = FLASH_Setup_Code2; - *block = FLASH_Block_Erase; - for (timeout = 50; timeout--; timeout > 0) ; - erase_state2 = *block & FLASH_Busy; - timeout = 5000000; - while (true) { - new_state2 = *block; - if ((new_state2 & FLASH_Busy) == erase_state2) break; // "toggle" stopped - erase_state2 = new_state2 & FLASH_Busy; - if (new_state2 & FLASH_Err) break; - if (--timeout == 0) break; - } - - // Restore ROM to "normal" mode - ROM[0] = FLASH_Reset; - } -#else - // Erase block - six step sequence - FLASH_CMD_WRITE(ROM+FLASH_Setup_Addr1, FLASH_Setup_Code1); - FLASH_CMD_WRITE(ROM+FLASH_Setup_Addr2, FLASH_Setup_Code2); - FLASH_CMD_WRITE(ROM+FLASH_Setup_Addr1, FLASH_Setup_Erase); - FLASH_CMD_WRITE(ROM+FLASH_Setup_Addr1, FLASH_Setup_Code1); - FLASH_CMD_WRITE(ROM+FLASH_Setup_Addr2, FLASH_Setup_Code2); - FLASH_CMD_WRITE(block, FLASH_Block_Erase); - - state = array1; - new_state = array2; - - // Now poll for the completion of the sector erase timer (50us) - timeout = 5000000; // how many retries? - while (true) { - int i; - int done = 1; - - FLASH_DATA_READ(block, state); - for (i = 0; i < CYGHWR_FLASH_INTERLEAVE; i++) { - if (0 == (state[i] & FLASH_Sector_Erase_Timer)) - done = 0; - } - - if (done) break; // sector erase timers completed - if (--timeout == 0) break; // too many tries without success - } - - FLASH_DATA_READ(block, state); - timeout = 5000000; // how many retries? - while (true) { - int i; - int done = 1; - - FLASH_DATA_READ(block, new_state); - for (i = 0; i < CYGHWR_FLASH_INTERLEAVE; i++) { - if ((new_state[i] & FLASH_Busy) != (state[i] & FLASH_Busy)) { - done = 0; - if (new_state[i] & FLASH_Err) - fail = FLASH_Err; - } - } - // Switch state arrays - tmp_state = state; - state = new_state; - new_state = state; - - if (done) break; // "toggle" stopped - if (fail) break; // device failure - if (--timeout == 0) break; // too many tries without success - } - FLASH_CMD_WRITE(ROM, FLASH_Reset); -#endif - if (!fail) { - // Verify erase operation - len = (FLASH_BLOCK_SIZE*CYGHWR_FLASH_INTERLEAVE); - while (len > 0) { - if (*block++ != 0xFF) { - fail = FLASH_Drv_Verify_Err; - break; - } - len -= sizeof(*block); - } - } - - return fail; -} diff --git a/packages/devs/flash/amd/am29f040b/current/src/flash_program_buf.c b/packages/devs/flash/amd/am29f040b/current/src/flash_program_buf.c deleted file mode 100644 --- a/packages/devs/flash/amd/am29f040b/current/src/flash_program_buf.c +++ /dev/null @@ -1,154 +0,0 @@ -//========================================================================== -// -// flash_program_buf.c -// -// Flash programming -// -//========================================================================== -//####COPYRIGHTBEGIN#### -// -// ------------------------------------------- -// The contents of this file are subject to the Red Hat eCos Public License -// Version 1.1 (the "License"); you may not use this file except in -// compliance with the License. You may obtain a copy of the License at -// http://www.redhat.com/ -// -// Software distributed under the License is distributed on an "AS IS" -// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the -// License for the specific language governing rights and limitations under -// the License. -// -// The Original Code is eCos - Embedded Configurable Operating System, -// released September 30, 1998. -// -// The Initial Developer of the Original Code is Red Hat. -// Portions created by Red Hat are -// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. -// All Rights Reserved. -// ------------------------------------------- -// -//####COPYRIGHTEND#### -//========================================================================== -//#####DESCRIPTIONBEGIN#### -// -// Author(s): gthomas -// Contributors: gthomas, jskov -// Date: 2000-12-05 -// Purpose: -// Description: -// -//####DESCRIPTIONEND#### -// -//========================================================================== - -#include "flash.h" - -#include -#include -#include - -// -// CAUTION! This code must be copied to RAM before execution. Therefore, -// it must not contain any code which might be position dependent! -// - -int -flash_program_buf(volatile flash_data_t *addr, flash_data_t *data, int len) -{ - volatile flash_data_t *ROM; - int timeout; - int fail = 0; - flash_data_t array1[CYGHWR_FLASH_INTERLEAVE]; - flash_data_t array2[CYGHWR_FLASH_INTERLEAVE]; - flash_data_t *state, *new_state, *tmp_state; - -#if 0 - CYG_ASSERT(data & (sizeof(flash_data_t)-1) == 0, - "Data not properly aligned"); - CYG_ASSERT(addr & (CYGHWR_FLASH_INTERLEAVE*sizeof(flash_data_t)-1) == 0, - "Addr not properly aligned (to first interleaved device)"); -#endif - - while (len > 0) { - int i; - - // Base address of device(s) being programmed. - ROM = (volatile flash_data_t*)((unsigned long)addr & ~(FLASH_DEVICE_SIZE-1)); - -#if 1 // So much for my good intentions - { - int erase_state2, new_state2; - - // Program data [byte] - 4 step sequence - ROM[FLASH_Setup_Addr1] = FLASH_Setup_Code1; - ROM[FLASH_Setup_Addr2] = FLASH_Setup_Code2; - ROM[FLASH_Setup_Addr1] = FLASH_Program; - *addr = *data; - for (timeout = 50; timeout--; timeout > 0) ; - erase_state2 = *addr & FLASH_Busy; - while (true) { - new_state2 = *addr; - if ((new_state2 & FLASH_Busy) == erase_state2) break; // "toggle" stopped - erase_state2 = new_state2 & FLASH_Busy; - if (new_state2 & FLASH_Err) break; - if (--timeout == 0) break; - } - ROM[0] = FLASH_Reset; - if (*addr++ != *data++) { - new_state2 = 0xFF; - break; - } - len -= sizeof(*data); - } - -#else - // Program data - 4 step sequence - FLASH_CMD_WRITE(ROM+FLASH_Setup_Addr1, FLASH_Setup_Code1); - FLASH_CMD_WRITE(ROM+FLASH_Setup_Addr2, FLASH_Setup_Code2); - FLASH_CMD_WRITE(ROM+FLASH_Setup_Addr1, FLASH_Program); - FLASH_DATA_WRITE(addr, data); - - state = array1; - new_state = array2; - - FLASH_DATA_READ(addr, state); - timeout = 5000000; // how many retries? - while (true) { - int i; - int done = 1; - - FLASH_DATA_READ(addr, new_state); - for (i = 0; i < CYGHWR_FLASH_INTERLEAVE; i++) { - if ((new_state[i] & FLASH_Busy) != (state[i] & FLASH_Busy)) { - done = 0; - if (new_state[i] & FLASH_Err) - fail = FLASH_Err; - } - } - // Switch state arrays - tmp_state = state; - state = new_state; - new_state = state; - - if (done) break; // "toggle" stopped - if (fail) break; // device failure - if (--timeout == 0) break; // too many tries without success - } - FLASH_CMD_WRITE(ROM, FLASH_Reset); - // We have state in 'state' now, use 'new_state' to verify data. - for (i = 0; i < CYGHWR_FLASH_INTERLEAVE; i++) { - if (*addr++ != *data++) { - state[i] = FLASH_Drv_Verify_Err; - fail = FLASH_Drv_Verify_Err; - } - } - if (fail) break; - - len -= sizeof(flash_data_t) * CYGHWR_FLASH_INTERLEAVE; -#endif - } - - // Ideally, we'd want to return not only the failure code, but also - // the address/device that reported the error. - return fail; -} diff --git a/packages/devs/flash/amd/am29f040b/current/src/flash_query.c b/packages/devs/flash/amd/am29f040b/current/src/flash_query.c deleted file mode 100644 --- a/packages/devs/flash/amd/am29f040b/current/src/flash_query.c +++ /dev/null @@ -1,80 +0,0 @@ -//========================================================================== -// -// flash_query.c -// -// Flash programming - query device -// -//========================================================================== -//####COPYRIGHTBEGIN#### -// -// ------------------------------------------- -// The contents of this file are subject to the Red Hat eCos Public License -// Version 1.1 (the "License"); you may not use this file except in -// compliance with the License. You may obtain a copy of the License at -// http://www.redhat.com/ -// -// Software distributed under the License is distributed on an "AS IS" -// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the -// License for the specific language governing rights and limitations under -// the License. -// -// The Original Code is eCos - Embedded Configurable Operating System, -// released September 30, 1998. -// -// The Initial Developer of the Original Code is Red Hat. -// Portions created by Red Hat are -// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. -// All Rights Reserved. -// ------------------------------------------- -// -//####COPYRIGHTEND#### -//========================================================================== -//#####DESCRIPTIONBEGIN#### -// -// Author(s): gthomas -// Contributors: gthomas -// Date: 2000-10-20 -// Purpose: -// Description: -// -//####DESCRIPTIONEND#### -// -//========================================================================== - -#include "flash.h" - -#include -#include -#include -#include CYGHWR_MEMORY_LAYOUT_H - -// -// CAUTION! This code must be copied to RAM before execution. Therefore, -// it must not contain any code which might be position dependent! -// - -// Only reads the manufacturer and part number codes for the first -// device(s) in series. It is assumed that any devices in series -// will be of the same type. - -void -flash_query(void* data) -{ - volatile flash_data_t *ROM; - flash_data_t* id = (flash_data_t*) data; - - ROM = (volatile flash_data_t*) CYGHWR_FLASH_BASE; - - FLASH_CMD_WRITE(ROM+FLASH_Setup_Addr1, FLASH_Setup_Code1); - FLASH_CMD_WRITE(ROM+FLASH_Setup_Addr2, FLASH_Setup_Code2); - FLASH_CMD_WRITE(ROM+FLASH_Setup_Addr1, FLASH_Read_ID); - - // Manufacturers' code - FLASH_DATA_READ(ROM, id); - // Part number - FLASH_DATA_READ(ROM+CYGHWR_FLASH_INTERLEAVE, &id[CYGHWR_FLASH_INTERLEAVE]); - - FLASH_CMD_WRITE(ROM, FLASH_Reset); - - return id; -} diff --git a/packages/devs/flash/amd/am29xxxxx/current/ChangeLog b/packages/devs/flash/amd/am29xxxxx/current/ChangeLog --- a/packages/devs/flash/amd/am29xxxxx/current/ChangeLog +++ b/packages/devs/flash/amd/am29xxxxx/current/ChangeLog @@ -1,3 +1,23 @@ +2001-05-29 Jesper Skov + + * include/flash_am29xxxxx.inl (flash_hwr_init): Call platform init + code if defined. + +2001-05-28 Jesper Skov + + * include/flash_am29xxxxx.inl: Rewritten to handle bootblock + parts, autodetect part and configure accordingly. + Fixed erase and program code to work with devices in parallel. + Fixed buglet in bootblock detect code. + +2001-05-23 Jesper Skov + + * cdl/flash_amd_am29xxxxx.cdl: Links function in RAM. IO driver + need not copy. + + * include/flash_am29xxxxx.inl: Check for WP before trying to erase + block. Use P2V macro. + 2001-02-23 Jesper Skov * include/flash_am29xxxxx.inl (flash_query): Allow device to diff --git a/packages/devs/flash/amd/am29xxxxx/current/cdl/flash_amd_am29xxxxx.cdl b/packages/devs/flash/amd/am29xxxxx/current/cdl/flash_amd_am29xxxxx.cdl --- a/packages/devs/flash/amd/am29xxxxx/current/cdl/flash_amd_am29xxxxx.cdl +++ b/packages/devs/flash/amd/am29xxxxx/current/cdl/flash_amd_am29xxxxx.cdl @@ -48,7 +48,6 @@ cdl_package CYGPKG_DEVS_FLASH_AMD_AM29XX active_if CYGINT_DEVS_FLASH_AMD_AM29XXXXX_REQUIRED implements CYGHWR_IO_FLASH_DEVICE - implements CYGHWR_IO_FLASH_DEVICE_IN_RAM include_dir cyg/io } diff --git a/packages/devs/flash/amd/am29xxxxx/current/include/flash_am29xxxxx.inl b/packages/devs/flash/amd/am29xxxxx/current/include/flash_am29xxxxx.inl --- a/packages/devs/flash/amd/am29xxxxx/current/include/flash_am29xxxxx.inl +++ b/packages/devs/flash/amd/am29xxxxx/current/include/flash_am29xxxxx.inl @@ -38,11 +38,21 @@ // Date: 2001-02-21 // Purpose: // Description: AMD AM29xxxxx series flash device driver -// Notes: While the parts support sector locking, this is controlled -// using a 12V source (on F parts anyway) - so it is left -// unimplemented for now. When it does get implemented, let -// the platform CDL control the availability of that feature. -// FIXME: Does not use FLASH_P2V +// Notes: While the parts support sector locking, some only do so +// via crufty magic and the use of programmer hardware +// (specifically by applying 12V to one of the address +// pins) so the driver does not support write protection. +// +// FIXME: Make support for specific devices CDL configurable. Make +// support for bootblock (and associated code/structs) +// configurable. +// +// FIXME: Should support SW locking on the newer devices. +// +// FIXME: Figure out how to do proper error checking when there are +// devices in parallel. Presently the driver will return +// driver timeout error on device errors which is not very +// helpful. // //####DESCRIPTIONEND#### // @@ -60,6 +70,7 @@ //---------------------------------------------------------------------------- // Common device details. #define FLASH_Read_ID FLASHWORD( 0x90 ) +#define FLASH_WP_State FLASHWORD( 0x90 ) #define FLASH_Reset FLASHWORD( 0xFF ) #define FLASH_Program FLASHWORD( 0xA0 ) #define FLASH_Block_Erase FLASHWORD( 0x30 ) @@ -69,6 +80,8 @@ #define FLASH_Err FLASHWORD( 0x20 ) #define FLASH_Sector_Erase_Timer FLASHWORD( 0x08 ) +#define FLASH_unlocked FLASHWORD( 0x00 ) + #define FLASH_Setup_Addr1 (0x555) #define FLASH_Setup_Addr2 (0x2AA) #define FLASH_Setup_Code1 FLASHWORD( 0xAA ) @@ -78,21 +91,17 @@ // Platform code must define the below // #define CYGNUM_FLASH_INTERLEAVE : Number of interleaved devices (in parallel) // #define CYGNUM_FLASH_SERIES : Number of devices in series +// #define CYGNUM_FLASH_WIDTH : Width of devices on platform // #define CYGNUM_FLASH_BASE : Address of first device -// And select one of the below device variants + +#define CYGNUM_FLASH_BLANK (1) -#ifdef CYGPKG_DEVS_FLASH_AMD_AM29F040B -# define FLASH_BLOCK_SIZE (0x10000*CYGNUM_FLASH_INTERLEAVE) -# define FLASH_NUM_REGIONS (8) -# define CYGNUM_FLASH_BASE_MASK (0xFFF80000u) // 512kB devices -# define CYGNUM_FLASH_WIDTH (8) -# define CYGNUM_FLASH_BLANK (1) -# define CYGNUM_FLASH_ID_MANUFACTURER FLASHWORD(0x01) -# define CYGNUM_FLASH_ID_DEVICE FLASHWORD(0xA4) +#ifndef FLASH_P2V +# define FLASH_P2V( _a_ ) ((volatile flash_data_t *)((CYG_ADDRWORD)(_a_))) #endif - -#define FLASH_DEVICE_SIZE (FLASH_BLOCK_SIZE*FLASH_NUM_REGIONS) -#define CYGNUM_FLASH_DEVICES (CYGNUM_FLASH_INTERLEAVE*CYGNUM_FLASH_SERIES) +#ifndef CYGHWR_FLASH_AM29XXXXX_PLF_INIT +# define CYGHWR_FLASH_AM29XXXXX_PLF_INIT() +#endif //---------------------------------------------------------------------------- // Now that device properties are defined, include magic for defining @@ -100,6 +109,95 @@ #include //---------------------------------------------------------------------------- +// Information about supported devices +typedef struct flash_dev_info { + flash_data_t device_id; + cyg_uint32 block_size; + cyg_int32 block_count; + cyg_uint32 base_mask; + cyg_uint32 device_size; + cyg_bool bootblock; + cyg_uint32 bootblocks[6]; // 0 is bootblock offset, 1-5 sub-sector sizes (or 0) +} flash_dev_info_t; + +static const flash_dev_info_t supported_devices[] = { +#if CYGNUM_FLASH_WIDTH == 8 + { + device_id : FLASHWORD(0xa4), + block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE, + block_count: 8, + device_size: 0x80000 * CYGNUM_FLASH_INTERLEAVE, + base_mask : ~(0x80000 * CYGNUM_FLASH_INTERLEAVE - 1), + bootblock : false + }, + { // MBM29LV160-T | AM29LV160-T + device_id : FLASHWORD(0xc4), + block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE, + block_count: 32, + device_size: 0x200000 * CYGNUM_FLASH_INTERLEAVE, + base_mask : ~(0x200000 * CYGNUM_FLASH_INTERLEAVE - 1), + bootblock : true, + bootblocks : { 0x1f0000 * CYGNUM_FLASH_INTERLEAVE, + 0x008000 * CYGNUM_FLASH_INTERLEAVE, + 0x002000 * CYGNUM_FLASH_INTERLEAVE, + 0x002000 * CYGNUM_FLASH_INTERLEAVE, + 0x004000 * CYGNUM_FLASH_INTERLEAVE, + 0 + } + }, + { // MBM29LV160-B | AM29LV160-B + device_id : FLASHWORD(0x49), + block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE, + block_count: 32, + device_size: 0x200000 * CYGNUM_FLASH_INTERLEAVE, + base_mask : ~(0x200000 * CYGNUM_FLASH_INTERLEAVE - 1), + bootblock : true, + bootblocks : { 0x000000 * CYGNUM_FLASH_INTERLEAVE, + 0x004000 * CYGNUM_FLASH_INTERLEAVE, + 0x002000 * CYGNUM_FLASH_INTERLEAVE, + 0x002000 * CYGNUM_FLASH_INTERLEAVE, + 0x008000 * CYGNUM_FLASH_INTERLEAVE, + 0 + } + } +#else // 16 bit devices + { // MBM29LV160-T | AM29LV160-T + device_id : FLASHWORD(0x22c4), + block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE, + block_count: 32, + device_size: 0x200000 * CYGNUM_FLASH_INTERLEAVE, + base_mask : ~(0x200000 * CYGNUM_FLASH_INTERLEAVE - 1), + bootblock : true, + bootblocks : { 0x1f0000 * CYGNUM_FLASH_INTERLEAVE, + 0x008000 * CYGNUM_FLASH_INTERLEAVE, + 0x002000 * CYGNUM_FLASH_INTERLEAVE, + 0x002000 * CYGNUM_FLASH_INTERLEAVE, + 0x004000 * CYGNUM_FLASH_INTERLEAVE, + 0 + } + }, + { // MBM29LV160-B | AM29LV160-B + device_id : FLASHWORD(0x2249), + block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE, + block_count: 32, + device_size: 0x200000 * CYGNUM_FLASH_INTERLEAVE, + base_mask : ~(0x200000 * CYGNUM_FLASH_INTERLEAVE - 1), + bootblock : true, + bootblocks : { 0x000000 * CYGNUM_FLASH_INTERLEAVE, + 0x004000 * CYGNUM_FLASH_INTERLEAVE, + 0x002000 * CYGNUM_FLASH_INTERLEAVE, + 0x002000 * CYGNUM_FLASH_INTERLEAVE, + 0x008000 * CYGNUM_FLASH_INTERLEAVE, + 0 + } + } +#endif +}; +#define NUM_DEVICES (sizeof(supported_devices)/sizeof(flash_dev_info_t)) + +static const flash_dev_info_t* flash_dev_info; + +//---------------------------------------------------------------------------- // Functions that put the flash device into non-read mode must reside // in RAM. void flash_query(void* data) __attribute__ ((section (".2ram.flash_query"))); @@ -119,24 +217,29 @@ void flash_query(void* data) { volatile flash_data_t *ROM; + volatile flash_data_t *f_s1, *f_s2; flash_data_t* id = (flash_data_t*) data; - int i; + flash_data_t w; - ROM = (volatile flash_data_t*) CYGNUM_FLASH_BASE; + ROM = (flash_data_t*) CYGNUM_FLASH_BASE; + f_s1 = FLASH_P2V(ROM+FLASH_Setup_Addr1); + f_s2 = FLASH_P2V(ROM+FLASH_Setup_Addr2); - ROM[FLASH_Setup_Addr1] = FLASH_Setup_Code1; - ROM[FLASH_Setup_Addr2] = FLASH_Setup_Code2; - ROM[FLASH_Setup_Addr1] = FLASH_Read_ID; + w = *(FLASH_P2V(ROM)); + + *f_s1 = FLASH_Setup_Code1; + *f_s2 = FLASH_Setup_Code2; + *f_s1 = FLASH_Read_ID; // Manufacturers' code - id[0] = ROM[0]; + id[0] = *(FLASH_P2V(ROM)); // Part number - id[1] = ROM[1]; + id[1] = *(FLASH_P2V(ROM+1)); - ROM[0] = FLASH_Reset; + *(FLASH_P2V(ROM)) = FLASH_Reset; - // Allow device to settle. - for (i = 500; i > 0; i--); + // Stall, waiting for flash to return to read mode. + while (w != *(FLASH_P2V(ROM))); } //---------------------------------------------------------------------------- @@ -145,20 +248,28 @@ int flash_hwr_init(void) { flash_data_t id[2]; + int i; + + CYGHWR_FLASH_AM29XXXXX_PLF_INIT(); flash_dev_query(id); - // Check that flash_id data is matching the one the driver was - // configured for. - if (id[0] != CYGNUM_FLASH_ID_MANUFACTURER - || id[1] != CYGNUM_FLASH_ID_DEVICE) + // Look through table for device data + flash_dev_info = supported_devices; + for (i = 0; i < NUM_DEVICES; i++) { + if (flash_dev_info->device_id == id[1]) + break; + } + + // Did we find the device? If not, return error. + if (NUM_DEVICES == i) return FLASH_ERR_DRV_WRONG_PART; // Hard wired for now - flash_info.block_size = FLASH_BLOCK_SIZE * CYGNUM_FLASH_INTERLEAVE; - flash_info.blocks = FLASH_NUM_REGIONS; + flash_info.block_size = flash_dev_info->block_size; + flash_info.blocks = flash_dev_info->block_count; flash_info.start = (void *)CYGNUM_FLASH_BASE; - flash_info.end = (void *)(CYGNUM_FLASH_BASE+ (FLASH_NUM_REGIONS * FLASH_BLOCK_SIZE * CYGNUM_FLASH_INTERLEAVE * CYGNUM_FLASH_SERIES)); + flash_info.end = (void *)(CYGNUM_FLASH_BASE+ (flash_dev_info->device_size * CYGNUM_FLASH_SERIES)); return FLASH_ERR_OK; } @@ -191,71 +302,98 @@ int flash_erase_block(void* block, unsigned int size) { volatile flash_data_t* ROM; - volatile flash_data_t* block_ptr = (volatile flash_data_t*) block; + volatile flash_data_t* b_p = (flash_data_t*) block; + volatile flash_data_t *b_v; + volatile flash_data_t *f_s1, *f_s2; int timeout = 50000; - int len; - flash_data_t res = FLASH_ERR_OK; - int state; - - ROM = (volatile flash_data_t*)((unsigned long)block & ~(FLASH_DEVICE_SIZE-1)); + int len, len_ix = 1; + int res = FLASH_ERR_OK; + flash_data_t state; + cyg_bool bootblock; - // Send erase block command - six step sequence - ROM[FLASH_Setup_Addr1] = FLASH_Setup_Code1; - ROM[FLASH_Setup_Addr2] = FLASH_Setup_Code2; - ROM[FLASH_Setup_Addr1] = FLASH_Setup_Erase; - ROM[FLASH_Setup_Addr1] = FLASH_Setup_Code1; - ROM[FLASH_Setup_Addr2] = FLASH_Setup_Code2; - *block_ptr = FLASH_Block_Erase; + ROM = (volatile flash_data_t*)((unsigned long)block & flash_dev_info->base_mask); + f_s1 = FLASH_P2V(ROM+FLASH_Setup_Addr1); + f_s2 = FLASH_P2V(ROM+FLASH_Setup_Addr2); - // Now poll for the completion of the sector erase timer (50us) - timeout = 5000000; // how many retries? - while (true) { - state = *block_ptr; - if ((state & FLASH_Sector_Erase_Timer) == 0) break; - if (state & FLASH_Err) { - res = FLASH_ERR_ERASE; - break; - } - if (--timeout == 0) { - res = FLASH_ERR_DRV_TIMEOUT; - break; - } + // Is this the boot sector? + bootblock = (flash_dev_info->bootblock && + (flash_dev_info->bootblocks[0] == ((unsigned long)block - (unsigned long)ROM))); + if (bootblock) { + len = flash_dev_info->bootblocks[len_ix++]; + } else { + len = flash_dev_info->block_size; } - // Then wait for erase completion. - if (FLASH_ERR_OK == res) { - timeout = 5000000; + while (len > 0) { + // First check whether the block is protected + *f_s1 = FLASH_Setup_Code1; + *f_s2 = FLASH_Setup_Code2; + *f_s1 = FLASH_WP_State; + state = *FLASH_P2V(b_p+2); + *FLASH_P2V(ROM) = FLASH_Reset; + + if (FLASH_unlocked != state) + return FLASH_ERR_PROTECT; + + b_v = FLASH_P2V(b_p); + + // Send erase block command - six step sequence + *f_s1 = FLASH_Setup_Code1; + *f_s2 = FLASH_Setup_Code2; + *f_s1 = FLASH_Setup_Erase; + *f_s1 = FLASH_Setup_Code1; + *f_s2 = FLASH_Setup_Code2; + *b_v = FLASH_Block_Erase; + + // Now poll for the completion of the sector erase timer (50us) + timeout = 5000000; // how many retries? while (true) { - state = *block_ptr; - if (FLASH_BlankValue == state) { - break; - } - if (state & FLASH_Err) { - res = FLASH_ERR_ERASE; - break; - } + state = *b_v; + if ((state & FLASH_Sector_Erase_Timer) == 0) break; + if (--timeout == 0) { res = FLASH_ERR_DRV_TIMEOUT; break; } } - } - if (FLASH_ERR_OK != res) - ROM[0] = FLASH_Reset; + // Then wait for erase completion. + if (FLASH_ERR_OK == res) { + timeout = 5000000; + while (true) { + state = *b_v; + if (FLASH_BlankValue == state) { + break; + } + + // Don't check for FLASH_Err here since it will fail + // with devices in parallel because these may finish + // at different times. - // Verify erase operation - len = (FLASH_BLOCK_SIZE*CYGNUM_FLASH_INTERLEAVE); - while (len > 0) { - if (*block_ptr != FLASH_BlankValue) { - // Only update return value if erase operation was OK - if (FLASH_ERR_OK == res) res = FLASH_ERR_DRV_VERIFY; - break; + if (--timeout == 0) { + res = FLASH_ERR_DRV_TIMEOUT; + break; + } + } } - block_ptr++; - len -= sizeof(*block_ptr); + + if (FLASH_ERR_OK != res) + *FLASH_P2V(ROM) = FLASH_Reset; + + // Verify erase operation + while (len > 0) { + b_v = FLASH_P2V(b_p++); + if (*b_v != FLASH_BlankValue) { + // Only update return value if erase operation was OK + if (FLASH_ERR_OK == res) res = FLASH_ERR_DRV_VERIFY; + return res; + } + len -= sizeof(*b_p); + } + + if (bootblock) + len = flash_dev_info->bootblocks[len_ix++]; } - return res; } @@ -266,41 +404,44 @@ int flash_program_buf(void* addr, void* data, int len) { volatile flash_data_t* ROM; - volatile flash_data_t* addr_ptr = (volatile flash_data_t*) addr; volatile flash_data_t* data_ptr = (volatile flash_data_t*) data; + volatile flash_data_t* addr_v; + volatile flash_data_t* addr_p = (flash_data_t*) addr; + volatile flash_data_t *f_s1, *f_s2; int timeout; int res = FLASH_ERR_OK; -#if 0 - CYG_ASSERT((unsigned long)data_ptr & (sizeof(flash_data_t)-1) == 0, - "Data not properly aligned"); - CYG_ASSERT((unsigned long)addr_ptr & (CYGNUM_FLASH_INTERLEAVE*sizeof(flash_data_t)-1) == 0, - "Addr not properly aligned (to first interleaved device)"); -#endif - while (len > 0) { int state; - // Base address of device(s) being programmed. - ROM = (volatile flash_data_t*)((unsigned long)addr & ~(FLASH_DEVICE_SIZE-1)); + // Note: Should really only do the address calculations on + // section/device boundaries - but then, we're likely to be + // spinning for a while down below anyway, so no point in + // making the loop more complicated. + + // Base address of device(s) being programmed. + ROM = (volatile flash_data_t*)((unsigned long)addr_p & flash_dev_info->base_mask); + f_s1 = FLASH_P2V(ROM+FLASH_Setup_Addr1); + f_s2 = FLASH_P2V(ROM+FLASH_Setup_Addr2); + addr_v = FLASH_P2V(addr_p++); // Program data [byte] - 4 step sequence - ROM[FLASH_Setup_Addr1] = FLASH_Setup_Code1; - ROM[FLASH_Setup_Addr2] = FLASH_Setup_Code2; - ROM[FLASH_Setup_Addr1] = FLASH_Program; - *addr_ptr = *data_ptr; + *f_s1 = FLASH_Setup_Code1; + *f_s2 = FLASH_Setup_Code2; + *f_s1 = FLASH_Program; + *addr_v = *data_ptr; timeout = 5000000; while (true) { - state = *addr_ptr; + state = *addr_v; if (*data_ptr == state) { break; } - if (state & FLASH_Err) { - res = FLASH_ERR_PROGRAM; - break; - } + + // Can't check for FLASH_Err since it'll fail in parallel + // configurations. + if (--timeout == 0) { res = FLASH_ERR_DRV_TIMEOUT; break; @@ -308,9 +449,9 @@ flash_program_buf(void* addr, void* data } if (FLASH_ERR_OK != res) - ROM[0] = FLASH_Reset; + *FLASH_P2V(ROM) = FLASH_Reset; - if (*addr_ptr++ != *data_ptr++) { + if (*addr_v != *data_ptr++) { // Only update return value if erase operation was OK if (FLASH_ERR_OK == res) res = FLASH_ERR_DRV_VERIFY; break; diff --git a/packages/devs/flash/arm/ebsa285/current/ChangeLog b/packages/devs/flash/arm/ebsa285/current/ChangeLog --- a/packages/devs/flash/arm/ebsa285/current/ChangeLog +++ b/packages/devs/flash/arm/ebsa285/current/ChangeLog @@ -1,3 +1,8 @@ +2001-05-23 Jesper Skov + + * cdl/flash_ebsa285.cdl: Needs IO controller to copy functions to + RAM. + 2000-12-05 Jonathan Larmour * src/ebsa285_flash.c (flash_code_overlaps): Define stext/etext diff --git a/packages/devs/flash/arm/ebsa285/current/cdl/flash_ebsa285.cdl b/packages/devs/flash/arm/ebsa285/current/cdl/flash_ebsa285.cdl --- a/packages/devs/flash/arm/ebsa285/current/cdl/flash_ebsa285.cdl +++ b/packages/devs/flash/arm/ebsa285/current/cdl/flash_ebsa285.cdl @@ -23,7 +23,7 @@ # # The Initial Developer of the Original Code is Red Hat. # Portions created by Red Hat are -# Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +# Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc. # All Rights Reserved. # ------------------------------------------- # @@ -48,6 +48,7 @@ cdl_package CYGPKG_DEVS_FLASH_EBSA285 { requires CYGPKG_HAL_ARM_EBSA285 implements CYGHWR_IO_FLASH_DEVICE + implements CYGHWR_IO_FLASH_DEVICE_NOT_IN_RAM include_dir . include_files ; # none _exported_ whatsoever diff --git a/packages/devs/flash/arm/edb7xxx/current/ChangeLog b/packages/devs/flash/arm/edb7xxx/current/ChangeLog --- a/packages/devs/flash/arm/edb7xxx/current/ChangeLog +++ b/packages/devs/flash/arm/edb7xxx/current/ChangeLog @@ -1,3 +1,8 @@ +2001-05-23 Jesper Skov + + * cdl/flash_edb7xxx.cdl: Needs IO controller to copy functions to + RAM. + 2000-12-05 Jonathan Larmour * src/edb7xxx_flash.c (flash_code_overlaps): Define stext/etext diff --git a/packages/devs/flash/arm/edb7xxx/current/cdl/flash_edb7xxx.cdl b/packages/devs/flash/arm/edb7xxx/current/cdl/flash_edb7xxx.cdl --- a/packages/devs/flash/arm/edb7xxx/current/cdl/flash_edb7xxx.cdl +++ b/packages/devs/flash/arm/edb7xxx/current/cdl/flash_edb7xxx.cdl @@ -23,7 +23,7 @@ # # The Initial Developer of the Original Code is Red Hat. # Portions created by Red Hat are -# Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +# Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc. # All Rights Reserved. # ------------------------------------------- # @@ -48,6 +48,7 @@ cdl_package CYGPKG_DEVS_FLASH_EDB7XXX { requires CYGPKG_HAL_ARM_EDB7XXX implements CYGHWR_IO_FLASH_DEVICE + implements CYGHWR_IO_FLASH_DEVICE_NOT_IN_RAM include_dir . include_files ; # none _exported_ whatsoever diff --git a/packages/devs/flash/arm/iq80310/current/ChangeLog b/packages/devs/flash/arm/iq80310/current/ChangeLog --- a/packages/devs/flash/arm/iq80310/current/ChangeLog +++ b/packages/devs/flash/arm/iq80310/current/ChangeLog @@ -1,3 +1,8 @@ +2001-05-23 Jesper Skov + + * cdl/flash_iq80310.cdl: Needs IO controller to copy functions to + RAM. + 2000-12-05 Jonathan Larmour * src/iq80310_flash.c (flash_code_overlaps): Define stext/etext diff --git a/packages/devs/flash/arm/iq80310/current/cdl/flash_iq80310.cdl b/packages/devs/flash/arm/iq80310/current/cdl/flash_iq80310.cdl --- a/packages/devs/flash/arm/iq80310/current/cdl/flash_iq80310.cdl +++ b/packages/devs/flash/arm/iq80310/current/cdl/flash_iq80310.cdl @@ -48,6 +48,7 @@ cdl_package CYGPKG_DEVS_FLASH_IQ80310 { requires CYGPKG_HAL_ARM_IQ80310 implements CYGHWR_IO_FLASH_DEVICE + implements CYGHWR_IO_FLASH_DEVICE_NOT_IN_RAM implements CYGHWR_IO_FLASH_BLOCK_LOCKING include_dir . diff --git a/packages/devs/flash/arm/sa1100mm/current/ChangeLog b/packages/devs/flash/arm/sa1100mm/current/ChangeLog --- a/packages/devs/flash/arm/sa1100mm/current/ChangeLog +++ b/packages/devs/flash/arm/sa1100mm/current/ChangeLog @@ -1,3 +1,8 @@ +2001-05-23 Jesper Skov + + * cdl/flash_sa1100mm.cdl: Needs IO controller to copy functions to + RAM. + 2000-12-05 Jonathan Larmour * src/sa1100mm_flash.c (flash_code_overlaps): Define stext/etext diff --git a/packages/devs/flash/arm/sa1100mm/current/cdl/flash_sa1100mm.cdl b/packages/devs/flash/arm/sa1100mm/current/cdl/flash_sa1100mm.cdl --- a/packages/devs/flash/arm/sa1100mm/current/cdl/flash_sa1100mm.cdl +++ b/packages/devs/flash/arm/sa1100mm/current/cdl/flash_sa1100mm.cdl @@ -23,7 +23,7 @@ # # The Initial Developer of the Original Code is Red Hat. # Portions created by Red Hat are -# Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +# Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc. # All Rights Reserved. # ------------------------------------------- # @@ -48,6 +48,7 @@ cdl_package CYGPKG_DEVS_FLASH_SA1100MM { requires CYGPKG_HAL_ARM_SA11X0 implements CYGHWR_IO_FLASH_DEVICE + implements CYGHWR_IO_FLASH_DEVICE_NOT_IN_RAM include_dir . include_files ; # none _exported_ whatsoever diff --git a/packages/devs/flash/atmel/at29cxxxx/current/ChangeLog b/packages/devs/flash/atmel/at29cxxxx/current/ChangeLog --- a/packages/devs/flash/atmel/at29cxxxx/current/ChangeLog +++ b/packages/devs/flash/atmel/at29cxxxx/current/ChangeLog @@ -1,3 +1,8 @@ +2001-05-23 Jesper Skov + + * cdl/flash_atmel_at29cxxxx.cdl: Links functions to RAM. IO driver + need not copy. + 2001-02-23 Jesper Skov * include/flash_at29cxxxx.inl: Include type macros from IO driver. diff --git a/packages/devs/flash/atmel/at29cxxxx/current/cdl/flash_atmel_at29cxxxx.cdl b/packages/devs/flash/atmel/at29cxxxx/current/cdl/flash_atmel_at29cxxxx.cdl --- a/packages/devs/flash/atmel/at29cxxxx/current/cdl/flash_atmel_at29cxxxx.cdl +++ b/packages/devs/flash/atmel/at29cxxxx/current/cdl/flash_atmel_at29cxxxx.cdl @@ -48,7 +48,6 @@ cdl_package CYGPKG_DEVS_FLASH_ATMEL_AT29 active_if CYGINT_DEVS_FLASH_ATMEL_AT29CXXXX_REQUIRED implements CYGHWR_IO_FLASH_DEVICE - implements CYGHWR_IO_FLASH_DEVICE_IN_RAM include_dir cyg/io } diff --git a/packages/devs/flash/intel/28fxxx/current/ChangeLog b/packages/devs/flash/intel/28fxxx/current/ChangeLog --- a/packages/devs/flash/intel/28fxxx/current/ChangeLog +++ b/packages/devs/flash/intel/28fxxx/current/ChangeLog @@ -1,3 +1,8 @@ +2001-05-23 Jesper Skov + + * cdl/flash_intel_28fxxx.cdl: Links flash functions to RAM. IO + driver should not copy them there. + 2001-03-23 Jesper Skov * include/flash_28fxxx.inl (flash_program_buf): Calculate correct diff --git a/packages/devs/flash/intel/28fxxx/current/cdl/flash_intel_28fxxx.cdl b/packages/devs/flash/intel/28fxxx/current/cdl/flash_intel_28fxxx.cdl --- a/packages/devs/flash/intel/28fxxx/current/cdl/flash_intel_28fxxx.cdl +++ b/packages/devs/flash/intel/28fxxx/current/cdl/flash_intel_28fxxx.cdl @@ -48,7 +48,6 @@ cdl_package CYGPKG_DEVS_FLASH_INTEL_28FX active_if CYGINT_DEVS_FLASH_INTEL_28FXXX_REQUIRED implements CYGHWR_IO_FLASH_DEVICE - implements CYGHWR_IO_FLASH_DEVICE_IN_RAM include_dir cyg/io } diff --git a/packages/devs/flash/intel/bootblock/current/ChangeLog b/packages/devs/flash/intel/bootblock/current/ChangeLog --- a/packages/devs/flash/intel/bootblock/current/ChangeLog +++ b/packages/devs/flash/intel/bootblock/current/ChangeLog @@ -1,3 +1,8 @@ +2001-05-23 Jesper Skov + + * cdl/flash_intel_bootblock.cdl: Needs IO driver to copy functions + to RAM. + 2000-12-05 Jonathan Larmour * src/bootblock_flash.c (flash_code_overlaps): Define stext/etext diff --git a/packages/devs/flash/intel/bootblock/current/cdl/flash_intel_bootblock.cdl b/packages/devs/flash/intel/bootblock/current/cdl/flash_intel_bootblock.cdl --- a/packages/devs/flash/intel/bootblock/current/cdl/flash_intel_bootblock.cdl +++ b/packages/devs/flash/intel/bootblock/current/cdl/flash_intel_bootblock.cdl @@ -46,6 +46,7 @@ cdl_package CYGPKG_DEVS_FLASH_INTEL_BOOT active_if CYGPKG_IO_FLASH implements CYGHWR_IO_FLASH_DEVICE + implements CYGHWR_IO_FLASH_DEVICE_NOT_IN_RAM include_dir . include_files ; # none _exported_ whatsoever diff --git a/packages/devs/flash/intel/strata/current/ChangeLog b/packages/devs/flash/intel/strata/current/ChangeLog --- a/packages/devs/flash/intel/strata/current/ChangeLog +++ b/packages/devs/flash/intel/strata/current/ChangeLog @@ -1,3 +1,7 @@ +2001-05-23 Jesper Skov + + * cdl/flash_strata.cdl: Needs IO driver to copy functions to RAM. + 2001-04-26 Gary Thomas * src/strata.c: Be more careful when enable/flush/disable caches. diff --git a/packages/devs/flash/intel/strata/current/cdl/flash_strata.cdl b/packages/devs/flash/intel/strata/current/cdl/flash_strata.cdl --- a/packages/devs/flash/intel/strata/current/cdl/flash_strata.cdl +++ b/packages/devs/flash/intel/strata/current/cdl/flash_strata.cdl @@ -47,6 +47,7 @@ cdl_package CYGPKG_DEVS_FLASH_STRATA { active_if CYGPKG_IO_FLASH implements CYGHWR_IO_FLASH_DEVICE + implements CYGHWR_IO_FLASH_DEVICE_NOT_IN_RAM active_if CYGINT_DEVS_FLASH_STRATA_REQUIRED diff --git a/packages/devs/flash/mips/atlas/current/ChangeLog b/packages/devs/flash/mips/atlas/current/ChangeLog --- a/packages/devs/flash/mips/atlas/current/ChangeLog +++ b/packages/devs/flash/mips/atlas/current/ChangeLog @@ -1,3 +1,7 @@ +2001-05-23 Jesper Skov + + * cdl/flash_atlas.cdl: Needs IO controller to copy functions to + RAM. //=========================================================================== //####COPYRIGHTBEGIN#### @@ -18,7 +22,7 @@ // // The Initial Developer of the Original Code is Red Hat. // Portions created by Red Hat are -// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc. // All Rights Reserved. // ------------------------------------------- // diff --git a/packages/devs/flash/mips/atlas/current/cdl/flash_atlas.cdl b/packages/devs/flash/mips/atlas/current/cdl/flash_atlas.cdl --- a/packages/devs/flash/mips/atlas/current/cdl/flash_atlas.cdl +++ b/packages/devs/flash/mips/atlas/current/cdl/flash_atlas.cdl @@ -23,7 +23,7 @@ # # The Initial Developer of the Original Code is Red Hat. # Portions created by Red Hat are -# Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +# Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc. # All Rights Reserved. # ------------------------------------------- # @@ -48,6 +48,7 @@ cdl_package CYGPKG_DEVS_FLASH_ATLAS { requires CYGPKG_HAL_MIPS_ATLAS implements CYGHWR_IO_FLASH_DEVICE + implements CYGHWR_IO_FLASH_DEVICE_NOT_IN_RAM implements CYGHWR_IO_FLASH_BLOCK_LOCKING include_dir . diff --git a/packages/devs/flash/mips/ocelot/current/ChangeLog b/packages/devs/flash/mips/ocelot/current/ChangeLog --- a/packages/devs/flash/mips/ocelot/current/ChangeLog +++ b/packages/devs/flash/mips/ocelot/current/ChangeLog @@ -1,3 +1,13 @@ +2001-05-28 Jesper Skov + + * src/mips_ocelot_flash.c: Specify data width now driver + autodetects part. + +2001-05-22 Jesper Skov + + * cdl/flash_mips_ocelot.cdl: QED renamed to PMC-Sierra. + * include/devs_flash_mips_ocelot.inl: Same. + 2000-12-05 Jesper Skov * Created. @@ -21,7 +31,7 @@ 2000-12-05 Jesper Skov " - puts $::cdl_system_header "#define CYGDAT_DEVS_FLASH_AMD_AM29F040B_CFG " - puts $::cdl_system_header "/***** flash driver proc output end *****/" - } -} diff --git a/packages/devs/flash/mips/ocelot/current/include/devs_flash_mips_qed_ocelot.inl b/packages/devs/flash/mips/ocelot/current/include/devs_flash_mips_qed_ocelot.inl deleted file mode 100644 --- a/packages/devs/flash/mips/ocelot/current/include/devs_flash_mips_qed_ocelot.inl +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef CYGONCE_DEVS_FLASH_MIPS_OCELOT_H -#define CYGONCE_DEVS_FLASH_MIPS_OCELOT_H -//========================================================================== -// -// devs_flash_mips_qed_ocelot.inl -// -// Ocelot flash information -// -//========================================================================== -//####COPYRIGHTBEGIN#### -// -// ------------------------------------------- -// The contents of this file are subject to the Red Hat eCos Public License -// Version 1.1 (the "License"); you may not use this file except in -// compliance with the License. You may obtain a copy of the License at -// http://www.redhat.com/ -// -// Software distributed under the License is distributed on an "AS IS" -// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the -// License for the specific language governing rights and limitations under -// the License. -// -// The Original Code is eCos - Embedded Configurable Operating System, -// released September 30, 1998. -// -// The Initial Developer of the Original Code is Red Hat. -// Portions created by Red Hat are -// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. -// All Rights Reserved. -// ------------------------------------------- -// -//####COPYRIGHTEND#### -//========================================================================== -//#####DESCRIPTIONBEGIN#### -// -// Author(s): jskov -// Contributors: jskov -// Date: 2000-12-05 -// Purpose: -// Description: -// -//####DESCRIPTIONEND#### -// -//========================================================================== - -#define CYGHWR_FLASH_INTERLEAVE 1 -#define CYGHWR_FLASH_SERIES 1 -#define CYGHWR_FLASH_BASE 0xbfc00000 - -#endif // CYGONCE_DEVS_FLASH_MIPS_OCELOT_H diff --git a/packages/devs/flash/mips/ocelot/current/include/plf_flash.inc b/packages/devs/flash/mips/ocelot/current/include/plf_flash.inc deleted file mode 100644 --- a/packages/devs/flash/mips/ocelot/current/include/plf_flash.inc +++ /dev/null @@ -1,65 +0,0 @@ -#ifndef CYGONCE_DEVS_PLF_FLASH_INC -#define CYGONCE_DEVS_PLF_FLASH_INC - -##============================================================================= -## -## plf_flash.inc -## -## MIPS assembler header file -## -##============================================================================= -#####COPYRIGHTBEGIN#### -# -# ------------------------------------------- -# The contents of this file are subject to the Red Hat eCos Public License -# Version 1.1 (the "License"); you may not use this file except in -# compliance with the License. You may obtain a copy of the License at -# http://www.redhat.com/ -# -# Software distributed under the License is distributed on an "AS IS" -# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the -# License for the specific language governing rights and limitations under -# the License. -# -# The Original Code is eCos - Embedded Configurable Operating System, -# released September 30, 1998. -# -# The Initial Developer of the Original Code is Red Hat. -# Portions created by Red Hat are -# Copyright (C) 1998, 1999, 2000 Red Hat, Inc. -# All Rights Reserved. -# ------------------------------------------- -# -#####COPYRIGHTEND#### -##============================================================================= -#######DESCRIPTIONBEGIN#### -## -## Author(s): jskov -## Contributors:jskov -## Date: 2000-12-05 -## Purpose: MIPS definitions. -## Description: This file contains various definitions and macros that are -## useful for writing assembly code for the MIPS CPU family. -## Usage: -## #include -## ... -## -## -######DESCRIPTIONEND#### -## -##============================================================================= - -#define FUNC_START(name) \ - .type name,@function; \ - .globl name; \ - .ent name; \ -name: - -#define FUNC_END(name) \ - .globl name; \ -name: - - -#------------------------------------------------------------------------------ -#endif // ifndef CYGONCE_DEVS_PLF_FLASH_INC -# end of plf_flash.inc diff --git a/packages/devs/flash/mips/ocelot/current/src/mips_ocelot_flash.c b/packages/devs/flash/mips/ocelot/current/src/mips_ocelot_flash.c new file mode 100644 --- /dev/null +++ b/packages/devs/flash/mips/ocelot/current/src/mips_ocelot_flash.c @@ -0,0 +1,60 @@ +//========================================================================== +// +// mips_ocelot_flash.c +// +// Flash programming for AMD device on MIPS Ocelot board +// +//========================================================================== +//####COPYRIGHTBEGIN#### +// +// ------------------------------------------- +// The contents of this file are subject to the Red Hat eCos Public License +// Version 1.1 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://www.redhat.com/ +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +// License for the specific language governing rights and limitations under +// the License. +// +// The Original Code is eCos - Embedded Configurable Operating System, +// released September 30, 1998. +// +// The Initial Developer of the Original Code is Red Hat. +// Portions created by Red Hat are +// Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc. +// All Rights Reserved. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +//========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): jskov +// Contributors: jskov +// Date: 2001-05-22 +// Purpose: +// Description: +// +//####DESCRIPTIONEND#### +// +//========================================================================== + +//-------------------------------------------------------------------------- +// Device properties + +#define CYGNUM_FLASH_INTERLEAVE (1) +#define CYGNUM_FLASH_SERIES (1) +#define CYGNUM_FLASH_WIDTH (8) +#define CYGNUM_FLASH_BASE (0xbfc00000u) + +//-------------------------------------------------------------------------- +// Platform specific extras + +//-------------------------------------------------------------------------- +// Now include the driver code. +#include "cyg/io/flash_am29xxxxx.inl" + +// ------------------------------------------------------------------------ +// EOF mips_ocelot_flash.c diff --git a/packages/devs/flash/powerpc/mbx/current/ChangeLog b/packages/devs/flash/powerpc/mbx/current/ChangeLog --- a/packages/devs/flash/powerpc/mbx/current/ChangeLog +++ b/packages/devs/flash/powerpc/mbx/current/ChangeLog @@ -1,3 +1,8 @@ +2001-05-28 Jesper Skov + + * src/powerpc_mbx_flash.c: Specify data width now driver + autodetects part. + 2001-02-23 Jesper Skov * cdl/flash_mbx.cdl: Use new generic AMD driver. diff --git a/packages/devs/flash/powerpc/mbx/current/src/powerpc_mbx_flash.c b/packages/devs/flash/powerpc/mbx/current/src/powerpc_mbx_flash.c --- a/packages/devs/flash/powerpc/mbx/current/src/powerpc_mbx_flash.c +++ b/packages/devs/flash/powerpc/mbx/current/src/powerpc_mbx_flash.c @@ -44,10 +44,9 @@ //-------------------------------------------------------------------------- // Device properties -// We use the single AM29F040B on the MBX board. -#define CYGPKG_DEVS_FLASH_AMD_AM29F040B #define CYGNUM_FLASH_INTERLEAVE (1) #define CYGNUM_FLASH_SERIES (1) +#define CYGNUM_FLASH_WIDTH (8) #define CYGNUM_FLASH_BASE (0xfe000000u) //-------------------------------------------------------------------------- diff --git a/packages/devs/flash/powerpc/viper/current/ChangeLog b/packages/devs/flash/powerpc/viper/current/ChangeLog --- a/packages/devs/flash/powerpc/viper/current/ChangeLog +++ b/packages/devs/flash/powerpc/viper/current/ChangeLog @@ -1,3 +1,8 @@ +2001-05-23 Jesper Skov + + * cdl/flash_viper.cdl: Needs IO controller to copy functions to + RAM. + 2001-01-22 Gary Thomas * src/viper_flash.c: diff --git a/packages/devs/flash/powerpc/viper/current/cdl/flash_viper.cdl b/packages/devs/flash/powerpc/viper/current/cdl/flash_viper.cdl --- a/packages/devs/flash/powerpc/viper/current/cdl/flash_viper.cdl +++ b/packages/devs/flash/powerpc/viper/current/cdl/flash_viper.cdl @@ -48,6 +48,7 @@ cdl_package CYGPKG_DEVS_FLASH_VIPER { requires CYGPKG_HAL_POWERPC_VIPER implements CYGHWR_IO_FLASH_DEVICE + implements CYGHWR_IO_FLASH_DEVICE_NOT_IN_RAM include_dir . include_files ; # none _exported_ whatsoever diff --git a/packages/devs/usb/sa11x0/current/ChangeLog b/packages/devs/usb/sa11x0/current/ChangeLog --- a/packages/devs/usb/sa11x0/current/ChangeLog +++ b/packages/devs/usb/sa11x0/current/ChangeLog @@ -1,3 +1,14 @@ +2001-05-21 Bart Veer + + * src/usbs_sa11x0.c (usbs_sa11x0_ep2_dsr): + Fix the boundary condition where the transmission is an exact + multiple of 64 bytes. ep2_process_packet() already did the + right thing but was not getting called. + Also, some cosmetic changes to the receive code for the + same boundary condition. These actually have no effect + because of the hardware, but may be useful for other + people writing USB device drivers. + 2001-04-05 Bart Veer * src/usbs_sa11x0.c (usbs_sa11x0_ep0_fill_fifo): diff --git a/packages/devs/usb/sa11x0/current/src/usbs_sa11x0.c b/packages/devs/usb/sa11x0/current/src/usbs_sa11x0.c --- a/packages/devs/usb/sa11x0/current/src/usbs_sa11x0.c +++ b/packages/devs/usb/sa11x0/current/src/usbs_sa11x0.c @@ -1441,7 +1441,7 @@ ep1_clear_error(void) // A packet has been received. Some of it may still be in the fifo // and must be extracted by hand. The data then has to copied to // a higher-level buffer. -static void +static int ep1_process_packet(void) { // First, work out how much data has been processed by the DMA @@ -1462,7 +1462,6 @@ ep1_process_packet(void) if ((pkt_size > 0) && ((ep1.fetched + pkt_size) < ep1.common.buffer_size)) { memcpy(ep1.common.buffer + ep1.fetched, ep1_dma_buf, pkt_size); } - ep1.fetched += pkt_size; // Copy remaining bytes into the target buffer directly. // The DMA buffer could be used instead, moving the memcpy() @@ -1478,11 +1477,13 @@ ep1_process_packet(void) } else { int datum = *EP1_DATA; if (ep1.fetched < ep1.common.buffer_size) { - ep1.common.buffer[ep1.fetched] = datum; + ep1.common.buffer[ep1.fetched + pkt_size] = datum; } - ep1.fetched++; + pkt_size++; } } + ep1.fetched += pkt_size; + return pkt_size; } #else @@ -1505,16 +1506,18 @@ ep1_clear_error(void) EP1_PACKET_COMPLETE | EP1_SENT_STALL | EP1_FORCE_STALL); } -static void +static int ep1_process_packet(void) { + int pkt_size = 0; while (0 != (*EP1_CONTROL & EP1_FIFO_NOT_EMPTY)) { int datum = *EP1_DATA; - ep1.fetched++; + pkt_size++; if (ep1.fetched < ep1.common.buffer_size) { - ep1.common.buffer[ep1.fetched] = datum; + ep1.common.buffer[ep1.fetched + pkt_size] = datum; } } + return pkt_size; } #endif @@ -1577,7 +1580,7 @@ ep1_start_rx(usbs_rx_endpoint* endpoint) #ifdef CYGNUM_DEVS_USB_SA11X0_EP1_DMA_CHANNEL *EP1_DMA_BUF_A_SIZE = EP1_MTU; #endif - ep1_process_packet(); + (void) ep1_process_packet(); ep1_rx_complete(ep1.fetched); } else { // Start a new transfer. @@ -1661,13 +1664,12 @@ usbs_sa11x0_ep1_dsr(void) } else { // Another packet has been received. Process it, which may // complete the transfer or it may leave more to be done. + int pkt_size = ep1_process_packet(); INCR_STAT(ep1_receives); - ep1_process_packet(); if (0 != (EP1_PACKET_ERROR & *EP1_CONTROL)) { + CYG_ASSERT( 0, "an error has occurred inside ep1_process_packet()\n"); - CYG_ASSERT( 0, "an error has occurred inside ep1_process_packet()\n"); - - } else if ((ep1.fetched != ep1.common.buffer_size) && (0 == (ep1.fetched % EP1_MTU))) { + } else if ((ep1.fetched != ep1.common.buffer_size) && (0 != pkt_size) && (0 == (ep1.fetched % EP1_MTU))) { ep1_start_rx_packet(); } else if (ep1.fetched > ep1.common.buffer_size) { // The host has sent too much data. @@ -2044,7 +2046,8 @@ usbs_sa11x0_ep2_dsr(void) // Another packet has gone out. INCR_STAT(ep2_transmits); ep2.transmitted += ep2.pkt_size; - if (ep2.transmitted < ep2.common.buffer_size) { + if ((ep2.transmitted < ep2.common.buffer_size) || + ((ep2.transmitted == ep2.common.buffer_size) && (0 == (ep2.common.buffer_size % EP2_MTU)))) { ep2_process_packet(); ep2_tx_packet(); } else { diff --git a/packages/ecos.db b/packages/ecos.db --- a/packages/ecos.db +++ b/packages/ecos.db @@ -162,23 +162,14 @@ package CYGPKG_DEVS_FLASH_ARM_PID { on the ARM PID platform." } -package CYGPKG_DEVS_FLASH_AMD_AM29F040B { - alias { "Support for AMD AM29F040B flash memory" flash_amd_am29f040b } - directory devs/flash/amd/am29f040b - script flash_amd_am29f040b.cdl - hardware - description " - This package contains hardware support for AMD AM29F040B - flash memory." -} -package CYGPKG_DEVS_FLASH_MIPS_QED_OCELOT { - alias { "Support for flash memory on QED/Ocelot board" flash_qed_ocelot } +package CYGPKG_DEVS_FLASH_MIPS_OCELOT { + alias { "Support for flash memory on PMC-Sierra/Ocelot board" flash_qed_ocelot } directory devs/flash/mips/ocelot - script flash_mips_qed_ocelot.cdl + script flash_mips_ocelot.cdl hardware description " This package contains hardware support for flash memory - on the QED Ocelot platform." + on the PMC-Sierra Ocelot platform." } package CYGPKG_DEVS_FLASH_EBSA285 { @@ -618,15 +609,6 @@ package CYGPKG_SNMPAGENT { description "UCD SNMP agent." } -package CYGPKG_NET_AUTOTEST { - alias { "Network Autotesting" autotest net_autotest } - directory net/autotest - script net_autotest.cdl - description " - Automated network testing support. - ***Red Hat internal use only***" -} - package CYGPKG_DEVS_ETH_ARM_EDB7XXX { alias { "Cirrus Logic ethernet driver" edb7xxx_eth_driver } hardware @@ -675,7 +657,7 @@ package CYGPKG_DEVS_ETH_MIPS_RM7000_OCEL hardware directory devs/eth/mips/ocelot script mips_rm7000_ocelot_eth_drivers.cdl - description "Ethernet driver for QED Ocelot board." + description "Ethernet driver for PMC-Sierra Ocelot board." } package CYGPKG_DEVS_ETH_ARM_IQ80310 { @@ -1523,7 +1505,7 @@ package CYGPKG_HAL_MIPS_RM7000 { } package CYGPKG_HAL_MIPS_RM7000_OCELOT { - alias { "QED Ocelot platform" hal_rm7000_ocelot rm7000_ocelot_hal } + alias { "PMC-Sierra Ocelot platform" hal_rm7000_ocelot rm7000_ocelot_hal } directory hal/mips/rm7000/ocelot script hal_mips_rm7000_ocelot.cdl hardware @@ -1659,7 +1641,11 @@ The CEB-V850/SA1 HAL package provides th evaluation board." } + + # ========================================================================== + + # -------------------------------------------------------------------------- # ARM targets @@ -2067,20 +2053,20 @@ target ref4955 { } target ocelot { - alias { "QED Ocelot platform" ocelot } + alias { "PMC-Sierra Ocelot platform" ocelot } packages { CYGPKG_HAL_MIPS CYGPKG_HAL_MIPS_RM7000 CYGPKG_HAL_MIPS_RM7000_OCELOT CYGPKG_IO_PCI - CYGPKG_DEVS_FLASH_MIPS_QED_OCELOT - CYGPKG_DEVS_FLASH_AMD_AM29F040B + CYGPKG_DEVS_FLASH_MIPS_OCELOT + CYGPKG_DEVS_FLASH_AMD_AM29XXXXX CYGPKG_IO_SERIAL_GENERIC_16X5X CYGPKG_DEVS_ETH_INTEL_I82559 CYGPKG_DEVS_ETH_MIPS_RM7000_OCELOT } description " The ocelot target provides the packages needed to run - eCos on a QED Ocelot Hot-Swap Computer." + eCos on a PMC-Sierra Ocelot Hot-Swap Computer." } target vrc4373 { diff --git a/packages/ecosadmin.tcl b/packages/ecosadmin.tcl --- a/packages/ecosadmin.tcl +++ b/packages/ecosadmin.tcl @@ -597,14 +597,15 @@ proc ecosadmin::read_data { } { set pkgdir [file join $ecosadmin::component_repository $ecosadmin::package_data($pkg,dir)] if { ![file exists $pkgdir] || ![file isdir $pkgdir] } { - fatal_error "package $pkg at $pkgdir missing" - } + warning "package $pkg at $pkgdir missing" + } else { - # Each subdirectory should correspond to a release. A utility routine - # is available for this. - set ecosadmin::package_data($pkg,versions) [locate_subdirs $pkgdir] - if { $ecosadmin::package_data($pkg,versions) == "" } { - fatal_error "package $pkg has no version directories" + # Each subdirectory should correspond to a release. A utility routine + # is available for this. + set ecosadmin::package_data($pkg,versions) [locate_subdirs $pkgdir] + if { $ecosadmin::package_data($pkg,versions) == "" } { + fatal_error "package $pkg has no version directories" + } } # Sort all the versions using a version-aware comparison version diff --git a/packages/hal/arm/arch/current/ChangeLog b/packages/hal/arm/arch/current/ChangeLog --- a/packages/hal/arm/arch/current/ChangeLog +++ b/packages/hal/arm/arch/current/ChangeLog @@ -1,3 +1,9 @@ +2001-05-23 Gary Thomas + + * src/vectors.S: Allow platforms to define a 'preamble' which gets + included _before_ the vectors. This is often required for modules + which are run from ROM/Flash. + 2001-04-30 Gary Thomas * src/vectors.S (__exception_handlers): Platforms must explicitly diff --git a/packages/hal/arm/arch/current/src/vectors.S b/packages/hal/arm/arch/current/src/vectors.S --- a/packages/hal/arm/arch/current/src/vectors.S +++ b/packages/hal/arm/arch/current/src/vectors.S @@ -156,6 +156,15 @@ // .code 32 .section ".vectors","ax" + +// This macro allows platforms to add their own code at the very start of +// the image. This may be required in some circumstances where eCos ROM +// based code does not run immediately upon reset and/or when some sort of +// special header is required at the start of the image. +#ifdef PLATFORM_PREAMBLE + PLATFORM_PREAMBLE +#endif + .global __exception_handlers __exception_handlers: #ifdef CYGSEM_HAL_ROM_RESET_USES_JUMP diff --git a/packages/hal/arm/edb7xxx/current/ChangeLog b/packages/hal/arm/edb7xxx/current/ChangeLog --- a/packages/hal/arm/edb7xxx/current/ChangeLog +++ b/packages/hal/arm/edb7xxx/current/ChangeLog @@ -1,3 +1,7 @@ +2001-05-29 Jonathan Larmour + + * include/hal_platform_setup.h: Use correct 7209 define. + 2001-05-01 Gary Thomas * misc/edb7212_redboot_ROM.ecm: diff --git a/packages/hal/arm/edb7xxx/current/include/hal_platform_setup.h b/packages/hal/arm/edb7xxx/current/include/hal_platform_setup.h --- a/packages/hal/arm/edb7xxx/current/include/hal_platform_setup.h +++ b/packages/hal/arm/edb7xxx/current/include/hal_platform_setup.h @@ -170,7 +170,7 @@ 15: bne 15b ;\ 20: -#ifdef CYGPKG_HAL_ARM_EDB7209 +#ifdef CYGHWR_HAL_ARM_EDB7XXX_VARIANT_EP7209 // No DRAM controller #define INIT_MEMORY_CONFIG \ /* Initialize memory configuration */ ;\ diff --git a/packages/hal/arm/pid/current/misc/dl.c b/packages/hal/arm/pid/current/misc/dl.c new file mode 100644 --- /dev/null +++ b/packages/hal/arm/pid/current/misc/dl.c @@ -0,0 +1,81 @@ +//========================================================================== +// +// dl.c +// +// ARM PID7 eval board FLASH program tool +// +//========================================================================== +//####COPYRIGHTBEGIN#### +// +// ------------------------------------------- +// The contents of this file are subject to the Red Hat eCos Public License +// Version 1.1 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://www.redhat.com/ +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +// License for the specific language governing rights and limitations under +// the License. +// +// The Original Code is eCos - Embedded Configurable Operating System, +// released September 30, 1998. +// +// The Initial Developer of the Original Code is Red Hat. +// Portions created by Red Hat are +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// All Rights Reserved. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +//========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): gthomas +// Contributors: gthomas +// Date: 1998-11-18 +// Description: Tool used for simple handshake downloads. +//####DESCRIPTIONEND#### + +#include + +#define SYNC_COUNT 63 + +int +main(int argc, char *argv[]) +{ + int c, count, j; + char cout, cin; + FILE *in, *log; + if ((in = fopen(argv[1], "r")) == (FILE *)NULL) { + fprintf(stderr, "Can't open '%s'\n", argv[1]); + exit(1); + } + if ((log = fopen("/tmp/dl.log", "w")) == (FILE *)NULL) { + fprintf(stderr, "Can't open log file\n"); + exit(1); + } + fprintf(stderr, "Downloading '%s'\n", argv[1]); + count = 0; j = 0; + write(1, ">", 1); // Magic start + while ((c = fgetc(in)) != EOF) { + cout = c; + write(1, &cout, 1); + if (++j == SYNC_COUNT) { + read(0, &cin, 1); + if (cin != cout) { + fprintf(stderr, "Sync problem - in: %x, out: %x, byte: %x\n", cin, cout, count); + fprintf(log, "Sync problem - in: %x, out: %x, byte: %x\n", cin, cout, count); + fflush(log); + break; + } + j = 0; + } + count++; + if ((count % 256) == 255) fprintf(stderr, "%08X\n", count); + } + sleep(2); + write(1, ":", 1); + fclose(log); + exit(0); +} diff --git a/packages/hal/arm/pid/current/misc/redboot_RAM-BE.ecm b/packages/hal/arm/pid/current/misc/redboot_RAM-BE.ecm new file mode 100644 --- /dev/null +++ b/packages/hal/arm/pid/current/misc/redboot_RAM-BE.ecm @@ -0,0 +1,54 @@ +cdl_savefile_version 1; +cdl_savefile_command cdl_savefile_version {}; +cdl_savefile_command cdl_savefile_command {}; +cdl_savefile_command cdl_configuration { description hardware template package }; +cdl_savefile_command cdl_package { value_source user_value wizard_value inferred_value }; +cdl_savefile_command cdl_component { value_source user_value wizard_value inferred_value }; +cdl_savefile_command cdl_option { value_source user_value wizard_value inferred_value }; +cdl_savefile_command cdl_interface { value_source user_value wizard_value inferred_value }; + +cdl_configuration eCos { + description "" ; + hardware pid ; + template redboot ; + package -hardware CYGPKG_HAL_ARM current ; + package -hardware CYGPKG_HAL_ARM_PID current ; + package -hardware CYGPKG_IO_SERIAL_GENERIC_16X5X current ; + package -hardware CYGPKG_IO_SERIAL_ARM_PID current ; + package -hardware CYGPKG_DEVS_FLASH_ARM_PID current ; + package -hardware CYGPKG_DEVS_FLASH_ATMEL_AT29CXXXX current ; + package -template CYGPKG_HAL current ; + package -template CYGPKG_INFRA current ; + package -template CYGPKG_REDBOOT current ; + package CYGPKG_IO_FLASH current ; +}; + +cdl_option CYGBLD_BUILD_GDB_STUBS { + user_value 0 +}; + +cdl_option CYGDBG_HAL_COMMON_INTERRUPTS_SAVE_MINIMUM_CONTEXT { + user_value 0 +}; + +cdl_option CYGDBG_HAL_COMMON_CONTEXT_SAVE_MINIMUM { + inferred_value 0 +}; + +cdl_option CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS { + inferred_value 1 +}; + +cdl_option CYGSEM_HAL_USE_ROM_MONITOR { + inferred_value 0 0 +}; + +cdl_option CYGHWR_HAL_ARM_BIGENDIAN { + user_value 1 +}; + +cdl_component CYGBLD_BUILD_REDBOOT { + user_value 1 +}; + + diff --git a/packages/hal/arm/pid/current/misc/redboot_RAM.ecm b/packages/hal/arm/pid/current/misc/redboot_RAM.ecm new file mode 100644 --- /dev/null +++ b/packages/hal/arm/pid/current/misc/redboot_RAM.ecm @@ -0,0 +1,50 @@ +cdl_savefile_version 1; +cdl_savefile_command cdl_savefile_version {}; +cdl_savefile_command cdl_savefile_command {}; +cdl_savefile_command cdl_configuration { description hardware template package }; +cdl_savefile_command cdl_package { value_source user_value wizard_value inferred_value }; +cdl_savefile_command cdl_component { value_source user_value wizard_value inferred_value }; +cdl_savefile_command cdl_option { value_source user_value wizard_value inferred_value }; +cdl_savefile_command cdl_interface { value_source user_value wizard_value inferred_value }; + +cdl_configuration eCos { + description "" ; + hardware pid ; + template redboot ; + package -hardware CYGPKG_HAL_ARM current ; + package -hardware CYGPKG_HAL_ARM_PID current ; + package -hardware CYGPKG_IO_SERIAL_GENERIC_16X5X current ; + package -hardware CYGPKG_IO_SERIAL_ARM_PID current ; + package -hardware CYGPKG_DEVS_FLASH_ARM_PID current ; + package -hardware CYGPKG_DEVS_FLASH_ATMEL_AT29CXXXX current ; + package -template CYGPKG_HAL current ; + package -template CYGPKG_INFRA current ; + package -template CYGPKG_REDBOOT current ; + package CYGPKG_IO_FLASH current ; +}; + +cdl_option CYGBLD_BUILD_GDB_STUBS { + user_value 0 +}; + +cdl_option CYGDBG_HAL_COMMON_INTERRUPTS_SAVE_MINIMUM_CONTEXT { + user_value 0 +}; + +cdl_option CYGDBG_HAL_COMMON_CONTEXT_SAVE_MINIMUM { + inferred_value 0 +}; + +cdl_option CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS { + inferred_value 1 +}; + +cdl_option CYGSEM_HAL_USE_ROM_MONITOR { + inferred_value 0 0 +}; + +cdl_component CYGBLD_BUILD_REDBOOT { + user_value 1 +}; + + diff --git a/packages/hal/arm/pid/current/misc/redboot_ROM-BE.ecm b/packages/hal/arm/pid/current/misc/redboot_ROM-BE.ecm new file mode 100644 --- /dev/null +++ b/packages/hal/arm/pid/current/misc/redboot_ROM-BE.ecm @@ -0,0 +1,62 @@ +cdl_savefile_version 1; +cdl_savefile_command cdl_savefile_version {}; +cdl_savefile_command cdl_savefile_command {}; +cdl_savefile_command cdl_configuration { description hardware template package }; +cdl_savefile_command cdl_package { value_source user_value wizard_value inferred_value }; +cdl_savefile_command cdl_component { value_source user_value wizard_value inferred_value }; +cdl_savefile_command cdl_option { value_source user_value wizard_value inferred_value }; +cdl_savefile_command cdl_interface { value_source user_value wizard_value inferred_value }; + +cdl_configuration eCos { + description "" ; + hardware pid ; + template redboot ; + package -hardware CYGPKG_HAL_ARM current ; + package -hardware CYGPKG_HAL_ARM_PID current ; + package -hardware CYGPKG_IO_SERIAL_GENERIC_16X5X current ; + package -hardware CYGPKG_IO_SERIAL_ARM_PID current ; + package -hardware CYGPKG_DEVS_FLASH_ARM_PID current ; + package -hardware CYGPKG_DEVS_FLASH_ATMEL_AT29CXXXX current ; + package -template CYGPKG_HAL current ; + package -template CYGPKG_INFRA current ; + package -template CYGPKG_REDBOOT current ; + package CYGPKG_IO_FLASH current ; +}; + +cdl_option CYGBLD_BUILD_GDB_STUBS { + user_value 0 +}; + +cdl_option CYGDBG_HAL_COMMON_INTERRUPTS_SAVE_MINIMUM_CONTEXT { + user_value 0 +}; + +cdl_option CYGDBG_HAL_COMMON_CONTEXT_SAVE_MINIMUM { + inferred_value 0 +}; + +cdl_option CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS { + inferred_value 1 +}; + +cdl_option CYGSEM_HAL_ROM_MONITOR { + inferred_value 1 +}; + +cdl_option CYGSEM_HAL_USE_ROM_MONITOR { + inferred_value 0 0 +}; + +cdl_option CYGHWR_HAL_ARM_BIGENDIAN { + user_value 1 +}; + +cdl_component CYG_HAL_STARTUP { + user_value ROM +}; + +cdl_component CYGBLD_BUILD_REDBOOT { + user_value 1 +}; + + diff --git a/packages/hal/arm/pid/current/misc/redboot_ROM.ecm b/packages/hal/arm/pid/current/misc/redboot_ROM.ecm new file mode 100644 --- /dev/null +++ b/packages/hal/arm/pid/current/misc/redboot_ROM.ecm @@ -0,0 +1,58 @@ +cdl_savefile_version 1; +cdl_savefile_command cdl_savefile_version {}; +cdl_savefile_command cdl_savefile_command {}; +cdl_savefile_command cdl_configuration { description hardware template package }; +cdl_savefile_command cdl_package { value_source user_value wizard_value inferred_value }; +cdl_savefile_command cdl_component { value_source user_value wizard_value inferred_value }; +cdl_savefile_command cdl_option { value_source user_value wizard_value inferred_value }; +cdl_savefile_command cdl_interface { value_source user_value wizard_value inferred_value }; + +cdl_configuration eCos { + description "" ; + hardware pid ; + template redboot ; + package -hardware CYGPKG_HAL_ARM current ; + package -hardware CYGPKG_HAL_ARM_PID current ; + package -hardware CYGPKG_IO_SERIAL_GENERIC_16X5X current ; + package -hardware CYGPKG_IO_SERIAL_ARM_PID current ; + package -hardware CYGPKG_DEVS_FLASH_ARM_PID current ; + package -hardware CYGPKG_DEVS_FLASH_ATMEL_AT29CXXXX current ; + package -template CYGPKG_HAL current ; + package -template CYGPKG_INFRA current ; + package -template CYGPKG_REDBOOT current ; + package CYGPKG_IO_FLASH current ; +}; + +cdl_option CYGBLD_BUILD_GDB_STUBS { + user_value 0 +}; + +cdl_option CYGDBG_HAL_COMMON_INTERRUPTS_SAVE_MINIMUM_CONTEXT { + user_value 0 +}; + +cdl_option CYGDBG_HAL_COMMON_CONTEXT_SAVE_MINIMUM { + inferred_value 0 +}; + +cdl_option CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS { + inferred_value 1 +}; + +cdl_option CYGSEM_HAL_ROM_MONITOR { + inferred_value 1 +}; + +cdl_option CYGSEM_HAL_USE_ROM_MONITOR { + inferred_value 0 0 +}; + +cdl_component CYG_HAL_STARTUP { + user_value ROM +}; + +cdl_component CYGBLD_BUILD_REDBOOT { + user_value 1 +}; + + diff --git a/packages/hal/arm/sa11x0/ipaq/current/ChangeLog b/packages/hal/arm/sa11x0/ipaq/current/ChangeLog --- a/packages/hal/arm/sa11x0/ipaq/current/ChangeLog +++ b/packages/hal/arm/sa11x0/ipaq/current/ChangeLog @@ -1,3 +1,9 @@ +2001-05-24 Gary Thomas + + * misc/redboot_ROM.ecm: + * misc/redboot_RAM.ecm: Remove 'RedBoot[backup]' image by + default - to make room for Linux kernel. + 2001-05-16 Gary Thomas * include/hal_platform_setup.h: Always init UART3. Add support diff --git a/packages/hal/arm/sa11x0/ipaq/current/cdl/hal_arm_sa11x0_ipaq.cdl b/packages/hal/arm/sa11x0/ipaq/current/cdl/hal_arm_sa11x0_ipaq.cdl --- a/packages/hal/arm/sa11x0/ipaq/current/cdl/hal_arm_sa11x0_ipaq.cdl +++ b/packages/hal/arm/sa11x0/ipaq/current/cdl/hal_arm_sa11x0_ipaq.cdl @@ -125,6 +125,18 @@ cdl_package CYGPKG_HAL_ARM_SA11X0_IPAQ { diagnostic and GDB port are the same." } + cdl_option CYGSEM_HAL_PARROT_BOOT { + display "Include Flash signature used by WinCE parrot mode" + flavor bool + active_if { CYG_HAL_STARTUP == "ROM" } + default_value 1 + description " + Enabling this option will add an additional header to the + executable image making it suitable for booting directly from + the native (WinCE Parrot) environment. This mode should be + the default for ROM based programs, such as RedBoot." + } + cdl_option CYGSEM_IPAQ_LCD_COMM { display "Support LCD/touchscreen for comminication channel" active_if CYGPKG_REDBOOT diff --git a/packages/hal/arm/sa11x0/ipaq/current/images/redboot_RAM.bin b/packages/hal/arm/sa11x0/ipaq/current/images/redboot_RAM.bin index 7c67d71a03776b752dcd38b107a31c70d1d2e85b..ed26f04ca0014aa06b771f2cc8687857ca52acbf GIT binary patch literal 157512 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