4
%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
6
%% The contents of this file are subject to the Erlang Public License,
7
%% Version 1.1, (the "License"); you may not use this file except in
8
%% compliance with the License. You should have received a copy of the
9
%% Erlang Public License along with this software. If not, it can be
10
%% retrieved online at http://www.erlang.org/.
12
%% Software distributed under the License is distributed on an "AS IS"
13
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
14
%% the License for the specific language governing rights and limitations
19
%%%-------------------------------------------------------------------
20
%%% File : wx_gen_cpp.erl
21
%%% Author : Dan Gudmundsson <dgud@erix.ericsson.se>
24
%%% Created : 19 Feb 2007 by Dan Gudmundsson <dgud@erix.ericsson.se>
25
%%%-------------------------------------------------------------------
28
-include("wx_gen.hrl").
32
-import(lists, [foldl/3,foldr/3,reverse/1, keysearch/3, map/2, filter/2]).
33
-import(gen_util, [lowercase/1, lowercase_all/1, uppercase/1, uppercase_all/1,
34
open_write/1, close/0, c_copyright/0, w/2, w/1,
35
args/3, strip_name/2]).
36
-import(wx_gen, [next_id/1]).
39
open_write("../c_src/gen/wxe_derived_dest.h"),
41
w("~n/***** This file is generated do not edit ****/ ~n~n", []),
42
gen_derived_dest(Defs),
45
open_write("../c_src/gen/wxe_funcs.cpp"),
47
Res = gen_funcs(Defs),
50
open_write("../c_src/gen/wxe_macros.h"),
55
open_write("../c_src/gen/wxe_init.cpp"),
63
gen_derived_dest(Defs) ->
64
[gen_derived_dest_2(Class) || Class <- Defs],
66
UglySkipList = ["wxCaret", "wxCalendarDateAttr",
67
"wxFileDataObject", "wxTextDataObject", "wxBitmapDataObject"
70
?WTC("gen_derived_dest"),
71
w("void WxeApp::delete_object(void *ptr, wxeRefData *refd) {~n", []),
72
w(" switch(refd->type) {~n", []),
73
Case = fun(#class{name=Class, id=Id, abstract=IsAbs, parent=P}) when P /= "static" ->
74
UglyWorkaround = lists:member(Class, UglySkipList),
75
case hd(reverse(wx_gen_erl:parents(Class))) of
76
root when IsAbs == false, UglyWorkaround == false ->
77
w(" case ~p: delete (~s *) ptr; break;~n", [Id, Class]);
78
root when IsAbs == false, UglyWorkaround == true ->
79
w(" case ~p: /* delete (~s *) ptr;"
80
"These objects must be deleted by owner object */ "
81
"break;~n", [Id, Class]);
86
[Case(Class) || Class <- Defs],
87
w(" default: delete (wxObject *) ptr;~n", []),
90
gen_derived_dest_2(C=#class{name=Class}) ->
93
?WTC("gen_derived_dest_2"),
94
w("class E~s : public ~s { ~n",[Class,Class]),
96
"wxGLCanvas" -> %% Special for cleaning up gl context
97
w(" public: ~~E~s() {deleteActiveGL(this);"
98
"((WxeApp *)wxTheApp)->clearPtr(this);}; ~n", [Class]);
100
w(" public: ~~E~s() {((WxeApp *)wxTheApp)->clearPtr(this);}; ~n", [Class])
108
gen_constructors(#class{name=Class, methods=Ms0}) ->
109
Ms = lists:append(Ms0),
110
Cs = lists:filter(fun(#method{method_type=MT}) -> MT =:= constructor end, Ms),
111
[gen_constructor(Class, Const) || Const <- Cs].
113
gen_constructor(_Class, #method{where=merged_c}) -> ok;
114
gen_constructor(_Class, #method{where=erl_no_opt}) -> ok;
115
gen_constructor(Class, _M=#method{params=Ps}) ->
116
Gen1 = fun(#param{name=N, type=T}) -> gen_type(T,1) ++ N end,
117
Gen2 = fun(#param{name=N, type=T}) -> gen_type(T,2) ++ N end,
118
CallA = fun(#param{name=N}) -> N end,
119
HaveMergedType = fun(#param{type={merged,_,_,_,_,_,_}}) -> true; (_) -> false end,
120
?WTC("gen_constructor"),
121
case lists:any(HaveMergedType, Ps) of
123
w(" E~s(~s) : ~s(~s) {};~n",
124
[Class,args(Gen1,",",Ps),Class,args(CallA,",",Ps)]);
126
w(" E~s(~s) : ~s(~s) {};~n",
127
[Class,args(Gen1,",",Ps),Class,args(CallA,",",Ps)]),
128
w(" E~s(~s) : ~s(~s) {};~n",
129
[Class,args(Gen2,",",Ps),Class,args(CallA,",",Ps)])
132
gen_type(#type{name=Type, ref={pointer,1}, mod=Mod},_) ->
133
mods(Mod) ++ to_string(Type) ++ " * ";
134
gen_type(#type{name=Type, ref={pointer,2}, mod=Mod},_) ->
135
mods(Mod) ++ to_string(Type) ++ " ** ";
136
gen_type(#type{name=Type, ref=reference, mod=Mod},_) ->
137
mods(Mod) ++ to_string(Type) ++ "& ";
138
gen_type(#type{name=Type, ref=undefined, base=binary, mod=Mod},_) ->
139
mods(Mod) ++ to_string(Type) ++ " * ";
140
gen_type(#type{name=Type, ref=undefined, single=array, mod=Mod},_) ->
141
mods(Mod) ++ to_string(Type) ++ " * ";
142
gen_type(#type{name=Type, ref=undefined, mod=Mod},_) ->
143
mods(Mod) ++ to_string(Type) ++ " ";
144
gen_type({merged, _, T1, _,_, _T2,_}, 1) ->
146
gen_type({merged, _, _T1,_, _, T2,_}, 2) ->
150
w("~n/***** This file is generated do not edit ****/ ~n~n"),
151
w("#include <wx/wx.h>~n"),
152
w("#include \"../wxe_impl.h\"~n"),
153
w("#include \"../wxe_events.h\"~n"),
154
w("#include \"../wxe_return.h\"~n"),
155
w("#include \"wxe_macros.h\"~n"),
156
w("#include \"wxe_derived_dest.h\"~n~n"),
158
w("void WxeApp::wxe_dispatch(wxeCommand& Ecmd)~n{~n"),
159
w(" char * bp = Ecmd.buffer; ~n"),
160
w(" wxeMemEnv *memenv = getMemEnv(Ecmd.port);~n"),
161
%% w(" wxMBConvUTF32 UTFconverter;~n"),
162
w(" wxeReturn rt = wxeReturn(WXE_DRV_PORT, Ecmd.caller, true);~n"),
164
w(" switch (Ecmd.op) ~n{~n"),
165
%% w(" case WXE_CREATE_PORT: ~n", []),
166
%% w(" { newMemEnv(Ecmd.port); } break; ~n", []),
167
%% w(" case WXE_REMOVE_PORT: ~n", []),
168
%% w(" { destroyMemEnv(Ecmd.port); } break; ~n", []),
169
w(" case DESTROY_OBJECT: { ~n"),
170
w(" wxObject *This = (wxObject *) getPtr(bp,memenv); "),
172
w(" ((WxeApp *) wxTheApp)->clearPtr((void *) This);~n"),
173
w(" delete This; }~n } break; ~n"),
174
w(" case WXE_REGISTER_OBJECT: {~n"
175
" wxeErlTerm * term = new wxeErlTerm(Ecmd.bin[0]);~n"
176
" registerPid(bp, term, memenv);~n"
177
" rt.addAtom(\"ok\");~n"
181
Res = [gen_class(Class) || Class <- Defs],
184
w(" wxeReturn error = wxeReturn(WXE_DRV_PORT, Ecmd.caller, false);"),
185
w(" error.addAtom(\"_wxe_error_\");~n"),
186
w(" error.addInt((int) Ecmd.op);~n"),
187
w(" error.addAtom(\"undef\");~n"),
188
w(" error.addTupleCount(3);~n"),
193
w("} catch (wxe_badarg badarg) { // try ~n"),
194
w(" wxeReturn error = wxeReturn(WXE_DRV_PORT, Ecmd.caller, false);"),
195
w(" error.addAtom(\"_wxe_error_\");~n"),
196
w(" error.addInt((int) Ecmd.op);~n"),
197
w(" error.addAtom(\"badarg\");~n"),
198
w(" error.addInt((int) badarg.ref);~n"),
199
w(" error.addTupleCount(2);~n"),
200
w(" error.addTupleCount(3);~n"),
201
w(" error.send();~n"),
202
w("}} /* The End */ ~n"),
205
gen_class(C=#class{name=Name,methods=Ms,options=Opts}) ->
206
put(current_class, Name),
208
case lists:member(taylormade, Opts) of
210
{ok, Bin} = file:read_file(filename:join([wx_extra,Name++".c_src"])),
212
w("~s~n", [binary_to_list(Bin)]),
215
case lists:keysearch(ifdef,1,Opts) of
216
{value, {ifdef, What}} ->
217
w("#if ~p~n",[What]),
218
Methods = lists:flatten(Ms),
219
MsR = [gen_method(Name,M) ||
220
M <- lists:keysort(#method.id, Methods)],
221
w("#endif // ~p~n",[What]),
224
Methods = lists:flatten(Ms),
225
[gen_method(Name,M) ||
226
M <- lists:keysort(#method.id, Methods)]
229
erase(current_class),
230
C#class{methods=NewMs}.
232
%%gen_methods(ClassName, Ms) ->
233
%% [gen_method(ClassName, M) || M <- Ms].
235
gen_method(_CName, M=#method{where=erl_no_opt}) -> M;
236
gen_method(CName, M=#method{where=taylormade, name=Name, id=Id}) ->
237
{ok, Bin} = file:read_file(filename:join([wx_extra, CName ++".c_src"])),
238
Str0 = binary_to_list(Bin),
239
%% io:format("C++ Class ~p ~p ~n", [CName, Name]),
240
{match, Start, Len} = regexp:first_match(Str0, "<<" ++ Name),
241
{match, End, _} = regexp:first_match(Str0, Name ++ ">>"),
242
Str1 = string:substr(Str0, Start+Len, End-Start-Len),
243
%% {ok, Str, _} = regexp:sub(Str1, "FUNCID", integer_to_list(Id)),
245
w(Str1, [wx_gen_erl:get_unique_name(Id)]),
247
gen_method(CName, M=#method{name=N,params=[Ps],method_type=destructor,id=MethodId}) ->
248
case hd(reverse(wx_gen_erl:parents(CName))) of
251
w("case ~s: { // ~s::~s ~n", [wx_gen_erl:get_unique_name(MethodId),CName,N]),
252
decode_arguments([Ps]),
253
w(" if(This) {", []),
254
w(" ((WxeApp *) wxTheApp)->clearPtr((void *) This);~n", []),
255
w(" delete This;}~n", []),
257
w(" break; ~n}~n", []);
258
object -> %% Use default
262
gen_method(CName, M=#method{name=N,params=Ps0,type=T,method_type=MT,id=MethodId}) ->
263
put(current_func, N),
266
w("case ~s: { // ~s::~s ~n", [wx_gen_erl:get_unique_name(MethodId),CName,N]),
267
Ps1 = declare_variables(void, Ps0),
268
{Ps2,Align} = decode_arguments(Ps1),
269
Opts = [Opt || Opt = #param{def=Def,in=In,where=Where} <- Ps2,
270
Def =/= none, In =/= false, Where =/= c],
271
decode_options(Opts, Align),
272
case M#method.pre_hook of
274
Pre -> w(" ~s;~n", [Pre])
276
Ps3 = call_wx(N,{MT,CName},T,Ps2),
277
case M#method.post_hook of
279
Post -> w(" ~s;~n", [Post])
282
build_return_vals(T,Ps3),
283
w(" break; ~n}~n", []),
287
declare_variables(void,Ps) ->
288
[declare_var(P) || P <- Ps];
289
declare_variables(T, Ps) ->
290
declare_type("result", out, ignore, T),
291
[declare_var(P) || P <- Ps].
293
declare_var(P = #param{where=erl}) -> P;
294
declare_var(P = #param{where=this}) -> P;
295
declare_var(P = #param{name=Name,def=Def,type=Type,in=true}) when Def =/= none ->
296
declare_type(Name, true, Def, Type),
298
declare_var(P = #param{in=In}) when In =/= false -> P;
299
declare_var(P = #param{name=Name,in=In,def=Def,type=Type}) ->
300
declare_type(Name, In, Def, Type),
303
declare_type(N,false,_,#type{name="wxArrayInt"}) ->
304
w(" wxArrayInt ~s;~n", [N]);
305
declare_type(N,false,_,#type{name="wxArrayString"}) ->
306
w(" wxArrayString ~s;~n", [N]);
307
declare_type(N,false,_,#type{base=Base,single=true,name=Type,by_val=false,mod=Mod})
308
when Base =:= int; Base =:= long; Base =:= float; Base =:= double ->
309
w(" ~s~s ~s;~n", [mods(Mod),Type,N]);
310
declare_type(N,false,_,#type{base={enum,_},single=true,name=Type,by_val=false,mod=Mod}) ->
311
w(" ~s~s ~s;~n", [mods(Mod),Type,N]);
312
declare_type(N,false,_,#type{name="wxArrayTreeItemIds",ref=reference}) ->
313
w(" wxArrayTreeItemIds ~s;~n", [N]);
314
declare_type(N,false,_,#type{name="wxDateTime"}) ->
315
w(" wxDateTime ~s;~n", [N]);
316
declare_type(N,true,Def,#type{base=Base,single=true,name=Type,by_val=true})
317
when Base =:= int; Base =:= long; Base =:= float; Base =:= double; Base =:= bool ->
318
w(" ~s ~s=~s;~n", [Type,N,Def]);
319
declare_type(N,true,Def,#type{base={comp,_,_},single=true,name=Type,mod=Mod,ref={pointer,1}}) ->
320
w(" ~s~s *~s=~s; ~s ~s;~n", [mods(Mod),Type,N,Def,Type,N++"Tmp"]);
321
declare_type(N,true,Def,#type{base={comp,_,_},single=true,name=Type,ref=reference}) ->
322
w(" ~s ~s= ~s;~n", [Type,N,Def]);
323
declare_type(N,true,Def,#type{base={enum,Type},single=true}) ->
324
w(" ~s ~s=~s;~n", [enum_type(Type),N,Def]);
325
declare_type(N,true,Def,#type{base={class,_},single=true,name=Type,ref={pointer,1},mod=Mod}) ->
326
w(" ~s~s * ~s=~s;~n", [mods(Mod),Type,N,Def]);
327
declare_type(N,true,Def,#type{base={class,_},single=true,name=Type,ref=reference,mod=Mod}) ->
328
w(" ~s~s * ~s= &~s;~n", [mods(Mod),Type,N,Def]);
329
declare_type(N,true,Def,#type{base=Base,single=true,name=Type,by_val=false,ref={pointer,1}})
330
when Base =:= int; Base =:= long; Base =:= float; Base =:= double; Base =:= bool ->
331
w(" ~s *~s=~s;~n", [Type,N,Def]);
332
declare_type(N,true,Def,#type{single=true,name="wxString"}) ->
333
w(" wxString ~s= ~s;~n", [N,Def]);
334
declare_type(N,true,Def,#type{single=true,name="wxArtClient"}) ->
335
w(" wxArtClient ~s= ~s;~n", [N,Def]);
336
%% declare_type(N,true,_Def,#type{name="wxString"}) ->
337
%% w(" wxString ~s= wxEmptyString;~n", [N]);
338
declare_type(N,true,Def,#type{base=binary, name=char}) ->
339
w(" char ~sD[] = {~s}, * ~s = ~sD;~n", [N,Def,N,N]);
340
declare_type(_N,true,_Def,void) ->
342
declare_type(N,true,Def,#type{name=Type, ref={pointer,2}}) ->
344
w(" ~s ** ~s = ~s;~n", [Type,N,Def]);
345
declare_type(N,true,Def,#type{name=Type, single=array, ref={pointer,1}}) ->
346
w(" int * ~sLen = 0;~n", [N]),
347
w(" ~s * ~s = ~s;~n", [Type,N,Def]);
348
declare_type(N,true,"",#type{name="wxArrayString", single=array, ref=reference}) ->
349
w(" wxArrayString ~s;~n", [N]);
350
declare_type(N,true,Def,#type{name=Type, base={term,_}}) ->
351
w(" ~s * ~s= ~s;~n", [Type,N,Def]);
352
declare_type(N,In,Def,T) ->
353
?error({unhandled_type, {N,In,Def,T}}).
355
decode_options([], _Align) -> ok;
356
decode_options(Opts, Align) ->
358
w(" while( * (int*) bp) { switch (* (int*) bp) { ~n", []),
359
foldl(fun decode_opt/2, 1, Opts),
362
decode_opt(#param{name=Name,type=Type}, N) ->
363
w(" case ~p: {bp += 4;~n", [N]),
364
Align = decode_arg(Name,Type,opt,1),
366
w(" } break;~n", []),
369
decode_arguments(Ps0) ->
370
lists:mapfoldl(fun decode_arg/2,0,Ps0).
373
case get(free_args) of
374
undefined -> put(free_args, [N]);
375
List -> put(free_args, [N|List])
379
case get(free_args) of
383
[w(" driver_free(~s);~n", [Arg]) || Arg <- List]
386
decode_arg(P = #param{where=erl},A) -> {P,A};
387
decode_arg(P = #param{where=c},A) -> {P,A};
388
decode_arg(P = #param{in=false},A) -> {P,A};
389
decode_arg(P = #param{def=Def},A) when Def =/= none -> {P,A};
390
decode_arg(P = #param{name=Name,type=Type},A0) ->
391
A = decode_arg(Name, Type, arg, A0),
394
wa(Decl,DA,Get,GetA,arg) ->
397
wa(_Decl,_DA,Get,GetA,opt) ->
400
decode_arg(N,#type{name=Class,base={class,_},single=true},Arg,A0) ->
402
wa(" ~s *",[Class],"~s = (~s *) getPtr(bp,memenv); bp += 4;~n",[N,Class],Arg),
404
decode_arg(N,{merged,_,#type{name=Class,base={class,_},single=true},_,_,_,_},arg,A0) ->
406
w(" ~s * ~s = (~s *) getPtr(bp,memenv); bp += 4;~n", [Class,N,Class]),
408
decode_arg(N,#type{base=long,single=true,name=Type},arg,A0) ->
410
w(" long * ~s = (~s *) bp; bp += 8;~n", [N,Type]),
412
decode_arg(N,#type{base=int,single=true,mod=Mod0,name=Type},Arg,A0) ->
415
arg -> w(" ~s~s * ~s = (~s~s *) bp; bp += 4;~n", [Mod,int,N,Mod,int]);
416
opt -> w(" ~s = (~s)*(~s~s *) bp; bp += 4;~n", [N,Type,Mod,int])
419
decode_arg(N,#type{base=float,single=true,name=Type},arg,A0) ->
420
w(" ~s * ~s = (~s *) bp; bp += 4;~n", [Type,N,Type]),
422
decode_arg(N,#type{base=double,single=true,name=Type},Arg,A0) ->
425
arg -> w(" ~s * ~s = (~s *) bp; bp += 8;~n", [Type,N,Type]);
426
opt -> w(" ~s = * (~s *) bp; bp += 8;~n", [N,Type])
429
decode_arg(N,#type{base=bool,single=true,name=Type},Arg,A0) ->
431
arg -> w(" bool * ~s = (~s *) bp; bp += 4;~n", [N,Type]);
432
opt -> w(" ~s = *(~s *) bp; bp += 4;~n", [N,Type])
435
decode_arg(N,#type{base={enum,Type},single=true},Arg,A0) ->
436
wa(" ~s ", [enum_type(Type)], "~s = *(~s *) bp; bp += 4;;~n",[N, enum_type(Type)], Arg),
438
decode_arg(N,#type{base={comp,"wxDateTime",List},single=true,name=Type,ref=Ref},Arg,A0) ->
439
Decl = fun({int,Spec}) ->
440
w(" int * ~s~s = (int *) bp; bp += 4;~n", [N,Spec])
443
lists:foreach(Decl,List),
444
Name = fun({_,"Mo"}) -> "(wxDateTime::Month) *"++N++"Mo";
445
({_,"Y"}) -> "*"++N++"Y";
446
({_,Spec}) -> "(wxDateTime::wxDateTime_t) *"++N++Spec
449
arg -> w(" ~s ~s = ~s(~s);~n", [Type,N,Type,args(Name, ",", List)]);
450
opt when Ref =:= {pointer,1} ->
451
w(" ~sTmp = ~s(~s); ~s = & ~sTmp;~n",
452
[N,Type,args(Name, ",", List), N,N]);
454
w(" ~s = ~s(~s);~n", [N,Type,args(Name, ",", List)])
456
(A0+length(List)) rem 2;
457
decode_arg(N,#type{base={comp,_,List},single=true,name=Type,ref=Ref},Arg,A0) ->
458
Decl = fun({int,Spec}) ->
459
w(" int * ~s~s = (int *) bp; bp += 4;~n", [N,Spec]);
461
w(" wxDouble * ~s~s = (wxDouble *) bp; bp += 8;~n", [N,Spec])
464
{int, _} -> align(A0,32);
465
{double, _} -> align(A0,64)
467
lists:foreach(Decl,List),
468
Name = fun({_,Spec}) -> "*"++N++Spec end,
470
arg -> w(" ~s ~s = ~s(~s);~n", [Type,N,Type,args(Name, ",", List)]);
471
opt when Ref =:= {pointer,1} ->
472
w(" ~sTmp = ~s(~s); ~s = & ~sTmp;~n",
473
[N,Type,args(Name, ",", List), N,N]);
475
w(" ~s = ~s(~s);~n", [N,Type,args(Name, ",", List)])
478
{int, _} -> (A0+length(List)) rem 2;
482
decode_arg(N,#type{name=Class,base={ref,"wxTreeItemId"},single=true},Arg,A0) ->
484
wa(" ~s ",[Class],"~s = wxTreeItemId(getPtr(bp,memenv)); bp += 4;~n",[N],Arg),
486
decode_arg(N,#type{name="wxChar", single=S},Arg,A0)
488
w(" int * ~sLen = (int *) bp; bp += 4;~n", [N]),
489
wa(" wxString", []," ~s = wxString(bp, wxConvUTF8);~n", [N],Arg),
490
w(" bp += *~sLen+((8-((~p+ *~sLen) & 7)) & 7);~n", [N,4*((A0+1) rem 2),N]),
492
decode_arg(N,#type{base=[int], name=Name},Arg,A0)
493
when Name =:= "wxString"; Name =:= "wxArtClient" ->
494
w(" int * ~sLen = (int *) bp; bp += 4;~n", [N]),
495
wa(" wxString", []," ~s = wxString(bp, wxConvUTF8);~n", [N],Arg),
496
w(" bp += *~sLen+((8-((~p+ *~sLen) & 7)) & 7);~n", [N,4*((A0+1) rem 2),N]),
498
decode_arg(N,#type{name="wxArrayString"},Place,A0) ->
499
w(" int * ~sLen = (int *) bp; bp += 4;~n", [N]),
501
arg -> w(" wxArrayString ~s;~n", [N]);
502
opt -> ignore %% Allready declared
504
w(" int ~sASz = 0, * ~sTemp;~n", [N,N]),
505
w(" for(int i=0; i < *~sLen; i++) {~n", [N]),
506
w(" ~sTemp = (int *) bp; bp += 4;~n", [N]),
507
w(" ~s.Add(wxString(bp, wxConvUTF8));~n", [N]),
508
w(" bp += *~sTemp;~n", [N]),
509
w(" ~sASz += *~sTemp+4;~n }~n", [N,N]),
510
w(" bp += (8-((~p+ ~sASz) & 7 )) & 7;~n", [4*((A0+1) rem 2),N]),
513
decode_arg(N,#type{name="wxArrayInt"},arg,A0) ->
514
w(" int * ~sLen = (int *) bp; bp += 4;~n", [N]),
515
w(" wxArrayInt ~s;~n", [N]),
516
w(" for(int i=0; i < *~sLen; i++) {", [N]),
517
w(" ~s.Add(*(int *) bp); bp += 4;}~n", [N]),
518
w(" bp += ((*~sLen + ~p) % 2 )*4;~n",[N, (A0+1)]),
520
decode_arg(N,#type{name="wxArrayDouble"},arg,A0) ->
521
w(" int * ~sLen = (int *) bp; bp += 4;~n", [N]),
523
w(" wxArrayDouble ~s;~n", [N]),
524
w(" for(int i=0; i < *~sLen; i++) {", [N]),
525
w(" ~s.Add(*(int *) bp); bp += 4;}~n", [N]),
527
decode_arg(_N,#type{base=eventType},_Arg,A0) ->
528
%% w(" int * ~sLen = (int *) bp; bp += 4;~n", [N]),
531
%% w(" int ~s = wxeEventTypeFromAtom(bp);bp += *~sLen;~n",[N,N]),
532
%% w(" char *class_name = bp;~n", []),
533
%% w(" wxeCallbackData * Evt_cb = new wxeCallbackData(Ecmd.caller,This,class_name);~n",
537
decode_arg(N,#type{name=Type,base=binary,mod=Mod0},Arg,A0) ->
538
Mod = mods([M || M <- Mod0]),
541
w(" ~s~s * ~s = (~s~s*) Ecmd.bin[~p]->base; ~n",
542
[Mod,Type,N,Mod,Type, next_id(bin_count)]);
544
w(" ~s = (~s~s*) Ecmd.bin[~p]->base; ~n",
545
[N,Mod,Type,next_id(bin_count)])
548
decode_arg(N,#type{base={term,"wxTreeItemData"},mod=Mod0},Arg,A0) ->
549
Mod = mods([M || M <- Mod0]),
550
Type = "wxETreeItemData",
551
BinCnt = next_id(bin_count),
554
w(" ~s~s * ~s = new ~s(Ecmd.bin[~p]->size, Ecmd.bin[~p]->base); ~n",
555
[Mod,Type,N,Type,BinCnt,BinCnt]);
557
w(" ~s = new ~s(Ecmd.bin[~p]->size, Ecmd.bin[~p]->base); ~n",
558
[N,Type,BinCnt,BinCnt])
561
decode_arg(N,#type{name=Type,base={term,_},mod=Mod0},Arg,A0) ->
562
Mod = mods([M || M <- Mod0]),
563
BinCnt = next_id(bin_count),
566
w(" ~s~s * ~s = new ~s(Ecmd.bin[~p]); ~n",
567
[Mod,Type,N,Type,BinCnt]);
569
w(" ~s = new ~s(Ecmd.bin[~p]); ~n",
573
decode_arg(N,#type{single=array,base=int},Arg,A0) ->
576
w(" int * ~sLen = (int *) bp; bp += 4;~n", [N]),
577
w(" int * ~s = (int *) bp; bp += *~sLen*4+((~p+ *~sLen)%2 )*4;~n",
578
[N,N,(A0+1) rem 2,N]);
580
w(" ~sLen = (int *) bp; bp += 4;~n", [N]),
581
w(" ~s = (int *) bp; bp += *~sLen*4+((~p+ *~sLen)%2 )*4;~n",
582
[N,N,(A0+1) rem 2,N])
585
decode_arg(N,#type{by_val=true,single=array,base={comp,Class="wxPoint",_}},arg,A0) ->
586
w(" int * ~sLen = (int *) bp; bp += 4;~n", [N]),
587
w(" ~s *~s;~n",[Class,N]),
588
w(" ~s = (~s *) driver_alloc(sizeof(~s) * *~sLen);~n",[N,Class,Class,N]),
590
w(" for(int i=0; i < *~sLen; i++) {~n", [N]),
591
w(" int x = * (int *) bp; bp += 4;~n int y = * (int *) bp; bp += 4;~n", []),
592
w(" ~s[i] = wxPoint(x,y);}~n", [N]),
594
decode_arg(N,#type{by_val=true,single=array,base={class,Class}},arg,A0) ->
596
w(" int * ~sLen = (int *) bp; bp += 4;~n", [N]),
597
w(" ~s *~s;~n",[Class,N]),
598
w(" ~s = (~s *) driver_alloc(sizeof(~s) * *~sLen);", [N, Class, Class, N]),
600
w(" for(int i=0; i < *~sLen; i++) {", [N]),
601
w(" ~s[i] = * (~s *) getPtr(bp,memenv); bp += 4;}~n", [N,Class]),
602
w(" bp += ((~p+ *~sLen)%2 )*4;~n", [A, N]),
604
decode_arg(N,#type{name=Type,single=list,base={class,Class}},arg,A0) ->
605
w(" int * ~sLen = (int *) bp; bp += 4;~n", [N]),
607
w(" ~s ~s;~n",[Type,N]),
608
w(" for(int i=0; i < *~sLen; i++) {", [N]),
609
w(" ~s.Append(*(~s *) getPtr(bp,memenv)); bp += 4;}~n", [N,Class]),
610
w(" bp += ((~p+ *~sLen)%2 )*4;~n", [A,N]),
612
decode_arg(Name,T, Arg,_A) ->
613
?error({unhandled_type, {Name,T, Arg}}).
619
w(" bp += 4; /* Align */~n"),
624
call_wx(_N,{constructor,_},#type{base={class,RClass}},Ps) ->
625
#class{id=Id} = ClassDef = get({class,RClass}),
626
Class = case is_derived(ClassDef) of
627
true -> "E" ++ RClass;
630
w(" ~s * Result = new ~s(~s);~n",
631
[RClass, Class,args(fun call_arg/1, ",",filter(Ps))]),
632
CType = case is_window(RClass) of
633
true -> %% Windows have parents that should be deleted first
634
case is_dialog(RClass) of
635
true -> 2; %% Dialogs must be closed first event before windows
639
case hd(reverse(wx_gen_erl:parents(RClass))) of
644
case virtual_dest(ClassDef) orelse (CType =/= 0) of
646
w(" newPtr((void *) Result, ~p, memenv);~n", [CType]);
647
false -> %% Hmm window without virt dest
648
w(" /* Possible memory leak here, class is missing virt dest */ \n")
651
call_wx(N,{member,_},Type,Ps) ->
652
{Beg,End} = return_res(Type),
653
w(" if(!This) throw wxe_badarg(0);~n",[]),
654
w(" ~sThis->~s(~s)~s;~n",[Beg,N,args(fun call_arg/1, ",",filter(Ps)),End]),
656
call_wx(N,{static,Class},Type,Ps) ->
657
{Beg,End} = return_res(Type),
658
#class{parent=Parent} = get({class,Class}),
661
w(" ~s::~s(~s)~s;~n",[Beg,N,args(fun call_arg/1, ",",filter(Ps)),End]);
663
w(" ~s~s::~s(~s)~s;~n",[Beg,Class,N,args(fun call_arg/1, ",",filter(Ps)),End])
668
return_res(void) -> {"", ""};
669
return_res(Type = #type{mod=Mod}) ->
670
case lists:member(const, Mod) of
672
{Beg, End} = return_res1(Type),
673
{"const " ++ Beg, End};
678
return_res1(#type{name=Type,ref={pointer,_}, base={term,_}}) ->
679
{Type ++ " * Result = (" ++ Type ++ "*)", ""};
680
return_res1(#type{name=Type,ref={pointer,_}}) ->
681
{Type ++ " * Result = (" ++ Type ++ "*)", ""};
682
return_res1(#type{name=Type,single=true,ref=reference}) ->
683
{Type ++ " * Result = &", ""};
684
return_res1(#type{name=Type,single=true,by_val=true})
685
when is_atom(Type) ->
686
{atom_to_list(Type) ++ " Result = ", ""};
687
return_res1(#type{name=Type="wxArrayInt"}) ->
688
{Type ++ " Result = ", ""};
689
return_res1(#type{name=Type,base={class,_},single=list,ref=reference}) ->
690
{Type ++ " Result = ", ""};
691
return_res1(#type{name=Type,base={comp,_,_},single=array,by_val=true}) ->
692
{Type ++ " Result = ", ""};
693
return_res1(#type{name=Type,single=true,by_val=true, base={class, _}}) ->
694
%% Memory leak !!!!!! XXXX BUGBUG FIXME or doument!!
700
"wxGraphics" ++ _ -> ok;
702
io:format("~s::~s Building return value of temp ~s~n",
703
[get(current_class),get(current_func),Type])
705
%% #class{id=Id} = get({class,Type}),
706
{Type ++ " * Result = new " ++ Type ++ "(", "); newPtr((void *) Result,"
708
return_res1(#type{base={enum,_Type},single=true,by_val=true}) ->
709
{"int Result = " , ""};
710
return_res1(#type{name="wxCharBuffer", base={binary,_},single=true,by_val=true}) ->
711
{"char * Result = ", ".data()"};
712
return_res1(#type{name=Type,single=array,ref=reference}) ->
713
{Type ++ " Result = ", ""};
714
return_res1(#type{name=Type,single=true,by_val=true}) ->
715
{Type ++ " Result = ", ""}.
718
lists:filter(fun filter_arg/1, Ps).
719
filter_arg(#param{where=erl}) -> false;
720
filter_arg(#param{where=this}) -> false;
721
filter_arg(#param{}) -> true.
722
%%filter_arg(#param{def=Def, in=In}) -> Def =:= none orelse In =:= false.
725
call_arg(#param{where=c, alt={length,Alt}}) when is_list(Alt) ->
727
call_arg(#param{where=c, alt={size,Id}}) when is_integer(Id) ->
729
"Ecmd.bin["++ integer_to_list(Id) ++ "]->size";
730
call_arg(#param{name=N,def=Def,type=#type{name=Type,by_val=true,single=true,base=Base}})
731
when Base =:= int; Base =:= long; Base =:= float; Base =:= double; Base =:= bool ->
733
none -> "(" ++ to_string(Type) ++ ") *" ++ N;
737
call_arg(#param{name=N,type=#type{base={enum,Type}, by_val=true,single=true}}) ->
738
"(" ++ enum_type(Type) ++") " ++ N;
739
call_arg(#param{name=N,type=#type{base={class,_},by_val=true,single=true}}) -> "*" ++ N;
740
call_arg(#param{name=N,type=#type{base={class,_},ref=reference,single=true}}) -> "*" ++ N;
741
call_arg(#param{name=N,type=#type{base=eventType}}) ->
742
N ++ ", (wxObjectEventFunction)(wxEventFunction) &WxeApp::handle_evt, Evt_cb, this";
743
call_arg(#param{name=N,type=#type{by_val=true, single=_False}}) -> N;
744
call_arg(#param{name=N,def=Def,type=#type{by_val=false, ref={pointer,2}}})
745
when Def =/= none -> N;
746
call_arg(#param{name=N,type=#type{by_val=false, ref={pointer,2}}}) -> "&" ++ N;
747
call_arg(#param{name=N,in=false,type=#type{ref=reference, single=true}}) -> N;
748
call_arg(#param{name=N,in=false,type=#type{by_val=false, single=true}}) -> "&" ++ N;
749
call_arg(#param{name=N,def=Def,type=#type{base={comp,_,_},ref={pointer,1},single=true}})
752
call_arg(#param{name=N,type=#type{by_val=false}}) -> N;
753
call_arg(#param{name=N,type={merged,_,#type{base={class,_},single=true,
756
when ByVal =:= true; Ref =:= reference ->
758
call_arg(#param{def=Def, type=void}) when Def =/= none -> Def;
759
call_arg(#param{name=N,type=#type{base={ref,_},by_val=true,single=true}}) -> N;
760
call_arg(#param{name=N,type={merged,_,_,_,_,_,_}}) -> N.
762
%% call_arg(#param{name=N,type=#type{base=Tuple,ref=reference}})
763
%% when is_tuple(Tuple) -> "&" ++ N;
765
to_string(Type) when is_atom(Type) -> atom_to_list(Type);
766
to_string(Type) when is_list(Type) -> Type.
768
virtual_dest(#class{abstract=true, parent="root"}) -> false;
769
virtual_dest(#class{abstract=true, parent="object"}) -> true;
770
virtual_dest(#class{abstract=true, parent=Parent}) ->
771
virtual_dest(get({class,Parent}));
772
virtual_dest(#class{methods=Ms, parent=Parent}) ->
773
case lists:keysearch(destructor,#method.method_type, lists:append(Ms)) of
774
{value, #method{method_type=destructor, virtual=Virtual}} ->
777
case get({class,Parent}) of
785
io:format("Error: ~p ~n",[Parent]),
786
erlang:error(no_parent)
800
true -> ?warning(F,A);
804
is_derived(#class{abstract=true}) -> false;
805
is_derived(C = #class{}) -> virtual_dest(C).
808
lists:member("wxWindow", wx_gen_erl:parents(Class)).
811
lists:member("wxDialog", wx_gen_erl:parents(Class)).
813
build_return_vals(Type,Ps) ->
814
HaveType = case Type of void -> 0; _ -> 1 end,
815
NoOut = lists:sum([1 || #param{in=In} <- Ps, In =/= true]) + HaveType,
816
OutTupSz = if NoOut > 1 -> NoOut; true -> 0 end,
818
build_ret_types(Type,Ps),
820
OutTupSz > 1 -> w(" rt.addTupleCount(~p);~n",[OutTupSz]);
825
build_ret_types(void,Ps) ->
826
Calc = fun(#param{name=N,in=False,type=T}, Free) when False =/= true ->
827
case build_ret(N, False, T) of
829
Other -> [Other|Free]
833
lists:foldl(Calc, [], Ps);
834
build_ret_types(Type,Ps) ->
835
Free = case build_ret("Result", out, Type) of
839
Calc = fun(#param{name=N,in=False,type=T}, FreeAcc) when False =/= true ->
840
case build_ret(N, False, T) of
842
FreeMe -> [FreeMe|FreeAcc]
844
(_, FreeAcc) -> FreeAcc
846
lists:foldl(Calc, Free, Ps).
848
build_ret(Name,_,#type{base={class,Class},single=true}) ->
849
w(" rt.addRef(getRef((void *)~s,memenv), \"~s\");~n",[Name,Class]);
850
build_ret(Name,_,#type{base={ref,"wxTreeItemId"=Class},single=true}) ->
851
w(" rt.addRef(getRef((void *)~s.m_pItem,memenv), \"~s\");~n",[Name,Class]);
852
build_ret(Name,_,#type{base={term,_},single=true}) ->
853
w(" rt.addExt2Term(~s);~n", [Name]);
854
build_ret(Name,_,#type{base={binary,Size},single=true}) ->
855
w(" if(~s) {~n", [Name]),
856
w(" rt.addBinary(~s, ~s);~n", [Name,Size]),
857
w(" } else {rt.addAtom(\"null\");};~n");
858
build_ret(Name,_,#type{name="wxUIntPtr", ref={pointer,1}, single=true}) ->
859
w(" rt.add(~s);~n", [Name]);
860
build_ret(Name,_,#type{base={enum,_Type},single=true}) ->
861
w(" rt.addInt(~s);~n",[Name]);
862
build_ret(Name,_,#type{base={comp,_,{record, wxMouseState}},single=true}) ->
863
w(" rt.add(~s);~n", [Name]);
864
build_ret(Name,_,#type{base={comp,_,_},single=true, ref=reference}) ->
865
w(" rt.add((*~s));~n",[Name]);
866
build_ret(Name,_,#type{base={comp,_,_},single=true}) ->
867
w(" rt.add(~s);~n",[Name]);
868
build_ret(Name,_,#type{base=bool,single=true,by_val=true}) ->
869
w(" rt.addBool(~s);~n",[Name]);
870
build_ret(Name,both,#type{base=int,single=true,mod=M}) ->
871
case lists:member(unsigned, M) of
872
true -> w(" rt.addUint(*~s);~n",[Name]);
873
false -> w(" rt.addInt(*~s);~n",[Name])
875
build_ret(Name,_,#type{base=int,single=true,mod=M}) ->
876
case lists:member(unsigned, M) of
877
true -> w(" rt.addUint(~s);~n",[Name]);
878
false -> w(" rt.addInt(~s);~n",[Name])
880
build_ret(Name,_,#type{name="wxArrayInt"}) ->
881
w(" rt.add(~s);~n", [Name]);
882
build_ret(Name,_,#type{base={comp,_,_},single=array}) ->
883
w(" for(unsigned int i=0; i < ~s.GetCount(); i++) {~n", [Name]),
884
w(" rt.add(~s[i]);~n }~n",[Name]),
885
w(" rt.endList(~s.GetCount());~n",[Name]);
886
build_ret(Name,_,#type{name=List,single=list,base={class,Class}}) ->
888
w(" for(~s::Node *node = ~s.GetFirst(); node; node = node->GetNext()) {~n",
890
w(" ~s * ~sTmp = node->GetData();~n", [Class,Name]),
891
w(" rt.addRef(getRef((void *)~sTmp,memenv), \"~s\"); i++;}~n",[Name,Class]),
892
w(" rt.endList(~s.GetCount());~n",[Name]);
894
build_ret(Name,_,#type{name="wxArrayTreeItemIds"}) ->
895
w(" for(unsigned int i=0; i < ~s.GetCount(); i++) {~n", [Name]),
896
w(" rt.addRef(getRef((void *)~s[i].m_pItem,memenv), \"wxTreeItemId\");}~n",[Name]),
897
w(" rt.endList(~s.GetCount());~n",[Name]);
899
build_ret(Name,_,#type{base=float,single=true}) ->
900
%% w(" double Temp~s = ~s;~n", [Name,Name]),
901
w(" rt.addFloat(~s);~n",[Name]);
902
build_ret(Name,_,#type{base=double,single=true}) ->
903
w(" rt.addFloat(~s);~n",[Name]);
904
build_ret(Name,_,#type{name="wxString",single=true}) ->
905
w(" rt.add(~s);~n",[Name]);
906
build_ret(Name,_,#type{name="wxArrayString", single=array}) ->
907
w(" rt.add(~s);~n", [Name]);
908
build_ret(Name,In,T) ->
909
?error({nyi, Name,In, T}).
911
mods([const|R]) -> "const " ++ mods(R);
912
mods([unsigned|R]) -> "unsigned " ++ mods(R);
917
w(" /* This file is also generated */~n"),
918
w("#include <wx/wx.h>~n"),
919
w("#include \"../wxe_impl.h\"~n"),
920
w("#include \"wxe_macros.h\"~n"),
921
w("#include \"../wxe_return.h\"~n"),
922
w("void WxeApp::init_nonconsts(wxeMemEnv *memenv, ErlDrvTermData caller) {~n"),
923
NotConsts = [NC || NC = #const{is_const=false} <- gb_trees:values(Tree)],
924
Size = length(NotConsts),
926
GSize = length(GVars),
927
w(" wxeReturn rt = wxeReturn(WXE_DRV_PORT, caller);~n"),
928
w(" rt.addAtom((char*)\"wx_consts\");~n"),
929
[build_enum(NConst) || NConst <- lists:keysort(#const.val, NotConsts)],
930
_Cnt = foldl(fun(Gvar, I) -> build_gvar(Gvar,I) end, 0, lists:sort(GVars)),
931
w(" rt.endList(~p);~n", [Size+GSize]),
932
w(" rt.addTupleCount(2);~n"),
937
build_enum(#const{name=Name}) ->
938
w(" rt.addAtom(\"~s\"); rt.addInt(~s);~n", [Name, Name]),
939
w(" rt.addTupleCount(2);~n").
941
build_gvar({Name, "wxColour", _Id}, Cnt) ->
942
w(" rt.addAtom(\"~s\"); rt.add(*(~s));~n",[Name,Name]),
943
w(" rt.addTupleCount(2);~n"),
945
build_gvar({Name, {address,Class}, _Id}, Cnt) ->
946
w(" rt.addAtom(\"~s\"); rt.addRef(getRef((void *)&~s,memenv), \"~s\");~n",[Name,Name,Class]),
947
w(" rt.addTupleCount(2);~n"),
949
build_gvar({Name, Class, _Id}, Cnt) ->
950
w(" rt.addAtom(\"~s\"); rt.addRef(getRef((void *)~s,memenv),\"~s\");~n",[Name,Name,Class]),
951
w(" rt.addTupleCount(2);~n"),
955
w("#include <wx/caret.h>~n"), %% Arrg wxw forgot?? some files
956
w("#include <wx/tooltip.h>~n"),
957
w("#include <wx/gbsizer.h>~n"),
958
w("#include <wx/splash.h>~n"),
959
w("#include <wx/grid.h>~n"),
960
w("#include <wx/image.h>~n"),
961
w("#include <wx/tglbtn.h>~n"),
962
w("#include <wx/calctrl.h>~n"),
963
w("#include <wx/dirctrl.h>~n"),
964
w("#include <wx/listctrl.h>~n"),
965
w("#include <wx/treectrl.h>~n"),
966
w("#include <wx/spinbutt.h>~n"),
967
w("#include <wx/spinctrl.h>~n"),
968
w("#include <wx/colordlg.h>~n"),
969
w("#include <wx/fdrepdlg.h>~n"),
970
w("#include <wx/fontdlg.h>~n"),
971
w("#include <wx/progdlg.h>~n"),
972
w("#include <wx/printdlg.h>~n"),
973
w("#include <wx/dcbuffer.h>~n"),
974
w("#include <wx/dcmirror.h>~n"),
975
w("#include <wx/glcanvas.h>~n"),
976
w("#include <wx/dcps.h>~n"),
977
w("#include <wx/xrc/xmlres.h>~n"),
978
w("#include <wx/html/htmprint.h>~n"),
979
w("#include <wx/stc/stc.h>~n"),
980
w("#include <wx/minifram.h>~n"),
981
w("#include <wx/sashwin.h>~n"),
982
w("#include <wx/laywin.h>~n"),
983
w("#include <wx/graphics.h>~n"),
984
w("#include <wx/aui/aui.h>~n"),
985
w("#include <wx/datectrl.h>~n"),
986
w("#include <wx/filepicker.h>~n"),
987
w("#include <wx/fontpicker.h>~n"),
988
w("#include <wx/clrpicker.h>~n"),
989
w("#include <wx/statline.h>~n"),
990
w("#include <wx/clipbrd.h>~n"),
991
w("#include <wx/splitter.h>~n"),
994
[w("#define ~s_~s ~p~n", [Class,Name,Id]) ||
995
{Class,Name,_,Id} <- wx_gen_erl:get_unique_names()],
999
open_write("../c_src/gen/wxe_events.cpp"),
1001
w("~n/***** This file is generated do not edit ****/ ~n~n"),
1002
w("#include <wx/wx.h>~n"),
1003
w("#include \"../wxe_impl.h\"~n~n"),
1004
w("#include \"wxe_macros.h\"~n"),
1005
w("#include \"../wxe_events.h\"~n~n"),
1006
w("#include \"../wxe_return.h\"~n~n"),
1008
w("wxeEtype::wxeEtype(const char *name, int Id) {eName = name;cID = Id;}~n~n"),
1009
w("WX_DECLARE_HASH_MAP(int, wxeEtype*, wxIntegerHash, wxIntegerEqual, wxeETmap );~n~n"),
1011
w("wxeETmap etmap; ~n~n"),
1014
"int wxeEventTypeFromAtom(char *etype_atom) {
1015
wxeETmap::iterator it;
1016
for(it = etmap.begin(); it != etmap.end(); ++it) {
1017
wxeEtype * value = it->second;
1018
if(strcmp(value->eName, etype_atom) == 0) {
1019
if(it->first > wxEVT_USER_FIRST) {
1020
return it->first - wxEVT_USER_FIRST;
1031
Evs0 = [C || {_,C=#class{event=Evs}} <- get(), Evs =/= false],
1032
Evs = lists:keysort(#class.id, Evs0),
1033
initEventTable(Evs),
1037
initEventTable(Evs) ->
1038
w("void initEventTable() ~n{~n"),
1040
w("int ev_type; int class_id; char * ev_name;} event_types[] = ~n {~n",[]),
1042
lists:foreach(fun(Ev) -> init_event_classes(Ev) end,
1043
[#class{id=0,event=[wxEVT_NULL]}|Evs]),
1044
w(" {-1, 0, ""}~n };~n",[]),
1045
w(" for(int i=0; event_types[i].ev_type != -1; i++) {~n",[]),
1046
w(" if(NULL == etmap[event_types[i].ev_type]) {~n",[]),
1047
w(" etmap[event_types[i].ev_type] = ~n"
1048
" new wxeEtype(event_types[i].ev_name, event_types[i].class_id);~n"),
1049
w(" } else {~n",[]),
1050
w(" wxeEtype *prev = etmap[event_types[i].ev_type];~n"
1051
" wxString msg(wxT(\"Duplicate event defs: \"));~n"
1052
" msg += wxString::FromAscii(event_types[i].ev_name);~n"
1053
" msg += wxString::Format(wxT(\" %d \"), event_types[i].class_id);~n"
1054
" msg += wxString::FromAscii(prev->eName);~n"
1055
" msg += wxString::Format(wxT(\" %d\"), prev->cID);~n"
1056
" send_msg(\"internal_error\", &msg);~n"
1061
init_event_classes(#class{event=ETs, id=Id}) ->
1062
F = fun({Eev, Cev, OtherClass}) ->
1063
w(" {~w + wxEVT_USER_FIRST, ~w, ~p},~n",
1064
[Cev, find_id(OtherClass), wx_gen_erl:event_type_name(Eev)]);
1066
w(" {~w, ~w, ~p},~n",
1067
[Ev, Id, wx_gen_erl:event_type_name(Ev)])
1069
[F(ET) || ET <- ETs].
1071
find_id(OtherClass) ->
1072
Class = get({class,atom_to_list(OtherClass)}),
1073
%%{value, Class} = lists:keysearch(atom_to_list(OtherClass), #class.name, All),
1076
encode_events(Evs) ->
1077
?WTC("encode_events"),
1078
w("void wxeEvtListener::forward(wxEvent& event) ~n"
1081
" if(!sendevent(&event, port)) ~n"
1082
" fprintf(stderr, \"Couldn't send event!\\r\\n\");~n"
1084
"sendevent(&event, port);~n"
1087
w("int getRef(void* ptr, wxeMemEnv* memenv) ~n"
1089
" WxeApp * app = (WxeApp *) wxTheApp;~n"
1090
" return app->getRef(ptr,memenv);~n"
1092
w("bool sendevent(wxEvent *event, ErlDrvPort port)~n{~n"
1094
" char * evClass = NULL;~n"
1095
" wxMBConvUTF32 UTFconverter;~n"
1096
" wxeEtype *Etype = etmap[event->GetEventType()];~n"
1097
" wxeCallbackData *cb = (wxeCallbackData *)event->m_callbackUserData;~n"
1098
" WxeApp * app = (WxeApp *) wxTheApp;~n"
1099
" wxeMemEnv *memenv = app->getMemEnv(port);~n"
1100
" wxeReturn rt = wxeReturn(port, cb->listener);~n"),
1102
w("~n rt.addAtom((char*)\"wx\");~n"
1103
" rt.addInt((int) event->GetId());~n"
1104
" rt.addRef(getRef((void *)(cb->obj), memenv), cb->class_name);~n"
1105
" rt.addExt2Term(cb->user_data);~n"),
1107
w(" if(!memenv) return 0;~n~n"),
1108
w(" switch(Etype->cID) {~n"),
1109
lists:foreach(fun(Ev) -> encode_event(Ev) end, Evs),
1112
w(" rt.addTupleCount(5);~n"),
1113
w(" if(cb->fun_id) {~n"),
1114
w(" rt.addRef(getRef((void *)event,memenv), evClass);~n"),
1115
w(" rt.addTupleCount(2);~n"),
1116
w(" rt.addInt(cb->fun_id);~n"),
1117
w(" rt.addAtom(\"_wx_invoke_cb_\");~n"),
1118
w(" rt.addTupleCount(3);~n"),
1119
w(" pre_callback();~n"),
1120
w(" send_res = rt.send();~n"),
1121
w(" if(send_res) handle_event_callback(port, cb->listener);~n"),
1122
w(" app->clearPtr((void *) event);~n"),
1124
w(" send_res = rt.send();~n"),
1125
w(" if(cb->skip) event->Skip();~n"),
1127
w(" return send_res;~n"),
1130
encode_event(C = #class{name=Class, id=Id, options=Opts}) ->
1131
?WTC("encode_event"),
1132
case proplists:get_value("mixed_event", Opts) of
1134
w("case ~p: {// ~s~n", [Id,Class]),
1138
w("case ~p: {// ~s or ~s~n", [Id,Class,Mixed]),
1139
w(" if(event->IsKindOf(CLASSINFO(~s))) {~n",[Class]),
1141
w(" } else {~n",[]),
1142
w(" Etype = etmap[event->GetEventType() + wxEVT_USER_FIRST];~n",[]),
1143
encode_event2(get({class,atom_to_list(Mixed)})),
1149
encode_event2(Class = #class{name=Name}) ->
1150
Attrs = build_event_attrs(Class),
1151
w(" evClass = (char*)\"~s\";~n",[Name]),
1152
w(" rt.addAtom((char*)\"~s\");~n", [wx_gen_erl:event_rec_name(Name)]),
1153
w(" rt.addAtom(Etype->eName);~n"),
1154
build_ret_types(void, Attrs),
1155
w(" rt.addTupleCount(~p);~n",[length(Attrs) + 2]).
1157
build_event_attrs(ClassRec = #class{name=Class}) ->
1158
Attrs0 = wx_gen_erl:filter_attrs(ClassRec),
1160
fun(Att = #param{name=Name,prot=public,acc=undefined}, {All,Use}) ->
1161
{[Att#param{name= "ev->" ++ Name}|All],Use};
1162
(Att = #param{acc=Acc}, {All,_}) ->
1163
{[Att#param{name= "ev->" ++ Acc}|All], true}
1165
case foldr(Rename,{[],false},Attrs0) of
1168
%% w(" ~s ev = dynamic_cast<~s&>(event);~n",[Class,Class]),
1171
w(" ~s * ev = (~s *) event;~n",[Class,Class]),
1173
fun(P=#param{name=N,acc=Acc,type=#type{single=Single,by_val=ByVal,
1175
when Acc =/= undefined ->
1178
w(" ~s * ~s = new ~s(~s);~n", [C,Var,C,N]),
1179
w(" app->newPtr((void *) ~s,3, memenv);~n", [Var]);
1181
w(" ~s * ~s = ~s;~n", [C,Var,N])
1186
lists:map(FixClass, Attrs)
1189
var_name("ev->" ++ Name0) ->
1190
case reverse(Name0) of
1191
")(" ++ Name -> reverse(Name);
1194
var_name(Name) -> Name.
1196
enum_name({Class,Type}) ->
1197
uppercase_all(Class ++ "_" ++ Type);
1199
uppercase_all(Type).
1202
enum_type({Class,Type}) ->
1203
Class ++ "::" ++ Type;
1204
enum_type(Type) -> Type.