diff --git a/CMakeLists.txt b/CMakeLists.txt index c566cb45f3..18c2638636 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 ) cmake_minimum_required( VERSION 2.8.4 FATAL_ERROR ) diff --git a/CMakeModules/config.h.cmake b/CMakeModules/config.h.cmake index 00ae9a6bd1..fe255e07da 100644 --- a/CMakeModules/config.h.cmake +++ b/CMakeModules/config.h.cmake @@ -67,6 +67,9 @@ /// When defined, build the GITHUB_PLUGIN for pcbnew. #cmakedefine BUILD_GITHUB_PLUGIN +/// When defined, use KIWAY and DSOs +#cmakedefine USE_KIWAY_DLLS + /// Name of repo from which this build came. #define KICAD_REPO_NAME "@KICAD_REPO_NAME@" diff --git a/bitmap2component/bitmap2cmp_gui.cpp b/bitmap2component/bitmap2cmp_gui.cpp index 677f120d16..d83a0fce8c 100644 --- a/bitmap2component/bitmap2cmp_gui.cpp +++ b/bitmap2component/bitmap2cmp_gui.cpp @@ -548,6 +548,6 @@ bool EDA_APP::OnInit() } -void EDA_APP::MacOpenFile(const wxString &fileName) +void EDA_APP::MacOpenFile( const wxString& aFileName ) { } diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 44569f29e2..917ff1381a 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -131,6 +131,7 @@ set( COMMON_SRCS hotkeys_basic.cpp hotkey_grid_table.cpp html_messagebox.cpp + kiway.cpp msgpanel.cpp netlist_keywords.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} ) set( PCB_COMMON_SRCS diff --git a/common/kiway.cpp b/common/kiway.cpp new file mode 100644 index 0000000000..895f4db2a9 --- /dev/null +++ b/common/kiway.cpp @@ -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 + * 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 +#include +#include + +// 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; +} diff --git a/common/single_top.cpp b/common/single_top.cpp new file mode 100644 index 0000000000..8620e0f861 --- /dev/null +++ b/common/single_top.cpp @@ -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 + * 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 +#include +#include +#include +#include +#include + + +/** + * 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; +} + diff --git a/common/utf8.cpp b/common/utf8.cpp index 637d9fc8e1..b90e4a761d 100644 --- a/common/utf8.cpp +++ b/common/utf8.cpp @@ -157,9 +157,7 @@ int UTF8::uni_forward( const unsigned char* aSequence, unsigned* aResult ) } if( aResult ) - { *aResult = ch; - } return len; } @@ -234,10 +232,7 @@ int main() for( UTF8::uni_iter it = u2.ubegin(); it < u2.uend(); ) { // test post-increment: - printf( " _%c_", *it++ ); - - // after UTF8::uni_forward() is implemented, %c is no longer useable. - // printf( " _%02x_", *it++ ); + printf( " _%02x_", *it++ ); } printf( "\n" ); diff --git a/copyright.h b/copyright.h index 2410356303..79a50ecc4d 100644 --- a/copyright.h +++ b/copyright.h @@ -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. * - * Copyright (C) 2013 - * Copyright (C) 2013 KiCad Developers, see CHANGELOG.TXT for contributors. + * Copyright (C) 2014 + * 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 diff --git a/cvpcb/cvpcb.cpp b/cvpcb/cvpcb.cpp index a40e48f17e..84a1ae8b73 100644 --- a/cvpcb/cvpcb.cpp +++ b/cvpcb/cvpcb.cpp @@ -60,10 +60,11 @@ const wxString titleLibLoadError( _( "Library Load Error" ) ); * MacOSX: Needed for file association * http://wiki.wxwidgets.org/WxMac-specific_topics */ -void EDA_APP::MacOpenFile( const wxString &fileName ) +void EDA_APP::MacOpenFile( const wxString& aFileName ) { - wxFileName filename = fileName; - wxString oldPath; + wxFileName filename = aFileName; + wxString oldPath; + CVPCB_MAINFRAME* frame = (CVPCB_MAINFRAME*) GetTopWindow(); if( !filename.FileExists() ) diff --git a/eeschema/CMakeLists.txt b/eeschema/CMakeLists.txt index 82d8c544ba..0776a9ff13 100644 --- a/eeschema/CMakeLists.txt +++ b/eeschema/CMakeLists.txt @@ -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( ./dialogs ../common @@ -9,7 +11,8 @@ include_directories( ${INC_AFTER} ) -set(EESCHEMA_DLGS + +set( EESCHEMA_DLGS dialogs/dialog_color_config.cpp dialogs/dialog_annotate.cpp dialogs/dialog_annotate_base.cpp @@ -55,7 +58,7 @@ set(EESCHEMA_DLGS dialogs/dialog_schematic_find_base.cpp ) -set(EESCHEMA_SRCS +set( EESCHEMA_SRCS annotate.cpp backanno.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/base_screen.cpp ../common/eda_text.cpp @@ -167,22 +170,22 @@ set(EESCHEMA_COMMON_SRCS ) -if(WIN32) - if(MINGW) - # EESCHEMA_RESOURCES variable is set by the macro. - mingw_resource_compiler(eeschema) - else(MINGW) - set(EESCHEMA_RESOURCES eeschema.rc) - endif(MINGW) -endif(WIN32) +if( MINGW ) + # EESCHEMA_RESOURCES variable is set by the macro. + mingw_resource_compiler( eeschema ) +endif() -if(APPLE) - set(EESCHEMA_RESOURCES eeschema.icns eeschema_doc.icns) - set_source_files_properties("${CMAKE_CURRENT_SOURCE_DIR}/eeschema.icns" - PROPERTIES MACOSX_PACKAGE_LOCATION Resources) - set(MACOSX_BUNDLE_ICON_FILE eeschema.icns) - set(MACOSX_BUNDLE_GUI_IDENTIFIER org.kicad-eda.eeschema) -endif(APPLE) + +if( APPLE ) + set( EESCHEMA_RESOURCES eeschema.icns eeschema_doc.icns ) + + set_source_files_properties( "${CMAKE_CURRENT_SOURCE_DIR}/eeschema.icns" PROPERTIES + MACOSX_PACKAGE_LOCATION Resources + ) + + 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 @@ -211,7 +214,7 @@ make_lexer( T_BOMCFG_T # 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: @@ -231,27 +234,82 @@ set_source_files_properties( dialogs/dialog_bom.cpp 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) - set_target_properties(eeschema PROPERTIES MACOSX_BUNDLE_INFO_PLIST - ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist) -endif(APPLE) +# not ready for even building yet: +if( false AND USE_KIWAY_DLLS ) -target_link_libraries(eeschema - common - bitmaps - polygon - ${wxWidgets_LIBRARIES} - ${GDI_PLUS_LIBRARIES} - ) + add_executable( eeschema WIN32 MACOSX_BUNDLE + ../common/single_top.cpp + ) + target_link_libraries( eeschema + common + ${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} - 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 ) diff --git a/eeschema/eeschema.cpp b/eeschema/eeschema.cpp index c141046562..bb530ddd2e 100644 --- a/eeschema/eeschema.cpp +++ b/eeschema/eeschema.cpp @@ -48,6 +48,70 @@ #include +#if defined( USE_KIWAY_DLLS ) + +#include +#include + +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 wxSize g_RepeatStep; int g_RepeatDeltaLabel; @@ -61,19 +125,12 @@ TRANSFORM DefaultTransform = TRANSFORM( 1, 0, 0, -1 ); /* 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 * 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()); if( !frame ) @@ -82,7 +139,7 @@ void EDA_APP::MacOpenFile( const wxString &fileName ) if( !filename.FileExists() ) return; - frame->LoadOneEEProject( fileName, false ); + frame->LoadOneEEProject( aFileName, false ); } diff --git a/gerbview/gerbview.cpp b/gerbview/gerbview.cpp index 57d2b8462f..b1537bb0d1 100644 --- a/gerbview/gerbview.cpp +++ b/gerbview/gerbview.cpp @@ -67,15 +67,15 @@ IMPLEMENT_APP( EDA_APP ) /* MacOSX: Needed for file association * 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()); if( !filename.FileExists() ) return; - frame->LoadGerberFiles( fileName ); + frame->LoadGerberFiles( aFileName ); } diff --git a/new/import_export.h b/include/import_export.h similarity index 56% rename from new/import_export.h rename to include/import_export.h index b3b5b1291d..eed48fb797 100644 --- a/new/import_export.h +++ b/include/import_export.h @@ -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. * @@ -22,39 +24,33 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ -#ifndef IMPORT_EXPORT_H_ -#define IMPORT_EXPORT_H_ +// macros which export functions from a DLL/DSO. -// macros which export functions from a DLL/DSO. Not yet important with GCC, -// (either linux or mingw maybe OSX), until you compile with the hidden attribute: -// -fvisibility=hidden -fvisibility-inlines-hidden, which we are not yet. +#if defined(__MINGW32__) + #define APIEXPORT __declspec(dllexport) + #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 -# define MY_API APIIMPORT + #pragma message ( "warning: a supported C++ compiler is required" ) + #define APIEXPORT + #define APIIMPORT + #define APILOCAL #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_ diff --git a/include/kiway.h b/include/kiway.h new file mode 100644 index 0000000000..d5013b09ad --- /dev/null +++ b/include/kiway.h @@ -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 + * 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. + +

