File: //usr/lib/erlang/lib/wx-2.2/src/wxe_util.erl
%%
%% %CopyrightBegin%
%%
%% Copyright Ericsson AB 2008-2022. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
%%
%% http://www.apache.org/licenses/LICENSE-2.0
%%
%% Unless required by applicable law or agreed to in writing, software
%% distributed under the License is distributed on an "AS IS" BASIS,
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
%% %CopyrightEnd%
%%%-------------------------------------------------------------------
%%% File : wxe_util.erl
%%% Author : Dan Gudmundsson <dgud@erix.ericsson.se>
%%% Description :
%%%
%%% Created : 9 Feb 2007 by Dan Gudmundsson <dgud@erix.ericsson.se>
%%%-------------------------------------------------------------------
%% @hidden
-module(wxe_util).
-export([register_pid/1,rec/1,
connect_cb/2,disconnect_cb/2,
color/1,
get_cbId/1,
setup_consts/0, get_const/1, get_name/2]).
-export([queue_cmd/1,queue_cmd/2,queue_cmd/3,queue_cmd/4,queue_cmd/5,
queue_cmd/6,queue_cmd/7,queue_cmd/8,queue_cmd/9,queue_cmd/10,
queue_cmd/11,queue_cmd/12,queue_cmd/13,queue_cmd/14,queue_cmd/15,
make_env/0, delete_env/1, get_consts/0,
debug_ping/0, debug_driver/1,
init_opengl/1
]).
-nifs([queue_cmd/1,queue_cmd/2,queue_cmd/3,queue_cmd/4,queue_cmd/5,
queue_cmd/6,queue_cmd/7,queue_cmd/8,queue_cmd/9,queue_cmd/10,
queue_cmd/11,queue_cmd/12,queue_cmd/13,queue_cmd/14,queue_cmd/15,
make_env/0, delete_env/1, debug_driver/1, get_consts_impl/0,
init_opengl/1
]).
-export([priv_dir/2, opt_error_log/3, init_nif/1]).
-include("wxe.hrl").
-define(NIF_ERROR, erlang:nif_error({nif_not_loaded,{?MODULE,?FUNCTION_NAME,?FUNCTION_ARITY},
{line,?LINE}})).
init_nif(Silent) ->
{PrivDir, NifDir} = priv_dir("wxe_driver", Silent),
os:putenv("WX_PRIV_DIR", unicode:characters_to_list(PrivDir)),
erlang:load_nif(filename:join(NifDir, "wxe_driver"), 0).
color({R,G,B}) -> {R,G,B,255};
color(RGBA) -> RGBA.
get_name(Where, Id) when is_atom(Where), is_integer(Id) ->
{_Atom2Id, EnumId2Atom} = persistent_term:get(wx_consts),
maps:get(Id, maps:get(Where, EnumId2Atom, undefined), undefined).
get_const(Atom) when is_atom(Atom) ->
{Atom2Id, _EnumId2Atom} = persistent_term:get(wx_consts),
maps:get(Atom, Atom2Id).
setup_consts() ->
All = get_consts(),
Atom2Int = [{Key,Val} || {_Enum, Key, Val} <- All],
EKV = [{Enum, {Key,Val}} || {Enum, Key, Val} <- All],
Families = sofs:to_external(sofs:relation_to_family(sofs:relation(EKV))),
MakeId2Enum = fun(List) -> maps:from_list([{V,Key} || {Key,V} <- List]) end,
FamMaps = [{Enum, MakeId2Enum(KeyList)} || {Enum,KeyList} <- Families, Enum =/= define, Enum =/= global],
persistent_term:put(wx_consts, {maps:from_list(Atom2Int), maps:from_list(FamMaps)}),
ok.
get_consts() ->
get_consts_impl(),
rec(?WXE_GET_CONSTS).
init_opengl(_) -> ?NIF_ERROR.
get_consts_impl() -> ?NIF_ERROR.
debug_ping() -> queue_cmd(?WXE_DEBUG_PING).
debug_driver(_Level) -> ?NIF_ERROR.
make_env() -> ?NIF_ERROR.
delete_env(_EnvRef) -> ?NIF_ERROR.
queue_cmd(_) -> ?NIF_ERROR.
queue_cmd(_,_) -> ?NIF_ERROR.
queue_cmd(_,_,_) -> ?NIF_ERROR.
queue_cmd(_,_,_,_) -> ?NIF_ERROR.
queue_cmd(_,_,_,_,_) -> ?NIF_ERROR.
queue_cmd(_,_,_,_,_,_) -> ?NIF_ERROR.
queue_cmd(_,_,_,_,_,_,_) -> ?NIF_ERROR.
queue_cmd(_,_,_,_,_,_,_,_) -> ?NIF_ERROR.
queue_cmd(_,_,_,_,_,_,_,_,_) -> ?NIF_ERROR.
queue_cmd(_,_,_,_,_,_,_,_,_,_) -> ?NIF_ERROR.
queue_cmd(_,_,_,_,_,_,_,_,_,_,_) -> ?NIF_ERROR.
queue_cmd(_,_,_,_,_,_,_,_,_,_,_,_) -> ?NIF_ERROR.
queue_cmd(_,_,_,_,_,_,_,_,_,_,_,_,_) -> ?NIF_ERROR.
queue_cmd(_,_,_,_,_,_,_,_,_,_,_,_,_,_) -> ?NIF_ERROR.
queue_cmd(_,_,_,_,_,_,_,_,_,_,_,_,_,_,_) -> ?NIF_ERROR.
rec(Op) ->
receive
{'_wxe_result_', Res} -> Res;
{'_wxe_error_', Op, MFA, Error} ->
erlang:error({Error, MFA});
{'_wxe_error_', Op, {M,F,A}, Error} ->
Msg = io_lib:format("~p in ~w:~w/~w", [Error, M, F, A]),
wxe_master ! {wxe_driver, error, Msg},
rec(Op)
end.
register_pid(#wx_ref{ref=Index}) ->
queue_cmd(Index, ?get_env(), ?WXE_REGISTER_OBJECT),
rec(?WXE_REGISTER_OBJECT).
get_cbId(Fun) ->
gen_server:call((wx:get_env())#wx_env.sv,{register_cb, Fun}, infinity).
connect_cb(Object,EvData0 = #evh{cb=Callback}) ->
Server = (wx:get_env())#wx_env.sv,
case Callback of
0 -> %% Message api connect from this process
case wxEvtHandler:connect_impl(Object,EvData0) of
{ok, Listener} ->
EvData = EvData0#evh{handler=Listener, userdata=undefined},
gen_server:call(Server, {connect_cb,Object,EvData}, infinity);
Error ->
Error
end;
_ -> %% callback, fun or pid (pid for wx_object:sync_events masked callbacks)
%% let the server do the connect
gen_server:call(Server, {connect_cb,Object,EvData0}, infinity)
end.
disconnect_cb(Object,EvData) ->
Server = (wx:get_env())#wx_env.sv,
{try_in_order, Handlers} =
gen_server:call(Server, {disconnect_cb,Object,EvData}, infinity),
disconnect(Object, Handlers).
disconnect(Object,[Ev|Evs]) ->
try wxEvtHandler:disconnect_impl(Object,Ev) of
true -> true;
false -> disconnect(Object, Evs);
Error -> Error
catch _:_ ->
false
end;
disconnect(_, []) -> false.
priv_dir(Driver0, Silent) ->
{file, Path} = code:is_loaded(?MODULE),
Priv = case filelib:is_regular(Path) of
true ->
Beam = filename:join(["ebin/",atom_to_list(?MODULE) ++ ".beam"]),
filename:join(strip(Path, Beam), "priv");
false ->
code:priv_dir(wx)
end,
Driver = case os:type() of
{win32,_} ->
Driver0 ++ ".dll";
_ ->
Driver0 ++ ".so"
end,
case file:read_file_info(filename:join(Priv, Driver)) of
{ok, _} ->
{Priv, Priv};
{error, _} ->
SrcPriv = filename:join(Priv, erlang:system_info(system_architecture)),
case file:read_file_info(filename:join(SrcPriv, Driver)) of
{ok, _} ->
{Priv, SrcPriv};
{error, _} ->
opt_error_log(Silent,
"ERROR: Could not find \'~s\' in: ~s~n",
[Driver, Priv]),
erlang:error({load_driver, "No driver found"})
end
end.
strip(Src, Src) ->
[];
strip([H|R], Src) ->
[H| strip(R, Src)].
opt_error_log(false, Format, Args) ->
logger:log(error, Format, Args, #{domain => [wx]});
opt_error_log(true, _Format, _Args) ->
ok.