4
%% Copyright Ericsson AB 2008-2010. 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
19
19
%%%-------------------------------------------------------------------
20
20
%%% File : wx_gen_cpp.erl
21
21
%%% Author : Dan Gudmundsson <dgud@erix.ericsson.se>
24
24
%%% Created : 19 Feb 2007 by Dan Gudmundsson <dgud@erix.ericsson.se>
25
25
%%%-------------------------------------------------------------------
50
50
open_write("../c_src/gen/wxe_macros.h"),
55
55
open_write("../c_src/gen/wxe_init.cpp"),
63
63
gen_derived_dest(Defs) ->
64
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
67
gen_derived_dest_2(C=#class{name=Class}) ->
93
?WTC("gen_derived_dest_2"),
68
?WTC("gen_derived_dest_2"),
69
Derived = is_derived(C),
70
TaylorMade = taylormade_class(C),
71
if Derived andalso (TaylorMade =:= false) ->
94
72
w("class E~s : public ~s {~n",[Class,Class]),
96
74
"wxGLCanvas" -> %% Special for cleaning up gl context
102
80
gen_constructors(C),
82
TaylorMade /= false ->
83
w("~s~n", [TaylorMade]);
88
taylormade_class(#class{name=CName, methods=Ms}) ->
89
TaylorMade = lists:any(fun([#method{where=taylormade}|_]) -> true;
95
{ok, Bin} = file:read_file(filename:join([wx_extra, CName ++".c_src"])),
96
Src = binary_to_list(Bin),
97
case gen_util:get_taylor_made(Src, CName ++ "_class") of
99
{match, [Str0]} -> Str0
108
103
gen_constructors(#class{name=Class, methods=Ms0}) ->
109
104
Ms = lists:append(Ms0),
110
105
Cs = lists:filter(fun(#method{method_type=MT}) -> MT =:= constructor end, Ms),
111
106
[gen_constructor(Class, Const) || Const <- Cs].
113
108
gen_constructor(_Class, #method{where=merged_c}) -> ok;
114
109
gen_constructor(_Class, #method{where=erl_no_opt}) -> ok;
115
110
gen_constructor(Class, _M=#method{params=Ps}) ->
119
114
HaveMergedType = fun(#param{type={merged,_,_,_,_,_,_}}) -> true; (_) -> false end,
120
115
?WTC("gen_constructor"),
121
116
case lists:any(HaveMergedType, Ps) of
123
118
w(" E~s(~s) : ~s(~s) {};~n",
124
119
[Class,args(Gen1,",",Ps),Class,args(CallA,",",Ps)]);
141
136
mods(Mod) ++ to_string(Type) ++ " * ";
142
137
gen_type(#type{name=Type, ref=undefined, mod=Mod},_) ->
143
138
mods(Mod) ++ to_string(Type) ++ " ";
144
gen_type({merged, _, T1, _,_, _T2,_}, 1) ->
139
gen_type({merged, _, T1, _,_, _T2,_}, 1) ->
145
140
gen_type(T1,error);
146
gen_type({merged, _, _T1,_, _, T2,_}, 2) ->
141
gen_type({merged, _, _T1,_, _, T2,_}, 2) ->
147
142
gen_type(T2,error).
149
144
gen_funcs(Defs) ->
168
163
%% w(" case WXE_REMOVE_PORT:~n", []),
169
164
%% w(" { destroyMemEnv(Ecmd.port); } break;~n", []),
170
165
w(" case DESTROY_OBJECT: {~n"),
171
w(" wxObject *This = (wxObject *) getPtr(bp,memenv); "),
166
w(" wxObject *This = (wxObject *) getPtr(bp,memenv); "),
172
167
w(" if(This) {"),
173
168
w(" ((WxeApp *) wxTheApp)->clearPtr((void *) This);~n"),
174
169
w(" delete This; }~n } break;~n"),
203
198
w(" error.addTupleCount(2);~n"),
204
199
w(" error.addTupleCount(3);~n"),
205
200
w(" error.send();~n"),
206
w("}} /* The End */~n"),
201
w("}} /* The End */~n~n~n"),
203
UglySkipList = ["wxCaret", "wxCalendarDateAttr",
204
"wxFileDataObject", "wxTextDataObject", "wxBitmapDataObject"
207
w("void WxeApp::delete_object(void *ptr, wxeRefData *refd) {~n", []),
208
w(" switch(refd->type) {~n", []),
209
Case = fun(#class{name=Class, id=Id, abstract=IsAbs, parent=P}) when P /= "static" ->
210
UglyWorkaround = lists:member(Class, UglySkipList),
211
case hd(reverse(wx_gen_erl:parents(Class))) of
212
root when IsAbs == false, UglyWorkaround == false ->
213
w(" case ~p: delete (~s *) ptr; break;~n", [Id, Class]);
214
root when IsAbs == false, UglyWorkaround == true ->
215
w(" case ~p: /* delete (~s *) ptr;"
216
"These objects must be deleted by owner object */ "
217
"break;~n", [Id, Class]);
222
[Case(Class) || Class <- Defs],
223
w(" default: delete (wxObject *) ptr;~n", []),
209
227
gen_class(C=#class{name=Name,methods=Ms,options=Opts}) ->
210
228
put(current_class, Name),
212
230
case lists:member(taylormade, Opts) of
214
232
{ok, Bin} = file:read_file(filename:join([wx_extra,Name++".c_src"])),
216
234
w("~s~n", [binary_to_list(Bin)]),
220
238
{value, {ifdef, What}} ->
221
239
w("#if ~p~n",[What]),
222
240
Methods = lists:flatten(Ms),
223
MsR = [gen_method(Name,M) ||
241
MsR = [gen_method(Name,M) ||
224
242
M <- lists:keysort(#method.id, Methods)],
225
243
w("#endif // ~p~n",[What]),
228
246
Methods = lists:flatten(Ms),
229
[gen_method(Name,M) ||
247
[gen_method(Name,M) ||
230
248
M <- lists:keysort(#method.id, Methods)]
234
252
C#class{methods=NewMs}.
236
254
gen_method(_CName, M=#method{where=erl_no_opt}) -> M;
237
gen_method(CName, M=#method{where=taylormade, name=Name, id=Id}) ->
255
gen_method(CName, M=#method{where=taylormade, name=Name, id=Id}) ->
238
256
{ok, Bin} = file:read_file(filename:join([wx_extra, CName ++".c_src"])),
239
Str0 = binary_to_list(Bin),
257
Src = binary_to_list(Bin),
240
258
%% io:format("C++ Class ~p ~p~n", [CName, Name]),
242
{match, [Str1]} = re:run(Str0, "<<"++Name++"(.*)"++Name++">>",
243
[dotall, {capture, all_but_first, list}]),
259
Str = case gen_util:get_taylor_made(Src, Name) of
261
{match, [Str0]} = gen_util:get_taylor_made(Src, wx_gen_erl:get_unique_name(Id)),
244
266
?WTC("gen_method"),
245
w(Str1, [wx_gen_erl:get_unique_name(Id)]),
267
w(Str, [wx_gen_erl:get_unique_name(Id)]),
247
269
gen_method(CName, M=#method{name=N,params=[Ps],method_type=destructor,id=MethodId}) ->
248
270
case hd(reverse(wx_gen_erl:parents(CName))) of
266
288
w("case ~s: { // ~s::~s~n", [wx_gen_erl:get_unique_name(MethodId),CName,N]),
267
289
Ps1 = declare_variables(void, Ps0),
268
290
{Ps2,Align} = decode_arguments(Ps1),
269
Opts = [Opt || Opt = #param{def=Def,in=In,where=Where} <- Ps2,
291
Opts = [Opt || Opt = #param{def=Def,in=In,where=Where} <- Ps2,
270
292
Def =/= none, In =/= false, Where =/= c],
271
293
decode_options(Opts, Align),
272
294
case gen_util:get_hook(c, M#method.pre_hook) of
293
315
declare_var(P = #param{where=erl}) -> P;
294
316
declare_var(P = #param{where=this}) -> P;
295
declare_var(P = #param{name=Name,def=Def,type=Type,in=true}) when Def =/= none ->
317
declare_var(P = #param{name=Name,def=Def,type=Type,in=true}) when Def =/= none ->
296
318
declare_type(Name, true, Def, Type),
298
320
declare_var(P = #param{in=In}) when In =/= false -> P;
304
326
w(" wxArrayInt ~s;~n", [N]);
305
327
declare_type(N,false,_,#type{name="wxArrayString"}) ->
306
328
w(" wxArrayString ~s;~n", [N]);
307
declare_type(N,false,_,#type{base=Base,single=true,name=Type,by_val=false,mod=Mod})
329
declare_type(N,false,_,#type{base=Base,single=true,name=Type,by_val=false,mod=Mod})
308
330
when Base =:= int; Base =:= long; Base =:= float; Base =:= double ->
309
331
w(" ~s~s ~s;~n", [mods(Mod),Type,N]);
310
332
declare_type(N,false,_,#type{base={enum,_},single=true,name=Type,by_val=false,mod=Mod}) ->
315
337
w(" wxDateTime ~s;~n", [N]);
316
338
declare_type(N,false,_,#type{name=Type, base=int64, ref=reference}) ->
317
339
w(" ~s ~s;~n", [Type,N]);
318
declare_type(N,true,Def,#type{base=Base,single=true,name=Type,by_val=true})
340
declare_type(N,true,Def,#type{base=Base,single=true,name=Type,by_val=true})
319
341
when Base =:= int; Base =:= long; Base =:= float; Base =:= double; Base =:= bool ->
320
342
w(" ~s ~s=~s;~n", [Type,N,Def]);
321
343
declare_type(N,true,Def,#type{base={comp,_,_},single=true,name=Type,mod=Mod,ref={pointer,1}}) ->
328
350
w(" ~s~s * ~s=~s;~n", [mods(Mod),Type,N,Def]);
329
351
declare_type(N,true,Def,#type{base={class,_},single=true,name=Type,ref=reference,mod=Mod}) ->
330
352
w(" ~s~s * ~s= &~s;~n", [mods(Mod),Type,N,Def]);
331
declare_type(N,true,Def,#type{base=Base,single=true,name=Type,by_val=false,ref={pointer,1}})
353
declare_type(N,true,Def,#type{base=Base,single=true,name=Type,by_val=false,ref={pointer,1}})
332
354
when Base =:= int; Base =:= long; Base =:= float; Base =:= double; Base =:= bool ->
333
355
w(" ~s *~s=~s;~n", [Type,N,Def]);
334
356
declare_type(N,true,Def,#type{single=true,name="wxArtClient"}) ->
346
368
w(" ~s ** ~s = ~s;~n", [Type,N,Def]);
347
369
declare_type(N,true,Def,#type{name=Type, single=array, ref={pointer,1}}) ->
348
w(" int * ~sLen = 0;~n", [N]),
370
w(" int * ~sLen = 0;~n", [N]),
349
371
w(" ~s * ~s = ~s;~n", [Type,N,Def]);
350
372
declare_type(N,true,"",#type{name="wxArrayString", single=array, ref=reference}) ->
351
373
w(" wxArrayString ~s;~n", [N]);
364
386
decode_opt(#param{name=Name,type=Type}, N) ->
365
387
w(" case ~p: {bp += 4;~n", [N]),
366
Align = decode_arg(Name,Type,opt,1),
388
Align = decode_arg(Name,Type,opt,1),
367
389
align(Align, 64),
368
390
w(" } break;~n", []),
371
decode_arguments(Ps0) ->
393
decode_arguments(Ps0) ->
372
394
lists:mapfoldl(fun decode_arg/2,0,Ps0).
388
410
decode_arg(P = #param{where=erl},A) -> {P,A};
389
411
decode_arg(P = #param{where=c},A) -> {P,A};
390
412
decode_arg(P = #param{in=false},A) -> {P,A};
391
decode_arg(P = #param{def=Def},A) when Def =/= none -> {P,A};
413
decode_arg(P = #param{def=Def},A) when Def =/= none -> {P,A};
392
414
decode_arg(P = #param{name=Name,type=Type},A0) ->
393
415
A = decode_arg(Name, Type, arg, A0),
427
449
decode_arg(N,#type{base=double,single=true,name=Type},Arg,A0) ->
428
450
A = align(A0,64),
430
452
arg -> w(" ~s * ~s = (~s *) bp; bp += 8;~n", [Type,N,Type]);
431
453
opt -> w(" ~s = * (~s *) bp; bp += 8;~n", [N,Type])
434
456
decode_arg(N,#type{base=bool,single=true,name=Type},Arg,A0) ->
436
458
arg -> w(" bool * ~s = (~s *) bp; bp += 4;~n", [N,Type]);
437
459
opt -> w(" ~s = *(~s *) bp; bp += 4;~n", [N,Type])
440
462
decode_arg(N,#type{base={enum,Type},single=true},Arg,A0) ->
441
wa(" ~s ", [enum_type(Type)], "~s = *(~s *) bp; bp += 4;;~n",[N, enum_type(Type)], Arg),
463
wa(" ~s ", [enum_type(Type)], "~s = *(~s *) bp; bp += 4;;~n",[N, enum_type(Type)], Arg),
443
465
decode_arg(N,#type{base={comp,"wxDateTime",List},single=true,name=Type,ref=Ref},Arg,A0) ->
444
Decl = fun({int,Spec}) ->
466
Decl = fun({int,Spec}) ->
445
467
w(" int * ~s~s = (int *) bp; bp += 4;~n", [N,Spec])
454
476
arg -> w(" ~s ~s = ~s(~s);~n", [Type,N,Type,args(Name, ",", List)]);
455
opt when Ref =:= {pointer,1} ->
456
w(" ~sTmp = ~s(~s); ~s = & ~sTmp;~n",
477
opt when Ref =:= {pointer,1} ->
478
w(" ~sTmp = ~s(~s); ~s = & ~sTmp;~n",
457
479
[N,Type,args(Name, ",", List), N,N]);
459
481
w(" ~s = ~s(~s);~n", [N,Type,args(Name, ",", List)])
461
483
(A0+length(List)) rem 2;
462
484
decode_arg(N,#type{base={comp,_,List},single=true,name=Type,ref=Ref},Arg,A0) ->
463
Decl = fun({int,Spec}) ->
485
Decl = fun({int,Spec}) ->
464
486
w(" int * ~s~s = (int *) bp; bp += 4;~n", [N,Spec]);
465
487
({double, Spec}) ->
466
488
w(" wxDouble * ~s~s = (wxDouble *) bp; bp += 8;~n", [N,Spec])
473
495
Name = fun({_,Spec}) -> "*"++N++Spec end,
475
497
arg -> w(" ~s ~s = ~s(~s);~n", [Type,N,Type,args(Name, ",", List)]);
476
opt when Ref =:= {pointer,1} ->
477
w(" ~sTmp = ~s(~s); ~s = & ~sTmp;~n",
498
opt when Ref =:= {pointer,1} ->
499
w(" ~sTmp = ~s(~s); ~s = & ~sTmp;~n",
478
500
[N,Type,args(Name, ",", List), N,N]);
480
502
w(" ~s = ~s(~s);~n", [N,Type,args(Name, ",", List)])
483
505
{int, _} -> (A0+length(List)) rem 2;
487
509
decode_arg(N,#type{name=Class="wxTreeItemId",single=true},Arg,A0) ->
488
510
A = align(A0,64),
489
511
wa(" ~s ",[Class],"~s = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;~n",[N],Arg),
492
514
A = align(A0,64),
493
515
wa(" ~s ",[Class],"~s = (~s) * (wxUint64 *) bp; bp += 8;~n",[N,Class],Arg),
495
decode_arg(N,#type{name="wxChar", single=S},Arg,A0)
517
decode_arg(N,#type{name="wxChar", single=S},Arg,A0)
496
518
when S =/= true ->
497
519
w(" int * ~sLen = (int *) bp; bp += 4;~n", [N]),
498
520
wa(" wxString", []," ~s = wxString(bp, wxConvUTF8);~n", [N],Arg),
501
523
decode_arg(N,#type{base=string, name="wxFileName"},Arg,A0) ->
502
524
w(" int * ~sLen = (int *) bp; bp += 4;~n", [N]),
503
525
wa(" wxString", []," ~sStr = wxString(bp, wxConvUTF8);~n", [N],Arg),
504
w(" bp += *~sLen+((8-((~p+ *~sLen) & 7)) & 7);~n", [N,4*((A0+1) rem 2),N]),
526
w(" bp += *~sLen+((8-((~p+ *~sLen) & 7)) & 7);~n", [N,4*((A0+1) rem 2),N]),
505
527
w(" wxFileName ~s = wxFileName(~sStr);~n",[N,N]),
507
529
decode_arg(N,#type{base=string},Arg,A0) ->
541
563
decode_arg(_N,#type{base=eventType},_Arg,A0) ->
542
564
%% w(" int * ~sLen = (int *) bp; bp += 4;~n", [N]),
545
567
%% w(" int ~s = wxeEventTypeFromAtom(bp);bp += *~sLen;~n",[N,N]),
546
568
%% w(" char *class_name = bp;~n", []),
547
569
%% w(" wxeCallbackData * Evt_cb = new wxeCallbackData(Ecmd.caller,This,class_name);~n",
551
573
decode_arg(N,#type{name=Type,base=binary,mod=Mod0},Arg,A0) ->
552
574
Mod = mods([M || M <- Mod0]),
555
577
w(" ~s~s * ~s = (~s~s*) Ecmd.bin[~p]->base;~n",
556
578
[Mod,Type,N,Mod,Type, next_id(bin_count)]);
564
586
Type = "wxETreeItemData",
565
587
BinCnt = next_id(bin_count),
568
590
w(" ~s~s * ~s = new ~s(Ecmd.bin[~p]->size, Ecmd.bin[~p]->base);~n",
569
591
[Mod,Type,N,Type,BinCnt,BinCnt]);
571
593
w(" ~s = new ~s(Ecmd.bin[~p]->size, Ecmd.bin[~p]->base);~n",
572
594
[N,Type,BinCnt,BinCnt])
576
598
Mod = mods([M || M <- Mod0]),
577
599
BinCnt = next_id(bin_count),
580
602
w(" ~s~s * ~s = new ~s(Ecmd.bin[~p]);~n",
581
603
[Mod,Type,N,Type,BinCnt]);
583
605
w(" ~s = new ~s(Ecmd.bin[~p]);~n",
590
612
w(" int * ~sLen = (int *) bp; bp += 4;~n", [N]),
591
w(" int * ~s = (int *) bp; bp += *~sLen*4+((~p+ *~sLen)%2 )*4;~n",
613
w(" int * ~s = (int *) bp; bp += *~sLen*4+((~p+ *~sLen)%2 )*4;~n",
592
614
[N,N,(A0+1) rem 2,N]);
594
616
w(" ~sLen = (int *) bp; bp += 4;~n", [N]),
595
w(" ~s = (int *) bp; bp += *~sLen*4+((~p+ *~sLen)%2 )*4;~n",
617
w(" ~s = (int *) bp; bp += *~sLen*4+((~p+ *~sLen)%2 )*4;~n",
596
618
[N,N,(A0+1) rem 2,N])
599
621
decode_arg(N,#type{by_val=true,single=array,base={comp,Class="wxPoint",_}},arg,A0) ->
600
w(" int * ~sLen = (int *) bp; bp += 4;~n", [N]),
601
w(" ~s *~s;~n",[Class,N]),
622
w(" int * ~sLen = (int *) bp; bp += 4;~n", [N]),
623
w(" ~s *~s;~n",[Class,N]),
602
624
w(" ~s = (~s *) driver_alloc(sizeof(~s) * *~sLen);~n",[N,Class,Class,N]),
604
626
w(" for(int i=0; i < *~sLen; i++) {~n", [N]),
629
651
align(0, 32) -> 1;
630
652
align(1, 32) -> 0;
631
653
align(0, 64) -> 0;
633
655
w(" bp += 4; /* Align */~n"),
636
658
align(N rem 2, Sz).
638
call_wx(_N,{constructor,_},#type{base={class,RClass}},Ps) ->
660
call_wx(_N,{constructor,_},#type{base={class,RClass}},Ps) ->
639
661
#class{id=Id} = ClassDef = get({class,RClass}),
640
662
Class = case is_derived(ClassDef) of
641
663
true -> "E" ++ RClass;
682
704
return_res(void) -> {"", ""};
683
705
return_res(Type = #type{mod=Mod}) ->
684
706
case lists:member(const, Mod) of
686
{Beg, End} = return_res1(Type),
708
{Beg, End} = return_res1(Type),
687
709
{"const " ++ Beg, End};
689
711
return_res1(Type)
695
717
{Type ++ " * Result = (" ++ Type ++ "*)", ""};
696
718
return_res1(#type{name=Type,single=true,ref=reference}) ->
697
719
{Type ++ " * Result = &", ""};
698
return_res1(#type{name=Type,single=true,by_val=true})
699
when is_atom(Type) ->
720
return_res1(#type{name=Type,single=true,by_val=true})
721
when is_atom(Type) ->
700
722
{atom_to_list(Type) ++ " Result = ", ""};
701
723
return_res1(#type{name=Type="wxArrayInt"}) ->
702
724
{Type ++ " Result = ", ""};
705
727
return_res1(#type{name=Type,base={comp,_,_},single=array,by_val=true}) ->
706
728
{Type ++ " Result = ", ""};
707
729
return_res1(#type{name=Type,single=true,by_val=true, base={class, _}}) ->
708
%% Memory leak !!!!!! XXXX BUGBUG FIXME or doument!!
730
%% Memory leak !!!!!! XXXX BUGBUG FIXME or doument!!
712
734
"wxBitmap" -> ok;
714
736
"wxGraphics" ++ _ -> ok;
716
io:format("~s::~s Building return value of temp ~s~n",
738
io:format("~s::~s Building return value of temp ~s~n",
717
739
[get(current_class),get(current_func),Type])
719
741
%% #class{id=Id} = get({class,Type}),
720
{Type ++ " * Result = new " ++ Type ++ "(", "); newPtr((void *) Result,"
742
{Type ++ " * Result = new " ++ Type ++ "(", "); newPtr((void *) Result,"
721
743
++ "3, memenv);"};
722
744
return_res1(#type{base={enum,_Type},single=true,by_val=true}) ->
723
745
{"int Result = " , ""};
732
754
lists:filter(fun filter_arg/1, Ps).
733
filter_arg(#param{where=erl}) -> false;
755
filter_arg(#param{where=erl}) -> false;
734
756
filter_arg(#param{where=this}) -> false;
735
757
filter_arg(#param{}) -> true.
736
758
%%filter_arg(#param{def=Def, in=In}) -> Def =:= none orelse In =:= false.
739
761
call_arg(#param{where=c, alt={length,Alt}}) when is_list(Alt) ->
740
762
"*" ++ Alt ++ "Len";
741
763
call_arg(#param{where=c, alt={size,Id}}) when is_integer(Id) ->
743
765
"Ecmd.bin["++ integer_to_list(Id) ++ "]->size";
744
call_arg(#param{name=N,def=Def,type=#type{name=Type,by_val=true,single=true,base=Base}})
745
when Base =:= int; Base =:= long; Base =:= float; Base =:= double; Base =:= bool ->
766
call_arg(#param{name=N,def=Def,type=#type{name=Type,by_val=true,single=true,base=Base}})
767
when Base =:= int; Base =:= long; Base =:= float; Base =:= double; Base =:= bool ->
747
769
none -> "(" ++ to_string(Type) ++ ") *" ++ N;
751
call_arg(#param{name=N,type=#type{base={enum,Type}, by_val=true,single=true}}) ->
773
call_arg(#param{name=N,type=#type{base={enum,Type}, by_val=true,single=true}}) ->
752
774
"(" ++ enum_type(Type) ++") " ++ N;
753
775
call_arg(#param{name=N,type=#type{base={class,_},by_val=true,single=true}}) -> "*" ++ N;
754
776
call_arg(#param{name=N,type=#type{base={class,_},ref=reference,single=true}}) -> "*" ++ N;
755
call_arg(#param{name=N,type=#type{base=eventType}}) ->
777
call_arg(#param{name=N,type=#type{base=eventType}}) ->
756
778
N ++ ", (wxObjectEventFunction)(wxEventFunction) &WxeApp::handle_evt, Evt_cb, this";
757
779
call_arg(#param{name=N,type=#type{by_val=true, single=_False}}) -> N;
758
780
call_arg(#param{name=N,def=Def,type=#type{by_val=false, ref={pointer,2}}})
760
782
call_arg(#param{name=N,type=#type{by_val=false, ref={pointer,2}}}) -> "&" ++ N;
761
783
call_arg(#param{name=N,in=false,type=#type{ref=reference, single=true}}) -> N;
762
784
call_arg(#param{name=N,in=false,type=#type{by_val=false, single=true}}) -> "&" ++ N;
763
call_arg(#param{name=N,def=Def,type=#type{base={comp,_,_},ref={pointer,1},single=true}})
785
call_arg(#param{name=N,def=Def,type=#type{base={comp,_,_},ref={pointer,1},single=true}})
764
786
when Def =:= none ->
766
788
call_arg(#param{name=N,type=#type{by_val=false}}) -> N;
767
789
call_arg(#param{name=N,type={merged,_,#type{base={class,_},single=true,
770
when ByVal =:= true; Ref =:= reference ->
792
when ByVal =:= true; Ref =:= reference ->
772
call_arg(#param{def=Def, type=void}) when Def =/= none -> Def;
794
call_arg(#param{def=Def, type=void}) when Def =/= none -> Def;
773
795
call_arg(#param{name=N,type=#type{base={ref,_},by_val=true,single=true}}) -> N;
774
796
call_arg(#param{name=N,type={merged,_,_,_,_,_,_}}) -> N.
776
%% call_arg(#param{name=N,type=#type{base=Tuple,ref=reference}})
798
%% call_arg(#param{name=N,type=#type{base=Tuple,ref=reference}})
777
799
%% when is_tuple(Tuple) -> "&" ++ N;
779
801
to_string(Type) when is_atom(Type) -> atom_to_list(Type);
782
804
virtual_dest(#class{abstract=true, parent="root"}) -> false;
783
805
virtual_dest(#class{abstract=true, parent="object"}) -> true;
784
virtual_dest(#class{abstract=true, parent=Parent}) ->
806
virtual_dest(#class{abstract=true, parent=Parent}) ->
785
807
virtual_dest(get({class,Parent}));
786
808
virtual_dest(#class{methods=Ms, parent=Parent}) ->
787
809
case lists:keysearch(destructor,#method.method_type, lists:append(Ms)) of
788
810
{value, #method{method_type=destructor, virtual=Virtual}} ->
791
813
case get({class,Parent}) of
799
821
io:format("Error: ~p~n",[Parent]),
819
841
is_derived(C = #class{}) -> virtual_dest(C).
821
843
is_window(Class) ->
822
lists:member("wxWindow", wx_gen_erl:parents(Class)).
844
lists:member("wxWindow", wx_gen_erl:parents(Class)).
824
846
is_dialog(Class) ->
825
847
lists:member("wxDialog", wx_gen_erl:parents(Class)).
827
849
build_return_vals(Type,Ps) ->
828
850
HaveType = case Type of void -> 0; _ -> 1 end,
829
851
NoOut = lists:sum([1 || #param{in=In} <- Ps, In =/= true]) + HaveType,
830
852
OutTupSz = if NoOut > 1 -> NoOut; true -> 0 end,
832
854
build_ret_types(Type,Ps),
834
856
OutTupSz > 1 -> w(" rt.addTupleCount(~p);~n",[OutTupSz]);
839
build_ret_types(void,Ps) ->
861
build_ret_types(void,Ps) ->
840
862
Calc = fun(#param{name=N,in=False,type=T}, Free) when False =/= true ->
841
863
case build_ret(N, False, T) of
845
867
(_, Free) -> Free
847
869
lists:foldl(Calc, [], Ps);
848
build_ret_types(Type,Ps) ->
870
build_ret_types(Type,Ps) ->
849
871
Free = case build_ret("Result", out, Type) of
851
873
FreeStr -> [FreeStr]
898
920
build_ret(Name,_,#type{base={comp,_,_},single=array}) ->
899
921
w(" for(unsigned int i=0; i < ~s.GetCount(); i++) {~n", [Name]),
900
922
w(" rt.add(~s[i]);~n }~n",[Name]),
901
w(" rt.endList(~s.GetCount());~n",[Name]);
923
w(" rt.endList(~s.GetCount());~n",[Name]);
902
924
build_ret(Name,_,#type{name=List,single=list,base={class,Class}}) ->
903
925
w(" int i=0;~n"),
904
926
w(" for(~s::const_iterator it = ~s.begin(); it != ~s.end(); ++it) {~n",
905
927
[List, Name, Name]),
906
928
w(" ~s * ~sTmp = *it;~n", [Class,Name]),
907
929
w(" rt.addRef(getRef((void *)~sTmp,memenv), \"~s\"); i++;}~n",[Name,Class]),
908
w(" rt.endList(~s.GetCount());~n",[Name]);
930
w(" rt.endList(~s.GetCount());~n",[Name]);
910
932
build_ret(Name,_,#type{name="wxArrayTreeItemIds"}) ->
911
w(" for(unsigned int i=0; i < ~s.GetCount(); i++) {~n", [Name]),
933
w(" for(unsigned int i=0; i < ~s.GetCount(); i++) {~n", [Name]),
912
934
w(" rt.add((wxUIntPtr *)~s[i].m_pItem);}~n",[Name]),
913
935
w(" rt.endList(~s.GetCount());~n",[Name]);
923
945
w(" rt.add(~s);~n", [Name]);
924
946
build_ret(Name,In,T) ->
925
947
?error({nyi, Name,In, T}).
927
949
mods([const|R]) -> "const " ++ mods(R);
928
950
mods([unsigned|R]) -> "unsigned " ++ mods(R);
932
954
Tree = get(consts),
935
957
w("#include \"../wxe_impl.h\"~n"),
936
958
w("#include \"wxe_macros.h\"~n"),
937
959
w("#include \"../wxe_return.h\"~n"),
938
w("void WxeApp::init_nonconsts(wxeMemEnv *memenv, ErlDrvTermData caller) {~n"),
960
w("void WxeApp::init_nonconsts(wxeMemEnv *memenv, ErlDrvTermData caller) {~n"),
939
961
NotConsts = [NC || NC = #const{is_const=false} <- gb_trees:values(Tree)],
940
962
Size = length(NotConsts),
941
963
GVars = get(gvars),
942
964
GSize = length(GVars),
943
965
w(" wxeReturn rt = wxeReturn(WXE_DRV_PORT, caller);~n"),
944
w(" rt.addAtom((char*)\"wx_consts\");~n"),
966
w(" rt.addAtom((char*)\"wx_consts\");~n"),
945
967
[build_enum(NConst) || NConst <- lists:keysort(#const.val, NotConsts)],
946
968
_Cnt = foldl(fun(Gvar, I) -> build_gvar(Gvar,I) end, 0, lists:sort(GVars)),
947
969
w(" rt.endList(~p);~n", [Size+GSize]),
971
w("#include <wx/caret.h>~n"), %% Arrg wxw forgot?? some files
972
w("#include <wx/tooltip.h>~n"),
973
w("#include <wx/gbsizer.h>~n"),
993
w("#include <wx/caret.h>~n"), %% Arrg wxw forgot?? some files
994
w("#include <wx/tooltip.h>~n"),
995
w("#include <wx/gbsizer.h>~n"),
974
996
w("#include <wx/splash.h>~n"),
975
997
w("#include <wx/grid.h>~n"),
976
998
w("#include <wx/image.h>~n"),
995
1017
w("#include <wx/stc/stc.h>~n"),
996
1018
w("#include <wx/minifram.h>~n"),
997
1019
w("#include <wx/sashwin.h>~n"),
998
w("#include <wx/laywin.h>~n"),
999
w("#include <wx/graphics.h>~n"),
1000
w("#include <wx/aui/aui.h>~n"),
1001
w("#include <wx/datectrl.h>~n"),
1002
w("#include <wx/filepicker.h>~n"),
1003
w("#include <wx/fontpicker.h>~n"),
1004
w("#include <wx/clrpicker.h>~n"),
1005
w("#include <wx/statline.h>~n"),
1006
w("#include <wx/clipbrd.h>~n"),
1020
w("#include <wx/laywin.h>~n"),
1021
w("#include <wx/graphics.h>~n"),
1022
w("#include <wx/aui/aui.h>~n"),
1023
w("#include <wx/datectrl.h>~n"),
1024
w("#include <wx/filepicker.h>~n"),
1025
w("#include <wx/fontpicker.h>~n"),
1026
w("#include <wx/clrpicker.h>~n"),
1027
w("#include <wx/statline.h>~n"),
1028
w("#include <wx/clipbrd.h>~n"),
1007
1029
w("#include <wx/splitter.h>~n"),
1008
1030
w("#include <wx/choicebk.h>~n"),
1009
1031
w("#include <wx/toolbook.h>~n"),
1012
1034
w("#include <wx/html/htmlwin.h>~n"),
1013
1035
w("#include <wx/html/htmlcell.h>~n"),
1014
1036
w("#include <wx/filename.h>~n"),
1037
w("#include <wx/sysopt.h>~n"),
1017
1040
w("#ifndef wxICON_DEFAULT_BITMAP_TYPE~n",[]),
1018
1041
w(" #define wxICON_DEFAULT_BITMAP_TYPE wxBITMAP_TYPE_ICO_RESOURCE~n",[]),
1019
1042
w("#endif~n", []),
1022
[w("#define ~s_~s ~p~n", [Class,Name,Id]) ||
1045
[w("#define ~s_~s ~p~n", [Class,Name,Id]) ||
1023
1046
{Class,Name,_,Id} <- wx_gen_erl:get_unique_names()],
1032
1055
w("#include \"wxe_macros.h\"~n"),
1033
1056
w("#include \"../wxe_events.h\"~n~n"),
1034
1057
w("#include \"../wxe_return.h\"~n~n"),
1036
1059
w("wxeEtype::wxeEtype(const char *name, int Id) {eName = name;cID = Id;}~n~n"),
1037
1060
w("WX_DECLARE_HASH_MAP(int, wxeEtype*, wxIntegerHash, wxIntegerEqual, wxeETmap );~n~n"),
1039
1062
w("wxeETmap etmap;~n~n"),
1042
1065
"int wxeEventTypeFromAtom(char *etype_atom) {
1043
1066
wxeETmap::iterator it;
1044
1067
for(it = etmap.begin(); it != etmap.end(); ++it) {
1045
1068
wxeEtype * value = it->second;
1046
if(strcmp(value->eName, etype_atom) == 0) {
1047
if(it->first > wxEVT_USER_FIRST) {
1069
if(strcmp(value->eName, etype_atom) == 0) {
1070
if(it->first > wxEVT_USER_FIRST) {
1048
1071
return it->first - wxEVT_USER_FIRST;
1050
1073
return it->first;
1059
1082
Evs0 = [C || {_,C=#class{event=Evs}} <- get(), Evs =/= false],
1060
1083
Evs = lists:keysort(#class.id, Evs0),
1067
1090
w(" struct { ",[]),
1068
1091
w("int ev_type; int class_id; const char * ev_name;} event_types[] =~n {~n",[]),
1070
lists:foreach(fun(Ev) -> init_event_classes(Ev) end,
1093
lists:foreach(fun(Ev) -> init_event_classes(Ev) end,
1071
1094
[#class{id=0,event=[wxEVT_NULL]}|Evs]),
1072
1095
w(" {-1, 0, ""}~n };~n",[]),
1073
1096
w(" for(int i=0; event_types[i].ev_type != -1; i++) {~n",[]),
1089
1112
init_event_classes(#class{event=ETs, id=Id}) ->
1090
1113
F = fun({Eev, Cev, OtherClass}) ->
1091
1114
w(" {~w + wxEVT_USER_FIRST, ~w, ~p},~n",
1105
1128
Class = get({class,atom_to_list(OtherClass)}),
1106
1129
%%{value, Class} = lists:keysearch(atom_to_list(OtherClass), #class.name, All),
1107
1130
Class#class.id.
1109
1132
encode_events(Evs) ->
1110
1133
?WTC("encode_events"),
1111
1134
w("void wxeEvtListener::forward(wxEvent& event)~n"
1132
1155
" wxeMemEnv *memenv = app->getMemEnv(port);~n"
1133
1156
" if(!memenv) return 0;~n~n"
1134
1157
" wxeReturn rt = wxeReturn(port, cb->listener);~n"),
1136
1159
w("~n rt.addAtom((char*)\"wx\");~n"
1137
1160
" rt.addInt((int) event->GetId());~n"
1138
1161
" rt.addRef(getRef((void *)(cb->obj), memenv), cb->class_name);~n"
1155
1178
w(" app->clearPtr((void *) event);~n"),
1156
1179
w(" } else {~n"),
1157
1180
w(" send_res = rt.send();~n"),
1158
w(" if(cb->skip) event->Skip();~n"),
1181
w(" if(cb->skip) event->Skip();~n"),
1160
1183
w(" return send_res;~n"),
1163
1186
encode_event(C = #class{name=Class, id=Id, options=Opts}) ->
1164
1187
?WTC("encode_event"),
1165
case proplists:get_value("mixed_event", Opts) of
1188
case proplists:get_value("mixed_event", Opts) of
1167
1190
w("case ~p: {// ~s~n", [Id,Class]),
1168
1191
encode_event2(C),
1190
1213
build_event_attrs(ClassRec = #class{name=Class}) ->
1191
1214
Attrs0 = wx_gen_erl:filter_attrs(ClassRec),
1193
fun(Att = #param{name=Name,prot=public,acc=undefined}, {All,Use}) ->
1216
fun(Att = #param{name=Name,prot=public,acc=undefined}, {All,Use}) ->
1194
1217
{[Att#param{name= "ev->" ++ Name}|All],Use};
1195
(Att = #param{acc=Acc}, {All,_}) ->
1218
(Att = #param{acc=Acc}, {All,_}) ->
1196
1219
{[Att#param{name= "ev->" ++ Acc}|All], true}
1198
1221
case foldr(Rename,{[],false},Attrs0) of
1204
1227
w(" ~s * ev = (~s *) event;~n",[Class,Class]),
1206
1229
fun(P=#param{name=N,acc=Acc,type=#type{single=Single,by_val=ByVal,
1208
1231
when Acc =/= undefined ->
1209
1232
Var = var_name(N),
1210
1233
if Single, ByVal ->
1216
1239
P#param{name=Var};
1219
1242
lists:map(FixClass, Attrs)
1222
var_name("ev->" ++ Name0) ->
1245
var_name("ev->" ++ Name0) ->
1223
1246
case reverse(Name0) of
1224
1247
")(" ++ Name -> reverse(Name);
1227
1250
var_name(Name) -> Name.
1229
1252
enum_name({Class,Type}) ->
1230
1253
uppercase_all(Class ++ "_" ++ Type);
1231
1254
enum_name(Type) ->