diff options
author | Dan Gudmundsson <[email protected]> | 2014-01-21 15:57:57 +0100 |
---|---|---|
committer | Dan Gudmundsson <[email protected]> | 2014-01-21 15:57:57 +0100 |
commit | 31172443bfc849b879385d7ee0d2ea8019c32307 (patch) | |
tree | a66e29fe08d3bccc85a9b1a4cefdbb0f2edfceed | |
parent | 744984833cc1a51f51781e3417db7f152eeab4ae (diff) | |
parent | 51e369a1b90490e69a358d8c8f0bb9bfbf9f511c (diff) | |
download | otp-31172443bfc849b879385d7ee0d2ea8019c32307.tar.gz otp-31172443bfc849b879385d7ee0d2ea8019c32307.tar.bz2 otp-31172443bfc849b879385d7ee0d2ea8019c32307.zip |
Merge branch 'dgud/wx/more-fixes/OTP-11444' into maint
* dgud/wx/more-fixes/OTP-11444:
wx: Fix hanging wx calls
Update wx build instsructions for Darwin
wx: Remove compiler option -fomit-frame-pointer on Darwin
wx: Fix crash when garbage collect event handlers (debugger caused seg fault)
wx: Fix LDFLAGS for Mac
-rw-r--r-- | HOWTO/INSTALL.md | 20 | ||||
-rw-r--r-- | lib/wx/api_gen/wx_gen_cpp.erl | 34 | ||||
-rw-r--r-- | lib/wx/c_src/gen/wxe_derived_dest.h | 6 | ||||
-rw-r--r-- | lib/wx/c_src/gen/wxe_funcs.cpp | 8 | ||||
-rw-r--r-- | lib/wx/c_src/wxe_impl.cpp | 5 | ||||
-rwxr-xr-x | lib/wx/configure.in | 16 | ||||
-rw-r--r-- | lib/wx/test/wx_basic_SUITE.erl | 13 | ||||
-rw-r--r-- | lib/wx/test/wx_event_SUITE.erl | 33 | ||||
-rw-r--r-- | lib/wx/test/wx_obj_test.erl | 72 |
9 files changed, 124 insertions, 83 deletions
diff --git a/HOWTO/INSTALL.md b/HOWTO/INSTALL.md index 07a8db1a53..3dde37bfec 100644 --- a/HOWTO/INSTALL.md +++ b/HOWTO/INSTALL.md @@ -63,7 +63,7 @@ At Ericsson we have a "Daily Build and Test" that runs on: * x86 * OpenBSD 5.0 * x86\_64 -* Mac OS X 10.5.8 (Leopard), 10.6.0 (Snow Leopard), 10.7.3 (Lion) +* Mac OS X 10.5.8 (Leopard), 10.7.3 (Lion), 10.9 (Mavericks) * x86 * Windows XP SP3, 2003, Vista, 7 * x86 @@ -703,17 +703,18 @@ Install MacPorts (<http://www.macports.org/>). Then: ### Building with wxErlang ### -If you want to build the `wx` application, you will need to get wxWidgets-2.9.4 (or later) -(`wxWidgets-2.9.4.tar.bz2` from <http://sourceforge.net/projects/wxwindows/files/2.9.4/>) +If you want to build the `wx` application, you will need to get wxWidgets-3.0 (or later) +(`wxWidgets-3.0.0.tar.bz2` from <http://sourceforge.net/projects/wxwindows/files/3.0.0/>) or get it from github: $ git clone [email protected]:wxWidgets/wxWidgets.git -Be aware that the wxWidgets-2.9 branch is a development branch of wxWidgets and the MacOsX -port still lags behind the other ports. +Be aware that the wxWidgets-3.0 is a new release of wxWidgets, it is not as matured +as the old releases and the MacOsX port still lags behind the other ports. -Configure and build wxMac: +Configure and build wxWidgets: - $ ./configure --with-cocoa --prefix=/usr/local + $ ./configure --with-cocoa --prefix=/usr/local + % Optional version and static libs: --with-macosx-version-min=10.9 --disable-shared $ make $ sudo make install $ export PATH=/usr/local/bin:$PATH @@ -724,12 +725,11 @@ Check that you got the correct wx-config ### Finish up ### -Build Erlang with the MacPorts GCC as the main compiler (using `clang` -for the Objective-C Cocoa code in the `wx` application): +Build Erlang $ export PATH=/usr/local/bin:$PATH $ cd $ERL_TOP - $ CC=/opt/local/bin/gcc-mp-4.5 CXX=/opt/local/bin/g++-mp-4.5 ./configure --enable-darwin-64bit + $ ./configure --enable-shared-zlib $ make $ sudo make install diff --git a/lib/wx/api_gen/wx_gen_cpp.erl b/lib/wx/api_gen/wx_gen_cpp.erl index 7e35ebfa83..6eed0668f6 100644 --- a/lib/wx/api_gen/wx_gen_cpp.erl +++ b/lib/wx/api_gen/wx_gen_cpp.erl @@ -855,34 +855,24 @@ call_arg(#param{name=N,type={merged,_,_,_,_,_,_}}) -> N. to_string(Type) when is_atom(Type) -> atom_to_list(Type); to_string(Type) when is_list(Type) -> Type. -virtual_dest(#class{abstract=true, parent="root"}) -> false; -virtual_dest(#class{abstract=true, parent="object"}) -> true; virtual_dest(#class{abstract=true, parent=Parent}) -> - virtual_dest(get({class,Parent})); + virtual_dest(get_parent_class(Parent)); virtual_dest(#class{methods=Ms, parent=Parent}) -> case lists:keysearch(destructor,#method.method_type, lists:append(Ms)) of {value, #method{method_type=destructor, virtual=Virtual}} -> case Virtual of - undefined -> - case get({class,Parent}) of - undefined -> - case Parent of - "object" -> - true; - "root" -> - false; - _ -> - io:format("Error: ~p~n",[Parent]), - erlang:error(no_parent) - end; - PClass -> - virtual_dest(PClass) - end; - _ -> - Virtual + true -> true; + _ -> virtual_dest(get_parent_class(Parent)) end; - false -> - false + false -> virtual_dest(get_parent_class(Parent)) + end; +virtual_dest("root") -> false; +virtual_dest("object") -> true. + +get_parent_class(Parent) -> + case get({class, Parent}) of + undefined -> Parent; + Class -> Class end. debug(F,A) -> 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_funcs.cpp b/lib/wx/c_src/gen/wxe_funcs.cpp index b5fbac3fe0..329af36f4d 100644 --- a/lib/wx/c_src/gen/wxe_funcs.cpp +++ b/lib/wx/c_src/gen/wxe_funcs.cpp @@ -26953,14 +26953,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/wxe_impl.cpp b/lib/wx/c_src/wxe_impl.cpp index 4968075659..cc9bcc9957 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 @@ -195,9 +195,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) { diff --git a/lib/wx/configure.in b/lib/wx/configure.in index 12b4de6fe6..3756786831 100755 --- a/lib/wx/configure.in +++ b/lib/wx/configure.in @@ -183,7 +183,7 @@ AC_SUBST(OBJC_CFLAGS) case $host_os in darwin*) - LDFLAGS="-bundle -flat_namespace -undefined warning -fPIC $LDFLAGS" + LDFLAGS="$MAC_MIN -bundle -flat_namespace -undefined warning -fPIC $LDFLAGS" # Check sizof_void_p as future will hold 64bit MacOS wx if test $ac_cv_sizeof_void_p = 4; then LDFLAGS="-m32 $LDFLAGS" @@ -211,20 +211,20 @@ dnl ---------------------------------------------------------------------- case $host_os in mingw32) DEBUG_CFLAGS="-g -Wall -DDEBUG $CFLAGS" - CFLAGS="-g -Wall -O2 -fomit-frame-pointer -fno-strict-aliasing $CFLAGS" + CFLAGS="-g -Wall -O2 $CFLAGS -fomit-frame-pointer -fno-strict-aliasing" ;; win32) - DEBUG_CFLAGS="-g -Wall -DDEBUG $CFLAGS" + DEBUG_CFLAGS="-g -Wall $CFLAGS -DDEBUG" CFLAGS="-g -Wall -O2 $CFLAGS" ;; darwin*) - DEBUG_CFLAGS="-g -Wall -fPIC -DDEBUG $CFLAGS" - # Disable -02 crashes with xcode 5.0.2 (clang-500.2.79) - CFLAGS="-g -Wall -fPIC -fomit-frame-pointer -fno-strict-aliasing $CFLAGS" + DEBUG_CFLAGS="-g -Wall -fPIC $CFLAGS -DDEBUG" + # omit-frame-pointer causes seg faults with 10.9 and clang + CFLAGS="-g -Wall -fPIC $CFLAGS -fno-strict-aliasing" ;; *) - DEBUG_CFLAGS="-g -Wall -fPIC -DDEBUG $CFLAGS" - CFLAGS="-g -Wall -O2 -fPIC -fomit-frame-pointer -fno-strict-aliasing $CFLAGS" + DEBUG_CFLAGS="-g -Wall -fPIC $CFLAGS -DDEBUG" + CFLAGS="-g -Wall -O2 -fPIC $CFLAGS -fomit-frame-pointer -fno-strict-aliasing" ;; esac diff --git a/lib/wx/test/wx_basic_SUITE.erl b/lib/wx/test/wx_basic_SUITE.erl index d55a037599..c5b0927bf3 100644 --- a/lib/wx/test/wx_basic_SUITE.erl +++ b/lib/wx/test/wx_basic_SUITE.erl @@ -324,7 +324,18 @@ data_types(_Config) -> wx_object(TestInfo) when is_atom(TestInfo) -> wx_test_lib:tc_info(TestInfo); wx_object(Config) -> wx:new(), - Frame = ?mt(wxFrame, wx_obj_test:start([])), + Me = self(), + Init = fun() -> + Frame = wxFrame:new(wx:null(), ?wxID_ANY, "Test wx_object", [{size, {500, 400}}]), + Sz = wxBoxSizer:new(?wxHORIZONTAL), + Panel = wxPanel:new(Frame), + wxSizer:add(Sz, Panel, [{flag, ?wxEXPAND}, {proportion, 1}]), + wxPanel:connect(Panel, size, [{skip, true}]), + wxPanel:connect(Panel, paint, [callback, {userData, Me}]), + wxWindow:show(Frame), + {Frame, {Frame, Panel}} + end, + Frame = ?mt(wxFrame, wx_obj_test:start([{init, Init}])), timer:sleep(500), ?m(ok, check_events(flush())), diff --git a/lib/wx/test/wx_event_SUITE.erl b/lib/wx/test/wx_event_SUITE.erl index 6a9f19ad51..bbb5294d08 100644 --- a/lib/wx/test/wx_event_SUITE.erl +++ b/lib/wx/test/wx_event_SUITE.erl @@ -484,6 +484,7 @@ callback_clean(Config) -> %% timer:sleep(infinity), %% ok. + white_box_check_event_handlers() -> {_,_,Server,_} = wx:get_env(), {status, _, _, [Env, _, _, _, Data]} = sys:get_status(Server), @@ -495,3 +496,35 @@ white_box_check_event_handlers() -> gb_trees:to_list(CBs), [Funs || Funs = {Id, {Fun,_}} <- Env, is_integer(Id), is_function(Fun)] }. + +handler_clean(TestInfo) when is_atom(TestInfo) -> + wx_test_lib:tc_info(TestInfo); +handler_clean(_Config) -> + wx:new(), + Init = fun() -> create_window() end, + Frame1 = wx_obj_test:start([{init, Init}]), + ?mt(wxFrame, Frame1), + wxWindow:show(Frame1), + ?m([_|_], lists:sort(wx_test_lib:flush())), + ?m({stop,_}, wx_obj_test:stop(Frame1, fun(_) -> normal end)), + ?m([{terminate,normal}], lists:sort(wx_test_lib:flush())), + + Frame2 = wx_obj_test:start([{init, Init}]), + wxWindow:show(Frame2), + ?m([_|_], lists:sort(wx_test_lib:flush())), + ?m({stop,_}, wx_obj_test:stop(Frame2, fun(_) -> wxWindow:destroy(Frame2), normal end)), + ?m([{terminate,normal}], lists:sort(wx_test_lib:flush())), + timer:sleep(104), + ?m({[],[],[]}, white_box_check_event_handlers()), + ?m(ok, wx:destroy()), + ok. + +create_window() -> + Frame = wxFrame:new(wx:null(), ?wxID_ANY, "Test wx_object", [{size, {500, 400}}]), + Sz = wxBoxSizer:new(?wxHORIZONTAL), + Panel = wxPanel:new(Frame), + wxSizer:add(Sz, Panel, [{flag, ?wxEXPAND}, {proportion, 1}]), + wxWindow:connect(Frame, show), + %% wxPanel:connect(Panel, paint, [callback, {userData, foobar}]), + wxWindow:connect(Panel, size, [callback]), + {Frame, {Frame, Panel}}. diff --git a/lib/wx/test/wx_obj_test.erl b/lib/wx/test/wx_obj_test.erl index b4d7640c7e..f47f2fbc46 100644 --- a/lib/wx/test/wx_obj_test.erl +++ b/lib/wx/test/wx_obj_test.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2011. All Rights Reserved. +%% Copyright Ericsson AB 2011-2013. 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 @@ -18,69 +18,71 @@ -module(wx_obj_test). -include_lib("wx/include/wx.hrl"). --export([start/1]). +-export([start/1, stop/2]). %% wx_object callbacks -export([init/1, handle_info/2, terminate/2, code_change/3, handle_call/3, handle_sync_event/3, handle_event/2, handle_cast/2]). --record(state, {frame, panel, opts}). +-record(state, {parent, opts, user_state}). start(Opts) -> - wx_object:start_link(?MODULE, [{parent, self()}, Opts], []). + wx_object:start_link(?MODULE, [{parent, self()}| Opts], []). + +stop(Object, Fun) -> + wx_object:call(Object, {stop, Fun}). init(Opts) -> - put(parent_pid, proplists:get_value(parent, Opts)), - Frame = wxFrame:new(wx:null(), ?wxID_ANY, "Test wx_object", [{size, {500, 400}}]), - Sz = wxBoxSizer:new(?wxHORIZONTAL), - Panel = wxPanel:new(Frame), - wxSizer:add(Sz, Panel, [{flag, ?wxEXPAND}, {proportion, 1}]), - wxPanel:connect(Panel, size, [{skip, true}]), - wxPanel:connect(Panel, paint, [callback, {userData, proplists:get_value(parent, Opts)}]), - wxWindow:show(Frame), - {Frame, #state{frame=Frame, panel=Panel, opts=Opts}}. + Parent = proplists:get_value(parent, Opts), + put(parent_pid, Parent), + Init = proplists:get_value(init, Opts), + {Obj, UserState} = Init(), + {Obj, #state{parent=Parent, opts=Opts, user_state=UserState}}. -handle_sync_event(Event = #wx{obj=Panel}, WxEvent, #state{opts=Opts}) -> - DC=wxPaintDC:new(Panel), %% We must create & destroy paintDC, or call wxEvent:skip(WxEvent)) - wxPaintDC:destroy(DC), %% in sync_event. Otherwise wx on windows keeps sending the events. - Pid = proplists:get_value(parent, Opts), - true = is_pid(Pid), - Pid ! {sync_event, Event, WxEvent}, +handle_sync_event(Event = #wx{obj=Panel, event=#wxPaint{}}, + WxEvent, #state{parent=Parent, user_state=US, opts=Opts}) -> + case proplists:get_value(redraw, Opts) of + undefined -> + DC=wxPaintDC:new(Panel), %% We must create & destroy paintDC, or call wxEvent:skip(WxEvent)) + wxPaintDC:destroy(DC), %% in sync_event. Otherwise wx on windows keeps sending the events. + Parent ! {sync_event, Event, WxEvent}; + Redraw -> + Redraw(Event, WxEvent, US) + end, + ok; +handle_sync_event(Event, WxEvent, #state{parent=Parent}) -> + Parent ! {sync_event, Event, WxEvent}, ok. -handle_event(Event, State = #state{opts=Opts}) -> - Pid = proplists:get_value(parent, Opts), - Pid ! {event, Event}, +handle_event(Event, State = #state{parent=Parent}) -> + Parent ! {event, Event}, {noreply, State}. -handle_call(What, From, State) when is_function(What) -> - Result = What(State), +handle_call(What, From, State = #state{user_state=US}) when is_function(What) -> + Result = What(US), {reply, {call, Result, From}, State}; +handle_call({stop, Fun}, From, State = #state{user_state=US}) -> + {stop, Fun(US), {stop, From}, State}; handle_call(What, From, State) -> {reply, {call, What, From}, State}. -handle_cast(What, State = #state{opts=Opts}) when is_function(What) -> - Result = What(State), - Pid = proplists:get_value(parent, Opts), +handle_cast(What, State = #state{parent=Pid, user_state=US}) when is_function(What) -> + Result = What(US), Pid ! {cast, Result}, {noreply, State}; -handle_cast(What, State = #state{opts=Opts}) -> - Pid = proplists:get_value(parent, Opts), +handle_cast(What, State = #state{parent=Pid}) -> Pid ! {cast, What}, {noreply, State}. -handle_info(What, State = #state{opts=Opts}) -> - Pid = proplists:get_value(parent, Opts), +handle_info(What, State = #state{parent=Pid}) -> Pid ! {info, What}, {noreply, State}. -terminate(What, #state{opts=Opts}) -> - Pid = proplists:get_value(parent, Opts), +terminate(What, #state{parent=Pid}) -> Pid ! {terminate, What}, ok. -code_change(Ver1, Ver2, State = #state{opts=Opts}) -> - Pid = proplists:get_value(parent, Opts), +code_change(Ver1, Ver2, State = #state{parent=Pid}) -> Pid ! {code_change, Ver1, Ver2}, State. |