aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Gudmundsson <[email protected]>2014-01-21 15:57:57 +0100
committerDan Gudmundsson <[email protected]>2014-01-21 15:57:57 +0100
commit31172443bfc849b879385d7ee0d2ea8019c32307 (patch)
treea66e29fe08d3bccc85a9b1a4cefdbb0f2edfceed
parent744984833cc1a51f51781e3417db7f152eeab4ae (diff)
parent51e369a1b90490e69a358d8c8f0bb9bfbf9f511c (diff)
downloadotp-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.md20
-rw-r--r--lib/wx/api_gen/wx_gen_cpp.erl34
-rw-r--r--lib/wx/c_src/gen/wxe_derived_dest.h6
-rw-r--r--lib/wx/c_src/gen/wxe_funcs.cpp8
-rw-r--r--lib/wx/c_src/wxe_impl.cpp5
-rwxr-xr-xlib/wx/configure.in16
-rw-r--r--lib/wx/test/wx_basic_SUITE.erl13
-rw-r--r--lib/wx/test/wx_event_SUITE.erl33
-rw-r--r--lib/wx/test/wx_obj_test.erl72
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.