21 changed files with 1028 additions and 121 deletions
-
9CMakeLists.txt
-
3CMakeModules/config.h.cmake
-
2bitmap2component/bitmap2cmp_gui.cpp
-
11common/CMakeLists.txt
-
95common/kiway.cpp
-
300common/single_top.cpp
-
7common/utf8.cpp
-
4copyright.h
-
7cvpcb/cvpcb.cpp
-
140eeschema/CMakeLists.txt
-
77eeschema/eeschema.cpp
-
6gerbview/gerbview.cpp
-
48include/import_export.h
-
285include/kiway.h
-
10include/utf8.h
-
5kicad/kicad.cpp
-
8pagelayout_editor/pl_editor.cpp
-
3pcb_calculator/pcb_calculator.cpp
-
13pcbnew/pcbnew.cpp
-
56tools/CMakeLists.txt
-
60tools/mac_test.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 <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; |
|||
} |
|||
@ -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; |
|||
} |
|||
|
|||
@ -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_ |
|||
@ -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; |
|||
} |
|||
|
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue