Initial KIWAY (modular-kicad) work. Various tweeks.

This commit is contained in:
Dick Hollenbeck 2014-02-03 09:10:37 -06:00
parent 63bc40b58e
commit 4f26386e8d
21 changed files with 1030 additions and 123 deletions

View File

@ -1,3 +1,12 @@
# Default to CMAKE_BUILD_TYPE = Release unless overridden on command line
# http://www.cmake.org/pipermail/cmake/2008-September/023808.html
if( DEFINED CMAKE_BUILD_TYPE )
set( CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE} CACHE STRING "Set to either \"Release\" or \"Debug\"" )
else()
set( CMAKE_BUILD_TYPE Release CACHE STRING "Set to either \"Release\" or \"Debug\"" )
endif()
project( kicad ) project( kicad )
cmake_minimum_required( VERSION 2.8.4 FATAL_ERROR ) cmake_minimum_required( VERSION 2.8.4 FATAL_ERROR )

View File

@ -67,6 +67,9 @@
/// When defined, build the GITHUB_PLUGIN for pcbnew. /// When defined, build the GITHUB_PLUGIN for pcbnew.
#cmakedefine BUILD_GITHUB_PLUGIN #cmakedefine BUILD_GITHUB_PLUGIN
/// When defined, use KIWAY and DSOs
#cmakedefine USE_KIWAY_DLLS
/// Name of repo from which this build came. /// Name of repo from which this build came.
#define KICAD_REPO_NAME "@KICAD_REPO_NAME@" #define KICAD_REPO_NAME "@KICAD_REPO_NAME@"

View File

@ -548,6 +548,6 @@ bool EDA_APP::OnInit()
} }
void EDA_APP::MacOpenFile(const wxString &fileName) void EDA_APP::MacOpenFile( const wxString& aFileName )
{ {
} }

View File

