4
%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
4
%% Copyright Ericsson AB 2008-2011. All Rights Reserved.
6
6
%% The contents of this file are subject to the Erlang Public License,
7
7
%% Version 1.1, (the "License"); you may not use this file except in
8
8
%% compliance with the License. You should have received a copy of the
9
9
%% Erlang Public License along with this software. If not, it can be
10
10
%% retrieved online at http://www.erlang.org/.
12
12
%% Software distributed under the License is distributed on an "AS IS"
13
13
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
14
14
%% the License for the specific language governing rights and limitations
15
15
%% under the License.
18
18
%%%-------------------------------------------------------------------
19
19
%%% File : wxe_server.erl
28
28
-behaviour(gen_server).
31
-export([start/0, init_port/0]).
31
-export([start/0, init_port/0, init_opengl/0]).
33
33
%% gen_server callbacks
34
34
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
35
35
terminate/2, code_change/3]).
38
37
-record(state, {cb_port, %% Callback port and to erlang messages goes via it.
39
38
users, %% List of wx servers, needed ??
40
39
driver}). %% Driver name so wx_server can create it's own port
42
42
-include("gen/wxe_debug.hrl").
43
-include("gen/gl_debug.hrl").
45
44
-define(DRIVER, "wxe_driver").
121
128
process_flag(trap_exit, true),
122
129
DriverWithArgs = DriverName ++ " " ++ code:priv_dir(wx) ++ [0],
124
case catch open_port({spawn, DriverWithArgs},[binary]) of
126
erlang:error({open_port,Err});
128
wx_debug_info = ets:new(wx_debug_info, [named_table]),
129
wx_non_consts = ets:new(wx_non_consts, [named_table]),
130
true = ets:insert(wx_debug_info, wxdebug_table()),
131
true = ets:insert(wx_debug_info, gldebug_table()),
132
spawn_link(fun() -> debug_ping(Port) end),
135
true = ets:insert(wx_non_consts, List)
137
{ok, #state{cb_port=Port, driver=DriverName, users=gb_sets:empty()}}
132
Port = open_port({spawn, DriverWithArgs},[binary]),
133
wx_debug_info = ets:new(wx_debug_info, [named_table]),
134
wx_non_consts = ets:new(wx_non_consts, [named_table]),
135
true = ets:insert(wx_debug_info, wxdebug_table()),
136
spawn_link(fun() -> debug_ping(Port) end),
139
true = ets:insert(wx_non_consts, List)
141
{ok, #state{cb_port=Port, driver=DriverName, users=gb_sets:empty()}}
143
error({Err, "Could not initiate graphics"})
140
146
%%--------------------------------------------------------------------
207
213
%%%%%%%%%%%% INTERNAL %%%%%%%%%%%%%%%%%%%%%%%%
209
%% If you want anything done, do it yourself.
212
Type = erlang:system_info(system_architecture),
213
{file, Path} = code:is_loaded(?MODULE),
214
Priv = case filelib:is_regular(Path) of
216
Beam = filename:join(["ebin/",atom_to_list(?MODULE) ++ ".beam"]),
217
filename:join(strip(Path, Beam), "priv");
222
{ok, Dirs0} = file:list_dir(Priv),
223
Dirs1 = split_dirs(Dirs0),
224
Dirs = lists:reverse(lists:sort(Dirs1)),
226
Best = best_dir(hd(split_dirs([Type])),Dirs, Priv),
227
filename:join(Priv, Best)
229
error_logger:format("WX ERROR: Could not find suitable \'~s\' for ~s in: ~s~n",
230
[?DRIVER, Type, Priv]),
231
erlang:error({load_driver, "No driver found"})
234
best_dir(Dir, Dirs0, Priv) ->
235
Dirs = [{D,D} || D <- Dirs0],
236
best_dir(Dir, Dirs, [], Priv).
238
best_dir(Pre, [{[],_}|R], Acc, Priv) -> %% Empty skip'em
239
best_dir(Pre, R, Acc, Priv);
240
best_dir(Pre, [{Pre,Dir}|R], Acc, Priv) ->
241
Real = dir_app(lists:reverse(Dir)),
242
case file:list_dir(filename:join(Priv,Real)) of
244
case lists:any(fun(File) -> filename:rootname(File) =:= ?DRIVER end, Fs) of
245
true -> Real; %% Found dir and it contains a driver
246
false -> best_dir(Pre, R, Acc, Priv)
249
best_dir(Pre, R, Acc, Priv)
251
best_dir(Pre, [{[_|F],Dir}|R], Acc, Priv) ->
252
best_dir(Pre, R, [{F,Dir}|Acc], Priv);
253
best_dir(_Pre, [], [],_) -> throw(no_dir); %% Nothing found
254
best_dir([_|Pre], [], Acc, Priv) ->
255
best_dir(Pre, lists:reverse(Acc), [], Priv);
256
best_dir([], _, _,_) -> throw(no_dir). %% Nothing found
266
Toks = tokens(Dir,".-"),
267
lists:reverse([ToInt(Str) || Str <- Toks])
269
lists:map(Split,Dirs0).
272
dir_app([Dir]) -> Dir;
275
dir_app2([Int]) when is_integer(Int) ->
276
integer_to_list(Int);
277
dir_app2([Str]) when is_list(Str) ->
279
dir_app2([Head|Rest]) when is_integer(Head) ->
280
integer_to_list(Head) ++ dir_app2(Rest);
281
dir_app2([Head|Rest]) when is_list(Head) ->
282
Head ++ dir_app2(Rest).
290
215
debug_ping(Port) ->
291
216
timer:sleep(1*333),
292
217
_R = (catch erlang:port_call(Port, 0, [])),
293
218
%% io:format("Erlang ping ~p ~n", [_R]),
294
219
debug_ping(Port).
297
tokens1(S, Seps, []).
299
tokens1([C|S], Seps, Toks) ->
300
case lists:member(C, Seps) of
301
true -> tokens1(S, Seps, [[C]|Toks]);
302
false -> tokens2(S, Seps, Toks, [C])
304
tokens1([], _Seps, Toks) ->
307
tokens2([C|S], Seps, Toks, Cs) ->
308
case lists:member(C, Seps) of
309
true -> tokens1(S, Seps, [[C], lists:reverse(Cs) |Toks]);
310
false -> tokens2(S, Seps, Toks, [C|Cs])
312
tokens2([], _Seps, Toks, Cs) ->
313
lists:reverse([lists:reverse(Cs)|Toks]).