14 changed files with 1409 additions and 358 deletions
-
2423d-viewer/3d_cache/3d_plugin_manager.cpp
-
83d-viewer/3d_cache/3d_plugin_manager.h
-
43d-viewer/CMakeLists.txt
-
162include/plugins/3d/3d_plugin.h
-
112include/plugins/kicad_plugin.h
-
4plugins/3d/CMakeLists.txt
-
122plugins/3d/idf/s3d_plugin_idf.cpp
-
57plugins/3d/idf/s3d_plugin_idf.h
-
364plugins/ldr/3d/pluginldr3D.cpp
-
90plugins/ldr/3d/pluginldr3D.h
-
2plugins/ldr/README.txt
-
438plugins/ldr/pluginldr.cpp
-
158plugins/ldr/pluginldr.h
-
4utils/idftools/vrml_layer.cpp
@ -0,0 +1,112 @@ |
|||
/* |
|||
* This program source code file is part of KiCad, a free EDA CAD application. |
|||
* |
|||
* Copyright (C) 2015 Cirilo Bernardo <cirilo.bernardo@gmail.com> |
|||
* |
|||
* 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 |
|||
*/ |
|||
|
|||
/** |
|||
* @file kicad_plugin.h |
|||
* defines the most basic functions which all kicad plugins must implement. |
|||
* In the implementation the definitions must make use of the KICAD_PLUGIN_EXPORT |
|||
* to ensure symbol visibility. |
|||
*/ |
|||
|
|||
#ifndef KICAD_PLUGIN_H |
|||
#define KICAD_PLUGIN_H |
|||
|
|||
#ifndef _WIN32 |
|||
#ifndef KICAD_PLUGIN_EXPORT |
|||
#define KICAD_PLUGIN_EXPORT extern "C" __attribute__((__visibility__("default"))) |
|||
#endif |
|||
#else |
|||
#include <cstdint> |
|||
#ifndef KICAD_PLUGIN_EXPORT |
|||
#define KICAD_PLUGIN_EXPORT extern "C" __declspec( dllexport ) |
|||
#endif |
|||
#endif |
|||
|
|||
/** |
|||
* Function GetKicadPluginClass |
|||
* returns the name of the implemented plugin class; for |
|||
* example 3DPLUGIN. This should be implemented in a source |
|||
* module which is compiled as part of every implementation |
|||
* of a specific plugin class. |
|||
* |
|||
* @return is the NULL-terminated UTF-8 string representing the |
|||
* plugin class |
|||
*/ |
|||
KICAD_PLUGIN_EXPORT char const* GetKicadPluginClass( void ); |
|||
|
|||
/** |
|||
* Function GetClassVersion |
|||
* retrieves the version of the Plugin Class. This value is used to |
|||
* ensure API compatibility of a plugin as per typical practice. This must |
|||
* be implemented in a source module which is compiled as part of every |
|||
* implementation of a specific plugin class |
|||
* |
|||
* @param Major will hold the Plugin Class Major version |
|||
* @param Minor will hold the Plugin Class Minor version |
|||
* @param Revision will hold the Plugin Class Revision |
|||
* @param Patch will hold the Plugin Class Patch level |
|||
*/ |
|||
KICAD_PLUGIN_EXPORT void GetClassVersion( unsigned char* Major, |
|||
unsigned char* Minor, unsigned char* Revision, unsigned char* Patch ); |
|||
|
|||
/** |
|||
* Function CheckClassVersion |
|||
* returns true if the class version reported by the Plugin Loader |
|||
* is compatible with the specific implementation of a plugin. |
|||
* This function must be defined by each specific plugin and it is |
|||
* the plugin developer's responsibility to ensure that the Plugin |
|||
* is in fact compatible with the Plugin Loader. The Plugin Loader |
|||
* shall reject any Plugin with a different Major number regardless |
|||
* of the return value of this function. |
|||
*/ |
|||
KICAD_PLUGIN_EXPORT bool CheckClassVersion( unsigned char Major, |
|||
unsigned char Minor, unsigned char Revision, unsigned char Patch ); |
|||
|
|||
/** |
|||
* Function GetKicadPluginName |
|||
* returns the name of the plugin instance; for example IDFv3. |
|||
* This string may be used to check for name conflicts or to |
|||
* display informational messages about loaded plugins. This method |
|||
* must be implemented in specific instantiations of a plugin class. |
|||
* |
|||
* @return is the NULL-terminated UTF-8 string representing the |
|||
* plugin name |
|||
*/ |
|||
KICAD_PLUGIN_EXPORT const char* GetKicadPluginName( void ); |
|||
|
|||
|
|||
/** |
|||
* Function GetVersion |
|||
* retrieves the version of the instantiated plugin for informational |
|||
* purposes. Do not confuse this with GetAPIVersion which is used to |
|||
* determine API compatibility. |
|||
* |
|||
* @param Major will hold the Plugin Major version |
|||
* @param Minor will hold the Plugin Minor version |
|||
* @param Revision will hold the Plugin Revision |
|||
* @param Patch will hold the Plugin Patch level |
|||
*/ |
|||
KICAD_PLUGIN_EXPORT void GetVersion( unsigned char* Major, |
|||
unsigned char* Minor, unsigned char* Revision, unsigned char* Patch ); |
|||
|
|||
#endif // KICAD_PLUGIN_H |
|||
@ -1,3 +1,3 @@ |
|||
add_subdirectory( dummy ) |
|||
add_subdirectory( tetra ) |
|||
#add_subdirectory( dummy ) |
|||
#add_subdirectory( tetra ) |
|||
add_subdirectory( idf ) |
|||
@ -1,57 +0,0 @@ |
|||
/* |
|||
* This program source code file is part of KiCad, a free EDA CAD application. |
|||
* |
|||
* Copyright (C) 2015 Cirilo Bernardo <cirilo.bernardo@gmail.com> |
|||
* |
|||
* 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 |
|||
*/ |
|||
|
|||
/** |
|||
* @file 3d_plugin_idf.h |
|||
* is a 3D plugin to support the rendering of IDF component outlines |
|||
*/ |
|||
|
|||
|
|||
#ifndef PLUGIN_3D_IDF_H |
|||
#define PLUGIN_3D_IDF_H |
|||
|
|||
#include <vector> |
|||
#include <plugins/3d/3d_plugin.h> |
|||
|
|||
class SCENEGRAPH; |
|||
|
|||
class S3D_PLUGIN_IDF : public S3D_PLUGIN |
|||
{ |
|||
private: |
|||
std::vector< wxString > m_extensions; // supported extensions |
|||
std::vector< wxString > m_filters; // file filters |
|||
|
|||
public: |
|||
S3D_PLUGIN_IDF(); |
|||
virtual ~S3D_PLUGIN_IDF(); |
|||
|
|||
virtual int GetNExtensions( void ) const; |
|||
virtual const wxString GetModelExtension( int aIndex ) const; |
|||
virtual int GetNFilters( void ) const; |
|||
virtual const wxString GetFileFilter( int aIndex ) const; |
|||
|
|||
bool CanRender( void ) const; |
|||
SCENEGRAPH* Load( const wxString& aFileName ); |
|||
}; |
|||
|
|||
#endif // PLUGIN_3D_IDF_H |
|||
@ -0,0 +1,364 @@ |
|||
/*
|
|||
* This program source code file is part of KiCad, a free EDA CAD application. |
|||
* |
|||
* Copyright (C) 2015 Cirilo Bernardo <cirilo.bernardo@gmail.com> |
|||
* |
|||
* 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 <sstream>
|
|||
#include <iostream>
|
|||
#include "plugins/ldr/3d/pluginldr3D.h"
|
|||
|
|||
#define PLUGIN_CLASS_3D "PLUGIN_3D"
|
|||
#define PLUGIN_3D_MAJOR 1
|
|||
#define PLUGIN_3D_MINOR 0
|
|||
#define PLUGIN_3D_REVISION 0
|
|||
#define PLUGIN_3D_PATCH 0
|
|||
|
|||
|
|||
KICAD_PLUGIN_LDR_3D::KICAD_PLUGIN_LDR_3D() |
|||
{ |
|||
ok = false; |
|||
m_getNExtensions = NULL; |
|||
m_getModelExtension = NULL; |
|||
m_getNFilters = NULL; |
|||
m_getFileFilter = NULL; |
|||
m_canRender = NULL; |
|||
m_load = NULL; |
|||
|
|||
return; |
|||
} |
|||
|
|||
|
|||
KICAD_PLUGIN_LDR_3D::~KICAD_PLUGIN_LDR_3D() |
|||
{ |
|||
Close(); |
|||
|
|||
return; |
|||
} |
|||
|
|||
|
|||
bool KICAD_PLUGIN_LDR_3D::Open( const wxString& aFullFileName ) |
|||
{ |
|||
m_error.clear(); |
|||
|
|||
if( ok ) |
|||
Close(); |
|||
|
|||
if( !open( aFullFileName, PLUGIN_CLASS_3D ) ) |
|||
{ |
|||
if( m_error.empty() ) |
|||
{ |
|||
std::ostringstream ostr; |
|||
ostr << "Failed to open plugin '" << aFullFileName.ToUTF8() << "'"; |
|||
m_error = ostr.str(); |
|||
} |
|||
|
|||
#ifdef DEBUG
|
|||
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; |
|||
std::cerr << " * [INFO] failed on file " << aFullFileName.ToUTF8() << "\n"; |
|||
std::cerr << " * [INFO] error: " << m_error << "\n"; |
|||
#endif
|
|||
|
|||
return false; |
|||
} |
|||
|
|||
// the version checks passed and the base KICAD_PLUGIN functions have been linked;
|
|||
// now we link the remaining functions expected by PLUGIN_3D and confirm that the
|
|||
// plugin is loaded
|
|||
LINK_ITEM( m_getNExtensions, PLUGIN_3D_GET_N_EXTENSIONS, "GetNExtensions" ); |
|||
LINK_ITEM( m_getModelExtension, PLUGIN_3D_GET_MODEL_EXTENSION, "GetModelExtension" ); |
|||
LINK_ITEM( m_getNFilters, PLUGIN_3D_GET_N_FILTERS, "GetNFilters" ); |
|||
LINK_ITEM( m_getFileFilter, PLUGIN_3D_GET_FILE_FILTER, "GetFileFilter" ); |
|||
LINK_ITEM( m_canRender, PLUGIN_3D_CAN_RENDER, "CanRender" ); |
|||
LINK_ITEM( m_load, PLUGIN_3D_LOAD, "Load" ); |
|||
|
|||
#ifdef DEBUG
|
|||
bool fail = false; |
|||
|
|||
if( !m_getNExtensions ) |
|||
{ |
|||
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; |
|||
std::cerr << " * incompatible plugin: " << aFullFileName.ToUTF8() << "\n"; |
|||
std::cerr << " * missing function: GetNExtensions\n"; |
|||
fail = true; |
|||
} |
|||
|
|||
if( !m_getModelExtension ) |
|||
{ |
|||
if( !fail ) |
|||
{ |
|||
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; |
|||
std::cerr << " * incompatible plugin: " << aFullFileName.ToUTF8() << "\n"; |
|||
fail = true; |
|||
} |
|||
|
|||
std::cerr << " * missing function: GetModelExtension\n"; |
|||
} |
|||
|
|||
if( !m_getNFilters ) |
|||
{ |
|||
if( !fail ) |
|||
{ |
|||
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; |
|||
std::cerr << " * incompatible plugin: " << aFullFileName.ToUTF8() << "\n"; |
|||
fail = true; |
|||
} |
|||
|
|||
std::cerr << " * missing function: GetNFilters\n"; |
|||
} |
|||
|
|||
if( !m_getFileFilter ) |
|||
{ |
|||
if( !fail ) |
|||
{ |
|||
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; |
|||
std::cerr << " * incompatible plugin: " << aFullFileName.ToUTF8() << "\n"; |
|||
fail = true; |
|||
} |
|||
|
|||
std::cerr << " * missing function: GetFileFilter\n"; |
|||
} |
|||
|
|||
if( !m_canRender ) |
|||
{ |
|||
if( !fail ) |
|||
{ |
|||
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; |
|||
std::cerr << " * incompatible plugin: " << aFullFileName.ToUTF8() << "\n"; |
|||
fail = true; |
|||
} |
|||
|
|||
std::cerr << " * missing function: CanRender\n"; |
|||
} |
|||
|
|||
if( !m_load ) |
|||
{ |
|||
if( !fail ) |
|||
{ |
|||
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; |
|||
std::cerr << " * incompatible plugin: " << aFullFileName.ToUTF8() << "\n"; |
|||
fail = true; |
|||
} |
|||
|
|||
std::cerr << " * missing function: Load\n"; |
|||
} |
|||
|
|||
#endif
|
|||
|
|||
if( !m_getNExtensions || !m_getModelExtension || !m_getNFilters |
|||
|| !m_getFileFilter || !m_canRender || !m_load ) |
|||
{ |
|||
Close(); |
|||
|
|||
std::ostringstream ostr; |
|||
ostr << "Failed to open plugin '" << aFullFileName.ToUTF8() << "'; missing functions"; |
|||
m_error = ostr.str(); |
|||
|
|||
return false; |
|||
} |
|||
|
|||
ok = true; |
|||
return true; |
|||
} |
|||
|
|||
|
|||
void KICAD_PLUGIN_LDR_3D::Close( void ) |
|||
{ |
|||
#ifdef DEBUG
|
|||
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; |
|||
std::cerr << " * [INFO] closing plugin\n"; |
|||
#endif
|
|||
ok = false; |
|||
m_getNExtensions = NULL; |
|||
m_getModelExtension = NULL; |
|||
m_getNFilters = NULL; |
|||
m_getFileFilter = NULL; |
|||
m_canRender = NULL; |
|||
m_load = NULL; |
|||
close(); |
|||
|
|||
return; |
|||
} |
|||
|
|||
|
|||
void KICAD_PLUGIN_LDR_3D::GetLoaderVersion( unsigned char* Major, unsigned char* Minor, |
|||
unsigned char* Revision, unsigned char* Patch ) const |
|||
{ |
|||
if( Major ) |
|||
*Major = PLUGIN_3D_MAJOR; |
|||
|
|||
if( Minor ) |
|||
*Minor = PLUGIN_3D_MINOR; |
|||
|
|||
if( Revision ) |
|||
*Revision = PLUGIN_3D_REVISION; |
|||
|
|||
if( Patch ) |
|||
*Patch = PLUGIN_3D_PATCH; |
|||
|
|||
return; |
|||
} |
|||
|
|||
|
|||
// these functions are shadows of the 3D Plugin functions from 3d_plugin.h
|
|||
int KICAD_PLUGIN_LDR_3D::GetNExtensions( void ) |
|||
{ |
|||
m_error.clear(); |
|||
|
|||
if( !ok && !reopen() ) |
|||
{ |
|||
if( m_error.empty() ) |
|||
m_error = "[INFO] no open plugin / plugin could not be opened"; |
|||
|
|||
return 0; |
|||
} |
|||
|
|||
if( NULL == m_getNExtensions ) |
|||
{ |
|||
m_error = "[BUG] GetNExtensions is not linked"; |
|||
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; |
|||
std::cerr << " * " << m_error << "\n"; |
|||
return 0; |
|||
} |
|||
|
|||
return m_getNExtensions(); |
|||
} |
|||
|
|||
|
|||
char const* KICAD_PLUGIN_LDR_3D::GetModelExtension( int aIndex ) |
|||
{ |
|||
m_error.clear(); |
|||
|
|||
if( !ok && !reopen() ) |
|||
{ |
|||
if( m_error.empty() ) |
|||
m_error = "[INFO] no open plugin / plugin could not be opened"; |
|||
|
|||
return NULL; |
|||
} |
|||
|
|||
if( NULL == m_getModelExtension ) |
|||
{ |
|||
m_error = "[BUG] GetModelExtension is not linked"; |
|||
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; |
|||
std::cerr << " * " << m_error << "\n"; |
|||
return NULL; |
|||
} |
|||
|
|||
return m_getModelExtension( aIndex ); |
|||
} |
|||
|
|||
|
|||
int KICAD_PLUGIN_LDR_3D::GetNFilters( void ) |
|||
{ |
|||
m_error.clear(); |
|||
|
|||
if( !ok && !reopen() ) |
|||
{ |
|||
if( m_error.empty() ) |
|||
m_error = "[INFO] no open plugin / plugin could not be opened"; |
|||
|
|||
return 0; |
|||
} |
|||
|
|||
if( NULL == m_getNFilters ) |
|||
{ |
|||
m_error = "[BUG] GetNFilters is not linked"; |
|||
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; |
|||
std::cerr << " * " << m_error << "\n"; |
|||
return 0; |
|||
} |
|||
|
|||
int n = m_getNFilters(); |
|||
|
|||
return m_getNFilters(); |
|||
} |
|||
|
|||
|
|||
char const* KICAD_PLUGIN_LDR_3D::GetFileFilter( int aIndex ) |
|||
{ |
|||
m_error.clear(); |
|||
|
|||
if( !ok && !reopen() ) |
|||
{ |
|||
if( m_error.empty() ) |
|||
m_error = "[INFO] no open plugin / plugin could not be opened"; |
|||
|
|||
return NULL; |
|||
} |
|||
|
|||
if( NULL == m_getFileFilter ) |
|||
{ |
|||
m_error = "[BUG] GetFileFilter is not linked"; |
|||
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; |
|||
std::cerr << " * " << m_error << "\n"; |
|||
return NULL; |
|||
} |
|||
|
|||
return m_getFileFilter( aIndex ); |
|||
} |
|||
|
|||
|
|||
bool KICAD_PLUGIN_LDR_3D::CanRender( void ) |
|||
{ |
|||
m_error.clear(); |
|||
|
|||
if( !ok && !reopen() ) |
|||
{ |
|||
if( m_error.empty() ) |
|||
m_error = "[INFO] no open plugin / plugin could not be opened"; |
|||
|
|||
return false; |
|||
} |
|||
|
|||
if( NULL == m_canRender ) |
|||
{ |
|||
m_error = "[BUG] CanRender is not linked"; |
|||
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; |
|||
std::cerr << " * " << m_error << "\n"; |
|||
return false; |
|||
} |
|||
|
|||
return m_canRender(); |
|||
} |
|||
|
|||
|
|||
SCENEGRAPH* KICAD_PLUGIN_LDR_3D::Load( char const* aFileName ) |
|||
{ |
|||
m_error.clear(); |
|||
|
|||
if( !ok && !reopen() ) |
|||
{ |
|||
if( m_error.empty() ) |
|||
m_error = "[INFO] no open plugin / plugin could not be opened"; |
|||
|
|||
return NULL; |
|||
} |
|||
|
|||
if( NULL == m_load ) |
|||
{ |
|||
m_error = "[BUG] Load is not linked"; |
|||
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; |
|||
std::cerr << " * " << m_error << "\n"; |
|||
return NULL; |
|||
} |
|||
|
|||
return m_load( aFileName ); |
|||
} |
|||
@ -0,0 +1,90 @@ |
|||
/* |
|||
* This program source code file is part of KiCad, a free EDA CAD application. |
|||
* |
|||
* Copyright (C) 2015 Cirilo Bernardo <cirilo.bernardo@gmail.com> |
|||
* |
|||
* 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 |
|||
*/ |
|||
|
|||
/** |
|||
* @file pluginldr.h |
|||
* defines the most basic functions which all kicad plugin loaders require. |
|||
*/ |
|||
|
|||
|
|||
#ifndef PLUGINLDR3D_H |
|||
#define PLUGINLDR3D_H |
|||
|
|||
#include "../pluginldr.h" |
|||
|
|||
class SCENEGRAPH; |
|||
|
|||
// typedefs of the functions exported by the 3D Plugin Class |
|||
typedef int (*PLUGIN_3D_GET_N_EXTENSIONS) ( void ); |
|||
|
|||
typedef char const* (*PLUGIN_3D_GET_MODEL_EXTENSION) ( int aIndex ); |
|||
|
|||
typedef int (*PLUGIN_3D_GET_N_FILTERS) ( void ); |
|||
|
|||
typedef char const* (*PLUGIN_3D_GET_FILE_FILTER) ( int aIndex ); |
|||
|
|||
typedef bool (*PLUGIN_3D_CAN_RENDER) ( void ); |
|||
|
|||
typedef SCENEGRAPH* (*PLUGIN_3D_LOAD) ( char const* aFileName ); |
|||
|
|||
|
|||
class KICAD_PLUGIN_LDR_3D : public KICAD_PLUGIN_LDR |
|||
{ |
|||
private: |
|||
bool ok; // set TRUE if all functions are linked |
|||
PLUGIN_3D_GET_N_EXTENSIONS m_getNExtensions; |
|||
PLUGIN_3D_GET_MODEL_EXTENSION m_getModelExtension; |
|||
PLUGIN_3D_GET_N_FILTERS m_getNFilters; |
|||
PLUGIN_3D_GET_FILE_FILTER m_getFileFilter; |
|||
PLUGIN_3D_CAN_RENDER m_canRender; |
|||
PLUGIN_3D_LOAD m_load; |
|||
|
|||
public: |
|||
KICAD_PLUGIN_LDR_3D(); |
|||
virtual ~KICAD_PLUGIN_LDR_3D(); |
|||
|
|||
|
|||
// virtuals inherited from KICAD_PLUGIN_LDR |
|||
bool Open( const wxString& aFullFileName ); |
|||
|
|||
void Close( void ); |
|||
|
|||
void GetLoaderVersion( unsigned char* Major, unsigned char* Minor, |
|||
unsigned char* Revision, unsigned char* Patch ) const; |
|||
|
|||
|
|||
// these functions are shadows of the 3D Plugin functions from 3d_plugin.h |
|||
int GetNExtensions( void ); |
|||
|
|||
char const* GetModelExtension( int aIndex ); |
|||
|
|||
int GetNFilters( void ); |
|||
|
|||
char const* GetFileFilter( int aIndex ); |
|||
|
|||
bool CanRender( void ); |
|||
|
|||
SCENEGRAPH* Load( char const* aFileName ); |
|||
}; |
|||
|
|||
#endif // PLUGINMGR3D_H |
|||
@ -0,0 +1,2 @@ |
|||
This directory will contain Plugin Loaders for use by |
|||
KiCad to load the supported Plugin Classes. |
|||
@ -0,0 +1,438 @@ |
|||
/*
|
|||
* This program source code file is part of KiCad, a free EDA CAD application. |
|||
* |
|||
* Copyright (C) 2015 Cirilo Bernardo <cirilo.bernardo@gmail.com> |
|||
* |
|||
* 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 |
|||
*/ |
|||
|
|||
|
|||
#ifdef _WIN32
|
|||
#include <windows.h>
|
|||
#else
|
|||
#include <dlfcn.h>
|
|||
#include <pwd.h>
|
|||
#endif
|
|||
|
|||
#include <sstream>
|
|||
#include <iostream>
|
|||
|
|||
#include "pluginldr.h"
|
|||
|
|||
|
|||
KICAD_PLUGIN_LDR::KICAD_PLUGIN_LDR() |
|||
{ |
|||
ok = false; |
|||
m_getPluginClass = NULL; |
|||
m_getClassVersion = NULL; |
|||
m_checkClassVersion = NULL; |
|||
m_getPluginName = NULL; |
|||
m_getVersion = NULL; |
|||
m_dlHandle = NULL; |
|||
|
|||
return; |
|||
} |
|||
|
|||
|
|||
KICAD_PLUGIN_LDR::~KICAD_PLUGIN_LDR() |
|||
{ |
|||
close(); |
|||
return; |
|||
} |
|||
|
|||
|
|||
bool KICAD_PLUGIN_LDR::open( const wxString& aFullFileName, const char* aPluginClass ) |
|||
{ |
|||
m_error.clear(); |
|||
|
|||
if( ok ) |
|||
Close(); |
|||
|
|||
if( aFullFileName.empty() ) |
|||
return false; |
|||
|
|||
m_fileName.clear(); |
|||
|
|||
#ifdef _WIN32
|
|||
// NOTE: MSWin uses UTF-16 encoding
|
|||
#if defined( UNICODE ) || defined( _UNICODE )
|
|||
m_dlHandle = LoadLibrary( aFullFileName.wc_str() ); |
|||
#else
|
|||
m_dlHandle = LoadLibrary( aFullFileName.ToUTF8() ); |
|||
#endif
|
|||
#else
|
|||
m_dlHandle = dlopen( aFullFileName.ToUTF8(), RTLD_LAZY | RTLD_LOCAL ); |
|||
#endif
|
|||
|
|||
if( NULL == m_dlHandle ) |
|||
{ |
|||
#ifdef DEBUG
|
|||
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; |
|||
std::cerr << " * could not open file: '" << aFullFileName.ToUTF8() << "'\n"; |
|||
#endif
|
|||
return false; |
|||
} |
|||
|
|||
LINK_ITEM( m_getPluginClass, GET_PLUGIN_CLASS, "GetKicadPluginClass" ); |
|||
LINK_ITEM( m_getClassVersion, GET_CLASS_VERSION, "GetClassVersion" ); |
|||
LINK_ITEM( m_checkClassVersion, CHECK_CLASS_VERSION , "CheckClassVersion" ); |
|||
LINK_ITEM( m_getPluginName, GET_PLUGIN_NAME, "GetKicadPluginName" ); |
|||
LINK_ITEM( m_getVersion, GET_VERSION, "GetVersion" ); |
|||
|
|||
#ifdef DEBUG
|
|||
bool fail = false; |
|||
|
|||
if( !m_getPluginClass ) |
|||
{ |
|||
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; |
|||
std::cerr << " * incompatible plugin: " << aFullFileName.ToUTF8() << "\n"; |
|||
std::cerr << " * missing function: GetKicadPluginClass\n"; |
|||
fail = true; |
|||
} |
|||
|
|||
if( !m_getClassVersion ) |
|||
{ |
|||
if( !fail ) |
|||
{ |
|||
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; |
|||
std::cerr << " * incompatible plugin: " << aFullFileName.ToUTF8() << "\n"; |
|||
fail = true; |
|||
} |
|||
|
|||
std::cerr << " * missing function: GetClassVersion\n"; |
|||
} |
|||
|
|||
if( !m_checkClassVersion ) |
|||
{ |
|||
if( !fail ) |
|||
{ |
|||
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; |
|||
std::cerr << " * incompatible plugin: " << aFullFileName.ToUTF8() << "\n"; |
|||
fail = true; |
|||
} |
|||
|
|||
std::cerr << " * missing function: CheckClassVersion\n"; |
|||
} |
|||
|
|||
if( !m_getPluginName ) |
|||
{ |
|||
if( !fail ) |
|||
{ |
|||
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; |
|||
std::cerr << " * incompatible plugin: " << aFullFileName.ToUTF8() << "\n"; |
|||
fail = true; |
|||
} |
|||
|
|||
std::cerr << " * missing function: GetKicadPluginName\n"; |
|||
} |
|||
|
|||
if( !m_getVersion ) |
|||
{ |
|||
if( !fail ) |
|||
{ |
|||
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; |
|||
std::cerr << " * incompatible plugin: " << aFullFileName.ToUTF8() << "\n"; |
|||
} |
|||
|
|||
std::cerr << " * missing function: GetVersion\n"; |
|||
} |
|||
|
|||
#endif
|
|||
|
|||
if( !m_getPluginClass || !m_getClassVersion || !m_checkClassVersion |
|||
|| !m_getPluginName || !m_getVersion ) |
|||
{ |
|||
m_error = "incompatible plugin interface (missing functions)"; |
|||
close(); |
|||
return false; |
|||
} |
|||
|
|||
// note: since 'ok' is not yet set at this point we must use the function
|
|||
// pointers directly rather than invoking the functions exposed by this class
|
|||
|
|||
// check that the Plugin Class matches
|
|||
char const* pclassName = m_getPluginClass(); |
|||
|
|||
if( !pclassName || strcmp( aPluginClass, pclassName ) ) |
|||
{ |
|||
m_error = "Loader type ("; |
|||
m_error.append( aPluginClass ); |
|||
m_error.append( ") does not match Plugin type (" ); |
|||
|
|||
if( pclassName ) |
|||
m_error.append( pclassName ); |
|||
else |
|||
m_error.append( "NULL" ); |
|||
|
|||
m_error.append( ")" ); |
|||
|
|||
close(); |
|||
return false; |
|||
} |
|||
|
|||
// perform a universally enforced version check (major number must match)
|
|||
unsigned char lMajor; |
|||
unsigned char lMinor; |
|||
unsigned char lRevno; |
|||
unsigned char lPatch; |
|||
unsigned char pMajor; |
|||
unsigned char pMinor; |
|||
unsigned char pRevno; |
|||
unsigned char pPatch; |
|||
|
|||
m_getClassVersion( &pMajor, &pMinor, &pRevno, &pPatch ); |
|||
GetLoaderVersion( &lMajor, &lMinor, &lRevno, &lPatch ); |
|||
|
|||
// major version changes by definition are incompatible and
|
|||
// that is enforced here.
|
|||
if( pMajor != lMajor ) |
|||
{ |
|||
std::ostringstream ostr; |
|||
ostr << "Loader Major version (" << lMajor; |
|||
ostr << ") does not match Plugin Major version (" << pMajor << ")"; |
|||
|
|||
m_error = ostr.str(); |
|||
close(); |
|||
return false; |
|||
} |
|||
|
|||
if( !m_checkClassVersion( lMajor, lMinor, lRevno, lPatch ) ) |
|||
{ |
|||
std::ostringstream ostr; |
|||
ostr << "Plugin Version (" << pMajor << "." << pMinor << "." << pRevno << "." << pPatch; |
|||
ostr << ") does not support Loader Version (" << pMajor << "." << pMinor; |
|||
ostr << "." << pRevno << "." << pPatch << ")"; |
|||
|
|||
m_error = ostr.str(); |
|||
close(); |
|||
return false; |
|||
} |
|||
|
|||
m_fileName = aFullFileName; |
|||
|
|||
#ifdef DEBUG
|
|||
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; |
|||
std::cerr << " * [INFO] opened plugin " << m_fileName.ToUTF8() << "\n"; |
|||
char const* cp = m_getPluginName(); |
|||
if( !cp ) |
|||
std::cerr << " * [INFO] plugin name: '" << cp << "'\n"; |
|||
#endif
|
|||
|
|||
ok = true; |
|||
return true; |
|||
} |
|||
|
|||
|
|||
void KICAD_PLUGIN_LDR::close( void ) |
|||
{ |
|||
ok = false; |
|||
m_getPluginClass = NULL; |
|||
m_getClassVersion = NULL; |
|||
m_checkClassVersion = NULL; |
|||
m_getPluginName = NULL; |
|||
m_getVersion = NULL; |
|||
|
|||
if( NULL != m_dlHandle ) |
|||
{ |
|||
|
|||
#ifdef _WIN32
|
|||
FreeLibrary( m_dlHandle ); |
|||
#else
|
|||
dlclose( m_dlHandle ); |
|||
#endif
|
|||
|
|||
m_dlHandle = NULL; |
|||
} |
|||
|
|||
return; |
|||
} |
|||
|
|||
|
|||
bool KICAD_PLUGIN_LDR::reopen( void ) |
|||
{ |
|||
m_error.clear(); |
|||
|
|||
if( m_fileName.empty() ) |
|||
return false; |
|||
|
|||
wxString fname = m_fileName; |
|||
|
|||
return Open( fname ); |
|||
} |
|||
|
|||
|
|||
std::string KICAD_PLUGIN_LDR::GetLastError( void ) const |
|||
{ |
|||
return m_error; |
|||
} |
|||
|
|||
|
|||
char const* KICAD_PLUGIN_LDR::GetKicadPluginClass( void ) |
|||
{ |
|||
m_error.clear(); |
|||
|
|||
if( !ok && !reopen() ) |
|||
{ |
|||
if( m_error.empty() ) |
|||
m_error = "[INFO] no open plugin / plugin could not be opened"; |
|||
|
|||
return NULL; |
|||
} |
|||
|
|||
if( NULL == m_getPluginClass ) |
|||
{ |
|||
m_error = "[BUG] GetPluginClass is not linked"; |
|||
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; |
|||
std::cerr << " * " << m_error << "\n"; |
|||
return NULL; |
|||
} |
|||
|
|||
return m_getPluginClass(); |
|||
} |
|||
|
|||
|
|||
bool KICAD_PLUGIN_LDR::GetClassVersion( unsigned char* Major, unsigned char* Minor, |
|||
unsigned char* Revision, unsigned char* Patch ) |
|||
{ |
|||
m_error.clear(); |
|||
|
|||
if( Major ) |
|||
*Major = 0; |
|||
|
|||
if( Minor ) |
|||
*Minor = 0; |
|||
|
|||
if( Revision ) |
|||
*Revision = 0; |
|||
|
|||
if( Patch ) |
|||
*Patch = 0; |
|||
|
|||
unsigned char major; |
|||
unsigned char minor; |
|||
unsigned char revno; |
|||
unsigned char patch; |
|||
|
|||
if( !ok && !reopen() ) |
|||
{ |
|||
if( m_error.empty() ) |
|||
m_error = "[INFO] no open plugin / plugin could not be opened"; |
|||
|
|||
return false; |
|||
} |
|||
|
|||
if( NULL == m_checkClassVersion ) |
|||
{ |
|||
m_error = "[BUG] CheckClassVersion is not linked"; |
|||
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; |
|||
std::cerr << " * " << m_error << "\n"; |
|||
return false; |
|||
} |
|||
|
|||
m_getClassVersion( &major, &minor, &revno, &patch ); |
|||
|
|||
if( Major ) |
|||
*Major = major; |
|||
|
|||
if( Minor ) |
|||
*Minor = minor; |
|||
|
|||
if( Revision ) |
|||
*Revision = revno; |
|||
|
|||
if( Patch ) |
|||
*Patch = patch; |
|||
|
|||
return true; |
|||
} |
|||
|
|||
|
|||
bool KICAD_PLUGIN_LDR::CheckClassVersion( unsigned char Major, unsigned char Minor, |
|||
unsigned char Revision, unsigned char Patch ) |
|||
{ |
|||
m_error.clear(); |
|||
|
|||
if( !ok && !reopen() ) |
|||
{ |
|||
if( m_error.empty() ) |
|||
m_error = "[INFO] no open plugin / plugin could not be opened"; |
|||
|
|||
return NULL; |
|||
} |
|||
|
|||
if( NULL == m_checkClassVersion ) |
|||
{ |
|||
m_error = "[BUG] CheckClassVersion is not linked"; |
|||
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; |
|||
std::cerr << " * " << m_error << "\n"; |
|||
return NULL; |
|||
} |
|||
|
|||
return m_checkClassVersion( Major, Minor, Revision, Patch ); |
|||
} |
|||
|
|||
|
|||
const char* KICAD_PLUGIN_LDR::GetKicadPluginName( void ) |
|||
{ |
|||
m_error.clear(); |
|||
|
|||
if( !ok && !reopen() ) |
|||
{ |
|||
if( m_error.empty() ) |
|||
m_error = "[INFO] no open plugin / plugin could not be opened"; |
|||
|
|||
return NULL; |
|||
} |
|||
|
|||
if( NULL == m_getPluginName ) |
|||
{ |
|||
m_error = "[BUG] GetKicadPluginName is not linked"; |
|||
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; |
|||
std::cerr << " * " << m_error << "\n"; |
|||
return NULL; |
|||
} |
|||
|
|||
return m_getPluginName(); |
|||
} |
|||
|
|||
|
|||
bool KICAD_PLUGIN_LDR::GetVersion( unsigned char* Major, unsigned char* Minor, |
|||
unsigned char* Revision, unsigned char* Patch ) |
|||
{ |
|||
m_error.clear(); |
|||
|
|||
if( !ok && !reopen() ) |
|||
{ |
|||
if( m_error.empty() ) |
|||
m_error = "[INFO] no open plugin / plugin could not be opened"; |
|||
|
|||
return false; |
|||
} |
|||
|
|||
if( NULL == m_getVersion ) |
|||
{ |
|||
m_error = "[BUG] GetKicadPluginName is not linked"; |
|||
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; |
|||
std::cerr << " * " << m_error << "\n"; |
|||
return false; |
|||
} |
|||
|
|||
m_getVersion( Major, Minor, Revision, Patch ); |
|||
|
|||
return true; |
|||
} |
|||
@ -0,0 +1,158 @@ |
|||
/* |
|||
* This program source code file is part of KiCad, a free EDA CAD application. |
|||
* |
|||
* Copyright (C) 2015 Cirilo Bernardo <cirilo.bernardo@gmail.com> |
|||
* |
|||
* 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 |
|||
*/ |
|||
|
|||
/** |
|||
* @file pluginldr.h |
|||
* defines the most basic functions which all kicad plugin loaders require. |
|||
*/ |
|||
|
|||
|
|||
#ifndef PLUGINLDR_H |
|||
#define PLUGINLDR_H |
|||
|
|||
#include <dlfcn.h> |
|||
#include <string> |
|||
#include <wx/string.h> |
|||
|
|||
// helper functions to link functions |
|||
#ifdef _WIN32 |
|||
#define LINK_ITEM( funcPtr, funcType, funcName ) \ |
|||
funcPtr = (funcType) GetProcAddress( m_dlHandle, funcName ); |
|||
#else |
|||
#define LINK_ITEM( funcPtr, funcType, funcName ) \ |
|||
*(void**) (&funcPtr) = dlsym( m_dlHandle, funcName ); |
|||
#endif |
|||
|
|||
// typedefs of the functions exported by the 3D Plugin Class |
|||
typedef char const* (*GET_PLUGIN_CLASS) ( void ); |
|||
|
|||
typedef void (*GET_CLASS_VERSION) ( unsigned char*, unsigned char*, |
|||
unsigned char*, unsigned char* ); |
|||
|
|||
typedef bool (*CHECK_CLASS_VERSION) ( unsigned char, unsigned char, |
|||
unsigned char, unsigned char ); |
|||
|
|||
typedef const char* (*GET_PLUGIN_NAME) ( void ); |
|||
|
|||
typedef void (*GET_VERSION) ( unsigned char*, unsigned char*, |
|||
unsigned char*, unsigned char* ); |
|||
|
|||
|
|||
class KICAD_PLUGIN_LDR |
|||
{ |
|||
private: |
|||
bool ok; // set TRUE if all functions are linked |
|||
GET_PLUGIN_CLASS m_getPluginClass; |
|||
GET_CLASS_VERSION m_getClassVersion; |
|||
CHECK_CLASS_VERSION m_checkClassVersion; |
|||
GET_PLUGIN_NAME m_getPluginName; |
|||
GET_VERSION m_getVersion; |
|||
|
|||
wxString m_fileName; // name of last opened Plugin |
|||
|
|||
protected: |
|||
std::string m_error; // error message |
|||
|
|||
/** |
|||
* Function open |
|||
* opens a plugin of the specified class and links the extensions |
|||
* required by kicad_plugin. Returns true on success otherwise |
|||
* false. |
|||
*/ |
|||
bool open( const wxString& aFullFileName, const char* aPluginClass ); |
|||
|
|||
/** |
|||
* Function close |
|||
* nullifies internal pointers in preparation for closing the plugin |
|||
*/ |
|||
void close( void ); |
|||
|
|||
/** |
|||
* Function reopen |
|||
* reopens a plugin and returns true on success |
|||
*/ |
|||
bool reopen( void ); |
|||
|
|||
// handle to the opened plugin |
|||
#ifdef _WIN32 |
|||
HMODULE m_dlHandle; |
|||
#else |
|||
void* m_dlHandle; |
|||
#endif |
|||
|
|||
public: |
|||
KICAD_PLUGIN_LDR(); |
|||
virtual ~KICAD_PLUGIN_LDR(); |
|||
|
|||
/** |
|||
* Function GetLoaderVersion |
|||
* returns the version information of the Plugin Loader |
|||
* for plugin compatibility checking. |
|||
*/ |
|||
virtual void GetLoaderVersion( unsigned char* Major, unsigned char* Minor, |
|||
unsigned char* Revision, unsigned char* Patch ) const = 0; |
|||
|
|||
/** |
|||
* Function Open |
|||
* opens a plugin of the given class, performs version compatibility checks, |
|||
* and links all required functions. |
|||
* |
|||
* @return true on success, otherwise false and a message may be accessible |
|||
* via GetLastError() |
|||
*/ |
|||
virtual bool Open( const wxString& aFullFileName ) = 0; |
|||
|
|||
/** |
|||
* Function Close |
|||
* cleans up and closes/unloads the plugin |
|||
*/ |
|||
virtual void Close( void ) = 0; |
|||
|
|||
/** |
|||
* Function GetLastError |
|||
* returns the value of the internal error string |
|||
*/ |
|||
std::string GetLastError( void ) const; |
|||
|
|||
// the following functions are the equivalent of those required by kicad_plugin.h |
|||
|
|||
// returns the Plugin Class or NULL if no plugin loaded |
|||
char const* GetKicadPluginClass( void ); |
|||
|
|||
// returns false if no plugin loaded |
|||
bool GetClassVersion( unsigned char* Major, unsigned char* Minor, |
|||
unsigned char* Revision, unsigned char* Patch ); |
|||
|
|||
// returns false if the class version check fails or no plugin is loaded |
|||
bool CheckClassVersion( unsigned char Major, unsigned char Minor, |
|||
unsigned char Revision, unsigned char Patch ); |
|||
|
|||
// returns the Plugin Name or NULL if no plugin loaded |
|||
const char* GetKicadPluginName( void ); |
|||
|
|||
// returns false if no plugin is loaded |
|||
bool GetVersion( unsigned char* Major, unsigned char* Minor, |
|||
unsigned char* Revision, unsigned char* Patch ); |
|||
}; |
|||
|
|||
#endif // PLUGINLDR_H |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue