From 3f9b80b1e635f3b5f39bd7380b3bd777ebd98338 Mon Sep 17 00:00:00 2001 From: Dan Gudmundsson Date: Tue, 10 Dec 2013 15:08:41 +0100 Subject: wx: Fix LDFLAGS for Mac MacOSX min version must be applied to LDFLAGS otherwise linking with static wxWidgets libraries doesn't work. --- lib/wx/configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/wx') diff --git a/lib/wx/configure.in b/lib/wx/configure.in index 12b4de6fe6..2842db07c0 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" -- cgit v1.2.3 From 74f6d6d74f7a3be5aece37a0b419e40d96e036d4 Mon Sep 17 00:00:00 2001 From: Dan Gudmundsson Date: Fri, 20 Dec 2013 09:20:22 +0100 Subject: wx: Fix crash when garbage collect event handlers (debugger caused seg fault) wxStyledTextCtrl had no wrapper class so, because it was not detected that it had virtual destructors, thus references to it was not cleaned up on destruction. When a process dies and wx cleans up the event handlers access was made to the deleted object and caused a seg fault. Added a testcase which I thought could provoke the bug but didn't. --- lib/wx/api_gen/wx_gen_cpp.erl | 34 +++++++----------- lib/wx/c_src/gen/wxe_derived_dest.h | 6 ++++ lib/wx/c_src/gen/wxe_funcs.cpp | 8 ++--- lib/wx/test/wx_basic_SUITE.erl | 13 ++++++- lib/wx/test/wx_event_SUITE.erl | 33 +++++++++++++++++ lib/wx/test/wx_obj_test.erl | 72 +++++++++++++++++++------------------ 6 files changed, 104 insertions(+), 62 deletions(-) (limited to 'lib/wx') 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/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. -- cgit v1.2.3 From adf86abf64e25085785a65ed85a917251a301d94 Mon Sep 17 00:00:00 2001 From: Dan Gudmundsson Date: Wed, 15 Jan 2014 12:32:31 +0100 Subject: wx: Remove compiler option -fomit-frame-pointer on Darwin Causes a segfault when building on 10.9 with -mmacosx-version-min=10.9 --- lib/wx/configure.in | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'lib/wx') diff --git a/lib/wx/configure.in b/lib/wx/configure.in index 2842db07c0..3756786831 100755 --- a/lib/wx/configure.in +++ b/lib/wx/configure.in @@ -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 -- cgit v1.2.3 From 51e369a1b90490e69a358d8c8f0bb9bfbf9f511c Mon Sep 17 00:00:00 2001 From: Dan Gudmundsson Date: Thu, 16 Jan 2014 16:20:35 +0100 Subject: wx: Fix hanging wx calls wxWakeUpIdle doesn't always work on wxGTK and the workaround is to periodically invoke it, so the gui-thread doesn't get stuck in poll. Previously it was only called when NOT in batch mode, however if the wxWakeUpIdle call after a batch_begin command did not wake up the thread it would still get stuck in poll. --- lib/wx/c_src/wxe_impl.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'lib/wx') 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) { -- cgit v1.2.3