@ -131,6 +131,7 @@ set( COMMON_SRCS
hotkeys_basic.cpp hotkeys_basic.cpp
hotkey_grid_table.cpp hotkey_grid_table.cpp
html_messagebox.cpp html_messagebox.cpp
kiway.cpp
msgpanel.cpp msgpanel.cpp
netlist_keywords.cpp netlist_keywords.cpp
newstroke_font.cpp newstroke_font.cpp
@ -177,16 +178,6 @@ set( COMMON_SRCS
) )
# TODO: remove this whole "if test" on or after 14-Jan-2014 and remove the system/*.s
# sources if no one complains by then.
# boost::context library replaces this functionality:
if( false )
enable_language( C CXX ASM )
set_source_files_properties( system/fcontext.s PROPERTIES COMPILE_FLAGS "-x assembler-with-cpp" )
list( APPEND COMMON_SRCS system/fcontext.s )
endif()
add_library( common STATIC ${COMMON_SRCS} ) add_library( common STATIC ${COMMON_SRCS} )
set( PCB_COMMON_SRCS set( PCB_COMMON_SRCS

95
common/kiway.cpp Normal file
View File

@ -0,0 +1,95 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2014 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2014 KiCad Developers, see CHANGELOG.TXT for contributors.
*
* 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, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <kiway.h>
#include <wx/debug.h>
#include <string.h>
// one for each FACE_T
wxDynamicLibrary KIWAY::s_sch_dso;
wxDynamicLibrary KIWAY::s_pcb_dso;
KIWAY::KIWAY()
{
memset( &m_dso_players, 0, sizeof( m_dso_players ) );
}
const wxString KIWAY::dso_name( FACE_T aFaceId )
{
switch( aFaceId )
{
case FACE_SCH: return wxT( "_eeschema." ) DSO_EXT;
case FACE_PCB: return wxT( "_pcbnew." ) DSO_EXT;
default:
wxASSERT_MSG( 0, wxT( "caller has a bug, passed a bad aFaceId" ) );
return wxEmptyString;
}
}
PROJECT& KIWAY::Project()
{
return m_project;
}
KIFACE* KIWAY::KiFACE( FACE_T aFaceId, bool doLoad )
{
switch( aFaceId )
{
case FACE_SCH:
case FACE_PCB:
//case FACE_LIB:
//case FACE_MOD:
if( m_dso_players[aFaceId] )
return m_dso_players[aFaceId];
default:
wxASSERT_MSG( 0, wxT( "caller has a bug, passed a bad aFaceId" ) );
return NULL;
}
// DSO with KIFACE has not been loaded yet, does user want to load it?
if( doLoad )
{
switch( aFaceId )
{
case FACE_SCH:
break;
case FACE_PCB:
break;
//case FACE_LIB:
//case FACE_MOD:
default:
;
}
}
return NULL;
}

300
common/single_top.cpp Normal file
View File

@ -0,0 +1,300 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2014 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2014 KiCad Developers, see CHANGELOG.TXT for contributors.
*
* 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, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/*
This is a program launcher for a single DSO. Initially it will only mimic a
KIWAY not actually implement one, since only a single DSO is supported by
it.
*/
#include <macros.h>
#include <fctsys.h>
#include <wx/dynlib.h>
#include <wx/filename.h>
#include <kiway.h>
#include <wx/stdpaths.h>
/**
* Class PROCESS
* provides its own OnInit() handler.
*/
class PROCESS : public wxApp
{
public:
bool OnInit();
};
IMPLEMENT_APP( PROCESS )
#if !wxCHECK_VERSION( 3, 0, 0 )
// implement missing wx2.8 function until >= wx3.0 pervades.
static wxString wxJoin(const wxArrayString& arr, const wxChar sep,
const wxChar escape = '\\')
{
size_t count = arr.size();
if ( count == 0 )
return wxEmptyString;
wxString str;
// pre-allocate memory using the estimation of the average length of the
// strings in the given array: this is very imprecise, of course, but
// better than nothing
str.reserve(count*(arr[0].length() + arr[count-1].length()) / 2);
if ( escape == wxT('\0') )
{
// escaping is disabled:
for ( size_t i = 0; i < count; i++ )
{
if ( i )
str += sep;
str += arr[i];
}
}
else // use escape character
{
for ( size_t n = 0; n < count; n++ )
{
if ( n )
str += sep;
for ( wxString::const_iterator i = arr[n].begin(),
end = arr[n].end();
i != end;
++i )
{
const wxChar ch = *i;
if ( ch == sep )
str += escape; // escape this separator
str += ch;
}
}
}
str.Shrink(); // release extra memory if we allocated too much
return str;
}
#endif
// POLICY CHOICE: return the name of the DSO to load as single_top.
static const wxString dso_name( const wxString& aAbsoluteArgv0 )
{
// Prefix basename with '_' and change extension to DSO_EXT.
// POLICY CHOICE: Keep same path, and therefore installer must put the major DSO
// in same dir as top process module. Obviously alternatives are possible
// and that is why this is a separate function. One alternative would be to use
// a portion of CMAKE_INSTALL_PREFIX and navigate to a "lib" dir, but that
// would require a recompile any time you chose to install into a different place.
// It is my decision to treat _eeschema.so and _pcbnew.so as "executables",
// not "libraries" in this regard, since most all program functionality lives
// in them. They are basically spin-offs from what was once a top process module.
// That may not make linux package maintainers happy, but that is not my job.
// Get over it. KiCad is not a trivial suite, and multiple platforms come
// into play, not merely linux. If it freaks you out, we can use a different
// file extension than ".so", but they are not purely libraries, else they
// would begin with "lib" in basename. Like I said, get over it, we're serving
// too many masters here: python, windows, linux, OSX, multiple versions of wx...
wxFileName fn( aAbsoluteArgv0 );
wxString basename( wxT( '_' ) );
basename += fn.GetName();
fn.SetName( basename );
fn.SetExt( DSO_EXT );
return fn.GetFullPath();
}
/// Put aPriorityPath in front of all paths in the value of aEnvVar.
const wxString PrePendPath( const wxString& aEnvVar, const wxString& aPriorityPath )
{
wxPathList paths;
paths.AddEnvList( aEnvVar );
paths.Insert( aPriorityPath, 0 );
return wxJoin( paths, wxPATH_SEP[0] );
}
/// Extend LIB_ENV_VAR list with the directory from which I came, prepending it.
void SetLibEnvVar( const wxString& aAbsoluteArgv0 )
{
// POLICY CHOICE: Keep same path, so that installer MAY put the
// "subsidiary shared libraries" in the same directory as the top process module.
// A subsidiary shared library is one that is not a top level DSO, but rather
// some shared library that a top level DSO needs to even be loaded.
// This directory POLICY CHOICE is not the only dir in play, since LIB_ENV_VAR
// has numerous path options in it, as does DSO searching on linux.
// See "man ldconfig" on linux. What's being done here is for quick installs
// into a non-standard place, and especially for Windows users who may not
// know what the PATH environment variable is or how to set it.
wxFileName fn( aAbsoluteArgv0 );
wxString ld_path( LIB_ENV_VAR );
wxString my_path = fn.GetPath();
wxString new_paths = PrePendPath( ld_path, my_path );
wxSetEnv( ld_path, new_paths );
#if defined(DEBUG)
{
wxString test;
wxGetEnv( ld_path, &test );
printf( "LIB_ENV_VAR:'%s'\n", TO_UTF8( test ) );
}
#endif
}
// Only a single KIWAY is supported in this single_top to level component,
// which is dedicated to loading only a single DSO.
static KIWAY standalone;
// Use of this is arbitrary, remember single_top only knows about a single DSO.
// Could have used one from the KIWAY also.
static wxDynamicLibrary dso;
/**
* Function get_kiface_getter
* returns a KIFACE_GETTER_FUNC for the current process's main implemation link image.
*
* @param aDSOName is an absolute full path to the DSO to load and find KIFACE_GETTER_FUNC within.
*
* @return KIFACE_GETTER_FUNC* - a pointer to a function which can be called to get the KIFACE
* or NULL if not found or not version compatible.
*/
static KIFACE_GETTER_FUNC* get_kiface_getter( const wxString& aDSOName )
{
void* addr = NULL;
if( !dso.Load( aDSOName, wxDL_VERBATIM | wxDL_NOW ) )
{
// Failure: error reporting UI was done via wxLogSysError().
// No further reporting required here.
}
else if( ( addr = dso.GetSymbol( wxT( KIFACE_INSTANCE_NAME_AND_VERSION ) ) ) == NULL )
{
// Failure: error reporting UI was done via wxLogSysError().
// No further reporting required here.
}
return (KIFACE_GETTER_FUNC*) addr;
}
static KIFACE* kiface;
static int kiface_version;
bool PROCESS::OnInit()
{
// Choose to use argv command line processing in base class's OnInit().
// That choice is not mandatory, see wx's appbase.cpp OnInit().
if( !wxApp::OnInit() )
return false;
wxStandardPathsBase& paths = wxStandardPaths::Get();
wxString dir = paths.GetLocalizedResourcesDir( wxT( "de" ),
wxStandardPaths::ResourceCat_None );
printf( "LocalizeResourcesDir:'%s'\n", TO_UTF8( dir ) );
wxString dummy( _( "translate this" ) );
wxString absoluteArgv0 = paths.GetExecutablePath();
#if 0 || defined(DEBUG)
printf( "argv[0]:'%s' absoluteArgv0:'%s'\n",
TO_UTF8( wxString( argv[0] ) ),
TO_UTF8( absoluteArgv0 )
);
#endif
if( !wxIsAbsolutePath( absoluteArgv0 ) )
{
wxLogSysError( wxT( "No meaningful argv[0]" ) );
return false;
}
// Set LIB_ENV_VAR *before* loading the DSO, in case the module holding the
// KIFACE has hard dependencies on subsidiary DSOs below it, *before* loading
// the KIFACE.
SetLibEnvVar( absoluteArgv0 );
wxString dname = dso_name( absoluteArgv0 );
// Get the getter.
KIFACE_GETTER_FUNC* getter = get_kiface_getter( dname );
// get_kiface_getter() returned NULL? If so it handled the UI message, so
// we can fail without any further UI.
if( !getter )
return false;
// Get the KIFACE, and give the DSO a single chance to do its
// "process level" initialization.
kiface = getter( &kiface_version, KIFACE_VERSION, &wxGetApp() );
if( !kiface )
{
// get_kiface_getter() did its own UI error window, because it called
// functions in wxDynamicLibrary which did so using wxLogSysError().
// Therefore say nothing on failure, it's already been said.
// Return false telling startup code to fail the program immediately.
return false;
}
// Using the KIFACE, create a window that the KIFACE knows about,
// pass classId=0 for now. This uses a virtual function KIFACE::CreateWindow()
// so we don't need to link to it.
wxFrame* frame = (wxFrame*) kiface->CreateWindow( 0, &standalone );
SetTopWindow( frame );
frame->Centre();
frame->Show();
return true;
}

View File

@ -157,9 +157,7 @@ int UTF8::uni_forward( const unsigned char* aSequence, unsigned* aResult )
} }
if( aResult ) if( aResult )
{
*aResult = ch; *aResult = ch;
}
return len; return len;
} }
@ -234,10 +232,7 @@ int main()
for( UTF8::uni_iter it = u2.ubegin(); it < u2.uend(); ) for( UTF8::uni_iter it = u2.ubegin(); it < u2.uend(); )
{ {
// test post-increment: // test post-increment:
printf( " _%c_", *it++ ); printf( " _%02x_", *it++ );
// after UTF8::uni_forward() is implemented, %c is no longer useable.
// printf( " _%02x_", *it++ );
} }
printf( "\n" ); printf( "\n" );

View File

@ -12,8 +12,8 @@ may choose to document this corresponding work in the CHANGELOG.txt file.
/* /*
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2013 <author> * Copyright (C) 2014 <author>
* Copyright (C) 2013 KiCad Developers, see CHANGELOG.TXT for contributors. * Copyright (C) 2014 KiCad Developers, see CHANGELOG.TXT for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License

View File

@ -60,10 +60,11 @@ const wxString titleLibLoadError( _( "Library Load Error" ) );
* MacOSX: Needed for file association * MacOSX: Needed for file association
* http://wiki.wxwidgets.org/WxMac-specific_topics * http://wiki.wxwidgets.org/WxMac-specific_topics
*/ */
void EDA_APP::MacOpenFile( const wxString &fileName ) void EDA_APP::MacOpenFile( const wxString& aFileName )
{ {
wxFileName filename = fileName; wxFileName filename = aFileName;
wxString oldPath; wxString oldPath;
CVPCB_MAINFRAME* frame = (CVPCB_MAINFRAME*) GetTopWindow(); CVPCB_MAINFRAME* frame = (CVPCB_MAINFRAME*) GetTopWindow();
if( !filename.FileExists() ) if( !filename.FileExists() )

View File

@ -1,7 +1,9 @@
add_definitions(-DEESCHEMA) set( MAKE_LINK_MAPS false )
add_definitions( -DEESCHEMA )
include_directories(BEFORE ${INC_BEFORE}) include_directories( BEFORE ${INC_BEFORE} )
include_directories( include_directories(
./dialogs ./dialogs
../common ../common
@ -9,7 +11,8 @@ include_directories(
${INC_AFTER} ${INC_AFTER}
) )
set(EESCHEMA_DLGS
set( EESCHEMA_DLGS
dialogs/dialog_color_config.cpp dialogs/dialog_color_config.cpp
dialogs/dialog_annotate.cpp dialogs/dialog_annotate.cpp
dialogs/dialog_annotate_base.cpp dialogs/dialog_annotate_base.cpp
@ -55,7 +58,7 @@ set(EESCHEMA_DLGS
dialogs/dialog_schematic_find_base.cpp dialogs/dialog_schematic_find_base.cpp
) )
set(EESCHEMA_SRCS set( EESCHEMA_SRCS
annotate.cpp annotate.cpp
backanno.cpp backanno.cpp
block.cpp block.cpp
@ -158,7 +161,7 @@ set(EESCHEMA_SRCS
) )
set(EESCHEMA_COMMON_SRCS set( EESCHEMA_COMMON_SRCS
../common/dialogs/dialog_page_settings.cpp ../common/dialogs/dialog_page_settings.cpp
../common/base_screen.cpp ../common/base_screen.cpp
../common/eda_text.cpp ../common/eda_text.cpp
@ -167,22 +170,22 @@ set(EESCHEMA_COMMON_SRCS
) )
if(WIN32) if( MINGW )
if(MINGW) # EESCHEMA_RESOURCES variable is set by the macro.
# EESCHEMA_RESOURCES variable is set by the macro. mingw_resource_compiler( eeschema )
mingw_resource_compiler(eeschema) endif()
else(MINGW)
set(EESCHEMA_RESOURCES eeschema.rc)
endif(MINGW)
endif(WIN32)
if(APPLE)
set(EESCHEMA_RESOURCES eeschema.icns eeschema_doc.icns) if( APPLE )
set_source_files_properties("${CMAKE_CURRENT_SOURCE_DIR}/eeschema.icns" set( EESCHEMA_RESOURCES eeschema.icns eeschema_doc.icns )
PROPERTIES MACOSX_PACKAGE_LOCATION Resources)
set(MACOSX_BUNDLE_ICON_FILE eeschema.icns) set_source_files_properties( "${CMAKE_CURRENT_SOURCE_DIR}/eeschema.icns" PROPERTIES
set(MACOSX_BUNDLE_GUI_IDENTIFIER org.kicad-eda.eeschema) MACOSX_PACKAGE_LOCATION Resources
endif(APPLE) )
set( MACOSX_BUNDLE_ICON_FILE eeschema.icns )
set( MACOSX_BUNDLE_GUI_IDENTIFIER org.kicad-eda.eeschema )
endif()
# auto-generate cmp_library_lexer.h and cmp_library_keywords.cpp for the component # auto-generate cmp_library_lexer.h and cmp_library_keywords.cpp for the component
@ -211,7 +214,7 @@ make_lexer(
T_BOMCFG_T T_BOMCFG_T
# Pass header file with dependency on *_lexer.h as extra_arg # Pass header file with dependency on *_lexer.h as extra_arg
/dialogs/dialog_bom_cfg.h dialogs/dialog_bom_cfg.h
) )
# Create a C++ compilable string initializer containing html text into a *.h file: # Create a C++ compilable string initializer containing html text into a *.h file:
@ -231,27 +234,82 @@ set_source_files_properties( dialogs/dialog_bom.cpp
OBJECT_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/dialogs/dialog_bom_help_html.h OBJECT_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/dialogs/dialog_bom_help_html.h
) )
add_executable(eeschema WIN32 MACOSX_BUNDLE
${EESCHEMA_SRCS}
${EESCHEMA_COMMON_SRCS}
${EESCHEMA_RESOURCES}
)
if(APPLE) # not ready for even building yet:
set_target_properties(eeschema PROPERTIES MACOSX_BUNDLE_INFO_PLIST if( false AND USE_KIWAY_DLLS )
${CMAKE_CURRENT_SOURCE_DIR}/Info.plist)
endif(APPLE)
target_link_libraries(eeschema add_executable( eeschema WIN32 MACOSX_BUNDLE
common ../common/single_top.cpp
bitmaps )
polygon target_link_libraries( eeschema
${wxWidgets_LIBRARIES} common
${GDI_PLUS_LIBRARIES} ${wxWidgets_LIBRARIES}
) )
install(TARGETS eeschema add_library( eeschema_dso MODULE
${EESCHEMA_SRCS}
${EESCHEMA_COMMON_SRCS}
${EESCHEMA_RESOURCES}
)
set_target_properties( eeschema_dso PROPERTIES
# keep whatever file extension is supplied by SUFFIX, do not use the PREFIX,
# and set the basename. The result is eeschema.so or eeschema.dll.
OUTPUT_NAME eeschema
PREFIX ""
)
if( APPLE )
set_target_properties( eeschema_dso PROPERTIES
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist
)
endif()
if( MAKE_LINK_MAPS )
# generate a link map with cross reference
set_target_properties( eeschema_dso PROPERTIES
LINK_FLAGS "-Wl,-cref -Wl,-Map=eeschema_dso.map"
)
endif()
target_link_libraries( eeschema_dso
common
bitmaps
polygon
${wxWidgets_LIBRARIES}
${GDI_PLUS_LIBRARIES}
)
install( TARGETS eeschema_dso
DESTINATION ${KICAD_BIN} DESTINATION ${KICAD_BIN}
COMPONENT binary) COMPONENT binary
)
else()
add_executable( eeschema WIN32 MACOSX_BUNDLE
${EESCHEMA_SRCS}
${EESCHEMA_COMMON_SRCS}
${EESCHEMA_RESOURCES}
)
add_subdirectory(plugins) if( APPLE )
set_target_properties( eeschema PROPERTIES
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist
)
endif()
target_link_libraries( eeschema
common
bitmaps
polygon
${wxWidgets_LIBRARIES}
${GDI_PLUS_LIBRARIES}
)
endif()
install( TARGETS eeschema
DESTINATION ${KICAD_BIN}
COMPONENT binary
)
add_subdirectory( plugins )

View File

@ -48,6 +48,70 @@
#include <wx/snglinst.h> #include <wx/snglinst.h>
#if defined( USE_KIWAY_DLLS )
#include <kiway.h>
#include <import_export.h>
struct SCH_FACE : public KIFACE
{
wxWindow* CreateWindow( int aClassId, KIWAY* aKIWAY, int aCtlBits = 0 )
{
switch( aClassId )
{
default:
return new SCH_EDIT_FRAME( NULL, wxT( "Eeschema" ),
wxPoint( 0, 0 ), wxSize( 600, 400 ) );
}
}
/**
* Function IfaceOrAddress
* return a pointer to the requested object. The safest way to use this
* is to retrieve a pointer to a static instance of an interface, similar to
* how the KIFACE interface is exported. But if you know what you are doing
* use it to retrieve anything you want.
*
* @param aDataId identifies which object you want the address of.
*
* @return void* - and must be cast into the know type.
*/
VTBL_ENTRY void* IfaceOrAddress( int aDataId )
{
return NULL;
}
} kiface;
static EDA_APP* app;
extern "C" KIFACE* KIFACE_GETTER( int* aKIFACEversion, int aKIWAYversion, wxApp* aProcess );
MY_API( KIFACE* ) KIFACE_GETTER( int* aKIFACEversion, int aKIWAYversion, wxApp* aProcess )
{
app = (EDA_APP*) aProcess;
return &kiface;
}
EDA_APP& wxGetApp()
{
return *app;
}
#else
// Create a new application object: this macro will allow wxWindows to create
// the application object during program execution (it's better than using a
// static object for many reasons) and also declares the accessor function
// wxGetApp() which will return the reference of the right type (i.e. MyApp and
// not wxApp)
IMPLEMENT_APP( EDA_APP )
#endif
// Global variables // Global variables
wxSize g_RepeatStep; wxSize g_RepeatStep;
int g_RepeatDeltaLabel; int g_RepeatDeltaLabel;
@ -61,19 +125,12 @@ TRANSFORM DefaultTransform = TRANSFORM( 1, 0, 0, -1 );
/* Called to initialize the program */ /* Called to initialize the program */
/************************************/ /************************************/
// Create a new application object: this macro will allow wxWindows to create
// the application object during program execution (it's better than using a
// static object for many reasons) and also declares the accessor function
// wxGetApp() which will return the reference of the right type (i.e. MyApp and
// not wxApp)
IMPLEMENT_APP( EDA_APP )
/* MacOSX: Needed for file association /* MacOSX: Needed for file association
* http://wiki.wxwidgets.org/WxMac-specific_topics * http://wiki.wxwidgets.org/WxMac-specific_topics
*/ */
void EDA_APP::MacOpenFile( const wxString &fileName ) void EDA_APP::MacOpenFile( const wxString& aFileName )
{ {
wxFileName filename = fileName; wxFileName filename = aFileName;
SCH_EDIT_FRAME* frame = ((SCH_EDIT_FRAME*) GetTopWindow()); SCH_EDIT_FRAME* frame = ((SCH_EDIT_FRAME*) GetTopWindow());
if( !frame ) if( !frame )
@ -82,7 +139,7 @@ void EDA_APP::MacOpenFile( const wxString &fileName )
if( !filename.FileExists() ) if( !filename.FileExists() )
return; return;
frame->LoadOneEEProject( fileName, false ); frame->LoadOneEEProject( aFileName, false );
} }

View File

@ -67,15 +67,15 @@ IMPLEMENT_APP( EDA_APP )
/* MacOSX: Needed for file association /* MacOSX: Needed for file association
* http://wiki.wxwidgets.org/WxMac-specific_topics * http://wiki.wxwidgets.org/WxMac-specific_topics
*/ */
void EDA_APP::MacOpenFile(const wxString &fileName) void EDA_APP::MacOpenFile( const wxString& aFileName )
{ {
wxFileName filename = fileName; wxFileName filename = aFileName;
GERBVIEW_FRAME * frame = ((GERBVIEW_FRAME*)GetTopWindow()); GERBVIEW_FRAME * frame = ((GERBVIEW_FRAME*)GetTopWindow());
if( !filename.FileExists() ) if( !filename.FileExists() )
return; return;
frame->LoadGerberFiles( fileName ); frame->LoadGerberFiles( aFileName );
} }

View File

@ -1,3 +1,5 @@
#ifndef IMPORT_EXPORT_H_
#define IMPORT_EXPORT_H_
/* /*
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
@ -22,39 +24,33 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
#ifndef IMPORT_EXPORT_H_ // macros which export functions from a DLL/DSO.
#define IMPORT_EXPORT_H_
// macros which export functions from a DLL/DSO. Not yet important with GCC, #if defined(__MINGW32__)
// (either linux or mingw maybe OSX), until you compile with the hidden attribute: #define APIEXPORT __declspec(dllexport)
// -fvisibility=hidden -fvisibility-inlines-hidden, which we are not yet. #define APIIMPORT __declspec(dllimport)
#define APILOCAL
#elif defined(__GNUC__) && __GNUC__ >= 4
#define APIEXPORT __attribute__ ((visibility("default")))
#define APIIMPORT __attribute__ ((visibility("default")))
#define APILOCAL __attribute__ ((visibility("hidden")))
// GCC >= 4.x
#if defined(__GNUC__) && __GNUC__ >= 4
# define APIEXPORT __attribute__ ((visibility("default")))
# define APIIMPORT __attribute__ ((visibility("default")))
# define APILOCAL __attribute__ ((visibility("hidden")))
// windows
#elif (defined(__WINDOWS__) || defined(__CYGWIN__) || defined(_WIN32))
# define APIEXPORT __declspec(dllexport)
# define APIIMPORT __declspec(dllimport)
# define APILOCAL
#else // not windows nor GCC >= 4.x
# define APIEXPORT
# define APIIMPORT
# define APILOCAL
#endif
#ifdef COMPILING_DLL // by CMake magically when compiling implementation.
# define MY_API APIEXPORT
#else #else
# define MY_API APIIMPORT #pragma message ( "warning: a supported C++ compiler is required" )
#define APIEXPORT
#define APIIMPORT
#define APILOCAL
#endif #endif
#define MY_LOCAL APILOCAL
#endif // IMPORT_EXPORTS_H_ #if defined(test_EXPORTS) || defined(COMPILING_DLL)
// above defined by CMake magically when compiling implementation.
#define MY_API(rettype) APIEXPORT rettype
#else
#define MY_API(rettype) APIIMPORT rettype
#endif
#define MY_LOCAL(rettype) APILOCAL rettype
#endif // IMPORT_EXPORT_H_

285
include/kiway.h Normal file
View File

@ -0,0 +1,285 @@
#ifndef KIWAY_H_
#define KIWAY_H_
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2014 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2014 KiCad Developers, see CHANGELOG.TXT for contributors.
*
* 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, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/*
The KIWAY and KIFACE classes are used to communicate between various process
modules, all residing within a single process. The program modules are either
top level like an *.exe or subsidiary like a *.dll. In much of the documentation
the term DSO is used to refer to the *.dll portions, that is the term used on
linux. But it should be taken to mean DLL on Windows.
<p>These are a couple of reasons why this design was chosen:
<ol>
<li>By using DSOs within a single process, it is not necessary to use IPC.
The DSOs can send wxEvents between themselves using wxEvtHandler interfaces in
a platform independent way. There can also be function calls from one DSO to
another.</li>
<li>The use of a number of separately linked DSOs closely resembles the original
KiCad program design, consisting of Eeschema and Pcbnew. But it also allows
separate compilation and linking of those two DSOs without a ton of inter-DSO
dependencies and common data structures. Linking smaller, purpose specific DSOs
is thought to be better for maintenance simplicity than a large single link
image. </li>
<li>By keeping the core functionality in DSOs rather than EXE tops, it becomes
possible to re-use the DSOs under different program tops. For example, a DSO
named _pcbnew.so can be used under a C++ top or under a python top. Only one
CMake target must be defined to build either. Whether that is a separate build
or not is not the important thing. Simply having a single CMake target has
advantages. (Each builder person will have his/her own intentions relative to
use of python or not.) Once a DSO is python capable, it can be driven by any
number of python program tops, including demo-ing (automaton) and testing
separately.</li>
</ol>
All KiCad source code is UTF8 encoded by law, so make sure your editor is set
as such! As such, it is OK to use UTF8 characters:
<pre>
process top
wxEvent channels
-[KIWAY project 1]-
-[KIWAY project 2]-
-[KIWAY project 3]-
||| |||
KIFACE KIFACE
+ + + + + +
wxFrame wxFrame wxFrame wxFrame wxFrame wxFrame
project 1 project 2 project 3 project 3 project 2 project 1
eeschema DSO pcbnew DSO
</pre>
*/
#include <wx/event.h>
#include <wx/dynlib.h>
#include <import_export.h>
#define VTBL_ENTRY virtual
#define KIFACE_VERSION 1
#define KIFACE_GETTER KIFACE_1
// Adjust the spelling of this in a platform specific way if need be. The
// KIFACE acquistion function is declared extern "C" so its name should not
// be mangled. Keep the trailing version number in sync with the KIFACE_GETTER
// define above.
#define KIFACE_INSTANCE_NAME_AND_VERSION "KIFACE_1"
#if defined(__linux__)
#define LIB_ENV_VAR wxT( "LD_LIBRARY_PATH" )
#define DSO_EXT wxT( "so" )
#elif defined(__WXMAC__)
#define LIB_ENV_VAR wxT( "DYLD_LIBRARY_PATH" )
// This should be set to whatever CMake builds when using:
// add_library( target MODULE )
#define DSO_EXT wxT( "so" )
#elif defined(__MINGW32__)
#define LIB_ENV_VAR wxT( "PATH" )
#define DSO_EXT wxT( "dll" )
#endif
/**
* Class PROJECT
* holds project specific data. Because it is in the neutral program top, which
* is not linked to by subsidiarly DSOs, any functions in this interface must
* be VTBL_ENTRYs.
*/
class PROJECT
{
public:
#if 0
/// Derive PROCESS elements from this, it has a virtual destructor, and
/// Elem*() functions can work with it.
class ELEM_BASE
{
public:
virtual ~ELEM_BASE() {}
};
VTBL_ENTRY int ElemAllocNdx();
VTBL_ENTRY void ElemSet( int aIndex, ELEMENT_BASE* aBlock );
VTBL_ENTRY ELEM_BASE* ElemGet( int aIndex )
#endif
};
class KIWAY;
class wxWindow;
class wxApp;
/**
* Struct KIFACE
* is used by a participant in the KIWAY alchemy. KIWAY is a minimalistic
* software bus for communications between various DLLs/DSOs (DSOs) within the same
* KiCad process. It makes it possible to call between DSOs without having to link
* them together. Most all calls are via virtual functions which means C++ vtables
* are used to hold function pointers and eliminate the need to link to specific
* object code libraries. There is one KIWAY in the launching portion of the process
* for each open KiCad project. Each project has its own KIWAY. Within a KIWAY
* is an actual PROJECT data structure. A KIWAY also facilitates communicating
* between DSOs on the topic of the project in question.
*/
struct KIFACE
{
// Do not change the order of functions in this listing, add new ones at
// the end, unless you recompile all of KiCad.
#define KFCTL_STANDALONE (1<<0) ///< Am running as a standalone Top.
/**
* Function CreateWindow
* creates a wxTopLevelWindow for the current project. The caller
* must cast the return value into the known type.
*
* @param aClassId identifies which wxFrame or wxDialog to retrieve.
*
* @param aKIWAY tells the window which KIWAY (and PROJECT) it is a participant in.
*
* @param aCtlBits consists of bit flags from the set KFCTL_* #defined above.
*
* @return wxWindow* - and if not NULL, should be cast into the known type.
*/
VTBL_ENTRY wxWindow* CreateWindow( int aClassId, KIWAY* aKIWAY, int aCtlBits = 0 ) = 0;
/**
* Function IfaceOrAddress
* return a pointer to the requested object. The safest way to use this
* is to retrieve a pointer to a static instance of an interface, similar to
* how the KIFACE interface is exported. But if you know what you are doing
* use it to retrieve anything you want.
*
* @param aDataId identifies which object you want the address of.
*
* @return void* - and must be cast into the know type.
*/
VTBL_ENTRY void* IfaceOrAddress( int aDataId ) = 0;
};
/**
* Class KIWAY
* is a minimalistic software bus for communications between various
* DLLs/DSOs (DSOs) within the same KiCad process. It makes it possible
* to call between DSOs without having to link them together, and without
* having to link to the top process module which houses the KIWAY(s). It also
* makes it possible to send custom wxEvents between DSOs and from the top
* process module down into the DSOs. The latter capability is thought useful
* for driving the lower DSOs from a python test rig or for demo (automaton) purposes.
* <p>
* Most all calls are via virtual functions which means C++ vtables
* are used to hold function pointers and eliminate the need to link to specific
* object code libraries, speeding development and encourage clearly defined
* interface design. There is one KIWAY in the launching portion of the process
* for each open KiCad project. Each project has its own KIWAY. Within a KIWAY
* is an actual PROJECT data structure. In summary, a KIWAY facilitates
* communicating between DSOs, where the topic of the communication is
* project specific. Here a "project" means a BOARD and a SCHEMATIC and a NETLIST,
* (anything relating to production of a single BOARD and added to class PROJECT.)
*/
class KIWAY : public wxEvtHandler
{
public:
/// DSO players on *this* KIWAY
enum FACE_T
{
FACE_SCH, ///< _eeschema DSO
// FACE_LIB,
FACE_PCB, ///< _pcbnew DSO
// FACE_MOD,
FACE_COUNT ///< how many KIWAY player types
};
// Don't change the order of these VTBL_ENTRYs, add new ones at the end,
// unless you recompile all of KiCad.
VTBL_ENTRY KIFACE* KiFACE( FACE_T aFaceId, bool doLoad );
VTBL_ENTRY PROJECT& Project();
KIWAY();
private:
/// Get the name of the DSO holding the requested FACE_T.
static const wxString dso_name( FACE_T aFaceId );
// one for each FACE_T
static wxDynamicLibrary s_sch_dso;
static wxDynamicLibrary s_pcb_dso;
//static wxDynamicLibrary s_cvpcb_dso; // will get merged into pcbnew
KIFACE* m_dso_players[FACE_COUNT];
PROJECT m_project;
};
/**
* Function Pointer KIFACE_GETTER_FUNC
* points to the one and only KIFACE export. The export's address
* is looked up via symbolic string and should be extern "C" to avoid name
* mangling. That function can also implement process initialization functionality,
* things to do once per process that is DSO resident. This function will only be
* called one time. The DSO itself however may be asked to support multiple
* Top windows, i.e. multiple projects within its lifetime.
*
* @param aKIFACEversion is where to put the API version implemented by the KIFACE.
* @param aKIWAYversion tells the KIFACE what KIWAY version will be available.
* @param aProcess is a pointer to the basic wxApp for this process.
*/
typedef KIFACE* KIFACE_GETTER_FUNC( int* aKIFACEversion, int aKIWAYversion, wxApp* aProcess );
#endif // KIWAY_H_

View File

@ -55,14 +55,15 @@ public:
UTF8( const wxString& o ); UTF8( const wxString& o );
/// This is the only constructor for which you could end up with /// This is a constructor for which you could end up with
/// non-UTF8 encoding, but that would be your fault. /// non-UTF8 encoding, but that would be your fault.
UTF8( const char* txt ) : UTF8( const char* txt ) :
std::string( txt ) std::string( txt )
{ {
} }
/// For use with _() function on wx 2.8: /// For use with _() function on wx 2.8.
/// BTW _() on wx >= 2.9 returns wxString, not wchar_t* like on 2.8.
UTF8( const wchar_t* txt ); UTF8( const wchar_t* txt );
UTF8( const std::string& o ) : UTF8( const std::string& o ) :
@ -124,7 +125,7 @@ public:
* class uni_iter * class uni_iter
* is a non-muting iterator that walks through unicode code points in the UTF8 encoded * is a non-muting iterator that walks through unicode code points in the UTF8 encoded
* string. The normal ++(), ++(int), ->(), and *() operators are all supported * string. The normal ++(), ++(int), ->(), and *() operators are all supported
* for read only access and they return an unsigned holding the unicode character * for read only access and some return an unsigned holding the unicode character
* appropriate for the respective operator. * appropriate for the respective operator.
*/ */
class uni_iter class uni_iter
@ -152,7 +153,6 @@ public:
const uni_iter& operator++() const uni_iter& operator++()
{ {
it += uni_forward( it ); it += uni_forward( it );
return *this; return *this;
} }
@ -217,4 +217,4 @@ public:
} }
}; };
#endif // UTF8_H__ #endif // UTF8_H_

View File

@ -49,10 +49,11 @@ IMPLEMENT_APP( EDA_APP )
/* MacOSX: Needed for file association /* MacOSX: Needed for file association
* http://wiki.wxwidgets.org/WxMac-specific_topics * http://wiki.wxwidgets.org/WxMac-specific_topics
*/ */
void EDA_APP::MacOpenFile( const wxString &fileName ) void EDA_APP::MacOpenFile( const wxString& aFileName )
{ {
KICAD_MANAGER_FRAME* frame = (KICAD_MANAGER_FRAME*) GetTopWindow(); KICAD_MANAGER_FRAME* frame = (KICAD_MANAGER_FRAME*) GetTopWindow();
wxFileName fn = fileName;
wxFileName fn = aFileName;
frame->m_ProjectFileName = fn; frame->m_ProjectFileName = fn;

View File

@ -48,15 +48,15 @@ IMPLEMENT_APP( EDA_APP )
/* MacOSX: Needed for file association /* MacOSX: Needed for file association
* http://wiki.wxwidgets.org/WxMac-specific_topics * http://wiki.wxwidgets.org/WxMac-specific_topics
*/ */
void EDA_APP::MacOpenFile(const wxString &fileName) void EDA_APP::MacOpenFile( const wxString& aFileName )
{ {
wxFileName filename = fileName; PL_EDITOR_FRAME* frame = ((PL_EDITOR_FRAME*)GetTopWindow());
PL_EDITOR_FRAME * frame = ((PL_EDITOR_FRAME*)GetTopWindow()); wxFileName filename = aFileName;
if( !filename.FileExists() ) if( !filename.FileExists() )
return; return;
frame->LoadPageLayoutDescrFile( fileName ); frame->LoadPageLayoutDescrFile( aFileName );
} }

View File

@ -43,7 +43,7 @@ const wxString PcbCalcDataFileExt( wxT("pcbcalc") );
// PCB_CALCULATOR_APP // PCB_CALCULATOR_APP
void EDA_APP::MacOpenFile(const wxString &fileName) void EDA_APP::MacOpenFile( const wxString& aFileName )
{ {
} }
@ -56,7 +56,6 @@ IMPLEMENT_APP( EDA_APP )
bool EDA_APP::OnInit() bool EDA_APP::OnInit()
{ {
InitEDA_Appl( wxT( "pcb_calculator" ) ); InitEDA_Appl( wxT( "pcb_calculator" ) );
wxFrame* frame = new PCB_CALCULATOR_FRAME( NULL ); wxFrame* frame = new PCB_CALCULATOR_FRAME( NULL );

View File

@ -89,15 +89,15 @@ IMPLEMENT_APP( EDA_APP )
/* MacOSX: Needed for file association /* MacOSX: Needed for file association
* http://wiki.wxwidgets.org/WxMac-specific_topics * http://wiki.wxwidgets.org/WxMac-specific_topics
*/ */
void EDA_APP::MacOpenFile( const wxString& fileName ) void EDA_APP::MacOpenFile( const wxString& aFileName )
{ {
wxFileName filename = fileName;
PCB_EDIT_FRAME* frame = ( (PCB_EDIT_FRAME*) GetTopWindow() ); PCB_EDIT_FRAME* frame = ( (PCB_EDIT_FRAME*) GetTopWindow() );
wxFileName filename = aFileName;
if( !filename.FileExists() ) if( !filename.FileExists() )
return; return;
frame->LoadOnePcbFile( fileName, false ); frame->LoadOnePcbFile( aFileName, false );
} }
@ -216,9 +216,9 @@ bool EDA_APP::OnInit()
frame = new PCB_EDIT_FRAME( NULL, wxT( "Pcbnew" ), wxPoint( 0, 0 ), wxSize( 600, 400 ) ); frame = new PCB_EDIT_FRAME( NULL, wxT( "Pcbnew" ), wxPoint( 0, 0 ), wxSize( 600, 400 ) );
#ifdef KICAD_SCRIPTING #ifdef KICAD_SCRIPTING
ScriptingSetPcbEditFrame(frame); /* give the scripting helpers access to our frame */ ScriptingSetPcbEditFrame(frame); /* give the scripting helpers access to our frame */
#endif #endif
frame->UpdateTitle(); frame->UpdateTitle();
@ -282,7 +282,8 @@ bool EDA_APP::OnInit()
} }
if( ! file_exists ) if( ! file_exists )
{ // File does not exists: prepare an empty board {
// File does not exists: prepare an empty board
if( ! fn.GetPath().IsEmpty() ) if( ! fn.GetPath().IsEmpty() )
wxSetWorkingDirectory( fn.GetPath() ); wxSetWorkingDirectory( fn.GetPath() );

View File

@ -1,4 +1,5 @@
set( MAKE_LINK_MAPS true )
if( 0 ) if( 0 )
@ -76,3 +77,58 @@ target_link_libraries( property_tree
${wxWidgets_LIBRARIES} ${wxWidgets_LIBRARIES}
) )
#-----<MACOSX Temp Testing>------------------------------------------------------
# The small launcher, it sets up wxWidgets library and loads a MODULE by the same name
# but with extension *.dylib. The two files: mac_test and mac_test.dylib must be in
# same directory for the launcher to find the *.dylib.
set( PAIR_BASE dso )
add_executable( ${PAIR_BASE} WIN32 MACOSX_BUNDLE
EXCLUDE_FROM_ALL
../common/single_top.cpp
)
target_link_libraries( ${PAIR_BASE}
common
${wxWidgets_LIBRARIES}
)
# make a DLL/DSO/DYLIB, but *_dso is not its real name, see OUTPUT_NAME below.
add_library( ${PAIR_BASE}_dso MODULE
EXCLUDE_FROM_ALL
mac_test.cpp
)
target_link_libraries( ${PAIR_BASE}_dso
common
${wxWidgets_LIBRARIES}
)
set_target_properties( ${PAIR_BASE}_dso PROPERTIES
# keep whatever file extension is supplied by SUFFIX, do not use the PREFIX,
# and set the basename. The result is ${PAIR_BASE}.so or ${PAIR_BASE}.dll,
# or ${PAIR_BASE}.dylib
OUTPUT_NAME ${PAIR_BASE}
PREFIX "_"
)
if( APPLE )
set_target_properties( ${PAIR_BASE} PROPERTIES
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist
)
endif()
if( MAKE_LINK_MAPS )
# generate a link maps with cross reference
set_target_properties( ${PAIR_BASE}_dso PROPERTIES
LINK_FLAGS "${TO_LINKER},-cref ${TO_LINKER},-Map=${PAIR_BASE}_dso.map"
)
set_target_properties( ${PAIR_BASE} PROPERTIES
LINK_FLAGS "${TO_LINKER},-cref ${TO_LINKER},-Map=${PAIR_BASE}.map"
)
endif()

60
tools/mac_test.cpp Normal file
View File

@ -0,0 +1,60 @@
#include <wx/app.h>
#include <wx/frame.h>
#include <kiway.h>
// test static initialization, and translation in the DSO:
wxString GlobalTitle = _( "Some Translatable Window Title Text" );
/// Implement a KIFACE, and create a static instance of one.
static struct SCH_FACE : public KIFACE
{
wxWindow* CreateWindow( int aClassId, KIWAY* aKIWAY, int aCtlBits = 0 )
{
switch( aClassId )
{
// for now, I have no class:
default:
return new wxFrame( NULL, 0, GlobalTitle, wxPoint( 0, 0 ), wxSize( 600, 400 ) );
}
}
/**
* Function IfaceOrAddress
* return a pointer to the requested object. The safest way to use this
* is to retrieve a pointer to a static instance of an interface, similar to
* how the KIFACE interface is exported. But if you know what you are doing
* use it to retrieve anything you want.
*
* @param aDataId identifies which object you want the address of.
*
* @return void* - and must be cast into the known type.
*/
void* IfaceOrAddress( int aDataId )
{
return NULL;
}
} kiface_impl;
static wxApp* app;
extern "C" KIFACE* KIFACE_GETTER( int* aKIFACEversion, int aKIWAYversion, wxApp* aProcess );
MY_API( KIFACE* ) KIFACE_GETTER( int* aKIFACEversion, int aKIWAYversion, wxApp* aProcess )
{
// record the app's address.
app = aProcess;
// return a pointer to the KIFACE implementation.
return &kiface_impl;
}
wxApp& wxGetApp()
{
return *app;
}