diff --git a/CMakeLists.txt b/CMakeLists.txt
index 42addd2866..81be2b1b93 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -56,8 +56,8 @@ option(KICAD_SCRIPTING_MODULES
        "set this option ON to build kicad modules that can be used from scripting languages"
        )
        
-option(KICAD_SCRIPTING_EXPERIMENT
-       "set this option ON to build Edwin's TEST code with linking to python and pycrust shell"
+option(KICAD_SCRIPTING_WXPYTHON
+       "set this option ON to build wxpython implementation for wx interface building in python and py.shell"
        )
         
 
@@ -140,11 +140,11 @@ if(KICAD_SCRIPTING_MODULES)
     add_definitions(-DKICAD_SCRIPTING_MODULES)
 endif(KICAD_SCRIPTING_MODULES)
 
-if(KICAD_SCRIPTING_EXPERIMENT)
-    add_definitions(-DKICAD_SCRIPTING_EXPERIMENT)
+if(KICAD_SCRIPTING_WXPYTHON)
+    add_definitions(-DKICAD_SCRIPTING_WXPYTHON)
 
 
-endif(KICAD_SCRIPTING_EXPERIMENT)
+endif(KICAD_SCRIPTING_WXPYTHON)
 
 if(USE_WX_GRAPHICS_CONTEXT)
     add_definitions(-DUSE_WX_GRAPHICS_CONTEXT)
diff --git a/include/wxPcbStruct.h b/include/wxPcbStruct.h
index e6ba96a238..086e604889 100644
--- a/include/wxPcbStruct.h
+++ b/include/wxPcbStruct.h
@@ -86,6 +86,11 @@ class PCB_EDIT_FRAME : public PCB_BASE_FRAME
 
 protected:
 
+#ifdef KICAD_SCRIPTING_WXPYTHON
+    // Panel used to let user talk with internal scripting
+    wxWindow* m_pythonPanel;
+#endif
+
     PCB_LAYER_WIDGET* m_Layers;
 
     DRC* m_drc;                              ///< the DRC controller, see drc.cpp
diff --git a/include/wxstruct.h b/include/wxstruct.h
index 2bc471d242..3b18590ef1 100644
--- a/include/wxstruct.h
+++ b/include/wxstruct.h
@@ -1074,6 +1074,19 @@ public:
         return *this;
     }
 
+    /**
+     * Function ScriptingToolbarPane
+     * Change *this to a scripting toolbar for KiCad.
+     */
+    EDA_PANEINFO& ScriptingToolbarPane()
+    {
+        CloseButton( false );
+        Floatable( true );
+        Resizable( true );
+        return *this;
+    }
+
+
 };
 
 #endif  // WXSTRUCT_H_
diff --git a/pcbnew/pcbframe.cpp b/pcbnew/pcbframe.cpp
index 2af5e03aff..0e6f8c6ff7 100644
--- a/pcbnew/pcbframe.cpp
+++ b/pcbnew/pcbframe.cpp
@@ -53,6 +53,9 @@
 #include <dialog_SVG_print.h>
 #include <dialog_helpers.h>
 
+#ifdef KICAD_SCRIPTING
+#include <python_scripting.h>
+#endif
 
 // Keys used in read/write config
 #define OPTKEY_DEFAULT_LINEWIDTH_VALUE  wxT( "PlotLineWidth" )
