diff options
Diffstat (limited to 'lib/wx/c_src')
-rw-r--r-- | lib/wx/c_src/Makefile.in | 7 | ||||
-rw-r--r-- | lib/wx/c_src/gen/wxe_derived_dest.h | 6 | ||||
-rw-r--r-- | lib/wx/c_src/gen/wxe_events.cpp | 10 | ||||
-rw-r--r-- | lib/wx/c_src/gen/wxe_funcs.cpp | 21 | ||||
-rw-r--r-- | lib/wx/c_src/wxe_callback_impl.cpp (renamed from lib/wx/c_src/wxePrintout.cpp) | 71 | ||||
-rw-r--r-- | lib/wx/c_src/wxe_callback_impl.h | 75 | ||||
-rw-r--r-- | lib/wx/c_src/wxe_driver.c | 4 | ||||
-rw-r--r-- | lib/wx/c_src/wxe_driver.h | 3 | ||||
-rw-r--r-- | lib/wx/c_src/wxe_events.h | 14 | ||||
-rw-r--r-- | lib/wx/c_src/wxe_gl.cpp | 17 | ||||
-rw-r--r-- | lib/wx/c_src/wxe_gl.h | 25 | ||||
-rw-r--r-- | lib/wx/c_src/wxe_helpers.cpp | 95 | ||||
-rw-r--r-- | lib/wx/c_src/wxe_helpers.h | 122 | ||||
-rw-r--r-- | lib/wx/c_src/wxe_impl.cpp | 466 | ||||
-rw-r--r-- | lib/wx/c_src/wxe_impl.h | 218 | ||||
-rw-r--r-- | lib/wx/c_src/wxe_main.cpp | 163 | ||||
-rw-r--r-- | lib/wx/c_src/wxe_memory.h | 61 |
17 files changed, 784 insertions, 594 deletions
diff --git a/lib/wx/c_src/Makefile.in b/lib/wx/c_src/Makefile.in index 5507a74c14..93a191378f 100644 --- a/lib/wx/c_src/Makefile.in +++ b/lib/wx/c_src/Makefile.in @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2008-2012. All Rights Reserved. +# Copyright Ericsson AB 2008-2014. All Rights Reserved. # # The contents of this file are subject to the Erlang Public License, # Version 1.1, (the "License"); you may not use this file except in @@ -34,8 +34,9 @@ SO_EXT = @SO_EXT@ OBJC_CC=@OBJC_CC@ OBJC_CFLAGS=@OBJC_CFLAGS@ -GENERAL = wxe_driver wxe_ps_init wxe_impl wxePrintout wxe_return wxe_gl -GENERAL_H = wxe_driver.h wxe_impl.h wxe_return.h +GENERAL = wxe_driver wxe_ps_init wxe_main wxe_impl wxe_helpers wxe_callback_impl wxe_return wxe_gl +GENERAL_H = wxe_callback_impl.h wxe_driver.h wxe_events.h wxe_gl.h \ + wxe_helpers.h wxe_impl.h wxe_memory.h wxe_return.h GENERATED_F = wxe_funcs wxe_events wxe_init GENERATED_H = gen/wxe_macros.h diff --git a/lib/wx/c_src/gen/wxe_derived_dest.h b/lib/wx/c_src/gen/wxe_derived_dest.h index 8dcaf1c1ac..7e2d4524cb 100644 --- a/lib/wx/c_src/gen/wxe_derived_dest.h +++ b/lib/wx/c_src/gen/wxe_derived_dest.h @@ -736,6 +736,12 @@ class EwxPrintout : public wxPrintout { EwxPrintout(const wxString& title) : wxPrintout(title) {}; }; +class EwxStyledTextCtrl : public wxStyledTextCtrl { + public: ~EwxStyledTextCtrl() {((WxeApp *)wxTheApp)->clearPtr(this);}; + EwxStyledTextCtrl(wxWindow * parent,wxWindowID id,const wxPoint& pos,const wxSize& size,long style) : wxStyledTextCtrl(parent,id,pos,size,style) {}; + EwxStyledTextCtrl() : wxStyledTextCtrl() {}; +}; + class EwxClipboard : public wxClipboard { public: ~EwxClipboard() {((WxeApp *)wxTheApp)->clearPtr(this);}; EwxClipboard() : wxClipboard() {}; diff --git a/lib/wx/c_src/gen/wxe_events.cpp b/lib/wx/c_src/gen/wxe_events.cpp index fb3a065448..a1b4d090b3 100644 --- a/lib/wx/c_src/gen/wxe_events.cpp +++ b/lib/wx/c_src/gen/wxe_events.cpp @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2008-2013. All Rights Reserved. + * Copyright Ericsson AB 2008-2014. All Rights Reserved. * * The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in @@ -297,6 +297,7 @@ void initEventTable() {wxEVT_TASKBAR_RIGHT_UP, 227, "taskbar_right_up"}, {wxEVT_TASKBAR_LEFT_DCLICK, 227, "taskbar_left_dclick"}, {wxEVT_TASKBAR_RIGHT_DCLICK, 227, "taskbar_right_dclick"}, + {wxEVT_INIT_DIALOG, 228, "init_dialog"}, {-1, 0, } }; for(int i=0; event_types[i].ev_type != -1; i++) { @@ -814,6 +815,13 @@ case 227: {// wxTaskBarIconEvent rt.addTupleCount(2); break; } +case 228: {// wxInitDialogEvent + evClass = (char*)"wxInitDialogEvent"; + rt.addAtom((char*)"wxInitDialog"); + rt.addAtom(Etype->eName); + rt.addTupleCount(2); + break; +} } rt.addTupleCount(5); diff --git a/lib/wx/c_src/gen/wxe_funcs.cpp b/lib/wx/c_src/gen/wxe_funcs.cpp index b5fbac3fe0..82dd414911 100644 --- a/lib/wx/c_src/gen/wxe_funcs.cpp +++ b/lib/wx/c_src/gen/wxe_funcs.cpp @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2008-2013. All Rights Reserved. + * Copyright Ericsson AB 2008-2014. All Rights Reserved. * * The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in @@ -45,9 +45,14 @@ void WxeApp::wxe_dispatch(wxeCommand& Ecmd) switch (Ecmd.op) { case DESTROY_OBJECT: { - wxObject *This = (wxObject *) getPtr(bp,memenv); if(This) { ((WxeApp *) wxTheApp)->clearPtr((void *) This); - delete This; } - } break; + wxObject *This = (wxObject *) getPtr(bp,memenv); + if(This) { + if(recurse_level > 1) { + delayed_delete->Append(Ecmd.Save()); + } else { + ((WxeApp *) wxTheApp)->clearPtr((void *) This); + delete This; } + } } break; case WXE_REGISTER_OBJECT: { registerPid(bp, Ecmd.caller, memenv); rt.addAtom("ok"); @@ -26953,14 +26958,14 @@ case wxStyledTextCtrl_new_2: { // wxStyledTextCtrl::wxStyledTextCtrl style = (long)*(int *) bp; bp += 4; } break; }}; - wxStyledTextCtrl * Result = new wxStyledTextCtrl(parent,id,pos,size,style); - /* Possible memory leak here, class is missing virt dest */ + wxStyledTextCtrl * Result = new EwxStyledTextCtrl(parent,id,pos,size,style); + newPtr((void *) Result, 0, memenv); rt.addRef(getRef((void *)Result,memenv), "wxStyledTextCtrl"); break; } case wxStyledTextCtrl_new_0: { // wxStyledTextCtrl::wxStyledTextCtrl - wxStyledTextCtrl * Result = new wxStyledTextCtrl(); - /* Possible memory leak here, class is missing virt dest */ + wxStyledTextCtrl * Result = new EwxStyledTextCtrl(); + newPtr((void *) Result, 0, memenv); rt.addRef(getRef((void *)Result,memenv), "wxStyledTextCtrl"); break; } diff --git a/lib/wx/c_src/wxePrintout.cpp b/lib/wx/c_src/wxe_callback_impl.cpp index fc8782ba95..8ba2557d82 100644 --- a/lib/wx/c_src/wxePrintout.cpp +++ b/lib/wx/c_src/wxe_callback_impl.cpp @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2008-2013. All Rights Reserved. + * Copyright Ericsson AB 2008-2014. All Rights Reserved. * * The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in @@ -20,9 +20,49 @@ #include <wx/wx.h> #include "wxe_impl.h" #include "wxe_return.h" +#include "wxe_events.h" +#include "wxe_gl.h" #include "gen/wxe_macros.h" #include "gen/wxe_derived_dest.h" + +/* **************************************************************************** + * CallbackData * + * ****************************************************************************/ + +wxeCallbackData::wxeCallbackData(ErlDrvTermData caller, int req, char *req_type, + int funcb, int skip_ev, wxeErlTerm * userData, + wxeEvtListener *handler_cb) + : wxObject() +{ + listener = caller; + obj = req; + fun_id = funcb; + strcpy(class_name, req_type); + skip = skip_ev; + user_data = userData; + handler = handler_cb; +} + +wxeCallbackData::~wxeCallbackData() { + // fprintf(stderr, "CBD Deleteing %p %s\r\n", this, class_name); fflush(stderr); + if(user_data) { + delete user_data; + } + ptrMap::iterator it; + it = ((WxeApp *)wxTheApp)->ptr2ref.find(handler); + if(it != ((WxeApp *)wxTheApp)->ptr2ref.end()) { + wxeRefData *refd = it->second; + wxeReturn rt = wxeReturn(WXE_DRV_PORT, refd->memenv->owner, false); + rt.addAtom("wx_delete_cb"); + rt.addInt(fun_id); + rt.addRef(refd->ref, "wxeEvtListener"); + rt.addRef(obj, class_name); + rt.addTupleCount(4); + rt.send(); + } +} + /* *****************************************************************/ /* Special Class impls */ @@ -228,6 +268,35 @@ EwxListCtrl::~EwxListCtrl() { clear_cb(port, onGetItemColumnImage); ((WxeApp *)wxTheApp)->clearPtr(this); } + +/* **************************************************************************** + * wxListCtrlCompare wrapper + * ****************************************************************************/ + +int wxCALLBACK wxEListCtrlCompare(long item1, long item2, long callbackInfoPtr) +{ + callbackInfo * cb = (callbackInfo *)callbackInfoPtr; + wxeMemEnv * memenv = ((WxeApp *) wxTheApp)->getMemEnv(cb->port); + wxeReturn rt = wxeReturn(WXE_DRV_PORT, memenv->owner, false); + rt.addInt(cb->callbackID); + rt.addInt(item1); + rt.addInt(item2); + rt.endList(2); + rt.addAtom("_wx_invoke_cb_"); + rt.addTupleCount(3); + rt.send(); + handle_event_callback(WXE_DRV_PORT_HANDLE, memenv->owner); + + if(((WxeApp *) wxTheApp)->cb_buff) { + int res = * (int*) ((WxeApp *) wxTheApp)->cb_buff; + driver_free(((WxeApp *) wxTheApp)->cb_buff); + ((WxeApp *) wxTheApp)->cb_buff = NULL; + return res; + } + return 0; +} + + // tools void clear_cb(ErlDrvTermData port, int callback) diff --git a/lib/wx/c_src/wxe_callback_impl.h b/lib/wx/c_src/wxe_callback_impl.h new file mode 100644 index 0000000000..c7243e23a4 --- /dev/null +++ b/lib/wx/c_src/wxe_callback_impl.h @@ -0,0 +1,75 @@ +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 2014. All Rights Reserved. + * + * The contents of this file are subject to the Erlang Public License, + * Version 1.1, (the "License"); you may not use this file except in + * compliance with the License. You should have received a copy of the + * Erlang Public License along with this software. If not, it can be + * retrieved online at http://www.erlang.org/. + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * %CopyrightEnd% + */ + +#ifndef _WXE_CALLBACK_IMPL_H +#define _WXE_CALLBACK_IMPL_H + +void pre_callback(); +void handle_event_callback(ErlDrvPort port, ErlDrvTermData process); + +class wxEPrintout : public wxPrintout +{ + public: + wxEPrintout(wxString Title, int onPrintP, int onPrepareP, + int onBeginP, int onEndP, + int onBeginD, int onEndD, + int hasP, int getPageI, ErlDrvTermData Port) : + wxPrintout(Title), + onPrintPage(onPrintP), onPreparePrinting(onPrepareP), + onBeginPrinting(onBeginP), onEndPrinting(onEndP), + onBeginDocument(onBeginD), onEndDocument(onEndD), hasPage(hasP), getPageInfo(getPageI), + port(Port) + { } ; + + ~wxEPrintout(); + + bool OnBeginDocument(int startPage, int endPage); + void OnEndDocument(); + void OnBeginPrinting(); + void OnEndPrinting(); + + void OnPreparePrinting(); + + bool HasPage(int page); + bool OnPrintPage(int page); + void GetPageInfo(int *minPage, int *maxPage, int *pageFrom, int *pageTo); + + int onPrintPage; + int onPreparePrinting; + int onBeginPrinting; + int onEndPrinting; + int onBeginDocument; + int onEndDocument; + int hasPage; + int getPageInfo; + + ErlDrvTermData port; +}; + +void clear_cb(ErlDrvTermData port, int callback); + +// Implementation of wxListCtrlCompare +struct callbackInfo { + ErlDrvTermData port; + int callbackID; +}; + +int wxCALLBACK wxEListCtrlCompare(long item1, long item2, long callbackInfoPtr); + +#endif diff --git a/lib/wx/c_src/wxe_driver.c b/lib/wx/c_src/wxe_driver.c index 4d3aa577bf..ea52737fa2 100644 --- a/lib/wx/c_src/wxe_driver.c +++ b/lib/wx/c_src/wxe_driver.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2008-2013. All Rights Reserved. + * Copyright Ericsson AB 2008-2014. All Rights Reserved. * * The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in @@ -195,7 +195,7 @@ void wxe_process_died(ErlDrvData handle, ErlDrvMonitor *monitor) { /* Callback is active for the dead process */ wxe_data *sd = ((wxe_data *)handle); - push_command(WXE_CB_RETURN,NULL,0,sd); + push_command(WXE_CB_DIED,NULL,0,sd); /* ErlDrvTermData pid; */ /* pid = driver_get_monitored_process(sd->port_handle, monitor); */ diff --git a/lib/wx/c_src/wxe_driver.h b/lib/wx/c_src/wxe_driver.h index 0f0143bd4c..e35bbe2118 100644 --- a/lib/wx/c_src/wxe_driver.h +++ b/lib/wx/c_src/wxe_driver.h @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2008-2013. All Rights Reserved. + * Copyright Ericsson AB 2008-2014. All Rights Reserved. * * The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in @@ -89,6 +89,7 @@ extern char * erl_wx_privdir; #define WXE_BIN_INCR 11 #define WXE_BIN_DECR 12 #define WXE_INIT_OPENGL 13 +#define WXE_CB_DIED 14 #define OPENGL_START 5000 diff --git a/lib/wx/c_src/wxe_events.h b/lib/wx/c_src/wxe_events.h index 718e0ad120..22a737d854 100644 --- a/lib/wx/c_src/wxe_events.h +++ b/lib/wx/c_src/wxe_events.h @@ -1,20 +1,20 @@ /* * %CopyrightBegin% - * - * Copyright Ericsson AB 2008-2013. All Rights Reserved. - * + * + * Copyright Ericsson AB 2008-2014. All Rights Reserved. + * * The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in * compliance with the License. You should have received a copy of the * Erlang Public License along with this software. If not, it can be * retrieved online at http://www.erlang.org/. - * + * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See * the License for the specific language governing rights and limitations * under the License. - * - * %CopyrightEnd% + * + * %CopyrightEnd% */ #ifndef __WXE_EVENT_H__ @@ -22,6 +22,8 @@ #include "wxe_driver.h" +bool sendevent(wxEvent * event, ErlDrvTermData port); + class wxeEtype { public: diff --git a/lib/wx/c_src/wxe_gl.cpp b/lib/wx/c_src/wxe_gl.cpp index 34904397d3..a9feb23831 100644 --- a/lib/wx/c_src/wxe_gl.cpp +++ b/lib/wx/c_src/wxe_gl.cpp @@ -1,20 +1,20 @@ /* * %CopyrightBegin% - * - * Copyright Ericsson AB 2008-2013. All Rights Reserved. - * + * + * Copyright Ericsson AB 2008-2014. All Rights Reserved. + * * The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in * compliance with the License. You should have received a copy of the * Erlang Public License along with this software. If not, it can be * retrieved online at http://www.erlang.org/. - * + * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See * the License for the specific language governing rights and limitations * under the License. - * - * %CopyrightEnd% + * + * %CopyrightEnd% */ #include <stdio.h> @@ -26,8 +26,9 @@ #endif #include "wxe_impl.h" #include "wxe_return.h" +#include "wxe_gl.h" -/* **************************************************************************** +/* **************************************************************************** * Opengl context management * * ****************************************************************************/ @@ -138,7 +139,7 @@ void gl_dispatch(int op, char *bp,ErlDrvTermData caller,WXEBinRef *bins[]){ else { ErlDrvTermData rt[] = // Error msg {ERL_DRV_ATOM, driver_mk_atom((char *) "_egl_error_"), - ERL_DRV_INT, op, + ERL_DRV_INT, (ErlDrvTermData) op, ERL_DRV_ATOM, driver_mk_atom((char *) "no_gl_context"), ERL_DRV_TUPLE,3}; erl_drv_send_term(WXE_DRV_PORT,caller,rt,8); diff --git a/lib/wx/c_src/wxe_gl.h b/lib/wx/c_src/wxe_gl.h index 1b556ff4ec..dc117bf610 100644 --- a/lib/wx/c_src/wxe_gl.h +++ b/lib/wx/c_src/wxe_gl.h @@ -1,22 +1,35 @@ /* * %CopyrightBegin% - * - * Copyright Ericsson AB 2008-2010. All Rights Reserved. - * + * + * Copyright Ericsson AB 2008-2014. All Rights Reserved. + * * The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in * compliance with the License. You should have received a copy of the * Erlang Public License along with this software. If not, it can be * retrieved online at http://www.erlang.org/. - * + * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See * the License for the specific language governing rights and limitations * under the License. - * - * %CopyrightEnd% + * + * %CopyrightEnd% */ +#ifndef _WXE_GL_H +#define _WXE_GL_H + #include "egl_impl.h" +#include "wxe_return.h" +void activateGL(ErlDrvTermData caller); +void setActiveGL(ErlDrvTermData caller, wxGLCanvas *canvas); +void deleteActiveGL(wxGLCanvas *canvas); void wxe_initOpenGL(wxeReturn, char*); +void gl_dispatch(int op, char *bp, ErlDrvTermData caller, WXEBinRef *bins[]); + +WX_DECLARE_HASH_MAP(ErlDrvTermData, wxGLCanvas*, wxIntegerHash, wxIntegerEqual, wxeGLC); +extern wxeGLC glc; + +#endif diff --git a/lib/wx/c_src/wxe_helpers.cpp b/lib/wx/c_src/wxe_helpers.cpp new file mode 100644 index 0000000000..15d75080d9 --- /dev/null +++ b/lib/wx/c_src/wxe_helpers.cpp @@ -0,0 +1,95 @@ +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 2014. All Rights Reserved. + * + * The contents of this file are subject to the Erlang Public License, + * Version 1.1, (the "License"); you may not use this file except in + * compliance with the License. You should have received a copy of the + * Erlang Public License along with this software. If not, it can be + * retrieved online at http://www.erlang.org/. + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * %CopyrightEnd% + */ + +#include <wx/wx.h> +#include "wxe_impl.h" + +/* **************************************************************************** + * Erlang Commands + * ****************************************************************************/ + +wxeCommand::wxeCommand(int fc,char * cbuf,int buflen, wxe_data *sd) + : wxObject() +{ + WXEBinRef *temp, *start, *prev; + int n = 0; + ref_count = 1; + caller = driver_caller(sd->port_handle); + port = sd->port; + op = fc; + len = buflen; + bin[0] = NULL; + bin[1] = NULL; + bin[2] = NULL; + + if(cbuf) { + buffer = (char *) driver_alloc(len); + memcpy((void *) buffer, (void *) cbuf, len);; + + temp = sd->bin; + + prev = NULL; + start = temp; + + while(temp) { + if(caller == temp->from) { + bin[n++] = temp; + if(prev) { + prev->next = temp->next; + } else { + start = temp->next; + } + temp = temp->next; + } else { + prev = temp; + temp = temp->next; + } + } + sd->bin = start; + } else { // No-op only PING currently + buffer = NULL; + } +} + +wxeCommand::~wxeCommand() { + int n = 0; + if(buffer) { + while(bin[n]) { + if(bin[n]->bin) + driver_free_binary(bin[n]->bin); + driver_free(bin[n++]); + } + driver_free(buffer); + } +} + +/* **************************************************************************** + * TreeItemData + * ****************************************************************************/ + +wxETreeItemData::wxETreeItemData(int sz, char * data) { + size = sz; + bin = (char *) driver_alloc(sz); + memcpy(bin, data, sz); +} + +wxETreeItemData::~wxETreeItemData() +{ + driver_free(bin); +} diff --git a/lib/wx/c_src/wxe_helpers.h b/lib/wx/c_src/wxe_helpers.h new file mode 100644 index 0000000000..659bc666c6 --- /dev/null +++ b/lib/wx/c_src/wxe_helpers.h @@ -0,0 +1,122 @@ +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 2014. All Rights Reserved. + * + * The contents of this file are subject to the Erlang Public License, + * Version 1.1, (the "License"); you may not use this file except in + * compliance with the License. You should have received a copy of the + * Erlang Public License along with this software. If not, it can be + * retrieved online at http://www.erlang.org/. + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * %CopyrightEnd% + */ + +#ifndef _WXE_HELPER_H +#define _WXE_HELPER_H + +DECLARE_EVENT_TYPE(wxeEVT_META_COMMAND, -1) + +class wxeMetaCommand : public wxEvent +{ + public: + wxeMetaCommand(wxe_data *sd, int EvId) + : wxEvent(EvId, wxeEVT_META_COMMAND) + { caller = driver_caller(sd->port_handle); port = sd->port; pdl = sd->pdl; } ; + wxeMetaCommand(const wxeMetaCommand& event) + : wxEvent(event) + { caller = event.caller; port = event.port; pdl = event.pdl; }; + virtual ~wxeMetaCommand() {}; + virtual wxEvent *Clone() const { return new wxeMetaCommand(*this); } + + ErlDrvTermData caller; + ErlDrvTermData port; + ErlDrvPDL pdl; +}; + +class wxeCommand : public wxObject +{ + public: + wxeCommand(int fc,char * cbuf,int buflen, wxe_data *); + virtual ~wxeCommand(); // Use Delete() + + wxeCommand * Save() {ref_count++; return this; }; + void Delete() {if(--ref_count < 1) delete this;}; + + ErlDrvTermData caller; + ErlDrvTermData port; + WXEBinRef * bin[3]; + char * buffer; + int len; + int op; + int ref_count; +}; + +class intListElement { + public: + intListElement(int Element) {car = Element; cdr = NULL;}; + intListElement(int Element, intListElement *list) + {car = Element; cdr = list;}; + int car; + intListElement *cdr; +}; + +class intList { + public: + intList() {list = NULL;}; + ~intList() { + intListElement *head = list; + while(head) { + intListElement *tail=head->cdr; + delete head; + head = tail; + } }; + bool IsEmpty() {return list == NULL;}; + void Append(int Element) { list = new intListElement(Element, list); }; + int Pop() { + intListElement *temp = list; + int res = list->car; + list = temp->cdr; + delete temp; + return res; + } + intListElement *list; +}; + +class wxe_badarg +{ + public: + wxe_badarg(int Ref) : ref(Ref) { } ; + int ref; +}; + +class wxeErlTerm : public wxClientData +{ + public: + wxeErlTerm(WXEBinRef * data) + { + size = data->size; + bin = (char *) driver_alloc(size); + memcpy(bin, data->base, size); + } ; + ~wxeErlTerm() { driver_free(bin); }; + char * bin; + int size; +}; + +class wxETreeItemData : public wxTreeItemData +{ + public: + wxETreeItemData(int sz, char * data); + ~wxETreeItemData(); + + int size; + char * bin; +}; + +#endif diff --git a/lib/wx/c_src/wxe_impl.cpp b/lib/wx/c_src/wxe_impl.cpp index 4968075659..5964ccfd00 100644 --- a/lib/wx/c_src/wxe_impl.cpp +++ b/lib/wx/c_src/wxe_impl.cpp @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2008-2013. All Rights Reserved. + * Copyright Ericsson AB 2008-2014. All Rights Reserved. * * The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in @@ -23,10 +23,6 @@ #include <wx/wx.h> -#if defined(_WIN32) -#include <wx/msw/private.h> // for wxSetInstance -#endif - // Avoid including these in dcbuffer below #include "wx/dcmemory.h" #include "wx/dcclient.h" @@ -34,12 +30,12 @@ // Ok ugly but needed for wxBufferedDC crash workaround #define private public #include <wx/dcbuffer.h> - #undef private #include "wxe_impl.h" #include "wxe_events.h" #include "wxe_return.h" +#include "wxe_gl.h" IMPLEMENT_APP_NO_MAIN(WxeApp) @@ -47,120 +43,21 @@ DECLARE_APP(WxeApp) DEFINE_EVENT_TYPE(wxeEVT_META_COMMAND) -#define WXE_NOT_INITIATED 0 -#define WXE_INITIATED 1 -#define WXE_EXITED 2 -#define WXE_ERROR -1 - #define WXE_NORMAL 0 #define WXE_CALLBACK 1 #define WXE_STORED 2 -ErlDrvTid wxe_thread; - -ErlDrvMutex *wxe_status_m; -ErlDrvCond *wxe_status_c; - -ErlDrvMutex * wxe_batch_locker_m; -ErlDrvCond * wxe_batch_locker_c; - -static int wxe_status = WXE_NOT_INITIATED; +// Globals initiated in wxe_init.cpp +extern ErlDrvMutex *wxe_status_m; +extern ErlDrvCond *wxe_status_c; +extern ErlDrvMutex * wxe_batch_locker_m; +extern ErlDrvCond * wxe_batch_locker_c; +extern ErlDrvTermData init_caller; +extern int wxe_status; wxList * wxe_batch = NULL; wxList * wxe_batch_cb_saved = NULL; - -ErlDrvTermData wxe_batch_caller = 0; -ErlDrvTermData init_caller = 0; - -// extern opengl -void gl_dispatch(int op, char *bp, ErlDrvTermData caller, WXEBinRef *bins[]); - - -// Until fixed in emulator -#ifndef _WIN32 -extern "C" { -extern void erts_thread_disable_fpe(void); -} -#endif - -#if defined(__APPLE__) && defined(__MACH__) && !defined(__DARWIN__) -#define __DARWIN__ 1 -#endif - -#ifdef __DARWIN__ -extern "C" { - int erl_drv_stolen_main_thread_join(ErlDrvTid tid, void **respp); - int erl_drv_steal_main_thread(char *name, - ErlDrvTid *dtid, - void* (*func)(void*), - void* arg, - ErlDrvThreadOpts *opts); -} -#endif - -void *wxe_main_loop(void * ); - -/* ************************************************************ - * START AND STOP of driver thread - * ************************************************************/ - -int load_native_gui() -{ - return 1; -} - -int start_native_gui(wxe_data *sd) -{ - int res; - wxe_status_m = erl_drv_mutex_create((char *) "wxe_status_m"); - wxe_status_c = erl_drv_cond_create((char *)"wxe_status_c"); - - wxe_batch_locker_m = erl_drv_mutex_create((char *)"wxe_batch_locker_m"); - wxe_batch_locker_c = erl_drv_cond_create((char *)"wxe_batch_locker_c"); - init_caller = driver_connected(sd->port_handle); - -#ifdef __DARWIN__ - res = erl_drv_steal_main_thread((char *)"wxwidgets", - &wxe_thread,wxe_main_loop,(void *) sd->pdl,NULL); -#else - res = erl_drv_thread_create((char *)"wxwidgets", - &wxe_thread,wxe_main_loop,(void *) sd->pdl,NULL); -#endif - if(res == 0) { - erl_drv_mutex_lock(wxe_status_m); - for(;wxe_status == WXE_NOT_INITIATED;) { - erl_drv_cond_wait(wxe_status_c, wxe_status_m); - } - erl_drv_mutex_unlock(wxe_status_m); - return wxe_status; - } else { - wxString msg; - msg.Printf(wxT("Erlang failed to create wxe-thread %d\r\n"), res); - send_msg("error", &msg); - return -1; - } -} - -void stop_native_gui(wxe_data *sd) -{ - if(wxe_status == WXE_INITIATED) { - meta_command(WXE_SHUTDOWN, sd); - } -#ifdef __DARWIN__ - erl_drv_stolen_main_thread_join(wxe_thread, NULL); -#else - erl_drv_thread_join(wxe_thread, NULL); -#endif - erl_drv_mutex_destroy(wxe_status_m); - erl_drv_cond_destroy(wxe_status_c); - erl_drv_mutex_destroy(wxe_batch_locker_m); - erl_drv_cond_destroy(wxe_batch_locker_c); -} - -void unload_native_gui() -{ - -} +int wxe_batch_caller = 0; // inside batch if larger than 0 /* ************************************************************ * Commands from erlang @@ -169,7 +66,8 @@ void unload_native_gui() void push_command(int op,char * buf,int len, wxe_data *sd) { - // fprintf(stderr, "Op %d %d\r\n", op, (int) driver_caller(sd->port_handle)),fflush(stderr); + /* fprintf(stderr, "Op %d %d [%ld] %d\r\n", op, (int) driver_caller(sd->port_handle), + wxe_batch->size(), wxe_batch_caller),fflush(stderr); */ wxeCommand *Cmd = new wxeCommand(op, buf, len, sd); erl_drv_mutex_lock(wxe_batch_locker_m); wxe_batch->Append(Cmd); @@ -195,9 +93,8 @@ void meta_command(int what, wxe_data *sd) { wxeCommand *Cmd = new wxeCommand(WXE_DEBUG_PING, NULL, 0, sd); wxe_batch->Append(Cmd); erl_drv_cond_signal(wxe_batch_locker_c); - } else { - wxWakeUpIdle(); } + wxWakeUpIdle(); erl_drv_mutex_unlock(wxe_batch_locker_m); } else { if(sd) { @@ -207,60 +104,19 @@ void meta_command(int what, wxe_data *sd) { } } -/* ************************************************************ - * wxWidgets Thread - * ************************************************************/ - -void *wxe_main_loop(void *vpdl) -{ - int result; - int argc = 1; - char * temp = (char *) "Erlang"; - char * argv[] = {temp,NULL}; - ErlDrvPDL pdl = (ErlDrvPDL) vpdl; - - driver_pdl_inc_refc(pdl); - - // Disable floating point execption if they are on. - // This should be done in emulator but it's not in yet. -#ifndef _WIN32 - erts_thread_disable_fpe(); -#else - // Setup that wxWidgets should look for cursors and icons in - // this dll and not in werl.exe (which is the default) - HMODULE WXEHandle = GetModuleHandle(_T("wxe_driver")); - wxSetInstance((HINSTANCE) WXEHandle); -#endif - - wxe_ps_init(); - result = wxEntry(argc, argv); - // fprintf(stderr, "WXWidgets quits main loop %d \r\n", result); - if(result >= 0 && wxe_status == WXE_INITIATED) { - /* We are done try to make a clean exit */ - wxe_status = WXE_EXITED; - driver_pdl_dec_refc(pdl); -#ifndef __DARWIN__ - erl_drv_thread_exit(NULL); -#endif - return NULL; - } else { - erl_drv_mutex_lock(wxe_status_m); - wxe_status = WXE_ERROR; - erl_drv_cond_signal(wxe_status_c); - erl_drv_mutex_unlock(wxe_status_m); - driver_pdl_dec_refc(pdl); - return NULL; - } -} - -void WxeApp::dummy_close(wxEvent& Ev) { - // fprintf(stderr, "Dummy Close invoked\r\n"); - // wxMac really wants a top level window which command-q quits if there are no - // windows open, and this will kill the erlang, override default handling +void send_msg(const char * type, wxString * msg) { + wxeReturn rt = wxeReturn(WXE_DRV_PORT, init_caller); + rt.addAtom((char *) "wxe_driver"); + rt.addAtom((char *) type); + rt.add(msg); + rt.addTupleCount(3); + rt.send(); } +/* ************************************************************ + * Init WxeApp the application emulator + * ************************************************************/ -// Init wx-widgets thread bool WxeApp::OnInit() { @@ -268,6 +124,9 @@ bool WxeApp::OnInit() wxe_batch = new wxList; wxe_batch_cb_saved = new wxList; cb_buff = NULL; + recurse_level = 0; + delayed_cleanup = new wxList; + delayed_delete = new wxList; wxe_ps_init2(); // wxIdleEvent::SetMode(wxIDLE_PROCESS_SPECIFIED); // Hmm printpreview doesn't work in 2.9 with this @@ -305,13 +164,16 @@ void WxeApp::shutdown(wxeMetaCommand& Ecmd) { ExitMainLoop(); } -void send_msg(const char * type, wxString * msg) { - wxeReturn rt = wxeReturn(WXE_DRV_PORT, init_caller); - rt.addAtom((char *) "wxe_driver"); - rt.addAtom((char *) type); - rt.add(msg); - rt.addTupleCount(3); - rt.send(); +void WxeApp::dummy_close(wxEvent& Ev) { + // fprintf(stderr, "Dummy Close invoked\r\n"); + // wxMac really wants a top level window which command-q quits if there are no + // windows open, and this will kill the erlang, override default handling +} + +// Called by wx thread +void WxeApp::idle(wxIdleEvent& event) { + event.Skip(true); + dispatch_cmds(); } /* ************************************************************ @@ -328,29 +190,51 @@ void handle_event_callback(ErlDrvPort port, ErlDrvTermData process) { WxeApp * app = (WxeApp *) wxTheApp; ErlDrvMonitor monitor; - driver_monitor_process(port, process, &monitor); - // Should we be able to handle commands when recursing? probably - erl_drv_mutex_lock(wxe_batch_locker_m); - //fprintf(stderr, "\r\nCB EV Start %lu \r\n", process);fflush(stderr); - app->dispatch_cb(wxe_batch, wxe_batch_cb_saved, process); - //fprintf(stderr, "CB EV done %lu \r\n", process);fflush(stderr); - wxe_batch_caller = 0; - erl_drv_mutex_unlock(wxe_batch_locker_m); - driver_demonitor_process(port, &monitor); -} - -// Called by wx thread -void WxeApp::idle(wxIdleEvent& event) { - event.Skip(true); - dispatch_cmds(); + // Is thread safe if pdl have been incremented + if(driver_monitor_process(port, process, &monitor) == 0) { + // Should we be able to handle commands when recursing? probably + erl_drv_mutex_lock(wxe_batch_locker_m); + //fprintf(stderr, "\r\nCB EV Start %lu \r\n", process);fflush(stderr); + app->recurse_level++; + app->dispatch_cb(wxe_batch, wxe_batch_cb_saved, process); + app->recurse_level--; + //fprintf(stderr, "CB EV done %lu \r\n", process);fflush(stderr); + wxe_batch_caller = 0; + erl_drv_mutex_unlock(wxe_batch_locker_m); + driver_demonitor_process(port, &monitor); + } } -void WxeApp::dispatch_cmds() { +void WxeApp::dispatch_cmds() +{ erl_drv_mutex_lock(wxe_batch_locker_m); + recurse_level++; int level = dispatch(wxe_batch_cb_saved, 0, WXE_STORED); dispatch(wxe_batch, level, WXE_NORMAL); + recurse_level--; wxe_batch_caller = 0; erl_drv_mutex_unlock(wxe_batch_locker_m); + // Cleanup old memenv's and deleted objects + if(recurse_level == 0) { + if(delayed_delete->size() > 0) + for( wxList::compatibility_iterator node = delayed_delete->GetFirst(); + node; + node = delayed_delete->GetFirst()) { + wxeCommand *event = (wxeCommand *)node->GetData(); + delayed_delete->Erase(node); + wxe_dispatch(*event); + event->Delete(); + } + if(delayed_cleanup->size() > 0) + for( wxList::compatibility_iterator node = delayed_cleanup->GetFirst(); + node; + node = delayed_cleanup->GetFirst()) { + wxeMetaCommand *event = (wxeMetaCommand *)node->GetData(); + delayed_cleanup->Erase(node); + destroyMemEnv(*event); + delete event; + } + } } // Should have erl_drv_mutex_lock(wxe_batch_locker_m); @@ -402,7 +286,7 @@ int WxeApp::dispatch(wxList * batch, int blevel, int list_type) erl_drv_mutex_lock(wxe_batch_locker_m); break; } - delete event; + event->Delete(); } } else { if((list_type == WXE_STORED) || (blevel <= 0 && list_type == WXE_NORMAL)) { @@ -434,6 +318,7 @@ void WxeApp::dispatch_cb(wxList * batch, wxList * temp, ErlDrvTermData process) // fprintf(stderr, " Ev %d %lu\r\n", event->op, event->caller); if(event->caller == process || // Callbacks from CB process only event->op == WXE_CB_START || // Event callback start change process + event->op == WXE_CB_DIED || // Event callback process died // Allow connect_cb during CB i.e. msg from wxe_server. (memenv && event->caller == memenv->owner)) { @@ -446,7 +331,8 @@ void WxeApp::dispatch_cb(wxList * batch, wxList * temp, ErlDrvTermData process) if(event->len > 0) { cb_buff = (char *) driver_alloc(event->len); memcpy(cb_buff, event->buffer, event->len); - } + } // continue + case WXE_CB_DIED: callback_returned = 1; return; case WXE_CB_START: @@ -481,7 +367,7 @@ void WxeApp::dispatch_cb(wxList * batch, wxList * temp, ErlDrvTermData process) return; break; } - delete event; + event->Delete(); } else { // fprintf(stderr, " save %d \r\n", event->op); temp->Append(event); @@ -518,7 +404,8 @@ void WxeApp::newMemEnv(wxeMetaCommand& Ecmd) { erl_drv_send_term(WXE_DRV_PORT,Ecmd.caller,rt,2); } -void WxeApp::destroyMemEnv(wxeMetaCommand& Ecmd) { +void WxeApp::destroyMemEnv(wxeMetaCommand& Ecmd) +{ // Clear incoming cmd queue first // dispatch_cmds(); wxWindow *parent = NULL; @@ -537,26 +424,33 @@ void WxeApp::destroyMemEnv(wxeMetaCommand& Ecmd) { ptrMap::iterator it = ptr2ref.find(ptr); if(it != ptr2ref.end()) { wxeRefData *refd = it->second; - if(refd->alloc_in_erl) { - if(refd->type == 2) { - wxDialog *win = (wxDialog *) ptr; - if(win->IsModal()) { - win->EndModal(-1); - } - parent = win->GetParent(); - if(parent) { - ptrMap::iterator parentRef = ptr2ref.find(parent); - if(parentRef == ptr2ref.end()) { - // The parent is already dead delete the parent ref - win->SetParent(NULL); - } + if(refd->alloc_in_erl && refd->type == 2) { + wxDialog *win = (wxDialog *) ptr; + if(win->IsModal()) { + win->EndModal(-1); + } + parent = win->GetParent(); + if(parent) { + ptrMap::iterator parentRef = ptr2ref.find(parent); + if(parentRef == ptr2ref.end()) { + // The parent is already dead delete the parent ref + win->SetParent(NULL); } + } + if(recurse_level > 0) { + // Delay delete until we are out of dispatch* + delayed_cleanup->Append(Ecmd.Clone()); + } else { delete win; } } } } } + + if(recurse_level > 0) + return; + // First pass, delete all top parents/windows of all linked objects // fprintf(stderr, "close port %x\r\n", Ecmd.port);fflush(stderr); @@ -781,161 +675,3 @@ void WxeApp::registerPid(char * bp, ErlDrvTermData pid, wxeMemEnv * memenv) { }; throw wxe_badarg(index); } - - -/* ************************************************************ - * Misc utility classes - * ************************************************************/ - -/* **************************************************************************** - * Memory handling - * ****************************************************************************/ - -wxeMemEnv::wxeMemEnv() { - ref2ptr = (void **) driver_alloc(128*sizeof(void *)); - ref2ptr[0] = NULL; - next = 1; - max = 128; -} - -wxeMemEnv::~wxeMemEnv() { - driver_free(ref2ptr); -} - -/* **************************************************************************** - * Erlang Commands (don't need to be derived of wxEvent anymore should - * be re-written to own class struct) - * ****************************************************************************/ - -wxeCommand::wxeCommand(int fc,char * cbuf,int buflen, wxe_data *sd) - : wxObject() -{ - WXEBinRef *temp, *start, *prev; - int n = 0; - caller = driver_caller(sd->port_handle); - port = sd->port; - op = fc; - len = buflen; - bin[0] = NULL; - bin[1] = NULL; - bin[2] = NULL; - - if(cbuf) { - buffer = (char *) driver_alloc(len); - memcpy((void *) buffer, (void *) cbuf, len);; - - temp = sd->bin; - - prev = NULL; - start = temp; - - while(temp) { - if(caller == temp->from) { - bin[n++] = temp; - if(prev) { - prev->next = temp->next; - } else { - start = temp->next; - } - temp = temp->next; - } else { - prev = temp; - temp = temp->next; - } - } - sd->bin = start; - } else { // No-op only PING currently - buffer = NULL; - } -} - -wxeCommand::~wxeCommand() { - int n = 0; - if(buffer) { - while(bin[n]) { - if(bin[n]->bin) - driver_free_binary(bin[n]->bin); - driver_free(bin[n++]); - } - driver_free(buffer); - } -} - -/* **************************************************************************** - * TreeItemData - * ****************************************************************************/ - -wxETreeItemData::wxETreeItemData(int sz, char * data) { - size = sz; - bin = (char *) driver_alloc(sz); - memcpy(bin, data, sz); -} - -wxETreeItemData::~wxETreeItemData() -{ - driver_free(bin); -} - -/* **************************************************************************** - * CallbackData * - * ****************************************************************************/ - -wxeCallbackData::wxeCallbackData(ErlDrvTermData caller, int req, char *req_type, - int funcb, int skip_ev, wxeErlTerm * userData, - wxeEvtListener *handler_cb) - : wxObject() -{ - listener = caller; - obj = req; - fun_id = funcb; - strcpy(class_name, req_type); - skip = skip_ev; - user_data = userData; - handler = handler_cb; -} - -wxeCallbackData::~wxeCallbackData() { - // fprintf(stderr, "CBD Deleteing %p %s\r\n", this, class_name); fflush(stderr); - if(user_data) { - delete user_data; - } - ptrMap::iterator it; - it = ((WxeApp *)wxTheApp)->ptr2ref.find(handler); - if(it != ((WxeApp *)wxTheApp)->ptr2ref.end()) { - wxeRefData *refd = it->second; - wxeReturn rt = wxeReturn(WXE_DRV_PORT, refd->memenv->owner, false); - rt.addAtom("wx_delete_cb"); - rt.addInt(fun_id); - rt.addRef(refd->ref, "wxeEvtListener"); - rt.addRef(obj, class_name); - rt.addTupleCount(4); - rt.send(); - } -} - -/* **************************************************************************** - * wxListCtrlCompare wrapper - * ****************************************************************************/ - -int wxCALLBACK wxEListCtrlCompare(long item1, long item2, long callbackInfoPtr) -{ - callbackInfo * cb = (callbackInfo *)callbackInfoPtr; - wxeMemEnv * memenv = ((WxeApp *) wxTheApp)->getMemEnv(cb->port); - wxeReturn rt = wxeReturn(WXE_DRV_PORT, memenv->owner, false); - rt.addInt(cb->callbackID); - rt.addInt(item1); - rt.addInt(item2); - rt.endList(2); - rt.addAtom("_wx_invoke_cb_"); - rt.addTupleCount(3); - rt.send(); - handle_event_callback(WXE_DRV_PORT_HANDLE, memenv->owner); - - if(((WxeApp *) wxTheApp)->cb_buff) { - int res = * (int*) ((WxeApp *) wxTheApp)->cb_buff; - driver_free(((WxeApp *) wxTheApp)->cb_buff); - ((WxeApp *) wxTheApp)->cb_buff = NULL; - return res; - } - return 0; -} diff --git a/lib/wx/c_src/wxe_impl.h b/lib/wx/c_src/wxe_impl.h index a3c57e2598..bb54961edd 100644 --- a/lib/wx/c_src/wxe_impl.h +++ b/lib/wx/c_src/wxe_impl.h @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2008-2013. All Rights Reserved. + * Copyright Ericsson AB 2008-2014. All Rights Reserved. * * The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in @@ -14,12 +14,17 @@ * the License for the specific language governing rights and limitations * under the License. * - * %CopyrightEnd% + * %CopyrightEnd% */ #ifndef _WXE_IMPL_H #define _WXE_IMPL_H +#if defined(__APPLE__) && defined(__MACH__) && !defined(__DARWIN__) +#define __DARWIN__ 1 +#endif + + #include <wx/glcanvas.h> #include <wx/treectrl.h> #include <wx/print.h> @@ -27,119 +32,16 @@ extern "C" { #include "wxe_driver.h" } -DECLARE_EVENT_TYPE(wxeEVT_META_COMMAND, -1) - -class wxeMetaCommand : public wxEvent -{ - public: - wxeMetaCommand(wxe_data *sd, int EvId) - : wxEvent(EvId, wxeEVT_META_COMMAND) - { caller = driver_caller(sd->port_handle); port = sd->port; pdl = sd->pdl; } ; - wxeMetaCommand(const wxeMetaCommand& event) - : wxEvent(event) - { caller = event.caller; port = event.port; pdl = event.pdl; }; - virtual ~wxeMetaCommand() {}; - virtual wxEvent *Clone() const { return new wxeMetaCommand(*this); } - - ErlDrvTermData caller; - ErlDrvTermData port; - ErlDrvPDL pdl; -}; - -class wxeCommand : public wxObject -{ - public: - wxeCommand(int fc,char * cbuf,int buflen, wxe_data *); - virtual ~wxeCommand(); - - ErlDrvTermData caller; - ErlDrvTermData port; - WXEBinRef * bin[3]; - char * buffer; - int len; - int op; -}; - -#define WXE_EVENT_PTR 0 -#define WXE_OBJECT_PTR 1 - -class intListElement { -public: - intListElement(int Element) {car = Element; cdr = NULL;}; - intListElement(int Element, intListElement *list) - {car = Element; cdr = list;}; - int car; - intListElement *cdr; -}; - -class intList { -public: - intList() {list = NULL;}; - bool IsEmpty() {return list == NULL;}; - void Append(int Element) { list = new intListElement(Element, list); }; - int Pop() { - intListElement *temp = list; - int res = list->car; - list = temp->cdr; - delete temp; - return res; - } - intListElement *list; -}; - -class wxe_badarg -{ -public: - wxe_badarg(int Ref) : ref(Ref) { } ; - int ref; -}; - -class wxeErlTerm : public wxClientData -{ - public: - wxeErlTerm(WXEBinRef * data) - { - size = data->size; - bin = (char *) driver_alloc(size); - memcpy(bin, data->base, size); - } ; - ~wxeErlTerm() { driver_free(bin); }; - char * bin; - int size; -}; - -class wxeMemEnv -{ -public: - wxeMemEnv(); - int next; - int max; - void ** ref2ptr; - intList free; - ~wxeMemEnv(); - ErlDrvTermData owner; -}; - -class wxeRefData { - public: - wxeRefData(unsigned int dref, int ttype, int is_new, wxeMemEnv *menv) : - ref(dref), type(ttype), alloc_in_erl(is_new), memenv(menv), pid(-1) { } ; - int ref; - int type; - // 0 = wxWindow subclasses, 1 = wxObject subclasses - // 2 = wxDialog subclasses, 3 = allocated wxObjects but not returned from new - // > 3 classes which lack virtual destr, or are supposed to be allocated on - // the stack - bool alloc_in_erl; - wxeMemEnv *memenv; - ErlDrvTermData pid; -}; - -WX_DECLARE_HASH_MAP(ErlDrvTermData, wxGLCanvas*, wxIntegerHash, wxIntegerEqual, wxeGLC); -WX_DECLARE_HASH_MAP(ErlDrvTermData, wxeMemEnv*, wxIntegerHash, wxIntegerEqual, wxeMemMap); +#include "wxe_helpers.h" +#include "wxe_callback_impl.h" +#include "wxe_memory.h" +#define WXE_NOT_INITIATED 0 +#define WXE_INITIATED 1 +#define WXE_EXITED 2 +#define WXE_ERROR -1 -WX_DECLARE_VOIDPTR_HASH_MAP(wxeRefData *, ptrMap); +void send_msg(const char *, wxString *); // For debugging and error msgs class WxeApp : public wxApp { @@ -158,101 +60,31 @@ public: void dummy_close(wxEvent& Ev); bool sendevent(wxEvent *event); - // MemEnv handling + // MemEnv handling void newMemEnv(wxeMetaCommand& event); void destroyMemEnv(wxeMetaCommand& event); wxeMemEnv * getMemEnv(ErlDrvTermData port); - + int newPtr(void * ptr, int type, wxeMemEnv *memenv); int getRef(void * ptr, wxeMemEnv *memenv); - void * getPtr(char * bp, wxeMemEnv *memenv); + void * getPtr(char * bp, wxeMemEnv *memenv); void clearPtr(void *ptr); void registerPid(char *ptr, ErlDrvTermData pid, wxeMemEnv *memenv); - void init_nonconsts(wxeMemEnv *memenv, ErlDrvTermData caller); - + void init_nonconsts(wxeMemEnv *memenv, ErlDrvTermData caller); + // Code found in gen/wxe_derived_dest.h void delete_object(void *ptr, wxeRefData *refd); - + wxeMemMap refmap; ptrMap ptr2ref; wxeMemEnv * global_me; - + + int recurse_level; + wxList * delayed_cleanup; + wxList * delayed_delete; // Temp container for callbacks char *cb_buff; int cb_len; }; -class wxETreeItemData : public wxTreeItemData -{ - public: - wxETreeItemData(int sz, char * data); - - ~wxETreeItemData(); - - int size; - char * bin; -}; - -bool sendevent(wxEvent * event, ErlDrvTermData port); -void pre_callback(); -void handle_event_callback(ErlDrvPort port, ErlDrvTermData process); - -void activateGL(ErlDrvTermData caller); -void setActiveGL(ErlDrvTermData caller, wxGLCanvas *canvas); -void deleteActiveGL(wxGLCanvas *canvas); - -void send_msg(const char *, wxString *); // For debugging and error msgs - -extern wxeGLC glc; - -class wxEPrintout : public wxPrintout -{ - public: - wxEPrintout(wxString Title, int onPrintP, int onPrepareP, - int onBeginP, int onEndP, - int onBeginD, int onEndD, - int hasP, int getPageI, ErlDrvTermData Port) : - wxPrintout(Title), - onPrintPage(onPrintP), onPreparePrinting(onPrepareP), - onBeginPrinting(onBeginP), onEndPrinting(onEndP), - onBeginDocument(onBeginD), onEndDocument(onEndD), hasPage(hasP), getPageInfo(getPageI), - port(Port) - { } ; - - ~wxEPrintout(); - - bool OnBeginDocument(int startPage, int endPage); - void OnEndDocument(); - void OnBeginPrinting(); - void OnEndPrinting(); - - void OnPreparePrinting(); - - bool HasPage(int page); - bool OnPrintPage(int page); - void GetPageInfo(int *minPage, int *maxPage, int *pageFrom, int *pageTo); - - int onPrintPage; - int onPreparePrinting; - int onBeginPrinting; - int onEndPrinting; - int onBeginDocument; - int onEndDocument; - int hasPage; - int getPageInfo; - - ErlDrvTermData port; -}; - -void clear_cb(ErlDrvTermData port, int callback); - - -// Implementation of wxListCtrlCompare -struct callbackInfo { - ErlDrvTermData port; - int callbackID; -}; - -int wxCALLBACK wxEListCtrlCompare(long item1, long item2, long callbackInfoPtr); - #endif //_WXE_IMPL_H diff --git a/lib/wx/c_src/wxe_main.cpp b/lib/wx/c_src/wxe_main.cpp new file mode 100644 index 0000000000..2bec2422c9 --- /dev/null +++ b/lib/wx/c_src/wxe_main.cpp @@ -0,0 +1,163 @@ +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 2014. All Rights Reserved. + * + * The contents of this file are subject to the Erlang Public License, + * Version 1.1, (the "License"); you may not use this file except in + * compliance with the License. You should have received a copy of the + * Erlang Public License along with this software. If not, it can be + * retrieved online at http://www.erlang.org/. + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * %CopyrightEnd% + */ + +#if defined(_WIN32) +#include <wx/msw/private.h> // for wxSetInstance +#endif + +#include "wxe_impl.h" + +// Until fixed in emulator +#ifndef _WIN32 +extern "C" { + extern void erts_thread_disable_fpe(void); +} +#endif + +ErlDrvTid wxe_thread; + +ErlDrvMutex *wxe_status_m; +ErlDrvCond *wxe_status_c; + +int wxe_status = WXE_NOT_INITIATED; + +ErlDrvMutex * wxe_batch_locker_m; +ErlDrvCond * wxe_batch_locker_c; +ErlDrvTermData init_caller = 0; + +#ifdef __DARWIN__ +extern "C" { + int erl_drv_stolen_main_thread_join(ErlDrvTid tid, void **respp); + int erl_drv_steal_main_thread(char *name, + ErlDrvTid *dtid, + void* (*func)(void*), + void* arg, + ErlDrvThreadOpts *opts); +} +#endif + +void *wxe_main_loop(void * ); + +/* ************************************************************ + * START AND STOP of driver thread + * ************************************************************/ + +int load_native_gui() +{ + return 1; +} + +int start_native_gui(wxe_data *sd) +{ + int res; + wxe_status_m = erl_drv_mutex_create((char *) "wxe_status_m"); + wxe_status_c = erl_drv_cond_create((char *)"wxe_status_c"); + + wxe_batch_locker_m = erl_drv_mutex_create((char *)"wxe_batch_locker_m"); + wxe_batch_locker_c = erl_drv_cond_create((char *)"wxe_batch_locker_c"); + init_caller = driver_connected(sd->port_handle); + +#ifdef __DARWIN__ + res = erl_drv_steal_main_thread((char *)"wxwidgets", + &wxe_thread,wxe_main_loop,(void *) sd->pdl,NULL); +#else + res = erl_drv_thread_create((char *)"wxwidgets", + &wxe_thread,wxe_main_loop,(void *) sd->pdl,NULL); +#endif + if(res == 0) { + erl_drv_mutex_lock(wxe_status_m); + for(;wxe_status == WXE_NOT_INITIATED;) { + erl_drv_cond_wait(wxe_status_c, wxe_status_m); + } + erl_drv_mutex_unlock(wxe_status_m); + return wxe_status; + } else { + wxString msg; + msg.Printf(wxT("Erlang failed to create wxe-thread %d\r\n"), res); + send_msg("error", &msg); + return -1; + } +} + +void stop_native_gui(wxe_data *sd) +{ + if(wxe_status == WXE_INITIATED) { + meta_command(WXE_SHUTDOWN, sd); + } +#ifdef __DARWIN__ + erl_drv_stolen_main_thread_join(wxe_thread, NULL); +#else + erl_drv_thread_join(wxe_thread, NULL); +#endif + erl_drv_mutex_destroy(wxe_status_m); + erl_drv_cond_destroy(wxe_status_c); + erl_drv_mutex_destroy(wxe_batch_locker_m); + erl_drv_cond_destroy(wxe_batch_locker_c); +} + +void unload_native_gui() +{ + +} + +/* ************************************************************ + * wxWidgets Thread + * ************************************************************/ + +void *wxe_main_loop(void *vpdl) +{ + int result; + int argc = 1; + char * temp = (char *) "Erlang"; + char * argv[] = {temp,NULL}; + ErlDrvPDL pdl = (ErlDrvPDL) vpdl; + + driver_pdl_inc_refc(pdl); + + // Disable floating point execption if they are on. + // This should be done in emulator but it's not in yet. +#ifndef _WIN32 + erts_thread_disable_fpe(); +#else + // Setup that wxWidgets should look for cursors and icons in + // this dll and not in werl.exe (which is the default) + HMODULE WXEHandle = GetModuleHandle(_T("wxe_driver")); + wxSetInstance((HINSTANCE) WXEHandle); +#endif + + wxe_ps_init(); + result = wxEntry(argc, argv); + // fprintf(stderr, "WXWidgets quits main loop %d \r\n", result); + if(result >= 0 && wxe_status == WXE_INITIATED) { + /* We are done try to make a clean exit */ + wxe_status = WXE_EXITED; + driver_pdl_dec_refc(pdl); +#ifndef __DARWIN__ + erl_drv_thread_exit(NULL); +#endif + return NULL; + } else { + erl_drv_mutex_lock(wxe_status_m); + wxe_status = WXE_ERROR; + erl_drv_cond_signal(wxe_status_c); + erl_drv_mutex_unlock(wxe_status_m); + driver_pdl_dec_refc(pdl); + return NULL; + } +} diff --git a/lib/wx/c_src/wxe_memory.h b/lib/wx/c_src/wxe_memory.h new file mode 100644 index 0000000000..ec22183bfa --- /dev/null +++ b/lib/wx/c_src/wxe_memory.h @@ -0,0 +1,61 @@ +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 2014. All Rights Reserved. + * + * The contents of this file are subject to the Erlang Public License, + * Version 1.1, (the "License"); you may not use this file except in + * compliance with the License. You should have received a copy of the + * Erlang Public License along with this software. If not, it can be + * retrieved online at http://www.erlang.org/. + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * %CopyrightEnd% + */ + +#ifndef _WXE_MEMORY_H +#define _WXE_MEMORY_H + +class wxeMemEnv +{ +public: + wxeMemEnv() + { + ref2ptr = (void **) driver_alloc(128*sizeof(void *)); + ref2ptr[0] = NULL; + next = 1; + max = 128; + }; + ~wxeMemEnv() + { driver_free(ref2ptr); }; + int next; + int max; + void ** ref2ptr; + intList free; + ErlDrvTermData owner; +}; + +class wxeRefData { + public: + wxeRefData(unsigned int dref, int ttype, int is_new, wxeMemEnv *menv) : + ref(dref), type(ttype), alloc_in_erl(is_new), memenv(menv), pid(-1) { } ; + int ref; + int type; + // 0 = wxWindow subclasses, 1 = wxObject subclasses + // 2 = wxDialog subclasses, 3 = allocated wxObjects but not returned from new + // > 3 classes which lack virtual destr, or are supposed to be allocated on + // the stack + bool alloc_in_erl; + wxeMemEnv *memenv; + ErlDrvTermData pid; +}; + +WX_DECLARE_HASH_MAP(ErlDrvTermData, wxeMemEnv*, wxIntegerHash, wxIntegerEqual, wxeMemMap); + +WX_DECLARE_VOIDPTR_HASH_MAP(wxeRefData *, ptrMap); + +#endif |