From 02ced9a339e3ca6aa3662286d4ec9a1d04aa1d89 Mon Sep 17 00:00:00 2001 From: Miguel Angel Ajo Date: Thu, 2 Aug 2012 09:47:30 +0200 Subject: [PATCH] scripting: fixed kicad compilation, cleanups --- CMakeLists.txt | 13 ++++++ include/appl_wxstruct.h | 17 ++----- pcbnew/CMakeLists.txt | 6 --- pcbnew/pcbnew.cpp | 85 +++++++++++++++------------------- scripting/python_scripting.cpp | 15 +++++- scripting/python_scripting.h | 18 ++++++- 6 files changed, 82 insertions(+), 72 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 215ac4e65c..42addd2866 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -256,6 +256,19 @@ if(WIN32 AND USE_WX_GRAPHICS_CONTEXT) check_find_package_result(GDI_PLUS_FOUND "GDI+") endif(WIN32 AND USE_WX_GRAPHICS_CONTEXT) +# Find Python and other scripting resources +if (KICAD_SCRIPTING OR KICAD_SCRIPTING_MODULES) + + execute_process(COMMAND python2 -c "import sys;print\"%s.%s\"%sys.version_info[0:2]" OUTPUT_VARIABLE PYTHON_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE) + set(PYTHON_DEST "lib/python${PYTHON_VERSION}/dist-packages" ) + find_package(PythonLibs) + include_directories(${PYTHON_INCLUDE_PATH} + ./scripting) + +endif(KICAD_SCRIPTING OR KICAD_SCRIPTING_MODULES) + + + # Automagically create version header file. include(CreateBzrVersionHeader) create_bzr_version_header() diff --git a/include/appl_wxstruct.h b/include/appl_wxstruct.h index 06823b5c68..8358d8c74f 100644 --- a/include/appl_wxstruct.h +++ b/include/appl_wxstruct.h @@ -36,10 +36,7 @@ #include #include #include -#ifdef KICAD_SCRIPTING_EXPERIMENT -#include -#include -#endif + enum EDA_APP_T { APP_UNKNOWN_T, @@ -62,10 +59,7 @@ class wxHtmlHelpController; */ class EDA_APP : public wxApp { -#ifdef KICAD_SCRIPTING_EXPERIMENT - private: - PyThreadState* m_mainTState; -#endif + protected: /// Used mainly to handle default paths libs m_Id = APP_EESCHEMA_T, APP_PCBNEW_T ... EDA_APP_T m_Id; @@ -123,12 +117,6 @@ public: * @return true if the application can be started. */ bool OnInit(); // should this be virtual -#ifdef KICAD_SCRIPTING_EXPERIMENT - bool Init_wxPython(); -#endif - // This is only called if OnInit() returned true so it's a good place to do - // any cleanup matching the initializations done there. - //// virtual int OnExit() ;// { return(0) ; }; // TODO FIX THIS HACK MUST BE VIRTUAL wxHtmlHelpController* GetHtmlHelpController() { return m_HtmlCtrl; } @@ -421,6 +409,7 @@ public: * @param aIndex = insertion point */ void InsertLibraryPath( const wxString& aPaths, size_t aIndex ); + }; /* diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt index 26106ffdf6..17ccf619cb 100644 --- a/pcbnew/CMakeLists.txt +++ b/pcbnew/CMakeLists.txt @@ -1,14 +1,9 @@ add_definitions(-DPCBNEW) if (KICAD_SCRIPTING OR KICAD_SCRIPTING_MODULES) - EXECUTE_PROCESS(COMMAND python2 -c "import sys;print\"%s.%s\"%sys.version_info[0:2]" OUTPUT_VARIABLE PYTHON_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE) - SET(PYTHON_DEST "lib/python${PYTHON_VERSION}/dist-packages" ) file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/scripting) FIND_PACKAGE(SWIG REQUIRED) INCLUDE(${SWIG_USE_FILE}) - FIND_PACKAGE(PythonLibs) - INCLUDE_DIRECTORIES(${PYTHON_INCLUDE_PATH}) - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DKICAD_SCRIPTING -DKICAD_SCRIPTING_MODULES") endif(KICAD_SCRIPTING OR KICAD_SCRIPTING_MODULES) @@ -25,7 +20,6 @@ include_directories( ../polygon ../common/dialogs ./scripting - ../scripting ${INC_AFTER} ) diff --git a/pcbnew/pcbnew.cpp b/pcbnew/pcbnew.cpp index ed4bf1e820..de0e01cf8b 100644 --- a/pcbnew/pcbnew.cpp +++ b/pcbnew/pcbnew.cpp @@ -29,6 +29,7 @@ */ #ifdef KICAD_SCRIPTING +#include #include #endif #include @@ -51,12 +52,6 @@ #include #include -#include - -#ifdef KICAD_SCRIPTING -#include -#endif - // Colors for layers and items COLORS_DESIGN_SETTINGS g_ColorsSettings; @@ -141,15 +136,11 @@ bool EDA_APP::OnInit() PCB_EDIT_FRAME* frame = NULL; #ifdef KICAD_SCRIPTING - if ( !pcbnewInitPythonScripting(&m_mainTState) ) + if ( !pcbnewInitPythonScripting() ) { - return false; + return false; } #endif -#ifdef KICAD_SCRIPTING_EXPERIMENT - MyFrame *zz = new MyFrame(_T("Embedded wxPython Test"),wxDefaultPosition, wxSize(700, 600)); - zz->Show(true); -#endif InitEDA_Appl( wxT( "Pcbnew" ), APP_PCBNEW_T ); @@ -245,6 +236,11 @@ Changing extension to .brd." ), GetChars( fn.GetFullPath() ) ); frame->SetFocus(); frame->GetCanvas()->SetFocus(); #ifdef KICAD_SCRIPTING_EXPERIMENT + + MyFrame *zz = new MyFrame(_T("Embedded wxPython Test"),wxDefaultPosition, wxSize(700, 600)); + zz->Show(true); + + zz->ScriptingSetPcbEditFrame(frame); // make the frame available to my python thing // now to find a way to use it for something useful #endif @@ -261,39 +257,14 @@ int EDA_APP::OnExit() { // in OnExit instead of ~MyApp because OnExit is only called if OnInit is // successful. #if KICAD_SCRIPTING_EXPERIMENT - wxPyEndAllowThreads(m_mainTState); - Py_Finalize(); + pcbnewFinishPythonScripting(); #endif return 0; } #endif #ifdef KICAD_SCRIPTING_EXPERIMENT -// stuff copied from WxPython examples -bool EDA_APP::Init_wxPython() { - // Initialize Python - Py_Initialize(); - PyEval_InitThreads(); - // Load the wxPython core API. Imports the wx._core_ module and sets a - // local pointer to a function table located there. The pointer is used - // internally by the rest of the API functions. - if ( ! wxPyCoreAPI_IMPORT() ) { - wxLogError(wxT("***** Error importing the wxPython API! *****")); - PyErr_Print(); - Py_Finalize(); - return false; - } - - // Save the current Python thread state and release the - // Global Interpreter Lock. - m_mainTState = wxPyBeginAllowThreads(); - - return true; -} - - -// MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size) : wxFrame(NULL, -1, title, pos, size, wxDEFAULT_FRAME_STYLE|wxNO_FULL_REPAINT_ON_RESIZE) @@ -379,18 +350,35 @@ sys.stdin = sys.stderr = output\n"; wxPyEndBlockThreads(blocked); } -const char* python_code2 = "\ -import sys\nimport os\n\ -sys.path.append(os.path.expanduser('~/.kicad_plugins'))\n\ -import embedded_sample\n\ -\n\ -def makeWindow(parent):\n\ - win = embedded_sample.MyPanel(parent)\n\ - return win\n\ -"; + wxWindow* MyFrame::DoPythonStuff(wxWindow* parent) { + +const char* pycrust_panel = "\ +import wx\n\ +from wx.py import shell, version\n\ +\n\ +class MyPanel(wx.Panel):\n\ +\tdef __init__(self, parent):\n\ +\t\twx.Panel.__init__(self, parent, -1, style=wx.SUNKEN_BORDER)\n\ +\t\t\n\ +\t\ttext = wx.StaticText(self, -1,\n\ +\t\t\t\t\"Everything on this side of the splitter comes from Python.\")\n\ +\t\t\n\ +\t\tintro = \"Welcome To PyCrust %s - KiCad's Python Shell\" % version.VERSION\n\ +\t\tpycrust = shell.Shell(self, -1, introText=intro)\n\ +\t\t\n\ +\t\tsizer = wx.BoxSizer(wx.VERTICAL)\n\n\ +\t\tsizer.Add(text, 0, wx.EXPAND|wx.ALL, 10)\n\n\ +\t\tsizer.Add(pycrust, 1, wx.EXPAND|wx.BOTTOM|wx.LEFT|wx.RIGHT, 10)\n\n\ +\t\tself.SetSizer(sizer)\n\n\ +\n\ +def makeWindow(parent):\n\ + win = MyPanel(parent)\n\ + return win\n\ +"; + // More complex embedded situations will require passing C++ objects to // Python and/or returning objects from Python to be used in C++. This // sample shows one way to do it. NOTE: The above code could just have @@ -413,7 +401,7 @@ wxWindow* MyFrame::DoPythonStuff(wxWindow* parent) Py_DECREF(builtins); // Execute the code to make the makeWindow function - result = PyRun_String(python_code2, Py_file_input, globals, globals); + result = PyRun_String(pycrust_panel, Py_file_input, globals, globals); // Was there an exception? if (! result) { PyErr_Print(); @@ -443,6 +431,7 @@ wxWindow* MyFrame::DoPythonStuff(wxWindow* parent) // Otherwise, get the returned window out of Python-land and // into C++-ville... bool success = wxPyConvertSwigPtr(result, (void**)&window, _T("wxWindow")); + (void)success; wxASSERT_MSG(success, _T("Returned object was not a wxWindow!")); Py_DECREF(result); } diff --git a/scripting/python_scripting.cpp b/scripting/python_scripting.cpp index 8c3ec062c8..d76b79633c 100644 --- a/scripting/python_scripting.cpp +++ b/scripting/python_scripting.cpp @@ -116,7 +116,10 @@ static void swigSwitchPythonBuiltin() * initializes all the wxpython interface, and returns the python thread control structure * */ -bool pcbnewInitPythonScripting(PyThreadState** aMainTState) + +PyThreadState *g_PythonMainTState; + +bool pcbnewInitPythonScripting() { swigAddBuiltin(); // add builtin functions @@ -139,7 +142,7 @@ bool pcbnewInitPythonScripting(PyThreadState** aMainTState) // Save the current Python thread state and release the // Global Interpreter Lock. - *aMainTState = wxPyBeginAllowThreads(); + g_PythonMainTState = wxPyBeginAllowThreads(); // load pcbnew inside python, and load all the user plugins, TODO: add system wide plugins @@ -153,3 +156,11 @@ bool pcbnewInitPythonScripting(PyThreadState** aMainTState) return true; } + +void pcbnewFinishPythonScripting() +{ + + wxPyEndAllowThreads(g_PythonMainTState); + Py_Finalize(); + +} diff --git a/scripting/python_scripting.h b/scripting/python_scripting.h index 420c65b79d..6d28be4b10 100644 --- a/scripting/python_scripting.h +++ b/scripting/python_scripting.h @@ -1,12 +1,26 @@ #ifndef __PYTHON_SCRIPTING_H #define __PYTHON_SCRIPTING_H -#include + // undefs explained here: https://bugzilla.redhat.com/show_bug.cgi?id=427617 + + #ifdef _POSIX_C_SOURCE + #undef _POSIX_C_SOURCE + #endif + #ifdef _XOPEN_SOURCE + #undef _XOPEN_SOURCE + #endif + + #include + #ifndef NO_WXPYTHON_EXTENSION_HEADERS + #include + #endif + /* Function pcbnewInitPythonScripting * Initializes the Python engine inside pcbnew */ -bool pcbnewInitPythonScripting(PyThreadState** aMainTState); +bool pcbnewInitPythonScripting(); +void pcbnewFinishPythonScripting(); #endif