@@ -280,7 +283,9 @@ PCB_EDIT_FRAME::PCB_EDIT_FRAME( wxWindow* parent, const wxString& title,
     m_RecordingMacros = -1;
     m_microWaveToolBar = NULL;
     m_autoPlaceModeId = 0;
-
+#ifdef KICAD_SCRIPTING_WXPYTHON 
+    m_pythonPanel = NULL;
+#endif
     for ( int i = 0; i < 10; i++ )
         m_Macros[i].m_Record.clear();
 
@@ -397,6 +402,22 @@ PCB_EDIT_FRAME::PCB_EDIT_FRAME( wxWindow* parent, const wxString& title,
         m_auimgr.AddPane( m_messagePanel,
                           wxAuiPaneInfo( mesg ).Name( wxT( "MsgPanel" ) ).Bottom().Layer(10) );
 
+    
+    #ifdef KICAD_SCRIPTING_WXPYTHON
+    // Add the scripting panel
+    EDA_PANEINFO  pythonAuiInfo;
+    pythonAuiInfo.ScriptingToolbarPane();
+    pythonAuiInfo.Caption( wxT( "Python Scripting" ) );
+    pythonAuiInfo.MinSize( wxSize( 200, 100 ) );
+    pythonAuiInfo.BestSize( wxSize( GetClientSize().x/2, 200 ) );
+
+    m_pythonPanel = CreatePythonShellWindow( this );
+    m_auimgr.AddPane( m_pythonPanel,
+                          pythonAuiInfo.Name( wxT( "PythonPanel" ) ).Bottom().Layer(9) );
+
+    #endif
+
+
     ReFillLayerWidget();        // this is near end because contents establish size
 
     m_Layers->ReFillRender();   // Update colors in Render after the config is read
diff --git a/pcbnew/pcbnew.cpp b/pcbnew/pcbnew.cpp
index de0e01cf8b..bfa325e1ed 100644
--- a/pcbnew/pcbnew.cpp
+++ b/pcbnew/pcbnew.cpp
@@ -102,34 +102,6 @@ void EDA_APP::MacOpenFile( const wxString& fileName )
     frame->LoadOnePcbFile( fileName, false );
 }
 
-#ifdef KICAD_SCRIPTING_EXPERIMENT
-
-class MyFrame : public wxFrame	{
-	public:
-	    MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size);
-	    void RedirectStdio();
-	    wxWindow* DoPythonStuff(wxWindow* parent);
-	    void OnExit(wxCommandEvent& event);
-	    void OnPyFrame(wxCommandEvent& event);
-	    void ScriptingSetPcbEditFrame(PCB_EDIT_FRAME *aPCBEdaFrame);
-	private:
-	    DECLARE_EVENT_TABLE()
-            PCB_EDIT_FRAME *PcbEditFrame ;
-};
-
-enum
-	{
-	    ID_EXIT=1001,
-	    ID_PYFRAME
-	};
-
-BEGIN_EVENT_TABLE(MyFrame, wxFrame)
-    EVT_MENU(ID_EXIT,      MyFrame::OnExit)
-    EVT_MENU(ID_PYFRAME,   MyFrame::OnPyFrame)
-END_EVENT_TABLE()
-
-#endif
-
 bool EDA_APP::OnInit()
 {
     wxFileName      fn;
@@ -235,17 +207,10 @@ 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
     return true;
 }
+
 #if 0
 // for some reason KiCad classes do not implement OnExit
 // if I add it in the declaration, I need to fix it in every application
@@ -256,194 +221,12 @@ int EDA_APP::OnExit() {
     // wxPython will do its own cleanup as part of that process.  This is done
     // in OnExit instead of ~MyApp because OnExit is only called if OnInit is
     // successful.
-#if KICAD_SCRIPTING_EXPERIMENT
+#if KICAD_SCRIPTING_WXPYTHON
     pcbnewFinishPythonScripting();
 #endif
     return 0;    
 }