These are a couple of reasons why this design was chosen: + +

    + +
  1. 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.
  2. + +
  3. 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.
  4. + +
  5. 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.
  6. + + +
+ +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: + +┏ ┗ ┓ ┛ ━ ┃ + +
+
+                             ┏━━━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 ━━━━━━━━━━━━━━━━━┛
+
+
+ +*/ + + +#include +#include +#include + + +#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. + *

+ * 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_ diff --git a/include/utf8.h b/include/utf8.h index c1bf94a971..6f618a3897 100644 --- a/include/utf8.h +++ b/include/utf8.h @@ -55,14 +55,15 @@ public: 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. UTF8( const char* 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 std::string& o ) : @@ -124,7 +125,7 @@ public: * class uni_iter * is a non-muting iterator that walks through unicode code points in the UTF8 encoded * 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. */ class uni_iter @@ -152,7 +153,6 @@ public: const uni_iter& operator++() { it += uni_forward( it ); - return *this; } @@ -217,4 +217,4 @@ public: } }; -#endif // UTF8_H__ +#endif // UTF8_H_ diff --git a/kicad/kicad.cpp b/kicad/kicad.cpp index 672308ab29..b603c06432 100644 --- a/kicad/kicad.cpp +++ b/kicad/kicad.cpp @@ -49,10 +49,11 @@ IMPLEMENT_APP( EDA_APP ) /* MacOSX: Needed for file association * 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(); - wxFileName fn = fileName; + + wxFileName fn = aFileName; frame->m_ProjectFileName = fn; diff --git a/pagelayout_editor/pl_editor.cpp b/pagelayout_editor/pl_editor.cpp index ed1d0e2a5f..f8657090dd 100644 --- a/pagelayout_editor/pl_editor.cpp +++ b/pagelayout_editor/pl_editor.cpp @@ -48,15 +48,15 @@ IMPLEMENT_APP( EDA_APP ) /* MacOSX: Needed for file association * 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() ) return; - frame->LoadPageLayoutDescrFile( fileName ); + frame->LoadPageLayoutDescrFile( aFileName ); } diff --git a/pcb_calculator/pcb_calculator.cpp b/pcb_calculator/pcb_calculator.cpp index 09cb48d3f4..adeae6d2a6 100644 --- a/pcb_calculator/pcb_calculator.cpp +++ b/pcb_calculator/pcb_calculator.cpp @@ -43,7 +43,7 @@ const wxString PcbCalcDataFileExt( wxT("pcbcalc") ); // 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() { - InitEDA_Appl( wxT( "pcb_calculator" ) ); wxFrame* frame = new PCB_CALCULATOR_FRAME( NULL ); diff --git a/pcbnew/pcbnew.cpp b/pcbnew/pcbnew.cpp index 2d76584f36..37e0d12057 100644 --- a/pcbnew/pcbnew.cpp +++ b/pcbnew/pcbnew.cpp @@ -89,15 +89,15 @@ IMPLEMENT_APP( EDA_APP ) /* MacOSX: Needed for file association * 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() ); + wxFileName filename = aFileName; if( !filename.FileExists() ) 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 ) ); - #ifdef KICAD_SCRIPTING +#ifdef KICAD_SCRIPTING ScriptingSetPcbEditFrame(frame); /* give the scripting helpers access to our frame */ - #endif +#endif frame->UpdateTitle(); @@ -282,7 +282,8 @@ bool EDA_APP::OnInit() } if( ! file_exists ) - { // File does not exists: prepare an empty board + { + // File does not exists: prepare an empty board if( ! fn.GetPath().IsEmpty() ) wxSetWorkingDirectory( fn.GetPath() ); diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index daebd3fc47..bd9668017c 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -1,4 +1,5 @@ +set( MAKE_LINK_MAPS true ) if( 0 ) @@ -76,3 +77,58 @@ target_link_libraries( property_tree ${wxWidgets_LIBRARIES} ) + +#----------------------------------------------------------- + +# 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() diff --git a/tools/mac_test.cpp b/tools/mac_test.cpp new file mode 100644 index 0000000000..a7a5d89797 --- /dev/null +++ b/tools/mac_test.cpp @@ -0,0 +1,60 @@ + +#include +#include +#include + + +// 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; +} +