aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bootstrap/lib/kernel/ebin/dist_util.beambin10664 -> 11220 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet6_tcp_dist.beambin768 -> 872 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet_tcp_dist.beambin7216 -> 7616 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/net_kernel.beambin22980 -> 24856 bytes
-rw-r--r--bootstrap/lib/kernel/include/dist_util.hrl8
-rw-r--r--erts/emulator/beam/erl_bif_info.c7
-rw-r--r--lib/kernel/doc/src/inet.xml9
-rw-r--r--lib/kernel/doc/src/kernel_app.xml2
-rw-r--r--lib/kernel/doc/src/net_kernel.xml36
-rw-r--r--lib/kernel/include/dist_util.hrl8
-rw-r--r--lib/kernel/src/dist_util.erl71
-rw-r--r--lib/kernel/src/inet.erl1
-rw-r--r--lib/kernel/src/inet6_tcp_dist.erl7
-rw-r--r--lib/kernel/src/inet_tcp_dist.erl27
-rw-r--r--lib/kernel/src/net_kernel.erl128
-rw-r--r--lib/kernel/test/erl_distribution_SUITE.erl163
-rw-r--r--lib/wx/api_gen/wx_extra/wxListCtrl.erl62
-rw-r--r--lib/wx/api_gen/wx_extra/wxXmlResource.erl6
-rw-r--r--lib/wx/c_src/wxe_main.cpp6
-rw-r--r--lib/wx/include/wx.hrl434
-rw-r--r--lib/wx/src/gen/wxListCtrl.erl62
-rw-r--r--lib/wx/src/gen/wxXmlResource.erl6
-rw-r--r--lib/wx/src/wx_object.erl84
23 files changed, 769 insertions, 358 deletions
diff --git a/bootstrap/lib/kernel/ebin/dist_util.beam b/bootstrap/lib/kernel/ebin/dist_util.beam
index e5d0f66e6e..bf3572fe23 100644
--- a/bootstrap/lib/kernel/ebin/dist_util.beam
+++ b/bootstrap/lib/kernel/ebin/dist_util.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/inet6_tcp_dist.beam b/bootstrap/lib/kernel/ebin/inet6_tcp_dist.beam
index 1be1dc1c57..98f70db13c 100644
--- a/bootstrap/lib/kernel/ebin/inet6_tcp_dist.beam
+++ b/bootstrap/lib/kernel/ebin/inet6_tcp_dist.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/inet_tcp_dist.beam b/bootstrap/lib/kernel/ebin/inet_tcp_dist.beam
index 5fd6b3e909..087274e89d 100644
--- a/bootstrap/lib/kernel/ebin/inet_tcp_dist.beam
+++ b/bootstrap/lib/kernel/ebin/inet_tcp_dist.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/net_kernel.beam b/bootstrap/lib/kernel/ebin/net_kernel.beam
index 6cf6916fe6..1197b4f681 100644
--- a/bootstrap/lib/kernel/ebin/net_kernel.beam
+++ b/bootstrap/lib/kernel/ebin/net_kernel.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/include/dist_util.hrl b/bootstrap/lib/kernel/include/dist_util.hrl
index 43e50d4325..320e916c04 100644
--- a/bootstrap/lib/kernel/include/dist_util.hrl
+++ b/bootstrap/lib/kernel/include/dist_util.hrl
@@ -63,7 +63,7 @@
f_getll, %% Get low level port or pid.
f_address, %% The address of the "socket",
%% generated from Socket,Node
- %% These two are used in the tick loop,
+ %% These three are used in the tick loop,
%% so they are not fun's to avoid holding old code.
mf_tick, %% Takes the socket as parameters and
%% sends a tick, this is no fun, it
@@ -74,7 +74,11 @@
%% {ok, RecvCnt, SendCnt, SendPend} for
%% a given socket. This is a {M,F},
%% returning {error, Reason on failure}
- request_type = normal
+ request_type = normal,
+
+ %% New in kernel-5.1 (OTP 19.1):
+ mf_setopts, %% netkernel:setopts on active connection
+ mf_getopts %% netkernel:getopts on active connection
}).
diff --git a/erts/emulator/beam/erl_bif_info.c b/erts/emulator/beam/erl_bif_info.c
index 3fb866733c..6cedf3c8a5 100644
--- a/erts/emulator/beam/erl_bif_info.c
+++ b/erts/emulator/beam/erl_bif_info.c
@@ -2284,9 +2284,7 @@ BIF_RETTYPE system_info_1(BIF_ALIST_1)
} else if (ERTS_IS_ATOM_STR("dist_ctrl", BIF_ARG_1)) {
DistEntry *dep;
i = 0;
- /* Need to be the only thread running... */
- erts_smp_proc_unlock(BIF_P, ERTS_PROC_LOCK_MAIN);
- erts_smp_thr_progress_block();
+ erts_smp_rwmtx_rlock(&erts_dist_table_rwmtx);
for (dep = erts_visible_dist_entries; dep; dep = dep->next)
++i;
for (dep = erts_hidden_dist_entries; dep; dep = dep->next)
@@ -2309,8 +2307,7 @@ BIF_RETTYPE system_info_1(BIF_ALIST_1)
res = CONS(hp, tpl, res);
hp += 2;
}
- erts_smp_thr_progress_unblock();
- erts_smp_proc_lock(BIF_P, ERTS_PROC_LOCK_MAIN);
+ erts_smp_rwmtx_runlock(&erts_dist_table_rwmtx);
BIF_RET(res);
} else if (BIF_ARG_1 == am_system_version) {
erts_dsprintf_buf_t *dsbufp = erts_create_tmp_dsbuf(0);
diff --git a/lib/kernel/doc/src/inet.xml b/lib/kernel/doc/src/inet.xml
index c0dce2f50c..8cc21bf3e2 100644
--- a/lib/kernel/doc/src/inet.xml
+++ b/lib/kernel/doc/src/inet.xml
@@ -151,6 +151,12 @@ fe80::204:acff:fe17:bf38
<name name="socket_address"/>
</datatype>
<datatype>
+ <name name="socket_getopt"/>
+ </datatype>
+ <datatype>
+ <name name="socket_setopt"/>
+ </datatype>
+ <datatype>
<name name="returned_non_ip_address"/>
<desc>
<p>
@@ -327,8 +333,6 @@ fe80::204:acff:fe17:bf38
<func>
<name name="getopts" arity="2"/>
<fsummary>Get one or more options for a socket.</fsummary>
- <type name="socket_getopt"/>
- <type name="socket_setopt"/>
<desc>
<p>Gets one or more options for a socket. For a list of available
options, see
@@ -580,7 +584,6 @@ get_tcpi_sacked(Sock) ->
<func>
<name name="setopts" arity="2"/>
<fsummary>Set one or more options for a socket.</fsummary>
- <type name="socket_setopt"/>
<desc>
<p>Sets one or more options for a socket.</p>
<p>The following options are available:</p>
diff --git a/lib/kernel/doc/src/kernel_app.xml b/lib/kernel/doc/src/kernel_app.xml
index 9e6fb60bb7..dc0291babe 100644
--- a/lib/kernel/doc/src/kernel_app.xml
+++ b/lib/kernel/doc/src/kernel_app.xml
@@ -215,12 +215,14 @@
<p>Defines the <c>First..Last</c> port range for the listener
socket of a distributed Erlang node.</p>
</item>
+ <marker id="inet_dist_listen_options"></marker>
<tag><c>{inet_dist_listen_options, Opts}</c></tag>
<item>
<p>Defines a list of extra socket options to be used when opening the
listening socket for a distributed Erlang node.
See <seealso marker="gen_tcp#listen/2"><c>gen_tcp:listen/2</c></seealso>.</p>
</item>
+ <marker id="inet_dist_connect_options"></marker>
<tag><c>{inet_dist_connect_options, Opts}</c></tag>
<item>
<p>Defines a list of extra socket options to be used when connecting to
diff --git a/lib/kernel/doc/src/net_kernel.xml b/lib/kernel/doc/src/net_kernel.xml
index f48a534d4f..3c1b3d5190 100644
--- a/lib/kernel/doc/src/net_kernel.xml
+++ b/lib/kernel/doc/src/net_kernel.xml
@@ -116,6 +116,21 @@ $ <input>erl -sname foobar</input></pre>
</func>
<func>
+ <name name="getopts" arity="2"/>
+ <fsummary>Get distribution socket options.</fsummary>
+ <desc>
+ <p>Get one or more options for the distribution socket
+ connected to <c><anno>Node</anno></c>.</p>
+ <p>If <c><anno>Node</anno></c> is a connected node
+ the return value is the same as from
+ <seealso marker="inet#getopts/2"><c>inet:getopts(Sock, Options)</c></seealso>
+ where <c>Sock</c> is the distribution socket for <c><anno>Node</anno></c>.</p>
+ <p>Returns <c>ignored</c> if the local node is not alive or
+ <c>{error, noconnection}</c> if <c><anno>Node</anno></c> is not connected.</p>
+ </desc>
+ </func>
+
+ <func>
<name name="monitor_nodes" arity="1"/>
<name name="monitor_nodes" arity="2"/>
<fsummary>Subscribe to node status change messages.</fsummary>
@@ -289,6 +304,27 @@ $ <input>erl -sname foobar</input></pre>
</func>
<func>
+ <name name="setopts" arity="2"/>
+ <fsummary>Set distribution socket options.</fsummary>
+ <desc>
+ <p>Set one or more options for distribution sockets.
+ Argument <c><anno>Node</anno></c> can be either one node name
+ or the atom <c>new</c> to affect the distribution sockets of all
+ future connected nodes.</p>
+ <p>The return value is the same as from
+ <seealso marker="inet#setopts/2"><c>inet:setopts/2</c></seealso>
+ or <c>{error, noconnection}</c> if <c><anno>Node</anno></c> is not
+ a connected node or <c>new</c>.</p>
+ <p>If <c><anno>Node</anno></c> is <c>new</c> the <c><anno>Options</anno></c>
+ will then also be added to kernel configration parameters
+ <seealso marker="kernel:kernel_app#inet_dist_listen_options">inet_dist_listen_options</seealso>
+ and
+ <seealso marker="kernel:kernel_app#inet_dist_connect_options">inet_dist_connect_options</seealso>.</p>
+ <p>Returns <c>ignored</c> if the local node is not alive.</p>
+ </desc>
+ </func>
+
+ <func>
<name>start([Name]) -> {ok, pid()} | {error, Reason}</name>
<name>start([Name, NameType]) -> {ok, pid()} | {error, Reason}</name>
<name>start([Name, NameType, Ticktime]) -> {ok, pid()} | {error, Reason}</name>
diff --git a/lib/kernel/include/dist_util.hrl b/lib/kernel/include/dist_util.hrl
index 43e50d4325..320e916c04 100644
--- a/lib/kernel/include/dist_util.hrl
+++ b/lib/kernel/include/dist_util.hrl
@@ -63,7 +63,7 @@
f_getll, %% Get low level port or pid.
f_address, %% The address of the "socket",
%% generated from Socket,Node
- %% These two are used in the tick loop,
+ %% These three are used in the tick loop,
%% so they are not fun's to avoid holding old code.
mf_tick, %% Takes the socket as parameters and
%% sends a tick, this is no fun, it
@@ -74,7 +74,11 @@
%% {ok, RecvCnt, SendCnt, SendPend} for
%% a given socket. This is a {M,F},
%% returning {error, Reason on failure}
- request_type = normal
+ request_type = normal,
+
+ %% New in kernel-5.1 (OTP 19.1):
+ mf_setopts, %% netkernel:setopts on active connection
+ mf_getopts %% netkernel:getopts on active connection
}).
diff --git a/lib/kernel/src/dist_util.erl b/lib/kernel/src/dist_util.erl
index 47d0c1b861..8d2fc4d4b7 100644
--- a/lib/kernel/src/dist_util.erl
+++ b/lib/kernel/src/dist_util.erl
@@ -143,7 +143,11 @@ handshake_other_started(#hs_data{request_type=ReqType}=HSData0) ->
ChallengeB = recv_challenge_reply(HSData, ChallengeA, MyCookie),
send_challenge_ack(HSData, gen_digest(ChallengeB, HisCookie)),
?debug({dist_util, self(), accept_connection, Node}),
- connection(HSData).
+ connection(HSData);
+
+handshake_other_started(OldHsData) when element(1,OldHsData) =:= hs_data ->
+ handshake_other_started(convert_old_hsdata(OldHsData)).
+
%%
%% check if connecting node is allowed to connect
@@ -330,7 +334,20 @@ handshake_we_started(#hs_data{request_type=ReqType,
gen_digest(ChallengeA,HisCookie)),
reset_timer(NewHSData#hs_data.timer),
recv_challenge_ack(NewHSData, MyChallenge, MyCookie),
- connection(NewHSData).
+ connection(NewHSData);
+
+handshake_we_started(OldHsData) when element(1,OldHsData) =:= hs_data ->
+ handshake_we_started(convert_old_hsdata(OldHsData)).
+
+convert_old_hsdata({hs_data, KP, ON, TN, S, T, TF, A, OV, OF, OS, FS, FR,
+ FS_PRE, FS_POST, FG, FA, MFT, MFG, RT}) ->
+ #hs_data{
+ kernel_pid = KP, other_node = ON, this_node = TN, socket = S, timer = T,
+ this_flags = TF, allowed = A, other_version = OV, other_flags = OF,
+ other_started = OS, f_send = FS, f_recv = FR, f_setopts_pre_nodeup = FS_PRE,
+ f_setopts_post_nodeup = FS_POST, f_getll = FG, f_address = FA,
+ mf_tick = MFT, mf_getstat = MFG, request_type = RT}.
+
%% --------------------------------------------------------------
%% The connection has been established.
@@ -350,15 +367,15 @@ connection(#hs_data{other_node = Node,
mark_nodeup(HSData,Address),
case FPostNodeup(Socket) of
ok ->
- con_loop(HSData#hs_data.kernel_pid,
- Node,
- Socket,
- Address,
- HSData#hs_data.this_node,
- PType,
- #tick{},
- HSData#hs_data.mf_tick,
- HSData#hs_data.mf_getstat);
+ con_loop({HSData#hs_data.kernel_pid,
+ Node,
+ Socket,
+ PType,
+ HSData#hs_data.mf_tick,
+ HSData#hs_data.mf_getstat,
+ HSData#hs_data.mf_setopts,
+ HSData#hs_data.mf_getopts},
+ #tick{});
_ ->
?shutdown2(Node, connection_setup_failed)
end;
@@ -454,8 +471,8 @@ mark_nodeup(#hs_data{kernel_pid = Kernel,
?shutdown(Node)
end.
-con_loop(Kernel, Node, Socket, TcpAddress,
- MyNode, Type, Tick, MFTick, MFGetstat) ->
+con_loop({Kernel, Node, Socket, Type, MFTick, MFGetstat, MFSetOpts, MFGetOpts}=ConData,
+ Tick) ->
receive
{tcp_closed, Socket} ->
?shutdown2(Node, connection_closed);
@@ -468,15 +485,12 @@ con_loop(Kernel, Node, Socket, TcpAddress,
_ ->
ignore_it
end,
- con_loop(Kernel, Node, Socket, TcpAddress, MyNode, Type,
- Tick, MFTick, MFGetstat);
+ con_loop(ConData, Tick);
{Kernel, tick} ->
case send_tick(Socket, Tick, Type,
MFTick, MFGetstat) of
{ok, NewTick} ->
- con_loop(Kernel, Node, Socket, TcpAddress,
- MyNode, Type, NewTick, MFTick,
- MFGetstat);
+ con_loop(ConData, NewTick);
{error, not_responding} ->
error_msg("** Node ~p not responding **~n"
"** Removing (timedout) connection **~n",
@@ -489,13 +503,24 @@ con_loop(Kernel, Node, Socket, TcpAddress,
case MFGetstat(Socket) of
{ok, Read, Write, _} ->
From ! {self(), get_status, {ok, Read, Write}},
- con_loop(Kernel, Node, Socket, TcpAddress,
- MyNode,
- Type, Tick,
- MFTick, MFGetstat);
+ con_loop(ConData, Tick);
_ ->
?shutdown2(Node, get_status_failed)
- end
+ end;
+ {From, Ref, {setopts, Opts}} ->
+ Ret = case MFSetOpts of
+ undefined -> {error, enotsup};
+ _ -> MFSetOpts(Socket, Opts)
+ end,
+ From ! {Ref, Ret},
+ con_loop(ConData, Tick);
+ {From, Ref, {getopts, Opts}} ->
+ Ret = case MFGetOpts of
+ undefined -> {error, enotsup};
+ _ -> MFGetOpts(Socket, Opts)
+ end,
+ From ! {Ref, Ret},
+ con_loop(ConData, Tick)
end.
diff --git a/lib/kernel/src/inet.erl b/lib/kernel/src/inet.erl
index a91a6ed517..75dd800c6b 100644
--- a/lib/kernel/src/inet.erl
+++ b/lib/kernel/src/inet.erl
@@ -75,6 +75,7 @@
-export_type([address_family/0, hostent/0, hostname/0, ip4_address/0,
ip6_address/0, ip_address/0, port_number/0,
local_address/0, socket_address/0, returned_non_ip_address/0,
+ socket_setopt/0, socket_getopt/0,
posix/0, socket/0, stat_option/0]).
%% imports
-import(lists, [append/1, duplicate/2, filter/2, foldl/3]).
diff --git a/lib/kernel/src/inet6_tcp_dist.erl b/lib/kernel/src/inet6_tcp_dist.erl
index 3aa61973af..9b6c2745d5 100644
--- a/lib/kernel/src/inet6_tcp_dist.erl
+++ b/lib/kernel/src/inet6_tcp_dist.erl
@@ -24,6 +24,7 @@
-export([listen/1, accept/1, accept_connection/5,
setup/5, close/1, select/1, is_node_name/1]).
+-export([setopts/2, getopts/2]).
%% ------------------------------------------------------------
%% Select this protocol based on node name
@@ -72,3 +73,9 @@ close(Socket) ->
is_node_name(Node) when is_atom(Node) ->
inet_tcp_dist:is_node_name(Node).
+
+setopts(S, Opts) ->
+ inet_tcp_dist:setopts(S, Opts).
+
+getopts(S, Opts) ->
+ inet_tcp_dist:getopts(S, Opts).
diff --git a/lib/kernel/src/inet_tcp_dist.erl b/lib/kernel/src/inet_tcp_dist.erl
index 94bde55133..3084bd599a 100644
--- a/lib/kernel/src/inet_tcp_dist.erl
+++ b/lib/kernel/src/inet_tcp_dist.erl
@@ -24,13 +24,16 @@
-export([listen/1, accept/1, accept_connection/5,
setup/5, close/1, select/1, is_node_name/1]).
+%% Optional
+-export([setopts/2, getopts/2]).
+
%% Generalized dist API
-export([gen_listen/2, gen_accept/2, gen_accept_connection/6,
gen_setup/6, gen_select/2]).
%% internal exports
--export([accept_loop/3,do_accept/7,do_setup/7,getstat/1]).
+-export([accept_loop/3,do_accept/7,do_setup/7,getstat/1,tick/2]).
-import(error_logger,[error_msg/2]).
@@ -215,8 +218,10 @@ do_accept(Driver, Kernel, AcceptPid, Socket, MyNode, Allowed, SetupTime) ->
inet:getll(S)
end,
f_address = fun(S, Node) -> get_remote_id(Driver, S, Node) end,
- mf_tick = fun(S) -> tick(Driver, S) end,
- mf_getstat = fun ?MODULE:getstat/1
+ mf_tick = fun(S) -> ?MODULE:tick(Driver, S) end,
+ mf_getstat = fun ?MODULE:getstat/1,
+ mf_setopts = fun ?MODULE:setopts/2,
+ mf_getopts = fun ?MODULE:getopts/2
},
dist_util:handshake_other_started(HSData);
{false,IP} ->
@@ -320,6 +325,7 @@ do_setup(Driver, Kernel, Node, Type, MyNode, LongOrShortNames, SetupTime) ->
{packet, 4},
nodelay()])
end,
+
f_getll = fun inet:getll/1,
f_address =
fun(_,_) ->
@@ -329,9 +335,11 @@ do_setup(Driver, Kernel, Node, Type, MyNode, LongOrShortNames, SetupTime) ->
protocol = tcp,
family = AddressFamily}
end,
- mf_tick = fun(S) -> tick(Driver, S) end,
+ mf_tick = fun(S) -> ?MODULE:tick(Driver, S) end,
mf_getstat = fun ?MODULE:getstat/1,
- request_type = Type
+ request_type = Type,
+ mf_setopts = fun ?MODULE:setopts/2,
+ mf_getopts = fun ?MODULE:getopts/2
},
dist_util:handshake_we_started(HSData);
_ ->
@@ -492,3 +500,12 @@ split_stat([], R, W, P) ->
{ok, R, W, P}.
+setopts(S, Opts) ->
+ case [Opt || {K,_}=Opt <- Opts,
+ K =:= active orelse K =:= deliver orelse K =:= packet] of
+ [] -> inet:setopts(S,Opts);
+ Opts1 -> {error, {badopts,Opts1}}
+ end.
+
+getopts(S, Opts) ->
+ inet:getopts(S, Opts).
diff --git a/lib/kernel/src/net_kernel.erl b/lib/kernel/src/net_kernel.erl
index ac19f4935b..0c679e7349 100644
--- a/lib/kernel/src/net_kernel.erl
+++ b/lib/kernel/src/net_kernel.erl
@@ -59,6 +59,8 @@
connect_node/1,
monitor_nodes/1,
monitor_nodes/2,
+ setopts/2,
+ getopts/2,
start/1,
stop/0]).
@@ -111,7 +113,7 @@
}).
-record(listen, {
- listen, %% listen pid
+ listen, %% listen socket
accept, %% accepting pid
address, %% #net_address
module %% proto module
@@ -384,7 +386,7 @@ init({Name, LongOrShortNames, TickT, CleanHalt}) ->
connections =
ets:new(sys_dist,[named_table,
protected,
- {keypos, 2}]),
+ {keypos, #connection.node}]),
listen = Listeners,
allowed = [],
verbose = 0
@@ -554,6 +556,38 @@ handle_call({new_ticktime,_T,_TP},
#state{tick = #tick_change{time = T}} = State) ->
async_reply({reply, {ongoing_change_to, T}, State}, From);
+handle_call({setopts, new, Opts}, From, State) ->
+ Ret = setopts_new(Opts, State),
+ async_reply({reply, Ret, State}, From);
+
+handle_call({setopts, Node, Opts}, From, State) ->
+ Return =
+ case ets:lookup(sys_dist, Node) of
+ [Conn] when Conn#connection.state =:= up ->
+ case call_owner(Conn#connection.owner, {setopts, Opts}) of
+ {ok, Ret} -> Ret;
+ _ -> {error, noconnection}
+ end;
+
+ _ ->
+ {error, noconnection}
+ end,
+ async_reply({reply, Return, State}, From);
+
+handle_call({getopts, Node, Opts}, From, State) ->
+ Return =
+ case ets:lookup(sys_dist, Node) of
+ [Conn] when Conn#connection.state =:= up ->
+ case call_owner(Conn#connection.owner, {getopts, Opts}) of
+ {ok, Ret} -> Ret;
+ _ -> {error, noconnection}
+ end;
+
+ _ ->
+ {error, noconnection}
+ end,
+ async_reply({reply, Return, State}, From);
+
handle_call(_Msg, _From, State) ->
{noreply, State}.
@@ -1608,3 +1642,93 @@ async_gen_server_reply(From, Msg) ->
{'EXIT', _} ->
ok
end.
+
+call_owner(Owner, Msg) ->
+ Mref = monitor(process, Owner),
+ Owner ! {self(), Mref, Msg},
+ receive
+ {Mref, Reply} ->
+ erlang:demonitor(Mref, [flush]),
+ {ok, Reply};
+ {'DOWN', Mref, _, _, _} ->
+ error
+ end.
+
+
+-spec setopts(Node, Options) -> ok | {error, Reason} | ignored when
+ Node :: node() | new,
+ Options :: [inet:socket_setopt()],
+ Reason :: inet:posix() | noconnection.
+
+setopts(Node, Opts) when is_atom(Node), is_list(Opts) ->
+ request({setopts, Node, Opts}).
+
+setopts_new(Opts, State) ->
+ %% First try setopts on listening socket(s)
+ %% Bail out on failure.
+ %% If successful, we are pretty sure Opts are ok
+ %% and we continue with config params and pending connections.
+ case setopts_on_listen(Opts, State#state.listen) of
+ ok ->
+ setopts_new_1(Opts);
+ Fail -> Fail
+ end.
+
+setopts_on_listen(_, []) -> ok;
+setopts_on_listen(Opts, [#listen {listen = LSocket, module = Mod} | T]) ->
+ try Mod:setopts(LSocket, Opts) of
+ ok ->
+ setopts_on_listen(Opts, T);
+ Fail -> Fail
+ catch
+ error:undef -> {error, enotsup}
+ end.
+
+setopts_new_1(Opts) ->
+ ConnectOpts = case application:get_env(kernel, inet_dist_connect_options) of
+ {ok, CO} -> CO;
+ _ -> []
+ end,
+ application:set_env(kernel, inet_dist_connect_options,
+ merge_opts(Opts,ConnectOpts)),
+ ListenOpts = case application:get_env(kernel, inet_dist_listen_options) of
+ {ok, LO} -> LO;
+ _ -> []
+ end,
+ application:set_env(kernel, inet_dist_listen_options,
+ merge_opts(Opts, ListenOpts)),
+ case lists:keyfind(nodelay, 1, Opts) of
+ {nodelay, ND} when is_boolean(ND) ->
+ application:set_env(kernel, dist_nodelay, ND);
+ _ -> ignore
+ end,
+
+ %% Update any pending connections
+ PendingConns = ets:select(sys_dist, [{'_',
+ [{'=/=',{element,#connection.state,'$_'},up}],
+ ['$_']}]),
+ lists:foreach(fun(#connection{state = pending, owner = Owner}) ->
+ call_owner(Owner, {setopts, Opts});
+ (#connection{state = up_pending, pending_owner = Owner}) ->
+ call_owner(Owner, {setopts, Opts});
+ (_) -> ignore
+ end, PendingConns),
+ ok.
+
+merge_opts([], B) ->
+ B;
+merge_opts([H|T], B0) ->
+ {Key, _} = H,
+ B1 = lists:filter(fun({K,_}) -> K =/= Key end, B0),
+ merge_opts(T, [H | B1]).
+
+-spec getopts(Node, Options) ->
+ {'ok', OptionValues} | {'error', Reason} | ignored when
+ Node :: node(),
+ Options :: [inet:socket_getopt()],
+ OptionValues :: [inet:socket_setopt()],
+ Reason :: inet:posix() | noconnection.
+
+getopts(Node, Opts) when is_atom(Node), is_list(Opts) ->
+ request({getopts, Node, Opts}).
+
diff --git a/lib/kernel/test/erl_distribution_SUITE.erl b/lib/kernel/test/erl_distribution_SUITE.erl
index eb58e92224..e43be77428 100644
--- a/lib/kernel/test/erl_distribution_SUITE.erl
+++ b/lib/kernel/test/erl_distribution_SUITE.erl
@@ -25,6 +25,7 @@
init_per_group/2,end_per_group/2]).
-export([tick/1, tick_change/1, illegal_nodenames/1, hidden_node/1,
+ setopts/1,
table_waste/1, net_setuptime/1,
inet_dist_options_options/1,
@@ -42,6 +43,8 @@
-export([get_socket_priorities/0,
tick_cli_test/1, tick_cli_test1/1,
tick_serv_test/2, tick_serv_test1/1,
+ run_remote_test/1,
+ setopts_do/2,
keep_conn/1, time_ping/1]).
-export([init_per_testcase/2, end_per_testcase/2]).
@@ -66,6 +69,7 @@ suite() ->
all() ->
[tick, tick_change, illegal_nodenames, hidden_node,
+ setopts,
table_waste, net_setuptime, inet_dist_options_options,
{group, monitor_nodes}].
@@ -282,6 +286,165 @@ tick_cli_test1(Node) ->
end
end.
+setopts(Config) when is_list(Config) ->
+ register(setopts_regname, self()),
+ [N1,N2,N3,N4] = get_nodenames(4, setopts),
+
+ {_N1F,Port1} = start_node_unconnected(N1, ?MODULE, run_remote_test,
+ ["setopts_do", atom_to_list(node()), "1", "ping"]),
+ 0 = wait_for_port_exit(Port1),
+
+ {_N2F,Port2} = start_node_unconnected(N2, ?MODULE, run_remote_test,
+ ["setopts_do", atom_to_list(node()), "2", "ping"]),
+ 0 = wait_for_port_exit(Port2),
+
+ {ok, LSock} = gen_tcp:listen(0, [{packet,2}, {active,false}]),
+ {ok, LTcpPort} = inet:port(LSock),
+
+ {N3F,Port3} = start_node_unconnected(N3, ?MODULE, run_remote_test,
+ ["setopts_do", atom_to_list(node()),
+ "1", integer_to_list(LTcpPort)]),
+ wait_and_connect(LSock, N3F, Port3),
+ 0 = wait_for_port_exit(Port3),
+
+ {N4F,Port4} = start_node_unconnected(N4, ?MODULE, run_remote_test,
+ ["setopts_do", atom_to_list(node()),
+ "2", integer_to_list(LTcpPort)]),
+ wait_and_connect(LSock, N4F, Port4),
+ 0 = wait_for_port_exit(Port4),
+
+ ok.
+
+wait_and_connect(LSock, NodeName, NodePort) ->
+ {ok, Sock} = gen_tcp:accept(LSock),
+ {ok, "Connect please"} = gen_tcp:recv(Sock, 0),
+ flush_from_port(NodePort),
+ pong = net_adm:ping(NodeName),
+ gen_tcp:send(Sock, "Connect done"),
+ gen_tcp:close(Sock).
+
+
+flush_from_port(Port) ->
+ flush_from_port(Port, 10).
+
+flush_from_port(Port, Timeout) ->
+ receive
+ {Port,{data,String}} ->
+ io:format("~p: ~s\n", [Port, String]),
+ flush_from_port(Port, Timeout)
+ after Timeout ->
+ timeout
+ end.
+
+wait_for_port_exit(Port) ->
+ case (receive M -> M end) of
+ {Port,{exit_status,Status}} ->
+ Status;
+ {Port,{data,String}} ->
+ io:format("~p: ~s\n", [Port, String]),
+ wait_for_port_exit(Port)
+ end.
+
+run_remote_test([FuncStr, TestNodeStr | Args]) ->
+ Status = try
+ io:format("Node ~p started~n", [node()]),
+ TestNode = list_to_atom(TestNodeStr),
+ io:format("Node ~p spawning function ~p~n", [node(), FuncStr]),
+ {Pid,Ref} = spawn_monitor(?MODULE, list_to_atom(FuncStr), [TestNode, Args]),
+ io:format("Node ~p waiting for function ~p~n", [node(), FuncStr]),
+ receive
+ {'DOWN', Ref, process, Pid, normal} ->
+ 0;
+ Other ->
+ io:format("Node ~p got unexpected msg: ~p\n",[node(), Other]),
+ 1
+ end
+ catch
+ C:E ->
+ io:format("Node ~p got EXCEPTION ~p:~p\nat ~p\n",
+ [node(), C, E, erlang:get_stacktrace()]),
+ 2
+ end,
+ io:format("Node ~p doing halt(~p).\n",[node(), Status]),
+ erlang:halt(Status).
+
+% Do the actual test on the remote node
+setopts_do(TestNode, [OptNr, ConnectData]) ->
+ [] = nodes(),
+ {Opt, Val} = opt_from_nr(OptNr),
+ ok = net_kernel:setopts(new, [{Opt, Val}]),
+
+ [] = nodes(),
+ {error, noconnection} = net_kernel:getopts(TestNode, [Opt]),
+
+ case ConnectData of
+ "ping" -> % We connect
+ net_adm:ping(TestNode);
+ TcpPort -> % Other connect
+ {ok, Sock} = gen_tcp:connect("localhost", list_to_integer(TcpPort),
+ [{active,false},{packet,2}]),
+ ok = gen_tcp:send(Sock, "Connect please"),
+ {ok, "Connect done"} = gen_tcp:recv(Sock, 0),
+ gen_tcp:close(Sock)
+ end,
+ [TestNode] = nodes(),
+ {ok, [{Opt,Val}]} = net_kernel:getopts(TestNode, [Opt]),
+ {error, noconnection} = net_kernel:getopts('pixie@fairyland', [Opt]),
+
+ NewVal = change_val(Val),
+ ok = net_kernel:setopts(TestNode, [{Opt, NewVal}]),
+ {ok, [{Opt,NewVal}]} = net_kernel:getopts(TestNode, [Opt]),
+
+ ok = net_kernel:setopts(TestNode, [{Opt, Val}]),
+ {ok, [{Opt,Val}]} = net_kernel:getopts(TestNode, [Opt]),
+
+ ok.
+
+opt_from_nr("1") -> {nodelay, true};
+opt_from_nr("2") -> {nodelay, false}.
+
+change_val(true) -> false;
+change_val(false) -> true.
+
+start_node_unconnected(Name, Mod, Func, Args) ->
+ FullName = full_node_name(Name),
+ CmdLine = mk_node_cmdline(Name,Mod,Func,Args),
+ io:format("Starting node ~p: ~s~n", [FullName, CmdLine]),
+ case open_port({spawn, CmdLine}, [exit_status]) of
+ Port when is_port(Port) ->
+ {FullName, Port};
+ Error ->
+ exit({failed_to_start_node, FullName, Error})
+ end.
+
+full_node_name(PreName) ->
+ HostSuffix = lists:dropwhile(fun ($@) -> false; (_) -> true end,
+ atom_to_list(node())),
+ list_to_atom(atom_to_list(PreName) ++ HostSuffix).
+
+mk_node_cmdline(Name,Mod,Func,Args) ->
+ Static = "-noinput",
+ Pa = filename:dirname(code:which(?MODULE)),
+ Prog = case catch init:get_argument(progname) of
+ {ok,[[P]]} -> P;
+ _ -> exit(no_progname_argument_found)
+ end,
+ NameSw = case net_kernel:longnames() of
+ false -> "-sname ";
+ true -> "-name ";
+ _ -> exit(not_distributed_node)
+ end,
+ {ok, Pwd} = file:get_cwd(),
+ NameStr = atom_to_list(Name),
+ Prog ++ " "
+ ++ Static ++ " "
+ ++ NameSw ++ " " ++ NameStr
+ ++ " -pa " ++ Pa
+ ++ " -env ERL_CRASH_DUMP " ++ Pwd ++ "/erl_crash_dump." ++ NameStr
+ ++ " -setcookie " ++ atom_to_list(erlang:get_cookie())
+ ++ " -run " ++ atom_to_list(Mod) ++ " " ++ atom_to_list(Func)
+ ++ " " ++ string:join(Args, " ").
+
%% OTP-4255.
tick_change(Config) when is_list(Config) ->
diff --git a/lib/wx/api_gen/wx_extra/wxListCtrl.erl b/lib/wx/api_gen/wx_extra/wxListCtrl.erl
index acdb69fdeb..355a4cdfd1 100644
--- a/lib/wx/api_gen/wx_extra/wxListCtrl.erl
+++ b/lib/wx/api_gen/wx_extra/wxListCtrl.erl
@@ -43,33 +43,36 @@ SortItems>>
<<EXPORT:wxListCtrl new/0, new/1, new/2 wxListCtrl:EXPORT>>
<<wxListCtrl_new_0
-%% @spec () -> wxListCtrl()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxlistctrl.html#wxlistctrlwxlistctrl">external documentation</a>.
+-spec new() -> wxListCtrl().
new() ->
wxe_util:construct(~s, <<>>).
wxListCtrl_new_0>>
<<wxListCtrl_new_2
-%% @spec (Parent::wxWindow:wxWindow()) -> wxListCtrl()
-%% @equiv new(Parent, [])
+-spec new(Parent) -> wxListCtrl() when
+ Parent::wxWindow:wxWindow().
new(Parent)
when is_record(Parent, wx_ref) ->
new(Parent, []).
-%% @spec (Parent::wxWindow:wxWindow(), [Option]) -> wxListCtrl()
-%% Option = {winid, integer()} |
-%% {pos, {X::integer(),Y::integer()}} |
-%% {size, {W::integer(),H::integer()}} |
-%% {style, integer()} |
-%% {validator, wx:wx()} |
-%% {onGetItemText, OnGetItemText} |
-%% {onGetItemAttr, OnGetItemAttr} |
-%% {onGetItemColumnImage, OnGetItemColumnImage}
+%% @doc Creates a listctrl with optional callback functions:
%%
-%% OnGetItemText = (This, Item, Column) -> wxString()
-%% OnGetItemAttr = (This, Item) -> wxListItemAttr()
+%% OnGetItemText = (This, Item, Column) -> unicode:charlist()
+%% OnGetItemAttr = (This, Item) -> wxListItemAttr:wxListItemAttr()
%% OnGetItemColumnImage = (This, Item, Column) -> integer()
-%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxlistctrl.html#wxlistctrlwxlistctrl">external documentation</a>.
+%%
+%% See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxlistctrl.html#wxlistctrlwxlistctrl">external documentation</a>.
+-spec new(Parent, [Option]) -> wxListCtrl() when
+ Parent::wxWindow:wxWindow(),
+ Option::{winid, integer()} |
+ {pos, {X::integer(),Y::integer()}} |
+ {size, {W::integer(),H::integer()}} |
+ {style, integer()} |
+ {validator, wx:wx_object()} |
+ {onGetItemText, function()} |
+ {onGetItemAttr, function()} |
+ {onGetItemColumnImage, function()}.
new(#wx_ref{type=ParentT,ref=ParentRef}, Options)
when is_list(Options)->
@@ -101,26 +104,27 @@ wxListCtrl_new_2>>
<<EXPORT:Create create/2, create/3 Create:EXPORT>>
<<Create
-%% @spec (This::wxListCtrl(), Parent::wxWindow:wxWindow()) -> bool()
%% @equiv create(This,Parent, [])
+-spec create(This, Parent) -> wxListCtrl() when
+ This::wxWindow:wxWindow(),
+ Parent::wxWindow:wxWindow().
create(This,Parent)
when is_record(This, wx_ref),is_record(Parent, wx_ref) ->
create(This,Parent, []).
-%% @spec (This::wxListCtrl(), Parent::wxWindow:wxWindow(), [Option]) -> bool()
-%% Option = {winid, integer()} |
-%% {pos, {X::integer(),Y::integer()}} |
-%% {size, {W::integer(),H::integer()}} |
-%% {style, integer()} |
-%% {validator, wx:wx()} |
-%% {onGetItemText, OnGetItemText} |
-%% {onGetItemAttr, OnGetItemAttr} |
-%% {onGetItemColumnImage, OnGetItemColumnImage}
-%%
-%% OnGetItemText = (This, Item, Column) -> wxString()
-%% OnGetItemAttr = (This, Item) -> wxListItemAttr()
-%% OnGetItemColumnImage = (This, Item, Column) -> integer()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxlistctrl.html#wxlistctrlcreate">external documentation</a>.
+-spec create(This, Parent, [Option]) -> wxListCtrl() when
+ This::wxWindow:wxWindow(),
+ Parent::wxWindow:wxWindow(),
+ Option::{winid, integer()} |
+ {pos, {X::integer(),Y::integer()}} |
+ {size, {W::integer(),H::integer()}} |
+ {style, integer()} |
+ {validator, wx:wx_object()} |
+ {onGetItemText, function()} |
+ {onGetItemAttr, function()} |
+ {onGetItemColumnImage, function()}.
+
create(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef}, Options)
when is_list(Options) ->
?CLASS(ThisT,wxListCtrl),
diff --git a/lib/wx/api_gen/wx_extra/wxXmlResource.erl b/lib/wx/api_gen/wx_extra/wxXmlResource.erl
index 7700e2333e..b29ffba7c6 100644
--- a/lib/wx/api_gen/wx_extra/wxXmlResource.erl
+++ b/lib/wx/api_gen/wx_extra/wxXmlResource.erl
@@ -21,8 +21,6 @@
<<EXPORT:xrcctrl xrcctrl/3 xrcctrl:EXPORT>>
<<xrcctrl
-%% @spec (Window::wxWindow:wxWindow(),Name::string(), Type::atom()) -> wx:wxObject()
-
%% @doc Looks up a control with Name in a window created with XML
%% resources. You can use it to set/get values from controls.
%% The object is type casted to <b>Type</b>.
@@ -32,6 +30,10 @@
%% true = wxXmlResource:loadDialog(Xrc, Dlg, Frame, "controls_dialog"), <br />
%% LCtrl = xrcctrl(Dlg, "controls_listctrl", wxListCtrl), <br />
%% wxListCtrl:insertColumn(LCtrl, 0, "Name", [{width, 200}]), <br />
+-spec xrcctrl(Window, Name, Type) -> wx:wx_object() when
+ Window::wxWindow:wxWindow(),
+ Name::string(),
+ Type::atom().
xrcctrl(Window = #wx_ref{}, Name, Type) when is_list(Name), is_atom(Type) ->
%% Func Id ~s
diff --git a/lib/wx/c_src/wxe_main.cpp b/lib/wx/c_src/wxe_main.cpp
index 6fcde42eb5..c7565e33bd 100644
--- a/lib/wx/c_src/wxe_main.cpp
+++ b/lib/wx/c_src/wxe_main.cpp
@@ -67,6 +67,7 @@ int load_native_gui()
int start_native_gui(wxe_data *sd)
{
int res;
+ ErlDrvThreadOpts *opts = NULL;
wxe_status_m = erl_drv_mutex_create((char *) "wxe_status_m");
wxe_status_c = erl_drv_cond_create((char *)"wxe_status_c");
@@ -78,8 +79,11 @@ int start_native_gui(wxe_data *sd)
res = erl_drv_steal_main_thread((char *)"wxwidgets",
&wxe_thread,wxe_main_loop,(void *) sd->pdl,NULL);
#else
+ opts = erl_drv_thread_opts_create((char *)"wx thread");
+ opts->suggested_stack_size = 8192;
res = erl_drv_thread_create((char *)"wxwidgets",
- &wxe_thread,wxe_main_loop,(void *) sd->pdl,NULL);
+ &wxe_thread,wxe_main_loop,(void *) sd->pdl,opts);
+ erl_drv_thread_opts_destroy(opts);
#endif
if(res == 0) {
erl_drv_mutex_lock(wxe_status_m);
diff --git a/lib/wx/include/wx.hrl b/lib/wx/include/wx.hrl
index af7cca7ed2..30baeebb18 100644
--- a/lib/wx/include/wx.hrl
+++ b/lib/wx/include/wx.hrl
@@ -33,94 +33,51 @@
%% Here comes the definitions of all event records.
%% they contain the event type and possible some extra information.
--record(wxInitDialog, {type :: wxInitDialogEventType()}). %% Callback event: {@link wxInitDialogEvent}
--type wxInitDialogEventType() :: 'init_dialog'.
--type wxInitDialog() :: #wxInitDialog{}. %% Callback event: {@link wxInitDialogEvent}
-
--record(wxClose, {type :: wxCloseEventType()}). %% Callback event: {@link wxCloseEvent}
--type wxCloseEventType() :: 'close_window' | 'end_session' | 'query_end_session'.
--type wxClose() :: #wxClose{}. %% Callback event: {@link wxCloseEvent}
-
--record(wxStyledText,{type :: wxStyledTextEventType(), %% Callback event: {@link wxStyledTextEvent}
- position :: integer(),
- key :: integer(),
- modifiers :: integer(),
- modificationType :: integer(),
- text :: unicode:chardata(),
- length :: integer(),
- linesAdded :: integer(),
- line :: integer(),
- foldLevelNow :: integer(),
- foldLevelPrev :: integer(),
- margin :: integer(),
- message :: integer(),
- wParam :: integer(),
- lParam :: integer(),
- listType :: integer(),
- x :: integer(),
- y :: integer(),
- dragText :: unicode:chardata(),
- dragAllowMove :: boolean(),
- dragResult :: wx:wx_enum()}).
--type wxStyledTextEventType() :: 'stc_change' | 'stc_styleneeded' | 'stc_charadded' | 'stc_savepointreached' | 'stc_savepointleft' | 'stc_romodifyattempt' | 'stc_key' | 'stc_doubleclick' | 'stc_updateui' | 'stc_modified' | 'stc_macrorecord' | 'stc_marginclick' | 'stc_needshown' | 'stc_painted' | 'stc_userlistselection' | 'stc_uridropped' | 'stc_dwellstart' | 'stc_dwellend' | 'stc_start_drag' | 'stc_drag_over' | 'stc_do_drop' | 'stc_zoom' | 'stc_hotspot_click' | 'stc_hotspot_dclick' | 'stc_calltip_click' | 'stc_autocomp_selection'.
--type wxStyledText() :: #wxStyledText{}. %% Callback event: {@link wxStyledTextEvent}
-
--record(wxFileDirPicker,{type :: wxFileDirPickerEventType(), %% Callback event: {@link wxFileDirPickerEvent}
- path :: unicode:chardata()}).
--type wxFileDirPickerEventType() :: 'command_filepicker_changed' | 'command_dirpicker_changed'.
--type wxFileDirPicker() :: #wxFileDirPicker{}. %% Callback event: {@link wxFileDirPickerEvent}
-
--record(wxNotebook,{type :: wxNotebookEventType(), %% Callback event: {@link wxNotebookEvent}
- nSel :: integer(),
- nOldSel :: integer()}).
--type wxNotebookEventType() :: 'command_notebook_page_changed' | 'command_notebook_page_changing'.
--type wxNotebook() :: #wxNotebook{}. %% Callback event: {@link wxNotebookEvent}
+-record(wxFocus,{type :: wxFocusEventType(), %% Callback event: {@link wxFocusEvent}
+ win :: wxWindow:wxWindow()}).
+-type wxFocusEventType() :: 'set_focus' | 'kill_focus'.
+-type wxFocus() :: #wxFocus{}. %% Callback event: {@link wxFocusEvent}
--record(wxIdle, {type :: wxIdleEventType()}). %% Callback event: {@link wxIdleEvent}
--type wxIdleEventType() :: 'idle'.
--type wxIdle() :: #wxIdle{}. %% Callback event: {@link wxIdleEvent}
+-record(wxCommand,{type :: wxCommandEventType(), %% Callback event: {@link wxCommandEvent}
+ cmdString :: unicode:chardata(),
+ commandInt :: integer(),
+ extraLong :: integer()}).
+-type wxCommandEventType() :: 'command_button_clicked' | 'command_checkbox_clicked' | 'command_choice_selected' | 'command_listbox_selected' | 'command_listbox_doubleclicked' | 'command_text_updated' | 'command_text_enter' | 'command_menu_selected' | 'command_slider_updated' | 'command_radiobox_selected' | 'command_radiobutton_selected' | 'command_scrollbar_updated' | 'command_vlbox_selected' | 'command_combobox_selected' | 'command_tool_rclicked' | 'command_tool_enter' | 'command_checklistbox_toggled' | 'command_togglebutton_clicked' | 'command_left_click' | 'command_left_dclick' | 'command_right_click' | 'command_set_focus' | 'command_kill_focus' | 'command_enter'.
+-type wxCommand() :: #wxCommand{}. %% Callback event: {@link wxCommandEvent}
-record(wxColourPicker,{type :: wxColourPickerEventType(), %% Callback event: {@link wxColourPickerEvent}
colour :: wx:wx_colour()}).
-type wxColourPickerEventType() :: 'command_colourpicker_changed'.
-type wxColourPicker() :: #wxColourPicker{}. %% Callback event: {@link wxColourPickerEvent}
--record(wxSplitter, {type :: wxSplitterEventType()}). %% Callback event: {@link wxSplitterEvent}
--type wxSplitterEventType() :: 'command_splitter_sash_pos_changed' | 'command_splitter_sash_pos_changing' | 'command_splitter_doubleclicked' | 'command_splitter_unsplit'.
--type wxSplitter() :: #wxSplitter{}. %% Callback event: {@link wxSplitterEvent}
-
--record(wxSash,{type :: wxSashEventType(), %% Callback event: {@link wxSashEvent}
- edge :: wx:wx_enum(),
- dragRect :: {X::integer(), Y::integer(), W::integer(), H::integer()},
- dragStatus :: wx:wx_enum()}).
--type wxSashEventType() :: 'sash_dragged'.
--type wxSash() :: #wxSash{}. %% Callback event: {@link wxSashEvent}
-
-record(wxHelp, {type :: wxHelpEventType()}). %% Callback event: {@link wxHelpEvent}
-type wxHelpEventType() :: 'help' | 'detailed_help'.
-type wxHelp() :: #wxHelp{}. %% Callback event: {@link wxHelpEvent}
--record(wxDisplayChanged, {type :: wxDisplayChangedEventType()}). %% Callback event: {@link wxDisplayChangedEvent}
--type wxDisplayChangedEventType() :: 'display_changed'.
--type wxDisplayChanged() :: #wxDisplayChanged{}. %% Callback event: {@link wxDisplayChangedEvent}
-
--record(wxMouseCaptureLost, {type :: wxMouseCaptureLostEventType()}). %% Callback event: {@link wxMouseCaptureLostEvent}
--type wxMouseCaptureLostEventType() :: 'mouse_capture_lost'.
--type wxMouseCaptureLost() :: #wxMouseCaptureLost{}. %% Callback event: {@link wxMouseCaptureLostEvent}
+-record(wxSpin,{type :: wxSpinEventType(), %% Callback event: {@link wxSpinEvent}
+ commandInt :: integer()}).
+-type wxSpinEventType() :: 'command_spinctrl_updated' | 'spin_up' | 'spin_down' | 'spin'.
+-type wxSpin() :: #wxSpin{}. %% Callback event: {@link wxSpinEvent}
--record(wxFontPicker,{type :: wxFontPickerEventType(), %% Callback event: {@link wxFontPickerEvent}
- font :: wxFont:wxFont()}).
--type wxFontPickerEventType() :: 'command_fontpicker_changed'.
--type wxFontPicker() :: #wxFontPicker{}. %% Callback event: {@link wxFontPickerEvent}
+-record(wxAuiManager,{type :: wxAuiManagerEventType(), %% Callback event: {@link wxAuiManagerEvent}
+ manager :: wxAuiManager:wxAuiManager(),
+ pane :: wxAuiPaneInfo:wxAuiPaneInfo(),
+ button :: integer(),
+ veto_flag :: boolean(),
+ canveto_flag :: boolean(),
+ dc :: wxDC:wxDC()}).
+-type wxAuiManagerEventType() :: 'aui_pane_button' | 'aui_pane_close' | 'aui_pane_maximize' | 'aui_pane_restore' | 'aui_pane_activated' | 'aui_render' | 'aui_find_manager'.
+-type wxAuiManager() :: #wxAuiManager{}. %% Callback event: {@link wxAuiManagerEvent}
--record(wxFocus,{type :: wxFocusEventType(), %% Callback event: {@link wxFocusEvent}
- win :: wxWindow:wxWindow()}).
--type wxFocusEventType() :: 'set_focus' | 'kill_focus'.
--type wxFocus() :: #wxFocus{}. %% Callback event: {@link wxFocusEvent}
+-record(wxDate,{type :: wxDateEventType(), %% Callback event: {@link wxDateEvent}
+ date :: wx:wx_datetime()}).
+-type wxDateEventType() :: 'date_changed'.
+-type wxDate() :: #wxDate{}. %% Callback event: {@link wxDateEvent}
--record(wxPaletteChanged, {type :: wxPaletteChangedEventType()}). %% Callback event: {@link wxPaletteChangedEvent}
--type wxPaletteChangedEventType() :: 'palette_changed'.
--type wxPaletteChanged() :: #wxPaletteChanged{}. %% Callback event: {@link wxPaletteChangedEvent}
+-record(wxIconize,{type :: wxIconizeEventType(), %% Callback event: {@link wxIconizeEvent}
+ iconized :: boolean()}).
+-type wxIconizeEventType() :: 'iconize'.
+-type wxIconize() :: #wxIconize{}. %% Callback event: {@link wxIconizeEvent}
-record(wxScroll,{type :: wxScrollEventType(), %% Callback event: {@link wxScrollEvent}
commandInt :: integer(),
@@ -128,38 +85,41 @@
-type wxScrollEventType() :: 'scroll_top' | 'scroll_bottom' | 'scroll_lineup' | 'scroll_linedown' | 'scroll_pageup' | 'scroll_pagedown' | 'scroll_thumbtrack' | 'scroll_thumbrelease' | 'scroll_changed'.
-type wxScroll() :: #wxScroll{}. %% Callback event: {@link wxScrollEvent}
--record(wxChildFocus, {type :: wxChildFocusEventType()}). %% Callback event: {@link wxChildFocusEvent}
--type wxChildFocusEventType() :: 'child_focus'.
--type wxChildFocus() :: #wxChildFocus{}. %% Callback event: {@link wxChildFocusEvent}
+-record(wxSplitter, {type :: wxSplitterEventType()}). %% Callback event: {@link wxSplitterEvent}
+-type wxSplitterEventType() :: 'command_splitter_sash_pos_changed' | 'command_splitter_sash_pos_changing' | 'command_splitter_doubleclicked' | 'command_splitter_unsplit'.
+-type wxSplitter() :: #wxSplitter{}. %% Callback event: {@link wxSplitterEvent}
--record(wxAuiNotebook,{type :: wxAuiNotebookEventType(), %% Callback event: {@link wxAuiNotebookEvent}
- old_selection :: integer(),
- selection :: integer(),
- drag_source :: wxAuiNotebook:wxAuiNotebook()}).
--type wxAuiNotebookEventType() :: 'command_auinotebook_page_close' | 'command_auinotebook_page_changed' | 'command_auinotebook_page_changing' | 'command_auinotebook_button' | 'command_auinotebook_begin_drag' | 'command_auinotebook_end_drag' | 'command_auinotebook_drag_motion' | 'command_auinotebook_allow_dnd' | 'command_auinotebook_tab_middle_down' | 'command_auinotebook_tab_middle_up' | 'command_auinotebook_tab_right_down' | 'command_auinotebook_tab_right_up' | 'command_auinotebook_page_closed' | 'command_auinotebook_drag_done' | 'command_auinotebook_bg_dclick'.
--type wxAuiNotebook() :: #wxAuiNotebook{}. %% Callback event: {@link wxAuiNotebookEvent}
+-record(wxPaletteChanged, {type :: wxPaletteChangedEventType()}). %% Callback event: {@link wxPaletteChangedEvent}
+-type wxPaletteChangedEventType() :: 'palette_changed'.
+-type wxPaletteChanged() :: #wxPaletteChanged{}. %% Callback event: {@link wxPaletteChangedEvent}
--record(wxSize,{type :: wxSizeEventType(), %% Callback event: {@link wxSizeEvent}
- size :: {W::integer(), H::integer()},
- rect :: {X::integer(), Y::integer(), W::integer(), H::integer()}}).
--type wxSizeEventType() :: 'size'.
--type wxSize() :: #wxSize{}. %% Callback event: {@link wxSizeEvent}
+-record(wxNotebook,{type :: wxNotebookEventType(), %% Callback event: {@link wxNotebookEvent}
+ nSel :: integer(),
+ nOldSel :: integer()}).
+-type wxNotebookEventType() :: 'command_notebook_page_changed' | 'command_notebook_page_changing'.
+-type wxNotebook() :: #wxNotebook{}. %% Callback event: {@link wxNotebookEvent}
--record(wxCommand,{type :: wxCommandEventType(), %% Callback event: {@link wxCommandEvent}
- cmdString :: unicode:chardata(),
- commandInt :: integer(),
- extraLong :: integer()}).
--type wxCommandEventType() :: 'command_button_clicked' | 'command_checkbox_clicked' | 'command_choice_selected' | 'command_listbox_selected' | 'command_listbox_doubleclicked' | 'command_text_updated' | 'command_text_enter' | 'command_menu_selected' | 'command_slider_updated' | 'command_radiobox_selected' | 'command_radiobutton_selected' | 'command_scrollbar_updated' | 'command_vlbox_selected' | 'command_combobox_selected' | 'command_tool_rclicked' | 'command_tool_enter' | 'command_checklistbox_toggled' | 'command_togglebutton_clicked' | 'command_left_click' | 'command_left_dclick' | 'command_right_click' | 'command_set_focus' | 'command_kill_focus' | 'command_enter'.
--type wxCommand() :: #wxCommand{}. %% Callback event: {@link wxCommandEvent}
+-record(wxContextMenu,{type :: wxContextMenuEventType(), %% Callback event: {@link wxContextMenuEvent}
+ pos :: {X::integer(), Y::integer()}}).
+-type wxContextMenuEventType() :: 'context_menu'.
+-type wxContextMenu() :: #wxContextMenu{}. %% Callback event: {@link wxContextMenuEvent}
--record(wxMaximize, {type :: wxMaximizeEventType()}). %% Callback event: {@link wxMaximizeEvent}
--type wxMaximizeEventType() :: 'maximize'.
--type wxMaximize() :: #wxMaximize{}. %% Callback event: {@link wxMaximizeEvent}
+-record(wxFontPicker,{type :: wxFontPickerEventType(), %% Callback event: {@link wxFontPickerEvent}
+ font :: wxFont:wxFont()}).
+-type wxFontPickerEventType() :: 'command_fontpicker_changed'.
+-type wxFontPicker() :: #wxFontPicker{}. %% Callback event: {@link wxFontPickerEvent}
--record(wxSpin,{type :: wxSpinEventType(), %% Callback event: {@link wxSpinEvent}
- commandInt :: integer()}).
--type wxSpinEventType() :: 'command_spinctrl_updated' | 'spin_up' | 'spin_down' | 'spin'.
--type wxSpin() :: #wxSpin{}. %% Callback event: {@link wxSpinEvent}
+-record(wxChildFocus, {type :: wxChildFocusEventType()}). %% Callback event: {@link wxChildFocusEvent}
+-type wxChildFocusEventType() :: 'child_focus'.
+-type wxChildFocus() :: #wxChildFocus{}. %% Callback event: {@link wxChildFocusEvent}
+
+-record(wxTaskBarIcon, {type :: wxTaskBarIconEventType()}). %% Callback event: {@link wxTaskBarIconEvent}
+-type wxTaskBarIconEventType() :: 'taskbar_move' | 'taskbar_left_down' | 'taskbar_left_up' | 'taskbar_right_down' | 'taskbar_right_up' | 'taskbar_left_dclick' | 'taskbar_right_dclick'.
+-type wxTaskBarIcon() :: #wxTaskBarIcon{}. %% Callback event: {@link wxTaskBarIconEvent}
+
+-record(wxWindowDestroy, {type :: wxWindowDestroyEventType()}). %% Callback event: {@link wxWindowDestroyEvent}
+-type wxWindowDestroyEventType() :: 'destroy'.
+-type wxWindowDestroy() :: #wxWindowDestroy{}. %% Callback event: {@link wxWindowDestroyEvent}
-record(wxMenu,{type :: wxMenuEventType(), %% Callback event: {@link wxMenuEvent}
menuId :: integer(),
@@ -167,30 +127,63 @@
-type wxMenuEventType() :: 'menu_open' | 'menu_close' | 'menu_highlight'.
-type wxMenu() :: #wxMenu{}. %% Callback event: {@link wxMenuEvent}
+-record(wxActivate,{type :: wxActivateEventType(), %% Callback event: {@link wxActivateEvent}
+ active :: boolean()}).
+-type wxActivateEventType() :: 'activate' | 'activate_app' | 'hibernate'.
+-type wxActivate() :: #wxActivate{}. %% Callback event: {@link wxActivateEvent}
+
+-record(wxGrid,{type :: wxGridEventType(), %% Callback event: {@link wxGridEvent}
+ row :: integer(),
+ col :: integer(),
+ x :: integer(),
+ y :: integer(),
+ selecting :: boolean(),
+ control :: boolean(),
+ meta :: boolean(),
+ shift :: boolean(),
+ alt :: boolean()}).
+-type wxGridEventType() :: 'grid_cell_left_click' | 'grid_cell_right_click' | 'grid_cell_left_dclick' | 'grid_cell_right_dclick' | 'grid_label_left_click' | 'grid_label_right_click' | 'grid_label_left_dclick' | 'grid_label_right_dclick' | 'grid_row_size' | 'grid_col_size' | 'grid_range_select' | 'grid_cell_change' | 'grid_select_cell' | 'grid_editor_shown' | 'grid_editor_hidden' | 'grid_editor_created' | 'grid_cell_begin_drag'.
+-type wxGrid() :: #wxGrid{}. %% Callback event: {@link wxGridEvent}
+
+-record(wxPaint, {type :: wxPaintEventType()}). %% Callback event: {@link wxPaintEvent}
+-type wxPaintEventType() :: 'paint'.
+-type wxPaint() :: #wxPaint{}. %% Callback event: {@link wxPaintEvent}
+
-record(wxShow,{type :: wxShowEventType(), %% Callback event: {@link wxShowEvent}
show :: boolean()}).
-type wxShowEventType() :: 'show'.
-type wxShow() :: #wxShow{}. %% Callback event: {@link wxShowEvent}
--record(wxWindowDestroy, {type :: wxWindowDestroyEventType()}). %% Callback event: {@link wxWindowDestroyEvent}
--type wxWindowDestroyEventType() :: 'destroy'.
--type wxWindowDestroy() :: #wxWindowDestroy{}. %% Callback event: {@link wxWindowDestroyEvent}
-
--record(wxContextMenu,{type :: wxContextMenuEventType(), %% Callback event: {@link wxContextMenuEvent}
- pos :: {X::integer(), Y::integer()}}).
--type wxContextMenuEventType() :: 'context_menu'.
--type wxContextMenu() :: #wxContextMenu{}. %% Callback event: {@link wxContextMenuEvent}
-
--record(wxActivate,{type :: wxActivateEventType(), %% Callback event: {@link wxActivateEvent}
- active :: boolean()}).
--type wxActivateEventType() :: 'activate' | 'activate_app' | 'hibernate'.
--type wxActivate() :: #wxActivate{}. %% Callback event: {@link wxActivateEvent}
+-record(wxStyledText,{type :: wxStyledTextEventType(), %% Callback event: {@link wxStyledTextEvent}
+ position :: integer(),
+ key :: integer(),
+ modifiers :: integer(),
+ modificationType :: integer(),
+ text :: unicode:chardata(),
+ length :: integer(),
+ linesAdded :: integer(),
+ line :: integer(),
+ foldLevelNow :: integer(),
+ foldLevelPrev :: integer(),
+ margin :: integer(),
+ message :: integer(),
+ wParam :: integer(),
+ lParam :: integer(),
+ listType :: integer(),
+ x :: integer(),
+ y :: integer(),
+ dragText :: unicode:chardata(),
+ dragAllowMove :: boolean(),
+ dragResult :: wx:wx_enum()}).
+-type wxStyledTextEventType() :: 'stc_change' | 'stc_styleneeded' | 'stc_charadded' | 'stc_savepointreached' | 'stc_savepointleft' | 'stc_romodifyattempt' | 'stc_key' | 'stc_doubleclick' | 'stc_updateui' | 'stc_modified' | 'stc_macrorecord' | 'stc_marginclick' | 'stc_needshown' | 'stc_painted' | 'stc_userlistselection' | 'stc_uridropped' | 'stc_dwellstart' | 'stc_dwellend' | 'stc_start_drag' | 'stc_drag_over' | 'stc_do_drop' | 'stc_zoom' | 'stc_hotspot_click' | 'stc_hotspot_dclick' | 'stc_calltip_click' | 'stc_autocomp_selection'.
+-type wxStyledText() :: #wxStyledText{}. %% Callback event: {@link wxStyledTextEvent}
--record(wxMove,{type :: wxMoveEventType(), %% Callback event: {@link wxMoveEvent}
- pos :: {X::integer(), Y::integer()},
- rect :: {X::integer(), Y::integer(), W::integer(), H::integer()}}).
--type wxMoveEventType() :: 'move'.
--type wxMove() :: #wxMove{}. %% Callback event: {@link wxMoveEvent}
+-record(wxAuiNotebook,{type :: wxAuiNotebookEventType(), %% Callback event: {@link wxAuiNotebookEvent}
+ old_selection :: integer(),
+ selection :: integer(),
+ drag_source :: wxAuiNotebook:wxAuiNotebook()}).
+-type wxAuiNotebookEventType() :: 'command_auinotebook_page_close' | 'command_auinotebook_page_changed' | 'command_auinotebook_page_changing' | 'command_auinotebook_button' | 'command_auinotebook_begin_drag' | 'command_auinotebook_end_drag' | 'command_auinotebook_drag_motion' | 'command_auinotebook_allow_dnd' | 'command_auinotebook_tab_middle_down' | 'command_auinotebook_tab_middle_up' | 'command_auinotebook_tab_right_down' | 'command_auinotebook_tab_right_up' | 'command_auinotebook_page_closed' | 'command_auinotebook_drag_done' | 'command_auinotebook_bg_dclick'.
+-type wxAuiNotebook() :: #wxAuiNotebook{}. %% Callback event: {@link wxAuiNotebookEvent}
-record(wxList,{type :: wxListEventType(), %% Callback event: {@link wxListEvent}
code :: integer(),
@@ -201,9 +194,9 @@
-type wxListEventType() :: 'command_list_begin_drag' | 'command_list_begin_rdrag' | 'command_list_begin_label_edit' | 'command_list_end_label_edit' | 'command_list_delete_item' | 'command_list_delete_all_items' | 'command_list_key_down' | 'command_list_insert_item' | 'command_list_col_click' | 'command_list_col_right_click' | 'command_list_col_begin_drag' | 'command_list_col_dragging' | 'command_list_col_end_drag' | 'command_list_item_selected' | 'command_list_item_deselected' | 'command_list_item_right_click' | 'command_list_item_middle_click' | 'command_list_item_activated' | 'command_list_item_focused' | 'command_list_cache_hint'.
-type wxList() :: #wxList{}. %% Callback event: {@link wxListEvent}
--record(wxClipboardText, {type :: wxClipboardTextEventType()}). %% Callback event: {@link wxClipboardTextEvent}
--type wxClipboardTextEventType() :: 'command_text_copy' | 'command_text_cut' | 'command_text_paste'.
--type wxClipboardText() :: #wxClipboardText{}. %% Callback event: {@link wxClipboardTextEvent}
+-record(wxUpdateUI, {type :: wxUpdateUIEventType()}). %% Callback event: {@link wxUpdateUIEvent}
+-type wxUpdateUIEventType() :: 'update_ui'.
+-type wxUpdateUI() :: #wxUpdateUI{}. %% Callback event: {@link wxUpdateUIEvent}
-record(wxScrollWin,{type :: wxScrollWinEventType(), %% Callback event: {@link wxScrollWinEvent}
commandInt :: integer(),
@@ -211,92 +204,81 @@
-type wxScrollWinEventType() :: 'scrollwin_top' | 'scrollwin_bottom' | 'scrollwin_lineup' | 'scrollwin_linedown' | 'scrollwin_pageup' | 'scrollwin_pagedown' | 'scrollwin_thumbtrack' | 'scrollwin_thumbrelease'.
-type wxScrollWin() :: #wxScrollWin{}. %% Callback event: {@link wxScrollWinEvent}
--record(wxIconize,{type :: wxIconizeEventType(), %% Callback event: {@link wxIconizeEvent}
- iconized :: boolean()}).
--type wxIconizeEventType() :: 'iconize'.
--type wxIconize() :: #wxIconize{}. %% Callback event: {@link wxIconizeEvent}
+-record(wxJoystick,{type :: wxJoystickEventType(), %% Callback event: {@link wxJoystickEvent}
+ pos :: {X::integer(), Y::integer()},
+ zPosition :: integer(),
+ buttonChange :: integer(),
+ buttonState :: integer(),
+ joyStick :: integer()}).
+-type wxJoystickEventType() :: 'joy_button_down' | 'joy_button_up' | 'joy_move' | 'joy_zmove'.
+-type wxJoystick() :: #wxJoystick{}. %% Callback event: {@link wxJoystickEvent}
--record(wxUpdateUI, {type :: wxUpdateUIEventType()}). %% Callback event: {@link wxUpdateUIEvent}
--type wxUpdateUIEventType() :: 'update_ui'.
--type wxUpdateUI() :: #wxUpdateUI{}. %% Callback event: {@link wxUpdateUIEvent}
+-record(wxWindowCreate, {type :: wxWindowCreateEventType()}). %% Callback event: {@link wxWindowCreateEvent}
+-type wxWindowCreateEventType() :: 'create'.
+-type wxWindowCreate() :: #wxWindowCreate{}. %% Callback event: {@link wxWindowCreateEvent}
--record(wxMouse,{type :: wxMouseEventType(), %% Callback event: {@link wxMouseEvent}
+-record(wxClose, {type :: wxCloseEventType()}). %% Callback event: {@link wxCloseEvent}
+-type wxCloseEventType() :: 'close_window' | 'end_session' | 'query_end_session'.
+-type wxClose() :: #wxClose{}. %% Callback event: {@link wxCloseEvent}
+
+-record(wxKey,{type :: wxKeyEventType(), %% Callback event: {@link wxKeyEvent}
x :: integer(),
y :: integer(),
- leftDown :: boolean(),
- middleDown :: boolean(),
- rightDown :: boolean(),
+ keyCode :: integer(),
controlDown :: boolean(),
shiftDown :: boolean(),
altDown :: boolean(),
metaDown :: boolean(),
- wheelRotation :: integer(),
- wheelDelta :: integer(),
- linesPerAction :: integer()}).
--type wxMouseEventType() :: 'left_down' | 'left_up' | 'middle_down' | 'middle_up' | 'right_down' | 'right_up' | 'motion' | 'enter_window' | 'leave_window' | 'left_dclick' | 'middle_dclick' | 'right_dclick' | 'mousewheel'.
--type wxMouse() :: #wxMouse{}. %% Callback event: {@link wxMouseEvent}
-
--record(wxTree,{type :: wxTreeEventType(), %% Callback event: {@link wxTreeEvent}
- item :: integer(),
- itemOld :: integer(),
- pointDrag :: {X::integer(), Y::integer()}}).
--type wxTreeEventType() :: 'command_tree_begin_drag' | 'command_tree_begin_rdrag' | 'command_tree_begin_label_edit' | 'command_tree_end_label_edit' | 'command_tree_delete_item' | 'command_tree_get_info' | 'command_tree_set_info' | 'command_tree_item_expanded' | 'command_tree_item_expanding' | 'command_tree_item_collapsed' | 'command_tree_item_collapsing' | 'command_tree_sel_changed' | 'command_tree_sel_changing' | 'command_tree_key_down' | 'command_tree_item_activated' | 'command_tree_item_right_click' | 'command_tree_item_middle_click' | 'command_tree_end_drag' | 'command_tree_state_image_click' | 'command_tree_item_gettooltip' | 'command_tree_item_menu'.
--type wxTree() :: #wxTree{}. %% Callback event: {@link wxTreeEvent}
-
--record(wxSysColourChanged, {type :: wxSysColourChangedEventType()}). %% Callback event: {@link wxSysColourChangedEvent}
--type wxSysColourChangedEventType() :: 'sys_colour_changed'.
--type wxSysColourChanged() :: #wxSysColourChanged{}. %% Callback event: {@link wxSysColourChangedEvent}
+ scanCode :: boolean(),
+ uniChar :: integer(),
+ rawCode :: integer(),
+ rawFlags :: integer()}).
+-type wxKeyEventType() :: 'char' | 'char_hook' | 'key_down' | 'key_up'.
+-type wxKey() :: #wxKey{}. %% Callback event: {@link wxKeyEvent}
--record(wxNavigationKey,{type :: wxNavigationKeyEventType(), %% Callback event: {@link wxNavigationKeyEvent}
- flags :: integer(),
- focus :: wxWindow:wxWindow()}).
--type wxNavigationKeyEventType() :: 'navigation_key'.
--type wxNavigationKey() :: #wxNavigationKey{}. %% Callback event: {@link wxNavigationKeyEvent}
+-record(wxIdle, {type :: wxIdleEventType()}). %% Callback event: {@link wxIdleEvent}
+-type wxIdleEventType() :: 'idle'.
+-type wxIdle() :: #wxIdle{}. %% Callback event: {@link wxIdleEvent}
-record(wxQueryNewPalette, {type :: wxQueryNewPaletteEventType()}). %% Callback event: {@link wxQueryNewPaletteEvent}
-type wxQueryNewPaletteEventType() :: 'query_new_palette'.
-type wxQueryNewPalette() :: #wxQueryNewPalette{}. %% Callback event: {@link wxQueryNewPaletteEvent}
--record(wxMouseCaptureChanged, {type :: wxMouseCaptureChangedEventType()}). %% Callback event: {@link wxMouseCaptureChangedEvent}
--type wxMouseCaptureChangedEventType() :: 'mouse_capture_changed'.
--type wxMouseCaptureChanged() :: #wxMouseCaptureChanged{}. %% Callback event: {@link wxMouseCaptureChangedEvent}
-
-record(wxHtmlLink,{type :: wxHtmlLinkEventType(), %% Callback event: {@link wxHtmlLinkEvent}
linkInfo :: wx:wx_wxHtmlLinkInfo()}).
-type wxHtmlLinkEventType() :: 'command_html_link_clicked'.
-type wxHtmlLink() :: #wxHtmlLink{}. %% Callback event: {@link wxHtmlLinkEvent}
--record(wxKey,{type :: wxKeyEventType(), %% Callback event: {@link wxKeyEvent}
- x :: integer(),
- y :: integer(),
- keyCode :: integer(),
- controlDown :: boolean(),
- shiftDown :: boolean(),
- altDown :: boolean(),
- metaDown :: boolean(),
- scanCode :: boolean(),
- uniChar :: integer(),
- rawCode :: integer(),
- rawFlags :: integer()}).
--type wxKeyEventType() :: 'char' | 'char_hook' | 'key_down' | 'key_up'.
--type wxKey() :: #wxKey{}. %% Callback event: {@link wxKeyEvent}
+-record(wxInitDialog, {type :: wxInitDialogEventType()}). %% Callback event: {@link wxInitDialogEvent}
+-type wxInitDialogEventType() :: 'init_dialog'.
+-type wxInitDialog() :: #wxInitDialog{}. %% Callback event: {@link wxInitDialogEvent}
--record(wxTaskBarIcon, {type :: wxTaskBarIconEventType()}). %% Callback event: {@link wxTaskBarIconEvent}
--type wxTaskBarIconEventType() :: 'taskbar_move' | 'taskbar_left_down' | 'taskbar_left_up' | 'taskbar_right_down' | 'taskbar_right_up' | 'taskbar_left_dclick' | 'taskbar_right_dclick'.
--type wxTaskBarIcon() :: #wxTaskBarIcon{}. %% Callback event: {@link wxTaskBarIconEvent}
+-record(wxMaximize, {type :: wxMaximizeEventType()}). %% Callback event: {@link wxMaximizeEvent}
+-type wxMaximizeEventType() :: 'maximize'.
+-type wxMaximize() :: #wxMaximize{}. %% Callback event: {@link wxMaximizeEvent}
--record(wxGrid,{type :: wxGridEventType(), %% Callback event: {@link wxGridEvent}
- row :: integer(),
- col :: integer(),
- x :: integer(),
- y :: integer(),
- selecting :: boolean(),
- control :: boolean(),
- meta :: boolean(),
- shift :: boolean(),
- alt :: boolean()}).
--type wxGridEventType() :: 'grid_cell_left_click' | 'grid_cell_right_click' | 'grid_cell_left_dclick' | 'grid_cell_right_dclick' | 'grid_label_left_click' | 'grid_label_right_click' | 'grid_label_left_dclick' | 'grid_label_right_dclick' | 'grid_row_size' | 'grid_col_size' | 'grid_range_select' | 'grid_cell_change' | 'grid_select_cell' | 'grid_editor_shown' | 'grid_editor_hidden' | 'grid_editor_created' | 'grid_cell_begin_drag'.
--type wxGrid() :: #wxGrid{}. %% Callback event: {@link wxGridEvent}
+-record(wxClipboardText, {type :: wxClipboardTextEventType()}). %% Callback event: {@link wxClipboardTextEvent}
+-type wxClipboardTextEventType() :: 'command_text_copy' | 'command_text_cut' | 'command_text_paste'.
+-type wxClipboardText() :: #wxClipboardText{}. %% Callback event: {@link wxClipboardTextEvent}
+
+-record(wxTree,{type :: wxTreeEventType(), %% Callback event: {@link wxTreeEvent}
+ item :: integer(),
+ itemOld :: integer(),
+ pointDrag :: {X::integer(), Y::integer()}}).
+-type wxTreeEventType() :: 'command_tree_begin_drag' | 'command_tree_begin_rdrag' | 'command_tree_begin_label_edit' | 'command_tree_end_label_edit' | 'command_tree_delete_item' | 'command_tree_get_info' | 'command_tree_set_info' | 'command_tree_item_expanded' | 'command_tree_item_expanding' | 'command_tree_item_collapsed' | 'command_tree_item_collapsing' | 'command_tree_sel_changed' | 'command_tree_sel_changing' | 'command_tree_key_down' | 'command_tree_item_activated' | 'command_tree_item_right_click' | 'command_tree_item_middle_click' | 'command_tree_end_drag' | 'command_tree_state_image_click' | 'command_tree_item_gettooltip' | 'command_tree_item_menu'.
+-type wxTree() :: #wxTree{}. %% Callback event: {@link wxTreeEvent}
+
+-record(wxErase,{type :: wxEraseEventType(), %% Callback event: {@link wxEraseEvent}
+ dc :: wxDC:wxDC()}).
+-type wxEraseEventType() :: 'erase_background'.
+-type wxErase() :: #wxErase{}. %% Callback event: {@link wxEraseEvent}
+
+-record(wxSash,{type :: wxSashEventType(), %% Callback event: {@link wxSashEvent}
+ edge :: wx:wx_enum(),
+ dragRect :: {X::integer(), Y::integer(), W::integer(), H::integer()},
+ dragStatus :: wx:wx_enum()}).
+-type wxSashEventType() :: 'sash_dragged'.
+-type wxSash() :: #wxSash{}. %% Callback event: {@link wxSashEvent}
-record(wxCalendar,{type :: wxCalendarEventType(), %% Callback event: {@link wxCalendarEvent}
wday :: wx:wx_enum(),
@@ -304,42 +286,52 @@
-type wxCalendarEventType() :: 'calendar_sel_changed' | 'calendar_day_changed' | 'calendar_month_changed' | 'calendar_year_changed' | 'calendar_doubleclicked' | 'calendar_weekday_clicked'.
-type wxCalendar() :: #wxCalendar{}. %% Callback event: {@link wxCalendarEvent}
--record(wxWindowCreate, {type :: wxWindowCreateEventType()}). %% Callback event: {@link wxWindowCreateEvent}
--type wxWindowCreateEventType() :: 'create'.
--type wxWindowCreate() :: #wxWindowCreate{}. %% Callback event: {@link wxWindowCreateEvent}
+-record(wxMouse,{type :: wxMouseEventType(), %% Callback event: {@link wxMouseEvent}
+ x :: integer(),
+ y :: integer(),
+ leftDown :: boolean(),
+ middleDown :: boolean(),
+ rightDown :: boolean(),
+ controlDown :: boolean(),
+ shiftDown :: boolean(),
+ altDown :: boolean(),
+ metaDown :: boolean(),
+ wheelRotation :: integer(),
+ wheelDelta :: integer(),
+ linesPerAction :: integer()}).
+-type wxMouseEventType() :: 'left_down' | 'left_up' | 'middle_down' | 'middle_up' | 'right_down' | 'right_up' | 'motion' | 'enter_window' | 'leave_window' | 'left_dclick' | 'middle_dclick' | 'right_dclick' | 'mousewheel'.
+-type wxMouse() :: #wxMouse{}. %% Callback event: {@link wxMouseEvent}
--record(wxDate,{type :: wxDateEventType(), %% Callback event: {@link wxDateEvent}
- date :: wx:wx_datetime()}).
--type wxDateEventType() :: 'date_changed'.
--type wxDate() :: #wxDate{}. %% Callback event: {@link wxDateEvent}
+-record(wxSize,{type :: wxSizeEventType(), %% Callback event: {@link wxSizeEvent}
+ size :: {W::integer(), H::integer()},
+ rect :: {X::integer(), Y::integer(), W::integer(), H::integer()}}).
+-type wxSizeEventType() :: 'size'.
+-type wxSize() :: #wxSize{}. %% Callback event: {@link wxSizeEvent}
--record(wxAuiManager,{type :: wxAuiManagerEventType(), %% Callback event: {@link wxAuiManagerEvent}
- manager :: wxAuiManager:wxAuiManager(),
- pane :: wxAuiPaneInfo:wxAuiPaneInfo(),
- button :: integer(),
- veto_flag :: boolean(),
- canveto_flag :: boolean(),
- dc :: wxDC:wxDC()}).
--type wxAuiManagerEventType() :: 'aui_pane_button' | 'aui_pane_close' | 'aui_pane_maximize' | 'aui_pane_restore' | 'aui_pane_activated' | 'aui_render' | 'aui_find_manager'.
--type wxAuiManager() :: #wxAuiManager{}. %% Callback event: {@link wxAuiManagerEvent}
+-record(wxSysColourChanged, {type :: wxSysColourChangedEventType()}). %% Callback event: {@link wxSysColourChangedEvent}
+-type wxSysColourChangedEventType() :: 'sys_colour_changed'.
+-type wxSysColourChanged() :: #wxSysColourChanged{}. %% Callback event: {@link wxSysColourChangedEvent}
--record(wxJoystick,{type :: wxJoystickEventType(), %% Callback event: {@link wxJoystickEvent}
+-record(wxDisplayChanged, {type :: wxDisplayChangedEventType()}). %% Callback event: {@link wxDisplayChangedEvent}
+-type wxDisplayChangedEventType() :: 'display_changed'.
+-type wxDisplayChanged() :: #wxDisplayChanged{}. %% Callback event: {@link wxDisplayChangedEvent}
+
+-record(wxMove,{type :: wxMoveEventType(), %% Callback event: {@link wxMoveEvent}
pos :: {X::integer(), Y::integer()},
- zPosition :: integer(),
- buttonChange :: integer(),
- buttonState :: integer(),
- joyStick :: integer()}).
--type wxJoystickEventType() :: 'joy_button_down' | 'joy_button_up' | 'joy_move' | 'joy_zmove'.
--type wxJoystick() :: #wxJoystick{}. %% Callback event: {@link wxJoystickEvent}
+ rect :: {X::integer(), Y::integer(), W::integer(), H::integer()}}).
+-type wxMoveEventType() :: 'move'.
+-type wxMove() :: #wxMove{}. %% Callback event: {@link wxMoveEvent}
--record(wxPaint, {type :: wxPaintEventType()}). %% Callback event: {@link wxPaintEvent}
--type wxPaintEventType() :: 'paint'.
--type wxPaint() :: #wxPaint{}. %% Callback event: {@link wxPaintEvent}
+-record(wxNavigationKey,{type :: wxNavigationKeyEventType(), %% Callback event: {@link wxNavigationKeyEvent}
+ flags :: integer(),
+ focus :: wxWindow:wxWindow()}).
+-type wxNavigationKeyEventType() :: 'navigation_key'.
+-type wxNavigationKey() :: #wxNavigationKey{}. %% Callback event: {@link wxNavigationKeyEvent}
--record(wxErase,{type :: wxEraseEventType(), %% Callback event: {@link wxEraseEvent}
- dc :: wxDC:wxDC()}).
--type wxEraseEventType() :: 'erase_background'.
--type wxErase() :: #wxErase{}. %% Callback event: {@link wxEraseEvent}
+-record(wxFileDirPicker,{type :: wxFileDirPickerEventType(), %% Callback event: {@link wxFileDirPickerEvent}
+ path :: unicode:chardata()}).
+-type wxFileDirPickerEventType() :: 'command_filepicker_changed' | 'command_dirpicker_changed'.
+-type wxFileDirPicker() :: #wxFileDirPicker{}. %% Callback event: {@link wxFileDirPickerEvent}
-record(wxSetCursor,{type :: wxSetCursorEventType(), %% Callback event: {@link wxSetCursorEvent}
x :: integer(),
@@ -348,6 +340,14 @@
-type wxSetCursorEventType() :: 'set_cursor'.
-type wxSetCursor() :: #wxSetCursor{}. %% Callback event: {@link wxSetCursorEvent}
+-record(wxMouseCaptureChanged, {type :: wxMouseCaptureChangedEventType()}). %% Callback event: {@link wxMouseCaptureChangedEvent}
+-type wxMouseCaptureChangedEventType() :: 'mouse_capture_changed'.
+-type wxMouseCaptureChanged() :: #wxMouseCaptureChanged{}. %% Callback event: {@link wxMouseCaptureChangedEvent}
+
+-record(wxMouseCaptureLost, {type :: wxMouseCaptureLostEventType()}). %% Callback event: {@link wxMouseCaptureLostEvent}
+-type wxMouseCaptureLostEventType() :: 'mouse_capture_lost'.
+-type wxMouseCaptureLost() :: #wxMouseCaptureLost{}. %% Callback event: {@link wxMouseCaptureLostEvent}
+
-type event() :: wxActivate() | wxAuiManager() | wxAuiNotebook() | wxCalendar() | wxChildFocus() | wxClipboardText() | wxClose() | wxColourPicker() | wxCommand() | wxContextMenu() | wxDate() | wxDisplayChanged() | wxErase() | wxFileDirPicker() | wxFocus() | wxFontPicker() | wxGrid() | wxHelp() | wxHtmlLink() | wxIconize() | wxIdle() | wxInitDialog() | wxJoystick() | wxKey() | wxList() | wxMaximize() | wxMenu() | wxMouse() | wxMouseCaptureChanged() | wxMouseCaptureLost() | wxMove() | wxNavigationKey() | wxNotebook() | wxPaint() | wxPaletteChanged() | wxQueryNewPalette() | wxSash() | wxScroll() | wxScrollWin() | wxSetCursor() | wxShow() | wxSize() | wxSpin() | wxSplitter() | wxStyledText() | wxSysColourChanged() | wxTaskBarIcon() | wxTree() | wxUpdateUI() | wxWindowCreate() | wxWindowDestroy().
-type wxEventType() :: wxActivateEventType() | wxAuiManagerEventType() | wxAuiNotebookEventType() | wxCalendarEventType() | wxChildFocusEventType() | wxClipboardTextEventType() | wxCloseEventType() | wxColourPickerEventType() | wxCommandEventType() | wxContextMenuEventType() | wxDateEventType() | wxDisplayChangedEventType() | wxEraseEventType() | wxFileDirPickerEventType() | wxFocusEventType() | wxFontPickerEventType() | wxGridEventType() | wxHelpEventType() | wxHtmlLinkEventType() | wxIconizeEventType() | wxIdleEventType() | wxInitDialogEventType() | wxJoystickEventType() | wxKeyEventType() | wxListEventType() | wxMaximizeEventType() | wxMenuEventType() | wxMouseCaptureChangedEventType() | wxMouseCaptureLostEventType() | wxMouseEventType() | wxMoveEventType() | wxNavigationKeyEventType() | wxNotebookEventType() | wxPaintEventType() | wxPaletteChangedEventType() | wxQueryNewPaletteEventType() | wxSashEventType() | wxScrollEventType() | wxScrollWinEventType() | wxSetCursorEventType() | wxShowEventType() | wxSizeEventType() | wxSpinEventType() | wxSplitterEventType() | wxStyledTextEventType() | wxSysColourChangedEventType() | wxTaskBarIconEventType() | wxTreeEventType() | wxUpdateUIEventType() | wxWindowCreateEventType() | wxWindowDestroyEventType().
diff --git a/lib/wx/src/gen/wxListCtrl.erl b/lib/wx/src/gen/wxListCtrl.erl
index d1a063d900..851686062a 100644
--- a/lib/wx/src/gen/wxListCtrl.erl
+++ b/lib/wx/src/gen/wxListCtrl.erl
@@ -94,31 +94,34 @@ parent_class(_Class) -> erlang:error({badtype, ?MODULE}).
-type wxListCtrl() :: wx:wx_object().
-%% @spec () -> wxListCtrl()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxlistctrl.html#wxlistctrlwxlistctrl">external documentation</a>.
+-spec new() -> wxListCtrl().
new() ->
wxe_util:construct(?wxListCtrl_new_0, <<>>).
-%% @spec (Parent::wxWindow:wxWindow()) -> wxListCtrl()
-%% @equiv new(Parent, [])
+-spec new(Parent) -> wxListCtrl() when
+ Parent::wxWindow:wxWindow().
new(Parent)
when is_record(Parent, wx_ref) ->
new(Parent, []).
-%% @spec (Parent::wxWindow:wxWindow(), [Option]) -> wxListCtrl()
-%% Option = {winid, integer()} |
-%% {pos, {X::integer(),Y::integer()}} |
-%% {size, {W::integer(),H::integer()}} |
-%% {style, integer()} |
-%% {validator, wx:wx()} |
-%% {onGetItemText, OnGetItemText} |
-%% {onGetItemAttr, OnGetItemAttr} |
-%% {onGetItemColumnImage, OnGetItemColumnImage}
+%% @doc Creates a listctrl with optional callback functions:
%%
-%% OnGetItemText = (This, Item, Column) -> wxString()
-%% OnGetItemAttr = (This, Item) -> wxListItemAttr()
+%% OnGetItemText = (This, Item, Column) -> unicode:charlist()
+%% OnGetItemAttr = (This, Item) -> wxListItemAttr:wxListItemAttr()
%% OnGetItemColumnImage = (This, Item, Column) -> integer()
-%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxlistctrl.html#wxlistctrlwxlistctrl">external documentation</a>.
+%%
+%% See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxlistctrl.html#wxlistctrlwxlistctrl">external documentation</a>.
+-spec new(Parent, [Option]) -> wxListCtrl() when
+ Parent::wxWindow:wxWindow(),
+ Option::{winid, integer()} |
+ {pos, {X::integer(),Y::integer()}} |
+ {size, {W::integer(),H::integer()}} |
+ {style, integer()} |
+ {validator, wx:wx_object()} |
+ {onGetItemText, function()} |
+ {onGetItemAttr, function()} |
+ {onGetItemColumnImage, function()}.
new(#wx_ref{type=ParentT,ref=ParentRef}, Options)
when is_list(Options)->
@@ -185,26 +188,27 @@ clearAll(#wx_ref{type=ThisT,ref=ThisRef}) ->
<<ThisRef:32/?UI>>).
-%% @spec (This::wxListCtrl(), Parent::wxWindow:wxWindow()) -> bool()
%% @equiv create(This,Parent, [])
+-spec create(This, Parent) -> wxListCtrl() when
+ This::wxWindow:wxWindow(),
+ Parent::wxWindow:wxWindow().
create(This,Parent)
when is_record(This, wx_ref),is_record(Parent, wx_ref) ->
create(This,Parent, []).
-%% @spec (This::wxListCtrl(), Parent::wxWindow:wxWindow(), [Option]) -> bool()
-%% Option = {winid, integer()} |
-%% {pos, {X::integer(),Y::integer()}} |
-%% {size, {W::integer(),H::integer()}} |
-%% {style, integer()} |
-%% {validator, wx:wx()} |
-%% {onGetItemText, OnGetItemText} |
-%% {onGetItemAttr, OnGetItemAttr} |
-%% {onGetItemColumnImage, OnGetItemColumnImage}
-%%
-%% OnGetItemText = (This, Item, Column) -> wxString()
-%% OnGetItemAttr = (This, Item) -> wxListItemAttr()
-%% OnGetItemColumnImage = (This, Item, Column) -> integer()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxlistctrl.html#wxlistctrlcreate">external documentation</a>.
+-spec create(This, Parent, [Option]) -> wxListCtrl() when
+ This::wxWindow:wxWindow(),
+ Parent::wxWindow:wxWindow(),
+ Option::{winid, integer()} |
+ {pos, {X::integer(),Y::integer()}} |
+ {size, {W::integer(),H::integer()}} |
+ {style, integer()} |
+ {validator, wx:wx_object()} |
+ {onGetItemText, function()} |
+ {onGetItemAttr, function()} |
+ {onGetItemColumnImage, function()}.
+
create(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef}, Options)
when is_list(Options) ->
?CLASS(ThisT,wxListCtrl),
diff --git a/lib/wx/src/gen/wxXmlResource.erl b/lib/wx/src/gen/wxXmlResource.erl
index ae02c74751..aa65b8b04e 100644
--- a/lib/wx/src/gen/wxXmlResource.erl
+++ b/lib/wx/src/gen/wxXmlResource.erl
@@ -334,8 +334,6 @@ unload(#wx_ref{type=ThisT,ref=ThisRef},Filename)
<<ThisRef:32/?UI,(byte_size(Filename_UC)):32/?UI,(Filename_UC)/binary, 0:(((8- ((0+byte_size(Filename_UC)) band 16#7)) band 16#7))/unit:8>>).
-%% @spec (Window::wxWindow:wxWindow(),Name::string(), Type::atom()) -> wx:wxObject()
-
%% @doc Looks up a control with Name in a window created with XML
%% resources. You can use it to set/get values from controls.
%% The object is type casted to <b>Type</b>.
@@ -345,6 +343,10 @@ unload(#wx_ref{type=ThisT,ref=ThisRef},Filename)
%% true = wxXmlResource:loadDialog(Xrc, Dlg, Frame, "controls_dialog"), <br />
%% LCtrl = xrcctrl(Dlg, "controls_listctrl", wxListCtrl), <br />
%% wxListCtrl:insertColumn(LCtrl, 0, "Name", [{width, 200}]), <br />
+-spec xrcctrl(Window, Name, Type) -> wx:wx_object() when
+ Window::wxWindow:wxWindow(),
+ Name::string(),
+ Type::atom().
xrcctrl(Window = #wx_ref{}, Name, Type) when is_list(Name), is_atom(Type) ->
%% Func Id ?wxXmlResource_xrcctrl
diff --git a/lib/wx/src/wx_object.erl b/lib/wx/src/wx_object.erl
index 40ee308358..40170b6eb1 100644
--- a/lib/wx/src/wx_object.erl
+++ b/lib/wx/src/wx_object.erl
@@ -55,7 +55,7 @@
%% When stop is returned in one of the functions above with Reason =
%% normal | shutdown | Term, terminate(State) is called. It lets the
%% user module clean up, it is always called when server terminates or
-%% when wxObject() in the driver is deleted. If the Parent process
+%% when wx_object() in the driver is deleted. If the Parent process
%% terminates the Module:terminate/2 function is called. <br/>
%% terminate(Reason, State)
%%
@@ -171,58 +171,59 @@
%% -----------------------------------------------------------------
-%% @spec (Mod, Args, Options) -> wxWindow:wxWindow()
-%% Mod = atom()
-%% Args = term()
-%% Options = [{timeout, Timeout} | {debug, [Flag]}]
-%% Flag = trace | log | {logfile, File} | statistics | debug
%% @doc Starts a generic wx_object server and invokes Mod:init(Args) in the
%% new process.
+-spec start(Mod, Args, Options) -> wxWindow:wxWindow() | {error, term()} when
+ Mod::atom(),
+ Args::term(),
+ Flag::trace | log | {logfile, string()} | statistics | debug,
+ Options::[{timeout, timeout()} | {debug, [Flag]}].
start(Mod, Args, Options) ->
gen_response(gen:start(?MODULE, nolink, Mod, Args, [get(?WXE_IDENTIFIER)|Options])).
-
-%% @spec (Name, Mod, Args, Options) -> wxWindow:wxWindow()
-%% Name = {local, atom()}
-%% Mod = atom()
-%% Args = term()
-%% Options = [{timeout, Timeout} | {debug, [Flag]}]
-%% Flag = trace | log | {logfile, File} | statistics | debug
+
%% @doc Starts a generic wx_object server and invokes Mod:init(Args) in the
%% new process.
+-spec start(Name, Mod, Args, Options) -> wxWindow:wxWindow() | {error, term()} when
+ Name::{local, atom()},
+ Mod::atom(),
+ Args::term(),
+ Flag::trace | log | {logfile, string()} | statistics | debug,
+ Options::[{timeout, timeout()} | {debug, [Flag]}].
start(Name, Mod, Args, Options) ->
gen_response(gen:start(?MODULE, nolink, Name, Mod, Args, [get(?WXE_IDENTIFIER)|Options])).
-%% @spec (Mod, Args, Options) -> wxWindow:wxWindow()
-%% Mod = atom()
-%% Args = term()
-%% Options = [{timeout, Timeout} | {debug, [Flag]}]
-%% Flag = trace | log | {logfile, File} | statistics | debug
%% @doc Starts a generic wx_object server and invokes Mod:init(Args) in the
%% new process.
+-spec start_link(Mod, Args, Options) -> wxWindow:wxWindow() | {error, term()} when
+ Mod::atom(),
+ Args::term(),
+ Flag::trace | log | {logfile, string()} | statistics | debug,
+ Options::[{timeout, timeout()} | {debug, [Flag]}].
start_link(Mod, Args, Options) ->
gen_response(gen:start(?MODULE, link, Mod, Args, [get(?WXE_IDENTIFIER)|Options])).
-%% @spec (Name, Mod, Args, Options) -> wxWindow:wxWindow()
-%% Name = {local, atom()}
-%% Mod = atom()
-%% Args = term()
-%% Options = [{timeout, Timeout} | {debug, [Flag]}]
-%% Flag = trace | log | {logfile, File} | statistics | debug
%% @doc Starts a generic wx_object server and invokes Mod:init(Args) in the
%% new process.
+-spec start_link(Name, Mod, Args, Options) -> wxWindow:wxWindow() | {error, term()} when
+ Name::{local, atom()},
+ Mod::atom(),
+ Args::term(),
+ Flag::trace | log | {logfile, string()} | statistics | debug,
+ Options::[{timeout, timeout()} | {debug, [Flag]}].
start_link(Name, Mod, Args, Options) ->
gen_response(gen:start(?MODULE, link, Name, Mod, Args, [get(?WXE_IDENTIFIER)|Options])).
-
+
gen_response({ok, Pid}) ->
receive {ack, Pid, Ref = #wx_ref{}} -> Ref end;
gen_response(Reply) ->
Reply.
-%% @spec (Ref::wxObject()|atom()|pid()) -> ok
%% @doc Stops a generic wx_object server with reason 'normal'.
%% Invokes terminate(Reason,State) in the server. The call waits until
%% the process is terminated. If the process does not exist, an
%% exception is raised.
+-spec stop(Obj) -> ok when
+ Obj::wx:wx_object()|atom()|pid().
stop(Ref = #wx_ref{state=Pid}) when is_pid(Pid) ->
try
gen:stop(Pid)
@@ -236,11 +237,14 @@ stop(Name) when is_atom(Name) orelse is_pid(Name) ->
erlang:error({ExitReason, {?MODULE, stop, [Name]}})
end.
-%% @spec (Ref::wxObject()|atom()|pid(), Reason::term(), Timeout::timeout()) -> ok
%% @doc Stops a generic wx_object server with the given Reason.
%% Invokes terminate(Reason,State) in the server. The call waits until
%% the process is terminated. If the call times out, or if the process
%% does not exist, an exception is raised.
+-spec stop(Obj, Reason, Timeout) -> ok when
+ Obj::wx:wx_object()|atom()|pid(),
+ Reason::term(),
+ Timeout::timeout().
stop(Ref = #wx_ref{state=Pid}, Reason, Timeout) when is_pid(Pid) ->
try
gen:stop(Pid, Reason, Timeout)
@@ -254,12 +258,14 @@ stop(Name, Reason, Timeout) when is_atom(Name) orelse is_pid(Name) ->
erlang:error({ExitReason, {?MODULE, stop, [Name, Reason, Timeout]}})
end.
-%% @spec (Ref::wxObject()|atom()|pid(), Request::term()) -> term()
%% @doc Make a call to a wx_object server.
%% The call waits until it gets a result.
%% Invokes handle_call(Request, From, State) in the server
+-spec call(Obj, Request) -> term() when
+ Obj::wx:wx_object()|atom()|pid(),
+ Request::term().
call(Ref = #wx_ref{state=Pid}, Request) when is_pid(Pid) ->
- try
+ try
{ok,Res} = gen:call(Pid, '$gen_call', Request, infinity),
Res
catch _:Reason ->
@@ -272,10 +278,13 @@ call(Name, Request) when is_atom(Name) orelse is_pid(Name) ->
catch _:Reason ->
erlang:error({Reason, {?MODULE, call, [Name, Request]}})
end.
-
-%% @spec (Ref::wxObject()|atom()|pid(), Request::term(), Timeout::integer()) -> term()
+
%% @doc Make a call to a wx_object server with a timeout.
%% Invokes handle_call(Request, From, State) in server
+-spec call(Obj, Request, Timeout) -> term() when
+ Obj::wx:wx_object()|atom()|pid(),
+ Request::term(),
+ Timeout::integer().
call(Ref = #wx_ref{state=Pid}, Request, Timeout) when is_pid(Pid) ->
try
{ok,Res} = gen:call(Pid, '$gen_call', Request, Timeout),
@@ -291,10 +300,11 @@ call(Name, Request, Timeout) when is_atom(Name) orelse is_pid(Name) ->
erlang:error({Reason, {?MODULE, call, [Name, Request, Timeout]}})
end.
-%% @spec (Ref::wxObject()|atom()|pid(), Request::term()) -> ok
%% @doc Make a cast to a wx_object server.
%% Invokes handle_cast(Request, State) in the server
-
+-spec cast(Obj, Request) -> ok when
+ Obj::wx:wx_object()|atom()|pid(),
+ Request::term().
cast(#wx_ref{state=Pid}, Request) when is_pid(Pid) ->
Pid ! {'$gen_cast',Request},
ok;
@@ -302,21 +312,23 @@ cast(Name, Request) when is_atom(Name) orelse is_pid(Name) ->
Name ! {'$gen_cast',Request},
ok.
-%% @spec (Ref::wxObject()) -> pid()
%% @doc Get the pid of the object handle.
+-spec get_pid(Obj) -> pid() when
+ Obj::wx:wx_object()|atom()|pid().
get_pid(#wx_ref{state=Pid}) when is_pid(Pid) ->
Pid.
-%% @spec (Ref::wxObject(), pid()) -> wxObject()
%% @doc Sets the controlling process of the object handle.
+-spec set_pid(Obj, pid()) -> wx:wx_object() when
+ Obj::wx:wx_object()|atom()|pid().
set_pid(#wx_ref{}=R, Pid) when is_pid(Pid) ->
R#wx_ref{state=Pid}.
%% -----------------------------------------------------------------
%% Send a reply to the client.
%% -----------------------------------------------------------------
-%% @spec (From::tuple(), Reply::term()) -> pid()
%% @doc Get the pid of the object handle.
+-spec reply({pid(), Tag::term()}, Reply::term()) -> pid().
reply({To, Tag}, Reply) ->
catch To ! {Tag, Reply}.