-#endif
-
-#ifdef KICAD_SCRIPTING_EXPERIMENT
-
-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)
-{
-//    SetIcon(wxICON(mondrian));
-
-    wxMenuBar* mbar = new wxMenuBar;
-    wxMenu*    menu = new wxMenu;
-    menu->Append(ID_PYFRAME, _T("Make wx&Python frame"));
-    menu->AppendSeparator();
-    menu->Append(ID_EXIT, _T("&Close Frame\tAlt-X"));
-    mbar->Append(menu, _T("&File"));
-    SetMenuBar(mbar);
-
-    CreateStatusBar();
-    RedirectStdio();
-
-    // Make some child windows from C++
-    wxSplitterWindow* sp = new wxSplitterWindow(this, -1);
-    wxPanel* p1 = new wxPanel(sp, -1, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER);
-
-    new wxStaticText(p1, -1,
-                 _T("The frame, menu, splitter, this panel and this text were created in C++..."),
-                 wxPoint(10,10));
-
-    // And get a panel from Python
-    wxWindow* p2 = DoPythonStuff(sp);
-
-    if (p2)
-        sp->SplitHorizontally(p1, p2, GetClientSize().y/4);
-}
-
-void MyFrame::OnExit(wxCommandEvent& event)
-{
-    Close();
-}
-
-void MyFrame::ScriptingSetPcbEditFrame(PCB_EDIT_FRAME *aPCBEdaFrame)
-{
-	PcbEditFrame = aPCBEdaFrame;
-}
-
-//----------------------------------------------------------------------
-// This is where the fun begins...
-
-
-const char* python_code1 = "\
-import wx\n\
-f = wx.Frame(None, -1, 'Hello from wxPython!', size=(250, 150))\n\
-f.Show()\n\
-";
-
-void MyFrame::OnPyFrame(wxCommandEvent& event)
-{
-    // For simple Python code that doesn't have to interact with the
-    // C++ code in any way, you can execute it with PyRun_SimpleString.
-
-
-    // First, whenever you do anything with Python objects or code, you
-    // *MUST* aquire the Global Interpreter Lock and block other
-    // Python threads from running.
-    wxPyBlock_t blocked = wxPyBeginBlockThreads();
-
-    // Execute the code in the __main__ module
-    PyRun_SimpleString(python_code1);
-
-    // Finally, release the GIL and let other Python threads run.
-    wxPyEndBlockThreads(blocked);
-}
-
-
-void MyFrame::RedirectStdio() {
-    // This is a helpful little tidbit to help debugging and such.  It
-    // redirects Python's stdout and stderr to a window that will popup
-    // only on demand when something is printed, like a traceback.
-    const char* python_redirect = "import sys\n\
-import wx\n\
-output = wx.PyOnDemandOutputWindow()\n\
-sys.stdin = sys.stderr = output\n";
-    
-    wxPyBlock_t blocked = wxPyBeginBlockThreads();
-    PyRun_SimpleString(python_redirect);
-    wxPyEndBlockThreads(blocked);
-}
-
-
-
-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
-    // easily come from a file, or the whole thing could be in the Python
-    // module that is imported and manipulated directly in this C++ code.  See
-    // the Python API for more details.
-
-    wxWindow* window = NULL;
-    PyObject* result;
-
-    // As always, first grab the GIL
-    wxPyBlock_t blocked = wxPyBeginBlockThreads();
-
-    // Now make a dictionary to serve as the global namespace when the code is
-    // executed.  Put a reference to the builtins module in it.  (Yes, the
-    // names are supposed to be different, I don't know why...)
-    PyObject* globals = PyDict_New();
-    PyObject* builtins = PyImport_ImportModule("__builtin__");
-    PyDict_SetItemString(globals, "__builtins__", builtins);
-    Py_DECREF(builtins);
-
-    // Execute the code to make the makeWindow function
-    result = PyRun_String(pycrust_panel, Py_file_input, globals, globals);
-    // Was there an exception?
-    if (! result) {
-        PyErr_Print();
-        wxPyEndBlockThreads(blocked);
-        return NULL;
-    }
-    Py_DECREF(result);
-
-    // Now there should be an object named 'makeWindow' in the dictionary that
-    // we can grab a pointer to:
-    PyObject* func = PyDict_GetItemString(globals, "makeWindow");
-    wxASSERT(PyCallable_Check(func));
-
-    // Now build an argument tuple and call the Python function.  Notice the
-    // use of another wxPython API to take a wxWindows object and build a
-    // wxPython object that wraps it.
-    PyObject* arg = wxPyMake_wxObject(parent, false);
-    wxASSERT(arg != NULL);
-    PyObject* tuple = PyTuple_New(1);
-    PyTuple_SET_ITEM(tuple, 0, arg);
-    result = PyEval_CallObject(func, tuple);
-
-    // Was there an exception?
-    if (! result)
-        PyErr_Print();
-    else {
-        // 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);
-    }
-
-    // Release the python objects we still have
-    Py_DECREF(globals);
-    Py_DECREF(tuple);
-
-    // Finally, after all Python stuff is done, release the GIL
-    wxPyEndBlockThreads(blocked);
-
-    return window;
-}
 
 #endif
