PageRenderTime 71ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 1ms

/lib/wx/api_gen/wx_gen_cpp.erl

https://github.com/bsmr-erlang/otp
Erlang | 1421 lines | 1272 code | 92 blank | 57 comment | 75 complexity | fe538e4b916c9cf12377fa07a12f9c7d MD5 | raw file
Possible License(s): BSD-3-Clause, LGPL-2.1, MPL-2.0-no-copyleft-exception, Apache-2.0

Large files files are truncated, but you can click here to view the full file

  1. %%
  2. %% %CopyrightBegin%
  3. %%
  4. %% Copyright Ericsson AB 2008-2018. All Rights Reserved.
  5. %%
  6. %% Licensed under the Apache License, Version 2.0 (the "License");
  7. %% you may not use this file except in compliance with the License.
  8. %% You may obtain a copy of the License at
  9. %%
  10. %% http://www.apache.org/licenses/LICENSE-2.0
  11. %%
  12. %% Unless required by applicable law or agreed to in writing, software
  13. %% distributed under the License is distributed on an "AS IS" BASIS,
  14. %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. %% See the License for the specific language governing permissions and
  16. %% limitations under the License.
  17. %%
  18. %% %CopyrightEnd%
  19. %%
  20. %%%-------------------------------------------------------------------
  21. %%% File : wx_gen_cpp.erl
  22. %%% Author : Dan Gudmundsson <dgud@erix.ericsson.se>
  23. %%% Description :
  24. %%%
  25. %%% Created : 19 Feb 2007 by Dan Gudmundsson <dgud@erix.ericsson.se>
  26. %%%-------------------------------------------------------------------
  27. -module(wx_gen_cpp).
  28. -include("wx_gen.hrl").
  29. -compile(export_all).
  30. -import(lists, [foldl/3,foldr/3,reverse/1, keysearch/3, map/2, filter/2]).
  31. -import(gen_util, [lowercase/1, lowercase_all/1, uppercase/1, uppercase_all/1,
  32. open_write/1, close/0, c_copyright/0, w/2, w/1,
  33. args/3, strip_name/2]).
  34. -import(wx_gen, [next_id/1]).
  35. gen(Defs) ->
  36. open_write("../c_src/gen/wxe_derived_dest.h"),
  37. c_copyright(),
  38. w("~n/***** This file is generated do not edit ****/~n~n", []),
  39. gen_derived_dest(Defs),
  40. close(),
  41. open_write("../c_src/gen/wxe_funcs.cpp"),
  42. c_copyright(),
  43. Res = gen_funcs(Defs),
  44. close(),
  45. open_write("../c_src/gen/wxe_macros.h"),
  46. c_copyright(),
  47. gen_macros(),
  48. close(),
  49. open_write("../c_src/gen/wxe_init.cpp"),
  50. c_copyright(),
  51. build_enums(),
  52. close(),
  53. build_events(),
  54. Res.
  55. gen_derived_dest(Defs) ->
  56. [gen_derived_dest_2(Class) || Class <- Defs],
  57. ok.
  58. gen_derived_dest_2(C=#class{name=Class, options=Opts}) ->
  59. ?WTC("gen_derived_dest_2"),
  60. Derived = is_derived(C),
  61. TaylorMade = taylormade_class(C),
  62. if Derived andalso (TaylorMade =:= false) ->
  63. case lists:keysearch(ifdef,1,Opts) of
  64. {value, {ifdef, What}} when is_list(What)-> w("#if ~s~n",[What]);
  65. {value, {ifdef, What}} when is_atom(What) -> w("#if ~p~n",[What]);
  66. _ -> ok
  67. end,
  68. w("class E~s : public ~s {~n",[Class,Class]),
  69. case Class of
  70. "wxGLCanvas" -> %% Special for cleaning up gl context
  71. w(" public: ~~E~s() {deleteActiveGL(this);"
  72. "((WxeApp *)wxTheApp)->clearPtr(this);};~n", [Class]);
  73. _ ->
  74. w(" public: ~~E~s() {((WxeApp *)wxTheApp)->clearPtr(this);};~n", [Class])
  75. end,
  76. gen_constructors(C),
  77. case lists:keysearch(ifdef,1,Opts) of
  78. {value, {ifdef, Endif}} ->
  79. w("};~n", []),
  80. w("#endif // ~p~n~n",[Endif]);
  81. _ ->
  82. w("};~n~n", [])
  83. end;
  84. TaylorMade /= false ->
  85. w("~s~n", [TaylorMade]);
  86. true ->
  87. ignore
  88. end.
  89. taylormade_class(#class{name=CName, methods=Ms}) ->
  90. TaylorMade = lists:any(fun([#method{where=taylormade}|_]) -> true;
  91. (_) -> false
  92. end, Ms),
  93. case TaylorMade of
  94. false -> false;
  95. true ->
  96. {ok, Bin} = file:read_file(filename:join([wx_extra, CName ++".c_src"])),
  97. Src = binary_to_list(Bin),
  98. case gen_util:get_taylor_made(Src, CName ++ "_class") of
  99. nomatch -> false;
  100. {match, [Str0]} -> Str0
  101. end
  102. end.
  103. gen_constructors(#class{name=Class, methods=Ms0}) ->
  104. Ms = lists:append(Ms0),
  105. Cs = lists:filter(fun(#method{method_type=MT}) -> MT =:= constructor end, Ms),
  106. [gen_constructor(Class, Const) || Const <- Cs],
  107. case need_copy_constr(Class) of
  108. true ->
  109. w(" E~s(~s copy) : ~s(copy) {};~n", [Class, Class, Class]);
  110. false ->
  111. ignore
  112. end.
  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, opts=FOpts}) ->
  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. Endif = case lists:keysearch(deprecated, 1, FOpts) of
  122. {value, {deprecated, IfDef}} ->
  123. w("#if ~s~n", [IfDef]),
  124. true;
  125. _ -> false
  126. end,
  127. case lists:any(HaveMergedType, Ps) of
  128. false ->
  129. w(" E~s(~s) : ~s(~s) {};~n",
  130. [Class,args(Gen1,",",Ps),Class,args(CallA,",",Ps)]);
  131. true ->
  132. w(" E~s(~s) : ~s(~s) {};~n",
  133. [Class,args(Gen1,",",Ps),Class,args(CallA,",",Ps)]),
  134. w(" E~s(~s) : ~s(~s) {};~n",
  135. [Class,args(Gen2,",",Ps),Class,args(CallA,",",Ps)])
  136. end,
  137. Endif andalso w("#endif~n", []),
  138. ok.
  139. need_copy_constr("wxFont") -> true;
  140. need_copy_constr("wxIcon") -> true;
  141. need_copy_constr("wxImage") -> true;
  142. need_copy_constr("wxBitmap") -> true;
  143. %%need_copy_constr("wxGraphics" ++ _) -> true;
  144. need_copy_constr(_) -> false.
  145. gen_type(#type{name=Type, ref={pointer,1}, mod=Mod},_) ->
  146. mods(Mod) ++ to_string(Type) ++ " * ";
  147. gen_type(#type{name=Type, ref={pointer,2}, mod=Mod},_) ->
  148. mods(Mod) ++ to_string(Type) ++ " ** ";
  149. gen_type(#type{name=Type, ref=reference, mod=Mod},_) ->
  150. mods(Mod) ++ to_string(Type) ++ "& ";
  151. gen_type(#type{name=Type, ref=undefined, base=binary, mod=Mod},_) ->
  152. mods(Mod) ++ to_string(Type) ++ " * ";
  153. gen_type(#type{name=Type, ref=undefined, single=array, mod=Mod},_) ->
  154. mods(Mod) ++ to_string(Type) ++ " * ";
  155. gen_type(#type{name=Type, ref=undefined, mod=Mod},_) ->
  156. mods(Mod) ++ to_string(Type) ++ " ";
  157. gen_type({merged, _, T1, _,_, _T2,_}, 1) ->
  158. gen_type(T1,error);
  159. gen_type({merged, _, _T1,_, _, T2,_}, 2) ->
  160. gen_type(T2,error).
  161. gen_funcs(Defs) ->
  162. w("~n/***** This file is generated do not edit ****/~n~n"),
  163. w("#include <wx/wx.h>~n"),
  164. w("#include \"../wxe_impl.h\"~n"),
  165. w("#include \"../wxe_events.h\"~n"),
  166. w("#include \"../wxe_return.h\"~n"),
  167. w("#include \"../wxe_gl.h\"~n"),
  168. w("#include \"wxe_macros.h\"~n"),
  169. w("#include \"wxe_derived_dest.h\"~n~n"),
  170. w("#if !wxCHECK_VERSION(2,9,0)~n", []),
  171. [w("#define ~p int~n", [Enum]) ||
  172. Enum <- [wxPenJoin, wxPenCap, wxImageResizeQuality, %%wxBitmapType,
  173. wxPolygonFillMode, wxMappingMode, wxRasterOperationMode,
  174. wxFloodFillStyle
  175. ]],
  176. w("#endif~n",[]),
  177. w("void WxeApp::wxe_dispatch(wxeCommand& Ecmd)~n{~n"),
  178. w(" char * bp = Ecmd.buffer;~n"),
  179. w(" int op = Ecmd.op;~n"),
  180. w(" Ecmd.op = -1;~n"),
  181. w(" wxeMemEnv *memenv = getMemEnv(Ecmd.port);~n"),
  182. %% w(" wxMBConvUTF32 UTFconverter;~n"),
  183. w(" wxeReturn rt = wxeReturn(WXE_DRV_PORT, Ecmd.caller, true);~n"),
  184. w(" try {~n"),
  185. w(" switch (op)~n{~n"),
  186. %% w(" case WXE_CREATE_PORT:~n", []),
  187. %% w(" { newMemEnv(Ecmd.port); } break;~n", []),
  188. %% w(" case WXE_REMOVE_PORT:~n", []),
  189. %% w(" { destroyMemEnv(Ecmd.port); } break;~n", []),
  190. w(" case DESTROY_OBJECT: {~n"),
  191. w(" void *This = getPtr(bp,memenv);~n"),
  192. w(" wxeRefData *refd = getRefData(This);~n"),
  193. w(" if(This && refd) {~n"),
  194. w(" if(recurse_level > 1 && refd->type != 8) {~n"),
  195. w(" delayed_delete->Append(Ecmd.Save(op));~n"),
  196. w(" } else {~n"),
  197. w(" delete_object(This, refd);~n"),
  198. w(" ((WxeApp *) wxTheApp)->clearPtr(This);}~n"),
  199. w(" } } break;~n"),
  200. w(" case WXE_REGISTER_OBJECT: {~n"
  201. " registerPid(bp, Ecmd.caller, memenv);~n"
  202. " rt.addAtom(\"ok\");~n"
  203. " break;~n"
  204. " }~n"),
  205. w(" case WXE_BIN_INCR:~n driver_binary_inc_refc(Ecmd.bin[0].bin);~n break;~n",[]),
  206. w(" case WXE_BIN_DECR:~n driver_binary_dec_refc(Ecmd.bin[0].bin);~n break;~n",[]),
  207. w(" case WXE_INIT_OPENGL:~n wxe_initOpenGL(&rt, bp);~n break;~n",[]),
  208. Res = [gen_class(Class) || Class <- Defs],
  209. w(" default: {~n"),
  210. w(" wxeReturn error = wxeReturn(WXE_DRV_PORT, Ecmd.caller, false);"),
  211. w(" error.addAtom(\"_wxe_error_\");~n"),
  212. w(" error.addInt((int) op);~n"),
  213. w(" error.addAtom(\"not_supported\");~n"),
  214. w(" error.addTupleCount(3);~n"),
  215. w(" error.send();~n"),
  216. w(" return ;~n"),
  217. w(" }~n"),
  218. w("} // switch~n"),
  219. w(" rt.send();~n"),
  220. w("} catch (wxe_badarg badarg) { // try~n"),
  221. w(" wxeReturn error = wxeReturn(WXE_DRV_PORT, Ecmd.caller, false);"),
  222. w(" error.addAtom(\"_wxe_error_\");~n"),
  223. w(" error.addInt((int) op);~n"),
  224. w(" error.addAtom(\"badarg\");~n"),
  225. w(" error.addInt((int) badarg.ref);~n"),
  226. w(" error.addTupleCount(2);~n"),
  227. w(" error.addTupleCount(3);~n"),
  228. w(" error.send();~n"),
  229. w("}} /* The End */~n~n~n"),
  230. UglySkipList = ["wxCaret", "wxCalendarDateAttr",
  231. "wxFileDataObject", "wxTextDataObject", "wxBitmapDataObject",
  232. "wxAuiSimpleTabArt"
  233. ],
  234. w("bool WxeApp::delete_object(void *ptr, wxeRefData *refd) {~n", []),
  235. w(" if(wxe_debug) {\n"
  236. " wxString msg;\n"
  237. " const wxChar *class_info = wxT(\"unknown\");\n"
  238. " if(refd->type < 10) {\n"
  239. " wxClassInfo *cinfo = ((wxObject *)ptr)->GetClassInfo();\n"
  240. " class_info = cinfo->GetClassName();\n"
  241. " }\n"
  242. " msg.Printf(wxT(\"Deleting {wx_ref, %d, %s} at %p \"), refd->ref, class_info, ptr);\n"
  243. " send_msg(\"debug\", &msg);\n"
  244. " };\n"),
  245. w(" switch(refd->type) {~n", []),
  246. w("#if wxUSE_GRAPHICS_CONTEXT~n", []),
  247. w(" case 4: delete (wxGraphicsObject *) ptr; break;~n", []),
  248. w("#endif~n", []),
  249. Case = fun(C=#class{name=Class, id=Id, abstract=IsAbs, parent=P}) when P /= "static" ->
  250. UglyWorkaround = lists:member(Class, UglySkipList),
  251. HaveVirtual = virtual_dest(C),
  252. case hd(reverse(wx_gen_erl:parents(Class))) of
  253. root when IsAbs == false, UglyWorkaround == true ->
  254. w(" case ~p: /* delete (~s *) ptr;"
  255. "These objects must be deleted by owner object */ "
  256. "break;~n", [Id, Class]);
  257. root when IsAbs == false, HaveVirtual == true ->
  258. w(" case ~p: delete (E~s *) ptr; return false;~n", [Id, Class]);
  259. root when IsAbs == false, UglyWorkaround == false ->
  260. w(" case ~p: delete (~s *) ptr; break;~n", [Id, Class]);
  261. _ -> ok
  262. end;
  263. (_) -> ok
  264. end,
  265. [Case(Class) || Class <- Defs],
  266. w(" default: delete (wxObject *) ptr; return false;~n", []),
  267. w(" }~n return true;~n}~n~n", []),
  268. Res.
  269. gen_class(C=#class{name=Name,methods=Ms,options=Opts}) ->
  270. put(current_class, Name),
  271. NewMs =
  272. case lists:member(taylormade, Opts) of
  273. true ->
  274. {ok, Bin} = file:read_file(filename:join([wx_extra,Name++".c_src"])),
  275. ?WTC("gen_class"),
  276. w("~s~n", [binary_to_list(Bin)]),
  277. Ms;
  278. false ->
  279. case lists:keysearch(ifdef,1,Opts) of
  280. {value, {ifdef, What}} ->
  281. is_atom(What) andalso w("#if ~p~n",[What]),
  282. is_list(What) andalso w("#if ~s~n",[What]),
  283. Methods = lists:flatten(Ms),
  284. MsR = [gen_method(Name,M) ||
  285. M <- lists:keysort(#method.id, Methods)],
  286. w("#endif // ~p~n",[What]),
  287. MsR;
  288. false ->
  289. Methods = lists:flatten(Ms),
  290. [gen_method(Name,M) ||
  291. M <- lists:keysort(#method.id, Methods)]
  292. end
  293. end,
  294. erase(current_class),
  295. C#class{methods=NewMs}.
  296. gen_method(_CName, M=#method{where=erl_no_opt}) -> M;
  297. gen_method(CName, M=#method{where=taylormade, name=Name, id=Id}) ->
  298. {ok, Bin} = file:read_file(filename:join([wx_extra, CName ++".c_src"])),
  299. Src = binary_to_list(Bin),
  300. %% io:format("C++ Class ~p ~p~n", [CName, Name]),
  301. Str = case gen_util:get_taylor_made(Src, Name) of
  302. nomatch ->
  303. {match, [Str0]} = gen_util:get_taylor_made(Src, wx_gen_erl:get_unique_name(Id)),
  304. Str0;
  305. {match, [Str0]} ->
  306. Str0
  307. end,
  308. ?WTC("gen_method"),
  309. w(Str, [wx_gen_erl:get_unique_name(Id)]),
  310. M;
  311. gen_method(CName, M=#method{name=N,params=[Ps],method_type=destructor,id=MethodId}) ->
  312. case hd(reverse(wx_gen_erl:parents(CName))) of
  313. root ->
  314. ?WTC("gen_method"),
  315. w("case ~s: { // ~s::~s~n", [wx_gen_erl:get_unique_name(MethodId),CName,N]),
  316. decode_arguments([Ps]),
  317. w(" if(This) {", []),
  318. w(" ((WxeApp *) wxTheApp)->clearPtr((void *) This);~n", []),
  319. w(" delete This;}~n", []),
  320. free_args(),
  321. w(" break;~n}~n", []);
  322. object -> %% Use default
  323. ignore
  324. end,
  325. M;
  326. gen_method(CName, M=#method{name=N,params=Ps0,type=T,method_type=MT,id=MethodId, opts=FOpts}) ->
  327. put(current_func, N),
  328. put(bin_count,-1),
  329. ?WTC("gen_method"),
  330. Endif1 = gen_if(deprecated, FOpts),
  331. Endif2 = gen_if(test_if, FOpts),
  332. w("case ~s: { // ~s::~s~n", [wx_gen_erl:get_unique_name(MethodId),CName,N]),
  333. Ps1 = declare_variables(void, Ps0),
  334. {Ps2,Align} = decode_arguments(Ps1),
  335. Opts = [Opt || Opt = #param{def=Def,in=In,where=Where} <- Ps2,
  336. Def =/= none, In =/= false, Where =/= c],
  337. decode_options(Opts, Align),
  338. case gen_util:get_hook(c, M#method.pre_hook) of
  339. ignore -> skip;
  340. Pre -> w(" ~s;~n", [Pre])
  341. end,
  342. Ps3 = call_wx(N,{MT,CName},T,Ps2),
  343. case gen_util:get_hook(c, M#method.post_hook) of
  344. ignore -> skip;
  345. Post -> w(" ~s;~n", [Post])
  346. end,
  347. free_args(),
  348. build_return_vals(T,Ps3),
  349. w(" break;~n}~n", []),
  350. Endif1 andalso w("#endif~n", []),
  351. Endif2 andalso w("#endif~n", []),
  352. erase(current_func),
  353. M.
  354. gen_if(What, Opts) ->
  355. case lists:keysearch(What, 1, Opts) of
  356. {value, {What, IfDef}} ->
  357. w("#if ~s~n", [IfDef]),
  358. true;
  359. _ -> false
  360. end.
  361. declare_variables(void,Ps) ->
  362. [declare_var(P) || P <- Ps];
  363. declare_variables(T, Ps) ->
  364. declare_type("result", out, ignore, T),
  365. [declare_var(P) || P <- Ps].
  366. declare_var(P = #param{where=erl}) -> P;
  367. declare_var(P = #param{where=this}) -> P;
  368. declare_var(P = #param{name=Name,def=Def,type=Type,in=true}) when Def =/= none ->
  369. declare_type(Name, true, Def, Type),
  370. P;
  371. declare_var(P = #param{in=In}) when In =/= false -> P;
  372. declare_var(P = #param{name=Name,in=In,def=Def,type=Type}) ->
  373. declare_type(Name, In, Def, Type),
  374. P.
  375. declare_type(N,false,_,#type{name="wxArrayInt"}) ->
  376. w(" wxArrayInt ~s;~n", [N]);
  377. declare_type(N,false,_,#type{name="wxArrayDouble"}) ->
  378. w(" wxArrayDouble ~s;~n", [N]);
  379. declare_type(N,false,_,#type{name="wxArrayString"}) ->
  380. w(" wxArrayString ~s;~n", [N]);
  381. declare_type(N,false,_,#type{base=Base,single=true,name=Type,by_val=false,mod=Mod})
  382. when Base =:= int; Base =:= long; Base =:= float; Base =:= double ->
  383. w(" ~s~s ~s;~n", [mods(Mod),Type,N]);
  384. declare_type(N,false,_,#type{base={enum,_},single=true,name=Type,by_val=false,mod=Mod}) ->
  385. w(" ~s~s ~s;~n", [mods(Mod),Type,N]);
  386. declare_type(N,false,_,#type{name="wxArrayTreeItemIds",ref=reference}) ->
  387. w(" wxArrayTreeItemIds ~s;~n", [N]);
  388. declare_type(N,false,_,#type{name="wxDateTime"}) ->
  389. w(" wxDateTime ~s;~n", [N]);
  390. declare_type(N,false,_,#type{name="wxColour"}) ->
  391. w(" wxColour ~s;~n", [N]);
  392. declare_type(N,false,_,#type{name=Type, base=int, ref=reference}) ->
  393. w(" ~s ~s;~n", [Type,N]);
  394. declare_type(N,false,_,#type{name=Type, base=int64, ref=reference}) ->
  395. w(" ~s ~s;~n", [Type,N]);
  396. declare_type(N,false,_,#type{base={comp,_,_},single=true,name=Type,ref=reference}) ->
  397. w(" ~s ~s;~n", [Type,N]);
  398. declare_type(N,true,Def,#type{base=Base,single=true,name=Type,by_val=true})
  399. when Base =:= int; Base =:= long; Base =:= float; Base =:= double; Base =:= bool ->
  400. w(" ~s ~s=~s;~n", [Type,N,Def]);
  401. declare_type(N,true,Def,#type{base={comp,_,_},single=true,name=Type,mod=Mod,ref={pointer,1}}) ->
  402. w(" ~s~s *~s=~s; ~s ~s;~n", [mods(Mod),Type,N,Def,Type,N++"Tmp"]);
  403. declare_type(N,true,Def,#type{base={comp,_,_},single=true,name=Type,ref=reference}) ->
  404. w(" ~s ~s= ~s;~n", [Type,N,Def]);
  405. declare_type(N,true,Def,#type{base={enum,Type},single=true}) ->
  406. w(" ~s ~s=~s;~n", [enum_type(Type),N,Def]);
  407. declare_type(N,true,Def,#type{base={class,_},single=true,name=Type,ref={pointer,1},mod=Mod}) ->
  408. w(" ~s~s * ~s=~s;~n", [mods(Mod),Type,N,Def]);
  409. declare_type(N,true,Def,#type{base={class,_},single=true,name=Type,ref=reference,mod=Mod}) ->
  410. w(" ~s~s * ~s= &~s;~n", [mods(Mod),Type,N,Def]);
  411. declare_type(N,true,Def,#type{base=Base,single=true,name=Type,by_val=false,ref={pointer,1}})
  412. when Base =:= int; Base =:= long; Base =:= float; Base =:= double; Base =:= bool ->
  413. w(" ~s *~s=~s;~n", [Type,N,Def]);
  414. declare_type(N,true,Def,#type{single=true,name="wxArtClient"}) ->
  415. w(" wxArtClient ~s= ~s;~n", [N,Def]);
  416. declare_type(N,true,_Def,#type{name="wxeLocaleC", single=true,base=string}) ->
  417. w(" wxString ~s= wxEmptyString;~n", [N]);
  418. declare_type(N,true,Def,#type{single=true,base=string}) ->
  419. w(" wxString ~s= ~s;~n", [N,Def]);
  420. %% declare_type(N,true,_Def,#type{name="wxString"}) ->
  421. %% w(" wxString ~s= wxEmptyString;~n", [N]);
  422. declare_type(N,true,Def,#type{base=binary, name=char}) ->
  423. w(" char ~sD[] = {~s}, * ~s = ~sD;~n", [N,Def,N,N]);
  424. declare_type(_N,true,_Def,void) ->
  425. skip;
  426. declare_type(_N,true,_Def,voidp) ->
  427. skip;
  428. declare_type(N,true,Def,#type{name=Type, ref={pointer,2}}) ->
  429. %% xxxx
  430. w(" ~s ** ~s = ~s;~n", [Type,N,Def]);
  431. declare_type(N,true,Def,#type{name=Type, single=array, ref={pointer,1}}) ->
  432. w(" int * ~sLen = 0;~n", [N]),
  433. w(" ~s * ~s = ~s;~n", [Type,N,Def]);
  434. declare_type(N,true,"",#type{name="wxArrayString", single=array, ref=reference}) ->
  435. w(" wxArrayString ~s;~n", [N]);
  436. declare_type(N,true,Def,#type{name=Type, base={term,_}}) ->
  437. w(" ~s * ~s= ~s;~n", [Type,N,Def]);
  438. declare_type(N,In,Def,T) ->
  439. ?error({unhandled_type, {N,In,Def,T}}).
  440. decode_options([], _Align) -> ok;
  441. decode_options(Opts, Align) ->
  442. align(Align, 64),
  443. w(" while( * (int*) bp) { switch (* (int*) bp) {~n", []),
  444. foldl(fun decode_opt/2, 1, Opts),
  445. w(" }};~n", []).
  446. decode_opt(#param{name=Name,type=Type}, N) ->
  447. w(" case ~p: {bp += 4;~n", [N]),
  448. Align = decode_arg(Name,Type,opt,1),
  449. align(Align, 64),
  450. w(" } break;~n", []),
  451. N+1.
  452. decode_arguments(Ps0) ->
  453. lists:mapfoldl(fun decode_arg/2,0,Ps0).
  454. store_free(N) ->
  455. case get(free_args) of
  456. undefined -> put(free_args, [N]);
  457. List -> put(free_args, [N|List])
  458. end.
  459. free_args() ->
  460. case get(free_args) of
  461. undefined -> ignore;
  462. List ->
  463. erase(free_args),
  464. [w(" driver_free(~s);~n", [Arg]) || Arg <- List]
  465. end.
  466. decode_arg(P = #param{where=erl},A) -> {P,A};
  467. decode_arg(P = #param{where=c},A) -> {P,A};
  468. decode_arg(P = #param{in=false},A) -> {P,A};
  469. decode_arg(P = #param{def=Def},A) when Def =/= none -> {P,A};
  470. decode_arg(P = #param{name=Name,type=Type},A0) ->
  471. A = decode_arg(Name, Type, arg, A0),
  472. {P, A}.
  473. wa(Decl,DA,Get,GetA,arg) ->
  474. w(Decl,DA),
  475. w(Get,GetA);
  476. wa(_Decl,_DA,Get,GetA,opt) ->
  477. w(Get,GetA).
  478. decode_arg(N,#type{name=Class,base={class,_},single=true},Arg,A0) ->
  479. A = align(A0,32),
  480. wa(" ~s *",[Class],"~s = (~s *) getPtr(bp,memenv); bp += 4;~n",[N,Class],Arg),
  481. A;
  482. decode_arg(N,{merged,_,#type{name=Class,base={class,_},single=true},_,_,_,_},arg,A0) ->
  483. A = align(A0,32),
  484. w(" ~s * ~s = (~s *) getPtr(bp,memenv); bp += 4;~n", [Class,N,Class]),
  485. A;
  486. decode_arg(N,#type{base=long,single=true,name=Type},arg,A0) ->
  487. A = align(A0,64),
  488. w(" long * ~s = (~s *) bp; bp += 8;~n", [N,Type]),
  489. A;
  490. decode_arg(N,#type{base=int,single=true,mod=Mod0,name=Type,ref=Ref},Arg,A0) ->
  491. Mod = mods(Mod0),
  492. case Arg of
  493. arg -> w(" ~s~s * ~s = (~s~s *) bp; bp += 4;~n", [Mod,int,N,Mod,int]);
  494. opt when Ref =:= {pointer,1} ->
  495. w(" ~s = (~s *) bp; bp += 4;~n", [N,int]);
  496. opt ->
  497. w(" ~s = (~s)*(~s~s *) bp; bp += 4;~n", [N,Type,Mod,int])
  498. end,
  499. align(A0,32);
  500. decode_arg(N,#type{base=float,single=true,name=Type},arg,A0) ->
  501. w(" ~s * ~s = (~s *) bp; bp += 4;~n", [Type,N,Type]),
  502. align(A0,32);
  503. decode_arg(N,#type{base=double,single=true,name=Type},Arg,A0) ->
  504. A = align(A0,64),
  505. case Arg of
  506. arg -> w(" ~s * ~s = (~s *) bp; bp += 8;~n", [Type,N,Type]);
  507. opt -> w(" ~s = * (~s *) bp; bp += 8;~n", [N,Type])
  508. end,
  509. A;
  510. decode_arg(N,#type{base=bool,single=true,name=Type},Arg,A0) ->
  511. case Arg of
  512. arg -> w(" bool * ~s = (~s *) bp; bp += 4;~n", [N,Type]);
  513. opt -> w(" ~s = *(~s *) bp; bp += 4;~n", [N,Type])
  514. end,
  515. align(A0,32);
  516. decode_arg(N,#type{base={enum,Type},single=true},Arg,A0) ->
  517. wa(" ~s ", [enum_type(Type)], "~s = *(~s *) bp; bp += 4;;~n",[N, enum_type(Type)], Arg),
  518. align(A0,32);
  519. decode_arg(N,#type{base={comp,"wxDateTime",List},single=true,name=Type,ref=Ref},Arg,A0) ->
  520. Decl = fun({int,Spec}) ->
  521. w(" int * ~s~s = (int *) bp; bp += 4;~n", [N,Spec])
  522. end,
  523. align(A0,32),
  524. lists:foreach(Decl,List),
  525. Name = fun({_,"Mo"}) -> "(wxDateTime::Month) *"++N++"Mo";
  526. ({_,"Y"}) -> "*"++N++"Y";
  527. ({_,Spec}) -> "(wxDateTime::wxDateTime_t) *"++N++Spec
  528. end,
  529. case Arg of
  530. arg -> w(" ~s ~s = ~s(~s);~n", [Type,N,Type,args(Name, ",", List)]);
  531. opt when Ref =:= {pointer,1} ->
  532. w(" ~sTmp = ~s(~s); ~s = & ~sTmp;~n",
  533. [N,Type,args(Name, ",", List), N,N]);
  534. opt ->
  535. w(" ~s = ~s(~s);~n", [N,Type,args(Name, ",", List)])
  536. end,
  537. (A0+length(List)) rem 2;
  538. decode_arg(N,#type{base={comp,_,List},single=true,name=Type,ref=Ref},Arg,A0) ->
  539. Decl = fun({int,Spec}) ->
  540. w(" int * ~s~s = (int *) bp; bp += 4;~n", [N,Spec]);
  541. ({double, Spec}) ->
  542. w(" wxDouble * ~s~s = (wxDouble *) bp; bp += 8;~n", [N,Spec])
  543. end,
  544. case hd(List) of
  545. {int, _} -> align(A0,32);
  546. {double, _} -> align(A0,64)
  547. end,
  548. lists:foreach(Decl,List),
  549. Name = fun({_,Spec}) -> "*"++N++Spec end,
  550. case Arg of
  551. arg -> w(" ~s ~s = ~s(~s);~n", [Type,N,Type,args(Name, ",", List)]);
  552. opt when Ref =:= {pointer,1} ->
  553. w(" ~sTmp = ~s(~s); ~s = & ~sTmp;~n",
  554. [N,Type,args(Name, ",", List), N,N]);
  555. opt ->
  556. w(" ~s = ~s(~s);~n", [N,Type,args(Name, ",", List)])
  557. end,
  558. case hd(List) of
  559. {int, _} -> (A0+length(List)) rem 2;
  560. {double, _} -> 0
  561. end;
  562. decode_arg(N,#type{name=Class="wxTreeItemId",single=true},Arg,A0) ->
  563. A = align(A0,64),
  564. wa(" ~s ",[Class],"~s = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;~n",[N],Arg),
  565. A;
  566. decode_arg(N,#type{name=Class="wxTreeItemIdValue",single=true},Arg,A0) ->
  567. A = align(A0,64),
  568. wa(" ~s ",[Class],"~s = (~s) * (wxUint64 *) bp; bp += 8;~n",[N,Class],Arg),
  569. A;
  570. decode_arg(N,#type{name="wxChar", single=S},Arg,A0)
  571. when S =/= true ->
  572. w(" int * ~sLen = (int *) bp; bp += 4;~n", [N]),
  573. wa(" wxString", []," ~s = wxString(bp, wxConvUTF8);~n", [N],Arg),
  574. w(" bp += *~sLen+((8-((~p+ *~sLen) & 7)) & 7);~n", [N,4*((A0+1) rem 2),N]),
  575. 0;
  576. decode_arg(N,#type{base=string, name="wxFileName"},Arg,A0) ->
  577. w(" int * ~sLen = (int *) bp; bp += 4;~n", [N]),
  578. wa(" wxString", []," ~sStr = wxString(bp, wxConvUTF8);~n", [N],Arg),
  579. w(" bp += *~sLen+((8-((~p+ *~sLen) & 7)) & 7);~n", [N,4*((A0+1) rem 2),N]),
  580. w(" wxFileName ~s = wxFileName(~sStr);~n",[N,N]),
  581. 0;
  582. decode_arg(N,#type{base=string},Arg,A0) ->
  583. w(" int * ~sLen = (int *) bp; bp += 4;~n", [N]),
  584. wa(" wxString", []," ~s = wxString(bp, wxConvUTF8);~n", [N],Arg),
  585. w(" bp += *~sLen+((8-((~p+ *~sLen) & 7)) & 7);~n", [N,4*((A0+1) rem 2),N]),
  586. 0;
  587. decode_arg(N,#type{name="wxArrayString"},Place,A0) ->
  588. w(" int * ~sLen = (int *) bp; bp += 4;~n", [N]),
  589. case Place of
  590. arg -> w(" wxArrayString ~s;~n", [N]);
  591. opt -> ignore %% Already declared
  592. end,
  593. w(" int ~sASz = 0, * ~sTemp;~n", [N,N]),
  594. w(" for(int i=0; i < *~sLen; i++) {~n", [N]),
  595. w(" ~sTemp = (int *) bp; bp += 4;~n", [N]),
  596. w(" ~s.Add(wxString(bp, wxConvUTF8));~n", [N]),
  597. w(" bp += *~sTemp;~n", [N]),
  598. w(" ~sASz += *~sTemp+4;~n }~n", [N,N]),
  599. w(" bp += (8-((~p+ ~sASz) & 7 )) & 7;~n", [4*((A0+1) rem 2),N]),
  600. 0;
  601. decode_arg(N,#type{name="wxArrayInt"},arg,A0) ->
  602. w(" int * ~sLen = (int *) bp; bp += 4;~n", [N]),
  603. w(" wxArrayInt ~s;~n", [N]),
  604. w(" for(int i=0; i < *~sLen; i++) {", [N]),
  605. w(" ~s.Add(*(int *) bp); bp += 4;}~n", [N]),
  606. w(" bp += ((*~sLen + ~p) % 2 )*4;~n",[N, (A0+1)]),
  607. 0;
  608. decode_arg(N,#type{name="wxArrayDouble"},arg,A0) ->
  609. w(" int * ~sLen = (int *) bp; bp += 4;~n", [N]),
  610. align(A0+1,64),
  611. w(" wxArrayDouble ~s;~n", [N]),
  612. w(" for(int i=0; i < *~sLen; i++) {", [N]),
  613. w(" ~s.Add(*(int *) bp); bp += 4;}~n", [N]),
  614. 0;
  615. decode_arg(_N,#type{base=eventType},_Arg,A0) ->
  616. %% w(" int * ~sLen = (int *) bp; bp += 4;~n", [N]),
  617. %% case Arg of
  618. %% arg ->
  619. %% w(" int ~s = wxeEventTypeFromAtom(bp);bp += *~sLen;~n",[N,N]),
  620. %% w(" char *class_name = bp;~n", []),
  621. %% w(" wxeCallbackData * Evt_cb = new wxeCallbackData(Ecmd.caller,This,class_name);~n",
  622. %% [])
  623. %% end,
  624. A0;
  625. decode_arg(N,#type{name=Type,base=binary,mod=Mod0},Arg,A0) ->
  626. Mod = mods([M || M <- Mod0]),
  627. case Arg of
  628. arg ->
  629. w(" ~s~s * ~s = (~s~s*) Ecmd.bin[~p].base;~n",
  630. [Mod,Type,N,Mod,Type, next_id(bin_count)]);
  631. opt ->
  632. w(" ~s = (~s~s*) Ecmd.bin[~p].base;~n",
  633. [N,Mod,Type,next_id(bin_count)])
  634. end,
  635. A0;
  636. decode_arg(N,#type{base={term,"wxTreeItemData"},mod=Mod0},Arg,A0) ->
  637. Mod = mods([M || M <- Mod0]),
  638. Type = "wxETreeItemData",
  639. BinCnt = next_id(bin_count),
  640. case Arg of
  641. arg ->
  642. w(" ~s~s * ~s = new ~s(Ecmd.bin[~p].size, Ecmd.bin[~p].base);~n",
  643. [Mod,Type,N,Type,BinCnt,BinCnt]);
  644. opt ->
  645. w(" ~s = new ~s(Ecmd.bin[~p].size, Ecmd.bin[~p].base);~n",
  646. [N,Type,BinCnt,BinCnt])
  647. end,
  648. A0;
  649. decode_arg(N,#type{name=Type,base={term,_},mod=Mod0},Arg,A0) ->
  650. Mod = mods([M || M <- Mod0]),
  651. BinCnt = next_id(bin_count),
  652. case Arg of
  653. arg ->
  654. w(" ~s~s * ~s = new ~s(&Ecmd.bin[~p]);~n",
  655. [Mod,Type,N,Type,BinCnt]);
  656. opt ->
  657. w(" ~s = new ~s(&Ecmd.bin[~p]);~n",
  658. [N,Type,BinCnt])
  659. end,
  660. A0;
  661. decode_arg(N,#type{single=array,base=int},Arg,A0) ->
  662. case Arg of
  663. arg ->
  664. w(" int * ~sLen = (int *) bp; bp += 4;~n", [N]),
  665. w(" int * ~s = (int *) bp; bp += *~sLen*4+((~p+ *~sLen)%2 )*4;~n",
  666. [N,N,(A0+1) rem 2,N]);
  667. opt ->
  668. w(" ~sLen = (int *) bp; bp += 4;~n", [N]),
  669. w(" ~s = (int *) bp; bp += *~sLen*4+((~p+ *~sLen)%2 )*4;~n",
  670. [N,N,(A0+1) rem 2,N])
  671. end,
  672. 0;
  673. decode_arg(N,#type{by_val=true,single=array,base={comp,Class="wxPoint",_}},arg,A0) ->
  674. w(" int * ~sLen = (int *) bp; bp += 4;~n", [N]),
  675. w(" ~s *~s;~n",[Class,N]),
  676. w(" ~s = (~s *) driver_alloc(sizeof(~s) * *~sLen);~n",[N,Class,Class,N]),
  677. store_free(N),
  678. w(" for(int i=0; i < *~sLen; i++) {~n", [N]),
  679. w(" int x = * (int *) bp; bp += 4;~n int y = * (int *) bp; bp += 4;~n", []),
  680. w(" ~s[i] = wxPoint(x,y);}~n", [N]),
  681. align(A0,32);
  682. decode_arg(N,#type{by_val=true,single=array,base={class,Class}},arg,A0) ->
  683. A = align(A0,32),
  684. w(" int * ~sLen = (int *) bp; bp += 4;~n", [N]),
  685. w(" ~s *~s;~n",[Class,N]),
  686. w(" ~s = (~s *) driver_alloc(sizeof(~s) * *~sLen);", [N, Class, Class, N]),
  687. store_free(N),
  688. w(" for(int i=0; i < *~sLen; i++) {", [N]),
  689. w(" ~s[i] = * (~s *) getPtr(bp,memenv); bp += 4;}~n", [N,Class]),
  690. w(" bp += ((~p+ *~sLen)%2 )*4;~n", [A, N]),
  691. 0;
  692. decode_arg(N,#type{name=Type,single=list,base={class,Class}},arg,A0) ->
  693. w(" int * ~sLen = (int *) bp; bp += 4;~n", [N]),
  694. A = align(A0,32),
  695. w(" ~s ~s;~n",[Type,N]),
  696. w(" for(int i=0; i < *~sLen; i++) {", [N]),
  697. w(" ~s.Append(*(~s *) getPtr(bp,memenv)); bp += 4;}~n", [N,Class]),
  698. w(" bp += ((~p+ *~sLen)%2 )*4;~n", [A,N]),
  699. 0;
  700. decode_arg(N,#type{single=array,base={comp,Class="wxPoint2DDouble",_}},arg,A0) ->
  701. w(" int * ~sLen = (int *) bp; bp += 4;~n", [N]),
  702. w(" ~s *~s;~n",[Class,N]),
  703. w(" ~s = (~s *) driver_alloc(sizeof(~s) * *~sLen);~n",[N,Class,Class,N]),
  704. store_free(N),
  705. align(A0+1,64),
  706. w(" for(int i=0; i < *~sLen; i++) {~n", [N]),
  707. w(" double x = * (double *) bp; bp += 8;~n double y = * (double *) bp; bp += 8;~n", []),
  708. w(" ~s[i] = wxPoint2DDouble(x,y);}~n", [N]),
  709. 0;
  710. decode_arg(Name,T, Arg,_A) ->
  711. ?error({unhandled_type, {Name,T, Arg}}).
  712. align(0, 32) -> 1;
  713. align(1, 32) -> 0;
  714. align(0, 64) -> 0;
  715. align(1, 64) ->
  716. w(" bp += 4; /* Align */~n"),
  717. 0;
  718. align(N,Sz) ->
  719. align(N rem 2, Sz).
  720. call_wx(_N,{constructor,_},#type{base={class,RClass}},Ps) ->
  721. #class{id=Id} = ClassDef = get({class,RClass}),
  722. Class = case is_derived(ClassDef) of
  723. true -> "E" ++ RClass;
  724. false -> RClass
  725. end,
  726. w(" ~s * Result = new ~s(~s);~n",
  727. [RClass, Class,args(fun call_arg/1, ",",filter(Ps))]),
  728. CType = case is_window(RClass) of
  729. true -> %% Windows have parents that should be deleted first
  730. case is_dialog(RClass) of
  731. true -> 2; %% Dialogs must be closed first event before windows
  732. false -> 0
  733. end;
  734. false ->
  735. case is_dc(RClass) of
  736. true -> 8;
  737. false ->
  738. case hd(reverse(wx_gen_erl:parents(RClass))) of
  739. root -> Id;
  740. _ -> 1
  741. end
  742. end
  743. end,
  744. case virtual_dest(ClassDef) orelse (CType =/= 0) of
  745. true ->
  746. w(" newPtr((void *) Result, ~p, memenv);~n", [CType]);
  747. false -> %% Hmm window without virt dest
  748. w(" /* Possible memory leak here, class is missing virt dest */ \n")
  749. end,
  750. Ps;
  751. call_wx(N,{member,_},Type,Ps) ->
  752. {Beg,End} = return_res(Type),
  753. w(" if(!This) throw wxe_badarg(0);~n",[]),
  754. w(" ~sThis->~s(~s)~s;~n",[Beg,N,args(fun call_arg/1, ",",filter(Ps)),End]),
  755. Ps;
  756. call_wx(N,{static,Class},Type,Ps) ->
  757. {Beg,End} = return_res(Type),
  758. #class{parent=Parent} = get({class,Class}),
  759. case Parent of
  760. "static" ->
  761. w(" ~s::~s(~s)~s;~n",[Beg,N,args(fun call_arg/1, ",",filter(Ps)),End]);
  762. _ ->
  763. w(" ~s~s::~s(~s)~s;~n",[Beg,Class,N,args(fun call_arg/1, ",",filter(Ps)),End])
  764. end,
  765. Ps.
  766. return_res(void) -> {"", ""};
  767. return_res(Type = #type{mod=Mod}) ->
  768. case lists:member(const, Mod) of
  769. true ->
  770. {Beg, End} = return_res1(Type),
  771. {"const " ++ Beg, End};
  772. _ ->
  773. return_res1(Type)
  774. end.
  775. return_res1(#type{name=Type,ref={pointer,_}, base={term,_}}) ->
  776. {Type ++ " * Result = (" ++ Type ++ "*)", ""};
  777. return_res1(#type{name=Type,ref={pointer,_}}) ->
  778. {Type ++ " * Result = (" ++ Type ++ "*)", ""};
  779. return_res1(#type{name=Type,single=true,by_val=false,ref=reference}) ->
  780. {Type ++ " * Result = &", ""};
  781. return_res1(#type{name=Type,single=true,by_val=true})
  782. when is_atom(Type) ->
  783. {atom_to_list(Type) ++ " Result = ", ""};
  784. return_res1(#type{name=Type="wxArrayInt"}) ->
  785. {Type ++ " Result = ", ""};
  786. return_res1(#type{name=Type,base={class,_},single=list,ref=reference}) ->
  787. {Type ++ " Result = ", ""};
  788. return_res1(#type{name=Type,base={comp,_,_},single=array,by_val=true}) ->
  789. {Type ++ " Result = ", ""};
  790. return_res1(#type{name=Type,single=true,by_val=true, base={class, _}}) ->
  791. case {need_copy_constr(Type), Type} of
  792. {true, _} ->
  793. {Type ++ " * Result = new E" ++ Type ++ "(", "); newPtr((void *) Result,"
  794. ++ "3, memenv);"};
  795. {false, "wxGraphics" ++ _} ->
  796. %% {"wxGraphicsObject * Result = new wxGraphicsObject(", "); newPtr((void *) Result,"
  797. %% ++ "3, memenv);"};
  798. {Type ++ " * Result = new " ++ Type ++ "(", "); newPtr((void *) Result,"
  799. ++ "4, memenv);"};
  800. {false, _} ->
  801. %% Temporary memory leak !!!!!!
  802. io:format("~s::~s Building return value of temp ~s~n",
  803. [get(current_class),get(current_func),Type]),
  804. {Type ++ " * Result = new " ++ Type ++ "(", "); newPtr((void *) Result,"
  805. ++ "3, memenv);"}
  806. end;
  807. return_res1(#type{base={enum,_Type},single=true,by_val=true}) ->
  808. {"int Result = " , ""};
  809. return_res1(#type{name="wxCharBuffer", base={binary,_},single=true,by_val=true}) ->
  810. {"char * Result = ", ".data()"};
  811. return_res1(#type{name=Type,single=array,ref=reference}) ->
  812. {Type ++ " Result = ", ""};
  813. return_res1(#type{name=Type,single=true,by_val=true}) ->
  814. {Type ++ " Result = ", ""}.
  815. filter(Ps) ->
  816. lists:filter(fun filter_arg/1, Ps).
  817. filter_arg(#param{where=erl}) -> false;
  818. filter_arg(#param{where=this}) -> false;
  819. filter_arg(#param{}) -> true.
  820. %%filter_arg(#param{def=Def, in=In}) -> Def =:= none orelse In =:= false.
  821. call_arg(#param{where=c, alt={length,Alt}}) when is_list(Alt) ->
  822. "*" ++ Alt ++ "Len";
  823. call_arg(#param{where=c, alt={size,Id}}) when is_integer(Id) ->
  824. %% It's a binary
  825. "Ecmd.bin["++ integer_to_list(Id) ++ "].size";
  826. call_arg(#param{name=N,def=Def,type=#type{by_val=true,single=true,base=Base}})
  827. when Base =:= int; Base =:= long; Base =:= float; Base =:= double; Base =:= bool ->
  828. case Def of
  829. none -> "*" ++ N;
  830. _ -> N
  831. end;
  832. call_arg(#param{name=N,type=#type{base={enum,_Type}, by_val=true,single=true}}) ->
  833. N;
  834. call_arg(#param{name=N,type=#type{base={class,_},by_val=true,single=true}}) -> "*" ++ N;
  835. call_arg(#param{name=N,type=#type{base={class,_},ref=reference,single=true}}) -> "*" ++ N;
  836. call_arg(#param{name=N,type=#type{base=eventType}}) ->
  837. N ++ ", (wxObjectEventFunction)(wxEventFunction) &WxeApp::handle_evt, Evt_cb, this";
  838. call_arg(#param{name=N,type=#type{by_val=true, single=_False}}) -> N;
  839. call_arg(#param{name=N,def=Def,type=#type{by_val=false, ref={pointer,2}}})
  840. when Def =/= none -> N;
  841. call_arg(#param{name=N,type=#type{by_val=false, ref={pointer,2}}}) -> "&" ++ N;
  842. call_arg(#param{name=N,in=false,type=#type{ref=reference, single=true}}) -> N;
  843. call_arg(#param{name=N,in=false,type=#type{by_val=false, single=true}}) -> "&" ++ N;
  844. call_arg(#param{name=N,def=Def,type=#type{base={comp,_,_},ref={pointer,1},single=true}})
  845. when Def =:= none ->
  846. "&" ++N;
  847. call_arg(#param{name=N,type=#type{base=int, ref=reference, single=true}}) -> "*" ++ N;
  848. call_arg(#param{name=N,type=#type{by_val=false}}) -> N;
  849. call_arg(#param{name=N,type={merged,_,#type{base={class,_},single=true,
  850. by_val=ByVal,
  851. ref=Ref},_,_,_,_}})
  852. when ByVal =:= true; Ref =:= reference ->
  853. "*" ++ N;
  854. call_arg(#param{def=Def, type=void}) when Def =/= none -> Def;
  855. call_arg(#param{def=Def, type=voidp}) when Def =/= none -> "(void **) " ++ Def;
  856. call_arg(#param{name=N,type=#type{base={ref,_},by_val=true,single=true}}) -> N;
  857. call_arg(#param{name=N,type={merged,_,_,_,_,_,_}}) -> N.
  858. %% call_arg(#param{name=N,type=#type{base=Tuple,ref=reference}})
  859. %% when is_tuple(Tuple) -> "&" ++ N;
  860. to_string(Type) when is_atom(Type) -> atom_to_list(Type);
  861. to_string(Type) when is_list(Type) -> Type.
  862. virtual_dest(#class{abstract=true, parent=Parent}) ->
  863. virtual_dest(get_parent_class(Parent));
  864. virtual_dest(#class{methods=Ms, parent=Parent}) ->
  865. case lists:keysearch(destructor,#method.method_type, lists:append(Ms)) of
  866. {value, #method{method_type=destructor, virtual=Virtual}} ->
  867. case Virtual of
  868. true -> true;
  869. _ -> virtual_dest(get_parent_class(Parent))
  870. end;
  871. false -> virtual_dest(get_parent_class(Parent))
  872. end;
  873. virtual_dest("root") -> false;
  874. virtual_dest("object") -> true.
  875. get_parent_class(Parent) ->
  876. case get({class, Parent}) of
  877. undefined -> Parent;
  878. Class -> Class
  879. end.
  880. debug(F,A) ->
  881. case get(debug) of
  882. true -> ?warning(F,A);
  883. _ -> ok
  884. end.
  885. is_derived(#class{abstract=true}) -> false;
  886. is_derived(C = #class{}) -> virtual_dest(C).
  887. is_window(Class) ->
  888. lists:member("wxWindow", wx_gen_erl:parents(Class)).
  889. is_dialog(Class) ->
  890. lists:member("wxDialog", wx_gen_erl:parents(Class)).
  891. is_dc(Class) ->
  892. Parents = wx_gen_erl:parents(Class),
  893. lists:member("wxDC", Parents) orelse lists:member("wxGraphicsContext", Parents).
  894. build_return_vals(Type,Ps0) ->
  895. Ps = [P || P = #param{in=In} <- Ps0, In =/= true],
  896. HaveType = case Type of void -> 0; _ -> 1 end,
  897. NoOut = length(Ps) + HaveType,
  898. OutTupSz = if NoOut > 1 -> NoOut; true -> 0 end,
  899. CountFloats = fun(#param{type=#type{base=Float, single=true}}, Acc)
  900. when Float =:= float; Float =:= double ->
  901. Acc + 1;
  902. (_, Acc) ->
  903. Acc
  904. end,
  905. NofFloats = lists:foldl(CountFloats, 1, Ps),
  906. case NofFloats > 1 of
  907. true -> %%io:format("Floats ~p:~p ~p ~n",[get(current_class),get(current_func), NofFloats]);
  908. w(" rt.ensureFloatCount(~p);~n",[NofFloats]);
  909. false -> ignore
  910. end,
  911. build_ret_types(Type,Ps),
  912. if
  913. OutTupSz > 1 -> w(" rt.addTupleCount(~p);~n",[OutTupSz]);
  914. true -> ignore
  915. end,
  916. Ps.
  917. build_ret_types(void,Ps) ->
  918. Calc = fun(#param{name=N,in=In,type=T}, Free) ->
  919. case build_ret(N, {arg, In}, T) of
  920. ok -> Free;
  921. Other -> [Other|Free]
  922. end
  923. end,
  924. lists:foldl(Calc, [], Ps);
  925. build_ret_types(Type,Ps) ->
  926. Free = case build_ret("Result", {ret, out}, Type) of
  927. ok -> [];
  928. FreeStr -> [FreeStr]
  929. end,
  930. Calc = fun(#param{name=N,in=In,type=T}, FreeAcc) ->
  931. case build_ret(N, {arg, In}, T) of
  932. ok -> FreeAcc;
  933. FreeMe -> [FreeMe|FreeAcc]
  934. end
  935. end,
  936. lists:foldl(Calc, Free, Ps).
  937. build_ret(Name,_D,#type{base={class,Class},single=true}=_T) ->
  938. case Class of
  939. "wxGraphicsContext" ->
  940. w(" rt.addRef(getRef((void *)~s,memenv,8), \"~s\");~n",[Name,Class]);
  941. _ ->
  942. w(" rt.addRef(getRef((void *)~s,memenv), \"~s\");~n",[Name,Class])
  943. end;
  944. build_ret(Name,_,#type{name="wxTreeItemId",single=true}) ->
  945. w(" rt.add((wxUIntPtr *) ~s.m_pItem);~n",[Name]);
  946. build_ret(Name,_,#type{name="wxTreeItemIdValue",single=true}) ->
  947. w(" rt.add((wxUIntPtr *) ~s);~n",[Name]);
  948. build_ret(Name,_,#type{base={term,_},single=true}) ->
  949. w(" rt.addExt2Term(~s);~n", [Name]);
  950. build_ret(Name,_,#type{base={binary,Size},single=true}) ->
  951. w(" if(~s) {~n", [Name]),
  952. w(" rt.addBinary(~s, ~s);~n", [Name,Size]),
  953. w(" } else {rt.addAtom(\"null\");};~n");
  954. build_ret(Name,_,#type{name="wxUIntPtr", ref={pointer,1}, single=true}) ->
  955. w(" rt.add(~s);~n", [Name]);
  956. build_ret(Name,_,#type{base={enum,_Type},single=true}) ->
  957. w(" rt.addInt(~s);~n",[Name]);
  958. build_ret(Name,_,#type{base={comp,_,{record, _}},single=true}) ->
  959. w(" rt.add(~s);~n", [Name]);
  960. build_ret(Name,{ret,_},#type{base={comp,_,_},single=true, by_val=true}) ->
  961. w(" rt.add(~s);~n",[Name]);
  962. build_ret(Name,{ret,_},#type{base={comp,_,_},single=true, ref=reference}) ->
  963. w(" rt.add((*~s));~n",[Name]);
  964. build_ret(Name,_,#type{base={comp,_,_},single=true}) ->
  965. w(" rt.add(~s);~n",[Name]);
  966. build_ret(Name = "ev->m_scanCode",_,#type{base=bool,single=true,by_val=true}) ->
  967. %% Hardcoded workaround for 2.9 and later
  968. w("#if !wxCHECK_VERSION(2,9,0)~n", []),
  969. w(" rt.addBool(~s);~n",[Name]),
  970. w("#else~n rt.addBool(false);~n",[]),
  971. w("#endif~n",[]);
  972. build_ret(Name = "ev->m_metaDown",_,#type{base=bool,single=true,by_val=true}) ->
  973. %% Hardcoded workaround for MAC on 2.9 and later
  974. w("#if wxCHECK_VERSION(2,9,0) && defined(_MACOSX)~n", []),
  975. w(" rt.addBool(ev->m_rawControlDown);~n",[]),
  976. w("#else~n rt.addBool(~s);~n",[Name]),
  977. w("#endif~n",[]);
  978. build_ret(Name,_,#type{base=bool,single=true,by_val=true}) ->
  979. w(" rt.addBool(~s);~n",[Name]);
  980. build_ret(Name,{arg, both},#type{base=int,single=true,mod=M}) ->
  981. case lists:member(unsigned, M) of
  982. true -> w(" rt.addUint(*~s);~n",[Name]);
  983. false -> w(" rt.addInt(*~s);~n",[Name])
  984. end;
  985. build_ret(Name,_,#type{base=int,single=true,mod=M}) ->
  986. case lists:member(unsigned, M) of
  987. true -> w(" rt.addUint(~s);~n",[Name]);
  988. false -> w(" rt.addInt(~s);~n",[Name])
  989. end;
  990. build_ret(Name,_,#type{name="wxArrayInt"}) ->
  991. w(" rt.add(~s);~n", [Name]);
  992. build_ret(Name,_,#type{name="wxArrayDouble"}) ->
  993. w(" rt.add(~s);~n", [Name]);
  994. build_ret(Name,_,#type{base={comp,_,_},single=array}) ->
  995. w(" for(unsigned int i=0; i < ~s.GetCount(); i++) {~n", [Name]),
  996. w(" rt.add(~s[i]);~n }~n",[Name]),
  997. w(" rt.endList(~s.GetCount());~n",[Name]);
  998. build_ret(Name,_,#type{base={class,Class},single=array}) ->
  999. w(" for(unsigned int i=0; i < ~s.GetCount(); i++) {~n", [Name]),
  1000. w(" rt.addRef(getRef((void *) &~s.Item(i), memenv), \"~s\");~n }~n",[Name, Class]),
  1001. w(" rt.endList(~s.GetCount());~n",[Name]);
  1002. build_ret(Name,_,#type{name=List,single=list,base={class,Class}}) ->
  1003. w(" int i=0;~n"),
  1004. w(" for(~s::const_iterator it = ~s.begin(); it != ~s.end(); ++it) {~n",
  1005. [List, Name, Name]),
  1006. w(" ~s * ~sTmp = *it;~n", [Class,Name]),
  1007. w(" rt.addRef(getRef((void *)~sTmp,memenv), \"~s\"); i++;}~n",[Name,Class]),
  1008. w(" rt.endList(~s.GetCount());~n",[Name]);
  1009. build_ret(Name,_,#type{name="wxArrayTreeItemIds"}) ->
  1010. w(" for(unsigned int i=0; i < ~s.GetCount(); i++) {~n", [Name]),
  1011. w(" rt.add((wxUIntPtr *)~s[i].m_pItem);}~n",[Name]),
  1012. w(" rt.endList(~s.GetCount());~n",[Name]);
  1013. build_ret(Name,_,#type{base=float,single=true}) ->
  1014. w(" rt.addFloat(~s);~n",[Name]);
  1015. build_ret(Name,_,#type{base=double,single=true}) ->
  1016. w(" rt.addFloat(~s);~n",[Name]);
  1017. build_ret(Name,_,#type{name="wxeLocaleC"}) ->
  1018. w(" rt.add(wxeLocaleC2String(~s));~n",[Name]);
  1019. build_ret(Name,_,#type{base=string,single=true}) ->
  1020. w(" rt.add(~s);~n",[Name]);
  1021. build_ret(Name,_,#type{name="wxArrayString", single=array}) ->
  1022. w(" rt.add(~s);~n", [Name]);
  1023. build_ret(Name,_,#type{name="wxString", single={list,Variable}}) ->
  1024. Obj = case Name of
  1025. "ev->" ++ _ -> "ev";
  1026. _ -> "This"
  1027. end,
  1028. w(" wxArrayString tmpArrayStr(~s->~s, ~s);~n", [Obj,Variable,Name]),
  1029. w(" rt.add(tmpArrayStr);~n", []);
  1030. build_ret(Name,In,T) ->
  1031. ?error({nyi, Name,In, T}).
  1032. mods([const|R]) -> "const " ++ mods(R);
  1033. mods([unsigned|R]) -> "unsigned " ++ mods(R);
  1034. mods([]) -> "".
  1035. build_enums() ->
  1036. Tree = get(consts),
  1037. w(" /* This file is also generated */~n"),
  1038. w("#include <wx/wx.h>~n"),
  1039. w("#include \"../wxe_impl.h\"~n"),
  1040. w("#include \"wxe_macros.h\"~n"),
  1041. w("#include \"../wxe_return.h\"~n"),
  1042. w("void WxeApp::init_nonconsts(wxeMemEnv *memenv, ErlDrvTermData caller) {~n"),
  1043. NotConsts = [NC || NC = #const{is_const=false} <- gb_trees:values(Tree)],
  1044. Size = length(NotConsts),
  1045. GVars = get(gvars),
  1046. GSize = length(GVars),
  1047. w(" wxeReturn rt = wxeReturn(WXE_DRV_PORT, caller);~n"),
  1048. w(" rt.addAtom((char*)\"wx_consts\");~n"),
  1049. [build_enum(NConst) || NConst <- lists:keysort(#const.val, NotConsts)],
  1050. _Cnt = foldl(fun(Gvar, I) -> build_gvar(Gvar,I) end, 0, lists:sort(GVars)),
  1051. w(" rt.endList(~p);~n", [Size+GSize]),
  1052. w(" rt.addTupleCount(2);~n"),
  1053. w(" rt.send();~n"),
  1054. w("}~n"),
  1055. ok.
  1056. build_enum(#const{name=Name}) ->
  1057. w(" rt.addAtom(\"~s\"); rt.addInt(~s);~n", [Name, Name]),
  1058. w(" rt.addTupleCount(2);~n").
  1059. build_gvar({Name, "wxColour", _Id}, Cnt) ->
  1060. w(" rt.addAtom(\"~s\"); rt.add(*(~s));~n",[Name,Name]),
  1061. w(" rt.addTupleCount(2);~n"),
  1062. Cnt;
  1063. build_gvar({Name, {address,Class}, _Id}, Cnt) ->
  1064. w(" rt.addAtom(\"~s\"); rt.addRef(getRef((void *)&~s,memenv), \"~s\");~n",[Name,Name,Class]),
  1065. w(" rt.addTupleCount(2);~n"),
  1066. Cnt+1;
  1067. build_gvar({Name, {test_if,Test}, _Id}, Cnt) ->
  1068. w("#if ~s~n", [Test]),
  1069. w(" rt.addAtom(\"~s\"); rt.addInt(~s);~n", [Name, Name]),
  1070. w(" rt.addTupleCount(2);~n"),
  1071. w("#else~n", []),
  1072. w(" rt.addAtom(\"~s\"); rt.addAtom(\"undefined\");~n", [Name]),
  1073. w(" rt.addTupleCount(2);~n"),
  1074. w("#endif~n", []),
  1075. Cnt+1;
  1076. build_gvar({Name, Class, _Id}, Cnt) ->
  1077. w(" rt.addAtom(\"~s\"); rt.addRef(getRef((void *)~s,memenv),\"~s\");~n",[Name,Name,Class]),
  1078. w(" rt.addTupleCount(2);~n"),
  1079. Cnt+1.
  1080. gen_macros() ->
  1081. w("#include <wx/caret.h>~n"), %% Arrg wxw forgot?? some files
  1082. w("#include <wx/tooltip.h>~n"),
  1083. w("#include <wx/gbsizer.h>~n"),
  1084. w("#include <wx/splash.h>~n"),
  1085. w("#include <wx/grid.h>~n"),
  1086. w("#include <wx/image.h>~n"),
  1087. w("#include <wx/tglbtn.h>~n"),
  1088. w("#include <wx/calctrl.h>~n"),
  1089. w("#include <wx/dirctrl.h>~n"),
  1090. w("#include <wx/listctrl.h>~n"),
  1091. w("#include <wx/treectrl.h>~n"),
  1092. w("#include <wx/spinbutt.h>~n"),
  1093. w("#include <wx/spinctrl.h>~n"),
  1094. w("#include <wx/colordlg.h>~n"),
  1095. w("#include <wx/fdrepdlg.h>~n"),
  1096. w("#include <wx/fontdlg.h>~n"),
  1097. w("#include <wx/progdlg.h>~n"),
  1098. w("#include <wx/printdlg.h>~n"),
  1099. w("#include <wx/display.h>~n"),
  1100. w("#include <wx/dcbuffer.h>~n"),
  1101. w("#include <wx/dcmirror.h>~n"),
  1102. w("#include <wx/glcanvas.h>~n"),
  1103. w("#include <wx/dcps.h>~n"),
  1104. w("#include <wx/xrc/xmlres.h>~n"),
  1105. w("#include <wx/html/htmprint.h>~n"),
  1106. w("#include <wx/stc/stc.h>~n"),
  1107. w("#include <wx/minifram.h>~n"),
  1108. w("#include <wx/sashwin.h>~n"),
  1109. w("#include <wx/laywin.h>~n"),
  1110. w("#include <wx/graphics.h>~n"),
  1111. w("#include <wx/dcgraph.h>~n"),
  1112. w("#include <wx/aui/aui.h>~n"),
  1113. w("#include <wx/datectrl.h>~n"),
  1114. w("#include <wx/filepicker.h>~n"),
  1115. w("#include <wx/fontpicker.h>~n"),
  1116. w("#include <wx/clrpicker.h>~n"),
  1117. w("#include <wx/statline.h>~n"),
  1118. w("#include <wx/clipbrd.h>~n"),
  1119. w("#include <wx/splitter.h>~n"),
  1120. w("#include <wx/choicebk.h>~n"),
  1121. w("#include <wx/toolbook.h>~n"),
  1122. w("#include <wx/listbook.h>~n"),
  1123. w("#include <wx/treebook.h>~n"),
  1124. w("#include <wx/taskbar.h>~n"),
  1125. w("#include <wx/popupwin.h>~n"),
  1126. w("#include <wx/html/htmlwin.h>~n"),
  1127. w("#include <wx/html/htmlcell.h>~n"),
  1128. w("#include <wx/filename.h>~n"),
  1129. w("#include <wx/sysopt.h>~n"),
  1130. w("#include <wx/overlay.h>~n"),
  1131. w("~n~n", []),
  1132. w("#ifndef wxICON_DEFAULT_BITMAP_TYPE~n",[]),
  1133. w(" #define wxICON_DEFAULT_BITMAP_TYPE wxBITMAP_TYPE_ICO_RESOURCE~n",[]),
  1134. w("#endif~n", []),
  1135. w("~n~n", []),
  1136. [w("#define ~s_~s ~p~n", [Class,Name,Id]) ||
  1137. {Class,Name,_,Id} <- wx_gen_erl:get_unique_names()],
  1138. w("~n~n").
  1139. build_events() ->
  1140. open_write("../c_src/gen/wxe_events.cpp"),
  1141. c_copyright(),
  1142. w("~n/***** This file is generated do not edit ****/~n~n"),
  1143. w("#include <wx/wx.h>~n"),
  1144. w("#include \"../wxe_impl.h\"~n~n"),
  1145. w("#include \"wxe_macros.h\"~n"),
  1146. w("#include \"../wxe_events.h\"~n~n"),
  1147. w("#include \"../wxe_return.h\"~n~n"),
  1148. w("wxeEtype::wxeEtype(const char *name, int Id) {eName = name;cID = Id;}~n~n"),
  1149. w("WX_DECLARE_HASH_MAP(int, wxeEtype*, wxIntegerHash, wxIntegerEqual, wxeETmap );~n~n"),
  1150. w("wxeETmap etmap;~n~n"),
  1151. w(
  1152. "int wxeEventTypeFromAtom(char *etype_atom) {
  1153. wxeETmap::iterator it;
  1154. for(it = etmap.begin(); it != etmap.end(); ++it) {
  1155. wxeEtype * value = it->second;
  1156. if(strcmp(value->eName, etype_atom) == 0) {
  1157. if(it->first > wxEVT_USER_FIRST) {
  1158. return it->first - wxEVT_USER_FIRST;
  1159. } else {
  1160. return it->first;
  1161. }
  1162. }
  1163. }
  1164. return -1;
  1165. }
  1166. "),
  1167. Evs0 = [C || {_,C=#class{event=Evs}} <- get(), Evs =/= false],
  1168. Evs = lists:keysort(#class.id, Evs0),
  1169. initEventTable(Evs),
  1170. encode_events(Evs),
  1171. close().
  1172. initEventTable(Evs) ->
  1173. w("void initEventTable()~n{~n"),
  1174. w(" struct { ",[]),
  1175. w("int ev_type; int class_id; const char * ev_name;} event_types[] =~n {~n",[]),
  1176. lists:foreach(fun(Ev) -> init_event_classes(Ev) end,
  1177. [#class{id=0,event=[wxEVT_NULL]}|Evs]),
  1178. w(" {-1, 0, ""}~n };~n",[]),
  1179. w(" for(int i=0; event_types[i].ev_type != -1; i++) {~n",[]),
  1180. w(" if(NULL == etmap[event_types[i].ev_type]) {~n",[]),
  1181. w(" etmap[event_types[i].ev_type] =~n"
  1182. " new wxeEtype(event_types[i].ev_name, event_types[i].class_id);~n"),
  1183. w(" } else {~n",[]),
  1184. w(" wxeEtype *prev = etmap[event_types[i].ev_type];~n"
  1185. " wxString msg(wxT(\"Duplicate event defs: \"));~n"
  1186. " msg += wxString::FromAscii(event_types[i].ev_name);~n"
  1187. " msg += wxString::Format(wxT(\" %d \"), event_types[i].class_id);~n"
  1188. " msg += wxString::FromAscii(prev->eName);~n"
  1189. " msg += wxString::Format(wxT(\" %d\"), prev->cID);~n"
  1190. " send_msg(\"internal_error\", &msg);~n"
  1191. " }~n"
  1192. " }~n", []),
  1193. w("}~n~n").
  1194. init_event_classes(#class{event=ETs, id=Id}) ->
  1195. F = fun({Eev, Cev, OtherClass}) ->
  1196. w(" {~w + wxEVT_USER_FIRST, ~w, ~p},~n",
  1197. [Cev, find_id(OtherClass), wx_gen_erl:event_type_name(Eev)]);
  1198. ({Ev, {test_if, Test}}) ->
  1199. w("#if ~s~n", [Test]),
  1200. w(" {~w, ~w, ~p},~n",
  1201. [Ev, Id, wx_gen_erl:event_type_name(Ev)]),
  1202. w("#endif~n", []);
  1203. (Ev) ->
  1204. w(" {~w, ~w, ~p},~n",
  1205. [Ev, Id, wx_gen_erl:event_type_name(Ev)])
  1206. end,
  1207. [F(ET) || ET <- ETs].
  1208. find_id(OtherClass) ->
  1209. Class = get({class,atom_to_list(OtherClass)}),
  1210. %%{value, Class} = lists:keysearch(atom_to_list(OtherClass), #class.name, All),
  1211. Class#class.id.
  1212. encode_events(Evs) ->
  1213. ?WTC("encode_events"),
  1214. w("int getRef(void* ptr, wxeMemEnv* memenv)~n"
  1215. "{~n"
  1216. " WxeApp * app = (WxeApp *) wxTheApp;~n"
  1217. " return app->getRef(ptr,memenv);~n"
  1218. "}~n~n"),
  1219. w("bool sendevent(wxEvent *event, ErlDrvTermData port)~n{~n"
  1220. " int send_res ;~n"
  1221. " char * evClass = NULL;~n"
  1222. " wxMBConvUTF32 UTFconverter;~n"
  1223. " wxeEtype *Etype = etmap[event->GetEventType()];~n"
  1224. " wxeEvtListener *cb = (wxeEvtListener *)event->m_callbackUserData;~n"
  1225. " WxeApp * app = (WxeApp *) wxTheApp;~n"
  1226. " wxeMemEnv *memenv = app->getMemEnv(port);~n"
  1227. " if(!memenv) return 0;~n~n"
  1228. " wxeReturn rt = wxeReturn(port, cb->listener);~n"),
  1229. w("~n rt.addAtom((char*)\"wx\");~n"
  1230. " rt.addInt((int) event->GetId());~n"
  1231. " rt.addRef(cb->obj, cb->class_name);~n"
  1232. " rt.addExt2Term(cb->user_data);~n"),
  1233. w(" switch(Etype->cID) {~n"),
  1234. lists:foreach(fun(Ev) -> encode_event(Ev) end, Evs),
  1235. w(" }~n~n"),
  1236. w(" rt.addTupleCount(5);~n"),
  1237. w(" if(cb->fun_id) {~n"),
  1238. w(" rt.addRef(getRef((void *)event,memenv), evClass);~n"),
  1239. w(" rt.addTupleCount(2);~n"),
  1240. w(" rt.addInt(cb->fun_id);~n"),
  1241. w(" rt.addAtom(\"_wx_invoke_cb_\");~n"),
  1242. w(" rt.addTupleCount(3);~n"),
  1243. w(" pre_callback();~n"),
  1244. w(" send_res = rt.send();~n"),
  1245. w(" if(send_res) handle_event_callback(WXE_DRV_PORT_HANDLE, cb->listener);~n"),
  1246. w(" app->clearPtr((void *) event);~n"),
  1247. w(" } else {~n"),
  1248. w(" send_res = rt.send();~n"),
  1249. w(" if(cb->skip) event->Skip();~n"),
  1250. #class{id=SizeId} = lists:keyfind("wxSizeEvent", #class.name, Evs),
  1251. #class{id=MoveId} = lists:keyfind("wxMoveEvent", #class.name, Evs),
  1252. w(" if(app->recurse_level < 1 && (Etype->cID == ~w ||…

Large files files are truncated, but you can click here to view the full file