+
+
diff --git a/pcbnew/scripting/pcbnew_footprint_wizards.cpp b/pcbnew/scripting/pcbnew_footprint_wizards.cpp
index c14b8c20c7..3c59c2502a 100644
--- a/pcbnew/scripting/pcbnew_footprint_wizards.cpp
+++ b/pcbnew/scripting/pcbnew_footprint_wizards.cpp
@@ -4,7 +4,8 @@
  */
 
 #include "pcbnew_footprint_wizards.h"
-#include <wx/wxPython/wxPython.h>
+#include <python_scripting.h>
+
 #include <stdio.h>
 
 PYTHON_FOOTPRINT_WIZARD::PYTHON_FOOTPRINT_WIZARD(PyObject *aWizard)
@@ -29,7 +30,7 @@ PyObject* PYTHON_FOOTPRINT_WIZARD::CallMethod(const char* aMethod, PyObject *aAr
     {
         PyObject *result;
 
-        wxPyBlock_t blocked = wxPyBeginBlockThreads();
+        PY_BLOCK_THREADS( blocked );
 
         result = PyObject_CallObject( pFunc, aArglist );
         
@@ -42,7 +43,7 @@ PyObject* PYTHON_FOOTPRINT_WIZARD::CallMethod(const char* aMethod, PyObject *aAr
             printf ( "         : %s\n", PyString_AsString( PyObject_Str(b) ) );
         }
 
-        wxPyEndBlockThreads( blocked );
+        PY_UNBLOCK_THREADS( blocked );
         
         if ( result )
         {
@@ -70,12 +71,12 @@ wxString PYTHON_FOOTPRINT_WIZARD::CallRetStrMethod( const char* aMethod, PyObjec
     PyObject *result = CallMethod( aMethod, aArglist );
     if ( result )
     {
-         wxPyBlock_t blocked = wxPyBeginBlockThreads();
+         PY_BLOCK_THREADS( blocked );
          const char *str_res = PyString_AsString( result );
          ret  = wxString::FromUTF8( str_res );
          Py_DECREF( result );    
 
-         wxPyEndBlockThreads( blocked );
+         PY_UNBLOCK_THREADS( blocked );
     }
     return ret;
 }
@@ -99,7 +100,8 @@ wxArrayString PYTHON_FOOTPRINT_WIZARD::CallRetArrayStrMethod
              return ret;
          }
 
-         wxPyBlock_t blocked = wxPyBeginBlockThreads();
+         PY_BLOCK_THREADS( blocked );
+         
          int list_size = PyList_Size( result );
          
          for ( int n=0; n<list_size; n++ )
@@ -112,7 +114,8 @@ wxArrayString PYTHON_FOOTPRINT_WIZARD::CallRetArrayStrMethod
          }
          
          Py_DECREF( result );    
-         wxPyEndBlockThreads( blocked );
+         
+         PY_UNBLOCK_THREADS( blocked );
     }
     
     
@@ -148,12 +151,13 @@ int PYTHON_FOOTPRINT_WIZARD::GetNumParameterPages()
     {
          if ( !PyInt_Check( result ) ) 
             return -1;
-         wxPyBlock_t blocked = wxPyBeginBlockThreads();
+            
+         PY_BLOCK_THREADS( blocked );
 
          ret = PyInt_AsLong( result ); 
          Py_DECREF( result );    
 
-         wxPyEndBlockThreads( blocked );
+         PY_UNBLOCK_THREADS( blocked );
     }
     return ret;
 }
@@ -171,13 +175,13 @@ wxString PYTHON_FOOTPRINT_WIZARD::GetParameterPageName( int aPage )
     
     if ( result )
     {
-         wxPyBlock_t blocked = wxPyBeginBlockThreads();
+         PY_BLOCK_THREADS( blocked );
 
          const char *str_res = PyString_AsString( result );
          ret  = wxString::FromUTF8( str_res );
          Py_DECREF( result );    
 
-         wxPyEndBlockThreads( blocked );
+         PY_UNBLOCK_THREADS( blocked );
     }
     return ret;
 }
@@ -295,7 +299,7 @@ MODULE *PYTHON_FOOTPRINT_WIZARD::GetModule()
     if (!result) 
         return NULL;
     
-    wxPyBlock_t blocked = wxPyBeginBlockThreads();
+    PY_BLOCK_THREADS( blocked );
 
     obj = PyObject_GetAttrString( result, "this" );
     
@@ -310,7 +314,7 @@ MODULE *PYTHON_FOOTPRINT_WIZARD::GetModule()
         */
         PyErr_Print();
     }
-    wxPyEndBlockThreads( blocked );
+    PY_UNBLOCK_THREADS( blocked );
 
     MODULE *mod = PyModule_to_MODULE( obj );
 
diff --git a/scripting/python_scripting.cpp b/scripting/python_scripting.cpp
index d76b79633c..a84b804d03 100644
--- a/scripting/python_scripting.cpp
+++ b/scripting/python_scripting.cpp
@@ -28,9 +28,16 @@
  */
 
 #include <python_scripting.h>
-#include <wx/wxPython/wxPython.h>
 #include <stdlib.h>
 #include <string.h>
+#ifdef __GNUG__
+#pragma implementation
+#endif
+
+#include <fctsys.h>
+#include <wxstruct.h>
+#include <common.h>
+#include <colors.h>
 
 /* init functions defined by swig */
 
@@ -127,6 +134,8 @@ bool pcbnewInitPythonScripting()
     swigSwitchPythonBuiltin();  // switch the python builtin modules to our new list
 
     Py_Initialize();
+
+    #ifdef KICAD_SCRIPTING_WXPYTHON
     PyEval_InitThreads();
 
     // Load the wxPython core API.  Imports the wx._core_ module and sets a
@@ -146,21 +155,140 @@ bool pcbnewInitPythonScripting()
 
     // load pcbnew inside python, and load all the user plugins, TODO: add system wide plugins
 
-    wxPyBlock_t blocked = wxPyBeginBlockThreads();
+    PY_BLOCK_THREADS( blocked );
+    #endif
     PyRun_SimpleString( "import sys\n"
                         "sys.path.append(\".\")\n"
                         "import pcbnew\n"
                         "pcbnew.LoadPlugins()"
                         );
-    wxPyEndBlockThreads(blocked);
 
+    PY_UNBLOCK_THREADS( blocked );
     return true;
 }
 
 void pcbnewFinishPythonScripting()
 {
-
+#ifdef KICAD_SCRIPTING_WXPYTHON
     wxPyEndAllowThreads(g_PythonMainTState);
+#endif
     Py_Finalize();
 
 }
+
+#ifdef KICAD_SCRIPTING_WXPYTHON
+
+void RedirectStdio() 
+{
+    // This is a helpful little tidbit to help debugging and such.  It
+    // redirects Python's stdout and stderr to a window that will popup
+    // only on demand when something is printed, like a traceback.
+    const char* python_redirect = 
+"import sys\n\
+import wx\n\
+output = wx.PyOnDemandOutputWindow()\n\
+c sys.stderr = output\n";
+    
+    PY_BLOCK_THREADS( blocked );
+    PyRun_SimpleString( python_redirect );
+    PY_UNBLOCK_THREADS( blocked );
+}
+
+
+
+wxWindow* CreatePythonShellWindow(wxWindow* parent)
+{
+
+const char* pycrust_panel = "\
+import wx\n\
+from wx.py import shell, version\n\
+\n\
+class PyCrustPanel(wx.Panel):\n\
+\tdef __init__(self, parent):\n\
+\t\twx.Panel.__init__(self, parent, -1, style=wx.SUNKEN_BORDER)\n\
+\t\t\n\
+\t\t\n\
+\t\tintro = \"Welcome To PyCrust %s - KiCAD 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(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 = PyCrustPanel(parent)\n\
+    return win\n\
+";
+
+
+    wxWindow* window = NULL;
+    PyObject* result;
+
+    // As always, first grab the GIL
+    PY_BLOCK_THREADS( blocked );
+
+    // Now make a dictionary to serve as the global namespace when the code is
+    // executed.  Put a reference to the builtins module in it.  
+
+    PyObject* globals = PyDict_New();
+    PyObject* builtins = PyImport_ImportModule( "__builtin__" );
+    PyDict_SetItemString( globals, "__builtins__", builtins );
+    Py_DECREF(builtins);
+
+    // Execute the code to make the makeWindow function we defined above
+    result = PyRun_String( pycrust_panel, Py_file_input, globals, globals );
+
+    // Was there an exception?
+    if ( !result ) 
+    {
+        PyErr_Print();
+        PY_UNBLOCK_THREADS( blocked );
+        return NULL;
+    }
+    Py_DECREF(result);
+
+    // Now there should be an object named 'makeWindow' in the dictionary that
+    // we can grab a pointer to:
+    PyObject* func = PyDict_GetItemString( globals, "makeWindow" );
+    wxASSERT( PyCallable_Check( func ) );
+
+    // Now build an argument tuple and call the Python function.  Notice the
+    // use of another wxPython API to take a wxWindows object and build a
+    // wxPython object that wraps it.
+
+    PyObject* arg = wxPyMake_wxObject( parent, false );
+    wxASSERT( arg != NULL );
+    PyObject* tuple = PyTuple_New( 1 );
+    PyTuple_SET_ITEM( tuple, 0, arg );
+    result = PyEval_CallObject( func, tuple );
+
+    // Was there an exception?
+    if ( !result )
+        PyErr_Print();
+    else 
+    {
+        // 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);
+    }
+
+    // Release the python objects we still have
+    Py_DECREF( globals );
+    Py_DECREF( tuple );
+
+    // Finally, after all Python stuff is done, release the GIL
+    PY_UNBLOCK_THREADS( blocked );
+
+    return window;
+}
+#endif
+
+
+
+
+
+
+
diff --git a/scripting/python_scripting.h b/scripting/python_scripting.h
index 6d28be4b10..2964157668 100644
--- a/scripting/python_scripting.h
+++ b/scripting/python_scripting.h
@@ -12,8 +12,10 @@
 
     #include <Python.h>
     #ifndef NO_WXPYTHON_EXTENSION_HEADERS
+    #ifdef KICAD_SCRIPTING_WXPYTHON
         #include <wx/wxPython/wxPython.h>
     #endif
+    #endif
 
 
 /* Function pcbnewInitPythonScripting
@@ -23,4 +25,21 @@
 bool pcbnewInitPythonScripting();
 void pcbnewFinishPythonScripting();
 
+
+
+#ifdef KICAD_SCRIPTING_WXPYTHON
+
+void RedirectStdio(); 
+wxWindow* CreatePythonShellWindow(wxWindow* parent);
+
+#define PY_BLOCK_THREADS(name)    wxPyBlock_t name = wxPyBeginBlockThreads()
+#define PY_UNBLOCK_THREADS(name)    wxPyEndBlockThreads(name)
+
+#else
+
+#define PY_BLOCK_THREADS(name)    
+#define PY_UNBLOCK_THREADS(name) 
+
+#endif
+
 #endif